1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2025-08-06 06:10:21 +00:00

First proper commit.

This commit is contained in:
Jack Walker 2020-03-17 00:31:30 -04:00
parent be78236d36
commit 087f561f77
14086 changed files with 1200489 additions and 1 deletions

9
src/boot/assert.c Normal file
View file

@ -0,0 +1,9 @@
#include <z64.h>
void __assert(const char* exp, const char* file, s32 line)
{
char msg[256];
osSyncPrintf("Assertion failed: %s, file %s, line %d, thread %d\n", exp, file, line, osGetThreadId(NULL));
sprintf(msg, "ASSERT: %s:%d(%d)", file, line, osGetThreadId(NULL));
Fault_AddHungupAndCrashImpl(msg, exp);
}

32
src/boot/boot_main.c Normal file
View file

@ -0,0 +1,32 @@
#include <ultra64.h>
#include <global.h>
StackEntry sBootThreadInfo;
OSThread sIdleThread;
u8 sIdleThreadStack[0x400];
StackEntry sIdleThreadInfo;
u8 sBootThreadStack[0x400];
void cleararena(void)
{
bzero(_dmadataSegmentStart, (u8*)osMemSize - OS_K0_TO_PHYSICAL(_dmadataSegmentStart));
}
void bootproc(void)
{
StackCheck_Init(&sBootThreadInfo, sBootThreadStack, sBootThreadStack+sizeof(sBootThreadStack), 0, -1, "boot");
osMemSize = osGetMemSize();
cleararena();
__osInitialize_common();
__osInitialize_autodetect();
gCartHandle = osCartRomInit();
osDriveRomInit();
isPrintfInit();
Locale_Init();
StackCheck_Init(&sIdleThreadInfo, sIdleThreadStack, sIdleThreadStack+sizeof(sIdleThreadStack), 0, 256, "idle");
osCreateThread(&sIdleThread, 1, Idle_ThreadEntry, 0, sIdleThreadStack+sizeof(sIdleThreadStack), 10);
osStartThread(&sIdleThread);
}

3
src/boot/build.c Normal file
View file

@ -0,0 +1,3 @@
const char gBuildTeam[] = "zelda@srd022j";
const char gBuildDate[] = "03-02-21 00:16:31";
const char gBuildMakeOption[] = "";

92
src/boot/idle.c Normal file
View file

