	device SX28,STACKX, OPTIONX, CARRYX

;Fractional multiply. 
;This is a routine that multiplies two values, 
;  one treated as an integer, 
;  and the other treated as a binary fraction.

;Adapted from 6800 code by Ira Chayut. 
;BYTE Magazine, September 1976, Programming Quickies, page 124.

	org $10
arg1	ds	1
arg2	ds	1

	RESET	Start
Start
	clr	fsr
;test code: 255 * 2/3 ~= 170. Actually returns 166.
	mov arg1,#255
	mov arg2,#256 * 2/3
	call fracmul2
;test code: 80 * 1/2 ~= 40. Actually returns 40.
	mov arg1,#80
	mov arg2,#256 * 1/2
	call fracmul2
	jmp $

fracmul
;This version depends on CARRYX being off.
	clr	W		;W=0
:mloop
	clc
	rr arg1		;ARG1:=ARG1/2
	clc			; don't copy the carry
	rl arg2		;CY:=MSB(ARG2), ARG2:=ASL(ARG2,1)
	snc			;IF CY=0 THEN SKIP THE ADDITION
	 add w,arg1	;ELSE W:=W+ARG1
; CARRYX must be off.
	test arg2
	jnz @:mloop	;IF ARG2 NE 0 THEN REITERATE
	ret			;ELSE RETURN WITH RESULT IN W

fracmul2
;Version not sensitve to CARRRYX
	clr W		;W=0
:loop
	clc
	rr arg1		;arg1 = arg1 / 2
	clc
	snb arg2.7	;if arg2 <= 128
	 add w,arg1	; W = W + arg1
	clc
	rl arg2		;arg2 = arg2 * 2
	test arg2	;if arg2 <> 0
	jnz @:loop	; goto loop
	ret			;return


