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

Subversion Repositories rtf65002

[/] [rtf65002/] [trunk/] [software/] [asm/] [keyboard.asm] - Blame information for rev 40

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 40 robfinch
 
2
; ============================================================================
3
;        __
4
;   \\__/ o\    (C) 2013, 2014  Robert Finch, Stratford
5
;    \  __ /    All rights reserved.
6
;     \/_//     robfinch@opencores.org
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
; keyboard.asm
24
; ============================================================================
25
;
26
DCMD_INITIALIZE         EQU             0
27
DCMD_MEDIA_CHK          EQU             1
28
DCMD_BUILD_BPB          EQU             2
29
DCMD_IOCTRL_READ        EQU             3
30
DCMD_READ                       EQU             4
31
DCMD_PEEK                       EQU             5
32
DCMD_INPUT_STATUS       EQU             6
33
DCMD_FLUSH_INPUT        EQU             7
34
DCMD_WRITE                      EQU             8
35
DCMD_WRITE_VERIFY       EQU             9
36
DCMD_OUTPUT_STATUS      EQU             10
37
DCMD_FLUSH_OUTPUT       EQU             11
38
DCMD_IOCTRL_WRITE       EQU             12
39
DCMD_OPEN                       EQU             13
40
DCMD_CLOSE                      EQU             14
41
DCMD_IS_REMOVEABLE      EQU             15
42
DCMD_OUTPUT_UNTIL_BUSY  EQU     16
43
DCMD_IRQ                        EQU             0xFFFFFFFD
44
DCMD_GETCHAR            EQU             32
45
 
46
DRSP_DONE                       EQU             1
47
 
48
                cpu             RTF65002
49
 
50
                .code
51
;------------------------------------------------------------------------------
52
;       The keyboard interrupt is selectively disabled and enabled to protect
53
; the keyboard buffers structure. Other interrupts are still enabled.
54
;------------------------------------------------------------------------------
55
 
56
macro DisKeybd
57
        pha
58
        lda             #15
59
        sta             PIC+2
60
        pla
61
endm
62
 
63
macro EnKeybd
64
        pha
65
        lda             #15
66
        sta             PIC+3
67
        pla
68
endm
69
 
70
        align   4
71
        ; Device driver struct
72
        dw              0xFFFFFFFF                      ; link to next device
73
        dw              0x00008001                      ; device attributes
74
        dw              KeybdStrategy           ; strategy routine
75
        dw              KeybdIRQ                        ; interrupt routine
76
        dw              KeybdCmdProc            ; command processor
77
 
78
        align   4
79
        dw      KeybdNop
80
        dw      KeybdInit
81
        dw      KeybdMediaChk
82
        dw      KeybdBuildBPB
83
        dw      KeybdGetChar                    ; GetChar()
84
        dw      KeybdCheckForKey                ; PeekChar()
85
        dw      KeybdGetCharDirect              ; unbuffered GetChar()
86
        dw      KeybdCheckForKeyDirect  ; unbuffered PeekChar()
87
        dw      SendByteToKeybd                 ; KeybdPutChar
88
        dw      SetKeyboardEcho
89
        dw      KeybdSetpos                             ; set position
90
 
91
;------------------------------------------------------------------------------
92
;------------------------------------------------------------------------------
93
public KeybdDCB:
94
        align   4
95
        db      "KBD1        "  ; name
96
        dw      4       ; number of chars in name
97
        dw      1       ; type
98
        dw      1       ; nBPB
99
        dw      0        ; last erc
100
        dw      0        ; nBlocks
101
        dw      KeybdCmdProc
102
        dw      KeybdInit
103
        dw      KeybdStat
104
        dw      1       ; reentrancy count (1 to 255 are valid)
105
        dw      0        ; single user
106
        dw      0        ; hJob
107
        dw      0        ; OSD1
108
        dw      0        ; OSD2
109
        dw      0        ; OSD3
110
        dw      0        ; OSD4
