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
|
.export _timed_getch, _set_jiffy_timer, _agetc, _numgetc
.export _yngetc, _lcgetc, _jsleep
.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
beq @done ; yes, return(0)
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
jmp _agetc_no_cursor ; user hit a key, read it.
@done:
;lda #$00 ; return(0), A is already 0 here
tax
rts
_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:
lda #$80 ; inverse space
jsr putchar
jsr _cgetc ; get ATASCII code of keypress
pha
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
|