View Single Post
Old 8th Jun 2019, 11:44 pm   #13
julie_m
Dekatron
 
Join Date: May 2008
Location: Derby, UK.
Posts: 7,735
Default Re: Fun with 6502 Assembler

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.
__________________
If I have seen further than others, it is because I was standing on a pile of failed experiments.
julie_m is offline