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/workflows/build.yml | 208 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 208 insertions(+) create mode 100644 .github/workflows/build.yml (limited to '.github/workflows') 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/workflows') 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 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/workflows') 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/workflows') 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