• entries
17
28
• views
32,214

# Hex to Decimal (0-255)

1,556 views

This morning I decided to extend my Hex to BCD routines so that I can cover a whole byte.

This is what I came up with :

```;---------------------------------------
lda    hexValue              ;3  @3     (0 - 255)
ldx    #0                    ;2  @5     hundreds digit = 0
;divide by 10, and times result by 6
sta    temp                  ;3  @8
lsr                          ;2  @10
ror                          ;2  @17
lsr                          ;2  @19
lsr                          ;2  @21
ror                          ;2  @26
ror                          ;2  @31
lsr                          ;2  @33
and    #\$7C                  ;2  @35
sta    temp2                 ;3  @38
lsr                          ;2  @40
adc    temp2                 ;3  @43    extra weight = 0,6,12,18,24,30,36,42,48,54,60,66,72,78,84,
;                         90,96,102,108,114,120,126,132,138,144, or 150
;add extra weight to original sum...
;look for overflow, if so minus 100, plus extra weight (100/10)*6, total = 160
bcc    .checkForCorrection   ;2³ @48/49
sbc    #160                  ;2  @50
inx                          ;2  @52    hundreds digit = 1
;repeat check for final 100 correction
.checkForCorrection:
cmp    #160                  ;2  @54
bcc    .storeDecimal         ;2³ @56/57
sbc    #160                  ;2  @58
inx                          ;2  @60    hundreds digit = 1 or 2
.storeDecimal:
stx    decHundreds           ;3  @63
tax                          ;2  @65    at this point A = \$00 to \$99, you can store it in one byte,
lsr                          ;2  @67    or break it out into two digits, as I did here.
lsr                          ;2  @69
lsr                          ;2  @71
lsr                          ;2  @73
sta    decTens               ;3  @76
txa                          ;2  @78
and    #\$0F                  ;2  @80
sta    decOnes               ;3  @83    83 cycles worse case (77 cycles best case), 56 bytes total.
;          This routine can be evened out to be 83 cycles all the time
;          by adding 2 branches, costing 4 bytes.
;---------------------------------------```

I broke the result into three bytes (100's value, 10's value, and 1's value). There are always some more optimizations that could be done, but that's up to user.

One optimization would be to use BCS instead of BCC for the branch at cycle 56/57. You could just branch backwards and eliminate the second SBC #160 and INX instructions. That would save 3 bytes, but at a cost of 5 more cycles it seems more like a loss then a gain.

Another optimization would be to convert the decimal values into pointer values before they get stored. The code snippet below assumes that your digit graphics are eight bytes high in the rom, and that the zero graphic begins at the start of a page with the rest of the graphics following in order.

```;repeat check for final 100 correction
.checkForCorrection:
cmp    #160                  ;2  @54
bcc    .storeDecimal         ;2³ @56/57
sbc    #160                  ;2  @58
inx                          ;2  @60    hundreds digit = 1 or 2
.storeDecimal:
;     stx    decHundreds           ;3  @63   Skip storing the digits as is.
;     tax                          ;2  @65
;     lsr                          ;2  @67
;     lsr                          ;2  @69
;     lsr                          ;2  @71
;     lsr                          ;2  @73
;     sta    decTens               ;3  @76
;     txa                          ;2  @78
;     and    #\$0F                  ;2  @80
;     sta    decOnes               ;3  @83
tay                          ;2  @62    For just 10 more cycles and 6 bytes,
and    #\$F0                  ;2  @64    you can convert the low pointers at the same time...
lsr                          ;2  @66
sta    tensPtrLo             ;3  @69
tya                          ;2  @71
and    #\$0F                  ;2  @73
asl                          ;2  @75
asl                          ;2  @77
asl                          ;2  @79
sta    onesPtrLo             ;3  @82
txa                          ;2  @84
asl                          ;2  @86
asl                          ;2  @88
asl                          ;2  @90
sta    hunsPtrLo             ;3  @93
```

I left that out of the original routine to keep it more general purpose, and perhaps more useful for the NES programmers. If a NES programmer was using ASCII then they could do an optimization by OR'ing their values with \$30 before they store them, as ASCII zero begins at \$30.

## 1 Comment

This routine has been surpassed by another one in my blog here.

×   Pasted as rich text.   Paste as plain text instead

Only 75 emoji are allowed.