summaryrefslogtreecommitdiff
path: root/arm9/lib/src
diff options
context:
space:
mode:
authorRevo <projectrevotpp@hotmail.com>2021-01-08 19:33:39 -0500
committerGitHub <noreply@github.com>2021-01-08 19:33:39 -0500
commit3289261e5aaddcd67f72513de06a72a379854d5c (patch)
tree3af221138ff7d6e8ad56a4b95a6255a0edc3812b /arm9/lib/src
parentee1f12ce06e865f47511ba200029e0afaafa4255 (diff)
parent1e268426533b6bb78b86e35577c72cd4bb5cbb4c (diff)
Merge pull request #312 from red031000/master
decompile CTRDG_common
Diffstat (limited to 'arm9/lib/src')
-rw-r--r--arm9/lib/src/CTRDG_common.c349
1 files changed, 349 insertions, 0 deletions
diff --git a/arm9/lib/src/CTRDG_common.c b/arm9/lib/src/CTRDG_common.c
new file mode 100644
index 00000000..3d80cf24
--- /dev/null
+++ b/arm9/lib/src/CTRDG_common.c
@@ -0,0 +1,349 @@
+#include "CTRDG_common.h"
+#include "function_target.h"
+#include "syscall.h"
+#include "OS_cache.h"
+#include "OS_protectionRegion.h"
+#include "OS_terminate_proc.h"
+#include "PXI_fifo.h"
+#include "MI_dma.h"
+#include "MI_memory.h"
+
+CTRDGWork CTRDGi_Work;
+
+static BOOL CTRDGi_EnableFlag = FALSE;
+
+ARM_FUNC void CTRDGi_InitCommon(void)
+{
+ SVC_CpuClear(0, &CTRDGi_Work, sizeof(CTRDGi_Work), 32);
+
+ CTRDGi_Work.lockID = (u16)OS_GetLockID();
+}
+
+ARM_FUNC BOOL CTRDG_IsAgbCartridge(void)
+{
+ return (CTRDG_IsExisting() && CTRDGi_IsAgbCartridgeAtInit());
+}
+
+ARM_FUNC BOOL CTRDG_IsOptionCartridge(void)
+{
+ return (CTRDG_IsExisting() && !CTRDGi_IsAgbCartridgeAtInit());
+}
+
+ARM_FUNC BOOL CTRDGi_IsAgbCartridgeAtInit(void)
+{
+ CTRDGModuleInfo *cip = CTRDGi_GetModuleInfoAddr();
+
+ return cip->isAgbCartridge;
+}
+
+ARM_FUNC u32 CTRDG_GetAgbGameCode(void)
+{
+ u32 ret = 0;
+
+ if (CTRDG_IsExisting())
+ {
+ ret = CTRDGi_GetAgbGameCodeAtInit();
+ }
+
+ return ret;
+}
+
+ARM_FUNC u32 CTRDGi_GetAgbGameCodeAtInit(void)
+{
+ CTRDGModuleInfo *cip = CTRDGi_GetModuleInfoAddr();
+ u32 ret = 0;
+
+ if (CTRDGi_IsAgbCartridgeAtInit())
+ {
+ ret = cip->gameCode;
+ }
+
+ return ret;
+}
+
+ARM_FUNC u16 CTRDG_GetAgbMakerCode(void)
+{
+ u16 ret = 0;
+
+ if (CTRDG_IsExisting())
+ {
+ ret = CTRDGi_GetAgbMakerCodeAtInit();
+ }
+
+ return ret;
+}
+
+ARM_FUNC u16 CTRDGi_GetAgbMakerCodeAtInit(void)
+{
+ CTRDGModuleInfo *cip = CTRDGi_GetModuleInfoAddr();
+ u16 ret = 0;
+
+ if (CTRDGi_IsAgbCartridgeAtInit())
+ {
+ ret = cip->makerCode;
+ }
+
+ return ret;
+}
+
+ARM_FUNC BOOL CTRDG_IsPulledOut(void)
+{
+ CTRDGModuleInfo *cip = CTRDGi_GetModuleInfoAddr();
+
+ if (cip->moduleID.raw == 0xffff)
+ {
+ return FALSE;
+ }
+
+ if (!cip->detectPullOut)
+ {
+ (void)CTRDG_IsExisting();
+ }
+
+ return cip->detectPullOut;
+}
+
+ARM_FUNC BOOL CTRDG_IsExisting(void)
+{
+ BOOL ret = TRUE;
+ CTRDGLockByProc lockInfo;
+
+ CTRDGHeader *chp = CTRDGi_GetHeaderAddr();
+ CTRDGModuleInfo *cip = CTRDGi_GetModuleInfoAddr();
+
+ if (cip->moduleID.raw == 0xffff)
+ {
+ return FALSE;
+ }
+
+ if (cip->detectPullOut == TRUE)
+ {
+ return FALSE;
+ }
+
+ CTRDGi_LockByProcessor(CTRDGi_Work.lockID, &lockInfo);
+
+ CTRDGRomCycle rc;
+
+ CTRDGi_ChangeLatestAccessCycle(&rc);
+ u8 isRomCode = chp->isRomCode;
+
+ if ((isRomCode == CTRDG_IS_ROM_CODE && cip->moduleID.raw != chp->moduleID)
+ || (isRomCode != CTRDG_IS_ROM_CODE && cip->moduleID.raw != *CTRDGi_GetModuleIDImageAddr())
+ || ((cip->gameCode != chp->gameCode) && cip->isAgbCartridge))
+ {
+ cip->detectPullOut = TRUE;
+ ret = FALSE;
+ }
+
+ CTRDGi_RestoreAccessCycle(&rc);
+
+ CTRDGi_UnlockByProcessor(CTRDGi_Work.lockID, &lockInfo);
+
+ return ret;
+}
+
+ARM_FUNC void CTRDGi_ChangeLatestAccessCycle(CTRDGRomCycle *r)
+{
+ r->c1 = MI_GetCartridgeRomCycle1st();
+ r->c2 = MI_GetCartridgeRomCycle2nd();
+
+ MI_SetCartridgeRomCycle1st(MI_CTRDG_ROMCYCLE1_18);
+ MI_SetCartridgeRomCycle2nd(MI_CTRDG_ROMCYCLE2_6);
+}
+
+ARM_FUNC void CTRDGi_RestoreAccessCycle(CTRDGRomCycle *r)
+{
+ MI_SetCartridgeRomCycle1st(r->c1);
+ MI_SetCartridgeRomCycle2nd(r->c2);
+}
+
+ARM_FUNC void CTRDGi_LockByProcessor(u16 lockID, CTRDGLockByProc *info)
+{
+ while (TRUE)
+ {
+ info->irq = OS_DisableInterrupts();
+ if (((info->locked = OS_ReadOwnerOfLockCartridge() & CTRDG_LOCKED_BY_MYPROC_FLAG) != 0)
+ || (OS_TryLockCartridge(lockID) == OS_LOCK_SUCCESS))
+ {
+ break;
+ }
+ (void)OS_RestoreInterrupts(info->irq);
+
+ SVC_WaitByLoop(1);
+ }
+}
+
+ARM_FUNC void CTRDGi_UnlockByProcessor(u16 lockID, CTRDGLockByProc *info)
+{
+ if (!info->locked)
+ {
+ (void)OS_UnLockCartridge(lockID);
+ }
+
+ (void)OS_RestoreInterrupts(info->irq);
+}
+
+ARM_FUNC void CTRDGi_SendtoPxi(u32 data)
+{
+ while (PXI_SendWordByFifo(PXI_FIFO_TAG_CTRDG, data, FALSE) != PXI_FIFO_SUCCESS)
+ {
+ SVC_WaitByLoop(1);
+ }
+}
+
+ARM_FUNC BOOL CTRDG_CpuCopy8(const void *src, void *dest, u32 size)
+{
+ if (HW_CTRDG_ROM <= (u32)dest && (u32)dest < HW_CTRDG_RAM_END)
+ {
+ return CTRDGi_CopyCommon(0, (const void *)dest, (void *)src, size, CTRDGi_FORWARD_CPU8);
+ }
+ else
+ {
+ return CTRDGi_CopyCommon(0, src, dest, size, CTRDGi_FORWARD_CPU8);
+ }
+}
+
+ARM_FUNC BOOL CTRDG_CpuCopy16(const void *src, void *dest, u32 size)
+{
+ return CTRDGi_CopyCommon(0, src, dest, size, CTRDGi_FORWARD_CPU16);
+}
+
+ARM_FUNC BOOL CTRDG_CpuCopy32(const void *src, void *dest, u32 size)
+{
+ return CTRDGi_CopyCommon(0, src, dest, size, CTRDGi_FORWARD_CPU32);
+}
+
+ARM_FUNC BOOL CTRDGi_CopyCommon(u32 dmaNo, const void *src, void *dest, u32 size, u32 forwardType)
+{
+ if (!CTRDG_IsExisting())
+ {
+ return FALSE;
+ }
+
+ CTRDG_CheckEnabled();
+
+ (void)OS_LockCartridge(CTRDGi_Work.lockID);
+
+ if ((forwardType & CTRDGi_FORWARD_TYPE_MASK) == CTRDGi_FORWARD_TYPE_DMA)
+ {
+ MI_StopDma(dmaNo);
+ DC_FlushRange(dest, size);
+ }
+
+ switch (forwardType)
+ {
+ case CTRDGi_FORWARD_DMA16:
+ MI_DmaCopy16(dmaNo, src, dest, size);
+ break;
+ case CTRDGi_FORWARD_DMA32:
+ MI_DmaCopy32(dmaNo, src, dest, size);
+ break;
+ case CTRDGi_FORWARD_CPU16:
+ MI_CpuCopy16(src, dest, size);
+ break;
+ case CTRDGi_FORWARD_CPU32:
+ MI_CpuCopy32(src, dest, size);
+ break;
+
+ case CTRDGi_FORWARD_CPU8:
+ u8 *dest8 = (u8 *)dest;
+ u8 *src8 = (u8 *)src;
+ for (s32 n = 0; n < size; n++)
+ {
+ *dest8++ = *src8++;
+ }
+ break;
+ }
+
+ (void)OS_UnLockCartridge(CTRDGi_Work.lockID);
+
+ if (!CTRDG_IsExisting())
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+ARM_FUNC BOOL CTRDG_Read32(const u32 *address, u32 *rdata)
+{
+ return CTRDGi_AccessCommon((void *)address, 0, rdata, CTRDGi_ACCESS_READ32);
+}
+
+ARM_FUNC BOOL CTRDGi_AccessCommon(void *address, u32 data, void *rdata, u32 accessType)
+{
+ if (!CTRDG_IsExisting())
+ {
+ return FALSE;
+ }
+
+ CTRDG_CheckEnabled();
+
+ (void)OS_LockCartridge(CTRDGi_Work.lockID);
+
+ switch (accessType)
+ {
+ case CTRDGi_ACCESS_READ8:
+ if (rdata)
+ {
+ *(u8 *)rdata = *(u8 *)address;
+ }
+ break;
+ case CTRDGi_ACCESS_READ16:
+ if (rdata)
+ {
+ *(u16 *)rdata = *(u16 *)address;
+ }
+ break;
+ case CTRDGi_ACCESS_READ32:
+ if (rdata)
+ {
+ *(u32 *)rdata = *(u32 *)address;
+ }
+ break;
+ case CTRDGi_ACCESS_WRITE8:
+ *(u8 *)address = (u8)data;
+ break;
+ case CTRDGi_ACCESS_WRITE16:
+ *(u16 *)address = (u16)data;
+ break;
+ case CTRDGi_ACCESS_WRITE32:
+ *(u32 *)address = (u32)data;
+ break;
+ }
+
+ (void)OS_UnLockCartridge(CTRDGi_Work.lockID);
+
+ if (!CTRDG_IsExisting())
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+ARM_FUNC BOOL CTRDG_IsEnabled(void)
+{
+ return CTRDGi_EnableFlag;
+}
+
+ARM_FUNC void CTRDG_Enable(BOOL enable)
+{
+ OSIntrMode bak_cpsr = OS_DisableInterrupts();
+ CTRDGi_EnableFlag = enable;
+ if (!CTRDG_IsOptionCartridge())
+ {
+ u32 acc = (u32)(enable ? OS_PR3_ACCESS_RW : OS_PR3_ACCESS_RO);
+ (void)OS_SetDPermissionsForProtectionRegion(OS_PR3_ACCESS_MASK, acc);
+ }
+ (void)OS_RestoreInterrupts(bak_cpsr);
+}
+
+ARM_FUNC void CTRDG_CheckEnabled(void)
+{
+ if (!CTRDG_IsOptionCartridge() && !CTRDG_IsEnabled())
+ {
+ OS_Terminate();
+ }
+}