As part of a program which involves converting decimal numbers to binary, I wrote a dedicated subroutine to multiply by ten, in 16-bit unsigned arithmetic. Ten is known as a sparse number, because its binary representation contains only a few ones (just 2 i,n fact: 1010.) This means we can do our multiplication as follows:
- Make a copy
- Double the original number
- Double it again (now we have n * 4)
- Add the copy (giving n * 5)
- Double it one last time.
This will be quicker than a "general-purpose" multiplying routine, which would have to check every bit in the multiplier.
Code:
.times10
LDX #0
JSR cpydn
JSR dbldn
JSR dbldn
LDX #0
CLC
JSR add_dn
.dbldn
ASL decnum
ROL decnum+1
RTS
.cpydn
JSR cpydn_1
.cpydn_1
LDA decnum,X
STA dncpy,X
INX
RTS
.add_dn
JSR add_dn1
.add_dn1
LDA decnum,X
ADC dncpy,X
STA decnum,X
INX
RTS
\TEMPORARY WORKSPACES
.decnum EQUW 0
.dncpy EQUW 0
decnum and decnum + 1 are used to store the decimal number which gets multiplied by 10 in situ, and dncpy and dncpy + 1 are used to store a copy of the original value during the multiplication. X gets stomped on, and Z=0 on exit (so a BNE instruction following a JSR here will always branch). The code itself isn't relocatable, as it contains absolute jumps.