Conversation
Three device-agnostic improvements, independent of any one dumper. MMC3 / MMC6 battery-save dumping. The shared MMC3 save path read $6000 with the PRG-RAM chip off the bus, so it returned zero fill. Give MMC3 a dumpSave that brackets the read FME-7-style -- $A001 <- $C0 (enabled, write-protected) only for the read, then $40 to take the chip back off the bus -- so the SRAM is exposed for as short a time as possible. MMC6 (HKROM) shares mapper 4 but keeps its 1 KiB save inside the mapper at $7000-$73FF behind a master gate ($8000 bit 5) and per-512-byte-half enables ($A001): auto-detect it when $6000 reads uniform, fingerprint it by the driven zeros a single-half read-enable produces (a response open bus cannot mimic), gate detection on byte diversity rather than uniformity (open bus can read as a few capacitance-echo values), and consensus-read the 1 KiB to ride out a battery-weak array. Uniform-fill save warning. A save that reads back as a solid 0x00 or 0xFF block is the electrical signature of a chip that never reached the bus or an erased region, not real data -- surface the suspicion in the event log at dump time while keeping the bytes. Reload survival. Reloading with a serial port open could hang the navigation until the device was physically unplugged. Add Transport.closeNow() for a synchronous best-effort teardown from beforeunload/pagehide, and persist the last-connected device id so the page-load auto-reconnect resumes the device that was actually in use.
Per PR review: dumpSave's MMC6 code paths exited with $A001 <- 0x00, clearing the write-protect bit (6) and contradicting initMmc3's safe park ($40 — off the bus AND write-protected, so a variant that ignores the enable bit still can't be written). Close the MMC6 master gate first, then park PRG-RAM control at $40 on both the MMC6-detected and not-MMC6 exits: a no-op on a gated MMC6, the safe state on an MMC3 false-positive. Tests now assert every dumpSave exit leaves $A001 at $40 — the not-MMC6 path directly, and the MMC6-detected path via its final write value (the master gate forces $A001 to 0, which would otherwise mask a regression on that path).
Two more PR-review nits on the unload path: - The closeNow-less fallback in the unload handler floated transport.disconnect() (async) inside a synchronous try/catch, which cannot catch its rejection. Swallow it with .catch() to avoid an unhandled promise rejection during navigation. - closeNow()'s docstring claimed teardown happened "in one synchronous burst", but releaseLock + port.close() are deliberately deferred to a microtask (the stream locks aren't free until cancel/abort settle, so releaseLock would throw this tick). Reword to describe the actual synchronous-cancel/abort plus deferred-close behavior.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three device-agnostic improvements, independent of any one dumper.
$6000with the PRG-RAM chip off the bus and returned zero fill. Give MMC3 adumpSavethat brackets the read FME-7-style —$A001 <- $C0(enabled, write-protected) only for the read, then$40to take the chip back off the bus — so the SRAM is exposed for as short a time as possible. MMC6 (HKROM) shares mapper 4 but keeps its 1 KiB save inside the mapper at$7000-$73FFbehind a master gate ($8000bit 5) and per-512-byte-half enables ($A001): auto-detect it when$6000reads uniform, fingerprint it by the driven zeros a single-half read-enable produces (a response open bus can't mimic), gate detection on byte diversity rather than uniformity (open bus can read as a few capacitance-echo values), and consensus-read the 1 KiB to ride out a battery-weak array.0x00or0xFFblock is the electrical signature of a chip that never reached the bus or an erased region, not real data — surface the suspicion in the event log at dump time while keeping the bytes.Transport.closeNow()for a synchronous best-effort teardown frombeforeunload/pagehide, and persist the last-connected device id so the page-load auto-reconnect resumes the device that was actually in use.