Skip to content

fix(mmce): session-death resilience -- distinct errno, visible bails, VCD retry, MX4SIO settle (HW batch S3/S5/S6/S7) - #248

Merged
NathanNeurotic merged 3 commits into
masterfrom
claude/mmce-resilience
Jul 21, 2026
Merged

fix(mmce): session-death resilience -- distinct errno, visible bails, VCD retry, MX4SIO settle (HW batch S3/S5/S6/S7)#248
NathanNeurotic merged 3 commits into
masterfrom
claude/mmce-resilience

Conversation

@NathanNeurotic

@NathanNeurotic NathanNeurotic commented Jul 21, 2026

Copy link
Copy Markdown
Owner

Four verified mechanisms from the MC-boot HW batch (10-agent triage, adversarially verified) — all pre-existing holes exposed by one degraded-MMCE session; none of yesterday's merges caused them:

  • S3 (art death): a misclassification, not a wedge. mmceman returned one bare -1 for six different open failures; OPL memoized every one as "file doesn't exist" for the session. New driver patch (applies at both pins, validated) makes only the card's explicit not-found return -ENOENT; the staging arm memoizes only on ENOENT — everything else takes the existing transient lane and art self-heals when the bus quiets. BDM/HDD branch untouched.
  • S5 ("GameID then nothing"): silent bails. Both launch bails now toast; the iso open gets a bounded poll-first retry (~0 ms healthy / ~2 s dead); LOGs carry path+code.
  • S6 (empty VCD page): one contended scan latched forever. Bounded ~15×2 s retry in the proven first-scan-sentinel shape, re-armed by L3, self-quiescing. Manual refresh works in the failed state again.
  • S7 (lime green): decoded — ee_core's pre-LoadElf marker; cdvdman's (deliberately untimed, untouched) wait for the MX4SIO SD, starved by an MMCE GameID switch still in flight through the IOP reboot on the shared SIO2. mmceSendGameID is tri-state, remembers its target slot, and the SDC leg only runs a 5 s settle gate — warn-and-launch-anyway on expiry, never a block. Busy-bit-less firmware exits immediately on presence (no stall).

Companion PRs from the same batch: #247 (S4 interlaced-PNG art), claude/hdd-coexist (S1/S2 APA+ATA).

Builds clean (incl. lang regen for the one appended label). HW-pending: the same session recipe that produced the batch.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved MMCE cross-device launches by polling GameID settling (up to a timeout) and warning if confirmation isn’t reached.
    • Added bounded retries and state resets for MMCE VCD rescan failures.
    • Refined error handling to better separate “not found” (missing card/file) from transient I/O failures, reducing stale virtual-card access.
  • User Experience
    • Added clearer on-screen warnings for MMCE port detection, GameID unsettled, and ISO/open access failures.
  • Internationalization
    • Added a new localized message for the “GameID unsettled” warning.

…aunch bails, VCD-scan retry, MX4SIO settle gate (HW batch S3/S5/S6/S7)

Four verified mechanisms from the MC-boot HW batch triage (adversarially CONFIRMED/PLAUSIBLE), all
pre-existing holes EXPOSED by one degraded-MMCE session -- none of the 07-20 merges caused them:

S3 -- ART DEATH IS A MISCLASSIFICATION, NOT A WEDGE. mmceman's mmce_fs_open returned ONE bare -1 for
six different failures (fd-pool exhausted, three packet timeouts, garbled reply, AND the card's
genuine not-found). OPL's staging arm mapped every failed open to ERR_BAD_FILE = memoized permanently
absent on the fail-epoch -- so a rapid-nav contention storm branded every browsed game's art
"nonexistent" for the whole session. FIX, two halves that land together: a new mmceman patch
(mmceman-fs-open-enoent.patch, applied by BOTH build scripts; same content applies at both pins --
validated) makes ONLY the card's explicit bad-fd reply return -ENOENT; and the staging arm now
memoizes ONLY on errno==ENOENT, everything else takes the existing transient lane (ERR_FILE_IO,
lazy once-per-generation re-probe) so art SELF-HEALS when the bus quiets. Generic loose-file branch
(BDM/HDD) untouched. If the newlib errno glue is ever unfaithful, worst case is a bounded re-probe.

