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 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
This commit is contained in:
Anachronaut
2026-08-29 14:59:15 -04:00
co-authored by Claude Opus 5
parent adefce975b
commit f2e26c1852
3 changed files with 15 additions and 7 deletions
+4
View File
@@ -643,6 +643,10 @@ void consoleResetInput(void) {
clearInterrupt(PORT_CONSOLE);
}
int resetIsPending(void) {
return resetWanted;
}
int takeResetRequest(void) {
int wanted = resetWanted;
resetWanted = 0;
+4
View File
@@ -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;
+7 -7
View File
@@ -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