IDTITL 0405,AVD, .TITLE AVD - ASSIGN VIRTUAL DISK .IDENT /Y04.05/ .SBTTL AVD - TITLE PAGE .NLIST BEX .LIST MEB .ENABL LC ;**- ; Module name: AVD - ASSIGN VIRTUAL DISK ; ; Version Y04.05 Last edit: 06-MAR-81 16:08 ; Status: Released for test ; ; ASSIGN VIRTUAL DISK DEVICE TO SPECIFIED FILE. ; ; AUTHOR: R.W. STAMERJOHN MAPC 19-MAR-79 ; ; Revision history: ; ; Version X04.00 13-NOV-80 09:19 - 14-NOV-80 09:51 ; Modified by: K.J. CROSS ; COMPLETELY REVISED. NEW FORMAT, USES PIPUTL ROUTINES. ; ; Version Y04.00 14-NOV-80 09:51 - 18-NOV-80 09:00 ; Modified by: KJC ; ; Version Y04.01 18-NOV-80 09:01 - 19-NOV-80 07:59 ; Modified by: KJC ; FIX BUG IN SWITCHES. ADD "PUBLIC" TO LISTINGS. ; ; Version Y04.02 19-NOV-80 07:59 - 20-NOV-80 08:53 ; Modified by: KJC ; SET PRIVILEGED WHILE DOING ASN /LOGIN ; ; Version Y04.03 20-NOV-80 08:53 - 26-NOV-80 09:36 ; Modified by: KJC ; CHECK FOR FILE ALREADY ASSOCIATED ON ANOTHER UNIT. ; ; Version Y04.04 26-NOV-80 09:36 - 06-MAR-81 16:08 ; Modified by: KJC ; FIX /LI WHEN A SINGLE UNIT IS SPECIFIED ; ; Version Y04.05 06-MAR-81 16:08 - 06-MAR-81 16:08 ; Modified by: KJC ; ADDED /BR LISTING ; ;**- ; ; ************************************************************************ ; * ; THIS PROGRAM IS PROVIDED ON AN "AS IS" BASIS ONLY. * ; * ; FULL PERMISSION AND CONSENT IS HEREBY GIVEN TO DECUS AND TO THE DECUS * ; SPECIAL INTEREST GROUPS TO REPRODUCE, DISTRIBUTE, AND PUBLISH AND * ; PERMIT OTHERS TO REPRODUCE IN WHOLE OR IN PART, IN ANY FORM AND * ; WITHOUT RESTRICTION, THIS PROGRAM AND ANY INFORMATION RELATING THERETO * ; * ; ************************************************************************ ; .SBTTL AVD - DECLARATIONS ; ; MACRO LIBRARY CALLS: ; ; SYMBOLIC DEFINITIONS. ; .MCALL F11DF$ ;DEFINE VCB OFFSETS F11DF$ .MCALL DCBDF$ ;DEFINE DCB OFFSETS DCBDF$ .MCALL HDRDF$ ;DEFINE TASK HEADER OFFSETS HDRDF$ .MCALL UCBDF$ ;DEFINE UCB OFFSETS UCBDF$ <:>,<=> .MCALL TCBDF$ ;DEFINE TCB OFFSETS TCBDF$ ,<=> ; ; DIRECTIVE MACROS. ; .MCALL DIR$ ;ISSUE DIRECTIVE .MCALL ALUN$S ;ASSIGN LUN .MCALL GLUN$S ;GET LUN INFORMATION .MCALL EXIT$S ;EXIT SYSTEM .MCALL EXST$S ;EXIT WITH STATUS .MCALL GMCR$ ;GET MCR COMMAND LINE .MCALL QIOW$,QIOW$S ;ISSUE QIO AND WAIT .MCALL SVTK$S ;SETUP SST VECTOR TABLE .MCALL SPWN$ ;SPAWN .MCALL WTSE$S ;WAITFOR ; ; CSI MACROS. ; .MCALL CSI$ ;DEFINE CSI OFFSETS CSI$ .MCALL CSI$SW,CSI$SV,CSI$ND ;SWITCH TABLE MACROS .MCALL CSI$1,CSI$2 ;PARSE COMMAND LINE ; ; FCS MACROS. ; .MCALL FDOF$L ;DEFINE FCS OFFSETS FDOF$L .MCALL NBOF$L ;DEFINE FNB OFFSETS NBOF$L .MCALL FCSBT$ ;DEFINE FCS BIT MASKS. FCSBT$ .MCALL FDBDF$ ;DEFINE FDB .MCALL FDAT$A ;DEFINE FILE ATTRIBUTES .MCALL FDRC$A ;DEFINE RECORD ACCESS .MCALL FDBK$A ;DEFINE BLOCK ACCESS .MCALL FDOP$A ;DEFINE OPEN CHARACTERISTICS .MCALL FSRSZ$ ;DEFINE FSR REGION .MCALL NMBLK$ ;DEFINE DEFAULT FILENAME BLOCK ; ; OTHER MACROS. ; .MCALL CALLR .SBTTL AVD - MACROS ; ; DEFINE SYSTEM STATE MACRO. ; .MACRO SYSTEM ADR EMT 376 .WORD ADR .ENDM SYSTEM ; ; DEFINE FILES-11 QIO MACRO. ; .MACRO F11QIO DPB,ADR DIR$ #DPB .IF NB ADR BCS ADR CMPB #IS.SUC,IOSTAT BNE ADR .ENDC .ENDM F11QIO ; ; THIS MACRO BUILDS THE SWITCH TABLE FOR AVD. ; ; IT CREATES AUXILLIARY TABLES WHICH CONTAIN: ; ; .PSECT DSKSW ; DSKTBL: .WORD SWIBIT ;BIT TO SET @SWADR ; .WORD SWADR ;ADDRESS OF SWITCH WORD ; .WORD HOVAL ;HIGH-ORDER DISK SIZE ; .WORD LOVAL ;LOW-ORDER DISK SIZE ; .ASCII "SWNAME";6-CHARACTER DISK NAME (SWITCH) ; .WORD SWIBIT ;BIT FOR NEXT DEVICE ; . ; . ; . ; .WORD 0 ;0 IN SWIBIT LOCATION INDICATES END OF TABLE ; ; .PSECT DSWTB ; DSWTBL: .WORD SWTCH+0 ;ADDRESS OF FIRST SWITCH WORD ; .WORD SWTCH+2 ;ADDRESS OF SECOND SWITCH WORD ; . ; . ; . ; .WORD 0 ;ZERO TERMINATES THE TABLE ; ; .PSECT SWTCH ; .WORD 0 ;FIRST SWITCH WORD ; .WORD 0 ;SECOND SWITCH WORD ; . ; . ; . ; .WORD 0 ;NTH SWITCH WORD (N=NO. OF SWITCHES/16 + 1) ; ; THE MACRO IS INVOKED AS FOLLOWS: ; ; DSKSW$ HOVAL,LOVAL,SWNAME ; ; THE SWIBIT VALUES AND SWITCH WORDS WILL AUTOMATICALLY BE GENERATED ; AS THEY ARE NEEDED. ; .MACRO DSKSW$ HOVAL,LOVAL,SWNAME .NCHR NNAM,SWNAME .IF LE NNAM .ERROR ;NULL SWITCH NAME INVALID .PSECT .MEXIT .ENDC .IF GT NNAM-6 .ERROR ;SWITCH NAME TOO LONG: 'SWNAME' .PSECT .MEXIT .ENDC .IF EQ SWBIT .IF EQ SWFLG .PSECT SWTCH SWADR = . ;SWITCH WORD ADDRESS SWFLG = -1 ;FIRST SWITCH WORD DEFINED .WORD 0 ;SWITCH WORD .PSECT DSWTB DSWTBL = . .WORD SWADR ;START OF SWITCH WORD ADDRESS TABLE DSADR = . ;ADDRESS OF NEXT WORD .WORD 0 ;TERMINATE WITH NULL .PSECT .IFF ;EQ SWFLG .PSECT SWTCH SWADR = . ;SWITCH WORD ADDRESS .WORD 0 ;SWITCH WORD .PSECT DSWTB . = DSADR ;ADDRESS OF NEXT LOCATION IN TABLE .WORD SWADR ;ADDRESS OF SWITCH WORD DSADR = . ;ADDRESS OF NEXT SWITCH WORD .WORD 0 ;TERMINATE WITH NULL .PSECT .ENDC ;EQ SWADR SWBIT = 1 ;INIT SWITCH BIT VALUE .ENDC ;EQ SWBIT CSI$SW 'SWNAME',SWBIT,SWADR,SET,,,EXACT .PSECT DSKSW .IF EQ DSKFLG DSKTBL = . ;START OF DISK SWITCH TABLE DSKSWA = . ;ADDRESS OF NEXT TABLE ENTRY DSKFLG = -1 ;SET FLAG INDICATING DSKTBL DEFINED .ENDC ;EQ DSKTBL . = DSKSWA ;ADDRESS OF NEXT TABLE ENTRY .WORD SWBIT,SWADR,HOVAL,LOVAL .ASCII "'SWNAME'" .REPT 6-NNAM .ASCII " " .ENDR DSKSWA = . ;ADDRESS OF NEXT TABLE ENTRY .WORD 0 ;TERMINATE WITH NULL .PSECT SWBIT = SWBIT + SWBIT .ENDM ; ; DEFINE OFFSETS WITHIN THE TABLE ENTRIES. ; .ASECT . = 0 D.BIT: .BLKW 1 ;BIT TURNED ON WHEN SWITCH SPECIFIED D.SWAD: .BLKW 1 ;SWITCH WORD with BITS SET D.SIZE: .BLKW 2 ;DOUBLE-WORD SIZE OF ASSOCIATED DISK D.NAME: .BLKW 3 ;6-CHARACTER SWITCH NAME D.LENG = . ;LENGTH OF A TABLE ENTRY .PSECT ; ; BEFORE CALLING THE MACRO, FIRST INITIALIZE THE FOLLOWING VARIABLES: ; SWBIT = 0 SWFLG = 0 DSKFLG = 0 DSWTBL = 0 .SBTTL AVD - LOCAL DATA ; ; LOCAL SYMBOLS: ; ; LOGICAL UNITS/EVENT FLAGS. ; TSTLUN = 1 ;AVD WORKING LUN TTYLUN = 2 ;TERMINAL I/O LUN FILLUN = 3 ;FILE I/O LUN MSGLUN = 4 ;QIOSYM MESSAGE FILE LUN MSGEFN = 4 ;EVENT FLAG FOR QIOSYM EV.QIO = 1 ;QIO WAIT EVENT FLAG MCREFN = 2 ;SPAWN WAIT EVENT FLAG ; ; SWITCH BIT MASKS. ; FL.RON = 1 ;READ-ONLY ACCESS FL.CRE = 2 ;CREATE FILE FL.HEL = 4 ;HELP! FL.LST = 10 ;LIST ASSIGNMENTS FL.NM = 20 ;/NM = NO MESSAGES (EXCEPT ERRORS) FL.VM = 40 ;ASSIGN VDN: TO VM: FL.ID = 100 ;DISPLAY ID FL.BR = 200 ;/BREIF LISTING ; ; LOCAL DATA: ; ; DIRECTIVES. ; .NLIST MEB GETCMD: GMCR$ ;GET COMMAND LINE CREDPB: QIOW$ IO.CRE,FILLUN,EV.QIO,,IOSTAT,, ENADPB: QIOW$ IO.ENA,FILLUN,EV.QIO,,IOSTAT,,<0,0,0,0,0,FILFDB+F.FNB> DELDPB: QIOW$ IO.DEL,FILLUN,EV.QIO,,IOSTAT,, FNADPB: QIOW$ IO.FNA,FILLUN,EV.QIO,,IOSTAT,,<0,0,0,0,0,FILFDB+F.FNB> ACWDPB: QIOW$ IO.ACW,FILLUN,EV.QIO,,IOSTAT,, DACDPB: QIOW$ IO.DAC,FILLUN,EV.QIO,,IOSTAT,, WATDPB: QIOW$ IO.WAT,FILLUN,EV.QIO,,IOSTAT,, MCR1: SPWN$ MCR...,,,,,MCREFN,,,OUTBUF,0 ;SPAWN AN MCR COMMMAND LINE ; ; STT VECTOR TABLE. ; SSTTBL: .WORD 0 ;ODD ADDRESS .WORD 0 ;MEMORY PROTECTION .WORD 0 ;T-BIT TRAP OR BPT .WORD 0 ;IOT TRAP .WORD 0 ;RESERVED INSTRUCTION .WORD 0 ;NON-RSX EMT INSTRUCTION .WORD .ERTRP ;TRAP INSTRUCTION (IN PIPUTL) SSTSIZ = <.-SSTTBL>/2 ; ; .ABORT IS VECTORED THROUGH WHEN AN ERROUX MACRO IS EXECUTED. ; $DFNAM AND $IDR50 CONTAINS THE DEFAULT TASK NAME IN RAD50. ; .EXSTS IS USED IN EXST$. ; GCMLCB == 0 .ABORT:: ERRSRV $DFNAM:: $IDR50:: .RAD50 /AVD/ .EXSTS:: EX$SUC ;ASSUME SUCCESS ; ; CSI CONTROL BLOCK. ; CSIBLK: .BLKB C.SIZE ;DEFINE CSI EXTENSION BLOCK .EVEN ; ; CSI SWITCH TABLES. ; .NLIST MEB SWTTAB: CSI$SW CR,FL.CRE,SWITCH,SET,,CREVAL, CSI$SW RO,FL.RON,SWITCH,SET,,,EXACT CSI$SW HELP,FL.HEL,SWITCH,SET CSI$SW LIST,FL.LST,SWITCH,SET CSI$SW BREIF,FL.LST!FL.BR,SWITCH,SET CSI$SW NM,FL.NM,SWITCH,SET CSI$SW VM,FL.VM,SWITCH,SET CSI$SW ID,FL.ID,SWITCH,SET DSKSW$ 0,4800.,RK05 DSKSW$ 0,27126.,RK06 DSKSW$ 0,53790.,RK07 DSKSW$ 0,24000,RL01 DSKSW$ 0,50000,RL02 DSKSW$ 2,1140,RM02 DSKSW$ 2,1140,RM03 DSKSW$ 0,116100,RP02 DSKSW$ 1,34200,RP03 DSKSW$ 2,117426,RP04 DSKSW$ 2,117426,RP05 DSKSW$ 5,31276,RP06 DSKSW$ 0,2000,RS03 DSKSW$ 0,4000,RS04 DSKSW$ 0,1024.,RF11 DSKSW$ 0,494.,RX01 DSKSW$ 0,988.,RX02 CSI$ND CREVAL: CSI$SV ASCII,STRING,8. CSI$ND .LIST MEB ; ; FAKE FILE FDB (FOR PARSING PURPOSES). ; FILFDB: FDBDF$ ;DEFINE FDB BLOCK. FDAT$A R.FIX,,512. ;DEFINE FILE ATTRIBUTES FDRC$A FD.RWM ;DEFINE RECORD ACCESS FDBK$A ;DEFINE BLOCK ACCESS FDOP$A FILLUN ;DEFINE OPEN ACCESS ; ; DEFAULT FILENAME BLOCK. ; FILDFB: NMBLK$ ,DSK,,SY,0 ;DEFAULT FILENAME ; ; CREATE WRITE ATTRIBUTE LIST. ; CRELST: .BYTE 02,02 ;WRITE PROTECTION .WORD PROATT ; .BYTE 04,16 ;WRITE FCS ATTRIBUTES .WORD FILFDB ; .BYTE 05,12 ;WRITE FILENAME ATTRIBUTES .WORD FILFDB+F.FNB+N.FNAM ; .BYTE 0,0 ;END-OF-LIST PROATT: .WORD 177714 ;FILE PROTECTION [RW,RW,,] ; ; READ ATTRIBUTE LIST. ; ACWLST: .BYTE -11,12 ;READ STATISTICS BLOCK .WORD STAATT ; .BYTE 0,0 ;END-OF-LIST STAATT: .BLKB 12 ;STATISTICS BLOCK ; ; WRITE ATTRIBUTE LIST. ; WATLST: .BYTE 03,01 ;WRITE USER CHARACTERISTICS .WORD WATATT ; .BYTE 0,0 ;END-OF-LIST WATATT: .BYTE 300 ;MARK CONTIGIOUS, LOCKED .EVEN ; ; OTHER VARIOUS BUFFERS. ; IOSTAT: .WORD 0,0 ;I/O STATUS BLOCK STRING: .BLKB 8. ;DISK BLOCK STRING BLKNUM: .BLKW 2 ;DISK BLOCK NUMBER UCBADR: .WORD 0 ;VD: UCB ADDRESS EXTADR: .WORD 0 ;VIRTUAL EXTENSION BLOCK ADDRESS TIUCB: .WORD 0 ;TI: UCB ADDRESS VDUNIT: .WORD 0 ;VD: UNIT NUMBER VDUCB: .WORD 0 ;VD: UCB ADDRESS PRIVST: .WORD 0 ;PRIV/NON-PRIV STATUS, 0 = PRIV SWITCH: .WORD 0 ;SPECIAL FUNCTION SWITCH FILUIC: .WORD 0 ;FILE'S BINARY UIC LIFLAG: .WORD 0 ;0 = NOT A /LI OPERATION ;1 = /LI FOR ONE DEVICE ;-1 = /LI FOR ALL VD'S ; ; ERROR MESSAGES. ; MSG INFN, MSG HWAR,<*Warning* - No operations are performed with /HELP> MSG PRSE, MSG NOVD, MSG FATL, MSG NOCM, MSG INCM, MSG NOVS,<*Warning* - No VS: units available for assignment> MSG SPER,<*Warning* - Error spawning MCR command line for ASN> MSG NOEQ, MSG INVD, MSG SERR, MSG INUN, MSG VDUK, MSG VDNL, MSG VDRD, MSG VDVD, MSG POOL, MSG NOAL, MSG BDSK, MSG AMSW, MSG PRIV, MSG ERCR, MSG FNF, MSG ACCS, MSG NOTC, ; ; FSR REGION ; FSRSZ$ 0 ;NO RECORD I/O ; ; MCR COMMAND LINES. ; ; NOTE: DON'T SEPERATE THE FOLLOWING LINES. ; INFO1: .ASCII #%NLogical assignment: # ASNSTR: .ASCIZ #ASN VD%O:=VS%O:/LOGIN# INFO2: .ASCII #%NLogical assignment: # AVMSTR: .ASCIZ #ASN VD%O:=VM:# ; ; LOCAL DATA FOR "HELP" OPERATION. ; OUTBUF: .BLKB 512. ;STRING OUTPUT BUFFER HLPMSG: .ASCII #%2N%4SAVD assigns a contiguous disk file to a virtual disk VDn:.# .ascii #%N%4SThe first available virtual disk unit will be used, and# .ascii #%N%8Swill be assigned to the first available logical VSn:,# .ascii #%N%8S(e.g., ASN VD3:=VS:/LOGIN is effectively executed).# .ASCII #%2N%4SThe user must be privileged in order to create a virtual disk.# .ASCII #%2N%4SCommand format:%2N#<11>#>AVD filespec[/sw]%2N# .ASCII <11>#where [/sw] is one of the following switches:%2N#<11><11> .ASCII #/LI#<11><11>#List the status of virtual disks%N#<11><11> .ascii #/BR#<11><11>#Breif listing of virtual disks%2N#<11><11> .ASCII #/ID#<11><11>#Print the current version number and exit%N#<11><11> .ascii #/HE[lp]#<11><11>#Print this help message and exit%N#<11><11> .ascii #/NM#<11><11>#Suppress informational messages%N#<11><11> .ascii #/VM#<11><11>#Assign VDn: to VM: (i.e., ASN VDn:=VM:)%N#<11><11> .ASCII #/RO#<11><11>#Define VDn: with READONLY access%N#<11><11> .ASCIZ #/CR:mmmm#<11>#Create VDn: with mmmm (decimal) disk blocks%N# .EVEN DSKSTR: .ASCIZ <11><11>#/%6A#<11><11>#Create disk with %T. blocks%N# ENDMSG: .ASCII #%N%4SIf no switches are specified, then the # .ASCII #disk file must already exist.# CRLF: .ASCIZ #%N# FNMSTR: .ASCIZ #%X# OFLSTR: .ASCIZ #OFFLINE# SIZSTR: .ASCIZ #%VS#<11>#%T./%T.# UNMSTR: .ASCIZ #%VS#<11>#UNMOUNTED#<11> PRISTR: .ASCIZ #PRIVATE# PUBSTR: .ASCIZ #PUBLIC# WRNSTR: .ASCIZ <11><7><7>#** WARNING -- # ENDWRN: .ASCIZ # is not mounted. **#<7><7>#%N# .EVEN ARGBLK: .BLKW 6 ;ARGUMENT BLOCK FOR $EDMSG .SBTTL AVD * MAIN-LINE TASK CODE ; ;+ ; THIS SECTION CONTAINS THE ENTRY LEVEL CODE FOR THE AVD TASK. ; IN GENERAL, THE STEPS PERFORMED ARE AS FOLLOWS: ; ; 1. GET THE COMMAND LINE. ; 2. PARSE COMMAND INTO ELEMENTS. ; 3. DETERMINE FIRST AVAILABLE VD: AND VS: ; 4. ALLOCATE EXTENSION BLOCK IF VDN: IS AVAILABLE. ; 5. IF NEW FILE, CREATE FILE OF SPECIFIED SIZE. ; 6. ASSIGN FILE TO VIRTUAL DISK. ; ; INPUT: ; ; MCR COMMAND LINE IN FORM SHOWN BELOW. ; ; AVD /HELP ; ; OR ; ; AVD [VDN:]/LI [/BR] ; ; OR ; ; AVD FILE[/SW] ; ; FILE FILE TO BE USED AS VIRTUAL DISK ; /SW SWITCHES - ONE OF FOLLOWING ; ; /NM SUPPRESS INFORMATIONAL MESSAGES ; /VM ASSIGN VDN: TO VM: ALSO ; /RO ALLOW ONLY READ ACCESS ; /CR:N CREATE FILE WITH N BLOCKS ; /XXXX CREATE FILE EMULATING DEVICE "XXXX" ; ; OUTPUT: ; ; VIRTUAL DISK ASSIGNED TO FILE OR ERROR MESSAGE ; OUTPUT TO USER'S TERMINAL. ; ;- ; AVD:: ;REF. LABEL. ; ; SET UP THINGS IN PIPUTL. ; MOV #MSGLUN,.EOLUN ;LUN FOR QIOSYM.MSG MOV #MSGEFN,.EOEFN ;EVENT FLAG FOR MSGLUN ALUN$S #MSGLUN,#"LB,#0 ;MAKE SURE LUN IS ASSIGNED TO LB: MOV $DFNAM,R1 ;GET DEFAULT TASK NAME CALL $GTKNM ;GET OUR TASK NAME MOV R1,$IDR50 ;STORE IT ; ; SETUP SST VECTOR TABLE AND FSR REGION FOR PROCESSING. ; SVTK$S #SSTTBL,#SSTSIZ ;SETUP SST VECTOR TABLE CALL .FINIT ;INITIALIZE FSR REGION ; ; ZERO VARIOUS VARIABLES. ; CLR BLKNUM ;CLEAR NUMBER OF BLOCK TO ALLOCATE CLR UCBADR ;CLEAR VDN: UCB ADDRESS CLR EXTADR ;CLEAR EXTENSION BLOCK ADDRESS CLR PRIVST ;CLEAR PRIV/NON-PRIV STATUS 0 = PRIV CLR LIFLAG ;ASSUME NO /LI ; ; LOCATE AND STORE OUR TI'S UCB ADDRESS. ; MOV $TKTCB,R0 ;SET UP ADDRESS OF TASK CONTROL BLOCK MOV T.UCB(R0),R0 ;GET UCB ADDRESS FOR "TI0:" FOR THIS TASK 10$: MOV U.RED(R0),R1 ;FOLLOW ALL REDIRECTS TO THE BOTTOM CMP R0,R1 ;ARE WE REDIRECTED? BEQ 20$ ; IF EQ - NO, CONTINUE MOV R1,R0 ; IF NE - YES, TRY TO ELIMINATE ANOTHER LEVEL BR 10$ ; OF REDIRECT 20$: MOV R0,TIUCB ;SAVE THE UCB ADDRESS FOR LATER ; ; GET COMMAND LINE, ERROR IF NONE AVAIABLE. ; DIR$ #GETCMD ;GET MCR COMMAND LINE BCC 30$ ; IF CC - OK, CONTINUE ERROUX NOCM ;DECLARE ERROR ; ; SETUP FOR COMMAND PARSING. ; 30$: MOV #GETCMD+G.MCRB,R1 ;GET START OF COMMAND LINE MOV $DSW,R2 ;GET LENGTH OF COMMAND LINE 40$: CMPB #' ,(R1)+ ;SCAN FOR FIRST BLANK CHARACTER BEQ 50$ ; IF EQ - FOUND CHARACTER SOB R2,40$ ;LOOP THROUGH ENTIRE LINE ERROUX INCM ;DECLARE ERROR ; ; CHECK COMMAND FOR SYNTACTICAL CORRECTNESS. ; 50$: DEC R2 ;CORRECT LINE LENGTH CSI$1 #CSIBLK,R1,R2 ;CHECK COMMAND LINE SYNTAX BCC 70$ ; IF CC - OK, CONTINUE 60$: CALLR .SYNER ;SYNTAX ERROR ; ; GET OUTPUT FILE SPECIFICATION. ; 70$: CSI$2 #CSIBLK,OUTPUT,#SWTTAB ;GET OUTPUT SPECIFICATION BCS 60$ ; IF CS - BAD, ERROR BIT #FL.ID,SWITCH ;/ID? BEQ 80$ ;IF EQ, NO ERROUT IDNT ;OUTPUT OUR VERSION NUMBER JMP AVDEX ;EXIT 80$: BIT #FL.HEL,SWITCH ;/HELP? BEQ 100$ ;IF EQ, NO BITB #CS.NMF!CS.DIF!CS.MOR!CS.DVF!CS.EQU,C.STAT(R0) ;ALLOW ONLY AVD /HE[LP] BEQ 90$ ;IF EQ, OK ERROUT HWAR ;PRINT WARNING 90$: JMP AVDHLP ;PRINT HELP MESSAGE AND EXIT 100$: BITB #CS.EQU,C.STAT(R0) ;IS THERE AN EQUAL SIGN? BEQ 110$ ;IF EQ, NO ERROUX NOEQ ;DECLARE ERROR 110$: CLR R1 ;IF NOT /LI, CHECK FOR VD0: BIT #FL.LST,SWITCH ;/LI? BEQ 180$ ;IF EQ, NO .SBTTL CHECK COMMAND LINE WITH /LI SWITCH ; ; /LI IS ON THE COMMAND LINE. THE COMMAND LINE CAN THEREFORE ; HAVE THE FORM "VDN:/LI" (LIFLAG=1) OR "/LI" (LIFLAG=-1). ; IF /BR WAS SPECIFIED, THEN ONLY LIST ACTIVE DISKS. ; INC LIFLAG ;ASSUME A VDn: IS SPECIFIED BITB #CS.DVF,C.STAT(R0) ;ANY DEVICE SPECIFIED? BNE 120$ ;IF NE, YES NEG LIFLAG ;SET FLAG TO -1 120$: BITB #CS.NMF!CS.DIF!CS.MOR!CS.EQU,C.STAT(R0) ;ANY GARBAGE? BNE 160$ ;IF NE, YES - TOO BAD TST LIFLAG ;SINGLE DEVICE? BGT 130$ ;IF GT, YES - PARSE THE DEVICE NAME BR 180$ ;OTHERWISE, NO NEED 130$: MOV #FILFDB,R0 ;GET FILE FDB ADDRESS MOV #FILFDB+F.FNB,R1 ;AND NAMEBLOCK ADDRESS MOV #CSIBLK+C.DSDS,R2 ;GET DATASET DESCRIPTOR ADDRESS CLR R3 ;NO DEFAULT NAMEBLOCK CALL .PRSDV ;PARSE DEVICE NAME ONLY BCC 140$ ;IF CC, ALL OK MOV $DSW,R4 ;GET DSW ERROR CODE SUB #128.,R4 ;MINUS 128 FOR .ERTRP ERROUX PRSE,,R4 ;PRINT ERROR AND CODE 140$: CMP #"VD,N.DVNM(R1) ;IS IT A VD: ? BEQ 170$ ;IF EQ, YES 150$: ERROUX INVD ;INVALID DEVICE 160$: ERROUX SERR ;BAD SPECIFICATION ; ; VERIFY UNIT NUMBER RANGE ; 170$: MOV N.UNIT(R1),R1 ;GET THE UNIT NUMBER BIT #177400,R1 ;UNIT NUMBER MUST BE ONE BYTE BNE 210$ ;IF NE, ERROR .SBTTL LOCATE THE UCB ADDRESS ; ; LOCATE PHYSICAL DEVICE VDN:'S UCB ADDRESS ; 180$: CALL $LOCKL ;;LOCK SYSTEM LISTS WHILE HANDLING REDIRECTS MOV $DEVHD,R4 ;;GET ADDRESS OF DCB INTO R4 190$: CMP D.NAM(R4),#"VD ;;IS THIS DEVICE "VD"? BEQ 200$ ;; IF EQ - YES, FOUND "VD" MOV D.LNK(R4),R4 ;; IF NE - NO, LINK TO NEXT DEVICE BNE 190$ ;; IF NE - THERE ARE MORE DEVICES ERROUX VDUK 200$: TST LIFLAG ;;/LI ALL VD'S? BMI 220$ ;;IF MI, YES - DON'T CHECK UNIT NO. CMPB D.UNIT(R4),R1 ;;IS UNIT NUMBER REQUESTED VALID? BHI 210$ ;; IF HI - NO, UNIT NUMBER NOT IN RANGE CMPB D.UNIT+1(R4),R1 ;;IS UNIT NUMBER REQUESTED VALID? BHIS 220$ ;; IF HIS - YES, UNIT NUMBER IS VALID 210$: ERROUX INUN ; ; VERIFY THAT DRIVER IS LOADED ; 220$: TST D.DSP(R4) ;;CHECK TO BE SURE DRIVER IS LOADED BNE 230$ ;;IF NE - DRIVER IS LOADED OR RESIDENT ERROUX VDNL ; ; COMPUTE UCB ADDRESS FOR VDN: ; 230$: MOV D.UCBL(R4),R3 ;;GET LENGTH OF UCB FOR "VD" MOV D.UCB(R4),R5 ;;GET ADDRESS OF FIRST UCB FOR "VD" MOV D.UNIT(R4),R2 ;;GET UNIT RANGE WORD TST LIFLAG ;;/LI ALL VD'S? BEQ 270$ ;;IF EQ, NOT /LI OPERATION BGE 250$ ;;IF GE, NOT ALL VD'S 240$: JMP AVDLST ;;DO THE /LI 250$: BIC #177400,R2 ;; AND THROW OUT HIGHEST UNIT SUB R2,R1 ;;COMPUTE OFFSET INDEX INTO UCSS BEQ 240$ ;; IF EQ - R5 HAS ADDRESS OF UCB FOR VDN: 260$: ADD R3,R5 ;;ADD LENGTH OF UCB TO GET NEXT UCB SOB R1,260$ ;; IF EQ - R5 HAS ADDRESS OF UCB FOR VDN: BR 240$ ;;DO LISTING .SBTTL PARSE FILENAME ; ; PARSE FILENAME SPECIFICATION. ; 270$: TST LIFLAG ;;/LI OPERATION? BNE 240$ ;;IF NE, YES MOV #FILFDB,R0 ;;GET FDB ADDRESS MOV #FILFDB+F.FNB,R1 ;;GET FNB ADDRESS MOV #CSIBLK+C.DSDS,R2 ;;GET DATASET DESCRIPTOR ADDRESS MOV #FILDFB,R3 ;;GET DEFAULT FILENAME BLOCK CALL .PARSE ;;PARSE FILENAME INTO FILENAME BLOCK BCC 290$ ;; IF CC - OK, CONTINUE 280$: ERROUT INFN ;;INVALID FILENAME MOV #CSIBLK,R0 ;;GET CSI BLOCK CALLR .SYNER ;;PRINT OUT ERRANT COMMAND LINE, EXIT ; ; CALL .FIND TO LOCATE THE FILE ON DISK TO FILL IN THE FILE ID ; IN THE FILENAME BLOCK. IF THE .FIND FAILS, IT'S OK. ; 290$: CALL .FIND ;;FILL IN THE FILE ID MOV D.UNIT(R4),R2 ;;GET THE UNITS MOV D.UCBL(R4),R3 ;;GET THE UCB LENGTH ; ; GET THE FIRST AVAILABLE VD:. DON'T USE A VD IF IT: ; ; 1. IS ALREADY ASSOCIATED WITH ANOTHER FILE ; 2. IS ALLOCATED FOR ANOTHER USER ; ; IF A FREE UNIT IS FOUND, SAVE ITS UNIT NUMBER BUT KEEP CHECKING ; TO SEE IF THE FILE IS ASSOCIATED WITH ANOTHER UNIT WE HAVEN'T CHECKED. ; MOV #-1,VDUNIT ;;INIT VD: UNIT NUMBER TO NONE SWAB R2 ;;PUT HIGHEST UNIT IN L.O. BYTE BIC #177400,R2 ;;R2 = HIGHEST UNIT NUMBER INC R2 ;;R2 = NUMBER OF UNITS IN EXISTENCE 300$: TST U.NXT(R5) ;;IS THIS UNIT FREE? BEQ 340$ ;;IF EQ, YES - USE IT ; ; IT IS IN USE -- CHECK TO SEE IF IT MAY BE THE SAME ONE WE'RE TRYING FOR. ; MOV U.NXT(R5),R0 ;;GET THE EXTENSION BLOCK ADDRESS ADD #X.FNB,R0 ;;POINT TO THE FILENAME BLOCK MOV #FILFDB+F.FNB,R1 ;;POINT TO THE NEW FNB MOV #S.FNB/2,-(SP) ;;SIZE OF THE FNB (IN WORDS) 310$: CMP (R0)+,(R1)+ ;;MATCH? BNE 320$ ;;IF NE, NO DEC (SP) ;;DEC COUNTER BNE 310$ ;;KEEP TRYING TST (SP)+ ;;CLEAN STACK JMP 700$ ;;FINISH UP USING THIS VD: 340$: TST U.OWN(R5) ;;IS IT ALLOCATED? BEQ 350$ ;;IF EQ, NO CMP U.OWN(R5),TIUCB ;;IS IT OURS? BNE 330$ ;;IF NE, NO - CAN'T USE IT 350$: CMP VDUNIT,#-1 ;;FOUND ONE ALREADY? BNE 330$ ;;IF NE, YES - KEEP LOOKING FOR IT MOVB U.UNIT(R5),R1 ;;GET THE UNIT NUMBER BIC #177400,R1 ;;MAKE SURE THERE'S NO GARBAGE MOV R1,VDUNIT ;;STORE IT MOV R5,VDUCB ;;SAVE UCB, TOO BR 330$ ;;AND KEEP CHECKING 320$: TST (SP)+ ;;CLEAN STACK 330$: ADD R3,R5 ;;COMPUTE ADDRESS OF NEXT UCB SOB R2,300$ ;;CHECK ALL UCBS CMP VDUNIT,#-1 ;;FOUND ONE? BNE 360$ ;;IF NE, YES - CONTINUE ERROUX NOVD ;;"NO VD'S AVAILABLE" ; ; CHECK TO BE SURE VDN: IS NOT REDIRECTED ; 360$: MOV VDUCB,R5 ;;GET THE UCB ADDRESS CMP U.RED(R5),R5 ;;CHECK REDIRECT UCB ADDRESS BEQ 370$ ;; IF EQ - VDN: IS NOT REDIRECTED ERROUX VDRD ; ; VERIFY THAT VIRTUAL DISK IS NOT BEING SET UP ON A VIRTUAL DISK ; 370$: MOV #FILFDB+F.FNB,R1 ;;GET ADDRESS OF FNB CMP N.DVNM(R1),#"VD ;;IS REDIRECTED DEVICE NAME "VD"? BNE 380$ ;; IF NE, OK - CONTINUE CMPB D.UNIT(R4),N.UNIT(R1) ;;CHECK UNIT NUMBER WITHIN RANGE BHI 380$ ;; IF HI, OK - CONTINUE CMPB D.UNIT+1(R4),N.UNIT(R1) ;;CHECK UNIT NUMBER WITHIN RANGE BLO 380$ ;; IF LO, OK - CONTINUE ERROUX VDVD ; ; ALLOCATE EXTENSION BLOCK AND ASSIGN TO VIRTUAL DISK. ; 380$: SYSTEM 400$ ;;ENTER SYSTEM STATE TST U.NXT(R5) ;;IS VCB ALLOCATED? BNE 390$ ;; IF NE - YES, ERROR MOV R5,UCBADR ;;MARK GOOD UCB FOUND MOV #X.LGTH,R1 ;;SET EXTENSION BLOCK LENGTH CALL $ALOCB ;;ALLOCATE EXTENSION BLOCK BCS 390$ ;; IF CS - NO POOL, ERROR MOV R0,U.NXT(R5) ;;ALLOCATE UCB MOV R0,EXTADR ;; AND RETURN BLOCK ADDRESS MOV TIUCB,R0 ;;GET OUR TI'S UCB ADDRESS BIT #U2.PRV,U.CW2(R0) ;;IS TERMINAL PRIVILEGED? BNE 390$ ;; IF NE - YES, ACCESS ALLOWED COM PRIVST ;; IF EQ - NO, ACCESS ALLOWED IF VDN: ALLOCATED 390$: RETURN ;;RETURN TO USER STATE 400$: TST UCBADR ;;WAS DISK ALLOCATED? BNE 410$ ;; IF NE - YES, CONTINUE ERROUX FATL ;; ??? - SHOULDN'T HAPPEN 410$: TST EXTADR ;;WAS EXTENSION BLOCK ALLOCATED? BNE 420$ ;; IF NE - YES, CONTINUE ERROUX POOL ;;DECLARE ERROR 420$: TST PRIVST ;;WAS ACCESS ALLOWED? BLE 430$ ;; IF LE - YES, CONTINUE ERROUX NOAL ; ; CHECK FOR CREATION SWITCH DEFINITIONS ; ; ; ALLOW CREATION OF NEW VIRTUAL DISK AREA ONLY TO PRIVILEGED USERS ; 430$: BIT #FL.CRE,SWITCH ;;IS FILE CREATION REQUESTED? BEQ 470$ ;; IF EQ - NO, SKIP MOV #STRING,R4 ;;GET START OF SIZE STRING MOV R4,R5 ;;COPY START OF STRING MOV #8.,R3 ;;SET SIZE OF STRING 440$: TSTB (R4)+ ;;SCAN FOR NULL CHARACTER BEQ 450$ ;; IF EQ - FOUND END OF STRING SOB R3,440$ ;;LOOP TILL DONE BR 460$ ;; IF NO NULL, BAD SIZE STRING 450$: SUB #STRING+1,R4 ;;GET LENGTH OF STRING MOV #BLKNUM,R3 ;;GET STORAGE SPACE CALL .DD2CT ;;CONVERT NUMBER TO BINARY BCS 460$ ;; IF CS - CONVERSION ERROR MOV (R3)+,R1 ;;GET HIGH PART OF NUMBER TSTB -1(R3) ;;CHECK IF TOO LARGE BNE 460$ ;; IF NE - YES, ERROR MOV (R3)+,R0 ;;GET LOW PART OF NUMBER BIC #FL.CRE,SWITCH ;;RESET THE SWITCH BR 500$ ;;CONTINUE IN COMMON CODE 460$: ERROUX BDSK ; ; CHECK STANDARD DEVICE CREATION SWITCHES AND SET UP DEVICE SIZE ; 470$: MOV #DSKTBL,R5 ;;SET UP ADDRESS OF AUX SWITCH TABLE 480$: TST @R5 ;;HAVE WE COMPLETED ALL CHECKING? BEQ 570$ ;; IF EQ - YES, NO SWITCHES SET BIT D.BIT(R5),@D.SWAD(R5) ;;IS THIS OPTION SWITCH SELECTED? BNE 490$ ;; IF NE - YES, OPTION SWITCH FOUND ADD #D.LENG,R5 ;;COMPUTE ADDRESS OF NEXT ENTRY BR 480$ ;; AND CONTINUE CHECKING 490$: BIC D.BIT(R5),@D.SWAD(R5) ;;CLEAR OPTION SWITCH ADD #D.SIZE,R5 ;;COMPUTE ADDRESS OF SIZE VALUES MOV (R5)+,R1 ;;GET HI ORDER SIZE INTO R1 MOV (R5)+,R0 ;; AND LO ORDER SIZE INTO R0 ; ; CHECK TO BE SURE SWITCHES ARE NOT AMBIGUOUS ; 500$: MOV #DSWTBL,R5 ;;SET UP POINTER TO SWITCHES MOV SWITCH,R4 ;;PUT SPECIAL SWITCHES IN STORAGE WORD BIC #FL.RON,R4 ;; AND CLEAR "RO" BIT 510$: TST @R5 ;;HAVE WE CHECKED ALL SWITCHES? BEQ 520$ ;; IF EQ - YES, ALL DONE BIS @(R5)+,R4 ;; "OR" IN SWITCHES BR 510$ ;; AND CONTINUE 520$: TST R4 ;;"OR" OF ALL SWITCH WORDS ZERO? BEQ 530$ ;; IF EQ - YES, NO AMBIGUOUS SWITCHES ERROUX AMSW .SBTTL CREATE A VIRTUAL DISK FILE ; ; CREATE SPECIFIED FILE ; ; ; CHECK PRIVILEGE STATUS OF TERMINAL. ; 530$: TST PRIVST ;;IS USER PRIVILEGED? BEQ 540$ ;;IF EQ, YES - ALLOW CREATION ERROUX PRIV 540$: MOV R0,CREDPB+Q.IOPL+6 ;;SET SIZE OF FILE TO CREATE MOVB R1,CREDPB+Q.IOPL+4 ;; AND HIGH-PART ALSO MOV R0,FILFDB+F.HIBK+2 ;;SET FCS SIZE MOVB R1,FILFDB+F.HIBK+0 ;; AND HIGH-PART ALSO MOV R0,FILFDB+F.EFBK+2 ;;SET EOF BLOCK MOVB R1,FILFDB+F.EFBK+0 ;; AND HIGH PART ALSO MOV #1000,FILFDB+F.FFBY ;; AND MARK EOF AT END OF BLOCK F11QIO CREDPB,560$ ;;ISSUE CREATE REQUEST F11QIO ENADPB,550$ ;;ISSUE ENTER NAME REQUEST BR 590$ ;; CONTINUE ON SUCCESS 550$: F11QIO DELDPB ;;ON ENTER ERROR, DELETE FILE 560$: MOV #FILFDB,R0 ;;GET THE FILE FDB ADDRESS ERROUX ERCR,0,IOSTAT ;;DECLARE ERROR .SBTTL OPEN REQUESTED FILE ;; ;; LOOKUP SPECIFIED FILE. ;; 570$: F11QIO FNADPB,580$ ;;ISSUE FIND REQUEST BR 590$ ;; CONTINUE ON SUCCESS 580$: MOV #FILFDB,R0 ;;GET THE FILE FDB ADDRESS ERROUX FNF,0 ;;DECLARE ERROR ;; ;; ACCESS AND DEACESS FILE, GET SIZE AND STARTING BLOCK NUMBER ;; 590$: F11QIO ACWDPB,600$ ;;ISSUE ACCESS REQUEST F11QIO DACDPB,600$ ;; AND DEACCESS FILE (LOCKED) F11QIO WATDPB,600$ ;; AND LOCK FILE BR 610$ ;; CONTINUE ON SUCCESS 600$: MOV #FILFDB,R0 ;;GET THE FILE FDB ADDRESS ERROUX ACCS,0,IOSTAT ;;DECLARE ERROR ;; ;; CHECK THAT FILE IS CONTIGUOUS AND STORE OFFSET, SIZE IN UCB. ;; 610$: MOV UCBADR,R5 ;;GET UCB ADDRESS MOV EXTADR,R4 ;; AND EXTENSION BLOCK MOV #STAATT,R0 ;;GET ADDRESS OF STATISTICS BLOCK MOV (R0)+,(R4)+ ;;STORE BLOCK OFFSET MOV (R0)+,(R4)+ ;; AND LOW PART BNE 620$ ;; IF NE - OK, CONTINUE MOV #FILFDB,R0 ;;GET THE FILE FDB ADDRESS ERROUX NOTC,0 ;;DECLARE ERROR 620$: MOV (R0)+,U.CW2(R5) ;;STORE SIZE OF FILE (DISK) MOV (R0)+,U.CW3(R5) ;; AND LOW PART TST (R4)+ ;;SKIP NEXT UCB ADDRESS CLR (R4)+ ;;CLEAR EXTENSION FLAGS BIT #FL.RON,SWITCH ;;SHOULD WE MARK READ-ONLY? BEQ 630$ ;; IF EQ - NO, SKIP BIS #XF.RON,-2(R4) ;;SET READ-ONLY ACCESS 630$: MOV #FILFDB+F.FNB,R1 ;;GET FILENAME BLOCK MOV #S.FNB/2,R2 ;;GET SIZE OF FILENAME BLOCK 640$: MOV (R1)+,(R4)+ ;;STORE FILENAME BLOCK SOB R2,640$ ;;LOOP TILL DONE SYSTEM 680$ ;;;ENTER SYSTEM STATE MOV $HEADR,R0 ;;GET OUR FILE HEADER MOV H.CUIC(R0),FILUIC ;;SAVE CURRENT TASK UIC ADD #*4+H.LUN,R0 ;;POSITION TO FILE'S UCB POINTER MOV (R0),R0 ;;GET FILE'S UCB ADDRESS 650$: MOV U.RED(R0),R1 ;;GET REDIRECT UCB CMP R0,R1 ;;IS THIS LAST REDIRECTION BEQ 660$ ;; IF EQ - YES, SKIP MOV R1,R0 ;;COPY UCB ADDRESS BR 650$ ;; AND LOOP AGAIN 660$: MOV EXTADR,R4 ;;GET EXTENSION BLOCK MOV R0,X.UCB(R4) ;;STORE NEXT UCB IN EXTENSION BLOCK .IF GE V$$RSN-32 ;; RSX-11M V3.2 OR LATER MOV U.VCB(R0),R0 ;;GET HOST'S DISK VCB ADDRESS ADD #V.LABL,R0 ;;POINT TO VOLUME LABEL ADD #X.LABL,R4 ;;POINT TO LABEL FIELD IN EXTENSION BLOCK MOV #6,R2 ;;SET COUNTER FOR 12 BYTES 670$: MOV (R0)+,(R4)+ ;;SAVE VOLUME LABEL IN EXTENSION BLOCK SOB R2,670$ ;; ... .ENDC BICB #US.OFL,U.ST2(R5) ;;MARK DISK ENABLED RETURN ;;RETURN TO USER STATE 680$: MOV #CSIBLK,R2 ;;GET START ADDRESS OF CSI BLOCK BITB #CS.DIF,C.STAT(R2) ;;WAS A UIC SPECIFIED IN THE FILESPEC? BEQ 690$ ;;IF EQ, NO - USE DEFAULT MOV #FILUIC,R3 ;;GET ADDRESS TO STORE UIC ADD #C.DIRD,R2 ;;POINT TO DIRECTORY DESCRIPTOR IN CSIBLK CALL .ASCPP ;;CONVERT ASCII UIC TO BINARY IN FILUIC 690$: MOV EXTADR,R4 ;;GET EXTENDED ADDRESS POINTER MOV FILUIC,X.UIC(R4) ;;STORE FILE'S BINARY UIC 700$: CALL $UNLKL ;;UNLOCK SYSTEM TABLES .SBTTL DETERMINE FIRST AVAILABLE VS: UNIT ; ; CHECK FOR AN AVAILABLE VS: TO ASSIGN TO THE VD:. ; THIS IS DONE BY TRYING SUCCESSIVE ALUN$ UNTIL ONE FAILS. ; ; R5 = VD: UCB ADDRESS OF SELECTED UNIT ; CLR R2 ;START WITH VS0: MOV #$MAXVS,R3 ;MAX NUMBER OF TRIES 710$: ALUN$S #TSTLUN,#"VS,R2 ;TRY AN ALUN$ BCS 720$ ;IF CS, IT'S AVAILABLE (NOT ASSIGNED) INC R2 ;BUMP UNIT NUMBER SOB R3,710$ ;TRY AGAIN ERROUT NOVS ;NO VS: UNITS AVAILABLE MOV #EX$ERR,.EXSTS ;SIGNAL ERROR CONDITION (NOT FATAL) BR 730$ ;CONTINUE 720$: MOVB U.UNIT(R5),R0 ;GET VD:UNIT NUMBER BIC #177400,R0 ;MAKE SURE ITS ONE BYTE MOV R0,ARGBLK ;STORE UNIT NUMBER IN ARG BLOCK MOV R2,ARGBLK+2 ;STORE VS: UNIT NUMBER MOV #OUTBUF,R0 ;GET ADDR OF OUTPUT BUFFER MOV #ASNSTR,R1 ;GET ADDR OF INPUT STRING MOV #ARGBLK,R2 ;AND ARGUMENT BLOCK CALL $EDMSG ;EDIT IT MOVB #33,(R0)+ ;TERMINATE WITH SUB #OUTBUF,R0 ;COMPUTE LENGTH MOV R0,MCR1+S.PWCL ;SET LENGTH IN DPB MOV #IS.SUC,IOSTAT ;(DON'T CONFUSE THINGS) MOV TIUCB,R3 ;GET THE UCB ADDRESS OF TI: MOV U.CW2(R3),-(SP) ;SAVE OLD U.CW2 BIS #,U.CW2(R3) ;SET PRIVILEGED, SLAVED F11QIO MCR1,740$ ;EXECUTE THE SPAWN WTSE$S #MCREFN ;WAIT FOR IT MOV (SP)+,U.CW2(R3) ;RESTORE PRIVILEGE STATUS BIT #FL.NM,SWITCH ;PRINT INFORMATIONAL MESSAGES? BNE 730$ ;IF NE, NO MOV #OUTBUF,R0 ;GET ADDR OF OUTPUT BUFFER MOV #INFO1,R1 ;GET ADDR OF INPUT STRING MOV #ARGBLK,R2 ;AND ARGUMENT BLOCK CALL $EDMSG ;EDIT IT MOV R0,R1 ;COPY ADDRESS OF END OF STRING SUB #OUTBUF,R1 ;COMPUTE LENGTH CALL OUTMSG ;OUTPUT THE MESSAGE 730$: BIT #FL.VM,SWITCH ;ASSIGN TO VM:,ALSO? BEQ AVDEX ;IF EQ, NO - ALL DONE MOV #OUTBUF,R0 ;GET OUTPUT BUFFER ADDRESS MOV #AVMSTR,R1 ;GET INPUT STRING MOV #ARGBLK,R2 ;GET ARG BLOCK ADDR CALL $EDMSG ;FIX IT UP MOVB #33,(R0)+ ;TERMINATE IT SUB #OUTBUF,R0 ;COMPUTE LENGTH MOV R0,MCR1+S.PWCL ;SET LENGTH IN DPB F11QIO MCR1,750$ ;DO IT WTSE$S #MCREFN ;WAIT FOR IT BIT #FL.NM,SWITCH ;PRINT INFORMATIONAL MESSAGES? BNE AVDEX ;IF NE, NO MOV #OUTBUF,R0 ;GET ADDR OF OUTPUT BUFFER MOV #INFO2,R1 ;GET ADDR OF INPUT STRING MOV #ARGBLK,R2 ;AND ARGUMENT BLOCK CALL $EDMSG ;EDIT IT MOV R0,R1 ;COPY ADDRESS OF END OF STRING SUB #OUTBUF,R1 ;COMPUTE LENGTH CALL OUTMSG ;OUTPUT THE MESSAGE BR AVDEX ;SUCCESS... 740$: MOV (SP)+,U.CW2(R3) ;RESTORE PRIVILEGE STATUS 750$: MOVB $DSW,R4 ;GET DSW ERROR CODE SUB #128.,R4 ;COMPUTE OFFSET INTO QIOSYM.MSG ERROUT SPER,,R4 ;OUTPUT ERROR MESSAGE MOV #EX$ERR,.EXSTS ;SIGNAL NON-FATAL ERROR AVDEX: EXST$S .EXSTS ;SUCCESSFUL EXIT (FALLS THROUGH TO ; EXIT$S IF EXST$S NOT DEFINED) EXIT$S ;ALL DONE, EXIT .SBTTL AVDHLP - PRINT HELP MESSAGE ; ; THIS IS THE ENTRY POINT FOR PRINTING THE "HELP" MESSAGE IN RESPONSE TO ; "AVD /HELP". ALL THE SWITCHES ARE PRINTED OUT WITH A FEW OTHER HELPFUL ; COMMENTS. AFTER THE MESSAGE IS OUTPUT, THE PROGRAM IS TERMINATED. ; AVDHLP:: CALL ATTTI ;ATTACH TI: SO CTRL/O WILL WORK MOV #OUTBUF,R0 ;GET OUTPUT BUFFER ADDRESS MOV #HLPMSG,R1 ;GET INPUT STRING ADDRESS CLR R2 ;NO ARGUMENT BLOCK CALL $EDMSG ;EDIT THE MESSAGE CALL OUTMSG ;OUTPUT THE BUFFER ; ; GO THROUGH THE DISK TABLE ENTRIES AND PRINT THE SWITCHES AND DISK ; BLOCK SIZES. ; MOV #DSKTBL,R4 ;GET STARTING DISK TABLE ADDRESS 10$: TST (R4) ;ANY MORE ENTRIES? BEQ 20$ ;IF EQ, NO MOV #ARGBLK,R3 ;GET ADDRESS OF $EDMSG ARGUMENT BLOCK MOV R3,R2 ;COPY ADDRESS ADD #D.NAME,R4 ;POINT TO THE SWITCH NAME MOV R4,(R3)+ ;SAVE STRING ADDRESS IN ARG BLOCK ADD #D.SIZE-D.NAME,R4 ;POINT TO THE DISK SIZE (DOUBLE WORD) MOV R4,(R3) ;SAVE DOUBLE WORD ADDRESS IN ARG BLOCK MOV #OUTBUF,R0 ;GET OUTPUT BUFFER ADDRESS MOV #DSKSTR,R1 ;GET INPUT STRING ADDRESS CALL $EDMSG ;EDIT THE STRING CALL OUTMSG ;OUTPUT THE BUFFER ADD #D.LENG-D.SIZE,R4 ;POINT TO THE NEXT TABLE ENTRY BR 10$ ;AND GO AGAIN 20$: MOV #OUTBUF,R0 ;GET OUTPUT BUFFER ADDRESS AGAIN MOV #ENDMSG,R1 ;AND FINAL MESSAGE ADDRESS CALL $EDMSG ;EDIT IT CALL OUTMSG ;OUTPUT THE BUFFER EXST$S .EXSTS ;SUCCESSFUL EXIT (FALLS THROUGH TO ; EXIT$S IF EXST$S NOT DEFINED) EXIT$S .SBTTL AVDLST - LIST AVD ASSIGNMENTS ; ;+ ; THIS ROUTINE LISTS ANY OR ALL THE ASSIGNMENTS OF VD'S MADE BY AVD. ; THE REQUEST MAY BE IN ONE OF TWO FORMS: ; ; >AVD VDn:/LI or /BR TO LIST INFO ABOUT VDn: ONLY ; ; >AVD /LI or /BR TO LIST ALL VD'S ; ; IF /BR IS SPECIFIED, ONLY LIST ACTIVE DISKS, AND ONLY THE FILENAME. ; ; ON ENTRY, LIFLAG = 1 TO ONLY LIST ONE VD:, -1 TO LIST ALL. ; ALSO ON ENTRY, ; ; R4 = VD: DCB ADDRESS ; R5 = FIRST UCB ADDRESS IF ALL VD'S TO BE LISTED, OR ; VDn: UCB ADDRESS IF ONLY ONE IS TO BE LISTED ; ; NO RETURN IS MADE FROM THIS ROUTINE. ; ;- ; AVDLST: CALL ATTTI ;;ATTACH TI: MOV #OUTBUF,R0 ;;GET OUTPUT BUFFER ADDRESS MOVB #15,(R0)+ ;;START WITH CARRIAGE-RETURN MOVB #12,(R0)+ ;;AND LINE FEED MOV #2,R1 ;;2 WHOLE CHARACTERS CALL OUTMSG ;;OUTPUT CR-LF MOV #OUTBUF,R0 ;;GET OUTPUT BUFFER ADDRESS 10$: MOV R5,R3 ;;COPY UCB ADDRESS CALL $FMTDV ;;GENERATE "VDn:" STRING MOVB #11,(R0)+ ;;PUT TAB IN STRING TST U.NXT(R5) ;;IS THIS VD: ASSIGNED? BNE 20$ ;;IF NE, YES BIT #FL.BR,SWITCH ;;/BR? BEQ 12$ ;;IF EQ, NO - LIST IT CALL $UNLKL ;;UNLOCK LISTS JMP 95$ ;DON'T LIST OFFLINE DISKS 12$: MOV #OFLSTR,R1 ;;OUTPUT "OFFLINE" CALL $EDMSG ;;EDIT STRING MOV #ARGBLK,R2 ;;GET ADDRESS OF ARGUMENT BLOCK MOV #23.,(R2) ;;SET UP FOR 23 SPACES TST U.OWN(R5) ;;IS IT ALLOCATED? BNE 30$ ;;IF NE, YES - COMPLETE THE LINE BITB #US.PUB,U.ST2(R5) ;;PUBLIC? BEQ 15$ ;;IF EQ, NO MOVB #11,(R0)+ ;;TAB MOV #PUBSTR,R1 ;;"PUBLIC" CALL $EDMSG ;; WITH CR-LF 15$: MOV #CRLF,R1 ;;TERMINATE THE LINE CALL $EDMSG ;; WITH CR-LF JMP 90$ ;;ALL DONE 20$: MOV R0,-(SP) ;;SAVE CURRENT STRING POINTER MOV U.NXT(R5),R4 ;;GET POOL BLOCK ADDRESS MOV X.UCB(R4),R3 ;;GET DEVICE'S UCB ADDRESS CALL $FMTDV ;;PUT DEVICE NAME IN STRING MOV R0,R2 ;;GET ADDRESS TO STORE UIC STRING MOV X.UIC(R4),R3 ;;GET THE BINARY UIC CLR R4 ;;SET FORMAT CODE CALL .PPASC ;;CONVERT UIC TO [NNN,MMM] MOV R2,R0 ;;GET UPDATED STRING POINTER MOV U.NXT(R5),R4 ;;RESTORE POOL BLOCK ADDRESS MOV R4,R2 ;;COPY BLOCK ADDRESS ADD #X.FNB+N.FNAM,R2 ;;POINT TO FILENAME IN FNB MOV #FNMSTR,R1 ;;GET ADDRESS OF FILENAME STRING CALL $EDMSG ;;EDIT FILENAME INTO STRING MOV (SP)+,R3 ;;GET STARTING STRING ADDRESS BIT #FL.BR,SWITCH ;;/BR? BNE 75$ ;;IF NE, YES -- DONE WITH THE LINE SUB R0,R3 ;;COMPUTE -(LENGTH OF STRING) MOV #ARGBLK,R2 ;;GET ADDRESS OF ARGUMENT BLOCK MOV #1,(R2) ;;ASSUME VERY LONG FILESPEC ADD #24.,R3 ;;COMPUTE NO. OF SPACES TO INSERT BLE 30$ ;;IF LE, USE 1 SPACE MOV R3,(R2) ;;STORE NO. OF SPACES 30$: MOV #UNMSTR,R1 ;;ASSUME IT'S UNMOUNTED MOV U.VCB(R5),R3 ;;GET VCB ADDRESS - MOUNTED? BEQ 40$ ;;IF EQ, NO MOV V.FRBK+2(R3),-(SP) ;;PUT NO. OF FREE BLOCKS MOVB V.FRBK(R3),-(SP) ;;ONTO THE STACK CLRB 1(SP) ;;TRUNCATE TO 24 BITS MOV #ARGBLK,R2 ;;GET ARGUMENT BLOCK ADDRESS MOV SP,2(R2) ;;STORE FREE BLOCKS ADDRESS MOV R5,4(R2) ;;STORE UCB ADDRESS ADD #U.CW2,4(R2) ;;COMPUTE ADDRESS OF NO. OF TOTAL BLOCKS MOV #SIZSTR,R1 ;;INPUT STRING CALL $EDMSG ;;OUTPUT FREE./TOTAL. CMP (SP)+,(SP)+ ;;CLEAN UP THE STACK TST U.OWN(R5) ;;ALLOCATED? BEQ 70$ ;;IF EQ, NO - ALL DONE MOVB #11,(R0)+ ;;INSERT TAB SUB ARGBLK,R1 ;;DON'T COUNT NUMBER OF SPACES INSERTED CMP R1,#10. ;;DID WE OUTPUT ENOUGH CHARACTERS? BGE 50$ ;;IF GE, YES MOVB #11,(R0)+ ;;INSERT ANOTHER TAB BR 50$ ;;CONTINUE 40$: CALL $EDMSG ;;OUTPUT LABEL OR "UNMOUNTED" 50$: MOV U.OWN(R5),R3 ;;IS IT ALLOCATED? BEQ 70$ ;;IF EQ, NO CALL $FMTDV ;;OUTPUT OWNING TERMINAL MOVB #11,(R0)+ ;;TAB MOV #PRISTR,R1 ;;ASSUME IT'S PRIVATE BITB #US.PUB,U.ST2(R5) ;;IS IT PUBLIC? BEQ 60$ ;;IF EQ, NO MOV #PUBSTR,R1 ;;YES - OUTPUT "PUBLIC" 60$: CALL $EDMSG ;;OUTPUT PUBLIC/PRIVATE STATUS BR 75$ ;;CONTINUE 70$: BITB #US.PUB,U.ST2(R5) ;;PUBLIC? BEQ 75$ ;;IF EQ, NO MOVB #11,(R0)+ ;;TAB MOV #PUBSTR,R1 ;;"PUBLIC" CALL $EDMSG ;;PUT INTO STRING 75$: MOV #CRLF,R1 ;;GET END-OF-LINE STRING CALL $EDMSG ;;THAT'S IT MOV X.UCB(R4),R3 ;;GET DEVICE'S UCB AGAIN BITB #US.MNT,U.STS(R3) ;;IS IT MOUNTED? BNE 80$ ;;IF NE, NO - OH-OH BITB #US.MDM,U.STS(R3) ;;MARKED FOR DISMOUNT? BEQ 90$ ;;IF EQ, NO - WHEW. 80$: MOV #WRNSTR,R1 ;; ** WARNING -- CALL $EDMSG ;; CALL $FMTDV ;; "DDNN:" MOV #ENDWRN,R1 ;; IS NOT MOUNTED. ** CALL $EDMSG ;; ... 90$: CALL $UNLKL ;;UNLOCK SYSTEM LISTS SUB #OUTBUF,R0 ;COMPUTE LENGTH OF STRING MOV R0,R1 ;PUT LENGTH IN R1 CALL OUTMSG ;OUTPUT THE BUFFER 95$: TST LIFLAG ;JUST DO ONE DEVICE? BGT 100$ ;IF GT, YES MOV U.DCB(R5),R4 ;GET THE DCB ADDRESS CMPB U.UNIT(R5),D.UNIT+1(R4) ;IS THIS THE HIGHEST DEVICE? BHIS 100$ ;IF HIS, YES - EXIT ADD D.UCBL(R4),R5 ;COMPUTE ADDRESS OF NEXT UCB MOV #OUTBUF,R0 ;RESET THE STRING POINTER CALL $LOCKL ;;LOCK LISTS AGAIN JMP 10$ ;;AND DO IT... 100$: EXST$S .EXSTS ;SUCCESSFUL EXIT (FALLS THROUGH TO ; EXIT$S IF EXST$S NOT DEFINED) EXIT$S ;ALL DONE .SBTTL ATTTI AND OUTMSG - TI: UTILITY ROUTINES ; ; ATTTI - ATTACH TI:. ; ATTTI: QIOW$S #IO.ATT,#TTYLUN,#EV.QIO ;ATTACH TI: RETURN ;ALL DONE ; ; OUTMSG - OUTPUT A MESSAGE TO TI: ; ; THE MESSAGE IS ASSUMED TO START IN LOCATION "OUTBUF". ; R1 = NO. OF BYTES IN THE MESSAGE. ; OUTMSG: QIOW$S #IO.WLB,#TTYLUN,#EV.QIO,,,,<#OUTBUF,R1> RETURN ;ALL DONE .SBTTL ERRSRV - EXIT AFTER ERROR ; ; THIS ROUTINE IS CALLED AFTER A FATAL ERROR HAS OCCURRED. ; MAKE SURE EVERYTHING IS CLEANED UP AND EXIT WITH BAD STATUS. ; ERRSRV: MOV UCBADR,R5 ;GET UCB ADDRESS BEQ 10$ ; IF EQ - NO UCB, NO EXTENSION BLOCK MOV EXTADR,R0 ;GET EXTENSION BLOCK ADDRESS BEQ 10$ ; IF EQ- NO EXTENSION BLOCK SYSTEM 10$ ;;ENTER SYSTEM STATE CLR U.NXT(R5) ;;MARK DISK NOT ALLOCATED MOV #X.LGTH,R1 ;;GET BLOCK SIZE CALLR $DEACB ;;DEALLOCATE EXTENSION BLOCK 10$: MOV #EX$SEV,.EXSTS ;SET SEVERE EXIT STATUS EXST$S #EX$SEV ;EXIT WITH FATAL STATUS EXIT$S ;EXIT TASK IF EXST$S FAILS .END AVD