S5 -- "DOES GAMEID AND THEN NOTHING" WAS A SILENT BAIL. GameID uses fd-less devctls (they work on a
degraded channel); the iso open after it failed and returned to the menu with only a LOG. Both launch
bails (slot-lost + iso-open) now guiWarning before returning, the iso open gets a bounded poll-first
retry (10x200ms -- ~0ms on a healthy card), and the LOG carries path+code (the #246 doctrine).

S6 -- ONE CONTENDED VCD SCAN LATCHED AN EMPTY PAGE FOREVER. vcdFillGameList cannot tell ABSENT from
CONTENDED (-1 both) and NOUPDATE then never rescanned. Bounded retry in the proven first-scan-sentinel
shape: ~15 passes at the ~2s cadence, re-armed by a fresh L3 toggle, self-quiescing on
success/expiry/card-removal. Also revives the manual refresh button in the failed state.

S7 -- LIME GREEN = ee_core's marker before LoadElf from cdrom0:, i.e. cdvdman waiting (deliberately
untimed, upstream design -- NOT touched) for the MX4SIO SD to enumerate. MX4SIO shares SIO2 with the
MMCE, and the cross-device GameID switch still in flight through the IOP reboot can starve that
enumeration. mmceSendGameID is now tri-state (-1 = switch sent, settle NOT confirmed; still truthy so
the mmce-launch callers keep their own settle), remembers the exact slot it targeted, and the SDC
launch leg alone gates on mmceGameIdSettle(5000) -- settled = presence answers AND busy clear-or-
UNAVAILABLE (requiring a readable busy bit would stall every firmware lacking that devctl). On expiry:
warn (new label, APPENDED at _base.yml end per the position rule) and LAUNCH ANYWAY -- mitigation,
never a gate. Other BDM transports don't share SIO2 and pay nothing.

Builds clean (make opl.elf + lang regen, exit 0). HW-pending: Nathan's rig, same session recipe.

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

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

MMCE handling now distinguishes missing files from transient errors, confirms cross-device GameID switches, retries failed VCD scans, reports launch failures, and applies the new mmceman error patch during installation.

Changes

MMCE reliability updates