@ -0,0 +1,92 @@
#include <ultra64.h>
#include <global.h>
#include <vt.h>
OSThread sMainThread;
u8 sMainStack[0x900];
StackEntry sMainStackInfo;
OSMesg sPiMgrCmdBuff[50];
OSMesgQueue gPiMgrCmdQ;
OSViMode gViConfigMode;
u8 D_80013960;
u8 D_80009430 = 1;
u8 volatile gViConfigUseDefault = 1;
u8 gViConfigAdditionalScanLines = 0;
u32 gViConfigFeatures = OS_VI_DITHER_FILTER_ON | OS_VI_GAMMA_OFF;
f32 gViConfigXScale = 1.0;
f32 gViConfigYScale = 1.0;
void Main_ThreadEntry(void* arg0)
{
OSTime var1;
osSyncPrintf("mainx 実行開始\n");
DmaMgr_Start();
osSyncPrintf("codeセグメントロード中...");
var1 = osGetTime();
DmaMgr_SendRequest1((u32)_dmadataSegmentEnd, (u32)_codeSegmentRomStart, _codeSegmentRomEnd - _codeSegmentRomStart, "../idle.c", 238);
var1 -= osGetTime();
osSyncPrintf("\rcodeセグメントロード中...完了\n");
osSyncPrintf("転送時間 %6.3f\n");
bzero(_codeSegmentBssStart, _codeSegmentBssEnd - _codeSegmentBssStart);
osSyncPrintf("codeセグメントBSSクリア完了\n");
Main(arg0);
osSyncPrintf("mainx 実行終了\n");
}
void Idle_ThreadEntry(void* a0)
{
osSyncPrintf("アイドルスレッド(idleproc)実行開始\n");
osSyncPrintf("作製者 : %s\n", gBuildTeam);
osSyncPrintf("作成日時 : %s\n", gBuildDate);
osSyncPrintf("MAKEOPTION: %s\n", gBuildMakeOption);
osSyncPrintf(VT_FGCOL(GREEN));
osSyncPrintf("RAMサイズは %d キロバイトです(osMemSize/osGetMemSize)\n", (s32)osMemSize / 1024);
osSyncPrintf("_bootSegmentEnd(%08x) 以降のRAM領域はクリアされました(boot)\n", _bootSegmentEnd);
osSyncPrintf("Zバッファのサイズは %d キロバイトです\n", 0x96);
osSyncPrintf("ダイナミックバッファのサイズは %d キロバイトです\n", 0x92);
osSyncPrintf("FIFOバッファのサイズは %d キロバイトです\n", 0x60);
osSyncPrintf("YIELDバッファのサイズは %d キロバイトです\n", 3);
osSyncPrintf("オーディオヒープのサイズは %d キロバイトです\n", ((s32)gSystemHeap - (s32)gAudioHeap) / 1024);
osSyncPrintf(VT_RST);
osCreateViManager(0xFE);
gViConfigFeatures = 0x42;
gViConfigXScale = 1.0f;
gViConfigYScale = 1.0f;
switch (osTvType)
{
case 1:
D_80013960 = 2;
gViConfigMode = osViModeNtscLan1;
break;
case 2:
D_80013960 = 0x1E;
gViConfigMode = osViModeMpalLan1;
break;
case 0:
D_80013960 = 0x2C;
gViConfigMode = osViModeFpalLan1;
gViConfigYScale = 0.833f;
break;
}
D_80009430 = 1;
osViSetMode(&gViConfigMode);
ViConfig_UpdateVi(1);
osViBlack(1);
osViSwapBuffer(0x803da80);
osCreatePiManager(0x96, &gPiMgrCmdQ, sPiMgrCmdBuff, 0x32);
StackCheck_Init(&sMainStackInfo, sMainStack, sMainStack+sizeof(sMainStack), 0, 0x400, "main");
osCreateThread(&sMainThread, 3, Main_ThreadEntry, a0, sMainStack+sizeof(sMainStack), 10);
osStartThread(&sMainThread);
osSetThreadPri(NULL, 0);
while(1)
;
}

93
src/boot/is_debug.c Normal file
View file

@ -0,0 +1,93 @@
#include <z64.h>
#include <global.h>
OSPiHandle* sISVHandle; //official name : is_Handle
#define gISVDbgPrnAdrs ((ISVDbg*)0xb3ff0000)
#define ASCII_TO_U32(a, b, c, d) ((u32)((a << 24) | (b << 16) | (c << 8) | (d << 0)))
void isPrintfInit()
{
sISVHandle = osCartRomInit();
osEPiWriteIo(sISVHandle, (u32)&gISVDbgPrnAdrs->put, 0);
osEPiWriteIo(sISVHandle, (u32)&gISVDbgPrnAdrs->get, 0);
osEPiWriteIo(sISVHandle, (u32)&gISVDbgPrnAdrs->magic, ASCII_TO_U32('I','S','6','4'));
}
void osSyncPrintfUnused(const char* fmt, ...)
{
va_list args;
va_start(args, fmt);
_Printf(&is_proutSyncPrintf, NULL, fmt, args);
}
void osSyncPrintf(const char* fmt, ...)
{
va_list args;
va_start(args, fmt);
_Printf(&is_proutSyncPrintf, NULL, fmt, args);
}
//assumption
void rmonPrintf(const char* fmt, ...)
{
va_list args;
va_start(args, fmt);
_Printf(&is_proutSyncPrintf, NULL, fmt, args);
}
u32 is_proutSyncPrintf(void* arg0, const char *str, s32 count)
{
u32 data;
s32 pos;
s32 start;
s32 end;
osEPiReadIo(sISVHandle, (u32)&gISVDbgPrnAdrs->magic, &data);
if (data != ASCII_TO_U32('I','S','6','4'))
return 1;
osEPiReadIo(sISVHandle, (u32)&gISVDbgPrnAdrs->get, &data);
pos = data;
osEPiReadIo(sISVHandle, (u32)&gISVDbgPrnAdrs->put, &data);
start = data;
end = start + count;
if (end >= 0xffe0)
{
end -= 0xffe0;
if (pos < end || start < pos)
return 1;
}
else
{
if (start < pos && pos < end)
return 1;
}
while (count)
{
u32 addr = (u32)&gISVDbgPrnAdrs->data + (start & 0xffffffc);
s32 shift = ((3 - (start & 3)) * 8);
if (*str)
{
osEPiReadIo(sISVHandle, addr, &data);
osEPiWriteIo(sISVHandle, addr, (*str << shift) | (data & ~(0xff << shift)));
start++;
if (start >= 0xffe0)
start -= 0xffe0;
}
count--;
str++;
}
osEPiWriteIo(sISVHandle, (u32)&gISVDbgPrnAdrs->put, start);
return 1;
}
void func_80002384(const char* exp, const char* file, u32 line)
{
osSyncPrintf("File:%s Line:%d %s \n", file, line, exp);
while (true)
;
}

