Skip to content

Wednesday Double Dabbling

April 29, 2015

I had a little epiphany based on a friend’s work on the double dabble code.

He had improved the baseline code a lot with a bunch of tricks but I had lost lock on how the code worked. One major thing he had done was to make the number of passes of the inner loop variable, increasing as the number of bcd digits developed. Looking at my own code, it occurred to me that there was a fairly easy way for me to do the same thing. A conceptually minor change to my code gave me the variable length inner loop and obviated the need to initialize the buffer. It’s not quite as quick as his code but I understand it and i may be able to apply some of his other innovations. I’m quite pleased. For the record, it takes about 900 instructions to convert 0x3039 to “12345” vs 2200 for my current itoa and 750 for the best previous effort. Also, as a result of understanding the code better i can probably dispense with the C wrapper code.

_dubdab16v:
;experimental binay-ascii conversion using the double-dabble algorithm for 16 bits
;thanks to Charles Richmond for the suggestion and code
;15-04-29 upgraded to variable digit processing
;interger is passed in r12
;buffer pointer is passed in r13
;a pointer to the 1st non-zero byte in the buffer is passed back in r15
;r8-11 are used as temps
;r8 is the working pointer
;r15.0 is bit count(16) and the return value register
;r10.0 is the count of digits as the bcd number is developed
;r9.0 is digit count for the current pass
alu2i r8,r13,6,adi,adci	;point to the terminator position
ldi 0	;source a 0
str r8	;terminate the buffer
dec r8	;back to units position
str r8	;initialize bcd number to 0
ldi 1	;vdc initialize the bcd digit count at 1
plo r10 ;vdc
;at this point the bcd return buffer has been initialized and the digit count is 1
ldi 16	;bit count
plo r15
;now i'm going to spin off any leading 0's in the binary number
$$cktop:
ghi r12		;get the top bit of the number
shl		;check for a 1
bdf $$bitloop	;move on if we have one
shl2 r12	;shift the input number
dec r15		;reduce the number of times to shift
glo r15
bnz $$cktop	;
inc r15		;our whole number was 0 but force at least one pass
$$bitloop:
glo r10	;digit count vdc
plo r9
$$dcklp:
ldn r8 	;pick up a digit
smi 5	;see if it's greater than 4
bnf $$dnoadd ;if not, bypass add
adi 0x08	;add the 5 black and 3 more
str r8	;put it back
$$dnoadd:
inc r8
dec r9	;decrement digit count
glo r9
bnz $$dcklp ;and back for next digit

shl2 r12 ;shift the input number

glo r10	;load the digit count again vdc
plo r9
;r8 is now just past the units location and ready to walk back
$$dshlp:
dec r8	;walk back from 0's position
ldn r8	;get the digit back
shlc	;continue the shift
phi r15 ;save it for the carry test
ani 0x0f ;clear the 10 bit
str r8	;put the digit back
ghi r15	;now test for carry
smi 0x10 ; this will make df 1 if the 10 bit is set
dec r9	;decrement the digit count
glo r9
bnz $$dshlp ;back for more if needed
;we are now out of digit positions but if DF is 1 we need another digit vdc
bnf $$nextbit	;no need to increase digits vdc
inc r10	;increase BCD digit count vdc
dec r8	;back up pointer to new digit position vdc
ldi 1	;source a 1 vdc
str r8	;initialize the position vdc

$$nextbit:
dec r15
glo r15
bnz $$bitloop

cpy2 r15,r8	;save the starting location of the digits to return
glo r10		;digit count again vdc
plo r9
$$upnxt:
ldn r8		;get digit
ori 0x30	;make ascii
str r8		;put it back
inc r8		;next digit
dec r9		;counter
glo r9
bnz $$upnxt	;upgrade all spots

cretn		;return with pointer to 1st digit in r15
Advertisements

From → Uncategorized

Leave a Comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: