Browse Source

NABU Keyboard Typeahead

- Implemented a 16 character typeahead buffer for interrupt-enabled builds of NABU.
work v3.5.0-dev.43
Wayne Warthen 2 years ago
parent
commit
78a765147e
  1. 199
      Source/HBIOS/nabukb.asm
  2. 2
      Source/HBIOS/util.asm
  3. 2
      Source/ver.inc
  4. 2
      Source/ver.lib

199
Source/HBIOS/nabukb.asm

@ -21,9 +21,11 @@
; WILL TRANSLATE SPECIAL KEYS ($E0-$FF) TO ROMWBW EQUIVALENTS. ALL
; OTHER KEYS WILL BE PASSED THROUGH AS IS.
;
;
NABUKB_IODAT .EQU $90 ; KEYBOARD DATA (READ)
NABUKB_IOSTAT .EQU $91 ; STATUS (READ), CMD (WRITE)
;
;
NABUKB_BUFSZ .EQU 16 ; RECEIVE RING BUFFER SIZE
;
DEVECHO "NABUKB: IO="
DEVECHO NABUKB_IODAT
@ -62,6 +64,7 @@ NABUKB_INIT:
LD (IVT(INT_NABUKB)),HL ; IVT INDEX
#ENDIF
;
#IF (INTMODE > 0)
; ENABLE KEYBOARD INTERRUPTS ON NABU INTERRUPT CONTROLLER
LD A,14 ; PSG R14 (PORT A DATA)
OUT (NABU_RSEL),A ; SELECT IT
@ -69,6 +72,7 @@ NABUKB_INIT:
SET 5,A ; ENABLE VDP INTERRUPTS
LD (NABU_CTLVAL),A ; UPDATE SHADOW REG
OUT (NABU_RDAT),A ; WRITE TO HARDWARE
#ENDIF
;
XOR A
RET
@ -87,96 +91,149 @@ NABUKB_INT:
;
;CALL PC_LT ; *DEBUG*
IN A,(NABUKB_IODAT) ; GET THE KEY
LD E,A ; STASH IN REG E
;CALL PRTHEXBYTE ; *DEBUG*
;CALL PC_COMMA ; *DEBUG*
CALL NABUKB_XB ; TRANSLATE THE KEY
;CALL PRTHEXBYTE ; *DEBUG*
;CALL PC_GT ; *DEBUG*
;
LD A,(NABUKB_KSTAT) ; GET KEY BUFFER STAT
OR A ; SET FLAGS
RET NZ ; BUFFER FULL, BAIL OUT W/ NZ (INT HANDLED), KEY DISCARDED
;
LD A,E ; RECOVER THE KEY CODE
CALL NABUKB_XB ; TRANSLATE AND BUFFER KEY
OR $FF ; SIGNAL INT HANDLED
RET ; DONE
JR C,NABUKB_INTRCV4 ; ABORT IF UNUSABLE KEY
LD B,A ; SAVE BYTE READ
LD HL,NABUKB_RCVBUF ; SET HL TO START OF BUF STRUCT
LD A,(HL) ; GET COUNT
CP NABUKB_BUFSZ ; COMPARE TO BUFFER SIZE
JR Z,NABUKB_INTRCV4 ; BAIL OUT IF BUFFER FULL, RCV BYTE DISCARDED
INC A ; INCREMENT THE COUNT
LD (HL),A ; AND SAVE IT
INC HL ; HL NOW HAS ADR OF HEAD PTR
PUSH HL ; SAVE ADR OF HEAD PTR
LD A,(HL) ; DEREFERENCE HL
INC HL
LD H,(HL)
LD L,A ; HL IS NOW ACTUAL HEAD PTR
LD (HL),B ; SAVE CHARACTER RECEIVED IN BUFFER AT HEAD
INC HL ; BUMP HEAD POINTER
POP DE ; RECOVER ADR OF HEAD PTR
LD A,L ; GET LOW BYTE OF HEAD PTR
SUB NABUKB_BUFSZ+4 ; SUBTRACT SIZE OF BUFFER AND POINTER
CP E ; IF EQUAL TO START, HEAD PTR IS PAST BUF END
JR NZ,NABUKB_INTRCV3 ; IF NOT, BYPASS
LD H,D ; SET HL TO
LD L,E ; ... HEAD PTR ADR
INC HL ; BUMP PAST HEAD PTR
INC HL
INC HL
INC HL ; ... SO HL NOW HAS ADR OF ACTUAL BUFFER START
NABUKB_INTRCV3:
EX DE,HL ; DE := HEAD PTR VAL, HL := ADR OF HEAD PTR
LD (HL),E ; SAVE UPDATED HEAD PTR
INC HL
LD (HL),D
NABUKB_INTRCV4:
OR $FF ; NZ SET TO INDICATE INT HANDLED
RET ; AND RETURN
;
#ENDIF
;
; NORMAL HBIOS CHAR INPUT STATUS. IF INTERRUPTS ARE NOT ACTIVE, THEN
; KEYBOARD POLLING IS IMPLEMENTED HERE.
;
#IF (INTMODE == 0)
NABUKB_STAT:
LD A,(NABUKB_KSTAT) ; GET KEY WAITING STATUS
OR A ; SET FLAGS
#IF (INTMODE > 0)
JR Z,NABUKB_STATX ; BAIL OUT W/ Z (NO KEY)
RET ; KEY WAITING, ALL SET
#ELSE
RET NZ ; KEY WAITING, ALL SET
IN A,(NABUKB_IOSTAT) ; GET KBD STATUS
AND $02 ; CHECK DATA RDY BIT
JR Z,NABUKB_STATX ; BAIL OUT W/ Z (NO KEY)
IN A,(NABUKB_IODAT) ; GET THE KEY
CALL NABUKB_XB ; TRANSLATE AND BUFFER KEY
LD A,(NABUKB_KSTAT) ; GET NEW KEY WAITING STATUS
CALL NABUKB_XB ; TRANSLATE/FILTER
JR C,NABUKB_STATX ; IF CF SET, IGNORE
LD (NABUKB_KEY),A ; BUFFER IT
LD A,1 ; SIGNAL KEY WAITING
LD (NABUKB_KSTAT),A ; SAVE IT
OR A ; SET FLAGS
RET ; DONE
#ENDIF
;
NABUKB_STATX:
XOR A ; SIGNAL NO CHAR READY
JP CIO_IDLE ; RETURN VIA IDLE PROCESSOR
;
; ROUTINE TO TRANSLATE AND BUFFER INCOMING NABU KEYBOARD KEYCODES
#ELSE
NABUKB_STAT:
LD A,(NABUKB_BUFCNT) ; GET BUFFER UTILIZATION COUNT
OR A ; SET FLAGS
JP Z,CIO_IDLE ; NOT READY, RETURN VIA IDLE PROCESSING
RET ; DONE
#ENDIF
;
; ROUTINE TO FILTER AND TRANSLATE INCOMING NABU KEYBOARD KEYCODES
; ENTER WITH RAW KEY CODE IN A
; RESULT IN A, CF SET IF THE KEY SHOULD BE DISCARDED
;
NABUKB_XB:
; $00 - $7F ARE NORMAL ASCII CHARS (PASS THROUGH)
BIT 7,A ; HIGH BIT IS SPECIAL CHAR
JR Z,NABUKB_XB2 ; IF NORMAL CHAR, BUFFER IT
CP $90 ; START OF ERR CODES
JR C,NABUKB_XB1 ; NOT ERR CODE, CONTINUE
JR Z,NABUKB_XB2 ; IF NORMAL CHAR, RETURN W/ CF CLEAR
; $80-$8F ARE JOSYSTICK PREFIXES (PASS THESE THROUGH)
CP $90 ; END OF JOYSTICK PREFIXES
JR C,NABUKB_XB2 ; IF JOY PRE, RETURN W/ CF CLEAR
; $90-$9F ARE KEYBOARD ERROR CODES (IGNORE THESE)
CP $A0 ; END OF ERR CODES
JR NC,NABUKB_XB1 ; NOT ERR CODE, CONTINUE
RET ; DISCARD ERR CODE AND RETURN
NABUKB_XB1:
CP $E0 ; SPECIAL CHARACTER?
JR C,NABUKB_XB2 ; IF NOT, SKIP XLAT, BUFFER KEY
CALL NABUKB_XLAT ; IF SO, TRANSLATE IT
RET C ; CF INDICATES INVALID, DISCARD AND RETURN
NABUKB_XB2:
LD (NABUKB_KEY),A ; BUFFER IT
LD A,1 ; SIGNAL KEY WAITING
LD (NABUKB_KSTAT),A ; SAVE IT
RET ; DONE
;
; ROUTINE TO TRANSLATE SPECIAL NABU KEYBOARD KEY CODES
;
NABUKB_XLAT:
JR C,NABUKB_XB1 ; IF ERR CODE, RETURN W/ CF SET
; $A0-$BF ARE JOYSTICK DATA (PASS THESE THROUGH)
CP $C0 ; END OF JOYSTICK DATA
JR C,NABUKB_XB2 ; IF JOY DATA, RETURN W/ CF CLEAR
; $C0-$DF ARE UNUSED CODES (IGNORE THESE)
CP $E0 ; END OF UNUSED CODES
JR C,NABUKB_XB1 ; IF UNUSED CODE, RETURN W/ CF SET
; NABU KEYBOARD USES $E0-$FF FOR SPECIAL KEYS
; HERE WE TRANSLATE TO ROMWBW SPECIAL KEYS AS BEST WE CAN
; CF IS SET ON RETURN IF KEY IS INVALID (NO TRANSLATION)
SUB $E0 ; ZERO OFFSET
RET C ; ABORT IF < $E0, CF SET!
LD HL,NABUKB_XTBL ; POINT TO XLAT TABLE
CALL ADDHLA ; OFFSET BY SPECIAL KEY VAL
LD A,(HL) ; GET TRANSLATED VALUE
OR A ; CHECK FOR N/A (0)
RET NZ ; XLAT OK, RET W/ CF CLEAR
SCF ; SIGNAL INVALID
NABUKB_XB1:
; RETURN W/ CF SET (DISCARD RESULT)
SCF ; ELSE SIGNAL INVALID
RET ; DONE
;
NABUKB_XLAT1:
SCF ; SIGNAL INVALID
RET ; AND DONE
NABUKB_XB2:
; RETURN W/ CF CLEAR (KEEP RESULT)
OR A ; CLEAR CF
RET ; RETURN, CF CLEAR
;
; FLUSH KEYBOARD BUFFER
;
NABUKB_FLUSH:
#IF (INTMODE == 0)
XOR A
LD (NABUKB_KSTAT),A
#ELSE
; RESET THE RECEIVE BUFFER
LD DE,NABUKB_RCVBUF ; DE := CNT
XOR A ; A := 0
LD (DE),A ; _CNT = 0
INC DE ; DE := ADR OF _HD
PUSH DE ; SAVE IT
INC DE
INC DE
INC DE
INC DE ; DE := ADR OF _BUF
POP HL ; HL := ADR OF _HD
LD (HL),E
INC HL
LD (HL),D ; _HD := _BUF
INC HL
LD (HL),E
INC HL
LD (HL),D ; _TL := _BUF
#ENDIF
RET
;
; WAIT FOR A KEY TO BE READY AND RETURN IT.
;
#IF (INTMODE == 0)
NABUKB_READ:
CALL NABUKB_STAT ; CHECK FOR KEY READY
JR Z,NABUKB_READ ; LOOP TIL ONE IS READY
@ -187,6 +244,46 @@ NABUKB_READ:
LD D,A ; NO KEYSTATE
LD (NABUKB_KSTAT),A ; CLEAR KEY WAITING STATUS
RET ; AND RETURN
#ELSE
;
NABUKB_READ:
CALL NABUKB_STAT ; SEE IF CHAR AVAILABLE
JR Z,NABUKB_READ ; LOOP UNTIL SO
HB_DI ; AVOID COLLISION WITH INT HANDLER
LD HL,NABUKB_RCVBUF ; SET HL TO START OF BUF STRUCT
LD A,(HL) ; GET COUNT
DEC A ; DECREMENT COUNT
LD (HL),A ; SAVE UPDATED COUNT
INC HL ; HL := ADR OF TAIL PTR
INC HL ; "
INC HL ; "
PUSH HL ; SAVE ADR OF TAIL PTR
LD A,(HL) ; DEREFERENCE HL
INC HL
LD H,(HL)
LD L,A ; HL IS NOW ACTUAL TAIL PTR
LD C,(HL) ; C := CHAR TO BE RETURNED
INC HL ; BUMP TAIL PTR
POP DE ; RECOVER ADR OF TAIL PTR
LD A,L ; GET LOW BYTE OF TAIL PTR
SUB NABUKB_BUFSZ+2 ; SUBTRACT SIZE OF BUFFER AND POINTER
CP E ; IF EQUAL TO START, TAIL PTR IS PAST BUF END
JR NZ,NABUKB_READ2 ; IF NOT, BYPASS
LD H,D ; SET HL TO
LD L,E ; ... TAIL PTR ADR
INC HL ; BUMP PAST TAIL PTR
INC HL ; ... SO HL NOW HAS ADR OF ACTUAL BUFFER START
NABUKB_READ2:
EX DE,HL ; DE := TAIL PTR VAL, HL := ADR OF TAIL PTR
LD (HL),E ; SAVE UPDATED TAIL PTR
INC HL ; "
LD (HL),D ; "
LD E,C ; MOVE CHAR TO RETURN TO E
HB_EI ; INTERRUPTS OK AGAIN
XOR A ; SIGNAL SUCCESS
RET ; AND DONE
;
#ENDIF
;
; HELPER ROUTINE TO WRITE
;
@ -201,8 +298,20 @@ NABUKB_PUT:
;
;
;
#IF (INTMODE == 0)
NABUKB_KSTAT .DB 0 ; KEY STATUS
NABUKB_KEY .DB 0 ; KEY BUFFER
#ELSE
;
; RECEIVE BUFFER
;
NABUKB_RCVBUF:
NABUKB_BUFCNT .DB 0 ; CHARACTERS IN RING BUFFER
NABUKB_HD .DW NABUKB_BUF ; BUFFER HEAD POINTER
NABUKB_TL .DW NABUKB_BUF ; BUFFER TAIL POINTER
NABUKB_BUF .FILL NABUKB_BUFSZ,0 ; RECEIVE RING BUFFER
NABUKB_BUFEND .EQU $ ; END OF BUFFER
#ENDIF
;
; THIS TABLE TRANSLATES THE NABU KEYBOARD SPECIAL CHARS INTO
; ANALOGOUS ROMWBW STANDARD SPECIAL CHARACTERS. THE TABLE STARTS WITH

2
Source/HBIOS/util.asm

@ -101,8 +101,8 @@ PRTCH:
PUSH AF
LD A,(HL)
CALL COUT
POP AF
INC HL
POP AF
EX (SP),HL
RET
;

2
Source/ver.inc

@ -2,7 +2,7 @@
#DEFINE RMN 5
#DEFINE RUP 0
#DEFINE RTP 0
#DEFINE BIOSVER "3.5.0-dev.42"
#DEFINE BIOSVER "3.5.0-dev.43"
#define rmj RMJ
#define rmn RMN
#define rup RUP

2
Source/ver.lib

@ -3,5 +3,5 @@ rmn equ 5
rup equ 0
rtp equ 0
biosver macro
db "3.5.0-dev.42"
db "3.5.0-dev.43"
endm

Loading…
Cancel
Save