115
src/boot/logutils.c Normal file
View file

@ -0,0 +1,115 @@
#include <z64.h>
#include <global.h>
#include <vt.h>
float LogUtils_CheckFloatRange(const char* exp, s32 arg1, const char* var1Name, float var1, const char* var2Name, float var2, const char* var3Name, float var3)
{
if (var1 < var2 || var3 < var1)
osSyncPrintf("%s %d: range error %s(%f) < %s(%f) < %s(%f)\n", exp, arg1, var2Name, var2, var1Name, var1, var3Name, var3);
return var1;
}
s32 LogUtils_CheckIntRange(const char* exp, s32 arg1, const char* var1Name, s32 var1, const char* var2Name, s32 var2, const char* var3Name, s32 var3)
{
if (var1 < var2 || var3 < var1)
osSyncPrintf("%s %d: range error %s(%d) < %s(%d) < %s(%d)\n", exp, arg1, var2Name, var2, var1Name, var1, var3Name, var3);
return var1;
}
void LogUtils_LogHexDump(void* ptr, s32 size0)
{
u8* addr = (u8*)ptr;
s32 size = (s32)size0;
s32 rest;
s32 i;
u32 off;
osSyncPrintf("dump(%08x, %u)\n", addr, size);
osSyncPrintf("address off +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f 0123456789abcdef\n");
off = 0;
while (size > 0)
{
osSyncPrintf("%08x %04x", addr, off);
rest = (size < 0x10) ? size : 0x10;
i = 0;
while (true)
{
if(i < rest)
osSyncPrintf(" %02x", *((u8*)addr + i));
else
osSyncPrintf(" ");
i++;
if (i > 0xf)
break;
}
osSyncPrintf(" ");
i = 0;
while (true)
{
if(i < rest)
{
u8 a = *(addr+i);
osSyncPrintf("%c", (a >= 0x20 && a < 0x7f) ? a : '.');
}
else
osSyncPrintf(" ");
i++;
if (i > 0xf)
break;
}
osSyncPrintf("\n");
size -= rest;
addr += rest;
off += rest;
}
}
void LogUtils_LogPointer(s32 value, u32 max, void* ptr, const char *name, const char *file, s32 line)
{
osSyncPrintf(VT_COL(RED, WHITE) "%s %d %s[%d] max=%u ptr=%08x\n" VT_RST, file, line, name, value, max, ptr);
}
void LogUtils_CheckBoundary(const char* name, s32 value, s32 unk, const char* file, s32 line)
{
u32 mask = (unk - 1);
if (value & mask)
osSyncPrintf(VT_COL(RED, WHITE) "%s %d:%s(%08x) は バウンダリ(%d)違反です\n" VT_RST, file, line, name, value, unk);
}
void LogUtils_CheckNullPointer(const char* exp, void* ptr, const char* file, s32 line)
{
if (!ptr)
osSyncPrintf(VT_COL(RED, WHITE) "%s %d:%s は はヌルポインタです\n" VT_RST, file, line, exp);
}
//check valid pointer
void LogUtils_CheckValidPointer(const char* exp, void* ptr0, const char* file, s32 line)
{
u32 ptr = (u32)ptr0;
if (!ptr || ptr < 0x80000000U || (0x80000000U + osMemSize) <= ptr)
osSyncPrintf(VT_COL(RED, WHITE) "%s %d:ポインタ %s(%08x) が異常です\n" VT_RST, file, line, exp, ptr);
}
//there's probalby a macro like this : MACRO(exp) LogUtils_LogThreadId(__FILE__, __LINE__); osSyncPrintf(exp)
void LogUtils_LogThreadId(const char* name, s32 line)
{
osSyncPrintf("<%d %s %d>", osGetThreadId(NULL), name, line);
}
void LogUtils_HungupThread(const char* name, s32 line)
{
osSyncPrintf("*** HungUp in thread %d, [%s:%d] ***\n", osGetThreadId(NULL), name, line);
Fault_AddHungupAndCrash(name, line);
}
void LogUtils_ResetHungup()
{
osSyncPrintf("*** Reset ***\n");
Fault_AddHungupAndCrash("Reset", 0);
}

