struct / union in initializer, RFE #901.
[sdcc.git] / sdcc / device / lib / r3ka / divunsigned.s
blobe5c5781f9731807a7bd86790f99fe6c124a94d28
1 ;--------------------------------------------------------------------------
2 ; divunsigned.s
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
9 ; later version.
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,
19 ; MA 02110-1301, USA.
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.
31 .area _CODE
33 .globl __divuint
34 .globl __divuchar
36 __divuint:
37 pop iy
38 pop de
40 call __divu16
42 jp (iy)
44 __divuchar:
45 ld e, l
46 ld l, a
48 ;; Fall through
49 __divu8::
50 ld h,#0x00
51 ld d,h
52 ; Fall through to __divu16
54 ;; unsigned 16-bit division
56 ;; Entry conditions
57 ;; HL = dividend
58 ;; DE = divisor
60 ;; Exit conditions
61 ;; HL = quotient
62 ;; DE = remainder
63 ;; carry = 0
64 ;; If divisor is 0, quotient is set to "infinity", i.e HL = 0xFFFF.
66 ;; Register used: AF,B,DE,HL
67 __divu16::
68 ;; Two algorithms: one assumes divisor <2^7, the second
69 ;; assumes divisor >=2^7; choose the applicable one.
70 ld a,e
71 and a,#0x80
72 or a,d
73 jr NZ,.morethan7bits
74 ;; Both algorithms "rotate" 24 bits (H,L,A) but roles change.
76 ;; unsigned 16/7-bit division
77 .atmost7bits:
78 ld b,#16 ; bits in dividend and possible quotient
79 ;; Carry cleared by AND/OR, this "0" bit will pass trough HL.[*]
80 adc hl,hl
81 .dvloop7:
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.
84 ;; A holds remainder.
85 rla
87 ;; If remainder is >= divisor, next bit of quotient is 1. We try
88 ;; to compute the difference.
89 sub a,e
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.
93 .nodrop7:
94 ccf ; Complement borrow so 1 indicates a
95 ; successful subtraction (this is the
96 ; next bit of quotient)
97 adc hl,hl
98 djnz .dvloop7
99 ;; Carry now contains the same value it contained before
100 ;; entering .dvloop7[*]: "0" = valid result.
101 ld e,a ; DE = remainder, HL = quotient
104 .morethan7bits:
105 ld b,#9 ; at most 9 bits in quotient.
106 ld a,l ; precompute the first 7 shifts, by
107 ld l,h ; doing 8
108 ld h,#0
109 rr l ; undoing 1
110 .dvloop:
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.
120 sbc hl,de
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.
124 .nodrop:
125 ccf ; Complement borrow so 1 indicates a
126 ; successful subtraction (this is the
127 ; next bit of quotient)
129 djnz .dvloop
130 ;; Take care of the ninth quotient bit! after the loop B=0.
131 rl b ; BA = quotient
132 ;; Carry now contains "0" = valid result.
133 ld d,b
134 ld e,a ; DE = quotient, HL = remainder
135 ex de,hl ; HL = quotient, DE = remainder