Trailing-Edge
-
PDP-10 Archives
-
tops10_tools_bb-fp64b-sb
-
10,7/frecor/frecor.mac
There are 5 other files named frecor.mac in the archive. Click here to see a list.
TITLE FRECOR -- Program to figure out where all the Free Core went
SUBTTL C.D.O'Toole/CDO 18-Mar-87
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;COPYRIGHT (C) 1979,1980 BY DIGITAL EQUIPMENT CORPORATION
SEARCH MACTEN, UUOSYM
SALL
;VERSION STUFF
FCREDT==4 ;EDIT NUMBER
FCRVER==704 ;MAJOR VERSION
FCRMIN==0 ;MINOR VERSION
FCRWHO==0 ;WHO LAST EDITTED
LOC 137
VRSN. FCR
RELOC
;CHANNELS
XPN==0 ;FOR READING CRASHES
;AC DEFINITIONS
F==0 ;A FLAG REG
FL.EOL==1B0 ;END OF LINE SEEN
FL.ETX==1B1 ;END OF PHYSICAL LINE SEEN
FL.RSC==1B2 ;HAVE GETONE USE RESCAN LAST CHARACTER
FL.UPZ==1B3 ;^Z TYPED, EXIT AFTER COMMAND
T1==1 ;TEMPORARY ACS FOR ANY SUBROUTINE
T2==2
T3==3
T4==4
T5==5
CH==6 ;CHARACTER HOLDER
UU==7 ;FOR LUUO HANDLER
UA==10 ;HOLDS LUUO EFFECTIVE ADDRESS
J==11 ;HOLDS JOB NUMBER FOR LOOPS
P1==12 ;PRESERVED ACS FOR ANY COMMAND PROCESSOR
P2==13
P3==14
P4==15
P5==16
P==17
.PSECT CODE,740000 ;START CODE PSECT AT FYSORG
SUBTTL Macros and other stuff
DEFINE FORMAT(A),<
..N==0
IRP A,<
IFN ..N,<XLIST>
IFE ..N&1,<IFNB <A>,<TEXT.(A)>>
IFN ..N&1,<A>
..N==..N+1
>
LIST
SALL
>
DEFINE TEXT.(A),<OUTSTR[ASCIZ\A\]>
DEFINE GTTAB(ENTRY),<
MOVE T1,[ENTRY]
XLIST
PUSHJ P,GTBSPY
HALT .
LIST
SALL
>
OPDEF DEC [001000,,0] ;OUTPUT DECIMAL NUMBER
OPDEF OCT [002000,,0] ;OUTPUT OCTAL NUMBER
OPDEF SIX [003000,,0] ;OUTPUT SIXBIT VALUE
OPDEF PER [004000,,0] ;OUTPUT FRECOR NUMBERS AS PERCENT
OPDEF CRLF [005000,,0] ;DO A CRLF
OPDEF OCT4 [006000,,0] ;OUTPUT OCTAL * 4
OPDEF GTTO [007000,,0] ;GETTAB VALUE IN OCTAL
OPDEF GTTD [010000,,0] ;GETTAB VALUE IN DECIMAL
OPDEF GTTA [011000,,0] ;GETTAB VALUE AS ASCII WORD
OPDEF GTTD2 [012000,,0] ;GETTAB VALUE, DECIMAL, 2 DIGITS
DEFINE MSYM(NAME,VALUE),<NAME==VALUE>
MSYM MONITR,0 ;SYMBOLIZE LOCATION 0 OF THE MONITOR
MSYM NUMTAB,410 ;WHERE .GTSLF LIVES
MSYM DEVNAM,0 ;SIXBIT DEVICE NAME IN DDB
MSYM DEVSER,3 ;LINK TO NEXT DDB
MSYM DEVMOD,4 ;DEVICE MODE WORD
MSYM DEVXTR,13 ;POINTER TO CDT IF A MPX DDB
MSYM STRNAM,0 ;NAME OF STRUCTURE
MSYM STRSYS,1 ;LH LINK TO NEXT STRUCTURE
MSYM STRUNI,2 ;LH LINKS TO FIRST UNIT IN STRUCTURE
MSYM UNINAM,0 ;NAME OF UNIT
MSYM UNISTR,16 ;CONTINUE UNITS IN STRUCTURE
MSYM UNISPU,62 ;SPT SIZE IN THIS WORD
MSYM UNIWPS,62 ;SAT SIZE IN IT TOO
MSYM UNISAB,65 ;LINK TO SAB RING
MSYM UNISPT,112 ;LINK TO SPT
MSYM SABRNG,0 ;LINK TO NEXT SAB IN RING
MSYM PTRSYS,0 ;LINK TO NEXT PTR COPY BLOCK
MSYM .LBNHS,0 ;POINTER TO NEXT ENQ/DEQ LOCK BLOCK
MSYM .LBLEN,1 ;L.H. = LENGTH OF THIS LOCK BLOCK
MSYM .LBNQ,2 ;POINTER TO FIRST ENQ/DEQ QUEUE BLOCK
MSYM .LBNMS,7 ;L.H. = LENGTH OF MASK BLOCK
MSYM .QBNQ,2 ;POINTER TO NEXT ENQ/DEQ QUEUE BLOCK
MSYM .QBMSK,6 ;POINTER TO MASK BLOCK FOR THIS Q-BLOCK
MSYM .CBNHB,0 ;POINTER TO NEXT CACHE BLOCK
MSYM .CBNAB,2 ;POINTER TO NEXT ACTIVE CACHE BLOCK
MSYM .CBDAT,6 ;ADDRESS OF CACHED BLOCK
MSYM .CBLEN,10 ;LENGTH OF A CACHE BLOCK
MSYM .CTNXT,2 ;POINTER TO NEXT CONTEXT BLOCK
MSYM .CTBPR,43 ;BEGINNING OF PARAMETER AREA
MSYM .CXSCX,2 ;POINTER TO SAVED CONTEXT
MSYM .CXPIA,43 ;POINTER TO SAVED JBTPIA
MSYM .CTSIZ,200 ;SIZE OF A CONTEXT BLOCK
MSYM AHBNXT,0 ;POINTER TO NEXT ALLOCATION HEADER BLOCK
MSYM AHBAEB,14 ;ALLOCATION HEADER EXTENT BLOCK POINTER
MSYM AEBNXT,0 ;POINTER TO NEXT EXTENT BLOCK
MSYM AEBBMP,5 ;BITMAP TO EXTENT
MSYM ETDOBK,51 ;DTE OUTPUT BUFFER
MSYM ETDIBK,52 ;DTE INPUT BUFFER
MSYM UBLSIZ,223 ;SIZE OF DTE BUFFER MINUS HEADER
MSYM MS.MEM,<3,,0> ;SECTION FOR PAGTAB/MEMTAB
;SYMBOLS NOT GETTAB'ABLE
PDBLEN==111 ;WORDS IN A PDB
DSKDDS==66 ;WORDS IN A DISK DDB
MPXLEN==32 ;WORDS IN A MPX DDB
SPROTO==41 ;WORDS IN A MAG TAPE LABEL DDB
STRLEN==27 ;WORDS IN STR DATA BLOCK
SPTFIR==0 ;SPT OVERHEAD
SABBIT==5 ;SAB OVERHEAD
LNMLEN==4 ;WORDS IN A LOGICAL NAME TABLE
PTHLEN==5+2 ;WORDS IN A PATH BLOCK
PTRCOR==3*4 ;WORDS IN A UPDATE FILE POINTER COPY BLOCK
NWSCTX==30 ;WORDS IN A SAVED CONTEXT BLOCK
.PDSCX==37 ;WORD IN PDB THAT POINTS TO CONTEXT BLOCK
.PDSAC==76 ;FIRST CONTEXT
.PDCTC==77 ;CURRENT CONTEXT
DVDSK==200000 ;BIT IN DEVMOD FOR DSK DEVICE
SHRSEG==200000 ;BIT IN JBTSTS FOR A SEGMENT SAYING SHARABLE
QBSIZE==7 ;SIZE OF ENQ/DEQ QUEUE BLOCK
;PAGTAB DEFINITIONS
PAGTAB==730000 ;WHERE IT LIVES (ON KS'S ANYWAY)
PT.FRE==400000 ;ON THE FREE LIST
PT.LPH==200000 ;LOCKED PHYSICALLY CONTIGUOUS
PT.LEV==100000 ;LOCKED IN EVM
PT.LIP==040000 ;LOCKED IN PLACE
PT.NXM==020000 ;NON-EXISTANT
PT.MON==010000 ;BELONGS TO THE MONITOR
PT.IPC==004000 ;BELONGS TO IPCF
PT.TNC==002000 ;TEMPORARILY UNCACHED (1099 ONLY)
;THINGS THAT CAN'T REALLY CHANGE, JUST MADE SYMBOLIC
DSKBLK==200 ;SIZE OF A DISK BLOCK
NBCSHE==20 ;NUMBER OF DISK BLOCKS TO CACHE FOR "READ" COMMAND
;STORAGE
OPNBLK: EXP 17,0,0 ;DUMP MODE, STR FILLED IN, NO BUFFERS
LUKBLK: BLOCK 4 ;LOOKUP BLOCK
EXEDIR: BLOCK DSKBLK ;EXE DIRECTORY
DCACHD: BLOCK NBCSHE*DSKBLK ;SPACE FOR THE CACHE
DCACHE: BLOCK NBCSHE ;SPACE FOR CACHE POINTERS
PDL: BLOCK 50 ;A STACK
SAVCHR: BLOCK 1 ;SAVED CHARACTER FROM GETONE
LOCORE: BLOCK 1 ;COPY OF MONITOR "LOCORE"
FRUSED: BLOCK 1 ;COPY OF "FRUSED"
FREPTR: BLOCK 1 ;COPY OF "FREPTR"
RNGTAB: BLOCK 1 ;ADDRESS OF RANGE TABLE
PDBPTR: BLOCK 1 ;ADDRESS OF JBTPDB FOR NULL JOB
JBTMXL: BLOCK 1 ;HIGHEST JOB+SEGN
JOBMAX: BLOCK 1 ;NUMBER OF JOBS (0-N)
FREAVB: BLOCK 1 ;NUMBER OF CHUNKS POSSIBLE
FRERTN: BLOCK 1 ;NUMBER OF CHUNKS RETURNED
PGTLEN: BLOCK 1 ;NUMBER OF PAGES DESCRIBED BY PAGTAB
EPTADR: BLOCK 1 ;BOOT CPU'S EPT
EPMADR: BLOCK 1 ;BOOT CPU'S EXEC MAP
JBTUPM: BLOCK 1 ;WHERE JBTUPM IS
JBTAD2: BLOCK 1 ;WHERE JBTAD2 IS
JBTADR: BLOCK 1 ;WHERE JBTADR IS
JBTSTS: BLOCK 1 ;WHERE JBTSTS IS
FYSORG: EXP 740000 ;ORIGIN OF PER-PROCESS AREA
LOWLIM: EXP CODE-400K ;LIMIT FOR PEEKING
PITSIZ: BLOCK 1 ;SIZE OF JBTPIA ENTRY
PTBADR: BLOCK 1 ;ADDRESS OF PAGTAB ON THIS SYSTEM
ERPTSZ: BLOCK 1 ;SIZE OF DAEMON ERROR ENTRY
ESVIDX: BLOCK 1 ;START OF ERROR TABLE
ERPTMX: BLOCK 1 ;MAXIM
EPKIDX: BLOCK 1 ;INDEX INTO TABLE
ERPTBK: BLOCK 10 ;THE BLOCK
SUBTTL Entry Point and Main Command Dispatch
FRECOR: JFCL ;NO CCL ENTRY
RESET ;START FRESH
MOVE P,[IOWD 50,PDL] ;GET A STACK
MOVE T1,[PUSHJ P,UUOCON] ;HOW TO GET TO THE LUUO HANDLER
MOVEM T1,41 ;STORE IN JOBDAT
MOVEI T1,CODE-1-400000 ;HIGHEST ADDRESS WHERE I'LL PUT MONITOR DATA
CORE T1, ;ASK FOR IT ALL
HALT . ;WHAT
NXTCOM: OUTSTR [ASCIZ/FRECOR>/] ;PROMPT THE OPERATOR
SETZB F,SAVCHR ;CLEAR FLAGS, NO SAVED CHARACTER NOW
PUSHJ P,GETSIX ;GET COMMAND AND MASK
JUMPE T1,NULCMD ;NULL COMMAND
MOVE T3,[-NUMCMD,,CMDTBL] ;GET AOBJN TO COMMAND TABLE
PUSHJ P,TABSRC ;LOOK IT UP IN THE TABLE
SKIPA T2,[NUMCMD] ;ILLEGAL COMMAND
MOVEI T2,NUMCMD+1 ;AMBIGUOUS COMMAND
PUSHJ P,@CMDDSP(T2) ;EXECUTE IT
MAIN.1: PUSHJ P,FLUSH ;EAT UP REST OF INPUT LINE
TLNN F,(FL.UPZ) ;YES, WAS END A CONTROL-Z
JRST NXTCOM ;NO, GET ANOTHER COMMAND
MONRT. ;YES, EXIT NOW
JRST FRECOR ;RESTART PROGRAM ON CONTINUE
NULCMD: TLNN F,(FL.EOL) ;JUST AN EMPTY LINE
PUSHJ P,BADFMT ;NO, COMPLAIN
JRST MAIN.1 ;THEN FLUSH INPUT LINE
DEFINE COMNDS,<
XLIST
X DDT,<go to DDT>
X FIND,<information about monitor pages>
X HELP,<types out this text>
X MONITOR,<look at the running monitor>
X READ,<FILE-SPEC Read a crash file>
LIST
SALL
>
DEFINE X(CMD,STR),<<SIXBIT/CMD />>
CMDTBL: COMNDS ;GENERATE THE COMMAND TABLE
NUMCMD==<.-CMDTBL> ;NUMBER OF COMMANDS
DEFINE X(CMD,STR),<EXP %'CMD>
CMDDSP: COMNDS ;GENERATE THE DISPATCH TABLE
EXP ILLCMD ;TYPE OUT ILLEGAL COMMAND
EXP AMBIGC ;TYPE OUT AMBIGUOUS COMMAND
DEFINE X(CMD,STR),<EXP [ASCIZ\STR\]>
CMDHLP: COMNDS ;GENERATE THE HELP DESCRIPTORS
SUBTTL Random Error Message Printers for Command Scanner
BADEXE: OUTSTR [ASCIZ/?Bad EXE Header code - Not an EXE file/]
JRST ERRXIT ;END LINE AND RETURN
COMEXE: OUTSTR [ASCIZ/?EXE Directory is too complex/]
JRST ERRXIT ;END LINE AND RETURN
AMBIGA: OUTSTR [ASCIZ/?Ambiguous Argument - "/]
JRST ILSXIT ;FINISH ERROR MESSAGE
ILLARG: OUTSTR [ASCIZ/?Unknown Argument - "/]
JRST ILSXIT ;FINISH ERROR MESSAGE
NOARGS: TLNN F,(FL.EOL) ;END OF INPUT
JRST BADFMT ;NO, GIVE DIFFERENT ERROR
OUTSTR [ASCIZ/?Missing Argument/]
JRST ERRXIT ;END LINE AND RETURN
JUNK: OUTSTR [ASCIZ/?Junk after end of command - "/]
SKIPA ;OUTPUT OFFENDING CHARACTER
BADFMT: OUTSTR [ASCIZ/?Command Error - "/]
CAIGE CH,40 ;A REGULAR CHARACTER
JRST [OUTCHR ["^"] ;NO, OUTPUT UP-ARROW
ADDI CH,100 ;MAKE A REAL LETTER
JRST .+1] ;RETURN INLINE
OUTCHR CH ;OUTPUT OFFENDING CHARACTER
JRST ILLXIT ;FINISH UP AND RETURN
AMBIGC: OUTSTR [ASCIZ/?Ambiguous Command - "/]
SKIPA ;SKIP OVER OTHER MESSAGE
ILLCMD: OUTSTR [ASCIZ/?Unknown Command - "/]
ILSXIT: PUSHJ P,SIXOUT ;APPEND COMMAND TYPED
ILLXIT: OUTCHR [""""] ;CLOSE QUOTES
ERRXIT:
CRPOPJ: OUTSTR [BYTE (7)15,12,0]
POPJ P,
SUBTTL The "FIND" Command
%FIND: SKIPN PGTLEN ;DO WE KNOW ABOUT PAGTAB YET
JRST [OUTSTR[ASCIZ/?Use READ or MONITOR command first/]
JRST ERRXIT] ;END LINE AND RETURN
PUSHJ P,GETNUO ;GET OCTAL PAGE NUMBER
SKIPGE P2,T1 ;COPY INTO P2 FOR LATER USE
JRST NOARGS ;IF -1, BAD ARGUMENTS (OR NONE)
MOVE P1,T1 ;COPY NUMBER
PUSHJ P,CMDEND ;NO MORE ARGUMENTS
JRST JUNK ;ISN'T
PUSHJ P,PGFTCH ;FETCH THE PAGTAB ENTRY FOR IT
TLNE T1,PT.FRE ;A FREE PAGE
JRST [OUTSTR[ASCIZ/Page is on the Free List/]
JRST CRPOPJ] ;END LINE AND RETURN
TLNE T1,PT.NXM ;NON-EXISTANT
JRST [OUTSTR[ASCIZ/Page is off-line/]
JRST CRPOPJ] ;END LINE AND RETURN
TLNE T1,PT.MON ;BELONG TO THE MONITOR
JRST [OUTSTR[ASCIZ/Page belongs to the Monitor/]
JRST CRPOPJ] ;END LINE AND RETURN
TLNE T1,PT.IPC ;BELONG TO IPCF
JRST [OUTSTR[ASCIZ/Page in somebody's IPCF queue/]
JRST CRPOPJ] ;END LINE AND RETURN
TLNE T1,PT.LPH!PT.LEV!PT.LIP ;ANY LOCK BITS
OUTSTR [ASCIZ/Page is locked /]
TLNE T1,PT.LPH ;PHYSICALLY CONTIGUOUS
OUTSTR [ASCIZ/physically contiguously/]
TLNE T1,PT.LEV ;IN EVM
OUTSTR [ASCIZ/in EVM/]
TLNE T1,PT.LIP ;IN PLACE
OUTSTR [ASCIZ/in place/]
TLNE T1,PT.LPH!PT.LEV!PT.LIP ;ANY OF THE ABOVE
OUTSTR [ASCIZ/ for /]
MOVE J,JOBMAX ;START AT HIGHEST JOB NUMBER
FIND.1: HRRZ T1,@JBTUPM ;PAGE NUMBER OF UPMP
CAIN T1,(P2) ;THIS THE ONE WE'RE LOOKING FOR
JRST [OUTSTR[ASCIZ/UPMP of /]
JRST FIND.5] ;PRETTY UP OUTPUT AND DONE
SOJG J,FIND.1 ;LOOK AT ALL UPMP'S
MOVEI J,1 ;START LOOKING AT ALL JOBS/SEGMENTS
FIND.2: MOVSI T1,SHRSEG ;SHARABLE SEGMENT BIT
CAMLE J,JOBMAX ;IS THIS A SEGMENT
TDNE T1,@JBTSTS ;YES, IS IT SHARABLE
SKIPN @JBTADR ;CHECK IF IN CORE
JRST FIND.4 ;NON-SHARABLE SEGMENTS ARE COUNTED IN JOB LOW SEG
LDB P1,[POINT 13,@JBTUPM,35] ;JBYHSA
CAMG J,JOBMAX ;IS THIS A HIGH SEGMENT
LDB P1,[POINT 13,@JBTAD2,35] ;JBYLSA
FIND.3: CAIN P1,(P2) ;IS THIS THE PAGE WE'RE LOOKING FOR
JRST FIND.5 ;FOUND
PUSHJ P,PGFTCH ;GET PAGTAB ENTRY FOR PAGE IN JOB/SEGMENT
HRRZ P1,T1 ;GET LINK TO NEXT PAGE IN SEGMENT/JOB
JUMPN P1,FIND.3 ;CONTINUE WITH JOB/SEGMENT
FIND.4: CAMG J,JBTMXL ;OFF THE END OF JOBS/SEGMENTS
AOJA J,FIND.2 ;NO, LOOK AT NEXT ONE
OUTSTR [ASCIZ/?Not found for any job or segment/]
JRST CRPOPJ ;END LINE AND RETURN
FIND.5: CAMLE J,JOBMAX ;JOB OR SEGMENT
SKIPA T1,[[ASCIZ/Segment /]]
MOVEI T1,[ASCIZ/Job /]
FORMAT <,<OUTSTR @T1>,,<DEC J>,< (>,<OCT J>,< octal)>>
JRST CRPOPJ ;END LINE AND RETURN
POPJ P,
SUBTTL The "READ" Command
%READ: PUSHJ P,GETFN ;GO GET THE FILE TO READ
POPJ P, ;ALREADY GAVE ERROR
PUSHJ P,CMDEND ;REALLY OUGHT TO BE THE END
JRST JUNK ;ISN'T
OPEN XPN,OPNBLK ;OPEN THE STR
POPJ P, ;FAILED
LOOKUP XPN,LUKBLK ;GET THE FILE
POPJ P, ;FAILED
IN XPN,IOLST1 ;READ EXE DIRECTORY, PAGE 0 INTO 1000
CAIA ;OK SO FAR
HALT . ;WHAT
MOVE T1,[1140,,140] ;140 FROM EXE FILE INTO MY 140
BLT T1,777 ;GET ALL OF PAGE 0 BUT JOBDAT
IN XPN,IOLST2 ;GET REST OF FILE LOW SEGMENT
CAIA ;OK SO FAR
HALT . ;WHAT
HLRZ T1,EXEDIR ;GET EXE HEADER CODE
CAIE T1,1776 ;BETTER BE
JRST BADEXE ;BAD DIRECTORY FORMAT
HRRZ T1,EXEDIR ;GET LENGTH OF DIRECTORY
CAIL T1,DSKBLK ;CHECK AGAINST SPACE ALLOCATED
JRST COMEXE ;TOO COMPLEX
MOVEI T1,DCACHD ;POINT TO THE DATA BUFFERS
MOVSI T2,-NBCSHE ;NUMBER OF BUFFERS
HRROM T1,DCACHE(T2) ;MARK ENTRY AVAILABLE
ADDI T1,DSKBLK ;STEP TO NEXT BUFFER
AOBJN T2,.-2 ;PRIME THE TABLES
JRST MONCOM ;JOIN COMMON CODE
IOLST1: IOWD 1000,EXEDIR ;EXE DIRECTORY (CLOBBER SOME OF DCACHD)
IOWD 1000,1000 ;PAGE 0 INTO PAGE 1
0
IOLST2: IOWD CODE-401K,1000 ;ENTIRE LOW SEGMENT NOW
0
SUBTTL The "MONITOR" Command
%MONIT: PUSHJ P,CMDEND ;NO ARGUMENTS
JRST JUNK ;JUNK ON THE LINE
SETZM EXEDIR ;NO EXE DIRECTORY NOW
MOVE T1,[%CNSIZ] ;SIZE OF THE MONITOR
GETTAB T1, ;DON'T USE SIMULATOR, WANT REAL CURRENT
HALT . ;WHAT
MOVEI T1,-1(T1) ;WANT HIGHEST ADDRESS
CAILE T1,377777 ;LESS THAN 128K?
MOVEI T1,377777 ;NO, GO FOR THE MAX
CAILE T1,CODE-400000 ;TOO BIG?
MOVEI T1,CODE-400000 ;YEP
MOVE T2,T1 ;SAVE ADDRESS
SPY T1, ;SPY ON THE MONITOR
HALT . ;WHAT
MOVE T1,[400140,,140] ;MONITOR 140 TO MY 140
BLT T1,(T2) ;COPY SO WE DON'T GET CONFUSED BY CHANGES
HRRZM T1,LOWLIM ;SAVE INITIAL LIMIT
JRST MONCOM ;JOIN COMMON CODE
SUBTTL Check Out the Free Core
MONCOM: FORMAT <,<CRLF>,<Monitor is:>,<CRLF>,,<CRLF>,,<GTTA [%CNFG0]>>
FORMAT <,<GTTA [%CNFG1]>,,<GTTA [%CNFG2]>,,<GTTA [%CNFG3]>,,<GTTA [%CNFG4]>>
OUTCHR [11] ;ALIGN WITH A TAB
GTTAB %CNMON ;GET MONTH NUMBER
OUTSTR MONTAB-1(T1) ;OUTPUT MONTH
FORMAT << >,<GTTD [%CNDAY]>,<,>,<GTTD [%CNYER]>>
FORMAT << >,<GTTD [%CNHOR]>,<:>,<GTTD2 [%CNMIN]>,<:>,<GTTD2 [%CNSEC]>>
FORMAT <,<CRLF>,,<CRLF>>
GTTAB %CNNWC ;AMOUNT OF CORE POSSIBLE
LSH T1,-^D9 ;TO NUMBER OF PAGES
MOVEM T1,PGTLEN ;STORE LENGTH OF PAGTAB
GTTAB %CNBCP ;FIND A BOOT CPU
LSH T1,1 ;*2 FOR CPU SPECIFIC GETTABS
MOVE P1,T1 ;SAVE IT
ADD T1,[%CCTOS] ;FIND EPT ADDRESS
PUSHJ P,GTBSPY ;GET IT (SHOULD SMARTEN UP GTTAB MACRO)
HALT . ;WHAT?
MOVEM T1,EPTADR ;SAVE FOR LATER
ADDI T1,1000 ;OFFSET TO EXEC MAP
MOVEM T1,EPMADR ;SAVE FOR LATER
MOVE T1,[%CCTYP] ;FIND CPU TYPE
ADD T1,P1
PUSHJ P,GTBSPY ;GET IT
HALT . ;WHAT?
CAIE T1,.CCKLX ;KL-10 SYSTEM?
SKIPA T1,[PAGTAB] ;NO, GET KS PAGTAB OFFSET
MOVSI T1,(MS.MEM) ;YES, GET PAGTAB/MEMTAB SECTION
MOVEM T1,PTBADR ;WHERE PAGTAB STARTS ON THIS MACHINE
GTTAB %VMPPB ;GET BEGINNING OF PER-PROCESS AREA
MOVEM T1,FYSORG ;SAVE IT
CAILE T1,CODE-400K ;DOES IT FIT?
MOVEI T1,CODE-400K ;NO, STOP AT OUR LIMIT
CAMG T1,LOWLIM ;IF THIS IS A RESTRICTION,
MOVEM T1,LOWLIM ;SAVE WHERE WE STOP PEEKING
GTTAB %CNSJN ;GET JOB/SEGMENT INFORMATION
SOS T1 ;DECREMENT TO HIGHEST JOB NUMBER
HRRZM T1,JOBMAX ;STORE
HLRE T2,T1 ;GET NUMBER OF SEGMENTS
MOVNS T2 ;FROM AOBJN TYPE TO A REAL NUMBER
ADDI T2,(T1) ;NUMBER OF JOBS + SEGMENTS
MOVEM T2,JBTMXL ;STORE FOR GETTAB SIMULATOR
GTTAB %CNPDB ;FIND OUT BASE OF PDB'S
MOVEM T1,PDBPTR ;STORE IT TOO
GTTAB <.GTIDX,,.GTSLF> ;BASE OF RANGE TABLE FOR GETTABS
HRRZM T1,RNGTAB ;STORE THAT TOO
GTTAB <.GTUPM,,.GTSLF> ;BASE OF JOB UPMP TABLE
HRRZS T1 ;ISOLATE ADDRESS
ADD T1,[Z MONITR(J)] ;FUTURE INDIRECT REFERENCES
MOVEM T1,JBTUPM ;STORE ADDRESS OF JBTUPM
GTTAB <.GTSTS,,.GTSLF> ;BASE OF JOB STATUS TABLE
HRRZS T1 ;ISOLATE ADDRESS
ADD T1,[Z MONITR(J)] ;FUTURE INDIRECT REFERENCES
MOVEM T1,JBTSTS ;STORE ADDRESS OF JBTSTS
GTTAB <.GTADR,,.GTSLF> ;BASE OF JOB ADDRESS TABLE
HRRZS T1 ;ISOLATE ADDRESS
ADD T1,[Z MONITR(J)] ;FUTURE INDIRECT REFERENCES
MOVEM T1,JBTADR ;STORE ADDRESS OF JBTADR
GTTAB <.GTPRV,,.GTSLF> ;HACK COMING
HRRZS T1 ;ISOLATE ADDRESS
SUB T1,JOBMAX ;JBTAD2 IS NOT GETTABABLE
SUB T1,JOBMAX ;BUT IT IS JBTPRV-2*JOBN
SUBI T1,2 ;ACCOUNT FOR TWICE THE NULL JOB REMOVED ABOVE
ADD T1,[Z MONITR(J)] ;FUTURE INDIRECT REFERENCES
MOVEM T1,JBTAD2 ;STORE IT (HACK)
GTTAB %CNFRE ;POINTER TO FREE CORE BIT MAP
MOVEM T1,FREPTR ;STORE
HLRE T1,T1 ;SIZE OF TABLE
MOVNS T1 ;TO A REAL NUMBER
IMULI T1,^D36 ;TO CHUNKS AVAILABLE
MOVEM T1,FREAVB ;STORE FOR PERCENT COMPUTATIONS
GTTAB %CNLOC ;WHERE FREE CORE STARTS
MOVEM T1,LOCORE ;STORE
GTTAB %CNFRU ;CURRENT AMOUNT USED
MOVEM T1,FRUSED ;STORE
FORMAT <<Free Core Used = >,<OCT4 FRUSED>,< Words = >,<PER>,,<CRLF>>
PUSHJ P,RTNPDB ;ACCOUNT FOR PDB SPACE
PUSHJ P,RTNPSI ;GET PSISER DATA BASE
PUSHJ P,RTNSTR ;GET STR DATA BASE, SAT, SPT
PUSHJ P,RTNCPY ;RETURN UPDATE FILE RIB POINTERS
PUSHJ P,RTNDDB ;ANY DDBS CARVED OUT OF FREE SPACE
PUSHJ P,RTNIPC ;DO IPCF RECEIVE QUEUES
; PUSHJ P,RTNLNM ;RETURN JOBS LOGICAL NAME TABLES
PUSHJ P,RTNPTH ;RETURN PATH BLOCKS FOR EXE'S FROM SFD'S
PUSHJ P,RTNCTX ;RETURN SAVED CONTEXT BLOCKS
PUSHJ P,RTNENQ ;RETURN ENQ/DEQ LOCK BLOCKS
PUSHJ P,RTNNET ;NETSER STUFF
PUSHJ P,RTNDTE ;RETURN DTESER STUFF
PUSHJ P,RTNCSH ;RETURN DISK CACHE STUFF
PUSHJ P,RTNEBM ;RETURN EXTENSIBLE BITMAP MEMORY
PUSHJ P,RTNDAE ;RETURN DAEMON ERROR STUFF
PUSHJ P,RTNNRT ;*** MUST BE LAST *** RETURN NRTSER STUFF
JRST LEFT ;TELL WHATS LEFT OVER
;HERE TO ACCOUNT FOR PDB SPACE USED BY JOBS
RTNPDB: MOVEI P1,PDBLEN ;NUMBER OF WORDS IN A PDB
MOVE P2,PDBPTR ;ADDR OF JBTPDB
MOVSI P3,'PDB' ;TEXT FOR TYPEOUT
RTNCOM: MOVE J,JOBMAX ;FOR ALL JOBS
SETZM FRERTN ;START COUNTS FRESH
RTNC.1: DMOVE T1,P1 ;SIZE AND JBTXXX BASE
ADDI T2,(J) ;FOR JOB N
HRRZ T2,MONITR(T2) ;GET TABLE ADDRESS
SKIPE T2 ;ANY THERE
PUSHJ P,GIVWDS ;YES, RETURN IT
SOJGE J,RTNC.1 ;GET ALL INCLUDING THE NULL JOB
FORMAT <,<SIX P3>,< Space is >,<OCT4 FRERTN>>
JRST CRPOPJ ;CRLF AND EXIT
;HERE TO ACCOUNT FOR PSISER DATA BASE
RTNPSI: GTTAB %CNPIL ;LENGTH OF PSI DATA BASE
MOVE P1,T1 ;COPY SIZE
MOVEM T1,PITSIZ ;SAVE FOR LATER
GTTAB %CNPIA ;ADDRESS OF JBTPIA
MOVE P2,T1 ;COPY IT
MOVSI P3,'PSI' ;TEXT FOR TYPE OUT
JRST RTNCOM ;USE COMMON CODE
;HERE TO ACCOUNT FOR PATH BLOCKS FOR EXE FILES RUN FROM SFD'S
RTNPTH: SETZM FRERTN ;START FRESH
MOVE J,JBTMXL ;HIGHEST SEGMENT NUMBER
PTH.1: GTTAB <-1,,.GTPPN> ;JBTPPN FOR EXE FILE
SKIPN T2,T1 ;COPY ADDRESS
JRST PTH.2 ;NEVER MIND
MOVEI T1,PTHLEN ;NUMBER OF WORDS TO RETURN
TLNN T2,-1 ;WAIT, IS THAT REALLY A PPN LIKE THE OLD DAYS
PUSHJ P,GIVWDS ;NOPE, RETURN IT
PTH.2: CAMLE J,JOBMAX ;INTO REAL JOB TABLES YET
SOJA J,PTH.1 ;NO, KEEP GOING
FORMAT <<High Seg PATH. Block Space is >,<OCT4 FRERTN>>
JRST CRPOPJ ;RETURN
;HERE TO ACCOUNT FOR JOB LOGICAL NAME TABLE
REPEAT 0,<;REMOVED FROM 7.04
RTNLNM: SETZM FRERTN ;START FRESH
MOVE J,JOBMAX ;FOR ALL JOBS
LNM.1: GTTAB <-1,,.GTDVL> ;LOGICAL NAME TABLE
HRRE T2,T1 ;WHERE IT IS
MOVEI T1,LNMLEN ;NUMBER OF WORDS
SKIPLE T2 ;IS THERE ONE
PUSHJ P,GIVWDS ;YES, RETURN IT
SOJG J,LNM.1 ;GET ALL JOBS
FORMAT <<Logical Name Space is >,<OCT4 FRERTN>>
JRST CRPOPJ ;RETURN
> ;END REPEAT 0
;HERE TO ACCOUNT FOR COPIES OF RIB POINTERS FOR UPDATE FILES
RTNCPY: SETZM FRERTN ;START FRESH
GTTAB %LDPTR ;GET POINTER TO FIRST UPDATE FILE RIB POINTER COPY
HLRZ P1,T1 ;COPY IT
CPY.1: JUMPE P1,CPY.2 ;ALL DONE
MOVE T2,P1 ;ADDRESS OF BLOCK
MOVEI T1,PTRCOR ;SIZE OF THE BLOCK
PUSHJ P,GIVWDS ;RETURN THE SPACE
HLRZ P1,PTRSYS(P1) ;STEP TO NEXT BLOCK
JRST CPY.1 ;GET THEM ALL
CPY.2: FORMAT <<File Pointer Copy Space is >,<OCT4 FRERTN>>
JRST CRPOPJ ;AND RETURN
;HERE TO ACCOUNT FOR SAVED CONTEXT BLOCKS
RTNCTX: SETZM FRERTN ;START FRESH
MOVE J,JOBMAX ;FOR EACH JOB
CTX.1: MOVE P1,J ;COPY JOB NUMBER
ADD P1,PDBPTR ;ADDRESS OF JBTPDB FOR JOB
HRRZ P1,MONITR(P1) ;GET ADD OF PDB ITSELF
JUMPE P1,CTX.5 ;NONE, GET ANOTHER JOB
HRRZ T2,MONITR+.PDSCX(P1) ;GET ADDRESS OF SAVED CONTEXT BLOCK
JUMPE T2,CTX.2 ;NONE
MOVEI T1,NWSCTX ;WORDS IN A CONTEXT BLOCK
CAMGE T2,FYSORG ;MIGHT BE IN FUNNY SPACE
PUSHJ P,GIVWDS ;ISN'T, RETURN LOW CORE
CTX.2: MOVE P3,MONITR+.PDCTC(P1) ;GET CURRENT CONTEXT
MOVE T2,MONITR+.PDSAC(P1) ;GET START OF CONTEXT CHAIN
CTX.3: SKIPN P2,T2 ;COPY ADDRESS
JRST CTX.5 ;NONE?
MOVEI T1,.CTSIZ ;NUMBER OF WORDS
TLNN T2,-1 ;NZS ADDRESS?
PUSHJ P,GIVWDS ;RETURN THEM
;REPEAT 0,< ;THIS DOESN'T WORK?
MOVE T1,P2 ;ADDRESS OF THIS BLOCK
ADDI T1,.CTBPR+.CXPIA ;OFFSET TO POINTER TO SAVED JBTPIA BLOCK
PUSHJ P,WDFTCH ;GET IT
CAME P2,P3 ;IGNORE THE CURRENT CTX
SKIPN T2,T1 ;COPY ADDRESS
JRST CTX.3A ;NOTHING
MOVE T1,PITSIZ ;SIZE OF A BLOCK
PUSHJ P,GIVWDS ;RETURN IT
;>; END REPEAT 0
CTX.3A:
;REPEAT 0,< ;THIS DOESN'T WORK?
CAMN P2,P3 ;THE "CURRENT" CONTEXT?
JRST CTX.4 ;YES, IGNORE SAVED CONTEXT BLOCK
MOVE T1,P2 ;ADDRESS OF THIS BLOCK
ADDI T1,.CTBPR+.CXSCX ;OFFSET TO POINTER TO SAVED CONTEXT BLOCK
PUSHJ P,WDFTCH ;GET IT
SKIPN T2,T1 ;COPY ADDRESS
JRST CTX.4 ;NOTHING THERE, DON'T TRY TO RETURN IT
MOVEI T1,NWSCTX ;WORDS IN A CONTEXT BLOCK
CAMGE T2,FYSORG ;MIGHT BE IN FUNNY SPACE
PUSHJ P,GIVWDS ;ISN'T, RETURN LOW CORE
;>; END REPEAT 0
CTX.4: MOVE T1,P2 ;ADDRESS OF THIS BLOCK
ADDI T1,.CTNXT ;OFFSET TO LINK WORD
PUSHJ P,WDFTCH ;GET IT
MOVE T2,T1 ;COPY ADDRESS
JRST CTX.3 ;GIVE IT BACK
CTX.5: SOJG J,CTX.1 ;AND GET ALL THE JOBS
FORMAT <<Saved Context Space is >,<OCT4 FRERTN>>
JRST CRPOPJ ;AND RETURN
;HERE TO ACCOUNT FOR STUFF REQUIRED BY DISK STRUCTURES
RTNSTR: GTTAB %LDSTR ;FIRST STRUCTURE IN SYS
HLRZ P1,T1 ;PUT IN SAFER PLACE
SETZ P5, ;CLEAR TOTAL COUNT
STR.1: JUMPE P1,STR.7 ;DONE IF LAST STR
SKIPN STRNAM(P1) ;A REAL STRUCTURE THERE
JRST STR.6 ;NO, DON'T BOTHER
SETZM FRERTN ;START COUNTS OVER FOR EACH STR
MOVE T2,P1 ;WHERE STR DATA BLOCK IS
MOVEI T1,STRLEN ;AND HOW LONG IT IS
CAML T2,LOCORE ;MOUNTED AT ONCE TIME
PUSHJ P,GIVWDS ;NO, REMOVE THE CORE
HLRZ P2,STRUNI(P1) ;STEP TO FIRST UNIT IN STR
STR.2: JUMPE P2,STR.5 ;LAST UNIT, GO TO NEXT STR
MOVEI T1,UNISAB(P2) ;GET ADDRESS OF WORD WE WANT
PUSHJ P,WDFTCH ;GET IT
SKIPE P3,T1 ;GET SAT BLOCK TABLE ADDRESS
TLZE P3,-1 ;SKIP THIS IF ITS NOT IN SECTION 0
JRST STR.4 ;SKIP THIS WHOLE SAT
MOVE J,P3 ;COPY WHERE RING STARTS
LDB P4,[POINT 9,UNIWPS(P2),8] ;GET SIZE OF SAT ON THIS UNIT
STR.3: MOVE T2,P3 ;ADDR OF SAB
MOVEI T1,SABBIT(P4) ;SPACE ALLOCATED
CAML T2,LOCORE ;FROM ONCE
PUSHJ P,GIVWDS ;NO, RETURN THE SPACE
MOVE P3,SABRNG(P3) ;TO NEXT SAB IN RING
JUMPE P3,STR.3A ;CHECK LINK WORD
CAIE P3,(J) ;BACK WHERE WE STARTED
JRST STR.3 ;NOPE, DO THE NEXT ONE
JRST STR.4 ;DONE WOTH SAB RING, GET SPT
STR.3A: FORMAT <<SAB Ring Messed Up for >,<SIX UNINAM(P2)>,,<CRLF>>
STR.4: MOVEI T1,UNISPT(P2) ;ADDRESS OF THE SPT
PUSHJ P,WDFTCH ;GET IT
TLZE T1,-1 ;UNLESS IN A NON-ZERO SECTION
JRST STR.4A ;SKIP THE SPT
MOVE T2,T1 ;SAVE A COPY
LDB T1,[POINT 8,UNISPU(P2),17] ;SIZE OF THE SPT ON THIS UNIT
ADDI T1,SPTFIR+1 ;PLUS OVERHEAD
CAML T2,LOCORE ;IN FREE CORE
PUSHJ P,GIVWDS ;RETURN IT
STR.4A: MOVEI T1,UNISTR(P2) ;WORD WE WANT
PUSHJ P,WDFTCH ;GET IT
HLRZ P2,T1 ;STEP TO NEXT UNIT IN STRUCTURE
JRST STR.2 ;AND DO THAT ONE
STR.5: SKIPN T1,FRERTN ;DON'T BOTHER IF NO SPACE RECLAIMED
JRST STR.6 ;NONE, TRY ANOTHER
ADD P5,T1 ;ACCUMULATE TOTAL
FORMAT <,<SIX STRNAM(P1)>,<: >,<OCT4 T1>,< Words>,<CRLF>>
STR.6: HLRZ P1,STRSYS(P1) ;TO NEXT FILE STRUCTURE
JRST STR.1 ;AND DO IT
STR.7: FORMAT <<Total File Structure Space is >,<OCT4 P5>>
JRST CRPOPJ ;AND RETURN
;HERE TO ACCOUNT FOR ENQ/DEQ LOCK BLOCKS
RTNENQ: GTTAB %CNHSH ;-LEN,,ADDR OF HSHTAB
HLRE J,T1 ;GET -VE LENGTH
MOVMS J ;MAKE +VE
MOVEI P1,-1(T1) ;POINT TO LAST ENTRY IN HSHTAB
ADDI P1,(J) ;...
SETZM FRERTN ;START FRESH
ENQ.1: HRRZ P2,.LBNHS(P1) ;FIRST LOCK BLOCK OFF THIS ENTRY
ENQ.2: CAIN P2,(P1) ;CHAIN ENDS WHEN WE GET BACK TO HSHTAB
JRST ENQ.5 ;LOOK AT NEXT HSHTAB ENTRY
HRRZ P3,.LBNQ(P2) ;FIRST Q-BLOCK
ENQ.3: CAIN P3,(P2) ;BACK TO THE LOCK BLOCK
JRST ENQ.4 ;YES, DONE WITH Q-BLOCKS
MOVE T2,P3 ;ADDR OF Q-BLOCK
MOVEI T1,QBSIZE ;AND LENGTH OF IT
HRRZ P4,.QBMSK(P3) ;POINT TO ANY MASK BLOCK OWNED
HRRZ P3,.QBNQ(P3) ;NEXT Q-BLOCK IN CHAIN
PUSHJ P,GIVWDS ;RETURN THIS BLOCK
JUMPE P4,ENQ.3 ;GET NEXT Q-BLOCK IF NO MASK BLOCK
MOVE T2,P4 ;ADDRESS OF IT
HLRZ T1,.LBNMS(P2) ;LENGTH OF IT
PUSHJ P,GIVWDS ;RETURN MASK BLOCK
JRST ENQ.3 ;AND CHECK OUT NEXT Q-BLOCK
ENQ.4: MOVE T2,P2 ;ADDRESS OF THE BLOCK
HLRZ T1,.LBLEN(P2) ;LENGTH OF THE BLOCK
PUSHJ P,GIVWDS ;RETURN THE SPACE
HRRZ P2,.LBNHS(P2) ;NEXT BLOCK IN THE CHAIN
JRST ENQ.2 ;CHECK IT OUT
ENQ.5: SOS P1 ;BACK DOWN HSHTAB
SOJG J,ENQ.1 ;TRY NEXT ENTRY
FORMAT <<ENQ/DEQ Lock Block Space is >,<OCT4 FRERTN>>
JRST CRPOPJ ;AND RETURN
;HERE TO ACCOUNT FOR DDB'S BUILT IN FREE CORE
;WARNING:
; DO NOT RETURN NETWORK DDB'S IN THIS ROUTINE
RTNDDB: FORMAT <<Scanning free core for DDB's>,<CRLF>>
SETZM FRERTN ;START FRESH
GTTAB %CNDEV ;START OF DDB CHAIN
HLRZ P2,T1 ;SAVE ADDRESS OF FIRST DDB
DDB.1: CAMGE P2,LOCORE ;IN FREE SPACE
JRST DDB.2 ;NO, TRY ANOTHER
CAML P2,LOWLIM ;UP IN MONITORS HIGHSEG (DSKDDB)
JRST DDB.2 ;YES, QUIT NOW, MAY LOSE SOME DDBS
FORMAT << >,<SIX DEVNAM(P2)>,< at >,<OCT P2>,< size >>
HLLZ T4,DEVNAM(P2) ;GET WHAT IT IS
MOVE T2,P2 ;ADDRESS FOR RETURN
SETZ T1, ;IN CASE WE DON'T KNOW ABOUT IT
MOVE T3,DEVMOD(P2) ;GET DEVMOD
TLNE T3,DVDSK ;IS IT A "FAKE" DISK DDB
JRST [MOVEI T1,DSKDDS ;YES, GET DISK DDB SIZE
JRST DDB.0] ;AND RETURN THE SPACE
MOVSI T3,-NUMDVS ;NUMBER HARD-WIRED
CAME T4,DVSNMS(T3) ;LOOK FOR IT
AOBJN T3,.-1 ;TRY NEXT
SKIPGE T3 ;KNOWN
XCT DVSLDS(T3) ;YES, GET SIZE VALUE
DDB.0: FORMAT <,<OCT T1>,,<CRLF>>
SKIPE T1 ;KNOW THE SIZE
PUSHJ P,GIVWDS ;YES, RETURN SOME
DDB.2: MOVEI T1,DEVSER(P2) ;ADDRESS TO FETCH
CAMGE T1,LOWLIM ;DOES IT FIT?
SKIPA T1,MONITR(T1) ;YES--JUST GRAB IT
PUSHJ P,WDFTCH ;NO--GET IT THE HARD WAY
HLRZ P2,T1 ;STEP TO NEXT DEVICE
JUMPN P2,DDB.1 ;LOOK AT IT
DDB.3: FORMAT <<DDB Space is >,<OCT4 FRERTN>>
JRST CRPOPJ ;RETURN
DVSNMS: SIXBIT /MPX/ ;MPX DEVICE
SIXBIT /'LA/ ;MTA LABEL DDB
SIXBIT /'LB/ ;MTB LABEL DDB
SIXBIT /'LC/ ;MTC LABEL DDB
SIXBIT /'LD/ ;MTD LABEL DDB
SIXBIT /'LE/ ;MTE LABEL DDB
SIXBIT /'LF/ ;MTF LABEL DDB
NUMDVS==.-DVSNMS ;NUMBER KNOWN
DVSLDS: PUSHJ P,DVSMPX ;MPX IS SPECIAL
MOVEI T1,SPROTO ;LENGTH OF A MAG TAPE LABEL DDB
MOVEI T1,SPROTO ;LENGTH OF A MAG TAPE LABEL DDB
MOVEI T1,SPROTO ;LENGTH OF A MAG TAPE LABEL DDB
MOVEI T1,SPROTO ;LENGTH OF A MAG TAPE LABEL DDB
MOVEI T1,SPROTO ;LENGTH OF A MAG TAPE LABEL DDB
MOVEI T1,SPROTO ;LENGTH OF A MAG TAPE LABEL DDB
DVSMPX: MOVEI T1,MPXLEN ;SIZE OF MPX DDB
FORMAT <,<OCT T1>,,<CRLF>>
PUSHJ P,GIVWDS ;RETURN DDB
HLRZ T2,DEVXTR(P2) ;ADDRESS OF CDT
SKIPE T1,T2 ;MIGHT NOT BE ANY
HLRZ T1,MONITR(T2) ;LENGTH OF CDT
FORMAT << CDT at >,<OCT T2>,< size >>
POPJ P, ;RETURN TO GIVE BACK CDT INSTEAD OF DDB
;HERE TO ACCOUNT FOR IPCF RECEIVE QUEUES
RTNIPC: FORMAT <<Scanning IPCF Receive Queues>,<CRLF>>
SETZM FRERTN ;START FRESH
MOVE J,JOBMAX ;GET ALL JOBS
IPC.1: GTTAB <-1,,.GTIPP> ;IPCF POINTERS FOR JOB (J)
HLRZ P2,T1 ;GET ADDRESS OF FIRST MESSAGE
ANDI T1,777 ;ISOLATE COUNT OF MESSAGES
JUMPE T1,IPC.3 ;NONE, GET NEXT JOB
FORMAT << Job >,<DEC J>,< has >,<DEC T1>,< messages>,<CRLF>>
IPC.2: JUMPE P2,IPC.3 ;NEXT JOB
MOVE T2,P2 ;FOR RETURN
SKIPGE MONITR+.IPCFP(P2) ;SKIP IF NOT ON DISK
JRST [SETZ T1, ;NOT IN CORE, GET A ZERO
JRST IPC.2A] ;CONTINUE
MOVEI T1,IP.CFV ;PAGE MODE?
TDNE T1,MONITR+.IPCFL(P2) ;IN PACKET HEADER?
JRST [LDB T1,[POINT 21,MONITR+.IPCFP(P2),35] ;GET PAGE NUMBER
FORMAT << Page >,<OCT T1>,< is in-core>,<CRLF>>
SETZ T1, ;ZERO LENGTH
JRST IPC.2A] ;CONTINUE
LDB T1,[POINT 10,MONITR+.IPCFP(P2),12] ;GET LENGTH
IPC.2A: ADDI T1,.IPCFC+1 ;PLUS OVERHEAD
PUSHJ P,GIVWDS ;RETURN IT
IPC.2B: HLRZ P2,MONITR+.IPCFL(P2) ;LINKED THROUGH LH OF FLAG WORD
JRST IPC.2 ;AND TRY THAT
IPC.3: SOJG J,IPC.1 ;GET ALL THE JOBS
FORMAT <<IPCF Space is >,<OCT4 FRERTN>>
JRST CRPOPJ ;RETURN
;HERE TO ACCOUNT FOR NETWORK FREE CORE
;ASSUMPTIONS:
; NETSER HAS "PARANOID" AND "P$COR" TURNED ON
; %NTMEM IS NOT GETTABABLE BUT IS "NETGTT-1" (HACK)
RTNNET: GTTAB <.GTNTP,,.GTSLF> ;ADDRESS OF NETGTT
TLNN T1,777000 ;CHECK TABLE LENGTH
POPJ P, ;ZERO, GETTAB REMOVED
MOVEI P1,-1(T1) ;POINT TO %NTMEM ( I KNOW )
SETZM FRERTN ;START COUNT FRESH
NET.1: HRRZ P1,MONITR(P1) ;NEXT ITEM ON NETWORK LIST
JUMPE P1,NET.3 ;DONE ON ZERO LINK
MOVEI T1,1 ;THERE IS NO COUNT WORD, MUST COMPUTE LENGTH
MOVEI T2,(P1) ;WHERE IT STARTS
MOVEI T3,(P1) ;AND A WORKING COPY
NET.2: MOVE T4,MONITR(T3) ;GET A WORD
CAME T4,[SIXBIT/NETMEM/] ;THIS PATTERN IS THE LAST WORD OF THE SPACE
AOJA T1,[AOJA T3,NET.2] ;NOT END, COUNT WORD AND GO TO NEXT ONE
PUSHJ P,GIVWDS ;RETURN THE SPACE
JRST NET.1 ;AND GET NEXT CHUNK
NET.3: FORMAT <<NETWORK Space is >,<OCT4 FRERTN>,< (NETSER Claims it knows >,<GTTO [%NTCOR]>,<)>,<CRLF>>
POPJ P, ;DONE WITH NETWORKS
;HERE TO ACCOUNT FOR NRTSER FREE CORE (AS MUCH AS WE CAN)
;NOTE: NRTSER USES NO LINKED LISTS TO KEEP TRACK OF ALLOCATED
;CORE. WE DEPEND ON HIM STORING THE ADDRESS OF EVERY CHUNK
;OF MEMORY ALLOCATED IN HIS "CHANNEL TABLE".
RTNNRT: SETZM FRERTN ;START COUNTS FRESH
GTTAB %DNNCH ;GET ADDRESS OF NRTSER'S CHANNEL TABLE POINTER
JUMPE T1,CPOPJ ;RETURN IF NO TABLE
MOVE P1,MONITR(T1) ;GET THE TABLE ADDRESS
HRRZ T2,MONITR+3(T1) ;GET POINTER TO NRTSER'S SAB
HLRZ T1,MONITR-1(T2) ;GET CHECK WORD
CAIE T1,'NRT' ;SHOULD BE THIS
POPJ P, ;NOPE
HRRZ T1,MONITR-1(T2) ;GET LENGTH
ADDI T1,1 ;ACCOUNT FOR NRTSER'S LEADING TAG WORD
SUBI T2,1 ;POINT AT REAL START OF BLOCK
PUSHJ P,GIVWDS ;RETURN THE SPACE
HLRZ T1,MONITR-1(P1) ;GET THE LH OF FIRST WORD
CAIE T1,'NRT' ;SHOULD BE THIS
POPJ P, ;NOT, WE DON'T KNOW WHAT TO DO HERE
HRRZ T1,MONITR-1(P1) ;GET LENGTH OF HIS TABLE
MOVN T2,T1 ;NEGATE LENGTH
HRL P1,T2 ;MAKE AN AOBJN POINTER
ADDI T1,1 ;ACCOUNT FOR NRTSER'S LEADING TAG WORD
MOVEI T2,-1(P1) ;POINT AT REAL START OF BLOCK
PUSHJ P,GIVWDS ;RETURN THE SPACE
NRT.1: SKIPN T2,MONITR(P1) ;GET AN ENTRY FROM CHANNEL TABLE
JRST NRT.2 ;NOTHING THERE
HLRZ T1,MONITR-1(T2) ;GET THE CHECK WORD
CAIE T1,'NRT' ;NRTSER'S TAG?
JRST NRT.2 ;NOPE, LEAVE IT ALONE
HRRZ T1,MONITR-1(T2) ;GET SIZE OF BLOCK
ADDI T1,1 ;ACCOUNT FOR NRTSER'S LEADING TAG WORD
MOVEI T2,-1(T2) ;POINT AT REAL START OF BLOCK
PUSHJ P,GIVWDS ;RETURN THE SPACE
NRT.2: AOBJN P1,NRT.1 ;LOOP FOR ALL ENTRIES
FORMAT <<NRTSER Space is >,<OCT4 FRERTN>>
JRST CRPOPJ ;RETURN
;HERE TO ACCOUNT FOR HASH BLOCKS IN THE DISK CACHE AND THE DATA
;BLOCKS (KS ONLY).
RTNCSH: GTTAB %LDCHD ;GET HEADER OF CACHE LIST
MOVE P1,T1 ;SAVE IT HERE
SETZM FRERTN ;START COUNTS FRESH
MOVEI T1,.CBNHB(P1) ;POINTER TO FREE LIST
MOVE P2,T1 ;SAVE START
PUSHJ P,WDFTCH ;GET IT
CSH.1: CAMN T1,P2 ;HIT THE END YET?
JRST CSH.2 ;YES
MOVE P3,T1 ;SAVE BLOCK ADDRESS
ADDI T1,.CBDAT ;OFFSET TO DATA BLOCK
PUSHJ P,WDFTCH ;GET IT
MOVE T2,T1 ;COPY ADDRESS
MOVEI T1,DSKBLK ;SIZE OF A BLOCK
TLNN T2,-1 ;NON-ZERO SECTION?
PUSHJ P,GIVWDS ;RETURN BLOCK
MOVEI T1,.CBLEN ;LENGTH OF BLOCK
MOVE T2,P3 ;BLOCK ADDRESS
MOVEI T1,.CBNHB(P3) ;LINK TO NEXT BLOCK
PUSHJ P,WDFTCH ;GET IT
JRST CSH.1 ;CHECK IT
CSH.2: MOVEI T1,.CBNAB(P1) ;POINTER TO ACTIVE LIST
PUSHJ P,WDFTCH ;GET IT
CSH.3: CAMN T1,P2 ;HIT THE END YET?
JRST CSH.4 ;YES
MOVE P3,T1 ;SAVE BLOCK ADDRESS
ADDI T1,.CBDAT ;OFFSET TO DATA BLOCK
PUSHJ P,WDFTCH ;GET IT
MOVE T2,T1 ;COPY ADDRESS
MOVEI T1,DSKBLK ;SIZE OF A BLOCK
TLNN T2,-1 ;NON-ZERO SECTION?
PUSHJ P,GIVWDS ;RETURN BLOCK
MOVEI T1,.CBLEN ;LENGTH OF BLOCK
MOVE T2,P3 ;BLOCK ADDRESS
PUSHJ P,GIVWDS ;RETURN IT
MOVEI T1,.CBNAB(P3) ;LINK TO NEXT BLOCK
PUSHJ P,WDFTCH ;GET IT
JRST CSH.3 ;CHECK IT
CSH.4: FORMAT <<Disk Cache Space is >,<OCT4 FRERTN>>
JRST CRPOPJ ;RETURN
;HERE TO ACCOUNT FOR EXTENSIBLE BITMAP MEMORY BLOCKS
RTNEBM: SETZM FRERTN ;START COUNTS FRESH
GTTAB %CNAHB ;GET FIRST ALLOCATION HEADER BLOCK
MOVE P1,T1 ;SAVE IT HERE
EBM.1: MOVE P2,MONITR+AHBAEB(P1) ;GET FIRST EXTENT BLOCK
EBM.2: HLRE T1,MONITR+AEBBMP(P2) ;GET LENGTH OF BITMAP
MOVMS T1 ;MAKE +VE
ADDI T1,AEBBMP+1 ;INCLUDE HEADER
MOVE T2,P2 ;ADDRESS OF EXTENT BLOCK
CAML T2,LOCORE ;DON'T RETURN ASSEMBLED-IN BLOCKS
CAML T2,LOWLIM ;...
SKIPA ;NO GOOD
PUSHJ P,GIVWDS ;RETURN THE SPACE
MOVE P2,MONITR+AEBNXT(P2) ;GET LINK TO NEXT BLOCK
JUMPN P2,EBM.2 ;JUMP FOR NEXT ONE
MOVE P1,MONITR+AHBNXT(P1) ;GET NEXT HEADER BLOCK
JUMPN P1,EBM.1 ;JUMP FOR NEXT ONE
FORMAT <<Extensible Bitmap Memory Space is >,<OCT4 FRERTN>>
JRST CRPOPJ ;RETURN
;HERE TO ACCOUNT FOR ANY MESSAGE BUFFERS USED FOR DECNET OVER DTE.
RTNDTE: SETZM FRERTN ;START COUNT FRESH
GTTAB %DNETH ;GET POINTER TO DTE TABLE
SKIPN P1,T1 ;COPY ADDRESS, SKIP IF THERE IS ONE
POPJ P, ;NONE
GTTAB %CNCPU ;NUMBER OF CPU'S
MOVNS T1 ;NEGATE
HRL P1,T1 ;BUILD AN AOBJN WORD
DTE.1: MOVE P2,MONITR(P1) ;GET ADDRESS OF A DTE BLOCK
HRLI P2,-4 ;MAXIMUM OF 4 DTE'S
DTE.2: MOVE P3,MONITR(P2) ;GET DTE CONTROL BLOCK ADDRESS
MOVEI T1,UBLSIZ+6 ;SIZE
SKIPE T2,MONITR+ETDOBK(P3) ;AN OUTPUT BUFFER?
PUSHJ P,GIVWDS ;YES, RETURN IT
MOVEI T1,UBLSIZ+6 ;SIZE
SKIPE T2,MONITR+ETDIBK(P3) ;AN INPUT BUFFER?
PUSHJ P,GIVWDS ;YES, RETURN IT
AOBJN P2,DTE.2 ;LOOP FOR DTE'S ON THIS CPU
AOBJN P1,DTE.1 ;LOOP FOR ALL DTE'S
FORMAT <<DTE Buffer Space is >,<OCT4 FRERTN>>
JRST CRPOPJ ;RETURN
SETZM FRERTN ;START COUNT FRESH
;HERE TO ACCOUNT FOR ANY FREE CORE USED BY DAEMON ERROR ENTRIES
;RIGHT NOW ONLY CODE 30 (KLEERR) AND INDIRECTLY CODE NN (SYSTEM
;ERROR BLOCKS).
RTNDAE: POPJ P, ;DONE
GTTAB %LDESZ ;GET LENGTH OF ERPTBK ENTRY
SKIPN T1 ;ANYTHING?
MOVEI T1,2 ;NO, USE OLD DEFAULT
MOVEM T1,ERPTSZ ;SAVE SIZE
GTTAB %LDERT ;ADDRESS OF ERPTBK
SKIPN T1 ;ANYTHING?
HALT . ;NO, HANDLE SOME DAY
MOVEM T1,ESVIDX ;SAVE
GTTAB %LDPT1 ;POINTER TO EXTRACT ENTRIES
PUSHJ P,WDFTCH ;FETCH THE WORD
SKIPN T1 ;IF INITIAL IS ZERO
MOVE T1,ERPTSZ ;OTHER ENTRY IS BLANK
MOVEI T3,(T1) ;COPY INITIAL OFFSET
GTTAB %LDLTH ;GET MAX TABLE LENGTH
MOVEM T1,ERPTMX ;SAVE IT TOO
GTTAB %CNFRE ;POINTER TO FREE CORE BIT MAP
;HERE TO REPORT STUFF LEFT OVER
LEFT: SKIPN FRUSED ;ANYTHING LEFT OVER?
JRST LEFT.4 ;NOPE
FORMAT <,<CRLF>,,<PER>,< Chunks (>,<OCT4 FRUSED>,< Words) unaccounted for:>,<CRLF>>
MOVE P1,FREPTR ;AOBJN FOR BIT MAP
ADDI P1,MONITR ;OFFSET FOR WHERE WE PUT THE MONITOR
HRLI P1,(POINT 1,0) ;LOOK AT A BIT AT A TIME
MOVE J,FREAVB ;MAX POSSIBLE( i.e. NUMBER OF BITS TO LOOK AT)
MOVE P2,LOCORE ;WHERE THEY ARE
SETZB P3,P4 ;CLEAR COUNTERS
LEFT.1: ILDB T1,P1 ;GET A BIT
JUMPN T1,[AOS P3 ;COUNT SPACE TAKEN
SKIPN P4 ;FIRST 1 BIT SEEN
MOVE P4,P2 ;YES, REMEMBER WHERE IT STARTS
JRST LEFT.2] ;AND GET ANOTHER BIT
JUMPE P4,LEFT.2 ;END OF A TAKEN SLOT
FORMAT << >,<OCT4 P3>,< Words @ >,<OCT P4>,,<CRLF>>
SETZB P3,P4 ;START LOOKING AGAIN
LEFT.2: ADDI P2,4 ;STEP TO NEXT ADDRESS
SOJG J,LEFT.1 ;GET ALL THE BITS
JUMPE P4,LEFT.3 ;ANY AT THE END
FORMAT << >,<OCT4 P3>,< Words @ >,<OCT P4>,,<CRLF>>
LEFT.3: POPJ P, ;RETURN
LEFT.4: OUTSTR [ASCIZ /
All free core accounted for!
/]
POPJ P, ;RETURN
SUBTTL The "HELP" Command
%HELP: OUTSTR [ASCIZ/Commands are:/]
MOVEI P2,CMDHLP ;FIRST HELP TEXT
SKIPA P1,[-NUMCMD,,CMDTBL] ;AOBJN FOR MAIN COMMAND TABLE
HLPCOM: OUTSTR [ASCIZ/Arguments are:/]
;COMMON PART OF HELP TEXT FOR OTHER COMMAND PROCESSORS
; P1 = AOBJN TO COMMAND TABLE
; P2 = ADDRESS OF PARALLEL HELP TEXT TABLE
HELP.1: OUTSTR [BYTE (7)15,12,11,0] ;CR,LF,TAB
MOVE T1,(P1) ;GET A COMMAND FROM THE TABLE
PUSHJ P,SIXOUT ;OUTPUT IT
OUTCHR [11] ;ALIGN WITH A TAB
OUTSTR @(P2) ;TEXT FOR IT
AOS P2 ;STEP TO NEXT HELP TEXT
AOBJN P1,HELP.1 ;AND TRY ANOTHER
JRST CRPOPJ ;END LINE AND RETURN
SUBTTL The "DDT" Command
%DDT: PUSHJ P,FLUSH ;NO ARGUMENTS
HRRZ T1,74 ;ADDRESS OF DDT
JUMPN T1,(T1) ;GO TO IT
OUTSTR [ASCIZ/?DDT not loaded/]
JRST CRPOPJ ;RETURN
SUBTTL Some Input Subroutines
;SUBROUTINE TO INPUT A SINGLE CHARACTER INTO CH
; PUSHJ P,GETONE
; RETURN HERE IF A SPECIAL CHARACTER
; RETURN HERE IF A NUMBER
; RETURN HERE IF A LETTER
;IF FL.RSC IS ON, THIS GETS THE LAST CHARACTER (TERMINATOR OF PREVIOUS)
GETONE: TLNE F,(FL.EOL) ;END OF LINE SEEN
JRST GETO.2 ;YES, RETURN LINE FEED
TLZE F,(FL.RSC) ;WANT OLD CHARACTER AGAIN
JRST [MOVE CH,SAVCHR ;YES, GET SAVED CHARACTER
JRST GETO.B] ;AND PROCESS IT
INCHWL CH ;NO, GET A CHARACTER
GETO.A: MOVEM CH,SAVCHR ;SAVE FOR RESCAN
GETO.B: JUMPE CH,GETONE ;IGNORE NULLS
CAIN CH,15 ;CARRIAGE RETURN ??
JRST GETONE ;YES, PITCH THOSE
CAIE CH,7 ;^G ??
CAIN CH,13 ;^K ??
JRST GETO.1 ;YES, MARK END OF TEXT AND RETURN LINE FEED
CAIN CH,14 ;^L ??
JRST GETO.1 ;YES, MARK END OF TEXT AND RETURN LINE FEED
CAIE CH,12 ;LINE FEED ??
CAIN CH,33 ;ALTMODE ??
JRST GETO.1 ;YES, MARK END OF TEXT AND RETURN LINE FEED
CAIN CH,32 ;^Z ??
JRST GETO.0 ;YES, LIGHT LOTS OF BITS FOR ^Z
CAIN CH,11 ;A TAB
SKIPA CH,[" "] ;YES, CONVERT TO SPACE
CAIN CH," " ;A SPACE
POPJ P, ;YES, TAKE "SPECIAL" RETURN
CAIE CH,"!" ;LOOK FOR COMMENTS
CAIN CH,";" ;...
JRST GETO.2 ;FAKE AN END OF LINE
CAIG CH,"9" ;LOOK FOR DIGITS
CAIGE CH,"0" ;...
SKIPA ;NOT A DIGIT
JRST CPOPJ1 ;TAKE "DIGIT" EXIT
CAIG CH,"Z"+40 ;LOWER CASE LETTER
CAIGE CH,"A"+40 ;...
SKIPA ;NOT LOWER CASE
SUBI CH," " ;CONVERT TO UPPER CASE
CAIG CH,"Z" ;NOW DO LETTER CHECK
CAIGE CH,"A" ;...
POPJ P, ;MUST BE A SPECIAL
CPOPJ2: AOS (P) ;TAKE "LETTER" EXIT
CPOPJ1: AOS (P) ;LOTS OF SKIP RETURNS
CPOPJ: POPJ P, ;RETURN
GETO.0: TLO F,(FL.UPZ) ;MARK ^Z FOR JMF
GETO.1: TLO F,(FL.ETX) ;MARK REAL END OF TEXT
GETO.2: TLO F,(FL.EOL) ;LIGHT FAKE END OF LINE
MOVEI CH,12 ;RETURN LINE FEED
POPJ P, ;TAKE "SPECIAL" RETURN
GETO.3: PUSHJ P,CRPOPJ ;END ECHOING WITH CR,LF
JRST GETO.1 ;AND MARK LINE AS COMPLETE
;SUBROUTINE TO SEARCH A TABLE FOR A COMMAND OR ARGUMENT
;CALL: T1 = ITEM IN SIXBIT
; T2 = MASK FOR CHARACTERS TYPED
; T3 = AOBJN POINTER FOR TABLE TO SEARCH
;RTNS: CPOPJ = NOT IN THE TABLE
; CPOPJ1 = AMBIGUOUS
; CPOPJ2 = FOUND IT
;RETURNS T1 INTACT, T2 = RELATIVE INDEX FOR COMMAND, CLOBBERS T3,T4,T5
TABSRC: MOVEI T4,(T3) ;SAVE TABLE START ADDRESS
PUSH P,T2 ;SAVE MASK TO USE
SETZ T2, ;CLEAR FOUND INDICATOR
TABS.1: MOVE T5,(T3) ;GET AN ITEM
CAMN T1,T5 ;EXACT MATCH
JRST [MOVEI T2,(T3) ;YES, MARK WHERE WE FOUND IT
JRST TABS.3] ;AND EXIT
ANDCM T5,(P) ;MASK TO AS MANY CHARS AS IN T1
CAME T1,T5 ;NOW DO WE HAVE A MATCH
JRST TABS.2 ;NO, TRY NEXT ENTRY IN TABLE
JUMPN T2,[POP P,(P) ;IF ALREADY HAVE 1 MATCH
JRST CPOPJ1] ;GIVE AMBIGUOUS RETURN
MOVEI T2,(T3) ;SAVE ADDRESS OF THIS MATCH
TABS.2: AOBJN T3,TABS.1 ;AND LOOK SOME MORE
TABS.3: POP P,(P) ;CLEAN STACK NOW
JUMPE T2,CPOPJ ;RETURN IF NEVER FOUND ONE
SUBI T2,(T4) ;COMPUTE RELATIVE OFFSET OF COMMAND
JRST CPOPJ2 ;AND GIVE LOTS OF SKIP RETURNS
;SUBROUTINE TO EAT UP THE REST OF THE INPUT LINE
FLUSH: TLZ F,(FL.EOL!FL.RSC) ;CLEAR SCANNER FLAGS
TLNE F,(FL.ETX) ;REACHED END OF LINE YET
POPJ P, ;YES, RETURN
PUSHJ P,GETONE ;GET A CHARACTER
JFCL ;IGNORE VARIOUS RETURNS
JFCL ;...
JRST FLUSH ;NOW LOOK FOR END OF LINE
;SUBROUTINE TO ENSURE THAT NO GARBAGE FOLLOWS LAST ARGUMENT OF A COMMAND
;CALLED BY VARIOUS COMMAND PROCESSORS AFTER READING LAST ARGUMENT BUT BEFORE
; EXECUTING THE COMMAND ITSELF.
;RTNS: CPOPJ JUNK AFTER COMMAND
; CPOPJ1 NOTHING BUT END OF LINE
CMDEND: TLO F,(FL.RSC) ;GET LAST ARGUMENT TERMINATOR
CMDE.1: PUSHJ P,GETONE ;GET A CHARACTER
JRST CMDE.2 ;SPECIAL, CHECK IT OUT
POPJ P, ;NUMBER, JUNK
POPJ P, ;SPECIAL, JUNK
CMDE.2: CAIN CH," " ;SPACE AFTER COMMAND
JRST CMDE.1 ;ALLOW SPACES BEFORE ANY COMMENTS
TLNE F,(FL.EOL) ;END OF LINE
AOS (P) ;YES, NO JUNK
POPJ P, ;RETURN
;SUBROUTINE TO GET A SIXBIT WORD FROM THE INPUT STREAM INTO "T1"
; ALSO RETURNS MASK FOR POSSIBLE COMMAND IN "T2"
;CLOBBERS T3
GETSIX: MOVE T3,[POINT 6,T1] ;PRIME THE BYTE POINTER
SETZ T1, ;AND THE RECEIVING WORD
SETO T2, ;AND THE EVENTUAL COMMAND MASK
TLO F,(FL.RSC) ;START WITH LAST TERMINATOR
GETS.1: PUSHJ P,GETONE ;GET A CHARACTER
JRST GETS.2 ;SPECIAL, GO LOOK
JRST [JUMPE T1,CPOPJ ;NUMBERS CANNOT BE THE FIRST IN A COMMAND
JRST .+1] ;BUT CAN BE PARTS OF IT (e.g. CPU0, RPE4)
SUBI CH,40 ;TO SIXBIT
TLNE T3,770000 ;GOT THEM ALL YET
IDPB CH,T3 ;NO, INSERT NEW CHARACTER
LSH T2,-6 ;ADJUST MASK FOR NEW CHARACTER
JRST GETS.1 ;AND GET ANOTHER
GETS.2: CAIN CH," " ;STOP ON A BLANK
JUMPE T1,GETS.1 ;YES, IGNORE LEADING BLANKS
POPJ P, ;RETURN WITH T1,T2 SET UP
;SUBROUTINE TO GET A NUMERIC ARGUMENT FROM THE INPUT STREAM INTO "T1"
;RTNS: T1 .LT. 0 IF NO DIGITS FOUND
;CLOBBERS T2,T3
GETNUM: SKIPA T2,[^D10] ;DEFAULT RADIX
GETNUO: MOVEI T2,^D8 ;HERE FOR OCTAL INPUT
SETO T1, ;NO DIGITS SEEN YET
TLO F,(FL.RSC) ;START WITH LAST TERMINATOR
GETN.1: PUSHJ P,GETONE ;GET A CHARACTER
JRST GETN.2 ;A SPECIAL, CHECK IT OUT
SKIPA ;A NUMBER, INCLUDE IT
JRST GETN.3 ;A LETTER, CHECK FOR K OR P
MOVEI T3,-"0"(CH) ;CONVERT TO ASCII
CAIL T3,(T2) ;RADIX CHECK
JRST GETN.4 ;ILLEGAL ( NO 8'S OR 9'S IN OCTAL )
SKIPGE T1 ;ANY DIGITS SO FAR
TDZA T1,T1 ;NO, THIS IS THE FIRST
IMULI T1,(T2) ;"SHIFT" PREVIOUS SUM
ADDI T1,(T3) ;AND INCLUDE THE NEW DIGIT
JRST GETN.1 ;GET MORE
GETN.2: CAIN CH,"#" ;INPUTTING OCTAL
JRST [JUMPGE T1,GETN.4 ;CAN'T CHANGE RADIX IN THE MIDDLE OF THE STREAM
CAIN T2,^D8 ;ALREADY DONE THIS ONCE
POPJ P, ;YES, CAN'T TYPE TWO OF THEM
MOVEI T2,^D8 ;NEW RADIX
JRST GETN.1] ;AND GET ANOTHER DIGIT
CAIN CH," " ;A BLANK
JUMPL T1,GETN.1 ;YES, IGNORE LEADING BLANKS ALWAYS
POPJ P, ;STOP ON A SPECIAL OR OTHER BLANKS
GETN.3: JUMPL T1,CPOPJ ;ERROR IF NO DIGITS YET
SETO T3, ;FLAG INVALID LETTER
CAIN CH,"K" ;ALLOW "K"
MOVEI T3,^D10 ;*1024 IF "K"
CAIN CH,"P" ;ALLOW "P"
MOVEI T3,^D9 ;*512 IF "P"
JUMPL T3,GETN.4 ;ILLEGAL IF NEITHER
LSH T1,(T3) ;ADJUST APPROPRIATELY
SETZM SAVCHR ;EAT UP THE "P" OR "K"
POPJ P, ;RETURN WITH NUMBER IN T1
GETN.4: SETO T1, ;ANYTHING ILLEGAL, RETURN -1
POPJ P, ;RETURN
;SUBROUTINE TO SET UP OPEN/LOOKUP BLOCKS WITH FILE NAME ENTERED
GETFN: SETZB T1,OPNBLK+1 ;CLEAR STRUCTURE
MOVSI T2,'EXE' ;EXTENSION DEFAULT
DMOVEM T1,LUKBLK ;CLEAR FILE NAME, SET EXTENSION
SETZ T2, ;ANOTHER 0
DMOVEM T1,LUKBLK+2 ;CLEAR REST OF SHORT LOOKUP BLOCK
GETF.1: PUSHJ P,GETSIX ;GET NEXT ARGUMENT
JUMPE T1,GETF.2 ;NO MORE, LOOK FOR ERRORS
CAIN CH,":" ;DEVICE TERMINATOR
JRST [SKIPE OPNBLK+1 ;ALREADY HAVE A DEVICE NAME
JRST BADFMT ;YES, SAY ILLEGAL CONSTRUCTION
MOVEM T1,OPNBLK+1 ;STORE IT
SETZM SAVCHR ;EAT UP THE COLON
JRST GETF.1] ;AND GET NEXT FIELD
MOVEM T1,LUKBLK ;STORE FILE NAME (MUST BE ONE)
TLNE F,(FL.EOL) ;END OF LINE SEEN
JRST GETF.2 ;YES, CHECK RESULTS
CAIE CH,"[" ;ONLY PPN SPEC CAN BE LEFT
JRST CPOPJ1 ;RETURN NOW, GIVE RIGHT ERROR MESSAGE
SETZM SAVCHR ;EAT THE "["
PUSHJ P,GETNUO ;GET OCTAL PROJECT NUMBER
TLNN T1,-1 ;SMALL NUMBERS ONLY
CAIE CH,"," ;BETTER BE
JRST BADFMT ;ILLEGAL
HRRE T1,T1 ;EXTEND SIGN
JUMPLE T1,BADFMT ;THIS IS BAD TOO
HRLM T1,LUKBLK+3 ;STORE IT
SETZM SAVCHR ;EAT THE COMMA
PUSHJ P,GETNUO ;GET THE PROJECT NUMBER
TLNE T1,-1 ;SMALL HERE TOO
JRST BADFMT ;NO GOOD
JUMPLE T1,BADFMT ;THIS IS REAL BAD
HRRM T1,LUKBLK+3 ;STORE THAT
CAIN CH,"]" ;ALLOW CLOSURE
SETZM SAVCHR ;BUT DON'T REQUIRE IT
GETF.2: MOVSI T1,'DSK' ;DEFAULT DEVICE
SKIPN OPNBLK+1 ;UNLESS STR GIVEN
MOVEM T1,OPNBLK+1 ;ISN'T, FILL IT IN
SKIPN LUKBLK ;GOTTA HAVE A FILE NAME
JRST NOARGS ;COMPLAIN
JRST CPOPJ1 ;RETURN
SUBTTL Some Output Subroutines
;SUBROUTINE TO OUTPUT SIXBIT VALUE IN AC "T1"
SIXOUA: SKIPA T2,@UA ;LUUO, GET SIXBIT VALUE
SIXOUT: MOVE T2,T1 ;COPY SIXBIT OVER
SIXOU1: JUMPE T2,CPOPJ ;ALL DONE AT END OF SIXBIT WORD
SETZ T1, ;CLEAR RECEIVING AC
LSHC T1,6 ;BRING IN A CHARACTER
MOVEI T1," "(T1) ;TO ASCII
OUTCHR T1 ;OUTPUT IT
JRST SIXOU1 ;AND GET THEM ALL
;SUBROUTINE TO OUTPUT "T1" IN CORRECT RADIX
DECOU2: CAIGE T1,^D10 ;2 DIGIT MINIMUM
OUTCHR ["0"] ;OUTPUT LEADING ZERO
JRST DECOUT ;NOW OUTPUT DECIMAL NUMBER
DECOUA: SKIPA T1,@UA ;LUUO, GET NUMBER
OCTOUA: SKIPA T1,@UA ;LUUO, GET NUMBER
DECOUT: SKIPA T3,[^D10] ;GET RADIX
OCTOUT: MOVEI T3,10 ;GET RADIX
JUMPL T1,[OUTCHR ["-"] ;NEGATIVE VALUE
MOVMS T1 ;OUTPUT "-" AND POSITIVE NUMBER
JRST OCTOU1] ;RESUME INLINE
OCTOU1: IDIVI T1,(T3) ;STRIP DIGIT
PUSH P,T2 ;SAVE IT
SKIPE T1 ;WAS THAT ALL
PUSHJ P,OCTOU1 ;NO, GET ANOTHER
POP P,T1 ;RESTORE CHARACTER
MOVEI T1,"0"(T1) ;TO ASCII
OUTCHR T1 ;OUTPUT IT
POPJ P, ;AND RETURN
;SUBROUTINE TO OUTPUT "T1" AS ASCII WORD
ASCOUT: SETZ T2, ;MAKE SURE THERE'S A NULL AT THE END
OUTSTR T1 ;OUTPUT T1 AND MAYBE T2
POPJ P, ;RETURN
;SUBROUTINE TO OUTPUT FREE CORE NUMBERS AC A PERCENTAGE
PERCNT: SKIPGE T1,FRUSED ;GET AMOUNT TAKEN
OUTCHR ["-"] ;NEGATIVE, OUTPUT MINUS
MOVMS T1 ;MAKE POSITIVE NUMBER
IMULI T1,^D10000 ;SCALE
IDIV T1,FREAVB ;COMPUTE PERCENTAGE
IDIVI T1,^D100 ;UN-SCALE
IDIVI T2,^D10 ;AND 2 HUNDREDTHS DIGITS
FORMAT <,<DEC T1>,<.>,<DEC T2>,,<DEC T3>,<%>>
POPJ P, ;AND RETURN
SUBTTL Some Random (or stolen) Subroutines
;SUBROUTINE TO RETURN "FREE" CORE
;ENTER GIVWDS: T1=# WDS. TO RETURN, T2=START ADR. OF CORE
GIVWDS: ADDI T1,3 ;CONVERT TO # 4WD. BLOCKS
ASH T1,-2
SUB T2,LOCORE ;GET ADR. RELATIVE TO START OF TABLE
MOVN T3,T1
ADDM T3,FRUSED ;DECREMENT FREE-CORE USED
ADDM T1,FRERTN ;INCREMENT AMOUNT RETURNED
LSH T2,-2 ;/4 TO CONVERT TO BITS
IDIVI T2,^D36 ;COMPUTE WORD LOC, STARTING BIT
HRLS T2 ;WORD POSITION IN BOTH HALVES
ADD T2,FREPTR ;SET AOBJN WORD FOR TABLE
;FALL INTO SETZRS
;SUBROUTINE TO SET ZEROS IN A TABLE
;ARG T1=HOW MANY BITS TO CLEAR
; T2=AOBJN POINTER FOR TABLE
; T3=POSITION IN WORD OF FIRST BIT TO CLEAR
; (0=BIT 0, 1=BIT 1, ETC.)
SETZRS: EXCH T1,T3 ;SET ACS FOR CLRBTS
MOVEI T4,^D36 ;ADJUST FOR 1ST WORD
SUBM T4,T1
HRRZ T4,T2 ;SET T4 FOR CLRBTS
PUSH P,T2 ;SAVE AOBJN WORD
PUSHJ P,CLRBTS ;CLEAR SOME BITS
HALT . ;STOPCD BAC HERE
POP P,T2 ;RESTORE AOBJN WORD
HLRE T3,T2 ;LENGTH OF POINTER
SUB T2,T3 ;COMPUTE TOP OF TABLE
CAILE T4,(T2) ;FINAL ADR PAST TOP?
HALT . ;STOPCD PTT HERE
POPJ P, ;NO, GOOD RETURN
;SUBROUTINE TO SET UP A BIT MASK FOR IORM OR ANDCAM INTO A TABLE
;ENTER WITH T1=POSITION (36=BIT0, 1=BIT35) AND T3=HOW MANY
;AFTER THE FIRST CALL USE BITMS2, T3=COUNT RETURNS T1=MASK,
;T3=REMAINING COUNT ROUTINE HAS RETURNED FINAL MASK IF
;T3 .LE. 0 ASSUMES T4=ADR IN TABLE, BITMS2 INCREMENTS T4
BITMSK: PUSH P,T1 ;SAVE POSITION
MOVN T1,T3 ;- COUNT
CAILE T3,^D36 ;MORE THAN 1 WORD?
MOVNI T1,^D36 ;YES, SETTLE FOR A WORD (OR LESS)
MOVSI T2,400000 ;SET TO PROPOGATE A MASK
ASH T2,1(T1) ;GET THE RIGHT NUMBER OF BITS
SETZ T1,
LSHC T1,@0(P) ;POSITION THE BITS IN T1 (=MASK)
SUB T3,0(P) ;REDUCE THE COUNT TO THE NEW VALUE
POP P,T2 ;RESTORE T2
POPJ P, ;RETURN
;HERE AFTER FIRST CALL, MASK STARTS AT BIT 0
BITMS2: SETO T1, ;MASK STARTS AT BIT 0
MOVNI T2,-^D36(T3) ;SET UP SHIFT
CAIGE T3,^D36 ;DONT SHIFT IS .GE. 36
LSH T1,(T2) ;POSTION THE MASK
SUBI T3,^D36 ;REDUCE THE COUNT
AOJA T4,CPOPJ ;UPDATE THE POSITION AND RETURN
;ROUTINE TO CLEAR BITS FROM A TABLE
;ENTER T1=POSITION, T3=COUNT, T4=TABLE ADR (POSITION=36 IF BIT0, 1 IF BIT35)
;RETURNS POPJ IF BIT ALREADY 0, POPJ1 OTHERWISE
CLRBTS: PUSHJ P,BITMSK ;GENERATE A MASK
CLRBT1: MOVE T2,MONITR(T4) ;WORD TO CLEAR BITS FROM
TDC T2,T1 ;ARE THE BITS ALREADY OFF?
TDNE T2,T1
POPJ P, ;YES, RETURN NON-SKIP
MOVEM T2,MONITR(T4) ;NO, NOW THEY ARE
JUMPLE T3,CPOPJ1 ;DONE IF COUNT .LE. 0
PUSHJ P,BITMS2 ;GENERATE MASK FOR NEXT WORD
JRST CLRBT1 ;AND GO CLEAR THOSE BITS
;SUBROUTINE TO PERFORM GETTAB VIA SPY IF POSSIBLE
;ARGS T1=GETTAB ARG
;VALUES T1=GETTAB VALUE
GTBSPY: SKIPGE T1 ;WANT JOB NUMBER (- INDEX)
HRLI T1,(J) ;YES, INSERT IT
SKIPN NUMTAB ;HAVE GETTAB STUFF YET
JRST [GETTAB T1, ;NO, GET IT FROM CURENT MONITOR
POPJ P, ;IT FAILED
JRST CPOPJ1] ;GIVE GOOD RETURN
PUSH P,P1 ;SAVE P REGS
PUSH P,P2 ;...
PUSH P,P3 ;...
HRRZI P1,(T1) ;P1=TABLE NUMBER
ADD P1,NUMTAB ;ADDR OF PTR FOR THIS TABLE
LDB P3,[POINT 3,MONITR(P1),11] ;GET TYPE OF TABLE
CAIN P3,.SLIXP ;IS DATUM IN THE PDB?
JRST GTBPDB ;YES, GO GET IT
CAIN P3,.SLIXS ;INDEXED BY JOB OR SEGMENT NUMBER?
SKIPA P2,JBTMXL ;YES, MAX IS JOBN+SEGN-1
LDB P2,[POINT 9,MONITR(P1),8] ;NO. GET MAX ITEM VALUE
CAIE P3,.SLIXR ;IS THIS A RANGED GETTAB?
JRST GTBSP1 ;NO, P2 CONTAINS 0,,MAX
SKIPN P3,RNGTAB ;DO WE HAVE THE ADDRESS OF RNGTAB?
JRST GTBSP3 ;NO, FAIL
ADDI P2,(P3) ;ADD OFFSET INTO RNGTAB FOR THIS ENTRY
MOVE P2,MONITR(P2) ;GET MIN,,MAX FROM RNGTAB ENTRY
GTBSP1: HLRZ P3,T1 ;GET ITEM NUMBER CALLER WANTS
CAILE P3,(P2) ;.LE. MAX?
JRST GTBSP3 ;NO, FAIL
MOVSS P2 ;EXCHANGE MIN AND MAX
CAIGE P3,(P2) ;AND .GE. MIN?
JRST GTBSP3 ;NO, FAIL
HRRZ T1,MONITR(P1) ;GET BASE OF TABLE WANTED
ADD T1,P3 ;PLUS INDEX WANTED
CAMGE T1,LOWLIM ;IN HIGH SEG?
SKIPA T1,MONITR(T1) ;GET DATA ITEM
PUSHJ P,WDFTCH ;YES, GET IT
GTBSP2: AOS -3(P) ;GIVE GOOD RETURN
GTBSP3: POP P,P3 ;RESTORE P REGS
POP P,P2 ;...
POP P,P1 ;...
POPJ P, ;RETURN
GTBPDB: SKIPN PDBPTR ;IS JBTPDB BASE AVAILABLE?
JRST GTBSP3 ;NO, FAIL
HLRZS T1 ;JOB NUMBER
ADD T1,PDBPTR ;PLUS JBTPDB ADDRESS
HRRZ T1,MONITR(T1) ;GET ADDRESS OF WD 0 OF JOBS PDB
JUMPE T1,GTBSP2 ;NO JOB THERE, RETURN 0
ADD T1,MONITR(P1) ;ADD ON ITEM NUMBER
MOVE T1,MONITR(T1) ;GET THE WORD FROM THE PDB
JRST GTBSP2 ;GIVE GOOD RETURN
;SUBROUTINE TO RETURN THE CONTENTS OF PAGTAB FOR A SPECIFIC PAGE
;ARGS P1 = PAGE NUMBER
;RETURN T1 = BITS FROM PAGTAB
PGFTCH: CAML P1,PGTLEN ;RANGE CHECK IT
JRST [MOVSI T1,PT.NXM ;OUT OF RANGE, SAY NXM
POPJ P,] ;AND RETURN
MOVE T1,P1 ;COPY PAGE NUMBER
ADD T1,PTBADR ;ADD ADDRESS OF PAGTAB
; JRST WDFTCH ;FALL INTO WORD FETCH ROUTINE
;SUBROUTINE TO FETCH A SPECIFIC WORD FROM THE MONITOR HIGH SEGMENT
;ARGS T1 = ADDRESS (1B0 ON IF WANT PHYSICAL 22 BIT ADDRESS)
;RETURN T1 = THE CONTENTS
WDFTCH: SKIPN EXEDIR ;RUNNING FROM AN EXE FILE
JRST [MOVE T2,[PEEK T1,] ;NO, GET IT FROM RUNNING MONITOR
TLZE T1,(1B0) ;WANT PHYSICAL ADDRESS
TRO T2,UU.PHY ;YES, DO PHYSICAL ONLY PEEK
XCT T2 ;GET THE WORD
POPJ P,] ;AND RETURN
TLZE T1,(1B0) ;WANT PHYSICAL WORD
JRST [IDIVI T1,1000 ;SPLIT INTO PAGE AND OFFSET INTO PAGE
JRST WDFPHY] ;AND BYPASS EPT RELOCATION
CAMGE T1,LOWLIM ;IN LOW MONITOR LOW SEGMENT?
JRST [MOVE T1,MONITR(T1) ;YES, ALREADY HAVE THAT SOMEWHERE
POPJ P,] ;RETURN
IDIVI T1,1000 ;SPLIT INTO PAGE AND OFFSET INTO PAGE
LDB T3,[POINT 9,T1,26] ;GET SECTION NUMBER
ANDI T1,777 ;KEEP JUST IN-SECTION PAGE
CAILE T3,1 ;SECTION 0 AND 1 ARE EASY
JRST [ADD T3,EPTADR ;FOR OTHERS, MUST LOOK IN SECTAB
HRRZ T3,MONITR+540(T3) ;GET SECTAB ENTRY
LSH T3,9 ;CONVERT TO ADDRESS OF SECTION MAP
ADD T1,T3 ;OFFSET IN SECTION MAP FOR OUR ADDRESS
TLO T1,(1B0) ;PHYSICAL REFERENCE
PUSH P,T2 ;SAVE OFFSET
PUSHJ P,WDFTCH ;RECURSE
TLZ T1,-1 ;CLEAR MAP BITS
POP P,T2 ;RESTORE OFFSET
JRST WDFPHY] ;CONTINUE
ADD T1,EPMADR ;RELOCATE INTO THE EXEC MAP
LDB T1,[POINT 13,MONITR(T1),35] ;GET PAGE NUMBER
WDFPHY: HRRZ T3,EXEDIR ;NUMBER OF WORDS IN EXE DIRECTORY
MOVNI T3,-1(T3) ;DON'T COUNT HEADER WORD
HRLZS T3 ;FORM AOBJN
WDFT.1: HRRZ T4,EXEDIR+2(T3) ;GET CORE ADDRESS FROM DESCRIPTOR
CAILE T4,(T1) ;PAST THE ONE WE WANT
HALT . ;WORD NOT IN FILE
LDB T5,[POINT 9,EXEDIR+2(T3),8] ;GET REPEATER
ADDI T5,1(T4) ;FIRST PAGE NOT IN POINTER
CAIL T1,(T5) ;PAGE IN THIS POINTER AT ALL
JRST [ADD T3,[1,,1] ;ADJUST FOR DOUBLE WORD ENTRIES
AOBJN T3,WDFT.1 ;GET ANOTHER POINTER
HALT .] ;WORD NOT IN FILE
SUBI T1,(T4) ;HOW FAR INTO POINTER
ADD T1,EXEDIR+1(T3) ;HOW FAR INTO THE FILE PROPER
TLZ T1,-1 ;KEEP IT REASONABLE (FLAG BITS)
LSH T1,^D9 ;CONVERT TO A PAGE NUMBER IN THE FILE
ADDI T1,(T2) ;INCLUDE WORD OFFSET NOW
IDIVI T1,DSKBLK ;NOW CONVERT TO BLOCK NUMBER AND OFFSET INTO BLOCK
MOVSI T3,-NBCSHE ;SEARCH FOR BLOCK IN IN-CORE CACHE
HLRZ T4,DCACHE(T3) ;BLOCK DESCRIBED IN CACHE
CAIE T4,(T1) ;IS THIS IT
AOBJN T3,.-2 ;NO, KEEP LOOKING
JUMPL T3,WDFT.2 ;FOUND ONE, UPDATE LEAST RECENTLY USED TABLES
HRLM T1,DCACHE+NBCSHE-1 ;STORE BLOCK NUMBER IN LAST (OLDEST)
HRRZ T3,DCACHE+NBCSHE-1 ;WHERE DATA IS TO BE READ
SOS T3 ;-1 FOR THE IOWD
HRLI T3,-DSKBLK ;NUMBER OF WORDS
SETZ T4, ;LAST IOWD
USETI XPN,1(T1) ;POSITION FILE
IN XPN,T3 ;READ BLOCK INTO CACHE
CAIA ;READ OK
HALT . ;DISK I/O READ ERROR
MOVEI T3,NBCSHE-1 ;INDEX WHERE FOUND (READ)
WDFT.2: HRRZS T3 ;ISOLATE INDEX
CAIG T3,NBCSHE/3 ;DON'T RIPPLE IF ALREADY CLOSE TO START OF TABLE
JRST WDFT.3 ;THIS MIGHT NOT BE TOO GOOD WITH A SMALL "NBCSHE"
PUSH P,DCACHE(T3) ;SAVE ENTRY FOUND
MOVE T4,DCACHE-1(T3) ;COMPRESS TABLE SO LEAST USED IS LAST
MOVEM T4,DCACHE(T3) ;MOVE UP ENTRIES BELOW ONE FOUND
SOJG T3,.-2 ;SO NEW ONE CAN BE FOUND QUICKLY
POP P,DCACHE(T3) ;PUT NEW ONE AT THE FRONT
WDFT.3: HRRZ T1,DCACHE(T3) ;GET ADDRESS OF DATA IN THIS BUFFER
ADD T1,T2 ;PLUS OFFSET INTO BUFFER
MOVE T1,(T1) ;FETCH IT
POPJ P, ;AND RETURN
SUBTTL Local UUO Handler
UUOCON: LDB UU,[POINT 9,40,8] ;GET OPCODE
HRRZ UA,40 ;GET EFFECTIVE ADDRESS
CAILE UU,UUOMAX ;RANGE CHECK
HALT . ;WHAT
SKIPGE UU,UUODSP-1(UU) ;FAST UUO (DOESN'T CLOBBER REGS)
JRST (UU) ;YES, GO RIGHT TO IT
PUSH P,T1 ;SAVE ALL THE TEMP REGS
PUSH P,T2 ;...
PUSH P,T3 ;...
PUSH P,T4 ;...
PUSH P,T5 ;...
PUSHJ P,(UU) ;CALL ROUTINE
POP P,T5 ;NOW UNDO ALL THAT
POP P,T4 ;...
POP P,T3 ;...
POP P,T2 ;...
POP P,T1 ;...
POPJ P, ;AND RETURN
UUODSP: EXP DECOUA ;001 - OUTPUT DECIMAL NUMBER
EXP OCTOUA ;002 - OUTPUT OCTAL NUMBER
EXP SIXOUA ;003 - OUTPUT SIXBIT VALUE
EXP PERCNT ;004 - FREE CORE STATS
SETZ CRPOPJ ;005 - OUTPUT A CRLF
EXP [MOVE T1,@UA ;006 - OUTPUT OCTAL NUMBER * 4
LSH T1,2
JRST OCTOUT]
EXP [JSP T2,GTTOUT ;007 - OUTPUT GETTAB VALUE AS OCTAL
EXP OCTOUT]
EXP [JSP T2,GTTOUT ;010 - OUTPUT GETTAB VALUE AS DECIMAL
EXP DECOUT]
EXP [JSP T2,GTTOUT ;011 - OUTPUT GETTAB VALUE AS ASCII WORD
EXP ASCOUT]
EXP [JSP T2,GTTOUT ;012 - OUTPUT GETTAB VALUE, DECIMAL, 2 DIGITS
EXP DECOU2]
UUOMAX==<.-UUODSP> ;HIGHEST LUUO
GTTOUT: MOVE T1,@UA ;GET GETTAB ARGUMENT
PUSHJ P,GTBSPY ;GET VALUE
HALT . ;WHAT
JRST @0(T2) ;TO CORRECT OUTPUT ROUTINE
MONTAB: ASCII /Jan/
ASCII /Feb/
ASCII /Mar/
ASCII /Apr/
ASCII /May/
ASCII /Jun/
ASCII /Jul/
ASCII /Aug/
ASCII /Sep/
ASCII /Oct/
ASCII /Nov/
ASCII /Dec/
XLIST ;FORCED OUT LITERAL POOL HERE
LIT
LIST
.ENDPS ;END OF THE CODE PSECT
END FRECOR ;END OF THIS PROGRAM