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=3D39 instruction cycles ; ; Notes: ;1) if input is higher than 65535 output is meaningless ;2) algorithm synopsis: ; ;> dec2bin([1 10 100 1000 1e4], 16) ;ans =3D=20 ;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 =3D (((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 addwf thou, w movwf lo movf tenk, w movwf hi rlf lo, f rlf hi, f swapf hund, w addwf hund, w addwf lo, f movf thou, w addwf hi, f rlf lo, f rlf hi, f swapf hund, w addwf tens, w addwf lo, f swapf tenk, w skpnc iorlw 0x01 addwf hi, f swapf thou, w subwf lo, f skpc decf hi, f clrc rlf lo, f rlf hi, f swapf tenk, w addwf ones, w addwf lo, f movf tenk, w skpnc decf tenk, w subwf hi, f return ;************************************************************************= ******* The first few lines: dec2bin16 movf tens, w addwf thou, w movwf lo movf tenk, w movwf hi rlf lo, f rlf hi, f can be replaced by these: dec2bin16 movf tens, w addwf thou, w movwf lo addwf lo, f 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 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 =3D tens:ones ; bcd1 =3D thou:hund ; bcd2 =3D 0:tenk ; Output: 16 bit binary in hi:lo ;Temporary: counter ; Size: 23 instructions ; Timing: 2+2+16*(6+12+3)-1+2=3D341 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 =20 decfsz counter, f goto bcd2bin16loop return ;************************************************************************= ******* END =20 Best regards, Nikolai ---- Original Message ---- From: K=FCbek Tony Sent: Tuesday, January 23, 2001 17:04:34 To: PICLIST@MITVMA.MIT.EDU Subj: [PIC]: Challenge: bcd to 16 bit binary (was: Maths Problem) > 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 > ; load test value > 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=3D 1 =3D 1 > ; 0000000000001010=3D 10 =3D 8+2 > ; 0000000001100100=3D 100 =3D 64+32+4 > ; 0000001111101000=3D 1000 =3D 512+256+128+64+32+8 > ; 0010011100010000=3D 10000 =3D 8192+1024+512+256+32 > ; > ; calculation perform according to the following pseudo code: > ; Separate each nibble: > ; > ; 0000 0000 0000 0001=3D 1 =3D 1 > ; 0000 0000 0000 1010=3D 10 =3D 8+2 > ; 0000 0000 0110 0100=3D 100 =3D 64+32+4 > ; 0000 0011 1110 1000=3D 1000 =3D 512+256+128+64+32+8 > ; 0010 0111 0001 0000=3D 10000 =3D 8192+1024+512+256+32 > ; =20 > ; Use the variable lo to calculate the result of the lowest > nibble: > ; lo =3D 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 =3D 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 =3D hi<<4 + lo > ; etc. etc.. > ; > MOVF Thou,W ; w =3D thou > ADDWF Ten,W ; w =3D thou + ten > MOVWF Lo ; lo =3D thou + ten > ADDWF Lo,W ; w =3D 2*(thou + ten) > ADDWF Hun,W ; w =3D 2*(thou + ten) + hun > MOVWF Lo ; lo =3D 2*(thou + ten) + hun > ADDWF Lo,W ; w =3D 2*(2*(thou + ten) + hun) > ADDWF Ten,W ; w =3D 2*(2*(thou + ten) + hun)+ten > MOVWF Lo ; lo =3D 2*(2*(thou + ten) + hun)+ten > ADDWF Lo,W ; w =3D 2*(2*(2*(thou + ten) + hun)) > ADDWF Ones,W ; w =3D 2*(2*(2*(thou + ten) + hun)) + ones > MOVWF Lo ; lo =3D 2*(2*(2*(thou + ten) + hun)) + > ones =3D 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 =3DThou=20 > ADDWF Thou,W ; w =3D 2 * Thou > ADDWF Hun,W ; w =3D 2 * Thou + hun > ADDWF Thou,W ; w =3D 2 * Thou + hun + thou > MOVWF Hi ; hi =3D 2 * Thou + hun + thou > ADDWF Hi,W ; w =3D 2*(2 * Thou + hun + thou) =3D 6= *thou > + 2*hun > ADDWF Thou,W ; w =3D 6*thou + 2*hun + thou > ADDWF Hun,W ; w =3D 6*thou + 2*hun + thou + hun > MOVWF Hi ; hi =3D 6*thou + 2*hun + thou + hun > ADDWF Hi,W ; w =3D 2* ( 6*thou + 2*hun + thou + hu= n > )) =3D 14*thou + 6*hun > ADDWF TenK,W ; w =3D 14*thou + 6*hun + tenk > MOVWF Hi ; hi =3D 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 > ADDWF Lo,F ; add result to lo byte ( note carry > checked 4 rows down ! ) > SWAPF Hi,W ; swap nibbles ( high nibble->low )=20 > ANDLW 0x0F ; mask out low nibble > BTFSC STATUS,C ; now we check the carry from the > addition of the lo byte=20 > ADDLW 0x01 ; in case of ripple carry we add one to > hi byte > MOVWF Hi ; Hi =3D overflow(lo) > ; now we have overflow from lo byte caculation in Hi therefor w= e > cannot use the hi byte temporarily > ; the following calculation must be performed in w only ( I jus= t > whish an temp was available :)=20 > ; or one could trash the input....)=20 > RLF TenK,W ; w =3D 2*tenk > ADDWF TenK,W ; w =3D 3*tenk=20 > ADDWF TenK,W ; w =3D 4*tenk=20 > ADDWF TenK,W ; w =3D 5*tenk=20 > ADDWF TenK,W ; w =3D 6*tenk=20 > ADDWF TenK,W ; w =3D 7*tenk=20 > ADDWF Thou,W ; w =3D 7*tenk + thou > ADDWF Thou,W ; w =3D 7*tenk + 2*thou > ADDWF Thou,W ; w =3D 7*tenk + 3*thou > ADDWF Hi,F ; add it to the overflow from lo = =20 > SWAPF TenK,W ; w =3D 32 * tenk > ADDWF Hi,F ; hi =3D 7*tenk + 3*thou + 32*Tenk > ADDWF Hi,F ; hi =3D 7*tenk + 3*thou + 32*Tenk + > 32*Tenk =3D 7*tenk + 3*thou + 64*Tenk=20 > 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=FCbek, Flintab AB =20 > =B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2= =B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2= =B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2 > E-mail: tony.kubek@flintab.com > =B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2= =B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2= =B2=B2=B2=B2=B2=B2=B2=B2=B2=B2=B2 > -- > 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 -- http://www.piclist.com hint: The PICList is archived three different ways. See http://www.piclist.com/#archives for details.