struct / union in initializer, RFE #901.
[sdcc.git] / sdcc / device / lib / r2ka / divsigned.s
blob1a04429939569d333a1938af02b81a735f4c068a
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 .area _CODE
31 .globl __divsint
32 .globl __divschar
34 __divsint:
35 pop iy
36 pop de
38 call __div16
40 jp (iy)
42 __divschar:
43 ld e, l
44 ld l, a
46 __div8::
47 ld a, l ; Sign extend
48 rlca
49 sbc a,a
50 ld h, a
51 __div_signexte::
52 ld a, e ; Sign extend
53 rlca
54 sbc a, a
55 ld d, a
56 ; Fall through to __div16
58 ;; signed 16-bit division
60 ;; Entry conditions
61 ;; HL = dividend
62 ;; DE = divisor
64 ;; Exit conditions
65 ;; HL = quotient
66 ;; DE = remainder
68 ;; Register used: AF,B,DE,HL
69 __div16::
70 ;; Determine sign of quotient by xor-ing high bytes of dividend
71 ;; and divisor. Quotient is positive if signs are the same, negative
72 ;; if signs are different
73 ;; Remainder has same sign as dividend
74 ld a, h ; Get high byte of dividend
75 xor a, d ; Xor with high byte of divisor
76 rla ; Sign of quotient goes into the carry
77 ld a, h ; Get high byte of dividend
78 push af ; Save sign of both quotient and reminder
80 ; Take absolute value of dividend
81 rla
82 jr NC, .chkde ; Jump if dividend is positive
83 sub a, a ; Subtract dividend from 0
84 sub a, l
85 ld l, a
86 sbc a, a ; Propagate borrow (A=0xFF if borrow)
87 sub a, h
88 ld h, a
90 ; Take absolute value of divisor
91 .chkde:
92 bit 7, d
93 jr Z, .dodiv ; Jump if divisor is positive
94 sub a, a ; Subtract divisor from 0
95 sub a, e
96 ld e, a
97 sbc a, a ; Propagate borrow (A=0xFF if borrow)
98 sub a, d
99 ld d, a
101 ; Divide absolute values
102 .dodiv:
103 call __divu16
105 .fix_quotient:
106 ; Negate quotient if it is negative
107 pop af ; recover sign of quotient
108 ret NC ; Jump if quotient is positive
109 ld b, a
110 sub a, a ; Subtract quotient from 0
111 sub a, l
112 ld l, a
113 sbc a, a ; Propagate borrow (A=0xFF if borrow)
114 sub a, h
115 ld h, a
116 ld a, b
119 __get_remainder::
120 ; Negate remainder if it is negative and move it into hl
122 ex de, hl
123 ret NC ; Return if remainder is positive
124 sub a, a ; Subtract remainder from 0
125 sub a, l
126 ld l, a
127 sbc a, a ; Propagate remainder (A=0xFF if borrow)
128 sub a, h
129 ld h, a