Interrupt core wired, and isa now fails on ADD

/ DINO / from dino-homebrew @ a05633d dino interrupts debugging scope alu

The interrupt core is wired. Eight new chips (U80-U87), two resistors, and seven lifts on old copper. With the IRQ line idle, every new path should sit in a state that recreates the old machine, so PROG_isa should still read 0xB4. Instead it reads 0x22 or 0x23, which is the subtest number of ADD (34) or SUB (35). Everything before ADD passes. The wiring is right as far as I can see, and I haven’t found the cause yet.

The ‘05 became a 7406N

The serial card needs one open-collector inverter to turn the 16550’s active-high INTR into a pull on the shared, active-low IRQ line. I didn’t have a ‘05. I had a 7406N, which is the same pinout, so U104 on the serial card is now a 7406N in the schematic too. The netlist didn’t change and ERC didn’t change.

The 7406N is standard TTL, so it costs a bit:

74LS057406N
Input low current0.4 mA1.6 mA
Supply current, max6.6 mA51 mA
Output sink8 mA40 mA
Output rating5.5 V30 V

The numbers come from TI’s datasheets. The extra 45 mA or so goes into the power budget for the PCB.

Wiring it one wire at a time

I wired the lifts first, then power and straps on every chip before any signal crossed them, then the logic, one wire and one beep at a time. Working from the full landing list makes me speed up and miss things. One wire, one beep is slower and I didn’t lose a wire.

The seven lifts:

Old pinWas onNow driven by
U28.4GNDU84.9, INJECT
U36.1PC_UPU81.8, PC_UP gated by ~INJECT
U61.3ENDU82.6, END OR ACCEPT
U49.3, .4, .7, .8U48 flag outputsU87, the POPF mux

The interrupt logic (U80-U84) and the K buffer (U85, strapped to 0x90) went on a new board at the top left of the machine. Nothing comes into it from the top or the left. The IRQ line from the serial card will be a jumper of about 15 inches, which isn’t wired yet.

The two flag chips went where their wires are. U86 drives the flags onto MDR, so it’s in the last free row of the registers board, which carries MDR, one board up from the flags register. U87 sits in the flags path, so it took the last free spot on the ALU board.

Where the two flag chips ended up. U86, the PUSHF buffer, sits in the last free row of the registers board, right above the ALU. U87, the POPF mux, took the last free spot on the ALU board's top row, next to the flags register. The interrupt logic and U85 are on a new board out of frame, top left.
Where the two flag chips ended up. U86, the PUSHF buffer, sits in the last free row of the registers board, right above the ALU. U87, the POPF mux, took the last free spot on the ALU board’s top row, next to the flags register. The interrupt logic and U85 are on a new board out of frame, top left.

isa reads 0x22 or 0x23

For the first few runs I read 0x44 and 0x43 off the LEDs, and spent a while on LDCX and STBX before I realised I was counting the LEDs wrong. The real readings are 0x22 and 0x23, and they alternate run to run.

Here’s what I’ve ruled out so far:

SuspectTestResult
New ~RESET wire picking up runts (it lands on U49.1, the flags clear)pulled itsame failure
New ~CLK wire to U83 ringing onto U49 and U36pulled itsame failure
CLK stub before R29looked at itunder 2 inches
Loose ALU operand wires near where I tapped Wbeeped U45.2/.5/.6/.9 to U38 under pressureall good
K buffer U85 enabling when it shouldn’tscope, falling edge on U83.6, SINGLEnever fires
PUSHF buffer U86 enabling when it shouldn’tscope on U86.19, then U86 strapped offfires (see below), still fails with U86 off
U87 select line glitchingscope on U87.1never fires
U87 too slow in the flags pathscope on Z in and out of U87 and U49’s clock, triggered on HALT18 ns through U87, about 344 ns of margin
Something too slow at 1.024 MHzran at 500 kHzstill 0x22

The useful capture was the last scope one. I triggered on HALT rising, so the window looked back over the failing compare. Z never goes high for the CPI that checks SUB’s result. The flag gets through U87 and into U49 fine. The ALU really is saying “not equal”, so the value in A after SUB is wrong, or the compare’s operand is. The fault is in the datapath.

Triggered on HALT rising (yellow, right edge) after isa failed on SUB, looking back 26 us. Magenta is Z going into U87, green is Z coming out, cyan is U49's clock. The two Z traces fall together, 18 ns apart, and Z never comes back high for the final compare. The flag path is fine; the ALU said not equal.
Triggered on HALT rising (yellow, right edge) after isa failed on SUB, looking back 26 us. Magenta is Z going into U87, green is Z coming out, cyan is U49’s clock. The two Z traces fall together, 18 ns apart, and Z never comes back high for the final compare. The flag path is fine; the ALU said not equal.

Halving the clock didn’t help, and the failure moves between two neighbouring subtests. My best guess is two drivers fighting over one bus line, which leaves it at a middle voltage that reads randomly. I haven’t shown that yet.

U86’s enable glitches, and it doesn’t matter yet

U86.19 (~FLAGS_OUT, from U70.10) goes low for about 46 ns, 68 ns after a CLK rise, while isa runs. isa never runs PUSHF, so nothing should enable U86. Before this build U70.10 drove nothing, so a glitch there didn’t matter. It’s probably skew between the three microcode EEPROMs briefly decoding a bank-1 code. I haven’t measured that. With U86 strapped off, isa still fails the same way, so this isn’t the fault. It still needs gating before PUSHF can be trusted.

U86.19, the PUSHF buffer's enable (magenta), dropping low for about 46 ns, 68 ns after a CLK rise (cyan), during an isa run that never executes PUSHF. Before this build that decoder output drove nothing.
U86.19, the PUSHF buffer’s enable (magenta), dropping low for about 46 ns, 68 ns after a CLK rise (cyan), during an isa run that never executes PUSHF. Before this build that decoder output drove nothing.

Still open