diff --git a/branches/dgg/Source/ppk.asm b/branches/dgg/Source/ppk.asm index d7e97ecd..10ebc95b 100644 --- a/branches/dgg/Source/ppk.asm +++ b/branches/dgg/Source/ppk.asm @@ -12,7 +12,7 @@ ;__________________________________________________________________________________________________ ; #IF (PLATFORM == PLT_N8) -PPK_PPI .EQU PPI2 ; PPI PORT BASE FOR N8 +PPK_PPI .EQU 084H ; PPI PORT BASE FOR N8 #ELSE PPK_PPI .EQU 0F4H ; PPI PORT BASE FOR VDU #ENDIF @@ -21,31 +21,51 @@ 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 + +PPK_DAT .EQU 01111000B ; PPIX MASK TO MANAGE DATA LINE (C:4) +PPK_CLK .EQU 01111010B ; PPIX MASK TO MANAGE CLOCK LINE (C:5) + +PPK_WAITTO .EQU 50 * CPUFREQ ; TUNE!!! WANT SMALL AS POSSIBLE W/O ERRORS +PPK_WAITRDY .EQU 10 * CPUFREQ ; TUNE!!! 100US LOOP DELAY TO ENSURE DEVICE READY ; ;__________________________________________________________________________________________________ ; KEYBOARD INITIALIZATION ;__________________________________________________________________________________________________ ; PPK_INIT: - CALL PPK_SETPORTC ; SETS PORT C SO CAN INPUT AND OUTPUT + CALL PPK_INITPORT ; 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 + XOR A ; SIGNAL SUCCESS RET ; ;__________________________________________________________________________________________________ ; KEYBOARD STATUS ;__________________________________________________________________________________________________ ; +; CHECKING THE KEYBOARD REQUIRES "WAITING" FOR A KEY TO BE SENT AND USING A TIMEOUT +; TO DETECT THAT NO KEY IS READY. MANY APPS CALL STATUS REPEATEDLY. IN ORDER TO AVOID +; SLOWING THEM DOWN, WE IGNORE 1/256 OF THE CALLS. +; 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 + LD A,(PPK_STATUS) ; GET STATUS + AND PPK_KEYRDY ; ISOLATE READ BIT + JR NZ,PPK_STAT3 ; KEY READY, DONE + +PPK_STAT1: + LD A,(PPK_IDLE) ; GET IDLE COUNT + DEC A ; DECREMENT IT + LD (PPK_IDLE),A ; SAVE IT + JR Z,PPK_STAT2 ; ZERO? OK, DO A REAL KEY CHECK + XOR A ; RETURN KEY NOT READY + RET + +PPK_STAT2: + CALL Z,PPK_DECODE ; NOT READY, RUN THE DECODING ENGINE + LD A,(PPK_STATUS) ; GET STATUS + AND PPK_KEYRDY ; ISOLATE READ BIT + +PPK_STAT3: + RLCA ; ROTATE READY BIT TO LOW ORDER BIT RET ; ;__________________________________________________________________________________________________ @@ -53,11 +73,20 @@ PPK_STAT: ;__________________________________________________________________________________________________ ; 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 +; CALL PPK_STAT ; CHECK TO SEE IF KEY READY + LD A,(PPK_STATUS) ; GET STATUS + AND PPK_KEYRDY ; ISOLIATE KEY READY BIT + JR NZ,PPK_READ1 ; READY, GO GET THE KEY AND RETURN + CALL PPK_DECODE ; TRY TO GET A KEY + JR PPK_READ ; AND LOOP +; +PPK_READ1: + LD A,(PPK_KEYCODE) ; GET KEYCODE + LD E,A ; SAVE IT IN E + LD A,(PPK_STATE) ; GET STATE FLAGS + LD D,A ; SAVE THEM IN D XOR A ; SIGNAL SUCCESS + LD (PPK_STATUS),A ; CLEAR STATE TO INDICATE BYTE RECEIVED RET ; ;__________________________________________________________________________________________________ @@ -65,566 +94,562 @@ PPK_READ: ;__________________________________________________________________________________________________ ; PPK_FLUSH: - LD A,0 ; EMPTY KB QUEUE - LD (PPK_QLEN),A ; SAVE IT - XOR A ; SIGNAL SUCCESS + XOR A ; A = 0 + LD (PPK_STATE),A ; CLEAR STATE + RET +; +;__________________________________________________________________________________________________ +; HARDWARE INTERFACE +;__________________________________________________________________________________________________ +; +;__________________________________________________________________________________________________ +PPK_GETBYTE: +; +; GET RAW BYTE FROM KEYBOARD INTERFACE INTO A +; IF TIMEOUT, RETURN WITH A=0 AND Z SET +; +; ALL REGISTERS ARE DESTROYED +; + CALL PPK_CLKHI ; ALLOW KEYBOARD TO XMIT + CALL PPK_WTCLKLO ; WAIT FOR CLOCK LINE TO GO LOW + JP NZ,PPK_GETBYTE1 ; IF IT WENT LOW, READ THE BYTE + CALL PPK_CLKLO ; SUPPRESS KEYBOARD XMIT + XOR A ; SIGNAL TIMEOUT RET + +PPK_GETBYTE1: + CALL PPK_WTCLKHI ; WAIT FOR END OF START BIT + LD B,8 ; SAMPLE 8 TIMES + LD E,0 ; START WITH E=0 -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +PPK_GETBYTE2: + CALL PPK_WTCLKLO ; 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_WTCLKHI ; WAIT TILL GOES HIGH + DJNZ PPK_GETBYTE2 ; DO THIS 8 TIMES + CALL PPK_WTCLKLO ; GET THE PARITY BIT + CALL PPK_WTCLKHI + CALL PPK_WTCLKLO ; GET THE STOP BIT + CALL PPK_WTCLKHI + CALL PPK_CLKLO ; SUPPRESS KEYBOARD XMIT + LD A,E ; RETURN WITH RAW SCANCODE BYTE IN A + +; ; *DEBUG* +; CALL PC_SPACE +; CALL PC_LT +; CALL PRTHEXBYTE -;__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_PUTBYTE: +; +; PUT A RAW BYTE FROM A TO THE KEYBOARD INTERFACE +; +; ALL REGISTERS ARE DESTROYED +; + LD E,A ; STASH INCOMING BYTE VALUE IN E + +; ; *DEBUG* +; CALL PC_SPACE +; CALL PC_GT +; CALL PRTHEXBYTE + + ; START WITH DATA HI AND CLOCK LOW + CALL PPK_DATHI + CALL PPK_CLKLO ; NEED CLOCK LOW TO GET DEVICE ATTENTION + + ; WAIT 100US TO MAKE SURE DEVICE IS READY TO RECEIVE + LD B,PPK_WAITRDY ; WAIT 100US + DJNZ $ ; SPIN -;__PPK_SETPORTC_____________________________________________________________________________________ + ; SEND START BIT + CALL PPK_DATLO ; SET DATA LOW - REQUEST TO SEND/START BIT + CALL PPK_CLKHI ; RELEASE THE CLOCK LINE + CALL PPK_WTCLKLO ; DEVICE HAS RECEIVED THE START BIT + + ; SEND DATA BITS + LD B,8 ; 8 DATA BITS +PPK_PUTBYTE1: + RRC E ; ROTATE LOW BIT OF E TO CARRY (NEXT BIT TO SEND) + LD A,PPK_DAT >> 1 ; INIT A WITH DATA MASK SHIFTED RIGHT BY ONE BIT + RLA ; SHIFT CARRY INTO LOW BIT OF A + OUT (PPK_PPIX),A ; SET/RESET DATA LINE FOR NEXT BIT VALUE + CALL PPK_WTCLKHI ; WAIT FOR CLOCK TO TRANSTION HI + CALL PPK_WTCLKLO ; THEN LO, BIT HAS NOW BEEN RECEIVED BY DEVICE + DJNZ PPK_PUTBYTE1 ; LOOP TO SEND 8 DATA BITS + + ; SEND PARITY BIT + XOR A ; CLEAR A + OR E ; OR WITH SENT VALUE, SETS PARITY FLAG! + LD A,PPK_DAT ; PREPARE A WITH DATA MASK + JP PO,PPK_PUTBYTE2 ; PARITY IS ALREADY ODD, LEAVE A ALONE + INC A ; SET PARITY BIT BY INCREMENTING A +PPK_PUTBYTE2: + OUT (PPK_PPIX),A ; SET THE DATA LINE + CALL PPK_WTCLKHI ; WAIT FOR CLOCK TO TRANSITION HI + CALL PPK_WTCLKLO ; THEN LO, BIT HAS NOW BEEN RECEIVED BY DEVICE + + ; SEND STOP BIT, NO NEED TO WATCH CLOCK, JUST WAIT FOR START OF DEVICE ACK + CALL PPK_DATHI ; STOP BIT IS 1 (HI) + + ; HANDLE DEVICE ACK + CALL PPK_WTDATLO ; WAIT FOR DEVICE TO START ACK + CALL PPK_WTCLKLO ; WAIT FOR CLOCK TO TRANSITION LO + CALL PPK_WTCLKHI ; THEN HI + CALL PPK_WTDATHI ; FINALLY WAIT FOR DEVICE TO RELEASE DATA LINE + + ; ASSERT CLOCK TO INHIBIT DEVICE FROM SENDING US ANYTHING UNTIL WE ARE READY + CALL PPK_CLKLO ; SET CLOCK LOW + + RET +; +;__________________________________________________________________________________________________ +PPK_INITPORT: ; -; SETUP PORT C OF 8255 FOR KEYBOARD -;__________________________________________________________________________________________________ -PPK_SETPORTC: +; INITIALIZE PPI +; 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 + OUT (PPK_PPIX),A ; SET PPI CONTROL PORT + XOR A ; A=0 + OUT (PPK_PPIA),A ; PPI PORT A TO ZERO (REQUIRED FOR PAR PRINTER) + CALL PPK_DATHI ; KBD DATA LINE HI (IDLE) + CALL PPK_CLKHI ; KBD CLOCK LINE HI (IDLE) 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 +; +;__________________________________________________________________________________________________ +; +; BIT TESTING (PORT B) +; +; B:0 = KBD DATA LINE (INPUT) +; B:1 = KBD CLOCK LINE (INPUT) +; +; TEST PPI PORT B BIT(S) DESIGNATED BY BITMASK IN D AFTER XOR WITH E +; WAIT FOR ANY OF THE DESIGNATED BITS TO BE SET, THEN RETURN +; IF TIMEOUT, RETURN WITH A=0 AND Z SET +; HL IS DESTROYED, A IS OVERWRITTEN WITH RETURN VALUE +; +PPK_WTCLKLO: ; WAIT FOR CLOCK LINE TO BE LOW + PUSH DE + LD DE,0202H ; TEST BIT 1 AFTER INVERTING + JR PPK_WAIT +; +PPK_WTCLKHI: ; WAIT FOR CLOCK LINE TO BE HIGH + PUSH DE + LD DE,0200H ; TEST BIT 1 + JR PPK_WAIT +; +PPK_WTDATLO: ; WAIT FOR DATA LINE TO BE LOW + PUSH DE + LD DE,0101H ; TEST BIT 0 AFTER INVERTING + JR PPK_WAIT +; +PPK_WTDATHI: ; WAIT FOR DATA LINE TO BE HIGH + PUSH DE + LD DE,0100H ; TEST BIT 0 + JR PPK_WAIT +; +PPK_WAIT: ; COMPLETE THE WAIT PROCESSING + LD HL,PPK_WAITTO +PPK_WAIT1: + IN A,(PPK_PPIB) ; GET BYTE FROM PORT B + XOR E + AND D + JR NZ,PPK_WAIT2 ; EXIT IF ANY BIT IS SET + DEC HL + LD A,H + OR L + JR NZ,PPK_WAIT1 +PPK_WAIT2: + POP DE 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 +; +;__________________________________________________________________________________________________ +; +; BIT MANAGEMENT (PORT C) +; +; C:4 = KBD DATA LINE (LATCHED OUTPUT) +; C:5 = KBD CLOCK LINE (LATCHED OUTPUT) +; +; A IS DESTROYED (OVERWRITTEN WITH PORT OUTPUT VALUE) +; +PPK_DATHI: + LD A,PPK_DAT + 1 + JR PPK_SETBIT +PPK_DATLO: + LD A,PPK_DAT + JR PPK_SETBIT +PPK_CLKHI: + LD A,PPK_CLK + 1 + JR PPK_SETBIT +PPK_CLKLO: + LD A,PPK_CLK + JR PPK_SETBIT +PPK_SETBIT: + OUT (PPK_PPIX),A RET +; +;__________________________________________________________________________________________________ +; RESET KEYBOARD +;__________________________________________________________________________________________________ +; +PPK_RESET: + LD A,$FF ; RESET COMMAND + CALL PPK_PUTBYTE ; SEND IT + CALL PPK_GETBYTE ; GET THE ACK + LD B,0 ; SETUP LOOP COUNTER +PPK_RESET0: + PUSH BC ; PRESERVE LOOP COUNTER + CALL DELAY ; DELAY 25MS + CALL PPK_GETBYTE ; TRY TO GET $AA + POP BC ; RESTORE LOOP COUNTER + JR NZ,PPK_RESET1 ; GOT A BYTE? IF SO, DONE (WE IGNORE RESPONSE CODE VALUE) + DJNZ PPK_RESET0 ; KEEP TRYING UNTIL COUNTER EXPIRES +PPK_RESET1: + XOR A ; SIGNAL SUCCESS + RET ; DONE +; +;__________________________________________________________________________________________________ +; DECODING ENGINE +;__________________________________________________________________________________________________ +; +; STATUS BITS (FOR PPK_STATUS) +; +PPK_EXT .EQU 01H ; BIT 0, EXTENDED SCANCODE ACTIVE +PPK_BREAK .EQU 02H ; BIT 1, THIS IS A KEY UP (BREAK) EVENT +PPK_KEYRDY .EQU 80H ; BIT 7, INDICATES A DECODED KEYCODE IS READY +; +; STATE BITS (FOR PPK_STATE, PPK_LSTATE, PPK_RSTATE) +; +PPK_SHIFT .EQU 01H ; BIT 0, SHIFT ACTIVE (PRESSED) +PPK_CTRL .EQU 02H ; BIT 1, CONTROL ACTIVE (PRESSED) +PPK_ALT .EQU 04H ; BIT 2, ALT ACTIVE (PRESSED) +PPK_WIN .EQU 08H ; BIT 3, WIN ACTIVE (PRESSED) +PPK_SCRLCK .EQU 10H ; BIT 4, CAPS LOCK ACTIVE (TOGGLED ON) +PPK_NUMLCK .EQU 20H ; BIT 5, NUM LOCK ACTIVE (TOGGLED ON) +PPK_CAPSLCK .EQU 40H ; BIT 6, SCROLL LOCK ACTIVE (TOGGLED ON) +PPK_NUMPAD .EQU 80H ; BIT 7, NUM PAD KEY (KEY PRESSED IS ON NUM PAD) +; +PPK_SCANCODE .DB 0 ; RAW SCANCODE +PPK_KEYCODE .DB 0 ; RESULTANT KEYCODE AFTER DECODING +PPK_STATE .DB 0 ; STATE BITS (SEE ABOVE) +PPK_LSTATE .DB 0 ; STATE BITS FOR "LEFT" KEYS +PPK_RSTATE .DB 0 ; STATE BITS FOR "RIGHT" KEYS +PPK_STATUS .DB 0 ; CURRENT STATUS BITS (SEE ABOVE) +PPK_IDLE .DB 0 ; IDLE COUNT +; +;__________________________________________________________________________________________________ +PPK_DECODE: +; +; RUN THE DECODING ENGINE UNTIL EITHER: 1) A TIMEOUT OCCURS TRYING TO GET SCANCODES +; FROM THE KEYBOARD, OR 2) A DECODED KEY VALUE IS AVAILABLE +; +; RETURNS A=0 AND Z SET IF TIMEOUT, OTHERWISE A DECODED KEY VALUE IS AVAILABLE. +; THE DECODED KEY VALUE AND KEY STATE IS STORED IN PPK_KEYCODE AND PPK_STATE. +; +; PPK_KEYCODE AND PPK_STATUS ARE CLEARED AT START. IF IS THE CALLER'S RESPONSIBILITY +; TO RETRIEVE ANY PRIOR VALUE BEFORE CALLING THIS FUNCTION AGAIN. +; + XOR A ; A = ZERO + LD (PPK_STATUS),A ; CLEAR STATUS + DEC A ; A = $FF + LD (PPK_KEYCODE),A ; CLEAR KEYCODE -;__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_DECODENEXT: ; PROCESS NEXT SCANCODE + CALL PPK_GETBYTE ; GET A SCANCODE + RET Z ; TIMEOUT, RETURN WITH A=0, Z SET + LD (PPK_SCANCODE),A ; SAVE SCANCODE -;__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_DECODE1: ; HANDLE BREAK (KEYUP) F0 PREFIX + CP $F0 ; BREAK (KEY UP) PREFIX? + JR NZ,PPK_DECODE2 ; NOPE MOVE ON + LD A,(PPK_STATUS) ; GET STATUS + OR PPK_BREAK ; SET BREAK BIT + LD (PPK_STATUS),A ; SAVE STATUS + JR PPK_DECODENEXT ; LOOP TO DO NEXT SCANCODE + +PPK_DECODE2: ; HANDLE EXTENDED KEY E0 PREFIX + CP $E0 ; EXTENDED KEY PREFIX? + JR NZ,PPK_DECODE3 ; NOPE MOVE ON + LD A,(PPK_STATUS) ; GET STATUS + OR PPK_EXT ; SET EXTENDED BIT + LD (PPK_STATUS),A ; SAVE STATUS + JR PPK_DECODENEXT ; LOOP TO DO NEXT SCANCODE + +PPK_DECODE3: ; HANDLE SPECIAL EXTENDED KEY E1 PREFIX + ; TODO: HANDLE PAUSE KEY HERE... + +PPK_DECODE4: ; PERFORM EXTENDED MAPPING + LD A,(PPK_STATUS) ; GET STATUS + AND PPK_EXT ; EXTENDED BIT SET? + JR Z,PPK_DECODE5 ; NOPE, MOVE ON + LD A,(PPK_SCANCODE) ; GET SCANCODE + LD E,A ; STASH IT IN E + LD HL,PPK_MAPEXT ; POINT TO START OF EXT MAP TABLE +PPK_DECODE4A: + LD A,(HL) ; GET FIRST BYTE OF PAIR + CP $00 ; END OF TABLE? + JP Z,PPK_DECODE ; UNKNOWN OR BOGUS, START OVER + INC HL ; INC HL FOR FUTURE + CP E ; DOES MATCH BYTE EQUAL SCANCODE? + JR Z,PPK_DECODE4B ; YES! JUMP OUT + INC HL ; BUMP TO START OF NEXT PAIR + JR PPK_DECODE4A ; LOOP TO CHECK NEXT TABLE ENTRY +PPK_DECODE4B: + LD A,(HL) ; GET THE KEYCODE VIA MAPPING TABLE + LD (PPK_KEYCODE),A ; SAVE IT + JR PPK_DECODE6 + +PPK_DECODE5: ; PERFORM SHIFTED/UNSHIFTED MAPPING + LD A,(PPK_SCANCODE) ; GET THE SCANCODE + CP $85 ; PAST END OF TABLE? + JR NC,PPK_DECODE6 ; YES, SKIP OVER LOOKUP + + LD A,(PPK_STATE) ; GET STATE + AND PPK_SHIFT ; SHIFT ACTIVE? + LD HL,PPK_MAPSTD ; LOAD ADDRESS OF NON-SHIFTED MAPPING TABLE + JR Z,PPK_DECODE5A ; NON-SHIFTED, MOVE ON + LD HL,PPK_MAPSHIFT ; LOAD ADDRESS OF SHIFTED MAPPING TABLE +PPK_DECODE5A: + LD A,(PPK_SCANCODE) ; GET THE SCANCODE + LD E,A ; SCANCODE TO E FOR TABLE OFFSET + LD D,0 ; D -> 0 + ADD HL,DE ; COMMIT THE TABLE OFFSET TO HL + LD A,(HL) ; GET THE KEYCODE VIA MAPPING TABLE + LD (PPK_KEYCODE),A ; SAVE IT + +PPK_DECODE6: ; HANDLE MODIFIER KEY MAKE/BREAK EVENTS + LD A,(PPK_KEYCODE) ; MAKE SURE WE HAVE KEYCODE + CP $B8 ; END OF MODIFIER KEYS + JR NC,PPK_DECODE13 ; BYPASS MODIFIER KEY CHECKING + CP $B0 ; START OF MODIFIER KEYS + JR C,PPK_DECODE13 ; BYPASS MODIFIER KEY CHECKING + ; TODO: STUFF BELOW COULD BE A LOOP -;__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 + ; HANDLE L/R SHIFT KEYS + LD E,PPK_SHIFT ; SETUP TO SET/CLEAR SHIFT BIT + SUB $B0 ; L-SHIFT? + JR Z,PPK_DECODE7 ; YES, HANDLE L-SHIFT MAKE/BREAK + DEC A ; R-SHIFT? + JR Z,PPK_DECODE8 ; YES, HANDLE R-SHIFT MAKE/BREAK -;__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 + ; HANDLE L/R CONTROL KEYS + LD E,PPK_CTRL ; SETUP TO SET/CLEAR CONTROL BIT + DEC A ; L-CONTROL? + JR Z,PPK_DECODE7 ; YES, HANDLE L-CONTROL MAKE/BREAK + DEC A ; R-CONTROL? + JR Z,PPK_DECODE8 ; YES, HANDLE R-CONTROL MAKE/BREAK + + ; HANDLE L/R ALT KEYS + LD E,PPK_ALT ; SETUP TO SET/CLEAR ALT BIT + DEC A ; L-ALT? + JR Z,PPK_DECODE7 ; YES, HANDLE L-ALT MAKE/BREAK + DEC A ; R-ALT? + JR Z,PPK_DECODE8 ; YES, HANDLE R-ALT MAKE/BREAK + + ; HANDLE L/R WIN KEYS + LD E,PPK_WIN ; SETUP TO SET/CLEAR WIN BIT + DEC A ; L-WIN? + JR Z,PPK_DECODE7 ; YES, HANDLE L-WIN MAKE/BREAK + DEC A ; R-WIN? + JR Z,PPK_DECODE8 ; YES, HANDLE R-WIN MAKE/BREAK + +PPK_DECODE7: ; LEFT STATE KEY MAKE/BREAK (STATE BIT TO SET/CLEAR IN E) + LD HL,PPK_LSTATE + JR PPK_DECODE9 + +PPK_DECODE8: ; RIGHT STATE KEY MAKE/BREAK (STATE BIT TO SET/CLEAR IN E) + LD HL,PPK_RSTATE + JR PPK_DECODE9 + +PPK_DECODE9: ; BRANCH BASED ON WHETHER THIS IS A MAKE OR BREAK EVENT + LD A,(PPK_STATUS) ; GET STATUS FLAGS + AND PPK_BREAK ; BREAK EVENT? + JR Z,PPK_DECODE10 ; NO, HANDLE A MODIFIER KEY MAKE EVENT + JR PPK_DECODE11 ; YES, HANDLE A MODIFIER BREAK EVENT + +PPK_DECODE10: ; HANDLE STATE KEY MAKE EVENT + LD A,E + OR (HL) + LD (HL),A + JR PPK_DECODE12 + +PPK_DECODE11: ; HANDLE STATE KEY BREAK EVENT + LD A,E + XOR $FF + AND (HL) + LD (HL),A + JR PPK_DECODE12 + +PPK_DECODE12: ; COALESCE L/R STATE FLAGS + LD A,(PPK_STATE) ; GET EXISTING STATE BITS + AND $F0 ; GET RID OF OLD MODIFIER BITS + LD DE,(PPK_LSTATE) ; LOAD BOTH L/R STATE BYTES IN D/E + OR E ; MERGE IN LEFT STATE BITS + OR D ; MERGE IN RIGHT STATE BITS + LD (PPK_STATE),A ; SAVE IT + JP PPK_DECODE ; DONE WITH CURRENT KEYSTROKE + +PPK_DECODE13: ; NO MORE BREAK KEY PROCESSING! + LD A,(PPK_STATUS) + AND PPK_BREAK + JP NZ,PPK_DECODE + +PPK_DECODE14: ; TOGGLE KEY PROCESSING + LD A,(PPK_KEYCODE) + LD E,PPK_CAPSLCK + CP $BC + JR Z,PPK_DECODE15 + LD E,PPK_NUMLCK + CP $BD + JR Z,PPK_DECODE15 + LD E,PPK_SCRLCK + CP $BE + JR Z,PPK_DECODE15 + JR PPK_DECODE16 + +PPK_DECODE15: ; RECORD THE TOGGLE + LD A,(PPK_STATE) + XOR E + LD (PPK_STATE),A + + LD A,$ED ; SET/RESET LED'S COMMAND + CALL PPK_PUTBYTE + CALL PPK_GETBYTE + CP $FA ; MAKE SURE WE GET ACK + JP NZ,PPK_DECODE ; ABORT IF NO ACK + LD A,(PPK_STATE) + RRCA + RRCA + RRCA + RRCA + AND $07 + CALL PPK_PUTBYTE ; SEND THE LED DATA + CALL PPK_GETBYTE ; READ THE ACK + + JP PPK_DECODE ; DONE WITH CURRENT KEYSTROKE -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 +PPK_DECODE16: ; CONTROL KEY PROCESSING + LD A,(PPK_STATE) + AND PPK_CTRL + JR Z,PPK_DECODE18 ; CONTROL KEY NOT PRESSED, MOVE ON + LD A,(PPK_KEYCODE) + CP 'a' + JR C,PPK_DECODE17 + CP 'z' + 1 + JR NC,PPK_DECODE17 + RES 5,A ; CLEAR BIT 5 TO MAP LOWERCASE A-Z TO UPPERCASE +PPK_DECODE17: + CP '@' + JR C,PPK_DECODE18 + CP '_' + 1 + JR NC,PPK_DECODE18 + RES 6,A + LD (PPK_KEYCODE),A ; UPDATE KEYCODE TO CONTROL VALUE + +PPK_DECODE18: ; CAPS LOCK KEY PROCESSING + LD A,(PPK_STATE) + AND PPK_CAPSLCK + JR Z,PPK_DECODE21 ; CAPS LOCK NOT ACTIVE, MOVE ON + LD A,(PPK_KEYCODE) + CP 'a' + JR C,PPK_DECODE19 + CP 'z' + 1 + JR NC,PPK_DECODE19 + JR PPK_DECODE20 +PPK_DECODE19: + CP 'A' + JR C,PPK_DECODE21 + CP 'Z' + 1 + JR NC,PPK_DECODE21 + JR PPK_DECODE20 +PPK_DECODE20: + LD A,(PPK_KEYCODE) + XOR $20 + LD (PPK_KEYCODE),A + +PPK_DECODE21: ; NUM PAD PROCESSING + LD A,(PPK_STATE) + AND ~PPK_NUMPAD + LD (PPK_STATE),A ; ASSUME NOT A NUMPAD KEY + + LD A,(PPK_KEYCODE) + AND 11100000B ; ISOLATE TOP 3 BITS + CP 11000000B ; IS NUMPAD RANGE? + JR NZ,PPK_DECODEX ; NOPE, GET OUT + + LD A,(PPK_STATE) + OR PPK_NUMPAD + LD (PPK_STATE),A ; SET NUMPAD BIT IN STATE + + AND PPK_NUMLCK + JR Z,PPK_DECODE22 ; SKIP NUMLOCK PROCESSING + LD A,(PPK_KEYCODE) + XOR $10 ; FLIP FOR NUMLOCK + LD (PPK_KEYCODE),A ; SAVE IT + +PPK_DECODE22: ; DO NUMPAD MAPPING + LD A,(PPK_KEYCODE) + LD HL,PPK_MAPNUMPAD + SUB $C0 + LD E,A + LD D,0 + ADD HL,DE + LD A,(HL) + LD (PPK_KEYCODE),A + +PPK_DECODEX: + LD A,(PPK_KEYCODE) ; GET THE FINAL KEYCODE + CP $FF ; IS IT $FF (UNKNOWN/INVALID) + JP Z,PPK_DECODE ; IF SO, JUST RESTART THE ENGINE + + LD A,(PPK_STATUS) ; GET CURRENT STATUS + OR PPK_KEYRDY ; SET KEY READY BIT + LD (PPK_STATUS),A ; SAVE IT + XOR A ; A=0 + INC A ; SIGNAL SUCCESS WITH A=1 + RET +; +;__________________________________________________________________________________________________ +; MAPPING TABLES +;__________________________________________________________________________________________________ +; +PPK_MAPSTD: ; SCANCODE IS INDEX INTO TABLE TO RESULTANT LOOKUP KEYCODE + .DB $FF,$E8,$FF,$E4,$E2,$E0,$E1,$EB,$FF,$E9,$E7,$E5,$E3,$09,'`',$FF + .DB $FF,$B4,$B0,$FF,$B2,'q','1',$FF,$FF,$FF,'z','s','a','w','2',$FF + .DB $FF,'c','x','d','e','4','3',$FF,$FF,' ','v','f','t','r','5',$FF + .DB $FF,'n','b','h','g','y','6',$FF,$FF,$FF,'m','j','u','7','8',$FF + .DB $FF,',','k','i','o','0','9',$FF,$FF,'.','/','l',';','p','-',$FF + .DB $FF,$FF,$27,$FF,'[','=',$FF,$FF,$BC,$B1,$0D,']',$FF,'\',$FF,$FF + .DB $FF,$FF,$FF,$FF,$FF,$FF,$08,$FF,$FF,$C0,$FF,$C3,$C6,$FF,$FF,$FF + .DB $C9,$CA,$C1,$C4,$C5,$C7,$1B,$BD,$FA,$CE,$C2,$CD,$CC,$C8,$BE,$FF + .DB $FF,$FF,$FF,$E6,$EC +; +PPK_MAPSHIFT: ; SCANCODE IS INDEX INTO TABLE TO RESULTANT LOOKUP KEYCODE WHEN SHIFT ACTIVE + .DB $FF,$E8,$FF,$E4,$E2,$E0,$E1,$EB,$FF,$E9,$E7,$E5,$E3,$09,'~',$FF + .DB $FF,$B4,$B0,$FF,$B2,'Q','!',$FF,$FF,$FF,'Z','S','A','W','@',$FF + .DB $FF,'C','X','D','E','$','#',$FF,$FF,' ','V','F','T','R','%',$FF + .DB $FF,'N','B','H','G','Y','^',$FF,$FF,$FF,'M','J','U','&','*',$FF + .DB $FF,'<','K','I','O',')',')',$FF,$FF,'>','?','L',':','P','_',$FF + .DB $FF,$FF,$22,$FF,'{','+',$FF,$FF,$BC,$B1,$0D,'}',$FF,'|',$FF,$FF + .DB $FF,$FF,$FF,$FF,$FF,$FF,$08,$FF,$FF,$D0,$FF,$D3,$D6,$FF,$FF,$FF + .DB $D9,$DA,$D1,$D4,$D5,$D7,$1B,$BD,$FA,$DE,$D2,$DD,$DC,$D8,$BE,$FF + .DB $FF,$FF,$FF,$E6,$EC +; +PPK_MAPEXT: ; PAIRS ARE [SCANCODE,KEYCODE] FOR EXTENDED SCANCODES + .DB $11,$B5, $14,$B3, $1F,$B6, $27,$B7 + .DB $2F,$EF, $37,$FA, $3F,$FB, $4A,$CB + .DB $5A,$CF, $5E,$FC, $69,$F3, $6B,$F8 + .DB $6C,$F2, $70,$F0, $71,$F1, $72,$F7 + .DB $74,$F9, $75,$F6, $7A,$F5, $7C,$ED + .DB $7D,$F4, $7E,$FD, $00,$00 +; +PPK_MAPNUMPAD: ; KEYCODE TRANSLATION FROM NUMPAD RANGE TO STD ASCII/KEYCODES + .DB $F3,$F7,$F5,$F8,$FF,$F9,$F2,$F6,$F4,$F0,$F1,$2F,$2A,$2D,$2B,$0D + .DB $31,$32,$33,$34,$35,$36,$37,$38,$39,$30,$2E,$2F,$2A,$2D,$2B,$0D diff --git a/branches/dgg/Source/util.asm b/branches/dgg/Source/util.asm index a5dee9cc..d156ded7 100644 --- a/branches/dgg/Source/util.asm +++ b/branches/dgg/Source/util.asm @@ -43,6 +43,16 @@ PC_RBKT: LD A,']' JR PC_PRTCHR +PC_LT: + PUSH AF + LD A,'<' + JR PC_PRTCHR + +PC_GT: + PUSH AF + LD A,'>' + JR PC_PRTCHR + PC_LPAREN: PUSH AF LD A,'(' diff --git a/branches/dgg/Source/vdu.asm b/branches/dgg/Source/vdu.asm index 82f8fe8d..1db1a068 100644 --- a/branches/dgg/Source/vdu.asm +++ b/branches/dgg/Source/vdu.asm @@ -11,17 +11,10 @@ ; DATA CONSTANTS ;__________________________________________________________________________________________________ ; -READR .EQU 0F0h ; READ VDU -WRITR .EQU 0F1h ; WRITE VDU -SY6545S .EQU 0F2h ; VDU STATUS/REGISTER -SY6545D .EQU 0F3h ; - -STATE_NORMAL .EQU 00H ; NORMAL TERMINAL OPS -STATE_ESC .EQU 01H ; ESC MODE -STATE_DIR_L .EQU 02H ; ESC-Y X * -STATE_DIR_C .EQU 03H ; ESC-Y * X - -ESC_KEY .EQU 1BH ; ESCAPE CODE +VDU_RD .EQU 0F0h ; READ VDU +VDU_WR .EQU 0F1h ; WRITE VDU +VDU_STREG .EQU 0F2h ; VDU STATUS/REGISTER +VDU_DATA .EQU 0F3h ; VDU DATA REGISTER ; ;__________________________________________________________________________________________________ ; BOARD INITIALIZATION @@ -34,7 +27,7 @@ VDU_INIT: RET ; ;__________________________________________________________________________________________________ -; FUNCTION JUMP TABLE +; CHARACTER I/O (CIO) FUNCTION JUMP TABLE ;__________________________________________________________________________________________________ ; VDU_DISPCIO: @@ -64,10 +57,9 @@ VDU_CIOOST: RET ; ;__________________________________________________________________________________________________ -; NEW FUNCTION JUMP TABLE +; VIDEO DISPLAY ADAPTER (VDA) FUNCTION JUMP TABLE ;__________________________________________________________________________________________________ ; - VDU_DISPVDA: LD A,B ; GET REQUESTED FUNCTION AND $0F ; ISOLATE SUB-FUNCTION @@ -115,10 +107,10 @@ VDU_VDASCS: VDU_VDASCP: LD A,E - LD (TERM_X),A + LD (VDU_X),A LD A,D - LD (TERM_Y),A - CALL GOTO_XY + LD (VDU_Y),A + CALL VDU_XY XOR A RET @@ -133,10 +125,10 @@ VDU_VDASCO: VDU_VDAWRC: ; PUSH CHARACTER OUT AT CURRENT POSITION LD A,31 ; PREP VDU FOR DATA R/W - OUT (SY6545S),A + OUT (VDU_STREG),A CALL VDU_WAITRDY ; WAIT FOR VDU TO BE READY LD A,E - OUT (WRITR),A ; OUTPUT CHAR TO VDU + OUT (VDU_WR),A ; OUTPUT CHAR TO VDU ; UPDATE CURSOR POSITION TO FOLLOW CHARACTERS LD HL,(VDU_DISPLAYPOS) ; GET CURRENT DISPLAY POSITION @@ -153,18 +145,18 @@ VDU_VDAWRC: VDU_VDAFIL: LD A, 31 ; PREP VDU FOR DATA R/W - OUT (SY6545S),A + OUT (VDU_STREG),A VDU_VDAFIL1: LD A,H ; CHECK NUMBER OF FILL CHARS LEFT OR L JR Z,VDU_VDAFIL2 ; ALL DONE, GO TO COMPLETION CALL VDU_WAITRDY ; WAIT FOR VDU TO BE READY LD A,E - OUT (WRITR), A ; OUTPUT CHAR TO VDU + OUT (VDU_WR), A ; OUTPUT CHAR TO VDU DEC HL ; DECREMENT COUNT JR VDU_VDAFIL1 ; LOOP AS NEEDED VDU_VDAFIL2: - CALL GOTO_XY ; YES, MOVE CURSOR BACK TO ORIGINAL POSITION + CALL VDU_XY ; YES, MOVE CURSOR BACK TO ORIGINAL POSITION XOR A ; RESULT = 0 RET @@ -180,10 +172,11 @@ VDU_VDASCR: JR VDU_VDASCR ; VDU_WAITRDY: - IN A,(SY6545S) ; READ STATUS + IN A,(VDU_STREG) ; READ STATUS OR A ; SET FLAGS RET M ; IF BIT 7 SET, THEN READY! JR VDU_WAITRDY ; KEEP CHECKING +; ;__________________________________________________________________________________________________ ; IMBED COMMON PARALLEL PORT KEYBOARD DRIVER ;__________________________________________________________________________________________________ @@ -194,356 +187,31 @@ VDU_WAITRDY: ; INITIALIZATION ;__________________________________________________________________________________________________ INITVDU: - CALL VDUINIT ; INIT VDU -; CALL KB_INITIALIZE ; INIT KB -; CALL PR_INITIALIZE ; INIT PR - -; CALL DSPMATRIX ; DISPLAY INIT MATRIX SCREEN -; CALL WAIT_KBHIT ; WAIT FOR A KEYSTROKE -; LD A,0 ; EMPTY KB QUEUE -; LD (KB_QUEUE_PTR),A ; - + CALL VDUINIT ; INIT VDU CALL PERF_ERASE_EOS ; CLEAR SCREEN CALL PERF_CURSOR_HOME ; CURSOR HOME RET -; -;__CHARIN__________________________________________________________________________________________ -; -; PROCESS INCOMMING CHARACTER AND DISPLAY ON SCREEN OR PERFORM FUNCTION -; C: INCOMMING CHARACTER -;__________________________________________________________________________________________________ -CHARIN: - LD A,C - PUSH AF ; STORE AF - LD A,(TERMSTATE) ; MOVE CURRENT STATE INTO A - CP STATE_NORMAL ; NORMAL PROCESSING STATE? - JP Z,CHARIN_NORM ; - CP STATE_ESC ; ESCAPE PROCESSING STATE? - JP Z,CHARIN_ESCSTATE ; - CP STATE_DIR_L ; WAITING FOR Y COORD STATE? - JP Z,CHARIN_DIR_L_STATE ; - CP STATE_DIR_C ; WAITING FOR X COORD STATE? - JP Z,CHARIN_DIR_C_STATE ; - LD A,STATE_NORMAL ; UNKNOWN STATE, RESET STATE - LD (TERMSTATE),A ; - POP AF ; - RET ; - -;__CHARIN_DIR_L_STATE______________________________________________________________________________ -; -; PROCESS "WAITING FOR Y COORD STATE" -;__________________________________________________________________________________________________ -CHARIN_DIR_L_STATE: - LD A,32 ; MOVE 32 (' ') INTO A - LD C,A ; PARK INTO C - POP AF ; GET CHAR FROM STACK - SUB C ; DECODE CHAR INTO USABLE Y COORD - CP 24 ; IS OFF SCREEN? - JP M,CHARIN_DIR_L_STATE_CONT - LD A,23 ; YES, PLACE CRSR ON LAST ROW -CHARIN_DIR_L_STATE_CONT: - LD (TERM_Y),A ; NO, USE DECODED VALUE - LD A,STATE_DIR_C ; SET UP STATE TO GET X COORD - LD (TERMSTATE),A ; - RET - -;__CHARIN_DIR_C_STATE______________________________________________________________________________ -; -; PROCESS "WAITING FOR X COORD STATE" -;__________________________________________________________________________________________________ -CHARIN_DIR_C_STATE: - LD A,32 ; MOVE 32 (' ') INTO A - LD C,A ; PARK INTO C - POP AF ; GET CHAR FROM STACK - SUB C ; DECODE CHAR INTO USABLE X COORD - CP 80 ; IS OFF SCREEN? - JP M,CHARIN_DIR_C_STATE_CONT - LD A,79 ; YES, PLACE CRSR IN LAST COLUMN -CHARIN_DIR_C_STATE_CONT: - LD (TERM_X),A ; NO, USE DECODED VALUE - CALL GOTO_XY ; SET CURSOR POS - LD A,STATE_NORMAL ; RESET STATE TO NORMAL - LD (TERMSTATE),A ; - RET - - -;__CHARIN_NORM_____________________________________________________________________________________ -; -; PROCESS NORMAL STATE -;__________________________________________________________________________________________________ -CHARIN_NORM: - POP AF ; GET CHAR FROM STACK - CP 0AH ; IS LINEFEED? - JP Z,CHARIN_LF ; - CP 09H ; IS TAB? - JP Z,CHARIN_TAB ; - CP 08H ; IS BS? - JP Z,CHARIN_BS ; - CP 0DH ; IS CR? - JP Z,CHARIN_CR ; - CP 07H ; IS BELL? - JP Z,CHARIN_BELL ; - CP 13H ; IS XOFF? - JP Z,CHARIN_XOFF ; - CP 11H ; IS XON? - JP Z,CHARIN_XON ; - CP ESC_KEY ; IS ESC? - JP Z,CHARIN_ESC ; - JP VDU_PUTCHAR ; NORMAL OUTPUT CHAR - -;__CHARIN_ESC______________________________________________________________________________________ -; -; PROCESS "ESC" STATE -;__________________________________________________________________________________________________ -CHARIN_ESC: - LD A,STATE_ESC ; ESC PRESSED, STATE TO ESCPRESSED - LD (TERMSTATE),A ; - RET - -;__CHARIN_LF_______________________________________________________________________________________ -; -; PROCESS LINE FEED -;__________________________________________________________________________________________________ -CHARIN_LF: - LD A,(TERM_Y) ; MOVE CRSR Y COORD INTO A - INC A ; INC A - LD (TERM_Y),A ; STORE NEW Y COORD - JP GOTO_XY ; SET CRSR POSITION - - -;__CHARIN_TAB______________________________________________________________________________________ -; -; PROCESS TABS -;__________________________________________________________________________________________________ -CHARIN_TAB: - LD HL,TABSTOPS ; SET HL TO TAB STOP TABLE - LD A,(TERM_X) ; MOVE CURENT CRSR X COORD INTO A - INC A ; INC A - LD C,A ; STORE CRSR X COORD INTO A -CHARIN_TAB_LOOP: - LD A,(HL) ; GET NEXT TAB STOP - OR A ; IS ZERO? - JP Z,CHARIN_TAB_EXIT ; END OF TABLE, PROCESS 73+ - INC HL ; SET POINTER TO NEXT TABLE ENTRY - CP C ; IS CURRENT ENTRY > X COORD? - JP M,CHARIN_TAB_LOOP ; NO, LOOP - LD (TERM_X),A ; YES, USE IT - JP GOTO_XY ; SET CRSR POSITION -CHARIN_TAB_EXIT: - LD A,(TERM_X) ; COLUMN IS PAST LAST TAB STOP, SET A TO CRSR POS - CP 79 ; IS LAST PHYSICAL POS? - RET Z ; YES, DO NOTHING - INC A ; NO, INC CRSR BY ONE - LD (TERM_X),A ; STORE NEW X COORD - JP GOTO_XY ; SET CRSR POSITION - -TABSTOPS: - .DB 09,17,25,33,41,49,57,65,73,00 - - -;__CHARIN_BS_______________________________________________________________________________________ -; -; PROCESS BACKSPACE -;__________________________________________________________________________________________________ -CHARIN_BS: - JP PERF_CURSOR_LEFT ; PERFORM CRSR LEFT FUNCTION - - -;__CHARIN_CR_______________________________________________________________________________________ -; -; PROCESS CARRAGE RETURN -;__________________________________________________________________________________________________ -CHARIN_CR: - LD A,00H ; MOVE 0 TO X COORD - LD (TERM_X),A ; - JP GOTO_XY ; GOTO XY COORDS - - -;__CHARIN_BELL_____________________________________________________________________________________ -; -; PROCESS BELL -;__________________________________________________________________________________________________ -CHARIN_BELL: - ; - ; NO HARDWARE FOR THIS, DO NOTHING - ; - RET - - -;__CHARIN_XOFF_____________________________________________________________________________________ -; -; PROCESS XOFF -;__________________________________________________________________________________________________ -CHARIN_XOFF: - ; - ; SHOULD NOT BE NECESSARY FOR LOCAL IMPLIMENTATION - ; - RET - - -;__CHARIN_XON______________________________________________________________________________________ -; -; PROCESS XON -;__________________________________________________________________________________________________ -CHARIN_XON: - ; - ; SHOULD NOT BE NECESSARY FOR LOCAL IMPLIMENTATION - ; - RET - - -;__CHARIN_ESCSTATE_________________________________________________________________________________ -; -; PROCESS ESC STATE -;__________________________________________________________________________________________________ -CHARIN_ESCSTATE: - POP AF ; - CP 'A' ; IS CURSOR UP? - JP Z, PERF_CURSOR_UP ; - CP 'B' ; IS CURSOR DOWN? - JP Z, PERF_CURSOR_DOWN ; - CP 'C' ; IS CURSOR RIGHT? - JP Z, PERF_CURSOR_RIGHT ; - CP 'D' ; IS CURSOR LEFT? - JP Z, PERF_CURSOR_LEFT ; - CP 'F' ; IS ENTER GRAPHICS MODE? - JP Z, PERF_ENTER_GR ; - CP 'G' ; IS EXIT GRAPHICS MODE? - JP Z, PERF_EXIT_GR ; - CP 'H' ; IS CURSOR HOME? - JP Z, PERF_CURSOR_HOME ; - CP 'I' ; IS CURSOR HOME? - JP Z, PERF_REVERSE_LF ; - CP 'Y' ; IS REVERSE LINE FEED? - JP Z, PERF_DIRECT_ADDRESS ; - CP 'K' ; IS ERASE TO END OF LINE? - JP Z,PERF_ERASE_EOL ; - CP 'J' ; IS ERASE TO END OF SCREEN? - JP Z,PERF_ERASE_EOS ; - CP 'Z' ; IS TERMINAL IDENTIFY? - JP Z,PERF_IDENTIFY ; - CP '{' ; IS ENTER HOLD SCREEN MODE? - JP Z,PERF_ENTER_HOLD ; - CP 05CH ; IS EXIT HOLD SCREEN MODE? - JP Z,PERF_EXIT_HOLD ; - CP '=' ; IS ENTER ALT KEYPAD MODE? - JP Z,PERF_ENTER_ALT ; - CP '}' ; IS EXIT ALT KEYPAD MODE? - JP Z,PERF_EXIT_ALT ; - CALL VDU_PUTCHAR ; NORMAL OUTPUT CHAR - JP SET_STATE_NORMAL ; - - -;__PERF_REVERSE_LF_________________________________________________________________________________ -; -; PERFORM REVERSE LINE FEED -;__________________________________________________________________________________________________ -PERF_REVERSE_LF: - CALL SET_STATE_NORMAL ; SET STATE TO NORMAL - LD A,(TERM_Y) ; GET CURRENT Y COORD INTO A - OR A ; IS ZERO - JP Z,REVERSE_SCROLL ; YES, SCROLL SCREEN DOWN ONE LINE - DEC A ; NO, MOVE CRSR UP ONE LINE - LD (TERM_Y),A ; STORE NEW CRSR POSITION - JP GOTO_XY ; POSITION CRSR - - -;__PERF_DIRECT_ADDRESS_____________________________________________________________________________ -; -; PERFORM DIRECT CURSOR ADDRESSING -;__________________________________________________________________________________________________ -PERF_DIRECT_ADDRESS: - LD A,STATE_DIR_L ; SET STATE "WAITING FOR Y COORD" - LD (TERMSTATE),A ; - RET ; - -;__PERF_ENTER_GR___________________________________________________________________________________ -; -; PERFORM ENTER GRAPHICS MODE -;__________________________________________________________________________________________________ -PERF_ENTER_GR: - LD A,0FFH ; - LD (GR_MODE),A ; GRAPHICS MODE - JP SET_STATE_NORMAL ; - - -;__PERF_EXIT_GR____________________________________________________________________________________ -; -; PERFORM EXIT GRAPHICS MODE -;__________________________________________________________________________________________________ -PERF_EXIT_GR: - LD A,00FH ; - LD (GR_MODE),A ; GRAPHICS MODE - JP SET_STATE_NORMAL ; - - -;__PERF_ENTER_ALT___________________________________________________________________________________ -; -; PERFORM ENTER ALTERNATE KEYPAD MODE -;__________________________________________________________________________________________________ -PERF_ENTER_ALT: - LD A,0FFH ; - LD (ALT_KEYPAD),A ; ALT KEYPAD - JP SET_STATE_NORMAL ; - - -;__PERF_EXIT_ALT___________________________________________________________________________________ -; -; PERFORM EXIT ALTERNATE KEYPAD MODE -;__________________________________________________________________________________________________ -PERF_EXIT_ALT: - LD A,00H ; - LD (ALT_KEYPAD),A ; ALT KEYPAD - JP SET_STATE_NORMAL ; - -;__PERF_ENTER_HOLD_________________________________________________________________________________ -; -; PERFORM ENTER HOLD MODE -;__________________________________________________________________________________________________ -PERF_ENTER_HOLD: - ; ********* IGNORE HOLD MODE !! - JP SET_STATE_NORMAL ; - - -;__PERF_EXIT_HOLD__________________________________________________________________________________ -; -; PERFORM EXIT HOLD MODE -;__________________________________________________________________________________________________ -PERF_EXIT_HOLD: - ; ********* IGNORE HOLD MODE !! - JP SET_STATE_NORMAL ; - - -;__SET_STATE_NORMAL________________________________________________________________________________ -; -; SET NORMAL STATE -;__________________________________________________________________________________________________ -SET_STATE_NORMAL: - LD A,STATE_NORMAL ; RESET STATE - LD (TERMSTATE),A ; - RET - +; ;__PERF_ERASE_EOL__________________________________________________________________________________ ; ; PERFORM ERASE FROM CURSOR POS TO END OF LINE ;__________________________________________________________________________________________________ -PERF_ERASE_EOL: - LD A,(TERM_X) ; GET CURRENT CURSOR X COORD +PERF_ERASE_EOL: + LD A,(VDU_X) ; GET CURRENT CURSOR X COORD LD C,A ; STORE IT IN C LD A,80 ; MOVE CURRENT LINE WIDTH INTO A SUB C ; GET REMAINING POSITIONS ON CURRENT LINE LD B,A ; MOVE IT INTO B - LD A, 31 ; UPDATE TOGGLE VDU CHIP - OUT (SY6545S),A ; + LD A,31 ; UPDATE TOGGLE VDU CHIP + OUT (VDU_STREG),A PERF_ERASE_EOL_LOOP: - CALL VDU_UPDATECHECK ; WAIT FOR VDU CHIP TO BE READY + CALL VDU_WAITRDY ; WAIT FOR VDU CHIP TO BE READY LD A,32 ; MOVE SPACE CHARACTER INTO A - OUT (WRITR),A ; WRITE IT TO SCREEN, VDU WILL AUTO INC TO NEXT ADDRESS - DJNZ PERF_ERASE_EOL_LOOP ; LOOP UNTIL DONE - CALL GOTO_XY ; MOVE CURSOR BACK TO ORIGINAL POSITION - CALL SET_STATE_NORMAL ; SET NORMAL STATE + OUT (VDU_WR),A ; WRITE IT TO SCREEN, VDU WILL AUTO INC TO NEXT ADDRESS + DJNZ PERF_ERASE_EOL_LOOP ; LOOP UNTIL DONE + CALL VDU_XY ; MOVE CURSOR BACK TO ORIGINAL POSITION RET - +; ;__PERF_ERASE_EOS__________________________________________________________________________________ ; ; PERFORM ERASE FROM CURSOR POS TO END OF SCREEN @@ -551,105 +219,30 @@ PERF_ERASE_EOL_LOOP: PERF_ERASE_EOS: LD HL,0780H ; SET SCREEN SIZE INTO HL PUSH HL ; MOVE IT TO DE - POP DE ; - LD A, 31 ; UPDATE TOGGLE VDU CHIP - OUT (SY6545S),A ; + POP DE + LD A,31 ; UPDATE TOGGLE VDU CHIP + OUT (VDU_STREG),A PERF_ERASE_EOS_LOOP: - CALL VDU_UPDATECHECK ; WAIT FOR VDU CHIP TO BE READY - LD A, ' ' ; MOVE SPACE CHARACTER INTO A - OUT (WRITR),A ; WRITE IT TO SCREEN, VDU WILL AUTO INC TO NEXT ADDRESS - DEC DE ; DEC COUNTER - LD A,D ; IS COUNTER 0 YET? - OR E ; - JP NZ,PERF_ERASE_EOS_LOOP ; NO, LOOP - CALL GOTO_XY ; YES, MOVE CURSOR BACK TO ORIGINAL POSITION - CALL SET_STATE_NORMAL ; SET NORMAL STATE + CALL VDU_WAITRDY ; WAIT FOR VDU CHIP TO BE READY + LD A, ' ' ; MOVE SPACE CHARACTER INTO A + OUT (VDU_WR),A ; WRITE IT TO SCREEN, VDU WILL AUTO INC TO NEXT ADDRESS + DEC DE ; DEC COUNTER + LD A,D ; IS COUNTER 0 YET? + OR E + JP NZ,PERF_ERASE_EOS_LOOP ; NO, LOOP + CALL VDU_XY ; YES, MOVE CURSOR BACK TO ORIGINAL POSITION RET - - -;__PERF_IDENTIFY___________________________________________________________________________________ -; -; PERFORM TERMINAL IDENTIFY FUNCTION -;__________________________________________________________________________________________________ -PERF_IDENTIFY: -; LD A,ESC_KEY ; -; CALL KB_ENQUEUE ; STORE ON KB QUEUE -; LD A,'/' ; -; CALL KB_ENQUEUE ; STORE ON KB QUEUE -; LD A,'K' ; -; CALL KB_ENQUEUE ; STORE ON KB QUEUE - CALL SET_STATE_NORMAL ; SET NORMAL STATE - RET - +; ;__PERF_CURSOR_HOME________________________________________________________________________________ ; ; PERFORM CURSOR HOME ;__________________________________________________________________________________________________ PERF_CURSOR_HOME: LD A,0 ; LOAD 0 INTO A - LD (TERM_X),A ; SET X COORD - LD (TERM_Y),A ; SET Y COORD - CALL SET_STATE_NORMAL ; SET NORMAL STATE - JP GOTO_XY ; MOVE CURSOR TO POSITION - -;__PERF_CURSOR_LEFT________________________________________________________________________________ -; -; PERFORM CURSOR LEFT -;__________________________________________________________________________________________________ -PERF_CURSOR_LEFT: - LD A,(TERM_X) ; GET CURRENT X COORD INTO A - OR A ; IS ZERO? - JP Z,PERF_CURSOR_ABORT ; YES, ABORT - DEC A ; MOVE ONE TO THE LEFT - LD (TERM_X),A ; STORE NEW CURSOR POSITION - CALL SET_STATE_NORMAL ; SET NORMAL STATE - JP GOTO_XY ; MOVE CURSOR TO POSITION - -;__PERF_CURSOR_RIGHT_______________________________________________________________________________ + LD (VDU_X),A ; SET X COORD + LD (VDU_Y),A ; SET Y COORD + JP VDU_XY ; MOVE CURSOR TO POSITION ; -; PERFORM CURSOR RIGHT -;__________________________________________________________________________________________________ -PERF_CURSOR_RIGHT: - LD A,(TERM_X) ; GET CURRENT X COORD INTO A - CP 79 ; IS END OF LINE? - JP Z,PERF_CURSOR_ABORT ; YES, ABORT - INC A ; MOVE ONE TO THE RIGHT - LD (TERM_X),A ; STORE NEW CURSOR POSITION - CALL SET_STATE_NORMAL ; SET NORMAL STATE - JP GOTO_XY ; MOVE CURSOR TO POSITION - -;__PERF_CURSOR_UP__________________________________________________________________________________ -; -; PERFORM CURSOR UP -;__________________________________________________________________________________________________ -PERF_CURSOR_UP: - LD A,(TERM_Y) ; GET CURRENT Y COORD INTO A - OR A ; IS ZERO? - JP Z,PERF_CURSOR_ABORT ; YES, ABORT - DEC A ; MOVE UP ONE POSITION - LD (TERM_Y),A ; STORE NEW CURSOR POSITION - CALL SET_STATE_NORMAL ; SET NORMAL STATE - JP GOTO_XY ; MOVE CURSOR TO POSTION - - -;__PERF_CURSOR_DOWN________________________________________________________________________________ -; -; PERFORM CURSOR DOWN -;__________________________________________________________________________________________________ -PERF_CURSOR_DOWN: - LD A,(TERM_Y) ; GET CURRENT Y COORD INTO A - CP 23 ; IS END OF SCREEN? - JP Z,PERF_CURSOR_ABORT ; YES, ABORT - INC A ; NO, MOVE DOWN ONE POSITION - LD (TERM_Y),A ; STORE NEW CURSOR POSITION -PERF_CURSOR_ABORT: - CALL SET_STATE_NORMAL ; SET NORMAL STATE - JP GOTO_XY ; MOVE CURSOR TO POSITION - - - - - ;__DO_SCROLL_______________________________________________________________________________________ ; ; SCROLL THE SCREEN UP ONE LINE @@ -660,30 +253,30 @@ DO_SCROLL1: PUSH HL ; STORE HL PUSH BC ; STORE BC LD A, 31 ; TOGGLE VDU FOR UPDATE - OUT (SY6545S),A ; - CALL VDU_UPDATECHECK ; WAIT FOR VDU TO BE READY + OUT (VDU_STREG),A + CALL VDU_WAITRDY ; WAIT FOR VDU TO BE READY LD HL, (VDU_DISPLAY_START) ; GET UP START OF DISPLAY LD DE,0050H ; SET AMOUNT TO ADD ADD HL,DE ; ADD TO START POS LD (VDU_DISPLAY_START),HL ; STORE DISPLAY START LD A, 12 ; SAVE START OF DISPLAY TO VDU - CALL VDU_HL2WREG_A ; - LD A,23 ; SET CURSOR TO BEGINNING OF LAST LINE - LD (TERM_Y),A ; - LD A,(TERM_X) ; - PUSH AF ; STORE X COORD - LD A,0 ; - LD (TERM_X),A ; - CALL GOTO_XY ; SET CURSOR POSITION TO BEGINNING OF LINE - CALL PERF_ERASE_EOL ; ERASE SCROLLED LINE + CALL VDU_HL2WREG_A + LD A,23 ; SET CURSOR TO BEGINNING OF LAST LINE + LD (VDU_Y),A + LD A,(VDU_X) + PUSH AF ; STORE X COORD + LD A,0 + LD (VDU_X),A + CALL VDU_XY ; SET CURSOR POSITION TO BEGINNING OF LINE + CALL PERF_ERASE_EOL ; ERASE SCROLLED LINE POP AF ; RESTORE X COORD - LD (TERM_X),A ; - CALL GOTO_XY ; SET CURSOR POSITION - POP BC ; RESTORE BC - POP HL ; RESTORE HL - POP AF ; RESTORE AF - RET ; - + LD (VDU_X),A + CALL VDU_XY ; SET CURSOR POSITION + POP BC ; RESTORE BC + POP HL ; RESTORE HL + POP AF ; RESTORE AF + RET ; +; ;__REVERSE_SCROLL__________________________________________________________________________________ ; ; SCROLL THE SCREEN DOWN ONE LINE @@ -692,31 +285,31 @@ REVERSE_SCROLL: PUSH AF ; STORE AF PUSH HL ; STORE HL PUSH BC ; STORE BC - LD A, 31 ; TOGGLE VDU FOR UPDATE - OUT (SY6545S),A ; - CALL VDU_UPDATECHECK ; WAIT FOR VDU TO BE READY - LD HL, (VDU_DISPLAY_START) ; GET UP START OF DISPLAY + LD A, 31 ; TOGGLE VDU FOR UPDATE + OUT (VDU_STREG),A + CALL VDU_WAITRDY ; WAIT FOR VDU TO BE READY + LD HL, (VDU_DISPLAY_START) ; GET UP START OF DISPLAY LD DE,0FFB0H ; SET AMOUNT TO SUBTRACT (TWOS COMPLEMENT 50H) ADD HL,DE ; ADD TO START POS LD (VDU_DISPLAY_START),HL ; STORE DISPLAY START - LD A, 12 ; SAVE START OF DISPLAY TO VDU - CALL VDU_HL2WREG_A ; - LD A,23 ; SET CURSOR TO BEGINNING OF LAST LINE - LD (TERM_Y),A ; - LD A,(TERM_X) ; - PUSH AF ; STORE X COORD - LD A,0 ; - LD (TERM_X),A ; - CALL GOTO_XY ; SET CURSOR POSITION TO BEGINNING OF LINE - CALL PERF_ERASE_EOL ; ERASE SCROLLED LINE + LD A, 12 ; SAVE START OF DISPLAY TO VDU + CALL VDU_HL2WREG_A + LD A,23 ; SET CURSOR TO BEGINNING OF LAST LINE + LD (VDU_Y),A + LD A,(VDU_X) + PUSH AF ; STORE X COORD + LD A,0 + LD (VDU_X),A + CALL VDU_XY ; SET CURSOR POSITION TO BEGINNING OF LINE + CALL PERF_ERASE_EOL ; ERASE SCROLLED LINE POP AF ; RESTORE X COORD - LD (TERM_X),A ; - CALL GOTO_XY ; SET CURSOR POSITION - POP BC ; RESTORE BC - POP HL ; RESTORE HL - POP AF ; RESTORE AF - RET ; - + LD (VDU_X),A + CALL VDU_XY ; SET CURSOR POSITION + POP BC ; RESTORE BC + POP HL ; RESTORE HL + POP AF ; RESTORE AF + RET +; ;__VDUINIT__________________________________________________________________________________________ ; ; INITIALIZE VDU @@ -728,23 +321,23 @@ VDUINIT: CALL VDU_CRTINIT ; INIT 6545 VDU CHIP LD A, 31 ; TOGGLE VDU FOR UPDATE - OUT (SY6545S),A ; + OUT (VDU_STREG),A LD HL,0 ; SET-UP START OF DISPLAY LD DE, 2048 ; SET-UP DISPLAY SIZE LD A, 18 ; WRITE HL TO R18 AND R19 (UPDATE ADDRESS) CALL VDU_HL2WREG_A ; LD A, 31 ; TOGGLE VDU FOR UPDATE - OUT (SY6545S),A ; + OUT (VDU_STREG),A VDU_CRTSPACELOOP: ; - CALL VDU_UPDATECHECK ; WAIT FOR VDU TO BE READY + CALL VDU_WAITRDY ; WAIT FOR VDU TO BE READY LD A, ' ' ; CLEAR SCREEN - OUT (WRITR),A ; SEND SPACE TO DATAPORT + OUT (VDU_WR),A ; SEND SPACE TO DATAPORT DEC DE ; DECREMENT DE LD A,D ; IS ZERO? OR E ; JP NZ, VDU_CRTSPACELOOP ; NO, LOOP LD A, 31 ; TOGGLE VDU FOR UPDATE - OUT (SY6545S),A ; + OUT (VDU_STREG),A LD HL, 0 ; SET UP START OF DISPLAY LD (VDU_DISPLAY_START),HL ; STORE DISPLAY START LD A, 12 ; SAVE START OF DISPLAY TO VDU @@ -754,57 +347,8 @@ VDU_CRTSPACELOOP: ; POP AF ; CALL PERF_CURSOR_HOME ; CURSOR HOME CALL PERF_ERASE_EOS ; CLEAR SCREEN - CALL VDU_CURSORON ; TURN ON CURSOR RET - - -;;__DSPMATRIX_______________________________________________________________________________________ -;; -;; DISPLAY INTRO SCREEN -;;__________________________________________________________________________________________________ -;DSPMATRIX: -; CALL PERF_CURSOR_HOME ; RESET CURSOR TO HOME POSITION -; LD HL,TESTMATRIX ; SET HL TO SCREEN IMAGE -; LD DE, 1918 ; SET IMAGE SIZE -;DSPMATRIX_LOOP: -; LD A,(HL) ; GET NEXT CHAR FROM IMAGE -; CALL VDU_PUTCHAR ; DUMP CHAR TO DISPLAY -; INC HL ; INC POINTER -; DEC DE ; DEC COUNTER -; LD A,D ; IS COUNTER ZERO? -; OR E ; -; JP NZ,DSPMATRIX_LOOP ; NO, LOOP -; CALL PERF_CURSOR_HOME ; YES, RESET CURSOR TO HOME POSITION -; RET - -;TESTMATRIX: -; .TEXT "0 1 2 3 4 5 6 7 " -; .TEXT "01234567890123456789012345678901234567890123456789012345678901234567890123456789" -; .TEXT "2 " -; .TEXT "3 " -; .TEXT "4 " -; .TEXT "5 " -; .TEXT "6 NN NN 8888 VV VV EEEEEEEEEE MM MM " -; .TEXT "7 NNNN NN 88 88 VV VV EE MMMM MMMM " -; .TEXT "8 NN NN NN 88 88 VV VV EE MM MM MM MM " -; .TEXT "9 NN NNNN 88 88 VV VV EE MM MM MM " -; .TEXT "10 NN NN 8888 VV VV EEEEEEE MM MM " -; .TEXT "11 NN NN 88 88 VV VV EE MM MM " -; .TEXT "12 NN NN 88 88 VV VV EE MM MM " -; .TEXT "13 NN NN 88 88 VVV EE MM MM " -; .TEXT "14 NN NN 8888 V EEEEEEEEEE MM MM S B C " -; .TEXT "15 " -; .TEXT "16 " -; .TEXT "17 " -; .TEXT "18 * VDU OK * VT-52 EMULATION " -; .TEXT "19 " -; .TEXT "20 ** PRESS ANY KEY TO ENTER TERMINAL MODE ** " -; .TEXT "21 " -; .TEXT "22 " -; .TEXT "23 " -; .TEXT "24 " - - +; ;__VDU_HL2WREG_A___________________________________________________________________________________ ; ; WRITE VALUE IN HL TO REGISTER IN A @@ -813,70 +357,18 @@ VDU_CRTSPACELOOP: ; ;__________________________________________________________________________________________________ VDU_HL2WREG_A: PUSH BC ; STORE BC -; PUSH AF ; STORE AF -; CALL VDU_UPDATECHECK ; WAIT FOR VDU TO BE READY -; POP AF ; RESTORE AF - LD C, SY6545S ; ADDRESS REGISTER - OUT (C), A ; SELECT REGISTER (A) + LD C,VDU_STREG ; ADDRESS REGISTER + OUT (C),A ; SELECT REGISTER (A) INC C ; NEXT WRITE IN REGISTER - OUT (C), H ; WRITE H TO SELECTED REGISTER + OUT (C),H ; WRITE H TO SELECTED REGISTER DEC C ; NEXT WRITE SELECT REGISTER INC A ; INCREASE REGISTER NUMBER - OUT (C), A ; SELECT REGISTER (A+1) + OUT (C),A ; SELECT REGISTER (A+1) INC C ; NEXT WRITE IN REGISTER - OUT (C), L ; WRITE L TO SELECTED REGISTER + OUT (C),L ; WRITE L TO SELECTED REGISTER POP BC ; RESTORE BC RET - -;__VDU_UPDATECHECK_________________________________________________________________________________ -; -; WAIT FOR VDU TO BE READY -;__________________________________________________________________________________________________ -VDU_UPDATECHECK: - IN A,(SY6545S) ; READ ADDRESS/STATUS REGISTER - BIT 7,A ; IF BIT 7 = 1 THAN AN UPDATE STROBE HAS OCCURED - RET NZ - JR VDU_UPDATECHECK ; WAIT FOR READY - -VDU_INIT6845: -; DB 07FH, 50H, 60H, 7CH, 19H, 1FH, 19H, 1AH, 78H, 09H, 60H, 09H, 00H, 00H, 00H, 00H - - ; CCIR 625/50 VERSION (USED IN MOST OF THE WORLD) - ; JUMPER K1 2-3, K2 1-2 FOR 2MHz CHAR CLOCK - .DB 07FH ; R0 TOTAL NUMBER OF HORIZONTAL CHARACTERS (DETERMINES HSYNC) - .DB 050H ; R1 NUMBER OF HORIZONTAL CHARACTERS DISPLAYED (80 COLUMNS) - .DB 060H ; R2 HORIZONTAL SYNC POSITION - .DB 00CH ; R3 SYNC WIDTHS - .DB 01EH ; R4 VERTICAL TOTAL (TOTAL CHARS IN A FRAME -1) - .DB 002H ; R5 VERTICAL TOTAL ADJUST ( - .DB 018H ; R6 VERTICAL DISPLAYED (24 ROWS) - .DB 01AH ; R7 VERTICAL SYNC - .DB 078H ; R8 MODE B7=0 TRANSPARENT UPDATE DURING BLANKING - ; B6=1 PIN 34 IS UPDATE STROBE - ; B5=1 DELAY CURSOR 1 CHARACTER - ; B4=1 DELAY DISPLAY ENABLE 1 CHARACTER - ; B3=1 TRANSPARENT MEMORY ADDRESSING - ; B2=0 RAM STRAIGHT BINARY ADDRESSING - ; B1,B0=0 NON-INTERLACE - .DB 009H ; R9 SCAN LINE (LINES PER CHAR AND SPACING -1) - .DB 060H ; R10 CURSOR START RASTER - .DB 009H ; R11 CURSOR END RASTER - .DB 00H ; R12 START ADDRESS HI - .DB 00H ; R13 START ADDRESS LO - .DB 00H ; R14 CURSOR ADDRESS HI - .DB 00H ; R15 CURSOR ADDRESS LO -; THE CCIR 625/50 TELEVISION STANDARD HAS 625 LINES INTERLACED AT 50 FIELDS PER SECOND. THIS WORKS -; OUT AS 50 FIELDS OF 312.5 LINES PER SECOND NON-INTERLACED AS USED HERE. -; HORIZONTAL LINE WIDTH IS 64uS. FOR A 2 MHz CHARACTER CLOCK (R0+1)/2000000 = 64uS -; NEAREST NUMBER OF LINES IS 312 = (R4+1) * (R9+1) + R5. -; 15625 / 312 = 50.08 FIELDS PER SECOND (NEAR ENOUGH-DGG) ; -; IF TRYING THE SLOWER CHAR CLOCK TO GIVE 9 PIXELS HORIZONTAL PER CHAR, CHANGE THE FOLLOWING -; JUMPER K1 1-2 TO GIVE 1.777MHz CHAR CLOCK -; CHANGE R0 TO 112 FOR A HSYNC OF 15732 -; CHANGE R2 TO 91 TO CENTRE DISPLAY - - ;__VDU_CRTINIT_____________________________________________________________________________________ ; ; INIT VDU CHIP @@ -886,15 +378,15 @@ VDU_CRTINIT: PUSH BC ; STORE BC PUSH DE ; STORE DE PUSH HL ; STORE HL - LD BC,010F2h ; B = 16, C = SY6545S + LD BC,010F2h ; B = 16, C = VDU_STREG LD HL,VDU_INIT6845 ; HL = POINTER TO THE DEFAULT VALUES XOR A ; A = 0 VDU_CRTINITLOOP: - OUT (C), A ; SY6545S SET REGISTER + OUT (C), A ; VDU_STREG SET REGISTER INC C ; 0F3h LD D,(HL) ; LOAD THE NEXT DEFAULT VALUE IN D OUT (C),D ; 0F3h ADDRESS - DEC C ; SY6545S + DEC C ; VDU_STREG INC HL ; TAB + 1 INC A ; REG + 1 DJNZ VDU_CRTINITLOOP ; LOOP UNTIL DONE @@ -903,52 +395,23 @@ VDU_CRTINITLOOP: POP BC ; RESTORE BC POP AF ; RESTORE AF RET - - -;__VDU_CURSORON____________________________________________________________________________________ ; -; TURN ON CURSOR -;__________________________________________________________________________________________________ -VDU_CURSORON: - PUSH AF ; STORE AF - LD A, 060h ; SET CURSOR VALUE - JP VDU_CURSORSET ; - -;__VDU_CURSOROFF___________________________________________________________________________________ +;__VDU_XY__________________________________________________________________________________________ ; -; TURN OFF CURSOR -;__________________________________________________________________________________________________ -VDU_CURSOROFF: - PUSH AF ; STORE AF - LD A, 020h ; SET CURSOR VALUE -VDU_CURSORSET: - PUSH BC ; STORE BC - LD C,A ; MOVE A TO C - CALL VDU_UPDATECHECK ; WAIT FOR VDU TO BE READY - LD A, 10 ; R10, CURSOR START AND STATUS - OUT (SY6545S), A ; - LD A,C ; STORE CURSOR VALUE - OUT (SY6545D), A ; - POP BC ; RESTORE BC - POP AF ; RESTORE AF - RET - -;__GOTO_XY_________________________________________________________________________________________ -; -; MOVE CURSOR TO POSITON IN TERM_X AND TERM_Y +; MOVE CURSOR TO POSITON IN VDU_X AND VDU_Y ;__________________________________________________________________________________________________ -GOTO_XY: +VDU_XY: PUSH AF ; STORE AF - LD A,(TERM_Y) ; PLACE Y COORD IN A + LD A,(VDU_Y) ; PLACE Y COORD IN A CP 24 ; IS 24? JP Z,DO_SCROLL1 ; YES, MUST SCROLL PUSH BC ; STORE BC PUSH DE ; STORE DE - LD A,(TERM_X) ; + LD A,(VDU_X) ; LD H,A ; - LD A,(TERM_Y) ; + LD A,(VDU_Y) ; LD L,A ; PUSH HL ; STORE HL LD B, A ; B = Y COORD @@ -973,115 +436,58 @@ VDU_YLOOPEND: ; LD A, 18 ; SET UPDATE ADDRESS IN VDU CALL VDU_HL2WREG_A ; LD A, 31 ; TOGGLE VDU FOR UPDATE - OUT (SY6545S),A ; + OUT (VDU_STREG),A LD A, 14 ; SET CURSOR POS CALL VDU_HL2WREG_A ; POP DE ; RESTORE DE POP BC ; RESTORE BC POP AF ; RESTORE AF RET - -;__VDU_PUTCHAR______________________________________________________________________________________ -; -; PLACE CHARACTER ON SCREEN -; A: CHARACTER TO OUTPUT -;__________________________________________________________________________________________________ -VDU_PUTCHAR: - PUSH DE ; STORE DE - PUSH AF ; STORE AF - LD A,(TERM_X) ; PLACE X COORD IN A - INC A ; INC X COORD - LD (TERM_X),A ; STORE IN A - CP 80 ; IS 80? - JP NZ,VDU_PUTCHAR1 ; NO, PLACE CHAR ON DISPLAY - LD A,0 ; YES, WRAP TO NEXT LINE - LD (TERM_X),A ; STORE X - LD A,(TERM_Y) ; A= Y COORD - INC A ; INC Y COORD - LD (TERM_Y),A ; STORE Y - CP 24 ; IS PAST END OF SCREEN? - CALL Z,GOTO_XY ; YES, HANDLE SCROLLING -VDU_PUTCHAR1: ; - CALL VDU_UPDATECHECK ; WAIT FOR VDU TO BE READY - ; - LD A, 31 ; TOGGLE VDU FOR UPDATE - OUT (SY6545S),A ; - ; - CALL VDU_UPDATECHECK ; WAIT FOR VDU TO BE READY - ; - LD A, 31 ; TOGGLE VDU FOR UPDATE - OUT (SY6545S),A ; - ; - POP AF ; RESTORE CHAR - OUT (WRITR), A ; OUTPUT CHAR TO VDU - PUSH AF ; STORE AF - PUSH HL ; STORE HL - LD HL, (VDU_DISPLAYPOS) ; GET CURRENT DISPLAY ADDRESS - INC HL ; INCREMENT IT - LD (VDU_DISPLAYPOS), HL ; STORE CURRENT DISPLAY ADDRESS - PUSH HL ; MOVE HL TO DE - POP DE ; - LD HL,(VDU_DISPLAY_START) ; - ADD HL,DE ; - LD A, 14 ; UPDATE CURSOR POSITION IN HARDWARE - CALL VDU_HL2WREG_A ; - POP HL ; RESTORE HL - POP AF ; RESTORE AF - POP DE ; RESTORE DE - RET - - - - - - -;;__PR_OUTCHAR______________________________________________________________________________________ -;; -;; PR_OUTCHAR- OUTPUT CHAR TO PRINTER PORT -;; A: CHAR TO OUTPUT -;;__________________________________________________________________________________________________ -;PR_OUTCHAR: -; PUSH AF ; STORE AF -;PR_OUTCHAR_LOOP: -; IN A,(VPPIB) ; GET STATUS INFO -; AND 10000000B ; ONLY INTERESTED IN BUSY FLAG -; JP NZ,PR_OUTCHAR_LOOP ; LOOP IF BUSY -; POP AF ; RESTORE AF -; OUT (VPPIA),A ; OUTPUT DATA TO PORT -; LD A,1 ; 01 SECOND DELAY -; CALL KB_DELAY ; IGNORE ANYTHING BACK AFTER A RESET -; CALL KB_PORTCBIT0LOW ; STROBE -; LD A,1 ; 01 SECOND DELAY -; CALL KB_DELAY ; IGNORE ANYTHING BACK AFTER A RESET -; CALL KB_PORTCBIT0HIGH ; STROBE -; RET - -;;__PR_INITIALIZE___________________________________________________________________________________ -;; -;; INITIALISE - SET UP PORT FOR PRINTING -;;__________________________________________________________________________________________________ -;PR_INITIALIZE: -; CALL KB_PORTCBIT0HIGH ; STROBE -; CALL KB_PORTCBIT1HIGH ; FORM FEED -; CALL KB_PORTCBIT2LOW ; DEVICE SELECT -; CALL KB_PORTCBIT3LOW ; DEVICE INIT -; LD A,200 ; 1 SECOND DELAY -; CALL KB_DELAY ; IGNORE ANYTHING BACK AFTER A RESET -; CALL KB_PORTCBIT3HIGH ; DEVICE INIT -; RET - - ; ;================================================================================================== ; VDU DRIVER - DATA ;================================================================================================== ; -ALT_KEYPAD .DB 0 ; ALT KEYPAD ENABLED? -GR_MODE .DB 0 ; GRAPHICS MODE ENABLED? -TERM_X .DB 0 ; CURSOR X -TERM_Y .DB 0 ; CURSOR Y -TERMSTATE .DB 0 ; TERMINAL STATE - ; 0 = NORMAL - ; 1 = ESC RCVD +VDU_X .DB 0 ; CURSOR X +VDU_Y .DB 0 ; CURSOR Y VDU_DISPLAYPOS .DW 0 ; CURRENT DISPLAY POSITION VDU_DISPLAY_START .DW 0 ; CURRENT DISPLAY POSITION +; +;================================================================================================== +; VDU DRIVER - 6845 REGISTER INITIALIZATION +;================================================================================================== +; +VDU_INIT6845: +; DB 07FH, 50H, 60H, 7CH, 19H, 1FH, 19H, 1AH, 78H, 09H, 60H, 09H, 00H, 00H, 00H, 00H +; + ; CCIR 625/50 VERSION (USED IN MOST OF THE WORLD) + ; JUMPER K1 2-3, K2 1-2 FOR 2MHz CHAR CLOCK + .DB 07FH ; R0 TOTAL NUMBER OF HORIZONTAL CHARACTERS (DETERMINES HSYNC) + .DB 050H ; R1 NUMBER OF HORIZONTAL CHARACTERS DISPLAYED (80 COLUMNS) + .DB 060H ; R2 HORIZONTAL SYNC POSITION + .DB 00CH ; R3 SYNC WIDTHS + .DB 01EH ; R4 VERTICAL TOTAL (TOTAL CHARS IN A FRAME -1) + .DB 002H ; R5 VERTICAL TOTAL ADJUST ( + .DB 018H ; R6 VERTICAL DISPLAYED (24 ROWS) + .DB 01AH ; R7 VERTICAL SYNC + .DB 078H ; R8 MODE B7=0 TRANSPARENT UPDATE DURING BLANKING + ; B6=1 PIN 34 IS UPDATE STROBE + ; B5=1 DELAY CURSOR 1 CHARACTER + ; B4=1 DELAY DISPLAY ENABLE 1 CHARACTER + ; B3=1 TRANSPARENT MEMORY ADDRESSING + ; B2=0 RAM STRAIGHT BINARY ADDRESSING + ; B1,B0=0 NON-INTERLACE + .DB 009H ; R9 SCAN LINE (LINES PER CHAR AND SPACING -1) + .DB 060H ; R10 CURSOR START RASTER + .DB 009H ; R11 CURSOR END RASTER + .DB 00H ; R12 START ADDRESS HI + .DB 00H ; R13 START ADDRESS LO + .DB 00H ; R14 CURSOR ADDRESS HI + .DB 00H ; R15 CURSOR ADDRESS LO +; +; THE CCIR 625/50 TELEVISION STANDARD HAS 625 LINES INTERLACED AT 50 FIELDS PER SECOND. THIS WORKS +; OUT AS 50 FIELDS OF 312.5 LINES PER SECOND NON-INTERLACED AS USED HERE. +; HORIZONTAL LINE WIDTH IS 64uS. FOR A 2 MHz CHARACTER CLOCK (R0+1)/2000000 = 64uS +; NEAREST NUMBER OF LINES IS 312 = (R4+1) * (R9+1) + R5. +; 15625 / 312 = 50.08 FIELDS PER SECOND (NEAR ENOUGH-DGG) +; diff --git a/branches/dgg/Source/ver.inc b/branches/dgg/Source/ver.inc index b2d57a13..5e5d7ba9 100644 --- a/branches/dgg/Source/ver.inc +++ b/branches/dgg/Source/ver.inc @@ -1,6 +1,6 @@ #DEFINE RMJ 2 #DEFINE RMN 2 #DEFINE RUP 0 -#DEFINE RTP 2 -#DEFINE BIOSVER "2.2 B2" +#DEFINE RTP 3 +#DEFINE BIOSVER "2.2 B3" #DEFINE REVISION 1741