ENNS0 LU 2240B device pin - what ENNS0 waits on and why it never wakes (2026-07-23)¶
Follow-up to ROOT-CAUSE-ENNS0-HANGS-INPUT-WAIT-LU2240B-2026-07-23.md. Static, read-only
decode of Installation\Communication\Ethernet\x\encos-err-i-b01.brf (MAIN=ENNS0 @031655),
cross-checked against Reference-Manuals\ND-860228-2-EN SINTRAN III Monitor Calls.md,
SINTRAN\OS\00-SINTRAN-ARCHITECTURE-OVERVIEW.md, and RetroCore NDBusEthernetII.cs.
[V]=VERIFIED (decoded bytes / read manual). [I]=INFERRED. [OPEN]=undecidable statically.
Tools reused (not rebuilt): tools\brf_link.py, tools\nd100dis.py, tools\dumpwords.py,
tools\symdump.py.
TL;DR¶
[V]MON identities confirmed against the manual: MON 322 = GSGNO GetSegmentNo; MON 124 = PRSRV ForceReserve(DeviceNo, IOflag, RTProgram, Stat); MON 125 = PRLS ForceRelease. PRSRV works only on peripheral devices and semaphores (manual line 8967).[V]LU 2240B is not a literal in ENNS0. The only002240word in the whole image is the instructionSTZ -96,Xat 030327 (false match);103356appears nowhere. Both the LU number and the datafield address are runtime values - confirmed, not fabricated.[V]Datafield 103356B lands in the POF resident range 100000-110000B, which00-SINTRAN-ARCHITECTURE-OVERVIEW.md(sec 5.3) labels "Error device, line printers, SINTRAN communication, SIBAS internal devices." So LU 2240B's datafield is a SINTRAN communication / internal-device datafield - NOT a terminal, disk, or ordinary peripheral. This is the strongest single locator we have.[I, strong]LU 2240B is the SINTRAN Ethernet-interface communication device (the "Ethernet Interface datafield" the install prereq ND-210580 p1 requires). ENNS0 force-reserves its input part and blocks reading it.[V, NEW]resume-P030440sits on the PRSRV-returned-NONZERO branch, not the OK branch (see section 2). This reframes the hang and is the key new fact this pass adds.[V]The routine reached from the blocked frame (JPL I *12@030440 -> pointer word@030452 =146547) is outside the ENNS0 image (image occupies 001756B..073116B; 0146547B is above it). It is an external/shared (RTCOMMON-class) routine, not ENNS0 code.- Fix direction: leading candidate is an emulator gap - nothing ever delivers a SINTRAN device INPUT on LU 2240B - but a live single-step is required to close it decisively (section 5). Do NOT ship a fix on the static read alone.
1. The verified instruction path (Task 1 + 2)¶
From nd100dis.py, POSU startup body (execution order; all opcodes [V]):
030375 153322 MON 322 ; [V] GSGNO GetSegmentNo ; A -> STA -118,B
030376 004612 STA -118,B
...
030405 045042 LDA I *42 =030447 ; param staging for the reserve
030406..030426 (compute DeviceNo/IOflag param block; DD MGRE byte-extract idiom)
030426 044607 LDA -121,B ; A = DeviceNo argument for PRSRV
030427 153124 MON 124 ; [V] PRSRV ForceReserve(DeviceNo, IOflag, RTProgram, Stat)
030430 004616 STA -114,B ; save returned Stat
030431 044616 LDA -114,B ; A = Stat
030432 131012 JAZ 030444 ; [V] if Stat==0 (OK) -> jump to OK path @030444
; if Stat!=0 (error) -> fall through @030433
--- PRSRV-NONZERO (error) path -------------------------------------------------
030433 044016 LDA *16 =030451 ; A = word@030451 = 030147
030434 054602 LDX -126,B ; X = POSU context block ptr
030435 006006 STA 6,X ; block[6] = 030147
030436 170462 SAA 50 ; A = 50B (=40 dec)
030437 006007 STA 7,X ; block[7] = 50B
030440 135012 JPL I *12 =030452 ; <== RESUME-P. indirect via word@030452 = 0146547
030441 135012 JPL I *11 =030453
030442 170400 SAA 0
030443 135011 JPL I *11 =030454
--- OK path --------------------------------------------------------------------
030444 170401 SAA 1
030445 135007 JPL I *7 =030454
030446 001761 ; data
030447 001756 -> POSUERR ; [V] POSUERR datafield pointer (001756B)
030450 044511
030451 030147 ; block[6] value used above
030452 146547 ; [V] pointer -> 0146547B (OUTSIDE ENNS0 image)
[V] dumpwords: word@030452 = 146547; ENNS0's non-zero image span is 001756B..073116B, so
0146547B is not ENNS0 code - it is an external/shared routine (RTCOMMON-class COSMOS
common, [I]; exact identity [OPEN] - could be the POSUERR reporter at 001756B reached via a
different word, or a shared input primitive). 030447 = 001756 = POSUERR sits in this same
data island, so the block is the standard POSU error-report idiom used after every MON in this
module.
PRSRV parameter order (manual 8975-8978, [V]): 1=Logical device number (=LU 2240B),
2=IOflag (0=input part / 1=output part), 3=RT-description addr (0=own program), 4=Stat
(0=OK; negative = device already reserved). ENNS0 reserves the input part of LU 2240B for
its own RT, then reads that input.
Name-registration footprint: unchanged from the annotated disassembly - ENNS0's only XMSG is
030230 MON 200 T=0 (XFDUM) + 030233 MON 200 T=1 (XFDCT). This hang is a device INPUT
wait, a separate mechanism from XMSG naming.
2. NEW finding: the blocked frame is on the PRSRV-NONZERO branch [V]¶
JAZ 030444 (@030432) jumps to the OK path when Stat==0. resume-P is 030440, which is
only reachable by falling through = Stat != 0. Per the manual a negative PRSRV Stat
means the device was already reserved. So statically:
- ENNS0's PRSRV @030427 on LU 2240B returned non-zero, and the RT is parked in the
non-zero handler that calls out to
0146547.
This partially tensions with the live descriptor line RESERVED DATAFIELDS 103356B (which says
the device is reserved). Two readings, both consistent with the bytes, cannot be separated
without live registers:
- [I-a] the device was already reserved (by a prior ENNS0 run / another RT), PRSRV returned
negative, and ENNS0 fell into a handler that queues it INPUT-waiting on that same device
(hence FIRST WAITING); or
- [I-b] a different/earlier reserve holds 103356B and this PRSRV concerns another unit.
This is exactly the point where I stop and refuse to guess: which branch and which LU the
live registers actually carry is [OPEN] on static evidence and must be read live (section 5).
3. What the input is, and T=2 (Task 2 continued)¶
[V]ENNS0 does an INPUT (FIRST WAITING) on LU 2240B - a SINTRAN device-input wait, queued first. The reading routine is the external0146547(block[7]=50B/40dec looks like a max byte/record length passed to it,[I]).[I]What it is trying to receive: an input record/byte on the Ethernet-interface communication device - i.e. data the SINTRAN level-12 Ethernet driver would post after the controller signals inbound data. NOT an XMSG message (no XFRCV/XFGET in ENNS0) and not an inter-RT signal via XMSG.[OPEN]T=2 in the saved register set: I cannot verify a meaning. T is just the RT's T register at suspension; SINTRAN MON params are passed on the RT stack, not in T, so T=2 is most likely a leftover. I will not invent a semantic for it.
4. Identifying LU 2240B / datafield 103356B in SINTRAN terms (Task 4)¶
[V]103356Bin 100000-110000B = POF resident "SINTRAN communication / internal devices" area (00-SINTRAN-ARCHITECTURE-OVERVIEW.mdsec 5.3). => a communication/internal device datafield, not a terminal/disk.[V]PRSRV only reserves peripheral devices + semaphores => LU 2240B is a peripheral-class (communication) device, consistent with the datafield range.[V]RetroCore Ethernet II (NDBusEthernetII.csheader + IdentCode): hardware DEVNO 140360-140363B, IDENT 140034B, interrupt LEVEL 12; the SINTRAN logical device number is assigned at SINTRAN-generation time (the "Ethernet Interface datafield").[I, strong]Net: LU 2240B = the SINTRAN-generated Ethernet-interface communication device (input part).2240B=1184dec is a generated logical number, computed at runtime - which is why it is not a literal anywhere in ENNS0.
I did NOT find an Appendix-B logical-number table for THIS generated system in the repo, so the
exact LU->hardware binding is [I], not byte-proven.
5. Why no input arrives, and the fix (Task 3 + 5)¶
Evidence-ranked:
[I, leading] Emulator gap on the SINTRAN device-input path.The RetroCore Ethernet II is serviced at IOX / SCIP / INT12 / kernel-PIOCM (MON 255) level, and ENNS0 drives the controller only through PIOCM. But the thing that must wake this INPUT wait is a SINTRAN level-12 Ethernet-driver input completion on LU 2240B (driver posts a record to the device's input buffer and dequeues the first waiter). If the emulator never raises the specific input-ready interrupt (IDENT 140034B on level 12) that the generated ETH-datafield driver turns into LU-2240B input, ENNS0 waits forever. This matches the observed symptom (controller reaches READY / LANCE RX+TX ON in the harness, yet ENNS0's SINTRAN-level read never completes).[I] SINTRAN generation.The device clearly EXISTS (real datafield 103356B, ENNS0 reached the reserve), so it was generated. But whether SINTRAN L actually has a level-12 driver that converts controller input into LU-2240B records is unproven here. If that driver is absent or not wired to IDENT 140034B, the wait never satisfies regardless of the emulator.[ruled-down] ENNS0 self-trigger.ENNS0 has no XMSG receive and no prior step it skipped that would feed this device; the input is expected to come from the controller/driver side, not from another ENNS0 action.
[OPEN] I cannot decide (1) vs (2) statically - both produce an identical never-woken INPUT
wait. Decisive next step (live, DAP):
- Breakpoint 030427 (PRSRV) and 030440 (resume-P). Read A/Stat and the PRSRV param block to
get the actual DeviceNo (confirm =2240B), IOflag, and Stat - this settles section 2.
- Step into 0146547 to name the input primitive (INBT/WAITF) and read the datafield 103356B
driver state.
- From SINTRAN's side, check whether an IDENT 140034B on level 12 dequeues this waiter. If the
controller can be made to post an input interrupt and ENNS0 wakes -> fix is emulator
input-delivery on the LU-2240B path (option i). If SINTRAN has no driver to service it -> the
fix is a generation issue (option ii).
Verified evidence index¶
030432 131012 JAZ 030444=> resume-P 030440 is the PRSRV-nonzero branch.[V]- MON 322/124/125 identities + PRSRV param order + "0=OK, negative=already reserved":
Reference-Manuals\ND-860228-2-EN SINTRAN III Monitor Calls.mdlines 1442-1445, 8963-8978,[V]
- LU 2240B / 103356B not literals in ENNS0 (
002240only @030327;103356absent).[V] - word@030452=146547 outside image (image hi=073116B).
[V] - Datafield 103356B in POF 100000-110000B "SINTRAN communication / internal devices":
SINTRAN\OS\00-SINTRAN-ARCHITECTURE-OVERVIEW.mdsec 5.3.[V] - ETH hardware DEVNO/IDENT/level: RetroCore
Emulated.HW\ND\CPU\NDBUS\NDBusEthernetII.cslines 17-22, 497.[V]
Honest OPEN items (no guessing)¶
- Exact identity of routine at 0146547 (RTCOMMON input primitive vs POSUERR reporter).
[OPEN] - Which branch/LU the LIVE registers carry at the hang (static shows nonzero-PRSRV path).
[OPEN] - Meaning of T=2.
[OPEN] - Whether the failure is emulator input-delivery (option i) or a missing/unwired SINTRAN L
ETH-datafield level-12 driver (option ii) - needs the live DAP session above.
[OPEN]