Thought ROL/ROR would do this...

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Thought ROL/ROR would do this...
by on (#146614)
I have a byte I want to cycle through, where the bits should be shifted with 'wrapping' - like so:

#%00000010 --> #%00000001 --> #%10000000

I thought that ROR / ROL worked this way (and opposite), but it does not seem to in this case. Is my understanding flawed, or is it something deeper in the code giving me the issue? If my understanding is flawed, how do you guys achieve something like this?

Thanks!
Re: Thought ROL/ROR would do this...
by on (#146615)
ROR and ROL work through a ninth bit, the carry bit, so that you can ROR the least significant bit out of a more significant byte (into the carry) and then ROR that bit into the most significant bit of a less significant byte. Do you want to see a worked example of this?
Re: Thought ROL/ROR would do this...
by on (#146616)
I see - so directly no, what I was trying wouldn't work directly. It would require a little bit more logic (checking either bit 0 or 7 depending on direction, setting or clearing the carry based on its value so that the ROR/ROL works as described?) Would something like this work? Am I making it too complicated? (assuming I wanted to do this all within one byte)
Re: Thought ROL/ROR would do this...
by on (#146617)
JoeGtake2 wrote:
It would require a little bit more logic (checking either bit 0 or 7 depending on direction, setting or clearing the carry based on its value so that the ROR/ROL works as described?) Would something like this work? Am I making it too complicated?

It's not as complicated as it seems. It's easier for ROL:

Code:
   cmp #%10000000 ;copy bit 7 to carry
   rol

And here's ROR:

Code:
   lsr
   bcc +
   ora #%10000000
+
Re: Thought ROL/ROR would do this...
by on (#146618)
Yep, that did it! Thanks! :-)
Re: Thought ROL/ROR would do this...
by on (#146621)
If you're rotating a value in memory (as opposed to A), you can rotate without a branch. This is 10 cycles for zero page dd; add 2 for absolute aaaa, add 2 for indexed dd,X or aaaa,X, and subtract 1 for absolute aaaa,X that does not cross a page (256-byte) boundary.
Code:
  lda some_byte  ; 3: put memory bit 0 in A bit 0
  lsr a          ; 2: put A bit 0 in carry
  ror some_byte  ; 5: put carry in memory bit 7
Re: Thought ROL/ROR would do this...
by on (#146626)
tepples wrote:
If you're rotating a value in memory (as opposed to A), you can rotate without a branch.

You can also rotate "without a branch" (i.e. there are 2 branches, but they're arranged so that the execution time constant - 7 cycles) using the accumulator:

Code:
   lsr
   bcs +
   bcc ++
+
   ora #%10000000
++