Take a device's line down when its status port is read

A device raises a line and something has to take it down. Two things did:
being interrupted, and being woken from WAIT with the Interrupt Flag down -
the second because a masked program has nowhere to dispatch to, so nobody
else would.

There was a third way to learn a device had finished and nothing answered
it. The documented idiom reads the status, branches out if the device is
already done, and only WAITs otherwise; on a disk quick enough to finish
before the first look, which is every disk here, the WAIT is unreachable.
The line then stood for the rest of the machine's life.

The program that leaves it standing never pays for it - it was masked
throughout. The bill arrives at whoever next sets the Interrupt Flag. The
boot chain reads the disk to load a program, leaves the line up, and hands
over; the loaded program is then interrupted on behalf of a read that
finished before it existed, through a vector table with no entry for a
device it never touched, and faults on the instruction after its SIF.

Found by running Examples/tune.asm through Once. It set up its whole sound
and died four bytes before its first note, which is why it was silent
rather than wrong - and why it looked like a sound bug for a while.

So reading the port that answers a device takes its line down, the same way
taking the byte already took the console's down. Disk and screen do it on
their status port. And a reset now clears every line, which is the sentence
the manual already makes about the vector table: a handler left behind aims
an interrupt into a program that is no longer running, and so does a line.

testPrograms/diskLineTest.asm pins it - the racy idiom, then SIF with no
handler installed anywhere. It faults without the fix.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
This commit is contained in:
Anachronaut
2026-08-29 22:15:02 -04:00
co-authored by Claude Opus 5
parent 62a657f1a7
commit 85329f13c3
9 changed files with 158 additions and 2 deletions
+69
View File
@@ -0,0 +1,69 @@
; diskLineTest.asm
; A device's line comes down when its status port is read.
; Written by Anachronaut
;
; ---- The idiom with the race in it ----
;
; This is the shape the manual gives for waiting on a device, and it has a hole. It reads the
; status, branches out if the device has already finished, and only WAITs otherwise. On a disk
; fast enough to finish before the first look - which is every disk here - the WAIT is never
; reached, and WAIT was the only thing that took the line down for a program with no handler.
;
; The line then stood for the rest of the machine's life. Nothing else was going to answer it:
; the program is masked and has nowhere to dispatch to. So the next program to set the
; Interrupt Flag was interrupted on behalf of a read that finished before it was loaded, and
; faulted on the instruction after the SIF.
;
; That is not a story about the disk. It is what happens to any program CosmOS loads, because
; the boot chain reads the disk to load it. Playing Examples/tune.asm through Once is how it
; was found: the program set its whole patch up and died four bytes before its first note.
;
; So reading the status takes the line down, the same way taking the byte takes the console's
; down. This program is the check on that: read the disk without ever waiting, then let
; interrupts in with no handler installed anywhere. If a line were standing, SIF would find it
; and there would be nothing to catch it.
#Program
start:
; Block 0, read.
RSTA
OUTA 0x20
OUTA 0x21
INIA 0x01
OUTA 0x22
waitDisk:
INA 0x23
INIB 0x01
AND
BRQ readDone ; Already finished, so the WAIT below never runs.
WAIT
BRI waitDisk
readDone:
; No handler is installed for anything, and none is installed below either. This is the
; instruction the fault used to land on.
SIF
INIA 0d110
OUTA 0x00
INIA 0d111
OUTA 0x00
INIA 0d32
OUTA 0x00
INIA 0d108
OUTA 0x00
INIA 0d105
OUTA 0x00
INIA 0d110
OUTA 0x00
INIA 0d101
OUTA 0x00
INIA 0d10
OUTA 0x00
HALT
#Vectors
Boot start