Common: move the step refresh into the bridge - #194
Merged
Merged
Conversation
The shared GameConsoleEventBridge answered "step" with updateDebugInfo() alone, which ends at DebuggerController.updateDebugInfo() and touches the debug-info widget only — the memory monitor was never redrawn. Two of the three ports had quietly compensated for that in their own callback: app-gnome and app-web both ran `if (simulator.stepperEnabled) this.updateDebugger()`, so on both the monitor does follow a single step (measured on the web app: 6 of 24 steps change the dump, exactly the six STA writes). app-android had no such guard, so there a single step refreshed the registers and nothing else. The bridge could not simply refresh everything, and that is why the guard existed: Simulator.execute() dispatches "step" for every executed instruction, and a free run calls execute() 97 times per multiExecute() tick. So the guard moves into the bridge instead of being copied a third time — with the stepper on, multiExecute() returns early and one event is one press of Step; a free run stays on the throttled "multistep" path. updateDebugInfo is therefore gone from GameConsoleEventBridgeCallbacks and from all three ports, because nothing calls it any more. Android gains the memory refresh and loses an unthrottled per-instruction register redraw during a free run; GNOME and web behave exactly as before.
JumpLink
added a commit
that referenced
this pull request
Sep 22, 2026
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.
The claim, and what it is worth
Half of that holds. The bridge really did answer
"step"withupdateDebugInfo()alone, andthat path ends in
DebuggerController.updateDebugInfo(), which touches the debug-info widgetand nothing else. But the reach was wrong: two of the three ports had already re-implemented
the missing half in their own callback.
updateDebugInfocallbackif (simulator.stepperEnabled) this.updateDebugger()debuggerView.updateDebugInfo(simulator)Measured, not read: the web app built with
gjsify build --app browser, driven in headlessChrome — region
Display Memory ($0200-$05FF), Stepping mode on, 24 × Step through the starterprogram. On unmodified
mainthe dump already changed on 6 of those 24 steps, which isexactly the six
STA $0200,Xwrites among them. So the claim is false for Web, false for GNOMEby the same two lines, and true only for Android.
Top row
mainat7319f80d, bottom row this PR; left after Assemble, right after 24 x Step.Method, and why the bytes differ between the rows:
pr-194/README.mdon theassetsbranch.Why
"step"could not simply refresh everythingSimulator.execute()dispatches"step"for every executed instruction, not just for theStep button, and a free run calls
execute()97 times permultiExecute()tick. Anunconditional debugger refresh there would redraw the hex monitor ~97 times a tick. That is
what the
stepperEnabledguard buys: with the stepper on,multiExecute()returns early, soone event is one press of Step. A free run stays on the throttled
"multistep"path.The change
The guard moves into the shared bridge, so the rule is stated once instead of twice plus a gap:
GameConsoleEventBridgedecides on"step": stepper on →updateDebugger().updateDebugInfoleavesGameConsoleEventBridgeCallbacksand all three ports — nothingcalled it any more.
during a free run. GNOME and Web keep the behaviour they had.
No new cost class:
updateDebugger()runs throughDebuggerController.update, throttled to349 ms, and every port already drives that same path from
assemble-success,start,stop,reset,gotoandmultistep.What is not verified
deletion in all three, but no GUI was driven for them.
main(e855872e) in this worktreecrashes at launch on a
Medium_Phone_API_36emulator —TypeError: Cannot read properties of undefined (reading 'split')inclampChildClassName←AdwClamp._allocate←set_child,from
buildEditorScreen, wherenew ScrollView()reachesAdw.Clampwith noclassName.It reproduces on unmodified
main, so it is not this change; an APK built elsewhere from thepre-Android: drop Material-era leftovers #192 tree launches on the same emulator, and I did not isolate the difference further
(
@gjsify/adwaita-nativescriptis 0.51.1 andadw-clamp.jsbyte-identical in both trees).gjsify format --check,gjsify lint, andcheckfor core, common-ui, app-web, app-gnome andapp-android all pass;
@learn6502/coreand the web app build.🤖 Generated with Claude Code