Trailing-Edge
-
PDP-10 Archives
-
cuspjul86upd_bb-jf24a-bb
-
10,7/galaxy/operat/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/JAD 23-Apr-86
;
;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==22 ;EDIT LEVEL
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
20 Fix boot text to set the arguement count correctly.
28-Feb-86 GCO 10385 /NT
21 Rewrite lots of CNFORN so it is more maintainable. Call a
new routine in CNFTAB to build a database of disk units, and
use that when twiddling with the disks.
11-Apr-86 GCO 10396 /JAD
22 Edit 20 did not work for all cases.
6-May-86 GC0 10404 /NT
\
SUBTTL Macros and other stuff
F==.A13 ;Dedicated flag AC
FL.ADD==1B0 ;Various bit flags
FL.NO==1B1
FL.DMN==1B2
FL.HEA==1B3
FL.NCD==1B4
FL.WAC==1B5
;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>,<JSP TF,GTBERR>
IFNB <DEFAULT>,<MOVE AC,[DEFAULT]>
LIST
SALL
>
;The routines to set up the disk database live in CNFTAB since
;they are needed by OPR as well as ORION. Definitions for the
;entries are duplicated here to catch skews.
;Each entry in the database has the following form:
.DDNAM==:0 ;NAME
.DDSTS==:1 ;DSKCHR UUO STATUS WORD
.DDSNM==:2 ;STRUCTURE UNIT BELONGS TO
.DDALT==:3 ;ALTERNATE PORT FOR THIS UNT
.DDXCH==:4 ;EXTENDED CHARACTERISTICS
.DDLEN==:5 ;LENGTH OF ENTRY
;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
SYSSIZ: BLOCK 1 ;SIZE OF THE MONITOR
NWCORE: BLOCK 1 ;NUMBER OF WORDS OF MEMORY ON THE SYSTEM
JOBPTR: BLOCK 1 ;AOBJN POINTER TO ALL JOBS
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
ADDREM: BLOCK 1 ;ADDRESS OF "ADD" OR "REMOVE" TEXT
TXTPTR: BLOCK 1 ;BYTE POINTER TO DEPOSIT MESSAGE CHARACTERS
; 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 Tables
;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
CNFDSX::BLOCK 1 ;For stand-alone CONFIG
CNFDSL==:CNFDSX-CNFDSP ;Ditto
;ADD/REMOVE commands
ADDDSP: $STAB
.ARMEM##,,ADDMEM ;Memory
$ETAB
ADDCPX: $STAB
.ARCPU##,,ADDCPU ;CPU
.ARCI##,,ADDCI ;CI
.ARNI##,,ADDNI ;NI
$ETAB
;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
;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
;SHOW commands
SHODSP: $STAB
.SHKLI##,,KLISHW ;SHOW KLINIK
.SHSTP##,,SHWSTP ;SHOW STOPCODE-FLAGS
$ETAB
;CPU names table
DEFINE CPUNMS(NUMBER)<IRP <NUMBER>,<SIXBIT |CPU'NUMBER|>>
CPUNAM: CPUNMS<0,1,2,3,4,5>
;CPU bits
CPUBIT: EXP 1,2,4,10,20,40 ;BIT FOR CPUN
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,%CNSJN ;Get -#segments,,#jobs
MOVNI S1,-1(S1) ;Make it negative and skip null job
HRLI S1,1 ;Start at job 1
MOVSM S1,JOBPTR ;Save for DETJBS
SETOM INIDON ;Remember we've come through here
CNF.1: $CALL SETCPU ;Set up CPU database
$CALL SETDSK## ;Set up disk database
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: TXZA F,FL.ADD ;Clear the adding flag
C$ADD: TXO F,FL.ADD ;Set flag to add
MOVEI S1,[ASCIZ |ADD|] ;Assume ADD command
TXNN 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
JRST RATKON ;Must be magtape
$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
RATKON: $IACK (^T/@ADDREM/ magtape controller doesn't work yet)
$RETF ;Not yet
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
TXNN 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
TXNN 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> ;Make room
HRLZS P1,S1 ;Save controller name, move to LH
MOVEM S1,DCHARG+.DCNAM ;Set up for DSKCHR
MOVE S1,[.DCMAX,,DCHARG] ;Point at DSKCHR argument list
DSKCHR S1, ;Get info
JRST AKON.2 ;Gulp?
LOAD S1,DCHARG+.DCXCH,DC.XCA ;Get CPU mask
TDNE S1,CPURUN ;Any of the CPUs up?
JRST AKON.1 ;Yes, remove kontroller and return
$TEXT (WTORTN,<CPU owning controller ^W/P1/ is down>)
$RETF ;END MESSAGE AND RETURN
AKON.1: MOVE S1,P1 ;Copy controller name
TXNN F,FL.ADD ;Removing a controller?
PUSHJ P,CRDKON ;Yes, must check first
TXNE F,FL.NCD ;Can we do it?
JRST AKON.2 ;Nope
MOVE S1,P1 ;Copy controller name
PUSHJ P,RADKON ;Remove the controller
MOVEI S1,[ITEXT (added)]
TXNN F,FL.ADD ;Removing?
MOVEI S1,[ITEXT (removed)]
$TEXT (WTORTN,<Controller ^W/P1/ ^I/(S1)/>)
$RETT ;Done
AKON.2: MOVEI S1,[ITEXT (added)]
TXNN F,FL.ADD ;Removing?
MOVEI S1,[ITEXT (removed)]
$TEXT (WTORTN,<Controller ^W/P1/ can't be ^I/(S1)/>)
$RETF ;Croak 'em
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
$IACK (^T/@ADDREM/ CPU)
MOVSI S1,(CS.NEX) ;NON-EXISTANT BIT
TDNN S1,CPUSTS(P1) ;IN RANGE, IS IT REAL
JRST ADDCP1 ;Yep try to do it
$TEXT (WTORTN,<Illegal CPU specified - CPU^O/P1/ does not exist>)
$RETF
ADDCP1: TXNE F,FL.ADD ;Adding?
JRST A%CPU ;Go to that routine
; JRST R%CPU ;Remove CPU
;HERE TO REMOVE A CPU
.CREF CS.DWN ;BIT WE'RE TESTING
R%CPU: SKIPL CPUSTS(P1) ;CPU ALREADY DOWN
JRST RCPU.1 ;NO
$TEXT (WTORTN,<CPU^D/P1/ is already removed>)
$RETT ;YES, JUST RETURN NOW
RCPU.1: MOVE S1,CPUN ;GET NUMBER OF RUNNING CPUS
CAIE S1,1 ;TRYING TO REMOVE THE LAST REMAINING CPU
JRST RCPU.2 ;NO, ONWARD
$TEXT (WTORTN,<Use SHUTDOWN to remove last CPU>)
$RETF ;END OUTPUT AND RETURN
RCPU.2: MOVE S1,CPUOK ;NUMBER OF ACTUALLY RUNNING CPUS
CAIE S1,1 ;ONLY ONE OF THOSE LEFT
JRST RCPU.3 ;NO
MOVSI S1,(CS.NOK) ;YES, CHECK IF CPU NOT RUNNING ANYWAY
TDNE S1,CPUSTS(P1) ;WELL?
JRST RCPU.3 ;CPU IS DEAD, OK TO REMOVE IT
$TEXT (WTORTN,<No running CPUs would be left>)
$RETF ;IF OPERATOR REALLY WANTS THIS, USE "SHUT"
RCPU.3: $CALL P$SWITCH## ;See if he typed the force switch
JUMPF RCPU.4 ;No, check before doing
HLRZ S1,0(S1) ;Get switch keyword
CAIN S1,.ARFRC## ;Force switch?
JRST RCPU.5 ;Yes, so bypass
$RETF ;COMMAND ERROR
RCPU.4: TXO F,FL.WAC ;SET "WORRY ABOUT CPU"
SETZ S1, ;CHECK ALL CONTROLLERS
MOVE S2,CPUBIT(P1) ;GET BIT FOR THE CPU
PUSHJ P,CRDKON ;CHECK DISK CONTROLLERS
TXNE F,FL.NCD ;DID SOME CHECK FAIL
JRST RCPU.E ;GENERIC ERROR MESSAGE
MOVE S1,P1 ;Get the CPU number
PUSHJ P,LSTDEV ;LOOK FOR LOST DEVICES, GIVE WARNING
MOVE S1,P1 ;Get the CPU we're removing
PUSHJ P,DETJBS ;DETACH JOBS AS APPROPRIATE
TRNA ;WE HAVE DONE CHECKS
RCPU.5: $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
TLON S1,(CS.NOK) ;WAS CPU'S OK WORD COUNTING BEFORE
SOS CPUOK ;YES, BUT IT WILL STOP SOON
MOVEM S1,CPUSTS(P1) ;LIGHT THE BIT NOW
MOVE S1,CPUBIT(P1) ;GET BIT FOR CPU BEING REMOVED
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/P1/ runnability failed>)
MOVSI T1,(CS.NOK) ;IS CPU'S OK WORD COUNTING?
TDNE T1,CPUSTS(P1)
JRST RCPU.7 ;NO, AVOID LOOP, SHUT DOWN IF ALREADY DEAD
RCPU.6: 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,RCPU.6 ;WAIT FOR CPU TO ONLY RUN NULL JOB
SETZ S1, ;REMOVE ALL CONTROLLERS
MOVE S2,CPUBIT(P1) ;BIT FOR THE CPU BEING REMOVED
TXNN F,FL.DMN ;DON'T DETACH IF FORCED REMOVAL
PUSHJ P,RADKON ;GO AND DETACH ALL THE UNITS NOW
RCPU.7: 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/>)
RCPU.8: 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,RCPU.8 ;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 RCPU.9 ;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
RCPU.9: MOVSI S1,(CS.DET) ;"CPU DETACHED" BIT
TDNE S1,CPUSTS(P1) ;IS THE CPU ALREADY DETACHED
JRST RCPU.0 ;YES, ACK 'EM AND RETURN
IORM S1,CPUSTS(P1) ;SAY DETACHED NOW
MOVEI S1,2 ;Get the lenght of the arge block
MOVE S2,CPUNAM(P1) ;And get the SIXBIT CPU name
DMOVEM S1,RCNARG ;SAVE ARGUMENTS
PUSHJ P,ATTDET ;Do the UUO
JUMPF RCPU.E ;If error
RCPU.0: $TEXT (WTORTN,<CPU^D/P1/ removed>)
$RETT
RCPU.E: $TEXT (WTORTN,<CPU^D/P1/ can't be removed>)
$RETF ;ERROR
;HERE TO ADD A CPU
.CREF CS.DWN ;BIT WE'RE TESTING
A%CPU: SKIPL CPUSTS(P1) ;IS IT ALREADY UP
JRST ACPU.2 ;YES, GO LET IT IN
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 ACPU.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
PUSHJ P,ATTDET ;DO THE UUO
$RETIF ;QUIT WHILE WE'RE AHEAD?
ACPU.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/P1/ to up status>)
ACPU.2: MOVE S1,CPUBIT(P1) ;GET A BIT FOR CPU BEING ADDED
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>)
$TEXT (WTORTN,<CPU^D/P1/ added>) ;ACK 'EM
$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
TXNE 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
TXNE 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
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
TXNE 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
TXNE 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
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
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
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
PUSHJ P,RCNERR ;REPORT RECON. UUO ERROR
MOVSI T1,-6 ;NUMBER OF CPUS
.CREF CS.DWN ;BIT WE'RE TESTING
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 suspend CPU^D/T1,RHMASK/>)
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
PUSHJ P,RCNERR ;REPORT RECON. UUO ERROR
MOVSI 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
PUSHJ P,RCNERR ;REPORT RECON. UUO ERROR
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
$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)
TXZ F,FL.ADD ;SET TO SEIZE MAGTAPE CONTROLLERS
PUSHJ P,SEZMTK ;DO IT
JUMPF RCNERR ;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 AUTO.M ;PROBABLY NOT PRIVLEGED
MOVSI S1,.RCIOW ;Get wait for I/O to finish function
RECON. S1, ;Wait
PUSHJ P,RCNERR ;REPORT RECON. UUO ERROR
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.1 ;Done, continue onward
PUSHJ P,RCNERR ;PRINT RECON. UUO ERROR MESSAGE
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
AUTO.M: TXO F,FL.ADD ;ALSO FREE UP MAGTAPES
PUSHJ P,SEZMTK ;RELEASE MTA KONTROLLERS
$RETT ;FINISH THE LINE AND EXIT
AUTO.1: 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
TXO F,FL.ADD!FL.WAC ;WANT TO ADD CONTROLLERS
PUSHJ P,SEZMTK ;FREE UP MAGTAPE KONTROLLERS
MOVSI P1,-6 ;NUMBER OF CPUS
.CREF CS.DWN ;BIT WE'RE TESTING
AUTO.2: SKIPGE CPUSTS(P1) ;CPU UP?
JRST AUTO.3 ;NO, DON'T WORRY ABOUT IT
SETZ S1, ;ALL CONTROLLERS
MOVE S2,CPUBIT(P1) ;BIT FOR CPU BEING ADDED
PUSHJ P,RADKON ;ADD ALL DISK CONTROLLERS
AUTO.3: AOBJN P1,AUTO.2 ;DO IT FOR ALL CPUS
$RETT ;ALL DONE, SO JUST EXIT
;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
SEZMTK: $SAVE <P1,P2> ;Get some save acs
MOVE S1,[-2,,P1] ;DIAG. ARGUMENT LIST
MOVEI P1,.DIARM ;ASSUME RELEASING MAGTAPE KONTROLLERS
TXNN 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: TXO 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
TXNE F,FL.NO ;NO?
MOVEI S2,[ASCIZ /disabled/] ;DISABLE
HRRI T1,.DIELD ;ASSUME ENABLE
TXNE 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
TXNE 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,1(T2) ;INCLUDE NULL IN COUNT, MOVE TO P1
IDIVI S1,5 ;COMPUTE WORD COUNT
SKIPE S2 ;Any chars left over?
ADDI S1,1 ;Yes, account for them also
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
TXNN 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
TXNE 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
$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: 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
TXZ F,FL.HEA ;New heading required
MOVE P4,CPUBIT(S1) ;Get bit for CPU being checked
MOVE P1,JOBPTR ;Get AOBJN for jobs
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
TDZN 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: TXON 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
TXNE 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
MOVE P1,CPUBIT(S1) ;Get a bit for CPU being checked
TXZ 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,T3] ;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 Check if Disk Controller May be Removed
;Routine to check if a disk controller may be removed.
;Call:
; S1/ Controller name (zero if ALL controllers)
; S2/ Bit for CPU being removed if FL.WAC set
; PUSHJ P,CRDKON
;Returns:
; FL.NCD set if can't remove (warnings printed)
; FL.NCD clear if OK to remove
;Note: S2 only needs to be set up when removing a CPU, i.e., when
;FL.WAC is set. In this case, S1 should contains zero.
CRDKON: $SAVE <P1,P2> ;SAVE AN AC OR TWO
SKIPN S1 ;CONTROLLER NAME ZERO?
TXNE F,FL.WAC ;YES, THIS IS THE ONLY LEGAL CASE
SKIPA ;OK
$STOP (BAR,<Bad arguments to CRDKON>)
DMOVE P1,S1 ;COPY ARGUMENTS
TXZ F,FL.NCD!FL.HEA ;ASSUME IT WILL WORK
MOVE S1,DSKLST## ;GET LIST HANDLE FOR DISK DATABASE
$CALL L%FIRST ;POSITION TO FIRST ENTRY
CRDK.1: JUMPF .RETT ;RETURN WHEN HIT END OF LIST
JUMPE P1,CRDK.2 ;SKIP NAME CHECK IF ALL CONTROLLERS ACCEPTABLE
HLLZ S1,.DDNAM(S2) ;GET CONTROLLER NAME
CAME S1,P1 ;MATCH?
JRST CRDK.4 ;NO
CRDK.2: SKIPE .DDSNM(S2) ;A STRUCTURE MOUNTED?
SKIPE .DDALT(S2) ;YES, NO ALTERNATE PORT?
JRST CRDK.4 ;NO, NO BIG DEAL
TXNN F,FL.WAC ;REMOVING A CPU?
JRST CRDK.3 ;NO
LOAD S1,.DDXCH(S2),DC.XCA ;GET MASK OF ACCESSIBLE CPUS
TDZN S1,P2 ;CLEAR BITS FOR THIS CPU
JRST CRDK.4 ;CONTROLLER ISN'T ON CPU BEING REMOVED
JUMPN S1,CRDK.4 ;OK IF STILL ACCESSIBLE VIA OTHER CPUS
CRDK.3: TXON F,FL.NCD!FL.HEA ;SET THE BITS, IS IT THE FIRST TIME?
$TEXT (WTORTN,<The following structures must be dismounted:>)
$TEXT (WTORTN,< ^W/.DDSNM(S2)/ on unit ^W/.DDNAM(S2)/>)
CRDK.4: MOVE S1,DSKLST## ;GET LIST HANDLE
$CALL L%NEXT ;POSITION TO NEXT ENTRY
JRST CRDK.1 ;SEE IF OTHERS
SUBTTL Add/Remove Disk Controller
;Routine to add or remove a disk controller.
;Call:
; F/ FL.ADD set if add, FL.ADD clear if remove
; S1/ Controller name (zero if ALL controllers)
; S2/ Bit for CPU being removed if FL.WAC set
; PUSHJ P,RADKON
;Return:
; TRUE always
RADKON: $SAVE <P1,P2> ;SAVE AN AC OR TWO
DMOVE P1,S1 ;COPY ARGUMENTS
TXZ F,FL.HEA ;CLEAR HEADER PRINTED FLAG
MOVE S1,DSKLST## ;GET LIST HANDLE FOR DISK DATABASE
$CALL L%FIRST ;POSITION TO FIRST ENTRY
RADK.1: JUMPF .RETT ;RETURN WHEN HIT END OF LIST
JUMPE P1,RADK.2 ;SKIP NAME CHECK IF ALL CONTROLLERS ACCEPTABLE
HLLZ S1,.DDNAM(S2) ;GET CONTROLLER NAME
CAME S1,P1 ;MATCH?
JRST RADK.6 ;NO
RADK.2: TXNN F,FL.WAC ;ADDING A CPU?
JRST RADK.3 ;NO
TDNN P2,.DDXCH(S2) ;IS CONTROLLER ON CPU BEING ADDED/REMOVED?
JRST RADK.6 ;NO, SKIP IT
RADK.3: LOAD S1,.DDSTS(S2),DC.STS ;GET UNIT STATUS
TXNN F,FL.ADD ;ADD OR REMOVE?
JRST RADK.4 ;REMOVE
;Add
CAIE S1,.DCSTD ;ADD IS EASIER, IS UNIT STATE = DOWN?
JRST RADK.6 ;NO, IT'S ALREADY THERE, NOTHING TO DO
MOVEI T1,2 ;LENGTH OF ARGUMENT BLOCK
MOVE T2,.DDNAM(S2) ;UNIT NAME
DMOVEM T1,RCNARG ;SAVE ARGUMENTS
PUSHJ P,ATTDET ;DO THE UUO
JRST RADK.6 ;THAT WAS EASY!
;Remove
RADK.4: CAIN S1,.DCSTD ;IS UNIT STATE = DOWN?
JRST RADK.6 ;YES, IT'S ALREADY REMOVED, NOTHING TO DO
SKIPN .DDALT(S2) ;IS THE UNIT DUAL PORTED?
JRST RADK.5 ;NO
TXON F,FL.HEA ;FIRST TIME?
$TEXT (WTORTN,<The following drives are dual ported with the CPU being removed:>)
$TEXT (WTORTN,< ^W/.DDALT(S2)/>) ;GIVE THEM A CLUE
RADK.5: MOVEI T1,2 ;LENGTH OF ARGUMENT BLOCK
MOVE T2,.DDNAM(S2) ;UNIT NAME
DMOVEM T1,RCNARG ;SAVE ARGUMENTS
PUSHJ P,ATTDET ;DO THE UUO
RADK.6: MOVE S1,DSKLST## ;GET LIST HANDLE
$CALL L%NEXT ;POSITION TO NEXT ENTRY
JRST RADK.1 ;SEE IF OTHERS
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,[.GTC0C,,.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
MOVE P1,CPUBIT(S1) ;Get a bit for this CPU
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
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
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 Useful subroutines
;Do the RECON. UUO to attach or detach a piece of hardware, and
;report any errors which occur.
;Call:
; RCNARG/ Arguments (word count, device name)
ATTDET: MOVE S1,[.RCDET,,RCNARG] ;Assume DETACH
TXNE F,FL.ADD ;ADD command?
HRLI S1,.RCATT ;Yes, that means ATTACH
RECON. S1, ;Do the UUO
PJRST RCNERR ;Report error and FALSE return
$RETT ;TRUE return
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,< ^I/@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
GTBERR: $STOP (GTE,<GETTAB error>)
RCNETX: [ITEXT (<No such error code>)]
[ITEXT (<Illegal argument list>)]
[ITEXT (<Not privileged>)]
[ITEXT (<Timesharing has already stopped on some CPU>)]
[ITEXT (<Illegal job number>)]
[ITEXT (<System cannot be snapshotted>)]
[ITEXT (<Address check>)]
[ITEXT (<Illegal string>)]
[ITEXT (<Illegal CPU number>)]
[ITEXT (<CPU still running>)]
[ITEXT (<Can't attach disk unit ^W/RCNARG+1/>)]
[ITEXT (<Device is spooled>)]
[ITEXT (<Device is already attached>)]
[ITEXT (<Illegal device>)]
[ITEXT (<Device in use>)]
[ITEXT (<Can't detach disk unit ^W/RCNARG+1/>)]
[ITEXT (<LOKCON not loaded (can't set memory off-line)>)]
[ITEXT (<Removing monitor memory>)]
[ITEXT (<Job(s) too big>)]
[ITEXT (<Moving locked job(s)>)]
RCNETL==.-RCNETX
[ITEXT (<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/]
[ASCIZ /Port not running/]
DIAETL==.-DIAETX
[ASCIZ /Unknown error code/]
SUBTTL End of CNFORN
END