DaveTCode/GBADotnet

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?