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

Subversion Repositories rf6809

[/] [rf6809/] [trunk/] [software/] [boot/] [keyboard.asm] - Blame information for rev 14

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

Line No. Rev Author Line
1 4 robfinch
; ============================================================================
2
;        __
3
;   \\__/ o\    (C) 2013-2022  Robert Finch, Waterloo
4
;    \  __ /    All rights reserved.
5
;     \/_//     robfinch@opencores.org
6
;       ||
7
;
8
;
9
;       Keyboard driver routines to interface to a PS2 style keyboard
10
; Converts the scancode to ascii
11
;
12
; This source file is free software: you can redistribute it and/or modify
13
; it under the terms of the GNU Lesser General Public License as published
14
; by the Free Software Foundation, either version 3 of the License, or
15
; (at your option) any later version.
16
;
17
; This source file is distributed in the hope that it will be useful,
18
; but WITHOUT ANY WARRANTY; without even the implied warranty of
19
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
; GNU General Public License for more details.
21
;
22
; You should have received a copy of the GNU General Public License
23
; along with this program.  If not, see .
24
;
25
; ============================================================================
26
;
27
SC_F12  EQU     $07
28
SC_C    EQU             $21
29
SC_T    EQU         $2C
30
SC_Z            EQU     $1A
31
SC_DEL  EQU                     $71     ; extend
32
SC_KEYUP        EQU             $F0     ; should be $f0
33
SC_EXTEND EQU     $E0
34
SC_CTRL EQU                     $14
35
SC_RSHIFT               EQU     $59
36
SC_NUMLOCK      EQU     $77
37
SC_SCROLLLOCK           EQU     $7E
38
SC_CAPSLOCK             EQU             $58
39
SC_ALT  EQU                     $11
40
 
41
;#define SC_LSHIFT      EQU             $12
42
;SC_DEL         EQU             $71             ; extend
43
;SC_LCTRL       EQU             $58
44
 
45
SC_TAB  EQU     $0D
46
 
47
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
48
; Recieve a byte from the keyboard, used after a command is sent to the
49
; keyboard in order to wait for a response.
50
;
51
; Parameters: none
52
; Returns: accd = recieved byte ($00 to $FF), -1 on timeout
53
; Modifies: acc
54
; Stack Space: 2 words
55
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
56
 
57
KeybdRecvByte:
58
        pshs    x
59
        ldx             #100                                            ; wait up to 1s
60
krb3:
61
        bsr             KeybdGetStatus  ; wait for response from keyboard
62
        tstb
63
        bmi             krb4                                            ; is input buffer full ? yes, branch
64
        bsr             Wait10ms                                ; wait a bit
65 14 robfinch
        dex
66 4 robfinch
        bne             krb3                                            ; go back and try again
67
        ldd             #-1                                                     ; return -1
68
        puls    x,pc
69
krb4:
70
        bsr             KeybdGetScancode
71
        puls    x,pc
72
 
73
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
74
; Send a byte to the keyboard.
75
;
76
; Parameters: accb byte to send
77
; Returns: none
78
; Modifies: none
79
; Stack Space: 0 words
80
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
81
 
82
KeybdSendByte:
83
        stb             KEYBD
84
        rts
85
 
86
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
87
; Wait until the keyboard transmit is complete
88
;
89
; Parameters: none
90
; Returns: r1 = 0 if successful, r1 = -1 timeout
91
; Modifies: r1
92
; Stack Space: 3 words
93
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
94
 
95
KeybdWaitTx:
96
        pshs    x
97
        ldx             #100                            ; wait a max of 1s
98
kwt1:
99
        bsr             KeybdGetStatus
100
        andb    #$40                            ; check for transmit complete bit; branch if bit set
101
        bne             kwt2
102
        bsr             Wait10ms                ; delay a little bit
103 14 robfinch
        dex
104 4 robfinch
        bne             kwt1                            ; go back and try again
105
        ldd             #-1                                     ; timed out, return -1
106
        puls    x,pc
107
kwt2:
108
        clra                                                    ; wait complete, return 0
109
        clrb
110
        puls    x,pc
111
 
112
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
113
; Wait for 10 ms
114
;
115
; Parameters: none
116
; Returns: none
117
; Modifies: none
118
; Stack Space: 2 words
119
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
120
 
121
Wait10ms:
122
        pshs    d
123
        lda             MSCOUNT+3
124
W10_0001:
125
        tfr             a,b
126
        subb    MSCOUNT+3
127
        cmpb    #$FFA
128
        bhi             W10_0001
129
        puls    d,pc
130
 
131
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
132
; Wait for 300 ms (256 ms)
133
;
134
; Parameters: none
135
; Returns: none
136
; Modifies: none
137
; Stack Space: 2 words
138
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
139
 
140
Wait300ms:
141
        pshs    d
142
        lda             MSCOUNT+3
143
W300_0001:
144
        tfr             a,b
145
        subb    MSCOUNT+3
146
        cmpb    #$F00
147
        bhi     W300_0001
148
        puls    d,pc
149
 
150
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
151
; Get the keyboard status
152
;
153
; Parameters: none
154
; Returns: d = status
155
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
156
 
157
KeybdGetStatus:
158
kbgs3:
159
        ldb             KEYBD+1
160
        bitb    #$80
161
        bne             kbgs1
162
        bitb    #$01            ; check parity error flag
163
        bne             kbgs2
164
        clra
165
        rts
166
kbgs2:
167
        ldb             #$FE            ; request resend
168
        bsr             KeybdSendByte
169
        bsr             KeybdWaitTx
170
        bra             kbgs3
171
kbgs1:                                  ; return negative status
172
        orb             #$F00
173
        lda             #-1
174
        rts
175
 
176
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
177
; Get the scancode from the keyboard port
178
;
179
; Parameters: none
180
; Returns: acca = scancode
181
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
182
 
183
KeybdGetScancode:
184
        clra
185
        ldb             KEYBD                           ; get the scan code
186
        clr             KEYBD+1                 ; clear receive register (write $00 to status reg)
187
        rts
188
 
189
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
190
; Set the LEDs on the keyboard.
191
;
192
; Parameters: d LED status to set
193
; Returns: none
194
; Modifies: none
195
; Stack Space: 2 words
196
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
197
 
198
KeybdSetLED:
199
        pshs    b
200
        ldb             #$ED                                            ; set LEDs command
201
        bsr             KeybdSendByte
202
        bsr             KeybdWaitTx
203
        bsr             KeybdRecvByte   ; should be an ack
204
        puls    b
205
        bsr             KeybdSendByte
206
        bsr             KeybdWaitTx
207
        bsr             KeybdRecvByte   ; should be an ack
208
        rts
209
 
210
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
211
; Get ID - get the keyboards identifier code.
212
;
213
; Parameters: none
214
; Returns: d = $AB83, $00 on fail
215
; Modifies: d, KeybdID updated
216
; Stack Space: 2 words
217
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
218
 
219
KeybdGetID:
220
        ldb             #$F2
221
        bsr             KeybdSendByte
222
        bsr             KeybdWaitTx
223
        bsr             KeybdRecvByte
224
        bitb    #$80
225
        bne             kgnotKbd
226
        cmpb    #$AB
227
        bne             kgnotKbd
228
        bsr             KeybdRecvByte
229
        bitb    #$80
230
        bne             kgnotKbd
231
        cmpb    #$83
232
        bne             kgnotKbd
233
        ldd             #$AB83
234
kgid1:
235
        std             KeybdID
236
        rts
237
kgnotKbd:
238
        clra
239
        clrb
240
        bra             kgid1
241
 
242
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
243
; Initialize the keyboard.
244
;
245
; Parameters:
246
;               none
247
;       Modifies:
248
;               none
249
; Returns:
250
;               none
251
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
252
 
253
KeybdInit:
254
        pshs    d,y
255
        ldy             #5
256 14 robfinch
        clr             KeyState1               ; records key up/down state
257
        clr             KeyState2               ; records shift,ctrl,alt state
258 4 robfinch
kbdi0002:
259
        bsr             Wait10ms
260
        clr             KEYBD+1                 ; clear receive register (write $00 to status reg)
261
        ldb             #-1                                     ; send reset code to keyboard
262
        stb             KEYBD+1                 ; write $FF to status reg to clear TX state
263
        bsr             KeybdSendByte   ; now write to transmit register
264
        bsr             KeybdWaitTx             ; wait until no longer busy
265
        bsr             KeybdRecvByte   ; look for an ACK ($FA)
266
        cmpb    #$FA
267
        bne             kbdiTryAgain
268
        bsr             KeybdRecvByte   ; look for BAT completion code ($AA)
269
        cmpb    #$FC                            ; reset error ?
270
        beq             kbdiTryAgain
271
        cmpb    #$AA                            ; reset complete okay ?
272
        bne             kbdiTryAgain
273
 
274
        ; After a reset, scan code set #2 should be active
275
.config:
276
        ldb             #$F0                    ; send scan code select
277
        stb             LEDS
278
        bsr             KeybdSendByte
279
        bsr             KeybdWaitTx
280
        tstb
281
        bmi             kbdiTryAgain
282
        bsr             KeybdRecvByte   ; wait for response from keyboard
283
        tsta
284
        bmi             kbdiTryAgain
285
        cmpb    #$FA                                    ; ACK
286
        beq             kbdi0004
287
kbdiTryAgain:
288
        dey
289
        bne       kbdi0002
290
.keybdErr:
291
        ldd             #msgBadKeybd
292
        lbsr    DisplayStringCRLF
293
        bra             ledxit
294
kbdi0004:
295
        ldb             #2                      ; select scan code set #2
296
        bsr             KeybdSendByte
297
        bsr             KeybdWaitTx
298
        tstb
299
        bmi             kbdiTryAgain
300
        bsr             KeybdRecvByte   ; wait for response from keyboard
301
        tsta
302
        bmi             kbdiTryAgain
303
        cmpb    #$FA
304
        bne             kbdiTryAgain
305
        bsr             KeybdGetID
306
ledxit:
307
        ldb             #$07
308
        bsr             KeybdSetLED
309
        bsr             Wait300ms
310
        ldb             #$00
311
        bsr             KeybdSetLED
312
        puls    d,y,pc
313
 
314
msgBadKeybd:
315
        fcb             "Keyboard error",0
316
 
317 14 robfinch
;------------------------------------------------------------------------------
318
; Calculate number of character in input buffer
319
;
320
; Parameters:
321
;               y = $Cn00000 where n is core id
322
; Returns:
323
;               d = number of bytes in buffer.
324
;------------------------------------------------------------------------------
325
 
326
kbdRcvCount:
327
        clra
328
        ldb             kbdTailRcv,y
329
        subb    kbdHeadRcv,y
330
        bge             krcXit
331
        ldb             #$40
332
        subb    kbdHeadRcv,y
333
        addb    kbdTailRcv,y
334
krcXit:
335
        rts
336
 
337
 
338 4 robfinch
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
339
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
340
 
341 14 robfinch
KeybdIRQ:
342
        lda             KEYBD+1                                         ; check status
343
        bita    #$80                                                    ; was key pressed?
344
        beq             notKbdIRQ                                       ; if not, exit
345
        ldb             KEYBD                                                   ; get the scan code
346
        clr             KEYBD+1                                         ; clear receive register (write $00 to status reg)
347
        pshs    b                                                                       ; save it off
348
        lda             IOFocusID                                       ; compute core memory address $Cn0000
349
        clrb
350
        asla
351
        asla
352
        asla
353
        asla
354
        ora             #$C00                                                   ; address $Cn0000
355
        tfr             d,y                                                             ; y =
356
        bsr             kbdRcvCount                             ; get count of scan codes in buffer
357
        cmpb    #64                                                             ; check if buffer full?
358
        bhs             kbdBufFull                              ; if buffer full, ignore new keystroke
359
        tfr             y,x                                                             ; compute fifo address
360
        ldb             kbdTailRcv,y                    ; b = buffer index
361
        puls    a                                                                       ; get back scancode
362
        leax    kbdFifo,x                                       ; x = base address for fifo
363
        sta             b,x                                                             ; store in buffer
364
        incb                                                                            ; increment buffer index
365
        andb    #$3f                                                    ; wrap around at 64 chars
366
        stb             kbdTailRcv,y                    ; update it
367
        lda             #28                                                             ; Keyboard is IRQ #28
