From f9851e6b752f1f792b98eb8c427bae070dee42ac Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 25 Nov 2024 19:22:03 -0800 Subject: [PATCH] GBA BIOS: Move SoftReset implementation to assembly This improves the timing of the SoftReset implementation (though it's still way faster than Nintendo's official implementation), which is important for some multicarts. --- CHANGES | 1 + src/gba/bios.c | 26 +------------------------- src/gba/hle-bios.c | 22 ++++++++++++++++++---- src/gba/hle-bios.s | 43 ++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 62 insertions(+), 30 deletions(-) diff --git a/CHANGES b/CHANGES index f0a3d785f..9f505f816 100644 --- a/CHANGES +++ b/CHANGES @@ -49,6 +49,7 @@ Misc: - GB Serialize: Add missing savestate support for MBC6 and NT (newer) - GBA: Improve detection of valid ELF ROMs - GBA Audio: Remove broken XQ audio pending rewrite + - GBA BIOS: Move SoftReset implementation to assembly - GBA Memory: Improve VRAM access stall cycle estimation - GBA SIO: Rewrite lockstep driver for improved stability - GBA Video: Add special circlular window handling in OpenGL renderer diff --git a/src/gba/bios.c b/src/gba/bios.c index caca48a0b..1ff5004d3 100644 --- a/src/gba/bios.c +++ b/src/gba/bios.c @@ -35,30 +35,6 @@ static int _mulWait(int32_t r) { } } -static void _SoftReset(struct GBA* gba) { - struct ARMCore* cpu = gba->cpu; - ARMSetPrivilegeMode(cpu, MODE_IRQ); - cpu->spsr.packed = 0; - cpu->gprs[ARM_LR] = 0; - cpu->gprs[ARM_SP] = GBA_SP_BASE_IRQ; - ARMSetPrivilegeMode(cpu, MODE_SUPERVISOR); - cpu->spsr.packed = 0; - cpu->gprs[ARM_LR] = 0; - cpu->gprs[ARM_SP] = GBA_SP_BASE_SUPERVISOR; - ARMSetPrivilegeMode(cpu, MODE_SYSTEM); - cpu->gprs[ARM_LR] = 0; - cpu->gprs[ARM_SP] = GBA_SP_BASE_SYSTEM; - int8_t flag = ((int8_t*) gba->memory.iwram)[0x7FFA]; - memset(((int8_t*) gba->memory.iwram) + GBA_SIZE_IWRAM - 0x200, 0, 0x200); - if (flag) { - cpu->gprs[ARM_PC] = GBA_BASE_EWRAM; - } else { - cpu->gprs[ARM_PC] = GBA_BASE_ROM0; - } - _ARMSetMode(cpu, MODE_ARM); - ARMWritePC(cpu); -} - static void _RegisterRamReset(struct GBA* gba) { uint32_t registers = gba->cpu->gprs[0]; struct ARMCore* cpu = gba->cpu; @@ -445,7 +421,7 @@ void GBASwi16(struct ARMCore* cpu, int immediate) { bool useStall = false; switch (immediate) { case GBA_SWI_SOFT_RESET: - _SoftReset(gba); + ARMRaiseSWI(cpu); break; case GBA_SWI_REGISTER_RAM_RESET: _RegisterRamReset(gba); diff --git a/src/gba/hle-bios.c b/src/gba/hle-bios.c index 8f689fa7a..f3c58b62b 100644 --- a/src/gba/hle-bios.c +++ b/src/gba/hle-bios.c @@ -20,7 +20,7 @@ const uint8_t hleBios[GBA_SIZE_BIOS] = { 0x00, 0x00, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe1, 0x04, 0x40, 0xbd, 0xe8, 0x93, 0xf0, 0x29, 0xe3, 0x00, 0x08, 0xbd, 0xe8, 0x0b, 0xf0, 0x69, 0xe1, 0x00, 0x58, 0xbd, 0xe8, 0x0e, 0xf0, 0xb0, 0xe1, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x20, 0xa0, 0xe3, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x01, 0x00, 0x00, + 0x04, 0x20, 0xa0, 0xe3, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x00, 0xb0, 0x01, 0x00, 0x00, 0xb4, 0x01, 0x00, 0x00, 0xb0, 0x01, 0x00, 0x00, 0xcc, 0x01, 0x00, 0x00, 0xc4, 0x01, 0x00, 0x00, 0x48, 0x03, 0x00, 0x00, 0x48, 0x03, 0x00, 0x00, 0x48, 0x03, 0x00, 0x00, 0x48, 0x03, 0x00, 0x00, @@ -79,12 +79,26 @@ const uint8_t hleBios[GBA_SIZE_BIOS] = { 0x00, 0x10, 0x9e, 0xe5, 0x00, 0x00, 0x51, 0xe3, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x00, 0x00, 0x1a, 0xc0, 0xe0, 0x4e, 0xe2, 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x29, 0xe1, 0xc0, 0x00, 0x00, 0x02, - 0x4c, 0xd0, 0x9f, 0xe5, 0x00, 0x50, 0x2d, 0xe9, 0x00, 0xc0, 0x4f, 0xe1, + 0xe0, 0xd0, 0x9f, 0xe5, 0x00, 0x50, 0x2d, 0xe9, 0x00, 0xc0, 0x4f, 0xe1, 0x00, 0xe0, 0x0f, 0xe1, 0x00, 0x50, 0x2d, 0xe9, 0x02, 0xe3, 0xa0, 0xe3, 0x9c, 0xc0, 0xde, 0xe5, 0xa5, 0x00, 0x5c, 0xe3, 0x04, 0x00, 0x00, 0x1a, 0xb4, 0xc0, 0xde, 0xe5, 0x80, 0x00, 0x1c, 0xe3, 0x04, 0xe0, 0x8f, 0xe2, - 0x20, 0xf0, 0x9f, 0x15, 0x20, 0xf0, 0x9f, 0x05, 0x14, 0xd0, 0x9f, 0xe5, + 0xb4, 0xf0, 0x9f, 0x15, 0xb4, 0xf0, 0x9f, 0x05, 0xa8, 0xd0, 0x9f, 0xe5, 0x10, 0xc0, 0x1d, 0xe5, 0x0c, 0xf0, 0x69, 0xe1, 0x00, 0x50, 0x3d, 0xe9, 0x04, 0xf0, 0x5e, 0xe2, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe0, 0xa0, 0x03, - 0xf0, 0x7f, 0x00, 0x03, 0x00, 0x20, 0xfe, 0x09, 0x00, 0xc0, 0xff, 0x09 + 0x00, 0xf0, 0x69, 0xe3, 0x00, 0xe0, 0xa0, 0xe3, 0x90, 0xd0, 0x9f, 0xe5, + 0x92, 0xf0, 0x21, 0xe3, 0x00, 0xf0, 0x69, 0xe3, 0x00, 0xe0, 0xa0, 0xe3, + 0x84, 0xd0, 0x9f, 0xe5, 0x9f, 0xf0, 0x21, 0xe3, 0x00, 0xf0, 0x69, 0xe3, + 0x00, 0xe0, 0xa0, 0xe3, 0x78, 0xd0, 0x9f, 0xe5, 0x93, 0xf0, 0x21, 0xe3, + 0x01, 0x03, 0xa0, 0xe3, 0x02, 0x1c, 0x40, 0xe2, 0x06, 0x00, 0x50, 0xe5, + 0x00, 0x20, 0xa0, 0xe3, 0x00, 0x30, 0xa0, 0xe3, 0x00, 0x40, 0xa0, 0xe3, + 0x00, 0x50, 0xa0, 0xe3, 0x00, 0x60, 0xa0, 0xe3, 0x00, 0x70, 0xa0, 0xe3, + 0x00, 0x80, 0xa0, 0xe3, 0x00, 0x90, 0xa0, 0xe3, 0x00, 0xa0, 0xa0, 0xe3, + 0x00, 0xb0, 0xa0, 0xe3, 0x00, 0xc0, 0xa0, 0xe3, 0xfc, 0x03, 0xa1, 0xe8, + 0x01, 0x03, 0x51, 0xe3, 0xfc, 0xff, 0xff, 0x1a, 0x00, 0x00, 0x50, 0xe3, + 0x00, 0x00, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3, 0x02, 0xe3, 0xa0, 0x03, + 0x02, 0xe4, 0xa0, 0x13, 0x0e, 0xf0, 0xb0, 0xe1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf0, 0x29, 0xe1, 0xf0, 0x7f, 0x00, 0x03, 0x00, 0x20, 0xfe, 0x09, + 0x00, 0xc0, 0xff, 0x09, 0xe0, 0x7f, 0x00, 0x03, 0xa0, 0x7f, 0x00, 0x03, + 0x00, 0x7f, 0x00, 0x03 }; diff --git a/src/gba/hle-bios.s b/src/gba/hle-bios.s index aa77160c1..871d79849 100644 --- a/src/gba/hle-bios.s +++ b/src/gba/hle-bios.s @@ -129,7 +129,6 @@ subs pc, lr, #4 .word 0x03A0E004 @ Unimplemented -SoftReset: RegisterRamReset: Stop: GetBiosChecksum: @@ -358,3 +357,45 @@ ldmdb sp!, {r12, lr} subs pc, lr, #4 .word 0 .word 0x03A0E004 + +SoftReset: +msr spsr, #0 +mov lr, #0 +ldr sp, =0x03007FE0 +msr cpsr_c, #0x92 +msr spsr, #0 +mov lr, #0 +ldr sp, =0x03007FA0 +msr cpsr_c, #0x9F +msr spsr, #0 +mov lr, #0 +ldr sp, =0x03007F00 +msr cpsr_c, #0x93 +mov r0, #0x04000000 +sub r1, r0, #0x200 +ldrb r0, [r0, #-6] +mov r2, #0 +mov r3, #0 +mov r4, #0 +mov r5, #0 +mov r6, #0 +mov r7, #0 +mov r8, #0 +mov r9, #0 +mov r10, #0 +mov r11, #0 +mov r12, #0 +1: +stmia r1!, {r2, r3, r4, r5, r6, r7, r8, r9} +cmp r1, #0x04000000 +bne 1b +cmp r0, #0 +mov r0, #0 +mov r1, #0 +moveq lr, #0x08000000 +movne lr, #0x02000000 +movs pc, lr +.word 0 +.word 0xE129F000 + +.ltorg