div32.asm 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772
  1. #include once <neg32.asm>
  2. ;---------------------------------------------------------
  3. __DIVU32:
  4. ; 32 bit unsigned division
  5. ; DEHL = Dividend, Stack Top = Divisor
  6. ; OPERANDS P = Dividend, Q = Divisor => OPERATION => P / Q
  7. ; Changes A, BC DE HL B'C' D'E' H'L'
  8. ;---------------------------------------------------------
  9. lda z80_c ;- exx
  10. ldx z80_cp
  11. stx z80_c
  12. sta z80_cp
  13. lda z80_b
  14. ldx z80_bp
  15. stx z80_b
  16. sta z80_bp
  17. lda z80_e
  18. ldx z80_ep
  19. stx z80_e
  20. sta z80_ep
  21. lda z80_d
  22. ldx z80_dp
  23. stx z80_d
  24. sta z80_dp
  25. lda z80_l
  26. ldx z80_lp
  27. stx z80_l
  28. sta z80_lp
  29. lda z80_h
  30. ldx z80_hp
  31. stx z80_h
  32. sta z80_hp
  33. pla ;- pop hl ; return address
  34. sta z80_h
  35. pla
  36. sta z80_l
  37. sta z80_d
  38. pla
  39. sta z80_e
  40. tsx ;- ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend
  41. lda $0103,x
  42. ldy z80_h
  43. sta z80_h
  44. tya
  45. sta $0103,x
  46. lda $0104,x
  47. ldy z80_l
  48. sta z80_l
  49. tya
  50. __DIVU32START: ; Performs D'E'H'L' / HLDE
  51. ; Now switch to DIVIDEND = B'C'BC / DIVISOR = D'E'DE (A / B)
  52. lda z80_e ;- push de ; push Lowpart(Q)
  53. pha
  54. lda z80_d
  55. pha
  56. lda z80_e ;- ex de, hl ; DE = HL
  57. ldx z80_l
  58. stx z80_e
  59. sta z80_l
  60. lda z80_d
  61. ldx z80_h
  62. stx z80_d
  63. sta z80_h
  64. lda #<0 ;- ld hl, 0
  65. sta z80_l
  66. lda #>0
  67. sta z80_h
  68. lda z80_c ;- exx
  69. ldx z80_cp
  70. stx z80_c
  71. sta z80_cp
  72. lda z80_b
  73. ldx z80_bp
  74. stx z80_b
  75. sta z80_bp
  76. lda z80_e
  77. ldx z80_ep
  78. stx z80_e
  79. sta z80_ep
  80. lda z80_d
  81. ldx z80_dp
  82. stx z80_d
  83. sta z80_dp
  84. lda z80_l
  85. ldx z80_lp
  86. stx z80_l
  87. sta z80_lp
  88. lda z80_h
  89. ldx z80_hp
  90. stx z80_h
  91. sta z80_hp
  92. lda z80_c ;- ld b,c
  93. sta z80_b
  94. lda z80_l ;- ld c,l
  95. sta z80_c
  96. pla ;- pop hl
  97. sta z80_h
  98. pla
  99. sta z80_l
  100. lda z80_e ;- push de
  101. pha
  102. lda z80_d
  103. pha
  104. lda z80_e ;- ex de,hl
  105. ldx z80_l
  106. stx z80_e
  107. sta z80_l
  108. lda z80_d
  109. ldx z80_h
  110. stx z80_d
  111. sta z80_h
  112. lda #<0 ;- ld hl, 0 ; H'L'HL = 0
  113. sta z80_l
  114. lda #>0
  115. sta z80_h
  116. lda z80_c ;- exx
  117. ldx z80_cp
  118. stx z80_c
  119. sta z80_cp
  120. lda z80_b
  121. ldx z80_bp
  122. stx z80_b
  123. sta z80_bp
  124. lda z80_e
  125. ldx z80_ep
  126. stx z80_e
  127. sta z80_ep
  128. lda z80_d
  129. ldx z80_dp
  130. stx z80_d
  131. sta z80_dp
  132. lda z80_l
  133. ldx z80_lp
  134. stx z80_l
  135. sta z80_lp
  136. lda z80_h
  137. ldx z80_hp
  138. stx z80_h
  139. sta z80_hp
  140. pla ;- pop bc ; Pop HightPart(B) => B = B'C'BC
  141. sta z80_b
  142. pla
  143. sta z80_c
  144. lda z80_c ;- exx
  145. ldx z80_cp
  146. stx z80_c
  147. sta z80_cp
  148. lda z80_b
  149. ldx z80_bp
  150. stx z80_b
  151. sta z80_bp
  152. lda z80_e
  153. ldx z80_ep
  154. stx z80_e
  155. sta z80_ep
  156. lda z80_d
  157. ldx z80_dp
  158. stx z80_d
  159. sta z80_dp
  160. lda z80_l
  161. ldx z80_lp
  162. stx z80_l
  163. sta z80_lp
  164. lda z80_h
  165. ldx z80_hp
  166. stx z80_h
  167. sta z80_hp
  168. lda #32 ;- ld a,32 ; Loop count
  169. __DIV32LOOP:
  170. ;- sll c ; B'C'BC << 1 ; Output most left bit to carry
  171. rol z80_b ;- rl b
  172. lda z80_c ;- exx
  173. ldx z80_cp
  174. stx z80_c
  175. sta z80_cp
  176. lda z80_b
  177. ldx z80_bp
  178. stx z80_b
  179. sta z80_bp
  180. lda z80_e
  181. ldx z80_ep
  182. stx z80_e
  183. sta z80_ep
  184. lda z80_d
  185. ldx z80_dp
  186. stx z80_d
  187. sta z80_dp
  188. lda z80_l
  189. ldx z80_lp
  190. stx z80_l
  191. sta z80_lp
  192. lda z80_h
  193. ldx z80_hp
  194. stx z80_h
  195. sta z80_hp
  196. rol z80_c ;- rl c
  197. rol z80_b ;- rl b
  198. lda z80_c ;- exx
  199. ldx z80_cp
  200. stx z80_c
  201. sta z80_cp
  202. lda z80_b
  203. ldx z80_bp
  204. stx z80_b
  205. sta z80_bp
  206. lda z80_e
  207. ldx z80_ep
  208. stx z80_e
  209. sta z80_ep
  210. lda z80_d
  211. ldx z80_dp
  212. stx z80_d
  213. sta z80_dp
  214. lda z80_l
  215. ldx z80_lp
  216. stx z80_l
  217. sta z80_lp
  218. lda z80_h
  219. ldx z80_hp
  220. stx z80_h
  221. sta z80_hp
  222. ;- adc hl,hl
  223. lda z80_c ;- exx
  224. ldx z80_cp
  225. stx z80_c
  226. sta z80_cp
  227. lda z80_b
  228. ldx z80_bp
  229. stx z80_b
  230. sta z80_bp
  231. lda z80_e
  232. ldx z80_ep
  233. stx z80_e
  234. sta z80_ep
  235. lda z80_d
  236. ldx z80_dp
  237. stx z80_d
  238. sta z80_dp
  239. lda z80_l
  240. ldx z80_lp
  241. stx z80_l
  242. sta z80_lp
  243. lda z80_h
  244. ldx z80_hp
  245. stx z80_h
  246. sta z80_hp
  247. ;- adc hl,hl
  248. lda z80_c ;- exx
  249. ldx z80_cp
  250. stx z80_c
  251. sta z80_cp
  252. lda z80_b
  253. ldx z80_bp
  254. stx z80_b
  255. sta z80_bp
  256. lda z80_e
  257. ldx z80_ep
  258. stx z80_e
  259. sta z80_ep
  260. lda z80_d
  261. ldx z80_dp
  262. stx z80_d
  263. sta z80_dp
  264. lda z80_l
  265. ldx z80_lp
  266. stx z80_l
  267. sta z80_lp
  268. lda z80_h
  269. ldx z80_hp
  270. stx z80_h
  271. sta z80_hp
  272. ;- sbc hl,de
  273. lda z80_c ;- exx
  274. ldx z80_cp
  275. stx z80_c
  276. sta z80_cp
  277. lda z80_b
  278. ldx z80_bp
  279. stx z80_b
  280. sta z80_bp
  281. lda z80_e
  282. ldx z80_ep
  283. stx z80_e
  284. sta z80_ep
  285. lda z80_d
  286. ldx z80_dp
  287. stx z80_d
  288. sta z80_dp
  289. lda z80_l
  290. ldx z80_lp
  291. stx z80_l
  292. sta z80_lp
  293. lda z80_h
  294. ldx z80_hp
  295. stx z80_h
  296. sta z80_hp
  297. lda z80_l ;- sbc hl,de
  298. sbc z80_e
  299. sta z80_l
  300. lda z80_h
  301. sbc z80_d
  302. sta z80_h
  303. lda z80_c ;- exx
  304. ldx z80_cp
  305. stx z80_c
  306. sta z80_cp
  307. lda z80_b
  308. ldx z80_bp
  309. stx z80_b
  310. sta z80_bp
  311. lda z80_e
  312. ldx z80_ep
  313. stx z80_e
  314. sta z80_ep
  315. lda z80_d
  316. ldx z80_dp
  317. stx z80_d
  318. sta z80_dp
  319. lda z80_l
  320. ldx z80_lp
  321. stx z80_l
  322. sta z80_lp
  323. lda z80_h
  324. ldx z80_hp
  325. stx z80_h
  326. sta z80_hp
  327. jcs __DIV32NOADD ;- jp nc, __DIV32NOADD ; use JP inside a loop for being faster
  328. clc ;- add hl,de
  329. lda z80_l
  330. adc z80_e
  331. sta z80_l
  332. lda z80_h
  333. adc z80_d
  334. sta z80_h
  335. lda z80_c ;- exx
  336. ldx z80_cp
  337. stx z80_c
  338. sta z80_cp
  339. lda z80_b
  340. ldx z80_bp
  341. stx z80_b
  342. sta z80_bp
  343. lda z80_e
  344. ldx z80_ep
  345. stx z80_e
  346. sta z80_ep
  347. lda z80_d
  348. ldx z80_dp
  349. stx z80_d
  350. sta z80_dp
  351. lda z80_l
  352. ldx z80_lp
  353. stx z80_l
  354. sta z80_lp
  355. lda z80_h
  356. ldx z80_hp
  357. stx z80_h
  358. sta z80_hp
  359. ;- adc hl, de
  360. lda z80_c ;- exx
  361. ldx z80_cp
  362. stx z80_c
  363. sta z80_cp
  364. lda z80_b
  365. ldx z80_bp
  366. stx z80_b
  367. sta z80_bp
  368. lda z80_e
  369. ldx z80_ep
  370. stx z80_e
  371. sta z80_ep
  372. lda z80_d
  373. ldx z80_dp
  374. stx z80_d
  375. sta z80_dp
  376. lda z80_l
  377. ldx z80_lp
  378. stx z80_l
  379. sta z80_lp
  380. lda z80_h
  381. ldx z80_hp
  382. stx z80_h
  383. sta z80_hp
  384. ;- dec bc
  385. __DIV32NOADD:
  386. ;- dec a
  387. jne __DIV32LOOP ;- jp nz, __DIV32LOOP ; use JP inside a loop for being faster
  388. ; At this point, quotient is stored in B'C'BC and the reminder in H'L'HL
  389. lda z80_l ;- push hl
  390. pha
  391. lda z80_h
  392. pha
  393. lda z80_c ;- exx
  394. ldx z80_cp
  395. stx z80_c
  396. sta z80_cp
  397. lda z80_b
  398. ldx z80_bp
  399. stx z80_b
  400. sta z80_bp
  401. lda z80_e
  402. ldx z80_ep
  403. stx z80_e
  404. sta z80_ep
  405. lda z80_d
  406. ldx z80_dp
  407. stx z80_d
  408. sta z80_dp
  409. lda z80_l
  410. ldx z80_lp
  411. stx z80_l
  412. sta z80_lp
  413. lda z80_h
  414. ldx z80_hp
  415. stx z80_h
  416. sta z80_hp
  417. pla ;- pop de
  418. sta z80_d
  419. pla
  420. sta z80_e
  421. lda z80_e ;- ex de,hl ; D'E'H'L' = 32 bits modulus
  422. ldx z80_l
  423. stx z80_e
  424. sta z80_l
  425. lda z80_d
  426. ldx z80_h
  427. stx z80_d
  428. sta z80_h
  429. lda z80_c ;- push bc
  430. pha
  431. lda z80_b
  432. pha
  433. lda z80_c ;- exx
  434. ldx z80_cp
  435. stx z80_c
  436. sta z80_cp
  437. lda z80_b
  438. ldx z80_bp
  439. stx z80_b
  440. sta z80_bp
  441. lda z80_e
  442. ldx z80_ep
  443. stx z80_e
  444. sta z80_ep
  445. lda z80_d
  446. ldx z80_dp
  447. stx z80_d
  448. sta z80_dp
  449. lda z80_l
  450. ldx z80_lp
  451. stx z80_l
  452. sta z80_lp
  453. lda z80_h
  454. ldx z80_hp
  455. stx z80_h
  456. sta z80_hp
  457. pla ;- pop de ; DE = B'C'
  458. sta z80_d
  459. pla
  460. sta z80_e
  461. lda z80_b ;- ld h,b
  462. sta z80_h
  463. lda z80_c ;- ld l,c ; DEHL = quotient D'E'H'L' = Modulus
  464. sta z80_l
  465. rts ;- ret ; DEHL = quotient, D'E'H'L' = Modulus
  466. __MODU32: ; 32 bit modulus for 32bit unsigned division
  467. ; DEHL = Dividend, Stack Top = Divisor (DE, HL)
  468. lda z80_c ;- exx
  469. ldx z80_cp
  470. stx z80_c
  471. sta z80_cp
  472. lda z80_b
  473. ldx z80_bp
  474. stx z80_b
  475. sta z80_bp
  476. lda z80_e
  477. ldx z80_ep
  478. stx z80_e
  479. sta z80_ep
  480. lda z80_d
  481. ldx z80_dp
  482. stx z80_d
  483. sta z80_dp
  484. lda z80_l
  485. ldx z80_lp
  486. stx z80_l
  487. sta z80_lp
  488. lda z80_h
  489. ldx z80_hp
  490. stx z80_h
  491. sta z80_hp
  492. pla ;- pop hl ; return address
  493. sta z80_h
  494. pla
  495. sta z80_l
  496. pla ;- pop de ; low part
  497. sta z80_d
  498. pla
  499. sta z80_e
  500. tsx ;- ex (sp),hl ; CALLEE Convention ; H'L'D'E' => Dividend
  501. lda $0103,x
  502. ldy z80_h
  503. sta z80_h
  504. tya
  505. sta $0103,x
  506. lda $0104,x
  507. ldy z80_l
  508. sta z80_l
  509. tya
  510. sta $104,x
  511. jsr __DIVU32START ;- call __DIVU32START ; At return, modulus is at D'E'H'L'
  512. __MODU32START:
  513. lda z80_c ;- exx
  514. ldx z80_cp
  515. stx z80_c
  516. sta z80_cp
  517. lda z80_b
  518. ldx z80_bp
  519. stx z80_b
  520. sta z80_bp
  521. lda z80_e
  522. ldx z80_ep
  523. stx z80_e
  524. sta z80_ep
  525. lda z80_d
  526. ldx z80_dp
  527. stx z80_d
  528. sta z80_dp
  529. lda z80_l
  530. ldx z80_lp
  531. stx z80_l
  532. sta z80_lp
  533. lda z80_h
  534. ldx z80_hp
  535. stx z80_h
  536. sta z80_hp
  537. lda z80_e ;- push de
  538. pha
  539. lda z80_d
  540. pha
  541. lda z80_l ;- push hl
  542. pha
  543. lda z80_h
  544. pha
  545. lda z80_c ;- exx
  546. ldx z80_cp
  547. stx z80_c
  548. sta z80_cp
  549. lda z80_b
  550. ldx z80_bp
  551. stx z80_b
  552. sta z80_bp
  553. lda z80_e
  554. ldx z80_ep
  555. stx z80_e
  556. sta z80_ep
  557. lda z80_d
  558. ldx z80_dp
  559. stx z80_d
  560. sta z80_dp
  561. lda z80_l
  562. ldx z80_lp
  563. stx z80_l
  564. sta z80_lp
  565. lda z80_h
  566. ldx z80_hp
  567. stx z80_h
  568. sta z80_hp
  569. pla ;- pop hl
  570. sta z80_h
  571. pla
  572. sta z80_l
  573. pla ;- pop de
  574. sta z80_d
  575. pla
  576. sta z80_e
  577. rts ;- ret
  578. __DIVI32: ; 32 bit signed division
  579. ; DEHL = Dividend, Stack Top = Divisor
  580. ; A = Dividend, B = Divisor => A / B
  581. lda z80_c ;- exx
  582. ldx z80_cp
  583. stx z80_c
  584. sta z80_cp
  585. lda z80_b
  586. ldx z80_bp
  587. stx z80_b
  588. sta z80_bp
  589. lda z80_e
  590. ldx z80_ep
  591. stx z80_e
  592. sta z80_ep
  593. lda z80_d
  594. ldx z80_dp
  595. stx z80_d
  596. sta z80_dp
  597. lda z80_l
  598. ldx z80_lp
  599. stx z80_l
  600. sta z80_lp
  601. lda z80_h
  602. ldx z80_hp
  603. stx z80_h
  604. sta z80_hp
  605. pla ;- pop hl ; return address
  606. sta z80_h
  607. pla
  608. sta z80_l
  609. pla ;- pop de ; low part
  610. sta z80_d
  611. pla
  612. sta z80_e
  613. tsx ;- ex (sp),hl ; CALLEE Convention ; H'L'D'E' => Dividend
  614. lda $0103,x
  615. ldy z80_h
  616. sta z80_h
  617. tya
  618. sta $0103,x
  619. lda $0104,x
  620. ldy z80_l
  621. sta z80_l
  622. tya
  623. sta $104,x
  624. __DIVI32START:
  625. lda z80_c ;- exx
  626. ldx z80_cp
  627. stx z80_c
  628. sta z80_cp
  629. lda z80_b
  630. ldx z80_bp
  631. stx z80_b
  632. sta z80_bp
  633. lda z80_e
  634. ldx z80_ep
  635. stx z80_e
  636. sta z80_ep
  637. lda z80_d
  638. ldx z80_dp
  639. stx z80_d
  640. sta z80_dp
  641. lda z80_l
  642. ldx z80_lp
  643. stx z80_l
  644. sta z80_lp
  645. lda z80_h
  646. ldx z80_hp
  647. stx z80_h
  648. sta z80_hp
  649. lda z80_d ;- ld a,d ; Save sign
  650. sta z80_a
  651. ldx z80_ap ;- ex af,af'
  652. sta z80_ap
  653. txa
  654. lda z80_d ;- bit 7, d ; Negative?
  655. cmp #$80
  656. beq *+5 ;- call nz, __NEG32 ; Negates DEHL
  657. jsr __NEG32
  658. lda z80_c ;- exx ; Now works with H'L'D'E'
  659. ldx z80_cp
  660. stx z80_c
  661. sta z80_cp
  662. lda z80_b
  663. ldx z80_bp
  664. stx z80_b
  665. sta z80_bp
  666. lda z80_e
  667. ldx z80_ep
  668. stx z80_e
  669. sta z80_ep
  670. lda z80_d
  671. ldx z80_dp
  672. stx z80_d
  673. sta z80_dp
  674. lda z80_l
  675. ldx z80_lp
  676. stx z80_l
  677. sta z80_lp
  678. lda z80_h
  679. ldx z80_hp
  680. stx z80_h
  681. sta z80_hp
  682. ldx z80_ap ;- ex af,af'
  683. sta z80_ap
  684. txa
  685. eor z80_h ;- xor h
  686. ldx z80_ap ;- ex af,af' ; Stores sign of the result for later
  687. sta z80_ap
  688. txa
  689. lda z80_h ;- bit 7,h ; Negative?
  690. cmp #$80
  691. lda z80_e ;- ex de,hl ; HLDE = DEHL
  692. ldx z80_l
  693. stx z80_e
  694. sta z80_l
  695. lda z80_d
  696. ldx z80_h
  697. stx z80_d
  698. sta z80_h
  699. beq *+5 ;- call nz,__NEG32
  700. jsr __NEG32
  701. lda z80_e ;- ex de,hl
  702. ldx z80_l
  703. stx z80_e
  704. sta z80_l
  705. lda z80_d
  706. ldx z80_h
  707. stx z80_d
  708. sta z80_h
  709. jsr __DIVU32START ;- call __DIVU32START
  710. ldx z80_ap ;- ex af,af' ; Recovers sign
  711. sta z80_ap
  712. txa
  713. and 128 ;- and 128 ; positive?
  714. bne *+3 ;- ret z
  715. rts
  716. jmp __NEG32 ;- jp __NEG32 ; Negates DEHL and returns from there
  717. __MODI32: ; 32bits signed division modulus
  718. lda z80_c ;- exx
  719. ldx z80_cp
  720. stx z80_c
  721. sta z80_cp
  722. lda z80_b
  723. ldx z80_bp
  724. stx z80_b
  725. sta z80_bp
  726. lda z80_e
  727. ldx z80_ep
  728. stx z80_e
  729. sta z80_ep
  730. lda z80_d
  731. ldx z80_dp
  732. stx z80_d
  733. sta z80_dp
  734. lda z80_l
  735. ldx z80_lp
  736. stx z80_l
  737. sta z80_lp
  738. lda z80_h
  739. ldx z80_hp
  740. stx z80_h
  741. sta z80_hp
  742. pla ;- pop hl ; return address
  743. sta z80_h
  744. pla
  745. sta z80_l
  746. pla ;- pop de ; low part
  747. sta z80_d
  748. pla
  749. sta z80_e
  750. tsx ;- ex (sp),hl ; CALLEE Convention ; H'L'D'E' => Dividend
  751. lda $0103,x
  752. ldy z80_h
  753. sta z80_h
  754. tya
  755. sta $0103,x
  756. lda $0104,x
  757. ldy z80_l
  758. sta z80_l
  759. tya
  760. sta $104,x
  761. jsr __DIVI32START ;- call __DIVI32START
  762. jmp __MODU32START ;- jp __MODU32START