; kgetc() is a replacement for cc65's cgetc(). It does *not* call the
; OS's K: "get one byte" routine to decode keycodes into (AT)ASCII. It
; *does* support all 255 keycodes, meaning ctrl+shift combos work.

; kgetc() actually does call the OS K: handler to produce a keyclick, but
; it does so with a fixed keycode (12, the Return key) and throws away
; the result. This means we can turn off the keyclick even on an 800.
; The OS NOCLIK location is used on the 800, too.

; There is no blocking for another keystroke, if a key like Escape or
; Inverse is pressed. The ctrl-1 keystroke is detected, even though
; the OS "pre-empts" it (we never see $b1 in CH).

; There is no inverse video mode! INVFLG is never set, and is ignored.
; There is no Control-lock either, although Caps-lock exists.

; Unlike cgetc(), kgetc() doesn't need to be able to return 0 as a valid
; character. So instead, 0 is used to mean "ignore keystroke".

; Since inverse numbers can't be returned, I've reused their ATASCII codes
; for 'switch window' with ctrl-1 through 7.

; kgetc() blocks if no key has been pressed when it's called. to do
; non-blocking reads:
;   if(keypress())
;     c = kgetc();
;   /* c is 0 if either no key or a non-ATASCII keystroke was pressed,
;      e.g. caps lock or an unused ctrl-shift-letter. */

 .include "atari.inc"
 .export _kgetc, _keypress
 .import _keytab

 XCH_CAPS = $8a ; must agree with keytab.h

 ; note: _keypress returns true/false, but also the Z
 ; flag reflects the return status (Z clear for true).
_keypress:
 ldx CH
 cpx #$ff
 bne ret1 ; if CH != $ff, a key is pressed...
 ldx SSFLAG
 bne ret1 ; if SSFLAG != 0, a key is pressed...
 ldx HELPFG
 bne ret1 ; if HELPFG != 0, a key (Help) is pressed...
 txa      ; return(0);
 .byte $2c ; BIT ABS, skip LDA imm below
ret1:
 lda #1
 rts

_kgetc:
 ldx HELPFG
 beq read_ch ; Help key pressed?
 lda #0
 sta HELPFG ; yes, clear it
 ldx #$54 ; 1200XL Shift-F4 keycode
 bne decode

read_ch:
 ldx CH
 cpx #$ff
 bne decode
 ldx SSFLAG
 beq read_ch
 lda #0
 sta SSFLAG
 ldx #$9f ; real Ctrl-1 keycode

decode:
 lda _keytab,x
 beq done ; 0 in the table means ignore the keystroke (not even a click)

 cmp #XCH_CAPS
 bne gotkey

 lda SHFLOK ; caps was pressed. we use SHFLOK different from how the OS does.
 eor #$20
 sta SHFLOK
 lda #0
 beq click_and_done

gotkey: ; ATASCII code in A here, don't overwrite
 cmp #'z'+1 ; only apply caps lock to a-z
 bcs noshf
 cmp #'a'
 bcc noshf
 sbc SHFLOK
noshf:
 ldx NOCLIK
 bne done ; obey the XL OS's keyclick disable flag, even on an 800

 ; sound the keyclick (let the OS do it)
click_and_done:
 pha
 jsr keyclick
 pla

done:
 ldx #$ff
 stx CH
 rts

keyclick:
 lda NOCLIK
 bne return ; disabled
 lda #0
 sta SSFLAG
 lda #12  ; EOL (could be any regular key but we need 12 below)
 sta CH   ; fall thru to cgetc...

; ripped from the cc65 lib src, and modified.
; original code by Christian Groessler, November-2002.
;_cgetc:
 ;lda     #12 ; already in A
 sta     ICAX1Z          ; fix problems with direct call to KEYBDV
 jsr     callit
return:
 ;ldx     #0
 rts

callit:
 lda     KEYBDV+5
 pha
 lda     KEYBDV+4
 pha
 rts
