SX Microcontroller Radix Math Method

ASCII decimal to Binary

Scott Dattalo and Dmitry Kiryashov

;ascii1 and ascii2 are the tens and ones digit of a number we wish
;to convert to binary
;
; In C:
;
;  binary = (ascii1 & 0xf) * 10 + (ascii2 & 0xf);
;
; (I'd be interested to see how a compiler would generate the asm for this.)
;

        ;Clear the upper nibble of the one's digit
        mov     W, #$0f
        and     ascii2, W

        ;Multiply the tens digit by 10.
        mov     W, <<ascii1     ;2*tens
                                ;Note that the carry is also cleared because
                                ;ascii1 is an ASCII number between 0x30-0x39
        and     W, #$1e         ;Clear upper nibble of tens digit
                                ;In addition, we clear the shifted in carry
        mov     ascii1, W       ;W = ascii1 = 2*original ascii1
        rl      ascii1          ;ascii1 = 4*original ascii1
        rl      ascii1          ;ascii1 = 8*original ascii1
        add     W, ascii1       ;W = 2*original ascii1 + 8 *original ascii1
                                ;  = 10*original ascii1
        ;add the one's digit
        add     W, ascii2       ;

; Or use this one that preserves input:

        mov     W, <<tens
        and     W, #$1e         ;w=2*tens
        mov     temp, W
        rl      temp            ;temp=4*tens
        rl      temp            ;temp=8*tens
        add     temp, W         ;temp=8*tens+2*tens=10*tens
        mov     W, #-'0'        ;convert one's digit from ASCII to decimal
        add     W, ones         ;w=ones
        add     W, temp         ;w=ones+10*tens

;Dmitry Kiryashov [zews at AHA.RU] says:
;Destructive way to save one more clock ;-)

        mov     W, tens         ;*1     w=0x30..0x39
        add     tens, W         ;*2     tens=0x60..0x72
        rl      tens            ;*4     tens=0xC0..0xE4
        add     tens, W         ;*5     tens=0xF0..0x1ED

        mov     W, #(-11*'0') & $FF     ;low byte of -48*11
        add     W, ones
        add     W, tens         ;add two times tens=5*original_tens
        add     W, tens

;Why so ? tens is '0' + x , ones is '0' + y , where x and y are in range
;of 0..9 So finally '0'*(10+1)=48.*11.=528.=0x210 . it is constant so we
;can subtract it back from result. Here we gone ;)