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.
45 ; Fall through to __divu16
47 ;; unsigned
16-bit division
57 ;; If divisor is
0, quotient is set to
"infinity", i.e HL
= 0xFFFF.
59 ;; Register used
: AF
,B,DE
,HL
62 ;; Two algorithms
: one assumes divisor
<2^
7, the second
63 ;; assumes divisor
>=2^
7; choose the applicable one.
68 ;; Both algorithms
"rotate" 24 bits
(H
,L,A) but roles change.
70 ;; unsigned
16/7-bit division
72 ld b,#16 ; bits in dividend and possible quotient
73 ;; Carry cleared by
AND/OR, this
"0" bit will pass trough HL.
[*]
76 ;; HL holds both dividend
and quotient. While we shift
a bit from
77 ;; MSB of dividend
, we shift next bit of quotient in from carry.
81 ;; If remainder is
>= divisor
, next bit of quotient is
1. We try
82 ;; to compute the difference.
84 jr NC
,.nodrop7 ; Jump if remainder is >= dividend
85 add a,e ; Otherwise
, restore remainder
86 ;; The
add above sets the carry
, because sbc
a,e did set it.
88 ccf ; Complement borrow so
1 indicates
a
89 ; successful subtraction
(this is the
90 ; next bit of quotient
)
93 ;; Carry now contains the same value it contained before
94 ;; entering
.dvloop7[*]: "0" = valid result.
95 ld e
,a ; DE
= remainder
, HL
= quotient
100 ld b,#9 ; at most 9 bits in quotient.
101 ld a,l ; precompute the first
7 shifts
, by
106 ;; Shift next bit of quotient into bit
0 of dividend
107 ;; Shift next MSB of dividend into LSB of remainder
108 ;;
A holds both dividend
and quotient. While we shift
a bit from
109 ;; MSB of dividend
, we shift next bit of quotient in from carry
110 ;; HL holds remainder
111 adc hl
,hl ; HL
< 2^
(7+9), no carry
, ever.
113 ;; If remainder is
>= divisor
, next bit of quotient is
1. We try
114 ;; to compute the difference.
116 jr NC
,.nodrop ; Jump if remainder is >= dividend
117 add hl
,de ; Otherwise
, restore remainder
118 ;; The
add above sets the carry
, because sbc hl
,de did set it.
120 ccf ; Complement borrow so
1 indicates
a
121 ; successful subtraction
(this is the
122 ; next bit of quotient
)
125 ;; Take care of the ninth quotient bit
! after the loop
B=0.
127 ;; Carry now contains
"0" = valid result.
129 ld e
,a ; DE
= quotient
, HL
= remainder