@ -486,13 +486,15 @@ STR_TSTPT .TEXT "\r\n+++ TSTPT: $"
;STR_PC .DB " PC=$"
;STR_SP .DB " SP=$"
;
; INDIRECT JUMP TO ADDRESS IN HL
; INDIRECT JUMP TO ADDRESS IN HL,IX, OR IY
;
; MOSTLY USEFUL TO PERFORM AN INDIRECT CALL LIKE:
; LD HL,xxxx
; CALL JPHL
;
JPHL: JP ( HL )
JPIX: JP ( IX )
JPIY: JP ( IY )
;
; ADD HL,A
;
@ -829,54 +831,155 @@ BITLOC1:
DJNZ BITLOC1 ; LOOP AS NEEDED
RET ; DONE
;
; PRINT VALUE OF A IN DECIMAL WITH LEADING ZERO SUPPRESSION
; DECIMAL NUMBER PRINTING ROUTINES
;
PRTDECB:
PUSH HL
PUSH AF
LD L , A
LD H , 0
CALL PRTDEC
POP AF
POP HL
PRTDEC8: ; PRINT VALUE OF A REGISTER IN DECIMAL
PUSH IY
LD IY , B2D8
CALL PRTDECSTR
POP IY
RET
;
; PRINT VALUE OF HL IN DECIMAL WITH LEADING ZERO SUPPRESSION
PRTDEC16: ; PRINT VALUE OF HL REGISGTER IN DECIMAL
PUSH IY
LD IY , B2D16
CALL PRTDECSTR
POP IY
RET
;
PRTDEC:
PRTDEC32: ; PRINT VALUE OF DE:HL REGISTERS IN DECIMAL
PUSH IY
LD IY , B2D32
CALL PRTDECSTR
POP IY
RET
;
PRTDECSTR:
PUSH AF
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
PUSH IX
CALL JPIY ; CALL (IY)
EX DE , HL
LD A , '$'
LD ( B2DEND ), A
CALL WRITESTR
POP IX
POP HL
POP DE
POP BC
POP AF
RET
PRTDEC1:
LD A , '0' - 1
PRTDEC2:
INC A
ADD HL , BC
JR C , PRTDEC2
;
; Combined routine for conversion of different sized binary numbers into
; directly printable ASCII(Z)-string
; Input value in registers, number size and -related to that- registers to fill
; is selected by calling the correct entry:
;
; entry inputregister(s) decimal value 0 to:
; B2D8 A 255 (3 digits)
; B2D16 HL 65535 5 "
; B2D24 E:HL 16777215 8 "
; B2D32 DE:HL 4294967295 10 "
; B2D48 BC:DE:HL 281474976710655 15 "
; B2D64 IX:BC:DE:HL 18446744073709551615 20 "
;
; The resulting string is placed into a small buffer attached to this routine,
; this buffer needs no initialization and can be modified as desired.
; The number is aligned to the right, and leading 0's are replaced with spaces.
; On exit HL points to the first digit, (B)C = number of decimals
; This way any re-alignment / postprocessing is made easy.
; Changes: AF,BC,DE,HL,IX
; P.S. some examples below
;
; by Alwin Henseler
;
B2D8: LD H , 0
LD L , A
B2D16: LD E , 0
B2D24: LD D , 0
B2D32: LD BC , 0
B2D48: LD IX , 0 ; zero all non-used bits
B2D64: LD ( B2DINV ), HL
LD ( B2DINV + 2 ), DE
LD ( B2DINV + 4 ), BC
LD ( B2DINV + 6 ), IX ; place full 64-bit input value in buffer
LD HL , B2DBUF
LD DE , B2DBUF + 1
LD ( HL ), ' '
B2DFILC .EQU $ - 1 ; address of fill-character
LD BC , 18
LDIR ; fill 1st 19 bytes of buffer with spaces
LD ( B2DEND - 1 ), BC ;set BCD value to "0" & place terminating 0
LD E , 1 ; no. of bytes in BCD value
LD HL , B2DINV + 8 ; (address MSB input)+1
LD BC , $ 0909
XOR A
B2DSKP0: DEC B
JR Z , B2DSIZ ; all 0: continue with postprocessing
DEC HL
OR ( HL ) ; find first byte <>0
JR Z , B2DSKP0
B2DFND1: DEC C
RLA
JR NC , B2DFND1 ; determine no. of most significant 1-bit
RRA
LD D , A ; byte from binary input value
B2DLUS2: PUSH HL
PUSH BC
B2DLUS1: LD HL , B2DEND - 1 ; address LSB of BCD value
LD B , E ; current length of BCD value in bytes
RL D ; highest bit from input value -> carry
B2DLUS0: LD A ,( HL )
ADC A , A
DAA
LD ( HL ), A ; double 1 BCD byte from intermediate result
DEC HL
DJNZ B2DLUS0 ; and go on to double entire BCD value (+carry!)
JR NC , B2DNXT
INC E ; carry at MSB -> BCD value grew 1 byte larger
LD ( HL ), 1 ; initialize new MSB of BCD value
B2DNXT: DEC C
JR NZ , B2DLUS1 ; repeat for remaining bits from 1 input byte
POP BC ; no. of remaining bytes in input value
LD C , 8 ; reset bit-counter
POP HL ; pointer to byte from input value
DEC HL
LD D ,( HL ) ; get next group of 8 bits
DJNZ B2DLUS2 ; and repeat until last byte from input value
B2DSIZ: LD HL , B2DEND ; address of terminating 0
LD C , E ; size of BCD value in bytes
OR A
SBC HL , BC ; calculate address of MSB BCD
LD D , H
LD E , L
SBC HL , BC
CP E
JR Z , PRTDEC3
LD E , 0
CALL COUT
PRTDEC3:
EX DE , HL ; HL=address BCD value, DE=start of decimal value
LD B , C ; no. of bytes BCD
SLA C ; no. of bytes decimal (possibly 1 too high)
LD A , '0'
RLD ; shift bits 4-7 of (HL) into bit 0-3 of A
CP '0' ; (HL) was > 9h?
JR NZ , B2DEXPH ; if yes, start with recording high digit
DEC C ; correct number of decimals
INC DE ; correct start address
JR B2DEXPL ; continue with converting low digit
B2DEXP: RLD ; shift high digit (HL) into low digit of A
B2DEXPH: LD ( DE ), A ; record resulting ASCII-code
INC DE
B2DEXPL: RLD
LD ( DE ), A
INC DE
INC HL ; next BCD-byte
DJNZ B2DEXP ; and go on to convert each BCD-byte into 2 ASCII
SBC HL , BC ; return with HL pointing to 1st decimal
RET
;
B2DINV .FILL 8 ; space for 64-bit input value (LSB first)
B2DBUF .FILL 20 ; space for 20 decimal digits
B2DEND .DB 1 ; space for terminating 0
;
; SHIFT HL:DE BY B BITS
;
SRL32:
@ -897,6 +1000,57 @@ SLA32:
DJNZ SLA32
RET
;
; PRINT VALUE OF A IN DECIMAL WITH LEADING ZERO SUPPRESSION
; BELOW ARE NOW OBSOLETE AND MAPPED TO NEW ROUTINES
;
PRTDECB .EQU PRTDEC8
;;;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 .EQU PRTDEC16
;;;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
;
; LOAD OR STORE DE:HL
;
LD32: