It is currently Mon Oct 22, 2018 1:21 am

 All times are UTC - 7 hours

 Page 1 of 1 [ 4 posts ]
 Print view Previous topic | Next topic
Author Message
 Post subject: CC65 bit shifting bug?Posted: Wed Dec 06, 2017 2:01 pm

Joined: Sun Sep 26, 2010 10:29 pm
Posts: 40
Hi,
I am wondering if I am facing a known CC65 bug: I am using a simple macro to calculate, in which 32x30 tile the given x/y coordinates a placed.
The calculation is as follows: (((y/8)*32)+(x/8)). To calculate this more efficiently, I am transforming this formula, using bit operators like follows:

step 0: (((y/8)*32)+(x/8)) --> working
step 1: (((y/8)*32)|(x>>3)) --> working
step 2: (((y>>3)*32)|(x>>3)) --> working
step 3: (((y>>3)<<5)|(x>>3)) --> working
step 4: ((y<<2)|(x>>3)) --> not working!

I rebuild each version using Java and here all versions produce the same result. Here is the Java code:
Code:

int x = 110;
int y = 50;

int result1 = (((y/8)*32)+(x/8));
int result2 = (((y>>3)<<5)|(x>>3));
int result3 = ((y<<2)|(x>>3));

System.out.println(result1); //output: 205
System.out.println(result2); //output: 205
System.out.println(result3); //output: 205

I guess there is something special with CC65 bit shifting? The problem obviously lies in the part when combining two shifts into one.

Regards
Sebastian

Top

 Post subject: Re: CC65 bit shifting bug?Posted: Wed Dec 06, 2017 2:08 pm

Joined: Sun Jan 31, 2016 9:55 pm
Posts: 47
Quote:
step 3: (((y>>3)<<5)|(x>>3)) --> working
step 4: ((y<<2)|(x>>3)) --> not working!

This isn't a valid transformation. ((y>>3)<<5) is not equivalent to (y<<2). If it were, then (y>>3)<<3 would be the same as y, but when you do y>>3, you chop off the lower 3 bits, and doing y<<3 afterward doesn't bring them back.

Top

 Post subject: Re: CC65 bit shifting bug?Posted: Wed Dec 06, 2017 2:21 pm

Joined: Sun Sep 26, 2010 10:29 pm
Posts: 40
Thanks for explaining. I guess this operation is working in my Java code, since I use int and not unsigned char, like in my C code.

Top

 Post subject: Re: CC65 bit shifting bug?Posted: Wed Dec 06, 2017 3:07 pm

Joined: Sun Jan 31, 2016 9:55 pm
Posts: 47
You are right that int and unsigned char will have different behaviors. In Java, >> is an arithmetic right shift, while for an unsigned number you will get a logical right shift (in Java represented by >>>).

You are working to optimize this part of the expression:
((y>>3)<<5).

This might be compiled something like:
Code:
lda yValue
lsr
lsr
lsr
asl
asl
asl
asl
asl

Note that doing shifts by amounts more than 1 takes multiple instructions on the 6502, so replacing it with a different operation can be beneficial.

If you have a byte y made up of bits a-h:
abcdefgh

y>>3 is:
000abcde

and that shifted left 5 is:
cde00000

So the value is equivalent to:
(y<<2)&0b11100000

This can be compiled to
Code:
lda yValue
asl
asl
and #%11100000

Top

 Display posts from previous: All posts1 day7 days2 weeks1 month3 months6 months1 year Sort by AuthorPost timeSubject AscendingDescending
 Page 1 of 1 [ 4 posts ]

 All times are UTC - 7 hours

#### Who is online

Users browsing this forum: No registered users and 2 guests

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

Search for:
 Jump to:  Select a forum ------------------ NES / Famicom    NESdev    NESemdev    NES Graphics    NES Music    Homebrew Projects       2018 NESdev Competition       2017 NESdev Competition       2016 NESdev Competition       2014 NESdev Competition       2011 NESdev Competition    Newbie Help Center    NES Hardware and Flash Equipment       Reproduction    NESdev International       FCdev       NESdev China       NESdev Middle East Other    General Stuff    Membler Industries    Other Retro Dev       SNESdev       GBDev    Test Forum Site Issues    phpBB Issues    Web Issues    nesdevWiki