Random notes - PDP-10/tenex GitHub Wiki
See here for 1972 build instructions. They don't fully apply to sources here; even our 1.28 version is different. http://www.bitsavers.org/pdf/bbn/tenex/MonitorTechSummary_Feb72.pdf
There are many script files with hints how to assemble TENEX, e.g. ASSAIC.CMD, LOD10X.RUN, etc.
The files STENEX.MAC and PROLOG.MAC should be assembled to produce universal files. However, they don't have any END statement, and STENEX even lacks the UNIVERSAL directive. I found a clue in the file SYSSTENEX.RUN. It says it should be assembled like TTY:,STENEX,TTY:
. The first TTY: input should be UNIVERSAL
and optionally some parameters. The second input should be END
. Presumably PROLOG should also be assembled similarly. Maybe PARAMS,PROLOG,TTY:
and enter END
.
<134-TENEX>PARAMS.MAC uses .DIRECTIVE XSRCVN
, which is not supported by any MACRO version I have found.""
I will focus on <133-TENEX> for now. But it would also be possible to just remove XSRCVN; it doesn't seem to be used for anything really.
TENEX uses the ORG
pseudo-op. DEC MACRO has .ORG
. As luck would have it MACRO.10X does have ORG
, so hopefully that's the version to use. It doesn't have .DIRECTIVE XSRCVN
though.
Another BBN vs DEC incompatibility: ASSIGN
vs .ASSIGN
. <CUSPS>MACRO.MAC has ASSIGN
.
MACRO.10X is damaged: look for ^L^L^L^L
to find gaps in the file. But <CUSPS>MACRO.MAC is newer, and assembles cleanly. It claims to have ;FIXES TO MAKE IT TENEX COMPATABLE
.
By diffing and comparing MACRO.10X and <CUSPS>MACRO.MAC it's possible to fill those gaps. But CUSPS is newer anyway and seem to do quite well so far.
<CUSPS>MACRO will not assemble PAGEM.MAC: ? PA1050: ILLEGAL INSTRUCTION 0,,0 AT USER 24164
IMPDV complains about undefined symbols: ASNSX1, ASNSX2, NTWZX1, SNDIX1, SNDIX2, SNDIX3, SNDIX4, SNDIX5, SQX1, SQX2. They should be defined by STENEX.
DSK,DSKPAK, many undefined symbols. They seem to be in DSKPAK though.
DEVICE, DIRECT: undefined symbols found in STENEX.
Assembling with <CUSPS>MACRO, as per the order in <133-TENEX>ASSAIC.CMD. Running on TOPS-20 V3A, but the host shouldn't matter much.
- STENEX=TTY:,STENEX,TTY:
- TENDMP
- PROLOG=PARAMS.AI,PROLOG
- VERSIO=VERSIO,SYSNAM
- LDINIT
- SCHED - undefined symbol
MAXQ
- PAGEM - crash
- PISRV
- SWPMON
- FORKS
- TTYSRV
- IMPDV
- DSK=DSK,DSKPAK - undefined symbols
- DRM=DRMBRY
- FILEDE=PARAMS.AI,FILE
- PSDOTY
- DEVICE
- DIRECT
- FREE
- FUTLII
- GTJFN
- IO
- JSYS
- LOOKUP
- DECTAP
- MAGTAP
- DISC
- FILINI
- FILTTY
- HOSTS
- LINEPR
- PDP15
- TV
- NETWRK
- NIL
- PTP
- PTR
- STRING
- MFLIN,MR,MFLOUT,DATIME
- JOBDAT
- EDDT
- POSTLD
The LOD10X.RUN
script is for RUNFIL. It starts CCL
which does LOAD @ASSCL.CMD
. The CMD
file is interpreted by CCL
.
Making sense of the CCL @-file, e.g. <134-TENEX>ASSCL.CMD.
/
starts a switch parsed by CCL. %
starts a switch passed to LINK.
-
/LINK
- Use LINK10 rather than LOADER. -
%/NOINIT/
- Prevents loading of LINK's initial global symbol table (JOBDAT). -
/MAP:MAP
- ProduceMAP.MAP
loader map file. -
%/SYMSEG:L/
- Places the symbol table in the low segment. -
%/SET:.LOW.:200/
- Sets low segment location pointer. -
/MACRO
- Use MACRO to compile source files. -
%/NOLOCALS/
- Do no include local symbols in the symbol table. -
%/CORE:80K/
- Initial low segment size is 80K. -
/COMPILE
- Compile source files even if .REL files exist and are newer. -
%/SET:.LOW.:RESMA0/
- Sets low segment location pointer. -
%/LOCALS/
- Includes local symbols from a module in the symbol table. -
%/SEGMENT:HIGH/
- Load into high segment. -
%/NOSYSLIB/
- Prevents searching system libraries. -
%/SEGMENT:LOW/
- Load into low segment. -
%/SEGMENT:DEFAULT/
- Load into both? segments?
Most assembler problems fixed by assembling STENEX with INTERF==1
.
SCHED.MAC problem solved by moving definitions of LS RUNLST
and LS RUNLSB
below definition of MAXQ
.
TENEX 1.34 has this fix:
;<134-TENEX>SCHED.MAC;317 25-FEB-75 14:26:47 EDIT BY CLEMENTS
; MOVE DEFINITION OF MAXQ UP BEFORE USE OF IT TO AVOID PASS1 "V" ERRS
Another RUNFIL (<MON>LODX.SMX) says to use LOADER instead of CCL and LINK:
LOADER
(W200O)SYS:STENEX.REL,DSK:TENDMP,PROLOG.SRL
(&RESMA0&O)VERSIO.SRL,LDINIT.SRL
(S)MON.SRL,SWPMON.SRL
I4.SRL,SUMX.SRL,TTYSRV.SRL,IMPDV.SRL
DSK.SRL,DRM.SRL,FILEDE.SRL
DEVICE.SRL,DIRECT.SRL,FREE.SRL,FUTILI.SRL,GTJFN.SRL
IO.SRL,JSYS.SRL,LOOKUP.SRL,DECTAP.SRL,DISC.SRL
FILINI.SRL,FILTTY.SRL,MAGTAP.SRL,HOSTS.SRL,NETWRK.SRL
NIL.SRL,PTP.SRL,PTR.SRL,STRING.SRL
LINEPR.SRL,PLOTTE.SRL,ISYS.SRL,SSYS.SRL
(S)CRSHSV.SRL
(1HW)MFLIN
(-B)MR
MFLOUT,DATIME
(S)SYSSAV.SRL,SYSBT.SRL
(W)
SYS:JOBDAT.REL
(-H)DSK:EDDT.SRL
MAP_(P)DSK:POSTLD.SRL(FMG)
SSAVE 0 677 AMON.SMX
; SYMBOL TABLE COMPACTING FOLLOWS
START
SSAVE 0 677 AMON.SMX
I succeeded in linking a monitor by entering the above into LOADER. Except one thing: I removed the /F
switch, i.e. from (FMG)
.
The .REL files were assembled as per the ASSA.SMX CCL script. I used the <CUSPS> MACRO and LOADER which I built before with no problems.
The resulting core image should be STARTed once, and then the resident monitor should be saved from 20-377777, and the swappable monitor from 400000-777777. You also get an RLRMON file which is a disk bootstrap; ignore this for now.
When the monitor is entered at location 100, it goes to EDDT. From there we can examine the core image, make patches, set breakpoints, and start various monitor entry points. The next logical step is to start from SYSLOD
to refresh the disk and then enter the mini-exec to make a bit table. From there it should be possible to load and run programs off DECtape or magtape.
One of the first things that happens is that the resident monitor calls GETSWM
to load the swappable monitor from DECtape. To do this, it calls the linked-in TENDMP which has been primed with the command 0$M$TENEX SWP^M
.
I wrote a tool to create a DECtape image in the format TENDMP expects: https://github.com/larsbrinkhoff/pdp10-its-disassembler/pull/129
With TD10 debugging messages enabled, I see that calling SYSLOD
now reads TENEX.SWP from the tape. The last part matches the end of the file; so far so good. However, after this the monitor seems stuck and nothing else happens.
There was a problem in the DK10 timer device. Taking an interrupt and clearing the done flag doesn't properly clear the interrupt conditions. A patch from Cornwell fixed the problem. Next stop is WRMON
calling the DSKOP
JSYS to write the resident monitor to disk. The system does poke the RP10 a bit, but never returns from DSKOP
.
Patching out the calls to WRMON
and WRSWM
at ULKSM1+17
and DTAINI
at FILINI+33
gets us this:
DO YOU REALLY WANT TO CLOBBER THE DISC BY RE-INITIALIZING? Y
OK, YOU ASKED FOR IT.
TENEX RESTARTING, WAIT... NO CHECKDSK