Commit 2af5efb
Add Platform SDK abstractions: 36+ high-level modules, 30 examples (#4)
* Add SDK platform abstractions: sync, cache, DMA, VFPU math, audio mixer, framebuffer, memory
Push reusable platform infrastructure into the SDK so every project benefits:
- psp::sync — Extract SpinMutex from debug.rs, add SpinRwLock, SPSC ring buffer, UncachedBox<T>
- psp::cache — Type-safe CachedPtr/UncachedPtr with flush/invalidate conversions
- psp::me::MeExecutor — High-level ME task submission with poll/wait and shared uncached state
- psp::dma — DmaTransfer handle with memcpy_dma/vram_blit_dma and sceDmac syscall bindings
- psp::simd — VFPU-accelerated Vec4/Mat4 math, color ops, easing functions
- psp::audio_mixer — Multi-channel PCM mixer with volume/panning/fade
- psp::framebuffer — DoubleBuffer, DirtyRect tracking, LayerCompositor
- psp::mem — Typed partition allocators (Partition2Alloc/Partition3Alloc) preventing ME pointer misuse
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add Phase 2 SDK abstractions: io, thread, input, time + Phase 1 bugfixes
Bugfixes:
- Fix MeExecutor::submit() race condition by storing real_task/real_arg
in dedicated MeSharedState fields instead of double-writing boot_params
- Fix audio_mixer volume mixing i32 overflow by using i64 intermediates
- Document sceDmacMemcpy synchronous behavior in dma.rs
- Remove unnecessary blanket #![allow(unsafe_op_in_unsafe_fn)] from simd.rs
New modules:
- psp::io - File (RAII), ReadDir iterator, read_to_vec, write_bytes, stat,
create_dir, remove_file, remove_dir, rename
- psp::thread - ThreadBuilder, JoinHandle, spawn() with closure trampoline,
sleep_ms, current_thread_id
- psp::input - Controller with press/release detection, analog deadzone
- psp::time - Instant, Duration, DateTime, FrameTimer
Enhanced modules:
- psp::sync - Add Semaphore and EventFlag kernel primitive wrappers
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add Phase 3 SDK abstractions: display, power, audio, dialog, net, wlan, callback + bugfixes
Code review fixes:
- Wrap thread trampoline in catch_unwind for panic safety
- Simplify DmaTransfer to DmaResult (remove fake async API)
- Add #[repr(C, align(64))] to MeSharedState for cache coherency
- Document DoubleBuffer::new() init requirement
- Add vec4_length and vec4_distance to VFPU simd module
New SDK modules:
- psp::display - vblank sync, framebuffer get/set
- psp::power - clock control, battery info, AC detection
- psp::audio - AudioChannel with RAII reserve/release
- psp::callback - one-call exit callback setup
- psp::dialog - blocking message/confirm/error dialogs
- psp::wlan - WiFi hardware status
- psp::net - init/term, AP connect, TcpStream, UdpSocket, DNS resolve
Update examples to use new SDK modules:
- clock-speed, file-io, time, wlan, audio-tone, msg-dialog
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add Phase 4 SDK abstractions: gu_ext, timer, usb, config, image, font + power extensions
New modules:
- psp::gu_ext — GU state snapshot/restore, 2D setup, SpriteVertex, SpriteBatch
- psp::timer — Alarm (one-shot closure trampoline) and VTimer (RAII wrapper)
- psp::usb — USB bus control and UsbStorageMode (RAII mass storage)
- psp::config — Binary key-value config persistence (RCFG format)
- psp::image — Hardware JPEG decode (sceJpeg*) and software BMP 24/32-bit decode
- psp::font — FontLib, Font, FontRenderer with VRAM glyph atlas (PsmT8 + CLUT)
Extended:
- psp::power — on_power_event (RAII callback), prevent_sleep, prevent_display_off
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add 6 SDK showcase examples and expand README Platform SDK docs
New examples demonstrating Phase 1-4 SDK modules: thread-sync (SpinMutex
+ spawn), input-analog (Controller deadzone), config-save (RCFG format),
timer-alarm (Alarm + VTimer), net-http (WiFi + TcpStream), system-font
(FontLib + FontRenderer + GU). README revised: "High-Level Utilities"
replaced with comprehensive "Platform SDK" section (30+ modules in 9
domain categories), examples table updated with 6 new entries, structure
description updated.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add Phase 5 SDK hardening: soundness fixes, correctness improvements, 6 new modules
Critical soundness fixes: UncachedBox Drop now calls drop_in_place, SpscQueue
Drop drains remaining items, PartitionAlloc tracks initialization state to
prevent UB on uninit Drop, Alarm restructured with AtomicU8 state machine
to eliminate interrupt-context allocation and TOCTOU race between Drop and
trampoline.
Medium correctness fixes: JoinHandle::join returns thread exit status,
dialog/connect_ap polling timeouts, config serialize overflow checks, power
callback cleanup on failure, callback registration error check, audio mixer
volume saturation, glyph atlas eviction bounds, SpriteBatch dcache flush,
sleep_ms overflow protection, removed dead mixer code.
Low-priority improvements: cached tick resolution const, deprecated
enable_home_button, Default impls, null-termination asserts, doc fixes,
remapf division-by-zero guard.
New modules: psp::http (RAII HTTP client), psp::mp3 (hardware MP3 decoder),
psp::osk (on-screen keyboard), psp::rtc (extended RTC operations),
psp::savedata (system save/load dialog), psp::system_param (system settings).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Replace deprecated enable_home_button() with setup_exit_callback() across all examples, add 4 new SDK examples
Migrate all 26 existing examples from the deprecated psp::enable_home_button()
to psp::callback::setup_exit_callback().unwrap(). Add 4 new examples showcasing
Phase 5 SDK modules: http-client (psp::http), savedata (psp::savedata),
osk-input (psp::osk), and rtc-sysinfo (psp::rtc + psp::system_param). Update
README code snippets and examples table accordingly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix CI: add -Zjson-target-spec for newer nightly toolchains
Post-January 2026 nightly builds destabilized custom JSON target specs
(rust-lang/rust#151534), requiring an explicit -Zjson-target-spec flag
when passing a .json path to cargo --target. Without this, cargo-psp
fails with "`.json` target specs require -Zjson-target-spec" in CI.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix soundness and correctness issues from AI code review
- audio.rs: Validate buffer length in safe output_blocking/output_blocking_panning
functions to prevent out-of-bounds reads by the PSP audio hardware. Store
AudioFormat on AudioChannel to compute required buffer size.
- audio_mixer.rs: Fix fade_out/fade_in duration capping at 256 frames by
switching fade_level/fade_step to 16.16 fixed-point arithmetic, allowing
accurate fades of any duration.
- power.rs: Delete callback UID via sceKernelDeleteCallback on drop to prevent
kernel resource leaks.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix CI: add pre-checkout cleanup to all workflow jobs
The gemini-review, codex-review, agent-review-response, agent-failure-handler
(pr-validation.yml) and create-release (main-ci.yml) jobs were missing
pre-checkout cleanup. When the ci job runs Docker containers that create
root-owned files in outputs/, subsequent jobs fail with EACCES when
actions/checkout tries to clean the workspace.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: address AI review feedback (iteration 2)
Automated fix by Claude in response to Gemini/Codex review.
Iteration: 2/5
Co-Authored-By: AI Review Agent <noreply@anthropic.com>
* fix: address AI review feedback (iteration 3)
- Fix JoinHandle::drop double-free: check thread completion via
sceKernelWaitThreadEnd before deciding whether to free the closure.
Previously, dropping an unjoined handle for a thread that already
finished would double-free the closure (trampoline freed it, then
drop freed it again).
- Fix audio mixer 1-sample silence gap on loop: remove `continue`
after resetting position to 0, so the current output frame reads
from position 0 instead of being skipped.
- Replace unsafe transmute with TryFromPrimitive in system_param:
language(), date_format(), and time_format() now use safe
try_from() conversion instead of transmute, preventing UB if
firmware returns an unexpected enum value.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: eliminate JoinHandle double-free race via shared ThreadPayload
Replace the raw closure pointer with a ThreadPayload struct containing
the closure and an AtomicBool flag. The trampoline sets the flag after
consuming the closure, and Drop checks it after terminating the thread.
This eliminates the race where a thread finishes between the zero-timeout
wait check and sceKernelTerminateDeleteThread, which previously caused
a double-free.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: validate thread name null termination in spawn_inner
Both Gemini and Codex flagged that safe code could pass a non-null-terminated
byte slice to sceKernelCreateThread, causing the kernel to read past the
buffer. Add validation that name ends with \0 before proceeding.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: validate stereo buffer length parity in submit_samples
Reject odd-length buffers in submit_samples to prevent an out-of-bounds
panic when the mixing loop reads stereo pairs (L,R) from a looping
channel that wraps around on a buffer with non-even length.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: AI Agent Bot <ai-agent@localhost>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: AI Review Agent <ai-review-agent@localhost>1 parent 2b510bb commit 2af5efb
79 files changed
Lines changed: 9750 additions & 259 deletions
File tree
- .github/workflows
- cargo-psp/src
- examples
- audio-tone/src
- clock-speed/src
- config-save
- src
- cube/src
- embedded-graphics/src
- file-io/src
- fontdue-scrolltext/src
- gu-background/src
- gu-debug-print/src
- hello-world/src
- http-client
- src
- input-analog
- src
- kernel-mode/src
- msg-dialog/src
- net-http
- src
- osk-input
- src
- paint-mode/src
- rainbow/src
- ratatui/src
- rtc-sysinfo
- src
- rust-std-hello-world/src
- savedata
- src
- screenshot/src
- system-font
- src
- thread-sync
- src
- timer-alarm
- src
- time/src
- vfpu-addition/src
- vfpu-context-switching/src
- wlan/src
- psp/src
- sys/kernel
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
188 | 188 | | |
189 | 189 | | |
190 | 190 | | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
191 | 201 | | |
192 | 202 | | |
193 | 203 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
137 | 137 | | |
138 | 138 | | |
139 | 139 | | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
140 | 150 | | |
141 | 151 | | |
142 | 152 | | |
| |||
224 | 234 | | |
225 | 235 | | |
226 | 236 | | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
227 | 247 | | |
228 | 248 | | |
229 | 249 | | |
| |||
301 | 321 | | |
302 | 322 | | |
303 | 323 | | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
304 | 334 | | |
305 | 335 | | |
306 | 336 | | |
| |||
380 | 410 | | |
381 | 411 | | |
382 | 412 | | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
383 | 423 | | |
384 | 424 | | |
385 | 425 | | |
| |||
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
16 | | - | |
| 16 | + | |
17 | 17 | | |
18 | 18 | | |
19 | 19 | | |
| |||
51 | 51 | | |
52 | 52 | | |
53 | 53 | | |
54 | | - | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
55 | 136 | | |
56 | 137 | | |
57 | 138 | | |
| |||
61 | 142 | | |
62 | 143 | | |
63 | 144 | | |
64 | | - | |
65 | | - | |
66 | 145 | | |
67 | 146 | | |
68 | 147 | | |
| |||
78 | 157 | | |
79 | 158 | | |
80 | 159 | | |
81 | | - | |
| 160 | + | |
82 | 161 | | |
83 | 162 | | |
84 | 163 | | |
85 | 164 | | |
86 | | - | |
| 165 | + | |
87 | 166 | | |
88 | 167 | | |
89 | 168 | | |
| |||
95 | 174 | | |
96 | 175 | | |
97 | 176 | | |
98 | | - | |
| 177 | + | |
99 | 178 | | |
100 | | - | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
101 | 190 | | |
102 | 191 | | |
103 | 192 | | |
| |||
115 | 204 | | |
116 | 205 | | |
117 | 206 | | |
118 | | - | |
| 207 | + | |
119 | 208 | | |
120 | 209 | | |
121 | 210 | | |
| |||
158 | 247 | | |
159 | 248 | | |
160 | 249 | | |
161 | | - | |
| 250 | + | |
162 | 251 | | |
163 | 252 | | |
164 | 253 | | |
| |||
234 | 323 | | |
235 | 324 | | |
236 | 325 | | |
237 | | - | |
| 326 | + | |
238 | 327 | | |
239 | 328 | | |
240 | 329 | | |
| |||
441 | 530 | | |
442 | 531 | | |
443 | 532 | | |
444 | | - | |
| 533 | + | |
445 | 534 | | |
446 | 535 | | |
447 | 536 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
529 | 529 | | |
530 | 530 | | |
531 | 531 | | |
532 | | - | |
533 | | - | |
534 | | - | |
| 532 | + | |
| 533 | + | |
| 534 | + | |
| 535 | + | |
| 536 | + | |
| 537 | + | |
| 538 | + | |
| 539 | + | |
| 540 | + | |
535 | 541 | | |
536 | 542 | | |
537 | 543 | | |
| |||
0 commit comments