PIC Microcontoller Math Method

32 bits by 16 via Tom Napier from FIG-Forth '79

"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

; - - - - - - - - - - - -