@@ -45,76 +45,112 @@ _PENotRelease:
4545_PENotRaw:
4646 beq _PECheckNormal ; flags=0, normal processing
4747 ;
48- ; flags != 0, check for shift +arrow or shift+backspace
48+ ; flags != 0, check for FNX +arrow or shift+backspace
4949 ;
5050 lda KNLEvent.key.ascii
5151 cmp #$10 ; Up arrow
52- beq _PEShiftUp
52+ beq _PEFlagsArrowUD
5353 cmp #$0E ; Down arrow
54- beq _PEShiftDown
54+ beq _PEFlagsArrowUD
5555 cmp #$08 ; Backspace (Shift+DEL = insert line)
5656 beq _PEShiftBackspace ; queue it, input.asm handles shift detection
5757 cmp #$B5 ; INS key (Shift+Backspace)
5858 beq _PEDoInsertLine
59+ cmp #$93 ; Shift+HOME (CLR)?
60+ beq _PEDoClearScreen
5961 bra ProcessEvents ; other modified keys, ignore
6062
63+ _PEFlagsArrowUD:
64+ pha
65+ jsr IsFnxPressed
66+ beq _PEFlagsNoFnx
67+ pla
68+ cmp #$10
69+ beq _PEFnxUp
70+ bra _PEFnxDown
71+ _PEFlagsNoFnx:
72+ pla
73+ jmp ProcessEvents ; non-FNX modified arrow, ignore
74+
6175_PEDoInsertLine:
6276 lda #$B5 ; queue INS code for input.asm to handle
6377 jmp _PEQueueA
6478
79+ _PEDoClearScreen:
80+ lda #$0C ; remap to Ctrl+L (clear screen)
81+ jmp _PEQueueA
82+
6583_PEShiftBackspace:
6684 jmp _PEQueueA
6785
68- _PEShiftUp :
86+ _PEFnxUp :
6987 jsr HandleShiftUp
70- ; Schedule repeat for shift +up (CBM/K keyboards only)
88+ ; Schedule repeat for FNX +up (CBM/K keyboards only)
7189 phx
7290 ldx KNLEvent.key.keyboard
73- bne _PEShiftUpDone
74- lda #$90 ; special code for shift +up
91+ bne _PEFnxUpDone
92+ lda #$90 ; special code for FNX +up
7593 jsr StartRepeatTimerForKey
76- _PEShiftUpDone :
94+ _PEFnxUpDone :
7795 plx
7896 jmp ProcessEvents
79- _PEShiftDown :
97+ _PEFnxDown :
8098 jsr HandleShiftDown
81- ; Schedule repeat for shift +down (CBM/K keyboards only)
99+ ; Schedule repeat for FNX +down (CBM/K keyboards only)
82100 phx
83101 ldx KNLEvent.key.keyboard
84- bne _PEShiftDownDone
85- lda #$8E ; special code for shift +down
102+ bne _PEFnxDownDone
103+ lda #$8E ; special code for FNX +down
86104 jsr StartRepeatTimerForKey
87- _PEShiftDownDone :
105+ _PEFnxDownDone :
88106 plx
89107 jmp ProcessEvents
90108
91109_PECheckNormal:
92110 lda KNLEvent.key.ascii ; check for arrow keys
93111 cmp #$10 ; Up arrow?
94- beq _PECheckShiftArrow
112+ beq _PECheckModArrow
95113 cmp #$0E ; Down arrow?
96- beq _PECheckShiftArrow
114+ beq _PECheckModArrow
97115 cmp #$02 ; Left arrow?
98- beq _PECheckShiftArrow
116+ beq _PECheckModArrow
99117 cmp #$06 ; Right arrow?
100- beq _PECheckShiftArrow
118+ beq _PECheckModArrow
101119 cmp #$B5 ; INS key (Shift+Backspace)?
102120 beq _PEDoInsertLine
121+ cmp #$93 ; Shift+HOME (CLR)?
122+ beq _PEDoClearScreen
103123 bra _PECheckCtrlC
104- _PECheckShiftArrow :
124+ _PECheckModArrow :
105125 pha ; save arrow key
106- jsr IsShiftPressed ; check if shift held
107- beq _PENoShiftArrow ; Z set = no shift
126+ jsr IsCtrlPressed ; check if Ctrl held
127+ beq _PENoCtrlArrow ; Z set = no Ctrl
108128 pla ; restore arrow key
109129 cmp #$10
110- beq _PEShiftUp
130+ beq _PECtrlUp
111131 cmp #$0E
112- beq _PEShiftDown
132+ beq _PECtrlDown
113133 ; Must be Left ($02) or Right ($06) - do word jump
114134 cmp #$06 ; C=1 if right, C=0 if left
115135 jsr EXTWordJump
116136 jmp ProcessEvents
117- _PENoShiftArrow:
137+ _PECtrlUp:
138+ lda #$01 ; Ctrl+A = beginning of line
139+ jmp _PEQueueA
140+ _PECtrlDown:
141+ lda #$05 ; Ctrl+E = end of line
142+ jmp _PEQueueA
143+ _PENoCtrlArrow:
144+ ; Check FNX for Up/Down scroll
145+ jsr IsFnxPressed
146+ beq _PENoModArrow
147+ pla ; restore arrow key
148+ cmp #$10
149+ beq _PEFnxUp
150+ cmp #$0E
151+ beq _PEFnxDown
152+ bra _PEScheduleRepeat ; FNX+Left/Right = plain arrow
153+ _PENoModArrow:
118154 pla ; restore arrow key, continue to repeat scheduling
119155 bra _PEScheduleRepeat
120156_PECheckCtrlC:
@@ -138,16 +174,16 @@ _PEIsTimer:
138174 bcc _PETimerValid
139175 jmp ProcessEvents
140176_PETimerValid:
141- ; Check for shift +arrow repeat codes
142- cmp #$90 ; shift +up?
143- beq _PERepeatShiftUp
144- cmp #$8E ; shift +down?
145- beq _PERepeatShiftDown
177+ ; Check for FNX +arrow repeat codes
178+ cmp #$90 ; FNX +up?
179+ beq _PERepeatFnxUp
180+ cmp #$8E ; FNX +down?
181+ beq _PERepeatFnxDown
146182 bra _PEQueueA
147- _PERepeatShiftUp :
183+ _PERepeatFnxUp :
148184 jsr HandleShiftUp
149185 jmp ProcessEvents
150- _PERepeatShiftDown :
186+ _PERepeatFnxDown :
151187 jsr HandleShiftDown
152188 jmp ProcessEvents
153189_PEIsRelease:
@@ -171,23 +207,23 @@ _PEIsRelease:
171207
172208 jmp ProcessEvents
173209_PEIsRaw:
174- lda KNLEvent.key.ascii ; check for shift +arrow in raw mode too
210+ lda KNLEvent.key.ascii ; check for FNX +arrow in raw mode too
175211 cmp #$10 ; Up arrow
176212 beq _PERawArrow
177213 cmp #$0E ; Down arrow
178214 beq _PERawArrow
179215 bra _PERawNotArrow
180216_PERawArrow:
181217 pha ; save arrow key code
182- jsr IsShiftPressed ; check if shift is held
183- beq _PERawNoShift ; Z set = no shift
218+ jsr IsFnxPressed ; check if FNX is held
219+ beq _PERawNoFnx ; Z set = no FNX
184220 pla ; restore arrow code
185221 cmp #$10
186- bne _PERawShiftDown
187- jmp _PEShiftUp
188- _PERawShiftDown :
189- jmp _PEShiftDown
190- _PERawNoShift :
222+ bne _PERawFnxDown
223+ jmp _PEFnxUp
224+ _PERawFnxDown :
225+ jmp _PEFnxDown
226+ _PERawNoFnx :
191227 pla ; restore arrow code, continue to queue
192228 bra _PEQueueA
193229_PERawNotArrow:
@@ -359,28 +395,80 @@ _repeat
359395IsShiftPressed:
360396 pha
361397 phx
398+ phy
362399 ;
363- ; Kernel normalizes shift raw codes:
364400 ; LSHIFT = 0, RSHIFT = 1 (from keys.asm)
365401 ;
366- ; Check left shift (raw code 0)
367402 lda #0
368- jsr KeyboardConvertXA ; X = index, A = mask
403+ ldy #1
404+ bra CheckModPair
405+
406+ ; ************************************************************************************************
407+ ;
408+ ; Check if either Ctrl key is currently pressed
409+ ; Returns: Z clear if Ctrl pressed, Z set if not pressed
410+ ; Preserves: X, Y
411+ ;
412+ ; ************************************************************************************************
413+
414+ IsCtrlPressed:
415+ pha
416+ phx
417+ phy
418+ ;
419+ ; LCTRL = 2, RCTRL = 3 (from keys.asm)
420+ ;
421+ lda #2
422+ ldy #3
423+ bra CheckModPair
424+
425+ ; ************************************************************************************************
426+ ;
427+ ; Check if either FNX/Meta key is currently pressed
428+ ; Returns: Z clear if FNX pressed, Z set if not pressed
429+ ; Preserves: X, Y
430+ ;
431+ ; ************************************************************************************************
432+
433+ IsFnxPressed:
434+ pha
435+ phx
436+ phy
437+ ;
438+ ; LMETA/FNX = 6, RMETA/FNX = 7 (from keys.asm)
439+ ;
440+ lda #6
441+ ldy #7
442+ ;
443+ ; Fall through to CheckModPair
444+ ;
445+
446+ ; ************************************************************************************************
447+ ;
448+ ; Shared: check a pair of modifier keys (raw codes in A and Y)
449+ ; Called with A=left raw code, Y=right raw code
450+ ; Returns: Z clear if either pressed, Z set if neither
451+ ; Preserves: X, Y
452+ ;
453+ ; ************************************************************************************************
454+
455+ CheckModPair:
456+ jsr KeyboardConvertXA
369457 and KeyStatus,x
370- bne _ISPShiftFound
371- ; Check right shift (raw code 1)
372- lda #1
458+ bne _CMPFound
459+ tya ; try right-key code
373460 jsr KeyboardConvertXA
374461 and KeyStatus,x
375- bne _ISPShiftFound
462+ bne _CMPFound
376463 ;
377- ; No shift pressed - return with Z set
464+ ; Not pressed - return with Z set
465+ ply
378466 plx
379467 pla
380468 lda #0 ; sets Z flag
381469 rts
382- _ISPShiftFound :
383- ; Shift is pressed - return with Z clear
470+ _CMPFound :
471+ ply
384472 plx
385473 pla
386474 lda #1 ; clears Z flag
@@ -414,5 +502,7 @@ KeyboardQueueEntries:
414502; 19/02/26 Added GetNextEvent for non-dispatching event read,
415503; IsShiftPressed helper for keyboard status check.
416504; 20/02/26 Added Shift+Left/Right word jump dispatch as $B6/$B7.
505+ ; 28/02/26 Remapped to macOS conventions: Ctrl+arrow=word jump/home/end,
506+ ; FNX+Up/Down=scroll. Added IsCtrlPressed, IsFnxPressed helpers.
417507;
418508; ************************************************************************************************
0 commit comments