divf16.asm 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. #include once <div32.asm>
  2. ;
  3. __DIVF16: ; 16.16 Fixed point Division (signed)
  4. ; DE.HL = Dividend, Stack Top = Divisor
  5. ; A = Dividend, B = Divisor => A / B
  6. lda z80_c ;- exx
  7. ldx z80_cp
  8. stx z80_c
  9. sta z80_cp
  10. lda z80_b
  11. ldx z80_bp
  12. stx z80_b
  13. sta z80_bp
  14. lda z80_e
  15. ldx z80_ep
  16. stx z80_e
  17. sta z80_ep
  18. lda z80_d
  19. ldx z80_dp
  20. stx z80_d
  21. sta z80_dp
  22. lda z80_l
  23. ldx z80_lp
  24. stx z80_l
  25. sta z80_lp
  26. lda z80_h
  27. ldx z80_hp
  28. stx z80_h
  29. sta z80_hp
  30. pla ;- pop hl ; return address
  31. sta z80_h
  32. pla
  33. sta z80_l
  34. pla ;- pop de ; low part
  35. sta z80_d
  36. pla
  37. sta z80_e
  38. tsx ;- ex (sp),hl ;- CALLEE Convention ; H'L'D'E' => Dividend
  39. lda $0103,x
  40. ldy z80_h
  41. sta z80_h
  42. tya
  43. sta $0103,x
  44. lda $0104,x
  45. ldy z80_l
  46. sta z80_l
  47. tya
  48. sta $104,x
  49. lda z80_e ;- ex de,hl ;- D'E'.H'L' Dividend
  50. ldx z80_l
  51. stx z80_e
  52. sta z80_l
  53. lda z80_d
  54. ldx z80_h
  55. stx z80_d
  56. sta z80_h
  57. __DIVF16START: ; FAST Entry: DEHL => Dividend, D'E'H'L' => Divisor
  58. lda z80_d ;- ld a,d ; Save sign
  59. sta z80_a
  60. ldx z80_ap ;- ex af,af'
  61. sta z80_ap
  62. txa
  63. lda z80_d ;- bit 7,d ; Negative?
  64. bit 7
  65. beq *+5 ;- call nz, __NEG32 ; Negates DEHL
  66. jsr __NEG32
  67. lda z80_c ;- exx ; Now works with D'E'.H'L'
  68. ldx z80_cp
  69. stx z80_c
  70. sta z80_cp
  71. lda z80_b
  72. ldx z80_bp
  73. stx z80_b
  74. sta z80_bp
  75. lda z80_e
  76. ldx z80_ep
  77. stx z80_e
  78. sta z80_ep
  79. lda z80_d
  80. ldx z80_dp
  81. stx z80_d
  82. sta z80_dp
  83. lda z80_l
  84. ldx z80_lp
  85. stx z80_l
  86. sta z80_lp
  87. lda z80_h
  88. ldx z80_hp
  89. stx z80_h
  90. sta z80_hp
  91. ldx z80_ap ;- ex af,af'
  92. sta z80_ap
  93. txa
  94. eor z80_d ;- xor d
  95. ldx z80_ap ;- ex af,af' ; Stores sign of the result for later
  96. sta z80_ap
  97. txa
  98. lda z80_d ;- bit 7,d ; Negative?
  99. bit 7
  100. beq *+5 ;- call nz, __NEG32
  101. jsr __NEG32
  102. lda z80_c ;- exx ; Now we have DE.HL => Dividend
  103. ldx z80_cp
  104. stx z80_c
  105. sta z80_cp
  106. lda z80_b
  107. ldx z80_bp
  108. stx z80_b
  109. sta z80_bp
  110. lda z80_e
  111. ldx z80_ep
  112. stx z80_e
  113. sta z80_ep
  114. lda z80_d
  115. ldx z80_dp
  116. stx z80_d
  117. sta z80_dp
  118. lda z80_l
  119. ldx z80_lp
  120. stx z80_l
  121. sta z80_lp
  122. lda z80_h
  123. ldx z80_hp
  124. stx z80_h
  125. sta z80_hp
  126. lda %16 ;- ld b,16
  127. sta z80_b
  128. __SHIFTALOOP:
  129. ; Tries to shift Dividend to the left
  130. lda z80_d ;- bit 7,d
  131. bit 7
  132. jne __SHIFTB ;- jp nz, __SHIFTB
  133. asl z80_l ;- add hl,hl
  134. rol z80_h
  135. lda z80_e ;- ex_de_hl
  136. ldx z80_l
  137. stx z80_e
  138. sta z80_l
  139. lda z80_d
  140. ldx z80_h
  141. stx z80_d
  142. sta z80_h
  143. ;- adc hl,hl
  144. lda z80_e ;- ex_de_hl
  145. ldx z80_l
  146. stx z80_e
  147. sta z80_l
  148. lda z80_d
  149. ldx z80_h
  150. stx z80_d
  151. sta z80_h
  152. ;- djnz __SHIFTALOOP
  153. jmp __DOF16_DIVRDY ;- jp __DOF16_DIVRDY
  154. __SHIFTB:
  155. ; Cannot shift Dividend more to the left, try to shift Divisor to the right
  156. lda z80_b ;- ld a,b
  157. sta z80_a
  158. lda z80_c ;- exx
  159. ldx z80_cp
  160. stx z80_c
  161. sta z80_cp
  162. lda z80_b
  163. ldx z80_bp
  164. stx z80_b
  165. sta z80_bp
  166. lda z80_e
  167. ldx z80_ep
  168. stx z80_e
  169. sta z80_ep
  170. lda z80_d
  171. ldx z80_dp
  172. stx z80_d
  173. sta z80_dp
  174. lda z80_l
  175. ldx z80_lp
  176. stx z80_l
  177. sta z80_lp
  178. lda z80_h
  179. ldx z80_hp
  180. stx z80_h
  181. sta z80_hp
  182. lda z80_a ;- ld b,a
  183. sta z80_b
  184. ; Divisor is in DEHL
  185. __SHIFTBLOOP:
  186. ;- bit 1, l
  187. jne __DOF16_DIVIDE ;- jp nz, __DOF16_DIVIDE
  188. ;- sra d
  189. ror z80_e ;- rr e
  190. ror z80_h ;- rr h
  191. ror z80_l ;- rr l
  192. dec z80_b ;- djnz __SHIFTBLOOP
  193. jne __SHIFTBLOOP
  194. __DOF16_DIVIDE:
  195. lda z80_b ;- ld a,b
  196. sta z80_a
  197. lda z80_c ;- exx
  198. ldx z80_cp
  199. stx z80_c
  200. sta z80_cp
  201. lda z80_b
  202. ldx z80_bp
  203. stx z80_b
  204. sta z80_bp
  205. lda z80_e
  206. ldx z80_ep
  207. stx z80_e
  208. sta z80_ep
  209. lda z80_d
  210. ldx z80_dp
  211. stx z80_d
  212. sta z80_dp
  213. lda z80_l
  214. ldx z80_lp
  215. stx z80_l
  216. sta z80_lp
  217. lda z80_h
  218. ldx z80_hp
  219. stx z80_h
  220. sta z80_hp
  221. lda z80_a ;- ld b,a
  222. sta z80_b
  223. __DOF16_DIVRDY:
  224. lda z80_c ;- exx
  225. ldx z80_cp
  226. stx z80_c
  227. sta z80_cp
  228. lda z80_b
  229. ldx z80_bp
  230. stx z80_b
  231. sta z80_bp
  232. lda z80_e
  233. ldx z80_ep
  234. stx z80_e
  235. sta z80_ep
  236. lda z80_d
  237. ldx z80_dp
  238. stx z80_d
  239. sta z80_dp
  240. lda z80_l
  241. ldx z80_lp
  242. stx z80_l
  243. sta z80_lp
  244. lda z80_h
  245. ldx z80_hp
  246. stx z80_h
  247. sta z80_hp
  248. lda z80_e ;- ex de,hl
  249. ldx z80_l
  250. stx z80_e
  251. sta z80_l
  252. lda z80_d
  253. ldx z80_h
  254. stx z80_d
  255. sta z80_h
  256. lda z80_c ;- push bc
  257. pha
  258. lda z80_b
  259. pha
  260. jsr __DIVU32START ;- call __DIVU32START
  261. pla ;- pop bc
  262. sta z80_b
  263. pla
  264. sta z80_c
  265. eor z80_a ;- xor a
  266. ora z80_b ;- or b
  267. jmp __ENDF16DIV ;- jp z,__ENDF16DIV
  268. __SHIFTCLOOP:
  269. asl z80_l ;- add hl,hl ; Shift DECIMAL PART << 1
  270. rol z80_h
  271. lda z80_e ;- ex_de_hl
  272. ldx z80_l
  273. stx z80_e
  274. sta z80_l
  275. lda z80_d
  276. ldx z80_h
  277. stx z80_d
  278. sta z80_h
  279. ;- adc hl,hl ; Shift INTEGER PART << 1 Plus Carry
  280. lda z80_e ;- ex_de_hl
  281. ldx z80_l
  282. stx z80_e
  283. sta z80_l
  284. lda z80_d
  285. ldx z80_h
  286. stx z80_d
  287. sta z80_h
  288. dec z80_b ;- djnz __SHIFTCLOOP
  289. jne __SHIFTCLOOP
  290. __ENDF16DIV: ; Put the sign on the result
  291. ldx z80_ap ;- ex af, af' ; Recovers sign
  292. sta z80_ap
  293. txa
  294. and #128 ;- and 128 ; positive?
  295. bne *+3 ;- ret z
  296. rts
  297. jcs __NEG32 ;- jp __NEG32 ; Negates DEHL and returns from there