]> git.sur5r.net Git - cc65/blobdiff - libsrc/runtime/lshr.s
Add interrupt handling code from Stefan Haubenthal
[cc65] / libsrc / runtime / lshr.s
index 2e3e051012cf576876cf52fc358554f9a8f28e59..9c2a6e3a882a17790e187ab52302fdff1661f05f 100644 (file)
 ;
-; Ullrich von Bassewitz, 20.09.1998
+; Ullrich von Bassewitz, 2004-06-30
 ;
-; CC65 runtime: right shift support for longs
+; CC65 runtime: right shift support for unsigned longs
 ;
+; 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!
+;
+
+
+       .export         tosshreax
+       .import         popeax
+       .importzp       sreg, tmp1
+
+
+tosshreax:
+        and     #$1F            ; Bring the shift count into a valid range
+        sta     tmp1            ; Save it
+
+        jsr     popeax          ; Get the left hand operand
+
+        ldy     tmp1            ; Get shift count
+        beq     L9              ; Bail out if shift count zero
+        stx     tmp1            ; Save byte 1
+
+; Do the actual shift. Faster solutions are possible but need a lot more code.
 
+L2:     lsr     sreg+1
+       ror     sreg
+        ror            tmp1
+        ror     a
+        dey
+               bne     L2
 
-       .export         tosasreax, tosshreax
-       .import         addysp1
-       .importzp       sp, sreg, ptr1, ptr2
-
-; --------------------------------------------------------------------
-; signed shift
-
-.proc  tosasreax
-
-               jsr     getlhs          ; Get the lhs from the stack
-
-               jsr     checkovf        ; Check for overflow
-       bcs     L6              ; Jump if shift count too large
-
-       cpy     #0              ; Shift count zero?
-       beq     L5
-
-; We must shift. Shift by multiples of eight if possible
-
-       tya
-L1:    cmp     #8
-       bcc     L3
-       sbc     #8
-               ldx     ptr1+1
-       stx     ptr1
-       ldx     ptr2
-       stx     ptr1+1
-       ldy     #0
-       ldx     ptr2+1
-       stx     ptr2
-       bpl     L2
-       dey                     ; Get sign
-L2:    sty     ptr2+1
-       jmp     L1
-
-; Shift count is now less than eight. Do a real shift.
-               
-L3:    tay                     ; Shift count to Y
-       lda     ptr2+1          ; Get one byte into A for speed
-       cpy     #0
-               beq     L4a             ; Jump if done
-L4:    cmp     #$80            ; Get sign bit into C
-       ror     a
-       ror     ptr2
-       ror     ptr1+1
-       ror     ptr1
-       dey
-       bne     L4
-
-; Put the result in place
-
-L4a:   sta     sreg+1
-       lda     ptr2
-       sta     sreg
-       ldx     ptr1+1
-       lda     ptr1
-L5:    rts
-
-; Jump here if shift count overflow
-
-L6:    ldx     #0
-       lda     ptr2+1          ; Check sign
-               bpl     L7
-       dex
-L7:    stx     sreg+1
-       stx     sreg
-       txa
-       rts
-
-.endproc
-
-; --------------------------------------------------------------------
-; unsigned shift
-
-.proc  tosshreax
-
-               jsr     getlhs          ; Get the lhs from the stack
-
-       jsr     checkovf        ; Check for overflow
-               bcs     L6              ; Jump if shift count too large
-
-       cpy     #0              ; Shift count zero?
-       beq     L5
-
-; We must shift. Shift by multiples of eight if possible
-
-       tya
-L1:    cmp     #8
-       bcc     L3
-       sbc     #8
-               ldx     ptr1+1
-       stx     ptr1
-       ldx     ptr2
-       stx     ptr1+1
-       ldx     ptr2+1
-       stx     ptr2
-       ldx     #0
-       stx     ptr2+1
-               beq     L1
-
-; Shift count is now less than eight. Do a real shift.
-
-L3:    tay                     ; Shift count to Y
-       lda     ptr2+1          ; Get one byte into A for speed
-       cpy     #0
-               beq     L4a             ; Jump if done
-L4:    lsr     a
-       ror     ptr2
-       ror     ptr1+1
-       ror     ptr1
-       dey
-       bne     L4
-
-; Put the result in place
-
-L4a:   sta     sreg+1
-       lda     ptr2
-       sta     sreg
-       ldx     ptr1+1
-       lda     ptr1
-L5:    rts
-
-; Jump here if shift count overflow
-
-L6:    lda     #0
-       sta     sreg+1
-       sta     sreg
-       tax
-       rts
-
-.endproc
-
-; --------------------------------------------------------------------
-; Helpers
-
-.proc          getlhs                  ; Get the lhs from stack into ptr1/ptr2
-
-       pha
-       ldy     #0
-       lda     (sp),y
-       sta     ptr1
-       iny
-       lda     (sp),y
-       sta     ptr1+1
-       iny
-       lda     (sp),y
-       sta     ptr2
-       iny
-       lda     (sp),y
-       sta     ptr2+1
-       pla
-               jmp     addysp1
-
-.endproc
-
-
-.proc  checkovf                ; Check for shift overflow
-
-               tay                     ; Low byte of shift count into y
-               txa                     ; Get byte 2
-       ora     sreg
-       ora     sreg+1          ; Check high 24 bit
-       bne     TooLarge        ; Shift count too large
-       cpy     #32
-       bcc     Ok
-TooLarge:
-       sec
-Ok:    rts
-
-.endproc
+; Shift done
 
+        ldx     tmp1
+L9:     rts