From efe485f01720034ea9e844b3f385e3352bb63b20 Mon Sep 17 00:00:00 2001 From: Tharo <17233964+Thar0@users.noreply.github.com> Date: Sun, 13 Nov 2022 07:16:01 +0000 Subject: [PATCH 1/4] Improve rcp.h, remove `HW_REG` macro (#1425) * Real rcp.h * Correction to comment in initialize.c * Try fix R4300.h * Adjust rcp.h formatting, remove defines in other headers that are now in rcp.h * Suggested changes, document a bug in the modified osAiSetNextBuffer * More rcp.h formatting changes --- include/libc/math.h | 2 +- include/ultra64.h | 6 +- include/ultra64/{r4300.h => R4300.h} | 2 +- include/ultra64/controller.h | 13 - include/ultra64/exception.h | 2 +- include/ultra64/pi.h | 6 - include/ultra64/printf.h | 2 +- include/ultra64/rcp.h | 904 +++++++++++++++++++--- include/ultra64/rdb.h | 2 +- include/ultra64/rdp.h | 51 -- include/ultra64/rsp.h | 50 -- include/ultra64/sptask.h | 2 +- include/ultra64/thread.h | 2 +- include/ultra64/ucode.h | 2 +- include/ultra64/{types.h => ultratypes.h} | 8 +- include/z64curve.h | 2 +- src/code/graph.c | 8 +- src/code/rcp_utils.c | 2 +- src/libultra/gu/sintable.inc.c | 2 +- src/libultra/io/aigetlen.c | 8 +- src/libultra/io/aisetfreq.c | 27 +- src/libultra/io/aisetnextbuf.c | 41 +- src/libultra/io/cartrominit.c | 59 +- src/libultra/io/devmgr.c | 2 +- src/libultra/io/dpgetstat.c | 2 +- src/libultra/io/dpsetstat.c | 2 +- src/libultra/io/driverominit.c | 42 +- src/libultra/io/epirawdma.c | 32 +- src/libultra/io/epirawread.c | 24 +- src/libultra/io/epirawwrite.c | 24 +- src/libultra/io/pirawdma.c | 15 +- src/libultra/io/si.c | 7 +- src/libultra/io/sirawdma.c | 14 +- src/libultra/io/sirawread.c | 2 +- src/libultra/io/sirawwrite.c | 2 +- src/libultra/io/sp.c | 2 +- src/libultra/io/spgetstat.c | 2 +- src/libultra/io/sprawdma.c | 8 +- src/libultra/io/spsetpc.c | 5 +- src/libultra/io/spsetstat.c | 2 +- src/libultra/io/sptask.c | 2 +- src/libultra/io/vi.c | 9 +- src/libultra/io/viswapcontext.c | 28 +- src/libultra/os/exceptasm.s | 3 +- src/libultra/os/getcause.s | 2 +- src/libultra/os/getcount.s | 2 +- src/libultra/os/getfpccsr.s | 2 +- src/libultra/os/getsr.s | 2 +- src/libultra/os/initialize.c | 69 +- src/libultra/os/interrupt.s | 2 +- src/libultra/os/invaldcache.s | 2 +- src/libultra/os/invalicache.s | 2 +- src/libultra/os/maptlbrdb.s | 2 +- src/libultra/os/probetlb.s | 2 +- src/libultra/os/setcompare.s | 2 +- src/libultra/os/setfpccsr.s | 2 +- src/libultra/os/setintmask.s | 2 +- src/libultra/os/setsr.s | 2 +- src/libultra/os/setwatchlo.s | 2 +- src/libultra/os/unmaptlball.s | 2 +- src/libultra/os/writebackdcache.s | 2 +- src/libultra/os/writebackdcacheall.s | 2 +- 62 files changed, 1058 insertions(+), 477 deletions(-) rename include/ultra64/{r4300.h => R4300.h} (99%) delete mode 100644 include/ultra64/rdp.h delete mode 100644 include/ultra64/rsp.h rename include/ultra64/{types.h => ultratypes.h} (91%) 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/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/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/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/src/code/graph.c b/src/code/graph.c index 0deb81fb80..bbd87434cc 100644 --- a/src/code/graph.c +++ b/src/code/graph.c @@ -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) { 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/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..5d1ce6e9ac 100644 --- a/src/libultra/io/devmgr.c +++ b/src/libultra/io/devmgr.c @@ -43,7 +43,7 @@ void __osDevMgrMain(void* arg) { __osEPiRawWriteIo(ioMesg->piHandle, 0x05000510, transfer->bmCtlShadow | 0x1000000); } block->errStatus = 4; - HW_REG(PI_STATUS_REG, u32) = PI_STATUS_CLR_INTR; + 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); 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/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/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..6e4db3f8d7 100644 --- a/src/libultra/io/vi.c +++ b/src/libultra/io/vi.c @@ -11,8 +11,8 @@ void __osViInit(void) { __osViNext->retraceCount = 1; __osViCurr->retraceCount = 1; - __osViNext->buffer = (void*)0x80000000; - __osViCurr->buffer = (void*)0x80000000; + __osViNext->buffer = (void*)K0BASE; + __osViCurr->buffer = (void*)K0BASE; if (osTvType == OS_TV_PAL) { __osViNext->modep = &osViModePalLan1; @@ -25,10 +25,9 @@ void __osViInit(void) { __osViNext->state = 0x20; __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/viswapcontext.c b/src/libultra/io/viswapcontext.c index d82d5cce65..7a46fb7bd1 100644 --- a/src/libultra/io/viswapcontext.c +++ b/src/libultra/io/viswapcontext.c @@ -13,7 +13,7 @@ void __osViSwapContext(void) { field = 0; viNext = __osViNext; viMode = viNext->modep; - field = HW_REG(VI_V_CURRENT_LINE_REG, u32) & 1; + field = IO_READ(VI_V_CURRENT_LINE_REG) & 1; s2 = osVirtualToPhysical(viNext->buffer); origin = (viMode->fldRegs[field].origin) + s2; if (viNext->state & 2) { @@ -43,19 +43,19 @@ void __osViSwapContext(void) { viNext->y.scale = (viNext->y.offset << 0x10) & 0x3FF0000; origin = osVirtualToPhysical(viNext->buffer); } - 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 From abb4201e57ed2200b745a5dc067665818141ca3e Mon Sep 17 00:00:00 2001 From: Dragorn421 Date: Sun, 13 Nov 2022 23:47:25 +0100 Subject: [PATCH 2/4] Fix misc 18 (#1423) * two more ABS * fixup item_name_static texs outnames * fixup CollisionCheck_SetOCvsOC docs * Cleanup int comments alignments * collsion -> collision * `SQ*` macros fixup * use `LERP` more * static -> `s` prefix * grammar: dont -> don't * 3 --- assets/xml/textures/item_name_static.xml | 6 ++-- include/z64collision_check.h | 20 ++++++------ include/z64environment.h | 20 ++++++------ include/z64math.h | 8 ++--- include/z64ocarina.h | 6 ++-- src/code/z_camera.c | 6 ++-- src/code/z_collision_check.c | 32 +++++++++---------- src/code/z_effect_soft_sprite_old_init.c | 2 +- .../ovl_Bg_Mori_Hashigo/z_bg_mori_hashigo.h | 2 +- .../actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c | 2 +- src/overlays/actors/ovl_Demo_6K/z_demo_6k.c | 6 ++-- src/overlays/actors/ovl_Demo_Du/z_demo_du.c | 6 ++-- src/overlays/actors/ovl_En_Arrow/z_en_arrow.h | 22 ++++++------- src/overlays/actors/ovl_En_Eg/z_en_eg.c | 6 ++-- src/overlays/actors/ovl_En_Horse/z_en_horse.h | 20 ++++++------ .../ovl_Obj_Makekinsuta/z_obj_makekinsuta.h | 10 +++--- .../ovl_Object_Kankyo/z_object_kankyo.c | 4 +-- .../actors/ovl_player_actor/z_player.c | 12 ++----- .../ovl_Effect_Ss_G_Spk/z_eff_ss_g_spk.c | 2 +- .../ovl_file_choose/z_file_nameset_PAL.c | 2 +- 20 files changed, 93 insertions(+), 101 deletions(-) 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/z64collision_check.h b/include/z64collision_check.h index 383bbbc009..b0b6879d93 100644 --- a/include/z64collision_check.h +++ b/include/z64collision_check.h @@ -231,16 +231,16 @@ typedef struct { } OcLine; // size = 0x1C 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/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/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 fd7069761f..6ac812d6bf 100644 --- a/src/code/z_collision_check.c +++ b/src/code/z_collision_check.c @@ -2648,8 +2648,8 @@ void CollisionCheck_SetOCvsOC(Collider* left, ColliderInfo* leftInfo, Vec3f* lef f32 zDelta; Actor* leftActor = left->actor; Actor* rightActor = right->actor; - s32 leftMassType; s32 rightMassType; + s32 leftMassType; left->ocFlags1 |= OC1_HIT; left->oc = rightActor; @@ -2666,8 +2666,8 @@ void CollisionCheck_SetOCvsOC(Collider* left, ColliderInfo* leftInfo, Vec3f* lef if (leftActor == NULL || rightActor == NULL || left->ocFlags1 & OC1_NO_PUSH || right->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; @@ -2679,30 +2679,30 @@ void CollisionCheck_SetOCvsOC(Collider* left, ColliderInfo* leftInfo, Vec3f* lef 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; } @@ -3494,7 +3494,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; } @@ -3511,10 +3511,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/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 474ee4eccb..e1f2b7fe93 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); 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 3/4] 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; From 6d5287ff12919332eff421ad833ba0b7421f6158 Mon Sep 17 00:00:00 2001 From: Tharo <17233964+Thar0@users.noreply.github.com> Date: Sun, 13 Nov 2022 23:29:50 +0000 Subject: [PATCH 4/4] TwoHeadArena and TwoHeadGfxArena docs (#1349) * TwoHeadArena and TwoHeadGfxArena docs, ALIGNOF macro * AllocStart -> AllocHead , AllocEnd -> AllocTail * Format * Suggested changes * Fix * Further suggested changes --- include/alignment.h | 12 +++ include/functions.h | 29 ------ include/tha.h | 28 ++++++ include/thga.h | 33 +++++++ include/z64.h | 16 +--- spec | 1 + src/code/TwoHeadArena.c | 179 ++++++++++++++++++------------------- src/code/TwoHeadGfxArena.c | 102 +++++++++++++++++++++ src/code/game.c | 28 +++--- src/code/graph.c | 16 ++-- src/code/speed_meter.c | 9 +- src/code/z_bgcheck.c | 15 ++-- src/code/z_play.c | 4 +- 13 files changed, 302 insertions(+), 170 deletions(-) create mode 100644 include/tha.h create mode 100644 include/thga.h create mode 100644 src/code/TwoHeadGfxArena.c 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 9a42f50ff7..3502a6dc96 100644 --- a/include/functions.h +++ b/include/functions.h @@ -1460,35 +1460,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/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/z64.h b/include/z64.h index 526921d074..8cfcfd160b 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" diff --git a/spec b/spec index dd2dc1036b..a8a6dbb534 100644 --- a/spec +++ b/spec @@ -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/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 b004dd3676..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; } @@ -325,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); } @@ -340,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) { @@ -360,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); @@ -441,7 +441,7 @@ void GameState_Destroy(GameState* gameState) { 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); @@ -467,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; @@ -488,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 bbd87434cc..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; @@ -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/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_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);