I finally think I understand. The now correctly (right?) commented routine is at http://techref.massmind.org/microchip/math/radix/b2bu-16b5d.htm --- James Newton mailto:jamesnewton@geocities.com 1-619-652-0593 http://techref.massmind.org NEW! FINALLY A REAL NAME! Members can add private/public comments/pages ($0 TANSTAAFL web hosting) -----Original Message----- From: pic microcontroller discussion list [mailto:PICLIST@MITVMA.MIT.EDU]On Behalf Of Nikolai Golovchenko Sent: Friday, February 11, 2000 20:54 To: PICLIST@MITVMA.MIT.EDU Subject: Re: PIC Math FAQ page James, you miss a bit (literally). This routine works exactly as Scott deducted: b_0 = a_0 - 4*(a_3 + a_2 + a_1) - 20 b_1 = 6*a_2 + 2*a_1 + 2 - 140 = 6*a_2 + 2*a_1 - 138 b_2 = a_3 + 2*a_2 + 14 - 60 = a_3 + 2*a_2 - 46 b_3 = 4*a_3 + 6 - 70 = 4*a_3 - 64 b_4 = 0 + 7 = 7 First, let's make clear how to do some math operations: 1) Negation - invert all bits and add one: comf reg, f incf reg, f 2) Multiply by two signed byte (arithmetical shift left)- bcf _C ;clear carry rlf reg, f 3) Divide by two signed byte (arithmetical shift right)- rlf reg, w ;sign extension rrf reg, f I added some comments to this routine (;; marked, too many commenters ) ;------------------------------------------------------------------- ; ; Binary-to-BCD. Written by John Payson. ; ; Enter with 16-bit binary number in NumH:NumL. ; Exits with BCD equivalent in TenK:Thou:Hund:Tens:Ones. ; org $0010 ;Start of user files for 16c84 NumH: ds 1 NumL: ds 1 TenK: ds 1 Thou: ds 1 Hund: ds 1 Tens: ds 1 Ones: ds 1 Convert: ; Takes number in NumH:NumL ; Returns decimal in ; TenK:Thou:Hund:Tens:Ones swapf NumH,w andlw $0F ;*** PERSONALLY, I'D REPLACE THESE 2 addlw $F0 ;*** LINES WITH "IORLW 11110000B" -AW movwf Thou addwf Thou,f addlw $E2 movwf Hund addlw $32 movwf Ones ;;At this point ;;Thou = 2 (A3 - 16) = 2 * A3 - 32 ;;Hund = A3 - 16 - 30 = A3 - 46 ;;Ones = A3 - 16 - 30 + 50 = A3 + 4 movf NumH,w andlw $0F addwf Hund,f addwf Hund,f addwf Ones,f addlw $E9 movwf Tens addwf Tens,f addwf Tens,f ;;Now ;;Hund = Hund + 2 * A2 = A3 + 2 * A2 - 46 ;;Ones = Ones + A2 = A3 + A2 + 4 ;;Tens = (A2 - 23) * 3 = 3 * A2 - 69 swapf NumL,w andlw $0F addwf Tens,f addwf Ones,f ;;Tens = Tens + A1 = 3 * A2 + A1 - 69 ;;Ones = Ones + A1 = A3 + A2 + A1 + 4 ;;C = 0 rlf Tens,f ;;Tens = Tens * 2 = 6 * A2 + 2 * A1 - 138 ;; ~~~~~~~~~~~~~~~~~~~~~ ;;Also bit C is set, because Tens register was negative. rlf Ones,f ;;Ones = 2 * Ones + 1 = 2 * (A3 + A2 + A1 + 4) + 1 = 2 * (A3 + A2 + ;;A1) + 9 ;;C = 0 comf Ones,f ;;comf can be regarded like: ;; comf Ones, f ;; incf Ones, f ;; decf Ones, f ;;First two instructions make up negation. So, ;;Ones = - Ones - 1 = - 2 * (A3 + A2 + A1) - 9 - 1 = - 2 * (A3 + A2 + ;;A1) - 10 rlf Ones,f ;;Ones = 2 * Ones = - 4 * (A3 + A2 + A1) - 20 movf NumL,w andlw $0F addwf Ones,f rlf Thou,f ;;Ones = Ones + A0 = A0 - 4 * (A3 + A2 + A1) - 20 ;; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ;;C = 0 ;;Thou = 2 * Thou = 4 * A3 - 64 ;; ~~~~~~~~~~~ movlw $07 movwf TenK ;;TenK = 7 ;;~~~~~~~~ ; At this point, the original number is ; equal to TenK*10000+Thou*1000+Hund*100+Tens*10+Ones ; if those entities are regarded as two's compliment ; binary. To be precise, all of them are negative ; except TenK. Now the number needs to be normal- ; ized, but this can all be done with simple byte ; arithmetic. movlw $0A ; Ten Lb1: addwf Ones,f decf Tens,f btfss 3,0 goto Lb1 Lb2: addwf Tens,f decf Hund,f btfss 3,0 goto Lb2 Lb3: addwf Hund,f decf Thou,f btfss 3,0 goto Lb3 Lb4: addwf Thou,f decf TenK,f btfss 3,0 goto Lb4 retlw 0 Best regards, Nikolai