ND-500 Interface Locking Mechanism¶
Corrected 2026-07-08 against the NPL sources and ND-30.013.02 (see ND500-BUS-INTERFACE-REFERENCE.md sections 3.2, 9 and 10, and the evidence in ND500-EVIDENCE-AND-CONTRADICTIONS.md). The former "High-Level TAG-IN Codes 8/9/16" content was an emulator invention and has been removed; see section "TAG-IN Code Reference" below for what replaced it. All IOX offsets in this document are OCTAL.
Overview¶
The InterfaceLocked state (bit 5 of the Status Register) is a critical hardware interlock in the PCB 3022 (ND-500 Interface) that prevents the ND-100 from modifying interface settings while the ND-500 is executing an operation.
This document provides a comprehensive reference for the InterfaceLocked state machine, documenting all lock triggers and unlock mechanisms.
Purpose¶
When the interface is locked (per the four-mode decode, ND-30.013.02 section 3.14): - ND-100 cannot load the control register (LCON5 does not decode while locked) - ND-100 cannot read or load the Memory Address Register (MAR) - ND-100 cannot load the status register (LSTA5 requires unlocked + test mode) - Still available while locked (not test): RSTA5, MCLR5, TERM5, RTAG5/LTAG5 (TAG loopback), WDAT (DATAX), SLOC5, CLKD5, UNLC5, RETG5
This prevents race conditions where the ND-100 might modify settings mid-operation, which could: - Corrupt data transfers - Cause undefined behavior - Create timing hazards between the two processors
State Machine¶
┌───────────────────────┐
│ UNLOCKED │
│ (InterfaceLocked=0) │
│ Interface ready │
│ ND-100 can modify │
│ all settings │
└───────────┬───────────┘
│
LoadControlRegister (IOX +5) with ActivateND500Operation (bit 2)
│
┌───────────▼───────────┐
│ LOCKED │
│ (InterfaceLocked=1) │
│ ND-500 running │
│ ND-100 blocked │
│ from modifications │
└───────────┬───────────┘
│
┌─────────────────────┼─────────────────────┐
│ │ │
Terminate ResetActivate Master Clear
(IOX +7) (TAG-OUT code 5) (IOX +6)
│ │ │
│ MicroclockStop │
│ (RETG5 bit 1) │
│ │ │
│ DUNL TAG-IN │
│ (code 14) │
│ │ │
└─────────────────────┼─────────────────────┘
│
┌───────────▼───────────┐
│ UNLOCKED │
└───────────────────────┘
Lock Trigger¶
Two lock triggers: CONTROL bit 2 (activate) and SLOC5¶
| Trigger | IOX Offset (oct) | Detail |
|---|---|---|
| LoadControlRegister (LCON5) with bit 2 set | +5 | "Activate ND-500 operation (and lock the communication)" - ND-30.013.02 section 3.1 |
| SLOC5 "Set locked" | +14 | write/command register; last step of SINTRAN's enable sequence |
Real SINTRAN activate-with-message path (ACT50, MP-P2-N500.NPL:3084-3086):
ACT50: 5MBBANK; T:=HDEV+LMAR5; *IOXT % MAR (MS part) := message bank
A:=X; *IOXT % MAR (LS part) := message address
A:=5; T+"LCON5-LMAR5"; *IOXT % CONTROL := 5 (int enable + ACTIVATE/lock)
Real SINTRAN enable sequence (MP-P2-N500.NPL:3089-3092):
A:=10; T:=HDEV+LCON5; *IOXT % test mode (so LSTA5 decodes)
A:=0; T+"LSTA5-LCON5"; *IOXT % clear status
A:=1; T+"LCON5-LSTA5"; *IOXT % leave test mode, enable interrupt
T+"SLOC5-LCON5"; *IOXT % SET LOCK via SLOC5
Other control register bits do NOT cause locking: - Bit 0 (Enable interrupt from ND-500) - No lock - Bit 3 (Test mode) - No lock - Bit 4 (ND-500 programmed clear; also clears DMA-error status bit 6) - No lock - Bit 5 (Disable TAG-IN decoding when locked) - No lock - Bit 6 (DMA error) - No lock - Bit 7 (Command chaining) - No lock
Unlock Mechanisms¶
1. Terminate (Normal Completion)¶
| Register | IOX Offset (oct) | Description |
|---|---|---|
| Terminate (TERM5) | +7 | Request the ND-500 to stop |
Semantics (verified, MP-P2-N500.NPL:2933-2946): TERM5 REQUESTS a stop. The ND-500 microcode acknowledges by releasing the interface lock; SINTRAN then POLLS RSTA5 in a bounded loop until 5ILOCK (bit 5) clears, and falls back to the 5MCST micro-stop on timeout ("Time out; master clear it").
Real SINTRAN code (XTER500):
T:=HDEV+RSTA5; *IOXT % read status
IF A BIT 5ILOCK THEN % ND-500 running, i/f locked
T+"TERM5-RSTA5"; *IOXT % terminate request
T+"RSTA5-TERM5"
FOR LOOPCOUNTER DO % wait for nd-500 to unlock i/f
FOR X:=-20 DO; OD
*IOXT
WHILE A BIT 5ILOCK
OD
FI
2. Micro-stop via the 5MCST sequence (RETG5 stop bit)¶
| Register | IOX Offset (oct) | Bit | Meaning |
|---|---|---|---|
| ReturnGate (RETG5) | +17 | 1 | STOP BIT (bit 0 = reverse tag bus) |
Semantics (ND-30.013.02 TST02/TST04): RETG5 A-bit1 sets the microcode stop bit (STATUS bit 9, 5CLOST, goes up); A-bit0 drives the reverse tag bus. There is NO evidence that RETG5 itself clears the interface lock - SINTRAN unlocks explicitly with UNLC5 FIRST:
Real SINTRAN code (5MCST, CC-P2-N500.NPL:213-217):
X5MCST: T:=HDEV
5MCST: T+UNLC5; *IOXT % UNLOCK
A:=40; T+"LCON5-UNLC5"; *IOXT % DISABLE TAG-IN DECODING
A:=2; T+"RETG5-LCON5"; *IOXT % set stop bit
Use Case: terminate timeout ("master clear it") and power-fail paths. Note this sequence does NOT touch the MCLR5 register.
3. UNLC5 - the explicit unlock register¶
| Register | IOX Offset (oct) | Description |
|---|---|---|
| UNLC5 "Release locked" | +16 | write/command; clears the lock directly |
Used by SINTRAN as the FIRST step of 5MCST (see mechanism 2) and by the hardware master-clear reference sequence (ND-30.013.02 section 3.15.1).
4. ResetActivate (TAG-OUT code 5, driven by the ND-500)¶
| Source | TAG-OUT code | Description |
|---|---|---|
| ND-500 microcode (TAG-OUT register on 5015) | 5 | "Reset activate" - releases the activate/lock |
TAG-OUT is the register the ND-500 MICROCODE drives toward the 3022 (ND-30.013.02 section 3.13); the ND-100 cannot send TAG-OUT codes. This is how the microcode itself releases the lock on completion. SINTRAN never does this - the formerly quoted "SINTRAN Code Pattern" writing LTAG5 was fabricated (SINTRAN never writes LTAG5 at all - see the master reference section 3.3).
5. DUNL TAG-IN strobe (code 14, written by the ND-100)¶
| Source | TAG-IN code | Description |
|---|---|---|
| ND-100 writes WTAG (offset +11) | 14 (16 oct) | DUNL "unlock" strobe decoded on the 5015 |
TAG-IN is written BY THE ND-100 into the 5015 ("The TAG-IN register on 5015 (I/O from ND-100)" - ND-30.013.02 section 3.12). The old description here ("the ND-500 can voluntarily release the lock by writing TAG code 14") had the direction inverted; that inverted model also lives in the current C# emulator (audit D01/D15). SINTRAN does not use this path.
6. Master Clear (MCLR5)¶
| Register | IOX Offset (oct) | Description |
|---|---|---|
| MasterClear (MCLR5) | +6 | Command strobe: restart microprogram at control-store address 0 |
Semantics (ND-30.013.02 sections 3.14, 6.3.1): executing the IOX is the action; no data word is involved (in unlocked+test mode this offset loads the DATA register instead). Available in both locked and unlocked NOT-test modes.
SINTRAN never issues MCLR5 - the OS stops the machine with the 5MCST sequence (mechanism 2). MCLR5 is used by test programs and the hardware master-clear reference sequence (ND-30.013.02 section 3.15.1).
Summary Table¶
| Unlock Mechanism | IOX (oct) | Code | Who uses it | Notes |
|---|---|---|---|---|
| Terminate | +7 | - | SINTRAN (XTER500, power-fail) | request; microcode releases lock; SINTRAN polls 5ILOCK |
| UNLC5 | +16 | - | SINTRAN (5MCST), test programs | direct unlock |
| 5MCST sequence | +16,+5,+17 | LCON5:=40, RETG5:=2 | SINTRAN | unlock + disable TAG decode + STOP BIT (5CLOST) |
| ResetActivate | - | TAG-OUT 5 | ND-500 microcode | normal completion release |
| DUNL TAG-IN | +11 | TAG-IN 14 | ND-100 diagnostics | strobe decoded on 5015; not used by SINTRAN |
| Master Clear | +6 | - | test programs / loader | microcode restart at CS address 0 |
Typical Operation Sequence¶
(Verified flow - master reference sections 5 and 7.)
1. SINTRAN builds a MESSAGE in mailbox memory [UNLOCKED]
|
v
2. SINTRAN loads MAR (bank, then address) [UNLOCKED]
and writes CONTROL := 5 (int enable + activate) [-> LOCKED]
|
v
3. ND-500 microcode DMA-fetches the message, [LOCKED]
executes MICFU, writes answer into the message
(N5STA status word, STOPR stop reason)
|
v
4. ND-500 stops/finishes; microcode releases [-> UNLOCKED]
the lock (TAG-OUT 5 reset-activate);
level 12 interrupt raised (ident 16 for twh 0)
|
v
5. SINTRAN ISR (5STDRIV): CLE5STATUS reads RSTA5, [UNLOCKED]
walks the message queue, dispatches on N5STA
(DECOMESS -> MCHANDLE for monitor calls)
|
v
6. SINTRAN activates the next waiting message [-> LOCKED]
(XACT500)
Register Reference¶
(ND-30.013.02 sections 3.1/3.2 - full maps in the master reference section 4.)
Status Register (read RSTA5, IOX +2)¶
| Bit | Name (SINTRAN symbol) | Description |
|---|---|---|
| 0 | InterruptEnabled | Interrupt enable status (not settable via LSTA5) |
| 1 | (unused) | - |
| 2 | ND500Busy | ND-500 operation in progress |
| 3 | ND500Finished | ND-500 operation completed |
| 4 | Error (5PAGF) | Inclusive OR of errors |
| 5 | InterfaceLocked (5ILOC) | Interface locked = ND-500 running (not settable via LSTA5) |
| 6 | DMAError (5DMAER) | DMA transfer error |
| 7 | PowerFault (5PFAIL) | Power fault executed by microprogram; stop bit set |
| 8 | ND500PowerOff (5POWOF) | ND-500 power is/has been off (latched) |
| 9 | ND500MicroClockStopped (5CLOST) | Microclock has stopped (not settable via LSTA5) |
| 10-14 | Stop reason | ND-500 stop reason field (values UNVERIFIED) |
| 15 | Control bit 15 | Mirrors CONTROL register bit 15 (not settable via LSTA5) |
Control Register (write LCON5, IOX +5)¶
| Bit | Name | Description |
|---|---|---|
| 0 | EnableInterruptFromND500 | Enable Level 12 interrupt |
| 1 | (unused) | - |
| 2 | ActivateND500Operation | Start operation (LOCKS interface) |
| 3 | TestMode | Test mode (changes the IOX decode) |
| 4 | ND500ProgrammedClear | ND-500 programmed clear; also clears status bit 6 (DMA error) |
| 5 | DisableTagInDecoding | Disable TAG-IN decode when locked |
| 6 | DMAError | DMA error |
| 7 | CommandChaining | Enable command chaining |
| 8-14 | ND500Operation | Operation field (400 used in the power-fail path) |
| 15 | (unused) | - |
Implementation Notes¶
C# Emulator (NDBusND500IF.cs)¶
The interface lock state is tracked via the StatusRegisterBits.InterfaceLocked flag:
// Check if locked
public bool isLocked => (statusRegister & StatusRegisterBits.InterfaceLocked) != 0;
// Lock on activate
if ((controlRegister & ControlWordBits.ActivateND500Operation) != 0)
{
statusRegister |= StatusRegisterBits.InterfaceLocked;
statusRegister |= StatusRegisterBits.ND500Busy;
statusRegister &= ~StatusRegisterBits.ND500Finished;
}
// Unlock mechanisms
statusRegister &= ~StatusRegisterBits.InterfaceLocked;
Unit Test Coverage¶
The following test methods verify the InterfaceLocked state machine. WARNING: tests marked (*) encode the OLD fabricated/inverted TAG model or the "only activate locks" claim and must be revised together with the code fixes in ND500-EMULATOR-DISCREPANCY-AUDIT.md (D01, D07, D11, D15):
| Test | Verifies |
|---|---|
Test_NDBusND500IF_InterfaceLocked_InitiallyUnlocked |
Initial state |
Test_NDBusND500IF_InterfaceLocked_LocksOnActivate |
Lock trigger |
Test_NDBusND500IF_InterfaceLocked_UnlocksOnTerminate |
Terminate unlock |
Test_NDBusND500IF_InterfaceLocked_UnlocksOnMicroclockStop |
(*) RETG5 does not unlock per evidence (D11) |
Test_TagOut_Code5_ResetActivate_UnlocksInterface |
(*) valid concept, wrong port in emulator (D15) |
Test_TagIn_Code14_DUNL_UnlocksInterface |
(*) direction inverted in emulator (D01/D15) |
Test_InterfaceLocked_UnlocksOnMasterClear |
Master Clear unlock |
Test_InterfaceLocked_StateMachine_FullCycle_* |
Full cycle tests |
Test_InterfaceLocked_MultipleUnlockMechanisms |
All mechanisms |
Test_InterfaceLocked_OnlyActivateLocks |
(*) SLOC5 also locks |
TAG-IN Code Reference¶
Direction (ND-30.013.02 section 3.12): the TAG-IN register on the 5015 is written BY THE ND-100 (WTAG, offset +11) and decoded on the 5015 into register strobes. TAG-OUT (section 3.13) is driven by the ND-500 microcode toward the 3022. SINTRAN uses NEITHER - the driver never reads RTAG5 or writes LTAG5 (master reference section 3.3). These codes matter for microcode loading, test programs and hardware-faithful emulation.
TAG-IN codes (4-bit, decoded on the 5015)¶
Names OCR-corrected from ND-30.013.02; positions reliable:
| Code (dec) | Name | Description |
|---|---|---|
| 0 | - | Not used |
| 1 | DICLK1 | Clock DATA-IN-1 register |
| 2 | DICLK2 | Clock DATA-IN-2 register |
| 3 | DUCLK | Clock DATA-OUT register (both halves) |
| 4 | WACLK | Clock control-store write-address (WA) register |
| 5 | BRKCLK | Clock BREAK register |
| 6 | TGCLK | Clock TAG-OUT register |
| 7 | CNTCLK | Clock CSCNT register |
| 8 | DIEN | Enable DATA-IN register to bus (CDB) |
| 9 | DUEN | Enable DATA-OUT register (least significant) |
| 10 | WAR | Read write-address register |
| 11 | BRKR | Read BREAK register |
| 12 | CNTR | Read CSCNT register |
| 13 | RESBRK | Reset break |
| 14 | DUNL | Unlock |
| 15 | EOUTEN | Enable data line driver |
Bits 0-3 carry the code; bit 4 is unused; bit 5 (octal 040) returns TAG-IN bits 0-4 (loopback for verification - read back via RTAG, offset +10).
Note: WACLK clocks the CONTROL-STORE write-address register (used in microcode loading), not the MAR - the earlier "copy DATA to MAR" side-effect claim was wrong.
TAG-OUT codes (3-bit, driven by ND-500 microcode)¶
| Code | Function |
|---|---|
| 0 | Read MAR |
| 1 | Write MAR |
| 2 | Read STATUS register |
| 3 | Write STATUS register |
| 4 | Read CONTROL register |
| 5 | Reset activate (releases the lock) |
| 6 | Read DATA register (and ND-100 memory) - DMA read |
| 7 | Write DATA register (and then into ND-100 memory) - DMA write |
Bit 3 = 0 means the operation targets the ND-100; bit 7 (MOST) selects the most/ least significant half of the 32-bit data registers.
The removed "High-Level TAG-IN Codes (8, 9, 16)"¶
Earlier versions of this document defined operational TAG-IN codes 8 = MonitorCallRequest, 9 = PageFaultRequest, 16 = OperationComplete with a process number in bits 8-11. These do not exist. Code 8 is DIEN, code 9 is DUEN, and the code field is 4 bits wide so 16 is unrepresentable. They were an emulator-internal invention (still present in NDBusND500IF.cs - audit D01) that conflated the hardware TAG strobes with the real signalling path: monitor calls and page faults reach SINTRAN as MESSAGES (MICFU + STOPR fields) dispatched by the level-12 driver - see the master reference sections 7.3-7.4 and 10.3.
Related Documentation¶
References¶
- PCB 3022: ND-500 Interface card (in ND-100 chassis)
- PCB 5015: ND-500 Control II card (in ND-500 chassis)
- IOX Base: thumbwheel-selected - 60, 1060, 660, 760 or 560 octal with ident 16, 116, 36, 114, 76 (ND-06.015.02 section D.13.1); per-CPU HDEV in SINTRAN
- Interrupt Level: 12 (SINTRAN driver level)
- Authoritative spec: ND500-BUS-INTERFACE-REFERENCE.md
Last Updated: 2026-07-08 Document Version: 2.0 (corrected against NPL sources and ND-30.013.02; removed fabricated high-level TAG protocol) Author: RetroCore Emulator Project