diff --git a/assets/xml/textures/item_name_static.xml b/assets/xml/textures/item_name_static.xml
index 00c497490f..adf66fcb9b 100644
--- a/assets/xml/textures/item_name_static.xml
+++ b/assets/xml/textures/item_name_static.xml
@@ -12,7 +12,7 @@
-
+
@@ -124,7 +124,7 @@
-
+
@@ -135,7 +135,7 @@
-
+
diff --git a/include/alignment.h b/include/alignment.h
index 7a3b94ea2c..e26a1d3f33 100644
--- a/include/alignment.h
+++ b/include/alignment.h
@@ -13,4 +13,16 @@
#define ALIGNED8
#endif
+#ifdef __sgi /* IDO compiler */
+#define ALIGNOF(x) __builtin_alignof(x)
+#elif (__STDC_VERSION__ >= 201112L) /* C11 */
+#define ALIGNOF(x) _Alignof(x)
+#else /* __GNUC__ */
+#define ALIGNOF(x) __alignof__(x)
+#endif
+
+#define ALIGN_MASK(n) (~((n) - 1))
+
+#define ALIGNOF_MASK(x) ALIGN_MASK(ALIGNOF(x))
+
#endif
diff --git a/include/functions.h b/include/functions.h
index f50a64631b..b866e4721f 100644
--- a/include/functions.h
+++ b/include/functions.h
@@ -78,7 +78,7 @@ void __osPiGetAccess(void);
void __osPiRelAccess(void);
s32 osSendMesg(OSMesgQueue* mq, OSMesg msg, s32 flag);
void osStopThread(OSThread* thread);
-void osViExtendVStart(u32 arg0);
+void osViExtendVStart(u32 value);
s32 osRecvMesg(OSMesgQueue* mq, OSMesg* msg, s32 flag);
void __osInitialize_common(void);
void __osInitialize_autodetect(void);
@@ -120,7 +120,7 @@ s32 osJamMesg(OSMesgQueue* mq, OSMesg msg, s32 flag);
void osSetThreadPri(OSThread* thread, OSPri pri);
OSPri osGetThreadPri(OSThread* thread);
s32 __osEPiRawReadIo(OSPiHandle* handle, u32 devAddr, u32* data);
-void osViSwapBuffer(void* vaddr);
+void osViSwapBuffer(void* frameBufPtr);
s32 __osEPiRawStartDma(OSPiHandle* handle, s32 direction, u32 cartAddr, void* dramAddr, size_t size);
u32 bcmp(void* __sl, void* __s2, u32 __n);
OSTime osGetTime(void);
@@ -1290,8 +1290,8 @@ s32 View_UpdateViewingMatrix(View* view);
s32 View_ApplyTo(View* view, s32 mask, Gfx** gfxp);
s32 View_ErrorCheckEyePosition(f32 eyeX, f32 eyeY, f32 eyeZ);
void ViMode_LogPrint(OSViMode* osViMode);
-void ViMode_Configure(ViMode* viMode, s32 mode, s32 type, s32 unk_70, s32 unk_74, s32 unk_78, s32 unk_7C, s32 width,
- s32 height, s32 unk_left, s32 unk_right, s32 unk_top, s32 unk_bottom);
+void ViMode_Configure(ViMode* viMode, s32 type, s32 tvType, s32 loRes, s32 antialiasOff, s32 modeN, s32 fb16Bit,
+ s32 width, s32 height, s32 leftAdjust, s32 rightAdjust, s32 upperAdjust, s32 lowerAdjust);
void ViMode_Save(ViMode* viMode);
void ViMode_Load(ViMode* viMode);
void ViMode_Init(ViMode* viMode);
@@ -1459,35 +1459,6 @@ void func_800C213C(PreRender* this, Gfx** gfxp);
void PreRender_RestoreFramebuffer(PreRender* this, Gfx** gfxp);
void PreRender_CopyImageRegion(PreRender* this, Gfx** gfxp);
void PreRender_ApplyFilters(PreRender* this);
-void THGA_Ct(TwoHeadGfxArena* thga, Gfx* start, u32 size);
-void THGA_Dt(TwoHeadGfxArena* thga);
-u32 THGA_IsCrash(TwoHeadGfxArena* thga);
-void THGA_Init(TwoHeadGfxArena* thga);
-s32 THGA_GetSize(TwoHeadGfxArena* thga);
-Gfx* THGA_GetHead(TwoHeadGfxArena* thga);
-void THGA_SetHead(TwoHeadGfxArena* thga, Gfx* start);
-Gfx* THGA_GetTail(TwoHeadGfxArena* thga);
-Gfx* THGA_AllocStartArray8(TwoHeadGfxArena* thga, u32 count);
-Gfx* THGA_AllocStart8(TwoHeadGfxArena* thga);
-Gfx* THGA_AllocStart8Wrapper(TwoHeadGfxArena* thga);
-Gfx* THGA_AllocEnd(TwoHeadGfxArena* thga, u32 size);
-Gfx* THGA_AllocEndArray64(TwoHeadGfxArena* thga, u32 count);
-Gfx* THGA_AllocEnd64(TwoHeadGfxArena* thga);
-Gfx* THGA_AllocEndArray16(TwoHeadGfxArena* thga, u32 count);
-Gfx* THGA_AllocEnd16(TwoHeadGfxArena* thga);
-void* THA_GetHead(TwoHeadArena* tha);
-void THA_SetHead(TwoHeadArena* tha, void* start);
-void* THA_GetTail(TwoHeadArena* tha);
-void* THA_AllocStart(TwoHeadArena* tha, u32 size);
-void* THA_AllocStart1(TwoHeadArena* tha);
-void* THA_AllocEnd(TwoHeadArena* tha, u32 size);
-void* THA_AllocEndAlign16(TwoHeadArena* tha, u32 size);
-void* THA_AllocEndAlign(TwoHeadArena* tha, u32 size, u32 mask);
-s32 THA_GetSize(TwoHeadArena* tha);
-u32 THA_IsCrash(TwoHeadArena* tha);
-void THA_Init(TwoHeadArena* tha);
-void THA_Ct(TwoHeadArena* tha, void* ptr, u32 size);
-void THA_Dt(TwoHeadArena* tha);
void AudioMgr_StopAllSfx(void);
void func_800C3C80(AudioMgr* audioMgr);
void AudioMgr_HandleRetrace(AudioMgr* audioMgr);
diff --git a/include/libc/math.h b/include/libc/math.h
index b41cb8e524..2858084eba 100644
--- a/include/libc/math.h
+++ b/include/libc/math.h
@@ -1,7 +1,7 @@
#ifndef MATH_H
#define MATH_H
-#include "ultra64/types.h"
+#include "ultra64/ultratypes.h"
#define M_PI 3.14159265358979323846f
#define M_SQRT2 1.41421356237309504880f
diff --git a/include/macros.h b/include/macros.h
index 37d326c529..7d000af07c 100644
--- a/include/macros.h
+++ b/include/macros.h
@@ -119,6 +119,7 @@
#define LOG_TIME(exp, value, file, line) LOG(exp, value, "%lld", file, line)
#define LOG_NUM(exp, value, file, line) LOG(exp, value, "%d", file, line)
#define LOG_HEX(exp, value, file, line) LOG(exp, value, "%x", file, line)
+#define LOG_HEX32(exp, value, file, line) LOG(exp, value, "%08x", file, line)
#define LOG_FLOAT(exp, value, file, line) LOG(exp, value, "%f", file, line)
#define SET_NEXT_GAMESTATE(curState, newInit, newStruct) \
diff --git a/include/regs.h b/include/regs.h
index e9f6af90e2..d5ca906c92 100644
--- a/include/regs.h
+++ b/include/regs.h
@@ -52,6 +52,13 @@
#define R_ROOM_BG2D_FORCE_SCALEBG SREG(26)
#define R_UPDATE_RATE SREG(30)
#define R_ENABLE_AUDIO_DBG SREG(36)
+#define R_VI_MODE_EDIT_STATE SREG(48)
+#define R_VI_MODE_EDIT_WIDTH SREG(49)
+#define R_VI_MODE_EDIT_HEIGHT SREG(50)
+#define R_VI_MODE_EDIT_ULY_ADJ SREG(51)
+#define R_VI_MODE_EDIT_LRY_ADJ SREG(52)
+#define R_VI_MODE_EDIT_ULX_ADJ SREG(53)
+#define R_VI_MODE_EDIT_LRX_ADJ SREG(54)
#define R_FB_FILTER_TYPE SREG(80)
#define R_FB_FILTER_PRIM_COLOR(c) SREG(81 + (c))
#define R_FB_FILTER_A SREG(84)
diff --git a/include/sched.h b/include/sched.h
index 48ecc7b245..da946bdce3 100644
--- a/include/sched.h
+++ b/include/sched.h
@@ -65,6 +65,6 @@ typedef struct {
} Scheduler; // size = 0x258
void Sched_Notify(Scheduler* sc);
-void Sched_Init(Scheduler* sc, void* stack, OSPri priority, UNK_TYPE arg3, UNK_TYPE arg4, IrqMgr* irqMgr);
+void Sched_Init(Scheduler* sc, void* stack, OSPri priority, u8 viModeType, UNK_TYPE arg4, IrqMgr* irqMgr);
#endif
diff --git a/include/tha.h b/include/tha.h
new file mode 100644
index 0000000000..1f086b0016
--- /dev/null
+++ b/include/tha.h
@@ -0,0 +1,28 @@
+#ifndef THA_H
+#define THA_H
+
+#include "ultra64.h"
+#include "alignment.h"
+
+typedef struct {
+ /* 0x00 */ size_t size;
+ /* 0x04 */ void* start;
+ /* 0x08 */ void* head;
+ /* 0x0C */ void* tail;
+} TwoHeadArena; // size = 0x10
+
+void* THA_GetHead(TwoHeadArena* tha);
+void THA_SetHead(TwoHeadArena* tha, void* newHead);
+void* THA_GetTail(TwoHeadArena* tha);
+void* THA_AllocHead(TwoHeadArena* tha, size_t size);
+void* THA_AllocHeadByte(TwoHeadArena* tha);
+void* THA_AllocTail(TwoHeadArena* tha, size_t size);
+void* THA_AllocTailAlign16(TwoHeadArena* tha, size_t size);
+void* THA_AllocTailAlign(TwoHeadArena* tha, size_t size, uintptr_t mask);
+s32 THA_GetRemaining(TwoHeadArena* tha);
+u32 THA_IsCrash(TwoHeadArena* tha);
+void THA_Reset(TwoHeadArena* tha);
+void THA_Init(TwoHeadArena* tha, void* start, size_t size);
+void THA_Destroy(TwoHeadArena* tha);
+
+#endif
diff --git a/include/thga.h b/include/thga.h
new file mode 100644
index 0000000000..9d9e96950a
--- /dev/null
+++ b/include/thga.h
@@ -0,0 +1,33 @@
+#ifndef THGA_H
+#define THGA_H
+
+#include "tha.h"
+
+typedef union {
+ /* 0x00 */ TwoHeadArena tha;
+ struct { // Same as TwoHeadArena, with different types and field names for the head and tail pointers
+ /* 0x00 */ size_t size;
+ /* 0x04 */ void* start;
+ /* 0x08 */ Gfx* p;
+ /* 0x0C */ void* d;
+ };
+} TwoHeadGfxArena; // size = 0x10
+
+void THGA_Init(TwoHeadGfxArena* thga, void* start, size_t size);
+void THGA_Destroy(TwoHeadGfxArena* thga);
+u32 THGA_IsCrash(TwoHeadGfxArena* thga);
+void THGA_Reset(TwoHeadGfxArena* thga);
+s32 THGA_GetRemaining(TwoHeadGfxArena* thga);
+Gfx* THGA_GetHead(TwoHeadGfxArena* thga);
+void THGA_SetHead(TwoHeadGfxArena* thga, Gfx* newHead);
+void* THGA_GetTail(TwoHeadGfxArena* thga);
+Gfx* THGA_AllocDisplayList(TwoHeadGfxArena* thga, size_t num);
+Gfx* THGA_AllocGfx(TwoHeadGfxArena* thga);
+Gfx* THGA_AllocGfx2(TwoHeadGfxArena* thga);
+void* THGA_AllocTail(TwoHeadGfxArena* thga, size_t size);
+Mtx* THGA_AllocMtxArray(TwoHeadGfxArena* thga, size_t num);
+Mtx* THGA_AllocMtx(TwoHeadGfxArena* thga);
+Vtx* THGA_AllocVtxArray(TwoHeadGfxArena* thga, size_t num);
+Vtx* THGA_AllocVtx(TwoHeadGfxArena* thga);
+
+#endif
diff --git a/include/ultra64.h b/include/ultra64.h
index e53e7a751f..6eadfb6af4 100644
--- a/include/ultra64.h
+++ b/include/ultra64.h
@@ -1,7 +1,7 @@
#ifndef ULTRA64_H
#define ULTRA64_H
-#include "ultra64/types.h"
+#include "ultra64/ultratypes.h"
#include "unk.h"
#include "libc/stdarg.h"
@@ -13,8 +13,6 @@
#include "ultra64/exception.h"
#include "ultra64/rcp.h"
-#include "ultra64/rdp.h"
-#include "ultra64/rsp.h"
#include "ultra64/thread.h"
#include "ultra64/convert.h"
#include "ultra64/time.h"
@@ -28,7 +26,7 @@
#include "ultra64/mbi.h"
#include "ultra64/pfs.h"
#include "ultra64/motor.h"
-#include "ultra64/r4300.h"
+#include "ultra64/R4300.h"
#include "ultra64/ucode.h"
#endif
diff --git a/include/ultra64/r4300.h b/include/ultra64/R4300.h
similarity index 99%
rename from include/ultra64/r4300.h
rename to include/ultra64/R4300.h
index 42782f80ca..6398ea17c4 100644
--- a/include/ultra64/r4300.h
+++ b/include/ultra64/R4300.h
@@ -2,7 +2,7 @@
#define ULTRA64_R4300_H
#ifdef _LANGUAGE_C
-#include "types.h"
+#include "ultratypes.h"
#define U32(x) ((u32)x)
#define C_REG(x) (x)
#else
diff --git a/include/ultra64/controller.h b/include/ultra64/controller.h
index 313809bf64..8b759db77f 100644
--- a/include/ultra64/controller.h
+++ b/include/ultra64/controller.h
@@ -3,19 +3,6 @@
#include "message.h"
-/**
- * Controller channel
- * Each game controller channel has 4 error bits that are defined in bit 6-7 of
- * the Rx and Tx data size area bytes. Programmers need to clear these bits
- * when setting the Tx/Rx size area values for a channel
- */
-#define CHNL_ERR_NORESP 0x80 /* Bit 7 (Rx): No response error */
-#define CHNL_ERR_OVERRUN 0x40 /* Bit 6 (Rx): Overrun error */
-#define CHNL_ERR_FRAME 0x80 /* Bit 7 (Tx): Frame error */
-#define CHNL_ERR_COLLISION 0x40 /* Bit 6 (Tx): Collision error */
-
-#define CHNL_ERR_MASK 0xC0 /* Bit 6-7: channel errors */
-
#define CHNL_ERR(readFormat) (((readFormat).rxsize & CHNL_ERR_MASK) >> 4)
#define BLOCKSIZE 32
diff --git a/include/ultra64/exception.h b/include/ultra64/exception.h
index c101bc5cea..7d4977f4f9 100644
--- a/include/ultra64/exception.h
+++ b/include/ultra64/exception.h
@@ -28,7 +28,7 @@
#ifdef _LANGUAGE_C
-#include "types.h"
+#include "ultratypes.h"
typedef u32 OSIntMask;
typedef u32 OSHWIntr;
diff --git a/include/ultra64/internal.h b/include/ultra64/internal.h
index a301f4a70a..0851314a8b 100644
--- a/include/ultra64/internal.h
+++ b/include/ultra64/internal.h
@@ -4,21 +4,21 @@
#include "pi.h"
typedef struct {
- /* 0x00 */ u32 initialized;
- /* 0x04 */ OSThread* mgrThread;
+ /* 0x00 */ u32 active;
+ /* 0x04 */ OSThread* thread;
/* 0x08 */ OSMesgQueue* cmdQueue;
- /* 0x0C */ OSMesgQueue* eventQueue;
- /* 0x10 */ OSMesgQueue* acccessQueue;
- /* 0x14 */ s32 (*piDmaCallback)(s32, u32, void*, size_t);
- /* 0x18 */ s32 (*epiDmaCallback)(OSPiHandle*, s32, u32, void*, size_t);
-} OSMgrArgs; // size = 0x1C
+ /* 0x0C */ OSMesgQueue* evtQueue;
+ /* 0x10 */ OSMesgQueue* acsQueue;
+ /* 0x14 */ s32 (*dma)(s32, u32, void*, size_t);
+ /* 0x18 */ s32 (*edma)(OSPiHandle*, s32, u32, void*, size_t);
+} OSDevMgr; // size = 0x1C
typedef struct {
/* 0x00 */ OSMesgQueue* queue;
/* 0x04 */ OSMesg msg;
} __OSEventState; // size = 0x08
-extern OSMgrArgs __osPiDevMgr;
+extern OSDevMgr __osPiDevMgr;
extern __OSEventState __osEventStateTab[];
#endif
diff --git a/include/ultra64/leodrive.h b/include/ultra64/leodrive.h
new file mode 100644
index 0000000000..36b28f4b9e
--- /dev/null
+++ b/include/ultra64/leodrive.h
@@ -0,0 +1,47 @@
+#ifndef ULTRA64_LEODRIVE_H
+#define ULTRA64_LEODRIVE_H
+
+#include "rcp.h"
+
+#define ASIC_BASE PI_DOM2_ADDR1
+
+#define ASIC_C2_BUFF (ASIC_BASE + 0x000) // C2 Sector Buffer
+#define ASIC_SECTOR_BUFF (ASIC_BASE + 0x400) // Data Sector Buffer
+#define ASIC_DATA (ASIC_BASE + 0x500) // Data
+#define ASIC_MISC_REG (ASIC_BASE + 0x504) // Misc Register
+#define ASIC_CMD (ASIC_BASE + 0x508) // Command (write)
+#define ASIC_STATUS (ASIC_BASE + 0x508) // Status (read)
+#define ASIC_CUR_TK (ASIC_BASE + 0x50C) // Current Track
+#define ASIC_BM_CTL (ASIC_BASE + 0x510) // Buffer Manager Control (write)
+#define ASIC_BM_STATUS (ASIC_BASE + 0x510) // Buffer Manager Status (read)
+#define ASIC_ERR_SECTOR (ASIC_BASE + 0x514) // Sector Error Status
+#define ASIC_SEQ_CTL (ASIC_BASE + 0x518) // Sequencer Control (write)
+#define ASIC_SEQ_STATUS (ASIC_BASE + 0x518) // Sequencer Status (read)
+#define ASIC_CUR_SECTOR (ASIC_BASE + 0x51C) // Current Sector
+#define ASIC_HARD_RESET (ASIC_BASE + 0x520) // Hard Reset
+#define ASIC_C1_S0 (ASIC_BASE + 0x524) // C1
+#define ASIC_HOST_SECBYTE (ASIC_BASE + 0x528) // Sector Size (in bytes)
+#define ASIC_C1_S2 (ASIC_BASE + 0x52C) // C1
+#define ASIC_SEC_BYTE (ASIC_BASE + 0x530) // Sectors per Block, Full Size
+#define ASIC_C1_S4 (ASIC_BASE + 0x534) // C1
+#define ASIC_C1_S6 (ASIC_BASE + 0x538) // C1
+#define ASIC_CUR_ADDR (ASIC_BASE + 0x53C) // Current Address
+#define ASIC_ID_REG (ASIC_BASE + 0x540) // ID
+#define ASIC_TEST_REG (ASIC_BASE + 0x544) // Test Read
+#define ASIC_TEST_PIN_SEL (ASIC_BASE + 0x548) // Test Write
+#define MSEQ_RAM_ADDR (ASIC_BASE + 0x580) // Microsequencer RAM
+
+// ASIC_BM_CTL write bits
+#define LEO_BM_START 0x80000000 // Start Buffer Manager
+#define LEO_BM_MODE 0x40000000 // Buffer Manager Mode
+#define LEO_BM_IMASK 0x20000000 // BM Interrupt Mask
+#define LEO_BM_RESET 0x10000000 // Buffer Manager Reset
+#define LEO_BM_DISABLE_OR_CHECK 0x08000000 // Disable OR Check
+#define LEO_BM_DISABLE_C1 0x04000000 // Disable C1 Correction
+#define LEO_BM_XFER_BLOCK 0x02000000 // Block Transfer
+#define LEO_BM_CLR_MECHANIC_INTR 0x01000000 // Mechanic Interrupt Reset
+
+// ASIC_STATUS read bits
+#define LEO_STATUS_MECHANIC_INTR 0x02000000 // Mechanic Interrupt Raised
+
+#endif
diff --git a/include/ultra64/pi.h b/include/ultra64/pi.h
index 8557189951..6fb52cea70 100644
--- a/include/ultra64/pi.h
+++ b/include/ultra64/pi.h
@@ -74,10 +74,4 @@ typedef struct {
#define OS_MESG_PRI_NORMAL 0
#define OS_MESG_PRI_HIGH 1
-#define DEVICE_TYPE_CART 0 /* ROM cartridge */
-#define DEVICE_TYPE_BULK 1 /* ROM bulk */
-#define DEVICE_TYPE_64DD 2 /* 64 Disk Drive */
-#define DEVICE_TYPE_SRAM 3 /* SRAM */
-#define DEVICE_TYPE_INIT 7 /* initial value */
-
#endif
diff --git a/include/ultra64/printf.h b/include/ultra64/printf.h
index 7724432f6f..4f2e29730a 100644
--- a/include/ultra64/printf.h
+++ b/include/ultra64/printf.h
@@ -1,7 +1,7 @@
#ifndef ULTRA64_PRINTF_H
#define ULTRA64_PRINTF_H
-#include "types.h"
+#include "ultratypes.h"
typedef struct {
/* 0x0 */ union {
diff --git a/include/ultra64/rcp.h b/include/ultra64/rcp.h
index d92b743c63..86387ef5e8 100644
--- a/include/ultra64/rcp.h
+++ b/include/ultra64/rcp.h
@@ -1,139 +1,811 @@
#ifndef ULTRA64_RCP_H
#define ULTRA64_RCP_H
-#ifdef _LANGUAGE_C
-#define HW_REG(reg, type) *(volatile type*)((reg) | 0xA0000000)
-#endif
+#include "R4300.h"
+#include "ultratypes.h"
-#define AI_DRAM_ADDR_REG 0x04500000
-#define AI_LEN_REG 0x04500004
-#define AI_CONTROL_REG 0x04500008
-#define AI_STATUS_REG 0x0450000C
-#define AI_DACRATE_REG 0x04500010
-#define AI_BITRATE_REG 0x04500014
+/**
+ * RCP memory map overview:
+ *
+ * 0x0000_0000 .. 0x03EF_FFFF RDRAM memory
+ * 0x03F0_0000 .. 0x03FF_FFFF RDRAM registers
+ *
+ * 0x0400_0000 .. 0x0400_2000 SP memory
+ * 0x0404_0000 .. 0x040F_FFFF SP registers
+ * 0x0410_0000 .. 0x041F_FFFF DP command registers
+ * 0x0420_0000 .. 0x042F_FFFF DP span registers
+ * 0x0430_0000 .. 0x043F_FFFF MI registers
+ * 0x0440_0000 .. 0x044F_FFFF VI registers
+ * 0x0450_0000 .. 0x045F_FFFF AI registers
+ * 0x0460_0000 .. 0x046F_FFFF PI registers
+ * 0x0470_0000 .. 0x047F_FFFF RI registers
+ * 0x0480_0000 .. 0x048F_FFFF SI registers
+ * 0x0490_0000 .. 0x04FF_FFFF unused
+ *
+ * 0x0500_0000 .. 0x05FF_FFFF cartridge domain 2
+ * 0x0600_0000 .. 0x07FF_FFFF cartridge domain 1
+ * 0x0800_0000 .. 0x0FFF_FFFF cartridge domain 2
+ * 0x1000_0000 .. 0x1FBF_FFFF cartridge domain 1
+ *
+ * 0x1FC0_0000 .. 0x1FC0_07BF PIF Boot Rom (1984 bytes)
+ * 0x1FC0_07C0 .. 0x1FC0_07FF PIF (JoyChannel) RAM (64 bytes)
+ * 0x1FC0_0800 .. 0x1FCF_FFFF Reserved
+ * 0x1FD0_0000 .. 0x7FFF_FFFF cartridge domain 1
+ * 0x8000_0000 .. 0xFFFF_FFFF external SysAD device
+ */
-#define AI_STATUS_AI_FULL (1 << 31)
-#define AI_STATUS_AI_BUSY (1 << 30)
-#define VI_STATUS_REG 0x04400000
-#define VI_CONTROL_REG VI_STATUS_REG
-#define VI_ORIGIN_REG 0x04400004
-#define VI_DRAM_ADDR_REG VI_ORIGIN_REG
-#define VI_WIDTH_REG 0x04400008
-#define VI_H_WIDTH_REG VI_WIDTH_REG
-#define VI_INTR_REG 0x0440000C
-#define VI_V_INTER_REG VI_INTR_REG
-#define VI_CURRENT_REG 0x04400010
+/**
+ * RDRAM memory
+ */
+
+#define RDRAM_0_START 0x00000000
+#define RDRAM_0_END 0x001FFFFF
+#define RDRAM_1_START 0x00200000
+#define RDRAM_1_END 0x003FFFFF
+
+#define RDRAM_START RDRAM_0_START
+#define RDRAM_END RDRAM_1_END
+
+
+/**
+ * RDRAM registers
+ */
+#define RDRAM_BASE_REG 0x03F00000
+
+#define RDRAM_CONFIG_REG (RDRAM_BASE_REG + 0x00)
+#define RDRAM_DEVICE_TYPE_REG (RDRAM_BASE_REG + 0x00)
+#define RDRAM_DEVICE_ID_REG (RDRAM_BASE_REG + 0x04)
+#define RDRAM_DELAY_REG (RDRAM_BASE_REG + 0x08)
+#define RDRAM_MODE_REG (RDRAM_BASE_REG + 0x0C)
+#define RDRAM_REF_INTERVAL_REG (RDRAM_BASE_REG + 0x10)
+#define RDRAM_REF_ROW_REG (RDRAM_BASE_REG + 0x14)
+#define RDRAM_RAS_INTERVAL_REG (RDRAM_BASE_REG + 0x18)
+#define RDRAM_MIN_INTERVAL_REG (RDRAM_BASE_REG + 0x1C)
+#define RDRAM_ADDR_SELECT_REG (RDRAM_BASE_REG + 0x20)
+#define RDRAM_DEVICE_MANUF_REG (RDRAM_BASE_REG + 0x24)
+
+#define RDRAM_0_DEVICE_ID 0
+#define RDRAM_1_DEVICE_ID 1
+
+#define RDRAM_RESET_MODE 0
+#define RDRAM_ACTIVE_MODE 1
+#define RDRAM_STANDBY_MODE 2
+
+#define RDRAM_LENGTH (2 * 512 * 2048)
+#define RDRAM_0_BASE_ADDRESS (RDRAM_0_DEVICE_ID * RDRAM_LENGTH)
+#define RDRAM_1_BASE_ADDRESS (RDRAM_1_DEVICE_ID * RDRAM_LENGTH)
+
+#define RDRAM_0_CONFIG 0x00000
+#define RDRAM_1_CONFIG 0x00400
+#define RDRAM_GLOBAL_CONFIG 0x80000
+
+
+/**
+ * PIF Physical memory map (total size = 2 KB)
+ *
+ * Size Description Mode
+ * 1FC007FF +-------+-----------------+-----+
+ * | 64 B | JoyChannel RAM | R/W |
+ * 1FC007C0 +-------+-----------------+-----+
+ * |1984 B | Boot ROM | * | * = Reserved
+ * 1FC00000 +-------+-----------------+-----+
+ */
+#define PIF_ROM_START 0x1FC00000
+#define PIF_ROM_END 0x1FC007BF
+#define PIF_RAM_START 0x1FC007C0
+#define PIF_RAM_END 0x1FC007FF
+
+
+/**
+ * Controller channel
+ * Each game controller channel has 4 error bits that are defined in bit 6-7 of
+ * the Rx and Tx data size area bytes. Programmers need to clear these bits
+ * when setting the Tx/Rx size area values for a channel
+ */
+#define CHNL_ERR_NORESP 0x80 /* Bit 7 (Rx): No response error */
+#define CHNL_ERR_OVERRUN 0x40 /* Bit 6 (Rx): Overrun error */
+#define CHNL_ERR_FRAME 0x80 /* Bit 7 (Tx): Frame error */
+#define CHNL_ERR_COLLISION 0x40 /* Bit 6 (Tx): Collision error */
+
+#define CHNL_ERR_MASK 0xC0 /* Bit 6-7: channel errors */
+
+
+/**
+ * External device info
+ */
+#define DEVICE_TYPE_CART 0 // ROM cartridge
+#define DEVICE_TYPE_BULK 1 // ROM bulk
+#define DEVICE_TYPE_64DD 2 // 64 Disk Drive
+#define DEVICE_TYPE_SRAM 3 // SRAM
+// 4-6 are reserved
+#define DEVICE_TYPE_INIT 7 // initial value
+// 8-14 are reserved
+
+
+/**
+ * Signal Processor (SP) Memory
+ */
+#define SP_DMEM_START 0x04000000
+#define SP_DMEM_END 0x04000FFF
+#define SP_IMEM_START 0x04001000
+#define SP_IMEM_END 0x04001FFF
+
+
+/**
+ * Signal Processor (SP) CP0 Registers
+ */
+
+#define SP_BASE_REG 0x04040000
+
+// SP memory address (R/W): [12] 0=DMEM,1=IMEM, [11:0] DMEM/IMEM address
+#define SP_MEM_ADDR_REG (SP_BASE_REG + 0x00)
+
+// SP DRAM DMA address (R/W): [23:0] RDRAM address
+#define SP_DRAM_ADDR_REG (SP_BASE_REG + 0x04)
+
+// SP read DMA length (R/W): [31:20] skip, [19:12] count, [11:0] length; RDRAM -> I/DMEM
+#define SP_RD_LEN_REG (SP_BASE_REG + 0x08)
+
+// SP write DMA length (R/W): [31:20] skip, [19:12] count, [11:0] length; I/DMEM -> RDRAM
+#define SP_WR_LEN_REG (SP_BASE_REG + 0x0C)
+
+// SP status (R/W): [14:0] valid bits; see below for write/read mode
+#define SP_STATUS_REG (SP_BASE_REG + 0x10)
+
+// SP DMA full (R): [0] dma full
+#define SP_DMA_FULL_REG (SP_BASE_REG + 0x14)
+
+// SP DMA busy (R): [0] dma busy
+#define SP_DMA_BUSY_REG (SP_BASE_REG + 0x18)
+
+// SP semaphore (R/W): Read: [0] acquire semaphore; Write: [] release semaphore
+#define SP_SEMAPHORE_REG (SP_BASE_REG + 0x1C)
+
+// SP PC (R/W): [11:0] program counter
+#define SP_PC_REG 0x04080000
+
+/*
+ * SP_MEM_ADDR_REG: bit 12
+ */
+#define SP_DMA_DMEM (0 << 12)
+#define SP_DMA_IMEM (1 << 12)
+
+/*
+ * SP_STATUS_REG: write bits
+ */
+#define SP_CLR_HALT (1 << 0) // clear halt
+#define SP_SET_HALT (1 << 1) // set halt
+#define SP_CLR_BROKE (1 << 2) // clear broke
+#define SP_CLR_INTR (1 << 3) // clear interrupt
+#define SP_SET_INTR (1 << 4) // set interrupt
+#define SP_CLR_SSTEP (1 << 5) // clear sstep
+#define SP_SET_SSTEP (1 << 6) // set sstep
+#define SP_CLR_INTR_BREAK (1 << 7) // clear interrupt on break
+#define SP_SET_INTR_BREAK (1 << 8) // set interrupt on break
+#define SP_CLR_SIG0 (1 << 9) // clear signal 0
+#define SP_SET_SIG0 (1 << 10) // set signal 0
+#define SP_CLR_SIG1 (1 << 11) // clear signal 1
+#define SP_SET_SIG1 (1 << 12) // set signal 1
+#define SP_CLR_SIG2 (1 << 13) // clear signal 2
+#define SP_SET_SIG2 (1 << 14) // set signal 2
+#define SP_CLR_SIG3 (1 << 15) // clear signal 3
+#define SP_SET_SIG3 (1 << 16) // set signal 3
+#define SP_CLR_SIG4 (1 << 17) // clear signal 4
+#define SP_SET_SIG4 (1 << 18) // set signal 4
+#define SP_CLR_SIG5 (1 << 19) // clear signal 5
+#define SP_SET_SIG5 (1 << 20) // set signal 5
+#define SP_CLR_SIG6 (1 << 21) // clear signal 6
+#define SP_SET_SIG6 (1 << 22) // set signal 6
+#define SP_CLR_SIG7 (1 << 23) // clear signal 7
+#define SP_SET_SIG7 (1 << 24) // set signal 7
+
+/*
+ * SP_STATUS_REG: read bits
+ */
+#define SP_STATUS_HALT (1 << 0)
+#define SP_STATUS_BROKE (1 << 1)
+#define SP_STATUS_DMA_BUSY (1 << 2)
+#define SP_STATUS_DMA_FULL (1 << 3)
+#define SP_STATUS_IO_FULL (1 << 4)
+#define SP_STATUS_SSTEP (1 << 5)
+#define SP_STATUS_INTR_BREAK (1 << 6)
+#define SP_STATUS_SIG0 (1 << 7)
+#define SP_STATUS_SIG1 (1 << 8)
+#define SP_STATUS_SIG2 (1 << 9)
+#define SP_STATUS_SIG3 (1 << 10)
+#define SP_STATUS_SIG4 (1 << 11)
+#define SP_STATUS_SIG5 (1 << 12)
+#define SP_STATUS_SIG6 (1 << 13)
+#define SP_STATUS_SIG7 (1 << 14)
+
+/*
+ * SP_STATUS_REG: use of SIG bits
+ */
+#define SP_CLR_YIELD SP_CLR_SIG0
+#define SP_SET_YIELD SP_SET_SIG0
+#define SP_STATUS_YIELD SP_STATUS_SIG0
+#define SP_CLR_YIELDED SP_CLR_SIG1
+#define SP_SET_YIELDED SP_SET_SIG1
+#define SP_STATUS_YIELDED SP_STATUS_SIG1
+#define SP_CLR_TASKDONE SP_CLR_SIG2
+#define SP_SET_TASKDONE SP_SET_SIG2
+#define SP_STATUS_TASKDONE SP_STATUS_SIG2
+#define SP_CLR_RSPSIGNAL SP_CLR_SIG3
+#define SP_SET_RSPSIGNAL SP_SET_SIG3
+#define SP_STATUS_RSPSIGNAL SP_STATUS_SIG3
+#define SP_CLR_CPUSIGNAL SP_CLR_SIG4
+#define SP_SET_CPUSIGNAL SP_SET_SIG4
+#define SP_STATUS_CPUSIGNAL SP_STATUS_SIG4
+
+// SP IMEM BIST REG (R/W): [6:0] BIST status bits; see below for detail
+#define SP_IBIST_REG 0x04080004
+
+/*
+ * SP_IBIST_REG: write bits
+ */
+#define SP_IBIST_CHECK (1 << 0) // BIST check
+#define SP_IBIST_GO (1 << 1) // BIST go
+#define SP_IBIST_CLEAR (1 << 2) // BIST clear
+
+/*
+ * SP_BIST_REG: read bits
+ * First 2 bits are same as in write mode
+ */
+#define SP_IBIST_DONE (1 << 2)
+#define SP_IBIST_FAILED 0x78 // bits [6:3], BIST fail
+
+
+/**
+ * Display Processor Command (DPC) Registers
+ */
+#define DPC_BASE_REG 0x04100000
+
+// DP CMD DMA start (R/W): [23:0] DMEM/RDRAM start address
+#define DPC_START_REG (DPC_BASE_REG + 0x00)
+
+// DP CMD DMA end (R/W): [23:0] DMEM/RDRAM end address
+#define DPC_END_REG (DPC_BASE_REG + 0x04)
+
+// DP CMD DMA end (R): [23:0] DMEM/RDRAM current address
+#define DPC_CURRENT_REG (DPC_BASE_REG + 0x08)
+
+// DP CMD status (R/W): [9:0] valid bits - see below for definitions
+#define DPC_STATUS_REG (DPC_BASE_REG + 0x0C)
+
+// DP clock counter (R): [23:0] clock counter
+#define DPC_CLOCK_REG (DPC_BASE_REG + 0x10)
+
+// DP buffer busy counter (R): [23:0] clock counter
+#define DPC_BUFBUSY_REG (DPC_BASE_REG + 0x14)
+
+// DP pipe busy counter (R): [23:0] clock counter
+#define DPC_PIPEBUSY_REG (DPC_BASE_REG + 0x18)
+
+// DP TMEM load counter (R): [23:0] clock counter
+#define DPC_TMEM_REG (DPC_BASE_REG + 0x1C)
+
+/*
+ * DPC_STATUS_REG: write bits
+ */
+#define DPC_CLR_XBUS_DMEM_DMA (1 << 0)
+#define DPC_SET_XBUS_DMEM_DMA (1 << 1)
+#define DPC_CLR_FREEZE (1 << 2)
+#define DPC_SET_FREEZE (1 << 3)
+#define DPC_CLR_FLUSH (1 << 4)
+#define DPC_SET_FLUSH (1 << 5)
+#define DPC_CLR_TMEM_CTR (1 << 6)
+#define DPC_CLR_PIPE_CTR (1 << 7)
+#define DPC_CLR_CMD_CTR (1 << 8)
+#define DPC_CLR_CLOCK_CTR (1 << 9)
+
+/*
+ * DPC_STATUS_REG: read bits
+ */
+#define DPC_STATUS_XBUS_DMEM_DMA (1 << 0)
+#define DPC_STATUS_FREEZE (1 << 1)
+#define DPC_STATUS_FLUSH (1 << 2)
+#define DPC_STATUS_START_GCLK (1 << 3)
+#define DPC_STATUS_TMEM_BUSY (1 << 4)
+#define DPC_STATUS_PIPE_BUSY (1 << 5)
+#define DPC_STATUS_CMD_BUSY (1 << 6)
+#define DPC_STATUS_CBUF_READY (1 << 7)
+#define DPC_STATUS_DMA_BUSY (1 << 8)
+#define DPC_STATUS_END_VALID (1 << 9)
+#define DPC_STATUS_START_VALID (1 << 10)
+
+
+/**
+ * Display Processor Span (DPS) Registers
+ */
+#define DPS_BASE_REG 0x04200000
+
+// DP tmem built-in self-test (R/W): [10:0] BIST status bits
+#define DPS_TBIST_REG (DPS_BASE_REG + 0x00)
+
+// DP span test mode (R/W): [0] Span buffer test access enable
+#define DPS_TEST_MODE_REG (DPS_BASE_REG + 0x04)
+
+// DP span buffer test address (R/W): [6:0] bits
+#define DPS_BUFTEST_ADDR_REG (DPS_BASE_REG + 0x08)
+
+// DP span buffer test data (R/W): [31:0] span buffer data
+#define DPS_BUFTEST_DATA_REG (DPS_BASE_REG + 0x0C)
+
+/*
+ * DPS_TMEM_BIST_REG: write bits
+ */
+#define DPS_TBIST_CHECK (1 << 0)
+#define DPS_TBIST_GO (1 << 1)
+#define DPS_TBIST_CLEAR (1 << 2)
+
+/*
+ * DPS_TMEM_BIST_REG: read bits
+ * First 2 bits are same as in write mode
+ */
+#define DPS_TBIST_DONE (1 << 2)
+#define DPS_TBIST_FAILED 0x7F8 // bits [10:3], BIST fail
+
+
+/**
+ * MIPS Interface (MI) Registers
+ */
+#define MI_BASE_REG 0x04300000
+
+// MI init mode (W): [11] clear DP interrupt, [9/10] clear/set ebus test mode
+// [8] set init mode, [7] clear init mode, [6:0] init length
+// (R): [8] ebus test mode, [7] init mode, [6:0] init length
+#define MI_INIT_MODE_REG (MI_BASE_REG + 0x00)
+#define MI_MODE_REG MI_INIT_MODE_REG
+
+/*
+ * MI_MODE_REG: write bits
+ */
+#define MI_CLR_INIT (1 << 7) // clear init mode
+#define MI_SET_INIT (1 << 8) // set init mode
+#define MI_CLR_EBUS (1 << 9) // clear ebus test
+#define MI_SET_EBUS (1 << 10) // set ebus test mode
+#define MI_CLR_DP_INTR (1 << 11) // clear dp interrupt
+#define MI_CLR_RDRAM (1 << 12) // clear RDRAM reg
+#define MI_SET_RDRAM (1 << 13) // set RDRAM reg mode
+
+/*
+ * MI_MODE_REG: read bits
+ */
+#define MI_MODE_INIT (1 << 7) /* init mode */
+#define MI_MODE_EBUS (1 << 8) /* ebus test mode */
+#define MI_MODE_RDRAM (1 << 9) /* RDRAM reg mode */
+
+// MI version (R): [31:24] rsp, [23:16] rdp, [15:8] rac, [7:0] io
+#define MI_VERSION_REG (MI_BASE_REG + 0x04)
+#define MI_NOOP_REG MI_VERSION_REG
+
+// MI interrupt (R): [5:0] valid bits - see below for bit patterns
+#define MI_INTR_REG (MI_BASE_REG + 0x08)
+
+// MI interrupt mask (R): [5:0] valid bits - see below for bit patterns
+// (W): [11:0] valid bits - see below for bit patterns
+#define MI_INTR_MASK_REG (MI_BASE_REG + 0x0C)
+
+/*
+ * MI_INTR_REG: read bits
+ */
+#define MI_INTR_SP (1 << 0) // SP intr
+#define MI_INTR_SI (1 << 1) // SI intr
+#define MI_INTR_AI (1 << 2) // AI intr
+#define MI_INTR_VI (1 << 3) // VI intr
+#define MI_INTR_PI (1 << 4) // PI intr
+#define MI_INTR_DP (1 << 5) // DP intr
+
+/*
+ * MI_INTR_MASK_REG: write bits
+ */
+#define MI_INTR_MASK_CLR_SP (1 << 0) // clear SP mask
+#define MI_INTR_MASK_SET_SP (1 << 1) // set SP mask
+#define MI_INTR_MASK_CLR_SI (1 << 2) // clear SI mask
+#define MI_INTR_MASK_SET_SI (1 << 3) // set SI mask
+#define MI_INTR_MASK_CLR_AI (1 << 4) // clear AI mask
+#define MI_INTR_MASK_SET_AI (1 << 5) // set AI mask
+#define MI_INTR_MASK_CLR_VI (1 << 6) // clear VI mask
+#define MI_INTR_MASK_SET_VI (1 << 7) // set VI mask
+#define MI_INTR_MASK_CLR_PI (1 << 8) // clear PI mask
+#define MI_INTR_MASK_SET_PI (1 << 9) // set PI mask
+#define MI_INTR_MASK_CLR_DP (1 << 10) // clear DP mask
+#define MI_INTR_MASK_SET_DP (1 << 11) // set DP mask
+
+/*
+ * MI_INTR_MASK_REG: read bits
+ */
+#define MI_INTR_MASK_SP (1 << 0) // SP intr mask
+#define MI_INTR_MASK_SI (1 << 1) // SI intr mask
+#define MI_INTR_MASK_AI (1 << 2) // AI intr mask
+#define MI_INTR_MASK_VI (1 << 3) // VI intr mask
+#define MI_INTR_MASK_PI (1 << 4) // PI intr mask
+#define MI_INTR_MASK_DP (1 << 5) // DP intr mask
+
+
+/**
+ * Video Interface (VI) Registers
+ */
+#define VI_BASE_REG 0x04400000
+
+/*
+ * VI status/control (R/W): [15-0] valid bits:
+ * [1:0] = type[1:0] (pixel size)
+ * 0: blank (no data, no sync)
+ * 1: reserved
+ * 2: 5/5/5/3 ("16" bit)
+ * 3: 8/8/8/8 (32 bit)
+ * [2] = gamma_dither_enable (normally on, unless "special effect")
+ * [3] = gamma_enable (normally on, unless MPEG/JPEG)
+ * [4] = divot_enable (normally on if antialiased, unless decal lines)
+ * [5] = vbus_clock_enable - always off
+ * [6] = serrate (always on if interlaced, off if not)
+ * [7] = test_mode - diagnostics only
+ * [9:8] = anti-alias (aa) mode[1:0]
+ * 0: aa & resamp (always fetch extra lines)
+ * 1: aa & resamp (fetch extra lines if needed)
+ * 2: resamp only (treat as all fully covered)
+ * 3: neither (replicate pixels, no interpolate)
+ * [11] = kill_we - diagnostics only
+ * [15:12] = pixel_advance
+ * [16] = dither_filter_enable
+ */
+#define VI_CONTROL_REG (VI_BASE_REG + 0x00)
+#define VI_STATUS_REG VI_CONTROL_REG
+
+// VI origin (R/W): [23:0] frame buffer origin in bytes
+#define VI_ORIGIN_REG (VI_BASE_REG + 0x04)
+#define VI_DRAM_ADDR_REG VI_ORIGIN_REG
+
+// VI width (R/W): [11:0] frame buffer line width in pixels
+#define VI_WIDTH_REG (VI_BASE_REG + 0x08)
+#define VI_H_WIDTH_REG VI_WIDTH_REG
+
+// VI vertical intr (R/W): [9:0] interrupt when current half-line = V_INTR
+#define VI_INTR_REG (VI_BASE_REG + 0x0C)
+#define VI_V_INTR_REG VI_INTR_REG
+
+// VI current vertical line (R/W): [9:0] current half line, sampled once per
+// line (the lsb of V_CURRENT is constant within a field, and in interlaced
+// modes gives the field number - which is constant for non-interlaced modes)
+// - Any write to this register will clear interrupt line
+#define VI_CURRENT_REG (VI_BASE_REG + 0x10)
#define VI_V_CURRENT_LINE_REG VI_CURRENT_REG
-#define VI_BURST_REG 0x04400014
-#define VI_TIMING_REG VI_BURST_REG
-#define VI_V_SYNC_REG 0x04400018 //VI vertical sync
-#define VI_H_SYNC_REG 0x0440001C //VI horizontal sync
-#define VI_LEAP_REG 0x04400020 //VI horizontal sync leap
-#define VI_H_SYNC_LEAP_REG VI_LEAP_REG
-#define VI_H_START_REG 0x04400024 //VI horizontal video
-#define VI_H_VIDEO_REG VI_H_START_REG
-#define VI_V_START_REG 0x04400028 //VI vertical video
-#define VI_V_VIDEO_REG VI_V_START_REG
-#define VI_V_BURST_REG 0x0440002C //VI vertical burst
-#define VI_X_SCALE_REG 0x04400030 //VI x-scale
-#define VI_Y_SCALE_REG 0x04400034 //VI y-scale
-#define SP_IMEM_START 0x04001000
-#define SP_DMEM_START 0x04000000
+// VI video timing (R/W): [29:20] start of color burst in pixels from h-sync
+// [19:16] vertical sync width in half lines,
+// [15: 8] color burst width in pixels,
+// [ 7: 0] horizontal sync width in pixels,
+#define VI_BURST_REG (VI_BASE_REG + 0x14)
+#define VI_TIMING_REG VI_BURST_REG
-#define SP_MEM_ADDR_REG 0x04040000
-#define SP_DRAM_ADDR_REG 0x04040004
-#define SP_RD_LEN_REG 0x04040008
-#define SP_WR_LEN_REG 0x0404000C
-#define SP_STATUS_REG 0x04040010
-#define SP_PC_REG 0x04080000
+// VI vertical sync (R/W): [9:0] number of half-lines per field
+#define VI_V_SYNC_REG (VI_BASE_REG + 0x18)
-#define PI_DRAM_ADDR_REG 0x04600000 //PI DRAM address
-#define PI_CART_ADDR_REG 0x04600004 //PI pbus (cartridge) address
-#define PI_RD_LEN_REG 0x04600008 //PI read length
-#define PI_WR_LEN_REG 0x0460000C //PI write length
-#define PI_STATUS_REG 0x04600010 //PI status
-#define PI_BSD_DOM1_LAT_REG 0x04600014 //PI dom1 latency
-#define PI_DOMAIN1_REG 0x04600014
-#define PI_BSD_DOM1_PWD_REG 0x04600018 //PI dom1 pulse width
-#define PI_BSD_DOM1_PGS_REG 0x0460001C //PI dom1 page size
-#define PI_BSD_DOM1_RLS_REG 0x04600020 //PI dom1 release
-#define PI_BSD_DOM2_LAT_REG 0x04600024 //PI dom2 latency
-#define PI_DOMAIN2_REG 0x04600024
-#define PI_BSD_DOM2_PWD_REG 0x04600028 //PI dom2 pulse width
-#define PI_BSD_DOM2_PGS_REG 0x0460002C //PI dom2 page size
-#define PI_BSD_DOM2_RLS_REG 0x04600030 //PI dom2 release
+// VI horizontal sync (R/W): [20:16] a 5-bit leap pattern used for PAL only (h_sync_period)
+// [11: 0] total duration of a line in 1/4 pixel
+#define VI_H_SYNC_REG (VI_BASE_REG + 0x1C)
-// PI_STATUS (read) bits
-#define PI_STATUS_BUSY (1 << 0)
-#define PI_STATUS_IOBUSY (1 << 1)
-#define PI_STATUS_ERROR (1 << 2)
+// VI horizontal sync leap (R/W): [27:16] identical to h_sync_period
+// [11: 0] identical to h_sync_period
+#define VI_LEAP_REG (VI_BASE_REG + 0x20)
+#define VI_H_SYNC_LEAP_REG VI_LEAP_REG
-// PI_STATUS (write) bits
-#define PI_STATUS_RESET (1 << 0)
-#define PI_STATUS_CLR_INTR (1 << 1)
+// VI horizontal video (R/W): [25:16] start of active video in screen pixels
+// [ 9: 0] end of active video in screen pixels
+#define VI_H_START_REG (VI_BASE_REG + 0x24)
+#define VI_H_VIDEO_REG VI_H_START_REG
-#define SI_DRAM_ADDR_REG 0x04800000
-#define SI_PIF_ADDR_RD64B_REG 0x04800004
-#define SI_PIF_ADDR_WR64B_REG 0x04800010
-#define SI_STATUS_REG 0x04800018
+// VI vertical video (R/W): [25:16] start of active video in screen half-lines
+// [ 9: 0] end of active video in screen half-lines
+#define VI_V_START_REG (VI_BASE_REG + 0x28)
+#define VI_V_VIDEO_REG VI_V_START_REG
-// SI_STATUS (read) bits
-#define SI_STATUS_DMA_BUSY (1 << 0)
-#define SI_STATUS_IO_READ_BUSY (1 << 1)
-#define SI_STATUS_DMA_ERROR (1 << 3)
-#define SI_STATUS_INTERRUPT (1 << 12)
+// VI vertical burst (R/W): [25:16] start of color burst enable in half-lines
+// [ 9: 0] end of color burst enable in half-lines
+#define VI_V_BURST_REG (VI_BASE_REG + 0x2C)
-#define PIF_RAM_START 0x1FC007C0
+// VI x-scale (R/W): [27:16] horizontal subpixel offset (2.10 format)
+// [11: 0] 1/horizontal scale up factor (2.10 format)
+#define VI_X_SCALE_REG (VI_BASE_REG + 0x30)
-#define MI_INIT_MODE_REG 0x04300000
-#define MI_MODE_REG MI_INIT_MODE_REG
-#define MI_VERSION_REG 0x04300004
-#define MI_INTR_REG 0x04300008
-#define MI_INTR_MASK_REG 0x0430000C
+// VI y-scale (R/W): [27:16] vertical subpixel offset (2.10 format)
+// [11: 0] 1/vertical scale up factor (2.10 format)
+#define VI_Y_SCALE_REG (VI_BASE_REG + 0x34)
-// MI_INIT_MODE_REG bits (write)
-#define MI_CLR_INIT (1 << 7)
-#define MI_SET_INIT (1 << 8)
-#define MI_CLR_EBUS (1 << 9)
-#define MI_SET_EBUS (1 << 10)
-#define MI_CLR_DP_INTR (1 << 11)
-#define MI_CLR_RDRAM (1 << 12)
-#define MI_SET_RDRAM (1 << 13)
+/*
+ * VI_CONTROL_REG: read bits
+ */
+#define VI_CTRL_TYPE_16 0x00002 // [1:0] pixel size: 16 bit
+#define VI_CTRL_TYPE_32 0x00003 // [1:0] pixel size: 32 bit
+#define VI_CTRL_GAMMA_DITHER_ON 0x00004 // 2: default = on
+#define VI_CTRL_GAMMA_ON 0x00008 // 3: default = on
+#define VI_CTRL_DIVOT_ON 0x00010 // 4: default = on
+#define VI_CTRL_SERRATE_ON 0x00040 // 6: on if interlaced
+#define VI_CTRL_ANTIALIAS_MASK 0x00300 // [9:8] anti-alias mode
+#define VI_CTRL_ANTIALIAS_MODE_0 0x00000 // Bit [9:8] anti-alias mode: AA enabled, resampling enabled, always fetch extra lines
+#define VI_CTRL_ANTIALIAS_MODE_1 0x00100 // Bit [9:8] anti-alias mode: AA enabled, resampling enabled, fetch extra lines as-needed
+#define VI_CTRL_ANTIALIAS_MODE_2 0x00200 // Bit [9:8] anti-alias mode: AA disabled, resampling enabled, operate as if everything is covered
+#define VI_CTRL_ANTIALIAS_MODE_3 0x00300 // Bit [9:8] anti-alias mode: AA disabled, resampling disabled, replicate pixels
+#define VI_CTRL_PIXEL_ADV_MASK 0x0F000 // [15:12] pixel advance mode
+#define VI_CTRL_PIXEL_ADV(n) (((n) << 12) & VI_CTRL_PIXEL_ADV_MASK) // Bit [15:12] pixel advance mode: Always 3 on N64
+#define VI_CTRL_DITHER_FILTER_ON 0x10000 // 16: dither-filter mode
-// MI_INTR_REG bits
-#define MI_INTR_SP (1 << 0)
-#define MI_INTR_SI (1 << 1)
-#define MI_INTR_AI (1 << 2)
-#define MI_INTR_VI (1 << 3)
-#define MI_INTR_PI (1 << 4)
-#define MI_INTR_DP (1 << 5)
+/*
+ * Possible video clocks (NTSC or PAL)
+ */
+#define VI_NTSC_CLOCK 48681812 // Hz = 48.681812 MHz
+#define VI_PAL_CLOCK 49656530 // Hz = 49.656530 MHz
+#define VI_MPAL_CLOCK 48628316 // Hz = 48.628316 MHz
-// MI_INTR_MASK_REG masks (read)
-#define MI_INTR_MASK_SP 0x01
-#define MI_INTR_MASK_SI 0x02
-#define MI_INTR_MASK_AI 0x04
-#define MI_INTR_MASK_VI 0x08
-#define MI_INTR_MASK_PI 0x10
-#define MI_INTR_MASK_DP 0x20
-// MI_INTR_MASK_REG masks (write)
-#define MI_INTR_MASK_CLR_SP 0x0001
-#define MI_INTR_MASK_SET_SP 0x0002
-#define MI_INTR_MASK_CLR_SI 0x0004
-#define MI_INTR_MASK_SET_SI 0x0008
-#define MI_INTR_MASK_CLR_AI 0x0010
-#define MI_INTR_MASK_SET_AI 0x0020
-#define MI_INTR_MASK_CLR_VI 0x0040
-#define MI_INTR_MASK_SET_VI 0x0080
-#define MI_INTR_MASK_CLR_PI 0x0100
-#define MI_INTR_MASK_SET_PI 0x0200
-#define MI_INTR_MASK_CLR_DP 0x0400
-#define MI_INTR_MASK_SET_DP 0x0800
+/**
+ * Audio Interface (AI) Registers
+ *
+ * The address and length registers are double buffered; that is, they
+ * can be written twice before becoming full.
+ * The address must be written before the length.
+ */
+#define AI_BASE_REG 0x04500000
-#define VI_NTSC_CLOCK 48681812 /* Hz = 48.681812 MHz */
-#define VI_PAL_CLOCK 49656530 /* Hz = 49.656530 MHz */
-#define VI_MPAL_CLOCK 48628316 /* Hz = 48.628316 MHz */
+// AI DRAM address (W): [23:0] starting RDRAM address (8B-aligned)
+#define AI_DRAM_ADDR_REG (AI_BASE_REG + 0x00)
+
+// AI length (R/W): [14:0] transfer length (v1.0) - Bottom 3 bits are ignored
+// [17:0] transfer length (v2.0) - Bottom 3 bits are ignored
+#define AI_LEN_REG (AI_BASE_REG + 0x04)
+
+// AI control (W): [0] DMA enable - if LSB == 1, DMA is enabled
+#define AI_CONTROL_REG (AI_BASE_REG + 0x08)
+
+/*
+ * AI_CONTROL_REG: write bits
+ */
+#define AI_CONTROL_DMA_ON 1 // LSB = 1: DMA enable
+#define AI_CONTROL_DMA_OFF 0 // LSB = 1: DMA enable
+
+// AI status (R): [31]/[0] ai_full (addr & len buffer full), [30] ai_busy
+// Note that a 1->0 transition in ai_full will set interrupt
+// (W): clear audio interrupt
+#define AI_STATUS_REG (AI_BASE_REG + 0x0C)
+
+/*
+ * AI_STATUS_REG: read bits
+ */
+#define AI_STATUS_FIFO_FULL (1 << 31)
+#define AI_STATUS_DMA_BUSY (1 << 30)
+
+// AI DAC sample period register (W): [13:0] dac rate
+// - vid_clock/(dperiod + 1) is the DAC sample rate
+// - (dperiod + 1) >= 66 * (aclockhp + 1) must be true
+#define AI_DACRATE_REG (AI_BASE_REG + 0x10)
+
+// DAC rate = video clock / audio frequency
+// - DAC rate >= (66 * Bit rate) must be true
+#define AI_MAX_DAC_RATE 16384 // 14-bit+1
+#define AI_MIN_DAC_RATE 132
+
+// AI bit rate (W): [3:0] bit rate (abus clock half period register - aclockhp)
+// - vid_clock/(2 * (aclockhp + 1)) is the DAC clock rate
+// - The abus clock stops if aclockhp is zero
+#define AI_BITRATE_REG (AI_BASE_REG + 0x14)
+
+// Bit rate <= (DAC rate / 66)
+#define AI_MAX_BIT_RATE 16 // 4-bit+1
+#define AI_MIN_BIT_RATE 2
+
+/*
+ * Maximum and minimum values for audio frequency based on video clocks
+ * max frequency = (video clock / min dac rate)
+ * min frequency = (video clock / max dac rate)
+ */
+#define AI_NTSC_MAX_FREQ 368000 // 368 KHz
+#define AI_NTSC_MIN_FREQ 3000 // 3 KHz ~ 2971 Hz
+
+#define AI_PAL_MAX_FREQ 376000 // 376 KHz
+#define AI_PAL_MIN_FREQ 3050 // 3 KHz ~ 3031 Hz
+
+#define AI_MPAL_MAX_FREQ 368000 // 368 KHz
+#define AI_MPAL_MIN_FREQ 3000 // 3 KHz ~ 2968 Hz
+
+
+/**
+ * Peripheral Interface (PI) Registers
+ */
+#define PI_BASE_REG 0x04600000
+
+// PI DRAM address (R/W): [23:0] starting RDRAM address
+#define PI_DRAM_ADDR_REG (PI_BASE_REG + 0x00)
+
+// PI pbus (cartridge) address (R/W): [31:0] starting AD16 address
+#define PI_CART_ADDR_REG (PI_BASE_REG + 0x04)
+
+// PI read length (R/W): [23:0] read data length
+#define PI_RD_LEN_REG (PI_BASE_REG + 0x08)
+
+// PI write length (R/W): [23:0] write data length
+#define PI_WR_LEN_REG (PI_BASE_REG + 0x0C)
+
+// PI status (R): [3] interrupt flag, [2] error, [1] IO busy, [0] DMA busy
+// (W): [1] clear intr, [0] reset controller (and abort current op)
+#define PI_STATUS_REG (PI_BASE_REG + 0x10)
+
+// PI dom1 latency (R/W): [7:0] domain 1 device latency
+#define PI_BSD_DOM1_LAT_REG (PI_BASE_REG + 0x14)
+
+// PI dom1 pulse width (R/W): [7:0] domain 1 device R/W strobe pulse width
+#define PI_BSD_DOM1_PWD_REG (PI_BASE_REG + 0x18)
+
+// PI dom1 page size (R/W): [3:0] domain 1 device page size
+#define PI_BSD_DOM1_PGS_REG (PI_BASE_REG + 0x1C)
+
+// PI dom1 release (R/W): [1:0] domain 1 device R/W release duration
+#define PI_BSD_DOM1_RLS_REG (PI_BASE_REG + 0x20)
+
+// PI dom2 latency (R/W): [7:0] domain 2 device latency
+#define PI_BSD_DOM2_LAT_REG (PI_BASE_REG + 0x24)
+
+// PI dom2 pulse width (R/W): [7:0] domain 2 device R/W strobe pulse width
+#define PI_BSD_DOM2_PWD_REG (PI_BASE_REG + 0x28)
+
+// PI dom2 page size (R/W): [3:0] domain 2 device page size
+#define PI_BSD_DOM2_PGS_REG (PI_BASE_REG + 0x2C)
+
+// PI dom2 release (R/W): [1:0] domain 2 device R/W release duration
+#define PI_BSD_DOM2_RLS_REG (PI_BASE_REG + 0x30)
+
+#define PI_DOMAIN1_REG PI_BSD_DOM1_LAT_REG
+#define PI_DOMAIN2_REG PI_BSD_DOM2_LAT_REG
+
+#define PI_DOM_LAT_OFS 0x00
+#define PI_DOM_PWD_OFS 0x04
+#define PI_DOM_PGS_OFS 0x08
+#define PI_DOM_RLS_OFS 0x0C
+
+/*
+ * PI_STATUS_REG: read bits
+ * Bit 0: DMA busy - set when DMA is in progress
+ * Bit 1: IO busy - set when IO is in progress
+ * Bit 2: Error - set when CPU issues IO request while DMA is busy
+ */
+#define PI_STATUS_DMA_BUSY (1 << 0)
+#define PI_STATUS_IO_BUSY (1 << 1)
+#define PI_STATUS_ERROR (1 << 2)
+
+/*
+ * PI status register has 2 bits active when written to:
+ * Bit 0: When set, reset PIC
+ * Bit 1: When set, clear interrupt flag
+ * The values of the two bits can be ORed together to both reset PIC and
+ * clear interrupt at the same time.
+ *
+ * Note:
+ * - The PIC does generate an interrupt at the end of each DMA. CPU
+ * needs to clear the interrupt flag explicitly (from an interrupt
+ * handler) by writing into the STATUS register with bit 1 set.
+ *
+ * - When a DMA completes, the interrupt flag is set. CPU can issue
+ * another request even while the interrupt flag is set (as long as
+ * PIC is idle). However, it is the CPU's responsibility for
+ * maintaining accurate correspondence between DMA completions and
+ * interrupts.
+ *
+ * - When PIC is reset, if PIC happens to be busy, an interrupt will
+ * be generated as PIC returns to idle. Otherwise, no interrupt will
+ * be generated and PIC remains idle.
+ */
+
+/*
+ * PI_STATUS_REG: write bits
+ */
+#define PI_STATUS_RESET (1 << 0)
+#define PI_SET_RESET PI_STATUS_RESET
+
+#define PI_STATUS_CLR_INTR (1 << 1)
+#define PI_CLR_INTR PI_STATUS_CLR_INTR
+
+#define PI_DMA_BUFFER_SIZE 128
+
+#define PI_DOM1_ADDR1 0x06000000 /* to 0x07FFFFFF */
+#define PI_DOM1_ADDR2 0x10000000 /* to 0x1FBFFFFF */
+#define PI_DOM1_ADDR3 0x1FD00000 /* to 0x7FFFFFFF */
+#define PI_DOM2_ADDR1 0x05000000 /* to 0x05FFFFFF */
+#define PI_DOM2_ADDR2 0x08000000 /* to 0x0FFFFFFF */
+
+
+/**
+ * RDRAM Interface (RI) Registers
+ */
+#define RI_BASE_REG 0x04700000
+
+// RI mode (R/W): [3] stop R active, [2] stop T active, [1:0] operating mode
+#define RI_MODE_REG (RI_BASE_REG + 0x00)
+
+// RI config (R/W): [6] current control enable, [5:0] current control input
+#define RI_CONFIG_REG (RI_BASE_REG + 0x04)
+
+// RI current load (W): [] any write updates current control register
+#define RI_CURRENT_LOAD_REG (RI_BASE_REG + 0x08)
+
+// RI select (R/W): [3:2] receive select, [1:0] transmit select
+#define RI_SELECT_REG (RI_BASE_REG + 0x0C)
+
+// RI refresh (R/W): [16] refresh bank, [17] refresh enable, [18] refresh optimize
+// [7:0] clean refresh delay, [15:8] dirty refresh dela
+#define RI_REFRESH_REG (RI_BASE_REG + 0x10)
+#define RI_COUNT_REG RI_REFRESH_REG
+
+// RI latency (R/W): [3:0] DMA latency/overlap
+#define RI_LATENCY_REG (RI_BASE_REG + 0x14)
+
+// RI error (R): [1] ack error, [0] nack error
+#define RI_RERROR_REG (RI_BASE_REG + 0x18)
+
+// RI error (W): [] any write clears all error bits
+#define RI_WERROR_REG (RI_BASE_REG + 0x1C)
+
+
+/**
+ * Serial Interface (SI) Registers
+ */
+#define SI_BASE_REG 0x04800000
+
+// SI DRAM address (R/W): [23:0] starting RDRAM address
+#define SI_DRAM_ADDR_REG (SI_BASE_REG + 0x00)
+
+// SI address read 64B (W): [] write begins a 64B DMA write PIF RAM -> RDRAM
+#define SI_PIF_ADDR_RD64B_REG (SI_BASE_REG + 0x04)
+
+// Address SI_BASE_REG + (0x08, 0x0C, 0x14) are reserved
+
+// SI address write 64B (W): [] write begins a 64B DMA read RDRAM -> PIF RAM */
+#define SI_PIF_ADDR_WR64B_REG (SI_BASE_REG + 0x10)
+
+// SI status (R/W): [] any write clears interrupt
+#define SI_STATUS_REG (SI_BASE_REG + 0x18)
+
+/*
+ * SI_STATUS_REG: read bits
+ */
+#define SI_STATUS_DMA_BUSY (1 << 0) // DMA in progress
+#define SI_STATUS_RD_BUSY (1 << 1) // IO access in progress
+#define SI_STATUS_DMA_ERROR (1 << 3) // Overlapping DMA requests
+#define SI_STATUS_INTERRUPT (1 << 12) // Interrupt is set
+
+
+/**
+ * Development Board GIO Control Registers
+ */
+
+#define GIO_BASE_REG 0x18000000
+
+// Game to Host Interrupt
+#define GIO_GIO_INTR_REG (GIO_BASE_REG+0x000)
+
+// Game to Host SYNC
+#define GIO_GIO_SYNC_REG (GIO_BASE_REG+0x400)
+
+// Host to Game Interrupt
+#define GIO_CART_INTR_REG (GIO_BASE_REG+0x800)
+
+
+/**
+ * Common macros
+ */
+#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
+
+#define IO_READ(addr) (*(vu32*)PHYS_TO_K1(addr))
+#define IO_WRITE(addr,data) (*(vu32*)PHYS_TO_K1(addr)=(u32)(data))
+
+#define RCP_STAT_PRINT \
+ rmonPrintf("current=%x start=%x end=%x dpstat=%x spstat=%x\n", \
+ IO_READ(DPC_CURRENT_REG), \
+ IO_READ(DPC_START_REG), \
+ IO_READ(DPC_END_REG), \
+ IO_READ(DPC_STATUS_REG), \
+ IO_READ(SP_STATUS_REG))
+
+#endif
#endif
diff --git a/include/ultra64/rdb.h b/include/ultra64/rdb.h
index 31442b587c..0493b82b99 100644
--- a/include/ultra64/rdb.h
+++ b/include/ultra64/rdb.h
@@ -68,7 +68,7 @@
#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
-#include "types.h"
+#include "ultratypes.h"
/* Structure for debug port */
typedef struct {
diff --git a/include/ultra64/rdp.h b/include/ultra64/rdp.h
deleted file mode 100644
index 8729a3fa85..0000000000
--- a/include/ultra64/rdp.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#ifndef ULTRA64_RDP_H
-#define ULTRA64_RDP_H
-
-/* DP Command Registers */
-
-#define DPC_REG_BASE 0xA4100000
-
-#define DPC_START_REG (*(vu32*)(DPC_REG_BASE + 0x00))
-#define DPC_END_REG (*(vu32*)(DPC_REG_BASE + 0x04))
-#define DPC_CURRENT_REG (*(vu32*)(DPC_REG_BASE + 0x08))
-#define DPC_STATUS_REG (*(vu32*)(DPC_REG_BASE + 0x0C))
-#define DPC_CLOCK_REG (*(vu32*)(DPC_REG_BASE + 0x10))
-#define DPC_BUFBUSY_REG (*(vu32*)(DPC_REG_BASE + 0x14))
-#define DPC_PIPEBUSY_REG (*(vu32*)(DPC_REG_BASE + 0x18))
-#define DPC_TMEM_REG (*(vu32*)(DPC_REG_BASE + 0x1C))
-
-/* DP Span Registers */
-
-#define DPS_REG_BASE 0xA4200000
-
-#define DPS_TBIST_REG (*(vu32*)(DPS_REG_BASE + 0x00))
-#define DPS_TEST_MODE_REG (*(vu32*)(DPS_REG_BASE + 0x04))
-#define DPS_BUFTEST_ADDR_REG (*(vu32*)(DPS_REG_BASE + 0x08))
-#define DPS_BUFTEST_DATA_REG (*(vu32*)(DPS_REG_BASE + 0x0C))
-
-/* DP Status Read Flags */
-#define DPC_STATUS_XBUS_DMEM_DMA 0x001
-#define DPC_STATUS_FREEZE 0x002
-#define DPC_STATUS_FLUSH 0x004
-#define DPC_STATUS_START_GCLK 0x008
-#define DPC_STATUS_TMEM_BUSY 0x010
-#define DPC_STATUS_PIPE_BUSY 0x020
-#define DPC_STATUS_CMD_BUSY 0x040
-#define DPC_STATUS_CBUF_READY 0x080
-#define DPC_STATUS_DMA_BUSY 0x100
-#define DPC_STATUS_END_VALID 0x200
-#define DPC_STATUS_START_VALID 0x400
-
-/* DP Status Write Flags */
-#define DPC_CLR_XBUS_DMEM_DMA 0x0001
-#define DPC_SET_XBUS_DMEM_DMA 0x0002
-#define DPC_CLR_FREEZE 0x0004
-#define DPC_SET_FREEZE 0x0008
-#define DPC_CLR_FLUSH 0x0010
-#define DPC_SET_FLUSH 0x0020
-#define DPC_CLR_TMEM_CTR 0x0040
-#define DPC_CLR_PIPE_CTR 0x0080
-#define DPC_CLR_CMD_CTR 0x0100
-#define DPC_CLR_CLOCK_CTR 0x0200
-
-#endif
diff --git a/include/ultra64/rsp.h b/include/ultra64/rsp.h
deleted file mode 100644
index dcc9dadc74..0000000000
--- a/include/ultra64/rsp.h
+++ /dev/null
@@ -1,50 +0,0 @@
-#ifndef ULTRA64_RSP_H
-#define ULTRA64_RSP_H
-
-/* SP Status Flags */
-#define SP_STATUS_HALT 0x001
-#define SP_STATUS_BROKE 0x002
-#define SP_STATUS_DMA_BUSY 0x004
-#define SP_STATUS_DMA_FULL 0x008
-#define SP_STATUS_IO_FULL 0x010
-#define SP_STATUS_SSTEP 0x020
-#define SP_STATUS_INTR_BREAK 0x040
-#define SP_STATUS_YIELD 0x080
-#define SP_STATUS_YIELDED 0x100
-#define SP_STATUS_TASKDONE 0x200
-//#define SP_STATUS_SIG0 0x080
-//#define SP_STATUS_SIG1 0x100
-//#define SP_STATUS_SIG2 0x200
-#define SP_STATUS_SIG3 0x400
-#define SP_STATUS_SIG4 0x800
-#define SP_STATUS_SIG5 0x1000
-#define SP_STATUS_SIG6 0x2000
-#define SP_STATUS_SIG7 0x4000
-
-#define SP_CLR_HALT 0x00001
-#define SP_SET_HALT 0x00002
-#define SP_CLR_BROKE 0x00004
-#define SP_CLR_INTR 0x00008
-#define SP_SET_INTR 0x00010
-#define SP_CLR_SSTEP 0x00020
-#define SP_SET_SSTEP 0x00040
-#define SP_CLR_INTR_BREAK 0x00080
-#define SP_SET_INTR_BREAK 0x00100
-#define SP_CLR_SIG0 0x00200
-#define SP_SET_SIG0 0x00400
-#define SP_CLR_SIG1 0x00800
-#define SP_SET_SIG1 0x01000
-#define SP_CLR_SIG2 0x02000
-#define SP_SET_SIG2 0x04000
-#define SP_CLR_SIG3 0x08000
-#define SP_SET_SIG3 0x10000
-#define SP_CLR_SIG4 0x20000
-#define SP_SET_SIG4 0x40000
-#define SP_CLR_SIG5 0x80000
-#define SP_SET_SIG5 0x100000
-#define SP_CLR_SIG6 0x200000
-#define SP_SET_SIG6 0x400000
-#define SP_CLR_SIG7 0x800000
-#define SP_SET_SIG7 0x1000000
-
-#endif
diff --git a/include/ultra64/sptask.h b/include/ultra64/sptask.h
index 06b4f77097..ea00dbfdf5 100644
--- a/include/ultra64/sptask.h
+++ b/include/ultra64/sptask.h
@@ -1,7 +1,7 @@
#ifndef ULTRA64_SPTASK_H
#define ULTRA64_SPTASK_H
-#include "types.h"
+#include "ultratypes.h"
/* Task Types */
#define M_NULTASK 0
diff --git a/include/ultra64/thread.h b/include/ultra64/thread.h
index 5adb689dd9..474a63641a 100644
--- a/include/ultra64/thread.h
+++ b/include/ultra64/thread.h
@@ -22,7 +22,7 @@
#ifdef _LANGUAGE_C
-#include "types.h"
+#include "ultratypes.h"
typedef s32 OSPri;
typedef s32 OSId;
diff --git a/include/ultra64/ucode.h b/include/ultra64/ucode.h
index a525b24839..00ef36ac2b 100644
--- a/include/ultra64/ucode.h
+++ b/include/ultra64/ucode.h
@@ -1,7 +1,7 @@
#ifndef ULTRA64_UCODE_H
#define ULTRA64_UCODE_H
-#include "types.h"
+#include "ultratypes.h"
#define SP_DRAM_STACK_SIZE8 (0x400)
#define SP_DRAM_STACK_SIZE64 (SP_DRAM_STACK_SIZE8 >> 3)
diff --git a/include/ultra64/types.h b/include/ultra64/ultratypes.h
similarity index 91%
rename from include/ultra64/types.h
rename to include/ultra64/ultratypes.h
index 84ee3cc6cb..e4a3053702 100644
--- a/include/ultra64/types.h
+++ b/include/ultra64/ultratypes.h
@@ -1,5 +1,7 @@
-#ifndef ULTRA64_TYPES_H
-#define ULTRA64_TYPES_H
+#ifndef ULTRA64_ULTRATYPES_H
+#define ULTRA64_ULTRATYPES_H
+
+#ifdef _LANGUAGE_C
typedef signed char s8;
typedef unsigned char u8;
@@ -37,3 +39,5 @@ typedef union {
} MtxF;
#endif
+
+#endif
diff --git a/include/ultra64/vi.h b/include/ultra64/vi.h
index c0a81f836f..5125461123 100644
--- a/include/ultra64/vi.h
+++ b/include/ultra64/vi.h
@@ -13,18 +13,6 @@
#define OS_VI_DITHER_FILTER_ON 0x0040
#define OS_VI_DITHER_FILTER_OFF 0x0080
-#define OS_VI_GAMMA 0x08
-#define OS_VI_GAMMA_DITHER 0x04
-#define OS_VI_DIVOT 0x10
-#define OS_VI_DITHER_FILTER 0x10000
-#define OS_VI_UNK1 0x1
-#define OS_VI_UNK2 0x2
-#define OS_VI_UNK40 0x40
-#define OS_VI_UNK100 0x100
-#define OS_VI_UNK200 0x200
-#define OS_VI_UNK1000 0x1000
-#define OS_VI_UNK2000 0x2000
-
typedef struct {
/* 0x00 */ u32 ctrl;
/* 0x04 */ u32 width;
@@ -60,7 +48,7 @@ typedef struct {
typedef struct {
/* 0x00 */ u16 state;
/* 0x02 */ u16 retraceCount;
- /* 0x04 */ void* buffer;
+ /* 0x04 */ void* framep;
/* 0x08 */ OSViMode* modep;
/* 0x0C */ u32 features;
/* 0x10 */ OSMesgQueue* mq;
@@ -132,6 +120,5 @@ typedef struct {
#define OS_TV_PAL 0
#define OS_TV_NTSC 1
#define OS_TV_MPAL 2
-#define OS_VI_UNK28 28
#endif
diff --git a/include/ultra64/viint.h b/include/ultra64/viint.h
new file mode 100644
index 0000000000..4fea2259a2
--- /dev/null
+++ b/include/ultra64/viint.h
@@ -0,0 +1,37 @@
+#ifndef ULTRA64_VIINT_H
+#define ULTRA64_VIINT_H
+
+#define VI_STATE_MODE_SET (1 << 0)
+#define VI_STATE_XSCALE_SET (1 << 1)
+#define VI_STATE_YSCALE_FACTOR_SET (1 << 2)
+#define VI_STATE_CTRL_SET (1 << 3)
+#define VI_STATE_BUFFER_SET (1 << 4)
+#define VI_STATE_BLACK (1 << 5)
+#define VI_STATE_REPEATLINE (1 << 6)
+#define VI_STATE_FADE (1 << 7)
+
+#define VI_SCALE_MASK 0xFFF
+#define VI_2_10_FPART_MASK 0x3FF
+#define VI_SUBPIXEL_SH 0x10
+
+// For use in initializing OSViMode structures
+
+#define BURST(hsync_width, color_width, vsync_width, color_start) \
+ (hsync_width | (color_width << 8) | (vsync_width << 16) | (color_start << 20))
+#define WIDTH(v) v
+#define VSYNC(v) v
+#define HSYNC(duration, leap) (duration | (leap << 16))
+#define LEAP(upper, lower) ((upper << 16) | lower)
+#define START(start, end) ((start << 16) | end)
+
+#define FTOFIX(val, i, f) ((u32)(val * (f32)(1 << f)) & ((1 << (i + f)) - 1))
+
+#define F210(val) FTOFIX(val, 2, 10)
+#define SCALE(scaleup, off) (F210((1.0f / (f32)scaleup)) | (F210((f32)off) << 16))
+
+#define VCURRENT(v) v
+#define ORIGIN(v) v
+#define VINTR(v) v
+#define HSTART START
+
+#endif
diff --git a/include/variables.h b/include/variables.h
index 32a5955f40..44f7a27250 100644
--- a/include/variables.h
+++ b/include/variables.h
@@ -45,7 +45,7 @@ extern u8 gBuildDate[];
extern u8 gBuildMakeOption[];
extern OSMesgQueue gPiMgrCmdQueue;
extern OSViMode gViConfigMode;
-extern u8 D_80013960;
+extern u8 gViConfigModeType;
extern OSMesgQueue __osPiAccessQueue;
extern OSPiHandle __Dom1SpeedParam;
extern OSPiHandle __Dom2SpeedParam;
diff --git a/include/z64.h b/include/z64.h
index 13bff7b679..fb260dfc49 100644
--- a/include/z64.h
+++ b/include/z64.h
@@ -38,6 +38,8 @@
#include "fault.h"
#include "sched.h"
#include "rumble.h"
+#include "tha.h"
+#include "thga.h"
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 240
@@ -106,20 +108,6 @@ typedef struct {
/* 0x12408 */ u16 tailMagic; // GFXPOOL_TAIL_MAGIC
} GfxPool; // size = 0x12410
-typedef struct {
- /* 0x0000 */ u32 size;
- /* 0x0004 */ void* bufp;
- /* 0x0008 */ void* head;
- /* 0x000C */ void* tail;
-} TwoHeadArena; // size = 0x10
-
-typedef struct {
- /* 0x0000 */ u32 size;
- /* 0x0004 */ Gfx* bufp;
- /* 0x0008 */ Gfx* p;
- /* 0x000C */ Gfx* d;
-} TwoHeadGfxArena; // size = 0x10
-
typedef struct GraphicsContext {
/* 0x0000 */ Gfx* polyOpaBuffer; // Pointer to "Zelda 0"
/* 0x0004 */ Gfx* polyXluBuffer; // Pointer to "Zelda 1"
@@ -1727,20 +1715,27 @@ typedef struct {
/* 0x10 */ s16 unk_10;
} JpegDecoderState; // size = 0x14
+typedef enum {
+ /* 0 */ VI_MODE_EDIT_STATE_INACTIVE,
+ /* 1 */ VI_MODE_EDIT_STATE_ACTIVE,
+ /* 2 */ VI_MODE_EDIT_STATE_2, // active, more adjustments
+ /* 3 */ VI_MODE_EDIT_STATE_3 // active, more adjustments, print comparison with NTSC LAN1 mode
+} ViModeEditState;
+
typedef struct {
/* 0x0000 */ OSViMode customViMode;
/* 0x0050 */ s32 viHeight;
/* 0x0054 */ s32 viWidth;
- /* 0x0058 */ s32 unk_58; // Right adjustment?
- /* 0x005C */ s32 unk_5C; // Left adjustment?
- /* 0x0060 */ s32 unk_60; // Bottom adjustment?
- /* 0x0064 */ s32 unk_64; // Top adjustment?
- /* 0x0068 */ s32 viModeBase; // enum: {0, 1, 2, 3}
- /* 0x006C */ s32 viTvType;
- /* 0x0070 */ u32 unk_70; // bool
- /* 0x0074 */ u32 unk_74; // bool
- /* 0x0078 */ u32 unk_78; // bool
- /* 0x007C */ u32 unk_7C; // bool
+ /* 0x0058 */ s32 rightAdjust;
+ /* 0x005C */ s32 leftAdjust;
+ /* 0x0060 */ s32 lowerAdjust;
+ /* 0x0064 */ s32 upperAdjust;
+ /* 0x0068 */ s32 editState;
+ /* 0x006C */ s32 tvType;
+ /* 0x0070 */ u32 loRes;
+ /* 0x0074 */ u32 antialiasOff;
+ /* 0x0078 */ u32 modeN; // Controls interlacing, the meaning of this mode is different based on choice of resolution
+ /* 0x007C */ u32 fb16Bit;
/* 0x0080 */ u32 viFeatures;
/* 0x0084 */ u32 unk_84;
} ViMode;
diff --git a/include/z64collision_check.h b/include/z64collision_check.h
index 1868b19156..0607987832 100644
--- a/include/z64collision_check.h
+++ b/include/z64collision_check.h
@@ -14,16 +14,16 @@ struct Actor;
*/
typedef enum {
- /* 0 */ COLTYPE_HIT0, // Blue blood, white hitmark
- /* 1 */ COLTYPE_HIT1, // No blood, dust hitmark
- /* 2 */ COLTYPE_HIT2, // Green blood, dust hitmark
- /* 3 */ COLTYPE_HIT3, // No blood, white hitmark
- /* 4 */ COLTYPE_HIT4, // Water burst, no hitmark
- /* 5 */ COLTYPE_HIT5, // No blood, red hitmark
- /* 6 */ COLTYPE_HIT6, // Green blood, white hitmark
- /* 7 */ COLTYPE_HIT7, // Red blood, white hitmark
- /* 8 */ COLTYPE_HIT8, // Blue blood, red hitmark
- /* 9 */ COLTYPE_METAL,
+ /* 0 */ COLTYPE_HIT0, // Blue blood, white hitmark
+ /* 1 */ COLTYPE_HIT1, // No blood, dust hitmark
+ /* 2 */ COLTYPE_HIT2, // Green blood, dust hitmark
+ /* 3 */ COLTYPE_HIT3, // No blood, white hitmark
+ /* 4 */ COLTYPE_HIT4, // Water burst, no hitmark
+ /* 5 */ COLTYPE_HIT5, // No blood, red hitmark
+ /* 6 */ COLTYPE_HIT6, // Green blood, white hitmark
+ /* 7 */ COLTYPE_HIT7, // Red blood, white hitmark
+ /* 8 */ COLTYPE_HIT8, // Blue blood, red hitmark
+ /* 9 */ COLTYPE_METAL,
/* 10 */ COLTYPE_NONE,
/* 11 */ COLTYPE_WOOD,
/* 12 */ COLTYPE_HARD,
diff --git a/include/z64curve.h b/include/z64curve.h
index a526effcb8..1864f2116e 100644
--- a/include/z64curve.h
+++ b/include/z64curve.h
@@ -1,7 +1,7 @@
#ifndef Z64_CURVE_H
#define Z64_CURVE_H
-#include "ultra64/types.h"
+#include "ultra64/ultratypes.h"
#include "z64math.h"
struct PlayState;
diff --git a/include/z64environment.h b/include/z64environment.h
index 1aa5d7490e..af77159e4c 100644
--- a/include/z64environment.h
+++ b/include/z64environment.h
@@ -95,16 +95,16 @@ typedef enum {
} StormState;
typedef enum {
- /* 0x00 */ TIMESEQ_DAY_BGM,
- /* 0x01 */ TIMESEQ_FADE_DAY_BGM,
- /* 0x02 */ TIMESEQ_NIGHT_BEGIN_SFX,
- /* 0x03 */ TIMESEQ_EARLY_NIGHT_CRITTERS,
- /* 0x04 */ TIMESEQ_NIGHT_DELAY,
- /* 0x05 */ TIMESEQ_NIGHT_CRITTERS,
- /* 0x06 */ TIMESEQ_DAY_BEGIN_SFX,
- /* 0x07 */ TIMESEQ_MORNING_CRITTERS,
- /* 0x08 */ TIMESEQ_DAY_DELAY,
- /* 0xFF */ TIMESEQ_DISABLED = 0xFF
+ /* 0x00 */ TIMESEQ_DAY_BGM,
+ /* 0x01 */ TIMESEQ_FADE_DAY_BGM,
+ /* 0x02 */ TIMESEQ_NIGHT_BEGIN_SFX,
+ /* 0x03 */ TIMESEQ_EARLY_NIGHT_CRITTERS,
+ /* 0x04 */ TIMESEQ_NIGHT_DELAY,
+ /* 0x05 */ TIMESEQ_NIGHT_CRITTERS,
+ /* 0x06 */ TIMESEQ_DAY_BEGIN_SFX,
+ /* 0x07 */ TIMESEQ_MORNING_CRITTERS,
+ /* 0x08 */ TIMESEQ_DAY_DELAY,
+ /* 0xFF */ TIMESEQ_DISABLED = 0xFF
} TimeBasedSeqState;
typedef enum {
diff --git a/include/z64math.h b/include/z64math.h
index 083fedb96b..b4a128dfb3 100644
--- a/include/z64math.h
+++ b/include/z64math.h
@@ -111,9 +111,9 @@ typedef VecSphGeo VecGeo;
#define BINANG_TO_RAD_ALT2(binang) (((f32)(binang) * M_PI) / 0x8000)
// Vector macros
-#define SQXZ(vec) ((vec.x) * (vec.x) + (vec.z) * (vec.z))
-#define DOTXZ(vec1, vec2) ((vec1.x) * (vec2.x) + (vec1.z) * (vec2.z))
-#define SQXYZ(vec) ((vec.x) * (vec.x) + (vec.y) * (vec.y) + (vec.z) * (vec.z))
-#define DOTXYZ(vec1, vec2) ((vec1.x) * (vec2.x) + (vec1.y) * (vec2.y) + (vec1.z) * (vec2.z))
+#define SQXZ(vec) ((vec).x * (vec).x + (vec).z * (vec).z)
+#define DOTXZ(vec1, vec2) ((vec1).x * (vec2).x + (vec1).z * (vec2).z)
+#define SQXYZ(vec) ((vec).x * (vec).x + (vec).y * (vec).y + (vec).z * (vec).z)
+#define DOTXYZ(vec1, vec2) ((vec1).x * (vec2).x + (vec1).y * (vec2).y + (vec1).z * (vec2).z)
#endif
diff --git a/include/z64ocarina.h b/include/z64ocarina.h
index 7dc1a4b331..1dfb629f27 100644
--- a/include/z64ocarina.h
+++ b/include/z64ocarina.h
@@ -140,9 +140,9 @@ typedef enum {
} OcarinaInstrumentId;
typedef enum {
- /* 0 */ OCARINA_RECORD_OFF,
- /* 1 */ OCARINA_RECORD_SCARECROW_LONG,
- /* 2 */ OCARINA_RECORD_SCARECROW_SPAWN,
+ /* 0 */ OCARINA_RECORD_OFF,
+ /* 1 */ OCARINA_RECORD_SCARECROW_LONG,
+ /* 2 */ OCARINA_RECORD_SCARECROW_SPAWN,
/* 0xFF */ OCARINA_RECORD_REJECTED = 0xFF
} OcarinaRecordingState;
diff --git a/spec b/spec
index 4fdacf2b8e..a8a6dbb534 100644
--- a/spec
+++ b/spec
@@ -30,7 +30,7 @@ beginseg
include "build/src/libultra/io/piacs.o"
include "build/src/libultra/os/sendmesg.o"
include "build/src/libultra/os/stopthread.o"
- include "build/src/libultra/io/viextend.o"
+ include "build/src/libultra/io/viextendvstart.o"
include "build/src/libultra/io/vimodepallan1.o"
include "build/src/libultra/os/recvmesg.o"
include "build/src/libultra/os/initialize.o"
@@ -385,6 +385,7 @@ beginseg
include "build/src/code/z_kaleido_scope_call.o"
include "build/src/code/z_play.o"
include "build/src/code/PreRender.o"
+ include "build/src/code/TwoHeadGfxArena.o"
include "build/src/code/TwoHeadArena.o"
include "build/src/code/code_800C3C20.o"
include "build/src/code/audioMgr.o"
diff --git a/src/boot/idle.c b/src/boot/idle.c
index f480ce8cb4..99a0276b44 100644
--- a/src/boot/idle.c
+++ b/src/boot/idle.c
@@ -7,7 +7,7 @@ StackEntry sMainStackInfo;
OSMesg sPiMgrCmdBuff[50];
OSMesgQueue gPiMgrCmdQueue;
OSViMode gViConfigMode;
-u8 D_80013960;
+u8 gViConfigModeType;
s8 D_80009430 = 1;
vu8 gViConfigBlack = true;
@@ -58,17 +58,17 @@ void Idle_ThreadEntry(void* arg) {
switch (osTvType) {
case OS_TV_NTSC:
- D_80013960 = 2;
+ gViConfigModeType = OS_VI_NTSC_LAN1;
gViConfigMode = osViModeNtscLan1;
break;
case OS_TV_MPAL:
- D_80013960 = 0x1E;
+ gViConfigModeType = OS_VI_MPAL_LAN1;
gViConfigMode = osViModeMpalLan1;
break;
case OS_TV_PAL:
- D_80013960 = 0x2C;
+ gViConfigModeType = OS_VI_FPAL_LAN1;
gViConfigMode = osViModeFpalLan1;
gViConfigYScale = 0.833f;
break;
diff --git a/src/code/TwoHeadArena.c b/src/code/TwoHeadArena.c
index 3340604607..271c2ae7ff 100644
--- a/src/code/TwoHeadArena.c
+++ b/src/code/TwoHeadArena.c
@@ -1,140 +1,135 @@
+/**
+ * @file TwoHeadArena.c
+ *
+ * This file implements a simple general purpose double-ended stack allocator.
+ *
+ * A double-ended stack allocator accepts allocations at either the "head" or "tail" of its allotted memory region.
+ * While in general this type of allocator could accept deallocations on the most recently allocated block at either
+ * end, this implementation does not support any individual deallocations; the only provided way to deallocate anything
+ * is to reset the entire arena, deallocating everything. This scheme is most applicable to allocating similar data
+ * with identical lifetime.
+ */
#include "global.h"
-void THGA_Ct(TwoHeadGfxArena* thga, Gfx* start, u32 size) {
- THA_Ct((TwoHeadArena*)thga, start, size);
-}
-
-void THGA_Dt(TwoHeadGfxArena* thga) {
- THA_Dt((TwoHeadArena*)thga);
-}
-
-u32 THGA_IsCrash(TwoHeadGfxArena* thga) {
- return THA_IsCrash((TwoHeadArena*)thga);
-}
-
-void THGA_Init(TwoHeadGfxArena* thga) {
- THA_Init((TwoHeadArena*)thga);
-}
-
-s32 THGA_GetSize(TwoHeadGfxArena* thga) {
- return THA_GetSize((TwoHeadArena*)thga);
-}
-
-Gfx* THGA_GetHead(TwoHeadGfxArena* thga) {
- return THA_GetHead((TwoHeadArena*)thga);
-}
-
-void THGA_SetHead(TwoHeadGfxArena* thga, Gfx* start) {
- THA_SetHead((TwoHeadArena*)thga, start);
-}
-
-Gfx* THGA_GetTail(TwoHeadGfxArena* thga) {
- return THA_GetTail((TwoHeadArena*)thga);
-}
-
-Gfx* THGA_AllocStartArray8(TwoHeadGfxArena* thga, u32 count) {
- return THA_AllocStart((TwoHeadArena*)thga, count * 8);
-}
-
-Gfx* THGA_AllocStart8(TwoHeadGfxArena* thga) {
- return THGA_AllocStartArray8(thga, 1);
-}
-
-Gfx* THGA_AllocStart8Wrapper(TwoHeadGfxArena* thga) {
- return THGA_AllocStart8(thga);
-}
-
-Gfx* THGA_AllocEnd(TwoHeadGfxArena* thga, u32 size) {
- return THA_AllocEnd((TwoHeadArena*)thga, size);
-}
-
-Gfx* THGA_AllocEndArray64(TwoHeadGfxArena* thga, u32 count) {
- return THGA_AllocEnd(thga, count * 0x40);
-}
-
-Gfx* THGA_AllocEnd64(TwoHeadGfxArena* thga) {
- return THGA_AllocEnd(thga, 0x40);
-}
-
-Gfx* THGA_AllocEndArray16(TwoHeadGfxArena* thga, u32 count) {
- return THGA_AllocEnd(thga, count * 0x10);
-}
-
-Gfx* THGA_AllocEnd16(TwoHeadGfxArena* thga) {
- return THGA_AllocEnd(thga, 0x10);
-}
-
void* THA_GetHead(TwoHeadArena* tha) {
return tha->head;
}
-void THA_SetHead(TwoHeadArena* tha, void* start) {
- tha->head = start;
+void THA_SetHead(TwoHeadArena* tha, void* newHead) {
+ tha->head = newHead;
}
void* THA_GetTail(TwoHeadArena* tha) {
return tha->tail;
}
-void* THA_AllocStart(TwoHeadArena* tha, u32 size) {
+/**
+ * Allocates to the head of the Two Head Arena. The allocation will not have any alignment guarantees.
+ */
+void* THA_AllocHead(TwoHeadArena* tha, size_t size) {
void* start = tha->head;
- tha->head = (void*)((u32)tha->head + size);
+ tha->head = (u8*)tha->head + size;
return start;
}
-void* THA_AllocStart1(TwoHeadArena* tha) {
- return THA_AllocStart(tha, 1);
+void* THA_AllocHeadByte(TwoHeadArena* tha) {
+ return THA_AllocHead(tha, 1);
}
-void* THA_AllocEnd(TwoHeadArena* tha, u32 size) {
- u32 mask;
+/**
+ * Allocates to the tail end of the Two Head Arena. The allocation will be aligned based on the size of the allocation.
+ * All allocations of 16 bytes or more will be aligned to 16-bytes. Otherwise, the alignment will be the largest power
+ * of 2 for which the size is a multiple, in order to accommodate the alignment requirements of any data types that can
+ * fit within the allocation.
+ */
+void* THA_AllocTail(TwoHeadArena* tha, size_t size) {
+ uintptr_t mask;
if (size == 8) {
- mask = ~7;
+ // Align 8 for multiples of 8
+ mask = ALIGN_MASK(8);
} else if (size == 4 || size == 12) {
- mask = ~3;
+ // Align 4 for multiples of 4
+ mask = ALIGN_MASK(4);
} else if (size == 2 || size == 6 || size == 10 || size == 12 || size == 14) {
- mask = ~1;
+ // Align 2 for multiples of 2
+ mask = ALIGN_MASK(2);
+ } else if (size >= 0x10) {
+ // Align 0x10 for allocations greater than 0x10
+ mask = ALIGN_MASK(0x10);
} else {
- mask = (size >= 0x10) ? ~0xF : 0;
+ //! @bug if size is less than 16 and odd the computation below will give NULL. The mask for this case would be
+ //! more sensible as ~0, for no extra alignment
+ mask = 0;
}
- tha->tail = (void*)((((u32)tha->tail & mask) - size) & mask);
+ tha->tail = (void*)((((uintptr_t)tha->tail & mask) - size) & mask);
return tha->tail;
}
-void* THA_AllocEndAlign16(TwoHeadArena* tha, u32 size) {
- u32 mask = ~0xF;
+/**
+ * Allocates to the tail end of the Two Head Arena with guaranteed 16-byte alignment.
+ */
+void* THA_AllocTailAlign16(TwoHeadArena* tha, size_t size) {
+ uintptr_t mask = ALIGN_MASK(0x10);
- tha->tail = (void*)((((u32)tha->tail & mask) - size) & (u32)(u64)mask);
+ tha->tail = (void*)((((uintptr_t)tha->tail & mask) - size) & (uintptr_t)(u64)mask);
return tha->tail;
}
-void* THA_AllocEndAlign(TwoHeadArena* tha, u32 size, u32 mask) {
- tha->tail = (void*)((((u32)tha->tail & mask) - size) & mask);
+/**
+ * Allocates to the tail end of the Two Head Arena using the provided mask to align the allocated region.
+ *
+ * @param tha Arena to allocate to
+ * @param size Size of the allocation
+ * @param mask Mask to use to align the allocated region. To align to n-bytes where n is a power of 2, use the
+ * ALIGN_MASK(n) macro
+ *
+ * @return Pointer to the start of the allocated block
+ */
+void* THA_AllocTailAlign(TwoHeadArena* tha, size_t size, uintptr_t mask) {
+ tha->tail = (void*)((((uintptr_t)tha->tail & mask) - size) & mask);
return tha->tail;
}
-s32 THA_GetSize(TwoHeadArena* tha) {
- return (u32)tha->tail - (u32)tha->head;
+/**
+ * Gets the remaining size of the Two Head Arena
+ *
+ * @return Remaining size. A negative number indicates an overflow.
+ */
+s32 THA_GetRemaining(TwoHeadArena* tha) {
+ return (s32)((u8*)tha->tail - (u8*)tha->head);
}
+/**
+ * @return true if the Two Head Arena has overflowed, false otherwise
+ */
u32 THA_IsCrash(TwoHeadArena* tha) {
- return THA_GetSize(tha) < 0;
+ return THA_GetRemaining(tha) < 0;
}
-void THA_Init(TwoHeadArena* tha) {
- tha->head = tha->bufp;
- tha->tail = (void*)((u32)tha->bufp + tha->size);
+/**
+ * Resets the head and tail positions of the Two Head Arena, all prior allocations are effectively considered free
+ * as any new allocations will begin to overwrite them.
+ */
+void THA_Reset(TwoHeadArena* tha) {
+ tha->head = tha->start;
+ tha->tail = (u8*)tha->start + tha->size;
}
-void THA_Ct(TwoHeadArena* tha, void* ptr, u32 size) {
- tha->bufp = ptr;
+/**
+ * Creates a new Two Head Arena at `start` with available size `size`
+ */
+void THA_Init(TwoHeadArena* tha, void* start, size_t size) {
+ tha->start = start;
tha->size = size;
- THA_Init(tha);
+ THA_Reset(tha);
}
-void THA_Dt(TwoHeadArena* tha) {
+/**
+ * Destroys the Two Head Arena, no further allocations are possible
+ */
+void THA_Destroy(TwoHeadArena* tha) {
bzero(tha, sizeof(TwoHeadArena));
}
diff --git a/src/code/TwoHeadGfxArena.c b/src/code/TwoHeadGfxArena.c
new file mode 100644
index 0000000000..ce7b8a45fb
--- /dev/null
+++ b/src/code/TwoHeadGfxArena.c
@@ -0,0 +1,102 @@
+/**
+ * @file TwoHeadGfxArena.c
+ *
+ * This file implements a particular use of the double-ended stack allocator from TwoHeadArena.c for graphics data.
+ *
+ * Display list commands are allocated from the head while other graphics data such as matrices and vertices are
+ * allocated from the tail end.
+ *
+ * @see TwoHeadArena.c
+ */
+#include "global.h"
+
+void THGA_Init(TwoHeadGfxArena* thga, void* start, size_t size) {
+ THA_Init(&thga->tha, start, size);
+}
+
+void THGA_Destroy(TwoHeadGfxArena* thga) {
+ THA_Destroy(&thga->tha);
+}
+
+u32 THGA_IsCrash(TwoHeadGfxArena* thga) {
+ return THA_IsCrash(&thga->tha);
+}
+
+void THGA_Reset(TwoHeadGfxArena* thga) {
+ THA_Reset(&thga->tha);
+}
+
+s32 THGA_GetRemaining(TwoHeadGfxArena* thga) {
+ return THA_GetRemaining(&thga->tha);
+}
+
+Gfx* THGA_GetHead(TwoHeadGfxArena* thga) {
+ return THA_GetHead(&thga->tha);
+}
+
+void THGA_SetHead(TwoHeadGfxArena* thga, Gfx* newHead) {
+ THA_SetHead(&thga->tha, newHead);
+}
+
+void* THGA_GetTail(TwoHeadGfxArena* thga) {
+ return THA_GetTail(&thga->tha);
+}
+
+/**
+ * Allocates a display list of `num` Gfx commands to the head of the Two Head Gfx Arena.
+ */
+Gfx* THGA_AllocDisplayList(TwoHeadGfxArena* thga, size_t num) {
+ return THA_AllocHead(&thga->tha, num * sizeof(Gfx));
+}
+
+/**
+ * Allocates a single Gfx command to the head of the Two Head Gfx Arena.
+ */
+Gfx* THGA_AllocGfx(TwoHeadGfxArena* thga) {
+ return THGA_AllocDisplayList(thga, 1);
+}
+
+/**
+ * Identical to `THGA_AllocGfx`
+ *
+ * @see THGA_AllocGfx
+ */
+Gfx* THGA_AllocGfx2(TwoHeadGfxArena* thga) {
+ return THGA_AllocGfx(thga);
+}
+
+/**
+ * Allocates to the end of the Two Head Gfx Arena. Intended for data complementary to the display lists such as
+ * matrices and vertices that are only needed for a single graphics task.
+ */
+void* THGA_AllocTail(TwoHeadGfxArena* thga, size_t size) {
+ return THA_AllocTail(&thga->tha, size);
+}
+
+/**
+ * Allocates `num` matrices to the tail end of the Two Head Gfx Arena.
+ */
+Mtx* THGA_AllocMtxArray(TwoHeadGfxArena* thga, size_t num) {
+ return THGA_AllocTail(thga, num * sizeof(Mtx));
+}
+
+/**
+ * Allocates a matrix to the tail end of the Two Head Gfx Arena.
+ */
+Mtx* THGA_AllocMtx(TwoHeadGfxArena* thga) {
+ return THGA_AllocTail(thga, sizeof(Mtx));
+}
+
+/**
+ * Allocates `num` vertices to the tail end of the Two Head Gfx Arena.
+ */
+Vtx* THGA_AllocVtxArray(TwoHeadGfxArena* thga, size_t num) {
+ return THGA_AllocTail(thga, num * sizeof(Vtx));
+}
+
+/**
+ * Allocates a vertex to the tail end of the Two Head Gfx Arena.
+ */
+Vtx* THGA_AllocVtx(TwoHeadGfxArena* thga) {
+ return THGA_AllocTail(thga, sizeof(Vtx));
+}
diff --git a/src/code/game.c b/src/code/game.c
index 297bd2c6e7..88d2f5527e 100644
--- a/src/code/game.c
+++ b/src/code/game.c
@@ -173,7 +173,7 @@ void GameState_Draw(GameState* gameState, GraphicsContext* gfxCtx) {
DebugArena_Display();
SystemArena_Display();
// "%08x bytes left until the death of Hyrule (game_alloc)"
- osSyncPrintf("ハイラル滅亡まであと %08x バイト(game_alloc)\n", THA_GetSize(&gameState->tha));
+ osSyncPrintf("ハイラル滅亡まであと %08x バイト(game_alloc)\n", THA_GetRemaining(&gameState->tha));
R_ENABLE_ARENA_DBG = 0;
}
@@ -243,14 +243,14 @@ void GameState_Update(GameState* gameState) {
func_800C4344(gameState);
if (SREG(63) == 1u) {
- if (SREG(48) < 0) {
- SREG(48) = 0;
+ if (R_VI_MODE_EDIT_STATE < VI_MODE_EDIT_STATE_INACTIVE) {
+ R_VI_MODE_EDIT_STATE = VI_MODE_EDIT_STATE_INACTIVE;
gfxCtx->viMode = &gViConfigMode;
gfxCtx->viFeatures = gViConfigFeatures;
gfxCtx->xScale = gViConfigXScale;
gfxCtx->yScale = gViConfigYScale;
- } else if (SREG(48) > 0) {
- ViMode_Update(&sViMode, gameState->input);
+ } else if (R_VI_MODE_EDIT_STATE > VI_MODE_EDIT_STATE_INACTIVE) {
+ ViMode_Update(&sViMode, &gameState->input[0]);
gfxCtx->viMode = &sViMode.customViMode;
gfxCtx->viFeatures = sViMode.viFeatures;
gfxCtx->xScale = 1.0f;
@@ -261,6 +261,7 @@ void GameState_Update(GameState* gameState) {
gfxCtx->viFeatures = gViConfigFeatures;
gfxCtx->xScale = gViConfigXScale;
gfxCtx->yScale = gViConfigYScale;
+
if (SREG(63) == 6 || (SREG(63) == 2u && osTvType == OS_TV_NTSC)) {
gfxCtx->viMode = &osViModeNtscLan1;
gfxCtx->yScale = 1.0f;
@@ -304,7 +305,8 @@ void GameState_Update(GameState* gameState) {
HREG(83) = HREG(82);
HREG(84) = HREG(81);
gViConfigAdditionalScanLines = HREG(82);
- gViConfigYScale = HREG(81) == 0 ? 240.0f / (gViConfigAdditionalScanLines + 240.0f) : 1.0f;
+ gViConfigYScale =
+ HREG(81) == 0 ? ((f32)SCREEN_HEIGHT) / (gViConfigAdditionalScanLines + (f32)SCREEN_HEIGHT) : 1.0f;
D_80009430 = 1;
}
}
@@ -323,10 +325,10 @@ void GameState_InitArena(GameState* gameState, size_t size) {
osSyncPrintf("ハイラル確保 サイズ=%u バイト\n"); // "Hyrule reserved size = %u bytes"
arena = GameAlloc_MallocDebug(&gameState->alloc, size, "../game.c", 992);
if (arena != NULL) {
- THA_Ct(&gameState->tha, arena, size);
+ THA_Init(&gameState->tha, arena, size);
osSyncPrintf("ハイラル確保成功\n"); // "Successful Hyral"
} else {
- THA_Ct(&gameState->tha, NULL, 0);
+ THA_Init(&gameState->tha, NULL, 0);
osSyncPrintf("ハイラル確保失敗\n"); // "Failure to secure Hyrule"
Fault_AddHungupAndCrash("../game.c", 999);
}
@@ -338,10 +340,10 @@ void GameState_Realloc(GameState* gameState, size_t size) {
u32 systemMaxFree;
u32 systemFree;
u32 systemAlloc;
- void* thaBufp = gameState->tha.bufp;
+ void* thaStart = gameState->tha.start;
- THA_Dt(&gameState->tha);
- GameAlloc_Free(alloc, thaBufp);
+ THA_Destroy(&gameState->tha);
+ GameAlloc_Free(alloc, thaStart);
osSyncPrintf("ハイラル一時解放!!\n"); // "Hyrule temporarily released!!"
SystemArena_GetSizes(&systemMaxFree, &systemFree, &systemAlloc);
if ((systemMaxFree - 0x10) < size) {
@@ -358,10 +360,10 @@ void GameState_Realloc(GameState* gameState, size_t size) {
osSyncPrintf("ハイラル再確保 サイズ=%u バイト\n", size); // "Hyral reallocate size = %u bytes"
gameArena = GameAlloc_MallocDebug(alloc, size, "../game.c", 1033);
if (gameArena != NULL) {
- THA_Ct(&gameState->tha, gameArena, size);
+ THA_Init(&gameState->tha, gameArena, size);
osSyncPrintf("ハイラル再確保成功\n"); // "Successful reacquisition of Hyrule"
} else {
- THA_Ct(&gameState->tha, NULL, 0);
+ THA_Init(&gameState->tha, NULL, 0);
osSyncPrintf("ハイラル再確保失敗\n"); // "Failure to secure Hyral"
SystemArena_Display();
Fault_AddHungupAndCrash("../game.c", 1044);
@@ -406,7 +408,7 @@ void GameState_Init(GameState* gameState, GameStateFunc init, GraphicsContext* g
func_800ACE70(&D_801664F0);
func_800AD920(&D_80166500);
VisMono_Init(&sMonoColors);
- if (SREG(48) == 0) {
+ if (R_VI_MODE_EDIT_STATE == VI_MODE_EDIT_STATE_INACTIVE) {
ViMode_Init(&sViMode);
}
SpeedMeter_Init(&D_801664D0);
@@ -436,10 +438,10 @@ void GameState_Destroy(GameState* gameState) {
func_800ACE90(&D_801664F0);
func_800AD950(&D_80166500);
VisMono_Destroy(&sMonoColors);
- if (SREG(48) == 0) {
+ if (R_VI_MODE_EDIT_STATE == VI_MODE_EDIT_STATE_INACTIVE) {
ViMode_Destroy(&sViMode);
}
- THA_Dt(&gameState->tha);
+ THA_Destroy(&gameState->tha);
GameAlloc_Cleanup(&gameState->alloc);
SystemArena_Display();
Fault_RemoveClient(&sGameFaultClient);
@@ -465,13 +467,13 @@ void* GameState_Alloc(GameState* gameState, size_t size, char* file, s32 line) {
if (THA_IsCrash(&gameState->tha)) {
osSyncPrintf("ハイラルは滅亡している\n");
ret = NULL;
- } else if ((u32)THA_GetSize(&gameState->tha) < size) {
+ } else if ((u32)THA_GetRemaining(&gameState->tha) < size) {
// "Hyral on the verge of extinction does not have %d bytes left (%d bytes until extinction)"
osSyncPrintf("滅亡寸前のハイラルには %d バイトの余力もない(滅亡まであと %d バイト)\n", size,
- THA_GetSize(&gameState->tha));
+ THA_GetRemaining(&gameState->tha));
ret = NULL;
} else {
- ret = THA_AllocEndAlign16(&gameState->tha, size);
+ ret = THA_AllocTailAlign16(&gameState->tha, size);
if (THA_IsCrash(&gameState->tha)) {
osSyncPrintf("ハイラルは滅亡してしまった\n"); // "Hyrule has been destroyed"
ret = NULL;
@@ -486,9 +488,9 @@ void* GameState_Alloc(GameState* gameState, size_t size, char* file, s32 line) {
}
void* GameState_AllocEndAlign16(GameState* gameState, size_t size) {
- return THA_AllocEndAlign16(&gameState->tha, size);
+ return THA_AllocTailAlign16(&gameState->tha, size);
}
s32 GameState_GetArenaSize(GameState* gameState) {
- return THA_GetSize(&gameState->tha);
+ return THA_GetRemaining(&gameState->tha);
}
diff --git a/src/code/graph.c b/src/code/graph.c
index 0deb81fb80..ba683b2670 100644
--- a/src/code/graph.c
+++ b/src/code/graph.c
@@ -93,10 +93,10 @@ void Graph_InitTHGA(GraphicsContext* gfxCtx) {
pool->headMagic = GFXPOOL_HEAD_MAGIC;
pool->tailMagic = GFXPOOL_TAIL_MAGIC;
- THGA_Ct(&gfxCtx->polyOpa, pool->polyOpaBuffer, sizeof(pool->polyOpaBuffer));
- THGA_Ct(&gfxCtx->polyXlu, pool->polyXluBuffer, sizeof(pool->polyXluBuffer));
- THGA_Ct(&gfxCtx->overlay, pool->overlayBuffer, sizeof(pool->overlayBuffer));
- THGA_Ct(&gfxCtx->work, pool->workBuffer, sizeof(pool->workBuffer));
+ THGA_Init(&gfxCtx->polyOpa, pool->polyOpaBuffer, sizeof(pool->polyOpaBuffer));
+ THGA_Init(&gfxCtx->polyXlu, pool->polyXluBuffer, sizeof(pool->polyXluBuffer));
+ THGA_Init(&gfxCtx->overlay, pool->overlayBuffer, sizeof(pool->overlayBuffer));
+ THGA_Init(&gfxCtx->work, pool->workBuffer, sizeof(pool->workBuffer));
gfxCtx->polyOpaBuffer = pool->polyOpaBuffer;
gfxCtx->polyXluBuffer = pool->polyXluBuffer;
@@ -175,8 +175,8 @@ void Graph_TaskSet00(GraphicsContext* gfxCtx) {
osSyncPrintf("RCPが帰ってきませんでした。"); // "RCP did not return."
osSyncPrintf(VT_RST);
- LogUtils_LogHexDump((void*)&HW_REG(SP_MEM_ADDR_REG, u32), 0x20);
- LogUtils_LogHexDump((void*)&DPC_START_REG, 0x20);
+ LogUtils_LogHexDump((void*)PHYS_TO_K1(SP_BASE_REG), 0x20);
+ LogUtils_LogHexDump((void*)PHYS_TO_K1(DPC_BASE_REG), 0x20);
LogUtils_LogHexDump(gGfxSPTaskYieldBuffer, sizeof(gGfxSPTaskYieldBuffer));
SREG(6) = -1;
@@ -321,8 +321,8 @@ void Graph_Update(GraphicsContext* gfxCtx, GameState* gameState) {
}
if (HREG(81) < 0) {
- LogUtils_LogHexDump((void*)&HW_REG(SP_MEM_ADDR_REG, u32), 0x20);
- LogUtils_LogHexDump((void*)&DPC_START_REG, 0x20);
+ LogUtils_LogHexDump((void*)PHYS_TO_K1(SP_BASE_REG), 0x20);
+ LogUtils_LogHexDump((void*)PHYS_TO_K1(DPC_BASE_REG), 0x20);
}
if (HREG(81) < 0) {
@@ -458,20 +458,20 @@ void* Graph_Alloc(GraphicsContext* gfxCtx, size_t size) {
TwoHeadGfxArena* thga = &gfxCtx->polyOpa;
if (HREG(59) == 1) {
- osSyncPrintf("graph_alloc siz=%d thga size=%08x bufp=%08x head=%08x tail=%08x\n", size, thga->size, thga->bufp,
+ osSyncPrintf("graph_alloc siz=%d thga size=%08x bufp=%08x head=%08x tail=%08x\n", size, thga->size, thga->start,
thga->p, thga->d);
}
- return THGA_AllocEnd(&gfxCtx->polyOpa, ALIGN16(size));
+ return THGA_AllocTail(&gfxCtx->polyOpa, ALIGN16(size));
}
void* Graph_Alloc2(GraphicsContext* gfxCtx, size_t size) {
TwoHeadGfxArena* thga = &gfxCtx->polyOpa;
if (HREG(59) == 1) {
- osSyncPrintf("graph_alloc siz=%d thga size=%08x bufp=%08x head=%08x tail=%08x\n", size, thga->size, thga->bufp,
+ osSyncPrintf("graph_alloc siz=%d thga size=%08x bufp=%08x head=%08x tail=%08x\n", size, thga->size, thga->start,
thga->p, thga->d);
}
- return THGA_AllocEnd(&gfxCtx->polyOpa, ALIGN16(size));
+ return THGA_AllocTail(&gfxCtx->polyOpa, ALIGN16(size));
}
void Graph_OpenDisps(Gfx** dispRefs, GraphicsContext* gfxCtx, const char* file, s32 line) {
diff --git a/src/code/main.c b/src/code/main.c
index bf2a75a67a..a1fe35ef38 100644
--- a/src/code/main.c
+++ b/src/code/main.c
@@ -80,7 +80,7 @@ void Main(void* arg) {
osSyncPrintf("タスクスケジューラの初期化\n"); // "Initialize the task scheduler"
StackCheck_Init(&sSchedStackInfo, sSchedStack, STACK_TOP(sSchedStack), 0, 0x100, "sched");
- Sched_Init(&gScheduler, STACK_TOP(sSchedStack), THREAD_PRI_SCHED, D_80013960, 1, &gIrqMgr);
+ Sched_Init(&gScheduler, STACK_TOP(sSchedStack), THREAD_PRI_SCHED, gViConfigModeType, 1, &gIrqMgr);
IrqMgr_AddClient(&gIrqMgr, &irqClient, &irqMgrMsgQueue);
diff --git a/src/code/rcp_utils.c b/src/code/rcp_utils.c
index 5c14c39f98..e258ab02fa 100644
--- a/src/code/rcp_utils.c
+++ b/src/code/rcp_utils.c
@@ -50,6 +50,6 @@ void RcpUtils_Reset(void) {
// Flush the RDP pipeline and freeze clock counter
osDpSetStatus(DPC_SET_FREEZE | DPC_SET_FLUSH);
// Halt the RSP, disable interrupt on break and set "task done" signal
- __osSpSetStatus(SP_SET_HALT | SP_SET_SIG2 | SP_CLR_INTR_BREAK);
+ __osSpSetStatus(SP_SET_HALT | SP_SET_TASKDONE | SP_CLR_INTR_BREAK);
RcpUtils_PrintRegisterStatus();
}
diff --git a/src/code/sched.c b/src/code/sched.c
index 343d0eeb8b..ea038d2f20 100644
--- a/src/code/sched.c
+++ b/src/code/sched.c
@@ -650,7 +650,7 @@ void Sched_ThreadEntry(void* arg) {
}
}
-void Sched_Init(Scheduler* sc, void* stack, OSPri priority, UNK_TYPE arg3, UNK_TYPE arg4, IrqMgr* irqMgr) {
+void Sched_Init(Scheduler* sc, void* stack, OSPri priority, u8 viModeType, UNK_TYPE arg4, IrqMgr* irqMgr) {
bzero(sc, sizeof(Scheduler));
sc->isFirstSwap = true;
diff --git a/src/code/speed_meter.c b/src/code/speed_meter.c
index f22680b566..5d38d65bf2 100644
--- a/src/code/speed_meter.c
+++ b/src/code/speed_meter.c
@@ -231,25 +231,26 @@ void SpeedMeter_DrawAllocEntries(SpeedMeter* meter, GraphicsContext* gfxCtx, Gam
}
thga = (TwoHeadGfxArena*)&state->tha;
- SpeedMeter_InitAllocEntry(&entry, thga->size, thga->size - THA_GetSize((TwoHeadArena*)thga),
+ //! @bug THA_GetRemaining call should be THGA_GetRemaining like the others below, harmless as-is
+ SpeedMeter_InitAllocEntry(&entry, thga->size, thga->size - THA_GetRemaining(&thga->tha),
GPACK_RGBA5551(0, 0, 255, 1), GPACK_RGBA5551(0, 255, 0, 1), ulx, lrx, y, y);
SpeedMeter_DrawAllocEntry(&entry, gfxCtx);
y++;
thga = &gfxCtx->polyOpa;
- SpeedMeter_InitAllocEntry(&entry, thga->size, thga->size - THGA_GetSize(thga), GPACK_RGBA5551(0, 0, 255, 1),
+ SpeedMeter_InitAllocEntry(&entry, thga->size, thga->size - THGA_GetRemaining(thga), GPACK_RGBA5551(0, 0, 255, 1),
GPACK_RGBA5551(255, 0, 255, 1), ulx, lrx, y, y);
SpeedMeter_DrawAllocEntry(&entry, gfxCtx);
y++;
thga = &gfxCtx->polyXlu;
- SpeedMeter_InitAllocEntry(&entry, thga->size, thga->size - THGA_GetSize(thga), GPACK_RGBA5551(0, 0, 255, 1),
+ SpeedMeter_InitAllocEntry(&entry, thga->size, thga->size - THGA_GetRemaining(thga), GPACK_RGBA5551(0, 0, 255, 1),
GPACK_RGBA5551(255, 255, 0, 1), ulx, lrx, y, y);
SpeedMeter_DrawAllocEntry(&entry, gfxCtx);
y++;
thga = &gfxCtx->overlay;
- SpeedMeter_InitAllocEntry(&entry, thga->size, thga->size - THGA_GetSize(thga), GPACK_RGBA5551(0, 0, 255, 1),
+ SpeedMeter_InitAllocEntry(&entry, thga->size, thga->size - THGA_GetRemaining(thga), GPACK_RGBA5551(0, 0, 255, 1),
GPACK_RGBA5551(255, 0, 0, 1), ulx, lrx, y, y);
SpeedMeter_DrawAllocEntry(&entry, gfxCtx);
y++;
diff --git a/src/code/z_bgcheck.c b/src/code/z_bgcheck.c
index d3223433bc..1385bbc835 100644
--- a/src/code/z_bgcheck.c
+++ b/src/code/z_bgcheck.c
@@ -149,7 +149,7 @@ void DynaSSNodeList_Initialize(PlayState* play, DynaSSNodeList* nodeList) {
* Initialize DynaSSNodeList tbl
*/
void DynaSSNodeList_Alloc(PlayState* play, DynaSSNodeList* nodeList, s32 max) {
- nodeList->tbl = THA_AllocEndAlign(&play->state.tha, max * sizeof(SSNode), -2);
+ nodeList->tbl = THA_AllocTailAlign(&play->state.tha, max * sizeof(SSNode), ALIGNOF_MASK(SSNode));
ASSERT(nodeList->tbl != NULL, "psst->tbl != NULL", "../z_bgcheck.c", 1811);
@@ -1613,9 +1613,10 @@ void BgCheck_Allocate(CollisionContext* colCtx, PlayState* play, CollisionHeader
colCtx->subdivAmount.z = 16;
}
}
- colCtx->lookupTbl = THA_AllocEndAlign(
- &play->state.tha,
- colCtx->subdivAmount.x * sizeof(StaticLookup) * colCtx->subdivAmount.y * colCtx->subdivAmount.z, ~1);
+ colCtx->lookupTbl = THA_AllocTailAlign(&play->state.tha,
+ colCtx->subdivAmount.x * sizeof(StaticLookup) * colCtx->subdivAmount.y *
+ colCtx->subdivAmount.z,
+ ALIGNOF_MASK(StaticLookup));
if (colCtx->lookupTbl == NULL) {
LogUtils_HungupThread("../z_bgcheck.c", 4176);
}
@@ -2501,7 +2502,7 @@ void SSNodeList_Initialize(SSNodeList* this) {
void SSNodeList_Alloc(PlayState* play, SSNodeList* this, s32 tblMax, s32 numPolys) {
this->max = tblMax;
this->count = 0;
- this->tbl = THA_AllocEndAlign(&play->state.tha, tblMax * sizeof(SSNode), -2);
+ this->tbl = THA_AllocTailAlign(&play->state.tha, tblMax * sizeof(SSNode), ALIGNOF_MASK(SSNode));
ASSERT(this->tbl != NULL, "this->short_slist_node_tbl != NULL", "../z_bgcheck.c", 5975);
@@ -2636,7 +2637,7 @@ void DynaPoly_NullPolyList(CollisionPoly** polyList) {
* Allocate dyna.polyList
*/
void DynaPoly_AllocPolyList(PlayState* play, CollisionPoly** polyList, s32 numPolys) {
- *polyList = THA_AllocEndAlign(&play->state.tha, numPolys * sizeof(CollisionPoly), -2);
+ *polyList = THA_AllocTailAlign(&play->state.tha, numPolys * sizeof(CollisionPoly), ALIGNOF_MASK(CollisionPoly));
ASSERT(*polyList != NULL, "ptbl->pbuf != NULL", "../z_bgcheck.c", 6247);
}
@@ -2651,7 +2652,7 @@ void DynaPoly_NullVtxList(Vec3s** vtxList) {
* Allocate dyna.vtxList
*/
void DynaPoly_AllocVtxList(PlayState* play, Vec3s** vtxList, s32 numVtx) {
- *vtxList = THA_AllocEndAlign(&play->state.tha, numVtx * sizeof(Vec3s), -2);
+ *vtxList = THA_AllocTailAlign(&play->state.tha, numVtx * sizeof(Vec3s), ALIGNOF_MASK(Vec3s));
ASSERT(*vtxList != NULL, "ptbl->pbuf != NULL", "../z_bgcheck.c", 6277);
}
diff --git a/src/code/z_camera.c b/src/code/z_camera.c
index 7a9ab5d655..4c69f5889b 100644
--- a/src/code/z_camera.c
+++ b/src/code/z_camera.c
@@ -816,10 +816,10 @@ Vec3f* Camera_BGCheckCorner(Vec3f* dst, Vec3f* linePointA, Vec3f* linePointB, Ca
}
/**
- * Checks collision between at and eyeNext, if `checkEye` is set, if there is no collsion between
+ * Checks collision between at and eyeNext, if `checkEye` is set, if there is no collision between
* eyeNext->at, then eye->at is also checked.
* Returns:
- * 0 if no collsion is found between at->eyeNext
+ * 0 if no collision is found between at->eyeNext
* 2 if the angle between the polys is between 60 degrees and 120 degrees
* 3 ?
* 6 if the angle between the polys is greater than 120 degrees
@@ -2531,7 +2531,7 @@ s32 Camera_Jump2(Camera* camera) {
Camera_AddVecGeoToVec3f(&camBgChk.pos, at, &bgChkPara);
if (Camera_BGCheckInfo(camera, at, &camBgChk)) {
// Collision found between parallel at->eyeNext, set eye position to
- // first collsion point.
+ // first collision point.
*eye = bgChkPos;
} else {
// no collision found with the parallel at->eye, animate to be parallel
diff --git a/src/code/z_collision_check.c b/src/code/z_collision_check.c
index 1d6f7129db..1735b58842 100644
--- a/src/code/z_collision_check.c
+++ b/src/code/z_collision_check.c
@@ -2709,8 +2709,8 @@ void CollisionCheck_SetOCvsOC(Collider* leftCol, ColliderElement* leftElem, Vec3
f32 zDelta;
Actor* leftActor = leftCol->self;
Actor* rightActor = rightCol->self;
- s32 leftMassType;
s32 rightMassType;
+ s32 leftMassType;
leftCol->ocFlags1 |= OC1_HIT;
leftCol->otherOC = rightActor;
@@ -2728,8 +2728,8 @@ void CollisionCheck_SetOCvsOC(Collider* leftCol, ColliderElement* leftElem, Vec3
rightCol->ocFlags1 & OC1_NO_PUSH) {
return;
}
- rightMassType = CollisionCheck_GetMassType(leftActor->colChkInfo.mass);
- leftMassType = CollisionCheck_GetMassType(rightActor->colChkInfo.mass);
+ leftMassType = CollisionCheck_GetMassType(leftActor->colChkInfo.mass);
+ rightMassType = CollisionCheck_GetMassType(rightActor->colChkInfo.mass);
leftMass = leftActor->colChkInfo.mass;
rightMass = rightActor->colChkInfo.mass;
totalMass = leftMass + rightMass;
@@ -2741,30 +2741,30 @@ void CollisionCheck_SetOCvsOC(Collider* leftCol, ColliderElement* leftElem, Vec3
zDelta = rightPos->z - leftPos->z;
xzDist = sqrtf(SQ(xDelta) + SQ(zDelta));
- if (rightMassType == MASSTYPE_IMMOVABLE) {
- if (leftMassType == MASSTYPE_IMMOVABLE) {
+ if (leftMassType == MASSTYPE_IMMOVABLE) {
+ if (rightMassType == MASSTYPE_IMMOVABLE) {
return;
- } else { // leftMassType == MASS_HEAVY | MASS_NORMAL
+ } else { // rightMassType == MASSTYPE_HEAVY or MASSTYPE_NORMAL
leftDispRatio = 0;
rightDispRatio = 1;
}
- } else if (rightMassType == MASSTYPE_HEAVY) {
- if (leftMassType == MASSTYPE_IMMOVABLE) {
+ } else if (leftMassType == MASSTYPE_HEAVY) {
+ if (rightMassType == MASSTYPE_IMMOVABLE) {
leftDispRatio = 1;
rightDispRatio = 0;
- } else if (leftMassType == MASSTYPE_HEAVY) {
+ } else if (rightMassType == MASSTYPE_HEAVY) {
leftDispRatio = 0.5f;
rightDispRatio = 0.5f;
- } else { // leftMassType == MASS_NORMAL
+ } else { // rightMassType == MASSTYPE_NORMAL
leftDispRatio = 0;
rightDispRatio = 1;
}
- } else { // rightMassType == MASS_NORMAL
- if (leftMassType == MASSTYPE_NORMAL) {
+ } else { // leftMassType == MASSTYPE_NORMAL
+ if (rightMassType == MASSTYPE_NORMAL) {
inverseTotalMass = 1 / totalMass;
leftDispRatio = rightMass * inverseTotalMass;
rightDispRatio = leftMass * inverseTotalMass;
- } else { // leftMassType == MASS_HEAVY | MASS_IMMOVABLE
+ } else { // rightMassType == MASSTYPE_HEAVY or MASSTYPE_IMMOVABLE
leftDispRatio = 1;
rightDispRatio = 0;
}
@@ -3579,7 +3579,7 @@ s32 CollisionCheck_CylSideVsLineSeg(f32 radius, f32 height, f32 offset, Vec3f* a
}
radSqDiff = SQXZ(actorToItem) - SQ(radius);
if (!IS_ZERO(SQXZ(itemStep))) {
- actorDotItemXZ = DOTXZ(2.0f * itemStep, actorToItem);
+ actorDotItemXZ = (2.0f * itemStep.x * actorToItem.x) + (2.0f * itemStep.z * actorToItem.z);
if (SQ(actorDotItemXZ) < (4.0f * SQXZ(itemStep) * radSqDiff)) {
return 0;
}
@@ -3596,10 +3596,10 @@ s32 CollisionCheck_CylSideVsLineSeg(f32 radius, f32 height, f32 offset, Vec3f* a
if (intersect2 == true) {
frac2 = (-actorDotItemXZ - closeDist) / (2.0f * SQXZ(itemStep));
}
- } else if (!IS_ZERO(DOTXZ(2.0f * itemStep, actorToItem))) {
+ } else if (!IS_ZERO((2.0f * itemStep.x * actorToItem.x) + (2.0f * itemStep.z * actorToItem.z))) {
intersect1 = true;
intersect2 = false;
- frac1 = -radSqDiff / DOTXZ(2.0f * itemStep, actorToItem);
+ frac1 = -radSqDiff / ((2.0f * itemStep.x * actorToItem.x) + (2.0f * itemStep.z * actorToItem.z));
} else {
if (radSqDiff <= 0.0f) {
test1 = (0.0f < actorToItem.y) && (actorToItem.y < height);
diff --git a/src/code/z_effect_soft_sprite_old_init.c b/src/code/z_effect_soft_sprite_old_init.c
index 106fdee1aa..1e30438d76 100644
--- a/src/code/z_effect_soft_sprite_old_init.c
+++ b/src/code/z_effect_soft_sprite_old_init.c
@@ -748,7 +748,7 @@ void EffectSsFhgFlash_SpawnLightBall(PlayState* play, Vec3f* pos, Vec3f* velocit
* Spawn a shock effect
*
* param determines where the ligntning should go
- * 0: dont attach to any actor. spawns at the position specified by pos
+ * 0: don't attach to any actor. spawns at the position specified by pos
* 1: spawn at one of Player's body parts, chosen at random
* 2: spawn at one of Phantom Ganon's body parts, chosen at random
*/
diff --git a/src/code/z_play.c b/src/code/z_play.c
index 24311b6010..b2fd9d5aaf 100644
--- a/src/code/z_play.c
+++ b/src/code/z_play.c
@@ -393,8 +393,8 @@ void Play_Init(GameState* thisx) {
D_801614B0.a = 0;
Flags_UnsetAllEnv(this);
- osSyncPrintf("ZELDA ALLOC SIZE=%x\n", THA_GetSize(&this->state.tha));
- zAllocSize = THA_GetSize(&this->state.tha);
+ osSyncPrintf("ZELDA ALLOC SIZE=%x\n", THA_GetRemaining(&this->state.tha));
+ zAllocSize = THA_GetRemaining(&this->state.tha);
zAlloc = (u32)GameState_Alloc(&this->state, zAllocSize, "../z_play.c", 2918);
zAllocAligned = (zAlloc + 8) & ~0xF;
ZeldaArena_Init((void*)zAllocAligned, zAllocSize - zAllocAligned + zAlloc);
diff --git a/src/code/z_vimode.c b/src/code/z_vimode.c
index f7f81bca92..d3f5e0a2c6 100644
--- a/src/code/z_vimode.c
+++ b/src/code/z_vimode.c
@@ -1,158 +1,190 @@
#include "global.h"
+#include "ultra64/viint.h"
void ViMode_LogPrint(OSViMode* osViMode) {
LOG_ADDRESS("osvimodep", osViMode, "../z_vimode.c", 87);
- LOG_ADDRESS("osvimodep->comRegs.ctrl", osViMode->comRegs.ctrl, "../z_vimode.c", 88);
- LOG_ADDRESS("osvimodep->comRegs.width", osViMode->comRegs.width, "../z_vimode.c", 89);
- LOG_ADDRESS("osvimodep->comRegs.burst", osViMode->comRegs.burst, "../z_vimode.c", 90);
- LOG_ADDRESS("osvimodep->comRegs.vSync", osViMode->comRegs.vSync, "../z_vimode.c", 91);
- LOG_ADDRESS("osvimodep->comRegs.hSync", osViMode->comRegs.hSync, "../z_vimode.c", 92);
- LOG_ADDRESS("osvimodep->comRegs.leap", osViMode->comRegs.leap, "../z_vimode.c", 93);
- LOG_ADDRESS("osvimodep->comRegs.hStart", osViMode->comRegs.hStart, "../z_vimode.c", 94);
- LOG_ADDRESS("osvimodep->comRegs.xScale", osViMode->comRegs.xScale, "../z_vimode.c", 95);
- LOG_ADDRESS("osvimodep->fldRegs[0].vStart", osViMode->fldRegs[0].vStart, "../z_vimode.c", 96);
- LOG_ADDRESS("osvimodep->fldRegs[0].vBurst", osViMode->fldRegs[0].vBurst, "../z_vimode.c", 97);
- LOG_ADDRESS("osvimodep->fldRegs[0].origin", osViMode->fldRegs[0].origin, "../z_vimode.c", 98);
- LOG_ADDRESS("osvimodep->fldRegs[0].yScale", osViMode->fldRegs[0].yScale, "../z_vimode.c", 99);
- LOG_ADDRESS("osvimodep->fldRegs[0].vIntr", osViMode->fldRegs[0].vIntr, "../z_vimode.c", 100);
- LOG_ADDRESS("osvimodep->fldRegs[1].vStart", osViMode->fldRegs[1].vStart, "../z_vimode.c", 101);
- LOG_ADDRESS("osvimodep->fldRegs[1].vBurst", osViMode->fldRegs[1].vBurst, "../z_vimode.c", 102);
- LOG_ADDRESS("osvimodep->fldRegs[1].origin", osViMode->fldRegs[1].origin, "../z_vimode.c", 103);
- LOG_ADDRESS("osvimodep->fldRegs[1].yScale", osViMode->fldRegs[1].yScale, "../z_vimode.c", 104);
- LOG_ADDRESS("osvimodep->fldRegs[1].vIntr", osViMode->fldRegs[1].vIntr, "../z_vimode.c", 105);
+ LOG_HEX32("osvimodep->comRegs.ctrl", osViMode->comRegs.ctrl, "../z_vimode.c", 88);
+ LOG_HEX32("osvimodep->comRegs.width", osViMode->comRegs.width, "../z_vimode.c", 89);
+ LOG_HEX32("osvimodep->comRegs.burst", osViMode->comRegs.burst, "../z_vimode.c", 90);
+ LOG_HEX32("osvimodep->comRegs.vSync", osViMode->comRegs.vSync, "../z_vimode.c", 91);
+ LOG_HEX32("osvimodep->comRegs.hSync", osViMode->comRegs.hSync, "../z_vimode.c", 92);
+ LOG_HEX32("osvimodep->comRegs.leap", osViMode->comRegs.leap, "../z_vimode.c", 93);
+ LOG_HEX32("osvimodep->comRegs.hStart", osViMode->comRegs.hStart, "../z_vimode.c", 94);
+ LOG_HEX32("osvimodep->comRegs.xScale", osViMode->comRegs.xScale, "../z_vimode.c", 95);
+ LOG_HEX32("osvimodep->fldRegs[0].vStart", osViMode->fldRegs[0].vStart, "../z_vimode.c", 96);
+ LOG_HEX32("osvimodep->fldRegs[0].vBurst", osViMode->fldRegs[0].vBurst, "../z_vimode.c", 97);
+ LOG_HEX32("osvimodep->fldRegs[0].origin", osViMode->fldRegs[0].origin, "../z_vimode.c", 98);
+ LOG_HEX32("osvimodep->fldRegs[0].yScale", osViMode->fldRegs[0].yScale, "../z_vimode.c", 99);
+ LOG_HEX32("osvimodep->fldRegs[0].vIntr", osViMode->fldRegs[0].vIntr, "../z_vimode.c", 100);
+ LOG_HEX32("osvimodep->fldRegs[1].vStart", osViMode->fldRegs[1].vStart, "../z_vimode.c", 101);
+ LOG_HEX32("osvimodep->fldRegs[1].vBurst", osViMode->fldRegs[1].vBurst, "../z_vimode.c", 102);
+ LOG_HEX32("osvimodep->fldRegs[1].origin", osViMode->fldRegs[1].origin, "../z_vimode.c", 103);
+ LOG_HEX32("osvimodep->fldRegs[1].yScale", osViMode->fldRegs[1].yScale, "../z_vimode.c", 104);
+ LOG_HEX32("osvimodep->fldRegs[1].vIntr", osViMode->fldRegs[1].vIntr, "../z_vimode.c", 105);
}
-// This function configures the custom VI mode (`viMode.customViMode`) based on the other flags in `viMode`.
-void ViMode_Configure(ViMode* viMode, s32 mode, s32 type, s32 unk_70, s32 unk_74, s32 unk_78, s32 unk_7C, s32 width,
- s32 height, s32 unk_left, s32 unk_right, s32 unk_top, s32 unk_bottom) {
- s32 not_70;
- s32 not_74;
- s32 not_78;
- s32 not_7C;
- s32 cond_4C;
- s32 cond_48;
- s32 cond_44;
- s32 cond_40;
- s32 cond_3C;
- s32 cond_38;
- s32 cond_34;
+/**
+ * Configures the custom OSViMode for this ViMode
+ *
+ * @param viMode ViMode to configure the custom OSViMode for
+ * @param type Identifying type for the OSViMode
+ * @param tvType TV Type: NTSC, PAL, MPAL or FPAL
+ * @param loRes Boolean: true = low resolution, false = high resolution.
+ * Corresponds to "L" or "H" in libultra VI mode names
+ * @param antialiasOff Boolean: true = point-sampling, false = anti-aliasing.
+ * Corresponds to "P" or "A" in libultra VI mode names
+ * @param modeN Boolean: controls interlacing mode, different based on resolution.
+ * Corresponds to "N" or "F" in libultra VI mode names
+ * @param fb16Bit Bolean: true = 16-bit framebuffer, false = 32-bit framebuffer.
+ * Corresponds to "1" or "2" in libultra VI mode names
+ * @param width Screen width
+ * @param height Screen height
+ * @param leftAdjust Left edge adjustment
+ * @param rightAdjust Right edge adjustment
+ * @param upperAdjust Upper edge adjustment
+ * @param lowerAdjust Lower edge adjustment
+ */
+void ViMode_Configure(ViMode* viMode, s32 type, s32 tvType, s32 loRes, s32 antialiasOff, s32 modeN, s32 fb16Bit,
+ s32 width, s32 height, s32 leftAdjust, s32 rightAdjust, s32 upperAdjust, s32 lowerAdjust) {
+ s32 hiRes;
+ s32 antialiasOn;
+ s32 modeF;
+ s32 fb32Bit;
+ s32 hiResDeflicker; // deflickered interlacing
+ s32 hiResInterlaced;
+ s32 loResDeinterlaced;
+ s32 loResInterlaced;
+ s32 modeLAN1; // L=(lo res) A=(antialias) N=(deinterlace) 1=(16-bit)
+ s32 modeLPN2; // L=(lo res) P=(point-sampled) N=(deinterlace) 2=(32-bit)
+ s32 modeHPN2; // H=(hi res) P=(point-sampled) N=(normal interlacing) 2=(32-bit)
s32 yScaleLo;
- s32 yScaleHi0;
- s32 yScaleHi1;
+ s32 yScaleHiEvenField;
+ s32 yScaleHiOddField;
- not_70 = !unk_70;
- not_74 = !unk_74;
- not_78 = !unk_78;
- not_7C = !unk_7C;
+ hiRes = !loRes;
+ antialiasOn = !antialiasOff;
+ modeF = !modeN;
+ fb32Bit = !fb16Bit;
- cond_4C = not_70 && not_78;
- cond_48 = not_70 && unk_78;
- cond_44 = unk_70 && unk_78;
- cond_40 = unk_70 && not_78;
- cond_3C = unk_70 && not_74 && unk_78 && unk_7C;
- cond_38 = unk_70 && unk_74 && unk_78 && not_7C;
- cond_34 = not_70 && unk_74 && unk_78 && not_7C;
+ hiResDeflicker = hiRes && modeF;
+ hiResInterlaced = hiRes && modeN;
+ loResDeinterlaced = loRes && modeN;
+ loResInterlaced = loRes && modeF;
- unk_top &= ~1;
- unk_bottom &= ~1;
+ modeLAN1 = loRes && antialiasOn && modeN && fb16Bit;
+ modeLPN2 = loRes && antialiasOff && modeN && fb32Bit;
+ modeHPN2 = hiRes && antialiasOff && modeN && fb32Bit;
- yScaleLo = (cond_4C ? 2 : 1) * ((height << 11) / (SCREEN_HEIGHT * 2 + unk_bottom - unk_top) / (unk_70 ? 1 : 2));
+ upperAdjust &= ~1;
+ lowerAdjust &= ~1;
- yScaleHi0 = not_78 ? (cond_40 ? 0x1000000 : 0x2000000) : 0;
- yScaleHi1 = not_78 ? (cond_40 ? 0x3000000 : 0x2000000) : 0;
+ yScaleLo =
+ (hiResDeflicker ? 2 : 1) * ((height << 11) / (SCREEN_HEIGHT * 2 + lowerAdjust - upperAdjust) / (loRes ? 1 : 2));
- viMode->customViMode.type = mode;
- viMode->customViMode.comRegs.ctrl = OS_VI_UNK2000 | OS_VI_UNK1000 | OS_VI_GAMMA | OS_VI_GAMMA_DITHER |
- (!cond_44 ? OS_VI_UNK40 : 0) | (not_74 ? OS_VI_DIVOT : 0) |
- (not_7C ? OS_VI_UNK2 | OS_VI_UNK1 : OS_VI_UNK2);
+ yScaleHiEvenField = modeF ? (loResInterlaced ? (F210(0.25) << 16) : (F210(0.5) << 16)) : 0;
+ yScaleHiOddField = modeF ? (loResInterlaced ? (F210(0.75) << 16) : (F210(0.5) << 16)) : 0;
- if (cond_3C) {
- viMode->customViMode.comRegs.ctrl |= 0x100;
- } else if (cond_38 | cond_34) {
- viMode->customViMode.comRegs.ctrl |= 0x300;
- } else if (unk_74) {
- viMode->customViMode.comRegs.ctrl |= 0x200;
+ viMode->customViMode.type = type;
+ viMode->customViMode.comRegs.ctrl = VI_CTRL_PIXEL_ADV(3) | VI_CTRL_GAMMA_ON | VI_CTRL_GAMMA_DITHER_ON |
+ (!loResDeinterlaced ? VI_CTRL_SERRATE_ON : 0) |
+ (antialiasOn ? VI_CTRL_DIVOT_ON : 0) |
+ (fb32Bit ? VI_CTRL_TYPE_32 : VI_CTRL_TYPE_16);
+
+ if (modeLAN1) {
+ // Anti-aliased, fetch extra lines as-needed
+ viMode->customViMode.comRegs.ctrl |= VI_CTRL_ANTIALIAS_MODE_1;
+ } else if (modeLPN2 | modeHPN2) {
+ // Point-sampled, resampling disabled
+ viMode->customViMode.comRegs.ctrl |= VI_CTRL_ANTIALIAS_MODE_3;
} else {
- viMode->customViMode.comRegs.ctrl |= 0;
+ if (antialiasOff) {
+ // Point-sampled, resampling enabled
+ viMode->customViMode.comRegs.ctrl |= VI_CTRL_ANTIALIAS_MODE_2;
+ } else {
+ // Anti-aliased, always fetch extra lines
+ viMode->customViMode.comRegs.ctrl |= VI_CTRL_ANTIALIAS_MODE_0;
+ }
}
- viMode->customViMode.comRegs.width = width * (cond_48 ? 2 : 1);
+ viMode->customViMode.comRegs.width = width * (hiResInterlaced ? 2 : 1);
- if (type == 1) {
- viMode->customViMode.comRegs.burst = 0x3E52239;
- viMode->customViMode.comRegs.vSync = 0x20C;
- viMode->customViMode.comRegs.hSync = 0xC15;
- viMode->customViMode.comRegs.leap = 0xC150C15;
- viMode->customViMode.comRegs.hStart = 0x6C02EC;
- viMode->customViMode.fldRegs[0].vStart = 0x2501FF;
- viMode->customViMode.fldRegs[0].vBurst = 0xE0204;
- } else if (type == 0) {
- viMode->customViMode.comRegs.burst = 0x404233A;
- viMode->customViMode.comRegs.vSync = 0x270;
- viMode->customViMode.comRegs.hSync = 0x150C69;
- viMode->customViMode.comRegs.leap = 0xC6F0C6E;
- viMode->customViMode.comRegs.hStart = 0x800300;
- viMode->customViMode.fldRegs[0].vStart = 0x5F0239;
- viMode->customViMode.fldRegs[0].vBurst = 0x9026B;
- } else if (type == 2) {
- viMode->customViMode.comRegs.burst = 0x4651E39;
- viMode->customViMode.comRegs.vSync = 0x20C;
- viMode->customViMode.comRegs.hSync = 0xC10;
- viMode->customViMode.comRegs.leap = 0xC1C0C1C;
- viMode->customViMode.comRegs.hStart = 0x6C02EC;
- viMode->customViMode.fldRegs[0].vStart = 0x2501FF;
- viMode->customViMode.fldRegs[0].vBurst = 0xE0204;
+ if (tvType == OS_TV_NTSC) {
+ viMode->customViMode.comRegs.burst = BURST(57, 34, 5, 62);
+ viMode->customViMode.comRegs.vSync = VSYNC(524);
+ viMode->customViMode.comRegs.hSync = HSYNC(3093, 0);
+ viMode->customViMode.comRegs.leap = LEAP(3093, 3093);
+ viMode->customViMode.comRegs.hStart = HSTART(108, 748);
+ viMode->customViMode.fldRegs[0].vStart = START(37, 511);
+ viMode->customViMode.fldRegs[0].vBurst = BURST(4, 2, 14, 0);
+ } else if (tvType == OS_TV_PAL) {
+ viMode->customViMode.comRegs.burst = BURST(58, 35, 4, 64);
+ viMode->customViMode.comRegs.vSync = VSYNC(624);
+ viMode->customViMode.comRegs.hSync = HSYNC(3177, 21);
+ viMode->customViMode.comRegs.leap = LEAP(3183, 3182);
+ viMode->customViMode.comRegs.hStart = HSTART(128, 768);
+ viMode->customViMode.fldRegs[0].vStart = START(95, 569);
+ viMode->customViMode.fldRegs[0].vBurst = BURST(107, 2, 9, 0);
+ } else if (tvType == OS_TV_MPAL) {
+ viMode->customViMode.comRegs.burst = BURST(57, 30, 5, 70);
+ viMode->customViMode.comRegs.vSync = VSYNC(524);
+ viMode->customViMode.comRegs.hSync = HSYNC(3088, 0);
+ viMode->customViMode.comRegs.leap = LEAP(3100, 3100);
+ viMode->customViMode.comRegs.hStart = HSTART(108, 748);
+ viMode->customViMode.fldRegs[0].vStart = START(37, 511);
+ viMode->customViMode.fldRegs[0].vBurst = BURST(4, 2, 14, 0);
}
viMode->customViMode.fldRegs[1].vStart = viMode->customViMode.fldRegs[0].vStart;
- viMode->customViMode.comRegs.hStart += (unk_left << 16) + (s16)unk_right;
- viMode->customViMode.fldRegs[0].vStart += (unk_top << 16) + (s16)unk_bottom;
- viMode->customViMode.fldRegs[1].vStart += (unk_top << 16) + (s16)unk_bottom;
+ viMode->customViMode.comRegs.hStart += (leftAdjust << 16) + (s16)rightAdjust;
+ viMode->customViMode.fldRegs[0].vStart += (upperAdjust << 16) + (s16)lowerAdjust;
+ viMode->customViMode.fldRegs[1].vStart += (upperAdjust << 16) + (s16)lowerAdjust;
viMode->customViMode.fldRegs[1].vBurst = viMode->customViMode.fldRegs[0].vBurst;
- if (cond_44) {
+ if (loResDeinterlaced) {
viMode->customViMode.comRegs.vSync++;
- if (type == 2) {
- viMode->customViMode.comRegs.hSync += 0x40001;
+ if (tvType == OS_TV_MPAL) {
+ viMode->customViMode.comRegs.hSync += HSYNC(1, 4);
}
- if (type == 2) {
- viMode->customViMode.comRegs.leap += 0xFFFCFFFE;
+ if (tvType == OS_TV_MPAL) {
+ viMode->customViMode.comRegs.leap += LEAP((u16)-4, (u16)-2);
}
} else {
- viMode->customViMode.fldRegs[0].vStart += 0xFFFDFFFE;
- if (type == 2) {
- viMode->customViMode.fldRegs[0].vBurst += 0xFFFCFFFE;
+ viMode->customViMode.fldRegs[0].vStart += START((u16)-3, (u16)-2);
+ if (tvType == OS_TV_MPAL) {
+ viMode->customViMode.fldRegs[0].vBurst += BURST((u8)-2, (u8)-1, 12, -1);
}
- if (type == 0) {
- viMode->customViMode.fldRegs[1].vBurst += 0x2FFFE;
+ if (tvType == OS_TV_PAL) {
+ viMode->customViMode.fldRegs[1].vBurst += BURST((u8)-2, (u8)-1, 2, 0);
}
}
- viMode->customViMode.comRegs.xScale = (width << 10) / (SCREEN_WIDTH * 2 + unk_right - unk_left);
- viMode->customViMode.comRegs.vCurrent = 0;
+ viMode->customViMode.comRegs.xScale = (width << 10) / (SCREEN_WIDTH * 2 + rightAdjust - leftAdjust);
+ viMode->customViMode.comRegs.vCurrent = VCURRENT(0);
- viMode->customViMode.fldRegs[0].origin = width * 2 * (unk_7C ? 1 : 2);
- viMode->customViMode.fldRegs[1].origin = width * 2 * (unk_7C ? 1 : 2) * (unk_70 ? 1 : 2);
+ viMode->customViMode.fldRegs[0].origin = ORIGIN(width * 2 * (fb16Bit ? 1 : 2));
+ viMode->customViMode.fldRegs[1].origin = ORIGIN(width * 2 * (fb16Bit ? 1 : 2) * (loRes ? 1 : 2));
- viMode->customViMode.fldRegs[0].yScale = yScaleLo | yScaleHi0;
- viMode->customViMode.fldRegs[1].yScale = yScaleLo | yScaleHi1;
+ viMode->customViMode.fldRegs[0].yScale = yScaleLo | yScaleHiEvenField;
+ viMode->customViMode.fldRegs[1].yScale = yScaleLo | yScaleHiOddField;
- viMode->customViMode.fldRegs[0].vIntr = 2;
- viMode->customViMode.fldRegs[1].vIntr = 2;
+ viMode->customViMode.fldRegs[0].vIntr = VINTR(2);
+ viMode->customViMode.fldRegs[1].vIntr = VINTR(2);
}
void ViMode_Save(ViMode* viMode) {
- SREG(48) = viMode->viModeBase;
- SREG(49) = viMode->viWidth;
- SREG(50) = viMode->viHeight;
- SREG(51) = viMode->unk_64;
- SREG(52) = viMode->unk_60;
- SREG(53) = viMode->unk_5C;
- SREG(54) = viMode->unk_58;
+ R_VI_MODE_EDIT_STATE = viMode->editState;
+ R_VI_MODE_EDIT_WIDTH = viMode->viWidth;
+ R_VI_MODE_EDIT_HEIGHT = viMode->viHeight;
+ R_VI_MODE_EDIT_ULY_ADJ = viMode->upperAdjust;
+ R_VI_MODE_EDIT_LRY_ADJ = viMode->lowerAdjust;
+ R_VI_MODE_EDIT_ULX_ADJ = viMode->leftAdjust;
+ R_VI_MODE_EDIT_LRX_ADJ = viMode->rightAdjust;
+
if (SREG(58) == 1) {
SREG(58) = 0;
+
switch (SREG(59)) {
case 1:
osSyncPrintf("osViModePalLan1\n");
@@ -171,33 +203,34 @@ void ViMode_Save(ViMode* viMode) {
}
void ViMode_Load(ViMode* viMode) {
- if ((SREG(49) & ~3) == 1) {
- SREG(49) += 4;
+ //! @bug This condition never passes as the lowest bit is always masked out to 0
+ if ((R_VI_MODE_EDIT_WIDTH & ~3) == 1) {
+ R_VI_MODE_EDIT_WIDTH += 4;
}
- viMode->viModeBase = SREG(48);
- viMode->viWidth = SREG(49) & ~3;
- viMode->viHeight = SREG(50);
- viMode->unk_64 = SREG(51);
- viMode->unk_60 = SREG(52);
- viMode->unk_5C = SREG(53);
- viMode->unk_58 = SREG(54);
+ viMode->editState = R_VI_MODE_EDIT_STATE;
+ viMode->viWidth = R_VI_MODE_EDIT_WIDTH & ~3;
+ viMode->viHeight = R_VI_MODE_EDIT_HEIGHT;
+ viMode->upperAdjust = R_VI_MODE_EDIT_ULY_ADJ;
+ viMode->lowerAdjust = R_VI_MODE_EDIT_LRY_ADJ;
+ viMode->leftAdjust = R_VI_MODE_EDIT_ULX_ADJ;
+ viMode->rightAdjust = R_VI_MODE_EDIT_LRX_ADJ;
}
void ViMode_Init(ViMode* viMode) {
- viMode->viModeBase = 0;
+ viMode->editState = VI_MODE_EDIT_STATE_INACTIVE;
viMode->viWidth = SCREEN_WIDTH;
viMode->viHeight = SCREEN_HEIGHT;
- viMode->unk_5C = 0;
- viMode->unk_58 = 0;
- viMode->unk_64 = 0;
- viMode->unk_60 = 0;
+ viMode->leftAdjust = 0;
+ viMode->rightAdjust = 0;
+ viMode->upperAdjust = 0;
+ viMode->lowerAdjust = 0;
viMode->viFeatures = OS_VI_DITHER_FILTER_ON | OS_VI_GAMMA_OFF;
- viMode->viTvType = osTvType;
- viMode->unk_7C = true;
- viMode->unk_78 = true;
- viMode->unk_74 = false;
- viMode->unk_70 = true;
+ viMode->tvType = osTvType;
+ viMode->fb16Bit = true;
+ viMode->modeN = true;
+ viMode->antialiasOff = false;
+ viMode->loRes = true;
ViMode_Save(viMode);
}
@@ -209,113 +242,140 @@ void ViMode_ConfigureFeatures(ViMode* viMode, s32 viFeatures) {
u32 ctrl = viMode->customViMode.comRegs.ctrl;
if (viFeatures & OS_VI_GAMMA_ON) {
- ctrl |= OS_VI_GAMMA;
+ ctrl |= VI_CTRL_GAMMA_ON;
}
if (viFeatures & OS_VI_GAMMA_OFF) {
- ctrl &= ~OS_VI_GAMMA;
+ ctrl &= ~VI_CTRL_GAMMA_ON;
}
if (viFeatures & OS_VI_GAMMA_DITHER_ON) {
- ctrl |= OS_VI_GAMMA_DITHER;
+ ctrl |= VI_CTRL_GAMMA_DITHER_ON;
}
if (viFeatures & OS_VI_GAMMA_DITHER_OFF) {
- ctrl &= ~OS_VI_GAMMA_DITHER;
+ ctrl &= ~VI_CTRL_GAMMA_DITHER_ON;
}
if (viFeatures & OS_VI_DIVOT_ON) {
- ctrl |= OS_VI_DIVOT;
+ ctrl |= VI_CTRL_DIVOT_ON;
}
if (viFeatures & OS_VI_DIVOT_OFF) {
- ctrl &= ~OS_VI_DIVOT;
+ ctrl &= ~VI_CTRL_DIVOT_ON;
}
viMode->customViMode.comRegs.ctrl = ctrl;
}
-// This function uses controller input (C buttons + D pad) to reconfigure the custom VI mode
+/**
+ * Updates the custom VI mode with controller input and any edits made with the REG editor
+ * (through R_VI_MODE_EDIT_* entries)
+ */
void ViMode_Update(ViMode* viMode, Input* input) {
+ // Load state from REGs
ViMode_Load(viMode);
- if ((viMode->viModeBase == 1) || (viMode->viModeBase == 2) || (viMode->viModeBase == 3)) {
+
+ if ((viMode->editState == VI_MODE_EDIT_STATE_ACTIVE) || (viMode->editState == VI_MODE_EDIT_STATE_2) ||
+ (viMode->editState == VI_MODE_EDIT_STATE_3)) {
gScreenWidth = viMode->viWidth;
gScreenHeight = viMode->viHeight;
+
+ // Controls to reset the ViMode to defaults
if (CHECK_BTN_ALL(input->cur.button, BTN_START | BTN_CUP | BTN_CRIGHT)) {
ViMode_Init(viMode);
}
+
+ // Controls to adjust the screen dimensions (upper-left)
if (CHECK_BTN_ALL(input->cur.button, BTN_CUP)) {
+ // upper
if (CHECK_BTN_ALL(input->cur.button, BTN_DUP)) {
- viMode->unk_64--;
+ viMode->upperAdjust--;
}
if (CHECK_BTN_ALL(input->cur.button, BTN_DDOWN)) {
- viMode->unk_64++;
+ viMode->upperAdjust++;
}
+ // left
if (CHECK_BTN_ALL(input->cur.button, BTN_DLEFT)) {
- viMode->unk_5C--;
+ viMode->leftAdjust--;
}
if (CHECK_BTN_ALL(input->cur.button, BTN_DRIGHT)) {
- viMode->unk_5C++;
+ viMode->leftAdjust++;
}
}
+
+ // Controls to adjust the screen dimensions (lower-right)
if (CHECK_BTN_ALL(input->cur.button, BTN_CRIGHT)) {
+ // lower
if (CHECK_BTN_ALL(input->cur.button, BTN_DUP)) {
- viMode->unk_60--;
+ viMode->lowerAdjust--;
}
if (CHECK_BTN_ALL(input->cur.button, BTN_DDOWN)) {
- viMode->unk_60++;
+ viMode->lowerAdjust++;
}
+ // right
if (CHECK_BTN_ALL(input->cur.button, BTN_DLEFT)) {
- viMode->unk_58--;
+ viMode->rightAdjust--;
}
if (CHECK_BTN_ALL(input->cur.button, BTN_DRIGHT)) {
- viMode->unk_58++;
+ viMode->rightAdjust++;
}
}
+
+ // Controls to adjust key features
if (CHECK_BTN_ALL(input->cur.button, BTN_CDOWN)) {
if (CHECK_BTN_ALL(input->press.button, BTN_DUP)) {
- viMode->unk_70 = !viMode->unk_70;
+ viMode->loRes = !viMode->loRes;
}
if (CHECK_BTN_ALL(input->press.button, BTN_DDOWN)) {
- viMode->unk_74 = !viMode->unk_74;
+ viMode->antialiasOff = !viMode->antialiasOff;
}
if (CHECK_BTN_ALL(input->press.button, BTN_DLEFT)) {
- viMode->unk_78 = !viMode->unk_78;
+ viMode->modeN = !viMode->modeN;
}
if (CHECK_BTN_ALL(input->press.button, BTN_DRIGHT)) {
- viMode->unk_7C = !viMode->unk_7C;
+ viMode->fb16Bit = !viMode->fb16Bit;
}
}
- if (viMode->viModeBase >= 2) {
- if (viMode->unk_5C < -16) {
- viMode->unk_5C = -16;
+
+ // Clamp adjustments
+ if (viMode->editState >= VI_MODE_EDIT_STATE_2) {
+ // Allow parts of the framebuffer to possibly be offscreen by a small margin
+ if (viMode->leftAdjust < -16) {
+ viMode->leftAdjust = -16;
}
- if (viMode->unk_64 < -50) {
- viMode->unk_64 = -50;
+ if (viMode->upperAdjust < -50) {
+ viMode->upperAdjust = -50;
}
- if (viMode->unk_58 > 16) {
- viMode->unk_58 = 16;
+ if (viMode->rightAdjust > 16) {
+ viMode->rightAdjust = 16;
}
- if (viMode->unk_60 > 50) {
- viMode->unk_60 = 50;
+ if (viMode->lowerAdjust > 50) {
+ viMode->lowerAdjust = 50;
}
} else {
- if (viMode->unk_5C < 0) {
- viMode->unk_5C = 0;
+ // Do not allow parts of the framebuffer to end up offscreen
+ if (viMode->leftAdjust < 0) {
+ viMode->leftAdjust = 0;
}
- if (viMode->unk_64 < 0) {
- viMode->unk_64 = 0;
+ if (viMode->upperAdjust < 0) {
+ viMode->upperAdjust = 0;
}
- if (viMode->unk_58 > 0) {
- viMode->unk_58 = 0;
+ if (viMode->rightAdjust > 0) {
+ viMode->rightAdjust = 0;
}
- if (viMode->unk_60 > 0) {
- viMode->unk_60 = 0;
+ if (viMode->lowerAdjust > 0) {
+ viMode->lowerAdjust = 0;
}
}
- ViMode_Configure(viMode, OS_VI_UNK28, osTvType, viMode->unk_70, viMode->unk_74, viMode->unk_78, viMode->unk_7C,
- viMode->viWidth, viMode->viHeight, viMode->unk_5C, viMode->unk_58, viMode->unk_64,
- viMode->unk_60);
+
+ // Configure the custom VI mode with the selected settings
+ ViMode_Configure(viMode, OS_VI_MPAL_LPN1, osTvType, viMode->loRes, viMode->antialiasOff, viMode->modeN,
+ viMode->fb16Bit, viMode->viWidth, viMode->viHeight, viMode->leftAdjust, viMode->rightAdjust,
+ viMode->upperAdjust, viMode->lowerAdjust);
ViMode_ConfigureFeatures(viMode, viMode->viFeatures);
- if (viMode->viModeBase == 3) {
+
+ if (viMode->editState == VI_MODE_EDIT_STATE_3) {
+ // Log comparison between the NTSC LAN1 mode and the custom mode
ViMode_LogPrint(&osViModeNtscLan1);
ViMode_LogPrint(&viMode->customViMode);
- viMode->viModeBase = 2;
+ viMode->editState = VI_MODE_EDIT_STATE_2;
}
}
+ // Save new state to REGs for interactive runtime editing
ViMode_Save(viMode);
}
diff --git a/src/libultra/gu/sintable.inc.c b/src/libultra/gu/sintable.inc.c
index d430d65ae3..2753d55a98 100644
--- a/src/libultra/gu/sintable.inc.c
+++ b/src/libultra/gu/sintable.inc.c
@@ -1,4 +1,4 @@
-#include "ultra64/types.h"
+#include "ultra64/ultratypes.h"
static s16 sintable[0x400] = {
0x0000, 0x0032, 0x0064, 0x0096, 0x00C9, 0x00FB, 0x012D, 0x0160, 0x0192, 0x01C4, 0x01F7, 0x0229, 0x025B, 0x028E,
diff --git a/src/libultra/io/aigetlen.c b/src/libultra/io/aigetlen.c
index 58d8db4875..45be442516 100644
--- a/src/libultra/io/aigetlen.c
+++ b/src/libultra/io/aigetlen.c
@@ -1,5 +1,11 @@
#include "global.h"
+/**
+ * Returns the number of bytes remaining in a currently ongoing audio DMA.
+ *
+ * Note that audio DMA is double-buffered, a DMA can be queued while another is in-progress. This only returns
+ * information about the currently in-progress DMA.
+ */
u32 osAiGetLength(void) {
- return HW_REG(AI_LEN_REG, u32);
+ return IO_READ(AI_LEN_REG);
}
diff --git a/src/libultra/io/aisetfreq.c b/src/libultra/io/aisetfreq.c
index 8702941b9a..9e1b8c44e2 100644
--- a/src/libultra/io/aisetfreq.c
+++ b/src/libultra/io/aisetfreq.c
@@ -1,20 +1,35 @@
#include "global.h"
+/**
+ * Programs the operating frequency of the Audio DAC.
+ *
+ * @param frequency Target Playback frequency.
+ * @return The actual playback frequency, or -1 if the supplied frequency cannot be used.
+ */
s32 osAiSetFrequency(u32 frequency) {
- u8 bitrate;
+ // Calculate the DAC sample period ("dperiod") (dperiod + 1 = vid_clock / frequency)
f32 dacRateF = ((f32)osViClock / frequency) + 0.5f;
+ u8 bitrate;
u32 dacRate = dacRateF;
- if (dacRate < 132) {
+ // Upcoming division by 66. If dacRate is smaller than 2 * 66 = 132, bitrate will be 1 and AI_BITRATE_REG will be
+ // programmed with 0, which results in no audio output. Return -1 to indicate an unusable frequency.
+ if (dacRate < AI_MIN_DAC_RATE) {
return -1;
}
+ // Calculate the largest "bitrate" (ABUS clock half period, "aclockhp") supported for this dacrate. These two
+ // quantities must satisfy (dperiod + 1) >= 66 * (aclockhp + 1), here this is taken as equality.
bitrate = (dacRate / 66);
- if (bitrate > 16) {
- bitrate = 16;
+ // Clamp to max value
+ if (bitrate > AI_MAX_BIT_RATE) {
+ bitrate = AI_MAX_BIT_RATE;
}
- HW_REG(AI_DACRATE_REG, u32) = dacRate - 1;
- HW_REG(AI_BITRATE_REG, u32) = bitrate - 1;
+ IO_WRITE(AI_DACRATE_REG, dacRate - 1);
+ IO_WRITE(AI_BITRATE_REG, bitrate - 1);
+
+ // Return the true playback frequency (frequency = vid_clock / (dperiod + 1)), which may differ from the target
+ // frequency.
return osViClock / (s32)dacRate;
}
diff --git a/src/libultra/io/aisetnextbuf.c b/src/libultra/io/aisetnextbuf.c
index 56a7e4e6e0..4cf5d1f7d9 100644
--- a/src/libultra/io/aisetnextbuf.c
+++ b/src/libultra/io/aisetnextbuf.c
@@ -1,31 +1,44 @@
#include "global.h"
-//! Note that this is not the same as the original libultra
-//! osAiSetNextBuffer, see comments in the function
-
+/**
+ * Submits an audio buffer to be consumed by the Audio DAC. The audio interface can queue a second DMA while another
+ * is in progress and automatically begin the next one as soon as the current DMA completes. If there is already a
+ * second DMA queued (DMA is full), -1 is returned to indicate the buffer could not be submitted.
+ *
+ * Note that this is not the same as the original libultra osAiSetNextBuffer, see comments in the function.
+ *
+ * @param buf Next audio buffer. Must be an 8-byte aligned KSEG0 (0x80XXXXXX) address.
+ * @param size Length of next audio buffer in bytes, maximum size 0x40000 bytes / 256 KiB. Should be a multiple of 8.
+ * @return 0 if the DMA was enqueued successfully, -1 if the DMA could not yet be queued.
+ */
s32 osAiSetNextBuffer(void* buf, u32 size) {
- static u8 D_80130500 = false;
+ static u8 hdwrBugFlag = false;
u32 bufAdjusted = (u32)buf;
s32 status;
- if (D_80130500) {
- bufAdjusted = (u32)buf - 0x2000;
+ // Workaround for a hardware bug. If the end of the previous buffer was on an 0x2000 byte boundary, adjust the
+ // start of the next buffer.
+ if (hdwrBugFlag) {
+ bufAdjusted -= 0x2000;
}
+ // Current buffer ends on an 0x2000 byte boundary, set flag to account for this in next buffer.
if ((((u32)buf + size) & 0x1FFF) == 0) {
- D_80130500 = true;
+ hdwrBugFlag = true;
} else {
- D_80130500 = false;
+ hdwrBugFlag = false;
}
// Originally a call to __osAiDeviceBusy
- status = HW_REG(AI_STATUS_REG, s32);
- if (status & AI_STATUS_AI_FULL) {
+ //! @bug The original __osAiDeviceBusy call was above the hardware bug workaround to ensure that it was only
+ //! performed when a transfer was guaranteed to start. If this condition passes and this function returns without
+ //! submitting a buffer for DMA, the code above will lose track of when to apply the workaround.
+ status = IO_READ(AI_STATUS_REG);
+ if (status & AI_STATUS_FIFO_FULL) {
return -1;
}
- // OS_K0_TO_PHYSICAL replaces osVirtualToPhysical, this replacement
- // assumes that only KSEG0 addresses are given
- HW_REG(AI_DRAM_ADDR_REG, u32) = OS_K0_TO_PHYSICAL(bufAdjusted);
- HW_REG(AI_LEN_REG, u32) = size;
+ // OS_K0_TO_PHYSICAL replaces osVirtualToPhysical, this replacement assumes that only KSEG0 addresses are given.
+ IO_WRITE(AI_DRAM_ADDR_REG, OS_K0_TO_PHYSICAL(bufAdjusted));
+ IO_WRITE(AI_LEN_REG, size);
return 0;
}
diff --git a/src/libultra/io/cartrominit.c b/src/libultra/io/cartrominit.c
index 231b007680..b2cf1d1e17 100644
--- a/src/libultra/io/cartrominit.c
+++ b/src/libultra/io/cartrominit.c
@@ -3,55 +3,54 @@
OSPiHandle __CartRomHandle;
OSPiHandle* osCartRomInit(void) {
- register u32 a;
+ static u32 first = true;
+ register u32 value;
register s32 status;
register u32 prevInt;
- register u32 lastLatency;
- register u32 lastPageSize;
- register u32 lastRelDuration;
- register u32 lastPulse;
-
- static u32 D_8000AF10 = 1;
+ register u32 latency;
+ register u32 pageSize;
+ register u32 relDuration;
+ register u32 pulse;
__osPiGetAccess();
- if (!D_8000AF10) {
+ if (!first) {
__osPiRelAccess();
return &__CartRomHandle;
}
- D_8000AF10 = 0;
+ first = false;
__CartRomHandle.type = DEVICE_TYPE_CART;
- __CartRomHandle.baseAddress = 0xB0000000;
+ __CartRomHandle.baseAddress = PHYS_TO_K1(PI_DOM1_ADDR2);
__CartRomHandle.domain = PI_DOMAIN1;
__CartRomHandle.speed = 0;
bzero(&__CartRomHandle.transferInfo, sizeof(__OSTranxInfo));
- status = HW_REG(PI_STATUS_REG, u32);
- while (status & (PI_STATUS_BUSY | PI_STATUS_IOBUSY)) {
- status = HW_REG(PI_STATUS_REG, u32);
+ status = IO_READ(PI_STATUS_REG);
+ while (status & (PI_STATUS_DMA_BUSY | PI_STATUS_IO_BUSY)) {
+ status = IO_READ(PI_STATUS_REG);
}
- lastLatency = HW_REG(PI_BSD_DOM1_LAT_REG, u32);
- lastPageSize = HW_REG(PI_BSD_DOM1_PGS_REG, u32);
- lastRelDuration = HW_REG(PI_BSD_DOM1_RLS_REG, u32);
- lastPulse = HW_REG(PI_BSD_DOM1_PWD_REG, u32);
+ latency = IO_READ(PI_BSD_DOM1_LAT_REG);
+ pageSize = IO_READ(PI_BSD_DOM1_PGS_REG);
+ relDuration = IO_READ(PI_BSD_DOM1_RLS_REG);
+ pulse = IO_READ(PI_BSD_DOM1_PWD_REG);
- HW_REG(PI_BSD_DOM1_LAT_REG, u32) = 0xFF;
- HW_REG(PI_BSD_DOM1_PGS_REG, u32) = 0;
- HW_REG(PI_BSD_DOM1_RLS_REG, u32) = 3;
- HW_REG(PI_BSD_DOM1_PWD_REG, u32) = 0xFF;
+ IO_WRITE(PI_BSD_DOM1_LAT_REG, 255);
+ IO_WRITE(PI_BSD_DOM1_PGS_REG, 0);
+ IO_WRITE(PI_BSD_DOM1_RLS_REG, 3);
+ IO_WRITE(PI_BSD_DOM1_PWD_REG, 255);
- a = HW_REG(__CartRomHandle.baseAddress, u32);
- __CartRomHandle.latency = a & 0xFF;
- __CartRomHandle.pageSize = (a >> 0x10) & 0xF;
- __CartRomHandle.relDuration = (a >> 0x14) & 0xF;
- __CartRomHandle.pulse = (a >> 8) & 0xFF;
+ value = IO_READ(__CartRomHandle.baseAddress);
+ __CartRomHandle.latency = value & 0xFF;
+ __CartRomHandle.pageSize = (value >> 0x10) & 0xF;
+ __CartRomHandle.relDuration = (value >> 0x14) & 0xF;
+ __CartRomHandle.pulse = (value >> 8) & 0xFF;
- HW_REG(PI_BSD_DOM1_LAT_REG, u32) = lastLatency;
- HW_REG(PI_BSD_DOM1_PGS_REG, u32) = lastPageSize;
- HW_REG(PI_BSD_DOM1_RLS_REG, u32) = lastRelDuration;
- HW_REG(PI_BSD_DOM1_PWD_REG, u32) = lastPulse;
+ IO_WRITE(PI_BSD_DOM1_LAT_REG, latency);
+ IO_WRITE(PI_BSD_DOM1_PGS_REG, pageSize);
+ IO_WRITE(PI_BSD_DOM1_RLS_REG, relDuration);
+ IO_WRITE(PI_BSD_DOM1_PWD_REG, pulse);
prevInt = __osDisableInt();
__CartRomHandle.next = __osPiTable;
diff --git a/src/libultra/io/devmgr.c b/src/libultra/io/devmgr.c
index e8581d821e..d0e7d5289a 100644
--- a/src/libultra/io/devmgr.c
+++ b/src/libultra/io/devmgr.c
@@ -1,97 +1,110 @@
#include "global.h"
#include "ultra64/internal.h"
+#include "ultra64/leodrive.h"
+
+// os.h
+#define LEO_BLOCK_MODE 1
+#define LEO_TRACK_MODE 2
+#define LEO_SECTOR_MODE 3
void __osDevMgrMain(void* arg) {
- OSIoMesg* ioMesg;
- OSMesg sp70;
- OSMesg sp6C;
- OSMgrArgs* arg0 = (OSMgrArgs*)arg;
- __OSTranxInfo* transfer;
- __OSBlockInfo* block;
- s32 phi_s2;
- s32 phi_s0;
- u32 sp54;
-
- ioMesg = NULL;
+ OSIoMesg* ioMesg = NULL;
+ OSMesg em;
+ OSMesg dummy;
+ s32 ret;
+ OSDevMgr* dm = (OSDevMgr*)arg;
+ s32 messageSend;
while (true) {
- osRecvMesg(arg0->cmdQueue, (OSMesg*)&ioMesg, OS_MESG_BLOCK);
+ osRecvMesg(dm->cmdQueue, (OSMesg*)&ioMesg, OS_MESG_BLOCK);
+
if ((ioMesg->piHandle != NULL) && (ioMesg->piHandle->type == DEVICE_TYPE_64DD) &&
((ioMesg->piHandle->transferInfo.cmdType == 0) || (ioMesg->piHandle->transferInfo.cmdType == 1))) {
- transfer = &ioMesg->piHandle->transferInfo;
- block = &transfer->block[transfer->blockNum];
- transfer->sectorNum = -1;
- if (transfer->transferMode != 3) {
- block->dramAddr = (void*)((u32)block->dramAddr - block->sectorSize);
+ __OSBlockInfo* blockInfo;
+ __OSTranxInfo* info;
+
+ info = &ioMesg->piHandle->transferInfo;
+ blockInfo = &info->block[info->blockNum];
+ info->sectorNum = -1;
+
+ if (info->transferMode != LEO_SECTOR_MODE) {
+ blockInfo->dramAddr = (void*)((u32)blockInfo->dramAddr - blockInfo->sectorSize);
}
- phi_s2 = ((transfer->transferMode == 2) && (ioMesg->piHandle->transferInfo.cmdType == 0)) ? 1 : 0;
+ if (info->transferMode == LEO_TRACK_MODE && ioMesg->piHandle->transferInfo.cmdType == 0) {
+ messageSend = 1;
+ } else {
+ messageSend = 0;
+ }
- osRecvMesg(arg0->acccessQueue, &sp6C, OS_MESG_BLOCK);
+ osRecvMesg(dm->acsQueue, &dummy, OS_MESG_BLOCK);
__osResetGlobalIntMask(OS_IM_PI);
- __osEPiRawWriteIo(ioMesg->piHandle, 0x05000510, transfer->bmCtlShadow | 0x80000000);
+ __osEPiRawWriteIo(ioMesg->piHandle, ASIC_BM_CTL, info->bmCtlShadow | LEO_BM_START);
- while (true) {
- osRecvMesg(arg0->eventQueue, &sp70, OS_MESG_BLOCK);
- transfer = &ioMesg->piHandle->transferInfo;
- block = &transfer->block[transfer->blockNum];
- if (block->errStatus == 0x1D) {
- __osEPiRawWriteIo(ioMesg->piHandle, 0x05000510, transfer->bmCtlShadow | 0x10000000);
- __osEPiRawWriteIo(ioMesg->piHandle, 0x05000510, transfer->bmCtlShadow);
- __osEPiRawReadIo(ioMesg->piHandle, 0x05000508, &sp54);
- if (sp54 & 0x02000000) {
- __osEPiRawWriteIo(ioMesg->piHandle, 0x05000510, transfer->bmCtlShadow | 0x1000000);
- }
- block->errStatus = 4;
- HW_REG(PI_STATUS_REG, u32) = PI_STATUS_CLR_INTR;
- __osSetGlobalIntMask(OS_IM_CART | OS_IM_PI);
+ readblock1:
+ osRecvMesg(dm->evtQueue, &em, OS_MESG_BLOCK);
+
+ info = &ioMesg->piHandle->transferInfo;
+ blockInfo = &info->block[info->blockNum];
+
+ if (blockInfo->errStatus == 29) {
+ u32 stat;
+
+ __osEPiRawWriteIo(ioMesg->piHandle, ASIC_BM_CTL, info->bmCtlShadow | LEO_BM_RESET);
+ __osEPiRawWriteIo(ioMesg->piHandle, ASIC_BM_CTL, info->bmCtlShadow);
+ __osEPiRawReadIo(ioMesg->piHandle, ASIC_STATUS, &stat);
+
+ if (stat & LEO_STATUS_MECHANIC_INTR) {
+ __osEPiRawWriteIo(ioMesg->piHandle, ASIC_BM_CTL, info->bmCtlShadow | LEO_BM_CLR_MECHANIC_INTR);
}
- osSendMesg(ioMesg->hdr.retQueue, (OSMesg)ioMesg, OS_MESG_NOBLOCK);
+ blockInfo->errStatus = 4;
- if ((phi_s2 != 1) || (ioMesg->piHandle->transferInfo.block[0].errStatus != 0)) {
- break;
- }
+ IO_WRITE(PI_STATUS_REG, PI_STATUS_CLR_INTR);
+ __osSetGlobalIntMask(OS_IM_CART | OS_IM_PI);
+ }
+ osSendMesg(ioMesg->hdr.retQueue, (OSMesg)ioMesg, OS_MESG_NOBLOCK);
- phi_s2 = 0;
+ if (messageSend == 1 && ioMesg->piHandle->transferInfo.block[0].errStatus == 0) {
+ // Run the above once more
+ messageSend = 0;
+ goto readblock1;
}
- osSendMesg(arg0->acccessQueue, NULL, OS_MESG_NOBLOCK);
+ osSendMesg(dm->acsQueue, NULL, OS_MESG_NOBLOCK);
if (ioMesg->piHandle->transferInfo.blockNum == 1) {
osYieldThread();
}
} else {
switch (ioMesg->hdr.type) {
case OS_MESG_TYPE_DMAREAD:
- osRecvMesg(arg0->acccessQueue, &sp6C, OS_MESG_BLOCK);
- phi_s0 = arg0->piDmaCallback(OS_READ, ioMesg->devAddr, ioMesg->dramAddr, ioMesg->size);
+ osRecvMesg(dm->acsQueue, &dummy, OS_MESG_BLOCK);
+ ret = dm->dma(OS_READ, ioMesg->devAddr, ioMesg->dramAddr, ioMesg->size);
break;
case OS_MESG_TYPE_DMAWRITE:
- osRecvMesg(arg0->acccessQueue, &sp6C, OS_MESG_BLOCK);
- phi_s0 = arg0->piDmaCallback(OS_WRITE, ioMesg->devAddr, ioMesg->dramAddr, ioMesg->size);
+ osRecvMesg(dm->acsQueue, &dummy, OS_MESG_BLOCK);
+ ret = dm->dma(OS_WRITE, ioMesg->devAddr, ioMesg->dramAddr, ioMesg->size);
break;
case OS_MESG_TYPE_EDMAREAD:
- osRecvMesg(arg0->acccessQueue, &sp6C, OS_MESG_BLOCK);
- phi_s0 = arg0->epiDmaCallback(ioMesg->piHandle, OS_READ, ioMesg->devAddr, ioMesg->dramAddr,
- ioMesg->size);
+ osRecvMesg(dm->acsQueue, &dummy, OS_MESG_BLOCK);
+ ret = dm->edma(ioMesg->piHandle, OS_READ, ioMesg->devAddr, ioMesg->dramAddr, ioMesg->size);
break;
case OS_MESG_TYPE_EDMAWRITE:
- osRecvMesg(arg0->acccessQueue, &sp6C, OS_MESG_BLOCK);
- phi_s0 = arg0->epiDmaCallback(ioMesg->piHandle, OS_WRITE, ioMesg->devAddr, ioMesg->dramAddr,
- ioMesg->size);
+ osRecvMesg(dm->acsQueue, &dummy, OS_MESG_BLOCK);
+ ret = dm->edma(ioMesg->piHandle, OS_WRITE, ioMesg->devAddr, ioMesg->dramAddr, ioMesg->size);
break;
case OS_MESG_TYPE_LOOPBACK:
osSendMesg(ioMesg->hdr.retQueue, (OSMesg)ioMesg, OS_MESG_NOBLOCK);
- phi_s0 = -1;
+ ret = -1;
break;
default:
- phi_s0 = -1;
+ ret = -1;
break;
}
- if (phi_s0 == 0) {
- osRecvMesg(arg0->eventQueue, &sp70, OS_MESG_BLOCK);
+ if (ret == 0) {
+ osRecvMesg(dm->evtQueue, &em, OS_MESG_BLOCK);
osSendMesg(ioMesg->hdr.retQueue, (OSMesg)ioMesg, OS_MESG_NOBLOCK);
- osSendMesg(arg0->acccessQueue, NULL, OS_MESG_NOBLOCK);
+ osSendMesg(dm->acsQueue, NULL, OS_MESG_NOBLOCK);
}
}
}
diff --git a/src/libultra/io/dpgetstat.c b/src/libultra/io/dpgetstat.c
index b5267b060d..1a944b2c7a 100644
--- a/src/libultra/io/dpgetstat.c
+++ b/src/libultra/io/dpgetstat.c
@@ -1,5 +1,5 @@
#include "global.h"
u32 osDpGetStatus(void) {
- return DPC_STATUS_REG;
+ return IO_READ(DPC_STATUS_REG);
}
diff --git a/src/libultra/io/dpsetstat.c b/src/libultra/io/dpsetstat.c
index ecd3f77e07..4275e1fde6 100644
--- a/src/libultra/io/dpsetstat.c
+++ b/src/libultra/io/dpsetstat.c
@@ -1,5 +1,5 @@
#include "global.h"
void osDpSetStatus(u32 status) {
- DPC_STATUS_REG = status;
+ IO_WRITE(DPC_STATUS_REG, status);
}
diff --git a/src/libultra/io/driverominit.c b/src/libultra/io/driverominit.c
index d6247298ae..7d1441cdd9 100644
--- a/src/libultra/io/driverominit.c
+++ b/src/libultra/io/driverominit.c
@@ -3,45 +3,45 @@
OSPiHandle __DriveRomHandle;
OSPiHandle* osDriveRomInit(void) {
+ static u32 first = true;
register s32 status;
- register u32 a;
+ register u32 value;
register u32 prevInt;
- static u32 D_8000AC70 = 1;
__osPiGetAccess();
- if (!D_8000AC70) {
+ if (!first) {
__osPiRelAccess();
return &__DriveRomHandle;
}
- D_8000AC70 = 0;
+ first = false;
__DriveRomHandle.type = DEVICE_TYPE_BULK;
- __DriveRomHandle.baseAddress = 0xA6000000;
+ __DriveRomHandle.baseAddress = PHYS_TO_K1(PI_DOM1_ADDR1);
__DriveRomHandle.domain = PI_DOMAIN1;
__DriveRomHandle.speed = 0;
bzero(&__DriveRomHandle.transferInfo, sizeof(__OSTranxInfo));
- status = HW_REG(PI_STATUS_REG, u32);
- while (status & (PI_STATUS_BUSY | PI_STATUS_IOBUSY)) {
- status = HW_REG(PI_STATUS_REG, u32);
+ status = IO_READ(PI_STATUS_REG);
+ while (status & (PI_STATUS_DMA_BUSY | PI_STATUS_IO_BUSY)) {
+ status = IO_READ(PI_STATUS_REG);
}
- HW_REG(PI_BSD_DOM1_LAT_REG, u32) = 0xFF;
- HW_REG(PI_BSD_DOM1_PGS_REG, u32) = 0;
- HW_REG(PI_BSD_DOM1_RLS_REG, u32) = 3;
- HW_REG(PI_BSD_DOM1_PWD_REG, u32) = 0xFF;
+ IO_WRITE(PI_BSD_DOM1_LAT_REG, 255);
+ IO_WRITE(PI_BSD_DOM1_PGS_REG, 0);
+ IO_WRITE(PI_BSD_DOM1_RLS_REG, 3);
+ IO_WRITE(PI_BSD_DOM1_PWD_REG, 255);
- a = HW_REG(__DriveRomHandle.baseAddress, u32);
- __DriveRomHandle.latency = a & 0xFF;
- __DriveRomHandle.pulse = (a >> 8) & 0xFF;
- __DriveRomHandle.pageSize = (a >> 0x10) & 0xF;
- __DriveRomHandle.relDuration = (a >> 0x14) & 0xF;
+ value = IO_READ(__DriveRomHandle.baseAddress);
+ __DriveRomHandle.latency = value & 0xFF;
+ __DriveRomHandle.pulse = (value >> 8) & 0xFF;
+ __DriveRomHandle.pageSize = (value >> 0x10) & 0xF;
+ __DriveRomHandle.relDuration = (value >> 0x14) & 0xF;
- HW_REG(PI_BSD_DOM1_LAT_REG, u32) = (u8)a;
- HW_REG(PI_BSD_DOM1_PGS_REG, u32) = __DriveRomHandle.pageSize;
- HW_REG(PI_BSD_DOM1_RLS_REG, u32) = __DriveRomHandle.relDuration;
- HW_REG(PI_BSD_DOM1_PWD_REG, u32) = __DriveRomHandle.pulse;
+ IO_WRITE(PI_BSD_DOM1_LAT_REG, __DriveRomHandle.latency);
+ IO_WRITE(PI_BSD_DOM1_PGS_REG, __DriveRomHandle.pageSize);
+ IO_WRITE(PI_BSD_DOM1_RLS_REG, __DriveRomHandle.relDuration);
+ IO_WRITE(PI_BSD_DOM1_PWD_REG, __DriveRomHandle.pulse);
__osCurrentHandle[__DriveRomHandle.domain]->type = __DriveRomHandle.type;
__osCurrentHandle[__DriveRomHandle.domain]->latency = __DriveRomHandle.latency;
diff --git a/src/libultra/io/epidma.c b/src/libultra/io/epidma.c
index 41b39caa9d..28565e72c0 100644
--- a/src/libultra/io/epidma.c
+++ b/src/libultra/io/epidma.c
@@ -4,7 +4,7 @@
s32 osEPiStartDma(OSPiHandle* handle, OSIoMesg* mb, s32 direction) {
s32 ret;
- if (!__osPiDevMgr.initialized) {
+ if (!__osPiDevMgr.active) {
return -1;
}
diff --git a/src/libultra/io/epirawdma.c b/src/libultra/io/epirawdma.c
index ccc23f7085..ff6bb9a653 100644
--- a/src/libultra/io/epirawdma.c
+++ b/src/libultra/io/epirawdma.c
@@ -4,9 +4,9 @@ s32 __osEPiRawStartDma(OSPiHandle* handle, s32 direction, u32 cartAddr, void* dr
s32 status;
OSPiHandle* curHandle;
- status = HW_REG(PI_STATUS_REG, u32);
- while (status & (PI_STATUS_BUSY | PI_STATUS_IOBUSY)) {
- status = HW_REG(PI_STATUS_REG, u32);
+ status = IO_READ(PI_STATUS_REG);
+ while (status & (PI_STATUS_DMA_BUSY | PI_STATUS_IO_BUSY)) {
+ status = IO_READ(PI_STATUS_REG);
}
if (__osCurrentHandle[handle->domain]->type != handle->type) {
@@ -14,35 +14,35 @@ s32 __osEPiRawStartDma(OSPiHandle* handle, s32 direction, u32 cartAddr, void* dr
if (handle->domain == 0) {
if (curHandle->latency != handle->latency) {
- HW_REG(PI_BSD_DOM1_LAT_REG, u32) = handle->latency;
+ IO_WRITE(PI_BSD_DOM1_LAT_REG, handle->latency);
}
if (curHandle->pageSize != handle->pageSize) {
- HW_REG(PI_BSD_DOM1_PGS_REG, u32) = handle->pageSize;
+ IO_WRITE(PI_BSD_DOM1_PGS_REG, handle->pageSize);
}
if (curHandle->relDuration != handle->relDuration) {
- HW_REG(PI_BSD_DOM1_RLS_REG, u32) = handle->relDuration;
+ IO_WRITE(PI_BSD_DOM1_RLS_REG, handle->relDuration);
}
if (curHandle->pulse != handle->pulse) {
- HW_REG(PI_BSD_DOM1_PWD_REG, u32) = handle->pulse;
+ IO_WRITE(PI_BSD_DOM1_PWD_REG, handle->pulse);
}
} else {
if (curHandle->latency != handle->latency) {
- HW_REG(PI_BSD_DOM2_LAT_REG, u32) = handle->latency;
+ IO_WRITE(PI_BSD_DOM2_LAT_REG, handle->latency);
}
if (curHandle->pageSize != handle->pageSize) {
- HW_REG(PI_BSD_DOM2_PGS_REG, u32) = handle->pageSize;
+ IO_WRITE(PI_BSD_DOM2_PGS_REG, handle->pageSize);
}
if (curHandle->relDuration != handle->relDuration) {
- HW_REG(PI_BSD_DOM2_RLS_REG, u32) = handle->relDuration;
+ IO_WRITE(PI_BSD_DOM2_RLS_REG, handle->relDuration);
}
if (curHandle->pulse != handle->pulse) {
- HW_REG(PI_BSD_DOM2_PWD_REG, u32) = handle->pulse;
+ IO_WRITE(PI_BSD_DOM2_PWD_REG, handle->pulse);
}
}
@@ -53,20 +53,18 @@ s32 __osEPiRawStartDma(OSPiHandle* handle, s32 direction, u32 cartAddr, void* dr
curHandle->pulse = handle->pulse;
}
- HW_REG(PI_DRAM_ADDR_REG, void*) = (void*)osVirtualToPhysical(dramAddr);
- HW_REG(PI_CART_ADDR_REG, void*) = (void*)((handle->baseAddress | cartAddr) & 0x1FFFFFFF);
+ IO_WRITE(PI_DRAM_ADDR_REG, osVirtualToPhysical(dramAddr));
+ IO_WRITE(PI_CART_ADDR_REG, K1_TO_PHYS(handle->baseAddress | cartAddr));
switch (direction) {
case OS_READ:
- HW_REG(PI_WR_LEN_REG, u32) = size - 1;
+ IO_WRITE(PI_WR_LEN_REG, size - 1);
break;
case OS_WRITE:
- HW_REG(PI_RD_LEN_REG, u32) = size - 1;
+ IO_WRITE(PI_RD_LEN_REG, size - 1);
break;
default:
return -1;
- break;
}
-
return 0;
}
diff --git a/src/libultra/io/epirawread.c b/src/libultra/io/epirawread.c
index 5a3109364b..41997df66d 100644
--- a/src/libultra/io/epirawread.c
+++ b/src/libultra/io/epirawread.c
@@ -4,9 +4,9 @@ s32 __osEPiRawReadIo(OSPiHandle* handle, u32 devAddr, u32* data) {
s32 status;
OSPiHandle* curHandle;
- status = HW_REG(PI_STATUS_REG, u32);
- while (status & (PI_STATUS_BUSY | PI_STATUS_IOBUSY)) {
- status = HW_REG(PI_STATUS_REG, u32);
+ status = IO_READ(PI_STATUS_REG);
+ while (status & (PI_STATUS_DMA_BUSY | PI_STATUS_IO_BUSY)) {
+ status = IO_READ(PI_STATUS_REG);
}
if (__osCurrentHandle[handle->domain]->type != handle->type) {
@@ -14,35 +14,35 @@ s32 __osEPiRawReadIo(OSPiHandle* handle, u32 devAddr, u32* data) {
if (handle->domain == 0) {
if (curHandle->latency != handle->latency) {
- HW_REG(PI_BSD_DOM1_LAT_REG, u32) = handle->latency;
+ IO_WRITE(PI_BSD_DOM1_LAT_REG, handle->latency);
}
if (curHandle->pageSize != handle->pageSize) {
- HW_REG(PI_BSD_DOM1_PGS_REG, u32) = handle->pageSize;
+ IO_WRITE(PI_BSD_DOM1_PGS_REG, handle->pageSize);
}
if (curHandle->relDuration != handle->relDuration) {
- HW_REG(PI_BSD_DOM1_RLS_REG, u32) = handle->relDuration;
+ IO_WRITE(PI_BSD_DOM1_RLS_REG, handle->relDuration);
}
if (curHandle->pulse != handle->pulse) {
- HW_REG(PI_BSD_DOM1_PWD_REG, u32) = handle->pulse;
+ IO_WRITE(PI_BSD_DOM1_PWD_REG, handle->pulse);
}
} else {
if (curHandle->latency != handle->latency) {
- HW_REG(PI_BSD_DOM2_LAT_REG, u32) = handle->latency;
+ IO_WRITE(PI_BSD_DOM2_LAT_REG, handle->latency);
}
if (curHandle->pageSize != handle->pageSize) {
- HW_REG(PI_BSD_DOM2_PGS_REG, u32) = handle->pageSize;
+ IO_WRITE(PI_BSD_DOM2_PGS_REG, handle->pageSize);
}
if (curHandle->relDuration != handle->relDuration) {
- HW_REG(PI_BSD_DOM2_RLS_REG, u32) = handle->relDuration;
+ IO_WRITE(PI_BSD_DOM2_RLS_REG, handle->relDuration);
}
if (curHandle->pulse != handle->pulse) {
- HW_REG(PI_BSD_DOM2_PWD_REG, u32) = handle->pulse;
+ IO_WRITE(PI_BSD_DOM2_PWD_REG, handle->pulse);
}
}
@@ -53,6 +53,6 @@ s32 __osEPiRawReadIo(OSPiHandle* handle, u32 devAddr, u32* data) {
curHandle->pulse = handle->pulse;
}
- *data = HW_REG(handle->baseAddress | devAddr | 0, u32);
+ *data = IO_READ(handle->baseAddress | devAddr);
return 0;
}
diff --git a/src/libultra/io/epirawwrite.c b/src/libultra/io/epirawwrite.c
index 2c24c5e254..4d704a1923 100644
--- a/src/libultra/io/epirawwrite.c
+++ b/src/libultra/io/epirawwrite.c
@@ -4,9 +4,9 @@ s32 __osEPiRawWriteIo(OSPiHandle* handle, u32 devAddr, u32 data) {
s32 status;
OSPiHandle* curHandle;
- status = HW_REG(PI_STATUS_REG, u32);
- while (status & (PI_STATUS_BUSY | PI_STATUS_IOBUSY)) {
- status = HW_REG(PI_STATUS_REG, u32);
+ status = IO_READ(PI_STATUS_REG);
+ while (status & (PI_STATUS_DMA_BUSY | PI_STATUS_IO_BUSY)) {
+ status = IO_READ(PI_STATUS_REG);
}
if (__osCurrentHandle[handle->domain]->type != handle->type) {
@@ -14,35 +14,35 @@ s32 __osEPiRawWriteIo(OSPiHandle* handle, u32 devAddr, u32 data) {
if (handle->domain == 0) {
if (curHandle->latency != handle->latency) {
- HW_REG(PI_BSD_DOM1_LAT_REG, u32) = handle->latency;
+ IO_WRITE(PI_BSD_DOM1_LAT_REG, handle->latency);
}
if (curHandle->pageSize != handle->pageSize) {
- HW_REG(PI_BSD_DOM1_PGS_REG, u32) = handle->pageSize;
+ IO_WRITE(PI_BSD_DOM1_PGS_REG, handle->pageSize);
}
if (curHandle->relDuration != handle->relDuration) {
- HW_REG(PI_BSD_DOM1_RLS_REG, u32) = handle->relDuration;
+ IO_WRITE(PI_BSD_DOM1_RLS_REG, handle->relDuration);
}
if (curHandle->pulse != handle->pulse) {
- HW_REG(PI_BSD_DOM1_PWD_REG, u32) = handle->pulse;
+ IO_WRITE(PI_BSD_DOM1_PWD_REG, handle->pulse);
}
} else {
if (curHandle->latency != handle->latency) {
- HW_REG(PI_BSD_DOM2_LAT_REG, u32) = handle->latency;
+ IO_WRITE(PI_BSD_DOM2_LAT_REG, handle->latency);
}
if (curHandle->pageSize != handle->pageSize) {
- HW_REG(PI_BSD_DOM2_PGS_REG, u32) = handle->pageSize;
+ IO_WRITE(PI_BSD_DOM2_PGS_REG, handle->pageSize);
}
if (curHandle->relDuration != handle->relDuration) {
- HW_REG(PI_BSD_DOM2_RLS_REG, u32) = handle->relDuration;
+ IO_WRITE(PI_BSD_DOM2_RLS_REG, handle->relDuration);
}
if (curHandle->pulse != handle->pulse) {
- HW_REG(PI_BSD_DOM2_PWD_REG, u32) = handle->pulse;
+ IO_WRITE(PI_BSD_DOM2_PWD_REG, handle->pulse);
}
}
@@ -53,6 +53,6 @@ s32 __osEPiRawWriteIo(OSPiHandle* handle, u32 devAddr, u32 data) {
curHandle->pulse = handle->pulse;
}
- HW_REG(handle->baseAddress | devAddr, u32) = data;
+ IO_WRITE(handle->baseAddress | devAddr, data);
return 0;
}
diff --git a/src/libultra/io/pigetcmdq.c b/src/libultra/io/pigetcmdq.c
index f0e32ae20b..3f6f173580 100644
--- a/src/libultra/io/pigetcmdq.c
+++ b/src/libultra/io/pigetcmdq.c
@@ -2,7 +2,7 @@
#include "ultra64/internal.h"
OSMesgQueue* osPiGetCmdQueue(void) {
- if (!__osPiDevMgr.initialized) {
+ if (!__osPiDevMgr.active) {
return NULL;
}
diff --git a/src/libultra/io/pimgr.c b/src/libultra/io/pimgr.c
index e7b735e6b3..514fe26e8a 100644
--- a/src/libultra/io/pimgr.c
+++ b/src/libultra/io/pimgr.c
@@ -1,7 +1,7 @@
#include "global.h"
#include "ultra64/internal.h"
-OSMgrArgs __osPiDevMgr = { 0 };
+OSDevMgr __osPiDevMgr = { 0 };
OSPiHandle __Dom1SpeedParam;
OSPiHandle __Dom2SpeedParam;
@@ -22,7 +22,7 @@ void osCreatePiManager(OSPri pri, OSMesgQueue* cmdQueue, OSMesg* cmdBuf, s32 cmd
OSPri newPri;
OSPri currentPri;
- if (!__osPiDevMgr.initialized) {
+ if (!__osPiDevMgr.active) {
osCreateMesgQueue(cmdQueue, cmdBuf, cmdMsgCnt);
osCreateMesgQueue(&piEventQueue, piEventBuf, 1);
if (!__osPiAccessQueueEnabled) {
@@ -38,13 +38,13 @@ void osCreatePiManager(OSPri pri, OSMesgQueue* cmdQueue, OSMesg* cmdBuf, s32 cmd
}
prevInt = __osDisableInt();
- __osPiDevMgr.initialized = true;
+ __osPiDevMgr.active = true;
__osPiDevMgr.cmdQueue = cmdQueue;
- __osPiDevMgr.mgrThread = &piThread;
- __osPiDevMgr.eventQueue = &piEventQueue;
- __osPiDevMgr.acccessQueue = &__osPiAccessQueue;
- __osPiDevMgr.piDmaCallback = __osPiRawStartDma;
- __osPiDevMgr.epiDmaCallback = __osEPiRawStartDma;
+ __osPiDevMgr.thread = &piThread;
+ __osPiDevMgr.evtQueue = &piEventQueue;
+ __osPiDevMgr.acsQueue = &__osPiAccessQueue;
+ __osPiDevMgr.dma = __osPiRawStartDma;
+ __osPiDevMgr.edma = __osEPiRawStartDma;
osCreateThread(&piThread, 0, __osDevMgrMain, (void*)&__osPiDevMgr, STACK_TOP(piStackThread), pri);
osStartThread(&piThread);
diff --git a/src/libultra/io/pirawdma.c b/src/libultra/io/pirawdma.c
index d3dda984cd..84f809c9c9 100644
--- a/src/libultra/io/pirawdma.c
+++ b/src/libultra/io/pirawdma.c
@@ -3,21 +3,20 @@
s32 __osPiRawStartDma(s32 dir, u32 cartAddr, void* dramAddr, size_t size) {
s32 status;
- status = HW_REG(PI_STATUS_REG, u32);
- while (status & (PI_STATUS_BUSY | PI_STATUS_IOBUSY)) {
- status = HW_REG(PI_STATUS_REG, u32);
+ status = IO_READ(PI_STATUS_REG);
+ while (status & (PI_STATUS_DMA_BUSY | PI_STATUS_IO_BUSY)) {
+ status = IO_READ(PI_STATUS_REG);
}
- HW_REG(PI_DRAM_ADDR_REG, void*) = (void*)osVirtualToPhysical(dramAddr);
-
- HW_REG(PI_CART_ADDR_REG, void*) = (void*)((osRomBase | cartAddr) & 0x1FFFFFFF);
+ IO_WRITE(PI_DRAM_ADDR_REG, osVirtualToPhysical(dramAddr));
+ IO_WRITE(PI_CART_ADDR_REG, K1_TO_PHYS(osRomBase | cartAddr));
switch (dir) {
case OS_READ:
- HW_REG(PI_WR_LEN_REG, u32) = size - 1;
+ IO_WRITE(PI_WR_LEN_REG, size - 1);
break;
case OS_WRITE:
- HW_REG(PI_RD_LEN_REG, u32) = size - 1;
+ IO_WRITE(PI_RD_LEN_REG, size - 1);
break;
default:
return -1;
diff --git a/src/libultra/io/si.c b/src/libultra/io/si.c
index 7898153124..4afee03405 100644
--- a/src/libultra/io/si.c
+++ b/src/libultra/io/si.c
@@ -1,11 +1,10 @@
#include "global.h"
s32 __osSiDeviceBusy(void) {
- register u32 status = HW_REG(SI_STATUS_REG, u32);
+ register u32 status = IO_READ(SI_STATUS_REG);
- if (status & (SI_STATUS_DMA_BUSY | SI_STATUS_IO_READ_BUSY)) {
+ if (status & (SI_STATUS_DMA_BUSY | SI_STATUS_RD_BUSY)) {
return true;
- } else {
- return false;
}
+ return false;
}
diff --git a/src/libultra/io/sirawdma.c b/src/libultra/io/sirawdma.c
index 00b80b4b0a..9bf499cc6a 100644
--- a/src/libultra/io/sirawdma.c
+++ b/src/libultra/io/sirawdma.c
@@ -1,20 +1,22 @@
#include "global.h"
+#define PIF_RAM_SIZE (PIF_RAM_END + 1 - PIF_RAM_START)
+
s32 __osSiRawStartDma(s32 dir, void* addr) {
- if (HW_REG(SI_STATUS_REG, u32) & (SI_STATUS_DMA_BUSY | SI_STATUS_IO_READ_BUSY)) {
+ if (IO_READ(SI_STATUS_REG) & (SI_STATUS_DMA_BUSY | SI_STATUS_RD_BUSY)) {
return -1;
}
if (dir == OS_WRITE) {
- osWritebackDCache(addr, 0x40);
+ osWritebackDCache(addr, PIF_RAM_SIZE);
}
- HW_REG(SI_DRAM_ADDR_REG, void*) = (void*)osVirtualToPhysical(addr);
+ IO_WRITE(SI_DRAM_ADDR_REG, osVirtualToPhysical(addr));
if (dir == OS_READ) {
- HW_REG(SI_PIF_ADDR_RD64B_REG, void*) = (void*)PIF_RAM_START;
+ IO_WRITE(SI_PIF_ADDR_RD64B_REG, PIF_RAM_START);
} else {
- HW_REG(SI_PIF_ADDR_WR64B_REG, void*) = (void*)PIF_RAM_START;
+ IO_WRITE(SI_PIF_ADDR_WR64B_REG, PIF_RAM_START);
}
if (dir == OS_READ) {
- osInvalDCache(addr, 0x40);
+ osInvalDCache(addr, PIF_RAM_SIZE);
}
return 0;
}
diff --git a/src/libultra/io/sirawread.c b/src/libultra/io/sirawread.c
index 61b2d730ef..8efa071efb 100644
--- a/src/libultra/io/sirawread.c
+++ b/src/libultra/io/sirawread.c
@@ -4,6 +4,6 @@ s32 __osSiRawReadIo(void* devAddr, u32* dst) {
if (__osSiDeviceBusy()) {
return -1;
}
- *dst = HW_REG((u32)devAddr, u32);
+ *dst = IO_READ(devAddr);
return 0;
}
diff --git a/src/libultra/io/sirawwrite.c b/src/libultra/io/sirawwrite.c
index a1935c2e2e..f0e4514d77 100644
--- a/src/libultra/io/sirawwrite.c
+++ b/src/libultra/io/sirawwrite.c
@@ -4,6 +4,6 @@ s32 __osSiRawWriteIo(void* devAddr, u32 val) {
if (__osSiDeviceBusy()) {
return -1;
}
- HW_REG((u32)devAddr, u32) = val;
+ IO_WRITE(devAddr, val);
return 0;
}
diff --git a/src/libultra/io/sp.c b/src/libultra/io/sp.c
index 67ccd8939c..1796dc8f6e 100644
--- a/src/libultra/io/sp.c
+++ b/src/libultra/io/sp.c
@@ -1,7 +1,7 @@
#include "global.h"
u32 __osSpDeviceBusy(void) {
- register u32 status = HW_REG(SP_STATUS_REG, u32);
+ register u32 status = IO_READ(SP_STATUS_REG);
if (status & (SP_STATUS_DMA_BUSY | SP_STATUS_DMA_FULL | SP_STATUS_IO_FULL)) {
return 1;
diff --git a/src/libultra/io/spgetstat.c b/src/libultra/io/spgetstat.c
index 99a4ad0a18..e1545bdb7c 100644
--- a/src/libultra/io/spgetstat.c
+++ b/src/libultra/io/spgetstat.c
@@ -1,5 +1,5 @@
#include "global.h"
u32 __osSpGetStatus(void) {
- return HW_REG(SP_STATUS_REG, u32);
+ return IO_READ(SP_STATUS_REG);
}
diff --git a/src/libultra/io/sprawdma.c b/src/libultra/io/sprawdma.c
index 6a1b01b2af..795282c4a0 100644
--- a/src/libultra/io/sprawdma.c
+++ b/src/libultra/io/sprawdma.c
@@ -4,12 +4,12 @@ s32 __osSpRawStartDma(s32 direction, void* devAddr, void* dramAddr, u32 size) {
if (__osSpDeviceBusy()) {
return -1;
}
- HW_REG(SP_MEM_ADDR_REG, u32) = (u32)devAddr;
- HW_REG(SP_DRAM_ADDR_REG, u32) = osVirtualToPhysical(dramAddr);
+ IO_WRITE(SP_MEM_ADDR_REG, devAddr);
+ IO_WRITE(SP_DRAM_ADDR_REG, osVirtualToPhysical(dramAddr));
if (direction == OS_READ) {
- HW_REG(SP_WR_LEN_REG, u32) = size - 1;
+ IO_WRITE(SP_WR_LEN_REG, size - 1);
} else {
- HW_REG(SP_RD_LEN_REG, u32) = size - 1;
+ IO_WRITE(SP_RD_LEN_REG, size - 1);
}
return 0;
}
diff --git a/src/libultra/io/spsetpc.c b/src/libultra/io/spsetpc.c
index 2c3cc32ba0..944fc98631 100644
--- a/src/libultra/io/spsetpc.c
+++ b/src/libultra/io/spsetpc.c
@@ -1,13 +1,12 @@
#include "global.h"
s32 __osSpSetPc(void* pc) {
- register u32 spStatus = HW_REG(SP_STATUS_REG, u32);
+ register u32 spStatus = IO_READ(SP_STATUS_REG);
if (!(spStatus & SP_STATUS_HALT)) {
return -1;
- } else {
- HW_REG(SP_PC_REG, void*) = pc;
}
+ IO_WRITE(SP_PC_REG, pc);
return 0;
}
diff --git a/src/libultra/io/spsetstat.c b/src/libultra/io/spsetstat.c
index b2f97a3ff0..3fa7a49188 100644
--- a/src/libultra/io/spsetstat.c
+++ b/src/libultra/io/spsetstat.c
@@ -1,5 +1,5 @@
#include "global.h"
void __osSpSetStatus(u32 status) {
- HW_REG(SP_STATUS_REG, u32) = status;
+ IO_WRITE(SP_STATUS_REG, status);
}
diff --git a/src/libultra/io/sptask.c b/src/libultra/io/sptask.c
index bd9b5fdf2f..8b3286a453 100644
--- a/src/libultra/io/sptask.c
+++ b/src/libultra/io/sptask.c
@@ -32,7 +32,7 @@ void osSpTaskLoad(OSTask* intp) {
intp->t.flags &= ~OS_TASK_YIELDED;
if (tp->t.flags & OS_TASK_LOADABLE) {
- tp->t.ucode = (u64*)HW_REG((u32)intp->t.yield_data_ptr + OS_YIELD_DATA_SIZE - 4, u32);
+ tp->t.ucode = (u64*)IO_READ((u32)intp->t.yield_data_ptr + OS_YIELD_DATA_SIZE - 4);
}
}
osWritebackDCache(tp, sizeof(OSTask));
diff --git a/src/libultra/io/vi.c b/src/libultra/io/vi.c
index 12905742e1..dac56ed812 100644
--- a/src/libultra/io/vi.c
+++ b/src/libultra/io/vi.c
@@ -1,4 +1,5 @@
#include "global.h"
+#include "ultra64/viint.h"
OSViContext vi[2] = { 0 };
OSViContext* __osViCurr = &vi[0];
@@ -11,8 +12,8 @@ void __osViInit(void) {
__osViNext->retraceCount = 1;
__osViCurr->retraceCount = 1;
- __osViNext->buffer = (void*)0x80000000;
- __osViCurr->buffer = (void*)0x80000000;
+ __osViNext->framep = (void*)K0BASE;
+ __osViCurr->framep = (void*)K0BASE;
if (osTvType == OS_TV_PAL) {
__osViNext->modep = &osViModePalLan1;
@@ -22,13 +23,12 @@ void __osViInit(void) {
__osViNext->modep = &osViModeNtscLan1;
}
- __osViNext->state = 0x20;
+ __osViNext->state = VI_STATE_BLACK;
__osViNext->features = __osViNext->modep->comRegs.ctrl;
- while (HW_REG(VI_CURRENT_REG, u32) > 10) {
+ while (IO_READ(VI_CURRENT_REG) > 10) {
;
}
-
- HW_REG(VI_CONTROL_REG, u32) = 0;
+ IO_WRITE(VI_CONTROL_REG, 0);
__osViSwapContext();
}
diff --git a/src/libultra/io/viblack.c b/src/libultra/io/viblack.c
index 6571688660..491522fb1f 100644
--- a/src/libultra/io/viblack.c
+++ b/src/libultra/io/viblack.c
@@ -1,13 +1,13 @@
#include "global.h"
+#include "ultra64/viint.h"
-// TODO: name magic constants
void osViBlack(u8 active) {
register u32 prevInt = __osDisableInt();
if (active) {
- __osViNext->state |= 0x20;
+ __osViNext->state |= VI_STATE_BLACK;
} else {
- __osViNext->state &= ~0x20;
+ __osViNext->state &= ~VI_STATE_BLACK;
}
__osRestoreInt(prevInt);
}
diff --git a/src/libultra/io/viextend.c b/src/libultra/io/viextend.c
deleted file mode 100644
index 4808b0e29c..0000000000
--- a/src/libultra/io/viextend.c
+++ /dev/null
@@ -1,5 +0,0 @@
-#include "global.h"
-
-void osViExtendVStart(u32 arg0) {
- __additional_scanline = arg0;
-}
diff --git a/src/libultra/io/viextendvstart.c b/src/libultra/io/viextendvstart.c
new file mode 100644
index 0000000000..9efb9dbc3a
--- /dev/null
+++ b/src/libultra/io/viextendvstart.c
@@ -0,0 +1,5 @@
+#include "global.h"
+
+void osViExtendVStart(u32 value) {
+ __additional_scanline = value;
+}
diff --git a/src/libultra/io/vigetcurrframebuf.c b/src/libultra/io/vigetcurrframebuf.c
index 2093645d91..442a1afa9d 100644
--- a/src/libultra/io/vigetcurrframebuf.c
+++ b/src/libultra/io/vigetcurrframebuf.c
@@ -2,9 +2,9 @@
void* osViGetCurrentFramebuffer(void) {
register u32 prevInt = __osDisableInt();
- void* buffer = __osViCurr->buffer;
+ void* framep = __osViCurr->framep;
__osRestoreInt(prevInt);
- return buffer;
+ return framep;
}
diff --git a/src/libultra/io/vigetnextframebuf.c b/src/libultra/io/vigetnextframebuf.c
index a15a2db21c..5e6bd2ac74 100644
--- a/src/libultra/io/vigetnextframebuf.c
+++ b/src/libultra/io/vigetnextframebuf.c
@@ -1,9 +1,9 @@
#include "global.h"
void* osViGetNextFramebuffer(void) {
- u32 prevInt = __osDisableInt();
- void* buff = __osViNext->buffer;
+ register u32 prevInt = __osDisableInt();
+ void* framep = __osViNext->framep;
__osRestoreInt(prevInt);
- return buff;
+ return framep;
}
diff --git a/src/libultra/io/vimgr.c b/src/libultra/io/vimgr.c
index f2ec481e12..2d541672b7 100644
--- a/src/libultra/io/vimgr.c
+++ b/src/libultra/io/vimgr.c
@@ -7,7 +7,7 @@ OSMesgQueue viEventQueue;
OSMesg viEventBuf[5];
OSIoMesg viRetraceMsg;
OSIoMesg viCounterMsg;
-OSMgrArgs __osViDevMgr = { 0 };
+OSDevMgr __osViDevMgr = { 0 };
u32 __additional_scanline = 0;
void viMgrMain(void*);
@@ -17,7 +17,7 @@ void osCreateViManager(OSPri pri) {
OSPri newPri;
OSPri currentPri;
- if (!__osViDevMgr.initialized) {
+ if (!__osViDevMgr.active) {
__osTimerServicesInit();
__additional_scanline = 0;
osCreateMesgQueue(&viEventQueue, viEventBuf, ARRAY_COUNT(viEventBuf));
@@ -37,13 +37,13 @@ void osCreateViManager(OSPri pri) {
}
prevInt = __osDisableInt();
- __osViDevMgr.initialized = true;
- __osViDevMgr.mgrThread = &viThread;
+ __osViDevMgr.active = true;
+ __osViDevMgr.thread = &viThread;
__osViDevMgr.cmdQueue = &viEventQueue;
- __osViDevMgr.eventQueue = &viEventQueue;
- __osViDevMgr.acccessQueue = NULL;
- __osViDevMgr.piDmaCallback = NULL;
- __osViDevMgr.epiDmaCallback = NULL;
+ __osViDevMgr.evtQueue = &viEventQueue;
+ __osViDevMgr.acsQueue = NULL;
+ __osViDevMgr.dma = NULL;
+ __osViDevMgr.edma = NULL;
osCreateThread(&viThread, 0, &viMgrMain, &__osViDevMgr, STACK_TOP(viThreadStack), pri);
__osViInit();
@@ -55,27 +55,27 @@ void osCreateViManager(OSPri pri) {
}
}
-void viMgrMain(void* vargs) {
+void viMgrMain(void* arg) {
static u16 viRetrace;
- OSMgrArgs* args;
+ OSDevMgr* dm;
u32 addTime;
- OSIoMesg* msg = NULL;
- u32 temp = 0; // always 0
+ OSIoMesg* mb = NULL;
+ u32 first = 0;
viRetrace = __osViGetCurrentContext()->retraceCount;
if (viRetrace == 0) {
viRetrace = 1;
}
- args = (OSMgrArgs*)vargs;
+ dm = (OSDevMgr*)arg;
while (true) {
- osRecvMesg(args->eventQueue, (OSMesg*)&msg, OS_MESG_BLOCK);
- switch (msg->hdr.type) {
+ osRecvMesg(dm->evtQueue, (OSMesg*)&mb, OS_MESG_BLOCK);
+ switch (mb->hdr.type) {
case OS_MESG_TYPE_VRETRACE:
__osViSwapContext();
viRetrace--;
- if (!viRetrace) {
+ if (viRetrace == 0) {
OSViContext* ctx = __osViGetCurrentContext();
if (ctx->mq) {
osSendMesg(ctx->mq, ctx->msg, OS_MESG_NOBLOCK);
@@ -85,12 +85,12 @@ void viMgrMain(void* vargs) {
__osViIntrCount++;
- // block optimized out since temp is always 0,
+ // block optimized out since first is always 0,
// but it changes register allocation and ordering for __osCurrentTime
- if (temp != 0) {
+ if (first != 0) {
addTime = osGetCount();
__osCurrentTime = addTime;
- temp = 0;
+ first = 0;
}
addTime = __osBaseCounter;
diff --git a/src/libultra/io/vimodefpallan1.c b/src/libultra/io/vimodefpallan1.c
index f3e7421bab..5fb019cdfb 100644
--- a/src/libultra/io/vimodefpallan1.c
+++ b/src/libultra/io/vimodefpallan1.c
@@ -1,32 +1,46 @@
+/**
+ * @file vimodefpallan1.c
+ *
+ * FPAL LAN1 Video Mode
+ *
+ * L = Low Resolution
+ * A = Anti-Aliased
+ * N = Deinterlaced
+ * 1 = 16-bit Framebuffer
+ */
#include "global.h"
+#include "ultra64/viint.h"
OSViMode osViModeFpalLan1 = {
- 0x2C, // type
+ OS_VI_FPAL_LAN1, // type
{
// comRegs
- 0x311E, // ctrl
- SCREEN_WIDTH, // width
- 0x4541E3A, // burst
- 0x271, // vSync
- 0x170C69, // hSync
- 0xC6F0C6D, // leap
- 0x800300, // hStart
- 0x200, // xScale
- 0 // vCurrent
+ VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | VI_CTRL_DIVOT_ON | VI_CTRL_ANTIALIAS_MODE_1 |
+ VI_CTRL_PIXEL_ADV(3), // ctrl
+ WIDTH(320), // width
+ BURST(58, 30, 4, 69), // burst
+ VSYNC(625), // vSync
+ HSYNC(3177, 23), // hSync
+ LEAP(3183, 3181), // leap
+ HSTART(128, 768), // hStart
+ SCALE(2, 0), // xScale
+ VCURRENT(0), // vCurrent
},
{ // fldRegs
{
- 0x280, // origin
- 0x400, // yScale
- 0x2F0269, // vStart
- 0x9026B, // vBurst
- 2, // vIntr
+ // [0]
+ ORIGIN(640), // origin
+ SCALE(1, 0), // yScale
+ START(47, 617), // vStart
+ BURST(107, 2, 9, 0), // vBurst
+ VINTR(2), // vIntr
},
{
- 0x280, // origin
- 0x400, // yScale
- 0x2F0269, // vStart
- 0x9026B, // vBurst
- 2 // vIntr
+ // [1]
+ ORIGIN(640), // origin
+ SCALE(1, 0), // yScale
+ START(47, 617), // vStart
+ BURST(107, 2, 9, 0), // vBurst
+ VINTR(2), // vIntr
} },
};
diff --git a/src/libultra/io/vimodempallan1.c b/src/libultra/io/vimodempallan1.c
index b872b897ec..23d53987b0 100644
--- a/src/libultra/io/vimodempallan1.c
+++ b/src/libultra/io/vimodempallan1.c
@@ -1,34 +1,46 @@
+/**
+ * @file vimodempallan1.c
+ *
+ * MPAL LAN1 Video Mode
+ *
+ * L = Low Resolution
+ * A = Anti-Aliased
+ * N = Deinterlaced
+ * 1 = 16-bit Framebuffer
+ */
#include "global.h"
+#include "ultra64/viint.h"
OSViMode osViModeMpalLan1 = {
- 0x1E, // type
+ OS_VI_MPAL_LAN1, // type
{
// comRegs
- 0x311E, // ctrl
- SCREEN_WIDTH, // width
- 0x4651E39, // burst
- 0x20D, // vSync
- 0x40C11, // hSync
- 0xC190C1A, // leap
- 0x6C02EC, // hStart
- 0x200, // xScale
- 0, // vCurrent
+ VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | VI_CTRL_DIVOT_ON | VI_CTRL_ANTIALIAS_MODE_1 |
+ VI_CTRL_PIXEL_ADV(3), // ctrl
+ WIDTH(320), // width
+ BURST(57, 30, 5, 70), // burst
+ VSYNC(525), // vSync
+ HSYNC(3089, 4), // hSync
+ LEAP(3097, 3098), // leap
+ HSTART(108, 748), // hStart
+ SCALE(2, 0), // xScale
+ VCURRENT(0), // vCurrent
},
{ // fldRegs
{
// [0]
- 0x280, // origin
- 0x400, // yScale
- 0x2501FF, // vStart
- 0xE0204, // vBurst
- 2, // vIntr
+ ORIGIN(640), // origin
+ SCALE(1, 0), // yScale
+ START(37, 511), // vStart
+ BURST(4, 2, 14, 0), // vBurst
+ VINTR(2), // vIntr
},
{
// [1]
- 0x280, // origin
- 0x400, // yScale
- 0x2501FF, // vStart
- 0xE0204, // vBurst
- 2, // vIntr
+ ORIGIN(640), // origin
+ SCALE(1, 0), // yScale
+ START(37, 511), // vStart
+ BURST(4, 2, 14, 0), // vBurst
+ VINTR(2), // vIntr
} },
};
diff --git a/src/libultra/io/vimodentsclan1.c b/src/libultra/io/vimodentsclan1.c
index 80330f21e1..19a7160ac8 100644
--- a/src/libultra/io/vimodentsclan1.c
+++ b/src/libultra/io/vimodentsclan1.c
@@ -1,34 +1,46 @@
+/**
+ * @file vimodentsclan1.c
+ *
+ * NTSC LAN1 Video Mode
+ *
+ * L = Low Resolution
+ * A = Anti-Aliased
+ * N = Deinterlaced
+ * 1 = 16-bit Framebuffer
+ */
#include "global.h"
+#include "ultra64/viint.h"
OSViMode osViModeNtscLan1 = {
- 2, // type
+ OS_VI_NTSC_LAN1, // type
{
// comRegs
- 0x311E, // ctrl
- SCREEN_WIDTH, // width
- 0x3E52239, // burst
- 0x20D, // vSync
- 0xC15, // hSync
- 0xC150C15, // leap
- 0x6C02EC, // hStart
- 0x200, // xScale
- 0, // vCurrent
+ VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | VI_CTRL_DIVOT_ON | VI_CTRL_ANTIALIAS_MODE_1 |
+ VI_CTRL_PIXEL_ADV(3), // ctrl
+ WIDTH(320), // width
+ BURST(57, 34, 5, 62), // burst
+ VSYNC(525), // vSync
+ HSYNC(3093, 0), // hSync
+ LEAP(3093, 3093), // leap
+ HSTART(108, 748), // hStart
+ SCALE(2, 0), // xScale
+ VCURRENT(0), // vCurrent
},
{ // fldRegs
{
// [0]
- 0x280, // origin
- 0x400, // yScale
- 0x2501FF, // vStart
- 0xE0204, // vBurst
- 2, // vIntr
+ ORIGIN(640), // origin
+ SCALE(1, 0), // yScale
+ START(37, 511), // vStart
+ BURST(4, 2, 14, 0), // vBurst
+ VINTR(2), // vIntr
},
{
// [1]
- 0x280, // origin
- 0x400, // yScale
- 0x2501FF, // vStart
- 0xE0204, // vBurst
- 2, // vIntr
+ ORIGIN(640), // origin
+ SCALE(1, 0), // yScale
+ START(37, 511), // vStart
+ BURST(4, 2, 14, 0), // vBurst
+ VINTR(2), // vIntr
} },
};
diff --git a/src/libultra/io/vimodepallan1.c b/src/libultra/io/vimodepallan1.c
index 2f69c8197b..7a8db603f4 100644
--- a/src/libultra/io/vimodepallan1.c
+++ b/src/libultra/io/vimodepallan1.c
@@ -1,32 +1,46 @@
+/**
+ * @file vimodepallan1.c
+ *
+ * PAL LAN1 Video Mode
+ *
+ * L = Low Resolution
+ * A = Anti-Aliased
+ * N = Deinterlaced
+ * 1 = 16-bit Framebuffer
+ */
#include "global.h"
+#include "ultra64/viint.h"
OSViMode osViModePalLan1 = {
- 0x10, // type
+ OS_VI_PAL_LAN1, // type
{
// comRegs
- 0x311E, // ctrl
- SCREEN_WIDTH, // width
- 0x4541E3A, // burst
- 0x271, // vSync
- 0x170C69, // hSync
- 0xC6F0C6D, // leap
- 0x800300, // hStart
- 0x200, // xScale
- 0 // vCurrent
+ VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | VI_CTRL_DIVOT_ON | VI_CTRL_ANTIALIAS_MODE_1 |
+ VI_CTRL_PIXEL_ADV(3), // ctrl
+ WIDTH(320), // width
+ BURST(58, 30, 4, 69), // burst
+ VSYNC(625), // vSync
+ HSYNC(3177, 23), // hSync
+ LEAP(3183, 3181), // leap
+ HSTART(128, 768), // hStart
+ SCALE(2, 0), // xScale
+ VCURRENT(0), // vCurrent
},
{ // fldRegs
{
- 0x280, // origin
- 0x400, // yScale
- 0x5F0239, // vStart
- 0x9026B, // vBurst
- 2, // vIntr
+ // [0]
+ ORIGIN(640), // origin
+ SCALE(1, 0), // yScale
+ START(95, 569), // vStart
+ BURST(107, 2, 9, 0), // vBurst
+ VINTR(2), // vIntr
},
{
- 0x280, // origin
- 0x400, // yScale
- 0x5F0239, // vStart
- 0x9026B, // vBurst
- 2 // vIntr
+ // [1]
+ ORIGIN(640), // origin
+ SCALE(1, 0), // yScale
+ START(95, 569), // vStart
+ BURST(107, 2, 9, 0), // vBurst
+ VINTR(2), // vIntr
} },
};
diff --git a/src/libultra/io/visetmode.c b/src/libultra/io/visetmode.c
index 621b7ca4ac..ab5b3b0e18 100644
--- a/src/libultra/io/visetmode.c
+++ b/src/libultra/io/visetmode.c
@@ -1,10 +1,11 @@
#include "global.h"
+#include "ultra64/viint.h"
void osViSetMode(OSViMode* mode) {
register u32 prevInt = __osDisableInt();
__osViNext->modep = mode;
- __osViNext->state = 1;
+ __osViNext->state = VI_STATE_MODE_SET;
__osViNext->features = __osViNext->modep->comRegs.ctrl;
__osRestoreInt(prevInt);
diff --git a/src/libultra/io/visetspecial.c b/src/libultra/io/visetspecial.c
index e5bd21029d..d51e3479d3 100644
--- a/src/libultra/io/visetspecial.c
+++ b/src/libultra/io/visetspecial.c
@@ -1,38 +1,55 @@
#include "global.h"
+#include "ultra64/viint.h"
+/**
+ * Configures VI "special features" to be applied on the next context swap.
+ *
+ * "Special features" refer to the mode bits in the Video Interface control register that enable effects such as gamma
+ * correction, gamma dither, dither filtering, anti-aliasing filtering and divot filtering. Configuring the same
+ * setting ON and OFF in the same call will result in OFF taking precedence.
+ *
+ * Any unrecognized bits will be ignored. Note that this is very intentional as in early revisions of retail N64
+ * hardware setting bit 5 in the `features` field of OSViContext may cause physical damage to the console once it is
+ * fed to VI_CONTROL_REG on next context swap.
+ *
+ * @param func OS_VI_*_ON / OS_VI_*_OFF bits to enable or disable a setting.
+ */
void osViSetSpecialFeatures(u32 func) {
register u32 prevInt = __osDisableInt();
if (func & OS_VI_GAMMA_ON) {
- __osViNext->features |= OS_VI_GAMMA;
+ __osViNext->features |= VI_CTRL_GAMMA_ON;
}
if (func & OS_VI_GAMMA_OFF) {
- __osViNext->features &= ~OS_VI_GAMMA;
+ __osViNext->features &= ~VI_CTRL_GAMMA_ON;
}
+
if (func & OS_VI_GAMMA_DITHER_ON) {
- __osViNext->features |= OS_VI_GAMMA_DITHER;
+ __osViNext->features |= VI_CTRL_GAMMA_DITHER_ON;
}
if (func & OS_VI_GAMMA_DITHER_OFF) {
-
- __osViNext->features &= ~OS_VI_GAMMA_DITHER;
+ __osViNext->features &= ~VI_CTRL_GAMMA_DITHER_ON;
}
- if (func & OS_VI_DIVOT_ON) {
- __osViNext->features |= OS_VI_DIVOT;
+ if (func & OS_VI_DIVOT_ON) {
+ __osViNext->features |= VI_CTRL_DIVOT_ON;
}
if (func & OS_VI_DIVOT_OFF) {
-
- __osViNext->features &= ~OS_VI_DIVOT;
+ __osViNext->features &= ~VI_CTRL_DIVOT_ON;
}
+
if (func & OS_VI_DITHER_FILTER_ON) {
- __osViNext->features |= OS_VI_DITHER_FILTER;
- __osViNext->features &= ~(OS_VI_UNK200 | OS_VI_UNK100);
+ // If the dither filter is enabled, also force anti-alias mode 0 irrespective of the current OSViMode.
+ __osViNext->features |= VI_CTRL_DITHER_FILTER_ON;
+ __osViNext->features &= ~VI_CTRL_ANTIALIAS_MASK;
}
if (func & OS_VI_DITHER_FILTER_OFF) {
- __osViNext->features &= ~OS_VI_DITHER_FILTER;
- __osViNext->features |= __osViNext->modep->comRegs.ctrl & (OS_VI_UNK200 | OS_VI_UNK100);
+ // If the dither filter is disabled, use the anti-alias mode from the current OSViMode.
+ __osViNext->features &= ~VI_CTRL_DITHER_FILTER_ON;
+ __osViNext->features |= __osViNext->modep->comRegs.ctrl & VI_CTRL_ANTIALIAS_MASK;
}
- __osViNext->state |= 8;
+
+ __osViNext->state |= VI_STATE_CTRL_SET;
__osRestoreInt(prevInt);
}
diff --git a/src/libultra/io/visetxscale.c b/src/libultra/io/visetxscale.c
index aeeb5e784f..5e5e04ee47 100644
--- a/src/libultra/io/visetxscale.c
+++ b/src/libultra/io/visetxscale.c
@@ -1,14 +1,15 @@
#include "global.h"
+#include "ultra64/viint.h"
void osViSetXScale(f32 value) {
register u32 nomValue;
register u32 prevInt = __osDisableInt();
__osViNext->x.factor = value;
- __osViNext->state |= 0x2;
+ __osViNext->state |= VI_STATE_XSCALE_SET;
- nomValue = __osViNext->modep->comRegs.xScale & 0xFFF;
- __osViNext->x.scale = (u32)(__osViNext->x.factor * nomValue) & 0xFFF;
+ nomValue = __osViNext->modep->comRegs.xScale & VI_SCALE_MASK;
+ __osViNext->x.scale = (u32)(__osViNext->x.factor * nomValue) & VI_SCALE_MASK;
__osRestoreInt(prevInt);
}
diff --git a/src/libultra/io/visetyscale.c b/src/libultra/io/visetyscale.c
index 0d7a5f9684..adea96fd23 100644
--- a/src/libultra/io/visetyscale.c
+++ b/src/libultra/io/visetyscale.c
@@ -1,10 +1,11 @@
#include "global.h"
+#include "ultra64/viint.h"
void osViSetYScale(f32 scale) {
register u32 prevInt = __osDisableInt();
__osViNext->y.factor = scale;
- __osViNext->state |= 4;
+ __osViNext->state |= VI_STATE_YSCALE_FACTOR_SET;
__osRestoreInt(prevInt);
}
diff --git a/src/libultra/io/viswapbuf.c b/src/libultra/io/viswapbuf.c
index b7ab9f9170..99259c03c3 100644
--- a/src/libultra/io/viswapbuf.c
+++ b/src/libultra/io/viswapbuf.c
@@ -1,10 +1,11 @@
#include "global.h"
+#include "ultra64/viint.h"
-void osViSwapBuffer(void* vaddr) {
+void osViSwapBuffer(void* frameBufPtr) {
u32 prevInt = __osDisableInt();
- __osViNext->buffer = vaddr;
- __osViNext->state |= 0x10; // TODO: figure out what this flag means
+ __osViNext->framep = frameBufPtr;
+ __osViNext->state |= VI_STATE_BUFFER_SET;
__osRestoreInt(prevInt);
}
diff --git a/src/libultra/io/viswapcontext.c b/src/libultra/io/viswapcontext.c
index d82d5cce65..d1a7d0c0e6 100644
--- a/src/libultra/io/viswapcontext.c
+++ b/src/libultra/io/viswapcontext.c
@@ -1,4 +1,5 @@
#include "global.h"
+#include "ultra64/viint.h"
void __osViSwapContext(void) {
register OSViMode* viMode;
@@ -6,56 +7,57 @@ void __osViSwapContext(void) {
u32 origin;
u32 hStart;
u32 vstart;
- u32 sp34;
+ u32 nomValue;
u32 field;
- register u32 s2;
field = 0;
viNext = __osViNext;
viMode = viNext->modep;
- field = HW_REG(VI_V_CURRENT_LINE_REG, u32) & 1;
- s2 = osVirtualToPhysical(viNext->buffer);
- origin = (viMode->fldRegs[field].origin) + s2;
- if (viNext->state & 2) {
- viNext->x.scale |= viMode->comRegs.xScale & ~0xFFF;
+ field = IO_READ(VI_V_CURRENT_LINE_REG) & 1; // even or odd field
+ origin = osVirtualToPhysical(viNext->framep) + viMode->fldRegs[field].origin;
+
+ if (viNext->state & VI_STATE_XSCALE_SET) {
+ viNext->x.scale |= viMode->comRegs.xScale & ~VI_SCALE_MASK;
} else {
viNext->x.scale = viMode->comRegs.xScale;
}
- if (viNext->state & 4) {
- sp34 = (u32)(viMode->fldRegs[field].yScale & 0xFFF);
- viNext->y.scale = viNext->y.factor * sp34;
- viNext->y.scale |= viMode->fldRegs[field].yScale & ~0xFFF;
+ if (viNext->state & VI_STATE_YSCALE_FACTOR_SET) {
+ nomValue = (u32)(viMode->fldRegs[field].yScale & VI_SCALE_MASK);
+ viNext->y.scale = viNext->y.factor * nomValue;
+ viNext->y.scale |= viMode->fldRegs[field].yScale & ~VI_SCALE_MASK;
} else {
viNext->y.scale = viMode->fldRegs[field].yScale;
}
- vstart = (viMode->fldRegs[field].vStart - (__additional_scanline << 0x10)) + __additional_scanline;
+ vstart = (viMode->fldRegs[field].vStart - (__additional_scanline << VI_SUBPIXEL_SH)) + __additional_scanline;
hStart = viMode->comRegs.hStart;
- if (viNext->state & 0x20) {
+ if (viNext->state & VI_STATE_BLACK) {
hStart = 0;
}
- if (viNext->state & 0x40) {
+ if (viNext->state & VI_STATE_REPEATLINE) {
viNext->y.scale = 0;
- origin = osVirtualToPhysical(viNext->buffer);
+ origin = osVirtualToPhysical(viNext->framep);
}
- if (viNext->state & 0x80) {
- viNext->y.scale = (viNext->y.offset << 0x10) & 0x3FF0000;
- origin = osVirtualToPhysical(viNext->buffer);
+ if (viNext->state & VI_STATE_FADE) {
+ viNext->y.scale = (viNext->y.offset << VI_SUBPIXEL_SH) & (VI_2_10_FPART_MASK << VI_SUBPIXEL_SH);
+ origin = osVirtualToPhysical(viNext->framep);
}
- HW_REG(VI_ORIGIN_REG, u32) = origin;
- HW_REG(VI_WIDTH_REG, u32) = viMode->comRegs.width;
- HW_REG(VI_BURST_REG, u32) = viMode->comRegs.burst;
- HW_REG(VI_V_SYNC_REG, u32) = viMode->comRegs.vSync;
- HW_REG(VI_H_SYNC_REG, u32) = viMode->comRegs.hSync;
- HW_REG(VI_LEAP_REG, u32) = viMode->comRegs.leap;
- HW_REG(VI_H_START_REG, u32) = hStart;
- HW_REG(VI_V_START_REG, u32) = vstart;
- HW_REG(VI_V_BURST_REG, u32) = viMode->fldRegs[field].vBurst;
- HW_REG(VI_INTR_REG, u32) = viMode->fldRegs[field].vIntr;
- HW_REG(VI_X_SCALE_REG, u32) = viNext->x.scale;
- HW_REG(VI_Y_SCALE_REG, u32) = viNext->y.scale;
- HW_REG(VI_CONTROL_REG, u32) = viNext->features;
+
+ IO_WRITE(VI_ORIGIN_REG, origin);
+ IO_WRITE(VI_WIDTH_REG, viMode->comRegs.width);
+ IO_WRITE(VI_BURST_REG, viMode->comRegs.burst);
+ IO_WRITE(VI_V_SYNC_REG, viMode->comRegs.vSync);
+ IO_WRITE(VI_H_SYNC_REG, viMode->comRegs.hSync);
+ IO_WRITE(VI_LEAP_REG, viMode->comRegs.leap);
+ IO_WRITE(VI_H_START_REG, hStart);
+ IO_WRITE(VI_V_START_REG, vstart);
+ IO_WRITE(VI_V_BURST_REG, viMode->fldRegs[field].vBurst);
+ IO_WRITE(VI_INTR_REG, viMode->fldRegs[field].vIntr);
+ IO_WRITE(VI_X_SCALE_REG, viNext->x.scale);
+ IO_WRITE(VI_Y_SCALE_REG, viNext->y.scale);
+ IO_WRITE(VI_CONTROL_REG, viNext->features);
+
__osViNext = __osViCurr;
__osViCurr = viNext;
*__osViNext = *__osViCurr;
diff --git a/src/libultra/os/exceptasm.s b/src/libultra/os/exceptasm.s
index d6bd3082ce..16ff4f5792 100644
--- a/src/libultra/os/exceptasm.s
+++ b/src/libultra/os/exceptasm.s
@@ -1,7 +1,6 @@
#include "ultra64/asm.h"
-#include "ultra64/r4300.h"
+#include "ultra64/R4300.h"
#include "ultra64/rcp.h"
-#include "ultra64/rsp.h"
#include "ultra64/message.h"
#include "ultra64/thread.h"
#include "ultra64/exception.h"
diff --git a/src/libultra/os/getcause.s b/src/libultra/os/getcause.s
index 48fbf3236e..a621e97363 100644
--- a/src/libultra/os/getcause.s
+++ b/src/libultra/os/getcause.s
@@ -1,5 +1,5 @@
#include "ultra64/asm.h"
-#include "ultra64/r4300.h"
+#include "ultra64/R4300.h"
.set noreorder
diff --git a/src/libultra/os/getcount.s b/src/libultra/os/getcount.s
index bad47d0bc5..242c9da692 100644
--- a/src/libultra/os/getcount.s
+++ b/src/libultra/os/getcount.s
@@ -1,5 +1,5 @@
#include "ultra64/asm.h"
-#include "ultra64/r4300.h"
+#include "ultra64/R4300.h"
.set noreorder
diff --git a/src/libultra/os/getfpccsr.s b/src/libultra/os/getfpccsr.s
index d86734ad00..93d4e51b8e 100644
--- a/src/libultra/os/getfpccsr.s
+++ b/src/libultra/os/getfpccsr.s
@@ -1,5 +1,5 @@
#include "ultra64/asm.h"
-#include "ultra64/r4300.h"
+#include "ultra64/R4300.h"
.set noreorder
diff --git a/src/libultra/os/getsr.s b/src/libultra/os/getsr.s
index aed66d40a2..dc6901b982 100644
--- a/src/libultra/os/getsr.s
+++ b/src/libultra/os/getsr.s
@@ -1,5 +1,5 @@
#include "ultra64/asm.h"
-#include "ultra64/r4300.h"
+#include "ultra64/R4300.h"
.set noreorder
diff --git a/src/libultra/os/initialize.c b/src/libultra/os/initialize.c
index d3998c0bbf..3266d1e4dd 100644
--- a/src/libultra/os/initialize.c
+++ b/src/libultra/os/initialize.c
@@ -1,63 +1,62 @@
#include "global.h"
typedef struct {
- u32 ins_00; // lui k0, 0x8000
- u32 ins_04; // addiu k0, k0, 0x39E0
- u32 ins_08; // jr k0 ; __osException
- u32 ins_0C; // nop
-} struct_exceptionPreamble;
+ u32 inst1; // lui $k0, %hi(__osException)
+ u32 inst2; // addiu $k0, $k0, %lo(__osException)
+ u32 inst3; // jr $k0
+ u32 inst4; // nop
+} __osExceptionVector;
-void __osExceptionPreamble(void);
+extern __osExceptionVector __osExceptionPreamble;
u64 osClockRate = OS_CLOCK_RATE;
s32 osViClock = VI_NTSC_CLOCK;
-u32 __osShutdown = 0;
+u32 __osShutdown = false;
OSHWIntr __OSGlobalIntMask = OS_IM_ALL;
-u32 D_800145C0;
+u32 __osFinalrom;
void __createSpeedParam(void) {
__Dom1SpeedParam.type = DEVICE_TYPE_INIT;
- __Dom1SpeedParam.latency = HW_REG(PI_BSD_DOM1_LAT_REG, u32);
- __Dom1SpeedParam.pulse = HW_REG(PI_BSD_DOM1_PWD_REG, u32);
- __Dom1SpeedParam.pageSize = HW_REG(PI_BSD_DOM1_PGS_REG, u32);
- __Dom1SpeedParam.relDuration = HW_REG(PI_BSD_DOM1_RLS_REG, u32);
+ __Dom1SpeedParam.latency = IO_READ(PI_BSD_DOM1_LAT_REG);
+ __Dom1SpeedParam.pulse = IO_READ(PI_BSD_DOM1_PWD_REG);
+ __Dom1SpeedParam.pageSize = IO_READ(PI_BSD_DOM1_PGS_REG);
+ __Dom1SpeedParam.relDuration = IO_READ(PI_BSD_DOM1_RLS_REG);
__Dom2SpeedParam.type = DEVICE_TYPE_INIT;
- __Dom2SpeedParam.latency = HW_REG(PI_BSD_DOM2_LAT_REG, u32);
- __Dom2SpeedParam.pulse = HW_REG(PI_BSD_DOM2_PWD_REG, u32);
- __Dom2SpeedParam.pageSize = HW_REG(PI_BSD_DOM2_PGS_REG, u32);
- __Dom2SpeedParam.relDuration = HW_REG(PI_BSD_DOM2_RLS_REG, u32);
+ __Dom2SpeedParam.latency = IO_READ(PI_BSD_DOM2_LAT_REG);
+ __Dom2SpeedParam.pulse = IO_READ(PI_BSD_DOM2_PWD_REG);
+ __Dom2SpeedParam.pageSize = IO_READ(PI_BSD_DOM2_PGS_REG);
+ __Dom2SpeedParam.relDuration = IO_READ(PI_BSD_DOM2_RLS_REG);
}
void __osInitialize_common(void) {
- u32 sp2C;
+ u32 pifdata;
- D_800145C0 = 1;
+ __osFinalrom = true;
__osSetSR(__osGetSR() | SR_CU1);
__osSetFpcCsr(FPCSR_FS | FPCSR_EV);
- __osSetWatchLo(0x4900000);
+ __osSetWatchLo(0x04900000);
- while (__osSiRawReadIo((void*)(PIF_RAM_START + 0x3C), &sp2C)) {
+ while (__osSiRawReadIo((void*)(PIF_RAM_END - 3), &pifdata)) {
+ ;
+ }
+ while (__osSiRawWriteIo((void*)(PIF_RAM_END - 3), pifdata | 8)) {
;
}
- while (__osSiRawWriteIo((void*)(PIF_RAM_START + 0x3C), sp2C | 8)) {
- ;
- }
+ *(__osExceptionVector*)UT_VEC = __osExceptionPreamble; // TLB miss
+ *(__osExceptionVector*)XUT_VEC = __osExceptionPreamble; // XTLB miss
+ *(__osExceptionVector*)ECC_VEC = __osExceptionPreamble; // cache errors
+ *(__osExceptionVector*)E_VEC = __osExceptionPreamble; // general exceptions
- *(struct_exceptionPreamble*)UT_VEC = *(struct_exceptionPreamble*)__osExceptionPreamble; // TLB miss
- *(struct_exceptionPreamble*)XUT_VEC = *(struct_exceptionPreamble*)__osExceptionPreamble; // XTLB miss
- *(struct_exceptionPreamble*)ECC_VEC = *(struct_exceptionPreamble*)__osExceptionPreamble; // cache errors
- *(struct_exceptionPreamble*)E_VEC = *(struct_exceptionPreamble*)__osExceptionPreamble; // general exceptions
-
- osWritebackDCache((void*)K0BASE, E_VEC - K0BASE + sizeof(struct_exceptionPreamble));
- osInvalICache((void*)K0BASE, E_VEC - K0BASE + sizeof(struct_exceptionPreamble));
+ osWritebackDCache((void*)K0BASE, E_VEC - K0BASE + sizeof(__osExceptionVector));
+ osInvalICache((void*)K0BASE, E_VEC - K0BASE + sizeof(__osExceptionVector));
__createSpeedParam();
osUnmapTLBAll();
osMapTLBRdb();
- osClockRate = (u64)((osClockRate * 3ll) / 4ull);
+ osClockRate = osClockRate * 3 / 4;
if (!osResetType) {
bzero(osAppNMIBuffer, sizeof(osAppNMIBuffer));
@@ -71,16 +70,16 @@ void __osInitialize_common(void) {
osViClock = VI_NTSC_CLOCK;
}
- // Wait until there are no RCP interrupts
+ // If PreNMI is pending, loop until reset
if (__osGetCause() & CAUSE_IP5) {
while (true) {
;
}
}
- HW_REG(AI_CONTROL_REG, u32) = 1;
- HW_REG(AI_DACRATE_REG, u32) = 0x3FFF;
- HW_REG(AI_BITRATE_REG, u32) = 0xF;
+ IO_WRITE(AI_CONTROL_REG, AI_CONTROL_DMA_ON);
+ IO_WRITE(AI_DACRATE_REG, AI_MAX_DAC_RATE - 1);
+ IO_WRITE(AI_BITRATE_REG, AI_MAX_BIT_RATE - 1);
}
void __osInitialize_autodetect(void) {
diff --git a/src/libultra/os/interrupt.s b/src/libultra/os/interrupt.s
index 82090742b7..829377bb0e 100644
--- a/src/libultra/os/interrupt.s
+++ b/src/libultra/os/interrupt.s
@@ -1,5 +1,5 @@
#include "ultra64/asm.h"
-#include "ultra64/r4300.h"
+#include "ultra64/R4300.h"
#include "ultra64/thread.h"
.set noat
diff --git a/src/libultra/os/invaldcache.s b/src/libultra/os/invaldcache.s
index 41799d3188..9464a24da6 100644
--- a/src/libultra/os/invaldcache.s
+++ b/src/libultra/os/invaldcache.s
@@ -1,5 +1,5 @@
#include "ultra64/asm.h"
-#include "ultra64/r4300.h"
+#include "ultra64/R4300.h"
.set noat
.set noreorder
diff --git a/src/libultra/os/invalicache.s b/src/libultra/os/invalicache.s
index 79d576fba9..55f8312380 100644
--- a/src/libultra/os/invalicache.s
+++ b/src/libultra/os/invalicache.s
@@ -1,5 +1,5 @@
#include "ultra64/asm.h"
-#include "ultra64/r4300.h"
+#include "ultra64/R4300.h"
.set noat
.set noreorder
diff --git a/src/libultra/os/maptlbrdb.s b/src/libultra/os/maptlbrdb.s
index ea8fe4aa4a..c3ac20948b 100644
--- a/src/libultra/os/maptlbrdb.s
+++ b/src/libultra/os/maptlbrdb.s
@@ -1,5 +1,5 @@
#include "ultra64/asm.h"
-#include "ultra64/r4300.h"
+#include "ultra64/R4300.h"
#include "ultra64/rdb.h"
.set noreorder
diff --git a/src/libultra/os/probetlb.s b/src/libultra/os/probetlb.s
index ce655facaf..7bc7856e13 100644
--- a/src/libultra/os/probetlb.s
+++ b/src/libultra/os/probetlb.s
@@ -1,5 +1,5 @@
#include "ultra64/asm.h"
-#include "ultra64/r4300.h"
+#include "ultra64/R4300.h"
.set noat
.set noreorder
diff --git a/src/libultra/os/setcompare.s b/src/libultra/os/setcompare.s
index 4b69b2ea90..bd16533774 100644
--- a/src/libultra/os/setcompare.s
+++ b/src/libultra/os/setcompare.s
@@ -1,5 +1,5 @@
#include "ultra64/asm.h"
-#include "ultra64/r4300.h"
+#include "ultra64/R4300.h"
.set noreorder
diff --git a/src/libultra/os/setfpccsr.s b/src/libultra/os/setfpccsr.s
index 9b6b368f39..1aa0e7d298 100644
--- a/src/libultra/os/setfpccsr.s
+++ b/src/libultra/os/setfpccsr.s
@@ -1,5 +1,5 @@
#include "ultra64/asm.h"
-#include "ultra64/r4300.h"
+#include "ultra64/R4300.h"
.set noreorder
diff --git a/src/libultra/os/setintmask.s b/src/libultra/os/setintmask.s
index 3afadb73a6..3d2bc5b9c9 100644
--- a/src/libultra/os/setintmask.s
+++ b/src/libultra/os/setintmask.s
@@ -1,5 +1,5 @@
#include "ultra64/asm.h"
-#include "ultra64/r4300.h"
+#include "ultra64/R4300.h"
#include "ultra64/rcp.h"
#include "ultra64/exception.h"
diff --git a/src/libultra/os/setsr.s b/src/libultra/os/setsr.s
index 382f2eada1..b754359eae 100644
--- a/src/libultra/os/setsr.s
+++ b/src/libultra/os/setsr.s
@@ -1,5 +1,5 @@
#include "ultra64/asm.h"
-#include "ultra64/r4300.h"
+#include "ultra64/R4300.h"
.set noreorder
diff --git a/src/libultra/os/setwatchlo.s b/src/libultra/os/setwatchlo.s
index 749b1dbd85..aee3ad4d6d 100644
--- a/src/libultra/os/setwatchlo.s
+++ b/src/libultra/os/setwatchlo.s
@@ -1,5 +1,5 @@
#include "ultra64/asm.h"
-#include "ultra64/r4300.h"
+#include "ultra64/R4300.h"
.set noreorder
diff --git a/src/libultra/os/unmaptlball.s b/src/libultra/os/unmaptlball.s
index d7fe7cf53b..e1a03b1a23 100644
--- a/src/libultra/os/unmaptlball.s
+++ b/src/libultra/os/unmaptlball.s
@@ -1,5 +1,5 @@
#include "ultra64/asm.h"
-#include "ultra64/r4300.h"
+#include "ultra64/R4300.h"
.set noreorder
diff --git a/src/libultra/os/writebackdcache.s b/src/libultra/os/writebackdcache.s
index 4eea0d83a3..829f6f4a05 100644
--- a/src/libultra/os/writebackdcache.s
+++ b/src/libultra/os/writebackdcache.s
@@ -1,5 +1,5 @@
#include "ultra64/asm.h"
-#include "ultra64/r4300.h"
+#include "ultra64/R4300.h"
.set noat
.set noreorder
diff --git a/src/libultra/os/writebackdcacheall.s b/src/libultra/os/writebackdcacheall.s
index 837495c761..54a58dff8a 100644
--- a/src/libultra/os/writebackdcacheall.s
+++ b/src/libultra/os/writebackdcacheall.s
@@ -1,5 +1,5 @@
#include "ultra64/asm.h"
-#include "ultra64/r4300.h"
+#include "ultra64/R4300.h"
.set noat
.set noreorder
diff --git a/src/overlays/actors/ovl_Bg_Mori_Hashigo/z_bg_mori_hashigo.h b/src/overlays/actors/ovl_Bg_Mori_Hashigo/z_bg_mori_hashigo.h
index 35281d5c7a..fc5d99cc34 100644
--- a/src/overlays/actors/ovl_Bg_Mori_Hashigo/z_bg_mori_hashigo.h
+++ b/src/overlays/actors/ovl_Bg_Mori_Hashigo/z_bg_mori_hashigo.h
@@ -20,7 +20,7 @@ typedef struct BgMoriHashigo {
typedef enum {
/* -1 */ HASHIGO_CLASP = -1,
- /* 0 */ HASHIGO_LADDER
+ /* 0 */ HASHIGO_LADDER
} HasigoType;
#endif
diff --git a/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c b/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c
index 5443da2100..ebd4255d90 100644
--- a/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c
+++ b/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c
@@ -134,7 +134,7 @@ void func_808BB0AC(BgTokiSwd* this, PlayState* play) {
if (Actor_HasParent(&this->actor, play)) {
if (!LINK_IS_ADULT) {
Audio_PlayActorSfx2(&this->actor, NA_SE_IT_SWORD_PUTAWAY_STN);
- this->actor.draw = NULL; // sword has been pulled, dont draw sword
+ this->actor.draw = NULL; // sword has been pulled, don't draw sword
} else {
this->actor.draw = BgTokiSwd_Draw; // sword has been placed, draw the master sword
}
diff --git a/src/overlays/actors/ovl_Demo_6K/z_demo_6k.c b/src/overlays/actors/ovl_Demo_6K/z_demo_6k.c
index cf649244d5..435889305f 100644
--- a/src/overlays/actors/ovl_Demo_6K/z_demo_6k.c
+++ b/src/overlays/actors/ovl_Demo_6K/z_demo_6k.c
@@ -812,7 +812,7 @@ void func_809691BC(Demo6K* this, PlayState* play, s32 params) {
temp = Environment_LerpWeight(csAction->endFrame, csAction->startFrame, play->csCtx.frames);
- this->actor.world.pos.x = (((endPos.x - startPos.x) * temp) + startPos.x);
- this->actor.world.pos.y = (((endPos.y - startPos.y) * temp) + startPos.y);
- this->actor.world.pos.z = (((endPos.z - startPos.z) * temp) + startPos.z);
+ this->actor.world.pos.x = LERP(startPos.x, endPos.x, temp);
+ this->actor.world.pos.y = LERP(startPos.y, endPos.y, temp);
+ this->actor.world.pos.z = LERP(startPos.z, endPos.z, temp);
}
diff --git a/src/overlays/actors/ovl_Demo_Du/z_demo_du.c b/src/overlays/actors/ovl_Demo_Du/z_demo_du.c
index 74344ffa9b..305b542968 100644
--- a/src/overlays/actors/ovl_Demo_Du/z_demo_du.c
+++ b/src/overlays/actors/ovl_Demo_Du/z_demo_du.c
@@ -454,9 +454,9 @@ void DemoDu_CsGoronsRuby_DaruniaFalling(DemoDu* this, PlayState* play) {
endPos.y = npcAction->endPos.y;
endPos.z = npcAction->endPos.z;
- pos->x = ((endPos.x - startPos.x) * traveledPercent) + startPos.x;
- pos->y = ((endPos.y - startPos.y) * traveledPercent) + startPos.y;
- pos->z = ((endPos.z - startPos.z) * traveledPercent) + startPos.z;
+ pos->x = LERP(startPos.x, endPos.x, traveledPercent);
+ pos->y = LERP(startPos.y, endPos.y, traveledPercent);
+ pos->z = LERP(startPos.z, endPos.z, traveledPercent);
}
}
}
diff --git a/src/overlays/actors/ovl_En_Arrow/z_en_arrow.h b/src/overlays/actors/ovl_En_Arrow/z_en_arrow.h
index f250cafe30..9dee2f8f04 100644
--- a/src/overlays/actors/ovl_En_Arrow/z_en_arrow.h
+++ b/src/overlays/actors/ovl_En_Arrow/z_en_arrow.h
@@ -27,17 +27,17 @@ typedef struct EnArrow {
typedef enum {
/* -10 */ ARROW_CS_NUT = -10, // cutscene deku nuts are allowed to update in blocking mode
- /* -1 */ ARROW_NORMAL_SILENT = -1, // normal arrow that does not make a sound when being shot
- /* 0 */ ARROW_NORMAL_LIT, // normal arrow lit on fire
- /* 1 */ ARROW_NORMAL_HORSE, // normal arrow shot while riding a horse
- /* 2 */ ARROW_NORMAL,
- /* 3 */ ARROW_FIRE,
- /* 4 */ ARROW_ICE,
- /* 5 */ ARROW_LIGHT,
- /* 6 */ ARROW_0C,
- /* 7 */ ARROW_0D,
- /* 8 */ ARROW_0E,
- /* 9 */ ARROW_SEED,
+ /* -1 */ ARROW_NORMAL_SILENT = -1, // normal arrow that does not make a sound when being shot
+ /* 0 */ ARROW_NORMAL_LIT, // normal arrow lit on fire
+ /* 1 */ ARROW_NORMAL_HORSE, // normal arrow shot while riding a horse
+ /* 2 */ ARROW_NORMAL,
+ /* 3 */ ARROW_FIRE,
+ /* 4 */ ARROW_ICE,
+ /* 5 */ ARROW_LIGHT,
+ /* 6 */ ARROW_0C,
+ /* 7 */ ARROW_0D,
+ /* 8 */ ARROW_0E,
+ /* 9 */ ARROW_SEED,
/* 10 */ ARROW_NUT
} ArrowType;
diff --git a/src/overlays/actors/ovl_En_Eg/z_en_eg.c b/src/overlays/actors/ovl_En_Eg/z_en_eg.c
index 591624ce1f..6ef0636c61 100644
--- a/src/overlays/actors/ovl_En_Eg/z_en_eg.c
+++ b/src/overlays/actors/ovl_En_Eg/z_en_eg.c
@@ -16,7 +16,7 @@ void EnEg_Draw(Actor* thisx, PlayState* play);
void func_809FFDC8(EnEg* this, PlayState* play);
-static s32 voided = false;
+static s32 sVoided = false;
static EnEgActionFunc sActionFuncs[] = {
func_809FFDC8,
@@ -48,14 +48,14 @@ void EnEg_Init(Actor* thisx, PlayState* play) {
}
void func_809FFDC8(EnEg* this, PlayState* play) {
- if (!voided && (gSaveContext.timer2Value < 1) && Flags_GetSwitch(play, 0x36) && (kREG(0) == 0)) {
+ if (!sVoided && (gSaveContext.timer2Value < 1) && Flags_GetSwitch(play, 0x36) && (kREG(0) == 0)) {
// Void the player out
Play_TriggerRespawn(play);
gSaveContext.respawnFlag = -2;
SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_BGM_MAIN, 0);
play->transitionType = TRANS_TYPE_FADE_BLACK;
EnEg_PlayVoidOutSFX();
- voided = true;
+ sVoided = true;
}
}
diff --git a/src/overlays/actors/ovl_En_Horse/z_en_horse.h b/src/overlays/actors/ovl_En_Horse/z_en_horse.h
index fb07caa697..5a2f47f1b0 100644
--- a/src/overlays/actors/ovl_En_Horse/z_en_horse.h
+++ b/src/overlays/actors/ovl_En_Horse/z_en_horse.h
@@ -5,16 +5,16 @@
#include "global.h"
typedef enum {
- /* 0 */ ENHORSE_ACT_FROZEN,
- /* 1 */ ENHORSE_ACT_INACTIVE,
- /* 2 */ ENHORSE_ACT_IDLE,
- /* 3 */ ENHORSE_ACT_FOLLOW_PLAYER,
- /* 4 */ ENHORSE_ACT_INGO_RACE,
- /* 5 */ ENHORSE_ACT_MOUNTED_IDLE,
- /* 6 */ ENHORSE_ACT_MOUNTED_IDLE_WHINNEYING,
- /* 7 */ ENHORSE_ACT_MOUNTED_TURN,
- /* 8 */ ENHORSE_ACT_MOUNTED_WALK,
- /* 9 */ ENHORSE_ACT_MOUNTED_TROT,
+ /* 0 */ ENHORSE_ACT_FROZEN,
+ /* 1 */ ENHORSE_ACT_INACTIVE,
+ /* 2 */ ENHORSE_ACT_IDLE,
+ /* 3 */ ENHORSE_ACT_FOLLOW_PLAYER,
+ /* 4 */ ENHORSE_ACT_INGO_RACE,
+ /* 5 */ ENHORSE_ACT_MOUNTED_IDLE,
+ /* 6 */ ENHORSE_ACT_MOUNTED_IDLE_WHINNEYING,
+ /* 7 */ ENHORSE_ACT_MOUNTED_TURN,
+ /* 8 */ ENHORSE_ACT_MOUNTED_WALK,
+ /* 9 */ ENHORSE_ACT_MOUNTED_TROT,
/* 10 */ ENHORSE_ACT_MOUNTED_GALLOP,
/* 11 */ ENHORSE_ACT_MOUNTED_REARING,
/* 12 */ ENHORSE_ACT_STOPPING,
diff --git a/src/overlays/actors/ovl_Obj_Makekinsuta/z_obj_makekinsuta.h b/src/overlays/actors/ovl_Obj_Makekinsuta/z_obj_makekinsuta.h
index 72aec99c56..5cd76798c1 100644
--- a/src/overlays/actors/ovl_Obj_Makekinsuta/z_obj_makekinsuta.h
+++ b/src/overlays/actors/ovl_Obj_Makekinsuta/z_obj_makekinsuta.h
@@ -9,10 +9,10 @@ struct ObjMakekinsuta;
typedef void (*ObjMakekinsutaActionFunc)(struct ObjMakekinsuta*, PlayState*);
typedef struct ObjMakekinsuta {
- /* 0x0000 */ Actor actor;
- /* 0x014C */ ObjMakekinsutaActionFunc actionFunc;
- /* 0x150 */ s16 timer;
- /* 0x152 */ s16 unk_152;
-} ObjMakekinsuta; // size = 0x0154
+ /* 0x000 */ Actor actor;
+ /* 0x14C */ ObjMakekinsutaActionFunc actionFunc;
+ /* 0x150 */ s16 timer;
+ /* 0x152 */ s16 unk_152;
+} ObjMakekinsuta; // size = 0x154
#endif
diff --git a/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c b/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c
index bf8b33f80a..73d78a5552 100644
--- a/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c
+++ b/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c
@@ -849,8 +849,8 @@ void ObjectKankyo_DrawSunGraveSpark(Actor* thisx, PlayState* play2) {
weight = Environment_LerpWeight(play->csCtx.npcActions[1]->endFrame, play->csCtx.npcActions[1]->startFrame,
play->csCtx.frames);
- Matrix_Translate((end.x - start.x) * weight + start.x, (end.y - start.y) * weight + start.y,
- (end.z - start.z) * weight + start.z, MTXMODE_NEW);
+ Matrix_Translate(LERP(start.x, end.x, weight), LERP(start.y, end.y, weight), LERP(start.z, end.z, weight),
+ MTXMODE_NEW);
Matrix_Scale(this->effects[0].size, this->effects[0].size, this->effects[0].size, MTXMODE_APPLY);
Gfx_SetupDL_25Xlu(play->state.gfxCtx);
gDPPipeSync(POLY_XLU_DISP++);
diff --git a/src/overlays/actors/ovl_player_actor/z_player.c b/src/overlays/actors/ovl_player_actor/z_player.c
index f348f913fb..f341f514a3 100644
--- a/src/overlays/actors/ovl_player_actor/z_player.c
+++ b/src/overlays/actors/ovl_player_actor/z_player.c
@@ -5401,11 +5401,7 @@ s32 func_8083B644(Player* this, PlayState* play) {
this->targetActor = NULL;
if (sp28 || !sp24) {
- if (this->naviTextId >= 0) {
- sp2C->textId = this->naviTextId;
- } else {
- sp2C->textId = -this->naviTextId;
- }
+ sp2C->textId = ABS(this->naviTextId);
} else {
if (sp2C->naviEnemyId != NAVI_ENEMY_NONE) {
sp2C->textId = sp2C->naviEnemyId + 0x600;
@@ -12891,11 +12887,7 @@ void func_8084F104(Player* this, PlayState* play) {
GetItemEntry* giEntry = &sGetItemTable[D_80854528[this->exchangeItemId - 1] - 1];
if (this->itemAction >= PLAYER_IA_LETTER_ZELDA) {
- if (giEntry->gi >= 0) {
- this->unk_862 = giEntry->gi;
- } else {
- this->unk_862 = -giEntry->gi;
- }
+ this->unk_862 = ABS(giEntry->gi);
}
if (this->unk_850 == 0) {
diff --git a/src/overlays/effects/ovl_Effect_Ss_G_Spk/z_eff_ss_g_spk.c b/src/overlays/effects/ovl_Effect_Ss_G_Spk/z_eff_ss_g_spk.c
index f2858afd78..be37446a40 100644
--- a/src/overlays/effects/ovl_Effect_Ss_G_Spk/z_eff_ss_g_spk.c
+++ b/src/overlays/effects/ovl_Effect_Ss_G_Spk/z_eff_ss_g_spk.c
@@ -128,7 +128,7 @@ void EffectSsGSpk_Update(PlayState* play, u32 index, EffectSs* this) {
}
// this update mode is unused in the original game
-// with this update mode, the sparks dont move randomly in the xz plane, appearing to be on top of each other
+// with this update mode, the sparks don't move randomly in the xz plane, appearing to be on top of each other
void EffectSsGSpk_UpdateNoAccel(PlayState* play, u32 index, EffectSs* this) {
if (this->actor != NULL) {
if ((this->actor->category == ACTORCAT_EXPLOSIVE) && (this->actor->update != NULL)) {
diff --git a/src/overlays/gamestates/ovl_file_choose/z_file_nameset_PAL.c b/src/overlays/gamestates/ovl_file_choose/z_file_nameset_PAL.c
index 43202108b7..a7050e208d 100644
--- a/src/overlays/gamestates/ovl_file_choose/z_file_nameset_PAL.c
+++ b/src/overlays/gamestates/ovl_file_choose/z_file_nameset_PAL.c
@@ -561,7 +561,7 @@ void FileSelect_UpdateKeyboardCursor(GameState* thisx) {
this->kbdY--;
if (this->kbdY < 0) {
- // dont go to bottom row
+ // don't go to bottom row
if (this->kbdX < 8) {
this->kbdY = 4;
this->charIndex = (s32)(this->kbdX + 52);