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.
630 lines
21 KiB
630 lines
21 KiB
;__________________________________________________________________________________________________
|
|
;
|
|
; PARALLEL PORT KEYBOARD DRIVER FOR N8VEM
|
|
; SUPPORT KEYBOARD/MOUSE ON VDU AND N8
|
|
;
|
|
; ORIGINAL CODE BY DR JAMES MOXHAM
|
|
; ROMWBW ADAPTATION BY WAYNE WARTHEN
|
|
;__________________________________________________________________________________________________
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
; DATA CONSTANTS
|
|
;__________________________________________________________________________________________________
|
|
;
|
|
#IF (PLATFORM == PLT_N8)
|
|
PPK_PPI .EQU PPI2 ; PPI PORT BASE FOR N8
|
|
#ELSE
|
|
PPK_PPI .EQU 0F4H ; PPI PORT BASE FOR VDU
|
|
#ENDIF
|
|
|
|
PPK_PPIA .EQU PPK_PPI + 0 ; KEYBOARD PPI PORT A
|
|
PPK_PPIB .EQU PPK_PPI + 1 ; KEYBOARD PPI PORT B
|
|
PPK_PPIC .EQU PPK_PPI + 2 ; KEYBOARD PPI PORT C
|
|
PPK_PPIX .EQU PPK_PPI + 3 ; KEYBOARD PPI CONTROL PORT
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
; KEYBOARD INITIALIZATION
|
|
;__________________________________________________________________________________________________
|
|
;
|
|
PPK_INIT:
|
|
CALL PPK_SETPORTC ; SETS PORT C SO CAN INPUT AND OUTPUT
|
|
CALL PPK_RESET ; RESET TO THE KEYBOARD
|
|
LD A,200 ; 1 SECOND DELAY AS KEYBOARD SENDS STUFF BACK WHEN RESET
|
|
CALL PPK_DELAY ; IGNORE ANYTHING BACK AFTER A RESET
|
|
LD A,0 ; EMPTY KB QUEUE
|
|
LD (PPK_QLEN),A
|
|
XOR A
|
|
RET
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
; KEYBOARD STATUS
|
|
;__________________________________________________________________________________________________
|
|
;
|
|
PPK_STAT:
|
|
CALL PPK_PROCESS ; CALL KEYBOARD ROUTINE
|
|
LD A,(PPK_QLEN) ; ASK IF KEYBOARD HAS KEY WAITING
|
|
OR A ; SET FLAGS
|
|
JP Z,CIO_IDLE ; NO DATA, EXIT VIA IDLE PROCESSING
|
|
LD A,$FF ; SIGNAL DATA PENDING
|
|
RET
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
; KEYBOARD READ
|
|
;__________________________________________________________________________________________________
|
|
;
|
|
PPK_READ:
|
|
CALL PPK_STAT ; CHECK TO SEE IF KEY READY
|
|
JR Z,PPK_READ ; IF NOT, LOOP
|
|
CALL PPK_GETKEY ; GET IT
|
|
LD E,A ; PUT KEY WHERE IT BELONGS
|
|
XOR A ; SIGNAL SUCCESS
|
|
RET
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
; KEYBOARD FLUSH
|
|
;__________________________________________________________________________________________________
|
|
;
|
|
PPK_FLUSH:
|
|
LD A,0 ; EMPTY KB QUEUE
|
|
LD (PPK_QLEN),A ; SAVE IT
|
|
XOR A ; SIGNAL SUCCESS
|
|
RET
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
;__PPK_GETKEY______________________________________________________________________________________
|
|
;
|
|
; GET KEY PRESS VALUE
|
|
;__________________________________________________________________________________________________
|
|
PPK_GETKEY:
|
|
LD A,(PPK_QLEN) ; GET QUEUE POINTER
|
|
OR A
|
|
RET Z ; ABORT IF QUEUE EMPTY
|
|
PUSH BC ; STORE BC
|
|
LD B,A ; STORE QUEUE COUNT FOR LATER
|
|
PUSH HL ; STORE HL
|
|
LD A,(PPK_QUEUE) ; GET TOP BYTE FROM QUEUE
|
|
PUSH AF ; STORE IT
|
|
LD HL,PPK_QUEUE ; GET POINTER TO QUEUE
|
|
PPK_GETKEY1: ;
|
|
INC HL ; POINT TO NEXT VALUE IN QUEUE
|
|
LD A,(HL) ; GET VALUE
|
|
DEC HL ;
|
|
LD (HL),A ; MOVE IT UP ONE
|
|
INC HL ;
|
|
DJNZ PPK_GETKEY1 ; LOOP UNTIL DONE
|
|
LD A,(PPK_QLEN) ; DECREASE QUEUE POINTER BY ONE
|
|
DEC A ;
|
|
LD (PPK_QLEN),A
|
|
POP AF ; RESTORE VALUE
|
|
POP HL ; RESTORE HL
|
|
POP BC ; RESTORE BC
|
|
RET
|
|
|
|
;__PPK_RESET________________________________________________________________________________________
|
|
;
|
|
; RESET THE KEYBOARD
|
|
;__________________________________________________________________________________________________
|
|
PPK_RESET:
|
|
CALL PPK_DATAHIGH ;
|
|
CALL PPK_CLOCKHIGH ;
|
|
LD B,255 ;
|
|
SF1: DJNZ SF1 ;
|
|
CALL PPK_CLOCKLOW ; STEP 1
|
|
LD B,255 ;
|
|
SF2: DJNZ SF2 ;
|
|
CALL PPK_DATALOW ; STEP 2
|
|
CALL PPK_CLOCKHIGH ; STEP 3
|
|
CALL PPK_WAITCLOCKLOW ; STEP 4
|
|
LD B,9 ; 8 DATA BITS + 1 PARITY BIT LOW
|
|
SF3: PUSH BC ;
|
|
CALL PPK_DATAHIGH ; STEP 5
|
|
CALL PPK_WAITCLOCKHIGH ; STEP 6
|
|
CALL PPK_WAITCLOCKLOW ; STEP 7
|
|
POP BC ;
|
|
DJNZ SF3 ;
|
|
CALL PPK_DATAHIGH ; STEP9
|
|
CALL PPK_WAITCLOCKLOW ; STEP 10 COULD READ THE ACK BIT HERE IF WANT TO
|
|
CALL PPK_WAITCLOCKHIGH ; STEP 11
|
|
LD B,255 ;
|
|
SF4: DJNZ SF4 ; FINISH UP DELAY
|
|
RET
|
|
|
|
;__PPK_SETPORTC_____________________________________________________________________________________
|
|
;
|
|
; SETUP PORT C OF 8255 FOR KEYBOARD
|
|
;__________________________________________________________________________________________________
|
|
PPK_SETPORTC:
|
|
LD A,10000010B ; A=OUT B=IN, C HIGH=OUT, CLOW=OUT
|
|
OUT (PPK_PPIX),A ; PPI CONTROL PORT
|
|
LD A,00000000B ; PORT A TO ZERO AS NEED THIS FOR COMMS TO WORK
|
|
OUT (PPK_PPIA),A ; PPI PORT A
|
|
CALL PPK_DATAHIGH ;
|
|
CALL PPK_CLOCKHIGH ;
|
|
LD A,0 ;
|
|
LD (CAPSLOCK),A ; SET CAPSLOCK OFF TO START
|
|
LD (CTRL),A ; CONTROL OFF
|
|
LD (NUMLOCK),A ; NUMLOCK OFF
|
|
RET
|
|
;_________________________________________________________________________________________________
|
|
;
|
|
; PORT C BIT ROUTINES
|
|
;__________________________________________________________________________________________________
|
|
PPK_PORTCBIT0HIGH: ;
|
|
LD A,01110001B ; SEE THE 8255 DATA SHEET
|
|
JP PPK_SETBITS ;
|
|
PPK_PORTCBIT1HIGH: ;
|
|
LD A,01110011B ; SEE THE 8255 DATA SHEET
|
|
JP PPK_SETBITS ;
|
|
PPK_PORTCBIT2HIGH: ;
|
|
LD A,01110101B ; SEE THE 8255 DATA SHEET
|
|
JP PPK_SETBITS ;
|
|
PPK_PORTCBIT3HIGH: ;
|
|
LD A,01110111B ; SEE THE 8255 DATA SHEET
|
|
JP PPK_SETBITS ;
|
|
PPK_PORTCBIT0LOW: ;
|
|
LD A,01110000B ; SEE THE 8255 DATA SHEET
|
|
JP PPK_SETBITS ;
|
|
PPK_PORTCBIT1LOW: ;
|
|
LD A,01110010B ; SEE THE 8255 DATA SHEET
|
|
JP PPK_SETBITS ;
|
|
PPK_PORTCBIT2LOW: ;
|
|
LD A,01110100B ; SEE THE 8255 DATA SHEET
|
|
JP PPK_SETBITS ;
|
|
PPK_PORTCBIT3LOW: ;
|
|
LD A,01110110B ; SEE THE 8255 DATA SHEET
|
|
JP PPK_SETBITS ;
|
|
PPK_DATAHIGH:
|
|
PPK_PORTCBIT4HIGH: ;
|
|
LD A,01111001B ; SEE THE 8255 DATA SHEET
|
|
JP PPK_SETBITS ;
|
|
PPK_DATALOW: ;
|
|
PPK_PORTCBIT4LOW: ;
|
|
LD A,01111000B ; SEE THE 8255 DATA SHEET
|
|
JP PPK_SETBITS ;
|
|
PPK_CLOCKHIGH: ;
|
|
PPK_PORTCBIT5HIGH: ;
|
|
LD A,01111011B ; BIT 5 HIGH
|
|
JP PPK_SETBITS ;
|
|
PPK_CLOCKLOW: ;
|
|
PORTCBIT5LOW: ;
|
|
LD A,01111010B ;
|
|
PPK_SETBITS: ;
|
|
OUT (PPK_PPIX),A ;
|
|
RET ;
|
|
|
|
;__PPK_WAITCLOCKLOW_________________________________________________________________________________
|
|
;
|
|
; WAITCLOCKLOW SAMPLES DATA BIT 0, AND WAITS TILL
|
|
; IT GOES LOW, THEN RETURNS
|
|
; ALSO TIMES OUT AFTER 0 001 SECONDS
|
|
; USES A, CHANGES B
|
|
;__________________________________________________________________________________________________
|
|
PPK_WAITCLOCKLOW:
|
|
LD B,255 ; FOR TIMEOUT COUNTER
|
|
PPK_WAITCLOCKLOW1:
|
|
IN A,(PPK_PPIB) ; GET A BYTE FROM PORT B
|
|
BIT 1,A ; TEST THE CLOCK BIT
|
|
RET Z ; EXIT IF IT WENT LOW
|
|
DJNZ PPK_WAITCLOCKLOW1 ; LOOP B TIMES
|
|
RET
|
|
|
|
;__PPK_WAITCLOCKHIGH_________________________________________________________________________________
|
|
;
|
|
; WAITCLOCKHIGH SAMPLES DATA BIT 0, AND WAITS TILL
|
|
; IT GOES HIGH, THEN RETURNS
|
|
; ALSO TIMES OUT AFTER 0 001 SECONDS
|
|
; USES A, CHANGES B
|
|
;__________________________________________________________________________________________________
|
|
PPK_WAITCLOCKHIGH:
|
|
LD B,255 ; FOR TIMEOUT COUNTER
|
|
PPK_WAITCLOCKHIGH1:
|
|
IN A,(PPK_PPIB) ; GET A BYTE FROM PORT B
|
|
BIT 1,A ; TEST THE CLOCK BIT
|
|
RET NZ ; EXIT IF IT WENT HIGH
|
|
DJNZ PPK_WAITCLOCKHIGH1 ; LOOP B TIMES
|
|
RET
|
|
|
|
;__PPK_DELAY________________________________________________________________________________________
|
|
;
|
|
; PASS A - DELAY IS B*0 005 SECONDS, BCDEHL ALL PRESERVED
|
|
;__________________________________________________________________________________________________
|
|
PPK_DELAY:
|
|
PUSH BC ; STORE ALL VARIABLES
|
|
PUSH DE ;
|
|
PUSH HL ;
|
|
LD B,A ; PUT THE VARIABLE DELAY IN B
|
|
LD DE,1 ;
|
|
PPK_DELAY1:
|
|
LD HL,740 ; ADJUST THIS VALUE FOR YOUR CLOCK 1481=3 68MHZ, 3219=8MHZ (TEST WITH A=1000=10 SECS)
|
|
PPK_DELAY2:
|
|
SBC HL,DE ; HL-1
|
|
JR NZ,PPK_DELAY2
|
|
DJNZ PPK_DELAY1
|
|
POP HL ; RESTORE VARIABLES
|
|
POP DE ;
|
|
POP BC ;
|
|
RET ;
|
|
|
|
;__PPK_PROCESS______________________________________________________________________________________
|
|
;
|
|
; A=0 IF WANT TO KNOW IF A BYTE IS AVAILABLE, AND A=1 TO ASK FOR THE BYTE
|
|
;__________________________________________________________________________________________________
|
|
PPK_PROCESS:
|
|
CALL PPK_SKIP ; DON'T TEST EVERY ONE AS TAKES TIME
|
|
OR A ; IS IT ZERO
|
|
RET Z ; RETURN IF ZERO
|
|
CALL PPK_WAITBYTE ; TEST KEYBOARD TIMES OUT AFTER A BIT
|
|
CALL PPK_DECODECHAR ; RETURNS CHAR OR 0 FOR THINGS LIKE KEYUP, SOME RETURN DIRECTLY TO CP/M
|
|
RET ; RETURN TO CP/M
|
|
|
|
;-----------------------------------------------
|
|
; CPM CALLS THE KEYBOARD QUITE FREQUENTLY IF A KEYBOARD WAS LIKE A UART WHICH CAN BE CHECKED
|
|
; WITH ONE INSTRUCTION, THAT WOULD BE FINE BUT CHECKING A KEYBOARD INVOLVES PUTTING THE CLOCK LINE LOW
|
|
; THEN WAITING SOME TIME FOR A POSSIBLE REPLY, THEN READING IN BITS WITH TIMEOUTS AND THEN RETURNING
|
|
; THIS SLOWS DOWN A LOT OF CP/M PROCESSES, EG TRY TYPE MYPROG AND PRINTING OUT TEXT
|
|
PPK_SKIP:
|
|
LD B,0 ;
|
|
LD A,(SKIPCOUNT) ;
|
|
DEC A ; SUBTRACT 1
|
|
LD (SKIPCOUNT),A ; STORE IT BACK
|
|
CP 0 ;
|
|
JP NZ,PPK_SKIP1 ; WORDSTAR IS VERY SLOW EVEN TRIED A VALUE OF 5 TO 200 HERE
|
|
LD A,200 ; ONLY ACT ON EVERY N CALLS - BIGGER=BETTER BECAUSE THIS SUB IS QUICKER THAN READBITS
|
|
LD (SKIPCOUNT),A ; RESET COUNTER
|
|
LD B,1 ; FLAG TO SAY RESET COUNTER
|
|
PPK_SKIP1: ;
|
|
LD A,B ; RETURN THE VALUE IN A
|
|
RET
|
|
|
|
;__PPK_DECODECHAR____________________________________________________________________________________
|
|
;
|
|
; DECODE CHARACTER PASS A AND PRINTS OUT THE CHAR
|
|
; ON THE LCD SCREEN
|
|
;__________________________________________________________________________________________________
|
|
PPK_DECODECHAR:
|
|
CP 0 ; IS IT ZERO
|
|
RET Z ; RETURN IF A ZERO - NO NEED TO DO ANYTHING
|
|
CP 0F0H ; IS A KEY UP (NEED TO DO SPECIAL CODE FOR SHIFT)
|
|
JP Z,DECKEYUP ; IGNORE CHAR UP
|
|
CP 0E0H ; TWO BYTE KEYPRESSES
|
|
JP Z,TWOBYTE ;
|
|
CP 058H ; CAPS LOCK SO TOGGLE
|
|
JP Z,CAPSTOG ;
|
|
CP 12H ; SHIFT (DOWN, BECAUSE UP WOULD BE TRAPPED BY 0F ABOVE)
|
|
JP Z,SHIFTDOWN ;
|
|
CP 59H ; OTHER SHIFT KEY
|
|
JP Z,SHIFTDOWN ;
|
|
CP 014H ; CONTROL KEY
|
|
JP Z,CONTROLDOWN ;
|
|
CP 05AH ; ENTER KEY
|
|
JP Z,RETURN ;
|
|
CP 066H ; BACKSPACE KEY
|
|
JP Z,BACKSPACE ;
|
|
CP 0DH ; TAB KEY
|
|
JP Z,TABKEY ;
|
|
CP 076H ; ESCAPE KEY
|
|
JP Z,ESCAPE ;
|
|
LD C,A ;
|
|
LD B,0 ; ADD BC TO HL
|
|
LD HL,PPK_KEYMAP ; OFFSET TO ADD
|
|
ADD HL,BC ;
|
|
JP TESTCONTROL ; IS THE CONTROL KEY DOWN?
|
|
DC1: LD A,(CAPSLOCK) ;
|
|
CP 0 ; IS IT 0, IF SO THEN DON'T ADD THE CAPS OFFSET
|
|
JR Z,DC2 ;
|
|
LD C,080H ; ADD ANOTHER 50H TO SMALLS TO GET CAPS
|
|
ADD HL,BC ;
|
|
DC2: LD A,(HL) ;
|
|
CALL PPK_ENQUEUE ; STORE ON KB QUEUE
|
|
RET ;
|
|
TESTCONTROL:
|
|
LD A,(CTRL) ;
|
|
CP 0 ; IS CONTROL BEING HELD DOWN?
|
|
JP Z,DC1 ; NO SO GO BACK TO TEST CAPS LOCK ON
|
|
LD A,(HL) ; GET THE LETTER, SHOULD BE SMALLS
|
|
SUB 96 ; A=97 SO SUBTRACT 96 A=1=^A
|
|
CALL PPK_ENQUEUE ; STORE ON KB QUEUE
|
|
RET ; RETURN INSTEAD OF THE RET AFTER DC2
|
|
TABKEY: ;
|
|
LD A,9 ;
|
|
CALL PPK_ENQUEUE ; STORE ON KB QUEUE
|
|
RET ;TAB
|
|
BACKSPACE: ;
|
|
LD A,8 ; BACKSPACE
|
|
CALL PPK_ENQUEUE ; STORE ON KB QUEUE
|
|
RET ;
|
|
ESCAPE: ;
|
|
LD A,27 ;
|
|
CALL PPK_ENQUEUE ; STORE ON KB QUEUE
|
|
RET ;
|
|
RETURN: ;
|
|
LD A,13 ; CARRIAGE RETURN
|
|
CALL PPK_ENQUEUE ; STORE ON KB QUEUE
|
|
RET ;
|
|
DECKEYUP:
|
|
CALL PPK_WAITBYTE ; IGNORE KEY UP THROW AWAY THE CHARACTER UNLESS A SHIFT
|
|
CP 012H ; IS IT A SHIFT
|
|
JP Z,SHIFTUP ;
|
|
CP 59H ; OTHER SHIFT KEY
|
|
JP Z,SHIFTUP ;
|
|
CP 014H ; CONTROL UP
|
|
JP Z,CONTROLUP ; CONTROL UP
|
|
LD A,0 ; NOTHING CAPTURED SO SEND BACK A ZERO
|
|
RET
|
|
TWOBYTE:; ALREADY GOT EO SO GET THE NEXT CHARACTER
|
|
CALL PPK_WAITBYTE
|
|
CP 0F0H ; SEE THE NOTES - KEYUP FOR E0 KEYS IS EO F0 NN NOT F0 EO!!
|
|
JP Z,TWOBYTEUP ;
|
|
CP 071H ; DELETE
|
|
JP Z,DELETEKEY ;
|
|
CP 05AH ; RETURN ON NUMBER PAD
|
|
JP Z,RETURNKEY ;
|
|
CP 072H ;
|
|
JP Z,DOWNARROW ;
|
|
CP 074H ;
|
|
JP Z,RIGHTARROW ;
|
|
CP 06BH ;
|
|
JP Z,LEFTARROW ;
|
|
CP 075H ;
|
|
JP Z,UPARROW ;
|
|
CP 070H ;
|
|
JP Z,INSERT ;
|
|
CP 07DH ;
|
|
JP Z,PAGEUP ;
|
|
CP 07AH ;
|
|
JP Z,PAGEDOWN ;
|
|
CP 06CH ;
|
|
JP Z,HOME ;
|
|
CP 069H ;
|
|
JP Z,END ;
|
|
LD A,0 ; RETURNS NOTHING
|
|
RET
|
|
TWOBYTEUP: ;EXPECT A BYTE AND IGNORE IT
|
|
CALL PPK_WAITBYTE ;
|
|
LD A,0 ;
|
|
RET ;
|
|
HOME: ;
|
|
LD A,1BH ; ESC
|
|
CALL PPK_ENQUEUE ; STORE ON KB QUEUE
|
|
LD A,'?' ; ?
|
|
CALL PPK_ENQUEUE ; STORE ON KB QUEUE
|
|
LD A,'W' ; W
|
|
CALL PPK_ENQUEUE ; STORE ON KB QUEUE
|
|
RET ;
|
|
END: ;
|
|
LD A,1BH ; ESC
|
|
CALL PPK_ENQUEUE ; STORE ON KB QUEUE
|
|
LD A,'?' ; ?
|
|
CALL PPK_ENQUEUE ; STORE ON KB QUEUE
|
|
LD A,'Q' ; Q
|
|
CALL PPK_ENQUEUE ; STORE ON KB QUEUE
|
|
RET ;
|
|
DOWNARROW: ;
|
|
LD A,1BH ; ESC
|
|
CALL PPK_ENQUEUE ; STORE ON KB QUEUE
|
|
LD A,'B' ; B
|
|
CALL PPK_ENQUEUE ; STORE ON KB QUEUE
|
|
RET ;
|
|
RIGHTARROW: ;
|
|
LD A,1BH ; ESC
|
|
CALL PPK_ENQUEUE ; STORE ON KB QUEUE
|
|
LD A,'C' ; C
|
|
CALL PPK_ENQUEUE ; STORE ON KB QUEUE
|
|
RET ;
|
|
LEFTARROW: ;
|
|
LD A,1BH ; ESC
|
|
CALL PPK_ENQUEUE ; STORE ON KB QUEUE
|
|
LD A,'D' ; D
|
|
CALL PPK_ENQUEUE ; STORE ON KB QUEUE
|
|
RET ;
|
|
UPARROW: ;
|
|
LD A,1BH ; ESC
|
|
CALL PPK_ENQUEUE ; STORE ON KB QUEUE
|
|
LD A,'A' ; A
|
|
CALL PPK_ENQUEUE ; STORE ON KB QUEUE
|
|
RET ;
|
|
INSERT: ;
|
|
LD A,1BH ; ESC
|
|
CALL PPK_ENQUEUE ; STORE ON KB QUEUE
|
|
LD A,'?' ; ?
|
|
CALL PPK_ENQUEUE ; STORE ON KB QUEUE
|
|
LD A,'P' ; P
|
|
CALL PPK_ENQUEUE ; STORE ON KB QUEUE
|
|
RET ;
|
|
PAGEUP: ;
|
|
LD A,1BH ; ESC
|
|
CALL PPK_ENQUEUE ; STORE ON KB QUEUE
|
|
LD A,'?' ; ?
|
|
CALL PPK_ENQUEUE ; STORE ON KB QUEUE
|
|
LD A,'Y' ; Y
|
|
CALL PPK_ENQUEUE ; STORE ON KB QUEUE
|
|
RET ;
|
|
PAGEDOWN: ;
|
|
LD A,1BH ; ESC
|
|
CALL PPK_ENQUEUE ; STORE ON KB QUEUE
|
|
LD A,'?' ; ?
|
|
CALL PPK_ENQUEUE ; STORE ON KB QUEUE
|
|
LD A,'S' ; S
|
|
CALL PPK_ENQUEUE ; STORE ON KB QUEUE
|
|
RET ;
|
|
CONTROLDOWN: ; SAME CODE AS SHIFTDOWN BUT DIFF LOCATION
|
|
LD A,0FFH ;
|
|
LD (CTRL),A ; CONTROL DOWN
|
|
LD A,0 ;
|
|
RET ;
|
|
CONTROLUP: ; CONTROL KEY UP SEE SHIFT FOR EXPLANATION
|
|
LD A,0 ;
|
|
LD (CTRL),A ;
|
|
LD A,0 ;
|
|
RET ;
|
|
RETURNKEY: ;
|
|
LD A,13 ;
|
|
CALL PPK_ENQUEUE ; STORE ON KB QUEUE
|
|
RET ;
|
|
DELETEKEY: ;
|
|
LD A,07FH ; DELETE KEY VALUE THAT CP/M USES
|
|
CALL PPK_ENQUEUE ; STORE ON KB QUEUE
|
|
RET ;
|
|
CAPSTOG: ;
|
|
LD A,(CAPSLOCK) ;
|
|
XOR 11111111B ; SWAP ALL THE BITS
|
|
LD (CAPSLOCK),A ;
|
|
LD A,0 ; RETURNS NOTHING
|
|
RET ;
|
|
SHIFTDOWN: ; SHIFT IS SPECIAL - HOLD IT DOWN AND IT AUTOREPEATS
|
|
; SO ONCE IT IS DOWN, TURN CAPS ON AND IGNORE ALL FURTHER SHIFTS
|
|
; ONLY AN F0+SHIFT TURNS CAPS LOCK OFF AGAIN
|
|
LD A,0FFH ;
|
|
LD (CAPSLOCK),A ;
|
|
LD A,0 ; RETURNS NOTHING
|
|
RET ;
|
|
SHIFTUP: ; SHIFTUP TURNS OFF CAPS LOCK DEFINITELY
|
|
LD A,0 ;
|
|
LD (CAPSLOCK),A ;
|
|
LD A,0 ; RETURNS NOTHING
|
|
RET ;
|
|
|
|
;__PPK_ENQUEUE______________________________________________________________________________________
|
|
;
|
|
; STORE A BYTE IN THE KEYBOARD QUEUE
|
|
; A: BYTE TO ENQUEUE
|
|
;__________________________________________________________________________________________________
|
|
PPK_ENQUEUE:
|
|
PUSH DE ; STORE DE
|
|
PUSH HL ; STORE HL
|
|
PUSH AF ; STORE VALUE
|
|
LD A,(PPK_QLEN) ; PUT QUEUE POINTER IN A
|
|
CP 15 ; IS QUEUE FULL
|
|
JP P,PPK_ENQUEUE1 ; YES, ABORT
|
|
LD HL,PPK_QUEUE ; GET QUEUE POINTER
|
|
PUSH HL ; MOVE HL TO BC
|
|
POP BC ;
|
|
LD H,0 ; ZERO OUT H
|
|
LD L,A ; PLACE QUEUE POINTER IN L
|
|
ADD HL,BC ; POINT HL AT THE NEXT LOACTION TO ADD VALUE
|
|
POP AF ; RESTORE VALUE
|
|
LD (HL),A ; ENQUEUE VALUE
|
|
LD A,(PPK_QLEN) ; GET QUEUE POINTER
|
|
INC A ; INC IT
|
|
LD (PPK_QLEN),A ;STORE QUEUE POINTER
|
|
PPK_ENQUEUE1:
|
|
POP HL ; RESTORE HL
|
|
POP DE ; RESTORE DE
|
|
RET
|
|
|
|
|
|
;__PPK_WAITBYTE_____________________________________________________________________________________
|
|
;
|
|
; WAIT FOR A BYTE - TESTS A NUMBER OF TIMES IF THERE IS A KEYBOARD INPUT,
|
|
; OVERWRITES ALL REGISTERS, RETURNS BYTE IN A
|
|
;__________________________________________________________________________________________________
|
|
PPK_WAITBYTE:
|
|
CALL PPK_CLOCKHIGH ; TURN ON KEYBOARD
|
|
LD HL,500 ; NUMBER OF TIMES TO CHECK 200=SLOW TYPE
|
|
; 10=ERROR, 25 ?ERROR 50 OK -
|
|
; THIS DELAY HAS TO BE THERE OTHERWISE WEIRD KEYUP ERRORS
|
|
PPK_WAITBYTE1:
|
|
PUSH HL ; STORE COUNTER
|
|
CALL PPK_READBITS ; TEST FOR A LOW ON THE CLOCK LINE
|
|
POP HL ; GET THE COUNTER BACK
|
|
CP 0 ; TEST FOR A ZERO BACK FROM READBITS
|
|
JR NZ,PPK_WAITBYTE2 ; IF NOT A ZERO THEN MUST HAVE A BYTE IE A KEYBOARD PRESS
|
|
LD DE,1 ; LOAD WITH 1
|
|
SBC HL,DE ; SUBTRACT 1
|
|
JR NZ,PPK_WAITBYTE1 ; LOOP WAITING FOR A RESPONSE
|
|
PPK_WAITBYTE2:
|
|
PUSH AF ; STORE THE VALUE IN A
|
|
CALL PPK_CLOCKLOW ; TURN OFF KEYBOARD
|
|
POP AF ; GET BACK BYTE AS CLOCKLOW ERASED IT
|
|
RET
|
|
|
|
;__PPK_READBITS_____________________________________________________________________________________
|
|
;
|
|
; READBITS READS 11 BITS IN FROM THE KEYBOARD
|
|
; FIRST BIT IS A START BIT THEN 8 BITS FOR THE BYTE
|
|
; THEN A PARITY BIT AND A STOP BIT
|
|
; RETURNS AFTER ONE MACHINE CYCLE IF NOT LOW
|
|
; USES A, B,D, E
|
|
; RETURNS A=0 IF NO DATA, A= SCANCODE (OR PART THEREOF)
|
|
;__________________________________________________________________________________________________
|
|
PPK_READBITS:
|
|
IN A,(PPK_PPIB)
|
|
BIT 1,A ; TEST THE CLOCK BIT
|
|
JR Z,PPK_READBITS1 ; IF LOW THEN START THE CAPTURE
|
|
LD A,0 ; RETURNS A=0 IF NOTHING
|
|
RET
|
|
PPK_READBITS1:
|
|
CALL PPK_WAITCLOCKHIGH ; IF GETS TO HERE THEN MUST BE LOW SO WAIT TILL HIGH
|
|
LD B,8 ; SAMPLE 8 TIMES
|
|
LD E,0 ; START WITH E=0
|
|
PPK_READBITS2:
|
|
LD D,B ; STORE BECAUSE WAITCLOCKHIGH DESTROYS
|
|
CALL PPK_WAITCLOCKLOW ; WAIT TILL CLOCK GOES LOW
|
|
IN A,(PPK_PPIB) ; SAMPLE THE DATA LINE
|
|
RRA ; MOVE THE DATA BIT INTO THE CARRY REGISTER
|
|
LD A,E ; GET THE BYTE WE ARE BUILDING IN E
|
|
RRA ; MOVE THE CARRY BIT INTO BIT 7 AND SHIFT RIGHT
|
|
LD E,A ; STORE IT BACK AFTER 8 CYCLES 1ST BIT READ WILL BE IN B0
|
|
CALL PPK_WAITCLOCKHIGH ; WAIT TILL GOES HIGH
|
|
LD B,D ; RESTORE FOR LOOP
|
|
DJNZ PPK_READBITS2 ; DO THIS 8 TIMES
|
|
CALL PPK_WAITCLOCKLOW ; GET THE PARITY BIT
|
|
CALL PPK_WAITCLOCKHIGH
|
|
CALL PPK_WAITCLOCKLOW ; GET THE STOP BIT
|
|
CALL PPK_WAITCLOCKHIGH
|
|
LD A,E ; RETURNS WITH ANSWER IN A
|
|
RET
|
|
|
|
PPK_KEYMAP:
|
|
; THE TI CHARACTER CODES, OFFSET FROM LABEL BY KEYBOARD SCAN CODE
|
|
.DB $00, $00, $00, $00, $00, $00, $00, $00
|
|
.DB $00, $00, $00, $00, $00, $09, "`", $00 ; $09=TAB
|
|
.DB $00, $00, $00, $00, $00, "q", "1", $00
|
|
.DB $00, $00, "z", "s", "a", "w", "2", $00
|
|
.DB $00, "c", "x", "d", "e", "4", "3", $00
|
|
.DB $00, " ", "v", "f", "t", "r", "5", $00
|
|
.DB $00, "n", "b", "h", "g", "y", "6", $00
|
|
.DB $00, $00, "m", "j", "u", "7", "8", $00
|
|
.DB $00, ",", "k", "i", "o", "0", "9", $00
|
|
.DB $00, ".", "/", "l", ";", "p", "-", $00
|
|
.DB $00, $00, $27, $00, "[", "=", $00, $00 ; $27=APOSTROPHE
|
|
.DB $00, $00, $00, "]", $00, $5C, $00, $00 ; $5C=BACKSLASH
|
|
.DB $00, $00, $00, $00, $00, $00, $00, $00
|
|
.DB $00, "1", $00, "4", "7", $00, $00, $00
|
|
.DB "0", ".", "2", "5", "6", "8", $00, $00
|
|
.DB $00, "+", "3", "-", "*", "9", $00, $00
|
|
|
|
PPK_SHIFTKEYMAP:
|
|
.DB $00, $00, $00, $00, $00, $00, $00, $00
|
|
.DB $00, $00, $00, $00, $00, $09, "~", $00 ; $09=TAB
|
|
.DB $00, $00, $00, $00, $00, "Q", "!", $00
|
|
.DB $00, $00, "Z", "S", "A", "W", "@", $00
|
|
.DB $00, "C", "X", "D", "E", "$", "#", $00
|
|
.DB $00, " ", "V", "F", "T", "R", "%", $00
|
|
.DB $00, "N", "B", "H", "G", "Y", "^", $00
|
|
.DB $00, $00, "M", "J", "U", "&", "*", $00
|
|
.DB $00, "<", "K", "I", "O", ")", "(", $00
|
|
.DB $00, ">", "?", "L", ":", "P", "_", $00
|
|
.DB $00, $00, $22, $00, "{", "+", $00, $00 ; $22=DBLQUOTE
|
|
.DB $00, $00, $00, "}", $00, "|", $00, $00
|
|
.DB $00, $00, $00, $00, $00, $00, $00, $00
|
|
.DB $00, "1", $00, "4", "7", $00, $00, $00
|
|
.DB "0", ".", "2", "5", "6", "8", $00, $00
|
|
.DB $00, "+", "3", "-", "*", "9", $00, $00
|
|
;
|
|
;==================================================================================================
|
|
; PARALLEL PORT KEYBOARD DRIVER - DATA
|
|
;==================================================================================================
|
|
;
|
|
CAPSLOCK .DB 0 ; CAPS LOCK TOGGLED FLAG, $00=NO, $FF=YES
|
|
CTRL .DB 0 ; CTRL KEY PRESSED FLAG, $00=NO, $FF=YES
|
|
NUMLOCK .DB 0 ; NUM LOCK TOGGLED FLAG, $00=NO, $FF=YES
|
|
SKIPCOUNT .DB 0 ; SKIP COUNTER (SEE CODE COMMENTS)
|
|
PPK_QUEUE .FILL 16,0 ; 16 BYTE KB QUEUE
|
|
PPK_QLEN .DB 0 ; COUNT OF BYTES CURRENTLY IN QUEUE
|
|
|