Reboot, and the machine device that makes it possible
Until now the only way to restart was to stop the emulator and run it again, which meant the one thing the machine could not do was the thing Once was written for. The loop now closes without leaving it: > Once /System/Boot/bare.bin next start: /System/Boot/bare.bin, once > Reboot starting again stage two just this once: /System/Boot/bare.bin bare metal: no system, just this Writing 1 to port 0x13 asks the machine to start over. A PORT RATHER THAN A SERVICE, because a reset has to work when the system does not: something only askable through SWI would be unavailable in exactly the case that wants it most, and a program that owns the whole machine has no system to ask. It is device class 0x04, in the range kept for the machine rather than among the peripherals, because it is not one - it is not attached to anything and cannot be unplugged. WHAT A RESET REPEATS IS HOW THE MACHINE STARTED. Named an image, the emulator places it again; named none, the ROM is shadowed again and reads the disk. Anything else would mean a reset changed what the machine IS, which is the one thing a reset must not do. Both are tested. Taken between instructions, because a device cannot restart the machine from inside the instruction that asked: the CPU is part way through a step and its state is not yet anything a reset could leave behind consistently. The disk stays attached and keeps everything written to it - that is what warm means. The vector table is cleared, which is the one deliberate departure from leaving memory alone: a vector points into whatever installed it, and after a reset that program is not running, so a handler left behind would aim an interrupt at an address belonging to something gone. It is the argument CosmOS already makes at exit, applied to the machine. Reboot is 45 bytes, most of them the word it prints.
This commit is contained in:
@@ -27,6 +27,21 @@
|
||||
#define PORT_REFUSE 0x11
|
||||
#define PORT_MEMORY 0x12
|
||||
|
||||
// ---- Starting again ----
|
||||
//
|
||||
// Writing 1 here asks the machine to start over: whatever put the first instruction in
|
||||
// memory does it again, and the CPU begins where the boot vector points.
|
||||
//
|
||||
// A PORT RATHER THAN A SERVICE, because a reset has to work when the system does not.
|
||||
// Something that could only be asked for through SWI would be unavailable in exactly the
|
||||
// case that most wants it, and a program that owns the whole machine has no system to ask.
|
||||
//
|
||||
// What it does NOT do is unplug anything. The disk stays attached and its image keeps
|
||||
// whatever was written to it, which is what a warm restart means: the machine starts
|
||||
// again, the world it starts into does not.
|
||||
#define PORT_MACHINE 0x13
|
||||
#define MACHINE_RESET 0x01
|
||||
|
||||
// The disk answers on a block of four ports and interrupts on the first of them. A device
|
||||
// that spans more than one port raises its line on its base, which is the rule the
|
||||
// machine has not needed until now: the controller spans sixteen and never interrupts.
|
||||
@@ -121,6 +136,10 @@ uint8_t consoleReadByte(void);
|
||||
#define DEVICE_REGISTRY 0x01
|
||||
#define DEVICE_CONSOLE 0x02
|
||||
#define DEVICE_CONTROLLER 0x03
|
||||
// The machine itself, which is what a reset is asking. In the range kept for the machine
|
||||
// rather than among the peripherals, because it is not one: it is not attached to
|
||||
// anything and cannot be unplugged.
|
||||
#define DEVICE_MACHINE 0x04
|
||||
#define DEVICE_TEST 0x10
|
||||
#define DEVICE_REFUSE 0x11
|
||||
#define DEVICE_MEMORY 0x12
|
||||
@@ -213,6 +232,11 @@ uint8_t InputHandler(uint8_t Address);
|
||||
// must cost nothing when it does not.
|
||||
void serviceDevices(void);
|
||||
|
||||
// Set when something has written MACHINE_RESET, and taken by the loop that acts on it. A
|
||||
// request rather than an action, because a device cannot restart the machine from inside
|
||||
// the instruction that asked - the CPU is mid-step and its state is not yet consistent.
|
||||
int takeResetRequest(void);
|
||||
|
||||
void raiseInterrupt(uint8_t port);
|
||||
|
||||
void clearInterrupt(uint8_t port);
|
||||
|
||||
Reference in New Issue
Block a user