http://z80-heaven.wikidot.com/math#toc32
Code: Select all
; based on code from here http://map.grauw.nl/sources/external/z80bits.html#5.1
; and the 2's complement without using a spare register was from here
; https://wikiti.brandonw.net/index.php?title=Z80_Routines:Other:DispA#Decimal_Signed_Version
; Input: HL = number to convert, DE = location of ASCII string
; Output: ASCII string at (DE)
signedhltodecimal:
bit 7, h
jr z, hltodecimal
ld a, '-'
ld (de), a
; negate hl
xor a
sub l
ld l, a
ld a, 0 ; Note that XOR A or SUB A would disturb CF
sbc a, h
ld h, a
inc de
hltodecimal:
ld bc, -10000
call .num1
ld bc, -1000
call .num1
ld bc, -100
call .num1
ld c, -10
call .num1
ld c, b
.num1
ld a, '0' - 1
.num2
inc a
add hl, bc
jr c, .num2
sbc hl, bc
ld (de), a
inc de
ret
Code: Select all
ld de, char_buff
call signedhltodecimal
Code: Select all
char_buff BLOCK 8
Code: Select all
char_buff
db 0, 0, 0, 0, 0, 0, 0, 0
EDIT2: I don't think I've ever used a multiply routine and certainly never a divide one
Here's how I skip leading zeros
Code: Select all
ld de, char_buff
call signedhltodecimal
.print
xor a
ld (de), a; null terminate the string
ld hl, char_buff
call skipleadingzeros
.doprintrest
ld a, (hl)
or a
ret z
call puts
Code: Select all
; HL points to string of digits
skipleadingzeros:
ld c, 0 ; set to 1 if starts with '-'
ld a, (hl)
cp '-'
jr z, .isnegative
.nextdigit
cp '0'
jr nz, .doret
inc hl
ld a, (hl)
or a
jr nz, .nextdigit
dec hl
.doret
dec c
ret nz
dec hl
ld a, '-'
ld (hl), a
ret
.isnegative
inc c
inc hl
ld a, (hl)
jr .nextdigit