From aacdf7bbb2596629e2e4fcbd50c2caec6b644239 Mon Sep 17 00:00:00 2001 From: Simen Svale Date: Tue, 30 Dec 2025 03:28:27 +0100 Subject: [PATCH] Add ensureStopped() before memory operations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit VICE stops emulation on first command and sends async events, but may not process the command itself until fully stopped. This adds an ensureStopped() mechanism that sends RegistersGet first to confirm VICE is in stopped state before memory read/write operations. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/protocol/client.ts | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/protocol/client.ts b/src/protocol/client.ts index f23d3a9..7652fce 100644 --- a/src/protocol/client.ts +++ b/src/protocol/client.ts @@ -350,6 +350,27 @@ export class ViceClient { }); } + // Ensure VICE is in stopped state before operations that require it + // On first command after connect, VICE stops emulation and sends async events + // but may not process the command itself. Calling this first ensures VICE is ready. + private stoppedConfirmed = false; + + private async ensureStopped(): Promise { + if (this.stoppedConfirmed && !this.state.running) { + return; // Already confirmed stopped + } + + // Send RegistersGet to trigger stop and wait for response + // This ensures VICE has fully stopped and is ready to process commands + debugLog("ensureStopped: sending RegistersGet to confirm stopped state"); + const body = Buffer.alloc(1); + body[0] = MemorySpace.MainCPU; + await this.sendCommand(Command.RegistersGet, body, ResponseType.RegisterInfo); + this.stoppedConfirmed = true; + this.state.running = false; + debugLog("ensureStopped: VICE confirmed stopped"); + } + // High-level commands async readMemory( @@ -380,6 +401,9 @@ export class ViceClient { ); } + // Ensure VICE is stopped before memory read + await this.ensureStopped(); + // Build request per official VICE docs: // side_effects(1) + start(2) + end(2) + memspace(1) + bankId(2) = 8 bytes const body = Buffer.alloc(8); @@ -428,6 +452,9 @@ export class ViceClient { ); } + // Ensure VICE is stopped before memory write + await this.ensureStopped(); + // Build request: side_effects(1) + start(2) + memspace(1) + length-1(1) + data(N) const body = Buffer.alloc(5 + dataBuffer.length); body[0] = 0; // No side effects @@ -478,6 +505,7 @@ export class ViceClient { // Exit command (0xaa) resumes execution await this.sendCommand(Command.Exit); this.state.running = true; + this.stoppedConfirmed = false; // Need to re-confirm stopped state after resume } async step(count = 1, stepOver = false): Promise {