111
        dw      0        ; OSD5
112
        dw      0        ; OSD6
113
 
114
KeybdStrategy:
115
        rts
116
KeybdCmdProc:
117
        rts
118
KeybdStat:
119
        rts
120
KeybdBuildBPB:
121
        rts
122
KeybdSetpos:
123
        rts
124
KeybdNop:
125
        lda             #E_Ok
126
        rts
127
 
128
;------------------------------------------------------------------------------
129
; Setup keyboard
130
;
131
; Issues a 'reset keyboard' command to the keyboard, then selects scan code
132
; set #2 (the most common one). Also sets up the keyboard buffer and
133
; initializes the keyboard semaphore.
134
;------------------------------------------------------------------------------
135
;
136
message "KeybdSetup"
137
public KeybdSetup:
138
        lda             #1                      ; setup semaphore
139
        sta             keybd_sema
140
        lda             #32
141
        sta             LEDS
142
        ldx             #0
143
 
144
        ; Set Keyboard IRQ vector
145
        tsr             vbr,r2
146
        and             r2,#-2
147
        lda             #KeybdIRQ
148
        sta             448+15,x
149
 
150
        lda             #15                             ; enable kbd_irq
151
        sta             PIC+3
152
 
153
        jsr             KeybdInit
154
 
155
        lda             #1                              ; keyboard is device #1
156
        ldx             #KeybdDCB               ; pointer to DCB
157
        ldy             #1                              ; number of DCB's to setup
158
        ld              r4,#1                   ; Flag: is okay to replace existing device
159
;       jsr             InitDevDrv
160
        stz             keybdInIRQ
161
        inc             keybdIsSetup    ; set the setup flag
162
        rts
163
 
164
KeybdInit:
165
        lda             #33
166
        sta             LEDS
167
        lda             #$ff            ; issue keyboard reset
168
        jsr             SendByteToKeybd
169
        lda             #38
170
        sta             LEDS
171
        lda             #4
172
;       jsr             Sleep
173
        lda             #1000000                ; delay a bit
174
kbdi5:
175
        dea
176
        sta             LEDS
177
        bne             kbdi5
178
        lda             #34
179
        sta             LEDS
180
        lda             #0xf0           ; send scan code select
181
        jsr             SendByteToKeybd
182
        lda             #35
183
        sta             LEDS
184
        ldx             #0xFA
185
        jsr             WaitForKeybdAck
186
        cmp             #$FA
187
        bne             kbdi2
188
        lda             #36
189
        sta             LEDS
190
        lda             #2                      ; select scan code set#2
191
        jsr             SendByteToKeybd
192
        lda             #39
193
        sta             LEDS
194
kbdi2:
195
        rts
196
 
197
msgBadKeybd:
198
        db              "Keyboard not responding.",0
199
 
200
SendByteToKeybd:
201
        phx
202
        ldx             IOFocusNdx
203
        sta             KEYBD
204
        lda             #40
205
        sta             LEDS
206
        tsr             TICK,r3
207
kbdi4:                                          ; wait for transmit complete
208
        tsr             TICK,r4
209
        sub             r4,r4,r3
210
        cmp             r4,#1000000
211
        bhi             kbdbad
212
        lda             #41
213
        sta             LEDS
214
        lda             KEYBD+3
215
        bit             #64
216
        beq             kbdi4
217
        bra             sbtk1
218
kbdbad:
219
        lda             #42
220
        sta             LEDS
221
        lda             JCB_KeybdBad,x
222
        bne             sbtk2
223
        lda             #1
224
        sta             JCB_KeybdBad,x
225
        lda             #43
226
        sta             LEDS
227
        lda             #msgBadKeybd
228
        jsr             DisplayStringCRLFB
229
sbtk1:
230
        lda             #44
231
        sta             LEDS
232
        plx
233
        rts
234
sbtk2:
235
        bra             sbtk1
236
 
