**** SD -- Sorted Directory ** ** ** Sorted Directory Program ** ** by ** James M. Knox ** TriSoft ** ** (C) 1983 by TriSoft ** ** modified 14Feb85 jmk /fixed for high TPA/ ** ** ** Function: ** Print sorted directory to CON: or disk file. ** Inputs: ** Command line of the form: ** ** SD [filespec] [-optionlist] [>outfilespec] ** ** where ** filespec == description of files to be listed ** ** optionlist == list of options selected ** ** -F == display file flags (R*eadonly) ** (S*ystem file) ** (A*rchived) ** ** -S == (don't) display system files ** ** -K == (don't) display file size ** ** note: option list may be combined or separate, and ** may use $ instead of - for indicator. ex) ** ** SD -S -F -K ** SD -SFK ** SD $SF -K ** all perform the same function. ** ** outfilespec == output is written to disk file rather ** than to CON: ** .globl endjob .globl crlf .globl cout .globl sort .globl cmpa12 .globl md5dc .globl optscn * cr equ 13 * carriage return lf equ 10 * line feed * .text ** initialize * sd: clr tblcnt * clear table count clr filcnt * clear file count move.l #table,tblptr * move.l #secb,d1 * set DMA pointer move #26,d0 trap #2 * move #$19,d0 trap #2 * get current disk # ext.w d0 move d0,curdsk * move.l 4(a7),bpage move.l 4(a7),d0 addi.l #$81,d0 move.l #opttbl,d1 move.l #fcb,d2 clr.l d3 * no input re-direct move.l #outfcb,d4 * output fcb move.b #$ff,outfcb * set to default jsr optscn * scan command line tst.l d1 beq endjob * if errors found, abort move.b #'?',fcb+12 * get all extents * * ** get first DIR entry * move.l #fcb,d1 move #17,d0 trap #2 bra gtnxt1 * ** get next DIR entry * gtnext: move.l #fcb,d1 move #18,d0 trap #2 gtnxt1: cmpi.b #$ff,d0 * check for last beq dsort * andi.l #3,d0 * compute ptr to entry rol #5,d0 addi.l #secb+1,d0 moveq #11,d1 * eleven characters in name move.l d0,a0 * plus extent move.l tblptr,a1 tst.b sflag bne gtnxt2 * wants all files btst #7,9(a0) * test system bit bne gtnext * skip if system file gtnxt2: move.b (a0)+,(a1)+ dbra d1,gtnxt2 * loop for file name * gtnxt3: move.b 2(a0),(a1)+ * pick up size addq #1,a1 move.l a1,tblptr addq #1,tblcnt jmp gtnext * ** sort table * dsort: * tst tblcnt * check for empty directory beq nofil * plum clean * move.l #ssbtbl,d1 move.w tblcnt,ssbtbl+4 jsr sort * sort names * move.l #table,a0 move tblcnt,a1 jsr prtbl jmp endjob * ** no files found * nofil: move.l #mnofil,d1 * print message moveq #9,d0 trap #2 jmp endjob * * ** print table * * A0 = table pointer * A1 = # of entries * prtbl: move.b outfcb,d1 cmpi.b #$ff,d1 beq prtbl0 * no output file spec * movem.l a0-a1,-(a7) move.l #outbuf,a0 move #31,d0 opof1: move.l #$1a1a1a1a,(a0)+ * clear buffer dbra d0,opof1 move.l #outfcb,d1 move #$13,d0 * delete existing file trap #2 move.l #outfcb,d1 move #$16,d0 * make new file trap #2 cmpi.b #3,d0 bgt sdperr * error opening file move.l #outbuf,d1 move #$1a,d0 trap #2 * set dma to OUTBUF movem.l (a7)+,a0-a1 * prtbl0: move.b fcb,d1 beq prtbl1 * if default drive chosen ext.w d1 subq #1,d1 move #$0e,d0 trap #2 * select disk prtbl1: move.l #secb,d1 move #$1f,d0 trap #2 * get disk parameter table move.b secb+3,d0 * get block mask ext.w d0 move d0,blm move.b secb+4,d0 ext.w d0 move d0,exm tst.b fcb beq prtbl2 * default, no need to reset move curdsk,d1 move #$0e,d0 trap #2 * re-select default prtbl2: * move #6,fplin * files per line move.b kflag,d1 * check for options add.b fflag,d1 cmpi.b #0,d1 beq prtbl8 * no display options addq.b #1,d1 ext.w d1 sub d1,fplin * prtbl8: clr nflin * # of files on line clr totsiz clr fcount * prnxt: clr fsize * files size prnxt0: move.b 12(a0),d2 * fsize=fsize+reccnt andi #$00ff,d2 move blm,d3 * block mask size add d3,d2 not d3 and d3,d2 ext.l d2 ror.l #3,d2 * convert to k-bytes add d2,fsize clr d3 move.b 11(a0),d2 * extent mask and exm,d2 prnx00: beq prnx01 * if end of extent overflows addi #16,d3 subq #1,d2 bra prnx00 prnx01: add d3,fsize * add overflow moveq #10,d0 * compare file names move.l a0,a2 move.l a0,a3 add.l #14,a3 prnxt1: cmpm.b (a0)+,(a3)+ bne prnxt2 * if no match dbra d0,prnxt1 * loop for 11 characters move.l a2,a0 * restore pointer to fcb subq #1,a1 * one less entry add #14,a0 * move to next fcb bra prnxt0 * prnxt2: addq #1,fcount * bump file count (names dont match) move fsize,d2 * totsiz=totsiz+fsiz add d2,totsiz movea.l #prbuf,a3 move.l a2,a0 * restore pointer to fcb move (a0)+,(a3)+ move (a0)+,(a3)+ move (a0)+,(a3)+ move (a0)+,(a3)+ addq #1,a3 move.b (a0)+,(a3) move.b (a3),fcb+1 bclr.b #7,(a3)+ move.b (a0)+,(a3) move.b (a3),fcb+2 bclr.b #7,(a3)+ move.b (a0)+,(a3) move.b (a3),fcb+3 bclr.b #7,(a3)+ cmpi.b #0,kflag beq prnxt3 * if size not wanted move.l a3,d0 * buffer move fsize,d1 * size in 128 byte recs ext.l d1 jsr md5dc * put number in buffer move.l d0,a3 move.b #$20,(a3)+ * add blank * prnxt3: cmpi.b #0,fflag * if no flags wanted beq prnxt7 * if no flags wanted * move.l #' ',(a3)+ * second blank and flags subq.l #3,a3 move.l #fcb+1,a4 * first ext. char btst.b #7,(a4)+ * check read-only flag beq prflg2 * nope, its r/w move.b #'R',(a3) prflg2: addq.l #1,a3 btst.b #7,(a4)+ beq prflg3 * not a system file either move.b #'S',(a3) prflg3: addq.l #1,a3 btst.b #7,(a4) beq prflg4 * hasn't been archived move.b #'A',(a3) prflg4: addq.l #1,a3 move.b #' ',(a3)+ move.b #' ',(a3)+ * * * prnxt7: move.b #$20,(a3)+ * add final blank move.b #$24,(a3)+ * add $ terminator move.l prbuf+2,d1 andi.l #$7f7f7f7f,d1 * clear flags move.l d1,prbuf+2 * move.l a2,a0 * restore pointer again move.l #prbuf,d1 * print file name movem.l a0-a1,-(a7) jsr sdout * print to CON: or file movem.l (a7)+,a0-a1 move nflin,d2 * at end-of-line? addq #1,d2 move d2,nflin cmp fplin,d2 bne prnxt8 * go get next one * clr nflin * at EOL bsr crlfx * prnxt8: add #14,a0 * bump to next file subq #1,a1 * at end of files? move.l a1,d0 bne prnxt * not yet * tst nflin * at end of line beq prnxt9 * yes, don't need crlf bsr crlfx * one last cr lf * prnxt9: move.b fcb,d1 bne pfm1 * if not default move curdsk,d1 addq #1,d1 pfm1: subq #1,d1 move d1,-(a7) * save disk move #$2e,d0 move.l outbuf,d6 * save outbuf first word trap #2 * get free space move.l secb,d1 * free sectors move.b outfcb,d0 cmpi.b #$ff,d0 beq pfm2 * output to CON: move.l outbuf,d1 * the free space value was written move.l d6,outbuf * to outbuf, not secb. pfm2: ror.l #3,d1 * convert to k move.l #mfre,d0 andi #$7fff,d1 jsr md5dc * free space * move (a7)+,d0 addi.b #'A',d0 move.b d0,mdrun * drive # * move #$20,d0 move.l #$ff,d1 trap #2 * get user number move.l d0,d1 move.l #secb,d0 jsr md5dc * convert to text move.b secb+3,musrn * and move last two digits move.b secb+4,musrn+1 * move.l #mfsz,d0 move totsiz,d1 ext.l d1 jsr md5dc * total file size * move.l #mfcnt,d0 move filcnt,d1 jsr md5dc * total # of files * move.l #endm,d1 * print ending msg jsr sdout * print to CON: or file move.b outfcb,d0 cmpi.b #$ff,d0 beq pfm8 * CON: output, no problem move.b outbuf,d1 cmpi.b #$1a,d1 beq pfm6 * buffer is empty move.l #outfcb,d1 move #$15,d0 trap #2 tst.b d0 * write o.k.? bne sdperr * nope pfm6: move.l #outfcb,d1 move #$10,d0 trap #2 * close file cmpi.b #3,d0 bgt sdperr * error closing file pfm8: * rts * * sdout: * print (D1.L) to CON: or file move.b outfcb,d0 cmpi.b #$ff,d0 bne sdoutc * not console output moveq #9,d0 trap #2 rts * sdoutc: * write is to a file move.l d1,a1 * pointer to msg sdotc1: move.b (a1)+,d0 * get char cmpi.b #'$',d0 beq sdoutx * if end of string bsr sdpout * put char in d0.b bra sdotc1 * sdoutx: rts * sdpout: * write char in d0.b to file movem.l a0-a1,-(a7) move.l outbfp,a0 move.b d0,(a0)+ move.l a0,outbfp * cmpa.l #outbuf+128,a0 beq sdp2 * end of buffer sdpx: movem.l (a7)+,a0-a1 rts * sdp2: * write buffer move.l #outbuf,outbfp move.l #outfcb,d1 moveq #$15,d0 * write sequential trap #2 tst.b d0 beq sdp3 * good write sdperr: move.l #errwf,d1 * error writing file moveq #9,d0 trap #2 bra endjob * sdp3: * clear new buffer move.l #outbuf,a0 move #31,d0 sdp4: move.l #$1a1a1a1a,(a0)+ dbra d0,sdp4 bra sdpx * * crlfx: movem.l a0-a1,-(a7) move.l #crstr,d1 bsr sdout movem.l (a7)+,a0-a1 rts * * .data fcb: .dc.b 0,'????????????',0,0,0 .dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .dc.b 0,0,0,0 outfcb: .dc.b 0,'DIRLIST LIS',0,0,0,0 .dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .dc.b 0,0,0,0 * mnofil: .dc.b cr,lf,'No files',cr,lf,'$',0 errwf: .dc.b cr,lf,' Error writing output file.',cr,lf,'$' * prbuf: .dc.l 'xxxxxxxx.xxxnnnnn ars $' * file name prbfe equ prbuf+9 * crstr: .dc.b cr,lf,'$',0 endm: .dc.b ' Drive ' * ending SD message mdrun: .dc.b 'x, user ' musrn: .dc.b 'nn, contains' mfsz: .dc.b 'nnnnnk in ' mfcnt: .dc.b 'nnnnn files with' mfre: .dc.b 'nnnnnk free.',cr,lf,'$' * * bpage: .dc.l 0 * base page address outbfp: .dc.l outbuf * output buffer pointer curdsk: .dc.w 0 * current default disk blm: .dc.w 0 * block mask size exm: .dc.w 0 * extent mask * ssbtbl: .dc.l table * start of records .dc.w 1 * number of records .dc.w 14 * size of records .dc.l cmpa12 * compare ascending .dc.l 0 .dc.b 0 .dc.b 0 * ** options table * opttbl: .dc.b 'F',0 * Flags .dc.b 'K',1 * size .dc.b 'S',0 * system files .dc.b 0,0 * termination fflag: .equ opttbl+1 * flag print option kflag: .equ fflag+2 * size print option sflag: .equ kflag+2 * system file option * * .bss tblcnt: .ds.w 1 * table count filcnt: .ds.w 1 * file count fcount .equ filcnt fplin: .ds.w 1 * number of files per line nflin: .ds.w 1 * number of files currently on line fsize: .ds.w 1 * size of current file totsiz: .ds.w 1 * total size of all files secb: .ds.l 32 * sector buffer outbuf: .ds.l 32 * output buffer tblptr: .ds.l 1 * table pointer table: .ds.l 13000 * actual file table (12 bytes/entry) * * .end