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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
|
.export _timed_getch, _set_jiffy_timer, _agetc, _numgetc
.export _yngetc, _lcgetc, _jsleep, _get_item_port, _get_item_battle, _tjsleep
.import _cgetc, _cblank, putchar, _rand, _turbo
.include "atari.inc"
.ifdef CART_TARGET
.segment "HIGHCODE"
.else
.code
.endif
; keyboard and timer functions for taipan.
; sleep for j jiffies, unless _turbo is set.
; extern void __fastcall__ tjsleep(unsigned int j);
_tjsleep:
sta FR0+4
lda _turbo
bne jret
lda FR0+4
; 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
jret:
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
.ifdef GAME_HELP
.import _print_game_help
cmp #'?'
bne notquestion
jmp _print_game_help
notquestion:
.endif
; 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
ora #$80 ; show user the default (or a regular cursor if none)
and #$bf ; (uppercase)
jsr putchar
jsr _agetc_no_cursor
ora #$20 ; lowercase
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_port(void)
; return 0-3 for opium, silk, arms, general.
; return 5 for Enter key (nothing chosen)
_get_item_port:
lda #4
.byte $2c
; extern unsigned char get_item_battle(void)
; return 0-4 for opium, silk, arms, general, all.
_get_item_battle:
lda #5
sta FR0
@get_loop:
jsr get_item
cmp FR0
beq @get_loop
rts
get_item:
@getkey:
jsr _lcgetc ; switch(lcgetc()) {
sta FR0+1
;;; 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;
ldx #5
@giloop:
lda items_tbl,x
cmp FR0+1
beq @gi_done
dex
bpl @giloop
bmi @getkey
@gi_done:
txa
rts
.rodata
items_tbl: .byte "osag*",$9b
|