Mercurial > hg > index.cgi
comparison src/keyb.s @ 73:2d52cd154ed1
Split some code into separate files for easier management
Because the source for lwbasic is so large, split it into several
different files to make it easier to navigate and modify. This is
part one of the split.
author | William Astle <lost@l-w.ca> |
---|---|
date | Sun, 06 Aug 2023 00:12:29 -0600 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
72:f492fa6f6dc8 | 73:2d52cd154ed1 |
---|---|
1 *pragmapush list | |
2 *pragma list | |
3 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
4 ; Check for BREAK; this needs to check the keyboard directly instead of just using the usual key fetching routine so | |
5 ; we don't interfere with keyboard buffering if BREAK isn't pressed. We also need to scan the keyboard directly for this | |
6 ; so we react even if the keyboard buffer is full. If BREAK is pressed, the keyboard buffer is emptied. | |
7 breakcheck lda #0xfb ; strobe column for BREAK | |
8 sta PIA0.DB | |
9 clra ; clear carry for no BREAK | |
10 lda PIA0.DA ; read rows | |
11 bita #0x40 ; is BREAK down? | |
12 bne breakcheck0 ; brif not - check for SHIFT-@ | |
13 sync ; wait for interrupt to scan keyboard | |
14 bsr keyb_clearbuff ; reset keyboard buffer | |
15 coma ; flag BREAK | |
16 breakcheck1 rts | |
17 breakcheck0 lda #0x7f ; check for SHIFT | |
18 sta PIA0.DB | |
19 lda PIA0.DA | |
20 bita #0x40 ; shift? | |
21 bne breakcheck1 ; brif not | |
22 lda #0xfe ; check for @ | |
23 sta PIA0.DB | |
24 lda PIA0.DA | |
25 bita #1 ; @? | |
26 bne breakcheck1 ; brif not | |
27 bsr keyb_clearbuff ; clear buffer | |
28 breakcheck2 sync ; wait for keyboard to actually be scanned | |
29 bsr keyb_getkey | |
30 bcs breakcheck2 ; brif no key down | |
31 bra breakcheck ; go do the break/pause check dance again | |
32 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
33 ; Console keyboard input driver | |
34 ; | |
35 ; Reset the keyboard state, which means clearing the buffer and state flags | |
36 keyb_reset bsr keyb_clearbuff ; clear keyboard buffer | |
37 lda keyb_flags ; reset keyboard state flags but keep capslock | |
38 anda #keyb_caps | |
39 sta keyb_flags | |
40 clr keyb_joystate ; clear joystick button state | |
41 clr keyb_curscan ; stop any keyboard repeating | |
42 ldx #0xffff ; mark all key state as "unpressed" | |
43 stx keyb_state | |
44 stx keyb_state+2 | |
45 stx keyb_state+4 | |
46 stx keyb_state+6 | |
47 rts | |
48 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
49 ; Empty the keyboard buffer | |
50 keyb_clearbuff ldx #keyb_buff ; point to start of buffer | |
51 stx keyb_buffr ; set both pointers to the start | |
52 stx keyb_buffw | |
53 rts | |
54 ; Read character from keyboard ring buffer; return with C set if buffer empty; this doesn't actually need to have | |
55 ; interrupts disabled because the interrupt only ever updates the write pointer and then only to increase it. As a | |
56 ; result, worst case is that we don't detect the contents added to the buffer on this call and have to wait for the | |
57 ; next. | |
58 keyb_getkey pshs x ; save register | |
59 ldx keyb_buffr ; get read pointer | |
60 cmpx keyb_buffw ; same as write pointer? | |
61 bne keyb_getkey0 ; brif not - we have a result | |
62 coma ; set carry for empty buffer | |
63 puls x,pc ; restore register and return | |
64 keyb_getkey0 lda ,x+ ; get character from buffer | |
65 cmpx #keyb_buff+keyb_bufflen ; did we run off end of buffer? | |
66 blo keyb_getkey1 ; brif not | |
67 ldx #keyb_buff ; reset to start | |
68 keyb_getkey1 stx keyb_buffr ; save new read pointer | |
69 andcc #0xfe ; flag key retrieved | |
70 puls x,pc ; restore register and return | |
71 ; The PIA reading loop is specifically set up to NOT read PIA0.DB to avoid prematurely clearing the VSYNC interrupt flag | |
72 ; since that could lead to missing interrupts. Reading PIA0.DA will clear the HSYNC interrupt flag but that's less of a | |
73 ; problem because that interrupt is basically useless. | |
74 ; | |
75 ; As a note, doing the PIA read in a loop ends up using an extra 27 CPU cycles for the BCS instruction. However, it | |
76 ; saves 70 code bytes. The trade off seems worth it in this case. | |
77 ; | |
78 ; Once keyboard state is read, we do the following: | |
79 ; | |
80 ; * update the state of SHIFT, CTRL, ALT | |
81 ; * decode all other keys in a loop | |
82 keyb_read0a pshs b ; save flag bit | |
83 ldb a,y ; get state flag | |
84 bitb #0x40 ; did it change state? | |
85 bne keyb_read0d ; brif so | |
86 puls b,pc ; clean up and return | |
87 keyb_read0d andb #0xbf ; flag it as not changed | |
88 stb a,y | |
89 ldb a,u ; get current modifier state | |
90 eorb #0x40 ; flip the state bit | |
91 stb a,u ; save new state flags | |
92 bitb #0x40 ; Z set if not down | |
93 puls b ; get back flag bit | |
94 beq keyb_read0b ; brif key is pressed | |
95 comb ; invert bit flag | |
96 andb keyb_flags ; clear bit in flags | |
97 bra keyb_read0c ; finish up | |
98 keyb_read0b orb keyb_flags ; set the flag | |
99 keyb_read0c stb keyb_flags ; update flags | |
100 rts | |
101 keyb_read leas -9,s ; make temporary buffer | |
102 leay 1,s ; point to temporary state buffer | |
103 clra ;* set to 0xff with C clear; start by strobing no columns for joystick | |
104 deca ;* then rotate the 0 bit through to do the actual keyboard columns | |
105 ldu #keyb_state ; point to end of keyboard state buffer | |
106 sta PIA0.DB ; strobe no columns | |
107 ldb PIA0.DA ; get joystick button state | |
108 stb keyb_joystate ; save it for later when needed | |
109 andb #0x7f ; mask off comparator (pretend "button" down) | |
110 stb ,s ; save button/comparator state mask | |
111 rola ; set up for first column | |
112 keyb_read0 sta PIA0.DB ; set column strobe | |
113 ldb PIA0.DA ; read row data | |
114 eorb ,u+ ; set bits if state changed | |
115 andb ,s ; mask off comparator and active buttons | |
116 stb ,y+ ; save state change information | |
117 rola ; shift to next column | |
118 bcs keyb_read0 ; brif we haven't done the last column | |
119 sta PIA0.DB ; reset column strobe to none | |
120 ldd #0xff00|keyb_shift | |
121 bsr keyb_read0a | |
122 ldd #0xfc00|keyb_ctrl | |
123 bsr keyb_read0a | |
124 ldd #0xfb00|keyb_alt | |
125 bsr keyb_read0a | |
126 keyb_read3 ldd #0x0701 ; initialize bit probe and counter | |
127 keyb_read4 leay -1,y ; move pointers to next byte | |
128 leau -1,u | |
129 keyb_read5 bitb ,y ; did this key change state? | |
130 bne keyb_read7 ; brif so | |
131 keyb_read6 adda #8 ; adjust scan code | |
132 lslb ; shift bit probe | |
133 bpl keyb_read5 ; brif we haven't done all bits | |
134 ldb ,y ; update state flags for this byte | |
135 eorb ,u | |
136 stb ,u | |
137 ldb #1 ; reset bit probe | |
138 anda #0x07 ; reset scan code | |
139 deca ; adjust for next column | |
140 bpl keyb_read4 ; brif not - do another | |
141 leas 9,s ; clean up stack | |
142 ldb keyb_curscan ; is key repeating? | |
143 bne keyb_read9 ; brif so | |
144 keyb_reada rts | |
145 keyb_read7 bitb ,u ; get current state | |
146 bne keyb_read8 ; brif key pressed (make) | |
147 cmpa keyb_curscan ; is it the currently repeating key? | |
148 bne keyb_read6 ; brif not - don't need to do anything | |
149 clr keyb_curscan ; clear the current repeat | |
150 bra keyb_read6 | |
151 keyb_read8 sta keyb_curscan ; set the current scan code that is repeating | |
152 pshs d ; save current bit probe and scan code | |
153 ldb #keyb_repdeli ; intialize repeat delay | |
154 stb keyb_repdel | |
155 bsr keyb_tobuff ; decode key to buffer | |
156 puls d ; restore scan code and bit probe | |
157 bra keyb_read6 ; go handle the next bit | |
158 keyb_read9 dec keyb_repdel ; is it time to repeat it? | |
159 bne keyb_reada ; brif not | |
160 ldb #keyb_repdelr ; reset repeat delay | |
161 stb keyb_repdel | |
162 lda keyb_curscan ; get current scan code | |
163 keyb_tobuff tsta ; @? | |
164 beq keyb_tobuff7 ; brif so | |
165 cmpa #26 ; is it alpha or @? | |
166 bhi keyb_tobuff6 ; brif not | |
167 ldb keyb_flags ; get shift flags | |
168 bitb #keyb_ctrl|keyb_alt ; ALT or CTRL? | |
169 bne keyb_tobuff4 ; brif one or both | |
170 ora #0x60 ; make lower case | |
171 bitb #keyb_caps ; capslock enabled? | |
172 beq keyb_tobuff0 ; brif not | |
173 eora #0x20 ; flip to upper case | |
174 keyb_tobuff0 bitb #keyb_shift ; shifted? | |
175 beq keyb_tobuff1 ; brif not | |
176 eora #0x20 ; flip case if shifted | |
177 keyb_tobuff1 ldx keyb_buffw ; get write pointer for keyboard buffer | |
178 sta ,x+ ; put it in the buffer | |
179 cmpx #keyb_buff+keyb_bufflen ; end of buffer? | |
180 blo keyb_tobuff2 ; brif not | |
181 ldx #keyb_buff ; reset pointer to start | |
182 keyb_tobuff2 cmpx keyb_buffr ; did we run into the read pointer? | |
183 beq keyb_tobuff3 ; brif so - there wasn't room so don't save pointer | |
184 stx keyb_buffw ; update the write pointer | |
185 keyb_tobuff3 rts | |
186 keyb_tobuff4 bitb #keyb_alt ; is ALT? | |
187 beq keyb_tobuff1 ; brif not - scan code is CTRL-<letter> code | |
188 ora #0x80 ; set bit 7 for "ALT" codes | |
189 bitb #keyb_shift ; shifted? | |
190 beq keyb_tobuff5 ; brif not | |
191 ora #0x20 ; set bit 5 | |
192 keyb_tobuff5 bitb #keyb_ctrl ; ctrl? | |
193 beq keyb_tobuff1 ; brif not - stash it in the buffer | |
194 ora #0x40 ; set bit 6 for "ctrl | |
195 bra keyb_tobuff1 ; stash it the buffer | |
196 keyb_tobuff6 suba #26 ; codes above 26 down to 1; @ will be 0 | |
197 keyb_tobuff7 cmpa #6 ; is it "0"? | |
198 bne keyb_tobuff8 ; brif not | |
199 ldb keyb_flags ; get shift flags | |
200 bitb #keyb_shift|keyb_ctrl ; CTRL-0 or SHIFT-0? | |
201 beq keyb_tobuff8 ; brif not - not "capslock" | |
202 eorb #keyb_caps ; flip the capslock state | |
203 stb keyb_flags | |
204 keyb_tobuffa rts ; and don't put it in the buffer | |
205 keyb_tobuff8 cmpa #25 ; is it at or above ALT? | |
206 blo keyb_tobuff9 ; brif not | |
207 suba #2 ; close gap for ALT/CTRL | |
208 keyb_tobuff9 ldb #8 ;* 8 codes; multiply by 8 and move to B | |
209 mul ;* | |
210 ldx #keyb_codetab ; point to special code table | |
211 abx ; now X points to the base entry in the table | |
212 ldb keyb_flags ; get shift flags | |
213 andb #keyb_shift|keyb_ctrl|keyb_alt ; keep only shift/ctrl/alt | |
214 lda b,x ; fetch key code | |
215 beq keyb_tobuffa ; brif no code to return | |
216 bra keyb_tobuff1 ; go stash it in the buffer | |
217 ; This is the keyboard code table; there are 8 bytes per entry in the following order: | |
218 ; 0: unmodified | |
219 ; 1: shift | |
220 ; 2: ctrl | |
221 ; 3: ctrl-shift | |
222 ; 4: alt | |
223 ; 5: alt-shift | |
224 ; 6: alt-ctrl | |
225 ; 7: alt-ctrl-shift | |
226 ; | |
227 ; No entries for ALT, CTRL, SHIFT, or letters | |
228 keyb_codetab fcb 0x40,0x13,0x40,0x40,0x80,0xa0,0xc0,0xe0 ; @ | |
229 fcb 0x5e,0x5f,0x00,0x00,0x00,0x00,0x00,0x00 ; <UP> | |
230 fcb 0x0a,0x5b,0x00,0x00,0x00,0x00,0x00,0x00 ; <DOWN> | |
231 fcb 0x08,0x15,0x00,0x00,0x00,0x00,0x00,0x00 ; <LEFT> | |
232 fcb 0x09,0x5d,0x00,0x00,0x00,0x00,0x00,0x00 ; <RIGHT> | |
233 fcb 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20 ; <SPACE> | |
234 fcb 0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ; 0 (shift/ctrl variants shadowed above) | |
235 fcb 0x31,0x21,0x00,0x00,0x00,0x00,0x00,0x00 ; 1 ! | |
236 fcb 0x32,0x22,0x00,0x00,0x00,0x00,0x00,0x00 ; 2 " | |
237 fcb 0x33,0x23,0x00,0x00,0x00,0x00,0x00,0x00 ; 3 # | |
238 fcb 0x34,0x24,0x00,0x00,0x00,0x00,0x00,0x00 ; 4 $ | |
239 fcb 0x35,0x25,0x00,0x00,0x00,0x00,0x00,0x00 ; 5 % | |
240 fcb 0x36,0x26,0x00,0x00,0x00,0x00,0x00,0x00 ; 6 & | |
241 fcb 0x37,0x27,0x00,0x00,0x00,0x00,0x00,0x00 ; 7 ' | |
242 fcb 0x38,0x28,0x00,0x00,0x00,0x00,0x00,0x00 ; 8 ( | |
243 fcb 0x39,0x29,0x00,0x00,0x00,0x00,0x00,0x00 ; 9 ) | |
244 fcb 0x3a,0x2a,0x00,0x00,0x00,0x00,0x00,0x00 ; : * | |
245 fcb 0x3b,0x2b,0x00,0x00,0x00,0x00,0x00,0x00 ; ; + | |
246 fcb 0x2c,0x3c,0x00,0x00,0x00,0x00,0x00,0x00 ; , < | |
247 fcb 0x2d,0x3d,0x00,0x00,0x00,0x00,0x00,0x00 ; - = | |
248 fcb 0x2e,0x3e,0x00,0x00,0x00,0x00,0x00,0x00 ; . > | |
249 fcb 0x2f,0x3f,0x00,0x00,0x00,0x00,0x00,0x00 ; / ? | |
250 fcb 0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d ; <ENTER> | |
251 fcb 0x0c,0x5c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c ; <CLEAR> | |
252 fcb 0x03,0x03,0x1b,0x1b,0x9b,0xbb,0xdb,0xfb ; <BREAK> | |
253 fcb 0x1c,0x1d,0x1c,0x1d,0x00,0x00,0x00,0x00 ; <F1> | |
254 fcb 0x1e,0x1f,0x1e,0x1f,0x00,0x00,0x00,0x00 ; <F2> | |
255 *pragmapop list |