please dont rip this site

Scenix Sx_arith.src

;  to test different modules, set the corresponding test to 1 and reset all others to 0

addsub_test	equ	0
bcd_test	equ	0
mul88_test	equ	0
mul1616_test	equ	0
div1616_test	equ	1
;		mathpak for SX
;
IF mul88_test=1
		device	pins28,pages4,banks8,turbo,oschs,optionx,stackx
ELSE
		device	pins28,pages4,banks8,turbo,oschs,optionx,carryx,stackx
ENDIF

		; use oschs only for debugging
		; frequency does not matter much here except when incorporating these routines
		; into a real program


		;32 bit addition
		org 	8
IF addsub_test=1 OR bcd_test=1
		;8,9,a,b=1000,1001,1010,1011=10xx
operand1	ds	4
		;c,d,e,f=1100,1101,1110,1111=11xx
operand2	ds	4
bin_number	ds	4
bcd_number	ds	5
count		equ	operand1	; share storage in other routines
temp		equ	operand1+1	; share 1 more

ENDIF
IF mul88_test=1
		; for 8 bit x 8 bit multiplication
count		ds	1
multiplier	ds	1
upper_prdt	ds	1
ENDIF

IF mul1616_test=1
		; for 16 bit x 16 bit multiplication
md16		ds	2
mr16		ds	2
upper_prdt	ds	2
count		ds	1
ENDIF

IF div1616_test=1
		; for 16 bit / 16 bit division
a		ds	2
b		ds	2
rlo		ds	1
rhi		ds	1
d		ds	2
count		ds	1
ENDIF

load32		MACRO	8		; macro used to load the operands
		mov	operand1,#\1
		mov	operand1+1,#\2
		mov	operand1+2,#\3
		mov	operand1+3,#\4
		mov	operand2,#\5
		mov	operand2+1,#\6
		mov	operand2+2,#\7
		mov	operand2+3,#\8
		ENDM

		reset	start			; goto 'start' on reset

		org	0
start		;test procedures

IF addsub_test=1
		; $7fffffff+$01ffffff
		load32 $ff,$ff,$ff,$01,$ff,$ff,$ff,$7f
		call	add32			;result=$81fffffe

		; $8ffffffe-$01ffffff
		call	sub32			;result=$7fffffff, carry=1-> result is positive

		; $01ffffff-$7fffffff
		load32 $ff,$ff,$ff,$7f,$ff,$ff,$ff,$01
		call	sub32			;result=$82000000, carry=0-> result is negative and in
						;2's complement form, =-$7e000000

ENDIF
IF bcd_test=1
		load32 $78,$56,$89,$67,$78,$56,$89,$67
		call	badd32			;result=35791356 carry=1 (overflow)

		load32 $12,$34,$56,$78,$78,$56,$34,$21
		call	badd32			;result=99909090 

		; 87654321-90123456= -2469135 
		load32 $56,$34,$12,$90,$21,$43,$65,$87
		call	bsub32			; result= 2469135, no carry means result is negative

		; 90123456-87654321
		load32 $21,$43,$65,$87,$56,$34,$12,$90
		call	bsub32			;result=02469135 carry=1 (no borrow), result is positive


		mov	bin_number,#$ff		; largest 32 bit number
		mov	bin_number+1,#$ff	; $ffffffff
		mov	bin_number+2,#$ff	; let's see how big the number will be
		mov	bin_number+3,#$ff	; in decimal
		call	bindec			; result = 4,294,967,295
		call	decbin			; result = $ffffffff
ENDIF
IF mul88_test=1
		mov	multiplier,#$ff		; largest number
		mov	W,#$ff			; largest 8 bit no. as multiplicand
		call	mul88			; result=$fe01

		; test fast 8 x 8 multiplication
		mov	multiplier,#$ff		; largest number
		mov	W,#$ff			; largest 8 bit no. as multiplicand
		call	fmul88			; result=$fe01
ENDIF

IF mul1616_test=1
		mov	md16,#$ff		; largest 16 bit number
		mov	md16+1,#$ff
		mov	mr16,#$ff		; multiplied with largest 16 bit number
		mov	mr16+1,#$ff
		call	mul1616			; result = fffe0001
	
		mov	md16,#$ff		; largest 16 bit number
		mov	md16+1,#$01
		mov	mr16,#$ff		; multiplied with largest 16 bit number
		mov	mr16+1,#$7f
		call	mul1616			; result = 00ff7e01

		mov	md16,#$ff		; largest 16 bit number
		mov	md16+1,#$ff
		mov	mr16,#$ff		; multiplied with largest 16 bit number
		mov	mr16+1,#$ff
		call	fmul1616		; result = fffe0001
	
		mov	md16,#$ff		; largest 16 bit number
		mov	md16+1,#$01
		mov	mr16,#$ff		; multiplied with largest 16 bit number
		mov	mr16+1,#$7f
		call	fmul1616		; result = 00ff7e01



		
ENDIF

IF div1616_test=1
		mov	a+1,#$01
		mov	a,#$ff			; 01ff
		mov	b+1,#$7f		
		mov	b,#$ff			; 7fff
		call	div1616			; 7fff/01ff=$40 remainder $3f
	
		mov	a+1,#$00
		mov	a,#$ff			; 00ff
		mov	b+1,#$ff		
		mov	b,#$ff			; ffff
		call	div1616			; ffff/00ff=$101 remainder 0

		mov	a+1,#$01
		mov	a,#$ff			; 01ff
		mov	b+1,#$7f		
		mov	b,#$ff			; 7fff
		call	fdiv1616		; 7fff/01ff=$40 remainder $3f
	
		mov	a+1,#$00
		mov	a,#$ff			; 00ff
		mov	b+1,#$ff		
		mov	b,#$ff			; ffff
		call	fdiv1616		; ffff/00ff=$101 remainder 0

ENDIF


loop		jmp	loop
IF addsub_test=1
		;32 bit addition
		;entry = 32 bit operand1 and 32 bit operand2 in binary form
		;exit  = operand2 become operand2+operand1, carry flag=1 for overflow from MSB
add32		clc				; clear carry, prepare for addition
		mov	fsr,#operand1		; points to operand 1 first
add_more	clrb	fsr.2			; toggle back to operand 1
		mov	w,ind			; get contents into the work register
		setb	fsr.2			; points to operand 2
		add	ind,w			; operand2=operand2+operand1
		inc	fsr			; next byte
		sb	fsr.4			; done? (fsr=$10?)
		jmp	add_more		; not yet
		ret				; done, return to calling routine

		;32 bit subtraction
		;entry = 32 bit operand1 and 32 bit operand2 in binary form
		;exit  = operand2 become operand2-operand1, carry flag=0 for underflow from MSB
sub32		stc				; set carry, prepare for subtraction
		mov	fsr,#operand1		; points to operand 1 first
sub_more	clrb	fsr.2			; toggle back to operand 1
		mov	w,ind			; get contents into the work register
		setb	fsr.2			; points to operand 2
		sub	ind,w			; operand2=operand2-operand1
		inc	fsr			; next byte
		sb	fsr.4			; done? (fsr=$10?)
		jmp	sub_more		; not yet
		ret				; done, return to calling routine
