12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- .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
|