hex to decimal conversion
Posted: Wed Jan 28, 2004 7:26 am
Garth [et-all],
I've been using something similar to your HTD routine for years but starting LSbit first, had I thought to do it MSbit first it would have been faster and shorter. What I have now is similar and as short and fast as I can easily make it. If anyone can think of a faster and/or shorter version please post it.
First saving is to convert the lowest four bits directly thus ..
.. this saves cycles, as we don't have four trips through the add loop, and bytes as the table is shorter. Next re-arrange the table so that all the bytes of the same magnitude are together. This saves two DEX instructions and looks like this ..
.. note that the values are all -1 as the next change is to remove the CLC from before the adds. As the carry is always set it is allowed for here.
The only other change is to hold the highest result byte in the Y register while evaluating, this saves a couple of cycles per loop.
The result is ..
That's all I can think of, it runs somewhere between 250 cycles for all bits = 0, and 650 cycles for all 1s.
Cheers,
Lee.
I've been using something similar to your HTD routine for years but starting LSbit first, had I thought to do it MSbit first it would have been faster and shorter. What I have now is similar and as short and fast as I can easily make it. If anyone can think of a faster and/or shorter version please post it.
First saving is to convert the lowest four bits directly thus ..
Code: Select all
LDA HTD_IN ; get the value
AND #$0F ; mask low 4 bits
SED ; set decimal mode
CLC ; clear carry for decimal adjust
ADC #$00 ; decimal adjust low nibble
STA HTD_OUT ; save value
Code: Select all
TABLE2:
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01,$03 ; 990000s
TABLE1:
.byte $00,$00,$00,$01,$02,$05,$10,$20,$40,$81,$63,$27 ; 9900s
TABLE0:
.byte $15,$31,$63,$27,$55,$11,$23,$47,$95,$91,$83,$67 ; 99s
The only other change is to hold the highest result byte in the Y register while evaluating, this saves a couple of cycles per loop.
The result is ..
Code: Select all
HTD_IN:
.ds 2 ; Low byte first, as is normal for 6502.
HTD_OUT:
.ds 3 ; Low byte first, highest byte last.
; hex to decimal conversion table
; table entries are 2^n-1 as the carry is always set before the add
TABLE2:
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01,$03 ; 990000s
TABLE1:
.byte $00,$00,$00,$01,$02,$05,$10,$20,$40,$81,$63,$27 ; 9900s
TABLE0:
.byte $15,$31,$63,$27,$55,$11,$23,$47,$95,$91,$83,$67 ; 99s
HTD:
LDA HTD_IN ; get the low byte
AND #$0F ; mask low 4 bits
SED ; set decimal mode
CLC ; clear carry for decimal adjust
ADC #$00 ; decimal adjust low nibble
STA HTD_OUT ; set 99s
LDY #$00 ; clear 990000s
STY HTD_OUT+1 ; clear 9900s
LDX #$0B ; set bit count/table index
; (# of highest bit - 4)
HTD1:
ASL HTD_IN ; shift number low byte
ROL HTD_IN+1 ; shift number high byte
BCC HTD2 ; branch if bit = zero
LDA HTD_OUT ; get 99s
ADC TABLE0,X ; add table 99s byte
STA HTD_OUT ; save 99s
LDA HTD_OUT+1 ; get 9900s
ADC TABLE1,X ; add table 9900s byte
STA HTD_OUT+1 ; save 9900s
TYA ; copy 990000s
ADC TABLE2,X ; add table 990000s byte
TAY ; save 990000s
HTD2:
DEX ; decrement bit count ..
BPL HTD1 ; loop if not all done yet
CLD ; clear decimal mode
STY HTD_OUT+2 ; save 990000s
RTS
Cheers,
Lee.