bcd.asm 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. DivideBCDPredef::
  2. DivideBCDPredef2::
  3. DivideBCDPredef3::
  4. DivideBCDPredef4::
  5. call GetPredefRegisters
  6. DivideBCD::
  7. xor a
  8. ld [hDivideBCDBuffer], a
  9. ld [hDivideBCDBuffer+1], a
  10. ld [hDivideBCDBuffer+2], a
  11. ld d, $1
  12. .mulBy10Loop
  13. ; multiply the divisor by 10 until the leading digit is nonzero
  14. ; to set up the standard long division algorithm
  15. ld a, [hDivideBCDDivisor]
  16. and $f0
  17. jr nz, .next
  18. inc d
  19. ld a, [hDivideBCDDivisor]
  20. swap a
  21. and $f0
  22. ld b, a
  23. ld a, [hDivideBCDDivisor+1]
  24. swap a
  25. ld [hDivideBCDDivisor+1], a
  26. and $f
  27. or b
  28. ld [hDivideBCDDivisor], a
  29. ld a, [hDivideBCDDivisor+1]
  30. and $f0
  31. ld b, a
  32. ld a, [hDivideBCDDivisor+2]
  33. swap a
  34. ld [hDivideBCDDivisor+2], a
  35. and $f
  36. or b
  37. ld [hDivideBCDDivisor+1], a
  38. ld a, [hDivideBCDDivisor+2]
  39. and $f0
  40. ld [hDivideBCDDivisor+2], a
  41. jr .mulBy10Loop
  42. .next
  43. push de
  44. push de
  45. call DivideBCD_getNextDigit
  46. pop de
  47. ld a, b
  48. swap a
  49. and $f0
  50. ld [hDivideBCDBuffer], a
  51. dec d
  52. jr z, .next2
  53. push de
  54. call DivideBCD_divDivisorBy10
  55. call DivideBCD_getNextDigit
  56. pop de
  57. ld a, [hDivideBCDBuffer]
  58. or b
  59. ld [hDivideBCDBuffer], a
  60. dec d
  61. jr z, .next2
  62. push de
  63. call DivideBCD_divDivisorBy10
  64. call DivideBCD_getNextDigit
  65. pop de
  66. ld a, b
  67. swap a
  68. and $f0
  69. ld [hDivideBCDBuffer+1], a
  70. dec d
  71. jr z, .next2
  72. push de
  73. call DivideBCD_divDivisorBy10
  74. call DivideBCD_getNextDigit
  75. pop de
  76. ld a, [hDivideBCDBuffer+1]
  77. or b
  78. ld [hDivideBCDBuffer+1], a
  79. dec d
  80. jr z, .next2
  81. push de
  82. call DivideBCD_divDivisorBy10
  83. call DivideBCD_getNextDigit
  84. pop de
  85. ld a, b
  86. swap a
  87. and $f0
  88. ld [hDivideBCDBuffer+2], a
  89. dec d
  90. jr z, .next2
  91. push de
  92. call DivideBCD_divDivisorBy10
  93. call DivideBCD_getNextDigit
  94. pop de
  95. ld a, [hDivideBCDBuffer+2]
  96. or b
  97. ld [hDivideBCDBuffer+2], a
  98. .next2
  99. ld a, [hDivideBCDBuffer]
  100. ld [hDivideBCDQuotient], a ; the same memory location as hDivideBCDDivisor
  101. ld a, [hDivideBCDBuffer+1]
  102. ld [hDivideBCDQuotient+1], a
  103. ld a, [hDivideBCDBuffer+2]
  104. ld [hDivideBCDQuotient+2], a
  105. pop de
  106. ld a, $6
  107. sub d
  108. and a
  109. ret z
  110. .divResultBy10loop
  111. push af
  112. call DivideBCD_divDivisorBy10
  113. pop af
  114. dec a
  115. jr nz, .divResultBy10loop
  116. ret
  117. DivideBCD_divDivisorBy10:
  118. ld a, [hDivideBCDDivisor+2]
  119. swap a
  120. and $f
  121. ld b, a
  122. ld a, [hDivideBCDDivisor+1]
  123. swap a
  124. ld [hDivideBCDDivisor+1], a
  125. and $f0
  126. or b
  127. ld [hDivideBCDDivisor+2], a
  128. ld a, [hDivideBCDDivisor+1]
  129. and $f
  130. ld b, a
  131. ld a, [hDivideBCDDivisor]
  132. swap a
  133. ld [hDivideBCDDivisor], a
  134. and $f0
  135. or b
  136. ld [hDivideBCDDivisor+1], a
  137. ld a, [hDivideBCDDivisor]
  138. and $f
  139. ld [hDivideBCDDivisor], a
  140. ret
  141. DivideBCD_getNextDigit:
  142. ld bc, $3
  143. .loop
  144. ld de, hMoney ; the dividend
  145. ld hl, hDivideBCDDivisor
  146. push bc
  147. call StringCmp
  148. pop bc
  149. ret c
  150. inc b
  151. ld de, hMoney+2 ; since SubBCD works starting from the least significant digit
  152. ld hl, hDivideBCDDivisor+2
  153. push bc
  154. call SubBCD
  155. pop bc
  156. jr .loop
  157. AddBCDPredef::
  158. call GetPredefRegisters
  159. AddBCD::
  160. and a
  161. ld b, c
  162. .add
  163. ld a, [de]
  164. adc [hl]
  165. daa
  166. ld [de], a
  167. dec de
  168. dec hl
  169. dec c
  170. jr nz, .add
  171. jr nc, .done
  172. ld a, $99
  173. inc de
  174. .fill
  175. ld [de], a
  176. inc de
  177. dec b
  178. jr nz, .fill
  179. .done
  180. ret
  181. SubBCDPredef::
  182. call GetPredefRegisters
  183. SubBCD::
  184. and a
  185. ld b, c
  186. .sub
  187. ld a, [de]
  188. sbc [hl]
  189. daa
  190. ld [de], a
  191. dec de
  192. dec hl
  193. dec c
  194. jr nz, .sub
  195. jr nc, .done
  196. ld a, $00
  197. inc de
  198. .fill
  199. ld [de], a
  200. inc de
  201. dec b
  202. jr nz, .fill
  203. scf
  204. .done
  205. ret