Added more registers and documentation.

Added currently unused GBA reset code.
Other small changes.
This commit is contained in:
profi200 2020-06-19 17:17:21 +02:00
parent c9cd1c6eea
commit fd0ee01abb
No known key found for this signature in database
GPG Key ID: 17B42AE5911139F3
3 changed files with 38 additions and 24 deletions

View File

@ -107,10 +107,10 @@ Result LGY_setGbaRtc(const GbaRtc rtc);
Result LGY_getGbaRtc(GbaRtc *const out);
Result LGY_backupGbaSave(void);
#ifdef ARM11
Result LGY_prepareGbaMode(bool gbaBios, const char *const romPath, const char *const savePath);
Result LGY_prepareGbaMode(bool biosIntro, const char *const romPath, const char *const savePath);
void LGY_switchMode(void);
void LGY_handleEvents(void);
void LGY_deinit(void);
#elif ARM9
Result LGY_prepareGbaMode(bool gbaBios, u16 saveType, const char *const savePath);
Result LGY_prepareGbaMode(bool biosIntro, u16 saveType, const char *const savePath);
#endif

View File

@ -14,14 +14,17 @@
#define LGY_REGS_BASE (IO_MEM_ARM9_ARM11 + 0x41100)
#define REG_LGY_MODE *((vu16*)(LGY_REGS_BASE + 0x00))
#define REG_LGY_SLEEP *((vu16*)(LGY_REGS_BASE + 0x04))
#define REG_LGY_UNK *((vu16*)(LGY_REGS_BASE + 0x08)) // IRQ related?
#define REG_LGY_PADCNT *((vu16*)(LGY_REGS_BASE + 0x0A)) // ARM7 "KEYCNT"
#define REG_LGY_PAD_SEL *((vu16*)(LGY_REGS_BASE + 0x10)) // Select which keys to override.
#define REG_LGY_PAD_VAL *((vu16*)(LGY_REGS_BASE + 0x12)) // Override value.
#define REG_LGY_GPIO_SEL *((vu16*)(LGY_REGS_BASE + 0x14)) // Select which GPIOs to override.
#define REG_LGY_GPIO_VAL *((vu16*)(LGY_REGS_BASE + 0x16)) // Override value.
#define REG_LGY_MODE *(( vu16*)(LGY_REGS_BASE + 0x00))
#define REG_LGY_SLEEP *(( vu16*)(LGY_REGS_BASE + 0x04))
#define REG_LGY_UNK *((const vu16*)(LGY_REGS_BASE + 0x08)) // IRQ related?
#define REG_LGY_PADCNT *((const vu16*)(LGY_REGS_BASE + 0x0A)) // ARM7 "KEYCNT"
#define REG_LGY_PAD_SEL *(( vu16*)(LGY_REGS_BASE + 0x10)) // Select which keys to override.
#define REG_LGY_PAD_VAL *(( vu16*)(LGY_REGS_BASE + 0x12)) // Override value.
#define REG_LGY_GPIO_SEL *(( vu16*)(LGY_REGS_BASE + 0x14)) // Select which GPIOs to override.
#define REG_LGY_GPIO_VAL *(( vu16*)(LGY_REGS_BASE + 0x16)) // Override value.
#define REG_LGY_UNK2 *(( vu8*)(LGY_REGS_BASE + 0x18)) // DSi gamecard detection select?
#define REG_LGY_UNK3 *(( vu8*)(LGY_REGS_BASE + 0x19)) // DSi gamecard detection value?
#define REG_LGY_UNK4 *((const vu8*)(LGY_REGS_BASE + 0x20)) // Some legacy status bits?
@ -195,7 +198,7 @@ static void setupFcramForGbaMode(void)
while(REG_PDN_FCRAM_CNT & PDN_FCRAM_CNT_CLK_E_ACK); // Wait until clock is disabled.
}
Result LGY_prepareGbaMode(bool gbaBios, const char *const romPath, const char *const savePath)
Result LGY_prepareGbaMode(bool biosIntro, const char *const romPath, const char *const savePath)
{
// Load the ROM image.
u32 romSize;
@ -209,7 +212,7 @@ Result LGY_prepareGbaMode(bool gbaBios, const char *const romPath, const char *c
u32 cmdBuf[4];
cmdBuf[0] = (u32)savePath;
cmdBuf[1] = strlen(savePath) + 1;
cmdBuf[2] = gbaBios;
cmdBuf[2] = biosIntro;
cmdBuf[3] = saveType;
res = PXI_sendCmd(IPC_CMD9_PREPARE_GBA, cmdBuf, 4);
if(res != RES_OK) return res;

View File

@ -14,13 +14,13 @@
#define LGY_REGS_BASE (IO_MEM_ARM9_ONLY + 0x18000)
#define REG_LGY_MODE *((vu16*)(LGY_REGS_BASE + 0x000))
#define REGs_LGY_A7_VECTOR ((vu32*)(LGY_REGS_BASE + 0x080)) // ARM7 vector override 32 bytes.
#define REGs_LGY_A7_VECTOR ((vu32*)(LGY_REGS_BASE + 0x080)) // ARM7 vector override 32 bytes. Writable at runtime.
#define REG_LGY_GBA_SAVE_TYPE *((vu16*)(LGY_REGS_BASE + 0x100))
#define REG_LGY_GBA_SAVE_MAP *((vu8* )(LGY_REGS_BASE + 0x104)) // Remaps the GBA save to ARM9 if set to 1.
#define REG_LGY_GBA_RTC_CNT *((vu16*)(LGY_REGS_BASE + 0x108))
#define REG_LGY_GBA_RTC_BCD_DATE *((vu32*)(LGY_REGS_BASE + 0x110))
#define REG_LGY_GBA_RTC_BCD_TIME *((vu32*)(LGY_REGS_BASE + 0x114))
#define REG_LGY_GBA_RTC_HEX_TIME *((vu32*)(LGY_REGS_BASE + 0x118))
#define REG_LGY_GBA_RTC_HEX_TIME *((vu32*)(LGY_REGS_BASE + 0x118)) // Writing bit 7 at runtime completely deadlocks the ARM7.
#define REG_LGY_GBA_RTC_HEX_DATE *((vu32*)(LGY_REGS_BASE + 0x11C))
#define REGs_LGY_GBA_SAVE_TIMING ((vu32*)(LGY_REGS_BASE + 0x120))
@ -44,13 +44,16 @@ NAKED static void _overlay_stub(void)
}
extern const u32 _overlay_stub_size[];
static void setupBiosOverlay(bool gbaBios)
static void setupBiosOverlay(bool biosIntro)
{
iomemcpy(REGs_LGY_A7_VECTOR, (u32*)_overlay_stub, (u32)_overlay_stub_size);
//static const u32 biosVectors[8] = {0xEA000018, 0xEA000004, 0xEA00004C, 0xEA000002,
// 0xEA000001, 0xEA000000, 0xEA000042, 0xE59FD1A0};
//iomemcpy(REGs_LGY_A7_VECTOR, biosVectors, 32);
NDMA_copy((u32*)ARM7_STUB_LOC9, _arm7_stub_start, (u32)_arm7_stub_size);
// Patch swi 0x01 (RegisterRamReset) to swi 0x26 (HardReset).
if(gbaBios) *((u8*)_arm7_stub_swi) = 0x26;
if(biosIntro) *((u8*)_arm7_stub_swi) = 0x26;
}
static void setupSaveType(u16 saveType)
@ -73,11 +76,11 @@ static void setupSaveType(u16 saveType)
iomemcpy(REGs_LGY_GBA_SAVE_TIMING, saveTm, 16);
}
Result LGY_prepareGbaMode(bool gbaBios, u16 saveType, const char *const savePath)
Result LGY_prepareGbaMode(bool biosIntro, u16 saveType, const char *const savePath)
{
REG_LGY_MODE = LGY_MODE_AGB;
setupBiosOverlay(gbaBios);
setupBiosOverlay(biosIntro);
setupSaveType(saveType);
strncpy_s(g_savePath, savePath, 255, 256);
@ -87,16 +90,13 @@ Result LGY_prepareGbaMode(bool gbaBios, u16 saveType, const char *const savePath
FHandle f;
if(fOpen(&f, savePath, FA_OPEN_EXISTING | FA_READ) == RES_OK)
{
// TODO: Should we handle 0 byte files?
res = fRead(f, (void*)SAVE_LOC, MAX_SAVE_SIZE, NULL);
fClose(f);
if(res == RES_OK)
{
sha((u32*)SAVE_LOC, g_saveSize, g_saveHash, SHA_INPUT_BIG | SHA_MODE_256, SHA_OUTPUT_BIG);
}
}
else NDMA_fill((u32*)SAVE_LOC, 0xFFFFFFFFu, g_saveSize);
// Hash the savegame so it's only backed up when changed.
sha((u32*)SAVE_LOC, g_saveSize, g_saveHash, SHA_INPUT_BIG | SHA_MODE_256, SHA_OUTPUT_BIG);
}
return res;
@ -137,6 +137,17 @@ Result LGY_getGbaRtc(GbaRtc *const out)
return RES_GBA_RTC_ERR;
}
/*#include "arm9/hardware/timer.h"
void LGY_gbaReset(void)
{
// Hook the SVC vector for 17 ms and hope it jumps to the
// BIOS reset function skipping the "POSTFLG" check.
REGs_LGY_A7_VECTOR[2] = 0xEA00001F; // SVC_vector: b 0x8C @ resetHandler
TIMER_sleep(17); // Wait 17 ms.
// Restore vector.
REGs_LGY_A7_VECTOR[2] = 0xEA00004C; // SVC_vector: b 0x140 @ svcHandler
}*/
Result LGY_backupGbaSave(void)
{
Result res = RES_OK;