ENDIF
IF bcd_test=1
		;8 BCD digit addition
		;entry = 8 BCD digit operand1 and 8 BCD digit operand2 in BCD form
		;exit  = operand2 become operand2+operand1, carry flag=1 for overflow from MSB
		;	 operand1 will be DESTROYED
badd32		clc				; clear carry, prepare for addition
		mov	fsr,#operand1		; points to operand 1 first
badd_more
		mov	w,ind			; get contents into the working register
		clr	ind
		setb	fsr.2			; points to operand 2
		add	ind,w			; operand2=operand2+operand1
		clrb	fsr.2
		rl	ind			; store carry bit which will be altered by decimal
						; adjustment (adding 6)
		setb	fsr.2			; points back to operand 2
		snb	status.1		; digit carry set? if so, need decimal correction
		jmp	dcor
		
		jnb	ind.3,ck_overflow	; if 0xxx, check MSD
		jb	ind.2,dcor		; if 11xx, it's >9, thus need correction
		jnb	ind.1,ck_overflow	; 100x, number is 8 or 9, no decimal correction

		; here if 101x, decimal adjust	
dcor		clc				; clear effect of previous carry
		add	ind,#6			; decimal correction by adding 6
	
		; finish dealing with least significant digit, proceed to MSD
ck_overflow 	clrb	fsr.2			; points to operand1
		jb	ind.0,dcor_msd		; stored carry=1, decimal correct
		; test if MSD > 9
		setb	fsr.2			; points back to operand2
		jnb	ind.7,next_badd		; if 0xxx, it's <9, add next byte
		jb	ind.6,dcor_msd		; if 11xx, it's >9, thus need correction
		jnb	ind.5,next_badd		; if 100x, it's <9
		
		;here if 101x, decimal adjust
dcor_msd	clc				; clear effect of carry
		setb	fsr.2			; make sure that it's pointing at the result
		add	ind,#$60		; decimal correct


next_badd	clrb	fsr.2			; points to stored carry
		snb	ind.0			; skip if not set
		stc				; restore stored carry
		inc	fsr			; next byte
		sb	fsr.2			; done? (fsr=$0c?)
		jmp	badd_more		; not yet
		ret				; done, return to calling routine

		;8 BCD digit subtraction
		;entry = 8 BCD digit operand1 and 8 BCD digit operand2 in BCD form
		;exit  = operand2 become operand2-operand1, carry flag=0 for underflow from MSB
		;					    carry flag=1 for positive result
		;	 operand1 will be DESTROYED
bsub32		call 	bs32			; do subtraction
		snc				; no carry=underflow?
		jmp	bs_done			; carry=1 positive, done
		call 	neg_result		; yes, get the magnitude, 0-result
		call	bs32			; keep in mind that this result is a negative number (carry=0)
bs_done		ret

bs32		stc				; set carry, prepare for subtraction
		mov	fsr,#operand1		; points to operand 1 first
bsub_more
		mov	w,ind			; get contents into the working register
		clr	ind
		setb	ind.7			; set to 1 so that carry=1 after rl instruction
		setb	fsr.2			; points to operand 2
		sub	ind,w			; operand2=operand2+operand1
		clrb	fsr.2
		rl	ind			; store carry bit which will be altered by decimal
						; adjustment (adding 6)
		setb	fsr.2			; points back to operand 2
		sb	status.1		; digit carry set? if so, need decimal correction
		jmp	dec_cor
	
		jnb	ind.3,ck_underflow	; if 0xxx, check MSD
		jb	ind.2,dec_cor		; if 11xx, it's >9, thus need correction
		jnb	ind.1,ck_underflow	; 100x, number is 8 or 9, no decimal correction

		; here if 101x, decimal adjust	
dec_cor		stc				; clear effect of previous carry
		sub	ind,#6			; decimal correction by subtracting 6
	
		; finish dealing with least significant digit, proceed to MSD
ck_underflow 	clrb	fsr.2			; points to operand1
		jnb	ind.0,dadj_msd		; stored carry=0, decimal adjust
		; test if MSD > 9
		setb	fsr.2			; points back to operand2
		jnb	ind.7,next_bsub		; if 0xxx, it's <9, add next byte
		jb	ind.6,dadj_msd		; if 11xx, it's >9, thus need correction
		jnb	ind.5,next_bsub		; if 100x, it's <9
		
		;here if 101x, decimal adjust
dadj_msd	stc				; clear effect of carry
		setb	fsr.2			; make sure that it's pointing at the result
		sub	ind,#$60		; decimal correct


next_bsub	clrb	fsr.2			; points to stored carry
		sb	ind.0			; skip if not set
		clc				; restore stored carry
		inc	fsr			; next byte
		sb	fsr.2			; done? (fsr=$0c?)
		jmp	bsub_more		; not yet
		ret				; done, return to calling routine


		; move the result to operand1 and change operand2 to 0
		; the intention is prepare for 0-result or getting the magnitude of a 
		; negative BCD number which is in complement form
neg_result	mov	fsr,#operand2		; points to
mov_more	setb	fsr.2			; operand2
		mov	w,ind			; temp. storage
		clr	ind			; clear operand2
		clrb	fsr.2			; points to operand1
		mov	ind,w			; store result
		inc	fsr			; next byte
		sb	fsr.2			; done?
		jmp	mov_more		; no
		ret				; yes, finish


		; 32 bit binary to BCD conversion
		; entry: 32 bit binary number in $10-13
		; exit: 10 digit BCD number in $14-18
		; algorithm= shift the bits of binary number into the BCD number and decimal
		; 	     correct on the way
bindec		mov	count,#32
		mov	fsr,#bcd_number		; points to the BCD result
		
clr_bcd		clr	ind			; clear BCD number
		snb	fsr.3			; reached $18?
		jmp	shift_both		; yes, begin algorithm
		inc	fsr			; no, continue on next byte
		jmp	clr_bcd			; loop to clear
		
shift_both	mov	fsr,#bin_number		; points to the binary number input
		clc				; clear carry, prepare for shifting
		
shift_loop	rl 	ind			; shift the number left
		snb	fsr.3			; reached $18? (finish shifting both numbers)
		jmp	check_adj		; yes, check if end of everything
		inc	fsr			; no, next byte
		jmp	shift_loop		; not yet

check_adj	decsz	count			; end of 32 bit operation?
		jmp	bcd_adj			; no, do bcd adj
		ret

bcd_adj		mov	fsr,#bcd_number		; points to first byte of the BCD result

bcd_adj_loop	call	digit_adj		; decimal adjust
		snb	fsr.3			; reached last byte?
		jmp	shift_both		; yes, go to shift both number left again
		inc	fsr			; no, next byte
		jmp	bcd_adj_loop		; looping for decimal adjust

		; prepare for next shift    
		; 0000  --> 0000	0 -->0
		; 0001	--> 0010	1 -->2
		; 0010 	--> 0100	2 -->4
		; 0011	--> 0110	3 -->6
		; 0100	--> 1000	4 -->8
		; 0101	--> 1010	5 -->A, correct result is 10, so need to add 3
		;			so that 5+3=8, and 1000 will be shifted to be 1 0000
		; the same is true for 6-9
