How overdrivenpotato/rust-psp works
Purpose and Workspace Shape
rust-psp is a Rust SDK for producing PlayStation Portable homebrew applications and PRX plugins without PSPSDK. The root workspace centers on the target runtime crate and a Cargo subcommand that builds/package PSP artifacts: Cargo.toml, psp/Cargo.toml, and cargo-psp/Cargo.toml.
Application-Facing PSP Runtime
The psp crate is the primary consumer API for #![no_std] PSP binaries. Its module macro establishes PSP module metadata and the expected psp_main-style program boundary; the crate also exports allocation, panic, debugging, math, graphics, VFPU, and test support. Core integration is concentrated in psp/src/lib.rs, psp/src/alloc_impl.rs, and psp/src/panic.rs.
System ABI and PSP Services
Low-level bindings expose PSP firmware services through a structured sys namespace. This is the boundary between safe/higher-level Rust APIs and PSP kernel/user-mode ABI calls, covering input, display, graphics engine, audio, I/O, networking, power, threads, and utility dialogs. Key aggregation and graphics/control surfaces are psp/src/sys/mod.rs, psp/src/sys/ge.rs, and psp/src/sys/kernel/thread.rs.
Graphics, Memory, and Vector Processing
The SDK provides direct graphics-engine APIs plus higher-level GU/GUM wrappers, VRAM allocation, screenshots, embedded-graphics adaptation, and a VFPU interface/assembler-oriented layer. Applications issue rendering work through these APIs against PSP display/VRAM constraints. Architecture-defining paths are psp/src/sys/gu.rs, psp/src/vram_alloc.rs, and psp/src/vfpu.rs.
Build and Packaging Pipeline
cargo-psp is the principal host-side entry point, invoked as cargo psp. It orchestrates Cargo builds for the PSP MIPS target, produces PRX/module output, repairs imports where needed, creates metadata, and packages an installable EBOOT.PBP. Main command behavior and metadata schema reside in cargo-psp/src/main.rs; standalone packaging stages are cargo-psp/src/bin/prxgen.rs, cargo-psp/src/bin/pack-pbp.rs, and cargo-psp/src/bin/mksfo.rs.
Native Unwinding Boundary
Unwinding support depends on bundled PSP-specific libunwind static archives, integrated by the runtime build script. This is a native build/link boundary required for panic = "unwind" rather than a normal Rust-only dependency. Relevant assets are psp/build.rs, psp/libunwind.a, and libunwind/Makefile.
Delivery, Examples, and Verification
Example crates are executable integration clients of the SDK and packaging command, ranging from minimal modules to graphics and networking workloads: examples/hello-world/src/main.rs, examples/cube/src/main.rs, and examples/paint-mode/src/main.rs. CI builds and validates binaries, including PPSSPP-oriented test execution and screenshot/graphics checks, through ci/concourse/concourse.yml, ci/Dockerfile-ppsspp, and ci/tests/src/main.rs. External runtime targets are custom-firmware PSP hardware or PPSSPP; optional developer tooling includes PSPLink, pspsh, and GDB.
Main entry points: lib.rs Runtime core · main.rs cargo psp · Cargo.toml psp crate · mod.rs sys namespace
Components 22
PSP Runtime
Target-side no_std SDK.
- psp crate · Application-facing SDK for PSP binaries and plugins.
psp/Cargo.toml - Runtime core · Exports module, debug, math, graphics, and test APIs.
psp/src/lib.rs - Allocation support
psp/src/alloc_impl.rs - Panic support
psp/src/panic.rs
PSP ABI & Graphics
Firmware bindings and rendering facilities.
- sys namespace · Low-level firmware service boundary.
psp/src/sys/mod.rs - Kernel threads
psp/src/sys/kernel/thread.rs - GE services
psp/src/sys/ge.rs - GU rendering API · Direct graphics-unit command interface.
psp/src/sys/gu.rs - VRAM allocator · Manages PSP display memory constraints.
psp/src/vram_alloc.rs - VFPU layer · Vector processor interface and assembler support.
psp/src/vfpu.rs
Build & Packaging
Host-side Cargo subcommand pipeline.
- cargo psp · Builds PSP targets and orchestrates artifact generation.
cargo-psp/src/main.rs - PRX generation · Produces module/PRX output and repairs imports.
cargo-psp/src/bin/prxgen.rs - SFO metadata
cargo-psp/src/bin/mksfo.rs - EBOOT.PBP packer · Creates installable PSP packages.
cargo-psp/src/bin/pack-pbp.rs
Native Unwinding
Bundled PSP native link support.
- Runtime build script · Links PSP-specific unwinding archives.
psp/build.rs - Bundled libunwind · Required for panic unwinding.
psp/libunwind.a - libunwind build
libunwind/Makefile
Examples & CI
Integration clients and validation.
- Example applications · Hello-world, cube, and paint-mode PSP programs.
examples/hello-world/src/main.rs - CI validation · Builds binaries and runs PPSSPP-oriented graphics checks.
ci/concourse/concourse.yml - PPSSPP tests · Emulator-driven validation client.
ci/tests/src/main.rs - PSP hardware / PPSSPP · Custom-firmware hardware or emulator execution environment.
Other components
- Cargo workspace · Coordinates runtime and cargo subcommand crates.
Cargo.toml
Connections 25
- Cargo workspace → psp crate: includes
- Cargo workspace → cargo psp: includes
- psp crate → Runtime core: exposes
- Runtime core → Allocation support: uses
- Runtime core → Panic support: uses
- Runtime core → sys namespace: wraps
- sys namespace → Kernel threads: contains
- sys namespace → GE services: contains
- Runtime core → GU rendering API: provides
- GU rendering API → GE services: submits commands to
- GU rendering API → VRAM allocator: uses
- Runtime core → VFPU layer: provides
- Runtime build script → Bundled libunwind: links
- libunwind build → Bundled libunwind: builds
- psp crate → Runtime build script: runs
- Example applications → psp crate: uses SDK
- cargo psp → PRX generation: generates PRX
- cargo psp → SFO metadata: creates metadata
- PRX generation → EBOOT.PBP packer: supplies module
- SFO metadata → EBOOT.PBP packer: supplies metadata
- Example applications → cargo psp: built by
- EBOOT.PBP packer → PSP hardware / PPSSPP: deploys EBOOT.PBP
- CI validation → cargo psp: builds with
- CI validation → PPSSPP tests: runs
- PPSSPP tests → PSP hardware / PPSSPP: executes on emulator