;Author: ©JPANHALT ;Based on Reichborn-Kjennerud (http://www.piclist.com/techref/method/math/muldiv.htm ) description. list p=16f1829 ; list directive to define processor #include ; processor specific variable definitions errorlevel -302,-305 RADIX DEC cblock 0x20 T3 T2 T1 T0 B3 B2 B1 B0 result0 result1 result2 result3 bitcount endc org 0x0000 goto Start Start ByteScreen Dividend ;Determine highest byte populated to reduce multiplications and trial ;subtractions of each operand movlw T3 movwf FSR1 _TByte ; movlw T0+1 ;eliminate first 4 instructions, if test -- ; subwf FSR1,w ;for zero not needed ; btfsc STATUS,0 ; ; bra fault ;dividend=0 moviw FSR1++ btfsc STATUS,2 bra _TByte ;byte is empty test next byte decf FSR1,f ;return FSR to highest non-zero byte bra Divisor ;repeat process for divisor Divisor movlw B1 movwf FSR0 _Byte ; movlw B0+1 ;eliminate first 4 instructions, if test -- ; subwf FSR0,w ;for zero not needed ; btfsc STATUS,0 ; ; bra fault ;counter reached 0 before non-zero byte detected moviw FSR0++ btfsc STATUS,2 bra _Byte ;byte is empty test next byte decf FSR0,f ;return to FSR for highest non-zero byte bra PreCalc ;divisor byte number in WREG PreCalc movf FSR1,w addlw 4 ; movwf FSR1 ;FSR1 address = address needed for FSR0 subwf FSR0,w ;calculate byte shift needed (used later) btfss STATUS,0 bra Fault ;Divisor>Dividend call Table movwf bitcount ;bitcount = 8*(byte shift) movf INDF0,w ;INDFO is highest divisor byte >0 clrf INDF0 movwi FSR1++ movlw B0 ; B0+1? ;test for when FSR0 = B0 subwf FSR0,w btfsc STATUS,0 bra Exit ;FSR0 = B0, so branch out incf FSR0,f ;FSR0 = B1, shift B0 same movf INDF0,w clrf INDF0 movwf INDF1 decf FSR0,f ;restore FSR0 Exit decf FSR1,w movwf FSR0 ;reset FSR0 addfsr FSR1,-5 ;restore FSR1 bra SetBit Table brw dt 0,8,16,24 SetBit movf B0,w subwf T0,w movf B1,w subwfb T1,w movf B2,w subwfb T2,w movf B3,w subwfb T3,w btfss STATUS,0 bra SetCount ;B=T rotate once more or T>B keep rotating ;Additional code can eliminate doubling for B=T ;but does not save time. bra RBL RBL ;rotate byte left until B>T incf bitcount,f lslf B0,f rlf B1,f rlf B2,f rlf B3,f bra SetBit SetCount incf bitcount,f bra Cycle Fault ;dividend or divisor is zero nop Cycle movf B0,w subwf T0,w movf B1,w subwfb T1,w movf B2,w subwfb T2,w movf B3,w subwfb T3,w btfss STATUS,0 ;subtrahend too big divide by 2 and repeat goto Result movf B0,w ;subtrahend OK, repeat subtraction w/saves in f subwf T0,f movf B1,w subwfb T1,f movf B2,w subwfb T2,f movf B3,w subwfb T3,f ;carry will be set correctly Result rlf result0,f rlf result1,f rlf result2,f rlf result3,f lsrf B3,f ;divides divisor by 2 and subtracts again rrf B2,f rrf B1,f rrf B0,f decfsz bitcount goto Cycle bra Finish Finish goto Start ;answer in result<3,2,1,0> end