From 603b42797c4b0e7a3e2a3cac320daecf1ee34feb Mon Sep 17 00:00:00 2001 From: spicyjpeg <88942473+spicyjpeg@users.noreply.github.com> Date: Sun, 28 Nov 2021 17:31:33 +0100 Subject: Add GitHub Actions CI/release workflow, rewrite changelog --- .github/scripts/generate_release_notes.py | 194 ++++++++++++++++++++++++++++ .github/workflows/build.yml | 208 ++++++++++++++++++++++++++++++ 2 files changed, 402 insertions(+) create mode 100644 .github/scripts/generate_release_notes.py create mode 100644 .github/workflows/build.yml (limited to '.github') diff --git a/.github/scripts/generate_release_notes.py b/.github/scripts/generate_release_notes.py new file mode 100644 index 0000000..f3e4870 --- /dev/null +++ b/.github/scripts/generate_release_notes.py @@ -0,0 +1,194 @@ +#!/usr/bin/env python3 +# PSn00bSDK release notes generator +# (C) 2021 spicyjpeg - MPL licensed + +import sys, re +from time import gmtime, strptime +from argparse import ArgumentParser, FileType + +## Helpers + +VERSION_REGEX = re.compile(r"^(?:refs\/tags\/)?(?:v|ver|version|release)? *(.*)") + +def parse_date(date): + return strptime(date.strip(), "%Y-%m-%d") + +def normalize_version(version): + match = VERSION_REGEX.match(version.lower()) + if not match: + raise ValueError(f"invalid version string: {version}") + + return match.group(1) + +## Changelog parser + +BLOCK_REGEX = re.compile(r"^#{2,}[ \t]*([0-9]{4}-[0-9]{2}-[0-9]{2})(?:[:\- \t]+(.+?))?$", re.MULTILINE) +AUTHOR_REGEX = re.compile(r"^([A-Za-z0-9_].*?)[ \t]*:.*?$", re.MULTILINE) +FIRST_VERSION = "initial" + +def parse_authors(block): + # [ _crap, author, body, author, body, ... ] + items = AUTHOR_REGEX.split(block.strip()) + + if items[0].strip(): + raise RuntimeError("a block has changes listed with no author specified") + + authors = {} + for i in range(1, len(items), 2): + name, body = items[i:i + 2] + + name = name.strip() + body = body.strip() + if name not in authors: + authors[name] = "" + + authors[name] += body + + return authors + +def parse_blocks(changelog): + # [ _crap, date, version, body, date, version, body, ... ] + items = BLOCK_REGEX.split(changelog.strip()) + + #if items[0].strip(): + #raise RuntimeError("the changelog doesn't start with a valid block") + + # Iterate over all blocks from bottom to top (i.e. oldest first). + last_version = FIRST_VERSION + + for i in range(len(items), 1, -3): + date, version, body = items[i - 3:i] + + # If no version is present in the header, assume it's the same as the + # previous block's version. + if version: + version = normalize_version(version) + last_version = version + else: + version = last_version + + yield parse_date(date), version, parse_authors(body) + +## Release notes generation + +VERSION_TEMPLATE = """New in version **{version}** (contributed by {authors}): + +{changes} + +""" +NOTES_TEMPLATE = """{notes} + +------------------------------------------------------- +_These notes have been generated automatically._ +_See the changelog or commit history for more details._ +""" + +NO_VERSIONS_TEMPLATE = "No information available about this release." +AUTHOR_LINK_TEMPLATE = "**{0}**" +#AUTHOR_LINK_TEMPLATE = "[{0}](https://github.com/{0})" + +def generate_notes(versions): + notes = "" + + for version, ( authors, changes ) in versions.items(): + _authors = list(set(authors)) + _authors.sort() + _authors = map(AUTHOR_LINK_TEMPLATE.format, _authors) + + notes += VERSION_TEMPLATE.format( + version = version, + authors = ", ".join(_authors), + changes = "\n\n".join(changes) + ) + + if not notes: + notes = NO_VERSIONS_TEMPLATE + + return NOTES_TEMPLATE.format(notes = notes.strip()) + +## Main + +def get_args(): + parser = ArgumentParser( + description = "Generates and outputs release notes from a Markdown changelog file.", + add_help = False + ) + + tools_group = parser.add_argument_group("Tools") + tools_group.add_argument( + "-h", "--help", + action = "help", + help = "Show this help message and exits" + ) + + files_group = parser.add_argument_group("Files") + files_group.add_argument( + "changelog", + type = FileType("rt"), + help = "Markdown changelog file to parse" + ) + files_group.add_argument( + "-o", "--output", + type = FileType("wt"), + default = sys.stdout, + help = "Where to output release notes (stdout by default)", + metavar = "file" + ) + + filter_group = parser.add_argument_group("Filters") + filter_group.add_argument( + "-v", "--version", + action = "append", + type = str, + help = "Ignore all changes not belonging to a version (can be specified multiple times)", + metavar = "name" + ) + filter_group.add_argument( + "-f", "--from-date", + type = parse_date, + default = parse_date("2000-01-01"), + help = "Ignore all changes before date", + metavar = "yyyy-mm-dd" + ) + filter_group.add_argument( + "-t", "--to-date", + type = parse_date, + default = gmtime(), + help = "Ignore all changes after date", + metavar = "yyyy-mm-dd" + ) + + return parser.parse_args() + +def main(): + args = get_args() + version_list = list(map(normalize_version, args.version or [])) + + with args.changelog as _file: + changelog = _file.read() + + # Iterate over all blocks in the changelog and sort them by version, + # merging all changes and authors for each version. + versions = {} + + for date, version, authors in parse_blocks(changelog): + # Apply version and date filters. + if version_list and (version not in version_list): + continue + if date < args.from_date or date > args.to_date: + continue + + if version not in versions: + versions[version] = [], [] + + _authors, _changes = versions[version] + _authors.extend(authors.keys()) + _changes.extend(authors.values()) + + notes = generate_notes(versions) + + with args.output as _file: + _file.write(notes) + +if __name__ == "__main__": + main() diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..d6746b0 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,208 @@ +# PSn00bSDK GitHub Actions CI script +# (C) 2021 spicyjpeg - MPL licensed + +# The GCC toolchain is stored in the GitHub Actions cache after being built. To +# minimize build times, all the toolchain build steps are skipped if there is a +# cached copy of the toolchain that has not expired (even though the build-gcc +# job still has to run in order to check the cache's contents). The cache is +# shared between all actions in a repo. + +name: Build PSn00bSDK +on: [ push, pull_request ] +env: + BINUTILS_VERSION: 2.36 + GCC_VERSION: 11.1.0 + GCC_TARGET: mipsel-none-elf + +jobs: + # This is based on doc/toolchain.md, no surprises here other than the cache. + build-gcc: + name: Build GCC toolchain + runs-on: ubuntu-latest + + steps: + - name: Initialize toolchain cache + id: _cache + uses: actions/cache@v2 + with: + key: gcc-${{ env.GCC_TARGET }}-${{ env.GCC_VERSION }} + path: gcc + + - name: Install prerequisites + if: ${{ steps._cache.outputs.cache-hit != 'true' }} + run: | + sudo apt-get update -y + sudo apt-get install -y --no-install-recommends make g++-mingw-w64-x86-64 + + - name: Download and extract sources + if: ${{ steps._cache.outputs.cache-hit != 'true' }} + run: | + wget -q -O binutils.tar.xz https://ftpmirror.gnu.org/gnu/binutils/binutils-${{ env.BINUTILS_VERSION }}.tar.xz + wget -q -O gcc.tar.xz https://ftpmirror.gnu.org/gnu/gcc/gcc-${{ env.GCC_VERSION }}/gcc-${{ env.GCC_VERSION }}.tar.xz + tar xf binutils.tar.xz + tar xf gcc.tar.xz + cd gcc-${{ env.GCC_VERSION }} + contrib/download_prerequisites + + - name: Build binutils for Linux + if: ${{ steps._cache.outputs.cache-hit != 'true' }} + run: | + mkdir binutils_linux + cd binutils_linux + ../binutils-${{ env.BINUTILS_VERSION }}/configure --prefix=${{ github.workspace }}/gcc/linux --target=${{ env.GCC_TARGET }} --disable-docs --disable-nls --with-float=soft + make -j 2 + make install-strip + echo "${{ github.workspace }}/gcc/linux/bin" >>$GITHUB_PATH + + - name: Build GCC for Linux + if: ${{ steps._cache.outputs.cache-hit != 'true' }} + run: | + mkdir gcc_linux + cd gcc_linux + ../gcc-${{ env.GCC_VERSION }}/configure --prefix=${{ github.workspace }}/gcc/linux --target=${{ env.GCC_TARGET }} --disable-docs --disable-nls --disable-libada --disable-libssp --disable-libquadmath --disable-libstdc++-v3 --with-float=soft --enable-languages=c,c++ --with-gnu-as --with-gnu-ld + make -j 2 + make install-strip + + - name: Build binutils for Windows + if: ${{ steps._cache.outputs.cache-hit != 'true' }} + run: | + mkdir binutils_windows + cd binutils_windows + ../binutils-${{ env.BINUTILS_VERSION }}/configure --prefix=${{ github.workspace }}/gcc/windows --build=x86_64-linux-gnu --host=x86_64-w64-mingw32 --target=${{ env.GCC_TARGET }} --disable-docs --disable-nls --with-float=soft + make -j 2 + make install-strip + + - name: Build GCC for Windows + if: ${{ steps._cache.outputs.cache-hit != 'true' }} + run: | + mkdir gcc_windows + cd gcc_windows + ../gcc-${{ env.GCC_VERSION }}/configure --prefix=${{ github.workspace }}/gcc/windows --build=x86_64-linux-gnu --host=x86_64-w64-mingw32 --target=${{ env.GCC_TARGET }} --disable-docs --disable-nls --disable-libada --disable-libssp --disable-libquadmath --disable-libstdc++-v3 --with-float=soft --enable-languages=c,c++ --with-gnu-as --with-gnu-ld + make -j 2 + make install-strip + + # No surprises here either. The GitHub Actions VMs even come with most of the + # dependencies required to build PSn00bSDK preinstalled. + build-sdk-windows: + name: Build PSn00bSDK on Windows + runs-on: windows-latest + needs: build-gcc + + steps: + # Due to a bug in the cache action (and in order to use Ninja and pacman) + # the directories MSys2 stores binaries in must be added to PATH. For + # some reason they are not present in PATH by default. + # https://github.com/actions/cache/issues/576 + - name: Add MSys2 to PATH + run: | + echo "C:\msys64\mingw64\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + echo "C:\msys64\usr\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + + - name: Initialize toolchain cache + uses: actions/cache@v2 + with: + key: gcc-${{ env.GCC_TARGET }}-${{ env.GCC_VERSION }} + path: gcc + + - name: Install prerequisites + run: | + pacman -S --noconfirm mingw-w64-x86_64-ninja mingw-w64-x86_64-gcc + + - name: Fetch repo contents + uses: actions/checkout@v2 + with: + path: sdk + + - name: Update repo submodules + run: | + cd sdk + git submodule update --init --recursive --remote + + - name: Build and package PSn00bSDK + run: | + cmake --preset ci -S sdk -DPSN00BSDK_TC=${{ github.workspace }}\gcc\windows + cmake --build build + cmake --build build -t package + + - name: Upload build artifacts + uses: actions/upload-artifact@v2 + with: + name: psn00bsdk-windows + path: | + build/packages/* + !build/packages/_CPack_Packages + + build-sdk-linux: + name: Build PSn00bSDK on Linux + runs-on: ubuntu-latest + needs: build-gcc + + steps: + - name: Initialize toolchain cache + uses: actions/cache@v2 + with: + key: gcc-${{ env.GCC_TARGET }}-${{ env.GCC_VERSION }} + path: gcc + + - name: Install prerequisites + run: | + sudo apt-get update -y + sudo apt-get install -y --no-install-recommends ninja-build + + - name: Fetch repo contents + uses: actions/checkout@v2 + with: + path: sdk + + - name: Update repo submodules + run: | + cd sdk + git submodule update --init --recursive --remote + + - name: Build and package PSn00bSDK + run: | + cmake --preset ci -S sdk -DPSN00BSDK_TC=${{ github.workspace }}/gcc/linux + cmake --build build + cmake --build build -t package + + - name: Upload build artifacts + uses: actions/upload-artifact@v2 + with: + name: psn00bsdk-linux + path: | + build/packages/* + !build/packages/_CPack_Packages + + # This job takes care of creating a new release and upload the build + # artifacts if the last commit is associated to a tag. + create-release: + name: Create release + runs-on: ubuntu-latest + needs: [ build-sdk-windows, build-sdk-linux ] + + steps: + - name: Fetch repo contents + uses: actions/checkout@v2 + with: + path: sdk + + - name: Fetch build artifacts + if: ${{ github.ref_type == 'tag' }} + uses: actions/download-artifact@v2 + with: + path: . + + - name: Generate release notes + if: ${{ github.ref_type == 'tag' }} + run: | + sdk/.github/scripts/generate_release_notes.py -v ${{ github.ref_name }} -o release.md sdk/CHANGELOG.md + + - name: Publish release + if: ${{ github.ref_type == 'tag' }} + uses: softprops/action-gh-release@v1 + with: + fail_on_unmatched_files: true + body_path: release.md + files: | + psn00bsdk-windows/* + psn00bsdk-linux/* -- cgit v1.2.3 From 31fba94b8e8c15c1d127925f01a38efc68933fd1 Mon Sep 17 00:00:00 2001 From: spicyjpeg <88942473+spicyjpeg@users.noreply.github.com> Date: Mon, 29 Nov 2021 00:17:28 +0100 Subject: Add io/system573 example, rewrite dev notes, fix CI --- .github/workflows/build.yml | 27 ++- CHANGELOG.md | 14 +- README.md | 87 ++++---- doc/dev notes.txt | 250 ----------------------- doc/dev_notes.md | 280 ++++++++++++++++++++++++++ examples/io/system573/CMakeLists.txt | 27 +++ examples/io/system573/iso.xml | 34 ++++ examples/io/system573/main.c | 371 +++++++++++++++++++++++++++++++++++ 8 files changed, 785 insertions(+), 305 deletions(-) delete mode 100644 doc/dev notes.txt create mode 100644 doc/dev_notes.md create mode 100644 examples/io/system573/CMakeLists.txt create mode 100644 examples/io/system573/iso.xml create mode 100644 examples/io/system573/main.c (limited to '.github') diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d6746b0..8c16ac3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -181,22 +181,38 @@ jobs: needs: [ build-sdk-windows, build-sdk-linux ] steps: + - name: Initialize toolchain cache + if: ${{ github.ref_type == 'tag' }} + uses: actions/cache@v2 + with: + key: gcc-${{ env.GCC_TARGET }}-${{ env.GCC_VERSION }} + path: gcc + + - name: Package GCC toolchains + if: ${{ github.ref_type == 'tag' }} + run: | + cd gcc/windows + zip -9 -q -r ../../gcc-${{ env.GCC_TARGET }}-${{ env.GCC_VERSION }}-windows.zip . + cd ../linux + zip -9 -q -r ../../gcc-${{ env.GCC_TARGET }}-${{ env.GCC_VERSION }}-linux.zip . + - name: Fetch repo contents + if: ${{ github.ref_type == 'tag' }} uses: actions/checkout@v2 with: path: sdk + - name: Generate release notes + if: ${{ github.ref_type == 'tag' }} + run: | + python3 sdk/.github/scripts/generate_release_notes.py -v ${{ github.ref_name }} -o release.md sdk/CHANGELOG.md + - name: Fetch build artifacts if: ${{ github.ref_type == 'tag' }} uses: actions/download-artifact@v2 with: path: . - - name: Generate release notes - if: ${{ github.ref_type == 'tag' }} - run: | - sdk/.github/scripts/generate_release_notes.py -v ${{ github.ref_name }} -o release.md sdk/CHANGELOG.md - - name: Publish release if: ${{ github.ref_type == 'tag' }} uses: softprops/action-gh-release@v1 @@ -204,5 +220,6 @@ jobs: fail_on_unmatched_files: true body_path: release.md files: | + *.zip psn00bsdk-windows/* psn00bsdk-linux/* diff --git a/CHANGELOG.md b/CHANGELOG.md index c05105e..9463b83 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,7 +17,7 @@ contributing to PSn00bSDK, add a new block at the top following this template: You may run `.github/scripts/generate_release_notes.py CHANGELOG.md` afterwards to ensure the changelog can be parsed correctly. --------- +------------------------------------------------------------------------------- ## 2021-11-28: 0.18 @@ -25,13 +25,13 @@ spicyjpeg: - libc: Removed `STACK_MAX_SIZE` and added `_mem_init()` back. RAM and stack size can now be set by calling `_mem_init()` manually before allocating any - memory. + memory (however this seems to be currently broken). - libc: `sprintf()` now supports fixed padding when using the `%@` (binary integer) format specifier. -- psxcd: File paths with forward slashes instead of backslashes are now - accepted. +- psxcd: File paths with forward slashes instead of backslashes, as well as + paths containing both slash types, are now accepted. - psxapi: Added wrapper around BIOS function `GetSystemInfo()`. @@ -44,8 +44,10 @@ spicyjpeg: - Deprecated `malloc.h` and removed all references to it (`stdlib.h` should be used instead). Moved `int*_t` and `uint*_t` types to `stdint.h`. -- Fixed file permission errors when attempting to install the SDK on macOS and - made some small updates to `INSTALL.md`, which is now `doc/installation.md`. +- Fixed file permission errors when attempting to install the SDK on macOS. + +- Cleaned up, updated and moved all documentation to the `doc` folder. + Rewritten this changelog and added a script to generate release notes. ## 2021-10-31 diff --git a/README.md b/README.md index 6fd4cd1..13ab7d1 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ + # PSn00bSDK PSn00bSDK is a 100% free and open source SDK project for the original Sony @@ -5,33 +6,32 @@ PlayStation for developing homebrew applications and games for the console 100% freely. This SDK can be used for freeware, commercial, and open source homebrew projects. -The SDK is composed mainly of libraries (libpsn00b) and some utilities that -provide a basic framework for developing software for the PlayStation -hardware, the compiler is separate (GCC) and should be acquired from GNU. -The library API is intentionally written to resemble the library API of the -official libraries as closely as possible. This design decision is not only -for familiarity reasons to experienced programmers, but also so that existing -sample code and tutorials would still apply to this SDK, as well as making -the process of porting over existing homebrew originally made with official -SDKs easier with minimal modification, provided it doesn't use libgs. +The SDK is composed mainly of libraries (`libpsn00b`) and some utilities that +provide a basic framework for developing software for the PlayStation hardware, +the compiler is separate (GCC) and should be acquired from GNU. The library API +is intentionally written to resemble the library API of the official libraries +as closely as possible. This design decision is not only for familiarity +reasons to experienced programmers, but also so that existing sample code and +tutorials would still apply to this SDK, as well as making the process of +porting over existing homebrew originally made with official SDKs easier with +minimal modification, provided it doesn't use `libgs`. PSn00bSDK is currently a work in progress and cannot really be considered -production ready, but what is currently implemented should be enough to -produce some interesting homebrew with the SDK, especially with its extensive -support for the GPU and GTE hardware. There's no reason not to fully support -hardware features of a target platform when said hardware features have been -fully documented for years (nocash's PSX specs document in this case). +production ready, but what is currently implemented should be enough to produce +some interesting homebrew with the SDK, especially with its extensive support +for the GPU and GTE hardware. There's no reason not to fully support hardware +features of a target platform when said hardware features have been fully +documented for years (nocash's PSX specs document in this case). -Most of libpsn00b is written mostly in MIPS assembly, moreso functions that +Most of `libpsn00b` is written mostly in MIPS assembly, moreso functions that interface with the hardware. Many of the standard C functions are implemented in custom MIPS assembly instead of equivalents found in the BIOS ROM, for both -stability (the BIOS libc implementation of the PlayStation is actually buggy) +stability (the BIOS `libc` implementation of the PlayStation is actually buggy) and performance reasons. - ## Notable features -As of August 16, 2021 +As of November 28, 2021 * Extensive GPU support with polygon, line and sprite primitives, high-speed DMA transfers for VRAM data and ordering tables. All video modes for both @@ -76,28 +76,25 @@ As of August 16, 2021 * Fully expandable and customizable to your heart's content. - ## Obtaining PSn00bSDK PSn00bSDK has switched to a CMake-based build and installation system. See [installation.md](doc/installation.md) for details. -Because PSn00bSDK is updated semi-regularly due to this project being in -a work-in-progress state, it is better to obtain this SDK from source and -building it yourself in the long run. Pre-compiled packages for Debian and -Msys2 are being planned however (it is already possible to build installers, -DEB and RPM packages through CPack so it's only a matter of time). +Prebuilt SDK packages and versions of the GCC toolchain for Windows and Linux +(DEB/RPM) are available through GitHub Actions. Stable releases haven't yet +been published however, due to this project being in a work-in-progress state. +It is still recommended to build the SDK from source for the time being. ## Examples -There are a few examples and complete source code of n00bdemo included in -the examples directory. More example programs may be added in the future -and contributed example programs are welcome. - -There's also Lameguy's PlayStation Programming Tutorial Series at -http://lameguy64.net/tutorials/pstutorials/ for learning how to program -for the PlayStation. The tutorials should still apply to PSn00bSDK. +There are a few examples and complete source code of `n00bdemo` included in the +`examples` directory. More example programs may be added in the future and +contributed example programs are welcome. +There's also [Lameguy's PlayStation Programming Tutorial Series](http://lameguy64.net/tutorials/pstutorials) +for learning how to program for the PlayStation. The tutorials should still +apply to PSn00bSDK. ## To-do List @@ -121,33 +118,35 @@ for the PlayStation. The tutorials should still apply to PSn00bSDK. ## Usage terms (or lack thereof) -PSn00bSDK falls under the terms and conditions of the Mozilla Public -License. A quick summary of this license is that PSn00bSDK can be used -freely in both free and open source projects and commercial closed source -projects as projects using PSn00bSDK does not necessarily have to follow -the MPL as well. +PSn00bSDK falls under the terms and conditions of the Mozilla Public License. A +quick summary of this license is that PSn00bSDK can be used freely in both free +and open source projects and commercial closed source projects as projects +using PSn00bSDK does not necessarily have to follow the MPL as well. If modifications to the SDK were made as part of the development of such -projects that enhance its functionality, such changes must be contributed -back in return. +projects that enhance its functionality, such changes must be contributed back +in return. Homebrew made with PSn00bSDK may not be released under 'annoyingmous'. Although there's nothing that would enforce it, this term may as well be ignored despite it annoying this SDK's author. - ## Credits -Main developer: -* Lameguy64 +Main developers: + +* **Lameguy64** +* **spicyjpeg**: dynamic linker, CMake scripts, some docs and examples Honorable mentions: -* ijacquez - helpful suggestions for getting C++ working. -* NicolasNoble - his OpenBIOS project gave insight to how the BIOS works + +* **ijacquez**: helpful suggestions for getting C++ working. +* **Nicolas Noble**: his OpenBIOS project gave insight to how the BIOS works internally. Helpful contributors can be found in the changelog. References used: -* nocash's PlayStation specs document (http://problemkaputt.de/psx-spx.htm) + +* [nocash's PlayStation specs document](http://problemkaputt.de/psx-spx.htm) * Tails92's PSXSDK project (during PSn00bSDK's infancy). diff --git a/doc/dev notes.txt b/doc/dev notes.txt deleted file mode 100644 index 65a3976..0000000 --- a/doc/dev notes.txt +++ /dev/null @@ -1,250 +0,0 @@ -These are some development notes I've put together that would be of great -aid to those willing to contribute to the PSn00bSDK project. Many of these -came from my own experience dealing with the PS1 at low-level when I ran -into some unexplained quirks while some are from disassembly observations -and clarification of existing documents. More entries will be added when -I run into more previously undocumented quirks in the future. - - Lameguy64 - -* When calling C functions (ie. BIOS functions) from assembly code you'll -need to allocate N words on the stack first when calling a function that has -N arguments (addiu $sp, -(4*N) where N = number of arguments of the function -being called) even if the arguments are on registers a0 to a3 and the C -functions don't always use the space allotted in stack. When calling a -function with a variable number of arguments (printf) always allocate -16 bytes of stack. - -* Hooking a custom handler using BIOS function HookEntryInt (B(19h), known -as SetCustomExitFromException in nocash docs) is only triggered when there's -an IRQ that is not yet acknowledged by previous IRQ handlers built into the -kernel. This is also the best point to acknowledge any IRQs without breaking -compatibility with built-in BIOS IRQ handlers and is what the official SDK -uses to handle IRQs. To make sure this handler is triggered on every interrupt -you must call ChangeClearPad(0) and ChangeClearRCnt(3, 0) (which are functions -(B(5Bh)) and C(0Ah) respectively) otherwise the pad and root counter handlers -in the kernel will acknowledge the interrupt before your handler, preventing -you from handling them yourself. - -* It is not advisable to handle interrupts using event handlers like in -PSXSDK as it breaks BIOS features that depend on interrupts. Clearing the -VBlank IRQ in a event handler for example prevents the BIOS controller -functions from working as it depends on the VBlank IRQ to determine when to -query controllers. Acknowledge interrupts using a custom handler set by BIOS -function HookEntryInt (B(19h), known as SetCustomExitFromException in nocash -docs). - -* When running in high resolution mode you must additionally wait for bit 31 -in GPUSTAT (1F801814h) to alternate on every frame (frame 0: wait until 0, -frame 1: wait until 1, frame 2: wait until 0) before waiting for VSync -otherwise the GPU will only draw the first field if you don't have drawing -to displayed area enabled. Performing this check in a low resolution/non -interlaced mode is harmless. - -* There's a hardware bug in the GPU FillVRAM command GP0(02h) where if you -set the height to 512 pixels the primitive is processed with a height of 0 -as the hardware does not appear to interpret the last bit of the height -value. This is most apparent when putting a DRAWENV with the height of 512 -pixels (for PAL for example) and background clearing is enabled, hence why -DRAWENV.isbg is not effective in the official SDK. - -* In the official SDK, DMA IRQs appear to be enabled only when a callback -function is set (ie. DrawSyncCallback() enables IRQ for DMA channel 2). DMA -IRQs are only triggered on transfer completion. - -Additional notes by spicyjpeg: - -* The controller/memory card SPI interface is poorly implemented in most -emulators, making custom controller polling code insanely hard to write and -debug. The only emulator that comes close to real hardware is no$psx, which -seems to correctly implement all features of the SPI port (even those not used -by the BIOS pad driver, such as TX/RX interrupts). DuckStation only emulates -the bare minimum required by the BIOS and Sony libraries, and pcsx-redux has -major bugs that break most custom polling implementations. This pretty much -means TX/RX IRQs and many flags in the JOY_* registers should not be used -unless you are willing to break compatibility with emulators. - -* As if communicating with controllers wasn't difficult enough already, -DualShock pads also have a built-in watchdog timer that gets enabled when first -putting them in configuration mode (and is NOT disabled after exiting config -mode). If no polling commands are sent to the controller for about 1 second, -vibration motors are switched off and analog mode is disabled; the same happens -if the analog button is pressed while in analog mode. In order to always keep -the pad in analog mode you must: - - * Poll both controller ports at least once per frame by sending command 42h. - Polling at a higher rate might be desirable in some cases (such as rhythm - games) to increase timing accuracy. - * If a digital pad response (type = 4) is received from a port that hasn't - previously been flagged as digital-only, attempt to put the pad into config - mode using command 43h *twice* (as the proper response is delayed). - * If the pad doesn't recognize the config command, flag it as digital-only - and treat all further digital pad responses from it as valid. - * If the pad recognizes the command, it will reply by identifying as an - analog pad in config mode (type = 15). Send command 44h immediately - (without sending 42h first, otherwise the pad will exit config mode) to - enable analog mode and turn on the LED. - * Pressing the analog button will result in the controller identifying as - digital even though it is not flagged as such, thus re-triggering the - configuration process and putting it back into analog mode. - * All analog pad responses (type = 7) can be treated as valid, as they will - come from controllers that have already been configured. - * If no valid response is received, assume no controller is connected and - reset the port's digital-only flag. - -* The SDK provides no support yet for replacing the BIOS exception handler with -a custom one, however it can be done (if you are ok with losing all BIOS -controller, memory card and file functionality). In order not to break anything -your exception handler must do the following: - - * prevent GTE opcodes from being executed twice due to a hardware glitch (the - nocash docs explain how to do this); - * define _irq_func_table[12] as an *extern* array of function pointers, call - the appropriate entry when an IRQ occurs and clear the respective flag in - register 1F801070h; - * handle syscalls 01h-02h, i.e. EnterCriticalSection and ExitCriticalSection - properly. You should also handle syscall FF00h (invalid API usage), as well - as breaks 1800h and 1C00h (division errors injected by GCC), by locking up - and maybe showing a BSOD or similar; - * overwrite the default BIOS API vectors with a passthrough that checks no - controller- or interrupt-related function is being called. This is necessary - (although ugly) as libpsn00b often calls such functions internally. - -* For some reason mipsel-unknown-elf-nm and mipsel-none-elf-nm (symbol map -generators) insist on outputting 64-bit addresses (with the top 32 bits set, -e.g. FFFFFFFF80010000) even when feeding it a regular 32-bit MIPS executable, -while the standard x86 nm tool that ships with most GCC packages prints the -proper 32-bit address. Unclear whether this is a bug, intended behavior or the -result of some ancient ELF ABI flag crap. DL_ParseSymbolMap() will ignore the -top 32 bits, so this should only bother you if you're implementing your own -symbol map parser. - -* I haven't worked on psxspu but, for those willing to write some code, this is -the formula to calculate SPU pitch values for playing musical notes ("^" is the -power operator, not xor): - - frequency = (ref / 32) * (2 ^ ((note - 9) / 12)) - spu_pitch = frequency / 44100 * 4096 - - ref = frequency the sample should be played at to play a middle A (MIDI note 69) - note = MIDI note number (usually 0-127, 60 is middle C) - -* If you are overriding any of the memory allocation functions, DO NOT ENABLE -LINK-TIME OPTIMIZATION. GCC has a long-standing bug with LTO and weak functions -written in assembly, also LTO hasn't been tested at all yet. - -Obscure CMake issues and related stuff: - -* Toolchain files are loaded "early" according to the CMake docs. What this -means in practice is that a lot of commands, such as find_*(), won't work -properly in a toolchain script as they rely on variables initialized by the -project() command. The poorly documented solution to this is to move such -commands to a separate file and set CMAKE_PROJECT_INCLUDE to point to it, so -project() will execute it immediately after initialization. - -* After executing the toolchain file, CMake generates and attempts to build -several dummy projects to test the compiler. Each of these projects re-includes -the toolchain script (which is why you'll see commands executed multiple times) -and uses the same variable values as the main project, however CMake will *NOT* -pass custom variables through by default. If your toolchain script has options -that can be set via custom variables (like PSN00BSDK_TC and PSN00BSDK_PREFIX in -PSn00bSDK), you'll have to set CMAKE_TRY_COMPILE_PLATFORM_VARIABLES to a list -of variable names to be exported to generated dummy projects. - -* There is no way to use multiple toolchains (PS1 + host) in a single project, -even if you use add_subdirectory() to execute multiple project files (which, -confusingly, adds their targets to the parent project rather than treating them -as separate projects). Thankfully though CMake provides support for automating -the build process of independent CMake projects via the ExternalProject module. -Which brings me to the next issue... - -* If you run CPack on a "superbuild" project (i.e. a project that calls -ExternalProject_Add() to configure, compile and install subprojects at build -time), you'll likely run into a weird issue with CPack bundling folders from -your build directory into DEB and RPM packages. This is caused by the DEB/RPM -generators running "cmake --install" in a chroot/fakeroot to prepare the files -to be packaged, which seems to interfere with absolute paths in the project -cache or something like that (?). The only workaround I know of is to use -CPACK_PRE_BUILD_SCRIPTS to trigger a custom script that deletes anything other -than the actual files to be packaged (see cpack/fakeroot_fix.cmake). - -* Project installation might fail on macOS (and possibly some Linux distros) if -CMake attempts to set permissions on system directories such as /usr/local. -This is usually caused by install() commands that copy files to the root -installation directory rather than to a subfolder, like this: - - install( - DIRECTORY install_tree/ - DESTINATION . - USE_SOURCE_PERMISSIONS - ) - -If the USE_SOURCE_PERMISSIONS flag is specified CMake will attempt to set -permissions on the DESTINATION folder, which in this case would be the root -prefix (/usr/local by default on macOS), to match the source directory. This -will however fail as macOS restricts top-level system directories from having -their permissions changed. The simplest workaround is to avoid using -"DESTINATION ." and install each subdirectory explicitly instead, like this: - - foreach( - _dir IN ITEMS - ${CMAKE_INSTALL_BINDIR} - ${CMAKE_INSTALL_LIBDIR} - ${CMAKE_INSTALL_INCLUDEDIR} - ${CMAKE_INSTALL_DATADIR} - ) - install( - DIRECTORY install_tree/${_dir}/ - DESTINATION ${_dir} - USE_SOURCE_PERMISSIONS - ) - endforeach() - -* Depending on how you find external dependencies (find_package(), vcpkg, -pkg-config...), CMake may end up outputting an executable that relies on a DLL -installed system-wide. To correctly install the DLL alongside the executable -you have to specify a regex as follows: - - install( - TARGETS my_executable - RUNTIME_DEPENDENCIES - PRE_EXCLUDE_REGEXES ".*" - PRE_INCLUDE_REGEXES "tinyxml2" - ) - -CMake will scan the executable at install time and copy all the required DLLs -that match the second regex. If no regex is specified CMake will also copy OS -DLLs like libc or msvcrt, which usually isn't the desired behavior. - -* Using interface targets to set include directories can be finicky. Not only -do you have to use generator expressions to conditionally use different paths -depending on whether the targets are installed, but CMake can get confused on -which options to pass to the compiler. I spent hours trying to get CMake to use --I rather than -isystem for include directories (for some reason GCC would -ignore -isystem completely). I eventually gave up and just set the include -directories manually for each target, and for some reason CMake actually -started passing -I instead of -isystem to GCC. - -* When using CPack with NSIS, all CPACK_NSIS_* variables are passed to NSIS -verbatim, i.e. without the usual slash-to-backslash path conversion that CMake -does on Windows. Most Windows programs accept paths with slashes without issue, -unfortunately the NSIS builder is not one of those. To add insult to injury, -CMake doesn't even escape backslashes by default when quoting strings in the -generated CPack config file! So you have to convert the paths manually *and* -tell CMake to enable escaping by setting CPACK_VERBATIM_VARIABLES, like this: - - set(CPACK_VERBATIM_VARIABLES ON) - foreach( - _var IN ITEMS - CPACK_NSIS_MUI_ICON - CPACK_NSIS_MUI_UNIICON - CPACK_NSIS_MUI_HEADERIMAGE - CPACK_NSIS_MUI_WELCOMEFINISHPAGE_BITMAP - CPACK_NSIS_MUI_UNWELCOMEFINISHPAGE_BITMAP - ) - cmake_path(NATIVE_PATH ${_var} ${_var}) - endforeach() - -* Not a CMake/CPack bug per se, but NSIS is picky about the banner and header -images shown in generated installers. They must be Windows BMP version 3 files -with no alpha channel, no compression and no metadata. They can either be -24-bit RGB or indexed, though it's common to use indexed colors to save space. diff --git a/doc/dev_notes.md b/doc/dev_notes.md new file mode 100644 index 0000000..3aa2304 --- /dev/null +++ b/doc/dev_notes.md @@ -0,0 +1,280 @@ + +# Development notes + +These are some development notes I've put together that would be of great aid +to those willing to contribute to the PSn00bSDK project. Many of these came +from my own experience dealing with the PS1 at low-level when I ran into some +unexplained quirks while some are from disassembly observations and +clarification of existing documents. More entries will be added when I run into +more previously undocumented quirks in the future. _- Lameguy64_ + +Porting PSn00bSDK to CMake also uncovered a lot of bugs and undocumented +behavior in CMake itself. I documented [below](#cmake) all issues I ran into. +_- spicyjpeg_ + +## MIPS ABI / compiler + +- When calling C functions (ie. BIOS functions) from assembly code you'll need + to allocate N words on the stack first when calling a function that has N + arguments (`addiu $sp, -(4*N)` where N = number of arguments of the function + being called) even if the arguments are on registers `a0` to `a3` and the C + functions don't always use the space allotted in stack. When calling a + function with a variable number of arguments (`printf`) always allocate 16 + bytes of stack. + +- For some reason `mipsel-unknown-elf-nm` and `mipsel-none-elf-nm` (symbol map + generators) insist on outputting 64-bit addresses (with the top 32 bits set, + e.g. `FFFFFFFF80010000`) even when feeding it a regular 32-bit MIPS + executable, while the standard x86 nm tool that ships with most GCC packages + prints the proper 32-bit address. Unclear whether this is a bug, intended + behavior or the result of some ancient ELF ABI flag crap. + `DL_ParseSymbolMap()` will ignore the top 32 bits, so this should only bother + you if you're implementing your own symbol map parser. + +- If you are overriding any of the memory allocation functions, + **DO NOT ENABLE LINK-TIME OPTIMIZATION**. GCC has a long-standing bug with + LTO and weak functions written in assembly, also LTO hasn't been tested at + all yet. + +## BIOS and interrupts + +- Hooking a custom handler using BIOS function `HookEntryInt` (`B(19h)`, known + as `SetCustomExitFromException` in nocash docs) is only triggered when + there's an IRQ that is not yet acknowledged by previous IRQ handlers built + into the kernel. This is also the best point to acknowledge any IRQs without + breaking compatibility with built-in BIOS IRQ handlers and is what the + official SDK uses to handle IRQs. To make sure this handler is triggered on + every interrupt you must call `ChangeClearPad(0)` and `ChangeClearRCnt(3, 0)` + (which are functions `B(5Bh)` and `C(0Ah)` respectively) otherwise the pad + and root counter handlers in the kernel will acknowledge the interrupt before + your handler, preventing you from handling them yourself. + +- It is not advisable to handle interrupts using event handlers like in PSXSDK + as it breaks BIOS features that depend on interrupts. Clearing the VBlank IRQ + in a event handler for example prevents the BIOS controller functions from + working as it depends on the VBlank IRQ to determine when to query + controllers. Acknowledge interrupts using a custom handler set by BIOS + function `HookEntryInt` (`B(19h)`, known as `SetCustomExitFromException` in + nocash docs). + +- In the official SDK, DMA IRQs appear to be enabled only when a callback + function is set (ie. `DrawSyncCallback()` enables IRQ for DMA channel 2). DMA + IRQs are only triggered on transfer completion. + +- PSn00bSDK provides no support yet for replacing the BIOS exception handler + with a custom one, however it can be done (if you are ok with losing all BIOS + controller, memory card and file functionality). In order not to break + anything your exception handler must do the following: + + - prevent GTE opcodes from being executed twice due to a hardware glitch (the + nocash docs explain how to do this); + - define `_irq_func_table[12]` as an *extern* array of function pointers, + call the appropriate entry when an IRQ occurs and clear the respective flag + in register `1F801070h`; + - handle syscalls `01h`-`02h`, i.e. `EnterCriticalSection` and + `ExitCriticalSection`, properly. You should also handle syscall `FF00h` + (invalid API usage), as well as breaks `1800h` and `1C00h` (division errors + injected by GCC), by locking up and maybe showing a BSOD or similar; + - overwrite the default BIOS API vectors with a passthrough that checks no + controller- or interrupt-related function is being called. This is necessary + (although ugly) as `libpsn00b` often calls such functions internally. + +## Hardware + +- When running in high resolution mode you must additionally wait for bit 31 in + `GPUSTAT` (`1F801814h`) to alternate on every frame (frame 0: wait until 0, + frame 1: wait until 1, frame 2: wait until 0) before waiting for VSync + otherwise the GPU will only draw the first field if you don't have drawing to + displayed area enabled. Performing this check in a low resolution/non + interlaced mode is harmless. + +- There's a hardware bug in the GPU `FillVRAM` command `GP0(02h)` where if you + set the height to 512 pixels the primitive is processed with a height of 0 as + the hardware does not appear to interpret the last bit of the height value. + This is most apparent when putting a DRAWENV with the height of 512 pixels + (for PAL for example) and background clearing is enabled, hence why + `DRAWENV.isbg` is not effective in the official SDK. + +- The controller/memory card SPI interface is poorly implemented in most + emulators, making custom controller polling code insanely hard to write and + debug. The only emulator that comes close to real hardware is no$psx, which + seems to correctly implement all features of the SPI port (even those not + used by the BIOS pad driver, such as TX/RX interrupts). DuckStation only + emulates the bare minimum required by the BIOS and Sony libraries, and + pcsx-redux has major bugs that break most custom polling implementations. + This pretty much means TX/RX IRQs and many flags in the `JOY_*` registers + should **not** be used unless you are willing to break compatibility with + emulators. + +- As if communicating with controllers wasn't difficult enough already, + DualShock pads also have a built-in watchdog timer that gets enabled when + first putting them in configuration mode (and is **not** disabled after + exiting config mode). If no polling commands are sent to the controller for + about 1 second, vibration motors are switched off and analog mode is + disabled; the same happens if the analog button is pressed while in analog + mode. In order to always keep the pad in analog mode you must: + + 1. Poll both controller ports at least once per frame by sending command + `42h`. Polling at a higher rate might be desirable in some cases (such as + rhythm games) to increase timing accuracy. + 2. If a digital pad response (type = 4) is received from a port that hasn't + previously been flagged as digital-only, attempt to put the pad into + config mode using command `43h` *twice* (as the proper response is + delayed). + - If the pad doesn't recognize the config command, flag it as digital-only + and treat all further digital pad responses from it as valid. + - If the pad recognizes the command, it will reply by identifying as an + analog pad in config mode (type = 15). Send command `44h` immediately + (without sending `42h` first, otherwise the pad will exit config mode) + to enable analog mode and turn on the LED. + - Pressing the analog button will result in the controller identifying as + digital even though it is not flagged as such, thus re-triggering the + configuration process and putting it back into analog mode. + 3. All analog pad responses (type = 7) can be treated as valid, as they will + come from controllers that have already been configured. + 4. If no valid response is received, assume no controller is connected and + reset the port's digital-only flag. + +- I haven't worked on `psxspu` but, for those willing to write some code, this + is the formula to calculate SPU pitch values for playing musical notes (`^` + is the power operator, not xor): + + ``` + frequency = (ref / 32) * (2 ^ ((note - 9) / 12)) + spu_pitch = frequency / 44100 * 4096 + + ref = frequency the sample should be played at to play a middle A (MIDI note 69) + note = MIDI note number (usually 0-127, 60 is middle C) + ``` + +## CMake + +- Toolchain files are loaded "early" according to the CMake docs. What this + means in practice is that a lot of commands, such as `find_*()`, won't work + properly in a toolchain script as they rely on variables initialized by the + `project()` command. The poorly documented solution to this is to move such + commands to a separate file and set `CMAKE_PROJECT_INCLUDE` to point to it, + so `project()` will execute it immediately after initialization. + +- After executing the toolchain file, CMake generates and attempts to build + several dummy projects to test the compiler. Each of these projects + re-includes the toolchain script (which is why you'll see commands executed + multiple times) and uses the same variable values as the main project, + however CMake will *not* pass custom variables through by default. If your + toolchain script has options that can be set via custom variables (like + `PSN00BSDK_TC` and `PSN00BSDK_PREFIX` in PSn00bSDK), you'll have to set + `CMAKE_TRY_COMPILE_PLATFORM_VARIABLES` to a list of variable names to be + exported to generated dummy projects. + +- There is no way to use multiple toolchains (PS1 + host) in a single project, + even if you use `add_subdirectory()` to execute multiple project files + (which, confusingly, adds their targets to the parent project rather than + treating them as separate projects). Thankfully though CMake provides support + for automating the build process of independent CMake projects via the + `ExternalProject` module. Which brings me to the next issue... + +- If you run CPack on a "superbuild" project (i.e. a project that calls + `ExternalProject_Add()` to configure, compile and install subprojects at + build time), you'll likely run into a weird issue with CPack bundling folders + from your build directory into DEB and RPM packages. This is caused by the + DEB/RPM generators running `cmake --install` in a chroot/fakeroot to prepare + the files to be packaged, which seems to interfere with absolute paths in the + project cache or something like that (?). The only workaround I know of is to + use `CPACK_PRE_BUILD_SCRIPTS` to trigger a custom script that deletes + anything other than the actual files to be packaged (see + `cpack/fakeroot_fix.cmake`). + +- Project installation might fail on macOS (and possibly some Linux distros) if + CMake attempts to set permissions on system directories such as `/usr/local`. + This is usually caused by `install()` commands that copy files to the root + installation directory rather than to a subfolder, like this: + + ```cmake + install( + DIRECTORY install_tree/ + DESTINATION . + USE_SOURCE_PERMISSIONS + ) + ``` + + If the `USE_SOURCE_PERMISSIONS` flag is specified CMake will attempt to set + permissions on the `DESTINATION` folder, which in this case would be the root + prefix (`/usr/local` by default on macOS), to match the source directory. + This will however fail as macOS restricts top-level system directories from + having their permissions changed. The simplest workaround is to avoid using + `DESTINATION .` and install each subdirectory explicitly instead, like this: + + ```cmake + foreach( + _dir IN ITEMS + ${CMAKE_INSTALL_BINDIR} + ${CMAKE_INSTALL_LIBDIR} + ${CMAKE_INSTALL_INCLUDEDIR} + ${CMAKE_INSTALL_DATADIR} + ) + install( + DIRECTORY install_tree/${_dir}/ + DESTINATION ${_dir} + USE_SOURCE_PERMISSIONS + ) + endforeach() + ``` + +- Depending on how you find external dependencies (`find_package()`, vcpkg, + pkg-config...), CMake may end up outputting an executable that relies on a + DLL installed system-wide. To correctly install the DLL alongside the + executable you have to specify a regex as follows: + + ```cmake + install( + TARGETS my_executable + RUNTIME_DEPENDENCIES + PRE_EXCLUDE_REGEXES ".*" + PRE_INCLUDE_REGEXES "tinyxml2" + ) + ``` + + CMake will scan the executable at install time and copy all the required DLLs + that match the second regex. If no regex is specified CMake will also copy OS + DLLs like `libc` or `msvcrt`, which usually isn't the desired behavior. + +- Using interface targets to set include directories can be finicky. Not only + do you have to use generator expressions to conditionally use different paths + depending on whether the targets are installed, but CMake can get confused on + which options to pass to the compiler. I spent hours trying to get CMake to + use `-I` rather than `-isystem` for include directories (for some reason GCC + would ignore `-isystem` completely). I eventually gave up and just set the + include directories manually for each target, and for some reason CMake + actually started passing `-I` instead of `-isystem` to GCC. + +- When using CPack with NSIS, all `CPACK_NSIS_*` variables are passed to NSIS + verbatim, i.e. without the usual slash-to-backslash path conversion that + CMake does on Windows. Most Windows programs accept paths with slashes + without issue, unfortunately the NSIS builder is not one of those. To add + insult to injury, CMake doesn't even escape backslashes by default when + quoting strings in the generated CPack config file! So you have to convert + the paths manually *and* tell CMake to enable escaping by setting + `CPACK_VERBATIM_VARIABLES`, like this: + + ```cmake + set(CPACK_VERBATIM_VARIABLES ON) + foreach( + _var IN ITEMS + CPACK_NSIS_MUI_ICON + CPACK_NSIS_MUI_UNIICON + CPACK_NSIS_MUI_HEADERIMAGE + CPACK_NSIS_MUI_WELCOMEFINISHPAGE_BITMAP + CPACK_NSIS_MUI_UNWELCOMEFINISHPAGE_BITMAP + ) + cmake_path(NATIVE_PATH ${_var} ${_var}) + endforeach() + ``` + +- Not a CMake/CPack bug per se, but NSIS is picky about the banner and header + images shown in generated installers. They must be Windows BMP version 3 + files with no alpha channel, no compression and no metadata. They can either + be 24-bit RGB or indexed, though it's common to use indexed colors to save + space. + +----------------------------------------- +_Last updated on 2021-11-28 by spicyjpeg_ diff --git a/examples/io/system573/CMakeLists.txt b/examples/io/system573/CMakeLists.txt new file mode 100644 index 0000000..34c9153 --- /dev/null +++ b/examples/io/system573/CMakeLists.txt @@ -0,0 +1,27 @@ +# PSn00bSDK example CMake script +# (C) 2021 spicyjpeg - MPL licensed + +cmake_minimum_required(VERSION 3.21) + +if(NOT DEFINED CMAKE_TOOLCHAIN_FILE AND DEFINED ENV{PSN00BSDK_LIBS}) + set(CMAKE_TOOLCHAIN_FILE $ENV{PSN00BSDK_LIBS}/cmake/sdk.cmake) +endif() + +project( + system573 + LANGUAGES C ASM + VERSION 1.0.0 + DESCRIPTION "PSn00bSDK Konami System 573 example" + HOMEPAGE_URL "http://lameguy64.net/?page=psn00bsdk" +) + +file(GLOB _sources *.c *.s) +psn00bsdk_add_executable(system573 STATIC ${_sources}) +psn00bsdk_add_cd_image(system573_iso system573 iso.xml DEPENDS system573) + +install( + FILES + ${PROJECT_BINARY_DIR}/system573.bin + ${PROJECT_BINARY_DIR}/system573.cue + TYPE BIN +) diff --git a/examples/io/system573/iso.xml b/examples/io/system573/iso.xml new file mode 100644 index 0000000..09b4d85 --- /dev/null +++ b/examples/io/system573/iso.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + diff --git a/examples/io/system573/main.c b/examples/io/system573/main.c new file mode 100644 index 0000000..67a98da --- /dev/null +++ b/examples/io/system573/main.c @@ -0,0 +1,371 @@ +/* + * PSn00bSDK Konami System 573 example + * (C) 2021 spicyjpeg - MPL licensed + * + * This is a minimal example demonstrating how to target the Konami System 573 + * using PSn00bSDK. The System 573 is a PS1-based arcade motherboard that + * powered various Konami arcade games throughout the late 1990s, most notably + * Dance Dance Revolution and other Bemani rhythm games. It came in several + * configurations, with slightly different I/O connectors depending on the game + * and two optional add-on modules (known as the "analog I/O" and "digital I/O" + * boards respectively) providing light control outputs and, in the case of the + * digital I/O board, MP3 audio playback. + * + * Unlike other arcade systems based on PS1 hardware, the 573 is mostly + * identical to a regular PS1, with almost all custom extensions mapped into + * the expansion port region at 0x1f000000. The major differences are: + * + * - RAM is 4 MB instead of 2, and VRAM is 2 MB instead of 1. It is recommended + * *not* to use the additional memory to preserve PS1 compatibility. + * + * - The CD drive is replaced by a standard IDE/ATAPI drive (which most of the + * time is going to be an aftermarket DVD drive, as the original drives the + * system shipped with were prone to failure and couldn't read CD-Rs). This + * also means the 573 has no support at all for XA audio playback, as XA is + * not part of the CD-ROM specification implemented by IDE drives. CD audio + * is supported by most IDE drives, but 573 units with the digital I/O board + * installed have the 4-pin audio cable plugged into that instead of the + * drive. The IDE bus is connected to IRQ10 and DMA5 (expansion port) instead + * of IRQ2 and DMA3, which go unused. + * + * - The BIOS seems to have most file I/O APIs removed and exposes no functions + * whatsoever for accessing the IDE drive or the filesystem on the disc. The + * launcher/shell is completely different from Sony's shell and is capable of + * loading an executable from the CD drive, a PCMCIA memory-mapped flash card + * or the internal 16 MB flash memory. + * + * - The SPI controller bus seems to be left unconnected. Inputs are routed to + * a JAMMA PCB edge connector and handled through two custom/relabeled chips, + * which expose the inputs as memory-mapped registers. There is also a JVS + * port (i.e. RS-485 serial bus wired to a USB-A connector, commonly used for + * daisy-chaining peripherals in arcade cabinets) managed by a + * microcontroller. + * + * - There is a "security cartridge" slot, which breaks out the serial port as + * well as several GPIO pins. All security cartridge communication and DRM is + * handled by games rather than by the BIOS, so a security cartridge is *not* + * required to boot homebrew. Each game came with a different cartridge type; + * many of them expose the serial port or provide additional game-specific + * I/O connectors. + * + * Currently the only publicly available documentation for the custom registers + * is the System 573 MAME driver. Also keep in mind that the psxcd library does + * not yet support IDE drives, so the 573's drive can only be accessed by + * writing a custom ATAPI driver and ISO9660 parser (which is out of the scope + * of this example). + * + * https://github.com/mamedev/mame/blob/master/src/mame/drivers/ksys573.cpp + * https://github.com/mamedev/mame/blob/master/src/mame/machine/k573dio.cpp + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Register definitions */ + +#define EXP1_ADDR *((volatile uint32_t *) 0x1f801000) +#define EXP1_CTRL *((volatile uint32_t *) 0x1f801008) + +#define K573_IN0 *((volatile uint16_t *) 0x1f400000) +#define K573_IN1_L *((volatile uint16_t *) 0x1f400004) +#define K573_IN1_H *((volatile uint16_t *) 0x1f400006) +#define K573_IN2 *((volatile uint16_t *) 0x1f400008) +#define K573_IN3_L *((volatile uint16_t *) 0x1f40000c) +#define K573_IN3_H *((volatile uint16_t *) 0x1f40000e) +#define K573_BANK *((volatile uint16_t *) 0x1f500000) +#define K573_WATCHDOG *((volatile uint16_t *) 0x1f5c0000) + +#define K573_IDE_CS0 ((volatile uint16_t *) 0x1f480000) +#define K573_IDE_CS1 ((volatile uint16_t *) 0x1f4c0000) +#define K573_RTC ((volatile uint16_t *) 0x1f620000) +#define K573_IO_BOARD ((volatile uint16_t *) 0x1f640000) + +typedef enum { + ANALOG_IO_LIGHTS0 = 0x20, + ANALOG_IO_LIGHTS1 = 0x22, + ANALOG_IO_LIGHTS2 = 0x24, + ANALOG_IO_LIGHTS3 = 0x26, + + // The digital I/O board has a lot more registers than these, but there + // seems to be no DIGITAL_IO_LIGHTS6 register. WTF + DIGITAL_IO_LIGHTS1 = 0x70, + DIGITAL_IO_LIGHTS0 = 0x71, + DIGITAL_IO_LIGHTS3 = 0x72, + DIGITAL_IO_LIGHTS7 = 0x73, + DIGITAL_IO_LIGHTS4 = 0x7d, + DIGITAL_IO_LIGHTS5 = 0x7e, + DIGITAL_IO_LIGHTS2 = 0x7f +} IO_BOARD_REG; + +// The 573's real-time clock chip is an M48T58, which behaves like a standard +// 8 KB battery-backed SRAM with a bunch of special registers. Official games +// store highscores and settings in RTC RAM. +typedef enum { + RTC_CTRL = 0x1ff8, + RTC_SECONDS = 0x1ff9, + RTC_MINUTES = 0x1ffa, + RTC_HOURS = 0x1ffb, + RTC_DAY_OF_WEEK = 0x1ffc, + RTC_DAY_OF_MONTH = 0x1ffd, + RTC_MONTH = 0x1ffe, + RTC_YEAR = 0x1fff +} RTC_REG; + +#define btoi(x) ((((x) >> 4) & 0xf) * 10 + ((x) & 0xf)) + +/* Display/GPU context utilities */ + +#define SCREEN_XRES 320 +#define SCREEN_YRES 240 + +#define BGCOLOR_R 48 +#define BGCOLOR_G 24 +#define BGCOLOR_B 0 + +typedef struct { + DISPENV disp; + DRAWENV draw; +} DB; + +typedef struct { + DB db[2]; + uint32_t db_active; +} CONTEXT; + +void init_context(CONTEXT *ctx) { + DB *db; + + ResetGraph(0); + ctx->db_active = 0; + + db = &(ctx->db[0]); + SetDefDispEnv(&(db->disp), 0, 0, SCREEN_XRES, SCREEN_YRES); + SetDefDrawEnv(&(db->draw), SCREEN_XRES, 0, SCREEN_XRES, SCREEN_YRES); + setRGB0(&(db->draw), BGCOLOR_R, BGCOLOR_G, BGCOLOR_B); + db->draw.isbg = 1; + db->draw.dtd = 1; + + db = &(ctx->db[1]); + SetDefDispEnv(&(db->disp), SCREEN_XRES, 0, SCREEN_XRES, SCREEN_YRES); + SetDefDrawEnv(&(db->draw), 0, 0, SCREEN_XRES, SCREEN_YRES); + setRGB0(&(db->draw), BGCOLOR_R, BGCOLOR_G, BGCOLOR_B); + db->draw.isbg = 1; + db->draw.dtd = 1; + + PutDrawEnv(&(db->draw)); + //PutDispEnv(&(db->disp)); + + // Create a text stream at the top of the screen. + FntLoad(960, 0); + FntOpen(8, 16, 304, 208, 2, 512); +} + +void display(CONTEXT *ctx) { + DB *db; + + DrawSync(0); + VSync(0); + ctx->db_active ^= 1; + + db = &(ctx->db[ctx->db_active]); + PutDrawEnv(&(db->draw)); + PutDispEnv(&(db->disp)); + SetDispMask(1); +} + +/* Input polling utilities */ + +typedef struct { + uint8_t p1_joy, p1_btn; + uint8_t p2_joy, p2_btn; + uint8_t coin, dip_sw; +} JAMMA_INPUTS; + +void get_jamma_inputs(JAMMA_INPUTS *output) { + uint16_t in1l = K573_IN1_L; + uint16_t in1h = K573_IN1_H; + uint16_t in2 = K573_IN2; + uint16_t in3l = K573_IN3_L; + uint16_t in3h = K573_IN3_H; + uint8_t p1_btn, p2_btn, coin; + + // Rearrange the bits read from the input register into something that's + // easier to parse and display. Refer to MAME for information on what each + // bit in the IN* registers does. + p1_btn = ((in2 >> 15) & 0x0001); // Bit 0 = start button + p1_btn |= ((in2 >> 8) & 0x0007) << 1; // Bit 1-3 = buttons 1-3 + p1_btn |= ((in3l >> 8) & 0x0003) << 4; // Bit 4-5 = buttons 4-5 + p1_btn |= ((in3l >> 11) & 0x0001) << 6; // Bit 6 = button 6 + p2_btn = ((in2 >> 7) & 0x0001); // Bit 0 = start button + p2_btn |= ((in2 >> 4) & 0x0007) << 1; // Bit 1-3 = buttons 1-3 + p2_btn |= ((in3h >> 8) & 0x0003) << 4; // Bit 4-5 = buttons 4-5 + p2_btn |= ((in3h >> 11) & 0x0001) << 6; // Bit 6 = button 6 + coin = ((in1h >> 8) & 0x0003); // Bit 0-1 = coin switches + coin |= ((in1h >> 12) & 0x0001) << 2; // Bit 2 = service button + coin |= ((in3l >> 10) & 0x0001) << 3; // Bit 3 = test button + coin |= ((in1h >> 10) & 0x0003) << 4; // Bit 4-5 = PCMCIA cards + + output->p1_joy = (in2 >> 8) & 0x000f; + output->p1_btn = p1_btn; + output->p2_joy = in2 & 0x000f; + output->p2_btn = p2_btn; + output->coin = coin; + output->dip_sw = in1l & 0x000f; +} + +/* I/O board (light control) utilities */ + +// This function controls light outputs on analog I/O boards. +void set_lights_analog(uint32_t lights) { + uint32_t bits; + + bits = (lights & 0x01010101) << 7; // Lamp 0 -> bit 7 + bits |= (lights & 0x02020202) << 5; // Lamp 1 -> bit 6 + bits |= (lights & 0x04040404) >> 1; // Lamp 2 -> bit 1 + bits |= (lights & 0x08080808) >> 3; // Lamp 3 -> bit 0 + bits |= (lights & 0x10101010) << 1; // Lamp 4 -> bit 5 + bits |= (lights & 0x20202020) >> 1; // Lamp 5 -> bit 4 + bits |= (lights & 0x40404040) >> 3; // Lamp 6 -> bit 3 + bits |= (lights & 0x80808080) >> 5; // Lamp 7 -> bit 2 + + K573_IO_BOARD[ANALOG_IO_LIGHTS0] = (bits) & 0xff; + K573_IO_BOARD[ANALOG_IO_LIGHTS1] = (bits >> 8) & 0xff; + K573_IO_BOARD[ANALOG_IO_LIGHTS2] = (bits >> 16) & 0xff; + K573_IO_BOARD[ANALOG_IO_LIGHTS3] = (bits >> 24) & 0xff; +} + +// This function controls light outputs on digital I/O boards (i.e. the ones +// that include MP3 playback hardware in addition to the light control). +// TODO: test this on real hardware -- it might not work if lights are handled +// by the board's FPGA, which requires a binary blob... +void set_lights_digital(uint32_t lights) { + uint32_t bits; + + bits = (lights & 0x11111111); // Lamp 0 -> bit 0 + bits |= (lights & 0x22222222) << 1; // Lamp 1 -> bit 2 + bits |= (lights & 0x44444444) << 1; // Lamp 2 -> bit 3 + bits |= (lights & 0x88888888) >> 2; // Lamp 3 -> bit 1 + + K573_IO_BOARD[DIGITAL_IO_LIGHTS0] = ((bits) & 0xf) << 12; + K573_IO_BOARD[DIGITAL_IO_LIGHTS1] = ((bits >> 4) & 0xf) << 12; + K573_IO_BOARD[DIGITAL_IO_LIGHTS2] = ((bits >> 8) & 0xf) << 12; + K573_IO_BOARD[DIGITAL_IO_LIGHTS3] = ((bits >> 12) & 0xf) << 12; + K573_IO_BOARD[DIGITAL_IO_LIGHTS4] = ((bits >> 16) & 0xf) << 12; + K573_IO_BOARD[DIGITAL_IO_LIGHTS5] = ((bits >> 20) & 0xf) << 12; + //K573_IO_BOARD[DIGITAL_IO_LIGHTS6] = ((bits >> 24) & 0xf) << 12; + K573_IO_BOARD[DIGITAL_IO_LIGHTS7] = ((bits >> 28) & 0xf) << 12; +} + +/* Main */ + +static CONTEXT ctx; + +#define SHOW_STATUS(...) { FntPrint(-1, __VA_ARGS__); FntFlush(-1); display(&ctx); } +#define SHOW_ERROR(...) { SHOW_STATUS(__VA_ARGS__); while (1) __asm__("nop"); } + +int main(int argc, const char* argv[]) { + // Reinitialize the heap and relocate the stack to allow the 573's full 4 + // MB of RAM to be used. This isn't strictly required; executables designed + // for 2 MB of RAM will also run fine on the 573 (obviously). + // FIXME: this seems to be broken currently + //__asm__ volatile("li $sp, 0x803fffe0"); + //_mem_init(0x400000, 0x20000); + + EXP1_ADDR = 0x1f000000; + EXP1_CTRL = 0x24173f47; // 573 BIOS uses this value + K573_WATCHDOG = 0; + + init_context(&ctx); + + // Determine whether we are running on a 573 by fetching the version string + // from the BIOS. + const char *const version = (const char *const) GetSystemInfo(0x02); + //if (strncmp(version, "Konami OS", 9)) + //SHOW_ERROR("ERROR: NOT RUNNING ON A SYSTEM 573!\n\n[%s]\n", version); + + uint32_t counter = 0; + uint8_t last_joystick = 0xff; + uint8_t last_buttons = 0xff; + uint32_t current_light = 0; + uint32_t is_digital = 0; + + while (1) { + FntPrint(-1, "COUNTER=%d\n", counter++); + + JAMMA_INPUTS inputs; + get_jamma_inputs(&inputs); + + FntPrint(-1, "\nJAMMA INPUTS:\n"); + FntPrint(-1, " P1 JOYSTICK =%04@\n", inputs.p1_joy); + FntPrint(-1, " P1 BUTTONS =%07@\n", inputs.p1_btn); + FntPrint(-1, " P2 JOYSTICK =%04@\n", inputs.p2_joy); + FntPrint(-1, " P2 BUTTONS =%07@\n", inputs.p2_btn); + FntPrint(-1, " COIN/SERVICE=%04@\n", inputs.coin); + FntPrint(-1, " DIP SWITCHES=%04@\n", inputs.dip_sw); + + FntPrint(-1, "\nCABINET LIGHTS:\n"); + FntPrint(-1, " BOARD=%s I/O\n", is_digital ? "DIGITAL" : "ANALOG"); + FntPrint(-1, " LIGHT=%d\n\n", current_light); + FntPrint(-1, " [START] CHANGE BOARD TYPE\n"); + FntPrint(-1, " [LEFT/RIGHT] SELECT LIGHT TO TEST\n"); + + // Request the current date/time from the RTC and display it. + K573_RTC[RTC_CTRL] |= 0x40; + FntPrint(-1, "\nRTC:\n"); + FntPrint( + -1, + " %02d-%02d-%02d %02d:%02d:%02d\n", + btoi(K573_RTC[RTC_YEAR]), + btoi(K573_RTC[RTC_MONTH]), + btoi(K573_RTC[RTC_DAY_OF_MONTH] & 0x3f), + btoi(K573_RTC[RTC_HOURS]), + btoi(K573_RTC[RTC_MINUTES]), + btoi(K573_RTC[RTC_SECONDS] & 0x7f) + ); + + FntPrint(-1, "\nSYSTEM:\n"); + FntPrint(-1, " KERNEL=%s\n", version); + FntPrint(-1, " PCMCIA=%02@\n", inputs.coin >> 4); + + FntFlush(-1); + display(&ctx); + + // Reset the watchdog. This must be done at least once per frame to + // prevent the 573 from rebooting. + K573_WATCHDOG = 0; + + if (is_digital) + set_lights_digital(1 << current_light); + else + set_lights_analog(1 << current_light); + + // Handle inputs. + if ((last_joystick & 0x01) && !(inputs.p1_joy & 0x01)) // Left + current_light--; + if ((last_joystick & 0x02) && !(inputs.p1_joy & 0x02)) // Right + current_light++; + if ((last_buttons & 0x02) && !(inputs.p1_btn & 0x02)) // Button 1 + current_light--; + if ((last_buttons & 0x04) && !(inputs.p1_btn & 0x04)) // Button 2 + current_light++; + if ((last_buttons & 0x01) && !(inputs.p1_btn & 0x01)) { // Start + is_digital = !is_digital; + if (is_digital) + set_lights_analog(0); + else + set_lights_digital(0); + } + + current_light %= 32; + last_joystick = inputs.p1_joy; + last_buttons = inputs.p1_btn; + } + + return 0; +} -- cgit v1.2.3 From 2e6625481cd006d0a9d68285ce557f195030718e Mon Sep 17 00:00:00 2001 From: spicyjpeg <88942473+spicyjpeg@users.noreply.github.com> Date: Thu, 23 Dec 2021 22:09:06 +0100 Subject: Fix CdGetSector size inconsistency, update changelog --- .github/scripts/generate_release_notes.py | 46 ++++++++++--------------------- CHANGELOG.md | 29 +++++++++++++------ examples/cdrom/cdxa/main.c | 2 +- examples/io/system573/main.c | 2 +- libpsn00b/psxcd/cdgetsector.s | 3 +- libpsn00b/psxcd/isofs.c | 2 +- libpsn00b/psxcd/psxcd.c | 8 +++--- 7 files changed, 44 insertions(+), 48 deletions(-) (limited to '.github') diff --git a/.github/scripts/generate_release_notes.py b/.github/scripts/generate_release_notes.py index f3e4870..e3fbc7f 100644 --- a/.github/scripts/generate_release_notes.py +++ b/.github/scripts/generate_release_notes.py @@ -3,7 +3,7 @@ # (C) 2021 spicyjpeg - MPL licensed import sys, re -from time import gmtime, strptime +from time import gmtime, strptime, struct_time from argparse import ArgumentParser, FileType ## Helpers @@ -11,14 +11,13 @@ from argparse import ArgumentParser, FileType VERSION_REGEX = re.compile(r"^(?:refs\/tags\/)?(?:v|ver|version|release)? *(.*)") def parse_date(date): + if isinstance(date, struct_time): + return date + return strptime(date.strip(), "%Y-%m-%d") def normalize_version(version): - match = VERSION_REGEX.match(version.lower()) - if not match: - raise ValueError(f"invalid version string: {version}") - - return match.group(1) + return VERSION_REGEX.match(version.lower()).group(1) ## Changelog parser @@ -50,9 +49,6 @@ def parse_blocks(changelog): # [ _crap, date, version, body, date, version, body, ... ] items = BLOCK_REGEX.split(changelog.strip()) - #if items[0].strip(): - #raise RuntimeError("the changelog doesn't start with a valid block") - # Iterate over all blocks from bottom to top (i.e. oldest first). last_version = FIRST_VERSION @@ -110,51 +106,39 @@ def generate_notes(versions): def get_args(): parser = ArgumentParser( - description = "Generates and outputs release notes from a Markdown changelog file.", - add_help = False + description = "Generates and outputs release notes from a Markdown changelog file." ) - - tools_group = parser.add_argument_group("Tools") - tools_group.add_argument( - "-h", "--help", - action = "help", - help = "Show this help message and exits" - ) - - files_group = parser.add_argument_group("Files") - files_group.add_argument( + parser.add_argument( "changelog", type = FileType("rt"), help = "Markdown changelog file to parse" ) - files_group.add_argument( + parser.add_argument( "-o", "--output", type = FileType("wt"), default = sys.stdout, - help = "Where to output release notes (stdout by default)", + help = "where to output release notes (stdout by default)", metavar = "file" ) - - filter_group = parser.add_argument_group("Filters") - filter_group.add_argument( + parser.add_argument( "-v", "--version", action = "append", type = str, - help = "Ignore all changes not belonging to a version (can be specified multiple times)", + help = "ignore all changes not belonging to a version (can be specified multiple times)", metavar = "name" ) - filter_group.add_argument( + parser.add_argument( "-f", "--from-date", type = parse_date, default = parse_date("2000-01-01"), - help = "Ignore all changes before date", + help = "ignore all changes before date", metavar = "yyyy-mm-dd" ) - filter_group.add_argument( + parser.add_argument( "-t", "--to-date", type = parse_date, default = gmtime(), - help = "Ignore all changes after date", + help = "ignore all changes after date", metavar = "yyyy-mm-dd" ) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9463b83..ea4f4d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ contributing to PSn00bSDK, add a new block at the top following this template: ``` -## --: +## --: [optional new version] : @@ -19,6 +19,17 @@ to ensure the changelog can be parsed correctly. ------------------------------------------------------------------------------- +## 2021-12-23 + +spicyjpeg: + +- psxcd: `CdGetSector()` now expects the sector size to be in 32-bit word units + (rather than bytes) for consistency with the official CD-ROM library. The + library's ISO9660 parser and helper functions have been updated accordingly. + **This is a breaking change**. + +- examples: Added `spustream` audio streaming example. + ## 2021-11-28: 0.18 spicyjpeg: @@ -453,7 +464,7 @@ Lameguy64: - psxgpu: Fixed typos in `setUVWH()` macro. -- Added `_boot()` BIOS function (A(A0h) aka Warmboot, useful for CD based +- Added `_boot()` BIOS function (`A(A0h)` aka Warmboot, useful for CD based serial loaders). ## 2019-08-17: 0.13b @@ -505,9 +516,9 @@ Lameguy64: executable to return to a parent executable, return logic automatically calls `EnterCriticalSection()`. -- libc: Updated build method which takes libgcc from the compiler and adds +- libc: Updated build method which takes `libgcc` from the compiler and adds its own object files into it, eliminating linker problems caused by having - to order libc and libgcc libraries in a specific manner. + to order `libc` and `libgcc` libraries in a specific manner. - psxgpu: Added `RestartCallback()`. @@ -526,7 +537,7 @@ Lameguy64: performance, as the R3000 does not support 64-bit arithmetic natively so its emulated like floats. `int64` still used for processing floats and doubles and old `vsprintf.c` file is still included for those who really - want int64 support for whatever reason. + want `int64` support for whatever reason. - libc: Removed `stdarg.h` which is part of GCC and not license compatible with MPL. The toolchain compiled with libgcc provides `stdarg.h` and other @@ -540,7 +551,7 @@ Lameguy64: - psxgpu: Fixed bug in DMACallback where the internal DMA handler would fail to install due to `GetInterruptCallback()` retrieving the callback value - immediately in the branch delay slot of a jr instruction, which resuls to + immediately in the branch delay slot of a `jr` instruction, which resuls to an inconsistent return value. This also broke `DrawSyncCallback()`. - psxsio: Done fixes on `_sio_control()` from the aformentioned issues with @@ -619,7 +630,7 @@ Lameguy64: ready instead of simply waiting for GPU transfer ready which is the likely cause of subtle GPU related timing issues, it also sets GPU DMA transfer mode to off afterwards. It can also read number of words remaining in DMA - transfer if a0 is non-zero but it likely only returns the correct value on + transfer if `a0` is non-zero but it likely only returns the correct value on VRAM transfers. Exact way how `DrawSync()` returns the count in the official SDK is currently unknown. @@ -645,10 +656,10 @@ Lameguy64: - Added `rgb24` example. - Got custom exit handler set using `SetCustomExitFromException()` (BIOS - function B(19h)) working. Currently used to acknowledge VSync IRQ but + function `B(19h)`) working. Currently used to acknowledge VSync IRQ but actual VSync handling is still done with events and needs to be transferred to the custom exit handler. At least it lets BIOS - controller functions to work now. See doc/dev `notes.txt` for details + controller functions to work now. See `doc/dev notes.txt` for details on how this handler behaves. - Made stack usage in `ResetGraph()` less wasteful. You only need to diff --git a/examples/cdrom/cdxa/main.c b/examples/cdrom/cdxa/main.c index 5f11d8d..284b92f 100644 --- a/examples/cdrom/cdxa/main.c +++ b/examples/cdrom/cdxa/main.c @@ -199,7 +199,7 @@ void xa_callback(int intr, unsigned char *result) if (intr == CdlDataReady) { /* Fetch data sector */ - CdGetSector((u_long*)&xa_sector_buff, 2048); + CdGetSector((u_long*)&xa_sector_buff, 512); /* Quirk: This CdGetSector() implementation must fetch 2048 bytes */ /* or more otherwise the following sectors will be read in an */ diff --git a/examples/io/system573/main.c b/examples/io/system573/main.c index 67a98da..95c3155 100644 --- a/examples/io/system573/main.c +++ b/examples/io/system573/main.c @@ -306,7 +306,7 @@ int main(int argc, const char* argv[]) { FntPrint(-1, " P1 BUTTONS =%07@\n", inputs.p1_btn); FntPrint(-1, " P2 JOYSTICK =%04@\n", inputs.p2_joy); FntPrint(-1, " P2 BUTTONS =%07@\n", inputs.p2_btn); - FntPrint(-1, " COIN/SERVICE=%04@\n", inputs.coin); + FntPrint(-1, " COIN/SERVICE=%04@\n", inputs.coin & 0xf); FntPrint(-1, " DIP SWITCHES=%04@\n", inputs.dip_sw); FntPrint(-1, "\nCABINET LIGHTS:\n"); diff --git a/libpsn00b/psxcd/cdgetsector.s b/libpsn00b/psxcd/cdgetsector.s index 9af3543..dbe95cb 100644 --- a/libpsn00b/psxcd/cdgetsector.s +++ b/libpsn00b/psxcd/cdgetsector.s @@ -18,7 +18,8 @@ CdGetSector: # nop lui $v0, 0x1 - srl $a1, 2 +# 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) diff --git a/libpsn00b/psxcd/isofs.c b/libpsn00b/psxcd/isofs.c index 29bbb76..d1c1b18 100644 --- a/libpsn00b/psxcd/isofs.c +++ b/libpsn00b/psxcd/isofs.c @@ -795,7 +795,7 @@ static void _scan_callback(int status, unsigned char *result) { if( status == CdlDataReady ) { - CdGetSector((void*)_ses_scanbuff, 2048); + CdGetSector((void*)_ses_scanbuff, 512); if( _ses_scanbuff[0] == 0x1 ) { diff --git a/libpsn00b/psxcd/psxcd.c b/libpsn00b/psxcd/psxcd.c index 74c6c1c..76415f9 100644 --- a/libpsn00b/psxcd/psxcd.c +++ b/libpsn00b/psxcd/psxcd.c @@ -255,7 +255,7 @@ static void _CdReadReadyCallback(int status, unsigned char *result) CdGetSector((void*)_cd_read_addr, _cd_read_sector_sz); // Increment destination address - _cd_read_addr += _cd_read_sector_sz>>2; + _cd_read_addr += _cd_read_sector_sz; // Subtract sector count _cd_sector_count--; @@ -290,15 +290,15 @@ int CdRead(int sectors, u_long *buf, int mode) // Determine sector based on mode flags if( mode & CdlModeSize0 ) { - _cd_read_sector_sz = 2328; + _cd_read_sector_sz = 2328 / 4; } else if( mode & CdlModeSize1 ) { - _cd_read_sector_sz = 2340; + _cd_read_sector_sz = 2340 / 4; } else { - _cd_read_sector_sz = 2048; + _cd_read_sector_sz = 2048 / 4; } _cd_read_counter = VSync(-1); -- cgit v1.2.3 From d60b046bf362fcc9332f463823e8d02147d516de Mon Sep 17 00:00:00 2001 From: spicyjpeg <88942473+spicyjpeg@users.noreply.github.com> Date: Thu, 23 Dec 2021 23:20:12 +0100 Subject: Remove PSN00BSDK_LIBS leftovers, improve CI artifact upload --- .github/workflows/build.yml | 32 +++++++++++++++++++++++------ doc/installation.md | 25 +++++++++++----------- examples/beginner/cppdemo/CMakeLists.txt | 4 ---- examples/beginner/hello/CMakeLists.txt | 4 ---- examples/cdrom/cdbrowse/CMakeLists.txt | 4 ---- examples/cdrom/cdxa/CMakeLists.txt | 4 ---- examples/demos/n00bdemo/CMakeLists.txt | 4 ---- examples/graphics/balls/CMakeLists.txt | 4 ---- examples/graphics/billboard/CMakeLists.txt | 4 ---- examples/graphics/fpscam/CMakeLists.txt | 4 ---- examples/graphics/gte/CMakeLists.txt | 4 ---- examples/graphics/hdtv/CMakeLists.txt | 4 ---- examples/graphics/render2tex/CMakeLists.txt | 4 ---- examples/graphics/rgb24/CMakeLists.txt | 4 ---- examples/io/pads/CMakeLists.txt | 4 ---- examples/io/system573/CMakeLists.txt | 4 ---- examples/lowlevel/cartrom/CMakeLists.txt | 4 ---- examples/sound/spustream/CMakeLists.txt | 4 ---- examples/sound/vagsample/CMakeLists.txt | 4 ---- examples/system/childexec/CMakeLists.txt | 4 ---- examples/system/console/CMakeLists.txt | 4 ---- examples/system/dynlink/CMakeLists.txt | 4 ---- examples/system/timer/CMakeLists.txt | 4 ---- examples/system/tty/CMakeLists.txt | 4 ---- 24 files changed, 38 insertions(+), 107 deletions(-) (limited to '.github') diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8c16ac3..3cbefb1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -124,13 +124,20 @@ jobs: cmake --build build cmake --build build -t package + # The GitHub Actions UI doesn't allow downloading individual files from + # an artifact, so it's best to upload each package type as a separate + # artifact. - name: Upload build artifacts uses: actions/upload-artifact@v2 with: name: psn00bsdk-windows - path: | - build/packages/* - !build/packages/_CPack_Packages + path: build/packages/*.zip + + - name: Upload build artifacts (NSIS) + uses: actions/upload-artifact@v2 + with: + name: psn00bsdk-windows-nsis + path: build/packages/*.exe build-sdk-linux: name: Build PSn00bSDK on Linux @@ -169,9 +176,19 @@ jobs: uses: actions/upload-artifact@v2 with: name: psn00bsdk-linux - path: | - build/packages/* - !build/packages/_CPack_Packages + path: build/packages/*.zip + + - name: Upload build artifacts (DEB) + uses: actions/upload-artifact@v2 + with: + name: psn00bsdk-linux-deb + path: build/packages/*.deb + + - name: Upload build artifacts (RPM) + uses: actions/upload-artifact@v2 + with: + name: psn00bsdk-linux-rpm + path: build/packages/*.rpm # This job takes care of creating a new release and upload the build # artifacts if the last commit is associated to a tag. @@ -222,4 +239,7 @@ jobs: files: | *.zip psn00bsdk-windows/* + psn00bsdk-windows-nsis/* psn00bsdk-linux/* + psn00bsdk-linux-deb/* + psn00bsdk-linux-rpm/* diff --git a/doc/installation.md b/doc/installation.md index 576eb7a..ca3aab4 100644 --- a/doc/installation.md +++ b/doc/installation.md @@ -96,9 +96,9 @@ and installed properly. - `/lib/libpsn00b` - `/share/psn00bsdk` -7. Set the `PSN00BSDK_LIBS` environment variable to point to the `lib/libpsn00b` - subfolder inside the install directory. You might also want to add the `bin` - folder to `PATH` if it's not listed already. +7. You may optionally set the `PSN00BSDK_LIBS` environment variable to point to + the `lib/libpsn00b` subfolder inside the install directory. You might also + want to add the `bin` folder to `PATH` if it's not listed already. Although not strictly required, you'll probably want to install a PS1 emulator with debugging capabilities such as [no$psx](https://problemkaputt.de/psx.htm) @@ -132,24 +132,23 @@ far from being feature-complete. 1. Copy the contents of `/share/psn00bsdk/template` (or the `template` folder within the repo) to your new project's root directory. -2. Configure and build the template by running: +2. If you haven't set the `PSN00BSDK_LIBS` environment variable previously or + if you want to use a different PSn00bSDK installation for the project, edit + `CMakePresets.json` to set the path you installed the SDK to. See the + [setup guide](cmake_reference.md#setup) for details. + +3. Configure and build the template by running: ```bash - cmake -S . -B ./build + cmake --preset default . cmake --build ./build ``` If you did everything correctly there should be a `template.bin` CD image in the `build` folder. Test it in an emulator to ensure it works. -Note that, even though the template relies on the `PSN00BSDK_LIBS` environment -variable to locate the SDK by default, you can also specify the path directly -on the CMake command line by adding -`-DCMAKE_TOOLCHAIN_FILE=/lib/libpsn00b/cmake/sdk.cmake` to the -CMake command line. - The toolchain script defines a few CMake macros to create PS1 executables, DLLs -and CD images. See the [reference](doc/cmake_reference.md) for details. +and CD images. See the [reference](cmake_reference.md) for details. ----------------------------------------- -_Last updated on 2021-11-19 by spicyjpeg_ +_Last updated on 2021-12-23 by spicyjpeg_ diff --git a/examples/beginner/cppdemo/CMakeLists.txt b/examples/beginner/cppdemo/CMakeLists.txt index becf464..c43d4a1 100644 --- a/examples/beginner/cppdemo/CMakeLists.txt +++ b/examples/beginner/cppdemo/CMakeLists.txt @@ -3,10 +3,6 @@ cmake_minimum_required(VERSION 3.20) -if(NOT DEFINED CMAKE_TOOLCHAIN_FILE AND DEFINED ENV{PSN00BSDK_LIBS}) - set(CMAKE_TOOLCHAIN_FILE $ENV{PSN00BSDK_LIBS}/cmake/sdk.cmake) -endif() - project( cppdemo LANGUAGES CXX diff --git a/examples/beginner/hello/CMakeLists.txt b/examples/beginner/hello/CMakeLists.txt index 7fb7c22..d8297c5 100644 --- a/examples/beginner/hello/CMakeLists.txt +++ b/examples/beginner/hello/CMakeLists.txt @@ -3,10 +3,6 @@ cmake_minimum_required(VERSION 3.20) -if(NOT DEFINED CMAKE_TOOLCHAIN_FILE AND DEFINED ENV{PSN00BSDK_LIBS}) - set(CMAKE_TOOLCHAIN_FILE $ENV{PSN00BSDK_LIBS}/cmake/sdk.cmake) -endif() - project( hello LANGUAGES C diff --git a/examples/cdrom/cdbrowse/CMakeLists.txt b/examples/cdrom/cdbrowse/CMakeLists.txt index e5ec759..e36407d 100644 --- a/examples/cdrom/cdbrowse/CMakeLists.txt +++ b/examples/cdrom/cdbrowse/CMakeLists.txt @@ -3,10 +3,6 @@ cmake_minimum_required(VERSION 3.20) -if(NOT DEFINED CMAKE_TOOLCHAIN_FILE AND DEFINED ENV{PSN00BSDK_LIBS}) - set(CMAKE_TOOLCHAIN_FILE $ENV{PSN00BSDK_LIBS}/cmake/sdk.cmake) -endif() - project( cdbrowse LANGUAGES C diff --git a/examples/cdrom/cdxa/CMakeLists.txt b/examples/cdrom/cdxa/CMakeLists.txt index 18dcc69..7b90f59 100644 --- a/examples/cdrom/cdxa/CMakeLists.txt +++ b/examples/cdrom/cdxa/CMakeLists.txt @@ -3,10 +3,6 @@ cmake_minimum_required(VERSION 3.20) -if(NOT DEFINED CMAKE_TOOLCHAIN_FILE AND DEFINED ENV{PSN00BSDK_LIBS}) - set(CMAKE_TOOLCHAIN_FILE $ENV{PSN00BSDK_LIBS}/cmake/sdk.cmake) -endif() - project( cdxa LANGUAGES C diff --git a/examples/demos/n00bdemo/CMakeLists.txt b/examples/demos/n00bdemo/CMakeLists.txt index c62c4ef..1c211b3 100644 --- a/examples/demos/n00bdemo/CMakeLists.txt +++ b/examples/demos/n00bdemo/CMakeLists.txt @@ -3,10 +3,6 @@ cmake_minimum_required(VERSION 3.20) -if(NOT DEFINED CMAKE_TOOLCHAIN_FILE AND DEFINED ENV{PSN00BSDK_LIBS}) - set(CMAKE_TOOLCHAIN_FILE $ENV{PSN00BSDK_LIBS}/cmake/sdk.cmake) -endif() - project( n00bdemo LANGUAGES C ASM diff --git a/examples/graphics/balls/CMakeLists.txt b/examples/graphics/balls/CMakeLists.txt index 5886484..f5297c3 100644 --- a/examples/graphics/balls/CMakeLists.txt +++ b/examples/graphics/balls/CMakeLists.txt @@ -3,10 +3,6 @@ cmake_minimum_required(VERSION 3.20) -if(NOT DEFINED CMAKE_TOOLCHAIN_FILE AND DEFINED ENV{PSN00BSDK_LIBS}) - set(CMAKE_TOOLCHAIN_FILE $ENV{PSN00BSDK_LIBS}/cmake/sdk.cmake) -endif() - project( balls LANGUAGES C diff --git a/examples/graphics/billboard/CMakeLists.txt b/examples/graphics/billboard/CMakeLists.txt index 8cd31a9..1b417d2 100644 --- a/examples/graphics/billboard/CMakeLists.txt +++ b/examples/graphics/billboard/CMakeLists.txt @@ -3,10 +3,6 @@ cmake_minimum_required(VERSION 3.20) -if(NOT DEFINED CMAKE_TOOLCHAIN_FILE AND DEFINED ENV{PSN00BSDK_LIBS}) - set(CMAKE_TOOLCHAIN_FILE $ENV{PSN00BSDK_LIBS}/cmake/sdk.cmake) -endif() - project( billboard LANGUAGES C ASM diff --git a/examples/graphics/fpscam/CMakeLists.txt b/examples/graphics/fpscam/CMakeLists.txt index 791f6c2..cb0c086 100644 --- a/examples/graphics/fpscam/CMakeLists.txt +++ b/examples/graphics/fpscam/CMakeLists.txt @@ -3,10 +3,6 @@ cmake_minimum_required(VERSION 3.20) -if(NOT DEFINED CMAKE_TOOLCHAIN_FILE AND DEFINED ENV{PSN00BSDK_LIBS}) - set(CMAKE_TOOLCHAIN_FILE $ENV{PSN00BSDK_LIBS}/cmake/sdk.cmake) -endif() - project( fpscam LANGUAGES C diff --git a/examples/graphics/gte/CMakeLists.txt b/examples/graphics/gte/CMakeLists.txt index 85b2942..f95c5ff 100644 --- a/examples/graphics/gte/CMakeLists.txt +++ b/examples/graphics/gte/CMakeLists.txt @@ -3,10 +3,6 @@ cmake_minimum_required(VERSION 3.20) -if(NOT DEFINED CMAKE_TOOLCHAIN_FILE AND DEFINED ENV{PSN00BSDK_LIBS}) - set(CMAKE_TOOLCHAIN_FILE $ENV{PSN00BSDK_LIBS}/cmake/sdk.cmake) -endif() - project( gte LANGUAGES C diff --git a/examples/graphics/hdtv/CMakeLists.txt b/examples/graphics/hdtv/CMakeLists.txt index f92faeb..804b096 100644 --- a/examples/graphics/hdtv/CMakeLists.txt +++ b/examples/graphics/hdtv/CMakeLists.txt @@ -3,10 +3,6 @@ cmake_minimum_required(VERSION 3.20) -if(NOT DEFINED CMAKE_TOOLCHAIN_FILE AND DEFINED ENV{PSN00BSDK_LIBS}) - set(CMAKE_TOOLCHAIN_FILE $ENV{PSN00BSDK_LIBS}/cmake/sdk.cmake) -endif() - project( hdtv LANGUAGES C diff --git a/examples/graphics/render2tex/CMakeLists.txt b/examples/graphics/render2tex/CMakeLists.txt index 360840d..70e489e 100644 --- a/examples/graphics/render2tex/CMakeLists.txt +++ b/examples/graphics/render2tex/CMakeLists.txt @@ -3,10 +3,6 @@ cmake_minimum_required(VERSION 3.20) -if(NOT DEFINED CMAKE_TOOLCHAIN_FILE AND DEFINED ENV{PSN00BSDK_LIBS}) - set(CMAKE_TOOLCHAIN_FILE $ENV{PSN00BSDK_LIBS}/cmake/sdk.cmake) -endif() - project( render2tex LANGUAGES C ASM diff --git a/examples/graphics/rgb24/CMakeLists.txt b/examples/graphics/rgb24/CMakeLists.txt index bf8a8fa..449981a 100644 --- a/examples/graphics/rgb24/CMakeLists.txt +++ b/examples/graphics/rgb24/CMakeLists.txt @@ -3,10 +3,6 @@ cmake_minimum_required(VERSION 3.20) -if(NOT DEFINED CMAKE_TOOLCHAIN_FILE AND DEFINED ENV{PSN00BSDK_LIBS}) - set(CMAKE_TOOLCHAIN_FILE $ENV{PSN00BSDK_LIBS}/cmake/sdk.cmake) -endif() - project( rgb24 LANGUAGES C ASM diff --git a/examples/io/pads/CMakeLists.txt b/examples/io/pads/CMakeLists.txt index 5bd7f5d..cf5f817 100644 --- a/examples/io/pads/CMakeLists.txt +++ b/examples/io/pads/CMakeLists.txt @@ -3,10 +3,6 @@ cmake_minimum_required(VERSION 3.20) -if(NOT DEFINED CMAKE_TOOLCHAIN_FILE AND DEFINED ENV{PSN00BSDK_LIBS}) - set(CMAKE_TOOLCHAIN_FILE $ENV{PSN00BSDK_LIBS}/cmake/sdk.cmake) -endif() - project( pads LANGUAGES C ASM diff --git a/examples/io/system573/CMakeLists.txt b/examples/io/system573/CMakeLists.txt index 34c9153..1c74347 100644 --- a/examples/io/system573/CMakeLists.txt +++ b/examples/io/system573/CMakeLists.txt @@ -3,10 +3,6 @@ cmake_minimum_required(VERSION 3.21) -if(NOT DEFINED CMAKE_TOOLCHAIN_FILE AND DEFINED ENV{PSN00BSDK_LIBS}) - set(CMAKE_TOOLCHAIN_FILE $ENV{PSN00BSDK_LIBS}/cmake/sdk.cmake) -endif() - project( system573 LANGUAGES C ASM diff --git a/examples/lowlevel/cartrom/CMakeLists.txt b/examples/lowlevel/cartrom/CMakeLists.txt index 3e807a3..107cc3d 100644 --- a/examples/lowlevel/cartrom/CMakeLists.txt +++ b/examples/lowlevel/cartrom/CMakeLists.txt @@ -3,10 +3,6 @@ cmake_minimum_required(VERSION 3.21) -if(NOT DEFINED CMAKE_TOOLCHAIN_FILE AND DEFINED ENV{PSN00BSDK_LIBS}) - set(CMAKE_TOOLCHAIN_FILE $ENV{PSN00BSDK_LIBS}/cmake/sdk.cmake) -endif() - project( cartrom LANGUAGES C ASM diff --git a/examples/sound/spustream/CMakeLists.txt b/examples/sound/spustream/CMakeLists.txt index 91243cf..9e84fa3 100644 --- a/examples/sound/spustream/CMakeLists.txt +++ b/examples/sound/spustream/CMakeLists.txt @@ -3,10 +3,6 @@ cmake_minimum_required(VERSION 3.20) -if(NOT DEFINED CMAKE_TOOLCHAIN_FILE AND DEFINED ENV{PSN00BSDK_LIBS}) - set(CMAKE_TOOLCHAIN_FILE $ENV{PSN00BSDK_LIBS}/cmake/sdk.cmake) -endif() - project( spustream LANGUAGES C diff --git a/examples/sound/vagsample/CMakeLists.txt b/examples/sound/vagsample/CMakeLists.txt index 1a15d9c..f37be97 100644 --- a/examples/sound/vagsample/CMakeLists.txt +++ b/examples/sound/vagsample/CMakeLists.txt @@ -3,10 +3,6 @@ cmake_minimum_required(VERSION 3.20) -if(NOT DEFINED CMAKE_TOOLCHAIN_FILE AND DEFINED ENV{PSN00BSDK_LIBS}) - set(CMAKE_TOOLCHAIN_FILE $ENV{PSN00BSDK_LIBS}/cmake/sdk.cmake) -endif() - project( vagsample LANGUAGES C diff --git a/examples/system/childexec/CMakeLists.txt b/examples/system/childexec/CMakeLists.txt index 88168e0..ca0c110 100644 --- a/examples/system/childexec/CMakeLists.txt +++ b/examples/system/childexec/CMakeLists.txt @@ -3,10 +3,6 @@ cmake_minimum_required(VERSION 3.20) -if(NOT DEFINED CMAKE_TOOLCHAIN_FILE AND DEFINED ENV{PSN00BSDK_LIBS}) - set(CMAKE_TOOLCHAIN_FILE $ENV{PSN00BSDK_LIBS}/cmake/sdk.cmake) -endif() - project( childexec LANGUAGES C ASM diff --git a/examples/system/console/CMakeLists.txt b/examples/system/console/CMakeLists.txt index 6dc6154..d58f212 100644 --- a/examples/system/console/CMakeLists.txt +++ b/examples/system/console/CMakeLists.txt @@ -3,10 +3,6 @@ cmake_minimum_required(VERSION 3.20) -if(NOT DEFINED CMAKE_TOOLCHAIN_FILE AND DEFINED ENV{PSN00BSDK_LIBS}) - set(CMAKE_TOOLCHAIN_FILE $ENV{PSN00BSDK_LIBS}/cmake/sdk.cmake) -endif() - project( console LANGUAGES C diff --git a/examples/system/dynlink/CMakeLists.txt b/examples/system/dynlink/CMakeLists.txt index 5834647..aae3bb3 100644 --- a/examples/system/dynlink/CMakeLists.txt +++ b/examples/system/dynlink/CMakeLists.txt @@ -3,10 +3,6 @@ cmake_minimum_required(VERSION 3.20) -if(NOT DEFINED CMAKE_TOOLCHAIN_FILE AND DEFINED ENV{PSN00BSDK_LIBS}) - set(CMAKE_TOOLCHAIN_FILE $ENV{PSN00BSDK_LIBS}/cmake/sdk.cmake) -endif() - project( dynlink LANGUAGES C diff --git a/examples/system/timer/CMakeLists.txt b/examples/system/timer/CMakeLists.txt index 58daf9b..328e07e 100644 --- a/examples/system/timer/CMakeLists.txt +++ b/examples/system/timer/CMakeLists.txt @@ -3,10 +3,6 @@ cmake_minimum_required(VERSION 3.20) -if(NOT DEFINED CMAKE_TOOLCHAIN_FILE AND DEFINED ENV{PSN00BSDK_LIBS}) - set(CMAKE_TOOLCHAIN_FILE $ENV{PSN00BSDK_LIBS}/cmake/sdk.cmake) -endif() - project( timer LANGUAGES C diff --git a/examples/system/tty/CMakeLists.txt b/examples/system/tty/CMakeLists.txt index 4e0ca36..0664502 100644 --- a/examples/system/tty/CMakeLists.txt +++ b/examples/system/tty/CMakeLists.txt @@ -3,10 +3,6 @@ cmake_minimum_required(VERSION 3.20) -if(NOT DEFINED CMAKE_TOOLCHAIN_FILE AND DEFINED ENV{PSN00BSDK_LIBS}) - set(CMAKE_TOOLCHAIN_FILE $ENV{PSN00BSDK_LIBS}/cmake/sdk.cmake) -endif() - project( tty LANGUAGES C -- cgit v1.2.3 From fe42ce7f1c98947baa49427835deb5ce70470afb Mon Sep 17 00:00:00 2001 From: spicyjpeg <88942473+spicyjpeg@users.noreply.github.com> Date: Wed, 29 Dec 2021 17:30:56 +0100 Subject: Fix CMake and CI bugs, set version number, update docs --- .github/workflows/build.yml | 4 ++-- CMakeLists.txt | 33 ++++++++++++++++++++++----------- CMakePresets.json | 9 +++++---- cpack/setup.cmake | 3 +-- cpack/welcome.txt | 3 --- doc/cmake_reference.md | 10 +++++++--- doc/installation.md | 9 ++++----- examples/sound/spustream/main.c | 2 +- libpsn00b/CMakeLists.txt | 1 - libpsn00b/build.json.template | 9 ++++++--- libpsn00b/cmake/internal_setup.cmake | 5 +++-- 11 files changed, 51 insertions(+), 37 deletions(-) delete mode 100644 cpack/welcome.txt (limited to '.github') diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3cbefb1..a72f5d3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -116,7 +116,7 @@ jobs: - name: Update repo submodules run: | cd sdk - git submodule update --init --recursive --remote + git submodule update --init --recursive - name: Build and package PSn00bSDK run: | @@ -164,7 +164,7 @@ jobs: - name: Update repo submodules run: | cd sdk - git submodule update --init --recursive --remote + git submodule update --init --recursive - name: Build and package PSn00bSDK run: | diff --git a/CMakeLists.txt b/CMakeLists.txt index 720ca8c..6a20a0e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ include(ExternalProject) project( PSn00bSDK LANGUAGES NONE - VERSION 0.1.0 + VERSION 0.18 DESCRIPTION "Open source PlayStation 1 SDK" HOMEPAGE_URL "http://lameguy64.net/?page=psn00bsdk" ) @@ -39,9 +39,15 @@ set( CACHE BOOL "Skip building SDK examples (not required for installation)" ) set( - BUILD_INFO "" - CACHE STRING "Information about this build to be included in build.json" + PSN00BSDK_GIT_TAG "" + CACHE STRING "Git tag or branch name (used by CI)" ) +set( + PSN00BSDK_GIT_COMMIT "" + CACHE STRING "Git commit hash (used by CI)" +) + +string(TIMESTAMP PSN00BSDK_BUILD_DATE UTC) # Forward some important variables to mkpsxiso and to the subprojects (they are # not inherited automatically as they are not environment variables). This also @@ -50,20 +56,24 @@ set( # invoked (ExternalProject_Add() runs the subprojects' install step at build # time). set( - COMMON_ARGS + _common_args -DPSN00BSDK_TC:PATH=${PSN00BSDK_TC} -DPSN00BSDK_TARGET:STRING=${PSN00BSDK_TARGET} -DPSN00BSDK_VERSION:STRING=${PROJECT_VERSION} - -DPSN00BSDK_BUILD_INFO:STRING=${BUILD_INFO} + -DPSN00BSDK_BUILD_DATE:STRING=${PSN00BSDK_BUILD_DATE} + -DPSN00BSDK_GIT_TAG:STRING=${PSN00BSDK_GIT_TAG} + -DPSN00BSDK_GIT_COMMIT:STRING=${PSN00BSDK_GIT_COMMIT} -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} ) set( - SUBPROJECT_ARGS + _sdk_args + ${_common_args} -DCMAKE_TOOLCHAIN_FILE:FILEPATH=${CMAKE_TOOLCHAIN_FILE} -DCMAKE_INSTALL_PREFIX:PATH=${PROJECT_BINARY_DIR}/install_tree ) set( - EXAMPLES_ARGS + _examples_args + ${_common_args} -DCMAKE_TOOLCHAIN_FILE:FILEPATH=${PROJECT_BINARY_DIR}/install_tree/${CMAKE_INSTALL_LIBDIR}/libpsn00b/cmake/sdk.cmake -DCMAKE_INSTALL_PREFIX:PATH=${PROJECT_BINARY_DIR}/examples ) @@ -77,26 +87,26 @@ endif() ExternalProject_Add( tools SOURCE_DIR ${PROJECT_SOURCE_DIR}/tools - CMAKE_CACHE_ARGS ${COMMON_ARGS} ${SUBPROJECT_ARGS} + CMAKE_CACHE_ARGS ${_sdk_args} INSTALL_DIR install_tree ) ExternalProject_Add( mkpsxiso SOURCE_DIR ${PROJECT_SOURCE_DIR}/tools/mkpsxiso - CMAKE_CACHE_ARGS ${COMMON_ARGS} ${SUBPROJECT_ARGS} + CMAKE_CACHE_ARGS ${_sdk_args} INSTALL_DIR install_tree ) ExternalProject_Add( libpsn00b SOURCE_DIR ${PROJECT_SOURCE_DIR}/libpsn00b - CMAKE_CACHE_ARGS ${COMMON_ARGS} ${SUBPROJECT_ARGS} + CMAKE_CACHE_ARGS ${_sdk_args} INSTALL_DIR install_tree #DEPENDS tools ) ExternalProject_Add( examples SOURCE_DIR ${PROJECT_SOURCE_DIR}/examples - CMAKE_CACHE_ARGS ${COMMON_ARGS} ${EXAMPLES_ARGS} + CMAKE_CACHE_ARGS ${_examples_args} INSTALL_DIR examples DEPENDS libpsn00b tools mkpsxiso EXCLUDE_FROM_ALL ${SKIP_EXAMPLES} @@ -108,6 +118,7 @@ foreach( _subdir IN ITEMS ${CMAKE_INSTALL_BINDIR} ${CMAKE_INSTALL_LIBDIR} + ${CMAKE_INSTALL_INCLUDEDIR} ${CMAKE_INSTALL_DATADIR} ) install( diff --git a/CMakePresets.json b/CMakePresets.json index 7c9fdd3..d71c1ae 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -32,10 +32,11 @@ "generator": "Ninja", "binaryDir": "${sourceDir}/../build", "cacheVariables": { - "CMAKE_BUILD_TYPE": "Release", - "BUNDLE_TOOLCHAIN": "ON", - "BUILD_INFO": "Built by GitHub Actions ($env{GITHUB_REF_NAME} $env{GITHUB_SHA})", - "PSN00BSDK_TARGET": "$env{GCC_TARGET}" + "CMAKE_BUILD_TYPE": "Release", + "BUNDLE_TOOLCHAIN": "ON", + "PSN00BSDK_TARGET": "$env{GCC_TARGET}", + "PSN00BSDK_GIT_TAG": "$env{GITHUB_REF_NAME}", + "PSN00BSDK_GIT_COMMIT": "$env{GITHUB_SHA}" } } ] diff --git a/cpack/setup.cmake b/cpack/setup.cmake index 57568bb..a5d71ff 100644 --- a/cpack/setup.cmake +++ b/cpack/setup.cmake @@ -21,7 +21,7 @@ set( ## Bundled components -# "Install" the toolchain and CMake (by pulling files from its their install +# "Install" the toolchain and CMake (by pulling files from their install # locations). This is only useful when building installers, as CPack will pick # up these installation rules and bundle the toolchain in the installers. # NOTE: unfortunately there is no easy way to reuse the toolchain finding logic @@ -105,7 +105,6 @@ set(CPACK_RESOURCE_FILE_README ${PROJECT_SOURCE_DIR}/README.md) set(CPACK_RESOURCE_FILE_LICENSE ${PROJECT_SOURCE_DIR}/LICENSE.md) set(CPACK_PACKAGE_ICON ${CMAKE_CURRENT_LIST_DIR}/icon.ico) set(CPACK_PACKAGE_DESCRIPTION_FILE ${CMAKE_CURRENT_LIST_DIR}/description.txt) -set(CPACK_RESOURCE_FILE_WELCOME ${CMAKE_CURRENT_LIST_DIR}/welcome.txt) set(CPACK_PRE_BUILD_SCRIPTS ${CMAKE_CURRENT_LIST_DIR}/fakeroot_fix.cmake) set(CPACK_PACKAGE_INSTALL_DIRECTORY PSn00bSDK) diff --git a/cpack/welcome.txt b/cpack/welcome.txt deleted file mode 100644 index e024336..0000000 --- a/cpack/welcome.txt +++ /dev/null @@ -1,3 +0,0 @@ -This installer will set up PSn00bSDK, including prebuilt libraries, CMake scripts as well as several command-line utilities for PlayStation 1 homebrew development. - -NOTE: CMake and the GCC toolchain must be installed separately. diff --git a/doc/cmake_reference.md b/doc/cmake_reference.md index 9e134d9..3c89da3 100644 --- a/doc/cmake_reference.md +++ b/doc/cmake_reference.md @@ -207,9 +207,13 @@ the build script. ## Read-only variables -- `PSN00BSDK_VERSION` +- `PSN00BSDK_VERSION`, `PSN00BSDK_BUILD_DATE`, `PSN00BSDK_GIT_TAG`, + `PSN00BSDK_GIT_COMMIT` - The SDK's version number (`major.minor.patch`). + These variables are loaded from `lib/libpsn00b/build.json` and contain + information about the SDK's version. Note that `PSN00BSDK_GIT_TAG` and + `PSN00BSDK_GIT_COMMIT` are not populated by default when building PSn00bSDK + manually from source, so they might be empty strings. - `PSN00BSDK_TOOLS`, `PSN00BSDK_INCLUDE`, `PSN00BSDK_LDSCRIPTS` @@ -229,4 +233,4 @@ the build script. LZP archives as part of the build pipeline. ----------------------------------------- -_Last updated on 2021-11-24 by spicyjpeg_ +_Last updated on 2021-12-29 by spicyjpeg_ diff --git a/doc/installation.md b/doc/installation.md index ca3aab4..1646653 100644 --- a/doc/installation.md +++ b/doc/installation.md @@ -62,7 +62,7 @@ and installed properly. repository to download additional dependencies: ```bash - git submodule update --init --recursive --remote + git submodule update --init --recursive ``` 5. Compile the libraries, tools and examples using CMake: @@ -74,9 +74,8 @@ and installed properly. If you want to install the SDK to a custom location rather than the default one (`C:\Program Files\PSn00bSDK` or `/usr/local` depending on your OS), add - `--install-prefix ` to the first command. Add - `-DPSN00BSDK_TARGET=mipsel-none-elf` if your toolchain targets - `mipsel-none-elf` rather than `mipsel-unknown-elf`. + `--install-prefix ` to the first command. Remember to add + `-DPSN00BSDK_TARGET=mipsel-unknown-elf` if necessary. **NOTE**: Ninja is used by default to build the SDK. If you can't get it to work or don't have it installed, pass `-G "Unix Makefiles"` (or @@ -151,4 +150,4 @@ The toolchain script defines a few CMake macros to create PS1 executables, DLLs and CD images. See the [reference](cmake_reference.md) for details. ----------------------------------------- -_Last updated on 2021-12-23 by spicyjpeg_ +_Last updated on 2021-12-29 by spicyjpeg_ diff --git a/examples/sound/spustream/main.c b/examples/sound/spustream/main.c index 2032df5..e268c7d 100644 --- a/examples/sound/spustream/main.c +++ b/examples/sound/spustream/main.c @@ -349,7 +349,7 @@ void start_stream(void) { 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 = 0xdfee80ff; // or 0x9fc080ff, 0xdff18087 + SPU_CHANNELS[i].adsr_param = 0x1fee80ff; // or 0x9fc080ff, 0xdff18087 } // Unmute the channels and route them for stereo output. You'll want to diff --git a/libpsn00b/CMakeLists.txt b/libpsn00b/CMakeLists.txt index 2b2e76d..829a2f7 100644 --- a/libpsn00b/CMakeLists.txt +++ b/libpsn00b/CMakeLists.txt @@ -73,7 +73,6 @@ install( # Generate build.json. This file is used to determine the SDK version after # installation and may contain additional metadata about the build. -string(TIMESTAMP PSN00BSDK_BUILD_DATE UTC) configure_file( build.json.template build.json ESCAPE_QUOTES diff --git a/libpsn00b/build.json.template b/libpsn00b/build.json.template index 666bb43..374b22a 100644 --- a/libpsn00b/build.json.template +++ b/libpsn00b/build.json.template @@ -1,5 +1,8 @@ { - "version": "${PSN00BSDK_VERSION}", - "build_date": "${PSN00BSDK_BUILD_DATE}", - "build_info": "${PSN00BSDK_BUILD_INFO}" + "version": "${PSN00BSDK_VERSION}", + "build_date": "${PSN00BSDK_BUILD_DATE}", + "git_tag": "${PSN00BSDK_GIT_TAG}", + "git_commit": "${PSN00BSDK_GIT_COMMIT}", + "cmake_version": "${CMAKE_VERSION}", + "host_system": "${CMAKE_HOST_SYSTEM_NAME}" } diff --git a/libpsn00b/cmake/internal_setup.cmake b/libpsn00b/cmake/internal_setup.cmake index 1d63e92..7d6bfdd 100644 --- a/libpsn00b/cmake/internal_setup.cmake +++ b/libpsn00b/cmake/internal_setup.cmake @@ -7,13 +7,14 @@ cmake_minimum_required(VERSION 3.20) include(GNUInstallDirs) -# Fetch the SDK version number from build.json. +# Fetch SDK version information from build.json. if(NOT DEFINED PSN00BSDK_VERSION) file(READ ${CMAKE_CURRENT_LIST_DIR}/../build.json _json) string(JSON PSN00BSDK_VERSION GET ${_json} version) string(JSON PSN00BSDK_BUILD_DATE GET ${_json} build_date) - string(JSON PSN00BSDK_BUILD_INFO GET ${_json} build_info) + string(JSON PSN00BSDK_GIT_TAG GET ${_json} git_tag) + string(JSON PSN00BSDK_GIT_COMMIT GET ${_json} git_commit) endif() ## Settings (can be overridden by projects) -- cgit v1.2.3