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.
632 lines
12 KiB
632 lines
12 KiB
;
|
|
;==================================================================================================
|
|
; 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_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 (PIOX),A
|
|
LD A,30H ;disable /CS on PPISD card(s)
|
|
OUT (PIOC),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 (PIOC),A ; SEND TO COLUMN LINES
|
|
CALL DELAY ; DEBOUNCE
|
|
IN A,(PIOB) ; 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 (PIOC),A ; SEND TO COLUMN LINES
|
|
CALL DELAY ; DEBOUNCE
|
|
IN A,(PIOB) ; 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 (PIOC),A ; SEND TO COLUMN LINES
|
|
CALL DELAY ; DEBOUNCE
|
|
IN A,(PIOB) ; 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 (PIOC),A ; SEND TO COLUMN LINES
|
|
CALL DELAY ; DEBOUNCE
|
|
IN A,(PIOB) ; 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 (PIOC),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 (PIOC),A ; SEND TO COLUMN LINES
|
|
CALL DELAY ; DEBOUNCE
|
|
KY_CLEAR_LOOP: ; WAIT FOR KEY TO CLEAR
|
|
IN A,(PIOB) ; 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 (PIOC),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 (PIOX),A
|
|
CALL DSKY_COFF
|
|
LD A,0D0H ; 7218 -> (DATA COMING, HEXA DECODE)
|
|
OUT (PIOA),A
|
|
CALL DSKY_STROBEC
|
|
|
|
LD HL,DSKY_BUF ; POINT TO START OF BUF
|
|
LD B,DSKY_BUFLEN ; NUMBER OF DIGITS
|
|
LD C,PIOA
|
|
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 (PIOC),A ; OUT TO PORTC
|
|
CALL DELAY ; DELAY
|
|
DSKY_COFF
|
|
LD A,40H+30H ; SET CONTROL PORT OFF
|
|
OUT (PIOC),A ; OUT TO PORTC
|
|
CALL DELAY ; WAIT
|
|
RET
|
|
#ENDIF
|
|
;
|
|
;==================================================================================================
|
|
; DATA
|
|
;==================================================================================================
|
|
;
|
|
STR_EMPTY .TEXT "<EMPTY>$"
|
|
;
|
|
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
|
|
|