;MULDIV/ASM - 16 x 8 multiplication & division
	SUBTTL	'<16 X 8 multiply/divide>'
	PAGE	OFF
*MOD
;
;	Multiply HL by A - SVC 91
;	HL => multiplicand
;	A  => multiplier
;	HLA <= 24-bit result
;	DE destroyed
;
@MUL16	PUSH	BC		;Save reg BC
	EX	DE,HL		;Multiplicand to DE
	LD	C,A		;  & multiplier to C
	LD	HL,0		;Init value to zero
	LD	A,L		;  in regs HLA
	LD	B,8		;Init for 8-bit mult
$?1	ADD	HL,HL		;Shift to next place
	RLA			;Use A for bits 16-23
	RLC	C		;Multiply this bit?
	JR	NC,$?2		;Go if not
	ADD	HL,DE		;Else add multiplicand
	ADC	A,0		;  & any overflow to 16
$?2	DJNZ	$?1		;Loop for 8 bits
	LD	C,A		;Tempy save
	LD	A,L		;Xfer low-order to A
	LD	L,H		;Xfer mid-order to L
	LD	H,C		;Xfer hi-order to H
	POP	BC
	RET
;
;	Divide HL by A - SVC 94
;	HL => dividend
;	A  => divisor
;	HL <= resulting quotient
;	A  <= remainder
;
*MOD
@DIV16	PUSH	DE		;Save this reg pair
	LD	D,A		;Xfer divisor to D
	LD	E,16		;Init for 16-bits
	XOR	A
$?1	ADD	HL,HL		;Rotate dividend
	RLA			;  & subtract divisor if
	JR	C,$?2		;  carry into bit-16
	CP	D		;Compare divisor
	JR	C,$?3		;Go if no subtract
$?2	SUB	D		;  else subtract divisor
	INC	L		;Set lo-order
$?3	DEC	E		;Count down one bit
	JR	NZ,$?1		;Loop for 16-bits
	POP	DE
	RET
;
;	@HEXDEC - SVC 97
;	Routine to convert 16-bit hexadecimal to decimal
;	HL => value
;	DE => buffer pointer of 5-character buffer
;	HL <= destroyed (always set to zero)
;	DE <= Buffer+5
;	BC <= destroyed
;	Z  <= set
;
*MOD
@HEXDEC	LD	B,5		;Length max
@HEXD	LD	A,' '		;Load blank
HEXDEC1	LD	(DE),A		;To string
	INC	DE		;Bump pointer
	DJNZ	HEXDEC1		;Go for length
	PUSH	DE		;Save end +1
	DEC	DE		;Adjust back
HEXDEC2	LD	A,10		;Base to convert to
	CALL	@DIV16		;HL+A  =  HL/A
	ADD	A,'0'		;Add ASCII to result
	LD	(DE),A		;  to user string
	DEC	DE		;Move back
;
;	Check if done
;
	LD	A,H		;Get subtotal remainder
	OR	L		;Done?
	JR	NZ,HEXDEC2	;Go till completed
	POP	DE		;Restore end+1
	RET			;Return Z
;
