Trailing-Edge
-
PDP-10 Archives
-
bb-d549g-sb
-
config.mac
There are 2 other files named config.mac in the archive. Click here to see a list.
TITLE CONFIG -- Congifuration Program for 7.01
SUBTTL C.D.O'Toole/CDO 18-Apr-80
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;COPYRIGHT (C) 1978,1979,1980 BY DIGITAL EQUIPMENT CORPORATION
SEARCH UUOSYM
CFGWHO==0
CFGVER==1
CFGMIN==0
CFGEDT==6
CFGVER==BYTE(3)CFGWHO(9)CFGVER(6)CFGMIN(18)CFGEDT
LOC <.JBVER==137>
EXP CFGVER
RELOC
;Revision History
;1 Create CONFIG.MAC and implement original features
;2 Correct bug which allowed the removal of the last running CPU
;3 Begin implementation of System Sleep
;4 Dont DETACH disk units if forced removal of a CPU
;5 KONCPU moved in load 70037
;6 DETACH the CPU after REMOVE so that unit record gear comes out right
;AC DEFINITIONS
F==0 ;A FLAG REG
FL.EOL==1B0 ;END OF LINE SEEN
FL.ETX==1B1 ;END OF PHYSICAL LINE SEEN
FL.RSC==1B2 ;HAVE GETONE USE RESCAN LAST CHARACTER
FL.WAC==1B3 ;WORRY ABOUT CPU NUMBER IN REMOVE
FL.NCD==1B4 ;"NO CAN DO" THIS COMMAND
FL.HEA==1B5 ;HEADING ALREADY GIVEN
FL.CHK==1B6 ;CHECKING ONLY
FL.ADD==1B7 ;"ADD" RATHER THAN "REMOVE"
FL.UPZ==1B8 ;^Z TYPED, EXIT AFTER COMMAND
FL.DMN==1B9 ;OPERATOR REALLY WANTS COMMAND DONE
FL.POK==1B10 ;"P" OR "K" SEEN IN "GETNUM"
FL.DME==1B11 ;"DETJBS" FOUND ME IN ITS SCAN
FL.NIN==1B12 ;DISALLOW ^C INTERRUPTS
T1==1 ;TEMPORARY ACS FOR ANY SUBROUTINE
T2==2
T3==3
T4==4
T5==5
CH==6 ;CHARACTER HOLDER
P1==12 ;PRESERVED ACS FOR ANY COMMAND PROCESSOR
P2==13
P3==14
P4==15
P5==16
P==17
;I/O CHANNELS
PTY==0 ;FOR "SET MEMORY" UNTIL JIM WRITES THE UUO
;DEBUGGING SWITCHES
IFNDEF FTPTYDEBUG,<FTPTYDEBUG==0>
;TEMPORARY DEFINITIONS
OPDEF RECON. [CALLI 202] ;RE-CONFIGURE UUO
.RCROJ==0 ;FUNCTION 0 - RUN ONLY SPECIFIED JOB
.RCSLP==1 ;FUNCTION 1 - SUSPEND THE SYSTEM NOW
SUBTTL Macros and other stuff
SALL ;CLEAN UP LISTING
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==400000+VALUE>
MSYM MONITR,0 ;SYMBOLIZE LOCATION 0 OF THE MONITOR
;DISK DATA BASE
MSYM UNINAM,0 ;UDB: SIXBIT/kon/,,SIXBIT/unit/
MSYM UNILOG,1 ;UDB: SIXBIT/str/ IF STRUCTURE MOUNTED
MSYM UNISYS,3 ;UDB: NEXT SYSTEM UNIT,,xxx
MSYM UNIKON,6 ;UDB: xxx,,KONTROLLER FOR UNIT
MSYM UNIDES,55 ;UDB: UNIT STATUS IS BITS 7-8
UNVDWN==3 ;CODE INDICATING UNIT IS DOWN (DETACHED)
MSYM UNI2ND,72 ;UDB: bits,,2ND PORT IF DUAL
MSYM KONTAB,0 ;KDB: 8 WORD TABLE OF UNITS ON KONTROLLER
MSYM KONCPU,32 ;KDB: CPU OWNING KONTROLLER IS BITS 0-2
;DDB'S IN GENERAL
MSYM DEVNAM,0 ;SIXBIT/device/
MSYM DEVCHR,1 ;DEVICE CHARACTERISTICS
DCVNET==20000,,0 ;"NETWORK DEVICE"
MSYM DEVIOS,2 ;IO STATUS
IOACT==10000 ;IO IN PROGESS
MSYM DEVSER,3 ;LH = LINK TO NEXT DDB
MSYM DEVTYP,12 ;BITS 4-9 ARE DEVICE TYPE
MSYM DEVCPU,20 ;BITS 0-2 IS CPU OWNING DEVICE
MSYM DEVJOB,21 ;BITS 27-35 ARE JOB NUMBER
MSYM DDBLDB,22 ;RH LINK TO LDB FOR TTY'S
;LINE DATA BLOCKS
LDBDCH==22 ;LINE BITS, (27-35 ARE LINE NUMBER)
; ( 22 IS THE 7.00 VALUE, GETTAB'ABLE IN 7.01 )
LDRPTY==400000 ;LINE IS REALLY A PTY
LDRREM==2000 ;LINE IS A REMOTE (NETWORK) LINE
LDBBYT==LDBDCH+1 ;BITS 22-24 ARE CPU OWNING TERMINAL
;MONBTS COMMUNICATION DATA
MSYM MBTCOM,411 ;ADDRESS OF COMMUNICATION REGION
MBTPGS==10 ;NUMBER OF PAGES MIKE WANTS FOR MONBTS
;PSI INTERRUPT BLOCKS
PSIBAS: ;BASE OF INTERRUPT SYSTEM
CCINT: EXP CCTRAP ;NEW PC AT INTERRUPT
BLOCK 3 ;OTHER 3 WORDS
;BUFFER STUFF
PTYOBF: BLOCK 3 ;PTY OUTPUT RING HEADER
PTYIBF: BLOCK 3 ; " INPUT " "
PTYOPN: EXP .IOASC ;ASCII MODE
SIXBIT /PTY/ ;GET A PTY
XWD PTYOBF,PTYIBF ;FOR I/O
;TRMOP. BLOCKS
FRCTYP: EXP .TOTYP ;STICK STRING INTO INPUT BUFFER
FRCLIN: BLOCK 1 ;LINE NUMBER FILLED IN
FRCSTR: EXP 0 ;ASSRESS OF THE STRING
;STORAGE
PDL: BLOCK 50 ;A STACK
DOPTR: BLOCK 1 ;POINTER TO PROCEDURE COMMAND STRING
DONAM: BLOCK 1 ;NAME OF PROCEDURE IN PROGRESS
DOFLG: BLOCK 1 ;SAVED "F" DURING PROCEDURE (REALLY FL.UPZ)
SAVCHR: BLOCK 1 ;SAVED CHARACTER FROM GETONE
TTYTAB: BLOCK 1 ;ADDRESS OF TTYTAB (INDEXED BY T1)
FIRDSK: BLOCK 1 ;ADDRESS OF FIRST DISK UNIT IN SYSTEM
ACTDEV: BLOCK 1 ;COUNT OF IOACT DDB'S
DEVLST: BLOCK 1 ;ADDRESS OF FIRST DDB IN SYSTEM
MYJOBN: BLOCK 1 ;MY JOB NUMBER
MYLINE: BLOCK 1 ;AND MY LINE NUMBER
DCHOFS: BLOCK 1 ;OFFSET INTO LDB FOR LDBDCH
BYTOFS: BLOCK 1 ;OFFSET FOR LDBBYT ( LDBDCH+1 )
SYSSIZ: BLOCK 1 ;SIZE OF THE MONITOR
NWCORE: BLOCK 1 ;NUMBER OF WORDS OF MEMORY ON THE SYSTEM
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)
;1B0 = CPU IS DOWN
;1B1 = CPU IS NON-EXISTANT
;1B2 = CPU HAS BEEN DETACHED
;1B3 = CPU'S OK WORD IS NOT COUNTING
;1B4 = THIS IS THE CURRENT POLICY CPU
;RH = CDB ADDRESS
SUBTTL Entry Point and Main Command Dispatch
CONFIG: JFCL ;NO CCL ENTRY
RESET ;START FRESH
MOVE P,[IOWD 50,PDL] ;GET A STACK
OPEN PTY,PTYOPN ;GRAB A PTY
HALT . ;WHAT
INBUF PTY,1 ;ONLY NEED 1 BUFFER
OUTBUF PTY,1 ;IN EITHER DIRECTION
MOVEI T1,[EXP <PS.SON+5>,PSIBAS
EXP .PCSTP,<<CCINT-PSIBAS>,,0>,0]
PIRST. T1, ;BUILD THE PSI SYSTEM IN ONE SWELL FOOP
HALT . ;WHAT
GTTAB T1,%CNSIZ ;SIZE OF THE MONITOR
HRRZM T1,SYSSIZ ;SAVE FOR LATER
MOVEI T1,-1(T1) ;WANT HIGHEST ADDRESS
SPY T1, ;SPY ON THE MONITOR
HALT . ;WHAT
MOVSI T1,1 ;;; GET 256K FOR NOW
;;; GTTAB T1,%CNNWC ;GET NUMBER OF WORDS OF MEMORY
MOVEM T1,NWCORE ;SAVE FOR LATER
GTTAB T1,%LDUNI ;GET ADDRESS OF FIRST UNIT IN SYSTEM
HLRZM T1,FIRDSK ;SAVE FOR LATER USE
GTTAB T1,%CNDEV ;GET HEADER OF DEVICES
HLRZM T1,DEVLST ;SAVE FOR LATER
GTTAB T1,<.GTTTY,,.GTSLF> ;GET ADDRESS OF TTYTAB
TLZ T1,-1 ;CLEAR GETTAB BITS
TDO T1,[Z MONITR(T1)] ;INDEX BY TI FOR INDIRECT ADDRESSING
MOVEM T1,TTYTAB ;STORE FOR LATER USE
GTTAB T1,%CNDCH,LDBDCH ;GET OFFSET FOR LDBDCH
HRRZM T1,DCHOFS ;STORE FOR DETJBS
ADDI T1,LDBBYT-LDBDCH ;GET OFFSET FOR LDBBYT
HRRZM T1,BYTOFS ;STORE THAT TOO
GTTAB T1,%CNFLN ;FIND MONITORS SPECIAL TTY
TRO T1,.UXTRM ;ADD TERMINAL IONDX FOR TRMOP.
HRRZM T1,FRCLIN ;REMEMBER FOR LATER
PJOB T1, ;GET MY JOB NUMBER
MOVEM T1,MYJOBN ;FOR "DETJBS"
TRMNO. T1, ;GET LINE NUMBER FOR MY JOB
HALT . ;WHAT
ANDI T1,777 ;JUST THE NUMBER
MOVEM T1,MYLINE ;FOR "DETJBS"
SETZM DOPTR ;NO PROCEDURES IN PROGRESS
SUBTTL Main Command Loop
NXTCOM: OUTSTR [ASCIZ/CONFIG>/] ;PROMPT THE OPERATOR
SETZB F,SAVCHR ;CLEAR FLAGS, NO SAVED CHARACTER NOW
MAIN.0: PUSHJ P,GETSIX ;GET COMMAND AND MASK
JUMPE T1,NULCMD ;NULL COMMAND
MOVE T3,[-NUMCMD,,CMDTBL] ;GET AOBJN TO COMMAND TABLE
PUSHJ P,TABSRC ;LOOK IT UP IN THE TABLE
SKIPA T2,[NUMCMD] ;ILLEGAL COMMAND
MOVEI T2,NUMCMD+1 ;AMBIGUOUS COMMAND
PUSHJ P,@CMDDSP(T2) ;EXECUTE IT
MAIN.1: PUSHJ P,FLUSH ;EAT UP REST OF INPUT LINE
SKIPN P1,DOPTR ;DOING A PROCEDURE
JRST MAIN.2 ;NO
TLNE F,(FL.NCD) ;ERROR DURING PROCEDURE
PUSHJ P,[OUTSTR [ASCIZ/?Procedure "/]
MOVE T1,DONAM ;GET PROCEDURE WE WERE DOING
PUSHJ P,SIXOUT ;OUTPUT IT
OUTSTR [ASCIZ/" terminated due to above error/]
SETZ P1, ;SHUT DOWN PROCEDURE
JRST CRPOPJ] ;END MESSAGE AND RETURN
ILDB P1,P1 ;GET NEXT CHARACTER IN PROCEDURE
JUMPN P1,MAIN.2 ;STILL MORE, CONTINUE
SETZM DOPTR ;END OF PROCEDURE
MOVE F,DOFLG ;RESTORE OLD FLAGS ( FL.UPZ )
MAIN.2: TLNN F,(FL.UPZ) ;YES, WAS END A CONTROL-Z
JRST NXTCOM ;NO, GET ANOTHER COMMAND
JRST %EXIT ;YES, EXIT NOW
NULCMD: TLNN F,(FL.EOL) ;JUST AN EMPTY LINE
PUSHJ P,BADFMT ;NO, COMPLAIN
JRST MAIN.1 ;THEN FLUSH INPUT LINE
DEFINE COMNDS,<
XLIST
X ADD,<put a piece of hardware back on-line>
X EXIT,<exit this program>
X DO,<canned procedure>
X HELP,<types out this text>
X REMOVE,<disconnect a piece of hardware>
;;; "SUSPEND" command not available yet
;;; X SUSPEND,<put the system to sleep>
LIST
SALL
>
DEFINE X(CMD,STR),<<SIXBIT/CMD />>
CMDTBL: COMNDS ;GENERATE THE COMMAND TABLE
NUMCMD==<.-CMDTBL> ;NUMBER OF COMMANDS
DEFINE X(CMD,STR),<EXP %'CMD>
CMDDSP: COMNDS ;GENERATE THE DISPATCH TABLE
EXP [CAME T1,[SIXBIT/DAMNIT/] ;FORCE THE COMMAND
JRST ILLCMD ;NO, TYPE OUT ILLEGAL COMMAND
TLO F,(FL.DMN) ;LIGHT THE BIT
POP P,(P) ;REMOVE THE CALL
JRST MAIN.0] ;GET THE COMMAND FORCED
EXP AMBIGC ;TYPE OUT AMBIGUOUS COMMAND
DEFINE X(CMD,STR),<EXP [ASCIZ\STR\]>
CMDHLP: COMNDS ;GENERATE THE HELP DESCRIPTORS
SUBTTL Random Error Message Printers for Command Scanner
AMBIGA: OUTSTR [ASCIZ/?Ambiguous Argument - "/]
JRST ILSXIT ;FINISH ERROR MESSAGE
ILLARG: OUTSTR [ASCIZ/?Unknown Argument - "/]
JRST ILSXIT ;FINISH ERROR MESSAGE
ILLCPU: OUTSTR [ASCIZ/?Illegal CPU/]
JRST ERRXIT ;FINISH UP AND RETURN
NOARGS: TLNN F,(FL.EOL) ;END OF INPUT
JRST BADFMT ;NO, GIVE DIFFERENT ERROR
OUTSTR [ASCIZ/?Missing Argument/]
JRST ERRXIT ;END LINE AND RETURN
JUNK: OUTSTR [ASCIZ/?Junk after end of command - "/]
SKIPA ;OUTPUT OFFENDING CHARACTER
BADFMT: OUTSTR [ASCIZ/?Command Error - "/]
CAIGE CH,40 ;A REGULAR CHARACTER
JRST [OUTCHR ["^"] ;NO, OUTPUT UP-ARROW
ADDI CH,100 ;MAKE A REAL LETTER
JRST .+1] ;RETURN INLINE
OUTCHR CH ;OUTPUT OFFENDING CHARACTER
JRST ILLXIT ;FINISH UP AND RETURN
AMBIGC: OUTSTR [ASCIZ/?Ambiguous Command - "/]
SKIPA ;SKIP OVER OTHER MESSAGE
ILLCMD: OUTSTR [ASCIZ/?Unknown Command - "/]
ILSXIT: PUSHJ P,SIXOUT ;APPEND COMMAND TYPED
ILLXIT: OUTCHR [""""] ;CLOSE QUOTES
ERRXIT: TLO F,(FL.NCD) ;MARK COMMAND ERROR
CRPOPJ: OUTSTR [BYTE (7)15,12,0]
POPJ P,
SUBTTL The "DO" Command
%DO: PUSHJ P,GETSIX ;GET PROCEDURE NAME
JUMPE T1,NOARGS ;ERROR IF NONE (MAYBE TRY MIC:MIC.MIC)
MOVE T3,[-NUMPRC,,PRCTBL] ;KNOWN PROCEDURES
PUSHJ P,TABSRC ;LOOK IT UP
JRST ILLARG ;ILLEGAL
JRST AMBIGA ;AMBIGUOUS
MOVE P1,T2 ;SAVE OFFSET TO PROCEDURE
SKIPE DOPTR ;ONLY 1 LEVEL
JRST [OUTSTR [ASCIZ/?Cannot nest procedures/]
JRST ERRXIT] ;TERMINATE
MOVE T1,PRCPTR(P1) ;GET POINTER TO COMMAND STRING
JUMPG T1,(T1) ;ROUTINE TO USE IF NOT A BYTE POINTER
PUSHJ P,CMDEND ;MUST BE END OF COMMAND STRING
JRST JUNK ;ISN'T, ERROR
PUSHJ P,FLUSH ;EAT UP REST OF THIS LINE
MOVEM T1,DOPTR ;STORE FOR "GETONE"
MOVE P1,PRCTBL(P1) ;GET NAME OF PROCEDURE
MOVEM P1,DONAM ;STORE FOR ANY ERROR MESSAGES
MOVEM F,DOFLG ;SAVE OLD FLAGS ( FL.UPZ )
TLZ F,(FL.UPZ) ;CLEAR ^Z TYPED FLAG
POPJ P, ;RETURN TO START PROCEDURE
DEFINE COMNDS,<
XLIST
X DUALIZ,<put 1026/1042 back together>,<ADD CPU1@ADD MEMORY 512K TO 1024K@>
X HELP,<types out this text>
X SPLIT,<10AM split of 1026/1042>,<REMOVE CPU1@REMOVE MEMORY 512K TO 1024K@>
X BUG,<BUG>,<DO SPLIT@>
LIST
SALL
>
DEFINE X(CMD,STR,TEXT),<<SIXBIT/CMD />>
PRCTBL: COMNDS ;GENERATE THE PROCEDURE TABLE
NUMPRC==<.-PRCTBL> ;NUMBER OF PROCEDURES
DEFINE X(CMD,STR,TEXT),<EXP [ASCIZ\STR\]>
PRCHLP: COMNDS ;GENERATE THE HELP DESCRIPTORS
DEFINE X(CMD,STR,TEXT),<
IFNB <TEXT>,<POINT 7,[ASCIZ\TEXT\]>
IFB <TEXT>,<EXP D%'CMD>
>
PRCPTR: COMNDS ;GENERATE BYTE POINTERS TO TEXT
SUBTTL The "HELP" Command
%HELP: OUTSTR [ASCIZ/Commands are:/]
MOVEI P2,CMDHLP ;FIRST HELP TEXT
SKIPA P1,[-NUMCMD,,CMDTBL] ;AOBJN FOR MAIN COMMAND TABLE
HLPCOM: OUTSTR [ASCIZ/Arguments are:/]
;COMMON PART OF HELP TEXT FOR OTHER COMMAND PROCESSORS
; P1 = AOBJN TO COMMAND TABLE
; P2 = ADDRESS OF PARALLEL HELP TEXT TABLE
HELP.1: OUTSTR [BYTE (7)15,12,11,0] ;CR,LF,TAB
MOVE T1,(P1) ;GET A COMMAND FROM THE TABLE
PUSHJ P,SIXOUT ;OUTPUT IT
OUTCHR [11] ;ALIGN WITH A TAB
OUTSTR @(P2) ;TEXT FOR IT
AOS P2 ;STEP TO NEXT HELP TEXT
AOBJN P1,HELP.1 ;AND TRY ANOTHER
JRST CRPOPJ ;END LINE AND RETURN
;"DO HELP"
D%HELP: MOVEI P2,PRCHLP ;POINT TO HELP TEXT TABLE
MOVE P1,[-NUMPRC,,PRCTBL] ;AOBJN TO COMMAND TABLE
JRST HLPCOM ;DO HELP COMMAND
;"ADD/REMOVE HELP"
R%HELP: MOVE P1,[-NUMRMV,,RMVTBL] ;AOBJN TO COMMAND TABLE
MOVEI P2,RMVHLP ;HELP TEXTS
JRST HLPCOM ;ENTER COMMON PART OF HELP
SUBTTL The "ADD" and "REMOVE" Commands
%ADD: TLO F,(FL.ADD) ;REALLY THE ADD COMMAND
%REMOV: PUSHJ P,GETSIX ;GET THING TO REMOVE
JUMPE T1,NOARGS ;NONE SUPPLIED
MOVE T3,[-NUMRMV,,RMVTBL] ;KNOWN ARGUMENTS
PUSHJ P,TABSRC ;FIND ARGUMENT
JRST %REM.1 ;ILLEGAL, LOOK FURTHER
JRST AMBIGA ;AMBIGUOUS
PUSHJ P,@RMVDSP(T2) ;DISPATCH TO IT
JRST %REM.2 ;AND CHECK IF WE SHOULD BE DETACHED
%REM.1: SETZ T2, ;EXACT MATCH REQUIRED
MOVE T3,[-6,,[SIXBIT/CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 /]]
PUSHJ P,TABSRC ;MAKE TONY HAPPY, TAKE "CPU 1" OR "CPU1"
JFCL ;STILL ILLEGAL
JRST ILLARG ;TYPE OUT ILLEGAL ARGUMENT
MOVE P2,T2 ;PUT OFFSET = CPU NUMBER IN P2
PUSHJ P,R%CPU1 ;AND GO REMOVE IT
%REM.2: TLNN F,(FL.DME) ;IS MY JOB SUPPOSED TO GET DETACHED TOO
POPJ P, ;NO, ALL DONE
HRLZ T2,MYLINE ;GET LINE NUMBER FOR DETACH
ATTACH T2, ;DETACH ME NOW
HALT . ;WHAT
JRST %EXIT ;AND GO AWAY
DEFINE COMNDS,<
XLIST
X CONTRO,<controller id>
X CPU,<CPU number>
X HELP,<types out this text>
X MEMORY,<addr TO addr>
LIST
SALL
>
DEFINE X(CMD,STR),<<SIXBIT/CMD />>
RMVTBL: COMNDS ;GENERATE THE ARGUMENT TABLE
NUMRMV==<.-RMVTBL> ;NUMBER OF ARGUMENTS
DEFINE X(CMD,STR),<EXP R%'CMD>
RMVDSP: COMNDS ;GENERATE THE DISPATCH TABLE
DEFINE X(CMD,STR),<EXP [ASCIZ\STR\]>
RMVHLP: COMNDS ;GENERATE THE HELP DESCRIPTORS
;"MEMORY addr1 TO addr2"
R%MEMO: PUSHJ P,GETNUM ;GET FIRST ADDRESS
JUMPL T1,NOARGS ;MISSING
MOVE P1,T1 ;REMEMBER FIRST ADDRESS
PUSHJ P,GETSIX ;GET GUIDE WORD
TLNN F,(FL.EOL) ;IF NOT AT END OF LINE
JUMPE T1,NOARGS ;SAY INVALID CHARACTER IF NO COMMAND
CAME T1,[SIXBIT/TO/] ;IS IT THERE
JRST [OUTSTR [ASCIZ/?Keyword "TO" Missing/]
JRST ERRXIT] ;GIVE ERROR AND RETURN
PUSHJ P,GETNUM ;GET LAST ADDRESS
JUMPL T1,NOARGS ;MISSING
TLNE F,(FL.POK) ;ADDRESS END WITH "P" OR "K"
SOSA P2,T1 ;YES, BACK OFF BY ONE LOCATION
MOVE P2,T1 ;REMEMBER LAST ADDRESS
PUSHJ P,CMDEND ;MUST BE THE END OF THE COMMAND
JRST JUNK ;ISN'T, GIVE AN ERROR MESSAGE
RMEMCM: TLZ F,(FL.NCD) ;CLEAR "NO CAN DO" ERROR FLAG
MOVEI T1,[ASCIZ/SET MEMORY /]
PUSHJ P,PTYSTR ;FIRST PART OF COMMAND
TLNN F,(FL.ADD) ;ADDING OR REMOVING
SKIPA T1,[[ASCIZ/OFF/]]
MOVEI T1,[ASCIZ/ON/]
PUSHJ P,PTYSTR ;OUTPUT DIRECTION
MOVEI T1,[ASCIZ/ FROM #/]
PUSHJ P,PTYSTR ;OUTPUT REST
MOVE T1,P1 ;WHERE TO START
PUSHJ P,PTYOCT ;OUTPUT IT
MOVEI T1,[ASCIZ/ TO #/]
PUSHJ P,PTYSTR ;SOME MORE
MOVE T1,P2 ;WHERE IT ENDS
PUSHJ P,PTYOCT ;IN OCTAL
JRST PTYCLF ;END LINE AND WAIT FOR COMPLETION
;"CONTROLLER xxx"
R%CONT: PUSHJ P,GETSIX ;GET KONTROLLER TYPE
JUMPE T1,NOARGS ;NONE GIVEN
MOVE P1,T1 ;COPY KONTROLLER WANTED
PUSHJ P,CMDEND ;MUST BE THE END OF THE COMMAND
JRST JUNK ;ISN'T, GIVE AN ERROR MESSAGE
SETZ T1, ;INDICATE FIRST CALL
CONT.1: PUSHJ P,FNDKON ;GET A DISK KONTROLLER
JUMPE T1,[MOVE T1,P1 ;COPY ONE WE COULDN'T FIND
JRST ILLARG] ;AND GIVE A MESSAGE
CAME T2,P1 ;THIS THE ONE WE'RE LOOKING FOR
JRST CONT.1 ;NO, LOOK FOR ANOTHER
MOVE P1,T1 ;COPY KONTROLLER ADDRESS
PUSHJ P,SETCPU ;SET UP NEEDED CPU DATA BASE
LDB T1,[POINT 3,KONCPU(P1),2] ;GET CPU OWNING KONTROLLER
SKIPL CPUSTS(T1) ;IS THE CPU OWNING THE KONTROLLER DOWN
JRST DKONCM ;REMOVE KONTROLLER AND RETURN
OUTSTR [ASCIZ/?CPU owning Controller is down/]
JRST ERRXIT ;END MESSAGE AND RETURN
;"CPU n"
R%CPU: PUSHJ P,GETNUM ;GET CPU NUMBER
JUMPL T1,NOARGS ;ILLEGAL CPU NUMBER
MOVE P2,T1 ;COPY CPU NUMBER
R%CPU1: PUSHJ P,CMDEND ;MUST BE THE END OF THE COMMAND
JRST JUNK ;ISN'T, GIVE AN ERROR MESSAGE
PUSHJ P,SETCPU ;SET UP NEEDED CPU DATA BASE
MOVSI T1,(1B1) ;NON-EXISTANT BIT
CAIGE P2,6 ;RANGE CHECK CPU NUMBER
TDNE T1,CPUSTS(P2) ;IN RANGE, IS IT REAL
JRST ILLCPU ;NOPE
TLNE F,(FL.ADD) ;TRYING TO ADD A CPU
JRST R%CPUA ;YES, GO DO THAT
;HERE TO REMOVE A CPU
SKIPGE CPUSTS(P2) ;CPU ALREADY DOWN
POPJ P, ;YES, JUST RETURN NOW
MOVE T1,CPUN ;GET NUMBER OF RUNNING CPUS
CAIN T1,1 ;TRYING TO REMOVE THE LAST REMAINING CPU
JRST [OUTSTR [ASCIZ/?You really DON'T want to remove the last one/]
JRST ERRXIT] ;END OUTPUT AND RETURN
MOVE T1,CPUOK ;NUMBER OF ACTUALLY RUNNING CPUS
CAIN T1,1 ;ONLY ONE OF THOSE LEFT
JRST [MOVSI T1,(1B3) ;YES, REMOVING A CPU THAT ISN'T RUNNING IS OK
TDNE T1,CPUSTS(P2) ;WELL?
JRST CPU.1 ;CPU IS DEAD, OK TO REMOVE IT
OUTSTR [ASCIZ/?No running CPUs will be left/]
JRST ERRXIT] ;IF OPERATOR REALLY WANTS THIS, USE "SHUT"
CPU.1: TLNE F,(FL.DMN) ;FORCED REMOVE
JRST [OUTSTR [ASCIZ/%Bypassing lots of checking/]
PUSHJ P,CRPOPJ ;PRETTY UP OUTPUT
JRST CPU.2] ;YES, SKIP CHECKS
TLO F,(FL.WAC!FL.CHK) ;SET "WORRY ABOUT CPU",ONLY CHECKING
PUSHJ P,RADKON ;CHECK ALL DISK KONTROLLERS
TLNE F,(FL.NCD) ;DID SOME CHECK FAIL
POPJ P, ;YES, CANNOT REMOVE THE CPU
PUSHJ P,LSTDEV ;LOOK FOR LOST DEVICES, GIVE WARNING
TLZ F,(FL.CHK) ;NOT CHECKING ANY MORE
PUSHJ P,DETJBS ;DETACH JOBS AS APPROPRIATE
CPU.2: MOVSI T1,(1B0) ;GET CPU IS DOWN BIT
IORB T1,CPUSTS(P2) ;LIGHT IN STATUS BLOCK
SOS CPUN ;ONE LESS CPU IN SYSTEM
TLNN T1,(1B3) ;WAS CPU'S OK WORD COUNTING BEFORE
SOS CPUOK ;YES, BUT IT WILL STOP SOON
MOVSI T1,(1B3) ;IN CASE IT WASN'T
IORM T1,CPUSTS(P2) ;LIGHT THE BIT NOW
MOVEI T1,1B35 ;GET BIT FOR CPU0
LSH T1,(P2) ;POSITION FOR CORRECT CPU
ANDCAB T1,CPURUN ;CLEAR/GET NEW RUNNING CPU MASK
HRLI T1,.STCRN ;SET RUN CPUN
SETUUO T1, ;SET NEW SPECIFICATION
HALT . ;WHAT
MOVEI P3,(P2) ;GET CPU NUMBER
LSH P3,1 ;*2 FOR GETTABS
MOVE T2,[%CCOKP] ;GET THE OK WORD FOR CPU
ADD T2,P3 ;FOR CPUN
GETTAB T2, ;GET IT
HALT . ;WHAT
JUMPG T2,CPU.5 ;AVOID LOOP, SHUT IT DOWN IF ALREADY DEAD
CPU.3: MOVE T2,[%CVJOB] ;JOB CURRENTLY RUNNING ON CPU
ADD T2,P3 ;FOR CPUN
GETTAB T2, ;GET IT
HALT . ;WHAT
JUMPN T2,CPU.3 ;WAIT FOR CPU TO ONLY RUN NULL JOB
CPU.4: PUSHJ P,LSTDEV ;COUNT IOACT DDB'S (FL.CHK IS OFF)
SKIPE ACTDEV ;ANY IOACTIVE
JRST CPU.4 ;YES, WAIT FOR THEM TO STOP
TLNN F,(FL.DMN) ;DONT DETACH IF FORCED REMOVAL
PUSHJ P,RADKON ;GO AND DETACH ALL THE UNITS NOW
CPU.5: MOVEI T2,1B18(P2) ;GET CPU NUMBER, FLAG AS REMOVE
HRLI T2,.STCDN ;SET "DOWN" CPUN
SETUUO T2, ;SHUT IT DOWN
HALT . ;WHAT
CPU.6: MOVE T2,[%CCOKP] ;GET THE OK WORD FOR CPU
ADD T2,P3 ;FOR CPUN
GETTAB T2, ;GET IT
HALT . ;WHAT
JUMPLE T2,CPU.6 ;WAIT FOR IT TO STICK ITS HEAD IN THE SAND
MOVE T1,CPUN ;HOW MANY CPU'S ARE LEFT
CAIE T1,1 ;ONLY 1 REMAINING
JRST CPU.7 ;NO, JUST MAKE THE CPU GO AWAY
MOVSI T1,.STCSB ;OK TO CACHE MONITOR DATA BASE NOW
HRRI T1,1B35 ;LIGHT BIT TO TURN ON CACHE
SETUUO T1, ;SINCE ONLY 1 PROCESSOR LEFT
JFCL ;OK, MUST BE A KI
CPU.7: MOVSI T1,(1B2) ;"CPU DETACHED" BIT
TDNE T1,CPUSTS(P2) ;IS THE CPU ALREADY DETACHED
POPJ P, ;YES, RETURN NOW
IORM T1,CPUSTS(P2) ;SAY DETACHED NOW
MOVEI T1,[ASCIZ/DETACH CPU/]
PUSHJ P,PTYSTR ;OUTPUT DETACH COMMAND
MOVE T1,P2 ;THE CPU NUMBER
PUSHJ P,PTYOCT ;OUTPUT THAT TOO
JRST PTYCLF ;END THE LINE AND RETURN
;HERE TO ADD A CPU
R%CPUA: SKIPL CPUSTS(P2) ;IS IT ALREADY UP
JRST CPUA.2 ;YES, GO LET IT IN (UNDO OPSER'S ":SET RUN")
MOVSI T1,(1B0!1B3) ;CPU IS DOWN BIT
ANDCAM T1,CPUSTS(P2) ;NOT ANY MORE
AOS CPUN ;ONE MORE CPU RUNNING
AOS CPUOK ;ONE MORE COUNTING
MOVSI T1,.STCSB ;MUST UNCACHE MONITOR DATA BASE
SETUUO T1, ;DO IT (1B35 = 0)
JFCL ;OK, MUST BE A KI
MOVSI T1,(1B2) ;CPU DETACHED BIT
TDNN T1,CPUSTS(P2) ;IS IT
JRST CPUA.1 ;NO, LET IT IN
ANDCAM T1,CPUSTS(P2) ;CLEAR DETACHED CPU BIT
MOVEI T1,[ASCIZ/ATTACH CPU/]
PUSHJ P,PTYSTR ;OUTPUT ATTACH COMMAND
MOVE T1,P2 ;COPY CPU NUMBER
PUSHJ P,PTYOCT ;WHICH ONE TO ATTACH
PUSHJ P,PTYCLF ;END THE COMMAND
TLNE F,(FL.NCD) ;DID IT WORK
POPJ P, ;NO, RETURN NOW
CPUA.1: MOVE T1,P2 ;GET CPU NUMBER ( 1B18 OFF = ADD THIS ONE )
HRLI T1,.STCDN ;SET CPU UP ( OR ALLOWED TO BE UP )
SETUUO T1, ;i.e. LET THIS CPU IN
HALT . ;WHAT
CPUA.2: MOVEI T1,1B35 ;GET A BIT FOR CPU0
LSH T1,(P2) ;POSITION FOR CPUN
IORB T1,CPURUN ;ADD/GET NEW RUNNING CPU MASK
HRLI T1,.STCRN ;NOW ALLOW IT TO RUN JOBS
SETUUO T1, ;OTHERWISE WHY BOTHER ADDING IT
HALT . ;WHAT
POPJ P, ;ADDING IS A LOT EASIER THAN REMOVING
SUBTTL The "SUSPEND" Command
%SUSPE: TLNE F,(FL.DMN) ;ONLY WORKS IF YOU MEAN IT
PUSHJ P,CMDEND ;NO ARGUMENTS
JRST JUNK ;COMPLAIN
MOVE T1,[.RCROJ,,T2] ;SET TO RUN ONLY 1 JOB
MOVEI T2,2 ;2 WORD ARGUMENT BLOCK
SETZ T3, ;JOB NUMBER 0 = ALLOW ALL USERS
RECON. T1, ;DO THE UUO
JRST [OUTSTR [ASCIZ/?No System Sleep support in the monitor/]
JRST ERRXIT] ;END MESSAGE AND RETURN
MOVEI T1,[ASCIZ/SEND ALL Expect an interruption of service/]
PUSHJ P,FRCOLF ;OUTPUT THE MESSAGE, END STRING
MOVEI T1,^D5 ;GIVE IT TIME TO TYPE OUT
SLEEP T1, ;WAIT
MOVE P1,SYSSIZ ;FIRST WORD OUTSIDE THE MONITOR
SUSP.3: MOVE P2,P1 ;COPY ADDRESS
ADDI P2,<MBTPGS*1000>-1 ;LAST LOCATION NEEDED FOR MONBTS
CAMLE P2,NWCORE ;OFF THE TOP OF MEMORY
HALT . ;WHAT
PUSHJ P,RMEMCM ;SET SOME MEMORY OFF-LINE
TLNE F,(FL.NCD) ;DID IT WORK
JRST [ADDI P1,1000 ;NO, TRY A DIFFERENT PLACE
JRST SUSP.3] ;TRY AGAIN
MOVE T1,[3,,T2] ;SET UP FOR POKE
MOVEI T2,MBTCOM-MONITR ;WHERE TO POKE ADDRESS OF COMM REGION
MOVE T3,MBTCOM ;GET OLD VALUE
MOVE T4,P1 ;NEW VALUE = WHERE COMM REGION IS
LSH T4,-^D9 ;AS A PAGE NUMBER
POKE. T1, ;STORE FOR MONBTS
HALT . ;WHAT
TLO F,(FL.NIN) ;DON'T LET THE OPERATOR ^C OUT OF THIS
MOVE T1,[.RCROJ,,T2] ;SET TO RUN ONLY ME NOW
MOVEI T2,2 ;2 WORD ARGUMENT BLOCK
MOVE T3,MYJOBN ;ONLY ME
RECON. T1, ;DO IT
HALT . ;WHAT
MOVEI T1,^D5 ;ALLOW SYSTEM TO SETTLE DOWN
SLEEP T1, ;WAIT
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,(1B4) ;OR THE BOOT CPU
JRST SUSP.2 ;IGNORE THIS ONE
MOVEI T2,1B19(T1) ;GET CPU NUMBER AND FLAG = SUSPEND THYSELF
HRLI T2,.STCDN ;SET "DOWN" CPU FUNCTION
SETUUO T2, ;MAKE IT GO AWAY
HALT . ;WHAT
SUSP.2: AOBJN T1,SUSP.1 ;DO ALL CPUS THAT WILL REMAIN AFTER SUSPEND
MOVEI T1,^D5 ;ALLOW SYSTEM TO SETTLE DOWN
SLEEP T1, ;WAIT
MOVE T1,[.RCSLP,,0] ;FUNCTION SUSPEND
RECON. T1, ;"COMPUTUS INTERRUPTUS"
CAIA ;DUMP MUST HAVE FAILED, LET THE WORLD BACK IN
JRST SUSP.4 ;JIM ALREADY TOLD EVERYBODY THAT WE ARE BACK
MOVEI T1,[ASCIZ/SEND ALL System resumed/]
PUSHJ P,FRCOLF ;TELL WORLD THE SYSTEM IS BACK
SUSP.4: MOVE T1,[.RCROJ,,T2] ;SET TO RUN ONLY 1 JOB
MOVEI T2,2 ;2 WORD ARGUMENT BLOCK
SETZ T3, ;JOB NUMBER 0 = ALLOW ALL USERS
RECON. T1, ;DO THE UUO
HALT . ;WHAT
TLO F,(FL.ADD) ;MUST RETURN THE MEMORY WE STOLE FOR MONBTS
JRST RMEMCM ;PUT BACK ON-LINE AND RETURN TO COMMAND LEVEL
SUBTTL Some Input Subroutines
;SUBROUTINE TO INPUT A SINGLE CHARACTER INTO CH
; PUSHJ P,GETONE
; RETURN HERE IF A SPECIAL CHARACTER
; RETURN HERE IF A NUMBER
; RETURN HERE IF A LETTER
;IF FL.RSC IS ON, THIS GETS THE LAST CHARACTER (TERMINATOR OF PREVIOUS)
GETONE: TLNE F,(FL.EOL) ;END OF LINE SEEN
JRST GETO.2 ;YES, RETURN LINE FEED
TLZE F,(FL.RSC) ;WANT OLD CHARACTER AGAIN
JRST [MOVE CH,SAVCHR ;YES, GET SAVED CHARACTER
JRST GETO.B] ;AND PROCESS IT
SKIPE DOPTR ;DOING A PROCEDURE
JRST [ILDB CH,DOPTR ;GET A CHARACTER
CAIN CH,"@" ;CRLF REQUESTED
JRST GETO.3 ;YES, GET ONE
OUTCHR CH ;ECHO IT SINCE OPERATOR DIDN'T TYPE IT
JUMPN CH,GETO.A ;RETURN IN LINE IF A REAL CHARACTER
HALT .] ;SOME BODY DIDN'T ADD PROCEDURE CORRECTLY
INCHWL CH ;NO, GET A CHARACTER
GETO.A: MOVEM CH,SAVCHR ;SAVE FOR RESCAN
GETO.B: JUMPE CH,GETONE ;IGNORE NULLS
CAIN CH,15 ;CARRIAGE RETURN ??
JRST GETONE ;YES, PITCH THOSE
CAIE CH,7 ;^G ??
CAIN CH,13 ;^K ??
JRST GETO.1 ;YES, MARK END OF TEXT AND RETURN LINE FEED
CAIN CH,14 ;^L ??
JRST GETO.1 ;YES, MARK END OF TEXT AND RETURN LINE FEED
CAIE CH,12 ;LINE FEED ??
CAIN CH,33 ;ALTMODE ??
JRST GETO.1 ;YES, MARK END OF TEXT AND RETURN LINE FEED
CAIN CH,32 ;^Z ??
JRST GETO.0 ;YES, LIGHT LOTS OF BITS FOR ^Z
CAIN CH,11 ;A TAB
SKIPA CH,[" "] ;YES, CONVERT TO SPACE
CAIN CH," " ;A SPACE
POPJ P, ;YES, TAKE "SPECIAL" RETURN
CAIE CH,"!" ;LOOK FOR COMMENTS
CAIN CH,";" ;...
JRST GETO.2 ;FAKE AN END OF LINE
CAIG CH,"9" ;LOOK FOR DIGITS
CAIGE CH,"0" ;...
SKIPA ;NOT A DIGIT
JRST CPOPJ1 ;TAKE "DIGIT" EXIT
CAIG CH,"Z"+40 ;LOWER CASE LETTER
CAIGE CH,"A"+40 ;...
SKIPA ;NOT LOWER CASE
SUBI CH," " ;CONVERT TO UPPER CASE
CAIG CH,"Z" ;NOW DO LETTER CHECK
CAIGE CH,"A" ;...
POPJ P, ;MUST BE A SPECIAL
CPOPJ2: AOS (P) ;TAKE "LETTER" EXIT
CPOPJ1: AOS (P) ;LOTS OF SKIP RETURNS
CPOPJ: POPJ P, ;RETURN
GETO.0: TLO F,(FL.UPZ) ;MARK ^Z FOR JMF
GETO.1: TLO F,(FL.ETX) ;MARK REAL END OF TEXT
GETO.2: TLO F,(FL.EOL) ;LIGHT FAKE END OF LINE
MOVEI CH,12 ;RETURN LINE FEED
POPJ P, ;TAKE "SPECIAL" RETURN
GETO.3: PUSHJ P,CRPOPJ ;END ECHOING WITH CR,LF
JRST GETO.1 ;AND MARK LINE AS COMPLETE
;SUBROUTINE TO SEARCH A TABLE FOR A COMMAND OR ARGUMENT
;CALL: T1 = ITEM IN SIXBIT
; T2 = MASK FOR CHARACTERS TYPED
; T3 = AOBJN POINTER FOR TABLE TO SEARCH
;RTNS: CPOPJ = NOT IN THE TABLE
; CPOPJ1 = AMBIGUOUS
; CPOPJ2 = FOUND IT
;RETURNS T1 INTACT, T2 = RELATIVE INDEX FOR COMMAND, CLOBBERS T3,T4,T5
TABSRC: MOVEI T4,(T3) ;SAVE TABLE START ADDRESS
PUSH P,T2 ;SAVE MASK TO USE
SETZ T2, ;CLEAR FOUND INDICATOR
TABS.1: MOVE T5,(T3) ;GET AN ITEM
CAMN T1,T5 ;EXACT MATCH
JRST [MOVEI T2,(T3) ;YES, MARK WHERE WE FOUND IT
JRST TABS.3] ;AND EXIT
ANDCM T5,(P) ;MASK TO AS MANY CHARS AS IN T1
CAME T1,T5 ;NOW DO WE HAVE A MATCH
JRST TABS.2 ;NO, TRY NEXT ENTRY IN TABLE
JUMPN T2,[POP P,(P) ;IF ALREADY HAVE 1 MATCH
JRST CPOPJ1] ;GIVE AMBIGUOUS RETURN
MOVEI T2,(T3) ;SAVE ADDRESS OF THIS MATCH
TABS.2: AOBJN T3,TABS.1 ;AND LOOK SOME MORE
TABS.3: POP P,(P) ;CLEAN STACK NOW
JUMPE T2,CPOPJ ;RETURN IF NEVER FOUND ONE
SUBI T2,(T4) ;COMPUTE RELATIVE OFFSET OF COMMAND
JRST CPOPJ2 ;AND GIVE LOTS OF SKIP RETURNS
;SUBROUTINE TO EAT UP THE REST OF THE INPUT LINE
FLUSH: TLZ F,(FL.EOL!FL.RSC) ;CLEAR SCANNER FLAGS
TLNE F,(FL.ETX) ;REACHED END OF LINE YET
POPJ P, ;YES, RETURN
PUSHJ P,GETONE ;GET A CHARACTER
JFCL ;IGNORE VARIOUS RETURNS
JFCL ;...
JRST FLUSH ;NOW LOOK FOR END OF LINE
;HERE WHEN OPERATOR TYPES ^C AT US, IGNORE IT IF FL.NIN IS ON, ELSE EXIT
CCTRAP: TLNE F,(FL.NIN) ;DO WE HAVE THE SYSTEM LOCKED UP
DEBRK. ;YES, IGNORE ^C^C
%EXIT: MONRT. ;OK TO STOP, STOP
JRST CONFIG ;RESTART PROGRAM ON CONTINUE
;SUBROUTINE TO ENSURE THAT NO GARBAGE FOLLOWS LAST ARGUMENT OF A COMMAND
;CALLED BY VARIOUS COMMAND PROCESSORS AFTER READING LAST ARGUMENT BUT BEFORE
; EXECUTING THE COMMAND ITSELF.
;RTNS: CPOPJ JUNK AFTER COMMAND
; CPOPJ1 NOTHING BUT END OF LINE
CMDEND: TLO F,(FL.RSC) ;GET LAST ARGUMENT TERMINATOR
CMDE.1: PUSHJ P,GETONE ;GET A CHARACTER
JRST CMDE.2 ;SPECIAL, CHECK IT OUT
POPJ P, ;NUMBER, JUNK
POPJ P, ;SPECIAL, JUNK
CMDE.2: CAIN CH," " ;SPACE AFTER COMMAND
JRST CMDE.1 ;ALLOW SPACES BEFORE ANY COMMENTS
TLNE F,(FL.EOL) ;END OF LINE
AOS (P) ;YES, NO JUNK
POPJ P, ;RETURN
;SUBROUTINE TO GET A SIXBIT WORD FROM THE INPUT STREAM INTO "T1"
; ALSO RETURNS MASK FOR POSSIBLE COMMAND IN "T2"
;CLOBBERS T3
GETSIX: MOVE T3,[POINT 6,T1] ;PRIME THE BYTE POINTER
SETZ T1, ;AND THE RECEIVING WORD
SETO T2, ;AND THE EVENTUAL COMMAND MASK
TLO F,(FL.RSC) ;START WITH LAST TERMINATOR
GETS.1: PUSHJ P,GETONE ;GET A CHARACTER
JRST GETS.2 ;SPECIAL, GO LOOK
JRST [JUMPE T1,CPOPJ ;NUMBERS CANNOT BE THE FIRST IN A COMMAND
JRST .+1] ;BUT CAN BE PARTS OF IT (e.g. CPU0, RPE4)
SUBI CH,40 ;TO SIXBIT
TLNE T3,770000 ;GOT THEM ALL YET
IDPB CH,T3 ;NO, INSERT NEW CHARACTER
LSH T2,-6 ;ADJUST MASK FOR NEW CHARACTER
JRST GETS.1 ;AND GET ANOTHER
GETS.2: CAIN CH," " ;STOP ON A BLANK
JUMPE T1,GETS.1 ;YES, IGNORE LEADING BLANKS
POPJ P, ;RETURN WITH T1,T2 SET UP
;SUBROUTINE TO GET A NUMERIC ARGUMENT FROM THE INPUT STREAM INTO "T1"
;RTNS: T1 .LT. 0 IF NO DIGITS FOUND
;CLOBBERS T2,T3
GETNUM: SETO T1, ;NO DIGITS SEEN YET
MOVEI T2,^D10 ;DEFAULT RADIX
TLO F,(FL.RSC) ;START WITH LAST TERMINATOR
TLZ F,(FL.POK) ;CLEAR "P" OR "K" SEEN
GETN.1: PUSHJ P,GETONE ;GET A CHARACTER
JRST GETN.2 ;A SPECIAL, CHECK IT OUT
SKIPA ;A NUMBER, INCLUDE IT
JRST GETN.3 ;A LETTER, CHECK FOR K OR P
MOVEI T3,-"0"(CH) ;CONVERT TO ASCII
CAIL T3,(T2) ;RADIX CHECK
JRST GETN.4 ;ILLEGAL ( NO 8'S OR 9'S IN OCTAL )
SKIPGE T1 ;ANY DIGITS SO FAR
TDZA T1,T1 ;NO, THIS IS THE FIRST
IMULI T1,(T2) ;"SHIFT" PREVIOUS SUM
ADDI T1,(T3) ;AND INCLUDE THE NEW DIGIT
JRST GETN.1 ;GET MORE
GETN.2: CAIN CH,"#" ;INPUTTING OCTAL
JRST [JUMPGE T1,GETN.4 ;CAN'T CHANGE RADIX IN THE MIDDLE OF THE STREAM
CAIN T2,^D8 ;ALREADY DONE THIS ONCE
POPJ P, ;YES, CAN'T TYPE TWO OF THEM
MOVEI T2,^D8 ;NEW RADIX
JRST GETN.1] ;AND GET ANOTHER DIGIT
CAIN CH," " ;A BLANK
JUMPL T1,GETN.1 ;YES, IGNORE LEADING BLANKS ALWAYS
POPJ P, ;STOP ON A SPECIAL OR OTHER BLANKS
GETN.3: JUMPL T1,CPOPJ ;ERROR IF NO DIGITS YET
SETO T3, ;FLAG INVALID LETTER
CAIN CH,"K" ;ALLOW "K"
MOVEI T3,^D10 ;*1024 IF "K"
CAIN CH,"P" ;ALLOW "P"
MOVEI T3,^D9 ;*512 IF "P"
JUMPL T3,GETN.4 ;ILLEGAL IF NEITHER
TLO F,(FL.POK) ;LIGHT "P" OR "K" SEEN
LSH T1,(T3) ;ADJUST APPROPRIATELY
SETZM SAVCHR ;EAT UP THE "P" OR "K"
POPJ P, ;RETURN WITH NUMBER IN T1
GETN.4: SETO T1, ;ANYTHING ILLEGAL, RETURN -1
POPJ P, ;RETURN
SUBTTL Some Output Subroutines
;SUBROUTINE TO OUTPUT SIXBIT VALUE IN AC "T1"
SIXOUT: MOVE T2,T1 ;COPY SIXBIT OVER
SIXOU1: JUMPE T2,CPOPJ ;ALL DONE AT END OF SIXBIT WORD
SETZ T1, ;CLEAR RECEIVING AC
LSHC T1,6 ;BRING IN A CHARACTER
MOVEI T1," "(T1) ;TO ASCII
OUTCHR T1 ;OUTPUT IT
JRST SIXOU1 ;AND GET THEM ALL
;SUBROUTINE TO OUTPUT "T1" IN CORRECT RADIX
DECOUT: SKIPA T3,[^D10] ;GET RADIX
OCTOUT: MOVEI T3,10 ;GET RADIX
OCTOU1: IDIVI T1,(T3) ;STRIP DIGIT
PUSH P,T2 ;SAVE IT
SKIPE T1 ;WAS THAT ALL
PUSHJ P,OCTOU1 ;NO, GET ANOTHER
POP P,T1 ;RESTORE CHARACTER
MOVEI T1,"0"(T1) ;TO ASCII
OUTCHR T1 ;OUTPUT IT
POPJ P, ;AND RETURN
;SUBROUTINE TO OUTPUT THE ASCIZ STRING POINTED TO BY "T1" ON THE SYSTEM TTY
FRCOLF: PUSHJ P,FRCOUT ;OUTPUT STRING AND THEN <CR><LF>
FRCCLF: MOVEI T1,[BYTE (7)15,12,0] ;A <CR><LF> PAIR
FRCOUT: HRRM T1,FRCSTR ;STORE IN TRMOP. BLOCK
MOVE T1,[3,,FRCTYP] ;FOR TRMOP.
TRMOP. T1, ;OUTPUT THE STRING
HALT . ;WHAT
POPJ P, ;AND RETURN
SUBTTL Some PTY Subroutines
;SUBROUTINE TO OUTPUT AN ASCIZ STRING TO THE PTY
PTYSTR: MOVE T2,T1 ;MOVE STRING ADDRESS
TLO T2,(POINT 7,0) ;MAKE A BYTE POINTER
PTYST1: ILDB T1,T2 ;GET A CHARACTER
JUMPE T1,CPOPJ ;DONE ON A NULL
PUSHJ P,PTYPUT ;OUTPUT IT
JRST PTYST1 ;AND LOOP
;SUBROUTINE TO STICK 1 CHARACTER INTO THE PTY OUTPUT BUFFER
OUTPUT PTY, ;HERE WHEN FULL
PTYPUT: SOSGE PTYOBF+.BFCTR ;MAKE ROOM - MAKE ROOM
JRST .-2 ;HACK, DUMP THE BUFFER
IDPB T1,PTYOBF+.BFPTR ;STICK THE NEW CHARACTER
IFE FTPTYDEBUG,<TLNE F,(FL.NCD)> ;ERROR SEEN?
OUTCHR T1 ;SHOW THE CHARACTER
POPJ P, ;ALL DONE
;SUBROUTINE TO STUFF "T1" DOWN THE PTY IN CORRECT RADIX
PTYDEC: SKIPA T3,[^D10] ;GET RADIX
PTYOCT: MOVEI T3,10 ;GET RADIX
PTYOC1: IDIVI T1,(T3) ;STRIP A DIGIT
PUSH P,T2 ;SAVE IT
SKIPE T1 ;DONE YET
PUSHJ P,PTYOC1 ;NO, GET ANOTHER
POP P,T1 ;GET DIGIT
MOVEI T1,"0"(T1) ;TO ASCII
JRST PTYPUT ;OUTPUT IT AND RETURN (MAYBE)
;SUBROUTINE TO OUTPUT "T1" IN SIXBIT TO THE PTY
PTYSIX: MOVE T2,T1 ;COPY VALUE
PTYSI1: JUMPE T2,CPOPJ ;DONE AT END OF SIXBIT WORD
SETZ T1, ;CLEAR RECEIVING AC
LSHC T1,6 ;SHIFT IN A CHARACTER
MOVEI T1," "(T1) ;CONVERT TO ASCII
PUSHJ P,PTYPUT ;STUFF INTO PTY BUFFER
JRST PTYSI1 ;AND GET ANOTHER
;SUBROUTINE TO END THE CURRENT LINE AND WAIT FOR PTY TO GO HUNGRY AGAIN
PTYOLF: PUSHJ P,PTYSTR ;STRING FIRST, THEN <CR><LF>, THEN WAIT
PTYCLF: MOVEI T1,[BYTE (7)15,12,0] ;A CRLF
PUSHJ P,PTYSTR ;ADD THAT TO THE BUFFER
OUTPUT PTY, ;DUMP THE BUFFER
PTYCL1: MOVEI T1,PTY ;CHANNEL USED
JOBSTS T1, ;GET ITS STATUS
HALT . ;WHAT
TLNN T1,(JB.UOA) ;SOMETHING TO READ
JRST [TLNE T1,(JB.UDI) ;NO, PTY READY FOR MORE
POPJ P, ;YES, FINALLY RETURN
MOVE T1,[HB.RPT+^D500] ;NO 1/2 SECOND NAP
HIBER T1, ;GIVE IT A CHANGE TO MAKE SOME OUTPUT
HALT . ;WHAT
JRST PTYCL1] ;GO BACK AND WAIT
INPUT PTY, ;FILL ONE BUFFER
PTYCL2: PUSHJ P,PTYGET ;SNARF UP A CHARACTER
JRST PTYCL1 ;NO MORE, GO BACK AND WAIT
CAIN T1,"?" ;AN ERROR MESSAGE COMING AT US
TLO F,(FL.NCD) ;YES, LIGHT BIT
IFE FTPTYDEBUG,<TLNE F,(FL.NCD)> ;ERROR SEEN?
OUTCHR T1 ;SHOW THE CHARACTER
JRST PTYCL2 ;GO BACK AND GET ANOTHER CHARACTER
;SUBROUTINE TO GET 1 CHARACTER FROM THE PTY (CALLER MUST FILL BUFFER)
;RTNS: CPOPJ BUFFER IS EMPTY
; CPOPJ1 GOT ONE IN "T1"
PTYGET: SOSGE PTYIBF+.BFCTR ;ANYTHING THERE
POPJ P, ;NO, RETURN NOW
ILDB T1,PTYIBF+.BFPTR ;GET ONE
JUMPN T1,CPOPJ1 ;RETURN WITH IT
JRST PTYGET ;PITCH NULLS
SUBTTL Some Random Subroutines
;SUBROUTINE TO DETACH JOBS WHOSE TERMINAL WILL BE LOST BY REMOVING A CPU
;CALL: P2 = CPU BEING REMOVED
DETJBS: TLZ F,(FL.HEA) ;NEW HEADING REQUIRED
GTTAB T1,%CNSJN ;NUMBER OF JOBS IN THE SYSTEM
MOVNI T1,-1(T1) ;FORM AOBJN FOR JOBS
HRLZS T1 ;...
DETJ.1: SKIPN T2,@TTYTAB ;GET TTY DDB FOR JOB
JRST DETJ.3 ;ISN'T ANY, TRY NEXT
MOVE T3,DEVNAM(T2) ;SIXBIT TTY NAME
TLNN T3,-1 ;IS IT ALREADY DETACHED
JRST DETJ.3 ;YES, DON'T OVERKILL
HRRZ T2,DDBLDB(T2) ;STEP TO LDB FOR LINE
MOVE T3,T2 ;COPY LDB ADDRESS
ADD T3,BYTOFS ;WORD CONTAINING CPU NUMBER
PEEK T3, ;GET IT
LDB T3,[POINT 3,T3,24] ;GET CPU OWNING TERMINAL
CAME T3,P2 ;ON THE CPU BEING REMOVED
JRST DETJ.3 ;NO, LEAVE IT ALONE
ADD T2,DCHOFS ;GET LINE CHARACTERISTICS WORD
PEEK T2, ;LDB'S ARE NOT IN THE SPY SEG
TRNE T2,LDRPTY!LDRREM ;IGNORE PTY AND NETWORK LINES
JRST DETJ.3 ;TRY ANOTHER LINE
ANDI T2,777 ;ISOLATE LINE NUMBER FOR JOB
CAMN T2,MYLINE ;IS THIS ME
JRST [TLO F,(FL.DME) ;YES, MARK TO DO THIS ONE LATER
JRST DETJ.2] ;AND RESUME
HRLZS T2 ;IN LEFT HALF FOR DETACH
ATTACH T2, ;DETACH THE JOB
HALT . ;WHAT
DETJ.2: TLON F,(FL.HEA) ;NEED A HEADING
OUTSTR [ASCIZ/% Detaching Jobs:/]
OUTCHR [" "] ;SPACE BETWEEN JOB NUMBERS
PUSH P,T1 ;SAVE AOJBN
HRRZS T1 ;ISOLATE JOB NUMBER
PUSHJ P,DECOUT ;OUTPUT IT
POP P,T1 ;RESTORE
DETJ.3: AOBJN T1,DETJ.1 ;CONTINUE FOR ALL JOBS IN THE SYSTEM
TLNE F,(FL.HEA) ;HAVE TO CLEAN UP
JRST CRPOPJ ;YES
POPJ P, ;NO, RETURN
;SUBROUTINE TO LOOK FOR AND REPORT ANY DEVICES THAT WILL BE LOST
;CALL: P2 = CPU BEING REMOVED
;RTNS: P1 = CLOBBERED
; COUNTS ACTDEV FOR EACH IOACT DDB
LSTDEV: TLZ F,(FL.HEA) ;NEW HEADING FOR THIS LOOP
SETZM ACTDEV ;CLEAR COUNT OF ACTIVE DEVICES
SKIPA P1,DEVLST ;POINT TO FIRST DDB
LSTD.1: HLRZ P1,DEVSER(P1) ;STEP TO NEXT DDB
LSTD.2: JUMPE P1,CPOPJ ;DONE WITH OTHER DDBS
CAIL P1,MONITR ;THIS DDB IN THE MONITORS HIGH SEGMENT
JRST [MOVEI P1,DEVSER-MONITR(P1) ;YES, MUST BE "DSKDDB"
PEEK P1, ;SO JUST GET ADDRESS OF NEXT DDB
HLRZ P1,P1 ;SINCE NOBODY CAN OWN THIS ONE (NOT WRITTABLE)
JRST LSTD.2] ;AND LOOK SOME MORE
LDB T2,[POINT 6,DEVTYP(P1),9] ;GET DEVICE TYPE
CAIE T2,.TYPTY ;DON'T CARE ABOUT PTY'S
CAIN T2,.TYDSK ;OR DSK'S
JRST LSTD.1 ;TRY NEXT DDB
CAIN T2,.TYMPX ;OR MPX'S
JRST LSTD.1 ;TRY NEXT DDB
LDB T1,[POINT 3,DEVCPU(P1),2] ;GET CPU OWNING THE DEVICE
CAME T1,P2 ;SAME AS CPU BEING REMOVED
JRST LSTD.1 ;TRY NEXT DDB
LDB T1,[POINT 9,DEVJOB(P1),35] ;GET JOB NUMBER USING DEVICE
JUMPE T1,LSTD.1 ;OK, NOBODY USING IT
CAIN T2,.TYTTY ;IS THIS SOMEBODYS TTY
JRST [CAMN P1,@TTYTAB ;CHECK IT CONTROLLS A JOB OR JUST INITED
JRST LSTD.1 ;CONTROLLING, WILL DETACH JOB IN ANOTHER ROUTINE
JRST LSTD.3] ;GIVE WARNING
MOVSI T2,(DCVNET) ;GET "NETWORK" BIT
TDNE T2,DEVCHR(P1) ;IS THIS A NETWORK DEVICE
JRST LSTD.1 ;TRY NEXT DDB
MOVEI T2,IOACT ;"IO IN PROGRESS" BIT
TDNE T2,DEVIOS(P1) ;IS IT
AOS ACTDEV ;YES, COUNT NUMBER OF ACTIVES DEVICES
LSTD.3: TLNN F,(FL.CHK) ;WANT OUTPUT OR JUST ADDING UP ACTDEV
JRST LSTD.1 ;JUST ADDING, GET NEXT DDB
TLON F,(FL.HEA) ;HEADING GIVEN
PUSHJ P,[OUTSTR [ASCIZ/% Following Jobs will lose devices:/]
JRST CRPOPJ] ;OUTPUT HEADING
OUTCHR [11] ;ALIGN OUTPUT
PUSHJ P,DECOUT ;OUTPUT JOB NUMBER
OUTSTR [ASCIZ/ has /] ;PRETTY IT UP
MOVE T1,DEVNAM(P1) ;GET DEVICE OWNED
PUSHJ P,SIXOUT ;OUTPUT IT
PUSHJ P,CRPOPJ ;ADD CRLF
JRST LSTD.1 ;AND LOOK AT ANOTHER DEVICE
;SUBROUTINE TO REMOVE ALL DISK KONTROLLERS ON A CPU
;CALL: P2 = CPU TO WORRY ABOUT (FL.WAC ALREADY ON)
;RTNS: P1 = CLOBBERED
; CALLS DKONCM SO FL.NCD MAY BE LIT
RADKON: SETZ P1, ;INDICATE FIRST CALL
RADK.1: MOVE T1,P1 ;GET PREVIOUS KONTROLLER ADDRESS
PUSHJ P,FNDKON ;FIND NEXT DISK KONTROLLER
JUMPE T1,CPOPJ ;DONE WITH DISK KONTROLLERS
MOVE P1,T1 ;COPY KONTROLLER ADDRESS
LDB T1,[POINT 3,KONCPU(P1),2] ;GET CPU OWNING KONTROLLER
CAMN T1,P2 ;THIS ON THE CPU BEING REMOVED
PUSHJ P,[TLNE F,(FL.CHK) ;CHECKING OR DOING
JRST DKONCM ;CHECKING
JRST DKONRM] ;REMOVING
JRST RADK.1 ;DO NEXT KONTROLLER
;SUBROUTINE TO STEP THROUGH THE DISK KONTROLLER DATA BLOCKS
;CALL: T1 = PREVIOUS KONTROLLER OR 0 FOR FIRST TIME
;RTNS: T1 = NEXT KONTROLLER OR 0 IF NO MORE
; T2 = SIXBIT NAME OF KONTROLLER
FNDKON: JUMPE T1,[MOVE T1,FIRDSK ;GET FIRST UNIT IN SYSTEM
JRST FNDK.2] ;AND STEP TO ITS KONTROLLER
MOVSI T2,-10 ;NUMBER OF POSSIBLE UNITS ON KONTROLLER
HRRI T2,KONTAB(T1) ;AND WHERE THEY ARE
SETZ T1, ;COMPUTE LAST UNIT
FNDK.1: HRRZ T3,0(T2) ;ADDRESS OF UNIT
CAILE T3,(T1) ;SINCE "XCHANGE" COULD RE-ORDER THE TABLE
MOVE T1,T3 ;FIND HIGHEST ADDRESS AS LAST UNIT BY SYSINI
AOBJN T2,FNDK.1 ;LOOK AT ALL POSSIBLE UNITS
HLRZ T1,UNISYS(T1) ;POINTER TO NEXT UNIT IN SYSTEM
JUMPE T1,CPOPJ ;LAST UNIT IN SYSTEM
FNDK.2: HLLZ T2,UNINAM(T1) ;NAME OF UNIT
HRRZ T1,UNIKON(T1) ;LINK BACK TO KONTROLLER
POPJ P, ;AND RETURN
;SUBROUTINE TO REMOVE A DISK KONTROLLER
;CALL: P1 = KONTROLLER ADDRESS
; P2 = CPU # IF FL.WAC IS ON
;RTNS: FL.NCD ON IF CANNOT REMOVE THE KONTROLLER
DKONCM: MOVSI T2,-10 ;MAX NUMBER OF UNITS ON KONTROLLER
HRRI T2,KONTAB(P1) ;THE START OF THE UNIT TABLE
DKON.1: SKIPN T3,0(T2) ;NEXT UNIT ON KONTROLLER
JRST DKON.3 ;NONE, ALL DONE
SKIPN UNILOG(T3) ;THE LOGICAL NAME OF STRUCTURE MOUNTED
JRST DKON.3 ;OK TO REMOVE UNIT IF NOTHING SPINNING
HRRZ T1,UNI2ND(T3) ;SOMETHING THERE, SEE IF DUAL PORTED
JUMPE T1,DKON.2 ;CANNOT REMOVE IF NO OTHER PATH
TLNN F,(FL.WAC) ;WORRYING ABOUT REMOVING A CPU
JRST DKON.3 ;NO, OK TO REMOVE IT
MOVE T1,UNIKON(T1) ;GET KONTROLLER FOR 2ND PATH
LDB T1,[POINT 3,KONCPU(T1),2] ;GET CPU OF 2ND KONTROLLER
SKIPGE CPUSTS(T1) ;IS THE CPU OF 2ND KONTROLLER DOWN
JRST DKON.2 ;YES, TELL OPERATOR TO DISMOUNT PACK
CAME T1,P2 ;ON SAME CPU AS ONE BEING REMOVED
JRST DKON.3 ;NO, OK TO REMOVE IT
DKON.2: PUSH P,T2 ;SAVE AOBJN FOR UNITS
TLON F,(FL.HEA) ;ALREADY GIVE HEADER
PUSHJ P,[OUTSTR [ASCIZ/? Following Packs MUST be dismounted:/]
JRST CRPOPJ] ;NO, GIVE HEADER NOW
OUTCHR [11] ;OUTPUT A TAB TO ALIGN
MOVE T1,UNILOG(T3) ;POINT TO STRUCTURE NAME
PUSHJ P,SIXOUT ;OUTPUT STR NAME
OUTSTR [ASCIZ/ on /]
MOVE T1,UNINAM(T3) ;GET DRIVE NAME
PUSHJ P,SIXOUT ;OUTPUT THAT
PUSHJ P,ERRXIT ;END LINE, LIGHT ERROR BIT
POP P,T2 ;RESTORE AOBJN TO KONTROLLER
DKON.3: AOBJN T2,DKON.1 ;DO NEXT UNIT
TLNE F,(FL.NCD!FL.CHK) ;OK TO REALLY REMOVE THE UNITS
POPJ P, ;NO, RETURN NOW
DKONRM: MOVSI T5,-10 ;NUMBER OF UNITS POSSIBLE
HRRI T5,KONTAB(P1) ;AND WHERE THEY ARE
DKON.4: SKIPN T4,0(T5) ;NEXT UNIT ON THE KONTROLLER
JRST DKON.6 ;NONE, ALL DONE
LDB T1,[POINT 2,UNIDES(T4),8] ;GET UNIT STATUS CODE
TLNE F,(FL.ADD) ;ADD OR REMOVE COMMAND
JRST [CAIE T1,UNVDWN ;ADD, IS UNIT DOWN (DETACHED)
JRST DKON.6 ;NO, ALREADY USABLE
MOVEI T1,[ASCIZ/ATTACH /] ;ADD
JRST DKON.5] ;GO ATTACH THE UNIT
CAIN T1,UNVDWN ;IS UNIT ALREADY DETACHED
JRST DKON.6 ;YES, DON'T DO IT AGAIN
MOVEI T1,[ASCIZ/DETACH /] ;REMOVE
DKON.5: PUSHJ P,PTYSTR ;OUTPUT THAT
MOVE T1,UNINAM(T4) ;GET UNIT TO ATTACH/DETACH
PUSHJ P,PTYSIX ;OUTPUT THAT
PUSHJ P,PTYCLF ;END THE COMMAND LINE
DKON.6: AOBJN T5,DKON.4 ;AND GET THE REST
POPJ P, ;ALL DONE
;SUBROUTINE TO SET UP CPU STATUS TABLE
SETCPU: MOVE T1,[.STCPU,,SP.CR0!SP.CR1!SP.CR2!SP.CR3!SP.CR4!SP.CR5]
SETUUO T1, ;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 T1,-6 ;MAX CPUS
SETC.1: MOVSI T2,(T1) ;CPUN TO LH
LSH T2,1 ;*2 FOR GETTAB
ADD T2,[%CCPTR&777777,,.GTSLF]
GETTAB T2, ;GET BASE OF CDB CONSTANTS = CDB ADDRESS
HALT . ;WHAT
TLNN T2,(SL.MAX) ;IS MAX FOR GETTAB = 0
JRST [MOVSI T2,(1B0!1B1) ;YES, MARK IT NON-EXISTANT
JRST SETC.2] ;AND STORE DATA
MOVEI T3,(T1) ;COPY CPU NUMBER
LSH T3,1 ;*2 FOR GETTAB
ADD T3,[%CVRUN] ;GET .CPRUN
GETTAB T3, ;GET IT
HALT . ;WHAT
TLNE T3,(1B2) ;IS IT DETACHED
JRST [HRLI T2,(1B0!1B2) ;YES, MARK IT
JRST SETC.2] ;STORE DATA
TLNE T3,(1B1) ;IS CPU ALREADY STOPPED
JRST [HRLI T2,(1B0) ;YES, MARK IT DOWN
JRST SETC.2] ;STORE DATA
TLZ T2,-1 ;CPU IS UP, CLEAR STATUS BITS
AOS CPUN ;COUNT A RUNNING CPU
GTTAB T3,%CNBCP ;FIND THE BOOT CPU
CAIN T3,(T1) ;THIS IT
TLO T2,(1B4) ;YES, REMEMBER THAT
MOVEI T3,1B35 ;GET A BIT FOR CPU0
LSH T3,(T1) ;POSITION IT CORRECTLY
IORM T3,CPURUN ;LIGHT A RUNNING CPU BIT
MOVEI T3,(T1) ;COPY CPU NUMBER
LSH T3,1 ;*2 FOR GETTAB
ADD T3,[%CCOKP] ;GET THE OK WORD
GETTAB T3, ;GET IT
HALT . ;WHAT
SKIPG T3 ;IS THE CPU REALLY RUNNING
AOSA CPUOK ;YES, COUNT THE CPU
TLO T2,(1B3) ;NO, REMEMBER THIS ONE ISN'T
SETC.2: MOVEM T2,CPUSTS(T1) ;UPDATE STATUS
AOBJN T1,SETC.1 ;AND TRY ANOTHER CPU
POPJ P, ;RETURN
END CONFIG ;END OF THIS PROGRAM