mli2.s 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. .define .mli2
  2. .sect .text
  3. .sect .rom
  4. .sect .data
  5. .sect .bss
  6. .sect .text
  7. ! 16 bits signed integer multiply
  8. ! the algorithm multiples A * B, where A = A0*2^8 + A1 and B = B0*2^8 + B1
  9. ! product is thus A0*B0*2^16 + 2^8 * (A0 * B1 + B0 * A1) + A0 * B0
  10. ! hence either A0 = 0 or B0 = 0 or overflow.
  11. ! initial part of code determines which high byte is 0 (also for negative #s)
  12. ! then the multiply is reduced to 8 x 16 bits, with the 8 bit number in the
  13. ! a register, the 16 bit number in the hl register, and the product in de
  14. ! Expects operands on stack
  15. ! Yields result in de-registers
  16. .mli2: pop h
  17. shld .retadr ! get the return address out of the way
  18. lxi h,255
  19. pop d
  20. mov a,d ! check hi byte for 0
  21. cmp h ! h = 0
  22. jz 1f ! jump if de is a positive 8 bit number
  23. cmp l
  24. jz 5f ! jump if de is a negative 8 bit number
  25. xchg
  26. shld .tmp1 ! we ran out of scratch registers
  27. pop h
  28. mov a,h
  29. cmp e
  30. jz 7f ! jump if second operand is 8 bit negative
  31. jmp 6f ! assume second operand is 8 bit positive
  32. 1: mov a,e ! 8 bit positive number in a
  33. pop h ! 16 bit number in hl
  34. ! here is the main loop of the multiplication. the a register is shifted
  35. ! right 1 bit to load the carry bit for testing.
  36. ! as soon as the a register goes to zero, the loop terminates.
  37. ! in most cases this requires fewer than 8 iterations.
  38. 2: lxi d,0
  39. ora a
  40. 3: rar ! load carry bit from a
  41. jnc 4f ! add hl to de if low bit was a 1
  42. xchg
  43. dad d
  44. xchg
  45. 4: dad h
  46. ora a ! sets zero correct and resets carry bit
  47. jnz 3b ! if a has more bits, continue the loop
  48. lhld .retadr ! go get return address
  49. pchl
  50. ! the 8 bit operand is negative. negate both operands
  51. 5: pop h
  52. mov a,l
  53. cma
  54. mov l,a
  55. mov a,h
  56. cma
  57. mov h,a
  58. inx h ! 16 bit negate is 1s complement + 1
  59. xra a
  60. sub e ! negate 8 bit operand
  61. jmp 2b
  62. ! second operand is small and positive
  63. 6: mov a,l
  64. lhld .tmp1
  65. jmp 2b
  66. ! second operand is small and negative
  67. 7: mov e,l
  68. lhld .tmp1
  69. mov a,l
  70. cma
  71. mov l,a
  72. mov a,h
  73. cma
  74. mov h,a
  75. inx h
  76. xra a
  77. sub e
  78. jmp 2b