Trailing-Edge
-
PDP-10 Archives
-
tops10_tools_bb-fp64b-sb
-
10,7/fscopy/fscopy.mac
There are 3 other files named fscopy.mac in the archive. Click here to see a list.
TITLE FSCOPY - A PROGRAM TO COPY FIL;E
SUBTTL BILL MEIER 8-SEP-77
SEARCH JOBDAT,MACTEN,SCNMAC,UUOSYM
FSYVER==1
FSYMIN==0
FSYWHO==0
FSYEDT==26
LOC .JBVER
VRSN. (FSY)
TWOSEG
RELOC 400000
.TEXT ",REL:SCAN/SEARCH, REL:WILD, REL:HELPER"
;AC'S
F=0 ;FLAGS
T4=<1+<T3=1+<T2=1+<T1=1>>>> ;FOUR CONSECUTIVE TEMPORARY ACS
P4=<1+<P3=1+<P2=1+<P1=5>>>> ;FOUR CONSECUTIVE PRESERVED ACS
N=P3 ;SCANNING WORD RESULT
C=P4 ;SCANNING CHARACTER RESULT
MP=11
DP=12
L=13
P=17 ;PUSH DOWN LIST POINTER
;SOFTWARE CHANNELS
OC==1 ;OUTPUT CHANNEL
IC==2 ;INPUT CHANNEL
;ASSEMBLY PARAMETERS
ND LN$PDL,^D100
ND LN$LEN,.RBAC8+1 ;INCLUDE ACCOUNT STRING
ND LN$DSK,.DCSMT+1
;FLAGS
FL.PSI==1B0 ;PSISER BROKEN
FL.EXI==1B1 ;EXIT WHEN DONE
FL.CC== 1B2 ;^C CONTINUE TYPED
FR.STO==1B18 ;KSCOPY IS STOPPED
FR.ABO==1B19 ;ABORT COPING THIS FILE
FR.FE= 1B20 ;COPYING FE.SYS FILE
FR.SWT==1B21 ;SOME /BEFORE/SINCE SWITCHES (FOR WHAT)
;MONITOR PARAMETERS (FROM COMMOD.MAC)
ND FBOOTB,4 ;FIRST BLOCK FOR BOOTB
ND NBOOTB,4 ;NUMBER OF BOOT BLOCKS
ND LBNHM1,1 ;LOGICAL BLOCK NUMBER FIRST HOME BLOCK
ND LBNHM2,12 ;LOGICAL BLOCK NUMBER SECOND HOME BLOCK
ND HOMNAM,0 ;LOCATION OF SIXBIT/HOM/
ND HOMFEA,61 ;LOCATION OF FE.SYS
ND HM$VAL,1B2 ;BIT THAT SAYS ITS VALID
ND HOMFES,62 ;SIZE OF FE.SYS
ND HOMCOD,176 ;UNLIKELY CODE OFFSET
ND CODHOM,707070 ;THAT UNLIKELY CODE VALUE
ND HOMSLF,177 ;SELF BLOCK NUMBER
ND .RBSLF,177 ;SELF BLOCK NUMBER OF RIB
ND NM$RIB,2 ;NUMBER OF RIBS (PRIME+SPARE)
ND JACCT,1B17 ;BIT IN JBTSTS (.GTSTS) FOR JACCT
SUBTTL EDIT HISTORY
;8-Sep-77
;
;1 FSCOPY -- The fast disk-2-disk copy utility
;2 Improve command scanning a little
;3 Fix ?ILL MEM REF when copying 0 block SFD's
;4 Allow FSCOPY to copy boot blocks (0,4-7) and FE.SYS
;5 Implement /SINCE/BEFORE/ASINCE/ABEFORE/MSINCE/MBEFORE
;6 Do Checkpointing for better restarting
;7 Add SUPERSEDE (ALWAYS, OLDER, NEVER)
;10 Fix ?Quota exceeded message
;6-Sep-78
;11 Dont hang in TI after ^C^C CONTinue sequence
;12 Add EXIT when done in interactive mode
;13 Dont abort transfer of UFD if input read errors
;14 Add /EXCLUDE [P,PN] to exclude copying of PPN
;15 Give %No files/%No UFDs match message if thats the case
;16 Default [*,*] if [1,2] or [,] if not. Also handle [,123] etc
;17 Handle NUL: better
;
;20-25 Mysteriously lost
;
;26 Convert to use standard SCAN and WILD.
;
;END EDIT HISTORY
DEFINE $FATAL (PFX,TXT,MOR,CON<.FMSGE##>),<ERR (0,PFX,<TXT>,MOR,CON)>
DEFINE $WARN (PFX,TXT,MOR,CON<.+1>),<ERR (1,PFX,<TXT>,MOR,CON)>
DEFINE $INFO (PFX,TXT,MOR,CON<.+1>),<ERR (2,PFX,<TXT>,MOR,CON)>
DEFINE ERR (TYP,PFX,TXT,MOR,CON),<
E$$'PFX:PUSHJ P,[XLIST
PUSHJ P,ERROR
XWD ''PFX'',[ASCIZ |TXT|]
XWD TYP,CON
XWD MOR,0
LIST]
>
DEFINE WRD2BK (AC,E),<
IFNB <E>,<MOVE AC,E>
ADDI AC,177
LSH AC,-7
>
SUBTTL SCAN DEFINITIONS
DEFINE SWTCHS,<
SN ALLOCATE,S.ALLOC,FS.NFS
SP BUFFERSIZE,S.BUFF,.BLOKW##,BUF,FS.NFS!FS.LRG
SN BOOTS,S.BOOT,FS.NFS
SP CHECKPOINT,S.CHECK,.SWDEC##,CHK,FS.NFS
SP COPY,,$COPY,,FS.NFS!FS.VRQ!FS.HEL
SS DIRECTORY,S.LEVEL,%DIRECTORY,FS.NFS
SP DSKPRI,S.DSKP,.SWDEC##,DSK,FS.NFS
SP EXCLUDE,S.EXCLUDE,.SWFIL##,EXCL,FS.NFS!FS.VRQ
SN FESYS,S.FESYS,FS.NFS
SS FILES,S.LEVEL,%FILES,FS.NFS
SP HPQ,S.HPQ,.SWDEC,HPQ,FS.NFS
SP INITIAL,S.INIT,.SWFIL##,INIT,FS.NFS!FS.VRQ
SP MBEFORE,S.MBFR,.SWDTP##,,FS.NFS
SP MSINCE,S.MSNC,.SWDTP##,,FS.NFS
SP RETRY,S.RETRY,.SWDEC##,RET,FS.NFS!FS.LRG
SS SILENCE,S.LEVEL,%SILENCE,FS.NFS
SN SINGLE,S.SINGLE,FS.NFS
SP SORT,,$SORT,,FS.NFS!FS.HEL
SL SUPERSEDE,S.SUPER,SUP,,FS.VRQ
SP WHAT,,$WHAT,,FS.NFS
>
KEYS (SRT,<FILES,DIRECTORY>)
KEYS (SRTK,<NONE,NAME,EXTENSION,LOCATION>)
KEYS (SUP,<ALWAYS,OLDER,NEVER>)
%SILENCE==0
%DIRECTORY==1
%FILES==2
DM BUF,^D1000*200,^D100*200,^D200*200
DM INIT,.FXLEN,.FXLEN,.FXLEN
DM EXCL,.FXLEN,.FXLEN,.FXLEN
DM HPQ,17,0,1
DM DSK,3,0,1
DM RET,.INFIN,.INFIN,5
DM CHK,^D60,^D10,^D5
IBLK: IOWD 1,[SIXBIT/FSCOPY/]
OFFSET,,'FSY'
EXP .TOCHR##
LN$IBLK==.-IBLK
OBLK:!
VBLK: IOWD FSY.L,FSY.N
XWD FSY.D,FSY.M
EXP FSY.P
EXP -1
LN$OBLK==.-OBLK
LN$VBLK==.-VBLK
DOSCAN (FSY.)
SUBTTL INITIALIZE
FSCOPY: TDZA T1,T1 ;FLAG NORMAL ENTRY
MOVEI T1,1 ;FLAG CCL ENTRY
MOVEM T1,OFFSET ;SAVE STARTING OFFSET
RESET ;RESET THE WORLD
MOVEI F,0 ;CLEAR FLAGS
MOVE T1,[S.ZER,,S.ZER+1] ;SET UP BLT
SETZM S.ZER ;CLEAR FIRST WORD
BLT T1,S.ZERM ;CLEAR CORE
MOVE T1,[S.ONE,,S.ONE+1] ;SET UP BLT
SETO S.ONE ;INIT FIRST WORD
BLT T1,S.ONEM ;RESET SWITCHES
MOVE P,[IOWD LN$PDL,PDL] ;SETUP A STACK
PUSHJ P,.TOINI## ;INIT BUFFERED OUTSTR
MOVE T1,[LN$IBLK,,IBLK] ;POINT TO .ISCAN BLOCK
PUSHJ P,.ISCAN## ;INITIALIZE COMMAND SCANNER
MOVE T1,[LN$OBLK,,OBLK] ;POINT TO .OSCAN BLOCK
PUSHJ P,.OSCAN## ;READ SWITCH.INI
MOVE T1,.JBFF ;GET INITAIL .JBFF
MOVEM T1,SAVFF ;SAVE AWAY FOR LATER
PUSHJ P,I$INIT ;INIT VARIABLES
PUSHJ P,SWTDEF ;DEFAULT THE SWITCHES
MAINLP: MOVE P,[IOWD LN$PDL,PDL] ;FIX STACK
MOVE T1,[LN$VBLK,,VBLK] ;POINT TO .VSCAN BLOCK
PUSHJ P,.VSCAN## ;DO ALL THE WORK
PUSHJ P,.MONRT## ;RETURN TO MONITOR
JRST MAINLP ;RESTART IN CASE CONTINUE
SUBTTL SWTDEF -- DEFAULT THE SWITCHES
SWTDEF: MOVEI T1,%DIRECTORY ;ASSUME LEVEL=DIRECTORY
SKIPGE S.LEVEL ;SEE IF SPECIFIED
MOVEM T1,S.LEVEL ;NO--STORE DEFAULT
MOVEI T1,1 ;DEFAULT /ALLOCATE
SKIPGE S.ALLOCATE ;SEE IF GIVEN
MOVEM T1,S.ALLOCATE ;NO--STORE DEFAULT
MOVEI T1,SRTKNAME ;/SORT:DIRECTORY:NAME
SKIPG S.DSRT ;SEE IF GIVEN
MOVEM T1,S.DSRT ;NO--STORE
MOVEI T1,SRTKNONE ;/SORT:FILES:NONE
SKIPG S.FSRT ;SEE IF GIVEN
MOVEM T1,S.FSRT ;NO--STORE DEFAULT
MOVX T1,AD.RET ;GET ABSENT DEFAULT
SKIPGE S.RETRY ;SEE IF GIVEN
MOVEM T1,S.RETRY ;NO--STORE DEFAULT
MOVX T1,AD.CHK ;GET ABSENT DEFAULT
SKIPG S.CHECK ;SEE IF GIVEN
MOVEM T1,S.CHECK ;NO--STORE DEFAULT
MOVX T1,SUPALWAYS ;GET DEFAULT
SKIPG S.SUPER ;SEE IF GIVEN
MOVEM T1,S.SUPER ;NO--STORE DEFAULT
POPJ P, ;AND RETURN
SUBTTL CPYDEF -- FILL IN DEFAULTS AFTER COPY
CPYDEF: MOVEI T1,S.INITIAL ;GET /INITIAL SPEC
PUSHJ P,DEFPPN ;FILL IN DEFAULTS
MOVEI T1,S.EXCLUDE ;GET /EXCLUDE SPEC
PUSHJ P,DEFPPN ;FILL IN DEFAULTS
MOVX T1,FX.DIR ;GET DIRECTORY BIT
TDNN T1,I.SPEC+.FXMOD ;SEE IF GIVEN ON INPUT
PUSHJ P,FIXPPN ;NO--DEFAULT IT
MOVEI T1,I.SPEC ;GET INPUT SCAN BLOCK
PUSHJ P,DEFPPN ;DEFAULT IT
;Default /BOOTS/FESYS if [1,2], full wildcard, and no /INITIAL
SKIPE S.INIT+.FXDIR ;/INITIAL GIVEN?
JRST CPYD.1 ;YES
MOVE T1,.MYPPN## ;GET ME
CAMN T1,OPRPPN ;[1,2]?
SKIPE I.SPEC+.FXDIM ;YES--FULL WILDCARD?
CPYD.1: TDZA T1,T1 ;NO--CLEAR T1
MOVEI T1,1 ;YES--SET /YES
SKIPGE S.BOOTS ;/BOOTS GIVEN?
MOVEM T1,S.BOOTS ;NO--DEFAULT IT
SKIPGE S.FESYS ;/FESYS GIVEN?
MOVEM T1,S.FESYS ;NO--DEFAULT IT
POPJ P, ;AND RETURN
;DEFPPN fills in the users PPN for constructions like [,],[123,],[,123]
DEFPPN: MOVX T2,FX.DIR ;GET DIRECTORY BIT
TDNN T2,.FXMOD(T1) ;SEE IF GIVEN
POPJ P, ;NO--RETURN
MOVE T2,.FXDIR(T1) ;GET PPN
TLNN T2,-1 ;SEE IF PROJ
HRROS .FXDIM(T1) ;NO--CLEAR WILDCARDS
TLNN T2,-1 ;CHECK AGAIN
HLL T2,.MYPPN## ;NO--USE MINE
TRNN T2,-1 ;SEE IF PROG
HLLOS .FXDIM(T1) ;NO--CLEAR WILDCARDS
TRNN T2,-1 ;CHECK AGAIN
HRR T2,.MYPPN## ;NO--USE MINE
MOVEM T2,.FXDIR(T1) ;STORE PPN
POPJ P, ;AND RETURN
;FIXPPN defaults [*,*] if [1,2] and [,] if not
FIXPPN: MOVE T1,.MYPPN## ;GET ME
CAME T1,OPRPPN ;GOD?
JRST FIXP.1 ;NO
SETOM I.SPEC+.FXDIR ;YES--FORCE WILD
JRST FIXP.2 ;AND SET DIR BIT
FIXP.1: MOVEM T1,I.SPEC+.FXDIR ;NO--SET MY PPN
SETOM I.SPEC+.FXDIM ;AND CLEAR WILDS
FIXP.2: MOVX T1,FX.DIR ;GET DIRECTORY BIT
IORM T1,I.SPEC+.FXMOD ;SET
POPJ P, ;AND RETURN
SUBTTL COPY -- COPY THE FILE STRUCTURE
[ASCIZ/OUTPUT=INPUT/]
$COPY: TRZ F,-1 ;CLEAR LOCAL FLAGS
SETZM S.ZER1 ;ZERO PER COMMAND VARIABLES
MOVE T1,[S.ZER1,,S.ZER1+1] ;SETUP FOR BLT
BLT T1,S.ZERM ;CLEAR THEM OUT
PUSHJ P,CPYSCN ;SCAN THE COPY SPEC
PUSHJ P,CPYDEF ;DEFAULT SWITCHS AFTER COPY
PUSHJ P,CPYOPN ;OPEN CHANNELS
PUSHJ P,SETHPQ ;SET HPQ IF GIVEN
PUSHJ P,SETDSK ;SET DSKPRIORITY IF GIVEN
PUSHJ P,PIINIT ;INITIALIZE PSISER
PUSHJ P,SETCHK ;SETUP FOR CHECKPOINTING
PUSHJ P,FILDAE ;SEE IF FILDAE RUNNING
PUSHJ P,CBOOTS ;COPY BOOTS BLOCKS
PUSHJ P,CFESYS ;COPY FE.SYS
PUSHJ P,CPYMFD ;PROCESS THE MFD
PUSHJ P,CPYREL ;RELEASE THE CHANNELS
PUSHJ P,TOTALS ;GIVE TOTALS
PUSHJ P,CHKFIL ;CHECK TO SEE IF FILES FOUND
PUSHJ P,PIOFF ;TURN OFF PSISER
PUSHJ P,RSTPTH ;RESTORE PATH
TLNE F,(FL.EXIT) ;EXIT WHEN DONE?
PUSHJ P,.MONRT## ;YES
PJRST .POPJ1## ;AND RETURN W/O STORE
SUBTTL CPYSCN -- SCAN THE COPY SWITCH
CPYSCN: PUSHJ P,.CLRFL## ;CLEAR FILE AREA
PUSHJ P,.FILIN## ;READ A FILE SPEC
CAIE C,"=" ;SEE IF EQUALS
JRST E$$CRO ;NO--COPY REQUIRES OUTPUT SPEC
MOVEI T1,O.SPEC ;POINT TO OUTPUT SPEC
MOVEI T2,.FXLEN ;INDICATE LENGTH
PUSHJ P,.GTSPC## ;COPY FROM SCAN
PUSHJ P,.FILIN## ;READ ANOTHER
JUMPG C,E.INCL## ;SHOULD BE <EOL> NOW
MOVEI T1,I.SPEC ;POINT TO INPUT SPEC
MOVEI T2,.FXLEN ;INDICATE LENGTH
PUSHJ P,.GTSPC## ;COPY FROM SCAN
POPJ P,
$FATAL (CRO,<COPY requires output specification>)
SETHPQ: SKIPGE T1,S.HPQ ;SEE IF HPQ GIVEN
POPJ P, ;NO--RETURN
HPQ T1, ;TRY TO SET
SKIPA ;FAILED
POPJ P, ;LOOKS GOOD
$WARN (CSH,<Cant set HPQ >,E.CSH,.POPJ##)
E.CSH: MOVE T1,S.HPQ
PJRST .TDECW##
SETDSK: SKIPGE T1,S.DSKP ;SEE IF DSKPRI GIVEN
POPJ P, ;NO--RETURN
HRLI T1,-1 ;FOR ALL OPEN CHANNELS
MOVE T2,[.DUPRI,,T1] ;FUNCTION,,ADDR
DISK. T2, ;TRY
SKIPA ;FAILED
POPJ P, ;LOOKS GOOD
$WARN (CSP,<Cant set DSKPRI >,E.CSP,.POPJ##)
E.CSP: MOVE T1,S.DSKP
PJRST .TDECW##
SUBTTL $SORT -- SCAN THE SORT SWITCH
[ASCIZ/SORT <TYPE> <KEY>/]
$SORT: JUMPLE C,SORT2 ;DEFAULT IF NO KEYWORDS
PUSHJ P,.SIXSW## ;READ A SIXBIT READ
MOVE T1,[IOWD SRT.L,SRT.T] ;POINT TO TABLE
PUSHJ P,.NAME## ;LOOK LOOK
JRST E$$USK ;UNKNOWN
SUBI T1,SRT.T-1 ;REMOVE OFFSET
TLZ T1,-1 ;KEEP RH ONLY
PUSH P,T1 ;SAVE
MOVEI T2,SRTKNAME ;DEFAULT IS /SORT::NAME
JUMPLE C,SORT1 ;YES--USE DEFAULT
PUSHJ P,.SIXSW## ;READ NEXT KEYWORD
MOVE T1,[IOWD SRTK.L,SRTK.T] ;POINT TO TABLE
PUSHJ P,.NAME## ;LOOK IN TABLE
JRST E$$USK ;UNKNOWN
SUBI T1,SRTK.T-1 ;REMOVE OFFSET
MOVEI T2,(T1) ;MOVE RH INTO T2
SORT1: POP P,T1
CAIN T1,SRTDIRECTORY-1
MOVEM T2,S.DSRT
CAIN T1,SRTFILES-1
MOVEM T2,S.FSRT
JRST .POPJ1##
SORT2: MOVEI T1,SRTKNAME ;DEFAULT /SORT::NAME
MOVEM T1,S.DSRT ;FOR /SORT:DIRECTORY
MOVEM T1,S.FSRT ;AND /SORT:FILES
JRST .POPJ1## ;AND RETURN
$FATAL (USK,<Unknown SORT keyword >,E.USK)
E.USK: MOVE T1,N
PJRST .TSIXN##
SUBTTL CPYOPN -- OPEN THE CHANNELS FOR COPY
CPYOPN: MOVEI T1,I.SPEC+.FXDEV ;GET INPUT DEVICE
MOVEI T2,I.DISK ;WHERE TO PUT DSKCHR INFO
PUSHJ P,DODSK ;DO DSKCHR
MOVEI T1,O.SPEC+.FXDEV ;GET OUTPUT DEVICE
MOVEI T2,O.DISK ;WHERE TO PUT DSKCHR INFO
PUSHJ P,DODSK ;DO DSKCHR
LDB T1,[POINTR (I.DISK+.DCUCH,DC.UCC)] ;GET INPUT BLOCKS/CLUSTER
MOVEM T1,ICLUST ;SAVE
LDB T2,[POINTR (O.DISK+.DCUCH,DC.UCC)] ;GET OUTPUT BLOCKS/CLUSTER
MOVEM T2,OCLUST ;SAVE
JUMPE T2,CPYOP2 ;NO CHECK IF NUL:
CAIE T1,(T2) ;THE SAME?
$WARN (CSD,<Cluster sizes differ; >,E.CSD)
CPYOP2: MOVX T1,.IODMP!UU.PHS ;WE USE DUMP MODE
MOVEM T1,I.OPEN+.OPMOD ;STORE FOR INPUT OPEN
MOVEM T1,O.OPEN+.OPMOD ;AND OUTPUT OPEN
SETZM I.OPEN+.OPBUF ;NO BUFFERS FOR DUMP MODE
SETZM O.OPEN+.OPBUF ;..
MOVE T1,I.SPEC+.FXDEV ;GET INPUT DEVICE
MOVEM T1,I.OPEN+.OPDEV ;TRANSFER
MOVE T1,O.SPEC+.FXDEV ;GET OUTPUT DEVICE
MOVEM T1,O.OPEN+.OPDEV ;TRANSFER
OPEN IC,I.OPEN ;OPEN THE INPUT CHANNEL
$FATAL (COI,<Can't OPEN input device >,E.COI)
OPEN OC,O.OPEN ;OPEN THE OUTPUT CHANNEL
$FATAL (COO,<Can't OPEN output device >,E.COO)
MOVE T1,SAVFF ;GET OLD CORE
MOVEM T1,.JBFF ;RESET CORE
SKIPG T1,S.BUFF ;GET BUFFER SIZE
MOVX T1,AD.BUF ;NOT GIVEN--GET DEFAULT
WRD2BK T1 ;CONVERT TO BLOCKS
CAIGE T1,NBOOTB ;SEE IF ENOUGH FOR BOOTS
MOVEI T1,NBOOTB ;NO--MAKE BIG ENOUGH
LSH T1,7 ;MAKE WORDS(MULTIPLE OF BLOCKS)
MOVEM T1,BUFSIZ ;STORE BUFFERSIZE
PUSHJ P,.GTMEM ;GET SOME CORE FOR THEM
$FATAL (NCB,<Need >,E.NCB) ;NO CORE FOR BUFFERS
MOVEM T1,BUFLOC ;SAVE ADDR OF BUFFER
SETZM NUFDS ;CLEAR COUNTS
SETZM NSFDS
SETZM NFILES
SETZM NBLKS
MOVX T1,%NSUPT ;GET UPTIME (JIFFIES)
GETTAB T1,
MOVEI T1,0
MOVEM T1,UPTIME
;GET TOTAL DISK READS/WRITES FOR INCREMENTAL REPORTING
HRROI T1,.GTRCT ;GET DISK READS
GETTAB T1, ;..
MOVEI T1,0 ;FAILED
ANDX T1,RC.TTL ;MASK TO JUST TOTAL
MOVEM T1,READS ;AND SAVE
HRROI T1,.GTWCT ;GET DISK READS
GETTAB T1, ;..
MOVEI T1,0 ;FAILED
ANDX T1,WC.TTL ;MASK TO JUST TOTAL
MOVEM T1,WRITES ;AND SAVE
POPJ P, ;RETURN
E.COI: MOVE T1,I.OPEN+.OPDEV
PJRST .TSIXN##
E.COO: MOVE T1,O.OPEN+.OPDEV
PJRST .TSIXN##
E.NCB: MOVE T1,BUFSIZ ;GET BUFFER SIZE
PUSHJ P,.TCORW## ;TYPE AS CORE WORD
MOVEI T1,[ASCIZ/ core for buffers/];GET MESSAGE
PJRST .TSTRG## ;FINISH OFF AND RETURN
E.CSD: MOVE T1,I.DISK+.DCNAM ;GET NAME
PUSHJ P,.TSIXN##
PUSHJ P,.TCOLN##
MOVE T1,ICLUST
PUSHJ P,.TDECP
MOVEI T1,[ASCIZ/ and /]
PUSHJ P,.TSTRG##
MOVE T1,O.DISK+.DCNAM
PUSHJ P,.TSIXN##
PUSHJ P,.TCOLN##
MOVE T1,OCLUST
PJRST .TDECP
SUBTTL DODSK -- ROUTINE TO PERFORM DSKCHR UUO
;CALL:
; MOVEI T1,ADDR STRNAME
; MOVEI T2,DSKCHR ARG BLOCK
DODSK: PUSHJ P,.SAVE2## ;SAVE P1,P2
MOVEI P1,(T1) ;SAVE ADDR STRNAME
MOVEI P2,(T2) ;SAVE ADDR OF DSKCHR BLOCK
MOVE T1,(P1) ;GET STRNAME
MOVEM T1,.DCNAM(T2) ;STORE STR NAME
DEVCHR T1, ;SEE IF GOOD DEVICE
JUMPE T1,E$$NSD ;JUMP IF NO SUCH DEVICE
TLC T1,-1-<(DV.TTA)> ;SEE IF NUL:
TLCN T1,-1-<(DV.TTA)> ;..
JRST [CAIN P1,O.SPEC+.FXDEV ;YES--SEE IF OUTPUT SPEC
POPJ P, ;YES--JUST RETURN
JRST E$$DND] ;NO--ERROR
HRLI T2,LN$DSK ;INDICATE LENGTH OF DSKCHR BLOCK
DSKCHR T2, ;TRY
$FATAL (DND,<Device not a disk >,E.DND)
LDB T1,[POINTR (T2,DC.TYP)] ;GET TYPE
CAIE T1,.DCTFS ;A FILE STR NAME?
$FATAL (DNF,<Device not a file structure >,E.DND)
MOVE T1,.DCSNM(P2) ;GET PHYSICAL STR NAME
MOVEM T1,(P1) ;SAVE AS USERS ARG
SKIPG S.SINGLE ;/SINGLE?
POPJ P, ;NO--RETURN
MOVX T2,.FSRDF ;GET FUNCTION
MOVEM T2,STRBLK+.FSFCN ;STORE
SETOM STRBLK+.FSRJN ;ME
SETOM STRBLK+.FSRPP ;..
MOVEM T1,STRBLK+.FSRNM ;STORE STR NAME
MOVX T1,FS.RSA ;SET SINGLE ACCESS
MOVEM T1,STRBLK+.FSRST ;STORE FLAGS
MOVE T1,[5,,STRBLK] ;POINT TO ARGS
STRUUO T1, ;TRY SINGLE ACCESS
JRST E.SUF ;CANT
$INFO (SSS,<Setting structure >,E.SSS,.POPJ##)
E.SSS: MOVE T1,(P1) ;GET STR NAME
PUSHJ P,.TSIXN## ;TYPE
MOVEI T1,[ASCIZ/ single access/];FINISH OFF
PJRST .TSTRG## ;AND RETURN
E.SUF: $WARN (CSS,<Cannot set single access for >,ESUF,.POPJ##)
ESUF: MOVE T1,(P1) ;GET STR NAME
PJRST .TSIXN## ;TYPE AND RETURN
$FATAL (NSD,<No such device >,E.DND)
E.DND: MOVE T1,.DCNAM(P2) ;GET USER ARG
PJRST .TSIXN## ;TYPE
SUBTTL FILDAE -- CHECK IF THE FILE DAEMON IS RUNNING
FILDAE: MOVX T1,%SIFDA ;GET FILDAE PID
GETTAB T1, ;FROM MONITOR
MOVEI T1,0 ;FAILED-ASSUME NOT THERE
JUMPE T1,.POPJ## ;RETURN IF NO FILDAE AROUND
$WARN (FDR,<File Daemon is running>);WARN HIM
POPJ P, ;AND RETURN
SUBTTL CPYREL -- RELEASE THE CHANNELS FOR COPY
CPYREL: RELEAS IC, ;FREE INPUT CHANNEL
RELEAS OC, ;AND OUTPUT CHANNEL
MOVE T1,SAVFF ;GET OLD CORE SIZE
PJRST .PTMEM ;RESET CORE AND RETURN
SUBTTL CBOOTS -- COPY BOOTS IN BLOCKS 4-7
CBOOTS: SKIPE OCLUST ;SKIP IF OUTPUT TO NUL:
SKIPG S.BOOTS ;COPY BOOTS?
POPJ P, ;NO
MOVEI T1,FBOOTB ;POINT TO FIRST BOOT BLOCK
MOVEI T2,NBOOTB ;SET NUMBER OF BOOT BLOCKS
PUSHJ P,BOOTB ;COPY
JRST E$$ATB ;ERROR
MOVEI T1,0 ;COPY BLOCK 0
MOVEI T2,1 ;1 BLOCK
PUSHJ P,BOOTB ;COPY
$WARN (ATB,<Aborting transfer of BOOT blocks>,,.POPJ##)
$INFO (BBC,<BOOT blocks copied>)
POPJ P, ;AND RETURN
;SUBROUTINE TO COPY BLOCKS
;CALL:
; MOVEI T1,STARTING BLOCK
; MOVEI T2,NUMBER OF BLOCKS
; PUSHJ P,BOOTB
; <ERROR> ;INPUT/OUTPUT/SUSET. FAILURE
; <NORMAL> ;BLOCKS COPIED
BOOTB: MOVEI T3,IC ;GET CHANNEL
DPB T3,[POINTR (T1,SU.SCH)] ;STORE FOR SUSET.
SUSET. T1, ;SET TO READ BOOTS
JRST E$$SUF ;FAILED!
MOVEI T3,OC ;GET CHANNEL
DPB T3,[POINTR (T1,SU.SCH)] ;STORE FOR SUSET.
TXO T1,SU.SOT ;INDICATE WRITE
SUSET. T1, ;SET TO WRITE BOOTS
JRST E$$SUF ;FAILED!
IMULI T2,200 ;MAKE WORDS
MOVNS T2 ;NEGATE
HRLZ T1,T2 ;POSITION
HRR T1,BUFLOC ;POINT TO BUFFER
SUBI T1,1 ;MAKE IOWD
MOVEI T2,0 ;CLEAR IO LIST
IN IC,T1 ;READ BOOTS
SKIPA ;GOOD!
JRST E$$IRB ;INPUT ERROR READING BOOTS
OUT OC,T1 ;WRITE BOOTS
JRST .POPJ1## ;GOOD RETURN
JRST E$$OWB ;OUTPUT ERROR WRITING BOOTS
$WARN (SUF,<SUSET. UUO failure>,,.POPJ##)
$WARN (IRB,<>,E.IRB,.POPJ##)
E.IRB: GETSTS IC,T1
PUSHJ P,.TIOER
MOVEI T1,[ASCIZ/ reading BOOT blocks/]
PJRST .TSTRG##
$WARN (OWB,<>,E.OWB,.POPJ##)
E.OWB: GETSTS OC,T1
PUSHJ P,.TIOER
MOVEI T1,[ASCIZ/ writing BOOT blocks/]
PJRST .TSTRG##
SUBTTL CFESYS -- COPY FE.SYS
CFESYS: SKIPE OCLUST ;SKIP IF OUTPUT TO NUL:
SKIPG S.FESYS ;COPY FE.SYS?
POPJ P, ;NO
TRO F,FR.FE ;FLAG COPING FE.SYS
RELEAS OC, ;RE-OPEN OUTPUT CHANNEL
MOVX T1,UU.DER ;DISABLE ERROR RETRY
IORM T1,O.OPEN+.OPMOD ;SET FOROPEN
OPEN OC,O.OPEN ;OPEN IT UP
JRST E$$COO ;FAILED??
MOVE T1,SYSPPN ;GET SYS: PPN
MOVEM T1,I.PATH+.PTPPN ;SET
SETZM I.PATH+.PTPPN+1 ;INSURE NO SFD'S
MOVEI DP,[SIXBIT/FE/ ;SETUP FILENAME
SIXBIT/SYS/] ;AND EXTENSION
PUSHJ P,CPYFIL ;COPY THE FILE
JRST E%ACF ;ERROR
PUSHJ P,FERIB ;FIX FE.SYS RIB
JRST E$$ACF ;FAILED
MOVEI T1,LBNHM1 ;GET 1ST HOME BLOCK
PUSHJ P,FEHOME ;PUT IN HOME BLOCK
JRST E$$ACF ;FAILED
MOVEI T1,LBNHM2 ;GET 2ND HOME BLOCK
PUSHJ P,FEHOME ;PUT IN HOME BLOCK
JRST E$$ACF ;FAILED
$INFO (FEC,<Front end file FE.SYS copied>)
FEDONE: TRZ F,FR.FE ;FLAG DONE WITH FRE.SYS
RELEAS OC, ;RE-OPEN CHANNEL
MOVX T1,UU.DER ;ENABLING ERROR RETRY
ANDCAM T1,O.OPEN+.OPMOD ;..
OPEN OC,O.OPEN ;OPEN CHANNEL AGAIN
JRST E$$COO ;FAIILED??
POPJ P, ;AND RETURN
E%ACF: TRNE F,FR.FE ;FILE NOT FOUND?(FR.FE FLAG)
$WARN (ACF,<Aborting copying of front end file>)
JRST FEDONE
SUBTTL FE ROUTINES -- FIX RIB
FERIB: LOOKUP OC,I.LOOK ;LOOKUP FILE
POPJ P, ;SHOULD NEVER HAPPEN
USETI OC,0 ;READ THE PRIME RIB
IN OC,BLKIO
SKIPA
HALT
CLOSE OC,CL.ACS!CL.DAT
MOVX T1,RP.NDL!RP.NFS!RP.ABC
IORM T1,BLK+.RBSTS
MOVE T1,BLK+.RBSLF ;GET RIB POSITION
MOVEI T3,OC ;GET CHANNEL
DPB T3,[POINTR (T1,SU.SCH)] ;STORE
TXO T1,SU.SOT ;INDICATE WRITE
SUSET. T1, ;SET TO WRITE
JRST E$$SUF ;FAILED
OUT OC,BLKIO ;WRITE IT
SKIPA
HALT
JRST .POPJ1##
SUBTTL FE ROUTINES -- FIX HOME BLOCKS
;CALL: MOVEI T1,HOME BLOCK NUMBER
; PUSHJ P,FEHOME
; <ERROR>
; <NORMAL>
FEHOME: PUSHJ P,.SAVE1## ;SAVE P1
MOVEI P1,(T1) ;GET BLOCK NUMBER
MOVEI T1,OC ;GET CHANNEL
DPB T1,[POINTR (P1,SU.SCH)] ;STORE FOR SUSET.
SUSET. P1, ;SETUP TO READ HOME BLOCKS
JRST E$$SUF ;FAILED!
IN OC,BLKIO ;READ HOME BLOCK
SKIPA ;GOOD!
JRST E$$IHB ;INPUT ERROR READING HOME BLOCKS
PUSHJ P,HOMCHK ;CHECK HOME BLOCKS
POPJ P, ;CONSISTENCY FAILURE
MOVE T3,FEPOS ;GET FE.SYS POSTION
ADDI T3,1 ;JUST PAST RIB
PUSHJ P,SPLTWO ;MAKE INTO 11 FORMAT
TXO T3,HM$VAL ;SAY ITS VALID
MOVEM T3,HOMFEA+BLK ;STORE FOR 11
WRD2BK T3,I.LOOK+.RBSIZ ;GET FILE SIZE IN BLOCKS
PUSHJ P,SPLTWO ;MAKE INTO 11 FORMAT
MOVEM T3,HOMFES+BLK ;STORE
TXO P1,SU.SOT ;SET TO WRITE
SUSET. P1, ;SHOOT
JRST E$$SUF ;FAILED
OUT OC,BLKIO ;WRITE BLOCKS
JRST .POPJ1## ;GOOD!
$WARN (OHB,<>,E.OHB,.POPJ##)
E.OHB: GETSTS OC,T1
PUSHJ P,.TIOER
MOVEI T1,[ASCIZ/ writing HOME blocks/]
PJRST .TSTRG##
$WARN (IHB,<>,E.IHB,.POPJ##)
E.IHB: GETSTS OC,T1
PUSHJ P,.TIOER
MOVEI T1,[ASCIZ/ reading HOME blocks/]
PJRST .TSTRG##
;ROUTINE TO SPLIT UP 36 BIT -10 WORD INTO TWO 16 BIT QUANTITIES, IN
; HALF WORDS
SPLTWO: LDB T4,[POINT 16,T3,35-16] ;GET SECOND 16 BITS
ANDI T3,177777 ;MASK OFF ALL BUT FIRST 16 BITS
HRL T3,T4 ;MAKE HALF-WORDS SO -11 CAN SEE ALL
POPJ P, ;RETURN
SUBTTL HOME ROUTINES -- CHECK THE HOME BLOCK
HOMCHK: MOVE T3,HOMNAM+BLK
CAME T3,[SIXBIT/HOM/]
$WARN (HBC,<HOME block consistency failure>,,.POPJ##)
MOVE T1,HOMCOD+BLK
CAIE T1,CODHOM
JRST E$$HBC
JRST .POPJ1##
SUBTTL CPYMFD -- PROCESS THE MFD
CPYMFD: MOVE T1,MFDPPN ;GET MFD PPN
MOVEM T1,I.LOOK+.RBNAM ;SAVE AS FILENAME
MOVEM T1,I.PATH+.PTPPN ;STORE PATH
SETZM I.PATH+.PTPPN+1 ;INSURE END
MOVSI T1,'UFD' ;GET UFD EXTENSION
MOVEM T1,I.LOOK+.RBEXT ;SET
MOVEI T1,I.PATH ;POINT TO PATH
MOVEM T1,I.LOOK+.RBPPN ;RESET
MOVEI T1,LN$LEN-1 ;GET LENGTH OF LOOKUP
MOVEM T1,I.LOOK+.RBCNT ;SET
PUSHJ P,GETDIR ;LOOKUP AND READ DIRECTORY
POPJ P, ;LOOKUP OR INPUT ERROR
SKIPN MP,T1 ;GET AOBJN POINTER TO UFD LIST
POPJ P, ;EMPTY--RETURN NOW
MFDLOP: PUSHJ P,CPYUFD ;COPY THE UFD
AOBJN MP,.+1 ;ADVANCE
AOBJN MP,MFDLOP ;LOOP FOR ALL ENTRIES IN MFD
POPJ P, ;AND RETURN
SUBTTL CPYUFD -- PROCESS A UFD
CPYUFD: MOVE T1,[I.LOOK,,I.LOOK+1] ;SET UP BLT
SETZM I.LOOK ;CLEAR FIRST WORD
BLT T1,I.LOOK+LN$LEN-1 ;CLEAR BLOCK
SKIPN T1,S.INIT+.FXDIR ;GET PPN
JRST CPYUF1 ;NO /INITIAL--GO
CAME T1,(MP) ;MATCH CURRENT PPN?
POPJ P, ;NO--RETURN
SETZM S.INIT+.FXDIR ;YES--RESET
CPYUF1: SKIPN T1,(MP) ;GET PPN
POPJ P, ;THAT WAS EASY!
CAMN T1,MFDPPN ;THE MFD?
POPJ P, ;YES--SKIP THAT
MOVEM T1,I.LOOK+.RBNAM ;STORE
XOR T1,.FXDIR+I.SPEC ;COMPARE PPNS
TDNE T1,.FXDIM+I.SPEC ;CLEAR WILDCARDS
POPJ P, ;DIDNT MATCH
SKIPN T1,.FXDIR+S.EXCLUDE ;GET DIRECTORY
JRST CPYU.1 ;NO /EXCLUDE
XOR T1,I.LOOK+.RBNAM ;COMPARE
TDNN T1,.FXDIM+S.EXCLUDE ;SEE IF MATCH
POPJ P, ;YES--RETURN
CPYU.1: MOVE T1,MFDPPN ;GET MFDPPN
MOVEM T1,I.PATH+.PTPPN ;SET PATH
SETZM I.PATH+.PTPPN+1 ;INSURE END
MOVSI T1,'UFD' ;GET UFD EXTENSION
MOVEM T1,I.LOOK+.RBEXT ;STORE
MOVEI T1,I.PATH ;GET PATH
MOVEM T1,I.LOOK+.RBPPN ;RESET
MOVEI T1,LN$LEN-1 ;GET LENGTH OF LOOKUP
MOVEM T1,I.LOOK+.RBCNT ;STORE
PUSH P,.JBFF ;SAVE CURRENT CORE SIZE
PUSHJ P,GETDIR ;READ THE DIRECORY
JRST UFDEND ;LOOKUP/INPUT ERROR
MOVE DP,T1 ;GET AOBJN POINTER TO FILENAMES
PUSHJ P,MAKDIR ;ENTER NEW DIRECTORY
JRST UFDEND ;FAILED
AOS NUFDS ;COUNT UFDS
JUMPE DP,UFDEND ;IF EMPTY, NOTHING TO DO
MOVE T1,I.LOOK+.RBNAM ;GET UFD NAME
MOVEM T1,I.PATH+.PTPPN ;STORE FOR PATH
SETZB L,I.PATH+.PTPPN+1 ;START AT LEVEL 0, CLEAR PATH
PUSHJ P,SETPTH ;SET DIRECTORY PATH FOR SPEED
UFDLOP: PUSHJ P,CPYFIL ;COPY FILE
JFCL ;ERROR--INGORE
AOBJN DP,.+1 ;ADVANCE
AOBJN DP,UFDLOP ;LOOP FOR ALL
UFDEND: POP P,.JBFF ;RESTORE CORE SIZE
POPJ P, ;AND RETURN
SUBTTL CPYFIL -- PROCESS A FILE
CPYFIL: PUSHJ P,.SAVE4##
MOVE T1,S.RETRY ;GET RETRY COUNTER
MOVEM T1,NRETRY ;RESET
CPYAGN: MOVE T1,[I.LOOK,,I.LOOK+1] ;SET UP BLT
SETZM I.LOOK ;CLEAR FIRST WORD
BLT T1,I.LOOK+LN$LEN-1 ;CLEAR BLOCK
SETZM CURBLK ;CLEAR BLOCK COUNT
SKIPN T1,(DP) ;GET FILENAME
JRST .POPJ1## ;ALL DONE
MOVEM T1,I.LOOK+.RBNAM ;STORE NAME
HLRZ T1,1(DP) ;GET EXTENSION
HRLZM T1,I.LOOK+.RBEXT ;STORE EXTENSION
MOVEI T2,I.PATH ;POINT TO PATH
MOVEM T2,I.LOOK+.RBPPN ;STORE POINTER
CAIN T1,'SFD' ;SEE IF SFD
JRST CPYSFD ;YES--HANDLE DIFFERENTLY
MOVEI T1,LN$LEN-1 ;GET LENGTH OF LOOKUP
MOVEM T1,I.LOOK+.RBCNT ;SET
LOOKUP IC,I.LOOK ;LOOKUP FILE
JRST CPYLOK ;HANDLE LOOKUP ERROR
PUSHJ P,CHKOPR ;SEE IF ANY COMMANDS
PUSHJ P,CHKTST ;CHECK /SINCE/BEFORE, ETC.
JRST CPYSKP ;NO--SKIP THE COPY
PUSHJ P,CHKSUP ;CHECK /SUPERSEDE: ARG
JRST CPYSKP ;NO--SKIP THE COPY
TRNN F,FR.FE ;SKIP IF DOING FE.SYS
PUSHJ P,LSTFIL ;LIST FILE
MOVE T1,[I.LOOK,,O.ENTER] ;START AT .RBCNT
BLT T1,O.ENTER+LN$LEN-1 ;BLT LOOKUP BLOCK
SETZM O.ENTER+.RBDEV ;CLEAR DEVICE
SETZM O.ENTER+.RBPOS ;CLEAR POSITION TO ALLOCATE
SETZM O.ENTER+.RBSTS ;CLEAR STATUS
SETZM O.ENTER+.RBXRA ;CLEAR NEXT RIB ADDR
PUSHJ P,GETALC ;GET FILE ALLOCATION
JRST CPYIER ;INPUT READ ERROR (FE.SYS RIB)
LDB T1,[POINTR (I.LOOK+.RBPRV,RB.MOD)];GET FILE MODE
SETSTS OC,(T1) ;FOOL FILSER
ENTER OC,O.ENTER ;ENTER THE OUTPUT FILE
JRST CPYENT ;HANDLE ENTER ERROR
SETSTS OC,.IODMP ;BACK TO DUMP MODE FOR TRANSFERS
MOVE P2,I.LOOK+.RBSIZ ;GET INPUT SIZE
MOVEI P4,0 ;CLEAR IOWD LIST
CPYLOP: JUMPLE P2,CPYEND ;JUMP IF ALL DONE
CAMG P2,BUFSIZ ;TOO BIG FOR BUFFER?
SKIPA P3,P2 ;NO--USE WHATS LEFT
MOVE P3,BUFSIZ ;YES--JUST USE BUFSIZ
MOVNS P3 ;MAKE IOWD
HRLZS P3 ;..
HRR P3,BUFLOC ;GET ADDR OF BUFFERS
SUBI P3,1 ;MINUS 1
IN IC,P3 ;READ THE BUFFER
SKIPA ;OK
JRST CPYIER ;INPUT ERROR
CAMG P2,BUFSIZ
SKIPA T1,P2
WRD2BK T1,BUFSIZ ;CONVERT BUFSIZ TO BLOCKS
ADDM T1,CURBLK ;ADVANCE BLOCK COUNTER
OUT OC,P3 ;WRITE THE BUFFER
SKIPA ;OK
JRST CPYOER ;OUTPUT ERROR
SUB P2,BUFSIZ ;SUBTRACT WHAT WE DID
TRZE F,FR.ABORT ;ABORTED?
JRST CPYABT ;YES
PUSHJ P,CHKOPR ;SEE IF ANY COMMANDS
JRST CPYLOP
CPYEND: CLOSE IC,CL.ACS!CL.DAT ;CLOSE INPUT FILE
CLOSE OC,CL.ACS!CL.DAT!CL.DLL ;CLOSE OUTPUT FILE
GETSTS OC,P1 ;GET STATUS
TXNE P1,IO.ERR ;ANY ERRORS?
JRST CPYCLS ;CLOSE ERROR
AOS NFILES ;COUNT FILES
WRD2BK T1,I.LOOK+.RBSIZ ;GET FILE SIZE
ADDM T1,NBLKS ;AND KEEP TOTALS
JRST .POPJ1## ;RETURN
CPYSKP: CLOSE IC,CL.ACS!CL.DAT ;CLOSE INPUT FILE
JRST .POPJ1## ;AND RETURN
CPYCLS: PUSHJ P,E$$OCE ;ISSUE CLOSE ERROR
JRST CPYTRY ;AND DO A RETRY
CPYLOK: HRRZ T1,I.LOOK+.RBEXT ;GET ERROR CODE
TRZE F,FR.FE ;DOING FE.SYS?
JUMPE T1,.POPJ## ;YES--RETURN IF FILE NOT FOUND
PUSHJ P,E$$ILE ;ISSUE LOOKUP ERROR
PJRST E$$ATF ;ABORT FILE MESSAGE AND RETURN
CPYENT: SETSTS OC,.IODMP ;BACK TO DUMP MODE
CLOSE IC,CL.ACS!CL.DAT ;CLOSE INPUT CHANNEL
PUSHJ P,E$$OEE ;ISSUE ENTER ERROR
PUSHJ P,E$$ATF ;ABORT FILE MESSAGE
HRRZ T1,O.ENTER+.RBEXT ;GET ENTER ERROR
CAIE T1,ERNRM% ;NO MORE ROOM?
POPJ P, ;NO--RETURN
PJRST CHKSTR ;YES--CHECK STR QUOTAS
CPYIER: GETSTS IC,P1 ;GET STATUS
PUSHJ P,E$$IRE ;ISSUE INPUT READ ERROR
CLOSE IC,CL.ACS!CL.DAT ;CLOSE INPUT FILE
CLOSE OC,CL.RST!CL.DAT ;CLOSE AND ABORT OUTPUT FILE
PJRST E$$ATF ;ABORT FILE MESSAGE AND RETURN
CPYOER: GETSTS OC,P1 ;GET STATUS
PUSHJ P,E$$OWE ;ISSUE OUTPUT ERROR
CLOSE IC,CL.ACS ;CLOSE INPUT FILE
CLOSE OC,CL.RST ;CLOSE AND ABORT OUTPUT FILE
TXNE P1,IO.BKT ;QUOTA EXCEEDED?
JRST [PUSHJ P,CHKSTR ;YES--CHECK STR QUOTAS
JRST E$$ATF] ;AND ABORT TRANSFER OF FILE
JRST CPYTRY ;NO--TRY AGAIN
CPYTRY: SOSG NRETRY ;COUNT RETRIES
PJRST E$$ATF ;TOO MANY--ABORT FILE AND RETURN
$INFO (RCF,<Retrying copying file >,E.RCF,CPYAGN)
E.RCF: MOVEI T1,I.OPEN ;POINT TO OPEN BLOCK
MOVEI T2,I.LOOK ;POINT TO LOOKUP BLOCK
PJRST .TOLEB## ;TYPE AND RETURN
CPYABT: CLOSE IC,CL.ACS!CL.DAT ;CLOSE INPUT FILE
CLOSE OC,CL.RST!CL.DAT ;CLOSE AND DELETE OUTPUT FILE
PJRST E$$ATF ;ISSUE ABORT FILE ERROR AND RETURN
SUBTTL CHKTST -- SEE IF WE SHOULD COPY THE FILE
CHKTST: TRNE F,FR.FE ;SEE IF FE.SYS
JRST .POPJ1## ;YES--ALWAYS WINS
MOVE T1,I.LOOK+.RBSTS ;GET FILE STATUS
TXNE T1,RP.NFS ;SEE IF NEVER FAILSAFE (FSCOPY?)
POPJ P, ;YES--REJECT
SKIPGE I.SPEC+.FXSNC ;SEE IF /SINCE
SKIPL I.SPEC+.FXBFR ;OR /BEFORE
SKIPA ;YES
JRST CHKT.1 ;NO--SAVE SOME DATE CONVERSION
MOVE T2,I.LOOK+.RBPRV ;GET CREATION DATE/TIME
LDB T3,[POINTR (I.LOOK+.RBEXT,RB.CRX)] ;GET HIGH CREATION DATE
LSH T3,WID(RB.CRD) ;POSITION OVER
LDB T1,[POINTR (T2,RB.CRT)] ;GET CREATION TIME
IMULI T1,^D60000 ;CONVERT TO MILLISECONDS
ANDX T2,RB.CRD ;MASK DATE
ADD T2,T3 ;COMBINE WITH DATE EXTENSION
PUSHJ P,.CNVDT## ;CONVERT TO INTERNAL FORMAT
SKIPLE I.SPEC+.FXBFR ;SEE IF /BEFORE
CAMG T1,I.SPEC+.FXBFR ;YES--SEE IF TOO YOUNG
CAMGE T1,I.SPEC+.FXSNC ;SEE IF TOO OLD
POPJ P, ;NO--REJECT
CHKT.1: SKIPGE I.SPEC+.FXASN ;SEE IF /ASINCE
SKIPL I.SPEC+.FXABF ;SEE IF /ABEFORE
SKIPA ;YES
JRST CHKT.2 ;NO--SAVE SOME DATE CONVERSION
LDB T2,[POINTR (I.LOOK+.RBEXT,RB.ACD)] ;GET ACCESS DATE
MOVEI T1,0 ;CLEAR TIME
PUSHJ P,.CNVDT## ;CONVERT TO INTERNAL FORMAT
SKIPLE I.SPEC+.FXABF ;SEE IF /ABEFORE
CAMG T1,I.SPEC+.FXABF ;YES--SEE IF TOO YOUNG
CAMGE T1,I.SPEC+.FXASN ;SEE IF TOO OLD
POPJ P, ;NO--REJECT
CHKT.2: MOVE T1,I.LOOK+.RBTIM ;GET INTERNAL DATE
SKIPLE S.MBFR ;SEE IF /MBEFORE
CAMG T1,S.MBFR ;YES--SEE IF TOO YOUNG
CAMGE T1,S.MSNC ;SEE IF TOO OLD
POPJ P, ;NO--REJECT
JRST .POPJ1## ;WINS!
SUBTTL CHKSUP -- See if you should SUPERSEDE the output file
CHKSUP: PUSHJ P,.SAVE1## ;SAVE P1
MOVE P1,S.SUPER ;GET /SUPERSEDE
CAIN P1,SUPALWAYS ;SEE IF /SUPERSEDE:ALWAYS
JRST .POPJ1## ;YES
MOVE T1,[I.LOOK,,O.ENTER] ;BLT LOOKUP BLOCK
BLT T1,O.ENTER+LN$LEN-1 ;..
LOOKUP OC,O.ENTER ;LOOKUP OUTPUT FILE
JRST .POPJ1## ;FAILED--ASSUME SUPERSEDE
CAIN P1,SUPNEVER ;SEE IF /SUPERSEDE:NEVER
JRST CHKS.1 ;YES--DONT SUPERSEDE
MOVEI T1,O.ENTER ;POINT TO LOOKUP BLOCK
PUSHJ P,GETDAT ;CONVERT
PUSH P,T1 ;SAVE
MOVEI T1,I.LOOK ;POINT TO LOOKUP BLOCK
PUSHJ P,GETDAT ;CONVERT
POP P,T2 ;GET NEW DATE
CAMG T2,T1 ;OUTPUT NEWER?
AOS (P) ;NO--SUPERSEDE
CHKS.1: CLOSE OC,CL.ACS!CL.NMB ;CLOSE FILE
POPJ P, ;AND RETURN
GETDAT: MOVEI T4,(T1) ;SAVE ADDR BLOCK
MOVE T2,.RBPRV(T4) ;GET CREATION DATE/TIME
LDB T3,[POINTR (.RBEXT(T4),RB.CRX)] ;GET HIGH CREATION DATE
LSH T3,WID(RB.CRD) ;POSITION OVER
LDB T1,[POINTR (T2,RB.CRT)] ;GET CREATION TIME
IMULI T1,^D60000 ;MAKE MILLSECONDS
ANDX T2,RB.CRD ;MASK DATE
ADD T2,T3 ;CONBINE WITH DATE EXTENSION
PJRST .CNVDT## ;CONVERT TO INTERNAL FORMAT
SUBTTL GETALC -- Routine to set .RBEST, .RBALC, .RBPOS
;This routine computes the estimated file size based on the input
;and output cluster sizes, and the input file size. If the output
;cluster size is greater than the input cluster size, the input
;.RBALC (allocated) is used as .RBEST (estimated) for output. If the
;input cluster size is greater than the output cluster size, we
;determine if the input file is really allocated for more than it is
;written, or if the larger allocation is just due to the rounding
;involved with ribs, and cluster sizes. If the file is not over
;allocated, its written size (rounded) is used as .RBEST (estimated)
;for the output file. If the file is over allocated, the input .RBALC
;(allocated) is used as .RBEST (estimated) for output.
;However, if we are copying FE.SYS we must allocate it contigiously,
;and in the same position as the input FE.SYS
GETALC: TRNE F,FR.FE ;DOING FE.SYS?
JRST GETA.1 ;YES
MOVE T1,I.LOOK+.RBALC ;GET ALLOCATED SIZE
MOVE T2,ICLUST ;GET INPUT CLUSTER SIZE
CAMG T2,OCLUST ;BIGGER THAN OUTPUT CLUSTER?
JRST GETA.2 ;NO--USE INPUT ALOOCATED
WRD2BK T3,I.LOOK+.RBSIZ ;GET INPUT FILE SIZE
ADDI T3,NM$RIB ;ACCOUNT FOR RIBS
PUSH P,T3 ;SAVE SIZE
ADDI T3,-1(T2) ;ROUND UP TO CLUSTER SIZE
IDIVI T3,(T2) ;TO INPUT CLUSTER SIZE
IMULI T3,(T2) ;..
CAMG T1,T3 ;EXTRA ALLOCATION?
MOVE T1,(P) ;NO--USE JUST ROUNDED WRITTEN
POP P,T3 ;FIX STACK
GETA.2: MOVEM T1,O.ENTER+.RBEST ;STORE AS ESTIMATED
SETZM O.ENTER+.RBALC ;CLEAR ALLOCATED
JRST .POPJ1## ;GOOD RETURN
GETA.1: SETZM O.ENTER+.RBEST ;CLEAR EST SO ALC USED
USETI IC,0 ;SET TO READ PRIME RIB
IN IC,BLKIO ;READ IT
SKIPA ;OK
POPJ P, ;INPUT READ ERROR
MOVE T1,BLK+.RBSLF ;GET SELF BLOCK
MOVEM T1,FEPOS ;SAVE FOR LATER
MOVEM T1,O.ENTER+.RBPOS ;AND SET FOR ENTER
JRST .POPJ1## ;GOOD RETURN
CHKSTR: MOVE T1,[LN$DSK,,O.DISK] ;DO DSKCHR ON OUTPUT STR
DSKCHR T1, ;..
POPJ P, ;
SKIPL O.DISK+.DCFCT ;FILE STRF FULL?
POPJ P, ;NO
$FATAL (FSF,<File structure >,E.FSF)
E.FSF: MOVE T1,O.OPEN+.OPDEV ;GET DEVICE
PUSHJ P,.TSIXN## ;TYPE
MOVEI T1,[ASCIZ/ is full/]
PJRST .TSTRG##
SUBTTL CPYSFD -- PROCESS AN SFD
CPYSFD: SETZM I.PATH+.PTPPN+1(L) ;INSURE END OF PATH
PUSH P,.JBFF ;SAVE .JBFF
PUSHJ P,GETDIR ;READ DIRECTORY
JRST SFDEND ;LOOKUP/INPUT ERROR
PUSH P,DP ;SAVE OLD DIRECTORY POINTER
MOVE DP,T1 ;GET NEW DIRECTORY POINTER
PUSHJ P,MAKDIR ;CREATE SFD
JRST SFDEN1 ;ERROR
AOS NSFDS ;COUNT SFDS
JUMPE DP,SFDEN1 ;ALL DONE IF NULL SFD
ADDI L,1 ;ADVANCE INTO SFD NESTING
MOVE T1,I.LOOK+.RBNAM ;GET SFD NAME
MOVEM T1,I.PATH+.PTPPN(L) ;SAVE
SETZM I.PATH+.PTPPN+1(L) ;INSURE END OF PATH
PUSHJ P,SETPTH ;SET DIRECTORY PATH FOR SPEED
SFDLOP: PUSHJ P,CPYFIL ;COPY FILE
JFCL ;ERROR--INGORE
AOBJN DP,.+1 ;ADVANCE
AOBJN DP,SFDLOP ;LOOP FOR ALL FILES
SUBI L,1 ;BACK UP TREE
SETZM I.PATH+.PTPPN+1(L) ;INSURE END OF PATH
SFDEN1: POP P,DP ;RESTORE OLD DIRECTORY POINTER
SFDEND: POP P,.JBFF ;RESTORE .JBFF
PJRST .POPJ1## ;AND RETURN
SUBTTL GETDIR -- LOOKUP AND READ DIRECTORY INTO CORE
;THIS ROUTINE LOOKS UP THE DIRECTORY (I.LOOK BLOCK ALREADY SET UP)
;IT READS IT INTO CORE WITH ONE DUMP IOWD, AND RETURNS AN AOBJN POINTER
;TO THE DIRECTORY IN T1. IF THIS IS ZERO, THE DIRECTORY IS EMPTY.
;CALL:
; PUSHJ P,GETDIR
; <ERROR> ;LOOKUP FAILURE OR INPUT READ ERROR
; <RETURN> ;T1=AOBJN POINTER
GETDIR: PUSHJ P,.SAVE1## ;SAVE P1
MOVEI T1,LN$LEN-1 ;GET LOOKUP LENGTH
MOVEM T1,I.LOOK+.RBCNT ;SET
LOOKUP IC,I.LOOK ;LOOKUP THE DIRECTORY
JRST D$ILE ;PROCESS LOOKUP ERROR
SKIPN T1,I.LOOK+.RBSIZ ;GET SIZE OF DIRECTORY
JRST GETDR2 ;EMPTY--CLOSE AND RETURN
PUSHJ P,.GTMEM ;GET SOME CORE
JRST E$$NCD ;NO CORE FOR DIRECTORY
MOVN T2,I.LOOK+.RBSIZ ;GET SIZE IN WORDS
HRLZS T2 ;MAKE IOWD
HRRI T2,-1(T1) ;POINT TO FREE CORE
MOVEI T1,0 ;CLEAR IOWD LIST
EXCH T1,T2 ;REPOSITION ARGUMENTS
INPUT IC,T1 ;READ THE UFD
ADDI T1,1 ;MAKE INTO AOBJN FROM IOWD
PUSH P,T1 ;SAVE AOBJN
MOVE T2,S.FSRT ;GET /SORT:FILES
MOVE T3,I.LOOK+.RBNAM ;GET DIRECTORY NAME
CAMN T3,MFDPPN ;SEE IF [1,1]
MOVE T2,S.DSRT ;YES--USE /SORT:DIRECTORY
PUSHJ P,.SORT2 ;SORT THE GUY
; $WARN (NCS,<No core for directory sort>)
POP P,T1 ;RESTORE T1
GETDR2: CLOSE IC,CL.ACS ;AND CLOSE IT
GETSTS IC,P1 ;GET CHANNEL STATUS
TXNE P1,IO.ERR ;ANY ERRORS?
PUSHJ P,E$$IRE ;YES--REPORT THEM
JRST .POPJ1## ;NO--LOOKS GOOD
D$ILE: PUSHJ P,E$$ILE
PJRST E$$ATD
$WARN (NCD,<No core for directory>,,E$$ATD)
$WARN (ATD,<Aborting transfer of directory >,E.ATD,.POPJ##)
E.ATD: MOVE T1,I.OPEN+.OPDEV ;GET DEVICE
PUSHJ P,.TSIXN## ;TYPE
PUSHJ P,.TCOLN## ;TYPE COLON
MOVE T1,I.LOOK+.RBNAM ;GET DIRECTORY NAME
HLRZ T2,I.LOOK+.RBEXT ;GET UFD/SFD
CAIN T2,'UFD' ;UFD?
PJRST .TPPNW## ;YES--TYPE AS PPN
MOVE T2,[I.PATH,,E.PATH] ;COPY CURRENT PATH
BLT T2,E.PATH+.PTMAX ;CLEAR OUT
MOVEM T1,E.PATH+.PTPPN+1(L) ;STORE SFD NAME
SETZM E.PATH+.PTPPN+2(L) ;INSURE END
MOVEI T1,[E.PATH] ;POINT TO PATH
PJRST .TDIRB## ;TYPE SPEC
SUBTTL SETPTH -- SET DEFAULT DIRECTORY PATH
SETPTH: MOVX T1,.PTFSD ;DEFINE DEFAULT PATH
MOVEM T1,I.PATH+.PTFCN
SETZM I.PATH+.PTSWT
MOVE T1,[2+.FXLND,,I.PATH]
PATH. T1,
JFCL
POPJ P,
RSTPTH: MOVX T1,.PTFSD ;DEFINE PATH
MOVEM T1,SVPATH+.PTFCN ;STORE
MOVE T1,[.PTMAX,,SVPATH] ;POINT TO BLOCK
PATH. T1, ;RESTORE PATH
JFCL ;PROBABLY NEVER CHANGED
POPJ P, ;AND RETURN
SUBTTL MAKDIR -- CREATE A DIRECTORY
MAKDIR: MOVE T1,[I.LOOK,,O.ENTER] ;GET LOOKUP BLOCK
BLT T1,O.ENTER+LN$LEN-1 ;BLT ACROSS
SETZM O.ENTER+.RBDEV ;CLEAR DEVICE
SETZM O.ENTER+.RBPOS ;AND POSITION
MOVE T1,O.ENTER+.RBALC ;GET ALOOCATED
MOVEM T1,O.ENTER+.RBEST ;STORE
SETZM O.ENTER+.RBALC ;CLEAR ALLOCATED
SETZM O.ENTER+.RBUSD ;CLEAR USED
MOVX T1,RP.DIR!RP.ABC ;GET DIRECTORY BITS
MOVEM T1,O.ENTER+.RBSTS ;SET
ENTER OC,O.ENTER ;ENTER FILE
JRST DERR ;SOME ERROR
USETO OC,2 ;WRITE A BLOCK
MOVX T1,CL.ACS ;GET CLOSE BITS
SKIPE S.ALLOCATE ;/ALLOCATE?
TXO T1,CL.DLL ;YES--KEEP EXTRA SPACE
CLOSE OC,(T1) ;CLOSE FILE
JRST .POPJ1## ;AND RETURN
DERR: HRRZ T1,O.ENTER+.RBEXT ;GET ERROR CODE
CAIE T1,ERCSD% ;SEE IF CANT SIPERCEED DIRECTORY
CAIN T1,ERPRT% ;SEE IF PROTECTION FAILURE
JRST .POPJ1## ;YES--THATS OK
PUSHJ P,E$$OEE ;ISSUE ENTER ERROR
PJRST E$$ATD ;GIVE ABORT ERROR AND RETURN
SUBTTL LSTFIL -- LIST A FILE SPEC
LSTFIL: MOVE T1,S.LEVEL ;GET LEVEL
CAIN T1,%SILENCE ;SEE IF SILENCE
POPJ P, ;YES--DO NOTHING
MOVSI T2,-2-.FXLND ;GET PATH POINTER
LSTCHK: MOVE T3,I.PATH(T2) ;GET CURRENT PATH
CAME T3,C.PATH(T2) ;SEE IF SAME
JRST LSTNEW ;NO--NEW PATH
AOBJN T2,LSTCHK ;LOOP FOR ALL
JRST LSTIT
LSTNEW: MOVE T1,[I.PATH,,C.PATH] ;GET PATH
BLT T1,C.PATH+1+.FXLND ;COPY
MOVEI T1,C.PATH+.PTPPN
TLO T1,1
PUSHJ P,.TDIRB##
PUSHJ P,.TCRLF##
LSTIT: MOVE T1,S.LEVEL
CAIN T1,%DIRECT
POPJ P,
MOVE T1,I.LOOK+.RBNAM
PUSHJ P,.TSIXN##
MOVEI T1,"."
PUSHJ P,.TCHAR##
HLLZ T1,I.LOOK+.RBEXT
PUSHJ P,.TSIXN##
PJRST .TCRLF##
SUBTTL CHKFIL -- SEE IF FILES COPIED
CHKFIL: MOVX T1,FX.NOM ;GET /ER[OR]NONE
TDNE T1,.FXMOD+I.SPEC ;SEE IF GIVEN
POPJ P, ;YES--OK
SKIPN NUFDS ;SEE IF ANY UFDS
$WARN (NUF,<No UFDs found to match >,E.NUF,.POPJ##)
SKIPN NFILES ;SEE IF ANY FILES
$WARN (NFF,<No files found to match >,E.NFF,.POPJ##)
POPJ P, ;RETURN
E.NUF: MOVE T1,I.SPEC+.FXDEV ;GET INPUT DEVICE
PUSHJ P,.TDEVN## ;TYPE
MOVEI T1,I.SPEC+.FXDIR ;POINT TO PPN
TLO T1,2 ;INDICATE BIWORDS
PUSHJ P,.TDIRB## ;TYPE
MOVEI T1,[ASCIZ/.UFD/] ;FINISH OFF
PJRST .TSTRG## ;TYPE AND RETURN
E.NFF: MOVE T1,I.SPEC+.FXDEV ;GET INPUT DEVICE
PUSHJ P,.TDEVN## ;TYPE
MOVEI T1,[ASCIZ/*.*/] ;LOAD FULL WILD
PUSHJ P,.TSTRG## ;TYPE
MOVEI T1,I.SPEC+.FXDIR ;POINT TO PPN
TLO T1,2 ;INDICATE BIWORDS
PJRST .TDIRB## ;TYPE AND RETURN
SUBTTL ERRORS
$WARN (IRE,<>,E.IRE,.POPJ##) ;ISSUE INPUT READ ERROR
E.IRE: MOVE T1,[I.OPEN,,I.LOOK] ;POINT TO BLOCK
MOVE T2,P1 ;GET ERROR BITS
PJRST .TIERR ;ISSUE MESSAGE
$WARN (OWE,<>,E.OWE,.POPJ##) ;ISSUE OUTPUT WRITE ERROR
E.OWE: MOVE T1,[O.OPEN,,O.ENTER] ;POINT TO BLOCK
MOVE T2,P1 ;GET ERROR BITS
PJRST .TOERR ;ISSUE MESSAGE
$WARN (OCE,<>,E.OCE,.POPJ##) ;ISSUE OUTPUT CLOSE ERROR
E.OCE: MOVE T1,[O.OPEN,,O.ENTER] ;POINT TO BLOCK
MOVE T2,P1 ;GET ERROR BITS
PJRST .TCERR ;ISSUE MESSAGE
$WARN (ILE,<>,E.ILE,.POPJ##) ;ISSUE INPUT LOOKUP ERROR
E.ILE: MOVE T1,[I.OPEN,,I.LOOK] ;POINT TO BLOCK
PJRST .TERRL ;ISSUE MESSAGE
$WARN (OEE,<>,E.OEE,.POPJ##) ;ISSUE OUTPUT ENTER ERROR
E.OEE: MOVE T1,[O.OPEN,,O.ENTER] ;POINT TO BLOCK
PJRST .TERRL ;ISSUE MESSAGE
$WARN (ATF,<Aborting transfer of file >,E.ATF,.POPJ##)
E.ATF: MOVEI T1,I.OPEN
MOVEI T2,I.LOOK
PJRST .TOLEB##
SUBTTL I$INIT -- INITIALIZE PROGRAM VARIABLES
I$INIT:
;GET MFD PPN (IF FAILED ASSUME [1,1])
MOVX T1,%LDMFD ;GET MFD PPN
GETTAB T1, ;FROM MONITOR
MOVE T1,[1,,1] ;FAILED--ASSUME [1,1]
MOVEM T1,MFDPPN ;AND SAVE
;GET SYS PPN (IF FAILED ASSUME [1,4])
MOVX T1,%LDSYS ;GET SYS PPN
GETTAB T1, ;FROM MONITOR
MOVE T1,[1,,4] ;FAILED!--ASSUME [1,4]
MOVEM T1,SYSPPN ;AND SAVE
;GET OPR PPN (IF FAILED ASSUME [1,2])
MOVX T1,%LDFFA ;GET OPR PPN
GETTAB T1, ;FROM MONITOR
MOVE T1,[1,,2] ;FAILED!--ASSUME [1,2]
MOVEM T1,OPRPPN ;AND SAVE
;READ DEFAULT PATH FOR LATER RESTORE (DONT CARE IF FAILED)
MOVX T1,.PTFRD ;READ DEFAULT PATH
MOVEM T1,SVPATH+.PTFCN ;SAVE
MOVE T1,[.PTMAX,,SVPATH] ;POINT TO BLOCK
PATH. T1, ;READ IT
JFCL ;SO WHAT
;SETUP ^C TRAPPING TO RESET PATH. AT EXIT
MOVE T1,[4,,CCINT] ;ADDR OF INTERRUPT ROUTINE
MOVEM T1,CCBLK+.ERNPC ;SAVE
MOVX T1,ER.ICC ;BITS TO TRAP
MOVEM T1,CCBLK+.ERCLS ;STORE CLASS
SETZM CCBLK+.EROPC ;CLEAR OLD PC
SETZM CCBLK+.ERCCL ;AND STATUS
MOVEI T1,CCBLK ;POINT TO BLOCK
MOVEM T1,.JBINT ;INABLE INTERRUPTS
;GET TICKS/SECOND TO CONVERT UPTIME TO SECONDS
MOVX T1,%CNTIC ;GET TICKS/SECOND FROM MONITOR
GETTAB T1, ;..
MOVEI T1,^D60 ;ASSUME 60 CYCLE IF FAILED
MOVEM T1,TICKS ;AND SAVE
POPJ P, ;INITIALIZATION DONE, RETURN
SUBTTL PSISER ROUTINES
PIINIT: MOVE T1,[VECTOR,,VECTOR+1] ;SET UP BLT
SETZM VECTOR ;CLEAR FIRST WORD
BLT T1,VECTOR+LN$VEC-1 ;CLEAR VECTORS
MOVEI T1,TTYSER ;GET ROUTINE TO HANDLE TTY
MOVEM T1,VECTOR+TTYBLK+.PSVNP ;SAVE PC
MOVEI T1,CHKPNT ;ROUTINE TO HANDLE CHECKPOINTS
MOVEM T1,VECTOR+CHKBLK+.PSVNP ;SAVE PC
MOVEI T1,VECTOR ;POINT TO BLOCK
PIINI. T1, ;TURN SYSTEM ON
TLO F,(FL.PSI) ;FLAG PSISER BROKEN
REPEAT 0,<
MOVSI T1,'TTY' ;DEVICE TTY:
MOVE T2,[TTYBLK,,PS.RID] ;ON INPUT DONE
MOVEI T3,0 ;MUST BE ZERO
MOVE T4,[PS.FON+PS.FAC+T1] ;POINT TO BLOCK
TLNN F,(FL.PSI) ;SKIP IF PSISER BROKEN
PISYS. T4, ;TRY IT
TLO F,(FL.PSI) ;FLAG PSISER BROKEN
>
MOVX T1,.PCWAK ;INTERRUPT ON WAKE UUO
MOVSI T2,CHKBLK ;OFFSET,,REASONS
MOVEI T3,0 ;MUST BE ZERO
MOVE T4,[PS.FAC+T1] ;POINT TO BLOCK
TLNN F,(FL.PSI) ;SKIP IF PSISER BROKEN
PISYS. T4, ;TRY IT
TLO F,(FL.PSI) ;FLAG PSISER BROKEN
POPJ P, ;RETURN
PIOFF: SKIPA T1,[PS.FOF] ;TURN SYSTEM OFF
PION: MOVX T1,PS.FON ;TURN SYSTEM ON
TLNN F,(FL.PSI) ;SKIP IF PSISER BROKEN
PISYS. T1, ;DO IT
TLO F,(FL.PSI) ;FLAG PSISER BROKEN
POPJ P,
TTYSER: TLZN F,(FL.CC) ;SEE IF ^C TYPED
SETOM TTYFLG ;NO--FLAG SOMETHING TYPED
INTJEN: DEBRK. ;RETURN
JFCL
$FATAL (CRI,<Can't return from interrupt>)
SUBTTL CHKPNT -- ROUTINES FOR CHECKPOINTING
;CHKPNT -- TAKE A CHECKPOINT NOW
CHKPNT: PUSHJ P,.PSH4T## ;SAVE T1-T4
PUSHJ P,CHKDAE ;SEE IF REALLY DAEMON
JRST CHKP.1 ;NO--JUST INGORE
$INFO (CHK,<Checkpoint at >,DOCHK)
PUSHJ P,SETCHK ;SETUP FOR NEXT CHECKPOINT
CHKP.1: PUSHJ P,.POP4T## ;RESTORE AC'S
JRST INTJEN ;AND RETURN
;SETCHK -- SETUP FOR NEXT CHECKPOINT
SETCHK: MOVX T2,.CLOCK ;CLOCK FUNCTION
MOVE T3,S.CHECK ;MINUTES BETWEEN CHECKPOINTS
IMULI T3,^D60 ;MAKE SECONDS FOR DAEMON
MOVE T1,[2,,T2] ;POINT TO ARG BLOCK
DAEMON T1, ;DO IT
$WARN (DUF,<DAEMON UUO failure>)
POPJ P,
;CHKDAE -- SEE IF WAKER IS REALLY DAEMON
CHKDAE: MOVS T1,VECTOR+CHKBLK+.PSVIS ;GET JOB NUMBER OF WAKER
HRRI T1,.GTPRG ;GET PROGRAM NAME
GETTAB T1, ;TRY
JRST .POPJ1## ;?? ASSUME OK
CAME T1,[SIXBIT/DAEMON/] ;PROGRAM=DAEMON?
POPJ P, ;NO
MOVS T1,VECTOR+CHKBLK+.PSVIS ;GET JOB NUMBER AGAIN
HRRI T1,.GTSTS ;GET JOB STATUS
GETTAB T1, ;TRY
JRST .POPJ1## ;?? ASSUME OK
TXNN T1,JACCT ;SEE IF JACCTED
POPJ P, ;NO
JRST .POPJ1## ;YES--ITS THE REAL DAEMON!
CHKOPR: JRST CHKO.1
TLNE F,(FL.PSI) ;SEE IF PSISER WORKS
JRST CHKO.1 ;NO--DO THE HARD WAY
MOVEI T1,0 ;LOAD A ZERO
EXCH T1,TTYFLG ;GET FLAG,,CLEAR IT
JUMPE T1,.POPJ## ;JUMP IF NO INPUT
CHKO.1: SKPINL ;SEE IF LINE TYPED
POPJ P, ;NO
PUSHJ P,TTYCOM ;YES--PROCESS A COMMAND
JRST CHKO.1 ;AND SEE IF ANOTHER
SUBTTL TTY COMMAND PROCESSOR
TTYCOM: PUSHJ P,SIXIN ;READ A SIXBIT WORD
CLRBFI
JUMPE T2,PROMPT ;JUMP IF NOTHING
MOVE T1,[IOWD LN$RUN,RUNCMD] ;GET POINTER TO KNOWN COMMANDS
PUSHJ P,.LKNAM## ;LOOK THEN UP
JRST CMDERR ;NOT FOUND
SUBI T1,RUNCMD ;GET INDEX
PUSHJ P,@RUNDSP(T1) ;DISPATCH ON COMMAND
PROMPT: TRNN F,FR.STOP ;WE STOPPED?
OUTCHR ["!"] ;NO--GIVE "GO" PROMPT
TRNE F,FR.STOP ;WE STOPPED?
OUTCHR ["/"] ;YES--GIVE "STOPPED" PROMPT
TRNE F,FR.STOP ;WE STOPPED?
JRST TTYCOM ;YES--WAIT FOR COMMAND
POPJ P, ;AND RETURN
CMDERR: JUMPG T1,E$$ARC
$WARN (URC,<Unknown runtime command>,,PROMPT)
$WARN (ARC,<Ambiguous runtime command>,,PROMPT)
DEFINE CMDS,<
XLIST
XX WHAT,DOWHAT
XX SILENCE,DOSIL
XX DIRECTORY,DODIR
XX NODIRECTORY,DOSIL
XX FILES,DOFIL
XX NOFILE,DODIR
XX HELP,DOHELP
XX KILL,DOKILL
XX STOP,DOSTOP
XX GO,DOGO
XX CURRENT,DOCURR
XX ABORT,DOABORT
XX EXIT,DOEXIT
LIST
>
DEFINE XX(NAME,DISPATCH),<EXP SIXBIT/NAME/>
RUNCMD: CMDS
LN$RUN==.-RUNCMD
DEFINE XX(NAME,DISPATCH),<EXP DISPATCH>
RUNDSP: CMDS
SUBTTL RUNTIME COMMAND DISPATCH ROUTINES
DOSIL: MOVEI T1,%SILENCE
JRST SETLVL
DODIR: SKIPA T1,[%DIRECTORY]
DOFIL: MOVEI T1,%FILES
SETLVL: MOVEM T1,S.LEVEL
POPJ P,
DOWHAT: MOVEI T1,[ASCIZ/Stopped
/]
TRNE F,FR.STOP
PUSHJ P,.TSTRG##
MOVEI T1,[ASCIZ/Will EXIT when done
/]
TLNE F,(FL.EXIT)
PUSHJ P,.TSTRG##
PUSHJ P,$WHAT
PUSHJ P,DOCURR
PJRST TOTALS
DOHELP: OUTSTR [ASCIZ/
[NO]FILES Type files as processed
[NO]DIRECTORY Type directories as processed
SILENCE No progress message typeout
HELP This text
KILL Abort copying the file structure
ABORT Stop copying this file only
CURRENT Type current file spec being ocpied
WHAT Type job statistics and current file
STOP Stop FSCOPY now
GO Continue from a STOP
EXIT Exit from FSCOPY when done
/]
POPJ P,
DOKILL: PUSHJ P,E$$ATF ;GIVE ABORT FILE MESSAGE
PUSHJ P,CHKFIL ;SEE IF ANY FILES FOUND
PUSHJ P,RSTPTH ;RESTORE PATH
RESET ;RESET THE WORLD
TLNE F,(FL.EXIT) ;EXIT WHEN DONE?
PUSHJ P,.MONRT## ;YES--EXIT
JRST MAINLP ;AND START AGAIN
DOABORT:TRO F,FR.ABORT
SETZM NRETRY
POPJ P,
DOEXIT: TLO F,(FL.EXIT) ;SET EXIT WHEN DONE
POPJ P, ;AND RETURN
DOSTOP: TROA F,FR.STOP
DOGO: TRZ F,FR.STOP
POPJ P,
DOCURR: PUSHJ P,DOCHK
PJRST .TCRLF##
DOCHK: SKIPN T1,I.LOOK+.RBNAM
POPJ P,
MOVEI T1,I.OPEN
MOVEI T2,I.LOOK
PUSHJ P,.TOLEB##
MOVEI T1,[ASCIZ/ (block=/]
PUSHJ P,.TSTRG##
MOVE T1,CURBLK
PUSHJ P,.TDECW##
MOVEI T1,"/"
PUSHJ P,.TCHAR##
WRD2BK T1,I.LOOK+.RBSIZ
PUSHJ P,.TDECW##
MOVEI T1,")"
PJRST .TCHAR##
$WHAT: PUSHJ P,.SAVE1##
MOVE T1,S.LEVEL
MOVE T1,[ [ASCIZ/Silence/]
[ASCIZ/Type Directories/]
[ASCIZ/Type Files/] ](T1)
PUSHJ P,.TSTRG##
PUSHJ P,.TCRLF##
MOVE T1,S.DSRT
CAIN T1,SRTKNONE
JRST WHAT1
MOVEI T1,[ASCIZ/Sort Directories /]
PUSHJ P,.TSTRG##
MOVE T1,S.DSRT
MOVE T1,[ [ASCIZ/Name/]
[ASCIZ/Extension/]
[ASCIZ/Location/] ]-2(T1)
PUSHJ P,.TSTRG##
PUSHJ P,.TCRLF##
WHAT1: MOVE T1,S.FSRT
CAIN T1,SRTKNONE
JRST WHAT2
MOVEI T1,[ASCIZ/Sort Files /]
PUSHJ P,.TSTRG##
MOVE T1,S.FSRT
MOVE T1,[ [ASCIZ/Name/]
[ASCIZ/Extension/]
[ASCIZ/Location/] ]-2(T1)
PUSHJ P,.TSTRG##
PUSHJ P,.TCRLF##
WHAT2: MOVEI T1,[ASCIZ/Copying BOOT blocks
/]
SKIPLE S.BOOTS
PUSHJ P,.TSTRG##
MOVEI T1,[ASCIZ/Copying front end file FE.SYS
/]
SKIPLE S.FESYS
PUSHJ P,.TSTRG##
MOVEI T1,[ASCIZ/Checkpointing every /]
PUSHJ P,.TSTRG##
MOVE T1,S.CHECK
MOVEI T2,[ASCIZ/minute/]
PUSHJ P,.TPLRS
PUSHJ P,.TCRLF##
MOVSI P1,-LN$WHT
TRZ F,FR.SWT
WHAT3: SKIPG @WHTSWT(P1)
JRST WHAT4
MOVEI T1,[ASCIZ/Conditions /]
TRON F,FR.SWT
PUSHJ P,.TSTRG##
MOVEI T1,[ASCIZ/ /]
PUSHJ P,.TSTRG##
MOVE T1,WHTTXT(P1)
PUSHJ P,.TSTRG##
PUSHJ P,.TCOLN##
MOVE T1,@WHTSWT(P1)
PUSHJ P,.TDTTM##
PUSHJ P,.TCRLF##
WHAT4: AOBJN P1,WHAT3
TRZE F,FR.SWT
PUSHJ P,.TCRLF##
MOVEI T1,[ASCIZ/SUPERSEDE /]
PUSHJ P,.TSTRG##
MOVE T1,S.SUPER
MOVE T1,[ [ASCIZ/Always/]
[ASCIZ/Older/]
[ASCIZ/Never/] ]-1(T1)
PUSHJ P,.TSTRG##
PUSHJ P,.TCRLF##
POPJ P,
DEFINE SWTS,<
XLIST
X SINCE,.FXSNC+I.SPEC
X BEFORE,.FXBFR+I.SPEC
X ASINCE,.FXASN+I.SPEC
X ABEFORE,.FXABF+I.SPEC
X MSINCE,S.MSNC
X MBEFORE,S.MBFR
LIST
>
DEFINE X(A,B),<EXP [ASCIZ/A/]>
WHTTXT: SWTS
LN$WHT==.-WHTTXT
DEFINE X(A,B),<EXP B>
WHTSWT: SWTS
SUBTTL RUNTIME COMMAND INPUT
SIXIN: MOVEI T2,0 ;CLEAR WORD
MOVE T1,[POINT 6,T2] ;GET BYTE POINTER
SIXIN1: INCHWL T3 ;GET A CHAR
CAIL T3,"a" ;SEE IF LOWER CASE
CAILE T3,"z" ;..
SKIPA ;NO
SUBI T1,"a"-"A" ;YES--MAKE UPPER CASE
CAIL T3,"A" ;ALPHABETIC?
CAILE T3,"Z" ;..
POPJ P, ;NO--RETURN
SUBI T3," "-' ' ;MAKE SIXBIT
TLNE T1,(77B5) ;POINTER OVERFLOW?
IDPB T3,T1 ;NO--STORE CHAR
JRST SIXIN1 ;LOOP FOR MORE
SUBTTL SORT ROUTINES
;
; SOME NON-STANDARD AC DEFINITIONS
;
I==T3 ;INDEX TO LOW END OF SWAP LIST
J==T4 ;INDEX TO HIGH END OF SWAP LIST
LL==P1 ;POINTER TO LEFT END OF LIST TO SORT
R==P2 ;POINTER TO RIGHT END OF LIST TO SORT
X1==P3 ;HIGH ORDER VALUE TO SPLIT WITH
X2==P4 ;LOW ORDER VALUE TO SPLIT WITH
Q==16 ;FORTRAN ARG POINTER
; .SORT2 - SORT TWO WORD PAIRS INTO ASCENDING ORDER
; INPUT: T1/ AOBJN POINTER TO LIST TO BE SORTED
; MUST BE EVEN NUMBER OF WORDS
; T2/ FLAGS,,SORT CODE
; FLAGS ARE 400000 FOR UNSIGNED SORT
; 200000 FOR DESCENDING SORT
; SORT CODE IS
; 0 NONE
; 1 NONE
; 2 KEY IS 1234
; 3 KEY IS 3124
; 4 KEY IS 4123
; WHERE HALF WORDS ARE NUMBERED 1-4 FOR
; THE TWO WORD PAIR
; CALL: PUSHJ P,.SORT2##
; RETURN: NON-SKIP
; OUTPUT: NONE
; USES: T1-4
;
.SORT2: PUSHJ P,.SAVE4## ;GET SOME ACS
JUMPGE T1,.POPJ## ;RETURN IF LIST EMPTY
MOVEI T3,(T2) ;GET JUST TYPE OF SORT
CAIG T3,1 ;SEE IF ANYTHING TO DO
POPJ P, ;NO--RETURN
DMOVEM T1,USRARG ;SAVE USERS ARGS
HLRE R,T1 ;GET -LENGTH IN R
MOVM R,R ;MAKE +LENGTH
SUBI R,1 ;SUBTRACT ONE, SO POINTING TO LAST PAIR
CAIE R,1 ;SEE IF ONLY 1
TRNN R,1B35 ;ENSURE AN ODD COUNT NOW
POPJ P, ;JUST RETURN
MOVE P1,USRARG ;GET IOWD POINTER
PUSHJ P,@INISRT-2(T2) ;DO INITIAL SETUP
MOVE P1,USRARG ;PICKUP IOWD POINTER AGAIN
MOVE T2,USRARG+1 ;PICKUP USER FLAGS
TLNE T2,200000 ;DESCENDING ORDER?
PUSHJ P,NEGSRT ;YES--FIX UP
MOVE P1,USRARG ;PICKUP IOWD POINTER AGAIN
MOVE T2,USRARG+1 ;PICKUP USER FLAGS
TLNE T2,400000 ;USER WANT UNSIGNED?
PUSHJ P,FLPSRT ;YES--FIX UP
MOVE T1,USRARG ;GET IOWD PNTR
ADDI R,-1(T1) ;ADD IN BASE ADR, GET ADR OF RIGHT END
MOVEI LL,(T1) ;GET BASE ADR IN L, ADR OF LEFT END
MOVEM P,SAVPDP ;STORE P FOR TERMINATION CHECK
JRST SOR.02 ;JUMP INTO "SORT THIS L,R PAIR"
SUBTTL SORT A PARTITION
SOR.01: POP P,T1 ;TAKE OFF TOP REQUEST
HRRZI R,(T1) ;EXTRACT RIGHT END ADR
HLRZ LL,T1 ;EXTRACT LEFT END ADR
SOR.02: MOVEI I,(LL) ;SET UP POINTERS FOR THIS
MOVEI J,(R) ; SCAN AND SWAP SEQUENCE
MOVE X1,(LL) ;USE FIRST PAIR FOR SCAN AND SWAP
MOVE X2,1(LL) ; SO GET FIRST AND SECOND WORDS
JRST SOR.06 ;AND SKIP TO CHECK RIGHT,SINCE LEFT .EQ.
SOR.03: CAME X1,(I) ;SEE IF HIGH ORDER MATCH
JRST SOR.05 ;NO, USE THAT TO DECIDE
CAMG X2,1(I) ;YES, CHECK NEXT WORD
JRST SOR.06 ;WE FOUND AN I ENTRY LESS THAN X
SOR.04: ADDI I,2 ;MOVE UP TO NEXT SPOT
JRST SOR.03 ;BACK TO FIND A SWAPPABLE ENTRY
SOR.05: CAML X1,(I) ;CHECK FIRST WORD AGAIN
JRST SOR.04 ;NO SWAP, BACK TO INCREMENT AND LOOP
SOR.06: CAME X1,(J) ;NOW SAME PROCEDURE FOR RIGHT END
JRST SOR.08 ;DON'T HAVE TO CHECK X2
CAML X2,1(J) ;CHECK LOW ORDER WORD
JRST SOR.09 ;YES, MAKE A SWAP
SOR.07: SUBI J,2 ;ELSE DECREMENT J
JRST SOR.06 ;AND BACK TO FIND A SWAPPABLE ENTRY
SOR.08: CAMG X1,(J) ;CHECK FIRST ENTRY AGAIN, SINCE .NE.
JRST SOR.07 ;NO SWAP, BACK TO DECREMENT AND LOOP
SOR.09: CAILE I,(J) ;CHECK IF POINTERS HAVE SWAPPED
JRST SOR.10 ;YES, THIS SWAP AND SCAN COMPLETE
DMOVE T1,(I) ;NO, MAKE A SWAP
EXCH T1,(J) ;EXCH EACH WORD
EXCH T2,1(J) ; ...
DMOVEM T1,(I) ;FINISH THE EXCHANGE
ADDI I,2 ;MOVE THE POINTERS
SUBI J,2 ; TOWARD EACH OTHER
CAILE I,(J) ;CHECK IF POINTERS HAVE SWAPPED
JRST SOR.10 ;YES, THIS SWAP AND SCAN COMPLETE
JRST SOR.03 ;AND BACK TO CONTINUE
SUBTTL SELECT NEXT PARTITION FOR SORT
SOR.10: MOVEI T1,(J) ;CALCULATE J-LL
SUBI T1,(LL) ; ...
MOVEI T2,(R) ;AND CALCULATE R-I
SUBI T2,(I) ; ...
CAML T1,T2 ;SEE WHICH IS LONGER
JRST SOR.11 ;(J-LL) .GE. (R-I)
CAIL I,(R) ;IS I .LT. R? (IE, MORE TO SORT?)
JRST SOR.12 ;NO, CHECK IF OTHER SIDE NEEDS
MOVEI T1,(R) ;STACK REQUEST TO SORT THIS
HRLI T1,(I) ;T1/ XWD I,R
PUSH P,T1 ;STICK IT ON THE STACK
SOR.12: MOVEI R,(J) ;AND MOVE DOWN THE R POINTER
JRST SOR.13 ;THEN GO CHECK IF DONE
SOR.11: CAIL LL,(J) ;IS LL .LT. J?
JRST SOR.14 ;NO, GO MOVE UP THE L POINTER
MOVEI T1,(J) ;YES, STACK REQUEST TO SORT THIS
HRLI T1,(LL) ;FROM LL TO J
PUSH P,T1 ;STACK IT
SOR.14: MOVEI LL,(I) ;MOVE UP LL, SINCE ALL BELOW SORTED
SOR.13: CAIGE LL,(R) ;ARE WE DONE WITH THIS PARTITION?
JRST SOR.02 ;NO, BACK TO REPEAT THE WHOLE MESS
CAME P,SAVPDP ;YES, IS THE PARTITION THE WHOLE LIST?
JRST SOR.01 ;NO, LOOP TO PICK NEXT REQUEST
MOVE P1,USRARG ;GET IOWD POINTER
MOVE T2,USRARG+1 ;GET SORT TYPE
TLNE T2,400000 ;USER WANT UNSIGNED?
PUSHJ P,FLPSRT ;YES--FIX BACK
MOVE P1,USRARG ;GET IOWD POINTER
MOVE T2,USRARG+1 ;GET SORT TYPE
TLNE T2,200000 ;DESCENDING?
PUSHJ P,NEGSRT ;YES--FIX BACK
MOVE P1,USRARG ;GET IOWD POINTER
MOVE T2,USRARG+1 ;GET SORT TYPE
PUSHJ P,@FINSRT-2(T2) ;FINISH UP
POPJ P, ;AND RETURN
SUBTTL INITIAL/FINAL SORT ARRANGING ROUTINES
INISRT: I1234
I3124
I4123
FINSRT: F1234
F3124
F4123
I1234:
F1234: POPJ P, ;T1/ 1,,2 T2/ 3,,4
I3124: DMOVE T1,(P1) ;T1/ 1,,2 T2/ 3,,4
MOVSS T2 ;T1/ 1,,2 T2/ 4,,3
ROTC T1,-^D18 ;T1/ 3,,1 T2/ 2,,4
DMOVEM T1,(P1) ;STORE
AOBJN P1,.+1
AOBJN P1,I3124 ;AND LOOP FOR ALL
POPJ P,
F3124: DMOVE T1,(P1) ;T1/ 3,,1 T2/ 2,,4
ROTC T1,^D18 ;T1/ 1,,2 T2/ 4,,3
MOVSS T2 ;T1/ 1,,2 T2/ 3,,4
DMOVEM T1,(P1) ;STORE
AOBJN P1,.+1
AOBJN P1,F3124 ;AND LOOP FOR ALL
POPJ P,
I4123: DMOVE T1,(P1) ;T1/ 1,,2 T2/ 3,,4
ROTC T1,-^D18 ;T1/ 4,,1 T2/ 2,,3
DMOVEM T1,(P1) ;STORE
AOBJN P1,.+1
AOBJN P1,I4123 ;AND LOOP FOR ALL
POPJ P,
F4123: DMOVE T1,(P1) ;T1/ 4,,1 T2/ 2,,3
ROTC T1,^D18 ;T1/ 1,,2 T2/ 3,,4
DMOVEM T1,(P1) ;STORE
AOBJN P1,.+1
AOBJN P1,F4123 ;AND LOOP FOR ALL
POPJ P,
FLPSRT: MOVSI T1,(1B0) ;GET THE SIGN BIT
FLPS.1: XORM T1,(P1) ;TOGGLE SIGN BIT
AOBJN P1,.+1
AOBJN P1,FLPS.1 ;AND LOOP FOR ALL
POPJ P,
NEGSRT: SETCMM (P1) ;NEGATE
AOBJN P1,.+1
AOBJN P1,NEGSRT ;AND LOOP FOR ALL
POPJ P,
;.GTMEM -- GET CORE
;CALL: MOVEI T1,WORDS TO GET
; PUSHJ P,.GTMEM
; (ERROR)
; RETURN W/ T1=START OF ZEROED CORE, .JBFF UPDATED
;USES T1-3
.GTMEM: PUSH P,.JBFF ;SAVE FREE CORE ADR
MOVE T2,T1 ;SAVE # WORDS
ADDB T1,.JBFF ;UPDATE .JBFF
SUBI T1,1 ;SUBTRACT 1
CAMG T1,.JBREL ;SEE IF NEED CORE
JRST GTMEM1 ;NO
TLNN T1,-1 ;SEE IF TOO BIG
CORE T1, ;YES, GET IT
JRST GTMEM2 ;CAN'T
GTMEM1: POP P,T1 ;GET BACK STARTING ADR
HRLI T3,(T1) ;GET STARTING ADR
HRRI T3,1(T1) ;GET STARTING ADR+1
SETZM (T1) ;ZERO THE FIRST WORD
CAIN T2,1 ;SEE IF ONLY 1 WORD
JRST .POPJ1## ;YES--RETURN NOW
ADD T2,T1 ;FIND FINAL LOCATION
BLT T3,-1(T2) ;AND CLEAR IT ALL OUT
JRST .POPJ1## ;AND RETURN SUCCESSFUL
GTMEM2: POP P,.JBFF ;RESTORE .JBFF
POPJ P, ;AND ERROR RETURN
;.PTMEM -- RESET CORE BACK
;CALL: MOVEI T1,NEW .JBFF
; PUSHJ P,.PTMEM
;USES T1
.PTMEM: MOVEM T1,.JBFF ;STORE NEW .JBFF
MOVNS T1 ;MAKE NEGATIVE
ADD T1,.JBREL ;ADD TO CURRECT SIZE
CAIGE T1,1000 ;SEE IF DIFFERENCE A P
POPJ P, ;NO
MOVE T1,.JBFF ;GET .JBFF
SUBI T1,1 ;SUBTRACT ONE
CORE T1, ;REDUCE CORE
JFCL ;ERROR (DON'T CARE)
POPJ P,
SUBTTL ERROR PROCESSING
ERROR: MOVEM 0,CRSHAC+0 ;SAVE AC 0
MOVE 0,[1,,CRSHAC+1] ;SET UP BLT
BLT 0,CRSHAC+17 ;SAVE THE ACS
HRRZ P1,(P) ;GET ADDRESS OF ARGS FROM CALL
POP P,(P) ;GET EXTRA PUSHJ OFF THE STACK
HRRZ T1,1(P1) ;GET CONTINUATION ADDRESS
MOVEM T1,(P) ;RETURN HERE
MOVEM P,CRSHAC+P ;UPDATE FOR LATER
PUSHJ P,.VERBO## ;GET VERBOSITY BITS
PUSH P,T1 ;SAVE THEM FOR LATER
PUSHJ P,.TNEWL## ;START WITH A CRLF IF NEEDED
HLRZ T2,1(P1) ;GET MESSAGE TYPE
SKIPN T2 ;SKIP IF WARN OR INFO
PUSHJ P,.CLRBF## ;MUST CLEAR TYPEAHEAD
ERROR1: MOVE T1,[EXP "?","%","["](T2) ; AND THE SEVERITY CHARACTER
PUSHJ P,.TCHAR## ;TYPE IT
MOVE T1,(P) ;GET VERBOSITY BITS
TRNN T1,JWW.PR ;/MESSAGE:PREFIX?
JRST ERROR2 ;NO
HRLZ T1,IBLK+1 ;GET OUR PREFIX
HLR T1,0(P1) ;INCLUDE ONE FOR MESSAGE
PUSHJ P,.TSIXN## ;TYPE IN SIXBIT
ERROR2: PUSHJ P,.TSPAC## ;SPACE
POP P,T1 ;GET VERBOSITY BITS
TRNN T1,JWW.FL ;/MESSAGE:FIRST?
JRST ERROR4 ;NO
ERROR3: HRRZ T1,0(P1) ;GET TEXT ADDRESS
PUSHJ P,.TSTRG## ;TYPE STRING
HLRZ T1,2(P1) ;GET ADDRESS FOR ADDITIONAL TYPEOUT
JUMPE T1,ERROR4 ;JUMP IF NONE
MOVEM T1,ERRSUB ;SAVE ADDRESS
MOVEM P1,ERRSP1 ;SAVE P1
MOVSI 0,CRSHAC ;SET UP BLT
BLT 0,17 ;RESTORE THE ACS
PUSHJ P,@ERRSUB ;CALL ADDITIONAL TYPEOUT ROUTINE
MOVE P1,ERRSP1 ;RELOAD P1
ERROR4: HLRZ T1,1(P1) ;GET ERROR TYPE
CAIN T1,2 ;INFORMATIONAL?
PUSHJ P,.TRBRK## ;YES--TERMINATE WITH A BRACKET
PUSHJ P,.TCRLF## ;TYPE A CRLF
MOVSI 0,CRSHAC ;SET UP BLT
BLT 0,17 ;RESTORE THE ACS
POPJ P, ;AND RETURN
SUBTTL ^C AND ERROR TRAPPING
CCINT: PUSH P,CCBLK+.EROPC ;SAVE CURRENT PC
SETZM CCBLK+.EROPC ;AND RENABLE
PUSHJ P,.PSH4T## ;SAVE T1-T4
PUSHJ P,RSTPTH ;RESTORE PATH
EXIT 1, ;AND EXIT
;HERE IF CONTINUE
PUSHJ P,SETPTH ;SET PATH
TLO F,(FL.CC) ;FLAG ^C TYPED
PUSHJ P,.POP4T## ;RESTORE T1-T4
POPJ P, ;AND RETURN
TOTALS: MOVEI T2,[ASCIZ/UFD/]
SKIPE T1,NUFDS
PUSHJ P,.TPLRS
SKIPN NSFDS
JRST TOT1
MOVEI T1,[ASCIZ/, /]
PUSHJ P,.TSTRG##
MOVE T1,NSFDS
MOVEI T2,[ASCIZ/SFD/]
PUSHJ P,.TPLRS
TOT1: SKIPN NFILES
JRST TOT2
MOVEI T1,[ASCIZ/, /]
PUSHJ P,.TSTRG##
MOVE T1,NFILES
MOVEI T2,[ASCIZ/file/]
PUSHJ P,.TPLRS
TOT2: SKIPN NBLKS
JRST TOT3
MOVEI T1,[ASCIZ/, /]
PUSHJ P,.TSTRG##
MOVE T1,NBLKS
MOVEI T2,[ASCIZ/block/]
PUSHJ P,.TPLRS
TOT3: PUSHJ P,.TCRLF##
MOVEI T1,[ASCIZ/Elapsed time:/]
PUSHJ P,.TSTRG##
MOVX T1,%NSUPT ;GET UPTIME (TICKS)
GETTAB T1,
MOVEI T1,0
SUB T1,UPTIME ;MINUS STARTING TIME
IDIV T1,TICKS ;INTO SECONDS
IMULI T1,^D1000 ;INTO MILLSECONDS
PUSHJ P,.TTIME## ;TYPE TIME AS HH:MM:SS
MOVEI T1,[ASCIZ/, disk reads: /]
PUSHJ P,.TSTRG##
HRROI T1,.GTRCT
GETTAB T1,
MOVEI T1,0
ANDX T1,RC.TTL
SUB T1,READS
PUSHJ P,.TDECW##
MOVEI T1,[ASCIZ/, writes: /]
PUSHJ P,.TSTRG##
HRROI T1,.GTWCT
GETTAB T1,
MOVEI T1,0
ANDX T1,WC.TTL
SUB T1,WRITES
PUSHJ P,.TDECW##
PJRST .TCRLF##
.TERRL: PUSHJ P,.SAVE1## ;Save P1
MOVE P1,T1 ;Remember arg
HRRZ T1,.RBEXT(P1) ;Get error code
MOVSI T2,-ERRLEN
HLRZ T3,ERRTAB(T2)
CAIE T1,(T3)
AOBJN T2,.-2
HRRZ T1,ERRTAB(T2)
PUSHJ P,.TSTRG##
MOVEI T1,[ASCIZ/ (/] ;Get string
PUSHJ P,.TSTRG## ;Type
HRRZ T1,.RBEXT(P1) ;Get error code
PUSHJ P,.TOCTW## ;Type in octal
MOVEI T1,[ASCIZ/) file /] ;Get string
PUSHJ P,.TSTRG## ;Type
HLRZ T1,P1 ;Get OPEN block address
HRR T2,P1 ;Get LOOKUP block address
PJRST .TOLEB## ;Type and return
ERRTAB: ERFNF%,,[ASCIZ/Non-existent file/]
ERIPP%,,[ASCIZ/Non-existent UFD/]
ERPRT%,,[ASCIZ/Protection failure/]
ERFBM%,,[ASCIZ/File being modified/]
ERAEF%,,[ASCIZ/Already existing file/]
ERISU%,,[ASCIZ/Illegal sequence of monitor calls/]
ERTRN%,,[ASCIZ/Rib or directory read error/]
ERNSF%,,[ASCIZ/Not a saved file/]
ERNEC%,,[ASCIZ/Not enough core/]
ERDNA%,,[ASCIZ/Device not availible/]
ERNSD%,,[ASCIZ/No such device/]
ERILU%,,[ASCIZ/No two register relocation capability/]
ERNRM%,,[ASCIZ/No room or quota exceeded/]
ERWLK%,,[ASCIZ/Write-lock error/]
ERNET%,,[ASCIZ/Not enough free core/]
ERPOA%,,[ASCIZ/Partial allocation only/]
ERBNF%,,[ASCIZ/Block not free on allocated position/]
ERCSD%,,[ASCIZ/Can't supersede existing directory/]
ERDNE%,,[ASCIZ/Can't delete non-empty directory/]
ERSNF%,,[ASCIZ/Non-existent SFD/]
ERSLE%,,[ASCIZ/Search list empty/]
ERLVL%,,[ASCIZ/SFD nested too deep/]
ERNCE%,,[ASCIZ/No create/]
ERSNS%,,[ASCIZ/Segment not on the swapping space/]
ERFCU%,,[ASCIZ/Can't update file/]
ERLOH%,,[ASCIZ/Low segment overlaps high segment/]
ERNLI%,,[ASCIZ/Not logged in/]
ERENQ%,,[ASCIZ/Outstanding locks set/]
ERBED%,,[ASCIZ/Bad EXE file directory/]
ERBEE%,,[ASCIZ/Bad EXE extension/]
ERDTB%,,[ASCIZ/EXE directory too big/]
ERENC%,,[ASCIZ/Network capacity exceeded/]
ERTNA%,,[ASCIZ/Task not available/]
ERUNN%,,[ASCIZ/Unknown network node/]
ERSIU%,,[ASCIZ/SFD in use by another job/]
ERNDR%,,[ASCIZ/NDR lock on/]
ERJCH%,,[ASCIZ/Too many readers/]
ERSSL%,,[ASCIZ/Cant rename SFD to lower level/]
ERCNO%,,[ASCIZ/Channel not open/]
ERDDU%,,[ASCIZ/Device detached/]
ERDRS%,,[ASCIZ/Device is restricted/]
ERDCM%,,[ASCIZ/Device is controlled by MDA/]
ERDAJ%,,[ASCIZ/Device in use by another job/]
ERIDM%,,[ASCIZ/Illegal data mode/]
ERUOB%,,[ASCIZ/Undefined OPEN bits set/]
ERDUM%,,[ASCIZ/Device in use on MPX channel/]
ERNPC%,,[ASCIZ/No core for extended channel table/]
ERNFC%,,[ASCIZ/No free channels available/]
ERUFF%,,[ASCIZ/Unknown FILOP function/]
ERCTB%,,[ASCIZ/Channel number too big/]
ERCIF%,,[ASCIZ/Channel illegal for operation/]
ERRLEN==.-ERRTAB
0,,[ASCIZ .Unknown LOOKUP/ENTER/RENAME error.]
.TOERR: MOVEI T3,2 ;Flag OUTPUT error
JRST TERR ;And process
.TIERR: TDZA T3,T3 ;Flag INPUT error
.TCERR: MOVEI T3,1 ;Flag CLOSE error
TERR: PUSH P,T1 ;Save ADDR of FILOP. block
PUSH P,T3 ;Save error type
MOVE T1,T2 ;Get GETSTS word
PUSHJ P,.TIOER ;Issue message
POP P,T2 ;Get error type
MOVE T1,[ [ASCIZ/ reading /]
[ASCIZ/ closing /]
[ASCIZ/ writing /] ](T2);Load corrosponding function
PUSHJ P,.TSTRG## ;Type it
POP P,T1 ;GET OPEN,,LKP BLOCK
HRRZ T2,T1 ;ISOLATE LKP
HLRZS T1 ;AND OPEN
PJRST .TOLEB## ;TYPE AND RETURN
.TIOER: MOVEI T2,(T1) ;Save GETSTS word
MOVEI T1,[ASCIZ"I/O error "] ;Load general message
TXNE T2,IO.IMP ;See if IO.IMP
MOVEI T1,[ASCIZ/Improper mode /];Yes--Load that text
TXNE T2,IO.DER ;See if IO.DER
MOVEI T1,[ASCIZ/Hardware device error /];Yes--Load that text
TXNE T2,IO.DTE ;See if IO.DTE
MOVEI T1,[ASCIZ/Parity error /];Yes--Load that text
TXNE T2,IO.BKT ;See if IO.BKT
MOVEI T1,[ASCIZ/Block too large or quota exceeded /];Yes--Load that text
PUSHJ P,.TSTRG## ;Issue explaination of error
MOVEI T1,(T2) ;Get GETSTS word
; PJRST .TOCTP ;Type in parathesis and return
.TOCTP: SKIPA T2,[.TOCTW##]
.TDECP: MOVEI T2,.TDECW##
PUSH P,T1 ;Save word
MOVEI T1,"("
PUSHJ P,.TCHAR##
POP P,T1 ;Get word back
PUSHJ P,(T2) ;Call routine
MOVEI T1,")"
PJRST .TCHAR##
.TPLRS: MOVEI T3,[ASCIZ/s/]
PUSH P,T1
PUSH P,T3
PUSH P,T2
PUSHJ P,.TDECW##
PUSHJ P,.TSPAC##
POP P,T1
PUSHJ P,.TSTRG##
POP P,T1
POP P,T2
CAIE T2,1
PJRST .TSTRG##
POPJ P,
SUBTTL IMPURE STORAGE
BLKIO: IOWD 200,BLK
Z
RELOC 0
OFFSET: BLOCK 1 ;STARTING OFFSET FOR SCAN
S.ZER:! ;START OF VARIABLES ZEROD AT PROGRAM STARTUP
PDL: BLOCK LN$PDL ;THE STACK
CRSHAC: BLOCK 20 ;STORAGE FOR ACS ON ERRORS
ERRSP1: BLOCK 1 ;SPECIAL SAVED COPY OF P1
ERRSUB: BLOCK 1 ;ADDITIONAL TYPEOUT SUBROUTINE
SAVFF: BLOCK 1 ;.JBFF AFTER SCAN CALLS
MFDPPN: BLOCK 1 ;MFD [1,1] PPN
OPRPPN: BLOCK 1 ;FFA [1,2] PPN
SYSPPN: BLOCK 1 ;SYS [1,4] PPN
VECTOR: TTYBLK==.-VECTOR ;SPACE FOR TTY BLOCK
BLOCK 4
CHKBLK==.-VECTOR ;SPACE FOR CHKPNT BLOCK
BLOCK 4
LN$VEC==.-VECTOR
TTYFLG: BLOCK 1 ;-1 IF TTY INPUT TYPED
CCBLK: BLOCK 4 ;BLOCK FOR ^C AND OTHER TRAPPING
SVPATH: BLOCK .PTMAX ;ORIGINAL PATH
TICKS: BLOCK 1 ;TICKS/SECOND
SAVPDP: BLOCK 1 ;SAVED PDL FOR SORT
USRARG: BLOCK 2 ;SAVED ACS FOR SORT
S.INIT: BLOCK .FXLEN ;SPACE FOR /INITIAL:[PPN]
S.EXCL: BLOCK .FXLEN ;SPACE FOR /EXCLUDE:[PPN]
S.ZER1:! ;START OF VARIABLES ZEROED PER COPY COMMAND
BLK: BLOCK 200
FEPOS: BLOCK 1
BUFSIZ: BLOCK 1
BUFLOC: BLOCK 1
CURBLK: BLOCK 1
NUFDS: BLOCK 1
NSFDS: BLOCK 1
NFILES: BLOCK 1
NBLKS: BLOCK 1
NRETRY: BLOCK 1
UPTIME: BLOCK 1
READS: BLOCK 1
WRITES: BLOCK 1
STRBLK: BLOCK 5
C.PATH: BLOCK .PTMAX
O.SPEC: BLOCK .FXLEN
O.OPEN: BLOCK 3
O.ENTER:BLOCK LN$LEN
O.PATH: BLOCK .PTMAX
O.DISK: BLOCK LN$DSK
OCLUST: BLOCK 1
I.SPEC: BLOCK .FXLEN
I.OPEN: BLOCK 3
I.LOOK: BLOCK LN$LEN
I.PATH: BLOCK .PTMAX
I.DISK: BLOCK LN$DSK
ICLUST: BLOCK 1
E.PATH: BLOCK .PTMAX+1
S.ZERM==.-1 ;END OF VARIABLES TO BE ZEROED
S.ONE:! ;START OF AREA TO BE SET TO -1 (SCANS SWITCH AREA)
S.LEVEL:BLOCK 1
S.BUFF: BLOCK 1
S.ALLOC:BLOCK 1
S.CHECK:BLOCK 1
S.DSKP: BLOCK 1
S.HPQ: BLOCK 1
S.MBFR: BLOCK 1
S.MSNC: BLOCK 1
S.BOOTS:BLOCK 1
S.FESYS:BLOCK 1
S.RETRY:BLOCK 1
S.FSRT: BLOCK 1
S.DSRT: BLOCK 1
S.SUPER:BLOCK 1
S.SING: BLOCK 1
S.ONEM==.-1 ;END OF SCANS SWITCH AREA
END FSCOPY