þþ8èEIòX; üX;DIRT SOURCE CODE X; X; †PROTCT;; Protected bit $†HIDDEN;; Hidden bit .†ARCHIV;; Archived bit 8!†SUBDIR ;; Subdirectory bit B!†DEFRAG@;; Defragmented bit L$ƒEOL›;; set end of line marker V/†COMTAB ;; where to look for Sparta stuff `„CIOVVä;; CIO Vector j …INDEXÐt.†BRKKEY;; Break key location, 0=pressed ~X; ˆ,P;; get it up real high so it doesn't ’'!…START;; interfere with anything. œX; ¦†NUMBUF Aˆ00000000A°X; º…DVEND ==Ä Î ƒDLP ØX; â …POINT ì †POINT2 öX; X; #…VALID A A======= ==A‚*+A==A‚-.A=# A‹0123456789:A==A?A( =AABCDEFGHIJKLMNOA2# A‹PQRSTUVWXYZA==A\A===< =AABCDEFGHIJKLMNOAF! A‹PQRSTUVWXYZA=====PX; Z †HEADERd& ƒEOL=ƒEOL=ADIRT Version 1.0A=ƒEOLn1 A Copyright 1990 Charles K. HughesA=ƒEOL=ƒEOLx A‹Volume: A‚ †VOLBUFŒ Aˆ A=ƒEOL– A‹Directory: A  †DIRBUFª Aˆ A=ƒEOL=ƒEOL´„PRFS A Free SectorA¾†FRESCT Aˆs: 00000A=ƒEOLÈX; Ò„HLEN„PRFS†HEADERÜX; æ…FNAME A . Að…FATTR A†..... Aú„FLEN A‰ AƒFMM Aƒ -AƒFDD Aƒ -AƒFYY A‚ A=ƒEOL"X; , …ENTRY6„STAT ==@ƒLEN ==J„NAME A‹ AT„DATE =====^„DMIX ==hX; r#…COUNT ;; position into lbuff |.…LBUFF@;; command line buffer (64 bytes) † …DFLAG  †DEVICE AƒDD:A;; device name š„PATH Aƒ*.*A=ƒEOL¤$;; pathname ®X; ¸…FMASK A‹???????????AÂX; Ì.…SFLAG ;; Previous char was a space flag Ö…NFLAG ;; NOT flag à%…IFLAG ;; Invalid filename flag ê'†ATTRIB ;; Attribute compare byte ô&…ATYPE ;; type of attribute mask þ4…FSECT ==;; number of free sectors on disk X; X; Start of program X; &*X; Close IOCB #7 (Of course I cheat! :)0X; : …STARTD †CLOSE7NX; X.X; Copy command line buffer to DIRT buffer bX; l4Q†COMTAB;; Get index to the SpartaDOS command vP…INDEX;; line buffer € Q†COMTABŠ,”O>?žDƒONE¨ #…INDEX²ƒONE¼ P…INDEXÆX; ÐX; Do the copy and: Ú:X; skip the file name of the command & first space ä(X; make all lowercase into upper î8X; set NOT flag if an exclamation point is found ø"X; delete all extra spaces X; .%>;; Start at beginning of Sparta buffer 5'…COUNT;; and at the beginning of the DIRT buffer ƒTWO* Q@…INDEX74!R>ƒEOL;; look for end of line >H‚T1H #…DFLAGR !ˆCOM_EXIT\‚T1fR> ;; look for first space pFƒPT3z3„1)>@;; check for end of buffer, error if yes. ŽHƒTWO˜%>þ¢:¬X; ¶X; ÀX; ʃPT3Ô #…SFLAGÞ …THREEè'3;; increment to the next character ò Q@…INDEX7ü$R>ƒEOL;; if at end of line, exit  F„EXIT "R> !;; look for the NOT option  H„FIVE$ Q>. P…NFLAG;; set the nflag = ! 8 +I…THREE;; always jump to next character B „FIVEL R> ;; if <$20 V E‚F1;; then ERROR ` %>ýj :t ‚F1~ Q@…INDEX7;; if >=$80 ˆ I‚F2;; then ERROR ’ %>üœ :¦ ‚F2° ,>;; else use character as index into the º #Q…VALID 9;; translation table Ä -H‚F3;; if the character doesn't translate Î %>ü;; then ERROR Ø :â ‚F3ì '$…COUNT;; get the DIRT buffer count ö !P…LBUFF9;; save the character !#…COUNT;; increment the count *R> ;; check to see if this is a space  FƒSIX Q>;; not a space, so reset ( P…SFLAG;; the space flag 2 F…THREE;; and always branch < ƒSIXF /$…SFLAG;; check to see if previous char was P 'H…SEVEN;; a space, branch if it was Z #…SFLAG;; set sflag d H…THREE;; always branch n …SEVENx !"…COUNT;; delete second space ‚ 0I…THREE;; always branch, if count = negative Œ )%>ð;; then it is an error anyway. :) – :  X; ª X; Look for switches ´ X; ¾ „EXITÈ $…COUNTÒ P…LBUFF9Ü H‚N0æ #…DFLAGð !ˆCOM_EXITú ‚N0 %> Q> $…LBUFF" (> +, F…EIGHT6 (> -@ H„NINEJ …EIGHTT &…ATYPE^ ƒATEh 3r $…LBUFF8| (> P† H‚N1 !N>†PROTCT;; Bit 0 = protected š ‚N1¤ (> H® H‚N2¸ N>†HIDDEN;; Bit 1 = Hidden  ‚N2Ì (> AÖ H‚N3à N>†ARCHIV;; Bit 2 = Archived ê ‚N3ô (> Sþ H‚N4 N>†SUBDIR;; Bit 5 = Subdir  ‚N4 (> D& H‚N50 $N>†DEFRAG;; Bit 6 = Defragmented : ‚N5D (> ;; compare to a space N F†ELEVEN;; in order to exit X (>ƒEOL;; compare to EOL b F†ELEVEN;; also to exit l %HƒATE;; always get next character v X; € †ELEVENŠ !R>ÿ;; if there were no flags ” H‚E1;; then ERROR ž %>û¨ :² ‚E1¼ P†ATTRIBÆ 2(>ƒEOL;; if end of line, then use default mask Ð H†TWELVEÚ #…DFLAGä !ˆCOM_EXITî †TWELVEø 3;; skip the space  X; 7X; Here only if there is some sort of mask or path  X; „NINE* X; 4 X; Check for device first > X; H Q…LBUFF8R R> :\ F‡DEV_ONEf Q…LBUFF8p R> :z H†NO_DEV„ Q…LBUFF8Ž P†DEVICE˜ 3¢ 3¬ 3¶ H‚D1;; always jump À ‡DEV_ONEÊ QÔ -R>@;; Check to see if Sparta version 4.x Þ F‚V4è 3ò 3ü H†NO_DEV;; always jump ‚V4 Q…LBUFF8P†DEVICE$3.38H‚D1;; always jump B †NO_DEVL#…DFLAG;; Set D: flag V‚D1` Q…LBUFF8j R>ƒEOLtH‚P1~ !ˆCOM_EXITˆX; ’X; Search for a path œX; ¦‚P1°*'…POINT;; save current point in buffer º(%…COUNT;; get length of input buffer Ä‚S1Î1Ø Q…LBUFF8âR> >ìF‚S3öR> <F‚S3 R> \F‚S3 )…POINT(H‚S12,< %…POINTFD‚S2;; branch if no path P‚S3Z-3;; inc y so it points to char after path d'†POINT2;; save y n %…POINTx$>‚‚S4Œ Q…LBUFF8– P„PATH9 3ª2´/)†POINT2;; has entire path has been copied? ¾H‚S4È'Q> *;; Add *.* to end of path. Ò P„PATH9Ü P„PATH9æQ> .ð P„PATH9ú Q>ƒEOL P„PATH9X; X; Copy and expand mask "X; ,X; first do filename 6X; @‚S2J$>TƒEX7^ Q…LBUFF8hR> *rHƒEX2|X; †#X; Found a wildcard, so skip to +X; extension by searching for a period šX; ¤ƒEX0®3¸ )…COUNTÂF†NO_EXT;; else clobber itÌ Q…LBUFF8ÖR> .;; if we find it àFƒEX4;; then expand it êHƒEX0ôX; þƒEX2R> . F†DO_EXT(>;; if we get too many&EƒEX3;; then ignore them0-P…FMASK9;; save the character in the mask :ƒEX3D2N3X )…COUNTb'HƒEX7;; continue until end of bufferlX; v,X; if no extension, then we must assume €,X; that none is wanted. So, we clobber ŠX; the extension. ”X; ž †NO_EXT¨Q> ;; grab a space ²P…FMASK;; and clobber ¼P…FMASK ;; the extension Æ P…FMASK ÐHˆCOM_EXIT;; always exit ÚX; ä †DO_EXTî(>øFƒEX4Q> ;; clobber the rest P…FMASK9;; of the filename 2  H†DO_EXT*ƒEX44$>>3;; skip past the . H)…COUNT;; if at the end RF†NO_EXT;; then clobber it \ƒEX5f Q…LBUFF8pR> *;; check for wildcard z FˆCOM_EXIT„P…FMASK9Ž2˜(>¢ FˆCOM_EXIT¬3¶ )…COUNTÀHƒEX5ʃEX6ÔQ> ÞP…FMASK9è2ò(>üHƒEX6X; 0X; VOILA! The command line has been parsed, #X; wasn't that great fun! YUCK! $X; .+X; Now, lets do what we were told to do 8X; and stop wasting time. BX; L ˆCOM_EXITVX; `3X; do like normal DIR and execute a chkdsk call jX; tQ>/;; Chkdsk function ~P²;; ICCOM, IOCB #7 ˆ3Q>5†DEVICE;; Tell CIO where to find the filename’Pµœ Q>4†DEVICE¦,° O…DFLAGºP´Ä D„SKPRÎ#µØ„SKPRâ1Q>4…ENTRY;; Tell CIO where to put chkdsk info ìP¸ö Q>5…ENTRYP¹ Q>PºP»($>p;; Use IOCB #7 2 „CIOV<IƒCE2;; Check for error F:;; Exit with an error PƒCE2Z*%>;; Copy Volume name to volbuf area dƒCE3nQ…ENTRY8x P†VOLBUF8‚1ŒIƒCE3–0Q…ENTRY;; Save the number of free sectors   P…FSECTª Q…ENTRY´ P…FSECT¾X; È?X; Open the appropriate directory so that we can read it in Ò5X; the raw format. This is absolutely necessary. ÜX; æ1Q>5†DEVICE;; Point to our device and pathname ðPµú Q>4†DEVICE, O…DFLAGDƒCE4"#µ,ƒCE46P´@0Q>;; Indicate read [4] raw [+16] directory JPºT)Q>;; Indicate open channel function ^P²h$>p;; use IOCB #7 r „CIOV|IƒCE5;; check for error †:;; exit with error ƒCE5šQ>¤P´®Pµ¸P¶ÂQ>%;; Point command ÌP²Ö$>pà „CIOVê. ‰GET_ENTRY;; get first entry in directory ôX; þ;; Copy directory name to dirbuf ƒCE6& Q„NAME80 P†DIRBUF8:1DIƒCE6NX; XX; Print the header out. bX; l>X; Since we have the volume name, and the directory name, v;X; we can print them out right now, and not worry about €X; it later. ŠX; ”Q> ;; Print the header žPB¨*Q>4†HEADER;; tell E: the start address ²PD¼ Q>5†HEADERÆPEÐ Q>„HLEN;; give it the length ÚPHäQ>îPIø$>;; Use IOCB #0  „CIOV X; =X; If an error occurs here, we don't give a damn because 2X; it would mean the user has bigger problems. *X; 4#)>€;; But check for a break key>H„@BK1;; anyway, so that weH%>€;; can exit smoothlyR:\„@BK1f=X; So, here is the main loop for reading in and printing p%X; the directory. Short, huh? :) zX; „ƒTOPŽ ‰GET_VALID˜0IƒMN1;; an error here means end of directory ¢ !‡DIR_END¬ƒMN1¶ ‹PRINT_ENTRYÀ!ƒTOPÊX; Ô8X; print_entry is easier, so I'll do that one first. ÞX; è‹PRINT_ENTRYòX; ü(X; copy filename and extension first X; %> $> $ƒPE1. Q„NAME88 P…FNAME9B0L(>VHƒPE2`0jƒPE2t1~IƒPE1ˆX; ’X; set attributes list œX; ¦$> .° Q„STATºT?;; skip bit 7 ÄT?;; check bit 6 ÎDƒSA1Ø$> d;; defrag bit âƒSA1ì&…FATTR;; flag it :) ö$> .T?;; check bit 5 DƒSA2$> s;; subdir bit ƒSA2( &…FATTR2$> .<T?;; skip bit 4 FT?;; skip bit 3 PT?;; check bit 2 ZDƒSA3d$> a;; archive bit nƒSA3x &…FATTR‚$> .ŒT?;; check bit 1 –DƒSA4 $> h;; hidden bit ªƒSA4´ &…FATTR¾$> .ÈT?;; check bit 0 ÒDƒPE5Ü$> p;; protected bit æƒPE5ð &…FATTRúX; (X; That wasn't so hard, now was it? X; X; "-X; Okay, now we get to the hard parts... ,7X; I need to turn the file length into a its ascii 64X; equivalent and do the same for the 3 parts of @7X; the date. Coding this myself would be a pain in J,X; SpartaDOS routine just wouldn't work. TX; ^X; watch carefully. :) hX; rX; |X; Now convert the length. †X; %>šƒCR2¤ QƒLEN8® P…DVEND8¸1ÂIƒCR2Ì …B2ASC;; convert! Ö+%>;; copy ASCII number to output line àƒCR4ê Q†NUMBUF8ô P„FLEN8þ1IƒCR4X; X &…DVENDb Q>4ƒFYYl P…INDEXv Q>5ƒFYY€ P…INDEXŠƒCV0” %…DVENDž $„DMIX8¨Q„DATE9;; Get date² P…DVEND¼ †SB2ASCÆ%>ЃCV1ÚQ†NUMBUF8ä P@…INDEX7î1øIƒCV1 Q…INDEX ;S>  P…INDEX*EƒCV24 "…INDEX>ƒCV2H "…DVENDRIƒCV0\QƒFMMfR>0pHƒCV3zQ> „PƒFMMŽƒCV3˜X; ¢7X; Well, that's the hard part, now we just need to ¬X; print it. ¶X; À!Q> ;; select put buf command ÊPBÔ3Q>4…FNAME;; give E: start address of the header ÞPDè Q>5…FNAMEòPEüQ>%;; give it the length PHQ>PI$$>;; Use IOCB #0 . „CIOV8X; B=X; If an error occurs here, we don't give a damn because L2X; it would mean the user has bigger problems. VX; `)>€;; However, check forjH„@BK2;; break key errort7;; and exit if found~7ˆ%>€’„@BK2œ :;; exit print_entry routine ¦X; °X; ºX; Now, a simple routine... ÄX; Î;; number of byteS to get P¸Q>P¹( Q>4…ENTRY2P´< Q>5…ENTRYFPµPQ>ZP²d$>pn „CIOVx%³‚:ŒX; –X;  =X; Now comes the hard part, validating an entry with the ªX; options given. ´X; ¾.X; This routine has to do several things: È#X; 1) read in a 23 byte entry Ò1X; 2) ensure that the attributes are correctÜ,X; 3) ensure the filename fits the maskæX; ð ‰GET_VALIDú*Q†BRKKEY;; Check for break key pressed. H„@BK377":,„@BK36 ‰GET_ENTRY@IƒGV1J :;; exit if end of directory TƒGV1^X; check attribs first h Q„STATr4F‰GET_VALID;; should never happen (0=end of dir) |3M>;; mask out all except deleted & write open †-H‰GET_VALID;; skip entry if either is set  Q…ATYPEš F†CHKMSK¤ Q…ATYPE®R> +¸ F„PLUSÂX; Ì2X; minus compare, any bit on rejects the entry ÖX; à Q„STATê M†ATTRIBôH‰GET_VALIDþ F†CHKMSK X;  1X; plus compare, any bit on accepts the entry  X; & „PLUS0 Q„STAT: M†ATTRIBD F‰GET_VALIDN X; X X; check the mask b X; l †CHKMSKv %> € Q>Š P…IFLAG” ƒCK1ž Q…FMASK8¨ R> ?² FƒCM2¼ R„NAME8Æ FƒCM2Ð Q>Ú P…IFLAGä ƒCM2î 1ø IƒCK1!X; !9X; Examine the NOT flag. If the filename is a valid !3X; one given the mask, then IFLAG will equal 0. !7X; The NOT flag equals 0 when it is not being used. *!-X; If the NOT flag and IFLAG are the same,4!$X; then the entry is a good one. >!X; H!Q…NFLAG;; Get NOT flag R!,R…IFLAG;; Check for fname match/no match \!1H‰GET_VALID;; If not equal then invalid entry f!X; p!X; Boy, was that hard! :) z!X; „!Q>Ž!:;; exit with good flag set ˜!X; ¢!4X; What to do at the end of the directory? This ¬!X; is what you do.... ¶!X; À! ‡DIR_ENDÊ!X; Ô!&X; Convert the free sector count. Þ!X; è!%>ò!ƒIF2ü! Q…FSECT8" P…DVEND8"1"IƒIF2$" …B2ASC."%>8"ƒED1B" Q†NUMBUF8L" P†FRESCT8V"1`")>j"HƒED1t"X; ~"&X; Print out the free sector count ˆ"X; ’"Q> œ"PB¦" Q>4„PRFS°"PDº" Q>5„PRFSÄ"PEÎ"Q>Ø"PHâ"Q>ì"PIö"># „CIOV #X; #X; Close IOCB #7 #X; (# †CLOSE72#Q> <#P²F#$>pP# „CIOVZ# %>;; Indicate a good close.d# :;; All done, return to DOS. n#X;x#+X; SB2ASC - Converts a byte to 2 digits.‚#X;Œ# †SB2ASC–#$>ÿ # Q…DVENDª#ƒSB0´#2¾#;È#S> Ò#EƒSB0Ü#O>:æ#P†NUMBUFð#Aú#,$O>0$P†NUMBUF$:"$X; ,$7X; This routine converts a 3 byte number to ascii. 6$X; @$ …B2ASCJ$(Q>;; Set loop counter so that all T$*PƒDLP;; 8 possible digits are figured. ^$X; h$X; divide by 10 r$X; |$„UDIV†$Q>$ P…DVENDš$ P…DVEND¤$ †OKUDIV®$$>¸$ …DIVLPÂ$ U…DVENDÌ$ U…DVENDÖ$ U…DVENDà$ U…DVENDê$ …CHKLTô$;þ$ Q…DVEND%S> % D†DECCNT% P…DVEND&% †DECCNT0%0:% H…DIVLPD% U…DVENDN% U…DVENDX% U…DVENDb%X; l%$ƒDLPv%,€% Q…DVENDŠ%O>0”% P†NUMBUF9ž%"ƒDLP¨% I„UDIV²%X; ¼%$>Æ%ƒBA3Ð% Q†NUMBUF9Ú%R> 0ä%HƒBA4î%Q> ø% P†NUMBUF9&2 &(>&HƒBA3 &ƒBA4*&:4&X; >&X; Set the run addressH&X; R&à\& …STARTf&