digit_adj	; consider LSD first
		mov	w,#3			; 3 will become 6 on next shift
		add	w,ind			; which is the decimal correct factor to be added
		mov	temp,w
		snb	temp.3			; > 7? if bit 3 not set, then must be <=7, no adj.
		mov	ind,w			; yes, decimal adjust needed, so store it
		
		; now for the MSD
		mov	w,#$30			; 3 for MSD is $30
		add	w,ind			; add for testing
		mov	temp,w
		snb	temp.7			; > 7?
		mov	ind,w			; yes, store it
		
		ret

		; 10 digit BCD to 32 bit binary conversion
		; entry: 10 digit BCD number in $14-18
		; exit: 32 bit binary number in $10-13
		; algorithm= shift the bits of BCD number into the binary number and decimal
		; 	     correct on the way
decbin		mov	count,#32		; 32 bit number
		mov	fsr,#bin_number		; points to the binary result
		
clr_bin		clr	ind			; clear binary number
		inc	fsr			; no, continue on next byte
		snb	fsr.2			; reached $13? (then fsr will be $14 here)
		jmp	shift_b			; yes, begin algorithm
		jmp	clr_bin			; loop to clear
		
shift_b		mov	fsr,#bcd_number+4	; points to the last BCD number 
		clc				; clear carry, prepare for shifting right
		
shft_loop	rr 	ind			; shift the number right
		dec	fsr			; reached $10? (finish shifting both numbers)
		sb	fsr.4			; then fsr will be $0f
		jmp	chk_adj			; yes, check if end of everything
		jmp	shft_loop		; not yet

chk_adj		decsz	count			; end of 32 bit operation?
		jmp	bd_adj			; no, do bcd adj
		ret

bd_adj		mov	fsr,#bcd_number		; points to first byte of the BCD result

bd_adj_loop	call	dgt_adj			; decimal adjust
		snb	fsr.3			; reached last byte?
		jmp	shift_b			; yes, go to shift both number right again
		inc	fsr			; no, next byte
		jmp	bd_adj_loop		; looping for decimal adjust

		; prepare for next shift right   
		; 0000  --> 0000	0 -->0
		; 0010	--> 0001	2 -->1
		; 0100 	--> 0010	4 -->2
		; 0110	--> 0011	6 -->3
		; 1000	--> 0100	8 -->4
		; 1 0000 --> 1000	10-->8 !! it should be 5, so -3
		; 1 0010 --> 1001	12-->9 !! it should be 6, so -3
		; in general when the highest bit in a nibble is 1, it should be subtracted with 3
dgt_adj		; consider LSD first
		sb	ind.3			; check highest bit in LSD, =1?
		jmp	ck_msd			; no, check MSD
		stc				; prepare for subtraction, no borrow
		sub	ind,#3			; yes, adjust
			
		; now for the MSD
ck_msd		sb	ind.7			; highest bit in MSD, =1?
		ret				; no

		; yes, do correction
		stc				; no borrow
		sub	ind,#$30		; this is  a 2 word instruction, and cannot be skipped
		ret
ENDIF
IF mul88_test=1
		; 8 bit x 8 bit multiplication (RAM efficient, 2 bytes only)
		; entry: multiplicand in W, multiplier at 09
		; exit : product at $0a,09
						; cycles
mul88		mov	upper_prdt,w		; 1 	store W
		mov	count,#9		; 2	set number of times to shift
		mov	w,upper_prdt		; 1 	restore W (multiplicand)		
		clr	upper_prdt		; 1	clear upper product
		clc				; 1	clear carry
						; the following are executed [count] times
m88loop		rr	upper_prdt		; 1	rotate right the whole product
		rr	multiplier		; 1	check lsb
		snc				; 1	skip addition if no carry
		add	upper_prdt,w		; 1	add multiplicand to upper product
no_add		decsz	count			; 1/2	loop 9 times to get proper product
		jmp	m88loop			; 3	jmp to rotate the next half of product

		ret				; 3	done...
						; one time instructions = 1+2+1+1+1+3= 9 cycles
						; repetitive ones	= (1+1+1+1+1+3)9-3+2=71
						; total worst case cycles=80 cycles

		; fast 8 bit x 8 bit multiplication (RAM efficient, 2 bytes only)
		; entry: multiplicand in W, multiplier at 09
		; exit : product at $0a,09

		; macro to rotate product right and add
rra		MACRO
		rr	upper_prdt		; 1	rotate right the whole product
		rr	multiplier		; 1	check lsb
		snc				; 1	skip addition if no carry
		add	upper_prdt,w		; 1	add multiplicand to upper product
		ENDM
						; cycles
fmul88		clr	upper_prdt		; 1	clear upper product
		clc				; 1	clear carry
						; the following are executed [count] times
		rra				; call the macro 9 times
		rra
		rra
		rra
		rra
		rra
		rra
		rra
		rra

		ret				; 3	done...
						; one time instructions = 1+1+3= 5 cycles
						; repetitive ones	= (1+1+1+1)9=36
						; total worst case cycles=41 cycles
ENDIF
IF mul1616_test=1
		; 16 bit x 16 bit multiplication 
		; entry: multiplicand in $09,08, multiplier at $0b,$0a
		; exit : 32 bit product at $0d,$0c,$b,$a
						; cycles
mul1616	
		mov	count,#17		; 2	set number of times to shift
		clr	upper_prdt		; 1	clear upper product
		clr	upper_prdt+1		; 1	higher byte of the 16 bit upeper product
		clc				; 1	clear carry
						; the following are executed [count] times
m1616loop	rr	upper_prdt+1		; 1	rotate right the whole product
		rr	upper_prdt		; 1 	lower byte of the 16 bit upper product
		rr	mr16+1			; 1	high byte of the multiplier
		rr	mr16			; 1	check lsb
		sc				; 1	skip addition if no carry
		jmp	no_add			; 3     no addition since lsb=0
		clc				; 1	clear carry
		add	upper_prdt,md16		; 1	add multiplicand to upper product
		add	upper_prdt+1,md16+1	; 1	add the next 16 bit of multiplicand
no_add		decsz	count			; 1/2	loop [count] times to get proper product
		jmp	m1616loop		; 3	jmp to rotate the next half of product

		ret				; 3	done...
						; one time instructions = 8 cycles
						; repetitive ones	= 15*16+11+2=253
						; total worst case cycles=261 cycles

		; fast 16 bit x 16 bit multiplication 
		; entry: multiplicand in $09,08, multiplier at $0b,$0a
		; exit : 32 bit product at $0d,$0c,$b,$a
						; cycles
						; one time instructions = 6
						; repetitive ones = 11*17=187
						; total = 193 cycles
