asleax2.o \
asleax3.o \
asleax4.o \
+ asr.o \
asrax1.o \
asrax2.o \
asrax3.o \
--- /dev/null
+;
+; Ullrich von Bassewitz, 2004-06-30
+;
+; CC65 runtime: right shift support for ints
+;
+; 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 tosasrax
+ .import popax
+ .importzp tmp1
+
+tosasrax:
+ and #$0F ; Bring the shift count into a valid range
+ sta tmp1 ; Save it
+
+ jsr popax ; Get the left hand operand
+
+ ldy tmp1 ; Get shift count
+ beq L9 ; Bail out if shift count zero
+
+ cpy #8 ; Shift count 8 or greater?
+ bcc L1 ; Jump if not
+
+; Shift count is greater 8. The carry is set when we enter here.
+
+ tya
+ sbc #8
+ tay ; Adjust shift count
+ txa
+ ldx #$00 ; Shift by 8 bits
+ cmp #$00 ; Test sign bit
+ bpl L1
+ dex ; Make X the correct sign extended value
+
+; Save the high byte so we can shift it
+
+L1: stx tmp1 ; Save high byte
+ jmp L3
+
+; Do the actual shift
+
+L2: cpx #$80 ; Copy bit 15 into the carry
+ ror tmp1
+ ror a
+L3: dey
+ bpl L2
+
+; Done with shift
+
+ ldx tmp1
+L9: rts
+
+
+
--- /dev/null
+;
+; Ullrich von Bassewitz, 2004-06-30
+;
+; CC65 runtime: right shift support for 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 tosasreax
+ .import popeax
+ .importzp sreg, tmp1
+
+
+tosasreax:
+ 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
+ ldx sreg+1 ; Load byte 3
+
+; Do the actual shift. Faster solutions are possible but need a lot more code.
+
+L2: cpx #$80 ; Copy bit 31 into the carry
+ ror sreg+1
+ ror sreg
+ ror tmp1
+ ror a
+ dey
+ bne L2
+
+; Shift done
+
+ ldx tmp1
+L9: rts
+
;
-; Ullrich von Bassewitz, 20.09.1998
+; Ullrich von Bassewitz, 2004-06-30
;
-; CC65 runtime: left shift support for longs
+; CC65 runtime: left shift support for long and unsigned long
+;
+; 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 tosasleax, tosshleax
- .import addysp1
- .importzp sp, sreg, ptr1, ptr2
+ .import popeax
+ .importzp sreg, tmp1
tosshleax:
tosasleax:
+ and #$1F ; Bring the shift count into a valid range
+ sta tmp1 ; Save it
-; 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
- jsr addysp1
-
-; Check for shift overflow or zero shift
-
- tay ; Low byte of shift count into y
- txa ; Get byte 2
- ora sreg
- ora sreg+1 ; Check high 24 bit
- bne @L6 ; Shift count too large
- cpy #32
- bcs @L6
-
- 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 ptr2
- stx ptr2+1
- ldx ptr1+1
- stx ptr2
- ldx ptr1
- stx ptr1+1
- ldx #0
- stx ptr1
- beq @L1
-
-; Shift count is now less than eight. Do a real shift.
-
-@L3: tay ; Shift count to Y
- lda ptr1 ; Get one byte into A for speed
- cpy #0
- beq @L4a ; Jump if done
-@L4: asl a
- rol ptr1+1
- rol ptr2
- rol ptr2+1
- dey
- bne @L4
-
-; Put the result in place
+ jsr popeax ; Get the left hand operand
-@L4a: ldx ptr2
- stx sreg
- ldx ptr2+1
- stx sreg+1
- ldx ptr1+1
-@L5: rts
+ ldy tmp1 ; Get shift count
+ beq L9 ; Bail out if shift count zero
+ stx tmp1 ; Save byte 1
-; Jump here if shift count overflow
+; Do the actual shift. Faster solutions are possible but need a lot more code.
-@L6: lda #0
- sta sreg+1
- sta sreg
- tax
- rts
+L2: asl a
+ rol tmp1
+ rol sreg
+ rol sreg+1
+ dey
+ bne L2
+; Shift done
+ ldx tmp1
+L9: rts
;
-; 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
;
-; Ullrich von Bassewitz, 05.08.1998
+; Ullrich von Bassewitz, 1998-08-05, 2004-06-25
;
-; CC65 runtime: left shift support for ints
+; CC65 runtime: left shift support for ints and 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!
+;
+
- .export tosasla0, tosaslax, tosshla0, tosshlax
- .import popsreg, return0
- .importzp sreg
+ .export tosaslax, tosshlax
+ .import popax
+ .importzp tmp1
-tosshla0:
-tosasla0:
- ldx #0
tosshlax:
tosaslax:
- 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 L3 ; Jump if exactly 8
- bcc L1 ; 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
- ldy sreg
- sty sreg+1
- stx sreg ; Low byte = 0
- sec
- sbc #8
+ 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.
-L1: tay ; Shift count --> Y
- beq Zero ; Done if shift count zero
+ tax
+ tya
+ sbc #8
+ tay
+ txa
+ jmp L2
+L1: asl a
+L2: dey
+ bpl L1
+ tax
+ lda #$00
+ rts
- lda sreg ; get low byte for faster shift
+; Shift count is less than 8.
-; Do the actual shift
-
-L2: asl a
- rol sreg+1
- dey
- bne L2
+L3: stx tmp1 ; Save high byte of lhs
+L4: asl a
+ rol tmp1
+ dey
+ bne L4
; Done with shift
- ldx sreg+1
- rts
-
-; Shift count == 8
-
-L3: txa ; X == 0, now A == 0
- ldx sreg
- rts
-
-; Shift count was zero
-
-Zero: lda sreg
- ldx sreg+1
- rts
-
-; Shift count too large, result is zero
-
-TooLarge:
- jmp return0
+ ldx tmp1
+L9: rts
;
-; 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