6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Thu Mar 28, 2024 1:46 pm

All times are UTC




Post new topic Reply to topic  [ 28 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Tue Nov 10, 2020 6:42 pm 
Offline
User avatar

Joined: Wed Aug 17, 2005 12:07 am
Posts: 1206
Location: Soddy-Daisy, TN USA
Once I load a value into the accumulator, I want to then rotate it either left or right one bit.

The issue is that "9th bit" of the carry is causing more code that I want. For example:

Code:
                clc
                lda $c000
                ror
                bcs !carry_set+
            !carry_clear:
                jmp !+
            !carry_set:
                clc
                adc #$80
            !:
                sta $c000


This is just pseudo code that I *THINK* may work. But is it the most efficient?
Bottom line, I only want to rotate the 8 bits of an address left/right and don't care about the carry. But, obviously, I have to deal with it somehow.

Would it be more efficient to use a SHIFT but then check to see if I need to set the MSB or LSB? Not sure on that one.

Advice would be appreciated. :-)

Thanks!

_________________
Cat; the other white meat.


Top
 Profile  
Reply with quote  
PostPosted: Tue Nov 10, 2020 6:59 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10760
Location: England
How about:
Code:
                lda $c000
                clc
                ror
                bcc !+
                eor #$80
            !:
                sta $c000


Top
 Profile  
Reply with quote  
PostPosted: Tue Nov 10, 2020 7:01 pm 
Offline
User avatar

Joined: Tue Nov 16, 2010 8:00 am
Posts: 2353
Location: Gouda, The Netherlands
Code:
lda $c000
lsr
bcc carry_clear
adc #$7f
carry_clear:
sta $c000


Top
 Profile  
Reply with quote  
PostPosted: Tue Nov 10, 2020 7:04 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10760
Location: England
oh, of course, lsr!


Top
 Profile  
Reply with quote  
PostPosted: Tue Nov 10, 2020 7:05 pm 
Offline
User avatar

Joined: Tue Nov 16, 2010 8:00 am
Posts: 2353
Location: Gouda, The Netherlands
How about
Code:
lda $c000
lsr
ror $c000


Top
 Profile  
Reply with quote  
PostPosted: Tue Nov 10, 2020 7:06 pm 
Offline

Joined: Sun Jun 29, 2014 5:42 am
Posts: 330
Rotating left:
Code:
LDA $C000
ASL A
ADC #$00
STA $C000

Rotating right:
Code:
LDA $C000
LSR A
BCC !+
ORA #$80
!:
STA $C000

Dave


Top
 Profile  
Reply with quote  
PostPosted: Tue Nov 10, 2020 7:10 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10760
Location: England
Oh, Arlet might have it! So long as we're OK reading the source twice.


Top
 Profile  
Reply with quote  
PostPosted: Tue Nov 10, 2020 7:25 pm 
Offline
User avatar

Joined: Wed Aug 17, 2005 12:07 am
Posts: 1206
Location: Soddy-Daisy, TN USA
You guys rock! I knew I came to the right place. :-)

Thanks! I will give those a shot.

_________________
Cat; the other white meat.


Top
 Profile  
Reply with quote  
PostPosted: Tue Nov 10, 2020 7:33 pm 
Offline
User avatar

Joined: Wed Aug 17, 2005 12:07 am
Posts: 1206
Location: Soddy-Daisy, TN USA
Arlet wrote:
How about
Code:
lda $c000
lsr
ror $c000



Wait, I'm curious on how this one works.
Wouldn't the ROR be separate than the LDA/LSR?

_________________
Cat; the other white meat.


Top
 Profile  
Reply with quote  
PostPosted: Tue Nov 10, 2020 7:37 pm 
Offline
User avatar

Joined: Tue Nov 16, 2010 8:00 am
Posts: 2353
Location: Gouda, The Netherlands
The final ROR $C000 would be all that you need if the 6502 had an 8-bit rotate without the carry flag.

Since it does rotate through the carry flag, we just need to make sure that the carry is preset correctly with the least significant bit. That's what the LDA/LSR do. (You could also do LDA/ROR, which would look more pleasing)


Top
 Profile  
Reply with quote  
PostPosted: Tue Nov 10, 2020 7:46 pm 
Offline
User avatar

Joined: Wed Aug 17, 2005 12:07 am
Posts: 1206
Location: Soddy-Daisy, TN USA
Arlet wrote:
The final ROR $C000 would be all that you need if the 6502 had an 8-bit rotate without the carry flag.

Since it does rotate through the carry flag, we just need to make sure that the carry is preset correctly with the least significant bit. That's what the LDA/LSR do. (You could also do LDA/ROR, which would look more pleasing)


Ah, OK. So, to rotate left, I assume the following would work:

Code:
lda $c000
asl
rol $c000

_________________
Cat; the other white meat.


Top
 Profile  
Reply with quote  
PostPosted: Tue Nov 10, 2020 7:48 pm 
Offline
User avatar

Joined: Tue Mar 05, 2013 4:31 am
Posts: 1373
There's always many ways to twiddle bits with the 6502... if you just wanted to make a (sub)routine that would rotate a value in accumulator, you could use this:

Code:
   PHA    ;Save value
   LSR A  ;Shift bit to carry
   PLA    ;Get original value back
   ROR A  ;Rotate it
   RTS    ;Return to caller

If you didn't care about clobbering an Index register, you could xfer the A reg before the shift, then xfer it back before the rotate. It would save some clock cycles from using the stack.

_________________
Regards, KM
https://github.com/floobydust


Top
 Profile  
Reply with quote  
PostPosted: Tue Nov 10, 2020 7:50 pm 
Offline
User avatar

Joined: Tue Nov 16, 2010 8:00 am
Posts: 2353
Location: Gouda, The Netherlands
Yes. And if you wanted to rotate two bits, you could do:
Code:
lda $c000
ror
ror $c000
ror
ror $c000

Note that you could make it a few cycles faster if you can put the data in zeropage.


Top
 Profile  
Reply with quote  
PostPosted: Tue Nov 10, 2020 8:46 pm 
Offline
User avatar

Joined: Wed Aug 17, 2005 12:07 am
Posts: 1206
Location: Soddy-Daisy, TN USA
OK, so I ran the rotate code in a loop and noticed some strange numbers.

So, your code worked great...but it showed a flaw in my design! lol

Here are the numbers I got:

Code:
        $48 01001000
        $24 00100100
        $12 00010010
        $09 00001001
        $84 10000100
        $42 01000010
        $21 00100001
        $90 10010000


Well, that's technically correct. But what I missed what that I actually need to rotate within the two NYBBLE's.

Totally my fault! I didn't "see" the issue until the code ran.

So, why do I need this? Well, I'm using one byte to represent a sprite. The byte contains the direction it is pointing along with the direction it's moving.

Like this:

Code:
Facing  Moving
NESW    NESW
1000    0100


Which means the sprite is facing north and moving east.

So, when I rotate right, I need the upper nybble to not spill into the lower nybble.

I'll keep digging at this but any pointers are greatly appreciated (AGAIN).

Thanks!

_________________
Cat; the other white meat.


Top
 Profile  
Reply with quote  
PostPosted: Tue Nov 10, 2020 9:13 pm 
Offline
User avatar

Joined: Tue Mar 05, 2013 4:31 am
Posts: 1373
Well, that's not quite the same thing :?

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.

_________________
Regards, KM
https://github.com/floobydust


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 28 posts ]  Go to page 1, 2  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 6 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: