Announce SDCC 4.5.0 RC1.
[sdcc.git] / sdcc / device / lib / z80 / divsigned.s
blob686052a169359658d3f72b7af0b12fb9330de2de
1 ;--------------------------------------------------------------------------
2 ; divsigned.s
4 ; Copyright (C) 2000-2021, Michael Hope, Philipp Klaus Krause
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 .module divsigned
30 .optsdcc -mz80 sdcccall(1)
32 .area _CODE
34 .globl __divsint
35 .globl __divschar
37 __divschar:
38 ld e, l
39 ld l, a
41 __div8::
42 ld a, l ; Sign extend
43 rlca
44 sbc a,a
45 ld h, a
46 __div_signexte::
47 ld a, e ; Sign extend
48 rlca
49 sbc a, a
50 ld d, a
51 ; Fall through to __div16
53 ;; signed 16-bit division
55 ;; Entry conditions
56 ;; HL = dividend
57 ;; DE = divisor
59 ;; Exit conditions
60 ;; DE = quotient
61 ;; HL = remainder
63 ;; Register used: AF,B,DE,HL
64 __divsint:
65 __div16::
66 ;; Determine sign of quotient by xor-ing high bytes of dividend
67 ;; and divisor. Quotient is positive if signs are the same, negative
68 ;; if signs are different
69 ;; Remainder has same sign as dividend
70 ld a, h ; Get high byte of dividend
71 xor a, d ; Xor with high byte of divisor
72 rla ; Sign of quotient goes into the carry
73 ld a, h ; Get high byte of dividend
74 push af ; Save sign of both quotient and reminder
76 ; Take absolute value of dividend
77 rla
78 jr NC, .chkde ; Jump if dividend is positive
79 sub a, a ; Subtract dividend from 0
80 sub a, l
81 ld l, a
82 sbc a, a ; Propagate borrow (A=0xFF if borrow)
83 sub a, h
84 ld h, a
86 ; Take absolute value of divisor
87 .chkde:
88 bit 7, d
89 jr Z, .dodiv ; Jump if divisor is positive
90 sub a, a ; Subtract divisor from 0
91 sub a, e
92 ld e, a
93 sbc a, a ; Propagate borrow (A=0xFF if borrow)
94 sub a, d
95 ld d, a
97 ; Divide absolute values
98 .dodiv:
99 call __divu16
101 .fix_quotient:
102 ; Negate quotient if it is negative
103 pop af ; recover sign of quotient
104 ret NC ; Jump if quotient is positive
105 ld b, a
106 sub a, a ; Subtract quotient from 0
107 sub a, e
108 ld e, a
109 sbc a, a ; Propagate borrow (A=0xFF if borrow)
110 sub a, d
111 ld d, a
112 ld a, b
115 __get_remainder::
116 ; Negate remainder if it is negative.
118 ex de, hl
119 ret NC ; Return if remainder is positive
120 sub a, a ; Subtract quotient from 0
121 sub a, e
122 ld e, a
123 sbc a, a ; Propagate borrow (A=0xFF if borrow)
124 sub a, d
125 ld d, a