PIC Microcontoller 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.)
;

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

 ; Multiply the ones 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	W, ascii2	;

; Or use this one that saves a cycle:

	mov	W, <<tens
	and	W, #$1e	;w=2*tens
	mov	temp, W
	rl	temp	;temp=4*tens
	rl	temp	;temp=8*tens
	add	W, ones
;*** WARNING: ADDLW was expanded in three instructions! Check if previous instruction is a skip instruction. 
;   addlw -'0'      ;convert from ASCII to decimal
	mov	Hack, W
	mov	W, #-'0'	;convert from ASCII to decimal
	add	W, Hack
                   ;w=tens*2 + ones
	add	W, temp	;w=10*tens + ones

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

	mov	W, tens	;*1
	add	tens, W	;*2
	rl	tens	;*4
	add	tens, W	;*5
	mov	W, <<tens	;*10
	add	W, ones
;*** WARNING: ADDLW was expanded in three instructions! Check if previous instruction is a skip instruction. 
;        addlw   low     -11.*'0'
	mov	Hack, W
	mov	W, #low     -11.*'0'
	add	W, Hack

;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 ;)