I ran across this while working on my Millfork NES game, and initially patched it up with some inline assembly because I wanted to keep going, but it's getting to the point of being annoying. I can try to create a minimal reproducible example if that's necessary, but this is my code:
// i'm using addresses for these so my emulator script for drawing a debug overlay knows where to find them
array(word) enemy_xs[12] align(fast) @ $a8
array enemy_ys[12] @ $62
array enemy_types[12] @ $580
array enemy_healths[12] @ $ca
array enemy_data1[12] @ $f1
array enemy_data2[12] @ $6f
array enemy_data3[12] @ $1b
array enemy_tags[12] @ $9d
byte enemy_count @ $9a
// [...]
// part of the code for enemies dying
if (enemy_healths[i] == 0 && enemy_flags[enemy_types[i]] & $20 == 0) {
create_effect($80, enemy_xs[i], enemy_ys[i], $20, 0) // enemy dying from damage
}
destroy_enemy(i)
i += 1
On optimization level 1 (which I don't want to use unless I have to), those arguments are compiled into
LDA #$80
STA create_effect$type
LDA main$i
ASL
TAY
LDA $A8, Y
INY
STA create_effect$x
LDA $A8, Y
STA create_effect$x + 1
LDY main$i
LDA $62, Y
STA create_effect$y
LDA #$20
STA create_effect$timer
LDA #0
STA create_effect$flags
On O2 and up, we instead get
LDA main$i
ASL
TAY
LDA $A8, Y
STA create_effect$x + 1
STA create_effect$x
LDY main$i
LDA $62, Y
STA create_effect$y
LDA #$80
Some of the arguments are optimized into registers (yay!) but the sketchy thing here is those two STA back to back. The low and high bytes of entries of enemy_xs are NOT the same. This has shown up in other situations before involving loading from array of words.
I ran across this while working on my Millfork NES game, and initially patched it up with some inline assembly because I wanted to keep going, but it's getting to the point of being annoying. I can try to create a minimal reproducible example if that's necessary, but this is my code:
On optimization level 1 (which I don't want to use unless I have to), those arguments are compiled into
On O2 and up, we instead get
Some of the arguments are optimized into registers (yay!) but the sketchy thing here is those two
STAback to back. The low and high bytes of entries ofenemy_xsare NOT the same. This has shown up in other situations before involving loading from array of words.