368
        sta             IrqSource                                       ; stuff a byte indicating the IRQ source for PEEK()
369
notKbdIRQ:
370
        rts
371
kbdBufFull:
372
        leas    1,s                                                             ; get rid of saved scancode
373
        rts
374
 
375
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
376
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
377
 
378 4 robfinch
DBGCheckForKey:
379
        bra             KeybdGetStatus
380
 
381
 
382
; KeyState2 variable bit meanings
383
;1176543210
384
; ||||||||+ = shift
385
; |||||||+- = alt
386
; ||||||+-- = control
387
; |||||+--- = numlock
388
; ||||+---- = capslock
389
; |||+----- = scrolllock
390
; ||+------ = 
391
; |+------- =    "
392
; |         =    "
393
; |         =    "
394
; |         =    "
395
; +-------- = extended
396
 
397
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
398 14 robfinch
; Keyboard get routine.
399 4 robfinch
;
400 14 robfinch
; The routine may get characters directly from the scancode input or less
401
; directly from the scancode buffer, if things are interrupt driven.
402
;
403 4 robfinch
; Parameters:
404 14 robfinch
;               b:  bit 11 = blocking status 1=blocking, 0=non blocking
405
;               b:      bit 1  = scancode source 1=scancode buffer, 0=direct
406 4 robfinch
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
407
 
408 14 robfinch
GetKey:
409
        pshs    x,y
410
        stb             KeybdBlock                              ; save off blocking status
411 4 robfinch
dbgk2:
412 14 robfinch
        ldb             KeybdBlock
413 4 robfinch
        pshs    b
414 14 robfinch
        bitb    #1                                                              ; what is the scancode source
415
        beq             dbgk20                                          ; branch if direct read
416
        lda             COREID                                          ; compute core memory address
417
        clrb
418
        asla
419
        asla
420
        asla
421
        asla
422
        ora             #$C00
423
        tfr             d,y                                                             ; y = $Cn0000
424
        bsr             kbdRcvCount
425
        tstb                                                                            ; anything in buffer?
426
        puls    b
427
        bne             dbgk1                                                   ; branch if something in buffer
428
        tstb
429
        bmi             dbgk2                                                   ; if no key and blocking - loop
430
dbgk20:
431
        ldy             #0
432 4 robfinch
        bsr             KeybdGetStatus
433
        andb    #$80                                                    ; is key available?
434
        puls    b
435
        bne             dbgk1                                                   ; branch if key
436
        tstb                                                                            ; block?
437 14 robfinch
        bmi             dbgk2                                                   ; If no key and blocking - loop
438 4 robfinch
        ldd             #-1                                                             ; return -1 if no block and no key
439
        puls    x,pc
440
dbgk1:
441 14 robfinch
        cmpy    #0
442
        bne             dbgk22
443
        bsr             KeybdGetScancode        ; get scancode directly
444
        bra             dbgk23
445
dbgk22:
446
        ; Retrieve value from scancode buffer
447
        tfr             y,x
448
        leax    kbdFifo,x                                       ; x = fifo address
449
        ldb             kbdHeadRcv,y                    ; b = buffer index
450
        lda             b,x                                                             ; get the scancode
451
        incb                                                                            ; increment fifo index
452
        andb    #$3f                                                    ; and wrap around
453
        stb             kbdHeadRcv,y                    ; save it back
454
        tfr             a,b                                                             ; the scancode is needed in accb
455
dbgk23:
456 4 robfinch
;       lbsr    DispByteAsHex
457
        ; Make sure there is a small delay between scancode reads
458
        ldx             #20
459
dbgk3:
460
        dex
461
        bne             dbgk3
462
        ; switch on scan code
463
        cmpb    #SC_KEYUP
464
        bne             dbgk4
465 14 robfinch
        stb             KeyState1                                       ; make KeyState1 <> 0
466 4 robfinch
        bra             dbgk2                                                   ; loop back
467
dbgk4:
468
        cmpb    #SC_EXTEND
469
        bne             dbgk5
470
        lda             KeyState2
471
        ora             #$800
472
        sta             KeyState2
473
        bra             dbgk2
474
dbgk5:
475
        cmpb    #SC_CTRL
476
        bne             dbgkNotCtrl