fmul1616	
		clr	upper_prdt		; 1	clear upper product
		clr	upper_prdt+1		; 1	higher byte of the 16 bit upeper product
		clc				; 1	clear carry
					
		rr	upper_prdt+1		; 1	rotate right the whole product
		rr	upper_prdt		; 1 	lower byte of the 16 bit upper product
		rr	mr16+1			; 1	high byte of the multiplier
		rr	mr16			; 1	check lsb
		sc				; 1	skip addition if no carry
		jmp	no_add1			; 3     no addition since lsb=0
		clc				; 1	clear carry
		add	upper_prdt,md16		; 1	add multiplicand to upper product
		add	upper_prdt+1,md16+1	; 1	add the next 16 bit of multiplicand
no_add1		
		rr	upper_prdt+1		; 1	rotate right the whole product
		rr	upper_prdt		; 1 	lower byte of the 16 bit upper product
		rr	mr16+1			; 1	high byte of the multiplier
		rr	mr16			; 1	check lsb
		sc				; 1	skip addition if no carry
		jmp	no_add2			; 3     no addition since lsb=0
		clc				; 1	clear carry
		add	upper_prdt,md16		; 1	add multiplicand to upper product
		add	upper_prdt+1,md16+1	; 1	add the next 16 bit of multiplicand
no_add2				
		rr	upper_prdt+1		; 1	rotate right the whole product
		rr	upper_prdt		; 1 	lower byte of the 16 bit upper product
		rr	mr16+1			; 1	high byte of the multiplier
		rr	mr16			; 1	check lsb
		sc				; 1	skip addition if no carry
		jmp	no_add3			; 3     no addition since lsb=0
		clc				; 1	clear carry
		add	upper_prdt,md16		; 1	add multiplicand to upper product
		add	upper_prdt+1,md16+1	; 1	add the next 16 bit of multiplicand
no_add3
		rr	upper_prdt+1		; 1	rotate right the whole product
		rr	upper_prdt		; 1 	lower byte of the 16 bit upper product
		rr	mr16+1			; 1	high byte of the multiplier
		rr	mr16			; 1	check lsb
		sc				; 1	skip addition if no carry
		jmp	no_add4			; 3     no addition since lsb=0
		clc				; 1	clear carry
		add	upper_prdt,md16		; 1	add multiplicand to upper product
		add	upper_prdt+1,md16+1	; 1	add the next 16 bit of multiplicand
no_add4
		rr	upper_prdt+1		; 1	rotate right the whole product
		rr	upper_prdt		; 1 	lower byte of the 16 bit upper product
		rr	mr16+1			; 1	high byte of the multiplier
		rr	mr16			; 1	check lsb
		sc				; 1	skip addition if no carry
		jmp	no_add5			; 3     no addition since lsb=0
		clc				; 1	clear carry
		add	upper_prdt,md16		; 1	add multiplicand to upper product
		add	upper_prdt+1,md16+1	; 1	add the next 16 bit of multiplicand
no_add5
		rr	upper_prdt+1		; 1	rotate right the whole product
		rr	upper_prdt		; 1 	lower byte of the 16 bit upper product
		rr	mr16+1			; 1	high byte of the multiplier
		rr	mr16			; 1	check lsb
		sc				; 1	skip addition if no carry
		jmp	no_add6			; 3     no addition since lsb=0
		clc				; 1	clear carry
		add	upper_prdt,md16		; 1	add multiplicand to upper product
		add	upper_prdt+1,md16+1	; 1	add the next 16 bit of multiplicand
no_add6
		rr	upper_prdt+1		; 1	rotate right the whole product
		rr	upper_prdt		; 1 	lower byte of the 16 bit upper product
		rr	mr16+1			; 1	high byte of the multiplier
		rr	mr16			; 1	check lsb
		sc				; 1	skip addition if no carry
		jmp	no_add7			; 3     no addition since lsb=0
		clc				; 1	clear carry
		add	upper_prdt,md16		; 1	add multiplicand to upper product
		add	upper_prdt+1,md16+1	; 1	add the next 16 bit of multiplicand
no_add7
					
		rr	upper_prdt+1		; 1	rotate right the whole product
		rr	upper_prdt		; 1 	lower byte of the 16 bit upper product
		rr	mr16+1			; 1	high byte of the multiplier
		rr	mr16			; 1	check lsb
		sc				; 1	skip addition if no carry
		jmp	no_add8			; 3     no addition since lsb=0
		clc				; 1	clear carry
		add	upper_prdt,md16		; 1	add multiplicand to upper product
		add	upper_prdt+1,md16+1	; 1	add the next 16 bit of multiplicand
no_add8
		rr	upper_prdt+1		; 1	rotate right the whole product
		rr	upper_prdt		; 1 	lower byte of the 16 bit upper product
		rr	mr16+1			; 1	high byte of the multiplier
		rr	mr16			; 1	check lsb
		sc				; 1	skip addition if no carry
		jmp	no_add9			; 3     no addition since lsb=0
		clc				; 1	clear carry
		add	upper_prdt,md16		; 1	add multiplicand to upper product
		add	upper_prdt+1,md16+1	; 1	add the next 16 bit of multiplicand
no_add9					
		rr	upper_prdt+1		; 1	rotate right the whole product
		rr	upper_prdt		; 1 	lower byte of the 16 bit upper product
		rr	mr16+1			; 1	high byte of the multiplier
		rr	mr16			; 1	check lsb
		sc				; 1	skip addition if no carry
		jmp	no_add10		; 3     no addition since lsb=0
		clc				; 1	clear carry
		add	upper_prdt,md16		; 1	add multiplicand to upper product
		add	upper_prdt+1,md16+1	; 1	add the next 16 bit of multiplicand
no_add10
		rr	upper_prdt+1		; 1	rotate right the whole product
		rr	upper_prdt		; 1 	lower byte of the 16 bit upper product
		rr	mr16+1			; 1	high byte of the multiplier
		rr	mr16			; 1	check lsb
		sc				; 1	skip addition if no carry
		jmp	no_add11		; 3     no addition since lsb=0
		clc				; 1	clear carry
		add	upper_prdt,md16		; 1	add multiplicand to upper product
		add	upper_prdt+1,md16+1	; 1	add the next 16 bit of multiplicand
no_add11
		rr	upper_prdt+1		; 1	rotate right the whole product
		rr	upper_prdt		; 1 	lower byte of the 16 bit upper product
		rr	mr16+1			; 1	high byte of the multiplier
		rr	mr16			; 1	check lsb
		sc				; 1	skip addition if no carry
		jmp	no_add12		; 3     no addition since lsb=0
		clc				; 1	clear carry
		add	upper_prdt,md16		; 1	add multiplicand to upper product
		add	upper_prdt+1,md16+1	; 1	add the next 16 bit of multiplicand
no_add12
		rr	upper_prdt+1		; 1	rotate right the whole product
		rr	upper_prdt		; 1 	lower byte of the 16 bit upper product
		rr	mr16+1			; 1	high byte of the multiplier
		rr	mr16			; 1	check lsb
		sc				; 1	skip addition if no carry
		jmp	no_add13		; 3     no addition since lsb=0
		clc				; 1	clear carry
		add	upper_prdt,md16		; 1	add multiplicand to upper product
		add	upper_prdt+1,md16+1	; 1	add the next 16 bit of multiplicand
no_add13
		rr	upper_prdt+1		; 1	rotate right the whole product
		rr	upper_prdt		; 1 	lower byte of the 16 bit upper product
		rr	mr16+1			; 1	high byte of the multiplier
		rr	mr16			; 1	check lsb
		sc				; 1	skip addition if no carry
		jmp	no_add14		; 3     no addition since lsb=0
		clc				; 1	clear carry
		add	upper_prdt,md16		; 1	add multiplicand to upper product
		add	upper_prdt+1,md16+1	; 1	add the next 16 bit of multiplicand
no_add14
		rr	upper_prdt+1		; 1	rotate right the whole product
		rr	upper_prdt		; 1 	lower byte of the 16 bit upper product
		rr	mr16+1			; 1	high byte of the multiplier
		rr	mr16			; 1	check lsb
		sc				; 1	skip addition if no carry
		jmp	no_add15		; 3     no addition since lsb=0
		clc				; 1	clear carry
		add	upper_prdt,md16		; 1	add multiplicand to upper product
		add	upper_prdt+1,md16+1	; 1	add the next 16 bit of multiplicand
no_add15
					
		rr	upper_prdt+1		; 1	rotate right the whole product
		rr	upper_prdt		; 1 	lower byte of the 16 bit upper product
		rr	mr16+1			; 1	high byte of the multiplier
		rr	mr16			; 1	check lsb
		sc				; 1	skip addition if no carry
		jmp	no_add16		; 3     no addition since lsb=0
		clc				; 1	clear carry
		add	upper_prdt,md16		; 1	add multiplicand to upper product
		add	upper_prdt+1,md16+1	; 1	add the next 16 bit of multiplicand
no_add16
		rr	upper_prdt+1		; 1	rotate right the whole product
		rr	upper_prdt		; 1 	lower byte of the 16 bit upper product
		rr	mr16+1			; 1	high byte of the multiplier
		rr	mr16			; 1	check lsb
		sc				; 1	skip addition if no carry
		jmp	no_add17		; 3     no addition since lsb=0
		clc				; 1	clear carry
		add	upper_prdt,md16		; 1	add multiplicand to upper product
		add	upper_prdt+1,md16+1	; 1	add the next 16 bit of multiplicand
no_add17
		ret				; 3	done...
					
ENDIF
IF div1616_test=1
		; 16 bit by 16 bit division (b/a)
		; entry: 16 bit b, 16 bit a
		; exit : result in b, remainder in remainder
						; cycles
div1616		mov	count,#16 		; 2	no. of time to shift
		mov	d,b			; 2	move b to make space
		mov	d+1,b+1			; 2	for result
		clr	b			; 1	clear the result fields
		clr 	b+1			; 1	one more byte
		clr	rlo			; 1	clear remainder low byte
		clr	rhi			; 1	clear remainder high byte
						; subtotal=10
divloop		clc				; 1	clear carry before shift	
		rl	d			; 1	check the dividend
		rl	d+1			; 1	bit by bit
		rl	rlo			; 1	put it in the remainder for 
		rl	rhi			; 1	trial subtraction
						; subtotal=5
		stc				; 1	prepare for subtraction, no borrow
		mov	w,a+1			; 1	do trial subtraction
		mov	w,rhi-w			; 1	from MSB first
		sz				; 1/2	if two MSB equal, need to check LSB
		jmp	chk_carry		; 3	not equal, check which one is bigger
						; 
		; if we are here, then z=1, so c must be 1 too, since there is no 
		; underflow, so we save a stc instruction
		
		mov	w,a			; 1	equal MSB, check LSB
		mov	w,rlo-w			; 1	which one is bigger?
						; subtotal=7
chk_carry	sc				; 1/2	partial dividend >a?
		jmp	shft_quot		; 3	no, partial dividend < a, set a 0 into quotient

		; if we are here, then c must be 1, again, we save another stc instruction

						; yes, part. dividend > a, subtract a from it
		sub	rlo,a			; 2	store part. dividend-a into a
		sub	rhi,a+1			; 2	2 bytes
		stc				; 1	shift a 1 into quotient
						; subtotal=7 worst case
shft_quot	rl	b			; 1	store into result
		rl	b+1			; 1	16 bit result, thus 2 rotates
		decsz	count			; 1/2
		jmp	divloop			; 3
						; subtotal=6, 4 on last count
		ret				; 3
						; one time instructions=13
						; repetitive ones=(19+6)*15+19+4=398
						; total=411

		; fast 16 bit by 16 bit division (b/a)
		; entry: 16 bit b, 16 bit a
		; exit : result in b, remainder in remainder
						; cycles=347
						; one time=11
						; repetitive=21*16=336
fdiv1616
		mov	d,b			; 2	move b to make space
		mov	d+1,b+1			; 2	for result
		clr	b			; 1	clear the result fields
		clr 	b+1			; 1	one more byte
		clr	rlo			; 1	clear remainder low byte
		clr	rhi			; 1	clear remainder high byte
						; subtotal=8
		clc				; 1	clear carry before shift	
		rl	d			; 1	check the dividend
		rl	d+1			; 1	bit by bit
		rl	rlo			; 1	put it in the remainder for 
		rl	rhi			; 1	trial subtraction
						; subtotal=5
		stc				; 1	prepare for subtraction, no borrow
		mov	w,a+1			; 1	do trial subtraction
		mov	w,rhi-w			; 1	from MSB first
		sz				; 1/2	if two MSB equal, need to check LSB
		jmp	chk_carry1		; 3	not equal, check which one is bigger
						; 
		; if we are here, then z=1, so c must be 1 too, since there is no 
		; underflow, so we save a stc instruction
		
		mov	w,a			; 1	equal MSB, check LSB
		mov	w,rlo-w			; 1	which one is bigger?
						; subtotal=7
chk_carry1	sc				; 1/2	partial dividend >a?
		jmp	shft_quot1		; 3	no, partial dividend < a, set a 0 into quotient

		; if we are here, then c must be 1, again, we save another stc instruction

						; yes, part. dividend > a, subtract a from it
		sub	rlo,a			; 2	store part. dividend-a into a
		sub	rhi,a+1			; 2	2 bytes
		stc				; 1	shift a 1 into quotient
						; subtotal=7 worst case
shft_quot1	rl	b			; 1	store into result
		rl	b+1			; 1	16 bit result, thus 2 rotates
		
		clc				; 1	clear carry before shift	
		rl	d			; 1	check the dividend
		rl	d+1			; 1	bit by bit
		rl	rlo			; 1	put it in the remainder for 
		rl	rhi			; 1	trial subtraction
						; subtotal=5
		stc				; 1	prepare for subtraction, no borrow
		mov	w,a+1			; 1	do trial subtraction
		mov	w,rhi-w			; 1	from MSB first
		sz				; 1/2	if two MSB equal, need to check LSB
		jmp	chk_carry2		; 3	not equal, check which one is bigger
						; 
		; if we are here, then z=1, so c must be 1 too, since there is no 
		; underflow, so we save a stc instruction
		
		mov	w,a			; 1	equal MSB, check LSB
		mov	w,rlo-w			; 1	which one is bigger?
						; subtotal=7
