diff options
| author | B. Watson <urchlay@slackware.uk> | 2026-03-25 03:08:11 -0400 |
|---|---|---|
| committer | B. Watson <urchlay@slackware.uk> | 2026-03-25 03:08:11 -0400 |
| commit | b74d292847b22cf282ff8ae7d1b51df34176ce4d (patch) | |
| tree | 4717814a5390d1672840c2c417ebb4d9606480d8 /src/kgetc.s | |
| parent | 8f19c016edd9f258c1b39eb44647c685b245f2fc (diff) | |
| download | fujinet-chat-b74d292847b22cf282ff8ae7d1b51df34176ce4d.tar.gz | |
Banish cgetc(), and all its annoyances. Much more flexible and precise keyboard control, see keytab.[ch] and kgetc.[ch]
Diffstat (limited to 'src/kgetc.s')
| -rw-r--r-- | src/kgetc.s | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/src/kgetc.s b/src/kgetc.s new file mode 100644 index 0000000..c11cb6d --- /dev/null +++ b/src/kgetc.s @@ -0,0 +1,125 @@ +; 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 |
