1 ;
--------------------------------------------------------------------------
4 ; Copyright
(C
) 2000-2021, Michael Hope
, Philipp Klaus Krause
, Marco Bodrato
6 ; This library is free software; you can redistribute it
and/or modify it
7 ; under the terms of the GNU General Public License as published by the
8 ; Free Software Foundation; either version
2, or (at your option
) any
11 ; This library is distributed in the hope that it will
be useful
,
12 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ; MERCHANTABILITY
or FITNESS FOR
A PARTICULAR PURPOSE. See the
14 ; GNU General Public License for more details.
16 ; You should have received
a copy of the GNU General Public License
17 ; along with this library; see the file COPYING. If
not, write to the
18 ; Free Software Foundation
, 51 Franklin Street
, Fifth Floor
, Boston
,
21 ; As
a special exception
, if you link this library with other files
,
22 ; some of which are compiled with SDCC
, to produce an executable
,
23 ; this library does
not by itself cause the resulting executable to
24 ;
be covered by the GNU General Public License. This exception does
25 ;
not however invalidate any other reasons why the executable file
26 ; might
be covered by the GNU General Public License.
27 ;
--------------------------------------------------------------------------
29 ;; Originally from GBDK by Pascal Felber.
52 ; Fall through to __divu16
54 ;; unsigned
16-bit division
64 ;; If divisor is
0, quotient is set to
"infinity", i.e HL
= 0xFFFF.
66 ;; Register used
: AF
,B,DE
,HL
68 ;; Two algorithms
: one assumes divisor
<2^
7, the second
69 ;; assumes divisor
>=2^
7; choose the applicable one.
74 ;; Both algorithms
"rotate" 24 bits
(H
,L,A) but roles change.
76 ;; unsigned
16/7-bit division
78 ld b,#16 ; bits in dividend and possible quotient
79 ;; Carry cleared by
AND/OR, this
"0" bit will pass trough HL.
[*]
82 ;; HL holds both dividend
and quotient. While we shift
a bit from
83 ;; MSB of dividend
, we shift next bit of quotient in from carry.
87 ;; If remainder is
>= divisor
, next bit of quotient is
1. We try
88 ;; to compute the difference.
90 jr NC
,.nodrop7 ; Jump if remainder is >= dividend
91 add a,e ; Otherwise
, restore remainder
92 ;; The
add above sets the carry
, because sbc
a,e did set it.
94 ccf ; Complement borrow so
1 indicates
a
95 ; successful subtraction
(this is the
96 ; next bit of quotient
)
99 ;; Carry now contains the same value it contained before
100 ;; entering
.dvloop7[*]: "0" = valid result.
101 ld e
,a ; DE
= remainder
, HL
= quotient
105 ld b,#9 ; at most 9 bits in quotient.
106 ld a,l ; precompute the first
7 shifts
, by
111 ;; Shift next bit of quotient into bit
0 of dividend
112 ;; Shift next MSB of dividend into LSB of remainder
113 ;;
A holds both dividend
and quotient. While we shift
a bit from
114 ;; MSB of dividend
, we shift next bit of quotient in from carry
115 ;; HL holds remainder
116 adc hl
,hl ; HL
< 2^
(7+9), no carry
, ever.
118 ;; If remainder is
>= divisor
, next bit of quotient is
1. We try
119 ;; to compute the difference.
121 jr NC
,.nodrop ; Jump if remainder is >= dividend
122 add hl
,de ; Otherwise
, restore remainder
123 ;; The
add above sets the carry
, because sbc hl
,de did set it.
125 ccf ; Complement borrow so
1 indicates
a
126 ; successful subtraction
(this is the
127 ; next bit of quotient
)
130 ;; Take care of the ninth quotient bit
! after the loop
B=0.
132 ;; Carry now contains
"0" = valid result.
134 ld e
,a ; DE
= quotient
, HL
= remainder
135 ex de
,hl ; HL
= quotient
, DE
= remainder