.title k11wld .ident -010000- ; ; This is only used for those systems which support FCS wild cards ; on RMS version 1. ; ; Calling sequence: ; ; mov #plist,r5 ; call fndfir ; Find first file-spec. ; ; call fndnxt ; Find next file-spec. ; ; plist:.word 3 ; Number of parameters ; .word chan_num ; Channel number ; .word file_name ; .ASCIZ file name string to look for ; .word result_name ; .ASCIZ file name string found. ; ; Written: 13-Sep-1985, -1.0.0-, Bruce C. Wright ; .include /K11MAC.MAC/ .iif ndf, k11inc, .error ; INCLUDE missing for K11MAC.MAC ; ; .macro save list ; .if b , ; .ift ; save ; .iff ; .irp x, ; mov x,-(sp) ; .endr ; .endc ; .endm save ; ; ; .macro unsave list ; .if b , ; .ift ; unsave ; .iff ; .irp x, ; mov (sp)+,x ; .endr ; .endc ; .endm unsave ; .mcall nboff$,fdoff$,fhdof$ .mcall fsrsz$,finit$ .mcall csi$,csi$1,csi$2 .mcall fdbdf$,fdop$a,fdop$r,fdbf$a .mcall nmblk$ .mcall qiow$s ; .macro strlen arg,?x mov arg,-(sp) mov (sp),r0 x: tstb (r0)+ bne x dec r0 sub (sp)+,r0 .endm strlen ; nboff$ def$l fdoff$ def$l fhdof$ def$l ; fsrsz$ 0 ; .psect $idata ; Ensure data .psect ; csi$ ; Define CSI symbols. ; csiblk: .blkb c.size ; Define CSI block. wldfdb: fdbdf$ ; Define wild-card FDB. fdop$a 1,csiblk+c.dsds fdbf$a wldfnb: nmblk$ ,,,SY,0 ; Default file name block dirfnb: nmblk$ 000000,DIR,,SY,0 ; Default name block for directory. numfil: .word 0 ; Number of files found. stat: .word 0,0 ; State of name block. fcs: .word 0 ; Flag for FCS initialized. dirbuf: .blkb 20. ; Buffer for current directory string. ; ; Automatic (stack) equates ; a.rat = 0 ; Read attributes buffer a.buf = 6 ; Buffer for file header a.size = 1006 ; Size of automatic area ; .psect $code ; fndfir::save ; Save registers sub #a.size,sp ; Allocate space on the stack. mov sp,r4 ; Point to it from r4 ; call inifcs strlen 4(r5) ; Find length of string to look for mov r0,r1 ; Save length in r1 clr wldfdb+f.fnb+n.stat ; Show no wild-card garbage. clr wldfdb+f.fnb+n.next ; ... clr numfil ; Also no files found yet. csi$1 #csiblk,4(r5),r1 ; Parse the "command line" bcs 90$ ; J if failed. csi$2 #csiblk,output ; Complete file string parse. bcs 90$ ; J if failed. ; mov #wldfdb,r0 ; Get wild-card FDB. fdop$r r0,2(r5) ; Set up the unit number. mov r0,r1 ; Into r1 as well. add #f.fnb,r1 ; Get wild-card FNB. mov #csiblk+c.dsds,r2 ; Get file name descriptor. mov #wldfnb,r3 ; Get default file-name block. call .parse ; Parse the file name. bcs 90$ ; J if failed the parse. ; bit #nb.svr!nb.stp!nb.snm,n.stat(r1) ; Wild cards? beq 30$ ; J if not bis #nb.svr,n.stat(r1) ; Force wild-card version 30$: mov n.stat(r1),stat ; Set up state of name block mov n.next(r1),stat+2 ; ... ; ; Now read the directory ID and return the directory information. ; mov #dirfnb,r3 ; point to directory FNB. mov n.did(r1),n.fid(r3) ; Set up directory FNB. mov n.did+2(r1),n.fid+2(r3) ; ... mov n.did+4(r1),n.fid+4(r3) ; ... mov n.dvnm(r1),n.dvnm(r3) mov n.unit(r1),n.unit(r3) ; mov r4,r1 ; Get buffer address into r1. add #a.buf,r1 ; ... mov r4,r2 ; Get statistics block into r2 add #a.rat,r2 ; ... movb #-12,(r2) ; Set up the statistics block clrb 1(r2) ; ... mov r1,2(r2) ; ... clr 4(r2) ; ... qiow$s #io.rat,2(r5),#1,,,, bcs 90$ ; J if error of some kind. ; ; File header is now in the buffer pointed to by (r1). Now set up ; the directory string... ; mov #dirbuf,r0 ; Get directory buffer movb #'[,(r0)+ ; ... movb h.idof(r1),r3 ; Get ID offset in header asl r3 ; Convert to byte offset add r1,r3 ; Point to header from (r3). mov i.fnam(r3),r1 ; Get file name call $c5ta ; Convert to ASCII call uicprt ; Pretty up the UIC movb #',,(r0)+ ; Output a , mov i.fnam+2(r3),r1 ; Get second part of file name call $c5ta ; Convert to ASCII call uicprt ; Pretty up the UIC movb #'],(r0)+ ; Output a ] to end directory clrb (r0)+ ; End it with a 0 for .asciz ; ; Now we call fndnxt to find the first file with these attributes ... ; call fndnxt ; Call the find-next routine to get them br 99$ ; And return. ; 90$: mov #er$fnm,r0 ; Show file name error. 99$: add #a.size,sp ; Free up space on stack. unsave ; Recover registers return ; And return. ; ; FNDNXT -- Find next file with the indicated specifications. ; ; Only one file search is allowed at a time because this ; routine keeps information on the context in its static ; storage. ; ; Arguments: ; ; see fndfir. ; fndnxt::save ; Save registers call inifcs ; Initialize FCS mov #wldfdb+f.fnb,r1 ; Point at the File-Name block. bit #nb.svr!nb.stp!nb.snm,n.stat(r1) ; Wild cards? bne 10$ ; J if wild-card. tst numfil ; Found any files yet? beq 10$ ; J if not - handle normally. mov #er$nmf,r0 ; Show no more files. br 99$ ; And leave. ; 10$: mov #wldfdb,r0 ; Get wild-card FDB. mov stat,n.stat(r1) ; Reset name block mov stat+2,n.next(r1) ; ... 15$: call .find ; Get another file-name. bcs 80$ ; J if error of some kind. bit #nb.svr!nb.stp!nb.snm,n.stat(r1) ; Wild cards? beq 20$ ; J if not. cmp n.next(r1),stat+2 ; Same file? beq 15$ ; J if so - try again mov n.stat(r1),stat ; Set up state of name block mov n.next(r1),stat+2 ; ... 20$: inc numfil ; Count number of files found. mov 6(r5),r0 ; Get address of return string. movb wldfdb+f.fnb+n.dvnm,(r0)+ ; Get device name movb wldfdb+f.fnb+n.dvnm+1,(r0)+ ; mov wldfdb+f.fnb+n.unit,r1 ; Get device unit clr r2 ; Suppress leading 0's call $cbomg ; Convert to ASCII movb #':,(r0)+ ; put in the : mov #dirbuf,r1 ; Get directory buffer. 30$: movb (r1)+,(r0)+ ; Output directory bne 30$ ; ... dec r0 ; Backup over the 0 just moved. mov wldfdb+f.fnb+n.fnam,r1 ; Get file name call $c5ta ; Convert to ASCII mov wldfdb+f.fnb+n.fnam+2,r1 ; ... call $c5ta ; ... mov wldfdb+f.fnb+n.fnam+4,r1 call $c5ta ; 40$: cmpb #' ,-(r0) ; Find the last blank. beq 40$ ; ... inc r0 ; Skip the non-blank. movb #'.,(r0)+ ; Put in . for file-type. mov wldfdb+f.fnb+n.ftyp,r1 call $c5ta ; 50$: cmpb #' ,-(r0) ; Pretty up the file type too beq 50$ ; ... inc r0 ; movb #';,(r0)+ ; Put in ; for file version. mov wldfdb+f.fnb+n.fver,r1 ; Get file version # clr r2 ; Show 0 suppress. call $cbomg ; Convert to ASCII clrb (r0)+ ; Plant a 0 to show end of string. mov #su$suc,r0 ; Show success. br 99$ ; And leave. ; 80$: cmpb f.err(r0),#ie.nsf ; No such file error? bne 90$ ; J if not, some kind of fatal error. mov #er$nmf,r0 ; Show no more files. tst numfil ; Were any files ever found? bne 99$ ; J if so, take that as the error. mov #er$fnf,r0 ; Otherwise show never found. br 99$ ; And leave. 90$: mov #er$fnm,r0 ; Show internal error of some kind. ; 99$: unsave ; Recover registers return ; And return. ; ; Internal subroutine to initialize FCS if needed. ; inifcs: tst fcs ; Is FCS initialized? bne 90$ ; J if so. finit$ ; Init FCS inc fcs ; Show FCS is initialized. 90$: return ; And return. ; ; Internal subroutine to pretty up a UIC ; uicprt: cmpb -3(r0),#'0 ; Is the first character a 0? bne 80$ ; J if not movb -2(r0),-3(r0) ; Yes, fix it up movb -1(r0),-2(r0) ; dec r0 ; Show reduced one digit cmpb -2(r0),#'0 ; Is the first character now a 0? bne 80$ ; J if not. movb -1(r0),-2(r0) ; Yes, fix it up too dec r0 ; Adjust pointer 80$: return ; And return. ; .end