mirror of https://github.com/wwarthen/RomWBW.git
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.
384 lines
11 KiB
384 lines
11 KiB
;======================================================================
|
|
; NABU KEYBOARD DRIVER
|
|
;
|
|
; CREATED BY: LES BIRD
|
|
;
|
|
;======================================================================
|
|
;
|
|
; NABU KEYBOARD CODES:
|
|
;
|
|
; $00-$7F STANDARD ASCII CODES
|
|
; $80-$8F JOYSTICK PREFIXES ($80 = JS1, $81 = JS2)
|
|
; $90-$9F KEYBOARD ERROR CODES
|
|
; $A0-$BF JOYSTICK DATA
|
|
; $C0-$DF UNUSED
|
|
; $E0-$EF SPECIAL KEYS
|
|
;
|
|
; NOTE THAT THE ERROR CODE $94 IS A WATCHDOG TIMER THAT WILL BE
|
|
; SENT BY THE KEYBOARD EVERY 3.7 SECONDS.
|
|
;
|
|
; THE CODE BELOW WILL IGNORE (SWALLOW) THE ERROR CODES ($90-$9F) AND
|
|
; 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
|
|
DEVECHO "\n"
|
|
;
|
|
;--------------------------------------------------------------------------------------------------
|
|
; HBIOS MODULE HEADER
|
|
;--------------------------------------------------------------------------------------------------
|
|
;
|
|
ORG_NABUKB .EQU $
|
|
;
|
|
.DW SIZ_NABUKB ; MODULE SIZE
|
|
.DW NABUKB_INITPHASE ; ADR OF INIT PHASE HANDLER
|
|
;
|
|
NABUKB_INITPHASE:
|
|
; INIT PHASE HANDLER, A=PHASE
|
|
;CP HB_PHASE_PREINIT ; PREINIT PHASE?
|
|
;JP Z,NABUKB_PREINIT ; DO PREINIT
|
|
CP HB_PHASE_INIT ; INIT PHASE?
|
|
JP Z,NABUKB_INIT ; DO INIT
|
|
RET ; DONE
|
|
;
|
|
; INITIALZIZE THE KEYBOARD CONTROLLER.
|
|
;
|
|
NABUKB_INIT:
|
|
CALL NEWLINE
|
|
PRTS("NABUKB: IO=0x$")
|
|
LD A,NABUKB_IODAT
|
|
CALL PRTHEXBYTE
|
|
;
|
|
XOR A
|
|
CALL NABUKB_PUT
|
|
CALL NABUKB_PUT
|
|
CALL NABUKB_PUT
|
|
CALL NABUKB_PUT
|
|
CALL NABUKB_PUT
|
|
LD A,$40 ; RESET 8251
|
|
CALL NABUKB_PUT
|
|
LD A,$4E ; 1 STOP BIT, 8 BITS, 64X CLK
|
|
CALL NABUKB_PUT
|
|
LD A,$04 ; ENABLE RECV
|
|
CALL NABUKB_PUT
|
|
;
|
|
#IF (INTMODE == 1)
|
|
; ADD TO INTERRUPT CHAIN
|
|
LD HL,NABUKB_INT
|
|
CALL HB_ADDIM1 ; ADD TO IM1 CALL LIST
|
|
#ENDIF
|
|
;
|
|
#IF (INTMODE == 2)
|
|
; INSTALL VECTOR
|
|
LD HL,NABUKB_INT
|
|
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
|
|
LD A,(NABU_CTLVAL) ; GET NABU CTL PORT SHADOW REG
|
|
SET 5,A ; ENABLE VDP INTERRUPTS
|
|
LD (NABU_CTLVAL),A ; UPDATE SHADOW REG
|
|
OUT (NABU_RDAT),A ; WRITE TO HARDWARE
|
|
#ENDIF
|
|
;
|
|
XOR A
|
|
RET
|
|
;
|
|
#IF (INTMODE > 0)
|
|
;
|
|
; INTERRUPT HANDLER FOR NABU KEYBOARD. HANDLES INTERRUPTS FOR EITHER
|
|
; INT MODE 1 OR INT MODE 2. THE KEYBOARD BUFFER IS JUST A SINGLE CHAR
|
|
; AT THIS POINT. NEW CHARACTERS ARRIVING WHEN THE BUFFER IS FULL WILL
|
|
; BE DISCARDED.
|
|
;
|
|
NABUKB_INT:
|
|
IN A,(NABUKB_IOSTAT) ; GET KBD STATUS
|
|
AND $02 ; CHECK DATA RDY BIT
|
|
RET Z ; ABORT W/ Z (INT NOT HANDLED)
|
|
;
|
|
;CALL PC_LT ; *DEBUG*
|
|
IN A,(NABUKB_IODAT) ; GET THE KEY
|
|
;CALL PRTHEXBYTE ; *DEBUG*
|
|
;CALL PC_COMMA ; *DEBUG*
|
|
CALL NABUKB_XB ; TRANSLATE THE KEY
|
|
;CALL PRTHEXBYTE ; *DEBUG*
|
|
;CALL PC_GT ; *DEBUG*
|
|
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
|
|
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/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
|
|
;
|
|
NABUKB_STATX:
|
|
XOR A ; SIGNAL NO CHAR READY
|
|
JP CIO_IDLE ; RETURN VIA IDLE PROCESSOR
|
|
;
|
|
#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, 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 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
|
|
SUB $E0 ; ZERO OFFSET
|
|
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
|
|
NABUKB_XB1:
|
|
; RETURN W/ CF SET (DISCARD RESULT)
|
|
SCF ; ELSE SIGNAL INVALID
|
|
RET ; 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
|
|
LD A,(NABUKB_KEY) ; GET THE BUFFERED KEY
|
|
LD E,A ; PUT IN E FOR RETURN
|
|
XOR A ; ZERO TO ACCUM
|
|
LD C,A ; NO SCANCODE
|
|
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
|
|
;
|
|
NABUKB_PUT:
|
|
OUT (NABUKB_IOSTAT),A
|
|
NOP
|
|
NOP
|
|
NOP
|
|
NOP
|
|
NOP
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
#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
|
|
; NABU KEY CODE $E0 AND HANDLES $20 POSSIBLE VALUES ($E0-$FF)
|
|
; THE SPECIAL KEYS SEND A SPECIFIC KEYCODE TO INDICATE DOWN (KEY
|
|
; PRESSED) AND UP (KEY RELEASED). WE WILL ARBITRARILY CHOOSE TO
|
|
; RESPOND TO KEY PRESSED. a TRANSLATION VALUE OF $00 MEANS THAT THE
|
|
; KEY CODE SHOULD BE DISCARDED.
|
|
;
|
|
NABUKB_XTBL:
|
|
.DB $F9 ; $E0, RIGHT ARROW (DN) -> RIGHT ARROW
|
|
.DB $F8 ; $E1, LEFT ARROW (DN) -> LEFT ARROW
|
|
.DB $F6 ; $E2, UP ARROW (DN) -> UP ARROW
|
|
.DB $F7 ; $E3, DOWN ARROW (DN) -> DOWN ARROW
|
|
.DB $F5 ; $E4, PAGE RIGHT (DN) -> PAGE DOWN
|
|
.DB $F4 ; $E5, PAGE LEFT (DN) -> PAGE UP
|
|
.DB $F3 ; $E6, NO (DN) -> END
|
|
.DB $F2 ; $E7, YES (DN) -> HOME
|
|
.DB $EE ; $E8, SYM (DN) -> SYSRQ
|
|
.DB $EF ; $E9, PAUSE (DN) -> PAUSE
|
|
.DB $00 ; $EA, TV/NABU (DN) -> APP
|
|
.DB $00 ; $EB, N/A
|
|
.DB $00 ; $EC, N/A
|
|
.DB $00 ; $ED, N/A
|
|
.DB $00 ; $EE, N/A
|
|
.DB $00 ; $EF, N/A
|
|
.DB $00 ; $F0, RIGHT ARROW (UP)
|
|
.DB $00 ; $F1, LEFT ARROW (UP)
|
|
.DB $00 ; $F2, UP ARROW (UP)
|
|
.DB $00 ; $F3, DOWN ARROW (UP)
|
|
.DB $00 ; $F4, PAGE RIGHT (UP)
|
|
.DB $00 ; $F5, PAGE LEFT (UP)
|
|
.DB $00 ; $F6, NO (UP)
|
|
.DB $00 ; $F7, YES (UP)
|
|
.DB $00 ; $F8, SYM (UP)
|
|
.DB $00 ; $F9, PAUSE (UP)
|
|
.DB $00 ; $FA, TV/NABU (UP)
|
|
.DB $00 ; $FB, N/A
|
|
.DB $00 ; $FC, N/A
|
|
.DB $00 ; $FD, N/A
|
|
.DB $00 ; $FE, N/A
|
|
.DB $00 ; $FF, N/A
|
|
;
|
|
;--------------------------------------------------------------------------------------------------
|
|
; HBIOS MODULE TRAILER
|
|
;--------------------------------------------------------------------------------------------------
|
|
;
|
|
END_NABUKB .EQU $
|
|
SIZ_NABUKB .EQU END_NABUKB - ORG_NABUKB
|
|
;
|
|
MEMECHO "NABUKB occupies "
|
|
MEMECHO SIZ_NABUKB
|
|
MEMECHO " bytes.\n"
|
|
|