diff --git a/README.md b/README.md index 776eebf..0fc99c9 100644 --- a/README.md +++ b/README.md @@ -47,12 +47,19 @@ The suite holds the two to being the same machine rather than taking it on trust the entire manifest through Voyager as well, with `--headless`, and requires it to satisfy every recorded result byte for byte. -**Control, Alt and Delete is the reset button.** On real hardware it is not a key at all - a -Voyager has a button on the case, and what a window has instead of a case is a gesture. Two +**Control, Shift and R is the reset button.** On real hardware it is not a key at all - a +Voyager has a button on the case, and what a window has instead of a case is a gesture. Three things follow from that. It must not be a key software might want, because a machine with a -keyboard has function keys and something will eventually have a use for them. And it must not -be reachable by accident, because restarting throws away everything in memory and a single -key that does that sits one mistake away from losing work. +keyboard has function keys and something will eventually have a use for them. It must not be +reachable by accident, because restarting throws away everything in memory and a single key +that does that sits one mistake away from losing work. And **it must be a gesture the host +has no opinion about**. + +That last one rules out the obvious answer. Control, Alt and Delete has meant this since 1981 +and cannot be used: it is a secure attention key, reserved by every serious operating system +so that it always reaches the system and never an application - precisely so a program cannot +imitate a login screen. On Windows an application cannot see it without a kernel driver, and +on Linux the desktop takes it. It is unavailable for the same reason it seemed right. It does exactly what writing to the machine port does: the machine starts the way it started, so the boot chain runs again and finds whatever the disk now says to run. diff --git a/Source/Emulator/voyager.c b/Source/Emulator/voyager.c index 5e7309a..6433123 100644 --- a/Source/Emulator/voyager.c +++ b/Source/Emulator/voyager.c @@ -140,8 +140,22 @@ static void drainKeyboard(void) { // memory, and a single key that does that sits one mistake away from losing work. Three keys // together are not pressed by mistake. // -// Control, Alt and Delete, which has meant this since 1981 and is the one gesture nobody has -// to be told the meaning of. +// Control, Shift and R. It was Control, Alt and Delete, which has meant this since 1981 and +// is the one gesture nobody has to be told the meaning of - AND WHICH CANNOT BE USED. +// +// It is a secure attention key. Every serious operating system reserves it so that it always +// reaches the system and never an application, precisely so that a program cannot imitate a +// login screen; on Windows an application cannot see it at all without a kernel driver, and +// on Linux the desktop takes it. That is not an oversight to work around - it is the same +// guarantee a reset button wants, being enforced one layer further down, and there is no +// call this program can make that would win the argument. +// +// So the gesture has to be one the host has no opinion about. Control and Shift with a +// letter is about as free as a combination gets: it is not window management, not a virtual +// terminal switch, and not a shortcut any desktop claims by default. +// +// If a platform does send a character for it, nothing comes of that either - whatever +// arrives is in memory that is about to be thrown away. // // What it does is what writing MACHINE_RESET does: the machine starts the way it started, so // the boot chain runs again and finds whatever the disk now says to run. Which is what makes @@ -152,8 +166,8 @@ static int resetPending = 0; static void checkResetButton(void) { const int control = IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_CONTROL); - const int alt = IsKeyDown(KEY_LEFT_ALT) || IsKeyDown(KEY_RIGHT_ALT); - if (control && alt && IsKeyPressed(KEY_DELETE)) { + 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.