summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/cic6105.text.s2
-rw-r--r--include/audiomgr.h10
-rw-r--r--include/cic6105.h10
-rw-r--r--include/regs.h2
-rw-r--r--src/boot/boot_main.c2
-rw-r--r--src/boot/cic6105.c100
-rw-r--r--src/code/audio_thread_manager.c6
-rw-r--r--src/code/main.c2
-rw-r--r--src/overlays/actors/ovl_Fishing/z_fishing.c2
-rw-r--r--src/overlays/gamestates/ovl_title/z_title.c2
10 files changed, 86 insertions, 52 deletions
diff --git a/data/cic6105.text.s b/data/cic6105.text.s
index 387beeded..5020669e2 100644
--- a/data/cic6105.text.s
+++ b/data/cic6105.text.s
@@ -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
diff --git a/include/audiomgr.h b/include/audiomgr.h
index 66a905026..10dee7fab 100644
--- a/include/audiomgr.h
+++ b/include/audiomgr.h
@@ -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;
diff --git a/include/cic6105.h b/include/cic6105.h
index c4983db8f..16d1c86e5 100644
--- a/include/cic6105.h
+++ b/include/cic6105.h
@@ -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
diff --git a/include/regs.h b/include/regs.h
index a59e059ab..8d67563d2 100644
--- a/include/regs.h
+++ b/include/regs.h
@@ -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)
diff --git a/src/boot/boot_main.c b/src/boot/boot_main.c
index 91b74cbe9..ba95a33bf 100644
--- a/src/boot/boot_main.c
+++ b/src/boot/boot_main.c
@@ -29,7 +29,7 @@ void bootproc(void) {
osMemSize = osGetMemSize();
#if PLATFORM_N64
- func_80001720();
+ CIC6105_SaveBootMagicValues();
#endif
bootclear();
osInitialize();
diff --git a/src/boot/cic6105.c b/src/boot/cic6105.c
index fadae3a18..8f8ba0d0e 100644
--- a/src/boot/cic6105.c
+++ b/src/boot/cic6105.c
@@ -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);
}
diff --git a/src/code/audio_thread_manager.c b/src/code/audio_thread_manager.c
index 01b0072d9..6a1ae175c 100644
--- a/src/code/audio_thread_manager.c
+++ b/src/code/audio_thread_manager.c
@@ -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);
diff --git a/src/code/main.c b/src/code/main.c
index e137cff75..f693a5c49 100644
--- a/src/code/main.c
+++ b/src/code/main.c
@@ -159,7 +159,7 @@ void Main(void* arg) {
#if PLATFORM_N64
CIC6105_AddFaultClient();
- func_80001640();
+ CIC6105_RunBootTask();
#endif
IrqMgr_AddClient(&gIrqMgr, &irqClient, &irqMgrMsgQueue);
diff --git a/src/overlays/actors/ovl_Fishing/z_fishing.c b/src/overlays/actors/ovl_Fishing/z_fishing.c
index 52e636c77..f1e41b80e 100644
--- a/src/overlays/actors/ovl_Fishing/z_fishing.c
+++ b/src/overlays/actors/ovl_Fishing/z_fishing.c
@@ -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
diff --git a/src/overlays/gamestates/ovl_title/z_title.c b/src/overlays/gamestates/ovl_title/z_title.c
index a17bd0f4d..c8b90787b 100644
--- a/src/overlays/gamestates/ovl_title/z_title.c
+++ b/src/overlays/gamestates/ovl_title/z_title.c
@@ -212,7 +212,7 @@ void ConsoleLogo_Destroy(GameState* thisx) {
Sram_InitSram(&this->state, &this->sramCtx);
#if PLATFORM_N64
- func_800014E8();
+ CIC6105_EnableAudio();
#endif
}