; ;================================================================================================== ; UTILITY FUNCTIONS ;================================================================================================== ; ; CHR_CR .EQU 0DH CHR_LF .EQU 0AH CHR_BS .EQU 08H CHR_ESC .EQU 1BH ; ;__________________________________________________________________________________________________ ; ; UTILITY PROCS TO PRINT SINGLE CHARACTERS WITHOUT TRASHING ANY REGISTERS ; PC_SPACE: PUSH AF LD A,' ' JR PC_PRTCHR PC_PERIOD: PUSH AF LD A,'.' JR PC_PRTCHR PC_COLON: PUSH AF LD A,':' JR PC_PRTCHR PC_COMMA: PUSH AF LD A,',' JR PC_PRTCHR PC_LBKT: PUSH AF LD A,'[' JR PC_PRTCHR PC_RBKT: PUSH AF 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,'(' JR PC_PRTCHR PC_RPAREN: PUSH AF LD A,')' JR PC_PRTCHR PC_ASTERISK: PUSH AF LD A,'*' JR PC_PRTCHR PC_CR: PUSH AF LD A,CHR_CR JR PC_PRTCHR PC_LF: PUSH AF LD A,CHR_LF JR PC_PRTCHR PC_PRTCHR: CALL COUT POP AF RET NEWLINE: CALL PC_CR CALL PC_LF RET ; ; PRINT THE HEX BYTE VALUE IN A ; PRTHEXBYTE: PUSH AF PUSH DE LD DE,HEXSTRBUF CALL HEXSTRBYTE LD A,'$' LD (DE),A LD DE,HEXSTRBUF CALL WRITESTR POP DE POP AF RET ; ; PRINT THE HEX WORD VALUE IN BC ; PRTHEXWORD: PUSH AF LD A,B CALL PRTHEXBYTE LD A,C CALL PRTHEXBYTE POP AF RET ; ; CONVERT VALUE IN A TO A 2 CHARACTER HEX STRING AT DE ; HEXCHR .TEXT "0123456789ABCDEF" ; HEXSTRBYTE: PUSH BC PUSH HL PUSH AF LD BC,0 RRA RRA RRA RRA AND 0FH LD C,A LD HL,HEXCHR ADD HL,BC LD A,(HL) LD (DE),A INC DE POP AF PUSH AF LD BC,0 AND 0FH LD C,A LD HL,HEXCHR ADD HL,BC LD A,(HL) LD (DE),A INC DE POP AF POP HL POP BC RET ; ; CONVERT VALUE IN BC TO A 4 CHARACTER HEX STRING AT DE ; HEXSTRWORD: LD A,B CALL HEXSTRBYTE LD A,C CALL HEXSTRBYTE RET ; ; PRINT A BYTE BUFFER IN HEX POINTED TO BY DE ; REGISTER A HAS SIZE OF BUFFER ; PRTHEXBUF: CP 0 ; EMPTY BUFFER? JP Z,PRTHEXBUF2 LD B,A PRTHEXBUF1: CALL PC_SPACE LD A,(DE) CALL PRTHEXBYTE INC DE DJNZ PRTHEXBUF1 JP PRTHEXBUFX PRTHEXBUF2: CALL PC_SPACE LD DE,STR_EMPTY CALL WRITESTR PRTHEXBUFX: RET ; ; OUTPUT A '$' TERMINATED STRING ; WRITESTR: PUSH AF WRITESTR1: LD A,(DE) CP '$' ; TEST FOR STRING TERMINATOR JP Z,WRITESTR2 CALL COUT INC DE JP WRITESTR1 WRITESTR2: POP AF RET ; ; PANIC: TRY TO DUMP MACHINE STATE AND HALT ; PANIC: PUSH HL PUSH DE PUSH BC PUSH AF LD DE,STR_PANIC CALL WRITESTR LD DE,STR_AF CALL WRITESTR POP BC CALL PRTHEXWORD LD DE,STR_BC CALL WRITESTR POP BC CALL PRTHEXWORD LD DE,STR_DE CALL WRITESTR POP BC CALL PRTHEXWORD LD DE,STR_HL CALL WRITESTR POP BC CALL PRTHEXWORD LD DE,STR_PC CALL WRITESTR POP BC CALL PRTHEXWORD LD DE,STR_SP CALL WRITESTR LD (PANIC_SP),SP LD BC,(PANIC_SP) CALL PRTHEXWORD JP 0 ; ;================================================================================================== ; CONSOLE CHARACTER I/O HELPER ROUTINES (REGISTERS PRESERVED) ;================================================================================================== ; ; OUTPUT CHARACTER FROM A COUT: PUSH AF PUSH BC PUSH DE PUSH HL #IFDEF CIOMODE_CONSOLE #DEFINE CIOMODE_NONDOS LD E,A LD A,(CONDEV) LD C,A LD B,BF_CIOOUT CALL BIOS_DISPATCH #ENDIF #IFDEF CIOMODE_CBIOS #DEFINE CIOMODE_NONDOS LD C,A CALL CBIOS_CONOUT #ENDIF #IFNDEF CIOMODE_NONDOS LD E,A LD C,03H CALL 0005H #ENDIF POP HL POP DE POP BC POP AF RET ; ; INPUT CHARACTER TO A ; CIN: PUSH BC PUSH DE PUSH HL #IFDEF CIOMODE_CONSOLE #DEFINE CIOMODE_NONDOS LD A,(CONDEV) LD C,A LD B,BF_CIOIN CALL BIOS_DISPATCH LD A,E #ENDIF #IFDEF CIOMODE_CBIOS #DEFINE CIOMODE_NONDOS CALL CBIOS_CONIN #ENDIF #IFNDEF CIOMODE_NONDOS LD C,01H CALL 0005H #ENDIF POP HL POP DE POP BC RET ; ; RETURN INPUT STATUS IN A (0 = NO CHAR, !=0 CHAR WAITING) ; CST: PUSH BC PUSH DE PUSH HL #IFDEF CIOMODE_CONSOLE #DEFINE CIOMODE_NONDOS LD B,BF_CIOIST LD A,(CONDEV) LD C,A CALL BIOS_DISPATCH #ENDIF #IFDEF CIOMODE_CBIOS #DEFINE CIOMODE_NONDOS CALL CBIOS_CONST #ENDIF #IFNDEF CIOMODE_NONDOS LD C,0BH CALL 0005H #ENDIF POP HL POP DE POP BC RET ; STR_PANIC .DB "\r\n\r\n>>> FATAL ERROR:$" STR_AF .DB " AF=$" STR_BC .DB " BC=$" STR_DE .DB " DE=$" STR_HL .DB " HL=$" STR_PC .DB " PC=$" STR_SP .DB " SP=$" ; ; INDIRECT JUMP TO ADDRESS IN HL ; ; MOSTLY USEFUL TO PERFORM AN INDIRECT CALL LIKE: ; LD HL,xxxx ; CALL JPHL ; JPHL: JP (HL) ; ; DELAY ABOUT 25us (100 TSTATES INCLUDING CALL AND RET) ; ; TOTAL T STATES = ((B*13) + 51) ; 4MHZ CPU, B=4, 103 T STATES = 25.75us ; 8MHZ CPU, B=12, 207 TSTATES = 25.875us ; B = ((2 * FREQ) - 4) ; DELAY: ; 17 T STATES (FOR CALL) PUSH BC ; 11 T STATES LD B,((CPUFREQ * 2) - 4) ; 8 T STATES DJNZ $ ; (B*13) - 5 T STATES POP BC ; 10 T STATES RET ; 10 T STATES ; ; DELAY 25us * VALUE IN DE (VARIABLE DELAY) ; VDELAY: CALL DELAY DEC DE LD A,D OR E JP NZ,VDELAY RET ; ; DELAY ABOUT 0.5 SECONDS = 25us * 20,000 ; LDELAY: PUSH DE LD DE,20000 CALL VDELAY POP DE RET ; ; MULTIPLY 8-BIT VALUES ; IN: MULTIPLY H WITH E ; OUT: HL = RESULT ; MULT8: LD D,0 LD L,D LD B,8 MULT8_LOOP: ADD HL,HL JR NC,MULT8_NOADD ADD HL,DE MULT8_NOADD: DJNZ MULT8_LOOP RET ; ;================================================================================================== ; DSKY KEYBOARD ROUTINES ;================================================================================================== ; #IF (DSKYENABLE) ; ; _____C0______C1______C2______C3__ ;B5 | $20 D $60 E $A0 F $E0 BO ;B4 | $10 A $50 B $90 C $D0 GO ;B3 | $08 7 $48 8 $88 9 $C8 EX ;B2 | $04 4 $44 5 $84 6 $C4 DE ;B1 | $02 1 $42 2 $82 3 $C2 EN ;B0 | $01 FW $41 0 $81 BK $C1 CL ; KY_0 .EQU 000H KY_1 .EQU 001H KY_2 .EQU 002H KY_3 .EQU 003H KY_4 .EQU 004H KY_5 .EQU 005H KY_6 .EQU 006H KY_7 .EQU 007H KY_8 .EQU 008H KY_9 .EQU 009H KY_A .EQU 00AH KY_B .EQU 00BH KY_C .EQU 00CH KY_D .EQU 00DH KY_E .EQU 00EH KY_F .EQU 00FH KY_FW .EQU 010H ; FORWARD KY_BK .EQU 011H ; BACKWARD KY_CL .EQU 012H ; CLEAR KY_EN .EQU 013H ; ENTER KY_DE .EQU 014H ; DEPOSIT KY_EX .EQU 015H ; EXAMINE KY_GO .EQU 016H ; GO KY_BO .EQU 017H ; BOOT ; ;__DSKY_INIT_________________________________________________________________________________________ ; ; CHECK FOR KEY PRESS, SAVE RAW VALUE, RETURN STATUS ;____________________________________________________________________________________________________ ; DSKY_INIT: LD A,82H OUT (PPIX),A LD A,30H ;disable /CS on PPISD card(s) OUT (PPIC),A XOR A LD (KY_BUF),A RET #IFDEF DSKY_KBD ; ;__KY_STAT___________________________________________________________________________________________ ; ; CHECK FOR KEY PRESS, SAVE RAW VALUE, RETURN STATUS ;____________________________________________________________________________________________________ ; KY_STAT: ; IF WE ALREADY HAVE A KEY, RETURN WITH NZ LD A,(KY_BUF) OR A RET NZ ; SCAN FOR A KEYPRESS, A=0 NO DATA OR A=RAW BYTE CALL KY_SCAN ; SCAN KB ONCE OR A ; SET FLAGS RET Z ; NOTHING FOUND, GET OUT LD (KY_BUF),A ; SAVE RAW KEYCODE RET ; RETURN ; ;__KY_GET____________________________________________________________________________________________ ; ; GET A SINGLE KEY (WAIT FOR ONE IF NECESSARY) ;____________________________________________________________________________________________________ ; KY_GET: ; SEE IF WE ALREADY HAVE A KEY SAVED, GO TO DECODE IF SO LD A,(KY_BUF) OR A JR NZ,KY_DECODE ; NO KEY SAVED, WAIT FOR ONE KY_STATLOOP: CALL KY_STAT OR A JR Z,KY_STATLOOP ; DECODE THE RAW VALUE KY_DECODE: LD D,00H LD HL,KY_KEYMAP ; POINT TO BEGINNING OF TABLE KY_GET_LOOP: CP (HL) ; MATCH? JR Z,KY_GET_DONE ; FOUND, DONE INC HL INC D ; D + 1 JR NZ,KY_GET_LOOP ; NOT FOUND, LOOP UNTIL EOT KY_GET_DONE: ; CLEAR OUT KEY_BUF XOR A LD (KY_BUF),A ; RETURN THE INDEX POSITION WHERE THE RAW VALUE WAS FOUND LD A,D RET ; ;__KY_SCAN____________________________________________________________________________________________ ; ; SCAN KEYBOARD MATRIX FOR AN INPUT ;____________________________________________________________________________________________________ ; KY_SCAN: LD C,0000H LD A,41H | 30H ; SCAN COL ONE OUT (PPIC),A ; SEND TO COLUMN LINES CALL DELAY ; DEBOUNCE IN A,(PPIB) ; GET ROWS AND 7FH ;ignore PB7 for PPISD CP 00H ; ANYTHING PRESSED? JR NZ,KY_SCAN_FOUND ; YES, EXIT LD C,0040H LD A,42H | 30H ; SCAN COL TWO OUT (PPIC),A ; SEND TO COLUMN LINES CALL DELAY ; DEBOUNCE IN A,(PPIB) ; GET ROWS AND 7FH ;ignore PB7 for PPISD CP 00H ; ANYTHING PRESSED? JR NZ,KY_SCAN_FOUND ; YES, EXIT LD C,0080H LD A,44H | 30H ; SCAN COL THREE OUT (PPIC),A ; SEND TO COLUMN LINES CALL DELAY ; DEBOUNCE IN A,(PPIB) ; GET ROWS AND 7FH ;ignore PB7 for PPISD CP 00H ; ANYTHING PRESSED? JR NZ,KY_SCAN_FOUND ; YES, EXIT LD C,00C0H ; LD A,48H | 30H ; SCAN COL FOUR OUT (PPIC),A ; SEND TO COLUMN LINES CALL DELAY ; DEBOUNCE IN A,(PPIB) ; GET ROWS AND 7FH ;ignore PB7 for PPISD CP 00H ; ANYTHING PRESSED? JR NZ,KY_SCAN_FOUND ; YES, EXIT LD A,040H | 30H ; TURN OFF ALL COLUMNS OUT (PPIC),A ; SEND TO COLUMN LINES LD A,00H ; RETURN NULL RET ; EXIT KY_SCAN_FOUND: AND 3FH ; CLEAR TOP TWO BITS OR C ; ADD IN ROW BITS LD C,A ; STORE VALUE ; WAIT FOR KEY TO BE RELEASED LD A,4FH | 30H ; SCAN ALL COL LINES OUT (PPIC),A ; SEND TO COLUMN LINES CALL DELAY ; DEBOUNCE KY_CLEAR_LOOP: ; WAIT FOR KEY TO CLEAR IN A,(PPIB) ; GET ROWS AND 7FH ;ignore PB7 for PPISD CP 00H ; ANYTHING PRESSED? JR NZ,KY_CLEAR_LOOP ; YES, LOOP UNTIL KEY RELEASED LD A,040H | 30H ; TURN OFF ALL COLUMNS OUT (PPIC),A ; SEND TO COLUMN LINES LD A,C ; RESTORE VALUE RET ; ;_KEYMAP_TABLE_____________________________________________________________________________________________________________ ; KY_KEYMAP: ; 0 1 2 3 4 5 6 7 .DB 041H,002H,042H,082H,004H,044H,084H,008H ; 8 9 A B C D E F .DB 048H,088H,010H,050H,090H,020H,060H,0A0H ; FW BK CL EN DE EX GO BO .DB 001H,081H,0C1H,0C2H,0C4H,0C8H,0D0H,0E0H #ENDIF ; DSKY_KBD ; ;================================================================================================== ; DSKY HEX DISPLAY ;================================================================================================== ; DSKY_HEXOUT: LD B,DSKY_HEXBUFLEN LD HL,DSKY_BUF LD DE,DSKY_HEXBUF DSKY_HEXOUT1: LD A,(DE) ; FIRST NIBBLE SRL A SRL A SRL A SRL A LD (HL),A INC HL LD A,(DE) ; SECOND NIBBLE AND 0FH LD (HL),A INC HL INC DE ; NEXT BYTE DJNZ DSKY_HEXOUT1 LD A,82H ; SETUP PPI OUT (PPIX),A CALL DSKY_COFF LD A,0D0H ; 7218 -> (DATA COMING, HEXA DECODE) OUT (PPIA),A CALL DSKY_STROBEC LD HL,DSKY_BUF ; POINT TO START OF BUF LD B,DSKY_BUFLEN ; NUMBER OF DIGITS LD C,PPIA DSKY_HEXOUT2: OUTI JP Z,DSKY_STROBE ; DO FINAL STROBE AND RETURN CALL DSKY_STROBE JR DSKY_HEXOUT2 DSKY_STROBEC: LD A,80H | 30H JP DSKY_STROBE0 DSKY_STROBE: LD A,00H | 30H ; SET WRITE STROBE DSKY_STROBE0: OUT (PPIC),A ; OUT TO PORTC CALL DELAY ; DELAY DSKY_COFF LD A,40H | 30H ; SET CONTROL PORT OFF OUT (PPIC),A ; OUT TO PORTC CALL DELAY ; WAIT RET #ENDIF ; ;================================================================================================== ; DATA ;================================================================================================== ; STR_EMPTY .TEXT "$" ; HEXSTRBUF .TEXT "XX$" ; KY_BUF .DB 0 DSKY_BUF: .FILL 8,0 DSKY_BUFLEN .EQU $ - DSKY_BUF DSKY_HEXBUF .FILL 4,0 DSKY_HEXBUFLEN .EQU $ - DSKY_HEXBUF ; PANIC_SP .DW 0