dvi4.s 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. .define .dvi4
  2. .sect .text
  3. .sect .rom
  4. .sect .data
  5. .sect .bss
  6. .sect .text
  7. ! 32 bits integer divide and remainder routine
  8. ! Bit 0 of a-reg is set iff quotient has to be delivered
  9. ! Bit 7 of a-reg is set iff the operands are signed, so:
  10. ! Expects in a-reg: 0 if called by rmu 4
  11. ! 1 if called by dvu 4
  12. ! 128 if called by rmi 4
  13. ! 129 if called by dvi 4
  14. ! Expects on stack: divisor
  15. ! dividend
  16. ! Yields on stack: quotient or remainder
  17. .dvi4: pop h
  18. shld .retadr
  19. mov h,b
  20. mov l,c
  21. shld .bcreg
  22. sta .areg
  23. pop h ! store divisor
  24. shld block3
  25. xchg
  26. pop h
  27. shld block3+2
  28. dad d
  29. jc 1f
  30. mov a,l
  31. ora h
  32. cz eidivz ! trap if divisor = 0
  33. 1: pop h ! store dividend
  34. shld block1
  35. pop h
  36. shld block1+2
  37. lxi h,0 ! store initial value of remainder
  38. shld block2
  39. shld block2+2
  40. mvi b,0
  41. lda .areg
  42. ral
  43. jnc 2f ! jump if unsigned
  44. lda block1+3
  45. ral
  46. jnc 1f
  47. mvi b,129
  48. lxi h,block1
  49. call compl ! dividend is positive now
  50. 1: lda block3+3
  51. ral
  52. jnc 2f
  53. inr b
  54. lxi h,block3
  55. call compl ! divisor is positive now
  56. 2: push b ! save b-reg
  57. mvi b,32
  58. dv0: lxi h,block1 ! left shift: block2 <- block1 <- 0
  59. mvi c,8
  60. xra a
  61. 1: mov a,m
  62. ral
  63. mov m,a
  64. inx h
  65. dcr c
  66. jnz 1b
  67. lxi h,block2+3 ! which is larger: divisor or remainder?
  68. lxi d,block3+3
  69. mvi c,4
  70. 1: ldax d
  71. cmp m
  72. jz 0f
  73. jnc 3f
  74. jmp 4f
  75. 0: dcx d
  76. dcx h
  77. dcr c
  78. jnz 1b
  79. 4: lxi d,block2 ! remainder is larger or equal: subtract divisor
  80. lxi h,block3
  81. mvi c,4
  82. xra a
  83. 1: ldax d
  84. sbb m
  85. stax d
  86. inx d
  87. inx h
  88. dcr c
  89. jnz 1b
  90. lxi h,block1
  91. inr m
  92. 3: dcr b
  93. jnz dv0 ! keep looping
  94. pop b
  95. lda .areg ! quotient or remainder?
  96. rar
  97. jnc 4f
  98. ! for dvi 4 and dvu 4 only:
  99. mov a,b
  100. rar
  101. lxi h,block1 ! complement quotient if divisor
  102. cc compl ! and dividend have different signs
  103. lhld block1+2 ! push quotient
  104. push h
  105. lhld block1
  106. push h
  107. jmp 5f
  108. ! for rmi 4 and rmu 4 only:
  109. 4: mov a,b
  110. ral
  111. lxi h,block2
  112. cc compl ! negate remainder if dividend was negative
  113. lhld block2+2
  114. push h
  115. lhld block2
  116. push h
  117. 5: lhld .bcreg
  118. mov b,h
  119. mov c,l
  120. lhld .retadr
  121. pchl
  122. ! make 2's complement of 4 bytes pointed to by hl.
  123. compl: push b
  124. mvi c,4
  125. xra a
  126. 1: mvi a,0
  127. sbb m
  128. mov m,a
  129. inx h
  130. dcr c
  131. jnz 1b
  132. pop b
  133. ret