]> git.sur5r.net Git - cc65/blobdiff - libsrc/runtime/shr.s
Add interrupt handling code from Stefan Haubenthal
[cc65] / libsrc / runtime / shr.s
index 2b51500bcc4fa2794a0eec8da8eb8c7a95f2d83a..3b505e74dbe6002102c404a01302e0c5910a30e3 100644 (file)
 ;
-; Ullrich von Bassewitz, 05.08.1998
+; Ullrich von Bassewitz, 2004-06-30
 ;
-; CC65 runtime: right shift support for ints
+; CC65 runtime: right shift support for unsigneds
+;
+; Note: The standard declares a shift count that is negative or >= the
+; bitcount of the shifted type for undefined behaviour.
+;
+; Note^2: The compiler knowns about the register/zero page usage of this
+; function, so you need to change the compiler source if you change it!
 ;
 
 
-; --------------------------------------------------------------------
-; signed shift
-
-       .export         tosasra0, tosasrax
-       .import         popsreg, return0
-       .importzp       sreg
-
-tosasra0:
-       ldx     #0
-tosasrax:
-       jsr     popsreg         ; get TOS into sreg
-       cpx     #0
-       bne     TooLarge
-       cmp     #16
-       bcs     TooLarge
-
-               cmp     #8              ; Shift count greater 8?
-       beq     L4              ; Jump if exactly 8
-               bcc     L2              ; Jump if no
-
-; Shift count is greater 8. Do the first 8 bits the fast way
-
-       ldy     #0
-       ldx     sreg+1
-       stx     sreg
-       bpl     L1
-       dey                     ; Create correct sign bits
-L1:    sty     sreg+1
-       sec
-       sbc     #8
-
-; Shift count less than 8 if we come here
-
-L2:    tay                     ; Shift count --> Y
-       beq     Zero            ; Done if shift count zero
-
-       lda     sreg            ; get low byte for faster shift
-       ldx     sreg+1          ; get high byte
-
-; Do the actual shift
-
-L3:    cpx     #$80            ; get bit 7 into carry
-       ror     sreg+1
-       ror     a
-       dey
-               bne     L3
-
-; Done with shift
-
-       ldx     sreg+1
-       rts
-
-; Shift count == 8
-
-L4:    lda     sreg+1          ; X is zero
-       bpl     *+3
-       dex                     ; X == 0xFF
-       rts
-
-; Shift count was zero
-
-Zero:  lda     sreg
-       ldx     sreg+1
-       rts
-
-; Shift count too large, result is zero
-
-TooLarge:
-       jmp     return0
-
-
-; --------------------------------------------------------------------
-; unsigned shift
-
-       .export         tosshra0, tosshrax
+       .export         tosshrax
+       .import         popax
+       .importzp       tmp1
 
-tosshra0:
-       ldx     #0
 tosshrax:
-       jsr     popsreg         ; get TOS into sreg
-       cpx     #0
-       bne     TooLarge
-       cmp     #16
-       bcs     TooLarge
+        and     #$0F            ; Bring the shift count into a valid range
+        sta     tmp1            ; Save it
 
-               cmp     #8              ; Shift count greater 8?
-       beq     L8              ; Jump if exactly 8
-               bcc     L6              ; Jump if no
+        jsr     popax           ; Get the left hand operand
 
-; Shift count is greater 8. Do the first 8 bits the fast way
+        ldy     tmp1            ; Get shift count
+        beq     L9              ; Bail out if shift count zero
 
-       sbc     #8              ; Carry already set
-       ldy     sreg+1
-       sty     sreg
-               stx     sreg+1          ; High byte = 0
+        cpy     #8              ; Shift count 8 or greater?
+        bcc     L3              ; Jump if not
 
-; Shift count less than 8 if we come here
+; Shift count is greater 7. The carry is set when we enter here.
 
-L6:    tay                     ; Shift count --> Y
-       beq     Zero            ; Done if shift count zero
+        tya
+        sbc     #8
+        tay                     ; Adjust shift count
+        txa
+        ldx     #$00            ; Shift by 8 bits
+        beq     L2              ; Branch always
+L1:     lsr     a
+L2:     dey
+        bpl     L1
+        rts
 
-       lda     sreg            ; get low byte for faster shift
+; Shift count is less than 8. Do the actual shift.
 
-; Do the actual shift
-
-L7:            lsr     sreg+1
-       ror     a
-       dey
-               bne     L7
+L3:     stx     tmp1            ; Save high byte of lhs
+L4:     lsr     tmp1
+        ror     a
+        dey
+               bne     L4
 
 ; Done with shift
 
-       ldx     sreg+1
-       rts
-
-; Shift count == 8
-
-L8:    lda     sreg+1          ; X is zero
-       rts
+        ldx    tmp1
+L9:     rts