aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorspicyjpeg <88942473+spicyjpeg@users.noreply.github.com>2022-02-09 22:59:16 +0100
committerspicyjpeg <88942473+spicyjpeg@users.noreply.github.com>2022-02-09 22:59:16 +0100
commitaca79b2a75c9a6106bc0047f767a475a2c3aaf8e (patch)
treea9536efe30ce2d3a40414948494a0eda3e45dbbd
parentc083d3f18ecf80297b45eeda2abdf2fd6719cd7b (diff)
downloadpsn00bsdk-aca79b2a75c9a6106bc0047f767a475a2c3aaf8e.tar.gz
Rename hwregs_a definitions, add hwregs_c, fix io/pads
-rw-r--r--examples/io/pads/main.c57
-rw-r--r--examples/io/pads/spi.c103
-rw-r--r--examples/io/pads/spi.h15
-rw-r--r--examples/sound/spustream/main.c46
-rw-r--r--libpsn00b/include/hwregs_a.h174
-rw-r--r--libpsn00b/include/hwregs_c.h129
-rw-r--r--libpsn00b/psxapi/_initcd.s6
-rw-r--r--libpsn00b/psxcd/cdgetsector.s8
-rw-r--r--libpsn00b/psxcd/psxcd_asm.s8
-rw-r--r--libpsn00b/psxetc/dmacallback.s16
-rw-r--r--libpsn00b/psxetc/interruptcallback.s8
-rw-r--r--libpsn00b/psxetc/isr.s8
-rw-r--r--libpsn00b/psxetc/restartcallback.s4
-rw-r--r--libpsn00b/psxgpu/clearotagr.s6
-rw-r--r--libpsn00b/psxgpu/drawotag.s6
-rw-r--r--libpsn00b/psxgpu/drawsync.s4
-rw-r--r--libpsn00b/psxgpu/drawsynccallback.s2
-rw-r--r--libpsn00b/psxgpu/loadimage.s6
-rw-r--r--libpsn00b/psxgpu/resetgraph.s18
-rw-r--r--libpsn00b/psxgpu/storeimage.s6
-rw-r--r--libpsn00b/psxspu/spuinit.s57
-rw-r--r--libpsn00b/psxspu/spureverbon.s2
-rw-r--r--libpsn00b/psxspu/spusetreverb.s7
-rw-r--r--libpsn00b/psxspu/spusetreverbaddr.s8
-rw-r--r--libpsn00b/psxspu/transfer.s16
25 files changed, 426 insertions, 294 deletions
diff --git a/examples/io/pads/main.c b/examples/io/pads/main.c
index d100482..17bf331 100644
--- a/examples/io/pads/main.c
+++ b/examples/io/pads/main.c
@@ -15,12 +15,12 @@
* but the code in spi.c can be used to read/write sectors on a memory card and
* combined with a higher-level filesystem driver for full support.
*
- * IMPORTANT: this example hasn't yet been tested on real hardware and/or with
- * unofficial controllers, which might behave differently at higher poll rates.
- * Also keep in mind that many emulators emulate controllers and memory cards
- * inaccurately. It is thus recommended to test controller I/O code extensively
- * and handle as many edge cases as possible (e.g. partial but valid responses,
- * zerofilled responses, slow replies) for maximum compatibility.
+ * IMPORTANT: some controller models seem to be unable to respond to config
+ * mode commands reliably, even though simple high-speed polling usually works
+ * without issues. Also keep in mind that many emulators emulate controllers
+ * and memory cards inaccurately. It is thus recommended to test controller I/O
+ * code extensively and handle as many edge cases as possible (e.g. partial but
+ * valid responses, zerofilled responses, slow replies) for best compatibility.
*/
#include <stdint.h>
@@ -116,7 +116,7 @@ void display(CONTEXT *ctx) {
static volatile uint8_t pad_buff[2][34];
static volatile size_t pad_buff_len[2];
-static volatile uint32_t pad_digital_only[2] = { 0, 0 };
+static volatile uint32_t pad_config_attempt[2] = { 0, 0 };
// Just a wrapper around SPI_CreateRequest(). This does not send the command
// immediately but adds it to the driver's request queue.
@@ -148,7 +148,8 @@ void send_pad_cmd(
// This callback determines whether a pad that identified as digital is
// actually a DualShock in digital mode by checking if it started identifying
-// as CONFIG_MODE after receiving a configuration command.
+// as CONFIG_MODE after receiving a configuration command. Calls to printf()
+// had to be commented out due to them being too slow.
void dualshock_init_cb(uint32_t port, const volatile uint8_t *buff, size_t rx_len) {
PadResponse *pad = (PadResponse *) buff;
@@ -157,13 +158,13 @@ void dualshock_init_cb(uint32_t port, const volatile uint8_t *buff, size_t rx_le
(pad->prefix != 0x5a) ||
(pad->type != PAD_ID_CONFIG_MODE)
) {
- printf("no, pad is digital-only (len = %d)\n", rx_len);
+ //printf("no, pad is digital-only (len = %d)\n", rx_len);
- pad_digital_only[port] = 1;
+ pad_config_attempt[port]++;
return;
}
- printf("yes, forcing analog mode (len = %d)\n", rx_len);
+ //printf("yes, forcing analog mode (len = %d)\n", rx_len);
// Issue further commands to force analog mode on, unlock rumble (not used
// in this example) and enable longer responses containing button pressure
@@ -171,6 +172,7 @@ void dualshock_init_cb(uint32_t port, const volatile uint8_t *buff, size_t rx_le
// TODO: find out if passing 0x03 instead of 0x02 in PAD_CMD_SET_ANALOG
// locks the analog button, as emulated by DuckStation...
// https://gist.github.com/scanlime/5042071
+ send_pad_cmd(port, PAD_CMD_CONFIG_MODE, 0x01, 0x00, 0);
send_pad_cmd(port, PAD_CMD_SET_ANALOG, 0x01, 0x02, 0);
send_pad_cmd(port, PAD_CMD_INIT_PRESSURE, 0x00, 0x00, 0); // Ignored by DualShock 1
send_pad_cmd(port, PAD_CMD_REQUEST_CONFIG, 0x00, 0x01, 0);
@@ -189,29 +191,37 @@ void poll_cb(uint32_t port, const volatile uint8_t *buff, size_t rx_len) {
PadResponse *pad = (PadResponse *) buff;
- // If this pad identifies as a digital pad and hasn't been flagged as a
- // digital-only pad already, attempt to put it into analog mode by entering
- // configuration mode. It this fails, it will be flagged as digital-only.
- // The digital-only flag is reset when the controller is unplugged or stops
+ // If this pad identifies as a digital pad, attempt to put it into analog
+ // mode up to 3 times by entering configuration mode. Once the attempt
+ // counter exceeds the threshold, it will be treated as digital-only. The
+ // attempt counter is reset when the controller is unplugged or stops
// returning digital pad responses.
+ // NOTE: according to nocash docs, there is a hardware bug in DualShock
+ // controllers that causes the prefix byte (normally 0x5a) to turn into
+ // 0x00 if the analog button is pressed after config commands have been
+ // used.
if (
rx_len &&
- (pad->prefix == 0x5a) &&
+ ((pad->prefix == 0x5a) || !(pad->prefix)) &&
(pad->type == PAD_ID_DIGITAL)
) {
- if (!pad_digital_only[port]) {
- printf("Detecting if pad %d supports config mode... ", port + 1);
+ if (pad_config_attempt[port] < 3) {
+ /*printf(
+ "Detecting if pad %d supports config mode: attempt %d... ",
+ port + 1,
+ pad_config_attempt[port] + 1
+ );*/
// The pad only identifies as CONFIG_MODE after at least another
// command is sent.
send_pad_cmd(port, PAD_CMD_CONFIG_MODE, 0x01, 0x00, 0);
- send_pad_cmd(port, PAD_CMD_CONFIG_MODE, 0x01, 0x00, &dualshock_init_cb);
+ send_pad_cmd(port, PAD_CMD_READ, 0x00, 0x00, &dualshock_init_cb);
}
} else {
- //printf("Clearing digital-only flag for pad %d\n", port + 1);
+ //printf("Clearing attempt counter for pad %d\n", port + 1);
- pad_digital_only[port] = 0;
+ pad_config_attempt[port] = 0;
}
}
@@ -240,11 +250,6 @@ int main(int argc, const char* argv[]) {
PadResponse *pad = (PadResponse *) pad_buff[port];
- // According to nocash docs, there is a hardware bug in DualShock
- // controllers that causes the prefix byte (normally 0x5a) to turn
- // into 0x00 if the analog button is pressed after configuration
- // commands have been used. Thus making sure the prefix is 0x5a
- // isn't enough to reliably detect pads.
/*if ((pad->prefix != 0x5a) && (pad->type != PAD_ID_ANALOG)) {
FntPrint(-1, "\n\nPORT %d: INVALID RESPONSE\n", port + 1);
if ((counter % 64) < 32)
diff --git a/examples/io/pads/spi.c b/examples/io/pads/spi.c
index ef75ffc..05a0e59 100644
--- a/examples/io/pads/spi.c
+++ b/examples/io/pads/spi.c
@@ -32,43 +32,27 @@
#include <psxetc.h>
#include <psxapi.h>
#include <psxpad.h>
+#include <hwregs_c.h>
#include "spi.h"
-/* Register definitions */
-
-#define F_CPU 33868800UL
-
-#define TIM_VALUE(N) *((volatile uint32_t *) 0x1f801100 + 4 * (N))
-#define TIM_CTRL(N) *((volatile uint32_t *) 0x1f801104 + 4 * (N))
-#define TIM_RELOAD(N) *((volatile uint32_t *) 0x1f801108 + 4 * (N))
-
-// IMPORTANT: even though JOY_TXRX is a 32-bit register, it should only be
-// accessed as 8-bit. Reading it as 16 or 32-bit works fine on real hardware,
-// but leads to problems in some emulators.
-#define JOY_TXRX *((volatile uint8_t *) 0x1f801040)
-#define JOY_STAT *((volatile uint16_t *) 0x1f801044)
-#define JOY_MODE *((volatile uint16_t *) 0x1f801048)
-#define JOY_CTRL *((volatile uint16_t *) 0x1f80104a)
-#define JOY_BAUD *((volatile uint16_t *) 0x1f80104e)
-
/* Internal structures and globals */
-typedef struct _SPI_CONTEXT {
+typedef struct _SPI_Context {
uint8_t tx_buff[SPI_BUFF_LEN];
uint8_t rx_buff[SPI_BUFF_LEN];
uint32_t tx_len, rx_len, port;
SPI_Callback callback;
} SPI_Context;
-static volatile SPI_Context ctx;
-static volatile SPI_Request volatile *current_req;
-static SPI_Callback default_cb;
+static volatile SPI_Context _context;
+static volatile SPI_Request volatile *_current_req;
+static volatile SPI_Callback _default_cb;
/* Request queue management */
static void _spi_create_poll_req(void) {
- PadRequest *req = (PadRequest *) ctx.tx_buff;
+ PadRequest *req = (PadRequest *) _context.tx_buff;
req->addr = 0x01;
req->cmd = PAD_CMD_READ;
@@ -76,27 +60,31 @@ static void _spi_create_poll_req(void) {
req->motor_l = 0x00;
req->motor_r = 0x00;
- ctx.tx_len = 4;
- ctx.rx_len = 0;
- ctx.port ^= 1;
- ctx.callback = default_cb;
+ _context.tx_len = 4;
+ _context.rx_len = 0;
+ _context.port ^= 1;
+ _context.callback = _default_cb;
}
static void _spi_next_req(void) {
// Copy the contents of the first request in the queue into the TX buffer.
- memcpy((void *) ctx.tx_buff, (void *) current_req->data, current_req->len);
+ memcpy(
+ (void *) _context.tx_buff,
+ (void *) _current_req->data,
+ _current_req->len
+ );
- ctx.tx_len = current_req->len;
- ctx.rx_len = 0;
- ctx.port = current_req->port;
- ctx.callback = current_req->callback;
+ _context.tx_len = _current_req->len;
+ _context.rx_len = 0;
+ _context.port = _current_req->port;
+ _context.callback = _current_req->callback;
// Pop the first request from the queue by deallocating it and adjusting
// the pointer to the first queue item.
- SPI_Request *next = current_req->next;
+ SPI_Request *next = _current_req->next;
- free((void *) current_req);
- current_req = next;
+ free((void *) _current_req);
+ _current_req = next;
}
/* Interrupt handlers */
@@ -105,13 +93,13 @@ static void _spi_poll_irq_handler(void) {
// Fetch the last response byte, which wasn't followed by a pulse on /ACK,
// from the RX FIFO.
if (JOY_STAT & 0x0002)
- ctx.rx_buff[ctx.rx_len - 1] = (uint8_t) JOY_TXRX;
+ _context.rx_buff[_context.rx_len - 1] = (uint8_t) JOY_TXRX;
- if (ctx.callback)
- ctx.callback(ctx.port, ctx.rx_buff, ctx.rx_len);
+ if (_context.callback)
+ _context.callback(_context.port, _context.rx_buff, _context.rx_len);
// If the request queue is empty, create a pad polling request.
- if (current_req)
+ if (_current_req)
_spi_next_req();
else
_spi_create_poll_req();
@@ -119,17 +107,18 @@ static void _spi_poll_irq_handler(void) {
// Prepare the SPI port by clearing any pending IRQ, pulling /CS high and
// enabling the /ACK IRQ. In order to communicate with controllers, /CS has
// to be driven low again for about 20 us before sending the first byte.
+ // TODO: these delays can be probably tweaked for better performance
JOY_CTRL = 0x0010;
- for (uint32_t i = 0; i < 50; i++)
- __asm__("nop");
+ for (uint32_t i = 0; i < 1000; i++)
+ __asm__ volatile("");
- JOY_CTRL = 0x1003 | (ctx.port << 13);
- for (uint32_t i = 0; i < 500; i++)
- __asm__("nop");
+ JOY_CTRL = 0x1003 | (_context.port << 13);
+ for (uint32_t i = 0; i < 2000; i++)
+ __asm__ volatile("");
// Send the first byte indicating which device to address. If the matching
// device is connected, it will reply by triggering the /ACK IRQ.
- JOY_TXRX = ctx.tx_buff[0];
+ JOY_TXRX = _context.tx_buff[0];
}
static void _spi_ack_irq_handler(void) {
@@ -137,29 +126,29 @@ static void _spi_ack_irq_handler(void) {
// byte. According to nocash docs, this has to be done before resetting the
// IRQ.
while (JOY_STAT & 0x0080)
- __asm__("nop");
+ __asm__ volatile("");
// Keep /CS pulled low and acknowledge the IRQ (bit 4) to ensure it can be
// triggered again.
- JOY_CTRL = 0x1013 | (ctx.port << 13);
+ JOY_CTRL = 0x1013 | (_context.port << 13);
- if (!ctx.rx_len) {
+ if (!_context.rx_len) {
// We just sent the first address byte. Obviously the response we
// received was read from an open bus, so the SPI port's internal FIFO
// must be flushed (by performing dummy reads) to ensure we are only
// going to read valid data from now on.
JOY_TXRX;
- } else if (ctx.rx_len <= SPI_BUFF_LEN) {
+ } else if (_context.rx_len <= SPI_BUFF_LEN) {
// If this is not the first byte, put it in the RX buffer.
- ctx.rx_buff[ctx.rx_len - 1] = (uint8_t) JOY_TXRX;
+ _context.rx_buff[_context.rx_len - 1] = (uint8_t) JOY_TXRX;
}
// Send the next byte, or a null byte if there is no more data to send and
// we're just reading a response.
- ctx.rx_len++;
- if (ctx.rx_len < ctx.tx_len)
- JOY_TXRX = (uint32_t) ctx.tx_buff[ctx.rx_len];
+ _context.rx_len++;
+ if (_context.rx_len < _context.tx_len)
+ JOY_TXRX = (uint32_t) _context.tx_buff[_context.rx_len];
else
JOY_TXRX = 0x00;
}
@@ -176,10 +165,10 @@ SPI_Request *SPI_CreateRequest(void) {
// Find the last queued request by traversing the linked list and append a
// pointer to the new request.
- if (!current_req) {
- current_req = req;
+ if (!_current_req) {
+ _current_req = req;
} else {
- volatile SPI_Request *volatile last = current_req;
+ volatile SPI_Request *volatile last = _current_req;
while (last->next)
last = last->next;
@@ -213,6 +202,6 @@ void SPI_Init(SPI_Callback callback) {
JOY_BAUD = 0x0088; // 250000 bps
SPI_SetPollRate(250);
- current_req = 0;
- default_cb = callback;
+ _current_req = 0;
+ _default_cb = callback;
}
diff --git a/examples/io/pads/spi.h b/examples/io/pads/spi.h
index c50e065..7d4d75b 100644
--- a/examples/io/pads/spi.h
+++ b/examples/io/pads/spi.h
@@ -9,8 +9,9 @@
#include <stdint.h>
#include <psxpad.h>
-// Maximum request/response length (34 bytes for pads, 140 for memory cards)
-//#define SPI_BUFF_LEN 34
+// Maximum request/response length (34 bytes for pads, 140 for memory cards).
+// Must be a multiple of 4 to avoid memory alignment issues.
+//#define SPI_BUFF_LEN 36
#define SPI_BUFF_LEN 140
/* Request structures */
@@ -30,6 +31,10 @@ typedef struct _SPI_Request {
/* Public API */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/**
* @brief Allocates a new request object and adds it to the request queue. The
* object must be populated afterwards by setting the length, callback and
@@ -49,7 +54,7 @@ void SPI_SetPollRate(uint32_t value);
/**
* @brief Installs the SPI and timer 2 interrupt handlers and starts the poll
* timer. By default the polling rate is set to 250 Hz (125 Hz per port),
- * however it can be changed at any time by calling spi_set_poll_rate().
+ * however it can be changed at any time by calling SPI_SetPollRate().
*
* The provided callback (if any) is called to report the result of poll
* requests, which are issued automatically when no other request is in the
@@ -59,4 +64,8 @@ void SPI_SetPollRate(uint32_t value);
*/
void SPI_Init(SPI_Callback callback);
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/examples/sound/spustream/main.c b/examples/sound/spustream/main.c
index be095cb..6284c6d 100644
--- a/examples/sound/spustream/main.c
+++ b/examples/sound/spustream/main.c
@@ -11,8 +11,8 @@
* SPU ADPCM data (one for each channel, so a stereo stream would have 2
* buffers per chunk). All buffers in a chunk are played simultaneously using
* multiple SPU channels; each buffer has the loop flag set at the end, so each
- * channel will jump to its loop address (SPU_CHANNELS[n].loop_addr) once the
- * chunk is played.
+ * channel will jump to its loop address (SPU_CH_LOOP_ADDR(n)) once the chunk
+ * is played.
*
* Since the loop point doesn't necessarily have to be within the chunk itself,
* we can abuse it to "queue" another set of buffers to be played immediately
@@ -94,6 +94,7 @@
#include <psxpad.h>
#include <psxspu.h>
#include <psxcd.h>
+#include <hwregs_c.h>
// To maximize STREAM.BIN packing efficiency and get rid of padding between
// chunks, buffer size should be a multiple of sector size (2048 bytes). Buffer
@@ -105,27 +106,6 @@
#define NUM_CHANNELS 2
#define CHANNEL_MASK 0x03
-/* Register definitions */
-
-// For some reason SpuVoiceRaw doesn't actually match the layout of SPU
-// registers, so here we go.
-typedef struct {
- uint16_t vol_left;
- uint16_t vol_right;
- uint16_t freq;
- uint16_t addr;
- uint32_t adsr_param;
- uint16_t _reserved;
- uint16_t loop_addr;
-} SPUChannel;
-
-#define SPU_CTRL *((volatile uint16_t *) 0x1f801daa)
-#define SPU_IRQ_ADDR *((volatile uint16_t *) 0x1f801da4)
-#define SPU_KEY_ON *((volatile uint32_t *) 0x1f801d88)
-#define SPU_KEY_OFF *((volatile uint32_t *) 0x1f801d8c)
-
-// SPU RAM is addressed in 8-byte units, using 16-bit pointers.
-#define SPU_CHANNELS ((volatile SPUChannel *) 0x1f801c00)
#define SPU_RAM_ADDR(x) ((uint16_t) (((uint32_t) (x)) >> 3))
/* Display/GPU context utilities */
@@ -252,7 +232,7 @@ void spu_irq_handler(void) {
SPU_IRQ_ADDR = SPU_RAM_ADDR(str_ctx.spu_addr);
for (uint32_t i = 0; i < NUM_CHANNELS; i++)
- SPU_CHANNELS[i].loop_addr = SPU_RAM_ADDR(str_ctx.spu_addr + BUFFER_SIZE * i);
+ SPU_CH_LOOP_ADDR(i) = SPU_RAM_ADDR(str_ctx.spu_addr + BUFFER_SIZE * i);
// Start loading the next chunk. cd_event_handler() will be called
// repeatedly for each sector until the entire chunk is read.
@@ -317,7 +297,7 @@ void init_spu_channels(void) {
SPU_KEY_OFF = 0x00ffffff;
for (uint32_t i = 0; i < 24; i++)
- SPU_CHANNELS[i].addr = SPU_RAM_ADDR(DUMMY_BLOCK_ADDR);
+ SPU_CH_ADDR(i) = SPU_RAM_ADDR(DUMMY_BLOCK_ADDR);
SPU_KEY_ON = 0x00ffffff;
}
@@ -347,18 +327,18 @@ void start_stream(void) {
SPU_KEY_OFF = CHANNEL_MASK;
for (uint32_t i = 0; i < NUM_CHANNELS; i++) {
- SPU_CHANNELS[i].addr = SPU_RAM_ADDR(BUFFER_START_ADDR + BUFFER_SIZE * i);
- SPU_CHANNELS[i].freq = SAMPLE_RATE;
- SPU_CHANNELS[i].adsr_param = 0x1fee80ff; // or 0x9fc080ff, 0xdff18087
+ SPU_CH_ADDR(i) = SPU_RAM_ADDR(BUFFER_START_ADDR + BUFFER_SIZE * i);
+ SPU_CH_FREQ(i) = SAMPLE_RATE;
+ SPU_CH_ADSR(i) = 0x1fee80ff; // or 0x9fc080ff, 0xdff18087
}
// Unmute the channels and route them for stereo output. You'll want to
// edit this if you are using more than 2 channels, and/or if you want to
// provide an option to output mono audio instead of stereo.
- SPU_CHANNELS[0].vol_left = 0x3fff;
- SPU_CHANNELS[0].vol_right = 0x0000;
- SPU_CHANNELS[1].vol_left = 0x0000;
- SPU_CHANNELS[1].vol_right = 0x3fff;
+ SPU_CH_VOL_L(0) = 0x3fff;
+ SPU_CH_VOL_R(0) = 0x0000;
+ SPU_CH_VOL_L(1) = 0x0000;
+ SPU_CH_VOL_R(1) = 0x3fff;
SPU_KEY_ON = CHANNEL_MASK;
spu_irq_handler();
@@ -446,7 +426,7 @@ int main(int argc, const char* argv[]) {
// Only set the sample rate registers if necessary.
if (pad->btn != 0xffff) {
for (uint32_t i = 0; i < NUM_CHANNELS; i++)
- SPU_CHANNELS[i].freq = sample_rate;
+ SPU_CH_FREQ(i) = sample_rate;
}
last_buttons = pad->btn;
diff --git a/libpsn00b/include/hwregs_a.h b/libpsn00b/include/hwregs_a.h
index 0680679..4d0bade 100644
--- a/libpsn00b/include/hwregs_a.h
+++ b/libpsn00b/include/hwregs_a.h
@@ -6,11 +6,13 @@
.set IOBASE, 0x1f80 # IO segment base
-# GPU
+## GPU
+
.set GP0, 0x1810 # Also GPUREAD
.set GP1, 0x1814 # Also GPUSTAT
-# CD
+## CD drive
+
.set CD_STAT, 0x1800
.set CD_CMD, 0x1801 # Also response FIFO
.set CD_DATA, 0x1802 # Also parameters
@@ -21,14 +23,14 @@
.set CD_REG2, 0x1802
.set CD_REG3, 0x1803
-.set SBUS_5, 0x1018
-.set COM_DELAY, 0x1020
+## SPU
-# SPU (must be used with 16-bit load/store instructions)
.set SPU_VOICE_BASE, 0x1c00
-.set SPU_MASTER_VOL, 0x1d80
-.set SPU_REVERB_VOL, 0x1d84
+.set SPU_MASTER_VOL_L, 0x1d80
+.set SPU_MASTER_VOL_R, 0x1d82
+.set SPU_REVERB_VOL_L, 0x1d84
+.set SPU_REVERB_VOL_R, 0x1d86
.set SPU_KEY_ON, 0x1d88
.set SPU_KEY_OFF, 0x1d8c
.set SPU_FM_MODE, 0x1d90
@@ -41,81 +43,107 @@
.set SPU_ADDR, 0x1da6
.set SPU_DATA, 0x1da8
-.set SPUCNT, 0x1daa
-.set SPUDTCNT, 0x1dac
-.set SPUSTAT, 0x1dae
+.set SPU_CTRL, 0x1daa
+.set SPU_DMA_CTRL, 0x1dac
+.set SPU_STAT, 0x1dae
-.set SPU_CD_VOL, 0x1db0
-.set SPU_EXT_VOL, 0x1db4
-.set SPU_CURRENT_VOL, 0x1db8
+.set SPU_CD_VOL_L, 0x1db0
+.set SPU_CD_VOL_R, 0x1db2
+.set SPU_EXT_VOL_L, 0x1db4
+.set SPU_EXT_VOL_R, 0x1db6
+.set SPU_CURRENT_VOL_L, 0x1db8
+.set SPU_CURRENT_VOL_R, 0x1dba
.set SPU_VOICE_VOL_L, 0x00
.set SPU_VOICE_VOL_R, 0x02
.set SPU_VOICE_FREQ, 0x04
.set SPU_VOICE_ADDR, 0x06
.set SPU_VOICE_ADSR_L, 0x08
-.set SPU_VOICE_ADSR_H, 0x0a
+.set SPU_VOICE_ADSR_H, 0x0a
.set SPU_VOICE_LOOP, 0x0e
-# MDEC
+## MDEC
+
.set MDEC0, 0x1820
.set MDEC1, 0x1824
-# Pads
-.set JOY_TXRX, 0x1040
-.set JOY_STAT, 0x1044
-.set JOY_MODE, 0x1048
-.set JOY_CTRL, 0x104A
-.set JOY_BAUD, 0x104E
-
-# Serial
-.set SIO_TXRX, 0x1050
-.set SIO_STAT, 0x1054
-.set SIO_MODE, 0x1058
-.set SIO_CTRL, 0x105a
-.set SIO_BAUD, 0x105e
-
-# IRQ
-.set ISTAT, 0x1070
-.set IMASK, 0x1074
-
-# DMA
-.set DPCR, 0x10f0
-.set DICR, 0x10f4
-
-.set D0_MADR, 0x1080
-.set D0_BCR, 0x1084
-.set D0_CHCR, 0x1088
-
-.set D1_MADR, 0x1090
-.set D1_BCR, 0x1094
-.set D1_CHCR, 0x1098
-
-.set D2_MADR, 0x10a0
-.set D2_BCR, 0x10a4
-.set D2_CHCR, 0x10a8
-
-.set D3_MADR, 0x10b0
-.set D3_BCR, 0x10b4
-.set D3_CHCR, 0x10b8
-
-.set D4_MADR, 0x10c0
-.set D4_BCR, 0x10c4
-.set D4_CHCR, 0x10c8
-
-.set D6_MADR, 0x10e0
-.set D6_BCR, 0x10e4
-.set D6_CHCR, 0x10e8
-
-# Timers
-.set T0_CNT, 0x1100
-.set T0_MODE, 0x1104
-.set T0_TGT, 0x1108
-
-.set T1_CNT, 0x1110
-.set T1_MODE, 0x1114
-.set T1_TGT, 0x1118
-
-.set T2_CNT, 0x1120
-.set T2_MODE, 0x1124
-.set T2_TGT, 0x1128
+## SPI controller port
+
+.set JOY_TXRX, 0x1040
+.set JOY_STAT, 0x1044
+.set JOY_MODE, 0x1048
+.set JOY_CTRL, 0x104a
+.set JOY_BAUD, 0x104e
+
+## Serial port
+
+.set SIO_TXRX, 0x1050
+.set SIO_STAT, 0x1054
+.set SIO_MODE, 0x1058
+.set SIO_CTRL, 0x105a
+.set SIO_BAUD, 0x105e
+
+## IRQ controller
+
+.set IRQ_STAT, 0x1070
+.set IRQ_MASK, 0x1074
+
+## DMA
+
+.set DMA_DPCR, 0x10f0
+.set DMA_DICR, 0x10f4
+
+.set DMA0_MADR, 0x1080
+.set DMA0_BCR, 0x1084
+.set DMA0_CHCR, 0x1088
+
+.set DMA1_MADR, 0x1090
+.set DMA1_BCR, 0x1094
+.set DMA1_CHCR, 0x1098
+
+.set DMA2_MADR, 0x10a0
+.set DMA2_BCR, 0x10a4
+.set DMA2_CHCR, 0x10a8
+
+.set DMA3_MADR, 0x10b0
+.set DMA3_BCR, 0x10b4
+.set DMA3_CHCR, 0x10b8
+
+.set DMA4_MADR, 0x10c0
+.set DMA4_BCR, 0x10c4
+.set DMA4_CHCR, 0x10c8
+
+.set DMA5_MADR, 0x10d0
+.set DMA5_BCR, 0x10d4
+.set DMA5_CHCR, 0x10d8
+
+.set DMA6_MADR, 0x10e0
+.set DMA6_BCR, 0x10e4
+.set DMA6_CHCR, 0x10e8
+
+## Timers
+
+.set TIM0_VALUE, 0x1100
+.set TIM0_CTRL, 0x1104
+.set TIM0_RELOAD, 0x1108
+
+.set TIM1_VALUE, 0x1110
+.set TIM1_CTRL, 0x1114
+.set TIM1_RELOAD, 0x1118
+
+.set TIM2_VALUE, 0x1120
+.set TIM2_CTRL, 0x1124
+.set TIM2_RELOAD, 0x1128
+
+## Memory control
+
+.set EXP1_ADDR, 0x1000
+.set EXP2_ADDR, 0x1004
+.set EXP1_DELAY_SIZE, 0x1008
+.set EXP3_DELAY_SIZE, 0x100c
+.set BIOS_DELAY_SIZE, 0x1010
+.set SPU_DELAY_SIZE, 0x1014
+.set CD_DELAY_SIZE, 0x1018
+.set EXP2_DELAY_SIZE, 0x101c
+.set COM_DELAY_CFG, 0x1020
+.set RAM_SIZE_CFG, 0x1060
diff --git a/libpsn00b/include/hwregs_c.h b/libpsn00b/include/hwregs_c.h
new file mode 100644
index 0000000..4222a22
--- /dev/null
+++ b/libpsn00b/include/hwregs_c.h
@@ -0,0 +1,129 @@
+/*
+ * PSn00bSDK hardware registers definitions
+ * (C) 2022 spicyjpeg - MPL licensed
+ */
+
+#ifndef __HWREGS_C_H
+#define __HWREGS_C_H
+
+#include <stdint.h>
+
+#define _MMIO8(addr) *((volatile uint8_t *) (addr))
+#define _MMIO16(addr) *((volatile uint16_t *) (addr))
+#define _MMIO32(addr) *((volatile uint32_t *) (addr))
+
+/* Constants */
+
+#define F_CPU 33868800UL
+#define F_GPU 53222400UL
+
+/* GPU */
+
+#define GP0 _MMIO32(0x1f801810)
+#define GP1 _MMIO32(0x1f801814)
+
+/* CD drive */
+
+#define CD_STAT _MMIO8(0x1f801800)
+#define CD_CMD _MMIO8(0x1f801801)
+#define CD_DATA _MMIO8(0x1f801802)
+#define CD_IRQ _MMIO8(0x1f801803)
+
+#define CD_REG(N) _MMIO8(0x1f801800 + (N))
+
+/* SPU */
+
+#define SPU_MASTER_VOL_L _MMIO16(0x1f801d80)
+#define SPU_MASTER_VOL_R _MMIO16(0x1f801d82)
+#define SPU_REVERB_VOL_L _MMIO16(0x1f801d84)
+#define SPU_REVERB_VOL_R _MMIO16(0x1f801d86)
+#define SPU_KEY_ON _MMIO32(0x1f801d88)
+#define SPU_KEY_OFF _MMIO32(0x1f801d8c)
+#define SPU_FM_MODE _MMIO32(0x1f801d90)
+#define SPU_NOISE_MODE _MMIO32(0x1f801d94)
+#define SPU_REVERB_ON _MMIO32(0x1f801d98)
+#define SPU_CHAN_STATUS _MMIO32(0x1f801d9c)
+
+#define SPU_REVERB_ADDR _MMIO16(0x1f801da2)
+#define SPU_IRQ_ADDR _MMIO16(0x1f801da4)
+#define SPU_ADDR _MMIO16(0x1f801da6)
+#define SPU_DATA _MMIO16(0x1f801da8)
+
+#define SPU_CTRL _MMIO16(0x1f801daa)
+#define SPU_DMA_CTRL _MMIO16(0x1f801dac)
+#define SPU_STAT _MMIO16(0x1f801dae)
+
+#define SPU_CD_VOL_L _MMIO16(0x1f801db0)
+#define SPU_CD_VOL_R _MMIO16(0x1f801db2)
+#define SPU_EXT_VOL_L _MMIO16(0x1f801db4)
+#define SPU_EXT_VOL_R _MMIO16(0x1f801db6)
+#define SPU_CURRENT_VOL_L _MMIO16(0x1f801db8)
+#define SPU_CURRENT_VOL_R _MMIO16(0x1f801dba)
+
+// These are not named SPU_VOICE_* to avoid name clashes with SPU attribute
+// flags defined in psxspu.h.
+#define SPU_CH_VOL_L(N) _MMIO16(0x1f801c00 + 16 * (N))
+#define SPU_CH_VOL_R(N) _MMIO16(0x1f801c02 + 16 * (N))
+#define SPU_CH_FREQ(N) _MMIO16(0x1f801c04 + 16 * (N))
+#define SPU_CH_ADDR(N) _MMIO16(0x1f801c06 + 16 * (N))
+#define SPU_CH_ADSR(N) _MMIO32(0x1f801c08 + 16 * (N))
+#define SPU_CH_LOOP_ADDR(N) _MMIO16(0x1f801c0e + 16 * (N))
+
+/* MDEC */
+
+#define MDEC0 _MMIO32(0x1f801820)
+#define MDEC1 _MMIO32(0x1f801824)
+
+/* SPI controller port */
+
+// IMPORTANT: even though JOY_TXRX is a 32-bit register, it should only be
+// accessed as 8-bit. Reading it as 16 or 32-bit works fine on real hardware,
+// but leads to problems in some emulators.
+#define JOY_TXRX _MMIO8(0x1f801040)
+#define JOY_STAT _MMIO16(0x1f801044)
+#define JOY_MODE _MMIO16(0x1f801048)
+#define JOY_CTRL _MMIO16(0x1f80104a)
+#define JOY_BAUD _MMIO16(0x1f80104e)
+
+/* Serial port */
+
+#define SIO_TXRX _MMIO8(0x1f801050)
+#define SIO_STAT _MMIO16(0x1f801054)
+#define SIO_MODE _MMIO16(0x1f801058)
+#define SIO_CTRL _MMIO16(0x1f80105a)
+#define SIO_BAUD _MMIO16(0x1f80105e)
+
+/* IRQ controller */
+
+#define IRQ_STAT _MMIO32(0x1f801070)
+#define IRQ_MASK _MMIO32(0x1f801074)
+
+/* DMA */
+
+#define DMA_DPCR _MMIO32(0x1f8010f0)
+#define DMA_DICR _MMIO32(0x1f8010f4)
+
+#define DMA_MADR(N) _MMIO32(0x1f801080 + 16 * (N))
+#define DMA_BCR(N) _MMIO32(0x1f801084 + 16 * (N))
+#define DMA_CHCR(N) _MMIO32(0x1f801088 + 16 * (N))
+
+/* Timers */
+
+#define TIM_VALUE(N) _MMIO32(0x1f801100 + 16 * (N))
+#define TIM_CTRL(N) _MMIO32(0x1f801104 + 16 * (N))
+#define TIM_RELOAD(N) _MMIO32(0x1f801108 + 16 * (N))
+
+/* Memory control */
+
+#define EXP1_ADDR _MMIO32(0x1f801000)
+#define EXP2_ADDR _MMIO32(0x1f801004)
+#define EXP1_DELAY_SIZE _MMIO32(0x1f801008)
+#define EXP3_DELAY_SIZE _MMIO32(0x1f80100c)
+#define BIOS_DELAY_SIZE _MMIO32(0x1f801010)
+#define SPU_DELAY_SIZE _MMIO32(0x1f801014)
+#define CD_DELAY_SIZE _MMIO32(0x1f801018)
+#define EXP2_DELAY_SIZE _MMIO32(0x1f80101c)
+#define COM_DELAY_CFG _MMIO32(0x1f801020)
+#define RAM_SIZE_CFG _MMIO32(0x1f801060)
+
+#endif
diff --git a/libpsn00b/psxapi/_initcd.s b/libpsn00b/psxapi/_initcd.s
index decf2bd..c3a2861 100644
--- a/libpsn00b/psxapi/_initcd.s
+++ b/libpsn00b/psxapi/_initcd.s
@@ -11,7 +11,7 @@ _InitCd:
lui $a0, IOBASE # Load IOBASE value
- lw $v0, DPCR($a0) # Get current DMA settings
+ lw $v0, DMA_DPCR($a0) # Get current DMA settings
nop
sw $v0, 4($sp) # Save to stack
@@ -21,14 +21,14 @@ _InitCd:
lui $a0, IOBASE # Load IOBASE again
lw $v0, 4($sp) # Get old DMA control settings
- lw $v1, DPCR($a0) # Get DMA settings by _96_init()
+ lw $v1, DMA_DPCR($a0) # Get DMA settings by _96_init()
lui $a1, 0xffff # Mask out settings for CD DMA
ori $a1, 0x0f00
and $v0, $a1
or $v0, $v1 # Merge and set new DMA settings
- sw $v0, DPCR($a0)
+ sw $v0, DMA_DPCR($a0)
lw $ra, 0($sp)
addiu $sp, 8
diff --git a/libpsn00b/psxcd/cdgetsector.s b/libpsn00b/psxcd/cdgetsector.s
index dbe95cb..9f38e7a 100644
--- a/libpsn00b/psxcd/cdgetsector.s
+++ b/libpsn00b/psxcd/cdgetsector.s
@@ -21,16 +21,16 @@ CdGetSector:
# srl $a1, 2 # (the official implementation expects $a1/size
# to be in 32-bit words rather than bytes)
or $v0, $a1
- sw $a0, D3_MADR($a2) # Set DMA base address and transfer length
- sw $v0, D3_BCR($a2)
+ sw $a0, DMA3_MADR($a2) # Set DMA base address and transfer length
+ sw $v0, DMA3_BCR($a2)
lui $v0, 0x1100 # Start DMA transfer
- sw $v0, D3_CHCR($a2)
+ sw $v0, DMA3_CHCR($a2)
nop
nop
.Ldma_wait: # Ensure DMA transfer has completed
- lw $v0, D3_CHCR($a2)
+ lw $v0, DMA3_CHCR($a2)
nop
srl $v0, 24
andi $v0, 0x1
diff --git a/libpsn00b/psxcd/psxcd_asm.s b/libpsn00b/psxcd/psxcd_asm.s
index 1dbf542..129bc89 100644
--- a/libpsn00b/psxcd/psxcd_asm.s
+++ b/libpsn00b/psxcd/psxcd_asm.s
@@ -17,9 +17,9 @@ _cd_init:
lui $a3, IOBASE # Acknowledge all CD IRQs
li $v0, 0x20943 # Set CD-ROM Delay/Size and common delay
- sw $v0, SBUS_5($a3)
+ sw $v0, CD_DELAY_SIZE($a3)
li $v0, 0x1325
- sw $v0, COM_DELAY($a3)
+ sw $v0, COM_DELAY_CFG($a3)
li $v0, 1
sb $v0, CD_REG0($a3)
@@ -71,10 +71,10 @@ _cd_init:
la $v0, _cd_read_cb
sw $0 , 0($v0)
- lw $v0, DPCR($a3)
+ lw $v0, DMA_DPCR($a3)
li $v1, 0xB000
or $v0, $v1
- sw $v0, DPCR($a3)
+ sw $v0, DMA_DPCR($a3)
jal ExitCriticalSection
nop
diff --git a/libpsn00b/psxetc/dmacallback.s b/libpsn00b/psxetc/dmacallback.s
index b2f86cf..8ea8ec0 100644
--- a/libpsn00b/psxetc/dmacallback.s
+++ b/libpsn00b/psxetc/dmacallback.s
@@ -46,13 +46,13 @@ DMACallback:
lui $a2, IOBASE
- lw $v0, DICR($a2) # Enable DMA interrupt
+ lw $v0, DMA_DICR($a2) # Enable DMA interrupt
lui $v1, 0x1
sll $v1, $a0
or $v0, $v1
lui $v1, 0x80
or $v0, $v1
- sw $v0, DICR($a2)
+ sw $v0, DMA_DICR($a2)
b .Lskip_remove
nop
@@ -67,7 +67,7 @@ DMACallback:
sw $v1, 4($sp)
lui $a2, IOBASE # Disable DMA interrupt
- lw $v0, DICR($a2)
+ lw $v0, DMA_DICR($a2)
lui $v1, 0x1
sll $v1, $a0
.set noat
@@ -78,13 +78,13 @@ DMACallback:
xor $v1, $at
and $v0, $v1
.set at
- sw $v0, DICR($a2)
+ sw $v0, DMA_DICR($a2)
jal _dma_has_cb # Check if callbacks are present
nop
bnez $v0, .Lskip_remove
nop
- sw $0 , DICR($a2)
+ sw $0 , DMA_DICR($a2)
jal GetInterruptCallback # Check if callback is the DMA handler
li $a0, 3
@@ -143,7 +143,7 @@ _dma_handler:
.Lhandler_loop:
lui $a0, IOBASE
- lw $v0, DICR($a0)
+ lw $v0, DMA_DICR($a0)
li $v1, 24
addu $v1, $s0
srl $v0, $v1
@@ -166,9 +166,9 @@ _dma_handler:
addi $s0, 1
lui $a0, IOBASE
- lw $v0, DICR($a0)
+ lw $v0, DMA_DICR($a0)
nop
- sw $v0, DICR($a0)
+ sw $v0, DMA_DICR($a0)
lw $ra, 0($sp)
lw $s0, 4($sp)
diff --git a/libpsn00b/psxetc/interruptcallback.s b/libpsn00b/psxetc/interruptcallback.s
index 8e912d8..78e5e6e 100644
--- a/libpsn00b/psxetc/interruptcallback.s
+++ b/libpsn00b/psxetc/interruptcallback.s
@@ -16,25 +16,25 @@ InterruptCallback:
beqz $a1, .Ldisable_irq
nop
- lw $v0, IMASK($a2) # Enable interrupt mask
+ lw $v0, IRQ_MASK($a2) # Enable interrupt mask
li $v1, 1
sll $v1, $a0
or $v0, $v1
b .Lcont
- sw $v0, IMASK($a2)
+ sw $v0, IRQ_MASK($a2)
.Ldisable_irq:
.set noat
- lw $v0, IMASK($a2) # Disable interrupt mask
+ lw $v0, IRQ_MASK($a2) # Disable interrupt mask
li $v1, 1
sll $v1, $a0
addiu $at, $0 , -1
xor $v1, $at
.set at
and $v0, $v1
- sw $v0, IMASK($a2)
+ sw $v0, IRQ_MASK($a2)
.Lcont:
diff --git a/libpsn00b/psxetc/isr.s b/libpsn00b/psxetc/isr.s
index 00428a4..440be50 100644
--- a/libpsn00b/psxetc/isr.s
+++ b/libpsn00b/psxetc/isr.s
@@ -20,7 +20,7 @@ _global_isr:
# changed elsewhere sometimes
lui $a0, IOBASE # Get IRQ status
- lw $v0, IMASK($a0)
+ lw $v0, IRQ_MASK($a0)
nop
srl $v0, $s1 # Check IRQ mask bit if set
@@ -29,7 +29,7 @@ _global_isr:
beqz $v0, .Lno_irq # Don't execute callback if IRQ not enabled
nop
- lw $v0, ISTAT($a0)
+ lw $v0, IRQ_STAT($a0)
nop
srl $v0, $s1 # Check IRQ status bit if set
andi $v0, 0x1
@@ -39,12 +39,12 @@ _global_isr:
lw $v1, 0($s0) # Load IRQ callback function
nop
- lw $v0, ISTAT($a0) # Acknowledge the IRQ (by writing a 0 bit)
+ lw $v0, IRQ_STAT($a0) # Acknowledge the IRQ (by writing a 0 bit)
li $a1, 1
sll $a1, $s1
addiu $a2, $0 , -1
xor $a1, $a2
- sw $a1, ISTAT($a0)
+ sw $a1, IRQ_STAT($a0)
beqz $v1, .Lno_irq # Don't execute if callback is not set
nop
diff --git a/libpsn00b/psxetc/restartcallback.s b/libpsn00b/psxetc/restartcallback.s
index 151d78e..036a5a0 100644
--- a/libpsn00b/psxetc/restartcallback.s
+++ b/libpsn00b/psxetc/restartcallback.s
@@ -44,8 +44,8 @@ RestartCallback:
addiu $a1, 1
lui $a0, IOBASE
- sw $0 , ISTAT($a0)
- sw $v0, IMASK($a0)
+ sw $0 , IRQ_STAT($a0)
+ sw $v0, IRQ_MASK($a0)
lw $ra, 0($sp)
addiu $sp, 4
diff --git a/libpsn00b/psxgpu/clearotagr.s b/libpsn00b/psxgpu/clearotagr.s
index 3e888f1..832e54c 100644
--- a/libpsn00b/psxgpu/clearotagr.s
+++ b/libpsn00b/psxgpu/clearotagr.s
@@ -12,10 +12,10 @@ ClearOTagR:
addi $v0, $a1, -1
sll $v0, 2
addu $a0, $v0
- sw $a0, D6_MADR($a2)
+ sw $a0, DMA6_MADR($a2)
andi $a1, 0xffff
- sw $a1, D6_BCR($a2)
+ sw $a1, DMA6_BCR($a2)
lui $v0, 0x1100
addiu $v0, 2
jr $ra
- sw $v0, D6_CHCR($a2)
+ sw $v0, DMA6_CHCR($a2)
diff --git a/libpsn00b/psxgpu/drawotag.s b/libpsn00b/psxgpu/drawotag.s
index ba771fc..595fcd5 100644
--- a/libpsn00b/psxgpu/drawotag.s
+++ b/libpsn00b/psxgpu/drawotag.s
@@ -25,12 +25,12 @@ DrawOTag:
beqz $v0, .Lgpu_wait
nop
- sw $a0, D2_MADR($a3) # Set DMA base address to specified OT
- sw $0 , D2_BCR($a3)
+ sw $a0, DMA2_MADR($a3) # Set DMA base address to specified OT
+ sw $0 , DMA2_BCR($a3)
lui $v0, 0x0100 # Begin OT transfer!
ori $v0, 0x0401
- sw $v0, D2_CHCR($a3)
+ sw $v0, DMA2_CHCR($a3)
lw $ra, 0($sp)
addiu $sp, 4
diff --git a/libpsn00b/psxgpu/drawsync.s b/libpsn00b/psxgpu/drawsync.s
index 2e29381..b671b03 100644
--- a/libpsn00b/psxgpu/drawsync.s
+++ b/libpsn00b/psxgpu/drawsync.s
@@ -24,7 +24,7 @@ DrawSync:
nop
.Ldma_wait:
- lw $v0, D2_CHCR($a0)
+ lw $v0, DMA2_CHCR($a0)
nop
srl $v0, 24
andi $v0, 0x1
@@ -59,7 +59,7 @@ DrawSync:
.Lgetwords:
- lw $v0, D2_BCR($a0)
+ lw $v0, DMA2_BCR($a0)
nop
jr $ra
diff --git a/libpsn00b/psxgpu/drawsynccallback.s b/libpsn00b/psxgpu/drawsynccallback.s
index 37c0375..2b2c172 100644
--- a/libpsn00b/psxgpu/drawsynccallback.s
+++ b/libpsn00b/psxgpu/drawsynccallback.s
@@ -64,7 +64,7 @@ _drawsync_handler:
addiu $sp, -4
sw $ra, 0($sp)
- lw $v0, D2_CHCR($a0)
+ lw $v0, DMA2_CHCR($a0)
nop
srl $v0, 24
andi $v0, 0x1
diff --git a/libpsn00b/psxgpu/loadimage.s b/libpsn00b/psxgpu/loadimage.s
index 4a3b4e0..e2a5be5 100644
--- a/libpsn00b/psxgpu/loadimage.s
+++ b/libpsn00b/psxgpu/loadimage.s
@@ -56,12 +56,12 @@ LoadImage:
sll $v1, 0x10
ori $v1, 0x8
- sw $a1, D2_MADR($s0) # Set DMA base address and transfer length
- sw $v1, D2_BCR($s0)
+ sw $a1, DMA2_MADR($s0) # Set DMA base address and transfer length
+ sw $v1, DMA2_BCR($s0)
lui $v0, 0x100 # Start DMA transfer
ori $v0, 0x201
- sw $v0, D2_CHCR($s0)
+ sw $v0, DMA2_CHCR($s0)
lw $ra, 0($sp)
lw $s0, 4($sp)
diff --git a/libpsn00b/psxgpu/resetgraph.s b/libpsn00b/psxgpu/resetgraph.s
index f469fbe..eae854c 100644
--- a/libpsn00b/psxgpu/resetgraph.s
+++ b/libpsn00b/psxgpu/resetgraph.s
@@ -42,10 +42,10 @@ ResetGraph:
lui $v0, 0x3b33 # Enables DMA channel 6 (for ClearOTag)
ori $v0, 0x3b33 # Enables DMA channel 2
- sw $v0, DPCR($a3)
- sw $0 , DICR($a3) # Clear DICR (not needed)
+ sw $v0, DMA_DPCR($a3)
+ sw $0 , DMA_DICR($a3) # Clear DICR (not needed)
- sw $0 , IMASK($a3) # Clear IRQ settings
+ sw $0 , IRQ_MASK($a3) # Clear IRQ settings
la $v0, _hooks_installed # Set installed flag
li $v1, 0x1
@@ -102,7 +102,7 @@ ResetGraph:
# by previous calls)
li $v0, 0x1d00 # Configure timer 1 as Hblank counter
- sw $v0, T1_MODE($a3) # Set timer 1 value
+ sw $v0, TIM1_CTRL($a3) # Set timer 1 value
beq $a0, 1, .Lgpu_init_1
nop
@@ -116,7 +116,7 @@ ResetGraph:
.Lgpu_init_1:
- sw $0 , D2_CHCR($a3) # Stop any DMA
+ sw $0 , DMA2_CHCR($a3) # Stop any DMA
.Lgpu_init_3:
@@ -143,9 +143,9 @@ VSync:
lw $s0, GP1($a3)
.Lhwait_loop: # Get Hblank time
- lw $v0, T1_CNT($a3)
+ lw $v0, TIM1_VALUE($a3)
nop
- lw $v1, T1_CNT($a3)
+ lw $v1, TIM1_VALUE($a3)
nop
bne $v0, $v1, .Lhwait_loop
nop
@@ -208,9 +208,9 @@ VSync:
la $a2, _vsync_lasthblank
.Lhwait2_loop:
- lw $v0, T1_CNT($a3)
+ lw $v0, TIM1_VALUE($a3)
nop
- lw $v1, T1_CNT($a3)
+ lw $v1, TIM1_VALUE($a3)
sw $v0, 0($a2)
bne $v0, $v1, .Lhwait2_loop
nop
diff --git a/libpsn00b/psxgpu/storeimage.s b/libpsn00b/psxgpu/storeimage.s
index 5d4c793..933b14c 100644
--- a/libpsn00b/psxgpu/storeimage.s
+++ b/libpsn00b/psxgpu/storeimage.s
@@ -54,8 +54,8 @@ StoreImage:
sll $v1, 0x10
ori $v1, 0x8
- sw $a1, D2_MADR($s0) # Set DMA base address and transfer length
- sw $v1, D2_BCR($s0)
+ sw $a1, DMA2_MADR($s0) # Set DMA base address and transfer length
+ sw $v1, DMA2_BCR($s0)
.Lgpu_wait_2: # Wait for GPU to be ready for commands and DMA
jal ReadGPUstat
@@ -67,7 +67,7 @@ StoreImage:
lui $v0, 0x100 # Start DMA transfer
ori $v0, 0x200
- sw $v0, D2_CHCR($s0)
+ sw $v0, DMA2_CHCR($s0)
lw $ra, 0($sp)
lw $s0, 4($sp)
diff --git a/libpsn00b/psxspu/spuinit.s b/libpsn00b/psxspu/spuinit.s
index 42f302a..6966213 100644
--- a/libpsn00b/psxspu/spuinit.s
+++ b/libpsn00b/psxspu/spuinit.s
@@ -17,30 +17,25 @@ SpuInit:
# Stop and mute everything
- sh $0 , SPUCNT($v1) # Clear control settings
+ sh $0 , SPU_CTRL($v1) # Clear control settings
jal SpuCtrlSync
move $a0, $0
- sh $0 , SPU_MASTER_VOL($v1) # Clear master volume
- sh $0 , SPU_MASTER_VOL+2($v1)
+ sh $0 , SPU_MASTER_VOL_L($v1) # Clear master volume
+ sh $0 , SPU_MASTER_VOL_R($v1)
- sh $0 , SPU_REVERB_VOL($v1) # Clear reverb volume
- sh $0 , SPU_REVERB_VOL+2($v1)
+ sh $0 , SPU_REVERB_VOL_L($v1) # Clear reverb volume
+ sh $0 , SPU_REVERB_VOL_R($v1)
- sh $0 , SPU_CD_VOL($v1) # Clear CD volume
- sh $0 , SPU_CD_VOL+2($v1)
+ sh $0 , SPU_CD_VOL_L($v1) # Clear CD volume
+ sh $0 , SPU_CD_VOL_R($v1)
- sh $0 , SPU_EXT_VOL($v1) # Clear external audio volume
- sh $0 , SPU_EXT_VOL+2($v1)
+ sh $0 , SPU_EXT_VOL_L($v1) # Clear external audio volume
+ sh $0 , SPU_EXT_VOL_R($v1)
- sh $0 , SPU_FM_MODE($v1) # Turn off FM modes
- sh $0 , SPU_FM_MODE+2($v1)
-
- sh $0 , SPU_NOISE_MODE($v1) # Turn off noise modes
- sh $0 , SPU_NOISE_MODE+2($v1)
-
- sh $0 , SPU_REVERB_ON($v1) # Turn off reverb modes
- sh $0 , SPU_REVERB_ON+2($v1)
+ sw $0 , SPU_FM_MODE($v1) # Turn off FM modes
+ sw $0 , SPU_NOISE_MODE($v1) # Turn off noise modes
+ sw $0 , SPU_REVERB_ON($v1) # Turn off reverb modes
li $v0, 0xfffe
sh $v0, SPU_REVERB_ADDR($v1)
@@ -65,32 +60,28 @@ SpuInit:
bgez $a2, .Lclear_voices
nop
- li $v0, 0xffff # Set all keys to off
- sh $v0, SPU_KEY_OFF($v1)
- sh $v0, SPU_KEY_OFF+2($v1)
+ addiu $v0, $0, -1 # Set all keys to off
+ sw $v0, SPU_KEY_OFF($v1)
li $v0, 0x4 # Set SPU data transfer control
- sh $v0, SPUDTCNT($v1) # (usually always 0x4)
+ sh $v0, SPU_DMA_CTRL($v1) # (usually always 0x4)
- lw $v0, DPCR($v1) # Enable DMA channel 4 (SPU DMA)
+ lw $v0, DMA_DPCR($v1) # Enable DMA channel 4 (SPU DMA)
lui $at, 0xb
or $v0, $at
- sw $v0, DPCR($v1)
+ sw $v0, DMA_DPCR($v1)
li $v0, 0xC001 # Enable SPU
- sh $v0, SPUCNT($v1)
+ sh $v0, SPU_CTRL($v1)
jal SpuCtrlSync
move $a0, $v0
li $v0, 0x3fff # Activate master volume
- sh $v0, SPU_MASTER_VOL($v1)
- sh $v0, SPU_MASTER_VOL+2($v1)
-
- sh $v0, SPU_CD_VOL($v1) # Activate CD volume
- sh $v0, SPU_CD_VOL+2($v1)
+ sh $v0, SPU_MASTER_VOL_L($v1)
+ sh $v0, SPU_MASTER_VOL_R($v1)
- sh $v0, SPU_CD_VOL($v1) # Activate CD volume
- sh $v0, SPU_CD_VOL+2($v1)
+ sh $v0, SPU_CD_VOL_L($v1) # Activate CD volume
+ sh $v0, SPU_CD_VOL_R($v1)
lw $ra, 0($sp)
addiu $sp, 4
@@ -108,7 +99,7 @@ SpuCtrlSync:
lui $v1, IOBASE
andi $a0, 0x3f
.Lctrl_wait:
- lhu $v0, SPUSTAT($v1) # Get SPUSTAT value
+ lhu $v0, SPU_STAT($v1) # Get SPUSTAT value
nop
andi $v0, 0x3f
bne $v0, $a0, .Lctrl_wait # Wait until SPUCNT and SPUSTAT are equal
@@ -123,7 +114,7 @@ SpuCtrlSync:
.type SpuWait, @function
SpuWait:
lui $v0, IOBASE
- lhu $v0, SPUSTAT($v0)
+ lhu $v0, SPU_STAT($v0)
nop
andi $v0, 0x400
bnez $v0, SpuWait
diff --git a/libpsn00b/psxspu/spureverbon.s b/libpsn00b/psxspu/spureverbon.s
index 852bff3..635fac3 100644
--- a/libpsn00b/psxspu/spureverbon.s
+++ b/libpsn00b/psxspu/spureverbon.s
@@ -11,6 +11,6 @@ SpuReverbOn:
lui $v1, IOBASE
li $v0, 1
sll $v0, $a0
- sh $v0, SPU_REVERB_ON($v1)
+ sw $v0, SPU_REVERB_ON($v1)
jr $ra
nop \ No newline at end of file
diff --git a/libpsn00b/psxspu/spusetreverb.s b/libpsn00b/psxspu/spusetreverb.s
index 993b166..8257812 100644
--- a/libpsn00b/psxspu/spusetreverb.s
+++ b/libpsn00b/psxspu/spusetreverb.s
@@ -10,11 +10,12 @@
SpuSetReverb:
addiu $sp, -4
sw $ra, 0($sp)
-
- lhu $v0, SPUCNT($v1)
+
+ lui $v1, IOBASE
+ lhu $v0, SPU_CTRL($v1)
nop
ori $v0, 0x80 # Enable reverb
- sh $v0, SPUCNT($v1)
+ sh $v0, SPU_CTRL($v1)
jal SpuCtrlSync
move $a0, $v0
diff --git a/libpsn00b/psxspu/spusetreverbaddr.s b/libpsn00b/psxspu/spusetreverbaddr.s
index 6ddbf44..089a91a 100644
--- a/libpsn00b/psxspu/spusetreverbaddr.s
+++ b/libpsn00b/psxspu/spusetreverbaddr.s
@@ -8,7 +8,7 @@
.global SpuSetReverbAddr
.type SpuSetReverbAddr, @function
SpuSetReverbAddr:
- lui $a3, 0x1f80
+ lui $a3, IOBASE
srl $a0, 3
sh $a0, SPU_REVERB_ADDR($a3)
jr $ra
@@ -18,8 +18,8 @@ SpuSetReverbAddr:
.global SpuSetReverbVolume
.type SpuSetReverbVolume, @function
SpuSetReverbVolume:
- lui $a3, 0x1f80
- sh $a0, SPU_REVERB_VOL($a3)
- sh $a1, SPU_REVERB_VOL+2($a3)
+ lui $a3, IOBASE
+ sh $a0, SPU_REVERB_VOL_L($a3)
+ sh $a1, SPU_REVERB_VOL_R($a3)
jr $ra
nop \ No newline at end of file
diff --git a/libpsn00b/psxspu/transfer.s b/libpsn00b/psxspu/transfer.s
index 5b62c28..adcdb33 100644
--- a/libpsn00b/psxspu/transfer.s
+++ b/libpsn00b/psxspu/transfer.s
@@ -46,10 +46,10 @@ SpuWrite:
lui $a3, IOBASE
- lhu $v0, SPUCNT($a3) # Set transfer mode to Stop
+ lhu $v0, SPU_CTRL($a3) # Set transfer mode to Stop
nop
andi $v0, 0xffcf
- sh $v0, SPUCNT($a3)
+ sh $v0, SPU_CTRL($a3)
jal SpuCtrlSync
move $a0, $v0
@@ -58,10 +58,10 @@ SpuWrite:
nop
sh $v1, SPU_ADDR($a3)
- lhu $v0, SPUCNT($a3) # Set transfer mode to DMA write
+ lhu $v0, SPU_CTRL($a3) # Set transfer mode to DMA write
nop
ori $v0, 0x20
- sh $v0, SPUCNT($a3)
+ sh $v0, SPU_CTRL($a3)
#jal SpuCtrlSync # Locks up on most emulators (bit 5 in
#move $a0, $v0 # SPUSTAT likely not updating, seems to
# be okay to not wait for it on real HW)
@@ -69,13 +69,13 @@ SpuWrite:
lw $a0, 4($sp)
.Ldma_wait: # Wait for SPU to be ready for DMA
- lhu $v0, SPUSTAT($a3)
+ lhu $v0, SPU_STAT($a3)
nop
andi $v0, 0x400 # Bit 8 in SPUSTAT never changes to 1 on
bnez $v0, .Ldma_wait # emulators so use bit 10 instead
nop
- sw $a0, D4_MADR($a3) # Set DMA source address
+ sw $a0, DMA4_MADR($a3) # Set DMA source address
li $v0, 0x10 # 16 words per block (64 bytes)
addiu $a1, 63 # Add by 63 to ensure all bytes get sent
@@ -83,11 +83,11 @@ SpuWrite:
andi $a1, 0xffff
sll $a1, 16
or $v0, $a1
- sw $v0, D4_BCR($a3)
+ sw $v0, DMA4_BCR($a3)
lui $v0, 0x0100 # Commence transfer
ori $v0, 0x0201
- sw $v0, D4_CHCR($a3)
+ sw $v0, DMA4_CHCR($a3)
lw $ra, 0($sp)
addiu $sp, 8