; Find UFD blocks (Even containing a specific file)
;
; Written by Dell Coleman (on October 7, 1991)
; Alpha Automation Incorporated
; 2000 West Loop South Suite 700
; Houston, TX 77027
; (713) 877-8039
; copyrighted by the above
; You are granted license to use this software any way you wish
; so long as you do NOT sell or charge any fee for it.
;
; NOTE: The idea of checking for extensions was taken from
; UFDFND.M68 written by Steven G. McNaughton &
; Rich Eakin of Quaker State Oil Corp. UFDFND.M68 was
; gotten from the AMUS bulletin board for free.
;
;[100] 7 October 1991 - Dell Coleman
; Program written.
; Because of the monitor call DEVCHR - AMOS 2.0 or above may be needed.
;
SYM
SEARCH SYS
SEARCH SYSSYM
SEARCH AAI
VMAJOR=1
VMINOR=0
VEDIT=100.
OFINI
OFDEF DDB,D.DDB ; DDB for reading disk
OFDEF FILNAM,6 ; ASCII filename
OFDEF LSTBAS,4 ; Last base address
OFDEF DVCHR,DC.SIZ ; Table for DEVCHR to return data
OFDEF COUNT,2 ; Count of blocks printed on this line
OFSIZ IMPSIZ
FNDUFD: PHDR -1,PV$RPD,PH$REE!PH$REU
GETIMP IMPSIZ,A5 ; Get impure area (Exit if no memory)
BYP ; Bypass any blanks in the input line
LIN ; End of line?
JEQ HELP ; Yes - Tell user how to execute
CLR D6 ; Default extension is null
FSPEC DDB(A5) ; Get device and optional file name
INIT DDB(A5) ; Initialize DDB and get buffer
DEVCHR DDB(A5),DVCHR(A5) ; Get device characteristics
MOV DC.FLG+DVCHR(A5),D7
AND #DC$FSD,D7 ; Is device file structured?
JEQ NOFSD ; Branch if not
MOV DC.FLG+DVCHR(A5),D7
AND #DC$MNT,D7 ; Is device mounted?
JEQ NOMNT ; Branch if not
TYPE <Blocks marked with '*' are probably UFD blocks. >
TYPECR <Unmarked blocks may not be.>
TYPE <Reading >
MOV DC.BLK+DVCHR(A5),D1 ; Number of blocks on disk to D1
DCVT 0,OT$TRM ; print it
TYPE < blocks with >
AND #DC$14D,DC.FLG+DVCHR(A5); Clear all bits except Extended dir
BEQ 10$ ; Branch if traditional directories
TYPE <extended directories>
BR 20$
10$: TYPE <traditional directories>
20$: TYPE < for >
PFILE DDB(A5) ; Print device (and filename)
CRLF
CLRW COUNT(A5) ; Clear blocks on this line counter
MOV D.BUF+DDB(A5),A4 ; Address of buffer to A4
MOV A4,A0 ; Save buffer address
MOV #2,D.REC+DDB(A5) ; Start at block 4th block on disk
; 1st block is label
; 2nd block is 1st block of MFD
; 3rd block is 1st block of bitmap
LOOP: CTRLC ENDIT ; Exit on ^C
ADD #1,D.REC+DDB(A5) ; Increment block number
MOV D.REC+DDB(A5),D7 ; Move to D7 for compare
CMP D7,DC.BLK+DVCHR(A5) ; Are we at end of disk?
JEQ ENDIT ; Branch if yes
READ DDB(A5) ; Read a block from disk
MOV #1,LSTBAS(A5) ; Set last UFD entry was not zeroes
TST DC.FLG+DVCHR(A5) ; Extended directories?
BEQ 10$ ; Branch if not
MOV A0,A4 ; Get addr of buffer
ADD #D$NAM,A4 ; Add displacement to filename
MOVW #^H26,D2 ; Length of a UFD entry
MOVW #4,D3 ; Starting byte in the block
MOVW #12.,D4 ; Number of possible entries in UFD -1
BR 20$
10$: MOVW #12.,D2 ; Length of a UFD entry
MOVW #2,D3 ; Starting byte in the block
MOVW #41.,D4 ; Number of possible entries in UFD -1
20$: SAVE A4,D2-4 ; Save registers
30$: BCALL CHKENT ; Is this the entry we want?
BEQ 40$ ; Branch if yes
ADDW D2,D3 ; Set for displacement to next entry
DBF D4,30$ ; Decrement counter and loop
REST A4,D2-4 ; Restore registers
BR LOOP ; Not this block
40$: REST A4,D2-4 ; Restore registers
INCW COUNT(A5) ; Incremment blocks counter
CMPW COUNT(A5),#9. ; Is it time for a CR/LF?
BMI 45$ ; Branch if not
CRLF
CLRW COUNT(A5) ; Clear blocks on this line counter
45$: MOV D.REC+DDB(A5),D1 ; Block number to D1 for printing
OCVT 9.,OT$TRM!OT$ZER ; Print block number on screen
; .LOG file if task manager
MOV #1,LSTBAS(A5) ; Set last UFD entry was not zeroes
50$: BCALL CHKUFD ; Is this a valid UFD entry
BNE 60$ ; This is not a good UFD block
ADDW D2,D3 ; Set displacement to next entry
DBF D4,50$ ; Decrement counter and loop
TYPE <*> ; Indicate this is a UFD block
JMP LOOP ; Get next block
60$: TYPE < > ; Indicate this may not be a UFD block
JMP LOOP
ENDIT: CRLF
EXIT
; Check an entry in this block
CHKENT: MOV D.FIL+DDB(A5),D7 ; Filename to D7
BEQ 10$ ; Branch if no filename specified
CMP D7,0(A4)[~D3] ; Do we have a match?
BNE 90$ ; Branch if not
MOVW D.EXT+DDB(A5),D7 ; Extension to D7
CMPW D7,4(A4)[~D3] ; Do we have a match?
RTN
10$: LEA A3,EXTTBL ; Address of extensions table to A3
20$: MOVW (A3)+,D7 ; Move an extension to compare to D7
BEQ 90$ ; Branch if end of table
CMPW D7,4(A4)[~D3] ; Is this an extension we want?
BNE 20$ ; Branch if not
BCALL CHKUFD ; Is this a valid UFD entry?
RTN
90$: MOVB #-1,D7 ; Set bad indicator
RTN
CHKUFD: ; This MAY be a UFD block. Check it
TST LSTBAS(A5) ; Have we encountered a zeroes UFD?
BNE 20$ ; Branch if not before in this block
LEA A2,0(A0)[~D3] ; Get addr of start of UFD entry
MOVW D2,D7 ; Size of UFD entry to D7
SUB #1,D7 ; Set for -1 stop
10$: TSTB (A2)+ ; Is this byte 0?
DBNE D7,10$ ; End loop if not 0 or count exhausted
RTN
20$: TST DC.FLG+DVCHR(A5) ; Extended directories
BEQ 40$ ; Branch if not
MOV D$BAS(A0)[~D3],LSTBAS(A5) ; Set last bas indicator
BEQ CHKUFD ; If base is 0, entire entry must be
CALL CHKNAM ; Is this a valid filename?
BNE 90$ ; Branch if not
MOV D$BAS(A0)[~D3],D5 ; Get first block number of file
BCALL CHKBAS ; Is it valid?
BNE 90$ ; Branch if not
MOVW D$LSZ(A0)[~D3],D6 ; Get bytes in last block
BCALL CHKLSZ ; Is it valid?
BNE 90$ ; Branch if not
MOV D$FSZ(A0)[~D3],D7 ; Get file size
BCALL CHKFSZ ; Is it valid?
RTN
40$: TSTW 10.(A4)[~D3] ; Is base block 0?
BNE 45$ ; Branch if not
CLR LSTBAS(A5) ; Set zero UFD indicator
BR CHKUFD ; Validate zero entry
45$: CMPW 0(A4)[~D3],#-1 ; Check for deleted entry
BNE 50$ ; Branch if not deleted
MOVW 2(A4)[~D3],0(A4)[~D3] ; Set last half of name to first half
CLRW 2(A4)[~D3] ; Clear last half of name
50$: BCALL CHKNAM ; Is this a valid filename?
BNE 90$ ; Branch if not
CLR D5
MOVW 10.(A4)[~D3],D5 ; Get first block number of file
BCALL CHKBAS ; Is it valid?
BNE 90$ ; Branch if not
MOVW 8.(A4)[~D3],D6 ; Get bytes in last block
BCALL CHKLSZ ; Is it valid?
BNE 90$ ; Branch if not
CLR D7
MOVW 6(A4)[~D3],D7 ; Get file size
BCALL CHKFSZ ; Is it valid?
RTN
90$: MOVB #-1,D7 ; Set not found flag
RTN
; Validate first block number
CHKBAS: CMP D5,#3 ; First block must be > 2
BMI 90$ ; Branch if it is NOT
CMP D5,DC.BLK+DVCHR(A5) ; Must be < number of blocks on disk
BPL 90$ ; Branch if is is not
CLRB D6 ; Set good return flag
RTN
90$: MOVB #-1,D7 ; Set bad indicator
RTN
; Validate last block size
CHKLSZ: CMPW D6,#-1 ; Is it > -1
BLE 10$ ; Branch if not
CMPW D6,#512. ; Is < 512 bytes?
BGE 10$ ; Branch if not
CLRB D7 ; Set good return
10$: RTN
; Validate file size
CHKFSZ: CMP D7,DC.BLK+DVCHR(A5) ; Must be < number of blocks on disk
BPL 90$ ; Branch if not
TSTW D6 ; Is this a contiguous file?
BMI 20$ ; Branch if it is
10$: CLRB D7 ; Set good return
RTN
20$: ADD D7,D5 ; Add file size to starting position
CMP D5,DC.BLK+DVCHR(A5) ; Must be < number of blocks on disk
BLE 10$ ; Branch if it is
90$: MOVB #-1,D7 ; Set bad indicator
RTN
; Validate a file name
CHKNAM: CMPW 0(A4)[~D3],#-1 ; Neither RAD50 word of name can be -1
BEQ 90$
CMPW 2(A4)[~D3],#-1
BEQ 90$
LEA A2,FILNAM(A5) ; Addr of ASCII filename to A2
LEA A1,0(A4)[~D3] ; Addr of RAD50 filename to A1
UNPACK
UNPACK
SUB #6,A2 ; Reset A1 to start of filename
MOVW #5,D7 ; Character count -1 to D7
10$: MOVB (A2)+,D6 ; Move a character to D6 for compares
CMPB D6,#'. ; Is it a period?
BEQ 90$ ; Branch if yes
CMPB D6,#^H20 ; Is it a space?
BEQ 70$ ; Branch if yes
DBF D7,10$ ; Decrement counter & loop
20$: CLRB D7 ; Set good indicator
RTN
70$: DECW D7 ; Decrement counter
BMI 20$ ; Branch at end
75$: CMPB (A2)+,#^H20 ; Is this byte a space?
DBNE D7,75$ ; Fall through if not or count exhausted
RTN
90$: MOVB #-1,D7 ; Set bad indicator
RTN
HELP: TYPECR <?To execute this program you should:>
TYPECR <FNDUFD DEVn:file.ext>
TYPECR <% file.ext is optional>
EXIT
EVEN
NOFSD: TYPECR <?Device is not file structured>
EXIT
EVEN
NOMNT: TYPECR <?Device is not mounted>
EXIT
EVEN
; Table of extensions to search for
EXTTBL: WORD [A ] ; A.A
WORD [ALC] ; AlphaCALC
WORD [BAK] ; Old file from several programs
WORD [BAS] ; Basic source file
WORD [BSI] ; Basic Include source file
; WORD [BV ]
WORD [CAX] ; AlphaCALC function key table
WORD [CBJ] ; COBOL object file
WORD [CBL] ; COBOL source file
WORD [CBX] ; AlphaCOBOL function key table
WORD [CMN] ; Compiled AlphaMENU
WORD [CMD] ; Command file
WORD [CPY]
WORD [DAT] ; Data file (Usually contiguous)
; WORD [DBD]
; WORD [DBK]
WORD [DO ] ; DO command file
WORD [FOR] ; Fortran source file
WORD [HLP] ; HELP file
WORD [HLV] ; Another type of HELP file
WORD [IDA] ; ISAM data file
WORD [IDX] ; ISAM index file
WORD [INC] ; Fortran include source file
WORD [INI] ; INItialization file
WORD [JRL] ; XED journal file
WORD [JRN] ; SuperVUE journal file
WORD [L ]
WORD [LCB] ; AAI COBOL copy source file
WORD [LIB]
WORD [LIT] ; Executable code
; WORD [LSP] ; LISP program file
WORD [LST] ; Listing file
WORD [LPT] ; Computer Details Listing file
WORD [M68] ; Assembly source code
WORD [MNU] ; AlphaMENU source file
WORD [MSG] ; AAI PICS message file
WORD [OBJ] ; Assembler object file
WORD [OLD] ; Old copy of a file
; WORD [PAS] ; Pascal source file
; WORD [PCF] ; Pascal object file
WORD [POT] ; AAI Purchasing line item description
WORD [QRY] ; AlphaMENU query file
; WORD [R ]
; WORD [REN]
; WORD [RPT]
WORD [RUN] ; Basic object file
; WORD [S ]
WORD [SAV] ; Old copy of a file
WORD [SEQ] ; Data file (Usually sequential)
WORD [SBR] ; Subroutine for Basic
WORD [SUB] ; Fortran subroutine
; WORD [SV ]
WORD [SYM] ; Assembler Symbol table file
WORD [SYS] ; System subroutine
WORD [T ] ; SuperVUE word processing file
WORD [TMP] ; Temporary file
WORD [TXT] ; TXTFMT text file
WORD [UNV] ; Assembler Universal file
WORD [VUE] ; Sequential file with CR/LF
WORD [VUX] ; AlphaVUE function key table
WORD [WRT] ; AlphaWRITE word processing file
WORD [WRX] ; AlphaWRITE function key table
WORD [WSV] ; MULTI configuration file
WORD [XBR] ; Basic+ subroutine file
WORD [XUX] ; AlphaXED function key table
WORD 0
END