Final Tweaks to KBD Interrupt Support

Related to PR #460
This commit is contained in:
Wayne Warthen
2024-12-07 15:12:19 -08:00
parent 7606abb8f3
commit 007e8a372a
2 changed files with 89 additions and 58 deletions

View File

@@ -113,18 +113,14 @@ KBD_INIT:
CP KBDMODE_VRC ; VRC?
JR Z,KBD_INIT1 ; IF SO, MUST ASSUME PRESENT
;
#IF ((INTMODE == 2) & KBDINTS)
HB_DI ; DISABLE INTERRUPTS WHILE WE PROBE
#ENDIF
LD A,$AA ; CONTROLLER SELF TEST
CALL KBD_PUTCMD ; SEND IT
CALL KBD_GETDATA_P ; CONTROLLER SHOULD RESPOND WITH $55 (ACK)
HB_EI ; RESTORE INTERRUPTS
;
CP $55 ; IS IT THERE?
JR Z,KBD_INIT1 ; IF SO, CONTINUE
#IF ((INTMODE == 2) & KBDINTS)
HB_EI ; RESTORE INTERRUPTS
#ENDIF
PRTS(" NOT PRESENT$") ; DIAGNOSE PROBLEM
RET ; BAIL OUT
;
@@ -133,7 +129,6 @@ KBD_INIT1:
; CALL KBDQINIT ; INITIALIZE QUEUE
LD HL,KBD_INT ; INSTALL VECTOR
LD (IVT(INT_PS2KB)),HL ; IVT INDEX
HB_EI ; ENABLE INTERUPTS
#ENDIF
PRTS(" MODE=$") ; TAG
LD A,(IY+KBD_MODE) ; GET MODE VALUE
@@ -268,33 +263,7 @@ KBD_PUTDATA2:
RET
;
;__________________________________________________________________________________________________
KBD_GETDATA:
;
; GET A RAW DATA BYTE FROM KEYBOARD INTERFACE INTO A WITH TIMEOUT.
; DEPENDING ON ASSEMBLY CONFIGURATION KBD_GETDATA READS A BYTE FROM
; EITHER THE INTERRUPT QUEUE OR FROM THE KEYBOARD CONTROLLER PORT.
;
LD B,KBD_WAITTO ; SETUP TO LOOP
KBD_GETDATA0:
CALL KBD_IST ; GET INPUT REGISTER STATUS
JR NZ,KBD_GETDATA1 ; BYTE PENDING, GO GET IT
CALL DELAY ; WAIT A BIT
DJNZ KBD_GETDATA0 ; LOOP UNTIL COUNTER EXHAUSTED
XOR A ; NO DATA, RETURN ZERO
RET
KBD_GETDATA1:
CALL KBD_IN ; GET A KEY
#IF (KBDTRACE >= 2)
PUSH AF
CALL PC_SPACE
CALL PC_LT
CALL PRTHEXBYTE
POP AF
#ENDIF
OR A ; SET FLAGS
RET
;
;__________________________________________________________________________________________________
KBD_GETDATA_P:
;
; GET A RAW DATA BYTE FROM KEYBOARD INTERFACE INTO A WITH TIMEOUT.
@@ -320,10 +289,52 @@ KBD_GETDATA1_P:
OR A ; SET FLAGS
RET
;
KBD_GETDATA_Q:
;
; GET A QUEUED DATA BYTE FROM KEYBOARD INTERFACE INTO A WITH TIMEOUT.
; KBD_GETDATA_Q ALWAYS READS A BYTE FROM THE KEYBOARD INTERRUPT QUEUE.
;
#IF ((INTMODE == 2) & KBDINTS))
;
LD B,KBD_WAITTO ; SETUP TO LOOP
KBD_GETDATA0_Q:
CALL KBD_IST_Q ; GET INPUT REGISTER STATUS
JR NZ,KBD_GETDATA1_Q ; BYTE PENDING, GO GET IT
CALL DELAY ; WAIT A BIT
DJNZ KBD_GETDATA0_Q ; LOOP UNTIL COUNTER EXHAUSTED
XOR A ; NO DATA, RETURN ZERO
RET
KBD_GETDATA1_Q:
CALL KBD_IN_Q ; GET A KEY
#IF (KBDTRACE >= 2)
PUSH AF
CALL PC_SPACE
CALL PC_LT
CALL PRTHEXBYTE
POP AF
#ENDIF
OR A ; SET FLAGS
RET
;
#ENDIF
;
; GET A DATA BYTE FROM KEYBOARD INTERFACE INTO A WITH TIMEOUT.
; DEPENDING ON ASSEMBLY CONFIGURATION KBD_GETDATA READS A BYTE FROM
; EITHER THE INTERRUPT QUEUE OR FROM THE KEYBOARD CONTROLLER PORT.
;
#IF ((INTMODE == 2) & KBDINTS))
KBD_GETDATA .EQU KBD_GETDATA_Q
KBD_GETDATA1 .EQU KBD_GETDATA1_Q
#ELSE
KBD_GETDATA .EQU KBD_GETDATA_P
KBD_GETDATA1 .EQU KBD_GETDATA1_P
#ENDIF
;
;__________________________________________________________________________________________________
KBD_GETDATAX:
;
; GET A RAW DATA BYTE FROM KEYBOARD INTERFACE INTO A WITH NOTIMEOUT
; GET A DATA BYTE FROM KEYBOARD INTERFACE INTO A WITH NO TIMEOUT
; IF NOTHING AVAILABLE, RETURN 0.
;
CALL KBD_IST ; GET INPUT REGISTER STATUS
RET Z ; NOTHING THERE, DONE

View File

@@ -82,16 +82,24 @@ KBDQFULL: ; RETURN Z IF QUEUE IS FULL
SUB KBDQSIZ
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))
;
; RETURN A BYTE TO FROM KEYBOARD QUEUE
; NOTE THE QUEUE INDEX'S NEVER DECREASE IN SIZE.
;
KBD_IN:
KBD_IN_Q:
KBDQPOP:
CALL KBDQLEN
RET Z ; EXIT IF THE QUEUE IS EMPTY
@@ -110,39 +118,51 @@ KBDQPOP:
;
RET
;
#ELSE
;
; RETURN A BYTE FROM THE KEYBOARD PORT
;
KBD_IN:
#ENDIF
KBD_IN_P:
LD C,(IY+KBD_DAT) ; DATA PORT
EZ80_IO
IN A,(C) ; GET THE DATA VALUE
RET
;
; RETURN A BYTE TO FROM KEYBOARD QUEUE
; NOTE THE QUEUE INDEX'S NEVER DECREASE IN SIZE.
;
#IF ((INTMODE == 2) & KBDINTS))
KBD_IN .EQU KBD_IN_Q
#ELSE
KBD_IN .EQU KBD_IN_P
#ENDIF
;
;__________________________________________________________________________________________________
; KEYBOARD INPUT STATUS
;__________________________________________________________________________________________________
;
#IF ((INTMODE == 2) & KBDINTS))
KBD_IST:
KBDQLEN: ; EXIT WITH NUMBER OF CHARACTERS IN QUEUE
LD A,(KBDQPUTX) ; Z STATUS AND ZERO IF NONE
LD HL,KBDQGETX
SUB (HL)
RET
#ELSE
KBD_IST:
#ENDIF
KBD_IST_P: ; A=0, Z SET FOR NOTHING PENDING, OTHERWISE DATA PENDING
; 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
;__________________________________________________________________________________________________