Searching \ for '[PIC]: Challenge: bcd to 16 bit binary (was: Maths' in subject line. ()
Help us get a faster server
FAQ page: techref.massmind.org/techref/microchip/math/index.htm?key=math
Search entire site for: 'Challenge: bcd to 16 bit binary (was: Maths'.

Exact match. Not showing close matches.
'[PIC]: Challenge: bcd to 16 bit binary (was: Maths'
2001\01\20@041051 by

#include <p16f84.inc>
cblock 0x0C
ones, tens, hund, thou, tenk
lo, hi
endc

mov     macro __x, __y
movlw __x
movwf __y
endm

mov 1, ones
mov 2, tens
mov 0, hund
mov 7, thou
mov 5, tenk
call bcd2bin16
nop
;*******************************************************************************
; Input: unpacked BCD in  tenk:thou:hund:tens:ones
;Output: 16 bit binary in hi:lo
;  Size: 35 instructions
;Timing: 2+3+10+6+10+1+10+3+7+1+10+3+10+1+10+2+2=91 instruction cycles
;
; Notes:
;1) uses two stack levels
;2) if input is higher than 65535 output is meaningless
;3) algorithm synopsis:
;
;» dec2bin([1 10 100 1000 1e4], 16)
;ans = ;0000000000000001
;0000000000001010
;0000000001100100
;0000001111101000
;0010011100010000
;
;Or coded in three levels ('+' represents +1, '-' represents -1):
;00000000 0000000+      ones
;00000000 0000+0+0      tens
;00000000 0++00+00      hund
;00000+00 00-0+000      thou
;00+0+00- 000+0000      tenk
;
;bin = (((((((((((hund<<1)+
;       hund-thou+tenk*256)<<1)+
;       tenk)<<1)+
;       tens+thou+tenk*256)<<1)+
;       hund+thou*256)<<1)+
;       tens)<<1)+
;       ones-tenk*256
;
;January 20, 2000 by Nikolai Golovchenko
;*******************************************************************************
bcd2bin16
movf hund, w
movwf lo
clrf hi
movf thou, w
subwf lo, f
skpc
decf hi, f
movf tenk, w
movf tens, w
movf tenk, w
movf thou, w
movf hund, w
movf thou, w
movf tens, w
movf ones, w
movf tenk, w
subwf hi, f
return

clrc
rlf lo, f
rlf hi, f
skpnc
incf hi, f
return
;*******************************************************************************

END
---- Original Message ----
From: Philip Martin <philip.martin1BTINTERNET.COM>
Sent: Friday, January 19, 2001 19:00:50
To: PICLISTMITVMA.MIT.EDU
Subj: [PIC]:Maths Problem

{Quote hidden}

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email listservmitvma.mit.edu with SET PICList DIGEST in the body

Ok..a challenge..from Nicolai...no chance of beating him
I guess :) ..but here goes 44'ish instructions ( not counting
setup of input ) executes in the same amount of cycles (i.e 44 ) :

;
***********************************************************************
; TEST_ASC_TO_BIN
; Routine to test ascii to 16 binary conversion
;
TEST_ASC_TO_BIN
GLOBAL  TEST_ASC_TO_BIN

MOVLW   D'1'
MOVWF   TenK,B
MOVLW   D'2'
MOVWF   Thou,B
MOVLW   D'0'
MOVWF   Hun,B
MOVLW   D'7'
MOVWF   Ten,B
MOVLW   D'5'
MOVWF   Ones,B
NOP

; these are not needed only used during dev. test
CLRF    Hi,B
CLRF    Lo,B

; bcd to binary conversion 16 bits ( i.e. max input is 65535 )
; uses nibble math there lowest nibble i calculated first
; the 'overflow' added to the calculation for the second nibble
; etc. upto the third nibble. Then the last additions for the
; fourth nibble which only is affected by ( apart from overflow
from lower nibbles )
; the input byte tenk.
; uses factorisation of the decimal weight contants as per this
table:
; 0000000000000001=    1     = 1
; 0000000000001010=    10    = 8+2
; 0000000001100100=    100   = 64+32+4
; 0000001111101000=    1000  = 512+256+128+64+32+8
; 0010011100010000=    10000 = 8192+1024+512+256+32
;
; calculation perform according to the following pseudo code:
; Separate each nibble:
;
; 0000 0000 0000 0001=    1     = 1
; 0000 0000 0000 1010=    10    = 8+2
; 0000 0000 0110 0100=    100   = 64+32+4
; 0000 0011 1110 1000=    1000  = 512+256+128+64+32+8
; 0010 0111 0001 0000=    10000 = 8192+1024+512+256+32
;
; Use the variable lo to calculate the result of the lowest
nibble:
; lo = Thou*8 + Hun*4 + Ten*(8+2) + Ones
; the result and overflow ( top nibble ) is saved and
calculation is perfromed on the second nibble
; by using the variable hi:
; hi = Tenk + Thou*(8+4+2) + Hun*(4+2)
; The low nibble from the result is added to the high nibble
from the
; previous calculation of lo:
; lo = hi<<4 + lo
; etc. etc..
;
MOVF    Thou,W  ; w = thou
ADDWF   Ten,W           ; w = thou + ten
MOVWF   Lo              ; lo = thou + ten
ADDWF   Lo,W            ; w = 2*(thou + ten)
ADDWF   Hun,W           ; w = 2*(thou + ten) + hun
MOVWF   Lo              ; lo = 2*(thou + ten) + hun
ADDWF   Lo,W            ; w = 2*(2*(thou + ten) + hun)
ADDWF   Ten,W           ; w = 2*(2*(thou + ten) + hun)+ten
MOVWF   Lo              ; lo = 2*(2*(thou + ten) + hun)+ten
ADDWF   Lo,W            ; w = 2*(2*(2*(thou + ten) + hun))
ADDWF   Ones,W  ; w = 2*(2*(2*(thou + ten) + hun)) + ones
MOVWF   Lo              ; lo = 2*(2*(2*(thou + ten) + hun)) +
ones = 8*Thou + 10*ten + 4*hun + ones
; low byte lowest nibble now fully calculated in lo
; now we calculate high nibble lo byte by using hi as temp
storage
MOVF    Thou,W  ; w =Thou
ADDWF   Thou,W  ; w = 2 * Thou
ADDWF   Hun,W           ; w = 2 * Thou + hun
ADDWF   Thou,W  ; w = 2 * Thou + hun + thou
MOVWF   Hi              ; hi = 2 * Thou + hun + thou
ADDWF   Hi,W            ; w = 2*(2 * Thou + hun + thou) = 6*thou
+ 2*hun
ADDWF   Thou,W  ; w = 6*thou + 2*hun + thou
ADDWF   Hun,W           ; w = 6*thou + 2*hun + thou + hun
MOVWF   Hi              ; hi = 6*thou + 2*hun + thou + hun
ADDWF   Hi,W            ; w = 2* ( 6*thou + 2*hun + thou + hun
)) = 14*thou + 6*hun
ADDWF   TenK,W  ; w =  14*thou + 6*hun + tenk
MOVWF   Hi              ; hi =  14*thou + 6*hun + tenk
; low byte high nibble fully calculated in hi
; now we need to add the low nibble to previous content in lo (
from low nibble calc. )
SWAPF   Hi,W            ; swap nibbles  ( lownibble->high )
ANDLW   0xF0            ; mask out high nibble
checked 4 rows down ! )
SWAPF   Hi,W            ; swap nibbles ( high nibble->low )
ANDLW   0x0F            ; mask out low nibble
BTFSC   STATUS,C        ; now we check the carry from the
ADDLW   0x01            ; in case of ripple carry we add one to
hi byte
MOVWF   Hi              ; Hi = overflow(lo)
; now we have overflow from lo byte caculation in Hi therefor we
cannot use the hi byte temporarily
; the following calculation must be performed in w only ( I just
whish an temp was available :)
; or one could trash the input....)
RLF     TenK,W  ; w = 2*tenk
ADDWF   TenK,W  ; w = 3*tenk
ADDWF   TenK,W  ; w = 4*tenk
ADDWF   TenK,W  ; w = 5*tenk
ADDWF   TenK,W  ; w = 6*tenk
ADDWF   TenK,W  ; w = 7*tenk
ADDWF   Thou,W  ; w = 7*tenk + thou
ADDWF   Thou,W  ; w = 7*tenk + 2*thou
ADDWF   Thou,W  ; w = 7*tenk + 3*thou
SWAPF   TenK,W  ; w = 32 * tenk
ADDWF   Hi,F            ; hi = 7*tenk + 3*thou + 32*Tenk
ADDWF   Hi,F            ; hi = 7*tenk + 3*thou + 32*Tenk +
32*Tenk = 7*tenk + 3*thou + 64*Tenk
NOP
RETURN

But I just happen to know that Nicolai has an 37 cycle waiting,
:( ...anyway..this beat's his 91 cycle version...

Have fun,

/Tony

Tony Kübek, Flintab AB
²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²
E-mail: tony.kubekflintab.com
²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

Very interesting, Tony! It also shows that there is a lot of
possible implementations, as many as Piclisters probably. So, a
pretty high chance of making an improvement!

It even gives me an idea to squeeze one more line out of the previous
36. :) But first the initial code:

