OpenCores
URL https://opencores.org/ocsvn/thor/thor/trunk

Subversion Repositories thor

[/] [thor/] [trunk/] [software/] [source/] [keyboard.asm] - Blame information for rev 41

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 24 robfinch
 
2
; ============================================================================
3
;        __
4
;   \\__/ o\    (C) 2015  Robert Finch, Stratford
5
;    \  __ /    All rights reserved.
6
;     \/_//     robfinch@finitron.ca
7
;       ||
8
;
9
;
10
; This source file is free software: you can redistribute it and/or modify
11
; it under the terms of the GNU Lesser General Public License as published
12
; by the Free Software Foundation, either version 3 of the License, or
13
; (at your option) any later version.
14
;
15
; This source file is distributed in the hope that it will be useful,
16
; but WITHOUT ANY WARRANTY; without even the implied warranty of
17
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
; GNU General Public License for more details.
19
;
20
; You should have received a copy of the GNU General Public License
21
; along with this program.  If not, see .
22
;
23
;
24
; KeyState1_
25
; 76543210
26
;        + = keyup
27
;
28
; KeyState2_
29
; 76543210
30
; |||||||+ = shift
31
; ||||||+- = alt
32
; |||||+-- = control
33
; ||||+--- = numlock
34
; |||+---- = capslock
35
; ||+----- = scrolllock
36
; |+------ =
37
; +------- = extended
38
;
39
; ============================================================================
40
;
41
; Static Device Control Block for Keyboard
42
;
43
                align   8
44
                byte    8,"keyboard   "         ; DCB_Name      string: first byte is length, 11 chars max
45
                dh              0                                        ; DCB_Type                      0 = character
46
                dw              0                                        ; DCB_nBPB
47
                dw              0                                        ; DCB_LastErc           last error code
48
                dw              0                                        ; DCB_StartBlock        starting block number (partitioned devices)
49
                dw              0                                        ; DCB_nBlocks           number of blocks on device
50
                dw              KeybdCmdProc            ; DCB_pCmdProc          pointer to command processor routine
51
                byte    1                                       ; DCB_ReentCount        re-entrancy count (1 to 255)
52
                byte    0                                        ; DCB_fSingleUser
53
                fill.b  6,0
54
                dw              0                                        ; DCB_hJob                      handle to associated job
55
                dw              0                                        ; DCB_Mbx
56
                dw              0                                        ; DCB_pSema                     pointer to device semaphore
57
                dw              0                                        ; DCB_Resv1                     reserved
58
                dw              0                                        ; DCB_Resv2                     reserved
59
 
60
        align   8
61
kbd_jmp:
62
                jmp             KeybdIRQ[c0]
63
 
64
KeybdCmdProc:
65
                rts
66
 
67
KeybdInit:
68
                addui   sp,sp,#-8
69
                sws             c1,[sp]
70
                lla             r1,cs:kbd_jmp           ; set interrupt vector
71
                ldi             r2,#194
72
                bsr             set_vector
73
                lws             c1,[sp]
74
                addui   sp,sp,#8
75
KeybdClearBuf:
76
                lw              r29,zs:RunningJCB_
77
                sb              r0,zs:JCB_KeybdHead[r29]        ; clear buffer pointers
78
                sb              r0,zs:JCB_KeybdTail[r29]
79
                sb              r0,zs:JCB_KeyState1[r29]
80
                sb              r0,zs:JCB_KeyState2[r29]
81
                sb              r0,zs:JCB_KeybdLEDs[r29]
82
                ldi             r1,#64
83
                sb              r1,zs:JCB_KeybdBufSz[r29]
84
                rts
85
 
86
; Check if a key is available
87
; Returns:
88
;       r1 = non-zero if key is available, otherwise zero
89
;
90
public KeybdCheckForKey
91
                addui   sp,sp,#-8
92
                sw              r2,[sp]
93
                lw              r2,zs:RunningJCB_
94
                lcu             r1,zs:JCB_KeybdHead[r2]
95
                shrui   r2,r1,#8
96
                zxb             r1,r1
97
                eor             r1,r1,r2
98
                lw              r2,[sp]
99
                addui   sp,sp,#8
100
                rts
101
endpublic
102
 
103
public KeybdGetCharWait:
104
                ldi             r1,#-1
105
                lw              r29,zs:RunningJCB_
106
                sb              r1,zs:JCB_KeybdWaitFlag[r29]
107
                br              KeybdGetChar
108
endpublic
109
 
110
public KeybdGetCharNoWait:
111
                lw              r1,zs:RunningJCB_
112
                sb              r0,zs:JCB_KeybdWaitFlag[r1]
113
                br              KeybdGetChar
114
endpublic
115
 
116
; Wait for a keyboard character to be available
117
; Returns (-1) if no key available
118
; Return key >= 0 if key is available
119
;
120
;
121
KeybdGetChar:
122
KeybdGetChar1:
123
                addui   sp,sp,#-64
124
                sw              r2,[sp]
125
                sws             c1,8[sp]                ; save off link register
126
                sws             hs,16[sp]
127
                sws             hs.lmt,24[sp]
128
                sw              r3,32[sp]
129
                sws             ds,40[sp]
130
                sws             ds.lmt,48[sp]
131
                ldis    hs,#$FFD00000
132
                ldis    hs.lmt,#$100000
133
                lws             ds,zs:RunningJCB_
134
                ldis    ds.lmt,#$10000
135
.0002:
136
.0003:
137
                ; Allow for some interruptible code to occur
138
                nop nop nop     nop
139
                nop     nop     nop     nop
140
                nop     nop     nop     nop
141
 
142
                ; Get head and tail pointers as a single load
143
                ; then separate
144
;               sei
145
                sync
146
                lcu             r1,JCB_KeybdHead        ; 1 memory op instead of 2
147
                shrui   r2,r1,#8                ; r2 = tail index
148
                zxb             r1,r1                   ; r1 = head index
149
                cmp             p0,r1,r2                ; is there anything in the buffer ?
150
p0.ne   br              .0006                   ; yes, branch
151
                cli
152
                lb              r1,JCB_KeybdWaitFlag    ; are we waiting indefinitely for a key ?
153
                tst             p0,r1
154
p0.lt   br              .0003                   ; if yes, branch
155
                br              .0008                   ; otherwise exit no key available
156
.0006:
157
                ldi             r1,#$300
158
                sc              r1,hs:LEDS
159
                lbu             r1,JCB_KeybdBuf[r2]     ; get scan code from buffer
160
                lbu             r3,JCB_KeybdBufSz
161
                addui   r2,r2,#1                ; increment tail index
162
                cmp             p0,r2,r3
163
p0.geu  mov             r2,r0                   ; take modulus
164
                sb              r2,JCB_KeybdTail        ; and store it back
165
                cli
166
.0001:
167
                cmp             p0,r1,#SC_KEYUP ; keyup scan code ?
168
p0.eq   br              .doKeyup
169
                cmp             p0,r1,#SC_EXTEND; extended scan code ?
170
p0.eq   br              .doExtend
171
                cmp             p0,r1,#$14              ; control ?
172
p0.eq   br              .doCtrl
173
                cmp             p0,r1,#$12              ; left shift
174
p0.eq   br              .doShift
175
                cmp             p0,r1,#$59              ; right shift
176
p0.eq   br              .doShift
177
                cmp             p0,r1,#SC_NUMLOCK
178
p0.eq   br              .doNumLock
179
                cmp             p0,r1,#SC_CAPSLOCK
180
p0.eq   br              .doCapsLock
181
                cmp             p0,r1,#SC_SCROLLLOCK
182
p0.eq   br              .doScrollLock
183
                cmp             p0,r1,#SC_ALT
184
p0.eq   br              .doAlt
185
                lb              r2,JCB_KeyState1
186
                sb              r0,JCB_KeyState1
