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.
 
 
 
 
 
 

444 lines
6.3 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
NEWLINE2:
CALL NEWLINE
NEWLINE:
CALL PC_CR
CALL PC_LF
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
;
;
;
TSTPT:
PUSH DE
LD DE,STR_TSTPT
CALL WRITESTR
POP DE
JR REGDMP ; DUMP REGISTERS AND RETURN
;
; PANIC: TRY TO DUMP MACHINE STATE
;
PANIC:
PUSH DE
LD DE,STR_PANIC
CALL WRITESTR
POP DE
CALL _REGDMP ; DUMP REGISTERS
CALL CONTINUE ; CHECK W/ USER
RET
;
;
;
REGDMP:
CALL _REGDMP
RET
;
_REGDMP:
EX (SP),HL ; RET ADR TO HL, SAVE HL ON TOS
LD (REGDMP_RET),HL ; SAVE RETURN ADDRESS
POP HL ; RESTORE HL AND BURN STACK ENTRY
EX (SP),HL ; PC TO HL, SAVE HL ON TOS
LD (REGDMP_PC),HL ; SAVE PC VALUE
EX (SP),HL ; BACK THE WAY IT WAS
LD (REGDMP_SP),SP ; SAVE STACK POINTER
;LD (RD_STKSAV),SP ; SAVE ORIGINAL STACK POINTER
;LD SP,RD_STACK ; SWITCH TO PRIVATE STACK
PUSH AF
PUSH BC
PUSH DE
PUSH HL
PUSH AF
LD A,'@'
CALL COUT
POP AF
PUSH BC
LD BC,(REGDMP_PC)
CALL PRTHEXWORD ; PC
POP BC
CALL PC_LBKT
PUSH BC
PUSH AF
POP BC
CALL PRTHEXWORD ; AF
POP BC
CALL PC_COLON
CALL PRTHEXWORD ; BC
CALL PC_COLON
PUSH DE
POP BC
CALL PRTHEXWORD ; DE
CALL PC_COLON
PUSH HL
POP BC
CALL PRTHEXWORD ; HL
CALL PC_COLON
LD BC,(REGDMP_SP)
CALL PRTHEXWORD ; SP
CALL PC_RBKT
CALL PC_SPACE
POP HL
POP DE
POP BC
POP AF
;LD SP,(RD_STKSAV) ; BACK TO ORIGINAL STACK FRAME
JP $FFFF ; RETURN, $FFFF IS DYNAMICALLY UPDATED
REGDMP_RET .EQU $-2 ; RETURN ADDRESS GOES HERE
;
REGDMP_PC .DW 0
REGDMP_SP .DW 0
;
;RD_STKSAV .DW 0
; .FILL $FF,16*2 ; 16 LEVEL PRIVATE STACK
;RD_STACK .EQU $
;
;
;
CONTINUE:
PUSH AF
PUSH DE
LD DE,STR_CONTINUE
CALL WRITESTR
POP DE
CONTINUE1:
CALL CIN
CP 'Y'
JR Z,CONTINUE3
CP 'y'
JR Z,CONTINUE3
CP 'N'
JR Z,CONTINUE2
CP 'n'
JR Z,CONTINUE2
JR CONTINUE1
CONTINUE2:
HALT
CONTINUE3:
POP AF
RET
;
;==================================================================================================
; CONSOLE CHARACTER I/O HELPER ROUTINES (REGISTERS PRESERVED)
;==================================================================================================
;
; OUTPUT CHARACTER FROM A
COUT:
PUSH AF
PUSH BC
PUSH DE
PUSH HL
LD C,A
CALL CONOUT
POP HL
POP DE
POP BC
POP AF
RET
;
;
;
CIN:
PUSH BC
PUSH DE
PUSH HL
CALL CONIN
LD A,E
POP HL
POP DE
POP BC
RET
;
STR_PANIC .DB "\r\n\r\n>>> PANIC: $"
STR_TSTPT .TEXT "\r\n+++ TSTPT: $"
STR_CONTINUE .TEXT " Continue? (Y/N): $"
;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)
;
; ADD HL,A
; ADC HL,A
;
; A REGISTER IS DESTROYED!
;
ADCHLA:
ADC A,L
JR ADDHLA1
ADDHLA:
ADD A,L
ADDHLA1:
LD L,A
RET NC
INC H
RET
;
; MULTIPLY 8-BIT VALUES
; IN: MULTIPLY H BY E
; OUT: HL = RESULT, E = 0, B = 0
;
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
;
; FILL MEMORY AT HL WITH VALUE A, LENGTH IN BC, ALL REGS USED
; LENGTH *MUST* BE GREATER THAN 1 FOR PROPER OPERATION!!!
;
FILL:
LD D,H ; SET DE TO HL
LD E,L ; SO DESTINATION EQUALS SOURCE
LD (HL),A ; FILL THE FIRST BYTE WITH DESIRED VALUE
INC DE ; INCREMENT DESTINATION
DEC BC ; DECREMENT THE COUNT
LDIR ; DO THE REST
RET ; RETURN
;
; PRINT VALUE OF A IN DECIMAL WITH LEADING ZERO SUPPRESSION
;
PRTDECB:
PUSH HL
PUSH AF
LD L,A
LD H,0
CALL PRTDEC
POP AF
POP HL
RET
;
; PRINT VALUE OF HL IN DECIMAL WITH LEADING ZERO SUPPRESSION
;
PRTDEC:
PUSH BC
PUSH DE
PUSH HL
LD E,'0'
LD BC,-10000
CALL PRTDEC1
LD BC,-1000
CALL PRTDEC1
LD BC,-100
CALL PRTDEC1
LD C,-10
CALL PRTDEC1
LD E,0
LD C,-1
CALL PRTDEC1
POP HL
POP DE
POP BC
RET
PRTDEC1:
LD A,'0' - 1
PRTDEC2:
INC A
ADD HL,BC
JR C,PRTDEC2
SBC HL,BC
CP E
JR Z,PRTDEC3
LD E,0
CALL COUT
PRTDEC3:
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:
OR A
RET Z ; EMPTY BUFFER
;
LD B,A
PRTHEXBUF1:
CALL PC_SPACE
LD A,(DE)
CALL PRTHEXBYTE
INC DE
DJNZ PRTHEXBUF1
RET
;
; LEFT SHIFT DE:HL BY B BITS (B > 0)
;
RL32:
OR A ; CLEAR CARRY
RL L
RL H
RL E
RL D
DJNZ RL32
RET