;*******************************************************************************
; Input: unpacked BCD in  tenk:thou:hund:tens:ones
;Output: 16 bit binary in hi:lo
;  Size: 36 instructions
;Timing: 2+35+2=39 instruction cycles
;
; Notes:
;1) if input is higher than 65535 output is meaningless
;2) algorithm synopsis:
;
;> dec2bin([1 10 100 1000 1e4], 16)
;ans = ;0000000000000001
;0000000000001010
;0000000001100100
;0000001111101000
;0010011100010000
;
;Or coded in three levels ('+' represents +1, '-' represents -1):
;0000 0000 0000 000+ * ones +
;0000 0000 0000 +0+0 * tens +
;0000 0000 0++0 0+00 * hund +
;0000 0+00 00-0 +000 * thou +
;00+0 +00- 000+ 0000 * tenk
;
;bin = (((tens+thou+tenk*256)*2+
;       hund+hund*16+thou*256)*2+
;       tens+hund*16-thou*16+tenk*16*256)*2+
;       ones+tenk*16-tenk*256
;
;January 22, 2001 by Nikolai Golovchenko
;*******************************************************************************

dec2bin16
movf tens, w
movwf lo
movf tenk, w
movwf hi
rlf lo, f
rlf hi, f

swapf hund, w
movf thou, w
rlf lo, f
rlf hi, f

swapf hund, w
swapf tenk, w
skpnc
iorlw 0x01
swapf thou, w
subwf lo, f
skpc
decf hi, f
clrc
rlf lo, f
rlf hi, f

swapf tenk, w
movf tenk, w
skpnc
decf tenk, w
subwf hi, f
return
;*******************************************************************************

The first few lines:
dec2bin16
movf tens, w
movwf lo
movf tenk, w
movwf hi
rlf lo, f
rlf hi, f

can be replaced by these:
dec2bin16
movf tens, w
movwf lo
rlf tenk, w
movwf hi

Thanks Tony. Hmm, I wonder how much code a C compiler would
generate for the routine above?

If someone is really desperate on the free RAM and ROM space,
here is a a smaller version (but much longer to execute) which
operates on packed BCD:

#include <p16f84.inc>
cblock 0x0C
bcd0, bcd1, bcd2
lo, hi
counter
endc

mov     macro __x, __y
movlw __x
movwf __y
endm

mov 0x06, bcd2
mov 0x55, bcd1
mov 0x35, bcd0
call bcd2bin16
nop

;*******************************************************************************
;    Input: packed BCD in bcd2:bcd1:bcd0 (modified!)
;           bcd0 = tens:ones
;           bcd1 = thou:hund
;           bcd2 = 0:tenk
;   Output: 16 bit binary in hi:lo
;Temporary: counter
;     Size: 23 instructions
;   Timing: 2+2+16*(6+12+3)-1+2=341 instruction cycles
;
; Notes: The routine uses BCD division by 2. Each iteration
;        the LSB of BCD value (which coincides with correspondent
;        binary bit) is shifted to output and BCD value is
;        divided by 2. To do the division, BCD is shifted right
;        once and corrected. Correction: if MSB of a nibble is set,
;        subtract 3 from it.
;
;January 22, 2001 by Nikolai Golovchenko
;*******************************************************************************
bcd2bin16
movlw 16
movwf counter
bcd2bin16loop
clrc
rrf bcd2, f
rrf bcd1, f
rrf bcd0, f
rrf hi, f
rrf lo, f

clrw
btfsc bcd0, 3
iorlw 0x03
btfsc bcd0, 7
iorlw 0x30
subwf bcd0, f
clrw
btfsc bcd1, 3
iorlw 0x03
btfsc bcd1, 7
iorlw 0x30
subwf bcd1, f
decfsz counter, f
goto bcd2bin16loop
return
;*******************************************************************************

END

Best regards,
Nikolai

---- Original Message ----
From: Kübek Tony <tony.kubekFLINTAB.COM>
Sent: Tuesday, January 23, 2001 17:04:34
To: PICLISTMITVMA.MIT.EDU
Subj: [PIC]: Challenge: bcd to 16 bit binary (was: Maths Problem)

{Quote hidden}

--
http://www.piclist.com hint: The PICList is archived three different
ways.  See http://www.piclist.com/#archives for details.

More... (looser matching)
- Last day of these posts
- In 2001 , 2002 only
- Today
- New search...