Trailing-Edge
-
PDP-10 Archives
-
BB-F493Z-DD_1986
-
10,7/cnforn.mac
There are 3 other files named cnforn.mac in the archive. Click here to see a list.
TITLE CNFORN - CONFIG module for ORION
SUBTTL Nick Tamburri 10-OCT-85
;
;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1975,1976,1977,1978,1979,1980,1981,1982,1983,1984,1986.
;ALL RIGHTS RESERVED.
;
;
; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED
; AND COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE
; AND WITH THE INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS
; SOFTWARE OR ANY OTHER COPIES THEREOF MAY NOT BE PROVIDED OR
; OTHERWISE MADE AVAILABLE TO ANY OTHER PERSON. NO TITLE TO
; AND OWNERSHIP OF THE SOFTWARE IS HEREBY TRANSFERRED.
;
; THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE
; WITHOUT NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT
; BY DIGITAL EQUIPMENT CORPORATION.
;
; DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY
; OF ITS SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY
; DIGITAL.
SALL
SEARCH GLXMAC
SEARCH ORNMAC
PROLOG(CNFORN)
.TEXT "/LOCALS"
EXTERN WTORTN
CNFEDT==17 ;EDIT LEVEL
.DIRECTIVE FLBLST
SUBTTL Table of Contents
SUBTTL Revision History
COMMENT \
1 Create this module.
9-Sep-84 GCO 10094/NT
2 Don't type "Structures must be removed" if adding a controller.
28-Nov-84 GCO 10125/NT
3 Add ADD/REMOVE commands for CI and NI.
29-Jan-85 GCO 10141/JAD
4 Add KLINIK line routines.
6-Feb-85 GCO 10146/DPM/TL
5 Rework most of CONFIG to provide ACKing and clean it up.
12-Mar-85 GCO 10163 /JAD
6 Make add/remove CPU and remove NI work. Make SYSPHY errors report
device name in sixbit, not octal. Include new error codes in RECON
UUO error reporting.
29-Mar-85 GCO 10182 /DPM
7 New DIAG. functions to add/remove CI/NI.
22-Apr-85 GCO 10194 /JAD
10 Add SET [NO] MICROCODE (loading) and LOAD (microcode) commands.
Remove SET [NO] DX20 command.
26-Apr-85 GCO 10199 /DPM
11 Expand list of DIAG. UUO error codes.
12 Fix loop in LSTDEV routine. Fix bad CPU argument to GETTAB UUO
when removing a CPU. Fix undeserved error messages when adding
or removing ALL-CI or ALL-NI ports on non-existant or down CPUs.
20-May-85 GCO 10210 /DPM
13 Add SET DUMP/RELOAD commands to diddle bits in DEBUGF. Add SHOW
STOPCODE-FLAGS command.
30-Jul-85 GCO 10264 /JAD
14 Do copyright statements. 12-SEP-85 /LEO
15 Don't process SUSPEND command if operator does not specify a
reason text.
18-Sep-85 /NT
16 Add/remove CPU loops if complex disk configuration.
21-Oct-85 GCO 10306 /JMF
17 Fix numerous errors when using a DSKCHR block that's too short
28-Jan-86 GCO 10371 /DPM
\
SUBTTL Macros and other stuff
F==.A13 ;Dedicated flag AC
FL.ADD==1B0 ;Various bit flags
FL.CHK==1B1
FL.ALT==1B2
FL.DMN==1B3
FL.HEA==1B4
FL.NCD==1B5
FL.WAC==1B6
FL.UN1==1B7
FL.NO==1B8
;CPU STATUS FLAGS
CS.DWN==1B0 ;DOWN
CS.NEX==1B1 ;NON-EXISTANT
CS.DET==1B2 ;DETACHED
CS.NOK==1B3 ;OK WORD NOT COUNTING UP
CS.BOT==1B4 ;THIS IS THE BOOT CPU
DEFINE GTTAB(AC,ENTRY,DEFAULT),<
MOVE AC,[ENTRY]
XLIST
GETTAB AC,
IFB <DEFAULT>,<HALT .>
IFNB <DEFAULT>,<MOVE AC,[DEFAULT]>
LIST
SALL
>
DEFINE MSYM(NAME,VALUE),<NAME==VALUE>
;STORAGE
;*** KEEP THE NEXT TWO SYMBOLS CONTIGUOUS
RCNARG: BLOCK 1 ;RECON. .RCBTX FUNCTION WORD COUNT
RSNTXT: BLOCK <<.TXTSZ==16>/5>+1 ;BUFFER FOR SNAPSHOT/SHUTDOWN REASON
RSNEND==.-1
RSNADR: BLOCK 1 ;Address of reason text
CTYBLK: BLOCK 3 ;Arg block for CTY typeout TRMOP.
DCHARG: BLOCK .DCMAX ;DSKCHR UUO BLOCK
INIDON: BLOCK 1 ;Initialization done flag
ULDTXT: BLOCK 10 ;DEVICE STORAGE FOR MICROCODE ACKS AND ERRORS
PHYNAM: BLOCK 1 ;SIXBIT UNIT NAME (USED BY NXTKON)
PHYUNI: BLOCK 1 ;SIXBIT UNIT NAME (USED BY NXTUNI)
SYSSIZ: BLOCK 1 ;SIZE OF THE MONITOR
NWCORE: BLOCK 1 ;NUMBER OF WORDS OF MEMORY ON THE SYSTEM
MONVER: BLOCK 1 ;MONITOR VERSION (%CNVER)
CPUN: BLOCK 1 ;NUMBER OF RUNNING CPU'S IN SYSTEM
CPUOK: BLOCK 1 ;NUMBER OF CPUS WITH OK WORDS RUNNING
CPURUN: BLOCK 1 ;MASK WHICH ARE RUNNING
CPUSTS: BLOCK 6 ;ONE PER CPU (EVEN IF NOT THERE)
;LH = CPU STATUS FLAGS (CS.XXX)
;RH = CDB ADDRESS
CHRCNT: BLOCK 1 ;COUNT OF CHARACTERS IN ACK MESSAGE
ADDREM: BLOCK 1 ;ADDRESS OF "ADD" OR "REMOVE" TEXT
TXTPTR: BLOCK 1 ;BYTE POINTER TO DEPOSIT MESSAGE CHARACTERS
;GET-DATA-FROM-MONITOR STUFF
SAVEP1: BLOCK 2
SAVEP3: BLOCK 2
INST: 0
DATA: 0
CNPNTR: 0,,DATA
; SET KLINIK
Z.KLIB:! ;Start of data to zero
KLICPU: BLOCK 1 ;CPU number or 7 for ALL
KLIDTD: BLOCK <26+3>/4 ;Data for DTE. UUO
Z.KLIE:! ;End of data to zero
SUBTTL Dispatch Table -- Main commands
CNFDSP: $STAB
.CFADD##,,C$ADD ;Add command
.CFAUT##,,C$AUTO ;Autoconfigure
.CFREM##,,C$REMV ;Remove
.CFLOD##,,C$LOAD ;Load microcode
.CFSET##,,C$SET ;Set
.CFSHO##,,C$SHOW ;Show
.CFSHT##,,C$SHUT ;Shutdown
.CFSNP##,,C$SNAP ;Snapshot
.CFSUS##,,C$SUSP ;Suspend
$ETAB
SUBTTL Dispatch Tables -- ADD/REMOVE commands
ADDDSP: $STAB
.ARMEM##,,ADDMEM ;Memory
$ETAB
ADDCPX: $STAB
.ARCPU##,,ADDCPU ;CPU
.ARCI##,,ADDCI ;CI
.ARNI##,,ADDNI ;NI
$ETAB
SUBTTL Dispatch Tables -- SET commands
SETDSP: $STAB
.STBOT##,,SETBOT ;Boot text
.STULD##,,SETULD ;Set [no] microcode loading
.STNOT##,,SETNOT ;Negator
.STAUT##,,SETAUT ;Auto-reload
.STKLI##,,KLINIK ;Set KLINIK
.STDMP##,,SETDMP ;Set DUMP (on)
.STRLD##,,SETRLD ;Set RELOAD (on)
$ETAB
SUBTTL Dispatch Tables -- SET NO commands
STNDSP: $STAB
.STBOT##,,SETBOT ;Boot text
.STULD##,,SETULD ;Set [no] microcode loading
.STAUT##,,SETAUT ;Auto-reload
.STDMP##,,SETDMP ;Set DUMP (on)
.STRLD##,,SETRLD ;Set RELOAD (on)
$ETAB
SHODSP: $STAB
.SHKLI##,,KLISHW ;SHOW KLINIK
.SHSTP##,,SHWSTP ;SHOW STOPCODE-FLAGS
$ETAB
SUBTTL CPUNAM - SIXBIT CPU names
DEFINE CPUNMS(NUMBER)<IRP <NUMBER>,<SIXBIT |CPU'NUMBER|>>
CPUNAM::CPUNMS<0,1,2,3,4,5>
SUBTTL CNFORN - Main dispatch routine.
; Here from ORION's application dispatch, to dispatch to the
; various CONFIG command routines.
; INTERN CNFORN ;MAKE AVAILABLE TO ORION
CNFORN::SKIPE INIDON ;Have we initialized ourselves
JRST CNF.1 ;Yes, don't do it again
GTTAB S1,%CNNWC ;Get the number of words of memory
MOVEM S1,NWCORE ;Save it
GTTAB S1,%CNSIZ ;Get maximum core size
MOVEM S1,SYSSIZ ;Store it
GTTAB S1,%CNVER ;Get the monitor version
MOVEM S1,MONVER ;Save it for later
SETOM INIDON ;Remember we've come through here
CNF.1: MOVE S2,COM.PB(MI) ;Was parser block filled in
ADDI S2,(MI) ;POINT PB AT THE BLOCK
MOVE S1,S2 ;GET THE BLOCK POINTER
$CALL P$SETU## ;SETUP THE POINTER
$CALL P$KEYW## ;GET THE FIRST KEYWORD
$RETIF ;ERROR
MOVEI S2,CNFDSP ;Get the address of the table
$CALL TABSRC## ;Search the command table for dispatch
$RETIF ;Illegal command?
$CALL .SAVET ;Give workers room
SETZB F,TXTPTR ;Clear all flags, and message address
PJRST (S2) ;Go process the command
SUBTTL Command processors -- ADD/REMOVE commands
C$REMV: TLZA F,(FL.ADD) ;Clear the adding flag
C$ADD: TLO F,(FL.ADD) ;Set flag to add
MOVEI S1,[ASCIZ |ADD|] ;Assume ADD command
TLNN F,(FL.ADD) ;Good guess?
MOVEI S1,[ASCIZ |REMOVE|] ;No
MOVEM S1,ADDREM ;Save for $IACK
$CALL P$KEYW## ;Get the object of the verb
$RETIF
HRLZ S2,S1 ;Copy keyword index
MOVEM S2,DCHARG+.DCNAM ;Store in DSKCHR argument block
MOVE T1,[.DCMAX,,DCHARG] ;Point at argument block
DSKCHR T1, ;Is it a DSK controller?
CAIA ;No
PJRST ADDKON ;Yes, go do that
DEVNAM S2, ;Perhaps a device?
SKIPA S2,[ADDDSP] ;Point to the dispatch table
PJRST RADMTK ;Go add/remove a kontroller
$CALL TABSRC## ;Search the table
JUMPT (S2) ;Dispatch if found a match
MOVEI S2,ADDCPX ;Point to per-CPU table
PUSHJ P,CPUSRC ;Search the table
JUMPT (S2) ;Dispatch if found a match
$RETF ;Else error
SUBTTL ADD/REMOVE MEMORY
ADDMEM: $IACK (^T/@ADDREM/ MEMORY)
$CALL GETADR ;Get the beginning address
$RETIF
MOVE T2,S1 ;Save it
$CALL GETADR ;Get the end address
$RETIF
MOVE T3,S1 ;Save it
MOVEI T1,3 ;Get the lenght of the arg block
MOVE S1,[XWD .RCMON,T1] ;Assume adding
TLNN F,(FL.ADD) ;Are we adding?
MOVE S1,[XWD .RCMOF,T1] ; Not, so we're removing
RECON. S1, ;Tell the monitor what we want
JRST RCNERR ;Go type the code and reason
MOVEI S1,[ASCIZ |online|] ;Assume he removed memory
TLNN F,(FL.ADD) ;Did he really add
MOVEI S1,[ASCIZ |offline|] ;Yes, get real message
LSH T2,-1 ;Convert to kilos
LSH T3,-1 ;Both addresses
$TEXT (WTORTN,<Memory from address ^D/T2/K to ^D/T3/K is now ^T/(S1)/>)
LSH T2,^D10 ;Convert to words now
LSH T3,^D10 ; . . .
$TEXT (WTORTN,<(Words from ^O/T2/ to ^O/T3/)>)
$RETT ;Return true
SUBTTL ADD/REMOVE KONTROLLER
ADDKON: $IACK (^T/@ADDREM/ CONTROLLER)
$SAVE <P1,P2,P3> ;Make room
HRLZS S1 ;Put kontroller name in LH
PUSHJ P,FNDKON ;Get the next disk kontroller
$RETIF ;Message already given
DMOVE P1,S1 ;Save controller and unit
PUSHJ P,SETCPU ;SET UP NEEDED CPU DATA BASE
MOVEM P1,DCHARG+.DCNAM ;For DSKCHR
MOVE T1,[.DCMAX,,DCHARG] ;Point at DSKCHR argument list
DSKCHR T1, ;Get info
JRST FNDK.E ;But we already found it?
LOAD S1,DCHARG+.DCXCH,DC.XCA ;Get CPU mask
TDNE S1,CPURUN ;Any of the CPUs up?
JRST CONT.3 ;Yes, remove kontroller and return
$TEXT (WTORTN,<CPU owning controller is down>)
$RETF ;END MESSAGE AND RETURN
CONT.3: MOVE P3,S1 ;Save bit mask
MOVE P2,P1 ;Shuffle first unit on the controller
MOVEI P1,2 ;And set up lenght of RECON. arg block
JRST DKONCM ;Go remove it
SUBTTL ADD/REMOVE CPU
ADDCPU: SUBI S1,.ARCPU## ;Translate to CPU number
CAIL S1,0 ;Range check
CAILE S1,5 ; (ALL is illegal)
$RETF ;Give up if not valid
$SAVE <P1> ;Make room for the CPU number
MOVE P1,S1 ;Save it
PUSHJ P,SETCPU ;Set up the CPU database
$IACK (^T/@ADDREM/ CPU)
MOVSI S1,(CS.NEX) ;NON-EXISTANT BIT
CAIGE P1,6 ;RANGE CHECK CPU NUMBER
TDNE S1,CPUSTS(P1) ;IN RANGE, IS IT REAL
TRNA ;Error
JRST ADDCP1 ;Yep try to do it
$TEXT (WTORTN,<Illegal CPU specified - CPU^O/P1/ does not exist>)
$RETF
ADDCP1: TLNE F,(FL.ADD) ;Adding?
JRST R%CPUA ;Go to that routine
;HERE TO REMOVE A CPU
SKIPGE CPUSTS(P1) ;CPU ALREADY DOWN
$RETT ;YES, JUST RETURN NOW
MOVE T3,CPUN ;GET NUMBER OF RUNNING CPUS
CAIE T3,1 ;TRYING TO REMOVE THE LAST REMAINING CPU
JRST ADDCP2 ;NO, ONWARD
$TEXT (WTORTN,<Use SHUTDOWN to remove last CPU>)
$RETF ;END OUTPUT AND RETURN
ADDCP2: MOVE T3,CPUOK ;NUMBER OF ACTUALLY RUNNING CPUS
CAIE T3,1 ;ONLY ONE OF THOSE LEFT
JRST CPU.1 ;NO
MOVSI T3,(CS.NOK) ;YES, CHECK IF CPU NOT RUNNING ANYWAY
TDNE T3,CPUSTS(P1) ;WELL?
JRST CPU.1 ;CPU IS DEAD, OK TO REMOVE IT
$TEXT (WTORTN,<No running CPUs will be left>)
$RETF ;IF OPERATOR REALLY WANTS THIS, USE "SHUT"
CPU.1: $CALL P$SWITCH## ;See if he typed the force switch
JUMPF CPU.10 ;No, check before doing
CAIN S1,.ARFRC## ;Force switch?
JRST CPU.2 ;Yes, so bypass
CPU.10: TLO F,(FL.WAC!FL.CHK) ;SET "WORRY ABOUT CPU",ONLY CHECKING
MOVE S1,P1 ;Get the CPU number
PUSHJ P,RADKON ;CHECK ALL DISK KONTROLLERS
TLNE F,(FL.NCD) ;DID SOME CHECK FAIL
$RETF ;YES, CANNOT REMOVE THE CPU
MOVE S1,P1 ;Get the CPU number
PUSHJ P,LSTDEV ;LOOK FOR LOST DEVICES, GIVE WARNING
TLZ F,(FL.CHK) ;NOT CHECKING ANY MORE
MOVE S1,P1 ;Get the CPU we're removing
PUSHJ P,DETJBS ;DETACH JOBS AS APPROPRIATE
TRNA ;WE HAVE DONE CHECKS
CPU.2: $TEXT (WTORTN,<%Bypassing lots of checking>)
MOVSI S1,(CS.DWN) ;GET CPU IS DOWN BIT
IORB S1,CPUSTS(P1) ;LIGHT IN STATUS BLOCK
SOS CPUN ;ONE LESS CPU IN SYSTEM
TLNN S1,(CS.NOK) ;WAS CPU'S OK WORD COUNTING BEFORE
SOS CPUOK ;YES, BUT IT WILL STOP SOON
MOVSI S1,(CS.NOK) ;IN CASE IT WASN'T
IORM S1,CPUSTS(P1) ;LIGHT THE BIT NOW
MOVEI S1,1 ;GET BIT FOR CPU0
LSH S1,(P1) ;POSITION FOR CORRECT CPU
ANDCAB S1,CPURUN ;CLEAR/GET NEW RUNNING CPU MASK
HRLI S1,.STCRN ;SET RUN CPUN
SETUUO S1, ;SET NEW SPECIFICATION
$TEXT (WTORTN,<SETUUO to set CPU^D/S1/ runnability failed>)
MOVEI S1,(P1) ;GET CPU NUMBER
LSH S1,1 ;*2 FOR SUBTABLE GETTABS
ADD S1,[%CCOKP] ;GET THE OK WORD FOR CPUN
GETTAB S1, ;GET IT
$TEXT (WTORTN,<%Unable to determine status of CPU^D/P1/ - continuing>)
JUMPG S1,CPU.5 ;AVOID LOOP, SHUT IT DOWN IF ALREADY DEAD
CPU.3: MOVEI S1,(P1) ;GET CPU NUMBER
LSH S1,1 ;*2 FOR SUBTABLE GETTABS
ADD S1,[%CVJOB] ;JOB CURRENTLY RUNNING ON CPU
GETTAB S1, ;GET IT
$TEXT (WTORTN,<%Unable to determine job running on CPU^D/P1/ - continuing>)
JUMPN S1,CPU.3 ;WAIT FOR CPU TO ONLY RUN NULL JOB
CPU.4: TLZ F,(FL.HEA) ;MAKE SURE HEADER GETS PRINTED
MOVE S1,P1 ;GET THE CPU NUMBER
TLNN F,(FL.DMN) ;DONT DETACH IF FORCED REMOVAL
PUSHJ P,RADKON ;GO AND DETACH ALL THE UNITS NOW
CPU.5: MOVEI S1,ST.URE(P1) ;GET CPU NUMBER, FLAG AS REMOVE
HRLI S1,.STCDN ;SET "DOWN" CPUN
SETUUO S1, ;SHUT IT DOWN
$TEXT (WTORTN,<%Can't shut down CPU^D/P1/>)
CPU.6: MOVEI S1,(P1) ;GET CPU NUMBER
LSH S1,1 ;*2 FOR SUBTABLE GETTABS
ADD S1,[%CCOKP] ;GET THE OK WORD FOR CPUN
GETTAB S1, ;GET IT
SKIPA ;ASSUME DOWN
JUMPLE S1,CPU.6 ;WAIT FOR IT TO STICK ITS HEAD IN THE SAND
MOVE S1,CPUN ;HOW MANY CPU'S ARE LEFT
CAIE S1,1 ;ONLY 1 REMAINING
JRST CPU.7 ;NO, JUST MAKE THE CPU GO AWAY
MOVSI S1,.STCSB ;OK TO CACHE MONITOR DATA BASE NOW
HRRI S1,1B35 ;LIGHT BIT TO TURN ON CACHE
SETUUO S1, ;SINCE ONLY 1 PROCESSOR LEFT
JFCL ;OK, MUST BE A KI
CPU.7: MOVSI S1,(CS.DET) ;"CPU DETACHED" BIT
TDNE S1,CPUSTS(P1) ;IS THE CPU ALREADY DETACHED
$RETT ;YES, RETURN NOW
IORM S1,CPUSTS(P1) ;SAY DETACHED NOW
MOVE S1,[XWD .RCDET,T1] ;GET THE DETACH CPU FUNCTION
MOVEI T1,2 ;Get the lenght of the arge block
MOVE T2,CPUNAM(P1) ;And get the SIXBIT CPU name
RECON. S1, ;Do the request
JRST RCNERR
$RETT
;HERE TO ADD A CPU
R%CPUA: SKIPL CPUSTS(P1) ;IS IT ALREADY UP
JRST CPUA.2 ;YES, GO LET IT IN (UNDO OPSER'S ":SET RUN")
MOVSI S1,(CS.DWN!CS.NOK) ;CPU IS DOWN BIT
ANDCAM S1,CPUSTS(P1) ;NOT ANY MORE
AOS CPUN ;ONE MORE CPU RUNNING
AOS CPUOK ;ONE MORE COUNTING
MOVSI S1,.STCSB ;MUST UNCACHE MONITOR DATA BASE
SETUUO S1, ;DO IT (1B35 = 0)
JFCL ;OK, MUST BE A KI
MOVSI S1,(CS.DET) ;CPU DETACHED BIT
TDNN S1,CPUSTS(P1) ;IS IT
JRST CPUA.1 ;NO, LET IT IN
ANDCAM S1,CPUSTS(P1) ;CLEAR DETACHED CPU BIT
MOVEI S1,2 ;TWO WORD ARGUMENT
MOVE S2,CPUNAM(P1) ;GET CPU NAME
DMOVEM S1,RCNARG ;SAVE
MOVE S1,[.RCATT,,RCNARG] ;SET UP UUO AC
RECON. S1, ;Go it
JRST RCNERR
TLNE F,(FL.NCD) ;DID IT WORK
$RETT ;NO, RETURN NOW
CPUA.1: MOVE S1,P1 ;GET CPU NUMBER (ST.URE OFF = ADD THIS ONE)
HRLI S1,.STCDN ;SET CPU UP ( OR ALLOWED TO BE UP )
SETUUO S1, ;i.e. LET THIS CPU IN
$TEXT (WTORTN,<Can't set CPU^D/T2/ to up status>)
CPUA.2: MOVEI S1,1B35 ;GET A BIT FOR CPU0
LSH S1,(P1) ;POSITION FOR CPUN
IORB S1,CPURUN ;ADD/GET NEW RUNNING CPU MASK
HRLI S1,.STCRN ;NOW ALLOW IT TO RUN JOBS
SETUUO S1, ;OTHERWISE WHY BOTHER ADDING IT
$TEXT (WTORTN,<Can't set CPU^D/P1/ to run jobs>)
$RETT ;ADDING IS A LOT EASIER THAN REMOVING
SUBTTL ENABLE/DISABLE CI
ADDCI: SUBI S1,.ARCI## ;TRANSLATE TO CI NUMBER
CAIL S1,0 ;RANGE
CAILE S1,6 ; CHECK
$RETF ;GIVE UP IF NOT VALID
$SAVE <P1> ;SAVE AN AC
MOVSI P1,-6 ;ASSUME ALL CPUS
CAIE S1,6 ;WAS IS?
HRRO P1,S1 ;NO
PUSHJ P,P$CFM## ;NEED A CRLF
$RETIF ;ERROR
$IACK (^T/@ADDREM/ CI)
ADCI.1: HRLZ T1,P1 ;GET CPU NUMBER
HRRI T1,.DIISM ;DIAG. FUNCTION TO SET MAINT MODE
TLNE F,(FL.ADD) ;"ADD CI"?
HRRI T1,.DIICM ;YES, THAT MEANS CLEAR MAINT MODE
MOVX T2,<574B8> ;LOAD DEVICE CODE
MOVEI S1,[ASCIZ |dis|] ;ASSUME REMOVING
TLNE F,(FL.ADD) ;GOOD GUESS?
MOVEI S1,[ASCIZ |en|] ;NOPE
MOVE S2,[XWD -2,T1] ;POINT AT THE ARGUMENTS
DIAG. S2, ;DO THE UUO
JRST ADCI.2 ;ERROR
$TEXT (WTORTN,<CI port on CPU^O/T1,LHMASK/ ^T/0(S1)/abled>)
JRST ADCI.3 ;ONWARD
ADCI.2: CAIN S2,DIANR% ;CPU DOWN?
JRST ADCI.3 ;YES
CAIL S2,DIAETL ;KNOWN ERROR CODE?
MOVEI S2,DIAETL ;NO, USE CATCH-ALL
$TEXT (WTORTN,<DIAG. UUO error attempting to ^T/0(S1)/able CI port on CPU^O/T1,LHMASK/^M^J(Error (^O/S2/) ^T/@DIAETX(S2)/)>)
ADCI.3: AOBJN P1,ADCI.1 ;LOOP FOR ANOTHER CPU
$RETT ;RETURN
SUBTTL ENABLE/DISABLE NI
.DIANI==114 ;NI MISCELLANEOUS FUNCTIONS
.DINEN==1 ;ENABLE/DISABLE SUB-FUNCTION
ADDNI: SUBI S1,.ARNI## ;TRANSLATE TO CI NUMBER
CAIL S1,0 ;RANGE
CAILE S1,6 ; CHECK
$RETF ;GIVE UP IF NOT VALID
$SAVE <P1> ;SAVE AN AC
MOVSI P1,-6 ;ASSUME ALL CPUS
CAIE S1,6 ;WAS IS?
HRRO P1,S1 ;NO
PUSHJ P,P$CFM## ;NEED A CRLF
$RETIF ;ERROR
$IACK (^T/@ADDREM/ NI)
ADNI.1: HRLZ T1,P1 ;GET CPU NUMBER
HRRI T1,.DIISM ;DIAG. FUNCTION TO SET MAINT MODE
TLNE F,(FL.ADD) ;"ADD NI"?
HRRI T1,.DIICM ;YES, THAT MEANS CLEAR MAINT MODE
MOVX T2,<564B8> ;LOAD DEVICE CODE
MOVEI S1,[ASCIZ |dis|] ;ASSUME REMOVING
TLNE F,(FL.ADD) ;GOOD GUESS?
MOVEI S1,[ASCIZ |en|] ;NOPE
MOVE S2,[XWD -2,T1] ;POINT AT THE ARGUMENTS
DIAG. S2, ;DO THE UUO
JRST ADNI.2 ;ERROR
$TEXT (WTORTN,<NI port on CPU^O/T1,LHMASK/ ^T/0(S1)/abled>)
JRST ADNI.3 ;ONWARD
ADNI.2: CAIN S2,DIANR% ;CPU DOWN?
JRST ADNI.3 ;YES
CAIL S2,DIAETL ;KNOWN ERROR CODE?
MOVEI S2,DIAETL ;NO, USE CATCH-ALL
$TEXT (WTORTN,<DIAG. UUO error attempting to ^T/0(S1)/able NI port on CPU^O/T1,LHMASK/^M^J(Error (^O/S2/) ^T/@DIAETX(S2)/)>)
ADNI.3: AOBJN P1,ADNI.1 ;LOOP
$RETT ;RETURN
SUBTTL "LOAD microcode"
C$LOAD: $IACK (LOAD microcode)
PUSHJ P,ULDARG ;GET DIAG ARGUMENTS
$RETIF ;CHECK FOR ERRORS
HRRI T1,.DILOD ;FUNCTION CODE
MOVE S1,[-2,,T1] ;SET UP UUO AC
DIAG. S1, ;LOAD MICROCODE
JRST LOAD.E ;FAILED
$TEXT (WTORTN,<Microcode loaded on ^T/ULDTXT/>)
$RETT ;RETURN
LOAD.E: $TEXT (WTORTN,<Microcode load failed; ^A>)
PJRST DIAERR ;REPORT DIAG ERROR AND RETURN
; RETURN DIAG. UUO ARGUMENTS FOR LOAD AND SET [NO] MICROCODE COMMANDS
ULDARG: SETZ T1, ;ASSUME CPU0
PUSHJ P,P$KEYW## ;GET A KEYWORD
JUMPF ULDDEV ;TRY FOR A DEVICE CODE
; CPU NUMBER
ULDCPU: MOVEI S2,-.ARCPU##(S1) ;GET POSSIBLE CPU INDEX
CAIL S2,0 ;RANGE
CAILE S2,5 ; CHECK
JRST ULDKON ;PERHAPS A KONTROLLER
MOVE T1,S2 ;SAVE
; DEVICE CODE
ULDDEV: PUSHJ P,P$NUM## ;GET A DEVICE CODE
JUMPF ULDOPE ;OPR CMD ERROR
CAIL S1,000 ;RANGE
CAILE S1,776 ; CHECK
JRST ULDDCE ;ILLEGAL DEVICE CODE
TRNE S1,3 ;ONE MORE
JRST ULDDCE ;ILLEGAL DEVICE CODE
HRLZ T2,S1 ;SAVE
PUSHJ P,P$NUM## ;ELSE GET A UNIT NUMBER
JUMPF ULDOPE ;OPR CMD ERROR
CAIL S1,0 ;RANGE
CAILE S1,7 ; CHECK
JRST ULDUNE ;ILLEGAL UNIT NUMBER
LSH S1,3 ;POSITION
HRR T2,S1 ;SAVE
JRST ULDXIT ;DONE
; KONTROLLER NAME
ULDKON: HRLZ S2,S1 ;COPY KEYWORD INDEX
MOVEM S2,DCHARG ;INCASE IT'S A DISK KONT
MOVE S2,[.DCMAX,,DCHARG] ;SET UP UUO AC
DSKCHR S2, ;A DISK?
JRST ULDKO1 ;NO--TRY FOR A NON-DISK KONT
MOVE S2,DCHARG+.DCUPN ;GET UNIT NAME
LOAD TF,DCHARG+.DCXCH,DC.XCA ;GET CPU MASK
JRST ULDKO2 ;ONWARD
ULDKO1: HRLZ S2,S1 ;COPY KEYWORD INDEX
DEVNAM S2, ;A NON-DISK KONTROLLER?
JRST ULDCIP ;CHECK CI PORT
MOVE TF,[.RCCPU,,S1] ;SET UP UUO AC
MOVEI S1,2 ;TWO WORD ARG BLOCK
RECON. TF, ;GET CPU MASK
JRST ULDNCP ;CAN'T GET CPU NUMBER
ULDKO2: JFFO TF,.+1 ;FIND FIRST BIT
MOVEI T1,43 ;OFFSET FROM CPU0
SUB T1,S1 ;GET CPU NUMBER
MOVE T2,[-2,,S1] ;SET UP UUO AC
MOVEI S1,.DIAKU ;FUNCTION CODE
DIAG. T2, ;TRANSLATE KONT NAME INTO DIAG ARGS
JRST ULDNDC ;CAN'T GET DEVICE CODE
JRST ULDXIT ;DONE
; CI20 PORT
ULDCIP: MOVEI S2,-.ARCI##(S1) ;GET POSSIBLE CI PORT INDEX
CAIL S2,0 ;RANGE
CAILE S2,5 ; CHECK
JRST ULDNIP ;CHECK NI PORT
MOVE T1,S2 ;PUT CPU NUMBER IN LH
MOVSI T2,574 ;DEVICE CODE
JRST ULDXIT ;DONE
; NIA20 PORT
ULDNIP: MOVEI S2,-.ARNI##(S1) ;GET POSSIBLE NI PORT INDEX
CAIL S2,0 ;RANGE
CAILE S2,5 ; CHECK
JRST ULDDCE ;SAY CAN'T DETERMINE DEVICE CODE
MOVE T1,S2 ;PUT CPU NUMBER IN LH
MOVSI T2,564 ;DEVICE CODE
; JRST ULDXIT ;DONE
; EXIT
ULDXIT: HLRZ S1,T2 ;GET DEVICE CODE
LDB S2,[POINT 3,T2,32] ;GET UNIT NUMBER
$TEXT (<-1,,ULDTXT>,<^I/ULDITX/^0>) ;GENERATE ACK TEXT
HRLZS T1 ;POSITION CPU NUMBER
MOVE S1,T2 ;COPY DEVICE,,UNIT
TRZ S1,7 ;CLEAR SLAVE NUMBER
TRZ T2,70 ;CLEAR UNIT NUMBER
LSH S1,3 ;POSITION UNIT FIELD
IOR T2,S1 ;MERGE CORRECT UNIT/SLAVE
LSH S1,6 ;POSITION DEVICE CODE
HLL T2,S1 ;REPLACE
$RETT ;RETURN
ULDITX: ITEXT (<CPU^O/T1/, device ^O3/S1/, unit ^O/S2/>)
ULDOPE: MOVEI S2,[ASCIZ /Operator command parsing error/]
JRST ULDERR
ULDDCE: MOVEI S2,[ASCIZ /Illegal device code/]
JRST ULDERR
ULDUNE: MOVEI S2,[ASCIZ /Illegal unit number/]
JRST ULDERR
ULDNDC: MOVEI S2,[ASCIZ /Cannot determine device code for controller/]
JRST ULDERR
ULDNCP: MOVEI S2,[ASCIZ /Cannot determine CPU number for controller/]
; JRST ULDERR
ULDERR: $TEXT (WTORTN,<^T/(S2)/>)
$RETF
SUBTTL The "SUSPEND" Command
MBTPGS==10 ;NUMBER OF PAGES FOR MONBTS
C$SUSP: $IACK (SUSPEND)
$CALL P$TEXT ;Get the text string
SKIPF ;Failed?
SKIPN 1(S1) ;String null?
JRST REAS.1 ;No reason given is an error
MOVEM S1,RSNADR ;Store its address
MOVE S1,[.RCROM,,T1] ;SET TO RUN ONLY 1 JOB
MOVEI T1,2 ;2 WORD ARGUMENT BLOCK
SETZ T2, ;JOB NUMBER 0 = ALLOW ALL USERS
RECON. S1, ;DO THE UUO
JRST RCNERR ;FAILED, TELL WHY
MOVEI S1,[ASCIZ /SEND ALL Expect an interruption of service/]
PUSHJ P,SNDALL ;OUTPUT THE MESSAGE
MOVEI S1,^D5 ;GIVE IT TIME TO TYPE OUT
SLEEP S1, ;WAIT
HRRZ S1,MONVER ;Get the monitor version
CAILE S1,70200 ;Pre-7.03?
JRST SUSP.5 ;No, 7.03 doesn't need this
MOVE S1,[XWD .RCMOF,T1] ;Point to the rem mem arg block
MOVEI T1,3 ;Get the lenght of the argument block
MOVE T2,SYSSIZ ;FIRST WORD OUTSIDE THE MONITOR
SUSP.3: MOVE T3,T2 ;COPY ADDRESS
ADDI T3,<MBTPGS*PAGSIZ>-1 ;LAST LOCATION NEEDED FOR MONBTS
CAMLE T3,NWCORE ;OFF THE TOP OF MEMORY
JRST SUSP.6 ;No room at all
RECON. S1, ;Tell the monitor what we want
TRNA ;Failed? Try again
JRST SUSP.5 ;It worked, continue
ADDI T2,PAGSIZ ;TRY A DIFFERENT PLACE
JRST SUSP.3 ;TRY AGAIN
SUSP.5: DMOVEM T2,SAVEP3 ;Save the addresses for later
MOVE S1,[.RCROM,,T1] ;SET TO RUN ONLY ME NOW
MOVEI T1,2 ;2 WORD ARGUMENT BLOCK
MOVE T2,G$MJOB## ;ONLY ME
RECON. S1, ;DO IT
JRST RCNERR
MOVSI S1,.RCIOW ;Get wait for I/O to finish function
RECON. S1, ;Wait
JRST RCNERR
PUSHJ P,SETCPU ;SET UP CPU DATA BASE
MOVSI T1,-6 ;NUMBER OF CPUS
SUSP.1: SKIPL T2,CPUSTS(T1) ;IS THE CPU DOWN
TLNE T2,(CS.BOT) ;OR THE BOOT CPU
JRST SUSP.2 ;IGNORE THIS ONE
MOVEI T2,ST.USU(T1) ;GET CPU NUMBER AND FLAG = SUSPEND THYSELF
HRLI T2,.STCDN ;SET "DOWN" CPU FUNCTION
SETUUO T2, ;MAKE IT GO AWAY
$TEXT (WTORTN,<Can't set CPU^D/(T1),RHMASK/ offline>)
SUSP.2: AOBJN T1,SUSP.1 ;DO ALL CPUS THAT WILL REMAIN AFTER SUSPEND
MOVSI S1,.RCIOW ;Get wait for I/O to finish function
RECON. S1, ;Wait
JRST RCNERR
MOVE S1,SAVEP3 ;Get the address of MONBTS
ADR2PG S1 ;Make it into a page number
HRLI S1,.RCSPN ;FUNCTION SUSPEND
MOVE 0,RSNADR ;Get the address of the reason
ADDI 0,1 ; so it can be found in the dump
RECON. S1, ;Do the suspend
TRNA ;Failed? Get everything back
JRST SUSP.4 ;Monitor already welcomed users
MOVEI S1,[ASCIZ /SEND ALL System resumed/]
PUSHJ P,SNDALL ;TELL WORLD THE SYSTEM IS BACK
SUSP.4: MOVE S1,[.RCROM,,T1] ;SET TO RUN ONLY 1 JOB
MOVEI T1,2 ;2 WORD ARGUMENT BLOCK
SETZ T2, ;JOB NUMBER 0 = ALLOW ALL USERS
RECON. S1, ;DO THE UUO
JRST AUTO.E ;Something really wrong here
HRRZ S1,MONVER ;Get the monitor version
CAILE S1,70200 ;Pre-7.03?
$RETT ;No, 7.03 doesn't need this
MOVE S1,[XWD .RCMON,T1] ;Get back the memory
MOVEI T2,3 ; MONBTS used
DMOVE T3,SAVEP3 ;Get the addresses
RECON. S1, ;Tell the monitor what we want
JFCL ;Failed? Non-fatal for now
$RETT
SUSP.6: $TEXT (WTORTN,<Cannot reorganize memory to make room for MONBTS reload>)
$RETT
SUBTTL The "SNAPSHOT" and "SHUTDOWN" commands
C$SNAP: $IACK (SNAPSHOT)
MOVSI T1,.RCCI7 ;WANT A CI7 CONTINUABLE STOPCD
JRST REASON ;ASK FOR REASON, DO COMMAND
C$SHUT: $IACK (SHUTDOWN)
MOVSI T1,.RCRLD ;WANT TO RELOAD THE MONITOR
JRST REASON ;ASK FOR REASON, DO COMMAND
REASON: $CALL P$TEXT## ;Get the reason
JUMPF REAS.1 ;Need a reason
MOVEI 0,1(S1) ;POINT TO IT WITH AC 0 FOR THE DUMP
SKIPN @0 ;Null reason illegal also
JRST REAS.1
MOVE S1,T1 ;Get function to perform (for RCNERR)
RECON. S1, ;DO THE FUNCTION
JRST RCNERR ;GIVE ERROR
$RETT ;RETURN
REAS.1: $TEXT (WTORTN,<A reason must be specified>)
$RET
SUBTTL The "AUTOCONFIGURE" command
C$AUTO: $SAVE <P1> ;SAVE P1
PUSHJ P,P$KEYW## ;TRY FOR A KEYWORD
JUMPF AUTO.A ;NO GOOD
SUBI S1,.ARCPU## ;OFFSET
CAIL S1,0 ;RANGE
CAILE S1,6 ; CHECK
$RETF ;BAD CPU NUMBER
CAIN S1,6 ;ALL CPUS?
AUTO.A: MOVNI S1,1 ;YES--SET TO -1
MOVE P1,S1 ;PRESERVE CPU ARGUMENT
PUSHJ P,P$CFM## ;TIME FOR A CRLF
$RETIF ;JUNK INPUT
$IACK (AUTOCONFIGURE)
TLZ F,(FL.ADD) ;SET TO SEIZE MAGTAPE CONTROLLERS
PUSHJ P,RADMTK ;DO IT
JUMPF AUTO.9 ;Not supported
MOVE S1,[.RCROM,,T1] ;SET TO RUN ONLY ME NOW
MOVEI T1,2 ;2 WORD ARGUMENT BLOCK
MOVE T2,G$MJOB## ;ONLY ME
RECON. S1, ;DO IT
JRST RCNERR ;PROBABLY NOT PRIVLEGED
MOVSI S1,.RCIOW ;Get wait for I/O to finish function
RECON. S1, ;Wait
JRST RCNERR
MOVE S1,[.RCRAC,,T1] ;AUTOCONFIGURE
MOVEI T1,2 ;ARGUMENT LIST IS 2 WORDS LONG
MOVE T2,P1 ;GET CPU ARGUMENT
RECON. S1, ;DO IT
TRNA
JRST AUTO.0 ;Done, continue onward
PUSHJ P,AUTO.9 ;Type this is not supported
MOVE S1,[.RCROM,,T1] ;SET TO TURN TIMESHARING BACK ON
MOVEI T1,2 ;2 WORD ARGUMENT LIST
SETZ T2, ;ALLOW USERS AGAIN
RECON. S1, ;DO IT
JRST AUTO.E ;System very sick
TLO F,(FL.ADD) ;ALSO FREE UP MAGTAPES
PUSHJ P,RADMTK ;RELEASE MTA KONTROLLERS
$RETT ;FINISH THE LINE AND EXIT
AUTO.0: MOVE S1,[.RCROM,,T1] ;SET TO RUN ALL JOBS
MOVEI T1,2 ;2 WORD ARGUMENT BLOCK
SETZ T2, ;JOB NUMBER 0 = ALLOW ALL USERS
RECON. S1, ;DO THE UUO
JRST AUTO.E ;Nasty trouble
PUSHJ P,SETCPU ;SET UP CPU DATA BASE
TLO F,(FL.ADD) ;WANT TO ADD CONTROLLERS
PUSHJ P,RADMTK ;FREE UP MAGTAPE KONTROLLERS
MOVSI T1,-6 ;NUMBER OF CPUS
AUTO.1: SKIPGE CPUSTS(T1) ;CPU UP?
JRST AUTO.2 ;NO, DON'T WORRY ABOUT IT
HRRZ S1,T1 ;CPU TO RADKON
PUSHJ P,RADKON ;ADD ALL CHANNELS ON THIS CPU
AUTO.2: AOBJN T1,AUTO.1 ;DO IT FOR ALL CPUS
$RETT ;ALL DONE, SO JUST EXIT
AUTO.9: $TEXT (WTORTN,<Monitor does not support auto-configuration>)
$RETF
;Here when we try to set system to run all and fail. The system is
;totally useless, and we might as well just reload.
AUTO.E: $TEXT (CTYTYP,<^G^G?Error trying to set all users to run>)
$TEXT (CTYTYP,<Error code from RECON. UUO is ^O/S1/>)
$TEXT (CTYTYP,<System shutting down with RLD stopcode>)
MOVEI 0,[ASCIZ |ORION CONFIG error trying to set all users to run|]
MOVSI S1,.RCRLD ;Get the reload function
RECON. S1, ;Reload the system please
TRNA ;Now we really can't do much more
$RETT ;Just for consistency's sake
$TEXT (CTYTYP,<^G^G?Error attempting reload function>)
$TEXT (CTYTYP,<Error code from RECON. UUO is ^O/S1/>)
$TEXT (CTYTYP,<Please reload system manually - ORION halting>)
$STOP(ESS,<Error shutting down system>)
;SUBROUTINE TO SEIZE OR RELEASE MAGTAPE CONTROLLERS
; RETURNS TRUE NORMALLY, FALSE IF NOT-IMPLEMENTED OR ALREADY SEIZED
RADMTK: $SAVE <P1,P2> ;Get some save acs
MOVE S1,[-2,,P1] ;DIAG. ARGUMENT LIST
MOVEI P1,.DIARM ;ASSUME RELEASING MAGTAPE KONTROLLERS
TLNN F,(FL.ADD) ;ACTUALLY SEIZING KONTROLLERS?
MOVEI P1,.DIASM ;YES, SET TO SEIZE KONTROLLER
MOVEI P2,0 ;ALL KONTROLLERS
DIAG. S1, ;DO IT
JRST DIAERR ;REPORT ERROR
$RETT
SUBTTL The "SET" command
C$SET: $CALL P$KEYW## ;Get the set keyword
$RETIF
MOVEI S2,SETDSP ;Get the address of the table
$CALL TABSRC## ;FIND ARGUMENT
$RETIF
JRST (S2) ;DISPATCH TO PROCESS ARGUMENT
;"NO"
SETNOT: TLO F,(FL.NO) ;Set no flag
$CALL P$KEYW## ;Get the next keyword
$RETIF
MOVEI S2,STNDSP ;GEt the address of the table to search
$CALL TABSRC## ;Fidn it
$RETIF
JRST (S2) ;Call the routine
;"MICROCODE (loading)"
SETULD: $IACK (SET MICROCODE)
PUSHJ P,ULDARG ;GET DIAG ARGUMENTS
$RETIF ;CHECK FOR ERRORS
MOVEI S2,[ASCIZ /enabled/] ;ASSUME ENABLE
TLNE F,(FL.NO) ;NO?
MOVEI S2,[ASCIZ /disabled/] ;DISABLE
HRRI T1,.DIELD ;ASSUME ENABLE
TLNE F,(FL.NO) ;NO?
HRRI T1,.DIDLD ;DISABLE
MOVE S1,[-2,,T1] ;SET UP UUO AC
DIAG. S1, ;LOAD MICROCODE
JRST ULDX.E ;FAILED
$TEXT (WTORTN,<Microcode loading is ^T/(S2)/ on ^T/ULDTXT/>)
$RETT
ULDX.E: $TEXT (WTORTN,<Set microcode loading ^T/(S2)/ failed; ^A>)
PJRST DIAERR ;REPORT DIAG ERROR AND RETURN
;"RELOAD"
SETAUT: $IACK (SET AUTO-RELOAD)
MOVE S1,[.RCNAR,,T1] ;GET FUNCTION CODE,,ADDRESS
MOVEI T1,2 ;LENGTH OF BLOCK IS 2
MOVE T2,F ;GET FLAG WORD
ANDX T2,<FL.NO> ;Set no if no bit on
RECON. S1, ;DO FUNCTION
JRST RCNERR ;FAILED, TELL WHY
MOVEI S1,[ASCIZ |enabled|] ;Assume he's enabling
TLNE F,(FL.NO) ;Is he really disabling
MOVEI S1,[ASCIZ |disabled|] ;Yes, get the real message
$TEXT (WTORTN,<Automatic system reload is ^T/(S1)/>)
$RETT
;"BOOTXT"
SETBOT: $CALL P$TEXT## ;Get the boot text
$RETIF
DMOVE T1,S1 ;Save the temporary ACs
$IACK (SET BOOTXT)
DMOVE S1,T1 ;Restore the temporaries
CAIG S2,.TXTSZ ;Less than eighty characters?
JRST SBOT.1 ;Yes, onward
$TEXT (WTORTN,<Maximum of ^D/[.TXTSZ]/ characters allowed for boot message>)
$RETF
SBOT.1: MOVEI T3,1(S1) ;Get the address of the text
HRLI T3,(POINT 7,) ;Build a byte pointer
MOVE T4,[POINT 7,RSNTXT] ;And get the destination pointer
SETZ T2, ;Zero character counter
SBOT.2: ILDB T1,T3 ;Get a character
JUMPE T1,SBOT.3 ;If the end, go finish things up
IDPB T1,T4 ;Store into the arg block
AOJA T2,SBOT.2 ;Count the character and loop
SBOT.3: SETZ T1,
IDPB T1,T4
MOVEI S1,2(T2) ;INCLUDE CR/NULL IN COUNT, MOVE TO P1
IDIVI S1,5 ;COMPUTE WORD COUNT
SKIPE S2 ;ANY RESIDUAL BYTES IN NEXT WORD?
ADDI S1,1 ;YES, ACCOUNT FOR THAT
ADDI S1,1 ;INCLUDE THE WORD COUNT WORD
MOVEM S1,RCNARG ;STORE WORD COUNT
MOVE S1,[.RCBTX,,RCNARG] ;POINT TO BLOCK
RECON. S1, ;REPLACE THE BOOTXT STRING
JRST RCNERR ;FAILED, TELL WHY
MOVEI S1,RSNTXT ;Get address of string
SKIPN T2 ;Null string?
MOVEI S1,[ASCIZ |[Null]|] ;Otherwise get null indicator
$TEXT (WTORTN,<Boot-text setting accepted. New boot string is:>)
$TEXT (WTORTN,< ^T/(S1)/>)
$RETT
;"DUMP" OR "RELOAD"
SETDMP: TDZA S1,S1 ;NOTE "DUMP" ENTRY AND SKIP
SETRLD: MOVEI S1,1 ;NOTE "RELOAD" ENTRY
$SAVE <P1,P2> ;SAVE AN AC OR TWO
MOVE P1,S1 ;SAVE ENTRY FLAG IN P1
SETZ P2, ;START WITH NOTHING
SDMP.1: $CALL P$KEYW## ;GET NEXT KEYWORD
$RETIF
MOVEI S2,DMPTAB ;ASSUME DUMP
SKIPE P1 ;GOOD GUESS?
MOVEI S2,RLDTAB ;NO
$CALL TABSRC## ;TRANSLATE THE KEYWORD
$RETIF ;SHOULDN'T HAPPEN
IOR P2,(S2) ;ADD IN THE BIT
$CALL P$COMMA## ;SEE IF COMMA
JUMPT SDMP.1 ;IF SO, KEEP LOOKING
$CALL P$CFM## ;SEE IF CONFIRM
$RETIF
$IACK (SET ^T/@DMPRLD(P1)/)
JUMPN P1,SRLD.1 ;JUMP IF SET [NO] RELOAD
MOVSI S1,.RCSDF ;ASSUME SET
TLNN F,(FL.NO) ;DID THEY SAY NO?
MOVSI S1,.RCCDF ;NO, THAT MEANS CLEAR THE BITS
JRST SDMP.2 ;JOIN COMMON CODE
SRLD.1: MOVSI S1,.RCSDF ;ASSUME SET
TLNE F,(FL.NO) ;DID THEY SAY NO?
MOVSI S1,.RCCDF ;YES, THAT MEANS CLEAR THE BITS
SDMP.2: HRRI S1,T1 ;ADDRESS OF ARGUMENT LIST
MOVEI T1,2 ;NUMBER OF WORDS
MOVE T2,P2 ;COPY FLAGS HERE
RECON. S1, ;DO IT
JRST RCNERR ;ERROR
PJRST SHST.1 ;FINISH UP VIA SHOW STOPCODE-FLAGS
DMPRLD: [ASCIZ /DUMP/]
[ASCIZ /RELOAD/]
DMPTAB: $STAB
.STCPN##,,[ST%DCP]
.STDBG##,,[ST%DDC]
.STJOB##,,[ST%DJE]
$ETAB
RLDTAB: $STAB
.STCPN##,,[ST%CP1]
.STDBG##,,[ST%RDC]
.STJOB##,,[ST%RJE]
$ETAB
SUBTTL The "SHOW STOPCODE-FLAGS" command
SHWSTP: $SAVE <P1> ;SAVE AN AC
$IACK (SHOW STOPCODE-FLAGS)
MOVX S1,%CNDBG ;DEBUG FLAGS WORD
GETTAB S1, ;ASK THE MONITOR
SETZ S1, ;DUH?
SHST.1: MOVE P1,S1 ;COPY FLAGS WORD TO A SAFE AC
$TEXT (WTORTN,<System will ^A>) ;START TEXT
TXC P1,ST%DCP!ST%DDC!ST%DJE ;FLIP THE BITS
TXNN P1,ST%DCP!ST%DDC!ST%DJE ;ALL BITS ON? (LEAVE FLIPPED)
JRST [$TEXT (WTORTN,<not do continuable stopcode dumps>)
JRST SHST.R] ;SEE ABOUT RELOADS
$TEXT (WTORTN,<do continuable dumps on ^A>) ;MORE NOISE
MOVEI S1,DMPBTS ;POINT AT TABLE
PUSHJ P,PRTBIT ;PRINT PRETTY BITS
$TEXT (WTORTN,< stopcodes>) ;ADD CRLF
SHST.R: $TEXT (WTORTN,<System will reload on ^A>) ;START TEXT
TXO P1,ST%NAR ;SET THE "STOP" BIT FOR PRTBIT
MOVEI S1,RLDBTS ;POINT AT TABLE
PUSHJ P,PRTBIT ;PRINT PRETTY BITS
$TEXT (WTORTN,< stopcodes>) ;ADD CRLF
$RETT
DMPBTS: $STAB
[ST%DCP],,[ASCIZ /CPU/]
[ST%DDC],,[ASCIZ /DEBUG/]
[ST%DJE],,[ASCIZ /JOB/]
$ETAB
RLDBTS: $STAB
[ST%CP1],,[ASCIZ /CPU/]
[ST%RDC],,[ASCIZ /DEBUG/]
[ST%RJE],,[ASCIZ /JOB/]
[ST%NAR],,[ASCIZ /STOP/] ;FAKE TO INCLUDE THIS
$ETAB
;ROUTINE TO HELP SHOW STOPCODE-FLAGS COMMAND PRINT PRETTY TEXT.
;COULD BE MADE MORE GENERAL IF THE NEED ARISES. CALL WITH THE
;CONTROL TABLE ADDRESS IN S1, AND THE BITS TO TEST IN P1. THIS
;ROUTINE WILL ADD COMMAS AND/OR "and" AS APPROPRIATE.
PRTBIT: $SAVE <P2,P3> ;SAVE AN AC OR TWO
MOVE P2,S1 ;COPY TABLE ADDRESS
HLLZ S1,(P2) ;GET LENGTH OF TABLE
MOVNS S1 ;MAKE IT -VE
HRRI S1,1(P2) ;POINT AT REAL ENTRIES
MOVE P2,S1 ;BACK WHERE ITS SAFE
;FIRST COUNT HOW MANY BITS ARE SET
SETZ P3, ;INIT COUNT OF BITS TO ZERO
MOVE T1,P2 ;COPY THE AOBJN POINTER
PBIT.1: HLRZ S1,(T1) ;GET A BIT ADDRESS
TDNE P1,(S1) ;BIT SET?
AOS P3 ;YES, COUNT IT
AOBJN T1,PBIT.1 ;LOOP
;NOW PRINT THE TEXT FOR EACH BIT WITH PROPER PUNCTUATION.
PUSH P,[0] ;INIT A FLAG
CAIL P3,3 ;3 OR MORE ITEMS?
SETOM (P) ;YES, REMEMBER THAT
PBIT.2: HLRZ S1,(P2) ;GET A BIT ADDRESS
TDNN P1,(S1) ;BIT SET?
JRST PBIT.4 ;NO
HRRZ S1,(P2) ;GET TEXT ADDRESS
$TEXT (WTORTN,<^T/0(S1)/^A>) ;ADD NAME
SUBI P3,1 ;ONE LESS ITEM LEFT
SKIPN (P) ;NEED ANY COMMAS?
JRST PBIT.3 ;NO
SKIPE P3 ;ANY MORE ITEMS?
$TEXT (WTORTN,<,^A>) ;YES, PRINT ","
CAILE P3,1 ;MORE THAN ONE ITEM LEFT?
$TEXT (WTORTN,< ^A>) ;YES, PRINT " "
PBIT.3: CAIN P3,1 ;ONE MORE ITEM LEFT?
$TEXT (WTORTN,< and ^A>) ;YES, NEED THE "and" NOW
PBIT.4: AOBJN P2,PBIT.2 ;DO ALL BITS
POP P,(P) ;TOSS JUNK
$RETT ;RETURN
SUBTTL KLINIK routines
;The SHOW KLINIK command
BYTMSK==377
KLISHW: $SAVE <P1,P2> ;Preserve AC
MOVE S1,[Z.KLIB,,Z.KLIB+1] ;Set up BLT
SETZM Z.KLIB ;Clear first word
BLT S1,Z.KLIE-1 ;Clear KLINIK data storage
PUSHJ P,P$CFM## ;Confirm this
$RETIF
PUSHJ P,SETCPU ;Set up CPU database
$IACK (KLINIK Status)
MOVSI P1,-6 ;For all CPUs
SETO P2, ;Flag for first time
KLIS.1: MOVSI S1,(CS.DWN!CS.NEX!CS.DET) ;Down, non-ex, or DET?
TDNE S1,CPUSTS(P1) ;??
JRST KLIS.X ;Yes, don't even try
AOSE P2 ;First time?
$TEXT (WTORTN,<>) ;No, add a blank line
HRLOM P1,T1 ;CPU,,Master DTE
MOVE T2,[XWD ^D16,KLIDTD] ;Point to string block
MOVE S1,[XWD .DTKPR,T1] ;Read parameters
MOVE S2,S1 ;Save original C(AC)
DTE. S1, ;Read current setting
JRST [PUSHJ P,KLIDTE ;Report error
HALT . ;Always skips
JRST KLIS.X] ;Go try next CPU
$TEXT (WTORTN,< -- CPU^O1/T1,LHMASK/ KLINIK Status -->)
MOVEI T4,KLIDTD ;Point to returned data
HRLI T4,(POINT 16,,) ;Thus
ILDB T1,T4 ;Get byte count
LDB T3,[POINT 16,KLIDTD+3,32];Console,,KLINIK
TRNE T3,BYTMSK ;Open?
JRST KLS.OW ;Yes
$TEXT (WTORTN,<Access window closed>)
JRST KLIS.X ;Output string
KLS.OW: $TEXT (WTORTN,<Access window open
Window opened on ^A>)
PUSHJ P,KLS.DT ;Type date
$TEXT (WTORTN,<^M^JWindow closes on ^A>)
PUSHJ P,KLS.DT ;Type date
$TEXT (WTORTN,<^M^JKLINIK mode: ^A>)
ILDB T1,T4 ;Fetch CSL,,KLINIK
MOVE T3,T1 ;Save CSL
ANDI T1,BYTMSK ;Get KLINIK
CAIN T1,BYTMSK ;USER mode?
JRST [$TEXT (WTORTN,<USER>)
JRST KLIS.X] ;Yes, done
MOVE T1,T3 ;Get CSL mode
LSH T1,-8 ;only CSL mode
IDIVI T1,3 ;Xlate (1,3,7) to (0,1,2)
$TEXT (WTORTN,<REMOTE Console mode: ^T/@MODTAB(T1)/>)
KLIS.X: AOBJN P1,KLIS.1 ;Next
$RETT
MODTAB: [ASCIZ .OPERATOR.]
[ASCIZ .PROGRAMMER.]
[ASCIZ .MAINTENANCE.]
KLS.DT: ILDB T1,T4 ;Fetch the time(sec/2)
PUSH P,T1 ;Save time
ILDB T1,T4 ;Get mon,,yr
ILDB T2,T4 ;Get 0,,day
MOVE T3,T1 ;Month,,yr
LSH T3,-8 ;Month
CAILE T3,^D12 ;Better be legal
SETZ T3, ;Glad we checked
$TEXT (WTORTN,<^D2R0/T2,BYTMSK/^T/MONTAB(T3)/-^D2R0/T1,BYTMSK/ at ^A>)
POP P,T1 ;Restore time
LSH T1,1 ;Make seconds
IDIVI T1,^D60 ;Min:sec
MOVE T3,T2 ;Sec
IDIVI T1,^D60 ;Hr:min
$TEXT (WTORTN,<^D2R0/T1/:^D2R0/T2/:^D2R0/T3/^A>)
POPJ P,
MONTAB: 0
ASCIZ .-Jan.
ASCIZ .-Feb.
ASCIZ .-Mar.
ASCIZ .-Apr.
ASCIZ .-May.
ASCIZ .-Jun.
ASCIZ .-Jul.
ASCIZ .-Aug.
ASCIZ .-Sep.
ASCIZ .-Oct.
ASCIZ .-Nov.
ASCIZ .-Dec.
;The SET KLINIK Command
KLINIK: $SAVE <P1> ;Save P1
MOVE S1,[Z.KLIB,,Z.KLIB+1] ;Set up BLT
SETZM Z.KLIB ;Clear first word
BLT S1,Z.KLIE-1 ;Clear KLINIK data storage
PUSHJ P,P$CFM## ;Try for a CRLF
JUMPT KLIN.1 ;Go default to "ALL-CPUS"
PUSHJ P,P$KEYW## ;Get a keyword instead
$RETIF ;Give up
SUBI S1,.ARCPU## ;Translate to CPU number
CAIL S1,0 ;Range
CAILE S1,6 ; Check
$RETF ;Loser
CAIN S1,6 ;"ALL-CPUS"?
MOVEI S1,7 ;Yes
HRLOM S1,KLICPU ;Save CPU number (DTE=MASTER)
PUSHJ P,P$CFM## ;Must have a CRLF now
$RETIF ;We don't
JRST KLIN.2 ;Onward
KLIN.1: MOVEI S1,7 ;All CPUs
HRLOM S1,KLICPU ;Save CPU number (DTE=MASTER)
KLIN.2: PUSHJ P,P$KEYW## ;Pick up a keyword
$RETIF ;Need one of these too
MOVNI P1,1 ;Init temp storage
CAIN S1,.KLOFF## ;Off?
MOVEI P1,0 ;Yes
CAIN S1,.KLREM## ;Remote?
MOVEI P1,1 ;Yes
CAIN S1,.KLUSR## ;User?
MOVEI P1,377 ;Yes
JUMPL P1,.RETF ;Give up if we're fed junk
DPB P1,[POINT 8,KLIDTD+3,31];Save KLINIK mode
PUSHJ P,P$CFM## ;Want a CRLF
$RETIF ;Didn't get one
JUMPE P1,KLIN.4 ;If SET KLINIK OFF, go do it now
CAIE P1,1 ;Remote?
JRST KLIN.3 ;No
PUSHJ P,P$SIXF## ;Get a sixbit quantity
$RETIF ;No such animal
SETZ T1, ;Keep track of where we are
MOVE S2,S1 ;Grab password
KLI.2A: JUMPE S2,KLI.2B ;If end, quit
SETZ S1, ;Clear junk
LSHC S1,6 ;Get next char
ADDI S1," "-' ' ;Make UC ASCII
DPB S1,[POINT 8,KLIDTD+4,15
POINT 8,KLIDTD+4,7
POINT 8,KLIDTD+4,31
POINT 8,KLIDTD+4,23
POINT 8,KLIDTD+5,15
POINT 8,KLIDTD+5,7](T1)
AOJA T1,KLI.2A ;Loop for all 6 chars of password
KLI.2B: PUSHJ P,P$CFM## ;Time for a CRLF
$RETIF ;OPR gave us garbage
KLIN.3: PUSHJ P,P$TIME## ;Get date-time
$RETIF ;Must have one of these
MOVE P2,S1 ;Save OPEN UDT
MOVE T4,[POINT 8,KLIDTD+0,15];Point to OPEN time
PUSHJ P,KLIN.T ;Convert and store
PUSHJ P,P$CFM## ;CRLF again
$RETIF ;Trashed.
PUSHJ P,P$TIME## ;Get date-time
$RETIF ;Not there
CAMG S1,P2 ;Closing beyond opening date-time?
$RETF ;Nope
MOVE T4,[POINT 8,KLIDTD+2] ;Point to CLOSE time
PUSHJ P,KLIN.T ;Convert and store
PUSHJ P,P$CFM## ;Get a CRLF
$RETIF ;Can't
CAIE P1,1 ;Remote?
JRST KLIN.4 ;No
PUSHJ P,P$KEYW## ;Get a keyword
$RETIF ;Must have one
MOVNI P1,1 ;Init temp storage
CAIN S1,.KLMNT## ;Console mode MAINTENANCE?
MOVEI P1,7 ;Yes
CAIN S1,.KLOPR## ;Console mode OPERATOR?
MOVEI P1,1 ;Yes
CAIN S1,.KLPRG## ;Console mode PROGRAMMER?
MOVEI P1,3 ;Yes
JUMPL P1,.RETF ;Have a known quantity?
DPB P1,[POINT 8,KLIDTD+3,23];Store for -20F
PUSHJ P,P$CFM## ;Parse a CRLF
$RETIF
KLIN.4: $IACK (SET KLINIK)
MOVE T1,KLICPU ;CPU#,,DTE#
MOVE T2,[XWD 26,KLIDTD] ;String len,,addr
MOVEI S1,24 ;Data length
DPB S1,[POINT 16,KLIDTD,15] ;Goes in arg block
HLRZ S1,T1 ;CPU#
CAIN S1,7 ;ALL?
JRST KLIN.A ;YES
MOVE S1,[XWD .DTKPS,T1] ;Set KLINIK
MOVE S2,S1 ;Keep a copy in case of error
DTE. S1, ;AHoooom
PUSHJ P,KLIDTE ;Report error
$TEXT (WTORTN,<CPU^O/T1,LHMASK/ SET KLINIK succeeded>)
$RETT ;Exit
KLIN.A: PUSHJ P,SETCPU ;See what's about
MOVSI P1,-6 ;TRY EACH CPU
KLIA.1: MOVSI S1,(CS.DWN!CS.NEX!CS.DET) ;Down, non-ex, or DET?
TDNE S1,CPUSTS(P1) ;??
JRST KLIA.2 ;Yes, don't even try
HRLM P1,T1 ;Try this CPU
MOVE S1,[XWD .DTKPS,T1] ;UUO pointer
MOVE S2,S1 ;Save in case of error
DTE. S1, ;AHoooom
PUSHJ P,KLIDTE ;Report error
$TEXT (WTORTN,<CPU^O/T1,LHMASK/ SET KLINIK succeeded>)
KLIA.2: AOBJN P1,KLIA.1 ;Next
$RETT ;Done
;DTE. UUO error handler
KLIDTE: PUSH P,T4 ;Save AC
HLRZ T4,S2 ;Get function that failed
CAIN T4,.DTKPR ;Read?
SKIPA T4,[SIXBIT /SHOW/] ;Yes
MOVE T4,[SIXBIT /SET/] ;No, must be a SET command
PUSH P,T4 ;Save command name for later
MOVSI T4,-ERRTBL ;Length of error table
CAMN S1,S2 ;No UUO?
JRST DTEERE ;If no UUO, no KLINIK
DTEERL: MOVS S2,ERRTAB(T4) ;Get error
CAIE S1,(S2) ;Match?
AOBJN T4,DTEERL ;No
DTEERE: HRRZ T4,ERRTAB(T4) ;Get ITEXT address
POP P,S2 ;Restore command that failed
$TEXT (WTORTN,<CPU^O/T1,LHMASK/ ^W/S2/ KLINIK failed>)
$TEXT (WTORTN,<DTE. UUO error - ^I/@T4,RHMASK/>)
POP P,T4
AOS (P)
POPJ P,
ERRTAB: XWD DTEUF%,[ITEXT <KLINIK functions not present>]
XWD DTEDC%,[ITEXT <CPU illegal or down>]
XWD DTEAP%,[ITEXT <Primary protocol not running>]
XWD DTENC%,[ITEXT <Inusfficient monitor free core>]
XWD DTEIB%,[ITEXT <CONFIG/Monitor version skew>]
ERRTBL==.-ERRTAB
XWD 0,[ITEXT <Unexpected DTE. error (^O/S1/)>]
KLIN.T: $CALL S%U2DT ;Get time and date
PUSH P,S2 ;Save date
ADDI S1,^D1K ;Round to nearest 2-sec clunk
IDIVI S1,^D2K ;And convert
ROT S1,-^D8 ;Get high byte first
IDPB S1,T4 ;Store
ROT S1,^D8 ;Now low byte
IDPB S1,T4 ;Finish time
MOVE S1,(P) ;Get date
IDIVI S1,^D31 ;Get days
AOJ S2, ;1-31
MOVEM S2,(P) ;Save daze
IDIVI S1,^D12 ;Get months
AOJ S2, ;1-12
IDPB S2,T4 ;Month comes next
ADDI S1,^D64 ;Year
IDPB S1,T4 ;Store year
SETZ S1, ;Required zero
IDPB S1,T4 ;Store that
POP P,S1 ;Day of month
IDPB S1,T4 ;Store that
POPJ P, ;Done
SUBTTL SHOW Command
C$SHOW: $CALL P$KEYW## ;Get the show keyword
$RETIF
MOVEI S2,SHODSP ;Get the address of the table
$CALL TABSRC## ;Find argument
$RETIF
JRST (S2) ;Dispatch to process argument
SUBTTL Some Random Subroutines -- DETJBS - Detach jobs lost from CPU
;SUBROUTINE TO DETACH JOBS WHOSE TERMINAL WILL BE LOST BY REMOVING A CPU
;CALL: S1 = CPU BEING REMOVED
DETJBS: $CALL .SAVE4 ;Get some save ACs
TLZ F,(FL.HEA) ;New heading required
MOVEI P4,1 ;Get a bit for CPU0
LSH P4,(S1) ;Set it for CPU being checked
GTTAB P1,%CNSJN ;Number of jobs in the system
MOVNI P1,-1(P1) ;Form AOBJN for jobs
HRLZS P1
MOVEI P2,2 ;Get the argblock lenght for RECON.
DETJ.1: HRRZ P3,P1 ;Get the job number to check
TRMNO. P3, ;Get its terminal number
JRST DETJ.3 ;ISN'T ANY, TRY NEXT
MOVE S2,P3 ;Save possible line number
DEVNAM P3, ;Get the SIXBIT terminal name
JRST DETJ.3 ;Shouldn't happen
MOVE S1,[XWD .RCCPU,P2] ;Get the argument pointer
RECON. S1, ;Get the CPU accessibility for terminal
JRST DETJ.3 ;Shouldn't happen
TRZN S1,P4 ;Accesible from us?
JRST DETJ.3 ;No, continue
JUMPN S1,DETJ.3 ;If others can access it, continue
ANDI S2,777 ;Isolate line number for job
HRLZS S2 ;In left half for detach
HRR S2,P1 ;Get the job number
ATTACH S2, ;DETACH THE JOB
JRST DETJ.3 ;Shouldn't happen
DETJ.2: TLON F,(FL.HEA) ;HEADING GIVEN
$TEXT (WTORTN,<% Detaching Jobs:>)
$TEXT (WTORTN,< ^D/P1/^A>)
DETJ.3: AOBJN P1,DETJ.1 ;CONTINUE FOR ALL JOBS IN THE SYSTEM
TLNE F,(FL.HEA) ;HAVE TO CLEAN UP
$TEXT (WTORTN,<>) ;Carriage return
$RETT
SUBTTL LSTDEV - Report any devices that will be lost
;CALL: S1 = CPU BEING REMOVED
LSTDEV: $SAVE <P1> ;Make room
MOVEI P1,1 ;Get a bit for CPU0
LSH P1,(S1) ;Move to the position CPU being checked
TLZ F,(FL.HEA) ;New heading for this loop
LSTD.0: SETO T1, ;Init DVPHY. arg block for all devices
SETZ T2, ;Start at first device
MOVEI T3,2 ;Init a place for RECON.
LSTD.1: MOVE S1,[XWD 2,T1] ;Get pointer to DVPHY. arg block
DVPHY. S1, ;Get a device name
JRST LSTD.0 ;Perhaps a network device disconnected
JUMPE T2,.RETT ;All done, return
MOVE T4,T2 ;Move to find CPU that owns it
MOVE S1,[XWD .RCCPU,P3] ;Get the pointer for a RECON.
RECON. S1, ;Get the mask of CPUs that own this
JRST RCNERR ;Strange
TDZN S1,P1 ;One of them the one we're looking for?
JRST LSTD.1 ;No, loop
JUMPN S1,LSTD.1 ;Continue if others can access it
MOVE S1,T4 ;Get the device name
DEVCHR S1, ;Get status bits
TXNN S1,<DV.ASC!DV.ASP> ;Is it inited or assigned?
JRST LSTD.1 ;No, loop
TXON F,FL.HEA ;Did we already print the header?
$TEXT (WTORTN,<The following active devices will be lost:>)
$TEXT (WTORTN,< ^W/T4/>)
JRST LSTD.1 ;AND LOOK AT ANOTHER DEVICE
SUBTTL Remove all disk kontrollers on a cpu
;CALL: S1 = CPU TO WORRY ABOUT (FL.WAC ALREADY ON)
RADKON: $SAVE <P1,P2,P3> ;Get scratch AC
MOVEI P3,1 ;Get a bit for CPU0
LSH P3,(S1) ;Make into a bit
MOVEI P1,2 ;Lenght of arg block for RECON.
SETZB P2,PHYNAM ;Indicate first call
RADK.1: MOVE S1,P2 ;Get previous kontroller address
PUSHJ P,NXTKON ;Find next disk kontroller
JUMPF RADK.E ;Strange
JUMPE S1,.POPJ ;Done with disk kontrollers
MOVE P2,S1 ;Save the address
MOVEM S1,DCHARG+.DCNAM ;Store name for DSKCHR
MOVE S2,[.DCMAX,,DCHARG] ;Argument for DSKCHR
DSKCHR S2, ;Get CPU this Kon is on
JRST RADK.E ;Shouldn't fail
LOAD S1,DCHARG+.DCXCH,DC.XCA ;Get CPU descriptors
TDZN S1,P3 ;Kon on this CPU?
JRST RADK.1 ;No, next Kon
JUMPN S1,RADK.1 ;Also go if Kon also on some other CPU
PUSHJ P,RADK.2 ;Remove or check the controller
JRST RADK.1 ;Loop for all
RADK.2: TXNE F,FL.CHK ;Checking or doing?
JRST DKONCM ;Checking
JRST DKONRM ;Removing
RADK.E: $TEXT (WTORTN,<Error trying to step through controllers - DSKCHR or SYSPHY error on unit ^W/S1/>)
$RETF
SUBTTL FNDKON - Find given controller name
;CALL: S1/ Controller name
;
;RTNS: TRUE S1/ First unit name on controller
; S2/ Alternate port name
FNDKON: $SAVE <P1> ;Make a scratch reg
HLLZ P1,S1 ;Get the controller name
FNDK.0: SETZ S1, ;Start at beginning of controller list
FNDK.1: PUSHJ P,NXTKON ;Get the next controller
JUMPF FNDK.E ;??
JUMPE S1,FNDK.N ;Non-exitent
CAME S2,P1 ;What we're looking for?
JRST FNDK.1 ;No, keep trying
$RETT ;Yes, return now
FNDK.E: $TEXT (WTORTN,<Error trying to find controller name - DSKCHR or SYSPHY error on unit ^W/S1/>)
$RETF
FNDK.N: $TEXT (WTORTN,<Non-existent controller ^W/P1/>)
$RETF
SUBTTL NXTKON - Step through the disk kontroller data blocks
;CALL: S1 = Previous unit or 0 for first time
;
;RTNS::S1 = SIXBIT name of unit
NXTKON: $SAVE <P1> ;Save a reg
HLLZ P1,S1 ;Save this controller
TXNN F,FL.ALT ;Already looking a alternate kontrollers?
MOVEM S1,PHYNAM ;Store for later
NXTK.1: MOVE S1,PHYNAM ;Get unit we're on
SYSPHY S1, ;Get the next kontroller on the system
$RETF ;??
MOVEM S1,PHYNAM ;Store for next time
JUMPE S1,NXTK.3 ;No more,,Go see if done
TXNN F,FL.ALT ;Looking for auxilliary?
JRST NXTK.2 ;No, go return this name
MOVEM S1,DCHARG+.DCNAM ;Store name for DSKCHR
MOVE S1,[.DCMAX,,DCHARG] ;Get the pointer to the arg list
DSKCHR S1, ;We're interested in the aux port
JRST FNDK.E ;Shouldn't happen
MOVEI S1,DCHARG+.DCALT ;Set to get second port name
TXNE F,FL.ADD ;Adding the controller?
MOVEI S1,DCHARG+.DCDET ;Yes, get detached port name
SKIPN S1,(S1) ;Get the alternate port name
JRST NXTK.1 ;None, so try for next
NXTK.2: HLLZ S2,S1 ;Get controller name
JUMPE P1,.RETT ;On the first one, return now
CAMN S2,P1 ;Same as what we have?
JRST NXTK.1 ;No, try the next
$RETT ;No, return it
NXTK.3: TXON F,FL.ALT ;Already checked alternate?
JRST NXTK.1 ;No, try it again now
TXZ F,FL.ALT ;Clear flag for next time
$RETT
SUBTTL NXTUNI - Return next unit on controller
;CALL: S1/ Kontroller name
;
;RTNS: TRUE S1/ Unit name
; S2/ Kontroller name
NXTUNI: $SAVE <P1> ;Get a scratch reg
TXNN F,FL.ALT ;Looking for alternate ports?
MOVEM S1,PHYUNI ;No, store kontroller in question
HLLZ P1,S1 ;Save the name to look for
NXTU.1: MOVE S1,PHYUNI ;Get the last name we wanted
SYSPHY S1, ;Get the next
JRST FNDK.E ;??
MOVEM S1,PHYUNI ;Store for next time
JUMPE S1,NXTU.3 ;All done, check aux port
TXNN F,FL.ALT ;Looking for auxilliary?
JRST NXTU.2 ;No, go return this name
MOVEM S1,DCHARG+.DCNAM ;Store name for DSKCHR
MOVE S1,[.DCMAX,,DCHARG] ;Get the pointer to the arg list
DSKCHR S1, ;We're interested in the aux port
JRST FNDK.E ;Shouldn't happen
MOVEI S1,DCHARG+.DCALT ;Set to get second port name
TXNE F,FL.ADD ;Adding the controller?
MOVEI S1,DCHARG+.DCDET ;Yes, get detached port name
SKIPN S1,(S1) ;Get the alternate port name
JRST NXTU.1 ;None, so try for next
NXTU.2: HLLZ S2,S1 ;Get controller name
CAME S2,P1 ;What we want?
JRST [SETZ S1, ;Not on this controller
$RETT] ;Return signifying that
$RETT ;Else return the names now
NXTU.3: TXNN F,FL.ALT ;Already checked alternate port
JRST NXTU.1 ;No, try it again now
$RETT
SUBTTL DKONCM - Check if disk controller may be removed
;CALL: P1 = 2 (FOR RECON. ARG COUNT)
; P2 = SIXBIT UNIT OR KONTROLLER NAME
; P3 = CPU BIT MASK # IF FL.WAC IS ON
;RTNS::FL.NCD ON IF CANNOT REMOVE THE KONTROLLER
DKONCM: $SAVE <P2> ;Callers want P2 preserved
MOVE S1,PHYNAM ;First unit on prime port
MOVEM S1,PHYUNI ;Where to start the search
MOVE S1,P2 ;First unit on kontroller
HLLZS P2 ;Kontroller name
MOVEM S1,DCHARG+.DCNAM ;Store for DSKCHR
JRST DKON.0 ;And go check if mounted
DKON.1: MOVE S1,DCHARG+.DCNAM ;Else, yes, get the first unit
PUSHJ P,NXTUNI ;Get the next
JUMPE S1,DKON.4 ;Zero means we're done
JUMPF RADK.E ;Strange error otherwise
MOVEM S1,DCHARG+.DCNAM ;Store the unit name for the DSKCHR
CAME S2,P2 ;Still on the one we want
JRST DKON.4 ;No, all done
DKON.0: MOVE S1,[XWD .DCMAX,DCHARG] ;Point to the argument block
DSKCHR S1, ;Get info about unit (just want STR)
JRST DKON.E ;Shouldn't happen
SKIPN T2,DCHARG+.DCSNM ;Get name of structure mounted
JRST DKON.1 ;Ok to remove unit if nothing spinning
MOVEI T1,2 ;Get lenght of arg block for RECON.
MOVE S1,[.RCCPU,,T1] ;Get the pointer to args
RECON. S1, ;Get CPU mask for acceptabity
JRST RCNERR
TDZE S1,P3 ;Is it on CPU being tested?
JUMPE S1,DKON.2 ;Yes, don't remove if only port
TLNE F,(FL.WAC) ;Worrying about removing a cpu
TDNE S1,CPURUN ;Are any other CPUs running?
JRST DKON.1 ;Yes, ok to remove it then
DKON.2: TLNE F,(FL.ADD) ;Adding?
JRST DKON.1 ;Yes, loop
TLON F,(FL.NCD!FL.HEA) ;Already give header, and flag error
$TEXT (WTORTN,<Following structures must be dismounted:>)
$TEXT (WTORTN,< ^W/DCHARG+.DCSNM/ on ^W/DCHARG+.DCNAM/>)
JRST DKON.1 ;Loop for all units
DKON.4: TLNE F,(FL.NCD!FL.CHK) ;Ok to really remove the units
$RETT ;No, return now
MOVE P2,-1(P) ;Restore first unit on controller
JRST DKOR.0 ;Go remove
SUBTTL DKONRM -- Add/Remove disk controller
DKONRM: $SAVE <P2> ;Callers want P2 to return intact
DKOR.0: MOVE S1,PHYNAM ;First unit on prime port
MOVEM S1,PHYUNI ;Where to start the search
MOVE S1,P2 ;First unit on kontroller
HLLZS P2 ;Kontroller name
MOVEM S1,DCHARG+.DCNAM ;Store for DSKCHR
JRST DKOR.4 ;And go check if mounted
DKOR.1: MOVE S1,DCHARG+.DCNAM ;Else, yes, get the first unit
PUSHJ P,NXTUNI ;Get the next
JUMPF RADK.E ;Strange error otherwise
JUMPE S1,.RETT ;Zero means we're done
MOVEM S1,DCHARG+.DCNAM ;Store the unit name for the DSKCHR
CAME S2,P2 ;Still on the one we want
JRST .RETT ;No, all done
DKOR.4: MOVE S1,[XWD .DCMAX,DCHARG] ;Point to the argument block
DSKCHR S1, ;Get info about unit (just want STR)
JRST DKON.E ;Shouldn't happen
LOAD S2,S1,DC.STS ;Get the status of the unit
TLNN F,(FL.ADD) ;Add or remove command
JRST DKOR.8 ;Remove
CAIE S2,.DCSTD ;Is the unit down
JRST DKOR.1 ;No, already usable
MOVE S1,[XWD .RCATT,T1] ;Add function
SKIPN T1,DCHARG+.DCDET ;Alternate port?
JRST DKOR.6 ;Go attach the unit
MOVEM T1,PHYNAM ;Yes, after the attach is done, won't
MOVEM T1,PHYUNI ; be able to find this unit in SYSPHY
TXO F,FL.ALT ; chain
JRST DKOR.6 ;Now go attach the unit
DKOR.8: CAIN S2,.DCSTD ;Is unit already detached
JRST DKOR.1 ;Yes, don't do it again
TXNE S1,DC.ALT ;This dual ported?
TXNN F,FL.WAC ;Removing a cpu?
JRST DKOR.5 ;No, don't report anything
MOVEI T1,2 ;Get lenght of arg block for RECON.
MOVE T2,DCHARG+.DCNAM ;Get the name of the unit
MOVE S1,[.RCCPU,,T1] ;Get the pointer to args
RECON. S1, ;Get CPU mask for acceptabity
JRST RCNERR ; ??
TDNN S1,P1 ;Unit on the CPU being removed
JRST DKOR.5 ;No, nothing to report
TLON F,(FL.HEA) ;Printed the header yet?
$TEXT (WTORTN,<%Following drive(s) are dual ported with the CPU being removed:>)
$TEXT (WTORTN,< ^W/DCHARG+.DCNAM/>)
DKOR.5: MOVE S1,[XWD .RCDET,T1] ;Remove function
DKOR.6: MOVEI T1,2 ;Lenght of arg block
MOVE T2,DCHARG+.DCNAM ;Get unit to attach/detach
RECON. S1, ;Do the function
PUSHJ P,RCNERR ;??
JRST DKOR.1 ;Loop for all units
DKON.E: $TEXT (WTORTN,<Error trying to get structure name mounted on drive ^W/DCHARG+.DCSNM/>)
$RETF
SUBTTL Subroutine to set up CPU status table
SETCPU: $SAVE <P1> ;Get a safe AC
MOVE S1,[.STCPU,,SP.CR0!SP.CR1!SP.CR2!SP.CR3!SP.CR4!SP.CR5]
SETUUO S1, ;Set this job to run anywhere
JFCL ;Ok, must be a single processor
SETZM CPUN ;Clear count of running cpus
SETZM CPUOK ;Clear count of cpus with ok words counting
SETZM CPURUN ;And mask for running ones
MOVSI S1,-6 ;Max cpus
SETC.1: MOVSI S2,(S1) ;Cpun to lh
LSH S2,1 ;*2 for gettab
ADD S2,[%CCPTR&777777,,.GTSLF]
GETTAB S2, ;Get base of cdb constants = cdb address
$STOP(CDB,<Can't determine CDB base address for CPU^D/S1,RHMASK/>)
TLNN S2,(SL.MAX) ;Is max for gettab = 0
JRST [MOVSI S2,(CS.DWN!CS.NEX) ;Yes, mark it non-existant
JRST SETC.2] ;And store data
MOVEI P1,(S1) ;Copy cpu number
LSH P1,1 ;*2 for gettab
ADD P1,[%CVRUN] ;Get .CPRUN
GETTAB P1, ;Get it
$STOP(CDS,<Can't determine run status for CPU^D/S1,RHMASK/>)
TLNE P1,(CV%DET) ;Is it detached
JRST [HRLI S2,(CS.DWN!CS.DET) ;Yes, mark it
JRST SETC.2] ;Store data
TLNE P1,(CV%RMV) ;Is cpu already stopped
JRST [HRLI S2,(CS.DWN) ;Yes, mark it down
JRST SETC.2] ;Store data
TLZ S2,-1 ;CPU is up, clear status bits
AOS CPUN ;Count a running CPU
GTTAB P1,%CNBCP ;Find the boot cpu
CAIN P1,(S1) ;This it
TLO S2,(CS.BOT) ;Yes, remember that
MOVEI P1,1B35 ;Get a bit for cpu0
LSH P1,(S1) ;Position it correctly
IORM P1,CPURUN ;Light a running cpu bit
MOVEI P1,(S1) ;Copy cpu number
LSH P1,1 ;*2 for gettab
ADD P1,[%CCOKP] ;Get the ok word
GETTAB P1, ;Get it
$STOP(CDU,<Can't determine up status for CPU^D/S1,RHMASK/>)
SKIPG P1 ;Is the cpu really running
AOSA CPUOK ;Yes, count the cpu
TLO S2,(CS.NOK) ;No, remember this one isn't
SETC.2: MOVEM S2,CPUSTS(S1) ;Update status
AOBJN S1,SETC.1 ;And try another cpu
$RETT ;Return
SUBTTL CPUSRC - CPU-driven table searching
CPUSRC: HLLZ T1,(S2) ;GET THE NUMBER OF ENTRIES
MOVN T1,T1 ;MAKE IT NEGATIVE
HRRI T1,1(S2) ;ADDRESS OF THE TABLE
CPUS.1: HLRZ T2,(T1) ;MINIMUM OFFSET IS CPU0
MOVEI T3,6(T2) ;MAXIMUM OFFSET IS CPU5 + 1 (ALL CPUS)
CAIL S1,(T2) ;RANGE
CAILE S1,(T3) ; CHECK
SKIPA ;NO MATCH
JRST CPUS.2 ;YES..
AOBJN T1,CPUS.1 ;TRY NEXT ONE
$RETF ;ERROR..RETURN
CPUS.2: HRRZ S2,(T1) ;GET THE DATA
$RETT ;RETURN TRUE
SUBTTL GETADR - Input an address from a token
; This routine will return a number based on the string a user types.
;If the string begins with a # character, the number will be assumed
;octal else it will be decimal, if the number is followed by a "P"
;then it will be assumed to mean page number, else it will be in units
;if 1024 words.
GETADR: $SAVE <P1,P2,P3> ;Make some room
MOVEI P3,^D10 ;Assume decimal radix
$CALL P$TOK## ;See if he specified octal
SKIPF ;Didn't see if number
MOVEI P3,^O10 ;He did, get real radix
GETAD1: PUSHJ P,P$FLD## ;Get the next token
JUMPF GETA.6 ; ??
MOVEI P1,1(S1) ;Save the string address
MOVE S2,P1 ;Make a working copy
HRLI S2,(POINT 7,) ;Make it a byte pointer
SETO P2, ;Clear the place for the number
GETA.1: ILDB S1,S2 ;Get the next character
CAIL S1,"0" ;Numeric?
CAILE S1,"9" ; . . .
JRST GETA.3 ;No, go see if done
SKIPGE P2 ;First time through?
SETZ P2, ;Yes, start with a null
IMUL P2,P3 ;Shift current total by radix
ADDI P2,-"0"(S1) ;Add this character into it
JRST GETA.1 ;Loop for all
;When we get here, we have a number in P2 which will default to
;representing pages. We'll see if we have to convert it to kilo-words.
GETA.3: JUMPE S1,GETA.8 ;All done?
CAIE S1,"K" ;No, did he specify kilo?
CAIN S1,"k" ;Both ways
TRNA ;Yes
JRST GETA30 ;No, try for pages
LSH P2,1 ;Convert to right number of pages
JRST GETA.9 ;Go return the value
GETA30: CAIE S1,"P" ;Did he specify pages
CAIN S1,"p" ; . . .
JRST GETA.9 ;All set, go return the number
JRST GETA40 ;Illegal format
GETA.4: ILDB S1,S2 ;Make sure he didn't type more
JUMPE S1,GETA.5 ;If he didn't, go finish up
GETA40: $TEXT (WTORTN,<Illegally formatted address>)
$RETF ;Return bad
GETA.5: JUMPGE P2,.RETT ;Did he type any digits?
$TEXT (WTORTN,<Illegal address specified - at least one digit must be specified>)
$RETF
GETA.6: $TEXT (WTORTN,<Error parsing address field>)
$RETF
;Here with a number of words.
GETA.8: ADR2PG P2 ;Convert to pages
GETA.9: MOVE S1,P2 ;Get the number to be returned
$RETT ;Return it
SUBTTL SNDALL - Routine to send a message to all terminals
SNDALL: $SAVE <S2+1> ;Save possible data reg
PUSHJ P,SEND.1 ;Send the message
MOVEI S1,[BYTE (7).CHCRT,.CHLFD] ;Append a CRLF to it
SEND.1: MOVE S2+1,S1 ;Point to text
MOVX S1,.TOTYP ;TRMOP. to stuff text down TTY's throat
MOVE S2,FRCLIN## ;Send text to FRCLIN
MOVX TF,<3,,S1> ;Set up for CALLI
TRMOP. TF, ;Do SEND ALL command
$RETF ;Can't
$RETT ;Return sucessful
SUBTTL CTYTYP - Type messages on the CTY
CTYTYP: SKIPN CTYBLK+1 ;Did we already set-up TRMOP. block
PUSHJ P,SETCTY ;No, do so now
MOVEM S1,CTYBLK+2 ;Store the character
MOVE S1,[3,,CTYBLK] ;Point to the argument block
TRMOP. S1, ;Type the character
$STOP(CTC,<Can't type to CTY>)
$RETT
SETCTY: MOVSI S2,'CTY' ;Get the name of the CTY
IONDX. S2, ;And get it's UDX
$STOP (CGU,<Can't get universal device index of CTY>)
MOVEM S2,CTYBLK+1 ;Store it
MOVEI S2,.TOOUC ;Get the output a character functionn
MOVEM S2,CTYBLK ;Store it
$RET
SUBTTL Error subroutines
RCNERR: $TEXT (WTORTN,<RECON. UUO error (^O/S1/)^A >)
CAIL S1,RCNETL ;Error number in range?
MOVEI S1,RCNETL ;No, something really wrong
$TEXT (WTORTN,< ^T/@RCNETX(S1)/>)
JRST ERRXIT ;Join common error exit
DIAERR: $TEXT (WTORTN,<DIAG. UUO error (^O/S1/)^A >)
CAIL S1,DIAETL ;Error number in range?
MOVEI S1,DIAETL ;No, something really wrong
$TEXT (WTORTN,< ^T/@DIAETX(S1)/>)
ERRXIT: MOVE S1,[EXP MF.FAT!<INSVL.(<'CNF'>,MF.SUF)>] ;Get error flags
MOVEM S1,G$APFG## ;Set them for typeout
$RETF
RCNETX: [ASCIZ /No such error code/]
[ASCIZ /Illegal argument list/]
[ASCIZ /Not privileged/]
[ASCIZ /Timesharing has already stopped on some CPU/]
[ASCIZ /Illegal job number/]
[ASCIZ /System cannot be snapshotted/]
[ASCIZ /Address check/]
[ASCIZ /Illegal string/]
[ASCIZ /Illegal CPU number/]
[ASCIZ /CPU still running/]
[ASCIZ /Can't attach disk/]
[ASCIZ /Device is spooled/]
[ASCIZ /Device is already attached/]
[ASCIZ /Illegal device/]
[ASCIZ /Device in use/]
[ASCIZ /Can not detach disk/]
[ASCIZ /LOKCON not loaded (can't set memory off-line)/]
[ASCIZ /Removing monitor memory/]
[ASCIZ /Job(s) too big/]
[ASCIZ /Moving locked job(s)/]
RCNETL==.-RCNETX
[ASCIZ |Unknown error code|]
DIAETX: [ASCIZ /No such error code/]
[ASCIZ /Not privileged/]
[ASCIZ /Illegal number of arguments/]
[ASCIZ /Illegal controller/]
[ASCIZ /Illegal unit/]
[ASCIZ /Some units already assigned/]
[ASCIZ /Unit not in diagnostic mode/]
[ASCIZ /Unit assigned to another job/]
[ASCIZ /No free core/]
[ASCIZ /No assigned units/]
[ASCIZ \I/O word crosses a page boundary\]
[ASCIZ /Illegal function/]
[ASCIZ /Job can't be virtual/]
[ASCIZ /No such CPU/]
[ASCIZ /CPU not running/]
[ASCIZ /Bad argument list/]
[ASCIZ /No CI port on CPU/]
[ASCIZ /Read CI port counters timed out/]
[ASCIZ /No NI port on CPU/]
[ASCIZ /Microcode reload failed/]
[ASCIZ /Microcode not available/]
DIAETL==.-DIAETX
[ASCIZ /Unknown error code/]
SUBTTL End of CNFORN
END