PAGE
;************
;* W.INIT *
;************
;Function: Allocate local memory for other WLDSCN calls
;
;Outputs: A4 - set to base of impure area MEM:WLDSCN.IMP
PAGE
;************
;* W.SPEC *
;************
;Function: Process wildcard file specification
;
;Inputs: A2 - address of file specification
; A4 - address of work area (normally set-up by W.INIT)
;
;Outputs: Z - set if specification is valid, -or- cleared if invalid
; A2 - updated past file specification
W.SPEC: POP A6 ;
MOV (A6)+,WS.DFX(A4) ;
PUSH A6 ;
CLR WS.FLG(A4) ; clear flags
CMPB @A2,#'- ; leading dash? [1.1]
BNE 10$ ; no [1.1]
OR #WS$NOT,WS.FLG(A4) ; yes - set NOT flag [1.1]
INC A2 ; bypass dash [1.1]
BYP ; bypass white space [1.1]
10$: CALL DEFDEV ; set default device
CALL CHKDEV ; device specified?
CEQ GETDEV ; yes - get device
CALL DEFFIL ; set default filename
CALL DEFPPN ; set default PPN
CALL CHKPPN ;
CEQ GETPPN ;
CALL CHKFIL ; filename specified?
CEQ GETFIL ; yes - get filename
CALL DEFEXT ; set default extension
CALL CHKEXT ; extension specified?
CEQ GETEXT ; yes - get extension
CALL CHKPPN ; PPN specified?
CEQ GETPPN ; yes - get PPN
CALL CHKRED ; redirection present? [110]
BNE 20$ ; no [110]
CALL GETRED ; shift input specs to output [110]
BR 10$ ; go get input specs again [110]
20$: CALL INIMEM ; initialize impure area
CALL ERROR ; display errmsg if required
RTN ;
;************
;* NXTFIL *
;************
;Function: Return next file from UFD
; Automatically redirect if {output=input} was present in
; command line
NXTFIL: SAVE A0 ; save registers
NF.LOP: TSTW WS.RFN(A4) ; is remaining file count zero?
JEQ NF.ERR ; yes
DECW WS.RFN(A4) ; decrement remaining file count
MOV WS.UFI(A4),A0 ; get UFD index
BIT #WS$EXD,WS.FLG(A4) ; extended directory? [108]
BNE NF.EXT
; yes [108]
;traditional directory structure
NF.TRA: ADD #UF.SIZ,WS.UFI(A4) ; add UFD size to index
TSTW UF.FIL(A0) ; end of UFD?
JEQ NF.ERR ; yes
BIT #WS$DEL,WS.FLG(A4) ; do we want deleted files?
BNE 10$ ; yes
CMPW UF.FIL(A0),#-1 ; deleted file entry? [1.6A]
BEQ NF.LOP ; yes - go get next one
CALL MATFIL ; matching file specification?
BNE NF.LOP ; no - go get next one
10$: MOV UF.FIL(A0),WS.DDB+D.FIL(A4);
MOVW UF.EXT(A0),WS.DDB+D.EXT(A4);
MOVW UF.BLK(A0),WS.DDB+D.WRK+2(A4);
MOVW UF.ACT(A0),WS.DDB+D.WRK+6(A4);
MOVW UF.LNK(A0),WS.DDB+D.WRK+12(A4);
CLR WS.DDB+D.DVR(A4) ; [113]
LCC #PS.Z ; set Z (file returned)
BR NF.RTN ; return
;extended directory structure
NF.EXT: ADD #D$SIZ,WS.UFI(A4) ; add UFD size to index [108]
ADD #D$NAM,A0 ; point to file information [108]
MOVW UF.FIL(A0),D7 ; end of UFD? [108]
BEQ NF.ERR ; yes [108]
BIT #WS$DEL,WS.FLG(A4) ; do we want deleted files?
BNE 10$ ; yes
MOVW D$TYP-D$NAM(A0),D7 ; [114]
ANDW #100000,D7 ; deleted file entry? [114]
JNE NF.LOP ; yes - go get next one [114]
MOVW UF.FIL(A0),D7 ;
CMPW D7,#-1 ; deleted file entry? [108]
JEQ NF.LOP ; yes - go get next one [108]
CMPW D7,#[$ ] ; is this a hidden file? [108]
JEQ NF.LOP ; yes - go get next one [108]
CMPW D7,#[$$ ] ; is this a hidden file? [108]
JEQ NF.LOP ; yes - go get next one [108]
CALL MATFIL ; matching file specification? [108]
JNE NF.LOP ; no - go get next one [108]
10$: MOV UF.FIL(A0),WS.DDB+D.FIL(A4); [108]
MOVW UF.EXT(A0),WS.DDB+D.EXT(A4); [108]
SUB #D$NAM,A0 ; [108]
MOV D$FSZ(A0),WS.DDB+D.WRK(A4); [108]
MOVW D$LSZ(A0),WS.DDB+D.WRK+6(A4); [108]
MOV D$BAS(A0),WS.DDB+D.WRK+10(A4); [108]
CLR WS.DDB+D.DVR(A4) ; [113]
LCC #PS.Z ; set Z (file returned) [108]
BR NF.RTN ; return [108]
NF.ERR: LCC #0 ; clear Z (end of UFD)
NF.RTN: REST A0 ; restore registers
RTN ; return
;************
;* MATFIL *
;************
;Function: Check for matching file specification
;
;Inputs: A0 - address of 6-word UFD file information
;************
;* NXTUFD *
;************
;Function: Return next UFD block
NXTUFD: SAVE A0,D0 ; save registers
CTRLC NU.ERR ; ^C check
TST WS.UFL(A4) ; check link
BEQ NU.ERR ; end of user file directory chain
MOV WS.UFL(A4),WS.DDB+D.REC(A4); set block number
PUSH WS.DDB+D.BUF(A4) ; push buffer address
LEA A0,WS.UFB(A4) ; change buffer address
MOV A0,WS.DDB+D.BUF(A4) ; to UFD buffer
CLR WS.DDB+D.DVR(A4) ; clear driver address [1.6]
READ WS.DDB(A4) ; read UFD block
POP WS.DDB+D.BUF(A4) ; restore buffer address
CLR D0 ; get
BIT #WS$EXD,WS.FLG(A4) ; extended directory structure? [108]
BNE NU.EXT ; yes
;traditional directory structure
NU.TRA: MOVW (A0)+,D0 ; link
MOV D0,WS.UFL(A4) ; store link
MOVW #42.,WS.RFN(A4) ; set number of files to be processed
MOV A0,WS.UFI(A4) ; set UFD index
LCC #PS.Z ; set Z
BR NU.RTN ; return
;extended directory structure
NU.EXT: MOV (A0)+,WS.UFL(A4) ; store link
MOVW #<512.-4>/D$SIZ,WS.RFN(A4); set number of files to be processed
MOV A0,WS.UFI(A4) ; set UFD index
LCC #PS.Z ; set Z
BR NU.RTN ; return
;************
;* NXTDEV *
;************
;Function: Find next mounted disk in device table & setup for processing
;
;Sets or clears WS$EXD bit to flag extended or traditional directory format
AND #^C<WS$EXD>,WS.FLG(A4) ; clear extended flag [108]
BITW #DV$14D,DV.FLG(A0) ; extended directory? [108]
BEQ 32$ ; no [108]
OR #WS$EXD,WS.FLG(A4) ; set extended flag [108]
32$:
NM.TRA: CLR D0 ; get
MOVW MF.LNK(A0),D0 ; MFD link
MOV D0,WS.MFL(A4) ; set link to next MFD block
LEA A0,WS.MFB(A4) ; set MFD
MOV A0,WS.MFI(A4) ; index
MOVW #63.,WS.RPN(A4) ; set remaining PPN count
LCC #PS.Z ; set Z
BR NM.RTN ; return
;extended directory structure
;A0 indexes buffer
NM.EXT: MOV (A0)+,WS.MFL(A4) ; store link to next block [108]
MOV A0,WS.MFI(A4) ; set MFD index [108]
MOVW #<512.-4>/D$SIZ,WS.RPN(A4); set remaining PPN count [108]
LCC #PS.Z ; set Z [108]
BR NM.RTN ; return [108]
NM.ERR: LCC #0 ;
NM.RTN: REST A0,D0 ;
RTN ;
;************
;* NXTPPN *
;************
;Function: Return next PPN of MFD
;
;Outputs: Z - 0 if end of this MFD block
NXTPPN: SAVE A0,D0,D5 ; save registers [108]
NP.LOP: TSTW WS.RPN(A4) ; is remaining PPN count zero?
BEQ NP.ERR ; yes
DECW WS.RPN(A4) ; decrement remaining PPN count
MOV WS.MFI(A4),A0 ; get MFD index
BIT #WS$EXD,WS.FLG(A4) ; extended directory structure? [108]
BNE NP.EXT ; yes [108]
;traditional directory structure
NP.TRA: ADD #MF.SIZ,WS.MFI(A4) ; add size of traditional MFD entry
MOVW MF.PPN(A0),D5 ; is this the end of the MFD? [108]
BEQ NP.ERR ; yes
CMPW D5,#-1 ; deleted PPN? [111]
BEQ NP.LOP ; yes - skip it [111]
CALL MATPPN ; matching PPN?
BNE NP.LOP ; no - go try next PPN
CLR D0 ; get
MOVW MF.UFD(A0),D0 ; UFD pointer
BEQ NP.LOP ; [113]
MOV D0,WS.UFL(A4) ; store UFD pointer
MOVW #42.,WS.RFN(A4) ; set remaining file count
MOVW MF.PPN(A0),WS.DDB+D.PPN(A4); set PPN into DDB
LCC #PS.Z ; set Z
BR NP.RTN ; return
;extended directory structure
NP.EXT: ADD #D$SIZ,WS.MFI(A4) ; add size of MFD entry [108]
MOVW D$NAM(A0),D5 ; is this the end of the MFD? [108]
BEQ NP.ERR ; yes [108]
CMPW D5,#-1 ; deleted PPN? [108]
BEQ NP.LOP ; yes - ignore it [108]
CALL MATPPN ; matching PPN? [108]
BNE NP.LOP ; no - go try next PPN [108]
MOV D$NXT(A0),D0 ; get UFD pointer [108]
MOV D0,WS.UFL(A4) ; store UFD pointer [108]
MOVW #<512.-4>/D$SIZ,WS.RFN(A4); set remaining file count [108]
MOVW D$NAM(A0),WS.DDB+D.PPN(A4); set PPN into DDB [108]
LCC #PS.Z ; set Z [108]
BR NP.RTN ; return [108]
;************
;* MATPPN *
;************
;Function: Determine if current PPN entry in MFD matches specification
; Traditional file structure
;
;Inputs: D5 - current PPN
;
;Outputs: Z - set if we have a match
MATPPN: SAVE A2-A3,D0-D1,D5 ; save registers
CLR D1 ; get
RORW D5,#8. ; [108]
MOVB D5,D1 ; programmer number [108]
LEA A2,WS.TMP(A4) ; index buffer
MOVB #40,WS.TMP+1(A4) ; load w/
MOVB #40,WS.TMP+2(A4) ; spaces
OCVT 0,OT$MEM ; output as an octal number
LEA A2,WS.PRG(A4) ; index programmer number spec
LEA A3,WS.TMP(A4) ; index current programmer number
CALL 30$ ; compare
BNE 10$ ; no match
ROLW D5,#8. ; move project into low byte [108]
CLR D1 ; [108]
MOVB D5,D1 ; get project number [108]
LEA A2,WS.TMP(A4) ; index buffer
MOVB #40,WS.TMP+1(A4) ; load w/
MOVB #40,WS.TMP+2(A4) ; spaces
OCVT 0,OT$MEM ; output as an octal number
LEA A2,WS.PRJ(A4) ; index project number spec
LEA A3,WS.TMP(A4) ; index current project
CALL 30$ ; compare
BNE 10$ ; no match
30$: MOV #3,D0 ; max count is three
40$: CMPB (A2)+,(A3)+ ; match? [1.6A]
BNE 60$ ; no
50$: SOB D0,40$ ; loop
LCC #PS.Z ; set Z - we have a match
RTN ; return
60$: CMPB -1(A2),#'? ; wildcard? [1.6A]
BEQ 50$ ; yes
LCC #0 ; clear Z - no match
RTN ; return
PAGE
;************
;* W.LIST *
;************
;Function: Return list of matching file specifications
;
;Inputs: A4 - must have been pre-indexed by W.INIT and W.SPEC calls
; A0 - must index table to return list in
; D0 - must contain maximum number of files table can hold
;
;Outputs: A0 - unchanged
; D0 - contains number of filenames returned
PAGE
;***********
;* W.DEL *
;***********
;Function: Set WS$DEL flag, which returns all files (even deleted ones)
; in each account.
W.DEL: OR #WS$DEL,WS.FLG(A4) ;
RTN ;
PAGE
;***********
;* W.OUT *
;***********
;Function: Transform WS.DDB(A4) as per output redirection specification
; Normally, this call immediately follows a W.SCAN call
;
;Inputs: A4 - pointer to wildcard scanner impure area
;
;Outputs: Z - set if output redirection was specified and performed
; WS.DDB(A4) - modified appropriately
W.OUT: BIT #WS$OUT,WS.FLG(A4) ; was redirection specified?
BEQ W.ONR ; no
SAVE A0-A2,D0-D2 ; save registers
CALL REDDEV ; redirect device
CALL REDDRV ; redirect drive
CALL REDFIL ; redirect filename
CALL REDEXT ; redirect extension
CALL REDPRG ; redirect programmer number
CALL REDPRJ ; redirect project number
REST A0-A2,D0-D2 ; restore registers
LCC #PS.Z ; set Z (redirection performed)
RTN ; return
W.ONR: LCC #0 ; no redirection
RTN ; return
LEA A0,WS.OFL(A4) ; index output filename
LEA A1,WS.TMP(A4) ;
MOV #6.,D2 ;
20$: MOVB (A0)+,D0 ; get char of output spec
BEQ 40$ ; end of filename
MOVB @A1,D1 ; get original filename char [112]
CMPB D0,#'? ; wildcard in redirected spec? [112]
BNE 30$ ; no [112]
MOVB D1,D0 ; yes - use original character[112]
30$: MOVB D0,(A1)+ ; set new char in filename [112]
SOB D2,20$ ; loop till done
40$: CLRB @A1 ; end of string