MATH_STATUS equ H'020' BIT_COUNTER equ H'021' ; für Division DIVIDEND_0 equ H'024' DIVIDEND_1 equ H'025' DIVIDEND_2 equ H'026' DIVIDEND_3 equ H'027' DIVISOR_0 equ H'028' DIVISOR_1 equ H'029' DIVISOR_2 equ H'02A' DIVISOR_3 equ H'02B' QUOTIENT_0 equ H'02C' QUOTIENT_1 equ H'02D' ;******************************************************************************* ; 16-Bit Division, DIVIDEND_0/1 / DIVISOR_0/1 = QUOTIENT_0/1 ; DIVIDEND_2/3 und DIVISOR_2/3 werden genutzt aber müssen nicht auf ; 0 gesetzt werden, das macht die Routine selbst ; bei Division durch 0 ist TEMP_STATUS.C gesetzt ; bei Quotient = 0 ist TEMP_STATUS.Z gesetzt ; Rest in DIVIDEND_0/1 division_16_bit ; Test auf Division durch 0 bsf MATH_STATUS,C ; schon mal C setzen falls DIVISOR 0 ist movf DIVISOR_0,f ; wenn 0, ist jetzt Z-Flag gesetzt btfsc STATUS,Z ; wenn nicht 0, dann überspringen movf DIVISOR_1,f ; wenn 0, ist jetzt Z-Flag gesetzt btfsc STATUS,Z ; wenn nicht 0, dann überspringen goto div_16_end ; prepare movlw 0x10 ; 16 Bit movwf BIT_COUNTER clrf MATH_STATUS clrf DIVIDEND_2 clrf DIVIDEND_3 movf DIVISOR_0,w ; divisor_0/1 nach divisor_2/3 movwf DIVISOR_2 movf DIVISOR_1,w movwf DIVISOR_3 clrf DIVISOR_0 ; divisor 0/1 löschen clrf DIVISOR_1 clrf QUOTIENT_0 clrf QUOTIENT_1 div_16_loop bcf STATUS,C ; oberstes Bit mit 0 füllen rrcf DIVISOR_3,f ; Divisor 1 Bit nach rechts schieben rrcf DIVISOR_2,f rrcf DIVISOR_1,f rrcf DIVISOR_0,f rlcf QUOTIENT_0,f ; Quotient 1 Stelle nach links schieben rlcf QUOTIENT_1,f ; Vergleich, ob Divisor größer ist movf DIVISOR_3,f ; nur Test auf 0 notwendig, oberer Teil des Dividend immer 0 btfss STATUS,Z ; überspringe, wenn oberer Teil des Divisor 0 war goto div_16_loop_end ; Divisor ist auf jeden Fall größer movf DIVISOR_2,f ; nur Test auf 0 notwendig, oberer Teil des Dividend immer 0 btfss STATUS,Z ; überspringe, wenn oberer Teil des Divisor 0 war goto div_16_loop_end ; Divisor ist auf jeden Fall größer movf DIVISOR_1,w subwf DIVIDEND_1,w btfss STATUS,C ; überspringe, wenn oberer Teil des Divisor nicht grö0er war goto div_16_loop_end ; Divisor ist größer btfss STATUS,Z ; überspringe, wenn oberer Teil des Divisor gleich war goto div_16_loop_kl ; Divisor ist kleiner movf DIVISOR_0,w subwf DIVIDEND_0,w btfss STATUS,C ; überspringe, wenn unterer Teil des Divisor nicht grö0er war goto div_16_loop_end ; Divisor ist größer div_16_loop_kl ; Quotient berechnen bsf QUOTIENT_0,0 ; in letzte Stelle des Quotient eine 1 schreiben ; neuen Dividend berechnen movf DIVISOR_0,w ; subtrahend_l nach w subwf DIVIDEND_0,f ; subtrahend_l von minuend_l abziehen movf DIVISOR_1,w ; subtrahend_h nach w btfss STATUS,C ; überspringe falls C gesetzt (wenn kein Übertrag!) incfsz DIVISOR_1,w ; addiere 1 falls C nicht gesetzt subwf DIVIDEND_1,f ; subtrahend_h von minuend_h abziehen div_16_loop_end ; nächste Schleife decfsz BIT_COUNTER,f ; nächste Stelle oder Ende goto div_16_loop ; eventuell Z setzen bsf MATH_STATUS,Z ; erst mal setzen, so rum ist bei ODER-Verknüpfung besser movf QUOTIENT_0,f ; Test des L-Teils auf 0 btfss STATUS,Z ; wenn 0, dann wird löschen des Hilfs-Z-Flag übersp. bcf MATH_STATUS,Z movf QUOTIENT_1,f ; Test des L-Teils auf 0 btfss STATUS,Z ; wenn 0, dann wird löschen des Hilfs-Z-Flag übersp. bcf MATH_STATUS,Z div_16_end return