TITLE F11 - Program to manipulate FILES-11 structures on TOPS-10 disks ;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1988, 1990. ALL RIGHTS RESERVED. ; ; ;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED ;ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE ;INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER ;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY ;OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY ;TRANSFERRED. ; ;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE ;AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT ;CORPORATION. ; ;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS ;SOFTWARE ON EQUIPMENT THAT IS NOT SUPPLIED BY DIGITAL. SALL SEARCH UUOSYM .REQUE REL:WILD, REL:SCAN TWOSEG RELOC 400000 RELOC 0 LOWSEG=. RELOC .DIRECT FLBLST VMAJ==2 ;MAJOR VERSION VMIN==0 ;MINOR VERSION VWHO==0 ;WHO DONE IT Comment @ F11 is a cheap program to create, destroy, and manipulate FILES-11 structures and files. @ SUBTTL Revision History VER==1 ;7-Jan-85 ; Duplicate some of the functionality of FESET with known ; compiler VER==2 ;6-Nov-85 ; Teach NXTFDB to ignore files with a file number of zero if the ; file being matched is non-null. Seems F11ACP does strange and ; wonderful things when dealing with files (such as leaving the ; directory entry and just zeroing the FHB). Fix a few bugs in ; image mode PUT code so first free byte gets set up correctly. VER==3 ;1-Jan-86 ; Fix "?NO WORD FOR INPUT" - remove instruction at EOFBYT+22L. ; Fix "?Ill UUO at..." - pop T3 off stack before POPJ at FCRLF+4L ; Fix "?Illegal switch" - forbid using "=" for switches @ILLSWT+6L ; RSX20F allows null file names! - make NXTFDB check name AND type ; before declaring directory slot as "null" ; LIBRARY files are not ascii - add .OLB and .SML to IMGTBL. ; Adding 33rd file to a UFD causes problems. Create EXPDIR ; to expand a UFD (or MFD) by one block and make it work. ; Add ASS FOO:=BLAH/IMAGE to allow reading a file which is a ; "disk image" file - ie: 1:1 correspondence between ; tops10 data blocks and a real disk. ; Do some things to make a F11 maintained "volume" acceptable ; to the RSX "VFY" utility (so it can recover lost blocks ; or simply verify the correctness of the volume) ; ; o Create TOPS10.NDL;n files in [0,0] to occupy the space ; between physical block 0 and the 1st block of FE.SYS. ; o Stop setting the "dirty" bits in the Storage Control ; Block in BITMAP.SYS. ; o Insert the "max # of retrieval pointers possible" ; in the proper slot when the FHB is initialized. ; o Insert the "BMAX" word into the Storage Control Block. ; (it contains a copy of the last valid LBN in volume). VER==4 ;25-Feb-86 ; Page marks get lost when PUT onto the front end file. ; Fix up C$PUTF so it considers line terminators as BOTH ; line terminators AND as textual characters of some sort. VER==5 ;25-Feb-87 ; Changes to make the volume a VAX/VMS FILES-11 level 1 volume. ; ; Add SETCPT to automatically select 16 bit mode as required. ; Note 16 bit mode doesn't work very well without RPXKON fixes. ; ; Use RSX/VMS "directory names" rather than UICs. ; Allow delete of EMPTY .dir files. ; Allow /NOCHECK to override checks for undeltable files. ; Correct usage of FSEQ/UFSQ and FRNO and UFX0. Always ; read old FHB at INIFHB so we can bump up FSEQ each re-use. ; Always zero newly acquired blocks in INDEXF so FSEQ starts at 0. ; Fix NXTDIR to ignore deleted directory files. ; Don't assume the "TMP166" words will be all blanks since ; RSX+ and VMS puts the volume label there. ; Truncate version to 15 bits as VMS doesn't like 16 bits. ; Fix bug @SIXIN4 causing bad wildcarding with 9 char file names. ; Don't put spaces or lower case in date/time fields as this ; confuses VAX/VMS DIRECTORY/DATE. Support either on input. VER==6 ;10-Dec-87 ; Teach the DESTROY command to find the Files-11 home block ; and zero it out. This makes sure that if F11 is always used ; to both create and destroy front end areas, -20F will never ; stumble across an obsolete home block and try to use it. ; If a pack is refreshed and FE.SYS disappears by itself, you ; may still need to run FEDEL. VER==100 ;4-Nov-87 DPM ;Create version 2(100) from original ADP version ; o Allow commands to work when the command name is really more ; than six characters. Hack FNDIDX to prune results down too. ; o Make sure that all blocks in the FE.SYS file are written ; during INItialization so that a DIR of FE.SYS[1,4] will ; not have zero written blocks. VER==101 ;12-Feb-88 JJF ;Merge in newer ADP version (7) so that the best of both worlds ;is preserved. ;Also put in a DEC copyright statement. VER=102 ;11-May-88 JJF ;Add a SETZM OPNBLK+.OPBUF at OPNVIL+a few so that the open ;of the Files-11 area won't trash the listing output file byte ;pointer. QAR# T10L342_00048. VER=103 ;17-Oct-89 DPM ;Incorporate bug fix from Jeff Gunter (ADP) which ensures the ;file ID in the directory for CORIMG.SYS matches the file ID in ;the FHB. LOC <.JBVER=137> EXP <%%F11==> RELOC SEARCH $SCNDC,MACTEN EXTERN .TYOCH ;FORCE SCAN TO LOAD WILD SUBROUTINES ; THESE ACS ARE IN ADDITION TO THOSE DEFINED IN $SCNDC FOR SCAN DEFINE BIT,<1B>> BITNUM==-1 F=0 X%INTRO==BIT ;INTRO LINE ALREADY TYPED X%EOF==BIT ;EOF PENDING X%SUPER==BIT ;SUPERCEEDING X%REEAT==BIT ;TYI SHOULD RETURN LASTCH AGAIN X%ODD==BIT ;ODD # OF BYTES IN ASCII RECORD X%UIC==BIT ;TYPFHB SHOULD GIVE UIC X%VMS==BIT ;VERTICAL MOTION SEEN ON THIS LINE X%PEOF==BIT ;PREMATURE EOF X%INT==BIT ;INTERACTIVE OUTPUT DEVICE (DO OUTPUT AFTER CRLF) X%FF==BIT ;FormFeed WAS SEEN IN THIS LINE X%SEQ==BIT ;THIS FILE IS A LINE SEQUENCED ASCII TEXT FILE X%FIR==BIT ;FIRST BLOCK XFER X%DEX==BIT ;DON'T FOLLOW EXTENSION LINKS ETC ;(USED TO MAKE REDFHB READ 1 FHB ONLY, ETC) N==P3 ;COPY SCAN'S N AC U0=16 FP=13 ;FILE POINTER AC M1=14 ;1ST MASK WORD M2=15 ;2ND MASK WORD ;N.B.: IT SEEMS LIKE SCAN DOES NOT USE ACS 0, 11 THRU 16, INCLUSIVE ; HERE ARE SOME RANDOM CONSTANTS ;THESE ARE I/O CHANNELS TTY=10 ; TTY I/O FIO==15 ; FILE I/O VIO=16 ; VOLUME I/O WLD==17 ; WILD'S I/O .RBSLF==177 ; WORD IN TOPS-10 FILE RIB THAT POINTS TO ITSELF M.INFH==^D64 ;# OF FILE HEADER BLOCKS (FHBs) IN FIRST CHUNK OF INDEXF.SYS ;NOT SURE, BUT SUSPECT MUST BE GREATER THAN 5. ;ALSO, DUE TO LAZINESS ON OUR PART TO CORRECTLY UPDATE ;THE EQUIVILENT OF THE RETRIEVAL POINTER IN THE FHB FOR ;INDEXF.SYS, YOU REALLY OUGHT TO MAKE THIS NUMBER LARGE ENOUGH ;TO ACCOUNT FOR THE NUMBER OF FILES YOU EXPECT TO HAVE IN ;A NEWLY CREATED FILES-11 VOLUME WHICH IS MANIPULATED BY ;F11 - OF COURSE 20F ITSELF WILL CORRECTLY ADD MORE THAN ;M.INFH FILES AND DO CORRECT UPDATES. ; **** N.B. **** DUE TO DESIGN DEFICIENCIES IN "FELOAD", F11ACP.TSK MUST ; **** **** HAVE AN FHB ALLOCATED IN THE FIRST CHUNK OF INDEXF.SYS ; **** **** OR IT WILL NOT BE ABLE TO FIND F11ACP DURING THE LOAD OPDEF PJRST [JRST] VOLMAX=3 ;MAX NUMBER OF CONCURRENTLY DEFINED LOGICAL VOLUMES SUBTTL DEFINITIONS -- MACROS ; DEFINE THE DEFINE'R MACRO DEFINE DEFPRE(.a),<.prefix=='.a' .offset==0> DEFINE X(.name,.size,.defalt),< IFNB <.name>,< A.'.name'==<.prefix> .XCREF A.'.name', S.'.name'> O.'.name'==.offset .offset==.offset+^D'.size' S.'.name'==^D'.size' IFNB <.defalt>,< M.'.name'==.defalt> > SUBTTL TOPS-10 HOME BLOCK DEFPRE HOMNAM==0 ;PDP10 WORD #0 HAS 36 BITS OF SIXBIT *HOM* .OFFSET==HOMNAM*4;FORCE PDP11 POINTER AT HOMNAM X HSIX,2 ; CONTAIN "SIXBIT" 'HOM' X HSX0,2 ; CONTAIN 0'S HOMFE0==61 ;PDP10 WORD#61 HAS 36 BIT POINTER TO FE.SYS (AND VALID BIT) .offset==HOMFE0*4;FORCE PDP11 POINTER AT HOMFE0 X HLBN,4 ; ADDRESS OF PDP11 FE.SYS FILE HOMFE1==62 ;PDP10 WORD#62 HAS 36 BIT LENGTH OF FE.SYS X HLEN,4,^D2048 ;LENGTH OF PDP11 FE.SYS FILE SUBTTL FILES-11 HOME BLOCK DEFPRE ;THESE ALL OFFSET OFF OF H11BUF X IBSZ,2 ; SIZE OF INDEX-BIT-MAP IN BLOCKS X IBLH,2 ; DISK LBN ADRRES OF INDEX BIT MAP HIGH WORD X IBLL,2 ; DISK LBN ADDRESS OF INDEX BIT MAP LOW WORD X FMAX,2,^O77777 ; MAX # OF FILES ALLOWED ON THIS VOLUME X SBCL,2,1 ; CLUSTER SIZE FOR STORAGE-BIT-MAP X DVTY,2 ; DISK-DEVICE TYPE X VLEV,2 ; STRUCTURE LEVEL X VNAM,12 ; VOLUME NAME X ,4 ; RESERVED AREA X VOWN,2,401 ; VOLUME OWNER'S DECIMAL UIC IN BINARY (IE: [1,1]) X VPRO,2,0 ; VOLUME PROTECTION CODE X VCHA,2,30 ; VOLUME CHARACTERISTICS (30=NO ATTACH, NO DEVICE CONTROL FCNS) X DFPR,2,164000 ; DEFAULT PROTECTION FOR FILES X ,6 ; RESERVED AREA X WISZ,1,7 ; DEFAULT # OF RETRIEVAL PAIRS IN A WINDOW X FIEX,1,5 ; DEFAULT # OF BLOCKS TO EXTEND FILES X LRUC,1,3 ; # ENTRIES IN A DIRECTORY LRU X ,11 ; "AVAILABLE SPACE" X CHK1,2 ; CHECKSUM OF WORDS 0-28 X VDAY,2 ; 2 DIGIT DAY OF MONTH X VMON,3 ; 3 BYTE NAME OF MONTH X VYER,2 ; 2 DIGIT YEAR IN CENTURY X ,1 ; ? BLANK PERHAPS? X VHOR,2 ; 2 DIGIT HOUR IN DAY X VMIN,2 ; 2 DIGIT MINUTE IN HOUR X VSEC,2 ; 2 DIGIT SECOND IN MINUTE X ,398 ;RESERVED FOR RELATIVE VOLUME TABLE X INDN,12 ;SYSTEM INDEPENDENT VOLUME NAME (12 BLANKS) X INDO,12 ;SYSTEM INDEPENDENT OWNER NAME ([001,001]) X INDF,12 ;SYSTEM INDEPENDENT FORMAT TYPE ("DECFILE11A") X ,2 ;NOT USED X CHK2,2 ;CHECKSUM OF WORDS 0-255. SUBTTL FILES-11 FILE HEADER BLOCK DEFPRE ;THESE ALL OFFSET OFF OF FHBBUF X IDOF,1 ; ID AREA OFFSET IN WORDS X MPOF,1 ; MAP AREA OFFSET IN WORDS X FNUM,2 ; FILE NUMBER X FSEQ,2 ; FILE SEQUENCE # X FLEV,2,401 ; STRUCTURE LEVEL AND SYSTEM NUMBER X PROG,1 ; PROGRAMMER NUMBER (MEMBER NUMBER) X PROJ,1 ; PROJECT NUMBER (GROUP NUMBER) X FPRO,2,164000 ; FILE PROTECTION CODE X UCHA,1 ; USER CONTROLLER FILE CHARACTERISTICS UC.CON=200 ; THIS FILE IS "LOGICALLY" (IE: DECLARED) CONTIGUOUS UC.DLK=100 ; FILE IMPROPERLY CLOSED X SCHA,1 ; SYSTEM CONTROLLED FILE CHARACTERISTICS SC.MDL=200 ; FILE MARKED FOR DELETETION SC.BAD=100 ; BAD BLOCK IN FILE ; ** HERE ARE THE USER FILE ATTRIBUTES X UFAT,32 ; USER FILE ATTRIBUTES ...==.offset ;;SAVE OFFSET TO THING AFTER UFAT .offset==O.UFAT ;;GO BACK TO UFAT X RTYP,1 ; RECORD TYPE BYTE R.FIX==1 ;TYPE 1 IS FIXED LENGTH R.VAR==2 ;TYPE 2 IS VARYED LENGTH R.SEQ==3 ;TYPE 3 IS SEQUENCED RECORDS X RATT,1 ; RECORD ATTRIBUTE BYTE FD.FTN==1;IF BIT SET, 1ST DATA BYTE IS CARRIAGE CONTROL FD.CR==2 ;IF BIT SET, DO "LF" BEFORE LINE DATA,CR AFTER FD.BLK==10;IF BIT SET, RECORDS CANNOT CROSS BLK BOUNDRYS X RSIZ,2 ; RECORD SIZE (IF VARYED LENGTH, BIGGEST RECORD IN FILE) ; X HIBK,4 ; HIGH BLOCK; HIGHEST VBN ACTUALLY IN USE X HIBH,2 ; HIGH BLOCK HIGH X HIBL,2 ; HIGH BLOCK LOW ; X EFBK,4 ; EOF BLOCK; VBN WHICH IS FIRST NOT IN USE X EFBH,2 ; EOF BLOCK HIGH X EFBL,2 ; EOF BLOCK LOW X FFBY,2 ; FIRST FREE BYTE (IN THE LAST BLOCK) X RACC,1 ;RECORD ACCESS BYTE FD.RWM==1;READ$/WRITE$ MODE IF1, 0 MEANS GET$/PUT$ FD.RAN==2;RANDOM ACCESS IF 1, 0 MEANS SEQUENTIAL FD.PLC==4;LOCATION MODE IF 1, 0 MEANS MOVE MODE FD.INS==10;PUT$ DOES NOT TRUNCATE IF 1, 0 IT DOES X RCTL,1 ;DEVICE-CHARACTERISTICS BYTE FD.REC==1;1 IF RECORD ORIENTED, 0 IF BLOCK ORIENTED (LIKE DISK) FD.CCL==2;1 IF CARRIAGE CONTROL DEVICE, 0 OTHERWISE FD.TTY==4;1 IF TELEPRINTER DEVICE FD.DIR==10;1 IF DIRECTORY DEVICE FD.SDI==20;1 IF SINGLE DIRECTORY ONLY FD.SEQ==40;1 IF INHERENTLY SEQUCENTIAL X CLL,2 ;"CORE LINK LOW" - USED TO LINK FHB SEGMENTS X CLH,2 ;"CORE LINK HIGH" - USED TO LINK FHB SEGMENTS .offset==... ;;RESUME NORMAL ALLOCATION ; HERE IS THE ID AREA M.IDOF==.offset/2 ;COMPUTE OFFSET TO ID AREA X FNAM,4 ; FILE NAME IN RAD50 X ,2 ; (LAST 3 CHARACTERS OF 9 CHARACTER RAD50 FILE NAME) .offset==o.fnam X FNM1,2 ; 1ST WORD OF 3 CONTAINING FILE NAME IN RAD50 X FNM2,2 ; 2ND WORD OF 3 CONTAINING FILE NAME IN RAD50 X FNM3,2 ; 3RD WORD OF 3 CONTAINING FILE NAME IN RAD50 X FTYP,2 ; FILE TYPE IN RAD50 X FVER,2 ; FILE VERSION IN BINARY X RVNO,2 ; REVISION # IN BINARY X RVDT,7 ;REVISION DATE .OFFSET==O.RVDT X RDAY,2 ; REVISION DATE DAY X RMON,3 ; REVISION DATE MONTH X RYER,2 ; REVISION DATE YEAR X RVTI,6 ;REVISION TIME .OFFSET==O.RVTI X RHOR,2 ; REVISION TIME HOUR X RMIN,2 ; REVISION TIME MINUTE X RSEC,2 ; REVISION TIME SECOND X CRDT,7 ;CREATE DATE .OFFSET==O.CRDT X CDAY,2 ; CREATION DATE DAY X CMON,3 ; CREATION DATE MONTH X CYER,2 ; CREATEION DATE YEAR X CRTI,6 ;CREATE TIME .OFFSET==O.CRTI X CHOR,2 ; CREATION TIME HOUR X CMIN,2 ; CREATION TIME MINUTE X CSEC,2 ; CREATION TIME SECOND X EXDT,7 ;EXPIRATION DATE .OFFSET==O.EXDT X XDAY,2 ; EXPIRATION DATE DAY X XMON,3 ; EXPIRATION DATE MONTH X XYER,2 ; EXPIRATION DATE YEAR X ,1 ; USED TO ROUND TO A WORD BOUNDRY ;; MAP AREA M.MPOF==.offset/2 ;COMPUTE OFFSET TO THE MAP AREA X ESQN,1 ; EXTENSION SEGMENT NUMBER X ERVN,1 ; EXTENSION RELATIVE VOLUME NUMBER X EFNU,2 ; EXTENSION FILE NUMBER X EFSQ,2 ; EXTENSION FILE SEQUENCE X CTSZ,1,1 ; SIZE OF THE BLK COUNT FIELD (ALWAYS 1) X LBSZ,1,3 ; SIZE OF BLOCK NUMBER FIELD (ALWAYS 3) X USE,1,0 ; # OF RET PNTRS IN USE X MAX,1,314 ; # OF RET PNTRS SLOTS POSSIBLE ;; RETRIEVAL POINTERS ...==.offset X RETP,4 ; 4 BYTES OF STUFF FOR EACH RETRIEVAL PAIR .offset==... X HRET,1 ; HIGH BYTE OF LBN OF 1ST BLOCK X RCNT,1 ; # BLKS-1 IN THIS CHUNK X RLBN,2 ; LOW LBN# OF 1ST BLK IN THIS CHUNK .offset==776 X CKSM,2 ; CHECKSUM OF WORDS 0 THRU 255. ; THE ABOVE DATA WAS RECONSTRUCTED FROM A SIMPLISTIC APPENDIX OF ; A "WELCOME TO RSX-11M" TYPE MANUAL AND IS LIKELY TO BE ; INCOMPLETE AND INACCURATE TO SOME UNDETERMINED EXTENT. SUBTTL FILES-11 DIRECTORY ENTRY DEFPRE ;THESE ALL OFFSET OFF OF MFDDAT X UFNO,2 ; FILE # X UFSQ,2 ; SEQ # X UFRV,2 ; ALWAYS (APPARENTLY) 0 ("RELATIVE VOLUME NUMBER") X UFN1,2 ; 1ST NAME WORD X UFN2,2 ; 2ND NAME WORD X UFN3,2 ; 3RD NAME WORD ...==.offset .offset==o.ufn1 X UFNM,4 ; FILE NAME X ,2 X UFTY,2 ; FILE TYPE X UVER,2 ; OCTAL BINARY GENERATION # .DIROF==.offset ; REMEMBER LENGTH OF DIRECTORY ENTRY ; DETERMINED BY INSPECTION SUBTTl FILES-11 BIT MAP BUFFER BLOCK DEFPRE X ,3 ; UNUSED X BCNT,1 ; # OF BLOCKS IN THE SBM ; THESE 2 FIELDS "FLOAT" AND ALWAYS FOLLOW THE LAST USED SAB COUNT WORD X BDMH,2 ; (THE "INI" UTILITY SETS THIS TO SOMETHING)? X BDML,2 ; (THE "INI" UTILITY SETS THIS TO SOMETHING)? X BMXH,2 ; HIGH PART OF LSTLBN COPY X BMXL,2 ; LOW PART OF LST LBN COPY ; DETERMINED BY INSPECTION SUBTTL FILE DESCRIPTOR BLOCK SEARCH SCNMAC ; THESE VALUES ARE STOLEN FROM SCAN, SO THAT WE CAN USE SCAN/WILD ; ROUTINES. NOTE HOWEVER, THAT BECAUSE OF THE "EXTRA" WORDS, WE ; MUST HAVE OUR OWN VERSION OF "FILIN" TO READ A FILE SPEC. .FXDEV==.FXDEV ;DEVICE NAME, COPIED FROM SCAN .FXNAM==.FXNAM ;FILE NAME, COPIED FROM SCAN .FXNMM==.FXNMM ;FILE NAME MASK .FXEXT==.FXEXT ;FILE-NAME-EXTENSION,,EXTENSION-MASK (MASK NON0 IF .) .FXMOD==.FXMOD ;MODIFIED WORD .FXMOM==.FXMOM ;MODIFIER MASK .FXDIR==.FXDIR ;DIRECTORY WORD (EACH HALF =0 IF DEFAULT;SFD:0 IF END) .FXDIM==.FXDIM ;DIRECTORY MASK .FXLND==.FXLND ;LENGTH OF "DIRECTORY SPECIFICATION" .FXBFR==.FXBFR ;/BEFORE VALUE .FXSNC==.FXSNC ;/SINCE .FXABF==.FXABF ;/ABEFORE .FXASN==.FXASN ;/ASINCE .FXFLI==.FXFLI ;FILE MINIMUM SIZE, IN WORDS .FXFLM==.FXFLM ;FILE MAXIMUM SIZE, IN WORDS .FXEST==.FXEST ;/ESTIMATE .FXVER==.FXVER ;/VERSION DEFINE FX(.NAME),<'.NAME'==.FXLEN .FXLEN==.FXLEN+1> .FXLEN==.FXVER+1 ;COMPUTE SIZE OF FILE SPEC BLOCK FX .F2NAM ;ADD ANOTHER WORD, 2ND PART OF FILE NAME FX .F2NMM ;ADD ANOTHER WORD, 2ND PART OF FILE NAME MASK FX .FXNUM ;FILE # OF FILE NXTFDB FOUND FX .FXFLG ;FLAGS ASSOCIATED WITH THAT FILE FX .FXGEN ;"GENERATION" NUMBER OF FILE FX .FXSEQ ;SEQ# OF FILE FX .FXSWT ;SWITCHES APPLIED TO THIS FILE SPEC FX .FXLNK ;POINTER TO NEXT FILE SPEC IN THIS CHAIN FX .FXDIN ;FIRST PART OF FILES-11 DIRECTORY NAME FX .F2DIN ;SECOND PART FX .FXDNM ;FIRST PART OF DIRECTORY NAME MASK FX .F2DNM ;SECOND PART FX .FXRVN ;RELATIVE VOLUME NUMBER ;HERE ARE BITS, BYTES, AND FIELDS IN THE MODIFIER WORD FX.NDV==FX.NDV ;SET IF NULL DEVICE FX.NUL==FX.NUL ;NULL EXTENSION FX.DIR==FX.DIR ;DIRECTORY SPECIFIED (MOD=0 IF [-]) FX.PHY==FX.PHY ;/PHYSICAL FX.NOM==FX.NOM ;/OKNONE FX.DFX==FX.DFX ;DIRECTORY DOES NOT NEED FIX-UP BY WILD FX.TRM==FX.TRM ;FIELD, CODE FOR FILE SPEC'S TERMINATING CHARACTER .FXTRA==.FXTRA ;& (AND) .FXTRO==.FXTRO ;! (OR) .FXTRN==.FXTRN ;- (NOT) .FXTRC==.FXTRC ;+ (CONCATENATE) FX.STR==FX.STR ;/STRS FX.PRT==FX.PRT ;/OKPROT FX.SUP==FX.SUP ;/ERSUPERSEDE ;N.B.: IT LOOKS AS IF BITS 12 THRU 20 ARE FREE, BUT DON'T BET ON IT FX.DEN==FX.DEN ;/DENSITY, 3 BIT FIELD FX.PAR==FX.PAR ;/PARITY, 1 BIT FIELD FX.PRO==FX.PRO ;/PROTECTION OR , 9 BIT FIELD FX.NUN==1B12 ;SET IF NO NAME WAS EVER SPECIFIED FX.EQL==1B13 ;SET IF THIS SPEC ENDED WITH = FX.CMA==1B14 ;SET IF THIS SPEC ENDED WITH , ; DEFINE THE FILE SWITCHES DEFINE SS,< S FILENO,FILEIN ;/FILENUMBER:number S CHARAC,CHAIN ;/CHARACTERISTICS:{ATCH:DCF} S CONTIG S IMAGE ;/IMAGE S BINARY ;/BINARY S ASCII ;/ASCII S SIZE,SIZIN ;/SIZE:nnn S MAXFIL,MAXFIN ;/MAXFIL:nnn S FULL ;/FULL S INDEX,IDXIN ;/INDEX:{BEG,MID,END,BLK:nnn} S DETAIL ;/DETAILS S ALLOCA,ALCIN ;/ALLOCATE:nnnn S VPROTE,VPRTIN ;/VPPROTECTION: S FPROTE,FPRTIN ;/FPROTECTION: S EXTEND,EXTDIN S DOTS ;/DOTS - give got every time ENTER for FE.SYS fails S NOVM ;/NOVM - do not copy motion characters CR,LF ;(BUT they are still implied if record type says so) S NOCHEC ;/NOCHECK - don't disallow this command > DEFINE S(.name,.serve), SS ;BUILD THE SWITCH SECTION OF THE FDB DEFINE TYPE(.text,adr),< PUSHJ P,[PUSHJ P,TYPE.. CAI [ASCIZ ~'.TEXT'~] IFB , IFNB ,] > DEFINE ERROR(.text,.adr<.ERR>),< JRST [RELEAS TTY, OUTSTR [ASCIZ ~? '.text' ~] JRST '.adr']> ; DEFINE THE PDP11 RAD50 CHARACTER SET DEFINE RDEF(.START,.STRING),<.FOO==.START-1 IRPC .STRING,<$R.'.STRING'==<.FOO==<.FOO+1>>>> $R.==0 ;BLANK MUST BE DONE THIS WAY RDEF 1, RDEF 33,<$.> RDEF 36,<0123456789> ; MACRO TO MOVE 1 PDP11 FORMATTED FIELD TO ANOTHER (LEFT TO RIGHT) DEFINE MOV.(.ORIGIN,.DESTINATION,.OFFSET<[0]>),< PUSHJ P,[JSP U0,MOV.. CAI .ORIGIN ;;POINT AT ORIGIN DATA CAI A.'.DESTINATION';;POINT AT DESTINATION STRUCTURE CAI O.'.DESTINATION';;SPECIFY OFFSET FROM DESTINATION CAI S.'.DESTINATION';;SPECIFY # OF BYTES TO MOVE CAI .OFFSET ;;POINT AT POSSIBLE ADDITIONAL OFFSET POPJ P,0]> ; MACRO TO MOVE 1 PDP10 FORMATTED FIELD TO A PDP11 FIELD (4 BYTES MAX) DEFINE STOR.(.ORIGIN,.DESTINATION,.OFFSET<[0]>),< PUSHJ P,[JSP U0,STOR.. CAI .ORIGIN ;;POINT AT ORIGIN PDP10 DATA CAI A.'.DESTINATION';;POINT AT DESTINATION FIELD CAI O.'.DESTINATION';;GIVE BYTE OFFSET FROM DESTINATION CAI S.'.DESTINATION';;#BYTES IN DESTINATION FIELD CAI .OFFSET ;;ADDRESS OF ADDITIONAL OFFSET POPJ P,0]> ; MACRO TO MOVE 1 PDP11 FORMATTED FIELD TO A PDP10 FIELD (4 BYTES MAX) DEFINE LOAD.(.ORIGIN,.DESTINATION,.OFFSET<[0]>),< PUSHJ P,[JSP U0,LOAD.. CAI .ORIGIN ;;POINT AT DESTINATION PDP10 FIELD CAI A.'.DESTIN' ;;POINT AT ORIGIN PDP11 FIELD CAI O.'.DESTIN' ;;BYTEOFFSET FROM PDP11 FIELD CAI S.'.DESTIN' ;;#BYTES IN PDP11 FIELD CAI .OFFSET ;;ADDRESS OF ADDITIONAL OFFSET POPJ P,0]> ; MACRO TO GENERATE PDP11 WORD STRINGS OF PDP11 RAD50 CHARACTERS DEFINE .RAD50(S),< COUNT==0 IRPC S, ;;FIRST COMPUTE TOTAL # CHARACTERS WORDS==COUNT/3 ;;WORDS=# PDP11 WORDS GENERATED REMAIN==COUNT- ;;REMAIN=REMAINDER FROM COUNT/3 IFN REMAIN, ;;ACCOUNT FOR NON-ZERO REMAINDER PAIRS==WORDS/2 ;;PAIRS=# PDP11 WORD PAIRS ;;(IE: # OF PDP10 WORDS NEEDED) IFN WORDS&1, ;;IF ODD WORDS, ONE MORE PAIR NEEDED C==0 ;; CURRENT CHARACTER POSITION = 1ST CHAR IN STR REPEAT PAIRS,< ;; FOR I=1 TO (#PDP10.WORDS.REQUIRED) TWV==0 ;; TWO-WORD-VALUE=0 REPEAT 2,< ;; FOR J=1 TO 2 (TO GET BOTH PDP11 WORDS) RAD3(,C,OWV) ;; GO GET 1 WORD OF 3 RAD50 CHARACTERS TWV==TWV_^D18 ;; MAKE ROOM BY PUTTING OLD IN LH TWV==TWV+OWV ;; ADD IN NEXT 3 CHARACTERS C==C+3 ;; POSITION TO GET NEXT 3 CHARACTERS > ;; LOOP TO GET BOTH PDP11 WORDS EXP TWV ;; DUMP OUT TWO PDP11 WORDS (INTO 1 PDP10 WORD) > ;;END REPEAT PAIRS ;; NEXT I (LOOP FOR ALL PDP10 WORDS NEEDED) >;;END DEFINE .RAD50 ;; MACRO TO EXTRACT 3 .RAD50 CHARACTERS FROM A STRING ARGUMENT DEFINE RAD3(S,C,OWV),< OWV==0 ;; ONE-WORD-VARIABLE STARTS OFF = 0 RC==0 ;; # OF RETURNED CHARACTERS = 0 CC==0 ;; CURRENT CHARACTER POSITION = 0 IRPC S,< IFL RC-3,> CC==CC+1> REPEAT 3-RC,;;LEFT JUSTIFY IT > ;; MACRO TO GENERATE PDP11 .ASCII STRINGS DEFINE .ASCII(S),< COUNT==0 ;; COUNT OF CHARACTERS TOTAL = 0 IRPC S, ;; COUNT THE NUMBER OF CHARACTERS IN STRING WORDS==COUNT/2 ;; COMPUTE # OF PDP11 WORDS IFN COUNT&1,;; ACCOUNT FOR POSSIBLE TRAILING BYTE PAIRS==WORDS/2 ;; COMPUTE # OF PDP10 WORDS (PAIRS OF PDP11 WDS) IFN WORDS&1,;; ACCOUNT FOR POSSIBLE TRAILING PDP11 WORD C==0 ;; START AT FIRST CHARACTER REPEAT PAIRS,< ;; FOR I = 1 TO (#PDP10.WORDS.NEEDED) TWV==0 REPEAT 2,< ;; FOR J= 1 TO 2 (ONCE FOR EACH HALF OF PDP10) ASC2(S,C,OWV) ;; GO GET 2 MORE BYTES TWV==TWV_^D18 ;; PUT PREVIOUS IN LH TWV==TWV+OWV ;; MERGE IN CURRENT 2 BYTES C==C+2 ;; ADVANCE PAST 2 MORE BYTES >;;END REPEAT 2 ;; NEXT J EXP TWV ;; DUMP OUT 4 ACCUMLATED BYTES >;;END REPEAT PAIRS >;;END DEFINE .ASCII ; MACRO TO EXTRACT (UP TO ) 2 ASCII BYTES FROM A LONG STRING DEFINE ASC2(S,C,OWV),< CC==0 ;;CURRENT CHARACTER POSITION RC==0 ;;# OF RETURNED CHARACTERS (IE: 0,1, OR 2) OWV==0 ;;16 BIT VALUE OF RETURNED CHARACTERS IRPC S, ;;RETURN 1ST CHAR IN "RH" IFN RC,>;;RETURN 2ND IN "LH" RC==RC+1>> CC==CC+1> > SUBTTL CODE F11: TDZA T1,T1 ;SET T1=0 FOR NORMAL ENTRY SETO T1, ;SET T1=-1 FOR CCL ENTRY MOVEM T1,CCLFLG ;INITIALIZE A FLAG TO REMEMBER RESET ; MOVE P,[IOWD PLEN,PSTAK] ;INIT THE STACK POINTER SETZ F, ;INIT THE FLAGS PUSHJ P,IMPURE ;GO INITIALIZE NECESSARY IMPURE DATA PROMPT: RELEAS TTY, ;FORCE FINAL STUFF OUT RESET ;FORGET FILES, ETC HLRZ T1,.JBSA## ;GET ORIGINAL SIZE CORE T1, ;RESTORE ORIGINAL SIZE JFCL ;IGNORE IT MOVE P,[IOWD PLEN,PSTAK] ;INIT THE STACK EXCH T1,LASTCH ;GET LAST CHARACTER CAIN T1,32 ;SKIP IF NOT ^Z EXIT 1, ;DO A SOFT EXIT IF ^Z SEEN SETZ F, ;INIT FLAGS SKPINL ;CLEAR ^O IF ANY JFCL ;IGNORE LIKELY NONSKIP RETURN SETZM BUF111 ;INDEXF NOT IN CORE ;< MATCH BRAKET IN LINE BELOW OUTSTR [ASCIZ .F11> .] ;PROMPT FOR INPUT PUSHJ P,SIXIN ;READ A POSSIBLE COMMAND VERB PUSHJ P,TRMSKP ;SKIP IFF END OF LINE AFTER VERB TDOA F,[X%REEAT] ;REEAT TERMINATOR JUMPE T1,.ERR ;REPROMPT ON BLANK LINES PUSHJ P,FNDIDX ;FIND INDEX OF COMMAND FROM TABLE CAI CMDSIX ;...USE SIXBIT TABLE "CMDSIX" SKIPGE T1 ;SKIP IF VALID COMMAND KEYWORD ILLCMD: ERROR ;CATCH ALL ERROR MESG HRRZM T1,CMDIDX ;SAVE THE COMMAND INDEX FOR LATER PUSHJ P,DOGETS ;GO DO UP-TO-THE-MINUTE GETTABs HRRZ T1,CMDIDX ;GET INDEX OF COMMAND PUSHJ P,@CMDADR(T1) ;GO EXECUTE THE COMMAND .ERR: PUSHJ P,SKEOL ;GET RID OF INPUT IF ANY LEFT JRST PROMPT ;AND LOOP FOR ANOTHER COMMAND SUBTTL COMMANDS DEFINE CC,< C ASSIGN,< ASSIGN (no arguments) List all currently assigned logical volume names. ASSIGN vol:= Forget logical volume name. ASSIGN vol:=str:file.ext[path] Create a logical volume. Logical volumes cannot be used in INI or DESTROY commands. > C BOOT,< BOOT vol:=str:file.ext[path] Copy the .BIN formatted input file onto the boot area of the volume. > C DELETE,< DELETE vol:file.typ;gen[uic]{,vol:file.typ;gen[uic],...} Delete a FILES-11 file. "Vol:" must be explicit. All other fields default to "*". N.B.: DELETE VOL: is the same as DELETE VOL:*.*;*[*,*] /FILE: delete file # from IBM, but don't try to deallocate FHB storage and don't try to fixup owning directory > C DESTRO,< DESTROY str:{,str:,str:,str:} Destroy the FILES-11 volume (if any) on the specified MOUNTed TOPS-10 file structure. "str:FE.SYS[1,4]" is deleted and the home blocks on "str:" are rewritten to remove the pointers to FE.SYS. > C DIRECT,< DIRECT {log file=}vol:file.typ;gen[uic]{,vol:file.typ;gen[uic],...} Give a "directory" ordered directory of a FILES-11 volume. List the FHB information for every file matching the FILES-11 file spec. Choose only files found in the system directory files. If "log file" is missing, the default is TTY:. "Vol:" must be explicit. All other missing components default to "*". /DETAILS list attribute and mapping information as well > C EXIT,< EXIT Exits from F11. > C GET,< GET {str:file.ext[p,pn]=}vol:file.typ;generation[uic] Copy files from the FILES-11 volume to the specified TOPS-10 structure. If "str:" is missing, DSK: is the default. If "[p,pn]" is missing, [-] is the default. "vol:" must be explicit. All other missing components default to "*". /IMAGE don't do data conversion /ASCII convert from PDP11 variable length ASCII (Generally speaking, a reasonable /IMAGE or /ASCII will be defaulted if both are omitted) > C HELP,< HELP Lists out brief list of commands. > C INDEX,< INDEX {log file=}str:{,str:,str:,str:,...} Give an "index" ordered directory of a FILES-11 volume. List the FHB information for every file on the structure. Choose files from the Index-bit-map rather than the directory files. If "log file" is missing, the default is TTY:. /DETAILS list attribute and mapping information as well > C INI,< INI str:{volumelabel}{[owner's UIC]} Create and initialize a FILES-11 volume on the MOUNTed TOPS10 str:. str: must be explicit. volumelabel is optional and defaults to blank. [owner's UIC] is optional and defaults to [1,1]. /CHARACTERISTIC:ATTACH allow 20F task to attach to volume. /CHARACTERISTIC:DCFUNC allow 20F device control functions. /EXTEND: (Default 5, minimum 1, maximum 127) /FPROTECTION:[default file protection for files on this volume] (Default is ) (/FPROTECTION can be given with notation, without giving a /FPROTECTION switch) /FULL allocate entire disk to RSX20F volume (N.B.: TOPS10 structures is destroyed!!) /INDEX:BEG allocate INDEXF.SYS near block 0 if possible /INDEX:BLK:nnn allocate INDEXF.SYS near block "nnn" if possible /INDEX:END allocate INDEXF.SYS on highest block possible /INDEX:MID allocate INDEXF.SYS near mid point of volume /MAXFIL: (default 65535, minimum 5, maximum 65535) /SIZE: (Default 2048, minimum about 150, no maximum) /VPROTECTION: (Default is <,,,>) > C PATH,< PATH vol:[uic] Setup defaults for "vol:" and "[uic]"; default default is vol:[*,*]. > C PUT,< PUT vol:file.typ;gen[uic]=str:file.ext[path]{,str:file.ext[path],...} Copy file(s) onto the front end area from the TOPS10 file system. "Vol:" must be explicit. "[uic]" must be explicit, but can be defaulted from PATH command. "[path]" defaults to [-]. ";gen" defaults to the "first free" gen number above the highest used. "str:" defaults to DSK:. All other missing fields default to "*". /FILE:n use file number "n" on output /IMAGE don't do any data conversion /ASCII convert to PDP11 varible length ASCII records /CONTIG set the "contiguous" bit in the FHB (Generally speaking, reasonable /IMAGE/ASCII/CONTIG switches will be defaulted if all are omitted) > C UFD,< UFD str:[uic]{,str:[uic],str:[uic...} Create a file directory for the specified UIC on the specified volume. str: is the TOPS10 name of the FILES-11 volume and must be explicit. [uic] must be explicit. The protection may be specified either via or /FPROTECTION. /ALLOCATE: /FPROTECTION: > C VOLUME,< VOLUME {log file=}str:{,str:,str:,str:,...} List some FILES-11 volume statistics to the TOPS10 log file. "str:" must be a MOUNTed TOPS-10 file structure. str: must be explicit. If "log file" is missing, the default is "TTY:". > > ; CREATE A BUNCH OF TABLES INDEXED BY COMMAND VERB'S INDEX DEFINE C(.a1,.a2),;BUILD SIXBIT TABLE OF COMMAND VERBS XLIST CMDSIX: CC 0 LIST DEFINE C(.a1,.a2),;BUILD ADDRESS TABLE OF COMMAND DISPATCHS XLIST CMDADR: CC LIST DEFINE C(.a1,.a2),;CREATE TABLE OF HELP TEXT POINTERS XLIST CMDTXT: CC LIST DEFINE c(.a1,.a2),;CREATE HELP TEXTS XLIST CC LIST SUBTTL COMMANDS -- ASSIGN ; THE ASSIGN COMMAND ALLOWS THE USER TO CREATE A "LOGICAL VOLUME". ; BY REFERRING TO A LOGICAL VOLUME NAME, THE USER CAN ACCESS A ; "FE.SYS" TYPE FILE WHICH NEED NOT RESIDE ON ANY TYPE OF DISK ; BLOCK NUMBER BOUNDRY, ETC. THUS, YOU CAN USE ORDINARY PIP COPY ; COMMANDS TO KEEP AN FE.SYS SOMEWHERE AND STILL BE ABLE TO ACCESS IT. C$ASSI: PUSHJ P,FILIN ;READ IN A FILE LIST SKIPN FP,IPLIST ;SKIP IF A LIST WAS GIVEN JRST C$VLSA ;LIST ALL OF THEM SKIPN .FXNAM(FP) ;MUST NOT BE A FILE NAME SKIPE .F2NAM(FP) ;... JRST ILLCMD ;COMPLAIN IF FILE NAME SKIPE .FXDEV(FP) ;MUST BE A VOLUME NAME SKIPE .FXDIR(FP) ;MUST NOT BE A DIRECTORY JRST ILLCMD ;COMPLAIN MOVE T1,[FX.EQL] ; TDNN T1,.FXMOD(FP) ;MUST BE AN = JRST C$VLST ;GO DO A LIST COMMAND HRRZ FP,.FXLNK(FP) ;ADVANCE TO FILE SPEC AFTER = JUMPE FP,C$VCLR ;BRANCH IF "CLEAR" REQUEST HRRZ FP,.FXLNK(FP) ;ADVANCE TO NEXT SPE JUMPN FP,ILLCMD ;MUST BE 2 AND ONLY 2 SPEX PJRST C$ASS1 ;GO DO ASSIGN ; HERE TO CLEAR AN ASSIGNED LOGICAL VOLUME NAME C$VCLR: PUSHJ P,SAVE1 MOVSI P1,-VOLMAX ;MAX # OF ENTRIES HRRZ FP,IPLIST ;LOAD PTR TO 1ST SPEC MOVE T1,.FXDEV(FP) ;LOAD VOLUME NAME SKIPN T2,VOLTBL(P1) ;GET IT'S VOLUME NAME C$CLR2: AOBJN P1,.-1 ;DO THEM ALL JUMPG P1,[ERROR ] CAME T2,.FXDEV(FP) ;IS THIS IT? JRST C$CLR2 ;BRANCH IF NO MATCH, TRY NEXT NAME MOVE FP,VOLPTR(P1) ;GET POINTER PUSH P,VOLTBL(P1) ;SAVE NAME SETZM VOLTBL(P1) ;ZERO NAME SO WE FORGET IT TYPE POP P,T1 ;GET BACK THE DELETED NAME PUSHJ P,SIXOUT ;TYPE NAME OF DELETED VOLUEM TYPE <:=> ;PRETTY STUFF PUSHJ P,TYPFDB ;TYPE USER'S FILE SPEC PJRST CRLF ; HERE TO LIST ALL LOGICAL VOLUMES C$VLSA: PUSHJ P,SAVE1 MOVSI P1,-VOLMAX C$VLA1: MOVE FP,VOLPTR(P1) ;GET POINTER TO THE FDB SKIPE VOLTBL(P1) ;SKIP IF NOT USED PUSHJ P,C$VLS0 ;JOIN COMMON CODE TO TYPE ONE DEF AOBJN P1,C$VLA1 ;LOOP FOR ALL POPJ P, ; HERE TO LIST A LOGICAL VOLUME C$VLST: PUSHJ P,SAVE1 MOVSI P1,-VOLMAX C$VLS1: MOVE T1,VOLPTR(P1) ;GET FDB POINTER CAME T1,.FXDEV(FP) ;SKIP IF WE FOUND A MATCH AOBJN P1,C$VLS1 ;KEEP TYRING JUMPGE P1,[ERROR ] MOVE FP,T1 ;COPY FDB POINTER C$VLS0: MOVE T1,VOLTBL(P1) ;GET NAME PUSHJ P,SIXOUT ;TYPE VOLUME NAME TYPE <:=> PUSHJ P,TYPFDB ;TYPE FILE SPEC FOR VOLUME MOVE T1,[S$IMAGE] ;GET THE /IMAGE MODE BIT TDNE T1,.FXSWT(FP) ;SKIP IF NOT /IMAGE MODE TYPE PJRST CRLF ; HERE TO CREATE A LOGICAL VOLUME NAME C$ASS1: HRRZ FP,IPLIST ;SET FP=1ST SPEC MOVE T1,.FXDEV(FP) ;GET VOLUME NAME MOVSI P1,-VOLMAX CAME T1,VOLTBL(P1) ;SKIP IF VOLUME ALREADY EXISTS AOBJN P1,.-1 ;BRANCH IF MORE VOLUMES TO CHECK JUMPLE P1,C$ASS2 ;BRANCH IF VOLUME ALREADY EXISTS MOVSI P1,-VOLMAX SKIPE VOLTBL(P1) ;SKIP IF VOLUME ENTRY FREE AOBJN P1,.-1 ;BRANCH IF MORE ENTRIES TO CHECK JUMPG P1,[ERROR ] C$ASS2: MOVEM T1,VOLTBL(P1) ;INSERT LOGICAL NAME HRRZ FP,.FXLNK(FP) ;STEP FP TO FILE NAME MOVEI T1,(FP) ;POINT AT FILE SPEC BLOCK MOVEI T2,OPNBLK ;POINT TO TOPS-10 OPEN/INIT BLOCK MOVEI T3,LERBLK ;POINT AT LOOKUP/RENAME/ENTER BLOCK MOVEI T4,PTHBLK ;POINT AT TOPS-10 PATH. BLOCK PUSHJ P,.STOPB## ;CALL SCAN TO EXPAND FILE SPEC BLOCKS ERROR MOVEI T1,.IODMP ;.IODMP IS TOPS-10 DUMP MODE MOVEM T1,OPNBLK ;FIXUP THE OPEN/INIT BLOCK OPEN FIO,OPNBLK ;ATTEMPT ACCESS TO HIS SPECIFIED DEVICE ERROR MOVEI T1,.RBSPL ;SETUP "LENGTH" WORD FOR LOOKUP BLOCK MOVEM T1,LERBLK+.RBCNT ;...INTO THE LOOKUP BLOCK LOOKUP FIO,LERBLK ;ATTEMPT ACCESS TO HIS SPECIFIED FILE ERROR MOVSI T1,(FP) ;GET POINTER = TEMP_FDB_ADR,,0 HRR T1,VOLPTR(P1) ;INSERT POINTER=TEMP_FDB_ADR,,PERM_ADR MOVEI T2,.FXLEN(T1) ;CALCULATE T2=LAST ADR IN PERM_FDB BLT T1,-1(T2) ;COPY TEMP FDB TO PERM FDB FOR THIS VOL MOVE T1,VOLTBL(P1) ;GET HIS SPECIFIED VOLUME NAME PUSHJ P,SIXOUT ;TYPE HIS SPECIFIED VOLUME NAME TYPE <:=> ;... PUSHJ P,TYPFIO ;TYPE REAL INFO MOVE T1,[S$IMAGE] TDNE T1,.FXSWT(FP) TYPE PUSHJ P,CRLF RELEAS FIO, ;DROP CONNECTION TO VOLUME FILE POPJ P, ;DONE SUBTTL COMMANDS -- BOOT ; "BOOT" READS A PDP11 .BIN FORMATTED FILE. ; IT CONSTRUCTS AN INCORE IMAGE OF WHAT THE PDP11 WOULD HAVE. ; IT WRITES THAT IMAGE TO DISK TO ABSOLUTE BLOCK NUMBERS IN 1:1 STYLE. ; IE: PDP11 ADDRESS 0 GOES TO BLOCK 0 WORD 0, ADDRESS 1000 GOES ; TO BLOCK 1 WORD 0, ETC. USED TO PUT "FELOAD" (IN PARTICULAR) ONTO ; BLOCKS 0 THRU 3 WHICH ARE STILL (APPARENTLY) NOT USED BY TOPS-10. C$BOOT: PUSHJ P,FILIN ;READ IN A FILE LIST SKIPN FP,IPLIST ;SKIP IF A LIST GIVEN JRST ILLCMD ; SKIPN .FXNAM(FP) ;SKIP IF OUTPUT FILE NAME GIVEN SKIPE .F2NAM(FP) ;SKIP IF OUTPUT FILE NAME NOT GIVEN JRST ILLCMD ;COMPLAIN IF OUTPUT FILE NAME GIVEN SKIPE .FXDIR(FP) ;SKIP IF OUTPUT PATH NOT GIVEN JRST ILLCMD ;COMPLAIN IF OUTPUT PATH GIVEN MOVE T1,[FX.EQL] ;GET THE "EQUAL SEEN" BIT TDNN T1,.FXMOD(FP) ;MUST BE = SIGN IN OUTPUT SPEC JRST ILLCMD ;COMPLAIN IF NO = SEEN AFTER OUTPUT SPEC HRRZ FP,.FXLNK(FP) ;GET LINK TO NEXT FILE JUMPE FP,ILLCMD ;COMPLAIN IF NO FILE AFTER THE = HRRZ FP,.FXLNK(FP) ;GET LINK TO NEXT FILE JUMPN FP,ILLCMD ;COMPLAIN IF THERE IS MORE THAN 1 INPUT PUSHJ P,SAVFF ;SAVE CORE BOUNDS PJRST C$BOT1 ;GO DO BOOT ; SETUP THE OUTPUT FILE (IE: THE VOLUME) C$BOT1: HRRZ FP,IPLIST ;LOAD FP TO POINT AT VOLUME NAME PUSHJ P,OPNVIO ;OPEN FOR I/O SKIPE FAKVOL ;SKIP IF VOLUME IS REAL ERROR ; SETUP THE INPUT FILE, THE .BIN FORMATTED FILE HRRZ FP,.FXLNK(FP) ;POINT AT INPUT FILE MOVEI T1,(FP) ;POINT AT FILE SPEC BLOCK MOVEI T2,OPNBLK ;POINT AT OPEN DEVICE BLOCK MOVEI T3,LERBLK ;POINT AT LOOKUP BLOCK MOVEI T4,PTHBLK ;POINT AT PATH BLOCK PUSHJ P,.STOPB## ;SET ALL UUO BLOCKS ERROR MOVE T1,[.IODMP] ;DUMP MODE MOVEM T1,OPNBLK+0 ;SET IT SETZM OPNBLK+2 ;NO BUFFERS OPEN FIO,OPNBLK ;OPEN IT ERROR MOVEI T1,.RBVER ;GET T1=SIZE OF LOOKUP BLOCK MOVEM T1,LERBLK+.RBCNT ;SETUP LOOKUP BLOCK SIZE LOOKUP FIO,LERBLK ;FIND INPUT FILE ERROR ; SHARP OBSERVERS WILL NOTE A SIMILARITY TO THE LOAD .BIN FILE CODE ; UPON KLDCP, UPON WHICH THIS CODE WAS LIGHTLY BASED SETZM BOTCNT ; SETZM BOTPTR ; SETZM LASTHI ; LOAD A "CHUNK" OF PDP11 BINARY CODE LDBINY: SETZM CHKVAL ;INIT CHECKSUM FOR THIS RECORD PUSHJ P,G10BYT ;GET PDP11 BYTE FROM PDP10 FILE SOJN T1,LDBINY ;IGNORE EVERYTHING TILL WE FIND A "1" PUSHJ P,G10BYT ;IGNORE BYTE FOLLOWING THE "1" PUSHJ P,G10WRD ;GET PDP11 WORD FROM PDP10 FILE SUBI T1,6 ;SUBTRACT 6 FROM THIS WORD COUNT JUMPE T1,LJMP ;IF WC=6, THEN THIS IS AN XFER RECORD MOVEM T1,LBC ;SAVE COUNT OF REMAINING DATA PUSHJ P,G10WRD ;GET PDP11 WORD, LOAD ADDRESS MOVE P1,T1 ;SAVE P1=LOAD ADDRESS CAIL P1,BOTBLK*200*4 ;SKIP IF IN RANGE ERROR
PUSHJ P,TELHGH ;MENTION PREVIOUS HIGH TYPE MOVE T1,P1 ;GET BACK THE LOAD ADDRESS PUSHJ P,OCTOUT ;TYPE THE LOAD ADDRESS LDBIN2: PUSHJ P,G10BYT ;GET A BYTE SOS T2,LBC ;ADJUST BYTE COUNT TO ACCOUNT FOR IT JUMPGE T2,LDBIN3 ;BRANCH IF THAT WAS NOT LAST BYTE SKIPE CHKVAL ;SKIP IF CHECKSUM ENDED UP 0S error JRSt LDBINY ;GO IF CHECKSUM WAS OK LDBIN3: MOVE P2,P1 ;COPY ADDRESS OF BYTE IDIVI P2,4 ;CONVERT TO PDP10 WORD IN P2, BYTEIN P3 DPB T1,[POINT 8,BOTBUF(P2),17 ; 0 POINT 8,BOTBUF(P2),9 ; 1 POINT 8,BOTBUF(P2),35 ; 2 POINT 8,BOTBUF(P2),27](P3) ; 3 MOVEM P1,LASTHI ;REMEMBER HIGHEST ADDRESS SO FAR CAML P1,HIHIGH ;SKIP IF NOT ABSOLUTE HIGHEST SO FAR MOVEM P1,HIHIGH ;REMEMBER ABSOLUTE HIGHEST AOJA P1,LDBIN2 ;LOOP BACK TO LOAD MORE BYTES ; HERE WHEN ALL DONE LJMP: PUSHJ P,TELHGH ;MENTION HIGHEST ADDR EVER LOADED PUSHj P,G10WRD ;GO GET POSSIBLE XFER ADDRESS PUSH P,T1 ;SAVE WHAT MAY BE XFER ADDR PUSHJ P,G10BYT ;GET NEXT BYTE SKIPE CHKVAL ;MAKE SURE WE ENDED UP WITHOUT ERROR ERROR POP P,T1 ;RESTORE XFER ADDR TYPE < Xfer address = > PUSHJ P,OCTOUT ;TYPE XFER ADDR TYPE < Highest address loaded = > CAMG P1,HIHIGH ;SKIP IF LAST RECORD WAS HIGHEST SKIPA T1,HIHIGH ;ELSE LOAD AND SKIP IF NOT SOS T1,P1 ;CONVERT TO LAST LOADED FROM FIRST FREE PUSHJ P,OCTOUT ;MENTION HIGHEST ADDRESS MOVSI T3,-BOTBLK ;# OF BLOCKS IN BOOT BUFFER ;SCAN THE INCORE BUFFER AND FIND NON-ZERO BLOCKS TO WRITE TO DISK LDBNLP: MOVEI T1,(T3) ;COPY BLOCK # IMULI T1,^O200 ;CONVERT TO OFFSET ADDRESS MOVEI T2,(T1) ;COPY CURRENT memory ADDRESS HRLI T2,-200 ;CONSTRUCT AOBJN SKIPN BOTBUF(T2) ;ANYTHING IN THIS WORD AOBJN T2,.-1 ;OR IN THIS BLOCK? JUMPGE T2,SKPBLK ;NO, SKIP THIS BLOCK MOVEI T1,(T3) ;GET BLOCK NUMBER PUSHJ P,SUSET ;POSITION TO IT MOVEI T1,(T3) ;COPY DISK BLOCK # IMULI T1,^O200 ;COMPUTE OFFSET ADDI T1,BOTBUF-1 ;CONVERT TO ABSOLUTE DF10 ADDRESS HRLI T1,-200 ;# OF WORDS TO WRITE TO DISK SETZ T2, ;END THE IO LIST OUTPUT VIO,T1 ;OUTPUT THE BLOCK SKPBLK: AOBJN T3,LDBNLP ;ADVANCE AND LOOP PJRST CRLF ; G10WRD - GET A PDP11 WORD (2 BYTES) G10WRD: PUSHJ P,G10BYT ;GET A BYTE PUSH P,T1 ;SAVE IT PUSHJ P,G10BYT ;GET ANOTHER BYTE LSH T1,^D8 ;MAKE ROOM FOR 1ST BYTE GOTTEN POP P,T2 ;GET BACK 1ST BYTE OR T1,T2 ;COMBINE POPJ P,0 ;RETURN THE WORD ; G10BYT - GET A PDP11 BYTE G10BYT: SKIPE PFLAG ;SKIP IF NOT PACKED 4 PER PDP10 WORD JRST GETPAK ; BRANCH TO GET DATA FROM PACKED WORDS SOSGE BOTCNT ;SKIP IF THERE ARE BYTES LEFT IN BUFFER JRST GETBUF ; BRANCH IF THE BUFFER IS EMPTY AOS T1,BOTPTR ;GET POINTER TO BYTE MOVE T1,(T1) ;GET BYTE FROM BUFFER MOVE T2,CHKVAL ;GET CURRENT CHECKSUM ADD T2,T1 ;COMPUTE NEW CHECKSUM ANDI T2,377 ;KEEP ONLY LOW BYTE OF CHECKSUM DATA MOVEM T2,CHKVAL ;RESTORE CHECKSUM POPJ P,0 ;HERE TO EXTRACT THE NEXT BYTE IF BUFFER IS IN PACKED MODE GETPAK: MOVE T1,BYTNUM ;GET NUMBER OF THIS BYTE IDIVI T1,4 ;COMPUTE WORD/BYTE IT FALLS IN CAIN T1,^D128 JRST GETBUF ;GET NEXT BOTDAT MOVE T1,BOTDAT(T1) ;GET THE WORD LDB T1,[POINT ^D8,T1,17 POINT ^D8,T1,9 POINT ^D8,T1,35 POINT ^D8,T1,27](T2) AOS T2,BYTNUM ;GET NEXT BYTE NEXT TIME POPJ P,0 ;HERE TO READ ANOTHER PDP10 DISK BLOCK FROM .BIN FILE GETBUF: INPUT FIO,[IOWD 200,BOTDAT 0] SETZM BYTNUM ;START WITH BYTE 0 MOVEI T1,^D128;INITIALIZE COUNT TO 128 (IE: 1 BYTE / 1 PDP10 WORD) MOVEM T1,BOTCNT ;INITIALIZE THE COUNTER MOVEI T1,BOTDAT-1 ;POINT AT DATA MOVEM T1,BOTPTR ;INITIALIZE THE POINTER ;LOOP THRU DATA AND SET "PFLAG" IF THE HIGH BITS ARE USED IN THE ;PDP10 WORD (WHICH WOULD IMPLY DATA IS PACKED 4 PDP11 BYTES PER 1 PDP10 WORD) MOVE T1,[-200,,BOTDAT] MOVE T2,[-1,,777400] TDNE T2,(T1) SETOM PFLAG ;PACKED AFTER ALL AOBJN T1,.-2 ;LOOK THRU ENTIRE BOTDAT IN CASE PATHOGENIC DATA JRST G10BYT ;ROUTINE TO MENTION THE RANGE OF THE LAST LOADED RECORD FROM THE .BIN FILE TELHGH: SKIPN LASTHI POPJ P, TYPE < THRU > MOVE T1,LASTHI PUSHJ P,OCTOUT PJRST CRLF SUBTTL COMMANDS -- EXIT C$EXIT: MONRT. ;EXIT TO MONITOR POPJ P, ;IF CONTINUE TYPED SUBTTL COMMANDS -- PATH C$PATH: PUSHJ P,TTYPHY ;SETUP TTY: PUSHJ P,FILIN ;READ IN A SPEC SKIPN FP,IPLIST ;MUST BE 1 SPEC PUSHJ P,ILLCMD ;ELSE SYNTAX ERROR SKIPE .FXLNK(FP) ;MUST BE *ONLY* ONE PUSHJ P,ILLCMD MOVSI T1,(FP) ;ORIGIN FDB HRRI T1,DEFFDB ;DEFAULT FDB BLT T1,DEFFDB+.FXLEN-1 ;COPY TO DEFAULT FDB POPJ P, SUBTTL COMMANDS -- HELP .HELPR::ERROR <.HELPR is not loaded> C$HELP: PUSHJ P,TTYPHY ;SETUP TTY: TYPE < F11 is a simple minded program to maintain a front end disk pack > MOVEI T1,CMDTXT C$HEL0: SKIPN CMDSIX-CMDTXT(T1) ;SKIP ANY MORE COMMANDS JRST C$HEL1 MOVE P1,(T1) HRLI P1,(POINT 7,0) PUSHJ P,TYPE.1 AOJA T1,C$HEL0 C$HEL1: PUSHJ P,TYPE.. CAI ENDING PJRST CRLF ENDING: ASCIZ @ The str:/vol: must be MOUNTed to TOPS10 for all commands, except INI/FULL. The disk: must be DIS-MOUNTed to TOPS10 for INI/FULL. INI/FULL will COMPLETELY DESTROY the TOPS10 file structure on disk:. All switches in all commands are optional - a (hopefully) reasonable action is taken in their absence. All missing parts of all file specifications are always wild, except vol:. vol: must always be specified and can never be wild. F11 should not be used at all if the vol/str/disk is "MOU"nted to RSX20F. @ SUBTTL COMMANDS -- INDEX C$INDE: PUSHJ P,FILIN ;GET A FILE SPECIFICATION SETZM TOTFIL ;INIT FILE TOTALS SETZM TOTBLK SKIPN FP,IPLIST ;LOAD POINTER TO LIST OF FILES MOVEI FP,DEFFDB PUSHJ P,SETTTY ;SETUP TERMINAL OUTPUT FILE C$IND0: PUSHJ P,C$IND1 ;CALL INDEX SUBROUTINE HRRZ FP,.FXLNK(FP) ;STEP TO NEXT SPEC, IF ANY JUMPN FP,C$IND0 ;LOOP IF ANOTHER PJRST TYPTOT ;TELL TOTALS AND EXIT ; SUBROUTINE TO DO AN "INDEX" OF THE "CURRENT" FILE SPEC (IE: @FP) C$IND1: PUSHJ P,SAVFF ;SAVE CORE FOR COLLAPSE LATTER PUSHJ P,OPNVOL ;GO OPEN THE VOLUME MOVEI P1,1 ;START WITH FILE #1 C$IND2: MOVEI T1,-1(P1) ;GET IBM NUMBER IDIVI T1,^D32 ; ADD T1,IBMINC ;COMPUTE WORD ADDRESS FOR THAT FHB MOVE T2,B32TBL(T2) ;FIND MASK FOR THAT FHB TDNN T2,@T1 ;SKIP IF THAT FHB IN USE JRST C$IND3 ;BRANCH IF FHB NOT IN USE AOS TOTFIL ;COUNT A FILE MOVEI T1,(P1) ;COPY FILE # MOVEI T2,FHBBUF ;READ INTO NORMAL BUFFER PUSHJ P,REDFHB ;READ THE FHB FOR THAT FILE MOVEI T1,FHBBUF PUSHJ P,TYPFHB ;TYPE INFO ON THAT FHB C$IND3: ADDI P1,1 ;STEP TO NEXT FILE # LOAD. T1,FMAX ;GET MAX # FILES CAMG P1,T1 ;SKIP IF END OF FILES JRST C$IND2 ;GO DO NEXT ONE TOO POPJ P, ;RETURN TO CALLER,INDIRECTLY THRU SAVFF SUBTTL COMMANDS -- DELETE C$DELE: PUSHJ P,TTYPHY ;FORCE OUTPUT TO PHYSICAL TTY ONLY PUSHJ P,FILIN ;GO GET FILE LIST SKIPN FP,IPLIST ;MUST BE AT LEAST 1 FILE PUSHJ P,ILLCMD ;GO COMPLAIN IF NO FILES SEEN C$DEL0: MOVE T1,[FX.EQL] ;MUST NOT BE ANY =S TDNE T1,.FXMOD(FP) ;SKIP IF NO =S SEEN PUSHJ P,ILLCMD ;COMPLAIN IF =S SEEN HRRZ FP,.FXLNK(FP) ;STEP TO NEXT FILE IF ANY JUMPN FP,C$DEL0 ;AND LOOP TO CHECK FOR = IN ALL FILES MOVE FP,IPLIST ;POINT AT 1ST FILE AGAIN PUSHJ P,C$DEL1 ;GO DELETE A FILE HRRZ FP,.FXLNK(FP) ;STEP TO NXT FILE, IF ANY JUMPN FP,.-2 ;LOOP FOR ALL FIELS POPJ P,0 ; HERE TO DELETE ALL FILES IN A SINGLE SPEC C$DEL1: PUSHJ P,SAVFF ;SAVE CORE TDZ F,[X%INTRO] ;INDICATE HERALD NOT YET TYPED PUSHJ P,OPNVOL ;OPEN THE FILES-11 VOLUME PUSH P,VOLTAL ;SAVE VOLUME FREE TALLY FOR LATER PUSHJ P,RLDINI ;INITIALIZE THE WILD CARD READER MOVE T1,.FXSWT(FP) ;GET SWITCHES TDNE T1,[S$FILE] ;/FILENUMBER? JRST C$DEL5 ;YES, GO DO SPECIAL WORK C$DEL2: MOVEI T1,(FP) ;POINT AT THIS BLOCK MOVEI T2,DELFDB ;POINT AT THE DELETE FDB PUSHJ P,NXTFDB ;FIND A FILE TO DELETE JRST C$DEL4 ;GO UPDATE THE IBM/SBM MOVE T1,.FXNUM+DELFDB ;GET FILE NUMBER MOVEI T2,FHBBUF ;GET BUFFER FOR FHB PUSHJ P,REDFHB ;GO READ THE FHB FOR THAT FILE PUSHJ P,DELCHK ;SKIP IF PERMISSIBLE TO DELETE TYPE <% Cannot delete file >,C$DEL3 MOVEI T1,FHBBUF ;POINT AT INCORE FHB PUSHJ P,DELFHB ;GO DLEETE IT TDON F,[X%INTRO] ;SKIP IF HERALD ALREADY TYPED TYPE C$DEL3: MOVEI T1,FHBBUF ;POINT AT INCORE FHB PUSHJ P,TYPFHU ;TYPE INFO ON THAT FHB PUSHJ P,CRLF ;TYPE CRLF JRST C$DEL2 ;LOOP FOR ANOTHER MATCH ;HERE AFTER DELETING ALL FILES MATCHES A SINGLE FILE SPEC C$DEL4: PUSHJ P,WRTSBM ;UPDATE THE SBM PUSHJ P,WRTIBM ;UPDATE THE IBM POP P,T1 ;GET BACK THE ORIGINAL FREE TALLY MOVNS T1 ;-VE FREE TALLY ADD T1,VOLTAL ;COMPUTE # OF BLOCKS FREED JUMPE T1,CPOPJ ;DON'T MENTION IT IF NONE HAPPENED PUSHJ P,DECOUT TYPE < blocks freed> PJRST CRLF ;ALL DONE ;HERE IF USER GAVE DELETE/FILE:n C$DEL5: MOVE T1,V$FILE(FP) ;GET FILE NUMBER OF FILE TO DELETE SUBI T1,1 ;GET BIT NUMBER FOR THE FILE IDIVI T1,^D32 ;COMPUTE WORD IN MAP ADD T1,IBMINC ;COMPUTE ADDRESS OF CORRECT BIT MOVE T2,B32TBL(T2) ;GET CORRECT BIT ANDCAM T2,@T1 ;TURN OFF BIT IN INDEX MAP JRST C$DEL4 ;REJOIN COMMON CODE ;ROUTINE TO CHECK IF DELETING A FILE MIGHT CAUSE A CORRUPT STRUCTURE ;DON'T ALLOW DELETE OF THE "KNOWN" FILES INDEXF,BITMAP,BADBLK,CORIMG,000000 ;DON'T ALLOW DELETE OF "PROTECTED" FILES *.NDL;*[*] ;DON'T ALLOW DELETE OF .DIR FILES THAT CONTAIN ACTIVE ENTRIES DELCHK: MOVE T1,.FXSWT(FP) ;GET SWITCHES TDNE T1,[S$NOCHECK] ;SKIP IF NOT /NOCHECK JRST CPOPJ1 ;ALLOW IT IF /NOCHECK MOVE T1,.FXNUM+DELFDB ;GET FILE'S NUMBER HLRZ T2,.FXEXT+DELFDB ;GET FILE'S TYPE CAILE T1,4 ;SKIP IF A KNOWN FILE CAIN T2,'NDL' ;SKIP IF NOT PROTECTED FILE POPJ P, ;BAD RETURN IF KNOWN FILE OR DIRECTORY CAIE T2,'DIR' ;SKIP IF A DIRECTORY FILE JRST CPOPJ1 ;GIVE SKIP (GOOD) RETURN PUSHJ P,SAVE1 ;SAVE SOME ACS MOVSI P1,-^D100 ;I HOPE NO DIR FILE IS EVEN THIS BIG! DELCH1: MOVEI T1,FHBBUF ;POINT AT THE INCORE FHB MOVEI T2,(P1) ;GET RBN OF DIR FILE PUSHJ P,SCNRET ;FIND THIS RBN JRST CPOPJ1 ;IF WE RUN OUT OF BLOCKS, THEY'RE ALL 0S PUSHJ P,SUSET ;POSITION TO IT IN VIO,[IOWD 200,TMPBUF ;READ IN THE DIRECTORY DATA BLOCK 0] ; SKIPA T1,[-200,,0] ;SET UP AOBJN POINTER IF I/O IS GOOD TYPE <% I/O error scanning directory entries>,CRLF SKIPN TMPBUF(T1) ;SKIP IF WE FOUND SOME DATA AOBJN T1,.-1 ;LOOP UNTIL WE SCAN ENTIRE BLOCK JUMPL T1,CPOPJ ;EXIT IF WE FIND DATA IN BLOCK AOBJN P1,DELCH1 ;ADVANCE TO NEXT BLOCK POPJ P, ;IF WE RUN OUT OF BLOCKS, WE LOSE ;ROUTINE TO ZERO THE OWNING DIRECTORY'S POINTERS TO A FILE ;WHICH HAS BE LOCATED VIA THE "WILD 20F" MECHANISM DELFHB: PUSHJ P,RETFHB ;RETURN FHB TO FREE POOL MOVE P1,WDIOFF ;GET POINTER USED BY WILD SCANNER SUBI P1,.DIROFF ;BACK OFF TO PREVIOUS (MATCHING) RECORD STOR. [0],UFN1,P1 ;STORE 0S STOR. [0],UFN2,P1 ;...INTO ALL STOR. [0],UFN3,P1 ;...OF THE STOR. [0],UFTY,P1 ;...DIRECTORY STOR. [0],UFNO,P1 ;...ENTRY STOR. [0],UFSQ,P1 ;... STOR. [0],UFRV,P1 ;... STOR. [0],UVER,P1 ;... PUSHJ P,UPDDIR ;GO UPDATE THE DIRECTORY TYPE <% OUT UUO failed to update directory and remove file reference > POPJ P,0 ;ROUTINE TO RE-WRITE THE LAST DIRECTORY BLOCK SCANNED BY THE WILD SCANNER ;USED TO HANDLE INSERTS, DELETES, RENAMES, ETC UPDDIR: MOVE T1,WDIPBN ;GET BLOCK WHERE FILE NAME IS PUSHJ P,SUSET ;POSITION DISK OUT VIO,[IOWD 200,WDIBUF ;...WRITE OUT DIRECTORY BLOCK WITHOUT FILE 0] ; JRST CPOPJ1 POPJ P, ;RETURN SUBTTL COMMANDS -- DIRECT C$DIRE: PUSHJ P,FILIN ;GET A FILE SPECIFICATION SETZM TOTFIL SETZM TOTBLK SKIPN FP,IPLIST ;SKIP IF THERE WAS A FILE MOVEI FP,DEFFDB ;USE DEFAULT VOL SPEC IF OMITTED PUSHJ P,C$DIR0 ;CALL SUBROUTINE TO DO "DIR" COMMAND HRRZ FP,.FXLNK(FP) ;POINT TO NEXT FILE SPEC, IF ANY JUMPN FP,.-2 ;LOOP IF ANOTHER TYPTOT: TYPE ; MOVE T1,TOTBLK PUSHJ P,DECOUT TYPE < blocks in > MOVE T1,TOTFIL PUSHJ P,DECOUT TYPE < files> JRST CRLF ;RETURN ;SUBROUTINE TO DO A "DIRECT" COMMAND ON THE CURRENT INPUT SPEC C$DIR0: PUSHJ P,SAVFF ;SAVE CORE LIMITS FOR COLLAPSE LATTER PUSHJ P,SAVE1 ;SAVE AN AC PUSHJ P,SETTTY ;SETUP TTY OUTPUT FILE IF ANY PUSHJ P,OPNVOL ;OPEN THE VOLUME FOR I/O PUSHJ P,RLDINI ;INITIALIZE RSX20F WILD CARD FILE SETO P1, ;"REMEMBER" OLD UFD NAME C$DIR1: MOVEI T1,(FP) ;POINT AT INPUT FDB MOVEI T2,INPFDB ;PUT RSX20F FILE IN INPFDB PUSHJ P,NXTFDB ;GET A FILE BLOCK JRST [RELEAS TTY, POPJ P,0] ;RETURN WHEN NO MORE MATCHES AOS TOTFIL PUSHJ P,UFDCHK ;CHECK FOR DIRECTORY CHANGE MOVE T1,.FXNUM+INPFDB ;GET ABSOLUTE FILE # MOVEI T2,FHBBUF ;READ INTO NORMAL BUFFER PUSHJ P,REDFHB ;READ FHB PUSHJ P,CHKFNM ;CHECK IF FILE NAME IN DIRECTORY AND ; FHB MATCH, PRINT MESSAGE IF NOT MOVEI T1,FHBBUF ;POINT AT THIS FILE'S FHB PUSHJ P,TYPFHB ;TYPE FHB JRST C$DIR1 ;GO TO NEXT FILE ;ROUTINE TO GIVE A CRLF BETWEEN DIRECTORYS UFDCHK: CAMN P1,DIRCNT ;SKIP IF DIRECTORY CHANGED POPJ P, ;EXIT IF DIRECTORY STAYED THE SAME MOVE P1,DIRCNT ;REMEMBER THE DIRECTORY PUSHJ P,CRLF ;GIVE A BLANK LINE MOVE T1,FEUNIT ;GET NAME OF CURRENT FILE'S VOLUME PUSHJ P,SIXOUT ;TYPE CURRENT FILE'S VOLUME TYPE <:> ;TYPE SEPERATOR DMOVE T1,UFDNAM ;GET DIRECTORY NAME PUSHJ P,TYPDIN ;TYPE DIRECTORY NAME PJRST CRLF ;ROUTINE TO CHECK IF FILE NAME IN DIRECTORY ENTRY AND FHB MATCH. ;IF NOT, A MESSAGE IS PRINTED. WDIOFF CONTAINS DIRECTORY, FHBBUF ;CONTAINS FHB. CHKFNM: PUSHJ P,SAVE2 ;FREE UP AN AC OR TWO MOVE P1,WDIOFF ;GET DIRECTORY ENTRY ADDRESS SUBI P1,.DIROFF ;(WAS POST-INCREMENTED) MOVEI P2,FHBBUF-FHBBUF ;OFFSET FOR FHB LOAD. T1,UFN1,P1 ;GET FIRST PART OF NAME LOAD. T2,FNM1,P2 ;DITTO FROM FHB CAME T1,T2 ;MATCH? JRST CHKFNE ;NO LOAD. T1,UFN2,P1 ;GET SECOND PART OF NAME LOAD. T2,FNM2,P2 ;DITTO FROM FHB CAME T1,T2 ;MATCH? JRST CHKFNE ;NO LOAD. T1,UFN3,P1 ;GET THIRD PART OF NAME LOAD. T2,FNM3,P2 ;DITTO FROM FHB CAME T1,T2 ;MATCH? JRST CHKFNE ;NO LOAD. T1,UFTY,P1 ;GET TYPE LOAD. T2,FTYP,P2 ;DITTO FROM FHB CAME T1,T2 ;MATCH? JRST CHKFNE ;NO LOAD. T1,UVER,P1 ;GET VERSION LOAD. T2,FVER,P2 ;DITTO FROM FHB CAMN T1,T2 ;MATCH? POPJ P, ;FHB AND DIRECTORY MATCH CHKFNE: TYPE <% Name in header block of > LOAD. T1,UFN1,P1 ;GET 1ST WORD OF FILE NAME LOAD. T2,UFN2,P1 ;GET 2ND WROD OF FILE NAME LOAD. T3,UFN3,P1 ;GET 3RD WORD OF FILE NAME PUSHJ P,FILE5O ;TYPE OUT FILE NAME TYPE <.> LOAD. T1,UFTY,P1 SETZB T2,T3 ;DON'T WANT EXTRA SPACING PUSHJ P,FILE5O TYPE <;> LOAD. T1,UVER,P1 ;GET VERSION # PUSHJ P,OCTOUT ;TYPE IT TYPE < is > LOAD. T1,FNM1,P2 ;GET 1ST WORD OF FILE NAME LOAD. T2,FNM2,P2 ;GET 2ND WROD OF FILE NAME LOAD. T3,FNM3,P2 ;GET 3RD WORD OF FILE NAME PUSHJ P,FILE5O ;TYPE OUT FILE NAME TYPE <.> LOAD. T1,FTYP,P2 SETZB T2,T3 ;DON'T WANT EXTRA SPACING PUSHJ P,FILE5O TYPE <;> LOAD. T1,FVER,P2 ;GET VERSION # PUSHJ P,OCTOUT ;TYPE IT PJRST CRLF ;END WITH NEW LINE SUBTTL COMMANDS -- VOLUME C$VOLU: PUSHJ P,FILIN ;GET A FILE SPECIFICATION SKIPN FP,IPLIST ;LOAD INPUT FILE LIST POINTER MOVEI FP,DEFFDB PUSHJ P,SETTTY ;SETUP TERMINAL OUTPUT FILE PUSHJ P,C$VOL0 ;DO THE "VOLUME" COMMAND TO ONE SPEC HRRZ FP,.FXLNK(FP) ;STEP TO NEXT FIEL SPEC, IF ANY JUMPN FP,.-2 ;LOOP IF ANOTHER FILE SPEC POPJ P,0 ;TYPE RANDOM INFORMATION EXTRACTED FROM A VOLUME'S FILES-11 HOME BLOCK C$VOL0: PUSHJ P,SAVFF ;SAVE .JBFF PUSHJ P,OPNVOL ;GO OPEN THE VOLUME TYPE MOVE T1,[XWD O.VDAY,A.VDAY] ;GET PDP11 BYTE POINTER SETZ P1, ;NO OFFSET PUSHJ P,TYPDAT ;TYPE DATE TYPE < > MOVE T1,[XWD O.VHOR,A.VHOR] ;GET BYTE POINTER SETZ P1, ;NO OFFSET PUSHJ P,TYPTIM ;TYPE CREATION TIME PUSHJ P,CRLF TYPE MOVE T1,H11LBN ;GET BLOCK NUMBER OF HOME BLOCK PUSHJ P,OCTOUT ;TYPE BLOCK NUMBER OF HOME BLOCK PUSHJ P,CRLF TYPE MOVE T1,FSTLBN ;GET FIRST BLOCK # ALLOCATED TO VOLUME PUSHJ P,OCTOUT ;TYPE FIRST BLOCK # ALLOCATED TO VOLUME TYPE < through block > MOVE T1,LSTLBN ;GET LAST BLOCK # ALOCATED TO VOLUME PUSHJ P,OCTOUT ;TYPE LAST BLOCK # ALLOCATED TO VOLUME PUSHJ P,CRLF MOVE T1,LSTLBN ;GET LAST LBN IN VOLUME SUB T1,FSTLBN ;GET FIRST LBN IN VOLUME ADDI T1,1 ;1 MORE PUSHJ P,DECOUT ;TYPE COMPUTED # BLOCKS IN VOLUME TYPE < blocks allocated to FILES-11 volume, > MOVE T1,VOLTAL ;GET # BLOCKS SEEN AS FREE PUSHJ P,DECOUT ;TYPE # BLOCKS SEEN AS FREE TYPE < blocks free> PUSHJ P,CRLF TYPE MOVE T1,IBMLBN ;GET INDEX-BIT-MAP LOCATION PUSHJ P,OCTOUT ;TYPE LOCATION OF INDEX-BIT-MAP TYPE <, > LOAD. T1,IBSZ ;GET SIZE OF INDEX-BIT-MAP PUSHJ P,DECOUT ;TYPE SIZE OF INDEX-BIT-MAP TYPE < blocks long> PUSHJ P,CRLF LOAD. T1,FMAX ;GET MAX # OF FILES PERMITTED PUSHJ P,DECOUT ;TYPE MAX# OF FILES PERMITTED TYPE < files possible, > MOVE T1,FHBTAL ;GET TALLY OF FREE FHBS PUSHJ P,DECOUT ;TYPE TALLY OF FREE FHBS TYPE < files remain unallocated> ; MORE OF THE VOLUME INFO CODE PUSHJ P,CRLF TYPE LOAD. T1,SBCL ;GET VOLUME'S SBM CLUSTER SIZE PUSHJ P,DECOUT ;TYPE CLUSTER SIZE PUSHJ P,CRLF ;START A NEW LINE TYPE LOAD. T1,DVTY ;GET DISK DEVICE TYPE PUSHJ P,OCTOUT ;TYPE IT PUSHJ P,CRLF ;START A NEW LINE TYPE ; LOAD. T1,VLEV ;GET STRUCTURE LEVEL PUSHJ P,OCTOUT ;TYPE IT PUSHJ P,CRLF TYPE MOVE T1,[XWD O.VNAM,A.VNAM] ;GET PDP11 BYTE POINTER PUSHJ P,TYPS12 ;TYPE 12 BYTES (IE: VOLUME NAME) TYPE <"> PUSHJ P,CRLF TYPE LOAD. T1,VOWN ;GET UIC LSH T1,-^D8 ;CHOP OFF RIGHT HALF PUSHJ P,OCTOUT ;TYPE FIRST PART OF UIC TYPE <,> LOAD. T1,VOWN ;GET UIC ANDI T1,377 ;CHOP OFF LEFT HALF PUSHJ P,OCTOUT ;TYPE 2ND PART OF UIC PUSHJ P,CRLF TYPE LOAD. T1,VPRO ;GET VOLUME PROTECION PUSHJ P,P11OUT ;TYPE VOLUME PROTECTION PUSHJ P,CRLF TYPE LOAD. T1,VCHA ;GET VOLUME CHARACTERISTICS BYTE PUSHJ P,OCTOUT ;TYPE OCTAL VALUE OF CHARACTERITSTICS PUSHJ P,CRLF TYPE LOAD. T1,DFPR ;GET DEFAULT FILE PROTECTION PUSHJ P,P11OUT ;TYPE FILE PROTECTION PUSHJ P,CRLF TYPE <# of retrieval pairs in a window: > LOAD. T1,WISZ ;GET # OF PAIRS PUSHJ P,DECOUT ;TYPE SIZE OF WINDOW PUSHJ P,CRLF TYPE LOAD. T1,FIEX ;GET SIZE OF EXTENSION PUSHJ P,DECOUT ;TYPE SIZE TO USE WHEN EXTENDING ; STILL MORE VOLUME INFO CODE PUSHJ P,CRLF TYPE <# Entries in a directory LRU: > LOAD. T1,LRUC ;GET SIZE OF LRU PUSHJ P,DECOUT ;TYPE SIZE OF LRU PUSHJ P,CRLF TYPE MOVE T1,[O.INDN,,A.INDN] ;GET BYTE POINTER TO VOLUME NAME PUSHJ P,TYPS12 ;TYPE 12 BYTE OF VOLUME NAME TYPE <"> PUSHJ P,CRLF TYPE MOVE T1,[O.INDO,,A.INDO] ;GET BYTE POINTER TO OWNER'S NAME PUSHJ P,TYPS12 ;TYPE OWNER'S NAME TYPE <"> PUSHJ P,CRLF TYPE MOVE T1,[O.INDF,,A.INDF] ;GET BYTE POINTER TO FORMAT TYPE PUSHJ P,TYPS12 ;TYPE 12 BYTES OF FORMAT TYPE TYPE <"> PUSHJ P,CRLF MOVE T1,.FXSWT(FP) ;GET SWITCHES TDNN T1,[S$DETAIL] ;SKIP IF /DETAIL REQUESTED POPJ P, ;EXIT WITHOUT MAP DATA IF NOT /DETAIL PJRST TYPSBM ; ROUTINE TO TYPE 12 PDP11 ASCII BYTES GIVEN PDP11 BYTE POINTER IN T1 TYPS12: PUSHJ P,SAVE1 ;SAVE AN AC MOVEI P1,^D12 ;INIT THE COUNTER TYPS13: PUSHJ P,TYPBYT ;GET&TYPE BYTE USING BYTE POINTER IN T1 SOJG P1,TYPS13 ;LOOP TILL ALL BYTES TYPED POPJ P, ;RETURN TO CALLER SUBTTL COMMANDS -- GET C$GET: PUSHJ P,FILIN ;GET FILE SPEX SKIPN FP,IPLIST ;GET FILE INPUT LIST MOVEI FP,DEFFDB C$GET1: PUSHJ P,SETOUT ;GRAB AN OP FDB IF ANY THERE PUSHJ P,C$GETA ;GO DO PER VOLUME INIT HRRZ FP,.FXLNK(FP) ;STEP TO NEXT INPUT SPEC JUMPN FP,C$GET1 ;LOOOP IF MORE POPJ P, ;RETURN TO CALLER ; HERE TO START A FILE COPY USING THE CURRENT INPUT FILE SPEC C$GETA: PUSHJ P,SAVFF ;SAVE PER-VOLUME CORE SIZE PUSHJ P,OPNVOL ;OPEN THE FILES-11 VOLUME PUSHJ P,RLDINI ;YES, INITIALIZE THE WILD READER C$GET2: MOVEI T1,(FP) ;POINT T1 AT USER'S FILE SPEC MOVEI T2,TMPFDB ;POINT AT OUTPUT FDB PUSHJ P,NXTFDB ;GET THE NEXT MATCHING FILE POPJ P, ; NO MORE WILD FILES, EXIT THIS LEVEL PUSHJ P,C$GETB ;GO DO COPY FOR THIS FILE JRST C$GET2 ;AND LOOP FOR ANOTHER ; HERE TO COPY A SINGLE NON-WILD FILE FROM FILES11 TO TOPS10 C$GETB: PUSHJ P,SAVFF ;SAVE .JBFF SO WE CAN COLAPSE CORE LATER SETOM RSXCTR ;INIT THE BYTE COUNTER SETOM RSXVBN ;INIT THE BLOCK POINTER MOVE T1,.FXNUM+TMPFDB ;GET THE FILE NUMBER OF THE MATCH MOVEI T2,FHBBUF ;NORMAL HEADER BUFFER PUSHJ P,REDFHB ;GO READ THAT FILE'S FFHB PUSHJ P,G$ENTER ;GO DO THE ENTER FOR "GET" COMMAND MOVE T1,.FXSWT+TMPFDB ;GET MODE FLAGS TDNN T1,[S$ASCI] ;SKIP IF EXPLICIT /ASCII TDNN T1,[S$IMAG!S$BINA] ;SKIP IFF EXPLICIT BINARY JRST C$GET5 ;BRANCH IF ASCII COPY ;FALL THROUGH TO DO IMAGE MODE COPY ;HERE TO XFER A FILE FROM FE DISK TO 10 DISK IN BINARY MODE C$GET3: MOVEI T1,FHBBUF ;POINT AT FHB BUFFER FOR THAT FILE AOS T2,RSXVBN ;LOAD T2=NEXT VBN PUSHJ P,SCNRET ;SCAN "RIB" AND FIND NEXT BLOCK # JRST C$GET4 ;FAILED, MUST BE EOF PUSHJ P,SUSET ;POSITION TO IT IN VIO,[IOWD 200,TMPBUF ;READ THAT BLOCK INTO BUFFER 0] ;... SKIPA T2,RSXVBN ;GET VBN AGAIN PUSHJ P,G$IER ;GO REPORT INPUT ERROR, THEN RETURN HERE MOVEI T1,FHBBUF ;POINT AT FHB FOR INPUT FILE PUSHJ P,EOFBYT ;GET # OF PDP11 BYTES IN BLOCK IDIVI T1,4 ;COMPUTE T1=# PDP10 WORDS CAIE T2,0 ;ANY LEFT OVER BYTES? ADDI T1,1 ;IF SO, USE ONE MORE PDP10 WORD IMUL T1,[-1,,0] ;CONVERT INTO -VE.COUNT,,0 SKIPE T1 ;SHOULD NOT HAPPEN, BUT AVOID GOTO WORDS HRRI T1,TMPBUF-1 ;INSERT BUFFER ADDRESS INTO IOWD WORD SETZ T2, ;END IOLIST WITH A 0 IOWD OUT FIO,T1 ;WRITE THAT BLOCK INTO FILE SKIPA ;SKIP IF OUTPUT GOOD PUSHJ P,G$OER ;REPORT ERROR, THEN RETURN HERE JRST C$GET3 ;LOOP TO XFER NEXT BLOCK IN FILE ;ROUTINE TO TYPE OUT DETAILS OF AN INPUT ERROR DURING "GET" COMMAND G$IER: TYPE <% Input error > ;HERALD THE ERROR GETSTS VIO,T1 ;GET I/O STATUS OF THAT CHANNEL PUSHJ P,OCTOUT ;TYPE OUT I/O STATUS IN OCTAL TYPE < on PBN > ;... MOVE T1,LASSET ;GET PHYSICAL BLOCK# LAST SUSET'D TO PUSHJ P,OCTOUT ;TYPE LAST BLOCK# SUSET'D TO TYPE < (RBN > ;... MOVE T1,RSXVBN ;GET RELATIVE BLOCK # IN FILE PUSHJ P,OCTOUT ;TYPE RELATIVE BLOCK # IN FILE TYPE <) of > ;... MOVEI T1,FHBBUF ;POINT AT FHB FOR INPUT FILE PUSHJ P,TYPFHU ;TYPE COMPLETE FILE11 FILE SPEC SETSTS VIO,17 ;TURN OFF THE ERROR BITS PJRST CRLF ;END WITH CRLF ;ROUTINE TO TYPE OUT DETAILS OF AN OUTPUT ERROR DURING "GET" COMMAND G$OER: TYPE <% Output error > ;HERALD THE ERROR GETSTS FIO,T1 ;GET THE I/O STATUS OF THAT CHANNEL PUSH P,T1 ;SAVE BITS PUSHJ P,OCTOUT ;TYPE I/O STATUS IN OCTAL TYPE < on RBN > ;... MOVE T1,RSXVBN ;GET RELATIVE BLOCK# IN OUTPUT FILE PUSHJ P,OCTOUT ;TYPE BLOCK # IN OCTAL TYPE < of > ;... PUSHJ P,TYPFIO ;TYPE FILE SPEC FOR OUTPUT FILE POP P,T1 ;GET BACK I/O STATUS BITS TRZ T1,IO.ERR ;TURN OFF ERRORS SETSTS FIO,(T1) ;TURN OFF ERROR BITS IN DDB PJRST CRLF ;END WITH CRLF ; HERE WHEN WE GET EOF ON THE FILES-11 VOLUME'S FILE C$GET4: MOVEI T1,FIO ;LOAD T1=CHANNEL # OF OUTPUT FILE DEVCHR T1, ;GET DEVICE CHARACTERISTICS TDNE T1,[DV.TTY] ;SKIP IF NOT USER'S TTY OUTPUT FIO, ;GIVE HIM HIS OUTPUT IMMEDIATELY PUSH P,FP ;SAVE FP MOVEI FP,TMPFDB ;POINT AT OUTPUT FDB PUSHJ P,TYPFIO ;TYPE ACTUAL OUTPUT SPEC POP P,FP ;RESTORE FP TYPE <=> MOVEI T1,FHBBUF ;POINT AT INPUT FILE'S FHB PUSHJ P,TYPFHU ;TYPE ACTUAL INPUT SPEC MOVE T1,.FXSWT+TMPFDB ;GET MODE FLAGS TDNN T1,[S$ASCI] ;SKIP IF EXPLICIT ASCII TDNN T1,[S$IMAG!S$BINA] ;SKIP IF EXPLICIT BINARY SKIPA T1,[SIXBIT ./ASCII.] ;HERE IF EXPLICIT OR IMPLICIT ASCII MOVE T1,[SIXBIT ./IMAGE.] ;HERE IF EXPLICIT (ONLY) BINARY PUSHJ P,SIXOUT ;TYPE MODE OF FILE XFER TDZE F,[X%PEOF] ;DID WE HAVE A PROBLEM COPYING? TYPE <(Unexpected end-of-file)> PUSHJ P,CRLF ;END LINE RELEASE FIO, ;RELEASE IT SETZB T3,TTYOBF+.BFCTR ; ZERO TTY'S BYTE COUNT PJRST TYO ;TYPE A NULL TO FORCE LINE OUT NOW ;HERE TO COPY AN ASCII TEXT FILE FROM THE FE DISK C$GET5: LOAD. P4,RTYP ;GET RECORD TYPE BYTE FROM FHB LOAD. P3,RATT ;GET RECORD ATTRIBUTE BYTE FROM FHB C$GET6: LOAD. P2,RSIZ ;GET RECORD SIZE FROM FHB TDZ F,[X%ODD] ;INITIALIZE ODD/EVEN RECORD SIZE FLAG MOVE T3,P2 ;COPY RECORD SIZE CAIN P4,R.FIX ;SKIP IF VARIABLE LENGTH RECORDS JRST .+3 ;BRANCH IF FIXED RECORD SIZE PUSHJ P,DVWORD ;GET RECORD SIZE FROM RECORD ITSELF JRST C$GET4 ;BRANCH IF DVWORD FAILS (EOF, APPARENTLY) MOVE P1,T3 ;COPY FINAL RECORD SIZE CAIN P4,R.SEQ ;SKIP IFF NOT SEQUNCED RECORD PUSHJ P,GETSEQ ;GET SEQUENCE NUMBER FROM RECORD HEADER MOVE P2,P1 ;COPY BYTE COUNT AGAIN CAIN P4,R.FIX ;SKIP IF VARIABLE LENGTH RECORD JRST C$GET7 ;BRANCH IF FIXED LENGTH RECORD TRNE P1,1 ;SKIP IF VARIABLE LENGTH RECORD WITH EVEN COUNT TDO F,[X%ODD] ;REMEMBER IF VARIABLE LENGTH ODD COUNT MOVEI T3,15 ;LOAD T3=CARRIAGE-RETURN TRNE P3,FD.CR ;SKIP IF NO IMPLIED CR'S AT HEAD OF RECORD PUSHJ P,PUTC ;INSERT IMPLIED CR AT HEAD OF RECORD JUMPE P1,C$GET8 ;BRANCH IF BLANK LINE ;HERE TO COPY THE LINE C$GET7: PUSHJ P,RDBYTE ;GET A BYTE FROM THE INPUT RECORD JRST C$G7B ;BRANCH IF WE GET AN EOF DURING COPY OF RECORD ANDI T3,177 ;TRUNCATE 8-BIT ASCII TO 7-BIT ASCII CAIE T3,14 ;SKIP IF EMBEDDED FOUND CAIN T3,13 ;NONSKIP IF EMBEDDED FOUND TDO F,[X%VMS] ;REMEMBER EXPLICIT VERTICAL MOTION SEEN CAIE T3,12 ;SKIP IF EXPLICIT FOUND CAIN T3,15 ;NONSKIP IF EMBEDDED FOUND JRST [TDO F,[X%VMS] ;REMEMBER VERTICAL MOTION SEEN MOVE T4,[S$NOVM];GET THE "DON'T COPY CRLF" BIT TDNE T4,.FXSWT(FP);SKIP IF ALLOWED TO COPY CR,LFS JRST .+2 ;SKIP OVER "PUTC" SO CRLF IS NOT COPIED JRST .+1] ;FALL THROUGH AND COPY CRLF PUSHJ P,PUTC ;PUT INPUTED BYTE INTO OUTPUT FILE SOJG P1,C$GET7 ;LOOP TO COPY MORE BYTES IF COUNT NOT EXPIRED ;HERE WHEN BYTE COUNT EXPIRES C$GET8: MOVEI T3,12 ;LOAD T3=LINE FEED TRNE P3,FD.CR ;SKIP IF NO IMPLIED CR AT END OF RECORD PUSHJ P,PUTC ;INSERT IMPLIED CR AT END OF THIS RECORD TDZN F,[X%VMS] ;SKIP IF VERTICAL MOTION CHARACTER WAS SEEN TRNE P3,FD.CR ;SKIP IF NO IMPLIED CR/LFS SKIPA ;NO NEED TO INSERT MOTION PUSHJ P,FCRLF ;INSERT A CR, LF INTO THE OUTPUT TEXT FILE TDZN F,[X%ODD] ;SKIP IF ODD BYTE STILL LEFT IN INPUT FILE JRST C$GET6 ;BRANCH IF NO EXTRA ODD BYTE TO TAKE CARE OF PUSHJ P,RDBYTE ;TRASH THE EXTRA ODD BYTE IF NECESSARY JRST C$GET4 ;BRANCH TO EOF HANDLER IF RDBYTE FAILS JRST C$GET6 ;LOOP FOR ANOTHER LINE ;ROUTINE TO GET FILES-11 SEQUENCE NUMBER FROM INPUT FILE ;...AND TYPE IT OUT TO TOPS-10 OUTPUT FILE GETSEQ: PUSHJ P,DVWORD ;GET THE SEQ# FOR THIS RECORD TYPE <% EOF while reading line sequence number>,C$GET4 SUBI P1,2 ;FIXUP BYTE COUNT WRT SEQUENCE # BYTES PJRST TYPSQN ;RE-TYPE SEQUENCE # INTO OUTPUT FILE ;COME HERE DURING COPY OF A RECORD THAT RUNS OUT OF BYTES C$G7B: CAME P1,FFBYTE ;SKIP IF EOF IN EXPECTED PLACE TDO F,[X%PEOF] ;REMEMBER IF EOF WAS IN UNEXPECTED PLACE JRST C$GET4 ;JOIN COMMON EOF HANDLER ; ROUTINE TO DO THE ENTER TO A TOPS10 FILE ; USED BY THE SINGLE FILE LOOP OF THE "GET" COMMAND G$ENTE: PUSHJ P,GE$FIL ;SETUP ENTER'S FILE NAME DATA PUSHJ P,GE$TYP ;SETUP ENTER'S FILE TYPE DATA PUSHJ P,GE$SWT ;GO GET THE SWITCH INFO MOVE T1,.FXDEV+OUTFDB ;GET OUTPUT DEVICE FROM WILD'S BLOCK MOVEM T1,.FXDEV+TMPFDB ;INSERT DEVICE INTO SCAN'S BLOCK MOVE T1,[OUTFDB+.FXDIR,,TMPFDB+.FXDIR] ;POINT AT WILD_PATH,,SCAN_PATH BLT T1,TMPFDB+.FXDIR+.FXLND-1 ;XFER WILD'S PATH INTO SCAN'S BLOCK MOVE T1,OUTFDB+.FXMOD ;GET WILD'S SWITCH BITS MOVEM T1,TMPFDB+.FXMOD ;INSERT WILD'S BITS INTO SCAN'S BLOCK MOVEI T1,TMPFDB ;POINT AT FILE SPEC BLOCK MOVEI T2,OPNBLK ;POINT AT OPEN BLOCK MOVEI T3,LERBLK ;POINT AT L/E/R BLOCK MOVEI T4,PTHBLK ;POINT AT PATH BLOCK PUSHJ P,.STOPB## ;CONSTRUCT OPEN/LER/PATH BLOCKS ERROR MOVEI T1,.RBSPL ;GET T1=LENGTH OF ENTER BLOCK MOVEM T1,LERBLK+.RBCNT ;INSERT LENGTH INTO COUNT WORD PUSHJ P,GE$CDT ;GO INSERT CREATE DATE/TIME LOAD. T1,FVER ;GET ;GENERATION MOVEM T1,LERBLK+.RBVER ;MAKE IT PDP10 VERSION "(nnn)-0" MOVEI T1,.IOASC ;USE ASCII MODE FOR OUTPUT MOVE T2,.FXSWT+TMPFDB ;GET MODE FLAGS TDNE T2,[S$IMAG!S$BINA] ;/BINARY OR /IMAGE? MOVEI T1,.IODMP ;THEN USE IMAGE MODE MOVE T2,OPNBLK+1 ;GET SCAN'S CHOICE OF DEVICE MOVSI T3,DOBUF ; OPEN FIO,T1 ;OPEN IT ERROR ENTER FIO,LERBLK ;GO ENTER THE FILE ERROR ,LSTLER SETZM PUTCTR ;INIT COUNTER POPJ P, ;ROUTINE TO SETUP THE FILE NAME DATA PRIOR TO THE ENTER FOR A "GET" CMD GE$FIL: LOAD. T1,FNM1 ;GET 1ST 3RD OF FILE NAME PUSHJ P,C5T6 ;CONVERT TO SIXBIT MOVSI P1,(T1) ;SAVE IT LOAD. T1,FNM2 ;GET 2ND 3RD OF FILE NAME PUSHJ P,C5T6 ;CONVERT TO SIXBIT HRRI P1,(T1) ;COMBINE IT WITH 1ST 3RD CAME P1,TMPFDB+.FXNAM ;SKIP IF FHB NAME MATCHS DIR NAME TYPE <% FHB name doesn't match directory name > MOVE T1,.FXNAM+TMPFDB ;GET FILE NAME FROM FHB TDZ T1,.FXNMM+OUTFDB ;AND EXTRACT CHARACTERS HE DIDN'T GIVE ;IN THE OUTPUT SPEC ON LEFT OF = MOVE T2,.FXNAM+OUTFDB ;GET OUTPUT SPEC FROM LEFT OF = AND T2,.FXNMM+OUTFDB ;KEEP ONLY NON WILD CHARACTERS OR T1,T2 ;MERGE THE TWO FOR FINAL OUTPUT NAME MOVEM T1,.FXNAM+TMPFDB ;RESSAVE OUTPUT FILE NAME POPJ P, ;ROUTINE TO SETUP THE FILE TYPE DATA PRIOR TO THE ENTER GE$TYP: LOAD. T1,FTYP ;GET FILE TYPE FROM FHB PUSHJ P,C5T6 ;CONVERT TO SIXBIT HLRZ T2,.FXEXT+TMPFDB ;GET FILE TYPE FROM DIRECTORY ENTRY CAME T1,T2 ;SKIP IF FHB TYPE IS SAME AS DIR TYPE TYPE <% FHB type doesn't match directory type > HRLZ T3,.FXEXT+OUTFDB ;GET WILD CARD MASK TO LEFT OF = HLLZ T1,.FXEXT+TMPFDB ;GET FILE TYPE FROM DIRECTORY ENTRY TDZ T1,T3 ;TURN OFF WILD CHARACTERS HLLZ T2,.FXEXT+OUTFDB ;GET FILE TYPE FROM LEFT OF = AND T2,T3 ;KEEP ONLY WILD CHARACTERS OR T1,T2 ;MERGE THE TWO TOGETHER HLLOM T1,.FXEXT+TMPFDB ;SAVE RECOMPUTED EXT NAME POPJ P, ;RETURN TO CALLER ;ROUTINE TO SETUP THE OUTPUT SWITCHES FOR THE FILE IN A "GET" COMMAND GE$SWT: HLRZ T1,.FXEXT+TMPFDB ;GET FILE TYPE FROM DIRECTORY PUSHJ P,C6T5 ;CONVERT TO RAD50 FOR EXTCHK PUSHJ P,EXTCHK ;GO CHECK AND SETUP FLAGS ;LEAVE RECOMMENDED SWITCHES IN T1 MOVE T2,.FXSWT(FP) ;GET INPUT SWITCHES MOVE T3,.FXSWT+OUTFDB ;GET DEFAULT OUTPUT SWITCHES TDNE T3,[S$IMAG!S$BINA!S$ASCI];DID HE GIVE AN ALL INCLUSIVE OUTPUT? MOVE T1,T3 ;USE SWITCHES FROM INCLUSIVE OUTPUT ;RATHER THAN THOSE IMPLIED BY EXT TDNE T2,[S$IMAG!S$BINA!S$ASCI];GIVE A SPEC ON THIS INPUT FFILE? MOVE T1,T2 ;USE SWITCHES APPLIED SPECIFICALLY ;TO THIS FILE IN PLACE OF ANY OTHER MOVEM T1,.FXSWT+TMPFDB ;SAVE THE ADJUSTED FLAGS POPJ P, ;ROUTINE TO EXTRACT ASCII DATE FROM FHB ; AND INSERT IT INTO ENTER BLOCK FOR "GET" COMMAND GE$CDT: MOVE T1,[O.CRDT,,A.CRDT] ;T1=BYTE POINTER TO CREATE DATE MOVEI T2,FHBBUF ;OFFSET TO FHB TO ACCESS PUSHJ P,REDDAT ;GO READ THE DATE FROM FHB DPB T1,[POINT 12,LERBLK+.RBPRV,35] ;INSERT LO 12 BITS OF DEC10 DATE LSH T1,^D-12 ;DUMP LOW 12 BITS DPB T1,[POINT 3,LERBLK+.RBEXT,20] ;INSERT HI 3 BITS OF DEC10 DATE MOVE T1,[O.CRTI,,A.CRTI] ;T1=BYTE POINTER TO CREATE TIME MOVEI T2,FHBBUF ;T2=OFFSET TO FHB TO ACCESS PUSHJ P,REDTIM ;GO READ THE TIME FROM FHB DPB T1,[POINT 11,LERBLK+.RBPRV,23] ;INSERT TIME INTO LER BLOCK POPJ P, ;RETURN TO CALLER SUBTTL COMMANDS -- PUT C$PUT: PUSHJ P,FILIN ;GET OUTPUT SPEX SKIPN FP,IPLIST ;LOAD UP POINTER TO FILE LIST PUSHJ P,ILLCMD PUSHJ P,TTYPHY ;SETUP TTY: SETZ T2, ;COUNT NUMBER OF OUTPUT FILE SPEX C$PUT0: MOVE T1,[FX.EQL] ;= SEEN IN THIS SPEC TDNE T1,.FXMOD(FP) ;SKIP IF INPUT SPEC PUSHJ P,POCHEK ;RETURN IF OUTPUT SPEC LOOKS VALID HRRZ FP,.FXLNK(FP) ;STEP TO NEXT FILE SPEC, IF ANY JUMPN FP,C$PUT0 ;BRANCH IF ANY FILE SPEC JUMPE T2,[PUSHJ P,ILLCMD] ;MUST BE AT LEAST 1 OUTPUT FILE HRRZ FP,IPLIST ;LOAD UP POINTER TO START OF FILE LIST PUSHJ P,C$PUTA ;GO DO A FILE SPEC HRRZ FP,.FXLNK(FP) ;STEP TO NEXT FILE SPEC, IF ANY JUMPN FP,.-2 ;LOOP IF ANOTHER FILE THERE POPJ P, ;DONE IF NO MORE ;ROUTINE TO LOOK AT OUTPUT SPEC TO DETERMINE VALIDITY POCHEK: SETO T1, ;NO WILD CHARS PLEASE CAMN T1,.FXDNM(FP) ;SKIP IF WILD CHARS CAME T1,.F2DNM(FP) ;SKIP IF NO WILD CHARS JSP U0,ILLPPN ;GO COMPLAIN SKIPE .FXDIR+2(FP) ;SKIP IF NO SFD LIST JSP U0,ILLPPN AOJA T2,CPOPJ ; COME HERE WITH A POSSIBLY WILD INPUT SPEC AT (FP) C$PUTA: PUSHJ P,SAVFF ;SAVE .JBFF PUSHJ P,SETOUT ;SETUP THE OUTPUT FDB (GOING TO 20F DISK) PUSHJ P,SAVFP ;SAVE FP MOVEM FP,FPCOPY ;SAVE FP MOVEI FP,OUTFDB ;POINT AT OUTPUT FDB PUSHJ P,OPNVOL ;OPEN THAT VOLUME SETZM FPWILD ;INIT FILE POINTER THAT WILD USES $PUTA0: MOVSI T1,'DSK' SKIPN @FPCOPY MOVEM T1,@FPCOPY ;THIS DEPENDS ON .FXDEV=0 MOVE T1,[XWD 5,[XWD FPCOPY,0 ; FPCOPY=POINTER TO CURRENT SPEC XWD OPNBLK,LERBLK; OPENBLOCK,,LOOKUP BLOCK XWD .FXLEN,177; FDB LENGTH,,LER LENGTH XWD <(1B0)>!WLD,FPWILD 0]] ; PUSHJ P,.LKWLD## ;EXPAND FILE SPEC POPJ P, ;ALL DONE PUSHJ P,C$PUTB ;GO XFER THE FILE WE FOUND POPJ P, ;HERE IF NO POINT IN CONTINUING WITH THIS FDB JRST $PUTA0 ;LOOP FINDING FILES ; HERE WHEN WE FIND AN INPUT FILE TO COPY TO THE 20F DISK ; COMPUTE NAME AS IT WILL APPEAR ON THE 20F DISK C$PUTB: PUSHJ P,SAVFF ;SAVE .JBFF, WE MIGHT EXPAND DURING I/O TDZ F,[X%SUPER] ;NOT SUPERCEEDING (YET) SETZM TMPFDB SETZM BLKCNT MOVE T1,[TMPFDB,,TMPFDB+1] BLT T1,TMPFDB+.FXLEN-1 MOVE T1,LERBLK+.RBNAM ;GET THE FILE NAME ON PDP10 DISK TDZ T1,OUTFDB+.FXNMM ;KEEP THE OUTPUT FILE'S WILD CHARACTERS MOVE T2,OUTFDB+.FXNAM ;GET THE FILE NAME ON 20F DISK AND T2,OUTFDB+.FXNMM ;TURN OFF THE WILD CHARACTERS IOR T1,T2 ;COMPUTE FINAL NAME MOVEM T1,TMPFDB+.FXNAM ;SAVE THE FINAL NAME MOVE T1,OUTFDB+.F2NAM ;GET 2ND HALF OF OUTPUT NAME MOVEM T1,TMPFDB+.F2NAM ;SPECIFY 2ND HALF OF OUTPUT NAME HLRZ T1,LERBLK+.RBEXT ;GET FILE TYPE ON PDP10 DISK TDZ T1,OUTFDB+.FXEXT ;KEEP OUTPUT FILE'S WILD CHARACTERS HLRZ T2,OUTFDB+.FXEXT ;GET FILE TYPE ON 20F DISK AND T2,OUTFDB+.FXEXT ;TURN OFF THE WILD CHARACTERS IOR T1,T2 ;MERGE AND COMPUTE FINAL TYPE HRLOM T1,TMPFDB+.FXEXT ;SPECIFY FILE TYPE DMOVE T1,OUTFDB+.FXDIN ;GET DIRECTORY SPEC DMOVEM T1,TMPFDB+.FXDIN ;STORE IT SETOM TMPFDB+.FXDNM ;MAKE DIRECTORY FULLY SPECIFIED SETOM TMPFDB+.F2DNM ;MAKE DIRECTORY FULLY SPECIFIED SETOM TMPFDB+.FXNMM ;MAKE FILE NAME FULLY SPECIFIED SETOM TMPFDB+.F2NMM ;MAKE ..... ; FIND INPUT FILE MOVE T1,[UU.PHS!.IOASC] ;BY DEFAULT, USE ASCII MODE MOVE T1,OPNBLK+0 ;... MOVEI T1,DIBUF ;BY DEFAULT, USE DISK INPUT BUFFER MOVEM T1,OPNBLK+2 ;... OPEN FIO,OPNBLK ;OPEN INPUT DISK FOR INPUT JRST PUTER4 ;COMPLAIN IF DEVICE DISAPPEARED LOOKUP FIO,LERBLK ;FIND INPUT FILE JRST PUTER5 ;GO COMPLAIN IF YOU CAN'T SKIPN T1,OUTFDB+.FXGEN ;SKIP IF HE GAVE EXPLICIT VERSION # HRRZ T1,LERBLK+.RBVER ;FETCH EDIT # IF GIVEN ON FILE RIB ANDI T1,77777 ;TRUNCATE VERSION NUMBER TO 15 BITS MOVEM T1,TMPFDB+.FXGEN ;REMEMBER VERSION NUMBER FOR OUTPUT ; SCAN THE SPECIFIED 20F DIRECTORY FOR THE PROPER SPOT TO INSERT THIS FILE. ; IF THE CORRECT FILE/GENERATION ALREADY EXISTS, PREPARE TO SUPERCEED IT. ; IF THE FILE IS BRAND NEW, FIND A NULL ENTRY AND INSERT THE FILE THERE. ; IF THE DIRECTORY IS FULL, EXPAND BY A BLOCK AND INSERT THE FILE THERE. PUSHJ P,RLDINI ;INITIALIZE 20F WILD CARD INTERFACE SETO P4, ;P4=BEST GENERATION NUMBER $PUTB1: MOVEI T1,TMPFDB ;GET FDB WITH FULLY SPECIFIED FILE MOVEI T2,FAKFDB ;GET AN FDB TO OUTPUT TO PUSHJ P,NXTFDB ;SEARCH 20F DISK FOR OLD VERSION OF FILE JRST $PUTB2 ;BRANCH IF NO MORE FILES CAMGE P4,.FXGEN+FAKFDB ;IS GENERATION HIGHER THAN BEST SO FAR? MOVE P4,.FXGEN+FAKFDB ;KEEP HIGHEST GEN# IN P4 SKIPE T1,TMPFDB+.FXGEN ;SKIP IF NO EXPLICIT GENERATION # CAME T1,FAKFDB+.FXGEN ;SKIP IF EXPLICIT AND THEY MATCH TOO JRST $PUTB1 ;LOOP IF NOT THE RIGHT FILE MOVE T1,.FXNUM+FAKFDB ;GET FILE # OF MATCHING FILE MOVEM T1,.FXNUM+TMPFDB ;AND REMEMBER IT TDO F,[X%SUPER] ;FILE IS BEING SUPERCEEDED MOVEI T2,DELBUF ;WHERE TO GET OLD FHB PUSHJ P,REDFHB ;READ IN OLD FHB JRST $PUTB3 ;YES, USE THIS SLOT ; HERE WHEN NXTFDB HAS SCANNED ALL OF THE DIRECTORY AND HAS NOT FOUND ; AN EXPLICIT MATCHING FILE TO SUPERCEED. NOW SCAN THE SAME DIRECTORY ; FOR A NULL SLOT WE CAN USE TO INSERT THIS NEW FILE. $PUTB2: MOVE T1,DIRMAT ;GET # OF DIRECTORIES SCANNED CAIE T1,1 ;000000.DIR AND OUR DIR JRST PUTER1 ;GO MENTION ERROR AND ABORT PUSHJ P,RLDINI ;INITIALIZE WILD CARDER DMOVE T1,OUTFDB+.FXDIN ;GET DIRECTORY WE WANT DMOVEM T1,NULFDB+.FXDIN ;SAVE DIRECTORY WE WANT IN NULL FDB MOVEI T1,NULFDB ;EXPLICIT FDB OF 0S MOVEI T2,FAKFDB ;FDB TO EXPAND INTO PUSHJ P,NXTFDB ;FIND AN EMPTY SLOT JRST UFDGRO ;GROW THE UFD 1 BLOCK AND TRY AGAIN CAIN P4,177777 ;SKIP IF WE HAVEN'T RUN OUT OF VERSIONS JRST PUTER3 ;COMPLAIN IF NO VERSION #S LEFT AOSN P4 ;INCREMENT TO NEXT HIGHEST GENERATION HRRZ P4,TMPFDB+.FXGEN ;GET GENERATION ANDI P4,177777 ;ONLY KEEP LOW ORDER BITS CAIN P4,0 ;CHECK FOR OVERFLOW MOVEI P4,1 ;AND CONVERT TO VERSION#1 IF SO MOVEM P4,TMPFDB+.FXGEN ;SAVE GENERATION NUMBER MOVE T1,IPLIST ;POINT AT FIRST FILE BLOCK MOVE T1,V$FILE(T1) ;GET /FILE SWITCH ON OUTPUT FILE PUSHJ P,ALCFHB ;GO GET A FILE NUMBER MOVEM T1,TMPFDB+.FXNUM ;AND REMEMBER IT FOR LATER ; HERE WHEN WE KNOW WHERE IN THE DIRECTORY WE WANT TO INSERT THIS FILE. $PUTB3: MOVNI T1,.DIROFF ;OFFSET TO MATCHING SLOT ADDM T1,WDIOFF ;ADJUST POINTER TO POINT AT MATCH MOVEI T1,*4 ;GET OFFSET FOR OUR FHB MOVEM T1,FHBFOO ;SAVE IT ;NOW, "FHBFOO" IS AN OFFSET STYLE POINTER INTO THE FHB WE'RE BUILDING ;AND "WDIOFF" IS AN OFFSET POINTER INTO THE SLOT IN THE DIRECTORY WE'RE USING. MOVE T1,TMPFDB+.FXNUM ;GET DESIRED FILE # STOR. T1,UFNO,WDIOFF ;STORE FILE # INTO DIRECTORY MOVEI T2,TMPBUF ;GET FHB ADDRESS PUSHJ P,INIFHB ;CREATE THE INITIAL FHB FOR ME MOVE T1,TMPFDB+.FXNUM ;GET SELECTED (OR REQUIRED) FILE NUMBER CAILE T1,5 ;SKIP IF KNOWN FILE (FORCE NUM=SEQ) LOAD. T1,FSEQ,FHBFOO ;GET THE NEW SEQ # STOR. T1,UFSQ,WDIOFF ;STORE SEQ# IN DIRECTORY HLRZ T1,TMPFDB+.FXNAM ;GET SIXBIT NAME 1ST 3RD PUSHJ P,C6T5 ;CONVERT 1ST 3RD TO RAD50 STOR. T1,FNM1,FHBFOO ;STORE FILE NAME PART 1 INTO FHB STOR. T1,UFN1,WDIOFF ;INSERT INTO DIRECTORY TOO HRRZ T1,TMPFDB+.FXNAM ;GET SIXBIT NAME PART 2 PUSHJ P,C6T5 ;CONVERT 2ND 3RD TO RAD50 STOR. T1,FNM2,FHBFOO ;STORE FILE NAME PART 2 IN FHB STOR. T1,UFN2,WDIOFF ;INSERT INTO DIRECTORY TOO HLRZ T1,TMPFDB+.F2NAM ;GET 3RD PART OF FILE NAME PUSHJ P,C6T5 ;CONVERT TO RAD50 STOR. T1,FNM3,FHBFOO ;PUT INTO FHB STOR. T1,UFN3,WDIOFF ;PUT INTO DIRECTORY FILE TOO HLRZ T1,TMPFDB+.FXEXT ;GET FILE TYPE PUSHJ P,C6T5 ;CONVERT TO RAD50 STOR. T1,FTYP,FHBFOO ;STORE INTO FHB STOR. T1,UFTY,WDIOFF ;STORE INTO DIRECTORY TOO MOVE T1,.FXGEN+TMPFDB ;GET GENERATION # STOR. T1,UVER,WDIOFF ;STORE INTO DIRECTORY STOR. T1,FVER,FHBFOO ;AND STORE INTO FHB SKIPE T1,V$FPRO+OUTFDB STOR. T1,FPRO,FHBFOO ;STORE PROTECTION IF SPECIFIED ;HERE TO SETUP AND PREPARE FOR ACTUAL TRANSFER OF DATA LOAD. T1,FTYP,FHBFOO ;GET THE FILE TYPE IN RAD50 PUSHJ P,EXTCHK ;GO IMPLY SOME FLAGS MOVE T2,.FXSWT+OUTFDB ;GET OUTPUT SWITCHES TDZ T2,[S$IMAG!S$BINA!S$ASCI!S$CONT];FORGET MODE FLAGS MOVE T3,.FXSWT+OUTFDB ;GET OUTPUT SWITCHES TDNE T3,[S$IMAG!S$BINA!S$ASCI!S$CONT];GIVE AN OUTPUT SWITCH? MOVE T1,T3 ;YES, GET MODE FLAGS FROM THAT AND T1,[S$IMAG!S$BINA!S$ASCI!S$CONT];ISOLATE MODE SWITCHES ONLY OR T1,T2 ;MIX UP ALL THE FLAGS TDNN T1,[S$IMAG!S$BINA!S$ASCI] TDO T1,[S$ASCI] ;FORCE /ASCII IF NOTHING ELSE MOVEM T1,TMPFDB+.FXSWT ;GO TURN ON THE SWITCHES, IF ANY SETZM CHULFT ;0 LEFT IN CURRENT CHUNK SETZM STOLFT ;0 LEFT IN CURRENT STORAGE POINTER TDZ F,[X%FIR!X%EOF] ;NO I/O YET, THEREFORE NO EOF YET MOVE T1,[O.CRDT,,A.CRDT] ;SETUP PDP11 BYTE POINTER TO CREATE DATE MOVEI T2,TMPBUF ;POINT AT OUTPUT FILE'S FHB LDB T4,[POINT 3,LERBLK+.RBEXT,20] ;FETCH PDP10'S CREATE DATE LSH T4,^D12 ;MAKE ROOM FOR MORE BITS LDB T3,[POINT 12,LERBLK+.RBPRV,35] ;GET LOW ORDER PDP10 DATE OR T3,T4 ;COMPUTE PDP10 CREATE DATE PUSHJ P,STODAT ;INSERT CREATE DATE INTO FHB MOVE T1,[O.CRTI,,A.CRTI] ;GET PDP11 BYTE POINTER TO CREATE TIME MOVEI T2,TMPBUF ;GET POINTER TO OUTPUT FILE'S FHB LDB T3,[POINT 11,LERBLK+.RBPRV,23] ;GET CREATE TIME FROM RIB PUSHJ P,STOTIM ;STORE CREATE TIME INTO FHB MOVE T1,TMPFDB+.FXSWT ;GET OUTPUT MODE FLAGS TDNN T1,[S$IMAG!S$BINA] JRST C$PUTC ;DO ASCI MODE XFER TO RSX20F JRST C$PUTD ;DO IMAGE MODE XFER TO 20F ;ROUTINE TO GROW THE UFD BY ONE BLOCK TO MAKE ROOM FOR MORE FILES UFDGRO: TYPE <% Expanding User File Directory> PUSHJ P,CRLF MOVEI T1,WDIFHB ;POINT AT THE FHB PUSHJ P,EXPDIR ;EXPAND T JRST PUTER2 ;GO COMPLAIN JRST $PUTB2 ;GO SCAN NEW UFD BLOCK FOR 0S SUBTTL EXPDIR ; ROUTINE TO EXPAND THE UFD WHOSE FHB IS (T1) ; ;ENTER: ; T1/ ADDRESS OF FHB ;EXIT: ; ; EXPDIR: PUSHJ P,SAVE4 ;SAVE SOME ACS MOVE P1,T1 ;SAVE THE FHB ADDRESS MOVEI T1,1 ;SPECIFY A MAX OF 1 BLOCK NEEDED PUSHJ P,SCNSBM ; JRST EXPER0 ;GO COMPLAIN MOVEI T1,1 ;ONLY USE 1 BLOCK, NO MATTER HOW MANY MOVE P2,T2 ;REMEMBER THE BLOCK WE GOT MOVEI T3,(P1) ;POINT AT THE FHB CONVERNED PUSHJ P,STORET ;INSERT RIB POINTER FOR NEW BLOCK MOVE P4,P1 ;COPY ADDRESS OF FHB SUBI P4,FHBBUF ;GET PDP10 OFFSET BETWEEN FHB BUFFRS IMULI P4,4 ;COMPUTE # PDP11 BYTES IN OFFSET LOAD. T1,HIBL,P4 ;GET # OF HI BLOCK (LOW) ADDI T1,1 ;ONE MORE BLOCK WAS ADDED STOR. T1,HIBL,P4 ;PUT IT BACK LOAD. T2,HIBH,P4 ;GET HIGH PART OF HI BLOK# ADDI T2,1 ;PRETEND A CARRY TOOK PLACE TRNE T1,200000 ;SKIP IF CARRY DIDN'T STOR. T2,HIBH,P4 ;UPDATE HIGH PART IF CARRY HAPPENED LOAD. T1,EFBL,P4 ;GET # OF EOF BLOCK (LOW) ADDI T1,1 ;ONE MORE BLOCK ADDED STOR. T1,EFBL,P4 ;INSERT INC'ED BLOCK # LOAD. T2,EFBH,P4 ;GET HGH # ADDI T2,1 ;ASSUME CARRY OCCURRED TRNE T1,200000 ;SKIP IFF CARRY DID NOT HAPPPEN STOR. T2,EFBH,P4 ;INSERT HGH ORDER IF CARRY HAPPENED MOVE T1,P1 ;T1=ADDR OF FHB PUSHJ P,WRUFHB ;GO (RE)WRITE THE FHB MOVE T1,P2 ;GET BACK THE NEWLY ALLOCATED BLOCK # PUSHJ P,SUSET ;POSITION THE DISK TO THAT BLOCK OUTPUT VIO,[IOWD 1,LOWZRO ;ZERO THE NEW BLOCK 0] ;... JRST CPOPJ1 EXPER0: TYPE <% Cannot extend directory > POPJ P, ; ; VARIOUS RANDOM OUTPUT ERRORS FOR PUT COMMAND ; HERE IF OUTPUT DIRECTORY FOR "PUT" COMMAND DOESN'T EXIST OR ; IF (HOW?) THERE IS MORE THAN 1 DIRECTORY PUTER1: TYPE <% Output directory does not exist for > PUTER0: PUSHJ P,VOLOUT ;TYPE NAME OF VOLUME DMOVE T1,OUTFDB+.FXDIN ;GET DIRECTORY PUSHJ P,TYPDIN ;TYPE DIRECTORY MOVE T1,TMPFDB+.FXNAM ;GET FILE NAME PUSHJ P,SIXOUT ;TYPE 1ST PART OF FILE NAME SKIPE T1,TMPFDB+.F2NAME ;GET 2ND PART OF FILE NAME PUSHJ P,SIXOUT ;TYPE 2ND PART OF FILE NAME TYPE <.> ;SEPERAT HLLZ T1,TMPFDB+.FXEXT ;GET EXTENSION PUSHJ P,SIXOUT ;TYPE FILENAME EXTENSION PJRST CRLF ;AND EXIT PUTER2: TYPE <% Cannot extend directory for > JRST PUTER0 PUTER3: TYPE <% All generation numbers already used for > AOS (P) JRST PUTER0 PUTER4: TYPE <% Cannot OPEN input device for > PUSHJ P,PUTR4B PUSHJ P,CRLF JRST CPOPJ1 PUTR4B: SKIPN T1,OPNBLK+1 ;GET DEVICE NAME MOVSI T1,'???' ;GET ERROR DEVICE NAME PUSHJ P,SIXOUT ;TYPE DEVICE NAME TYPE <:> ;TRAIL WITH SEPERATOR MOVE T1,LERBLK+.RBNAM ;GET FILE NAME FROM RIB PUSHJ P,SIXOUT ;TYPE FILE NAME TYPE <.> ;DOT SEPERATOR FOR FILENAME EXTENSION HLLZ T1,LERBLK+.RBEXT ;GET FILENAME EXTESION FROM RIB SKIPE T1 ;SKIP IF BLANK EXTENSION PUSHJ P,SIXOUT ;TYPE OUT FILENAME EXTENSION PJRST TYPPTH ;TYPE OUT PATH SPEC PUTER5: TYPE <% LOOKUP error > HRRZ T1,LERBLK+.RBEXT ;GET LOOKUP ERROR FROM L/E/R BLOCK PUSHJ P,OCTOUT ;TYPE ERROR NUMBER IN OCTAL TYPE < for > ; PUSHJ P,PUTR4B ;TYPE FILENAME.TYPE PUSHJ P,CRLF ;END WITH CRLF JRST CPOPJ1 ;HERE TO XFER AN IMAGE MODE FILE C$PUTD: SETZM STOCNT ;NO BLOCKS IN FIRST RET POINTER STOR. [R.FIX],RTYP,FHBFOO ;SHOW FIXED TYPE RECORDS STOR. [^D512],RSIZ,FHBFOO ;FIXED LENGTH IS 512 BYTES=1 DISK BLOK ; ^^^ THIS IS THE PLACE TO SETUP OTHER RANDOM FHB VALUES! SETSTS FIO,.IOIMG ;OVERRIDE ASCII, USE IMAGE MODE MOVSI T1,(POINT 36,0,35) ;GET IMAGE MODE BYTE POINTER HLLM T1,DIBUF+.BFPTR ;SO CALCULATIONS BELOW COME OUT RIGHT ;HERE TO READ ANOTHER BLOCK $PUTD1: IN FIO, ;READ BLOCK FROM 10 DISK SKIPA JRST $PUTD2 ;BRANCH IF INPUT FROM TOPS10 FAILED $PUTD3: HRRZ T1,DIBUF+.BFCTR ;GET PDP10 WORD COUNT IMULI T1,4 ;CONVERT TO PDP11 BYTE COUNT MOVNS T1 ;MAKE IT -VE ADDI T1,1000 ;COMPUTE RSX COUNT MOVEM T1,RSXCTR ;SAVE RSX COUNT FOR OUT20F HRRZ T1,DIBUF+.BFPTR ;POINT AT BUFFER ADDI T1,1 ;POINT AT DATA PORTION PUSHJ P,OUT20F ;OUTPUT THAT BLOCK JRST $PUTD1 ;LOOP ;HERE IF ERROR READING TOPS10 FILE $PUTD2: STATZ FIO,IO.ERR ;SKIP IF JUST AN EOF ERROR JRST $PUTD4 ;BRANCH IF REAL SERIOS ERROR JRST PTIEOF ;JOIN COMMON EOF PROCESSOR $PUTD4: TYPE <% Input error > ;HERALD THE ERROR GETSTS FIO,T1 ;GET I/O STATUS FOR THAT CHANNEL PUSHJ P,OCTOUT ;TYPE THE STATUS TYPE < for > ; PUSHJ P,PUTR4B ;TYPE FILE SPEC TYPE <, block > MOVE T1,BLKCNT ;GET RELATIVE BLOCK NUMBER PUSHJ P,DECOUT ;TYPE RELATIVE BLOCK # IN DECIMAL PUSHJ P,CRLF ;END MESG WITH CRLF GETSTS FIO,T1 ;GET STATUS AGAIN TDZ T1,[IO.ERR] ;TURN OFF ANY ERROR BITS SETSTS FIO,(T1) ;FORCE ERROR-FREE STATUS TO TAKE EFFECT JRST $PUTD3 ;GO OUTPUT BLOCK ANYWAY TO PRESERVE SIZE ;ROUTINE TO WRITE A BLOCK TO THE OUTPUT FILE OUT20F: TDZE F,[X%FIR] ;SKIP IF NOT FIRST XFER POPJ P, ;RETURN IMMEDIATELY IF FIRST XFER PUSHJ P,SAVE1 ;SAVE P1 MOVEI P1,(T1) ;COPY BUFFER ADDRESS OUT20: SOSGE STOLFT ;SKIP IF MORE BLOCKS LEFT IN POINTER JRST OUT20A ;BRANCH IF POINTER FULL HRLI T1,-200 ;INSERT A WORD COUNT INTO IOWD HRRI T1,-1(P1) ;CONSTRUCT IOWD STYLE ADDRESS SETZ T2, ;FINISH IOWD LIST OUT VIO,T1 ;WRITE A BLOCK AOSA T1,BLKCNT ;COUNT A GOOD BLOCK IN OUTPUT JRST OUT22F ;GO ANNOUNCE OUTPUT ERROR STOR. BLKCNT,HIBL,FHBFOO ;KEEP TRACK OF LO VBN IN FHB LSH T1,^D-16 ;ISOLATE THE HIGH PART STOR. T1,HIBH,FHBFOO ;KEEP TRACK OF HI VBN IN FHB SOS CHULFT ;ONE LESS IN THE CHUNK AOS CHULBN ;REMAINDER OF CHUNKS STARTS 1 LATER AOS STOCNT ;1 MORE BLOCK IN RET POINTER POPJ P, ;HERE IF WE JUST RAN OUT OF SPACE IN THE POINTER OUT20A: SKIPN BLKCNT ;SKIP IF NOT VERY FIRST TIME JRST OUT20B ;VERY FIRST TIME. PUSH P,T3 ;T3 MAY HAVE ASCII BYTE IN IT MOVE T1,STOCNT ;GET ACTUAL COUNT OF BLOCKS IN POINTER MOVE T2,STOLBN ;GET ACTUAL BASE LBN FOR POINTER MOVEI T3,TMPBUF ;POINT AT OUTPUT FILE'S FHB PUSHJ P,STORET ;SAVE THE RETRIEVAL POINTER IN FHB POP P,T3 ;HERE IF WE DIDN'T HAVE A RETREIVAL POINTER TO STORE OUT20B: SKIPN T1,CHULFT ;SKIP IF MORE SPACE IN CHUNK JRST OUT20C ;BRANCH IF TIME TO ALLOCATE NEW CHUNK CAILE T1,^D256 ;SKIP IF 256 OR LESS MOVEI T1,^D256 ;DON'T LET MORE THAN 256 INTO A POINTER MOVEM T1,STOLFT ;START A NEW POINTER SETZM STOCNT ;NO BLOCKS IN POINTER YET MOVE T1,CHULBN ;GET BASE OF REMAINDER OF CHUNK MOVEM T1,STOLBN ;MAKE IT BASE OF FUTURE POINTER JRST OUT20 ;LOOP TO TRY OUTPUT AGAIN ;HERE IF WE HAVEN'T ANY MORE SPACE AT ALL - ALLOCATE NEW CHUNK OUT20C: MOVE T1,LERBLK+.RBALC ;GET # OF BLOCKS WE NEED PUSHJ P,SCNSBM ;GET THOSE BLOCKS WE WANTED JRST OUT20D ;BRANCH IF VOLUME COMPLETELY FULL MOVEM T1,CHULFT ;SAVE # OF BLOCKS IN NEW CHUNK MOVEM T2,CHULBN ;SAVE # OF FIRST BLOCK IN CHUNK MOVNS T1 ;GET -VE # OF BLOCKS ALLOCATED ADDM T1,LERBLK+.RBALC ;REMEMBER # OF BLOCKS STILL NEEDED MOVE T1,CHULBN ;POSITION TO BEGINNING PUSHJ P,SUSET ;POINT AT THAT BLOCK JRST OUT20 ;LOOP TO TRY OUTPUT AGAIN ;HERE IF WE'RE COMPLETELY OUT OF SPACE IN THE VOLUME OUT20D: TYPE ,OUT23F OUT22F: TYPE <% Output error > GETSTS VIO,T1 ;GET I/O STATUS PUSHJ P,OCTOUT ;TYPE I/O STATUS IN OCTAL OUT23F: TYPE < for > ;PREFACE FILE SPEC PUSHJ P,PUTER0 ;GIVE FILE SPEC TYPE <, file block > MOVE T1,BLKCNT PUSHJ P,DECOUT ;ANNOUNCE BLOCK NUMBER PUSHJ P,CRLF ;GIVE CRLF JRST .ERR ;AND THEN ABORT ;HERE TO XFER AN ASCII MODE FILE C$PUTC: SETOM RSXCTR ;START OFF BUFFERED POINTER SETZM STOCNT ;NO BLOCKS IN FIRST RET POINTER TDO F,[X%FIR] ;FIRST XFER (FORCE "DUMMY" OUTPUT) STOR. [R.VAR],RTYP,FHBFOO ;VARIABLE LENGTH RECORDS STOR. [FD.CR],RATT,FHBFOO ;CR/LF PAIRS IMPLIED INPUT FIO, ;READ A BLOCK STATZ FIO,IO.EOF!IO.ERR ;EOF OR ERROR? JRST $PUTC1 ;YES, GO HANDLE THAT TDZ F,[X%SEQ] ;CLEAR SEQ FILE BIT MOVE T1,DIBUF+.BFPTR ;GET THE POINTER IBP T1 ;MAKE SURE IT'S VALID MOVE T1,(T1) ;GET THE 1ST WORD OF THE FILE TRNE T1,1B35 ;LINE # BIT ON? TDO F,[X%SEQ] ;REMEMBER THIS IS A SEQ FILE MOVE T1,LERBLK+.RBALC ;GET # OF PDP10 BLOCKS IMULI T1,5 ;COMPUTE # OF PDP10 TEXT BYTES IDIVI T1,4 ;COMPUTE # OF PDP11 BLOCKS NEEDED MOVEM T1,LERBLK+.RBALC ;SAVE # OF PDP11 BLOCKS IDIVI T1,<200/^D80> ;COMPUTE # OF "LINES" INVOLVED IMULI T1,2 ;ADD IN THE COUNT BYTES TDNE F,[X%SEQ] ;SKIP IF NOT A LINE-SEQUENCED FILE IMULI T1,2 ;ADD IN THE SEQUENCE BYTES IDIVI T1,1000 ;COMPUTE # OF BLOCKS ADDITIONAL NEEDED ADDI T1,1 ;ONE MORE ADDM T1,LERBLK+.RBALC ;ESTIMATE # BLOCKS NEEDED TOTAL SETZM LINSIZ ;MAX LINE SIZE SEEN WAS 0 BYTES TDZE F,[X%SEQ] ;SKIP IF REGULAR FILE JRST C$PUTE ;COPY A SEQUENCED FILE JRST C$PUTF ;COPY A VARIABLE FILE $PUTC1: STATO FIO,IO.EOF ;SKIP IF EOF (IE: NULL FILE) ERROR JRST PTAEOF ;ODD, NULL FILE ;HERE TO XFER A NORMAL ASCII MODE FILE C$PUTF: MOVSI P1,-<1000*5-1> ;COUNT OF MAX CHARACTERS PER LINE MOVE P2,[POINT 7,LINBUF] ;POINT AT LINE BUFFER TDZE F,[X%FF] ;SKIP IF NO PENDING FF JRST $PUTF5 ; BRANCH IF A FF IS PENDING $PUTF1: JSP T4,GETC ;GET A BYTE JRST [TDO F,[X%EOF] ;REMEMBER EOF TRNN P1,-1 ;SKIP SOME CHARACTER SEEN JRST PTAEOF ;BRANCH IF NO LAST LINE JRST $PUTF2] ;SKIP AHEAD CAILE T3,15 ;SKIP IF POSSIBLE CONTROL CHARACTER $PUTF6: AOBJN P1,[IDPB T3,P2 ;LOOP IF STILL ROOM, INSERT CHARACTER JRST $PUTF1] ;... JUMPGE P1,$PUTF0 ;BRANCH IF OUT OF LINE BUFFER SPACE CAIN T3,15 ;SKIP IF NOT CR JRST $PUTF1 ;BRANCH TO IGNORE CR'S CAIN T3,12 ;SKIP IF NOT LF JRST $PUTF0 ;BRANCH TO TERMINATE LINE, IF LF JUMPE T3,$PUTF1 ;BRANCH TO IGNORE NULL CHARACTERS CAIE T3,14 ;SKIP IF FORM FEED JRST $PUTF6 ;BRANCH IF JUST RANDOM CONTROL CHARATER TDO F,[X%FF] ;TURN ON FF FLAG IF FORM FEED SEEN $PUTF0: HRRZS P1 ;ISOLATE CHARACTER COUNT ;HERE IF WE FIND END OF LINE $PUTF2: PUSH P,P1 ;SAVE BYTE COUNT MOVE T3,(P) ;GET LOW BYTE JSP T4,PUT20F ;SAVE LOW BYTE OF COUNT IN 20F FILE LDB T3,[POINT 8,P1,27] ;GET HIGH BYTE OF COUNT JSP T4,PUT20F ;SAVE HIGH BYTE TOO MOVE P2,[POINT 7,LINBUF] ;GET POINTER HRRZ P1,(P) ;RESTORE P1 JUMPE P1,$PUTF4 ;SKIP XFER OF BYTES IF NONE THERE $PUTF3: ILDB T3,P2 ;GET A BYTE JSP T4,PUT20F ;PUT BYTE IN 20F FILE SOJG P1,$PUTF3 ;LOOP TILL LINE XFERRED $PUTF4: POP P,P1 ;RESTORE BYTE COUNT MOVEI T3,0 TRNE P1,1 JSP T4,PUT20F ;INSERT DUMMY IF ODD BYTE COUNT CAMLE P1,LINSIZ ;SKIP IF LINE NOT ANY BIGGER THAN OTHERS HRRZM P1,LINSIZ ;REMEBER BIGGEST LINE SIZE TDZN F,[X%EOF] ;SKIP IF END OF FILE JRST C$PUTF ;GO GET ANOTHER LINE JRST PTAEOF ;JOIN COMMON CLOSE FILE CODE ;HERE IF WE ARE DEFERRING A FF $PUTF5: MOVEI T3,14 ;GET A FF CHARACTER AOBJN P1,.+1 ;COUNT IT IDPB T3,P2 ;INSERT THE FF INTO THE LINE JRST $PUTF0 ;AND END THIS LINE WITH ONLY FF ON IT ;HERE TO XFER A LINE SEQUENCED ASCII MODE FILE C$PUTE: SETOM LINNUM ;ZERO LINE SEQ # STOR. [R.SEQ],RTYP,FHBFOO ;DECLARE A SEQ'D FILE $PUTE0: SETZ T1, ;ZERO COUNT OF CHARACTERS IN THIS LINE MOVE T2,[POINT 7,LINBUF] ;POINT AT LINE BUFFER $PUTE1: JSP T4,GETC ;GET A BYTE JRST [TDO F,[X%EOF] ;REMEMBER EOF JRST $PUTE2] ;SKIP AHEAD MOVE T4,DIBUF+.BFPTR ;GET POINTER MOVE T4,(T4) ;GET THE 5 CHARS THERE TRNE T4,1 ;CHECK FOR START OF A NEW LINE JRST $PUTE2 ;GO GET LINE NUMBER, FLUSH OLD ONE JUMPE T3,$PUTE1 ;IGNORE NULLS IDPB T3,T2 ;STORE THE BYTE WE JUST GOT AOJA T1,$PUTE1 ;LOOP TILL END OF LINE ;HERE IF WE FIND A LINE SEQ# FLAG $PUTE2: SKIPGE LINNUM ;SKIP IF NOT FIRST TIME JRST $PUTE4 ;BRANCH IF FIRST TIME ;HERE IF WE FIND END OF LINE ADDI T1,2 ;ACCOUNT FOR THE SEQ# BYTES PUSH P,T1 ;SAVE BYTE COUNT MOVE T3,T1 ;GET LOW BYTE OF COUNT JSP T4,PUT20F ;SAVE LOW BYTE OF COUNT IN 20F FILE LDB T3,[POINT 8,(P),27] ;GET HIGH BYTE OF COUNT JSP T4,PUT20F ;SAVE HIGH BYTE TOO MOVE T3,LINNUM ;GET LOW BYTE OF SEQ# JSP T4,PUT20F ;PUT HIGH BYTE OF COUNT IN FILE LDB T3,[POINT 8,LINNUM,27] ;GET HIGH BYTE OF SEQ# JSP T4,PUT20F ;PUT HIGH BYTE IN 20F FILE MOVE T1,(P) ;RESTORE BYTE COUNT SUBI T1,2 ;DISCOUNT THE SEQ# BYTES MOVE T2,[POINT 7,LINBUF] ;GET POINTER $PUTE3: ILDB T3,T2 ;GET A BYTE JSP T4,PUT20F ;PUT BYTE IN 20F FILE SOJG T1,$PUTE3 ;LOOP TILL LINE XFERRED POP P,T1 ;RESTORE BYTE COUNT TRNE T1,1 JSP T4,PUT20F ;INSERT DUMMY IF ODD BYTE COUNT TDZE F,[X%EOF] ;SKIP IF NOT END OF FILE JRST PTAEOF ;CLOSE UP FILE, START ANOTHER ;HERE TO START A NEW LINE STARTING AT LINE NUMBER $PUTE4: SETZ T1, ;START OFF AT 0 LDB T3,DIBUF+.BFPTR ;GET BACK 1ST DIGIT OF LINE NUMBER REPEAT 4,< IMULI T1,^D10 ADDI T1,-"0"(T3) JSP T4,GETC ERROR > IMULI T1,^D10 ADDI T1,-"0"(T3) MOVEM T1,LINNUM ;SAVE LINE # JRST $PUTE0 ;DO ANOTHER ;HERE WHEN WE ARE FINISHED XFER'ING AN ASCII MODE 20F OUTPUT FILE PTAEOF: PUSHJ P,ZERFIL ;GO FILL REMAINDER OF BLOCK WITH 0S MOVEI T1,BLKBFR ;POINT T1 AT OUTPUT BUFFER PUSHJ P,OUT20F ;PUT OUT LAST PARTIAL BUFFER STOR. LINSIZ,RSIZ,FHBFOO ;INSERT THE MAX LINE SIZE PTIEOF: SKIPLE T1,RSXCTR ;SKIP IF WE EXACTLY FILLED LAST BLOCK JRST PTXEOF ;NO, SO GO AHEAD AOSA BLKCNT ;IF EXACT FILL,BUMP EOF TO NEXT BLOCK ;AND SET FFBYTE=0 PTXEOF: MOVEI T1,1000 ;SIZE OF A BLOCK SUB T1,RSXCTR ;GET EOF BYTE STOR. T1,FFBY,FHBFOO ;STORE NUMBER BYTES MOVE T1,BLKCNT ;GET BLOCK COUNT STOR. T1,EFBL,FHBFOO ;STORE LOW ORDER EOF BLOCK # LSH T1,-^D16 ;DROP LOW ORDER PART OF EOF BLOCK STOR. T1,EFBH,FHBFOO ;STORE HIGH ORDER EOF BLOCK # ;HERE WHEN WE ARE FINISHED XFER'ING TO A 20F OUTPUT FILE PUTEOF: MOVE T1,STOCNT ;GET NUMBER OF BLOCKS IN THIS POINTER MOVE T2,STOLBN ;GET BASE LBN FOR THIS POINTER MOVEI T3,TMPBUF ;WHICH BUFFER TO STORETIZE SKIPE T1 ;SKIP IF GROUP WAS LEFT UNUSED PUSHJ P,STORET ;STORE FINAL RETRIEVAL POINTER PAIR MOVE T1,[S$CONT] ;/CONTIGUOUS OUTPUT? LOAD. T2,UCHA,FHBFOO ;GET OLD CHARACTERISTICS TDNE T1,.FXSWT+TMPFDB ;CHECK TDO T2,[UC.CON] ;TURN ON CONTIGUOUS BIT STOR. T2,UCHA,FHBFOO ;STORE NEW CAHRACTERISTICS MOVEI T1,TMPBUF ;POINT AT THE FHB WE BUILT PUSHJ P,WRUFHB ;WRITE OUT FHB AS IS MOVEI T1,TMPBUF PUSHJ P,TYPFHU TYPE <=> MOVEI FP,TMPFDB PUSHJ P,TYPFIO MOVE T1,.FXSWT(FP) TDNE T1,[S$ASCI] TYPE TDNN T1,[S$ASCI] TYPE MOVE T1,.FXSWT+TMPFDB TDNE T1,[S$CONT] TYPE RELEAS FIO, ;RELEASE INPUT FILE PUSHJ P,WRTSBM ;WRITE OUT STORAGE BIT MAP PUSHJ P,WRTIBM ;WRITE OUT INDEX BIT MAP PUSHJ P,UPDDIR ;WRITE OUT DIRECTORY BLOCK ERROR ;NOW GET RID OF OLD FILE'S STORAGE, IF ANY AOS (P) ;FORCE SKIP RETURN TDNN F,[X%SUPER] ;SKIP IF OLD FILE EXISTED JRST [PUSHJ P,CRLF OUTPUT TTY, POPJ P,] SOS (P) ;FORGET SKIP AFTER ALL MOVEI T1,DELBUF ;FILE TO GET RID OF PUSHJ P,RETFHB ;RETURN STORAGE, ETC PUSHJ P,WRTSBM ;REWRITE SBM ;IBM WILL BE THE SAME, SO WILL DIR TDZ F,[X%SUPER] ;NOW TURN OFF SUPERCEED TYPE OUTPUT TTY, JRST CPOPJ1 ;GIVE SKIP RETURN ;ROUTINE TO PUT 1 BYTE IN 20F OUTPUT FILE PUT20F: SOSGE RSXCTR ;CHECK FOR ROOM IN OUTPUT JRST PUT21F ;NO ROOM, MAKE ANOTHER BUFFER MOVS T1,RSXPTR ;GET PDP11 BYTE POINTER INTO BUFFER JSR PUTBYT ;INSERT BYTE AOS RSXPTR ;INCREMENT BYTE POINTER JRST (T4) ;RETURN PUT21F: MOVEI T1,BLKBFR ;POINT AT OUTPUT BLOCK PUSHJ P,OUT20F ;OUTPUT THE BLOCK MOVEI T1,1000 ;GET NEW BYTE COUNT MOVEM T1,RSXCTR ;INIT THE NEW COUNT MOVSI T1,BLKBFR ;GET NEW BYTE POINTER MOVEM T1,RSXPTR ;INIT NEW BYTE POINTER JRST PUT20F ;TRY AGAIN ;ROUTINE TO FILL REMAINDER OF DISK BUFFER WITH 0S ZERFIL: PUSHJ P,SAVE1 ;SAVE P1 SKIPG P1,RSXCTR ;COPY # OF BYTES REMAINING POPJ P, ;RETURN SETZ T3, ;THE CHARACTER TO DO MOVS T1,RSXPTR ZERFI1: JSR PUTBYT ;INSERT A ZERO BYTE SOJG P1,ZERFI1 ;FINISH POPJ P, ;ROUTINE TO GET ONE BYTE FROM THE PDP10 INPUT FILE GETC: SOSGE DIBUF+.BFCTR ;SKIP IF BYTES REMAIN IN BUFFER JRST GETC2 ;BRANCH IF CURRENT BUFFER EMPTY ILDB T3,DIBUF+.BFPTR ;GET A BYTE FROM BUFFER JRST 1(T4) ;GIVE GOOD RETURN GETC2: IN FIO, ;TRY TO GET ANOTHER INPUT BUFFER JRST GETC ;BRANCH TO TRY TO GET BYTE AGAIN STATO FIO,IO.EOF ;SKIP IF END OF FILE FOR INPUT ERROR JRST (T4) ;GIVE NON SKIP IF EOF ON INPUT ;ROUTINE TO GET ONE BYTE FROM 20F INPUT FILE RDBYTE: PUSHJ P,SAVE4 DMOVE P1,T1 ;SAVE T ACS DMOVE P3,T3 ;SAVE T ACS RDBYT0: SOSGE RSXCTR ;CHECK FOR MORE BYTES IN THIS BLOCK JRST RDBYT1 ;NO, GET ANOTHER BLOCK (IF POSSIBLE) MOVS T1,RSXPTR ;GET PDP11 BYTE POINTER JSR GETBYT ;GET BYTE FROM BUFFER AOS RSXPTR ;INCREMENT PDP11 BYTE POINTER DMOVE T1,P1 ;RESTORE T ACS MOVE T4,P4 ;RESTORE T ACS JRST CPOPJ1 ;GIVE GOOD RETURN RDBYT1: MOVEI T1,FHBBUF ;POINT AT THE INPUT FILE FHB AOS T2,RSXVBN ;GET VBN # PUSHJ P,SCNRET ;CONVERT VBN TO LBN JRST [DMOVE T1,P1 ;RESTORE T ACS DMOVE T3,P3 ;RESTORE T ACS POPJ P,] ;GIVE EOF RTURN PUSHJ P,SUSET ;POSITION TO READ THAT LBN IN VIO,[IOWD 200,TMPBUF 0] ;READ THAT BLOCK SKIPA PUSHJ P,G$IER ;REPORT ERROR AND FIX STATUS MOVEI T1,FHBBUF MOVE T2,RSXVBN PUSHJ P,EOFBYT MOVEM T1,RSXCTR ;INIT THE BYTE COUNT MOVNS T1 ;GET -VE ADDI T1,1000 ;GET FFBYTE MOVEM T1,FFBYTE MOVEI T1,TMPBUF ;PDP11 BYTE POINTER MOVSM T1,RSXPTR ;SAVE IT JRST RDBYT0 ;GO GET A BYTE ;ROUTINE TO GET ONE PDP11 WORD FROM 20F INPUT FILE DVWORD: PUSHJ P,SAVE2 ;SAVE SOME ACS PUSHJ P,RDBYTE ;GET LOW ORDER BYTE POPJ P, ;PASS ALONG ERROR RETURN MOVE P1,T3 ;SAVE LOW BYTE PUSHJ P,RDBYTE ;GET HIGH ORDER BYT ERROR LSH T3,^D8 ;PUT HIGH ORDER BYTE IN HIGH POSITION OR T3,P1 ;MERGE HIGH+LOW JRST CPOPJ1 ;GIVE GOOD RETURN ; ROUTINE TO COMPUTE THE # OF BYTES IN THE REQUESTED BLOCK # ;ENTER: T1/ FHB ADR T2/ BLOCK # (BASED ON 0) EOFBYT: PUSHJ P,SAVE4 ;SAVE SOME ACS DMOVE P1,T1 ;SAVE INPUTS PUSHJ P,SCNRET ;TRY TO USETI TO THAT BLOCK JRST [SETZ T1, ;ILLEGAL, SO RETURN 0 POPJ P,] ;... SUBI P1,FHBBUF ;COMPUTE PDP10 OFFSET IMULI P1,4 ;THEN COMPUTE PDP11 OFFSET MOVEI T1,1000 ;DEFAULT TO FULL BLOCK OF BYTES LOAD. T3,EFBL,P1 ;GET LOW EOF BLOCK # LOAD. T4,EFBH,P1 ;GET HIGH EOF BLOCK # LSH T4,^D16 OR T3,T4 JUMPE T3,CPOPJ ;IF EOF NOT SET, GIVE A FULL BLOCK ADDI P2,1 MOVEI T1,0 CAMLE P2,T3 POPJ P, ;NONE IF BEYOND EOF! MOVEI T1,1000 CAME P2,T3 POPJ P,0 LOAD. T1,FFBY,P1 ;GET FIRST FREE BYTE #(EXACTLY=COUNT) POPJ P, ;RETURN ; ROUTINE TO TYPE OUT LITERALLY THE FDB FILE SPEC TYPFDB: PUSHJ P,SAVE1 SKIPE T1,.FXDEV(FP) ;GET VOLUME/DEVICE NAME PUSHJ P,SIXOUT ;TYPE THE DEVIEC NAME SKIPE .FXDEV(FP) TYPE <:> ;TYPE SEPERATOR SKIPE T1,.FXNAM(FP) ;GET FILE NAME PUSHJ P,SIXOUT SKIPE T1,.F2NAM(FP) ;GET 2ND PART OF FILE NAME PUSHJ P,SIXOUT ;TYPE IT TOO HLLZ T1,.FXEXT(FP) ;GET EXTENTION JUMPN T1,[TYPE <.> PUSHJ P,SIXOUT JRST .+1] SKIPN .FXDIR(FP) ;SKIP IF EXPLICIT DIRECTORY GIVEN POPJ P, ;EXIT EARLY IF NO DIRECTORY MOVSI T1,-6 ;GET # OF DIRECTORY PAIRS MOVEI T2,.FXDIR(FP) ;POINT AT THEM TYPFD1: MOVE T3,(T2) ;GET A DIRECTORY MOVEM T3,PTHBLK+.PTPPN(T1) ;STORE IT ADDI T2,2 ;STEP TO NEXT PAIR AOBJN T1,TYPFD1 ;LOOP PUSHJ P,TYPPTH POPJ P, ; ROUTINE TO TYPE OUT THE FILE SPEC ASSOCIATED WITH CHANNEL "FIO" TYPFIO: PUSHJ P,SAVE2 ;SAVE SOME ACS SETZM PTHBLK ;INITIALIZE THE PTHBLK TO ZEROS MOVE T1,[PTHBLK,,PTHBLK+1] ;...SETUP BLT POINTER BLT T1,PTHBLK+PTHLEN-1 ;...AND INSERT THE ZEROS MOVEI T2,FIO ;GET CHANNEL NUMBER DEVNAM T2, ;GET DEVICE OPEN'ED ON THAT CHANNEL MOVSI T2,'NUL' ;DEFAULT IN CASE IT FAILS MOVEI T1,FIO ;GET CHANNEL NUMBER MOVEM T1,PTHBLK+.PTFCN ;STORE FUNCTION CODE MOVE T1,[XWD PTHLEN,PTHBLK] ;ARG POINTER FOR PATH. UUO PATH. T1, ;RETURN PATH INFO FOR THAT CHANNEL MOVEM T2,PTHBLK+0 ;INSERT DEVICE IF IT FAILS MOVE T1,PTHBLK ;GET DEVICE NAME PUSHJ P,SIXOUT ;TYPE THE DEVICE NAME TYPE <:> ;GIVE SEPERATOR ; MOVE T1,.FXNAM(FP) ;GET OUTPUT FILE NAME MOVE T1,LERBLK+.RBNAM ;GET FILE NAME PUSHJ P,SIXOUT ;TYPE OUTPUT FILE NAME TYPE <.> ;GIVE SEPERATOR HLLZ T1,LERBLK+.RBEXT ;GET FILE EXTENSION FROM RIB PUSHJ P,SIXOUT ;TYPE OUTPUT FILE TYPE ;ROUTINE TO TYPE THE PATH SPEC IN THE PTHBLK TYPPTH: TYPE <[> ;START PATH OFF WITH [ HLRZ T1,PTHBLK+2 ;GET THE P, PART OF P,PN PUSHJ P,OCTOUT ;TYPE P, PART TYPE <,> ;GIVE SEPERATOR HRRZ T1,PTHBLK+2 ;GET THE ,PN PART PUSHJ P,OCTOUT ;TYPE THE ,PN PART MOVEI P1,PTHBLK+3 ;POINT AT NEXT SFD TYPPT1: SKIPN T1,(P1) ;PICK UP NEXT SFD NAME JRST TYPPT2 ;DONE TYPE <,> ;GIVE SEPERATOR MOVE T1,(P1) ;PICK UP SFD NAME PUSHJ P,SIXOUT ;TYPE SFD NAME AOJA P1,TYPPT1 ;LOOP FOR ALL SFD NAMS TYPPT2: TYPE <]> ;END PATH WITH ] POPJ P,0 ;RETURN ;ROUTINE TO TYPE OUT A L/E/R ERROR GIVEN THE L/E/R BLOCK LSTLER: TYPE HRRZ T1,LERBLK+.RBEXT ;GET THE ERROR CODE PUSHJ P,OCTOUT ;TYPE ERROR CODE IN OCTAL TYPE < for > MOVE T1,LERBLK+.RBNAM ;GET FILE NAME FROM LER BLOCK PUSHJ P,SIXOUT ;TYPE FILE NAME TYPE <.> ;TYPE SEPERATOR HLLZ T1,LERBLK+.RBEXT ;GET FILE NAME EXTENSION PUSHJ P,SIXOUT ;TYPE FILE NAME EXTENSION MOVE T1,LERBLK+.RBPPN ;GET PPN OF FILE JUMPE T1,LSTDSH ;BRANCH IF USER SPECIFIED DEFAULT PATH TLNN T1,-1 ;SKIP IF USER SPECIFIED EXPLICIT PPN JRST LSTPTH ;GO LIST PATH FROM BLOCK PUSH P,T1 ;SAVE T1 HLRZS T1 ;GET LEFT HALF OF PPN TYPE <[> ;TYPE [ TO START PPN PUSHJ P,OCTOUT ;TYPE LEFT HALF OF PPN TYPE <,> ;TYPE PPN SEPERATOR HRRZ T1,(P) ;RECOVER RIGHT HALF OF PPN PUSHJ P,OCTOUT ;TYPE RIGHT HALF TYPE <]> ;END PPN WITH ] POP P,(P) ;WASTE COPY OF PPN PUSHJ P,CRLF ;END WITH CRLF JRST .ERR ;RESUME ERROR PROCESSING LSTDSH: TYPE <[-]> PUSHJ P,CRLF JRST .ERR LSTPTH: TYPE <[path]> PUSHJ P,CRLF JRST .ERR SUBTTL COMMANDS -- UFD C$UFD: PUSHJ P,TTYPHY PUSHJ P,FILIN ;MUST GET SOME SPEX SKIPN FP,IPLIST ;MUST BE A LIST PUSHJ P,ILLCMD MOVE T1,[FX.EQL] ;DID WE SEEN AN EQUAL? SETO T3, ;T3=-1=COMPLETELY SPECIFIED C$UFD0: SKIPE .FXNAM(FP) ; ERROR TDNN T1,.FXMOD(FP) ; SKIPE .FXEXT(FP) ; PUSHJ P,ILLCMD CAMN T3,.FXDNM(FP) ;SKIP IF DIRECTORY NAME WILD CAME T3,.F2DNM(FP) ;SKIP IF DIRECTORY NAME IS NOT WILD PUSHJ P,ILLCMD ;COMPLAIN IF DIRECTORY NAME WILD SKIPE .FXDIR+2(FP) ;SKIP IF NO SFD LIST PUSHJ P,ILLCMD ;COMPLAIN IF SFD LST GIVEN HRRZ FP,.FXLNK(FP) ;STEP TO NEXT SPEC IF ANY JUMPN FP,C$UFD0 ;CHECK ANOTHER SPEC IF PRESENT HRRZ FP,IPLIST ;POINT AT FIRST SPEC C$UFD1: PUSHJ P,C$UFDA ;GO PROCESS ONE OF THEM HRRZ FP,.FXLNK(FP) ;STEP TO NEXT FILE SPEC, IF ANY JUMPN FP,C$UFD1 ;BRANCH IF MORE TO PROCESS POPJ P, ;DONE C$UFDA: PUSHJ P,SAVFF ;SAVE THE FIRST FREE CORE POINTER PUSHJ P,SAVFP ;SAVE THE FILE POINTER PUSHJ P,OPNVOL ;OPEN THE VOLUME FOR FILE I/O ; LOOK FOR AN ALREADY EXISTING DIRECTORY FILE FOR THE SAME UIC ; IF IT IS PRESENT, ABORT WITH AN ERROR DMOVE T1,.FXDIN(FP) ;GET DIRECTORY NAME MOVEM T1,.FXNAM+UFDFDB ;SAVE 1ST PART MOVEM T2,.F2NAM+UFDFDB ;SAVE 2ND PART TOO SETOM UFDFDB+.FXNMM ;MAKE NAME NOT APPEAR WILD SETOM UFDFDB+.F2NMM ;MAKE SURE 2ND 6 LETTERS APPEAR NOT WILD HRRZI T1,'DIR' ;PICK UP FILE TYPE FOR DIRECTORY FILE HRLOM T1,UFDFDB+.FXEXT ;SPECIFY FILE TYPE AND ENSURE NOT WILD SETZM UFDFDB+.FXDIR ;SPECIFY EXPLICIT OWNER UIC OF [0,0] SETOM UFDFDB+.FXDIM ;MAKE SURE UIC FIELD IS NOT WILD SETZM UFDFDB+.FXDIR+2 ;MAKE SURE UIC FIELD HAS NO SFD! MOVE T1,['000000'] MOVEM T1,UFDFDB+.FXDIN ;DIRECTORY NAME SETZM UFDFDB+.F2DIN SETOM UFDFDB+.FXDNM SETOM UFDFDB+.F2DNM PUSHJ P,RLDINI ;INITIALIZE THE 20F .LKWLD ROUTINE MOVEI T1,UFDFDB ;POINT AT FDB TO FIND MOVEI T2,FAKFDB ;POINT AT FDB TO EXPAND INTO PUSHJ P,NXTFDB ;SCAN FOR ANY MATCHING FILES SKIPA ;SKIP OUT IF NONE FOUND (GOOD!) ERROR ; SCAN THE OWNING DIRECTORY (IE: [0,0]) FOR A HOLE WE CAN USE SETZ P1, ;0S EXCH P1,UFDFDB+.FXNAM ;REMEMBER FILE NAME IN SIXBIT MOVE P4,UFDFDB+.F2NAM ;REMEMBER 2ND HALF AS WELL SETZM UFDFDB+.FXDEV ;ENSURE ALL ZEROS HRRZS UFDFDB+.FXEXT ;EXPLICIT EXT OF 0S C$UFD2: PUSHJ P,RLDINI ;INITIALIZE THE 20F FILE FINDER MOVEI T1,UFDFDB ;FDB TO FIND MOVEI T2,FAKFDB ;FDB TO WRITE INTO PUSHJ P,NXTFDB ;SEARCH FOR THE ENTRY JRST C$UFD3 ;DARN, AREN'T ANY. EXTEND AND TRY AGAIN ; ALLOCATE AN FHB, FILL IT IN AND WRITE IT OUT. MOVEI P2,*4 ;GET OFFSET MOVE P3,WDIOFF SUBI P3,.DIROFF SETZ T1, ;NO SPECIAL FILENUMBER PUSHJ P,ALCFHB ;GO ALLOCATE AN FHB # ;? MOVEM T1,UFDFHB ;SAVE IT MOVEI T2,UFDFHB PUSHJ P,INIFHB ;GO MAKE UP AN FHB FOR ME HLRZ T1,P1 ;GET 1ST PART OF NAME PUSHJ P,C6T5 ;CONVERT TO RAD50 STOR. T1,FNM1,P2 ;STORE INTO OUR FHB STOR. T1,UFN1,P3 ;STORE 1ST PART IN DIRECTORY TOO HRRZ T1,P1 ;GET 2ND PART OF NAME PUSHJ P,C6T5 ;CONVERT TO RAD50 STOR. T1,FNM2,P2 ;STORE INTO OUR FHB STOR. T1,UFN2,P3 ;STORE 2ND PART IN DIRECTORY TOO HLRZ T1,P4 ;GET 3RD PART OF NAME PUSHJ P,C6T5 ;CONVERT TO RAD50 STOR. T1,FNM3,P2 ;STORE INTO OUR FHB STOR. T1,UFN3,P3 ;STORE INTO DIRECTORY FILE TOO MOV. [.RAD50 ],FTYP,P2 ;STORE FILE TYPE INTO OUR FHB MOV. [.RAD50 ],UFTY,P3 ;STORE FILE TYPE IN DIRECTORY TOO LOAD. T1,FSEQ,P2 ;GET SEQ# IN FHB STOR. T1,UFSQ,P3 ;AND COPY SEQ# TO DIRECTORY STOR. [UC.CON],UCHA,P2 ;SPECIFY CONTIGUOUS FILE STOR. [1],RTYP,P2 ;FILE TYPE=#1, FIXED LENGTH RECORDS STOR. [20],RSIZ,P2 ;RECORD SIZE=16. BYTES (8 WORDS) SKIPN T1,V$ALLOC(FP) ;GET /ALLOC:n VALUE MOVEI T1,^D1000 ;MAKE ROOM FOR AT LEAST 1000 FILES IDIVI T1,^D32 ;COMPUTE NUMBER OF BLOCKS REQUIRED CAIE T2,0 ;EXACT FIT? ADDI T1,1 ;NO, ADD ONE MORE BLOCK MOVEM T1,V$SIZE(FP) LDB T2,[POINT 16,T1,19] ;GET HI WORD STOR. T2,HIBH,P2 ;STORE HIGH PART OF HIGH BLOCK STOR. T1,HIBL,P2 ;STORE LOW PART OF HIGH BLOCK AOS T1 ;UP BY ONE TO GET EOF BLOK# LDB T2,[POINT 16,T1,19] ;GET HI WORD STOR. T2,EFBH,P2 ;... STOR. T1,EFBL,P2 ;...SO BLOCK HAVING EOF IS #2 SKIPE V$FPRO(FP) ;? STOR. V$FPRO(FP),FPRO ;USE HIS PROTECTION IF REQUESTED SKIPN T1,V$SIZE(FP) MOVEI T1,1 MOVEM T1,V$SIZE(FP) PUSHJ P,SCNSBM ;GO FIND 1 BLOCK ERROR CAMLE T1,V$SIZE(FP) ;BACK UP? MOVE T1,V$SIZE(FP) ;YES, PLEASE MOVEM T1,V$SIZE(FP) ;SAVE SIZE WE ACTUALLY GOT IMULI T1,^D32 ;COMPUTE # OF ENTRIES MOVEM T1,V$ALLO(FP) ;SAVE # OF ENTRIES MOVE P1,T2 ;SAVE THE BLOCK # MOVEI T3,UFDFHB ;POINT AT FHB TO STORETIZE MOVE T1,V$SIZE(FP) ;GET # OF BLOCKS TO GET PUSHJ P,STORET ;STORE RETRIEVAL PAIR, FIXUP SBM MOVEI T1,UFDFHB ;POINT AT FHB PUSHJ P,WRUFHB ;WRITE A USER FHB MOVE T1,P1 ;GET BLOCK # ALLOCATED MOVE T2,V$SIZE(FP) ;GET NUMBER OF BLOCKS ALLOCATED PUSHJ P,SUSET ;POSITION TO IT C$UFD4: OUT VIO,[IOWD 1,LOWZRO ; 0] ;GO ZERO IT SKIPA TYPE <% Cannot initialize directory to zeroes > SOJG T2,C$UFD4 ;LOOP ZEROING IT ALL PUSHJ P,WRTIBM ;WRITE INDEX BIT MAP PUSHJ P,WRTSBM ;WRITE STORAGE BIT MAP LOAD. T1,FNUM,P2 ;GET ALLOCATED FILE NUMBER STOR. T1,UFNO,P3 ;STORE IN DIRECTORY ENTRY STOR. [0],UFRV,P3 ;STORE 0 IN THE MAGIC PLACE STOR. [1],UVER,P3 ;STORE GENERATION # IN DIRECTORY MOVE T1,WDIPBN ;GET PHYSICAL BLOCK # PUSHJ P,SUSET ;POSITION TO DIRECTORY BLOCK OUT VIO,[IOWD 200,WDIBUF ;REWRITE THE MODIFIED DIRECTORY BLOCK 0] ; SKIPA TYPE <% Failed to insert new ufd name in owning directory > TDON F,[X%INTRO] TYPE MOVEI T1,UFDFHB PUSHJ P,TYPFHU LOAD. T1,FPRO,P2 PUSHJ P,P11OUT TYPE MOVE T1,V$ALLO(FP) PUSHJ P,DECOUT PUSHJ P,CRLF POPJ P, ;ALL DONE ;HERE TO EXPAND THE 000000.DIR TO MAKE ROOM FOR NEW UFD C$UFD3: MOVEI T1,BUF444 ;POINT AT MFD PUSHJ P,EXPDIR ;TRY ERROR JRST C$UFD2 ;GO RESCAN SUBTTL COMMANDS -- DESTROY C$DEST: PUSHJ P,TTYPHY ;FORCE OUTPUT TO PHYSICAL TTY PUSHJ P,FILIN ;GET LIST OF VOLUMES SKIPN FP,IPLIST ;SKIP IF A LIST GIVEN PUSHJ P,ILLCMD ;COMPLAIN IF NO VOLUMES TO DESTROY C$DES0: PUSHJ P,D$RSX ;DESTROY AN RSX FILE SYSTEM HRRZ FP,.FXLNK(FP) ;FETCH LINK TO NEXT VOLUME, IF ANY JUMPN FP,C$DES0 ;BRANCH IF ANOTHER VOLUME TO DESTROY POPJ P,0 ;RETURN IF ALL VOLUMES DESTROYED ; ROUTINE TO DESTROY THE FRONT END AREA OF RSX D$RSX: PUSHJ P,OPNVIO ;OPEN VOLUME FOR I/O SKIPE FAKVOL ;SKIP IF REAL VOLUME NAME GIVEN ERROR TYPE PUSHJ P,VOLOUT ;TYPE VOLUME NAME PUSHJ P,YESNO POPJ P, ;NO PUSHJ P,F11ZAP ;FIND AND ZAP F11 HOME BLOCK DMOVE T1,[SIXBIT .FE. SIXBIT .SYS.] ;LOAD FILENAME, EXTENSION FOR LOOKUP DMOVE T3,[0 1,,4] ;LOAD PPN FOR LOOKUP LOOKUP VIO,T1 ;FIND FE.SYS TYPE <% FE.SYS not found>,D$RSX0 SETZM BLKBFR+.RBNAM ;GET RID OF FILE NAME USETI VIO,0 ;SET TO READ RIB INPUT VIO,[IOWD 200,BLKBFR ; 0] ;READ RIB OF FE.SYS CAME T1,BLKBFR+.RBNAM ;SIMPLISTIC CHECK ERROR ; **** N.B. **** THIS MIGHT NOT WORK TOO WELL ON A MULTI UNIT STRUCTURE MOVE T1,BLKBFR+.RBSLF ;GET BLOCK # OF THE RIB PUSHJ P,SUSET ;POSITION TO IT MOVE T1,[RP.NDL] ;GET THE NO DELETE BIT ANDCAM T1,.RBSTS+BLKBFR ;TURN IT OFF OUTPUT VIO,[IOWD 200,BLKBFR 0] ;ULP - REWRITE RIB CLOSE VIO,CL.DAT ;DELETE THE ACCESS TABLE DMOVE T1,[SIXBIT .FE. SIXBIT .SYS.] ;RELOAD THE FILE NAME FOR THE LOOKUP DMOVE T3,[0 1,,4] ;RELOAD THE PPN FOR THE LOOKUP LOOKUP VIO,T1 ;LOOKUP THE FILE AGAIN ERROR SETZB T1,T2 ;ZERO THE FILE NAME FOR DELETE UUO SETZB T3,T4 ;MAKE WHOLE BLOCK ZEROS RENAME VIO,T1 ;DELETE FE.SYS ERROR TYPE <[> MOVE T1,FEUNIT PUSHJ P,SIXOUT TYPE <:FE.SYS[1,4] deleted, > MOVE T1,BLKBFR+.RBALC ;GET SIZE OF FILE PUSHJ P,DECOUT ;TYPE SIZE OF FILE IN BLOCKS TYPE < blocks freed]> D$RSX0: PUSHJ P,CRLF PUSHJ P,G10HOM ;READ HOME BLOCKS SETZM HOME1+HOMFE0 ;BREAK LINK IN HOME BLOCK TO FE.SYS SETZM HOME1+HOMFE1 ;BREAK LENGTH IN HOME BLOCK SETZM HOME2+HOMFE0 ;BREAK DATA IN 2ND HOME BLOCK TOO... SETZM HOME2+HOMFE1 ;... PUSHJ P,ZERHOM ; RELEASE VIO, ;RELEASE THE VOLUME POPJ P,0 ;RETURN ; ROUTINE TO FIND AND ZAP THE FILES-11 HOME BLOCK FOR THIS VOLUME ; TO LESSEN THE POSSIBILITY THAT RSX20F WILL STUMBLE ACROSS THIS ; NOW OBSOLETE HOME BLOCK IN A SEARCH FOR A HOME BLOCK LATER. F11ZAP: PUSHJ P,G11HOM ;FIGURE OUT WHERE IT IS POPJ P, ;OH WELL, CAN'T FIND IT MOVE T1,H11LBN ;GET THE HOME BLOCK BLOCK# PUSHJ P,SUSET ;POSITION TO THE BLOCK OUTPUT VIO,[IOWD 1,LOWZRO ;ZERO IT 0] ; POPJ P, ;RETURN WITH F11 HOME BLOCK DESTROYED SUBTTL COMMANDS -- ZERO ; ZERO {unit name}{/SIZE:<# OF BLOCKS>} C$INI: PUSHJ P,TTYPHY ;...OPEN UP THE TTY OUTPUT CHANNEL PUSHJ P,FILIN ;GET UNIT, SWITCHES, ETC SKIPN FP,IPLIST ;SKIP IF ANYTHING TO DO PUSHJ P,ILLCMD C$ZER0: PUSHJ P,Z$RSX ;GO ZERO IT HRRZ FP,.FXLNK(FP) ;STEP TO NEXT FILE SPEC JUMPN FP,C$ZER0 ;LOOP IF ANOTHER LEFT POPJ P, ;RETURN WHEN ALL DONE ; HERE TO ZERO RSX20F FILE SYSTEM Z$RSX: PUSHJ P,DOGETS ;GO DO GETTABS AS NEEDED PUSHJ P,OPNVIO ;OPEN UP FOR VOLUME I/O PUSHJ P,MKFESY ;MAKE THE FE.SYS FILE PUSHJ P,ZAPHOM ;GET RID OF OBSOLETE HOME BLOCKS PUSHJ P,MAK11H ;MAKE THE FILES11 HOME BLOCK PUSHJ P,MAKSBM ;MAKE THE STORAGE BIT MAPS PUSHJ P,MAKIBM ;MAKE THE INDEX BIT MAP PUSHJ P,WRT111 ;GO WRITE (1,1,0) INDEXF.SYS PUSHJ P,WRT222 ;GO WRITE (2,2,0) BITMAP.SYS PUSHJ P,WRT333 ;GO WRITE (3,3,0) BADBLK.SYS PUSHJ P,WRT444 ;GO WRITE (4,4,0) 000000.DIR;1 PUSHJ P,WRT555 ;GO WRITE (5,5,0) CORIMG.SYS;1 PUSHJ P,MAKLOS ;GO MAKE TOPS10.SYS;1,2,3,4,5 files PUSHJ P,WRTMFD ;WRITE OUT THE MFD DATA PUSHJ P,WRTSBM ;WRITE THE STORAGE BIT MAPS PUSHJ P,WRTIBM ;WRITE THE INDEX BIT MAP PJRST WRTHOM ;WRITE TOPS-10 HOME BLOCKS ; SUBROUTINE TO "CREATE" THE INDEXF.SYS (1,1,0) FILE WRT111: MOVEI T1,1 ;REQUEST FILE #1 MOVEI T2,FHBBUF ;WHICH ONE TO INITIALIZE PUSHJ P,INIFHB ;INITIALIZE THE FILE HEADER BLOCK MOV. [.RAD50 ],FNAM ;STORE FILE NAME MOV. [.RAD50 ],FTYP ;STORE FILE TYPE ; ATTACH THE BOOT BLOCK TO THIS FILE MOVE T1,[1] ;1 BLOCK MOVE T2,[0] ;AT BLOCK 0 MOVEI T3,FHBBUF ;POINT AT FHB TO STORETIZE PUSHJ P,STORET ;...STORE RETRIEVAL POINTERS ; ATTACH THE FILES11 HOME BLOCK MOVE T1,[1] ;1 BLOCK MOVE T2,H11LBN ;AT THE HOME BLOCK MOVEI T3,FHBBUF ;POINT AT FHB TO STORETIZE PUSHJ P,STORET ;...STORE RETRIEVAL POINTERS ; ATTACH THE FHB SAT LOAD. T1,FMAX ;GET # OF FILE HEADERS PERMITTED IDIVI T1,^D4096 ;COMPUTE # OF BLOCKS NEEDED FOR FHB SAT CAIE T2,0 ;ON THE NOSE? ADDI T1,1 ;NO, SO ADD ONE MORE MOVE T2,H11LBN ;GET THE HOME BLOCK ADDRESS ADDI T2,1 ;HOME BLOCK ADR+1 IS FHB SAT ADR MOVEM T2,IBMLBN ;BLOCK# OF FHB SAT MOVE T3,T1 ;COPY THE # OF BLOCKS ADD T3,T2 ;COMPUTE 1ST FHB BLOCK MOVEM T3,FHBLBN ;REMEMBER IT MOVEI T3,FHBBUF ;POINT AT FHB TO STORETIZE PUSHJ P,STORET ;...STORE RETRIEVAL POINTERS ; ATTACH THE FHB LIST MOVEI T1,M.INFH ;GET INITIAL NUMBER OF FILE HEADERS MOVE T2,FHBLBN ;GET WHERE THEY START MOVEI T3,FHBBUF ;POINT AT FHB TO STORETIZE PUSHJ P,ZERRET ;ZERO THE BLOCKS FIRST PUSHJ P,STORET ;...STORE RETRIEVAL POINTERS ; WRITE THE FHB MOVE T1,[FHBBUF,,BUF111] BLT T1,BUF111+177 ;COPY FHB FOR INDEXF TO WHERE WRUFHB WANTS IT PUSHJ P,WRTFHB ;GO WRITE IT (AND FHB SATS) POPJ P, ;ALL DONE ; SUBROUTINE TO "CREATE" THE BITMAP.SYS (2,2,0) FILE WRT222: MOVEI T1,2 ;REQUEST FILE #2 MOVEI T2,FHBBUF ; PUSHJ P,INIFHB ;INITIALIZE THE FILE HEADER BLOCK DATA MOV. [.RAD50 ],FNAM ;STORE FILE NAME MOV. [.RAD50 ],FTYP ;STORE FILE TYPE ; ATTACH THE BM BUFFER BLOCK TO BITMAP.SYS MOVE T1,[1] ;1 BLOCK MOVE T2,FFBLOK ;1ST FREE BLOCK MOVEM T2,SBMLBN ;SAVE LBN OF IT MOVEI T3,FHBBUF ;POINT AT FHB TO STORETIZE PUSHJ P,STORET ;...STORE RETRIEVAL POINTER ; ATTACH THE SAT BLOCKS TO BITMAP.SYS MOVE T1,LSTLBN ;GET LAST BLOCK # AVAILABLE TO OUR "VOLUME" IDIVI T1,^D4096 ;COMPUTE # OF BLOCKS IN SAT FOR OUR VOLUME CAIE T2,0 ;FIT EXACTLY? ADDI T1,1 ;NO, SO ADD ANOTHER BLOCK MOVE T2,FFBLOK ;1ST FREE BLOCK MOVEI T3,FHBBUF ;POINT AT FHB TO STORETIZE PUSHJ P,STORET ;...STORE RETRIEVAL POINTER PUSHJ P,WRTFHB ;WRITE THE FILE HEADER OUT POPJ P, ;RETURN ; SUBROUTINE TO WRITE OUT (3,3,0) BADBLK.SYS WRT333: MOVEI T1,3 ;REQUEST FILE #3 MOVEI T2,FHBBUF PUSHJ P,INIFHB ;INITIALIZE THE FILE HEADER BLOCK DATA MOV. [.RAD50 ],FNAM ;STORE FILE NAME MOV. [.RAD50 ],FTYP ;STORE FILE TYPE ;; N.B.: NO BLOCKS NEED TO BE ATTACHED! PUSHJ P,WRTFHB ;WRITE THE FILE HEADER OUT POPJ P, ;RETURN ; SUBROUTINE TO WRITE (4,4,0) 000000.DIR (IE: THE MFD) WRT444: MOVEI T1,4 ;REQUEST FILE #4 MOVEI T2,FHBBUF PUSHJ P,INIFHB ;INITIALIZE THE FHB MOV. [.RAD50 <000000>],FNAM ;STORE THE FILE NAME MOV. [.RAD50 ],FTYP ;STORE THE FILE TYPE STOR. [UC.CON],UCHA ;DECLARE FILE IS CONTIGUOUS STOR. [1],RTYP ;RECORD TYPE=#1, FIXED LENGTH RECORDS STOR. [20],RSIZ ;RECORD SIZE=16 (BYTES, ONLY 8 WORDS) STOR. [1],HIBL STOR. [2],EFBL ; MOVEI T1,1 ;1 BLOCK MOVE T2,FFBLOK ;AT NEXT FREE PLACE MOVEM T2,MFDLBN MOVEI T3,FHBBUF ;POINT AT FHB TO STORETIZE PUSHJ P,STORET ;STORE RETRIEVAL POINTERS MOVE T1,MFDLBN ;GET THE BLOCK WE WANT TO USE PUSHJ P,SUSET ;POSITION TO IT OUTPUT VIO,[IOWD 1,LOWZRO 0] ;INITIALIZE IT TO ZEROES MOVE T1,MFDLBN PUSHJ P,TAKSBM ;TAKE IT AWAY FROM SAT JFCL PJRST WRTFHB ; ROUTINE TO WRITE OUT THE MFD DATA AFTER [0,0] CHANGES WRTMFD: MOVE T1,MFDLBN ;GET BLOCK AGAIN PUSHJ P,SUSET ;POSITION DISK OUT VIO,[IOWD 200,MFDDAT ;WRITE OUT THE MFD DATA 0] ;... POPJ P, ;RETURN IF I/O WAS GOOD ERROR ; SUBROUTINE TO WRITE (5,5,0) CORIMG.SYS WRT555: MOVEI T1,5 ;REQUEST FILE #5 MOVEI T2,FHBBUF PUSHJ P,INIFHB ;INITIALIZE THE FHB MOV. [.RAD50 ],FNAM MOV. [.RAD50 ],FTYP STOR. [UC.CON],UCHA ;DECLARE FILE IS CONTIGUOUS MOVEI T1,^D100 ;100 BLOCKS MOVE T2,FFBLOK ;GET THE FIRST FREE BLOCK MOVEI T3,FHBBUF ;POINT AT FHB TO STORETIZE PUSHJ P,STORET ;STORE RETRIEVAL POINTERS STOR. [^D100],HIBL ;INSERT HIGHEST BLOK # ALLOCATED STOR. [^D101],EFBL ;INSERT "FIRST FREE" BLOK (IE: EOF BLOK) PUSHJ P,WRTFHB ;GO WRITE IT OUT POPJ P,0 ; ROUTINE TO CREATE A BUNCH OF FILES IN [0,0] THAT ARE ACTUALLY ; THE BLOCKED TIED UP TO THE TOPS-10 FILE STRUCTURE (IF ANY) ; AND WILL THUS ACCOUNT FOR THE "LOST" BLOCKS. ; (THIS IS NEEDED ONLY TO KEEP "VFY" FROM COMPLAINING. MAKLOS: PUSHJ P,SAVE4 ;SAVE SOME ACS MOVEI P4,6 ;START WITH FILE #6 SKIPN P3,FSTLBN ;SKIP IF LOST FILES NEEDED POPJ P, ;EXIT IF VOLUME ISN'T EMBEDDED MOVEI P2,1 ;CURRENT BASE LBN # ;BLOCK 0 IS ALREADY CLAIMED! MAKLO1: MOVE T1,P3 ;T1=NUMBER OF BLOCKS ;$ CAILE T1,^D26010 ;SKIP IF IT WILL ALREADY FIT ;$ MOVEI T1,^D26010 ;REDUCE IT SO IT WILL SUB P3,T1 ;AND ACCOUNT FOR BLOCKS USED MOVEI T2,(P4) ;T2=FILE # MOVE T3,P2 ;T3=BASE LBN# ADD P2,T1 ;UPDATE BASE LBN# FOR NEXT PASS PUSHJ P,LOSFIL ;MAKE A "LOST" FILE ADDI P4,1 ;GO FOR NEXT FILE NUMBER JUMPN P3,MAKLO1 ;MAKE ANOTHER IF NEEDED POPJ P, ;ROUTINE TO MAKE A LOST FILE ;T1=# BLOCKS (DO NOT CALL WITH T1 .GT. ^D26000 (APPROX) ;T2=FILE# ;T3=BASE LBN# LOSFIL: PUSHJ P,SAVE4 ;SAVE SOME ACS DMOVE P1,T1 ;SAVE T1,T2 DMOVE P3,T3 ;SAVE T3,T4 MOVE T1,T2 ;GET FILE # MOVEI T2,FHBBUF ;POINT AT FHB PUSHJ P,INIFHB ;INITIALIZE FHB MOV. [.RAD50 ],FNAM ;INITIALIZE NAME MOV. [.RAD50 ],FTYP ;STORE UNIQUE FILE TYPE STOR. P2,FVER ;STORE GENERATION NUMBER STOR. P2,FSEQ ;STORE FAKE SEQUENCE # TOO LOSFI1: MOVEI T1,^D255 ;# OF BLOCKS TO GRAB CAMLE T1,P1 ;SKIP IF THAT IS OK MOVE T1,P1 ;DO ALL OF REMAINDER IF LESS THAN 255 SUB P1,T1 ;ADJUST COUNT FOR NEXT PASS MOVE T2,P3 ;GET THE BASE LBN# OF THEM ADD P3,T1 ;ADJUST BASE LBN FOR NEXT PASS MOVEI T3,FHBBUF ;POINT AT BUFFER PUSHJ P,STORET ;GO ARRANGE FOR IT JUMPN P1,LOSFI1 ;LOOP IF MORE BLOCKS TO GRAB PUSHJ P,WRTFHB ;GO WRITE THE FILE POPJ P, ; SUBROUTINE TO DESTROY ANY BLOCKS THAT MIGHT BE OLD HOME BLOCKS ZAPHOM: MOVE T1,FSTLBN ;GET FIRST LBN PUSHJ P,SUSET ;POSITION TO IT OUTPUT VIO,[IOWD 1,LOWZRO ; 0] ;WRITE 1ST LBN TO ZEROES AOS T1,LASSET ;PICK UP 2ND LBN ZAPHO1: PUSHJ P,SUSET ;POSITION TO IT OUTPUT VIO,[IOWD 1,LOWZRO ; 0] ;WRITE NEXT LBN TO ZEROES MOVE T1,LASSET ;GET LAST I/O BLOCK TRZ T1,377 ;TRIM OFF LOW ORDER BITS ADDI T1,400 ;ADVANCE TO NEXT POSSIBLE HOME BLOCK CAMGE T1,LSTLBN ;SKIP IF BEYOND BOUNDS OF VOLUME CAMLE T1,H11LBN ;SKIP IF BELOW NEW HOME BLOCK # POPJ P, ;ALL DONE IF BEYOND BOUNDS JRST ZAPHO1 ; SUBROUTINE TO MAKE THE FILES11 HOME BLOCK (AND WRITE IT OUT) MAK11H: SETZM H11BUF ; MOVE T1,[H11BUF,,H11BUF+1] BLT T1,H11BUF+177 ;CLEAR FILES-11 HOME BLOCK ('CEPT DECFILE11A) MOVE T1,[TMP166,,H11BUF+166] BLT T1,H11BUF+177 ;INSERT MAGIC CONSTANTS SKIPN T1,V$MAXF(FP) ; MOVE T1,[M.FMAX] ;GET DEFAULT IDIVI T1,^D4096 ;DIVIDE BY # BITS PER DISK BLOCK CAIE T2,0 ;ANY LEFT OVER? ADDI T1,1 ;YES, NEED ONE MORE STOR. T1,IBSZ ;STORE "INDEX-BIT-MAP SIZE" (FILE HEADER SAT) MOVE T1,H11LBN ;GET BLOCK# OF HOME BLOCK ADDI T1,1 ;+1 MAKES IT BLOCK# OF INDEX BIT MAP STOR. T1,IBLL ;STORE LOW PART OF ADDRESS OF FH SAT LSH T1,-^D16 ;GET NEXT WORD STOR. T1,IBLH ;STORE HIGH PART OF ADDRESS OF FH SAT SKIPN T1,V$MAXF(FP) ; MOVE T1,[M.FMAX] STOR. T1,FMAX ;STORE IN HOME BLOCK STOR. [M.SBCL],SBCL ;STORE CLUSTER SIZE STOR. [401],VLEV ;STORE STRUCTURE LEVEL PUSHJ P,MAKLAB ;GO INSERT THE VOLUME LABEL(S) MOVE T1,.FXDIR(FP) ;GET OWNDER'S UIC HLRZ T2,T1 ;GET PROJECT # DPB T2,[POINT 8,T1,27] SKIPN T1 MOVE T1,[M.VOWN] ;DEFAULT IT STOR. T1,VOWN ;STORE VOLUME OWNER'S UIC SKIPN T1,V$VPRO(FP) ;GET VOLUME PROTECTION MOVE T1,[M.VPRO] ;NONE, GET DEFAULT STOR. T1,VPRO ;PUT INTO HOME BLOCK MOVE T1,[M.VCHA] ;GET DEFAULT VOLUME CHARACTERISTICS TDZ T1,V$CHAR(FP) ;TURN OFF APPROPRIATE BITS STOR. T1,VCHA ;STORE VOLUME CHARACTERISTICS SKIPN T1,V$FPRO(FP) ;ANYTHING? LDB T1,[POINTR(.FXMOD(FP),FX.PRO)] SKIPN T1 MOVE T1,[M.DFPR] ;FINAL DEFAULT STOR. T1,DFPR ;STORE DEFAULT FILE PROTECTION STOR. [M.WISZ],WISZ ;STORE # OF RET POINTERS IN WINDOW SKIPN T1,V$EXTE(FP) ;GET IT IF SPECIFIED MOVE T1,[M.FIEX] ;ELSE DEFAULT IT STOR. T1,FIEX ;STORE DEFAULT #BLKS IN AN EXTEND OPERATION STOR. [M.LRUC],LRUC ;STORE #ENTRIES IN DIRECTORY LRU MOVE T1,LOCDAY ;GET TODAY PUSHJ P,MAKSD ;MAKE 2 DIGITS ASCII MOV. T1,VDAY ;STORE IT MOVE T1,LOCMON ;GET MONTH MOV. MONTAB-1(T1),VMON;STORE MONTH MOVE T1,LOCYER ;GET YEAR SUBI T1,^D1900 ;ISOLATE xx PART OF 19xx PUSHJ P,MAK2D ;MAKE INTO 2 DIGITS ASCII MOV. T1,VYER ;STORE YEAR MOVE T1,LOCHOR ;GET HOUR PUSHJ P,MAKSD ;MAKE INTO 2 DIGITS MOV. T1,VHOR ;STORE HOUR MOVE T1,LOCMIN ;GET MINUTE PUSHJ P,MAK2D ;MAKE INTO 2 DIGITS MOV. T1,VMIN ;STORE MINUTES MOVE T1,LOCSEC ;GET SECONDS PUSHJ P,MAK2D ;MAKE INTO 2 DIGITS MOV. T1,VSEC ;STORE SECONDS ; DECFILE11A IS ALREADY AT OFFSETS 166-176 MOVEI T1,H11BUF ;POINT AT BLOCK TO CHECKSUM MOVEI T2,O.CHK1/2 ;COMPUTE # OF WORDS TO CHECKSUM PUSHJ P,CHKSUM ;COMPUTE CHECKSUM STOR. T1,CHK1 ;STORE IT MOVEI T1,H11BUF ;POINT AT BLOCK TO CHECKSUM MOVEI T2,O.CHK2/2 ;COMPUTE # OF WORDS TO CHECKSUM PUSHJ P,CHKSUM STOR. T1,CHK2 ;STORE THAT TOO MOVE T1,H11LBN ;GET ADDRESS OF HOME BLOCK PUSHJ P,SUSET ;POSITION TO FILES11 HOME BLOCK OUT VIO,[IOWD 200,H11BUF 0] SKIPA ERROR POPJ P, ; SUBROUTINE TO DECIDE ON A VOLUME LABEL AND INSERT IT INTO HOME BLOCK MAKLAB: PUSHJ P,SAVE2 ;SAVE 2 ACS MOVE T1,.FXNAM(FP) ;GET 1ST HALF OF FILENAME MOVE T2,.F2NAM(FP) ;GET 2ND HALF OF FILENAME JUMPN T1,MAKLA1 ;BRANCH IF WE HAVE A LABEL JUMPN T2,MAKLA1 ;BRANCH IF WE HAVE LEADING SPACE POPJ P, ;DON'T LABEL UNLESS SPECIFIC REQUEST MAKLA1: DMOVE P1,T1 ;SAVE THE NAME FOR LATER MOVE T3,[O.VNAM,,A.VNAM] ;POINT AT 1ST VOLUME NAME PUSHJ P,PUTSIX ;GO PUT IN SIXBIT STRING DMOVE T1,P1 ;RESTORE THE NAME FROM BEFORE MOVE T3,[O.INDN,,A.INDN] ;POINT AT 2ND VOLUME NAME PUSHJ P,PUTSIX ;PUT IT HERE TOO POPJ P, ; SUBROUTINE TO INSERT A 2WORD SIXBIT STRING INTO PDP11 TEXT FIELD PUTSIX: PUSHJ P,SAVE4 ;SAVE SOME ACS DMOVE P1,T1 ;COPY THE 2 WORD NAME SETZ P3, ;END WITH A GUARENTEED ZERO MOVE P4,[POINT 6,P1] ;POINT AT THE TEXT MOVE T1,T3 ;COPY THE BYTE POINTER PUTSI1: ILDB T3,P4 ;GET NEXT TEXT BYTE JUMPE T3,CPOPJ ;ALL DONE IF NO MORE TEXT ADDI T3," " ;CONVERT TO UPPER CASE ASCII JSR PUTBYT ;INSERT THE BYTE JRST PUTSI1 ;LOOP SUBTTL ROUTINES TO MANAGE THE INDEX FILE ; THE INDEX CONSISTS OF TWO PARTS, THE INDEX-BIT-MAP AND ; THE INDEX-LIST. ; ; THE FILE INDEXF.SYS[0,0] CONSISTS OF THE BOOT BLOCK (BLOCK0), ; THE HOME BLOCK, AND THE INDEX-BIT-MAP AND INDEX-LIST. ; ; THE INDEX-BIT-MAP IS A BIT MAP WITH ENOUGH BITS TO REPRESENT ; EACH POSSIBLE FILE-HEADER-BLOCK. THE NUMBER OF FILE-HEADER-BLOCKS ; PERMITTED IN A VOLUME IS IN THE H.MAXF WORD IN THE VOLUME HOME BLOCK. ; ; EACH BLOCK IN THE INDEX-BIT-MAP ("IBM") CAN REPRESENT 4096 FHBS. ; NO VOLUME CAN HAVE MORE THAN 15 BITS WORTH OF FILES, SO NO IBM ; CAN BE LARGER THAN (2**15)/4096 = 8 BLOCKS. ; ; THE INDEX-LIST CONSISTS OF ALL THE FILE HEADER BLOCKS. IF A FHB ; IS ACTUALLY BEING USED FOR A FILE, THEN THE CORRESPONDING BIT IN ; THE IBM IS A "1". (THUS, THE IBM "SAT" USES OPPOSITE LOGIC TO ; THE SBM "SAT"). ; ; THE FIRST 5 BLOCKS OF THE INDEX-LIST MUST BE PHYSICALLY CONTIGUOUS ; WITH THE IBM BLOCKS, BECAUSE THEY ARE USED TO FIND THE "KNOWN FILES". ; ; THE REMAINDER OF THE INDEX-LIST MAY BE SCATTERED THROUGHOUT THE ; FILES-11 VOLUME. ORDINARYILY ONLY ENOUGH BLOCKS ARE ALLOCATED TO ; THE INDEX-LIST TO ACCOUNT FOR THE FHBS IN USE (PLUS A SMALL ADDITIONAL ; NUMBER TO REDUCE OVERHEAD). FILE NUMBERS ARE ALWAYS ALLOCATED FROM ; THE IBM USING THE LOWEST FREE NUMBER. ; ; THE KNOWN FILES ARE GIVEN FILE NUMBERS OF 1 THROUGH 5. ; ; FILE#1 INDEXF.SYS ; FILE#2 BITMAP.SYS THE STORAGE-ALLOCATION-BIT-MAP ; FILE#3 BADBLK.SYS A FILE WHOSE RETRIEVAL POINTERS ARE BAD BLOCKS ; FILE#4 000000.DIR A DIRECTORY FILE HOLDING THE KNOWN FILES ; FILE#5 CORIMG.SYS A FILE WITH (POSSIBLY) AN IMAGE OF THE MONITOR ; ROUTINE TO MAKE AN INDEX BIT MAP FROM SCRATCH MAKIBM: LOAD. T1,FMAX ;LOAD T1=MAX# OF FHBS (FROM HOME BLOCK) IDIVI T1,^D4096 ;LOAD T1=# BLOCKS IN IBM... ;...BY DIVING MAX# FHBS/#BITS PER BLOCK CAIE T2,0 ;SKIP IFF NO REMAINDER ADDI T1,1 ;COUNT ONE MORE BLOCK TO COVER OVERAGE IMULI T1,200 ;CONVERT T1=#PDP10 WORDS FOR IBM MOVEM T1,IBMSIZ ;REMEMBER #PDP10 WORDS FOR INCORE IBM PUSHJ P,GETCOR ;GET MEMORY FOR INCORE IBM MOVEM T1,IBMINC ;REMEMBER ADDRESS OF INCORE IBM SETZM MFDDAT ;INITIALIZE THE DATA IN 000000.DIR MOVE T1,[MFDDAT,,MFDDAT+1] ;... BLT T1,MFDDAT+177 ;... POPJ P, ;RETURN ; ROUTINE TO WRITE THE INCORE IBM ONTO DISK (IE: INTO INDEXF.SYS) WRTIBM: MOVE T1,IBMLBN ;LOAD T1=LBN OF ONDISK IBM PUSHJ P,SUSET ;POSITION DISK HRRZ T1,IBMSIZ ;LOAD T1=SIZE OF MAP IN PDP10 WORDS IMUL T1,[-1,,0] ;CONVERT T1=AOBJN INTO MAP HRR T1,IBMINC ;INSERT RH(T1)=POINTER TO MAP DATA SUBI T1,1 ;CONVERT T1=IOWD INTO MAP DATA SETZ T2, ;LOAD T2=ENDING IOWD OUT VIO,T1 ;XFER MAP DATA TO DISK POPJ P, ;RETURN IF I/O WAS GOOD ERROR ; ROUTINE TO READ THE IBM INTO CORE REDIBM: MOVE T1,IBMLBN ;LOAD T1=LBN OF ONDISK IBM PUSHJ P,SUSET ;POSITION DISK MOVE T1,IBMSIZ ;GET SIZE OF IBM IN WORDS PUSHJ P,GETCOR ;ALLOCATE CORE FOR IT MOVEM T1,IBMINC ;SAVE ADDRESS OF INCORE IBM MOVE T1,IBMSIZ ;GET SIZE OF IBM IN WORDS IMUL T1,[-1,,0] ;MAKE INTO IOWD COUNT HRR T1,IBMINC ;INSERT ADDRESS SUBI T1,1 ;IOWDIZE THE ADDRESS FIELD SETZ T2, ;END THE IOWD LIST IN VIO,T1 ;READ THE IBM INTO CORE SKIPA ;SKIP IF I/O WAS GOOD ERROR MOVEI T3,0 ;START FILE COUNT AT 0 HRRZ T1,IBMINC ;GET POINTER TO INCORE IBM HRLI T1,(POINT 1,0) ;CONVERT TO BYTE POINTER MOVE T2,IBMSIZ ;GET # OF WORDS IN IBM IMULI T2,^D36 ;COMPUTE MAX # OF BITS REDIB2: ILDB T4,T1 ;READ A BIT FROM IBM CAIE T4,0 ;SKIP IF FILE IS FREE ADDI T3,1 ;COUNT A FILE IN USE SOJG T2,REDIB2 ;LOOP FOR ALL POSSIBLE FILES LOAD. T1,FMAX ;GET MAX POSSIBLE FILES SUB T1,T3 ;COMPUTE # OF FREE FILES MOVEM T1,FHBTAL ;SAVE # OF FREE FIELS POPJ P, ;RETRN ; ROUTINE TO ALLOCATE A FILE # ALCFHB: PUSHJ P,SAVE1 ;SAVE P1 MOVE P1,T1 ;COPY INITIAL FILE NUMBER REQUESTED LOAD. T3,FMAX ;LOAD T3=MAX# OF FILES MOVE T2,T3 ;COPY T2=MAX FILE # IMUL T3,[-1,,0] ;CONVERT T3=AOBJN COUNTER OF FILES HRRI T3,1 ;INSERT RH(T3)=1ST FILE NUMBER CAIE T1,0 ;USE 1 IF 0 CAIL T1,(T2) ;USE 1 IF ILLEGAL REQUEST SKIPA HRRI T3,(T1) ;USE REQUEST IF LEGAL ALCFH1: MOVEI T1,-1(T3) ;LOAD T1=CORRESPONDING BIT# OF FILE (T3) IDIVI T1,^D32 ;LOAD T1=WORD#, T2=BIT# ADD T1,IBMINC ;CONVERT T1=ADDRESS OF CORRECT BIT MOVE T2,B32TBL(T2) ;CONVERT T2=BIT MASK TDNE T2,@T1 ;SKIP IF THIS FILE# (IE: FHB) IS FREE AOBJN T3,[JUMPE P1,ALCFH1 ; BRANCH IF NONSPECIFIC REQUEST ERROR ] JUMPGE T3,[ERROR ] ORM T2,@T1 ;GRAB THE FHB INDEX NOW MOVEI T1,(T3) ;LOAD T1=FILE # WE KNOW TO BE FREE POPJ P, ;RETURN WITH T1=FREE FILE # ; ROUTINE TO "RETURN AN RHB" ; T1/ FHB BUFFER ADDRES ; ; THIS ROUTINE RETURNS ALL THE BLOCKS ALLOCATED TO THE FILE WHOSE FHB ; IS IN T1, AND THEN RETURNS THE FHB BLOCK BASED ON THE FILE# IN THE FHB. ; **THE CALLER IS RESPONSIBLE FOR UPDATING ANY DIRECTORIES THAT ; **MIGHT POINT AT THIS FHB!! RETFHB: PUSHJ P,SAVE4 ;SAVE P1,P2 RETFH0: MOVE P1,T1 ;COPY P1=FHB BUFFER ADDRESS SUBI P1,FHBBUF ;COMPUTE PDP10 OFFSET IMULI P1,4 ;AND THEN COMPUTE PDP11 OFFSET MOVE P4,P1 ;COPY PROPER OFFSET LOAD. T1,FNUM,P1 ;GET FILE NUMBER SUBI T1,1 IDIVI T1,^D32 ; ADD T1,IBMINC ;MAKE P1=ADDRESS OF WORD WITH CORRECT BIT MOVE T2,B32TBL(T2) ;MAKE P2=BIT MASK TDNN F,[X%SUPER] ;DO NOT DEALLOCATE THE RE-USED FHB ANDCAM T2,@T1 ;TURN OFF BIT FOR THIS FHB LOAD. T3,USE,P1 ;GET T3=# POINTERS IN USE JUMPE T3,CPOPJ ;EXIT IF A NULL FILE MOVE P3,T3 ;COPY P3=T3, # POINTERS IN USE LSH P3,-1 ;MAKE P3=# PAIRS IN USE RETFH1: LOAD. T4,RCNT,P1 ;GET # OF BLOCKS IN THIS PAIR ADDI T4,1 ;MAKE T1=TRUE # OF BLOCKS LOAD. T1,RLBN,P1 ;GET LOW LBN LOAD. T2,HRET,P1 ;GET HIGH LBN LSH T2,^D16 ;MAKE ROOM FOR LOW LBN OR T1,T2 ;T1=FINAL LBN PUSHJ P,GIVSBM ;GIVE THAT BLOCK BACK SOJG T4,[AOJA T1,.-1] ;RETURN ALL BLOCKS IN THAT POINTER ADDI P1,4 ;STEP TO NEXT RETRIEVAL PAIR SOJG P3,RETFH1 ;LOOP AND RELEASE THOSE BLOCKS TOO LOAD. T1,CLL,P4 ;GET CORE LINK LOW LOAD. T2,CLH,P4 ;GET CORE LINK HIGH LSH T2,^D16 ;POSITION CORE LINK HIGH OR T1,T2 ;MERGE SO THAT T1=CORE LINK ADDRESS JUMPN T1,RETFH0 ;BRANCH TO RELEASE NEXT SEG, IF ANY POPJ P, ; ROUTINE TO INITIALIZE THE FILE HEADER BUFFER ; T1/ FILE # ; T2/ FHB BUFFER ADDRESS INIFHB: PUSHJ P,SAVE2 ;SAVE SOME ACS DMOVE P1,T1 ;P1=FILE #, P2=FHB BUFFER TDO F,[X%DEX] ;DON'T CHAIN THE FHBS DURING THE READ PUSHJ P,REDFHB ;READ IN OLD COPY OF FHB TDZ F,[X%DEX] ;ALLOW CHAINING AGAIN MOVEI T2,(P2) ;COPY FHB BUFFER ADDRESS SUBI P2,FHBBUF ;CREATE PDP10 OFFSET IMULI P2,4 ;...AND THEN PDP11-IZE THAT LOAD. T1,FSEQ,P2 ;LOAD OLD SEQUENCE # SETZM (T2) ;START TO ZERO IT OUT HRLI T2,(T2) ;COPY ADDRESS ADDI T2,1 ;TURN INTO BLT POINTER MOVEI T3,176(T2) ;POINT AT LAST FHB WORD BLT T2,(T3) ;ZERO THE INITIAL FHB ADDI T1,1 ;BUMP SEQ # UP ONE STOR. T1,FSEQ,P2 ;INSERT INTO THE FHB STOR. [M.IDOF],IDOF,P2 ;INIT ID AREA OFFSET STOR. [M.MPOF],MPOF,P2 ;INIT MAP AREA OFFSET STOR. P1,FNUM,P2 ;INIT FILE # CAIG P1,5 ;SKIP IFF NOT A SYSTEM FILE STOR. P1,FSEQ ;FOR KNOWN FILES, MAKE SEQ#=FILE# STOR. [M.FLEV],FLEV,P2 ;INIT STRUCTURE LEVEL ST