Skip to content

feat(vcd): adaptive BDMA source seek -- Custom dir, boot device, then game device (FifthFox FR) - #244

Merged
NathanNeurotic merged 1 commit into
masterfrom
claude/bdma-adaptive
Jul 20, 2026
Merged

feat(vcd): adaptive BDMA source seek -- Custom dir, boot device, then game device (FifthFox FR)#244
NathanNeurotic merged 1 commit into
masterfrom
claude/bdma-adaptive

Conversation

@NathanNeurotic

@NathanNeurotic NathanNeurotic commented Jul 20, 2026

Copy link
Copy Markdown
Owner

The FR (FifthFox, maintainer-approved)

Adaptive BDMA should default to on, and it should be seeked in the order of: Custom Path, CWD, and finally game's device POPS/ folder... There should also be an indicator when these steps are taking place.

What ships

Seek order in vcdEquipBdma, which is also the fast order — the custom dir and boot device are on already-loaded stacks, so a hit costs a few open() probes and skips the family search's transport force-loads + 2s mount waits entirely (the second half of the "BDMA overboard" complaint, after #243's already-equipped fast path):

  1. the custom POPSTARTER.ELF's own folder (POPS_DEV_CUSTOM) — drivers beside the ELF;
  2. the boot (cwd) device's POPS/ (root derived from gBootDir);
  3. the existing game-device family search (byte-for-byte unchanged, gated on !found).

Already true: gBdmaApplyOnLaunch has been default ON since the MX4SIO→OSDSYS fix — the "default to on" ask was the shipped state.

Adversarially verified (SHIP)

Buffer math in-bounds (skip-not-truncate); identical probe shapes across tiers; the found gate airtight (pre-probe hit → zero force-loads; miss → family search unchanged); per-candidate pair atomicity; staging/commit untouched; POSIX-only rule kept. Verifier's one advisory taken (NULL-pointer relational compare → conforming C).

Deferred, with reasons (not silently dropped)

  • Progress indicator: the launch path blocks the GUI thread — an honest indicator needs frame-pump machinery. With perf(vcd): stop re-equipping BDMA on every launch when the card already carries a driver pair #243 + this, the slow path only runs on a one-time genuine variant switch; speed replaced the spinner. Revisit if HW still feels a pause.
  • "Don't launch when BDMA needed but missing": OPL can't reliably know a device needs the exFAT pair (a FAT32 stick launches fine on POPSTARTER's built-in driver) — gating on equip failure would block working FAT32 launches. Needs FS-type detection first; the dumb-handoff contract stands until then.

Reviewer notes

The pre-probe can also satisfy a Settings-screen equip from the boot/custom location (suffix encodes the variant, so the bytes are the intended pair either way). A Default-device user keeping drivers beside a boot-dir-resolved POPSTARTER falls through to the family search — no regression, just an FR coverage gap noted for the future.

Builds clean. HW-pending: FifthFox.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved detection of the appropriate BDMA module variant during startup.
    • Avoided unnecessary device scanning when the required modules are already available in configured locations.
    • Reduced redundant checks when locating BDMA modules, improving startup efficiency.

…oot device, then the game device (FifthFox FR)

FifthFox: "it should be seeked in the order of: Custom Path, CWD, and finally game's device POPS/
folder." Maintainer-approved. This is also the FAST order: the custom dir and the boot (cwd) device
live on ALREADY-LOADED stacks (we booted from one and are launching from the other), so a hit there
costs a few open() probes and skips the family search's transport force-loads and 2s bounded mount
waits entirely -- the second half of the "BDMA operations are overboard" complaint after #243's
already-equipped fast path.

Seek order in vcdEquipBdma:
1. the CUSTOM POPSTARTER.ELF's own folder (gPopstarterDevice == POPS_DEV_CUSTOM) -- a user who
   relocated POPSTARTER keeps its drivers beside it ("<elfdir>/usbd.irx.<suffix>");
2. the BOOT device's POPS/ folder (device root derived from gBootDir, e.g. "mmce0:/POPS/");
3. the existing game-device family search (unchanged, now gated on !found).

Adversarially verified (SHIP): buffer math in-bounds with skip-not-truncate guards; probe path shapes
identical across tiers; the found gate airtight (a pre-probe hit force-loads nothing; a miss runs the
family search byte-for-byte as before); src0/src1 pair atomicity per candidate; staging/commit
machinery untouched; POSIX-only IO rule kept. Verifier's one advisory taken: the NULL-pointer
relational compare in the separator pick rewritten to conforming C.

Also confirmed for the FR: gBdmaApplyOnLaunch has been default ON since the MX4SIO->OSDSYS fix --
FifthFox's "should default to on" was already the shipped state.

DEFERRED, with reasons (not silently dropped):
- progress indicator during equip: the launch path blocks the GUI thread, so an honest indicator
  needs frame-pump machinery; with #243 + this change the slow path now runs only on a genuine
  one-time variant switch, so speed replaced the spinner. Revisit if HW still feels a pause.
