move step_arm ldm/stm logic back to post-instruction, fix golden sun issues

This was causing battles and entering the overworld to fail. I saw a
`stmdb r1, {r0, r2, r3, r4, r5, r6, r7, r8, sb, sl, fp, ip}` while r1
was `03000380` and the currently executing instruction was `03000348`.
This means that the store would write over `03000350`, which is the
instruction being read. Because I had incremented r15 _ahead_ of the
instruction, this caused the pipeline to store the wrong values when the
write near r15 was detected. This changes moves the stepping logic back
to _after_ the instruction, and handles the r15 +12 case directly
This commit is contained in:
Matthew Berry 2021-02-20 21:11:28 -08:00
parent 2950d0d0a3
commit 7444832159

View file

@ -14,7 +14,6 @@ module ARM
switch_mode CPU::Mode::USR
end
step_arm # step in advance since str from r15 is 12 ahead
address = @r[rn]
bits_set = count_set_bits(list)
if bits_set == 0 # odd behavior on empty list, tested in gba-suite
@ -35,6 +34,7 @@ module ARM
set_reg(idx, @gba.bus.read_word(address))
else
@gba.bus[address] = @r[idx]
@gba.bus[address] &+= 4 if idx == 15 # pc reads 12 ahead instead of 8
end
address += 4 # can always do these post since the address was accounted for up front
set_reg(rn, final_addr) if write_back && !first_transfer && !(load && bit?(list, rn))
@ -45,5 +45,7 @@ module ARM
if s_bit
switch_mode CPU::Mode.from_value mode.not_nil!
end
step_arm unless load && bit?(list, 15)
end
end