## Saturday, September 29, 2018

### Rotating and Shifting Bits right

Shifting and rotating right works same as rotating left except in opposite direction so the bits move from high to low. The right shift command is LSR while the rotation command is ROR.
In the previous article we packed a playing card into a byte. We had a bit to representing if the card was revealed, 4 bits to hold the face value, and 2 bits to hold the suit. This would give us a packed byte in the format 0RFFFFSS. To unpack the card byte we can do the following

LDA cardToUnpack
TAX
AND #3
STA cardSuit
TXA
LSR
LSR
TAX
AND #15
STA cardFace
TXA
LSR
LSR
LSR
LSR
STA cardShowing
As with multiplication, shifting right is the equivalent of dividing by powers of 2. Unfortunately non-powers of two are a bit more complicated to perform than non-power of two multiplications.

Working with multi-byte shifting is a bit different with multiple bytes as you start with the highest byte and work your way towards the lowest byte using LSR on the high byte (ROR if doing a multi-byte rotation) and using ROR for all the remaining bytes working towards the lowest byte. Here is a two-byte example:

LDA highByte
LSR
STA highByte
LDA lowByte
ROR
STA lowByte
RORROtate Right by one bit
 Address Mode Decimal OPCode Hexadecimal OpCode Size Cycles Accumulator 106 \$6A 1 2 Zero Page 102 \$66 2 5 Zero Page,X 118 \$76 2 6 Absolute 110 \$6E 3 6 Absolute,X 126 \$7E 3 7
Flags affected: CNZ
Usage: Rotates bits right using the carry bit to fill in the missing bit and putting the low order bit into the carry flag. Used primarily for division by powers of 2 and reading serial data though can be used to reposition bits.
Test Code:
; ROR accumulator
CLC
LDA #1
ROR A
BRK
; expect A=0, Z=1, C=1, N=0
; ROR with memory
LDX #1
ROR 254
ROR 254,X
ROR 256
ROR 256,X
BRK
.ORG 254
.BYTE 1 254 \$EF 254
;expect MFE=0 MFF=255 M100=\$77 M101=\$FF N=1, Z=0, C=0
Implementation:
// Accumulator
state.acc = performRightBitShift(state.acc, true)
// Zero Page
// Zero Page, X
// Absolute
// Absolute, X
LSRLogical Shift Right by one bit
 Address Mode Decimal OPCode Hexadecimal OpCode Size Cycles Accumulator 74 \$4A 1 2 Zero Page 70 \$46 2 5 Zero Page,X 86 \$56 2 6 Absolute 78 \$4E 3 6 Absolute,X 94 \$5E 3 7
Flags affected: CNZ
Usage: Shifts bits right using  0 to fill in the missing bit and putting the low order bit into the carry flag. Used primarily for single byte division by powers of 2 and reading serial data though can be used to reposition bits.
Test Code:
; LSR accumulator
LDA #1
SEC
LSR A
BRK
; expect A=0, Z=1, C=1, N=0
; LSR with memory
LDX #1
LSR 254
LSR 254,X
LSR 256
LSR 256,X
BRK
.ORG 254
.BYTE 128 127 \$EE \$76
;expect MFE=64 MFF=63 M100=\$77 M101=\$3B N=1, Z=0, C=0
Implementation:
// Accumulator
state.acc = performRightBitShift(state.acc, false)
// Zero Page
// Zero Page, X
// Absolute