chk_carry2	sc				; 1/2	partial dividend >a?
		jmp	shft_quot2		; 3	no, partial dividend < a, set a 0 into quotient

		; if we are here, then c must be 1, again, we save another stc instruction

						; yes, part. dividend > a, subtract a from it
		sub	rlo,a			; 2	store part. dividend-a into a
		sub	rhi,a+1			; 2	2 bytes
		stc				; 1	shift a 1 into quotient
						; subtotal=7 worst case
shft_quot2	rl	b			; 1	store into result
		rl	b+1			; 1	16 bit result, thus 2 rotates
		
		clc				; 1	clear carry before shift	
		rl	d			; 1	check the dividend
		rl	d+1			; 1	bit by bit
		rl	rlo			; 1	put it in the remainder for 
		rl	rhi			; 1	trial subtraction
						; subtotal=5
		stc				; 1	prepare for subtraction, no borrow
		mov	w,a+1			; 1	do trial subtraction
		mov	w,rhi-w			; 1	from MSB first
		sz				; 1/2	if two MSB equal, need to check LSB
		jmp	chk_carry3		; 3	not equal, check which one is bigger
						; 
		; if we are here, then z=1, so c must be 1 too, since there is no 
		; underflow, so we save a stc instruction
		
		mov	w,a			; 1	equal MSB, check LSB
		mov	w,rlo-w			; 1	which one is bigger?
						; subtotal=7
chk_carry3	sc				; 1/2	partial dividend >a?
		jmp	shft_quot3		; 3	no, partial dividend < a, set a 0 into quotient

		; if we are here, then c must be 1, again, we save another stc instruction

						; yes, part. dividend > a, subtract a from it
		sub	rlo,a			; 2	store part. dividend-a into a
		sub	rhi,a+1			; 2	2 bytes
		stc				; 1	shift a 1 into quotient
						; subtotal=7 worst case
shft_quot3	rl	b			; 1	store into result
		rl	b+1			; 1	16 bit result, thus 2 rotates
	
		clc				; 1	clear carry before shift	
		rl	d			; 1	check the dividend
		rl	d+1			; 1	bit by bit
		rl	rlo			; 1	put it in the remainder for 
		rl	rhi			; 1	trial subtraction
						; subtotal=5
		stc				; 1	prepare for subtraction, no borrow
		mov	w,a+1			; 1	do trial subtraction
		mov	w,rhi-w			; 1	from MSB first
		sz				; 1/2	if two MSB equal, need to check LSB
		jmp	chk_carry4		; 3	not equal, check which one is bigger
						; 
		; if we are here, then z=1, so c must be 1 too, since there is no 
		; underflow, so we save a stc instruction
		
		mov	w,a			; 1	equal MSB, check LSB
		mov	w,rlo-w			; 1	which one is bigger?
						; subtotal=7
chk_carry4	sc				; 1/2	partial dividend >a?
		jmp	shft_quot4		; 3	no, partial dividend < a, set a 0 into quotient

		; if we are here, then c must be 1, again, we save another stc instruction

						; yes, part. dividend > a, subtract a from it
		sub	rlo,a			; 2	store part. dividend-a into a
		sub	rhi,a+1			; 2	2 bytes
		stc				; 1	shift a 1 into quotient
						; subtotal=7 worst case
shft_quot4	rl	b			; 1	store into result
		rl	b+1			; 1	16 bit result, thus 2 rotates
	
		clc				; 1	clear carry before shift	
		rl	d			; 1	check the dividend
		rl	d+1			; 1	bit by bit
		rl	rlo			; 1	put it in the remainder for 
		rl	rhi			; 1	trial subtraction
						; subtotal=5
		stc				; 1	prepare for subtraction, no borrow
		mov	w,a+1			; 1	do trial subtraction
		mov	w,rhi-w			; 1	from MSB first
		sz				; 1/2	if two MSB equal, need to check LSB
		jmp	chk_carry5		; 3	not equal, check which one is bigger
						; 
		; if we are here, then z=1, so c must be 1 too, since there is no 
		; underflow, so we save a stc instruction
		
		mov	w,a			; 1	equal MSB, check LSB
		mov	w,rlo-w			; 1	which one is bigger?
						; subtotal=7
chk_carry5	sc				; 1/2	partial dividend >a?
		jmp	shft_quot5		; 3	no, partial dividend < a, set a 0 into quotient

		; if we are here, then c must be 1, again, we save another stc instruction

						; yes, part. dividend > a, subtract a from it
		sub	rlo,a			; 2	store part. dividend-a into a
		sub	rhi,a+1			; 2	2 bytes
		stc				; 1	shift a 1 into quotient
						; subtotal=7 worst case
shft_quot5	rl	b			; 1	store into result
		rl	b+1			; 1	16 bit result, thus 2 rotates

		clc				; 1	clear carry before shift	
		rl	d			; 1	check the dividend
		rl	d+1			; 1	bit by bit
		rl	rlo			; 1	put it in the remainder for 
		rl	rhi			; 1	trial subtraction
						; subtotal=5
		stc				; 1	prepare for subtraction, no borrow
		mov	w,a+1			; 1	do trial subtraction
		mov	w,rhi-w			; 1	from MSB first
		sz				; 1/2	if two MSB equal, need to check LSB
		jmp	chk_carry6		; 3	not equal, check which one is bigger
						; 
		; if we are here, then z=1, so c must be 1 too, since there is no 
		; underflow, so we save a stc instruction
		
		mov	w,a			; 1	equal MSB, check LSB
		mov	w,rlo-w			; 1	which one is bigger?
						; subtotal=7
chk_carry6	sc				; 1/2	partial dividend >a?
		jmp	shft_quot6		; 3	no, partial dividend < a, set a 0 into quotient

		; if we are here, then c must be 1, again, we save another stc instruction

						; yes, part. dividend > a, subtract a from it
		sub	rlo,a			; 2	store part. dividend-a into a
		sub	rhi,a+1			; 2	2 bytes
		stc				; 1	shift a 1 into quotient
						; subtotal=7 worst case
shft_quot6	rl	b			; 1	store into result
		rl	b+1			; 1	16 bit result, thus 2 rotates

		clc				; 1	clear carry before shift	
		rl	d			; 1	check the dividend
		rl	d+1			; 1	bit by bit
		rl	rlo			; 1	put it in the remainder for 
		rl	rhi			; 1	trial subtraction
						; subtotal=5
		stc				; 1	prepare for subtraction, no borrow
		mov	w,a+1			; 1	do trial subtraction
		mov	w,rhi-w			; 1	from MSB first
		sz				; 1/2	if two MSB equal, need to check LSB
		jmp	chk_carry7		; 3	not equal, check which one is bigger
						; 
		; if we are here, then z=1, so c must be 1 too, since there is no 
		; underflow, so we save a stc instruction
		
		mov	w,a			; 1	equal MSB, check LSB
		mov	w,rlo-w			; 1	which one is bigger?
						; subtotal=7
