It is not really optimized for anything, but it could well be faster than TI's convOp1 (especially because this isn't a bcall so it doesn't have the huge overhead)
returns C on error (exponent < 0), Z on positive, NZ on negative
input: HL pointing to the signbyte of the FP
output: HL is the converted number (Signed!)
note: works with higher than 9999 as well. The time it takes depends on the number of digits in decimal. Does NOT work with negative values overflowing into the 7th bit of H (less than -32767), and of course it doesn't work with values which don't fit into a 16 bit number at all. For positive numbers it is actually unsigned, so it will look negative for numbers higher than 32767.
Code: Select all
ConvFP:
.module convFP
push hl
call {+}
pop de
ld a,(de)
bit 7,a
ret z
set 7,h
ret
+: inc hl
ld a,(hl)
sub $80
ret c ;return if exp is < 0
ld d,a ;store undivided exp
rra ;div by 2
ld c,a
ld a,0
rl a ;a is 0 (exp is even) or 1 (exp is odd)
inc c ;+1
ld b,0
add hl,bc
ex de,hl
ld b,h ;b is exp
ld hl,0
inc b
ld c,b
;hl = zero, de = pointer to first byte, a contains the 'parity' bit
or a
jr z,MSNibble
LSNibble:
ld a,(de)
and $0F
push de
ld d,0
ld e,a
push bc
ld a,c
sub b
inc a
ld b,a
call MultDE10pow
pop bc
add hl,de
pop de
djnz MSNibble
or a
ret
MSNibble:
ld a,(de)
and $F0
rra
rra
rra
rra
push de
ld d,0
ld e,a
push bc
ld a,c
sub b
inc a
ld b,a
call MultDE10pow
pop bc
add hl,de
pop de
dec de
djnz LSNibble
or a
ret
MultDE10pow:
djnz {+}
ret
+: push hl
ex de,hl
-: add hl,hl ;x2
push hl
add hl,hl ;x4
add hl,hl ;x8
pop de
add hl,de ;x10
djnz {-}
ex de,hl
pop hl
ret
.endmodule