- "don't launch when BDMA is needed but missing": OPL cannot reliably know a device NEEDS the exFAT
  pair (a FAT32 stick launches fine via POPSTARTER's built-in driver) -- gating on equip failure
  would block working FAT32 launches. Needs filesystem-type detection first; the dumb-handoff
  contract (toast + launch anyway) stands until then.

Builds clean (make opl.elf, exit 0). HW-pending: FifthFox.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 0d43ce9d-b9cc-4335-b46c-454aa978c04e

📥 Commits

Reviewing files that changed from the base of the PR and between dd91c04 and 8f64830.

📒 Files selected for processing (1)
  • src/vcdsupport.c
📜 Recent review details
⏰ Context from checks skipped due to timeout. (20)
  • GitHub Check: build-debug-ps2dev-latest (eesio_debug)
  • GitHub Check: build-debug-ps2dev-latest (iopcore_ppctty_debug)
  • GitHub Check: build-debug (eesio_debug, :v20250725-2)
  • GitHub Check: build-debug-ps2dev-latest (ingame_debug)
  • GitHub Check: build-debug-ps2dev-latest (DTL_T10000=1)
  • GitHub Check: build-ps2dev-latest
  • GitHub Check: build-debug (iopcore_ppctty_debug, :v20250725-2)
  • GitHub Check: build-debug (ingame_ppctty_debug, :v20250725-2)
  • GitHub Check: build
  • GitHub Check: build-variants-ps2dev-latest (EXTRA_FEATURES=0, PADEMU=1)
  • GitHub Check: build-variants-ps2dev-latest (EXTRA_FEATURES=1, PADEMU=0)
  • GitHub Check: build-variants (EXTRA_FEATURES=0, PADEMU=1)
  • GitHub Check: build-variants (EXTRA_FEATURES=1, PADEMU=1)
  • GitHub Check: build-lang-ps2dev-latest
  • GitHub Check: build-lang
  • GitHub Check: build-debug-ps2dev-latest (ingame_ppctty_debug)
  • GitHub Check: build-debug (iopcore_debug, :v20250725-2)
  • GitHub Check: build-debug-ps2dev-latest (iopcore_ppctty_debug)
  • GitHub Check: build-debug (ingame_ppctty_debug, :v20250725-2)
  • GitHub Check: build-debug-ps2dev-latest (eesio_debug)
🧰 Additional context used
🪛 ast-grep (0.44.1)
src/vcdsupport.c

[error] 800-800: Use of an unbounded buffer function that can overflow the destination; use a size-bounded equivalent (fgets, strncpy/strlcpy, strncat/strlcat, snprintf).
Context: strcat(preBuf[npre], "/" POPS_FOLDER "/")
Note: [CWE-120] Buffer Copy without Checking Size of Input ('Classic Buffer Overflow').

(dangerous-buffer-functions-c)

🔇 Additional comments (1)
src/vcdsupport.c (1)

765-837: LGTM!

Also applies to: 868-868


📝 Walkthrough

Walkthrough

vcdEquipBdma() now probes likely POPS locations for the selected BDMA module pair before resolving SOURCE devices, avoiding transport loading and candidate enumeration when the pair is already available.

Changes

BDMA module pre-probe

Layer / File(s) Summary
Adaptive variant detection and fallback probing
src/vcdsupport.c
Selects the BDMA suffix, probes custom POPSTARTER and boot-device POPS paths for both modules, bypasses unnecessary SOURCE-device resolution when found, and short-circuits remaining candidate probes.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the adaptive BDMA source-seek order and main change, though it is a bit long.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/bdma-adaptive

Comment @coderabbitai help to get the list of available commands.

@NathanNeurotic
NathanNeurotic merged commit 270f1b1 into master Jul 20, 2026
61 checks passed

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces an adaptive seek order to locate BDMA variant files, checking the custom POPSTARTER.ELF's directory and the boot device's POPS/ folder before falling back to the standard game device search. This optimization avoids unnecessary transport force-loads and mount waits. The review feedback identifies potential path truncation issues due to small buffer sizes and recommends increasing the capacities of src0, src1, and preBuf to 256 bytes to safely accommodate longer custom POPSTARTER paths.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread src/vcdsupport.c
}

const char *suffix = vcdBdmaSuffix[mode];
char src0[96], src1[96];

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

With the introduction of the adaptive seek order, src0 and src1 can now hold paths derived from gPopstarterPath (which can be up to 256 characters). A limit of 96 bytes is sufficient for root-level device paths, but can cause silent truncation for deeply nested custom POPSTARTER paths. Increasing the buffer size of src0 and src1 to 256 bytes prevents truncation and aligns with other path buffers in this file.

    char src0[256], src1[256];

Comment thread src/vcdsupport.c
// one and are launching from the other), so a hit here costs a few open() probes and skips the
// family search's transport force-loads and bounded mount waits entirely.
{
char preBuf[2][96];

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Similarly to src0 and src1, preBuf should be increased to 256 bytes to accommodate the potentially long custom POPSTARTER paths from gPopstarterPath without skipping the search due to the bounds check n < (int)sizeof(preBuf[0]).

        char preBuf[2][256];

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant