85 lines
		
	
	
	
		
			1.9 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			85 lines
		
	
	
	
		
			1.9 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
.define .mli2
 | 
						|
.sect .text
 | 
						|
.sect .rom
 | 
						|
.sect .data
 | 
						|
.sect .bss
 | 
						|
.sect .text
 | 
						|
 | 
						|
!  16 bits signed integer multiply
 | 
						|
!  the algorithm multiples A * B, where A = A0*2^8 + A1 and B = B0*2^8 + B1
 | 
						|
!  product is thus A0*B0*2^16 + 2^8 * (A0 * B1 + B0 * A1) + A0 * B0
 | 
						|
!  hence either A0 = 0 or B0 = 0 or overflow.
 | 
						|
!  initial part of code determines which high byte is 0 (also for negative #s)
 | 
						|
!  then the multiply is reduced to 8 x 16 bits, with the 8 bit number in the
 | 
						|
!  a register, the 16 bit number in the hl register, and the product in de
 | 
						|
!  Expects operands on stack
 | 
						|
!  Yields result in de-registers
 | 
						|
 | 
						|
.mli2:	pop h
 | 
						|
	shld .retadr	! get the return address out of the way
 | 
						|
	lxi h,255
 | 
						|
	pop d
 | 
						|
	mov a,d		! check hi byte for 0
 | 
						|
	cmp h		! h = 0
 | 
						|
	jz 1f		! jump if de is a positive 8 bit number
 | 
						|
	cmp l
 | 
						|
	jz 5f		! jump if de is a negative 8 bit number
 | 
						|
	xchg
 | 
						|
	shld .tmp1	! we ran out of scratch registers
 | 
						|
	pop h
 | 
						|
	mov a,h
 | 
						|
	cmp e
 | 
						|
	jz 7f		! jump if second operand is 8 bit negative
 | 
						|
	jmp 6f		! assume second operand is 8 bit positive
 | 
						|
 | 
						|
1:	mov a,e		! 8 bit positive number in a
 | 
						|
	pop h		! 16 bit number in hl
 | 
						|
 | 
						|
! here is the main loop of the multiplication.  the a register is shifted
 | 
						|
! right 1 bit to load the carry bit for testing.
 | 
						|
! as soon as the a register goes to zero, the loop terminates.
 | 
						|
! in most cases this requires fewer than 8 iterations.
 | 
						|
2:	lxi d,0
 | 
						|
	ora a
 | 
						|
3:	rar		! load carry bit from a
 | 
						|
	jnc 4f		! add hl to de if low bit was a 1
 | 
						|
	xchg
 | 
						|
	dad d
 | 
						|
	xchg
 | 
						|
4:	dad h
 | 
						|
	ora a		! sets zero correct and resets carry bit
 | 
						|
	jnz 3b		! if a has more bits, continue the loop
 | 
						|
	lhld .retadr	! go get return address
 | 
						|
	pchl
 | 
						|
 | 
						|
! the 8 bit operand is negative. negate both operands
 | 
						|
5:	pop h
 | 
						|
	mov a,l
 | 
						|
	cma
 | 
						|
	mov l,a
 | 
						|
	mov a,h
 | 
						|
	cma
 | 
						|
	mov h,a
 | 
						|
	inx h		! 16 bit negate is 1s complement + 1
 | 
						|
	xra a
 | 
						|
	sub e		! negate 8 bit operand
 | 
						|
	jmp 2b
 | 
						|
 | 
						|
! second operand is small and positive
 | 
						|
6:	mov a,l
 | 
						|
	lhld .tmp1
 | 
						|
	jmp 2b
 | 
						|
 | 
						|
! second operand is small and negative
 | 
						|
7:	mov e,l
 | 
						|
	lhld .tmp1
 | 
						|
	mov a,l
 | 
						|
	cma
 | 
						|
	mov l,a
 | 
						|
	mov a,h
 | 
						|
	cma
 | 
						|
	mov h,a
 | 
						|
	inx h
 | 
						|
	xra a
 | 
						|
	sub e
 | 
						|
	jmp 2b
 |