parent
602ec58777
commit
3c79369710
|
@ -5,4 +5,5 @@
|
|||
|
||||
|
||||
extern const u32 _arm7_stub_start[];
|
||||
extern const u32 _arm7_stub_swi[];
|
||||
extern const u32 _arm7_stub_end[];
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
|
||||
|
||||
|
||||
void LGY_prepareLegacyMode(void);
|
||||
void LGY_prepareLegacyMode(bool gbaBios);
|
||||
void LGY_backupGbaSave(void);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue