"I recently adapted the 32 bit division routine from a 1979 edition of 8080 FIG-Forth to run on a 16F876. As this uses only 16 loops it is inherently faster than Peter Hemsley's 32-loop version."
; This PIC division routine is adapted from that used in ; the 1979 version of FIG-Forth for the Intel 8080. ; It divides the 32-bit number in REG0-3 by the 16-bit number ; in TOSH/L. (REG0 is the least significant byte of the ; dividend.) The remainder ends up in REG2/3 and the ; quotient in REG1/0. TOSH/L is unchanged. ; It has tests for divide by zero and overflow errors. ; An overflow is flagged if the quotient requires more ; than 16 bits. The FAULT and OVER error handlers are ; system dependent. ; Most PIC assemblers accept abbreviations such as "SKNZ." ; If all else fails, here are their translations into ; formal PICese. ; SKNZ -> BTFSC STATUS,2 Skip if not zero ; SKNC -> BTFSC STATUS,0 Skip if no carry ; CLC -> BCF STATUS,0 Clear carry ; SKC -> BTFSS STATUS,0 Skip if carry ; This code runs on a 16F876. It should work on all but the ; simplest PIC chips, i.e. those which don't implement the ; "Increment/decrement and skip on zero instructions." DIV: MOVF TOSH,0 IORWF TOSL,0 SKNZ ; Test for zero divisor GOTO FAULT CALL SUBQ ; Carry set if overflow SKNC GOTO OVER ; Flag overflow MOVLW 16 MOVWF COUNT ; Set up loop count DIV1: CLC ; Preset quotient bit to 0 RLF REG0,1 RLF REG1,1 RLF REG2,1 RLF REG3,1 ; Left shift dividend SKNC GOTO DIV2 CALL SUBQ ; Test if subtraction OK SKC GOTO DIV3 DIV2: CALL SUBZ ; Do subtraction BSF REG0,0 ; Set quotient bit to 1 DIV3: DECFSZ COUNT,1 GOTO DIV1 RETURN ; - - - - - - - - - - - - ; Test subtraction. Parameters unchanged. ; Sets carry if (REG2/3 - TOSH/L) is positive. SUBQ: MOVF TOSL,0 SUBWF REG2,0 ; REG2 - TOSL -> W MOVF TOSH,0 SKC INCFSZ TOSH,0 ; Add carry SUBWF REG3,0 ; REG3 - TOSH -> W RETURN ; Carry set if result positive ; - - - - - - - - - - - - ; Real subtraction. (REG2/3 - TOSH/L) -> REG2/3 SUBZ: MOVF TOSL,0 SUBWF REG2,1 ; REG2 - TOSL -> REG2 MOVF TOSH,0 SKC INCFSZ TOSH,0 ; Add carry SUBWF REG3,1 ; REG3 - TOSH -> REG3 RETURN ; Carry set if result positive ; - - - - - - - - - - - -