]> git.sur5r.net Git - cc65/blob - libsrc/runtime/lshr.s
Fixed a bug
[cc65] / libsrc / runtime / lshr.s
1 ;
2 ; Ullrich von Bassewitz, 20.09.1998
3 ;
4 ; CC65 runtime: right shift support for longs
5 ;
6
7
8         .export         tosasreax, tosshreax
9         .import         addysp1
10         .importzp       sp, sreg, ptr1, ptr2
11
12 ; --------------------------------------------------------------------
13 ; signed shift
14
15 .proc   tosasreax
16
17         jsr     getlhs          ; Get the lhs from the stack
18
19         jsr     checkovf        ; Check for overflow
20         bcs     L6              ; Jump if shift count too large
21
22         cpy     #0              ; Shift count zero?
23         beq     L5
24
25 ; We must shift. Shift by multiples of eight if possible
26
27         tya
28 L1:     cmp     #8
29         bcc     L3
30         sbc     #8
31         ldx     ptr1+1
32         stx     ptr1
33         ldx     ptr2
34         stx     ptr1+1
35         ldy     #0
36         ldx     ptr2+1
37         stx     ptr2
38         bpl     L2
39         dey                     ; Get sign
40 L2:     sty     ptr2+1
41         jmp     L1
42
43 ; Shift count is now less than eight. Do a real shift.
44                 
45 L3:     tay                     ; Shift count to Y
46         lda     ptr2+1          ; Get one byte into A for speed
47         cpy     #0
48         beq     L4a             ; Jump if done
49 L4:     cmp     #$80            ; Get sign bit into C
50         ror     a
51         ror     ptr2
52         ror     ptr1+1
53         ror     ptr1
54         dey
55         bne     L4
56
57 ; Put the result in place
58
59 L4a:    sta     sreg+1
60         lda     ptr2
61         sta     sreg
62         ldx     ptr1+1
63         lda     ptr1
64 L5:     rts
65
66 ; Jump here if shift count overflow
67
68 L6:     ldx     #0
69         lda     ptr2+1          ; Check sign
70         bpl     L7
71         dex
72 L7:     stx     sreg+1
73         stx     sreg
74         txa
75         rts
76
77 .endproc
78
79 ; --------------------------------------------------------------------
80 ; unsigned shift
81
82 .proc   tosshreax
83
84         jsr     getlhs          ; Get the lhs from the stack
85
86         jsr     checkovf        ; Check for overflow
87         bcs     L6              ; Jump if shift count too large
88
89         cpy     #0              ; Shift count zero?
90         beq     L5
91
92 ; We must shift. Shift by multiples of eight if possible
93
94         tya
95 L1:     cmp     #8
96         bcc     L3
97         sbc     #8
98         ldx     ptr1+1
99         stx     ptr1
100         ldx     ptr2
101         stx     ptr1+1
102         ldx     ptr2+1
103         stx     ptr2
104         ldx     #0
105         stx     ptr2+1
106         beq     L1
107
108 ; Shift count is now less than eight. Do a real shift.
109
110 L3:     tay                     ; Shift count to Y
111         lda     ptr2+1          ; Get one byte into A for speed
112         cpy     #0
113         beq     L4a             ; Jump if done
114 L4:     lsr     a
115         ror     ptr2
116         ror     ptr1+1
117         ror     ptr1
118         dey
119         bne     L4
120
121 ; Put the result in place
122
123 L4a:    sta     sreg+1
124         lda     ptr2
125         sta     sreg
126         ldx     ptr1+1
127         lda     ptr1
128 L5:     rts
129
130 ; Jump here if shift count overflow
131
132 L6:     lda     #0
133         sta     sreg+1
134         sta     sreg
135         tax
136         rts
137
138 .endproc
139
140 ; --------------------------------------------------------------------
141 ; Helpers
142
143 .proc   getlhs                  ; Get the lhs from stack into ptr1/ptr2
144
145         pha
146         ldy     #0
147         lda     (sp),y
148         sta     ptr1
149         iny
150         lda     (sp),y
151         sta     ptr1+1
152         iny
153         lda     (sp),y
154         sta     ptr2
155         iny
156         lda     (sp),y
157         sta     ptr2+1
158         pla
159         jmp     addysp1
160
161 .endproc
162
163
164 .proc   checkovf                ; Check for shift overflow
165
166         tay                     ; Low byte of shift count into y
167         txa                     ; Get byte 2
168         ora     sreg
169         ora     sreg+1          ; Check high 24 bit
170         bne     TooLarge        ; Shift count too large
171         cpy     #32
172         bcc     Ok
173 TooLarge:
174         sec
175 Ok:     rts
176
177 .endproc
178
179
180
181
182
183
184
185