.MCALL .MODULE .MODULE PIP,VERSION=31,COMMENT=,AUDIT=YES ; Copyright (c) 1998 by Mentec, Inc., Nashua, NH. ; All rights reserved ; ; This software is furnished under a license for use only on a ; single computer system and may be copied only 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 except for use on such ; system and to one who agrees to these license terms. Title ; to and ownership of the software shall at all times remain ; in Mentec, Inc. ; ; The information in this document is subject to change without ; notice and should not be construed as a commitment by Digital ; Equipment Corporation, or Mentec, Inc. ; ; Digital and Mentec assume no responsibility for the use or ; reliability of its software on equipment which is not supplied ; by Digital or Mentec, and listed in the Software Product ; Description. ; Edit History: ; ; 001 22-Jan-80 22:17 Guldenschuh, Chuck cpg [240,148] ; Add missing error message ; (001) ; 002 03-Oct-80 11:22 AM Metsch, James (29602) [240,122] ; Fix system crash if disk copy is replaced while ; running PIP ; (002) ; 003 24-Dec-80 11:23 AM Lorraine Ricard [240,83] ; Update version number for patch to fix ; matching file specifications errors in PIPEXE ; (003) ; 004 09-Feb-81 09:39 AM Lorraine Ricard [240,83] ; update version number ; (004) ; 005 11-Mar-81 03:29 PM David Fingerhut [240,134] ; PUT IN /SINCE OPTION ; (005) ; 006 20-Mar-81 10:33 AM David Fingerhut [240,134] ; put in Verification Error message ; (006) ; 007 30-Mar-81 04:11 PM David Fingerhut [240,134] ; Add conditional assembly for /WAIT with IND ; (007) ; 008 03-Apr-81 03:15 PM David Fingerhut [240,134] ; /WAIT with IND: enlarge buffer for mount messages ; (008) ; 009 07-Apr-81 10:52 AM David Fingerhut [240,134] ; Fix /EXCL to work with multiple input devices ; (009) ; 010 17-Apr-81 01:48 PM David Fingerhut [240,134] ; Make PIP LOOKUP PIPA for Autopatch ; (010) ; 011 05-Jun-81 01:48 PM David Fingerhut [240,134] ; Put in COPY/MULTIVOL ; (011) ; 012 30-Jun-81 10:46 AM David Fingerhut [240,134] ; MT: input-copy files in physical order ; (012) ; 013 27-Aug-81 03:34 PM David Fingerhut [40,134] ; Allow "N" response during 'Continue[1,23]' for /WAIT ; (013) ; 014 13-Oct-81 02:51 PM David Fingerhut [40,134] ; Input file > output volume during /MULTIVOL ; (014) ; 015 05-Nov-81 04:17 PM David Fingerhut [40,134] ; Add error msg for /PROTECT and /NOPROTECT ; (015) ; 016 06-Jan-82 02:12 PM David Fingerhut [40,134] ; Add .SFDAT and /PROTECT support ; (016) ; 017 26-Jan-82 03:33 PM David Fingerhut [40,134] ; Use .PVAL request ; (017) ; 018 03-Feb-82 12:22 PM David Fingerhut [40,134] ; Can't incr siz of expan. inp. lst for .PROTECT ; (018) ; 019 12-Mar-82 12:22 PM David Fingerhut [40,134] ; update version number ; (019) ; ; 19-AUG-85 George Thissell ; update version number ; ; 3-OCT-85 George Thissell ; update version number ; ; 14-Apr-87 Deb Sengupta ; Deleted unused error message "IOV". ; ; (019) 08-Jun-89 Incomplete definitions for /ASCII and /BINARY ; MBG mutual exclusion list. Did not include /VERIFY ; although /VERIFY excluded /ASCII and /BINARY ; PIPINI (017) ; ; (021) 09-Jun-89 Code change to cause deletion of input files ; MBG when doing COPY/CONCATENATE/DELETE ; PIPROT (021) ; PIPEXE (027) ; ; (023) 16-Jun-89 Another change for COPY/DELETE/... so that protected ; MBG files are reported during the input volume scan ala ; the DELETE command and so that protected files ; cause a warning message (as before) but then really ; do get copied. ; PIPEXE (029) ; ; Incorrect exclusion list excludes COPY/MULTI/DEL ; while allowing COPY/DEL/MULTI. Fixed to allow both ; forms. KMON will reject DELETE/MULTI. ; PIPINI (019) ; ; (025) 16-Aug-89 Change to prevent double copying of a file when ; MBG the input and output device names are different ; logicals, but physically the same. ; PIPEXE (031) ; ; (027) 26-Sep-89 Yet another code change for COPY/CONCATENATE so ; MBG that if an input file is not found, the copy is ; terminated with an 'F' error and the output file ; is discarded. ; PIPEXE (033) ; ; (028) 05-Apr-90 Per action #7076, fix to code to prevent copy ; MBG of specific file from magtape if file is not ; in position specified by /POS:n. ; PIPEXE (034) ; ; (029) 02-Nov-1990 bracket error messages in ;+/;ERROR/.../;- ; JFW ; ; (030) 21-Oct-1996 Handle epoch bits correctly in dates ; Tim Shoppa ; ; (031) 21-Oct-1996 Complain about repeated date fields ; Tim Shoppa .SBTTL Edit History ; CG01 Correct .SYS processing PIPEXE EL42 PIP X07.00A ; CG02 Correct /EXCLUDE processing PIPROT EL33 PIP X07.00B ; PIPINI EL27 ; PIPEXE EL43 ; CG03 Correct /PREDELET processing PIPEXE EL44 PIP X07.00C ; CG04 Correct bootable magtape problem PIPMT EL10 PIP X07.00D .SBTTL General Comments .SBTTL MACRO definitions ;+ ; MACROS ;- .MCALL .CLOSE, .CSISPC,.DATE, .DSTATU,.ENTER, .FETCH .MCALL .GTIM, .GTLIN, .GVAL, .HERR, .LOCK, .LOOKUP .MCALL .PRINT, .PURGE, .READW, .RCTRLO,.RELEAS,.SCCA .MCALL .SERR, .SETTOP,.SPFUN, .TTYIN, .UNLOCK,.WRITW .MCALL .SAVES, .REOPEN, .TRPSET, .EXIT, .PVAL ;017 .MCALL .ASSUME .BR SOB .MACRO .BSECT NAME ..BS.. = 1 .ENDM .BSECT .MACRO .DSECT NAME ..DS.. = 0 .ENDM .DSECT .MACRO .ERR AREA,CODE,LEVEL,RETURN,FILE,TABLE,PREFIX,LEVBYT,RETRY,ASCII .IF NB AREA .IF DIF ,AREA MOV AREA,R0 .ENDC .ENDC .IF NB CODE MOVB CODE,@R0 .ENDC .RET.. = 0 ...... = 0 .IF NB RETURN .IRPC ..RET., .IF EQ ...... .IIF IDN ..RET., .RET.. = 200 ...... = 1 .ENDC .ENDM .ENDC .ASC.. = 0 .IIF NB .ASC.. = 40 ...... = 0 .IRPC ..LEV., .IF EQ ...... MOVB #''..LEV.!.RET..!.ASC..,1(R0) ...... = 1 .ENDC .ENDM .IIF NB MOV PREFIX,2(R0) .IIF NB MOV LEVBYT,4(R0) .IIF NB MOV TABLE,6(R0) .IF NB MOV FILE,10(R0) .IIF NB .ERROR ; F I L E and A S C I I can not both be specified; .IFF .IF NB MOV ASCII,10(R0) .IFF CLR 10(R0) .ENDC .ENDC .IIF NB MOV RETRY,12(R0) JSR PC,$ERROR .ENDM .ERR .MACRO .GTCOR SIZE MOV #FREMLH,R0 .IF NB SIZE MOV SIZE,R1 .ENDC CALL $RQCB .ENDM .GTCOR .MACRO BS NAME .IF NB NAME NAME == ..BS.. .ENDC ..BS.. = ..BS.. * 2 .ENDM BS .MACRO CM1... AREA,CHAN ...CM5 .IF IDN ,<#0> CLRB @R0 .IFF .IF NB MOVB CHAN,@R0 .ENDC .ENDC .ENDM CM1... .MACRO DS NAME,TYPE,SIZE .IF NB NAME NAME == ..DS.. .ENDC .IF NB TYPE .IF IDN TYPE, .IF B SIZE ..DS.. = ..DS.. + 1 .IFF ..DS.. = ..DS.. + SIZE .ENDC .IFF .IF B SIZE ..DS.. = ..DS.. + 2 .IFF ..DS.. = ..DS.. + .ENDC .ENDC .IFF .IF B SIZE ..DS.. = ..DS.. + 2 .IFF ..DS.. = ..DS.. + .ENDC .ENDC .ENDM DS .MACRO .BSECT NAME=...ABS,HILO=LOW,GLOBAL=YES PSECT , .IF NDF NAME NAME: .ENDC ;NDF NAME .. = . .IF IDN , . = . + NAME - . + 400 .IFF ;IDN , . = . + NAME - . + 1 .ENDC ;IDN , GLBL.. = 0 .IIF IDN ,, GLBL.. = 1 .MACRO BS NAME1,GLOBAL PSECT NAME .IF NB NAME1: .BLKB . .IF B .IIF NE GLBL.., .GLOBL NAME1 .IFF ;B .GLOBL NAME1 .ENDC ;B .IFF ;NB .BLKB . .ENDC ;NB .ENDM BS .ENDM .BSECT .MACRO .DSECT NAME=...ABS,N=0,GLOBAL=YES PSECT , .IF NDF NAME NAME: .ENDC ;NDF NAME .IF DIF , . = . + NAME - . + N .ENDC ;DIF , ..GLBL = 0 .IIF IDN ,, ..GLBL = 1 .MACRO DS NAME1,UNIT,SIZE=1,GLOBAL PSECT NAME .IF NB .IF B NAME1: .BLKW SIZE .IFF ;B NAME1: .BLKB SIZE .ENDC ;B .IF B .IIF NE ..GLBL, .GLOBL NAME1 .IFF ;B .GLOBL NAME1 .ENDC ;B .IFF ;NB .IF B .BLKW SIZE .IFF ;B .BLKB SIZE .ENDC ;B .ENDC ;NB .ENDM DS .ENDM .DSECT .MACRO UNORG .ENDM UNORG .MACRO ORIGIN SECT,LIST .MACRO UNORG .LIST BEX PSECT SECT, .ENDM UNORG PSECT , .NLIST BEX .ENDM ORIGIN .MACRO PSECT SECT,LIST .LIST BEX .IF IDN SECT,<*> UNORG .NLIST BEX .MEXIT .IFF .IF NB .PSECT SECT,LIST .IFF .PSECT SECT .ENDC .ENDC .NLIST BEX .ENDM PSECT .MACRO SAVE02 JSR R2,$SAVVR ;Save R0-R2 .ENDM SAVE02 .MACRO SAVE05 JSR PC,$SAVAL ;Save R0-R5 .ENDM SAVE05 .MACRO SAVE35 JSR R5,$SAVRG ;Save R3-R5 .ENDM SAVE35 .MACRO WAIT PROMPT,DEV .IF NB PROMPT MOV PROMPT,WAITPR .ENDC .IF NB DEV MOV DEV,R0 .ENDC CALL WAITCK .ENDM .AUDIT .PIPPRE,.PIPINI,.PIPEXE,.PIPDK,.PIPMT,.PIPCT .ENABL LC,GBL .SBTTL PSECT definitions ;+ ; CONDITIONAL ASSEMBLIES - ;010 ; The IND and ATP conditional assemblies are for using /WAIT with IND. ;010 ; If IND is NE, text will be read from the file AP.TMP. This text ;010 ; will be used in the mount messages for COPY/WAIT. The format of ;010 ; AP.TMP is: ;010 ; ;010 ; ;010 ; ;010 ; If an asterisk is used instead of the text, the prompt for that ;010 ; volume will not be issued. It is assumed that that volume is ;010 ; already mounted. ;010 ; If ATP is NE, IND will also be set NE. Besides that, the name used ;010 ; in the LOOKUP of PIP will be PIPA.SAV. This means that if ATP is set ;010 ; NE, PIP must be renamed to PIPA.SAV. ;010 ; ; IF VOL =1, following each text for a prompt in AP.TMP is the volume ; id of that volume. After the user mounts the volume, PIP checks the ; volume id to see that the right volume was mounted. ; - ;010 .IIF NDF IND, IND = 0 ;010 .IIF NDF ATP, ATP = 0 ;010 .IIF NE ATP, IND = 1 .IIF NDF VOL, VOL = 0 ;010 ;+ ;010 ; The PSECT's are defined here to give them the desired ordering. ; Consider the ordering critical. Several of the PSECT's contain ; stoppers for lists in the previous PSECT. ;- PSECT ...AFL ; PSECT ...CSW ; PSECT ...DIR ; PSECT ...DST ; PSECT ...EBL ; PSECT ...EBO ; PSECT ...ERS ; PSECT ...IOF ; PSECT ...MFL ; PSECT ...PDV ; PSECT IMPURE ;Impure data psect PSECT .LIBD. ;Data (library routines) PSECT .LIBP. ;Data (library routines) PSECT PURE ;Pure data PSECT PUREB ;[byte] Pure data PSECT .LIBC. ;Library routines PSECT .LIBO. ;Library overlay code PSECT PIPMTR ;Magtape support routines PSECT PIP ;Main code psect PSECT PATCH ;Patch psect .BLKW 64. ;Root patch space .SBTTL Symbolic definitions .SBTTL System symbolics S$STRT == 40 ;Job start address S$JSW == 44 ;Job status word JS.NTG == 10 ; Non-terminating .GTLIN bit JS.REE == 20000 ; Re-enter bit JS.TTLC == 40000 ; Lower case console input bit S$USRL == 46 ;Floating USR load address S$HLMT == 50 ;Job high limit S$EERB == 52 ;EMT error byte S$UERB == 53 ;User error byte UE.SUC == 1 ; Success UE.WRN == 2 ; Warning UE.ERR == 4 ; Error UE.SEV == 10 ; Severe S$RMON == 54 ;Base of RMON S$TFIL == 56 ;Terminal character and fill count S.BLKY == 256 ;Offset from RMON to BLKEY S.USRL == 266 ;Offset from RMON to USR load address S.VER == 276 ;Offset from RMON to monitor version number S.UPD == 277 ;Offset from RMON to monitor update number S.CNF1 == 300 ;Offset from RMON to configuration word 1 C1.FGL == 200 ; SET => Foreground loaded S.PNAM == 404 ;Offset from RMON to offset to PNAME$ S.MNAM == 406 ;Offset from RMON to RAD50 monitor name .SBTTL Channel status offsets and symbolics .DSECT ...CSW,GLOBAL=YES DS C.CSW ;Offset to channel status word CSW.HE == 1 ; Hard error bit CSW.DI == 76 ; Device index mask CSW.RF == 100 ; Rename in progress flag CSW.EN == 200 ; File was .ENTERed CSW.DS == 17400 ; Directory segment containing file mask CSW.EF == 20000 ; EOF encountered CSW.CA == 100000 ; Channel active flag DS C.SBLK ;Offset to starting block number of file DS C.LENG ;Length of file or empty DS C.USED ;Actual data length DS C.DEVQ,,0 ;Device word DS C.NREQ,BYTE ;Number of outstanding I/O requests DS C.UNIT,BYTE ;Device unit number .SBTTL Program symbolics OCHAN == 0 ;Output channel number NCHAN == 8. ;Channel for /NOREP .LOOKUPs ; also used for deletion of ; input files for /CONCAT/DELETE HICHAN == 8. ;Highest channel in use MAXSEG == 37 ;Maximum number of directory segments MAXBYT == 356 ;Maximum number of extra bytes .BSECT ...IOF,GLOBAL=YES BS DEV.DK ;Disk flag BS DEV.MT ;Magtape flag BS DEV.CT ;Cassette flag BS DEV.LP ;Line printer flag BS DEV.TT ;Console terminal flag BS DEV.SD ;Strange device flag BS DEV.DR ;Non-RT-11 directory structured (MT, CT) BS DEV.RO ;Read only device BS DEV.WO ;Write only device BS FLG.FL ;Indicates a file spec was given BS FLG.DV ;Indicates a device spec was given BS FLG.WM ;Indicates an embedded wild card was given BS FLG.WF ;Indicates a wildcard in the filename BS FLG.WE ;Indicates a wildcard in the filetype BS FLG.CO ;Indicates a matching file was found ;012 BS DEV.MS ;Multisize device ;014 ;014 FLG.WD == ;Wild is any of them .SBTTL Home block and VOL1 offsets and symbolics HOMBLK == 1 ;Home block for disks DK.SAV == 66.*2 ;INIT/RESTORE save area DK.VRN == 726 ;Offset to system version (disk) DK.VID == 730 ;Offset to vol id (disk) DK.OWN == 744 ;Offset to owner name (disk) DK.VLN == 12. ;Size of disk vol id (and owner name) MT.FID == 4 ;Offset to magtape file ID .SBTTL Directory offsets and symbolics SEGSIZ == <2 * 256.> ;Size of a directory segment in words .SBTTL Disk directory header offsets .DSECT ...DIR,GLOBAL=YES DS DH.AVL ;Number of available directory segments DS DH.NXT ;Pointer to next directory segment DS DH.HI ;Highest directory segment open DS DH.EXB ;Number of extra bytes in directory entries DS DH.STB ;Starting block number for files in segment DS DH.SIZ,,0 ;Size of directory header words .SBTTL Disk directory entry offsets and symbolics .DSECT ...DIR,GLOBAL=YES DS DE.ST ;Entry status DS DE.FN1 ;Offset to first word of filename DS DE.FN2 ;Offset to second word of filename DS DE.TYP ;Offset to filetype DS DE.LEN ;Offset to filesize DS DS DE.DAT ;Offset to file creation date DS DE.SIZ ;Size of directory entry .BSECT ...DIR,HIGH,GLOBAL=YES BS DS.TNT ; 1 => tentative entry BS DS.EMP ; 1 => empty entry BS DS.PRM ; 1 => permanent entry BS DS.EOS ; 1 => end-of-segment entry BS BS BS BS DS.PRO ; 1 => protected file .SBTTL Physical device table offsets .DSECT ...PDV,GLOBAL=YES DS VOL.SY ;Offset to system device entry DS VOL.IN ;Offset to input device entry DS VOL.OU ;Offset to output device entry .SBTTL Filename expansion block offsets .DSECT ...EBO,GLOBAL=YES DS EB.DEV ;Offset to device name DS EB.FN1 ;Offset to first word of filename DS EB.FN2 ;Offset to second word of filename DS EB.TYP ;Offset to filetype DS EB.LEN ;Offset to length of file DS EB.STB ;Offset to start block of file DS EB.DAT ;Offset to file creation date+prot statu;018 DS EB.SIZ ;Size of expansion block ;.ASSUME EB.SIZ EQ DE.SIZ .SBTTL ASCII symbolics LF == 012 ;ASCII CR == 015 ;ASCII BLANK == 040 ;ASCII blank RUBOUT == 377 ;Rubout HDR1 == "HD ;First 2 characters of HDR label (MT) EOF1 == "EO ;First 2 characters of EOF label (MT) .SBTTL RAD50 symbolics R50AST == 132500 ;RAD50 '* ' (unused character code) .SBTTL .CSI offsets OUSPSZ == 12 ;Size of CSI output spec in bytes INSPSZ == 10 ;Size of CSI input spec in bytes SPCSIZ == + ;Size of CSI file spec area .SBTTL .DSTATUS offsets and symbolics .DSECT ...DST,GLOBAL=YES DS DS.HID,BYTE ;Handler ID byte DS DS.HFL,BYTE ;Handler flag byte DS DS.HSZ ;Handler size DS DS.HLA ;Handler load address + 6 DS DS.SIZ ;Size of device .BSECT ...DST,HIGH,GLOBAL=YES BS DSH.MS ;Multisize Device ;014 BS BS DSH.SF ;Device accepts .SPFUN's BS BS DSH.ND ;Non-RT-11 directory structured BS DSH.WO ;Write only device BS DSH.RO ;Read only device BS DSH.RA ;Random access device LPID == 03 ;LP and LS dstatus code TTID == 04 ;TT dstatus code MTID == 11 ;MT dstatus code CTID == 13 ;CT dstatus code MMID == 20 ;MM dstatus code MSID == 35 ;MS dstatus code MUID == 60 ;MU dstatus code ; CT, MT, MM, MS codes SF.RDV == 370 ;.SPFUN code to read (MT) SF.WTV == 371 ;.SPFUN code to write (MT) SF.RWD == 373 ;.SPFUN code to rewind (CT,MT) SF.BS == 375 ;.SPFUN code to back space (MT) SF.FS == 376 ;.SPFUN code to forward space (MT) SF.WTM == 377 ;.SPFUN code to write tape mark (MT) ; DL, DM, DY, DX codes SF.GSZ == 373 ;.SPFUN code to get device size SF.IRT == 374 ;.SPFUN code to initializing replacement table SF.WPS == 376 ;.SPFUN code to write physical sector (DX) SF.WRT == 376 ;.SPFUN code to write SF.RED == 377 ;.SPFUN code to read .SBTTL Pure data PSECT PUREB .SBTTL Prompts and such .NLIST BEX VERSON::.NLCSI PATLEV=:.-2 CRLF:: .BYTE 0 MSGCON::.ASCII \; Continue? \<200> MSGRUS::.ASCII \; Are you sure? \<200> MSGFGL::.ASCII \Foreground loaded\<200> .EVEN ;005 MONTHS::.RAD50 \BADJANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC\ ;005 .WORD 0 ;005 .LIST BEX ;+ ;ERROR .SBTTL Error Messages ;+ ; All error message given by PIP are listed here for completeness. The ; comment following some of them give the module where that message is ; defined. The first argument to the ERRMSG macro is the 3 character ; name of the message. The second argument is the message text. The ; messages are given a number which is the index into a table which points ; to the message text. The table's name is defined by the MSGLST macro. ; The first word of the table is the maximum number of message. The ; MSGEND macro must be invoked after the last message. Message of the ; form "FE.xxx" are all found in the module ULB033. ;- .MACRO ERRMSG NAME,TEXT DS NAME,BYTE .PSECT .LIBD. EM.'NAME: .ASCII \TEXT\<200> .PSECT .LIBP. .WORD EM.'NAME .ENDM ERRMSG .MACRO MSGLST NAME .DSECT ...ERS,GLOBAL=YES .PSECT .LIBP. NAME: .WORD ..MAX. .ENDM MSGLST .MACRO MSGEND DS ..MAX.,BYTE .ENDM MSGEND ;+ ;ERROR MSGLST ERRTAB ERRMSG CSE, ERRMSG DIU, ERRMSG DIE, ERRMSG FLO, ERRMSG FSN, ERRMSG ILC, ERRMSG IDL, ERRMSG IPR, ;016 ERRMSG ISD, ;016 ERRMSG ILD, ERRMSG ILO, ;;;;ERRMSG IOV, ;020 ERRMSG IOF, ;001 ERRMSG ILR, ERRMSG IUW, ERRMSG LNC, ERRMSG NSY, ERRMSG NRP, ERRMSG ONC, ;013 ERRMSG PFL, ERRMSG RBT, ERRMSG SFF, ;014 ERRMSG TMO, ERRMSG WVR, ERRMSG VER, ;006 ; ; The following messages are in module ULB033 ; ;ERRMSG CIU ;ERRMSG CNO ;ERRMSG DVF ;ERRMSG DFL ;ERRMSG FER ;ERRMSG FCP ;ERRMSG FNF ;ERRMSG ILD ;ERRMSG INE ;ERRMSG NOM ;ERRMSG OPE ;ERRMSG OFF ;ERRMSG OFP ;ERRMSG SYS ;ERRMSG EOF MSGEND ;- .SBTTL Impure data PSECT IMPURE ;+ ; IMPURE ; All global impure data will be found here. Non-global impure data ; is defined in the routines which have major access. ;- $AFLAG::.WORD 0 ;Action option flag word $MFLAG::.WORD 0 ;Modification option flag word .ASSUME $DIRBF EQ BEGLST .ASSUME $DIRBF EQ $AVAIL+2 .ASSUME $DIRCH EQ ICHAN .ASSUME $DIRCH EQ $AVAIL+4 .ASSUME $DIRSG EQ $AVAIL+6 .ASSUME $EXTBY EQ $AVAIL+10 .ASSUME $HISEG EQ $AVAIL+12 .ASSUME $LSTLN EQ $AVAIL+14 .ASSUME $NXTFL EQ $AVAIL+16 .ASSUME $NXTSG EQ $AVAIL+20 .ASSUME $STBLK EQ $AVAIL+22 $AVAIL::.WORD 0 ;# of available directory segments (input) BEGLST:: ;-> expanded input list $DIRBF::.WORD 0 ;-> directory buffer ICHAN:: ;Input channel number $DIRCH::.WORD 0 ;Channel number for directory I/O $DIRSG::.WORD 0 ; $EXTBY::.WORD 0 ;# of extra bytes/entry $HISEG::.WORD 0 ;# of highest segment open $LSTLN::.WORD 0 ;Length of last file $NXTFL::.WORD 0 ;-> next entry in directory segment $NXTSG::.WORD 0 ; $STBLK::.WORD 0 ;Start block number of current entry ACTION::.WORD 0 ;-> action routine (DOCOPY, DOREN, DODEL) COPRTN::.WORD 0 ;-> copy routine to use (ASCII, BINARY, IMAGE) CTRLC:: .WORD 0 ;^C intercept flag DATE:: .WORD 0 ;System date OUTDAT::.WORD 0 ;Date for output file (/SETDAT:dat) ENDLST::.WORD 0 ;-> past end of expanded input list FREMLH::.WORD 0 ;Free memory list head for INITDM,$RQCB,$RLCB .WORD 0 ; MUST be 0 GETNXT::.WORD 0 ;-> directory scan routine for input device .ASSUME OFILNO EQ IFILNO+2 IFILNO::.WORD 0 ;File sequence number for magtape input OFILNO::.WORD 0 ;File sequence number for magtape output KOPIES::.WORD 0 ;Number of copies to make for PRINT INFOX:: .WORD 0 ;Value for /X: MATRTN::.WORD 0 ;-> routine to use for filespec match ;CG02 PRNTHD::.WORD 0 ;Flag for printing logging header SAVSTS::.WORD 0 ;-> device/file flag word for current file SCCNT:: .WORD 0 ;CTRL/C intercept counter SYSDEV::.WORD 0 ;RAD50 system device and unit number WAITPR::.WORD 0 ;Disk (sys, in, out) prompt for "continue?" LIMITS::.LIMIT ;Program high and low limits TIME:: .BLKW 2 ;System time PDEV:: .BLKW 3 ;Table of currently mounted devices DEFEXT::.BLKW 4 ;No default extension MTERR:: .BLKW 4 ;MT .SPFUN error reporting area STATUS::.BLKW 4 ;.DSTATUS block OLDNAM::.BLKW 4 ;Old or input filename NEWNAM::.BLKW 4 ;New or output filename OVSIZE::.WORD 0 ;Size of the output volume ;014 NONFIL::.WORD 2 ;Buffer for non-filestructured LOOKUP ;014 ;014 IBFPTR::.WORD 0 ;-> into input buffer IBFSIZ::.WORD 0 ;Size of input buffer in blocks IBUFE:: .WORD 0 ;-> past end of input buffer IBUFF:: .WORD 0 ;-> input buffer IERR:: .WORD 0 ;Flag that an input error occurred OBFPTR::.WORD 0 ;-> into output buffer OBFSIZ::.WORD 0 ;Size of output buffer in blocks OBLK:: .WORD 0 ;Next output block number OBUFE:: .WORD 0 ;-> past end of output buffer OBUFF:: .WORD 0 ;-> output buffer VBUFF:: .WORD 0 ;-> verification buffer ;006 OERR:: .WORD 0 ;Flag that an output error occurred FLGWRD::.WORD 0 ;Flag word for copy from MT ;012 ;Bits: ;012 PO.COP == 1 ;Do PHYSICAL ORDER copying ;012 AREA:: .BLKW 3 ;EMT area .IF NE IND APIN:: .BLKW 256. ;Buffer for mount message ;012 APSZ:: .WORD 256. ;Size of APIN ;012 APBLK:: .WORD 0 ;Block number for reading AP.TMP file ;012 ACHAN:: .WORD 7. ;Channel number for AP.TMP ;013 .ENDC ;NE IND ;012 ;***** The following words must be in this order ***** ;005 DAY:: .WORD 0 ;Current date (0-31) ;005 MON:: .WORD 0 ;Current month (0-12) ;005 YEAR:: .WORD 0 ;Current year (72-??) ;005 UDATE:: ;005 UYEAR:: .WORD 0 ;/DATE entered year UMON:: .WORD 0 ;/DATE entered month ;005 UDAY:: .WORD 0 ;/DATE entered date ;005 TDAY:: .WORD 0 ;Temp day used in date conversions ;005 TMON:: .WORD 0 ;Temp month ;005 TYEAR:: .WORD 0 ;Temp year ;005 SDATE:: SYEAR:: .WORD 0 ;/SETDATE entered year SMON:: .WORD 0 ;/SETDATE entered month SDAY:: .WORD 0 ;/SETDATE entered day BDATE:: BYEAR:: .WORD 0 ;/BEFORE entered year BMON:: .WORD 0 ;/BEFORE entered month BDAY:: .WORD 0 ;/BEFORE entered day IDATE:: IYEAR:: .WORD 0 ;/SINCE entered year IMON:: .WORD 0 ;/SINCE entered month IDAY:: .WORD 0 ;/SINCE entered day ;***** End of order dependent area ***** ;005 SDATSB::.WORD 0 ;031 BDATSB::.WORD 0 ;031 UDATSB::.WORD 0 ;031 IDATSB::.WORD 0 ;031 SWD:: .WORD 0 ;Number of times procedure SD was entere;005 ERAREA::.BYTE 0 ; Error code byte .BYTE 0 ; Error level/return flag .WORD ERRPRE ; -> Error message prefix .WORD ERRLEV ; -> Error level byte .WORD ERRTAB ; -> Error message offset table .WORD 0 ; -> File name block .WORD ABORT ; -> Abort return DEVSTS::.BLKW 7 ;Device/file flag words STAT:: .WORD 0 ;Pointer for DEVSTS ;012 PNAME:: .BLKW 7 ;Physical device name table FNAME:: .BLKW 6 ;Physical names for EXCLUDE ;009 FPTR:: .WORD 0 ;Pointer for FNAME ;009 IOAREA::.BLKW 10 ;EMT area block OUTFIL::.BLKB ;CSI output file spec area INFILE::.BLKB ;CSI input file spec area ENDSPC:: ;End of CSI filespec area TESTNM::.BLKB 11.*6.+2 ;Area for ASCII filespecs or /EXCLUDE ;CG02 .ASSUME ENDSPC EQ INFILE+ CMDBUF::.BLKB 42. ;CSI command buffer CMDBF1::.BLKB 40. ; .NLIST BEX ERRPRE::.ASCII \?PIP-\ ;Error message prefix string ERRLEV::.ASCII \x-\<200> ;Error message level string ERROPT::.ASCII \ \<200> ;Invalid option letter .EVEN .IF EQ ATP ;010 PIPLKB::.RAD50 \SY PIP SAV\ ;File name for LOOKUP ;002 .IFF ;010 PIPLKB::.RAD50 \SY PIPA SAV\ ;File name for LOOKUP ;010 .ENDC ;EQ ATP ;010 CSTAT:: .BLKW 6. ;Area for channel status information .LIST BEX .SBTTL Start-up and re-entry code .SBTTL PIP - Main entry point .ASECT . = S$JSW ;Set up the JSW .WORD JS.REE ; Re-enterable ORIGIN PIP PSECT IMPURE SAVESP: .WORD 0 ;SP save area PSECT * BR RETRY ;Re-entry point PIP:: MOV SP,SAVESP ;Save the initial stack pointer RETRY:: MOV SAVESP,SP ;Restore the initial stack pointer CALL INIT ;Initialize the state CALL EXPAND ;Expand the input list and do command ABORT:: BIT #NOTSYS,MNTFLG ;Is the system device down? ;013 BEQ 1$ ;Branch if not. No need to wait WAIT #WAITSY,#SYSDEV ;Wait for system device to be mounted (m 1$: ;MOV @#S$RMON,R0 ;Get start of RMON ;017 ;CLR S.BLKY(R0) ;Force in fresh directory ;017 .PVAL #IOAREA,#S.BLKY,#0 ;Clear BLKEY ;017 ;017 .PURGE #17 ;Purge channel 17 .LOOKUP #IOAREA,#17,#PIPLKB ;.LOOKUP SY:PIP.SAV ;002 BCC RETRY ;No error ;002 ;+ ;ERROR .ERR #ERAREA,#FE.SYS,LEVEL=FATAL,RETURN=YES ;System error ;002 ;- .EXIT ;002 .SBTTL Support routines .SBTTL YESCHK - Get a response from the console ;+ ; YESCHK ; This routine gets a response from the console terminal, rather than any ; indirect command file that may be running. It does this for the ; /QUERY and "continue" prompts. The entire purpose for taking input ;013 ; from the console is to protect the user from himself. ; ; JSR PC,YESCHK ; ; R0 = 1 if the console input = Y* ;013 ; R0 = -1 if the console input = N* or double Control/C ;013 ; R0 = 0 if the console input <> Y* or N* (other) ;013 ; ;013 ; also, ;013 ; Z-bit = 1 if the console input = Y* ;- YESCHK:: .TTYIN ;Get a character from the terminal MOV R0,-(SP) ;Save it 1$: .TTYIN ;Collect the rest of the stuff TST CTRLC ;Double Control/c's? ;013 BEQ 12$ ;No ;013 CLR R0 ;Clear out the Control/C ;013 BR 25$ ;Same as N* ;013 12$: CMPB R0,#LF ;Is it a ? ;013 BNE 1$ ;Branch if not. Get rest of line CLR R0 ;Default is neither Y* nor N* ;013 CMPB #'Y,(SP) ;Is it a Y? ;013 BNE 2$ ;No ;013 INC R0 ;It's Y* ;013 2$: CMPB #'N,(SP) ;Is it a N? ;013 BNE 3$ ;No ;013 25$: DEC R0 ;It's N* ;013 CLR CTRLC ;Clear SCCA status word ;013 3$: MOV R0,-(SP) ;Save answer BIT #FL.NRP,$AFLAG ;Doing /multi ? BEQ 50$ ;No, branch .PVAL #AREA,#S.BLKY,#0 ;Force new directory read 50$: MOV (SP)+,R0 ;Restore answer CMPB #'Y,(SP)+ ;Set the Z-bit if it's Y* ;013 RETURN .SBTTL FGCHEK - Check for a loaded foreground job ;+ ; FGCHEK ;- FGCHEK:: BIT #FL.YES,$MFLAG ;/Y specified? BNE 2$ ;Branch if so. Return with Z-bit set .GVAL #IOAREA,#S.CNF1 ;Get 1st config word BIT #C1.FGL,R0 ;Is a foreground job loaded? BEQ 2$ ;Branch if not .PRINT #MSGFGL ;Print the message .PRINT #MSGRUS ;Print "are you sure?" BR YESCHK ;Check the response and return 2$: SEZ ;Flag /Y RETURN .DSABL LSB .SBTTL WAITCK - Wait for a disk to be mounted ;+ ; WAITCK ; This routine will wait for the system device to be replaced with the output ; device, if /W (/WAIT) was given. It will prompt the user to type "Y". If ; anything other than "Y" is typed, the user is prompted again. ; ; R0 -> RAD50 device filename block ; WAITPR -> Prompt ; ; JSR PC,WAITCK ; ; R0 modified ; ; Can be called with macro WAIT ; ; WAIT PROMPT ;- PSECT PUREB MNTPRM: .ASCII \Mount \<200> WAITMV::.ASCII \next output\<200> ;011 ;007 .IF EQ IND ;007 VINPRM: .ASCII \ volume in \<200> WAITIN::.ASCII \input\<200> WAITSY::.ASCII \system\<200> WAITOU::.ASCII \output\<200> .IFF ;007 VINPRM: .ASCII \ in \<200> ;007 WAITIN::.ASCII \ \ ;011 WAITSY::.ASCII \ \ ;011 WAITOU::.ASCII \ \ WTINVL::.ASCII \ \ WTOUVL::.ASCII \ \ WTSYVL::.ASCII \ \ .ENDC ;EQ IND ;007 PSECT IMPURE DEVPRM: .BLKB 6 ;ASCII device name storage TMPDEV: .WORD 0 ;RAD50 device name .WORD 0 ;Must be 0 .BLKW 2 ; MNTFLG::.WORD 0 ;Flag word for /WAIT ;013 NOTSYS = 1 ;"System volume not mounted" flag ;013 ABT = 2 ;User typed N*: abort ;013 ;013 PSECT * WAITCK:: BIC #ABT,MNTFLG ;Clear abort flag ;013 CMP WAITPR,#WAITMV ;Is it for /MULTIVOL? ;011 BEQ 4$ ;Yes, force it ;011 BIT #FL.WAT,$AFLAG ;/WAIT given? BEQ 3$ ;Branch if not. Immediate return .IF NE IND ;007 CMPB @WAITPR,#'* ;Is the prompt a *? ;007 BEQ 3$ ;Yes, don't print it ;007 .ENDC ;.IFN IND ;007 4$: MOV R1,-(SP) ;Preserve R1 ;011 MOV #DEVPRM,R1 ;Point to RAD50/ASCII conversion area MOV @R0,TMPDEV ;Get the device name MOV #TMPDEV,R0 ;R0 -> device name CALL $FNASC ;Convert to ASCII (removes blanks) MOVB #200,@R1 ;No , please MOV (SP)+,R1 ;Restore R1 1$: .RCTRLO .PRINT #MNTPRM ;Print "Mount " .PRINT WAITPR ;Print the disk prompt (system, input, output) .PRINT #VINPRM ;Print " volume in " .PRINT #DEVPRM ;Print the device name .PRINT #MSGCON ;Print "; Continue? " CALL YESCHK ;Get a response ;013 ; BNE 1$ ; or wait until you do ;013 TST R0 ;What's the response? ;013 BGE 11$ ;Branch if it's not N* ;013 BIS #ABT,MNTFLG ;We want to abort ;013 BIT #NOTSYS,MNTFLG ;Is the system mounted? ;013 BEQ 19$ ;Yes - go ahead and abort ;013 MOV #WAITSY,WAITPR ;Set up prompt to mount system volume ;013 MOV #SYSDEV,R0 ;Device for system volume ;013 BR 4$ ;Go mount system volume ;013 11$: BEQ 1$ ;Not Y* or N* - go reprompt ;013 BIT #ABT,MNTFLG ;Answer was yes - Are we aborting? ;013 BEQ 12$ ;No it's just a normal mount ;013 BIC #NOTSYS,MNTFLG ;System volume is back up ;013 ;+ ;ERROR 19$: .ERR #ERAREA,#ONC,LEVEL=ERROR,RETURN=YES ;013 ; <-E-Operation not completed> ;013 ;- JMP RETRY ;Get a new command line ;013 12$: .IF NE VOL CALL VOLCHK ;Check for proper volume id BCS 1$ ;Wrong volume - reprompt .ENDC ;NE IND CMP WAITPR,#WAITSY ;Are we putting the system device back u;013 BNE 2$ ;Branch if not BIC #NOTSYS,MNTFLG ;Say we've got it back ;013 CALL NOSCCA ;Turn off CTRL/C intercept BR 3$ ; 2$: CMP SYSDEV,TMPDEV ;Are we dismounting the system device? BNE 3$ ;Branch if not. CALL SCCA ;Intercept CTRL/C's BIS #NOTSYS,MNTFLG ;Say the system device isn't there ;013 3$: RETURN .SBTTL VOLCHK - Verify volume id after volume is mounted. ;+ ;VOLCHK ;This procedure checks the volume id of a volume after it is mounted for ;a /WAIT operation. It is used in conjuction with the APPRMT procedure in ;PIPEXE. That procedure contains a more detailed description of how to use ;VOLCHK and APPRMT. ; ; Input: ; DEVPRM = ASCII device name storage ; WAITPR ->Prompt ; TMPDEV = RAD50 device name ; ; CALL VOLCHK ; ; Output: ; C BIT SET -> Wrong volume was mounted ; C BIT CLEAR -> Correct volume was mounted ;- .IF NE VOL PSECT PUREB ;+ ;ERROR ;only if VOL conditional selected MSGWVL: .ASCII \Wrong volume mounted in \<200> MGEND: .ASCIZ <12><15> ;- PSECT IMPURE DBLK: .BLKW 4 ;Device name block for .LOOKUP PSECT * VOLCHK: JSR R2,$SAVVR ;Save R0-R2 .LOOKUP #IOAREA,ACHAN,#TMPDEV ;Open the device non-filestructured BCC 1$ ;Branch if no error ;+ ;ERROR ;only if VOL conditional selected ;WHAT DOES A BLANK .ERR DO? .ERR 1$: .READW #IOAREA,ACHAN,#APIN,APSZ,#HOMBLK BCC 2$ ;Branch if no error .ERR #ERAREA,#FE.INE,LEVEL=FATAL,RETURN=NO,FILE=#TMPDEV ; <-F-Input error: dev> ;- 2$: .CLOSE ACHAN ;Close the channel MOV #APIN,R1 ;R1-> home block ADD #DK.VID,R1 ;R1-> volume id CMP WAITPR,#WAITIN ;Is it for input volume? BNE 3$ ;Branch if not MOV #WTINVL,R2 ;R2 -> vol id for input volume BR 5$ 3$: CMP WAITPR,#WAITOU ;Is it for output volume? BNE 4$ ;Branch if not MOV #WTOUVL,R2 ;R2 -> vol id for output volume BR 5$ 4$: MOV #WTSYVL,R2 ;R2 -> vol id for system volume 5$: MOV #6,R0 ;Number of words in vol id 6$: CMP (R1)+,(R2)+ ;Compare the vol ids BNE 7$ ;Branch if they differ SOB R0,6$ ;continue CLC ;Say they match BR 9$ ;And return ;+ ;ERROR ;only if VOL conditional selected 7$: .PRINT #MSGWVL ;"Wrong volume mounted in " .PRINT #DEVPRM ;Device name .PRINT #MGEND ;CRLF ;- SEC ;Say they didn't match 9$: RETURN .ENDC ;NE IND .SBTTL NOSCCA - Drop CTRL/C intercept ;+ ; NOSCCA ; This routine backs up one level of .SCCA. When the count goes to 0, ; CTRL/C intercept is disabled. ; ; CALL NOSCCA ; ; R0 = random ; SCCNT = SCCNT - 1 ;- .ENABL LSB NOSCCA:: DEC SCCNT ;Decrement the .SCCA count BGT 2$ ;Branch if it should still be in effect CLR SCCNT ;Don't allow it to go negative MOV R1,-(SP) ;Preserve R1 CLR R1 ;Set up to turn off CTRL/C intercept BR 1$ ;Go turn off CTRL/C .SBTTL SCCA - Set CTRL/C intercept ;+ ; SCCA ; This routine bumps the .SCCA count and sets CTRL/C intercept ; ; CALL SCCA ; ; R0 = random ; SCCNT = SCCNT + 1 ;- SCCA:: MOV R1,-(SP) ;Preserve R1 MOV #CTRLC,R1 ;R1 -> CTRL/C flag word INC SCCNT ;Bump the count 1$: .SCCA #IOAREA,R1 ;Set/clear the intercept MOV (SP)+,R1 ;Restore R1 2$: RETURN .DSABL LSB .SBTTL RTOA - Convert 3 RAD50 words to ASCII ;+ ; RTOA ; This routine converts 3 RAD50 words to ASCII. It assumes that the 3 ; words to convert is a filename block, and inserts blanks in the ASCII ; string at the places that the match routine expects them (after the ; filename and after the filetype.) ; ; R0 -> 3 word block ; R1 > 11 byte block to store the ASCII ; ; CALL RTOA ;- RTOA:: JSR R2,$SAVVR ;Save R0 - R2 MOV R0,R2 ;Point to the RAD50 to convert MOV (R2)+,R0 ;Get the first word CALL $R50AS ;Convert it MOV (R2)+,R0 ;Get next word CALL $R50AS ; and convert it MOVB #BLANK,(R1)+ ;Move in a blank MOV @R2,R0 ;Get the next word CALL $R50AS ;Convert it MOVB #BLANK,(R1)+ ;Store the final blank RETURN ;005 ;005 .SBTTL CONDAT ;005 ;005 ;+ ;005 ; CONDAT ;005 ; This routine converts the RT-11 format date into something usable. ;005 ; INPUTS: ;005 ; R0 contains the RT-11 format date ;005 ; OUTPUTS: ;005 ; The current day, month, and year stored in TDAY, TMON, and ;005 ; TYEAR. ;005 ; R0 is modified ;005 ;- ;005 ;005 ;XTERNL ;005 ;005 ;GBLDAT ;005 ;005 CONDAT:: ;005 MOV R1,-(SP) ;Save R1 ;005 MOV R2,-(SP) ; and R2 ;005 MOV R0,R1 ;Get the date ;005 BIC #177740,R1 ;Clear all but low 5 bits of year ;030 ADD #72.,R1 ;RT-11 years are -72 ;005 MOV R1,TYEAR ;Save the year ;005 MOV R0,R1 ;Now we pick out the epoch ;030 ASR R1 ;Shift right ;030 SWAB R1 ; by 9 bits ;030 BIC #^c0140,R1 ;Now we have epoch*32 ;030 ADD R1,TYEAR ;Add it to the year. ;030 BIC #140000,R0 ;clear out any epoch bits left ;030 MOV #32.,R2 ;Divide by 32 ;005 CALL DDIV ;This will put the day in the low 5 bits;005 MOV R0,TDAY ;Store it ;005 BIC #177740,TDAY ;Get rid of all but the day ;005 CALL DDIV ;Now get the month ;005 MOV R0,TMON ; and save it ;005 MOV (SP)+,R2 ;Restore the registers ;005 MOV (SP)+,R1 ; ;005 RETURN ;005 ;005 .SBTTL DDIV- Single precision divide ;005 ;005 ;+ ;005 ; DDIV ;005 ; INPUTS: ;005 ; R0 = dividend ;005 ; R2 = divisor ;005 ; OUTPUTS: ;005 ; R0 = quotient ;005 ; R1 = remainder ;005 ; R2 is unchanged ;005 ;- ;005 ;005 DDIV:: ;005 MOV #16.,-(SP) ;Push the shift count ;005 CLR R1 ;Clear out the remainder ;005 1$: ASL R0 ;Double precision shift ;005 ROL R1 ; ;005 CMP R2,R1 ;Will the divisor fit? ;005 BHI 2$ ;Branch if not ;005 SUB R2,R1 ; ;005 INC R0 ; ;005 2$: DEC @SP ;Done? ;005 BGT 1$ ;Branch if not ;005 TST (SP)+ ;Clean the stack ;005 RETURN ;005 ;014 .SBTTL GTOVSZ - Get the output volume size ;014 ;+ ;014 ; GTOVSZ ;014 ; ;014 ; Gets the size of the current output volume and puts it in OVSIZE. ;014 ; This is used during /MULTIVOL to determine if the reason why a file ;014 ; didn't fit was because the file was bigger than the volume. ;014 ; Assumes that if it's not a multisize device, OVSIZE already contains ;014 ; the device size. ;014 ; ;014 ; ;014 ; CALL GTOVSZ ;014 ; ;014 ; OVSIZE = Size of the output volume in blocks ;014 ;- ;014 ;014 GTOVSZ:: ;014 JSR R2,$SAVVR ;Save R0 - R2 ;014 MOV #OUTFIL,R2 ;R2 -> CSI file spec ;014 MOV #DEVSTS,R1 ;R1 -> Output device status word ;014 BIT #DEV.MS,@R1 ;Is it a multisize device? ;014 BEQ 6$ ;Branch if not ;014 MOV (R2),NONFIL ;Set up for non-file structured LOOKUP ;014 CLR NONFIL+2 ; ;014 .LOOKUP #IOAREA,#OCHAN,#NONFIL ;Open the channel ;014 BCC 5$ ;Branch if no error ;014 CLR R0 ;Get ready for MOVB ;014 BISB @#S$EERB,R0 ;Get the error byte ;014 BNE 1$ ;Branch if not channel in use ;014 ;+ ;ERROR MOV #FE.CIU,R1 ;Set error code ;014 ; <-F-Channel in use> ;014 ;- CLR R2 ;Don't give filename ;014 BR 4$ ; ;014 1$: DEC R0 ;File not found?? SHOULD NOT OCCUR!!! ;014 BNE 2$ ;Branch if not ;014 ;+ ;ERROR MOV #FE.FNF,R1 ;Set error code ;014 ; <-F-File not found DEV:> ;014 ;- BR 4$ ; ;014 2$: DEC R0 ;Device in use? ;014 BNE 3$ ;Branch if not ;014 ;+ ;ERROR MOV #DIU,R1 ;Set error code ;014 ; <-F-Device in use DEV:> ;014 BR 4$ ; ;014 3$: MOV #FE.SYS,R1 ;Oops! ;014 ; <-F-System error> ;014 CLR R2 ;No filename ;014 4$: .ERR #ERAREA,R1,LEVEL=FATAL,RETURN=NO,FILE=R2 ;014 ;- ;014 5$: .SPFUN #IOAREA,#OCHAN,#SF.GSZ,#OVSIZE,#1,#0,#0 ;Get the size ;014 ;of the device ;014 BCC 55$ ;Branch if no error ;014 ;+ ;ERROR .ERR #ERAREA,#SFF,LEVEL=FATAL,RETURN=NO ;014 ; <-F-Size function failed> ;014 ;- 55$: .CLOSE #OCHAN ;Close the channel ;014 6$: RETURN ;Return the device size.END PIP ;014 ;014 .END PIP ;014