SX Microcontroller Math Method

Divide 16 bit int by 8 bit int to 8 bit int and remainder

by Lou Zher

;-[ Div ]--------------------------------------------------------------
;	call	w/: Number in f_divhi:f_divlo
; Returns: Quotient in f_divlo, remainder in f_divhi. W preserved.
;          Carry set if error. Z if divide by zero, NZ if divide overflow.
; Notes:   Works by left shifted subtraction.
;          Size = 29, Speed(w/ call&ret) = 9 cycles if div by zero
;          Speed = 104 minimum, 142 maximum cycles
;          Not compatible with the CARRYX option.

Div
	or	W, #0		; w |= 0 (to test for div by zero)
	setb	C		; set carry in case of error
	snb	Z		; if zero
	ret			;   return (error C,Z)

	call	DivSkipHiShift
	call	DivCode
	call	DivCode
	call	DivCode
	call	DivCode

	call	DivCode
	call	DivCode
	call	DivCode
	call	DivCode

	rl	f_divlo		; C << lo << C

    ; If the first subtract didn't underflow, and the carry was shifted
    ; into the quotient, then it will be shifted back off the end by this
    ; last RLF. This will automatically raise carry to indicate an error.
    ; The divide will be accurate to quotients of 9-bits, but past that
    ; the quotient and remainder will be bogus and carry will be set.

	clrb	Z		; NZ (in case of overflow error)
	ret			; we are done!

DivCode
	rl	f_divlo		; C << lo << C
	rl	f_divhi		; C << hi << C
	sb	C		; if Carry
	jmp	DivSkipHiShift	;
	sub	f_divhi, W	;   hi-=w
	setb	C		;   ignore carry
	ret			;   done
                         	; endif
DivSkipHiShift
	sub	f_divhi, W	; hi-=w
	snb	C		; if carry set
	ret			;   done
	add	f_divhi, W	; hi+=w
	clrb	C		; clear carry
	ret			; done

Comments: