; 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 _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