summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTharo <17233964+Thar0@users.noreply.github.com>2022-11-13 07:16:01 +0000
committerGitHub <noreply@github.com>2022-11-13 02:16:01 -0500
commitefe485f01720034ea9e844b3f385e3352bb63b20 (patch)
tree40650cd20948aace578932bc1dafa402e814feaa
parentd8175501adac32dd10918f67f1a7ea278e2ed862 (diff)
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
-rw-r--r--include/libc/math.h2
-rw-r--r--include/ultra64.h6
-rw-r--r--include/ultra64/R4300.h (renamed from include/ultra64/r4300.h)2
-rw-r--r--include/ultra64/controller.h13
-rw-r--r--include/ultra64/exception.h2
-rw-r--r--include/ultra64/pi.h6
-rw-r--r--include/ultra64/printf.h2
-rw-r--r--include/ultra64/rcp.h936
-rw-r--r--include/ultra64/rdb.h2
-rw-r--r--include/ultra64/rdp.h51
-rw-r--r--include/ultra64/rsp.h50
-rw-r--r--include/ultra64/sptask.h2
-rw-r--r--include/ultra64/thread.h2
-rw-r--r--include/ultra64/ucode.h2
-rw-r--r--include/ultra64/ultratypes.h (renamed from include/ultra64/types.h)8
-rw-r--r--include/z64curve.h2
-rw-r--r--src/code/graph.c8
-rw-r--r--src/code/rcp_utils.c2
-rw-r--r--src/libultra/gu/sintable.inc.c2
-rw-r--r--src/libultra/io/aigetlen.c8
-rw-r--r--src/libultra/io/aisetfreq.c27
-rw-r--r--src/libultra/io/aisetnextbuf.c41
-rw-r--r--src/libultra/io/cartrominit.c65
-rw-r--r--src/libultra/io/devmgr.c2
-rw-r--r--src/libultra/io/dpgetstat.c2
-rw-r--r--src/libultra/io/dpsetstat.c2
-rw-r--r--src/libultra/io/driverominit.c46
-rw-r--r--src/libultra/io/epirawdma.c32
-rw-r--r--src/libultra/io/epirawread.c24
-rw-r--r--src/libultra/io/epirawwrite.c24
-rw-r--r--src/libultra/io/pirawdma.c15
-rw-r--r--src/libultra/io/si.c7
-rw-r--r--src/libultra/io/sirawdma.c14
-rw-r--r--src/libultra/io/sirawread.c2
-rw-r--r--src/libultra/io/sirawwrite.c2
-rw-r--r--src/libultra/io/sp.c2
-rw-r--r--src/libultra/io/spgetstat.c2
-rw-r--r--src/libultra/io/sprawdma.c8
-rw-r--r--src/libultra/io/spsetpc.c5
-rw-r--r--src/libultra/io/spsetstat.c2
-rw-r--r--src/libultra/io/sptask.c2
-rw-r--r--src/libultra/io/vi.c9
-rw-r--r--src/libultra/io/viswapcontext.c28
-rw-r--r--src/libultra/os/exceptasm.s3
-rw-r--r--src/libultra/os/getcause.s2
-rw-r--r--src/libultra/os/getcount.s2
-rw-r--r--src/libultra/os/getfpccsr.s2
-rw-r--r--src/libultra/os/getsr.s2
-rw-r--r--src/libultra/os/initialize.c65
-rw-r--r--src/libultra/os/interrupt.s2
-rw-r--r--src/libultra/os/invaldcache.s2
-rw-r--r--src/libultra/os/invalicache.s2
-rw-r--r--src/libultra/os/maptlbrdb.s2
-rw-r--r--src/libultra/os/probetlb.s2
-rw-r--r--src/libultra/os/setcompare.s2
-rw-r--r--src/libultra/os/setfpccsr.s2
-rw-r--r--src/libultra/os/setintmask.s2
-rw-r--r--src/libultra/os/setsr.s2
-rw-r--r--src/libultra/os/setwatchlo.s2
-rw-r--r--src/libultra/os/unmaptlball.s2
-rw-r--r--src/libultra/os/writebackdcache.s2
-rw-r--r--src/libultra/os/writebackdcacheall.s2
62 files changed, 1077 insertions, 496 deletions
diff --git a/include/libc/math.h b/include/libc/math.h
index b41cb8e52..2858084eb 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 e53e7a751..6eadfb6af 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
index 42782f80c..6398ea17c 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 313809bf6..8b759db77 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 c101bc5ce..7d4977f4f 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 855718995..6fb52cea7 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 7724432f6..4f2e29730 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 d92b743c6..86387ef5e 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"
+
+/**
+ * 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
+ */
+
+
+/**
+ * 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
-#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
-
-#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
+/*
+ * 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
-
-#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
-
-#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
-
-// PI_STATUS (read) bits
-#define PI_STATUS_BUSY (1 << 0)
-#define PI_STATUS_IOBUSY (1 << 1)
-#define PI_STATUS_ERROR (1 << 2)
-
-// PI_STATUS (write) bits
-#define PI_STATUS_RESET (1 << 0)
-#define PI_STATUS_CLR_INTR (1 << 1)
-
-#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
-
-// 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)
-
-#define PIF_RAM_START 0x1FC007C0
-
-#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
-
-// 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)
-
-// 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)
-
-// 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
-
-#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 */
+
+// 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
+
+// VI vertical sync (R/W): [9:0] number of half-lines per field
+#define VI_V_SYNC_REG (VI_BASE_REG + 0x18)
+
+// 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)
+
+// 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
+
+// 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
+
+// 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
+
+// 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)
+
+// 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)
+
+// 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)
+
+/*
+ * 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
+
+/*
+ * 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
+
+
+/**
+ * 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
+
+// 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 31442b587..0493b82b9 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 8729a3fa8..000000000
--- 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 dcc9dadc7..000000000
--- 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 06b4f7709..ea00dbfdf 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 5adb689dd..474a63641 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 a525b2483..00ef36ac2 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
index 84ee3cc6c..e4a305370 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 a526effcb..1864f2116 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 0deb81fb8..bbd87434c 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 5c14c39f9..e258ab02f 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 d430d65ae..2753d55a9 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 58d8db487..45be44251 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 8702941b9..9e1b8c44e 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 56a7e4e6e..4cf5d1f7d 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 231b00768..b2cf1d1e1 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);
-
- 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;
-
- 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;
-
- 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;
+ 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);
+
+ 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);
+
+ value = IO_READ(__CartRomHandle.baseAddress);
+ __CartRomHandle.latency = value & 0xFF;
+ __CartRomHandle.pageSize = (value >> 0x10) & 0xF;
+ __CartRomHandle.relDuration = (value >> 0x14) & 0xF;
+ __CartRomHandle.pulse = (value >> 8) & 0xFF;
+
+ 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 e8581d821..5d1ce6e9a 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 b5267b060..1a944b2c7 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 ecd3f77e0..4275e1fde 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 d6247298a..7d1441cdd 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;
-
- 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;
-
- 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, 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);
+
+ value = IO_READ(__DriveRomHandle.baseAddress);
+ __DriveRomHandle.latency = value & 0xFF;
+ __DriveRomHandle.pulse = (value >> 8) & 0xFF;
+ __DriveRomHandle.pageSize = (value >> 0x10) & 0xF;
+ __DriveRomHandle.relDuration = (value >> 0x14) & 0xF;
+
+ 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 ccc23f708..ff6bb9a65 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 5a3109364..41997df66 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 2c24c5e25..4d704a192 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 d3dda984c..84f809c9c 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 789815312..4afee0340 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 00b80b4b0..9bf499cc6 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 61b2d730e..8efa071ef 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 a1935c2e2..f0e4514d7 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 67ccd8939..1796dc8f6 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 99a4ad0a1..e1545bdb7 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 6a1b01b2a..795282c4a 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 2c3cc32ba..944fc9863 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 b2f97a3ff..3fa7a4918 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 bd9b5fdf2..8b3286a45 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 12905742e..6e4db3f8d 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 d82d5cce6..7a46fb7bd 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 d6bd3082c..16ff4f579 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 48fbf3236..a621e9736 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 bad47d0bc..242c9da69 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 d86734ad0..93d4e51b8 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 aed66d40a..dc6901b98 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 d3998c0bb..3266d1e4d 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_START + 0x3C), sp2C | 8)) {
+ while (__osSiRawWriteIo((void*)(PIF_RAM_END - 3), pifdata | 8)) {
;
}
- *(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
+ *(__osExceptionVector*)UT_VEC = __osExceptionPreamble; // TLB miss
+ *(__osExceptionVector*)XUT_VEC = __osExceptionPreamble; // XTLB miss
+ *(__osExceptionVector*)ECC_VEC = __osExceptionPreamble; // cache errors
+ *(__osExceptionVector*)E_VEC = __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 82090742b..829377bb0 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 41799d318..9464a24da 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 79d576fba..55f831238 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 ea8fe4aa4..c3ac20948 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 ce655faca..7bc7856e1 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 4b69b2ea9..bd1653377 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 9b6b368f3..1aa0e7d29 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 3afadb73a..3d2bc5b9c 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 382f2eada..b754359ea 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 749b1dbd8..aee3ad4d6 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 d7fe7cf53..e1a03b1a2 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 4eea0d83a..829f6f4a0 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 837495c76..54a58dff8 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