141
src/boot/stackcheck.c Normal file
View file

@ -0,0 +1,141 @@
#include <z64.h>
#include <global.h>
#include <vt.h>
StackEntry* sStackInfoListStart = NULL;
StackEntry* sStackInfoListEnd = NULL;
void StackCheck_Init(StackEntry* entry, void* stackTop, void* stackBottom, u32 initValue, s32 minSpace, const char* name)
{
StackEntry* iter;
u32* addr;
if (!entry)
sStackInfoListStart = NULL;
else
{
entry->head = (u32)stackTop;
entry->tail = (u32)stackBottom;
entry->initValue = initValue;
entry->minSpace = minSpace;
entry->name = name;
iter = sStackInfoListStart;
while (iter)
{
if (iter == entry)
{
osSyncPrintf(VT_COL(RED, WHITE) "stackcheck_init: %08x は既にリスト中にある\n" VT_RST, entry);
return;
}
iter = iter->next;
}
entry->prev = sStackInfoListEnd;
entry->next = NULL;
if (sStackInfoListEnd)
sStackInfoListEnd->next = entry;
sStackInfoListEnd = entry;
if (!sStackInfoListStart)
sStackInfoListStart = entry;
if (entry->minSpace != -1)
{
addr = (u32*)entry->head;
while ((u32)addr < entry->tail)
*addr++ = entry->initValue;
}
}
}
void StackCheck_Cleanup(StackEntry* entry)
{
bool inconsistency = false;
if (!entry->prev)
{
if (entry == sStackInfoListStart)
sStackInfoListStart = entry->next;
else
inconsistency = true;
}
else
entry->prev->next = entry->next;
if (!entry->next)
{
if (entry == sStackInfoListEnd)
sStackInfoListEnd = entry->prev;
else
inconsistency = true;
}
if (inconsistency)
osSyncPrintf(VT_COL(RED, WHITE) "stackcheck_cleanup: %08x リスト不整合です\n" VT_RST, entry);
}
StackStatus StackCheck_GetState(StackEntry* entry)
{
u32* last;
u32 used;
u32 free;
s32 ret;
for (last = (u32*)entry->head; (u32)last < entry->tail; last++)
{
if (entry->initValue != *last)
break;
}
used = entry->tail - (u32)last;
free = (u32)last - entry->head;
if (free == 0)
{
ret = STACK_STATUS_OVERFLOW;
osSyncPrintf(VT_FGCOL(RED));
}
else if (free < entry->minSpace && entry->minSpace != -1)
{
ret = STACK_STATUS_WARNING;
osSyncPrintf(VT_FGCOL(YELLOW));
}
else
{
osSyncPrintf(VT_FGCOL(GREEN));
ret = STACK_STATUS_OK;
}
osSyncPrintf("head=%08x tail=%08x last=%08x used=%08x free=%08x [%s]\n", entry->head, entry->tail, last, used, free, entry->name ? entry->name : "(null)");
osSyncPrintf(VT_RST);
if (ret != STACK_STATUS_OK)
LogUtils_LogHexDump(entry->head, entry->tail - entry->head);
return ret;
}
u32 StackCheck_CheckAll()
{
u32 ret = 0;
StackEntry* iter = sStackInfoListStart;
while(iter)
{
u32 state = StackCheck_GetState(iter);
if (state != STACK_STATUS_OK)
ret = 1;
iter = iter->next;
}
return ret;
}
u32 StackCheck_Check(StackEntry* entry)
{
if (!entry)
return StackCheck_CheckAll();
else
return StackCheck_GetState(entry);
}

48
src/boot/viconfig.c Normal file
View file

@ -0,0 +1,48 @@
#include <ultra64.h>
#include <global.h>
#include <vt.h>
//this should probably go elsewhere but right now viconfig.o is the only object between idle and z_std_dma
OSPiHandle* gCartHandle = 0;
void ViConfig_UpdateVi(u32 arg0)
{
if (arg0 != 0)
{
osSyncPrintf(VT_COL(YELLOW, BLACK) "osViSetYScale1(%f);\n" VT_RST, 1.0f);
if (osTvType == 0)
osViSetMode(&osViModePalLan1);
osViSetYScale(1.0f);
}
else
{
osViSetMode(&gViConfigMode);
if (gViConfigAdditionalScanLines != 0)
osViExtendVStart(gViConfigAdditionalScanLines);
if (gViConfigFeatures != 0)
osViSetSpecialFeatures(gViConfigFeatures);
if (gViConfigXScale != 1.0f)
osViSetXScale(gViConfigXScale);
if (gViConfigYScale != 1.0f)
{
osSyncPrintf(VT_COL(YELLOW, BLACK) "osViSetYScale3(%f);\n" VT_RST, gViConfigYScale);
osViSetYScale(gViConfigYScale);
}
}
gViConfigUseDefault = arg0;
}
void ViConfig_UpdateBlack()
{
if (gViConfigUseDefault != 0)
osViBlack(1);
else
osViBlack(0);
}

124
src/boot/yaz0.c Normal file
View file

