.TITLE JUICER_2 .SUBTITLE DECLARATIONS .MACRO VERSION ACTION ACTION /V02-018/ .ENDM VERSION VERSION .IDENT ; DEBUG=0 ;LOG MOVES ;V02-010 ; DEBUG2=50 ;LIMIT NUMBER OF CONTIGUOUS FILES COLLECTED ; DEBUG3=0 ;ASK IF MOVE OK TO DO ; ; Rewrite of the original JUICER program. This version ; is intended to do on-line disk compression and file ; defragmentation. ; ; Michael N. LeVine ; Naval Weapons Center ; Code 3514 ; China Lake ; Ca 93555 ; (619)939-3970 ; avn 437-3970 ; ; ; To run this program, the following is required: ; ; Privileges: ; ALTPRI ; BYPASS ; SYSNAM ;V02-002 ; ; Other: ; Process name must be changed to the name of the disk ; to be worked on. ; .ENABLE DEBUG .LIBRARY /SYS$LIBRARY:LIB.MLB/ $DCDEF ;Device type flags $DVIDEF ;Device information parameters $FATDEF ;File attributes $FH2DEF ;Declare structure of file header $FI2DEF ;File header ident area $FM2DEF ;File headr map area $HM2DEF ;Home block structure $IODEF ;I/O codes $JPIDEF ;Get JPI data items $LNMDEF ;Logical name table values $RMSDEF ;RMS error codes $SCBDEF ;Storage Control Block $SSDEF ;System Service error codes .PAGE .SUBTITLE UPDATE HISTORY ; ; 23-APR-1987 MNL V02-001 ; All files moved take on placement control entries in ; the file header map area-see if by decrementing starting ; LBN by one from wanted location will prevent this. ; ; 6-May-1987 MNL V02-002 ; Added use of logical names to pass information ; on current program status. Two logical names used ; JUICER_2_disk_STATUS= current status of program ; JUICER_2_disk_FILE= name of current or last file ; being moved. ; Both logicals placed in system logical name table. ; ; 8-May-1987 MNL V02-003 ; Added to verboten list VMB for 750's and logical ; JUICER_2_disk_PASSES_COMPLETED ; ; 21-May-1987 MNL V02-004 ; Added code to do on-line calc of disk frag,file frag ; and display in logical JUICER_2_disk_FRAG ; 19-June-1987 MNL V02-005 ; PSECT UPDATE_DISK_DATA_DATA was marked SHR, should have been ; NOSHR--corrected. ; 19-June-1987 MNL V02-006 ; Added code to display progress of various parts of ; JUICER_2 run. JUICER_2_disk_COUNT. ; 22-June-1987 MNL V02-007 ; Modified code to add new queue,modified data strurures ; and selection process. New queue is for fragmented ; files not in top 10. Selection process for defrag_disk ; phase will now check first in the new queue for ; candidates before going to the contiguous files queue. ; 24-June-1987 MNL V02-008 ; Modified code to add new queues for fragmented and ; unfragmented files larger than lrgest free frag ; available and for files larger than the total free ; space available on disk. ; Merge data structures for CONTIG and FRAG files so ; same structure used for both. ; 25-June-1987 MNL V02-009 ; Merged FRAGMENTED_FILES_QUEUE AND OTHER_FRAG_FILES_QUEUE. ; Split CHECK_ACCESS into CHECK_LIST for scan file headers ; and CHECK_ACCESS for decideing if file is candidate. ; 29-June-1987 MNL V02-010 ; Added new queue- REJECTED_FILES_QUEUE and dump code ; to dump to file on locating of logical symbol ; JUICER_2_devname_Q_queuename="file name to dump to". ; 29-June-1987 MNL V02-011 ; Modify code so the temp file into which the old file ; is copied is no longer named ; $$$$____JUICER_2____$$$$.$$$$____DUP_FILE____$$$$ ; The new name is the name of the file being moved ; with "$$$$"added just after the end of the directory ; string terminator "]". ; 30-June-1987 MNL V02-012 ; Added dump of directory files queue to those added ; is V02-010 also added auto stop on flag JUICE_2_dev_STOP. ; 9-July-1987 MNL V02-013 ; Fix returned status for some cases of checking logical ; name presence. ; 9-July-1987 MNL V02-014 ; Error handleing ACL's-got carried over to other files. ; 14-July-1987 MNL V02-015 ; Added new field to file data-highest lbn ; 22-July-1987 MNL V02-016 ; Added move option to look through LARGE_CONTIG and ; LARGE_FRAG files for file with highest high LBN and ; force it to be a the low end of disk-fragmented ; but out of the high end. Do it to one file every ; eight passes.Files marked CONTIGUOUS are exempt. ; 18-Feb-1988 MNL V02-017 ; Bug reported by Cliff Bicker of NWC-JUICER dies due ; to access violation. Problem found in routine ; FORCE_FILE_MOVE-used high LBN for pointer to ; queue entry ; 20-Sep-1988 MNL V02-018 ; make changes needed for VMS V5.0-1. ; Note that system disk organization for stand alone ; systems is now the same as for cluster common disks ; with SYS$SPECIFIC and SYS$COMMON paths. ; also changed number of passes between calls to ; FORCE_FILE_MOVE from 4 to 8 ; ; .PAGE .SUBTITLE DESCRIPTION OF KEY DISK FILE STRUCTURE FILES ; ; The information below on the ODS-2 file structure is current ; as of VMS 5.0-1. It contains the best approximation I have been ; able to provide as to the structures described below but is ; not guarenteed to be 100% accurate or not to change with new ; versions (minor or major updates) of VMS. Not all the data ; structures used by VMS in ODS-2 are described below, only ; those that I was directly or indirectly concerned with ; in writeing the JUICER package. Anyone useing this ; information does so at their own risk. ; ; At its most basic level, the file structure of a disk is based ; on three files: ; 1. 000000.DIR this is the master file directory ; this directory contains all the file ; structure files (includeing itself), and ; is the starting point for all user and system ; directory trees. ; 2. INDEXF.SYS boot block,home blocks, file header bit map ; and all file headers ; 3. BITMAP.SYS Storage Control Block and disk block allocation ; bitmap. ; ; ; ; This program makes direct use of the following files ; [000000]BITMAP.SYS ; [000000]INDEXF.SYS ; ; The file BITMAP.SYS is a bit map of the ; block clusters on the target disk.VBN 1 is the Storage Control ; block (see $SCBDEF). The rest of the file is a bit map, each ; bit representing one cluster on disk, if the bit is clear (0), the ; cluster is in-use. ; ; ; The file [000000]INDEXF.SYS consists of the following: ; where X is the cluster factor of the disk ; ; VBN 1 Boot block(only used by CPU's such as the 750 ; which do not need to boot off of CSA1:) ; This block is physically located on disk ; at LBN 0. ; VBN 2..2X Home block(s)(used by VMS to identify the disk ; and to find its way into the file structure. ; The following details on the placement of the ; home blocks is taken from the VMS V3.x RMS ; reference manual. The main home block is the ; first good block in the home block search ; sequence 1+n*DELTA where n=0,1,2,..... ; DELTA is computed from the geometry of the disk. ; s=sectors/track ; t=tracks/cylinder ; c=cylinders/disk ; ; Geometry ; s t c DELTA ; - 1 1 1 ; 1 - 1 1 ; 1 1 - 1 ; - - 1 s+1 ; - 1 - s+1 ; 1 - - t+1 ; - - - (t+1)*s+1 ; ; Usually LBN 1 wil be a good block so it will ; be the Main home block. ; VBN 2X+1..3X Backup home block(s). Just in case of corruption ; of the main home block, a backup is available. ; The placement is in the next good block found in the ; continuation of the search sequence used to locate ; the main home block. ; VBN 3X+1..4X Copy of file header block for INDEXF.SYS ; This is used if the original file header ; has been destroyed. ; VBN 4X+1...4X+M File headr allocation bitmap where Z is the ; max number of files allowed on the disk ; M=(Z+511)/(512*8) ; Bit set (1) means corresponding file header ; is inuse. ; VBN 4X+M+1...4X+M+9 ; File structure file headers in the following ; order... ; Sequence # Name ; 1 INDEXF.SYS ; 2 BITMAP.SYS ; 3 BADBLK.SYS ; Bad blocks found on disk ; but not in a file ; are placed in this file ; 4 000000.DIR ; Master File directory ; (MFD) ; 5 CORIMG.SYS ; Use is Operating system ; dependent. ; 6 VOLSET.SYS ; Used only by volume sets ; 7 CONTIN.SYS ; Used with loosely bound ; volume sets? ; 8 BACKUP.SYS ; History log of backups? ; 9 BADLOG.SYS ; Bad blocks on disk still ; in use are logged here. ; VBN 4X+M+10... File headers for all other files on disk ; .PAGE .SUBTITLE SCB Data structure ; ; The Storage Control Block (SCB) is the first block (VBN 1) in ; the file BITMAP.SYS. Its structure is defined by the macro ; $SCBDEF. ; ; +--------+--------+--------+--------+ ; | Cluster size |Str. Lvl|Str. Ver! 0 ; +--------+--------+--------+--------+ ; | Volume Size | 4 ; +--------+--------+--------+--------+ ; | Block Size | 8 ; +--------+--------+--------+--------+ ; | Sectors | 12 ; +--------+--------+--------+--------+ ; | Tracks ! 16 ; +--------+--------+--------+--------+ ; | Cylinders | 20 ; +--------+--------+--------+--------+ ; | Status | 24 ; +--------+--------+--------+--------+ ; | Status 2 | 28 ; +--------+--------+--------+--------+ ; | Volume Name | Write Count | 32 ; +--------+--------+--------+--------+ ; | Volume Name | 36 ; +--------+--------+--------+--------+ ; | Volume Name | 40 ; +--------+--------+--------+--------+ ; | Mount Time | Volume Name | 44 ; +--------+--------+--------+--------+ ; | Mount Time | 48 ; +--------+--------+--------+--------+ ; | Back Rev | Mount Time | 52 ; +--------+--------+--------+--------+ ; | Generation Number | 56 ; +--------+--------+--------+--------+ ; | Generation Number | 60 ; +--------+--------+--------+--------+ ; . ; . ; . ; +--------+--------+--------+--------+ ; | Checksum | | 508 ; +--------+--------+--------+--------+ ; ; Status bits-all names preceeded by SCB$M_ ; ; Bit value Status-1 Name Status-2 Name ; ; 1 MAPDIRTY MAPDIRTY2 ; 2 MAPALLOC MAPALLOC2 ; 4 FILALLOC FILALLOC2 ; 8 QUODIRTY QUODIRTY2 ; 16 HDRWRITE HDRWRITE2 ; 32 CORRUPT CORRUPT2 ;V2-018 ; ; The checksum is calculated by summing all the words in the data ; structure from byte 0 up to but not includeing the word containing ; the checksum. ; ; All times are in standard VAX 64 bit binary time format ; .PAGE .SUBTITLE HOME BLOCK DATA STRUCTURES ; ; The home block (defined in the macro $HM2DEF), is the bootstrap ; into the disk file structure. From this block, the system ; finds its way to the other key structures of ODS-2, and such other ; data it needs about the disk structure. ; ; +--------+--------+--------+--------+ ; | Home LBN | 0 Disk LBN of main home ; +--------+--------+--------+--------+ block ; | Alt Home LBN | 4 Disk LBN of next/alt ; +--------+--------+--------+--------+ Home block ; | Alt IDX LBN | 8 Disk LBN of alternate ; +--------+--------+--------+--------+ INDEXF.SYS file header ; | Cluster |Str Lvl |Str Ver | 12 Major/minor ODS-2 ver. ; +--------+--------+--------+--------+ Disk Cluster size ; | Alt Home VBN | Home VBN | 16 Location in INDEXF.SYS ; +--------+--------+--------+--------+ of (ALT)HOME blocks, ; | IBMAP VBN | Alt IDX VBN | 20 File header bitmap, ; +--------+--------+--------+--------+ and alt INDEXF.SYS hdr ; | IB Map LBN | 24 Abs loc on disk of file ; +--------+--------+--------+--------+ header bitmap ; | Max files | 28 Max #files-sets size of ; +--------+--------+--------+--------+ file header bitmap ; | Res files | IB Map Size | 32 Map size in blocks ; +--------+--------+--------+--------+ and reserved files ; | RVN | Dev Type | 36 Device type and Relative ; +--------+--------+--------+--------+ Volume # (Volume sets) ; | Vol. Charac. | Set count | 40 ; +--------+--------+--------+--------+ ; | Volume Owner | 44 ; +--------+--------+--------+--------+ ; | Sec Mask | 48 ; +--------+--------+--------+--------+ ; | File Protection| Protection | 52 ; +--------+--------+--------+--------+ ; | Checksum-1 | Record Protect.| 56 ; +--------+--------+--------+--------+ ; | Creation Date | 60 ; +--------+--------+--------+--------+ ; | Creation Date | 64 ;V2-018 ; +--------+--------+--------+--------+ ; | Extend | LRU Lim| Window | 68 ;V2-018 ; +--------+--------+--------+--------+ ; | Retain Min | 72 ; +--------+--------+--------+--------+ ; | Retain Min | 76 ;V2-018 ; +--------+--------+--------+--------+ ; | Retain max | 80 ; +--------+--------+--------+--------+ ; | Retain max | 84 ;V2-018 ; +--------+--------+--------+--------+ ; | Rev Date | 88 ; +--------+--------+--------+--------+ ; | Rev Date | 92 ;V2-018 ; +--------+--------+--------+--------+ ; | Min Class | 96 ; +--------+--------+--------+--------+ ; | Min Class | 100 ; +--------+--------+--------+--------+ ; | Min Class | 104 ; +--------+--------+--------+--------+ ; | Min Class | 108 ; +--------+--------+--------+--------+ ; | Min Class | 112 ;V2-018 ; +--------+--------+--------+--------+ ; | Max Class | 116 ; +--------+--------+--------+--------+ ; | Max Class | 120 ; +--------+--------+--------+--------+ ; | Max Class | 124 ; +--------+--------+--------+--------+ ; | Max Class | 128 ; +--------+--------+--------+--------+ ; | Max Class | 132 ;V2-018 ; +--------+--------+--------+--------+ ; . ; . ; . ; +--------+--------+--------+--------+ ; | Serial Number | 456 ; +--------+--------+--------+--------+ ; | Structure Name | 460 ; +--------+--------+--------+--------+ ; | Structure Name | 464 ; +--------+--------+--------+--------+ ; | Structure Name | 468 ; +--------+--------+--------+--------+ ; | Volume Name | 472 ; +--------+--------+--------+--------+ ; | Volume Name | 476 ; +--------+--------+--------+--------+ ; | Volume Name | 480 ; +--------+--------+--------+--------+ ; | Owner Name | 484 ; +--------+--------+--------+--------+ ; | Owner Name | 488 ; +--------+--------+--------+--------+ ; | Owner Name | 492 ; +--------+--------+--------+--------+ ; | Format | 496 ; +--------+--------+--------+--------+ ; | Format | 500 ; +--------+--------+--------+--------+ ; | Format | 502 ; +--------+--------+--------+--------+ ; | | 504 ; +--------+--------+--------+--------+ ; | | 508 ; +--------+--------+--------+--------+ ; | Checksum-2 | | 512 ; +--------+--------+--------+--------+ ; ; Volume chracteristics values-all names preceeded by HM2$M_ ; ; Name Value ; READCHECK 1 ; WRITECHECK 2 ; ERASE 4 ; NOHIGHWATER 8 ; CLASS_PROT 16 ; ; The two checksums are calculated by summing all the words in the data ; structure from byte 0 up to but not includeing the word containing ; the checksum. ; .PAGE .SUBTITLE FILE HEADER BLOCK DATA STRUCTURES ; ; A file header block is built in one 512 byte disk block and ; consists of three to five parts, the File Header , which begins at the ; beginning of the disk block, and contains pointers to the starting ; locations of the other four data structures that make up the ; File header block- the File ID block, File Map block, Access Control ; Block and Reserved area Block (the last two data structures are not ; covered here). If you are interested in the Access Control Block, it is ; just a list of ACE's starting at ACOFFSET*2. For information on the ; format of each ACE, look at the macro $ACEDEF and the system service ; $FORMAT_ACL . ; ; The defineing macros for this structure are: $FH2DEF,$FI2DEF,$FATDEF ; $FM2DEF,$ACEDEF .PAGE .SUBTITLE FILE HEADER SECTION ; ; +--------+--------+--------+--------+ Word offsets into header of ; |RSOFFSET|ACOFFSET|MPOFFSET|IDOFFSET| 0 sub-structures. ; +--------+--------+--------+--------+ Seg num=0 for 1'st header ; |Str Lev |Str Ver | Seg Num | 4 incremented with each ; +--------+--------+--------+--------+ extention header ; | FID Seq | FID num | 8 Identifies this header ; +--------+--------+--------+--------+ ; | Ex FID Num |FID Nmx |FID RVN | 12 'Ex identifies next ; +--------+--------+--------+--------+ extention header ; |ExFIDnmx|Ex RVN | Ex FIDSEQ | 16 ; +--------+--------+--------+--------+ ; | RSIZE | RATTRIB| RTYPE | 20 The record attributes ; +--------+--------+--------+--------+ section are all offsets ; | HI BLK | 24 from $FH2$W_RECATTR ; +--------+--------+--------+--------+ useing FAT$x_xxx symbols ; | EF BLK | 28 ; +--------+--------+--------+--------+ ; |VFC SIZE|BKT SIZE| FF BYTE | 32 ; +--------+--------+--------+--------+ ; | DEF EXT | MAX REC | 36 ; +--------+--------+--------+--------+ ; | | GBC | 40 ; +--------+--------+--------+--------+ ; | | 44 ; +--------+--------+--------+--------+ ; | VERSIONS | | 48 ; +--------+--------+--------+--------+ ; | File Char | 52 ; +--------+--------+--------+--------+ ; |Acc Mode|Mapinuse| Record Prot | 56 ;V2-018 ; +--------+--------+--------+--------+ ; | File Owner | 60 ; +--------+--------+--------+--------+ ; | Back Link FID | File Prot | 64 Backlink or Bk is identifier ; +--------+--------+--------+--------+ to preceeding extention header ; |BkFIDNMX| Bk RVN | Back Link SEQ | 68 or directory file containing ; +--------+--------+--------+--------+ this file ; | | RU act |Journal | 72 ; +--------+--------+--------+--------+ ; | High Water | 76 ; +--------+--------+--------+--------+ ; . ; . ; . ; +--------+--------+--------+--------+ ; | Checksum | | 508 ; +--------+--------+--------+--------+ ; ; The FID or File IDentifier is a 24 bit number broken up into 2 parts, ; a low order 16 bits and high order 8 bits. This number identifies ; a given file header by its position in INDEXF.SYS. INDEXF.SYS is the ; first file header in INDEXF.SYS following the file header bit map, ; BITMAP.SYS is the second, etc. The 16 bit sequence number logs the ; current useage of this file header. Each time the file header is ; reused, the value is incremented. This is so that if someone tries ; to open a file by ID that used to be in this file header, it will not ; suceed as the old file no longer exists. The 8 bit RVN is the Relaive ; Volume Number of the file header. ; ; Back link pointers FID (24 bits),Sequence Number(16 bits) RVN (8 bits) ; in the case of an extention header points to the preceeding extention ; header, and in the case of the initial file header, points back to ; the directory file containing this file. For a directory file this ; points back to the directory that contains it. The Master File Directory ; (MFD) is also known as [000000] and it contains itself. ; ; Extention pointers point to the next (if any) extention header ; for this file. The format is the same as outlined above ; ; The offsets to the other data structures are doubled. This results ; in the byte offset to the start of the data structure. ; ; The file size is taken from Hi Block which is the VBN of the last ; block allocated to the file. The EOF is indicated by the entries ; EF Block and FF BYTE. The entry EF Block is the block where the EOF ; occours, FF BYTE (First Free Byte) is the byte offset into the ; EF block of the first free byte available for use. If the ; end of file is the last byte of a block, then the EF BLOCK is ; the next VBN number (even if there is no such VBN allocated to ; that file) and FF BYTE is zero. ; ; File characteristics flags-name preceeded by FH2$M_ ; ; Name Value ; WASCONTIG 1 ;V2-018 ; NOBACKUP 2 ; WRITEBACK 4 ; READCHECK 8 ; WRITECHECK 16 ; CONTIGB 32 ; LOCKED 64 ; CONTIG 128 ; BADACL 2048 ; SPOOL 4096 ; DIRECTORY 8192 ; BADBLOCK 16384 ; MARKDEL 32768 ; NOCHARGE 65536 ; ERASE 131072 ; ; Journal flags ; ; Name Value ; ONLY_RU 1 ; RUJNL 2 ; BIJNL 4 ; AIJNL 8 ; ATJNL 16 ; NEVER_RU 32 ; JOURNAL_FILE 64 ; ; RU active byte-all names preceeded by the string FH2$C_RU_FACILITY_ ; ; Name Value ; RMS 1 ; DBMS 2 ; RDB 3 ; CHKPT 4 ; other undefined x ; ; Record attributes FH2$W_RECATTR+FAT$B_RTYPE ; The low nybble takes on the following values (all symbols ; preceeded by FAT$C_.... ; ; Name Value ; UNDEFINED 0 ; FIXED 1 ; VARIABLE 2 ; VFC 3 ; STREAM 4 ; STREAMLF 5 ; STREAMCR 6 ; ; The high nybble takes on the following values ; ; Name Value ; SEQUENTIAL 0 ; RELATIVE 1 ; INDEXED 2 ; DIRECT 3 ; ; Record attributes FH2$W_RECATTR+FAT$B_RATTRIB ; ; Takes on the following values (all symbols ; preceeded by FAT$M_.... ; ; Name Value ; FORTRANCC 1 ; IMPLIEDCC 2 ; PRINTCC 4 ; NOSPAN 8 ; STATS 16 ;V2-018 ; ; ; The checksum is calculated by summing all the words in the data ; structure from byte 0 up to but not includeing the word containing ; the checksum. ; .PAGE .SUBTITLE File Identification block ; ; A substructure within the file header pointed to by the offset pointer ; IDOFFSET. ; ; +--------+--------+--------+--------+ ; | File Name | 0 ; +--------+--------+--------+--------+ ; | File Name | 4 ; +--------+--------+--------+--------+ ; | File Name | 8 ; +--------+--------+--------+--------+ ; | File Name | 12 ; +--------+--------+--------+--------+ ; | File Name | 16 ; +--------+--------+--------+--------+ ; | Creation Date | Revision | 20 ; +--------+--------+--------+--------+ ; | Creation Date | 24 ; +--------+--------+--------+--------+ ; | Revision Date | Creation Date | 28 ; +--------+--------+--------+--------+ ; | Revision Date | 32 ; +--------+--------+--------+--------+ ; | Expiration Date | Revision Date | 36 ; +--------+--------+--------+--------+ ; | Expiration Date | 40 ; +--------+--------+--------+--------+ ; | Backup Date | Expiration date | 44 ; +--------+--------+--------+--------+ ; | Backup Date | 48 ; +--------+--------+--------+--------+ ; | File Name Ext | Backup Date | 52 ; +--------+--------+--------+--------+ ; | File Name Extention | 56 ; +--------+--------+--------+--------+ ; | File Name Extention | 60 ; +--------+--------+--------+--------+ ; | File Name Extention | 64 ; +--------+--------+--------+--------+ ; | File Name Extention | 68 ; +--------+--------+--------+--------+ ; | File Name Extention | 72 ; +--------+--------+--------+--------+ ; | File Name Extention | 76 ; +--------+--------+--------+--------+ ; | File Name Extention | 80 ; +--------+--------+--------+--------+ ; | File Name Extention | 84 ; +--------+--------+--------+--------+ ; | File Name Extention | 88 ; +--------+--------+--------+--------+ ; | File Name Extention | 92 ; +--------+--------+--------+--------+ ; | File Name Extention | 96 ; +--------+--------+--------+--------+ ; | File Name Extention | 100 ; +--------+--------+--------+--------+ ; | File Name Extention | 104 ; +--------+--------+--------+--------+ ; | File Name Extention | 108 ; +--------+--------+--------+--------+ ; | File Name Extention | 112 ; +--------+--------+--------+--------+ ; | File Name Extention | 116 ; +--------+--------+--------+--------+ ; | User Label | 120 ; +--------+--------+--------+--------+ ; | User Label | 124 ; +--------+--------+--------+--------+ ; | User Label | 128 ; +--------+--------+--------+--------+ ; | User Label | 132 ; +--------+--------+--------+--------+ ; | User Label | 136 ; +--------+--------+--------+--------+ ; | User Label | 140 ; +--------+--------+--------+--------+ ; | User Label | 142 ; +--------+--------+--------+--------+ ; | User Label | 146 ; +--------+--------+--------+--------+ ; | User Label | 148 ; +--------+--------+--------+--------+ ; | User Label | 152 ; +--------+--------+--------+--------+ ; | User Label | 156 ; +--------+--------+--------+--------+ ; | User Label | 160 ; +--------+--------+--------+--------+ ; | User Label | 164 ; +--------+--------+--------+--------+ ; | User Label | 168 ; +--------+--------+--------+--------+ ; | User Label | 172 ; +--------+--------+--------+--------+ ; | User Label | 174 ; +--------+--------+--------+--------+ ; | User Label | 178 ; +--------+--------+--------+--------+ ; | User Label | 182 ; +--------+--------+--------+--------+ ; | User Label | 186 ; +--------+--------+--------+--------+ ; | User Label | 192 ; +--------+--------+--------+--------+ ; | User Label | 196 ; +--------+--------+--------+--------+ ; ; All dates use the standard VAX 64 bit binary time format. ; ; The user label does not appear to be used at this time ; .PAGE .SUBTITLE FILE MAP BLOCK ; ; The file map area is not a static data structure as outlined above. ; The area starts at the location pointed at by the File Header area ; offset pointer FH2$B_MPOFFSET and extends to the location pointed to by ; FH2$B_MAP_INUSE. ; The map is a sequence of retrieval pointers/placement control ; structures added as needed. There are four(4) possable structures ; that can be found in this list. ; The type code is 2 bits long. ; ; The count has to be incremented by 1 to get the number of ; blocks pointed to by this pointer ; ; The LBN is the first LBN of the contiguous segment of ; COUNT+1 disk blocks pointed to by this retrival pointer. ; ; Placement Control (type code 0) ; ; +--------+--------+ ; | 0| Flags | ; +--------+--------+ ; ; Placement control flags-preceeded by FM2$M_ ; ; Name Value ; EXACT 1 ; ONCYL 2 ; LBN 4096 ; RVN 8192 ; ; Retrival Pointer format 1 (type code 1) ; ; +--------+--------+--------+--------+ ; | Low Lbn | 1|HiLBN| Count | ; +--------+--------+--------+--------+ ; ; Retrieval Pointer format 2 (type code 2) ; ; +--------+--------+--------+--------+--------+--------+ ; | LBN | 2| Count | ; +--------+--------+--------+--------+--------+--------+ ; ; Retreival Pointer format 3 (type code 3) ; ; +--------+--------+--------+--------+--------+--------+--------+--------+ ; | LBN | Low Count | 3| High Count | ; +--------+--------+--------+--------+--------+--------+--------+--------+ .PAGE .SUBTITLE DIRECTORY FILES ; ; Directory files are contiguous, not contiguous best try (so far). ; the internal structure is a series of entries in the following ; format(see also $DIRDEF) ; ; For each file entered in a directory includeing all versions ; one entry of the following format is found ; ; +--------+--------+--------+--------+ ; | Version Limit | Size | 0 ; +--------+--------+--------+--------+ ; | Name | Count | Flags | 4 ; +--------+--------+--------+--------+ ; . ; . ; . ; +--------+--------+--------+--------+ ; | Name | x ; +--------+--------+--------+--------+ ; ; The entire entry is Size+2 bytes long. ; The name is the full file name and extention in ; ASCII(this may not match the name found in the file header in the ; case of alias files-SET FILE/ENTER) and its length ; is in "Count". If the last character in the string ; falls on an odd byte boundry, a null character is added on to ; the end of the string (but not the count) to end this part of ; the file entry on a word boundry. ; ; Note that if the size field is FFFF%X then this is not a file entry, ; it is a flag indicateing that no more entries are to be found in ; this block of the directory file, but more entries may be found ; in following block(s) (if any) of the directory file. ; A block in a directory file does not have to be filled up ; in order to use any subsequent blocks in a directory file. ; this unused space allows a directory update to occour in a multi block ; directory file without haveing to update more than one or two ; blocks. I cannot be sure but it may be that directory entries ; cannot cross block boundries. All entries are stored in alphabetical ; order. A large (multi block) directory file that then has all the files ; in it deleted, will cause the EOF location to be reset so that only ; one block with no entries is in use, the rest are allocated but beyond ; the EOF location. ; ; Following the file name string, one for each version of ; the file to be found in the directory the following ; structure is appended: ; ; +--------+--------+--------+--------+ ; | FID | Version Number | 0 Version number in binary ; +--------+--------+--------+--------+ ; |FID Ext | RVN | Sequence Number | 4 ; +--------+--------+--------+--------+ ; ; The format of the File ID is the same as outlined in the discussion ; of the File Header area. ; ; FLAGS byte ;V2-018 ; ;V2-018 ; Bits 0-2 Type Unknown meaning ;V2-018 ; Bit 6 Next Record File name continued to next rec.;V2-018 ; Bit 7 Prev Record File name cont. from prev. rec ;V2-018 .PAGE .SUBTITLE VOLSET.SYS ; ; The file VOLSET.SYS is only used in the first volume (RVN=0) of a ; volume set. It consists of a series of names. The repeated data ; structure (see $VSLDEF) is as follows ; ; +--------+--------+--------+--------+ ; | Name | 0 ; +--------+--------+--------+--------+ ; | Name | 4 ; +--------+--------+--------+--------+ ; | Name | 8 ; +--------+--------+--------+--------+ ; | Unused | 12 ; +--------+--------+--------+--------+ ; . ; . ; . ; +--------+--------+--------+--------+ ; | Unused | 60 ; +--------+--------+--------+--------+ ; ; The name is blank padded ; ; The first use if the structure is at the beginning of the ; file VOLSET.SYS and defines the name of the volume set. ; The structure is then repeated for each volume in the volume ; in order 0..n giveing the label of each disk of the set. ; .PAGE .SUBTITLE GLOBAL DATA .PSECT GLOBAL_DATA,RD,WRT,NOEXE,PAGE,NOSHR DEVICE_NAME: .ASCID / / CLUSTER_SIZE: .LONG 0 DISK_SIZE: .LONG 0 FREE_BLOCKS: .LONG 0 FILE_BITMAP_VBN:.LONG 0 FILE_HEADER_VBN:.LONG 0 INDEXF_IFI: .LONG 0,0 LARGEST_FREE_FRAGMENT: .LONG 0 CENTER: .LONG 0 PASS_COUNTER: .LONG 0 ;V02-003 FRAGMENT_COUNT: .LONG 0 ;V02-004 FILE_COUNT: .LONG 0 ;V02-004 POINTER_COUNT: .LONG 0 ;V02-004 ; ; The following variable is an indicator for the exit handler to tell ; it where in the program JUICER_2 was at the time the exit was forced. ; MODE: .LONG 0 ; ; The possable bit mask flags are as follows ; ; Name Value Explanation ; ; MODE_SAFE =0 ;Input and output files not open MODE_M_INPUT_OPEN =1 ;Input file is or was about to be opened MODE_M_OUTPUT_OPEN =2 ;Output file is or is about to be opened MODE_M_INPUT_CLOSE =4 ;Input file is going to be or is closed MODE_M_INPUT_DELETE =8 ;Input file is going to be or is deleted MODE_M_OUTPUT_CLOSE =16 ;Output file is going to be or is closed MODE_M_OUTPUT_DELETE =32 ;Output file is going to be or is deleted MODE_M_RENAME =64 ;Output file is going to be or is renamed .PAGE .SUBTITLE Main line code ; ; Main line proeedure ; this program will never exit normally. ; the only exits are error exits. ; ; Programming note: All procedures and functions in JUICER_2 ; return some value in R0 wheather or not explicidly stated ; in the procedure header. Unless otherwise stated, the value is ; a status value that corresponds to the VAX/VMS SS$_xxx codes ; if the LSB is set no-error, other wise error. ; In most cases the value returned is SS$_NORMAL ; .PSECT MAIN_CODE,RD,NOWRT,EXE,SHR .ENTRY JUICER,0 CALLS #0,PROGRAM_INIT ;DO PROGRAM INIT'S CALLS #0,GET_DISK_INFO ;GET DISK PARAMETERS CALLS #0,INITIAL_SCAN_FILES_OPEN ;OPEN BITMAP/INDEXF AND GET ;FILE STRUCTURE PARAMETERS MAIN_LOOP: CALLS #0,LOOP_INIT ;Do any loop inits ;V02-003 CALLS #0,CHECK_FILE_DUMP_REJECTED ;V02-010 CALLS #0,SCAN_BITMAP ;FIND CURRENT LARGEST FRAGMENT CALLS #0,SCAN_FILE_HEADERS ;SCAN ALL FILE HEADERS AND SORT CALLS #0,CHECK_FILE_DUMP_CONTIG ;V02-010 CALLS #0,CHECK_FILE_DUMP_LARGE_CONTIG ;V02-010 CALLS #0,CHECK_FILE_DUMP_FRAG ;V02-010 CALLS #0,CHECK_FILE_DUMP_LARGE_FRAG ;V02-010 CALLS #0,CHECK_FILE_DUMP_TOO_LARGE ;V02-010 CALLS #0,CHECK_FILE_DUMP_DIRECTORY ;V02-012 CALLS #0,SCAN_BITMAP ;NEW LIST OF FRAGMENTS CALLS #0,ATTEMPT_DISK_DEFRAGMENT CALLS #0,SCAN_BITMAP ;GET LIST OF FRAGMENTS ;V02-009 CALLS #0,ATTEMPT_FILE_DEFRAGMENT ;V02-009 TSTL PASS_COUNTER ;V02-016 BEQL MAIN_LOOP ;V02-016 BITL #7,PASS_COUNTER ;V02-018 BNEQ MAIN_LOOP ;V02-016 CALLS #0,FORCE_FILE_MOVE ;V02-016 BRB MAIN_LOOP ;REPEAT FOREVER .PAGE .SUBTITLE JUICER_2 INTERNAL INITS .PSECT INIT_CODE,RD,NOWRT,EXE,SHR .ENTRY PROGRAM_INIT,^M ; ; Init any dynamic items that cant be done at assembly time. ; ; Inputs: None ; ; Outputs: ; Clear global variables MODE and PASS_COUNTER ;V02-003 ; Declare exit handler ; ; 1-set mode initial condition ; 2-declare exit handler ; CLRL MODE MOVL #-1,PASS_COUNTER ;V02-003 $DCLEXH_S EXIT_BLOCK BLBS R0,1$ $EXIT_S R0 1$: RET .PAGE .SUBTITLE PROGRAM INIT DATA AREA .PSECT INIT_DATA,RD,WRT,NOEXE,NOSHR,LONG EXIT_BLOCK: .LONG 0 ;FORWARD LINK .ADDRESS EXIT_HANDLER .LONG 1 ;ARGUMENT COUNT .LONG EXIT_VALUE ;REASON FOR EXIT GOES HERE ;V02-002 EXIT_VALUE: .LONG 0 ;V02-002 .PAGE ;V02-003 .SUBTITLE JUICER_2 PER LOOP INTERNAL INITS ;V02-003 .PSECT INIT_CODE,RD,NOWRT,EXE,SHR ;V02-003 .ENTRY LOOP_INIT,^M ;V02-003 ; ;V02-003 ; Do any inits requires on a per loop basis ;V02-003 ; ;V02-003 ; INPUTS: ;V02-012 ; Check SYSTEM logcial table for symbol JUICER_2_dev_STOP ;V02-012 ; ;V02-003 ; Outputs: ;V02-003 ; PASS_COUNTER Incremented ;V02-003 ; System Logical table entry JUICER_2_disk_PASS_COUNT ;V02-003 ; reset ;V02-003 ; ;V02-003 ; Other Juicer routines called ;V02-003 ; UPDATE_LOGICAL_NAME ;V02-003 ; GET_LOGICAL_NAME ;V02-012 ; DELETE_LOGICAL_NAME ;V02-012 ; ;V02-003 INCL PASS_COUNTER ;V02-003 PUSHL #4 ;V02-003 PUSHL #8 ;V02-003 PUSHAL PASS_COUNT ;V02-003 PUSHAL PASS_COUNTER ;V02-003 CALLS #4,G^OTS$CVT_L_TZ ;V02-003 PUSHAL PASS_COUNT ;V02-003 PUSHAL PASS_NAME ;V02-003 CALLS #2,UPDATE_LOGICAL_NAME ;V02-003 PUSHAL INIT_STOP_VALUE ;V02-012 PUSHAL INIT_STOP ;V02-012 CALLS #2,GET_LOGICAL_NAME ;V02-012 BLBS R0,1$ ;V02-013 MOVL #1,R0 ;V02-013 RET ;V02-003 ; Stop has been flagged-delete logical name and stop juicer_2 ;V02-012 1$: PUSHAL INIT_STOP ;V02-012 CALLS #1,DELETE_LOGICAL_NAME ;V02-012 $EXIT_S R0 ;V02-012 .PAGE ;V02-003 .SUBTITLE PROGRAM INIT DATA AREA ;V02-003 .PSECT INIT_DATA,RD,WRT,NOEXE,NOSHR,LONG ;V02-003 PASS_COUNT: .ASCID / / ;V02-003 PASS_NAME: .ASCID /PASSES_COMPLETED/ ;V02-003 INIT_STOP: .ASCID /STOP/ ;V02-012 INIT_STOP_VALUE:.LONG 256 ;V02-012 .ADDRESS 1$ ;V02-012 1$: .BLKB 256 ;V02-012 .PAGE .SUBTITLE GET DISK INFORMATION .PSECT DISK_INFO_CODE,RD,NOWRT,EXE,SHR .ENTRY GET_DISK_INFO,^M ; ; First initialization routine, gets the name of the disk to squeese ; from the process name, checks out the disk to see if is O.K. and ; returns selected information. ; ; Inputs: None ; ; Outputs: To Global data area ; ; DEVICE_NAME .ASCID max 15 chars includeing length ; CLUSTER_SIZE .LONG # disk blocks per cluster ; DISK_SIZE .LONG # blocks on disk ; FREE_SPACE .LONG # blocks unused ; ; Error exits: This subroutine with cause the process to exit ; if any of the following errors occour: ; ; Any system service error ; Any I/O service error ; Device not a Disk ; Disk not mounted ; Disk not ODS-2 ; Disk is part of a Volumn Set ; ; ; Other Juicer routines called: None ; ; First step is to get the process name which should be the ; name of the disk to be squeezed sans ":". ; $GETJPI_S ITMLST=JPI_ARG_LIST,IOSB=PROCESS_IOSB BLBC R0,11$ MOVZWL PROCESS_IOSB,R0 BLBS R0,12$ 11$: BRW 1$ 12$: MOVL DEVICE_NAME+4,R11 ;Get address of string to load name MOVB PROCESS_NAME_LENGTH,DEVICE_NAME ;Load length of device name MOVC3 PROCESS_NAME_LENGTH,PROCESS_NAME,(R11) LOCC #^A/:/,PROCESS_NAME_LENGTH,PROCESS_NAME ;See if one there anyway TSTL R0 BNEQ 2$ MOVL PROCESS_NAME_LENGTH,R0 ;Set up to load ":" ADDL2 ,R0 ;Calc addr to load MOVB #^A/:/,(R0) INCB DEVICE_NAME 2$: ; ; Get device data to see if it is what we can handle ; $GETDVIW_S EFN=#0,- ;V02-016 DEVNAM=DEVICE_NAME,- ITMLST=DEV_ARG_LIST,- IOSB=PROCESS_IOSB BLBC R0,1$ $WAITFR_S EFN=#0 BLBC R0,1$ MOVZWL PROCESS_IOSB,R0 BLBC R0,1$ MOVL #SS$_NOTFILEDEV,R0 CMPL #DC$_DISK,DEV_CLASS BNEQ 1$ MOVL #SS$_DEVNOTMOUNT,R0 CMPL #1,DEV_MOUNT_COUNT BGTR 1$ MOVL #SS$_DEVFOREIGN,R0 CMPL #DVI$C_ACP_F11V2,DEV_ACP BNEQ 1$ MOVL #SS$_NOTVOLSET,R0 CMPL #1,DEV_VOLUMN_COUNT BLSS 1$ MOVL #SS$_IVCHAR,R0 CMPL #1,CLUSTER_SIZE BGTR 1$ DIVL3 #2,DISK_SIZE,CENTER MOVL #SS$_NORMAL,R0 RET 1$: $EXIT_S R0 .PAGE .SUBTITLE GET DISK INFO DATA AREA .PSECT DISK_INFO_DATA,RD,WRT,NOEXE,PAGE,NOSHR DEV_ARG_LIST: .WORD 4,DVI$_DEVCLASS .ADDRESS DEV_CLASS .LONG 0 .WORD 4,DVI$_ACPTYPE .ADDRESS DEV_ACP .LONG 0 .WORD 4,DVI$_CLUSTER .ADDRESS CLUSTER_SIZE .LONG 0 .WORD 4,DVI$_MAXBLOCK .ADDRESS DISK_SIZE .LONG 0 .WORD 4,DVI$_FREEBLOCKS .ADDRESS FREE_BLOCKS .LONG 0 .WORD 4,DVI$_MOUNTCNT .ADDRESS DEV_MOUNT_COUNT .LONG 0 .WORD 4,DVI$_VOLCOUNT .ADDRESS DEV_VOLUMN_COUNT .LONG 0 .LONG 0 DEV_CLASS: .LONG 0 DEV_ACP: .LONG 0 DEV_MOUNT_COUNT: .LONG 0 DEV_VOLUMN_COUNT: .LONG 0 JPI_ARG_LIST: .WORD 15,JPI$_PRCNAM .ADDRESS PROCESS_NAME,PROCESS_NAME_LENGTH .LONG 0 PROCESS_NAME: .BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 PROCESS_NAME_LENGTH: .LONG 0 PROCESS_IOSB: .LONG 0,0 .PAGE .SUBTITLE INITIAL OPEN OF BITMAP AND INDEXF .PSECT IO_CODE,RD,NOWRT,EXE,PAGE,SHR .ENTRY INITIAL_SCAN_FILES_OPEN,^M ; ; Do an initial open of the bitmap and indexf files. ; get key information for offset into the indexf file ; ; Inputs: Name of device DEVICE_NAME ; Cluster size CLUSTER_SIZE ; ; Outputs: To global data area ; ; FILE_BITMAP_VBN LBN of first block of ; file header bitmap ; FILE_HEADER_VBN LBN of first file header ; ; INDEXF_IFI ID# for INDEXF.SYS ; ; leave open the files BITMAP.SYS,INDEXF.SYS ; ; Any directive error causes the process to exit ; No valid home block found causes the process to exit ; ; ; Other Juicer routines called: ; INDEXF_READ ; ; Load the file name length with the length of the device name ; MOVB DEVICE_NAME,NO_SHARE_BITMAP_FAB+FAB$B_FNS MOVB DEVICE_NAME,SHARE_BITMAP_FAB+FAB$B_FNS MOVB DEVICE_NAME,INDEX_FAB+FAB$B_FNS ; ; Open bitmap and indexf files ; $OPEN FAB=SHARE_BITMAP_FAB BLBC R0,1$ $CONNECT RAB=SHARE_BITMAP_RAB BLBC R0,1$ $OPEN FAB=INDEX_FAB BLBC R0,1$ MOVQ INDEX_NAM+NAM$W_FID,INDEXF_IFI $CONNECT RAB=INDEX_RAB BLBS R0,HOME_BLOCK_LOOP 1$: $EXIT_S R0 ; ; Read home block ; HOME_BLOCK_LOOP: CALLG READ_HOME_BLOCK_ARG,INDEXF_READ ; ; See if home block is valid ; CLRL R0 MOVL #,R1 MOVAL HOME_BLOCK,R2 15$: ADDW2 (R2)+,R0 SOBGTR R1,15$ CMPW R0,(R2) BNEQ 16$ ;BRANCH IF CHECKSUM1 DOES NOT MATCH CLRL R0 MOVL #,R1 MOVAL HOME_BLOCK,R2 17$: ADDW2 (R2)+,R0 SOBGTR R1,17$ CMPW R0,(R2) BEQL 18$ ;BRANCH IF CHECKSUM2 OK 16$: INCL HOME_BLOCK_VBN ;SKIP TO NEXT COPY OF HOME BLOCK MULL3 #3,CLUSTER_SIZE,R0 ;SEE IF ALL HOME BLOCKS CHECKED CMPL R0,HOME_BLOCK_VBN BGEQ HOME_BLOCK_LOOP MOVL #SS$_NOHOMEBLK,R0 ;NO VALID HOME BLOCK-EXIT $EXIT_S R0 18$: MOVZWL HOME_BLOCK+HM2$W_IBMAPVBN,R0 ;VBN OF BITMAP MOVL R0,FILE_BITMAP_VBN ;STORE MOVZWL HOME_BLOCK+HM2$W_IBMAPSIZE,R1 ;GET SIZE OF BITMAP ADDL3 R0,R1,FILE_HEADER_VBN ;STORE VBN OF FIRST FILE HEADER MOVL #SS$_NORMAL,R0 RET .PAGE .SUBTITLE INITIAL OPEN SCRATCH AREA .PSECT IO_SCRATCH,RD,WRT,NOEXE,PAGE,NOSHR .ALIGN LONG HOME_BLOCK: .BLKB 512 ;Home block read into here READ_HOME_BLOCK_ARG: .LONG 3 ;Argument list to INDEXF_READ HOME_BLOCK_VBN: .LONG 2 ;First home block is VBN 2 .ADDRESS HOME_BLOCK .LONG 1 .PAGE .SUBTITLE ALL I/O DATA STRUCTURES (FAB'S & RAB'S) .PSECT IO_DATA_STRUCTURES,RD,WRT,NOEXE,PAGE,NOSHR .ALIGN LONG NO_SHARE_BITMAP_FAB: $FAB ALQ=0,- DEQ=0,- DNM=,- FAC=,- FNA=,FNS=0,- SHR= .ALIGN LONG NO_SHARE_BITMAP_RAB: $RAB BKT=1,- FAB=NO_SHARE_BITMAP_FAB,- ROP= .ALIGN LONG SHARE_BITMAP_FAB: $FAB ALQ=0,- DEQ=0,- DNM=,- FAC=,- FNA=,FNS=0,- FOP=,SHR= .ALIGN LONG SHARE_BITMAP_RAB: $RAB BKT=1,- FAB=SHARE_BITMAP_FAB,- ROP= .ALIGN LONG INDEX_FAB: $FAB ALQ=0,- DEQ=0,- DNM=,- FAC=,- FNA=,FNS=0,- NAM=INDEX_NAM,- SHR= .ALIGN LONG INDEX_RAB: $RAB BKT=1,- FAB=INDEX_FAB,- ROP= .ALIGN LONG INDEX_NAM: $NAM .ALIGN LONG CHECK_ACCESS_FAB: $FAB ALQ=0,- DEQ=0,- FAC=,- SHR= .ALIGN LONG CHECK_ACCESS_RAB: $RAB BKT=1,- FAB=CHECK_ACCESS_FAB,- ROP= .PAGE .SUBTITLE PRIMITIVE FILE INPUT ROUTINES INDEXF_READ,BITMAP_READ .PSECT IO_CODE,RD,NOWRT,EXE,PAGE,SHR ; ; The two subroutines INDEXF_READ and BITMAP_READ are the lowest level ; input routines to get data from their respective files. ; ; Inputs are via argument list: ; 0(AP) 3 Argument count-must be 3-not checked ; 4(AP) VBN Starting VBN block of read-pass by value ; 8(AP) Buffer Starting address of buffer to store data ; 12(AP) Blocks Number of disk blocks to be read-pass by value ; ; Output: Data buffer ; R0= SS$_NORMAL or RMS$_EOF ; ; Exits: on any system service or I/O or RMS processing error ; .ENTRY INDEXF_READ,0 MOVL 4(AP),INDEX_RAB+RAB$L_BKT ; Load starting VBN MOVL 8(AP),INDEX_RAB+RAB$L_UBF ; Buffer address ASHL #9,12(AP),R0 ; Mul block count by 512 MOVW R0,INDEX_RAB+RAB$W_USZ ; And load $READ RAB=INDEX_RAB ; Read Block(s) BLBC R0,1$ ; Check for errors RET ; OK exit 1$: CMPL #RMS$_EOF,R0 ; See if EOF found BNEQ 2$ ; If not branch RET ; Return EOF error message 2$: $EXIT_S R0 ; Error exit .ENTRY BITMAP_READ,0 MOVL 4(AP),SHARE_BITMAP_RAB+RAB$L_BKT ; Load starting VBN MOVL 8(AP),SHARE_BITMAP_RAB+RAB$L_UBF ; Buffer address ASHL #9,12(AP),R0 ; Mul block count by 512 MOVW R0,SHARE_BITMAP_RAB+RAB$W_USZ ; And load $READ RAB=SHARE_BITMAP_RAB ; Read Block(s) BLBC R0,1$ ; Check for errors RET ; OK exit 1$: CMPL #RMS$_EOF,R0 ; See if EOF found BNEQ 2$ ; If not branch RET ; Return EOF error message 2$: $EXIT_S R0 ; Error exit .PAGE .SUBTITLE FLUSH THE BITMAP .PSECT IO_CODE,RD,NOWRT,EXE,SHR ; ; This procedure causes the cached bit map to be flushed back to ; the disk. ; ; Inputs: DEVICE_NAME ; ; Outputs: Flushed Bitmap to disk ; updates FREE_BLOCKS ; ; Exits: Any system service, I/O or RMS error. ; .ENTRY FLUSH_BITMAP,0 ; ; This routine flushes the bitmap by the folowing process ; ; 1 close shared access to bitmap file ; 2 open bitmap file in non-shared mode ; 3 close non-shared mode access to file ; 4 open bitmap file in shared mode ; ; all operations are done at elevated priority to ensure that minimun ; time is taken to do the task and no other processes are blocked. ; ; If someone else has the bitmap inuse so that it cannot be flushed ; but still is available an a shareable file-continue without ; the flush. ; $SETPRI_S PRI=#16,PRVPRI=OLD_PRIORITY BLBC R0,4$ $CLOSE FAB=SHARE_BITMAP_FAB BLBC R0,4$ $OPEN FAB=NO_SHARE_BITMAP_FAB BLBC R0,2$ $CLOSE FAB=NO_SHARE_BITMAP_FAB BLBS R0,3$ 2$: CMPL #RMS$_FLK,R0 ;SEE IF LOCKED OR NOT AVAILABLE EXCLUSEIVELY BEQL 3$ 4$: BRW 1$ 3$: $OPEN FAB=SHARE_BITMAP_FAB BLBC R0,1$ $CONNECT RAB=SHARE_BITMAP_RAB BLBC R0,1$ $SETPRI_S PRI=OLD_PRIORITY BLBC R0,1$ $GETDVI_S EFN=#0,- DEVNAM=DEVICE_NAME,- ITMLST=FLUSH_ARG_LIST,- IOSB=FLUSH_IOSB BLBC R0,1$ $WAITFR_S EFN=#0 BLBC R0,1$ BLBC FLUSH_IOSB,1$ RET 1$: $EXIT_S R0 .PAGE .SUBTITLE FLUSH BITMAP SCRATCH AREA .PSECT IO_SCRATCH,RD,WRT,NOEXE,PAGE,NOSHR OLD_PRIORITY: .LONG 0 FLUSH_IOSB: .LONG 0,0 FLUSH_ARG_LIST: .WORD 4,DVI$_FREEBLOCKS .ADDRESS FREE_BLOCKS .LONG 0,0 .PAGE .SUBTITLE CHECK FILE FOR EXCLUSIVE ACCESS .PSECT IO_CODE,RD,NOWRT,EXE,SHR .ENTRY CHECK_ACCESS,^M ; ; Checks the specified file to see if it can be opened by this ; program for exclusive access. This shows up files open for ; use by the system, INSTALL'ed, or open by other processes. ; ; Input: (AP)2/3 ; 4(AP) FID of file to be checked-pass by value ; 8(AP) Sequence number of file header-pass by value ; 16(AP) Pointer to memory starting loc of file header in memory ; if present ; ; Output: R0 LSB =1 file meets criterion ; LSB =0 file not eligable ; ; Other JUICER routines called: BUILD_FILE_NAME ; MOVL #4,CHECK_BUILD_ARG MOVL 4(AP),CHECK_BUILD_FID MOVL 8(AP),CHECK_BUILD_SEQ CMPW #3,(AP) BNEQ 6$ MOVL #5,CHECK_BUILD_ARG MOVL 12(AP),CHECK_BUILD_POINTER 6$: CALLG CHECK_BUILD_ARG,BUILD_FILE_NAME BLBC R0,4$ MOVAL CHECK_TEXT,CHECK_ACCESS_FAB+FAB$L_FNA MOVB CHECK_STRING_LENGTH,CHECK_ACCESS_FAB+FAB$B_FNS $OPEN FAB=CHECK_ACCESS_FAB BLBC R0,1$ $CLOSE FAB=CHECK_ACCESS_FAB 1$: RET 4$: CLRL R0 RET .PAGE .SUBTITLE CHECK FILE AGINST LIST OF VERBOTEN FILES ;V02-009 .PSECT IO_CODE,RD,NOWRT,EXE,SHR ;V02-009 .ENTRY CHECK_LIST,^M ;V02-009 ; ;V02-009 ; Check aginst list of files that do not show up as being ;V02-009 ; inuse but are...PAGEFILE.SYS and SWAPFILE.SYS... and directories;V02-009 ; known to be in more than one place at a time... SYSCOMMON.DIR ;V02-009 ; aka VMS$COMMON.DIR and SYSMAINT.DIR. ;V02-018 ; ;V02-009 ; Input: (AP)2/3 ;V02-009 ; 4(AP) FID of file to be checked-pass by value ;V02-009 ; 8(AP) Sequence number of file header-pass by value ;V02-009 ; 16(AP) Ptr to mem starting loc of file header in mem ;V02-009 ; if present ;V02-009 ; ;V02-009 ; Output: R0 LSB =1 file meets criterion ;V02-009 ; LSB =0 file not eligable ;V02-009 ; ;V02-009 ; Other JUICER routines called: BUILD_FILE_NAME ;V02-009 ; ;V02-009 MOVL #4,CHECK_BUILD_ARG ;V02-009 MOVL 4(AP),CHECK_BUILD_FID ;V02-009 MOVL 8(AP),CHECK_BUILD_SEQ ;V02-009 CMPW #3,(AP) ;V02-009 BNEQ 6$ ;V02-009 MOVL #5,CHECK_BUILD_ARG ;V02-009 MOVL 12(AP),CHECK_BUILD_POINTER ;V02-009 6$: CALLG CHECK_BUILD_ARG,BUILD_FILE_NAME ;V02-009 BLBC R0,4$ ;V02-009 ; ;V02-009 ; Scan the list of verboten files not to be copied ;V02-009 ; ;V02-009 MOVAL NO_COPY_FILE_LIST,R11 ;V02-009 LOCC #^A/[/,CHECK_STRING_LENGTH,CHECK_TEXT ;SKIP DEV TO '[';V02-009 MOVL R1,R9 ;SAVE COPY OF LOC OF '[' ;V02-009 MOVL R0,R8 ;SAVE COPY OF REMAINING CHRS ;V02-009 MOVL #NO_COPY_COUNT,R10 ;V02-009 2$: CMPB R8,(R11);CHECK TO SEE IF STRING IS LONG ENOUGH ;V02-009 BLSSU 3$ ;STRING TO SHORT ;V02-009 CMPC3 (R11),@4(R11),(R9) ;SEE IF STRING MATCHES ;V02-009 BEQL 4$ ;FORGET THIS ONE ;V02-009 3$: ADDL2 #8,R11 ;SKIP TO NEXT STRING ;V02-009 DECL R10 ;DEC STRING COUNTER ;V02-009 BGTR 2$ ;IF MORE TO CHECK-LOOP BACK ;V02-009 MOVL #SS$_NORMAL,R0 ;V02-009 1$: RET ;V02-009 4$: CLRL R0 ;V02-009 RET ;V02-009 .PAGE .SUBTITLE CHECK FILE SCRATCH AREA .PSECT IO_SCRATCH,RD,WRT,NOEXE,PAGE,NOSHR CHECK_BUILD_ARG: .LONG 4 CHECK_BUILD_FID: .LONG 0 .ADDRESS CHECK_STRING .ADDRESS CHECK_STRING_LENGTH CHECK_BUILD_SEQ: .LONG 0 CHECK_BUILD_POINTER: .LONG 0 CHECK_STRING: .LONG 4096 .ADDRESS CHECK_TEXT CHECK_STRING_LENGTH: .LONG 0 CHECK_TEXT: .BLKB 4096 .PAGE .SUBTITLE LIST OF VERBOTEN FILES-NOT TO BE MOVED ; ; The following is a list of files that due to one of the ; following reasons-are not to be moved.Note to anyone adding ; names to the list. The second argument to the macro is manditory. ; Files are included on this list for the following reasons... ; ; 1) Directory files that can themselves be reached by more than one ; path such as the case of a cluster common system disk where the ; common directory structure SYSCOMMON.DIR can be reached by either ; [SYSx.SYSCOMMON] or [000000.VMS$COMMON], or SYSMAINT, etc and due to the ; use of ANAL/DISK/REPAIR the back link pointers could back point ; to any route back up to [000000]. Also the directory ; [000000]VMS$COMMON.DIR;1 is named in the file header SYSCOMMON.DIR;1 ; Another case is a disk with stand alone backup set up on it in root ; SYSE, it contains a subdirectory SYSCOMMON, depending on the disk, ; this can be an alias for VMS$COMMON or SYS0. ; ; 2) Files that have been entered under an alias ($SET FILE/ENTER) ; and appear in more than one directory entry. ; ; 3)Files the running VMS uses but does not have open in the normal ; ODS-2 sense-i.e. PAGEFILE.SYS and SWAPFILE.SYS or INSTALLed but not ; opened. ; ; ; In the list below, I have attempted to list all possable combinations ; and permuations of file names that might be found that should not be ; moved. Unfortunately I could not know where or by what name ; secondary page/swap files could be designated, so that has to be ; added by the indivdual user. ; Also needed to be added by the user is the name of any file that ; is entered in more than one directory. The pointer in any directory ; files not pointed back to by the file header back pointer will ; end up pointing to a non existent file or files that have been installed ; but not with /OPEN. To check what files these are-run install and list ; all files installed and see which ones do not have /OPEN listed next ; to them. ; ; ; Define the two PSECTS to contain the list of verboten files .PSECT VERBOTEN_DATA1,RD,NOWRT,NOEXE,LONG,SHR NO_COPY_FILE_LIST: .PSECT VERBOTEN_DATA2,RD,NOWRT,NOEXE,LONG,SHR ; ; Define macros to genrate the list ; ; macro to build one entry in table ; .MACRO GEN_NO_COPY FILE_NAME,CTR ; ; FILE_NAME FILE NAME WITH FULL DIRECTORY LIST OF FILE TO AVOID ; CTR MUST BE \NO_COPY_COUNT ; .PSECT VERBOTEN_DATA2 VERBOTEN_A_'CTR': .ASCII /'FILE_NAME'/ VERBOTEN_B_'CTR=.-VERBOTEN_A_'CTR' .PSECT VERBOTEN_DATA1 .LONG VERBOTEN_B_'CTR' .ADDRESS VERBOTEN_A_'CTR' NO_COPY_COUNT=NO_COPY_COUNT+1 .ENDM ; ; Macro to build entries in all possable roots of a cluster common disk ; .MACRO MULTI_NO_COPY BASIC_NAME,FLAG ; ; FOR FILES RESIDEING ONLY IN THE ROOT DIR (SYSx) THE FLAG IS NOT USED ; AND THE ARGUMENT BASIC_NAME IS THE DIRECTORY/FILENAME STRING STARTING ; AT THE LOCATION JUST AFTER "[SYSx". ; ; FOR FILES THAT CAN BE RESIDEING IN SYSCOMMON, "FLAG" IS LOADED AND THE ; BASIC_NAME IS SET TO THE DIRECTORY NAME/STRING THAT FOLLOWS ; [SYSx.SYSCOMMON or [VMS$COMMON . ; .IRPC ROOT,<0123456789ABCDEF> GEN_NO_COPY [SYS'ROOT''BASIC_NAME,\NO_COPY_COUNT .ENDR .IF NB,FLAG .IRPC ROOT,<0123456789ABCDEF> GEN_NO_COPY [SYS'ROOT'.SYSCOMMON'BASIC_NAME,\NO_COPY_COUNT .ENDR GEN_NO_COPY [VMS$COMMON'BASIC_NAME',\NO_COPY_COUNT ;V2-018 GEN_NO_COPY [SYSCOMMON'BASIC_NAME',\NO_COPY_COUNT .ENDC .ENDM ; ; VERBOTEN_LIST ; NO_COPY_COUNT=0 ; Root specific items that VMS uses but are not open MULTI_NO_COPY .SYSEXE]PAGEFILE.SYS MULTI_NO_COPY .SYSEXE]SWAPFILE.SYS MULTI_NO_COPY .SYSEXE]SYSDUMP.DMP ; Cluster common disk,stand alone backup, etc multi entry problems MULTI_NO_COPY ]SYSCOMMON.DIR MULTI_NO_COPY ]SYSMAINT.DIR,1 ; VMS known files not opened MULTI_NO_COPY .SYSEXE]ANALIMDMP.EXE,1 MULTI_NO_COPY .SYSEXE]AUTHORIZE.EXE,1 MULTI_NO_COPY .SYSEXE]EVL.EXE,1 MULTI_NO_COPY .SYSEXE]INIT.EXE,1 MULTI_NO_COPY .SYSEXE]INSTALL.EXE,1 MULTI_NO_COPY .SYSEXE]NICONFIG.EXE,1 MULTI_NO_COPY .SYSEXE]REQUEST.EXE,1 MULTI_NO_COPY .SYSEXE]SETRIGHTS.EXE,1 MULTI_NO_COPY .SYSEXE]SYSMAN.EXE,1 ;V2-018 MULTI_NO_COPY .SYSLIB]BASRTL2.EXE,1 MULTI_NO_COPY .SYSLIB]CONVSHR.EXE,1 MULTI_NO_COPY .SYSLIB]FDLSHR.EXE,1 MULTI_NO_COPY .SYSLIB]FORRTL2.EXE,1 ;V2-018 MULTI_NO_COPY .SYSLIB]LIBRTL2.EXE,1 MULTI_NO_COPY .SYSLIB]RPGRTL.EXE,1 MULTI_NO_COPY .SYSLIB]SORTSHR.EXE,1 MULTI_NO_COPY .SYSLIB]UISSHR.EXE,1 ;V2-018 MULTI_NO_COPY .SYSMSG]DBGTBKMSG.EXE,1 MULTI_NO_COPY .SYSMSG]FILMNTMSG.EXE,1 MULTI_NO_COPY .SYSMSG]NETWRKMSG.EXE,1 MULTI_NO_COPY .SYSMSG]PASMSG.EXE,1 MULTI_NO_COPY .SYSMSG]PLIMSG.EXE,1 MULTI_NO_COPY .SYSMSG]RPGMSG.EXE,1 MULTI_NO_COPY .SYSMSG]SYSMGTMSG.EXE,1 MULTI_NO_COPY .SYSUTL]FRAG.EXE,1 ;THIS IS UNIQUE TO MY CONFIG ; Unique for 750's that boot off the system disk-need VMB not moved MULTI_NO_COPY .SYSEXE]VMB.EXE,1 ; MFD entries that may arise in cluster common disk GEN_NO_COPY [000000]VMS$COMMON.DIR,\NO_COPY_COUNT ;V2-018 GEN_NO_COPY [000000]SYSCOMMON.DIR,\NO_COPY_COUNT .PAGE .SUBTITLE HEAP AND QUEUES DATA AREA'S .PSECT HEAP_DATA,RD,WRT,NOEXE,PAGE,NOSHR HEAP: .ADDRESS HEAP,HEAP ; QUEUE OF UNUSED HEAP ELEMENTS CONTIGUOUS_FILES_QUEUE: .ADDRESS CONTIGUOUS_FILES_QUEUE,CONTIGUOUS_FILES_QUEUE FRAGMENTED_FILES_QUEUE: .ADDRESS FRAGMENTED_FILES_QUEUE,FRAGMENTED_FILES_QUEUE DIRECTORY_FILES_QUEUE: .ADDRESS DIRECTORY_FILES_QUEUE,DIRECTORY_FILES_QUEUE FREE_SPACE_BY_LBN_QUEUE: .ADDRESS FREE_SPACE_BY_LBN_QUEUE,FREE_SPACE_BY_LBN_QUEUE FREE_SPACE_BY_SIZE_QUEUE: .ADDRESS FREE_SPACE_BY_SIZE_QUEUE,FREE_SPACE_BY_SIZE_QUEUE LARGE_CONTIG_FILES_QUEUE: ;V02-008 .ADDRESS LARGE_CONTIG_FILES_QUEUE,LARGE_CONTIG_FILES_QUEUE;V02-008 LARGE_FRAG_FILES_QUEUE: ;V02-008 .ADDRESS LARGE_FRAG_FILES_QUEUE,LARGE_FRAG_FILES_QUEUE ;V02-008 TOO_LARGE_FILES_QUEUE: ;V02-008 .ADDRESS TOO_LARGE_FILES_QUEUE,TOO_LARGE_FILES_QUEUE ;V02-008 REJECTED_FILES_QUEUE: ;V02-010 .ADDRESS REJECTED_FILES_QUEUE,REJECTED_FILES_QUEUE ;V02-010 ; ; The following formats are used in the various queue's ; ; All element types are the same length so that they can be ; recycled easly. ; ; entries in the contiguous file queue are stored in assending ; order by LBN on disk as to where the contiguous file starts ; ; Entries in the directory file queue are the same as the contiguous ; file queue-stored in order of ascending LBN. ; ; entries in the fragmented file queue are stored in assending ; order by fragment count. ; ; +--------+--------+--------+--------+ ; | Forward link pointer | 0 ; +--------+--------+--------+--------+ ; | Backward link pointer | 4 ; +--------+--------+--------+--------+ ; | File Identification # | 8 ; +--------+--------+--------+--------+ ; | Size (blocks) | 12 ; +--------+--------+--------+--------+ ; | Lowest LBN of file | 16 ;V02-007 ; +--------+--------+--------+--------+ ; | Sequence # | 20 ; +--------+--------+--------+--------+ ; | Number of fragments | 24 ;V02-007 ; +--------+--------+--------+--------+ ;V02-007 ; | Highest LBN of file | 28 ;V02-015 ; +--------+--------+--------+--------+ ;V02-015 ; FILE_ELEMENT_Q_LINK = 0 ;V02-008 FILE_ELEMENT_L_FID = 8 ;V02-008 FILE_ELEMENT_L_SIZE = 12 ;V02-008 FILE_ELEMENT_L_LBN = 16 ;V02-008 FILE_ELEMENT_L_SEQ = 20 ;V02-008 FILE_ELEMENT_L_FRAG = 24 ;V02-008 FILE_ELEMENT_L_HIGH = 28 ;V02-015 ; ; free space elements appear in both free space queues ; useing 2 linked lists ; ; +--------+--------+--------+--------+ ; | LBN Forward link pointer | 0 ; +--------+--------+--------+--------+ ; | LBN Backward link pointer | 4 ; +--------+--------+--------+--------+ ; | Starting LBN # | 8 ; +--------+--------+--------+--------+ ; | Size (blocks) | 12 ; +--------+--------+--------+--------+ ; | Size Forward link pointer | 16 ; +--------+--------+--------+--------+ ; | Size Backward link pointer| 20 ; +--------+--------+--------+--------+ ; FREE_ELEMENT_Q_LBN_LINK = 0 FREE_ELEMENT_L_LBN = 8 FREE_ELEMENT_L_SIZE = 12 FREE_ELEMENT_Q_SIZE_LINK= 16 ; ; ; all elements are the same size for simpler allocation procedures ; ELEMENT_SIZE = 32 ; TOP_OF_NEW_MEMORY: .LONG 0 NEW_MEMORY_REQUIRED: .LONG MORE_HEAP_ARG: .LONG 2 .ADDRESS NEW_MEMORY_REQUIRED,TOP_OF_NEW_MEMORY .PAGE .SUBTITLE HEAP MANAGEMENT ROUTINES .SUBTITLE ALLOCATE MORE HEAP SPACE .PSECT HEAP_CODE,RD,NOWRT,EXE,SHR .ENTRY ALLOCATE_MORE_HEAP,^M ; ; When called, this procedure allocates more memory from the system ; and adds it to the heap queue. ; ; Inputs: None ; ; Output: additional memory on heap. ; R0 LSB SET MORE MEMORY FOUND ; R0 LSB CLEAR NO MORE MEMORY FOUND ; CALLG MORE_HEAP_ARG,G^LIB$GET_VM BLBC R0,1$ MOVL TOP_OF_NEW_MEMORY,R11 MOVL #128,R10 2$: INSQUE (R11),@HEAP+4 ADDL2 #ELEMENT_SIZE,R11 DECL R10 BGTR 2$ 1$: RET .PAGE .SUBTITLE EMPTY FILE QUEUES .PSECT HEAP_CODE,RD,NOWRT,EXE,SHR .ENTRY EMPTY_FILE_QUEUES,0 ; ; removes all entries from the contiguous and fragmented ; file queues and puts the elements back on the heap ; ; Inputs: CONTIGUOUS_FILES_QUEUE ; FRAGMENTED_FILES_QUEUE ; DIRECTORY_FILES_QUEUE ; LARGE_FRAG_FILES_QUEUE ;V02-008 ; LARGE_CONTIG_FILES_QUEUE ;V02-008 ; TOO_LARGE_FILES_QUEUE ;V02-008 ; REJECTED_FILES_QUEUE ;V02-010 ; ; Outputs: HEAP ; ; 1$: REMQUE @CONTIGUOUS_FILES_QUEUE,R1 BEQL 2$ INSQUE (R1),HEAP BRB 1$ 2$: REMQUE @FRAGMENTED_FILES_QUEUE,R1 BEQL 3$ INSQUE (R1),HEAP BRB 2$ 3$: REMQUE @DIRECTORY_FILES_QUEUE,R1 BEQL 4$ INSQUE (R1),HEAP BRB 3$ 4$: REMQUE @REJECTED_FILES_QUEUE,R1 ;V02-010 BEQL 5$ ;V02-010 INSQUE (R1),HEAP ;V02-010 BRB 4$ ;V02-010 5$: REMQUE @LARGE_FRAG_FILES_QUEUE,R1 ;V02-008 BEQL 6$ ;V02-008 INSQUE (R1),HEAP ;V02-008 BRB 5$ ;V02-008 6$: REMQUE @LARGE_CONTIG_FILES_QUEUE,R1 ;V02-008 BEQL 7$ ;V02-008 INSQUE (R1),HEAP ;V02-008 BRB 6$ ;V02-008 7$: REMQUE @TOO_LARGE_FILES_QUEUE,R1 ;V02-008 BEQL 8$ ;V02-008 INSQUE (R1),HEAP ;V02-008 BRB 7$ ;V02-008 8$: MOVL #SS$_NORMAL,R0 ;V02-008 RET .PAGE .SUBTITLE EMPTY FREE QUEUES .PSECT HEAP_CODE,RD,NOWRT,EXE,SHR .ENTRY EMPTY_FREE_QUEUES,0 ; ; Removes all entries from the free fragments queues and returns ; them to the heap ; ; Inputs: ; FREE_SPACE_BY_LBN_QUEUE ; FREE_SPACE_BY_SIZE_QUEUE ; ; Output: ; HEAP ; 1$: REMQUE @FREE_SPACE_BY_LBN_QUEUE,R1 BEQL 2$ INSQUE (R1),HEAP BRB 1$ 2$: MOVAL FREE_SPACE_BY_SIZE_QUEUE,FREE_SPACE_BY_SIZE_QUEUE MOVAL FREE_SPACE_BY_SIZE_QUEUE,FREE_SPACE_BY_SIZE_QUEUE+4 MOVL #SS$_NORMAL,R0 RET .PAGE .SUBTITLE ALLOCATE ELEMENT FROM HEAP .PSECT HEAP_CODE,RD,NOWRT,EXE,SHR .ENTRY ALLOCATE_ELEMENT,0 ; ; Remove an element from the heap and pass it to the ; calling routine ; ; Inputs: Heap ; ; Outputs: R0 ; R0 = address of top of element if one is available ; or zero if no element is available ; REMQUE @HEAP,R0 BEQL 1$ RET 1$: CALLS #0,ALLOCATE_MORE_HEAP BLBC R0,2$ REMQUE @HEAP,R0 BEQL 2$ RET 2$: CLRL R0 RET .PAGE .SUBTITLE INSERT ELEMENT IN CONTIGUOUS FILE QUEUE .PSECT HEAP_CODE,RD,NOWRT,EXE,SHR .ENTRY INSERT_CONTIG_QUEUE,^M ; ; Insert element into the CONTIGUOUS_FILES_QUEUE in order of ascending ; LBN. ; ; Inputs: R0 address of element to be inserted ; CONTIGUOUS_FILES_QUEUE ; ; Outputs: R0 1 ; CONTIGUOUS_FILES_QUEUE ; ; Check first for empty queue ; MOVAL CONTIGUOUS_FILES_QUEUE,R11 MOVL (R11),R10 CMPL R10,R11 BEQL 1$ ; ; Check next for value before first element in queue ; CMPL FILE_ELEMENT_L_LBN(R0),FILE_ELEMENT_L_LBN(R10) ;V02-008 BLEQ 1$ ; ; Next check to see if value is higher than last element in queue ; MOVL CONTIGUOUS_FILES_QUEUE+4,R1 CMPL FILE_ELEMENT_L_LBN(R0),FILE_ELEMENT_L_LBN(R1) ;V02-008 BGEQ 2$ ; ; VBN value lies between min/max of element already in queue. ; scan for location to put it in ; 3$: MOVL (R10),R10 ;Skip to next element CMPL FILE_ELEMENT_L_LBN(R0),FILE_ELEMENT_L_LBN(R10) ;V02-008 BGTR 3$ MOVL 4(R10),R10 ;Backup one INSQUE (R0),(R10) MOVL #SS$_NORMAL,R0 RET 2$: INSQUE (R0),@CONTIGUOUS_FILES_QUEUE+4 MOVL #SS$_NORMAL,R0 RET 1$: INSQUE (R0),CONTIGUOUS_FILES_QUEUE MOVL #SS$_NORMAL,R0 RET .PAGE ;V02-007 .SUBTITLE INSERT ELEMENT IN FRAGMENTED FILE QUEUE ;V02-009 .PSECT HEAP_CODE,RD,NOWRT,EXE,SHR ;V02-007 .ENTRY INSERT_FRAG_QUEUE,^M ;V02-009 ; ;V02-007 ; Insert element into the FRAGMENTED_FILES_QUEUE in order of ;V02-009 ; assending LBN. ;V02-007 ; ;V02-007 ; Inputs: R0 address of element to be inserted ;V02-007 ; FRAGMENTED_FILES_QUEUE ;V02-009 ; ;V02-007 ; Outputs: R0 1 ;V02-007 ; FRAGMENTED_FILES_QUEUE ;V02-009 ; ;V02-007 ; Check first for empty queue ;V02-007 ; ;V02-007 MOVAL FRAGMENTED_FILES_QUEUE,R11 ;V02-009 MOVL (R11),R10 ;V02-007 CMPL R10,R11 ;V02-007 BEQL 1$ ;V02-007 ; ;V02-007 ; Check next for value before first element in queue ;V02-007 ; ;V02-007 CMPL FILE_ELEMENT_L_LBN(R0),FILE_ELEMENT_L_LBN(R10) ;V02-008 BLEQ 1$ ;V02-007 ; ;V02-007 ; Next check to see if value is higher than last element in queue ;V02-007 ; ;V02-007 MOVL FRAGMENTED_FILES_QUEUE+4,R1 ;V02-009 CMPL FILE_ELEMENT_L_LBN(R0),FILE_ELEMENT_L_LBN(R1) ;V02-008 BGEQ 2$ ;V02-007 ; ;V02-007 ; VBN value lies between min/max of element already in queue. ;V02-007 ; scan for location to put it in ;V02-007 ; ;V02-007 3$: MOVL (R10),R10 ;Skip to next element ;V02-007 CMPL FILE_ELEMENT_L_LBN(R0),FILE_ELEMENT_L_LBN(R10) ;V02-008 BGTR 3$ ;V02-007 MOVL 4(R10),R10 ;Backup one ;V02-007 INSQUE (R0),(R10) ;V02-007 MOVL #SS$_NORMAL,R0 ;V02-007 RET ;V02-007 2$: INSQUE (R0),@FRAGMENTED_FILES_QUEUE+4 ;V02-009 MOVL #SS$_NORMAL,R0 ;V02-007 RET ;V02-007 1$: INSQUE (R0),FRAGMENTED_FILES_QUEUE ;V02-009 MOVL #SS$_NORMAL,R0 ;V02-007 RET ;V02-007 .PAGE ;V02-008 .SUBTITLE INSERT ELEMENT IN LARGE FRAGMENTED FILE QUEUE ;V02-008 .PSECT HEAP_CODE,RD,NOWRT,EXE,SHR ;V02-008 .ENTRY INSERT_LARGE_FRAG_QUEUE,^M ;V02-008 ; ;V02-008 ; Insert element into the LARGE_FRAG_FILES_QUEUE in order of ;V02-008 ; assending LBN. ;V02-008 ; ;V02-008 ; Inputs: R0 address of element to be inserted ;V02-008 ; LARGE_FRAG_FILES_QUEUE ;V02-008 ; ;V02-008 ; Outputs: R0 1 ;V02-008 ; LARGE_FRAG_FILES_QUEUE ;V02-008 ; ;V02-008 ; Check first for empty queue ;V02-008 ; ;V02-008 MOVAL LARGE_FRAG_FILES_QUEUE,R11 ;V02-008 MOVL (R11),R10 ;V02-008 CMPL R10,R11 ;V02-008 BEQL 1$ ;V02-008 ; ;V02-008 ; Check next for value before first element in queue ;V02-008 ; ;V02-008 CMPL FILE_ELEMENT_L_LBN(R0),FILE_ELEMENT_L_LBN(R10) ;V02-008 BLEQ 1$ ;V02-008 ; ;V02-008 ; Next check to see if value is higher than last element in queue ;V02-008 ; ;V02-008 MOVL LARGE_FRAG_FILES_QUEUE+4,R1 ;V02-008 CMPL FILE_ELEMENT_L_LBN(R0),FILE_ELEMENT_L_LBN(R1) ;V02-008 BGEQ 2$ ;V02-008 ; ;V02-008 ; VBN value lies between min/max of element already in queue. ;V02-008 ; scan for location to put it in ;V02-008 ; ;V02-008 3$: MOVL (R10),R10 ;Skip to next element ;V02-008 CMPL FILE_ELEMENT_L_LBN(R0),FILE_ELEMENT_L_LBN(R10) ;V02-008 BGTR 3$ ;V02-008 MOVL 4(R10),R10 ;Backup one ;V02-008 INSQUE (R0),(R10) ;V02-008 MOVL #SS$_NORMAL,R0 ;V02-008 RET ;V02-008 2$: INSQUE (R0),@LARGE_FRAG_FILES_QUEUE+4 ;V02-008 MOVL #SS$_NORMAL,R0 ;V02-008 RET ;V02-008 1$: INSQUE (R0),LARGE_FRAG_FILES_QUEUE ;V02-008 MOVL #SS$_NORMAL,R0 ;V02-008 RET ;V02-008 .PAGE ;V02-008 .SUBTITLE INSERT ELEMENT IN LARGE CONTIGUOUS FILE QUEUE ;V02-008 .PSECT HEAP_CODE,RD,NOWRT,EXE,SHR ;V02-008 .ENTRY INSERT_LARGE_CONTIG_QUEUE,^M ;V02-008 ; ;V02-008 ; Insert element into the LARGE_CONTIG_FILES_QUEUE in order of ;V02-008 ; assending LBN. ;V02-008 ; ;V02-008 ; Inputs: R0 address of element to be inserted ;V02-008 ; LARGE_CONTIG_FILES_QUEUE ;V02-008 ; ;V02-008 ; Outputs: R0 1 ;V02-008 ; LARGE_CONTIG_FILES_QUEUE ;V02-008 ; ;V02-008 ; Check first for empty queue ;V02-008 ; ;V02-008 MOVAL LARGE_CONTIG_FILES_QUEUE,R11 ;V02-008 MOVL (R11),R10 ;V02-008 CMPL R10,R11 ;V02-008 BEQL 1$ ;V02-008 ; ;V02-008 ; Check next for value before first element in queue ;V02-008 ; ;V02-008 CMPL FILE_ELEMENT_L_LBN(R0),FILE_ELEMENT_L_LBN(R10) ;V02-008 BLEQ 1$ ;V02-008 ; ;V02-008 ; Next check to see if value is higher than last element in queue ;V02-008 ; ;V02-008 MOVL LARGE_CONTIG_FILES_QUEUE+4,R1 ;V02-008 CMPL FILE_ELEMENT_L_LBN(R0),FILE_ELEMENT_L_LBN(R1) ;V02-008 BGEQ 2$ ;V02-008 ; ;V02-008 ; VBN value lies between min/max of element already in queue. ;V02-008 ; scan for location to put it in ;V02-008 ; ;V02-008 3$: MOVL (R10),R10 ;Skip to next element ;V02-008 CMPL FILE_ELEMENT_L_LBN(R0),FILE_ELEMENT_L_LBN(R10) ;V02-008 BGTR 3$ ;V02-008 MOVL 4(R10),R10 ;Backup one ;V02-008 INSQUE (R0),(R10) ;V02-008 MOVL #SS$_NORMAL,R0 ;V02-008 RET ;V02-008 2$: INSQUE (R0),@LARGE_CONTIG_FILES_QUEUE+4 ;V02-008 MOVL #SS$_NORMAL,R0 ;V02-008 RET ;V02-008 1$: INSQUE (R0),LARGE_CONTIG_FILES_QUEUE ;V02-008 MOVL #SS$_NORMAL,R0 ;V02-008 RET ;V02-008 .PAGE ;V02-008 .SUBTITLE INSERT ELEMENT IN TOO LARGE FILE QUEUE ;V02-008 .PSECT HEAP_CODE,RD,NOWRT,EXE,SHR ;V02-008 .ENTRY INSERT_TOO_LARGE_QUEUE,^M ;V02-008 ; ;V02-008 ; Insert element into the TOO_LARGE_FILES_QUEUE at end of ;V02-008 ; queue ;V02-008 ; ;V02-008 ; Inputs: R0 address of element to be inserted ;V02-008 ; TOO_LARGE_FILES_QUEUE ;V02-008 ; ;V02-008 ; Outputs: R0 1 ;V02-008 ; TOO_LARGE_FILES_QUEUE ;V02-008 ; ;V02-008 INSQUE (R0),@TOO_LARGE_FILES_QUEUE+4 ;V02-008 MOVL #SS$_NORMAL,R0 ;V02-008 RET ;V02-008 .PAGE ;V02-010 .SUBTITLE INSERT ELEMENT IN REJECTED FILE QUEUE ;V02-010 .PSECT HEAP_CODE,RD,NOWRT,EXE,SHR ;V02-010 .ENTRY INSERT_REJECTED_QUEUE,^M ;V02-010 ; ;V02-010 ; Insert element into the REJECTED_FILES_QUEUE at end of ;V02-010 ; queue ;V02-010 ; ;V02-010 ; Inputs: R0 address of element to be inserted ;V02-010 ; REJECTED_FILES_QUEUE ;V02-010 ; ;V02-010 ; Outputs: R0 1 ;V02-010 ; REJECTED_FILES_QUEUE ;V02-010 ; ;V02-010 INSQUE (R0),@REJECTED_FILES_QUEUE+4 ;V02-010 MOVL #SS$_NORMAL,R0 ;V02-010 RET ;V02-010 .PAGE .SUBTITLE INSERT ELEMENT IN DIRECTORY FILE QUEUE .PSECT HEAP_CODE,RD,NOWRT,EXE,SHR .ENTRY INSERT_DIR_QUEUE,^M ; ; Insert element into the DIRECTORY_FILES_QUEUE in order of ascending ; LBN. ; ; Inputs: R0 address of element to be inserted ; DIRECTORY_FILES_QUEUE ; ; Outputs: R0 1 ; DIRECTORY_FILES_QUEUE ; ; Check first for empty queue ; MOVAL DIRECTORY_FILES_QUEUE,R11 MOVL (R11),R10 CMPL R10,R11 BEQL 1$ ; ; Check next for value before first element in queue ; CMPL FILE_ELEMENT_L_LBN(R0),FILE_ELEMENT_L_LBN(R10) ;V02-008 BLEQ 1$ ; ; Next check to see if value is higher than last element in queue ; MOVL DIRECTORY_FILES_QUEUE+4,R1 CMPL FILE_ELEMENT_L_LBN(R0),FILE_ELEMENT_L_LBN(R1) ;V02-008 BGEQ 2$ ; ; VBN value lies between min/max of element already in queue. ; scan for location to put it in ; 3$: MOVL (R10),R10 ;Skip to next element CMPL FILE_ELEMENT_L_LBN(R0),FILE_ELEMENT_L_LBN(R10) ;V02-008 BGTR 3$ MOVL 4(R10),R10 ;Backup one INSQUE (R0),(R10) MOVL #SS$_NORMAL,R0 RET 2$: INSQUE (R0),@DIRECTORY_FILES_QUEUE+4 MOVL #SS$_NORMAL,R0 RET 1$: INSQUE (R0),DIRECTORY_FILES_QUEUE MOVL #SS$_NORMAL,R0 RET .PAGE .SUBTITLE INSERT ELEMENT IN FREE SPACE QUEUES .PSECT HEAP_CODE,RD,NOWRT,EXE,SHR .ENTRY INSERT_FREE_QUEUES,^M ; ; Insert element into the FREE_SPACE_BY_LBN_QUEUE and ; FREE_SPACE_BY_SIZE_QUEUE in order of ascending ; parameter values. ; ; Inputs: R0 address of element to be inserted ; FREE_SPACE_BY_LBN_QUEUE ; FREE_SPACE_BY_SIZE_QUEUE ; ; Outputs: R0 1 ; FREE_SPACE_BY_LBN_QUEUE ; FREE_SPACE_BY_SIZE_QUEUE ; ; First insert in FREE_SPACE_BY_LBN_QUEUE ; ; Check first for empty queue ; MOVAL FREE_SPACE_BY_LBN_QUEUE,R11 MOVL (R11),R10 CMPL R10,R11 BEQL 100$ ; ; Next for placement as new first element in queue ; CMPL FREE_ELEMENT_L_LBN(R0),FREE_ELEMENT_L_LBN(R10) BLEQ 1$ ; ; Next check to see if value is higher than last element in queue ; MOVL FREE_SPACE_BY_LBN_QUEUE+4,R1 CMPL FREE_ELEMENT_L_LBN(R0),FREE_ELEMENT_L_LBN(R1) BGEQ 2$ ; ; Size value lies between min/max of element already in queue. ; scan for location to put it in ; 3$: MOVL (R10),R10 ;Skip to next element CMPL FREE_ELEMENT_L_LBN(R0),FREE_ELEMENT_L_LBN(R10) BGTR 3$ MOVL 4(R10),R10 ;Backup one INSQUE (R0),(R10) BRB 10$ 2$: INSQUE (R0),@FREE_SPACE_BY_LBN_QUEUE+4 BRB 10$ 1$: INSQUE (R0),FREE_SPACE_BY_LBN_QUEUE BRB 10$ ; ; If one is empty-both are ; 100$: MOVAL FREE_ELEMENT_Q_SIZE_LINK(R0),R1 INSQUE (R1),FREE_SPACE_BY_SIZE_QUEUE INSQUE (R0),FREE_SPACE_BY_LBN_QUEUE MOVL #SS$_NORMAL,R0 RET ; ; Now insert in FREE_SPACE_BY_SIZE_QUEUE ; 10$: MOVAL FREE_SPACE_BY_SIZE_QUEUE,R11 MOVAL FREE_ELEMENT_Q_SIZE_LINK(R0),R0 MOVL (R11),R10 ; ; Check for placement as new first element in queue ; CMPL (R0),- (R10) BLEQ 11$ ; ; Next check to see if value is higher than last element in queue ; MOVL FREE_SPACE_BY_SIZE_QUEUE+4,R1 CMPL (R0),- (R1) BGEQ 12$ ; ; Size value lies between min/max of element already in queue. ; scan for location to put it in ; 13$: MOVL (R10),R10 ;Skip to next element CMPL (R0),- (R10) BGTR 13$ MOVL 4(R10),R10 ;Backup one INSQUE (R0),(R10) MOVL #SS$_NORMAL,R0 RET 12$: INSQUE (R0),@FREE_SPACE_BY_SIZE_QUEUE+4 MOVL #SS$_NORMAL,R0 RET 11$: INSQUE (R0),FREE_SPACE_BY_SIZE_QUEUE MOVL #SS$_NORMAL,R0 RET .PAGE .SUBTITLE BUILD FILE NAME FROM SEQUENCE NUMBER .PSECT FILE_CODE,RD,NOWRT,EXE,SHR .ENTRY BUILD_FILE_NAME,^M ; ; Given an input of a file header ID number, build a string ; containing the full name with directory string and device. ; ; Inputs: (AP) 4/5 ; 4(AP) FID-Pass by value ; 8(AP) Result string-address of descripter ; 12(AP) Address of long word to recieve length of file name ; 16(AP) File Sequence Number-Pass by value ; 20(AP) If already in memory-address of file header block ; ; ; DEVICE_NAME ; FILE_HEADER_VBN ; ; Outputs: 8(AP) Full file name in string ; R0 LSB = 1 Translation OK ; R0 LSB = 0 Error occoured-no translation ; ; Other JUICER routines called: ; INDEXF_READ ; ; First see if this is the same FID as the last done ? CMPL 4(AP),LAST_FID BNEQ 1$ ; YES-JUST RETURN THAT INFORMATION-NO NEED TO DO IT AGAIN ; SEE IF ENOUGH SPACE AVAILABLE TO LOAD STRING CMPL LAST_LENGTH,@8(AP) BLEQ 3$ CLRL R0 RET ; IF EMPTY-GO TRY AGAIN 3$: TSTL LAST_LENGTH BEQL 1$ MOVL LAST_LENGTH,@12(AP) MOVL 8(AP),R11 MOVC3 LAST_LENGTH,L^FILE_NAME_STRING,@4(R11) MOVL #SS$_NORMAL,R0 RET ; Load device name into scratch string and set up working registers ; ; R10 Number of chars in name ; R8 Pointer to next location to put char in scratch string ; 1$: MOVZBL DEVICE_NAME,R10 MOVC3 R10,@DEVICE_NAME+4,L^FILE_NAME_STRING ADDL3 R10,I^#FILE_NAME_STRING,R8 ; ; FILL IN EMPTY DIRECTORY DELIMITERS ; MOVW #^A/[]/,(R8) ADDL2 #2,R10 ; ; GET THE FILE HEADER IF NOT ALREADY IN MEMORY ; CMPL #5,(AP) BNEQ 7$ MOVC3 #512,@20(AP),L^BUILD_FILE_NAME_BUFFER BRB 5$ 7$: PUSHL #1 ; Get one header block PUSHAL L^BUILD_FILE_NAME_BUFFER ADDL3 FILE_HEADER_VBN,4(AP),R0 DECL R0 PUSHL R0 CALLS #3,INDEXF_READ BLBS R0,5$ RET 5$: ; ; Check the sequence number ; CMPW 16(AP),L^ BEQL 2$ CLRL R0 RET ; ; GET THE FILE NAME ; 2$: MOVZBL L^,R7 MULL2 #2,R7 ; ; BUILD A CONTIGUOUS FORM OF THE FILE NAME ; MOVC3 #FI2$S_FILENAME,- L^(R7),- 2(R8) MOVC3 #FI2$S_FILENAMEXT,- L^(R7),- (R8) ; ; LOCATE TERMINATEING BLANK OF FILE NAME ; LOCC #^A/ /,#,- 2(R8) SUBL3 R0,#,R1 ADDL2 R1,R10 ;BUMP COUNT OF LINE SIZE INCL R8 .PAGE .SUBTITLE LOOP TO PUT DIRECTORY STRING INTO FILE NAME ; ; R10 is a count of the number of characters in the string ; R8 points to the closeing bracket where the directory string ; is to be placed. ; ; NOW DO A LOOP BACK THROUGH BACK POINTERS THROUGH DIRECTORIES ; BUILDING THE EXACT LOCATION IN DIR TREE OF FILE ; ; ; GET SEQUENCE NUMBER OF DIRECTORY VIA BACK POINTER ; MOVW L^,TEMP_FID MOVZBW L^,TEMP_FID+2 ; DIR_LOOP: TSTL TEMP_FID ;SEE IF RAN OUT OF BACK POINTERS BNEQ 5$ ;NO BRW END_DIR_LOOP ;YES 5$: ; ; CHECK TO SEE IF THIS DIRECTORY IS IN THE TABLE-USE BINARY SEARCH ; TSTL CURRENT_DIR_ENTRY ;SEE IF TABLE EMPTY BNEQ 20$ ;NO BRW 10$ ;EMPTY-GO TO READ IN CODE 20$: CMPL TEMP_FID,L^DIR_TABLE+DIR_L_FID ;SEE IF IN RANGE OF TABLE BGTRU 22$ ;HIGHER THAN LOWEST IN TABLE BEQLU 1021$ ;FOUND IT AT START BRW 10$ ;TO LOW-NOT IN TABLE 1021$: BRW 21$ 22$: MULL3 #DIR_LENGTH,CURRENT_DIR_ENTRY,R1 SUBL2 #DIR_LENGTH,R1 CMPL TEMP_FID,L^DIR_TABLE+DIR_L_FID(R1);CHECK AGINST HIGH END BEQLU 23$ ;FOUND IT HIGH END BLSSU 24$ ;LESS THAN HIGHEST BRW 10$ ;TO HIGH 24$: CLRL R0 ;SET UP POINTERS AND COUNTERS SUBL3 #1,CURRENT_DIR_ENTRY,R2 ;FOR BINARY SEARCH MULL3 #DIR_LENGTH,R0,R1 MULL3 #DIR_LENGTH,R2,R3 25$: ADDL3 R0,R2,R4 ;GET NEW POINT TO TEST DIVL2 #2,R4 MULL3 #DIR_LENGTH,R4,R5 CMPL R4,R0 ;CHECK TO SEE IF REPEAT OF BNEQ 26$ ;PREVIOUS POINT-IF SO-NOT HERE BRW 10$ 26$: CMPL R4,R2 BNEQ 27$ BRW 10$ 27$: MULL3 #DIR_LENGTH,R4,R5 CMPL TEMP_FID,L^DIR_TABLE+DIR_L_FID(R5);CHECK FOR MATCH OR HIGH/LOW BEQL 28$ ;FOUND MATCH BLSSU 29$ MOVQ R4,R0 ;REPLACE LOW POINTER BRW 25$ ;ITERATE ONCE MORE 29$: MOVQ R4,R2 ;REPLACE HIGH POINTER BRW 25$ ;ITERATE AGAIN 21$: CLRL R4 ;SET UP POINTERS TO MATCH OF CLRL R5 ;LOW END BRB 28$ 23$: MOVL R1,R5 ;SET UP POINERS TO MATCH SUBL3 #1,CURRENT_DIR_ENTRY,R4 ;HIGH END 28$: ; HANDLE MATCH OF TARGET FID WITH AN ENTRY IN TABLE .PAGE .SUBTITLE UPDATE DIRECTORY STRING WITH ENTRY FOUND IN TABLE MOVL L^DIR_TABLE+DIR_L_NXT_FID(R5),TEMP_FID ;SET UP PTR TO NEXT ; ; SEE IF DOT IS NEEDED IN DIR STRING ; MOVZBL L^DIR_TABLE+DIR_B_CNT(R5),R7 DECL R7 CMPB #^A/]/,(R8) ;IS THIS FIRST DIR ENTRY BEQL 31$ ; ; SEE IF THIS IS DIR [000000] IF SO AT THIS POINT ; OTHER DIR ENTRIES HAVE BEEN MADE SO THIS IS NOT ; NEEDED-SKIP PUTTING IT IN ; CMPL #4,L^DIR_TABLE+DIR_L_FID(R5) BNEQ 34$ BRW END_DIR_LOOP 34$: INCL R7 ;DOT NEEDED 31$: ADDL2 R7,R10 ;BUMP COUNT OF LINE SIZE ; ; MOVE NAME AS BUILT SO FAR DOWN TO FIT IN DIR NAME ; SUBL3 R10,#4096,R6 SUBL2 R7,R6 ADDL3 R7,R8,R1 PUSHR #^M MOVC3 R6,(R8),(R1) ; ; MOVE IN DIR NAME ; POPR #^M PUSHR #^M MOVC3 R7,L^DIR_TABLE+DIR_T_NAME(R5),(R8) POPR #^M ; ; NOW SEE IF THIS IS DIR [000000] WE JUST GOT-IF SO DONE ; CMPL #4,L^DIR_TABLE+DIR_L_FID(R5) BNEQ 33$ BRW END_DIR_LOOP 33$: BRW DIR_LOOP .PAGE .SUBTITLE GET DIR NAME FROM FILE HEADER NOT TABLE-PUT IN TABLE ; ; AND READ IN THE FILE HEADER ; 10$: PUSHL #1 ; Get one header block PUSHAL L^BUILD_FILE_NAME_BUFFER ADDL3 FILE_HEADER_VBN,TEMP_FID,R0 DECL R0 PUSHL R0 CALLS #3,INDEXF_READ BLBS R0,2$ RET ; ; GET THE DIR NAME ; 2$: MOVZBL L^,R5 MULL2 #2,R5 ; ; BUILD A CONTIGUOUS FORM OF THE DIRECTORY NAME ; MOVC3 #FI2$S_FILENAME,- L^(R5),- TEMP_STRING MOVC3 #FI2$S_FILENAMEXT,- L^(R5),- TEMP_STRING+FI2$S_FILENAME ; ; LOCATE DOT IN DIR NAME ; LOCC #^A/./,#,- TEMP_STRING SUBL3 R0,#,R7 ; ; ENTER NEW DIRECTORY IN TO TABLE ; CMPL #DIR_MAX,CURRENT_DIR_ENTRY ;SEE IF TABLE FULL BGTRU 15$ BRW 11$ ;TABLE IS FULL 15$: MULL3 #DIR_LENGTH,CURRENT_DIR_ENTRY,R0;BUILD OFFSET TO NEW ENTRY ADDL2 I^#DIR_TABLE,R0 INCL CURRENT_DIR_ENTRY ;ACCOUNT FOR IT MOVL TEMP_FID,DIR_L_FID(R0) ;LOAD ENTRY ; ; GET POINTER TO NEXT ELEMENT UP THE CHAIN-BOTH FOR TABLE AN ; FOR NEXT LOOP ITERATION ; MOVW L^,TEMP_FID MOVZBW L^,TEMP_FID+2 MOVL TEMP_FID,DIR_L_NXT_FID(R0) ; ; LOAD COUNT AND STRING ; ADDL3 #1,R7,R1 ;INCLUDE THE TERMINATEING DOT MOVB R1,DIR_B_CNT(R0) PUSHR #^M MOVC3 R1,TEMP_STRING,DIR_T_NAME(R0) POPR #^M ; ; NOW SORT THE LIST TO PUT THE NEW ENTRY IN ASCENDING FID ORDER ; CMPL R6,I^#DIR_TABLE ;CHECK FOR CASE-ONLY ENTRY BGTRU 13$ BRW 11$ 13$: CMPL DIR_L_FID(R6),(R6) ;SEE IF SMALLER BLSSU 14$ ;YES BRW 11$ ;NO-IN PLACE 14$: MOVC3 #DIR_LENGTH,(R6),DIR_TEMP ;SWAP MOVC3 #DIR_LENGTH,-DIR_LENGTH(R6),(R6) MOVC3 #DIR_LENGTH,DIR_TEMP,-DIR_LENGTH(R6) SUBL2 #DIR_LENGTH,R6 ;NEXT SLOT DWN CMPL R6,I^#DIR_TABLE ;SEE IF DONE BGTRU 13$ ;NO-CONTINUE ; ; SEE IF DOT IS NEEDED IN DIR STRING ; 11$: CMPB #^A/]/,(R8) ;IS THIS FIRST DIR ENTRY BEQL 1$ ; ; SEE IF THIS IS DIR [000000] IF SO AT THIS POINT ; OTHER DIR ENTRIES HAVE BEEN MADE SO THIS IS NOT ; NEEDED-SKIP PUTTING IT IN ; TSTB L^ BNEQ 4$ CMPW #4,L^ BNEQ 4$ BRW END_DIR_LOOP 4$: INCL R7 ;DOT NEEDED 1$: ADDL2 R7,R10 ;BUMP COUNT OF LINE SIZE ; ; MOVE NAME AS BUILT SO FAR DOWN TO FIT IN DIR NAME ; SUBL3 R10,#4096,R6 SUBL2 R7,R6 ADDL3 R7,R8,R1 MOVC3 R6,(R8),(R1) ; ; MOVE IN DIR NAME ; MOVC3 R7,TEMP_STRING,(R8) ; ; NOW SEE IF THIS IS DIR [000000] WE JUST GOT-IF SO DONE ; TSTB L^ BNEQ 3$ CMPW #4,L^ BNEQ 3$ BRW END_DIR_LOOP 3$: BRW DIR_LOOP .PAGE .SUBTITLE FINISH UP BUILD FILE NAME END_DIR_LOOP: MOVZWL @8(AP),R0 ; Get length of target string CMPL R10,R0 ; See if enough room to store it BGTR 1$ ; OOPS ; ; This cluge is a fix up for the case of a directory string including ; dev:[SYSCOMMON.... this appears in in 000000.DIR as VMS$COMMON.DIR ; so must be changed to match ; ; first see if this is the special case LOCC #^A/[/,R10,L^FILE_NAME_STRING ;FIND OPENING [ ADDL3 #1,R1,R9 ;GET ADDR OF DIR NAME CMPC3 #SYS_STRING_LENGTH,SYS_STRING,(R9) ;SEE IF THIS IS IT BNEQ 2$ ;NOPE ; replace SYSCOMMON by VMS$COMMON ; FIRST ADJUST THE TRAILING CHARACTERS-CALC NUMBER OF CHARS TO MOVE SUBL3 I^#FILE_NAME_STRING,R9,R8 ADDL2 #SYS_STRING_LENGTH,R8 SUBL3 R8,R10,R7 ;R7 CONTAINS NUMBER OF CHARS MOVC3 R7,SYS_STRING_LENGTH(R9),V4_STRING_LENGTH(R9) ;MOVE TRAILING MOVC3 #V4_STRING_LENGTH,V4_STRING,(R9) ;LOAD NEW NAME ADDL2 #,R10 ;ADJ COUNT 2$: MOVL 8(AP),R1 MOVC3 R10,L^FILE_NAME_STRING,@4(R1) MOVL R10,@12(AP) MOVL #SS$_NORMAL,R0 MOVL R10,LAST_LENGTH MOVL 4(AP),LAST_FID RET 1$: CLRL R0 RET .PAGE .SUBTITLE INIT DIRECTORY LIST .ENTRY INIT_DIRECTORY_LIST,^M<> ; ; BUILD_FILE_NAME uses an internal table to hold ; a list of directory names. This routine init's it ; when a new scan is done of the file headers ; CLRL CURRENT_DIR_ENTRY RET .PAGE .SUBTITLE BUILD FILE NAME DATA AREA .PSECT FILE_DATA,RD,WRT,NOEXE,PAGE,NOSHR LAST_FID: .LONG 0 LAST_LENGTH: .LONG 0 TEMP_FID: .BLKL 1 TEMP_STRING: .BLKB BUILD_FILE_NAME_BUFFER: .BLKB 512 FILE_NAME_STRING: .BLKB 4096 .PSECT FILE_DATA_CONST,RD,NOWRT,NOEXE,SHR V4_STRING: .ASCII /VMS$COMMON/ ;V2.18 V4_STRING_LENGTH=.-V4_STRING SYS_STRING: .ASCII /SYSCOMMON/ SYS_STRING_LENGTH=.-SYS_STRING .PAGE .SUBTITLE DIRECTORY TABLE .PSECT DIRECTORY_DATA,RD,WRT,NOEXE,PAGE,NOSHR ; ; EACH ENTRY IN THE DIRECTORY TABLE HAS THE FOLLOWING FORMAT ; ; +--------------------------------+ ; | FID | 0 ; +--------------------------------+ ; | NEXT FID | 4 ; +--------------------------------+ ; | NAME | CNT | 8 ; +--------------------------------+ ; . ; . ; . ; . ; +--------------------------------+ ; | | ; +--------------------------------+ DIR_L_FID = 0 ;FID OF DIRECTORY ENTRY DIR_L_NXT_FID = 4 ;FID OF DIRECTORY THIS DIR IS IN DIR_B_CNT = 8 ;NO OF CHRS IN DIR NAME STRING DIR_T_NAME = 9 ;STARTING LOC OF NAME STRING DIR_S_NAME = FI2$S_FILENAME+FI2$S_FILENAMEXT DIR_LENGTH = 9+DIR_S_NAME DIR_MAX = 2000 ;2000 ENTRIES MAX CURRENT_DIR_ENTRY: .LONG 0 DIR_TEMP: .BLKB DIR_LENGTH DIR_TABLE: .BLKB .PAGE .SUBTITLE SCAN INDEXF.SYS FOR FILE'S FOR CONTIG AND FRAG QUEUES .PSECT SCAN_HEADER_CODE,RD,NOWRT,EXE,SHR .ENTRY SCAN_FILE_HEADERS,^M ; ; Called with no arguments. scans the file headers in INDEXF.SYS ; for candidates to enter into either the CONTIGUOUS_FILES_QUEUE or ; the FRAGMENTED_FILES_QUEUE, or DIRECTORY_FILES_QUEUE. ; ; Inputs: FRAGMENTED_FILES_QUEUE ; CONTIGUOUS_FILES_QUEUE ; DIRECTORY_FILES_QUEUE ; LARGE_FRAG_FILES_QUEUE ;V02-008 ; LARGE_CONTIG_FILES_QUEUE ;V02-008 ; TOO_LARGE_FILES_QUEUE ;V02-008 ; LARGEST_FREE_FRAGMENT ; FILE_HEADER_VBN ; FREE_BLOCKS ;V02-008 ; ; Outputs:FRAGMENTED_FILES_QUEUE ; CONTIGUOUS_FILES_QUEUE ; DIRECTORY_FILES_QUEUE ; LARGE_FRAG_FILES_QUEUE ;V02-008 ; LARGE_CONTIG_FILES_QUEUE ;V02-008 ; TOO_LARGE_FILES_QUEUE ;V02-008 ; FILE_COUNT ;V02-004 ; POINTER_COUNT ;V02-004 ; ; Juicer routines called: ; ALLOCATE_ELEMENT ; CHECK_LIST ;V02-009 ; EMPTY_FILE_QUEUES ; HEADER_VALID ; INIT_DIRECTORY_LIST ; INSERT_CONTIG_QUEUE ; INSERT_DIR_QUEUE ; INSERT_FRAG_QUEUE ; INSERT_TOO_LARGE_QUEUE ;V02-008 ; INSERT_LARGE_FRAG_QUEUE ;V02-008 ; INSERT_LARGE_CONTIG_QUEUE ;V02-008 ; INSERT_REJECTED_QUEUE ;V02-010 ; INDEXF_READ ; UPDATE_LOGICAL_NAME ;V02-002 ; UPDATE_DISK_DATA ;V02-004 ; ; This routine scans through INDEXF.SYS looking for candidates ; for inclusion into one of seven(7) queues: ;V02-008 ; ; CONTIGUOUS_FILES_QUEUE ;V02-008 ; Uses only one retrieval pointer ;V02-008 ; File size is less than or equal to the largest free ;V02-008 ; frag on disk ;V02-008 ; Not a file structure file (FID 1-9) ;V02-008 ; File can be opend for exclusive use by JUICER (no ;V02-008 ; installed or opened files) ;V02-008 ; File not on list of verboten files ;V02-008 ; Not flagged as a directory file ;V02-008 ; LARGE_CONTIG_FILES_QUEUE ;V02-008 ; Uses only one retrieval pointer ;V02-008 ; File size is larger than the largest free frag on disk ;V02-008 ; and less than or equal to the total free space ;V02-008 ; left on disk ;V02-008 ; Not a file structure file (FID 1-9) ;V02-008 ; File can be opend for exclusive use by JUICER (no ;V02-008 ; installed or opened files) ;V02-008 ; File not on list of verboten files ;V02-008 ; Not flagged as a directory file ;V02-008 ; DIRECTORY_FILES_QUEUE ;V02-008 ; Uses only one retrieval pointer ;V02-008 ; File size is ignored ;V02-008 ; Not a file structure file (FID 1-9) ;V02-008 ; File can be opend for exclusive use by JUICER (no ;V02-008 ; installed or opened files) ;V02-008 ; File not on list of verboten files ;V02-008 ; Flagged as a directory file ;V02-008 ; FRAGMENTED_FILES_QUEUE ;V02-008 ; Ueses more than one retrival pointer ;V02-009 ; File size is less than or equal to the largest free ;V02-008 ; frag on disk ;V02-008 ; Not a file structure file (FID 1-9) ;V02-008 ; File can be opend for exclusive use by JUICER (no ;V02-008 ; installed or opened files) ;V02-008 ; File not on list of verboten files ;V02-008 ; Not flagged as a directory file ;V02-008 ; LARGE_FRAG_QUEUE ;V02-008 ; Uses multiple retrival pointers. ;V02-008 ; File size is larger than the largest free frag on disk ;V02-008 ; and less than or equal to the total free space ;V02-008 ; left on disk ;V02-008 ; Not a file structure file (FID 1-9) ;V02-008 ; File can be opend for exclusive use by JUICER (no ;V02-008 ; installed or opened files) ;V02-008 ; File not on list of verboten files ;V02-008 ; Not flagged as a directory file ;V02-008 ; TOO_LARGE_FILES_QUEUE ;V02-008 ; Retrival pointer count is ignored ;V02-008 ; File size is larger than the total free space left. ;V02-008 ; Not a file structure file (FID 1-9) ;V02-008 ; File can be opend for exclusive use by JUICER (no ;V02-008 ; installed or opened files) ;V02-008 ; File not on list of verboten files ;V02-008 ; Not flagged as a directory file ;V02-008 ; REJECTED_FILES_QUEUE ;V02-010 ; All files that are found not to be eligable in any of ;V02-010 ; the other queues as they are on the VERBOTEN list.Also ;V02-010 ; durinf defrag processing-any file found to be open is ;V02-010 ; moved to this list. ;V02-010 ; ; Flush the xxx_FILE_QUEUES of the data from the previous ; scan ; PUSHAL HEADER_STATE ;V02-002 PUSHAL HEADER_STATUS ;V02-002 CALLS #2,UPDATE_LOGICAL_NAME ;V02-002 .IIF DF,DEBUG2, CLRL LIMIT_COUNT CALLS #0,EMPTY_FILE_QUEUES CALLS #0,INIT_DIRECTORY_LIST ; INIT LIST OF DIR'S IN BUILD FILE NAME MOVL #64,GROUP_COUNT ; SET THE NUMBER OF HEADERS TO READ ; AT ONE TIME MOVL FILE_HEADER_VBN,INDEXF_VBN ;SET STARTING POINT OF SCAN CLRL FILE_COUNT ;V02-004 CLRL POINTER_COUNT ;V02-004 HEADER_SCAN_LOOP: SUBL3 FILE_HEADER_VBN,INDEXF_VBN,R0 ;V02-006 INCL R0 ;V02-006 $FAO_S CTRSTR=HEADER_FAO,- ;V02-006 OUTBUF=HEADER_VALUE,- ;V02-006 P1=R0 ;V02-006 PUSHAL HEADER_VALUE ;V02-006 PUSHAL HEADER_COUNT ;V02-006 CALLS #2,UPDATE_LOGICAL_NAME ;V02-006 PUSHL GROUP_COUNT ; READ IN BLOCK OF FILE HEADERS PUSHAL HEADER_SCAN_BUFFER PUSHL INDEXF_VBN CALLS #3,INDEXF_READ BLBS R0,1$ ;CHECK FOR EOF CMPL #1,GROUP_COUNT ;SEE IF ALREADY DROPPED DOWN BNEQ 2$ ;NO CALLS #0,UPDATE_DISK_DATA ;V02-004 MOVL #SS$_NORMAL,R0 ;SET UP EXIT-DONE SCANNING RET 2$: MOVL #1,GROUP_COUNT ;DROP NUMBER OF HEADERS TO ONE-JUST ;TO GET THE LAST ONES AT THE BOTTOM ;OF THE BARREL BRB HEADER_SCAN_LOOP ;AND GO TRY AGAIN 1$: ADDL2 GROUP_COUNT,INDEXF_VBN ;SET UP NEXT READ START LOC MOVAL HEADER_SCAN_BUFFER,R11 ;GET POINTER TO START OF FILE HEADER MOVL GROUP_COUNT,R10 ;COUNT OF FILE HEADERS IN GROUP HEADER_INNER_LOOP: ; CHECK TO SEE IF HEADER IS VALID (IN-USE) CLRL SCAN_HEADER_SIZE CLRL SCAN_HEADER_COUNT MOVL #-1,SCAN_HEADER_LBN ;V02-007 CLRL SCAN_HEADER_HIGH ;V02-015 MOVL R11,R0 CALLS #0,HEADER_VALID BLBS R0,1$ BRW END_HEADER_INNER_LOOP 1$: TSTW FH2$W_SEG_NUM(R11) ;SEE IF IT IS AN EXTENTION HEADER BNEQ 1001$ ;IF SO-SKIPP IT MOVL R11,R6 ;WORKING DUPLICATE OF LOC OF HEADER ; CHECK TO SEE IF IT IS A FILE STRUCTURE FILE (FID 1-9) TSTB FH2$B_FID_NMX(R11) BNEQ 1002$ ;V02-004 CMPW #9,FH2$W_FID(R11) BLSSU 1002$ ;V02-004 1001$: BRW END_HEADER_INNER_LOOP ; LETS GOT TO THE MAP 1002$: INCL FILE_COUNT ;V02-004 2$: ; GET OFFSET IN HEADER TO MAP MOVZBL FH2$B_MPOFFSET(R6),R9 MULL2 #2,R9 ADDL2 R6,R9 ; GET OFFSET TO NEXT BYTE TO BE USED IN MAP MOVZBL FH2$B_MAP_INUSE(R6),R8 BNEQ 8$ BRW 21$ ;SKIP IF NO POINTERS IN THIS HEADER 8$: MULL2 #2,R8 ADDL2 R9,R8 ; FORMAT-FIELDS EXTRACTION LOOP 3$: EXTZV #FM2$V_FORMAT,#FM2$S_FORMAT,(R9),R7 ;EXTRACT FORMAT NUMBER CMPB #FM2$C_PLACEMENT,R7 ;CHECK FOR PLACEMENT CONTROL BNEQ 4$ ;NOT PLACEMENT CONTROL ADDL2 #2,R9 ;IGNORE PLACEMENT CONTROL BRW 20$ ;PLACEMENT CONTROL-FORGET THIS ONE 4$: CMPB #FM2$C_FORMAT1,R7 ;IS IT FORMAT 1 BNEQ 5$ ;NO ; EXTRACT SIZE,UPDATE TOTAL FILE SIZE, BUMP FRAGMENT COUNT INCL POINTER_COUNT ;V02-004 MOVZBL FM2$B_COUNT1(R9),R0 INCL R0 ADDL2 R0,SCAN_HEADER_SIZE MOVZWL FM2$W_LOWLBN(R9),SCAN_HEADER_TEMP_LBN ;V02-007 EXTZV #FM2$V_HIGHLBN,#FM2$S_HIGHLBN,(R9),R2 ;V02-007 MOVW R2,SCAN_HEADER_TEMP_LBN+2 ;V02-007 CMPL SCAN_HEADER_TEMP_LBN,SCAN_HEADER_LBN ;V02-007 BGEQU 1004$ ;V02-007 MOVL SCAN_HEADER_TEMP_LBN,SCAN_HEADER_LBN ;V02-007 1004$: ;V02-007 ADDL2 R0,SCAN_HEADER_TEMP_LBN ;V02-015 DECL SCAN_HEADER_TEMP_LBN ;V02-015 CMPL SCAN_HEADER_TEMP_LBN,SCAN_HEADER_HIGH ;V02-015 BLEQU 2004$ ;V02-015 MOVL SCAN_HEADER_TEMP_LBN,SCAN_HEADER_HIGH ;V02-015 2004$: ;V02-015 INCL SCAN_HEADER_COUNT ADDL2 #4,R9 BRW 20$ 5$: CMPB #FM2$C_FORMAT2,R7 ;IS IT FORMAT 2 BNEQ 6$ ; EXTRACT SIZE,UPDATE TOTAL FILE SIZE, BUMP FRAGMENT COUNT INCL POINTER_COUNT ;V02-004 EXTZV #FM2$V_COUNT2,#FM2$S_COUNT2,(R9),R0 INCL R0 ADDL2 R0,SCAN_HEADER_SIZE INCL SCAN_HEADER_COUNT CMPL FM2$L_LBN2(R9),SCAN_HEADER_LBN ;V02-007 BGEQU 1005$ ;V02-007 MOVL FM2$L_LBN2(R9),SCAN_HEADER_LBN ;V02-007 1005$: ;V02-007 ADDL3 R0,FM2$L_LBN2(R9),SCAN_HEADER_TEMP_LBN ;V02-015 DECL SCAN_HEADER_TEMP_LBN ;V02-015 CMPL SCAN_HEADER_TEMP_LBN,SCAN_HEADER_HIGH ;V02-015 BLEQU 2005$ ;V02-015 MOVL SCAN_HEADER_TEMP_LBN,SCAN_HEADER_HIGH ;V02-015 2005$: ;V02-015 ADDL2 #6,R9 BRW 20$ 6$: CMPB #FM2$C_FORMAT3,R7 ;IS TI FORMAT 3 BNEQ 7$ ; EXTRACT SIZE,UPDATE TOTAL FILE SIZE, BUMP FRAGMENT COUNT INCL POINTER_COUNT ;V02-004 ROTL #16,(R9),R1 EXTZV #0,#30,R1,R0 INCL R0 ADDL2 R0,SCAN_HEADER_SIZE INCL SCAN_HEADER_COUNT CMPL FM2$L_LBN3(R9),SCAN_HEADER_LBN ;V02-007 BGEQU 1006$ ;V02-007 MOVL FM2$L_LBN3(R9),SCAN_HEADER_LBN ;V02-007 1006$: ;V02-007 ADDL3 R0,FM2$L_LBN3(R9),SCAN_HEADER_TEMP_LBN ;V02-015 DECL SCAN_HEADER_TEMP_LBN ;V02-015 CMPL SCAN_HEADER_TEMP_LBN,SCAN_HEADER_HIGH ;V02-015 BLEQU 2006$ ;V02-015 MOVL SCAN_HEADER_TEMP_LBN,SCAN_HEADER_HIGH ;V02-015 2006$: ;V02-015 ADDL2 #8,R9 BRW 20$ 7$: ; OOP'S-SHOULD NOT GET HERE BRW END_HEADER_INNER_LOOP 20$: CMPL R9,R8 ;SEE IF DONE WITH FILE HEADER SCAN BGEQU 21$ ;YES DONE BRW 3$ ;NO-GET NEXT POINTER 21$:; CHECK FOR EXTENTION HEADER TSTB FH2$B_EX_FIDNMX(R6) BNEQ 22$ TSTW FH2$W_EX_FIDNUM(R6) BNEQ 22$ BRW 50$ ;NO EXTENTION HEADER 22$: ; DO EXTENTION HEADER PROCESSING PUSHL #1 PUSHAL HEADER_EXTENTION_BUFFER MOVZBW FH2$B_EX_FIDNMX(R6),HEADER_EXTENTION_VBN+2 MOVW FH2$W_EX_FIDNUM(R6),HEADER_EXTENTION_VBN ADDL2 FILE_HEADER_VBN,HEADER_EXTENTION_VBN DECL HEADER_EXTENTION_VBN PUSHL HEADER_EXTENTION_VBN CALLS #3,INDEXF_READ BLBS R0,23$ BRW END_HEADER_INNER_LOOP ;ON ERROR-JUST FORGET THIS FILE ; SEE IF EXTENTION HEADER IS VALID 23$: MOVAL HEADER_EXTENTION_BUFFER,R0 CALLS #0,HEADER_VALID BLBS R0,24$ BRW END_HEADER_INNER_LOOP ;FORGET FILE WITH INVALID EXT HEADER 24$: MOVAL HEADER_EXTENTION_BUFFER,R6 BRW 2$ 50$: ; File entry will end up someware-build entry element ;V02-008 CALLS #0,ALLOCATE_ELEMENT ;V02-008 TSTL R0 ;SEE IF GO ONE ;V02-008 BNEQ 51$ ;V02-008 MOVL #SS$_INSFMEM,R0 ;BOMB OUT- NOT ENOUGH MEMORY ;V02-008 $EXIT_S R0 ;V02-008 51$: MOVL SCAN_HEADER_SIZE,FILE_ELEMENT_L_SIZE(R0) ;SIZE ;V02-008 MOVZBW FH2$B_FID_NMX(R11),FILE_ELEMENT_L_FID+2(R0) ;FID ;V02-008 MOVW FH2$W_FID_NUM(R11),FILE_ELEMENT_L_FID(R0) ;V02-008 MOVZWL FH2$W_FID_SEQ(R11),FILE_ELEMENT_L_SEQ(R0) ;SEQ ;V02-008 MOVL SCAN_HEADER_LBN,FILE_ELEMENT_L_LBN(R0) ;V02-008 MOVL SCAN_HEADER_COUNT,FILE_ELEMENT_L_FRAG(R0) ;V02-008 MOVL SCAN_HEADER_HIGH,FILE_ELEMENT_L_HIGH(R0) ;V02-015 ; Scan is done-see if file is available for use ;V02-008 MOVZBW FH2$B_FID_NMX(R11),HEADER_EXTENTION_VBN+2 ;V02-008 MOVW FH2$W_FID_NUM(R11),HEADER_EXTENTION_VBN ;V02-008 PUSHR #^M ;V02-010 PUSHL R11 ;V02-008 MOVZWL FH2$W_FID_SEQ(R11),R1 ;V02-008 PUSHL R1 ;V02-008 PUSHL HEADER_EXTENTION_VBN ;V02-008 CALLS #3,CHECK_LIST ;V02-009 BLBS R0,54$ ;V02-008 POPR #^M ;V02-010 CALLS #0,INSERT_REJECTED_QUEUE ;V02-010 BRW END_HEADER_INNER_LOOP ;CANT USE IT ;V02-008 54$: POPR #^M ;V02-010 TSTL SCAN_HEADER_SIZE ;CHECK FOR ZERO LENGTH ;V02-009 BNEQ 55$ ;V02-009 CALLS #0,INSERT_REJECTED_QUEUE ;V02-010 BRW END_HEADER_INNER_LOOP ;ZERO LENGTH FILE-SKIP IT ;V02-009 55$: ;V02-009 ; see if this is a directory file ;V02-008 BITL #FH2$M_DIRECTORY,FH2$L_FILECHAR(R11) ;V02-008 BEQL 52$ ;ITS A DIRECTORY FILE ;V02-008 CALLS #0,INSERT_DIR_QUEUE ;V02-008 BRW END_HEADER_INNER_LOOP ;V02-008 52$: ;V02-008 ; See if this a too large file ;V02-008 CMPL SCAN_HEADER_SIZE,FREE_BLOCKS ;V02-008 BLEQU 53$ ;V02-008 CALLS #0,INSERT_TOO_LARGE_QUEUE ;V02-008 BRW END_HEADER_INNER_LOOP ;V02-008 ; is this a contiguous file (one retrival pointer) ;V02-008 53$: CMPL #1,SCAN_HEADER_COUNT ;V02-008 BEQL 58$ ;CONTIG ;V02-008 BRW 100$ ;NOT CONTIGUOUS-CHECK ITS QUALS ;V02-008 ; file is contiguous-can go in CONTIG OR LARGE CONTIG QUEUES ;V02-008 58$: CMPL SCAN_HEADER_SIZE,LARGEST_FREE_FRAGMENT ;V02-008 BGTRU 59$ ;V02-008 CALLS #0,INSERT_CONTIG_QUEUE ;CONTIG FILE ;V02-008 .IIF DF,DEBUG2, INCL LIMIT_COUNT ;V02-008 BRW END_HEADER_INNER_LOOP ;V02-008 59$: CALLS #0,INSERT_LARGE_CONTIG_QUEUE ;V02-008 .IIF DF,DEBUG2, INCL LIMIT_COUNT ;V02-008 BRW END_HEADER_INNER_LOOP ;V02-008 100$: ; FRAGMENTED FILE-SEE IF COUNT OK-IF LESS THAN 10 PUT IN ;V02-008 ; CHECK SIZE TO SEE IF IT IS LARGE ;V02-008 CMPL SCAN_HEADER_SIZE,LARGEST_FREE_FRAGMENT ;V02-008 BLEQU 109$ ;V02-008 CALLS #0,INSERT_LARGE_FRAG_QUEUE ;LARGE FRAG FILE ;V02-008 .IIF DF,DEBUG2, INCL LIMIT_COUNT ;V02-008 BRW END_HEADER_INNER_LOOP ;V02-008 109$: CALLS #0,INSERT_FRAG_QUEUE ;V02-009 .IIF DF,DEBUG2, INCL LIMIT_COUNT ;V02-008 END_HEADER_INNER_LOOP: .IF DF,DEBUG2 CMPL #DEBUG2,LIMIT_COUNT BGTR 100$ CALLS #0,UPDATE_DISK_DATA MOVL #SS$_NORMAL,R0 ;SET UP EXIT-DONE SCANNING RET 100$: .ENDC DECL R10 BLEQ 1$ ADDL2 #512,R11 BRW HEADER_INNER_LOOP 1$: BRW HEADER_SCAN_LOOP .PAGE .SUBTITLE SCAN FILE HEADER SCRATCH DATA AREA .PSECT SCAN_HEADER_DATA,RD,WRT,NOEXE,NOSHR SCAN_HEADER_SIZE: .LONG 0 SCAN_HEADER_COUNT: .LONG 0 SCAN_HEADER_LBN: .LONG 0 ;V02-007 SCAN_HEADER_HIGH: .LONG 0 ;V02-015 SCAN_HEADER_TEMP_LBN: .LONG 0 ;V02-007 GROUP_COUNT: .LONG 0 INDEXF_VBN: .LONG 0 HEADER_EXTENTION_BUFFER:.BLKB 512 HEADER_EXTENTION_VBN: .LONG 0 HEADER_STATE: .ASCID /SCANNING_HEADERS/ ;V02-002 HEADER_STATUS: .ASCID /STATUS/ ;V02-002 .IIF DF,DEBUG2, LIMIT_COUNT: .LONG 0 .PSECT SCAN_HEADER_BUFFER,RD,WRT,NOEXE,NOSHR,LONG HEADER_SCAN_BUFFER: .BLKB <512*64> HEADER_COUNT: .ASCID /COUNT/ ;V02-006 HEADER_FAO: .ASCID /FID !XL%X / ;V02-006 HEADER_VALUE: .ASCID / / ;V02-006 HEADER_NUMBER: .LONG 0 ;V02-006 .PAGE .SUBTITLE SCAN HEADER WHOS ADDRESS IS IN R0 FOR VALIDITY .PSECT SCAN_HEADER_CODE,RD,NOWRT,EXE,SHR .ENTRY HEADER_VALID,^M ; ; Routine to scan header to see if it is valid ; ; Inputs: R0 address of header to check ; ; Outputs:R0 LSB=1 if header valid ; LSB=0 if header not valid ; MOVL R0,R3 CLRL R1 MOVL #,R2 6$: ADDW2 (R0)+,R1 SOBGTR R2,6$ CMPW R1,(R0) BEQL 7$ BRW 500$ ;BAD CHECKSUM 7$: CMPB FH2$B_STRUCLEV(R3),#2;CHECK STRUCTURE LEVEL BEQL 8$ BRW 500$ ;BAD STRUCTURE ; ; CHECK OFFSETS INTO HEADER ; 8$:; CMPB FH2$B_IDOFFSET(R3),# ; BLSSU 500$ CMPB FH2$B_MPOFFSET(R3),FH2$B_IDOFFSET(R3) BLSSU 500$ CMPB FH2$B_ACOFFSET(R3),FH2$B_MPOFFSET(R3) BLSSU 500$ CMPB FH2$B_RSOFFSET(R3),FH2$B_ACOFFSET(R3) BLSSU 500$ SUBB3 FH2$B_MPOFFSET(R3),FH2$B_ACOFFSET(R3),R0 CMPB FH2$B_MAP_INUSE(R3),R0 BGTRU 500$ ; ; SEE IF HEADER IN USE ; TSTW FH2$W_FID_NUM(R3) BNEQ 10$ TSTB FH2$B_FID_NMX(R3) BEQL 500$ 10$: MOVL #SS$_NORMAL,R0 RET 500$: MOVL #SS$_BADFILEHDR,R0 RET .PAGE .SUBTITLE SCAN DISK USEAGE BITMAP .PSECT SCAN_BITMAP_CODE,RD,NOWRT,EXE,SHR .ENTRY SCAN_BITMAP,^M ; ; Routine to scan the disk bitmap and build a data structure ; for each free fragment found ; ; Inputs: FREE_SPACE_BY_LBN_QUEUE ; FREE_SPACE_BY_SIZE_QUEUE ; file [000000]BITMAP.SYS ; CLUSTER_SIZE ; ; Outputs: ; FREE_SPACE_BY_LBN_QUEUE ; FREE_SPACE_BY_SIZE_QUEUE ; LARGEST_FREE_FRAGMENT ; FRAGMENT_COUNT ;V02-004 ; ; Juicer routines called: ; BITMAP_READ ; EMPTY_FREE_QUEUES ; FLUSH_BITMAP ; ALLOCATE_ELEMENT ; INSERT_FREE_QUEUES ; UPDATE_LOGICAL_NAME ;V02-002 ; UPDATE_DISK_DATA ;V02-004 ; PUSHAL BITMAP_STATE ;V02-002 PUSHAL BITMAP_STATUS ;V02-002 CALLS #2,UPDATE_LOGICAL_NAME ;V02-002 ; ; First flush info from last pass ; CALLS #0,EMPTY_FREE_QUEUES ; ; FORCE UPDATE THE ON DISK BITMAP TO CURRENT DATA ; CALLS #0,FLUSH_BITMAP ; ; SET UP INITIAL VALUES FOR SCANNING ; CLRL FRAGMENT_SIZE CLRL FRAGMENT_LBN CLRL CURRENT_LBN CLRL LARGEST_FREE_FRAGMENT CLRL FRAGMENT_COUNT ;V02-004 MOVL #16,BITMAP_COUNT MOVL #2,BITMAP_VBN ; INPUT FIRST SEGMENT OF DISK BITMAP 16 BLOCK SEGMENTS 3$: $FAO_S CTRSTR=BITMAP_FAO,- ;V02-006 OUTBUF=BITMAP_VALUE,- ;V02-006 P1=CURRENT_LBN ;V02-006 PUSHAL BITMAP_VALUE ;V02-006 PUSHAL BITMAP_COUNTL ;V02-006 CALLS #2,UPDATE_LOGICAL_NAME ;V02-006 PUSHL BITMAP_COUNT PUSHAL BITMAP_SCAN_BUFFER PUSHL BITMAP_VBN CALLS #3,BITMAP_READ BLBS R0,1$ ; ; IN CASE OF ERROR HERE TRY 1 BLOCK SEGMENTS ; CMPL #1,BITMAP_COUNT BNEQ 2$ ; ; ALREADY DROPPED TO 1 BLOCK-QUIT ; MOVL #RMS$_EOF,R0 $EXIT_S R0 2$: MOVL #1,BITMAP_COUNT BRB 3$ 1$: ADDL2 BITMAP_COUNT,BITMAP_VBN MOVAL BITMAP_SCAN_BUFFER,R11 ;POINTER INTO BITMAP MOVL #32,R8 ;BITS/WORD CLRL R6 ;OFFSET INTO BIT MASK ARRAY MOVL (R11)+,R9 ;GET FIRST BITMAP WORD MULL3 #512,BITMAP_COUNT,R10 ;SET UP END OF SCAN POINTER ADDL2 #BITMAP_SCAN_BUFFER,R10 ; ; START CHECK ; BITMAP_LOOP: BITL BIT_MAP[R6],R9 ;SEE IF BIT IS SET BEQL NOT_SET ;IF NOT SET-CLUSTER IS IN USE INCL FRAGMENT_SIZE TSTL FRAGMENT_LBN BNEQ 1$ MOVL CURRENT_LBN,FRAGMENT_LBN 1$: BRW END_LOOP NOT_SET: TSTL FRAGMENT_SIZE ;SEE IF THIS IS THE END OF A FRAGMENT BEQL END_LOOP INCL FRAGMENT_COUNT ;V02-004 MULL2 CLUSTER_SIZE,FRAGMENT_SIZE ;CONVERT FROM CLUSTERS TO BLOCKS ; CHECK AND UPDATE AS REQUIRED-SIZE OF LARGEST FREE FRAGMENT AVAILABLE CMPL FRAGMENT_SIZE,LARGEST_FREE_FRAGMENT BLEQ 1$ MOVL FRAGMENT_SIZE,LARGEST_FREE_FRAGMENT ; ALOCATE,BUILD AND ENTER ELEMENT FOR FREE SPACE FRAGMENT 1$: CALLS #0,ALLOCATE_ELEMENT TSTL R0 BNEQ 2$ MOVL #SS$_INSFMEM,R0 ;BOMB OUT- NOT ENOUGH MEMORY $EXIT_S R0 2$: MOVL FRAGMENT_SIZE,FREE_ELEMENT_L_SIZE(R0);LOAD SIZE IN BLOCKS MULL3 CLUSTER_SIZE,FRAGMENT_LBN,FREE_ELEMENT_L_LBN(R0);LOAD LBN CALLS #0,INSERT_FREE_QUEUES CLRL FRAGMENT_SIZE CLRL FRAGMENT_LBN END_LOOP: INCL CURRENT_LBN INCL R6 ;BUMP BITMAP POINTER DECL R8 BLEQ 12$ BRW BITMAP_LOOP 12$: CMPL R10,R11 ;SEE IF DONE WITH CURRENT BUFFER FULL YET BLEQU 3$ ;V02-006 BRW 1$ ;IF NOT-SKIP OVER NEXT ;V02-006 3$: $FAO_S CTRSTR=BITMAP_FAO,- ;V02-006 OUTBUF=BITMAP_VALUE,- ;V02-006 P1=CURRENT_LBN ;V02-006 PUSHAL BITMAP_VALUE ;V02-006 PUSHAL BITMAP_COUNTL ;V02-006 CALLS #2,UPDATE_LOGICAL_NAME ;V02-006 PUSHL BITMAP_COUNT PUSHAL BITMAP_SCAN_BUFFER PUSHL BITMAP_VBN CALLS #3,BITMAP_READ BLBS R0,11$ ; ; IN CASE OF ERROR HERE TRY 1 BLOCK SEGMENTS ; CMPL #1,BITMAP_COUNT BNEQ 2$ ; ; ALREADY DROPPED TO 1 BLOCK-DONE-SCAN ; BRW 100$ 2$: MOVL #1,BITMAP_COUNT BRB 3$ 11$: MOVAL BITMAP_SCAN_BUFFER,R11 MULL3 #512,BITMAP_COUNT,R10 ADDL2 #BITMAP_SCAN_BUFFER,R10 ADDL2 BITMAP_COUNT,BITMAP_VBN 1$: MOVL (R11)+,R9 CLRL R6 MOVL #32,R8 BRW BITMAP_LOOP 100$: ; SEE IF ONE LAST FRAGMENT TO LOG TSTL FRAGMENT_SIZE ;SEE IF THIS IS THE END OF A FRAGMENT BEQL 103$ INCL FRAGMENT_COUNT ;V02-004 MULL2 CLUSTER_SIZE,FRAGMENT_SIZE ;CONVERT FROM CLUSTERS TO BLOCKS ; CHECK AND UPDATE AS REQUIRED-SIZE OF LARGEST FREE FRAGMENT AVAILABLE CMPL FRAGMENT_SIZE,LARGEST_FREE_FRAGMENT BLEQ 101$ MOVL FRAGMENT_SIZE,LARGEST_FREE_FRAGMENT ; ALOCATE,BUILD AND ENTER ELEMENT FOR FREE SPACE FRAGMENT 101$: CALLS #0,ALLOCATE_ELEMENT TSTL R0 BNEQ 102$ MOVL #SS$_INSFMEM,R0 ;BOMB OUT- NOT ENOUGH MEMORY $EXIT_S R0 102$: MOVL FRAGMENT_SIZE,FREE_ELEMENT_L_SIZE(R0);LOAD SIZE IN BLOCKS MULL3 CLUSTER_SIZE,FRAGMENT_LBN,FREE_ELEMENT_L_LBN(R0);LOAD LBN CALLS #0,INSERT_FREE_QUEUES 103$: CALLS #0,UPDATE_DISK_DATA MOVL #SS$_NORMAL,R0 RET .PAGE .SUBTITLE SCAN_BITMAP DATA AREA .PSECT SCAN_BITMAP_DATA,RD,WRT,NOEXE,PAGE,NOSHR FRAGMENT_SIZE: .LONG 0 FRAGMENT_LBN: .LONG 0 CURRENT_LBN: .LONG 0 BITMAP_COUNT: .LONG 0 BITMAP_VBN: .LONG 0 BITMAP_SCAN_BUFFER: .BLKB <512*16> BITMAP_STATE: .ASCID /SCANNING_BITMAP/ ;V02-002 BITMAP_STATUS: .ASCID /STATUS/ ;V02-002 BITMAP_COUNTL: .ASCID /COUNT/ ;V02-006 BITMAP_FAO: .ASCID /Last LBN before refresh !XL%X/ ;V02-006 BITMAP_VALUE: .ASCID / / ;V02-006 BITMAP_NUMBER: .LONG 0 ;V02-006 ; ; MAP THE BITS IN EACH 32 BIT WORD ; BIT_MAP:.LONG ^X1,^X2,^X4,^X8,^X10,^X20,^X40,^X80,^X100,^X200,^X400,^X800 .LONG ^X1000,^X2000,^X4000,^X8000,^X10000,^X20000,^X40000,^X80000 .LONG ^X100000,^X200000,^X400000,^X800000 .LONG ^X1000000,^X2000000,^X4000000,^X8000000 .LONG ^X10000000,^X20000000,^X40000000,^X80000000 .PAGE .SUBTITLE ATTEMPT_FILE_DEFRAGMENT .PSECT FILE_DEFRAG_CODE,RD,NOWRT,EXE,SHR .ENTRY ATTEMPT_FILE_DEFRAGMENT,^M ; ; Procedure that scans the built up data structures, determines if ; any are eligable to be moved and atempts to do so. ; ; Inputs: LARGEST_FREE_FRAGMENT ; FREE_SPACE_BY_FILE_QUEUE ; FRAGMENTED_FILES_QUEUE ; HEAP ; ; Outputs: ; FREE_SPACE_BY_SIZE_QUEUE ; FRAGMENTED_FILES_QUEUE ; possable moved files on disk ; HEAP ; ; Juicer routines called: ; MOVE_FILE ; INSERT_FREE_QUEUES ; UPDATE_LOGICAL_NAME ;V02-002 ; INSERT_REJECTED_QUEUE ;V02-010 ; PUSHAL FILE_STATE ;V02-002 PUSHAL FILE_STATUS ;V02-002 CALLS #2,UPDATE_LOGICAL_NAME ;V02-002 CLRL FILE_FRAG_CNT ;V02-009 ; CHECK TO SEE IF EMPTY 1$: CMPL #FRAGMENTED_FILES_QUEUE,FRAGMENTED_FILES_QUEUE BNEQ 2$ MOVL #SS$_NORMAL,R0 ;EXIT ON EMPTY RET 2$: CMPL #10,FILE_FRAG_CNT ;V02-009 BGTRU 9$ ;V02-009 MOVL #SS$_NORMAL,R0 ;EXIT ON 10 FILES DONE ;V02-009 RET ;V02-009 ; Locate the most fragmented file in fragmented files queue ;V02-009 9$: MOVAL FRAGMENTED_FILES_QUEUE,R11 ;V02-009 MOVL R11,R10 ;V02-009 CLRL R9 ;V02-009 4$: MOVL (R10),R10 ;V02-009 CMPL R10,R11 ;V02-009 BEQL 6$ ;V02-009 CMPL FILE_ELEMENT_L_FRAG(R10),R9 ;V02-009 BLEQ 4$ ;V02-009 MOVL FILE_ELEMENT_L_FRAG(R10),R9 ;V02-009 MOVL R10,R8 ;V02-009 BRB 4$ ;V02-009 6$: TSTL R9 ;V02-009 BNEQ 7$ ;V02-009 MOVL #SS$_NORMAL,R0 ;EXIT ON ZIP ;V02-009 RET ;V02-009 7$: REMQUE (R8),R11 ;V02-009 ; SCAN THE LIST OF FREE FRAGMENTS LOOKING FOR ; EITHER EXACT SIZE MATCH OR BEST FIT GT SIZE MOVAL FREE_SPACE_BY_SIZE_QUEUE,R10 MOVL (R10),R9 3$: CMPL R9,R10 BNEQ 10$ ; SCANNED FREE LIST WITH NO MATCH-DUMP THIS FILE INFO AND TRY AGAIN INSQUE (R11),HEAP BRB 1$ 10$: CMPL FILE_ELEMENT_L_SIZE(R11),- ;V02-008 (R9) BLEQU 11$ ;FOUND USEABLE-GO DO IT MOVL (R9),R9 BRB 3$ ;NOPE-TRY NEXT 11$: $FAO_S CTRSTR=FILE_FAO,- ;V02-006 OUTBUF=FILE_VALUE,- ;V02-006 P1=FILE_FRAG_CNT ;V02-009 PUSHAL FILE_VALUE ;V02-006 PUSHAL FILE_COUNTL ;V02-006 CALLS #2,UPDATE_LOGICAL_NAME ;V02-006 PUSHL #0 ;V02-016 PUSHL FILE_ELEMENT_L_LBN(R11) ;V02-010 PUSHL FILE_ELEMENT_L_SEQ(R11) ;V02-008 SUBL3 #1,- ;V02-001 (R9),- ;V02-001 -(SP) ;V02-001 PUSHL FILE_ELEMENT_L_FID(R11) ;V02-008 CALLS #5,MOVE_FILE ;V02-016 BLBC R0,14$ ;V02-010 INCL FILE_FRAG_CNT ;V02-009 REMQUE (R9),R9 SUBL2 #FREE_ELEMENT_Q_SIZE_LINK,R9 REMQUE (R9),R0 ADDL2 FILE_ELEMENT_L_SIZE(R11),FREE_ELEMENT_L_LBN(R0) ;V02-008 SUBL2 FILE_ELEMENT_L_SIZE(R11),FREE_ELEMENT_L_SIZE(R0) ;V02-008 BNEQ 13$ INSQUE (R0),HEAP BRW 12$ 13$: CALLS #0,INSERT_FREE_QUEUES 12$: INSQUE (R11),HEAP BRW 1$ 14$: MOVL R11,R0 ;V02-010 CALLS #0,INSERT_REJECTED_QUEUE ;V02-010 BRW 1$ ;V02-010 .PAGE ;V02-002 .SUBTITLE ATTEMPT_FILE_DEFRAGMENT DATA ;V02-002 .PSECT FILE_DEFRAG_DATA,RD,WRT,NOEXE,NOSHR ;V02-002 FILE_STATE: .ASCID /DEFRAG_FILES/ ;V02-002 FILE_STATUS: .ASCID /STATUS/ ;V02-002 FILE_COUNTL: .ASCID /COUNT/ ;V02-006 FILE_FAO: .ASCID /Files completed !UL / ;V02-009 FILE_VALUE: .ASCID / / ;V02-006 FILE_FRAG_CNT: .LONG 0 ;V02-009 .PAGE .SUBTITLE ATTEMPT_DISK_DEFRAGMENT .PSECT DISK_DEFRAG_CODE,RD,NOWRT,EXE,SHR .ENTRY ATTEMPT_DISK_DEFRAGMENT,^M ; ; Procedure that scans the built up data structures, determines if ; any are eligable to be moved and atempts to do so. ; ; Inputs: LARGEST_FREE_FRAGMENT ; FREE_SPACE_BY_LBN_QUEUE ; CONTIGUOUS_FILES_QUEUE ; FRAGMENTED_FILES_QUEUE ;V02-009 ; HEAP ; ; Outputs: ; FREE_SPACE_BY_FILE_QUEUE ; CONTIGUOUS_FILES_QUEUE ; FRAGMENTED_FILES_QUEUE ;V02-009 ; HEAP ; possable moved files on disk ; ; Juicer routines called: ; MOVE_FILE ; INSERT_FREE_QUEUES ; UPDATE_LOGICAL_NAME ;V02-002 ; INSERT_REJECTED_QUEUE ;V02-010 ; PUSHAL DISK_STATE ;V02-002 PUSHAL DISK_STATUS ;V02-002 CALLS #2,UPDATE_LOGICAL_NAME ;V02-002 ; START AT LOW END OF THE DISK AND START UP MOVAL FREE_SPACE_BY_LBN_QUEUE,R11 MOVL (R11),R10 1$: CMPL R10,R11 ;CHECK FOR EMPTY/DONE BNEQ 52$ ;V02-007 MOVL #SS$_NORMAL,R0 RET .PAGE ;V02-007 ; ;V02-007 ; First scan the FRAGMENTED_FILES_QUEUE for candidate files ;V02-009 ; that have a lowest LBN higher than LBN of starting location ;V02-007 ; of empty frag and is the same size or smaller than the frag ;V02-007 ; ;V02-007 52$: MOVAL FRAGMENTED_FILES_QUEUE,R9 ;V02-009 MOVL 4(R9),R8 ;V02-007 CLRL R7 ;SET UP POINTER TO BEST FIND SO FAR ;V02-007 53$: CMPL R8,R9 ;CHECK FOR EMPTY/DONE ;V02-007 BNEQ 54$ ;V02-007 TSTL R7 ;V02-007 BNEQ 70$ ;GO TAKE BEST FIT ;V02-007 ; NO MATCH FOUND-GO CHECK CONTIG ELEMENTS ;V02-007 BRW 2$ ;V02-007 54$: CMPL FILE_ELEMENT_L_LBN(R8),FREE_ELEMENT_L_LBN(R10) ;V02-008 BGTRU 55$ ;V02-007 TSTL R7 ;V02-007 BNEQ 70$ ;GO TAKE BEST FIT ;V02-007 ; BACKED UP TO LBN'S BELOW TARGET-TRY CONTIG ELEMENTS ;V02-007 BRW 2$ ;V02-007 55$: CMPL FILE_ELEMENT_L_SIZE(R8),FREE_ELEMENT_L_SIZE(R10) ;V02-008 BEQL 65$ ;EXACT MATCH FOUND ;V02-007 BGTRU 56$ ;TO BIG ;V02-007 ; PROSPECT IS TO SMALL-SEE IF FIRST BEST FIT CANDIDATE ;V02-007 TSTL R7 ;V02-007 BNEQ 57$ ;NOT FIRST ;V02-007 MOVL R8,R7 ;MAKE BEST FIT CANDIDATE ;V02-007 BRB 56$ ;V02-007 57$: CMPL FILE_ELEMENT_L_SIZE(R8),FILE_ELEMENT_L_SIZE(R7) ;V02-008 BLEQ 56$ ;V02-009 MOVL R8,R7 ;V02-007 56$: MOVL 4(R8),R8 ;BACKUP AND TRY NEXT ;V02-007 BRW 53$ ;V02-007 .PAGE ;V02-007 ; EXACT MATCH ;V02-007 65$: MOVL R8,R7 ;IS ALSO BEST FIT ;V02-007 70$: $FAO_S CTRSTR=DISK_COUNT_FAO,- ;V02-007 OUTBUF=DISK_COUNT_VAL,- ;V02-007 P1=FREE_ELEMENT_L_LBN(R10) ;V02-007 PUSHAL DISK_COUNT_VAL ;V02-007 PUSHAL DISK_COUNT ;V02-007 CALLS #2,UPDATE_LOGICAL_NAME ;V02-007 PUSHL #0 ;V02-016 PUSHL FILE_ELEMENT_L_LBN(R7) ;V02-010 PUSHL FILE_ELEMENT_L_SEQ(R7) ;V02-008 SUBL3 #1,FREE_ELEMENT_L_LBN(R10),-(SP) ;V02-007 PUSHL FILE_ELEMENT_L_FID(R7) ;V02-008 CALLS #5,MOVE_FILE ;V02-016 BLBC R0,75$ ;V02-010 MOVL (R10),R2 ;GET NEXT ELEMENT AS PART OF UPDATE ;V02-007 REMQUE (R10),R0 ;V02-007 ADDL3 #FREE_ELEMENT_Q_SIZE_LINK,R0,R3 ;V02-007 REMQUE (R3),R3 ;V02-007 ADDL2 FILE_ELEMENT_L_SIZE(R11),FREE_ELEMENT_L_LBN(R0) ;V02-008 SUBL2 FILE_ELEMENT_L_SIZE(R7),FREE_ELEMENT_L_SIZE(R0) ;V02-008 BNEQ 73$ ;V02-007 INSQUE (R0),HEAP ;V02-007 MOVL 4(R2),R10 ;RESET SCANNER POINTER BACK ONE ;V02-007 BRW 72$ ;V02-007 73$: CALLS #0,INSERT_FREE_QUEUES ;V02-007 MOVL 4(R2),R10 ;RESET SCANNER POINTER BACK ONE ;V02-007 MOVL 4(R10),R10 ;RESET SCANNER POINTER BACK ONE MORE ;V02-007 72$: REMQUE (R7),R7 ;DUMP THE FILE INFO ;V02-007 INSQUE (R7),HEAP ;V02-007 MOVL (R10),R10 ;V02-007 BRW 1$ ;V02-007 75$: REMQUE (R7),R0 ;V02-010 CALLS #0,INSERT_REJECTED_QUEUE ;V02-010 BRW 1$ ;V02-010 .PAGE ;V02-007 ; ;V02-007 ; If no candiate found above-then continue search ;V02-007 ; then scan the CONTIGUOUS_FILES_QUEUE for candidate files ;V02-007 ; that have a starting LBN higher than LBN of starting location ;V02-007 ; of empty frag and is the same size or smaller than the frag ;V02-007 ; ;V02-007 2$: ; SET UP SCAN (FROM HIGH LBN TO LOW FOR CONTIG FILE ; WITH LBN HIGHER THAN TARGET LOC AND SIZE .LE. TARGET FREE FRAG MOVAL CONTIGUOUS_FILES_QUEUE,R9 MOVL 4(R9),R8 CLRL R7 ;SET UP POINTER TO BEST FIND SO FAR 3$: CMPL R8,R9 ;CHECK FOR EMPTY/DONE BNEQ 4$ TSTL R7 BNEQ 20$ ;GO TAKE BEST FIT ; NO MATCH FOUND-GO DO NEXT FRAGMENT MOVL (R10),R10 BRW 1$ 4$: CMPL FILE_ELEMENT_L_LBN(R8),FREE_ELEMENT_L_LBN(R10) ;V02-008 BGTRU 5$ TSTL R7 BNEQ 20$ ;GO TAKE BEST FIT ; BACKED UP TO LBN'S BELOW TARGET-GO TO NEXT EMPTY FRAG MOVL (R10),R10 BRW 1$ 5$: CMPL FILE_ELEMENT_L_SIZE(R8),FREE_ELEMENT_L_SIZE(R10) ;V02-008 BEQL 15$ ;EXACT MATCH FOUND BGTRU 6$ ;TO BIG ; PROSPECT IS TO SMALL-SEE IF FIRST BEST FIT CANDIDATE TSTL R7 BNEQ 7$ ;NOT FIRST MOVL R8,R7 ;MAKE BEST FIT CANDIDATE BRB 6$ 7$: CMPL FILE_ELEMENT_L_SIZE(R8),FILE_ELEMENT_L_SIZE(R7) ;V02-008 BLEQ 6$ ;V02-009 MOVL R8,R7 6$: MOVL 4(R8),R8 ;BACKUP AND TRY NEXT BRW 3$ .PAGE ;V02-007 ; EXACT MATCH 15$: MOVL R8,R7 ;IS ALSO BEST FIT 20$: $FAO_S CTRSTR=DISK_COUNT_FAO,- ;V02-006 OUTBUF=DISK_COUNT_VAL,- ;V02-006 P1=FREE_ELEMENT_L_LBN(R10) ;V02-006 PUSHAL DISK_COUNT_VAL ;V02-006 PUSHAL DISK_COUNT ;V02-006 CALLS #2,UPDATE_LOGICAL_NAME ;V02-006 PUSHL #0 ;V02-016 PUSHL FILE_ELEMENT_L_LBN(R7) ;V02-010 PUSHL FILE_ELEMENT_L_SEQ(R7) ;V02-008 SUBL3 #1,FREE_ELEMENT_L_LBN(R10),-(SP) ;V02-001 PUSHL FILE_ELEMENT_L_FID(R7) ;V02-008 CALLS #5,MOVE_FILE ;V02-016 BLBC R0,22$ MOVL (R10),R2 ;GET NEXT ELEMENT AS PART OF UPDATE REMQUE (R10),R0 ADDL3 #FREE_ELEMENT_Q_SIZE_LINK,R0,R3 REMQUE (R3),R3 ADDL2 FILE_ELEMENT_L_SIZE(R11),FREE_ELEMENT_L_LBN(R0) ;V02-008 SUBL2 FILE_ELEMENT_L_SIZE(R7),FREE_ELEMENT_L_SIZE(R0) ;V02-008 BNEQ 23$ INSQUE (R0),HEAP MOVL 4(R2),R10 ;RESET SCANNER POINTER BACK ONE BRW 22$ 23$: CALLS #0,INSERT_FREE_QUEUES MOVL 4(R2),R10 ;RESET SCANNER POINTER BACK ONE MOVL 4(R10),R10 ;RESET SCANNER POINTER BACK ONE MORE 22$: REMQUE (R7),R7 ;DUMP THE FILE INFO INSQUE (R7),HEAP MOVL (R10),R10 BRW 1$ .PAGE ;V02-002 .SUBTITLE ATTEMPT_DISK_DEFRAGMENT DATA ;V02-002 .PSECT DISK_DEFRAG_DATA,RD,WRT,NOEXE,NOSHR ;V02-002 DISK_STATE: .ASCID /DEFRAG_DISK/ ;V02-002 DISK_STATUS: .ASCID /STATUS/ ;V02-002 DISK_COUNT: .ASCID /COUNT/ ;V02-006 DISK_COUNT_VAL: .ASCID / / ;V02-006 DISK_COUNT_FAO: .ASCID /Starting LBN !XL%X/ ;V02-006 .PAGE ;V02-016 .SUBTITLE FORCE FILE MOVE ;V02-016 .PSECT FORCE_FILE_CODE,RD,NOWRT,EXE,SHR ;V02-016 .ENTRY FORCE_FILE_MOVE,^M ;V02-016 ; ;V02-016 ; Procedure that scans the too large queues for the file with ;V02-016 ; the highest high LBN and forces it to the low end of disk ;V02-016 ; without reguard to the fragmentation ;V02-016 ; ;V02-016 ; Inputs: LARGE_CONTIG_FILES_QUEUE ;V02-016 ; LARGE_FRAG_FILES_QUEUE ;V02-016 ; ;V02-016 ; Outputs: ;V02-016 ; LARGE_CONTIG_FILES_QUEUE ;V02-016 ; LARGE_FRAG_FILES_QUEUE ;V02-016 ; HEAP ;V02-016 ; REJECTED_FILES_QUEUE ;V02-016 ; possable moved files on disk ;V02-016 ; ;V02-016 ; Juicer routines called: ;V02-016 ; MOVE_FILE ;V02-016 ; UPDATE_LOGICAL_NAME ;V02-016 ; INSERT_REJECTED_QUEUE ;V02-016 ; FLUSH_BITMAP ;V02-016 ; ;V02-016 PUSHAL FORCE_STATE ;V02-016 PUSHAL FORCE_STATUS ;V02-016 CALLS #2,UPDATE_LOGICAL_NAME ;V02-016 ; START WITH THE LARGE FRAGMENTED FILES QUEUE LOOKING FOR ;V02-016 ; THE HIGHEST HIGH LBN ;V02-016 ; RETRY-LOOP BACK POINT ;V02-016 15$: CLRL R11 ;POINTER TO HIGH LBN FILE ENTRY ;V02-016 MOVAL LARGE_FRAG_FILES_QUEUE,R10 ;V02-016 MOVL R10,R9 ;WORK WITH COPY OF POINTER ;V02-016 1$: MOVL (R9),R9 ;GET NEXT ENTRY ;V02-016 CMPL R9,R10 ;SEE IF DONE ;V02-016 BEQL 2$ ;YES ;V02-016 CMPL FILE_ELEMENT_L_HIGH(R9),R11 ;FIND HIGHEST ;V02-016 BLEQU 1$ ;V02-016 MOVL FILE_ELEMENT_L_HIGH(R9),R11 ;V02-016 MOVL R9,R8 ;V02-017 BRB 1$ ;V02-016 2$: ;NOW SCAN THE LARGE CONTIG FILES QUEUE ;V02-016 MOVAL LARGE_CONTIG_FILES_QUEUE,R10 ;V02-016 MOVL R10,R9 ;V02-016 3$: MOVL (R9),R9 ;GET NEXT ENTRY ;V02-016 CMPL R9,R10 ;SEE IF DONE ;V02-016 BEQL 4$ ;YES ;V02-016 CMPL FILE_ELEMENT_L_HIGH(R9),R11 ;FIND HIGHEST ;V02-016 BLEQU 3$ ;V02-016 MOVL FILE_ELEMENT_L_HIGH(R9),R11 ;V02-016 MOVL R9,R8 ;V02-017 BRB 3$ ;V02-016 4$: ;NOW SEE IF WE GOT ANYTHING ;V02-016 TSTL R11 ;V02-016 BNEQ 5$ ;V02-016 ; IF NO FILES FOUND-THEN JUST QUIETLY EXIT ;V02-016 MOVL #SS$_NORMAL,R0 ;V02-016 RET ;V02-016 .PAGE ;V02-016 5$: MOVL R8,R7 ;V02-017 CALLS #0,FLUSH_BITMAP ;V02-016 PUSHL #MOVE_FILE_FLAG_NOCBT ;V02-016 PUSHL FILE_ELEMENT_L_LBN(R7) ;V02-016 PUSHL FILE_ELEMENT_L_SEQ(R7) ;V02-016 PUSHL #0 ;V02-016 PUSHL FILE_ELEMENT_L_FID(R7) ;V02-016 CALLS #5,MOVE_FILE ;V02-016 BLBC R0,75$ ;V02-016 REMQUE (R7),R0 ;V02-016 INSQUE (R0),HEAP ;V02-016 MOVL #SS$_NORMAL,R0 ;V02-016 RET ;V02-016 75$: REMQUE (R7),R0 ;V02-016 CALLS #0,INSERT_REJECTED_QUEUE ;V02-016 BRW 15$ ;V02-016 .PAGE ;V02-016 .SUBTITLE FORCE FILE MOVE DATA DATA ;V02-016 .PSECT FORCE_FILE_DATA,RD,WRT,NOEXE,NOSHR ;V02-016 FORCE_STATE: .ASCID /FORCE FILE MOVE/ ;V02-016 FORCE_STATUS: .ASCID /STATUS/ ;V02-016 .PAGE .SUBTITLE DEBUG AND DUMP DATA TO FILE ROUTINES ;V02-010 .PSECT DEBUG_CODE,RD,NOWRT,EXE,NOSHR ; ;V02-010 ; Macro to set up call to common file queue's dump routine ;V02-010 ; ;V02-010 .MACRO DUMP NAME,INTRO,QUEUE ;V02-010 .ENTRY DUMP_'NAME',^M ;V02-010 PUSHAL 'QUEUE'_FILES_QUEUE ;V02-010 PUSHAL 'INTRO'_INTRO ;V02-010 PUSHL #0 ;V02-010 CALLS #3,DUMP_COMMON_FILES ;V02-010 RET ;V02-010 .ENDM DUMP ;V02-010 DUMP CONTIG,CONTIG,CONTIGUOUS ;V02-010 DUMP DIR,DIR,DIRECTORY ;V02-010 DUMP FRAG,FRAG,FRAGMENTED ;V02-010 DUMP LARGE_FRAG,LARGE_FRAG,LARGE_FRAG ;V02-010 DUMP LARGE_CONTIG,LARGE_CONTIG,LARGE_CONTIG ;V02-010 DUMP TOO_LARGE,TOO_LARGE,TOO_LARGE ;V02-010 DUMP REJECTED,REJECTED,REJECTED ;V02-010 .PAGE ;V02-010 .SUBTITLE COMMON FILE QUEUE DUMP ROUTINE ;V02-010 .ENTRY DUMP_COMMON_FILES,^M ;V02-008 ; ;V02-010 ; Common file queues dump and output routine ;V02-010 ; ;V02-010 ; Inputs: ;V02-010 ; (AP) 3 ;V02-010 ; 4(AP) pointer to RAB or 0 if output to sys$output ;V02-010 ; 8(AP) Pointer to descripter of intro ;V02-010 ; 12(AP) Pointer to head of queue to dump ;V02-010 ; ;V02-010 MOVL 4(AP),R8 ;V02-010 TSTL R8 ;V02-010 BNEQ 10$ ;V02-010 PUSHL 8(AP) ;V02-010 CALLS #1,G^LIB$PUT_OUTPUT ;V02-010 BRW 11$ ;V02-010 10$: MOVL 8(AP),R0 ;V02-010 MOVW (R0),RAB$W_RSZ(R8) ;V02-010 MOVL 4(R0),RAB$L_RBF(R8) ;V02-010 $PUT RAB=R8 ;V02-010 11$: MOVL 12(AP),R11 ;V02-010 MOVL (R11),R10 ;V02-008 2$: CMPL R10,R11 ;V02-008 BNEQ 1$ ;V02-008 RET ;V02-008 1$: PUSHL FILE_ELEMENT_L_SEQ(R10) ;V02-008 PUSHAL NAME_LENGTH ;V02-008 PUSHAL NAME_STRING ;V02-008 PUSHL FILE_ELEMENT_L_FID(R10) ;V02-008 CALLS #4,BUILD_FILE_NAME ;V02-008 MOVL NAME_LENGTH,DUMP_PARAM_LIST ;V02-008 MOVAL NAME_TEXT,DUMP_PARAM_LIST+4 ;V02-008 MOVL FILE_ELEMENT_L_FID(R10),DUMP_PARAM_LIST+8 ;V02-008 MOVL FILE_ELEMENT_L_SEQ(R10),DUMP_PARAM_LIST+12 ;V02-008 MOVL FILE_ELEMENT_L_SIZE(R10),DUMP_PARAM_LIST+16 ;V02-008 MOVL FILE_ELEMENT_L_FRAG(R10),DUMP_PARAM_LIST+20 ;V02-008 MOVL FILE_ELEMENT_L_LBN(R10),DUMP_PARAM_LIST+24 ;V02-008 MOVL FILE_ELEMENT_L_HIGH(R10),DUMP_PARAM_LIST+28 ;V02-015 $FAOL_S CTRSTR=DUMP_FILE_FAO_CTR,- ;V02-008 OUTBUF=DUMP_OUTBUF,- ;V02-008 OUTLEN=DUMP_OUTLEN,- ;V02-008 PRMLST=DUMP_PARAM_LIST ;V02-008 TSTL R8 ;V02-010 BNEQ 12$ ;V02-010 PUSHAL DUMP_OUTLEN ;V02-008 CALLS #1,G^LIB$PUT_OUTPUT ;V02-008 BRW 13$ ;V02-010 12$: MOVW DUMP_OUTLEN,RAB$W_RSZ(R8) ;V02-010 MOVL DUMP_OUTLEN+4,RAB$L_RBF(R8) ;V02-010 $PUT RAB=R8 ;V02-010 13$: ;V02-010 MOVL (R10),R9 ;V02-008 CMPL 4(R9),R10 ;V02-008 BEQL 3$ ;V02-008 TSTL R8 ;V02-010 BNEQ 14$ ;V02-010 PUSHAL BAD_BACK ;V02-008 CALLS #1,G^LIB$PUT_OUTPUT ;V02-008 BRW 15$ ;V02-010 14$: MOVW BAD_BACK,RAB$W_RSZ(R8) ;V02-010 MOVL BAD_BACK+4,RAB$L_RBF(R8) ;V02-010 $PUT RAB=R8 ;V02-010 15$: ;V02-010 MOVL R10,R0 ;V02-008 RET ;V02-008 3$: MOVL R9,R10 ;V02-008 BRW 2$ ;V02-008 .PAGE ;V02-010 .SUBTITLE DUMP FREE FRAG DATA TO TERMINAL ;V02-010 .ENTRY DUMP_FREE_LBN,^M PUSHAL FREE_LBN_INTRO CALLS #1,G^LIB$PUT_OUTPUT MOVAL FREE_SPACE_BY_LBN_QUEUE,R11 MOVL (R11),R10 2$: CMPL R10,R11 BNEQ 1$ RET 1$: MOVL FREE_ELEMENT_L_LBN(R10),DUMP_PARAM_LIST MOVL FREE_ELEMENT_L_SIZE(R10),DUMP_PARAM_LIST+4 $FAOL_S CTRSTR=DUMP_FL_FAO_CTR,- OUTBUF=DUMP_OUTBUF,- OUTLEN=DUMP_OUTLEN,- PRMLST=DUMP_PARAM_LIST PUSHAL DUMP_OUTLEN CALLS #1,G^LIB$PUT_OUTPUT MOVL (R10),R9 CMPL 4(R9),R10 BEQL 3$ PUSHAL BAD_BACK CALLS #1,G^LIB$PUT_OUTPUT MOVL R10,R0 RET 3$: MOVL R9,R10 BRW 2$ .ENTRY DUMP_FREE_SIZE,^M PUSHAL FREE_SIZE_INTRO CALLS #1,G^LIB$PUT_OUTPUT MOVAL FREE_SPACE_BY_SIZE_QUEUE,R11 MOVL (R11),R10 2$: CMPL R10,R11 BNEQ 1$ RET 1$: MOVL (R10),- DUMP_PARAM_LIST MOVL (R10),- DUMP_PARAM_LIST+4 $FAOL_S CTRSTR=DUMP_FL_FAO_CTR,- OUTBUF=DUMP_OUTBUF,- OUTLEN=DUMP_OUTLEN,- PRMLST=DUMP_PARAM_LIST PUSHAL DUMP_OUTLEN CALLS #1,G^LIB$PUT_OUTPUT MOVL (R10),R9 CMPL 4(R9),R10 BEQL 3$ PUSHAL BAD_BACK CALLS #1,G^LIB$PUT_OUTPUT MOVL R10,R0 RET 3$: MOVL R9,R10 BRW 2$ .ENTRY DUMP_DIR_TABLE,^M PUSHAL L^DIR_TABLE_INTRO CALLS #1,G^LIB$PUT_OUTPUT MOVAL L^DIR_TABLE,R11 MOVL CURRENT_DIR_ENTRY,R10 BNEQ 1$ RET 1$: MOVL DIR_L_FID(R11),DUMP_PARAM_LIST MOVL DIR_L_NXT_FID(R11),DUMP_PARAM_LIST+4 MOVZBL DIR_B_CNT(R11),DUMP_PARAM_LIST+8 MOVAL DIR_T_NAME(R11),DUMP_PARAM_LIST+12 $FAOL_S CTRSTR=DUMP_DT_FAO_CTR,- OUTBUF=DUMP_OUTBUF,- OUTLEN=DUMP_OUTLEN,- PRMLST=DUMP_PARAM_LIST PUSHAL DUMP_OUTLEN CALLS #1,G^LIB$PUT_OUTPUT ADDL2 #DIR_LENGTH,R11 DECL R10 BGTR 1$ RET .PAGE .SUBTITLE DEBUG DATA .PSECT DEBUG_DATA,RD,WRT,NOEXE,NOSHR CONTIG_INTRO: .ASCID /Dump of list of contiguous files / DIR_INTRO: .ASCID /Dump of list of directory files / DIR_TABLE_INTRO: .ASCID /Dump of directory table/ FRAG_INTRO: .ASCID /Dump of list of fragmented files/ FREE_LBN_INTRO: .ASCID /Dump of free fragments by LBN/ FREE_SIZE_INTRO: .ASCID /Dump of free fragments by size/ LARGE_FRAG_INTRO: ;V02-008 .ASCID /Dump of large frag files queue/ ;V02-008 LARGE_CONTIG_INTRO: ;V02-008 .ASCID /Dump of large contig files queue/ ;V02-008 TOO_LARGE_INTRO: ;V02-008 .ASCID /Dump of too large files/ ;V02-008 REJECTED_INTRO: ;V02-010 .ASCID /Dump of rejected files/ ;V02-010 BAD_BACK: .ASCID /Next element has bad back pointer/ NAME_LENGTH: .LONG 0 NAME_STRING: .LONG 4096 .ADDRESS NAME_TEXT NAME_TEXT: .BLKB 4096 DUMP_FILE_FAO_CTR: ;V02-008 .ASCID ?!/!AD !/ FID !XL%X SEQ !XL%X ?- ;V02-008 ?Size !ZL%D Frags !ZL%D LOW LBN !XL%X?- ;V02-016 ? Hi LBN !XL%X? ;V02-016 DUMP_FL_FAO_CTR:.ASCID ?LBN !XL%X Size !ZL%D? DUMP_DT_FAO_CTR:.ASCID ?FID !XL%X NXT FID !XL%X !AD? DUMP_OUTLEN: .LONG 0 .ADDRESS DUMP_TEXT DUMP_OUTBUF: .LONG 4300 .ADDRESS DUMP_TEXT DUMP_TEXT: .BLKB 4300 DUMP_PARAM_LIST: .LONG 0,0,0,0,0,0,0,0,0,0,0,0 ;V02-015 .PAGE ;V02-010 .SUBTITLE CHECK LOGICAL TABLE AND DUMP AS REQUIRED ;V02-010 ; ;V02-010 ; Defined by a macro, these routines check for the specific ;V02-010 ; logial symbol to be defined and if it is (value being the ;V02-010 ; file name to dump to) dump entries in corresponding queue ;V02-010 ; ;V02-010 ; Inputs: ;V02-010 ; Value of logical in system logical table ;V02-010 ; JUICER_2_devicename_tablename ;V02-010 ; tablename= CONTIG ;V02-010 ; LARGE_CONTIG ;V02-010 ; FRAG ;V02-010 ; LARGE_FRAG ;V02-010 ; TOO_LARGE ;V02-010 ; REJECTED ;V02-010 ; ;V02-010 ; Outputs: ;V02-010 ; Logical name in table is deleted ;V02-010 ; contents of corresponding queue dumped to file ;V02-010 ; ;V02-010 .MACRO FILE QUEUE,INTRO,LOGICAL,?A,?B ;V02-010 .PSECT DUMP_TO_FILE_CODE,RD,NOWRT,EXE,SHR ;V02-010 .PSECT DUMP_TO_FILE_DATA,RD,WRT,NOEXE,NOSHR,LONG ;V02-010 QUEUE_NAME_'LOGICAL': .ASCID /Q_'LOGICAL'/ ;V02-010 .PSECT DUMP_TO_FILE_CODE ;V02-010 .ENTRY CHECK_FILE_DUMP_'LOGICAL',^M ;V02-010 PUSHAL LOGICAL_VALUE ;V02-010 PUSHAL QUEUE_NAME_'LOGICAL' ;V02-010 CALLS #2,GET_LOGICAL_NAME ;V02-010 BLBS R0,A ;V02-010 MOVL #1,R0 ;V02-013 RET ;V02-010 A: PUSHAL QUEUE_NAME_'LOGICAL' ;V02-010 CALLS #1,DELETE_LOGICAL_NAME ;V02-010 BLBC R0,B ;V02-010 CALLS #0,OPEN_DUMP_FILE ;V02-010 BLBC R0,B ;V02-010 PUSHAL QUEUE ;V02-010 PUSHAL INTRO ;V02-010 PUSHAL DUMP_RAB ;V02-010 CALLS #3,DUMP_COMMON_FILES ;V02-010 CALLS #0,CLOSE_DUMP_FILE ;V02-010 BLBC R0,B ;V02-010 RET ;V02-010 B: $EXIT_S R0 ;V02-010 .ENDM FILE ;V02-010 FILE CONTIGUOUS_FILES_QUEUE,CONTIG_INTRO,CONTIG ;V02-010 FILE LARGE_CONTIG_FILES_QUEUE,LARGE_CONTIG_INTRO,LARGE_CONTIG;V02-010 FILE FRAGMENTED_FILES_QUEUE,FRAG_INTRO,FRAG ;V02-010 FILE LARGE_FRAG_FILES_QUEUE,LARGE_FRAG_INTRO,LARGE_FRAG ;V20-010 FILE TOO_LARGE_FILES_QUEUE,TOO_LARGE_INTRO,TOO_LARGE ;V02-010 FILE REJECTED_FILES_QUEUE,REJECTED_INTRO,REJECTED ;V02-010 FILE DIRECTORY_FILES_QUEUE,DIR_INTRO,DIRECTORY ;V02-012 .PAGE ;V02-010 .SUBTITLE OPEN/CLOSE DUMP FILES LIST FILE ;V02-010 .PSECT DUMP_TO_FILE_CODE ;V02-010 .ENTRY OPEN_DUMP_FILE,^M ;V02-010 ; ;V02-010 ; Open a file for output-file name found in LOGICAL_STRING ;V02-010 ; ;V02-010 $FAB_STORE FAB=DUMP_FAB,- ;V02-010 DNA=LOGICAL_STRING,- ;V02-010 DNS=#255,- ;V02-010 FAC=,- ;V02-010 FOP=,- ;V02-010 MRS=#0,- ;V02-010 ORG=SEQ,- ;V02-010 RAT=,- ;V02-010 RFM=,- ;V02-010 SHR= ;V02-010 $RAB_STORE RAB=DUMP_RAB,- ;V02-010 FAB=DUMP_FAB,- ;V02-010 RAC=SEQ ;V02-010 $CREATE FAB=DUMP_FAB ;V02-010 BLBC R0,1$ ;V02-010 $CONNECT RAB=DUMP_RAB ;V02-010 BLBC R0,2$ ;V02-010 1$: RET ;V02-010 2$: PUSHR #^M ;V02-010 $CLOSE FAB=DUMP_FAB ;V02-010 POPR #^M ;V02-010 RET ;V02-010 .ENTRY CLOSE_DUMP_FILE,^M ;V02-010 $CLOSE FAB=DUMP_FAB ;V02-010 RET ;V02-010 .PAGE ;V02-010 .SUBTITLE DATA FOR CHECK LOGICAL TABLE ;V02-010 .PSECT DUMP_TO_FILE_DATA ;V02-010 LOGICAL_VALUE: .LONG 256 ;V02-010 .ADDRESS LOGICAL_STRING ;V02-010 LOGICAL_STRING: .BLKB 256 ;V02-010 .ALIGN LONG ;V02-010 DUMP_FAB: $FAB ;V02-010 .ALIGN LONG ;V02-010 DUMP_RAB: $RAB ;V02-010 .PAGE .SUBTITLE MOVE SELECTED FILE TO LBN-init code .PSECT MOVE_FILES_CODE,RD,NOWRT,EXE,SHR .ENTRY MOVE_FILE,^M ; ; Procedure to move a file from its current position on disk to ; the location starting at a selected LBN. ; ; Inputs: (AP) 5 ;V02-016 ; 4(AP) FID of file to be moved (pass by value) ; 8(AP) LBN of starting location to move file (pass by value) ; 12(AP) Sequence number of file header(pass by value) ; 16(AP) Starting/lowest LBN of file(pass by value) ;V02-010 ; 20(AP) Flag word(pass by value) ;V02-016 MOVE_FILE_FLAG_NOCBT=1 ;Do not do move CBT ;V02-016 ; ; Outputs: File is moved ; R0 LSB=1 move ok ; R0 LSB=0 move not done,error ; ; Juicer routines called: ; CHECK_ACCESS ; BUILD_FILE_NAME ; UPDATE_LOGICAL_NAME ;V02-002 ; ; Check to see if the specified file is still acessable ; it may be in use or deleted ; ; Programming notes: ; The process priority is temorarily raised to 16 ; and before any exit-is dropped back down to its ; default value. ; ; The output file cannot be open unless the input file is open. ; At no time will there be the a situation where the output ; file is still open and the input file is not. ; This is to simplify the number of posabilites that the ; exit handler needs to handle. ; PUSHL 12(AP) PUSHL 4(AP) CALLS #2,CHECK_ACCESS BLBS R0,1$ RET ; ; obtain the full file name includeing device and directory string ; 1$: PUSHL 12(AP) PUSHAL MOVE_NAME_LENGTH PUSHAL MOVE_FILE_NAME PUSHL 4(AP) CALLS #4,BUILD_FILE_NAME BLBS R0,2$ RET 2$: $FAO_S CTRSTR=MOVED_FILE_FAO,- ;V02-010 OUTLEN=MOVED_NAME_LENGTH,- ;V02-010 OUTBUF=MOVED_FILE_NAME,- ;V02-010 P1=#MOVE_NAME_LENGTH,- ;V02-010 P2=16(AP) ;V02-010 PUSHAL MOVED_NAME_LENGTH ;V02-010 PUSHAL MOVE_STATUS ;V02-002 CALLS #2,UPDATE_LOGICAL_NAME ;V02-002 .IF DF,DEBUG MOVL 4(AP),MOVE_PARAM_LIST MOVL MOVE_NAME_LENGTH,MOVE_PARAM_LIST+4 MOVAL MOVE_FILE_STRING,MOVE_PARAM_LIST+8 MOVL 8(AP),MOVE_PARAM_LIST+12 $FAOL_S CTRSTR=BUILD_FAO_CTR,- OUTBUF=BUILD_OUTBUF_DSCR,- OUTLEN=BUILD_OUTLEN,- PRMLST=MOVE_PARAM_LIST PUSHAL BUILD_OUTLEN CALLS #1,G^LIB$PUT_OUTPUT .IF DF,DEBUG3 PUSHAL DO_IT_LENGTH PUSHAL DO_IT_PROMPT PUSHAL YES_NO CALLS #3,G^LIB$GET_COMMAND TSTL DO_IT_LENGTH BEQL 44$ CMPB #^A/Y/,@YES_NO+4 BEQL 43$ CMPB #^A/y/,@YES_NO+4 BEQL 43$ 44$: MOVL #SS$_NORMAL,R0 RET .ENDC .ENDC 43$: .PAGE .SUBTITLE MOVE FILES-INPUT FILE INIT RMS DATA STRUCTURES AND OPEN ; ; init the input data structures before doing open ; $FAB_STORE FAB=INPUT_FAB,- DNA=MOVE_FILE_STRING,- DNS=MOVE_NAME_LENGTH,- FAC=,- FOP=,- RAT=,- RTV=#0,- SHR=,- XAB=INPUT_XAB_ALL $RAB_STORE RAB=INPUT_RAB,- FAB=INPUT_FAB,- RAC=,- ROP= $XABALL_STORE XAB=INPUT_XAB_ALL,- NXT=INPUT_XAB_DAT $XABDAT_STORE XAB=INPUT_XAB_DAT,- NXT=INPUT_XAB_FHC $XABFHC_STORE XAB=INPUT_XAB_FHC,- NXT=INPUT_XAB_PRO $XABPRO_STORE XAB=INPUT_XAB_PRO,- ACLBUF=ACL_BUFF,- ACLSIZ=#512,- ACLLEN=#0,- ;V02-014 NXT=INPUT_XAB_SUM MOVC5 #0,ACL_BUFF,#0,#1024,ACL_BUFF ;V02-014 $XABSUM_STORE XAB=INPUT_XAB_SUM,- NXT=INPUT_XAB_RDT $XABRDT_STORE XAB=INPUT_XAB_RDT ; ; Build dummy output name ; ; Break out from input file-the device and directory string ; ADDL3 #4,MOVE_NAME_LENGTH,DUMMY_NAME_LENGTH ;V02-011 LOCC #^A/]/,MOVE_NAME_LENGTH,MOVE_FILE_STRING SUBL3 R0,MOVE_NAME_LENGTH,R1 INCL R1 SUBL3 R1,MOVE_NAME_LENGTH,R6 ;V02-011 MOVC3 R1,MOVE_FILE_STRING,DUMMY_NAME_STRING ;V02-011 ; ;V02-011 ; Add onto end just after "]" the string "$$$$" ;V02-011 ; ;V02-011 MOVL #^A/$$$$/,(R3)+ ;V02-011 ; ; COPY ONTO NEW END THE REST OF THE ORIGINAL FILE NAME ;V02-011 ; MOVC3 R6,(R1),(R3) ;V02-011 ; ; From this point unitll the close-we want to do the operations ; as fast as possable-so up the priority ; $SETPRI_S PRI=#16,PRVPRI=OLD_MOVE_PRIORITY ; ; Open the input file ; BISL #MODE_M_INPUT_OPEN,MODE $OPEN FAB=INPUT_FAB BLBS R0,4$ ;check for error PUSHR #^M CLRL MODE $SETPRI_S PRI=OLD_MOVE_PRIORITY POPR #^M RET ;file not opened-take error exit 4$: $CONNECT RAB=INPUT_RAB ;connect BLBS R0,5$ ;check for error PUSHR #^M ;SAVE R0 FOR ERROR EXIT RETURN XORL2 #,MODE $CLOSE FAB=INPUT_FAB ;CLOSE THE FILE CLRL MODE $SETPRI_S PRI=OLD_MOVE_PRIORITY POPR #^M RET ;AND RETURN UNMOVED 5$: .PAGE .SUBTITLE MOVE FILES INIT AND OPEN OUTPUT FILE ; ; Set up output RMS data structures ; $FAB_STORE FAB=OUTPUT_FAB,- BKS=INPUT_FAB+FAB$B_BKS,- BLS=#512,- FAC=,- FNA=DUMMY_NAME_STRING,- FNS=DUMMY_NAME_LENGTH,- FOP=,- FSZ=INPUT_FAB+FAB$B_FSZ,- GBC=INPUT_FAB+FAB$W_GBC,- MRN=INPUT_FAB+FAB$L_MRN,- MRS=INPUT_FAB+FAB$W_MRS,- ORG=INPUT_FAB+FAB$B_ORG,- RAT=INPUT_FAB+FAB$B_RAT,- RFM=INPUT_FAB+FAB$B_RFM,- RTV=#0,- SHR=,- XAB=OUTPUT_XAB_FHC BICL3 #^C,INPUT_FAB+FAB$L_FOP,R0 BISL2 R0,OUTPUT_FAB+FAB$L_FOP CMPB #FAB$C_SEQ,INPUT_FAB+FAB$B_ORG BNEQ 33$ BISB2 #FAB$M_BRO,OUTPUT_FAB+FAB$B_FAC BRB 34$ 33$: BISB2 #FAB$M_BIO,OUTPUT_FAB+FAB$B_FAC BICB2 #FAB$M_BRO,OUTPUT_FAB+FAB$B_FAC 34$: $XABFHC_STORE XAB=OUTPUT_XAB_FHC,- NXT=OUTPUT_XAB_ALL ; ; The macro $XABFHC_STORE does not load the following items ; so I have to do them this way ; MOVB INPUT_XAB_FHC+XAB$B_ATR,OUTPUT_XAB_FHC+XAB$B_ATR MOVB INPUT_XAB_FHC+XAB$B_BKZ,OUTPUT_XAB_FHC+XAB$B_BKZ MOVW INPUT_XAB_FHC+XAB$W_DXQ,OUTPUT_XAB_FHC+XAB$W_DXQ MOVL INPUT_XAB_FHC+XAB$L_EBK,OUTPUT_XAB_FHC+XAB$L_EBK MOVW INPUT_XAB_FHC+XAB$W_FFB,OUTPUT_XAB_FHC+XAB$W_FFB MOVW INPUT_XAB_FHC+XAB$W_GBC,OUTPUT_XAB_FHC+XAB$W_GBC MOVB INPUT_XAB_FHC+XAB$B_HSZ,OUTPUT_XAB_FHC+XAB$B_HSZ MOVW INPUT_XAB_FHC+XAB$W_LRL,OUTPUT_XAB_FHC+XAB$W_LRL MOVW INPUT_XAB_FHC+XAB$W_MRZ,OUTPUT_XAB_FHC+XAB$W_MRZ MOVB INPUT_XAB_FHC+XAB$B_RFO,OUTPUT_XAB_FHC+XAB$B_RFO CLRL OUTPUT_XAB_FHC+XAB$L_SBN MOVW INPUT_XAB_FHC+XAB$W_VERLIMIT,OUTPUT_XAB_FHC+XAB$W_VERLIMIT $XABALL_STORE XAB=OUTPUT_XAB_ALL,- NXT=OUTPUT_XAB_DAT,- AID=#0,- ALN=#XAB$C_LBN,- ALQ=INPUT_XAB_FHC+XAB$L_HBK,- AOP=INPUT_XAB_ALL+XAB$B_AOP,- BKZ=INPUT_FAB+FAB$B_BKS,- DEQ=INPUT_XAB_FHC+XAB$W_DXQ,- LOC=8(AP),- RFI=#0,- VOL=#0 BITL #XAB$M_CTG,OUTPUT_XAB_ALL+XAB$B_AOP BNEQ 6$ BITL #MOVE_FILE_FLAG_NOCBT,20(AP) ;V02-016 BNEQ 7$ ;V02-016 BISB #XAB$M_CBT,OUTPUT_XAB_ALL+XAB$B_AOP BRB 7$ 6$: BITL #MOVE_FILE_FLAG_NOCBT,20(AP) ;V02-016 BEQL 50$ ;V02-016 $CLOSE FAB=INPUT_FAB ;V02-016 CLRL MODE ;V02-016 $SETPRI_S PRI=OLD_MOVE_PRIORITY ;V02-016 CLRL R0 ;V02-016 RET ;V02-016 50$: MOVL 8(AP),OUTPUT_XAB_FHC+XAB$L_SBN ;V02-016 7$: $XABDAT_STORE XAB=OUTPUT_XAB_DAT,- NXT=OUTPUT_XAB_PRO,- BDT=INPUT_XAB_DAT+XAB$Q_BDT,- CDT=INPUT_XAB_DAT+XAB$Q_CDT,- EDT=INPUT_XAB_DAT+XAB$Q_EDT,- RDT=#0 ADDW3 #1,INPUT_XAB_DAT+XAB$W_RVN,OUTPUT_XAB_DAT+XAB$W_RVN $XABPRO_STORE XAB=OUTPUT_XAB_PRO,- NXT=OUTPUT_XAB_RDT,- ACLBUF=ACL_BUFF,- ACLCTX=#0,- ACLLEN=INPUT_XAB_PRO+XAB$W_ACLLEN,- ACLSIZ=#512,- PRO=INPUT_XAB_PRO+XAB$W_PRO,- PROT_OPT=INPUT_XAB_PRO+XAB$B_PROT_OPT,- UIC=INPUT_XAB_PRO+XAB$L_UIC $XABRDT_STORE XAB=OUTPUT_XAB_RDT,- RDT=#0 ADDW3 #1,INPUT_XAB_DAT+XAB$W_RVN,OUTPUT_XAB_RDT+XAB$W_RVN $RAB_STORE RAB=OUTPUT_RAB,- FAB=OUTPUT_FAB,- RAC=,- ROP= MOVW INPUT_XAB_PRO+XAB$W_ACLLEN,INPUT_XAB_PRO+XAB$W_ACLSIZ BITL #FAB$M_CTG,INPUT_FAB+FAB$L_FOP BEQL 10$ BISB #XAB$M_CTG,OUTPUT_XAB_ALL+XAB$B_AOP BRB 11$ 10$: BITL #MOVE_FILE_FLAG_NOCBT,20(AP) ;V02-016 BNEQ 11$ ;V02-016 BISB #XAB$M_CBT,OUTPUT_XAB_ALL+XAB$B_AOP 11$: BISL2 #MODE_M_OUTPUT_OPEN,MODE $CREATE FAB=OUTPUT_FAB BLBS R0,12$ ;CHECK FOR ERROR PUSHR #^M ;SAVE ERROR STATUS FOR RETURN AFTER CLEANUP XORL2 #,MODE $CLOSE FAB=INPUT_FAB CLRL MODE $SETPRI_S PRI=OLD_MOVE_PRIORITY POPR #^M RET 12$: $CONNECT RAB=OUTPUT_RAB ;CONNECT THE RAB TO THE NOW OPEN OUTPUT BLBS R0,13$ ;CHECK FOR ERROR PUSHL #^M ;SAVE R0 FOR ERROR RETURN AFTER CLEANUP BISL2 #FAB$M_DLT,OUTPUT_FAB+FAB$L_FOP ;DELETE OUTPUT FILE ON CLOSE XORL2 #,MODE $CLOSE FAB=OUTPUT_FAB XORL2 #,- MODE $CLOSE FAB=INPUT_FAB CLRL MODE $SETPRI_S PRI=OLD_MOVE_PRIORITY POPR #^M RET 13$: .PAGE .SUBTITLE MOVE FILE- ACTUAL MOVE FILE CODE BY BLOCKS ; ; Init the input and output RABS ; MOVAL IO_BUFFER,INPUT_RAB+RAB$L_UBF ;load io buff addr MOVW #<512*64>,INPUT_RAB+RAB$W_USZ ;xfer in 64 block chunks CLRL INPUT_RAB+RAB$L_BKT ;use internal next block ptr MOVAL IO_BUFFER,OUTPUT_RAB+RAB$L_RBF ;repeat for output buffer MOVW #<512*64>,OUTPUT_RAB+RAB$W_RSZ CLRL OUTPUT_RAB+RAB$L_BKT 25$: $READ RAB=INPUT_RAB ;read block from input BLBC R0,26$ ;error/eof check MOVW INPUT_RAB+RAB$W_RSZ,OUTPUT_RAB+RAB$W_RSZ;copy actual bytes xferd $WRITE RAB=OUTPUT_RAB ;write to new file BLBS R0,25$ ;if no error loop back .PAGE .SUBTITLE ERROR AND NORMAL EXITS ; ; If we got here, we have some error trying to write to ; the new file. No atempt is made to try and recover. The new file ; is deleted and the old one is left alone ; PUSHL #^M ;SAVE R0 FOR ERROR RETURN AFTER CLEANUP BISL2 #FAB$M_DLT,OUTPUT_FAB+FAB$L_FOP ;DELETE OUTPUT FILE ON CLOSE XORL2 #,MODE $CLOSE FAB=OUTPUT_FAB XORL2 #,- MODE $CLOSE FAB=INPUT_FAB CLRL MODE $SETPRI_S PRI=OLD_MOVE_PRIORITY POPR #^M RET ; ; Error reading-see if it was EOF ; 26$: CMPL #RMS$_EOF,R0 BEQL 28$ ;yes it was EOF-take normal exit ; ; error-reading-handle same as write error ; PUSHL #^M ;SAVE R0 FOR ERROR RETURN AFTER CLEANUP BISL2 #FAB$M_DLT,OUTPUT_FAB+FAB$L_FOP ;DELETE OUTPUT FILE ON CLOSE XORL2 #,MODE $CLOSE FAB=OUTPUT_FAB XORL2 #,- MODE $CLOSE FAB=INPUT_FAB CLRL MODE $SETPRI_S PRI=OLD_MOVE_PRIORITY POPR #^M RET 28$: ; ; Exact duplicate of input file has been made-now to do the ; close and cleanup ; first close output file ; then close and delete input file ; and rename output file the same as deleted input. ; Note that the order and placement of the $CLOSE and $RENAME ; keeps to the shortest possable time the gap during which ; the old file no longer exists and the new file does not ; yet have the name of the old file. ; BISL2 #FAB$M_DLT,INPUT_FAB+FAB$L_FOP ;DELETE INPUT FILE ON CLOSE $FAB_STORE FAB=OLD_RENAME_FAB,- FNA=DUMMY_NAME_STRING,- FNS=DUMMY_NAME_LENGTH $FAB_STORE FAB=NEW_RENAME_FAB,- FNA=MOVE_FILE_STRING,- FNS=MOVE_NAME_LENGTH XORL2 #,MODE $CLOSE FAB=OUTPUT_FAB XORL2 #,- MODE $CLOSE FAB=INPUT_FAB XORL2 #,MODE $RENAME OLDFAB=OLD_RENAME_FAB,- NEWFAB=NEW_RENAME_FAB CLRL MODE $SETPRI_S PRI=OLD_MOVE_PRIORITY RET .PAGE .SUBTITLE MOVE FILE DATA AREA .PSECT MOVE_FILES_DATA,RD,WRT,NOEXE,NOSHR,PAGE MOVE_FILE_NAME: .LONG 4096 .ADDRESS MOVE_FILE_STRING MOVE_FILE_STRING: .BLKB 4096 MOVE_NAME_LENGTH: .LONG 0 .ADDRESS MOVE_FILE_STRING ;V02-002 MOVE_STATUS: .ASCID /FILE_NAME/ ;V02-002 MOVED_FILE_STRING: ;V02-010 .BLKB 4096 ;V02-010 MOVED_FILE_NAME: ;V02-010 .LONG 4096 ;V02-010 .ADDRESS MOVED_FILE_STRING ;V02-010 MOVED_NAME_LENGTH: ;V02-010 .LONG 0 ;V02-010 .ADDRESS MOVED_FILE_STRING ;V02-010 MOVED_FILE_FAO: .ASCID /!AS @LBN !XL%X/ ;V02-010 DUMMY_NAME_STRING: .BLKB 4096 DUMMY_NAME_LENGTH: .LONG 0 DUMMY_NAME_TEXT: .ASCII /$$$$____JUICER_2____$$$$.$$$$____DUP_FILE____$$$$/ DUMMY_NAME_SIZE=.-DUMMY_NAME_TEXT OLD_MOVE_PRIORITY: .LONG 0 .IF DF,DEBUG BUILD_FAO_CTR: .ASCID ?Command to move file FID !XL !/ !AD !/To LBN !XL ? BUILD_OUTBUF_DSCR: .LONG 4352 .ADDRESS BUILD_OUTBUF BUILD_OUTBUF: .BLKB 4352 BUILD_OUTLEN: .LONG 0 .ADDRESS BUILD_OUTBUF MOVE_PARAM_LIST: .LONG 0,0,0,0 .LONG 3 .ADDRESS YES_NO,DO_IT_PROMPT,DO_IT_LENGTH YES_NO: .ASCID / / DO_IT_LENGTH: .LONG 0 DO_IT_PROMPT: .ASCID +Execute move (Y/N) [N] ? + .ENDC .PAGE .SUBTITLE MOVE FILES RMS DATA STRUCTURES AREA .PSECT MOVE_FILES_RMS_BLOCKS,RD,WRT,NOEXE,NOSHR,PAGE ; ; INPUT FILE DATA STRUCTURES ; .ALIGN LONG INPUT_FAB: $FAB .ALIGN LONG INPUT_RAB: $RAB .ALIGN LONG INPUT_XAB_ALL: $XABALL .ALIGN LONG INPUT_XAB_DAT: $XABDAT .ALIGN LONG INPUT_XAB_FHC: $XABFHC .ALIGN LONG INPUT_XAB_PRO: $XABPRO .ALIGN LONG INPUT_XAB_SUM: $XABSUM .ALIGN LONG INPUT_XAB_RDT: $XABRDT .ALIGN LONG OUTPUT_FAB: $FAB .ALIGN LONG OUTPUT_RAB: $RAB .ALIGN LONG OUTPUT_XAB_ALL: $XABALL .ALIGN LONG OUTPUT_XAB_DAT: $XABDAT .ALIGN LONG OUTPUT_XAB_FHC: $XABFHC .ALIGN LONG OUTPUT_XAB_PRO: $XABPRO .ALIGN LONG OUTPUT_XAB_SUM: $XABSUM .ALIGN LONG OUTPUT_XAB_RDT: $XABRDT ACL_BUFF: .BLKB 1024 .ALIGN LONG OLD_RENAME_FAB: $FAB .ALIGN LONG NEW_RENAME_FAB: $FAB .PSECT MOVE_FILES_BUFFER,RD,WRT,NOEXE,NOSHR,LONG .ALIGN LONG IO_BUFFER: .BLKB <512*64> ;BLOCK I/O as 64 block segments .PAGE .SUBTITLE EXIT HANDLER .PSECT EXIT_HANDLER_CODE,RD,NOWRT,EXE,SHR .ENTRY EXIT_HANDLER,^M ; ; This is the exit handler to check the status of the copy ; operation and make a try at not looseing anything even if ; the exit came during some critical part of the operation. ; Update the value of the logical name JUICER_2_disk_STATUS ;V02-002 ; to the text equivalent of the exit error value ;V02-002 ; ; Input: ;V02-002 ; @4(AP) exit error code ;V02-002 ; ;V02-002 ; Juicer routines called: ;V02-002 ; UPDATE_LOGICAL_NAME ;V02-002 ; ;V02-002 $GETMSG_S MSGID=@4(AP),- ;V02-002 MSGLEN=EXIT_LENGTH,- ;V02-002 BUFADR=EXIT_STRING,- ;V02-002 FLAGS=#15 ;V02-002 PUSHAL EXIT_LENGTH ;V02-002 PUSHAL EXIT_STATUS ;V02-002 CALLS #2,UPDATE_LOGICAL_NAME ;V02-002 ; ; Check to see if the input file is open or in process of ; being closed-if so close it ; BITL #,MODE BNEQ 12$ BRW 20$ ;IF NOT SKIP NEXT CODE ; INPUT MAY BE OPEN-CHECK IFI 12$: TSTW INPUT_FAB+FAB$W_IFI BEQL 10$ ;IF NOT YET OPENED SKIP NEXT $CLOSE FAB=INPUT_FAB ; ; At this point we have a closed input file that we want to keep. ; if the output file exists-we want to close and delete it ; no matter what the current state of MODE ; 10$: TSTW OUTPUT_FAB+FAB$W_IFI ;IF OUTPUT OPEN-DO A CLOSE ON IT BEQL 11$ BISL2 #FAB$M_DLT,OUTPUT_FAB+FAB$L_FOP ;DELETE OUTPUT FILE ON CLOSE $CLOSE FAB=OUTPUT_FAB ; ; This path requires no further action-just need to continue to next ; exit handler ; 11$: RET ; ; Check to see if the input file is being deleted on close?? ; 20$: BITL #MODE_M_INPUT_DELETE,MODE BNEQ 22$ BRW 30$ ;NO-SKIP NEXT CODE 22$: TSTW INPUT_FAB+FAB$W_IFI ;SEE IF STILL OPEN BEQL 21$ BISL2 #FAB$M_DLT,INPUT_FAB+FAB$L_FOP ;DELETE OUTPUT FILE ON CLOSE $CLOSE FAB=INPUT_FAB 21$: ; ; we need to keep the output file and rename it the same as input file ; TSTW OUTPUT_FAB+FAB$W_IFI BEQL 24$ BICL2 #FAB$M_DLT,OUTPUT_FAB+FAB$L_FOP ;DELETE OUTPUT FILE ON CLOSE $CLOSE FAB=OUTPUT_FAB ; ; Now rename ; 24$: $FAB_STORE FAB=OLD_RENAME_FAB,- FNA=DUMMY_NAME_STRING,- FNS=DUMMY_NAME_LENGTH $FAB_STORE FAB=NEW_RENAME_FAB,- FNA=MOVE_FILE_STRING,- FNS=MOVE_NAME_LENGTH $RENAME OLDFAB=OLD_RENAME_FAB,- NEWFAB=NEW_RENAME_FAB ; ; Done all that can be done in this path-return ; RET 30$: ; ; Input file has been closed and possably deleted. ; The output file cannot be open as the convention ; used in MOVE_FILE is for the output file to be ; OPEND/CLOSED/DELETED only while the input is already open ; the input file is never closed if the output file is open. ; ; The only possablility left is that of a rename ; BITL #MODE_M_RENAME,MODE BEQL 31$ ; ; This operation may fail as the rename took place but the flag ; in mode did not get cleared. But doint anyway ; $FAB_STORE FAB=OLD_RENAME_FAB,- FNA=DUMMY_NAME_STRING,- FNS=DUMMY_NAME_LENGTH $FAB_STORE FAB=NEW_RENAME_FAB,- FNA=MOVE_FILE_STRING,- FNS=MOVE_NAME_LENGTH $RENAME OLDFAB=OLD_RENAME_FAB,- NEWFAB=NEW_RENAME_FAB 31$: ; ; All conditions handled-done ; RET .PAGE ;V02-002 .SUBTITLE Exit handler data ;V02-002 .PSECT EXIT_HANDLER_DATA,RD,WRT,NOEXE,NOSHR ;V02-002 EXIT_LENGTH: .LONG 0 ;V02-002 .ADDRESS EXIT_TEXT ;V02-002 EXIT_STRING: .LONG 256 ;V02-002 .ADDRESS EXIT_TEXT ;V02-002 EXIT_TEXT: .BLKB 256 ;V02-002 EXIT_STATUS: .ASCID /STATUS/ ;V02-002 .PAGE ;V02-002 .SUBTITLE UPDATE LOGICAL NAME ;V02-002 .PSECT LOGICAL_NAME_CODE,RD,NOWRT,EXE,SHR ;V02-002 .ENTRY UPDATE_LOGICAL_NAME,^M ;V02-002 ; ;V02-002 ; Procedure to update a specified logical name in the system ;V02-002 ; logical name table. ;V02-002 ; ;V02-002 ; Arguments: ;V02-002 ; 4(AP) Address of descripter of which logical name ;V02-002 ; STATE or FILE only currently used ;V02-002 ; 8(AP) Address of descripter of values logical name ;V02-002 ; is to take. ;V02-002 ; ;V02-002 ; Other inputs: ;V02-002 ; DEVICE_NAME ;V02-002 ; ;V02-002 ; Outputs: ;V02-002 ; Modified System Logical Name Table ;V02-002 ; Return in R0 the status of the $CRELOG system service ;V02-002 ; ;V02-002 ; First build the logical name in form JUICER_2_disk_type ;V02-002 ; ;V02-002 ; Move in JUICER_2_ ;V02-002 ; ;V02-002 MOVL #JUICER_NAME_LENGTH,LOGICAL_NAME_LENGTH ;V02-002 MOVC3 #JUICER_NAME_LENGTH,JUICER_NAME_TEXT,LOGICAL_NAME_STRING;V02-002 ; ;V02-002 ; Next move in device name sans ":" ;V02-002 ; ;V02-002 MOVAL DEVICE_NAME,R11 ;V02-002 MOVZWL (R11),R10 ;V02-002 MOVL 4(R11),R9 ;V02-002 LOCC #^A/:/,R10,(R9) ;V02-002 SUBL2 R0,R10 ;V02-002 ADDL2 R10,LOGICAL_NAME_LENGTH ;V02-002 MOVC3 R10,(R9),(R3) ;V02-002 ; ;V02-002 ; add a "_" ;V02-002 ; ;V02-002 MOVB #^A/_/,(R3)+ ;V02-002 INCL LOGICAL_NAME_LENGTH ;V02-002 ; ;V02-002 ; Finally the type string ;V02-002 ; ;V02-002 MOVL 4(AP),R11 ;V02-002 MOVZWL (R11),R10 ;V02-002 MOVL 4(R11),R9 ;V02-002 ADDL2 R10,LOGICAL_NAME_LENGTH ;V02-002 MOVC3 R10,(R9),(R3) ;V02-002 ; ;V02-002 ; Post the updated logical name ;V02-002 ; ;V02-002 MOVL 8(AP),R2 ;V02-010 MOVW (R2),LOGICAL_NAME_ITMLST ;V02-010 MOVL 4(R2),LOGICAL_NAME_ITMLST+4 ;V02-010 $CRELNM_S ATTR=LOGICAL_NAME_CATT,- ;V02-010 TABNAM=LOGICAL_NAME_TABLE,- ;V02-010 LOGNAM=LOGICAL_NAME_LENGTH,- ;V02-010 ITMLST=LOGICAL_NAME_ITMLST ;V02-010 RET ;V02-002 .PAGE ;V02-010 .SUBTITLE GET LOGICAL NAME ;V02-010 .PSECT LOGICAL_NAME_CODE,RD,NOWRT,EXE,SHR ;V02-010 .ENTRY GET_LOGICAL_NAME,^M ;V02-010 ; ;V02-010 ; Procedure to obtain the value of a specified logical name in ;V02-010 ; the system logical name table. ;V02-010 ; ;V02-010 ; Arguments: ;V02-010 ; 4(AP) Address of descripter of which logical name ;V02-010 ; 8(AP) Address of descripter of for value of the ;V02-010 ; logical name. ;V02-010 ; ;V02-010 ; Other inputs: ;V02-010 ; DEVICE_NAME ;V02-010 ; ;V02-010 ; Outputs: ;V02-010 ; Return in R0 the status of the $TRNLNM system service ;V02-010 ; ;V02-010 ; First build the logical name in form JUICER_2_disk_type ;V02-010 ; ;V02-010 ; Move in JUICER_2_ ;V02-010 ; ;V02-010 MOVL #JUICER_NAME_LENGTH,LOGICAL_NAME_LENGTH ;V02-010 MOVC3 #JUICER_NAME_LENGTH,JUICER_NAME_TEXT,LOGICAL_NAME_STRING;V02-010 ; ;V02-010 ; Next move in device name sans ":" ;V02-010 ; ;V02-010 MOVAL DEVICE_NAME,R11 ;V02-010 MOVZWL (R11),R10 ;V02-010 MOVL 4(R11),R9 ;V02-010 LOCC #^A/:/,R10,(R9) ;V02-010 SUBL2 R0,R10 ;V02-010 ADDL2 R10,LOGICAL_NAME_LENGTH ;V02-010 MOVC3 R10,(R9),(R3) ;V02-010 ; ;V02-010 ; add a "_" ;V02-010 ; ;V02-010 MOVB #^A/_/,(R3)+ ;V02-010 INCL LOGICAL_NAME_LENGTH ;V02-010 ; ;V02-010 ; Finally the type string ;V02-010 ; ;V02-010 MOVL 4(AP),R11 ;V02-010 MOVZWL (R11),R10 ;V02-010 MOVL 4(R11),R9 ;V02-010 ADDL2 R10,LOGICAL_NAME_LENGTH ;V02-010 MOVC3 R10,(R9),(R3) ;V02-010 ; ;V02-010 ; Clear the output string ;V02-010 ; ;V02-010 MOVL 8(AP),R6 ;V02-010 MOVZWL (R6),R5 ;V02-010 MOVL 4(R6),R6 ;V02-010 MOVL R6,LOGICAL_NAME_ITMLST+4 ;V02-010 MOVW R5,LOGICAL_NAME_ITMLST ;V02-010 MOVC5 #0,(R6),#0,R5,(R6) ;V02-010 ; ;V02-010 ; Look for the logical name ;V02-010 ; ;V02-010 $TRNLNM_S ATTR=LOGICAL_NAME_GATT,- ;V02-010 TABNAM=LOGICAL_NAME_TABLE,- ;V02-010 LOGNAM=LOGICAL_NAME_LENGTH,- ;V02-010 ITMLST=LOGICAL_NAME_ITMLST ;V02-010 RET ;V02-010 .PAGE ;V02-010 .SUBTITLE DELETE LOGICAL NAME ;V02-010 .PSECT LOGICAL_NAME_CODE,RD,NOWRT,EXE,SHR ;V02-010 .ENTRY DELETE_LOGICAL_NAME,^M ;V02-010 ; ;V02-010 ; Procedure to delete a specified logical name in ;V02-010 ; the system logical name table. ;V02-010 ; ;V02-010 ; Arguments: ;V02-010 ; 4(AP) Address of descripter of which logical name ;V02-010 ; ;V02-010 ; Other inputs: ;V02-010 ; DEVICE_NAME ;V02-010 ; ;V02-010 ; Outputs: ;V02-010 ; Return in R0 the status of the $DELLNM system service ;V02-010 ; ;V02-010 ; First build the logical name in form JUICER_2_disk_type ;V02-010 ; ;V02-010 ; Move in JUICER_2_ ;V02-010 ; ;V02-010 MOVL #JUICER_NAME_LENGTH,LOGICAL_NAME_LENGTH ;V02-010 MOVC3 #JUICER_NAME_LENGTH,JUICER_NAME_TEXT,LOGICAL_NAME_STRING;V02-010 ; ;V02-010 ; Next move in device name sans ":" ;V02-010 ; ;V02-010 MOVAL DEVICE_NAME,R11 ;V02-010 MOVZWL (R11),R10 ;V02-010 MOVL 4(R11),R9 ;V02-010 LOCC #^A/:/,R10,(R9) ;V02-010 SUBL2 R0,R10 ;V02-010 ADDL2 R10,LOGICAL_NAME_LENGTH ;V02-010 MOVC3 R10,(R9),(R3) ;V02-010 ; ;V02-010 ; add a "_" ;V02-010 ; ;V02-010 MOVB #^A/_/,(R3)+ ;V02-010 INCL LOGICAL_NAME_LENGTH ;V02-010 ; ;V02-010 ; Finally the type string ;V02-010 ; ;V02-010 MOVL 4(AP),R11 ;V02-010 MOVZWL (R11),R10 ;V02-010 MOVL 4(R11),R9 ;V02-010 ADDL2 R10,LOGICAL_NAME_LENGTH ;V02-010 MOVC3 R10,(R9),(R3) ;V02-010 ; ;V02-010 ; Get the access mode of the logical name ;V02-010 ; ;V02-010 $TRNLNM_S ATTR=LOGICAL_NAME_GATT,- ;V02-010 TABNAM=LOGICAL_NAME_TABLE,- ;V02-010 LOGNAM=LOGICAL_NAME_LENGTH,- ;V02-010 ITMLST=LOGICAL_NAME_MODE ;V02-010 ; ;V02-010 ; Delete for the logical name ;V02-010 ; ;V02-010 $DELLNM_S TABNAM=LOGICAL_NAME_TABLE,- ;V02-010 LOGNAM=LOGICAL_NAME_LENGTH,- ;V02-010 ACMODE=LOGICAL_NAME_ACMODE ;V02-010 RET ;V02-010 .PAGE ;V02-002 .SUBTITLE LOGICAL NAME TABLE DATA AREA ;V02-002 .PSECT LOGICAL_NAME_DATA,RD,WRT,NOEXE,NOSHR ;V02-002 LOGICAL_NAME_GATT: .LONG LNM$M_CASE_BLIND ;V02-010 LOGICAL_NAME_CATT: .LONG LNM$M_NO_ALIAS ;V02-010 LOGICAL_NAME_TABLE: .ASCID /LNM$SYSTEM_TABLE/ ;V02-010 LOGICAL_NAME_ITMLST: .WORD 0,LNM$_STRING ;V02-010 .LONG 0,0,0 ;V02-010 LOGICAL_NAME_MODE: .WORD 4,LNM$_ACMODE ;V02-010 .ADDRESS LOGICAL_NAME_ACMODE ;V02-010 .LONG 0,0 ;V02-010 LOGICAL_NAME_ACMODE: .LONG 0 ;V02-010 LOGICAL_NAME_LENGTH: .LONG 0 ;V02-002 .ADDRESS LOGICAL_NAME_STRING ;V02-002 LOGICAL_NAME_STRING: .BLKB 4096 ;V02-002 JUICER_NAME_TEXT: .ASCII /JUICER_2_/ ;V02-002 JUICER_NAME_LENGTH=.-JUICER_NAME_TEXT ;V02-002 .PAGE ;V02-004 .SUBTITLE UPDATE DISK DATA ;V02-004 .PSECT UPDATE_DISK_DATA_CODE,RD,NOWRT,EXE,SHR ;V02-004 .ENTRY UPDATE_DISK_DATA,^M ;V02-004 ; ;V02-004 ; Generates the current statistics about the disk and outputs ;V02-004 ; ;V02-004 ; Inputs: ;V02-004 ; FRAGMENT_COUNT ;V02-004 ; LARGEST_FREE_FRAGMENT ;V02-004 ; FREE_BLOCKS ;V02-004 ; FILE_COUNT ;V02-004 ; POINTER_COUNT ;V02-004 ; ;V02-004 ; Output: ;V02-004 ; Updated logical JUICER_2_disk_FRAG ;V02-004 ; ;V02-004 ; Juicer routines called ;V02-004 ; UPDATE_LOGICAL_NAME ;V02-004 ; ;V02-004 MOVAL DD_PARAM,R11 ;V02-004 CVTLF FRAGMENT_COUNT,R10 ;V02-004 CVTLF FREE_BLOCKS,R9 ;V02-004 TSTL R9 ;V02-004 BNEQ 1$ ;V02-004 CLRQ (R11)+ ;V02-004 BRB 2$ ;V02-004 1$: DIVF2 R9,R10 ;V02-004 MULF2 ONE_HUNDRED,R10 ;V02-004 CVTFL R10,R9 ;V02-004 MOVL R9,(R11)+ ;V02-004 CVTLF R9,R9 ;V02-004 SUBF2 R9,R10 ;V02-004 MULF2 ONE_HUNDRED,R10 ;V02-004 CVTFL R10,(R11)+ ;V02-004 2$: MOVL LARGEST_FREE_FRAGMENT,(R11)+ ;V02-004 CVTLF POINTER_COUNT,R10 ;V02-004 CVTLF FILE_COUNT,R9 ;V02-004 TSTF R9 ;V02-004 BNEQ 3$ ;V02-004 CLRQ (R11)+ ;V02-004 BRB 4$ ;V02-004 3$: DIVF2 R9,R10 ;V02-004 CVTFL R10,R9 ;V02-004 MOVL R9,(R11)+ ;V02-004 CVTLF R9,R9 ;V02-004 SUBF2 R9,R10 ;V02-004 MULF ONE_THOUSAND,R10 ;V02-004 CVTFL R10,(R11)+ ;V02-004 4$: $FAOL_S CTRSTR=DD_FAO,- ;V02-004 OUTLEN=DD_LENGTH,- ;V02-004 OUTBUF=DD_DESCR,- ;V02-004 PRMLST=DD_PARAM ;V02-004 MOVAL DD_TEXT,R11 ;V02-004 MOVL DD_LENGTH,R10 ;V02-004 5$: CMPB #^A/./,(R11)+ ;V02-004 BEQL 6$ ;V02-004 DECL R10 ;V02-004 BGTR 5$ ;V02-004 BRW 10$ ;V02-004 6$: CMPB #^A/ /,(R11) ;V02-004 BNEQ 7$ ;V02-004 MOVB #^A/0/,(R11)+ ;V02-004 CMPB #^A/ /,(R11) ;V02-004 BNEQ 7$ ;V02-004 MOVB #^A/0/,(R11)+ ;V02-004 7$: SUBL2 #2,R10 ;V02-004 8$: CMPB #^A/./,(R11)+ ;V02-004 BEQL 9$ ;V02-004 DECL R10 ;V02-004 BGTR 8$ ;V02-004 BRW 10$ ;V02-004 9$: CMPB #^A/ /,(R11) ;V02-004 BNEQ 10$ ;V02-004 MOVB #^A/0/,(R11)+ ;V02-004 CMPB #^A/ /,(R11) ;V02-004 BNEQ 10$ ;V02-004 MOVB #^A/0/,(R11)+ ;V02-004 CMPB #^A/ /,(R11) ;V02-004 BNEQ 10$ ;V02-004 MOVB #^A/0/,(R11) ;V02-004 10$: PUSHAL DD_LENGTH ;V02-004 PUSHAL DD_FRAG ;V02-004 CALLS #2,UPDATE_LOGICAL_NAME ;V02-004 RET ;V02-004 .PAGE ;V02-004 .SUBTITLE UPDATE DISK DATA-DATA AREA ;V02-004 .PSECT UPDATE_DISK_DATA_DATA,RD,WRT,NOSHR,NOEXE,LONG ;V02-005 ONE_HUNDRED: .FLOAT 100.00 ;V02-004 ONE_THOUSAND: .FLOAT 1000.00 ;V02-004 DD_FRAG:.ASCID /FRAG/ ;V02-010 DD_FAO: .ASCID /Disk !UL.!(2UL)%, Largest free frag !UL blocks,/- ;V02-004 / File frag !UL.!(3UL)/ ;V02-004 DD_PARAM: .BLKL 5 ;V02-004 DD_DESCR: .LONG 61 ;V02-004 .ADDRESS DD_TEXT ;V02-004 DD_TEXT: .BLKB 61 ;V02-004 DD_LENGTH: .LONG 0 ;V02-004 .ADDRESS DD_TEXT ;V02-004 .END JUICER