Trailing-Edge
-
PDP-10 Archives
-
cust_sup_cusp_bb-x130c-sb
-
10,7/unscsp/mount/mntpar.mac
There are 4 other files named mntpar.mac in the archive. Click here to see a list.
TITLE MNTPAR MOUNT and ALLOCATE parser
SUBTTL P. Taylor/DPM/PJT/LWS 29-Feb-84
;
;
;
; COPYRIGHT (c) 1975,1976,1977,1978,1979,1980,1981,1982,
; 1983,1984,1985,1986
; DIGITAL EQUIPMENT CORPORATION
; ALL RIGHTS RESERVED.
;
; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED
; AND COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE
; AND WITH THE INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS
; SOFTWARE OR ANY OTHER COPIES THEREOF MAY NOT BE PROVIDED OR
; OTHERWISE MADE AVAILABLE TO ANY OTHER PERSON. NO TITLE TO
; AND OWNERSHIP OF THE SOFTWARE IS HEREBY TRANSFERRED.
;
; THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE
; WITHOUT NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT
; BY DIGITAL EQUIPMENT CORPORATION.
;
; DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY
; OF ITS SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY
; DIGITAL.
SEARCH GLXMAC ;Get Galaxy symbols
PROLOG (MOUNT)
SEARCH ORNMAC,QSRMAC,MNTMAC
EXTERN ERROR,HELPER
PARSET ;Declare external Parser routines
TWOSEG ;Make us sharable
RELOC 400000 ;Code goes here
SUBTTL ALLOCATE and MOUNT commands
;ALLOCATE and MOUNT syntax tables
MOU010:: ;Mount and allocate share common syntax
ALL010::$SWITCH(,MOU011,$ALTER(MOU015))
MOU015: $CRLF ($ALTER (MOU020))
MOU020: $FIELD(MOU022,<volume set name>,$BREAK(VSNBRK))
MOU022: $TOKEN(MOU023,<(>,$ALTER(MOU026))
MOU023: $FIELD(MOU024,<volume identifier>)
MOU024: $COMMA(MOU023,$ALTER(MOU025))
MOU025: $TOKEN(MOU026,<)>)
MOU026: $TOKEN(MOU030,<:>,$ALTER(MOU030))
MOU030: $FIELD(MOU032,<logical name>)
MOU032: $TOKEN(MOU040,<:>,$ALTER(MOU040))
MOU040: $SWITCH(,MOU041,$ALTER(MOU050))
MOU050: $COMMA(MOU020,$ALTER(MOU060))
MOU060: $CRLF
;Character set allowed for VOLUME-SET-NAME
VSNBRK::
777777,,777760 ;Break on all control
777754,,001760 ;Allow - and 0-9
400000,,000760 ;Allow A-Z
400000,,000760 ;Allow LC A-Z
;MOUNT and ALLOCATE option tables
MOU011: $STAB
DSPTAB(MOU010,MO$CHE,<CHECK>)
DSPTAB(MOU010,MO$DIS,<DISK>)
DSPTAB(,HELPER,<HELP>)
DSPTAB(MOU010,MO$NNT,<NONOTIFY>)
DSPTAB(MOU010,MO$NOT,<NOTIFY>)
DSPTAB(MOU010,MO$NOW,<NOWAIT>)
DSPTAB(MOU010,MO$TAP,<TAPE>)
DSPTAB(MOU010,MO$WAI,<WAIT>)
$ETAB
MOU041: $STAB
DSPTAB(MOU040,MO$ACT,<ACTIVE>)
DSPTAB(MOU040,MO$CRE,<CREATE>)
DSPTAB(M$DEN1,MO$DEN,<DENSITY>)
DSPTAB(M$FLD1,MO$DEV,<DEVICE>)
DSPTAB(MOU040,MO$DIS,<DISK>)
DSPTAB(MOU040,MO$EXC,<EXCLUSIVE>)
DSPTAB(M$LAB1,MO$LAB,<LABEL-TYPE>)
DSPTAB(MOU040,MO$SHA,<MULTI>) ;Ala SHARABLE
DSPTAB(MOU040,MO$NEW,<NEW-VOLUME-SET>)
DSPTAB(MOU040,MO$NOC,<NOCREATE>)
DSPTAB(MOU040,MO$NNT,<NONOTIFY>)
DSPTAB(MOU040,MO$NOT,<NOTIFY>)
DSPTAB(MOU040,MO$NOW,<NOWAIT>)
DSPTAB(MOU040,MO$PAS,<PASSIVE>)
DSPTAB(M$PRO1,MO$PRO,<PROTECTION>)
DSPTAB(MOU040,MO$QTA,<QUOTA>)
DSPTAB(MOU040,MO$REA,<READ-ONLY>)
DSPTAB(M$VOL1,MO$VOL,<REELID>) ;Ala VOLID
DSPTAB(M$REM1,MO$REM,<REMARK>)
DSPTAB(MOU040,MO$REA,<RONLY>) ;Ala READ-ONLY
DSPTAB(MOU040,MO$SCR,<SCRATCH>)
DSPTAB(MOU040,MO$SHA,<SHARABLE>)
DSPTAB(MOU040,MO$EXC,<SINGLE>) ;Ala EXCLUSIVE
DSPTAB(MOU040,MO$TAP,<TAPE>)
DSPTAB(M$TRA1,MO$TRA,<TRACKS>)
DSPTAB(M$REM1,MO$REM,<VID>) ;Ala REMARK
DSPTAB(M$VOL1,MO$VOL,<VOLID>)
DSPTAB(MOU040,MO$WAI,<WAIT>)
DSPTAB(MOU040,MO$WRI,<WENABLE>) ;Ala WRITE-ENABLE
DSPTAB(MOU040,MO$REA,<WLOCK>) ;Ala READ-ONLY
DSPTAB(M$WRI1,MO$WRI,<WRITE-ENABLE>) ;Also WRITE:YES and WRITE:NO
$ETAB
;ALLOCATE and MOUNT options syntax tables
M$DAT1: $DATE(MOU040)
M$DEN1: $KEY(MOU040,M$DEN2)
M$DEN2: $STAB
KEYTAB(.TFD16,<1600-BPI>)
KEYTAB(.TFD20,<200-BPI>)
KEYTAB(.TFD55,<556-BPI>)
KEYTAB(.TFD62,<6250-BPI>)
KEYTAB(.TFD80,<800-BPI>)
$ETAB
M$FLD1: $FIELD(MOU040)
M$LAB1: $KEY(MOU040,M$LAB2)
M$LAB2: $STAB
KEYTAB(%TFANS,<ANSI>)
KEYTAB(%TFLBP,<BLP>)
KEYTAB(%TFLBP,<BYPASS-LABEL-PROCESSING>)
KEYTAB(%TFEBC,<EBCDIC>)
KEYTAB(%TFEBC,<IBM>)
KEYTAB(%TFUNL,<NOLABELS>)
KEYTAB(%TFUNL,<NONE>)
KEYTAB(%TFUNL,<UNLABELED>)
KEYTAB(%TFUNV,<USER-EOT>)
$ETAB
M$NUM1: $NUMBER(MOU040,^D10)
M$PRO1: $NUMBER(MOU040,^D8)
M$REM1: $QUOTE(MOU040,,$ALTER(M$REM2))
M$REM2: $FIELD(MOU040,,$BREAK(REMBRK))
REMBRK: 777777,,777760 ;Break on all control
777754,,001760 ;Allow - and 0-9
400000,,000760 ;Allow A-Z
400000,,000760 ;Allow LC A-Z
M$TRA1: $KEY(MOU040,M$TRA2)
M$TRA2: $STAB
KEYTAB(.TMDR7,<7-TRACK>)
KEYTAB(.TMDR9,<9-TRACK>)
$ETAB
M$VOL1: $TOKEN(M$VOL2,<(>,$ALTER(M$VOL5))
M$VOL2: $FIELD(M$VOL3)
M$VOL3: $COMMA(M$VOL2,$ALTER(M$VOL4))
M$VOL4: $TOKEN(MOU040,<)>,$ALTER(MOU040))
M$VOL5: $FIELD(MOU040)
M$WRI1: $KEY(MOU040,M$WRI2,<$DEFAULT(YES),$ALTER(MOU040)>)
M$WRI2: $STAB
KEYTAB(FALSE,<NO>)
KEYTAB(TRUE,<YES>)
$ETAB
;MOUNT and ALLOCATE commands
;These routines will parse a MOUNT or an ALLOCATE command.
; The parse blocks are built in a page of data supplied by the caller
;Call -
; S1/ Adrs of a page into which the mount message
; will be built
;Return -
; TRUE always.
; If there are ANY errors, these routines pull a $ERR macro
; which JSPs to a caller-defined ERROR label (external from here)
; which should handle the error condition.
.ALLOC::
TDZA F,F ;CLEAR FLAG WORD
.MOUNT::
MOVX F,FL.MOU+FL.WAT ;Set Mount and Wait flags
$SAVE <P1,P2,P3,P4> ;Preserve some AC's
$SAVE <T1,T2,T3,T4> ;SAVE THE TEMP ACS
MOVE P1,S1 ;Save the incoming page adrs
MOVE S1,['MOUNT '] ;Assume mount
TXNN F,FL.MOU
MOVE S1,['ALLOCA']
MOVEM S1,CMDNAM ;Save incase /HELP was typed
MOUN05: PUSHJ P,P$CFM ;Try to get EOL
SKIPF ;User didn't type CRLF yet
;**;[56] Change 1 line at MOUN05+2L. /LWS
TXO F,FL.LST ;[56] Default to /LIST if EOL already
$CALL DOSWS ;Parse leading switches
MOVEM F,DEFSWS ;Save sticky options
MOVEI P2,.MMHSZ(P1) ;P2 contains first free address
MOVEI S2,.QOMNT ;Get mount message type
STORE S2,.MSTYP(P1),MS.TYP ;Save in the message
MOVX S2,MF.ACK ;Get ACK request flag
MOVEM S2,.MSFLG(P1)
$CALL P$CFM ;Get confirmation
JUMPT MOUN80 ;Yes..just return
JUMPE S1,MOUN80 ;Return at end of command (MOUNT/CHECK)
HRROI T1,.GTNM1 ;Get user name
GETTAB T1, ;May I?
SETZ T1, ;No..
HRROI T2,.GTNM2 ;Get second half
GETTAB T2, ;May I?
SETZ T2, ;No..
DMOVEM T1,.MMUSR(P1) ;Store in message
MOVEI T1,2 ;Get arg count for account
SETO T2, ;My Job
HRROI T3,.MMUAS(P1) ;Store in message
MOVE S2,[.ACTRD,,T1] ;Get the account
ACCT. S2,
JFCL
MOUN10: INCR .MMARC(P1) ;Increment total message arg count
MOVE P3,P2 ;P3 points to current entry
ADDI P2,.MEHSZ ;P2 points to first free word
MOVE F,DEFSWS ;Get default options
SETZ S1, ;Initially, no flags
TXNN F,FL.MOU ;Is this a mount request?
MOVX S1,ME%ALC ;Get the allocate-only bit
MOVEM S1,.MEFLG(P3) ;Stash the flags
SETZM VOLCNT ;Clear the count of VOLIDS
MOUN20: $CALL P$FLD ;Was VSN specified?
SKIPN ARG.DA(S1) ;Make sure its not null
$ERR (<Volume set name must be specified>)
MOVEM S1,VSNADR ;Save address of Volume set name
HRROI S1,ARG.DA(S1) ;Point to volume set name string
$CALL DEVCHK ;See if actual device name given
MOVEM S2,VSNAME ;Save SIXBIT volume set name
MOVE T1,S2 ;[10271]Save Device name
CAIN S1,.TYDSK ;[10271]Is it a disk?
DEVNAM T1, ;[10271]Yes, translate logical name.
JRST MOUN21 ;[10271]Failed, or not a disk.
MOVE T3,VSNADR ;[10271]Get device name address.
MOVEI T2,2 ;[10271]Arg block is only 2 long now.
STORE T2,ARG.HD(T3),AR.LEN ;[10271]So stuff it.
SETZM ARG.DA(T3) ;[10271]Zap the current name
ADD T3,[POINT 7,ARG.DA] ;[10271]Make into byte pointer
TRZ T1,7777 ;[10271]Ensure only 4 characters
MOLO: SETZ T2, ;[10271]Loop to change SIXBIT to ASCIZ
ROTC T1,6 ;[10271]Shift a character into T2
ADDI T2,"A"-'A' ;[10271]Make into ASCII
IDPB T2,T3 ;[10271]Stuff into name
JUMPN T1,MOLO ;[10271]Continue until done
MOUN21: TXNE F,FL.TAP!FL.DSK ;[10271]Request type known?
JRST MOUN25 ;Yes..then allow it
JUMPF [CAIN S1,ER$EZD ; ersatz device?
$ERR(<Ersatz device ^W/S2/ may not be mounted>)
CAIN S1,ER$PLD ; pathological name?
$ERR(<Pathological device ^W/S2/ may not be mounted>)
CAIN S1,ER$ASN ; ambigious?
$ERR(<Ambigious structure name ^W/S2/>)
CAIN S1,ER$ISN ; illegal?
$ERR(<Illegal structure name ^W/S2/>)
CAIN S1,ER$GDN ; generic?
$ERR(<Generic device ^W/S2/ may not be mounted>)
JRST MOUN25] ;No..process as VSN
CAIN S1,.TYMTA ;Yes..was it tape?
TXO F,FL.TAP ;Yes..specify tape
CAIN S1,.TYDSK ;Was it disk?
TXO F,FL.DSK
MOUN25: $CALL P$TOK ;Was it terminated by a token?
JUMPF MOUN30 ;No..on to parse logical name
MOVE S1,ARG.DA(S1) ;Get the token
CAMN S1,[ASCIZ/:/] ;Was VSN: specified?
JRST MOUN30 ;Yes..on to get logical name
$CALL P$PREV ;Backup to token again
$CALL MO$VOL ;Process VOLID list
JRST MOUN25 ;See if VSN(list): was specified!
MOUN30: $CALL P$SIXF ;Get locical name
JUMPF MOUN40 ;Don't store junk
MOVEM S1,LOGNAM ;Save logical name
$CALL P$TOK ;Get optional ":"
MOUN40: $CALL DOSWS
TXNN F,FL.DSK ;Is this a disk request ?
TXNE F,FL.TRK ;Was /TRACK specified ?
JRST MOUN41 ;Yes, skip this
SETZM S1 ;clear S1
MOVE S2,VSNAME ;Get the volume set name in sixbit
CAMN S2,[SIXBIT/M9/] ;Did he specify M9 ?
MOVX S1,.TMDR9 ;Yes, get 9 track code
CAMN S2,[SIXBIT/M7/] ;Did he specify M7 ?
MOVX S1,.TMDR7 ;Yes, get 7 track code
JUMPE S1,MOUN41 ;Neither,,skip this
MOVEI S2,.TMDRV ;Get /TRACK: block type
PUSHJ P,ADDSUB ;Add /TRACK:x to message
MOUN41: PUSHJ P,BLDVSN ;Build the VSN
PUSHJ P,LOGCHK ;No - check out the logical name
SETZ S1, ;Clear entry flags
TXNE F,FL.SCR ;Scratch volume wanted?
TXO S1,TM%SCR!TM%WEN ;Yes
TXNE F,FL.NEW ;New volume set wanted?
TXO S1,TM%NEW!TM%WEN ;Yes
TXNE F,FL.WRT ;Write enabled?
TXO S1,TM%WEN ;Yes
TXNE F,FL.WLK ;Write locked?
TXO S1,TM%WLK ;Yes
TXNE F,FL.BYP ;Bypass labels?
TXO S1,TM%BYP ;Yes
TXNE F,FL.PAS ;Was /PASSIVE specified?
TXO S1,SM%PAS ;Yes
TXNE F,FL.NOC ;Was /NOCREATE specified?
TXO S1,SM%NOC ;Yes
TXNE F,FL.EXC ;Was /EXCLUSIVE specified?
TXO S1,SM%EXC ;Yes
TXNE F,FL.QTA ;Was /QUOTA specified?
TXO S1,SM%ARD ;Yes
IORM S1,.MEFLG(P3) ;Save the entry flags
MOVEI S1,.MNUNK ;Get unknown entry type
TXNE F,FL.TAP ;Was it a tape request?
MOVEI S1,.MNTTP ;Yes..then use tape entry type
TXNE F,FL.DSK ;Was it a disk request?
MOVEI S1,.MNTST ;Yes..then use disk entry type
MOUN52: STORE S1,ARG.HD(P3),AR.TYP ;Save request type
MOVE S1,P2 ;Close current entry
SUB S1,P3 ;Compute entry length
STORE S1,ARG.HD(P3),AR.LEN ;Save in entry header
$CALL P$COMMA ;No..then must be a comma
JUMPT MOUN10 ;Yes..Back to try again
$CALL P$CFM ;Confirmed?
JUMPT MOUN80 ;Yes..send what we have
$ERR (<Unrecognized command syntax>)
MOUN80: SETZB S1,.MMFLG(P1) ;Clear message flag word
TXNE F,FL.WAT ;Want to wait for the mount?
TXO S1,MM.WAT ;Yes..light the flag
TXNE F,FL.NOT ;Want terminal notification?
TXO S1,MM.NOT ;Yes..light the flag
MOVEM S1,.MMFLG(P1) ;Set the message flags
SUB P2,P1 ;Compute message length
STORE P2,.MSTYP(P1),MS.CNT ;Save it
MOVEI S1,PAGSIZ ;Send of the page
MOVE S2,P1
$RETT
;MOUNT option processors
DOSWS:: $CALL P$SWIT ;Get a switch if any
$RETIF ;No, return
$CALL 0(S1) ; Else call the processor
JRST DOSWS ;Process next switch
;ACTIVE option places disk in jobs active search list
MO$ACT: MOVX S1,TXT(/ACTIVE) ;Get error prefix
$CALL DSKCHK ;Must be disk
TXZ F,FL.PAS ;Clear Passive flag
$RETT
;CHECK option lists the mount queues
MO$CHE: TXO F,FL.CHK ;Set the flag
$RETT
;CREATE option
MO$CRE: MOVX S1,TXT(/CREATE) ;Get error prefix
$CALL DSKCHK ;Must be disk
TXZ F,FL.PAS!FL.NOC ;Clear Passive and Nocreate
$RETT
;DENSITY option requests specific tape density
MO$DEN: MOVX S1,TXT(/DENSITY) ;Get error prefix
$CALL TAPCHK ;Must be tape
$CALL P$KEYW ;Get proper density
MOVEI S2,.TMDEN
PJRST ADDSUB
;DEVICE option requests specific device type
MO$DEV: $CALL P$SIXF ;Get requested device
$RETT
;DISK option declares disk devices
MO$DIS: MOVX S1,TXT(/DISK)
$CALL DSKCHK ;Must be disk request
$RETT
;EXCLUSIVE option declares that exclusive ownership is requested
MO$EXC: MOVX S1,TXT(/EXCLUSIVE)
$CALL DSKCHK ;Must be disk
TXO F,FL.EXC ;Set the flag
$RETT
;LABEL-TYPE option
MO$LAB: MOVX S1,TXT(/LABEL-TYPE) ;Get error prefix
$CALL TAPCHK ;Must be a tape request
$CALL P$KEYW ;Get the LABEL type
MO$LA1: CAXN S1,%TFLBP ;Was it BYPASS?
TXO F,FL.BYP ;Yes..set the flag
TXO F,FL.LAB ;Note that something was said
MOVEI S2,.TMLT ;Create label type entry
PJRST ADDSUB
;NEW-VOLUME-SET option
MO$NEW: MOVX S1,TXT(/NEW-VOLUME-SET)
$CALL TAPCHK ;Tape requests only
TXO F,FL.NEW ;Set the flag
$RETT
;NOCREATE option
MO$NOC: MOVX S1,TXT(/NOCREATE)
$CALL DSKCHK ;Disk requests only
TXO F,FL.NOC
$RETT
;NOWAIT option
;
;NOTIFY option
MO$NOW: TXZ F,FL.WAT ;Clear the wait flag,,imply notify
MO$NOT: TXOA F,FL.NOT ;Notify on completion
MO$NNT: TXZ F,FL.NOT ;No notify
$RETT
;PASSIVE option
MO$PAS: MOVX S1,TXT(/PASSIVE) ;Get error prefix
$CALL DSKCHK ;Must be dsk
TXO F,FL.PAS ;Set the PASSIVE flag
$RETT
;PROTECTION option
MO$PRO: MOVX S1,TXT(/PROTECTION) ;Get error prefix
$CALL TAPCHK ;Must be tape
$CALL P$NUM ;Get the value
CAIL S1,0 ;Check the range
CAILE S1,MAXPRO
$ERR (<Protection out of range>)
MOVEI S2,.TMVPR ;Create protection entry
PJRST ADDSUB ; and return
;QUOTA option
MO$QTA: MOVX S1,TXT(/QUOTA) ;Get error prefix
PUSHJ P,DSKCHK ;Must be dsk
TXO F,FL.QTA ;Set the quota flag
$RETT
;READ-ONLY option
MO$REA: TXO F,FL.WLK ;Set write lock flag
$RETT
;REMARK option
MO$REM: TXO F,FL.REM ;Remember we saw it
$CALL P$QSTR ;Get quoted string
SKIPT
$CALL P$FLD ;Or simple field
$CALL CPYSUB ;Create .TMRMK subentry
MOVEI S1,.TMRMK ;Make entry type remark
STORE S1,ARG.HD(S2),AR.TYP
$RETT
;SCRATCH option
MO$SCR: MOVX S1,TXT(/SCRATCH) ;Get error prefix
$CALL TAPCHK ;Must be tape
TXO F,FL.SCR ;Set the flag
$RETT
;SHARABLE option
MO$SHA: MOVX S1,TXT(/SHARABLE)
$CALL DSKCHK ;Must be disk
TXZ F,FL.EXC ;Clear Exclusive
$RETT
;TAPE option
MO$TAP: MOVX S1,TXT(/TAPE)
$CALL TAPCHK
$RETT
;TRACKS option
MO$TRA: MOVX S1,TXT(/TRACKS) ;Get error prefix
$CALL TAPCHK ;Must be tape
$CALL P$KEYW ;Get the track type
TXO F,FL.TRK ;Set /TRACK: flag
MOVEI S2,.TMDRV
PJRST ADDSUB
;WAIT option
MO$WAI: TXO F,FL.WAT ;Set the flag
$RETT
;WRITE-ENABLE option
MO$WRI: $CALL P$KEYW ;Get YES or NO
JUMPF [TXO F,FL.WRT ;Default is WRITE:YES
$RETT]
JUMPE S1,[TXO F,FL.WLK ;Set write lock if WRITE:NO
$RETT]
TXO F,FL.WRT ;Set write enable if WRITE:YES
$RETT
;VOLID option
MO$VOL: MOVX S1,TXT(Volume identifier) ;Get the error prefix
SKIPE VOLCNT ;Have we been here before?
$ERR (<Only one volume identifier list is allowed>)
INCR .MECNT(P3) ;Bump subentry count
MOVE P4,P2 ;Save free address
ADDI P2,1 ;Reserve a word for header
$CALL P$TOK ;Get optional list token
JUMPF [$CALL MO$VO3 ;Allow only one volume
JRST MO$VO2] ;If no token is found
MO$VO1: $CALL MO$VO3 ;Get volume identifier
$CALL P$COMMA ;More to come?
JUMPT MO$VO1 ;Yes..get the whole list
$CALL P$TOK ;Check optional list token
JUMPF [$ERR(<Missing volume identifier list terminator>)]
MO$VO2: MOVE S1,P2 ;Get final free address
SUB S1,P4 ;Compute argument length
MOVS S1,S1 ;Put length in Left half
HRRI S1,.TMVOL ;Get Volume subtype entry
MOVEM S1,ARG.HD(P4) ;Store in subentry header
MOVE S1,P4 ;Point to argument
$CALL UNICHK ;Check VOLID uniqueness
SKIPT ;All OK?
$ERR (<Volume identifiers must be unique>)
$RETT
;Routine to store and individual volume identifier
MO$VO3: $CALL P$SIXF ;Get the first volume
JUMPF [$ERR(<Invalid volume identifier>)]
JUMPE S1,[$ERR(<Volume identifier must not be null>)]
MOVEM S1,0(P2) ;Store the volume name
AOS VOLCNT ;Increment volume count
ADDI P2,1 ;Increment free address
$RETT
SUBTTL General routines
;ADDARG - Routine to add a 2 word argument to general message
;ADDSUB - Routine to add a 2 word subentry argument to MOUNT message
;ACCEPTS S1/ Data word to be stored in message
; S2/ argument type code
; P1/ Address of message header
; P2/ Address of first free word in message
; P3/ Address of current mount entry
ADDARG::
AOSA .OARGC(P1) ;Increment message arg count
ADDSUB::
INCR .MECNT(P3) ;Increment subargument count
MOVEM S1,ARG.DA(P2) ;Store data word
HRLI S2,ARG.SZ ;Get size of 2
MOVEM S2,ARG.HD(P2) ;Store in header
ADDI P2,ARG.SZ ;Point to next free word
$RETT
;CPYARG - Routine to copy argument to general message
;CPYSUB - Routine to copy subargument to MOUNT message
;ACCEPTS S1/ Address of argument header word
; S2/ Number of words in argument
;RETURNS S2/ Address of argument header in message
CPYARG::
AOSA .OARGC(P1) ;Increment message arg count
CPYSUB::
INCR .MECNT(P3) ;Increment subargument count
MOVS S1,S1 ;Create BLT pointer
HRR S1,P2
ADD S2,P2 ;Get Next Free address
BLT S1,-1(S2) ;Copy the whole argument
EXCH P2,S2 ;P2 points to next free address
$RETT ;S2 points to stored argument
;CPYSTR - routine to store asciz string
;ACCEPTS S1/ Pointer to source string
; S2/ Pointer to destination string
CPYSTR::
ILDB TF,S1
IDPB TF,S2
JUMPN TF,CPYSTR
$RETT
;TAPCHK - routine to ensure that we are processing a tape request
;DSKCHK - routine to ensure that we are processing a disk request
;ACCEPTS S1/ Pointer to error prefix
TAPCHK: TXNE F,FL.DSK ;Disk request?
$ERR (<^Q/S1/ is only valid for tape>)
TXO F,FL.TAP ;Remember we have a tape request
$RETT
DSKCHK: TXNE F,FL.TAP ;Tape request?
$ERR (<^Q/S1/ is only valid for disk>)
TXO F,FL.DSK ;Remember we have a disk request
$RETT
;LOGCHK - check and add LOGICAL name to mount request
LOGCHK: SKIPN S1,LOGNAM ;See if logical name
$RETT ;No--Just return
TXNE F,FL.DSK ;Disk request?
JRST LOGC.1 ;Yes--No logical name
DEVCHR S1, ;See if logical name in use
JUMPE S1,LOGC.2 ;No--Thats OK
TXNN S1,DV.ASC!DV.ASP ;Assigned by console or program?
JRST LOGC.2 ;No
SKIPE BATJOB ;Batch job?
$TEXT (,<% Specified logical name "^W/LOGNAM/" already in use>) ;Yes--Tell him
MOVX S1,<INSVL.(.FORED,FO.FNC)!FO.ASC>;Get a new channel
MOVEM S1,FBLK+.FOFNC ;Store
SETZM FBLK+.FOIOS ;No mode
MOVE S1,LOGNAM ;Get device
MOVEM S1,FBLK+.FODEV ;Store device
SETZM FBLK+.FOBRH ;And no buffers
MOVE S1,[.FOBRH+1,,FBLK] ;Point to FILOP.
FILOP. S1, ;Open the device
JRST LOGC.2 ;Cant
LOAD S1,FBLK+.FOFNC,FO.CHN ;Get channel
MOVEI S2,0 ;Clear logical name
DEVLNM S1, ;Zap it
JFCL ;We tried
MOVX S1,.FOREL ;Release function
STORE S1,FBLK+.FOFNC,FO.FNC ;Store it
MOVE S1,[1,,FBLK] ;Point to FILOP.
FILOP. S1, ;Release channel
JFCL ;Cant
LOGC.2: MOVE S1,LOGNAM ;Get logical name
MOVX S2,.TMLNM ;And block type
$CALL ADDSUB ;Add it
$RETT ;And return
LOGC.1: SKIPE BATJOB ;Batch job?
$TEXT (,<% Logical name "^W/LOGNAM/" ignored on disk structure ^W/VSNAME/:>) ;
$RETT ;Error and return
; Routine to build a volume set name into a MOUNT message block
; Call: PUSHJ P,BLDVSN
; <return>
;
; If the VSN is a generic device, then a VSN of DEV-xxxxxx (where xxxxxx
; is a random alpha-numeric value guaranteed to be unique) will be created.
; Otherwise, the existing VSN will be used.
;
BLDVSN: MOVEI TF,0 ;Clear character count
MOVEI S1,.TMSET ;Get subentry type
STORE S1,ARG.HD(P2),AR.TYP ;Store it
INCR .MECNT(P3) ;Increment subargument count
MOVEI S2,@VSNADR ;Get atring address - ARG.DA
ADD S2,[POINT 7,ARG.DA] ;Get byte pointer to read characters
MOVEI T1,ARG.DA(P2) ;Get storage address
HRLI T1,(POINT 7) ;Make a byte pointer
BLDV.1: ILDB S1,S2 ;Get a character
JUMPE S1,BLDV.2 ;Done ?
PUSHJ P,BLDV.C ;Store it
JRST BLDV.1 ;Loop back for another
BLDV.2: TXNE F,FL.GDV ;Generic device ?
PUSHJ P,BLDV.3 ;Yes - generate a special VSN
MOVX S1,.CHNUL ;Get a <NUL>
PUSHJ P,BLDV.C ;Store it
IDIVI TF,5 ;Count words in the VSN
ADDI TF,ARG.DA+1 ;Round up to the next full word
HRLM TF,(P2) ;Update word count
ADD P2,TF ;Get new first free word pointer
POPJ P, ;Return
BLDV.3: TXNE F,FL.MOU ;If ALLOCATE,,thats an error
SKIPN BATJOB ;If a batch pre-scan,,thats an error
$ERR (<Illegal volume set name specified for MOUNT/ALLOCATE command>)
MOVEI S1,"-" ;Get a funny character
PUSHJ P,BLDV.C ;Store it
$CALL I%NOW ;Get the current time
MOVEI T2,6 ;Only 6 characters
BLDV.4: IDIVI S1,^D36 ;Radix 36
PUSH P,S2 ;Save the remainder
SOSE T2 ;Count characters
PUSHJ P,BLDV.4 ;Recurse if not done
POP P,S1 ;Get a digit
ADDI S1,"0" ;Make it ASCII
CAILE S1,"9" ;A number ?
ADDI S1,"A"-"9"-1 ;No - make it a letter
BLDV.C: IDPB S1,T1 ;Store it
ADDI TF,1 ;Count characters
POPJ P, ;Return
;UNICHK - routine to ensure uniqueness among argument entries
;ACCEPTS S1/ Address of argument header
UNICHK: LOAD T2,ARG.HD(S1),AR.LEN ;Get argument length
MOVE T1,S1 ;Save beginning address
ADDI T2,-1(S1) ;Compute end test address
UNICH1: ADDI T1,1 ;Compute next address
CAML T1,T2 ;Done?
$RETT ;Yes..all are unique
MOVEI S2,1(T1) ;S2 points to comparision entry
MOVE S1,0(T1) ;Get entry to check
UNICH2: CAMLE S2,T2 ;Finished checking this entry?
JRST UNICH1 ;Yes..back for next
CAME S1,0(S2) ;No..is it unique?
AOJA S2,UNICH2 ;Yes..back to check next entry
$RETF ;No..return the failure
;DEVCHK - routine to ensure device string is valid
;ACCEPTS S1/ Pointer to device name string
;RETURNS S1/ Device type (.TYDSK or .TYMTA)
; S2/ Sixbit device name (abbrv of name string)
;ERRORS ER$IDN Invalid device name
; ER$NSD No such device
; ER$USD Unsupported device
; ER$EZD Ersatz device
; ER$PLD Pathological device
; ER$ASN Ambigious structure name
; ER$ISN Illegal structure name
; ER$GDN Generic device name
DEVCHK: $CALL S%SIXB ;Convert to sixbit
ILDB S1,S1 ;Get terminator
JUMPN S1,[$RETER(ER$IDN)] ;Invalid device name
$SAVE <S2,P1,P2,P3> ;Save sixbit for return
MOVE P1,S2 ;Save the device name
MOVE TF,[1,,P1] ;Yes, get DSKCHR parms
DSKCHR TF, ;Get structure status bits
JRST DEVC.1 ;Not a disk
LOAD TF,TF,DC.TYP ;Get the device type
CAXN TF,.DCTAB ;Ambigious?
$RETER(ER$ASN) ;Yes, say so
CAXE TF,.DCTUF ;Unit within strcuture?
CAXN TF,.DCTCN ;Controller class?
$RETER(ER$ISN) ;Yes, illegal structure
CAXE TF,.DCTCC ;Controller class?
CAXN TF,.DCTPU ;Physical unit?
$RETER(ER$ISN) ;Yes, illegal structure
CAXN TF,.DCTDS ;Generic or ersatz?
JRST DEVC.2 ;Yes, check it out some more
MOVX S1,.TYDSK ;Its a disk
$RETT ;And return
DEVC.2: MOVE TF,[3,,P1] ;Get PATH. args
PATH. TF, ;Find out some more
$RETT ;Ignore any error
TXNE P2,PT.DLN!PT.EDA ;Pathological name?
$RETER(ER$PLD) ;Yes, say so
TXNE P2,PT.IPP ;Implied PPN? (ersatz)
$RETER(ER$EZD) ;Yes, say so
$RETER(ER$GDN) ;Else call it generic
DEVC.1: DEVTYP S2, ;Get device type
$RETER(ER$NSD) ;Unknown device
JUMPE S2,[$RETER(ER$NSD)] ;Unknown device
TXNE S2,TY.GEN ;A generic device ?
TXO F,FL.GDV ;Yes - remember it
LOAD S1,S2,TY.DEV ;Load the device type
CAIE S1,.TYMTA ;Is it a tape??
$RETER(ER$USD) ;No,,Unsupported device
;(DSKCHR would win if a disk)
$RETT ;Yes,,return
SUBTTL DATA STORAGE
XLIST ;Turn listing off
LIT ;Dump literals
LIST ;Turn listing on
RELOC 0
$DATA DEFSWS,1 ;Sticky mount switches
$DATA VOLCNT,1 ;Number of volume identifiers specifed
$DATA LOGNAM,1 ;Logical name
$DATA FBLK,.FOMAX ;FILOP. UUO block
;Global data
$GDATA VSNAME,1 ;6bit Volume set name
$GDATA VSNDEV,1 ;6 bit device name
$GDATA VSNADR,1 ;Address of ASCIZ Volume set name argnt
$GDATA CMDNAM,1 ;Address of parsed command name
$GDATA BATJOB,1 ;Batch job flag (0 = batch job)
END