@ -0,0 +1,124 @@
#include <z64.h>
#include <global.h>
u8 sYaz0DataBuffer[0x400];
u32 sYaz0CurDataEnd;
u32 sYaz0CurRomStart;
u32 sYaz0CurSize;
u32 sYaz0MaxPtr;
void* Yaz0_FirstDMA()
{
u32 pad0;
u32 pad1;
u32 dmaSize;
u32 curSize;
sYaz0MaxPtr = sYaz0CurDataEnd - 0x19;
curSize = sYaz0CurDataEnd - (u32)sYaz0DataBuffer;
dmaSize = (curSize > sYaz0CurSize)
? sYaz0CurSize
: curSize;
DmaMgr_DMARomToRam(sYaz0CurRomStart, sYaz0DataBuffer, dmaSize);
sYaz0CurRomStart += dmaSize;
sYaz0CurSize -= dmaSize;
return sYaz0DataBuffer;
}
void* Yaz0_NextDMA(void* curSrcPos)
{
u8* dst;
u32 restSize;
u32 dmaSize;
restSize = sYaz0CurDataEnd - (u32)curSrcPos;
dst = (restSize & 7)
? (sYaz0DataBuffer - (restSize & 7)) + 8
: sYaz0DataBuffer;
bcopy(curSrcPos, dst, restSize);
dmaSize = (sYaz0CurDataEnd - (u32)dst) - restSize;
if (sYaz0CurSize < dmaSize)
dmaSize = sYaz0CurSize;
if (dmaSize != 0)
{
DmaMgr_DMARomToRam(sYaz0CurRomStart, (u32)dst + restSize, dmaSize);
sYaz0CurRomStart += dmaSize;
sYaz0CurSize -= dmaSize;
if (!sYaz0CurSize)
sYaz0MaxPtr = (u32)dst + restSize + dmaSize;
}
return dst;
}
#ifdef NON_MATCHING
// has an extra check at the start of the small compressed loop
// along with an extra move instruction
// maybe some regalloc differences besides these issues
void Yaz0_DecompressImpl(Yaz0Header* hdr, u8* dst)
{
u32 bitIdx;
u8* src;
u8* dstEnd;
u32 chunkHeader;
u32 nibble;
u8* backPtr;
s32 chunkSize;
u32 curDecBit;
u32 off;
bitIdx = 0;
src = hdr->data;
dstEnd = dst + hdr->decSize;
do
{
if (bitIdx == 0)
{
if ((sYaz0MaxPtr < (u32)src) && (sYaz0CurSize != 0))
src = Yaz0_NextDMA(src);
chunkHeader = *src++;
bitIdx = 8;
}
curDecBit = chunkHeader & (1 << 7);
chunkHeader <<= 1;
if (curDecBit) // uncompressed
{
*dst++ = *src++;
}
else // compressed
{
nibble = *src >> 4;
backPtr = dst - (*(src + 1) | (*src & 0xF) << 8);
src += 2;
chunkSize = (nibble == 0) // N = chunkSize; B = back offset
? *src++ + 0x12 // 3 bytes 0B BB NN
: nibble + 2; // 2 bytes NB BB
for (off = chunkSize; off > 0; off--)
*dst++ = *(backPtr++ - 1);
}
bitIdx--;
} while (dst != dstEnd);
}
#else
#pragma GLOBAL_ASM("asm/non_matchings/boot/yaz0/Yaz0_DecompressImpl.s")
#endif
void Yaz0_Decompress(u32 romStart, void* dst, u32 size)
{
sYaz0CurRomStart = romStart;
sYaz0CurSize = size;
sYaz0CurDataEnd = sYaz0DataBuffer + sizeof(sYaz0DataBuffer);
Yaz0_DecompressImpl(Yaz0_FirstDMA(), dst);
}

74
src/boot/z_locale.c Normal file
View file

@ -0,0 +1,74 @@
#include <ultra64.h>
#include <global.h>
#include <vt.h>
#include <padmgr.h>
u32 gCurrentRegion = 0;
LocaleCartInfo sCartInfo;
//temporary
extern PadMgr gPadMgr;
void Locale_Init()
{
osEPiReadIo(gCartHandle, 0x38, &sCartInfo.mediaFormat);
osEPiReadIo(gCartHandle, 0x3C, &sCartInfo.regionInfo);
switch (sCartInfo.countryCode)
{
case 'J': // "NTSC-U (North America)"
gCurrentRegion = REGION_US;
break;
case 'E': // "NTSC-J (Japan)"
gCurrentRegion = REGION_JP;
break;
case 'P': // "PAL (Europe)"
gCurrentRegion = REGION_EU;
break;
default:
osSyncPrintf(VT_COL(RED, WHITE));
osSyncPrintf("z_locale_init: 日本用かアメリカ用か判別できません\n");
LogUtils_HungupThread("../z_locale.c", 0x76);
osSyncPrintf(VT_RST);
break;
}
osSyncPrintf("z_locale_init:日本用かアメリカ用か3コンで判断させる\n");
}
void Locale_ResetRegion()
{
gCurrentRegion = REGION_NULL;
}
u32 func_80001F48()
{
PadMgr* padMgr = (PadMgr*)(u32)&gPadMgr; //cast required to match
if (gCurrentRegion == REGION_NATIVE)
return 0;
if (padMgr->unk_2A8 & 4)
return 0;
return 1;
}
u32 func_80001F8C()
{
PadMgr* padMgr = (PadMgr*)(u32)&gPadMgr; //cast required to match
if (gCurrentRegion == REGION_NATIVE)
return 0;
if (padMgr->unk_2A8 & 4)
return 1;
return 0;
}
// This function appears to be unused?
u32 Locale_IsRegionNative()
{
return gCurrentRegion == REGION_NATIVE;
}

1987
src/boot/z_std_dma.c Normal file

File diff suppressed because it is too large Load diff