Interrupt system implemented, some new programs.

This commit is contained in:
Anachronaut
2026-08-15 00:44:13 -04:00
parent 638b68b25c
commit 6d1966d500
79 changed files with 2778 additions and 88 deletions
+27
View File
@@ -26,6 +26,30 @@
#error "Cannot preserve more Data Pointers than the CPU has."
#endif
// The bits of the Status register that mean something.
#define STATUS_CARRY 0x01 // An arithmetic result carried out of, or borrowed into, a byte.
#define STATUS_FAULT 0x02 // The CPU met a byte it could not decode, and stopped.
#define STATUS_INTERRUPT 0x04 // Hardware interrupts are enabled. Nothing reads this yet.
#define STATUS_HALT 0x80 // Execution has stopped, either from HALT or from a fault.
// What an interrupt puts on the Stack: the resume address, every Data Pointer, and
// every register the CPU has. The CALL frame leaves Q and DP3 alone, but that is a
// convention between a caller and the subroutine it called. An interrupt arrives in
// code that never agreed to give anything up, so it saves the lot.
#define INTERRUPT_FRAME_BYTES (2 + DATA_POINTERS * 2 + 4)
// Why the CPU stopped, when the Fault Flag is set. This is not something a program can
// read, and it is deliberately not a register: when a handler is installed, the vector
// it arrived through already says what happened, which is why the ISA has no fault
// cause. This exists for the case where nothing is installed and the machine is dead,
// so that whatever examines the wreckage can say something better than "it stopped".
typedef enum {
FAULT_NONE = 0,
FAULT_BAD_OPCODE, // A byte that does not decode to an instruction.
FAULT_NO_HANDLER, // Dispatched through a software vector with nothing in it.
FAULT_NO_DEVICE_HANDLER // A device interrupted, and its vector was empty.
} FaultCause;
// The struct containing the CPU registers.
typedef struct {
uint8_t A;
@@ -37,6 +61,9 @@ typedef struct {
uint16_t StackPointer;
uint8_t *Program;
uint8_t *Data;
// Set alongside the Fault Flag, and read only by whatever reports the stop.
uint8_t Fault; // A FaultCause.
uint8_t FaultVector; // Which vector was empty, when Fault is FAULT_NO_HANDLER.
} CPURegisters;
uint8_t executeOperation(uint8_t instruction, CPURegisters *cpu);