millfork
millfork copied to clipboard
Compiler assuming C clear when it isn't?
Millfork has been great for developing my homebrew NES game, and so far it's been totally stable, but either I messed something up or the compiler is getting a bit overeager with an optimization. In my collision detection routine, I have this code:
level_idx = (lo(player_x >> 4) & $1f) | (word(player_y & $f0) << 1)
if (hi(vel_x) & $80 == 0) {
level_idx += 1
}
if (solidity[level_shadow[level_idx]] || (player_y & $0f != 0 && solidity[level_shadow[level_idx+32]])) {
k += 1
}
Using optimization level 8 (same thing happens with 4), I get this assembly:
;
;line:89:main.mfk
; level_idx = (lo(player_x >> 4) & $1f) | (word(player_y & $f0) << 1)
LDA player_x
STA __reg
LDA player_x + 1
LSR
ROR __reg
LSR
ROR __reg
LSR
LDA __reg
ROR
ALR #$3E
STA __reg
TXA
PHA
LDA __reg
PHA
LDA player_y
AND #$F0
PHA
ROL
ROL
AND #1
STA __reg + 1
PLA
ASL
STA __reg
PLA
ORA __reg
STA main$level_idx
PLA
ORA __reg + 1
STA main$level_idx + 1
;
;line:90:main.mfk
; if (hi(vel_x) & $80 == 0) {
BIT vel_x + 1
BMI .fi__00221
;
;line:91:main.mfk
; level_idx += 1
INC main$level_idx
BNE .in__00220
INC main$level_idx + 1
.in__00220:
;
;line:90:main.mfk
; if (hi(vel_x) & $80 == 0) {
.fi__00221:
;
;line:93:main.mfk
; if (solidity[level_shadow[level_idx]] || (player_y & $0f != 0 && solidity[level_shadow[level_idx+32]])) {
LDY main$level_idx
LDA main$level_idx + 1
ADC #3 ; THIS IS WHERE THE BUG IS
STA __reg + 1
STX __reg
LDA (__reg), Y
TAY
LDA solidity.array, Y
BNE .or__00223
LDA player_y
AND #$F
BEQ .fi__00222
LDY main$level_idx
LDA main$level_idx + 1
CLC
ADC #3
STA __reg + 1
LDA #$20
STA __reg
LDA (__reg), Y
TAY
LDA solidity.array, Y
BEQ .fi__00222
.or__00223:
;
;line:94:main.mfk
; k += 1
INX
;
;line:93:main.mfk
; if (solidity[level_shadow[level_idx]] || (player_y & $0f != 0 && solidity[level_shadow[level_idx+32]])) {
.fi__00222:
level_shadow
is located at $0300
, so the address computation optimization makes sense, but that ADC
is causing a bug when carry is set from the most recent ASL
. When I add a CLC
explicitly, or use optimization level 2, the bug disappears. Did I forget something or did the optimizer?