From d33ea43bd7d8382618ab32395e654676941ad4ef Mon Sep 17 00:00:00 2001 From: Neil Webber Date: Sat, 11 May 2024 16:17:44 -0500 Subject: [PATCH] implement halt toggle --- interrupts.py | 16 +++++++++++++++- unibus.py | 2 +- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/interrupts.py b/interrupts.py index 1f80521..182f403 100644 --- a/interrupts.py +++ b/interrupts.py @@ -39,6 +39,15 @@ PendingInterrupt = namedtuple( 'PendingInterrupt', ('pri', 'vector', 'callback')) +# This is a delicious hack so that the console can force a processor halt. +# Notice the sneaky pri=8 (more than 0..7 in the architecture). +# This phony 'halt interrupt' is unmaskable and outside the architecture. +# Also note the (too clever?) use of the callback to invoke exit() +# Think of this as the equivalent of the HALT toggle on the physical panel + +ProcessorHalt = PendingInterrupt(8, 0, exit) + + # Interrupts are priority sorted by pri (duh), but (less obviously) # two interrupts with the same pri are further priority sorted by # vector, with lower vector being higher priority. This calculation @@ -80,10 +89,11 @@ def _qpri(pdi): # method simple_irq() bundles all this minutia up for the caller. class InterruptManager: - def __init__(self): + def __init__(self, cpu): self.pri_pending = 0 self.requests = [] self.condition = threading.Condition() + self.logger = cpu.logger # only thing needed from cpu def simple_irq(self, pri, vector): """Pend an interrupt at the given pri/vector.""" @@ -108,6 +118,10 @@ class InterruptManager: self.pri_pending = self.requests[-1].pri self.condition.notify_all() + def halt_toggle(self, msg=""): + self.logger.info(f"HALT TOGGLE, {msg=}") + self.pend_interrupt(ProcessorHalt) + # called by the processor, to get one pending interrupt (if any). # An InterruptTrap with the highest priority is returned, IF it is # above the given processor priority. Else None. diff --git a/unibus.py b/unibus.py index e65c241..d0f6fc0 100644 --- a/unibus.py +++ b/unibus.py @@ -33,7 +33,7 @@ class UNIBUS: def __init__(self, cpu): self.cpu = cpu - self.intmgr = InterruptManager() + self.intmgr = InterruptManager(cpu) self.logger = cpu.logger self.mmiomap = [self.__nodev] * (self.cpu.IOPAGE_SIZE >> 1)