Trailing-Edge
-
PDP-10 Archives
-
BB-D868C-BM
-
4-sources/mountr.mac
There are 35 other files named mountr.mac in the archive. Click here to see a list.
;<4.UTILITIES>MOUNTR.MAC.59, 19-Feb-80 16:04:20, Edit by KONEN
;TCO 4.2605 - Get disk characteristics after mounting structure
;Correct structure mount count in accounting record
;<4.UTILITIES>MOUNTR.MAC.57, 28-Jan-80 13:36:35, Edit by KONEN
;REMOVE STRUCTURE STATUS CODE FROM DISK STATUS CODE IN DDSCIH
;<4.UTILITIES>MOUNTR.MAC.56, 4-Jan-80 13:52:52, Edit by KONEN
;ADD ERCAL FOR MSTR IN STRDM3:
;<4.UTILITIES>MOUNTR.MAC.55, 3-Jan-80 15:26:17, EDIT BY R.ACE
;UPDATE COPYRIGHT DATE
; UPD ID= 87, SNARK:<4.UTILITIES>MOUNTR.MAC.54, 5-Dec-79 05:30:43 by R.ACE
;TCO 4.2587 - CLASSIFY TAPES WITHOUT HDR1'S AS UNLABELED
;<4.UTILITIES>MOUNTR.MAC.53, 26-Nov-79 09:22:01, Edit by KONEN
;Return to user immediately if structure not found for dismount
;<4.UTILITIES>MOUNTR.MAC.52, 1-Nov-79 17:05:52, Edit by KONEN
;MAKE MOVES IMMEDIATE IN REARNG
;<4.UTILITIES>MOUNTR.MAC.51, 1-Nov-79 14:09:29, EDIT BY R.ACE
;MOVE TEST FLAG TO WRITE-PROTECTED AREA
;CHANGES TO STOP ROUTINE: REMOVE CHECKS FOR RUNNING DETACHED,
;IF CRASH FILE WASN'T CREATED, MAKE SURE MOUNTR SAYS WHY
;TCO 4.2560 - DEFEND AGAINST HUNG TAPE DRIVES CAUSING MOUNTR TO HANG
;<4.UTILITIES>MOUNTR.MAC.50, 30-Oct-79 14:38:37, Edit by KONEN
;PUT STRUCTURE ACCOUNTING BACK IN
;<4.UTILITIES>MOUNTR.MAC.49, 25-Oct-79 14:07:07, Edit by KONEN
;CHECK IF STRUCTURE JUST MADE AVAILABLE IN DDSCIH
;<4.UTILITIES>MOUNTR.MAC.46, 20-Oct-79 15:30:13, EDIT BY R.ACE
;TCO 4.2539 - GIVEN A TOPS-20 TAPE OWNED BY USER X, PERMIT OPERATOR TO
;SCRATCH IT WITH IDENTIFY COMMAND ONLY FOR A SCRATCH REQUEST FROM USER X
;ALSO... CHANGE TEXT IN ACKNOWLEDGMENT TO OPR DELETE COMMAND
;FROM "DELETED" TO "CANCELED"
;<4.UTILITIES>MOUNTR.MAC.45, 16-Oct-79 07:10:39, EDIT BY R.ACE
;TCO 4.2526 - CHANGE MONX01 TO MREQ31
;<4.UTILITIES>MOUNTR.MAC.44, 3-Oct-79 09:23:14, EDIT BY R.ACE
;TCO 4.2508 - WRITE-PROTECT PURE PROCEDURE
;REPLACE LOST INSTRUCTIONS IN SYTSET ROUTINE
;<4.UTILITIES>MOUNTR.MAC.43, 2-Oct-79 09:31:35, EDIT BY R.ACE
;TCO 4.2505 - USE GJ%OLD IN GTJFN IN GTINAM ROUTINE
;<4.UTILITIES>MOUNTR.MAC.42, 28-Sep-79 20:45:51, EDIT BY R.ACE
;TCO 4.2501 - GIVE SPECIFIC-VOLID REQUESTS PRIORITY OVER SCRATCH
;<4.UTILITIES>MOUNTR.MAC.41, 25-Sep-79 14:28:12, Edit by KONEN
;CORRECT IGNORED STRUCTURE CODE
;<4.UTILITIES>MOUNTR.MAC.40, 18-Sep-79 12:48:01, Edit by KONEN
;Implement SET DISK-DRIVE command for OPR
;<4.UTILITIES>MOUNTR.MAC.39, 12-Sep-79 13:00:57, Edit by KONEN
;CHECK FOR DRIVE NOT BEING WRITE-LOCKED IN DDSCIH
;ALLOW FOR NEW DRIVES COMING ON-LINE TO BE INSERTED BETWEEN OLD DRIVES
;<4.UTILITIES>MOUNTR.MAC.38, 31-Aug-79 14:53:59, EDIT BY R.ACE
;FIX DIAGNOSTIC WHEN IDENTIFYING REQUEST THAT IS WAITING FOR WTOR
;<4.UTILITIES>MOUNTR.MAC.37, 30-Aug-79 14:43:53, EDIT BY R.ACE
;TCO 4.2432 - CLEAR SJ%REW IF SJ%OFS IS SET
;<4.UTILITIES>MOUNTR.MAC.36, 21-Aug-79 07:21:33, EDIT BY R.ACE
;FIXUPS FOR EXTENDED ADDRESSING
;<4.UTILITIES>MOUNTR.MAC.35, 27-Jul-79 13:32:18, EDIT BY R.ACE
;TCO 4.2353 - CHANGE PS:<SYSTEM>DEVICE-STATUS.BIN TO SYSTEM:...
;<4.UTILITIES>MOUNTR.MAC.34, 26-Jul-79 06:52:04, EDIT BY R.ACE
;TCO 4.2346 - FIX VOLUME-PROTECTION BUGS FOR TOPS-20 TAPES
;<4.UTILITIES>MOUNTR.MAC.33, 24-Jul-79 16:44:49, EDIT BY R.ACE
;TCO 4.2343 - CHANGE "UNLOAD" TO "DISMOUNT TAPE" IN WARNING MESSAGE
;<4.UTILITIES>MOUNTR.MAC.32, 24-Jul-79 12:53:23, Edit by KONEN
;PRINT PHYSICAL NAME OF STRUCTURE IF NOT SAME AS ALIAS
;<4.UTILITIES>MOUNTR.MAC.31, 15-Jul-79 11:31:40, Edit by KONEN
;MOUNT ALL POSSIBLE STRUCTURES AT MOUNTR STARTUP
;TCO 4.2324 - ALLOW MAX TOPS-20 RECORD SIZE WHEN READING FOR VOL1
;<4.UTILITIES>MOUNTR.MAC.30, 27-Jun-79 12:53:06, Edit by KONEN
;MORE OF SAME
;<4.UTILITIES>MOUNTR.MAC.29, 26-Jun-79 15:22:04, Edit by KONEN
;<4.UTILITIES>MOUNTR.MAC.28, 20-Jun-79 17:14:12, Edit by KONEN
;CORRECT CODE FOR MULTI-PACK STRUCTURES COMING ON-LINE
;<4.UTILITIES>MOUNTR.MAC.27, 20-Jun-79 05:58:15, EDIT BY R.ACE
;CHANGE "LINE" TO "TERMINAL" IN OPR MESSAGES (%U)
;<4.UTILITIES>MOUNTR.MAC.26, 19-Jun-79 17:49:02, Edit by KONEN
;CORRECT LOSING ALIAS FOR DISMOUNT IF ASKING OPR IF OK TO PROCEED
;<4.UTILITIES>MOUNTR.MAC.25, 13-Jun-79 09:57:41, EDIT BY R.ACE
;COSMETIC FIXUPS, REMOVE ";" FROM TITLE COMMAND FOR JUDY
;TELL OPR IF WRONG VOLID KEYED IN FOR AVR-OFF DRIVE
;<4.UTILITIES>MOUNTR.MAC.24, 12-Jun-79 08:51:22, Edit by KONEN
;<4.UTILITIES>MOUNTR.MAC.23, 11-Jun-79 09:34:52, Edit by KONEN
;CHANGE OPR MESSAGE TITLE FOR SHOW DISK STATUS
;<4.UTILITIES>MOUNTR.MAC.22, 3-Jun-79 17:07:14, EDIT BY R.ACE
;ALWAYS REWRITE LABELS OF SCRATCH TAPE WHEN GIVING IT TO USER
;<4.UTILITIES>MOUNTR.MAC.21, 24-May-79 07:32:43, EDIT BY R.ACE
;MAKE CLRTAP RETURN +1 IF GDSTS TIMES OUT, +2 OTHERWISE
;<4.UTILITIES>MOUNTR.MAC.20, 23-May-79 18:17:45, Edit by KONEN
;MORE WORK ON MATCHING STRUCTURE REQUESTS TO PACK ON-LINE
;<4.UTILITIES>MOUNTR.MAC.19, 22-May-79 06:26:05, EDIT BY R.ACE
;FIX BUGS IN PREVIOUS EDIT:
;1 - CHANGE MOVE ac,RSBLT TO LOAD ac,RSBLT
;2 - ADD INDEX REGISTER (RSB) TO MOVE ac,RSBUNO
;<4.UTILITIES>MOUNTR.MAC.18, 20-May-79 18:06:11, EDIT BY R.ACE
;REMOVE VOLUME-INITIALIZATION FEATURES THAT WERE USED BY CHECKD
;ADD DECTAPE SUPPORT UNDER NOSHIP
;<4.UTILITIES>MOUNTR.MAC.17, 26-Apr-79 05:07:15, EDIT BY R.ACE
;FIX REQRSB - PRESERVE T1 ON +1 RETURN, SCAN ABORTED RSB'S TOO
;<4.UTILITIES>MOUNTR.MAC.16, 25-Apr-79 06:03:12, EDIT BY R.ACE
;MAKE STACK LARGER
;<4.UTILITIES>MOUNTR.MAC.15, 19-Apr-79 11:45:43, EDIT BY R.ACE
;SET UP RSBASN BEFORE CALLING MOLOC
;<4.UTILITIES>MOUNTR.MAC.14, 19-Apr-79 09:17:26, Edit by KONEN
;OPR DISMOUNT COMMAND, CHANGE OPR DISPLAY FOR DISMOUNT REQUESTS
;<4.UTILITIES>MOUNTR.MAC.13, 18-Apr-79 07:36:28, EDIT BY R.ACE
;FIX BUGS IN OPR SWITCH COMMAND
;<4.UTILITIES>MOUNTR.MAC.12, 17-Apr-79 10:42:34, EDIT BY R.ACE
;ADD JOB MESSAGES
;ADD SUPPORT FOR SWITCH COMMAND IN OPR
;IMPLEMENT NEW SHOW STATUS COMMANDS, REMOVE SHOW PARAMETERS
;DON'T WTO FOR MOUNT IF REQUESTED VOLUME IS BEING AVR'ED
;REWORK TMC TO USE %-SEQUENCES INSTEAD OF SUBROUTINES
;PERMIT UNNAMED UNLABELED SCRATCH TAPES
;REJECT "SET TAPE INIT" IF A USER HAS THE DRIVE
;ADD GJ%ACC TO GTJFN CALLS TO PREVENT TAMPERING BY OTHER FORKS
;INHIBIT ERROR LOGGING FOR REWIND OPERATIONS
;REMOVE WTOR FOR MOUNTING TAPES
;ADD SUPPORT FOR OPR COMMANDS: IDENTIFY, DELETE
;<4.UTILITIES>MOUNTR.MAC.11, 22-Mar-79 15:58:13, EDIT BY R.ACE
;MAKE MOUNTR SAVE CRASH FILES IN SPOOL DIRECTORY
;<4.UTILITIES>MOUNTR.MAC.10, 21-Mar-79 07:03:07, EDIT BY R.ACE
;IN EIHR, CLEAR IRETF BEFORE DEBRKING TO SCHEDULER
;SPECIAL-CASE UNLABELED VOLUME-SWITCH TO THE SAME VOLUME
;ADD SPECIAL CODE FOR CALLING STOP WHEN P IS KNOWN TO BE BAD
;<4.UTILITIES>MOUNTR.MAC.9, 17-Mar-79 08:53:07, EDIT BY R.ACE
;DON'T SEND IPCF REPLIES (TELUSR) FOR OPR-GENERATED REQUESTS
;<4.UTILITIES>MOUNTR.MAC.8, 16-Mar-79 09:28:51, EDIT BY R.ACE
;CHANGE MULTIPLE-MOUNTR PROTECTION TO WORK FROM MDA SYSTEM PID
;MISCELLANEOUS DISPLAY CLEANUP
;<4.UTILITIES>MOUNTR.MAC.7, 15-Mar-79 14:25:23, EDIT BY R.ACE
;ADD MULTIPLE-MOUNTR PROTECTION
;REMOVE REQUIREMENT FOR VOLID WHEN INITIALIZING UNLABELED TAPES
;SET R%PRIV IN GORSB
;ADD SUPPORT FOR TAPE-RECOGNITION-ERRORS COMMAND IN CONFIG FILE
;REMOVE TAPE-MOUNT DEFAULTS
;MAKE ACCOUNTING CHANGES
;ACCEPT OPNX8 IN MTAOPx, FIX BUSY-WTB CRASHES AGAIN
;<4.UTILITIES>MOUNTR.MAC.6, 8-Mar-79 16:26:16, EDIT BY R.ACE
;ADD CODE TO PARSE "SET TAPE INIT" MESSAGE FROM OPR/ORION/QUASAR
;<4.UTILITIES>MOUNTR.MAC.5, 7-Mar-79 11:52:12, EDIT BY R.ACE
;STOP COMND JSYS CRASHES WHEN PARSING NULL RESPONSE FROM WTOR
;<4.UTILITIES>MOUNTR.MAC.4, 7-Mar-79 07:44:04, EDIT BY R.ACE
;FIX BUGS IN KVI
;<4.UTILITIES>MOUNTR.MAC.3, 6-Mar-79 12:24:44, EDIT BY R.ACE
;ADD MISSING CALL TO MTARJF IN AVR
;FIX LOGIC IN DDSADD/DDSMCH THAT CAUSED AREQ TO BE CALLED WITH RSB/ 0
;<4.UTILITIES>MOUNTR.MAC.2, 5-Mar-79 15:03:12, EDIT BY R.ACE
;FIX MISCELLANEOUS BUGS, LAY GROUNDWORK FOR SET TAPE INITIALIZE,
;LET OPERATOR RESPOND TO TAPE MOUNT WITH DRIVE NAME
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1979,1980 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
SEARCH MONSYM,MACSYM,ACTSYM,SERCOD,GLXMAC,QSRMAC,ORNMAC
.REQUIRE SYS:MACREL
EXTERN .JBOPS ;JOBDAT CELL COMMANDEERED FOR TEST FLAG
EXTERN .JBSA ;LH/ ADDR OF 1ST LOCATION AFTER PROGRAM
EXTERN .JBSYM ;POINTER TO SYMBOL TABLE FOR DDT
EXTERN .RLEND ;LAST LOCATION IN MACREL
SALL
.DIRECTIVE FLBLST ;SUPPRESS ASCIZ MACHINE CODE EXPANSION
TITLE MOUNTR
; VERSION NUMBER EQUATES
VMAJOR==4 ;MAJOR VERSION #
VMINOR==0 ;MINOR VERSION #
VEDIT==63 ;EDIT #
VWHO==0 ;GROUP WHO LAST EDITED (0=DEC DEVELOPMENT)
VERS==<VWHO>B2+<VMAJOR>B11+<VMINOR>B17+VEDIT
SUBTTL PREFACE
COMMENT ^
MOUNTR - THIS PROGRAM CONTOLS MAGNETIC TAPE AND STRUCTURE MOUNT
REQUEST QUEUEING AND PROCESSING UNDER TOPS-20. IT INTERFACES WITH
QUASAR, ORION, NON-PRIVILEGED USER-MODE PROGRAMS (TOPS-20 EXEC,
ET AL), AND THE SYSTEM OPERATOR.
ACCUMULATOR CONVENTIONS:
F, Q1-Q3, AND SPECIAL-PURPOSE AC'S (E.G. MTA) ARE PRESERVED BY
SUBROUTINES, WHILE T1-T4 AND CX MAY BE CLOBBERED. SOME MACROS USE
CX TO LINK TO DRIVERS, SO BE CAREFUL. F CONTAINS PROGRAM-WIDE
FLAGS THAT MAY BE MODIFIED AND TESTED BY ANY ROUTINE THAT NEEDS
THEM. MACRO DRIVERS GENERALLY PRESERVE T1-T4.
INTERRUPT-LEVEL OPERATION:
TO MINIMIZE THE POSSIBILITY OF TIMING BUGS, PROCESSING AT
INTERRUPT LEVEL WILL BE KEPT TO AN ABSOLUTE MINIMUM. INTERRUPTS
FROM SOURCES EXTERNAL TO THE PROGRAM ARE PROCESSED AT PRIORITY
LEVEL 3 (DEFINED BY "PRIEXT" EQUATE). TYPICALLY, THE ONLY ACTION
TAKEN IS TO REQUEST THAT THE SCHEDULER PASS CONTROL TO THE
APPROPRIATE EVENT PROCESSOR AT NON-INTERRUPT LEVEL (ALL EVENT
PROCESSOR TAGS END IN "IH"). DEBRK IS DONE EITHER TO THE
INTERRUPTED PC OR TO THE BEGINNING OF THE SCHEDULER, DEPENDING
UPON THE SETTING OF THE FLAG, IRETF. ALL PANIC-CHANNEL ACTIVITY
OCCURS AT LEVEL 1 (DEFINED BY "PRIPAN" EQUATE).
ASSOCIATED PROCESSES:
THIS PROGRAM RELIES UPON SEVERAL OTHER SYSTEM TASKS TO PERFORM
ITS FUNCTIONS. THESE ARE REFERRED TO AS "ASSOCIATED PROCESSES",
ABBREVIATED A/P. PARALLEL A/P TABLES ARE MAINTAINED IN CORE,
INDEXED BY THE A/P INDEX (A SMALL INTEGER ASSOCIATED WITH THE
PROCESS).
RESTARTABILITY:
IT IS INTENDED THAT MOUNTR BE RESTARTABLE WITH A MINOR IMPACT
UPON SYSTEM PERFORMANCE. SOME OF THE PROBLEMS CREATED BY
RESTARTING THE PROGRAM ARE:
1. ALL STRUCTURE-MOUNT AND ACCOUNTING INFORMATION IS LOST.
2. ALL ACCOUNTING INFORMATION FOR CURRENTLY-MOUNTED TAPES IS
LOST.
3. ALL TAPE-MOUNT REQUESTS THAT HAVE NOT BEEN ASSIGNED AN MT
DEVICE ARE LOST.
4. USERS WITH MT DEVICES MAY CONTINUE USING THEM, BUT ANY
ATTEMPT AT A VOLUME SWITCH WILL RECEIVE AN ERROR.
WRITE-PROTECTION:
AS A SECURITY MEASURE, THE WRTP ROUTINE WRITE-PROTECTS AS MUCH
OF MOUNTR AS POSSIBLE TO GUARD AGAINST STRAY STORES.
EXTENDED ADDRESSING:
THOUGH MOUNTR WILL NOT NORMALLY RUN IN A NON-ZERO SECTION, ITS
CODE SHOULD NOT PRECLUDE THAT POSSIBILITY. BECAUSE OF THE VARIETY
OF JSYS'S IT EXECUTES, MOUNTR CAN BE OF GREAT ASSISTANCE IN
TESTING THE USER-MODE EXTENDED ADDRESSING FEATURES OF THE MONITOR.
TEST MODE:
PLACING A NON-ZERO VALUE IN LOCATION 137 (.JBOPS) BEFORE STARTING
MOUNTR WILL CAUSE MOUNTR TO RUN IN A TESTING MODE (THIS
CONVENTION IS ADOPTED FROM THE GALAXY WORLD). THE ESSENTIAL
DIFFERENCES FROM LIVE MODE ARE THAT MOUNTR WILL TALK TO PRIVATE
GALAXY COMPONENTS, AND IT WILL REFRAIN FROM DOING THINGS (E.G.,
ASSIGNING MTA DEVICES) THAT WOULD INTERFERE WITH THE OPERATION OF
THE REAL MOUNTR.
^
SUBTTL PROGRAM-WIDE MACROS
; MACRO TO PROVIDE A VALUE 1 GREATER THAT IT DID THE LAST TIME
DEFINE NEXT <NEXT$ ;;GIVE CURRENT VALUE
NEXT$==NEXT$+1 ;;INCREMENT IT
>
; MACRO TO DEFINE OFFSETS TO FIELDS WITHIN A MEMORY BLOCK
DEFINE FLDDEF (FLDSYM,FLDLEN) <
FLDSYM==FLDPTR ;;DEFINE FIELD-OFFSET SYMBOL
FLDPTR==FLDPTR+FLDLEN ;;RESERVE ROOM FOR FIELD
>
; SAVEQ MACRO - WORKS LIKE SAVEAC <Q1,Q2,Q3>
; SAVET MACRO - WORKS LIKE SAVEAC <T1,T2,T3,T4>
; STAKT MACRO - WORKS LIKE ASUBR WITH NO ARGUMENTS, DOESN'T USE AC15
; Tn ON STACK MAY BE REFERENCED AS CTn
DEFINE SAVEQ <JSP CX,SAVEQR>
DEFINE SAVET <JSP CX,SAVETR>
DEFINE STAKT <JSP CX,STAKTR>
DEFINE CT1<-4(P)> ;CALLER'S T1
DEFINE CT2<-3(P)> ;CALLER'S T2
DEFINE CT3<-2(P)> ;CALLER'S T3
DEFINE CT4<-1(P)> ;CALLER'S T4
; ASSEMBLY-CONTROL
DEFINE PRINT1(PR1) <IF1 <PRINTX PR1>> ;PRINTX FOR PASS1 ONLY
; MACRO TO DEFINE ASSOCIATED-PROCESS TABLES
DEFINE APTABL <
APENT QSR ;;QUASAR
APENT ORN ;;ORION
>
; MACROS TO GENERATE BYTE POINTERS TO FIELDS IN LBUF2
; LPTR(ARG) - BYTE POINTER TO FIELD FOR LDB/DPB
; ILPTR(ARG) - BYTE POINTER TO FIELD FOR ILDB/IDPB
; ARGUMENT IS BYTE POSITION OF FIELD (VALUE BETWEEN 1 AND 80)
DEFINE LPTR (LCP1)
<POINT 7,LBUF2+<LCP1+4>/5-1,<LCP1-<<LCP1-1>/5*5>>*7-1>
DEFINE ILPTR (LCP1)
<POINT 7,LBUF2+<LCP1+3>/5-1,<LCP1-<<LCP1+3>/5-1>*5>*7-8>
; CONDITIONAL ASSEMBLY MACROS FOR "NOSHIP" CODE
IFNDEF SHIPSW,<SHIPSW==-1>
DEFINE NOSHIP<IFE SHIPSW>
; MACROS TO GENERATE CALLS TO ASCIZ TEXT MESSAGE COMPOSER
DEFINE TMCT (TMCTA) <
MOVEI CX,[ASCIZ\TMCTA\] ;;GET ADDRESS OF FORMATTING STRING
CALL TMCT0 ;;CALL FORMATTING ROUTINE
>
DEFINE TMCTR (TMCTA) <
JSP CX,TMCT0 ;;POINT CX AT STRING AND CALLRET TMCT0
ASCIZ\TMCTA\
>
; MACROS TO ABORT USER MOUNT REQUEST - RSB ADDRESS MUST BE IN RSB AC
DEFINE ABTREQ (ABTCOD,ABTFLG<0>) <
CALL AREQ ;;CALL ABORT ROUTINE
EXP ABTCOD+ABTFLG
>
DEFINE ABTRET (ABTCOD,ABTFLG<0>) <
CALL ARET ;;CALL ABORT-AND-RET ROUTINE
EXP ABTCOD+ABTFLG
>
ABT%OP==1B0 ;OPERATOR RESPONSE IS PRESENT
ABT%IN==1B1 ;ABTCOD IS ADDRESS OF LOC CONTAINING CODE
; MACRO TO EXECUTE AND TIME OUT I/O JSYS
DEFINE IOXCT (IOJSYS,IOERR,IOTIMO) <
CALL IOXCTR ;;CALL DRIVER ROUTINE
IOJSYS ;;JSYS TO BE EXECUTED
XWD IOERR,IOTIMO ;;ERROR ADDRESS, TIMEOUT ADDRESS
>
; MACRO TO CREATE AND INIT STACK AREA AND QSB AC FOR QUEUE SCAN
; ARGUMENT IS ADDRESS OF QUEUE DESCRIPTOR BLOCK (QDB)
DEFINE QSCANI (QDBADR) <
JSP CX,QSCNIR ;;CALL DRIVER
SETZ QDBADR ;;QDB ADDRESS IN IFIW FORMAT
>
; MACRO TO MARK PLACES THAT HAVE TO CHANGE IF MORE LABEL TYPES ARE ADDED
DEFINE MAXLT <IFN .LTMAX-4,<IF2 <PRINTX LABEL TYPE ADDED>>>
SUBTTL EQUATES
; IT IS EXPECTED THAT THE EQUATES ON THIS PAGE MAY CHANGE TO
; REFLECT CHANGES IN TOPS-20 OR IN THE REQUIREMENTS OF THIS PROGRAM
; TABLE OF VALID TOPS-20 DENSITIES INDEXED BY MONSYM DENSITY CODE
DEFINE DENLST <
0 ;;ZEROTH ENTRY UNUSED
^D200 ;;.SJDN2
^D556 ;;.SJDN5
^D800 ;;.SJDN8
^D1600 ;;.SJD16
^D6250 ;;.SJD62
>
; MISCELLANEOUS
POLINT==^D120 ;NUMBER OF SECONDS BETWEEN MAGTAPE POLLS
MAXACC==400 ;NUMBER OF ACCOUNTING-BLOCKS
MAXDSK==20 ;MAXIMUM # OF DISK DRIVES SUPPORTED
MAXMRQ==200 ;MAXIMUM # OF MOUNT REQUESTS
MAXMT==100 ;MAXIMUM # OF MT DEVICES
MAXMTA==100 ;MAXIMUM # OF MTA DEVICES
ANSV=="3" ;ANSI LABELING STANDARD VERSION NUMBER
DECV=="1" ;DEC LABELING STANDARD VERSION NUMBER
PDLEN==140 ;LENGTH OF PUSH-DOWN LIST (WORDS)
RMKLEN==30 ;MAXIMUM SIZE (WORDS) OF ASCIZ MOUNT REMARK
DSFPGS==1 ;# OF PAGES IN DEVICE-STATUS FILE
SYRMSZ==40 ;MAX WORDS IN SYSERR MSG EXCLUDING HEADER
IFNDEF TST,<TST==0> ;1=TEST VERSION, 0=REAL VERSION
SYRHSZ==4 ;# OF WORDS IN SYSERR ENTRY HEADER
MOSTAL==.MODVT+1 ;LENGTH OF .MOSTA MTOPR ARGUMENT BLOCK
; ACCUMULATOR DEFINITIONS
F=0 ;FLAGS
T1=1 ;TEMPORARY
T2=2 ;TEMPORARY
T3=3 ;TEMPORARY
T4=4 ;TEMPORARY
Q1=5 ;PRESERVED
Q2=6 ;PRESERVED
Q3=7 ;PRESERVED
MTA=10 ;ADDRESS OF MTA STATUS BLOCK
DSK=10 ;ADDRESS OF DISK STATUS BLOCK
RSB=11 ;ADDRESS OF USER REQUEST STATUS BLOCK
MT=12 ;ADDRESS OF MT STATUS BLOCK
STR=12 ;ADDRESS OF STRUCTURE STATUS BLOCK
QSB=13 ;ADDRESS OF QUEUE-SCAN BLOCK
ACC=14 ;ADDRESS OF ACCOUNT BLOCK
CX=16 ;USED BY SUPPORT CODE
P=17 ;PUSH-DOWN POINTER
; DEFINITIONS OF BITS IN FLAG REGISTER (F)
IRETF==1B35 ;1 = EXTERNAL INTERRUPTS DEBRK TO SCHEDULER
MRMSF==1B34 ;1 = DO MRECV
MRPGF==1B33 ;1 = DO MRECV IN PAGE MODE
ABORTF==1B32 ;1 = ABORTED REQUEST(S) EXIST IN RSB QUEUE
NOMTF==1B31 ;1 = MT SHORTAGE EXISTS
JTOAF==1B30 ;1 = JSYS TIMER ARMED
TALCF==1B29 ;1 = TAPE-DRIVE ALLOCATION BY SETSPD
POLLF==1B28 ;1 = MAGTAPE POLLING IN PROGRESS
INITF==1B27 ;1 = IN INITIALIZATION SEQUENCE
CDENF==1B26 ;1 = ^D INTERRUPT ENABLED (^D SCHEDULES DDT)
ARGF==1B25 ;1 = ARGUMENT PRESENT (TMCT0 ROUTINE)
; PSI PRIORITY EQUATES (IN ORDER OF DESCENDING PRIORITY)
PRIPAN==1 ;PANIC (CRASH) HANDLERS
PRIEXT==3 ;EXTERNAL INTERRUPTS
; DEFINITION OF ASSOCIATED PROCESS INDICES
DEFINE APENT (X) <.AP'X==NEXT>
NEXT$==0 ;INITIALIZE VARIABLE
APTABL ;DEFINE SYMBOLS OF FORM .APxxx AS A/P INDICES
APNUM==NEXT$ ;# OF ASSOCIATED PROCESSES
;DEFINITIONS FOR COMND JSYS
CMKEY==<.CMKEY>B8 ;PARSE A KEYWORD
CMNOI==<.CMNOI>B8 ;PARSE A GUIDE WORD
CMCFM==<.CMCFM>B8 ;CONFIRM
CMFLD==<.CMFLD>B8 ;PARSE AN ARBITRARY FIELD
; OTHER EQUATES
DAYSEC==^D60*^D60*^D24 ;# OF SECONDS IN A DAY (NEVER CHANGES)
DSFSZ==DSFPGS*1000 ;# OF WORDS IN DEVICE-STATUS FILE
LBLSIZ==^D80 ;SIZE OF TAPE LABELS IN FRAMES
LB7WDS==<LBLSIZ+4>/5 ;LENGTH IN WORDS OF 7-BIT-BYTE LABEL
LB8WDS==<LBLSIZ+3>/4 ;LENGTH IN WORDS OF 8-BIT-BYTE LABEL
MTNAV==1 ;MTRSB VALUE THAT INDICATES MT NOT AVAILABLE
USRLH==500000 ;LEFT HALF OF USER NUMBER WORD
.MNTDT==77 ;REQUEST TYPE FOR DECTAPE-MOUNT
; OFFSETS OF LABEL FIELDS (VALUES IN THE RANGE 1-80)
V1VID==^D5 ;VOL1 - VOLUME IDENTIFIER
V1ACS==^D11 ;VOL1 - ACCESSIBILITY
V1SCD==^D25 ;VOL1 - SYSTEM CODE
V1OWN==^D38 ;VOL1 - OWNER IDENTIFIER
V1INAM==^D41 ;VOL1 - INSTALLATION NAME (ANSI, TOPS-20)
V1INME==^D42 ;VOL1 - INSTALLATION NAME (EBCDIC)
TPNMSZ==^D10 ;VOL1 - LENGTH OF V1INAM AND V1INME FIELDS
V1DECV==^D51 ;VOL1 - DEC STANDARD VERSION #
V1ANSV==^D80 ;VOL1 - ANSI STANDARD VERSION #
V2PRO==^D5 ;VOL2 - PROTECTION CODE
V2PPN==^D11 ;VOL2 - PROJECT-PROGRAMMER NUMBER
V2OWN==^D23 ;VOL2 - OWNER'S NAME
V2OWNL==^D39 ;VOL2 - LENGTH OF OWNER'S NAME
H1SET==^D22 ;HDR1 - FILE SET IDENTIFIER (SETNAME)
H1CRE==^D42 ;HDR1 - CREATION DATE
H1EXP==^D48 ;HDR1 - FILE EXPIRATION DATE
H1ACS==^D54 ;HDR1 - ACCESSIBILITY
H2PRO==^D38 ;HDR2 - PROTECTION CODE (TOPS-20 ONLY)
SUBTTL DATA STRUCTURES
; DEVICE STATUS FILE
; ==================
; TOPS-20 DEVICE STATUS IS KEPT IN SYSTEM:DEVICE-STATUS.BIN. IT
; IS MAINTAINED AND EXAMINED SOLELY BY THIS PROGRAM. ITS PURPOSE IS
; TO PRESERVE SYSTEM PERIPHERAL DEVICE STATUS ACROSS RELOADS. THE
; FILE IS TREATED AS A MONOLITHIC SET OF PAGES THAT IS MAPPED IN
; ITS ENTIRETY INTO THE AREA DSBUF, WHICH HAS THIS FORMAT:
; !=====================================!
; DSB.CK ! CHECKSUM OF FILE !
; !-------------------------------------!
; DSB.PS ! APR SERIAL NUMBER !
; !-------------------------------------!
; DSB.NE ! # OF ENTRIES IN FILE (n) !
; !-------------------------------------!
; DSB.EO ! !
; \ ENTRY 1 \
; ! !
; !-------------------------------------!
; ! . !
; \ . \
; ! . !
; !-------------------------------------!
; ! !
; \ ENTRY n \
; ! !
; !=====================================!
; ENTRY SIZE IS FIXED, SET BY THE EQUATE FOR DSFESZ
; ALL ENTRIES BEGIN AS FOLLOWS:
;
; WORD 0 - DEVICE TYPE CODE
; WORD 1 - DEVICE IDENTIFIER (UNIQUE WITHIN DEVICE TYPE)
;MAGNETIC TAPE ENTRIES:
; WORD 0 = DEVICE TYPE (.DVMTA)
; WORD 1 = TOPS-20 DEVICE DESIGNATOR
;DISK DRIVE ENTRIES:
; WORD 0 - DEVICE TYPE (.DVDSK)
; WORD 1 - CHANNEL,,DRIVE
MTS.SF==2 ;STATUS FLAGS
MTS%AV==1B0 ;1 = AVAILABLE FOR SYSTEM USE
DSFESZ==3 ;SIZE OF DEVICE-STATUS FILE ENTRIES (WORDS)
; WTB - WRITE-TO-OPERATOR-WITH-REPLY BLOCK
; ========================================
; WHEN A ROUTINE MUST ISSUE A MESSAGE TO THE OPERATOR AND RECEIVE A
; RESPONSE, IT CALLS THE BTWTOR ROUTINE. BTWTOR SENDS A WTOR
; REQUEST TO ORION, BUILDS A WTB, AND PLACES THE WTB ON A QUEUE OF
; OUTSTANDING WTOR REQUESTS. WHEN THE OPERATOR'S RESPONSE IS
; RECEIVED FROM ORION, INWTOR DEQUEUES THE WTB AND CALLS THE
; ROUTINE SPECIFIED IN T1 OF THE BTWTOR CALL WITH:
; T1/ BYTE POINTER TO ASCIZ REPLY FROM OPERATOR
; T2/ ADDRESS OF WTB
; !=======================================================!
;WTBLNK ! WTB QUEUE LINKAGE WORD !
; !-------------------------------------------------------!
;WTBCOD ! ACKNOWLEDGMENT CODE FOR THIS MESSAGE !
; !-------------------------------------------------------!
;WTBENT ! ORIGINATOR'S ROUTINE ADDRESS (BTWTOR T1) !
; !=======================================================!
FLDPTR==0
FLDDEF WTBLNK,1 ;QUEUE LINKAGE WORD
FLDDEF WTBCOD,1 ;ORION ACKNOWLEDGMENT CODE
FLDDEF WTBENT,1 ;ORIGINATOR'S ROUTINE ADDRESS
WTBSIZ==FLDPTR ;SIZE OF WTB
; TAPE MOUNT REQUEST STATUS BLOCK
; ===============================
; !=======================================================!
;RSBLNK ! QUEUE LINKAGE WORD !
; !-------------------------------------------------------!
;RSBIFL ! INTERNAL FLAGS !
; !-------------------------------------------------------!
;RSBUFL ! USER-SUPPLIED FLAGS !
; !-------------------------------------------------------!
;RSBMC1 ! USER'S JOB NUMBER ! REQUEST TYPE !
; !-------------------------------------------------------!
;RSBMC2 !CURRENT STATE OR ERROR CODE! ADDR OF ACCOUNT BLOCK !
; !-------------------------------------------------------!
;RSBITN ! INTERNAL TASK NUMBER FROM QUASAR !
; !-------------------------------------------------------!
;RSBUNO ! USER'S USER NUMBER !
; !-------------------------------------------------------!
;RSBPID ! USER'S PID !
; !-------------------------------------------------------!
;RSBCOD ! USER'S ACKNOWLEDGEMENT CODE !
; !-------------------------------------------------------!
;RSBRNM ! SIXBIT MOUNT REQUEST NAME !
; !-------------------------------------------------------!
;RSBWTB ! !
; \ WRITE-TO-OPERATOR-WITH-REPLY BLOCK (WTB) \
; ! !
; !-------------------------------------------------------!
;RSBACT ! !
; \ USER'S ACCOUNT STRING \
; ! !
; !-------------------------------------------------------!
;RSBRMK ! !
; \ USER'S REMARK \
; ! !
; !=======================================================!
;RSBSSN ! USER-SUPPLIED VOLUME SET NAME (SIXBIT) !
; !-------------------------------------------------------!
;RSBASN ! ACTUAL VOLUME SET NAME (SIXBIT) !
; !-------------------------------------------------------!
;RSBVLS ! QUEUE DESCRIPTOR BLOCK FOR VOLID LIST !
; !-------------------------------------------------------!
;RSBMT1 ! DENSITY ! DRIVE TYPE ! LABEL TYPE ! 0 !
; !-------------------------------------------------------!
;RSBMT2 ! ADDR OF MT STATUS BLOCK ! VOLUME PROTECTION CODE !
; !-------------------------------------------------------!
;RSBMT3 ! CURRENT VOLID INDEX ! 0 !
; !=======================================================!
; USER TAPE MOUNT REQUESTS THAT ARE RECEIVED FROM QUASAR ARE
; TRANSFORMED UPON ARRIVAL INTO A FIXED-FORMAT REQUEST BLOCK,
; DESCRIBED BELOW. WHEN A GIVEN MOUNT REQUEST IS BEING REFERENCED,
; RSB POINTS TO THE FIRST WORD OF THE BLOCK.
FLDPTR==0
FLDDEF RSBLNK,1 ;LINKAGE TO NEXT ENTRY IN QUEUE
FLDDEF RSBIFL,1 ;INTERNAL FLAGS
R%PRIV==1B0 ;USER IS PRIVILEGED
R%ORES==1B1 ;OPERATOR RESPONSE PRESENT
R%WVL==1B2 ;VOLUME LABELS SHOULD BE WRITTEN
R%ONV==1B3 ;OPERATOR WAS NOTIFIED OF VOLID LIST
R%OPR==1B4 ;REQUEST FROM OPR
R%DSM==1B5 ;DISMOUNT REQUEST
R%ONR==1B6 ;MOUNT-REQUEST MESSAGE SENT TO OPERATOR
FLDDEF RSBUFL,1 ;USER-DEFINED FLAGS
FLDDEF RSBMC1,1 ;MISCELLANEOUS DATA
FLDDEF RSBMC2,1 ;MISCELLANEOUS DATA
FLDDEF RSBITN,1 ;QUASAR INTERNAL TASK NUMBER
FLDDEF RSBUNO,1 ;USER'S USER NUMBER
FLDDEF RSBPID,1 ;USER'S PID
FLDDEF RSBCOD,1 ;USER'S ACKNOWLEDGMENT CODE
FLDDEF RSBRNM,1 ;MOUNT REQUEST NAME (SIXBIT)
FLDDEF RSBWTB,WTBSIZ ;WTOR BLOCK
FLDDEF RSBACT,10 ;USER'S ACCOUNT STRING (ASCIZ)
FLDDEF RSBRMK,RMKLEN ;USER'S REMARK (ASCIZ)
RSBCSZ==FLDPTR ;SIZE OF AREA COMMON TO ALL RSB'S
FLDDEF RSBSSN,1 ;USER-SUPPLIED VOLUME SET NAME (SIXBIT)
FLDDEF RSBASN,1 ;ACTUAL VOLUME SET NAME (SIXBIT)
FLDDEF RSBVLS,1 ;QUEUE DESCR BLOCK FOR VOLID LIST
FLDDEF RSBMT1,1 ;MISCELLANEOUS DATA
FLDDEF RSBMT2,1 ;MISCELLANEOUS DATA
FLDDEF RSBMT3,1 ;MISCELLANEOUS DATA
MTRSBS==FLDPTR ;SIZE OF TAPE MOUNT RSB
DEFSTR (RSBJNO,RSBMC1(RSB),17,18) ;USER'S JOB NUMBER
DEFSTR (RSBTYP,RSBMC1(RSB),35,18) ;REQUEST TYPE CODE
DEFSTR (RSBSTE,RSBMC2(RSB),17,18) ;CURRENT STATE OF REQUEST
DEFSTR (RSBACC,RSBMC2(RSB),35,18) ;ADDRESS OF ACCOUNT BLOCK
DEFSTR (RSBDEN,RSBMT1(RSB),8,9) ;DENSITY
DEFSTR (RSBDRV,RSBMT1(RSB),17,9) ;DRIVE TYPE
DEFSTR (RSBLT,RSBMT1(RSB),26,9) ;LABEL TYPE
DEFSTR (RSBMT,RSBMT2(RSB),17,18) ;MT STATUS BLOCK ADDRESS
DEFSTR (RSBVPR,RSBMT2(RSB),35,18) ;VOLUME PROTECTION CODE
DEFSTR (RSBCV,RSBMT3(RSB),17,18) ;INDEX TO CURRENT VOLID
NEXT$==0 ;DEFINE MAGTAPE REQUEST STATES
RST.IN==NEXT ;RSB BEING INITIALIZED
RST.WV==NEXT ;WAITING FOR VOLID KEYIN
RST.WM==NEXT ;WAITING FOR TAPE MOUNT
RST.AC==NEXT ;ACTIVE (USING VOLUME)
;STATE CODES .GE. .ERBAS IMPLY THAT THE REQUEST IS ABORTED
ABRTNR==.ERBAS ;ABORTED, NO RESPONSE TO USER
;DECTAPE RSB DEF'S
RSBDTA==RSBASN ;DECTAPE DEVICE DESIGNATOR
; WHEN THE "SET TAPE-DRIVE INITIALIZE" OPR COMMAND IS USED TO
; INITIALIZE TAPES, A SPECIAL RSB WITH R%OPR SET IS ALLOCATED
; AND ATTACHED TO THE MTA VIA A FAKE MT STATUS BLOCK WITHIN
; THE RSB. SPECIAL RSB FIELDS REQUIRED FOR THIS FUNCTION WILL
; OVERLAY THE RSBACT FIELD WHICH IS IGNORED HERE.
; SPECIAL RSB FIELDS FOR OPR-REQUESTED VOLUME INITIALIZATION:
RSBICT==RSBACT+0 ;# OF VOLUMES TO INITIALIZE
RSBIVI==RSBACT+1 ;NUMERIC VOLID INCREMENT
RSBIVL==RSBACT+2 ;CURRENT VOLID BEING INITIALIZED
RSBIVN==RSBACT+3 ;INTEGER VOLID
RSBIMT==RSBACT+4 ;FAKE MT STATUS BLOCK
; STRUCTURE MOUNT REQUEST STATUS BLOCK
; ====================================
; !=======================================================!
;RSBLNK ! QUEUE LINKAGE WORD !
; !-------------------------------------------------------!
;RSBIFL ! INTERNAL FLAGS !
; !-------------------------------------------------------!
;RSBUFL ! USER-SUPPLIED FLAGS !
; !-------------------------------------------------------!
;RSBMC1 ! USER'S JOB NUMBER ! REQUEST TYPE !
; !-------------------------------------------------------!
;RSBMC2 !CURRENT STATE OR ERROR CODE! ADDR OF ACCOUNT BLOCK !
; !-------------------------------------------------------!
;RSBITN ! INTERNAL TASK NUMBER FROM QUASAR !
; !-------------------------------------------------------!
;RSBUNO ! USER'S USER NUMBER !
; !-------------------------------------------------------!
;RSBPID ! USER'S PID !
; !-------------------------------------------------------!
;RSBCOD ! USER'S ACKNOWLEDGEMENT CODE !
; !-------------------------------------------------------!
;RSBRNM ! SIXBIT MOUNT REQUEST NAME !
; !-------------------------------------------------------!
;RSBWTB ! !
; \ WRITE-TO-OPERATOR-WITH-REPLY BLOCK (WTB) \
; ! !
; !-------------------------------------------------------!
;RSBACT ! !
; \ USER'S ACCOUNT STRING \
; ! !
; !-------------------------------------------------------!
;RSBRMK ! !
; \ USER'S REMARK \
; ! !
; !=======================================================!
;RSBSTN ! STRUCTURE NAME (SIXBIT) !
; !-------------------------------------------------------!
;RSBSTA ! STRUCTURE ALIAS (SIXBIT) !
; !-------------------------------------------------------!
;RSBMS1 ! ADDR OF STR STATUS BLOCK ! 0 !
; !=======================================================!
FLDPTR==RSBCSZ ;SET POINTER TO END OF COMMON SECTION
FLDDEF RSBSTN,1 ;STRUCTURE NAME (SIXBIT)
FLDDEF RSBSTA,1 ;STRUCTURE ALIAS (SIXBIT)
FLDDEF RSBMS1,1 ;MISCELLANEOUS DATA
STRSBS==FLDPTR ;SIZE OF STRUCTURE-MOUNT RSB
DEFSTR (RSBSS,RSBMS1(RSB),17,18) ;STR STATUS BLOCK ADDR
; SET RSBSIZ = MAX(MTRSBS,STRSBS)
RSBSIZ==MTRSBS
IFG STRSBS-MTRSBS,<RSBSIZ==STRSBS>
; MTA STATUS BLOCK
; ================
; EACH MTA DEVICE SUPPORTED BY THE SYSTEM HAS A STATUS BLOCK THAT
; CONTAINS VARIOUS PIECES OF DEVICE-DEPENDENT INFORMATION. THE MTA
; AC CONTAINS A POINTER TO THE FIRST WORD OF THE BLOCK THAT BELONGS
; TO THE MTA DEVICE CURRENTLY BEING SERVICED.
; !=======================================================!
;MTAVOL ! VOLID OF CURRENTLY-MOUNTED VOLUME !
; !-------------------------------------------------------!
;MTASET ! SETNAME OF CURRENTLY-MOUNTED VOLUME !
; !-------------------------------------------------------!
;MTAIDV ! VOLID FROM IDENTIFY COMMAND !
; !-------------------------------------------------------!
;MTAFLG ! SINGLE-BIT FLAGS !
; !-------------------------------------------------------!
;MTAFIL ! JFN ! GTJFN COUNT !
; !-------------------------------------------------------!
;MTAP1 ! ! STATE ! LABEL TYPE ! DENSITY !
; !-------------------------------------------------------!
;MTAP2 ! MT STATUS BLOCK ADDRESS ! REWIND END-ACTION ADDRESS !
; !-------------------------------------------------------!
;MTASDN ! SUPPORTED DENSITIES ! DRIVE TYPE CODE !
; !-------------------------------------------------------!
;MTAV1 ! !
; \ IMAGE OF VOL1 LABEL ON TAPE \
; ! (ASCII OR EBCDIC, 8-BIT BYTES) !
; !-------------------------------------------------------!
;MTAV2 ! !
; \ IMAGE OF VOL2 LABEL ON TAPE \
; ! (ASCII OR EBCDIC, 8-BIT BYTES) !
; !=======================================================!
; DEFINITIONS OF FIELDS WITHIN MTA STATUS BLOCK
FLDPTR==0
FLDDEF MTAVOL,1 ;CURRENT MTA VOLID (SIXBIT), 0 IF NONE
FLDDEF MTASET,1 ;CURRENT MTA SETNAME (SIXBIT), 0 IF NONE
FLDDEF MTAIDV,1 ;QUEUE LINKAGE WORD
FLDDEF MTAFLG,1 ;SINGLE-BIT FLAGS
MA%LOD==1B0 ;DRIVE IS LOADED
MA%OPN==1B1 ;JFN IS OPEN
MA%AVE==1B2 ;AVR ENABLED
MA%AVS==1B3 ;AVR SUPPORTED FOR THIS DRIVE
MA%WEN==1B4 ;WRITE PERMITTED
MA%SCR==1B5 ;VOLUME IS SCRATCH
MA%UXV==1B6 ;UNEXPIRED LABELED VOLUME
MA%VMG==1B7 ;VOLUME-MOUNTED MESSAGE GIVEN TO OPERATOR
MA%ULP==1B8 ;UNLOAD DRIVE WHEN REWIND COMPLETES
MA%OPF==1B9 ;OVERWRITE-PROTECTION FLAG, IF SET:
; ANSI - VOLUME MAY NOT BE OVERWRITTEN
; TOPS-20 - NON-OWNER MAY NOT OVERWRITE
FLDDEF MTAFIL,1 ;FILE STATUS
FLDDEF MTAP1,1 ;DEFSTR-DEFINED DATA
FLDDEF MTAP2,1 ;DEFSTR-DEFINED DATA
FLDDEF MTASDN,1 ;DEFSTR-DEFINED DATA
FLDDEF MTAV1,LB8WDS ;IMAGE OF VOL1 LABEL ON TAPE
FLDDEF MTAV2,LB8WDS ;IMAGE OF VOL2 LABEL ON TAPE
MTASZ==FLDPTR ;SIZE OF MTA STATUS BLOCK IN WORDS
DEFSTR (MTAJFN,MTAFIL(MTA),17,18) ;JFN
DEFSTR (MTAJCT,MTAFIL(MTA),35,18) ;JFN-IN-USE COUNT
DEFSTR (MTASTE,MTAP1(MTA),17,9) ;CURRENT STATE OF DRIVE
; MTASTE/ 0 IF AND ONLY IF MTA NOT ASSIGNED TO MY JOB (VIA ASND)
S.UNAV==0 ;UNAVAILABLE TO MOUNTR
S.AV==1 ;AVAILABLE FOR USE BY USERS
S.INIT==2 ;INITIALIZING TAPE VOLUMES
DEFSTR (MTALT,MTAP1(MTA),26,9) ;LABEL TYPE
DEFSTR (MTADEN,MTAP1(MTA),35,9) ;DENSITY
DEFSTR (MTAMT,MTAP2(MTA),17,18) ;MT STAT BLK ADDR OR 0 IF NONE
DEFSTR (MTAREA,MTAP2(MTA),35,18) ;REWIND END-ACTION SCHEDULE ADDR
DEFSTR (MTADRV,MTASDN(MTA),35,18) ;DRIVE TYPE
; MT STATUS BLOCK
; ===============
; EACH MT DEVICE SUPPORTED BY THE SYSTEM HAS A STATUS BLOCK THAT
; CONTAINS DEVICE-RELATED INFORMATION. THE MT AC POINTS TO THE
; FIRST WORD OF THE STATUS BLOCK OF THE MT CURRENTLY BEING SERVICED.
; !=======================================================!
;MTP1 ! ADDR OF MTA STATUS BLOCK !ADDR OF REQUEST STATUS BLK !
; !=======================================================!
; DEFINITIONS OF FIELDS WITHIN MT STATUS BLOCK
FLDPTR==0
FLDDEF MTP1,1 ;DEFSTR-DEFINED DATA
MTSZ==FLDPTR ;SIZE OF MT STATUS BLOCK
DEFSTR (MTMTA,MTP1(MT),17,18) ;MTA STATUS BLOCK ADDRESS
DEFSTR (MTRSB,MTP1(MT),35,18) ;REQUEST STATUS BLK ADDRESS
; DISK STATUS BLOCK
; =================
;EACH DISK ON THE SYSTEM HAS A STATUS BLOCK THAT CONTAINS INFORMATION
;ABOUT THAT DRIVE. THE DSK AC CONTAINS A POINTER TO THE FIRST WORD
;OF THE BLOCK THAT BELONGS TO THE DISK CURRENTLY BEING SERVICED.
; !=======================================================!
;DSKSTN ! SIXBIT STRUCTURE NAME !
; !-------------------------------------------------------!
;DSKSTA ! SIXBIT STRUCTURE ALIAS !
; !-------------------------------------------------------!
;DSKLNK ! QUEUE LINKAGE !
; !-------------------------------------------------------!
;DSKFLG ! STATUS OF UNIT !
; !-------------------------------------------------------!
;DSKNS ! LOGICAL UNIT NUMBER ! NUMBER OF UNITS !
; !-------------------------------------------------------!
;DSKP1 ! 0 !
; !-------------------------------------------------------!
;DSKP2 ! STR STATUS BLOCK ADDRESS ! CONTROLLER NUMBER !
; !-------------------------------------------------------!
;DSKNUM ! CHANNEL NUMBER ! DRIVE NUMBER !
; !=======================================================!
; DEFINITIONS OF FIELDS WITHIN DISK STATUS BLOCK
FLDPTR==0
FLDDEF DSKSTN,1 ;CURRENT FILE STRUCTURE NAME(SIXBIT) - 0 IF NONE
FLDDEF DSKSTA,1 ;CURRENT FILE STRUCTURE ALIAS(SIXBIT)-0 IF NONE
FLDDEF DSKLNK,1 ;QUEUE LINKAGE WORD
FLDDEF DSKFLG,1 ;STATUS OF UNIT
;ITEMS BELOW DEFINED IN MONSYM
; MS%MNT=1B0 ;UNIT IS PART OF A MOUNTED STRUCTURE
; MS%DIA==1B2 ;UNIT IS BEING USED BY ON-LINE DIAGNOTIC PROGRAM
; MS%OFL==1B3 ;UNIT IS OFF LINE
; MS%ERR==1B4 ;UNIT HAS ERROR THAT WAS DETECTED DURING READING
; MS%BBB==1B5 ;UNIT HAS A BAD BAT BLOCK
; MS%WLK==1B6 ;UNIT IS WRITE-LOCKED
; MS%TYP==777B17 ;TYPE OF DISK UNIT
; .MSRP4==1 ;RP04
; .MSRP5==5 ;RP05
; .MSRP6==6 ;RP06
; .MSRP7==7 ;RP07
FLDDEF DSKNS,1 ;LOGICAL UNIT # WITHIN STR,,# OF UNITS IN STR
FLDDEF DSKP1,1 ;UNUSED
FLDDEF DSKP2,1 ;STR STATUS BLOCK ADDR,,CONTROLLER #(MUST BE -1)
FLDDEF DSKNUM,1 ;CHANNEL NUMBER,,DRIVE NUMBER - 0 IF NONE
DSKSZ==FLDPTR ;SIZE OF DSK STATUS BLOCK
DEFSTR (DSKTYP,DSKFLG,17,11) ;TYPE OF DISK UNIT
DEFSTR (DSKLUN,DSKNS,17,18) ;LOGICAL UNIT NUMBER OF DISK WITHIN STR
DEFSTR (DSKNOU,DSKNS,35,18) ;NUMBER OF DISK UNITS IN STRUCTURE
DEFSTR (DSKSSA,DSKP2,17,18) ;STRUCTURE STATUS BLOCK ADDRESS
DEFSTR (DSKCTR,DSKP2,35,18) ;CONTROLLER NUMBER
DEFSTR (DSKCHN,DSKNUM,17,18) ;CHANNEL NUMBER
DEFSTR (DSKDRV,DSKNUM,35,18) ;DRIVE NUMBER
; STR STATUS BLOCK
; ================
;EACH STRUCTURE HAS A STATUS BLOCK THAT CONTAINS INFORMATION. THE STR
;AC POINTS TO THE FIRST WORD OF THE STATUS BLOCK OF THE STRUCTURE
;CURRENTLY BEING SERVICED.
; !=======================================================!
;STRALI ! SIXBIT STRUCTURE ALIAS !
; !-------------------------------------------------------!
;STRNAM ! SIXBIT STRUCTURE NAME !
; !-------------------------------------------------------!
;STRFLG ! STRUCTURE FLAGS !
; !-------------------------------------------------------!
;STRCNT ! # OF UNITS ! MOUNT COUNT ! ADDR OF REQUEST STATUS BLK!
; !-------------------------------------------------------!
;STRADD ! !
; \ ADDRESS(ES) OF DISK STATUS BLOCK(S) \
; ! !
; !=======================================================!
FLDPTR==0
FLDDEF STRALI,1 ;STRUCTURE ALIAS IN SIXBIT
FLDDEF STRNAM,1 ;STRUCTURE NAME IN SIXBIT
FLDDEF STRFLG,1 ;STRUCTURE STATUS AS DEFINED IN MONSYM
MS%PS==1B0 ;THIS STRUCTURE IS PUBLIC
MS%DIS==1B1 ;STRUCTURE IS BEING DISMOUNTED
MS%DOM==1B2 ;STRUCTURE IS DOMESTIC
MS%PPS==1B3 ;STRUCTURE IS PRIMARY PUBLIC STRUCTURE
MS%INI==1B4 ;STRUCTURE IS BEING INITIALIZED
MS%LIM==1B5 ;STRUCTURE LIMITED TO 2050 SIZES
MS%NRS==1B6 ;STRUCTURE IS NOT REGULATED
MS%MT==1B35 ;STRUCTURE IS MOUNTED
FLDDEF STRCNT,1 ;# OF UNITS IN STR,,RSB ADDR
FLDDEF STRADD,10 ;ADDRESSES OF DISK STRUCTURE BLOCKS
STRSZ==FLDPTR ;SIZE OF STR STATUS BLOCK
DEFSTR (STRUNI,STRCNT,8,9) ;NUMBER OF UNITS IN STRUCTURE
DEFSTR (STRMCT,STRCNT,17,9) ;COUNT OF UNITS MOUNTED IN STRUCTURE
DEFSTR (STRRSB,STRCNT,35,18) ;ADDRESS OF REQUEST STATUS BLOCK
; MAGTAPE ACCOUNT STATUS BLOCK
; ======= ======= ====== =====
;EACH TAPE DISMOUNT CAUSES AN ACCOUNT RECORD TO BE PUT INTO THE SYSTEM
;USAGE FILE. THE ACCOUNT STATUS BLOCK IS MADE WHEN A TAPE IS MOUNTED.
; !=======================================================!
;ACCLNK ! QUEUE LINKAGE !
; !-------------------------------------------------------!
;ACCDD ! DEVICE DESIGNATOR !
; !-------------------------------------------------------!
;ACCNO ! JOB NUMBER ! LINE NUMBER !
; !-------------------------------------------------------!
;ACCUSR ! !
; \ USER NAME \
; ! !
; !-------------------------------------------------------!
;ACCSTG ! !
; \ USER'S ACCOUNT STRING \
; ! !
; !-------------------------------------------------------!
;ACCCRT ! DATE/TIME OF REQUEST CREATION !
; !-------------------------------------------------------!
;ACCSCD ! DATE/TIME WHEN SCHEDULED !
; !-------------------------------------------------------!
;ACCSVT ! DATE/TIME WHEN SERVICED !
; !-------------------------------------------------------!
;ACCEUT ! ELAPSED TIME OF USE !
; !-------------------------------------------------------!
;ACCVID ! VOLUME IDENTIFIER !
; ! !
; !-------------------------------------------------------!
;ACCMC1 !CONTROLLER! LABEL! LABEL ! 0 !
; !-------------------------------------------------------!
;ACCP ! RECORDS READ ! RECORDS WRITTEN !
; !-------------------------------------------------------!
;ACCF ! FRAMES READ ! FRAMES WRITTEN !
; !-------------------------------------------------------!
;ACCFSI ! FILE SET IDENTIFIER !
; !=======================================================!
FLDPTR==0
FLDDEF ACCLNK,1 ;LINKAGE TO NEXT ENTRY IN QUEUE
FLDDEF ACCDD,1 ;DEVICE DESIGNATOR AS DEFINED BY SYSTEM
FLDDEF ACCNO,1 ;USER JOB NUMBER,,USER LINE NUMBER
FLDDEF ACCUSR,10 ;ASCIZ USER NAME
FLDDEF ACCSTG,10 ;USER ACCOUNT STRING
FLDDEF ACCCRT,1 ;DATE AND TIME OF REQUEST CREATION
FLDDEF ACCSCD,1 ;DATE AND TIME REQUEST SERVICED
FLDDEF ACCSVT,1 ;DATE AND TIME WHEN REQUEST SERVICED
FLDDEF ACCEUT,1 ;ELAPSED TIME OF USE
ACCCSZ=FLDPTR ;SIZE OF AREA COMMON TO ALL ACC BLOCKS
FLDDEF ACCVID,2 ;VOLUME IDENTIFIER
FLDDEF ACCMC1,1 ;CONTROLLER TYPE,LABEL TYPE,LABEL STATE
FLDDEF ACCP,1 ;NUMBER OF PHYSICAL RECORDS READ/WRITTEN
FLDDEF ACCF,1 ;NUMBER OF FRAMES READ/WRITTEN
FLDDEF ACCFSI,1 ;FILE SET IDENTIFIER (ASCIZ)
ACCSIZ==FLDPTR ;SIZE OF MAGTAPE ACCOUNT BLOCK
DEFSTR (ACCJN,ACCNO(ACC),17,18) ;USER'S JOB NUMBER
DEFSTR (ACCLN,ACCNO(ACC),35,18) ;USER'S LINE NUMBER
DEFSTR (ACCKT,ACCMC1(ACC),5,6) ;CONTROLLER TYPE
DEFSTR (ACCLT,ACCMC1(ACC),11,6) ;LABEL TYPE
DEFSTR (ACCLS,ACCMC1(ACC),17,6) ;VOLUME LABEL STATE
DEFSTR (ACCPR,ACCP(ACC),17,18) ;NUMBER OF PHYSICAL RECORDS READ
DEFSTR (ACCPW,ACCP(ACC),35,18) ;NUMBER OF PHYSICAL RECORDS WRITTEN
DEFSTR (ACCFR,ACCF(ACC),17,18) ;THOUSANDS OF FRAMES READ
DEFSTR (ACCFW,ACCF(ACC),35,18) ;THOUSANDS OF FRAMES WRITTEN
; STRUCTURE ACCOUNT STATUS BLOCK
; ========= ======= ====== =====
;EACH STRUCTURE DECREMENT CAUSES AN ACCOUNT RECORD TO BE PUT INTO THE
;SYSTEM USAGE FILE. THE ACCOUNT STATUS BLOCK IS MADE WHEN A STRUCURE
;IS INCREMENTED.
; !=======================================================!
;ACCLNK ! QUEUE LINKAGE !
; !-------------------------------------------------------!
;ACCDD ! DEVICE DESIGNATOR !
; !-------------------------------------------------------!
;ACCNO ! JOB NUMBER ! LINE NUMBER !
; !-------------------------------------------------------!
;ACCUSR ! !
; \ USER NAME \
; ! !
; !-------------------------------------------------------!
;ACCSTG ! !
; \ USER'S ACCOUNT STRING \
; ! !
; !-------------------------------------------------------!
;ACCCRT ! DATE/TIME OF REQUEST CREATION !
; !-------------------------------------------------------!
;ACCSCD ! DATE/TIME WHEN SCHEDULED !
; !-------------------------------------------------------!
;ACCSVT ! DATE/TIME WHEN SERVICED !
; !-------------------------------------------------------!
;ACCEUT ! ELAPSED TIME OF USE !
; !-------------------------------------------------------!
;ACCSTN ! STRUCTURE NAME !
; !-------------------------------------------------------!
;ACCMCT ! MOUNT COUNT BEFORE ! MOUNT COUNT AFTER !
; !-------------------------------------------------------!
;ACCMC2 !CONTROLLER! DEVICE! STR ! NUMBER OF UNITS !
; !-------------------------------------------------------!
;ACCFRK ! NUMBER OF JOB FORKS INCREMENTING MOUNT COUNT !
; !=======================================================!
FLDPTR==ACCCSZ ;SET POINTER TO END OF COMMON SECTION
FLDDEF ACCSTN,1 ;ASCIZ STRUCTURE PHYSICAL ID
FLDDEF ACCMCT,1 ;MOUNT COUNT BEFORE,,MOUNT COUNT AFTER
FLDDEF ACCMC2,1 ;CONTROLLER,DEVICE,STR TYPE,# OF UNITS
FLDDEF ACCFRK,1 ;NUMBER OF JOB FORKS INCREMENTING COUNT
DEFSTR (ACCDT,ACCMC2(ACC),11,6) ;DEVICE TYPE
DEFSTR (ACCST,ACCMC2(ACC),17,6) ;STRUCTURE TYPE
DEFSTR (ACCNU,ACCMC2(ACC),35,18) ;NUMBER OF UNITS IN STRUCTURE
DEFSTR (ACCMB,ACCMCT(ACC),17,18) ;MOUNT COUNT BEFORE MOUNTING STR
DEFSTR (ACCMA,ACCMCT(ACC),35,18) ;MOUNT COUNT AFTER DISMOUNTING STR
SUBTTL ADDRESS SPACE ALLOCATION
; MACRO TO ASSIGN LARGE REGIONS OF ADDRESS SPACE
DEFINE ADASN (ADSYM,ADSIZ,ADPAG) <
IFNB <ADPAG>,<ADPTR==<<ADPTR+777>&777000>> ;;PAGE BOUNDARY
ADSYM=ADPTR ;;DEFINE START OF REGION
ADPTR==ADPTR+ADSIZ ;;INCREMENT ALLOCATION POINTER
>
ADLOW==34000 ;START ASSIGNING SPACE AT THIS ADDRESS
ADPTR==ADLOW ;INITIALIZE CURRENT ASSIGNMENT LOCATION
; ASSIGNMENT OF ADDRESS SPACE
ADASN RBUF,1000,PAGE ;BUFFER FOR RECEIVING IPCF MESSAGES
ADASN TBUF,1000,PAGE ;MSEND MESSAGES BUILT HERE
ADASN BADMSG,1000,PAGE ;BAD GALAXY IPCF MESSAGES SAVED HERE
ADASN DSBUF,DSFSZ,PAGE ;DEVICE-STATUS FILE BUFFER PAGE
;NOTE - LBUF1W MUST BE .GE. MAXPPB*1000 (MAXPPB IS DEFINED IN STG)
LBUF1W==30000
ADASN LBUF1,LBUF1W,PAGE ;DUMPI/DUMPO LABEL BUFFER
ADASN SRQ,^D100*3 ;SCHEDULER REQUEST QUEUE
ADASN TMCMSG,1000 ;TEXT MESSAGE COMPOSITION AREA
ATMSIZ==100
ADASN ATMBFR,ATMSIZ ;ATOM BUFFER FOR COMND JSYS
ADASN MTA0,MTASZ*MAXMTA ;MTA STATUS BLOCKS
ADASN MT0,MTSZ*MAXMT ;MT STATUS BLOCKS
ADASN RSB0,<<MAXMRQ+1>*RSBSIZ> ;RSB POOL
ADASN DSKSTB,DSKSZ*MAXDSK ;DSK STATUS BLOCKS
ADASN STRSTB,STRSZ*MAXDSK ;STR STATUS BLOCKS
VOLPN==<MAXMRQ+1>*5 ;AVERAGE 5 VOLIDS PER TAPE REQUEST
ADASN VOLP0,VOLPN*2 ;VOLID STORAGE POOL
STSIZ==100
ADASN STRTBL,STSIZ ;STRUCTURE COMMANDS FOR MOUNTS
ADASN SSCNAM,STSIZ ;STRUCTURE NAMES FOR STATUS CHANGES
IGNLEN==20
ADASN IGNTBL,IGNLEN ;STRUCTURE NAMES TO BE IGNORED
ADASN ACC0,<<MAXACC+1>*ACCSIZ> ;ACCOUNT BLOCK POOL
IFG ADPTR-700000,<PRINT1 <ADDRESS SPACE OVERFLOW>>
; DEVICE STATUS BUFFER EQUATES
DSB.CK==DSBUF ;CHECKSUM WORD
DSB.PS==DSBUF+1 ;APR SERIAL NUMBER
DSB.NE==DSBUF+2 ;# OF ENTRIES IN DEVICE-STATUS FILE
DSB.EO==DSBUF+3 ;ORIGIN OF ENTRY LIST IN BUFFER
SUBTTL MODIFYABLE DATA AREA
; ALL DATA FROM ZROBGN TO ZROEND WILL BE SET TO ZEROS AT STARTUP
ZROBGN: ;BEGINNING OF AUTOMATIC ZERO AREA
NSR: BLOCK 1 ;# OF REQUESTS IN SCHEDULER QUEUE
TDSCF: BLOCK 1 ;.GE. 0 SCHED REQUEST EXISTS FOR TDSCIR
DSFJFN: BLOCK 1 ;DISK-STATUS FILE JFN
MYPID: BLOCK 1 ;SYSTEM MDA PID
MSGSIN: BLOCK 1 ;# OF IPCF MESSAGES RECEIVED
SHORT: BLOCK 1 ;MAXIMUM LENGTH OF NON-PAGE IPCF MESSAGE
MTAN: BLOCK 1 ;NUMBER OF MTA DEVICES ON SYSTEM
MTN: BLOCK 1 ;NUMBER OF MT DEVICES ON SYSTEM
PBACW: BLOCK 1 ;GLOBAL ADDR OF ARGUMENT COUNT WORD
PBBPT: BLOCK 1 ;ADDR OF NEXT BUILDING BLOCK TO BE BUILT
TMCPTR: BLOCK 1 ;BYTE POINTER INTO TMCMSG
TMCTSP: BLOCK 1 ;TMCT0 ROUTINE SOURCE STRING POINTER
TMCWDS: BLOCK 1 ;CURRENT LENGTH OF TMCMSG IN WORDS
WTRQDB: BLOCK 1 ;QDB FOR OUTSTANDING WTOR REQUESTS
ARBQDB: BLOCK 1 ;QDB FOR ACTIVE REQUEST STATUS BLOCKS
IRBQDB: BLOCK 1 ;QDB FOR INACTIVE REQUEST STATUS BLOCKS
FVSQDB: BLOCK 1 ;QDB FOR FREE VOLID SLOTS IN VOLP0
UNIQUE: BLOCK 1 ;UNIQUE VALUE WORD (ACCESSED WITH AOS)
BTFLGS: BLOCK 1 ;.OFLAG WORD FOR WTO'S AND ACK'S
TAPNAM: BLOCK TPNMSZ/5+1 ;INSTALLATION-SUPPLIED NAME FOR VOL1
CRSHAC: BLOCK 20 ;AC'S AT TIME OF CRASH
SSSDAT: BLOCK 2 ;DATA AND ROUTINE ADDRESS FOR DEBUG
LSTERR: BLOCK 1 ;LAST ERROR AT TIME OF CRASH
CSB: BLOCK 12 ;STATE BLOCK FOR COMND JSYS
FDB: BLOCK 4 ;FUNCTION DESCRIPTOR BLOCK FOR COMND
APPID: BLOCK APNUM ;A/P PID TABLE
MRPDB: BLOCK 10 ;PDB FOR MRECV OPERATIONS
TRPDB: BLOCK 4 ;MSEND PDB
PDL: BLOCK PDLEN+1 ;PUSH-DOWN STACK
PDL1: BLOCK 4 ;ALTERNATE PDL - USED BY STOPP ROUTINE
BADP: BLOCK 1 ;CONTENTS OF P WHEN STACK PROBLEM FOUND
SYRHDR: BLOCK SYRHSZ+SYRMSZ ;SYSERR HEADER AND MESSAGE
SYRMSG==SYRHDR+SYRHSZ ;ADDRESS OF SYSERR MESSAGE
COMJFN: BLOCK 1 ;HOLDS HANDLE (JFN) OF COMMANDS FILE
STAMP: BLOCK 1 ;LAST KNOWN WRITE TIME OF COMMANDS FILE
SAVEDP: BLOCK 1 ;USED TO SAVE STACK POINTER FOR REPARSES
SSCDEF: BLOCK 1 ;DEFAULT STR STATUS SETTING
IABQDB: BLOCK 1 ;QDB FOR INACTIVE ACCOUNT BLOCKS
AABQDB: BLOCK 1 ;QDB FOR ACTIVE ACCOUNT BLOCKS
READCL: BLOCK 2 ;DUMPI IOWD LIST FOR READING LABELS
LPC1: BLOCK 2 ;PSI LEVEL 1 FLAGS & PC
LPC2: BLOCK 2 ;PSI LEVEL 2 FLAGS & PC
LPC3: BLOCK 2 ;PSI LEVEL 3 FLAGS & PC
ZROEND==.-1 ;END OF AUTOMATIC ZERO AREA
; CDFLG - DEPOSIT 0 TO DISABLE ^D, DEPOSIT 1 TO ENABLE ^D
CDFLG: EXP -1 ;CONTROL-D ENABLE/DISABLE SWITCH
CFSPEC: ASCIZ/PS:<SPOOL>MOUNTR-CRASH.EXE/ ;CRASH FILESPEC
LBUF2: BLOCK LB7WDS ;7-BIT ASCII REPRESENTATION OF LBUF1
OPRHSZ==12
OPRHDR: BLOCK OPRHSZ ;TEMPORARY TEXT STORAGE
MSTRBK: BLOCK 20 ;PLACE FOR MSTR DSK STATUS ARG BLOCK
MSTNM: BLOCK 2 ;STRUCTURE NAME FOR MSTR IN 7-BIT ASCII
MSTAL: BLOCK 2 ;STRUCTURE ALIAS FOR MSTR IN 7-BIT ASCII
DSFE: BLOCK DSFESZ ;CURRENT DEVICE-STATUS FILE ENTRY
; STORAGE AREA FOR USAGE DATA
; ===========================
JOBNO: BLOCK 1 ;JOB NUMBER
LINO: BLOCK 1 ;LINE NUMBER
USRNAM: BLOCK 10 ;ASCIZ USER NAME
ACOUNT: BLOCK 10 ;ASCIZ ACCOUNT USTING
USTCRT: ;DATE/TIME OF REQUEST CREATION
UMTCRT: BLOCK 1 ;CREATION DATE/TIME OF REQUEST
USTSCD: ;SCHEDULED TIME
UMTSCD: BLOCK 1
USTSRV: ;DATE/TIME WHEN SERVICED
UMTSRV: BLOCK 1 ;SERVICED DATE/TIME
USTEUT: ;ELAPSED USAGE TIME
UMTEUT: BLOCK 1
USTDSP: ;DISPOSITION OF REQUEST
UMTDSP: BLOCK 1
USTTXT: ;OPERATOR/SYSTEM TEXT
UMTTXT: BLOCK 10
USGCSZ==.-JOBNO+1
USTNM: ;STRUCTURE NAME
UMTVID: BLOCK 1 ;MAGTAPE VOLUME IDENTIFIER
USTKTP: ;CONTROLLER TYPE
UMTKTP: BLOCK 1 ;CONTROLLER TYPE
USTDTP: ;DEVICE TYPE
UMTLT: BLOCK 1 ;LABEL TYPE
; 1 = UNLABELED, 2 = ANSI
; 3 = EBCDIC, 4 = DEC
USTSTP: ;STRUCTURE TYPE (3=DOMESTIC,4=FOREIGN)
UMTLS: BLOCK 1 ;LABEL STATUS
; 0 = UNLABLED VOLUME
; 1 = PRIVATE VOLUME
; 2 = SCRATCH VOLUME
; 3 = SCRATCH VOLUME ASSIGNED TO USER
; DURING THIS MOUNT
USTTNP: ;NUMBER OF PACKS IN STRUCTURE
UMTMRD: BLOCK 1 ;MAGTAPE READS
USTMC: ;MOUNT COUNT BEFORE MOUNT
UMTMWR: BLOCK 1 ;MAGTAPE WRITES
USTDC: ;MOUNT COUNT AFTER MOUNT
UMTMRF: BLOCK 1 ;THOUSANDS OF FRAMES READ OF MTA
USTATP: ;ACCESS TYPE
UMTMWF: BLOCK 1 ;THOUSANDS OF FRAMES WRITTEN
UMTFSI: BLOCK 1 ;FILE SET IDENTIFIER
UMTSRE: BLOCK 1 ;NUMBER OF SOFT READ ERRORS
UMTSWE: BLOCK 1 ;NUMBER OF SOFT WRITE ERRORS
UMTHRE: BLOCK 1 ;NUMBER OF HARD READ ERRORS
UMTHWE: BLOCK 1 ;NUMBER OF HARD WRITE ERRORS
UMTVSN: BLOCK 1 ;VISUAL SERIAL NUMBER
USGSIZ==.-JOBNO+1
SUBTTL STATIC DATA AREA
BLOCK 1000 ;GET INTO A NEW PAGE
PURE: ;LOWEST LOCATION IN STATIC DATA AREA
; EVERYTHING BEYOND THIS POINT WILL BE WRITE-PROTECTED BY THE
; ROUTINE WRTP, WHICH IS CALLED IN THE INITIALIZATION PHASE
TSTF: BLOCK 1 ;MODE FLAG: 0=LIVE, 1=TEST MODE
; SOFTWARE INTERRUPT SYSTEM DATA AREAS
; ------------------------------------
LEVTAB: LPC1
LPC2
LPC3
; MACRO TO DEFINE PANIC-CHANNEL INTERRUPT CHNTAB ENTRIES
DEFINE PANIC (PANHDL) <
INTMSK==INTMSK+1B<.-CHNTAB> ;;SET BIT IN CHANNEL MASK
XWD PRIPAN,PANHDL ;;GENERATE CHNTAB ENTRY
>
; MACRO TO DEFINE EXTERNAL INTERRUPT CHNTAB ENTRIES
DEFINE EXTPSI (ENAM,EADR) <
INTMSK==INTMSK+1B<.-CHNTAB> ;;SET BIT IN CHANNEL MASK
ENAM'CN==.-CHNTAB ;;DEFINE CHANNEL# SYMBOL
IFB <EADR>,<
XWD PRIEXT,[CALL EIHR ;;GENERATE CHNTAB ENTRY
EXP ENAM'IH] ;;ENTRY POINT FOR SCHEDULER
> ;;END IFB EADR
IFNB <EADR>,<
XWD PRIEXT,EADR ;;GENERATE CHNTAB ENTRY
> ;;END IFNB EADR
>
INTMSK==0 ;INITIAL VALUE OF INTRPT CHANNEL MASK
CHNTAB:
EXTPSI DDT ;0 - LOAD AND SCHEDULE DDT
0,,0 ;1 - ASSIGNABLE CHANNEL 1
0,,0 ;2 - ASSIGNABLE CHANNEL 2
0,,0 ;3 - ASSIGNABLE CHANNEL 3
0,,0 ;4 - ASSIGNABLE CHANNEL 4
0,,0 ;5 - ASSIGNABLE CHANNEL 5
0,,0 ;6 - ARITHMETIC OVERFLOW
0,,0 ;7 - FLOATING OVERFLOW
0,,0 ;8 - RESERVED
PANIC PANPOV ;9 - PDL OVERFLOW
0,,0 ;10 - END OF FILE
PANIC PANDAE ;11 - DATA ERROR
PANIC PANQTA ;12 - QUOTA EXCEEDED
0,,0 ;13 - RESERVED
0,,0 ;14 - TIME OF DAY (RESERVED)
PANIC PANILI ;15 - ILLEG INSTRUCTION
PANIC PANIRD ;16 - ILLEGAL READ
PANIC PANIWR ;17 - ILLEGAL WRITE
0,,0 ;18 - ILLEGAL EXECUTE (RESERVED)
0,,0 ;19 - INFERIOR FORK TERMINATION
PANIC PANMSE ;20 - MACHINE SIZE EXCEEDED
0,,0 ;21 - TRAP TO USER (RESERVED)
0,,0 ;22 - NONEXISTENT PAGE REFERENCED
0,,0 ;23 - ASSIGNABLE CHANNEL 23
EXTPSI MRCV ;24 - IPCF MESSAGE WAITING
EXTPSI TDSC,TDSCIH ;25 - MTA DEVICE STATUS CHANGE
EXTPSI JTO,JTOIH ;26 - JSYS TIMER EXPIRED
EXTPSI DDSC ;27 - DISK DEVICE STATUS CHANGE
0,,0 ;28 - ASSIGNABLE CHANNEL 28
0,,0 ;29 - ASSIGNABLE CHANNEL 29
0,,0 ;30 - ASSIGNABLE CHANNEL 30
0,,0 ;31 - ASSIGNABLE CHANNEL 31
0,,0 ;32 - ASSIGNABLE CHANNEL 32
0,,0 ;33 - ASSIGNABLE CHANNEL 33
0,,0 ;34 - ASSIGNABLE CHANNEL 34
0,,0 ;35 - ASSIGNABLE CHANNEL 35
; ENTRY VECTOR
ENTVEC: JRST START ;STARTING ADDRESS
JRST DEBUG ;REENTER ADDRESS
LVERS: EXP VERS ;PROGRAM VERSION
ENTVSZ==.-ENTVEC
; TABLE OF SUPPORTED DENSITIES
DENTAB: DENLST ;GENERATE LIST OF DENSITIES
DENMAX==.-DENTAB-1 ;MAXIMUM DENSITY INDEX
; POINTERS TO TEXT STRINGS INDEXED BY LABEL TYPE
LTTXT: 0
[ASCIZ/Unlabeled/]
[ASCIZ/ANSI/]
[ASCIZ/EBCDIC/]
[ASCIZ/TOPS-20/]
MAXLT ;CODE NEEDED HERE IF NEW LABEL TYPE ADDED
; POINTERS TO TEXT STRINGS INDEXED BY DRIVE TYPE
DRVTXT: 0
[ASCIZ/9-TRACK/]
[ASCIZ/7-TRACK/]
; TABLE OF INITIALIZATION ROUTINE ADDRESSES FOR ASSOCIATED PROCESSES;
; ROUTINE IS CALLED DURING PROGRAM INITIALIZATION, AND POSSIBLY
; BY THE RECOVERY ROUTINE IF THE PROCESS CRASHES.
DEFINE APENT (X) <IFIW!X'INI>
APINI: APTABL ;GENERATE LIST OF INIT ROUTINE ADDRS
; TABLE OF IPCF INPUT-MESSAGE PROCESSING ROUTINE ADDRESSES FOR A/P'S;
; ROUTINE IS CALLED WHEN AN IPCF MESSAGE IS RECEIVED FROM A PID THAT
; IS LISTED IN THE APPID TABLE
DEFINE APENT (X) <IFIW!X'MRC>
APMRC: APTABL ;GEN LIST OF IPCF-RECEIVE HANDLER ADDRS
; TEMPLATES FOR USAGE JSYS
; ========================
;STRUCTURE USE RECORD
USGSTR: USENT. (.UTMNT,1,1) ;STRUCTURE USAGE RECORD TYPE
USJNO. (JOBNO) ;JOB NUMBER
USLNO. (LINO) ;LINE NUMBER
USACT. (<-1,,ACOUNT>) ;ACCOUNT
USNM2. (<-1,,USRNAM>) ;USER NAME
USSSI. (USTNM) ;STRUCTURE NAME
USSTP. (USTSTP) ;STRUCTURE TYPE
USTNP. (USTTNP) ;TOTAL NUMBER OF PACKS IN FILE STRUCTURE
USKTP. (USTKTP) ;CONTROLLER TYPE (RH20)
USDTP. (USTDTP) ;DEVICE TYPE (RP04,ETC.)
USDSP. (USTDSP) ;DISPOSITION
USTXT. (<-1,,USTTXT>) ;SYSTEM/OPERATOR TEXT
USCRT. (USTCRT) ;CREATION DATE/TIME OF REQUEST
USSCD. (USTSCD) ;SCHEDULED TIME
USSRV. (USTSRV) ;SERVICED DATE/TIME
USMCT. (USTMC) ;MOUNT COUNT BEFORE MOUNT
USDCT. (USTDC) ;MOUNT COUNT AFTER DISMOUNT
USATP. (USTATP) ;ACCESS TYPE
USEUT. (USTEUT) ;ELAPSED TIME OF USAGE
0 ;END OF RECORD
;TAPE MOUNT RECORD
USGMTA: USENT. (.UTMMT,2,1) ;MAGTAPE USAGE RECORD TYPE
USJNO. (JOBNO) ;JOB NUMBER
USLNO. (LINO) ;LINE NUMBER
USACT. (<-1,,ACOUNT>) ;ACCOUNT
USNM2. (<-1,,USRNAM>) ;USER NAME
USVID. (UMTVID) ;VOLUME IDENTIFIER IN VOL1 LABEL
USMRF. (UMTMRF) ;THOUSANDS OF FRAMES READ
USMWF. (UMTMWF) ;THOUSANDS OF FRAMES WRITTEN
USDSP. (UMTDSP) ;DISPOSITION
USTXT. (<-1,,UMTTXT>) ;SYSTEM/OPERATOR TEXT
USCRT. (UMTCRT) ;CREATION DATE/TIME
USSCD. (UMTSCD) ;SCHEDULED TIME
USSRV. (UMTSRV) ;SERVICED DATE/TIME
USKTP. (UMTKTP) ;CONTROLLER TYPE
USMLT. (UMTLT) ;LABEL TYPE
USMLS. (UMTLS) ;LABEL STATE
USMRD. (UMTMRD) ;NUMBER OF TAPE READS
USMWR. (UMTMWR) ;NUMBER OF TAPE WRITES
USFSI. (UMTFSI) ;FILE SET IDENTIFIER
USSRE. (UMTSRE) ;NUMBER OF SOFT READ ERRORS
USSWE. (UMTSWE) ;NUMBER OF SOFT WRITE ERRORS
USHRE. (UMTHRE) ;NUMBER OF HARD READ ERRORS
USHWE. (UMTHWE) ;NUMBER OF HARD WRITE ERRORS
USVSN. (UMTVSN) ;VISUAL SERIAL NUMBER
USEUT. (UMTEUT) ;ELAPSED TIME OF USAGE
0 ;END OF RECORD
; ASCII-TO-EBCDIC TRANSLATION TABLE
; TABLE IS COMPOSED OF 128 8-BIT BYTES, INDEXED BY THE
; ASCII CHARACTER VALUE
AETT:
BYTE (8)000,001,002,003,067,055,056,057,026,005,045,013,014,015,016,017
BYTE (8)020,021,022,023,074,075,062,046,030,031,077,047,034,035,036,037
BYTE (8)100,117,177,173,133,154,120,175,115,135,134,116,153,140,113,141
BYTE (8)360,361,362,363,364,365,366,367,370,371,172,136,114,176,156,157
BYTE (8)174,301,302,303,304,305,306,307,310,311,321,322,323,324,325,326
BYTE (8)327,330,331,342,343,344,345,346,347,350,351,112,340,132,137,155
BYTE (8)171,201,202,203,204,205,206,207,210,211,221,222,223,224,225,226
BYTE (8)227,230,231,242,243,244,245,246,247,250,251,300,152,320,241,007
; EBCDIC-TO-ASCII TRANSLATION TABLE
; TABLE IS COMPOSED OF 256 7-BIT ASCII BYTES, INDEXED BY THE
; EBCDIC CHARACTER VALUE
XXX==.CHCNZ ;VALUE OF EBCDIC CHARS WITHOUT IMAGES (^Z=SUB)
EATT:
BYTE (7)000,001,002,003,XXX,011,XXX,177,XXX,XXX,XXX,013,014,015,016
BYTE (7)017,020,021,022,023,XXX,XXX,010,XXX,030,031,XXX,XXX,034,035
BYTE (7)036,037,XXX,XXX,XXX,XXX,XXX,012,027,033,XXX,XXX,XXX,XXX,XXX
BYTE (7)005,006,007,XXX,XXX,026,XXX,XXX,XXX,XXX,004,XXX,XXX,XXX,XXX
BYTE (7)024,025,XXX,032,040,XXX,XXX,XXX,XXX,XXX,XXX,XXX,XXX,XXX,133
BYTE (7)056,074,050,053,041,046,XXX,XXX,XXX,XXX,XXX,XXX,XXX,XXX,XXX
BYTE (7)135,044,052,051,073,136,055,057,XXX,XXX,XXX,XXX,XXX,XXX,XXX
BYTE (7)XXX,174,054,045,137,076,077,XXX,XXX,XXX,XXX,XXX,XXX,XXX,XXX
BYTE (7)XXX,140,072,043,100,047,075,042,XXX,141,142,143,144,145,146
BYTE (7)147,150,151,XXX,XXX,XXX,XXX,XXX,XXX,XXX,152,153,154,155,156
BYTE (7)157,160,161,162,XXX,XXX,XXX,XXX,XXX,XXX,XXX,176,163,164,165
BYTE (7)166,167,170,171,172,XXX,XXX,XXX,XXX,XXX,XXX,XXX,XXX,XXX,XXX
BYTE (7)XXX,XXX,XXX,XXX,XXX,XXX,XXX,XXX,XXX,XXX,XXX,XXX,173,101,102
BYTE (7)103,104,105,106,107,110,111,XXX,XXX,XXX,XXX,XXX,XXX,175,112
BYTE (7)113,114,115,116,117,120,121,122,XXX,XXX,XXX,XXX,XXX,XXX,134
BYTE (7)XXX,123,124,125,126,127,130,131,132,XXX,XXX,XXX,XXX,XXX,XXX
BYTE (7)060,061,062,063,064,065,066,067,070,071,XXX,XXX,XXX,XXX,XXX
BYTE (7)XXX,0,0,0,0
;COMMANDS FROM THE COMMAND FILE FOR STRUCTURE MOUNTS FOR COMND JSYS
COMTBL: COMLEN,,COMLEN ;LIST OF LEGAL COMMANDS
[ASCIZ /DOMESTIC/],,[TXO T4,MS%DOM] ;SET UP STR TO BE DOMESTIC
[ASCIZ /FOREIGN/],,[TXZ T4,MS%DOM] ;SET STR TO BE FOREIGN
[ASCIZ /NONREGULATED/],,[TXO T4,MS%NRS] ;SET STR TO BE NONREGULATED
[ASCIZ /REGULATED/],,[TXZ T4,MS%NRS] ;SET STR TO BE REGULATED
COMLEN==.-COMTBL-1 ;NUMBER OF COMMANDS IN TABLE
COMDEF: 1,,1 ;ONLY 1 COMMAND
[ASCIZ /DEFAULT/],,0 ;SET UP DEFAULTS FOR MOUNTING STRS
;NAME OF COMMANDS FILE
COMNAM: ASCIZ /SYSTEM:MOUNTR.CMD/
STRINI: STSIZ ;LENGTH,,MAX (INITIAL SETTING) FOR TBLUK
SSCINI: SSCNAM ;POSITION - 1 OF NEXT ENTRY IN TABLE
;DISPLAY MESSAGES FOR DISK STATUS
SFHDR: ASCIZ "
FREE DRIVES:
Type Chan/Drive Structure
____ __________ _________
"
SHDR: ASCIZ /Mounted? Type Chan Driv Structure name Logical unit
-------- ---- ---- ---- -------------- ------------
/
SMHDR: ASCIZ "
MOUNTED DRIVES:
Structure Type Chan/Drive Count Options
_____________ ____ __________ _____ _________________
"
;DISK UNIT TYPE TABLE
UNTYTB: ASCIZ "Unk " ;0 - UNKNOWN
ASCIZ "RP04" ;1 - RP04
ASCIZ "Unk " ;2 - UNKNOWN
ASCIZ "Unk " ;3 - UNKNOWN
ASCIZ "Unk " ;4 - UNKNOWN
ASCIZ "RP05" ;5 - RP05
ASCIZ "RP06" ;6 - RP06
ASCIZ "RP07" ;7 - RP07
ASCIZ "Unk " ;10 - UNKNOWN
ASCIZ "RM03" ;11 - RM03
MXUTYP==.-UNTYTB ;MAX UNIT TYPE
SUBTTL INITIALIZATION
; PROGRAM EXECUTION BEGINS HERE
START: HLRZ T1,.JBSA ;GET UPPER BOUND OF PROGRAM
CAIL T1,ADLOW ;PROGRAM TOO BIG?
JRST [ TMSG <MOUNTR program overlaps ADLOW> ;YES, ERROR
HALTF] ;MAKE ADLOW HIGHER TO CORRECT PROBLEM
RESET ;CLOSE JFNS, CLEAR PSI, DUMP PIDS, ETC.
MOVE P,[IOWD PDLEN,PDL] ;SET UP STACK POINTER
MOVX F,INITF ;INITIALIZE FLAGS AC
MOVE T1,.JBOPS ;GET GALAXY STANDARD TEST FLAG
MOVEM T1,TSTF ;COPY TO WRITE-PROTECTED LOCATION
; ZERO OUT MODIFYABLE DATA AREA
SETZM ZROBGN ;CLEAR FIRST WORD OF ZERO AREA
MOVE T1,[ZROBGN,,ZROBGN+1] ;GET BLT POINTER
BLT T1,ZROEND ;CLEAR THE REST OF THE ZERO AREA
SETOM TDSCF ;SET NO SCHED REQUEST PRESENT FOR TDSCIR
; TURN ON INTERRUPT SYSTEM
MOVEI T1,.FHSLF ;THIS FORK
MOVE T2,[LEVTAB,,CHNTAB] ;TABLE ADDRESSES
SIR ;COMMUNICATE TABLE ADDR'S TO MNTR
EIR ;TURN ON INTERRUPT SYSTEM
MOVX T2,INTMSK
AIC ;ENABLE INTERRUPT CHANNELS
SETO T3,
EPCAP ;ENABLE ALL CAPABILITIES
; PERFORM VARIOUS INITIALIZATION OPERATIONS
CALL WRTP ;WRITE-PROTECT MY CODE
MOVEI T1,.SFMTA
TMON ;TAPE-DRIVE ALLOCATION ENABLED?
JUMPN T2,[TXO F,TALCF ;YES, SET FLAG
MOVEI T1,POLINT ;GET POLLING INTERVAL
MOVEI T2,POLLR ;GET ADDRESS OF POLLING ROUTINE
CALL SRAI ;SCHEDULE MAGTAPE POLLING TASK
JRST .+1]
CALL PIDINI ;CREATE SYSTEM MDA PID
CALL GTINAM ;GET INSTALLATION NAME
CALL INAP ;MAKE FRIENDS WITH ASSOCIATED PROCESSES
SKIPN TSTF ;RUNNING LIVE?
JRST [ CALL DSFINI ;YES, MAP DEVICE-STATUS FILE
TXNE F,TALCF ;SKIP MTA ASSIGN IF ALLOCATION DISABLED
CALL ASMTA ;ASSIGN PHYSICAL MAGTAPES TO MYSELF
CALL ASMT ;PUT LOGICAL MAGTAPES IN ALLOC POOL
JRST .+1]
CALL GETRSI ;INITIALIZE FREE RSB POOL
CALL DSKINI ;SET UP DSK AND STR STATUS BLOCKS
CALL MNTALL ;MOUNT ALL STRUCTURES POSSIBLE
CALL VQSPIN ;INITIALIZE VOLID-SLOT POOL
CALL GETABI ;INITIALIZE FREE ACCOUNT BLOCK POOL
CALL TDSCIR ;REWIND TAPES, DO AVR, ETC.
TXZ F,INITF ;NOT INITIALIZING ANY MORE
JRST SSS ;ENTER SCHEDULER
SUBTTL SERVICE SCHEDULER (SS)
; SCHEDULER REQUEST QUEUE ENTRY EQUATES
FLDPTR==0
FLDDEF(RE.TIM,1) ;OFFSET TO ACTIVATION TIME
FLDDEF(RE.ENT,1) ;OFFSET TO GLOBAL ENTRY ADDRESS
FLDDEF(RE.ARG,1) ;OFFSET TO ARGUMENT
RE.LEN==FLDPTR ;LENGTH OF SCHEDULER ENTRY
; ONCE AGAIN INTO THE FRAY, DEAR FRIENDS
SSS: TXZ F,IRETF ;SET NOT INTERRUPTIBLE
CAME P,[IOWD PDLEN,PDL] ;STACK POINTER OK?
JSP CX,STOPP ;NO, CRASH
CALL DDCTLD ;CHECK FOR ENABLE/DISABLE ^D
TXO F,IRETF ;SET INTERRUPTIBLE
SKIPN NSR ;QUEUES EMPTY?
WAIT ;YES, REG TO SLEEP
GTAD ;GET CURRENT TIME & DATE IN T1
MOVE T2,SRQ+RE.TIM ;GET TIME/DATE OF EARLIEST REQUEST
SUB T2,T1 ;IS IT IN THE FUTURE?
JUMPLE T2,SSER ;NO, GET ON IT RIGHT AWAY
; SLEEP UNTIL WAKE-UP TIME OF EARLIEST REQUEST
MOVE T1,T2 ;COPY INTERNAL FORMAT SLEEP INTERVAL
MUL T1,[DAYSEC*^D1000] ;COMPUTE # OF MILLISECONDS
ASHC T1,^D17 ; TO SLEEP IN T1
DISMS ;SLEEP UNTIL NEEDED
JRST SSS ;ATTEMPT SCHEDULE AGAIN
; SCHEDULE THE FIRST REQUEST IN THE QUEUE
SSER: TXZ F,IRETF ;AIN'T IDLE NO MORE
MOVEI T1,.FHSLF
DIR ;INHIBIT INTERFERENCE
MOVE T4,SRQ+RE.ENT ;GET ROUTINE ENTRY ADDRESS
MOVE T3,SRQ+RE.ARG ;GET ARG FOR HANDLER ROUTINE
SOS T1,NSR ;GET # OF REQUESTS REMAINING
JUMPE T1,SSS1 ;IF NONE LEFT, DON'T BLT
IMULI T1,RE.LEN ;COMPUTE # OF WORDS TO BLT
MOVE T2,[SRQ+RE.LEN,,SRQ] ;GET BLT SOURCE,,DESTINATION
BLT T2,SRQ+RE.LEN-1(T1) ;DELETE HEAD OF QUEUE
SSS1: MOVEI T1,.FHSLF
EIR ;PERMIT INTERRUPTS
DMOVEM T3,SSSDAT ;STORE CALLED-ROUTINE INFO FOR DEBUG
CALL (T4) ;CALL USER ROUTINE WITH ARG IN T3
TXZE F,ABORTF ;WERE ANY REQUESTS ABORTED?
CALL PRQABT ;YES, PURGE THEM FROM REQUEST QUEUE
JRST SSS ;GO SEE IF MORE WORK TO DO
; SRA - ADD SCHEDULER REQUEST TO QUEUE (2 ENTRY POINTS)
; SRAA - ABSOLUTE INTERNAL-FORMAT TIME & DATE IN T1
; SRAI - INCREMENTAL FORM: # OF SECONDS FROM NOW IN T1
; SRAN - REQUEST IS TO BE SCHEDULED AS SOON AS POSSIBLE (T1 MEANINGLESS)
; T2/ ROUTINE ADDRESS IN RIGHT HALF
; T3/ ARGUMENT TO BE SUPPLIED TO ROUTINE IN T3 AT TIME OF CALL
; RETURNS +1: ALWAYS
SRAI: STAKT ;STACK T1-T4
MUL T1,[1,,0] ;CONVERT # OF SECONDS
DIVI T1,DAYSEC ; TO INCREMENTAL INTERNAL FORMAT
MOVE T2,T1 ;CLEAR OUT OF T1 FOR GTAD
GTAD ;GET CURRENT INTERNAL T/D
ADD T1,T2 ;ADD INCREMENT
JRST SRA1 ;SKIP OTHER ENTRY
SRAN: SETZ T1, ;IMMEDIATE FLAVOR - STUFF T1
SRAA: STAKT ;STACK T1-T4
; COMMON CODE FOR SRAx
SRA1: MOVE T4,T1 ;MOVE ACTIVATION TIME TO T4
MOVEI T1,.FHSLF
DIR ;INHIBIT INTERFERENCE
SETZ T2, ;INIT SCAN INDEX
MOVNI T3,RE.LEN ;INIT QUEUE POINTER
SRA2: ADDI T3,RE.LEN ;BUMP QUEUE POINTER
CAMGE T2,NSR ;ANY ENTRIES LEFT TO CHECK AGAINST?
JRST [ CAML T4,SRQ+RE.TIM(T3) ;YES, EARLIER THAN THIS ENTRY?
AOJA T2,SRA2 ;NO, CONTINUE SEARCH
JRST .+1] ;YES, GO INSERT IT HERE
SUB T2,NSR ;COMPUTE # OF
MOVNS T2 ; ENTRIES TO BE SHIFTED DOWN
IMULI T2,RE.LEN ;COMPUTE # OF WORDS TO SHIFT
MOVE T3,NSR
IMULI T3,RE.LEN ;SET UP LOAD/STORE INDEX AT TAIL
JUMPE T2,SRA3 ;IF NONE, SKIP SHIFTING STUFF
SRA4: MOVE T1,SRQ-1(T3) ;GET A WORD
MOVEM T1,SRQ+RE.LEN-1(T3) ;SHIFT IT DOWN
SOS T3 ;INDEX NEXT WORD
SOJG T2,SRA4 ;LOOP TILL ALL SHIFTING DONE
; INSTALL ENTRY IN NEWLY-CREATED SLOT
SRA3: MOVEM T4,SRQ+RE.TIM(T3) ;STUFF TIME/DATE
XMOVEI T1,20
HRR T1,CT2
MOVEM T1,SRQ+RE.ENT(T3) ;STUFF GLOBAL ENTRY ADDRESS
MOVE T1,CT3
MOVEM T1,SRQ+RE.ARG(T3) ;STUFF ARGUMENT
AOS NSR ;BUMP # OF ENTRIES IN QUEUE
MOVEI T1,.FHSLF
EIR ;PERMIT INTERRUPTS
RET
; EIHR - SUPPORT ROUTINE FOR EXTERNAL INTERRUPTS
EIHR: ADJSP P,5 ;CREATE ROOM ON STACK FOR T1-T4, CX
MOVEM CX,-4(P) ;SAVE CX
DMOVEM T1,-3(P) ;SAVE T1 & T2
DMOVEM T3,-1(P) ;SAVE T3 & T4
; REQUEST SCHEDULING AT INTERRUPT HANDLER ENTRY POINT
MOVE T2,@-5(P) ;GET ADDRESS OF ROUTINE
CALL SRAN ;SCHEDULE AT THIS ADDRESS IMMEDIATELY
; RESTORE AC'S AND EXIT TO INTERRUPTED PROGRAM OR SCHEDULER
MOVE CX,-4(P) ;RESTORE CX
DMOVE T1,-3(P) ;RESTORE T1 & T2
DMOVE T3,-1(P) ;RESTORE T3 & T4
ADJSP P,-6 ;DELETE TEMP SPACE FROM STACK
TXZN F,IRETF ;SCHED GOOFING OFF?
DEBRK ;NO, GO BACK TO INTERRUPTED CODE
MOVE CX,[PC%USR+SSS] ;YES, GET NEW PC
MOVEM CX,@LEVTAB+PRIEXT-1 ;STUFF IT
DEBRK ;EXIT TO SCHEDULER
SUBTTL ACCOUNTING ROUTINES
;ACCSTI - STRUCTURE COUNT BEING INCREMENTED. BUILD ACCOUNTING BLOCK FOR
; USER
ACCSTI: HRRZ T1,RBUF+4 ;GET STRUCTURE STATUS
TXNE T1,MS%NRS ;IS IT NON-REGULATED?
RET ;YES, FORGET ENTRY
HLRZ T1,RBUF+2 ;GET JOB NUMBER
HRRZ T2,RBUF+3 ;GET DEVICE DESIGNATOR
HRLI T2,.DVDES+.DVDSK ;ADD DISK DESIGNATION
CALL FNDACC ;SEE IF THERE IS A BLOCK ALREADY
JRST ACCS1 ;NO
AOS ACCFRK(ACC) ;YES, INCREMENT FORK COUNT
RET ;FINISHED
ACCS1: CALL GETACC ;GET AN ACCOUNT BLOCK
CALLRET DELACC ;ABORT SINCE ACC BLOCKS IN SHORT SUPPLY
AOS ACCFRK(ACC) ;SET NUMBER OF FORKS USING STR TO 1
;STORE ACCOUNTING INFORMATION
HRRZ T1,RBUF+3 ;GET STRUCTURE UNIQUE CODE
HRLI T1,.DVDES+.DVDSK ;ADD DISK DESIGNATOR
MOVEM T1,ACCDD(ACC) ;STORE IN ACCOUNTING BLOCK
MOVE T1,RBUF+2 ;GET JOB #,,LINE #
MOVEM T1,ACCNO(ACC)
MOVE T2,RBUF+10 ;GET USER #
HRROI T1,ACCUSR(ACC)
DIRST ;TRANSLATE TO NAME
JFCL
MOVEI T1,ACCSTG(ACC) ;SET UP BLT POINTER
HRLI T1,RBUF+11
BLT T1,ACCSTG+7(ACC) ;STORE ACCOUNT STRING
MOVE T1,RBUF+7
MOVEM T1,ACCCRT(ACC) ;STORE TIME AND DAY
MOVEM T1,ACCSCD(ACC) ;TIME SCHEDULED
MOVEM T1,ACCSVT(ACC) ; AND SERVICED ARE SAME
MOVE T1,RBUF+6
MOVEM T1,ACCSTN(ACC) ;STORE STRUCTURE NAME
HLRZ T1,RBUF+4
STOR T1,ACCMB ;STORE MOUNT COUNT
HLRZ T1,RBUF+5
STOR T1,ACCNU ;STORE NUMBER OF UNITS
HRRZ T1,RBUF+5
STOR T1,ACCDT ;STORE DISK TYPE
HRRZ T1,RBUF+4 ;GET STRUCTURE STATUS
MOVEI T2,4 ;ASSUME STRUCTURE IS FOREIGN
TXNN T1,MS%DOM ;IS IT DOMESTIC?
MOVEI T2,3 ;YES, GET DOMESTIC CODE
STOR T2,ACCST ;STORE STRUCTURE TYPE
SETONE ACCKT ;SET CONTROLLER TO ALL ONES
RET
;ACCSTD - STRUCTURE COUNT BEING DECREMENTED. MAKE USAGE ENTRY.
ACCSTD: HLRZ T1,RBUF+2 ;GET JOB NUMBER
MOVE T2,RBUF+3 ;GET DEVICE DESIGNATOR
HRLI T2,.DVDES+.DVDSK ;ADD DISK DESIGNATION
CALL FNDACC ;FIND ACCOUNT BLOCK
RET ;THERE WAS NONE
SOSE ACCFRK(ACC) ;ANY OTHER FORKS HAVE IT INCREMENTED?
RET ;YES, DON'T SEND ANY INFO, YET
CALL STOSTR ;STORE STR INFO FROM ACCOUNT BLOCK
HRRZ T1,RBUF+2 ;GET MOUNT COUNT
MOVEM T1,USTDC
MOVEI T1,.UTMNT ;THIS IS STRUCTURE MOUNT INFO
CALL SNDACC ;SEND USAGE INFO TO MONITOR
CALLRET DELACC ;DELETE ACCOUNT BLOCK
;ACCSTR - STRUCTURE BEING REMOVED. SEND ACCOUNT BLOCKS TO USAGE
ACCSTR: QSCANI AABQDB ;SET UP TO SCAN ACTIVE ACCOUNT BLOCKS
MOVE Q1,RBUF+3 ;GET DEVICE DESIGNATOR
HRLI Q1,.DVDES+.DVDSK ;ADD DISK DESIGNATION
ACCSR1: CALL QMSCAN ;GET ADDRESS OF NEXT ACC IN T2
RET ;NONE LEFT
MOVEI ACC,-ACCLNK(T2) ;LOAD ACC ADDRESS
CAME Q1,ACCDD(ACC) ;IS THIS THE STR BEING REMOVED
JRST ACCSR1 ;NO, GET NEXT ACCOUNT BLOCK
CALL STOSTR ;STORE STR INFO INTO USAGE BLOCK
MOVEI T1,.UTMNT ;THIS IS STRUCTURE MOUNT INFO
CALL SNDACC ;SEND USAGE INFO TO MONITOR
CALL DELACC ;DELETE ACCOUNT BLOCK
JRST ACCSR1 ;GET NEXT BLOCK
;ACCMTR - TAPE BEING REQUESTED. BUILD ACCOUNTING BLOCK FOR USER
ACCMTR: CALL GETACC ;GET ACCOUNT BLOCK
JRST DELACC ;ABORT SINCE ACC BLOCKS IN SHORT SUPPLY
MOVSI T1,RSBACT(RSB) ;BLT SOURCE
HRRI T1,ACCSTG(ACC) ;BLT DESTINATION
BLT T1,ACCSTG+7(ACC) ;MOVE USER'S ACCOUNT STRING TO ACC
LOAD T1,RSBJNO ;GET USER'S JOB NUMBER
STOR T1,ACCJN
CALL STONAM ;STORE USER'S NAME
JRST DELACC ;USER NOT AROUND, DELETE ACC BLOCK
STOR ACC,RSBACC ;STORE ACCOUNT BLOCK ADDRESS INTO RSB
RETSKP
;ACCMTD - TAPE BEING DISMOUNTED. MAKE USAGE ENTRY FOR USER
;ACCEPTS: MT/ ADDRESS OF MT STATUS BLOCK
; MTA/ ADDRESS OF MTA STATUS BLOCK
; RSB/ ADDRESS OF REQUEST STATUS BLOCK
ACCMTD: SAVEAC <ACC>
LOAD ACC,RSBACC ;RETRIEVE ACCOUNT BLOCK ADDRESS
MOVE T1,MTAVOL(MTA) ;GET VOLID
MOVEM T1,UMTVID
LOAD T1,MTALT ;GET LABEL TYPE
MOVEM T1,UMTLT ; INTO USAGE BLOCK
CALL MTAGJF ;GET MAGTAPE JFN
MOVEI T2,.MOINF ;GET TAPE INFORMATION
MOVEI T3,.MOIWF ;GET LENGTH OF INFO BLOCK
MOVEM T3,MSTRBK
MOVEI T3,MSTRBK ;PUT ALL INFO INTO MSTRBK
MTOPR
CALL MTARJF ;RELEASE JFN
MOVE T1,MSTRBK+.MOIRD ;GET NUMBER OF PHYSICAL RECS READ
MOVEM T1,UMTMRD
MOVE T1,MSTRBK+.MOIWT ;GET NUMBER OF PHYSICAL RECS WRITTEN
MOVEM T1,UMTMWR
MOVE T1,MSTRBK+.MOIRF ;GET NUMBER OF FRAMES READ
MOVEM T1,UMTMRF
MOVE T1,MSTRBK+.MOIWF ;GET NUMBER OF FRAMES WRITTEN
MOVEM T1,UMTMWF
MOVE T1,MSTRBK+.MOISR ;GET NUMBER OF SOFT READ ERRORS
MOVEM T1,UMTSRE
MOVE T1,MSTRBK+.MOISW ;GET NUMER OF SOFT WRITE ERRORS
MOVEM T1,UMTSWE
MOVE T1,MSTRBK+.MOIHR ;GET NUMBER OF HARD READ ERRORS
MOVEM T1,UMTHRE
MOVE T1,MSTRBK+.MOIHW ;GET NUMBER OF HARD WRITE ERRORS
MOVEM T1,UMTHWE
MOVE T1,RSBASN(RSB) ;GET VOLUME SET NAME
MOVEM T1,UMTFSI
MOVEI T1,.UTMMT ;THIS IS TAPE MOUNT INFO
CALL SNDACC ;SEND ACCOUNTING INFO TO MONITOR
CALLRET DELACC ;DELETE ACCOUNTING BLOCK
;DELACC - DELETE ACCOUNT BLOCK FROM QUEUE
;ACCEPTS: ACC/ ADDRESS OF ACCOUNT BLOCK
;RETURNS: +1, NOTHING
DELACC: SETZM ACCDD(ACC) ;SET ACC INACTIVE
QSCANI AABQDB ;SET UP TO SCAN ACTIVE ACC QUEUE
SAVEAC <ACC>
; SEARCH ACCOUNT BLOCK QUEUE AND EXTRACT ABORTED REQUESTS
DELAC1: CALL QMSCAN ;GET ADDRESS OF NEXT ACC ON QUEUE
RET ;NONE LEFT, EXIT
MOVEI ACC,-ACCLNK(T2) ;LOAD ACC WITH ACC BLOCK ADDRESS
SKIPE ACCDD(ACC) ;IS REQUEST ABORTED?
JRST DELAC1 ;NO, SKIP IT
CALL QMDQS ;DEQUEUE ACC, GET LINKAGE ADDR IN T2
MOVEI T1,IABQDB ;GET QDB ADDRESS
CALL QMQH ;QUEUE ACC TO HEAD OF INACTIVE QUEUE
JRST DELAC1 ;CONTINUE SCAN
;FNDACC - FIND AN EXISTING ACCOUNT BLOCK
;ACCEPTS: T1/ JOB NUMBER
; T2/ DEVICE DESIGNATOR
;RETURNS: +1, FAILURE, COULD NOT FIND BLOCK
; +2, SUCCESS, ACC/ ADDRESS OF ACCOUNT BLOCK
FNDACC: SAVEQ
DMOVE Q1,T1
QSCANI AABQDB ;SET UP TO SCAN ACTIVE ACC QUEUE
FNDAC1: CALL QMSCAN ;GET ADDRESS OF NEXT ACC IN T2
RET ;NONE LEFT
MOVEI ACC,-ACCLNK(T2) ;LOAD ACC ADDRESS
CAME Q2,ACCDD(ACC) ;IS THIS THE RIGHT DEVICE DESIGNATOR?
JRST FNDAC1 ;NO, GET ANOTHER ACC
LOAD T1,ACCJN
CAME Q1,T1 ;IS THIS THE RIGHT JOB?
JRST FNDAC1 ;NO, TRY ANOTHER ACC
RETSKP ;SUCCESS
; GETABI - INITIALIZE FREE ACC POOL FOR GETACC
; RETURNS +1: ALWAYS
GETABI: SAVEQ
MOVEI Q1,ACC0 ;GET ADDRESS OF ACC POOL
MOVEI Q2,MAXACC+1 ;# OF ACCS IN POOL
GTABI1: MOVEI T1,IABQDB ;GET QDB ADDRESS
MOVEI T2,ACCLNK(Q1) ;GET ADDRESS OF ACC LINKAGE
CALL QMQT ;QUEUE ACC TO TAIL OF FREE QUEUE
ADDI Q1,ACCSIZ ;POINT Q1 AT NEXT ACC
SOJG Q2,GTABI1 ;LOOP THRU ALL ACCOUNT BLOCKS
RET
; GETACC - ALLOCATE AN ACCOUNT BLOCK
; RETURNS +1: ACCOUNT BLOCK ALLOCATED, BUT IT'S THE LAST ONE
; +2: ACCOUNT BLOCK ALLOCATED, MORE FREE ACC BLOCK'S LEFT
; ACC/ ADDR OF ACCOUNTING BLOCK
GETACC: MOVEI T1,IABQDB ;POINT TO INACTIVE ACC QUEUE
CALL QMDQH ;DEQUEUE HEAD OF QUEUE
CALL STOP ;QUEUE EMPTY, PROGRAM LOGIC ERROR
MOVEI ACC,-ACCLNK(T2) ;LOAD UP ACC AC
MOVS T1,1(ACC) ;BLT SOURCE
HRRI T1,2(ACC) ;BLT DESTINATION
SETZM 1(ACC) ;CLEAR 2ND WORD OF ACC
BLT T1,ACCSIZ-1(ACC) ;CLEAR THE REST OF THE ACC
GTAD
MOVEM T1,ACCCRT(ACC) ;STORE TIME WHEN REQUEST WAS RECEIVED
MOVEI T2,ACCLNK(ACC) ;GET ADDRESS OF ACC LINKAGE WORD
SKIPN IABQDB ;WAS THIS THE LAST FREE ACC?
JRST [ MOVEI T1,IABQDB ;YES, CAN'T GIVE IT AWAY
CALLRET QMQH] ;PUT ON INACTIVE QUEUE AND TAKE +1
MOVEI T1,AABQDB ;NOT THE LAST FREE ONE
CALL QMQT ;QUEUE TO TAIL OF ACTIVE QUEUE
RETSKP
;SNDACC - SEND ACCOUNTING INFORMATION TO MONITOR
;ACCEPTS: T1/ TYPE OF ENTRY
; ACC/ ADDRESS OF ACCOUNT BLOCK
;RETURNS: +1, ALWAYS
SNDACC: MOVE T4,T1 ;SAVE TYPE OF ENTRY
GTAD ;GET CURRENT DATE AND TIME
MOVE T2,ACCSVT(ACC) ;GET SERVICED TIME
SUB T1,T2 ;GET ELAPSED TIME
MOVEM T1,ACCEUT(ACC) ; AND STORE
MOVE T1,T4 ;RESTORE TYPE OF ENTRY
MOVEI T2,USRNAM ;MOVE COMMON INFO FROM ACCOUNT BLOCK
HRLI T2,ACCUSR(ACC) ; TO USAGE AREA
BLT T2,USRNAM+ACCCSZ-4
LOAD T2,ACCJN ;GET JOB NUMBER
MOVEM T2,JOBNO
LOAD T2,ACCLN ;GET LINE NUMBER
MOVEM T2,LINO
MOVEI T2,USGSTR ;ASSUME STRUCTURE RECORD
CAIE T1,.UTMNT ;IS IT A STRUCTURE?
MOVEI T2,USGMTA ;NO, IT'S A MAGTAPE ENTRY
MOVEI T1,.USENT ;WRITE AN ENTRY INTO SYSTEM DATA FILE
SKIPN TSTF ;DON'T MAKE USAGE ENTRY IF TESTING
USAGE
SETZM JOBNO ;ZERO USAGE AREA
MOVE T1,[JOBNO,,JOBNO+1]
BLT T1,JOBNO+USGSIZ-2
RET
;STONAM - STORE USER'S NAME INTO ACCOUNT BLOCK
;ACCEPTS: T1/ USER NUMBER
;RETURNS: +1, FAILURE, COULD NOT FIND USER
; +2, SUCCESS
STONAM: MOVE T2,[-2,,Q1]
MOVEI T3,.JITNO ;GET TERMINAL AND USER NUMBERS
GETJI
RET ;USER NOT AROUND
SKIPN Q2 ;IS USER REALLY THERE?
RET ;NO
STOR Q1,ACCLN ;STORE LINE NUMBER
HRROI T1,ACCUSR(ACC) ;GET USER NAME
MOVE T2,Q2
DIRST
CALL STOP
RETSKP
;STOSTR - STORE STRUCTURE INFO INTO USAGE BLOCK
;ACCEPTS: ACC/ ADDRESS OF ACCOUNT BLOCK
;RETURNS: +1, ALWAYS
STOSTR: MOVE T1,ACCSTN(ACC) ;GET STRUCTURE NAME
MOVEM T1,USTNM
LOAD T1,ACCKT ;GET CONTROLLER TYPE
MOVEM T1,USTKTP
LOAD T1,ACCDT ;GET DEVICE TYPE
MOVEM T1,USTDTP
LOAD T1,ACCST ;GET STRUCTURE TYPE
MOVEM T1,USTSTP
LOAD T1,ACCNU ;GET NUMBER OF PACKS
MOVEM T1,USTTNP
LOAD T1,ACCMB ;GET MOUNT COUNT BEFORE MOUNTING
MOVEM T1,USTMC
RET
SUBTTL AVR - AUTOMATIC VOLUME RECOGNITION
; AVR - INITIATE AVR SEQUENCE FOR A TAPE DRIVE
; MTA/ ADDR OF MTA STATUS BLOCK
; RETURNS +1: ALWAYS
AVR: JN MTAJCT,,R ;EXIT IF I'M ALREADY PROCESSING
JN MTALT,,R ;EXIT IF VOLUME ALREADY RECOGNIZED
JN MTAMT,,[LOAD T1,MTASTE ;GET STATE
CAIE T1,S.INIT ;IN INIT MODE?
RET ;NO, EXIT
JRST .+1] ;YES, PROCEED
MOVE T1,MTAFLG(MTA) ;GET FLAGS
MOVEI T2,.LTUNL
TXNN T1,MA%AVS ;IS AVR SUPPORTED FOR THIS DRIVE?
STOR T2,MTALT ;NO, MUST CLASSIFY AS UNLABELED
TXNN T1,MA%AVE ;IS AVR ENABLED FOR THIS DRIVE?
JRST [ CALL REW ;NO, IS DRIVE LOADED?
RET ;NO
CALLRET WOTMD] ;YES, TELL OPERATOR ABOUT IT
MOVX T1,MA%UXV+MA%OPF
ANDCAM T1,MTAFLG(MTA) ;CLEAR LABEL-RELATED FLAGS
CALL MTAGJF ;GET JFN ON MTA DEVICE
MOVEI T1,DENMAX
STOR T1,MTADEN ;START AT HIGHEST DENSITY
; LOOP TO CHECK FOR LABEL AT ALL AVAILABLE DENSITIES
AVR2: LOAD T1,MTADEN ;GET DENSITY
CALL DRVDEN ;CAN THE DRIVE OPERATE AT THIS DENSITY?
JRST AVR2B ;NO, SKIP TO THE NEXT DENSITY
MOVEI T1,AVR2A ;ENTER AT AVR2A AFTER REWIND
CALL REWEA ;TRY TO REWIND
JRST AVR3 ;CAN'T REWIND, WRAP UP AVR
RET ;EXIT UNTIL REWIND COMPLETES
; END-ACTION FOR REWIND
AVR2A: CALL CHKLT ;CHECK LABEL TYPE OF THE TAPE
SKIPA ;CAN'T READ TAPE AT THIS DENSITY
JRST AVR3 ;TAPE WAS IDENTIFIFED AT THIS DENSITY
AVR2B: DECR MTADEN ;NEXT DENSITY
JN MTADEN,,AVR2 ;GO AROUND FOR ANOTHER TRY
; NOTHING CAN BE READ FROM THIS TAPE
MOVEI T1,.SFTDF
TMON ;GET TAPE-MOUNT CONTROLS SET BY SETSPD
JXN T2,MT%UUT,[CALL UNLOAD ;IF UNLOAD SET BY INSTALLATION, DO IT
CALL MTARJF ;DUMP JFN
CALL WOLRDX ;TELL OPERATOR
JRST AVR4] ;GO CHECK WAITING RSB'S
; MTA STATUS BLOCK NOW REFLECTS THE ATTRIBUTES OF THE AVR'ED VOLUME
AVR3: CALL MTARJF ;DUMP JFN
LOAD T1,MTASTE
CAIN T1,S.INIT ;DRIVE IN INITIALIZE MODE?
JRST [ CALLRET KVITAV] ;YES, SPECIAL EXIT
CALL CKMPAV ;DRIVE STILL AVAILABLE?
CALL DACMTA ;NO, HERE IS A GOOD PLACE TO DEACTIVATE
MOVE T1,MTAFLG(MTA)
JXE T1,MA%LOD,AVR4 ;WRAP UP IF DRIVE NOT LOADED
CALL WOTMD ;TELL OPERATOR TAPE IS MOUNTED
CALL WOCKSW ;IS THIS A WRITE-PROTECTED SCRATCH TAPE?
JRST AVR4 ;YES, DRIVE UNLOADED AND MESSAGE TYPED
SKIPN MTAVOL(MTA) ;HAS THE VOLUME BEEN IDENTIFIFED?
RET ;NO, MUST WAIT FOR KEYIN
CALL MATCHV ;YES, TRY FOR A MATCH
; CHECK IF NECESSARY TO TELL THE OPERATOR OF PENDING TAPE MOUNT REQUESTS
AVR4: QSCANI ARBQDB ;SET UP TO SCAN REQUEST QUEUE
AVR41: CALL NMTRSB ;GET NEXT TAPE REQUEST IN RSB AC
RET ;NONE LEFT
CALL WOVMT ;TELL OPERATOR IF NECESSARY
JRST AVR41 ;LOOP THRU ALL REQUESTS
; CHKLT - IDENTIFY LABEL TYPE OF A TAPE AND UPDATE MTA STATUS BLOCK
; MTA/ ADDR OF MTA STATUS BLOCK
; RETURNS +1: COULD NOT READ ANY INFORMATION FROM THE TAPE
; +2: TAPE WAS IDENTIFIED AT DENSITY IN MTADEN
CHKLT: SAVEQ
; Q1/ BIT 01 SET - VOL1 ACCESSIBILITY IS NOT BLANK
; BIT 02 SET - HDR1 ACCESSIBILITY IS NOT BLANK
; BIT 04 SET - OVERWRITE ACCESS DENIED - WORLD DP%CN IS RESET
; BIT 10 SET - OVERWRITE ACCESS DENIED - WORLD FP%WR IS RESET
; Q2/ 1 = READING CORE-DUMP MODE, 0 = READING INDUSTRY-COMPATIBLE MODE
; Q3/ CONTENTS OF MTAVOL AT TIME CHKLT WAS CALLED (USED TO RESTORE
; MTAVOL IF TAPE HAS A VOL1 BUT NO HDR1)
MOVE Q3,MTAVOL(MTA) ;REMEMBER CURRENT VOLID
SETZ Q1,
MOVEI T1,.LTUNL
STOR T1,MTALT ;SET UNLABELED INITIALLY FOR LBLICV
CALL MTAOPI ;OPEN MTA JFN
RETSKP ;OFFLINE
; CHECK FOR AND PROCESS VOL1 LABEL
; THE FIRST READ IS DONE IN CORE-DUMP MODE TO ALLOW FOR READING THE
; LARGEST POSSIBLE RECORD THAT TOPS-20 CAN WRITE (MOST LIKELY CASE
; SEEMS TO BE AN UNLABELED DUMPER TAPE WITH A LARGE BLOCKING FACTOR).
; BITS 0-31 OF THE FIRST WORD LOOK THE SAME IN CORE-DUMP AND I/C MODES,
; AND THAT'S THE FIRST 4 FRAMES OF THE RECORD (ALL I CARE ABOUT HERE).
; IF IT'S A VOL1, THEN REWIND AND READ IT AND ALL OTHER LABELS IN I/C
; MODE. IF IT'S NOT A VOL1, THEN JUST CLASSIFY THE TAPE AS UNLABELED.
MOVEI Q2,1 ;SETUP Q2 FOR LOOPING
CHKL1: CALL REW ;REWIND TO TEST IF DRIVE IS ONLINE
JRST [ CALL MTACLS ;OFFLINE, CLOSE JFN
RETSKP] ;PREVENT CHECKING OTHER DENSITIES
LOAD T1,MTAJFN ;GET JFN
MOVEI T2,.MOSDM ;MTOPR FUNCTION CODE
MOVE T3,[EXP .SJDM8,.SJDMC](Q2) ;GET DESIRED DATA MODE
MTOPR ;SET DATA MODE
CALL RDLBL ;TRY TO READ 1ST RECORD FROM TAPE
JRST [ JUMPLE T1,CHKLR1 ;TIMEOUT OR DATA ERROR
SKIPG Q2 ;SKIP IF CORE-DUMP READ
SETZM LBUF1 ;NON-LABEL READ SUCCESSFULLY
JRST .+1] ; SO FORCE CHKV1 TO SAY IT'S UNLABELED
SOJE Q2,[LOAD T1,MTAJFN ;FIRST READ ATTEMPT, GET JFN
MOVEI T2,.MORDN ;FUNCTION = READ DENSITY
MTOPR ;GET DENSITY THE TAPE WAS READ AT IN T3
STOR T3,MTADEN ;REMEMBER IT
CALL CHKV1A ;IS IT A VOL1?
JRST CHKLP ;NO, CLASSIFY AS UNLABELED
JRST CHKL1] ;YES, REWIND AND READ IN I/C MODE
CALL CHKV1 ;CHECK FOR VOL1, FILL IN STATUS BLOCK
JRST CHKLP ;NOT LABELED (SHOULD NEVER GET HERE)
CAIE T1," " ;VOL1 ACCESSIBILITY BLANK?
TRO Q1,1 ;NO, SET FLAG
SETZM MTASET(MTA) ;LABELED TAPE - CLEAR SETNAME
JUMPE T2,CHKL2 ;JUMP IF IT CAN'T BE A TOPS-20 TAPE
; CHECK FOR AND PROCESS VOL2 LABEL
CALL RDLBL ;YES, GET LABEL AFTER VOL1
JRST CHKLUN ;NO LABEL AFTER VOL1, IT'S UNLABELED
CALL CHKV2 ;IS IT A VOL2?
JRST CHKL3 ;NO
STOR T1,MA%SCR,MTAFLG(MTA) ;YES, STORE SCRATCH FLAG
TRNN T2,DP%CN ;WORLD DP%CN RESET?
TRO Q1,4 ;YES, SET DP%CN ACCESS-DENIED FLAG
MOVEI T1,.LTT20
STOR T1,MTALT ;SET LABEL-TYPE TO TOPS-20
; CHECK FOR AND PROCESS HDR1 LABEL
CHKL2: CALL RDLBL ;GET NEXT LABEL
JRST CHKLUN ;NO LABEL HERE, TAPE IS UNLABELED
CHKL3: MOVE T1,LBUF2 ;GET FIRST 5 CHARACTERS FROM RECORD
TRZ T1,77777 ;KEEP THE FIRST 3 CHARACTERS
CAME T1,[ASCIZ/VOL/] ;IS IT A VOL
CAMN T1,[ASCIZ/UVL/] ; OR A UVL?
JRST CHKL2 ;YES, CONTINUE SEARCH
CALL CKHDR1 ;IF HDR1, UPDATE STATUS BLOCK
JRST CHKLUN ;NOT HDR1, TAPE IS UNLABELED
CAIE T1," " ;HDR1 ACCESSIBILITY BLANK?
TRO Q1,2 ;NO, SET FLAG
; CHECK FOR AND PROCESS HDR2 LABEL
CALL RDLBL ;GET NEXT LABEL
JRST CHKLP ;NO LABEL
CALL CKHDR2 ;CHECK IF HDR2
JRST CHKLP ;NOT HDR2
TRNN T1,FP%WR ;WORLD WRITE-ACCESS ALLOWED TO FILE?
TRO Q1,10 ;NO, SET WRITE-ACCESS DENIED
CHKLP: CALL CHKLR1 ;REWIND AND CLOSE JFN
LOAD T1,MTALT ;GET LABEL TYPE
CAIN T1,.LTANS ;ANSI?
JRST [ TRNE Q1,1+2 ;YES, ANY NON-BLANK ACCESSIBILITIES?
JRST CHKLPS ;YES, SET PROTECTED
JRST CHKLPR] ;NO, RESET PROTECTED
CAIN T1,.LTT20 ;TOPS-20?
JRST [ TRNE Q1,4 ;YES, WORLD WRITE ACCESS DENIED TO VOL?
JRST CHKLPS ;YES, SET PROTECTED
TRNE Q1,2 ;RESET PROT IF FILE ACCESSIBILITY BLANK
TRNN Q1,10 ; OR IF WORLD WRITE ACCESS IS ALLOWED
JRST CHKLPR
JRST CHKLPS] ;NEITHER, SET PROTECTED
RETSKP
CHKLPS: SETONE MA%OPF,MTAFLG(MTA) ;SET OVERWRITE-PROTECTED FLAG
CHKLPR: JE MA%SCR,MTAFLG(MTA),RSKP ;RETURN IF NOT SCRATCH
MOVX T1,MA%OPF+MA%UXV ;IT'S A SCRATCH TAPE
ANDCAM T1,MTAFLG(MTA) ;TURN OFF OVERWRITE INHIBITORS
RETSKP
CHKLR1: CALL REW ;GET BACK TO BOT
JFCL ;OFFLINE, WILL BE CAUGHT BY AVR
CHKLID: CALL MTACLS ;CLOSE MTA
RET
; TAPE HAS A VOL1 BUT NO HDR1 - CLASSIFY IT AS UNLABELED
CHKLUN: MOVEI T1,.LTUNL
STOR T1,MTALT ;SET LABEL TYPE TO UNLABELED
MOVEM Q3,MTAVOL(MTA) ;REPLACE OLD VOLID
JRST CHKLP ;WRAP UP AND EXIT
; CHKV1 - IDENTIFY A VOLUME WHOSE FIRST RECORD IS IN LBUF1
; MTA/ ADDR OF MTA STATUS BLOCK
; LBUF1/ UNMODIFIED RECORD READ FROM TAPE
; RETURNS +1: VOLUME IS UNLABELED, MTALT UPDATED
; +2: VOLUME IS LABELED, MTALT AND MTAVOL UPDATED
; T1/ VOL1 ACCESSIBILITY CHARACTER
; T2/ 1 MEANS VOL1 MEETS NECESSARY CONDITIONS FOR
; CLASSIFICATION AS TOPS-20 LABEL TYPE, ELSE 0
; CHKV1A - DETERMINE IF RECORD IN LBUF1 (IN CORE-DUMP FORMAT) IS A VOL1
; LBUF1/ UNMODIFIED RECORD READ FROM TAPE IN CORE-DUMP MODE
; RETURNS +1: NOT A VOL1
; +2: IS A VOL1
CHKV1: TDZA T1,T1 ;REMEMBER CHKV1 ENTRY
CHKV1A: MOVEI T1,1 ;REMEMBER CHKV1A ENTRY
SAVET ;SET UP TO RETURN VALUES TO CALLER
SETZM CT2 ;SET NOT TOPS-20
MOVE T2,LBUF1 ;GET 1ST 4 FRAMES FROM TAPE
TRZ T2,17 ;B32-B35 MEANINGLESS, SO SET TO ZERO
CAMN T2,[713533,,237420] ;EBCDIC VOL1?
JRST [ MOVEI T1,.LTEBC ;YES, SET LABEL TYPE TO EBCDIC
JRST CHKV11] ;SKIP OTHER TESTS
TDZ T2,[1B0+1B8+1B16+1B24] ;CLEAR 8TH BITS FOR ASCII CHECK
CAMN T2,[BYTE(8) "V","O","L","1"] ;ASCII VOL1?
JRST [ MOVEI T1,.LTANS ;YES, IS EITHER ANSI OR TOPS-20
JRST CHKV11] ; BUT ASSUME ANSI FOR NOW...
CHKV12: MOVEI T1,.LTUNL
SKIPN CT1 ;DON'T STORE LABEL TYPE IF CHKV1A
STOR T1,MTALT ;SET LABEL TYPE = UNLABELED
RET ;+1 RETURN FOR UNLABELED
; VOL1 LABEL WAS FOUND
CHKV11: SKIPE CT1 ;CHKV1A ENTRY?
RETSKP ;YES, INDICATE RECORD WAS A VOL1
STOR T1,MTALT ;STORE LABEL TYPE IN MTA TABLE
CALL LBLICV ;CONVERT LABEL TO 7-BIT ASCII
MOVE T1,[ILPTR(V1VID)] ;ADDRESS VOLID FIELD IN VOL1
MOVEI T2,6 ;6-CHARACTER FIELD
CALL CVTA6 ;CONVERT VOLID TO SIXBIT
JRST CHKV12 ;BAD VOLID, SO ASSUME UNLABELED
; GIVE ERROR IF VOLID FROM "IDENTIFY" COMMAND DOESN'T MATCH THE
; ACTUAL VOLID THAT IS RECORDED ON THE TAPE
MOVEM T1,MTAVOL(MTA) ;STORE ACTUAL VOLID IN MTA STATUS BLOCK
SKIPE MTAIDV(MTA) ;DOES ALLEGED VOLID EXIST?
CAMN T1,MTAIDV(MTA) ;YES, ALLEGED VOLID MATCH ACTUAL VOLID?
SKIPA ;NO ALLEGED VOLID, OR IT MATCHES ACTUAL
CALL [ TMCT <%I%M Cannot Change Volid Of Labeled Tape>
MOVEI T3,TMCMSG ;POINT TO MESSAGE
CALLRET BTWTON] ;TELL OPERATOR HE BLEW IT
SETZM MTAIDV(MTA) ;CLEAR ALLEGED VOLID
; COPY VOL1 TO MTA STATUS BLOCK AND CHECK FOR TOPS-20 LABEL TYPE
MOVSI T1,LBUF1 ;BLT SOURCE
HRRI T1,MTAV1(MTA) ;BLT DESTINATION
BLT T1,MTAV1+LB8WDS-1(MTA) ;TRANSFER VOL1 LABEL TO STATUS BLOCK
LDB T1,[LPTR(V1ACS)] ;GET ACCESSIBILITY CHARACTER
MOVEM T1,CT1 ;RETURN ACCESSIBILTY TO CALLER
CAIE T1,"1" ;TOPS-20 PROTECTION?
RETSKP ;NO, WILL CLASSIFY AS ANSI TAPE
MOVE T1,[ILPTR(V1SCD)] ;GET POINTER TO SYS CODE IN VOL1
MOVE T2,[POINT 7,T20SCD] ;GET POINTER TO TOPS-20 SYS CODE
CHK201: ILDB T3,T1 ;GET CHAR FROM VOL1
ILDB T4,T2 ;GET CHAR FROM TOPS-20 SYS CODE
JUMPE T4,[AOS CT2 ;MATCH SUCCESSFUL, SET TOPS-20 VOL1
RETSKP]
CAMN T3,T4 ;MATCH SO FAR?
JRST CHK201 ;YES, CONTINUE SCAN
RETSKP ;RETURN, NON-TOPS-20 VOL1
; TOPS-20 SYSTEM CODE
T20SCD: ASCIZ /DECSYS20** /
; CHKV2 - EXAMINE LABEL BUFFER FOR VOL2 RECORD
; LBUF2/ RECORD TO BE EXAMINED
; RETURNS +1: RECORD IS NOT A VOL2
; +2: RECORD IS A VOL2
; T1/ 0=NON-SCRATCH 1=SCRATCH
; T2/ TOPS-20 VOLUME PROTECTION CODE
CHKV2: SAVET ;SET UP TO RETURN VALUES TO CALLER
SETZM CT1
MOVE T1,LBUF2 ;GET FIRST 5 CHARS OF LABEL
TRZ T1,377 ;MASK DOWN TO 4 CHARACTERS
CAME T1,[ASCII/VOL2/] ;IS IT A VOL2?
RET ;NO, RETURN +1
MOVSI T1,LBUF1 ;BLT SOURCE
HRRI T1,MTAV2(MTA) ;BLT DESTINATION
BLT T1,MTAV2+LB8WDS-1(MTA) ;TRANSFER VOL2 LABEL TO STATUS BLOCK
MOVE T1,[ILPTR(V2PRO)] ;GET POINTER TO PROTECTION FIELD
CALL PROTIN ;GET PROTECTION IN T1
MOVEI T1,777777 ;BAD PROTECTION, ASSUME ACCESSIBLE
MOVEM T1,CT2 ;RETURN PROTECTION CODE TO CALLER
MOVE T2,[ILPTR(V2OWN)] ;GET POINTER TO VOL2 OWNER-NAME FIELD
MOVEI T3,V2OWNL ;GET # OF CHARACTERS TO SCAN
CHKV21: ILDB T4,T2 ;GET A CHAR FROM OWNER'S NAME
CAIE T4," " ;SPACE?
RETSKP ;NO, NOT SCRATCH SO RETURN
SOJG T3,CHKV21 ;CONTINUE SCAN
AOS CT1 ;SCAN COMPLETE, IT'S A SCRATCH
RETSKP
; CKHDR1 - CHECK LBUF2 FOR HDR1 AND PROCESS HDR1 FIELDS
; LBUF2/ LABEL TO BE EXAMINED
; MTA/ ADDR OF MTA STATUS BLOCK
; RETURNS +1: NOT HDR1 LABEL
; +2: WAS HDR1 LABEL, INFORMATION STORED IN MTA STATUS BLOCK
; T1/ HDR1 ACCESSIBILITY CODE
CKHDR1: MOVE T1,LBUF2 ;GET FIRST 5 CHARS OF LABEL
TRZ T1,377 ;MASK DOWN TO 4 CHARACTERS
CAME T1,[ASCII/HDR1/] ;IS THIS A HDR1?
RET ;NO
MOVE T1,[ILPTR(H1SET)] ;YES, POINT TO SETNAME FIELD
MOVEI T2,6 ;6-CHARACTER FIELD
CALL CVTA6 ;CONVERT SETNAME TO SIXBIT
SETZ T1, ;BAD SETNAME, ASSUME NONE
MOVEM T1,MTASET(MTA) ;STORE SET NAME IN STATUS BLOCK
MOVE T1,[ILPTR(H1EXP)] ;POINT AT EXPIRATION-DATE FIELD
CALL LDATIN ;CONVERT THE DATE FROM THE LABEL
SETZ T1, ;BAD DATE, ASSUME EXPIRED
SETO T2, ;SPECIFY CURRENT DATE/TIME
MOVX T4,IC%JUD ;WANT JULIAN FORM
ODCNV ;GET T2/ YEAR,,JULIANDAY
MOVX T3,MA%UXV
CAMLE T1,T2 ;IS THE TAPE EXPIRED?
IORM T3,MTAFLG(MTA) ;NO, SET NOT-EXPIRED FLAG
LDB T1,[LPTR(H1ACS)] ;GET ACCESSIBILITY CODE FOR CALLER
RETSKP
; CKHDR2 - CHECK LBUF2 FOR HDR2 LABEL
; LBUF2/ LABEL TO BE EXAMINED
; RETURNS +1: NOT HDR2
; +2: HDR2, T1/ TOPS-20 FILE PROTECTION CODE
CKHDR2: MOVE T1,LBUF2 ;GET 5 CHARS
TRZ T1,377 ;MASK DOWN TO 4 CHARACTERS
CAME T1,[ASCII/HDR2/] ;HDR2?
RET ;NO
MOVE T1,[ILPTR(H2PRO)] ;GET POINTER TO PROTECTION CODE FIELD
CALL PROTIN ;GET PROTECTION
MOVEI T1,777777 ;ERROR, ASSUME UNPROTECTED
RETSKP
; LBLICV - CONVERT INDUSTRY-COMPATIBLE LABEL IN LBUF1 TO 7-BIT ASCII
; LABEL IN LBUF2, USING THE FOLLOWING RULES:
; NO CONVERSION PERFORMED FOR UNLABELED TAPES
; ANSI AND TOPS-20 LABEL TYPES ASSUMED TO BE 8-BIT ASCII
; EBCDIC LABEL TYPE ASSUMED TO BE 8-BIT EBCDIC
; LBUF1/ LABEL TO BE CONVERTED, 80 8-BIT BYTES
; MTA/ ADDR OF MTA STATUS BLOCK
; RETURNS +1: ALWAYS, LBUF2/ 7-BIT ASCII EQUIVALENT OF LABEL IN LBUF1
LBLICV: SAVEQ
LOAD T1,MTALT ;GET LABEL TYPE IN T1
CAIN T1,.LTUNL ;UNLABELED?
RET ;YES, RETURN TAKING NO ACTION
DMOVE Q1,[POINT 8,LBUF1 ;GET LOAD POINTER IN Q1
POINT 7,LBUF2] ;GET GET STORE POINTER IN Q2
MOVEI T2,LBLSIZ ;GET # OF FRAMES TO PROCESS
LBLCV1: ILDB T3,Q1 ;GET A BYTE FROM LBUF1
CAIN T1,.LTEBC ;EBCDIC LABEL?
JRST [ ADJBP T3,[POINT 7,EATT,6] ;YES, POINT AT ASCII EQUIV.
LDB T3,T3 ;GET ASCII EQUIVALENT IN T3
JRST .+1]
IDPB T3,Q2 ;STORE CHARACTER IN LBUF2
SOJG T2,LBLCV1 ;LOOP THRU ENTIRE BUFFER
RET
; RDLBL - READ A LABEL FROM A TAPE
; MTA/ ADDR OF MTA STATUS BLOCK
; RETURNS +1: T1/ -1 = READ I/O OPERATION TIMED OUT
; T1/ 0 = DEVICE OR DATA ERROR ON READ
; T1/ 1 = TAPE MARK OR RECORD .LT. 80 FRAMES READ
; +2: RECORD OF 80 BYTES OR LONGER READ SUCCESSFULLY INTO
; LBUF1 IN INDUSTRY-COMPATIBLE FORMAT; ASCII EQUIVALENT
; LABEL IN LBUF2
RDLBL: MOVE T1,[IOWD LBUF1W,LBUF1] ;GET IOWD FOR ENTIRE BUFFER
SKIPN READCL ;FIRST READ SINCE I STARTED?
MOVEM T1,READCL ;YES, SET UP TRIAL IOWD, EXPECT DUMPX3
RDLBL0: LOAD T1,MTAJFN
MOVEI T2,READCL ;GET ADDRESS OF COMMAND LIST
IOXCT DUMPI,RDLBL1,RDLBL2 ;EXECUTE AND TIME OUT DUMPI JSYS
JRST RDLBL3 ;SUCCESSFUL (PROBABLY VERY RARE)
; ERROR RETURN FROM DUMPI
RDLBL1: CALL CLRTAP ;CLEAR ERRORS AND GET ERROR INFO
JRST RDLBL2 ;TIMED OUT
CAIN T1,DUMPX3 ;RECORD SIZE TOO LARGE?
JRST [ MOVSI T1,1000 ;YES
ADDM T1,READCL ;REDUCE IT BY A PAGE
JRST RDLBL0] ;TRY IT AGAIN WITH SMALLER RECORD SIZE
CAIN T1,IOX4
JRST [ MOVEI T1,1 ;TAPE MARK, SET NON-LABEL
RET]
CAIE T1,IOX5 ;DEVICE OR DATA ERROR?
CALL STOP ;NO, I CAN'T HANDLE THIS ONE
TXNE T2,MT%DVE+MT%DAE ;DEVICE ERROR OR DATA ERROR?
JRST [ SETZ T1, ;YES
RET]
CAIGE T3,LBLSIZ ;IS THE RECORD LONG ENOUGH?
JRST [ MOVEI T1,1 ;NO
RET]
RDLBL3: CALL LBLICV ;GOOD LABEL, CONVERT IT
RETSKP ;SUCCESSFUL RETURN
; DUMPI DID NOT COMPLETE IN TIME
RDLBL2: CALL WOTIMO ;REPORT TIMEOUT TO OPERATOR
SETO T1, ;RETURN -1
RET
; POLLR - SELF-PERPETUATING PERIODIC MAGTAPE POLLING ROUTINE
; CHECKS FOR ONLINE-TO-OFFLINE AND OFFLINE-TO-ONLINE TRANSITIONS
; RETURNS +1: ALWAYS
POLLR: TXO F,POLLF ;CAUSE CHECKS FOR ONLINE-TO-OFFLINE
CALL TDSCIR ;PERFORM DRIVE SCAN
TXZ F,POLLF
MOVEI T1,POLINT ;GET INTERVAL BETWEEN POLLS
MOVEI T2,POLLR ;ROUTINE ADDRESS
CALLRET SRAI ;SCHEDULE NEXT POLL AND EXIT
; TDSCIH - CALLED AS A RESULT OF MTA STATUS CHANGE INTERRUPTS
TDSCIH: AOSE TDSCF ;SCHEDULING REQUEST PRESENT ALREADY?
DEBRK ;YES, EXIT
CALL EIHR ;NO, REQUEST SCHEDULING AT TDSCIR
EXP TDSCIR
; TDSCIR - CALLED BY SCHEDULER, REQUESTED BY TDSCIH
; RETURNS +1: ALWAYS
TDSCIR: SAVEQ
SAVEAC <MTA>
SETOM TDSCF ;SET NO SCHEDULER REQUESTS FOR TDSCIR
MOVE Q1,MTAN ;GET # OF MTA DEVICES ON SYSTEM
MOVEI MTA,MTA0-MTASZ ;INIT MTA STATUS BLOCK POINTER
; I DON'T KNOW WHICH DRIVE DID IT, SO I HAVE TO CHECK EVERY ONE
TDSCI1: SOJL Q1,R ;EXIT IF NO MTA DEVICES LEFT TO CHECK
ADDI MTA,MTASZ ;GET STATUS BLOCK ADDRESS
CALL TDSC1 ;CHECK IT FOR A STATUS CHANGE
JRST TDSCI1 ;LOOP THRU ALL DRIVES
; TDSC1 - CHECK TAPE DRIVE FOR ONLINE/OFFLINE/REWIND-COMPLETE TRANSITION
; MTA/ ADDR OF MTA STATUS BLOCK
; RETURNS +1: ALWAYS
TDSC1: SAVEQ
LOAD T1,MTASTE ;GET STATE
JUMPE T1,R ;IGNORE IF NOT AVAILABLE
CAIE T1,S.INIT ;IN INIT MODE?
JRST [ JN MTAMT,,R ;NO, EXIT IF USER HAS THE DRIVE
JRST .+1]
CALL MTAGJF ;GET JFN NOW TO REDUCE GTJFN OVERHEAD
MOVE Q1,MTAFLG(MTA) ;Q1/ MTA FLAGS
CALL GMTADS
MOVE Q2,T1 ;Q2/ MTA STATUS BITS FROM MONITOR
JXN Q2,SJ%OFS,[TXZE Q1,MA%LOD ;IF OFFLINE, DID I THINK SO TOO?
CALL WOUNLW ;NO, ADMONISH OPERATOR
MOVEM Q1,MTAFLG(MTA) ;UPDATE FLAGS
JRST .+1]
LOAD Q3,MTAREA ;END-ACTION ADDRESS PRESENT?
JUMPN Q3,TDSC11 ;YES
TXNE Q1,MA%LOD ;PROCEED IF I THINK DRIVE IS UNLOADED
TXNE Q1,MA%ULP ;PROCEED IF UNLOAD PENDING
JRST TDSC11 ;ONE OF THE ABOVE WAS TRUE
TXNN F,POLLF ;POLLING?
JRST [ CALLRET MTARJF] ;NO, NO NEED FOR FURTHER ANALYSIS
TDSC11: LOAD T1,SJ%WLK,Q2 ;GET WRITE-LOCKED BIT
TRC T1,1 ;COMPLEMENT TO GET WRITE-ENABLED
STOR T1,MA%WEN,MTAFLG(MTA) ;STORE HERE FOR EASY REFERENCE
; CHECK FOR PENDING UNLOAD-REQUEST OR REWIND-ENDACTION
TXZE Q1,MA%ULP ;WAS AN UNLOAD-REQUEST PENDING?
JRST [ JXN Q2,SJ%REW,[CALLRET MTARJF] ;YES
MOVEM Q1,MTAFLG(MTA) ;RESET MA%ULP IN STATUS BLOCK
CALL UNLOAD ;UNLOAD THE DRIVE
JRST .+1]
JUMPN Q3,[JXN Q2,SJ%REW,[CALLRET MTARJF] ;EXIT IF REWINDING
SETZRO MTAREA ;CLEAR END-ACTION ADDRESS
CALL MTARJF ;DUMP JFN
CALLRET (Q3)] ;CALL END-ACTION ROUTINE AND RETURN
; DRIVE NOT UNDER USER CONTROL AND AVR SEQUENCE NOT IN PROGRESS
TXNN F,POLLF ;CHECK FOR ANY TRANSITION IF POLLING
TXNN Q1,MA%LOD ;EXIT IF I THINK THE DRIVE IS LOADED
CAIA ;POLLING OR DRIVE UNLOADED
JRST [ CALLRET MTARJF] ;NOT POLLING AND DRIVE LOADED
CALL REW ;IS IT LOADED NOW?
JRST [ TXNE Q1,MA%LOD ;NO, DID I THINK IT WAS LOADED?
CALL WOUNLW ;YES, ADMONISH OPERATOR
CALLRET MTARJF] ;DUMP JFN AND RETURN
CALL MTARJF ;YES, DUMP JFN SO AVR CAN OCCUR
TXNE Q1,MA%LOD ;HAS IT BEEN ONLINE ALL ALONG?
RET ;YES, TAKE NO ACTION
; DRIVE IS COMING ON-LINE
SETONE MA%LOD,MTAFLG(MTA) ;SET DRIVE-LOADED
MOVX T1,MA%SCR+MA%UXV+MA%OPF+MA%ULP+MA%VMG
ANDCAM T1,MTAFLG(MTA) ;CLEAR VARIOUS FLAGS
SETZB T1,MTAVOL(MTA) ;SET VOLUME NOT IDENTIFIED (YET)
SETZM MTAIDV(MTA) ;CLEAR OPERATOR-SUPPLIED VOLID
STOR T1,MTALT ;SET RECOGNITION NOT ATTEMPTED (YET)
LOAD T1,MTASTE
CAIN T1,S.INIT ;DRIVE IN INITIALIZE MODE?
JRST [ CALLRET KVITAV] ;YES, SPECIAL EXIT
CALLRET AVR ;PERFORM IDENTIFICATION SEQUENCE
NOSHIP,<
SUBTTL DECTAPE SUPPORT
; RLSDTA - PROCESS RELEASE OF ALLOC'ED DECTAPE DEVICE
; T1/ DEVICE DESIGNATOR
; RETURNS +1: ALWAYS
RLSDTA: SAVEQ
MOVE Q1,T1 ;SAVE DESIGNATOR
MOVE T2,T1 ;COPY DESIGNATOR TO T2 FOR ALLOC
MOVEI T1,.ALCAL ;ALLOC FUNCTION CODE
MOVNI T3,1 ;MAKE DTA AVAILABLE TO ALL USERS
ALLOC
JFCL ;IGNORE FAILURE
; FIND REQUEST THAT WAS USING THIS DECTAPE AND DELETE IT
TMCT <%I%5V Released>
QSCANI ARBQDB ;SET UP TO SCAN REQUEST QUEUE
RDTA1: CALL NXXRSB ;GET ADDRESS OF NEXT ACTIVE RSB
JRST RDTA2 ;NONE LEFT
LOAD T1,RSBTYP ;GET REQUEST TYPE
CAIE T1,.MNTDT ;IS IT A DECTAPE-MOUNT REQUEST?
JRST RDTA1 ;NO, SKIP IT
CAME Q1,RSBDTA(RSB) ;DOES THIS REQUEST OWN THE DECTAPE?
JRST RDTA1 ;NO
LOAD T1,RSBJNO ;GET OWNER'S JOB #
TMCT < by job %1D>
ABTREQ (ABRTNR) ;FOUND THE OWNER, DELETE REQUEST
RDTA2: MOVEI T3,TMCMSG ;GET ADDRESS OF MESSAGE
CALLRET BTWTON ;TELL OPR'S THAT DECTAPE WAS RELEASED
; TLUDT - BUILD BLOCKS FOR SUCCESSFUL DECTAPE-MOUNT RESPONSE
; (CALLED BY TELUSR)
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: ALWAYS, T1/ FLAGS FOR GALAXY MSG HEADER
TLUDT: STKVAR <<DVBLK,3>>
CALL VQGCV ;GET VOLID IN T1
TMCT <%I[DECtape volume %1S mounted]%_>
MOVEI T1,TMCMSG ;GET ADDRESS OF TEXT
MOVEI T2,.MNRTX ;GET ARGUMENT TYPE
CALL PBTXT ;CREATE BUILDING BLOCK CONTAINING TEXT
MOVE T1,[FLD(3,AR.LEN)+FLD(.MNRDV,AR.TYP)] ;GET HEADER
MOVE T2,RSBSSN(RSB) ;GET SETNAME
DMOVEM T1,DVBLK ;STORE HEADER AND SETNAME
MOVE T1,RSBDTA(RSB) ;GET DECTAPE DEVICE DESIGNATOR
MOVEM T1,2+DVBLK ;STORE DESIGNATOR IN .MNRDV BLOCK
MOVEI T1,DVBLK ;GET ADDRESS OF BLOCK
CALL PBBLK ;INSTALL BLOCK IN MESSAGE
SETZ T1, ;NO FLAGS
RET
; UDTM - PROCESS USER DECTAPE-MOUNT REQUEST RECEIVED FROM QUASAR
; T1/ ADDRESS OF DECTAPE-MOUNT ENTRY IN IPCF MESSAGE FROM QUASAR
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: ALWAYS
UDTM: MOVEI T2,[[ MOVX T1,TM%WEN ;ROUTINE TO PROCESS FLAGS
AND T1,.MEFLG(Q1)
MOVEM T1,RSBUFL(RSB)
RETSKP]
BTRSET ;SETNAME
BTRVLS ;VOLID LIST
BTRRMK ;REMARK
0]
CALL BTMRSB ;BUILD RSB
RET ;ABORTED, EXIT
MOVEI T1,1
STOR T1,RSBCV ;CURRENT VOLUME = 1
CALL PWATCH ;ABORT REQUEST IF USER DELETES PID
MOVEI T1,RST.WM
STOR T1,RSBSTE ;SET STATE = WAITING FOR MOUNT
; BUILD HEADER LINE
UDTM1: MOVE T1,RSBITN(RSB) ;GET REQUEST #
TMCT <%IDECtape Mount Request # %1D>
CALL CPYHDR ;COPY HEADER TO OPRHDR
; BUILD BODY OF MESSAGE
CALL VQGCV ;GET CURRENT VOLID IN T1
TMCT <%IMount volume %1S%_%U>
SKIPE RSBRMK(RSB) ;DID THE USER SUPPLY A REMARK?
JRST [ MOVEI T1,RSBRMK(RSB) ;YES, GET ADDR OF REMARK
TMCT <%_User's remark: %1A>
JRST .+1]
MOVE T1,RSBITN(RSB) ;GET REQUEST #
TMCT <
RESPOND msg# DTAn:
or
DELETE MOUNT-REQUEST %1D /REASON:reason>
; SEND MESSAGE AND GET RESPONSE
MOVEI T2,RSBWTB(RSB) ;GET WTB ADDRESS
MOVEI T3,OPRHDR ;GET ADDRESS OF HEADER
JSP T1,BTWTOR ;SEND WTOR AND RECEIVE REPLY
; PROCESS RESPONSE
MOVEI RSB,-RSBWTB(T2) ;LOAD RSB AC
CALL COMNDI ;INIT FOR COMND PARSING
MOVEI T2,[FLDDB. .CMDEV]
CALL COMNDX ;PARSE DEVICE NAME
UDTM2: JRST [ MOVEI T3,[ASCIZ/Response Does Not Specify DECtape/]
CALL BTACK ;REJECT IT
JRST UDTM1] ;RE-ISSUE WTOR
LOAD T1,DV%TYP,T2 ;GET DEVICE TYPE
CAIE T1,.DVDTA ;DECTAPE?
JRST UDTM2 ;NO, REJECT
MOVEI T1,.ALCAL ;GET ALLOC FUNCTION CODE
LOAD T3,RSBJNO ;GET USER'S JOB #
ALLOC ;TRY TO ALLOC DTA TO USER
JRST UDTM3 ;FAILED
; ALLOCATION SUCCESSFUL
MOVEM T2,RSBDTA(RSB) ;STORE DEVICE DESIGNATOR
MOVE T1,RSBITN(RSB) ;GET REQUEST #
TMCT <%I%2V Allocated To Request # %1D>
MOVEI T3,TMCMSG
CALL BTACK ;ACKNOWLEDGE SUCCESSFUL ALLOCATION
MOVEI T1,RST.AC
STOR T1,RSBSTE ;SET STATE TO ACTIVE
CALL TELUSR ;TELL THE USER HE GOT IT
CALLRET TCKP ;TELL QUASAR
; ALLOCATION FAILED
UDTM3: CALL [ SAVET ;PRESERVE T1-T4
TMCT <%ICannot Allocate %2V> ;BUILD HEADER
CALLRET CPYHDR] ;SAVE HEADER IN OPRHDR
CAIE T1,ALCX5 ;SOMEONE ELSE HAS IT?
JRST [ TMCT <%IError from ALLOC JSYS: %1J>
JRST UDTM4]
MOVE T1,T2 ;ANOTHER JOB HAS IT
DVCHR ;GET OWNER'S JOB # IN LH(T3)
HLRZS T3 ;MOVE TO RIGHT HALF
TMCT <%IAlready in use by job %3D>
UDTM4: MOVEI T3,OPRHDR
CALL BTACKT ;TELL OPERATOR ABOUT ALLOC FAILURE
JRST UDTM1 ;SEND WTOR AGAIN
>;NOSHIP
SUBTTL IPCF SEND AND RECEIVE
; GSYSPD - DOES MUTIL TO GET PID FROM SYSTEM PID TABLE
; T1/ INDEX INTO SYSTEM PID TABLE
; RETURNS +1: PID COULD NOT BE OBTAINED
; +2: SUCCESS, PID IN T1
GSYSPD: SKIPE TSTF ;TESTING?
JRST GSYSPT ;YES, SPECIAL CODE
MOVE T2,T1 ;COPY INDEX TO T2 FOR XMUTIL
MOVEI T1,.MURSP ;FUNCTION = RETURN SYSTEM PID
CALL XMUTIL ;GET IT
JRST [ CAIN T1,IPCF27 ;SYSTEM PID TABLE SLOT EMPTY?
RET ;YES, TAKE ERROR RETURN
CALL STOP] ;UNEXPECTED ERROR
MOVE T1,T3 ;COPY TO T1 FOR RETURN
RETSKP ;SUCCESSFUL RETURN
GSYSPT: STAKT
MOVE T2,[[EXP IP%CPD,0,0,<20,,TBUF+4>,.IPCIW,0],,TBUF]
BLT T2,TBUF+5 ;MOVE PDB AND PART OF MESSAGE TO BUF
SKIPL SYPIDS(T1) ;WANT USERNAME PREFIX?
JRST [ HRROI T1,TBUF+6 ;NO, SET UP DESTINATION POINTER
JRST GSYSP1] ;COPY PID NAME SANS PREFIX INTO TMSG
GJINF ;GET USER# IN T1
MOVE T2,T1 ;COPY INTO T2
MOVE T1,[POINT 7,TBUF+6] ;GET POINTER
MOVEI T3,"["
IDPB T3,T1
DIRST ;ADD USER NAME
JSHLT
MOVEI T2,"]"
IDPB T2,T1
GSYSP1: MOVE T2,CT1 ;GET SYSTEM PID TABLE INDEX
HRRO T2,SYPIDS(T2) ;GET POINTER TO STRING
SETZ T3, ;STOP ON NULL
SOUT ;ADD PID NAME
MOVEI T1,4
MOVEI T2,TBUF
MSEND ;SHIP OFF QUESTION TO INFO
JSHLT
SETZM TBUF ;CLEAR FLAGS WORD FOR RECEIVE
MOVE T3,TBUF+1 ;GET MY PID SO I CAN RECEIVE
MOVE T4,[20,,TBUF+4] ;SIZE,,MSGADDR
DMOVEM T3,TBUF+2 ;SET WORDS 2 & 3 OF PDB
MRECV ;RECEIVE INFO'S REPLY
JSHLT
LOAD T4,IP%CFE,TBUF+.IPCFL ;ERROR FROM INFO?
JUMPN T4,[TMSG <%MOUNTR: CAN'T GET PID FOR > ;YES
HRROI T1,TBUF+6
PSOUT ;DISPLAY PID NAME
TMSG <
>
RET]
MOVEI T1,.MUDES
MOVE T2,TBUF+2 ;GET THE PID I USED FOR THIS CRAP
CALL XMUTIL ;LIQUIDATE IT
JSHLT
MOVE T1,TBUF+5 ;GET PID FOR CALLER
RETSKP ;GIVE IT TO HIM
SYPIDS: 0
0
-1,,[ASCIZ/QUASAR/]
0,,[ASCIZ/MOUNTR/]
-1,,[ASCIZ/ORION/]
; MRCVIH - ENTERED BY SCHEDULER WHEN INTERRUPT RECEIVED FROM PID
; RETURNS +1: ALWAYS
MRCVIH: TXO F,MRMSF+MRPGF ;EXPECTING PAGE-MODE MESSAGE
; RECEIVE THE HEAD MESSAGE FROM THE QUEUE
MRCVI1: TXZN F,MRMSF ;RECEIVE QUEUE EMPTY?
RET ;YES, EXIT TO SCHEDULER
TXCN F,MRPGF ;NON-PAGE-MODE MESSAGE COMING?
JRST [ MOVX T1,IP%CFB+IP%TTL ;YES, GET FLAGS
MOVE T2,[1000,,RBUF] ;SIZE,,ADDRESS
JRST MRCVI3] ;REJOIN
MOVX T1,IP%CFB+IP%TTL+IP%CFV ;DON'T BLOCK, TRUNCATE, PAGE MODE
MOVE T2,[1000,,RBUF_-9] ;SIZE,,PAGE#
MRCVI3: MOVEM T1,.IPCFL+MRPDB ;SET FLAGS
MOVEM T2,.IPCFP+MRPDB ;SET RECEIVER BUFFER LENGTH,,ADDRESS
MOVE T3,MYPID
MOVEM T3,.IPCFR+MRPDB ;SET RECEIVER'S PID
MOVEI T1,4 ;LENGTH OF PDB
MOVEI T2,MRPDB ;ADDRESS OF PDB
MRECV ;RECEIVE THE MESSAGE
JRST [ CAIN T1,IPCFX2 ;QUEUE EMPTY?
RET ;YES, EXIT TO SCHEDULER
TXO F,MRMSF ;SET DO-MRECV FLAG
CAIN T1,IPCF16 ;WRONG MODE?
JRST MRCVI1 ;YES, TRY OTHER MODE
CALL STOP] ;CAN'T HANDLE THIS ERROR
AOS MSGSIN ;COUNT # OF MESSAGES IN
JUMPN T1,[TXNE T1,IP%CFV ;THERE IS ANOTHER MSG, WHAT MODE?
TXO F,MRPGF ;PAGE-MODE
TXO F,MRMSF ;FORCE ANOTHER MRECV
JRST .+1]
TXNN F,INITF ;DISCARD MESSAGE IF INITIALIZING
CALL MRCVPM ;PROCESS MESSAGE
JRST MRCVI1 ;GO CHECK FOR MORE MESSAGES
; REFER THE MESSAGE TO THE APPROPRIATE PROCESSING ROUTINE
MRCVPM: JN IP%CFM,MRPDB+.IPCFL,R ;DISCARD UNDELIVERED MAIL
LOAD T1,IP%CFC,MRPDB+.IPCFL ;SENT BY <SYSTEM> ?
JUMPN T1,[CALLRET MRSYS] ;YES, PROCESS IT
MOVE T1,MRPDB+.IPCFS ;GET SENDER'S PID
MOVEI T2,APNUM-1 ;# OF ASSOCIATED PROCESSES - 1
MRCVAP: CAMN T1,APPID(T2) ;FROM THIS A/P?
JRST [ CALLRET @APMRC(T2)] ;YES, GIVE IT TO HIS HANDLER
SOJGE T2,MRCVAP ;NO, CHECK THE OTHERS
RET ;I DON'T KNOW THE SENDER, SO PITCH IT
; MRSYS - PROCESS IPCF MESSAGE FROM SYSTEM TASK
; T1/ SYSTEM SENDER CODE FROM IP%CFC FIELD OF PDB
; MRPDB, RBUF/ PDB AND MESSAGE
; RETURNS +1: ALWAYS
MRSYS: CAIN T1,.IPCCF ;SENT BY INFO?
JRST [ LOAD T1,IP%CFE,MRPDB+.IPCFL ;YES, GET CODE
CAIN T1,.IPCKM ;WATCHED PID DELETED?
JRST [ CALLRET INFOK] ;YES, GO PROCESS IT
CAIE T1,.IPCBP ;BAD PID (RESPONSE TO .IPCIK) ?
RET ;I DON'T RECOGNIZE IT, SO PITCH IT
CALLRET PRQPID] ;BAD PID, CHECK REQUEST QUEUE
CAIE T1,.IPCCC ;SENT BY SYSTEM IPCF?
RET ;NO, PITCH IT
HLRZ T1,MRPDB+.IPCFP ;GET SIZE OF MESSAGE
JUMPE T1,R ;NO MESSAGE, NO WORK
MOVE T2,RBUF ;GET SYSTEM MESSAGE CODE
CAIN T2,.IPCSA
JRST [ CALLRET SALMSG] ;ALLOCATED DEVICE BEING RETURNED
CAIN T2,.IPCTR
JRST [ CALLRET SMTMSG] ;MESSAGE ABOUT MAGTAPES
CAIN T2,.IPCMS
JRST [ CALLRET ACCSTI] ;STRUCTURE COUNT BEING INCREMENTED
CAIN T2,.IPCDS
JRST [ CALLRET ACCSTD] ;STRUCTURE COUNT BEING DECREMENTED
CAIN T2,.IPCRS
JRST [ CALLRET ACCSTR] ;STRUCTURE BEING REMOVED
RET
; INFOK - PROCESS PID-KILLED MESSAGE FROM INFO
; RBUF/ PID THAT WAS KILLED
; RETURNS +1: ALWAYS
INFOK: QSCANI ARBQDB ;SET UP TO SCAN ACTIVE RSB QUEUE
SAVEAC <RSB>
INFOK1: CALL QMSCAN ;GET NEXT ENTRY FROM RSB QUEUE
RET ;NONE LEFT, SPLIT
MOVEI RSB,-RSBLNK(T2) ;GET RSB ADDRESS
MOVE T1,RSBPID(RSB) ;GET PID FROM RSB
CAMN T1,RBUF ;WAS IT KILLED?
CALL VALPID ;YES, ABORT REQUEST IF NECESSARY
JFCL
JRST INFOK1
; SALMSG - PROCESS ALLOCATED-DEVICES-RELEASED MESSAGE
; RETURNS +1: ALWAYS
SALMSG: SAVEQ
HLRZ Q1,MRPDB+.IPCFP ;GET # OF DEVICES PLUS 1
SALMS1: SOJLE Q1,[CALLRET MCHWMT] ;EXIT WHEN DEVICE LIST EXHAUSTED
MOVE T1,RBUF(Q1) ;GET DEVICE DESIGNATOR
NOSHIP,<
LOAD T2,DV%TYP,T1 ;GET DEVICE TYPE
CAIN T2,.DVDTA ;DECTAPE?
JRST [ CALL RLSDTA ;YES, CALL PROCESSOR
JRST SALMS1] ;GET NEXT DEVICE
>;NOSHIP
CALL DDMT ;CONVERT IT TO MT STATUS BLK ADDR IN MT
JRST SALMS1 ;NOT MT DEVICE, IGNORE IT
CALL MTRLS ;PROCESS RELEASE OF MT DEVICE
JRST SALMS1 ;ON TO NEXT DEVICE IN IPCF MESSAGE
; SMTMSG - PROCESS IPCF MESSAGES FROM MONITOR TAPE SERVICE
; RETURNS +1: ALWAYS
SMTMSG: SAVEQ
MOVEI Q1,RBUF+1 ;GET ADDRESS OF .VMCOD WORD
SKIPL T1,.VSMTN(Q1) ;GET MT# AND CHECK IF LESS THAN 0
CAML T1,MTN ; OR TOO BIG
CALL STOP ;ILLEGAL MT# FROM MONITOR
IMULI T1,MTSZ ;EXPAND TO OFFSET
MOVEI MT,MT0(T1) ;LOAD MT WITH ADDR OF MT STATUS BLOCK
MOVE T1,.VMCOD(Q1) ;DISPATCH BY MESSAGE SUBCODE
CAIN T1,.VMVSM
JRST SMTVS ;VOLUME-SWITCH
CALL STOP ;CODE NOT RECOGNIZED
; PROCESS VOLUME-SWITCH
SMTVS: LOAD RSB,MTRSB ;GET REQUEST STATUS BUFFER ADDRESS
CAIN RSB,MTNAV ;DOES USER OWN MT AND NO RSB?
JRST [ MOVEI T1,.MTNVV ;YES
MOVE T2,MT ;COMPUTE MT #
SUBI T2,MT0
IDIVI T2,MTSZ
MOVEI T3,[EXP 3,MREQX8,0] ;GET ARGUMENT BLOCK
MTU% ;MOUNTR CRASHED, SO YOU CAN'T VOLSWITCH
RET]
SKIPN RSB ;DO I OWN THE MT?
CALL STOP ;YES, WHAT'S GOING ON HERE?
LOAD T2,VS%COD,.VSFLG(Q1) ;TYPE OF SWITCH
SKIPLE T2 ;VALIDATE TYPE
CAILE T2,4
CALL STOP ;UNKNOWN TYPE
LOAD T1,RSBCV ;GET CURRENT VOLID INDEX
XCT [ MOVE T1,.VSCNT(Q1) ;1 - MOUNT ABSOLUTE VOLUME #
MOVEI T1,1 ;2 - MOUNT FIRST VOLUME
CALL VQCNT ;3 - MOUNT LAST VOLUME
ADD T1,.VSCNT(Q1)]-1(T2) ;4- MOUNT RELATIVE VOLUME
LOAD T2,VS%WRT,.VSFLG(Q1) ;GET READ/WRITE FLAG
LOAD T3,RSBLT ;GET LABEL TYPE
CAIN T3,.LTUNL ;UNLABELED?
SETZ T2, ;YES, DON'T REWRITE VOLUME LABELS
STOR T2,R%WVL,RSBIFL(RSB) ;SET OR RESET FLAG IN RSB
CALLRET VOLSW ;PERFORM VOLUME-SWITCH
; PIDINI - GET AND INITIALIZE PID FOR COMMUNICATION WITH THE WORLD
; RETURNS +1: ALWAYS
PIDINI: SAVEQ
; SET JOB PID QUOTA TO A LARGE VALUE
MOVEI T1,.MUSPQ ;FUNCTION = SET JOB PID QUOTA
SETO T2, ;THIS JOB
MOVEI T3,777 ;NEW QUOTA
CALL XMUTIL
JFCL
; TRY TO USE THE PID IN THE SYSTEM PID TABLE (IF IT EXISTS)
; IF THIS IS NOT POSSIBLE, CREATE A NEW PID AND USE IT
; Q1/ 0 IF I CREATED THE PID, 1 IF THE PID IS RECYCLED
SETZ Q1, ;Q1/0 MEANS I CREATED THE PID
MOVEI T1,.SPMDA ;OFFSET INTO TABLE FOR MDA PID
CALL GSYSPD ;DOES MDA PID EXIST?
JRST PIN1 ;NO
MOVEM T1,MYPID ;YES, SAVE IT
AOJA Q1,PIN2 ;TRY TO RECYCLE IT
PIN1: MOVEI T1,.MUCRE ;FUNCTION = CREATE PID
MOVE T2,[IP%JWP+.FHSLF] ;JOB-WIDE
CALL XMUTIL ;CREATE PID
CALL STOP ;CAN'T WORK WITHOUT A PID
MOVEM T3,MYPID ;STORE MY PID
PIN2: MOVEI T1,.MUPIC ;FUNCTION = PUT PID ON INTERRUPT CHANNEL
MOVE T2,MYPID ;PID
MOVEI T3,MRCVCN ;CHANNEL #
CALL XMUTIL ;CAN PID BE PUT ON INT CHANNEL?
JRST [ SOJE Q1,PIN3 ;NO, REPORT ERROR IF NOT MY PID
CALL STOP] ;CAN'T PUT MY OWN PID ON INT CHANNEL
MOVEI T1,.MUSSQ ;FUNCTION = SET SEND AND RECEIVE QUOTAS
MOVE T2,MYPID ;PID
MOVEI T3,777100 ;SEND = 777, RECEIVE = 100
CALL XMUTIL ;SET SEND/RECEIVE QUOTAS
JFCL
SKIPE Q1 ;RECYCLING OLD MDA PID?
CALL MRCVIH ;YES, DISCARD ANY CURRENT MESSAGES
; IDENTIFY MYSELF TO THE WORLD
SKIPE TSTF ;TESTING?
JRST [ SETZM TRPDB+.IPCFL ;YES, DEFINE PID TO INFO
MOVE T1,MYPID
MOVEM T1,TRPDB+.IPCFS ;SET SENDER'S PID
SETZM TRPDB+.IPCFR ;RECEIVER = INFO
MOVE T1,[4,,[.IPCII
0
ASCIZ/MOUNTR/]]
MOVEM T1,TRPDB+.IPCFP ;SET PACKET ADDRESS
MOVEI T1,4
MOVEI T2,TRPDB
MSEND
CALL STOP
JRST PIN4]
MOVEI T1,.MUSSP ;FUNCTION = SET VALUE IN SYS PID TABLE
MOVEI T2,.SPMDA ;OFFSET INTO TABLE
MOVE T3,MYPID ;PID
CALL XMUTIL ;SET MY PID AS SYSTEM MDA PID
CALL STOP
PIN4:
; OBTAIN AND REMEMBER MAXIMUM LENGTH OF NON-PAGE-MODE IPCF PACKETS
MOVEI T1,.MUMPS ;FUNCTION = RETURN MAX NON-PAGE PACKET
CALL XMUTIL
CALL STOP
MOVEM T2,SHORT ;SAVE IT
RET
; ERROR ENCOUNTERED WHILE ASSIGNING EXISTING MDA PID TO PSI CHANNEL
; THIS IMPLIES THAT ANOTHER MOUNTR IS RUNNING, SO DON'T INTERFERE
PIN3: TMSG <?MDA PID is already defined>
MOVEI T1,.MUFOJ
MOVE T2,MYPID ;GET THE PID
CALL XMUTIL ;GET JOB# OF PID'S OWNER
HALTF
TMSG < by job >
MOVEI T1,.PRIOU
MOVE T2,T3 ;COPY JOB#
MOVEI T3,12 ;BASE 10
NOUT ;DISPLAY JOB#
JFCL
HALTF
; PWATCH - TELL INFO TO WATCH THE PID IN RSBPID
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: ALWAYS
PWATCH: MOVEI T1,.IPCIK
MOVEM T1,TBUF+.IPCI0 ;STORE INFO FUNCTION CODE
MOVE T1,RSBPID(RSB)
MOVEM T1,TBUF+.IPCI2 ;STORE PID TO BE WATCHED
SETZ T1, ;SENDING TO INFO
MOVEI T2,3 ;3 WORDS
CALLRET TRANM
; TRANG - TRANSMIT GALAXY IPCF MESSAGE TO ASSOCIATED PROCESS
; TRANU - TRANSMIT GALAXY IPCF MESSAGE TO USER PROCESS
; TRANM - TRANSMIT IPCF MESSAGE TO SPECIFIED PID
; T1/ ASSOCIATED-PROCESS INDEX (TRANG) OR PID (TRANM, TRANU)
; T2/ MESSAGE LENGTH IN WORDS (TRANM ONLY)
; TBUF/ MESSAGE TO BE TRANSMITTED
; RETURNS +1: ALWAYS
TRANG: MOVE T1,APPID(T1) ;GET PID OF ASSOCIATED PROCESS
TRANU: LOAD T2,MS.CNT,TBUF+.MSTYP ;GET SIZE FROM GALAXY HEADER
JUMPE T1,TRAN1 ;IF RECEIVER PID IS 0, DON'T BOTHER
TRANM: SAVEQ
MOVEI Q1,1 ;SET UP RETRY COUNTER
; BUILD PDB AND ATTEMPT TO TRANSMIT THE MESSAGE
SETZM TRPDB+.IPCFL ;CLEAR PDB FLAGS WORD
MOVE T4,MYPID
MOVEM T4,TRPDB+.IPCFS ;STORE SENDER'S PID IN PDB
MOVEM T1,TRPDB+.IPCFR ;STORE RECEIVER'S PID IN PDB
CAMG T2,SHORT ;CAN I SEND A SHORT MESSAGE?
JRST [ MOVSM T2,TRPDB+.IPCFP ;YES, SET SIZE IN PDB
MOVEI T2,TBUF
HRRM T2,TRPDB+.IPCFP ;INSTALL MSG ADDRESS IN PDB
JRST TRAN2] ;SKIP PAGE-MODE STUFF
MOVX T2,IP%CFV
IORM T2,TRPDB+.IPCFL ;SET PAGE-MODE IN PDB
MOVE T2,[1000,,TBUF_-9]
MOVEM T2,TRPDB+.IPCFP ;SET SIZE,,PAGE#
TRAN2: MOVEI T1,4 ;PDB LENGTH
MOVEI T2,TRPDB ;PDB ADDRESS
MSEND ;SEND THE MESSAGE
JRST TRAN3 ;FAILED
TRAN1: SETZM TBUF ;CLEAR 1ST WORD OF TBUF
MOVE T1,[TBUF,,TBUF+1] ;BLT SOURCE AND DESTINATION
BLT T1,TBUF+777 ;CLEAR TBUF FOR NEXT CALLER
RET
; IPCF TRANSMIT FAILED, FIND OUT WHY
TRAN3: CAIN T1,IPCFX4
JRST TRAN1 ;RECEIVER'S PID IS INVALID
CAIN T1,IPCFX5
JRST TRAN1 ;THE JERK DISABLED HIS PID
CAIN T1,IPCFX6
JRST TRAN4 ;SEND QUOTA EXCEEDED
CAIN T1,IPCFX7
JRST TRAN5 ;RECEIVE QUOTA EXCEEDED
CAIN T1,IPCFX8
JRST TRAN4 ;IPCF FREE SPACE EXHAUSTED
CALL STOP ;I CAN'T HANDLE THIS ERROR
TRAN5: SOJL Q1,TRAN1 ;GIVE UP IF RETRY COUNT EXHAUSTED
TRAN4: MOVEI T1,^D1000 ;RETRYABLE FAILURE
DISMS ;DELAY
JRST TRAN2 ;TRY IT AGAIN
SUBTTL LABELED TAPE INITIALIZATION
; LTINIT - CHECK IF LABELED TAPE MUST BE INITIALIZED, AND IF SO,
; WRITE VOLUME LABELS AND A DUMMY FILE ON THE TAPE
; MTA/ ADDR OF MTA STATUS BLOCK
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: ERROR, TAPE DISMOUNTED OR REQUEST ABORTED
; +2: SUCCESS, TAPE IS PROPERLY PREPARED
LTINIT: MOVX T1,R%WVL
TDNN T1,RSBIFL(RSB) ;SKIP IF LABELS MUST BE WRITTEN
RETSKP ;YES, SHOULDN'T WRITE LABELS!
CALL OWCHK ;OVERWRITE PERMITTED?
RET ;NO, REQUEST ABORTED
LOAD T1,RSBDEN ;GET DESIRED DENSITY
STOR T1,MTADEN ;OPEN MTA AT THAT DENSITY
LOAD T1,RSBLT ;GET LABEL TYPE
STOR T1,MTALT ;SET NEW LABEL TYPE OF TAPE
CALL MTAOPO ;OPEN MTA FOR OUTPUT
JRST [ CALLRET UNLOAD] ;WRITE PROTECTED OR OFFLINE ???
MOVEI T1,.MOREW
MOVEI T2,1
CALL XMTOPR ;REWIND TAPE (SHOULDN'T TAKE LONG)
JRST LTINI1
LOAD T1,RSBLT
CAIN T1,.LTUNL ;UNLABELED TAPE?
JRST [ SETZM LBUF1 ;YES
MOVE T1,[LBUF1,,LBUF1+1]
BLT T1,LBUF1+^D19 ;ZERO THE BUFFER
MOVEI T1,LBUF1 ;GET BUFFER ADDRESS
CALL WRTLBL ;WRITE A RECORD OF ZEROS
JRST LTINI2 ;ERROR
JRST LTINI0] ;SUCCESSFUL, GO WRAP UP
CALL BLDV1 ;BUILD VOL1 LABEL
MOVEI T1,MTAV1(MTA) ;GET ADDRESS OF VOL1
CALL WRTLBL ;WRITE VOL1
JRST LTINI2 ;ERROR
SETZM MTAV2(MTA) ;ZAP VOL2 BUFFER
LOAD T1,RSBLT ;GET LABEL TYPE
CAIN T1,.LTT20 ;IS THIS A TOPS-20 VOLUME?
JRST [ CALL BLDV2 ;YES, BUILD VOL2 LABEL
MOVEI T1,MTAV2(MTA) ;GET ADDRESS OF VOL2
CALL WRTLBL ;WRITE VOL2
JRST LTINI2 ;ERROR
JRST .+1]
; --- USER VOLUME LABELS WOULD BE WRITTEN HERE ---
CALL BLDH1 ;BUILD HDR1 FOR DUMMY FILE
MOVEI T1,LBUF1 ;GET ADDRESS OF HDR1
CALL WRTLBL ;WRITE HDR1
JRST LTINI2 ;ERROR
MOVEI T1,.MOEOF
MOVEI T2,2 ;REPEAT COUNT
CALL XMTOPR ;DOUBLE TAPE MARK FRAMING EMPTY FILE
JRST LTINI1
CALL BLDEF1 ;BUILD EOF1
MOVEI T1,LBUF1 ;GET ADDRESS OF EOF1
CALL WRTLBL ;WRITE EOF1
JRST LTINI2
LTINI0: MOVEI T1,.MOEOF
MOVEI T2,2 ;REPEAT COUNT
CALL XMTOPR ;WRITE DOUBLE TAPE MARK
JRST LTINI1
CALL REW ;REWIND TAPE
JRST LTINI2 ;OFFLINE ERROR
CALL MTACLS ;CLOSE TAPE
RETSKP ;I DID IT!!
; DEVICE ERROR OR TIMEOUT OCCURRED
LTINI1: CALL XMTREP ;TELL OPERATOR ABOUT ERROR OR TIMEOUT
LTINI2: CALL UNLOAD ;UNLOAD THE TAPE FROM THE DRIVE
CALL MTACLS ;CLOSE THE JFN
CALLRET WOLINF ;TELL OPERATOR LABEL INIT FAILED
; WRTLBL - WRITE A LABEL TO TAPE
; T1/ ADDRESS OF INDUSTRY-COMPATIBLE FORMAT LABEL
; MTA/ ADDR OF MTA STATUS BLOCK
; RETURNS +1: I/O ERROR OR DRIVE TIMED OUT
; +2: LABEL WRITTEN SUCCESSFULLY
WRTLBL: STKVAR <<WCLIST,2>>
SUBI T1,1 ;GET BUFFER ADDRESS MINUS 1
HRLI T1,-LBLSIZ/4 ;GET MINUS # OF WORDS TO WRITE
MOVEM T1,WCLIST ;STORE IOWD
SETZM 1+WCLIST ;FOLLOW IOWD WITH ZERO WORD
LOAD T1,MTAJFN ;GET JFN
MOVEI T2,WCLIST ;GET COMMAND LIST ADDRESS
IOXCT DUMPO,WRTLB1,WRTLB2 ;DO THE I/O
RETSKP ;SUCCESS
WRTLB1: CALL CLRTAP ;CLEAR ERRORS, GET ERROR CODE IN T1
JRST WRTLB2 ;TIMED OUT
CAIN T1,IOX5 ;DEVICE OR DATA ERROR?
RET ;YES, TELL CALLER
CALL STOP ;I CAN'T HANDLE THIS
WRTLB2: CALLRET WOTIMO ;TELL OPERATOR ABOUT TIMEOUT AND TAKE +1
; BLDV1 - BUILD VOL1 LABEL
; MTA/ ADDR OF MTA STATUS BLOCK
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: ALWAYS, VOL1 LABEL IN MTAV1 IN MTA STATUS BLOCK
BLDV1: DMOVE T1,[ASCII/VOL1 /]
DMOVEM T1,LBUF2 ;SET FIRST 2 WORDS OF VOL1
MOVE T1,[LBUF2+1,,LBUF2+2]
BLT T1,LBUF2+LB7WDS-1 ;SET THE REST TO BLANKS
MOVE T1,MTAVOL(MTA) ;GET VOLID
MOVE T2,[ILPTR(V1VID)] ;GET DESTINATION POINTER
CALL SIXASC ;PUT VOLID IN LABEL
LOAD T1,RSBLT ;GET LABEL TYPE
CAIN T1,.LTEBC ;EBCDIC?
JRST BLDV11 ;YES, SKIP ANSI/TOPS20 STUFF
CAIN T1,.LTT20 ;IS THIS A TOPS-20 VOLUME?
JRST [ MOVEI T1,"1" ;YES
DPB T1,[LPTR(V1ACS)] ;SET ACCESSIBILITY FIELD
HRROI T1,T20SCD
MOVE T2,[ILPTR(V1SCD)]
CALL MOVSTR ;PUT TOPS-20 SYSTEM CODE IN VOL1
JRST .+1]
HRROI T1,[ASCIZ/D%K/]
MOVE T2,[ILPTR(V1OWN)]
CALL MOVSTR ;PUT MACHINE CODE IN OWNER-ID FIELD
MOVEI T1,DECV
DPB T1,[LPTR(V1DECV)] ;STORE DEC STANDARD VERSION
MOVEI T1,ANSV
DPB T1,[LPTR(V1ANSV)] ;STORE ANSI STANDARD VERSION
SKIPA T2,[ILPTR(V1INAM)] ;GET POINTER TO ANSI/TOPS20 OWNER NAME
BLDV11: MOVE T2,[ILPTR(V1INME)] ;GET POINTER TO EBCDIC OWNER NAME
HRROI T1,TAPNAM ;POINT TO INSTALLATION NAME
CALL MOVSTR ;COPY INSTALLATION NAME INTO LABEL
MOVEI T1,MTAV1(MTA) ;GET DESTINATION ADDRESS
CALLRET LBLOCV ;CONVERT TO OUTPUT FORMAT AND RETURN
; BLDV2 - BUILD VOL2 LABEL
; MTA/ ADDR OF MTA STATUS BLOCK
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: ALWAYS, VOL2 LABEL IN MTAV2 IN MTA STATUS BLOCK
BLDV2: DMOVE T1,[ASCII/VOL2 /]
DMOVEM T1,LBUF2 ;SET FIRST 2 WORDS OF VOL2
MOVE T1,[LBUF2+1,,LBUF2+2]
BLT T1,LBUF2+LB7WDS-1 ;SET THE REST TO BLANKS
MOVE T1,[ILPTR(V2PRO)] ;GET POINTER TO ACCESS CODE FIELD
LOAD T2,RSBVPR ;GET PROTECTION CODE
TRO T2,770000 ;FORCE COMPLETE OWNER ACCESS
TRZ T2,007700 ;CLEAR WORLD ACCESS (NOT DEFINED YET)
MOVE T3,[6,,10] ;FIELD WIDTH,,RADIX
CALL FNOUT ;PUT NUMERIC FIELD IN LABEL
HRROI T1,[ASCIZ/000000000000/] ;DUMMY PPN
MOVE T2,[ILPTR(V2PPN)]
CALL MOVSTR ;INSTALL PPN
HRROI T1,MTAV2(MTA) ;USE MTAV2 TEMPORARILY
MOVE T2,RSBUNO(RSB) ;USER'S USER #
DIRST ;TRANSLATE USER # TO STRING
SETZM MTAV2(MTA)
HRROI T1,MTAV2(MTA) ;(ALL THIS FUDGING IS BECAUSE DIRST
MOVE T2,[ILPTR(V2OWN)] ; PUTS AN UNWANTED NULL AT THE END)
CALL MOVSTR ;TRANSFER OWNER'S NAME TO LABEL
MOVEI T1,MTAV2(MTA) ;GET DESTINATION ADDRESS
CALLRET LBLOCV ;CONVERT TO OUTPUT FORMAT AND RETURN
; BLDH1 - BUILD DUMMY HDR1 LABEL
; BLDEF1 - BUILD DUMMY EOF1 LABEL
; MTA/ ADDR OF MTA STATUS BLOCK
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: ALWAYS, LABEL IN LBUF1
BLDH1: SKIPA T1,[ASCII/HDR1D/]
BLDEF1: MOVE T1,[ASCII/EOF1D/]
MOVEM T1,LBUF2 ;SET FIRST WORD OF LABEL
MOVE T1,[SKEL1,,LBUF2+1]
BLT T1,LBUF2+LB7WDS-1 ;SUPPLY REMAINDER OF SKELETON
MOVE T1,MTAVOL(MTA) ;GET VOLID
MOVE T2,[ILPTR(H1SET)] ;GET DESTINATION POINTER
CALL SIXASC ;PUT VOLID IN FILE SET NAME FIELD
SETO T2, ;SPECIFY CURRENT DATE/TIME
MOVX T4,IC%JUD ;WANT JULIAN FORM
ODCNV ;GET T2/ YEAR,,JULIANDAY
HLRZ T1,T2 ;GET YEAR
SUBI T1,^D1900 ;DROP CENTURY PART
IMULI T1,^D1000 ;DECIMAL SHIFT
HRRZS T2 ;ISOLATE DAY IN T2
ADD T2,T1 ;GET T2/ YYDDD (DECIMAL)
MOVE T1,[ILPTR(H1CRE+1)] ;GET POINTER TO LABEL FIELD
MOVE T3,[5,,12] ;5 CHARS WIDE, BASE 10
CALL FNOUT ;EDIT CREATION DATE INTO LABEL
MOVEI T1,LBUF1 ;GET DESTINATION ADDRESS
CALLRET LBLOCV ;CONVERT TO OUTPUT FORMAT AND RETURN
SKEL1: ASCII /UMMY-FILE-0000 0001000100010/ ;CP 6-40
ASCII/0 00000 000000DECSYSTEM20 / ;CP 41-80
; LBLOCV - CONVERT 7-BIT ASCII LABEL IN LBUF2 TO 8-BIT ASCII OR EBCDIC
; T1/ ADDRESS OF DESTINATION LABEL
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: ALWAYS
LBLOCV: SAVEQ
HRLI T1,(POINT 8,0) ;MAKE POINTER TO DESTINATION
MOVE T2,[POINT 7,LBUF2] ;GET POINTER TO SOURCE
MOVEI T3,LBLSIZ ;GET # OF BYTES IN LABEL
LOAD T4,RSBLT ;GET LABEL TYPE
LBLOC1: ILDB Q1,T2 ;GET SOURCE BYTE
CAIN T4,.LTEBC ;EBCDIC LABEL?
JRST [ ADJBP Q1,[POINT 8,AETT,7] ;YES, GET POINTER TO TABLE
LDB Q1,Q1 ;TRANSLATE ASCII TO EBCDIC
JRST .+1]
IDPB Q1,T1 ;STORE BYTE IN DESTINATION
SOJG T3,LBLOC1
RET
; OWCHK - CHECK IF USER MAY OVERWRITE TAPE VOLUME
; MTA/ ADDR OF MTA STATUS BLOCK
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: OVERWRITE NOT PERMITTED, REQUEST ABORTED
; +2: OVERWRITE PERMITTED
OWCHK: JN R%PRIV,RSBIFL(RSB),RSKP ;PRIVILEGED USERS CAN DO ANYTHING
MOVE T1,MTAFLG(MTA) ;GET FLAGS
JXN T1,MA%UXV,[ABTRET (MREQ28)] ;ERROR IF FIRST FILE NOT EXPIRED
JXN T1,MA%SCR,RSKP ;OK IF IT'S A SCRATCH TAPE
LOAD T1,MTALT ;GET LABEL TYPE
LOAD T2,MA%OPF,MTAFLG(MTA) ;GET OVERWRITE-PROTECT FLAG
JRST @OWCDV(T1) ;DISPATCH ACCORDING TO LABEL TYPE
OWCDV: IFIW!RSKP ;LABEL TYPE NOT KNOWN YET
IFIW!RSKP ;UNLABELED
IFIW!OWCANS ;ANSI
IFIW!OWCPV ;EBCDIC (WRITE ACCESS NOT SUPPORTED)
IFIW!OWCT20 ;TOPS-20
MAXLT
OWCANS: JUMPE T2,RSKP ;OK IF FLAG IS RESET
OWCPV: ABTRET (MREQ29) ;OVERWRITE ACCESS VIOLATION, ABORT REQ
OWCT20: JUMPE T2,RSKP ;OK IF FLAG RESET
STKVAR <<OWNER,10>>
MOVEI T1,OWNER ;PROVIDE WORK AREA FOR GETVU
CALL GETVU ;GET TAPE-OWNER'S USER # IN T2
CAME T2,RSBUNO(RSB) ;TAPE USER # MATCH REQUESTOR USER # ?
JRST OWCPV ;NO, PROTECTION VIOLATION
RETSKP ;YES, YOU OWN IT, SO YOU CAN OVERWRITE
SUBTTL OPERATOR INTERFACE
; BADOM, BADQM - TYPE A MESSAGE ON CTY INDICATING THAT I RECEIVED A
; BAD IPCF MESSAGE FROM ORION OR QUASAR
; RETURNS +1: ALWAYS
BADOM: SKIPA T1,[[ASCIZ/ORION/]]
BADQM: MOVEI T1,[ASCIZ/QUASAR/]
MOVE T2,[RBUF,,BADMSG]
BLT T2,BADMSG+777 ;MAKE A COPY JUST FOR THE RECORD
TMCT <%IBad IPCF message received from %1A>
LOAD T1,MS.TYP,RBUF+.MSTYP ;GET MESSAGE TYPE
CAIN T1,MT.TXT ;TEXT MESSAGE?
CALL [ MOVEI T1,RBUF+.OHDRS+ARG.DA ;YES, POINT TO TEXT
TMCTR <%_TEXT MESSAGE: %1A>] ;DISPLAY IT
MOVEI T3,[ASCIZ/MOUNTR System Task Error/]
CALLRET BTWTO ;OUT TO CTY AND RETURN
; TO CLEAR SOME OF THE CONFUSION HERE, AN "ACK" IS USED WHEN SENDING
; TEXT TO A PARTICULAR OPR (E.G. WHEN TELLING THE OPERATOR THAT
; HE MADE A BAD KEYIN), WHEREAS "WTO" AND "WTOR" MESSAGES ARE SEEN
; BY ALL USERS RUNNING OPR THE TIME THE MESSAGE IS RECEIVED BY ORION.
; ALL OF THE BTxxx ROUTINES RETURN +1 ALWAYS
; BTACK - BUILD AND TRANSMIT ACK MESSAGE WITHOUT TEXT
; RBUF+.MSCOD/ ID OF OPR WHO WILL RECEIVE ACK
; T3/ ADDRESS OF ASCIZ MESSAGE TYPE
; BTACKT - BUILD AND TRANSMIT ACK MESSAGE WITH TEXT
; TMCMSG/ ASCIZ MESSAGE TO BE TRANSMITTED
; T3/ ADDRESS OF ASCIZ MESSAGE TYPE
; BTWTO - BUILD AND TRANSMIT WTO MESSAGE
; TMCMSG/ ASCIZ MESSAGE TO BE TRANSMITTED
; T3/ ADDRESS OF ASCIZ MESSAGE TYPE
; BTWTOR - BUILD AND TRANSMIT WTOR MESSAGE
; TMCMSG/ ASCIZ MESSAGE TO BE TRANSMITTED
; T1/ 0 ,, ADDR OF ROUTINE TO BE SCHEDULED WHEN RESPONSE IS RECEIVED
; T2/ ADDRESS OF WTB
; T3/ ADDRESS OF ASCIZ MESSAGE TYPE
BTACK: SKIPA T4,[1B0+.OMACK] ;ACK MESSAGE, NO TEXT BLOCK
BTACKT: MOVEI T4,.OMACK ;ACK MESSAGE WITH TEXT BLOCK
JRST BT1 ;ENTER COMMON CODE
BTWTON: MOVE T4,[1B0+.OMWTO] ;WTO MESSAGE WITHOUT TEXT BLOCK
JRST BT1
BTWTOR: SKIPA T4,[.OMWTR] ;WTOR MESSAGE
BTWTO: MOVEI T4,.OMWTO ;WTO MESSAGE
BT1: STAKT ;STACK T1-T4
SETZ T1,
EXCH T1,BTFLGS ;GET CURRENT FLAGS AND CLEAR WORD
TXO T1,WT.SJI ;ALWAYS SUPPRESS JOB INFORMATION
MOVEM T1,TBUF+.OFLAG ;SET FLAGS WORD OF MESSAGE TO ORION
; CONSTRUCT BUILDING BLOCKS IN IPCF MESSAGE TO ORION
CALL PBINIT ;SET UP TO CREATE BUILDING BLOCKS
MOVEI T1,[2,,.WTOCD
.OTMNT]
CALL PBBLK ;INSERT MESSAGE CLASSIFICATION BLOCK
MOVEI T1,TMCMSG ;ADDR OF FORMATTED TEXT
MOVEI T2,.WTTXT ;TYPE CODE
SKIPL CT4 ;TEXT PRESENT?
CALL PBTXT ;YES, INSTALL IT
HRRZ T1,CT3 ;ADDR OF ASCIZ MESSAGE TYPE
MOVEI T2,.WTTYP ;TYPE CODE
CALL PBTXT ;INSTALL MESSAGE TYPE TEXT
; BUILD GALAXY HEADER AND SHIP THE MESSAGE OFF TO ORION
HRRZ T1,CT4 ;GET MESSAGE TYPE
CAIE T1,.OMACK ;ACK MESSAGE?
AOSA T3,UNIQUE ;NO, GET A UNIQUE NUMBER
MOVE T3,RBUF+.MSCOD ;YES, GET OPR ID
MOVE T2,PBBPT
SUBI T2,TBUF ;COMPUTE SIZE OF IPCF MESSAGE
HRL T1,T2 ;GET LENGTH,,MSGTYPE
SETZ T2, ;NO FLAGS
CALL GALHDR ;BUILD GALAXY MESSAGE HEADER IN TBUF
MOVEI T1,.APORN ;GOING TO ORION
CALL TRANG ;QUEUE IT UP FOR TRANSMISSION
HRRZ T1,CT4 ;GET FUNCTION CODE
CAIE T1,.OMWTR ;WHAT FUNCTION?
RET ;NOT WTOR - ALL DONE
; WTOR - MAKE ENTRY IN RESPONSE-EXPECTED QUEUE
MOVE T1,CT2 ;GET WTB ADDRESS
SKIPE WTBCOD(T1) ;MESSAGE OUTSTANDING?
CALL STOP ;YES, PROGRAM LOGIC ERROR
MOVE T2,UNIQUE
MOVEM T2,WTBCOD(T1) ;SAVE ACK CODE
XMOVEI T2,20
HRR T2,CT1
MOVEM T2,WTBENT(T1) ;SAVE CALLER'S GLOBAL ENTRY ADDRESS
MOVEI T2,WTBLNK(T1) ;GET ADDRESS OF PACKET LINKAGE WORD
MOVEI T1,WTRQDB ;GET QUEUE DESCRIPTOR BLOCK ADDRESS
CALLRET QMQT ;PUT PACKET ON EXPECTED-RESPONSE QUEUE
; BTJOB - REQUEST WT.JOB BE SET IN NEXT MESSAGE TO ORION
; BTNFO - REQUEST WT.NFO BE SET IN NEXT MESSAGE TO ORION
; RETURNS +1: ALWAYS
BTJOB: SKIPA T1,[WT.JOB]
BTNFO: MOVX T1,WT.NFO
IORM T1,BTFLGS ;SET APPROPRIATE FLAG
RET
; CANWTR - CANCEL AN OUTSTANDING WTOR MESSAGE
; T1/ ACK CODE FROM WTB
; RETURNS +1: ALWAYS
CANWTR: QSCANI WTRQDB ;SET UP TO SCAN OUTSTANDING WTOR QUEUE
STKVAR <CANCOD>
MOVEM T1,CANCOD ;SAVE ACK CODE
; SEARCH WTB QUEUE FOR THE WTB WITH THE SPECIFIED ACK CODE
CANWT1: CALL QMSCAN ;GET ADDRESS OF NEXT WTB ON CHAIN
CALL STOP ;END OF LIST, EXPECTED WTB MISSING
MOVE T3,WTBCOD(T2) ;GET ACK CODE FROM WTB
CAME T3,CANCOD ;IS THIS THE ONE THE CALLER WANTS?
JRST CANWT1 ;NO, CONTINUE SEARCH
; FOUND THE WTB FOR THE WTOR REQUEST THAT'S GOING TO BE CANCELED
; BUILD AND TRANSMIT CANCEL-WTOR MESSAGE TO ORION
CALL QMDQS ;DEQUEUE WTB
SUBI T2,WTBLNK ;GET WTB ADDRESS IN T2
SETZM WTBCOD(T2) ;MARK WTB AS INACTIVE
MOVE T1,[.OARGC+1,,.OMWTR] ;BUILD GALAXY HEADER
SETZ T2, ; FLAGS
MOVE T3,CANCOD ; ACK CODE
CALL GALHDR
MOVX T1,WT.KIL+WT.SJI ;GET FLAG FOR KILL-WTOR
MOVEM T1,TBUF+.OFLAG
SETZM TBUF+.OARGC ;NO ARGUMENTS
MOVEI T1,.APORN ;MESSAGE GOING TO ORION
CALLRET TRANG ;SEND CANCEL REQUEST TO ORION
; CMDCFM - PARSE END-OF-LINE
; CSB/ COMND STATE BLOCK
; RETURNS +1: ERROR, MESSAGE SENT TO OPERATOR
; +2: SUCCESS
CMDCFM: MOVEI T2,[FLDDB. .CMCFM]
CALL COMNDX ;PARSE IT
SKIPA ;ERROR
RETSKP ;SUCCESS
JSP T1,RSPERR
ASCIZ/Superfluous information at end of response/
; COMNDI - SET UP COMND STATE BLOCK FOR PARSING OPERATOR RESPONSE
; T1/ ADDRESS OF ASCIZ OPERATOR RESPONSE TEXT
; RETURNS +1: ALWAYS, CSB SET UP FOR PARSING
COMNDI: STAKT ;STACK T1-T4
TMCT <%I> ;INIT MESSAGE COMPOSER
MOVE T1,CT1 ;GET ADDRESS OF RESPONSE TEXT
CALL TMCRSP ;COPY TEXT TO THE WIDE OPEN SPACES
MOVX T3,CM%RAI+CM%XIF ;RAISE INPUT, NO INDIRECT FILE
MOVEM T3,CSB+.CMFLG
SETZM CSB+.CMIOJ ;SET BAD JFNS TO PREVENT TTY I/O
HRROI T3,[0]
MOVEM T3,CSB+.CMRTY ;CTRL/R BUFFER BYTE POINTER
HRROI T1,TMCMSG
MOVEM T1,CSB+.CMBFP ;BEGINNING OF INPUT
MOVEM T1,CSB+.CMPTR ;POINTER TO NEXT FIELD TO BE PARSED
MOVEI T2,5000
MOVEM T2,CSB+.CMCNT ;SIZE OF AREA AFTER .CMPTR
MOVEM T2,CSB+.CMINC ;# OF UNPARSED CHARS AFTER .CMPTR
HRROI T3,ATMBFR
MOVEM T3,CSB+.CMABP ;POINTER TO ATOM BUFFER
MOVEI T3,ATMSIZ*5
MOVEM T3,CSB+.CMABC ;SIZE OF ATOM BUFFER (CHARACTERS)
SETZM CSB+.CMGJB ;GTJFN BUFFER ADDRESS
RET
; COMNDX - EXECUTE COMND JSYS TO PARSE OPERATOR RESPONSE IN CORE
; T2/ ADDRESS OF FUNCTION DESCRIPTOR BLOCK CHAIN
; CSB/ COMND JSYS STATE BLOCK SET UP BY COMNDI SUBROUTINE
; RETURNS +1: PARSE FAILED
; +2: PARSE SUCCEEDED, T2/ T2 RETURNED BY COMND JSYS
; T3/ ADDRESS OF FDB ACTUALLY USED
COMNDX: SAVEQ
MOVE T1,CSB+.CMINC ;GET # OF UNPARSED CHARACTERS
CAIN T1,5000 ;FIRST PARSE FOR THIS COMMAND LINE?
JRST [ MOVX Q1,FLD(.CMCFM,CM%FNC) ;YES
HRR Q1,T2 ;PREFIX CALLER'S FDB WITH CONFIRM FDB
MOVEI T2,Q1 ;SUBSTITUTE THE ADDRESS OF MY FDB
JRST .+1]
MOVEI T1,CSB ;GET ADDRESS OF COMND STATE BLOCK
COMND ;CALL MONITOR
ERJMP R ;JSYS FAILED, MAKE LIKE PARSE ERROR
HRRZS T3 ;GET ACTUAL FDB ADDRESS IN T3
TXNN T1,CM%NOP ;PARSE ERROR?
CAIN T3,Q1 ; OR NULL COMMAND LINE?
RET ;YES, RETURN +1, ERROR CODE IN T2
RETSKP
; COMNDV - PARSE A VOLID WITHIN OPERATOR RESPONSE
; CSB/ COMND JSYS STATE BLOCK
; RETURNS +1: BAD VOLID, ERROR MESSAGE SENT TO OPERATOR
; +2: SUCCESS, T1/ SIXBIT VOLID
COMNDV: MOVEI T2,[FLDDB.(.CMQST,,,,,[FLDDB.(.CMFLD)])]
CALL COMNDX ;PARSE QUOTED STRING OR FIELD
SETZM ATMBFR ;SYNTACTICAL ERROR
MOVEI T1,ATMBFR ;GET STRING ADDRESS
CALL ASCIZL ;GET LENGTH OF VOLID IN T2
JUMPE T2,[JSP T1,RSPERR ;ERROR IF NULL VOLID
ASCIZ/Syntactical error in volume-id/]
CAILE T2,6 ;TOO LONG?
JRST [ JSP T1,RSPERR ;YES
ASCIZ/Volume identifier longer than 6 characters/]
MOVE T1,[POINT 7,ATMBFR] ;GET POINTER TO ASCII VOLID
CALL CVTA6R ;CONVERT VOLID TO SIXBIT
JRST [ JSP T1,RSPERR ;ERROR
ASCIZ/Illegal volume identifier/]
RETSKP ;LOOKS GOOD, RETURN IT TO CALLER
; INWTOR - PROCESS INCOMING RESPONSE TO OUTSTANDING WTOR MESSAGE
; RBUF/ IPCF MESSAGE FROM ORION, MESSAGE TYPE = .OMRSP
; RETURNS +1: ALWAYS
INWTOR: QSCANI WTRQDB ;SET UP TO SCAN OUTSTANDING WTOR QUEUE
STKVAR <WTBAD>
; SCAN OUTSTANDING WTOR MESSAGE QUEUE FOR THE MESSAGE THAT
; MATCHES UP WITH THE RESPONSE I JUST GOT
INWTO1: CALL QMSCAN ;GET ADDR OF NEXT PACKET IN QUEUE
RET ;RACE - OPERATOR RESPONDED TO MESSAGE
;JUST BEFORE ORION GOT MY KILL ORDER
MOVE T3,WTBCOD-WTBLNK(T2) ;GET ACK CODE FROM ENTRY
CAME T3,RBUF+.MSCOD ;DOES IT MATCH CODE IN IPCF MESSAGE?
JRST INWTO1 ;NO, CONTINUE SCAN
; THE RESPONSE HAS BEEN IDENTIFIED - DEQUEUE THE WTB,
; LOAD AC'S FOR HANDLER, AND SCHEDULE IT
CALL QMDQS ;DEQUEUE THIS ENTRY, GET ADDR IN T2
SUBI T2,WTBLNK ;SUBTRACT LINKAGE WORD OFFSET
MOVEM T2,WTBAD ;SAVE ADDRESS OF WTB
SETZM WTBCOD(T2) ;MARK WTB AS INACTIVE
MOVEI T1,.ACKID
CALL ORNBLF ;LOOK UP OPR-IDENTIFIER BLOCK
SETZ T2, ;NOT THERE
JUMPE T2,[CALLRET BADOM] ;BLOCK NOT THERE OR TOO SHORT
MOVE T1,(T1) ;GET ID OF RESPONDING OPR
MOVEM T1,RBUF+.MSCOD ;SET IN CASE I WANT TO CALL BTACK
MOVEI T1,.CMTXT ;SPECIFY ARG TYPE I WANT
CALL ORNBLF ;SCAN ARG LIST FOR RESPONSE
JRST [ CALLRET BADOM] ;NO RESPONSE BLOCK, BAD MSG FROM ORION
HRLI T1,(POINT 7) ;CONSTRUCT POINTER TO RESPONSE TEXT
MOVE T2,WTBAD ;GET WTB ADDRESS IN T2
; ENTER RESPONSE PROCESSOR WITH THE FOLLOWING AC SETUP:
; T1/ BYTE POINTER TO ASCIZ RESPONSE FROM OPERATOR
; T2/ ADDRESS OF WTB
CALLRET @WTBENT(T2) ;CALL BTWTOR CLEANUP CODE
; KC ROUTINES - CHECK FOR VARIOUS TAPE DRIVE CONDITIONS
; MTA/ ADDR OF MTA STATUS BLOCK
; RETURNS +1: CONDITION NOT SATISFIED, ERROR MESSAGE SENT TO OPERATOR
; +2: CONDITION SATISFIED
; CHECK FOR DRIVE AVAILABLE TO USERS
KCAVL: LOAD T2,MTASTE ;GET STATE
CAIN T2,S.AV ;AVAILABLE?
RETSKP ;YES
MOVEI T1,[ASCIZ/Not Under Operator Control/]
JUMPE T2,KC1 ;JUMP IF DRIVE NOT ASSIGNED
JSP T1,KC1 ;ONLY OTHER CASE IS INITIALIZING
ASCIZ/In INITIALIZE Mode/
; CHECK IF DRIVE IS LOADED
KCLOAD: JN MA%LOD,MTAFLG(MTA),RSKP
JSP T1,KC1
ASCIZ/Not Loaded/
; CHECK IF DRIVE IS IN USE BY ME OR USER
KCUSE: SAVEAC <MT,RSB>
JN MTAJCT,,[TMCT <%I%M Is In Use By MOUNTR, Try Later>
MOVEI T3,TMCMSG
CALLRET BTACK] ;SEND REPLY AND RETURN +1
LOAD MT,MTAMT ;MT ASSOCIATED?
JUMPE MT,RSKP ;RETURN GOOD IF DRIVE NOT IN USE
LOAD RSB,MTRSB ;GET RSB ADDRESS
MOVE T1,RSBITN(RSB) ;GET REQUEST #
TMCT <%I%M Is In Use By Request # %1D> ;A USER HAS IT
MOVEI T3,TMCMSG
CALLRET BTACK ;TELL OPERATOR
; KC1 - T1/ ADDRESS OF ASCIZ ERROR MESSAGE
KC1: TMCT <%ITape Drive %M is %1A>
MOVEI T3,TMCMSG
CALLRET BTACK ;SEND ACK BACK TO OPR AND TAKE +1 RET
; KDMT - PROCESS DELETE MOUNT-REQUEST COMMAND FROM OPR
; RETURNS +1: ALWAYS
KDMT: SAVEQ
MOVEI T1,.ORREA
CALL ORNBLF ;LOOKUP REASON BLOCK
SETZ T2, ;NOT FOUND
SKIPE Q1,T2 ;REASON GIVEN?
JRST [ MOVSS T1 ;YES, GET BLT SOURCE
HRRI T1,ATMBFR ;BLT DESTINATION
BLT T1,ATMBFR-1(T2) ;COPY REASON TO ATMBFR FOR TELUSR
SETZM ATMBFR(T2) ;TIE IT OFF
JRST .+1]
MOVEI T1,.ORREQ
CALL ORNBLF ;LOOKUP REQUEST # BLOCK
JRST KDMT1 ;NOT THERE, TRY STRUCTURE FORM
; DELETING SPECIFIC MOUNT REQUEST
JUMPE T2,KBADM ;REJECT HEADER-ONLY ENTRY
MOVE T1,(T1) ;GET REQUEST #
CALL REQRSB ;TRANSLATE REQ# TO RSB ADDR
JRST KNXREQ ;REQUEST DOES NOT EXIST
LOAD T2,RSBSTE ;GET STATE OF REQUEST
CAIE T2,RST.WM ;WAITING FOR MOUNT?
CAIN T2,RST.WV ; OR WAITING FOR VOLID LIST KEYIN?
SKIPA ;IF EITHER, OK TO DELETE
JRST [ JSP T2,KACKRQ ;CAN'T DELETE THIS REQUEST
ASCIZ/Is Not Waiting/]
MOVEI T2,[ASCIZ/Canceled/]
CALL KACKRQ ;TELL OPERATOR I DELETED IT
JUMPN Q1,[ABTRET (MREQ15,ABT%OP)] ;ABORT WITH REASON
ABTRET (MREQ15) ;ABORT WITHOUT REASON
; DELETING ALL MOUNT REQUESTS FOR SPECIFIED STRUCTURE
KDMT1: MOVEI T1,.STRDV ;SPECIFY BLOCK TYPE
CALL KGTSTR ;GET STRUCTURE NAME
JRST KBADM ;NOT THERE, ERROR
MOVE Q2,T1 ;SAVE SIXBIT STRUCTURE NAME
QSCANI ARBQDB ;SET UP TO SCAN REQUEST QUEUE
SETZ Q3, ;SET ABORTED REQUEST COUNT TO ZERO
; SCAN REQUEST QUEUE ABORTING REQUESTS FOR THIS STRUCTURE
KDMT2: CALL NSTRSB ;GET NEXT RSB
JRST KDMT3 ;NONE LEFT
LOAD T1,RSBTYP ;GET TYPE
CAIE T1,.MNTST ;STRUCTURE MOUNT?
JRST KDMT2 ;NO, SKIP IT
SKIPN T1,RSBSTN(RSB) ;STRUCTURE NAME SPECIFIED?
MOVE T1,RSBSTA(RSB) ;NO, USE ALIAS
CAME Q2,T1 ;WANT TO CANCEL THIS REQUEST?
JRST KDMT2 ;NO, SKIP IT
JUMPN Q1,[ABTREQ (MREQ15,ABT%OP) ;ABORT WITH REASON
AOJA Q3,KDMT2] ;COUNT IT AND CONTINUE SCAN
ABTREQ (MREQ15) ;ABORT WITHOUT REASON
AOJA Q3,KDMT2 ;COUNT IT AND CONTINUE SCAN
; TELL THE OPERATOR HOW MANY REQUESTS WERE DELETED
KDMT3: JUMPE Q3,[TMCT <%INo>
JRST KDMT3A]
TMCT <%I%7D> ;DISPLAY # OF REQUESTS
KDMT3A: TMCT < Mount Request>
SOJN Q3,[TMCT <s> ;TACK ON S IF NOT 1 REQUEST
JRST .+1]
TMCT < Canceled>
MOVEI T3,TMCMSG ;GET ADDRESS OF MESSAGE
CALLRET BTACK ;RESPOND TO DELETE COMMAND
; KDIS/KENA - PROCESS ENABLE AND DISABLE COMMANDS FROM OPR
; RETURNS +1: ALWAYS
KDIS: SKIPA T1,[[LOAD T1,MTASTE
CAIE T1,S.AV
RET
MOVX T1,MA%AVE
ANDCAM T1,MTAFLG(MTA)
RET]] ;COROUTINE FOR DISABLE
KENA: MOVEI T1,[LOAD T1,MTASTE
CAIE T1,S.AV
RET
CALL AVRENA
CALLRET AVR] ;COROUTINE FOR ENABLE
JXE F,TALCF,KNALC ;REJECT IF ALLOCATION NOT ENABLED
STAKT
MOVEI T1,.AVREC ;CHECK FOR AVR KEYWORD
CALL ORNBLF ;IS IT THERE?
JRST KBADM ;NO
MOVE T1,CT1 ;GET ADDRESS OF COROUTINE
CALL KTXCT ;DO IT FOR SPECIFIED TAPE DRIVES
JRST KBADM ;BAD MESSAGE FROM QUASAR
RET
; KGBLK - LOOK UP SPECIFIED BLOCK TYPE IN MESSAGE
; T1/ BLOCK TYPE
; T2/ UPPER LIMIT OF ARGUMENT (LOWER LIMIT = 0)
; IF T2/ 0, NO LIMIT CHECKING IS DONE
; T3/ DEFAULT, APPLIED IF (T2).NE.0 AND VALUE=0
; OR IF ENTRY NOT PRESENT
; RETURNS +1: HEADER-ONLY ENTRY OR VALUE BEYOND LIMITS
; +2: T1/ VALUE (OR DEFAULT IF APPLICABLE)
KGBLK: STAKT ;SAVE ARGS
CALL ORNBLF ;LOOKUP ARGUMENT
JRST KGBLK1 ;NOT THERE, TAKE THE DEFAULT
JUMPE T2,R ;ERROR IF HEADER-ONLY
MOVE T1,(T1) ;GET ARGUMENT
SKIPN CT2 ;LIMIT CHECK REQUESTED?
RETSKP ;NO, JUST PASS IT BACK
CAMG T1,CT2 ;GREATER THAN UPPER LIMIT?
SKIPGE T1 ; OR BELOW 0 ?
RET ;YES, ERROR
SKIPN T1 ;IS IT 0 ?
KGBLK1: MOVE T1,CT3 ;YES, SUBSTITUTE THE DEFAULT
RETSKP
; KGTSTR - LOCATE AND EXTRACT STRUCTURE OR ALIAS NAME
; T1/ ENTRY TYPE CODE (.STRDV OR .STALS)
; RETURNS +1: ENTRY NOT FOUND
; +2: SUCCESS, T1/ SIXBIT STRUCTURE NAME T2,T3/ ASCIZ NAME
KGTSTR: CALL ORNBLF ;LOOKUP SPECIFIED BLOCK TYPE
RET ;NOT FOUND
SAVET ;SET UP TO RETURN VALUES TO CALLER
DMOVE T3,(T1) ;GET ASCIZ NAME FROM ENTRY
CAIG T2,1 ;ENTRY 1 WORD LONG?
SETZ T4, ;YES, ZAP SECOND WORD
DMOVEM T3,CT2 ;RETURN ASCIZ NAME IN T2,T3
MOVSI T1,(POINT 7)
HRRI T1,CT2 ;CONSTRUCT POINTER TO ASCIZ NAME
MOVEI T2,CT1 ;RETURN SIXBIT EQUIVALENT HERE
CALL SEVSIX ;CONVERT NAME TO SIXBIT
RETSKP
; KGTVOL - EXTRACT SIXBIT VOLID FROM .VOLID ENTRY
; RETURNS +1: ERROR, MESSAGE SENT TO OPR
; +2: T1/ 0 IF .VOLID ENTRY ABSENT, ELSE SIXBIT VOLID
KGTVOL: SAVEQ
MOVEI T1,.VOLID
CALL ORNBLF ;VOLID SPECIFIED?
JRST [ SETZ T1, ;NO, RETURN ZERO
RETSKP]
JUMPE T2,KBADV ;MUST HAVE SOMETHING AFTER HEADER
MOVE Q1,T1 ;SAVE ADDRESS OF ASCIZ VOLID
CALL ASCIZL ;GET # OF CHARACTERS IN VOLID
SKIPE T2 ;NULL VOLID IS AN ERROR
CAILE T2,6 ;LONGER THAN 6 CHARACTERS?
JRST KBADV ;YES, ERROR
MOVE T1,Q1 ;FETCH ADDRESS OF VOLID
HRLI T1,(POINT 7) ;MAKE BYTE POINTER
CALL CVTA6R ;CONVERT TO SIXBIT
JRST KBADV ;NOT A LEGAL VOLID
RETSKP
; KIDN - PROCESS IDENTIFY COMMAND FROM OPR
; RETURNS +1: ALWAYS
KIDN: SAVEQ
SAVEAC <MT,MTA,RSB>
STKVAR <<OWNER,10>> ;LOCAL WORK AREA FOR GETVU ROUTINE
; VALIDATE TAPE DRIVE
MOVEI T1,.TAPDV
CALL ORNBLF ;TAPE DRIVE SPECIFIED?
JRST KBADM ;NO, BAD MESSAGE FROM QUASAR
JXE F,TALCF,KNALC ;REJECT IF ALLOCATION IS NOT ENABLED
CALL STMTA ;CONVERT STRING TO MTA STATUS BLOCK ADDR
JRST KBADM ;NOT MTA DEVICE STRING
MOVEI T1,.ORREQ
CALL ORNBLF ;LOOKUP REQUEST # BLOCK
JRST KIDV ;NOT THERE, MAYBE ANOTHER FORM OF CMD
JUMPE T2,KBADM ;REJECT HEADER-ONLY ENTRY
MOVE Q3,(T1) ;GET REQUEST #
; PROCESS COMMAND: IDENTIFY drive REQUEST-ID n
MOVE T1,Q3 ;GET REQUEST #
CALL REQRSB ;GET RSB ADDRESS FOR THIS REQUEST
JRST KNXREQ ;REQUEST DOES NOT EXIST
HRROI T2,[ASCIZ/Not Waiting For Tape Mount/]
LOAD T3,RSBTYP
CAIE T3,.MNTTP ;TAPE REQUEST?
JRST KACKRQ ;NO, REJECT IT
LOAD T3,RSBSTE ;GET STATE
CAIN T3,RST.WV ;WAITING FOR KEYIN?
JRST [ JSP T2,KACKRQ ;YES, REJECT WITH APPROPRIATE MESSAGE
ASCIZ/Waiting For RESPOND Keyin/]
CAIE T3,RST.WM ;WAITING FOR TAPE MOUNT?
JRST KACKRQ ;NO
CALL VQGCV ;DOES USER WANT A SCRATCH TAPE?
JUMPE T1,KIDR1 ;YES, TAKE ALTERNATE PATH
MOVE Q1,T1 ;SPECIFIC VOLID, SAVE IT
MOVX T2,TM%BYP
TDNE T2,RSBUFL(RSB) ;BYPASS MODE?
SETZ T1, ;YES, KEEP KVAC FROM BARFING
SETZ T2, ;NOT SCRATCH
CALL KVAC ;OK TO SET NEW VOLID?
RET ;NO, ERROR MESSAGE SENT
MOVEM Q1,MTAIDV(MTA) ;SET ALLEGED VOLID
EXCH Q1,MTAVOL(MTA) ;SET NEW VOLID, SAVE OLD
CALL VRA ;TRY TO MATCH REQUEST TO VOLUME NOW
SKIPA ;DIDN'T MATCH
RET ;DID MATCH, ALL DONE
MOVEM Q1,MTAVOL(MTA) ;RESTORE OLD VOLID
CALL CHKAB ;REQUEST ABORTED?
JRST KIDR0 ;YES, CLEAN UP AND LEAVE
CALL VOLMNT ;STILL THERE, TRY TO MOUNT AGAIN
JN MTAJCT,,R ;RETURN IF AVR IN PROGRESS
KIDR0: SETZM MTAIDV(MTA) ;REQ ABORTED OR NOT DOING AVR
RET
; SAME AS ABOVE, BUT USER IS REQUESTING SCRATCH VOLUME
KIDR1: SETZ T1, ;NOT SETTING VOLID
MOVEI T2,1 ;SCRATCH
CALL KVAC ;OK TO SCRATCH THIS VOLUME?
RET ;NO, ERROR MESSAGE SENT
LOAD T1,MTALT
CAIN T1,.LTT20 ;TOPS-20 LABELED TAPE?
JRST [ JN MA%SCR,MTAFLG(MTA),.+1 ;YES, OK IF ALREADY SCRATCH
MOVEI T1,OWNER ;SUPPLY WORK AREA ADDRESS TO GETVU
CALL GETVU ;GET TAPE OWNER'S USER # IN T2
CAME T2,RSBUNO(RSB) ;OWNER AND REQUESTOR THE SAME?
JRST KNOSCR ;NO, REJECT KEYIN
JRST .+1] ;YES, PERMIT IT
MOVE Q1,MTAFLG(MTA) ;SAVE FLAGS
SETONE MA%SCR,MTAFLG(MTA) ;SET SCRATCH
SETZRO MA%OPF,MTAFLG(MTA) ;CLEAR OVERWRITE-PROTECTED
CALL VRA ;TRY TO MATCH REQUEST TO VOLUME
SKIPA ;DIDN'T MATCH
RET ;DID MATCH, ALL DONE
MOVX Q2,MA%SCR+MA%OPF ;RESTORE MA%SCR AND MA%OPF IN MTAFLG
AND Q1,Q2
ANDCAM Q2,MTAFLG(MTA)
IORM Q1,MTAFLG(MTA)
CALL CHKAB ;REQUEST ABORTED?
RET ;YES
MOVE T1,RSBITN(RSB) ;GET REQUEST #
TMCT <%I%M Tape Not Compatible With Request %1D>
MOVEI T3,TMCMSG
CALLRET BTACK ;SEND IT OFF
; PROCESS FOLLOWING FORMS OF IDENTIFY COMMAND:
; IDENTIFY drive VOLUME-ID volid
; IDENTIFY drive SCRATCH-TAPE
KIDV: CALL KGTVOL ;LOOKUP .VOLID ENTRY
RET ;SOME ERROR, OPERATOR NOTIFIED
MOVE Q1,T1 ;SAVE VOLID IN Q1
MOVEI T1,.SCRTP
MOVEI Q2,1 ;ASSUME SCRATCH SPECIFIED
CALL ORNBLF ;SCRATCH SPECIFIED?
JRST [ SETZ Q2, ;NO, SET NO SCRATCH
JUMPN Q1,.+1 ;ARE .SCRTP AND .VOLID BOTH ABSENT?
JRST KBADM] ;YES, BAD MESSAGE
JUMPN Q2,[MOVE T1,MTAFLG(MTA) ;IF SCRATCHING, GET FLAGS
LOAD T2,MTALT ;AND LABEL TYPE
TXNN T1,MA%SCR ;ALREADY SCRATCH?
CAIE T2,.LTT20 ;OR NOT TOPS-20 LABEL?
JRST .+1 ;YES TO EITHER, OK TO SCRATCH
JRST KNOSCR] ;CAN'T SCRATCH TOPS-20 TAPE WITH THE
;IDENTIFY COMMAND - MUST SET TAPE INIT
DMOVE T1,Q1 ;GET VOLID AND SCRATCH FLAG
CALL KVAC ;OK TO DO THIS TO THIS DRIVE?
RET ;NO, ERROR MESSAGE SENT
; EVERYTHING LOOKS LEGAL, NOW DO WHAT THE OPERATOR WANTS
SKIPE Q1 ;SETTING VOLID?
MOVEM Q1,MTAVOL(MTA) ;YES, DO IT
JUMPN Q2,[SETONE MA%SCR,MTAFLG(MTA) ;SETTING SCRATCH FLAG
SETZRO MA%OPF,MTAFLG(MTA) ;CLEAR OVERWRITE PROTECTION
JRST .+1]
CALLRET MATCHV ;TRY TO MATCH VOLUME WITH A REQUEST
; KSHT - PROCESS SHOW STATUS TAPE-DRIVE COMMAND FROM OPR
; ACCEPTS IPCF MESSAGE IN RBUF
; RETURNS +1: ALWAYS
KSHT: SAVEQ
JXE F,TALCF,KNALC ;REJECT IF ALLOCATION IS NOT ENABLED
MOVEI CX,[ASCIZ/%IDRIVE STATE VOLID REQ# JOB# USER
----- ----- ------ ---- ---- ----/]
MOVE T1,RBUF+.OFLAG ;GET FLAGS
TXNE T1,ST.AVA ;/FREE
MOVEI CX,[ASCIZ/%IDRIVE STATE AVR WRITE VOLID SCR LBL TYPE DENSITY
----- ----- --- ----- ------ --- -------- -------/]
TXNE T1,ST.CHR ;CHARACTERISTICS
MOVEI CX,[ASCIZ/%IDRIVE TYPE SUPPORTED DENSITIES
----- ---- -------------------/]
CALL TMCT0 ;INSERT HEADING
MOVE Q1,TMCPTR ;GET CURRENT TEXT POINTER
MOVEI T1,KSHSCR ;GET COROUTINE ADDRESS
CALL KTXCT ;BUILD THE BODY OF THE DISPLAY
JRST KBADM ;BAD IPCF MESSAGE
CAMN Q1,TMCPTR ;ANYTHING DISPLAYED?
JRST [ JE ST.AVA,RBUF+.OFLAG,.+1 ;NO, FREE-DRIVE DISPLAY?
MOVEI T3,[ASCIZ/There Are No Free Tape Drives/] ;YES
CALLRET BTACK]
MOVEI T3,[ASCIZ/Tape Drive Status/]
CALL BTNFO ;REQUEST NO FORMATTING
CALLRET BTACKT ;SEND DISPLAY TO OPERATOR AND SPLIT
; COROUTINE FOR SHOW STATUS
KSHSCR: SAVEQ
SAVEAC <MT,RSB>
MOVE Q3,RBUF+.OFLAG ;GET MESSAGE FLAGS
JXN Q3,ST.AVA,KSHF ;/FREE
JXN Q3,ST.CHR,KSHC ;/CHARACTERISTICS
; SHOW STATUS TAPE-DRIVE [/ALL]
LOAD MT,MTAMT ;GET ADDRESS OF MT STATUS BLOCK
JE MTASTE,,[CALL GMTADD ;DRIVE UNAVAILABLE, GET DESIGNATOR
DVCHR ;GET LH(T3)/ OWNER'S JOB#
TLNN T3,-1 ;SHOW IF PHYSICAL DEVICE EXISTS
CALL CKMPAV ;SHOW IF SET UNAVAILABLE
JRST .+1
RET] ;DON'T SHOW
TMCT <%_%M%8C> ;DISPLAY DRIVE NAME
LOAD Q1,MTASTE
CAIE Q1,S.AV ;AVAILABLE TO USERS?
JRST [ JUMPE Q1,[TMCTR <Unavailable>] ;NO
TMCT <Initialize>
LOAD RSB,MTRSB ;GET RSB ADDRESS
SKIPN RSBWTB+WTBCOD(RSB) ;WAITING FOR OPER RESPONSE?
RET ;NO
TMCTR <, operator response wait>]
MOVE Q1,MTAFLG(MTA) ;GET MTA FLAGS
JXE Q1,MA%LOD,[TMCT <Unloaded>
JRST KSHN1]
MOVEI T1,[ASCIZ/Loaded/] ;ASSUME JUST LOADED
SKIPE MT ;RIGHT?
MOVEI T1,[ASCIZ/In Use/] ;NO, CHANGE TO IN USE
TMCT <%1A%18C> ;DISPLAY STATE
SKIPE T1,MTAVOL(MTA) ;DO I KNOW VOLID?
CALL [ TMCTR <%1S>] ;YES, DISPLAY IT
JUMPE MT,KSHN1 ;THAT'S ALL IF NO USER
LOAD RSB,MTRSB ;GET REQUEST STATUS BLOCK ADDRESS
CAIN RSB,MTNAV ;MT OWNED BY PHANTOM USER?
JRST KSHN1 ;YES, THAT'S ALL
MOVE T1,RSBITN(RSB) ;GET REQUEST #
LOAD T2,RSBJNO ;GET JOB #
MOVE T3,RSBUNO(RSB) ;GET USER #
TMCT <%26C%1D%32C%2D%38C%3U> ;SHOW USER INFO
KSHN1: JXE Q3,ST.ALL,R ;/ALL REQUESTED?
LOAD T1,MA%AVE,Q1 ;YES, GET AVR STATUS
TMCT <%_%8CAVR: %1Y> ;DISPLAY AVR STATE
JXE Q1,MA%LOD,R ;EXIT IF NOT LOADED
LOAD T1,MA%WEN,Q1 ;GET WRITE-ENABLED FLAG
TMCT <, Write: %1Y> ;DISPLAY IT
LOAD T1,MTALT ;GET LABEL TYPE
JUMPE T1,R ;NOT IDENTIFIED YET
MOVE T2,LTTXT(T1) ;GET LABEL-TYPE TEXT
MOVEI T3,[0] ;ASSUME UNLABELED
CAIE T1,.LTUNL
MOVEI T3,[ASCIZ/ labels/]
TXNE Q1,MA%SCR ;SCRATCH?
MOVEI T3,[ASCIZ/ scratch tape/]
TMCT <, %2A%3A> ;SHOW LABEL TYPE, SCRATCH
CAIN T1,.LTUNL ;UNLABELED?
RET ;YES
LOAD T2,MTADEN ;LABELED, SHOW DENSITY
MOVE T2,DENTAB(T2)
TMCTR <, %2D BPI>
; SHOW STATUS TAPE-DRIVE /FREE
KSHF: LOAD T1,MTASTE ;GET STATE
CAIE T1,S.AV ;AVAILABLE TO USERS?
RET ;NO, SKIP IT
JN MTAMT,,R ;DON'T SHOW IF A USER HAS IT
MOVE T1,MTAFLG(MTA) ;GET FLAGS
MOVEI T2,[ASCIZ/Unloaded/] ;ASSUME UNLOADED
TXNE T1,MA%LOD ;LOADED?
MOVEI T2,[ASCIZ/Loaded/] ;YES
LOAD T3,MA%AVE,T1 ;GET AVR FLAG
TMCT <%_%M%8C%2A%17C%3Y> ;DISPLAY DRIVE, STATE, AVR
JXE T1,MA%LOD,R ;END OF LINE IF DRIVE NOT LOADED
LOAD T2,MA%WEN,T1 ;GET WRITE-ENABLED FLAG
MOVE T3,MTAVOL(MTA) ;GET VOLID
LOAD T4,MA%SCR,T1 ;GET SCRATCH FLAG
TMCT <%23C%2Y%29C%3S%37C%4Y> ;DISPLAY WRITE, VOLID, SCRATCH
LOAD T1,MTALT ;GET LABEL TYPE
JUMPE T1,R ;UNKNOWN
MOVE T2,LTTXT(T1) ;GET POINTER TO TEXT
TMCT <%42C%2A> ;DISPLAY LABEL TYPE
CAIN T1,.LTUNL ;LABELED?
RET ;NO, DONE
LOAD T2,MTADEN ;YES, GET DENSITY CODE
MOVE T2,DENTAB(T2) ;GET DENSITY
TMCTR <%52C%2D> ;DISPLAY AND RETURN
; SHOW STATUS TAPE-DRIVE /CHARACTERISTICS
KSHC: JE MTASTE,,R ;DON'T SHOW DRIVE IF I DON'T CONTROL IT
LOAD T1,MTADRV ;GET DRIVE TYPE CODE
MOVE T1,DRVTXT(T1) ;GET ADDRESS OF TEXT
TMCT <%_%M%8C%1A%17C> ;DISPLAY DRIVE, TYPE
MOVSI T1,-DENMAX-1 ;GET AOBJP POINTER
MOVSI T2,(1B0) ;SET UP INTERROGATION BIT
MOVEI T3,[0] ;NO ", " BEFORE FIRST DENSITY
KSHC1: AOBJP T1,R ;GET OUT OF LOOP IF DONE
LSH T2,-1 ;SHIFT BIT TO NEXT POSITION
TDNN T2,MTASDN(MTA) ;IS THIS DENSITY SUPPORTED?
JRST KSHC1 ;NO, TEST NEXT DENSITY
MOVE T4,DENTAB(T1) ;GET DENSITY
TMCT <%3A%4D> ;DISPLAY DENSITY
MOVEI T3,[ASCIZ/, /] ;SEPARATE SUBSEQUENT DENS WITH A COMMA
JRST KSHC1
; KSTP - PROCESS SET TAPE-DRIVE COMMAND FROM OPR
; RETURNS +1: ALWAYS
KSTP: SAVEQ
SAVEAC <MTA>
JXE F,TALCF,KNALC ;REJECT IF ALLOCATION IS NOT ENABLED
MOVEI T1,.TAPDV
CALL ORNBLF ;TAPE DRIVE SPECIFIED?
JRST KBADM ;NO
CALL STMTA ;CONVERT STRING TO MTA STATUS BLOCK ADDR
JRST KBADM ;BAD MTA STRING
SETZ Q1, ;ASSUME SETTING UNAVAILABLE
MOVEI T1,.DVUAV
CALL ORNBLF ;CHECK IF SETTING UNAVAILABLE
JRST [ MOVEI T1,.DVAVL ;NO
CALL ORNBLF ;SETTING AVAILABLE?
SKIPA ;NO
AOJA Q1,KSTPA ;SETTING AVAILABLE
MOVEI T1,.DVINI
CALL ORNBLF ;SETTING INITIALIZE MODE?
JRST KBADM ;NO, BAD MESSAGE
CALLRET KVI] ;YES, GO DO IT
; SETTING DRIVE UNAVAILABLE
MOVEI T1,.ORREA
CALL ORNBLF ;REASON BLOCK PRESENT?
JRST KBADM ;NO
MOVE Q2,T1 ;COPY ADDRESS OF REASON TEXT
CALL CKMPAV ;IS DRIVE ALREADY SET UNAVAILABLE?
KSTP1: JRST [ MOVE T1,[[ASCIZ/Unavailable/]
[ASCIZ/Available/]](Q1) ;GET TEXT POINTER
TMCT <%ITape Drive %M Is Already Set %1A>
MOVEI T3,TMCMSG
CALLRET BTACK] ;TELL OPRTR HIS COMMAND HAS NO EFFECT
LOAD T1,MTASTE
CAIN T1,S.INIT ;IN INITIALIZE MODE?
JRST [ CALL KVICU ;YES, CAN I GET OUT OF IT NOW?
RET ;NO
JRST .+1] ;YES, CONTINUE
MOVEI T1,CS%DDV ;GET CODE FOR DETACH-DEVICE
MOVE T2,Q2 ;GET ADDRESS OF ASCIZ REASON
CALL SYTSET ;LOG SYSERR ENTRY FOR DRIVE SET UNAVAIL
CALL DACMTA ;DEACTIVATE THE DRIVE IF POSSIBLE
SETZ T1, ;GET 0 TO SET UNAVAILABLE
CALL SMPAV ;UPDATE DEVICE STATUS FILE
CALL WOTDAV ;TELL ALL OPERATORS WHAT HAPPENED
RET
; SETTING DRIVE AVAILABLE
KSTPA: LOAD T1,MTASTE ;GET CURRENT STATE
CAIN T1,S.INIT ;INITIALIZING VOLUMES?
JRST [ CALL KVICU ;YES, CLEAR INITIALIZE STUFF
RET ;CAN'T DO IT NOW
CALLRET KVIDAV] ;GET BACK TO AVAILABLE STATE
MOVEI Q2,1 ;REMEMBER INITIAL SMPAV STATE IN Q2
SKIPE T1 ;OK IF DRIVE NOT BEING SCHEDULED
CALL CKMPAV ;OK IF DRIVE SET UNAVAILABLE
TDZA Q2,Q2 ;ONE OF THE ABOVE CONDITIONS WAS TRUE
JRST KSTP1 ;NEITHER TRUE, THAT'S AN ERROR
MOVEI T1,1
CALL SMPAV ;SET AVAILABLE IN STATUS FILE
MOVEI T1,S.AV ;GET DESIRED STATE
CALL ACTMTA ;TRY TO ACTIVATE THE MTA
JRST KSTP3 ;CAN'T, SO SEND DIAGNOSTIC TO OPR
CALL TDSC1 ;CHECK IF LOADED, DO AVR, ETC.
JUMPE Q2,[MOVEI T1,CS%ADV ;GET CODE FOR ATTACH-DEVICE
SETZ T2, ;NO REASON
CALL SYTSET ;LOG SYSERR ENTRY FOR DRIVE SET AVAIL
JRST .+1]
CALLRET WOTDAV ;TELL OPERATORS IT'S BACK
; TAPE DRIVE WAS ASSIGNED TO ANOTHER JOB T1/ JOB#
KSTP3: MOVE Q2,T1 ;SAVE JOB #
TMCT <%I%M is >
SKIPLE Q2 ;ASSIGNED TO JOB 0
CAIL Q2,4000 ;OR SOME FUNNY JOB?
JRST [ TMCT <not accessible by MOUNTR>
JRST KSTP2] ;YES, SPECIAL MESSAGE
MOVE T1,Q2 ;GET JOB#
TMCT <assigned to Job %1D>
KSTP2: MOVEI T3,[ASCIZ/Cannot Set Tape Drive Available/]
CALLRET BTACKT ;TELL OPERATOR WHY I CAN'T SET AVAIL
; KSWI - PROCESS SWITCH COMMAND FROM OPR
; RETURNS +1: ALWAYS
; VALIDATE REQUEST NUMBER AND STATE
KSWI: SAVEQ
SAVEAC <MT,MTA,RSB>
MOVEI T1,.ORREQ
CALL ORNBLF ;LOOKUP REQUEST #
JRST KBADM ;NOT THERE
MOVE T1,(T1) ;GET REQ#
CALL REQRSB ;FIND RSB
JRST KNXREQ ;UNKNOWN REQUEST #
MOVEI T2,[ASCIZ/Not Using An Unlabeled Tape/]
LOAD T3,RSBTYP ;GET REQ TYPE
CAIE T3,.MNTTP ;TAPE-MOUNT REQUEST?
JRST KACKRQ ;NO, REJECT IT
LOAD T3,RSBSTE ;GET STATE
LOAD T4,RSBLT ;GET LABEL-TYPE
CAIN T3,RST.AC ;MUST BE ACTIVE
CAIE T4,.LTUNL ;MUST HAVE UNLABELED TAPE
JRST KACKRQ ;DOESN'T QUALIFY, REJECT IT
LOAD MT,RSBMT ;GET MT STATUS BLOCK ADDRESS
; VALIDATE VOLID
CALL KGTVOL ;LOOKUP VOLID
RET ;SCREWED-UP VOLID
SKIPN Q1,T1 ;WAS THERE A .VOLID ENTRY?
JRST KBADM ;NO, BAD NEWS
; CHECK IF TAPE DRIVE SPECIFIED
SETZ MTA, ;ASSUME NO DRIVE SPECIFIED
MOVEI T1,.TAPDV
CALL ORNBLF ;TAPE DRIVE SPECIFIED?
JRST KSWI1 ;NO
CALL STMTA ;YES, LOAD MTA AC FOR THIS DRIVE
JRST KBADM ;BAD DRIVE NAME FROM QUASAR
LOAD T1,MTMTA ;GET CURRENT DRIVE
CAMN T1,MTA ;SWITCHING TO SAME DRIVE?
JRST [ MOVEI T3,[ASCIZ/Cannot SWITCH To Same Drive/] ;YES
CALLRET BTACK]
MOVE T1,Q1 ;GET VOLID
SETZ T2, ;NOT SETTING SCRATCH
CALL KVAC ;CHECK IF I CAN USE THIS MTA
RET ;NO, ERROR MSG SENT
LOAD T1,MTALT
CAIE T1,.LTUNL ;UNLABELED TAPE?
JRST [ TMCT <%I%M Does Not Contain An Unlabeled Tape>
MOVEI T3,TMCMSG
CALLRET BTACK] ;TELL OPERATOR
KSWI1:
; COMMAND HAS BEEN VALIDATED, NOW PERFORM SPECIFIED TASKS
CALL GMTDD ;GET MT DEVICE DESIGNATOR IN T1
LDB T2,[POINT 9,T1,35] ;GET MT UNIT# IN T2
MOVEI T1,.MTCVV ;FUNCTION CODE = CLEAR VOLUME-VALID
MTU% ;YANK MT AND MTA APART IN MONITOR
ERJMP [MOVE T1,RSBITN(RSB) ;CAN'T DO IT, GET REQUEST #
TMCT <%ICannot SWITCH - Request %1D Has Tape Drive Open>
MOVEI T3,TMCMSG
CALLRET BTACK] ;TELL OPR THE BAD NEWS
MOVX T1,TM%NUL
MOVE Q2,RSBUFL(RSB) ;GET CURRENT SETTING OF UNLOAD FLAG
AND Q2,T1 ;EXTRACT TM%NUL FLAG
ANDCAM T1,RSBUFL(RSB) ;MAKE SURE TAPE GETS UNLOADED
CALL PLDISA ;DISASSOCIATE MT&MTA IN MY TABLES
IORM Q2,RSBUFL(RSB) ;RESTORE USER SETTING OF TM%NUL
LOAD T1,RSBCV ;GET CURRENT VOLUME #
MOVE T2,Q1 ;GET VOLID
CALL VQSET ;SET NEW VOLID IN USER REQUEST
CALL STOP ;VOLID LIST SCREWED UP
JUMPE MTA,[CALLRET VOLMNT] ;NO MTA SPECIFIED, REQUEST TAPE MOUNT
; TRY TO ASSOCIATE SPECIFIED DRIVE WITH USER REQUEST
MOVEI T1,RST.WM
STOR T1,RSBSTE ;SET REQUEST WAITING FOR MOUNT
EXCH Q1,MTAVOL(MTA) ;SET NEW VOLID
CALL VRA ;TRY TO ASSOCIATE REQUEST WITH DRIVE
SKIPA ;NO GO
RET ;ASSOCIATION DONE, EXIT
MOVEM Q1,MTAVOL(MTA) ;RESTORE OLD VOLID
CALL CHKAB ;REQUEST ABORTED?
RET ;YES
CALLRET VOLMNT ;NO, ASK FOR VOLUME
; KTXCT - IMPLEMENTS EXECUTION OF MTA FUNCTION FOR ONE OR ALL TAPE
; DRIVES, ACCORDING TO PRESENCE OF .TAPDV AND .ALTAP BLOCKS
; T1/ ADDRESS OF COROUTINE TO BE CALLED; COROUTINE RECEIVES MTA
; STATUS BLOCK ADDRESS IN MTA AC, AND RETURNS +1 ALWAYS
; RETURNS +1: ERROR IN COMMAND MESSAGE
; +2: SUCCESS
KTXCT: SAVEAC <MTA>
SAVEQ
MOVE Q2,T1 ;SAVE COROUTINE ADDRESS
MOVEI T1,.ALTAP
CALL ORNBLF ;LOOKUP ALL-TAPES BLOCK
TDZA MTA,MTA ;NOT THERE, CLEAR MTA
MOVEI MTA,MTA0 ;ALL TAPES, POINT AT MTA0 STATUS BLOCK
MOVEI T1,.TAPDV
CALL ORNBLF ;LOOKUP SPECIFIC-TAPE-DRIVE BLOCK
JRST [ JUMPE MTA,R ;NO TAPE INFO SPECIFIED, BAD MESSAGE
MOVE Q1,MTAN ;ALL DRIVES, GET # OF DRIVES
JRST KTXCT1] ;GO DO THEM
JUMPN MTA,R ;CAN'T HAVE BOTH!
CALL STMTA ;GET MTA STATUS BLK ADDR FROM STRING
RET ;STRING DOESN'T SPECIFY MTA DEVICE
MOVEI Q1,1 ;DOING 1 DRIVE
KTXCT1: CALL (Q2) ;CALL COROUTINE
ADDI MTA,MTASZ ;POINT AT NEXT MTA STATUS BLOCK
SOJG Q1,KTXCT1 ;LOOP THRU SPECIFIED # OF DRIVES
RETSKP
; KUNL - PROCESS UNLOAD COMMAND FROM OPR
; RETURNS +1: ALWAYS
KUNL: SAVEQ
SAVEAC <MTA>
MOVEI T1,.TAPDV
CALL ORNBLF ;TAPE DRIVE SPECIFIED?
JRST KBADM ;NO, REJECT MESSAGE
JXE F,TALCF,KNALC ;REJECT IF ALLOCATION IS NOT ENABLED
CALL STMTA ;CONVERT STRING TO MTA STATUS BLK ADDR
JRST KBADM ;ERROR, BAD MESSAGE
MOVE Q1,MTAFLG(MTA) ;GET FLAGS
CALL KCAVL ;DRIVE AVAILABLE TO USERS?
RET ;NO
JN MTAMT,,[CALL KCUSE ;GIVE ERROR IF A USER HAS THE DRIVE
JFCL ;SHOULD ALWAYS RETURN +1
RET]
JN MTAJCT,,[SETONE MA%ULP,MTAFLG(MTA) ;IN USE BY ME, SET UNLOAD
JRST KUNL1] ; PENDING
CALL UNLOAD ;NOT IN USE BY ME, UNLOAD IT
KUNL1: TXNN Q1,MA%LOD ;DID I THINK IT WAS LOADED?
SETZM MTAVOL(MTA) ;NO, SUPPRESS VOLID IN UNLOAD MESSAGE
CALLRET WOUNL ;TELL OPERATORS IT'S UNLOADED
; KVAC - CHECK IF LEGAL FOR OPERATOR TO CHANGE VOLUME ATTRIBUTES
; T1/ 0 IF NOT CHANGING VOLID, NON-ZERO IF CHANGING VOLID
; T2/ 0 IF NOT SETTING SCRATCH, NON-ZERO IF SETTING SCRATCH
; MTA/ ADDR OF MTA STATUS BLOCK
; RETURNS +1: FUNCTION ILLEGAL, ERRROR MESSAGE SENT TO OPERATOR
; +2: FUNCTION IS LEGAL
KVAC: SAVEQ
DMOVE Q1,T1 ;COPY ARGS TO A SAFE PLACE
CALL KCAVL ;DRIVE MUST BE AVAILABLE TO USERS
RET
CALL KCLOAD ;DRIVE MUST BE LOADED
RET
CALL KCUSE ;DRIVE MUST NOT BE IN USE
RET
LOAD Q3,MTALT ;GET LABEL TYPE
JUMPN Q1,[JUMPE Q3,.+1 ;VOLID OK IF AVR NOT PERFORMED YET
CAIN Q3,.LTUNL ;WHAT KIND OF TAPE?
JRST .+1 ;UNLABELED, VOLID OK HERE
JSP T1,KVAX ;CAN'T SPECIFY VOLID FOR LABELED TAPE
ASCIZ/Cannot Change Volid Of Labeled Tape/]
JUMPE Q2,RSKP ;OK IF NOT SETTING SCRATCH
MOVE T1,MTAFLG(MTA) ;GET FLAGS
JXN T1,MA%UXV,[JSP T1,KVAX ;CAN'T SCRATCH AN UNEXPIRED VOLUME
ASCIZ/Cannot Scratch - Volume Is Not Expired/]
JXE T1,MA%WEN,[JSP T1,KVAX ;CAN'T SCRATCH A WRITE-PROTECTED VOL
ASCIZ/Cannot Scratch - Drive Is Write-Protected/]
JUMPE Q3,[JSP T1,KVAX ;CAN'T SCRATCH UNTIL I'VE DONE AVR
ASCIZ/Cannot Scratch - AVR Not Enabled/]
RETSKP
; ERROR DETECTED, T1/ ADDR OF ERROR TEXT
KVAX: TMCT <%I%M %1A>
MOVEI T3,TMCMSG ;GET ADDRESS OF MESSAGE
CALLRET BTACK ;SEND ERROR MESSAGE AND RETURN +1
; KVI - SUPPORT VOLUME INITIALIZATION UNDER OPR CONTROL
; MTA/ ADDR OF MTA STATUS BLOCK
; RBUF/ "SET TAPE-DRIVE INIT" MESSAGE FROM OPR
; RETURNS +1: ALWAYS
KVI: JE MA%AVS,MTAFLG(MTA),[LOAD T1,MTADRV
MOVE T1,DRVTXT(T1)
TMCT <%ICommand Illegal For %1A Drives>
MOVEI T3,TMCMSG
CALLRET BTACK] ;BLAST THE OPERATOR
CALL KCAVL ;DRIVE IN S.AV STATE?
RET ;NO, CAN'T DO THIS
CALL KCUSE ;DRIVE IN USE?
RET ;YES, ERROR
CALL GORSB ;GET RSB FOR INITIALIZATION
RET ;RSB POOL EXHAUSTED, MESSAGE TYPED
MOVEI T1,.MNTTP
STOR T1,RSBTYP ;SET RSB TYPE = TAPE-MOUNT
MOVEI T1,RST.AC
STOR T1,RSBSTE ;SET RSB ACTIVE
CALL KVIRSB ;BUILD RSB FROM USER PARAMETERS
RET ;ERROR, RSB ABORTED, MESSAGE SENT TO OPR
MOVEI T1,S.INIT
STOR T1,MTASTE ;PUT TAPE DRIVE IN PROPER STATE
MOVEI MT,RSBIMT(RSB) ;GET PSEUDO-MT STATUS BLOCK ADDRESS
STOR RSB,MTRSB ;LINK MT TO RSB
STOR MT,RSBMT ;LINK RSB TO MT
STOR MTA,MTMTA ;LINK MT TO MTA
STOR MT,MTAMT ;LINK MTA TO MT
; GET VOLID OF VOLUME TO BE INITIALIZED
KVI0: LOAD T1,RSBLT
CAIE T1,.LTUNL ;UNLABELED?
SKIPE RSBIVL(RSB) ;OR DO I KNOW THE VOLID?
JRST KVI2A ;YES TO EITHER, PROCEED
KVI1: JSP T1,KVIMR1 ;NO, HAVE TO ASK OPERATOR
MOVEI RSB,-RSBWTB(T2) ;GET RSB ADDRESS
LOAD MT,RSBMT
LOAD MTA,MTMTA ;GET MTA STATUS BLOCK ADDR
CALL PINI ;PARSE RESPONSE
JRST KVI1 ;ERROR, TRY IT AGAIN JACK
KVI2: MOVEM T1,RSBIVL(RSB) ;REMEMBER VOLID
; MAKE SURE DRIVE IS READY, DO AVR IF NEEDED
KVI2A: JN MTAJCT,,R ;WAIT IF AVR OR REWIND IN PROGRESS
MOVE T1,MTAFLG(MTA) ;GET FLAGS
JXE T1,MA%LOD,KVIM1 ;IF TAPE NOT UP, SAY SO
TXNE T1,MA%AVE ;WANT TO CHECK IF EXPIRED?
JRST [ JE MTALT,,[CALLRET AVR] ;YES, DO AVR IF NOT DONE YET
JXE T1,MA%UXV,.+1 ;AVR DONE, OK IF EXPIRED
CALL KVIM4 ;TELL OPERATOR IT'S NOT EXPIRED
CALL UNLOAD ;UNLOAD IT
JRST KVIM1] ;ASK HIM TO DO IT AGAIN
CALL MTAGJF ;LOCK UP THE DRIVE
MOVEI T1,KVI2B ;GET REWIND END-ACTION ADDRESS
CALL REWEA ;REWIND
JRST KVI2B ;FAILED, MA%LOD CLEARED
RET ;EXIT UNTIL REWIND COMPLETES
; REWIND END-ACTION
KVI2B: CALL MTARJF ;RELEASE LOCK
LOAD MT,MTAMT
LOAD RSB,MTRSB ;RESTORE RSB ADDRESS
JE MA%LOD,MTAFLG(MTA),KVIM1 ;ASK FOR TAPE IF NOT LOADED
; WRITE LABELS TO TAPE
MOVE T1,RSBIVL(RSB) ;GET VOLID
MOVEM T1,MTAVOL(MTA) ;STUFF IT FOR LTINIT
SETONE R%WVL,RSBIFL(RSB) ;REQUEST LTINIT TO WRITE LABELS
CALL LTINIT ;WRITE LABELS TO TAPE
JRST KVIM1 ;ERROR, TELL OPERATOR TO MOUNT AGAIN
CALL KVIM2 ;TELL OPERATOR WHAT HAPPENED
MOVX T1,TM%NUL
TDNN T1,RSBUFL(RSB) ;UNLOAD REQUESTED?
CALL UNLOAD ;YES, DO IT
; CHECK IF MORE INITIALIZATIONS LEFT TO DO
SOSG RSBICT(RSB) ;ANY TAPES LEFT TO DO?
JRST [ CALL KVICU ;NO, CLEAR INITIALIZE STUFF
CALL STOP
CALLRET KVIDAV] ;GET BACK TO AVAILABLE STATE
SETZM RSBIVL(RSB) ;YES, CLEAR VOLID
SKIPN T1,RSBIVI(RSB) ;DOING NUMERIC VOLIDS?
JRST KVI1 ;NO, MUST ASK FOR NEXT VOLID
ADD T1,RSBIVN(RSB) ;YES, STEP TO NEXT VOLID
MOVEM T1,RSBIVN(RSB) ;RESTORE NUMERIC VOLID
CALL INT26 ;CONVERT TO SIXBIT
JRST KVI2 ;GO GET IT MOUNTED
; KVICU - PROCESS REQUEST TO CANCEL INITIALIZATION SERIES
; MTA/ ADDR OF MTA STATUS BLOCK
; RETURNS +1: DRIVE BUSY, OPERATOR TOLD ABOUT FAILURE
; +2: SUCCESS, TAPE DRIVE INITIALIZE STATE IS CLEARED
KVICU: SAVEAC <MT,RSB>
LOAD MT,MTAMT
LOAD RSB,MTRSB ;GET RSB ADDRESS
JN MTAJCT,,[JSP T1,KC1 ;ERROR IF DRIVE BUSY
ASCIZ/Busy/]
SETZRO MTAMT ;CLEAR MTA LINK TO MT
SETZRO RSBMT ;CLEAR RSB LINK TO MT
SETZRO MA%LOD,MTAFLG(MTA) ;CLEAR DRIVE-LOADED
ABTREQ (ABRTNR) ;DUMP THE RSB
RETSKP
; KVIDAV - EXIT FROM INITIALIZE MODE TO AVAILABLE MODE
KVIDAV: MOVEI T1,S.AV
STOR T1,MTASTE ;SET STATE BACK TO AVAILABLE
CALL AVRENA ;ENABLE AVR IF POSSIBLE
CALL KVIM3 ;TELL OPERATOR THE DRIVE IS AVAIL
CALLRET TDSC1 ;GO CHECK IF DRIVE OCCUPIEDPIPER
; KVITAV - REPORT TAPE DRIVE COMING ONLINE OR AVR COMPLETED
; MTA/ ADDR OF MTA STATUS BLOCK
; RETURNS +1: ALWAYS
KVITAV: SAVEAC <MT,RSB>
LOAD MT,MTAMT
LOAD RSB,MTRSB ;GET RSB ADDRESS
JE MA%WEN,MTAFLG(MTA),[CALL UNLOAD ;WRITE-PROTECTED
TMCT <%I%M Write Protected, Unloading Volume>
MOVEI T3,TMCMSG ;GET ADDRESS OF TEXT
CALLRET BTWTON] ;TELL OPERATOR THE BAD NEWS
SKIPE RSBWTB+WTBCOD(RSB) ;WTOR OUTSTANDING?
RET ;YES, WAIT TILL IT COMES BACK
JN MA%LOD,MTAFLG(MTA),KVI0 ;IF TAPE IS READY, GET THINGS MOVING
RET ;OTHERWISE, STILL HAVE TO WAIT
; KVIM1 - TELL OPERATOR TO MOUNT TAPE TO BE INITIALIZED
KVIM1: TMCT <%IMount tape>
SKIPE T1,RSBIVL(RSB) ;KNOW VOLID?
JRST [ TMCT < volume %1S> ;YES
JRST .+1]
TMCT < for initialization on %M>
MOVEI T3,[ASCIZ/Mount Tape To Be Initialized/]
CALLRET BTWTO ;SEND MESSAGE TO OPERATOR
; KVIM2 - TELL OPERATOR TAPE WAS INITIALIZED SUCCESSFULLY
KVIM2: TMCT <%I%M> ;DISPLAY DRIVE NAME
LOAD T1,RSBLT
CAIN T1,.LTUNL ;UNLABELED TAPE?
JRST [ TMCT < Unlabeled Tape> ;YES, SAY SO
JRST .+2] ;DON'T TYPE VOLID
CALL TMCVOL ;DISPLAY VOLID
TMCT < Initialized>
CALL CPYHDR ;COPY HEADER TO A SAFE PLACE
LOAD T1,RSBLT ;GET LABEL TYPE
MOVE T1,LTTXT(T1) ;GET POINTER TO TEXT
LOAD T2,RSBDEN
MOVE T2,DENTAB(T2) ;GET DENSITY
TMCT <%ILabel type: %1A%25CDensity: %2D>
LOAD T1,RSBLT
CAIE T1,.LTT20 ;TOPS-20 TAPE?
JRST KVIM21 ;NO
TMCT <
Owner: > ;YES, MORE INFO
SKIPN T2,RSBUNO(RSB) ;GET OWNER USER #
JRST [ TMCT <Scratch> ;IF ZERO, IT'S A SCRATCH TAPE
JRST KVIM21]
TMCT <%2U%23C Protection: >
MOVE T1,TMCPTR
LOAD T2,RSBVPR ;GET PROTECTION CODE
MOVE T3,[NO%LFL+NO%ZRO+FLD(6,NO%COL)+10]
NOUT ;INSTALL IT
SKIPA
MOVEM T1,TMCPTR ;RESTORE UPDATED POINTER
CALL TMC1 ;STANDARD TMC CLEANUP
KVIM21: MOVEI T3,OPRHDR ;GET ADDRESS OF MESSAGE TYPE TEXT
CALLRET BTWTO ;TELL OPERATORS WHAT HAPPENED
; KVIM3 - TELL OPERATOR DRIVE IS NO LONGER INITIALIZING
KVIM3: TMCT <%I%M available for user tape requests>
MOVEI T3,[ASCIZ/INITIALIZE Completed/]
CALLRET BTWTO
; KVIM4 - TELL OPERATOR TAPE I CAN'T INITIALIZE - TAPE IS NOT EXPIRED
KVIM4: TMCT <%I>
CALL TMCVOL ;DISPLAY VOLID
TMCT < on drive %M is not expired, unloading>
MOVEI T3,[ASCIZ/Tape Volume Not Expired/]
CALLRET BTWTO
; KVIMR1 - ISSUE WTOR TO ASK OPERATOR FOR VOLID TO BE INITIALIZED
KVIMR1: STAKT
TMCT <%IWhat is the volume-id of the next tape to be
initialized on drive %M ?
Respond with:
RESPOND n volid>
MOVE T1,CT1 ;GET END-ACTION ADDRESS
MOVEI T2,RSBWTB(RSB) ;GET WTB ADDRESS
MOVEI T3,[ASCIZ/Key In Volume Identifier/]
CALLRET BTWTOR
; KVIRSB - SCAN "SET TAPE INITIALIZE" IPCF MESSAGE FROM OPR AND
; BUILD REQUEST STATUS BLOCK
; MTA/ ADDR OF MTA STATUS BLOCK
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: ERROR DETECTED, OPERATOR NOTIFIED, RSB ABORTED
; +2: SUCCESS, INFORMATION STORED IN RSB
KVIRSB: CALL KGTVOL ;GET VOLID
JRST KVIABT ;ERROR, MESSAGE SENT
MOVEM T1,RSBIVL(RSB) ;STORE VOLID OR 0 IF NONE
MOVEI T1,.SILBT ;CODE FOR LABEL TYPE
MOVEI T2,.LTMAX ;LIMIT
MOVEI T3,.LTT20 ;DEFAULT
CALL KGBLK ;LOOKUP LABEL TYPE
JRST KVIBM ;ERROR
STOR T1,RSBLT ;STORE LABEL TYPE
MOVEI T1,.SIDEN ;CODE FOR DENSITY
MOVEI T2,DENMAX ;LIMIT
MOVEI T3,.SJD16 ;DEFAULT
CALL KGBLK ;LOOKUP DENSITY
JRST KVIBM ;ERROR
STOR T1,RSBDEN ;STORE DENSITY
CALL DRVDEN ;CAN THE DRIVE OPERATE AT THIS DENSITY?
JRST [ LOAD T1,RSBDEN ;NO
MOVE T1,DENTAB(T1) ;GET NUMERIC DENSITY
TMCT <%I%1D BPI Is Not Supported On %M>
MOVEI T3,TMCMSG ;GET MESSAGE ADDRESS
CALL BTACK ;SEND ERROR MESSAGE
JRST KVIABT] ;ABORT REQUEST
MOVEI T1,.SICNT ;CODE FOR COUNT BLOCK
HRLOI T2,377777 ;LIMIT
MOVEI T3,1 ;DEFAULT
CALL KGBLK ;LOOKUP COUNT
JRST KVIBM ;ERROR
MOVEM T1,RSBICT(RSB) ;STORE COUNT
MOVEI T1,.SISVI ;CODE FOR STARTING NUMERIC VOLID
CALL ORNBLF ;LOOKUP VOLID
SETZ T2, ;NOT THERE
JUMPE T2,KVIR2 ;STARTING VOLID SPECIFIED?
MOVE T1,(T1) ;YES, GET IT
MOVEM T1,RSBIVN(RSB) ;STORE IT
CALL INT26 ;CONVERT TO SIXBIT
MOVEM T1,RSBIVL(RSB) ;SET SIXBIT VOLID TOO
MOVEI T1,.SIINC ;CODE FOR NUMERIC VOLID INCREMENT
SETZ T2, ;NO LIMIT
MOVEI T3,1 ;DEFAULT = 1
CALL KGBLK ;LOOKUP INCREMENT
JRST KVIBM ;ERROR
MOVEM T1,RSBIVI(RSB) ;STORE INCREMENT
KVIR2:
MOVEI T1,.SIHLD ;REQUESTED TO KEEP TAPE ON DRIVE?
CALL ORNBLF
SKIPA ;NO
JRST [ MOVE T1,RSBICT(RSB) ;YES, GET COUNT
MOVX T2,TM%NUL
CAIN T1,1 ;INITIALIZING 1 TAPE?
IORM T2,RSBUFL(RSB) ;YES, OK TO KEEP ON DRIVE
JRST .+1]
MOVEI T1,.SIOWN ;CODE FOR OWNER-ID
SETZB T2,T3 ;NO LIMIT, DEFAULT = 0 (SCRATCH)
CALL KGBLK ;LOOK OWNER-ID
JRST KVIBM ;ERROR
MOVEM T1,RSBUNO(RSB) ;STORE OWNER-ID
MOVEI T1,.SIPRO ;CODE FOR PROTECTION
SETZ T2, ;NO LIMIT
MOVEI T3,777777 ;DEFAULT = 777777
CALL KGBLK ;LOOKUP PROTECTION
JRST KVIBM ;ERROR
STOR T1,RSBVPR ;STORE PROTECTION
MOVEI T1,.SIOVR ;OVERRIDE EXPIRATION-DATE CHECK?
CALL ORNBLF
SKIPA T1,[1] ;NO
SETZ T1, ;YES
STOR T1,MA%AVE,MTAFLG(MTA) ;STORE OVERRIDE FLAG
RETSKP
; ERROR CONDITIONS
KVIBM: CALL BADQM ;ERROR IN IPCF MESSAGE FROM QUASAR
KVIABT: ABTRET (ABRTNR) ;ABORT RSB AND RETURN +1
; ERROR HANDLERS FOR UNSOLICITED OPERATOR KEYINS ("K" ROUTINES)
; RET IS DONE THROUGH BTACK, GIVING ERROR MESSAGE TO OFFENDING OPR
KBADM: CALLRET BADQM ;ERROR IN MESSAGE RECEIVED FROM QUASAR
KNXREQ: MOVEI T2,[ASCIZ/Does Not Exist/]
KACKRQ: TMCT <%IMount Request %1D %2A> ;T1/ REQ#, T2/ ADDRESS OF TEXT
MOVEI T3,TMCMSG
CALLRET BTACK ;SEND IT OFF TO OPERATOR
KBADV: MOVEI T3,[ASCIZ/Illegal Volume Identifier/]
CALLRET BTACK
KNALC: MOVEI T3,[ASCIZ/Tape drive allocation is not enabled/]
CALLRET BTACK
;REJECT IDENTIFY KEYIN TO SCRATCH A TAPE
KNOSCR: STKVAR <<OWNER,10>>
TMCT <%ICannot Scratch %M> ;BUILD HEADING WITH DRIVE NAME
CALL CPYHDR ;SAVE MESSAGE HEADING
MOVEI T1,OWNER ;OWNER'S NAME GOES HERE
CALL GETVU ;GET POINTER TO OWNER'S NAME IN T1
MOVE T2,MTAVOL(MTA) ;GET VOLID
TMCT <%IVolume %2S owned by user %1A>
MOVEI T3,OPRHDR ;POINT TO HEADING
CALLRET BTACKT ;TELL OPERATOR I REJECTED IT
; ORNBCK - CHECK BUILDING BLOCK STRUCTURE OF ORION-STYLE IPCF MESSAGE
; IN RBUF (ASSUMES CKGHDR HAS BEEN CALLED)
; RETURNS +1: ERROR IN BLOCK STRUCTURE
; +2: BLOCK STRUCTURE OK
ORNBCK: MOVE T1,RBUF+.OARGC ;GET # OF ARGS
MOVEI T2,RBUF+.OHDRS ;GET ADDRESS OF 1ST ARG
LOAD T3,MS.CNT,RBUF+.MSTYP ;GET SIZE OF IPCF MESSAGE FROM HEADER
SUBI T3,.OHDRS ;COMPUTE SIZE OF BUILDING BLOCK AREA
CALLRET CKBSTR ;CHECK BLOCK STRUCTURE
; ORNBLF - FIND ARGUMENT BLOCK IN ORION-STYLE IPCF MESSAGE
; T1/ TYPE CODE OF DESIRED ARGUMENT
; RETURNS +1: NO ARGUMENTS OF REQUESTED TYPE FOUND
; +2: SUCCESS, T1/ ADDRESS OF FIRST WORD OF ARGUMENT
; T2/ LENGTH OF ARGUMENT (NOT COUNTING HEADER)
ORNBLF: MOVE T3,T1 ;COPY ARG TYPE TO T3 FOR BLKFND
MOVEI T1,RBUF+.OARGC ;GET ADDRESS OF ARG COUNT WORD
MOVEI T2,RBUF+.OHDRS ;GET ADDRESS OF 1ST BLOCK
CALLRET BLKFND ;CALL BLKFND TO DO LOOKUP
; ORNINI - ESTABLISH IPCF RAPPORT WITH ORION
; RETURNS +1: ALWAYS
ORNINI: MOVEI T1,.SPOPR
CALL GSYSPD ;GET ORION'S PID FROM SYSTEM PID TABLE
JRST [ MOVEI T1,^D5000 ;NOT THERE YET
DISMS ;WAIT 5 SECONDS
JRST ORNINI] ; AND TRY AGAIN
MOVEM T1,APPID+.APORN ;STUFF PID IN A/P TABLE
GTAD ;GET FAIRLY UNIQUE VALUE IN RH(T1)
HRLM T1,UNIQUE ;INSURE CODES UNIQUE TO SYSTEM STARTUP
RET
; ORNMRC - PROCESS INCOMING IPCF MESSAGE FROM ORION
; RBUF/ INCOMING IPCF MESSAGE
; MRPDB/ PDB THAT WAS USED TO RECEIVE THE MESSAGE
; RETURNS +1: ALWAYS
ORNMRC: CALL CKGHDR ;GALAXY HEADER OK?
JRST [ CALLRET BADOM] ;NO
CALL ORNBCK ;BLOCK STRUCTURE OK?
JRST [ CALLRET BADOM] ;NO
LOAD T1,MS.TYP,RBUF+.MSTYP ;GET MESSAGE TYPE
CAIN T1,.OMRSP ;WHAT TYPE?
JRST [ CALLRET INWTOR] ;RESPONSE TO WTOR
LOAD T2,MF.SUF,RBUF+.MSFLG ;GET SIXBIT SUFFIX
CAIN T1,MT.TXT ;TEXT MESSAGE?
JRST [ CAIE T2,'NMC' ;CHECK FOR - NO MESSAGE WITH THIS CODE
CAIN T2,'ODE' ;CHECK FOR - OPR DOESN'T EXIST
RET ;IGNORE THIS ERROR
JRST .+1] ;CAN'T HANDLE THIS TEXT MESSAGE
CALLRET BADOM ;BAD TEXT MESSAGE, REPORT IT
; PINI - PARSE OPERATOR RESPONSE TO REQUEST FOR VOLID TO BE INIT'ED
; T1/ ADDRESS OF ASCIZ OPERATOR RESPONSE TEXT
; RETURNS +1: ERROR, MESSAGE SENT TO OPERATOR
; +2: SUCCESS, T1/ SIXBIT VOLID
PINI: SAVET ;SETUP TO RETURN VALUE IN T1
CALL COMNDI
CALL COMNDV ;PARSE VOLID
RET ;FAILED
MOVEM T1,CT1 ;RETURN VOLID TO CALLER
CALLRET CMDCFM ;GET CONFIRMATION AND RETURN
; PMR - PARSE OPERATOR RESPONSE TO WTOR ASKING FOR VOLID LIST
; T1/ ADDRESS OF ASCIZ OPERATOR RESPONSE TEXT
; RSB/ ADDRESS OF REQUEST STATUS BLOCK
; RETURNS +1: ERROR DETECTED WHILE PARSING RESPONSE, OPERATOR NOTIFIED
; +2: SUCCESSFUL PARSE
; T1/ 0 - RSB AND VOLID LIST SET UP
; T1/ 1 - REQUEST ABORTED
PMR: CALL COMNDI ;INITIALIZE FOR COMND JSYS
MOVEI T2,[FLDDB.(.CMKEY,,PMRT1)] ;SET UP FOR KEYWORD PARSE
CALL COMNDX ;ISSUE COMND JSYS TO DO PARSE
JRST [ MOVEI T3,[ASCIZ/Syntactical Error In Response/]
CALLRET BTACK] ;HE BLEW THE KEYWORD
HRRZ T2,(T2) ;GET ADDRESS OF KEYWORD PROCESSOR
CALLRET (T2) ;DISPATCH TO KEYWORD PROCESSOR
PMRT1: PMRT1L,,PMRT1L ;KEYWORD TABLE
[ASCIZ/REFUSE/],,PMRREF ;REFUSE reason
[ASCIZ/VOLUMES/],,PMRVOL ;VOLUMES volid,...,volid
PMRT1L==.-PMRT1-1
PMRREF: CALL PREFUS ;PARSE REFUSAL
RET ;OPERATOR ERROR
ABTREQ (MREQ16,ABT%OP) ;ABORT REQUEST
MOVEI T1,1 ;SET T1 TO INDICATE ABORTION
RETSKP
; PREFUS - COMPLETE PARSING OF REFUSAL BY OPERATOR
; RETURNS +1: ERROR, OPERATOR NOTIFIED
; +2: SUCCESSFUL PARSE, ATMBFR/ ASCIZ REASON GIVEN BY OPERATOR
PREFUS: MOVEI T2,[FLDDB. .CMTXT] ;PARSE TEXT OUT TO CARRIAGE RETURN
CALL COMNDX
JRST PREFU1 ;ERROR
LDB T1,[POINT 7,ATMBFR,6] ;WAS THERE A REASON GIVEN?
JUMPN T1,RSKP ;YES, TAKE GOOD RETURN
PREFU1: JSP T1,RSPERR ;ERROR, TELL OPERATOR
ASCIZ/No reason given/
; PMRVOL - PARSE VOLID LIST FROM OPERATOR
; RSB/ ADDRESS OF REQUEST STATUS BLOCK
; RETURNS +1: ERROR, T1/ ADDRESS OF ASCIZ ERROR MESSAGE FOR OPERATOR
; +2: T1/ 0 - RSB AND VOLID LIST SET UP
; T1/ 1 - REQUEST ABORTED
PMRVOL: CALL VQDEL ;DELETE VOLID LIST (IF ANY)
MOVEI T1,1
STOR T1,RSBCV ;SET CURRENT VOLUME # TO 1
PMRV1: CALL COMNDV ;PARSE VOLID
RET ;FAILED
CALL VQADD ;ADD VOLUME TO LIST
JRST [ MOVEI T1,1 ;OUT OF TABLE SPACE
RETSKP]
MOVEI T2,[FLDDB.(.CMCMA,,,,,[FLDDB.(.CMCFM)])]
CALL COMNDX ;PARSE COMMA OR CARRIAGE RETURN
JRST [ JSP T1,RSPERR ;PARSE FAILED
ASCIZ/Syntactical error in volume-id list/]
HRRZS T3 ;GET ADDRESS OF ACTUAL FDB
LOAD T3,CM%FNC,(T3) ;GET FUNCTION CODE FROM FDB
CAIN T3,.CMCMA ;WHAT DID I JUST PARSE?
JRST PMRV1 ;COMMA, GO GET ANOTHER VOLID
SETZ T1, ;CARRIAGE RETURN, CLEAR T1
RETSKP
; PNVR - PARSE OPERATOR RESPONSE TO "KEYIN NEXT VOLID" WTOR
; T1/ ADDR OF ASCIZ RESPONSE TEXT
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: ERROR, T1/ ADDRESS OF ASCIZ ERROR MESSAGE FOR OPERATOR
; +2: T1/ 0 - VOLID ADDED TO RSB VOLID LIST
; T1/ 1 - REQUEST ABORTED
PNVR: CALL COMNDI ;SET UP FOR PARSING WITH COMND
MOVEI T2,[FLDDB. .CMKEY,,PNVKT] ;GET FDB ADDRESS
CALL COMNDX ;PARSE KEYWORD
JRST [ JSP T1,RSPERR ;ERROR
ASCIZ/REFUSE or VOLUME keyword missing/]
HRRZ T2,(T2) ;GET HANDLER ADDRESS
CALLRET (T2) ;DISPATCH TO HANDLER
PNVKT: PNVKTL,,PNVKTL ;KEYWORD TABLE
[ASCIZ/REFUSE/],,PMRREF
[ASCIZ/VOLUME/],,PNVVOL
PNVKTL==.-PNVKT-1
PNVVOL: SAVEQ ;OPERATOR RESPONDED WITH A VOLID
CALL COMNDV ;PARSE VOLID
RET ;FAILED
MOVE Q1,T1 ;SAVE VOLID
CALL CMDCFM ;CHECK FOR EOL
RET ;NOT THERE
MOVE T1,Q1 ;GET VOLID
CALL VQADD ;TACK IT ON TO THE END OF THE LIST
JRST [ MOVEI T1,1 ;OUT OF TABLE SPACE
RETSKP]
SETZ T1, ;SET SUCCESSFUL COMPLETION
RETSKP
; PSMR - PARSE OPERATOR RESPONSE TO STRUCTURE MOUNT WTOR MESSAGE
; T1/ ADDRESS OF ASCIZ RESPONSE TEXT
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: ERROR DETECTED WHILE PARSING RESPONSE, OPERATOR NOTIFIED
; +2: SUCCESSFUL PARSE, REQUEST ABORTED
; ATMBFR/ ASCIZ REASON GIVEN BY OPERATOR
PSMR: CALL COMNDI ;INIIALIZE FOR COMND JSYS
MOVEI T2,[FLDDB.(.CMKEY,,PSMKT)] ;SET UP FOR KEYWORD PARSE
CALL COMNDX ;PARSE KEYWORD
JRST [ JSP T1,RSPERR ;BAD KEYWORD, GIVE ERROR
ASCIZ/Response must be of the form:
REFUSE reason/]
MOVX T2,R%OPR
TDNE T2,RSBIFL(RSB) ;IS THIS AN OPR REQUEST?
RETSKP ;YES, FORGET REASON
CALL PREFUS ;PARSE REMAINDER OF REFUSAL
RET ;OPERATOR ERROR
ABTREQ (MREQ15,ABT%OP) ;OPERATOR REFUSED TO MOUNT VOLUME
RETSKP
PSMKT: PSMKTL,,PSMKTL
[ASCIZ/REFUSE/],,0
PSMKTL==.-PSMKT-1
; RSPERR - TELL OPERATOR THAT THERE WAS AN ERROR IN HIS RESPONSE
; T1/ ADDRESS OF ASCIZ ERROR MESSAGE
; RETURNS +1: ALWAYS
RSPERR: TMCT <%I%1A>
MOVEI T3,[ASCIZ/Response Error/] ;GET MESSAGE TYPE
CALLRET BTACKT ;SEND IT OFF TO THE OPERATOR
; WOASO - TELL OPERATOR A TAPE HAS BEEN GIVEN TO A USER
; MTA/ ADDR OF MTA STATUS BLOCK
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: ALWAYS
WOASO: MOVE T1,RSBITN(RSB) ;GET REQUEST #
TMCT <%I%M Given To Request %1D>
CALL CPYHDR ;COPY HEADER TO OPRHDR
TMCT <%I>
CALL TMCVOL ;DISPLAY VOLID
TMCT < now in use by%_ %U>
MOVE T1,RSBIFL(RSB)
TXNN T1,R%ONR ;WAS OPERATOR TOLD TO MOUNT TAPE?
CALL BTJOB ;NO, MAKE THIS A JOB MESSAGE
MOVEI T3,OPRHDR ;POINT TO HEADING
CALLRET BTWTO ;SHIP IT OFF TO THE OPERATOR
; WOCKSW - IF A SCRATCH VOLUME IS WRITE-PROTECTED, DISMOUNT IT AND
; GIVE AN ERROR MESSAGE TO THE OPERATOR
; MTA/ ADDR OF MTA STATUS BLOCK
; RETURNS +1: WRITE-PROTECTED SCRATCH VOLUME UNLOADED
; +2: TAPE WAS NOT A WRITE-PROTECTED SCRATCH
WOCKSW: MOVE T1,MTAFLG(MTA) ;GET FLAGS
TXNE T1,MA%SCR ;TAKE +2 IF NOT SCRATCH
TXNE T1,MA%WEN ;TAKE +2 IF WRITE-ENABLED
RETSKP
TMCT <%IUnloading drive %M>
SKIPE MTAVOL(MTA) ;DO I KNOW ITS VOLID?
CALL TMCVOL ;YES, THROW IT IN THERE TOO
TMCT <
Remount scratch tape with write ring>
MOVEI T3,[ASCIZ/No Ring In Scratch Tape/]
CALL BTWTO ;TELL OPERATOR
CALLRET UNLOAD ;UNLOAD THE TAPE
; WODISA - TELL OPERATOR A USER HAS RELEASED A TAPE DRIVE
; T1/ ADDR OF ASCIZ DISPOSITION TEXT
; MTA/ ADDR OF MTA STATUS BLOCK
; RETURNS +1: ALWAYS
WODISA: STAKT
TMCT <%I%M>
SKIPN MTAVOL(MTA) ;TAPE HAVE A VOLID?
JRST [ TMCT < Tape> ;NO
JRST .+2]
CALL TMCVOL ;DISPLAY VOLID
MOVE T1,CT1 ;GET ADDRESS OF CALLER'S TEXT
TMCT < %1A>
CALL BTJOB ;THIS IS A JOB MESSAGE
MOVEI T3,[ASCIZ/Tape Drive Released By User/]
CALLRET BTWTO ;SEND IT OFF
; WOLINF - TELL OPERATOR THAT I FAILED TO WRITE LABELS ON A TAPE
; MTA/ ADDR OF MTA STATUS BLOCK
; RETURNS +1: ALWAYS
WOLINF: TMCT <%IError writing labels on %M>
CALL TMCVOL ;DISPLAY VOLID
MOVEI T3,[ASCIZ/Tape Error Writing Labels/]
CALLRET BTWTO ;OUT TO OPERATOR
; WOLOCF - TELL OPERATOR THAT .MOLOC MTOPR FAILED
; MTA/ ADDR OF MTA STATUS BLOCK
; MT/ ADDR OF MT STATUS BLOCK
; RETURNS +1: ALWAYS
WOLOCF: TMCT <%IFailed to associate %M with %N%_Reason: %J>
MOVEI T3,[ASCIZ/MOUNTR System Task Error/]
CALLRET BTWTO ;OUT TO OPERATOR
; WOLRDX - TELL OPERATOR I COULDN'T READ ANYTHING FROM THE TAPE
; MTA/ ADDR OF MTA STATUS BLOCK
; RETURNS +1: ALWAYS
WOLRDX: TMCT <%ITape on %M may be labeled at a density that
is not supported by this drive.
Tape has been unloaded.>
MOVEI T3,[ASCIZ/Cannot Read Tape/]
CALLRET BTWTO
; WORCAN - TELL OPERATOR A MOUNT REQUEST WAS CANCELED
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: ALWAYS
WORCAN: MOVE T1,RSBIFL(RSB) ;GET FLAGS
TXNN T1,R%ONR ;DID THE OPERATOR SEE THE MESSAGE?
RET ;NO, DON'T SAY ANYTHING WAS CANCELED
MOVE T1,RSBITN(RSB) ;GET REQUEST #
TMCT <%IMount Request # %1D Canceled>
MOVEI T3,TMCMSG ;GET ADDRESS OF TEXT
CALLRET BTWTON ;TELL ALL OPERATORS
; WOTDAV - TELL OPERATOR OF AVAILABILITY OF TAPE DRIVE FOR SYSTEM USE
; MTA/ ADDR OF MTA STATUS BLOCK
; RETURNS +1: ALWAYS
WOTDAV: SAVEQ
SAVEAC <MT,RSB>
MOVEI Q1,1 ;ASSUME AVAILABLE
CALL CKMPAV ;IS IT AVAILABLE?
SETZ Q1, ;NO, SET NOT AVAILABLE
TMCT <%I%M set >
JUMPE Q1,[TMCT <un>
JRST .+1]
TMCT <available for assignment by MOUNTR>
LOAD MT,MTAMT ;MT ASSOCIATED?
JUMPN MT,[LOAD RSB,MTRSB ;YES, GET RSB ADDRESS
TMCT <%_%%Drive is currently in use by %U>
JRST .+1]
MOVE T3,[[ASCIZ/Tape Drive Set Unavailable/]
[ASCIZ/Tape Drive Set Available/]](Q1) ;GET HEADER
CALLRET BTWTO ;GET MESSAGE OUT TO OPERATOR
; WOTIMO - REPORT MTA DEVICE TIMEOUT TO THE OPERATOR
; MTA/ ADDR OF MTA STATUS BLOCK
; RETURNS +1: ALWAYS
WOTIMO: TMCT <%I%M operation timed out>
MOVEI T3,[ASCIZ/Tape Drive Timed Out/]
CALLRET BTWTO ;TELL THE OPERATOR
; WOTMD - TELL OPERATOR A TAPE HAS BEEN MOUNTED ON A DRIVE
; MTA/ ADDR OF MTA STATUS BLOCK
; RETURNS +1: ALWAYS
WOTMD: MOVX T1,MA%VMG
TDNE T1,MTAFLG(MTA) ;HAS THE OPERATOR BEEN TOLD ALREADY?
RET ;YES, NO ACTION THEN
IORM T1,MTAFLG(MTA) ;NO, SET MESSAGE-GIVEN
TMCT <%I%M>
SKIPE MTAVOL(MTA) ;DOES IT HAVE A VOLID?
JRST [ CALL TMCVOL ;YES, DISPLAY IT
TMCT <,>
JRST .+1]
LOAD T1,MTALT ;GET LABEL TYPE
JUMPE T1,WOTMD1 ;JUMP IF LT NOT KNOWN (AVR DISABLED)
MOVE T2,LTTXT(T1) ;GET ADDRESS OF TEXT
TMCT < %2A> ;SPEW OUT LABEL TYPE
CAIE T1,.LTUNL ;IS IT LABELED?
CALL [ TMCTR < labeled>] ;YES
WOTMD1: TMCT < tape mounted>
MOVEI T3,TMCMSG ;GET ADDRESS OF TEXT
CALLRET BTWTON ;BUILD AND TRANSMIT WTO MESSAGE
; WOUNL - TELL OPERATOR THAT A TAPE HAS BEEN UNLOADED
; WOUNLW - SAME AS WOUNL, EXCEPT WARNING MESSAGE IS GIVEN TOO
; MTA/ ADDR OF MTA STATUS BLOCK
; RETURNS +1: ALWAYS
WOUNLW: SKIPA T1,[BTWTO] ;DISPLAY WARNING
WOUNL: MOVEI T1,BTWTON ;SUPPRESS WARNING
STAKT
TMCT <%I%M> ;DISPLAY DRIVE NAME
SKIPE MTAVOL(MTA) ;DO I KNOW THE VOLID?
CALL TMCVOL ;YES, DISPLAY IT
TMCT < unloaded>
CALL CPYHDR ;COPY HEADER TO OPRHDR
TMCT <%I%%Use the DISMOUNT TAPE command to unload tape drives>
MOVEI T3,OPRHDR ;GET ADDRESS OF HEADER
MOVE T1,CT1 ;GET ADDRESS OF ROUTINE TO CALL
CALLRET (T1) ;OUT TO OPERATOR AND RETURN
; WOVMT - TELL OPERATOR A TAPE VOLUME MUST BE MOUNTED
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: ALWAYS
WOVMT: SAVEQ
SAVEAC <MTA>
; IN THE EVENT THAT A USER IS REQUESTING A SPECIFIC VOLUME AND
; THAT VOLUME IS UNDERGOING AVR ON A TAPE DRIVE, WE WANT TO
; INHIBIT SENDING THE WTO TO REQUEST THE TAPE UNTIL THE AVR
; SEQUENCE COMPLETES. THIS CODE CHECKS FOR THIS CONDITION.
LOAD T1,RSBSTE ;GET REQUEST STATE
MOVE T2,RSBIFL(RSB) ;GET FLAGS
CAIN T1,RST.WM ;WAITING FOR MOUNT
TXNE T2,R%ONR ; AND OPERATOR NOT TOLD YET?
RET ;NOT BOTH, DON'T DO ANYTHING
CALL VQGCV ;GET CURRENT VOLID
JUMPE T1,WOV2 ;SCRATCH
MOVE T2,MTAN ;GET # OF MTA'S TO SCAN
MOVEI MTA,MTA0-MTASZ ;START HERE
WOV1: ADDI MTA,MTASZ ;POINT AT NEXT MTA
SOJL T2,WOV2 ;NONE LEFT, SEND MESSAGE
LOAD T3,MTASTE ;GET DRIVE STATE
CAIE T3,S.AV ;AVAILABLE TO USERS?
JRST WOV1 ;NO, SKIP IT
JE MTAJCT,,WOV1 ;SKIP IF AVR NOT IN PROGRESS
CAMN T1,MTAVOL(MTA) ;DRIVE & REQUEST VOLIDS MATCH?
RET ;YES, MESSAGE SUPPRESSED
JRST WOV1 ;NO, CONTINUE DRIVE SCAN
; MUST TELL THE OPERATOR TO MOUNT THE TAPE, START BUILDING MESSAGE
WOV2: SETONE R%ONR,RSBIFL(RSB) ;SET OPERATOR-NOTIFIED
MOVE T1,RSBITN(RSB) ;GET REQUEST #
TMCT <%ITape Mount Request # %1D>
CALL CPYHDR ;COPY HEADER TO OPRHDR
; BUILD THE BODY OF THE MESSAGE
TMCT <%IMount >
CALL VQGCV ;GET VOLID IN T1
MOVE Q1,T1 ;COPY VOLID TO SAFE PLACE
LOAD T2,RSBLT ;LABEL TYPE KNOWN?
JUMPN T2,[MOVEI T1,[ASCIZ/Labeled/] ;YES
CAIE T2,.LTUNL
SKIPE Q1
MOVE T1,LTTXT(T2) ;UNLABELED OR NOT SCRATCH
MOVX T2,TM%BYP
TDNE T2,RSBUFL(RSB) ;BYPASS?
MOVEI T1,[ASCIZ/BYPASS/] ;YES, SAY SO
TMCT <%1A > ;DISPLAY LABEL TYPE
JRST .+1]
JUMPE Q1,[TMCT <scratch tape> ;SCRATCH TAPE, SAY SO
JRST .+1]
JUMPN Q1,[TMCT <volume %5S> ;DISPLAY SPECIFIC VOLUME
JRST .+1]
LOAD Q1,RSBDRV ;DRIVE TYPE KNOWN?
JUMPN Q1,[MOVE T1,DRVTXT(Q1) ;GET POINTER TO DRIVE TEXT
TMCT <, %1A> ;DISPLAY DRIVE TYPE
JRST .+1]
LOAD Q1,RSBDEN ;DENSITY KNOWN?
JUMPN Q1,[MOVE T1,DENTAB(Q1) ;YES, GET DENSITY
TMCT <, %1D BPI>
JRST .+1]
MOVEI T1,[ASCIZ/, READ-ONLY/] ;ASSUME READ-ONLY
MOVX T2,TM%WEN
TDNE T2,RSBUFL(RSB)
MOVEI T1,[ASCIZ/, WRITE-ENABLED/]
TMCT <%1A%_%U>
JE R%ONV,RSBIFL(RSB),[SETONE R%ONV,RSBIFL(RSB)
CALL VQCNT ;MORE THAN 1 VOLID IN SET?
SOJLE T1,.+1 ;NO
MOVE T1,RSBSSN(RSB) ;GET SETNAME
TMCT <
Volumes in set %1S: >
CALL TMCVLS ;DISPLAY VOLID LIST
JRST .+1]
SKIPE RSBRMK(RSB) ;DID THE USER SUPPLY A REMARK?
JRST [ MOVEI T1,RSBRMK(RSB) ;YES, GET ADDR OF REMARK
TMCT <%_User's remark: %1A>
JRST .+1]
MOVEI T3,OPRHDR ;GET ADDRESS OF HEADING
CALLRET BTWTO ;SEND WTO OFF TO THE OPERATOR
; WOWDDR - REQUEST REMOUNT OF TAPE - DRIVE COULDN'T HANDLE DENSITY
; MTA/ ADDR OF MTA STATUS BLOCK
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: ALWAYS
WOWDDR: TMCT <%I%M>
CALL TMCVOL ;DISPLAY VOLID
MOVE T1,MTAVOL(MTA) ;GET VOLID
LOAD T2,RSBDEN
MOVE T2,DENTAB(T2) ;GET NUMERIC DENSITY
TMCT < being unloaded
Remount volume %1S on %2D BPI drive>
MOVEI T3,[ASCIZ/Remount Tape Volume/]
CALLRET BTWTO
; WOWPE - TELL OPERATOR THAT WRITE RING SHOULD BE INSERTED OR REMOVED
; MTA/ ADDR OF MTA STATUS BLOCK
; RETURNS +1: ALWAYS
WOWPE: TMCT <%I%M>
CALL TMCVOL ;DISPLAY VOLID
LOAD T1,MA%WEN,MTAFLG(MTA) ;GET CURRENT WRITE STATUS
MOVE T1,[[ASCIZ/Insert/]
[ASCIZ/Remove/]](T1) ;GET WHAT TO DO
TMCT <%_%1A write ring and remount tape>
MOVEI T3,[ASCIZ/Tape Write Protect Error/]
CALLRET BTWTO ;OUT TO OPERATOR
; WRNXTV - ASK OPERATOR FOR NEXT VOLUME OF VOLUME SET
; T1/ ADDR OF RESPONSE HANDLER THAT WILL BE CALLED BY INWTOR
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: ALWAYS
WRNXTV: MOVE T2,RSBSSN(RSB)
TMCT <%ISupply next volume-id for tape set %2S%_%U
Respond with either of:
VOLUME volid
REFUSE reason>
MOVEI T2,RSBWTB(RSB) ;GET WTB ADDRESS
MOVEI T3,[ASCIZ/Key In Next Volume Identifier/]
CALLRET BTWTOR ;SEND IT OFF
; WRUTR - TELL OPERATOR THAT A USER TAPE MOUNT REQUEST HAS BEEN
; RECEIVED AND ASK HIM TO KEY IN VOLID LIST
; T1/ ADDRESS OF RESPONSE HANDLER THAT WILL BE CALLED BY INWTOR
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: ALWAYS
WRUTR: MOVE T2,RSBSSN(RSB)
TMCT <%IVolume set %2S, %U
Respond with either of:
RESPOND n VOLUMES volid,volid,...
RESPOND n REFUSE reason>
MOVEI T2,RSBWTB(RSB) ;WTB ADDRESS
MOVEI T3,[ASCIZ/Tape Set Request/] ;MESSAGE TYPE
CALLRET BTWTOR ;SEND OFF WTOR
; TEXT MESSAGE COMPOSITION (TMC) SUBROUTINES
; ALL TMC SUBROUTINES RETURN +1 ALWAYS
TMC1: MOVE T1,TMCPTR ;GET BUFFER POINTER
SETZ T2,
IDPB T2,T1 ;PUT A NULL AT THE END OF THE BUFFER
SUBI T1,TMCMSG-1 ;COMPUTE BUFFER SIZE IN WORDS
HRRZM T1,TMCWDS ;STORE IT FOR CALLING ROUTINES
RET
; TMCRSP - SPECIAL VERSION OF TMCASZ FOR INCOMING WTOR RESPONSES
; T1/ 0 ,, ADDRESS OF ASCIZ WTOR RESPONSE
TMCRSP: HRLI T1,(POINT 7) ;CONSTRUCT BYTE POINTER
TMCRS1: ILDB T2,T1 ;GET A BYTE FROM RESPONSE TEXT
JUMPE T2,[TMCTR <%_>] ;END, APPEND CRLF AND RETURN
CAIN T2,"F"-100
JRST TMCRS1 ;DON'T COPY CTRL/F
CAIN T2,.CHESC
JRST TMCRS1 ;DON'T COPY ESCAPE
CAIN T2,"?"
JRST TMCRS1 ;DON'T COPY QUESTION MARK
CAIN T2,.CHCRT
JRST TMCRS1 ;DON'T COPY CARRIAGE RETURN
CAIN T2,.CHLFD
MOVEI T2," " ;CHANGE LINE FEED TO BLANK
IDPB T2,TMCPTR ;PUT CHARACTER IN TMCMSG
JRST TMCRS1 ;LOOP UNTIL NULL
; CPYHDR - COPY CONTENTS OF TMCMSG TO OPRHDR
CPYHDR: MOVE T1,[TMCMSG,,OPRHDR] ;BLT SOURCE,,DESTINATION
BLT T1,OPRHDR+OPRHSZ-1
RET
; TMCVOL - DISPLAY THE TEXT " Volume " FOLLOWED BY THE MTA VOLID
; MTA/ ADDR OF MTA STATUS BLOCK
TMCVOL: SKIPN T1,MTAVOL(MTA) ;GET VOLID
JRST [ TMCTR < scratch tape>] ;ZERO, THEREFORE SCRATCH
TMCTR < Volume %1S> ;DISPLAY AND RETURN
; TMCVLS - DISPLAY THE VOLUME-ID LIST FOR A GIVEN USER REQUEST
; RSB/ ADDR OF REQUEST STATUS BLOCK
TMCVLS: SAVEQ
QSCANI <RSBVLS(RSB)> ;SET UP TO SCAN VOLID LIST
SETO Q1, ;INIT COUNTER
TMCVL1: CALL QMSCAN ;GET ADDRESS OF NEXT VOLID ENTRY IN T2
RET ;NONE LEFT, SPLIT
AOJG Q1,[TMCT <, > ;SEPARATE VOLIDS WITH COMMAS
JRST .+1]
SKIPN T1,1(T2) ;GET SIXBIT VOLID
JRST [ TMCT <scratch> ;HE'S DEAD, JIM
JRST TMCVL1]
TMCT <%1S> ;VOLID IS KNOWN
JRST TMCVL1 ;LOOP UNTIL ALL VOLIDS ARE DISPLAYED
; DRIVER FOR TMCT AND TMCTR MACROS
; CX/ ADDRESS OF FORMATTING STRING
TMCT0: HRLI CX,(POINT 7) ;MAKE BYTE POINTER TO SOURCE STRING
MOVEM CX,TMCTSP ;SAVE POINTER
SAVET ;ALL AC'S PRESERVED (EXCEPT 15,16)
TRVAR <TMCTAR,<TMCTAC,4>>
DMOVEM T1,TMCTAC ;SAVE T1-T4
DMOVEM T3,2+TMCTAC
TMCT1: ILDB T1,TMCTSP ;GET NEXT CHARACTER FROM STRING
JUMPE T1,TMC1 ;END OF STRING
CAIE T1,"%" ;TRIGGER CHARACTER?
JRST [ IDPB T1,TMCPTR ;NO, JUST COPY IT
JRST TMCT1] ;LOOP THRU STRING
TXZ F,ARGF ;SAY NO ARGUMENT (YET)
SETZM TMCTAR ;ZERO ARGUMENT ACCUMULATOR
TMCT2: ILDB T1,TMCTSP ;GET NEXT CHARACTER
CAIG T1,"9" ;NUMERIC?
CAIGE T1,"0"
JRST TMCT3 ;NO
SUBI T1,"0" ;YES, CONVERT ASCII TO INTEGER
MOVE T2,TMCTAR ;GET CURRENT ACCUMULATOR
IMULI T2,12 ;DECIMAL SHIFT
ADD T2,T1 ;ADD IN NEXT DIGIT
MOVEM T2,TMCTAR ;STORE UPDATED ACCUMULATOR
TXO F,ARGF ;SET ARG-SEEN
JRST TMCT2 ;CONTINUE ARGUMENT SCAN
TMCT3: MOVSI T2,-TMCDTL ;GET AOBJN POINTER TO DISPATCH TABLE
TMCT4: HLRZ T3,TMCDT(T2) ;GET CHARACTER FROM DISPATCH TABLE
CAME T1,T3 ;MATCH FUNCTION CHARACTER?
JRST [ AOBJN T2,TMCT4 ;NO, CONTINUE SCAN
JRST TMC1] ;NO MATCH??? ERROR IN FORMAT STRING
HRRZ T1,TMCDT(T2) ;FOUND IT, GET ROUTINE ADDRESS
CALL (T1) ;CALL HANDLER
MOVE T1,TMCPTR ;GET BUFFER POINTER
SETZ T2,
IDPB T2,T1 ;PUT A NULL AT THE END OF TEXT
SUBI T1,TMCMSG-1 ;COMPUTE TEXT SIZE IN WORDS
HRRZM T1,TMCWDS ;STORE IT FOR CALLERS
JRST TMCT1 ;FUNCTION DONE, CONTINUE STRING SCAN
; TMCT DISPATCH TABLE
TMCDT: "A",,%A ;ASCIZ STRING, ARG = AC CONTAINING ADDRESS
"C",,%C ;ADVANCE TO COLUMN, ARG = COLUMN#
"D",,%D ;DECIMAL #, ARG = AC CONTAINING #
"I",,%I ;INITIALIZE TMC FORMATTED STRING
"J",,%J ;JSYS ERROR MESSAGE, ARG = AC CONT. ERROR CODE
;NO ARG MEANS USE MOST RECENT MOUNTR ERROR
"M",,%M ;DISPLAY "MTAn:" (NEEDS MTA AC)
"N",,%N ;DISPLAY "MTn:" (NEEDS MT AC)
"O",,%O ;OCTAL NUMBER, ARG = AC CONTAINING #
"S",,%S ;SIXBIT, ARG = AC CONTAINING SIXBIT VALUE
"U",,%U ;USER NAME, ARG = AC CONTAINING USER#
;NO ARG MEANS DO NAME/JOB/LINE FOR CURRENT RSB
"V",,%V ;DEVICE NAME, ARG = AC CONTAINING DESIGNATOR
"Y",,%Y ;ARG = AC CONTAINING NON-0 FOR Yes OR 0 FOR No
"%",,%% ;PERCENT SIGN
"_",,%CRLF ;CRLF
TMCDTL==.-TMCDT ;NUMBER OF ENTRIES IN TABLE
GETREG: JXE F,ARGF,[ADJSP P,-1 ;IF NO ARG PRESENT
RET] ;RETURN TO CALLER'S CALLER
MOVE T1,TMCTAR ;GET ARGUMENT
CAIG T1,T4 ;IN T1-T4?
ADDI T1,-1+TMCTAC ;YES, ADD OFFSET TO STORED AC'S
MOVE T1,(T1) ;GET CONTENTS OF REGISTER
RET
%CRLF: SKIPA T1,[[ASCIZ/
/]]
%A: CALL GETREG ;GET ADDRESS OF TEXT
%A0: HRLI T1,(POINT 7) ;MAKE STRING POINTER
%A1: ILDB T2,T1 ;GET NEXT CHARACTER FROM STRING
JUMPE T2,R ;EXIT IF END OF STRING
IDPB T2,TMCPTR ;COPY CHARACTER TO OUTPUT STRING
JRST %A1 ;LOOP THRU INPUT
%C: MOVE T3,[POINT 7,TMCMSG] ;GET POINTER TO EXISTING MESSAGE
TMCC2: SETZ T2, ;# OF CHARACTERS SINCE LAST LINEFEED
TMCC1: ILDB T4,T3 ;GET NEXT CHARACTER FROM MESSAGE
CAIN T4,.CHLFD ;IS IT A LINEFEED?
JRST TMCC2 ;YES, RESET COUNTER AND CONTINUE SCAN
SKIPE T4 ;END OF STRING?
AOJA T2,TMCC1 ;NO, COUNT CHARACTER AND LOOP
MOVE T1,TMCTAR ;GET DESIRED COLUMN POSITION
SUB T1,T2 ;GET # OF SPACES PLUS 1
MOVEI T2," " ;GET SPACE
TMCC3: SOJLE T1,TMC1 ;EXIT IF NO MORE SPACES NEEDED
IDPB T2,TMCPTR ;INSERT A SPACE
JRST TMCC3 ;LOOP UNTIL POSITION IS REACHED
%D: CALL GETREG ;GET NUMBER
MOVEI T3,12 ;BASE 10
JRST %DO ;MERGE
%O: CALL GETREG ;GET NUMBER
MOVEI T3,10 ;BASE 8
%DO: MOVE T2,T1 ;# TO T2 FOR NOUT
MOVE T1,TMCPTR ;GET DESTINATION STRING POINTER
NOUT ;OUTPUT NUMBER
SKIPA
MOVEM T1,TMCPTR ;STORE UPDATED POINTER
RET
%I: MOVE T1,[POINT 7,TMCMSG] ;GET PTR TO TEXT STRING
MOVEM T1,TMCPTR ;INITIALIZE IT
RET
%J: MOVEI T1,-1 ;ASSUME NO ARGUMENT
TXNE F,ARGF ;ARG PRESENT?
CALL GETREG ;YES, GET ERROR CODE FROM AC
MOVE T2,T1 ;CODE TO T2 FOR ERSTR
HRLI T2,.FHSLF ;FORK HANDLE ,, ERROR CODE
MOVE T1,TMCPTR ;DESTINATION STRING POINTER
SETZ T3, ;NO LIMIT ON LENGTH
ERSTR ;GET ERROR STRING
JFCL
JFCL
MOVEM T1,TMCPTR ;STORE UPDATED POINTER
RET
%M: CALL GMTADD ;GET MTA DEVICE DESIGNATOR
SKIPA
%N: CALL GMTDD ;GET MT DEVICE DESIGNATOR
%V1: MOVE T2,T1 ;DESIGNATOR TO T2 FOR DEVST
MOVE T1,TMCPTR ;GET DEST STRG PTR
DEVST ;GET DEVICE NAME
CALL STOP
MOVEM T1,TMCPTR ;STORE UPDATED POINTER
MOVEI T1,":"
IDPB T1,TMCPTR ;PUT A COLON AT THE END
RET
%S: CALL GETREG ;GET SIXBIT QUANTITY
%S1: SETZ T2, ;CLEAR T2 FOR SHIFT
ROTC T1,6 ;GET NEXT CHARACTER IN T2
ADDI T2,40 ;CONVERT TO ASCII
IDPB T2,TMCPTR ;STORE IT
JUMPN T1,%S1 ;LOOP IF MORE NON-BLANKS REMAINING
RET
%U: JXE F,ARGF,%UNA ;JUMP IF NO ARGUMENT
CALL GETREG ;GET USER#
MOVE T2,T1 ;USER# TO T2 FOR DIRST
MOVE T1,TMCPTR ;GET DEST POINTER
DIRST ;GET USER NAME
SKIPA
MOVEM T1,TMCPTR ;STORE UPDATED POINTER
RET
%UNA: PUSH P,TMCTSP ;SAVE CURRENT INPUT POINTER
TMCT <User>
CAIN RSB,MTNAV ;RSB AVAILABLE?
JRST %U1 ;NO, THAT'S ALL
LOAD T1,RSBJNO ;GET JOB #
MOVE T2,RSBUNO(RSB) ;GET USER #
TMCT < %2U, Job %1D>
MOVSS T1 ;MOVE JOB # TO LEFT HALF
HRRI T1,.JOBTT ;GET TABLE # IN RIGHT HALF
GETAB ;GET LINE # FROM JOBTTY TABLE
CALL STOP
HLRES T1 ;DETACHED?
JUMPE T1,%U1 ;IF ZERO, USER PROBABLY LOGGED OUT
JUMPL T1,[TMCT <, DETACHED> ;IF DETACHED, SAY SO
JRST %U1]
TMCT <, Terminal %1O> ;SHOW LINE # AND RETURN
%U1: POP P,TMCTSP ;RESTORE PREVIOUS STRING POINTER
RET
%V: CALL GETREG ;GET DESIGNATOR IN T1
JRST %V1 ;GO DISPLAY IT
%Y: CALL GETREG ;GET ARG IN T1
JUMPN T1,[JSP T1,%A0 ;NON-ZERO, SAY YES
ASCIZ/Yes/]
JSP T1,%A0 ;ZERO, SAY NO
ASCIZ/No/
%%: MOVEI T1,"%"
IDPB T1,TMCPTR ;STORE PERCENT CHARACTER
RET
SUBTTL QUASAR INTERFACE
; GETRSB - ALLOCATE A REQUEST STATUS BLOCK
; RETURNS +1: RSB ALLOCATED, BUT IT'S THE LAST ONE
; +2: RSB ALLOCATED, MORE FREE RSB'S LEFT
; RSB/ ADDR OF REQUEST STATUS BLOCK
GETRSB: MOVEI T1,IRBQDB ;POINT TO INACTIVE RSB QUEUE
CALL QMDQH ;DEQUEUE HEAD OF QUEUE
CALL STOP ;QUEUE EMPTY, PROGRAM LOGIC ERROR
MOVEI RSB,-RSBLNK(T2) ;LOAD UP RSB AC
MOVS T1,RSB ;BLT SOURCE
HRRI T1,1(RSB) ;BLT DESTINATION
SETZM (RSB) ;CLEAR 1ST WORD OF RSB
BLT T1,RSBSIZ-1(RSB) ;CLEAR THE REST OF THE RSB
MOVEI T2,RSBLNK(RSB) ;GET ADDRESS OF RSB LINKAGE WORD
MOVEI T1,ARBQDB
CALL QMQT ;QUEUE TO TAIL OF ACTIVE QUEUE
SKIPN IRBQDB ;WAS THIS THE LAST FREE RSB?
RET ;YES, RETURN +1
RETSKP
; GETRSI - INITIALIZE FREE RSB POOL FOR GETRSB
; RETURNS +1: ALWAYS
GETRSI: SAVEQ
MOVEI Q1,RSB0 ;GET ADDRESS OF RSB POOL
MOVEI Q2,MAXMRQ+1 ;# OF RSBS IN POOL
GTRSI1: MOVEI T1,IRBQDB ;GET QDB ADDRESS
MOVEI T2,RSBLNK(Q1) ;GET ADDRESS OF RSB LINKAGE
CALL QMQT ;QUEUE RSB TO TAIL OF FREE QUEUE
ADDI Q1,RSBSIZ ;POINT Q1 AT NEXT RSB
SOJG Q2,GTRSI1 ;LOOP THRU ALL RSBS
RET
; GORSB - GET RSB FOR FUNCTION REQUESTED VIA OPR COMMAND
; T1/ REQUEST TYPE CODE
; RETURNS +1: RSB POOL EMPTY, ACK MESSAGE SENT TO OPERATOR
; +2: SUCCESS, RSB/ ADDR OF REQUEST STATUS BLOCK
GORSB: STAKT
CALL GETRSB ;TRY TO ASSIGN RSB
TDZA T4,T4 ;SET SHORTAGE FLAG
MOVEI T4,1 ;SET NO SHORTAGE
MOVE T1,CT1
STOR T1,RSBTYP ;SET TYPE IN RSB
MOVX T1,R%OPR+R%PRIV ;SET FROM-OPERATOR AND PRIVILEGED
IORM T1,RSBIFL(RSB)
JUMPN T4,RSKP ;TAKE +2 IF NO FREESPACE SHORTAGE
ABTREQ (ABRTNR) ;SHORTAGE, ABORT REQUEST
CALL PRQABT ;PUT RSB BACK ON INACTIVE QUEUE
MOVEI T3,[ASCIZ/Space exhausted, try later/]
CALLRET BTACK ;TELL OPERATOR ABOUT BUMMER
; MATR - PROCESS USER REQUEST FOR ATTRIBUTES OF MOUNTED DEVICE
; (CURRENTLY VALID ONLY FOR TAPES)
; RBUF/ ATTRIBUTE-REQUEST MESSAGE
; T1/ SIZE OF MESSAGE (WORDS)
; RETURNS +1: ALWAYS
MATR: SAVEQ
SAVEAC <MT,RSB>
CAIE T1,.MATQS ;CHECK SIZE
JRST [ CALLRET BADQM] ;NOT WHAT IT SHOULD BE
MOVE T1,RBUF+.MATDV ;GET DEVICE DESIGNATOR
CALL DDMT ;GET MT STATUS BLOCK ADDRESS
TDZA RSB,RSB ;BAD MT DEVICE, FORCE ERROR RETURN
LOAD RSB,MTRSB ;GET RSB ADDRESS
SKIPE RSB
CAIN RSB,MTNAV
JRST [ TMCT <%IInvalid device> ;BAD MT OR NO REQ ASSOCIATED
MOVE T1,RBUF+.MATPD ;GET USER'S PID
MOVX T2,MF.FAT ;GET FATAL-ERROR FLAG
MOVE T3,RBUF+.MSCOD ;GET USER'S ACK CODE
CALLRET TXTMSG] ;RESPOND TO USER WITH GLX TEXT MESSAGE
; CONSTRUCT RESPONSE, BUILDING-BLOCK STYLE
CALL PBINIT ;INITIALIZE BUILDING-BLOCK STRUCTURE
MOVE Q1,[2,,.MATDD] ;CONSTRUCT DEVICE-DESIGNATOR BLOCK
MOVE Q2,RBUF+.MATDV
MOVEI T1,Q1 ;GET ADDR OF SOURCE BLOCK
CALL PBBLK ;INSTALL IT
HRRI Q1,.TMSET ;GET SIZE AND TYPE FOR SETNAME
MOVE Q2,RSBSSN(RSB) ;GET SETNAME
MOVEI T1,Q1 ;GET ADDR OF SOURCE BLOCK
CALL PBBLK ;INSTALL IT
CALL VQCNT ;GET # OF VOLIDS
MOVSI Q1,1(T1) ;BLOCK LENGTH = # OF VOLIDS + 1
HRRI Q1,.TMVOL ;GET BLOCK TYPE
MOVEI T1,Q1 ;GET ADDR OF SOURCE BLOCK
HRRZ Q2,PBBPT ;GET ADDRESS OF DESTINATION BLK HEADER
CALL PBBLK ;INSTALL IT
HLRZS Q1 ;GET # OF VOLIDS + 1
MATR3: SOJG Q1,[AOBJN Q2, ;BUMP INDICES (NEVER JUMPS)
HLRZ T1,Q2 ;GET VOLID INDEX
CALL VQGET ;GET VOLID
JFCL ;SHOULD NEVER FAIL
MOVEM T1,(Q2) ;STORE VOLID INTO MESSAGE
JRST MATR3] ;LOOP THRU ALL VOLIDS
MOVE T1,PBBPT ;MESSAGE IS COMPLETE, GET HIGH ADDRESS
SUBI T1,TBUF ;COMPUTE LENGTH OF MESSAGE
MOVSS T1 ;TO LEFT HALF
HRRI T1,.QOMAR ;GET MESSAGE CODE
SETZ T2, ;NO FLAGS
MATR2: MOVE T3,RBUF+.MSCOD ;GET ACK CODE FOR USER
CALL GALHDR ;BUILD GALAXY HEADER IN MESSAGE
MOVE T1,RBUF+.MATPD ;GET USER'S PID
CALLRET TRANU ;SEND MESSAGE TO USER
; QMNT - PROCESS USER MOUNT REQUEST MESSAGE FROM QUASAR
; RBUF/ IPCF MOUNT MESSAGE
; T1/ SIZE OF MESSAGE (WORDS)
; RETURNS +1: ALWAYS
QMNT: SAVEQ
CAIE T1,1000 ;DID I GET A PAGE OF DATA?
JRST [ CALLRET BADQM] ;NO, QUASAR BLEW IT
; GET RSB AND COPY USER-DESCRIPTOR INFORMATION INTO IT
SETZ Q2, ;ASSUME NO PROBLEMS WITH RSB POOL
CALL GETRSB ;ALLOCATE STATUS BLOCK FOR THIS REQUEST
SETO Q2, ;FREE RSB POOL IS NOW EMPTY
MOVE T1,RBUF+.MMNAM
MOVEM T1,RSBRNM(RSB) ;MOVE REQUEST NAME TO RSB
MOVE T1,RBUF+.MMITN
MOVEM T1,RSBITN(RSB) ;MOVE QUASAR INTERNAL TASK # TO RSB
MOVE T1,RBUF+.MMUCD
MOVEM T1,RSBCOD(RSB) ;MOVE USER'S ACK CODE TO RSB
MOVE T1,RBUF+.MMPID
MOVEM T1,RSBPID(RSB) ;MOVE USER'S PID TO RSB
LOAD T1,MD.PJB,RBUF+.MMCAP
STOR T1,RSBJNO ;MOVE USER'S JOB # TO RSB
MOVE T1,RBUF+.MMUNO
MOVEM T1,RSBUNO(RSB) ;MOVE USER'S USER # TO RSB
MOVX T1,MD.PWH+MD.POP
MOVX T2,R%PRIV
TDNE T1,RBUF+.MMCAP ;DOES USER HAVE WHEEL OR OPERATOR?
IORM T2,RSBIFL(RSB) ;YES, MARK HIM AS PRIVILEGED
MOVSI T1,RBUF+.MMACT ;BLT SOURCE
HRRI T1,RSBACT(RSB) ;BLT DESTINATION
BLT T1,RSBACT+7(RSB) ;MOVE USER'S ACCOUNT STRING TO RSB
; IDENTIFY REQUEST TYPE AND DISPATCH TO THE APPROPRIATE PROCESSOR
JUMPN Q2,[ABTREQ (MREQ31) ;ABORT IF RSB'S IN SHORT SUPPLY
TXZ F,ABORTF ;CLEAR ABORTED-REQUESTS-PRESENT
CALLRET PRQABT] ;MAKE SURE AT LEAST 1 FREE RSB IS LEFT
MOVE T1,RBUF+.MMARC ;GET ENTRY COUNT
CAIE T1,1 ;IS IT 1?
JRST MSERR ;NO, FORMAT ERROR
MOVEI T2,RBUF+.MMHSZ ;GET ADDRESS OF FIRST ENTRY
MOVE T3,RBUF+.MMUMS ;GET SIZE OF USER IPCF MESSAGE
SUBI T3,.MMHSZ ;COMPUTE SIZE OF MOUNT-ENTRY REGION
CALL CKBSTR ;CHECK BUILDING-BLOCK STRUCTURE
MSERR: JRST [ ABTRET (MREQ13)] ;STRUCTURAL ERROR IN MOUNT MESSAGE
MOVEI T1,RBUF+.MMHSZ ;GET ADDRESS OF FIRST ENTRY
LOAD T2,AR.TYP,(T1) ;GET TYPE OF ENTRY
STOR T2,RSBTYP ;STORE REQUEST TYPE IN RSB
CAIN T2,.MNTTP ;IS IT A USER TAPE MOUNT?
JRST [ CALLRET UTM] ;YES, GO PROCESS IT
CAIN T2,.MNTST ;USER STRUCTURE MOUNT?
JRST [ CALLRET USM] ;YES, GO PROCESS IT
CAIN T2,.DSMST ;DISMOUNT STRUCTURE?
JRST [ CALLRET USD] ;YES
NOSHIP,<
CAIN T2,.MNTDT ;DECTAPE MOUNT?
JRST [ CALLRET UDTM] ;YES
>;NOSHIP
ABTRET (MREQ21) ;I CAN'T HANDLE ANYTHING ELSE
; QSRINI - ESTABLISH IPCF RAPPORT WITH QUASAR
; RETURNS +1: ALWAYS
QSRINI: MOVEI T1,.SPQSR
CALL GSYSPD ;GET QUASAR'S PID FROM SYSTEM PID TABLE
JRST [ MOVEI T1,^D5000 ;NOT THERE YET
DISMS ;WAIT 5 SECONDS
JRST QSRINI] ; AND TRY AGAIN
MOVEM T1,APPID+.APQSR ;STUFF PID IN A/P TABLE
; BUILD AND TRANSMIT HELLO MESSAGE TO QUASAR
MOVE T1,[HEL.SZ,,.QOHEL] ;MESSAGE LENGTH ,, MESSAGE TYPE
SETZB T2,T3 ;NO FLAGS, NO ACK CODE
CALL GALHDR ;CONSTRUCT GALAXY HEADER IN TBUF
MOVE T1,[SIXBIT/MOUNTR/]
MOVEM T1,TBUF+HEL.NM ;MY NAME
MOVX T1,FLD(%%.QSR,HEFVER)
MOVEM T1,TBUF+HEL.FL ;QSRMAC VERSION #
MOVX T1,FLD(1,HENNOT)+FLD(HENMAX,HENMAX)
MOVEM T1,TBUF+HEL.NO ;# OF OBJ TYPES, MAX # OF JOBS
MOVX T1,.OTMNT
MOVEM T1,TBUF+HEL.OB ;I HANDLE MAGTAPE MOUNT REQUESTS
MOVEI T1,.APQSR ;GOING TO QUASAR
CALL TRANG ;TRANSMIT MESSAGE
RET
; QSRMRC - DISPATCH IPCF MESSAGES FROM QUASAR TO APPROPRIATE ROUTINES
; MRPDB, RBUF/ PDB AND MESSAGE
; RETURNS +1: ALWAYS
QSRMRC: SAVEQ
CALL CKGHDR ;CHECK OUT GALAXY HEADER
JRST [ CALLRET BADQM] ;BAD HEADER
; T1/ MESSAGE LENGTH (WORDS) T2/ MESSAGE TYPE
MOVSI T4,-QDTABL ;GET AOBJN POINTER
QSRMR1: HLRZ T3,QDTAB(T4) ;GET MESSAGE TYPE FROM TABLE
CAME T2,T3 ;DOES IT MATCH THE MESSAGE I JUST GOT?
JRST [ AOBJN T4,QSRMR1 ;NO, LOOP
CALLRET BADQM] ;DOESN'T MATCH ANYTHING IN THE TABLE
HRRZ T2,QDTAB(T4) ;GET ADDRESS OF DISPATCH WORD
MOVE T2,(T2) ;GET DISPATCH WORD
TLZE T2,1 ;HAVE TO CALL ORNBCK?
JRST [ DMOVE Q1,T1 ;YES, SAVE T1 & T2
CALL ORNBCK
JRST [ CALLRET BADQM] ;ERROR, REPORT IT AND RETURN
DMOVE T1,Q1 ;COPY 'EM BACK
JRST .+1]
CALLRET (T2) ;DISPATCH TO HANDLER, T1/ MSG LENGTH
; DISPATCH TABLE FOR MESSAGE TYPES RECEIVED FROM QUASAR
; 1 IN LEFT HALF OF LITERAL MEANS ORNBCK MUST BE CALLED BEFORE DISPATCH
QDTAB: .QOMNT,,[0,,QMNT] ;MOUNT REQUEST FROM USER
.QOMTA,,[0,,TCAN] ;TAPE MOUNT CANCEL
.QOMAT,,[0,,MATR] ;ATTRIBUTE REQUEST FROM USER
.OTDMT,,[1,,KDMT] ;OPR COMMAND - DELETE MOUNT-REQUEST
.OTENA,,[1,,KENA] ;OPR COMMAND - ENABLE
.OTDIS,,[1,,KDIS] ;OPR COMMAND - DISABLE
.OTDSM,,[1,,KDSM] ;OPR COMMAND - DISMOUNT
.OTSDK,,[1,,KSDK] ;OPR COMMAND - SET DISK-DRIVE
.OTIDN,,[1,,KIDN] ;OPR COMMAND - IDENTIFY
.OTMTS,,[1,,KMSS] ;OPR COMMAND - MOUNT
.OTSTP,,[1,,KSTP] ;OPR COMMAND - SET TAPE-DRIVE
.OTSHD,,[1,,KSHD] ;OPR COMMAND - SHOW STATUS DISK
.OTSHT,,[1,,KSHT] ;OPR COMMAND - SHOW STATUS TAPE
.OTSST,,[1,,KSST] ;OPR COMMAND - SET STRUCTURE
.OTSWI,,[1,,KSWI] ;OPR COMMAND - SWITCH
.OTUNL,,[1,,KUNL] ;OPR COMMAND - UNLOAD
QDTABL==.-QDTAB
; REQRSB - TRANSLATE REQUEST NUMBER INTO RSB ADDRESS
; T1/ REQUEST NUMBER
; RETURNS +1: UNKNOWN REQUEST #, T1/ REQUEST #
; +2: SUCCESS, RSB/ RSB ADDR, T1/ REQUEST #
REQRSB: QSCANI ARBQDB ;SET UP TO SCAN RSB QUEUE
SAVET ;PRESERVE T1 AS ADVERTISED
REQR1: CALL QMSCAN ;GET NEXT RSB
RET ;NONE LEFT, REQUEST # UNKNOWN
MOVEI RSB,-RSBLNK(T2) ;LOAD RSB AC WITH ADDRESS OF RSB
MOVE T1,CT1 ;GET REQ# FROM RSB
CAME T1,RSBITN(RSB) ;DOES IT MATCH WHAT THE CALLER GAVE?
JRST REQR1 ;NO, CONTINUE SCAN
RETSKP ;YES, SUCCESS
; RLSMSG - SEND RELEASE MESSAGE TO QUASAR
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: ALWAYS
RLSMSG: MOVE T1,RSBITN(RSB) ;GET ITN
MOVEM T1,TBUF+REL.IT ;STORE IN MESSAGE
MOVE T1,[REL.SZ,,.QOMTR] ;GET GALAXY HEADER
SETZB T2,T3
CALL GALHDR ;BUILD HEADER
MOVEI T1,.APQSR
CALLRET TRANG ;SEND RELEASE MESSAGE TO QUASAR
; TCAN - PROCESS USER TAPE REQUEST CANCEL MESSAGE FROM QUASAR
; RBUF/ IPCF TAPE MOUNT CANCEL MESSAGE
; T1/ SIZE OF MESSAGE (WORDS)
; RETURNS +1: ALWAYS
TCAN: SAVEQ
MOVE T3,T1 ;COPY SIZE OF MESSAGE
SUBI T3,.OHDRS ;GET SIZE OF BLOCK REGION OF MESSAGE
JUMPLE T3,TCANQE ;NO BLOCK REGION, ERROR BY QUASAR
MOVE T1,RBUF+.OARGC ;GET # OF BLOCKS
MOVEI T2,RBUF+.OHDRS ;GET ADDRESS OF 1ST BLOCK
CALL CKBSTR ;CHECK BLOCK STRUCTURE
TCANQE: JRST [ CALLRET BADQM] ;BAD STRUCTURE, QUASAR GOOFED
DMOVE T1,[EXP RBUF+.OARGC,RBUF+.OHDRS]
MOVEI T3,.MTPID ;GET TYPE OF BLOCK BEING SOUGHT
CALL BLKFND ;LOOK UP USER'S PID
JRST TCANQE ;PID BLOCK NOT THERE
JUMPE T2,TCANQE ;MAKE SURE THERE'S ROOM FOR A PID
MOVE Q2,(T1) ;GET PID SO I CAN REPLY TO THE USER
DMOVE T1,[EXP RBUF+.OARGC,RBUF+.OHDRS]
MOVEI T3,.MTITN ;GET BLOCK TYPE
CALL BLKFND ;LOOK UP ITN LIST
JRST TCANQE ;NOT THERE
SETZ Q1, ;CLEAR COUNTER OF CANCELED REQUESTS
JUMPE T2,TCAN2 ;NO SCAN IF NOTHING TO CANCEL
MOVN Q3,T2 ;GET NEGATIVE NUMBER OF ITN'S
MOVSS Q3 ;OVER TO LEFT HALF FOR AOBJN
HRR Q3,T1 ;MAKE AOBJN POINTER TO ITN LIST
; LOOP THROUGH ITN LIST, TRYING TO CANCEL EACH ONE
TCAN1: MOVE T1,(Q3) ;GET AN ITN
CALL TCITN ;TRY TO CANCEL IT
SKIPA ;CAN'T CANCEL
AOS Q1 ;COUNT CANCELED REQUEST
AOBJN Q3,TCAN1 ;LOOP
; ..
; ..
; BUILD TEXT REPLY TO CANCEL MESSAGE IN TMCMSG
TCAN2: JUMPG Q1,[TMCT <%I%5D> ;AT LEAST 1 REQUEST CANCELED
JRST TCAN3]
TMCT <%INo> ;NO REQUESTS CANCELED
TCAN3: TMCT < mount request>
SOJN Q1,[TMCT <s> ;IF NOT 1 REQUEST, TACK ON AN "S"
JRST .+1]
TMCT < canceled>
; BUILD IPCF MESSAGE AND SEND IT TO THE CANCELER
MOVE T1,Q2 ;GET USER'S PID
SETZ T2, ;NO FLAGS
MOVE T3,RBUF+.MSCOD ;GET CANCELER'S ACK CODE
CALLRET TXTMSG ;RESPOND TO CANCEL WITH GLX TEXT MESSAGE
; TCKP - SEND A STATUS UPDATE FOR A MOUNT REQUEST TO QUASAR
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: ALWAYS
TCKP: SAVEQ
SAVEAC <MT,MTA>
MOVE T1,RSBITN(RSB)
MOVEM T1,TBUF+CHE.IT ;STORE ITN IN MESSAGE
SETZM TBUF+CHE.FL ;SET NO SPECIAL FLAGS
MOVEI Q1,TBUF+CHE.IN ;GET ADDR OF START OF CKPT INFO AREA
LOAD Q2,RSBTYP ;GET REQUEST TYPE
MOVEM Q2,.MTTYP(Q1) ;STORE IT
CAIE Q2,.MNTTP ;TAPE REQUEST?
CAIN Q2,.MNTDT ; OR DECTAPE REQUEST?
SKIPA ;YES
JRST TCKP0 ;NO, SKIP VOLID STUFF
CALL VQGCV ;GET VOLID OF CURRENT VOLUME IN T1
SKIPN T1 ;SCRATCH?
MOVEI T1,%VOLSC ;YES, GET 1 TO DISPLAY "Scratch"
LOAD T2,RSBSTE ;GET CURRENT STATE OF REQUEST
CAIGE T2,.ERBAS ;ABORTED OR
CAIN T2,RST.WV ; WAITING FOR VOLID LIST?
MOVEI T1,%VOLBL ;YES, DON'T DISPLAY ANYTHING
MOVEM T1,.MTVOL(Q1) ;STORE VOLID
TCKP0:
CAIN T2,RST.AC ;REQUEST HAVE MTA OR DTA?
JRST [ MOVE T1,RSBDTA(RSB) ;YES, ASSUME DECTAPE
CAIN Q2,.MNTDT ;DECTAPE?
JRST TCKP1 ;YES, T1/ DECTAPE DEVICE DESIGNATOR
LOAD MT,RSBMT ;MAGTAPE REQUEST
LOAD MTA,MTMTA ;LOAD MTA AC
CALL GMTADD ;GET MTA DESIGNATOR IN T1
JRST TCKP1] ;GO STORE IT
MOVEI T1,%STAWT ;ASSUME WAITING FOR SOMETHING
CAIL T2,.ERBAS ;ABORTED?
MOVEI T1,%STAAB ;YES, SAY SO THEN
TCKP1: MOVEM T1,.MTSTA(Q1) ;STORE STATE FIELD OF MESSAGE
MOVE T1,[CHE.IN+EQCKSZ,,.QOMTC] ;GET SIZE AND MESSAGE TYPE
SETZB T2,T3 ;NO FLAGS OR ACK CODE
CALL GALHDR ;BUILD GALAXY HEADER
MOVEI 1,.APQSR
CALLRET TRANG ;SEND CHECKPOINT MESSAGE TO QUASAR
; TXTMSG - SEND GALAXY IPCF TEXT-MESSAGE
; T1/ RECEIVER'S PID
; T2/ FLAGS FOR GALAXY MESSAGE HEADER
; T3/ ACK CODE FOR MESSAGE HEADER
; TMCMSG/ ASCIZ MESSAGE TO BE SENT
; RETURNS +1: ALWAYS
TXTMSG: STAKT
AOS TBUF+.OARGC ;SET ARGUMENT COUNT TO 1
MOVE T1,TMCWDS ;GET LENGTH OF MESSAGE (WORDS)
MOVSI T2,1(T1) ;CONSTRUCT
HRRI T2,.CMTXT ; ARGUMENT HEADER WORD
MOVEM T2,TBUF+.OHDRS ;STORE ARG HEADER
MOVE T2,[TMCMSG,,TBUF+.OHDRS+1] ;GET BLT SOURCE,,DESTINATION
BLT T2,TBUF+.OHDRS(T1) ;COPY TEXT INTO IPCF MESSAGE
MOVSI T1,.OHDRS+1(T1) ;GET SIZE OF ENTIRE MESSAGE
HRRI T1,MT.TXT ;BUILD SIZE,,TYPE
MOVE T2,CT2 ;GET FLAGS
MOVE T3,CT3 ;GET ACK CODE
CALL GALHDR ;BUILD GALAXY HEADER FOR MESSAGE
MOVE T1,CT1 ;GET RECEIVER'S PID
CALLRET TRANU ;TRANSMIT MESSAGE AND RETURN
SUBTTL STRUCTURE ROUTINES
;BSRALI - GET STRUCTURE ALIAS FROM QUASAR MSSG INTO RSB
;ACCEPTS: T1/ ADDRESS OF SUBENTRY COUNT WORD
; T2/ ADDRESS OF FIRST SUBENTRY
; RSB/ ADDR OF REQUEST STATUS BLOCK
;RETURNS: +1, FAILURE
; +2, SUCCESS
BSRALI: MOVEI T3,.SMALI ;GET STRUCTURE ALIAS CODE
CALL BLKFND ;LOOKUP ALIAS
JRST [ ABTRET(MREQ22)] ;ERROR, CAN'T MOUNT STR IF NO ALIAS
JUMPE T2,[ABTRET(MREQ22)] ;TREAT ZERO-LENGTH NAME LIKE NO NAME
MOVE T1,(T1) ;GET ALIAS IN T1
MOVEM T1,RSBSTA(RSB) ;STORE ALIAS IN RSB
RETSKP
;BSRNAM - GET STRUCTURE NAME FROM QUASAR MSSG INTO RSB
;ACCEPTS: T1/ ADDRESS OF SUBENTRY COUNT WORD
; T2/ ADDRESS OF FIRST SUBENTRY
; RSB/ ADDR OF REQUEST STATUS BLOCK
;RETURNS: +1, FAILURE
; +2, SUCCESS
BSRNAM: MOVEI T3,.SMNAM ;GET STRUCTURE NAME CODE
CALL BLKFND ;LOOKUP NAME
JRST BSRNA1 ;NAME NOT GIVEN
JUMPE T2,BSRNA1 ;TREAT ZERO-LENGTH NAME AS NO NAME
MOVE T1,(T1) ;GET NAME IN T1
CAME T1,RSBSTA(RSB) ;IS NAME SAME AS ALIAS
JRST [ MOVX T2,R%PRIV ;NO, IS USER PRIVILEGED?
TDNE T2,RSBIFL(RSB)
JRST .+1 ;YES, LET IT GO
ABTRET (CAPX1)] ;NOT PRIVLEGED, ABORT REQUEST
SKIPA
BSRNA1: SETZ T1, ;STORE ZERO IF NO NAME MENTIONED
MOVEM T1,RSBSTN(RSB) ;STORE NAME IN REQUEST BLOCK
RETSKP
;THIS SECTION HANDLES COMMANDS, WHICH ARE READ FROM A SPECIAL FILE
;HERE'S THE "COMNDS" ROUTINE. ANY PLACE THAT A DECISION MUST BE MADE
;WHICH DEPENDS ON COMMANDS THAT MIGHT BE IN THE COMMAND FILE, MUST CALL
;THIS ROUTINE BEFORE MAKING THE DECISION.
;(REMEMBER, SOMEONE MIGHT UPDATE THE COMMANDS FILE WHILE IS RUNNING)
COMNDS: SAVEQ
MOVX T1,GJ%OLD+GJ%SHT+GJ%ACC
HRROI T2,COMNAM ;GET POINTER TO COMMANDS FILE NAME
GTJFN ;GET HANDLE ON COMMANDS FILE
RET ;COULD NOT GET FILE
MOVE T2,[70000,,OF%RD] ;BITS FOR OPENING FILE FOR READ
MOVE T4,T1 ;COPY JFN IN CASE OF FAILURE
OPENF ;OPEN COMMANDS FILE FOR READING
JRST [ MOVE T1,T4 ;GET JFN BACK
RLJFN ;DUMP IT
JFCL
JRST COMEO2] ;TYPE REASON AND GIVE UP
MOVEM T1,COMJFN ;REMEMBER NEW HANDLE ON COMMANDS FILE
GTAD ;GET CURRENT TIME AND DATE
MOVE T4,T1 ;T4 CONTAINS A NUMBER GUARANTEED DIFFERENT FROM FILE WRITE DATE
MOVE T1,COMJFN ;GET HANDLE ON COMMANDS FILE
MOVEI T2,T4 ;WE'LL READ TIME INTO T4
MOVEI T3,1 ;ONLY ONE DATUM REQUESTED
RFTAD ;GET LAST WRITE-TIME FOR COMMANDS FILE
CAMN T4,STAMP ;DIFFERENT THAN LAST TIME WE CHECKED?
JRST COMEO1 ;NO, SO COMMANDS ARE UP TO DATE
;...
;THERE'S A NEW COMMANDS FILE, SO CLEAR OLD COMMANDS STATUS AND READ
;NEW COMMANDS IN.
MOVEM T4,STAMP ;REMEMBER NEW UPDATE STAMP
SETZM STRTBL+1 ;ZERO FIRST ENTRY OF STRUCTURE TABLE
MOVE T1,[STRTBL+1,,STRTBL+2] ; TO CLEAR STRUCTURE TABLE FOR NEW
BLT T1,STRTBL+STSIZ-1 ; COMMANDS FILE
MOVE T1,STRINI ;INITIALIZE STRTBL
MOVEM T1,STRTBL
MOVE T1,SSCINI ;INITIALIZE SSCTBL FOR TBADD, ALSO
MOVEM T1,SSCNAM
COMND1: CALL CREADI ;INITIALIZE FOR COMND JSYS
MOVEI T1,COMTBL ;GET POINTER TO COMMANDS
MOVEM T1,FDB+.CMDAT
MOVX T1,CMKEY ;SPECIFY "KEYWORD"
HRRI T1,[FLDDB.(.CMKEY,,COMDEF)] ;CHECK IF SETTING UP DEFAULTS
CALL CREAD ;DO COMND JSYS
HRRZ T2,(T2) ;GET ADDRESS OF COMMAND'S SUPPORT ROUTINE
SKIPE T2 ;SETTING DEFAULTS?
JRST SETSTR ;NO, SET UP STR CHARACTERISTICS
JRST SETDEF ;YES
;ROUTINE TO DO COMND JSYS. IT RETURNS IFF A SUCCESFUL PARSE HAPPENS.
;CALL IT WITH THE VALUE FOR THE FIRST WORD OF THE FUNCTION BLOCK IN A.
CREAD: MOVEM T1,FDB
MOVEI T1,CSB
MOVEI T2,FDB ;COMMAND STATE BLOCK AND FUNCTION BLOCK
COMND ;READ COMMAND NAME
ERJMP COMEOF ;ERROR, HOPEFULLY END OF FILE
TXNE T1,CM%NOP ;DID IT PARSE CORRECTLY?
JRST COMBAD ;NO, GIVE WARNING AND CONTINUE
RET ;SUCCESFUL COMND JSYS, RETURN
;ROUTINE TO INITIALIZE POINTERS ETC. FOR COMND JSYS
CREADI: SETZM FDB+.CMFNP
SETZM FDB+.CMDAT
SETZM FDB+.CMHLP
SETZM FDB+.CMDEF ;CLEAR FUNCTION DESCRIPTOR BLOCK
MOVX T1,CM%RAI ;RAISE INPUT
MOVEM T1,CSB+.CMFLG ;SET UP REPARSE ADDRESS
HRL T1,COMJFN ;INPUT FROM COMMAND FILE JFN
HRRI T1,377777 ;NO EDITING OUTPUT
MOVEM T1,CSB+.CMIOJ
HRROI T1,TMCMSG ;POINTER TO USER'S (FILE'S) INPUT
MOVEM T1,CSB+.CMRTY ;CONTROL-R BUFFER IS REGULAR INPUT BUFFER
MOVEM T1,CSB+.CMBFP
MOVEM T1,CSB+.CMPTR ;POINTER TO NEXT FIELD TO BE PARSED
MOVEI T1,5000 ;GET LENGTH OF INPUT BUFFER
MOVEM T1,CSB+.CMCNT
SETZM CSB+.CMINC ;NO UNPARSED CHARACTERS YET
HRROI T1,ATMBFR ;POINTER TO ATOM BUFFER
MOVEM T1,CSB+.CMABP
MOVEI T1,ATMSIZ*5 ;LENGTH OF ATOM BUFFER
MOVEM T1,CSB+.CMABC
SETZM CSB+.CMGJB ;NO GTJFN BLOCK
RET
; DDSADD - ADD A DISK COMING ON-LINE
;ACCEPTS: DSK/ NUMBER OF DISK
;RETURNS: +1, ALWAYS
DDSADD: CALL STRINF ; YES, STORE STRUCTURE INFORMATION
LOAD T1,STRUNI,(STR) ;GET NUMBER OF DISKS IN STR
LOAD T2,STRMCT,(STR) ;GET NUMBER OF DISKS MOUNTED IN STR
CAME T1,T2 ;ARE ALL DISK PACKS MOUNTED?
RET ;NO, RETURN
;TRY TO MATCH STRUCTURE COMING ON-LINE TO USER REQUEST
QSCANI ARBQDB ;SET UP TO SCAN ACTIVE RSB QUEUE
SAVEAC <RSB,DSK>
CALL PRQPID ;CLEAN UP REQUEST QUEUE FIRST
MOVE Q2,DSKFLG(DSK) ;GET DISK STATUS
TXNE Q2,MS%MNT ;IS IT MOUNTED ALREADY?
JRST [ CALLRET DDSMC0] ;YES, CHECK MOUNT QUEUES
DDSAD1: CALL NSTRSB ;GET ADDRESS OF NEXT RSB
RET ;NONE LEFT
LOAD T1,RSBSTE ;GET STATE OF REQUEST
CAIE T1,RST.WM ;IS USER WAITING FOR STRUCTURE
JRST DDSAD1 ;NO, TRY NEXT REQUEST
SKIPN T1,RSBSTN(RSB) ;GET STRUCTURE NAME IN REQUEST
MOVE T1,RSBSTA(RSB) ;THERE IS NONE, GET ALIAS FOR NAME
CAME T1,STRNAM(STR) ;IS IT SAME AS STRUCTURE COMING ON-LINE
JRST DDSAD1 ;NO, TRY NEXT REQUEST
CALL STRMNT ;MOUNT THE STRUCTURE
RET ;ERROR IN MOUNTING STRUCTURE
SETZ T1, ;CHECK MOUNT REQUESTS
CALLRET DDSMCH ;STRUCTURE IS NOW READY FOR USERS. TELL THEM
; DDSMCH - MATCH USER REQUEST TO MOUNTS AND DISMOUNTS
;ACCEPTS: T1/ 0=LOOK AT MOUNT REQUESTS
; R%DSM=LOOK AT DISMOUNT REQUESTS
; QSB/ ADDRESS OF QUEUE SCAN BLOCK
; STR/ ADDRESS OF STRUCTURE BLOCK
;RETURNS: +1, ALWAYS
DDSMC0: SAVEQ ;ALTERNATE ENTRY FOR MOUNT REQUESTS
SETZ Q1,
JRST DDSMC1
DDSMCH: SAVEQ
MOVE Q1,T1
JUMPE Q1,DDSMC2 ;GO TO DDSMC2 FOR MOUNT REQUESTS
DDSMC1: CALL NSTRSB ;GET NEXT USER REQUEST
RET ;NONE LEFT
LOAD T1,RSBSTE ;GET STATE OF REQUEST
CAIE T1,RST.WM ;IS USER WAITING FOR STRUCTURE
JRST DDSMC1 ;NO, TRY NEXT REQUEST
MOVE T1,RSBSTA(RSB) ;GET STRUCTURE ALIAS
CAME T1,STRALI(STR) ;IS IT SAME AS THIS ONE
JRST DDSMC1 ;NO, TRY NEXT REQUEST
SKIPN T1,RSBSTN(RSB) ;GET STRUCTURE NAME
JRST DDSMC2 ;NONE SPECIFIED. ALLOW THIS MOUNT
CAME T1,STRNAM(STR) ;IS THIS THE SAME AS CURRENT STR
JRST DDSMC1 ;NO, GET NEXT REQUEST
DDSMC2: MOVE T1,RSBIFL(RSB) ;GET INTERNAL FLAGS
XOR T1,Q1 ;ARE WE LOOKING AT RIGHT REQUEST TYPE
TXNE T1,R%DSM
JRST DDSMC1 ;NO
MOVX T1,R%OPR
TDNN T1,RSBIFL(RSB) ;DID OPERATOR REQUEST THIS?
CALL TELUSR ;NO, LET USER KNOW HE HAS STRUCTURE
ABTREQ (ABRTNR) ;ABORT RSB WITH NO REPLY TO USER
JRST DDSMC1
;DDSCIH - ENTERED BY SCHEDULER WHEN PSI INTERRUPT RECEIVED
; INDICATING THAT A DISK STATUS CHANGE HAS OCCURRED
;ACCEPTS: NOTHING
;RETURNS: +1, ALWAYS
DDSCIH: SAVEQ
MOVSI DSK,-MAXDSK ;GET MAX NUMBER OF DISKS
HRRI DSK,DSKSTB ;GET STARTING POINT OF DISK BLOCKS
CALL DSTINI ;GET STATUS OF FIRST DISK
JFCL ;CAN'T HAVE SYSTEM WITH NO DISKS
JRST DDSLO1
DDSLOP: CALL DSTNXT ;GET STATUS OF NEXT DISK
JRST [SKIPN DSKFLG(DSK) ;IS THERE A DISK HERE?
RET ;NO, FINISHED
CALL DDSDEL ;YES, DELETE STRUCTURE INFORMATION
SETZM (DSK) ;CLEAR DISK BLOCK
MOVEI T1,1(DSK)
HRL T1,DSK
BLT T1,DSKSZ-1(DSK)
JRST DDSNXT] ;SEE IF ANY MORE
DDSLO1: LOAD T1,DSKCHN,(DSK) ;GET DISK CHANNEL
LOAD T2,DSKDRV,(DSK) ;GET DISK DRIVE
CAMN T1,MSTRBK+.MSRCH ;ARE DISK CHANNELS THE SAME?
CAME T2,MSTRBK+.MSRUN ;YES, ARE DRIVE UNITS THE SAME?
JRST [ CALL REARNG ;NO, REARRANGE DISK BLOCKS
JRST DDSNXT]
MOVE Q2,MSTRBK+.MSRST ;GET STATUS OF UNIT
MOVE Q1,Q2
MOVE Q3,DSKFLG(DSK) ;GET OLD STATUS
XOR Q1,Q3 ;GET CHANGED BITS
MOVEM Q2,DSKFLG(DSK) ;STORE NEW STATUS
TXNN Q1,MS%OFL!MS%MNT!MS%WLK ;CHANGE IN MOUNT, OFF-LINE
; OR WRITE-LOCK?
JRST [ TXNE Q2,MS%OFL ;NO, IS PACK ON-LINE
JRST DDSNXT ;NO
MOVE T1,[POINT 7,MSTNM] ;YES, CHECK IF SAME PACK
MOVEI T2,Q3
CALL SEVSIX ;CONVERT NAME TO SIXBIT
CAMN Q3,DSKSTN(DSK) ;HAS PACK BEEN CHANGED
JRST DDSNXT ;NO, GET NEXT ONE
CALL DDSDEL ;DELETE CURRENT STRUCTURE INFORMATION
CALL DDSADD ;GET NEW STRUCTURE INFORMATION
JRST DDSNXT]
TXNE Q2,MS%OFL ;IS DISK ON-LINE
JRST [ CALL DDSDEL ;NO, DELETE STRUCTURE INFORMATION
JRST DDSNXT]
TXNN Q1,MS%OFL ;DID STRUCTURE JUST COME ON-LINE
TXNE Q2,MS%MNT ;NO, IS STRUCTURE NOW MOUNTED?
JRST [ CALL DDSADD ;YES, ADD STR
JRST DDSNXT]
TXNE Q1,MS%WLK ;WAS DRIVE UNLOCKED
JRST [ CALL DDSADD ;YES, ADD STR
JRST DDSNXT]
SETZM DSKSTA(DSK) ;ZERO OUT DISK ALIAS
LOAD STR,DSKSSA,(DSK) ;GET STRUCTURE BLOCK ADDRESS
JUMPE STR,DDSNXT ;RETURN IF NOT PART OF MOUNTED STR
SETZM STRALI(STR) ;ZERO STRUCTURE ALIAS
MOVE T1,[MS%MT] ;TURN OFF FLAG SAYING STR IS MOUNTED
ANDCAM T1,STRFLG(STR)
DDSNXT: ADDI DSK,DSKSZ-1 ;GET NEXT DISK STATUS BLOCK
AOBJN DSK,DDSLOP ;IF STILL MORE DISKS, GO PROCESS
RET
;DDSDEL - DELETE STRUCTURE INFORMATION ABOUT A DISK
;ACCEPTS: DSK/ DISK NUMBER
;RETURNS: +1, ALWAYS
DDSDEL: LOAD STR,DSKSSA,(DSK) ;GET STRUCTURE BLOCK ADDRESS
JUMPE STR,R ;RETURN IF NOT PART OF A STRUCTURE
LOAD T1,STRMCT,(STR) ;GET NUMBER OF DISKS MOUNTED IN STR
SOJN T1,DDSDE1 ;JUMP IF THERE IS MORE THAN 1 DISK
QSCANI ARBQDB ;SET UP TO SCAN ACTIVE RSB QUEUE
SAVEAC <RSB,DSK>
CALL PRQPID ;CLEAN UP REQUEST QUEUE FIRST
MOVX T1,R%DSM ;CHECK DISMOUNT QUEUES
CALL DDSMCH ;MATCH AND FINISH ACTIVE RSB'S
SETZM STRALI(STR) ;ZERO OUT THIS STR STATUS BLOCK
MOVEI T1,STRNAM(STR)
HRLI T1,STRALI(STR)
BLT T1,STRALI+STRSZ-1(STR)
JRST DDSDE2 ;CONTINUE CLEARING STRUCTURE INFO
DDSDE1: STOR T1,STRMCT,(STR) ;STORE NUMBER OF DISKS MOUNTED IN STR
LOAD T1,DSKLUN,(DSK) ;GET DISK LOGICAL NUMBER
ADD T1,STR ;GET DISK ADDRESS INDEX
SETZM STRADD(T1) ; AND ZERO IT OUT
DDSDE2: SETZM DSKSTN(DSK) ;ZERO STRUCTURE NAME
SETZM DSKSTA(DSK) ;ZERO STRUCTURE ALIAS
RET
;DDSERR - RECOVER FROM AN ERROR WHEN TRYING TO MOUNT A STRUCTURE
DDSERR: MOVEI T1,MSTNM
TMCT <%IProblem with structure %1A: %J%_%U>
MOVEI T3,[ASCIZ/MOUNT PROBLEM/]
CALLRET BTWTO ;SEND MESSAGE TO OPERATOR
;DSFMGT - GET DEVICE-STATUS FILE ENTRY FOR SPECIFIED DRIVE
;ACCEPTS Q2: CHANNEL,,DRIVE
;RETURNS +1, ALWAYS, DSFE/ ENTRY FOR SPECIFIED DRIVE
DSFMGT: SAVET
MOVEI T1,.DVDSK ;GET DISK DESIGNATOR
MOVEM T1,DSFE
MOVEM Q2,DSFE+1 ;STORE CHANNEL,,DRIVE
CALL DSFLOC ;LOOK UP THIS DRIVE
JRST [ MOVX T1,MTS%AV ;NOT ON FILE YET
MOVEM T1,DSFE+MTS.SF ;SET UP DEFAULT ENTRY IN DSFE
CALLRET DSFPUT] ;ADD DRIVE TO FILE AND RETURN
MOVSS T1 ;FOUND IT. GET BLT SOURCE
HRRI T1,DSFE ;BLT DESTINATION
BLT T1,DSFE+DSFESZ-1 ;TRANSFER ENTRY TO DSFE
RET ;FOUND IT. RETURN
;DSKINI - SET UP DISK DRIVE AND STRUCTURE STATUS TABLES
;ACCEPTS: NOTHING
;RETURNS: +1, ALWAYS
DSKINI: MOVEI T1,1 ;SET UP IGNORED STRUCTURES TABLE
MOVEM T1,IGNTBL
MOVEI T1,33 ;GET INTERRUPT CHANNEL FOR DISK
MOVEM T1,MSTRBK+.MSCHN ; STATUS CHANGE
MOVE T1,[1,,.MSOFL] ;TELL MONITOR TO INTERRUPT US IF
MOVEI T2,MSTRBK ; THERE IS DISK CHANGE
SKIPN TSTF ;DON'T DO MSTR IF TESTING
MSTR
MOVSI DSK,-MAXDSK ;GET MAX NUMBER OF DISKS
HRRI DSK,DSKSTB ;GET STARTING POINT OF DISK BLOCKS
CALL DSTINI ;GET STATUS OF FIRST DISK
JFCL ;CAN'T HAVE SYSTEM WITH NO DISKS
JRST DSKLO1
;GET STATUS OF ALL DISKS ON SYSTEM
DSKLOP: CALL DSTNXT ;GET STATUS OF NEXT DISK
RET ;END OF DISKS
DSKLO1: MOVE T1,MSTRBK+.MSRCT ;GET CONTROLLER NUMBER
STOR T1,DSKCTR,(DSK) ;AND STORE IN DSK STATUS BLOCK
MOVE T1,MSTRBK+.MSRUN ;GET DRIVE NUMBER
STOR T1,DSKDRV,(DSK) ; AND STORE
MOVE T1,MSTRBK+.MSRCH ;GET CHANNEL NUMBER
STOR T1,DSKCHN,(DSK) ;AND STORE
MOVE Q2,MSTRBK+.MSRST ;GET STATUS OF UNIT
MOVEM Q2,DSKFLG(DSK)
TXNE Q2,MS%OFL ;IS DISK OFF-LINE
JRST DSKNXT ;YES, NO NEED TO CHECK FOR NAMES
CALL STRINF ;STORE STRUCTURE INFORMATION
;GET NEXT DRIVE
DSKNXT: ADDI DSK,DSKSZ-1 ;GET NEXT DISK STATUS BLOCK
AOBJN DSK,DSKLOP ;IF STILL MORE DISKS, GO PROCESS
RET ;FINISHED WITH DISKS
;DSTGIV - GET STATUS FOR GIVEN DISK UNIT
;ACCEPTS: DSK/ ADDRESS OF DISK STATUS BLOCK
;RETURNS: +1 ERROR, INVALID UNIT
; +2 SUCCESS, STATUS IN MSTRBK BLOCK
DSTGIV: LOAD T1,DSKCTR,(DSK) ;GET CONTROLLER NUMBER
LOAD T2,DSKCHN,(DSK) ;GET CHANNEL NUMBER
LOAD T3,DSKDRV,(DSK) ;GET UNIT NUMBER
CAIN T1,777777 ;IS CONTROLLER -1?
TLO T1,777777 ;YES, MAKE IT A FULL WORD
MOVEM T1,MSTRBK+.MSRCT
MOVEM T2,MSTRBK+.MSRCH
MOVEM T3,MSTRBK+.MSRUN ;STORE VALUES FOR MSTR JSYS
MOVE T1,[.MSRST+1,,.MSRUS] ;RETURN STATUS OF THE GIVEN UNIT
MOVEI T2,MSTRBK ;GIVE ADDRESS OF ARGUMENT BLOCK
MSTR
ERJMP R ;FAILURE RETURN
RETSKP
;DSTINI - GET STATUS OF FIRST DISK ON SYSTEM
;ACCEPTS: NOTHING
;RETURNS: +1, FAILURE
; +2, SUCCESS, STATUS RETURNED IN MSTRBK BLOCK
DSTINI: SETOM MSTRBK ;SET UP MSTR TO LOOK AT FIRST CHANNEL
SETOM MSTRBK+1 ; FOR FIRST CONTROLLER
SETOM MSTRBK+2 ; FOR FIRST DISK
;DSTNXT - GET STATUS OF THE NEXT DISK
;ACCEPTS: MSTRBK BLOCK FOR MSTR JSYS
;RETURNS: +1, FAILURE
; +2, SUCCESS, STATUS RETURNED IN MSTRBK BLOCK
DSTNXT: MOVE T1,[POINT 7,MSTNM] ;GET POINTER TO STRUCTURE NAME
MOVEM T1,MSTRBK+.MSRSN ; AND STORE IN MSTR ARGUMENT BLOCK
MOVE T1,[POINT 7,MSTAL] ;DO SAME FOR STRUCTURE ALIAS
MOVEM T1,MSTRBK+.MSRSA
MOVE T1,[7,,.MSRNU] ;SET UP CALL TO MONITOR TO GET STATUS
MOVEI T2,MSTRBK ;PUT STATUS IN MSTR BLOCK
MSTR ;GET STATUS
ERJMP R ;END OF DISKS
RETSKP
;KSDK - PROCESS SET DISK-DRIVE COMMAND FROM OPR
;RETURNS +1, ALWAYS
KSDK: SAVEQ
SAVEAC <DSK>
MOVEI T1,.DSKDV
CALL ORNBLF ;DISK DRIVE SPECIFIED?
JRST KBADM ;NO
MOVE Q2,1(T1) ;GET DRIVE NUMBER
HRL Q2,(T1) ;GET CHANNEL NUMBER
CALL DDSCIH ;MAKE SURE TABLES UP-TO-DATE
MOVSI DSK,-MAXDSK ;GET MAX NUMBER OF DISKS
HRRI DSK,DSKSTB ;GET STARTING POINT OF DISK BLOCKS
KSDK1: CAMN Q2,DSKNUM(DSK) ;IS THIS THE DISK WE'RE SETTING
JRST KSDK2 ;YES, CONTINUE
ADDI DSK,DSKSZ-1 ;GET NEXT DISK STATUS BLOCK
AOBJN DSK,KSDK1 ;IF STILL MORE DISKS, CONTINUE CHECK
JRST [ HLRZ T1,Q2 ;UNKNOWN DISK. GET CHANNEL
HRRZ T2,Q2 ;GET DRIVE
TMCT <%ICommand Ignored. Unknown Chan %1D Drive %2D>
MOVEI T3,TMCMSG
CALLRET BTACK] ;TELL OPERATOR NO SUCH DRIVE
KSDK2: SETZ Q1, ;ASSUME SETTING UNAVAILABLE
MOVEI T1,.DVUAV
CALL ORNBLF ;CHECK IF SETTING UNAVAILABLE
JRST [ MOVEI T1,.DVAVL ;NO
CALL ORNBLF ;SETTING AVAILABLE?
JRST KBADM ;NO
AOJA Q1,KSDKA] ;SETTING AVAILABLE
;SETTING DRIVE UNAVAILABLE
MOVEI T1,.ORREA
CALL ORNBLF ;REASON BLOCK PRESENT
JRST KBADM ;NO
MOVE Q3,T1 ;COPY ADDRESS OF REASON TEXT
CALL DSFMGT ;GET DEVICE-STATUS FILE ENTRY
MOVX T1,MTS%AV ;GET AVAILABLE-STATUS BIT
TDNN T1,DSFE+MTS.SF ;DRIVE AVAILABLE?
KSDK3: JRST [ MOVE T1,[[ASCIZ/Unavailable/]
[ASCIZ/Available/]](Q1) ;GET TEXT POINTER
HLRZ T2,Q2 ;GET CHANNEL
HRRZ T3,Q2 ;GET DRIVE
TMCT <%IChan %2D Drive %3D Is Already Set %1A>
MOVEI T3,TMCMSG
CALLRET BTACK] ;TELL OPRTR COMMAND HAS NO EFFECT
MOVEI T1,CS%DDV ;GET CODE FOR DETACH-DEVICE
MOVE T2,Q3 ;GET ADDRESS OF ASCIZ REASON
CALL SYMSET ;LOG SYSERR ENTRY FOR DRIVE SET UNAVAIL
SETZ T1, ;SET UNAVAILABLE
STOR T1,MTS%AV,DSFE+MTS.SF ;STORE FLAG
CALL DSFPUT ;PUT ENTRY BACK IN FILE
CALLRET WOMDAV ;TELL ALL OPERATORS WHAT HAPPENED
;SETTING DRIVE AVAILABLE
KSDKA: CALL DSFMGT ;GET DEVICE-STATUS FILE ENTRY
MOVX T1,MTS%AV ;GET AVAILABLE-STATUS BIT
TDNN T1,DSFE+MTS.SF ;DRIVE AVAILABLE?
SKIPA ;NO,
JRST KSDK3 ;ALREADY SET AVAILABLE
MOVEI T1,1 ;SET AVAILABLE
STOR T1,MTS%AV,DSFE+MTS.SF ;STORE FLAG
CALL DSFPUT ;PUT ENTRY BACK IN FILE
MOVEI T1,CS%ADV ;GET CODE FOR ATTACH-DEVICE
SETZ T2, ;NO REASON
CALL SYMSET ;LOG SYSERR ENTRY FOR DRIVE AVAILABLE
CALLRET WOMDAV ;TELL OPERATORS IT'S BACK
;KDSM - PROCESS DISMOUNT STRUCTURE COMMAND FROM OPR
;RETURNS +1, ALWAYS
KDSM: SAVEAC <STR>
CALL DDSCIH ;MAKE SURE TABLES UP-TO-DATE
MOVEI T1,.DSMST ;GET RSB TYPE
CALL OPRSB ;SET UP RSB FOR THIS OPR REQUEST
RET ;NO RSB AVAILABLE, MESSAGE SENT
SETZM RSBSTN(RSB) ;ZERO STRUCTURE NAME FOR MATCHS
MOVEI T1,RST.WM
STOR T1,RSBSTE ;SET STATE TO WAITING FOR DISMOUNT
MOVE T1,RSBSTA(RSB) ;GET STRUCTURE ALIAS
MOVE T2,RSBSTN(RSB) ;GET STRUCTURE NAME
CALL MATCHS ;MATCH REQUEST TO STRUCTURE
JRST [ABTRET (ABRTNR)] ;STRUCTURE NOT MOUNTED. NOTHING TO DO.
STOR STR,RSBSS ;STORE THE STRUCTURE ADDR INTO RSB
SKIPL STR ;IS STRUCTURE MOUNTED?
JRST [ MOVEI T1,RSBSTA(RSB) ;YES, DISMOUNT IT
MOVE T2,[POINT 7,MSTAL]
CALL SIXSEV
CALLRET STRDMT]
CALLRET WOVDS ;ASK OPERATOR TO REMOVE
;KMSS - PROCESS MOUNT STRUCTURE COMMAND FROM OPR
;RETURNS: +1, ALWAYS
KMSS: CALL DDSCIH ;MAKE SURE TABLES UP-TO-DATE
MOVEI T1,.MNTST ;GET REQUEST TYPE
CALL OPRSB ;BUILD REQUEST BLOCK FOR OPERATOR
RET ;NO RSB AVAILABLE, MESSAGE SENT
MOVE T1,RSBSTA(RSB) ;GET STRUCTURE ALIAS
MOVE T2,RSBSTN(RSB) ;GET STRUCTURE NAME
CALL MATCHS ;MATCH REQUEST TO STRUCTURE
JRST KMS2 ;STRUCTURE NOT MOUNTED, YET
JUMPLE STR,[LOAD T1,STRUNI,(STR) ;GET # OF DISKS IN STR
LOAD T2,STRMCT,(STR) ;GET # OF DISKS ON-LINE IN STR
CAME T1,T2 ;ARE THEY ALL ON-LINE
JRST KMS2 ;NO, ASK OPERATOR
CALL STRMNT ;SPINNING BUT NOT MOUNTED
JRST KMS2 ;PROBLEMS IN MOUNTING. ASK OPERATOR
JRST .+1]
ABTRET (ABRTNR) ;DISCARD REQUEST
KMS2: MOVEI T1,RST.WM
STOR T1,RSBSTE ;SET STATE TO WAITING FOR MOUNT
CALLRET WOVMS ;TELL OPERATOR TO MOUNT STRUCTURE
;KSHD - SHOW DISK STATUS COMMAND FROM OPR
;RETURN: +1, ALWAYS
KSHD: SAVEQ
TMCT <%I>
CALL DDSCIH ;MAKE SURE TABLES UP-TO-DATE
MOVE Q1,RBUF+.OFLAG ;GET COMMAND TYPE
CAMN Q1,[ST.MNT] ;IS IT ASKING FOR MOUNTED DISKS?
JRST KSHD2 ;YES, SHOW THEM
MOVEI T1,SFHDR ;GET HEADER FOR FREE DRIVES
TMCT <%1A>
MOVSI DSK,-MAXDSK ;GET MAX NUMBER OF DISKS
HRRI DSK,DSKSTB ;GET STARTING POINT OF DISK BLOCKS
KSHD1: SKIPE T1,DSKFLG(DSK) ;GET DISK STATUS
JRST [ TXNN T1,MS%MNT ;IS IT MOUNTED?
CALL WOFRE ;NO, DISPLAY THIS UNIT'S STATUS
JRST .+1]
ADDI DSK,DSKSZ-1 ;GET NEXT DISK STATUS BLOCK
AOBJN DSK,KSHD1 ;IF STILL MORE DISKS, GO PROCESS
CAMN Q1,[ST.AVA] ;WERE WE ASKED ONLY FOR FREE DRIVES?
JRST KSHD4 ;YES, FINISH DISPLAY
KSHD2: MOVEI T1,SMHDR ;GET HEADER FOR MOUNTED DRIVES
TMCT <%1A>
MOVSI DSK,-MAXDSK ;GET MAX NUMBER OF DISKS
HRRI DSK,DSKSTB ;GET STARTING POINT OF DISK BLOCKS
KSHD3: MOVE T1,DSKFLG(DSK) ;GET DISK STATUS
TXNE T1,MS%MNT ;IS IT MOUNTED?
CALL WOMNT ;YES, DISPLAY THIS UNIT'S STATUS
ADDI DSK,DSKSZ-1 ;GET NEXT DISK STATUS BLOCK
AOBJN DSK,KSHD3 ;IF STILL MORE DISKS, GO PROCESS
KSHD4: MOVEI T3,[ASCIZ/Disk Drive Status/]
CALL BTNFO ;ASK FOR NO FORMATTING
CALLRET BTACKT ;END OF DISKS, SEND STATUS TO OPR
;KSST - PROCESS SET STRUCTURE COMMAND FROM OPR
;ACCEPTS: MRPDB, RBUF/ PDB AND MESSAGE FROM OPR
; +1, ALWAYS
KSST: MOVEI T1,.STRDV ;GET BLOCK TYPE CODE
CALL KGTSTR ;GET STRUCTURE NAME
JRST KBADM ;NOT THERE, REJECT MESSAGE
DMOVEM T2,MSTAL ;STORE ASCII STRUCTURE NAME
MOVEI T1,.STCHR
CALL ORNBLF ;WAS A CHARACTERISTIC SPECIFIED?
JRST KBADM ;NO, REJECT MESSAGE
MOVE Q3,(T1) ;GET CHARACTERISTIC
SKIPL Q3 ;IS IT WITHIN RANGE?
CAIL Q3,S.UREG+1
JRST KBADM ;NO, REJECT MESSAGE
CAIE Q3,S.ACKN ;WAS CHARACTERISTIC ACKNOWLEDGED?
CAIN Q3,S.IGNO ; OR IGNORED?
JRST KSS1 ;YES
HRLZI Q2,-CHRTL ;FORM INDEX INTO CHRTBL
CAME Q3,CHRTBL(Q2) ;IS THIS THE CHARACTERISTIC
AOBJN Q2,.-1 ;NO, TRY AGAIN
HRLZ T2,CHRACT(Q2) ;GET VALUE OF MASKED BIT
MOVEM T2,MSTRBK+.MSSST
HLLZ T2,CHRACT(Q2) ;GET BIT TO CHANGE
MOVEM T2,MSTRBK+.MSSMW
MOVE T1,[POINT 7,MSTAL] ;GET POINTER TO ALIAS
MOVEM T1,MSTRBK+.MSSSN
MOVE T1,[3,,.MSSSS] ;SET UP TO CHANGE STATUS
MOVEI T2,MSTRBK
MSTR
ERJMP KSSERR ;SOMETHING WENT WRONG
HRRZ T1,CHRACT(Q2) ;GET STATUS SETTING
SKIPE T1 ;IS STATUS BEING SET TO ZERO?
TLOA T1,STRFLG(STR) ;NO, SET IT TO ONE
JRST [ HLRZ T1,CHRACT(Q2) ;YES, GET BIT BEING CHANGED
TLZ T1,STRFLG(STR) ;SET IT
JRST .+1]
MOVEM T1,STRFLG(STR)
MOVE T1,CHRSTG(Q2) ;SET STATUS CHANGED
CALLRET WOSSC ;TELL OPERATOR
;UPDATE STRUCTURE IGNORED TABLE
KSS1: MOVE T1,[POINT 7,MSTAL]
MOVEI T2,Q1 ;STORE SIXBIT ALIAS IN Q1
CALL SEVSIX ;CONVERT ALIAS
MOVE T1,IGNTBL ;GET INDEX AND # OF ENTRIES
JUMPG T1,KSS2 ;JUMP IF NO NAMES STORED YET
CAME Q1,IGNTBL(T1) ;IS THIS THE STRUCTURE
AOBJN T1,.-1 ;CHECK NEXT ENTRY
SKIPL T1 ;WAS STRUCTURE FOUND?
JRST KSS2 ;NO
CAIE Q3,S.ACKN ;IS STR BEING SET ACKNOWLEDGED?
JRST [ MOVE T1,CHRSTG+4 ;NO, TELL OPERATOR STRUCTURE IS
CALLRET WOSSC] ; SET IGNORED
MOVEI T2,IGNTBL(T1) ;SET UP TO MOVE IGNORED ENTRIES UP
MOVE T3,T2
HRLI T2,1(T2)
HLRO T4,T1 ;GET # OF ENTRIES TO MOVE
MOVNS T4 ;MAKE POSITIVE
BLT T2,IGNTBL(T4) ;MOVE ENTRIES
HLRO T1,IGNTBL ;GET # OF ENTRIES
AOS T1 ;DECREMENT IT
HRLM T1,IGNTBL
MOVE T1,CHRSTG ;TELL OPERATOR STRUCTURE IS
CALLRET WOSSC ; ACKNOWLEDGED
KSS2: CAIE Q3,S.IGNO ;IS IT BEING SET IGNORED?
JRST [ MOVE T1,CHRSTG ;NO, TELL OPERATOR STRUCTURE IS
CALLRET WOSSC] ; SET ACKNOWLEDGED
MOVEM Q1,IGNTBL(T1) ;STORE NEW NAME
HLRZ T1,IGNTBL ;GET # OF ENTRIES IN TABLE
SOS T1
CAILE T1,-IGNLEN ;IS THERE ROOM FOR ANOTHER?
JRST KSS3 ;NO, ISSUE ERROR
HRLM T1,IGNTBL
MOVE T1,CHRSTG+4 ;TELL OPERATOR STRUCTURE IS SET
CALLRET WOSSC ; IGNORED
KSS3: RET
;POSSIBLE CHARACTERISTICS TO BE CHANGED
CHRTBL: S.ACKN
S.AVAL
S.DOMS
S.FORN
S.IGNO
S.REGU
S.UAVL
S.UREG
CHRTL==.-CHRTBL
;BIT SETTINGS FOR STRUCTURE CHARACTERISTICS
CHRACT: MS%DIS ;ACKNOWLEDGED
MS%DIS ;AVAILABLE
MS%DOM+100000 ;DOMESTIC
MS%DOM ;FOREIGN
MS%DIS+200000 ;IGNORED
MS%NRS ;REGULATED
MS%DIS+200000 ;UNAVAILABLE
MS%NRS+004000 ;UNREGULATED
;ASCIZ STRINGS FOR STATUS
CHRSTG: -1,,[ASCIZ/ACKNOWLEDGED/]
-1,,[ASCIZ/AVAILABLE/]
-1,,[ASCIZ/DOMESTIC/]
-1,,[ASCIZ/FOREIGN/]
-1,,[ASCIZ/IGNORED/]
-1,,[ASCIZ/REGULATED/]
-1,,[ASCIZ/UNAVAILABLE/]
-1,,[ASCIZ/UNREGULATED/]
KSSERR: MOVEI T1,MSTAL
TMCT <%IProblem with structure %1A: %J>
MOVEI T3,[ASCIZ/STRUCTURE STATUS NOT SET/]
CALLRET BTACKT ;SEND MSSG TO OPERATOR
;MATCHS - MATCH REQUEST TO STRUCTURE
;ACCEPTS: T1 SIXBIT STRUCTURE ALIAS
; T2 SIXBIT STRUCTURE NAME
;RETURNS: +1, STRUCTURE NOT FOUND
; STR/ FIRST FREE STRUCTURE BLOCK
; +2, STRUCTURE SPINNING, BUT NOT MOUNTED
; STR/ -1,,CURRENT STRUCTURE BLOCK ADDRESS
; +2, STRUCTURE MOUNTED
; STR/ 0,,CURRENT STRUCTURE BLOCK ADDRESS
MATCHS: SAVEQ
MOVSI STR,-MAXDSK ;GET MAX NUMBER OF DISKS
HRRI STR,STRSTB ;GET STARTING POINT OF STR BLOCKS
SETZ T3, ;SET FLAG FOR NO FREE BLOCK FOUND YET
;FIND STRUCTURE BLOCK, OR IF NOT FOUND, FIRST FREE BLOCK
MAT1: SKIPN STRNAM(STR) ;IS THIS BLOCK FREE?
JRST [ JUMPN T3,MAT4 ;YES, JUMP IF ALREADY HAVE BLOCK
MOVEI T3,(STR) ;SAVE BLOCK ADDRESS
JRST MAT4]
MOVE T4,STRFLG(STR) ;IS THIS STRUCTURE MOUNTED?
TDNN T4,[MS%MT]
JRST MAT3 ;NO
MOVE T4,STRALI(STR) ;GET STRUCTURE ALIAS
;STRUCTURE BLOCK CONTAINS MOUNTED STRUCTURE
CAME T1,T4 ;IS THIS THE ONE WE'RE LOOKING FOR
JRST MAT4 ;NO, GET NEXT STRUCTURE
JUMPE T2,MAT2 ;WAS ONLY AN ALIAS SPECIFIED?
CAME T2,STRNAM(STR) ;NO, IS THIS THE RIGHT STRUCTURE NAME
JRST MAT4 ;NO, CONTINUE LOOKING
MAT2: HRRZS STR ;ZERO COUNT
RETSKP
;STRUCTURE BLOCK CONTAINS SPINNING, BUT NOT MOUNTED STRUCTURE
MAT3: JUMPL T3,MAT4 ;JUMP IF STR NAME ALREADY FOUND
SKIPN T4,T2 ;SKIP IF STR NAME GIVEN
MOVE T4,T1 ;NOT GIVEN, USE ALIAS INSTEAD
CAME T4,STRNAM(STR) ;IS THIS THE RIGHT STRUCTURE
JRST MAT4 ;NO, CONTINUE LOOKING
SETO T3, ;YES, RECORD IT
HRRI T3,(STR)
; ...
; ...
;INCREMENT STRUCTURE BLOCK INDEX FOR NEXT DISK UNIT
MAT4: ADDI STR,STRSZ-1 ;GET NEXT STRUCTURE STATUS BLOCK
AOBJN STR,MAT1 ;CHECK NEXT STRUCTURE
MOVE STR,T3 ;GET BLOCK ADDRESS
SKIPL T3 ;IS STRUCTURE SPINNING?
RET ;NO, IT WASN'T FOUND
RETSKP ;STR SPINNING, BUT NOT MOUNTED
;MESCHK - CHECK IF MESSAGE FOR STRUCTURE ALREADY SENT TO OPERATOR
;ACCEPTS: RSB/ ADDRESS OF RSB
;RETURNS: +1, OPERATOR ALREADY NOTIFIED OF STRUCTURE
; +2, OPERATOR NOT NOTIFIED
MESCHK: SAVEQ
MOVE Q1,RSBSTN(RSB) ;GET STRUCTURE NAME
MOVE Q2,RSBSTA(RSB) ;GET STRUCTURE ALIAS
MOVE Q3,RSB ;SAVE ADDRESS OF RSB
QSCANI ARBQDB ;SET UP TO SCAN ACTIVE RSB QUEUE
SAVEAC <RSB>
CALL PRQPID ;CLEAN UP REQUEST QUEUE FIRST
MESCH1: CALL NSTRSB ;GET ADDRESS OF NEXT RSB
RETSKP ;NONE LEFT
CAMN Q3,RSB ;IS THIS THE CURRENT RSB?
JRST MESCH1 ;YES, FORGET IT
CAMN Q1,RSBSTN(RSB) ;SAME STRUCTURE NAME?
CAME Q2,RSBSTA(RSB) ;YES, SAME ALIAS?
JRST MESCH1 ;NO, TRY NEXT RSB
RET ;SAME NAME AND ALIAS
;MNTALL - MOUNT ALL STRUCTURES NOT ALREADY MOUNTED
;ACCEPTS: NOTHING
;RETURNS: +1, ALWAYS
MNTALL: CALL GORSB ;MUST GET RSB SINCE MOUNT CODE
; WAS WRITTEN AROUND RSB LOGIC
JFCL ;RSB'S IN SHORT SUPPLY
MOVEI STR,STRSTB ;GET START OF STRUCTURE TABLES
HRLI STR,-MAXDSK ;MAXIMUM OF 16 STRUCTURES
MNTAL1: SKIPE T1,STRNAM(STR) ;IS A STRUCTURE IN THIS BLOCK?
CAMN T1,[SIXBIT 'PS'] ;YES, IS IT PS?
JRST MNTNXT ;YES, DON'T TRY THIS ONE
MOVE T1,STRFLG(STR) ;IS THIS STRUCTURE MOUNTED?
TDNE T1,[MS%MT]
JRST MNTNXT ;YES, GET NEXT ONE
LOAD T1,STRUNI,(STR) ;GET NUMBER OF DISKS IN STRUCTURE
LOAD T2,STRMCT,(STR) ;GET NUMBER OF DISKS ON-LINE
CAME T1,T2 ;ARE ALL DISKS ON-LINE?
JRST MNTNXT ;NO, GET NEXT ONE
MOVE T1,STRNAM(STR) ;GET STRUCTURE NAME
MOVEM T1,RSBSTA(RSB) ;ALIAS OF STRUCTURE WILL BE PHYSICAL NAME
CALL STRMNT ;MOUNT THE STRUCTURE
JFCL ;LET OPERATOR HANDLE THIS
MNTNXT: ADDI STR,STRSZ-1 ;GET NEXT STRUCTURE STATUS BLOCK
AOBJN STR,MNTAL1 ;JUMP IF THERE ARE MORE
ABTRET (ABRTNR) ;GET RID OF RSB AND RETURN
;OPRSB - SET UP REQUEST BLOCK FOR OPR MOUNT OR DISMOUNT COMMAND
;ACCEPTS: T1/ REQUEST TYPE (.MNTST OR .DSMST)
; MRPDB, RBUF/ PDB AND MESSAGE FROM OPR IPCF REQUEST
;RETURNS: +1, FAILURE
; +2, SUCCESS, RSB/ ADDR OF REQUEST STATUS BLOCK
OPRSB: CALL GORSB ;GET A STATUS BLOCK FOR REQUEST
RET ;NO RSB'S AVAILABLE, TAKE ERROR RETURN
MOVEI T1,.STRDV ;GET BLOCK TYPE
CALL KGTSTR ;GET STRUCTURE NAME
JRST [ ABTREQ (ABRTNR) ;NOT THERE, RELEASE RSB
JRST KBADM] ;REJECT MESSAGE
MOVEM T1,RSBSTN(RSB) ;STORE SIXBIT STRUCTURE NAME IN RSB
MOVEM T1,RSBSTA(RSB) ;DEFAULT ALIAS TO STRUCTURE NAME
MOVEI T1,.STALS
CALL KGTSTR ;WAS AN ALIAS SPECIFIED?
SKIPA ;NO
MOVEM T1,RSBSTA(RSB) ;YES, STORE IT IN RSB
MOVE T1,MRPDB+.IPCFS ;GET PID OF SENDER
MOVEM T1,RSBPID(RSB) ;STORE IN RSB
MOVEM T1,MSTRBK+1
MOVEI T1,.MUFOJ ;GET SENDER'S JOB NUMBER
MOVEM T1,MSTRBK
MOVEI T1,3 ;3 WORDS IN ARGUMENT BLOCK
MOVEI T2,MSTRBK ; WHICH IS MSTRBK
MUTIL
JRST [ ABTRET (ABRTNR)] ;SOMETHING HAPPENED TO REQUESTER
MOVE T1,MSTRBK+2 ;GET JOB NUMBER
STOR T1,RSBJNO
MOVE T2,[-1,,T4] ;GET USER NUMBER
MOVEI T3,.JIUNO
GETJI
JRST [ ABTRET (ABRTNR)] ;SOMETHING HAPPENED TO REQUESTER
MOVEM T4,RSBUNO(RSB) ;STORE USER NUMBER
RETSKP
;PSDR - PARSE OPERATOR RESPONSE TO DISMOUNT MESSAGE WHEN OTHER JOBS
; USING STRUCTURE
;ACCEPTS: T1/ ADDRESS OF ASCIZ RESPONSE TEXT
; RSB/ ADDRESS OF REQUEST STATUS BLOCK
;RETURNS: +1, ERROR DETECTED WHILE PARSING RESPONSE, OPERATOR TOLD
; +2, SUCCESSFUL PARSE
; IF ANSWER IS YES, T1/ 0
; IF ANSWER IS NO, T1/ -1
PSDR: CALL COMNDI ;INITIALIZE FOR COMND JSYS
MOVEI T2,[FLDDB.(.CMKEY,,PSDKT)] ;SETUP FOR KEYWORD PARSE
CALL COMNDX ;PARSE KEYWORD
JRST [ MOVEI T1,[ASCIZ/Response must be YES or NO/]
CALLRET RSPERR] ;DIDN'T SAY YES OR NO, GIVE ERROR
HRRZ T1,(T2) ;GET 0 FOR NO, 1 FOR YES
SOJA T1,RSKP ;RETURN -1 FOR NO, 0 FOR YES
PSDKT: PSDKTL,,PSDKTL
[ASCIZ/NO/],,0
[ASCIZ/YES/],,1
PSDKTL==.-PSDKT-1
;REAADD - ADD NEW UNIT FROM REARNG ROUTINE
;ACCEPTS: DSK/ ADDRESS OF DISK STATUS BLOCK
; MSTRBK/ MSTR JSYS UNIT INFORMATION
;RETURNS: +1, ALWAYS
REAADD: SETZM (DSK) ;ZERO NEW DISK BLOCK
MOVEI T1,1(DSK) ;GET DESTINATION ADDRESS
HRL T1,DSK ;GET SOURCE ADDRESS
BLT T1,DSKSZ-1(DSK)
MOVE T3,MSTRBK+.MSRCT ;GET CONTROLLER NUMBER
STOR T3,DSKCTR,(DSK) ; AND STORE IN DISK STATUS BLOCK
MOVE T3,MSTRBK+.MSRUN ;GET DRIVE NUMBER
STOR T3,DSKDRV,(DSK) ; AND STORE
MOVE T3,MSTRBK+.MSRCH ;GET CHANNEL NUMBER
STOR T3,DSKCHN,(DSK) ; AND STORE
MOVE Q2,MSTRBK+.MSRST ;GET STATUS OF UNIT
STOR Q2,DSKFLG(DSK) ; AND STORE
CALL DDSADD
RET
;READDR - READDRESS THE STRUCTURE BLOCKS AFTER TRANSFERRING THEM
;ACCEPTS: T3/ ADDRESS OF FIRST DISK BLOCK TO CHANGE
;RETURNS: +1, ALWAYS
READDR: LOAD T4,DSKSZ,(T3) ;GET STRUCTURE ADDRESS
JUMPE T4,[RET] ;FINISHED
LOAD T1,DSKLUN,(T3) ;GET LOGICAL UNIT NUMBER
ADD T4,T1 ;GET ADDRESS OF UNIT WITH STR BLOCK
MOVEM T3,STRADD(T4) ;STORE NEW DISK BLOCK ADDRESS
ADDI T3,DSKSZ ;GET NEXT DISK
JRST READDR
;REAFND - FIND FIRST EMPTY DISK STATUS BLOCK
;ACCEPTS: T3/ ADDRESS OF FIRST DISK BLOCK TO CHECK
;RETURNS: +1, ALWAYS WITH T3/ ADDRESS OF FIRST EMPTY BLOCK
REAFND: MOVE T4,DSKFLG(T3) ;GET DISK INFO
JUMPE T4,[RET] ;JUMP IF FINISHED
ADDI T3,DSKSZ ;GET NEXT DISK BLOCK
JRST REAFND
;REARNG - REARRANGE DISK BLOCKS IF CONFIGURATION CHANGES
;ACCEPTS: T1/ DISK CHANNEL
; T2/ DISK DRIVE
; DSK/ BLOCK ADDRESS
;RETURNS: +1, ALWAYS
REARNG: SKIPN DSKFLG(DSK) ;IS THERE A DISK BLOCK HERE?
JRST REARN5 ;NO, ADD IT
CAML T1,MSTRBK+.MSRCH ;DID WE LOSE A CHANNEL?
JRST REARN3 ;NO, JUMP
CALL DDSDEL ;DELETE STRUCTURE INFO ON THIS DISK
MOVEI T3,DSKSZ(DSK) ;GET ADDRESS OF NEXT STATUS BLOCK
REARN1: LOAD T4,DSKCHN,(T3) ;GET DISK CHANNEL
CAME T4,T1 ;ARE THEY THE SAME
JRST REARN2 ;NO, CONTINUE ON
MOVE Q1,DSK ;SAVE DISK BLOCK ADDRESS
MOVE DSK,T3 ;GET NEXT BLOCK
CALL DDSDEL ;DELETE STRUCTURE INFO ON THIS DISK
ADDI T3,DSKSZ ;GET NEXT BLOCK
MOVE DSK,Q1 ;RESTORE DSK
JRST REARN1 ;CHECK NEXT ONE
REARN2: CALL REAFND ;FIND END OF DISK BLOCKS
MOVE T4,DSK ;GET DESTINATION ADDRESS
HRLI T4,DSKSZ(DSK) ;GET SOURCE ADDRESS
BLT T4,-1(T3) ;TRANSFER BLOCK
MOVE T3,DSK ;GET BEGINNING AGAIN
CALL READDR ;GET NEW DISK ADDRS IN STR BLOCKS
RET
REARN3: CAME T1,MSTRBK+.MSRCH ;DID WE ADD A CHANNEL?
JRST REARN5 ;YES, JUMP
CAML T2,MSTRBK+.MSRUN ;ARE WE REMOVING A DRIVE?
JRST REARN4 ;NO, CONTINUE ON
CALL DDSDEL ;DELETE STRUCTURE INFO ON THIS DISK
MOVEI T3,DSKSZ(DSK) ;GET ADDRESS OF NEXT STATUS BLOCK
CALL REAFND ;FIND FIRST EMPTY BLOCK
MOVE T4,DSK ;GET DESTINATION ADDRESS
HRLI T4,DSKSZ(DSK) ;GET SOURCE ADDRESS
BLT T4,-1(T3) ;TRANSFER BLOCK
MOVE T3,DSK ;GET BEGINNING AGAIN
CALL READDR ;GET NEW DISK ADDRESS IN STR BLOCKS
RET
REARN4: CAMG T2,MSTRBK+.MSRUN ;DID WE ADD A DRIVE
RET ;NO, NOTHING TO DO
REARN5: MOVE T3,DSK
CALL REAFND ;FIND END OF DISK BLOCKS
MOVEI T4,DSKSZ(DSK) ;GET DESTINATION ADDRESS
HRL T4,DSK ;GET SOURCE ADDRESS
BLT T4,DSKSZ-1(T3) ;TRANSFER BLOCKS
MOVEI T3,DSKSZ(DSK) ;GET FIRST CHANGED BLOCK
CALL READDR ;READDRESS DISK BLOCKS IN STR BLOCKS
CALL REAADD ;ADD NEW DISK UNIT
RET
;SET UP DEFAULT STATUS FOR STRUCTURES TO MOUNT
SETDEF: SETZ T4, ;INITIALIZE STATUS
SETDE1: MOVX T1,CMKEY ;SPECIFY 'KEYWORD'
HRRI T1,[FLDDB.(.CMCFM)] ;ALSO, LOOK FOR CONFIRMATION
CALL CREAD ;READ NEXT FIELD
MOVE T2,(T2) ;GET DATA FOR FUNCTION
CAME T2,FDB ;IS IT END OF LINE?
JRST [ HRRZS T2 ;NO
XCT (T2) ;SET STATUS
JRST SETDE1] ;GET NEXT FIELD
MOVEM T4,SSCDEF ;STORE DEFAULT STRUCTURE STATUS CHANGE
JRST COMND1 ;GET NEXT COMMAND
;SET UP STRUCTURE STATUS CHANGES FOR MOUNT REQUESTS
SETSTR: SETZ T4, ;INITIALIZE STR STATUS
SETST1: HRRZS T2 ;CLEAR TRASH OUT OF LEFT HALF
XCT (T2) ;SET BIT FOR STR STATUS
HRROI T1,[ASCIZ /STRUCTURE/] ;GUIDE WORD STRING
MOVEM T1,FDB+.CMDAT
MOVX T1,CMNOI ;ALLOW 'NOISE' FUNCTION
CALL CREAD
MOVEI T1,COMTBL
MOVEM T1,FDB+.CMDAT ;CHECK FOR KEYWORD AGAIN
MOVX T1,CMKEY
HRRI T1,[FLDBK.(.CMFLD,,,,,<[BRMSK.(KEYB0.,KEYB1.,KEYB2.,KEYB3.,<:>)]>)]
;CHECK FOR STRUCTURE NAME & COLON, ALSO
CALL CREAD
MOVE T2,(T2) ;GET DATA PORTION OF FUNCTION
CAME T2,FDB ;IS THIS THE STRUCTURE FIELD?
JRST SETST1 ;NO, ANOTHER STATUS CHANGE
MOVE T2,SSCNAM ;GET ADDRESS TO STORE NAME
AOS T2 ;INCREMENT LOCATION TO USE
CAIL T2,SSCNAM+STSIZ ;HAVE WE RUN OUT OF STRUCTURE NAME SPACE
JRST NOSRUM ;YES, ERROR
MOVSS T4 ;SET STATUS CHANGES IN RIGHT HALF
HRL T4,T2 ;MOVE ADDRESS OF STRING FOR TBADD JSYS
MOVEM T4,Q1 ;SAVE ENTRY INFO FOR TBADD
MOVE T1,[POINT 7,ATMBFR] ;GET POINTER TO STRUCTURE NAME
MOVEI T4,6 ;MAX OF 6 CHARACTERS IN A STRUCTURE
HRLI T2,(POINT 7) ;MAKE BYTE POINTER TO STORE NAME
SETST2: ILDB T3,T1 ;GET CHARACTER
JUMPE T3,SETST3 ;FINISHED IF ZERO
CAIN T3,":" ;WAS THERE A COLON ON STRUCTURE NAME
JRST SETST3 ;YES, FINISHED WITH NAME
IDPB T3,T2 ;STORE CHARACTER
SOJG T4,SETST2 ;JUMP IF MORE CHARACTERS
SETST3: CAIN T4,1 ;IS AN EXTRA WORD OF ZEROS NEEDED.
AOS T2 ;YES, FOR ASCIZ STRING
HRRZM T2,SSCNAM ;STORE NEXT ADDRESS TO USE
MOVX T1,CMCFM ;GET COMMAND CONFIRMATION
CALL CREAD ;ASSURE GOOD CONFIRMATION
MOVEI T1,STRTBL ;GET ADDRESS OF STR STATUS CHANGE TABLE
MOVE T2,Q1 ;GET ENTRY NAME
TBADD ;ADD ENTRY
ERJMP TABFAL ;COULDN'T, GO SEE WHY
JRST COMND1 ;GO READ NEXT COMMAND
;SEVSIX - ROUTINE TO CONVERT 7-BIT ASCII TO 6-BIT
;ACCEPTS: T1 POINTER TO ASCIZ STRING
; T2 ADDRESS OF WORD IN WHICH TO STORE 6-BIT STRING
;RETURNS: +1, ALWAYS
SEVSIX: HRLI T2,(POINT 6,0) ;SET UP SIXBIT POINTER
SETZM (T2) ;CLEAR THE DESTINATION WORD
MOVEI T4,6 ;MAXIMUM OF 6 CHARACTERS
;LOOP OVER CHARACTERS
SEVLOP: ILDB T3,T1 ;GET 7-BIT CHARACTER
JUMPE T3,R ;RETURN IF END OF STRING
CAIL T3,"a" ;IS IT LOWER CASE?
TRZ T3,40 ;MAKE SURE IT IS UPPER CASE
SUBI T3,40 ;CONVERT TO 6-BIT
IDPB T3,T2 ;STORE CHARACTER
SOJG T4,SEVLOP ;JUMP IF MORE CHARACTERS
RET
;SIXSEV - ROUTINE TO CONVERT SIXBIT TO ASCIZ
;ACCEPTS: T1 ADDRESS OF WORD CONTAINING SIXBIT CHARACTERS
; T2 POINTER TO WORDS FOR STORING ASCIZ STRING (2 WORDS)
;RETURNS: +1, ALWAYS
SIXSEV: HRLI T1,(POINT 6) ;SET UP BYTE POINTER FOR SIXBIT WORD
MOVEI T4,6 ;MAXIMUM OF 6 CHARACTERS
;LOOP OVER CHARACTERS
SIXLOP: ILDB T3,T1 ;GET CHARACTER
JUMPE T3,SIXEND ;IF ZERO, THEN END OF STRING
ADDI T3,40 ;MAKE 7-BIT
IDPB T3,T2 ;STORE WORD
SOJG T4,SIXLOP ;JUMP IF MORE CHARACTERS
SIXEND: ADDI T4,4 ;ZERO OUT REST OF WORD(S)
SETZ T3,
IDPB T3,T2 ;DEPOSIT ZERO
SOJG T4,.-1 ;JUMP BACK IF MORE CHARACTERS
RET
;STRDMT - DISMOUNT A STRUCTURE
;ACCEPTS: RSB/ ADDR OF REQUEST STATUS BLOCK
; MSTAL/ ASCIZ ALIAS OF STRUCTURE
;RETURNS: +1, ALWAYS
STRDMT: MOVE T1,[POINT 7,MSTAL] ;GET POINTER TO STRUCTURE ALIAS
MOVEM T1,MSTRBK+.MSSSN
MOVX T1,MS%DIS
MOVEM T1,MSTRBK+.MSSST ;CHANGE ONLY THE BIT TO SAY THE STR
MOVEM T1,MSTRBK+.MSSMW ; IS BEING DISMOUNTED
MOVE T1,[3,,.MSSSS] ;CHANGING STRUCTURE STATUS
MOVEI T2,MSTRBK
MSTR
ERJMP [CALL GETERR ;ERROR, GET CODE
MOVEM T1,LSTERR ;PUT IN A SAFE PLACE
ABTRET (LSTERR,ABT%IN)] ;RETURN MSTR ERROR TO USER
MOVE T1,[POINT 7,MSTAL] ;NOW SET UP TO SEE IF THERE IS ANY USER
MOVEM T1,MSTRBK+.MSGSN
MOVE T1,[5,,.MSGSS]
MSTR
MOVE T1,MSTRBK+.MSGST ;GET STRUCTURE STATUS
TXNE T1,MS%PPS ;IS THIS THE PRIMARY PUBLIC STR?
JRST [ ABTRET (MSTX24)] ;YES, CAN'T DO THIS
SKIPN MSTRBK+.MSGMC ;IS ANYONE CONNECTED TO THIS STR
SKIPE MSTRBK+.MSGFC ;NO, ARE ANY FILES OPEN?
SKIPA ;YES
JRST STRDM2 ;NO ONE CONNECTED & NO FILES OPEN
STRDM5: MOVEI T1,STRDM1 ;GET END-ACTION ADDRESS
CALLRET WRDSC ;ASK OPERATOR IF OK TO PROCESS REQUEST
STRDM1: MOVEI RSB,-RSBWTB(T2) ;LOAD RSB AC
LOAD STR,RSBSS ;GET STRUCTURE STATUS BLOCK AGAIN
CALL PSDR ;PARSE OPERATOR RESPONSE
JRST STRDM5 ;BAD RESPONSE, TRY IT AGAIN
JUMPN T1,STRDM3 ;OPERATOR REFUSED REQUEST
MOVEI T1,RSBSTA(RSB) ;GET ALIAS AGAIN
MOVE T2,[POINT 7,MSTAL]
CALL SIXSEV ;CONVERT TO ASCIZ
;STRUCTURE HAS NO USERS OR OPERATOR HAS OK'ED DISMOUNT
STRDM2: MOVE T1,[POINT 7,MSTAL] ;GET POINTER TO ALIAS OF STR
MOVEM T1,MSTRBK+.MSDNM
MOVE T1,[1,,.MSDIS] ;DISMOUNT STRUCTURE
MOVEI T2,MSTRBK
MSTR
ERJMP STDERR
MOVEI T1,STRNAM(STR) ;GET SIXBIT STRUCTURE NAME AND
MOVE T2,[POINT 7,MSTNM] ; AND CONVERT TO ASCIZ
CALL SIXSEV
CALL WOSDM ;TELL OPERATOR OF DISMOUNT
MOVE T1,[MS%MT] ;TURN OFF FLAG SAYING STR IS MOUNTED
TDZ T1,STRFLG(STR)
MOVEM T1,STRFLG(STR)
CALLRET WOVDS ;TELL OPERATOR TO REMOVE STRUCTURE
;OPERATOR HAS REFUSED TO DISMOUNT STRUCTURE
STRDM3: MOVEI T1,RSBSTA(RSB) ;GET STRUCTURE ALIAS
MOVE T2,[POINT 7,MSTAL]
CALL SIXSEV ;CONVERT TO ASCIZ
MOVE T1,[POINT 7,MSTAL] ;GET POINTER TO ALIAS
MOVEM T1,MSTRBK+.MSSSN
MOVX T1,MS%DIS ;RESET STATUS OF STRUCTURE TO SAY
MOVEM T1,MSTRBK+.MSSMW ; IT IS NOT BEING DISMOUNTED
SETZM T1,MSTRBK+.MSSST
MOVE T1,[3,,.MSSSS]
MOVEI T2,MSTRBK
MSTR ;CHANGE STATUS
ERCAL STDERR ;STRUCTURE DISAPPEARED?
ABTRET (MREQ23,ABT%OP) ;OPERATOR REFUSED TO DISMOUNT STRUCTURE
;STDERR - RECOVER FROM AN ERROR WHEN TRYING TO DISMOUNT A STRUCTURE
STDERR: MOVEI T1,MSTNM
TMCT <%IProblem with structure %1A: %J%_%U>
MOVEI T3,[ASCIZ/DISMOUNT PROBLEM/]
CALLRET BTWTO ;SEND MESSAGE TO OPERATOR
;STRGSB - GET STRUCTURE STATUS BLOCK (BUILD ONE IF NECESSARY)
;ACCEPTS: T1 LOGICAL UNIT # OF CURRENT DISK,,# OF UNITS IN STRUCTURE
; T2 SIXBIT STRUCTURE ALIAS
; T3 SIXBIT STRUCTURE NAME
; DSK DISK STATUS BLOCK ADDRESS
;RETURNS: +1, ALWAYS
; STR/ CURRENT STRUCTURE BLOCK ADDRESS
STRGSB: STAKT
DMOVE T1,T2
CALL MATCHS ;DOES THIS STRUCTURE EXIST?
SKIPA ;NO
JRST STRFND ;YES, DON'T NEED TO BUILD NEW BLOCK
;DID NOT FIND STRUCTURE. BUILD NEW BLOCK
STRGS1: DMOVE T2,CT2 ;RESTORE STR NAME AND ALIAS
MOVEM T3,STRNAM(STR) ;SAVE STR NAME
MOVEM T2,STRALI(STR) ;SAVE STR ALIAS
HRRZ T3,CT1 ;GET NUMBER OF UNITS
STOR T3,STRUNI,(STR) ;AND STORE
;STORE DISK STATUS BLOCK ADDRESS
STRFND: HLRZ T3,CT1 ;GET UNIT NUMBER
ADD T3,STR ;GET OFFSET TO
HRRZM DSK,STRADD(T3) ; SAVE DISK STATUS BLOCK ADDRESS
SETZ T4, ;LOOP THRU TO GET # OF PACKS
MOVEI T3,STRADD(STR) ;GET START OF PACK LIST
HRLI T3,-10 ;WILL HAVE 8 AT MOST
SKIPE (T3) ;IS THIS A PACK
AOS T4 ;YES, COUNT IT
AOBJN T3,.-2 ;LOOK FOR ALL OF THEM
STOR T4,STRMCT,(STR) ; AND STORE
RET
;STRINF - STORE STRUCTURE INFORMATION FOR A DISK
;ACCEPTS: Q2/ STATUS OF UNIT
; DSK/ DISK NUMBER
; MSTRBK/ BLOCK FROM MSTR CALL
;RETURNS: NOTHING
STRINF: MOVE T1,[POINT 7,MSTNM] ;GET POINTER TO STRUCTURE NAME
MOVEI T2,DSKSTN(DSK) ;GET WORD IN WHICH TO STORE NAME
CALL SEVSIX ; CONVERT FROM 7-BIT TO 6-BIT
TXNN Q2,MS%MNT ;DOES DRIVE HAVE MOUNTED STRUCTURE
JRST STRIN1 ;NO, STORE REST OF INFORMATION
MOVE T1,[POINT 7,MSTAL] ;GET POINTER TO ALIAS NAME
MOVEI T2,DSKSTA(DSK) ;GET WORD IN WHICH TO STORE ALIAS
CALL SEVSIX ;CONVERT FROM 7-BIT TO 6-BIT
STRIN1: MOVE T1,MSTRBK+.MSRNS ;GET LOGICAL UNIT,,NUMBER OF UNITS
MOVEM T1,DSKNS(DSK) ; AND STORE
MOVE T2,DSKSTA(DSK) ;GET STRUCTURE ALIAS IN SIXBIT
MOVE T3,DSKSTN(DSK) ;GET STRUCTURE NAME
CALL STRGSB ;BUILD STR STATUS TABLE & GET STR ADDR
STOR STR,DSKSSA,(DSK) ;STORE STR STATUS BLOCK ADDRESS
TXNN Q2,MS%MNT ;IS STR MOUNTED?
RET ;NO
MOVE T1,[MS%MT] ;SET STR MOUNTED
IORM T1,STRFLG(STR)
RET
;STRMNT - MOUNT A STRUCTURE
;ACCEPTS: RSB/ CURRENT REQUEST BLOCK
; STR/ STRUCTURE TO MOUNT
;RETURNS: +1/ FAILURE
; +2/ SUCCESS
STRMNT: SAVEQ
MOVE T2,[POINT 7,MSTNM] ;GET PTR TO CONVERT STR NAME TO ASCIZ
MOVEM T2,MSTRBK+.MSTNM ;STORE POINTER FOR LATER MSTR CALL
MOVEI T1,RSBSTN(RSB)
SKIPN (T1) ;IF NO PHYSICAL NAME WAS SPECIFIED,
MOVEI T1,RSBSTA(RSB) ; USE ALIAS
CALL SIXSEV
MOVE T2,[POINT 7,MSTAL] ;DO SAME FOR STRUCTURE ALIAS
MOVEM T2,MSTRBK+.MSTAL
MOVEI T1,RSBSTA(RSB)
CALL SIXSEV
LOAD T1,STRUNI,(STR) ;GET NUMBER OF UNITS IN STRUCTURE
HRRZM T1,MSTRBK+.MSTFL ; AND DON'T SET ANY SPECIAL ACTION FLAGS
MOVNS T1 ;NEGATE NUMBER OF UNITS
MOVSS T1 ;SET UP INDEX FOR DISK ADDRESS
HRR T1,STR ;GET START OF STR STATUS BLOCK
MOVEI T2,MSTRBK+.MSTUI ;SET UP INDEX FOR STORING DISK INFO
STRMN1: MOVE DSK,STRADD(T1) ;GET ADDRESS OF DISK STATUS BLOCK
LOAD T3,DSKCHN,(DSK) ;GET DISK CHANNEL
MOVEM T3,(T2) ;STORE FOR MSTR CALL
SETOM 1(T2) ;DO SAME FOR CONTROLLER
HRL Q2,T3 ;GET CHANNEL FOR DEVICE-TABLE CALL
LOAD T3,DSKDRV,(DSK) ;AND FOR DRIVE NUMBER
MOVEM T3,2(T2)
HRR Q2,T3 ;GET DRIVE FOR DEVICE TABLE
CALL DSFMGT ;GET DISK DRIVE ENTRY FROM DEVICE TABLE
MOVX Q1,MTS%AV ;GET AVAILABLE-STATUS BIT
TDNN Q1,DSFE+MTS.SF ;DRIVE AVAILABLE?
JRST [ MOVE T1,RSBSTN(RSB) ;NO, GET STRUCTURE NAME
HLRZ T2,Q2 ;GET CHANNEL
HRRZ T3,Q2 ;GET DRIVE
TMCT <%IChan %2D Drive %3D Unavailable For Mounting %1S>
MOVEI T3,TMCMSG
CALLRET BTWTO] ;TELL OPERATOR
ADDI T2,3
AOBJN T1,STRMN1 ;STORE UNIT INFO FOR NEXT DRIVE
SUBI T2,MSTRBK ;GET LENGTH OF ARGUMENT BLOCK
MOVEI T1,.MSMNT ;SET UP TO MOUNT A STRUCTURE
HRL T1,T2
MOVEI T2,MSTRBK ;GET ADDRESS OF ARGUMENT BLOCK
MSTR ;FINALLY, MOUNT IT
ERJMP STMERR ; SOMETHING WENT WRONG
MOVE T1,RSBSTA(RSB) ;GET STRUCTURE ALIAS
MOVEM T1,STRALI(STR) ; AND STORE
MOVE T1,[MS%MT] ;SET STRUCTURE MOUNTED
IORM T1,STRFLG(STR)
;HAVE MOUNTED STRUCTURE. MODIFY STRUCTURE STATUS IF NEEDED.
CALL COMNDS ;CHECK IF STR STATUS TABLE UP-TO-DATE
MOVEI T1,STRTBL ;CHECK IF STRUCTURE IS IN TABLE TO
MOVE T2,[POINT 7,MSTAL] ; CHANGE STATUS
TBLUK
TXNE T2,TL%EXM ;WAS A MATCH FOUND
JRST [HRLZ T1,(T1) ;YES, GET STATUS IN T1
JRST STRMN2]
SKIPN T1,SSCDEF ;IS THERE A NONSTANDARD DEFAULT FOR STRS
JRST STRMN3 ;NO, DON'T NEED TO CHANGE ANY STATUS
STRMN2: MOVEM T1,MSTRBK+.MSSST ;STORE IN ARGUMENT BLOCK
MOVE T1,[POINT 7,MSTAL] ;POINT TO ALIAS OF STR
MOVEM T1,MSTRBK+.MSSSN
MOVX T1,MS%DOM+MS%NRS ;GET BITS THAT ARE POSSIBLE TO CHANGE
MOVEM T1,MSTRBK+.MSSMW
MOVE T1,[3,,.MSSSS] ;NOW SET UP CHANGE STATUS FUNCTION
MOVEI T2,MSTRBK ;POINT TO ARGUMENT BLOCK
MSTR ;CHANGE STATUS
ERJMP DDSERR ;SOMETHING WENT WRONG
MOVE T1,MSTRBK+.MSSST ;GET STRUCTURE STATUS
IORM T1,STRFLG(STR) ; AND STORE
STRMN3: LOAD T4,STRMCT,(STR) ;GET NUMBER OF DISKS IN STRUCTURE
MOVNS T4
HLRZS T4
HRRI T4,STRADD(STR)
STRMN4: MOVE DSK,(T4)
CALL DSTGIV ;GET STATUS OF GIVEN UNIT
CALL STOP ;THERE IS AN INCONSISTENCY
MOVE T1,MSTRBK+.MSRST ;GET STATUS OF UNIT
MOVEM T1,DSKFLG(DSK) ;STORE IT
MOVE T1,STRALI(STR) ;GET ALIAS
MOVEM T1,DSKSTA(DSK) ; AND STORE
AOBJN T4,STRMN4
CALL WOSMT ;TELL OPERATOR OF SUCCESS
RETSKP
;STMERR - ERROR IN MOUNTING A STRUCTURE
STMERR: SAVEQ
MOVEI T1,.FHSLF ;GET THE ERROR
GETER
HRRZS T2 ;GET ERROR ONLY
CAIL T2,MSTRX6 ;CHECK TO SEE IF ERROR IS CORRECTABLE
CAIL T2,MSTX14
JRST [CAIN T2,MSTX20
JRST .+1
CAIN T2,MSTX23
JRST .+1
CAIN T2,MSTX25
JRST .+1
CAIN T2,MSTX30
JRST .+1
JRST DDSERR] ;IT IS, TELL OPERATOR
MOVE Q1,T2 ;COPY ERROR CODE TO SAFE PLACE
CALL DDSERR ;TELL OPERATOR OF PROBLEM
ABTRET (Q1,ABT%IN) ;ABORT REQUEST AND RETURN TO CALLER
;SYMSET - BUILD AND LOG SYSERR ENTRY FOR DISK DRIVE STATUS CHANGE
;ACCEPTS: T1/ FUNCTION CODE (CS%ADV = SET AVAILABLE, CS%DDV = SET UNAVAILABLE)
; T2/ ADDRESS OF ASCIZ REASON, OR 0 IF NO REASON GIVEN
; Q2/ CHANNEL,,DRIVE
; DSK/ ADDR OF DISK STATUS BLOCK
;RETURNS: +1, ALWAYS
SYMSET: SAVEQ
SETZM SYRMSG ;ZERO OUT SYSERR MESSAGE AREA
MOVE T4,[SYRMSG,,SYRMSG+1]
BLT T4,SYRMSG+SYRMSZ-1
; TRANSFER OPERATION CODE AND REASON TO MESSAGE
STOR T1,CS%OPR,SYRMSG+CS%OPW ;STORE OPERATION CODE INTO MESSAGE
MOVEI Q1,SYRHSZ+CS%SIZ ;ASSUME NO REASON GIVEN
SKIPN T1,T2 ;REASON GIVEN?
JRST SYMSE1 ;NO
MOVS Q3,T1 ;YES, COPY ADDRESS OF STRING FOR BLT
CALL ASCIZL ;GET # OF CHARACTERS
IDIVI T2,5 ;GET # OF WORDS MINUS 1
CAIL T2,SYRMSZ ;TOO LONG?
MOVEI T2,SYRMSZ-1 ;YES, TRUNCATE
MOVEI Q1,SYRHSZ+CS%SIZ+1(T2) ;SAVE SIZE OF ENTIRE MESSAGE
HRRI Q3,SYRMSG+CS%SIZ ;GET BLT DESTINATION
BLT Q3,SYRMSG+CS%SIZ(T2) ;TRANSFER STRING TO MESSAGE
MOVEI T1,CS%SIZ
STOR T1,CS%RSN,SYRMSG+CS%RSW ;STORE POINTER TO REASON
SYMSE1: MOVEI T1,SEC%CS ;GET CONFIGURATION STATUS CHANGE CODE
DPB T1,[POINT 9,SYRHDR,8] ;STORE INTO SYSERR ENTRY HEADER
;BUILD AND STORE SIXBIT DEVICE NAME
MOVE T1,[SIXBIT/DP000 /]
MOVE T2,[POINT 6,1,11]
HLRZ T3,Q2 ;GET CHANNEL
ADDI T3,20 ;MAKE IT A SIXBIT NUMBER
IDPB T3,T2 ;SET CHANNEL INTO NAME
HRRZ T3,Q2 ;GET DRIVE NUMBER
ADDI T3,20
IDPB T3,T2 ;SET DRIVE INTO NAME
MOVEM T1,SYRMSG+CS%DNM ;STORE SIXBIT DEVICE NAME
SETZM SYRMSG+CS%ADS ;CAN'T GET THE SERIAL NUMBER
LOAD T1,DSKTYP,(DSK) ;GET DISK TYPE
STOR T1,CS%UTP,SYRMSG+CS%HTP
;LOG THE MESSAGE
MOVEI T1,SYRHDR ;GET ADDRESS OF SYSERR MESSAGE
MOVE T2,Q1 ;GET # OF WORDS IN MESSAGE
SKIPN TSTF ;DON'T LOG SYSERRS IF TESTING
SYERR ;LOG IT
ERJMP R ;IGNORE ERRORS
RET
;TLUSR - BUILD BLOCK FOR SUCCESSFUL STRUCTURE REMOVAL RESPONSE
;ACCEPTS: RSB/ ADDRESS OF REQUEST STATUS BLOCK
;RETURNS: +1, ALWAYS
TLUSR: MOVE T1,RSBSTA(RSB) ;GET STRUCTURE NAME
TMCT <%IStructure %1S: removed
>
MOVEI T1,TMCMSG ;GET ADDRESS OF ASCIZ TEXT
MOVEI T2,.MNRTX ;GET ARGUMENT TYPE
CALL PBTXT ;CREATE TEXT BUILDING BLOCK
SETZ T1, ;SET NO FLAGS IN GALAXY HEADER
RET
;TLUSS - BUILD BLOCKS FOR SUCCESSFUL STRUCTURE MOUNT RESPONSE
;ACCEPTS: RSB/ ADDRESS OF REQUEST STATUS BLOCK
;RETURNS: +1: ALWAYS
TLUSS: STKVAR <<DVBLK,2>>
TMCT <%I> ;NEED THIS?
MOVE T1,[FLD(2,AR.LEN)+FLD(.MNSDV,AR.TYP)] ;GET HEADER
MOVE T2,RSBSTA(RSB) ;GET STRUCTURE ALIAS
DMOVEM T1,DVBLK ;STORE HEADER AND STRUNCTURE NAME
MOVEI T1,DVBLK ;GET ADDRESS OF DEVICE BLOCK
CALL PBBLK ;ADD IT TO BUILDING BLOCK LIST
SETZ T1, ;SET NO FLAGS IN GALAXY HEADER
RET
;USD - PROCESS USER STRUCTURE DISMOUNT REQUEST RECEIVED THRU QUASAR
;ACCEPTS: T1/ ADDR OF STRUCTURE MOUNT ENTRY IN IPCF MSSG FROM QUASAR
; RSB/ ADDR OF REQUEST STATUS BLOCK
;RETURNS: +1, ALWAYS
USD: SAVEQ
MOVEI T2,BSRRTA ;SET UP ANALYSIS TABLE FOR BTMRSB
CALL BTMRSB ;BUILD RSB FROM QUASAR MESSAGE
RET ;REQUEST ABORTED, EXIT
MOVX T1,R%DSM ;GET DISMOUNT FLAG
IORM T1,RSBIFL(RSB) ;AND SET INTO RSB
CALL DDSCIH ;MAKE SURE TABLES UP-TO-DATE
CALL CHKAB ;REQUEST ABORTED?
RET ;YES, MADE UNCORRECTABLE MOUNT ERROR
MOVE T1,RSBSTA(RSB) ;GET STRUCTURE ALIAS
MOVE T2,RSBSTN(RSB) ;GET STRUCTURE NAME
CALL MATCHS ;MATCH REQUEST TO STRUCTURE
JRST [ABTRET(MREQ25)] ;STRUCTURE NOT FOUND
STOR STR,RSBSS ;STORE STRUCTURE STATUS BLOCK ADDR
;MAKE SURE USER ISN'T CONNECTED TO STRUCTURE TO DISMOUNT
LOAD T1,RSBJNO ;GET USER'S JOB NUMBER
MOVE T2,[-1,,Q1] ;GET USER'S CONNECTED DIRECTORY
MOVEI T3,.JIDNO ; INTO Q1
GETJI
RET ;INVALID JOB, ABORT REQUEST
HRROI T1,TMCMSG ;POINT TO PLACE TO PUT NAME OF CONN DIR
MOVE T2,Q1 ;GET CONNECTED DIRECTORY
DIRST
JRST USD1 ;FORGET CONNECTED STR
HRROI T1,TMCMSG ;GET DESIGNATOR OF CONNECTED STR
STDEV
USD1: SETZ T2, ;FORGET CONNECTED STR
MOVE Q1,T2 ;STORE DESIGNATOR IN T3
MOVEI T1,RSBSTA(RSB) ;GET SIXBIT ALIAS
MOVE T2,[POINT 7,MSTAL] ;THIS IS PLACE TO STORE 7-BIT
CALL SIXSEV ;CONVERT IT
HRROI T1,MSTAL ;POINT TO ALIAS
STDEV ;GET ITS DESIGNATOR
JRST [ JUMPN STR,[MOVEI T1,RST.WM ;STR SPINNING,BUT NOT MOUNTED?
STOR T1,RSBSTE ;SET STATE TO WAITING
JRST WOVDS]
ABTRET (MREQ25)] ;STR IS NOT TO BE FOUND
CAMN Q1,T2 ;IS USER CONNECTED TO STR BEING REMOVED?
JRST [ ABTRET (MREQ24)] ;YES, ILLEGAL
;USER ISN'T CONNECTED TO STRUCTURE. PREPARE TO DISMOUNT IT.
MOVEI T1,RST.WM
STOR T1,RSBSTE ;SET STATE TO WAITING FOR DISMOUNT
MOVEI T1,RSBSTN(RSB) ;CONVERT SIXBIT NAME TO 7-BIT
MOVE T2,[POINT 7,MSTNM]
CALL SIXSEV
CALL TCKP ;UPDATE QUASAR'S QUEUES FOR "INFO MOUNT"
CALLRET STRDMT ;DISMOUNT STRUCTURE
;USM - PROCESS USER STRUCTURE MOUNT REQUEST RECEIVED THROUGH QUASAR
;ACCEPTS: T1/ ADDR OF STRUCTURE MOUNT ENTRY IN IPCF MSSG FROM QUASAR
; RSB/ ADDR OR REQUEST STATUS BLOCK
;RETURNS: +1, ALWAYS
USM: MOVEI T2,BSRRTA ;SET UP ANALYSIS TABLE FOR BTMRSB
CALL BTMRSB ;BUILD RSB FROM QUASAR MESSAGE
RET ;REQUEST ABORTED, EXIT
MOVEI T1,RSBSTA(RSB) ;POINT TO SIXBIT ALIAS
MOVE T2,[POINT 7,MSTAL] ;ASCII GOES HERE
CALL SIXSEV ;CONVERT ALIAS TO ASCII
HRROI T1,MSTAL ;POINT TO ASCII ALIAS
STDEV ;IS THIS A TTY: OR OTHER ILLEGAL DEVICE
SKIPA ;ERROR, MUST BE OKAY
JRST [ HLRZS T2 ;GET LEFT HALF OF DESIGNATOR
CAIN T2,.DVDES+.DVDSK ;IS IT A DISK?
JRST [ CALL TELUSR ;YES, AND ALREADY MOUNTED
ABTRET (ABRTNR)]
MOVEI Q1,MSTRX7 ;GET ERROR MESSAGE
ABTRET (Q1,ABT%IN)] ;ILLEGAL DEVICE FOR MOUNT
MOVEI T1,RST.WM
STOR T1,RSBSTE ;SET STATE TO WAITING FOR MOUNT
MOVN T1,IGNTBL ;CHECK IF STRUCTURE IS TO BE IGNORED
HRL T1,T1 ;SET UP COUNTER FOR AOBJN LOOP
HRRI T1,1 ;START AT SECOND WORD IN TABLE
SKIPN T2,RSBSTN(RSB) ;GET STRUCTURE NAME
MOVE T2,RSBSTA(RSB)
CAME T2,IGNTBL(T1) ;IS THIS THE STRUCTURE
AOBJN T1,.-1 ;CHECK NEXT ENTRY
SKIPG T1 ;DID WE FIND A MATCH?
JRST [ MOVEI T1,IGNTBL(T1) ;YES,CONVERT STRUCTURE NAME TO ASCIZ
MOVE T2,[POINT 7,MSTNM]
CALL SIXSEV
MOVEI T1,.FHSLF
MOVEI T2,MREQ27 ; TELL OPERATOR A REQUEST HAS COME
SETER ; FOR A STRUCTURE THAT HAS BEEN SET
CALL DDSERR ; IGNORED
JRST USM1] ;ALLOW OPERATOR TO CHANGE STR STATUS
CALL DDSCIH ;MAKE SURE TABLES UP-TO-DATE
CALL CHKAB ;REQUEST ABORTED?
RET ;YES, MADE UNCORRECTABLE MOUNT ERROR
MOVE T1,RSBSTA(RSB) ;GET STRUCTURE ALIAS
MOVE T2,RSBSTN(RSB) ;GET STRUCTURE NAME
CALL MATCHS ;MATCH REQUEST TO STRUCTURE
JRST USM1 ;STRUCTURE NOT MOUNTED YET
SKIPG STR ;IS STRUCTURE MOUNTED?
JRST [ LOAD T1,STRUNI,(STR) ;NO, GET # OF DISKS IN STR
LOAD T2,STRMCT,(STR) ;GET # OF DISK ON-LINE IN STR
CAME T1,T2 ;ARE ALL DISKS ON-LINE?
JRST USM1 ;NO, ASK OPERATOR
CALL STRMNT ;PACK IS SPINNING. MOUNT IT
JRST USM1 ;PROBLEM IN MOUNTING,CHECK WITH OPERATOR
JRST .+1]
CALL TELUSR ;LET USER KNOW HE HAS STRUCTURE
ABTRET (ABRTNR) ;DUMP THE RSB AND RETURN TO CALLER
USM1: CALL CHKAB ;REQUEST ABORTED?
RET ;YES, DON'T TALK TO OPERATOR
CALL TCKP ;UPDATE QUASAR'S QUEUES FOR "INFO MOUNT"
CALL PWATCH ;WATCH FOR USER DELETING HIS PID
CALLRET WOVMS ;TELL OPERATOR TO MOUNT STRUCTURE
;WOFRE - SET UP STRING CONTAINING INFORMATION ON FREE DRIVE
;ACCEPTS DSK/ CURRENT DISK STATUS BLOCK ADDRESS
;RETURNS +1, ALWAYS
WOFRE: SAVEQ
MOVE Q1,DSKFLG(DSK) ;GET STATUS WORD
LOAD T2,MS%TYP,Q1
MOVEI T1,[ASCIZ /Unk /] ;SET UP TYPE IN CASE UNKNOWN CODE
CAIG T2,MXUTYP ;VALID TYPE?
MOVEI T1,UNTYTB(T2) ;NO, GET NAME OF UNIT TYPE
TMCT <%1A%9C>
LOAD T1,DSKCHN,(DSK) ;GET CHANNEL NUMBER
TMCT <%1O / >
LOAD T1,DSKDRV,(DSK) ;GET UNIT NUMBER
TMCT <%1O%22C>
TXNE Q1,MS%HBB ;VALID HOME BLOCKS?
HRROI T1,[ASCIZ /Bad home blocks/]
TXNE Q1,MS%DIA ;MAINT MODE?
HRROI T1,[ASCIZ /Maintenance mode/]
TXNE Q1,MS%OFL ;OFF-LINE?
HRROI T1,[ASCIZ / /]
TXNE Q1,MS%DIA!MS%OFL!MS%HBB
JRST [ TMCT <%1A> ;OUTPUT ERROR MESSAGE
JRST WOFRE2] ;NO MORE INFORMATION TO OUTPUT
MOVE T1,DSKSTN(DSK) ;GET STRUCTURE NAME
TMCT <%1S: (>
LOAD T1,DSKLUN,(DSK)
AOS T1 ;CHANGE UNIT NUMBER TO ORDINAL
TMCT <%1D OF >
LOAD T1,DSKNOU,(DSK) ;GET # OF UNITS IN STRUCTURE
TMCT <%1D)>
WOFRE2: TMCTR <%_> ;CRLF
;WOMDAV - TELL OPERATOR OF AVAILABILITY OF DISK DRIVE FOR SYSTEM USE
;ACCEPTS: Q1/ 0 IF UNAVAILABLE, 1 IF AVAILABLE
; Q2/ CHANNEL,,DRIVE
;RETURNS: +1, ALWAYS
WOMDAV: HLRZ T1,Q2 ;GET CHANNEL
HRRZ T2,Q2 ;GET DRIVE
TMCT <%IChan %1D Drive %2D set >
JUMPE Q1,[TMCT <un>
JRST .+1]
TMCT <available for mounting by MOUNTR>
MOVE T3,[[ASCIZ/Disk Drive Set Unavailable/]
[ASCIZ/Disk Drive Set Available/]](Q1) ;GET HEADER
CALLRET BTWTO ;GET MESSAGE OUT TO OPERATOR
;WOMNT - SET UP STRING CONTAINING INFORMATION ON MOUNTED DRIVE
;ACCEPTS DSK/ CURRENT DISK STATUS BLOCK ADDRESS
;RETURNS +1, ALWAYS
WOMNT: SAVEQ
MOVE Q1,DSKFLG(DSK) ;GET STATUS WORD
MOVE T1,DSKSTA(DSK) ;GET STRUCTURE ALIAS
TMCT <%1S:>
LOAD Q2,DSKNOU,(DSK) ;GET NUMBER OF UNITS IN STR
CAIN Q2,1 ;ONLY ONE UNIT?
JRST WOMNT1 ;YES, FORGET TELLING NUMBER OF UNITS
TMCT < (>
LOAD T1,DSKLUN,(DSK)
MOVE Q3,T1 ;SAVE UNIT NUMBER
AOS T1 ;CHANGE UNIT NUMBER TO ORDINAL
TMCT <%1D/%6D)> ;UNIT# / # OF UNITS
WOMNT1: TMCT <%16C>
LOAD T2,MS%TYP,Q1
MOVEI T1,[ASCIZ /Unk /] ;SET UP TYPE IN CASE UNKNOWN CODE
CAIG T2,MXUTYP ;VALID TYPE?
MOVEI T1,UNTYTB(T2) ;YES, GET NAME OF UNIT TYPE
LOAD T2,DSKCHN,(DSK) ;GET CHANNEL NUMBER
TMCT <%1A%24C%2O / >
LOAD T1,DSKDRV,(DSK) ;GET UNIT NUMBER
TMCT <%1O>
SOJE Q2,WOMNT2 ;JUMP IF ONLY ONE UNIT
SKIPE Q3 ;IS THIS FIRST UNIT OF STRUCTURE?
JRST WOMNT3 ;NO, HAVE ALREADY OUTPUT INFORMATION
WOMNT2: TMCT <%34C>
MOVE T2,[POINT 7,MSTAL];SET UP POINTER FOR ALIAS
MOVEM T2,MSTRBK+.MSGSN
MOVEI T1,DSKSTA(DSK)
CALL SIXSEV ;CONVERT SIXBIT ALIAS TO NEEDED 7-BIT
MOVE T1,[4,,.MSGSS] ;GET 4 WORDS OF STRUCTURE STATUS
MOVEI T2,MSTRBK
MSTR
ERJMP WOMNT3 ;NO STRUCTURE?
MOVE T1,MSTRBK+.MSGMC ;GET MOUNT COUNT
TMCT <%1D%41C>
SETZ Q2, ;THIS IS FLAG TO SEE IF STATUS PRINTED
MOVE Q1,MSTRBK+.MSGST ;GET STRUCTURE STATUS
TXNE Q1,MS%DOM ;IS THIS STRUCTURE DOMESTIC
JRST [TMCT <Domestic > ;YES
SETO Q2, ;SET FLAG TO SAY STATUS PRINTED
JRST .+1]
TXNN Q1,MS%NRS ;IS THIS STRUCTURE REGULATED?
JRST [TMCT <Regulated > ;YES
SETO Q2, ;SET FLAG TO SAY STATUS PRINTED
JRST .+1]
TXNE Q1,MS%DIS ;IS THIS STRUCTURE AVAILABLE?
JRST [TMCT <Unavailable >
SETO Q2, ;SET FLAG TO SAY STATUS PRINTED
JRST .+1]
MOVE T1,IGNTBL ;CHECK TO SEE IF STRUCTURE IS IGNORED
MOVE T2,DSKSTN(DSK)
CAME T2,IGNTBL(T1) ;IS THIS THE STRUCTURE?
AOBJN T1,.-1 ;CHECK NEXT ENTRY
SKIPG T1 ;DID WE FIND A MATCH?
JRST [TMCT <Ignored > ;YES
SETO Q2, ;SET FLAG TO SAY STATUS PRINTED
JRST .+1]
MOVE T1,DSKSTA(DSK) ;GET ALIAS
CAME T1,T2 ;ARE NAME AND ALIAS THE SAME?
JRST [ SKIPE Q2 ;IF NOTHING PRINTED, DON'T NEED CRLF
CALL [ TMCTR <%_>]
TMCT <%41CName: %2S>
JRST .+1]
WOMNT3: TMCTR <%_>
;WOSM - TELL OPERATOR OF A STRUCTURE
WOSM: MOVEI T1,MSTNM ;GET STRUCTURE NAME
TMCT <%IStructure %1A>
MOVE T1,MSTNM ;ARE ALIAS AND NAME THE SAME
CAME T1,MSTAL
JRST WOS1 ;NO, PRINT THE ALIAS
MOVE T1,MSTNM+1
CAMN T1,MSTAL+1
RET ;YES, FORGET THE ALIAS
WOS1: MOVEI T1,MSTAL ;POINT TO ALIAS
TMCTR <: (Alias: %1A)>
;WOSDM - TELL OPERATOR OF A STRUCTURE DISMOUNT
WOSDM: CALL WOSM ;SET UP STRUCTURE NAMES
TMCT < dismounted>
MOVEI T3,[ASCIZ/STRUCTURE DISMOUNTED/]
CALLRET BTWTO ;TELL OPERATOR
;WOSMT - TELL OPERATOR OF A STRUCTURE MOUNT
WOSMT: CALL WOSM ;SET UP STRUCTURE NAMES
TMCT < mounted>
MOVEI T3,[ASCIZ/STRUCTURE MOUNTED/]
CALLRET BTWTO ;TELL OPERATOR
;WOSSC - TELL OPERATOR STATUS OF STRUCTURE AFTER STATUS CHANGE
WOSSC: STAKT
MOVEI T2,MSTAL ;GET STRUCTURE NAME
TMCT <%I%2A: set %1A for use by system>
MOVEI T3,[ASCIZ/STRUCTURE STATUS SET/]
CALLRET BTWTO ;GET MESSAGE TO OPERATOR
;WRDSC - ASK OPERATOR IF STRUCTURE SHOULD BE REMOVED, EVEN THOUGH THERE
; ARE USERS ON IT
;ACCEPTS: T1/ ADDRESS OF RESPONSE HANDLER CALLED BY INWTOR
; STR/ ADDRESS OF STRUCTURE STATUS BLOCK
; RSB/ ADDRESS OF REQUEST STATUS BLOCK
;RETURNS: +1, ALWAYS
WRDSC: MOVE T3,STRNAM(STR) ;GET STRUCTURE NAME
MOVE T2,STRALI(STR) ;GET ALIAS
TMCT <%IRemoval of structure %3S: (Alias %2S:) requested.
Other jobs are currently using it. Should
removal request be processed (YES or NO)?
%U>
MOVEI T2,RSBWTB(RSB) ;GET WTB ADDRESS
MOVEI T3,[ASCIZ/DISMOUNT QUERY/]
CALLRET BTWTOR ;SEND WTOR OFF TO THE OPERATOR
;WOVDS - TELL OPERATOR A STRUCTURE MUST BE DISMOUNTED AND ACCEPT A
; POSSIBLE REFUSAL
;ACCEPTS: T1/ ADDRESS OF RESPONSE HANDLER CALLED BY INWTOR
; STR/ ADDRESS OF STRUCTURE STATUS BLOCK
; RSB/ ADDRESS OF REQUEST STATUS BLOCK
;RETURNS: +1, ALWAYS
WOVDS: STAKT
MOVE T1,STRNAM(STR) ;GET SIXBIT STRUCTURE NAME
MOVE T2,RSBSTA(RSB) ;GET SIXBIT STRUCTURE ALIAS
TMCT <%IRemove %1S: (alias %2S:)%_%U%_>
SKIPE RSBRMK(RSB) ;DID THE USER SUPPLY A REMARK?
JRST [ MOVEI T1,RSBRMK(RSB) ;YES, GET ADDRESS OF ASCIZ REMARK
TMCT <User's remark: %1A%_>
JRST .+1]
MOVEI T1,SMHDR ;GET STATUS HEADER TEXT
TMCT <%1A>
LOAD Q1,STRUNI,(STR) ;GET NUMBER OF UNITS IN STRUCTURE
MOVNS Q1 ;SET UP INDEX
HRLZ Q1,Q1
MOVE T1,STR
ADDI T1,STRADD ;GET INDEX TO START OF DISK ADDRESSES
HRR Q1,T1 ;GET ADDRESS FOR DISK
WOVD1: MOVE DSK,(Q1) ;GET DISK BLOCK ADDRESS
JUMPE DSK,WOVD2 ;JUMP IF PACK GONE
MOVX T1,MS%MNT ;MAKE SURE DISK IS NOT MOUNTED
ANDCAM T1,DSKFLG(DSK)
CALL WOMNT ;DISPLAY UNIT
WOVD2: AOBJN Q1,WOVD1 ;IF MORE PACKS, DISPLAY THEM
MOVE T1,CT1 ;GET RESPONSE HANDLER'S ADDRESS
MOVEI T2,RSBWTB(RSB) ;GET WTB ADDRESS
MOVEI T3,[ASCIZ/DISMOUNT STRUCTURE/]
CALLRET BTWTO ;SEND WTO OFF TO THE OPERATOR
;WOVMS - TELL OPERATOR A STRUCTURE MUST BE MOUNTED
;ACCEPTS: RSB/ ADDRESS OF REQUEST STATUS BLOCK
;RETURNS: +1, ALWAYS
WOVMS: CALL MESCHK ;HAVE WE ALREADY NOTIFIED OPR OF STR?
RET ;YES, FORGET THIS
SETONE R%ONR,RSBIFL(RSB) ;SET OPERATOR-NOTIFIED
MOVE T1,RSBITN(RSB) ;GET REQUEST #
TMCT <%IStructure Mount Request # %1D>
CALL CPYHDR ;COPY HEADER TO OPRHDR
SKIPN T1,RSBSTN(RSB) ;GET SIXBIT STRUCTURE NAME
MOVE T1,RSBSTA(RSB) ;NONE SPECIFIED, GET ALIAS AS NAME
MOVE T2,RSBSTA(RSB) ;GET SIXBIT STRUCTURE ALIAS
TMCT <%IMount %1S: (alias %2S:)%_%U%_>
SKIPE RSBRMK(RSB) ;DID THE USER SUPPLY A REMARK?
JRST [ MOVEI T1,RSBRMK(RSB) ;YES, GET ADDRESS OF REMARK
TMCT <User's remark: %1A%_>
JRST .+1]
MOVEI T1,SFHDR ;GET STATUS HEADER TEXT
TMCT <%1A>
MOVSI DSK,-MAXDSK ;GET MAX NUMBER OF DISKS
HRRI DSK,DSKSTB ;GET STARTING POINT OF DISK BLOCKS
SETZ Q1, ;SET FLAG TO SAY NO AVAILABLE DRIVES
WOVM1: SKIPN T1,DSKFLG(DSK) ;IF STATUS ZERO, MUST NOT BE A DISK
JRST WOVM2 ;NO DISK
TXNN T1,MS%MNT ;IS THIS DISK MOUNTED?
TXNE T1,MS%DIA ;NO, IS IT IN MAINT MODE?
JRST WOVM2 ;YES, SKIP THIS DISK
CALL WOFRE ;DISPLAY STATUS OF THIS DRIVE
SETO Q1, ;SET FLAG TO SAY WE HAVE A DRIVE
WOVM2: ADDI DSK,DSKSZ-1 ;GET NEXT STATUS BLOCK
AOBJN DSK,WOVM1 ;IF STILL MORE DISKS, GO PROCESS
JUMPE Q1,[TMCT <No drives available>
JRST .+1]
MOVEI T3,OPRHDR ;GET ADDRESS OF HEADER TEXT
CALLRET BTWTO ;SEND WTO OFF TO THE OPERATOR
;NO ROOM FOR ANOTHER STRING...
NOSRUM: MOVEI T1,ATMBFR ;POINT TO STRUCTURE NAME
TMCT <No more room, structure %1A: not put on structures list
>
JRST NOS1 ;SEND MESSAGE TO OPERATOR
;TBADD FAILED WHEN TRYING TO ADD STRUCTURE TO LIST
TABFAL: TMCT <%I>
CALL GETERR ;GET ERROR CODE
CAIN T1,TADDX1 ;TABLE FULL?
JRST TABFUL ;YES
CAIN T1,TADDX2 ;ENTRY ALREADY THERE?
JRST TABDUP ;YES
NOS2: MOVE T1,Q1 ;POINT TO STR NAME
TMCT <Structure %1A: not put on structures list>
NOS1: MOVEI T3,[ASCIZ/ERROR IN MOUNTR COMMAND FILE/]
CALL BTWTO ;WRITE MESSAGE TO OPERATOR
JRST COMND1 ;GO GET NEXT COMMAND
TABFUL: TMCT <Structures table full, >
JRST NOS2 ;GO SAY WHICH STR DIDN'T GET PUT ON LIST
TABDUP: MOVE T1,Q1 ;GET STRUCTURE NAME
TMCT <Duplicate structure name %1A:%_>
JRST NOS1 ;GO GET NEXT COMMAND
;GET TO HERE ON BAD COMMAND
COMBAD: POP P,T1 ;GET RID OF RETURN ADDRESS
MOVEI T1,ATMBFR ;GET BAD COMMAND
TMCT <%ICommand line containing "%1A" being ignored
>
JRST NOS1 ;SEND MESSAGE TO OPERATOR
;GET TO HERE ON COMND JSYS ERROR, HOPEFULLY END OF FILE CONDITION
COMEOF: POP P,T1 ;GET RID OF RETURN ADDRESS
CALL GETERR ;GET ERROR CODE
CAIN T1,IOX4 ;END OF FILE?
JRST COMEO1 ;YES
COMEO2: TMCT <%ICommand file execution failed, reason: %J>
MOVEI T3,[ASCIZ/ERROR IN MOUNTR COMMAND FILE/]
CALL BTWTO ;TELL OPERATOR
;HERE ON END OF COMMAND FILE...
COMEO1: MOVE T1,COMJFN ;GET JFN ON COMMANDS FILE
CLOSF ;CLOSE IT
JFCL ;IGNORE FAILURE
RET ;RETURN TO CALLER
SUBTTL USER TAPE MOUNT REQUEST
; BTMRSB - EXTRACT INFORMATION FROM USER MOUNT REQUEST AND
; TRANSFER IT TO THE REQUEST STATUS BUFFER
; T1/ ADDRESS OF MOUNT ENTRY IN IPCF MESSAGE FROM QUASAR
; T2/ ADDRESS OF TABLE MOUNT REQUEST ANALYSIS ROUTINE ADRESSES
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: FAILURE, MOUNT REQUEST ABORTED
; +2: SUCCESS, INFORMATION TRANSFERRED TO RSB
BTMRSB: SAVEQ
DMOVE Q1,T1 ;COPY ADDRESSES TO A SAFE PLACE
; PERFORM STRUCTURAL VALIDATION OF MOUNT ENTRY
MOVE T1,.MECNT(Q1) ;GET SUBENTRY COUNT
MOVEI T2,.MEHSZ(Q1) ;GET ADDRESS OF FIRST SUBENTRY
LOAD T3,AR.LEN,.MEHDR(Q1) ;GET LENGTH OF SUBENTRY
SUBI T3,.MEHSZ ;COMPUTE SIZE OF SUBENTRY AREA
SKIPL T3 ;ERROR IF HEADER IS INCOMPLETE
CALL CKBSTR ;CHECK STRUCTURE OF MOUNT REQUEST
JRST [ ABTRET (MREQ20)] ;STRUCTURE ERROR IN MOUNT ENTRY
; PERFORM SEMANTIC ANALYSIS OF MOUNT ENTRY
BTMR1: MOVEI T1,.MECNT(Q1) ;ADDRESS OF SUBENTRY COUNT WORD
MOVEI T2,.MEHSZ(Q1) ;ADDRESS OF FIRST SUBENTRY
SKIPN (Q2) ;FINISHED WITH ANALYSIS ROUTINES?
RETSKP ;YES, GO HOME
CALL @(Q2) ;CALL ANALYSIS ROUTINE
RET ;ERROR DETECTED, PASS IT TO CALLER
AOJA Q2,BTMR1 ;LOOP THRU ALL ANALYSIS ROUTINES
; TABLE OF TAPE MOUNT REQUEST ANALYSIS ROUTINE ADDRESSES
; WARNING:
; DO NOT CHANGE THE ORDER OF THE ROUTINES IN THIS TABLE - SOME
; DEPEND UPON RSB FIELDS SET UP BY THEIR PREDECESSORS
BTRRTA: IFIW!BTRFLG ;BIT FLAGS
IFIW!BTRDEN ;DENSITY
IFIW!BTRDRV ;DRIVE-TYPE
IFIW!BTRLT ;LABEL TYPE
IFIW!BTRSET ;SET NAME
IFIW!BTRRMK ;REMARK
IFIW!BTRVLS ;VOLID LIST
IFIW!BTRSTV ;STARTING VOLID NUMBER
IFIW!BTRVPR ;VOLUME PROTECTION
0 ;END OF ROUTINES
;TABLE OF STRUCTURE MOUNT REQUEST ANALYSIS ROUTINE ADDRESSES
; WARNING:
; BSRALI MUST BE AFTER BSRNAM IN THE TABLE
BSRRTA: IFIW!BSRALI ;ALIAS OF STRUCTURE
IFIW!BSRNAM ;NAME OF STRUCTURE
IFIW!BTRRMK ;REMARK
0 ;END OF ROUTINES
; ROUTINES FOR PROCESSING SUBENTRIES OF TAPE MOUNT REQUEST
; T1/ ADDRESS OF SUBENTRY COUNT WORD
; T2/ ADDRESS OF FIRST SUBENTRY
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: REQUEST ABORTED
; +2: SUBENTRY PROCESSED SUCCESSFULLY
; DENSITY
BTRDEN: MOVEI T3,.TMDEN
MOVEI T4,DENMAX ;GET MAXIMUM
CALL BTRG1 ;LOOKUP DENSITY PARAMETER
JRST [ ABTRET (MREQX3)] ;DENSITY ILLEGAL
STOR T1,RSBDEN ;STORE DENSITY IN RSB
RETSKP
; DRIVE TYPE
BTRDRV: MOVEI T3,.TMDRV
MOVEI T4,.TMDMX ;GET MAXIMUM
CALL BTRG1 ;LOOKUP DRIVE PARAMETER
JRST [ ABTRET (MREQX4)] ;DRIVE TYPE ILLEGAL
STOR T1,RSBDRV ;STORE DRIVE TYPE IN RSB
RETSKP
; BIT FLAGS
BTRFLG: MOVE T1,.MEFLG(Q1) ;GET USER-SUPPLIED FLAGS
TXNE T1,TM%BYP ;DOES HE WANT BYPASS?
JRST [ MOVX T2,R%PRIV ;YES
TDNE T2,RSBIFL(RSB) ;IS HE PRIVILEGED?
JRST .+1 ;YES, LET HIM DO IT
ABTRET (CAPX1)] ;NOT PRIVILEGED, ABORT REQUEST
TXNE T1,TM%SCR
JRST [ TXO T1,TM%NEW+TM%WEN ;FLAGS IMPLIED BY TM%SCR
TXZ T1,TM%OSV+TM%VFY
JRST .+1]
TXNE T1,TM%NEW
JRST [ TXO T1,TM%WEN ;FLAGS IMPLIED BY TM%NEW
TXZ T1,TM%VFY
MOVX T2,R%WVL
IORM T2,RSBIFL(RSB)
JRST .+1]
MOVEM T1,RSBUFL(RSB) ;MOVE USER REQUEST FLAGS TO RSB
RETSKP
; LABEL TYPE (MUST BE CALLED AFTER BTRDRV)
BTRLT: MOVEI T3,.TMLT
MOVEI T4,.LTMAX ;GET MAXIMUM
CALL BTRG1 ;LOOKUP DRIVE-TYPE PARAMETER
JRST [ ABTRET (MREQX5)] ;LABEL TYPE ILLEGAL
MOVX T2,TM%BYP
TDNE T2,RSBUFL(RSB) ;BYPASS?
MOVEI T1,.LTUNL ;YES, FORCE LABEL TYPE = UNLABELED
CAIE T1,.LTUNL ;LABELED TAPE?
JUMPN T1,[LOAD T2,RSBDRV ;YES, GET DRIVE TYPE
CAIE T2,.TMDR7 ;7-TRACK?
JRST .+1 ;NO
ABTRET (MREQX2)] ;YES, 7-TRACK LABELS NOT SUPPORTED
STOR T1,RSBLT ;STORE LABEL TYPE IN RSB
RETSKP
; REMARK
BTRRMK: MOVEI T3,.TMRMK
CALL BLKFND ;LOOKUP REMARK
RETSKP ;NO REMARK
JUMPE T2,RSKP ;TREAT ZERO-LENGTH REMARK LIKE NO REMARK
CAILE T2,RMKLEN ;IS REMARK TOO LONG?
MOVEI T2,RMKLEN ;YES, TRUNCATE
MOVSS T1 ;BLT SOURCE
HRRI T1,RSBRMK(RSB) ;BLT DESTINATION
ADDI T2,RSBRMK-1(RSB) ;LAST WORD OF DESTINATION
BLT T1,(T2) ;BLT REMARK INTO RSB
MOVEI T1,377
ANDCAM T1,(T2) ;MAKE SURE REMARK ENDS WITH A NULL
RETSKP
; SETNAME
BTRSET: MOVEI T3,.TMSET
CALL BLKFND ;LOOKUP SETNAME
JRST BTRSE1 ;SETNAME MISSING
JUMPE T2,BTRSE1 ;ERROR IF HEADER-ONLY SUBENTRY
MOVE T1,(T1) ;GET SETNAME IN T1 FOR CHKID
CALL CHKID ;IS IT A LEGAL SETNAME?
BTRSE1: JRST [ ABTRET (MREQX6)] ;SETNAME ILLEGAL OR MISSING
MOVEM T1,RSBSSN(RSB) ;STORE USER-SUPPLIED SETNAME IN RSB
MOVX T2,TM%NEW
TDNE T2,RSBUFL(RSB) ;USER CREATING NEW VOLUME SET?
MOVEM T1,RSBASN(RSB) ;YES, HIS SETNAME GOES IN THE LABELS
RETSKP
; STARTING VOLID NUMBER (MUST BE CALLED AFTER BTRVLS)
BTRSTV: SAVEQ
MOVEI T3,1
STOR T3,RSBCV ;DEFAULT CURRENT VOLID # IS 1
MOVEI T3,.TMSTV
CALL BLKFND ;STARTING VOLID ENTRY PRESENT?
RETSKP ;NO, DEFAULT WILL BE USED
JUMPE T2,BTRSTI ;ERROR IF HEADER-ONLY SUBENTRY
MOVX T3,TM%OSV+TM%NEW
TDNE T3,RSBUFL(RSB) ;ANY BITS SET?
JRST BTRSTI ;YES, USER CAN'T SPECIFY THIS PARAMETER
SKIPE Q1,(T1) ;SPECIFYING NUMBER OR VOLID?
JRST [ CALL VQCNT ;NUMBER, GET # OF VOLIDS IN REQUEST
CAMG Q1,T1 ;ERROR IF SPECIFIED VALUE .GT. MAX
SKIPG Q1 ;ERROR IF STARTING VOLID NOT POSITIVE
JRST BTRSTI
STOR Q1,RSBCV ;OFFSET IS LEGAL, STORE IT
RETSKP]
CAIGE T2,2 ;SPECIFYING VOLID, IS ENTRY LONG ENOUGH?
JRST BTRSTI ;NO
MOVE Q1,1(T1) ;GET VOLID
MOVEI Q2,1 ;GET COUNTER
QSCANI <RSBVLS(RSB)> ;SET UP TO SCAN VOLID LIST
BTRST1: CALL QMSCAN ;LOOK AT NEXT VOLID FOR THIS REQUEST
BTRSTI: JRST [ ABTRET (MREQX7)] ;ABORT REQUEST - ILLEGAL STARTING VOLID
CAME Q1,1(T2) ;IS THIS THE ONE?
AOJA Q2,BTRST1 ;NO, BUMP COUNTER & CONTINUE SEARCH
STOR Q2,RSBCV ;FOUND IT, STORE ORDINAL VOLID #
RETSKP
; VOLID LIST
BTRVLS: SAVEQ
MOVX T3,TM%OSV+TM%SCR
TDNE T3,RSBUFL(RSB) ;IS USER PERMITTED TO SPECIFY VOLIDS?
RETSKP ;NO, IGNORE VOLID LIST IF PRESENT
MOVEI T3,.TMVOL
CALL BLKFND ;LOOKUP VOLID LIST
SETZ T2, ;NO VOLID LIST
JUMPE T2,[MOVX T2,TM%OSV+TM%NEW ;ZERO-LENGTH IS LIKE NO LIST
TDNE T2,RSBUFL(RSB) ;IS VOLID LIST REQUIRED?
RETSKP ;NO, LET HIM BY
ABTRET (MREQ17)] ;YOU FORGOT TO LIST YOUR VOLIDS FELLA
MOVN Q1,T2 ;GET -#VOLIDS IN Q1
MOVSS Q1 ;CONSTRUCT LEFT HALF OF AOBJN POINTER
HRR Q1,T1 ;VOLID SOURCE ADDRESS IN RIGHT HALF
BTRVL1: MOVE T1,(Q1) ;GET A VOLID FROM SUBENTRY
CALL CHKID ;IS IT A LEGAL VOLID?
JRST [ ABTRET (MREQX9)] ;NO, ABORT REQUEST
CALL VQADD ;ADD VOLID TO END OF LIST
RET ;POOL EXHAUSTED, REQUEST ABORTED
AOBJN Q1,BTRVL1 ;LOOP TO TRANSFER ALL VOLIDS
RETSKP
; VOLUME PROTECTION
BTRVPR: MOVEI T3,.TMVPR
CALL BLKFND ;SEARCH FOR VOLUME-PROTECTION ENTRY
SETZ T2, ;NONE FOUND
MOVE T1,(T1) ;GET ARG IF THERE
SKIPN T2 ;SKIP IF ARGUMENT PRESENT
MOVEI T1,777777 ;USE DEFAULT
STOR T1,RSBVPR ;STORE VOLUME-PROTECTION CODE
RETSKP
; BTRG1 - GET A NUMERIC ARGUMENT FROM A BUILDING-BLOCK LIST
; IF NO VALUE SPECIFIED, RETURN 0
; IF VALUE SUPPLIED, VERIFY THAT 0 .LE. VALUE .LE. MAXIMUM
; T1-T3/ ARGUMENTS FOR BLKFND
; T4/ MAXIMUM VALUE
; RETURNS +1: ENTRY CONTAINS HEADER ONLY OR ARG LIES OUTSIDE LIMITS
; +2: ARGUMENT VALID, T1/ VALUE
BTRG1: STAKT
CALL BLKFND ;SEARCH FOR ENTRY
JRST [ SETZ T1, ;ENTRY NOT THERE, RETURN ZERO
RETSKP]
JUMPE T2,R ;ERROR IF HEADER-ONLY
SKIPGE T1,(T1) ;GET ARGUMENT
RET ;CAN'T BE LESS THAN ZERO
CAMLE T1,CT4
RET ;.GT. UPPER LIMIT
RETSKP
; TCITN - CANCEL A TAPE MOUNT REQUEST WITH A SPECIFIED ITN
; T1/ INTERNAL TASK NAME (ITN) OF REQUEST TO BE CANCELED
; RETURNS +1: ITN NOT FOUND OR REQUEST COULD NOT BE CANCELED
; +2: REQUEST CANCELED
TCITN: QSCANI ARBQDB ;SET UP TO SCAN TAPE REQUEST QUEUE
SAVEAC <RSB>
SAVEQ
MOVE Q1,T1 ;SAVE ITN
TCITN1: CALL QMSCAN ;GET ADDR OF NEXT RSB IN T2
RET ;NONE LEFT, EXIT
MOVEI RSB,-RSBLNK(T2) ;GET ADDRESS OF RSB INTO RSB AC
CAME Q1,RSBITN(RSB) ;IS THIS THE RIGHT REQUEST?
JRST TCITN1 ;NO, CONTINUE SEARCH
LOAD T1,RSBTYP
CAIN T1,.MNTTP ;TAPE REQUEST?
JRST [ JE RSBMT,,.+1 ;YES, CANCEL ONLY IF MT NOT ASSIGNED YET
RET] ;MT ASSIGNED, CAN'T CANCEL IT
CALL CHKAB ;REQUEST ABORTED?
RET ;YES, CAN'T CANCEL
ABTREQ (MREQX1) ;OK, KILL IT
CALL WORCAN ;TELL OPERATOR REQUEST WAS CANCELED
RETSKP
; TELMON - TELL THE MONITOR A TAPE VOLUME SWITCH WAS NOT PERFORMED
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: ALWAYS
MTUABS==3 ;SIZE OF ARGUMENT BLOCK
TELMON: STKVAR <<MTUAB,MTUABS>>
MOVEI T1,MTUABS
MOVEM T1,.MTCNT+MTUAB ;SET COUNT IN ARGUMENT BLOCK
LOAD T1,RSBSTE ;GET ERROR CODE
MOVEM T1,.MTCOD+MTUAB ;SET ERROR CODE IN ARG BLOCK
SETZ T1, ;ASSUME NO ERROR MESSAGE
MOVX T2,R%ORES
TDNE T2,RSBIFL(RSB) ;IS THERE AN OPERATOR RESPONSE?
HRROI T1,ATMBFR ;YES, GET POINTER TO RESPONSE STRING
MOVEM T1,.MTPTR+MTUAB ;SET STRING POINTER OR 0 IN ARG BLOCK
; ARGUMENT BLOCK IS SET UP, NOW LOAD THE AC'S AND ISSUE THE CALL
MOVEI T1,.MTNVV ;GET MTU FUNCTION CODE
LOAD T2,RSBMT ;GET MT STATUS BLOCK ADDRESS
SUBI T2,MT0 ;COMPUTE DISPLACEMENT FROM 0TH BLOCK
IDIVI T2,MTSZ ;COMPUTE MT#
MOVEI T3,MTUAB ;GET ARGUMENT BLOCK ADDRESS
MTU% ;TELL MONITOR
RET
; TELUSR - BUILD AND SEND IPCF MESSAGE TO USER TO NOTIFY HIM OF THE
; DISPOSITION OF A MOUNT REQUEST
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: ALWAYS
TELUSR: SAVEQ
SETZM TBUF+.OFLAG ;CLEAR FLAGS WORD
CALL PBINIT ;SET UP FOR CREATING BUILDING BLOCKS
MOVE Q1,[2,,.MNRNM] ;BUILD BLOCK CONTAINING REQUEST NAME
MOVE Q2,RSBRNM(RSB)
MOVEI T1,Q1
CALL PBBLK
LOAD T1,RSBSTE ;GET REQUEST STATE
CAIN T1,ABRTNR ;SHOULD USER GET A RESPONSE?
RET ;NO, EXIT
CAIL T1,.ERBAS ;IS THE REQUEST ABORTED?
JRST [ CALL TLUAB ;YES, BUILD MESSAGE FOR ABORT
JRST TELUS1]
LOAD T1,RSBTYP ;GET REQUEST TYPE
MOVEI T2,STOP ;IN CASE NO MATCH IS FOUND
CAIN T1,.MNTTP ;TAPE-MOUNT?
MOVEI T2,TLUTS ;YES
CAIN T1,.MNTST ;STRUCTURE MOUNT?
MOVEI T2,TLUSS ;YES
CAIN T1,.DSMST ;DISMOUNT STRUCTURE?
MOVEI T2,TLUSR ;YES
NOSHIP,<
CAIN T1,.MNTDT ;DECTAPE-MOUNT?
MOVEI T2,TLUDT ;YES
>;NOSHIP
CALL (T2) ;CALL APPROPRIATE TELL-ROUTINE
; TELUS1 - T1/ GALAXY HEADER FLAGS
TELUS1: MOVE T2,T1 ;COPY FLAGS TO T2 FOR GALHDR
MOVE T1,PBBPT ;GET POINTER AFTER LAST BLOCK
SUBI T1,TBUF ;COMPUTE LENGTH OF MESSAGE
MOVSS T1 ;MOVE TO LH OF T1
HRRI T1,.QOMNA ;PUT MESSAGE TYPE IN RIGHT HALF
MOVE T3,RSBCOD(RSB) ;GET USER'S ACK CODE
CALL GALHDR ;BUILD GALAXY HEADER FOR USER
MOVE T1,RSBPID(RSB) ;GET USER'S PID
CALLRET TRANU ;SEND THE MESSAGE AND RETURN TO CALLER
; TLUTS - BUILD BLOCKS FOR SUCCESSFUL TAPE MOUNT RESPONSE
TLUTS: STKVAR <<DVBLK,3>,SAVMT>
CALL VQGCV ;GET CURRENT VOLID IN T1
MOVE T2,RSBSSN(RSB) ;GET SETNAME
JUMPE T1,[TMCT <%I[Tape set %2S, scratch tape mounted]%_>
JRST TLUTS1]
TMCT <%I[Tape set %2S, volume %1S mounted]%_>
TLUTS1: JN TM%OSV,RSBUFL(RSB),[TMCT <[Volume identifiers: >
CALL TMCVLS ;DISPLAY VOLID LIST
TMCT <]
>
JRST .+1]
MOVEI T1,TMCMSG ;GET ADDR OF ASCIZ TEXT
MOVEI T2,.MNRTX ;GET ARGUMENT TYPE
CALL PBTXT ;CREATE TEXT BUILDING BLOCK
MOVE T1,[FLD(3,AR.LEN)+FLD(.MNRDV,AR.TYP)] ;GET HEADER
MOVE T2,RSBSSN(RSB) ;GET SETNAME
DMOVEM T1,DVBLK ;STORE HEADER AND SETNAME
MOVEM MT,SAVMT ;PRESERVE MT AC
LOAD MT,RSBMT ;GET ADDR OF MT STATUS BLOCK
CALL GMTDD ;GET MT DEVICE DESIGNATOR IN T1
MOVE MT,SAVMT ;RESTORE MT AC
MOVEM T1,2+DVBLK ;STORE MT DESIGNATOR IN .MNRDV BLOCK
MOVEI T1,DVBLK ;GET ADDRESS OF .MNRDV BLOCK
CALL PBBLK ;ADD IT TO BUILDING BLOCK LIST
SETZ T1, ;SET NO FLAGS IN GALAXY HEADER
RET
; TLUAB - BUILD BLOCKS FOR UNSUCCESSFUL MOUNT-REQUEST RESPONSE
TLUAB: SAVEQ
MOVE Q1,[FLD(2,AR.LEN)+FLD(.MNREC,AR.TYP)] ;GET HEADER
LOAD Q2,RSBSTE ;GET ERROR CODE
MOVEI T1,Q1 ;POINT AT ERROR CODE BLOCK
CALL PBBLK ;PUT BLOCK IN MESSAGE
JN R%ORES,RSBIFL(RSB),[MOVEI T1,ATMBFR ;POINT TO REASON
TMCT <%IReason given by operator: %1A>
MOVEI T1,TMCMSG ;GET ADDRESS OF ASCIZ TEXT
MOVEI T2,.MNRTX ;GET ENTRY TYPE
CALL PBTXT ;INSTALL TEXT BUILDING BLOCK
JRST .+1]
MOVX T1,MF.FAT ;GET FATAL-ERROR FLAG
RET
; TRESCK - CHECK IF THE SYSTEM HAS AT LEAST ONE OF THE TYPE OF
; TAPE DRIVE REQUESTED BY THE USER JOB
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: REQUEST CANNOT BE HANDLED BY THE SYSTEM
; +2: REQUEST CAN BE HANDLED BY THE SYSTEM
TRESCK: SAVEAC <MTA>
SAVEQ
SKIPE TSTF ;TEST MODE?
RETSKP ;YES, ALWAYS SUCCEED
MOVE Q1,MTAN ;GET # OF MTA DEVICES ON SYSTEM
MOVEI MTA,MTA0-MTASZ ;INIT MTA AC FOR STATUS BLOCK SCAN
LOAD Q2,RSBDRV ;GET REQUESTED DRIVE TYPE
; SCAN AVAILABLE TAPE DRIVES FOR ONE THAT CAN POTENTIALLY
; SATISFY THE USER TAPE MOUNT REQUEST
TRES1: SOJL Q1,R ;TAKE +1 RETURN IF NONE LEFT TO CHECK
ADDI MTA,MTASZ ;POINT AT NEXT MTA STATUS BLOCK
JE MTASTE,,TRES1 ;SKIP DRIVE IF NOT ASSIGNED TO ME
JUMPN Q2,[LOAD T1,MTADRV ;GET TYPE OF DRIVE
CAME T1,Q2 ;DOES IT MATCH WHAT THE USER WANTS?
JRST TRES1 ;NO, SKIP IT
JRST .+1]
LOAD T1,RSBDEN ;GET REQUESTED DENSITY
JUMPE T1,RSKP ;OK IF NOT PARTICULAR ABOUT DENSITY
CALL DRVDEN ;CAN THE DRIVE OPERATE AT THIS DENSITY?
JRST TRES1 ;NO, SKIP IT
RETSKP ;OK, AT LEAST 1 DRIVE CAN DO IT
; UTM - PROCESS USER TAPE MOUNT REQUEST RECEIVED THROUGH QUASAR
; 1 - ANALYZE BUILDING-BLOCK REQUEST AND BUILD RSB
; 2 - GET VOLID LIST FROM OPERATOR (IF TM%OSV SET)
; 3 - GET THE FIRST REQUESTED VOLUME MOUNTED
; T1/ ADDRESS OF TAPE MOUNT ENTRY IN IPCF MESSAGE FROM QUASAR
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: ALWAYS
UTM: MOVEI T2,BTRRTA ;TABLE OF TAPE MOUNT SUBENTRY PROCESSORS
CALL BTMRSB ;BUILD RSB FROM QUASAR MESSAGE
RET ;REQUEST ABORTED, EXIT
JXE F,TALCF,[ABTRET (MREQ26)] ;MUST HAVE ALLOCATION ENABLED
CALL TRESCK ;ARE REQUESTED TAPE RESOURCES AVAILABLE?
JRST [ ABTRET (MREQ19)] ;NO, ABORT REQUEST
CALL ACCMTR ;CREATE ACCOUNT BLOCK
JRST [ ABTRET (MREQ31)] ;ABORT REQUEST, NO BLOCKS AVAILABLE
CALL PWATCH ;TELL INFO TO WATCH USER'S PID
MOVX T1,TM%OSV
TDNN T1,RSBUFL(RSB) ;WHO IS SUPPLYING THE VOLIDS?
JRST [ CALLRET VOLMNT] ;USER, GO GET THE FIRST VOLUME MOUNTED
; GET THE VOLID LIST FROM THE OPERATOR
MOVEI T1,RST.WV ;OPERATOR IS SUPPLYING VOLIDS
STOR T1,RSBSTE ;SET STATE TO WAITING FOR VOLID KEYIN
CALL TCKP ;SEND STATUS UPDATE TO QUASAR
UTM1: JSP T1,WRUTR ;ASK OPERATOR TO KEY IN VOLID LIST
MOVEI RSB,-RSBWTB(T2) ;LOAD UP ADDR OF REQUEST STATUS BLOCK
CALL PMR ;PARSE RESPONSE TO VOLID REQUEST
JRST UTM1 ;BAD RESPONSE, TRY IT AGAIN
JUMPN T1,R ;RETURN IF REQUEST ABORTED
CALLRET VOLMNT ;GET 1ST VOLUME MOUNTED AND RETURN
SUBTTL VOLUME/REQUEST ASSOCIATION LOGIC
; MATCHR - TRY TO MATCH USER REQUEST TO TAPE VOLUME
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: ALWAYS
MATCHR: SAVEAC <MTA,Q1>
MOVE Q1,MTAN ;GET # OF MTA DEVICES ON SYSTEM
MOVEI MTA,MTA0-MTASZ ;INIT MTA AC FOR SCAN
; SCAN MTA STATUS BLOCKS FOR VOLUMES THAT CAN SATISFY THE REQUEST
MCHR1: ADDI MTA,MTASZ ;POINT AT NEXT MTA STATUS BLOCK
SOJL Q1,R ;NONE LEFT, SO SPLIT
CALL VRA ;TRY TO MATCH REQUEST TO VOLUME
JRST MCHR1 ;CAN'T, SO CONTINUE SEARCH
RET
; MATCHV - TRY TO MATCH TAPE VOLUME TO USER REQUEST
; MTA/ ADDR OF MTA STATUS BLOCK
; RETURNS +1: ALWAYS
MATCHV: SAVEQ
SAVEAC <RSB>
; PROBLEM: IF THE VOLUME IS A SCRATCH TAPE WITH A VOLID, I WANT TO
; ENSURE THAT ANY USER REQUESTING THE TAPE BY ITS VOLID GETS PRIORITY
; OVER ANY USER REQUESTING A RANDOM SCRATCH TAPE.
; SOLUTION: IMPLEMENT THE HAIRY CODE BELOW THAT PERFORMS A 2-PASS
; SEARCH OF THE RSB QUEUE WHEN THE VOLUME IS A SCRATCH TAPE. THE FIRST
; PASS (Q1/1) CHECKS ONLY RSB'S THAT ARE REQUESTING SPECIFIC (I.E.,
; NON-SCRATCH) VOLUMES. THE SECOND PASS (Q1/0) WILL CHECK ALL RSB'S. IF
; THE TAPE IS NOT A SCRATCH TAPE, ONLY THE SECOND PASS IS EXECUTED.
LOAD Q1,MA%SCR,MTAFLG(MTA) ;GET 1 IFF VOLUME IS A SCRATCH
MATV1: QSCANI ARBQDB ;SET UP TO SCAN ACTIVE RSB QUEUE
MATV2: CALL NMTRSB ;GET NEXT RSB
JRST [ SOJGE Q1,MATV1 ;MAKE 2ND PASS IF NEEDED
RET] ;ELSE RETURN
CALL VQGCV ;THIS USER WANT A SCRATCH TAPE?
SKIPN T1 ;NO
JUMPG Q1,MATV2 ;YES, BYPASS IF IN NON-SCRATCH PASS
CALL VRA ;TRY TO MATCH REQUEST TO VOLUME
JRST MATV2 ;CAN'T DO IT, CONTINUE SEARCH
RET ;REQUEST MATCHED TO VOLUME, EXIT
; MCHWMT - THIS ROUTINE IS CALLED WHEN MT DEVICES ARE FREED BY USER
; JOBS. ITS PURPOSE IS TO SCAN THE REQUEST QUEUE FOR REQUESTS
; THAT COULD NOT BE SATISFIED BECAUSE NO MT'S WERE AVAILABLE.
; RETURNS +1: ALWAYS
MCHWMT: QSCANI ARBQDB ;SET UP TO SCAN ACTIVE RSB QUEUE
SAVEAC <RSB>
TXZN F,NOMTF ;DOES AN MT SHORTAGE EXIST?
RET ;NO, NOTHING TO DO
; SCAN REQUEST QUEUE FOR REQUESTS THAT NEED MT DEVICES
MCHWM1: TXNN F,NOMTF ;EXIT IF MT SHORTAGE EXISTS
CALL NMTRSB ;GET NEXT RSB
RET ;NOTHING MORE TO DO
JN RSBMT,,MCHWM1 ;BYPASS IF HE'S GOT AN MT ALREADY
LOAD T1,RSBSTE ;GET STATE OF REQUEST
CAIE T1,RST.WM ;WAITING FOR TAPE MOUNT?
JRST MCHWM1 ;NO, DOESN'T NEED MT
CALL MATCHR ;TRY TO FIND A MATE FOR THIS REQUEST
JRST MCHWM1 ;GO ON TO NEXT REQUEST
; MOLOC - PERFORM .MOLOC MTOPR FUNCTION
; MT/ ADDR OF MT STATUS BLOCK
; MTA/ ADDR OF MTA STATUS BLOCK
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: ALWAYS
MOLASZ==10 ;SIZE OF .MOLOC ARG BLOCK
MOLOC: STKVAR <<MOLARG,MOLASZ>>
; SET UP ARGUMENT BLOCK FOR MTOPR
MOVEI T1,MOLASZ ;SET SIZE OF ARG BLOCK
MOVEM T1,.MOCNT+MOLARG
MOVE T1,MT ;GET MT STATUS BLOCK ADDR
SUBI T1,MT0 ;SUBTRACT BASE ADDRESS
IDIVI T1,MTSZ ;COMPUTE MT UNIT#
MOVEM T1,.MOMTN+MOLARG ;SET MT UNIT #
LOAD T1,RSBDEN
MOVEM T1,.MODNS+MOLARG ;SET DENSITY
MOVEI T1,MTAV1(MTA)
MOVEM T1,.MOAVL+MOLARG ;SET LABEL ADDRESS
LOAD T1,RSBCV
MOVEM T1,.MOCVN+MOLARG ;SET CURRENT VOLUME #
MOVE T1,RSBASN(RSB)
MOVEM T1,.MOVSN+MOLARG ;SET SIXBIT FILE SET IDENTIFIER
LOAD T1,RSBLT
MOVEM T1,.MOLBT+MOLARG ;SET LABEL TYPE
MOVEI T2,1 ;ASSUME EBCDIC OR ANSI
CAIN T1,.LTUNL
MOVEI T2,0 ;UNLABELED
CAIN T1,.LTT20
MOVEI T2,2 ;TOPS-20
MOVEM T2,.MONVL+MOLARG ;SET LABEL COUNT
; NOW PASS ALL THIS STUFF ON DOWN TO THE MONITOR
CALL MTAGJF ;GET JFN FOR MTOPR
MOVEI T2,.MOLOC ;GET MTOPR FUNCTION CODE
MOVEI T3,MOLARG ;ADDRESS OF ARGUMENT BLOCK
MTOPR ;PERFORM REQUESTED FUNCTION
ERCAL WOLOCF ;ERROR, DISPLAY TO OPERATOR
LOAD T1,MTAJFN ;GET JFN
MOVEI T2,.MOSID ;FUNCTION = SET VOLUME-ID
MOVE T3,MTAVOL(MTA) ;GET VOLID
MTOPR ;MAKE VOLID AVAILABLE TO USER VIA .MOINF
CALLRET MTARJF ;RELEASE JFN AND RETURN
; MTALC - ALLOC MT DEVICE TO A USER JOB
; MT/ ADDR OF MT STATUS BLOCK
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: FAILED, USER JOB DISAPPEARED
; +2: SUCCESS, MT AND RSB LINKED TO EACH OTHER
MTALC: CALL GMTDD ;GET MT DEVICE DESIGNATOR IN T1
MOVE T2,T1 ;MOVE IT TO T2 FOR ALLOC JSYS
MOVEI T1,.ALCAL ;ALLOC FUNCTION CODE
LOAD T3,RSBJNO ;GET USER'S JOB #
ALLOC ;ALLOCATE MT DEVICE TO USER JOB
JRST [ CAIE T1,ALCX4 ;INVALID JOB #?
CALL STOP ;NO, I CAN'T HANDLE THIS ERROR
ABTRET (ABRTNR)] ;ABORT - USER WENT AWAY
STOR MT,RSBMT ;STORE MT STATUS BLOCK ADDR IN RSB
STOR RSB,MTRSB ;STORE RSB ADDR IN MT STATUS BLOCK
RETSKP ;SUCCESSFUL COMPLETION
; MTGET - LOCATE A FREE MT DEVICE
; RETURNS +1: NO FREE MT'S AVAILABLE
; +2: FREE MT FOUND, MT/ ADDR OF MT STATUS BLOCK
MTGET: MOVEI MT,MT0-MTSZ ;INIT MT AC FOR STATUS BLOCK SEARCH
MOVE T1,MTN ;GET # OF MT DEVICES ON SYSTEM
MTGET1: ADDI MT,MTSZ ;POINT AT NEXT MT STATUS BLOCK
SOJL T1,[TXO F,NOMTF ;NONE LEFT, SET NONE-LEFT FLAG
RET] ;ERROR RETURN
JN MTRSB,,MTGET1 ;SKIP THIS ONE IF IT'S IN USE
RETSKP ;FREE MT FOUND
; MTRLS - PROCESS RELEASE OF MT DEVICE BY USER
; MT/ ADDR OF MT STATUS BLOCK
; RETURNS +1: ALWAYS
MTRLS: SAVEAC <RSB>
LOAD RSB,MTRSB ;GET RSB ADDRESS
JUMPE RSB,R ;EXIT IF NO RSB ASSOCIATED
CALL PLDISA ;DISASSOCIATE MT FROM MTA
SETZRO MTRSB ;CLEAR OWNER-OF-MT FIELD
CAIN RSB,MTNAV ;WAS THERE AN RSB?
RET ;NO, BYPASS RSB PROCESSING
SETZRO RSBMT ;CLEAR POINTER TO MT IN RSB
SKIPE T1,RSBWTB+WTBCOD(RSB) ;WTOR OUTSTANDING?
CALL CANWTR ;YES, CANCEL IT
TXO F,ABORTF ;FORCE A SCAN TO DUMP THE RSB
ABTRET (ABRTNR) ;GET THE REQUEST OUT OF MY QUEUES
; PLDISA - DISASSOCIATE PHYSICAL AND LOGICAL TAPE DEVICES
; MT/ ADDR OF MT STATUS BLOCK
; RETURNS +1: ALWAYS
; NOTE - IF MOUNTR CRASHES AND GETS RESTARTED, THE CURRENT MT-MTA
; ASSOCIATIONS ARE RESTORED FROM MONITOR TABLES (ASMT ROUTINE)
; BUT MTRSB WILL CONTAIN MTNAV (HENCE PLDISA CHECKS FOR THIS)
PLDISA: SAVEAC <MTA,RSB>
LOAD MTA,MTMTA ;GET MTA STATUS BLOCK ADDRESS
JUMPE MTA,R ;EXIT IF NO MTA ASSOCIATED WITH MT
LOAD RSB,MTRSB ;GET REQUEST STATUS BLOCK ADDRESS
SETZRO MTAMT ;CLEAR MTA-TO-MT LINK
SETZRO MTMTA ;CLEAR MT-TO-MTA LINK
CALL SCIENA ;GET STATUS INTERRUPTS FOR THIS DRIVE
CAIN RSB,MTNAV ;RSB ASSOCIATED?
JRST PLDISU ;NO, UNLOAD DRIVE TO PLAY IT SAFE
CALL ACCMTD ;SEND ACCOUNT INFO TO MONITOR
CALL CKMPAV ;DID OPERATOR SET MTA UNAVAILABLE?
JRST PLDISU ;YES, UNLOAD IT
JE TM%NUL,RSBUFL(RSB),PLDISU ;JUMP IF USER WANTS VOLUME UNLOADED
CALL REW ;IS MTA OFFLINE?
JRST PLDISU ;YES, NO HOPE FOR RE-USE
MOVEI T1,[ASCIZ/Remaining mounted on drive/]
CALL WODISA ;TELL OPERATOR THAT USER RELEASED TAPE
JE MA%AVS,MTAFLG(MTA),[CALLRET MATCHV] ;TRY MATCHUP IF NON-AVR
MOVX T1,MA%UXV+MA%OPF+MA%SCR
ANDCAM T1,MTAFLG(MTA) ;CLEAR SOME FLAGS
SETZRO MTALT ;CLEAR MTALT SO AVR WILL WORK
CALLRET AVR ;INITIATE AVR SEQUENCE FOR DRIVE
; AVR SEQUENCE MAY NOT BE PERFORMED UPON TAPE
PLDISU: CALL UNLOAD ;UNLOAD THE DRIVE
MOVEI T1,[ASCIZ/Being unloaded/]
CAIE RSB,MTNAV ;IF NO RSB, DON'T GIVE MESSAGE
CALL WODISA ;TELL OPERATOR THAT USER RELEASED TAPE
CALL CKMPAV ;DID OPERATOR SET MTA NOT-AVAILABLE?
CALL DACMTA ;YES, DEACTIVATE MTA
RET ;NO
; PRQABT - PURGE ABORTED REQUESTS FROM MOUNT REQUEST QUEUE
; RETURNS +1: ALWAYS
PRQABT: QSCANI ARBQDB ;SET UP TO SCAN ACTIVE RSB QUEUE
SAVEAC <RSB>
; SEARCH MOUNT REQUEST QUEUE AND EXTRACT ABORTED REQUESTS
PRQAB1: CALL QMSCAN ;GET ADDRESS OF NEXT RSB ON QUEUE
RET ;NONE LEFT, EXIT
MOVEI RSB,-RSBLNK(T2) ;LOAD RSB AC WITH RSB ADDRESS
CALL CHKAB ;REQUEST ABORTED?
SKIPA ;YES
JRST PRQAB1 ;NO, SKIP IT
LOAD T1,RSBTYP ;GET TYPE OF REQUEST
CAIN T1,.MNTTP ;TAPE MOUNT?
JRST [ JN RSBMT,,PRQAB1 ;YES, SKIP IF USER STILL HAS MT DEVICE
CALL VQDEL ;RELEASE VOLID LIST
JRST .+1] ;CONTINUE DELETION LOGIC
; DEQUEUE AND DISCARD ABORTED RSB
SKIPE RSBWTB+WTBCOD(RSB) ;IS WTB ACTIVE?
CALL STOP ;YES, CRASH!!!
MOVX T1,R%OPR
TDNN T1,RSBIFL(RSB) ;WAS THIS REQUEST FROM OPR?
CALL RLSMSG ;NO, TELL QUASAR TO RELEASE THIS ITN
CALL QMDQS ;DEQUEUE RSB, GET LINKAGE ADDR IN T2
MOVEI T1,IRBQDB ;GET QDB ADDRESS
CALL QMQH ;QUEUE RSB TO HEAD OF INACTIVE QUEUE
JRST PRQAB1 ;CONTINUE SCAN OF RSB QUEUE
; PRQPID - PURGE REQUESTS FROM MOUNT REQUEST QUEUE WHOSE OWNERS
; HAVE DELETED THEIR PIDS BEFORE THE FIRST VOLUME WAS MOUNTED
; RETURNS +1: ALWAYS
PRQPID: QSCANI ARBQDB ;SET UP TO SCAN ACTIVE RSB QUEUE
SAVEAC <RSB>
PURGR1: CALL QMSCAN ;GET ADDR OF NEXT RSB IN T2
RET ;END OF RSB QUEUE, EXIT
MOVEI RSB,-RSBLNK(T2) ;COPY RSB ADDRESS TO RSB AC
CALL CHKAB ;REQUEST ABORTED?
JRST PURGR1 ;YES, SKIP IT
CALL VALPID ;CHECK PID
JFCL ;REQUEST ABORTED
JRST PURGR1 ;CONTINUE SEARCH
; VALPID - ABORT REQUEST IF PID IS DELETED
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: REQUEST ABORTED BECAUSE USER PID WAS DELETED
; +2: REQUEST NOT ABORTED
VALPID: LOAD T1,RSBTYP
CAIN T1,.MNTTP ;TAPE REQUEST?
JRST [ JE RSBMT,,.+1 ;YES, DOES THE USER HAVE AN MT?
RETSKP] ;YES, DON'T DO PID CHECK
CAIN T1,.MNTDT ;DECTAPE-MOUNT REQUEST?
SKIPN RSBDTA(RSB) ;DOES USER HAVE THE DTA?
SKIPA ;NO TO EITHER
RETSKP ;USER HAS DECTAPE, PRESERVE REQUEST
MOVEI T1,.MUFOJ
MOVE T2,RSBPID(RSB) ;GET USER'S PID
CALL XMUTIL ;IS IT STILL VALID?
JRST [ CALL WORCAN ;NO, TELL OPERATOR REQ WAS CANCELED
ABTRET (ABRTNR)] ;ABORT REQUEST
RETSKP ;PID STILL GOOD
; VOLMNT - ATTEMPT TO MATCH REQUEST WITH MOUNTED VOLUME; IF THIS IS
; NOT POSSIBLE, THE OPERATOR IS TOLD TO MOUNT THE VOLUME
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: ALWAYS
VOLMNT: CALL VQCNT ;GET # OF VOLUMES IN SET IN T1
LOAD T2,RSBCV ;GET CURRENT VOLUME #
MOVX T3,R%WVL
TDNN T3,RSBIFL(RSB) ;NEED TO ASK OPERATOR FOR NEXT VOLID?
CAMG T2,T1
SKIPA T1,[RST.WM] ;NO
JRST [ MOVEI T1,RST.WV ;YES
STOR T1,RSBSTE ;SET STATE TO WAITING FOR VOLID KEYIN
CALL TCKP ;TELL QUASAR
MOVEI T1,VOLMT2 ;GET END-ACTION ADDRESS
CALLRET WRNXTV] ;GO ASK FOR NEXT VOLID
STOR T1,RSBSTE ;SET STATE TO WAITING FOR TAPE MOUNT
SETZRO R%ONR,RSBIFL(RSB) ;CLEAR OPERATOR-NOTIFIED FLAG
CALL TCKP ;SEND CHECKPOINT MESSAGE TO QUASAR
CALL MATCHR ;MATCH REQUEST TO VOLUME
CALL CHKAB ;REQUEST ABORTED?
RET ;YES, BACK TO CALLER
LOAD T1,RSBSTE ;GET STATE TO SEE WHAT MATCHR DID
CAIE T1,RST.WM ;STILL WAITING FOR A MOUNT?
RET ;NO, EXIT
CALLRET WOVMT ;TELL OPERATOR TO MOUNT VOLUME
; PROCESS RESPONSE TO WTOR ASKING OPERATOR TO SUPPLY NEXT VOLID
VOLMT2: MOVEI RSB,-RSBWTB(T2) ;LOAD RSB AC
CALL PNVR ;PARSE RESPONSE
JRST [ MOVEI T1,VOLMT2 ;BAD RESPONSE, GET END-ACTION ADDRESS
CALLRET WRNXTV] ;LET HIM TRY IT AGAIN
JUMPN T1,R ;RETURN NOW IF REQUEST ABORTED
JRST VOLMNT ;GOT THE VOLID, NOW GO GET IT MOUNTED
; VOLSW - PERFORM TAPE VOLUME-SWITCH
; T1/ ABSOLUTE VOLUME NUMBER TO SWITCH TO
; MT/ ADDR OF MT STATUS BLOCK
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: ALWAYS
VOLSW: SAVEAC <MTA>
STAKT
LOAD T2,RSBCV ;GET CURRENT VOLUME #
CAMN T1,T2 ;SWITCHING TO SAME VOLUME?
JRST [ LOAD MTA,MTMTA ;YES, GET MTA STATUS BLK ADDR
CALLRET MOLOC] ;HOOK UP MT&MTA AGAIN
CALL PLDISA ;DISASSOCIATE MTA FROM MT
CALL VQCNT ;GET # OF VOLUMES IN SET
ADDI T1,1 ;ADD 1 IN CASE EXPANDING VOLUME SET
SKIPLE T2,CT1 ;ERROR IF GOING TO VOLUME BEFORE FIRST
CAMLE T2,T1 ;ERROR IF GOING BEYOND END OF SET
JRST [ ABTRET (MREQX8)] ;ATTEMPT TO SWITCH TO VOL OUTSIDE SET
STOR T2,RSBCV ;SET CURRENT VOLUME # IN RSB
CALLRET VOLMNT ;GET THE REQUESTED VOLUME MOUNTED
; VRA - ASSOCIATE USER REQUEST AND TAPE VOLUME (IF POSSIBLE)
; MTA/ ADDR OF MTA STATUS BLOCK OF DRIVE TO BE CHECKED
; RSB/ ADDR OF USER REQUEST STATUS BLOCK
; RETURNS +1: FAILED, REQUEST MAY BE ABORTED
; +2: SUCCESS, MT/ ADDR OF MT STATUS BLOCK
VRA: SAVEQ
MOVE T1,MTAFLG(MTA)
LOAD T2,MTASTE
CAIN T2,S.AV ;INELIGIBLE IF DRIVE NOT AVAIL TO USERS
TXNN T1,MA%LOD ;INELIGIBLE IF DRIVE NOT LOADED
RET
SKIPN MTAVOL(MTA) ;IS VOLUME IDENTIFIED?
TXNE T1,MA%SCR ; OR SCRATCH?
SKIPA ;YES TO EITHER, PROCEED
RET ;BOTH NO
JN MTAJCT,,R ;INELIGIBLE IF AVR IN PROGRESS
JN MTAMT,,R ;INELIGIBLE IF DRIVE IN USE
LOAD T1,RSBSTE ;GET STATE OF REQUEST
CAIE T1,RST.WM ;WAITING FOR VOLUME TO BE MOUNTED?
RET ;NO
; REQUEST AND DRIVE ARE IN THE PROPER STATES... A GOOD SIGN
MOVEI Q1,VRACCN ;ASSUME NOT REQUESTING SCRATCH
CALL VQGCV ;GET CURRENT VOLID IN T1
SKIPN T1 ;WANT SCRATCH VOLUME?
MOVEI Q1,VRACCS ;YES, CALL SCRATCH ROUTINE
CALL (Q1) ;CALL APPROPRIATE ROUTINE
RET ;WRONG VOLUME OR REQUEST ABORTED
; MISCELLANEOUS CHECKS BEFORE I ASSIGN AN MT TO THE USER
CALL VALPID ;CHECK FOR DELETED PID
RET ;REQUEST ABORTED
CALL REW ;CHECK IF DRIVE IS REALLY LOADED
RET ;NO, DON'T ASSIGN
LOAD T1,MA%WEN,MTAFLG(MTA) ;GET DRIVE WRITE STATUS
LOAD T2,TM%WEN,RSBUFL(RSB) ;GET REQUESTED WRITE STATUS
CAME T1,T2 ;DO DRIVE AND USER AGREE?
JRST [ CALL UNLOAD ;NO, UNLOAD THE DRIVE
CALLRET WOWPE] ;TELL THE OPERATOR TO FIX IT
; GET MT DEVICE FOR THIS REQUEST IF IT DOESN'T ALREADY HAVE ONE
LOAD MT,RSBMT ;GET MT STATUS BLOCK ADDRESS
JUMPE MT,[CALL MTGET ;NO MT YET, ANY MT'S AVAILABLE?
RET ;NO, FAILED
JRST .+1] ;MT AC LOADED (NOT ALLOC'ED YET)
CALL VQCNT ;GET # OF VOLIDS IN REQUEST
LOAD T2,RSBCV ;GET CURRENT VOLUME #
CAMGE T1,T2 ;ASSIGNING SCRATCH TAPE TO USER?
JRST [ MOVE T1,MTAVOL(MTA) ;YES, GET VOLID OF TAPE
CALL VQADD ;TACK VOLID ON THE END OF LIST
RET ;REQUEST ABORTED (RESOURCES EXHAUSTED)
JRST .+1]
; PUT VALUES IN DEFAULTED RSB FIELDS (DENSITY, DRIVE-TYPE, LABEL-TYPE)
LOAD T1,MTADRV ;DRIVE-TYPE
LOAD T2,RSBDRV
SKIPN T2
STOR T1,RSBDRV
LOAD T1,MTALT ;LABEL-TYPE
LOAD T2,RSBLT
SKIPN T2
STOR T1,RSBLT
LOAD T1,RSBLT ;DENSITY
CAIE T1,.LTUNL ;LABELED?
JRST [ LOAD T1,MTADEN ;YES
LOAD T2,RSBDEN
SKIPN T2
STOR T1,RSBDEN
MOVX T1,MA%SCR
MOVX T2,R%WVL
TDNE T1,MTAFLG(MTA) ;SCRATCH TAPE?
IORM T2,RSBIFL(RSB) ;YES, INSURE LABELS GET REWRITTEN
CALL LTINIT ;WRITE LABELS IF NECESSARY
RET ;ERROR
JRST .+1]
; ALLOC THE MT TO THE USER (HAPPENS WHEN MOUNTING THE FIRST TAPE OF SET)
LOAD Q1,RSBMT ;HAVE I ALLOC'ED THE MT TO THE USER YET?
JUMPE Q1,[CALL MTALC ;NO, ALLOC MT TO USER
RET ;ALLOC FAILED (USER DISAPPEARED)
JRST .+1] ;MT DEVICE ALLOC'ED TO USER JOB
; MT DEVICE ASSIGNED TO USER JOB - ASSOCIATE MTA WITH MT
MOVE T1,MTASET(MTA) ;GET SETNAME FROM TAPE
SKIPN RSBASN(RSB) ;DOES THIS REQUEST HAVE A SETNAME YET?
MOVEM T1,RSBASN(RSB) ;NO, USE SETNAME FROM HDR1 ON TAPE
CALL MOLOC ;ISSUE JSYS TO ASSOCIATE MT WITH MTA
CALL SCIDIS ;DON'T TAKE INTERRUPTS FROM THIS MTA
SKIPN Q1 ;WAS MT DEVICE JUST GIVEN TO USER?
CALL TELUSR ;YES, SEND IPCF CONFIRMATION MSG TO USER
; PERFORM MISCELLANEOUS POST-ASSOCIATION TASKS
GTAD
LOAD ACC,RSBACC ;GET ADDRESS OF ACCOUNT BLOCK
MOVEM T1,ACCSVT(ACC) ;STORE SERVICED-TIME
SKIPE T1,RSBWTB+WTBCOD(RSB) ;WTOR MESSAGE OUTSTANDING?
CALL CANWTR ;YES, CANCEL IT
MOVEI T1,RST.AC
STOR T1,RSBSTE ;SET STATE TO ACTIVE
STOR MT,MTAMT ;PUT MT STATUS BLK ADDR IN MTA STAT BLK
STOR MTA,MTMTA ;PUT MTA STATUS BLK ADDR IN MT STAT BLK
CALL TCKP ;TELL QUASAR ABOUT STATE CHANGE
MOVX T1,MA%SCR
ANDCAM T1,MTAFLG(MTA) ;NOT SCRATCH AFTER I GIVE IT TO USER
CALL WOASO ;TELL OPERATOR ABOUT ASSOCIATION
RETSKP
; VRACCN - CHECK COMPATIBILITY OF NON-SCRATCH REQUEST AND TAPE VOLUME
; T1/ SIXBIT VOLID BEING REQUESTED
; MTA/ ADDR OF MTA STATUS BLOCK
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: NOT COMPATIBLE OR REQUEST ABORTED
; +2: COMPATIBLE
VRACCN: SAVEQ
CAME T1,MTAVOL(MTA) ;DO I HAVE THE RIGHT VOLUME?
RET ;NO
LOAD T1,RSBDRV ;DID USER SPECIFY A DRIVE TYPE?
JUMPN T1,[LOAD T2,MTADRV ;YES, GET ACTUAL DRIVE TYPE
CAMN T1,T2 ;DO THEY MATCH?
JRST .+1 ;YES
ABTRET (MREQ11)] ;NO, ABORT REQUEST
JN TM%BYP,RSBUFL(RSB),VRACN3 ;IF BYPASS, JUST CHECK DENSITY
JE MTALT,,[LOAD Q1,MA%AVE,MTAFLG(MTA) ;TAPE NOT AVR'ED YET
SETONE MA%AVE,MTAFLG(MTA) ;FORCE AVR
CALL AVR ;INITIATE AVR SEQUENCE
STOR Q1,MA%AVE,MTAFLG(MTA) ;RESTORE AVR-ENABLED FLAG
RET] ;YOU HAVE TO WAIT UNTIL AVR IS DONE
JN R%WVL,RSBIFL(RSB),VRACN2 ;SPECIAL CASE IF WRITING VOL LABELS
LOAD T1,RSBLT ;CHECK LABEL TYPES
LOAD T2,MTALT
JUMPN T1,[CAMN T1,T2 ;USER SPECIFIED LT, DOES IT MATCH TAPE?
JRST .+1 ;YES, PROCEED
ABTRET (MREQ12)] ;NO, LABEL TYPE MISMATCH
CAIN T2,.LTUNL ;WHAT KIND OF REQUEST?
JRST VRACN3 ;UNLABELED, CHECK DRIVE CAPABILITIES
LOAD T1,RSBDEN ;DID USER SPECIFY DENSITY?
JUMPN T1,[LOAD T2,MTADEN ;YES, GET DENSITY OF TAPE
CAMN T1,T2 ;DO REQUEST AND TAPE DENSITIES MATCH?
JRST .+1 ;YES, PROCEED
ABTRET (MREQ10)] ;MISMATCHED DENSITY
MOVX T1,TM%VFY
TDNE T1,RSBUFL(RSB) ;CHECKING SETNAME OF LABELED TAPE?
JRST [ MOVE T1,RSBSSN(RSB) ;YES, GET SETNAME FROM RSB
CAMN T1,MTASET(MTA) ;DOES IT MATCH SETNAME OF VOLUME?
JRST .+1 ;YES
ABTRET (MREQ14)] ;MISMATCHED SET NAME
RETSKP
; REWRITING VOLUME LABELS
VRACN2: CALL VRWLT ;LABEL TYPES COMPATIBLE?
JRST [ ABTRET (MREQ12)] ;NO, LABEL TYPE MISMATCH
; MAKE SURE THE DRIVE WILL HANDLE THE REQUESTED DENSITY
VRACN3: LOAD T1,RSBDEN ;ANY DENSITY SPECIFIED?
JUMPE T1,RSKP ;NO, IT'S OK
CALL DRVDEN ;WILL THE DRIVE HANDLE IT?
JRST [ CALL UNLOAD ;NO, UNLOAD IT
CALLRET WOWDDR] ;TELL OPERATOR AND POSTPONE REQUEST
RETSKP ;DRIVE CAN HANDLE THE DENSITY, OK
; VRACCS - CHECK COMPATIBILITY OF SCRATCH REQUEST AND TAPE VOLUME
; MTA/ ADDR OF MTA STATUS BLOCK
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: NOT COMPATIBLE
; +2: COMPATIBLE
VRACCS: JE MA%SCR,MTAFLG(MTA),R ;REJECT VOLUME IF NOT A SCRATCH
LOAD T1,RSBDRV ;GET REQUESTED DRIVE TYPE
JUMPN T1,[LOAD T2,MTADRV ;GET DRIVE-TYPE OF DRIVE
CAME T1,T2 ;SAME DRIVE TYPE?
RET ;NO
JRST .+1]
LOAD T1,RSBDEN ;GET REQUESTED DENSITY
JUMPN T1,[CALL DRVDEN ;CAN THE DRIVE OPERATE AT THIS DENSITY?
RET ;NO, THIS SCRATCH WON'T WORK
JRST .+1]
CALLRET VRWLT ;CHECK IF LABEL TYPES ARE COMPATIBLE
; VRWLT - TAPE VOLUME LABELS WILL BE REWRITTEN - CHECK IF LABEL TYPES
; OF REQUEST AND VOLUME ARE COMPATIBLE
; MTA/ ADDR OF MTA STATUS BLOCK
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: LABELED-UNLABELED OR UNLABELED-LABELED
; +2: UNLABELED-UNLABELED OR LABELED-LABELED
VRWLT: LOAD T1,RSBLT ;GET REQUESTED LABEL TYPE
JUMPE T1,RSKP ;NOT PARTICULAR, THIS ONE WILL DO
LOAD T2,MTALT ;GET LABEL TYPE OF TAPE
MOVE T3,[CAIE T2,.LTUNL] ;ASSUME HE WANTS UNLABELED SCRATCH
CAIE T1,.LTUNL ;RIGHT?
HRLI T3,(CAIN T2,) ;NO, WANTS LABELED
XCT T3 ;COMPARE REQUEST AND VOLUME
RET ;UNLABELED-LABELED OR LABELED-UNLABELED
RETSKP ;LABELED-LABELED OR UNLABELED-UNLABELED
SUBTTL SUBROUTINES
; ACTMTA - ACTIVATE AN MTA DEVICE (INITIALIZE STATUS BLOCK, ETC.)
; MTA/ ADDR OF MTA STATUS BLOCK
; T1/ MTA STATE CODE
; RETURNS +1: MTA ASSIGNED TO ANOTHER JOB T1/ OWNING JOB #
; +2: SUCCESS, MTA ACTIVATED
ACTMTA: STKVAR <ACTCOD,<MTOBLK,MOSTAL>>
MOVEM T1,ACTCOD ;SAVE STATE CODE
JN MTASTE,,RSKP ;RETURN GOOD IF ALREADY ACTIVATED
; ASSIGN MTA TO MY JOB
CALL GMTADD ;GET DEVICE DESIGNATOR
ASND ;TRY TO ASSIGN DEVICE TO MY JOB
JRST [ CALL GMTADD ;GET DESIGNATOR
DVCHR
HLRZ T1,T3 ;GET T1/ OWNER'S JOB#
RET]
; INITIALIZE MTA STATUS BLOCK AND ENABLE FOR STATUS-CHANGE INTERRUPT
SETZM (MTA) ;ZERO 1ST WORD OF STATUS BLOCK
MOVS T1,MTA ;BLT SOURCE
HRRI T1,1(MTA) ;BLT DESTINATION
BLT T1,MTASZ-1(MTA) ;CLEAR ENTIRE STATUS BLOCK
MOVE T1,ACTCOD
STOR T1,MTASTE ;SET STATE
CALL SCIENA ;RECEIVE STATUS CHANGE INTERRUPTS
MOVEI T1,MTOBLK ;GET MOSTA ARG BLOCK ADDRESS
CALL MOSTA ;GET MTA STATUS & CHARACTERISTICS
MOVE T1,.MODDN+MTOBLK ;GET SUPPORTED DENSITIES
HLLM T1,MTASDN(MTA) ;STORE SUPPORTED DENSITIES
LOAD T1,SJ%7TR,.MOTRK+MTOBLK ;GET 7-TRACK FLAG
MOVE T2,[EXP .TMDR9,.TMDR7](T1) ;GET DRIVE TYPE CODE
STOR T2,MTADRV ;STORE DRIVE TYPE IN STATUS BLOCK
TRC T1,1 ;GET 0 FOR 7-TRACK, 1 FOR 9-TRACK
STOR T1,MA%AVS,MTAFLG(MTA) ;STORE AVR-SUPPORTED FLAG
CALL AVRENA ;ENABLE AVR (IF LEGAL)
RETSKP
; AREQ - DRIVER FOR ABTREQ MACRO, ABORTS USER REQUEST
; ARET - DRIVER FOR ABTRET MACRO, ABORTS REQUEST AND DOES RET
; RSB/ ADDR OF REQUEST STATUS BLOCK
; CALL: ABTREQ (abortcode,flags)
; OR
; ABTRET (abortcode,flags)
AREQ: SKIPA T2,[AOS (P)] ;GET AREQ INSTRUCTION
ARET: MOVE T2,[ADJSP P,-1] ;GET ARET INSTRUCTION
MOVE T1,@(P) ;GET FLAGS AND CODE
XCT T2 ;EXECUTE INSTRUCTION BASED ON ENTRY
SAVEAC <MT>
HRRZ T2,T1 ;GET CODE
TXNE T1,ABT%IN ;INDIRECT?
MOVE T2,(T2) ;YES, GET CODE FROM LOCATION
LOAD T3,RSBSTE ;GET CURRENT STATE OF REQUEST
CAIE T2,ABRTNR ;FORCE STORE IF NO-REPLY ABORT
CAIGE T3,.ERBAS ;STORE IF REQUEST NOT ABORTED YET
JRST [ STOR T2,RSBSTE ;STORE CODE INTO RSB STATE FIELD
LOAD T2,ABT%OP,T1 ;GET OPERATOR-RESPONSE-PRESENT FLAG
STOR T2,R%ORES,RSBIFL(RSB) ;COPY FLAG TO RSB
LOAD T1,RSBTYP ;GET REQUEST TYPE
CAIE T1,.MNTTP ;TAPE-MOUNT?
JRST .+1 ;NO
JE RSBMT,,.+1 ;DON'T UPDATE STATUS IF RSB GOING AWAY
CALL TCKP ;UPDATE QUASAR QUEUE DISPLAY
JRST .+1]
SKIPE T1,RSBWTB+WTBCOD(RSB) ;WTOR MESSAGE OUTSTANDING?
CALL CANWTR ;YES, CANCEL IT
TXO F,ABORTF ;FORCE PURGE UPON RETURN TO SCHEDULER
LOAD T1,RSBSTE ;GET REQUEST STATE
MOVE T2,RSBIFL(RSB) ;GET INTERNAL REQUEST FLAGS
TXNN T2,R%OPR ;DON'T REPLY TO OPR-ORIGINATED REQUEST
CAIN T1,ABRTNR ;DON'T REPLY IF NO-REPLY REQUESTED
RET
LOAD T1,RSBTYP
CAIE T1,.MNTTP ;TAPE RSB?
JRST [ CALLRET TELUSR] ;NO, TELL USER VIA IPCF
JE RSBMT,,[CALLRET TELUSR] ;TELL USER ON 1ST VOLUME
CALLRET TELMON ;OTHERWISE TELL MONITOR TO TELL USER
; ASMT - PLACE MT DEVICES IN THE DEVICE ALLOCATOR'S POOL
; CALLED DURING INITIALIZATION
; RETURNS +1: ALWAYS
ASMT: SAVEQ
SAVEAC <MT,MTA>
MOVSI Q1,-MAXMT ;RH(Q1)/ MT UNIT NUMBER
MOVEI MT,MT0 ;ADDRESS OF FIRST MT STATUS BLOCK
; LOOP TO PLACE ALL MT DEVICES IN THE DEVICE ALLOCATOR'S POOL
ASMT1: SETZM (MT) ;CLEAR FIRST WORD OF MT STATUS BLOCK
IFG MTSZ-1,<
MOVS T1,MT ;BLT SOURCE
HRRI T1,1(MT) ;BLT DESTINATION
BLT T1,MTSZ-1(MT) ;CLEAR REMAINDER OF MT STATUS BLOCK
>
CALL GMTDD ;GET MT DEVICE DESIGNATOR IN T1
DVCHR ;IS THIS A VALID DESIGNATOR?
ERJMP ASMT2 ;NO, SKIP NON-DEVICE
HRRZM Q1,MTN ;SET HIGHEST MT UNIT NUMBER
MOVE T2,T1 ;MOVE DESIGNATOR TO T2 FOR ALLOC
MOVEI T1,.ALCAL ;GET ALLOC FUNCTION CODE
MOVNI T3,1 ;RELEASE DEVICE TO FREE POOL
ALLOC ;TRY TO FREE UP THE DEVICE
MOVEI T1,.ALCAL ;IGNORE ERROR, RESTORE T1
MOVNI T3,2 ;ASSIGN MT TO ALLOCATOR'S POOL
ALLOC ;TRY TO ASSIGN TO ALLOCATOR
SKIPA ;FAILED
JRST ASMT2 ;ASSIGNED TO ALLOCATOR, GO DO NEXT MT
; CANNOT PUT MT IN ALLOCATOR'S POOL, SO THIS IS PROBABLY A RESTART
; AND THE MT IS STILL IN A USER'S POSSESSION. THE LOGIC HERE FINDS
; OUT WHAT MTA DEVICE IS ASSOCIATED WITH THE MT, LINKS THEM UP, AND
; BUSYS THEM OUT UNTIL THE USER RELEASES THE MT.
MOVEI T1,MTNAV ;CAN'T GET CONTROL OF MT
STOR T1,MTRSB ;RSB ADDR NON-0 TO PREVENT ALLOCATION
MOVEI T1,.MTASI ;GET MTU FUNCTION CODE
HRRZ T2,Q1 ;GET MT UNIT #
MOVEI T3,Q2 ;GET ARGUMENT BLOCK ADDRESS (Q2,Q3)
MOVEI Q2,2 ;SET LENGTH IN ARG BLOCK
MTU% ;ASK MONITOR FOR ASSIGNMENT INFO
CAIN Q3,.MTNUL ;ANY MTA ASSIGNED TO THIS MT?
JRST ASMT2 ;NO
MOVE T1,Q3 ;GET MTA UNIT #
HRLI T1,.DVDES+.DVMTA ;MAKE DESIGNATOR
CALL DDMTA ;GET MTA STATUS BLOCK ADDRESS IN MTA
CALL STOP ;BAD MTA UNIT # FROM MONITOR
MOVEI T1,S.AV ;GET AVAILABLE-TO-USER STATE
CALL ACTMTA ;ACTIVATE MTA IF POSSIBLE
JRST ASMT2 ;CAN'T, SO DON'T CROSS-LINK
STOR MT,MTAMT ;ASSOCIATE MT WITH MTA
STOR MTA,MTMTA ;...
SETONE MA%LOD,MTAFLG(MTA) ;SET DRIVE-LOADED FOR KSHS
ASMT2: ADDI MT,MTSZ ;POINT AT NEXT MT STATUS BLOCK
AOBJN Q1,ASMT1 ;LOOP THRU ALL POSSIBLE MT'S
AOS MTN ;CONVERT HIGHEST UNIT# TO # OF DEVICES
RET
; ASMTA - ASSIGN MTA DEVICES TO THIS JOB
; CALLED DURING INITIALIZATION
; RETURNS +1: ALWAYS
ASMTA: SAVEAC <MTA,Q1>
MOVSI Q1,-MAXMTA ;# OF MTA DEVICES I CAN HANDLE
MOVEI MTA,MTA0 ;ADDRESS OF MTA0: STATUS BLOCK
; LOOP TO CHECK AND POSSIBLY ACTIVATE EVERY MTA DEVICE ON THE SYSTEM
ASMTA1: SETZRO MTASTE ;SET DRIVE NOT ASSIGNED
CALL GMTADD ;GET MTA DEVICE DESIGNATOR IN T1
DVCHR ;IS THIS A VALID DESIGNATOR?
ERJMP ASMTA2 ;NO, SKIP NON-DEVICE
HRRZM Q1,MTAN ;STORE HIGHEST MTA UNIT #
CALL CKMPAV ;IS THIS DRIVE SET AVAILABLE?
JRST ASMTA2 ;NO, DON'T ASSIGN IT
MOVEI T1,S.AV ;GET AVAILABLE-TO-USER STATE
CALL ACTMTA ;ACTIVATE THE MTA
JFCL ;DON'T CARE IF I CAN'T ASND
ASMTA2: ADDI MTA,MTASZ ;POINT AT NEXT MTA STATUS BLOCK
AOBJN Q1,ASMTA1 ;LOOP THROUGH ENTIRE DEVICE TABLE
AOS MTAN ;CONVERT HIGHEST UNIT# TO # OF DEVICES
RET
; ASCIZL - COMPUTE THE LENGTH OF AN ASCIZ STRING (NOT COUNTING NULL)
; T1/ ADDRESS OF STRING
; RETURNS +1: ALWAYS, WITH LENGTH IN BYTES IN T2
ASCIZL: HRLI T1,(POINT 7) ;CONSTRUCT BYTE POINTER
SETZ T2, ;CLEAR COUNTER
ASCIL1: ILDB T3,T1 ;LOAD A BYTE
JUMPE T3,R ;EXIT IF END OF STRING
AOJA T2,ASCIL1 ;OTHERWISE, COUNT IT AND LOOP
; AVRENA - ENABLE AVR FOR DRIVE (IF AVR SUPPORTED FOR THIS DRIVE TYPE)
; MTA/ ADDR OF MTA STATUS BLOCK
; RETURNS +1: ALWAYS
AVRENA: MOVX T1,MA%AVS
TDNN T1,MTAFLG(MTA) ;AVR SUPPORTED FOR THIS DRIVE?
RET ;NO
MOVX T1,MA%AVE
IORM T1,MTAFLG(MTA) ;SET AVR-ENABLED
RET
; BLKFND - SEARCH A GALAXY-STYLE BUILDING BLOCK ARGUMENT LIST FOR
; THE LAST OCCURRENCE OF A SPECIFIED ARGUMENT TYPE
; T1/ ADDRESS OF ARGUMENT COUNT WORD
; T2/ ADDRESS OF FIRST ARGUMENT BLOCK
; T3/ TYPE CODE OF DESIRED ARGUMENT
; RETURNS +1: NO ARGUMENTS OF REQUESTED TYPE FOUND
; +2: SUCCESS, T1/ ADDRESS OF FIRST WORD OF ARGUMENT
; T2/ LENGTH OF ARGUMENT (NOT COUNTING HEADER)
BLKFND: STKVAR <GETLA>
SETZM GETLA ;CLEAR ADDRESS OF LAST MATCHING HDR
SKIPG T1,(T1) ;GET # OF ARGUMENTS
RET ;NONE ???
BLKFN1: LOAD T4,AR.TYP,(T2) ;GET ARGUMENT TYPE CODE
CAMN T3,T4 ;DOES IT MATCH THE ONE I WANT?
MOVEM T2,GETLA ;YES, SAVE ITS ADDRESS
LOAD T4,AR.LEN,(T2) ;GET LENGTH OF THIS ENTRY
ADD T2,T4 ;COMPUTE ADDRESS OF NEXT ENTRY
SOJG T1,BLKFN1 ;LOOP UNTIL ARG COUNT EXHAUSTED
SKIPN T1,GETLA ;SCAN COMPLETE, ANY MATCHES?
RET ;NO
LOAD T2,AR.LEN,(T1) ;YES, GET SIZE OF ENTRY & HDR
SOS T2 ;SUBTRACT SIZE OF HEADER
AOJA T1,RSKP ;POINT T1 AT 1ST DATA WORD & RETURN
; CHKAB - CHECK IF MOUNT REQUEST IS ABORTED
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: REQUEST IS ABORTED
; +2: REQUEST IS NOT ABORTED
CHKAB: LOAD T1,RSBSTE ;GET STATE
CAIL T1,.ERBAS ;ABORTED?
RET ;YES
RETSKP ;NO
; CHKID - DETERMINE IF A WORD QUALIFIES AS A LEGAL SIXBIT VOLID/SETNAME
; T1/ WORD TO BE TESTED
; RETURNS +1: NOT A LEGAL VOLID/SETNAME
; +2: LEGAL VOLID SETNAME T1/ PRESERVED
CHKID: SKIPN T2,T1 ;COPY WORD TO PRESERVE T1
RET ;ALL BLANKS - ILLEGAL
CHKID1: SETZ T3, ;CLEAR T3 FOR ROTATING
ROTC T2,6 ;MOVE A CHARACTER FROM T2 INTO T3
ADJBP T3,[POINT 1,CHKCHR,0] ;GET BYTE POINTER TO BIT
LDB T3,T3 ;IS THIS A LEGAL CHARACTER?
JUMPE T3,R ;NO, ERROR RETURN
JUMPN T2,CHKID1 ;LOOP IF MORE CHARACTERS LEFT IN T2
RETSKP ;LOOKS OK TO ME
; TABLE OF LEGAL CHARACTERS FOR VOLIDS AND SETNAMES
CHKCHR: ^B111001111111111111111111111111110111 ;40-103
^B111111111111111111111110000000000000 ;104-147
; CKBSTR - CHECK GALAXY BUILDING BLOCK STRUCTURE TO VERIFY THAT ALL
; BUILDING BLOCKS LIE WITHIN THE STRUCTURE
; T1/ ENTRY COUNT
; T2/ ADDRESS OF FIRST ENTRY
; T3/ SIZE OF STRUCTURE
; RETURNS +1: ERROR WAS DETECTED
; +2: NO ERROR DETECTED
CKBSTR: JUMPL T1,R ;NEGATIVE ENTRY COUNT IS AN ERROR
JUMPL T3,R ;NEGATIVE STRUCTURE SIZE ALSO AN ERROR
JUMPE T1,RSKP ;ZERO ENTRY COUNT IS OK
CKBST1: LOAD T4,AR.LEN,(T2) ;GET SIZE OF THIS ENTRY
JUMPE T4,R ;ENTRY MUST HAVE A NON-ZERO SIZE
SUB T3,T4 ;SUBTRACT FROM REMAINING STRUCTURE SIZE
JUMPL T3,R ;ERROR IF BLOCK EXTENDS BEYOND END
ADD T2,T4 ;POINT T2 AT NEXT BLOCK
SOJG T1,CKBST1 ;LOOP THROUGH ALL BLOCKS
RETSKP ;LOOKS OK TO ME
; CKGHDR - PERFORM BASIC CONSISTENCY CHECK ON INCOMING GALAXY MESSAGE
; RBUF, MRPDB/ MESSAGE AND PDB
; RETURNS +1: ERROR IN HEADER
; +2: HEADER OK, T1/ SIZE OF MESSAGE IN WORDS
; T2/ MESSAGE TYPE
CKGHDR: HLRZ T2,MRPDB+.IPCFP ;GET ACTUAL SIZE OF MESSAGE FROM PDB
LOAD T1,MS.CNT,RBUF+.MSTYP ;GET SIZE OF MESSAGE FROM GLX HEADER
CAIL T1,MSHSIZ ;CRASH IF MSG DOESN'T CONTAIN FULL HDR
CAMGE T2,T1 ;IS MSG AS BIG AS ITS HEADER CLAIMS?
RET ;NO, ERROR IN HEADER
LOAD T2,MS.TYP,RBUF+.MSTYP ;GET MESSAGE TYPE FOR CALLER
RETSKP
; CKMPAV - TEST IF TAPE DRIVE IS AVAILABLE FOR USE BY SYSTEM
; BY CHECKING STATUS BIT IN DEVICE-STATUS FILE ENTRY
; MTA/ ADDR OF MTA STATUS BLOCK
; RETURNS +1: DRIVE NOT AVAILABLE
; +2: DRIVE AVAILABLE
CKMPAV: CALL GMTADD ;GET T1/ MTA DEVICE DESIGNATOR
CALL DSFTGT ;GET DEVICE STATUS FILE ENTRY FOR DRIVE
MOVX T1,MTS%AV ;GET AVAILABLE-STATUS BIT
TDNN T1,DSFE+MTS.SF ;DRIVE AVAILABLE?
RET ;NO
RETSKP ;YES
; CLRTAP - ISSUE MTOPR TO CLEAR ERRORS IN MTA DEVICE
; MTA/ ADDR OF MTA STATUS BLOCK
; RETURNS +1: GDSTS TIMED OUT
; +2: SUCCESS, AC'S SET UP:
; T1/ LAST ERROR CODE ENCOUNTERED BY PROCESS
; T2/ GDSTS T2
; T3/ # OF BYTES TRANSFERRED (LH OF GDSTS T3)
CLRTAP: SAVET ;SET UP RETURN VALUES IN STACK
CALL GETERR ;GET LAST ERROR CODE
MOVEM T1,CT1 ;GIVE TO CALLER
LOAD T1,MTAJFN ;GET JFN
IOXCT GDSTS,R,R ;GET STATUS IN T2,T3
MOVEM T2,CT2 ;GIVE T2 TO CALLER VERBATIM
HLRZM T3,CT3 ;PUT # OF BYTES XFERRED IN CALLER'S T3
MOVEI T2,.MOCLE ;GET CLEAR-ERRORS FUNCTION
MTOPR ;CLEAR ANY ERROR FLAGS
ERCAL STOP
RETSKP ;RETURN PULLING T1-T4 FROM STACK
; CTIMER - CANCEL ALL TIMER JSYS REQUESTS FOR THIS FORK
; RETURNS +1: ALWAYS
CTIMER: MOVE T1,[.FHSLF,,.TIMAL] ;FORK,,FUNCTION
SETZB T2,T3 ;PROPITIATE TIMER JSYS
TIMER ;CANCEL ALL REQUESTS FOR THIS FORK
CALL STOP
RET
; CVTA6 - CONVERT CONTIGUOUS ASCII CHARACTERS TO SIXBIT
; CVTA6R - SAME AS CVTA6, BUT INTERPRET LOWER CASE LETTERS AS UPPER CASE
; T1/ BYTE POINTER TO FIRST ASCII CHARACTER
; T2/ NUMBER OF CHARACTERS TO PROCESS
; RETURNS +1: FIELD WAS NOT A LEGAL VOLID OR SETNAME
; +2: FIELD WAS A LEGAL VOLID OR SETNAME, T1/ SIXBIT RESULT
CVTA6: TDZA T3,T3 ;REMEMBER NO-RAISE ENTRY
CVTA6R: MOVEI T3,1 ;REMEMBER RAISE ENTRY
STAKT
SETZ T1, ;CLEAR RESULT REGISTER
MOVE T4,[POINT 6,T1] ;GET BYTE POINTER FOR BUILDING RESULT
CVTA61: ILDB T3,CT1 ;GET NEXT CHARACTER FROM FIELD
CAIL T3,"a"
CAILE T3,"z" ;LOWER CASE?
JRST CVTA62 ;NO
SKIPE CT3 ;RAISING LOWER CASE?
SUBI T3,40 ;YES, DO IT
CVTA62: SUBI T3,40 ;CONVERT TO SIXBIT REPRESENTATION
TRNE T3,777700 ;OUT OF RANGE?
RET ;YES, RETURN ERROR
IDPB T3,T4 ;PACK IT INTO T1
SOJG T2,CVTA61 ;LOOP THRU ALL CHARS IN FIELD
CALLRET CHKID ;PASS JUDGMENT UPON CONVERTED VALUE
; DACMTA - UNDO THE EFFECTS OF ACTMTA (I.E. DEACTIVATE MTA DEVICE)
; MTA/ ADDR OF MTA STATUS BLOCK
; RETURNS +1: ALWAYS
DACMTA: JE MTASTE,,R ;RETURN IF ALREADY DONE
JN MTAJCT,,R ;CAN'T DO IT IF I'M USING THE DRIVE
JN MTAMT,,R ;CAN'T DO IT IF A USER HAS THE DRIVE
CALL SCIDIS ;DON'T TAKE INTERRUPTS FROM THIS MTA
CALL GMTADD ;GET DEVICE DESIGNATOR
RELD ;RELEASE CONTROL OF DEVICE
CALL STOP
SETZRO MTASTE ;SET MTA NOT ASSIGNED
RET
; DDMT - CONVERT MT DEVICE DESIGNATOR TO STATUS BLOCK ADDRESS
; T1/ DEVICE DESIGNATOR
; RETURNS +1: FAILED, NOT A VALID MT DEVICE DESIGNATOR
; +2: SUCCESS, MT/ ADDRESS OF MT STATUS BLOCK
DDMT: HLRZ T2,T1 ;GET LEFT HALF OF DESIGNATOR
CAIN T2,.DVDES+.DVMTA ;CHECK LEFT HALF
TRZN T1,400000 ;CHECK RIGHT HALF
RET ;SOMETHING'S ROTTEN
HRRZ MT,T1 ;GET UNIT# PART OF DESIGNATOR
CAML MT,MTN ;DO I KNOW ABOUT IT?
RET ;NO, ERROR
IMULI MT,MTSZ ;COMPUTE ADDRESS
ADDI MT,MT0 ; OF STATUS BLOCK
RETSKP ;SUCCESS
; DDMTA - CONVERT MTA DEVICE DESIGNATOR TO STATUS BLOCK ADDRESS
; T1/ DEVICE DESIGNATOR
; RETURNS +1: FAILED, NOT A VALID MTA DEVICE DESIGNATOR
; +2: SUCCESS, MTA/ ADDRESS OF MTA STATUS BLOCK
DDMTA: HLRZ T2,T1 ;GET LEFT HALF OF DESIGNATOR
CAIE T2,.DVDES+.DVMTA ;IS IT AN MTA DEVICE?
RET ;NO, ERROR
HRRZ MTA,T1 ;GET RIGHT HALF OF DESIGNATOR
CAML MTA,MTAN ;DO I KNOW ABOUT IT?
RET ;NO, ERROR
IMULI MTA,MTASZ ;COMPUTE ADDRESS
ADDI MTA,MTA0 ; OF STATUS BLOCK
RETSKP ;SUCCESS
; DRVDEN - DETERMINE IF DRIVE CAN OPERATE AT A GIVEN DENSITY
; T1/ DENSITY CODE
; MTA/ ADDR OF MTA STATUS BLOCK
; RETURNS +1: DRIVE CANNOT OPERATE AT THIS DENSITY
; +2: DRIVE CAN OPERATE AT THIS DENSITY
DRVDEN: MOVNS T1 ;NEGATE FOR RIGHT SHIFT
MOVSI T2,(1B0)
LSH T2,(T1) ;POSITION BIT FOR INTERROGATION
TDNN T2,MTASDN(MTA) ;CAN THE DRIVE WORK AT THIS DENSITY?
RET ;NO
RETSKP ;YES
; DDCTLD - CHECK FOR REQUEST TO ENABLE OR DISABLE ^D INTERCEPT
; RETURNS +1: ALWAYS
DDCTLD: SKIPGE T1,CDFLG ;HAS A REQUEST BEEN MADE?
RET ;NO
SETOM CDFLG ;YES, CLEAR IT
JUMPE T1,[MOVEI T1,.TICCD ;REQUEST TO DISABLE ^D
DTI
TXZ F,CDENF ;RESET ^D-ENABLED
RET]
MOVX T1,<.TICCD,,DDTCN> ;REQUEST TO ENABLE ^D
ATI
TXO F,CDENF ;SET ^D-ENABLED
RET
; DDT INTERRUPT PROCESSOR
DDTIH: CALL DDTLOD ;TRY TO LOAD DDT
SKIPA ;NO CAN DO
CALL 770000 ;CALL DDT - RETURN IS R$G
MOVEI T1,.FHSUP
MOVX T2,1B0
TXNN F,CDENF ;DON'T INTERRUPT IF CALLED BY ^D
IIC ;TRIGGER CHANNEL-0 INTERRUPT UPSTAIRS
RET ;EXIT TO SCHED
; DDTLOD - LOADS DDT INTO MY ADDRESS SPACE IF NOT ALREADY THERE
; RETURNS +1: ERROR LOADING DDT
; +2: DDT LOADED SUCCESSFULLY
DDTLOD: MOVE T1,[.FHSLF,,770]
RPACS ;IS DDT LOADED ALREADY?
JXN T2,PA%PEX,RSKP ;YES, RETURN +2
MOVX T1,GJ%OLD+GJ%SHT
HRROI T2,[ASCIZ/SYS:UDDT.EXE/]
GTJFN
DDTLDX: JRST [ TMSG <%MOUNTR: ERROR TRYING TO GET DDT>
JRST JSERR0] ;TYPE MESSAGE AND RETURN +1
HRLI T1,.FHSLF
GET
ERJMP DDTLDX
MOVE T1,.JBSYM ;GET ADDRESS OF SYMBOL TABLE
HRRZ T2,770001 ;GET ADDRESS OF WHERE TO STUFF IT
MOVEM T1,(T2) ;POINT DDT AT MY SYMBOL TABLE
RETSKP
; REENTER ADDRESS
DEBUG: MOVE P,[IOWD PDLEN,PDL] ;NEED STACK POINTER FOR CALL
CALL DDTLOD ;LOAD DDT
HALTF ;CAN'T
JRST 770000 ;GO RIGHT TO DDT
; DSFCKS - COMPUTE CHECKSUM OF DEVICE-STATUS FILE BUFFER
; RETURNS +1: ALWAYS, WITH CHECKSUM IN T1
DSFCKS: MOVE T1,LVERS ;START WITH CURRENT VERSION
MOVEI T3,DSFSZ-1 ;INIT SCANNING POINTER
DSFCK1: TLZ T1,400000 ;POSITIVE
TRO T1,1 ; AND ODD
MULI T1,400003 ;RANDOMIZE
MOVE T1,T2 ;COPY BACK TO T1
XOR T1,DSBUF(T3) ;MERGE NEXT WORD
SOJG T3,DSFCK1 ;LOOP THRU BUFFER
RET ;RETURN TO CALLER
; DSFINI - MAPS DEVICE-STATUS FILE INTO DSBUF
; RETURNS +1: ALWAYS
DSFINI: MOVX T1,GJ%SHT+GJ%ACC ;FLAGS
HRROI T2,[ASCIZ/SYSTEM:DEVICE-STATUS.BIN/] ;FILESPEC
GTJFN ;GET JFN ON DEVICE-STATUS FILE
RET ;ERROR, GIVE UP
MOVEM T1,DSFJFN ;SAVE JFN
MOVX T2,OF%RD+OF%WR ;FLAGS FOR OPENF
CALL DSFMAP ;TRY OPENING FILE FOR UPDATE
TRNA ;CAN'T DO IT
RET ;OPEN, RETURN
MOVX T2,OF%WR ;GET FLAGS FOR OPENF
CALL DSFMAP ;TRY RECREATING THE FILE
RET ;NO LUCK...
RET ;IT WORKED!
; DSFLOC - LOCATE ENTRY FOR SPECIFIED DEVICE IN DEVICE-STATUS FILE
; DSFE/ DEVICE TYPE
; DSFE+1/ DEVICE IDENTIFIER
; RETURNS +1: DEVICE NOT REPRESENTED IN FILE
; +2: DEVICE ENTRY FOUND, T1/ ADDRESS OF ENTRY
DSFLOC: SKIPN T4,DSB.NE ;GET # OF ENTRIES TO CHECK
RET ;NONE, IT AIN'T HERE!
MOVEI T1,DSB.EO ;START SCAN HERE
DMOVE T2,DSFE ;GET REQUESTED TYPE AND IDENTIFIER
DSFLC1: CAME T2,(T1) ;DO DEVICE TYPES MATCH?
JRST DSFLC2 ;NO, SKIP IT
CAMN T3,1(T1) ;DO IDENTIFIERS MATCH?
RETSKP ;YES, I FOUND IT
DSFLC2: ADDI T1,DSFESZ ;POINT AT NEXT ENTRY
SOJG T4,DSFLC1 ;GO CHECK NEXT ENTRY IF THERE IS ONE
RET ;NOT FOUND, ERROR RETURN
; DSFMAP - MAPS DEVICE-STATUS.BIN INTO DSBUF
; INTERNAL SUBROUTINE FOR DSFINI
; T2/ AC2 FOR OPENF
; RETURNS +1: FAILURE IN I/O JSYS
; +2: SUCCESS
DSFMAP: MOVE T1,DSFJFN ;GET JFN
TXO T2,OF%DUD ;NO AUTOMATIC UPDATING OF FILE PAGES
OPENF ;OPEN DEVICE-STATUS FILE
RET ;ERROR
HRLZ T1,DSFJFN ;GET JFN ,, FILE PAGE #
MOVE T2,[.FHSLF,,DSBUF_-9] ;FORK HANDLE ,, FORK PAGE #
MOVE T3,[PM%CNT+PM%RWX+PM%PLD+DSFPGS] ;FLAGS,,#PAGES
PMAP ;MAP THE FILE IN
ERJMP [MOVE T1,DSFJFN ;ERROR, GET JFN
TXO T1,CO%NRJ ;KEEP JFN
CLOSF ;CLOSE THE FILE
JFCL
RET] ;TAKE ERROR RETURN
CALL DSFCKS ;COMPUTE CHECKSUM
CAME T1,DSB.CK ;IS IT RIGHT?
JRST DSFMA1 ;NO
MOVEI T1,.APRID
GETAB ;GET APR SERIAL #
JFCL ;SHOULD NEVER FAIL
CAMN T1,DSB.PS ;SAME CPU?
RETSKP ;OK, THE FILE LOOKS GOOD
; RESET CONTENTS OF DEVICE-STATUS FILE (T1/ APR SERIAL #)
DSFMA1: SETZM DSBUF
MOVE T2,[DSBUF,,DSBUF+1] ;GET BLT POINTER
BLT T2,DSBUF+DSFSZ-1 ;CLEAR REMAINDER OF BUFFER
MOVEM T1,DSB.PS ;STORE APR SERIAL #
CALL DSFUPD ;UPDATE PAGES IN FILE
RETSKP ;ALL DONE, TAKE GOOD RETURN
; DSFPUT - ADD/REPLACE ENTRY IN DEVICE STATUS FILE
; DSFE/ ENTRY THAT IS TO BE ADDED OR REPLACED
; RETURNS +1: ALWAYS
DSFPUT: CALL DSFLOC ;DO I KNOW ABOUT IT ALREADY?
JRST [ MOVE T1,DSB.NE ;NO, APPEND TO END OF BUFFER
IMULI T1,DSFESZ ;COMPUTE DISPLACEMENT TO END
ADDI T1,DSB.EO ;ADD OFFSET TO START OF ENTRY AREA
AOS DSB.NE ;ADD THIS ENTRY TO THE TOTAL COUNT
JRST .+1] ;GO INSTALL IT
MOVEI T2,DSFESZ-1(T1) ;COMPUTE ADDR OF LAST WORD IN DEST
HRLI T1,DSFE ;BLT SOURCE
BLT T1,(T2) ;INSTALL ENTRY IN DSBUF
CALL DSFUPD ;UPDATE COPY OF FILE ON DISK
RET
; DSFTGT - GET DEVICE-STATUS FILE ENTRY FOR SPECIFIED TAPE DRIVE
; T1/ DEVICE DESIGNATOR OF TAPE DRIVE
; RETURNS +1: ALWAYS, DSFE/ ENTRY FOR SPECIFIED DRIVE
DSFTGT: MOVEM T1,DSFE+1 ;STORE DESIGNATOR
MOVEI T1,.DVMTA
MOVEM T1,DSFE ;STORE DEVICE TYPE
CALL DSFLOC ;LOOK UP THIS DRIVE
JRST [ MOVX T1,MTS%AV ;NOT ON FILE YET
MOVEM T1,DSFE+MTS.SF ;SET UP DEFAULT ENTRY IN DSFE
CALLRET DSFPUT] ;ADD DRIVE TO FILE AND RETURN
MOVSS T1 ;FOUND IT, GET BLT SOURCE
HRRI T1,DSFE ;BLT DESTINATION
BLT T1,DSFE+DSFESZ-1 ;TRANSFER ENTRY TO DSFE
RET ;FOUND IT, RETURN
; DSFUPD - COMPUTES AND INSTALLS CHECKSUM IN DEVICE-STATUS FILE
; BUFFER, THEN WRITES BUFFER OUT TO DISK
; RETURNS +1: ALWAYS
DSFUPD: CALL DSFCKS ;COMPUTE CHECKSUM OF BUFFER
MOVEM T1,DSB.CK ;STORE IT
HRLZ T1,DSFJFN ;GET JFN ,, FIRST PAGE #
JUMPE T1,R ;OOPS, NO JFN... HEH HEH HEH... BYE!
MOVEI T2,DSFPGS ;# OF PAGES TO UPDATE
UFPGS ;WRITE 'EM OUT
JFCL ;IGNORE ERRORS
RET
; ELOGOF - INHIBIT ERROR LOGGING FOR MAGTAPE
; ELOGON - RESTORE ERROR LOGGING FOR MAGTAPE
; MTA/ ADDR OF MTA STATUS BLOCK (MTA MUST BE OPEN)
; RETURNS +1: ALWAYS, REQUESTED FUNCTION PERFORMED
ELOGON: TDZA T3,T3 ;ENABLE ERROR LOGGING
ELOGOF: MOVEI T3,1 ;INHIBIT ERROR LOGGING
LOAD T1,MTAJFN ;GET JFN
MOVEI T2,.MOIEL ;FUNCTION = CONTROL ERROR LOGGING
IOXCT MTOPR,R,R ;SET DESIRED STATE
RET
; FNOUT - TRANSLATE A NUMBER INTO RIGHT-JUSTIFIED, ZERO-FILLED ASCII
; T1/ BYTE POINTER TO FIELD
; T2/ NUMBER
; T3/ FIELD SIZE ,, RADIX
; RETURNS +1: ALWAYS
FNOUT: HLRZ T4,T3 ;GET FIELD SIZE
ADJBP T4,T1 ;GET POINTER TO BYTE AFTER FIELD
ILDB T4,T4 ;GET BYTE FOLLOWING FIELD
TXO T3,NO%LFL+NO%ZRO ;TURN ON FLAGS
NOUT ;OUTPUT NUMBER
JFCL
IDPB T4,T1 ;FIX UP STUPID NULL LEFT BY NOUT
RET
; GALHDR - CONSTRUCT STANDARD GALAXY HEADER IN TBUF
; T1/ LENGTH OF MESSAGE (WORDS) ,, MESSAGE TYPE CODE
; T2/ MESSAGE FLAGS ,, SIXBIT SUFFIX
; T3/ ACKNOWLEDGMENT CODE
; RETURNS +1: ALWAYS, WITH GALAXY HEADER BUILT IN BEGINNING OF TBUF
; NOTE: THIS IS THE ONLY PLACE WHERE THE GALAXY HEADER IS BUILT
; IN THE ENTIRE MODULE
GALHDR: MOVEM T1,TBUF+.MSTYP
MOVEM T2,TBUF+.MSFLG
MOVEM T3,TBUF+.MSCOD
RET
; GETERR - RETURN THE MOST RECENT ERROR CODE FOR THIS FORK
; RETURNS +1: ALWAYS, WITH ERROR CODE IN T1
GETERR: MOVEI T1,.FHSLF
GETER ;GET MOST RECENT ERROR IN RH OF T2
ERJMP .+1
HRRZ T1,T2 ;MOVE TO T1 STRIPPING LEFT HALF
RET
; GETVU - TRANSFER USER NAME FROM VOL2 LABEL TO CALLER'S STRING AND
; RETURN USER NUMBER CORRESPONDING TO THE USER NAME
; T1/ ADDRESS OF 8-WORD AREA TO RECEIVE ASCIZ USER NAME
; MTA/ ADDR OF MTA STATUS BLOCK
; RETURNS +1: T1/ BYTE POINTER TO CALLER'S ASCIZ USER NAME STRING
; T2/ USER # CORRESPONDING TO NAME OR 0 IF THE USER DOESN'T
; EXIST ON THE SYSTEM
GETVU: HRLI T1,(POINT 7) ;CREATE BYTE POINTER TO CALLER'S AREA
SAVET ;RETURN IT TO CALLER IN T1
MOVEI T2,V2OWN-1
ADJBP T2,[POINT 8,MTAV2(MTA)] ;GET BYTE PTR TO VOL2 USER NAME
MOVEI T3,V2OWNL ;GET MAX LENGTH OF USER NAME
GETVU1: ILDB T4,T2 ;GET CHARACTER FROM VOL2
TRZ T4,200 ;MASK OFF TRASH
CAIN T4," " ;END OF NAME?
GETVU2: SETZ T4, ;YES, TIE IT OFF WITH A NULL
IDPB T4,T1 ;COPY CHARACTER TO CALLER'S AREA
JUMPN T4,[SOJG T3,GETVU1 ;LOOP IF MORE LEFT IN VOL2 LABEL
JRST GETVU2] ;OTHERWISE WRAP UP
; NOW TRY TO IDENTIFY THE USER WITH RCUSR
SETZM CT2 ;RETURN 0 IN T2 IF RCUSR FAILS
MOVX T1,RC%EMO ;REQUEST EXACT MATCH
MOVE T2,CT1 ;GET POINTER TO CALLER'S STRING
RCUSR ;TRY TO RECOGNIZE USER NAME
ERJMP R ;FAILED
TXNN T1,RC%NOM ;GOT A MATCH?
MOVEM T3,CT2 ;YES, RETURN USER # IN T2
RET
; GMTADD - GET MTA DEVICE DESIGNATOR
; MTA/ ADDR OF MTA STATUS BLOCK
; RETURNS +1: ALWAYS, WITH DEVICE DESIGNATOR IN T1
GMTADD: MOVE T1,MTA ;COPY STATUS BLK ADDR
SUBI T1,MTA0 ;COMPUTE OFFSET FROM START OF BLOCKS
IDIVI T1,MTASZ ;COMPUTE MTA UNIT #
HRLI T1,.DVDES+.DVMTA ;ADD LEFT HALF OF DEVICE DESIGNATOR
RET
; GMTADS - ISSUE MTOPR AND RETURN MTA DEVICE STATUS
; MTA/ ADDR OF MTA STATUS BLOCK
; RETURNS +1: ALWAYS, T1/ .MOSTA STATUS WORD .MOCST
GMTADS: STKVAR <<MTOBLK,MOSTAL>>
MOVEI T1,MTOBLK ;GET ARG BLOCK ADDRESS
CALL MOSTA ;GET STATUS & CHARACTERISTICS
MOVE T1,.MOCST+MTOBLK ;GET STATUS INFO FOR CALLER
TXNE T1,SJ%OFS ;OFFLINE?
TXZ T1,SJ%REW ;YES, CAN'T BE REWINDING THEN
RET
; GMTDD - GET MT DEVICE DESIGNATOR
; MT/ ADDR OF MT STATUS BLOCK
; RETURNS +1: ALWAYS, WITH DEVICE DESIGNATOR IN T1
GMTDD: MOVE T1,MT ;COPY STATUS BLK ADDR
SUBI T1,MT0 ;COMPUTE OFFSET FROM START OF BLOCKS
IDIVI T1,MTSZ ;COMPUTE MT UNIT #
TDO T1,[.DVDES+.DVMTA,,400000] ;ADD THE FRILLS
RET
; GTINAM - GET INSTALLATION NAME FROM FILE
; RETURNS +1: ALWAYS, ASCIZ INSTALLATION NAME IN TAPNAM
GTINAM: MOVX T1,GJ%SHT+GJ%ACC+GJ%OLD
HRROI T2,[ASCIZ/SYSTEM:TAPNAM.TXT/]
GTJFN ;GET JFN ON FILE
RET ;NO JFN, NO ARBEIT
MOVE T4,T1 ;SAVE JFN
MOVX T2,FLD(7,OF%BSZ)+OF%RD
OPENF ;OPEN FILE FOR READ ACCESS
JRST [ MOVE T1,T4 ;OPEN FAILED, GET JFN
RLJFN ;DUMP IT
JFCL
RET]
HRROI T2,TAPNAM ;GET ADDRESS OF TEXT IN CORE
MOVNI T3,TPNMSZ ;GET MAX # OF BYTES TO READ
SIN ;READ 'EM IN
ERJMP .+1 ;IGNORE ERRORS
CLOSF ;CLOSE FILE, DUMP JFN
JFCL
MOVE T1,[POINT 7,TAPNAM] ;GET POINTER TO TEXT
GTINM1: ILDB T2,T1 ;GET A BYTE
JUMPE T2,R ;EXIT IF END OF STRING
CAIE T2,.CHCRT ;CARRIAGE-RETURN?
JRST GTINM1 ;NO, CONTINUE SCAN
SETZ T2, ;YES
DPB T2,T1 ;DELETE C/R AND EVERYTHING AFTER IT
RET
; INAP - PERFORM INITIALIZATION RELATED TO ASSOCIATED PROCESSES
; RETURNS +1: ALWAYS
INAP: SAVEQ
MOVEI Q1,APNUM ;GET # OF A/P'S
INAP1: SOJL Q1,R ;EXIT IF NONE LEFT
CALL @APINI(Q1) ;CALL A/P INIT ROUTINE
JRST INAP1 ;LOOP THRU ALL A/P TABLE ENTRIES
; INT26 - CONVERT INTEGER TO SIXBIT, RIGHT-JUSTIFIED ZERO-FILLED
; T1/ INTEGER
; RETURNS +1: ALWAYS, T1/ SIXBIT RESULT
INT26: MOVM T2,T1 ;GET ABSOLUTE VALUE
IDIV T2,[^D1000000] ;GET NUMBER MOD 1000000 IN T3
MOVE T1,[SIXBIT/000000/] ;INIT RESULT
MOVE T2,[POINT 6,T1,35] ;GET POINTER TO RESULT
INT261: IDIVI T3,12 ;PEEL OFF A DIGIT
ADDI T4,20 ;CONVERT INTEGER TO SIXBIT
DPB T4,T2 ;STORE INTO T1
ADD T2,[6B5] ;BACK UP BYTE POINTER
JUMPN T3,INT261 ;LOOP IF MORE TO DO
RET
; IOXCTR - DRIVER FOR IOXCT MACRO; EXECUTES AND TIMES OUT A JSYS
; T1-T4/ ARGUMENTS FOR JSYS
; CALL: IOXCT <JSYS,ERJMP ADDRESS,TIMEOUT ADDRESS>
; RETURNS TO ERJMP ADDRESS IF JSYS ERJMP'ED
; TO TIMEOUT ADDRESS IF JSYS TIMED OUT
; TO INSTRUCTION AFTER IOXCT MACRO IF JSYS SUCCEEDED
; ALL RETURNS: T1-T4 CONTAINING VALUES RETURNED BY JSYS
; CAUTION - IN ORDER TO PICK UP THE ARGUMENTS THAT FOLLOW THE CALL,
; THIS ROUTINE DOES SOME SHADY THINGS WITH THE STACK
IOXCTR: CALL [ SAVET ;PRESERVE AC'S FOR JSYS
MOVE T1,[14,,.SYSTA]
GETAB ;GET CURRENT LOAD AVERAGE
CALL STOP ;SHOULD NEVER FAIL
FIXR T2,T1 ;CONVERT TO AN INTEGER
CAIGE T2,^D20 ;WAIT AT LEAST 20 SECONDS
MOVEI T2,^D20
MOVE T1,[.FHSLF,,.TIMEL] ;FORK,,FUNCTION
IMULI T2,^D1000 ;CONVERT SECONDS TO MILLISECONDS
MOVEI T3,JTOCN ;GET INTERRUPT CHANNEL #
TIMER ;SET UP FOR INTERRUPT
JFCL
RET]
TXO F,JTOAF ;SET JSYS-TIMEOUT-ARMED
XCT @(P) ;EXECUTE JSYS
ERJMP [TXZ F,JTOAF ;DISARM TIMER
CALL [ SAVET
CALLRET CTIMER] ;CANCEL TIMER
POP P,CX ;GET ADDRESS OF CALL+1
HLRZ CX,1(CX) ;GET ERJMP ADDRESS
JRST (CX)] ;RETURN TO ERJMP ADDRESS
TXZ F,JTOAF ;DISARM TIMER
CALL [ SAVET
CALLRET CTIMER] ;CANCEL TIMER
AOS (P) ;RETURN TO
RETSKP ; CALL+3
; INTERRUPT HANDLER FOR TIMER JSYS INTERRUPT
JTOIH: TXZN F,JTOAF ;TIMER STILL ARMED?
DEBRK ;NO, DON'T DO ANYTHING
MOVEM T1,@LEVTAB+PRIEXT-1 ;SAVE T1
MOVE T1,[PC%USR+IOXCT1] ;GET NEW PC
EXCH T1,@LEVTAB+PRIEXT-1 ;RESTORE T1, SET NEW PC
DEBRK ;DEBREAK TO IOXCT1
IOXCT1: POP P,CX ;TIMEOUT OCCURRED, GET ADDR OF CALL+1
HRRZ CX,1(CX) ;GET TIMEOUT-HANDLER ADDRESS
JRST (CX) ;EXIT TO CALLER'S TIMEOUT HANDLER
; LDATIN - PARSE AND RETURN DATE FROM TAPE LABEL (IN FORM " YYDDD")
; T1/ ILDB POINTER TO FIRST CHARACTER OF DATE FIELD
; RETURNS +1: DATE CONTAINED NON-NUMERIC CHARACTERS OR WAS ILLEGAL
; +2: DATE PARSED SUCCESSFULLY,
; T1/ YEAR,,JULIANDAY OR 0 (IF DATE WAS " 00000")
LDATIN: SAVEQ
IBP T1 ;SKIP OVER THE SPACE
MOVE Q1,T1 ;MOVE POINTER TO ANOTHER PLACE
SETO Q2, ;SET FOR 1ST PASS
LDAT1: MOVEI T4,3(Q2) ;COMPUTE # OF DIGITS TO SCAN
SETZ T2, ;CLEAR ACCUMULATOR
LDAT2: ILDB T3,Q1 ;GET NEXT CHARACTER
CAIL T3,"0" ;ERROR IF .LT. 0
CAILE T3,"9" ; OR .GT. 9
RET
IMULI T2,^D10 ;SHIFT CONTENTS OF ACCUMULATOR
ADDI T2,-"0"(T3) ;ADD IN NEW DIGIT
SOJG T4,LDAT2 ;LOOP
AOJE Q2,[MOVS T1,T2 ;DOING YEAR, GET T1/ YEAR-1900,,0
JRST LDAT1] ;NOW GO BACK AND DO THE DAY
JUMPE T2,[JUMPE T1,RSKP ;IF YEAR=DAY=0, RETURN GOOD WITH T1/ 0
RET] ;IF DAY=0 BUT YEAR.NE.0, ERROR
CAILE T2,^D366 ;IS DAY TOO LARGE?
RET ;YES, ERROR
HRR T1,T2 ;GET YEAR-1900,,JULIANDAY
ADD T1,[^D1900,,0] ;ADD IN THE 1900
RETSKP
; MOSTA - ISSUE .MOSTA MTOPR TO GET TAPE DRIVE CHARACTERISTICS AND STATUS
; NOTE - THIS MTOPR FUNCTION MUST BE GUARANTEED NOT TO BLOCK
; T1/ ADDRESS OF BLOCK TO RECEIVE INFORMATION (MOSTAL WORDS LONG)
; MTA/ ADDR OF MTA STATUS BLOCK
; RETURNS +1: ALWAYS, WITH INFORMATION IN ARGUMENT BLOCK
MOSTA: STAKT
CALL MTAGJF ;GET JFN FOR MTOPR IN T1
MOVEI T2,.MOSTA ;MTOPR FUNCTION CODE
MOVE T3,CT1 ;GET ADDR OF ARGUMENT BLOCK
MOVEI T4,MOSTAL
MOVEM T4,(T3) ;PUT LENGTH IN FIRST WORD OF BLOCK
MTOPR ;GET STATUS INFO INTO ARG BLOCK
CALLRET MTARJF ;RELEASE JFN AND RETURN
; MOVSTR - MOVE ASCIZ STRING (TRAILING NULL IS NOT MOVED)
; T1/ SOURCE STRING POINTER
; T2/ DESTINATION STRING POINTER
; STRING POINTERS MAY BE OF THE FORM: -1,,ADDRESS
; RETURNS +1: ALWAYS
MOVSTR: TLC T1,-1
TLCN T1,-1
HRLI T1,(POINT 7)
TLC T2,-1
TLCN T2,-1
HRLI T2,(POINT 7)
MOVST1: ILDB T3,T1
JUMPE T3,R
IDPB T3,T2
JRST MOVST1
; MTAGJF - GET A JFN ON MTA DEVICE
; MTA/ MTA STATUS BLOCK
; RETURNS +1: ALWAYS, WITH JFN IN MTAJFN AND T1
MTAGJF: JN MTAJCT,,MTAGJ1 ;JFN EXISTS ALREADY, USE IT
STKVAR <<GJFTXT,2>>
CALL GMTADD ;GET DEVICE DESIGNATOR IN T1
MOVE T2,T1 ;MOVE TO T2 FOR DEVST
HRROI T1,GJFTXT ;GET ADDRESS OF TEXT BUFFER
DEVST ;BEGIN JFN STRING WITH "MTAn"
CALL STOP
MOVEI T2,":"
IDPB T2,T1 ;TACK ON A COLON
SETZ T2,
IDPB T2,T1 ;TERMINATE WITH A NULL
MOVX T1,GJ%SHT+GJ%ACC ;GTJFN FLAGS
HRROI T2,GJFTXT ;POINTER TO STRING
GTJFN ;GET JFN ON MTA DEVICE
CALL STOP
STOR T1,MTAJFN ;STORE JFN IN TABLE
MTAGJ1: INCR MTAJCT ;INCREMENT JFN-IN-USE COUNT
LOAD T1,MTAJFN ;GET JFN FOR CALLER
RET
; MTARJF - RELEASE MTA JFN OBTAINED WITH MTAGJF
; MTA/ ADDR OF MTA STATUS BLOCK
; RETURNS +1: ALWAYS
MTARJF: LOAD T1,MTAJCT ;GET JFN-IN-USE COUNT
SOSGE T1 ;GOING NEGATIVE?
CALL STOP ;YES, PROGRAM LOGIC ERROR
STOR T1,MTAJCT ;STORE NEW COUNT
JUMPG T1,R ;EXIT IF JFN STILL IN USE
LOAD T1,MTAJFN ;GET JFN
RLJFN ;DISCARD IT
CALL STOP
SETZRO MTAJFN ;CLEAR JFN JUST TO PLAY IT SAFE
RET
; MTAOPI - GET A JFN OPEN FOR READ ON AN MTA DEVICE
; MTAOPO - GET A JFN OPEN FOR WRITE ON AN MTA DEVICE
; MTA/ ADDR OF MTA STATUS BLOCK (DENSITY SET FROM MTADEN)
; RETURNS +1: FAILED, DRIVE OFFLINE OR WRITE-LOCKED
; +2: SUCCESS, JFN IN MTAJFN AND T1
MTAOPI: SKIPA T1,[OF%RD] ;OPEN FOR READ ACCESS
MTAOPO: MOVX T1,OF%WR ;OPEN FOR WRITE ACCESS
SAVEQ
MOVE Q1,T1 ;SAVE MODE
MOVE T1,MTAFLG(MTA) ;GET MTA FLAGS
TXNE T1,MA%OPN ;JFN OPEN ALREADY?
CALL STOP ;YES, PROGRAM FAILURE
CALL MTAGJF ;GET JFN ON MTA
MOVX T2,FLD(17,OF%MOD)+FLD(10,OF%BSZ)+OF%OFL
TDO T2,Q1 ;SET MODE BIT
OPENF ;OPEN THE JFN
JRST [ CAIN T1,OPNX8 ;DEVICE OFFLINE?
JRST [ SETZRO MA%LOD,MTAFLG(MTA) ;YES, UPDATE STATUS
CALLRET MTARJF] ;DUMP JFN AND TAKE +1
CAIE T1,OPNX25 ;DEVICE WRITE PROTECTED?
CALL STOP ;NO, CAN'T HACK THIS ONE
CALLRET MTARJF] ;YES, DUMP JFN AND TAKE +1
SETONE MA%OPN,MTAFLG(MTA) ;SET JFN-OPEN FLAG
MOVEI T2,.MOSDM
MOVEI T3,.SJDM8 ;SPECIFY INDUSTRY-COMPATIBLE MODE
MTOPR ;SET DATA MODE OF DRIVE
MOVEI T2,.MOSDN
LOAD T3,MTADEN ;GET DESIRED DENSITY CODE
MTOPR ;SET DENSITY
RETSKP ;RETURN +2, T1/ JFN
; MTACLS - CLOSE MTA JFN
; MTA/ ADDR OF MTA STATUS BLOCK
; RETURNS +1: ALWAYS
MTACLS: MOVX T1,MA%OPN
TDNN T1,MTAFLG(MTA) ;IS THE JFN OPEN?
CALL STOP ;NO, PROGRAM FAILURE
ANDCAM T1,MTAFLG(MTA) ;IT'LL BE CLOSED WHEN I GET DONE
LOAD T1,MTAJFN ;GET MTA JFN
LOAD T2,MTAJCT ;GET JFN-IN-USE COUNT
SOSGE T2 ;GOING NEGATIVE?
CALL STOP ;YES, PROGRAM LOGIC ERROR
STOR T2,MTAJCT ;STORE NEW COUNT
SKIPE T2 ;DOES SOMEONE ELSE NEED THE JFN?
TXO T1,CO%NRJ ;YES, DON'T DUMP JFN, JUST CLOSE IT
TXO T1,CZ%ABT ;CLOSE WITHOUT BLOCKING
CLOSF ;CLOSE (AND POSSIBLY DISCARD) JFN
CALL STOP
JUMPN T2,R ;EXIT IF JFN STILL IN USE
SETZRO MTAJFN ;CLEAR JFN JUST TO PLAY IT SAFE
RET
; NMTRSB - GET ADDRESS OF NEXT MAGTAPE MOUNT RSB
; NSTRSB - GET ADDRESS OF NEXT STRUCTURE MOUNT OR DISMOUNT RSB
; NXXRSB - GET ADDRESS OF NEXT ACTIVE RSB
; QSB/ ADDR OF QUEUE SCAN BLOCK FOR ARBQDB
; RETURNS +1: NO RSB'S LEFT
; +2: SUCCESS, RSB/ ADDR OF REQUEST STATUS BLOCK
NMTRSB: SAVEQ
JSP Q1,NRSB1 ;SETUP COROUTINE ADDRESS IN Q1
CAIE T1,.MNTTP ;COROUTINE FOR TAPE MOUNT
JRST NRSB1
RETSKP
NSTRSB: SAVEQ
JSP Q1,NRSB1 ;SETUP COROUTINE ADDRESS IN Q1
CAIE T1,.MNTST ;COROUTINE FOR STRUCTURE MNT/DSMNT
CAIN T1,.DSMST
RETSKP
JRST NRSB1
NXXRSB: SAVEQ
JSP Q1,NRSB1 ;SETUP COROUTINE ADDRESS IN Q1
RETSKP ;COROUTINE TO SUCCEED FOR ANY RSB
; CHECK NEXT RSB TO SEE IF IT QUALIFIES
NRSB1: CALL QMSCAN ;GET ADDRESS OF RSB LINKAGE IN T2
RET ;END OF RSB LIST
MOVEI RSB,-RSBLNK(T2) ;LOAD RSB AC
CALL CHKAB ;REQUEST ABORTED?
JRST NRSB1 ;YES, SKIP IT
LOAD T1,RSBTYP ;LIVE RSB, GET TYPE FOR COROUTINE
JRST (Q1) ;DISPATCH TO COROUTINE
; PB ROUTINES - CONSTRUCT GALAXY-STYLE BUILDING-BLOCK LIST IN TBUF
; PBINIT - SET UP DATABASE FOR CALLS TO OTHER PB ROUTINES
; RETURNS +1: ALWAYS
PBINIT: XMOVEI T1,TBUF+.OARGC ;GET ADDRESS OF ARGUMENT COUNT WORD
MOVEI T2,TBUF+.OHDRS ;GET ADDRESS OF FIRST BUILDING BLOCK
MOVEM T1,PBACW ;SAVE ADDR OF ARGUMENT COUNT WORD
SETZM (T1) ;ZERO THE ARGUMENT COUNT
MOVEM T2,PBBPT ;SAVE ADDR OF 1ST BUILDING BLOCK
RET
; PBBLK - ADD PREFORMATTED BUILDING BLOCK TO LIST
; T1/ ADDRESS OF BUILDING BLOCK WITH HEADER
; RETURNS +1: ALWAYS
PBBLK: LOAD T2,AR.LEN,(T1) ;GET LENGTH OF BLOCK
MOVSS T1 ;BLT SOURCE
HRR T1,PBBPT ;BLT DESTINATION
ADDB T2,PBBPT ;COMPUTE ADDR OF NEXT BLOCK
BLT T1,-1(T2) ;MOVE BLOCK INTO LIST
AOS @PBACW ;BUMP ARG COUNT
RET
; PBTXT - CONSTRUCT ASCIZ TEXT BUILDING BLOCK
; T1/ ADDRESS OF ASCIZ TEXT
; T2/ ARGUMENT TYPE CODE
; RETURNS +1: ALWAYS
PBTXT: MOVE T4,PBBPT ;GET ADDR OF BLOCK HEADER
STOR T2,AR.TYP,(T4) ;STORE TYPE CODE IN HEADER
HRLI T1,(POINT 7) ;GET BYTE POINTER TO SOURCE
MOVEI T2,1(T4) ;COMPUTE ADDRESS OF TEXT IN BLOCK
HRLI T2,(POINT 7) ;GET BYTE POINTER TO DESTINATION
PBTXT1: ILDB T3,T1 ;GET BYTE
IDPB T3,T2 ;TRANSFER IT
JUMPN T3,PBTXT1 ;CONTINUE UNTIL I HIT A NULL
MOVEI T2,1(T2) ;GET ADDR OF WORD AFTER LAST TEXT WORD
MOVEM T2,PBBPT ;UPDATE BLOCK POINTER
SUB T2,T4 ;COMPUTE LENGTH OF BLOCK
STOR T2,AR.LEN,(T4) ;PUT LENGTH IN HEADER
AOS @PBACW ;BUMP ARG COUNT
RET
; PROTIN - CONVERT 6-DIGIT ASCII PROTECTION CODE TO FIXED-POINT INTEGER
; T1/ BYTE POINTER TO PROTECTION CODE
; RETURNS +1: CODE CONTAINED AT LEAST 1 NON-OCTAL DIGIT
; +2: SUCCESS, T1/ CODE
PROTIN: MOVE T4,T1 ;COPY POINTER TO T4
SETZ T1, ;INIT VALUE AC
MOVEI T2,6
PROT1: ILDB T3,T4 ;GET ASCII CHAR
SUBI T3,"0"
TRNE T3,777770 ;LEGAL OCTAL DIGIT?
RET ;NO
LSH T1,3 ;YES, SHIFT TO MAKE ROOM
ADD T1,T3 ;ADD IN THIS DIGIT
SOJG T2,PROT1 ;LOOP
RETSKP
; QUEUE-MANAGING ROUTINES
; ADD AND REMOVE PACKETS FROM QUEUES; QUEUES ARE DEFINED BY A
; 1-WORD QUEUE DESCRIPTOR WITH ADDRESS OF HEAD PACKET IN LEFT
; HALF AND ADDRESS OF TAIL IN RIGHT. IF ZERO, QUEUE IS EMPTY.
; QMDQH - DEQUEUE THE HEAD PACKET OF A QUEUE
; T1/ ADDRESS OF QUEUE DESCRIPTOR BLOCK
; RETURNS +1: QUEUE WAS EMPTY
; +2: SUCCESS, T2/ ADDRESS OF DEQUEUED HEAD PACKET
QMDQH: HLRZ T2,(T1) ;GET ADDRESS OF HEAD PACKET
JUMPE T2,R ;IF EMPTY, QUIT NOW
SKIPN T3,(T2) ;QUEUE GOING TO BE EMPTY?
SETZM (T1) ;YES, CLEAR DESCRIPTOR BLOCK
HRLM T3,(T1) ;SET NEW HEAD POINTER IN QDB
RETSKP
; QMQH - ADD A PACKET TO THE HEAD OF A QUEUE
; T1/ ADDRESS OF QUEUE DESCRIPTOR BLOCK
; T2/ ADDRESS OF PACKET TO BE ADDED TO HEAD OF QUEUE
; RETURNS +1: ALWAYS
QMQH: HLRZ T3,(T1) ;GET ADDRESS OF CURRENT HEAD
HRLM T2,(T1) ;SET ADDRESS OF NEW HEAD IN QDB
JUMPE T3,[HRRM T2,(T1) ;QUEUE WAS EMPTY, SET NEW TAIL
SETZM (T2) ;CLEAR LINKAGE IN ONLY ENTRY
RET]
MOVEM T3,(T2) ;POINT NEW HEAD AT OLD HEAD
RET
; QMQT - ADD A PACKET TO THE TAIL OF A QUEUE
; T1/ ADDRESS OF QUEUE DESCRIPTOR BLOCK
; T2/ ADDRESS OF PACKET TO BE ADDED TO TAIL OF QUEUE
; RETURNS +1: ALWAYS
QMQT: SETZM (T2) ;CLEAR LINKAGE IN NEW TAIL
HRRZ T3,(T1) ;GET CURRENT TAIL ADDRESS
HRRM T2,(T1) ;SET NEW TAIL
JUMPE T3,[HRLM T2,(T1) ;QUEUE WAS EMPTY, SET NEW HEAD
RET]
MOVEM T2,(T3) ;POINT OLD TAIL AT NEW TAIL
RET
; ROUTINES ON THIS PAGE ARE USED FOR SCANNING A QUEUE, POSSIBLY
; WITH THE INTENT OF DEQUEUEING ONE OF ITS ENTRIES.
; QUEUE-SCAN-BLOCK (QSB) OFFSETS:
QSB.QB==0 ;OFFSET TO QUEUE DESCRIPTOR BLOCK
QSB.LE==1 ;OFFSET TO LAST ENTRY SCANNED
QSB.LP==2 ;OFFSET TO ENTRY BEFORE LAST ENTRY
; QSCNIR - DRIVER FOR QSCANI MACRO
; CALL: QSCANI qdb-address
QSCNIR: PUSH P,QSB ;SAVE QSB AC
MOVEI QSB,1(P) ;GET ADDRESS OF QSB IN STACK
PUSH P,(CX) ;QSB.QB - QDB ADDRESS
PUSH P,[0] ;QSB.LE - ADDRESS OF LAST ENTRY SCANNED
PUSH P,[0] ;QSB.LP - ADDRESS OF ENTRY BEFORE THAT
CALL 1(CX) ;BACK TO CALLER FOR A WHILE
TRNA ;NON-SKIP RETURN
AOS -4(P) ;SKIP RETURN
ADJSP P,-3 ;DELETE QSB FROM STACK
POP P,QSB ;RESTORE QSB AC
RET ;TAKE +1 OR +2
; QMSCAN - RETURN ADDRESS OF NEXT ENTRY IN QUEUE
; QSB/ ADDRESS OF QUEUE SCAN BLOCK
; RETURNS +1: NO ENTRIES REMAINING IN QUEUE
; +2: SUCCESS, T2/ ADDRESS OF NEXT ENTRY IN QUEUE
QMSCAN: SKIPN T2,QSB.LE(QSB) ;FIRST CALL FOR THIS QUEUE SCAN?
JRST [ SETZM QSB.LP(QSB) ;YES, CLEAR OLD-LAST ADDRESS
HLRZ T2,@QSB.QB(QSB) ;GET ADDRESS OF HEAD PACKET
JRST QMS1]
MOVEM T2,QSB.LP(QSB) ;NOT FIRST TIME, SET OLD-LAST
MOVE T2,(T2) ;GET ADDRESS OF NEXT PACKET
QMS1: MOVEM T2,QSB.LE(QSB) ;SET NEW-LAST
JUMPN T2,RSKP ;TAKE +2 IF I FOUND SOMETHING
RET ;OTHERWISE +1
; QMDQS - DEQUEUE LAST PACKET RETURNED BY QMSCAN
; QSB/ ADDRESS OF QUEUE SCAN BLOCK
; RETURNS +1: ALWAYS, T2/ ADDRESS OF DEQUEUED PACKET
QMDQS: MOVE T2,QSB.LE(QSB) ;GET ADDRESS OF ENTRY TO BE DEQUEUED
MOVE T3,QSB.LP(QSB) ;GET ADDRESS OF PREVIOUS ENTRY
MOVEM T3,QSB.LE(QSB) ;FIX LE IN CASE QMSCAN IS CALLED AGAIN
SKIPN T4,(T2) ;GET ADDR OF FOLLOWING ENTRY
HRRM T3,@QSB.QB(QSB) ;IF DEQING TAIL, SET NEW TAIL IN QDB
JUMPE T3,[HRLM T4,@QSB.QB(QSB) ;DEQING HEAD, SET NEW HEAD IN QDB
RET]
MOVEM T4,(T3) ;NOT HEAD, FIX LINKAGE IN PREDECESSOR
RET
; REW - INITIATES A REWIND OPERATION ON AN MTA
; REWEA - LIKE REW, BUT ALSO SCHEDULES A CALLER-SPECIFIED ROUTINE
; WHEN THE REWIND IS COMPLETE
; T1/ ADDRESS OF END-ACTION ROUTINE THAT WILL BE ENTERED WHEN
; REWIND OPERATION IS COMPLETE (REWEA ONLY)
; MTA/ ADDR OF STATUS BLOCK
; RETURNS +1: DEVICE OFFLINE OR TIMED OUT
; +2: REWIND OPERATION INITIATED
; CONTROL IS GIVEN TO END-ACTION ROUTINE WHEN REWIND
; COMPLETES. MTA AC WILL HAVE ADDR OF MTA STATUS BLK.
; NOTE: SINCE NOT ALL THE MAGTAPE HARDWARE IS CONSCIENTIOUS ABOUT
; REPORTING STATUS CHANGES, THIS PROGRAM RELIES HEAVILY UPON
; DEVICE OPERATIONS (IN PARTICULAR, REWIND) TO DETERMINE THE
; LOADED/UNLOADED STATUS OF A TAPE DRIVE. THE BASIC LINE OF
; REASONING IS: IF SJ%OFS IS SET THEN BELIEVE IT; IF IT IS
; RESET, CHECK FOR ONLINE/OFFLINE BY ISSUING A REWIND MTOPR.
REW: SETZ T1,
REWEA: SAVEQ
MOVEI Q3,1 ;SET UP FOR SUCCESSFUL RETURN
MOVE Q2,T1 ;SAVE END-ACTION ADDRESS
LOAD T1,MTAREA
SKIPE T1 ;END-ACTION ALREADY REQUESTED?
CALL STOP ;YES, PROGRAM LOGIC FAILURE
CALL MTAGJF ;GET JFN NOW TO LIMIT GTJFN CALLS
CALL GMTADS ;GET MTA DEVICE STATUS
JXN T1,SJ%OFS,[SETZRO MA%LOD,MTAFLG(MTA) ;OFFLINE, SAY SO
CALLRET MTARJF] ;DUMP JFN AND GIVE ERROR RETURN
JXN T1,SJ%REW,[CALL MTARJF ;REWINDING ALREADY, DUMP JFN
STOR Q2,MTAREA ;SET END-ACTION ADDRESS
RETSKP] ;TAKE SUCCESSFUL RETURN
LOAD Q1,MA%OPN,MTAFLG(MTA) ;IS MTA JFN OPEN ALREADY?
JUMPE Q1,[CALL MTAOPI ;NO, OPEN IT
SKIPA ;OFFLINE
JRST .+1 ;OPENED
CALLRET MTARJF] ;DUMP JFN AND GIVE ERROR RETURN
CALL MTARJF ;UN-NEST PRIOR MTAGJF
CALL ELOGOF ;DON'T LOG ERRORS
MOVEI T1,.MOREW
MOVEI T2,1 ;REPEAT COUNT
CALL XMTOPR ;INITIATE REWIND
SETZ Q3, ;OFFLINE OR TIMED OUT, SET +1 RETURN
CALL ELOGON ;RESTORE ERROR LOGGING
STOR Q3,MA%LOD,MTAFLG(MTA) ;SET STATE (LOADED/UNLOADED)
SKIPN Q1 ;SKIP IF I DIDN'T OPEN MTA
CALL MTACLS ;I OPENED IT, SO I'LL CLOSE IT
JUMPE Q3,R ;TAKE ERROR RETURN IF INDICATED
STOR Q2,MTAREA ;GOOD RETURN, SET END-ACTION ADDR
RETSKP
; SCIDIS - DISABLE STATUS-CHANGE INTERRUPTS FROM MTA DEVICE
; SCIENA - ENABLE STATUS-CHANGE INTERRUPTS FROM MTA DEVICE
; WHEN A TAPE DRIVE IS ENABLED FOR STATUS-CHANGE INTERRUPTS, THE
; FOLLOWING EVENTS CAUSE A PSI INTERRUPT ON CHANNEL "TDSCCN":
; TRANSITION TO ONLINE, TRANSITION TO OFFLINE, REWIND COMPLETE
; MTA/ ADDR OF MTA STATUS BLOCK
; RETURNS +1: ALWAYS
SCIDIS: SKIPA T2,[0,,-1]
SCIENA: MOVEI T2,TDSCCN
MOVEI T1,2 ;BUILD ARG BLOCK IN CT1 AND CT2
STAKT
CALL MTAGJF ;GET JFN ON MTA
MOVEI T2,.MOOFL ;MTOPR FUNCTION CODE
MOVEI T3,CT1 ;GET ADDRESS OF ARG BLOCK
MTOPR ;ENABLE OR DISABLE
CALLRET MTARJF ;DUMP JFN AND EXIT
; SIXASC - CONVERT SIXBIT WORD TO ASCII STRING
; T1/ SIXBIT WORD
; T2/ BYTE POINTER TO ASCII DESTINATION STRING
; RETURNS +1: ALWAYS, 6 CHARACTERS PLACED IN DESTINATION STRING
SIXASC: MOVE T4,T2 ;MOVE POINTER OUT OF T2
MOVEI T3,6
SIXAS1: SETZ T2, ;CLEAR FOR SHIFT
ROTC T1,6 ;GET A SIXBIT CHARACTER
ADDI T2,40 ;CONVERT TO ASCII
IDPB T2,T4 ;STORE CHARACTER
SOJG T3,SIXAS1
RET
; SAVEQR - DRIVER FOR SAVEQ MACRO
SAVEQR: ADJSP P,3 ;CREATE ROOM ON STACK FOR Q1-Q3
DMOVEM Q1,-2(P) ;STACK Q1 & Q2
MOVEM Q3,0(P) ;STACK Q3
CALL (CX) ;BACK TO CALLER
TRNA ;NON-SKIP RETURN
AOS -3(P) ;SKIP RETURN
DMOVE Q1,-2(P) ;RESTORE Q1 & Q2
MOVE Q3,0(P) ;RESTORE Q3
ADJSP P,-3 ;DELETE TEMP SPACE FROM STACK
RET ;BACK TO CALLER'S CALLER +1 OR +2
; SAVETR - DRIVER FOR SAVET MACRO
SAVETR: ADJSP P,4 ;CREATE ROOM ON STACK FOR T1-T4
DMOVEM T1,-3(P) ;STACK T1 & T2
DMOVEM T3,-1(P) ;STACK T3 & T4
CALL (CX) ;BACK TO CALLER
TRNA ;NON-SKIP RETURN
AOS -4(P) ;SKIP RETURN
DMOVE T1,-3(P) ;RESTORE T1 & T2
DMOVE T3,-1(P) ; T3 & T4
ADJSP P,-4 ;DELETE TEMP SPACE FROM STACK
RET ;BACK TO CALLER'S CALLER +1 OR +2
; STAKTR - DRIVER FOR STAKT MACRO
STAKTR: ADJSP P,4 ;CREATE ROOM ON STACK FOR T1-T4
DMOVEM T1,-3(P) ;STACK T1 & T2
DMOVEM T3,-1(P) ;STACK T3 & T4
CALL (CX) ;BACK TO CALLER
TRNA ;NON-SKIP RETURN
AOS -4(P) ;SKIP RETURN
ADJSP P,-4 ;DELETE TEMP SPACE FROM STACK
RET ;BACK TO CALLER'S CALLER +1 OR +2
; SMPAV - SET AVAILABLE STATUS OF TAPE DRIVE
; T1/ 0 TO SET DRIVE UNAVAILABLE, 1 TO SET DRIVE AVAILABLE
; MTA/ ADDR OF MTA STATUS BLOCK
; RETURNS +1: ALWAYS
SMPAV: STAKT
CALL GMTADD ;GET DESIGNATOR
CALL DSFTGT ;GET DEVICE STATUS FILE ENTRY FOR DRIVE
MOVE T1,CT1 ;GET AVAILABLE OR UNAVAILABLE FLAG
STOR T1,MTS%AV,DSFE+MTS.SF ;STORE FLAG
CALLRET DSFPUT ;PUT ENTRY BACK IN FILE AND RETURN
; STMTA - CONVERT AN ASCIZ STRING TO AN MTA STATUS BLOCK ADDRESS
; T1/ ADDRESS OF ASCIZ STRING FOR MTA (IN FORM SUITABLE FOR STDEV JSYS)
; RETURNS +1: STRING DOES NOT SPECIFY MTA DEVICE
; +2: MTA/ ADDR OF MTA STATUS BLOCK
STMTA: HRLI T1,-1 ;GET STRING POINTER TO ASCIZ DEVNAME
STDEV ;TRANSLATE STRING TO DEV DESIGNATOR
RET ;NOT A DEVICE
MOVE T1,T2 ;GET DESIGNATOR
CALLRET DDMTA ;CONVERT TO MTA STATUS BLOCK ADDR IN MTA
; STOP - A FATAL ERROR WAS DETECTED; PROGRAM MUST HALT
; INVOKED BY:
; CALL STOP
STOP: MOVEM 17,CRSHAC+17 ;SAVE AC'S FROM CRASH
MOVEI 17,CRSHAC
BLT 17,CRSHAC+16
MOVEI T1,.FHSLF
SETZ T2,
GETER ;GET MOST RECENT ERROR
ERJMP .+1
HRRZM T2,LSTERR ;STORE IT FOR ANALYSIS
DIR ;DISABLE ALL INTERRUPTS
TMSG <
?MOUNTR crashing, PC = >
MOVEI T1,.PRIOU
HRRZ T2,CRSHAC+P ;GET TOP-OF-STACK ADDRESS
HRRZ T2,(T2) ;GET ADDRESS OF CALL + 1
SOS T2 ;GET ADDRESS OF CALL
MOVE T3,[NO%ZRO+NO%LFL+FLD(6,NO%COL)+10]
NOUT ;TYPE PC
JFCL
SKIPE TSTF ;TESTING?
JRST [ TMSG <
Test flag set, not saving MOUNTR core image> ;YES, DON'T SAVE CORE IMAGE
JRST STOP1]
; SAVE CORE IMAGE IN CRASH FILE
MOVX T1,GJ%SHT+GJ%FOU+GJ%ACC
HRROI T2,CFSPEC ;GET POINTER TO FILESPEC
GTJFN ;GET JFN ON CRASH FILE
JRST STOP2
MOVE Q2,T1 ;COPY JFN TO A SAFE PLACE
TMSG <
Saving MOUNTR core image on file >
MOVEI T1,.PRIOU
MOVE T2,Q2 ;JFN
SETZ T3,
JFNS ;DISPLAY FILESPEC
ERJMP STOP2
MOVSI T1,.FHSLF
HRR T1,Q2 ;FORK HANDLE,,JFN
MOVE T2,[-1000,,SS%CPY] ;ALL PAGES OF PROCESS, COPY-ON-WRITE
SETZ T3,
SSAVE ;SAVE CORE IMAGE
ERJMP STOP2
JRST STOP1 ;SKIP AROUND FAILURE-PROCESSOR
; ERROR SAVING CORE IMAGE, REPORT IT
STOP2: TMSG <
?Cannot save MOUNTR core image: >
MOVEI T1,.PRIOU
HRLOI T2,.FHSLF ;FORK HANDLE ,, -1 (MOST RECENT ERROR)
SETZ T3, ;NO LIMIT
ERSTR ;SHOW WHY SAVE FAILED
JFCL
JFCL
STOP1: MOVSI 17,CRSHAC ;GET BLT SOURCE,,DESTINATION
BLT 17,17 ;RESTORE AC'S TO CRASH STATE
HALTF
; STOPP - STOP BECAUSE OF SOME KIND OF STACK PROBLEM
; INVOKED BY:
; JSP CX,STOPP
STOPP: MOVEM P,BADP ;SAVE BAD P
MOVE P,[IOWD 4,PDL1] ;GET NEW P SO PDL IS PRESERVED
CALL STOP ;NOW CRASH
; PANIC INTERRUPT HANDLERS - PROGRAM IS CRASHING
PANPOV: JSP CX,STOPP ;PDL OVERFLOW
PANDAE: CALL STOP ;DATA ERROR
PANQTA: CALL STOP ;QUOTA EXCEEDED
PANILI: CALL STOP ;ILLEGAL INSTRUCTION
PANIRD: CALL STOP ;ILLEGAL READ
PANIWR: CALL STOP ;ILLEGAL WRITE
PANMSE: CALL STOP ;MACHINE SIZE EXCEEDED
; SYTSET - BUILD AND LOG SYSERR ENTRY FOR TAPE DRIVE STATUS CHANGE
; T1/ FUNCTION CODE (CS%ADV = SET AVAILABLE, CS%DDV = SET UNAVAILABLE)
; T2/ ADDRESS OF ASCIZ REASON, OR 0 IF NO REASON GIVEN
; MTA/ ADDR OF MTA STATUS BLOCK
; RETURNS +1: ALWAYS
SYTSET: SAVEQ
STKVAR <<SYTA,.MOISN+1>>
SETZM SYRMSG ;ZERO OUT SYSERR MESSAGE AREA
MOVE T4,[SYRMSG,,SYRMSG+1]
BLT T4,SYRMSG+SYRMSZ-1
; TRANSFER OPERATION CODE AND REASON TO MESSAGE
STOR T1,CS%OPR,SYRMSG+CS%OPW ;STORE OPERATION CODE INTO MESSAGE
MOVEI Q1,SYRHSZ+CS%SIZ ;ASSUME NO REASON GIVEN
SKIPN T1,T2 ;REASON GIVEN?
JRST SYTSE1 ;NO
MOVS Q2,T1 ;YES, COPY ADDRESS OF STRING FOR BLT
CALL ASCIZL ;GET # OF CHARACTERS
IDIVI T2,5 ;GET # OF WORDS MINUS 1
CAIL T2,SYRMSZ ;TOO LONG?
MOVEI T2,SYRMSZ-1 ;YES, TRUNCATE
MOVEI Q1,SYRHSZ+CS%SIZ+1(T2) ;SAVE SIZE OF ENTIRE MESSAGE
HRRI Q2,SYRMSG+CS%SIZ ;GET BLT DESTINATION
BLT Q2,SYRMSG+CS%SIZ(T2) ;TRANSFER STRING TO MESSAGE
MOVEI T1,CS%SIZ
STOR T1,CS%RSN,SYRMSG+CS%RSW ;STORE POINTER TO REASON
SYTSE1: MOVEI T1,SEC%CS ;GET CONFIGURATION STATUS CHANGE CODE
DPB T1,[POINT 9,SYRHDR,8] ;STORE INTO SYSERR ENTRY HEADER
; BUILD AND STORE SIXBIT DEVICE NAME (E.G. MTA0)
; (CAN'T STORE CHANNEL TYPE BECAUSE I DON'T KNOW IT)
CALL GMTADD ;GET MTA DEVICE DESIGNATOR
MOVE T2,T1 ;TO T2 FOR DEVST
HRROI T1,SYTA ;GET ADDR OF STRING AREA
DEVST ;GET ASCIZ DEVICE NAME (E.G. MTA0)
SETZM SYTA ;SHOULD NEVER FAIL
MOVEI T1,SYTA ;GET ADDR OF STRING
CALL ASCIZL ;GET LENGTH OF STRING FOR CVTA6
MOVSI T1,(POINT 7)
HRRI T1,SYTA ;GET POINTER TO STRING
CALL CVTA6 ;GET SIXBIT DEVICE NAME IN T1
SETZ T1, ;SHOULDN'T FAIL
MOVEM T1,SYRMSG+CS%DNM ;STORE SIXBIT DEVICE NAME
; GET DEVICE ADDRESS AND SERIAL#
JE MTASTE,,R ;DON'T BOTHER IF DEVICE NOT ASSIGNED
MOVEI T1,.MOISN
MOVEM T1,.MOICT+SYTA ;SET ARG BLOCK LENGTH IN ARG BLOCK
CALL MTAGJF ;GET MTA JFN IN T1
MOVEI T2,.MOINF ;GET MTOPR FUNCTION CODE
MOVEI T3,SYTA ;GET ADDRESS OF ARG BLOCK
MTOPR ;GET MTA INFO FROM MONITOR
CALL MTARJF ;DUMP JFN
MOVE T1,.MOISN+SYTA ;GET UNIT ADDRESS AND SERIAL#
MOVEM T1,SYRMSG+CS%ADS ;STORE IN SYSERR MESSAGE
MOVE T1,.MOITP+SYTA ;GET DRIVE TYPE CODE
STOR T1,CS%UTP,SYRMSG+CS%HTP ;STUFF IT
; LOG THE MESSAGE
MOVEI T1,SYRHDR ;GET ADDRESS OF SYSERR MESSAGE
MOVE T2,Q1 ;GET # OF WORDS IN MESSAGE
SKIPN TSTF ;DON'T LOG SYSERRS IF TESTING
SYERR ;LOG IT
ERJMP R ;IGNORE ERRORS
RET
; UNLOAD - UNLOAD A VOLUME FROM AN MTA DEVICE
; MTA/ ADDR OF MTA STATUS BLOCK
; RETURNS +1: ALWAYS
UNLOAD: SAVEQ
CALL MTAGJF ;GET JFN NOW TO LIMIT GTJFN CALLS
CALL GMTADS ;GET DEVICE STATUS IN T1
JXN T1,SJ%OFS,[SETZRO MA%LOD,MTAFLG(MTA) ;OFFLINE, SAY SO
CALLRET MTARJF] ;DUMP JFN AND RETURN
JXN T1,SJ%REW,[SETONE MA%ULP,MTAFLG(MTA) ;SET UNLOAD-PENDING
CALLRET MTARJF] ;DUMP JFN AND RETURN
SETZRO MA%LOD,MTAFLG(MTA) ;SET STATUS TO UNLOADED
LOAD Q1,MA%OPN,MTAFLG(MTA) ;IS MTA JFN OPEN ALREADY?
JUMPE Q1,[CALL MTAOPI ;NO, OPEN IT
SKIPA ;OFFLINE
JRST .+1 ;OPENED
CALLRET MTARJF] ;DUMP JFN AND GIVE ERROR RETURN
CALL MTARJF ;UN-NEST PRIOR MTAGJF
CALL ELOGOF ;DON'T LOG ERRORS
MOVEI T1,.MORUL
MOVEI T2,1 ;REPEAT COUNT
CALL XMTOPR ;INITIATE REWIND-AND-UNLOAD
JFCL
CALL ELOGON ;RESUME LOGGING ERRORS
JUMPN Q1,R ;EXIT IF I DIDN'T OPEN MTA
CALLRET MTACLS ;I OPENED IT, SO I'LL CLOSE IT
; VQADD - APPEND A NEW VOLID TO THE END OF THE RSB VOLID LIST
; T1/ SIXBIT VOLID
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: NO SLOTS LEFT IN VOLID POOL, REQUEST ABORTED
; +2: SUCCESS
VQADD: STAKT
MOVEI T1,FVSQDB ;POINT TO FREE POOL QDB
CALL QMDQH ;DEQUEUE HEAD OF FREE CHAIN
JRST [ ABTRET (MREQ31)] ;NO FREE SLOTS, ABORT REQUEST
MOVE T1,CT1 ;T2/ SLOT ADDR, GET VOLID
MOVEM T1,1(T2) ;STORE VOLID IN SLOT
MOVEI T1,RSBVLS(RSB) ;GET ADDR OF RSB VOLID LIST QDB
CALL QMQT ;ADD NEW VOLID TO END OF RSB VOLID QUEUE
RETSKP
; VQCNT - RETURN THE LENGTH OF THE RSB VOLID LIST
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: ALWAYS, T1/ LENGTH OF VOLID LIST
VQCNT: SETZ T1, ;CLEAR COUNTER
HLRZ T2,RSBVLS(RSB) ;GET HEAD OF QUEUE
VQCNT1: JUMPE T2,R ;END OF QUEUE, RETURN
MOVE T2,(T2) ;NOT THE END, GET ADDR OF NEXT ENTRY
AOJA T1,VQCNT1 ;COUNT THIS ENTRY AND LOOP
; VQDEL - RETURN RSB VOLID QUEUE TO FREE VOLID SLOT POOL
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: ALWAYS
VQDEL: SKIPN T1,RSBVLS(RSB) ;IS QUEUE EMPTY?
RET ;YES, NOTHING TO DO
SETZM RSBVLS(RSB) ;CLEAR QDB IN RSB
HRRZ T2,FVSQDB ;GET CURRENT FREE POOL TAIL
JUMPE T2,[MOVEM T1,FVSQDB ;NO FREE POOL, SO CREATE IT
RET]
HLRZM T1,(T2) ;POINT CURRENT TAIL AT RSB LIST HEAD
HRRM T1,FVSQDB ;SET TAIL OF FREE POOL TO RSB TAIL
RET
; VQGCV - GET CURRENT VOLID FOR TAPE MOUNT REQUEST
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: ALWAYS, T1/ 0 IF SCRATCH TAPE, ELSE SIXBIT VOLID
VQGCV: LOAD T1,RSBCV ;GET CURRENT VOLUME #
CALL VQGET ;GET VOLID IN T1
SETZ T1, ;BAD INDEX, MUST BE A SCRATCH
RET
; VQGET - RETURN A VOLID FROM RSB VOLID LIST
; VQSET - STORE A VOLID INTO RSB VOLID LIST
; T1/ ORDINAL NUMBER OF VOLID TO BE RETURNED
; T2/ SIXBIT VOLID TO BE STORED (VQSET ONLY)
; RSB/ ADDR OF REQUEST STATUS BLOCK
; RETURNS +1: VOLID NUMBER OUT OF RANGE
; +2: SUCCESS, T1/ SIXBIT VOLID
VQGET: SKIPA T3,[MOVE T1,1(T2)]
VQSET: MOVE T3,[MOVEM T1,1(T2)]
JUMPLE T1,R ;CHECK FOR FUNNY INPUT
QSCANI <RSBVLS(RSB)> ;SET UP TO SCAN RSB VOLID LIST
STAKT
VQGET1: CALL QMSCAN ;GET NEXT VOLID IN LIST
RET ;NONE LEFT, FAILED
SOSLE CT1 ;IS THIS THE ONE THE CALLER WANTED?
JRST VQGET1 ;NO, CONTINUE SCAN
MOVE T1,CT2 ;GET VOLID IN CASE OF VQSET
XCT CT3 ;LOAD OR STORE VOLID AS REQUESTED
RETSKP
; VQSPIN - INITIALIZE FREE POOL OF VOLID SLOTS
; RETURNS +1: ALWAYS
VQSPIN: SAVEQ
SETZM FVSQDB ;SET QUEUE EMPTY INITIALLY
MOVEI Q1,VOLP0 ;GET ADDRESS OF 1ST SLOT IN POOL
MOVEI Q2,VOLPN ;GET # OF SLOTS IN POOL
VQSPI1: MOVEI T1,FVSQDB ;GET QDB ADDRESS
MOVE T2,Q1 ;GET ADDRESS OF NEXT SLOT
CALL QMQT ;ADD SLOT TO TAIL OF FREE LIST
ADDI Q1,2 ;POINT TO NEXT SLOT
SOJG Q2,VQSPI1 ;LOOP
RET
; WRTP - WRITE-PROTECT MOUNTR'S CODE TO CATCH STRAY STORES
; RETURNS +1: ALWAYS
WRTP: MOVEI T1,PURE ;COMPUTE PAGE # OF FIRST
LSH T1,-11 ; PAGE OF NON-MODIFYABLE MEMORY
HRLI T1,.FHSLF ;GET FORK HANDLE ,, PAGE#
MOVX T2,PA%RD+PA%EX ;REQUEST READ AND EXECUTE ACCESS
MOVEI T3,.RLEND ;COMPUTE PAGE # OF LAST READ-ONLY
LSH T3,-11 ; PAGE PLUS 1
WRTP1: CAIG T3,(T1) ;ALL DONE?
RET ;YES
SPACS ;SET PAGE TO READ & EXECUTE
AOJA T1,WRTP1 ;INCREMENT PAGE # AND LOOP
; XMTOPR - EXECUTE MAGTAPE MTOPR FUNCTION A GIVEN NUMBER OF TIMES
; T1/ MTOPR FUNCTION CODE
; T2/ NUMBER OF TIMES TO EXECUTE
; MTA/ ADDR OF MTA STATUS BLOCK
; RETURNS +1: DEVICE FAILURE, T1/ 0=ERROR 1=TIMEOUT
; +2: SUCCESS
XMTOPR: SAVEQ
DMOVE Q1,T1 ;SAVE FUNCTION CODE AND REPEAT COUNT
XMTOP1: LOAD T1,MTAJFN ;GET JFN
MOVE T2,Q1 ;GET MTOPR FUNCTION CODE
IOXCT MTOPR,XMTOP2,XMTOP3 ;START POSITIONING OPERATION
MOVEI T2,.MONOP
IOXCT MTOPR,XMTOP2,XMTOP3 ;WAIT TILL OPERATION COMPLETES
CALL CLRTAP ;CLEAR ERRORS
JRST XMTOP3 ;TIMED OUT
TXNE T2,MT%DVE+MT%DAE ;ANY SERIOUS PROBLEMS?
JRST XMTOP2 ;YES
SOJG Q2,XMTOP1 ;LOOP TILL DONE
RETSKP ;SUCCESS
XMTOP2: TDZA T1,T1 ;ERROR, PUT 0 IN T1
XMTOP3: MOVEI T1,1 ;TIMEOUT, PUT 1 IN T1
RET ;TAKE ERROR RETURN
; XMTREP - REPORT MTA DEVICE FAILURE TO OPERATOR
; T1/ 0 TO REPORT DEVICE ERROR, 1 TO REPORT DEVICE TIMEOUT
; MTA/ ADDR OF MTA STATUS BLOCK
; RETURNS +1: ALWAYS
XMTREP: JUMPN T1,[CALLRET WOTIMO] ;TIMEOUT, RETURN THROUGH TIMEOUT CODE
TMCT <%I%M positioning operation failed>
MOVEI T3,[ASCIZ/Tape Positioning Error/]
CALLRET BTWTO ;TELL OPERATOR AND RETURN
; XMUTIL - EXECUTE MUTIL FOR CALLER
; T1-T4/ ARGUMENT BLOCK WORDS 0-3
; RETURNS +1: ERROR ON MUTIL CALL, CODE IN T1
; +2: SUCCESS, WITH COPY OF ARG BLOCK IN T1-T4
XMUTIL: SAVET ;SAVE CALLER'S AC'S ON STACK
MOVEI T1,4 ;ARGUMENT BLOCK LENGTH
MOVEI T2,CT1 ;ADDRESS OF ARGUMENT BLOCK
MUTIL ;DO MUTIL (ARG BLOCK IS IN STACK)
JRST [ MOVEM T1,CT1 ;ERROR, SUPPLY ERROR TO CALLER
RET] ;TAKE ERROR RETURN
RETSKP ;GOOD RETURN, T1-T4 COME OFF STACK
LIT: ;ADDRESS OF START OF LITERAL POOL
END <ENTVSZ,,ENTVEC>