1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
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
|