237
; Wait for keyboard to respond with an ACK (FA)
238
;
239
WaitForKeybdAck:
240
        lda             #64
241
        sta             LEDS
242
        tsr             TICK,r3
243
wkbdack1:
244
        tsr             TICK,r4
245
        sub             r4,r4,r3
246
        cmp             r4,#1000000
247
        bhi             wkbdbad
248
        lda             #65
249
        sta             LEDS
250
        lda             KEYBD
251
        bit             #$8000
252
        beq             wkbdack1
253
;       lda             KEYBD+8
254
        and             #$ff
255
wkbdbad:
256
        rts
257
 
258
; Wait for keyboard to respond with an ACK (FA)
259
; This routine picks up the ack status left by the
260
; keyboard IRQ routine.
261
; r2 = 0xFA (could also be 0xEE for echo command)
262
;
263
WaitForKeybdAck2:
264
        phy
265
        ldy             IOFocusNdx
266
WaitForKeybdAck2a:
267
        lda             JCB_KeybdAck,y
268
        cmp             r1,r2
269
        bne             WaitForKeybdAck2a
270
        stz             JCB_KeybdAck,y
271
        ply
272
        rts
273
 
274
;------------------------------------------------------------------------------
275
; Code in the works.
276
;------------------------------------------------------------------------------
277
;
278
comment ~
279
public KeybdService:
280
        lda             #keybd_mbx
281
        jsr             AllocMbx
282
        jsr             KeybdSetup
283
kbds3:
284
        ; Wait for a message to arrive at the service
285
        lda             keybd_mbx
286
        ldx             #-1                             ; wait forever
287
        jsr             WaitMsg
288
        cpx             #DCMD_IRQ
289
        beq             kbds1
290
        cpx             #DCMD_GETCHAR
291
        beq             kbds2
292
        cpx             #DCMD_INITIALIZE
293
        beq             kbds4
294
        bra             kbds3
295
kbds1:
296
        tyx             ; D2 holds character
297
        jsr             IKeybdIRQ
298
        bra             kbds3
299
kbds2:
300
        ; The mailbox number is the same as the TCB number
301
        tya
302
        jsr             IKeybdGetChar
303
        ; Send a message back to the requester containing the key value.
304
        tax
305
        tya
306
        ldy             #0
307
        jsr             SendMsg
308
        bra             kbds3
309
kbds4:
310
        jsr             KeybdInit
311
        bra             kbds3
312
~
313
comment ~
314
public XKeybdIRQ:
315
        pha
316
        phx
317
        phy
318
        lda             keybd_mbx
319
        ldx             #DCMD_IRQ
320
        ldy             KEYBD                           ; get keyboard character
321
        ld              r0,KEYBD+1                      ; clear keyboard strobe (turns off the IRQ)
322
        cli
323
        jsr             PostMsg
324
        ply
325
        plx
326
        pla
327
        rti
328
~
329
;------------------------------------------------------------------------------
330
; KeybdIRQ
331
;
332
; Normal keyboard interrupt, the lowest priority interrupt in the system.
333
; Grab the character from the keyboard device and store it in a buffer.
334
; The buffer of the task with the input focus is updated.
335
; This IRQ has to check for the ALT-tab character and take care of
336
; switching the IO focus if detected. It can't be done in the KeybdGetChar
337
; because the app with the IO focus may not call that routine. We know for
338
; sure the interrupt routine will be called when a key is pressed. The
339
; mechanism used is to set a flag indicating a focus switch is required.
340
; The actual focus switch occurs when a selected to run. The reason the
341
; focus switch doesn't occur during the interrupt routine is that it takes
342
; a large number of clock cycles (the screen buffer is transferred).
343
;------------------------------------------------------------------------------
344
;
345
message "KeybdIRQ"
346
 
347
public IKeybdIRQ:
348
public KeybdIRQ:
349
        inc             keybdInIRQ
350
        cld
351
        pha
352
        phx
353
        phy
354
        push    r4
355
 
356
        lda             #15                                     ; disable further keyboard interrupts
357
        sta             PIC+2
358
        ldx             KEYBD                           ; get keyboard character
359
        ld              r0,KEYBD+1                      ; clear keyboard strobe (turns off the IRQ)
360
        txy                                                     ;
361
        cli                                                     ; global interrupt enable
362
        bit             r3,#$800                        ; test bit #11
363
        bne             KeybdIRQc                       ; ignore keyup messages for now
364
        ld              r4,IOFocusNdx           ; get the job with the input focus
365
        bit             r3,#$200                        ; check for ALT-tab
366
        beq             KeybdIrq3
367
        and             r3,r3,#$FF
368
        cmp             r3,#TAB                         ; if we find an ALT-tab
369
        bne             KeybdIrq3
370
        inc             iof_switch
371
;       jsr             SwitchIOFocus
372
        bra             KeybdIRQc                       ; don't store off the ALT-tab character
373
KeybdIrq3:
374
        and             r3,r3,#$ff
375
        cmp             r3,#$FA
376
        bne             KeybdIrq1
377
        sty             JCB_KeybdAck,r4
378
        bra             KeybdIRQc
379
        ; strip out non-key keyboard responses
380
KeybdIrq1:
381
        cmp             r3,#$AA                         ; self test pass
382
        beq             KeybdIRQd
383
        cmp             r3,#$EE                         ; echo response
384
        beq             KeybdIRQd
385
        cmp             r3,#$00                         ; keyboard error
386
        beq             KeybdIRQd
387
        cmp             r3,#$FF                         ; keyboard error
388
        beq             KeybdIRQd
389
        bit             r2,#$800                        ; test bit #11
390
        bne             KeybdIRQc                       ; ignore keyup messages for now
391
KeybdIrq2:
392
        lda             JCB_KeybdHead,r4
393
        ina                                                     ; increment head pointer
394
        and             #$f                                     ; limit
395
        ldy             JCB_KeybdTail,r4        ; check for room in the keyboard buffer
396
        cmp             r1,r3
397
        beq             KeybdIRQc                       ; if no room, the newest char will be lost
398
        sta             JCB_KeybdHead,r4
399
        dea
400
        and             #$f
401
        stx             JCB_KeybdLocks,r4
402
        stx             keybdLock                       ; global keyboard lock status
403
        add             r1,r1,r4
404
        stx             JCB_KeybdBuffer,r1      ; store character in buffer
405
KeybdIRQc:
406
 
407
        ; support EhBASIC's IRQ functionality
408
        ; code derived from minimon.asm
409
        lda             #15                             ; Keyboard is IRQ #15
410
        sta             IrqSource
411
        lb              r1,IrqBase              ; get the IRQ flag byte
412
        lsr             r2,r1
413
        or              r1,r1,r2
414
        and             #$E0
415
        sb              r1,IrqBase              ; save the new IRQ flag byte
416
KeybdIRQd:
417
        lda             #15                             ; re-enable keyboard interrupts
418
        sta             PIC+3
419
        pop             r4
420
        ply
421
        plx
422
        pla
423
        dec             keybdInIRQ
424
        rti
425
 
426
 
427
public KeybdRstIRQ:
428
        jmp             start
429
 
430
;-----------------------------------------------------------------------------
431
; Media Check
432
;       A value of 1 is returned indicating that the media hasn't changed.
433
;-----------------------------------------------------------------------------
434
;
435
KeybdMediaChk:
436
        lda             #1
437
        rts
438
 
439
;-----------------------------------------------------------------------------
440
; r1 0=echo off, non-zero = echo on
441
;------------------------------------------------------------------------------
442
public SetKeyboardEcho:
443
        pha
444
        phx
445
        tax
446
        jsr             GetPtrCurrentJCB
447
        stx             JCB_KeybdEcho,r1
448
        plx
449
        pla
450
        rts
451
 
452
;------------------------------------------------------------------------------
453
; Get character from keyboard buffer
454
; return character in acc or -1 if no
455
; characters available.
456
;------------------------------------------------------------------------------
457
;
458
message "KeybdGetChar"
459
 
460
comment ~
461
public KeybdGetChar:
462
        phx
463
        phy
464
        push    r4
465
        ; Send a message to the keyboard service requesting a character.
466
        lda             keybd_mbx               ;
467
        ldx             #DCMD_GETCHAR   ; opcode
468
        ldy             RunningTCB              ; response mailbox number
469
        jsr             SendMsg
470
        ; Wait for a response message from the keyboard service.
471
        tya
472
        ldx             #-1
473
        jsr             WaitMsg
474
        txa
475
        pop             r4
476
        ply
477
        plx
478
        rts
479
~
480
;------------------------------------------------------------------------------
481
; KeybdGetChar
482
;
483
;       Get keyboard character from buffer for the current job.
484
;
485
; Registers Affected: r1, flags
486
; Parameters: none
487
; Returns:
488
;       r1 = keyboard character or -1 if no character is available.
489
;------------------------------------------------------------------------------
490
;
491
public KeybdGetChar:
492
        jsr             GetCurrentJob
493
 
494
;------------------------------------------------------------------------------
495
; Get keyboard character from buffer for the specified job. This entry point
496
; is meant to be called by the keyboard service.
497
;
498
; Registers Affected: r1, flags
499
; Parameters:
500
;       r1 = job number
501
; Returns:
502
;       r1 = keyboard character or -1 if no character is available.
503
;------------------------------------------------------------------------------
504
;
505
IKeybdGetChar:
506
        phx
507
        phy
508
        ld              r0,keybdIsSetup ; the system might call GetChar before the keyboard
509
        beq             .nochar                 ; is setup.
510
        tay
511
        cmp             r3,#NR_JCB
512
        bhs             .nochar
513
        mul             r3,r3,#JCB_Size         ; convert handle to pointer
514
        add             r3,r3,#JCBs
515
        lda             #15                                     ; disable keyboard interrupt
516
        sta             PIC+2
517
        ld              r0,keybdInIRQ
518
        bne             .nochari
519
        ldx             JCB_KeybdTail,y         ; if keybdTail==keybdHead then there are no
520
        lda             JCB_KeybdHead,y         ; characters in the keyboard buffer
521
        cmp             r1,r2
522
        beq             .nochari
523
        phx
524
        add             r2,r2,r3
525
        lda             JCB_KeybdBuffer,x
526
        plx
527
        and             r1,r1,#$ff              ; mask off control bits
528
        inx                                             ; increment index
529
        and             r2,r2,#$0f
530
        stx             JCB_KeybdTail,y
531
        ldx             JCB_KeybdEcho,y
532
        php
533
        ldx             #15                             ; re-enable keyboard interrupt
534
        stx             PIC+3
535
        plp
536
        beq             .xit                    ; status from the ldx
537
        cmp             #CR
538
        bne             .dispchar
539
        jsr             CRLF                    ; convert CR keystroke into CRLF
540
        bra             .xit
541
.dispchar:
542
        jsr             DisplayChar
543
        bra             .xit
544
.nochari
545
        lda             #15                             ; re-enable keyboard interrupt
546
        sta             PIC+3
547
.nochar:
548
        lda             #-1
549
.xit:
550
        ply
551
        plx
552
        rts
553
 
554
;------------------------------------------------------------------------------
555
; Check if there is a keyboard character available in the keyboard buffer.
556
;
557
; Returns
558
; r1 = n, Z=0 if there is a key available, otherwise
559
; r1 = 0, Z=1 if there is not a key available
560
;------------------------------------------------------------------------------
561
;
562
message "KeybdCheckForKey"
563
public KeybdCheckForKey:
564
        phx
565
        phy
566
        ldx             #0
567
        ld              r0,keybdIsSetup
568
        beq             .nochar2
569
        jsr             GetPtrCurrentJCB
570
        tay
571
        lda             #15                             ; disable keyboard interrupt
572
        sta             PIC+2
573
        ld              r0,keybdInIRQ
574
        bne             .nochar
575
        ldx             JCB_KeybdTail,y
576
        sub             r2,r2,JCB_KeybdHead,y
577
.nochar
578
        lda             #15                             ; re-enable keyboard interrupt
579
        sta             PIC+3
580
.nochar2
581
        txa
582
        ply
583
        plx
584
        cmp             #0
585
        rts
586
 
587
;------------------------------------------------------------------------------
588
; Tests the keyboard port directly.
589
; Check if there is a keyboard character available. If so return true (1)
590
; otherwise return false (0) in r1.
591
;------------------------------------------------------------------------------
592
;
593
message "KeybdCheckForKeyDirect"
594
public KeybdCheckForKeyDirect:
595
        lda             KEYBD
596
        and             #$8000
597
        beq             kcfkd1
598
        lda             #1
599
kcfkd1
600
        rts
601
 
602
;------------------------------------------------------------------------------
603
; Get character directly from keyboard. This routine blocks until a key is
604
; available.
605
;------------------------------------------------------------------------------
606
;
607
public KeybdGetCharDirect:
608
        phx
609
kgc1:
610
        lda             KEYBD
611
        bit             #$8000
612
        beq             kgc1
613
        ld              r0,KEYBD+1              ; clear keyboard strobe
614
        bit             #$800                   ; is it a keydown event ?
615
        bne             kgc1
616
;       bit             #$200                           ; check for ALT-tab
617
;       bne             kgc2
618
;       and             r2,r1,#$7f
619
;       cmp             r2,#TAB                                 ; if we find an ALT-tab
620
;       bne             kgc2
621
;       jsr             SwitchIOFocus
622
;       bra             kgc1
623
;kgc2:
624
        and             #$ff                    ; remove strobe bit
625
        ldx             KeybdEcho               ; is keyboard echo on ?
626
        beq             gk1
627
        cmp             #CR
628
        bne             gk2                             ; convert CR keystroke into CRLF
629
        jsr             CRLF
630
        bra             gk1
631
gk2:
632
        jsr             DisplayChar
633
gk1:
634
        plx
635
        rts
636
 
637
 
638
;------------------------------------------------------------------------------
639
; Keyboard LEDs task
640
;       This small task tracks the keyboard lock status keys and updates the
641
; keyboard LEDs accordingly. This task runs every 100ms.
642
;------------------------------------------------------------------------------
643
;
644
public KeybdStatusLEDs:
645
ksl4:
646
        lda             #15                             ; disable keyboard interrupt
647
        sta             PIC+2
648
        ld              r0,keybdInIRQ
649
        bne             ksl5
650
        lda             #$ED
651
        jsr             SendByteToKeybd
652
        jsr             WaitForKeybdAck ; wait for a feedback char
653
        cmp             #$FA            ; was it an acknowledge (should be)
654
        beq             ksl7
655
        lda             #15                     ; if not, re-enable keyboard, wait till next time
656
        sta             PIC+3
657
        bra             ksl5
658
ksl7:
659
        lda             #0
660
        ldx             keybdLock
661
        bit             r2,#4000        ; bit 14 = scroll lock status
662
        beq             ksl1
663
        lda             #1
664
ksl1:
665
        bit             r2,#1000        ; bit 12 = numlock status
666
        beq             ksl2
667
        or              r1,#2
668
ksl2:
669
        bit             r2,#2000        ; bit 13 = capslock status
670
        beq             ksl3
671
        or              r1,#4
672
ksl3:
673
    jsr         SendByteToKeybd
674
    lda         #15                     ; re-enabled keyboard interrupt
675
    sta         PIC+3
676
ksl5:
677
        lda             #10
678
        jsr             Sleep
679
        bra             ksl4

powered by: WebSVN 2.1.0

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