aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorspicyjpeg <thatspicyjpeg@gmail.com>2024-01-08 19:15:28 +0100
committerspicyjpeg <thatspicyjpeg@gmail.com>2024-01-08 19:15:28 +0100
commita149dc9e3b84922a7e52d31e9a56f255a5597dff (patch)
tree8f30aacab5d7e0d2569e821c2d3b83c6e703b81e
parentdd85f9f993427ae69ab905486f8ef372d3960664 (diff)
downloadpsn00bsdk-a149dc9e3b84922a7e52d31e9a56f255a5597dff.tar.gz
Fix examples, update submodules and CI script
-rw-r--r--.github/workflows/build.yml31
-rw-r--r--examples/cdrom/cdxa/main.c2
-rw-r--r--examples/mdec/strvideo/main.c22
-rw-r--r--examples/sound/cdstream/main.c11
-rw-r--r--examples/sound/cdstream/stream.c18
-rw-r--r--examples/sound/spustream/main.c11
-rw-r--r--examples/sound/vagsample/main.c31
m---------tools/mkpsxiso0
m---------tools/tinyxml20
9 files changed, 59 insertions, 67 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 00926ef..09147ab 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -10,17 +10,14 @@
name: Build PSn00bSDK
on: [ push, pull_request ]
env:
- BINUTILS_VERSION: '2.40'
+ BINUTILS_VERSION: '2.41'
BINUTILS_OPTIONS: '--disable-docs --disable-nls --disable-werror --with-float=soft'
- GCC_VERSION: '12.3.0'
+ GCC_VERSION: '13.2.0'
GCC_OPTIONS: '--disable-docs --disable-nls --disable-werror --disable-libada --disable-libssp --disable-libquadmath --disable-threads --disable-libgomp --disable-libstdcxx-pch --disable-hosted-libstdcxx --enable-languages=c,c++ --without-isl --without-headers --with-float=soft --with-gnu-as --with-gnu-ld'
GCC_TARGET: 'mipsel-none-elf'
jobs:
# This is based on doc/toolchain.md, no surprises here other than the cache.
- # Since actions/cache@v2 has bugs when restoring on Windows caches created on
- # Linux, v1 is used instead.
- # https://github.com/actions/cache/issues/576
build-gcc:
name: Build GCC toolchain
runs-on: ubuntu-latest
@@ -28,8 +25,9 @@ jobs:
steps:
- name: Initialize toolchain cache
id: _cache
- uses: actions/cache@v1
+ uses: actions/cache@v3.3.2
with:
+ enableCrossOsArchive: true
key: gcc-${{ env.GCC_TARGET }}-${{ env.GCC_VERSION }}
path: gcc
@@ -100,8 +98,9 @@ jobs:
echo "C:\msys64\usr\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
- name: Initialize toolchain cache
- uses: actions/cache@v1
+ uses: actions/cache@v3.3.2
with:
+ enableCrossOsArchive: true
key: gcc-${{ env.GCC_TARGET }}-${{ env.GCC_VERSION }}
path: gcc
@@ -110,7 +109,7 @@ jobs:
pacman -S --noconfirm mingw-w64-x86_64-ninja
- name: Fetch repo contents
- uses: actions/checkout@v2
+ uses: actions/checkout@v4
with:
path: sdk
submodules: recursive
@@ -125,7 +124,7 @@ jobs:
# an artifact, so it's best to upload each package type as a separate
# artifact.
- name: Upload build artifacts
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@v4
with:
name: psn00bsdk-windows
path: build/packages/*.zip
@@ -137,8 +136,9 @@ jobs:
steps:
- name: Initialize toolchain cache
- uses: actions/cache@v1
+ uses: actions/cache@v3.3.2
with:
+ enableCrossOsArchive: true
key: gcc-${{ env.GCC_TARGET }}-${{ env.GCC_VERSION }}
path: gcc
@@ -148,7 +148,7 @@ jobs:
sudo apt-get install -y --no-install-recommends ninja-build
- name: Fetch repo contents
- uses: actions/checkout@v2
+ uses: actions/checkout@v4
with:
path: sdk
submodules: recursive
@@ -160,7 +160,7 @@ jobs:
cmake --build build -t package
- name: Upload build artifacts
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@v4
with:
name: psn00bsdk-linux
path: build/packages/*.zip
@@ -175,8 +175,9 @@ jobs:
steps:
- name: Initialize toolchain cache
if: ${{ github.ref_type == 'tag' }}
- uses: actions/cache@v1
+ uses: actions/cache@v3.3.2
with:
+ enableCrossOsArchive: true
key: gcc-${{ env.GCC_TARGET }}-${{ env.GCC_VERSION }}
path: gcc
@@ -190,7 +191,7 @@ jobs:
- name: Fetch repo contents
if: ${{ github.ref_type == 'tag' }}
- uses: actions/checkout@v2
+ uses: actions/checkout@v4
with:
path: sdk
@@ -201,7 +202,7 @@ jobs:
- name: Fetch build artifacts
if: ${{ github.ref_type == 'tag' }}
- uses: actions/download-artifact@v2
+ uses: actions/download-artifact@v4
with:
path: .
diff --git a/examples/cdrom/cdxa/main.c b/examples/cdrom/cdxa/main.c
index 253f540..d49ff1b 100644
--- a/examples/cdrom/cdxa/main.c
+++ b/examples/cdrom/cdxa/main.c
@@ -214,7 +214,7 @@ void cd_event_handler(CdlIntrResult event, uint8_t *payload) {
if (
!(sector.xa_header[0].submode & XA_TYPE_AUDIO) &&
- !(sector.xa_header[0].submode & XA_TYPE_AUDIO)
+ !(sector.xa_header[1].submode & XA_TYPE_AUDIO)
) {
// Seek back to the beginning of the file.
CdControlF(CdlReadS, &xa_loc);
diff --git a/examples/mdec/strvideo/main.c b/examples/mdec/strvideo/main.c
index 853e0c2..038ba7a 100644
--- a/examples/mdec/strvideo/main.c
+++ b/examples/mdec/strvideo/main.c
@@ -17,13 +17,13 @@
* CD drive handles XA-ADPCM sectors automatically, so no CPU intervention is
* necessary to play the audio track interleaved with the video.
* - Once a full frame has been demuxed, the bitstream data is parsed and
- * decompressed by the CPU (using DecDCTvlc()) to an array of run-length
- * codes to be fed to the MDEC. This is done in the main loop.
+ * decompressed by the CPU (using DecDCTvlc()) to an array of run-length codes
+ * to be fed to the MDEC. This is done in the main loop.
* - At the same time the last frame decompressed is read from RAM by the MDEC,
* which decodes it and outputs one 16-pixel-wide vertical slice at a time.
* - When a slice is ready, it is uploaded by mdec_dma_handler() to the current
* framebuffer in VRAM while the MDEC is decoding the next slice.
- * A text overlay is drawn on top of the framebuffer using the GPU after the
+ * - A text overlay is drawn on top of the framebuffer using the GPU after the
* entire frame has been decoded.
*
* Since pretty much all buffers used are going to be read and written at the
@@ -56,6 +56,12 @@
// support 24bpp rendering, so the text overlay is only enabled in 16bpp mode.
//#define DISP_24BPP
+// Uncomment to enable waiting for vertical sync after each frame is decoded.
+// This will get rid of screen tearing, but may result in the player failing to
+// play .STR files with higher frame rates (see main() for more details and
+// possible workarounds).
+//#define ENABLE_VSYNC
+
/* Display/GPU context utilities */
#define SCREEN_XRES 320
@@ -163,12 +169,14 @@ typedef struct {
volatile int8_t cur_frame, cur_slice;
} StreamContext;
+// This structure contains all buffers required for playback as well as the
+// current state of the player. Note that it takes up a significant amount of
+// RAM, so allocating it on the heap when needed and keeping a pointer to it
+// may be a better option.
static StreamContext str_ctx;
// This buffer is used by cd_sector_handler() as a temporary area for sectors
-// read from the CD. Due to DMA limitations it can't be allocated on the stack
-// (especially not in the interrupt callbacks' stack, whose size is very
-// limited).
+// read from the CD. Due to DMA limitations it can't be allocated on the stack.
static STR_Header sector_header;
void cd_sector_handler(void) {
@@ -394,7 +402,9 @@ int main(int argc, const char* argv[]) {
// implement triple buffering (i.e. always keep 2 fully decoded frames
// in VRAM and use VSyncCallback() to register a function that displays
// the next decoded frame if available whenever vblank occurs).
+#ifdef ENABLE_VSYNC
VSync(0);
+#endif
DecDCTinSync(0);
DecDCToutSync(0);
diff --git a/examples/sound/cdstream/main.c b/examples/sound/cdstream/main.c
index 2bd2142..2a9bbab 100644
--- a/examples/sound/cdstream/main.c
+++ b/examples/sound/cdstream/main.c
@@ -152,13 +152,6 @@ typedef struct {
char name[16];
} VAG_Header;
-#define SWAP_ENDIAN(x) ( \
- (((uint32_t) (x) & 0x000000ff) << 24) | \
- (((uint32_t) (x) & 0x0000ff00) << 8) | \
- (((uint32_t) (x) & 0x00ff0000) >> 8) | \
- (((uint32_t) (x) & 0xff000000) >> 24) \
-)
-
/* Helper functions */
#define DUMMY_BLOCK_ADDR 0x1000
@@ -250,14 +243,14 @@ void setup_stream(const CdlLOC *pos) {
int num_channels = vag->channels ? vag->channels : 2;
int num_chunks =
- (SWAP_ENDIAN(vag->size) + vag->interleave - 1) / vag->interleave;
+ (__builtin_bswap32(vag->size) + vag->interleave - 1) / vag->interleave;
__builtin_memset(&config, 0, sizeof(Stream_Config));
config.spu_address = STREAM_BUFFER_ADDR;
config.interleave = vag->interleave;
config.buffer_size = RAM_BUFFER_SIZE;
- config.sample_rate = SWAP_ENDIAN(vag->sample_rate);
+ config.sample_rate = __builtin_bswap32(vag->sample_rate);
// Use the first N channels of the SPU and pan them left/right in pairs
// (this assumes the stream contains one or more stereo tracks).
diff --git a/examples/sound/cdstream/stream.c b/examples/sound/cdstream/stream.c
index 624b6e1..9dfc9ba 100644
--- a/examples/sound/cdstream/stream.c
+++ b/examples/sound/cdstream/stream.c
@@ -29,7 +29,7 @@
/* Private utilities */
-static volatile Stream_Context *_active_ctx = (void *) 0;
+static volatile Stream_Context *volatile _active_ctx = (void *) 0;
static Stream_Time _default_timer_function(void) {
return VSync(-1);
@@ -42,7 +42,7 @@ static int _get_default_timer_rate(void) {
/* Interrupt handlers */
static void _spu_irq_handler(void) {
- Stream_Context *ctx = _active_ctx;
+ volatile Stream_Context *ctx = _active_ctx;
// Acknowledge the interrupt to ensure it can be triggered again. The only
// way to do this is actually to disable the interrupt entirely; we'll
@@ -90,13 +90,13 @@ static void _spu_irq_handler(void) {
// both channels' loop addresses to make them "jump" to the new buffers,
// rather than actually looping when they encounter the loop flag at the end
// of the currently playing buffers.
- uint32_t offset = 0;
uint32_t address =
ctx->config.spu_address + (ctx->db_active ? ctx->chunk_size : 0);
int sample_rate = ctx->new_sample_rate;
ctx->config.sample_rate = sample_rate;
+ SpuSetTransferStartAddr(address);
SPU_IRQ_ADDR = getSPUAddr(address);
for (uint32_t ch = 0, mask = ctx->config.channel_mask; mask; ch++, mask >>= 1) {
@@ -104,15 +104,14 @@ static void _spu_irq_handler(void) {
continue;
SPU_CH_FREQ (ch) = getSPUSampleRate(sample_rate);
- SPU_CH_LOOP_ADDR(ch) = getSPUAddr(address + offset);
- offset += ctx->config.interleave;
+ SPU_CH_LOOP_ADDR(ch) = getSPUAddr(address);
+ address += ctx->config.interleave;
// Make sure this channel's data ends with an appropriate loop flag.
//ptr[offset - 15] |= 0x03;
}
// Start uploading the next chunk to the SPU.
- SpuSetTransferStartAddr(address);
SpuWrite((const uint32_t *) ptr, ctx->chunk_size);
}
@@ -186,6 +185,9 @@ bool Stream_Start(Stream_Context *ctx, bool resume) {
int sample_rate = ctx->new_sample_rate;
ctx->config.sample_rate = sample_rate;
+ // Disable the IRQ as we're going to call spu_irq_handler() manually (due to
+ // finicky SPU timings).
+ SPU_CTRL &= ~(1 << 6);
SpuSetKey(0, ctx->config.channel_mask);
for (uint32_t ch = 0, mask = ctx->config.channel_mask; mask; ch++, mask >>= 1) {
@@ -200,14 +202,14 @@ bool Stream_Start(Stream_Context *ctx, bool resume) {
address += ctx->config.interleave;
}
- _spu_irq_handler();
SpuSetKey(1, ctx->config.channel_mask);
+ _spu_irq_handler();
return true;
}
bool Stream_Stop(void) {
- Stream_Context *ctx = _active_ctx;
+ volatile Stream_Context *ctx = _active_ctx;
if (!ctx)
return false;
diff --git a/examples/sound/spustream/main.c b/examples/sound/spustream/main.c
index 28a0ce5..cf91c26 100644
--- a/examples/sound/spustream/main.c
+++ b/examples/sound/spustream/main.c
@@ -127,13 +127,6 @@ typedef struct {
char name[16];
} VAG_Header;
-#define SWAP_ENDIAN(x) ( \
- (((uint32_t) (x) & 0x000000ff) << 24) | \
- (((uint32_t) (x) & 0x0000ff00) << 8) | \
- (((uint32_t) (x) & 0x00ff0000) >> 8) | \
- (((uint32_t) (x) & 0xff000000) >> 24) \
-)
-
/* Interrupt callbacks */
// The first 4 KB of SPU RAM are reserved for capture buffers and psxspu
@@ -220,8 +213,8 @@ void init_stream(const VAG_Header *vag) {
stream_ctx.data = &((const uint8_t *) vag)[2048];
stream_ctx.buffer_size = buf_size;
- stream_ctx.num_chunks = (SWAP_ENDIAN(vag->size) + buf_size - 1) / buf_size;
- stream_ctx.sample_rate = SWAP_ENDIAN(vag->sample_rate);
+ stream_ctx.num_chunks = (__builtin_bswap32(vag->size) + buf_size - 1) / buf_size;
+ stream_ctx.sample_rate = __builtin_bswap32(vag->sample_rate);
stream_ctx.channels = vag->channels ? vag->channels : 1;
stream_ctx.db_active = 1;
diff --git a/examples/sound/vagsample/main.c b/examples/sound/vagsample/main.c
index 701bfb5..4af92e9 100644
--- a/examples/sound/vagsample/main.c
+++ b/examples/sound/vagsample/main.c
@@ -99,13 +99,6 @@ typedef struct {
char name[16];
} VAG_Header;
-#define SWAP_ENDIAN(x) ( \
- (((uint32_t) (x) & 0x000000ff) << 24) | \
- (((uint32_t) (x) & 0x0000ff00) << 8) | \
- (((uint32_t) (x) & 0x00ff0000) >> 8) | \
- (((uint32_t) (x) & 0xff000000) >> 24) \
-)
-
/* Helper functions */
// The first 4 KB of SPU RAM are reserved for capture buffers and psxspu
@@ -119,17 +112,17 @@ static int next_sample_addr = ALLOC_START_ADDR;
int upload_sample(const void *data, int size) {
// Round the size up to the nearest multiple of 64, as SPU DMA transfers
// are done in 64-byte blocks.
- int _addr = next_sample_addr;
- int _size = (size + 63) & 0xffffffc0;
+ int addr = next_sample_addr;
+ size = (size + 63) & ~63;
SpuSetTransferMode(SPU_TRANSFER_BY_DMA);
- SpuSetTransferStartAddr(_addr);
+ SpuSetTransferStartAddr(addr);
- SpuWrite((const uint32_t *) data, _size);
+ SpuWrite((const uint32_t *) data, size);
SpuIsTransferCompleted(SPU_TRANSFER_WAIT);
- next_sample_addr = _addr + _size;
- return _addr;
+ next_sample_addr = addr + size;
+ return addr;
}
void play_sample(int addr, int sample_rate) {
@@ -168,13 +161,13 @@ int main(int argc, const char* argv[]) {
SpuInit();
// Upload the samples to the SPU and parse their headers.
- VAG_Header *proyt_vag = (VAG_Header *) proyt;
- VAG_Header *tdfx_vag = (VAG_Header *) tdfx;
+ const VAG_Header *proyt_vag = (const VAG_Header *) proyt;
+ const VAG_Header *tdfx_vag = (const VAG_Header *) tdfx;
- int proyt_addr = upload_sample(&proyt_vag[1], SWAP_ENDIAN(proyt_vag->size));
- int tdfx_addr = upload_sample(&tdfx_vag[1], SWAP_ENDIAN(tdfx_vag->size));
- int proyt_sr = SWAP_ENDIAN(proyt_vag->sample_rate);
- int tdfx_sr = SWAP_ENDIAN(tdfx_vag->sample_rate);
+ int proyt_addr = upload_sample(proyt_vag + 1, __builtin_bswap32(proyt_vag->size));
+ int tdfx_addr = upload_sample(tdfx_vag + 1, __builtin_bswap32(tdfx_vag->size));
+ int proyt_sr = __builtin_bswap32(proyt_vag->sample_rate);
+ int tdfx_sr = __builtin_bswap32(tdfx_vag->sample_rate);
// Set up controller polling.
uint8_t pad_buff[2][34];
diff --git a/tools/mkpsxiso b/tools/mkpsxiso
-Subproject 9f6275f08829ea9de8122c8232a019e8724acbb
+Subproject 08fa69f61365a3314b98076bfe7b2f37ed9db5d
diff --git a/tools/tinyxml2 b/tools/tinyxml2
-Subproject e05956094c27117f989d22f25b75633123d72a8
+Subproject 321ea883b7190d4e85cae5512a12e5eaa8f8731