chk_carry7	sc				; 1/2	partial dividend >a?
		jmp	shft_quot7		; 3	no, partial dividend < a, set a 0 into quotient

		; if we are here, then c must be 1, again, we save another stc instruction

						; yes, part. dividend > a, subtract a from it
		sub	rlo,a			; 2	store part. dividend-a into a
		sub	rhi,a+1			; 2	2 bytes
		stc				; 1	shift a 1 into quotient
						; subtotal=7 worst case
shft_quot7	rl	b			; 1	store into result
		rl	b+1			; 1	16 bit result, thus 2 rotates

		clc				; 1	clear carry before shift	
		rl	d			; 1	check the dividend
		rl	d+1			; 1	bit by bit
		rl	rlo			; 1	put it in the remainder for 
		rl	rhi			; 1	trial subtraction
						; subtotal=5
		stc				; 1	prepare for subtraction, no borrow
		mov	w,a+1			; 1	do trial subtraction
		mov	w,rhi-w			; 1	from MSB first
		sz				; 1/2	if two MSB equal, need to check LSB
		jmp	chk_carry8		; 3	not equal, check which one is bigger
						; 
		; if we are here, then z=1, so c must be 1 too, since there is no 
		; underflow, so we save a stc instruction
		
		mov	w,a			; 1	equal MSB, check LSB
		mov	w,rlo-w			; 1	which one is bigger?
						; subtotal=7
chk_carry8	sc				; 1/2	partial dividend >a?
		jmp	shft_quot8		; 3	no, partial dividend < a, set a 0 into quotient

		; if we are here, then c must be 1, again, we save another stc instruction

						; yes, part. dividend > a, subtract a from it
		sub	rlo,a			; 2	store part. dividend-a into a
		sub	rhi,a+1			; 2	2 bytes
		stc				; 1	shift a 1 into quotient
						; subtotal=7 worst case
shft_quot8	rl	b			; 1	store into result
		rl	b+1			; 1	16 bit result, thus 2 rotates

		clc				; 1	clear carry before shift	
		rl	d			; 1	check the dividend
		rl	d+1			; 1	bit by bit
		rl	rlo			; 1	put it in the remainder for 
		rl	rhi			; 1	trial subtraction
						; subtotal=5
		stc				; 1	prepare for subtraction, no borrow
		mov	w,a+1			; 1	do trial subtraction
		mov	w,rhi-w			; 1	from MSB first
		sz				; 1/2	if two MSB equal, need to check LSB
		jmp	chk_carry9		; 3	not equal, check which one is bigger
						; 
		; if we are here, then z=1, so c must be 1 too, since there is no 
		; underflow, so we save a stc instruction
		
		mov	w,a			; 1	equal MSB, check LSB
		mov	w,rlo-w			; 1	which one is bigger?
						; subtotal=7
chk_carry9	sc				; 1/2	partial dividend >a?
		jmp	shft_quot9		; 3	no, partial dividend < a, set a 0 into quotient

		; if we are here, then c must be 1, again, we save another stc instruction

						; yes, part. dividend > a, subtract a from it
		sub	rlo,a			; 2	store part. dividend-a into a
		sub	rhi,a+1			; 2	2 bytes
		stc				; 1	shift a 1 into quotient
						; subtotal=7 worst case
shft_quot9	rl	b			; 1	store into result
		rl	b+1			; 1	16 bit result, thus 2 rotates

		clc				; 1	clear carry before shift	
		rl	d			; 1	check the dividend
		rl	d+1			; 1	bit by bit
		rl	rlo			; 1	put it in the remainder for 
		rl	rhi			; 1	trial subtraction
						; subtotal=5
		stc				; 1	prepare for subtraction, no borrow
		mov	w,a+1			; 1	do trial subtraction
		mov	w,rhi-w			; 1	from MSB first
		sz				; 1/2	if two MSB equal, need to check LSB
		jmp	chk_carry10		; 3	not equal, check which one is bigger
						; 
		; if we are here, then z=1, so c must be 1 too, since there is no 
		; underflow, so we save a stc instruction
		
		mov	w,a			; 1	equal MSB, check LSB
		mov	w,rlo-w			; 1	which one is bigger?
						; subtotal=7
chk_carry10	sc				; 1/2	partial dividend >a?
		jmp	shft_quot10		; 3	no, partial dividend < a, set a 0 into quotient

		; if we are here, then c must be 1, again, we save another stc instruction

						; yes, part. dividend > a, subtract a from it
		sub	rlo,a			; 2	store part. dividend-a into a
		sub	rhi,a+1			; 2	2 bytes
		stc				; 1	shift a 1 into quotient
						; subtotal=7 worst case
shft_quot10	rl	b			; 1	store into result
		rl	b+1			; 1	16 bit result, thus 2 rotates

		clc				; 1	clear carry before shift	
		rl	d			; 1	check the dividend
		rl	d+1			; 1	bit by bit
		rl	rlo			; 1	put it in the remainder for 
		rl	rhi			; 1	trial subtraction
						; subtotal=5
		stc				; 1	prepare for subtraction, no borrow
		mov	w,a+1			; 1	do trial subtraction
		mov	w,rhi-w			; 1	from MSB first
		sz				; 1/2	if two MSB equal, need to check LSB
		jmp	chk_carry11		; 3	not equal, check which one is bigger
						; 
		; if we are here, then z=1, so c must be 1 too, since there is no 
		; underflow, so we save a stc instruction
		
		mov	w,a			; 1	equal MSB, check LSB
		mov	w,rlo-w			; 1	which one is bigger?
						; subtotal=7
chk_carry11	sc				; 1/2	partial dividend >a?
		jmp	shft_quot11		; 3	no, partial dividend < a, set a 0 into quotient

		; if we are here, then c must be 1, again, we save another stc instruction

						; yes, part. dividend > a, subtract a from it
		sub	rlo,a			; 2	store part. dividend-a into a
		sub	rhi,a+1			; 2	2 bytes
		stc				; 1	shift a 1 into quotient
						; subtotal=7 worst case
shft_quot11	rl	b			; 1	store into result
		rl	b+1			; 1	16 bit result, thus 2 rotates

		clc				; 1	clear carry before shift	
		rl	d			; 1	check the dividend
		rl	d+1			; 1	bit by bit
		rl	rlo			; 1	put it in the remainder for 
		rl	rhi			; 1	trial subtraction
						; subtotal=5
		stc				; 1	prepare for subtraction, no borrow
		mov	w,a+1			; 1	do trial subtraction
		mov	w,rhi-w			; 1	from MSB first
		sz				; 1/2	if two MSB equal, need to check LSB
		jmp	chk_carry12		; 3	not equal, check which one is bigger
						; 
		; if we are here, then z=1, so c must be 1 too, since there is no 
		; underflow, so we save a stc instruction
		
		mov	w,a			; 1	equal MSB, check LSB
		mov	w,rlo-w			; 1	which one is bigger?
						; subtotal=7