187
                biti    p0,r2,#1                ; was keyup set ?
188
p0.ne   br              .0003                   ; if yes, ignore and branch back
189
                lb              r2,JCB_KeyState2        ; Is extended code ?
190
                biti    p0,r2,#$80
191
p0.eq   br              .0010
192
                lb              r2,JCB_KeyState2        ; clear extended bit
193
                andi    r2,r2,#$7F
194
                sb              r2,JCB_KeyState2
195
                sb              r0,JCB_KeyState1        ; clear keyup
196
                andi    r1,r1,#$7F
197
                lbu             r1,cs:keybdExtendedCodes_[r1]
198
                br              .0008
199
.0010:
200
                biti    p0,r2,#4                ; Is Cntrl down ?
201
p0.eq   br              .0009
202
                andi    r1,r1,#$7F
203
                lbu             r1,cs:keybdControlCodes_[r1]
204
                br              .0008
205
.0009:
206
                biti    p0,r2,#33               ; Is shift or CAPS-Lock down ?
207
p0.ne   lbu             r1,cs:shiftedScanCodes_[r1]
208
p0.eq   lbu             r1,cs:unshiftedScanCodes_[r1]
209
.0008:
210
                lw              r2,[sp]
211
                lws             c1,8[sp]
212
                lws             hs,16[sp]
213
                lws             hs.lmt,24[sp]
214
                lw              r3,32[sp]
215
                lws             ds,40[sp]
216
                lws             ds.lmt,48[sp]
217
                addui   sp,sp,#64
218
                rts
219
 
220
.doKeyup:
221
                lb              r2,JCB_KeyState1        ; set keyup flag
222
                ori             r2,r2,#1
223
                sb              r2,JCB_KeyState1
224
                br              .0003
225
.doExtend:
226
                lb              r2,JCB_KeyState2
227
                ori             r2,r2,#$80
228
                sb              r2,JCB_KeyState2
229
                br              .0003
230
.doCtrl:
231
                lb              r2,JCB_KeyState1
232
                biti    p0,r2,#1
233
                lbu             r2,JCB_KeyState2
234
p0.eq   ori             r2,r2,#4
235
p0.ne   andi    r2,r2,#~4
236
                sb              r2,JCB_KeyState2
237
                br              .0003
238
.doAlt:
239
                lb              r2,JCB_KeyState1
240
                biti    p0,r2,#1
241
                lbu             r2,JCB_KeyState2
242
p0.eq   ori             r2,r2,#2
243
p0.ne   andi    r2,r2,#~2
244
                sb              r2,JCB_KeyState2
245
                br              .0003
246
.doShift:
247
                lb              r2,JCB_KeyState1
248
                biti    p0,r2,#1
249
                lbu             r2,JCB_KeyState2
250
p0.eq   ori             r2,r2,#1
251
p0.ne   andi    r2,r2,#~1
252
                sb              r2,JCB_KeyState2
253
                br              .0003
254
.doNumLock:
255
                lbu             r2,JCB_KeyState2
256
                eori    r2,r2,#16
257
                sb              r2,JCB_KeyState2
258
                bsr             KeybdSetLEDStatus
259
                br              .0003
260
.doCapsLock:
261
                lbu             r2,JCB_KeyState2
262
                eori    r2,r2,#32
263
                sb              r2,JCB_KeyState2
264
                bsr             KeybdSetLEDStatus
265
                br              .0003
266
.doScrollLock:
267
                lbu             r2,JCB_KeyState2
268
                eori    r2,r2,#64
269
                sb              r2,JCB_KeyState2
270
                bsr             KeybdSetLEDStatus
271
                br              .0003
272
 
273
;------------------------------------------------------------------------------
274
; Set the keyboard LED status leds.
275
; Trashes r1, p0
276
;------------------------------------------------------------------------------
277
 
278
KeybdSetLEDStatus:
279
                addui   r27,r27,#-8
280
                sws             c1,[r27]
281
                sb              r0,KeybdLEDs
282
                lb              r1,JCB_KeyState2
283
                biti    p0,r1,#16
284
p0.ne   lb              r1,KeybdLEDs    ; set bit 1 for Num lock, 0 for scrolllock , 2 for caps lock
285
p0.ne   ori             r1,r1,#2
286
p0.ne   sb              r1,KeybdLEDs
287
                lb              r1,JCB_KeyState2
288
                biti    p0,r1,#32
289
p0.ne   lb              r1,KeybdLEDs
290
p0.ne   ori             r1,r1,#4
291
p0.ne   sb              r1,KeybdLEDs
292
                lb              r1,JCB_KeyState2
293
                biti    p0,r1,#64
294
p0.ne   lb              r1,KeybdLEDs
295
p0.ne   ori             r1,r1,#1
296
p0.ne   sb              r1,KeybdLEDs
297
                ldi             r1,#$ED
298
                sb              r1,hs:KEYBD             ; set status LEDs command
299
                bsr             KeybdWaitTx
300
                bsr             KeybdRecvByte
301
                cmpi    p0,r1,#$FA
302
                lb              r1,KeybdLEDs
303
                sb              r1,hs:KEYBD
304
                bsr             KeybdWaitTx
305
                bsr             KeybdRecvByte
306
                lws             c1,[r27]
307
                addui   r27,r27,#8
308
                rts
309
 
310
;------------------------------------------------------------------------------
311
; Receive a byte from the keyboard, used after a command is sent to the
312
; keyboard in order to wait for a response.
313
;
314
; Returns:
315
;       r1 >= 0 if a scancode is available
316
;   r1 = -1 on timeout
317
;------------------------------------------------------------------------------
318
;
319
KeybdRecvByte:
320
                addui   r27,r27,#-16
321
                sws             c1,8[r27]
322
                sw              r3,[r27]
323
                ldi             r3,#20                  ; wait up to .2s
324
.0003:
325
                bsr             KeybdWaitBusy
326
                lb              r1,hs:KEYBD+1   ; wait for response from keyboard
327
                biti    p0,r1,#$80              ; is input buffer full ?
328
p0.ne   br              .0004                   ; yes, branch
329
                bsr             Wait10ms                ; wait a bit
330
                addui   r3,r3,#-1
331
                tst             p0,r3
332
p0.ne   br              .0003                   ; go back and try again
333
                lw              r3,[r27]                ; timeout
334
                lws             c1,8[r27]
335
                addui   r27,r27,#16
336
                ldi             r1,#-1
337
                rts
338
.0004:
339
                lvb             r1,hs:KEYBD             ; get scancode
340
                zxb             r1,r1                   ; convert to unsigned char
341
                sb              r0,hs:KEYBD+1   ; clear recieve state
342
                lw              r3,[r27]
343
                lws             c1,8[r27]
344
                addui   r27,r27,#16
345
                rts                                             ; return char in r1
346
 
347
;------------------------------------------------------------------------------
348
; Wait until the keyboard isn't busy anymore
349
; Wait until the keyboard transmit is complete
350
; Returns:
351
;    r1 >= 0 if successful
352
;        r1 < 0 if timed out
353
;------------------------------------------------------------------------------
354
;
355
KeybdWaitBusy:                          ; alias for KeybdWaitTx
356
KeybdWaitTx:
357
                addui   r27,r27,#-16
358
                sws             c1,8[r27]
359
                sw              r3,[r27]
360
                ldi             r3,#10                  ; wait a max of .1s
361
.0001:
362
                lvb             r1,hs:KEYBD+1
363
                biti    p0,r1,#$40              ; check for transmit busy bit
364
p0.eq   br              .0002                   ; branch if bit clear
365
                bsr             Wait10ms                ; delay a little bit
366
                addui   r3,r3,#-1               ; go back and try again
367
                tst             p0,r3
368
p0.ne   br              .0001
369
                lw              r3,[r27]                ; timed out
370
                lws             c1,8[r27]
371
                addui   r27,r27,#16
