Rhythm Tengoku crashes during boot
Closed this issue · 3 comments
Game goes into a white screen (so has handled at least some level of processing first) then crashes attempting to execute 0x0804C870.
r0:000007E7 r1:030000B4 r2:000003FD r3:03000748
r4:030046A0 r5:03004498 r6:00000000 r7:00000000
r8:00000000 r9:00000000 r10:00000000 r11:00000000
r12:040000DC r13:03007FE0 r14:0804C86A r15:0804C878
cpsr: 00000093 -----I- Arm Supervisor
Cycle: 4968749
0804C870: 1C05B530 Coprocessor Data Transfer
Is the state of the cpu at this point. The fact that it's running in supervisor mode at that point is a bit suspect but I haven't looked into whats happening around that or how it got there.
r0:00000138 r1:03000098 r2:00000000 r3:00000000
r4:030046A0 r5:03004498 r6:00000000 r7:00000000
r8:00000000 r9:00000000 r10:00000000 r11:00000000
r12:040000B8 r13:03007F88 r14:08001397 r15:00000140
cpsr: 20000092 --C--I- Arm Irq
Cycle: 4968689
00000138: E8BD500F LDMIA SP!, {r0r1r2r3r12r14}
r0:00000000 r1:08000000 r2:000003FD r3:03000748
r4:030046A0 r5:03004498 r6:00000000 r7:00000000
r8:00000000 r9:00000000 r10:00000000 r11:00000000
r12:040000DC r13:03007FA0 r14:08001968 r15:00000144
cpsr: 20000092 --C--I- Arm Irq
Cycle: 4968697
0000013C: E25EF004 SUBS PC, LR, #4
Compared to mgba
r0: 00000138 r1: 03000098 r2: 00000000 r3: 00000000
r4: 030046A0 r5: 03004498 r6: 00000000 r7: 00000000
r8: 00000000 r9: 00000000 r10: 00000000 r11: 00000000
r12: 040000B8 r13: 03007F88 r14: 08001397 r15: 0000013C
cpsr: 20000092 [--C-I--]
Cycle: 4537864
00000138: E8BD500F ldmia sp!, {r0-r3,r12,lr}
> n
r0: 0000006D r1: 030000B4 r2: 0000DE36 r3: 03000748
r4: 030046A0 r5: 03004498 r6: 00000000 r7: 00000000
r8: 00000000 r9: 00000000 r10: 00000000 r11: 00000000
r12: 040000DC r13: 03007FA0 r14: 0800196E r15: 00000140
cpsr: 20000092 [--C-I--]
Cycle: 4537872
0000013C: E25EF004 subs pc, lr, #4
So values between 03007F88 and 03007FA0 are being read back differently in each case. Most likely cause is going to be something with banked SPs if i had to guess
Entry point to the broken area is SWI 12 (Cpu fast set) at 0x0804C868. That in turns does BX R12 to get to the specific interrupt taking it to 0x00000BC4. Eventually that jumps to supervisor mode with an msr from r12=0xD3. That then jumps to IRQ mode with movs pc, lr
having explicitly set MSR spsr, r11=0xB2 (note that it returns to thumb mode here as well)
All of this at that point is correct in my emulator as well, just noting my debugging process.
0x0800139E does a BX=r0=0x138 which returns to arm mode and goes back to the IRQ handler in bios
At 13C it then does subs pc, lr, #4
which on mgba sets cpsr to 2000003F
and on mine sets cpsr to 00000093
.
Where does cpsr come from in that case? The current SPSR. Which should be from the last mode switch I think.
I think what's going wrong here is that we're switching into System mode (which doesn't have an SPSR) and then when we switch out again we're using the SPSR which shouldn't have existed to write as the new CPSR. I'm not 100% sure what the right behaviour is yet but I know I don't properly account for User/System modes not having an SPSR
Trying to consolidate what I've worked out into the specific issue.
Executing 0x188 (MOVS R15,R14) which returns from bios to user code has
- CPSR = D3
- SPSR = B2
On both mine and no$gba.
I then set SPSR_Irq to 0x93 whereas no$gba appears to set it to 0x6000_003F which is what it was in IRQ mode back before the SWI that caused this code.
So SPSR_Irq would still be 0x6000_003F at this point but why does MOVS PC,LR not set SPSR on a mode switch from Supervisor to IRQ? I thought CPSR was copied to SPSR on any mode switch. Is it not done on data operations? What about MSR based mode switches? Just interrupts and SWI?