; 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 ; 7ドルfffffff+01ドルffffff load32 $ff,$ff,$ff,01,ドル$ff,$ff,$ff,7ドルf call add32 ;result=81ドルfffffe ; 8ドルffffffe-01ドルffffff call sub32 ;result=7ドルfffffff, carry=1-> result is positive ; 01ドルffffff-7ドルfffffff load32 $ff,$ff,$ff,7ドルf,$ff,$ff,$ff,01ドル call sub32 ;result=82000000,ドル carry=0-> result is negative and in ;2's complement form, =-7ドルe000000 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,#7ドルf 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,#7ドルf call fmul1616 ; result = 00ff7e01 ENDIF IF div1616_test=1 mov a+1,#01ドル mov a,#$ff ; 01ff mov b+1,#7ドルf mov b,#$ff ; 7fff call div1616 ; 7fff/01ff=40ドル remainder 3ドルf 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,#7ドルf mov b,#$ff ; 7fff call fdiv1616 ; 7fff/01ff=40ドル remainder 3ドルf 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=0ドルc?) 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=0ドルc?) 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 0ドルf 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 0ドルa,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 0ドルa,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 0ドルb,0ドルa ; exit : 32 bit product at 0ドルd,0ドルc,$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 0ドルb,0ドルa ; exit : 32 bit product at 0ドルd,0ドルc,$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
.