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
+39
View File
@@ -6,6 +6,37 @@
#include "io.h"
#include <stdio.h>
// One bit per port, so a device can ask for attention without anything having to poll
// it. Eight ports to the byte, low bit first.
#define INTERRUPT_LINE_BYTES 32
static uint8_t pendingInterrupts[INTERRUPT_LINE_BYTES];
void raiseInterrupt(uint8_t port) {
pendingInterrupts[port >> 3] |= (uint8_t)(1u << (port & 7));
}
void clearInterrupt(uint8_t port) {
pendingInterrupts[port >> 3] &= (uint8_t)~(1u << (port & 7));
}
int nextPendingInterrupt(void) {
// Lowest numbered port wins. This is a scan rather than a priority encoder, which
// means there is no arbitration to explain and a programmer can work out what
// happens next by reading the port numbers.
for (int group = 0; group < INTERRUPT_LINE_BYTES; group++) {
if (pendingInterrupts[group] == 0) {
continue;
}
for (int bit = 0; bit < 8; bit++) {
if (pendingInterrupts[group] & (1u << bit)) {
return group * 8 + bit;
}
}
}
return -1;
}
uint8_t OutputHandler(uint8_t DataByte, uint8_t Address) {
// This function sends the DataByte to the appropriate place based on the Port Address.
switch(Address) {
@@ -15,6 +46,14 @@ uint8_t OutputHandler(uint8_t DataByte, uint8_t Address) {
// Later, I'll want to use a buffer for this for performance, probably.
putchar(DataByte);
break;
case 0x10:
// A test device, and about the simplest one that can exist: writing to it
// puts its own line up. It stands in for the shape a real device has, where
// the CPU asks for something and is interrupted once the answer is ready,
// with the waiting taken out so that a test runs the same way every time.
// The byte written is ignored; only the asking matters.
raiseInterrupt(0x10);
break;
default:
// Writes to unused Output Ports are ignored.
return 1;