From f2e26c18526c78e53075f6b8b6ba429f2a6581ca Mon Sep 17 00:00:00 2001 From: Anachronaut Date: Sat, 29 Aug 2026 14:59:15 -0400 Subject: [PATCH] Stop a pending reset outliving the reset it belonged to Reset out of picture.bin and CosmOS booted and then halted at once, having been told there was nobody at the keyboard. The button set two things: the machine's reset request, and a flag of the window's own that said "end the next console read, so a machine blocked on a key can get to the point where it notices". The second was only cleared when the console actually asked - and picture.bin never asks. It draws and halts. So the flag survived the restart and answered the NEXT machine's first read with the end of input, which for CosmOS means stop. There is one fact and it now lives in one place. The window asks whether a reset is still waiting rather than remembering that it asked for one, so the read ends only while a restart is genuinely on its way and goes back to normal the moment it has happened. The local flag is gone. Two pieces of state meaning one thing, one of them cleared on a path the other did not need - which is the same shape as the console's line editing flag surviving a second run, a fortnight ago. Worth noticing twice. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW --- Source/Emulator/io.c | 4 ++++ Source/Emulator/io.h | 4 ++++ Source/Emulator/voyager.c | 14 +++++++------- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/Source/Emulator/io.c b/Source/Emulator/io.c index 679b8ab..a821816 100644 --- a/Source/Emulator/io.c +++ b/Source/Emulator/io.c @@ -643,6 +643,10 @@ void consoleResetInput(void) { clearInterrupt(PORT_CONSOLE); } +int resetIsPending(void) { + return resetWanted; +} + int takeResetRequest(void) { int wanted = resetWanted; resetWanted = 0; diff --git a/Source/Emulator/io.h b/Source/Emulator/io.h index 68047ee..98dfb35 100644 --- a/Source/Emulator/io.h +++ b/Source/Emulator/io.h @@ -306,6 +306,10 @@ void serviceDevices(void); // the instruction that asked - the CPU is mid-step and its state is not yet consistent. int takeResetRequest(void); +// Whether one is waiting, without taking it. For anything that has to behave differently +// while a restart is on its way but is not the thing that performs it. +int resetIsPending(void); + // ---- The button on the front of the case ---- // // A machine has one, and a window is the case. Writing MACHINE_RESET is how a PROGRAM asks; diff --git a/Source/Emulator/voyager.c b/Source/Emulator/voyager.c index 44f4779..5b6fd0a 100644 --- a/Source/Emulator/voyager.c +++ b/Source/Emulator/voyager.c @@ -173,16 +173,11 @@ static void drainKeyboard(void) { // a bare metal program escapable - Once puts a demo in front of the next start and deletes // the request before jumping, so a demo that has taken the whole machine is one gesture from // the system coming back, rather than closing the window and opening it again. -static int resetPending = 0; - static void checkResetButton(void) { const int control = IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_CONTROL); const int shift = IsKeyDown(KEY_LEFT_SHIFT) || IsKeyDown(KEY_RIGHT_SHIFT); if (control && shift && IsKeyPressed(KEY_R)) { requestReset(); - // Remembered as well as asked for, so that a machine waiting on a key can be woken - // to go and notice it. See voyagerKey. - resetPending = 1; } } @@ -249,8 +244,13 @@ static int voyagerKey(int mayWait) { // // So the wait ends. The console treats that as the end of input, which it is for the // machine that is about to stop existing, and the reset puts the console's input back. - if (resetPending) { - resetPending = 0; + // + // ASKED OF THE REQUEST ITSELF rather than remembered here. A flag of its own outlived + // the reset it belonged to: a program that never read the console - picture.bin, say, + // which draws and halts - left it set, and the NEXT machine's first read came back as + // the end of input. CosmOS booted and stopped immediately, having been told there was + // nobody there. There is one fact and it lives in one place. + if (resetIsPending()) { return CONSOLE_GONE; } // Whatever is already waiting, however long ago it was typed. This is the answer to