372
                ldi             r1,#-1                  ; return -1
373
                rts
374
.0002:
375
                lw              r3,[r27]                ; wait complete, return
376
                lws             c1,8[r27]               ; restore return address
377
                ldi             r1,#0                   ; return 0 for okay
378
                addui   r27,r27,#16
379
                rts
380
 
381
;------------------------------------------------------------------------------
382
; Delay for about 10 ms.
383
;------------------------------------------------------------------------------
384
 
385
Wait10ms:
386
                addui   r27,r27,#-16
387
                sw              r1,8[r27]
388
                sw              r2,[r27]
389
                mfspr   r1,tick
390
                addui   r1,r1,#250000   ; 10ms at 25 MHz
391
.0001:
392
                mfspr   r2,tick
393
                cmp             p0,r2,r1
394
p0.lt   br              .0001
395
                lw              r2,[r27]
396
                lw              r1,8[r27]
397
                addui   r27,r27,#16
398
                rts
399
 
400
;------------------------------------------------------------------------------
401
; KeybdIRQ:
402
;     Store scancode in keyboard buffer. Also check for the special key
403
; sequences ALT-tab and CTRL-ALT-del. If the keyboard buffer is full then
404
; the newest keystrokes are lost.
405
;------------------------------------------------------------------------------
406
 
407
KeybdIRQ:
408
                sync
409
                addui   r31,r31,#-80
410
                sws             p0,[r31]
411
                sw              r1,8[r31]
412
                sw              r2,16[r31]
413
                sws             hs,24[r32]
414
                sw              r3,32[r31]
415
                sws             ds,40[r31]
416
                sws             ds.lmt,48[r31]
417
                sws             hs.lmt,56[r31]
418
                sw              r4,64[r31]
419
                sw              r5,72[r31]
420
 
421
                ldis    hs,#$FFD00000
422
                ldis    hs.lmt,#$100000
423
                lws             ds,zs:IOFocusNdx_       ; set input to correct keyboard buffer
424
                ldis    ds.lmt,#$10000
425
                lvb             r1,hs:KEYBD                     ; get the scan code
426
                sb              r0,hs:KEYBD+1           ; clear interrupt status
427
                lcu             r2,JCB_KeybdHead        ; get head/tail index (1 memory op)
428
                shrui   r3,r2,#8                        ; r3 = tail
429
                zxb             r2,r2                           ; r2 = head
430
                mov             r4,r2                           ; make copy of old head index
431
                addui   r2,r2,#1                        ; increment head index
432
                lbu             r5,JCB_KeybdBufSz
433
                cmp             p0,r2,r5
434
p0.geu  mov             r2,r0                           ; modulus buffer size
435
                cmp             p0,r2,r3                        ; is there room in buffer ?
436
p0.ne   sb              r1,JCB_KeybdBuf[r4]     ; store scan code in buffer
437
p0.ne   sb              r2,JCB_KeybdHead        ; save buffer index
438
                lb              r2,JCB_KeyState2        ; check for ALT
439
                biti    p0,r2,#2
440
p0.eq   br              .exit
441
                cmpi    p0,r1,#SC_TAB
442
p0.eq   inc.b   zs:iof_switch_          ; set IOF switch flag if ALT-Tab pressed.
443
p0.eq   br              .exit
444
                cmpi    p0,r1,#SC_DEL
445
p0.ne   br              .exit
446
                biti    p0,r2,#4                        ; check for CTRL-ALT-DEL
447
p0.ne   jmp             cold_start
448
.exit:
449
                lws             p0,[r31]
450
                lw              r1,8[r31]
451
                lw              r2,16[r31]
452
                lws             hs,24[r32]
453
                lw              r3,32[r31]
454
                lws             ds,40[r31]
455
                lws             ds.lmt,48[r31]
456
                lws             hs.lmt,56[r31]
457
                lw              r4,64[r31]
458
                lw              r5,72[r31]
459
                addui   r31,r31,#80
460
                sync
461
                rti

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.