Skip to content

Commit

Permalink
Improved protected bios reading; fixes #90
Browse files Browse the repository at this point in the history
Fixes Wakeboarding Unleashed featuring Shaun Murray and the Super Mario Advance Mario Bros minigame
  • Loading branch information
Gericom committed Feb 6, 2020
1 parent b740476 commit e5eade0
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 18 deletions.
14 changes: 11 additions & 3 deletions arm9/source/bios.s
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,16 @@ gGbaBios:

.global bios_swiVeneer
bios_swiVeneer:
ldr pc,= (gGbaBios + 0x140)
b swiPatch

.pool
.space 0x4000 - (. - gGbaBios)

.space 0x4000 - (. - gGbaBios)
swiPatch:
push {r0,r1}
ldr r0,= gBiosOp
ldr r1,= 0xE3A02004
str r1, [r0]
pop {r0, r1}
b (gGbaBios + 0x140)

.pool
7 changes: 4 additions & 3 deletions arm9/source/bios.vram.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
#include "vram.h"
#include "sd_access.h"
#include "fat/ff.h"
#include "patchUtil.h"
#include "bios.h"

extern "C" void bios_cpuset_cache_patch();
extern "C" void bios_cpufastset_cache_patch();
extern "C" void bios_softResetPatch();

/**
* \brief Relocates the gba bios so it can be executed from vram
Expand Down Expand Up @@ -89,9 +91,8 @@ static void applyRelocation()
*/
static void applyPatches()
{
//Make bios jump to 02040000
//todo: check if this is even needed anymore, it may be handled by prefetch abort just fine
//gGbaBios[0xCC >> 2] = 0xE3A0E781;
//patch for having the right protected op at boot
gGbaBios[0xDC >> 2] = pcu_makeArmBranch((u32)&gGbaBios[0xDC >> 2], (u32)&bios_softResetPatch);

//fix post boot redirect
//todo: maybe I should correctly implement that register instead
Expand Down
12 changes: 11 additions & 1 deletion arm9/source/bios_patches.s
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,14 @@ bios_cpufastset_cache_patch:
//don't use the armv5 interworking!
ldr r4,= (gGbaBios + 0xBC8)
bx r4
#endif
#endif

.global bios_softResetPatch
bios_softResetPatch:
//set the right protected bios opcode
ldr r0,= gBiosOp
ldr r1,= 0xE129F000
str r1, [r0]
mov r0, #0
mov r1, #0
bx lr
15 changes: 12 additions & 3 deletions arm9/source/dtcm_data.s
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.section .dtcm2
.section ".dtcm2","ax"
.altmacro

#include "consts.s"
Expand Down Expand Up @@ -309,6 +309,15 @@ timer_shadow_regs_dtcm:
.short 0 //reload value
.endr

//the current bios opcode that is returned if you do a protected read
//[00DCh+8] = 0xE129F000, after startup and softreset //before this address 0x27C is read
//[0134h+8] = 0xE25EF004, during irq execution
//[013Ch+8] = 0xE55EC002, after irq execution
//[0188h+8] = 0xE3A02004, after swi execution; reads between 0x1C8 and 0x274
.global gBiosOp
gBiosOp:
.word 0xE3A02004

//for some reason the file is ignored without this nop here
nop
nop
@ nop
@ nop
14 changes: 6 additions & 8 deletions arm9/source/emu/handle_address_read.s
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@

#include "consts.s"

//bios_op = 0xE129F000 //[00DCh+8] after startup and softreset //before this address 0x27C is read
//bios_op = 0xE25EF004 //[0134h+8] during irq execution
//bios_op = 0xE55EC002 //[013Ch+8] after irq execution
bios_op = 0xE3A02004 //[0188h+8] after swi execution; reads between 0x1C8 and 0x274

.global read_address_from_handler_32bit
read_address_from_handler_32bit:
cmp r9, #0x10000000
Expand Down Expand Up @@ -54,8 +49,9 @@ read_address_from_handler_bios_32:
cmp r10, #0x4000
ldrlt r10, [r9] //if the opcode is in the bios, read the data
bxlt lr
ldr r10,= bios_op
ldr r10,= gBiosOp
and r11, r9, #3
ldr r10, [r10]
mov r11, r11, lsl #3
mov r10, r10, ror r11
bx lr
Expand Down Expand Up @@ -208,7 +204,8 @@ read_address_from_handler_bios_16:
sub r10, #8
cmp r10, #0x4000
ldrlth r10, [r9] //if the opcode is in the bios, read the data
ldrge r10,= (bios_op & 0xFFFF)
ldrge r10,= gBiosOp
ldrgeh r10, [r10]
tst r9, #1
movne r10, r10, ror #8
bx lr
Expand Down Expand Up @@ -368,8 +365,9 @@ read_address_from_handler_bios_8:
cmp r10, #0x4000
ldrltb r10, [r9] //if the opcode is in the bios, read the data
bxlt lr
ldr r10,= bios_op
ldr r10,= gBiosOp
and r11, r9, #3
ldr r10, [r10]
mov r11, r11, lsl #3
mov r10, r10, ror r11
and r10, r10, #0xFF
Expand Down
10 changes: 10 additions & 0 deletions arm9/source/emu/irq.s
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,11 @@ irq_cont_handle_gba:
bic r2, #(1 << 16)
ldr r1,= pu_data_permissions
str r2, [r12, #0x210]

ldr r0,= gBiosOp
ldr r2,= 0xE25EF004
str r2, [r0]

mcr p15, 0, r1, c5, c0, 2

ADR LR, loc_138
Expand All @@ -227,6 +232,11 @@ loc_138:
ldr r2,= pu_data_permissions
orr r1, #(1 << 16)
str r1, [r12, #0x210]

ldr r0,= gBiosOp
ldr r1,= 0xE55EC002
str r1, [r0]

mcr p15, 0, r2, c5, c0, 2

LDMFD SP!, {R0-R3,R12,LR}
Expand Down
3 changes: 3 additions & 0 deletions arm9/source/patchUtil.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#pragma once

u32 pcu_makeArmBranch(u32 instAddr, u32 target);
7 changes: 7 additions & 0 deletions arm9/source/patchUtil.vram.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include "vram.h"
#include "patchUtil.h"

u32 pcu_makeArmBranch(u32 instAddr, u32 target)
{
return 0xEA000000 | (((target >> 2) - (instAddr >> 2) - 2) & 0xFFFFFF);
}

0 comments on commit e5eade0

Please sign in to comment.