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.