From c165ed015c8cbd379fafaad11146bf909aedf647 Mon Sep 17 00:00:00 2001 From: Tharo <17233964+Thar0@users.noreply.github.com> Date: Sun, 13 Nov 2022 23:07:27 +0000 Subject: [PATCH] Improvements to Video Interface related functions and data (#1332) * Improvements to VI related functions * Fix * Suggested changes * Comment enum values Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * Suggested changes, plus comments in visetspecial.c * Name gViConfigModeType * Further suggested changes * Format * Fix comment on modeLPN2 Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> --- include/functions.h | 8 +- include/macros.h | 1 + include/regs.h | 7 + include/sched.h | 2 +- include/ultra64/internal.h | 16 +- include/ultra64/leodrive.h | 47 ++++ include/ultra64/vi.h | 15 +- include/ultra64/viint.h | 37 +++ include/variables.h | 2 +- include/z64.h | 27 +- spec | 2 +- src/boot/idle.c | 8 +- src/code/game.c | 16 +- src/code/main.c | 2 +- src/code/sched.c | 2 +- src/code/z_vimode.c | 410 ++++++++++++++++------------ src/libultra/io/devmgr.c | 123 +++++---- src/libultra/io/epidma.c | 2 +- src/libultra/io/pigetcmdq.c | 2 +- src/libultra/io/pimgr.c | 16 +- src/libultra/io/vi.c | 7 +- src/libultra/io/viblack.c | 6 +- src/libultra/io/viextend.c | 5 - src/libultra/io/viextendvstart.c | 5 + src/libultra/io/vigetcurrframebuf.c | 4 +- src/libultra/io/vigetnextframebuf.c | 6 +- src/libultra/io/vimgr.c | 38 +-- src/libultra/io/vimodefpallan1.c | 54 ++-- src/libultra/io/vimodempallan1.c | 52 ++-- src/libultra/io/vimodentsclan1.c | 52 ++-- src/libultra/io/vimodepallan1.c | 54 ++-- src/libultra/io/visetmode.c | 3 +- src/libultra/io/visetspecial.c | 45 ++- src/libultra/io/visetxscale.c | 7 +- src/libultra/io/visetyscale.c | 3 +- src/libultra/io/viswapbuf.c | 7 +- src/libultra/io/viswapcontext.c | 38 +-- 37 files changed, 684 insertions(+), 447 deletions(-) create mode 100644 include/ultra64/leodrive.h create mode 100644 include/ultra64/viint.h delete mode 100644 src/libultra/io/viextend.c create mode 100644 src/libultra/io/viextendvstart.c diff --git a/include/functions.h b/include/functions.h index fded37cd10..9a42f50ff7 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); @@ -1291,8 +1291,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); 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/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/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 dcccd73199..526921d074 100644 --- a/include/z64.h +++ b/include/z64.h @@ -1725,20 +1725,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/spec b/spec index 4fdacf2b8e..dd2dc1036b 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" 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/game.c b/src/code/game.c index 297bd2c6e7..b004dd3676 100644 --- a/src/code/game.c +++ b/src/code/game.c @@ -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; } } @@ -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,7 +438,7 @@ 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); 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/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/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/io/devmgr.c b/src/libultra/io/devmgr.c index 5d1ce6e9ac..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; - IO_WRITE(PI_STATUS_REG, 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/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/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/vi.c b/src/libultra/io/vi.c index 6e4db3f8d7..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*)K0BASE; - __osViCurr->buffer = (void*)K0BASE; + __osViNext->framep = (void*)K0BASE; + __osViCurr->framep = (void*)K0BASE; if (osTvType == OS_TV_PAL) { __osViNext->modep = &osViModePalLan1; @@ -22,7 +23,7 @@ void __osViInit(void) { __osViNext->modep = &osViModeNtscLan1; } - __osViNext->state = 0x20; + __osViNext->state = VI_STATE_BLACK; __osViNext->features = __osViNext->modep->comRegs.ctrl; while (IO_READ(VI_CURRENT_REG) > 10) { 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 7a46fb7bd1..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,43 +7,43 @@ 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 = IO_READ(VI_V_CURRENT_LINE_REG) & 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); } + IO_WRITE(VI_ORIGIN_REG, origin); IO_WRITE(VI_WIDTH_REG, viMode->comRegs.width); IO_WRITE(VI_BURST_REG, viMode->comRegs.burst); @@ -56,6 +57,7 @@ void __osViSwapContext(void) { 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;