Rewrite ARM7 stub.

Some small ARM9 code cleanup.
This commit is contained in:
profi200 2020-04-19 15:24:30 +02:00
parent 602ec58777
commit 3c79369710
No known key found for this signature in database
GPG Key ID: 17B42AE5911139F3
7 changed files with 51 additions and 49 deletions

View File

@ -5,4 +5,5 @@
extern const u32 _arm7_stub_start[];
extern const u32 _arm7_stub_swi[];
extern const u32 _arm7_stub_end[];

View File

@ -2,5 +2,5 @@
void LGY_prepareLegacyMode(void);
void LGY_prepareLegacyMode(bool gbaBios);
void LGY_backupGbaSave(void);

View File

@ -33,7 +33,7 @@
typedef enum
{
IPC_CMD9_PREPARE_AGB = MAKE_CMD(0, 0, 0, 0),
IPC_CMD9_PREPARE_AGB = MAKE_CMD(0, 0, 0, 1),
IPC_CMD9_PREPARE_POWER = MAKE_CMD(1, 0, 0, 0)
} IpcCmd9;

View File

@ -34,7 +34,8 @@ static void lgySleepIrqHandler(u32 intSource)
void LGY_prepareLegacyMode(void)
{
PXI_sendCmd(IPC_CMD9_PREPARE_AGB, NULL, 0);
const u32 cmdBuf = false;
PXI_sendCmd(IPC_CMD9_PREPARE_AGB, &cmdBuf, 1);
LGYFB_init();

View File

@ -3,56 +3,51 @@
.fpu softvfp
.global _arm7_stub_start
.global _arm7_stub_swi
.global _arm7_stub_end
.type _arm7_stub_start %function
.type gbaReset %function
.type waitCycles %function
.align 2
@ Must be located at 0x3007E00.
_arm7_stub_start:
mov r0, #0xD3
adr r1, _arm7_stub_start + 0x200 @ 0x3008000
msr CPSR_cxsf, r0
ldr sp, =0x03008000
mov r0, #0xD2
mov sp, r1
msr CPSR_cxsf, r0
ldr sp, =0x03007FA0
mov r0, #0xDF
sub sp, r1, #0x60 @ 0x3007FA0
msr CPSR_cxsf, r0
ldr sp, =0x03007F80
mov r3, #0x04700000
mov r0, #1
str r0, [r3] @ Disable BIOS overlay.
mov r0, #0x100
bl waitCycles
ldr r0, =0x1999E8
bl waitCycles
mov r3, #0x4700000
adr r2, _arm7_stub_16 + 1
sub sp, r1, #0x80 @ 0x3007F80
bx r2
ldr r3, =0x04000006 @ REG_VCOUNT
.thumb
_arm7_stub_16:
mov r0, #1
str r0, [r3] @ Disable BIOS overlay.
@ The original ARM7 stub waits 256 cycles here (for the BIOS overlay disable?).
@ The original ARM7 stub waits 1677800 cycles (100 ms) here.
lsl r3, r0, #26 @ 0x4000000
wait_vcount_160_lp:
ldrb r0, [r3]
cmp r0, #160 @ Wait for REG_VCOUNT = 160.
ldrb r0, [r3, #6] @ REG_VCOUNT
cmp r0, #160 @ Wait for REG_VCOUNT == 160.
bne wait_vcount_160_lp
mov r4, r3 @ Needed for function call 0xBC below.
mov r0, #0xFF
bl gbaReset
_arm7_stub_swi:
swi 0x10 @ RegisterRamReset
@swi 0x26 @ HardReset (BIOS animation)
mov r0, #0xBC
mov r2, #0
mov r4, #0x04000000
mov lr, #0xBC
bx lr
bx r0
.pool
gbaReset:
swi 0x10000 @ RegisterRamReset
@swi 0x260000 @ HardReset
bx lr
waitCycles:
subs r0, r0, #4
bcs waitCycles
bx lr
.align 2
_arm7_stub_end:

View File

@ -22,8 +22,12 @@
#define REGs_LGY_GBA_SAVE_TIMING ((vu32*)(LGY_REGS_BASE + 0x120))
#define MAX_ROM_SIZE (1024u * 1024u * 32u)
#define MAX_SAVE_SIZE (1024u * 128u)
#define MAX_ROM_SIZE (1024u * 1024u * 32u)
#define MAX_SAVE_SIZE (1024u * 128u)
#define ARM7_STUB_LOC (0x3007E00u)
#define ARM7_STUB_LOC9 (0x80BFE00u)
#define ROM_LOC (0x20000000u)
#define SAVE_LOC (0x08080000u)
static FATFS g_sd = {0};
@ -32,16 +36,17 @@ static u32 g_saveHash[8] = {0};
void LGY_prepareLegacyMode(void)
void LGY_prepareLegacyMode(bool gbaBios)
{
REG_LGY_MODE = 2; // GBA mode
// BIOS overlay
REGs_LGY_A7_VECTOR[0] = 0xE51FF004; //ldr pc, [pc, #-4]
REGs_LGY_A7_VECTOR[1] = 0x03007E00;
// GBA address: 0x03007E00
NDMA_copy((u32*)0x080BFE00, _arm7_stub_start, (u32)_arm7_stub_end - (u32)_arm7_stub_start);
//iomemcpy((u32*)0x080BFE00, _arm7_stub_start, (u32)_arm7_stub_end - (u32)_arm7_stub_start);
REGs_LGY_A7_VECTOR[1] = ARM7_STUB_LOC;
NDMA_copy((u32*)ARM7_STUB_LOC9, _arm7_stub_start, (u32)_arm7_stub_end - (u32)_arm7_stub_start);
//iomemcpy((u32*)ARM7_STUB_LOC9, _arm7_stub_start, (u32)_arm7_stub_end - (u32)_arm7_stub_start);
// Patch swi 0x10 (RegisterRamReset) to swi 0x26 (HardReset).
if(gbaBios) *((u8*)(ARM7_STUB_LOC9 + ((u32)_arm7_stub_swi - (u32)_arm7_stub_start))) = 0x26;
REG_LGY_GBA_SAVE_TYPE = 0xE;
static const u32 saveStuff[4] = {0x27C886, 0x8CE35, 0x184, 0x31170};
@ -55,7 +60,7 @@ void LGY_prepareLegacyMode(void)
{
if((romSize = f_size(&f)) > MAX_ROM_SIZE) panic();
u8 *ptr = (u8*)0x20000000u;
u8 *ptr = (u8*)ROM_LOC;
UINT read;
FRESULT res;
while((res = f_read(&f, ptr, 0x100000u, &read)) == FR_OK && read == 0x100000u)
@ -70,17 +75,17 @@ void LGY_prepareLegacyMode(void)
if(f_open(&f, "sdmc:/rom.sav", FA_OPEN_EXISTING | FA_READ) == FR_OK)
{
UINT read;
if(f_read(&f, (void*)0x08080000, MAX_SAVE_SIZE, &read) != FR_OK) panic();
if(f_read(&f, (void*)SAVE_LOC, MAX_SAVE_SIZE, &read) != FR_OK) panic();
f_close(&f);
sha((u32*)0x08080000, g_saveSize, g_saveHash, SHA_INPUT_BIG | SHA_MODE_256, SHA_OUTPUT_BIG);
sha((u32*)SAVE_LOC, g_saveSize, g_saveHash, SHA_INPUT_BIG | SHA_MODE_256, SHA_OUTPUT_BIG);
}
else NDMA_fill((u32*)0x08080000, 0xFFFFFFFFu, g_saveSize);
else NDMA_fill((u32*)SAVE_LOC, 0xFFFFFFFFu, g_saveSize);
}
// Pad ROM area with "open bus" value.
if(romSize < MAX_ROM_SIZE)
NDMA_fill((u32*)(0x20000000 + romSize), 0xFFFFFFFFu, MAX_ROM_SIZE - romSize);
NDMA_fill((u32*)(ROM_LOC + romSize), 0xFFFFFFFFu, MAX_ROM_SIZE - romSize);
}
void LGY_backupGbaSave(void)
@ -91,14 +96,14 @@ void LGY_backupGbaSave(void)
REG_LGY_GBA_SAVE_MAP = 1;
u32 newHash[8];
sha((u32*)0x08080000, g_saveSize, newHash, SHA_INPUT_BIG | SHA_MODE_256, SHA_OUTPUT_BIG);
sha((u32*)SAVE_LOC, g_saveSize, newHash, SHA_INPUT_BIG | SHA_MODE_256, SHA_OUTPUT_BIG);
if(memcmp(g_saveHash, newHash, 32) != 0) // Backup save if it changed.
{
FIL f;
if(f_open(&f, "sdmc:/rom.sav", FA_OPEN_ALWAYS | FA_WRITE) == FR_OK)
{
UINT written;
if(f_write(&f, (void*)0x08080000, g_saveSize, &written) != FR_OK) panic();
if(f_write(&f, (void*)SAVE_LOC, g_saveSize, &written) != FR_OK) panic();
f_close(&f);
}
}

View File

@ -36,7 +36,7 @@ u32 IPC_handleCmd(u8 cmdId, u32 inBufs, u32 outBufs, const u32 *const buf)
switch(cmdId)
{
case IPC_CMD_ID_MASK(IPC_CMD9_PREPARE_AGB):
LGY_prepareLegacyMode();
LGY_prepareLegacyMode(*buf);
break;
case IPC_CMD_ID_MASK(IPC_CMD9_PREPARE_POWER):
LGY_backupGbaSave();