struct / union in initializer, RFE #901.
[sdcc.git] / sdcc / device / lib / mos6502 / _divulong.s
blobb16ca7b808d056f63331ea4ab65c68c9298eac33
1 ;-------------------------------------------------------------------------
2 ; _divulong.s - routine for 32 bit unsigned long division
4 ; Copyright (C) 1998, Ullrich von Bassewitz
5 ; Copyright (C) 2022, Gabriele Gorla
7 ; This library is free software; you can redistribute it and/or modify it
8 ; under the terms of the GNU General Public License as published by the
9 ; Free Software Foundation; either version 2, or (at your option) any
10 ; later version.
12 ; This library is distributed in the hope that it will be useful,
13 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ; GNU General Public License for more details.
17 ; You should have received a copy of the GNU General Public License
18 ; along with this library; see the file COPYING. If not, write to the
19 ; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
20 ; MA 02110-1301, USA.
22 ; As a special exception, if you link this library with other files,
23 ; some of which are compiled with SDCC, to produce an executable,
24 ; this library does not by itself cause the resulting executable to
25 ; be covered by the GNU General Public License. This exception does
26 ; not however invalidate any other reasons why the executable file
27 ; might be covered by the GNU General Public License.
28 ;-------------------------------------------------------------------------
30 .module _divulong
32 ;--------------------------------------------------------
33 ; exported symbols
34 ;--------------------------------------------------------
35 .globl __divulong_PARM_2
36 .globl __divulong_PARM_1
37 .globl __divslong_PARM_2
38 .globl __divslong_PARM_1
39 .globl __modulong_PARM_2
40 .globl __modulong_PARM_1
41 .globl __modslong_PARM_2
42 .globl __modslong_PARM_1
43 .globl __divulong
44 .globl ___udivmod32
46 ;--------------------------------------------------------
47 ; overlayable function parameters in zero page
48 ;--------------------------------------------------------
49 .area OSEG (PAG, OVR)
50 __divulong_PARM_1:
51 __divslong_PARM_1:
52 __modulong_PARM_1:
53 __modslong_PARM_1:
54 .ds 4
55 __divulong_PARM_2:
56 __divslong_PARM_2:
57 __modulong_PARM_2:
58 __modslong_PARM_2:
59 .ds 4
61 ;--------------------------------------------------------
62 ; local aliases
63 ;--------------------------------------------------------
64 .define res0 "__divulong_PARM_1+0"
65 .define res1 "__divulong_PARM_1+1"
66 .define res2 "___SDCC_m6502_ret2"
67 .define res3 "___SDCC_m6502_ret3"
68 .define den "__divulong_PARM_2"
69 .define rem "___SDCC_m6502_ret4"
70 .define s1 "___SDCC_m6502_ret0"
71 .define s2 "___SDCC_m6502_ret1"
73 ;--------------------------------------------------------
74 ; code
75 ;--------------------------------------------------------
76 .area CODE
78 __divulong:
79 jsr ___udivmod32
80 lda *res0
81 ldx *res1
82 rts
84 ___udivmod32:
85 ldx __divulong_PARM_1+3
86 stx *res3
87 ldx __divulong_PARM_1+2
88 stx *res2
90 lda #0
91 sta *rem+0
92 sta *rem+1
93 sta *rem+2
94 sta *rem+3
95 ldy #32
96 L0:
97 asl *res0
98 rol *res1
99 rol *res2
100 rol *res3
101 rol a
102 rol *rem+1
103 rol *rem+2
104 rol *rem+3
106 ; Do a subtraction. we do not have enough space to store the intermediate
107 ; result, so we may have to do the subtraction twice.
109 cmp *den+0
110 lda *rem+1
111 sbc *den+1
112 lda *rem+2
113 sbc *den+2
114 lda *rem+3
115 sbc *den+3
116 bcc L1
118 ; Overflow, do the subtraction again, this time store the result
119 sta *rem+3 ; We have the high byte already
121 sbc *den+0 ; byte 0
123 lda *rem+1
124 sbc *den+1
125 sta *rem+1 ; byte 1
126 lda *rem+2
127 sbc *den+2
128 sta *rem+2 ; byte 2
129 inc *res0 ; Set result bit
133 bne L0
134 sta *rem+0