It is currently Sat Nov 17, 2018 7:58 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: 48
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: 48
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