You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

219 lines
5.8 KiB

;__________________________________________________________________________________________________
; HARDWARE INTERFACE FOR POLLED AND INTERRUPT DRIVEN PS2 KEYBOARD.
;
; IN POLLED MODE THE CONTROLLER PORT VALUES ARE KNOWN BY THE CALLING DRIVER.
; IN INTERRUPT MODE THE DEVICES PORTS ARE UNKNOWN SO PREDEFINED PORT VALUES ARE USED.
;
; REQUIRES AN APPROPRIATE INTERRUPT JUMPER TO BE SET.
; CURRENTLY CONFIGURED FOR INT #2 ON DUODYNE WITH I/O MULTI BOARD.
;__________________________________________________________________________________________________
;
#IF ((INTMODE == 2) & KBDINTS))
;
;__________________________________________________________________________________________________
; KEYBOARD QUEUE FOR INTERRUPTS
;__________________________________________________________________________________________________
;
;
KBDQSIZ .EQU 32 ; MUST BE POWER OF TWO, <=128
KBDQGETX .DB 0 ; QUEUE INDEX
KBDQPUTX .DB 0 ; QUEUE INDEX
; .DB $55 ; GUARD BYTE FOR DEBUGGING ; NOTE THAT SCAN CODES ARE BEING
KBDQ .FILL KBDQSIZ,0 ; CIRCULAR KEYBOARD BUFFER ; BUFFERED. ONE KEY PRESS CAN
; .DB $AA ; GUARD BYTE FOR DEBUGGING ; GENERATE SEVERAL SCAN CODES
;__________________________________________________________________________________________________
; RESET THE QUEUE TO EMPTY
;__________________________________________________________________________________________________
;
;KBDQINIT:
; XOR A
; LD (KBDQGETX),A
; LD (KBDQPUTX),A
; RET
;
;__________________________________________________________________________________________________
; KEYBOARD INTERRUPT VECTOR
;__________________________________________________________________________________________________
;
KBD_INT:
; CALL KBDQDBG
LD IY,KBDIDAT ; POINT TO PORT TABLE
;
CALL KBD_IST_P ; READ CONTROLLER STATUS
RET Z ; EXIT IF NOTHINGTO READ
LD C,(IY+KBD_DAT)
EZ80_IO ; IF SOMETHING PENDING
IN A,(C) ; READ THE BYTE IN
LD B,A ; AND SAVE IT
;
CALL KBDQLEN ; CHECK IF
SUB KBDQSIZ ; QUEUE IS FULL
RET Z ; EXIT IF THE QUEUE IS FULL
;
LD HL,KBDQPUTX ; CREATE QUEUE INDEX
CALL KBD_Q_IDX ; POINTER IN HL
;
LD (HL),A ; SAVE THE CHARACTER IN THE QUEUE
; CALL KBDQDBG
;
RET
;
#ENDIF
;
;__________________________________________________________________________________________________
; KEYBOARD READ
;__________________________________________________________________________________________________
;
; READ DIRECT FROM PORT
;
KBD_IN_P:
LD C,(IY+KBD_DAT) ; DATA PORT
EZ80_IO
IN A,(C) ; GET THE DATA VALUE
RET
;
; READ FROM INTERRUPT QUEUE
;
#IF ((INTMODE == 2) & KBDINTS))
;
KBD_IN_Q:
KBDQPOP:
CALL KBDQLEN
RET Z ; EXIT IF THE QUEUE IS EMPTY
;
LD HL,KBDQGETX ; CREATE QUEUE INDEX
CALL KBD_Q_IDX ; POINTER IN HL
;
LD A,(HL) ; GET THE CHARACTER FROM THE QUEUE
; LD (HL),B ; DEBUG - CLEAN QUEUE
;
RET
KBD_Q_IDX:
LD A,(HL) ; CREATE QUEUE INDEX
AND KBDQSIZ-1
INC (HL) ; UPDATE INDEX
LD HL,KBDQ ; INDEX INTO THE QUEUE
LD C,A
LD A,B ; NOTE THE QUEUE GET
LD B,0 ; AND PUT INDEXES
ADD HL,BC ; NEVER DECREASE
RET
;
#ENDIF
;
#IF ((INTMODE == 2) & KBDINTS))
KBD_IN .EQU KBD_IN_Q
#ELSE
KBD_IN .EQU KBD_IN_P
#ENDIF
;
;__________________________________________________________________________________________________
; KEYBOARD INPUT STATUS
;__________________________________________________________________________________________________
;
; DIRECT PORT STATUS READ
;
KBD_IST_P:
LD C,(IY+KBD_ST) ; STATUS PORT
EZ80_IO
IN A,(C) ; GET STATUS
AND $01 ; ISOLATE INPUT PENDING BIT
RET
;
; STATUS FROM INTERRUPT QUEUE
;
#IF ((INTMODE == 2) & KBDINTS))
;
KBD_IST_Q:
KBDQLEN: ; EXIT WITH NUMBER OF CHARACTERS IN QUEUE
LD A,(KBDQPUTX) ; Z STATUS AND ZERO IF NONE
LD HL,KBDQGETX
SUB (HL)
RET
;
#ENDIF
;
; RETURN INDICATION OF KEYBOARD DATA READY
;
#IF ((INTMODE == 2) & KBDINTS))
KBD_IST .EQU KBD_IST_Q
#ELSE
KBD_IST .EQU KBD_IST_P
#ENDIF
;
;__________________________________________________________________________________________________
; OUTPUT TO KEYBOARD COMMAND PORT
;__________________________________________________________________________________________________
;
KBD_CMDOUT:
LD C,(IY+KBD_CMD) ; COMMAND PORT
EZ80_IO
OUT (C),A
RET
;__________________________________________________________________________________________________
; OUTPUT TO KEYBOARD COMMAND DATA
;__________________________________________________________________________________________________
;
KBD_DTAOUT:
LD C,(IY+KBD_DAT) ; DATA PORT
EZ80_IO
OUT (C),A
RET
;__________________________________________________________________________________________________
; KEYBOARD OUTPUT STATUS - A=0, Z SET FOR NOT READY, OTHERWISE READY TO WRITE
;__________________________________________________________________________________________________
;
KBD_OST:
LD C,(IY+KBD_ST) ; STATUS PORT
EZ80_IO
IN A,(C) ; GET STATUS
AND $02 ; ISOLATE OUTPUT EMPTY BIT
XOR $02 ; FLIP IT FOR APPROPRIATE RETURN VALUES
RET
;
;__________________________________________________________________________________________________
; DEBUG QUEUE
;__________________________________________________________________________________________________
;
#IF ((INTMODE == 2) & KBDINTS & 0)
KBDQDBG:
PUSH HL
PUSH DE
PUSH BC
PUSH AF
CALL NEWLINE ; PRINT QUEUE CONTENTS
LD B,KBDQSIZ ; +2 PRE AND POST GUARD BYTES
LD HL,KBDQ ; -1 PRE AND POST GUARD BYTES
KBDQPRT:
LD A,(HL)
CALL PRTHEXBYTE
INC HL
DJNZ KBDQPRT
LD A,' ' ; PRINT QUEUE INDEX
CALL COUT
LD A,(KBDQGETX)
AND KBDQSIZ-1
CALL PRTHEXBYTE
LD A,' ' ; PRINT QUEUE INDEX
CALL COUT
LD A,(KBDQPUTX)
AND KBDQSIZ-1
CALL PRTHEXBYTE
LD A,' ' ; PRINT # SCAN CODES IN QUEUE
CALL COUT
CALL KBDQLEN
CALL PRTHEXBYTE
CALL NEWLINE
POP AF
POP BC
POP DE
POP HL
RET
#ENDIF