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.
 
 
 
 
 
 

645 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_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
CALL HEXASCII
LD A,D
CALL COUT
LD A,E
CALL COUT
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 BINARY VALUE IN A TO ASCII HEX CHARACTERS IN DE
;
HEXASCII:
LD D,A
CALL HEXCONV
LD E,A
LD A,D
RLCA
RLCA
RLCA
RLCA
CALL HEXCONV
LD D,A
RET
;
; CONVERT LOW NIBBLE OF A TO ASCII HEX
;
HEXCONV:
AND 0FH ;LOW NIBBLE ONLY
ADD A,90H
DAA
ADC A,40H
DAA
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 ; AF
CALL PRTHEXWORD
LD DE,STR_BC
CALL WRITESTR
POP BC ; BC
CALL PRTHEXWORD
LD DE,STR_DE
CALL WRITESTR
POP BC ; DE
CALL PRTHEXWORD
LD DE,STR_HL
CALL WRITESTR
POP BC ; HL
CALL PRTHEXWORD
LD DE,STR_PC
CALL WRITESTR
POP BC ; PC
CALL PRTHEXWORD
LD DE,STR_SP
CALL WRITESTR
LD HL,0
ADD HL,SP ; SP
LD B,H
LD C,L
CALL PRTHEXWORD
RST 38
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_HBIOS
#DEFINE CIOMODE_NONDOS
LD E,A
LD A,DEFCON
LD C,A
LD B,BF_CIOOUT
RST 08
#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_HBIOS
#DEFINE CIOMODE_NONDOS
LD A,DEFCON
LD C,A
LD B,BF_CIOIN
RST 08
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_HBIOS
#DEFINE CIOMODE_NONDOS
LD B,BF_CIOIST
LD A,DEFCON
LD C,A
RST 08
#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 "<EMPTY>$"
;
KY_BUF .DB 0
DSKY_BUF: .FILL 8,0
DSKY_BUFLEN .EQU $ - DSKY_BUF
DSKY_HEXBUF .FILL 4,0
DSKY_HEXBUFLEN .EQU $ - DSKY_HEXBUF