aboutsummaryrefslogtreecommitdiff
path: root/libpsn00b
diff options
context:
space:
mode:
authorspicyjpeg <thatspicyjpeg@gmail.com>2022-12-18 15:44:22 +0100
committerspicyjpeg <thatspicyjpeg@gmail.com>2022-12-18 15:44:22 +0100
commitb3fc13c36c4ed666e34e292a9ed7d45ae4f49454 (patch)
tree5a6af613dc529cd5dd5c6ef022be44d2508a6782 /libpsn00b
parent3b7c46ab74548a9a79bfb867551c51dd877c8f4d (diff)
downloadpsn00bsdk-b3fc13c36c4ed666e34e292a9ed7d45ae4f49454.tar.gz
Rearrange hwregs_c.h and k573io.h, add clz intrinsics
Diffstat (limited to 'libpsn00b')
-rw-r--r--libpsn00b/include/hwregs_a.inc64
-rw-r--r--libpsn00b/include/hwregs_c.h61
-rw-r--r--libpsn00b/libc/clz.s43
-rw-r--r--libpsn00b/psxcd/common.c2
-rw-r--r--libpsn00b/psxetc/interrupts.c2
-rw-r--r--libpsn00b/psxsio/sio.c40
-rw-r--r--libpsn00b/psxsio/tty.c4
-rw-r--r--libpsn00b/psxspu/common.c6
8 files changed, 131 insertions, 91 deletions
diff --git a/libpsn00b/include/hwregs_a.inc b/libpsn00b/include/hwregs_a.inc
index b0c6954..02c9a5a 100644
--- a/libpsn00b/include/hwregs_a.inc
+++ b/libpsn00b/include/hwregs_a.inc
@@ -4,6 +4,8 @@
## Constants
.set IOBASE, 0xbf80
+.set EXP1BASE, 0xbf00
+
.set F_CPU, 33868800
.set F_GPU, 53222400
@@ -61,34 +63,32 @@
.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_ADSR1, 0x08
-.set SPU_VOICE_ADSR2, 0x0a
-.set SPU_VOICE_LOOP, 0x0e
+.set SPU_CH_VOL_L, 0x00
+.set SPU_CH_VOL_R, 0x02
+.set SPU_CH_FREQ, 0x04
+.set SPU_CH_ADDR, 0x06
+.set SPU_CH_ADSR1, 0x08
+.set SPU_CH_ADSR2, 0x0a
+.set SPU_CH_LOOP_ADDR, 0x0e
## MDEC
.set MDEC0, 0x1820
.set MDEC1, 0x1824
-## SPI controller port
-
-.set JOY_TXRX, 0x1040
-.set JOY_STAT, 0x1044
-.set JOY_MODE, 0x1048
-.set JOY_CTRL, 0x104a
-.set JOY_BAUD, 0x104e
+## SPI and serial interfaces
-## Serial port
+.set SIO0_DATA, 0x1040
+.set SIO0_STAT, 0x1044
+.set SIO0_MODE, 0x1048
+.set SIO0_CTRL, 0x104a
+.set SIO0_BAUD, 0x104e
-.set SIO_TXRX, 0x1050
-.set SIO_STAT, 0x1054
-.set SIO_MODE, 0x1058
-.set SIO_CTRL, 0x105a
-.set SIO_BAUD, 0x105e
+.set SIO1_DATA, 0x1050
+.set SIO1_STAT, 0x1054
+.set SIO1_MODE, 0x1058
+.set SIO1_CTRL, 0x105a
+.set SIO1_BAUD, 0x105e
## IRQ controller
@@ -142,15 +142,15 @@
.set TIMER2_CTRL, 0x1124
.set TIMER2_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
+## Memory/bus control
+
+.set BUS_EXP1_ADDR, 0x1000
+.set BUS_EXP2_ADDR, 0x1004
+.set BUS_EXP1_CFG, 0x1008
+.set BUS_EXP3_CFG, 0x100c
+.set BUS_BIOS_CFG, 0x1010
+.set BUS_SPU_CFG, 0x1014
+.set BUS_CD_CFG, 0x1018
+.set BUS_EXP2_CFG, 0x101c
+.set BUS_COM_DELAY, 0x1020
+.set BUS_RAM_SIZE, 0x1060
diff --git a/libpsn00b/include/hwregs_c.h b/libpsn00b/include/hwregs_c.h
index 0e21922..7015101 100644
--- a/libpsn00b/include/hwregs_c.h
+++ b/libpsn00b/include/hwregs_c.h
@@ -8,15 +8,20 @@
#include <stdint.h>
-#define _MMIO8(addr) *((volatile uint8_t *) (addr))
-#define _MMIO16(addr) *((volatile uint16_t *) (addr))
-#define _MMIO32(addr) *((volatile uint32_t *) (addr))
+#define _ADDR8(addr) ((volatile uint8_t *) (addr))
+#define _ADDR16(addr) ((volatile uint16_t *) (addr))
+#define _ADDR32(addr) ((volatile uint32_t *) (addr))
+#define _MMIO8(addr) (*_ADDR8(addr))
+#define _MMIO16(addr) (*_ADDR16(addr))
+#define _MMIO32(addr) (*_ADDR32(addr))
/* Constants */
#define IOBASE 0xbf800000
-#define F_CPU 33868800UL
-#define F_GPU 53222400UL
+#define EXP1BASE 0xbf000000
+
+#define F_CPU 33868800L
+#define F_GPU 53222400L
/* GPU */
@@ -82,24 +87,16 @@
#define MDEC0 _MMIO32(IOBASE | 0x1820)
#define MDEC1 _MMIO32(IOBASE | 0x1824)
-/* SPI controller port */
+/* SPI and serial interfaces */
-// IMPORTANT: even though JOY_TXRX is a 32-bit register, it should only be
+// IMPORTANT: even though SIO_DATA 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 (IOBASE | 0x1040)
-#define JOY_STAT _MMIO16(IOBASE | 0x1044)
-#define JOY_MODE _MMIO16(IOBASE | 0x1048)
-#define JOY_CTRL _MMIO16(IOBASE | 0x104a)
-#define JOY_BAUD _MMIO16(IOBASE | 0x104e)
-
-/* Serial port */
-
-#define SIO_TXRX _MMIO8 (IOBASE | 0x1050)
-#define SIO_STAT _MMIO16(IOBASE | 0x1054)
-#define SIO_MODE _MMIO16(IOBASE | 0x1058)
-#define SIO_CTRL _MMIO16(IOBASE | 0x105a)
-#define SIO_BAUD _MMIO16(IOBASE | 0x105e)
+#define SIO_DATA(N) _MMIO8 (IOBASE | 0x1040 + 16 * (N))
+#define SIO_STAT(N) _MMIO16(IOBASE | 0x1044 + 16 * (N))
+#define SIO_MODE(N) _MMIO16(IOBASE | 0x1048 + 16 * (N))
+#define SIO_CTRL(N) _MMIO16(IOBASE | 0x104a + 16 * (N))
+#define SIO_BAUD(N) _MMIO16(IOBASE | 0x104e + 16 * (N))
/* IRQ controller */
@@ -121,17 +118,17 @@
#define TIMER_CTRL(N) _MMIO32(IOBASE | 0x1104 + 16 * (N))
#define TIMER_RELOAD(N) _MMIO32(IOBASE | 0x1108 + 16 * (N))
-/* Memory control */
-
-#define EXP1_ADDR _MMIO32(IOBASE | 0x1000)
-#define EXP2_ADDR _MMIO32(IOBASE | 0x1004)
-#define EXP1_DELAY_SIZE _MMIO32(IOBASE | 0x1008)
-#define EXP3_DELAY_SIZE _MMIO32(IOBASE | 0x100c)
-#define BIOS_DELAY_SIZE _MMIO32(IOBASE | 0x1010)
-#define SPU_DELAY_SIZE _MMIO32(IOBASE | 0x1014)
-#define CD_DELAY_SIZE _MMIO32(IOBASE | 0x1018)
-#define EXP2_DELAY_SIZE _MMIO32(IOBASE | 0x101c)
-#define COM_DELAY_CFG _MMIO32(IOBASE | 0x1020)
-#define RAM_SIZE_CFG _MMIO32(IOBASE | 0x1060)
+/* Memory/bus control */
+
+#define BUS_EXP1_ADDR _MMIO32(IOBASE | 0x1000)
+#define BUS_EXP2_ADDR _MMIO32(IOBASE | 0x1004)
+#define BUS_EXP1_CFG _MMIO32(IOBASE | 0x1008)
+#define BUS_EXP3_CFG _MMIO32(IOBASE | 0x100c)
+#define BUS_BIOS_CFG _MMIO32(IOBASE | 0x1010)
+#define BUS_SPU_CFG _MMIO32(IOBASE | 0x1014)
+#define BUS_CD_CFG _MMIO32(IOBASE | 0x1018)
+#define BUS_EXP2_CFG _MMIO32(IOBASE | 0x101c)
+#define BUS_COM_DELAY _MMIO32(IOBASE | 0x1020)
+#define BUS_RAM_SIZE _MMIO32(IOBASE | 0x1060)
#endif
diff --git a/libpsn00b/libc/clz.s b/libpsn00b/libc/clz.s
new file mode 100644
index 0000000..28a28eb
--- /dev/null
+++ b/libpsn00b/libc/clz.s
@@ -0,0 +1,43 @@
+# PSn00bSDK leading zero count intrinsics
+# (C) 2022 spicyjpeg - MPL licensed
+#
+# libgcc provides two functions used internally by GCC to count the number of
+# leading zeroes or ones in a value, _clzsi2() (32-bit) and _clzdi2() (64-bit).
+# This file overrides them with faster implementations that make use of the
+# GTE's LZCS/LZCR registers.
+
+.set noreorder
+
+.section .text._clzsi2
+.global _clzsi2
+.type _clzsi2, @function
+_clzsi2:
+ mtc2 $a0, $30
+ nop
+ nop
+ mfc2 $v0, $31
+
+ jr $ra
+ nop
+
+.section .text._clzdi2
+.global _clzdi2
+.type _clzdi2, @function
+_clzdi2:
+ bnez $a1, .Lhas_msb
+ nop
+
+ mtc2 $a0, $30 # if (!msb) return 32 + clz(lsb)
+ b .Lreturn
+ li $v1, 32
+
+.Lhas_msb:
+ mtc2 $a1, $30 # if (msb) return 0 + clz(msb)
+ nop
+ li $v1, 0
+
+.Lreturn:
+ mfc2 $v0, $31
+
+ jr $ra
+ addu $v0, $v1
diff --git a/libpsn00b/psxcd/common.c b/libpsn00b/psxcd/common.c
index 6b20df2..8b8030b 100644
--- a/libpsn00b/psxcd/common.c
+++ b/libpsn00b/psxcd/common.c
@@ -206,7 +206,7 @@ int CdInit(void) {
InterruptCallback(IRQ_CD, &_cd_irq_handler);
ExitCriticalSection();
- CD_DELAY_SIZE = 0x00020943;
+ BUS_CD_CFG = 0x00020943;
CD_REG(0) = 1;
CD_REG(3) = 0x1f; // Acknowledge all IRQs
diff --git a/libpsn00b/psxetc/interrupts.c b/libpsn00b/psxetc/interrupts.c
index f05b089..f2a273c 100644
--- a/libpsn00b/psxetc/interrupts.c
+++ b/libpsn00b/psxetc/interrupts.c
@@ -173,7 +173,7 @@ int ResetCallback(void) {
for (int i = 0; i < NUM_DMA_CHANNELS; i++)
_dma_handlers[i] = (void *) 0;
- COM_DELAY_CFG = 0x00001325;
+ BUS_COM_DELAY = 0x00001325;
_96_remove();
RestartCallback();
return 0;
diff --git a/libpsn00b/psxsio/sio.c b/libpsn00b/psxsio/sio.c
index cdcef0e..919f0cb 100644
--- a/libpsn00b/psxsio/sio.c
+++ b/libpsn00b/psxsio/sio.c
@@ -36,8 +36,8 @@ static volatile RingBuffer _tx_buffer, _rx_buffer;
static void _sio_handler(void) {
// Handle any incoming bytes.
- while (SIO_STAT & SR_RXRDY) {
- uint8_t value = SIO_TXRX;
+ while (SIO_STAT(1) & SR_RXRDY) {
+ uint8_t value = SIO_DATA(1);
// Skip storing this byte into the RX buffer if the callback returns a
// non-zero value.
@@ -63,7 +63,7 @@ static void _sio_handler(void) {
// Send the next byte in the buffer if the TX unit is ready. Note that
// checking for CTS is unnecessary as the serial port is already hardwired
// to do so.
- if (SIO_STAT & (SR_TXRDY | SR_TXU)) {
+ if (SIO_STAT(1) & (SR_TXRDY | SR_TXU)) {
int length = _tx_buffer.length;
if (length) {
@@ -71,18 +71,18 @@ static void _sio_handler(void) {
_tx_buffer.head = (head + 1) % BUFFER_LENGTH;
_tx_buffer.length = length - 1;
- SIO_CTRL |= CR_TXIEN;
- SIO_TXRX = _tx_buffer.data[head];
+ SIO_CTRL(1) |= CR_TXIEN;
+ SIO_DATA(1) = _tx_buffer.data[head];
} else {
- SIO_CTRL &= CR_TXIEN ^ 0xffff;
+ SIO_CTRL(1) &= CR_TXIEN ^ 0xffff;
}
}
// Acknowledge the IRQ and update flow control signals.
if (_rx_buffer.length < BUFFER_LENGTH)
- SIO_CTRL = CR_INTRST | (SIO_CTRL | _ctrl_reg_flag);
+ SIO_CTRL(1) = CR_INTRST | (SIO_CTRL(1) | _ctrl_reg_flag);
else
- SIO_CTRL = CR_INTRST | (SIO_CTRL & (_ctrl_reg_flag ^ 0xffff));
+ SIO_CTRL(1) = CR_INTRST | (SIO_CTRL(1) & (_ctrl_reg_flag ^ 0xffff));
}
/* Serial port initialization API */
@@ -91,10 +91,10 @@ void SIO_Init(int baud, uint16_t mode) {
EnterCriticalSection();
_old_sio_handler = InterruptCallback(IRQ_SIO1, &_sio_handler);
- SIO_CTRL = CR_ERRRST;
- SIO_MODE = (mode & 0xfffc) | MR_BR_16;
- SIO_BAUD = (uint16_t) ((int) 0x1fa400 / baud);
- SIO_CTRL = CR_TXEN | CR_RXEN | CR_RXIEN;
+ SIO_CTRL(1) = CR_ERRRST;
+ SIO_MODE(1) = (mode & 0xfffc) | MR_BR_16;
+ SIO_BAUD(1) = (uint16_t) ((int) 0x1fa400 / baud);
+ SIO_CTRL(1) = CR_TXEN | CR_RXEN | CR_RXIEN;
_tx_buffer.head = 0;
_tx_buffer.tail = 0;
@@ -113,7 +113,7 @@ void SIO_Quit(void) {
EnterCriticalSection();
InterruptCallback(IRQ_SIO1, _old_sio_handler);
- SIO_CTRL = CR_ERRRST;
+ SIO_CTRL(1) = CR_ERRRST;
ExitCriticalSection();
}
@@ -126,21 +126,21 @@ void SIO_SetFlowControl(SIO_FlowControl mode) {
_flow_control = SIO_FC_NONE;
_ctrl_reg_flag = 0;
- SIO_CTRL &= 0xffff ^ CR_DSRIEN;
+ SIO_CTRL(1) &= 0xffff ^ CR_DSRIEN;
break;
case SIO_FC_RTS_CTS:
_flow_control = SIO_FC_RTS_CTS;
_ctrl_reg_flag = CR_RTS;
- SIO_CTRL &= 0xffff ^ CR_DSRIEN;
+ SIO_CTRL(1) &= 0xffff ^ CR_DSRIEN;
break;
/*case SIO_FC_DTR_DSR:
_flow_control = SIO_FC_DTR_DSR;
_ctrl_reg_flag = CR_DTR;
- SIO_CTRL |= CR_DSRIEN;
+ SIO_CTRL(1) |= CR_DSRIEN;
break;*/
}
@@ -218,8 +218,8 @@ int SIO_WriteByte2(uint8_t value) {
// than via syscalls for performance reasons.
FastEnterCriticalSection();
- if (SIO_STAT & (SR_TXRDY | SR_TXU)) {
- SIO_TXRX = value;
+ if (SIO_STAT(1) & (SR_TXRDY | SR_TXU)) {
+ SIO_DATA(1) = value;
FastExitCriticalSection();
return 0;
}
@@ -238,7 +238,7 @@ int SIO_WriteByte2(uint8_t value) {
_tx_buffer.length = length + 1;
_tx_buffer.data[tail] = value;
- SIO_CTRL |= CR_TXIEN;
+ SIO_CTRL(1) |= CR_TXIEN;
FastExitCriticalSection();
return length;
@@ -256,7 +256,7 @@ int SIO_WriteSync(int mode) {
if (!_tx_buffer.length) {
// Wait for the TX unit to finish sending the last byte.
- while (!(SIO_STAT & (SR_TXRDY | SR_TXU)))
+ while (!(SIO_STAT(1) & (SR_TXRDY | SR_TXU)))
__asm__ volatile("");
} else {
//_sdk_log("SIO_WriteSync() timeout\n");
diff --git a/libpsn00b/psxsio/tty.c b/libpsn00b/psxsio/tty.c
index 4dc9fd1..a1b33c8 100644
--- a/libpsn00b/psxsio/tty.c
+++ b/libpsn00b/psxsio/tty.c
@@ -32,10 +32,10 @@ static int _sio_inout(FCB *fcb, int cmd) {
case 2: // write
for (int i = 0; i < fcb->trns_len; i++) {
- while (!(SIO_STAT & (SR_TXRDY | SR_TXU)))
+ while (!(SIO_STAT(1) & (SR_TXRDY | SR_TXU)))
__asm__ volatile("");
- SIO_TXRX = *(ptr++);
+ SIO_DATA(1) = *(ptr++);
}
return fcb->trns_len;
diff --git a/libpsn00b/psxspu/common.c b/libpsn00b/psxspu/common.c
index 5dae473..45654ad 100644
--- a/libpsn00b/psxspu/common.c
+++ b/libpsn00b/psxspu/common.c
@@ -45,9 +45,9 @@ static size_t _dma_transfer(uint32_t *data, size_t length, int write) {
}
// Increase bus delay for DMA reads
- SPU_DELAY_SIZE &= 0xf0ffffff;
+ BUS_SPU_CFG &= ~(0xf << 24);
if (!write)
- SPU_DELAY_SIZE = 2 << 24;
+ BUS_SPU_CFG = 2 << 24;
SPU_CTRL &= 0xffcf; // Disable DMA request
_wait_status(0x0030, 0x0000);
@@ -107,7 +107,7 @@ static size_t _manual_write(const uint16_t *data, size_t length) {
/* Public API */
void SpuInit(void) {
- SPU_DELAY_SIZE = 0x200931e1;
+ BUS_SPU_CFG = 0x200931e1;
SPU_CTRL = 0x0000; // SPU disabled
_wait_status(0x001f, 0x0000);