]> git.sur5r.net Git - cc65/blob - libsrc/runtime/shr.s
Split of the lruntime module
[cc65] / libsrc / runtime / shr.s
1 ;
2 ; Ullrich von Bassewitz, 05.08.1998
3 ;
4 ; CC65 runtime: right shift support for ints
5 ;
6
7
8 ; --------------------------------------------------------------------
9 ; signed shift
10
11         .export         tosasra0, tosasrax
12         .import         popsreg, return0
13         .importzp       sreg
14
15 tosasra0:
16         ldx     #0
17 tosasrax:
18         jsr     popsreg         ; get TOS into sreg
19         cpx     #0
20         bne     TooLarge
21         cmp     #16
22         bcs     TooLarge
23
24         cmp     #8              ; Shift count greater 8?
25         beq     L4              ; Jump if exactly 8
26         bcc     L2              ; Jump if no
27
28 ; Shift count is greater 8. Do the first 8 bits the fast way
29
30         ldy     #0
31         ldx     sreg+1
32         stx     sreg
33         bpl     L1
34         dey                     ; Create correct sign bits
35 L1:     sty     sreg+1
36         sec
37         sbc     #8
38
39 ; Shift count less than 8 if we come here
40
41 L2:     tay                     ; Shift count --> Y
42         beq     Zero            ; Done if shift count zero
43
44         lda     sreg            ; get low byte for faster shift
45         ldx     sreg+1          ; get high byte
46
47 ; Do the actual shift
48
49 L3:     cpx     #$80            ; get bit 7 into carry
50         ror     sreg+1
51         ror     a
52         dey
53         bne     L3
54
55 ; Done with shift
56
57         ldx     sreg+1
58         rts
59
60 ; Shift count == 8
61
62 L4:     lda     sreg+1          ; X is zero
63         bpl     *+3
64         dex                     ; X == 0xFF
65         rts
66
67 ; Shift count was zero
68
69 Zero:   lda     sreg
70         ldx     sreg+1
71         rts
72
73 ; Shift count too large, result is zero
74
75 TooLarge:
76         jmp     return0
77
78
79 ; --------------------------------------------------------------------
80 ; unsigned shift
81
82         .export         tosshra0, tosshrax
83
84 tosshra0:
85         ldx     #0
86 tosshrax:
87         jsr     popsreg         ; get TOS into sreg
88         cpx     #0
89         bne     TooLarge
90         cmp     #16
91         bcs     TooLarge
92
93         cmp     #8              ; Shift count greater 8?
94         beq     L8              ; Jump if exactly 8
95         bcc     L6              ; Jump if no
96
97 ; Shift count is greater 8. Do the first 8 bits the fast way
98
99         sbc     #8              ; Carry already set
100         ldy     sreg+1
101         sty     sreg
102         stx     sreg+1          ; High byte = 0
103
104 ; Shift count less than 8 if we come here
105
106 L6:     tay                     ; Shift count --> Y
107         beq     Zero            ; Done if shift count zero
108
109         lda     sreg            ; get low byte for faster shift
110
111 ; Do the actual shift
112
113 L7:     lsr     sreg+1
114         ror     a
115         dey
116         bne     L7
117
118 ; Done with shift
119
120         ldx     sreg+1
121         rts
122
123 ; Shift count == 8
124
125 L8:     lda     sreg+1          ; X is zero
126         rts
127