Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | \ ========== Copyright Header Begin ========================================== |
2 | \ | |
3 | \ Hypervisor Software File: usbkeyin.fth | |
4 | \ | |
5 | \ Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. | |
6 | \ | |
7 | \ - Do no alter or remove copyright notices | |
8 | \ | |
9 | \ - Redistribution and use of this software in source and binary forms, with | |
10 | \ or without modification, are permitted provided that the following | |
11 | \ conditions are met: | |
12 | \ | |
13 | \ - Redistribution of source code must retain the above copyright notice, | |
14 | \ this list of conditions and the following disclaimer. | |
15 | \ | |
16 | \ - Redistribution in binary form must reproduce the above copyright notice, | |
17 | \ this list of conditions and the following disclaimer in the | |
18 | \ documentation and/or other materials provided with the distribution. | |
19 | \ | |
20 | \ Neither the name of Sun Microsystems, Inc. or the names of contributors | |
21 | \ may be used to endorse or promote products derived from this software | |
22 | \ without specific prior written permission. | |
23 | \ | |
24 | \ This software is provided "AS IS," without a warranty of any kind. | |
25 | \ ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, | |
26 | \ INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A | |
27 | \ PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN | |
28 | \ MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR | |
29 | \ ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR | |
30 | \ DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN | |
31 | \ OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR | |
32 | \ FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE | |
33 | \ DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, | |
34 | \ ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF | |
35 | \ SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. | |
36 | \ | |
37 | \ You acknowledge that this software is not designed, licensed or | |
38 | \ intended for use in the design, construction, operation or maintenance of | |
39 | \ any nuclear facility. | |
40 | \ | |
41 | \ ========== Copyright Header End ============================================ | |
42 | \ id: @(#)usbkeyin.fth 1.19 06/12/15 | |
43 | \ purpose: | |
44 | \ copyright: Copyright 2006 Sun Microsystems, Inc. All Rights Reserved | |
45 | ||
46 | ||
47 | \ headers \ XXX for debugging | |
48 | external | |
49 | ||
50 | 1 instance value ha-toggle | |
51 | : our-toggle ( -- new-toggle ) | |
52 | ha-toggle if | |
53 | 0 dup to ha-toggle ( 0-toggle ) | |
54 | else | |
55 | 1 dup to ha-toggle ( 1-toggle ) | |
56 | then | |
57 | ; | |
58 | ||
59 | ||
60 | : get-keynumber ( index -- key# ) | |
61 | curr-byte1-bfaddr + c@ | |
62 | ; | |
63 | ||
64 | ||
65 | \ Once the current down keys have been evaluated and dealt with, they | |
66 | \ become the previous report's keys, so copy all relevant data. | |
67 | \ | |
68 | : copy-curr-to-prev ( -- ) | |
69 | ||
70 | /key-info-buff 0 do | |
71 | keybuff-curr^v i + c@ keybuff-prev i + c! | |
72 | loop | |
73 | ||
74 | shiftflag to pr-shiftflag stopflag to pr-stopflag | |
75 | ctrlflag to pr-ctrlflag altgflag to pr-altgflag | |
76 | powerflag to pr-powerflag monflag to pr-monflag | |
77 | ; | |
78 | ||
79 | ||
80 | ||
81 | \ Increment the variable (that's kept in the key input buffer) which | |
82 | \ keeps track of how many nonspecial keys are down in the current report. | |
83 | \ | |
84 | : count-curr-as-nonspcl ( -- ) | |
85 | keybuff-curr^v >#regl-keys-dn ( regkey-cnt-adr ) | |
86 | dup c@ 1+ swap c! | |
87 | ; | |
88 | ||
89 | ||
90 | \ If the keynumber matches for a special key ( Control, Shift - including | |
91 | \ capslock, Altg, Power, Mon or Stop ) then set the index from the 1st | |
92 | \ keybyte buff location into its "flag". | |
93 | \ At the same time keep a count of the non-special keys. | |
94 | \ | |
95 | \ Note that in a way this is cheating because we haven't used the | |
96 | \ keymap to get the "intent" of the key# - we've explicitly associated | |
97 | \ some of the key#s with their known actions. This will be OK for two | |
98 | \ reasons; 1) We won't take action on the special keys (except Stop) | |
99 | \ until later when we're applying the "rules", and 2) regardless of | |
100 | \ country layout, the key#/action for each of these keys will always | |
101 | \ remain constant. So, for example, if we get a key# of 102 (power | |
102 | \ key), it will only matter to us later if a shift key is also present. | |
103 | \ | |
104 | : chk-n-set-spcl|regl ( -- ) | |
105 | 0 keybuff-curr^v >#regl-keys-dn c! \ init count to 0 | |
106 | curr-#ksdn-bfaddr c@ ( #downkeys ) | |
107 | 0 do | |
108 | true i get-keynumber ( yes-spcl-flag key# ) | |
109 | ||
110 | case | |
111 | \ Note that the case doesn't contain values for rt shift or rt | |
112 | \ control since we explicitly convert the modifier byte's bits | |
113 | \ to be left shift and left control (in "add-key-to-array"). | |
114 | d# 225 of i to shiftflag endof \ left shift | |
115 | d# 224 of i to ctrlflag endof \ left control | |
116 | d# 230 of i to altgflag endof \ right alt == Altgraph | |
117 | d# 57 of i to shiftflag endof \ capslock | |
118 | d# 102 of i to powerflag endof \ power key | |
119 | d# 127 of i to monflag endof \ mute(nonshift) | |
120 | \ mon-off-on(shift) | |
121 | d# 120 of i to stopflag endof \ stop (L1) key down | |
122 | ||
123 | nip false swap ( no-spcl-flag key# ) | |
124 | endcase ( spcl-flag? ) | |
125 | ||
126 | \ Now use the index and flag to mark the key as special or regular. | |
127 | false = if ( ) | |
128 | count-curr-as-nonspcl ( ) | |
129 | then | |
130 | loop | |
131 | ; | |
132 | ||
133 | ||
134 | \ If the control key is down and it is in effect (it is the highest | |
135 | \ priority control key down) then apply the control offset to the | |
136 | \ keyvalue. | |
137 | \ | |
138 | : chk&adjust4ctrl ( keyvalue' -- keyvalue ) | |
139 | ||
140 | ctrl-in-effect if | |
141 | ctrlflag -1 > if | |
142 | h# 1f and ( keyvalue ) | |
143 | then | |
144 | then | |
145 | ; | |
146 | ||
147 | ||
148 | \ Take the key# (prior to conversion to the ascii char) and see if it was | |
149 | \ in the previous report. | |
150 | \ | |
151 | : in-last-rep? ( key# -- flag ) | |
152 | false swap ( flag' key# ) | |
153 | keybuff-prev >#keys-down c@ dup if ( flag' key# #prev-kys-dn ) | |
154 | 0 do ( flag' key# ) | |
155 | dup prev-byte1-bfaddr i + c@ = if ( flag' key# ) | |
156 | nip true swap ( true-flag key# ) | |
157 | then ( flag' key# ) | |
158 | loop 1 ( flag' key# dropjunk ) | |
159 | then ( flag' key# something ) | |
160 | 2drop ( flag ) | |
161 | ; | |
162 | ||
163 | ||
164 | : set-repeating-flag \ ( prpt|-1 rpting? newk|-1 key# keyval -- | |
165 | \ -- prpt|-1 rpting?' newk|-1 ) | |
166 | \ drop rot true or -rot | |
167 | 2drop >r true or r> | |
168 | ; | |
169 | ||
170 | ||
171 | : chknset-potential-rpt \ ( prpt|-1 rpting? newk|-1 k# keyval -- | |
172 | \ -- prpt rpting? newk|-1 ) | |
173 | >r drop ( prpt|-1 rpting? newk|-1 ) ( R: keyval ) | |
174 | rot dup -1 = if ( rpting? newk|-1 prpt|-1 ) ( R: keyval ) | |
175 | drop r> ( rpting? newk|-1 prpt ) | |
176 | else | |
177 | r> drop ( rpting? newk|-1 prpt ) | |
178 | then | |
179 | -rot ( prpt rpting? newk|-1 ) | |
180 | ; | |
181 | ||
182 | ||
183 | \ Set the keval as the newkey, but only if another keyval from the current | |
184 | \ report hasn't already been set. (The first "new" key found is used.) | |
185 | \ | |
186 | : chknset-new-keyval-rcvd \ ( prpt|-1 rpting? newk|-1 keyval -- | |
187 | \ -- prpt|-1 rpting? newkey' ) | |
188 | swap dup -1 = if ( prpt|-1 rpting? keyval newk|-1 ) | |
189 | drop ( prpt|-1 rpting? newkey ) | |
190 | else | |
191 | nip ( prpt|-1 rpting? prev-newkey ) | |
192 | then | |
193 | ; | |
194 | ||
195 | ||
196 | : queue?-adjust-flags \ ( prpt|-1 rpting? newkey|-1 key# keyval -- | |
197 | \ -- prpt|-1' rpting?' newkey|-1' ) | |
198 | dup curr-repeat-key = if ( prpt|-1 rpting? nwkey|-1 k# keyval ) | |
199 | set-repeating-flag ( prpt|-1 rpting! newkey|-1 ) | |
200 | exit | |
201 | then ( prpt|-1 rpting? nwkey|-1 k# keyval ) | |
202 | ||
203 | over in-last-rep? if ( prpt|-1 rpting? nwkey|-1 k# keyval ) | |
204 | chknset-potential-rpt ( prpt' rpting? newkey|-1 ) | |
205 | exit | |
206 | then nip ( prpt|-1 rpting? newkey|-1 keyval ) | |
207 | ||
208 | dup bput ( prpt|-1 rpting? newkey|-1 keyval ) | |
209 | chknset-new-keyval-rcvd ( prpt|-1 rpting? newkey' ) | |
210 | ; | |
211 | ||
212 | ||
213 | \ Go through the list of keys which are down, queuing any new keys after | |
214 | \ they've been converted to ascii chars. Three items are returned; | |
215 | \ 1) The first key in the current report which was also seen in the | |
216 | \ last report - but which is not the repeat key, or -1 if those | |
217 | \ criteria are not met. | |
218 | \ 2) A true/false flag which indicates if the repeat key was found in | |
219 | \ in this latest report. | |
220 | \ 3) The first "new" key in the report, or a -1 if there were no new | |
221 | \ keys seen. | |
222 | \ | |
223 | defer convert ' noop is convert | |
224 | ||
225 | 0 instance value shift-map? | |
226 | 0 instance value altg-map? | |
227 | ||
228 | : setup-flags ( -- altg? shift? ) | |
229 | altg-map? shift-map? | |
230 | ; | |
231 | ||
232 | : queue-new-keys ( -- potrptkey|-1 repeating? newkey|-1 ) | |
233 | -1 false -1 ( prpt|-1 rpting? newk|-1 ) | |
234 | ||
235 | curr-#ksdn-bfaddr c@ ( prpt|-1 rpting? newk|-1 #dnkeys ) | |
236 | 0 do ( prpt|-1 rpting? newk|-1 ) | |
237 | i get-keynumber dup ( prpt|-1 rpting? newk|-1 k# k# ) | |
238 | setup-flags ( prpt|-1 rpting? newk|-1 k# k# altg? shift? ) | |
239 | convert ( prpt|-1 rpting? newk|-1 k# keyval ) | |
240 | chk&adjust4ctrl ( prpt|-1 rpting? newk|-1 k# keyval' ) | |
241 | queue?-adjust-flags ( prpt|-1' rpting?' newk|-1' ) | |
242 | loop | |
243 | ; | |
244 | ||
245 | ||
246 | \ There's a new key, so mark it and add in the initial delay time | |
247 | \ for the repeat timer mechanism. | |
248 | \ | |
249 | : new-repeat-key ( keyvalue -- ) | |
250 | to curr-repeat-key ( ) | |
251 | get-msecs d# 700 + to key-repeat-time | |
252 | ; | |
253 | ||
254 | ||
255 | \ Using the specified keymap, have the regular keys queued and then | |
256 | \ set the repeat key. The algorithm for determining the repeat key is | |
257 | \ as follows; | |
258 | \ 1) If a new keyvalue is found that was not in the last report then | |
259 | \ set it as the new repeat key. | |
260 | \ 2) If no new keyvalue was found, see if the currently repeating | |
261 | \ keyvalue was seen - if so take no action so that the timers will | |
262 | \ be continuous. | |
263 | \ 3) If there's no new key, and the currently repeating key was not | |
264 | \ seen, it's still possible that a keyvalue that was found in the | |
265 | \ last report is still in the current report, and if so then that | |
266 | \ keyvalue becomes the repeat key. (This would occur if the user | |
267 | \ pressed two or more keys simultaneously, but then released one | |
268 | \ or more keys - including the repeat key, but still kept one or | |
269 | \ more keys pressed.) | |
270 | \ | |
271 | : process-dn-keys ( -- ) | |
272 | queue-new-keys ( potrptkey|-1 repeating? newkey|-1 ) | |
273 | ||
274 | dup -1 > if ( potrptkey|-1 repeating? newkey|-1 ) | |
275 | new-repeat-key ( potrptkey|-1 repeating? ) | |
276 | 2drop exit | |
277 | then drop ( potrptkey|-1 repeating? ) | |
278 | ||
279 | if ( potrptkey|-1 ) | |
280 | drop exit \ The "old" repeat key continues... | |
281 | then ( potrptkey|-1 ) | |
282 | ||
283 | dup -1 = if ( potrptkey|-1 ) | |
284 | drop ( ) | |
285 | nokey to curr-repeat-key | |
286 | else | |
287 | new-repeat-key ( ) | |
288 | then | |
289 | ; | |
290 | ||
291 | ||
292 | \ The only special key down is Stop, and at least 1 regular key is down. | |
293 | \ Stop-a was taken care of elsewhere. Not yet certain if we're going | |
294 | \ to attempt to put in Stop-d, Stop-n or Stop-f, so ignore for now. | |
295 | \ | |
296 | : eval-stop+keys ( table-offset -- ) | |
297 | process-dn-keys ( ) | |
298 | ; | |
299 | ||
300 | : stop-&-regl-dn ( -- ) | |
301 | false to shift-map? false to altg-map? eval-stop+keys | |
302 | ; | |
303 | ||
304 | ||
305 | : shift-&-regl-dn ( -- ) | |
306 | true to shift-map? false to altg-map? process-dn-keys | |
307 | ; | |
308 | ||
309 | ||
310 | : altg-&-regl-dn ( -- ) | |
311 | false to shift-map? true to altg-map? process-dn-keys | |
312 | ; | |
313 | ||
314 | ||
315 | \ Find out if each of the xspecial keys (don't bother with the monitor or | |
316 | \ power keys) that are currently down were also down in the last report | |
317 | \ - if so return a true flag. | |
318 | \ | |
319 | : all-spcl-prev-dn? ( -- flag ) | |
320 | true ( flag' ) | |
321 | stopflag -1 <> if | |
322 | pr-stopflag -1 <> and ( flag' ) | |
323 | then | |
324 | shiftflag -1 <> if | |
325 | pr-shiftflag -1 <> and ( flag' ) | |
326 | then | |
327 | ctrlflag -1 <> if | |
328 | pr-ctrlflag -1 <> and ( flag' ) | |
329 | then | |
330 | altgflag -1 <> if | |
331 | pr-altgflag -1 <> and ( flag ) | |
332 | then | |
333 | ; | |
334 | ||
335 | ||
336 | : check-shift-power&mon ( -- ) | |
337 | ||
338 | powerflag -1 > if turn-me-off then | |
339 | monflag -1 > if toggle-mon then | |
340 | ; | |
341 | ||
342 | ||
343 | : do-shift-&-regl-dn ( -- ) | |
344 | check-shift-power&mon shift-&-regl-dn | |
345 | ; | |
346 | ||
347 | ||
348 | \ Determine the highest priority spcecial key that is down so that only | |
349 | \ it will be considered when we evaluate the "normal" keys that will go | |
350 | \ into the queue. | |
351 | \ | |
352 | : use-hipri-spcl ( -- ) | |
353 | stopflag -1 > if | |
354 | stop-&-regl-dn ( ) | |
355 | exit | |
356 | then | |
357 | ||
358 | shiftflag -1 > if | |
359 | do-shift-&-regl-dn ( ) | |
360 | exit | |
361 | then | |
362 | ||
363 | ctrlflag -1 > if | |
364 | -1 to ctrl-in-effect ( ) | |
365 | shift-&-regl-dn ( ) | |
366 | 0 to ctrl-in-effect ( ) | |
367 | exit | |
368 | then | |
369 | ||
370 | altgflag -1 > if | |
371 | altg-&-regl-dn ( ) | |
372 | exit | |
373 | then | |
374 | ; | |
375 | ||
376 | ||
377 | ||
378 | \ Return true if the current flag is set and the previous flag is not set. | |
379 | \ | |
380 | : only-curr-set? ( curr-flag-val|-1 prev-flag-val|-1 -- flag ) | |
381 | -1 = ( curr-flag-val flag' ) | |
382 | swap -1 > and | |
383 | ; | |
384 | ||
385 | ||
386 | \ One or more special keys down. If only one is new then ignore the | |
387 | \ rest and use the new. If more than one special key is new then use | |
388 | \ the one with the highest priority. Note that checking of Stop-a was | |
389 | \ done prior to arriving here. | |
390 | \ | |
391 | : spcl-keys-dn ( -- ) | |
392 | ||
393 | all-spcl-prev-dn? if ( ) | |
394 | \ Since there are no new special keys, we're going to select the | |
395 | \ highest priority key as the one to use. | |
396 | use-hipri-spcl ( ) | |
397 | else | |
398 | \ Find out which of the special keys are "new" and select the | |
399 | \ highest priority key from that one. | |
400 | ||
401 | stopflag pr-stopflag only-curr-set? if | |
402 | stop-&-regl-dn ( ) | |
403 | exit | |
404 | then | |
405 | ||
406 | shiftflag pr-shiftflag only-curr-set? if | |
407 | do-shift-&-regl-dn ( ) | |
408 | exit | |
409 | then | |
410 | ||
411 | ctrlflag pr-ctrlflag only-curr-set? if | |
412 | -1 to ctrl-in-effect ( ) | |
413 | shift-&-regl-dn ( ) | |
414 | 0 to ctrl-in-effect ( ) | |
415 | exit | |
416 | then | |
417 | ||
418 | \ If none of the above-three are the new down special then it must | |
419 | \ be the AltGraph key. | |
420 | altg-&-regl-dn ( ) | |
421 | then | |
422 | ; | |
423 | ||
424 | ||
425 | \ Determine if special keys are present and will be used, or if there | |
426 | \ are only std keys. | |
427 | \ Note that checking of Stop-a was done prior to arriving here. | |
428 | \ | |
429 | : due-process ( #spclkeys-dn -- ) | |
430 | dup curr-#ksdn-bfaddr c@ swap ( #spclkeys-dn #keys-dn #spclkeys-dn ) | |
431 | - 0= if ( #spclkeys-dn ) | |
432 | \ Only spcl keys down. | |
433 | shiftflag -1 = if ( #spclkeys-dn ) | |
434 | \ If one of the spcl keys wasn't the shift key (indicating that a | |
435 | \ shift-power or shift-mon could be possible) then no keys from | |
436 | \ the current report will go into the queue. | |
437 | nokey to curr-repeat-key ( ) | |
438 | drop exit ( ) | |
439 | then | |
440 | then ( #spclkeys-dn ) | |
441 | ||
442 | if | |
443 | spcl-keys-dn ( ) | |
444 | else | |
445 | false to shift-map? false to altg-map? process-dn-keys | |
446 | then | |
447 | ; | |
448 | ||
449 | ||
450 | \ The Stop key is known to be down, so cycle through all down keys to | |
451 | \ see if the 'a' key is down. | |
452 | \ | |
453 | : stopA-active? ( -- StopA? ) | |
454 | false curr-#ksdn-bfaddr c@ ( StopA?' #down-keys ) | |
455 | 0 do | |
456 | i get-keynumber ( StopA?' key# ) | |
457 | 4 = if ( StopA?' ) | |
458 | true or leave ( yes-StopA ) | |
459 | then | |
460 | loop ( StopA? ) | |
461 | ; | |
462 | ||
463 | \ Check to see if alternate break chord is pressed - shift-pause | |
464 | ||
465 | : shift-pause? ( -- SPause? ) | |
466 | false curr-#ksdn-bfaddr c@ ( false #down-keys ) | |
467 | 0 do | |
468 | i get-keynumber ( false key# ) | |
469 | d# 72 = if ( false ) | |
470 | true or leave ( true-SPause? ) | |
471 | then | |
472 | loop ( SPause? ) | |
473 | ; | |
474 | ||
475 | ||
476 | ||
477 | \ If more than 1 key is down then we'll need to apply a set of "rules" | |
478 | \ that will let us know the precedence of the pressed keys. For example, | |
479 | \ there might just be several normal keys down, or there may be special | |
480 | \ keys down as well. In the case where multiple keys are reported, we'll | |
481 | \ look at the down keys in the previous report (if any) to see if it can | |
482 | \ be determined which of the current down keys are "new". | |
483 | \ | |
484 | : start-key-processing ( -- Abort-of-some-kind-requested? ) | |
485 | chk-n-set-spcl|regl ( ) | |
486 | ||
487 | shiftflag -1 > if | |
488 | shift-pause? dup if ( SPause? ) | |
489 | exit | |
490 | then | |
491 | else | |
492 | stopflag -1 > if | |
493 | stopA-active? dup if ( StopA? ) | |
494 | exit ( yes-StopA ) | |
495 | then | |
496 | else | |
497 | false ( no-stopA ) | |
498 | then | |
499 | then | |
500 | ||
501 | curr-#ksdn-bfaddr c@ ( no-StopA #down-keys ) | |
502 | keybuff-curr^v >#regl-keys-dn c@ - ( no-StopA #spclkeys-dn ) | |
503 | due-process ( no-StopA ) | |
504 | ; | |
505 | ||
506 | ||
507 | \ Sets the global offset into the current and previous report's key-down | |
508 | \ buffer to point to the 1st (of 9) key-down bytes. A pointer to the | |
509 | \ # of keys down in the current buffer is also set since it's used | |
510 | \ frequently. | |
511 | \ | |
512 | : set-oftused-buf-offsets ( -- ) | |
513 | keybuff-curr^v >kbd-in-byte1 to curr-byte1-bfaddr | |
514 | keybuff-curr^v >#keys-down to curr-#ksdn-bfaddr | |
515 | ||
516 | keybuff-prev >kbd-in-byte1 to prev-byte1-bfaddr | |
517 | ; | |
518 | ||
519 | ||
520 | \ Receive a keyvalue which represents a special key, and place it | |
521 | \ into the 1st available array position in the input key array. | |
522 | \ | |
523 | : add-key-to-array ( #dn-keys modbyte byte-to-add -- #dn-keys' modbyte ) | |
524 | swap >r ( #down-keys' byte-2-add ) | |
525 | over keybuff-curr^v >kbd-in-byte1 + ( #dn-keys' byte-2-add byteN-addr) | |
526 | c! 1+ r> ( #dn-keys' modbyte ) | |
527 | ; | |
528 | ||
529 | ||
530 | \ 1 indicates a keyboard rollover - indicating too many keys pressed or | |
531 | \ kbd is confused; 2 indicates kbd diag failure; 3 is undefined error; | |
532 | \ The rollover error seems to be cleared on next understandable keypress, | |
533 | \ but don't know about the other two. | |
534 | \ | |
535 | : kbd-err? ( key-value -- flag ) | |
536 | 4 < if true else false then | |
537 | ; | |
538 | ||
539 | ||
540 | \ The "down" keys from the latest key report are placed into one of the | |
541 | \ buffers by the HA by specifying its address in the enable-interrupts | |
542 | \ call to the HA; We then use pointers to the buffers to get at the | |
543 | \ key information. | |
544 | \ USB keyboards automatically sets individual key bytes to 0 if no key | |
545 | \ is down. | |
546 | \ Note that we'll "copy" any shift, cntrl or AltGraph keys into the | |
547 | \ 1st open slot in the array (based on the info in the modifier byte). This | |
548 | \ is being done since the code was originally written to expect those | |
549 | \ three special keys to be returned in the array rather than the modifier | |
550 | \ byte. The buffer definition was extended 3 bytes just for this purpose. | |
551 | \ | |
552 | : set-#down-keys ( -- #down-keys ) | |
553 | 0 ( #down-keys' ) | |
554 | 6 0 do | |
555 | i get-keynumber ?dup if ( #down-keys' key-value ) | |
556 | kbd-err? if ( #down-keys' ) | |
557 | drop 0 leave ( 0-down-keys ) | |
558 | else | |
559 | 1+ ( #down-keys' ) | |
560 | then | |
561 | then | |
562 | loop ( #down-keys' ) | |
563 | ||
564 | dup 0= if | |
565 | exit ( #down-keys ) | |
566 | then ( #down-keys' ) | |
567 | ||
568 | keybuff-curr^v >kbd-in-modkeys c@ ( #down-keys' modbyte ) | |
569 | ||
570 | dup h# 11 and if \ either left or rt cntrl | |
571 | d# 224 add-key-to-array ( #down-keys' modbyte ) | |
572 | \ put the byte representing a Cntrl into | |
573 | \ the 1st available key array locn | |
574 | then | |
575 | dup h# 22 and if \ either left or rt shift | |
576 | d# 225 add-key-to-array | |
577 | \ put the byte representing a Shift into | |
578 | \ the 1st available key array locn | |
579 | then | |
580 | dup h# 40 and if \ rt alt = AltGraph | |
581 | d# 230 add-key-to-array ( #down-keys' modbyte ) | |
582 | \ put the byte representing an AltGraph | |
583 | \ into the 1st available key array locn | |
584 | then | |
585 | drop ( #down-keys ) | |
586 | dup curr-#ksdn-bfaddr c! ( #down-keys ) | |
587 | ; | |
588 | ||
589 | ||
590 | \ In the buffer that holds the key information for the previous key | |
591 | \ report, zero the bytes that hold the # of down keys and # of "regular" | |
592 | \ down keys, and clear the special key flags. | |
593 | \ | |
594 | : clear-all-prev-keys ( -- ) | |
595 | 0 keybuff-prev >#keys-down c! | |
596 | 0 keybuff-prev >#regl-keys-dn c! | |
597 | -1 to pr-shiftflag -1 to pr-ctrlflag -1 to pr-altgflag | |
598 | -1 to pr-powerflag -1 to pr-monflag -1 to pr-stopflag | |
599 | ; | |
600 | ||
601 | ||
602 | \ In the buffer that holds the key information for the current key | |
603 | \ report, zero the bytes that hold the # of down keys and # of "regular" | |
604 | \ down keys, and clear the special key flags. Don't need to zero the | |
605 | \ individual key data bytes because they are set for each report by the | |
606 | \ hid kbd device. | |
607 | \ | |
608 | : clear-all-curr-keys ( -- ) | |
609 | 0 curr-#ksdn-bfaddr c! | |
610 | 0 keybuff-curr^v >#regl-keys-dn c! | |
611 | -1 to shiftflag -1 to ctrlflag -1 to altgflag | |
612 | -1 to powerflag -1 to monflag -1 to stopflag | |
613 | ; | |
614 | ||
615 | ||
616 | \ An "ack" was received from the keyboard, so we can now go and evaluate | |
617 | \ the keycodes that were received in the current report. | |
618 | \ | |
619 | : eval-key-data ( -- Stop-a? ) | |
620 | ||
621 | 0 to unstall-cnt | |
622 | set-#down-keys if ( ) | |
623 | \ If *any* key was pressed - std or "special", i.e. cntrl. | |
624 | start-key-processing ( Stop-a? ) | |
625 | copy-curr-to-prev ( Stop-a? ) | |
626 | clear-all-curr-keys ( Stop-a? ) | |
627 | else | |
628 | clear-all-prev-keys false ( no-Stop-a ) | |
629 | nokey to curr-repeat-key ( no-Stop-a ) | |
630 | then | |
631 | ; | |
632 | ||
633 | \ Clear the software state associated with the keyboard. This is called | |
634 | \ when the PROM is entered from an unknown state. | |
635 | \ | |
636 | : clear-keyboard ( -- ) | |
637 | initkeybuf \ clear the keyboard circular queue | |
638 | clear-all-curr-keys | |
639 | clear-all-prev-keys | |
640 | nokey to curr-repeat-key | |
641 | ; |