diff options
| -rw-r--r-- | sux.h | 22 | ||||
| -rw-r--r-- | test/rotate.s | 61 | 
2 files changed, 77 insertions, 6 deletions
@@ -351,20 +351,30 @@ static inline uint64_t asr(struct sux *cpu, uint64_t reg, uint64_t value, uint8_  }  static inline uint64_t rol(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t thread) { -	uint64_t sum = reg << value; -	sum |= getflag(C); +	uint64_t sum; +	uint64_t c = getflag(C); +	switch (value & 0x3F) { +		case 0 : return reg; +		case 1 : sum = (reg << 1) | (c & 1); break; +		default: sum = (reg << value) | (c << (value-1)) | (reg >> (65-value)); break; +	}  	setflag(sum == 0, Z);  	setflag(sum >> 63, N); -	setflag(reg >> (uint64_t)(64-value), C); +	setflag((reg >> (64-value)) & 1, C);  	return sum;  }  static inline uint64_t ror(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t thread) { -	uint64_t sum = reg >> value; -	sum |= (uint64_t)getflag(C) << (uint64_t)(64-value); +	uint64_t sum; +	uint64_t c = getflag(C); +	switch (value & 0x3F) { +		case 0 : return reg; +		case 1 : sum = (reg >> 1) | (c << 63); break; +		default: sum = (reg >> value) | (c << (64-value)) | (reg << (65-value)); break; +	}  	setflag(sum == 0, Z);  	setflag(sum >> 63, N); -	setflag(reg & 1, C); +	setflag((reg >> (value-1)) & 1, C);  	return sum;  } diff --git a/test/rotate.s b/test/rotate.s new file mode 100644 index 0000000..6115e94 --- /dev/null +++ b/test/rotate.s @@ -0,0 +1,61 @@ +; Test rol, and ror. + +.org 0 +count: +	.res 1 +tmp: +	.res 8 + +.org $8000 +reset: +	cps		; +	ldx.w #$FFFF	; +	txs		; +	and #0		; +	tax		; +	tab		; +	tay		; + + +start: +	ldb #8		; Set the loop count to 8. +@loop: +	lda #$AA	; Set A to magic byte. +	deb		; Decrement the loop count. +	beq @savemagic	; Save the magic number, if the loop count is zero. +	lsl #8		; Shift the magic number by one byte, if the loop count is non zero. +	bra @loop	; Keep looping. +@savemagic: +	sta.q tmp	; Save the magic number. + + +rotate: +	ldb #0		; Reset B. +@loop: +	and #0		; Reset A. +	lda #$40	; Set the shift count to 64. +	sta count	; +	lda.q tmp	; Get our magic number. +	inb		; Increment our shift amount by one. +	cpb #$40	; Is the shift amount greater than, or equal to 64? +	bcs rotate	; Yes, so reset B. +@rotl: +	rol b		; Rotate the magic number left by our shift amount. +	dec count	; Decrement the shift count. +	beq @rotr	; Start rotating right, if the shift count is zero. +	bra @rotl	; Keep looping, if the shift count is non zero. +@rotr: +	and #0		; Reset A. +	lda #$40	; Set the shift count to 64. +	sta count	; +	lda.q tmp	; Get our magic number. +@rotr2: +	ror b		; Rotate the magic number right by our shift amount. +	dec count	; Decrement the shift count. +	beq @loop	; Increment the shift amount, if the shift count is zero. +	bra @rotr2	; Keep looping, if the shift count is non zero. + +.org $FFC0 +.qword reset +a +d  | 
