mirror of
https://github.com/zeldaret/oot
synced 2026-05-22 22:44:26 -04:00
Document CIC6105 (#2739)
* Document CIC6105 * Changes, AUDIOMGR_DEBUG_LEVEL -> AUDIOMGR_ACTIVITY_LEVEL
This commit is contained in:
+1
-1
@@ -12,7 +12,7 @@
|
||||
/* RSP code for cic6105.c, used only in N64 versions. */
|
||||
glabel cic6105TextStart
|
||||
.word 0xE80C2001 # sqv $v12[0], 0x10($zero)
|
||||
.word 0x34014000 # li $1, 0x4000
|
||||
.word 0x34014000 # li $1, SP_SET_SIG2
|
||||
.word 0x40812000 # mtc0 $1, SP_STATUS
|
||||
.word 0x0000000D # break
|
||||
.word 0x00000000 # nop
|
||||
|
||||
+5
-5
@@ -4,11 +4,11 @@
|
||||
#include "sched.h"
|
||||
#include "audio.h"
|
||||
|
||||
typedef enum AudioMgrDebugLevel {
|
||||
/* 0 */ AUDIOMGR_DEBUG_LEVEL_NONE,
|
||||
/* 1 */ AUDIOMGR_DEBUG_LEVEL_NO_RSP,
|
||||
/* 2 */ AUDIOMGR_DEBUG_LEVEL_NO_UPDATE
|
||||
} AudioMgrDebugLevel;
|
||||
typedef enum AudioMgrActivityLevel {
|
||||
/* 0 */ AUDIOMGR_ACTIVITY_LEVEL_ALL,
|
||||
/* 1 */ AUDIOMGR_ACTIVITY_LEVEL_NO_RSP,
|
||||
/* 2 */ AUDIOMGR_ACTIVITY_LEVEL_NO_UPDATE
|
||||
} AudioMgrActivityLevel;
|
||||
|
||||
typedef struct AudioMgr {
|
||||
/* 0x0000 */ IrqMgr* irqMgr;
|
||||
|
||||
+6
-4
@@ -3,12 +3,14 @@
|
||||
|
||||
#include "ultra64.h"
|
||||
|
||||
extern u32 B_80008EE0;
|
||||
extern u32 gCICBootMagic0;
|
||||
|
||||
void func_800014E8(void);
|
||||
#define CIC_BOOT_MAGIC0_IS_CORRECT() (gCICBootMagic0 == 0xAD090010)
|
||||
|
||||
void CIC6105_EnableAudio(void);
|
||||
void CIC6105_AddFaultClient(void);
|
||||
void CIC6105_RemoveFaultClient(void);
|
||||
void func_80001640(void);
|
||||
void func_80001720(void);
|
||||
void CIC6105_RunBootTask(void);
|
||||
void CIC6105_SaveBootMagicValues(void);
|
||||
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -54,7 +54,7 @@ struct PlayState;
|
||||
#define R_DECELERATE_RATE REG(43)
|
||||
#define R_RUN_SPEED_LIMIT REG(45)
|
||||
#define R_ENABLE_ARENA_DBG SREG(0)
|
||||
#define R_AUDIOMGR_DEBUG_LEVEL SREG(20)
|
||||
#define R_AUDIOMGR_ACTIVITY_LEVEL SREG(20)
|
||||
#define R_ROOM_IMAGE_NODRAW_FLAGS SREG(25)
|
||||
#define R_ROOM_BG2D_FORCE_SCALEBG SREG(26)
|
||||
#define R_UPDATE_RATE SREG(30)
|
||||
|
||||
@@ -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