Rotate bits when you don't care about carry.

Programming the 6502 microprocessor and its relatives in assembly and other languages.
User avatar
cbmeeks
Posts: 1254
Joined: 17 Aug 2005
Location: Soddy-Daisy, TN USA
Contact:

Re: Rotate bits when you don't care about carry.

Post by cbmeeks »

floobydust wrote:
Well, that's not quite the same thing :?
HA! Yeah. After rotating the bits correctly and observing the numbers, I noticed my error. It's one of those situations where I got exactly what I asked for...just asked the wrong question. lol

floobydust wrote:
I would take a different approach. As there's only 16 bit combinations to a nibble, you can simply use a 16-byte lookup table with the rotated values. You can mask off the upper 4-bits (to retain the lower 4 bits), xfer to an index register and load the accumulator indexed from the lookup table.

For the upper nibble, you would need to do 4 LSR A instructions and again xfer it to an index register. To save time, you could use a different 16-byte table where the rotated values are in the upper 4 bits. Once you have both values, you just OR them together for the twin-shifted nibbles.

That's exactly what I'm going to do. I was trying to be fancy by containing everything in one byte and rotating. But proves to be more trouble.

Thanks for all the suggestions. At the very least, I know have a better rotation function. :-)
Cat; the other white meat.
User avatar
cbmeeks
Posts: 1254
Joined: 17 Aug 2005
Location: Soddy-Daisy, TN USA
Contact:

Re: Rotate bits when you don't care about carry.

Post by cbmeeks »

Wait...

What if I used two bytes?

One byte for the facing direction and one byte for the moving direction?

Then, just make both nybbles the same. Wouldn't the rotate then work out OK?

Code: Select all

// Facing Byte
%1000 1000

// Moving Byte
%0100 0100
Then, I can just rotate as normal and mask off either nybble.

I may try that next. If it doesn't work, use some lookup tables.

Thanks!
Cat; the other white meat.
User avatar
BigEd
Posts: 11463
Joined: 11 Dec 2008
Location: England
Contact:

Re: Rotate bits when you don't care about carry.

Post by BigEd »

I reckon you can still do the nibble rotate, with a bit of care. There are two checks and corrections to be made, one for each nibble. But I'm not quite smart enough right now to just write the code!
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: Rotate bits when you don't care about carry.

Post by barrym95838 »

In order to transform the current facing value to the new facing value without affecting the movement direction, you only need four different EOR operands (#$30, #$60, #$C0, #$90) for clockwise or counterclockwise. The trick is in calculating the desired operand as efficiently as possible. Are you more interested in fastest execution or smallest code footprint? Because the solutions will probably end up evolving differently. One intermediate possibility might look like:

Code: Select all

rotcw:
    lda status
    lsr
    lsr
    lsr
    lsr
    tax
    lda cwtable-2,x
    bne rotzzz
rotccw:
    lda status
    lsr
    lsr
    lsr
    lsr
    tax
    lda ccwtable-1,x
rotzzz:
    eor status
    sta status
    rts
ccwtable:
    dcb $30,$60,0,$C0,0,0,0,$90
cwtable:
    dcb $30,0,$60,0,0,0,$C0
[UNTESTED!]

I truncated and slightly overlapped the tables to save space, but this will blindly provide nonsense values for invalid inputs ... garbage in, garbage out.

I know someone here can do better, perhaps much better, but I'm just throwing this out there as an example. If status happens to reside at address $30 or address $30xx, I know how to save two more bytes of ccwtable! :shock:
Last edited by barrym95838 on Wed Nov 11, 2020 3:36 am, edited 2 times in total.
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)
User avatar
cbmeeks
Posts: 1254
Joined: 17 Aug 2005
Location: Soddy-Daisy, TN USA
Contact:

Re: Rotate bits when you don't care about carry.

Post by cbmeeks »

The EOR idea sounds interesting as well!

My idea of using two bytes seems to be working. The sprite is rotating correctly on screen now.

The numbers I am getting are:

Code: Select all

$88    // N
$44    // E
$22    // S
$11    // W
Which translates perfectly to:

Code: Select all

        .label FACING_DIR_N = %10001000
        .label FACING_DIR_E = %01000100
        .label FACING_DIR_S = %00100010
        .label FACING_DIR_W = %00010001
Same for moving.

Thanks again everyone for your help.
Cat; the other white meat.
User avatar
BigEd
Posts: 11463
Joined: 11 Dec 2008
Location: England
Contact:

Re: Rotate bits when you don't care about carry.

Post by BigEd »

Just a thought: you want to maintain two pieces of information, each of which has four possible states. You've chosen a one-hot encoding, and now you're looking for ways to manipulate it.

But four states can be encoded in two bits. The whole story fits in a nibble. And a nibble-sized lookup table is only 16 bytes: you can have one table for left rotation and one for right rotation.

If at some point you need a one-hot representation of this packed encoding, again a nibble-sized lookup table, with another 16 bytes, can give you what you want - or a pair of lookups, one to give you the movement part and the other to give you the orientation part.

(I have just spent 64 bytes on lookup tables! But the speed should be good.)
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: Rotate bits when you don't care about carry.

Post by barrym95838 »

Yeah, my suggested solution was constrained by the structure it was trying to update. In a clean-sheet design, I would probably just use the two low bits of two separate bytes for each attribute and just INC and DEC to rotate.
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)
MagerValp
Posts: 6
Joined: 29 Oct 2015

Re: Rotate bits when you don't care about carry.

Post by MagerValp »

Code: Select all

CMP #$80
ROL
Chromatix
Posts: 1462
Joined: 21 May 2018

Re: Rotate bits when you don't care about carry.

Post by Chromatix »

For rotating left:

Code: Select all

  ASL A
  ADC #0
And for rotating right:

Code: Select all

  LSR A
  BCC *+4
  ORA #$80
Barrel shifts by more than one bit are a little more involved - here's one way to do a nybble swap:

Code: Select all

  STZ tmp
  ASL A
  ROL tmp
  ASL A
  ROL tmp
  ASL A
  ROL tmp
  ASL A
  ROL tmp
  ORA tmp
User avatar
GARTHWILSON
Forum Moderator
Posts: 8773
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: Rotate bits when you don't care about carry.

Post by GARTHWILSON »

Chromatix wrote:
here's one way to do a nybble swap: <snip>

http://6502.org/source/general/SWN.html has a 6-instruction, 8-byte, 12-cycle nybble swap.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
TobyLobster
Posts: 37
Joined: 17 Jun 2021

Re: Rotate bits when you don't care about carry.

Post by TobyLobster »

To rotate the bits in each each nibble to the left, how about this:

Code: Select all

    asl
    bit sixteen
    beq +
    and #$ef
    ora #1
+
    bcc +
sixteen = * + 1
    ora #16
+
    
User avatar
BigEd
Posts: 11463
Joined: 11 Dec 2008
Location: England
Contact:

Re: Rotate bits when you don't care about carry.

Post by BigEd »

(welcome Toby! I've seen you over on stardot...)
TobyLobster
Posts: 37
Joined: 17 Jun 2021

Re: Rotate bits when you don't care about carry.

Post by TobyLobster »

(thanks, I've seen you in stardot-land too...)
Post Reply