]> git.sur5r.net Git - cc65/blob - libsrc/runtime/ludiv.s
54af4780e4407b74bf0e464fe366dfc1e1a4e06c
[cc65] / libsrc / runtime / ludiv.s
1 ;
2 ; Ullrich von Bassewitz, 17.08.1998
3 ; Christian Krueger, 11-Mar-2017, added 65SC02 optimization
4 ;
5 ; CC65 runtime: division for long unsigned ints
6 ;
7
8         .export         tosudiv0ax, tosudiveax, getlop, udiv32
9         .import         addysp1
10         .importzp       sp, sreg, tmp3, tmp4, ptr1, ptr2, ptr3, ptr4
11
12         .macpack        cpu
13
14 tosudiv0ax:
15 .if (.cpu .bitand ::CPU_ISET_65SC02)
16         stz     sreg
17         stz     sreg+1
18 .else
19         ldy     #$00
20         sty     sreg
21         sty     sreg+1
22 .endif
23
24 tosudiveax:                         
25         jsr     getlop          ; Get the paramameters
26         jsr     udiv32          ; Do the division
27         lda     ptr1            ; Result is in ptr1:sreg
28         ldx     ptr1+1
29         rts
30
31 ; Pop the parameters for the long division and put it into the relevant
32 ; memory cells. Called from the signed divisions also.
33
34 getlop: sta     ptr3            ; Put right operand in place
35         stx     ptr3+1
36         lda     sreg
37         sta     ptr4
38         lda     sreg+1
39         sta     ptr4+1
40
41 .if (.cpu .bitand ::CPU_ISET_65SC02)
42         lda     (sp)
43         ldy     #1
44 .else
45         ldy     #0              ; Put left operand in place
46         lda     (sp),y
47         iny
48 .endif
49         sta     ptr1
50         lda     (sp),y
51         sta     ptr1+1
52         iny
53         lda     (sp),y
54         sta     sreg
55         iny
56         lda     (sp),y
57         sta     sreg+1
58         jmp     addysp1         ; Drop parameters
59
60 ; Do (ptr1:sreg) / (ptr3:ptr4) --> (ptr1:sreg), remainder in (ptr2:tmp3:tmp4)
61 ; This is also the entry point for the signed division
62
63 udiv32: lda     #0
64         sta     ptr2+1
65         sta     tmp3
66         sta     tmp4
67 ;       sta     ptr1+1
68         ldy     #32
69 L0:     asl     ptr1
70         rol     ptr1+1
71         rol     sreg
72         rol     sreg+1
73         rol     a
74         rol     ptr2+1
75         rol     tmp3
76         rol     tmp4
77
78 ; Do a subtraction. we do not have enough space to store the intermediate
79 ; result, so we may have to do the subtraction twice.
80
81         pha
82         cmp     ptr3
83         lda     ptr2+1
84         sbc     ptr3+1
85         lda     tmp3
86         sbc     ptr4
87         lda     tmp4
88         sbc     ptr4+1
89         bcc     L1
90
91 ; Overflow, do the subtraction again, this time store the result
92
93         sta     tmp4            ; We have the high byte already
94         pla
95         sbc     ptr3            ; byte 0
96         pha
97         lda     ptr2+1
98         sbc     ptr3+1
99         sta     ptr2+1          ; byte 1
100         lda     tmp3
101         sbc     ptr4
102         sta     tmp3            ; byte 2
103         inc     ptr1            ; Set result bit
104
105 L1:     pla
106         dey
107         bne     L0
108         sta     ptr2
109         rts
110
111