I had this issue a few time and always thought I was doing something wrong but this time I'm pretty sure that something is going on.
I'm using a locally complied version under ubuntu (cc65 V2.17 - Git 535088fe).
Here's the code example:
What it does is if the Y value is smaller than 5, do something, pretty basic. The catch: if Y is an 16 bit value, that condition always fails. If I change the Y type to a char, it works fine.
I checked the assembler but I didn't do for a while so I'm a little rusty about the possible cause. here the 16 bit version:
My guess is something is going on around line 30F~313, where for some reason, because how the code was generated, it causes the branching to fails with small numbers but I'm too rusty to see it at all but I think I'm close to the cause.
Here's the 8 bit version (Y is now a char):
In that case, there is no need to extract the address in ptr to extract the value since it's 8 bit, the value is loaded in A and proper testing is done, bcs when it's false.
I have been bitten many times by that bug and was sure I was doing something wrong but now I'm getting quite convinced that something is not working as expected, unless I'm doing something in C that I was not supposed to do in cc65? I read the manual, I don't remember anything about testing 16/8 values against each other.
Any information on the subject would be greatly appreciated.
I'm using a locally complied version under ubuntu (cc65 V2.17 - Git 535088fe).
Here's the code example:
Code:
// if still active, check Y posisition
if(g_playerBullets.active[m_idx] == TRUE) {
if(g_playerBullets.y[m_idx] < 5) {
g_playerBullets.active[m_idx] = FALSE;
--g_playerBullets.count;
}
}
if(g_playerBullets.active[m_idx] == TRUE) {
if(g_playerBullets.y[m_idx] < 5) {
g_playerBullets.active[m_idx] = FALSE;
--g_playerBullets.count;
}
}
What it does is if the Y value is smaller than 5, do something, pretty basic. The catch: if Y is an 16 bit value, that condition always fails. If I change the Y type to a char, it works fine.
I checked the assembler but I didn't do for a while so I'm a little rusty about the possible cause. here the 16 bit version:
Code:
0002EFr 1 ; if(g_playerBullets.y[m_idx] < 5) {
0002EFr 1 ;
0002EFr 1 .dbg line, "src/manager/bulletsManager.c", 126
0002EFr 1 A2 00 ldx #$00
0002F1r 1 AD rr rr lda _m_idx
0002F4r 1 0A asl a
0002F5r 1 90 02 bcc L0106
0002F7r 1 E8 inx
0002F8r 1 18 clc
0002F9r 1 69 rr L0106: adc #<(_g_playerBullets+6)
0002FBr 1 85 rr sta ptr1
0002FDr 1 8A txa
0002FEr 1 69 rr adc #>(_g_playerBullets+6)
000300r 1 85 rr sta ptr1+1
000302r 1 A0 01 ldy #$01
000304r 1 B1 rr lda (ptr1),y
000306r 1 AA tax
000307r 1 88 dey
000308r 1 B1 rr lda (ptr1),y
00030Ar 1 C9 05 cmp #$05
00030Cr 1 8A txa
00030Dr 1 E9 00 sbc #$00
00030Fr 1 50 02 bvc L00BE
000311r 1 49 80 eor #$80
000313r 1 10 16 L00BE: bpl L00B7
000315r 1 ;
000315r 1 ; g_playerBullets.active[m_idx] = FALSE;
000315r 1 ;
000315r 1 .dbg line, "src/manager/bulletsManager.c", 127
000315r 1 AC rr rr ldy _m_idx
000318r 1 A9 00 lda #$00
00031Ar 1 99 rr rr sta _g_playerBullets+12,y
00031Dr 1 ;
00031Dr 1 ; --g_playerBullets.count;
00031Dr 1 ;
00031Dr 1 .dbg line, "src/manager/bulletsManager.c", 128
00031Dr 1 AD rr rr lda _g_playerBullets+25
000320r 1 38 sec
000321r 1 E9 01 sbc #$01
000323r 1 8D rr rr sta _g_playerBullets+25
000326r 1 B0 03 bcs L00B7
000328r 1 CE rr rr dec _g_playerBullets+25+1
00032Br 1 ;
00032Br 1 ; if(g_playerBullets.active[m_idx]) {
00032Br 1 ;
00032Br 1 .dbg line, "src/manager/bulletsManager.c", 135
00032Br 1 AC rr rr L00B7: ldy _m_idx
0002EFr 1 ;
0002EFr 1 .dbg line, "src/manager/bulletsManager.c", 126
0002EFr 1 A2 00 ldx #$00
0002F1r 1 AD rr rr lda _m_idx
0002F4r 1 0A asl a
0002F5r 1 90 02 bcc L0106
0002F7r 1 E8 inx
0002F8r 1 18 clc
0002F9r 1 69 rr L0106: adc #<(_g_playerBullets+6)
0002FBr 1 85 rr sta ptr1
0002FDr 1 8A txa
0002FEr 1 69 rr adc #>(_g_playerBullets+6)
000300r 1 85 rr sta ptr1+1
000302r 1 A0 01 ldy #$01
000304r 1 B1 rr lda (ptr1),y
000306r 1 AA tax
000307r 1 88 dey
000308r 1 B1 rr lda (ptr1),y
00030Ar 1 C9 05 cmp #$05
00030Cr 1 8A txa
00030Dr 1 E9 00 sbc #$00
00030Fr 1 50 02 bvc L00BE
000311r 1 49 80 eor #$80
000313r 1 10 16 L00BE: bpl L00B7
000315r 1 ;
000315r 1 ; g_playerBullets.active[m_idx] = FALSE;
000315r 1 ;
000315r 1 .dbg line, "src/manager/bulletsManager.c", 127
000315r 1 AC rr rr ldy _m_idx
000318r 1 A9 00 lda #$00
00031Ar 1 99 rr rr sta _g_playerBullets+12,y
00031Dr 1 ;
00031Dr 1 ; --g_playerBullets.count;
00031Dr 1 ;
00031Dr 1 .dbg line, "src/manager/bulletsManager.c", 128
00031Dr 1 AD rr rr lda _g_playerBullets+25
000320r 1 38 sec
000321r 1 E9 01 sbc #$01
000323r 1 8D rr rr sta _g_playerBullets+25
000326r 1 B0 03 bcs L00B7
000328r 1 CE rr rr dec _g_playerBullets+25+1
00032Br 1 ;
00032Br 1 ; if(g_playerBullets.active[m_idx]) {
00032Br 1 ;
00032Br 1 .dbg line, "src/manager/bulletsManager.c", 135
00032Br 1 AC rr rr L00B7: ldy _m_idx
My guess is something is going on around line 30F~313, where for some reason, because how the code was generated, it causes the branching to fails with small numbers but I'm too rusty to see it at all but I think I'm close to the cause.
Here's the 8 bit version (Y is now a char):
Code:
0002AFr 1 ; if(g_playerBullets.y[m_idx] < 5) {
0002AFr 1 ;
0002AFr 1 .dbg line, "src/manager/bulletsManager.c", 126
0002AFr 1 AC rr rr ldy _m_idx
0002B2r 1 B9 rr rr lda _g_playerBullets+6,y
0002B5r 1 C9 05 cmp #$05
0002B7r 1 B0 16 bcs L00BB
0002B9r 1 ;
0002B9r 1 ; g_playerBullets.active[m_idx] = FALSE;
0002B9r 1 ;
0002B9r 1 .dbg line, "src/manager/bulletsManager.c", 127
0002B9r 1 AC rr rr ldy _m_idx
0002BCr 1 A9 00 lda #$00
0002BEr 1 99 rr rr sta _g_playerBullets+9,y
0002C1r 1 ;
0002C1r 1 ; --g_playerBullets.count;
0002C1r 1 ;
0002C1r 1 .dbg line, "src/manager/bulletsManager.c", 128
0002C1r 1 AD rr rr lda _g_playerBullets+22
0002C4r 1 38 sec
0002C5r 1 E9 01 sbc #$01
0002C7r 1 8D rr rr sta _g_playerBullets+22
0002CAr 1 B0 03 bcs L00BB
0002CCr 1 CE rr rr dec _g_playerBullets+22+1
0002CFr 1 ;
0002CFr 1 ; if(g_playerBullets.active[m_idx]) {
0002CFr 1 ;
0002CFr 1 .dbg line, "src/manager/bulletsManager.c", 135
0002CFr 1 AC rr rr L00BB: ldy _m_idx
0002AFr 1 ;
0002AFr 1 .dbg line, "src/manager/bulletsManager.c", 126
0002AFr 1 AC rr rr ldy _m_idx
0002B2r 1 B9 rr rr lda _g_playerBullets+6,y
0002B5r 1 C9 05 cmp #$05
0002B7r 1 B0 16 bcs L00BB
0002B9r 1 ;
0002B9r 1 ; g_playerBullets.active[m_idx] = FALSE;
0002B9r 1 ;
0002B9r 1 .dbg line, "src/manager/bulletsManager.c", 127
0002B9r 1 AC rr rr ldy _m_idx
0002BCr 1 A9 00 lda #$00
0002BEr 1 99 rr rr sta _g_playerBullets+9,y
0002C1r 1 ;
0002C1r 1 ; --g_playerBullets.count;
0002C1r 1 ;
0002C1r 1 .dbg line, "src/manager/bulletsManager.c", 128
0002C1r 1 AD rr rr lda _g_playerBullets+22
0002C4r 1 38 sec
0002C5r 1 E9 01 sbc #$01
0002C7r 1 8D rr rr sta _g_playerBullets+22
0002CAr 1 B0 03 bcs L00BB
0002CCr 1 CE rr rr dec _g_playerBullets+22+1
0002CFr 1 ;
0002CFr 1 ; if(g_playerBullets.active[m_idx]) {
0002CFr 1 ;
0002CFr 1 .dbg line, "src/manager/bulletsManager.c", 135
0002CFr 1 AC rr rr L00BB: ldy _m_idx
In that case, there is no need to extract the address in ptr to extract the value since it's 8 bit, the value is loaded in A and proper testing is done, bcs when it's false.
I have been bitten many times by that bug and was sure I was doing something wrong but now I'm getting quite convinced that something is not working as expected, unless I'm doing something in C that I was not supposed to do in cc65? I read the manual, I don't remember anything about testing 16/8 values against each other.
Any information on the subject would be greatly appreciated.