Layer / File(s) Summary
MMCE error classification and patch installation
.github/patches/mmceman-fs-open-enoent.patch, .github/scripts/*.sh, src/textures.c
The mmceman patch maps explicit missing-file responses to -ENOENT; installation scripts apply it, and MMCE art loading maps ENOENT separately from other open errors.
GameID settling and launch handoff
include/mmcesupport.h, src/mmcesupport.c, src/bdmsupport.c, lng_tmpl/_base.yml
GameID targets are tracked and polled with bounded settling; MX4SIO launch handling reports an unconfirmed card-switch failure.
VCD retries and launch failure handling
src/mmcesupport.c
Failed VCD scans retry within a fixed budget, while missing ports and persistent ISO-open failures trigger warnings and VMC descriptor cleanup.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant bdmLaunchGame
  participant mmceSendGameID
  participant mmceGameIdSettle
  participant MMCEDevice
  participant GUI
  bdmLaunchGame->>mmceSendGameID: send startup GameID
  mmceSendGameID->>MMCEDevice: switch target device
  mmceSendGameID-->>bdmLaunchGame: failure
  bdmLaunchGame->>mmceGameIdSettle: probe for up to 5000 ms
  mmceGameIdSettle->>MMCEDevice: poll presence and busy state
  mmceGameIdSettle-->>bdmLaunchGame: settled or expired
  bdmLaunchGame->>GUI: show unsettled warning on expiry
Loading

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is specific and accurately reflects the PR’s main MMCE resilience changes, including errno handling, retries, and MX4SIO settle logic.
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/mmce-resilience

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

@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 several robustness improvements for MMCE support, addressing issues with contended bus states, transient failures, and cross-device launches sharing SIO2 (such as MX4SIO). Key changes include returning distinct -ENOENT errors on open failures, implementing a bounded retry mechanism for VCD scans, adding a post-GameID settle gate for MX4SIO, and ensuring that launch failures are visibly reported to the user. Additionally, texture loading now distinguishes between permanent and transient failures based on errno. The review feedback suggests explicitly including <errno.h> in src/textures.c to avoid relying on transitive headers, and resetting mmceGameIdTarget at the start of mmceSendGameID to prevent stale state polling.

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/textures.c
readFunction = &texReadMemBoundedFunction;
} else if (filePath) {
if (texShouldUseMemoryReader(filePath)) {
errno = 0;

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

To ensure codebase robustness and prevent potential compilation failures due to future SDK header refactorings, please explicitly include <errno.h> in src/textures.c since errno and ENOENT are now used in this file. While it might currently be transitively included by other headers, relying on transitive includes is discouraged.

Comment thread src/mmcesupport.c
Comment on lines 83 to 84
int mmceSendGameID(const char *startup, const char *protectMcPath, int vmcSlotMask)
{

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

To prevent stale state from a previous successful GameID switch being polled if a subsequent switch fails or is skipped, it is safer to reset mmceGameIdTarget[0] = '\0'; at the very beginning of mmceSendGameID.

Suggested change
int mmceSendGameID(const char *startup, const char *protectMcPath, int vmcSlotMask)
{
int mmceSendGameID(const char *startup, const char *protectMcPath, int vmcSlotMask)
{
mmceGameIdTarget[0] = '\0';
References
  1. When handling removable media or card swaps, ensure that static loading or caching flags are reset when the media is removed or absent. This ensures that newly inserted media can properly re-register and load its assets.

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

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/bdmsupport.c`:
- Around line 1231-1241: The MX4SIO settle gate currently runs after the
Neutrino early-return path, so Neutrino launches bypass it. Update
bdmTryNeutrinoLaunch() to perform the same mmceSendGameID failure check and
mmceGameIdSettle(5000) warning flow before teardown and launch, restricted to
bdmDriverIsMx4sio(bdmCurrentDriver), while preserving the existing gate for
other launch paths.

In `@src/mmcesupport.c`:
- Around line 569-570: Update the mmceNeedsUpdate() branch handling
mmcePrefix[0] == '\0' to reset both mmceVcdScanFailed and mmceVcdScanRetries,
matching the existing reset in the list-update path so removed and reinserted
cards receive a fresh retry budget.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 98dda537-5a46-41e9-a311-3949bded6ee7

📥 Commits

Reviewing files that changed from the base of the PR and between 6348662 and bf280f3.

📒 Files selected for processing (8)
  • .github/patches/mmceman-fs-open-enoent.patch
  • .github/scripts/install_coherent_mmce.sh
  • .github/scripts/patch_stock_mmceman.sh
  • include/mmcesupport.h
  • lng_tmpl/_base.yml
  • src/bdmsupport.c
  • src/mmcesupport.c
  • src/textures.c
📜 Review details
⏰ Context from checks skipped due to timeout. (17)
  • GitHub Check: build-ps2dev-latest
  • GitHub Check: build-debug (eesio_debug, :v20250725-2)
  • GitHub Check: build-variants-ps2dev-latest (EXTRA_FEATURES=1, PADEMU=1)
  • GitHub Check: build-debug-ps2dev-latest (ingame_debug)
  • GitHub Check: build-debug (DTL_T10000=1, :v20250725-2)
  • GitHub Check: build-debug-ps2dev-latest (iopcore_ppctty_debug)
  • GitHub Check: build-debug-ps2dev-latest (iopcore_debug)
  • GitHub Check: build-variants-ps2dev-latest (EXTRA_FEATURES=0, PADEMU=0)
  • GitHub Check: build-debug (iopcore_ppctty_debug, :v20250725-2)
  • GitHub Check: build-debug (ingame_ppctty_debug, :v20250725-2)
  • GitHub Check: build
  • GitHub Check: build-debug (ingame_debug, :v20250725-2)
  • GitHub Check: build-variants (EXTRA_FEATURES=0, PADEMU=1)
  • GitHub Check: build-variants (EXTRA_FEATURES=1, PADEMU=0)
  • GitHub Check: build-debug (iopcore_debug, :v20250725-2)
  • GitHub Check: build-variants (EXTRA_FEATURES=0, PADEMU=0)
  • GitHub Check: build-variants (EXTRA_FEATURES=1, PADEMU=1)
🧰 Additional context used
🪛 Cppcheck (2.21.0)
src/mmcesupport.c

[style] 196-196: The function 'mmceGameIdSettle' is never used.

(unusedFunction)

🔇 Additional comments (7)
.github/patches/mmceman-fs-open-enoent.patch (1)

1-17: LGTM!

.github/scripts/install_coherent_mmce.sh (1)

60-73: LGTM!

.github/scripts/patch_stock_mmceman.sh (1)

56-65: LGTM!

src/textures.c (1)

625-641: LGTM!

include/mmcesupport.h (1)

30-32: LGTM!

src/mmcesupport.c (1)

29-35: LGTM!

Also applies to: 81-81, 157-209, 454-471, 574-584, 888-891, 986-1003

lng_tmpl/_base.yml (1)

1008-1009: LGTM!

Comment thread src/bdmsupport.c
Comment thread src/mmcesupport.c

@coderabbitai coderabbitai 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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/mmcesupport.c (1)

888-891: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Use an MMCE-specific warning for slot/port detection failures.

This path handles MMCE slot/port detection failure but displays _STR_ERR_FILE_INVALID, which can mislead users into troubleshooting the game file instead of the device. Use a dedicated localized MMCE/port error label here; keep the file-invalid label for the ISO-open failure path.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/mmcesupport.c` around lines 888 - 891, Update the warning call in the
MMCE slot/port detection failure path to use the dedicated localized MMCE/port
error label instead of _STR_ERR_FILE_INVALID. Leave _STR_ERR_FILE_INVALID
unchanged in the ISO-open failure path.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/mmcesupport.c`:
- Around line 888-891: Update the warning call in the MMCE slot/port detection
failure path to use the dedicated localized MMCE/port error label instead of
_STR_ERR_FILE_INVALID. Leave _STR_ERR_FILE_INVALID unchanged in the ISO-open
failure path.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: d5b6a321-3ccc-4bd2-8973-772194f9d8ce

📥 Commits

Reviewing files that changed from the base of the PR and between bf280f3 and 9301ea6.

📒 Files selected for processing (1)
  • src/mmcesupport.c
📜 Review details
⏰ Context from checks skipped due to timeout. (4)
  • GitHub Check: build-debug (iopcore_ppctty_debug, :v20250725-2)
  • GitHub Check: build-variants-ps2dev-latest (EXTRA_FEATURES=0, PADEMU=1)
  • GitHub Check: build-ps2dev-latest
  • GitHub Check: build
🔇 Additional comments (1)
src/mmcesupport.c (1)

29-35: LGTM!

Also applies to: 80-81, 157-160, 175-209, 454-471, 569-584, 986-1003

- Neutrino BDM leg gets the SAME MX4SIO settle gate as the native leg (CodeRabbit major -- real: it
  also sends the cross-device GameID and shares SIO2 through the IOP reboot).
- Card-gone with an empty failed VCD list now resets the retry budget in mmceNeedsUpdate's early
  return -- a reinserted card no longer inherits a dead VCD page (CodeRabbit major -- real edge).
- mmceGameIdTarget cleared at the top of every send: only a switch made by THIS call can be settled
  against (Gemini -- unreachable via the current sole consumer, taken as free hardening).
- Explicit <errno.h> in textures.c (Gemini -- transitively included, taken for robustness).

Builds clean.

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

@coderabbitai coderabbitai 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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/mmcesupport.c (2)

198-211: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Do not sleep past the requested settle timeout.

The waited <= timeoutMs condition still executes DelayThread(200 * 1000) after the final poll. With the current mmceGameIdSettle(5000) callers, this blocks for at least 5200 ms instead of the promised 5000 ms.

Proposed fix
-    for (int waited = 0; waited <= timeoutMs; waited += 200) {
+    for (int waited = 0; waited <= timeoutMs;) {
         if (fileXioDevctl(mmceGameIdTarget, 0x1, NULL, 0, NULL, 0) != -1) {
             int busy = fileXioDevctl(mmceGameIdTarget, 0x2, NULL, 0, NULL, 0);
             if (busy < 0 || (busy & 1) == 0)
                 return 0;
         }
-        DelayThread(200 * 1000);
+        if (waited == timeoutMs)
+            break;
+        int delayMs = timeoutMs - waited;
+        if (delayMs > 200)
+            delayMs = 200;
+        DelayThread(delayMs * 1000);
+        waited += delayMs;
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/mmcesupport.c` around lines 198 - 211, Update the wait loop in
mmceGameIdSettle so it never calls DelayThread after the requested timeout has
been reached; retain polling at 200 ms intervals while waited remains within
timeoutMs, but skip the final sleep when no time remains.

33-35: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Reset the VCD retry state during mmceInit().

These static fields survive mmceInit(), but mmceInit() only resets the game lists. Re-enabling MMCE or applying settings while the same card remains present can retain an exhausted retry budget and leave the VCD page at NOUPDATE until the user manually toggles it.

Proposed fix
     mmceVcdGameCount = 0;
     mmceVcdGames = NULL;
+    mmceVcdScanFailed = 0;
+    mmceVcdScanRetries = 0;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/mmcesupport.c` around lines 33 - 35, Reset mmceVcdScanFailed and
mmceVcdScanRetries at the start of mmceInit(), alongside the existing game-list
state reset. Ensure reinitialization restores the full VCD scan retry budget so
a previously exhausted scan does not remain in NOUPDATE.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/mmcesupport.c`:
- Around line 198-211: Update the wait loop in mmceGameIdSettle so it never
calls DelayThread after the requested timeout has been reached; retain polling
at 200 ms intervals while waited remains within timeoutMs, but skip the final
sleep when no time remains.
- Around line 33-35: Reset mmceVcdScanFailed and mmceVcdScanRetries at the start
of mmceInit(), alongside the existing game-list state reset. Ensure
reinitialization restores the full VCD scan retry budget so a previously
exhausted scan does not remain in NOUPDATE.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 475343a4-42f9-489e-b701-a60d8988a109

📥 Commits

Reviewing files that changed from the base of the PR and between 9301ea6 and 3c643c1.

📒 Files selected for processing (3)
  • src/bdmsupport.c
  • src/mmcesupport.c
  • src/textures.c
📜 Review details
⏰ Context from checks skipped due to timeout. (19)
  • GitHub Check: check-format
  • GitHub Check: build-debug-ps2dev-latest (ingame_debug)
  • GitHub Check: build-debug-ps2dev-latest (iopcore_debug)
  • GitHub Check: build-debug-ps2dev-latest (iopcore_ppctty_debug)
  • GitHub Check: build-variants-ps2dev-latest (EXTRA_FEATURES=1, PADEMU=1)
  • GitHub Check: build-variants-ps2dev-latest (EXTRA_FEATURES=0, PADEMU=1)
  • GitHub Check: build-variants-ps2dev-latest (EXTRA_FEATURES=0, PADEMU=0)
  • GitHub Check: build-debug (ingame_debug, :v20250725-2)
  • GitHub Check: build-debug (DTL_T10000=1, :v20250725-2)
  • GitHub Check: build-variants-ps2dev-latest (EXTRA_FEATURES=1, PADEMU=0)
  • GitHub Check: build-debug-ps2dev-latest (DTL_T10000=1)
  • GitHub Check: build-debug (iopcore_debug, :v20250725-2)
  • GitHub Check: build-debug (eesio_debug, :v20250725-2)
  • GitHub Check: build-variants (EXTRA_FEATURES=0, PADEMU=1)
  • GitHub Check: build-variants (EXTRA_FEATURES=1, PADEMU=0)
  • GitHub Check: build
  • GitHub Check: build-debug-ps2dev-latest (eesio_debug)
  • GitHub Check: build-variants (EXTRA_FEATURES=1, PADEMU=1)
  • GitHub Check: build-ps2dev-latest
🔇 Additional comments (3)
src/textures.c (1)

6-6: LGTM!

Also applies to: 626-642

src/mmcesupport.c (1)

87-87: LGTM!

Also applies to: 159-189, 426-430, 461-478, 576-591, 895-898, 993-1010

src/bdmsupport.c (1)

911-918: LGTM!

Also applies to: 1238-1247

@NathanNeurotic
NathanNeurotic merged commit 1e32316 into master Jul 21, 2026
61 checks passed
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