ND-500 level-12 MON handlers: which carved segment overlays them¶
Question answered: the L07 symbols DVIO, GERRC, SWMC, A5XMSG/B5XMSG,
5MTRANS, 5SIBMO, STAPROC, NSTOPROC (all in virtual 140000-143500, octal)
read as zero in resident/SINTRAN-DATA_commoncode.bin because they sit in the
104000-170000 overlaid BSS gap. This document resolves them to the carved segment
that supplies the PIT overlay for that window and gives the real L disassembly.
Verdict¶
Winning segment: S3MPIT (the memory-resident "MPIT" segment, madr==0, so not
carved directly), recovered byte-for-byte from its carved Image / Save copies:
| Role | Carved file | segle | Load addr (octal) | nd100-dis -b (dec) |
Ghidra base (hex) |
|---|---|---|---|---|---|
| Image of MPIT | ../segments/026-S3IMPIT.bin |
51 | 32000 |
13312 |
0x3400 |
| Save of MPIT | ../segments/017-S3SMPIT.bin |
51 | 32000 |
13312 |
0x3400 |
The Image and Save copies are byte-identical across the whole driver region
(136000-144000 verified equal), exactly the pattern used for the other
madr==0 segments (Extended Common in EXTRACTING-RESIDENT-CODE.md section 7.2,
S3IMAGE/S3SAVE in section 4). This is the PIT-overlay resolution called for by
section 7.3 step 2: S3MPIT covers 32000 .. 32000+51*2000 = 154000 and is the
segment whose live PIT maps into the 140000-143500 gap of the common image.
Offset math¶
file_word_offset = symbol_addr(octal) - 32000(octal) # = load address
file_byte_offset = file_word_offset * 2 # .bin is big-endian words
141027 - 32000 = 107027(oct) words = 36887(dec) -> byte 73774.
Disassembly command¶
# byte-swap the big-endian carve to little-endian for nd100-dis
python3 -c "import sys;d=bytearray(open(sys.argv[1],'rb').read());d[0::2],d[1::2]=d[1::2],d[0::2];open(sys.argv[2],'wb').write(d)" \
../segments/026-S3IMPIT.bin /tmp/impit.le.bin
# base 32000 octal = 13312 decimal so printed addresses are the true virtual addresses
nd100-dis -a -o -S -b 13312 /tmp/impit.le.bin
Why S3MPIT and not the other candidates¶
The load-address-aware "non-zero content" scan returns many candidates because the
104000-170000 window is where several swappable segments map in. The discriminator
below is semantic, not "has bytes here".
1. Embedded call-pointer density (decisive)¶
The level-12 handlers reach shared routines through P-relative indirect pointer
words (JPL I n, JMP I n, LDT I n) whose target words hold fixed resident
addresses. Counting how many of those exact target addresses appear as data words in
136000-144000 of each covering segment:
| Segment (load, octal) | pointer-word hits | breakdown |
|---|---|---|
| S3IMPIT / S3SMPIT (32000) | 140 | 5MBBANK x29, NXTMSG x24, XACTRDY x17, WN5STATUS x17, GCPUDF x14, EMONICO x9, OKMONICO x8, SUNLOCK x8, SLOCK x6, MCCO x3, RTACT x3, 5ACTSWAP x2 |
| S3SM5 / S3SSM5 (40000) | 8 | NXTMSG x3, 5MBBANK x3, GCPUDF x2 |
| S3FS / S3SFS (26000) | 5 | NXTMSG x5 |
| S3DMAC (64000) | 0 | - |
| S3XMK, S3SPRMA, ... | <=1 | noise |
Resolved target addresses used above (L07 SYMBOL-2-LIST / SYMBOL-1-LIST, octal):
5MBBANK=4654, NXTMSG=135067, EMONICO=23021, OKMONICO=23025, XACTRDY=145466,
WN5STATUS=23670, MCCO=23044, SLOCK=23706, SUNLOCK=24041, 5ACTSWAPPER=145162,
RTACT=13552, GCPUDF=23624. Only S3MPIT carries the whole ND-500 driver linkage
table; every other segment is at noise level.
2. Instruction-level structural match to NPL/MP-P2-N500.NPL¶
nd100-dis decodes the ND-500 message micro-ops (LDATX, LDDTX, LDXTX, STATX,
STDTX) as mnemonics, so the NPL one-liners map directly onto the L bytes (the NPL is
a different revision - structure matches, exact bytes do not; L07 symbols sit a
uniform +200 octal above the NPL's own addresses):
- GERRC NPL
T:=5MBBANK; *5RECE@3 LDATX-> L141633 LDT I 50then141634 LDATX. - SWMC NPL
MSM510 SHZ 10=:D; T:=5MBBANK; *AAX TRAPN; LDATX-> LSAA 27 / SHA ZIN 10 / RADD..DD / LDT I 11 / AAX 16 / LDATX. - STAPROC NPL
T:=5MBBANK; *AAX NPROC; LDDTX-> LLDT I 156 / AAX 100 / LDDTX. - A5XMSG NPL
X=:B; T:=5MBBANK; *AAX N5XFU; LDATX; A/\X5MASK=:D-> LRADD..SX DB / LDT I 127 / AAX 101 / LDATX / AND 125 / RADD..DD. - 5MTRANS NPL
X=:CMSGA; 0=:CUREL; A:=B=:XC5CPUDF; T:=5MBBANK; *AAX 5MNWA; LDDTX-> LSTX I 142 / STZ I 142 / RADD SB DA / STA I 141 / LDT I 141 / AAX 100 / LDDTX.
3. Elimination of the confident-looking decoys¶
- S3DMAC (64000) and S3FS/S3SFS (26000) both decode as valid ND-100 code in
this window (low invalid-opcode density), which is why a "non-zero + coherent-ish"
test flags them - but the code is not the ND-500 driver: 0 and 5 linkage hits
respectively, and no
LDATX/LDDTXmessage-decode shape. S3FS is file-system code. - S3SM5 / S3SSM5 (40000) is the ND-500 32-bit System Monitor: 73 invalid ND-100
opcodes + 24
IOXin the window - it is 32-bit ND-500 code / data, not ND-100 level-12 handlers (confirmed the task's suspicion). - S3RFAC (26000) does not even cover the full driver (
hi = 146000 < 147715).
Per-handler L disassembly (from 026-S3IMPIT.bin, base -b 13312)¶
Addresses are the true virtual (octal) addresses. I n = P-relative indirect through
a pointer word; those pointer words hold the resident routine addresses listed above.
STAPROC = 140356 (Start / switch process)¶
NPL: T:=5MBBANK; *AAX NPROC; LDDTX; IF A<=5SWPROC OR A>>MX5PROCS GO ILPROC ...
140356 051156 LDT I 156 ; T := 5MBBANK
140357 173500 AAX 100 ; AAX NPROC
140360 143302 LDDTX ; A=proc.no, D=magno (read message)
140361 051154 LDT I 154
140362 143056 SKP IF DT LST SA ; A <= 5SWPROC ?
140363 124003 JMP 3 ; -> 140366
140364 051152 LDT I 152
140365 141456 SKP IF DT MGRE SA; A >> MX5PROCS ?
140366 124017 JMP 17 ; -> 140405 (GO ILPROC)
140367 065146 SUB I 146
140370 120147 MPY 147
140371 060147 ADD 147 ; A-5SWPROC*5PRDSIZE+"S500S"
140372 146157 RADD CLD SA DX
140373 056007 LDX ,X 7 ; X := A.MESSBUFF
140374 051140 LDT I 140 ; T := 5MBBANK
140375 173775 AAX -3
140376 143300 LDATX ; A := magno
140377 173547 AAX 147
140400 143301 LDXTX ; X := process descriptor
140401 140015 SKP IF DA EQL SD
NSTOPROC = 140511 (Stop process)¶
NPL: CALL SLOCK; 0/\0; T:=5MBBANK; *AAX 5MSFL; LDATX; IF A BIT 55REP ...
140511 135043 JPL I 43 ; CALL SLOCK (ptr -> 023706)
140512 144400 RAND 0 0 ; 0/\0 (interlock marker)
140513 051021 LDT I 21 ; T := 5MBBANK
140514 173777 AAX -1
140515 143300 LDATX ; A := 5MSFL (message flag)
140516 175375 BSKP ONE 170 DA ; IF A BIT 55REP
140517 124010 JMP 10 ; -> 140527
140520 174175 BSET ZRO 170 DA ; A BZERO 55REP (reset REP bit)
140521 143304 STATX ; write flag back
140522 173401 AAX 1
140523 135034 JPL I 34 ; CALL SUNLOCK
140524 135026 JPL I 26 ; CALL OKMONICO (restart ND-500 proc)
140525 135017 JPL I 17 ; CALL XACTRDY
140526 124005 JMP 5 ; GO NXTMSG path
140527 135030 JPL I 30 ; CALL SUNLOCK
140530 170413 SAA 13 ; STOPPED
140531 055011 LDX I 11 ; X := N5MESSAGE
140532 135030 JPL I 30 ; CALL WN5STATUS
140533 125012 JMP I 12 ; GO NXTMSG (-> 135067)
140534 004654 <data 004654> ; 5MBBANK pointer constant
DVIO = 141027 (Device I/O / NOUTSTR)¶
NPL: CALL 5GTDF; GO NORMMC; A:=D; X:=N5MESSAGE; T:=5MBBANK; *AAX TODF; STATX ...
141027 135063 JPL I 63 ; CALL 5GTDF (get datafield if terminal)
141030 125063 JMP I 63 ; GO NORMMC
141031 146115 RADD CLD SD DA ; A := D
141032 055062 LDX I 62 ; X := N5MESSAGE
141033 051062 LDT I 62 ; T := 5MBBANK
141034 173542 AAX 142 ; AAX TODF
141035 143304 STATX ; store output-datafield ptr
141036 173740 AAX -40
141037 143302 LDDTX ; read DNOBY (byte count)
141040 173676 AAX -102
141041 131404 JAF 4 ; -> 141045
141042 050054 LDT 54
141043 143416 SKP IF DT MLST SD; D >> 4000 ?
141044 124006 JMP 6 ; -> 141052
141045 170574 SAA 174 ; A := EC174 (error code)
141046 135051 JPL I 51 ; CALL EMONICO
141047 135051 JPL I 51 ; CALL XACTRDY
141050 125051 JMP I 51 ; GO NXTMSG
141051 124005 JMP 5 ; -> 141056
GERRC = 141633 (Get error register from ND-500 trap context)¶
NPL: T:=5MBBANK; *5RECE@3 LDATX; A-5SWPROC+1*REGBSZ+"ERREG"=:T ...
141633 051050 LDT I 50 ; T := 5MBBANK
141634 143340 LDATX ; A := 5RECE (received-trap register)
141635 065047 SUB I 47 ; A - 5SWPROC ...
141636 172401 AAA 1 ; ... + 1
141637 120046 MPY 46 ; * REGBSZ
141640 060046 ADD 46 ; + "ERREG"
141641 146156 RADD CLD SA DT ; =: T
141642 054045 LDX 45 ; "N500DF".CNTXPAGE + X.ADRZERO
141643 046057 LDA ,X 57
141644 062060 ADD ,X 60
141645 146151 RADD CLD SA DD ; =: D
141646 146105 RADD CLD 0 DA
141647 156612 SAD ZIN 12 ; AD SHZ 12
141650 146061 RADD ST DD ; D + T
5SIBMO = 141716 (Special MON call from SIBAS server in ND-500)¶
NPL: T:=5MBBANK; *AAX SIBNO; LDDTX; IF A><0 OR D>>MXSIBAS OR T=0 THEN ...error
141716 051101 LDT I 101 ; T := 5MBBANK
141717 173500 AAX 100 ; AAX SIBNO
141720 143302 LDDTX ; D := SIBAS number
141721 131406 JAF 6 ; IF A><0 -> 141727 (error)
141722 051076 LDT I 76
141723 141416 SKP IF DT MGRE SD; D >> MXSIBAS ?
141724 124003 JMP 3 ; -> 141727 (error)
141725 140006 SKP IF DT EQL 0 ; T = 0 ?
141726 124006 JMP 6 ; -> 141734 (ok, legal SIBAS)
141727 055072 LDX I 72 ; X := N5MESSAGE
141730 170574 SAA 174 ; A := EC174
141731 135071 JPL I 71 ; CALL EMONICO (illegal SIBAS number)
141732 135071 JPL I 71 ; CALL XACTRDY
141733 125071 JMP I 71 ; GO NXTMSG
141734 146117 RADD CLD SD DX ; X := D (=CSIBNO)
141735 014357 STX -21 ; =: CSIBNO
141736 057067 LDX I ,X 67 ; SIBBDEVS(X)
141737 146171 RADD CLD SX DD
141740 014355 STX -23
141741 046001 LDA ,X 1
SWMC = 142153 (SWap Monitor Call -> activate swapper)¶
NPL: MSM510 SHZ 10=:D; T:=5MBBANK; *AAX TRAPN; LDATX; ... CALL 5ACTSWAPPER
142153 170427 SAA 27 ; MSM510 (mask constant)
142154 156410 SHA ZIN 10 ; SHZ 10
142155 146151 RADD CLD SA DD ; =: D
142156 051011 LDT I 11 ; T := 5MBBANK
142157 173416 AAX 16 ; AAX TRAPN
142160 143300 LDATX ; A := trap number
142161 070007 AND 7
142162 146015 RADD SD DA
142163 143304 STATX ; write trap word back to message
142164 173762 AAX -16
142165 135004 JPL I 4 ; CALL 5ACTSWAPPER (ptr at 142171 = 145162)
142166 125004 JMP I 4 ; GO NXTMSG (ptr at 142172 = 135067)
142167 004654 <data 004654> ; 5MBBANK pointer
142170 000377 <data 000377>
142171 145162 <data 145162> ; 5ACTSWAPPER
142172 135067 <data 135067> ; NXTMSG
read TRAPN via 5MBBANK ->
CALL 5ACTSWAPPER -> GO NXTMSG, with the resident addresses 145162 and 135067
sitting inline as the indirect pointer words the two branches use.
A5XMSG / B5XMSG = 142253 (ND-500 XMSG bridge)¶
Both labels share one entry. The XMRETMASK writeback-mask array occupies the words
just below the entry. Its L bytes at 142173..142252 decode as
16, 0, 4, 0, 34, 0, 20, 20, 0, 14, 2, 0, 0, 74, 34, 4, ... - a byte-exact match
to the NPL INTEGER ARRAY XMRETMASK:=(16,0,4,0,34,0,20,20,0,14,2,0,0,74,34,4,...),
independent proof this is the ND-500 driver and that the segment is aligned correctly.
NPL: X=:B; T:=5MBBANK; *AAX N5XFU; LDATX; A/\X5MASK=:D; IF A-X5MAXF>0 GO X5EILF ...
142253 146173 RADD CLD SX DB ; X =: B
142254 051127 LDT I 127 ; T := 5MBBANK
142255 173501 AAX 101 ; AAX N5XFU
142256 143300 LDATX ; A := xmsg function word
142257 070125 AND 125 ; A /\ X5MASK
142260 146151 RADD CLD SA DD ; =: D (save xmsg function)
142261 172721 AAA -57 ; A - X5MAXF
142262 141050 SKP IF 0 GRE SA
142263 124135 JMP 135 ; GO X5EILF (illegal function) -> 142420
142264 173647 AAX -131
142265 143300 LDATX ; XTBLK (xtblock allocated?)
142266 131426 JAF 26 ; -> 142314
142267 170401 SAA 1
142270 142015 SKP IF DA UEQ SD
142271 125114 JMP I 114 ; GO FAR X5LEAVE (-> 142405)
142272 146137 RADD CLD SB DX ; X := B
142273 173540 AAX 140 ; AAX HBUFA
142274 143300 LDATX
142275 171043 SAT 43
142276 146104 RADD CLD 0 DL
5MTRANS = 143445 (ND-500 memory / disk transfer request)¶
NPL: X=:CMSGA; 0=:CUREL; A:=B=:XC5CPUDF; T:=5MBBANK; *AAX 5MNWA; LDDTX; AD=:NWFUNC ...
143445 015142 STX I 142 ; X =: CMSGA (current message ptr)
143446 001142 STZ I 142 ; 0 =: CUREL
143447 146135 RADD CLD SB DA ; A := B
143450 005141 STA I 141 ; =: XC5CPUDF
143451 051141 LDT I 141 ; T := 5MBBANK
143452 173500 AAX 100 ; AAX 5MNWA
143453 143302 LDDTX ; read 5MNWA (function/word)
143454 173700 AAX -100
143455 021136 STD I 136 ; AD =: NWFUNC
143456 045136 LDA I 136
143457 175205 BSKP ONE 0 DA ; IF 5MFNC NBIT 5DTRANS
143460 125135 JMP I 135 ; GO FAR CHEVENT (-> 143615)
143461 173510 AAX 110 ; AAX 5MLGN
143462 143300 LDATX ; A := logical device number
143463 135133 JPL I 133 ; CALL LOGPH (-> 143616)
143464 146157 RADD CLD SA DX ; A =: X
143465 050132 LDT 132
143466 141467 SKP IF DX MGRE ST; X >>= "9BBHD" (hard-disk range check)
143467 124024 JMP 24 ; -> 143513
143470 050130 LDT 130
One-line verdict per handler (all in S3MPIT via 026-S3IMPIT.bin, base 13312)¶
| Handler | Addr (octal) | Verdict |
|---|---|---|
| STAPROC | 140356 | CONFIRMED - LDT 5MBBANK / AAX NPROC / LDDTX, legal-proc checks, matches NPL start/switch process |
| NSTOPROC | 140511 | CONFIRMED - CALL SLOCK / 0/\0 / LDT 5MBBANK / AAX 5MSFL / LDATX, REP-bit test + WN5STATUS(STOPPED) |
| DVIO | 141027 | CONFIRMED - CALL 5GTDF / GO NORMMC, TODF/DNOBY message reads, EC174 error path |
| GERRC | 141633 | CONFIRMED - LDT 5MBBANK / LDATX 5RECE, reads trap ERREG from ND-500 context |
| 5SIBMO | 141716 | CONFIRMED - LDT 5MBBANK / AAX SIBNO / LDDTX, SIBAS-number validation then EMONICO |
| SWMC | 142153 | CONFIRMED - MSM510 SHZ 10 =:D / LDT 5MBBANK / AAX TRAPN / LDATX into swap-activate (5ACTSWAPPER) |
| A5XMSG/B5XMSG | 142253 | CONFIRMED - shared entry, X=:B / LDT 5MBBANK / AAX N5XFU / LDATX / AND X5MASK, XMRETMASK array below |
| 5MTRANS | 143445 | CONFIRMED - X=:CMSGA / A:=B / LDT 5MBBANK / AAX 5MNWA / LDDTX, disk/mem transfer dispatch |
Confidence: HIGH. Not a forced positive: the linkage-pointer density (140 vs <=8),
the LDATX/LDDTX message-decode shape, and the per-handler NPL structural match all
point to the same single segment. Save and Image copies are byte-identical, so both
026-S3IMPIT.bin and 017-S3SMPIT.bin are valid sources.