div16.asm 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. ; 16 bit division and modulo functions
  2. ; for both signed and unsigned values
  3. ;
  4. #include once <neg16.asm>
  5. ;
  6. __DIVU16: ; 16 bit unsigned division
  7. ; HL = Dividend, Stack Top = Divisor
  8. ; -- OBSOLETE ; Now uses FASTCALL convention
  9. ; ex de, hl
  10. ; pop hl ; Return address
  11. ; ex (sp), hl ; CALLEE Convention
  12. __DIVU16_FAST:
  13. lda z80_h ;- ld a,h
  14. sta z80_a
  15. lda z80_l ;- ld c,l
  16. sta z80_c
  17. lda #0 ;- ld hl,0
  18. sta z80_l
  19. lda #0
  20. sta z80_h
  21. lda #16 ;- ld b,16
  22. sta z80_b
  23. __DIV16LOOP:
  24. ;- sll c
  25. ;- rla
  26. lda z80_l ;- adc hl,hl
  27. adc z80_l
  28. sta z80_l
  29. lda z80_h
  30. adc z80_h
  31. sta z80_h
  32. ;- sbc hl,de
  33. jcs __DIV16NOADD ;- jr nc, __DIV16NOADD
  34. clc ;- add hl,de
  35. lda z80_l
  36. adc z80_e
  37. sta z80_l
  38. lda z80_h
  39. adc z80_d
  40. sta z80_h
  41. dec z80_c ;- dec c
  42. __DIV16NOADD:
  43. ;- djnz __DIV16LOOP
  44. lda z80_e ;- ex de,hl
  45. ldx z80_l
  46. stx z80_e
  47. sta z80_l
  48. lda z80_d
  49. ldx z80_h
  50. stx z80_d
  51. sta z80_h
  52. lda z80_a ;- ld h,a
  53. sta z80_h
  54. lda z80_c ;- ld l,c
  55. sta z80_l
  56. rts ;- ret ; HL = quotient, DE = Mudulus
  57. __MODU16: ; 16 bit modulus
  58. ; HL = Dividend, Stack Top = Divisor
  59. ;ex de, hl
  60. ;pop hl
  61. ;ex (sp), hl ; CALLEE Convention
  62. jsr __DIVU16_FAST ;- call __DIVU16_FAST
  63. lda z80_e ;- ex de, hl ; hl = reminder (modulus)
  64. ldx z80_l
  65. stx z80_e
  66. sta z80_l
  67. lda z80_d
  68. ldx z80_h
  69. stx z80_d
  70. sta z80_h
  71. ; de = quotient
  72. rts ;- ret
  73. __DIVI16: ; 16 bit signed division
  74. ; --- The following is OBSOLETE ---
  75. ; ex de, hl
  76. ; pop hl
  77. ; ex (sp), hl ; CALLEE Convention
  78. __DIVI16_FAST:
  79. lda z80_d ;- ld a,d
  80. sta z80_a
  81. eor z80_h ;- xor h
  82. ldx z80_ap ;- ex af,af' ; BIT 7 of a contains result
  83. sta z80_ap
  84. txa
  85. lda z80_d ;- bit 7,d ; DE is negative?
  86. bit 7
  87. jeq __DIVI16A ;- jr z, __DIVI16A
  88. lda z80_e ;- ld a,e ; DE = -DE
  89. sta z80_a
  90. eor #$ff ;- cpl
  91. lda z80_a ;- ld e,a
  92. sta z80_e
  93. lda z80_d ;- ld a,d
  94. sta z80_a
  95. eor #$ff ;- cpl
  96. lda z80_a ;- ld d,a
  97. sta z80_d
  98. inc z80_e ;- inc de
  99. bne *+4
  100. inc z80_d
  101. __DIVI16A:
  102. lda z80_h ;- bit 7,h ; HL is negative?
  103. bit 7
  104. beq *+5 ;- call nz, __NEGHL
  105. jsr __NEGHL
  106. __DIVI16B:
  107. jsr __DIVU16_FAST ;- call __DIVU16_FAST
  108. ldx z80_ap ;- ex af,af'
  109. sta z80_ap
  110. txa
  111. ora z80_a ;- or a
  112. bmi *+3 ;- ret p ; return if positive
  113. rts
  114. jmp __NEGHL ;- jp __NEGHL
  115. __MODI16: ; 16 bit modulus
  116. ; HL = Dividend, Stack Top = Divisor
  117. ;ex de, hl
  118. ;pop hl
  119. ;ex (sp), hl ; CALLEE Convention
  120. jsr __DIVI16_FAST ;- call __DIVI16_FAST
  121. lda z80_e ;- ex de,hl ; hl = reminder (modulus)
  122. ldx z80_l
  123. stx z80_e
  124. sta z80_l
  125. lda z80_d
  126. ldx z80_h
  127. stx z80_d
  128. sta z80_h
  129. ; de = quotient
  130. rts ;- ret