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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
|
.export _timed_getch, _set_jiffy_timer, _agetc, _numgetc
.export _yngetc, _lcgetc, _jsleep, _get_item
.import _cgetc, _cblank, putchar, _rand
.include "atari.inc"
.ifdef CART_TARGET
.segment "HIGHCODE"
.else
.code
.endif
; keyboard and timer functions for taipan.
; sleep for j jiffies.
; extern void __fastcall__ jsleep(unsigned int j);
_jsleep:
jsr _set_jiffy_timer
jiffy_wait:
lda CDTMV3
ora CDTMV3+1
bne jiffy_wait
rts
; extern void __fastcall__ set_jiffy_timer(unsigned int jiffies);
_set_jiffy_timer: ; called by jsleep() also.
sei ; disable IRQ while setting timer (probably overkill)
sta CDTMV3
stx CDTMV3+1
cli
rts
; like curses timeout(5000) followed by getch(): sleep until either
; a key is pressed or the timer expires. returns 0 if no key pressed.
; extern char __fastcall__ timed_getch(void);
_timed_getch:
lda #$2c ; $012c jiffies = 5 sec (NTSC) or 6 sec (PAL)
ldx #$01
jsr _set_jiffy_timer
@wait4key:
lda CDTMV3 ; has timer counted down to 0?
ora CDTMV3+1
bne @timer_running
tax ; timer expired, return(0), A is already 0 here
rts
@timer_running:
lda CH ; no, check for a keypress
; ...but don't let the capslock or inverse keys count
; as a keypress, here.
cmp #$ff ; no key pressed
beq @wait4key
and #$3f ; mask shift/control bits
cmp #$3c ; caps-lock
beq @wait4key
cmp #$27 ; inverse (atari) key
beq @wait4key
; user hit a key, handle it. but don't print a cursor.
_agetc_no_cursor:
jsr _cgetc
jmp finish_agetc
; _agetc removes the inverse-video bit, and if
; a control key is pressed, it turns it into the non-control version
; (e.g. ^A = lowercase a). Keys that can't be mapped to regular ASCII
; (such as clear, delete, escape) are replaced with a space.
; extern unsigned char agetc(void);
_agetc:
; show the user a cursor
lda #$80 ; inverse space (putchar uses screen codes)
jsr putchar
jsr _cgetc ; get ATASCII code of keypress
pha
; get rid of the cursor
lda #$00 ; space
jsr putchar
pla
finish_agetc:
pha
; twitch the random bottle based on the low bit of
; the character entered.
and #$01
beq @nr
jsr _rand
@nr:
pla
; special cases
cmp #$9b ; enter key, return as-is
beq ok
cmp #$9c ; delete key, return as-is
beq ok
cmp #$7e ; backspace
beq ok
; everything else
and #$7f ; strip bit 7 (inverse)
bne notnull
lda #$20 ; map null (heart, ctrl-,) to space
notnull:
cmp #$20
bcs notcontrol
ora #$60 ; 1 - 31 map to 96 - 127
notcontrol:
cmp #$7c ; | (pipe, vertical bar) allowed as-is.
beq ok
cmp #$7b ; rest of range $7b - $7f is unmappable.
bcc ok ; (remember, $7e, backspace, was handled above)
lda #$20
ok:
; pha
; ldx #0
; lda FR1+2
; jsr _cursor
; pla
ldx #0
rts
; extern unsigned char lcgetc(void);
_lcgetc:
jsr _agetc
cmp #'A'
bcc ok
cmp #'Z'+1
bcs ok
eor #$20 ; lowercase it
bcc ok
; extern unsigned char numgetc(void);
_numgetc:
jsr _agetc
cmp #$9b
beq ok
cmp #$7e ; backspace
beq ok
cmp #$61 ; allow 'a' for "all"
beq ok
cmp #$6b ; allow 'k' for 1000
beq ok
cmp #$6d ; allow 'm' for 1 million
beq ok
cmp #$9c ; shift-del
beq ok
cmp #'0'
bcc _numgetc
cmp #'9'+1
bcc ok
bcs _numgetc
; extern unsigned char __fastcall__ yngetc(char dflt);
_yngetc:
sta FR0 ; stash default arg
jsr _lcgetc
cmp #'y' ; return y or n immediately
beq ok
cmp #'n'
beq ok
lda FR0 ; otherwise, check for default arg
beq _yngetc ; no default, get another keypress
rts ; else return the default
; extern unsigned char get_item(unsigned char allow_all);
_get_item:
sta FR0 ; stash arg
@getkey:
jsr _lcgetc ; switch(lcgetc()) {
ldx #0
cmp #'o'
beq @gi_done ; case 'o': return 0;
inx
cmp #'s'
beq @gi_done ; case 's': return 1;
inx
cmp #'a'
beq @gi_done ; case 'a': return 2;
inx
cmp #'g'
beq @gi_done ; case 'g': return 3;
ldy FR0
beq @getkey ; if allow_all is false, get another key
inx
cmp #'*' ; case '*': return 4;
bne @getkey ; if none of the above, get another key
@gi_done:
txa
rts
|