chk_carry12	sc				; 1/2	partial dividend >a?
		jmp	shft_quot12		; 3	no, partial dividend < a, set a 0 into quotient

		; if we are here, then c must be 1, again, we save another stc instruction

						; yes, part. dividend > a, subtract a from it
		sub	rlo,a			; 2	store part. dividend-a into a
		sub	rhi,a+1			; 2	2 bytes
		stc				; 1	shift a 1 into quotient
						; subtotal=7 worst case
shft_quot12	rl	b			; 1	store into result
		rl	b+1			; 1	16 bit result, thus 2 rotates

		clc				; 1	clear carry before shift	
		rl	d			; 1	check the dividend
		rl	d+1			; 1	bit by bit
		rl	rlo			; 1	put it in the remainder for 
		rl	rhi			; 1	trial subtraction
						; subtotal=5
		stc				; 1	prepare for subtraction, no borrow
		mov	w,a+1			; 1	do trial subtraction
		mov	w,rhi-w			; 1	from MSB first
		sz				; 1/2	if two MSB equal, need to check LSB
		jmp	chk_carry13		; 3	not equal, check which one is bigger
						; 
		; if we are here, then z=1, so c must be 1 too, since there is no 
		; underflow, so we save a stc instruction
		
		mov	w,a			; 1	equal MSB, check LSB
		mov	w,rlo-w			; 1	which one is bigger?
						; subtotal=7
chk_carry13	sc				; 1/2	partial dividend >a?
		jmp	shft_quot13		; 3	no, partial dividend < a, set a 0 into quotient

		; if we are here, then c must be 1, again, we save another stc instruction

						; yes, part. dividend > a, subtract a from it
		sub	rlo,a			; 2	store part. dividend-a into a
		sub	rhi,a+1			; 2	2 bytes
		stc				; 1	shift a 1 into quotient
						; subtotal=7 worst case
shft_quot13	rl	b			; 1	store into result
		rl	b+1			; 1	16 bit result, thus 2 rotates

		clc				; 1	clear carry before shift	
		rl	d			; 1	check the dividend
		rl	d+1			; 1	bit by bit
		rl	rlo			; 1	put it in the remainder for 
		rl	rhi			; 1	trial subtraction
						; subtotal=5
		stc				; 1	prepare for subtraction, no borrow
		mov	w,a+1			; 1	do trial subtraction
		mov	w,rhi-w			; 1	from MSB first
		sz				; 1/2	if two MSB equal, need to check LSB
		jmp	chk_carry14		; 3	not equal, check which one is bigger
						; 
		; if we are here, then z=1, so c must be 1 too, since there is no 
		; underflow, so we save a stc instruction
		
		mov	w,a			; 1	equal MSB, check LSB
		mov	w,rlo-w			; 1	which one is bigger?
						; subtotal=7
chk_carry14	sc				; 1/2	partial dividend >a?
		jmp	shft_quot14		; 3	no, partial dividend < a, set a 0 into quotient

		; if we are here, then c must be 1, again, we save another stc instruction

						; yes, part. dividend > a, subtract a from it
		sub	rlo,a			; 2	store part. dividend-a into a
		sub	rhi,a+1			; 2	2 bytes
		stc				; 1	shift a 1 into quotient
						; subtotal=7 worst case
shft_quot14	rl	b			; 1	store into result
		rl	b+1			; 1	16 bit result, thus 2 rotates

		clc				; 1	clear carry before shift	
		rl	d			; 1	check the dividend
		rl	d+1			; 1	bit by bit
		rl	rlo			; 1	put it in the remainder for 
		rl	rhi			; 1	trial subtraction
						; subtotal=5
		stc				; 1	prepare for subtraction, no borrow
		mov	w,a+1			; 1	do trial subtraction
		mov	w,rhi-w			; 1	from MSB first
		sz				; 1/2	if two MSB equal, need to check LSB
		jmp	chk_carry15		; 3	not equal, check which one is bigger
						; 
		; if we are here, then z=1, so c must be 1 too, since there is no 
		; underflow, so we save a stc instruction
		
		mov	w,a			; 1	equal MSB, check LSB
		mov	w,rlo-w			; 1	which one is bigger?
						; subtotal=7
chk_carry15	sc				; 1/2	partial dividend >a?
		jmp	shft_quot15		; 3	no, partial dividend < a, set a 0 into quotient

		; if we are here, then c must be 1, again, we save another stc instruction

						; yes, part. dividend > a, subtract a from it
		sub	rlo,a			; 2	store part. dividend-a into a
		sub	rhi,a+1			; 2	2 bytes
		stc				; 1	shift a 1 into quotient
						; subtotal=7 worst case
shft_quot15	rl	b			; 1	store into result
		rl	b+1			; 1	16 bit result, thus 2 rotates

		clc				; 1	clear carry before shift	
		rl	d			; 1	check the dividend
		rl	d+1			; 1	bit by bit
		rl	rlo			; 1	put it in the remainder for 
		rl	rhi			; 1	trial subtraction
						; subtotal=5
		stc				; 1	prepare for subtraction, no borrow
		mov	w,a+1			; 1	do trial subtraction
		mov	w,rhi-w			; 1	from MSB first
		sz				; 1/2	if two MSB equal, need to check LSB
		jmp	chk_carry16		; 3	not equal, check which one is bigger
						; 
		; if we are here, then z=1, so c must be 1 too, since there is no 
		; underflow, so we save a stc instruction
		
		mov	w,a			; 1	equal MSB, check LSB
		mov	w,rlo-w			; 1	which one is bigger?
						; subtotal=7
chk_carry16	sc				; 1/2	partial dividend >a?
		jmp	shft_quot16		; 3	no, partial dividend < a, set a 0 into quotient

		; if we are here, then c must be 1, again, we save another stc instruction

						; yes, part. dividend > a, subtract a from it
		sub	rlo,a			; 2	store part. dividend-a into a
		sub	rhi,a+1			; 2	2 bytes
		stc				; 1	shift a 1 into quotient
						; subtotal=7 worst case
shft_quot16	rl	b			; 1	store into result
		rl	b+1			; 1	16 bit result, thus 2 rotates
	
					
		ret				; 3
					
		
ENDIF		

file: /Techref/scenix/sx_arith.src, 44KB, , updated: 1999/3/6 10:07, local time: 2024/4/16 13:33,
TOP NEW HELP FIND: 
18.189.180.244:LOG IN

 ©2024 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions?
Please DO link to this page! Digg it! / MAKE!

<A HREF="http://www.sxlist.com/techref/scenix/sx_arith.src"> scenix sx_arith</A>

Did you find what you needed?

 

Welcome to sxlist.com!


Site supported by
sales, advertizing,
& kind contributors
just like you!

Please don't rip/copy
(here's why

Copies of the site on CD
are available at minimal cost.
 

Welcome to www.sxlist.com!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  .