I've written a long to ascii integer converter for an arcade remake (Pacman on Commodore Amiga).
Actually, you can use DIVU up to (1<<16*10)-1
as the result of 655359/10 still fits in 16 bits (and is 65535)
To go further, just divide a copy of your long number by 10000
, it cannot be > 655359 either as 6553590000 > 1<<32
so the result will fit in 16 bits. Write the result as ASCII.
Then proceed with the remainder of the division you just obtained, and do the same for the lower part.
So if num = (1<<32)-1
(which is max unsigned value aka $ffffffff
), dividing num
by 10000
is 429496
which is < 65536*10-1
so can be processed. And the remainder can also be processed the same way.
Note: actually it works up only to 655360000-1 ($2710.0000-1) because that's the last number where the stage one divu #10000 will result in <65536, for higher numbers, a third division stage by 1 million must be performed.
Here's some code I adapted from my game & tested. Zero padding seems a bit off but you probably don't need it.
; main test code
main:
move.l #$12345678,d0
lea outbuf(pc),a1
move.w #0,d1
bsr write_decimal_number
; A1 contains "305419896"
move.l #2000001,d0
lea outbuf(pc),a1
move.w #0,d1
bsr write_decimal_number
; A1 contains "2000001"
rts
outbuf
ds.b 100,0
; the conversion routine
; < A1: buffer to write into
; < D0: 32 bit unsigned number
; < D1: number of padding zeroes
write_decimal_number:
movem.l A0-A1/D2-d5,-(a7)
move.l d1,d3 ; quickly adapted, old code needed D0 and D1 for coordinates
move.l d0,d2
cmp.w #18,d3
bcs.b .padok
move.w #18,d3
.padok
cmp.l #655360,d2
bcs.b .one
sub.l #4,d3
move.w d0,d5
; first write high part
divu #10000,d2
swap d2
moveq.l #0,d4
move.w d2,d4
clr.w d2
swap d2
bsr .write_num
subq.w #1,a1 ; cancel last zero
move.l d4,d2
moveq #4,d3 ; pad to 4
.one
bsr .write_num
clr.b (a1)
movem.l (a7)+,A0-A1/D2-d5
rts
.write_num
lea .buf+20(pc),a0
tst.w d2
beq.b .zero
.loop
divu #10,d2
swap d2
add.b #'0',d2
subq #1,d3
move.b d2,-(a0)
clr.w d2
swap d2
tst.w d2 ; probably unnecessary, swap sets Z flag already
beq.b .write
bra.b .loop
.zero
subq #1,d3
move.b #'0',-(a0)
.write
tst.b d3
beq.b .w
bmi.b .w
subq #1,d3
.pad
move.b #'0',-(a0)
dbf d3,.pad
.w
move.b (a0)+,(a1)+
bne.b .w
rts
.buf
ds.b 20
dc.b 0
even