diff --git a/src/ide/ui.ts b/src/ide/ui.ts index aff5f82a..395a2a2f 100644 --- a/src/ide/ui.ts +++ b/src/ide/ui.ts @@ -2641,11 +2641,14 @@ export function getSaveState() { export function emulationHalted(err: EmuHalt) { var msg = (err && err.message) || msg; showExceptionAsError(err, msg); - projectWindows.refresh(false); // don't mess with cursor + // passive refresh: show the PC gutter arrow but don't move the cursor or + // repaint the current line, since the user may be typing + projectWindows.refresh(false); if (platform.saveState) { - const state = platform.saveState() + const state = platform.saveState(); showDebugInfo(state); - openRelevantListing(state); + // don't do this because it'll mess with user selected window! + //openRelevantListing(state); } } diff --git a/src/ide/views/editors.ts b/src/ide/views/editors.ts index cb3896cd..9d05d14a 100644 --- a/src/ide/views/editors.ts +++ b/src/ide/views/editors.ts @@ -624,8 +624,11 @@ export class SourceEditor implements ProjectView { this.editor.dispatch({ effects: [ currentPcMarker.set.of(line.line), - currentPc.effect.of(line.line), - // Follow the execution point when stepping/hitting breakpoints. + // Follow the execution point when stepping/hitting breakpoints. A + // passive halt (e.g. the program ends while the user is typing) only + // shows the gutter arrow, so it doesn't repaint/highlight the line + // out from under the user's cursor. + currentPc.effect.of(moveCursor ? line.line : null), ...(moveCursor ? [EditorView.scrollIntoView(this.editor.state.doc.line(line.line).from, { y: "center" })] : []), ] }); diff --git a/src/platform/vcs.ts b/src/platform/vcs.ts index 1e403f13..0b93a896 100644 --- a/src/platform/vcs.ts +++ b/src/platform/vcs.ts @@ -97,9 +97,13 @@ class VCSPlatform extends BasePlatform { self.probe.logNewFrame(); this.oldClockPulse(); // look for KIL instruction - if (Javatari.room.console.getCPUState().o == 0x02 && Javatari.room.console.onBreakpointHit != null) { - Javatari.room.console.onBreakpointHit(Javatari.room.console.saveState()); - //throw new EmuHalt("CPU STOPPED"); // TODO: requires browser reload + // Halt passively, like vcs.jt4, instead of stopping as a breakpoint would + // (which moves the cursor). Throw outside Javatari's clock, since it + // can't recover from an exception. + if (Javatari.room.console.getCPUState().o == 0x02 && self.isRunning()) { + self.pause(); + const pc = (Javatari.room.console.saveState().c.PC - 1) & 0xffff; + setTimeout(() => { throw new EmuHalt(`CPU halted at $${pc.toString(16)}`); }, 0); } } // intercept TIA end of line