477
        tst             KeyState1
478 14 robfinch
        bne             dbgk7
479 4 robfinch
        lda             KeyState2
480
        ora             #4
481
        sta             KeyState2
482
        bra             dbgk8
483
dbgk7:
484
        lda             KeyState2
485
        anda    #~4
486
        sta             KeyState2
487
dbgk8:
488
        clr             KeyState1
489
        bra             dbgk2
490
dbgkNotCtrl:
491
        cmpb    #SC_RSHIFT
492
        bne             dbgkNotRshift
493
        tst             KeyState1
494 14 robfinch
        bne             dbgk9
495 4 robfinch
        lda             KeyState2
496
        ora             #1
497
        sta             KeyState2
498
        bra             dbgk10
499
dbgk9:
500
        lda             KeyState2
501
        anda    #~1
502
        sta             KeyState2
503
dbgk10:
504
        clr             KeyState1
505
        bra             dbgk2
506
dbgkNotRshift:
507
        cmpb    #SC_NUMLOCK
508
        bne             dbgkNotNumlock
509
        lda             KeyState2
510
        eora    #16
511
        sta             KeyState2
512
        lda             KeyLED
513
        eora    #2
514
        sta             KeyLED
515
        tfr             a,b
516
        clra
517
        bsr             KeybdSetLED
518
        bra             dbgk2
519
dbgkNotNumlock:
520
        cmpb    #SC_CAPSLOCK
521
        bne             dbgkNotCapslock
522
        lda             KeyState2
523
        eora    #32
524
        sta             KeyState2
525
        lda             KeyLED
526
        eora    #4
527
        sta             KeyLED
528
        tfr             a,b
529
        clra
530
        bsr             KeybdSetLED
531
        bra             dbgk2
532
dbgkNotCapslock:
533
        cmpb    #SC_SCROLLLOCK
534
        bne             dbgkNotScrolllock
535
        lda             KeyState2
536
        eora    #64
537
        sta             KeyState2
538
        lda             KeyLED
539
        eora    #1
540
        sta             KeyLED
541
        tfr             a,b
542
        clra
543
        bsr             KeybdSetLED
544
        bra             dbgk2
545
dbgkNotScrolllock:
546
        cmpb    #SC_ALT
547
        bne             dbgkNotAlt
548
        tst             KeyState1
549 14 robfinch
        bne             dbgk11
550 4 robfinch
        lda             KeyState2
551
        ora             #2
552
        sta             KeyState2
553
        bra             dbgk12
554
dbgk11:
555
        lda             KeyState2
556
        anda    #~2
557
        sta             KeyState2
558
dbgk12:
559
        clr             KeyState1
560
        bra             dbgk2
561
dbgkNotAlt:
562
        tst             KeyState1
563
        beq             dbgk13
564
        clr             KeyState1
565
        bra             dbgk2
566
dbgk13:
567
        lda             KeyState2               ; Check for CTRL-ALT-DEL
568
        anda    #6
569
        cmpa    #6
570
        bne             dbgk14
571
        cmpb    #SC_DEL
572
        bne             dbgk14
573 14 robfinch
        jmp             [$FFFFFC]               ; jump to NMI vector
574 4 robfinch
dbgk14:
575
        tst             KeyState2               ; extended code?
576
        bpl             dbgk15
577
        lda             KeyState2
578
        anda    #$7FF
579
        sta             KeyState2
580
        ldx             #keybdExtendedCodes
581
        bra             dbgk18
582
dbgk15:
583
        lda             KeyState2               ; Is CTRL down?
584
        bita    #4
585
        beq             dbgk16
586
        ldx             #keybdControlCodes
587
        bra             dbgk18
588
dbgk16:
589
        bita    #1                                      ; Is shift down?
590
        beq             dbgk17
591
        ldx             #shiftedScanCodes
592
        bra             dbgk18
593
dbgk17:
594
        ldx             #unshiftedScanCodes
595
dbgk18:
596 14 robfinch
        ldb             b,x                                     ; load accb with ascii from table
597 4 robfinch
        clra
598 14 robfinch
        puls    x,y,pc                  ; and return
599 4 robfinch
 

powered by: WebSVN 2.1.0

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