mirror of
https://github.com/zeldaret/oot
synced 2026-09-03 02:03:47 -04:00
Document CIC6105 (#2739)
* Document CIC6105 * Changes, AUDIOMGR_DEBUG_LEVEL -> AUDIOMGR_ACTIVITY_LEVEL
This commit is contained in:
@@ -29,7 +29,7 @@ void bootproc(void) {
|
||||
|
||||
osMemSize = osGetMemSize();
|
||||
#if PLATFORM_N64
|
||||
func_80001720();
|
||||
CIC6105_SaveBootMagicValues();
|
||||
#endif
|
||||
bootclear();
|
||||
osInitialize();
|
||||
|
||||
+66
-34
@@ -1,5 +1,19 @@
|
||||
/**
|
||||
* @file cic6105.c
|
||||
*
|
||||
* This file implements routines relating to the CIC X105 anti-piracy measures present in N64 releases.
|
||||
*
|
||||
* The "authentication" chain begins in IPL3, which deposits specific expected values into RAM and runs an RSP task in
|
||||
* parallel with loading the boot segment into RAM. This RSP task leaves data in the RSP's registers which rspboot and
|
||||
* the CIC6105 RSP task later read according to routines in this file. Their security model relied on CICs being
|
||||
* uncloneable with scarcely many donor CIC options from other games available at the time, in which case IPL3 would be
|
||||
* unmodifiable. The rest of the chain is designed with a "security through obscurity" mindset, storing later antipiracy
|
||||
* checks intermixed with other game code or RSP code that was expected to be non-trivial to analyze in a timely
|
||||
* fashion. Notably this effort did little to curb emulation, almost wholly due to early emulators being insufficiently
|
||||
* accurate to run RSP code or even IPL3 at a low level, sidestepping much of the early setup in favor of providing a
|
||||
* known-good post-boot state to begin emulation from.
|
||||
*/
|
||||
#pragma increment_block_number "ntsc-1.0:132 ntsc-1.1:132 ntsc-1.2:132 pal-1.0:132 pal-1.1:132"
|
||||
|
||||
#include "audiomgr.h"
|
||||
#include "build.h"
|
||||
#include "cic6105.h"
|
||||
@@ -7,35 +21,47 @@
|
||||
#include "regs.h"
|
||||
#include "sched.h"
|
||||
|
||||
s32 func_80001714(void);
|
||||
s32 CIC6105_Stub(void);
|
||||
|
||||
OSTask D_800067C0_unknown = {
|
||||
4, 0, rspbootTextStart, 0x3E8, cic6105TextStart, 0x20, (u64*)gBuildCreator, 8, NULL, 0, NULL, 0, NULL, 0, NULL, 0,
|
||||
OSTask sCIC6105Task = {
|
||||
// clang-format off
|
||||
4,
|
||||
0,
|
||||
rspbootTextStart, 0x3E8,
|
||||
cic6105TextStart, 0x20,
|
||||
(u64*)gBuildCreator, 8,
|
||||
NULL, 0,
|
||||
NULL, NULL,
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
u32 B_80008EE0;
|
||||
u32 B_80008EE4;
|
||||
u32 gCICBootMagic0;
|
||||
u32 gCICBootMagic1;
|
||||
FaultClient sCIC6105FaultClient;
|
||||
u32 B_80008EF8;
|
||||
u32 B_80008EFC;
|
||||
u32 sCICTaskResult0;
|
||||
u32 sCICTaskResult1;
|
||||
|
||||
void func_800014D0(void) {
|
||||
R_AUDIOMGR_DEBUG_LEVEL = AUDIOMGR_DEBUG_LEVEL_NO_RSP;
|
||||
void CIC6105_DisableAudio(void) {
|
||||
R_AUDIOMGR_ACTIVITY_LEVEL = AUDIOMGR_ACTIVITY_LEVEL_NO_RSP;
|
||||
}
|
||||
|
||||
void func_800014E8(void) {
|
||||
R_AUDIOMGR_DEBUG_LEVEL = AUDIOMGR_DEBUG_LEVEL_NONE;
|
||||
void CIC6105_EnableAudio(void) {
|
||||
R_AUDIOMGR_ACTIVITY_LEVEL = AUDIOMGR_ACTIVITY_LEVEL_ALL;
|
||||
}
|
||||
|
||||
void CIC6105_FaultClient(void) {
|
||||
s32 spStatus;
|
||||
u32 spStatus = IO_READ(SP_STATUS_REG);
|
||||
|
||||
spStatus = IO_READ(SP_STATUS_REG);
|
||||
Fault_SetCursor(48, 200);
|
||||
// Signal 7 is set by rspboot when it is first executed, corresponding to
|
||||
// whether rspboot's antipiracy checks passed. Signal 7 is expected to
|
||||
// stay set for the entire duration of the game running.
|
||||
if (spStatus & SP_STATUS_SIG7) {
|
||||
Fault_Printf("OCARINA %08x %08x", B_80008EF8, B_80008EFC);
|
||||
Fault_Printf("OCARINA %08x %08x", sCICTaskResult0, sCICTaskResult1);
|
||||
} else {
|
||||
Fault_Printf("LEGEND %08x %08x", B_80008EF8, B_80008EFC);
|
||||
Fault_Printf("LEGEND %08x %08x", sCICTaskResult0, sCICTaskResult1);
|
||||
}
|
||||
Fault_SetCursor(40, 184);
|
||||
Fault_Printf("ROM_F");
|
||||
@@ -47,7 +73,7 @@ void CIC6105_FaultClient(void) {
|
||||
#else
|
||||
Fault_SetCursor(96, 32);
|
||||
#endif
|
||||
Fault_Printf("I LOVE YOU %08x", func_80001714());
|
||||
Fault_Printf("I LOVE YOU %08x", CIC6105_Stub());
|
||||
}
|
||||
|
||||
void CIC6105_AddFaultClient(void) {
|
||||
@@ -58,31 +84,37 @@ void CIC6105_RemoveFaultClient(void) {
|
||||
Fault_RemoveClient(&sCIC6105FaultClient);
|
||||
}
|
||||
|
||||
void func_80001640(void) {
|
||||
OSScTask sp38;
|
||||
void CIC6105_RunBootTask(void) {
|
||||
OSScTask scTask;
|
||||
OSMesgQueue queue;
|
||||
OSMesg msg;
|
||||
|
||||
// Prepare the CIC6105 task
|
||||
osCreateMesgQueue(&queue, &msg, 1);
|
||||
sp38.next = NULL;
|
||||
sp38.flags = OS_SC_NEEDS_RSP;
|
||||
sp38.msgQueue = &queue;
|
||||
sp38.msg = (OSMesg)0;
|
||||
sp38.framebuffer = 0;
|
||||
sp38.list = D_800067C0_unknown;
|
||||
osSendMesg(&gScheduler.cmdQueue, &sp38, OS_MESG_BLOCK);
|
||||
scTask.next = NULL;
|
||||
scTask.flags = OS_SC_NEEDS_RSP;
|
||||
scTask.msgQueue = &queue;
|
||||
scTask.msg = (OSMesg)0;
|
||||
scTask.framebuffer = NULL;
|
||||
scTask.list = sCIC6105Task;
|
||||
// Send it to the scheduler for execution
|
||||
osSendMesg(&gScheduler.cmdQueue, &scTask, OS_MESG_BLOCK);
|
||||
Sched_Notify(&gScheduler);
|
||||
osRecvMesg(&queue, NULL, 1);
|
||||
B_80008EF8 = IO_READ(SP_DMEM_START + 0xFF4);
|
||||
B_80008EFC = IO_READ(SP_DMEM_START + 0xFFC);
|
||||
func_80001714();
|
||||
// Blocking wait until completion
|
||||
osRecvMesg(&queue, NULL, OS_MESG_BLOCK);
|
||||
// Retrieve results from RSP DMEM, it is assumed no other RSP task is running
|
||||
sCICTaskResult0 = IO_READ(SP_DMEM_START + 0xFF4);
|
||||
sCICTaskResult1 = IO_READ(SP_DMEM_START + 0xFFC);
|
||||
CIC6105_Stub();
|
||||
}
|
||||
|
||||
s32 func_80001714(void) {
|
||||
s32 CIC6105_Stub(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void func_80001720(void) {
|
||||
B_80008EE0 = IO_READ(0x002FB1F4);
|
||||
B_80008EE4 = IO_READ(0x002FE1C0);
|
||||
void CIC6105_SaveBootMagicValues(void) {
|
||||
// IPL3 writes two magic values into RDRAM during the boot process into fixed locations.
|
||||
// These must be retrieved early before memory is claimed by game memory management systems.
|
||||
gCICBootMagic0 = IO_READ(0x002FB1F4);
|
||||
gCICBootMagic1 = IO_READ(0x002FE1C0);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ void AudioMgr_NotifyTaskDone(AudioMgr* audioMgr) {
|
||||
void AudioMgr_HandleRetrace(AudioMgr* audioMgr) {
|
||||
AudioTask* rspTask;
|
||||
|
||||
if (R_AUDIOMGR_DEBUG_LEVEL > AUDIOMGR_DEBUG_LEVEL_NONE) {
|
||||
if (R_AUDIOMGR_ACTIVITY_LEVEL > AUDIOMGR_ACTIVITY_LEVEL_ALL) {
|
||||
// Inhibit audio rsp task processing
|
||||
audioMgr->rspTask = NULL;
|
||||
}
|
||||
@@ -53,7 +53,7 @@ void AudioMgr_HandleRetrace(AudioMgr* audioMgr) {
|
||||
|
||||
gAudioThreadUpdateTimeStart = osGetTime();
|
||||
|
||||
if (R_AUDIOMGR_DEBUG_LEVEL >= AUDIOMGR_DEBUG_LEVEL_NO_UPDATE) {
|
||||
if (R_AUDIOMGR_ACTIVITY_LEVEL >= AUDIOMGR_ACTIVITY_LEVEL_NO_UPDATE) {
|
||||
// Skip update, no rsp task produced
|
||||
rspTask = NULL;
|
||||
} else {
|
||||
@@ -160,7 +160,7 @@ void AudioMgr_Init(AudioMgr* audioMgr, void* stack, OSPri pri, OSId id, Schedule
|
||||
audioMgr->rspTask = NULL;
|
||||
|
||||
#if PLATFORM_N64
|
||||
R_AUDIOMGR_DEBUG_LEVEL = AUDIOMGR_DEBUG_LEVEL_NO_RSP;
|
||||
R_AUDIOMGR_ACTIVITY_LEVEL = AUDIOMGR_ACTIVITY_LEVEL_NO_RSP;
|
||||
#endif
|
||||
|
||||
osCreateMesgQueue(&audioMgr->taskDoneQueue, &audioMgr->taskDoneMsg, 1);
|
||||
|
||||
+1
-1
@@ -159,7 +159,7 @@ void Main(void* arg) {
|
||||
|
||||
#if PLATFORM_N64
|
||||
CIC6105_AddFaultClient();
|
||||
func_80001640();
|
||||
CIC6105_RunBootTask();
|
||||
#endif
|
||||
|
||||
IrqMgr_AddClient(&gIrqMgr, &irqClient, &irqMgrMsgQueue);
|
||||
|
||||
@@ -869,7 +869,7 @@ void Fishing_Init(Actor* thisx, PlayState* play2) {
|
||||
#if PLATFORM_N64
|
||||
// Anti-piracy check, if the check fails the line can't be reeled in if
|
||||
// a fish is caught and the fish will always let go after 50 frames.
|
||||
sReelLock = !(B_80008EE0 == 0xAD090010);
|
||||
sReelLock = !CIC_BOOT_MAGIC0_IS_CORRECT();
|
||||
#else
|
||||
sReelLock = 0;
|
||||
#endif
|
||||
|
||||
@@ -212,7 +212,7 @@ void ConsoleLogo_Destroy(GameState* thisx) {
|
||||
Sram_InitSram(&this->state, &this->sramCtx);
|
||||
|
||||
#if PLATFORM_N64
|
||||
func_800014E8();
|
||||
CIC6105_EnableAudio();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user