;***************************************************************************
;*
;* 32x32 Bit Multiply
;*
;***************************************************************************

;***** Subroutine Register Variables

.def	mc16a	=r14		;multiplicand low byte
.def	mc16b	=r15		;multiplicand high byte
.def	mc16a	=r16		;multiplicand low byte
.def	mc16b	=r17		;multiplicand high byte

.def	mp16uL	=r18		;multiplier low byte
.def	mp16uH	=r21		;multiplier high byte

.def	m16u0	=r18		;result byte 0 (LSB) and multiplier low byte
.def	m16u1	=r19		;result byte 1 
.def	m16u2	=r20		;result byte 2
.def	m16u3	=r21		;result byte 3 and multiplier high byte
.def	m16u4	=r22		;result byte 4
.def	m16u5	=r23		;result byte 5
.def	m16u6	=r24		;result byte 6
.def	m16u7	=r25		;result byte 7 (MSB)
.def	mcnt	=r26		;loop counter

;***** Code

mpy32:
	clr	m16u7		;clear 4 highest bytes of result
	clr	m16u6
	clr	m16u5
	clr	m16u4
	ldi	mcnt,32	;init loop counter
	lsr	m16u3
	ror	m16u2
	ror	m16u1
	ror	m16u0

loop1:
	brcc	noad		;if bit 0 of multiplier set
	add	m16u4,mc16a	;add multiplicand Low to byte 2 of res
	adc	m16u5,mc16b	;add multiplicand high to byte 3 of res
	adc	m16u6,mc16c	;add multiplicand Low to byte 2 of res
	adc	m16u7,mc16d	;add multiplicand high to byte 3 of res
noad:
	ror	m16u7		;shift  right result byte 7
	ror	m16u6		;rotate right result byte 6
	ror	m16u5		;rotate right result byte 5
	ror	m16u4		;rotate right result byte 4
	ror	m16u3		;rotate right result byte 3
	ror	m16u2		;rotate right result byte 2
	ror	m16u1		;rotate result byte 1 and multiplier High
	ror	m16u0		;rotate result byte 0 and multiplier Low
	dec	mcnt		;decrement loop counter
	brne loop1		;if not done, loop more
	ret
	
;***************************************************************************
;*
;* "mpy16u" - 16x16 Bit Unsigned Multiplication
;*
;* This subroutine multiplies the two 16-bit register variables 
;* mp16uH:mp16uL and mc16b:mc16a.
;* The result is placed in m16u3:m16u2:m16u1:m16u0.
;*  
;* Number of words	:14 + return
;* Number of cycles	:153 + return
;* Low registers used	:None
;* High registers used  :7 (mp16uL,mp16uH,mc16a/m16u0,mc16b/m16u1,m16u2,
;*                          m16u3,mcnt16u)	
;*
;***************************************************************************

;***** Subroutine Register Variables
.def	mc16uL	=r16		;multiplicand low byte
.def	mc16uH	=r17		;multiplicand high byte
.def	mp16uL	=r18		;multiplier low byte
.def	mp16uH	=r19		;multiplier high byte
.def	m16u0	=r18		;result byte 0 (LSB)
.def	m16u1	=r19		;result byte 1
.def	m16u2	=r20		;result byte 2
.def	m16u3	=r21		;result byte 3 (MSB)
.def	mcnt16u	=r22		;loop counter

;***** Code

mpy16u:	clr	m16u3		;clear 2 highest bytes of result
	clr	m16u2
	ldi	mcnt16u,16	;init loop counter
	lsr	mp16uH
	ror	mp16uL

m16u_1:	brcc	noad8		;if bit 0 of multiplier set
	add	m16u2,mc16uL	;add multiplicand Low to byte 2 of res
	adc	m16u3,mc16uH	;add multiplicand high to byte 3 of res
noad8:	ror	m16u3		;shift right result byte 3
	ror	m16u2		;rotate right result byte 2
	ror	m16u1		;rotate result byte 1 and multiplier High
	ror	m16u0		;rotate result byte 0 and multiplier Low
	dec	mcnt16u		;decrement loop counter
	brne	m16u_1		;if not done, loop more
	ret