IMD 1.16: 29/05/2007 12:28:55 FOGCPM.033 --FOGCPM033DA2 COMDA2 DOC7 DUMPDIR COM DUMPDIR DOCDUMPDIR MAC&LDIR23 COM!LDIR23 DOCLDIR23 MQC> !"#MATCHF REL$MYSORT REL%USQBASE REL&LDIR23 SUB'SETDRU COM/()*+,-SETDRU DOC./0123456789:;<=SETDRU DOC>?@-04-00 86 -01-08 88 SETDRU REL9ABCDEFGHSETDRU C 7IJKLMNOSDRU1 MACHPQRSTUVWXSDRU2 MACCYZ[\]^_`aUNSETDRUCOM bcUNSETDRUC defDIRF36-SCOMghiDIRFILESDOCGjklmnopqrDIRF3-S NOTsDIRF36-SNOTtDIRF36-SAQMuvwxyz{|}~DIRF36-SAQM4-CPM033 DOC"PRINTDF COMZPRNTDF10DOCDIRF-KP COMDIRF-KP INFDIRF37KPARKDIRF37KPARKThis is the disk name. w replacing the first line: * * * * PRNTDF v. 1.0 ERROR: File not on drive X If a drive which CP/M does not know about (determined by BDOS function 24) is specified, the following line replaces the first line when the help screen is displayed: * * * * PRNTDF v. 1.0 ERROR: Drive X not found If all goes well, the following message is displayed: PRNTDF Version 1.0 (Copyright 1986 by Steve T. Jones) In addition, the following messages are displayed as appropriate: ... Sending FormFeed (^L) to printer ... Writing DIRFILES.PRN ... Sending output to printer ... No screen display ------------------------------------------------------- An invalid parameter causes the program to halt and display the help screen. In this case, however, the first line is replaced with: * * * * PRNTDF v. 1.0 ERROR: Invalid parameter(s): X, X ^ DA 2.0 (2/86) (c)1986 E.Meyer ???: ????k in ??? files use ????k (????k free) XXXX!9"1:0! "I2 2!)60 84 0#w :\ :<2\=_A2(###~<2##^#V#"GZ! 08:\=_.*LJ:F#2(*#"*#"*R( :([*R:GL!:m+(-(?(~ >(2>2>2 >2Ϳ!m 2>?2h!]~  6?#2W!5)0 !*N!O\+2,2j2X>2M!(:=2\_!:\w #:(O ͥ(h0  ͽ ͺ###~O:O* "r* "*"!4:o=g}_ ͺ### O:O>G~w#xw* "r* "2:=2: 2Wo&6-*-!*D!!(͂:2::($>|2C:!(0x2*T]6!~()5( ͋ > #͋ :=( *"":2*~( z>.͖z> ͖###^#V*> j>Rj>Sj>Aj*>1j>2j>3j>4j!5(:G*"5X:_:_ 1:O!>:++~+0:2*0_~08 :02)0W_+8 !00") !]!m~ @2\>:]#(Y.(*( (7>?> ~#. #(**( ( >?~ #m#( 6 #R(S(A(18500O    ~ <+(/R(S(A(18500O    #] \:͋NO FILE (~ >-͖#~#͖ɯ͖#㯆#͖_~O (#R:oDM*+!???<%!!!z>kÖ:#:##!!0zݾ8 {ݾ8 V^Rq###06!>0 q# +60!'d  ٭!b`A0:;rD3biv:9Dp fuňWBC mbioÄbìfM;-Щ U0ʁ.06DuVQ[Täp&XF wscs!bv1L`S_[aio`'\`,a\.!bλ9y ~7vƂ04,֜C  DA.DOC ------ Documentation for DA.COM v2.0 (2/86) (c)1986 E. Meyer DA is a super directory utility (the name stands for Directory- Attributes) that will run on any Z80 CP/M system (2.2 or 3.0). DA.COM is like XDIR and STAT (or SET/SHOW) all rolled into one, but it takes just 2k of disk space. DA can: * show the files on a disk, the space they take, and free space * give an alphabetized directory with file sizes * select on, display, or change file attributes Without DA, file attributes are very clumsy to use, so you may not have been using them... but you'll start now. You can find the details in your CP/M manual, but briefly, the three basic attributes are: R = READ/ONLY -- the file cannot be erased or modified. S = SYSTEM -- the file will not appear in an ordinary DIR. A = ARCHIVE -- the file has not been changed since last archived. In addition there are four more, called simply "1" to "4", which have no established meaning under CP/M, and can be used for any purpose you like. (For example, you can think of them as "sub-user numbers".) USING DA SYNTAX: A>da [du:][filename] [op][attributes] ("[]"=optional) where "du" may include a user number, eg "B14"; "filename" may include wildcards ("*", "?"); "op" may be ONE of "~", "?", "+", or "-" (see below); "attributes" are any or all of: "R","S","A","1"-"4" (see above). DISPLAY: DA has three display modes, depending on the arguments given. If no filename is given, DA gives only disk statistics for the chosen drive/user. With a filename, you will also get a list of files that match, with their sizes. Finally, if you use the set operands "+-" or the display operand "?", you will get filenames and attributes. A>da b: B0: 84k in 4 files use 84k ( 97k free) A>da b:*.* B0:  84k in 4 files use 84k ( 97k free) ALPHA .FIL 6k > BETA .FIL 51k > GAMMA .FIL 18k > OMEGA .COM 9k A>da b:*.* ? B0:ALPHA .FIL RS----- > BETA .FIL ------- > GAMMA .FIL --A---- B0:OMEGA .COM ---1--4 INTERPRETATION: Disk B has 97k free. ALPHA.FIL is 6k, and has the "R" (Read/only) and "S" (System) attributes... etc. MORE EXAMPLES 1. If only a drive/user is given, DA displays the disk statistics for that drive/user. A>DA 12: will give statistics for drive A user 12. 2. If a filename is given, DA also displays the disk statistics, and the names and sizes of the specified file(s), if any exist, in alphabet- ical order (horizontally or vertically -- see below). A>DA *.DOC will show all files A:*.DOC on the current user. 3. You can get a selective display too; if you specify an attribute list, DA will display only those files which do (or do NOT, if the "~" operand was used) have the specified attributes. A>DA *.* RS will show ONLY Read/only System files. A>DA B:*.* ~A will show ONLY NON-Archived files on drive B. 4. You can display file attributes instead of sizes, if you use the "?" operand. (Disk statistics do not display in attribute mode.) A>DA *.* ? will show all files on A: with their attributes. A>DA *.* ?R same, but ONLY Read/only files. 4. You can change attributes on files, by giving a list of them preceded by "+" to set or "-" to remove them. DA will then display the new attribute status of the files. A>DA *.COM +RS will make all COM files on A: Read/only, System. A>DA B6:ART1.FIL -S will make B:ART1.FIL (user 6) NON-System. Note that if you want to specify attributes, you have to give a drive OR filename first. "A>DA ~SR" would look for a file named "~SR", so use "DA A: ~SR" or "DA *.* ~SR" instead. To use the set operands "+-", you must give a filename ("DA A: +S" makes no sense).  ADVANTAGES DA gives a more convenient way to set attributes than the usual CP/M commands. It displays attributes in an intuitive way, instead of using video bits or lowercase on filename characters as do other programs. And it is the only utility I know of that can give selective lists of files by attributes (other than "S"). DA is careful to give accurate statistics. The disk involved will be reset before it is accessed, so you can change disks and use DA without fear. The file sizes are accurate, rather than rounded up to your block size: DA will show a 1k file as 1k, even on a hard disk with 4k block size; most other programs would report 4k. The disk statistics message gives the actual space taken up on your drive (the "use" figure) as well as the total of the real file sizes, in case these differ. LIMITATIONS When DA is used on unusual "media", such as ROM or tape "drives" on some lap portables, the disk statistics may be inaccurate. This is a general problem, applying to STAT etc as well. DA has a few numerical limits. It can only cope with up to 255 files, 999k filesizes, and 8190k free space. Even hard disk users seldom exceed this on any one drive/user. OPTIONAL: Adjusting the Display You can vary the number of columns in which DA.COM displays the directory. Patch address 0103h in DA.COM (with DDT, SID etc) to the number you want. Each column is 18 characters wide. The default is 4 columns for an 80-column screen; 3 works well on a 52-column Osborne; 2 works with 40-column screens. (Note that in the attribute mode, the number of columns in the display will be one less in each case.) You can also choose whether you want the directory alphabetized horizontally or vertically. Patch address 0104h to FF for vertical (the default is 00 for horizontal). DA will use ">" as a file separator in horizontal mode, and "|" in vertical mode.  VERSION HISTORY v1.0-1.2: slight modifications. v1.3: avoid printing characters with parity bit; no default "*.*". v1.4: new algorithm handles larger disks (to 8190k). v1.5: dual-mode display; fixed disk free space bug under CP/M 2.2. v1.6: improved 52-column display option. If you have a lap portable with a small RAMdisk, you may still be interested in v1.6, which was just 1k in size. Its slowness under CP/M 2.2 is not noticable on a RAMdisk. VERSION 2.0 -- completely rewritten. Redesigned display formats, attributes only display under "+-?" operands. Added user number support. New algorithm greatly improves speed under CP/M 2.2. The DA name and version are no longer a part of the display, but you can view them by typing the file (TYPE DA.COM). --- Eric Meyer, 427 N. Washington #4, Bloomington IN 47401 --- ou can view them w]=kzd.2$;!!˄׊_d0KIQܔ>s Zb]WZY7bڐ l.pLxV6V}U02 B+n[^H/4^ N1ͥ ͥ_ͥ` DUMPDIR v1.20 by ESKAY 06/15/85 ] 526X=_ͥͥA2f:m u:nͭ8a"1ͭaͥ~27#^#V###F~#´`Hardþ`Floppy#` drive directory. Capacity: ` entries max, *-` entries displayed, *1|/W}/_#` entries unused. *-DM ͭ:5̄ͭ"/*-|+"-*/` ~y`**|>:͑#FAA####:7ʵ^#V#|A;šA~#&·*/ "/:*=2*R>2*̀RAN25>?2\o&  "3 *3>0Ñ2̀ͥ> ÑR>.͑~͑#R"+!"->?2hͥ͏ͥʊ͏z*-*+ƀO  w#£"+:ʾ*-#"-` *** OUT OF MEMORY *** ` *** ABORTED*** ` FILE NOT FOUND ` *** END OF EXECUTION *** ` To use: Enter: DUMPDIR [d:]ufn[ oo] All matching files (if any) will be displayed, along with the physical disk location information in group numbers. OPTIONS: A = display all user areas N = display unsorted :6)_ͥ?????????????"R"P`i"\"^*^|g}o"^}ª*\}o|g"P!"T"R- x"V"Z"X# x&&Fwx# x*^|/W}/_*T&#"T*X*V{ozg"X*R#"R"T*P}|ڕ*Z*V}o|gf~#ʺ ʤ S ʑ ʖʖʚkk kyk kyG>GO> ͑°k|&}&'d }0͑}o|g  }o|gy> Ñy0Ñ55 A7Ñ0Ñ> ͑> ͑ ґʑʑʑ ʑ ʑ>^͑@͑*. O*. *}ʹ$.ɽr) ld e,a rloc34: call obdos pop hl ;get real return values pop af rloc35 equ $+1 ld sp,(fstack) ret user: db 0 ;hold user number pdrive: db 0 ;hold phony drive spec oflag: db 0 ;open/make aflag: db 0 ;ambiguous? wfcb: db 0 This is version 1.20 of DUMPDIR as of 06/15/85 DUMPDIR allows you to display the disk directory by filename and file allocation. The hex numbers shown after the file name are the addresses of the disk allocation blocks used by the file. The syntax is DUMPDIR [d:]afn[ oo] The filename is mandatory, the drive (d:) is optional, as are the options (oo). The following options are available: a - show all files, all user areas n - do not sort output The following improvements have been made over version 1.10 of 05/11/84: 1. The program now warmboots, allowing an additional 2k of storage by overwriting the CCP 2. DUMPDIR no longer attempts to overwrite the BDOS with a superlarge directory, instead it aborts with an error message. SRREAD MA INPLN CORESPR MASUD1 d...$! #zͱP ‹! ~ ʯPâ7 G~# ³7# !z>:ɇ_~# y^# ! ;DUMPDIR v1.20 as of 06/15/85 ;ESKAY ; cr equ 0dh lf equ 0ah ; fcb equ 5ch fcb2 equ 6dh dreset equ 13 seldk equ 14 sfirst equ 17 snext equ 18 curdk equ 25 getdpb equ 31 ; extrn bdos,print,phl4hc,phldc,codend extrn pa2hc,cout,crlf,cin extrn sort ; begin: lxi sp,stack mvi c,curdk call bdos push psw mvi c,dreset call bdos pop psw mov e,a mvi c,seldk call bdos call print db cr,lf db 'DUMPDIR v1.20 by ESKAY 06/15/85',cr,lf,0 lxi d,fcb+1 ldax d cpi ' ' jz help dcx d ldax d sta defdrv ora a jz nosel push d dcr a mov e,a mvi c,seldk call bdos pop d nosel: mvi c,curdk call bdos adi 'A' sta drcd xra a stax d lda fcb2 cpi ' ' jz noopt call ckopt lda fcb2+1 call ckopt noopt: call codend push d lxi d,efcb call wildx1 pop d shld freed call codend call wildx1 jz nofile mvi c,getdpb call bdos lxi d,6 dad d mov a,m sta f816 inx h mov e,m inx h mov d,m inx h inx h inx h call crlf mov a,m inx h ora m jnz flp call print db 'Hard',0 jmp hrd ; flp: call print db 'Floppy',0 hrd: xchg inx h call print db ' drive directory.',cr,lf db 'Capacity: ',0 call phldc call print db ' entries max, ',0 push h lhld count call phldc call print db ' entries displayed, ',0 lhld freed mov a,h cma mov d,a mov a,l cma mov e,a pop h dad d inx h call phldc call print db ' entries unused.',cr,lf,0 lhld count mov b,h mov c,l lxi d,32 call codend lda nopt ora a cz sort call codend shld dptr dislp: lhld count mov a,h ora l jz done dcx h shld count lhld dptr call print db cr,lf drcd: db ' ',0 mov a,m push h push b cpi 0e5h jnz noers call print db '**',0 jmp ersd ; noers: call pa2dc ersd: pop b pop h mvi a,':' call cout inx h call pfn call spc call spc inx h inx h inx h inx h lda f816 ora a jz do8bit mvi b,8 lp16: mov e,m inx h mov d,m inx h call ckab xchg  mov a,h ora l jz disnx call spc call phl4hc xchg dcr b jnz lp16 jmp disnx ; do8bit: mvi b,16 lp08: call ckab call spc mov a,m inx h ora a jz disnx call pa2hc dcr b jnz lp08 disnx: lhld dptr lxi d,32 dad d shld dptr lda linect dcr a sta linect jnz dislp mvi a,23 sta linect call cin jmp dislp ; ckopt: cpi 'A' jz seta cpi 'N' rnz setn: sta nopt ret ; seta: mvi a,'?' sta fcb ret ; pa2dc: mov l,a mvi h,0 lxi b,-10 call mdec lxi b,-1 call mdec ret ; mdec: mvi d,-1 mdlp: shld dtemp inr d dad b jc mdlp lhld dtemp mvi a,'0' add d jmp cout ; ckab: call condin cpi 'C'-40h ;if ^C... jz abort ;...then finished cpi 'S'-40h ;if not ^S... rnz ;...then go on, else... call cin ;...wait for keypress cpi 'C'-40h jz abort ret ; ; This is NOT the SYSLIB routine by same name... ; condin: push h push d push b mvi c,6 mvi e,0ffh call bdos ora a pop b pop d pop h ret ; spc: mvi a,' ' jmp cout ; pfn: mvi b,8 call pfn1 mvi a,'.' call cout mvi b,3 pfn1: mov a,m ani 7fh call cout call ckab inx h dcr b jnz pfn1 ret ; wildx1: shld bufptr lxi h,0 shld count mvi a,'?' sta fcb+12 mvi c,sfirst call bdos cpi 0ffh rz ;nothing found -- error call moven ;move name wloop: mvi c,snext ;search for next call bdos cpi 0ffh jz donew ;finished call moven jmp wloop ; donew: ora a lhld count ret ; moven: lhld bufptr add a add a add a add a add a adi 80h mov c,a mvi b,0 ldax b cpi 0e5h rz push d mvi d,32 ;move 32 chars movlp: ldax b mov m,a inx h inx b dcr d jnz movlp shld bufptr lda 7 cmp h jz memful pop d lhld count inx h shld count ret ; memful: call print db cr,lf,7 db '*** OUT OF MEMORY ***',cr,lf,0 jmp quit ; abort: call print db cr,lf db '*** ABORTED***',cr,lf,0 jmp quit ; nofile: call print db cr,lf,lf db 'FILE NOT FOUND',cr,lf,0 jmp quit ; done: call print db cr,lf db '*** END OF EXECUTION ***',cr,lf,0 jmp quit ; help: call print db cr,lf,lf db 'To use:',cr,lf db 9,'Enter: DUMPDIR [d:]ufn[ oo]',cr,lf db 9,'All matching files (if any) will be displayed,',cr,lf db 9,'along with the physical disk location information',cr,lf db 9,'in group numbers.',cr,lf db 'OPTIONS:',cr,lf db 9,'A = display all user areas',cr,lf db 9,'N = display unsorted',cr,lf,lf,0 quit: lda defdrv ora a jz nol mov e,a dcr e mvi c,seldk call bdos nol: rst 0 ; linect: db 19 ; line count bufptr: dw 0 ; buffer pointer count: dw 0 dptr: dw 0 freed: dw 0 dtemp: dw 0 nopt: db 0 defdrv: db 0 f816: db 0 efcb: db '?????????????',0,0,0 ds 60 stack equ $ end  count inx h shld coun------------------------------------------------------- An invalid parameter causes the program to halt and display the help screen. In this case, however, the first line is replaced with: * * * * PRNTDF v. 1.0 ERROR: Invalid parameter(s): X, X  !"9"g1g{ LDIR v2.3 (c) ESKAY 02-04-85 :] )`i"!!m~ j> 6?#=c!>? #qx ʰx!’:GÖҔy?ʔ¨:Oí#Ҕ!6L#6B#6R͑ +6Q ·!d*>2:2 LBR directory for E>:P!~m# ~ m###~2=2G.~#fo"!"! "PFͮ*|j}ʲ|ʲ ** directory questionable ** CRC is Ͳ , should be Ͳii! ":O i~#6:<2mE6:<2:G: | > ##^#V*"ͻ}>k:=26:2i* ":=2:G:i Members mE displayed :, of :, active : *e sectors (ͻe k). :< !"w*,! *"w##  ÷!~͆,  Error unsqueezing .LQR file  Error reading file  Bad directory - not LBR format  Drive/user out of bounds  No such file on disk  No ambiguous LBR file names allowed USAGE: LDIR [du:]ufn[.LBR][ afn] Where: du: = drive and user, ufn = LBR or LQR file name afn=optional match filename (find files in LBR). Examples: A0>LDIR C3:TEST B2>LDIR 0:TEST1 B0>LDIR TEST1 C1>LDIR M7-OVL M7HZ*.* i*g"7"5`i"A"C*C|g}o"C}*A}o|g"5!"9"7- x¨";"?"=# x  Fwx# x*C|/W}/_*9 #"9*=*;{ozg"=*7#"7"9*5}|z*?*;÷}o|g M?Z`#P""!9"ͩvͣ>22ͩ"*w#‘ͩ"ͣڲ>*"|ͩs#r#ͩs#r#*+÷1>**USQ section (C) 1983, 1984 by Dave Rand (403) 484-4114!9":9=2:[V[L>==2:2:O:tO>=2yO*҃##^#Vzby2z>ʠ{/|}go>2 2 $կ~#:,L !L ~A A <2 #~:M ?" 2 #~:M  G~#:@ 0  OxG$ x  2 M ~:T #~,_ !w  >?d : G: O>͑ ~.‹ #͑ j ͱ j ͼ ʱ *£ >?å #‘ ͼ #é > ± ~! =_.:;,<>ɾͣͷ  9     &  C p ̈́ ! " F j j l n o !. Ö ^#Vbk$w#– *2 ͪ *6 ͖ *8 !͖ *4 Ͱ >*. ~ >ß *2 ͔ | ͑  >ß Ͷ >ß *6 *: s#r*> 6*. 6*0 ~S >ß *4 ͔ | ͩ i >ß *8 *< s#r*@ 6*0 6*. ~’ >ß *: ͌ | ~2B #*: s#r*> 5 *6 *: s#r*> 6Ͷ *: 6#6:B >ß 2B *0 ~ >ß *< ͌ :B w#*< s#r*@ 5 *8 *< s#r*@ 6 >Ÿ :B *. 62B > *@ ~^ N *0 6*4 ͤ t >ß :B w H@¤ >å @¤ @¤ Þ @ ~#(  v   y yG>GO>  dD D0N F_y[[{y0{'͎͎d͎ ͎}0}o|gڝ Ð}o|gyªy0|}d 0 _y> {y0{ 709>.99[>.[ [> >    >^@*./*. O*. 2 2 :_:_ Y X OGHQWrHgWrr# xr!"O*yO}o|gң|g}!o"͆͆*!"|}*"}o|g"}o!}o|g7a{_>?> ~#. #(**( ( >?~ #m#( 6 #R(S(A(18500O    ~ <+(/R(S(A(18500O    #] \:͋NO FILE (~ >-͖#~#͖ɯ͖#㯆#͖_~O (#R:oDM*+!???<%!!!z>kÖ:#:##!!0zݾ8 {ݾ8 V^Rq###06!>0 q# +60!'d  ٭!b`A0:;rD3biv:9Dp fuňWBC mbioÄbìfM;-Щ U0ʁ.06DuVQ[Täp&XF wscs!bv1L`S_[aio`'\`,a\.!bλ9y ~7vƂ04,֜C 02-04-85 This is version 2.3 of LDIR.MAC. NEW FEATURES IN VER 2.3: On RCPM systems, .LQR files no longer are a problem. While you still can't TYPE anything in an LQR file, LDIR23 at least gives you a glimpse at the directory! No syntax changes - simply say LDIR where can be that of an LBR or an LQR file. LQR files are only displayed if there is no LBR of the same name. EXAMPLE: A>DIR FOO .LBR FOO .LQR ZOT .LQR A>LDIR FOO (displays directory of FOO.LBR) A>LDIR FOO.LQR (still displays FOO.LBR) A>LDIR ZOT (displays directory of ZOT.LQR) VERSION 2.2 FEATURES: 1. SYSLIB3 now required for reassembly, as well as a new MATCHF module. 2. Syntax change - optional second argument used as match filename to allow searching for members. This allows use like normal DIR: A>ldir m7-ovl m7hz*.* only displays members matching M7HZ????.??? A>ldir m7-ovl same as: A>ldir m7-ovl *.* 3. New total line - total line now displays match filename, number of members displayed, number of active members and the size of the displayed members both in sectors and in k. Note: if the match filename is blank or *.*, then # of members and # of active members will be the same. Example: A>ldir test LDIR v2.2 ..... LBR directory for TEST.LBR: FOO .ASM 1k | TEST .MQC 23k | ZOT .ASM 11k Members ????????.??? displayed 3 of 3 total: 360 sectors (45k) A>ldir test *.asm LDIR v2.2 ..... LBR directory for TEST.LBR: FOO .ASM 1k | ZOT .ASM 11k Members ????????.ASM displayed 2 of 3 total: 96 sectors (12k) New procedure to assemble/link: A>m80 =ldir22 A>l80 /p:100,ldir22,matchf/s,mysort,syslib/s,ldir22/n/e OR A>link ldir22,matchf,mysort,syslib[s] MYSORT.REL, MATCHF.REL and SYSLIB.REL must be on the default drive! (Frequent users of SYSLIB should incorporate MATCHF into SYSLIB (name the module SMATCHF). Be sure not to APPEND it to the library! CUSTOMIZATION: 3 variables can be changed: 0103 COLUMNS set to number of columns desired (default 4) 0104 MAXDR highest drive +1 (A=2, B=3...) 0105 MAXUSR highest user area +1 filename is blank or *.*, then # of members and # of active members will be the same. Example: A>ldi.6: improved 52-column display option. If you have a lap portable with a small RAMdisk, you may still be interested in v1.6, which was just 1k in size. Its slowness under CP/M 2.2 is not noticable on a RAMdisk. VERSION 2.0 -- completely rewritten. Redesigned display formats, attributes only display under "+-?" operands. Added user number support. New algorithm greatly improves speed under CP/M 2.2. The DA name and version are no longer a part of the display, but you can view them by typing the file (TYPE DA.COM). --- Eric Meyer, 427 N. Washington #4, Bloomington IN 47401 --- ou can view them w]=kzd.2$;!!˄׊_d0KIQܔ>s Zb]WZY7bڐ l.pLxV6V}U02 B+n[^H/4^ Nvl5LDIR23.MAC_  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYoZ[\]^PbyxND36o<}74|CfFwG;%ߕYn2[=ScL>Й<㿓u èGb|4?=:T)|LٰBllhƦ6t 'GYn 5 7JWÛ@tXD =dȆm–I~$.G=+{?/7%.:'uٜ('Q ]|&Kg9m8l(~~t{ZPB_XӖ|F -~<<S 31\|6L4 /(뇛ŧ׎.pj6[{%8ǎp~Wm7n>9vt:'Kg뜨fC rQQbL }}SN4y׍^\?<}l)LW4dfG#)bYruNTgCNΆ o7y֞ѕs(Qnߝp3l<5lt@gk O*xJS)N46__45JuVPhnuy1Si du:JP)~$ /nj|lnu:x<=r|>|8?lݼ]/b5x6:_<}9>>~g|\_nnoV ^nKbN”gGNW[Ψl훁IbC%GNW87G;6__9`:]-bNN{SSx%8zu-bL GNW8|}qL&DφrKg1%::]oΟ[!Jptu?޽?E;6__S8QՖ/ΟTe2:]#g1UmR` %8zuůGΟdlXOMas㌞:]bhcyK4:]9:G G=GNWx|}qL#Buڒ㨇` _^_>?/3:yr +ѫ-޿]?G;6__SgtvMuڒ㨇`߮_=G;6__SgtvMkyOF ^n~uq{vl8JptuOߣ?/Sl)ln3VW[Nߣ?/ɰoL"goF ^nM|~&Wc4WdruGNWxyrףS?/)PՖ:]g3UHnYH ??^_ףkm!ɍ׉J5X^+iOhXOSS+% |Sq T8=%@[8q T㤤U2V.1'tG]0a`Ϧ(ilnkuP̶R YXvp-/߼^EmSKѓerFϘѵ!bvp}^o{.B\,SS7V*9khK1yAŇx.(A魃ϾpZLg]og6bnWJŇxP(X|=5C<(A "žWbl`-:W7aXaKJGO1q1Xڮ9+u5ƞtj˔T:jvJ;%-W}@3mGR̶8y%Z-{1<9g|6J0qR!`ǨMa2Ж0c1;۰\ 6ƸhAw{]HW1 y0N@eO㨫fG+nٓN> i˴lNcQk!1<9gvяC;3StWtGӵgSV!0A .1J_r!%LZzC1 :)qÐgc-{*G]5;j  Ncq Zj  C\@[=Bo(桳A'%Ƣhcc 'OMaCpbIY f h {6CgzPEgtJ&D3ڪnr}" Glh9.5XZ b]M@ߔM'@[ŒiCEtMѕ+-aƤ=LŇx  8.u_&}E ]Е+ݲ' }4xP!0A 聶:yWJ08(N{J0qP!`Ǡ.%̘6}6gt:W.iCD%(uǢWGT%(upSS;%v;`-b4hc3EfCnj`-m9tszJN^ ܄hF[MX~NN>3kxS,1V%ps҅B *A ֢>*A ֢3:y%p#>7ĴJV b]o_QI% GB:I{JjUṀbت1XhlUGom9莜6}6g}a[MMNh.@eO\p% q J04q:LJ`n|X@k8frtkJhK19mhjje1Xڒ'3Ԫ]=uY'φJ͹a3qP 9#ǖ=JpN@{erНX mj JNΆ3vT:%(>iW)=ؽ]÷k]ɓ4{I bC@;{=SՖS(A;8%L'HV-ݑ2 ^ p8]65Ćr%Kg;rQ q(u1ۢCaXm=A'&])1;"+A:LJpy+)StM P`pPMJ%-+A魃ϾpfLMgG`V}ڢOtgS(+҉ޮJZ9x*}6|HD+i) :m)evM40+m-MLz0/URgt{-S'L:QobL UmJ;ؽMrT o6%pfA t/O.|Uӳ3z{X f hCrTŒI{%L'HV-ݑu!])eO %. f[v˞u䕠m3$5\|6LII-$1XhlN$e[wupSS;-ݑϔxiC9SpâW:XE \4JP|'o4%L'p6N % m3$%CI b:A4*A ֢3:y%pmU7aMPpqzv1X%ZtF'n’. gh9.E b].*A ֢3:y%p+-DžX +A ֢ E%ZtF'n’BzƴP[}1XE%ZtF'n’ GM/qvƟ@krL6A \ppJh~y/Ϧ*A Y k1XMXnc4B .w@{hOR:gUҖ=*}6TMr |[%-qr0:%L'? )2l`ppJ5fLZ2ų)J5Ǥ]SzJ`X:y򙦦V6JZ%-`H%{BӖ|丆zrCJ&~Y)g;%b@sʕT%MܡkJ^ ^T%1hw a kMl::X%L'D]+aU[6L0iR–VI1XMfU ܄1P]|Ӗ6+rfu\(^I86fEgtJ&D3ڪnȘlpp:mj1qCF{%)81XMXGN>3zC){Zf3mJp9tkW*ֺfEgtJ&D3ڪn4 S4&mJp9tW*Ij;`-:W7!V%pJ{2DNrfu\(^I$0L;`-:W7!V%p0 mBUmRP6_[ %W};`-:W7!V%p珿h}]sSϿS1V%pݳfG3z~񊲡UmRx9F3ڪn’_ruN|j) L_N\H'ZnJ&D3ڪnhr-hF[MX>.Xt9F3ڪnO-vGh ş+:=^/hF[MX_i}?߼^|1q~E4*A b˾q@klXOϕ֡JP*aUbnj/Y^)sh})WB:FI̶nm̶$)lRMX1<5 Q3z)܄ɓ3zJ6E&,r%}䴡gS8mB; \)DgLNitMX#JNΆ3vEர@봡 uY'FϾp]ag,fPT8l Dv2J\4qwZ GΕ8 >mn<8)+YC<()> %̘߼C^w 5r) ld e,a rloc34: call obdos pop hl ;get real return values pop af rloc35 equ $+1 ld sp,(fstack) ret user: db 0 ;hold user number pdrive: db 0 ;hold phony drive spec oflag: db 0 ;open/make aflag: db 0 ;ambiguous? wfcb: db 0 PU dD4h5Q ! P5bldZP~ʢ *hY1Ѐ ɨ*iӀion. The hex numbers shown after the file name are the addresses of the disk allocation blocks used by the file. The syntax is DUMPDIR [d:]afn[ oo] The filename is mandatory, the drive (d:) is optional, as are the options (oo). The following options are available: a - show all files, all user areas n - do not sort output The following improvements have been made over version 1.10 of 05/11/84: 1. The program now warmboots, allowing an additional 2k of storage by overwriting the CCP 2. DUMPDIR no longer attempts to overwrite the BDOS with a superlarge directory, instead it aborts with an error message. SRREAD MA INPLN CORESPR MASUD1 d...$! #zͱP ‹! ~ ʯPâ7 G~# ³7# !z>:ɇ_~# y^# ! ԕ E4%I@pEsr "+"@>EvF&`Y.U>ќEs p ?] [b:. 4aVLxX4;B0xX`s輾*:WH7qapUp:W0>&TDUu-PˬUtl:}Iω;$:ԕ#QIU8QScM 98T# %Y%:Lӣ9=9:ӑL =5AI:Tc 9=QEV:U#@9=M]%R;TPcMI 1;QM=IQX;ԕM=IQX;ԕ#M9U5IR;ӕSTs nol: rst 0 ; linect: db 19 ; line count bufptr: dw 0 ; buffer pointer count: dw 0 dptr: dw 0 freed: dw 0 dtemp: dw 0 nopt: db 0 defdrv: db 0 f816: db 0 efcb: db '?????????????',0,0,0 ds 60 stack equ $ end  count inx h shld coun------------------------------------------------------- An invalid parameter causes the program to halt and display the help screen. In this case, however, the first line is replaced with: * * * * PRNTDF v. 1.0 ERROR: Invalid parameter(s): X, X TPT5U5QUMFP5dBZ 6Nm?X VUmEVUZr@ F® v-fPb,~کݒUXfP#9ܬڊpg!UWEl:15$UV]bWJ2e1 &pPC#X GA "NQHn2AR Ѡb4xU*FUduVWm$W}+>H/#ʬ 2+HDUpxT@ͥ *'ѕV<⪸ң"1d2 ecәʿW=?*Kn>.%AXUͨ,*gx FS@b:*v#*@ GA "NQHn2AR Ѡb4xU!!z>kÖ:#:##!!0zݾ8 {ݾ8 V^Rq###06!>0 q# +60!'d  ٭!b`A0:;rD3biv:9Dp fuňWBC mbioÄbìfM;-Щ U0ʁ.06DuVQ[Täp&XF wscs!bv1L`S_[aio`'\`,a\.!bλ9y ~7vƂ04,֜C ; assemble LDIR23.MAC m80 =ldir23 ; ; link with Digital Research LINK and SYSLIB.IRL ; link ldir23,mysort,matchf,usqbase,syslib.irl[s]  G O @ : < B - 8 ( 8 - ҀP σ 4  I ; W ^ e l s z.6: improved 52-column display option. If you have a lap portable with a small RAMdisk, you may still be interested in v1.6, which was just 1k in size. Its slowness under CP/M 2.2 is not noticable on a RAMdisk. VERSION 2.0 -- completely rewritten. Redesigned display formats, attributes only display under "+-?" operands. Added user number support. New algorithm greatly improves speed under CP/M 2.2. The DA name and version are no longer a part of the display, but you can view them by typing the file (TYPE DA.COM). --- Eric Meyer, 427 N. Washington #4, Bloomington IN 47401 --- ou can view them w]=kzd.2$;!!˄׊_d0KIQܔ>s Zb]WZY7bڐ l.pLxV6V}U02 B+n[^H/4^ N h fGGn5| Do you want SETDRU integrated with the program (y or n)? To which program do you want to apply SETDRU? Cannot open What is the name of the program to be created? $$$Cannot create file File Error writing file.Cannot rename output file. Installation successful. Copyright 1983-4 Michael M Rubenstein SETDRU 1.3 -- set drive and user for specified files in a program Up to 8 (ambiguous) file names may be specified. An input file will match the first matching file name. If it is ambiguous, the redirection (drive and user) will be used only if the file cannot be found on the drive specified by the program. If unambiguous, the file will always be redirected. An output file will match the first unambiguous (only) matching file name. It will always be redirected. Nonmatching files will not be affected May be installed as a separate program which loads the desired program or as a modification to the desired program. See SETDRU.DOC for more information. Specify drive letters in the normal manner (B:FILE.TYP). You will be prompted for user number. User number? !9 !VG "(*(|!!"&!!J@9͜ I !l@9*&##!K@9! <*&:\u|:\u_ #}*&#6*(|u!H@9 |j!H@9ͺ *&!k@9͂- ͇Ê!͸ Ç*&# }Ê!!&@9͜ I ʡ!@9!&@9!$<!-@9!!<!$@9r !$@9 |! !"***  ʹ **#"*!͸ **| !!\͜ I H** ?ùH!"**&** - ##!]! <*&** - :\u|ʔ:\uØ_ #}*&** - # }*&".*&###͂"*** *.".**"**. !$@9͍|! *(|ʿ!9".!@"*** lM*.".**"*'*. !H@9 ",|il6!9"0*.*0) ʶÐ*0"0s*0 *0!&@9͍|ʳ! Ã*,I !$@9R !@9r !4@9!@9!<!4@96!$@9 | !0 !K͸ *R!2"R*R͂zB 4 *R##"R *R͂͸ ) "R!9͂͸ ! ! ̈́!ts !!o Ø q q q Yu Ny G !9͂͸ ! ! ̈́:u| !:u6!!9͂ !9͂t| !9͂_ #}!9͂#t| !Ü !͸ ! ! ̈́:u|E :u6! "T n *T zx *T !9͂  ʟ !9͂! ͳ | !9͂! ͳ 0̈́!9͂t| !9͂t| ! ̈́!9͂#͇+ẗ́ø N#F#x ~#~# `i!" !" !9͂tG !" !9͂#͇T 2 -8 +!9͂t0 w !9͂t9 zʣ *  - !9͂#͇+t" T * * - ɯþ zO|OMD!x< z> jS\>)) # = OOc zW|}!+zz,c' | DM!z>< S\))D =< |ʀgoo&o&{ͥo&! W! W!9͂t|ʶ !9͂#͇+tWÏ o # o&o&o& o&o&:!9͂!$!< " !9͂! ͠"  !9͂t,|q * #" ø !9͂!9͂#͇+ts} ® !9͂t zʸ !!9͂t,| !9͂ " ( !!9͂* ͇!9!9͂!9͂#!n͇!9!9͂tI C!9͂#͇F! !9͂ !n͇!9͂tI !9͂+͇#|!9͂t!9͂#͇+6 !9͂#͇+6?!9͂#͇+!9͂#͇+ts} <>,;:=[]. *ñn!9͂t|4!9͂#͇!9͂!9͂+͇#|r!9͂#͇+!9͂#͇+t}<&}a{oo&!9͂"*t|(*#"ê*"!9͂"*t|*t*t`z *#"*#"*tI %*!9͂͏ø!{!0:,y_xs# F+|/g}/o|}!rr,ɯ~og|!,~#fos#r{ozgí,  ***SETDRU1***Copyright 1983 Michael M Rubenstein1*!h! l :2k 2g :_*"* " *"*$"$*7"7*?"?*N"N*b"b*o"o*t"t*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*&"&*)")*/"/*5"5*="=*H"H*S"S*Z"Z*^"^*d"d! !1*k<k!(k :g_!Z"!y(9 (0()  ((! " # ( 72is1!~(E2j ##:i( ~? 2j -#i:j(͒({}%{ yOڒ?ʒs1 ͒2g~2h_! ^͒+~͒y(:h :g_͒{ f eí   ***SETDRU2***Copywrite 1983 Michael M Rubenstein1!h*" +*"*"*"*"*"*"*"*"*"*("(*.".*2"2*5"5*:":*E"E*N"N*Y"Y*m"m*v"v*~"~*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"!!K1!"!y(9ʛ(0()ʛʛ((!ʛ"ʛ#ʛ(ʛ72ҡs1!~(E2 ##:( ~? 2 -#i:(({}%{ yO?s1 2~2_!  ^+~y(: :_{ Q ;hold user number pdrive: db 0 ;hold phony drive spec oflag: db 0 ;open/make aflag: db 0 ;ambiguous? wfcb: db 0 SETDRU.DOC Page 1 Copyright 1983 Michael M Rubenstein Permission is granted to distribute this software and documentation provided no fee is charged and the copyright notice is retained. Credit where credit is due. SETDRU was written in C and Z80 assembly language. It was compiled with the Software Toolworks C80 compiler and Microsoft M80 assembler. CP/M and CP/M Plus are trademarks of Digital Research. WordStar, MailMerge, and SpellStar are trademarks of Micropro International Corporation. Microsoft, Multiplan are trademarks of Microsoft Corporation. The Word Plus is a trademark of Oasis Systems. Perfect Writer is a trademark of Perfect Software. Z80 is a registered trademark of Zilog, Inc. What is it? Ok, you got a hard disk for your CP/M system. It's great having all that disk space, but then there are the problems. The directories get pretty big; even with a sorted listing (as from SD) it's pretty hard to keep track of what you've got. So, you start putting things in different user areas. CP/M sure doesn't make that easy though. Fortunately, there are a number of programs (SWEEP for example) which make it easy to move things around. Now that things are in different user areas, you can keep track of them, but there's another problem -- you end up with lot's of copies of some of those programs because CP/M doesn't let you access a program from more than one user area. So you search around and find some program which will let you access a program from any user area (and from any disk, so you don't always have to specify the disk). ZCPR by Richard Conn works nicely. That helps with a lot of your programs, but not with all. What's the problem? Well, a lot of the programs you want to use need overlays. Many -- too many -- don't allow you to specify where those overlays will be. So you need copies, of the overlays at least, on each user number. Others need data files or swap files. A system can get pretty cluttered just with WordStar overlays. SETDRU allows you to use most (unfortunately, not all) programs with some of the files used by the program redirected to standard drive and user areas. When combined with something like ZCPR it allows a single copy of a program to be accessible from any drive and user area. SETDRU.DOC Page 2 What's it need? SETDRU requires CP/M 2.2 Z80 processor. It will run with a minimum of memory. SETDRU will probably not be very useful unless the system contains a hard disk. I have reports that SETDRU also works under CP/M Plus. An 8080 version of SETDRU is being prepared by another person and should be available soon. How does it work? SETDRU installs a "filter" in high memory which monitors file accesses and modifies them, if necessary, to use standard drive and user areas. This filter is a temporary thing; it will disappear as soon as the program terminates. When you apply SETDRU to a program, you tell it which files need to be redirected to another drive and user number. SETDRU may be installed as a modification to the program (integrated) or as a separate program which loads and executes the desired program. Advantages of integrating SETDRU with the program: 1. There's one less file to keep track of. 2. In many cases, because of the allocation unit of CP/M, no extra disk space is required. Advantages of separating SETDRU from the program: 1. This technique may be used with programs, such as WordStar, which verify the program on disk. (WordStar does this when you try to use MailMerge or run a program.) 2. Since the program is unchanged, installation procedures are not affected. Also, some programs may modify themselves. This is only possible with separate installation. 3. If you haven't installed a system to make programs ac cessible to any user area, you only have a small program (about 1k) to make multiple copies of in different user areas. When won't it work? There are several things a program might do which will make it impossible to use SETDRU with it. SETDRU cannot handle programs which: 1. Require the CCP to remain resident (e.g. EX or SYNONYM). SETDRU.DOC Page 3 2. Use the BDOS entry address (at location 6) to determine addresses in the BDOS. 3. Modify the device field in the FCB after the file is opened. (This should never happen, but, of course, it does. This is the problem with applying SETDRU to MultiPlan.) There are, undoubtedly, other situations which will make SETDRU unusable. SETDRU makes some assumptions as to what is intended. These assumptions are usually valid, but may not always give the desired result. Installing SETDRU. When SETDRU is run, a summary of the instructions is displayed and you will be asked a series of questions. At any point in the procedure, you may terminate without installation by typing control C (^C). Upper or lower case may be used. The first question is Do you want SETDRU integrated with the program (y or n)? Respond "y" or "n" (and press return). SETDRU will then ask for the name of the program to which it is to be applied. The file type (usually .COM, but it may be different for special situations) must be specified. If SETDRU is to be integrated with the program, a copy must be accessible. The drive must be specified if it is not on the default drive. Make sure you have another copy (several others!!!) as backup in case you have to reinstall SETDRU or you find it won't work. If SETDRU is not to be integrated, the program need not be available. The drive specified is the drive from which the program is to be loaded when invoked. In this case, you will be asked for the user number from which the program is to be loaded. SETDRU then asks What is the name of the program to be created? Enter the name you wish to use to invoke the program. Again, the file type (usually .COM) must be specified. The drive on which the output is to go may also be specified. Note that this name may be the same as the name of the program to which SETDRU is applied. This is fairly normal when integrating and may occasionally be useful when not integrating. You will then be asked for a list of up to 8 files which are to be redirected. If you don't need to use all of them, just press return to terminate. SETDRU.DOC Page 4 If the drive is specified, it is the drive where the program will look for the file at run time. The user number is the user number where the program will look. If not specified, the current (AT INSTALLATION TIME) drive and/or user number is used. Now comes the hard part -- deciding on the file redirection. The order in which the files are specified is important. File names may be ambiguous (using "?" or "*") or unambiguous. When a the program attempts to open, search for, create, rename, or delete a file, the list of files will be scanned. For an open or search, the file will match the first ambiguous or unambiguous name on the list. If the name on the list is ambiguous, an attempt will be made to open the file on the drive specified by the program. If this fails, the open will be attempted on the drive and user specified in the list. If the name on the list is unambiguous, the file will always be redirected. For the other operations, only unambiguous names in the list may match. If there is a match, the file will be redirected. In any case, if there is no match, the file will not be affected. Examples. The rules for redirection look more complicated than they really are. For most practical purposes, you may just assume that an input file matching an ambiguous name will be redirected only if it cannot be otherwise found, and that an input or output file which matches an unambiguous name will always be redirected. There are a few things to watch out for. Remember that most programs do not create files with the name you finally see. It's common to use the same name with a file type of .$$$, but other schemes are sometimes used. You will have to specify the name actually used for creation of the file. Also, it's possible to really confuse a program if the order of the files in the list is not correct. For example, if you have the names foo.* foo.bar in the list, the program may write foo.bar to a redirected drive and user number, but then read a copy on the current drive (or the drive specified by the program) and the current user. It's almost always best to put unambiguous file names first in the list. Example 1: CAT (public domain catalog program). This is a simple case. The program uses a file called MAST.CAT, SETDRU.DOC Page 5 normally on the current drive and user. There is no reason not to use an integrated installation. If you wish to keep MAST.CAT on drive A: user 0, the file list consists of A:MAST.CAT user 0 Example 2: Perfect Writer This is only a little more complicated. If you use an integrated installation, you will have to use a plain copy of the program if you wish to modify Perfect Writer, so a separate installation of SETDRU should be considered. Let's assume we decided to use an integrated installation and put up with a little more work to modify the program. Perfect Writer uses a file PW.SWP as a virtual memory work area. It may use a file PW.HLP for help. Again assuming both files are on drive A: user 0, the list A:PW.SWP user 0 A:PW.HLP user 0 will work. Example 3: WordStar When a program is run is or SpellStar is invoked, WordStar must load another program and run it. Before doing this, WordStar checks to make sure that a valid version of WordStar is available. It will not recognize a copy which has been integrated with SETDRU, so a separate installation is called for. In order to keep WordStar accessible, one could include in the file list the WS.COM, but one probably has other .COM files that one might wish to run, so *.COM should be included. WS.COM need be included only if it is not on the same drive as the other .COM files. WordStar also uses overlays. Just which overlays, depend on the options used with WordStar, so it's probably best not to specify the unambiguous names. Let's assume that WS.COM and the overlays are on drive B: user 15, but that other .COM files that one might run are on drive A: user 0. The list B:WS.COM user 15 B:*.OVR user 15 A:*.COM user 0 would be appropriate. Note that this would not work properly if *.COM were before WS.COM. The program generated by SETDRU could have the name WS.COM if it were put elsewhere than drive B: user 15, but that could get confusing. It should have a different name, or one could reinstall WordStar with a SETDRU.DOC Page 6 different name. Example 4: The Word Plus This final example is rather complex. The Word Plus is a spelling checker which is implemented as a collection of programs with a master program controlling them. The programs use various files with file types .TXT and .CMP. The master program, TW.COM, may modify itself under certain options. Furthermore, logical updates to the main dictionary are actually put in a file UPDICT.CMP. When this file is updated, a new version is created as UPDICT.$$$ and then renamed. One could make this even more complex, as special dictionaries can be updated by the program also. We'll assume that any special dictionaries will be accessible though. If all these files are on drive b: user 4, an appropriate file list would be TW.COM user 4 UPDICT.CMP user 4 UPDICT.$$$ user 4 *.CMP user 4 *.COM user 4 Removing installation of SETDRU. Sometimes it will be necessary to remove SETDRU from a program. This is only a problem if SETDRU has been integrated with the program, as if it is separate, all that's required is to delete the separate program generated by setdru. To do this, the program UNSETDRU is provided. It is invoked with the command unsetdru where is the name of the program from which SETDRU is to be removed. The file type (usually .COM) must be specified. Make sure you have a backup before doing this. For the hacker. The source code of SETDRU and UNSETDRU have been released. The installation program source code won't be that useful without quite a bit of work since it uses a private run time system. It should be possible to modify it for your flavor of C, or to rewrite it in whatever language you prefer -- it's not a very complicated program. SETDRU.DOC Page 7 The filters themselves SDRU1 and SDRU2 (which are used when not integrated or integrated respectively) are much more interesting. These are coded for Microsoft's M80 assembler using Z80 mnemonics. The principles involved are quite simple, though the implementation is a bit tricky in places. The filter intercepts all BDOS calls. For certain file calls (open, make, etc.) the table of file names is searched for a match. In some cases (make, delete, rename) only unambiguous names in the list may be matched. If no match is found, control is simply passed to the BDOS to process the request. If a match is found, the request is modified to the desired drive and user and tried (for open and search, the request is first tried unmodified and only modified if not found). Assuming the modified request is satisfied, the drive in the fcb is then changed to 17 plus the address (relative to the start of the table) at which the match occurred. This is an otherwise illegal drive specification which will be detected on other operations. On any other file operation, the drive is checked and if illegal is modified to the desired drive and the user number is changed to the desired value. Of course, these must be changed back before returning to the program. There are some details to take care of to install the filter. If integrated (SDRU2), the required program must first be loaded. Otherwise (SDRU1), the program must be moved down to the start of the TPA (0100H). In either case, the filter must be moved up to just below the BDOS. Moving it is easy enough, but there are a number of locations which must be relocated. This is done in a very simple manner. When modifying either of the filters, care must be taken to preserve the relocation. Because relatively few people will have any need to modify the installation program and because it is written using a nonstandard run time library, a relocatable version (SETDRU.REL) is provided containing all needed routines except the filters themselves. There are a few things which must not be changed if this installation program is to be used. The start of each filter must contain Bytes Usage ------- --------------------------------------------------- 0- 2 A jump to the executable code. 3- 4 The length of the filter. 5- 6 The length of the program to be loaded will be put here by the installation program. This is only used by SDRU2. It is not set or used for SDRU1. 7- 19 The drive, user number, and name of the program to which SETDRU is being applied. This is only SETDRU.DOC Page 8 significant for SDRU1, though it is set for SDRU2 also. 20-123 The table of file names to be redirected. Each entry contains the drive (A=1, B=2, ...), the user number, and the file name (as it appears in an FCB). Asterisks are expanded to question marks. 123-135 Identification for the filter. This is only significant for SDRU2, where it must be "***SETDRU2***" for unsetdru to work. Note that the only parts of SETDRU which is dependent on the Z80 are the filters themselves (SDRU1 and SDRU2). The installation program and run time system will run on an 8080. After modifying either of the filters, a new version may be linked with the command l80 setdru/n,setdru,sdru1,sdru2/e I'm not sure what modifications anyone would want to make for general use, but it might be necessary to change some things for specific programs. The following variations have been found useful in the predecessors to SETDRU. These are not so much recommendations as suggestions for things to look at. SETDRU will not work with Multiplan. The problem is that Multiplan contains code to 1. Open the overlay file on the current drive and user number. 2. Get the current drive. 3. Change the FCB (while it's open!!) for the current drive. Horrible isn't it? Well, it doesn't do much good to complain about turkeys writing programs; we're stuck with them. If the filter is modified so that the first call to BDOS function 25 (get current drive) lies and actually returns the drive the overlay file is on (and the help file; they must be on the same drive), Multiplan will work fine with SETDRU (I think. This has not actually been tested, but it works in another such filter.) The filter might also be modified to correct deficiencies in the program or operating system. For example, on a CP/M lookalike which supposedly supported incremental backups through an archive attribute, I found that the system would allow the archive attribute to be set by the rename BDOS call. Unfortunately, WordStar renames the temporary (.$$$) file with the same attributes as the original file. This resulted in modifications made by WordStar not being detected for backups. It was a simple matter to always clear the archive bit on a rename. (Again, this was not actually done with SETDRU, but with another, similar filter -- still, it should work here too.) SETDRU.DOC Page 9 U`T%Th5%:SIGNONTT4d ANASKUSE@U`Yp h(Y CDbPV%>-YTB0 b0rID˕},hʨ ardD nQ ,9rA`+4`X"F.QVUvV0mfaנh#hBBF"1U@VU+4`@/jʸArf V#@(@@uDX,;*`82#rk#DaP'(L@Y f`UaӰ9rD˔B$9YT`E˔C͡`, B$ \!.Vh_ՅQD;"EX" 3@UaPV'8p DX"NfpFE9D5;l 62@ hʳ@,:(ô`"Eul[F*`82bp4ͷ ȌF@+ B 9Yx`D EX" 3m D2[mq>-YWuwY||YF>X"\NXY} 0Xb6mbpV' ʭL:*`2"`N@?",NäBVf 9r@ jʭ@B2f0  (jʣ@br"`EX"3ih*0@Pȋ 8E 8 XT@"Arf )>-YW qvDBDXUbZTD zX"DXsX͵LV-rD˕V,ՕC8dͬLH6h B$ \!.Vm)`F˔B \͸@, B4 F9r@D *!Š.Vm `r@ DX,:v./`:,g ,XȀyJ< 3 KZY<!,* BVt cY<F#dudmyrh+a峠nOd˔@%@r 19f07+6D8"P"û@r9n`d@K4a06hs  \2P v .Q} @iܬ& +6فD n#ͽ@'ū @H3h GFr@6Y!,n͸@gū @@69YF> Tlڎp?'ū*@ Ke Z!ҀVm`pB"P͢f`CՅh$u@T##`9YE@ 4e\AVQ _WLU@,:ɗ)Ku X 6ā2 n#B 3@+60D {bP|a2fF &\-@@63k0!jʪrͣ6 {?'ū A+6D ͤ6miP+NX,:& ɗ)u&㠀E* EQt2F ;NeF9m "y@nQP ; &3@r7FhoMQn:p6D2)PR*n7 s Qm2 aeF9m @c9L'C)~ @ n7΂a:DcI&(E9!i:Mql23 o:FSqeΧC 3MQpI7Άat4c2fc\ g4f-Ia2Hb2gC) ȥB!H bh@s2CeMAe9 p2&cI 3MSnDr0A@T :m1LSy)&(a6Nbi 1D3i3LAp( qt&(i6 h Qr9 h41e&(@ $s &u7NbeCIc:Mr4 :̧!Hi6#(s2q 4CA3MQn7΂@f7MA : !v2g)f4L@t4Dr0E$ Mig:Χ1`h2 Ɠa@w4  a<#(e2NFSd@ @o:Si6DsI 6N3@h2 Ɠ :&u7NbAl-XThB\#f9f@&LtRDH.SWITC݀DDC.GTD2Hʈ C.NOTT2THC_USERʀ4RG.dtUEU5(H.TDUPISDIGI%SETFCBe4UDT͸TOUPPE e5E$5 @\-@@˕ ٠eS`9rh0BnQ9rhGl} 0&2\ˣ$ 2TKMQI9 BpT`eDUY@DrD gʉ UԐӠUu$4@$jA&Hq 8UԔT`Uu%4U@4jAVho1p ~Jh3TS$H%= eR?DDISKOБSDd4( U?TPAPd%E%M-~BDOS_QЗdD%TdeQA~PHq ~J@ ~\hQ0 ~1P I Ȉ*ik )K*8RSV TDU@00\BY 4>-YV HXF" :*,!, "͡ū* 69EXP@4eVg`  EtUXR*€ BY2Xt`Bc.  9=R2K) 2ˣ/ :RSV#0@ LpTQ`d4Dt@@jOb0l?Mc&:TQgUQS`e4UDT@L<\.V+_<,Y1-B#MQ56pӑQT2Tx =6P5sɎT24C.NEGӓU d4UI@$jAfHq 8TS $R E.FME-)t} *$aQ c%^Ɏ$RE.14Ri $t C@SXTP˔%P`.3c  MaR:P# :'Q`4R RE.2MBV@2c : K` Rp $@#31]8 %@ qg'[&:KP%2 LP5 `X3c L:ˌgng system. For example, on a CP/M lookalike which supposedly supported incremental backups through an archive attribute, I found that the system would allow the archive attribute to be set by the rename BDOS call. Unfortunately, WordStar renames the temporary (.$$$) file with the same attributes as the original file. This resulted in modifications made by WordStar not being detected for backups. It was a simple matter to always clear the archive bit on a rename. (Again, this was not actually done with SETDRU, but with another, similar filter -- still, it should work here too.) SETDRU.DOC Page 9 /* setdru -- install setdru1 or setdru2 */ /* copyright 1983-84 Michael M Rubenstein */ /* version 1.3 9 Feb 84 -- eliminated Z80 code */ /* change in run time library only, but version */ /* changed to avoid confusion. */ /* version 1.2 2 Feb 84 -- code modified for distribution */ /* version 1.1 26 Nov 83 -- allowed user numbers up thru 31 for */ /* compatibility with zcpr */ #define NULL 0 #define TRUE 1 #define FALSE 0 /* declaration of structure for fcb */ struct fcb_ { struct { char drive; /* drive number */ char fname[8]; /* file name */ char ftype[3]; /* file type */ char fext; /* file extent */  char filler[3]; } name1, name2; char crec; /* current record */ int rrec; /* random record */ char rovf; /* random record overflow */ }; #define FCB struct fcb_ #define CTLC '\003' #define BUFSIZE (16*1024) struct sdr { char s_fil1[3]; /* jp instruction */ int s_len; /* length of module */ unsigned s_plen; /* length of pgm */ struct { char s_drive, s_user; char s_fname[8]; char s_ftype[3]; } s_file[9]; }; extern FCB dfcb_; extern char dbuff_[]; extern struct sdr sdru1, sdru2; struct { char maxin; char insize;  char inline[33]; } inbuf = { 32 }; main() { static struct sdr *sdru; static int integr; static int i, j; static char *s, *t; FCB infcb, outfcb, holdfcb; char buffer[BUFSIZE]; signon(); integr = ask("\nDo you want SETDRU integrated with the program (y or n)? "); sdru = integr ? &sdru2 : &sdru1; for (;;) { if (!askfn("\nTo which program do you want to apply SETDRU? ", &infcb)) return; strncpy(sdru->s_file[0].s_fname, infcb.name1.fname, 11); sdru->s_file[0].s_drive = dfcb_.name1.drive ? dfcb_.name1.drive : (curdsk() + 1); sdru->s_file[0].s_user = '\0'; if (integr) { if (open(&infcb) != 0xff) { filsiz(&infcb); sdru->s_plen = 128 * infcb.rrec; break; } ps("Cannot open\n"); } else { sdru->s_file[0].s_user = askuser(); break; } } if (!askfn("What is the name of the program to be created? ", &outfcb)) return; strncpy(&holdfcb, &outfcb, sizeof(FCB)); strncpy(outfcb.name1.ftype, "$$$", 3); delete(&outfcb); if (make(&outfcb) == 0xff) error("Cannot create file"); for (i = 1; i < 9; ++i) { ps("\nFile "); pn(i); if (!askfn("? ", &dfcb_)) if (i > 1) break; else { i = 0; continue; } strncpy(sdru->s_file[i].s_fname, dfcb_.name1.fname, 11); sdru->s_file[i].s_drive = dfcb_.name1.drive ? dfcb_.name1.drive : (curdsk() + 1); sdru->s_file[i].s_user = askuser(); } for (s = (char *) sdru, i = sdru->s_len; i > 0; s += 128, i -=128) { setdma(s); if (wrseq(&outfcb)) error("Error writing file."); } if (integr) { do { for (s = buffer, i = BUFSIZE; i > 0; s += 128, i -= 128) { setdma(s); if (j = rdseq(&infcb)) break; } for (t = buffer; t < s; t += 128) { setdma(t); if (wrseq(t, &outfcb)) error("Error writing file."); } } while(!j); } close(&outfcb); delete(&holdfcb); strncpy(&outfcb.name2, &holdfcb.name1, sizeof(outfcb.name1)); outfcb.name2.drive = '\0'; if (rename(&outfcb) == 0xff) error("Cannot rename output file."); ps("\nInstallation successful.\n"); } signon() { static char *msg[] = { "Copyright 1983-4 Michael M Rubenstein\n", "SETDRU 1.3 -- set drive and user for specified files in a program\n\n", "Up to 8 (ambiguous) file names may be specified.\n\n", "An input file will match the first matching file name. If it is\n", "ambiguous, the redirection (drive and user) will be used only if the\n", "file cannot be found on the drive specified by the program. If\n", "unambiguous, the file will always be redirected.\n\n", "An output file will match the first unambiguous (only) matching file\n", "name. It will always be redirected.\n\n", "Nonmatching files will not be affected\n\n", "May be installed as a separate program which loads the desired program\n", "or as a modification to the desired program.\n\n", "See SETDRU.DOC for more information.\n\n", "Specify drive letters in the normal manner (B:FILE.TYP). You will be\n", "prompted for user number.\n", NULL }; char **s; for (s = msg; *s != NULL; ++s) ps(*s); } /* ask yes or no */ ask(s) char *s; { for (;;) { ps(s); rdbuf(&inbuf); wrcon('\n'); switch (toupper(inbuf.inline[0])) { case '\r': case '\n': case 'Y': return TRUE; case 'N': return FALSE; case CTLC: exit(); } } } askfn(s, f) char *s; FCB  *f; { for (;;) { ps(s); rdbuf(&inbuf); wrcon('\n'); if (inbuf.insize == '\0') return FALSE; inbuf.inline[inbuf.insize] = '\0'; setfcb(inbuf.inline, f); if (f->name1.drive == '\0') f->name1.drive = curdsk() + 1; if (f->name1.fname[0] != ' ') return(TRUE); } } askuser() { static int n; for (;;) { ps("User number? "); rdbuf(&inbuf); wrcon('\n'); if (inbuf.insize == 0) return getusr(); inbuf.inline[inbuf.insize] = '\0'; if ((n = atoi(inbuf.inline)) >=0 && n <= 31) return n; } } pn(n) int n; { if (n > 9) pn(n / 10); wrcon(n % 10 + '0'); } ps(s) char *s; { while (*s) { if (*s == '\n') wrcon('\r'); wrcon(*(s++)); } }  return TRUE; case 'p screen. In this case, however, the first line is replaced with: * * * * PRNTDF v. 1.0 ERROR: Invalid parameter(s): X, X  title SDRUL1 -- allow setdru use of program ; copyright 1983 Michael M Rubenstein ; installs a filter to redirect certain files to a specified drive/user ; and loads program ; zcpr solves the problem of making a single copy of a program available ; to all user numbers, but many programs require overlays or work files ; which must also be made accessable. ; up to 8 files may be redirected. ; known limitations: ; requires CP/M 2.2 or higher ; requires Z80 processor ; untested under CP/M Plus ; will not work with programs (such as MultiPlan) which modify the drive ; spec in the fcb after opening. .z80 entry sdru1 false equ 0 true equ not false base equ 0000h ;standard cpm base boot equ base ;warm boot iobyte equ 0003h+base ;i/o byte cpmdsk equ 0004h+base ;current cpm disk bdos equ 0005h+base ;entry to bdos cpmfcb equ 005ch+base ;default cpm fcb cpmbuf equ 0080h+base ;default cpm buffer tpa equ 0100h+base ;start of transient pgm reset equ 0 ;system reset rdcon equ 1 ;read console wrcon equ 2 ;write console rdrdr equ 3 ;read reader wrpun equ 4 ;write punch wrlst equ 5 ;write list conio equ 6 ;console i/o getiob equ 7 ;get i/o byte setiob equ 8 ;set i/o byte wrstr equ 9 ;put string to console rdstr equ 10 ;get a string from con cnstat equ 11 ;console status getver equ 12 ;get cp/m version numb resetd equ 13 ;reset disk system seldsk equ 14 ;select disk opnfle equ 15 ;open disk file clsfle equ 16 ;close disk file search equ 17 ;get first disk file ;(ambiguous reference) snext equ 18 ;get next disk file delfle equ 19 ;delete disk file rdseq equ 20 ;read disk sequential wrseq equ 21 ;write disk sequential makefl equ 22 ;create a file rename equ 23 ;rename disk file glogin equ 24 ;return login vector curdsk equ 25 ;return current disk setdma equ 26 ;set dma for dsk access getalc equ 27 ;return disk alloc vect wrprot equ 28 ;write protect disk getro equ 29 ;get read only vector setfla equ 30 ;set file attributes gdprm equ 31 ;get disk parm ucode equ 32 ;set/get user code rdrand equ 33 ;read random record wrrand equ 34 ;write random record fsize equ 35 ;comp virt file size setrnd equ 36 ;set random record resdrv equ 37 ;reset drive wrranz equ 40 ;write random with zero fill ; relocation macro (just 'cause i'm lazy) reloc macro n ld hl,(rloc&n+1) add hl,de ld (rloc&n+1),hl endm sdru1: .phase tpa begin: jp start dw length ;length of this module dw 0 ;for compatibility pgm: db 0,0 ;file to load db ' ' db ' ' fssize equ $-pgm rfiles: db 0,0 ;file 1 db ' ' db ' ' db 0,0 ;file 2 db ' ' db ' ' db 0,0 ;file 3 db ' ' db ' ' db 0,0 ;file 4 db ' ' db ' ' db 0,0 ;file 5 db ' ' db ' ' db 0,0 ;file 6 db ' ' db ' ' db 0,0 ;file 7 db ' ' db ' ' db 0,0 ;file 8 db ' ' db ' ' lfiles equ $-rfiles db "***SETDRU1***" ;identification db "Copyright 1983 Michael M Rubenstein" start: ld sp,stack ld hl,rfiles ;move redirected file specs to filter ld de,wrfls ld bc,lfiles ldir ld hl,pgm+2 ;set up fcb to read program ld de,wfcb+1 ld bc,11 ldir ld a,(pgm) ld (wfcb),a ld c,ucode ;get current user number ld e,0ffh call bdos ld (user),a ld c,ucode ;set user code for program ld a,(pgm+1) ld e,a call bdos ld hl,(bdos+1) ;compute location to move to ld (obdos+1),hl ;save bdos location ld de,-lfilt add hl,de push hl ;save new location ld de,-filter ;compute relocation factor add hl,de ex de,hl reloc 01 reloc 02 reloc 03 reloc 04 reloc 05 reloc 06 reloc 07 reloc 08 reloc 09 reloc 10 reloc 11 reloc 12 reloc 13 reloc 14 reloc 15 reloc 16 reloc 17 reloc 18 reloc 19 reloc 20 reloc 21 reloc 22 reloc 23 reloc 24 reloc 25 reloc 26 reloc 27 reloc 28 reloc 29 reloc 30 reloc 31 reloc 32 reloc 33 reloc 34 reloc 35 reloc 36 reloc 37 reloc 38 reloc 39 ld hl,filter ;move the filter to high memory pop de ;get location again push de ;and save it again ld bc,lfilt ldir ret ;go to high memory routine ; the following code is moved to high memory before execution filter: rloc01: ld sp,stack ld c,opnfle ;open program rloc02: ld de,wfcb call bdos inc a jp z,boot ;get out if can't find ld de,tpa load: push de ;load program loop ld c,setdma call bdos rloc03: ld de,wfcb ld c,rdseq call bdos pop de ;advance position ld hl,128 add hl,de ex de,hl or a ;end of file? jr z,load ld c,clsfle ;close the file rloc04: ld de,wfcb call bdos ld c,ucode rloc05: ld a,(user) ;reset the user number ld e,a call bdos ld c,setdma ;reset the dma to default buffer ld de,cpmbuf call bdos rloc06: ld hl,nbdos ;set the bdos to filter ld (bdos+1),hl ld hl,boot ;return address push hl jp tpa ;do the program ;resident filter starts here nbdos: ld a,c ;check the function cp opnfle jr z,opnflt cp clsfle rloc07: jp z,fleflt cp search jr z,opnflt cp delfle jr z,mkflt cp rdseq rloc08: jp z,fleflt cp wrseq rloc09: jp z,fleflt cp makefl jr z,mkflt cp rename jr z,mkflt cp rdrand rloc10: jp z,fleflt cp wrrand rloc11: jp z,fleflt cp fsize rloc12: jp z,fleflt cp wrranz rloc13: jp z,fleflt obdos: jp 0 ;set to old bdos loc ;check file on open for redirection mkflt: or a ;flag for make jr opnfl1 opnflt: scf ;flag for open opnfl1: sbc a,a ;0 for make, ff for open rloc14: ld (oflag),a ld a,(de) ;may already be set to phony cp c rloc15: jp nc,flefl2 rloc16 equ $+1 ld (fstack),sp rloc17: ld sp,fstack push bc ;save parameters push de rloc18: ld hl,wrfls ld c,17 ;offset for phony drive inc de ;point to name ckloop: ld a,(hl) ;are we done checking? or a jr z,nored ;yes, no redirection sub a ;set not ambig rloc19: ld (aflag),a push de ;save pointer to name push hl ;save pointer to table ld b,11 ;length of name+type inc hl ;point to name in table inc hl rloc20: cmplp: ld a,(oflag) ;should we consider ambiguous? or a jr z,cmp1 ;not if make ld a,(hl) cp '?' jr nz,cmp1 rloc21: ld (aflag),a jr cmp2 cmp1: ld a,(de) ;compare and 7fh ;strip bit 7 cp (hl) jr nz,notit cmp2: inc hl ;advance pointer to table name inc de ;advance pointer to fcb name djnz cmplp pop hl ;got it, throw away pointer to table pop hl ;throw away pointer to name pop de ;get fcb ld l,c pop bc ;get function rloc22: ld a,(aflag) ;ambiguous? or a jr z,opnfl9 ;go to it if not push hl ;save everything push de push bc rloc23: call obdos cp 0ffh ;ok? jr z,opnfl8 rloc24 equ $+1 ld sp,(fstack) ret opnfl8: pop bc ;restore parameters pop de pop hl opnfl9: ld a,l ld (de),a ;set phony drive jr flefl1 ;now handle the redirection nored: pop de ;no redirection pop bc ;restore parameters rloc25 equ $+1 ld sp,(fstack) ;restore stack jr obdos notit: pop hl ;get pointer to table ld de,fssize ;size of table entry add hl,de ;advance to next entry ld a,c add a,e ;advance phony drive spec ld c,a pop de jr ckloop ; if the file is redirected, fudge it fleflt: ld a,(de) cp 16+1 ;if > max drive, redirected rloc26: jp c,obdos flefl2: cp '?' rloc27: jp z,obdos rloc28 equ $+1 ld (fstack),sp ;save old stack rloc29: ld sp,fstack ;and use local stack flefl1: push bc ;save parameters push de ld c,ucode ;get user number ld e,0ffh rloc30: call obdos rloc31: ld (user),a ;save user number pop hl ;get fcb address again push hl ;and save it ld a,(hl) ;get phony drive spec rloc32: ld (pdrive),a ;save it ld e,a ld d,0 rloc33: ld hl,wrfls-17+1 ;phony drive is entry in table + 17 add hl,de push hl ;save entry in table ld c,ucode ;set user code ld e,(hl) rloc34: call obdos pop hl ;get entry in table pop de ;get fcb again pop bc ;get function dec hl ;point to drive ld a,(hl) ld (de),a push de ;save fcb address push bc ;save function rloc35: call obdos pop bc ;get function again pop de ;get fcb again push af ld a,c cp clsfle ;is this a close? jr z,flefl9 ;don't reset phony spec if so rloc36: ld a,(pdrive) ;reset phony drive spec ld (de),a flefl9: push hl ;save hl return value ld c,ucode rloc37: ld a,(user) ld e,a rloc38: call obdos pop hl ;get real return values pop af rloc39 equ $+1 ld sp,(fstack) ret user: db 0 ;hold user number pdrive: db 0 ;hold phony drive spec oflag: db 0 ;open/make aflag: db 0 ;ambiguous? wfcb: db 0 db ' ' db ' ' db 0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0 wrfls: ds lfiles ;file table db 0 ;to end it all ds 32 fstack: ds 2 ds 16 stack: ds 2 length equ $-begin lfilt equ $-filter .dephase end loc34: call obdos pop hl ;get entry in table pop de ;get fcb atitle SDRU2 -- set drive and user for files in program ; copyright 1983 Michael M Rubenstein ; installs a filter to redirect certain files to a specified drive/user. ; is appended to start of program and moves it down ; zcpr solves the problem of making a single copy of a program available ; to all user numbers, but many programs require overlays or work files ; which must also be made accessable. ; up to 8 files may be redirected. ; known limitations: ; requires CP/M 2.2 or higher ; requires Z80 processor ; untested under CP/M Plus ; will not work with programs (such as MultiPlan) which modify the drive ; spec in the fcb after opening. .z80 entry sdru2 false equ 0 true equ not false base equ 0000h ;standard cpm base boot equ base ;warm boot iobyte equ 0003h+base ;i/o byte cpmdsk equ 0004h+base ;current cpm disk bdos equ 0005h+base ;entry to bdos cpmfcb equ 005ch+base ;default cpm fcb cpmbuf equ 0080h+base ;default cpm buffer tpa equ 0100h+base ;start of transient pgm reset equ 0 ;system reset rdcon equ 1 ;read console wrcon equ 2 ;write console rdrdr equ 3 ;read reader wrpun equ 4 ;write punch wrlst equ 5 ;write list conio equ 6 ;console i/o getiob equ 7 ;get i/o byte setiob equ 8 ;set i/o byte wrstr equ 9 ;put string to console rdstr equ 10 ;get a string from con cnstat equ 11 ;console status getver equ 12 ;get cp/m version numb resetd equ 13 ;reset disk system seldsk equ 14 ;select disk opnfle equ 15 ;open disk file clsfle equ 16 ;close disk file search equ 17 ;get first disk file ;(ambiguous reference) snext equ 18 ;get next disk file delfle equ 19 ;delete disk file rdseq equ 20 ;read disk sequential wrseq equ 21 ;write disk sequential makefl equ 22 ;create a file rename equ 23 ;rename disk file glogin equ 24 ;return login vector curdsk equ 25 ;return current disk setdma equ 26 ;set dma for dsk access getalc equ 27 ;return disk alloc vect wrprot equ 28 ;write protect disk getro equ 29 ;get read only vector setfla equ 30 ;set file attributes gdprm equ 31 ;get disk parm ucode equ 32 ;set/get user code rdrand equ 33 ;read random record wrrand equ 34 ;write random record fsize equ 35 ;comp virt file size setrnd equ 36 ;set random record resdrv equ 37 ;reset drive wrranz equ 40 ;write random with zero fill ; relocation macro (just 'cause i'm lazy) reloc macro n ld hl,(rloc&n+1) add hl,de ld (rloc&n+1),hl endm sdru2: .phase tpa begin: jp start dw length ;length of this module pgmlen: dw 0 ;filled in by during installation pgm: db 0,0 ;file to load db ' ' db ' ' fssize equ $-pgm rfiles: db 0,0 ;file 1 db ' ' db ' ' db 0,0 ;file 2 db ' ' db ' ' db 0,0 ;file 3 db ' ' db ' ' db 0,0 ;file 4 db ' ' db ' ' db 0,0 ;file 5 db ' ' db ' ' db 0,0 ;file 6 db ' ' db ' ' db 0,0 ;file 7 db ' ' db ' ' db 0,0 ;file 8 db ' '  db ' ' lfiles equ $-rfiles db "***SETDRU2***" ;identification db "Copywrite 1983 Michael M Rubenstein" start: ld sp,stack ld hl,rfiles ;move redirected file specs to filter ld de,wrfls ld bc,lfiles ldir ld hl,(bdos+1) ;compute location to move to ld (obdos+1),hl ;save bdos location ld de,-lfilt add hl,de push hl ;save new location ld de,-filter ;compute relocation factor add hl,de ex de,hl reloc 01 reloc 02 reloc 03 reloc 04 reloc 05 reloc 06 reloc 07 reloc 08 reloc 09 reloc 10 reloc 11 reloc 12 reloc 13 reloc 14 reloc 15 reloc 16 reloc 17 reloc 18 reloc 19 reloc 20 reloc 21 reloc 22 reloc 23 reloc 24 reloc 25 reloc 26 reloc 27 reloc 28 reloc 29 reloc 30 reloc 31 reloc 32 reloc 33 reloc 34 reloc 35 ld hl,filter ;move the filter to high memory pop de ;get location again push de ;and save it again ld bc,lfilt ldir ld hl,load ;set up to move down program ld de,tpa ld bc,(pgmlen) ret ;go to high memory routine ; the following code is moved to high memory before execution filter: rloc01: ld sp,stack ldir rloc02: ld hl,nbdos ;set the bdos to filter ld (bdos+1),hl ld hl,boot ;return address push hl jp tpa ;do the program ;resident filter starts here nbdos: ld a,c ;check the function cp opnfle jr z,opnflt cp clsfle rloc03: jp z,fleflt cp search jr z,opnflt cp delfle jr z,mkflt cp rdseq rloc04: jp z,fleflt cp wrseq rloc05: jp z,fleflt cp makefl jr z,mkflt cp rename jr z,mkflt cp rdrand rloc06: jp z,fleflt cp wrrand rloc07: jp z,fleflt cp fsize rloc08: jp z,fleflt cp wrranz rloc09: jp z,fleflt obdos: jp 0 ;set to old bdos loc ;check file on open for redirection mkflt: or a ;flag for make jr opnfl1 opnflt: scf ;flag for open opnfl1: sbc a,a ;0 for make, ff for open rloc10: ld (oflag),a ld a,(de) ;may already be set to phony cp 17 rloc11: jp nc,flefl2 rloc12 equ $+1 ld (fstack),sp rloc13: ld sp,fstack push bc ;save parameters push de rloc14: ld hl,wrfls ld c,17 ;offset for phony drive inc de ;point to name ckloop: ld a,(hl) ;are we done checking? or a jr z,nored ;yes, no redirection sub a ;set not ambig rloc15: ld (aflag),a push de ;save pointer to name push hl ;save pointer to table ld b,11 ;length of name+type inc hl ;point to name in table inc hl rloc16: cmplp: ld a,(oflag) ;should we consider ambiguous? or a jr z,cmp1 ;not if make ld a,(hl) cp '?' jr nz,cmp1 rloc17: ld (aflag),a jr cmp2 cmp1: ld a,(de) ;compare and 7fh ;strip bit 7 cp (hl) jr nz,notit cmp2: inc hl ;advance pointer to table name inc de ;advance pointer to fcb name djnz cmplp pop hl ;got it, throw away pointer to table pop hl ;throw away pointer to name pop de ;get fcb ld l,c pop bc ;get function rloc18: ld a,(aflag) ;ambiguous? or a jr z,opnfl9 ;go to it if not push hl ;save everything push de push bc rloc19: call obdos cp 0ffh ;ok? jr z,opnfl8 rloc20 equ $+1 ld sp,(fstack) ret opnfl8: pop bc ;restore parameters pop de pop hl opnfl9: ld a,l ld (de),a ;set phony drive jr flefl1 ;now handle the redirection nored: pop de ;no redirection pop bc ;restore parameters rloc21 equ $+1 ld sp,(fstack) ;restore stack jr obdos notit: pop hl ;get pointer to table ld de,fssize ;size of table entry add hl,de ;advance to next entry ld a,c add a,e ;advance phony drive spec ld c,a pop de jr ckloop ; if the file is redirected, fudge it fleflt: ld a,(de) cp 16+1 ;if > max drive, redirected rloc22: jp c,obdos flefl2: cp '?' ;and not ambigous? rloc23: jp z,obdos rloc24 equ $+1 ld (fstack),sp ;save old stack rloc25: ld sp,fstack ;and use local stack flefl1: push bc ;save parameters push de ld c,ucode ;get user number ld e,0ffh rloc26: call obdos rloc27: ld (user),a ;save user number pop hl ;get fcb address again push hl ;and save it ld a,(hl) ;get phony drive spec rloc28: ld (pdrive),a ;save it ld e,a ld d,0 rloc29: ld hl,wrfls-17+1 ;phony drive is entry in table + 17 add hl,de push hl ;save entry in table ld c,ucode ;set user code ld e,(hl) rloc30: call obdos pop hl ;get entry in table pop de ;get fcb again pop bc ;get function dec hl ;point to drive ld a,(hl) ld (de),a push de ;save fcb address push bc ;save function rloc31: call obdos pop bc ;get function again pop de ;get fcb again push af ld a,c cp clsfle ;is this a close? jr z,flefl9 ;don't reset phony spec if so rloc32: ld a,(pdrive) ;reset phony drive spec ld (de),a flefl9: push hl ;save hl return value ld c,ucode rloc33: ld a,(user) ld e,a rloc34: call obdos pop hl ;get real return values pop af rloc35 equ $+1 ld sp,(fstack) ret user: db 0 ;hold user number pdrive: db 0 ;hold phony drive spec oflag: db 0 ;open/make aflag: db 0 ;ambiguous? wfcb: db 0  db ' ' db ' ' db 0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0 wrfls: ds lfiles ;file table db 0 ;to end it all ds 32 fstack: ds 2 ds 16 stack: ds 2 lfilt equ $-filter length equ $-begin load equ ($+7fh) and 0ff80h .dephase end et entry in table pop de ;get fcb again pop bc ;get function dec hl ;point to drive hl ;save hl return value ld c,ucode rloc37: ld a,(user) ld e,a rloc38: call obdos pop hl ;get real return values pop af rloc39 equ $+1 ld sp,(fstack) ret user: db 0 ;hold user number pdrive: db 0 ;hold phony drive spec oflag: db 0 ;open/make aflag: db 0 ;ambiguous? wfcb: db 0 db ' ' db ' ' db 0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0 wrfls: ds lfiles ;file table db 0 ;to end it all ds 32 fstack: ds 2 ds 16 stack: ds 2 length equ $-begin lfilt equ $-filter .dephase end loc34: call obdos pop hl ;get entry in table pop de ;get fcb avSyntax: unsetdru ERROR: ambiguous file name not allowed.$$$ERROR: cannot open input file.***SETDRU2***ERROR: setdru not applied to input file.ERROR: unexpected EOF on inputERROR: cannot create output file.ERROR: output error.ERROR: cannot rename output.!ܿ9!]̀|=!;!"* ͓z\*#"C*]̀|w!,;R!9!\!$! 9!T!!!e!!\+|!X;!R!\8|!!w! ͪ!;*"!"**͓D,*"!\8|A!;!9!9|g!;!$9" !$9@* ͷʮÐ* " n* R!\8"|ʫîÃ!$9" * * ͷ* " õ* R!9[|!;*g!\!9!9!9!!9!!!"* ͓ʂS*#":!9*̀&}o}!9*̀&}o}I!\!9E|¤!;!$@9!9+#|!9̀!9̀!9̀!9̀͒!!ê!!9+#|:!9#+!9#+̀}! ! !9̀|r!9#+̀K}{!~og;(zW|}!+,;(|Ú|}!,ɯ~#fo|}!-|gos#r|!,o&o&o&o&o&o&o&gos#r|!, v1.6, which was just 1k in size. Its slowness under CP/M 2.2 is not noticable on a RAMdisk. VERSION 2.0 -- completely rewritten. Redesigned display formats, attributes only display under "+-?" operands. Added user number support. New algorithm greatly improves speed under CP/M 2.2. The DA name and version are no longer a part of the display, but you can view them by typing the file (TYPE DA.COM). --- Eric Meyer, 427 N. Washington #4, Bloomington IN 47401 --- ou can view them w]=kzd.2$;!!˄׊_d0KIQܔ>s Zb]WZY7bڐ l.pLxV6V}U02 B+n[^H/4^ N/* unsetdru -- remove installation of setdru2 */ #define NULL 0 #define TRUE 1 #define FALSE 0 /* declaration of structure for fcb */ struct fcb_ { struct { char drive; /* drive number */ char fname[8]; /* file name */ char ftype[3]; /* file type */ char fext; /* file extent */ char filler[3]; } name1, name2; char crec; /* current record */ int rrec; /* random record */ char rovf; /* random record overflow */ }; #define FCB struct fcb_ #define BUFSIZE (16*1024) struct sdr { char s_fil1[3]; /* jp instruction */ int s_len; /* length of module */ unsigned s_plen; /* length of pgm */  struct { char s_drive, s_user; char s_fname[8]; char s_ftype[3]; } s_file[9]; char s_id[13]; }; extern FCB dfcb_; extern struct sdr dbuff_; main() { char buffer[BUFSIZE]; FCB outfcb; static int i; static int n; static char holdtype[3]; static char *p, *q; static int eof; if (dfcb_.name1.fname[0] == ' ') error("Syntax: unsetdru "); for (i = 0; i < 11; ++i) if (dfcb_.name1.fname[i] == '?') error("ERROR: ambiguous file name not allowed."); strncpy(&outfcb, &dfcb_, sizeof(FCB)); strncpy(outfcb.name1.ftype, "$$$", 3); strncpy(holdtype, dfcb_.name1.ftype, 3); if (open(&dfcb_) == 0xff) error("ERROR: cannot open input file."); setdma(&dbuff_);  if (rdseq(&dfcb_) || strncmp(dbuff_.s_id, "***SETDRU2***", 13) != 0) error("ERROR: setdru not applied to input file."); n = dbuff_.s_len; for (i = 128; i < n; i += 128) if (rdseq(&dfcb_)) error("ERROR: unexpected EOF on input"); delete(&outfcb); if (make(&outfcb) == 0xff) error("ERROR: cannot create output file."); do { for (p = buffer; p < buffer + BUFSIZE; p += 128) { setdma(p); if (eof = rdseq(&dfcb_)) break; } for (q = buffer; q < p; q += 128) { setdma(q); if (wrseq(&outfcb)) error("ERROR: output error."); } } while (!eof); close(&dfcb_); close(&outfcb); strncpy(outfcb.name2.fname, outfcb.name1.fname, 8); strncpy(outfcb.name2.ftype, holdtype, 3); for (i = 0; i < 11; ++i) { outfcb.name1.fname[i] &=0x7f; outfcb.name2.fname[i] &=0x7f; } delete(&dfcb_); if (rename(&outfcb) == 0xff) error("ERROR: cannot rename output."); } DIRFILESDAT???????????!91   _ !<—:>p5 _Y{! (6 # yt<ʆڑQ !!~w5Q !! ~ #^͆6<<=! ~ #^͆6 ! ~RP6 #JP B! ~gwP _!! ~2> 0A! ʹʴùÿ J:> _QE  ÿ> 0> P7:>ʤ:>:IBP|:œ! !>2Iÿ2I| [ Options: =Quit, =Edit, =Continue ] $ [ Options: =Quit, =Continue, or ^C aborts while printing ] $>2[ > 0> P7  a:yrF!zz~.#!> !>.#~<.<#D(> <͆ڇP>A7a:yr!zA~|#m> |  File not found...Try again... $ Just a RETURN while in EDIT will go to the main menu with no changes... $ Enter File Name to EDIT: $:[ eQ !!~wä än ä { {  DIRFILES v3.6(S), 1985 from Horn Engineering Associates (Version 3.1 mods by Steve Sanders 10/24/84) >> Loading data file, one moment...$ DIRFILES.DAT file not found...Shall I create it? $ DIRFILES Aborted...$ No Disk Space...$ Disk Full...$ ++ NO FILES ++$ DIRFILES not supported in this area...$DIRFILESDATP 3! 7 ѷ!8$!6# Vz~# c>.~# qAborted...$! #zͱP ‹! ~ ʯPâ7 G~# ³7# !z>:ɇ_~# y^# ~ _#   __ 7!z~A]{]_w#I#I!z:xGw#ix ɀAborted...$! #zͱP ‹! ~ ʯPâ7 G~# ³7# !z>:ɇ_~# y^# ! P Q + y :P =2P \ PP!\ P>2P # Q ng system. For example, on a CP/M lookalike which supposedly supported incremental backups through an archive attribute, I found that the system would allow the archive attribute to be set by the rename BDOS call. Unfortunately, WordStar renames the temporary (.$$$) file with the same attributes as the original file. This resulted in modifications made by WordStar not being detected for backups. It was a simple matter to always clear the archive bit on a rename. (Again, this was not actually done with SETDRU, but with another, similar filter -- still, it should work here too.) SETDRU.DOC Page 9  DIRFILES: VER 2.0(S) ---------------------- from Horn Engineering Associates ----------------------------------------------------------------------- NOTE: DIRFILES is the property of Horn Engineering Associates. It is released to the public domain for use by anyone but it may not be sold or offered for sale, either in itself or as a part of any collection of programs, without the express permission of Horn Engineering Associates. We request that users retain the SIGNON logo intact. ----------------------------------------------------------------------- DIRFILES is a utility that creates a data files of all directory entries in the current default drive and user area. The data file contains each file name in a format that permits the user to add a description of each file by means of the resident editor within DIRFILES. For example, when DIRFILES is run, a directory display such as the following will appear: ASM .COM: The CP/M 8080 assembler. DDT .COM: The CP/M debugger utility. DIRFILES.COM: This program. DIRFILES.DAT: The DIRFILE directory data file. ED .COM: The CP/M context editor. STAT .COM: The CP/M status utility. WS .COM: The Wordstar editor. . . etc. . *** < Q = Quit > *** < E = Edit > *** *** The menu appears on the bottom line after the screen is full, and does not scroll up the screen when the display continues. When the last directory name is displayed a blank line is inserted and the display stops. On command to contine, the display starts at the top again, with the first directory entry. The file descriptions are entered by the user via the 'E'dit function. The directory entries are sorted alphabetically, and resorted each time the data file is loaded. When in the 'E'dit function, the program asks for the name of the file for which the description will be added or edited. A single RETURN here will cause an exit back to the display and main menu. If the entered file name does not exist, a message to that effect will appear and the program will revert to the editor prompt. After entering new text for a file name, a RETURN will bring back the prompt for another file name. When at the beginning of the text line and no edit is desired, a single RETURN will exit back to the display and the main menu. When editing an existing entry, the new text may simply be written over the existing text. When done, enter a RETURN without regard to any old trailing text. It will be automatically deleted. CAUTION: A single RETURN will abort from anyplace in the editor without changes. However, If any character (even a space) is entered before RETURN while on the descriptive text line, the original text will be deleted. No problem here, just edit the same file name again to restore the text. If this procedure seems complicated, try it. It is really very simple. When DIRFILES is first run, you will be asked if you want to create a DIRFILES.DAT file. This is the file that will contain all the current directory file names. You must have available sufficient disk space on the default drive and user area for the file to exist. The maximum number of directory entries for a SSSD diskette is 128. 80 columns are allocated in the data file for each entry. This will create a fixed length data file that will require 10K of disk space. The distributed version of DIRFILES is set for 128 directory entries, but this value can be easily changed at the EQUate "NUMFILES" in the .ASM source code. A more practical value in many cases would be 64, which would create a 5K data file. No harm will be caused by creation of more directory entries than the program permits. However, only the first 64 entries in the directory sectors will be entered into the data file. The number of console columns are set to 80, but this value can be changed at the EQUate "COLUMNS". The number of screen lines is set to 24 at the EQUate "SCREEN". Any of these values may be changed and the program can be reassembled, using ASM or MAC, to suit your taste. After the .DAT file is created it will not change in size. DIRFILES calls it in each time it is run, and always writes it back to the disk when done, but only after erasing the original. In this way, no extra disk space is required. When the .DAT file is called in, it is automatically updated to delete any file name that no longer exists (has been erased), and adds any new file name that has been created since last accessed. If the existing .DAT file has been set to R/O, it will be set to R/W by the program to permit it to be erased. If the default drive was not reset, the program will log it on by means of a disk system reset. If the diskette is write protected, the usual BDOS ERROR will appear and the program will abort without doing harm to the disk files. DIRFILES is distributed with the source code to permit the user to customize it for any particular system. The user is welcome to enhance it; however, it would seem to have about all the desirable features that it needs. The code will not always be easy to understand without flow-charting it, but it is fairly well commented. In places it is a real web of confusion. It might be desired to dynamically manipulate the data file to be only as large as it has to be to contain the existing file names. (This could lead to a problem if it grows too large for the existing disk space and we only learn about it after the existing data file has been erased). BUILT-IN RCP/M FEATURES ------------------------- Conditional assembly options are provided to permit use of DIRFILES on an RCP/M. Two options are SECURE and NOSYS. If SECURE is set TRUE, the WHEEL byte (ZCPR2) is used to switch out features that would not be desired. When the WHEEL is set secure (0): (1) When the program searches for the DIRFILES.DAT file and it is not found in the current drive and user area, it does not prompt to ask if you want to create it. It simply displays a message that DIRFILES is not supported in this area, and exits to CP/M. (2) The menu at the bottom of the display screen does not contain the 'E'dit option. Only the "Continue" and "Quit" options are offered. (3) When the program exits, it does not write the data file back to disk. It simply exits to CP/M. (4) When the WHEEL is set for full access, all normal features are available to the SYSOP. The NOSYS option causes the DIRFILES.DAT file SYS attribute to be set when it is created and when written back to disk. This option excludes SYS files from the data file and they are not displayed. The SYSOP may thus hide files from view (as does SD) by setting them to SYS. THE DISTRIBUTION LIBRARY  -------------------------- The public domain distribution library, DIRFILES.LBR, contains the following files: DIRFILES.DOC This file (squeezed). DIRF-NS .ASM Source code with SECURE and NOSYS set FALSE (squeezed). DIRF-NS .COM Assembled non-secure version. (not squeezed). DIRF-S .COM Assembled with SECURE and NOSYS set TRUE (RCP/M) SOME HISTORICAL NOTES ----------------------- We first intended to retain the data file within the main DIRFILES program itself. This will not work. If the activity is not confined only to the default drive it would be possible to over-write the internal data file with the directory from another drive and ruin it, or to write the data back to the wrong disk. ZCPR causes a problem here, because if DIRFILES is not found on the default drive it looks for it in other drives and user areas. However, as it is, the .COM file is small and can reside anywhere that it can be called from. The .DAT  file is little larger than it has to be without allowing it to grow dynamically as files are added. We could have configured the program to be installed for particular terminals. This would have permitted a much more functional editor because cursor control would have been available. For release to the public domain, we decided to code it for general use on any terminal. We hope that this program will be of some use to you. It does provide a means to keep track of the identity and purpose of disk files. In our experience, it is easy to lose track of what some of our files are, where they came from, which version is which, or how important they might be. Charles E. Horn,PE 29 August 1984 Sí  DIRF3-S.COM (modified) ====================== as of October 14, 1984 I found out after putting the release version of DIRF3-S.COM on-line that the "Hit any key to continue" was no good for remote use. In conditions of heavy line noise, a caller would be caught in an infinite loop. So... I modified it to only accept "Q" to quit and to continue. In local mode (wheel byte set), DIRF3-S allows for the "E"dit option as well. The edit option is not active when the wheel byte is non-zero (remote). All in all, a nice utility for remote or local use - try it! Steve Sanders DATA COM NETWORK RCPM SYSTEMS #1 & #2 (813) 937-3608 (813) 937-6829  db 0,0,0,0,0,0,0,0 wrfls: ds lfiles ;file table db 0 ;to end it all ds 32 fstack: ds 2 ds 16 stack: ds 2 length equ $-begin lfilt equ $-filter .dephase end loc34: call obdos pop hl ;get entry in table pop de ;get fcb a DIRFILES, V3.6(S) ------------------- DIRF36-S is a modification of the Sanders version of our original DIRFILES (DIRF3) with his improvements to the secure mode in remote service. The version number was bumped up to 3.6 because of several spurious versions that were created without coorination between authors. As it was, a compare of data file entries would fail if any flag had been changed in the directory entry. Also, a request to edit a file would fail if any flag was set in the data file filename entry. This bug was only noticed when a file was set R/O, since the normal mode is to exclude display of SYS files. The fix was to strip ALL flags in the character-by- character compare routine. Otherwise, this version is identical to the Sanders version, with minor changes to the cosmetics. Charles Horn Horn Engineering Associates 02/23/85 sv4*DIRF36-S.ASMb  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMoNOPQRSTUVWXYZ[\]^_`ad۟}5O= YnHYʆW~/m2(ipop^?쨜%) iҠH@Y#>?zk=)\_QErJ*M# Tf8otgkYop_(CYLJ>L72 ed1:}ם`?xtIzݯq!Y` .+FGu ΎJ $ !HRũŎ q>)gёWQ/"iT >G??~ll ' ŘPQ|VM_^7,ҘABil5k) ?/8/?46FG|Go]Ax:_8v;kiP5쪜FG|Ge6(.+op.Hsx^a syŕbtg\^\Y"]mPPvU90)P0%HFG#>?3`cW8i,^S W iʢq#X_pϾ} %eH4xY\)xH,9PhtDQҩW%)*9$PR`=E#EK`,)H2:b^%睿qAe+ W |:IFaRYbCPR; W.cHe) G ƵIJH(wyWF/&•bt`Jg$4V嬇- iXPAJZ$H+"#>t jmG1A9#ˇR+쪜7H(īltP"X|Ȣ0PvUTx#WXs+1;a E2`o!2`qP6xHp.g;$zi畅Zx-݀ƞ(l@D0fɿ^m bUA-I)+UFG\ٖ"é,e2Ś-0زA9a d[htċS"/ 9cpr9;a @zO$5϶\Ǣbr]ӽ|}2g[ Jj(F?(gyj;'dQh\5+9FOsw[O32f)ePhHcиYon?'*+7vӼ%o=86 W Yot[r֓YR6p!+4.pFOq o=Ș%aAa|PRP~Pz۹ڒ|Odl%(\)(F?(gk'AR•brs'|/)AJA1A9tߙ'pF=~8/Aƛ(4RTh\7z#o=ɘEtHM$giw>%c•TpQI6:qy1)FG/sU72^,1,)AI022^Q^ Ҡ$]m[O~=X:/(D39OK7A5o!o=25 aI! J}N?&%h~<]%2d8&•bT@z/UlyX% A]0dl9<Dh_H5[H'g,ht&95[H'ӽ;?'={wO2}<J@ᾐMR趻ofh~m_S?&O'-$PRE+֤H]K|w WO'8Y*/ҠWeߌg5 •%>z]1+\e ?2C?0?~LW6Rhи >ޝ)X8ߠV뼒`4ۮ7[i]2fQW1C*U>2dA&cz1dѬzǩ;q+(nz$tyg}_[1y/ph]U&ё+^lC-a AB#EK&/\_ ^ybt2NvJ4. N(xpvֿ)EA-双̯Y y"h\.%8%XU2(i"(o`G2) Fs^|o;dZi,>YwUK9=I2)yg}t`4뮪ٽ7')8ot4[/$jWP+*{=n? ]C-•b4뮪xiwgv$Kt}l0y@2BBማE)8ot4:/- W >$)SX%$~4:Ͼo1<ͪѬMF;A2G y> Ѭ=?$+«d+o#5[H'ёƬ0IJATBJyl]YI*:8Z&Q~gt4[qW%jWPMR +ױ($vj>S l&•bnܼssT; YBB^ F?A2^ӊ:$Ͷ~dBc_cwIƛ( v d4w}, @cO_qWnKkW(W^FGA#^SrD fZ^^$PRFzd\ b[_潞q}gނCj8 Fv7pfG2O\oѸ yMO/FGYwUoh~Rs~58"+и,fֳ=n ɸZŶ{=c]yKơYAJ1uWUhtd]JWE/X$M"Hj<"hJ(\)FGsPwUůd ht~(pj4I%tѬz^O2>%(Pfqlmf2yeATBJO'1[/zd\ k Mp Ƕͺ*nv$~(p  x,b_0}cBJxdQPp )uTbt4}Ⱋ1㸭/zS2yeez]W%Fs{qC2D);1Z-*1{;q5 Ͼ;~xMߘFGv 9(Ep7 :*R8%e\E<(3:g{q+(m}1ziwYR]G%h]U&ёU<"hJ(\)FGYlb47|ͺ*^D2z  J|G޾3"AFG%5p +lxE fSFGYwUܵ۾$5phVo=㶾{=c]yKFW) Pŋ ũ7Fv7|H(+"( Z 2(^8uD \_^ N-pJjX< 7WC-&• ^IZH//(\)pUXdh]Um}!'B-m}1[IǰQRIfqlmf2EC W |:Ѭzm} jWP•NAfU7fd?EPRIhVo=c;oMG, jon: ܼ׳>NtFv7<dZ 2(^%ay|SEA-SxJ-PRё/W$yeATBJu, Pk+$Ve| N ֔"E!Z$Rl A ʆW%y#_KPHv74HfWh47Ͷɨ)}N ~<]%@YEpB?/$cN 2[/$c|…pJjX潞q:׏ѬMFz8td\ ʢtE!h]Uqd,oAJO'Ptkh|~nd4ɘӇvӡpty%hVo=7 Iண\_Ͷkْu^AY8e477$M2ݡ>}/,q|O+hw{>H Y XJ7y"cȭp h|[ndt4q+)+4}(*h]Ukݝd\GNpynԂ*ёܝJk?(lZ+>C-&•8xqj2:r+oPMR +Ux , } xP7G#VP Y!}\Z&Jh]Uqs0uͮmfS@Y*vܼsst}EnP@ Yn dJ)}N +%Ïg^HxZ"x V N^H 9}(p0[/$ciG(l)aDJFs^8d, 2uWUh3;%e|> x •'_q<=@cs,1R+%Ͷ>#(4.Ƞlx`5 AY,Iel4c;oMG:,MXfUHjt8MAg8oLFs|9}(XJѬz?%o (Jf۵lI:,2{& N>HIpUȢ~d :$O_q;۾'2 gߝmeʢpVo b47?n$cQīA4PR2;ze4 xO+9^/*b4 ɘӇS+2fw}5Od,o 2(^!^'htdZRYqAe+ī$#)aoPR2R#2nCҠpd ʕ%2nwL#KF btdQM\?zo nj v-HL#Dd ֫7HHY# WJ>B-qPKmA%|L70 ^pd|xBA3:?~dJIY#Y|}5_[2ye$PRpBܼ׳>m_O wO+;z%cwܐ7QHUxEQܝ;v$cQ>%,O~j4?9|% x9= sPpBV뼒`47]&2t[$c*nܼssT; x% yMxO+V뼒`4 xO+['^I@c_sA•%J/N-~d 2%:y%zzW=77/īj4ۮeK2fQXJ/l3k:V4㔾@J+Iz((l@*K6gw-UpFGntC*K c WJ$XѬz>۾/-W뼂hJE!hnYͶ扌xJ- ^'m}]vfdx^Qf4}Oxx^j4?9|}[u_L# 1o(e|($|O5{;1En+n6F۪Ylzno ( /_(Wh]h5xO+䔜w*8P5꾮v= RYB No }>$ $qmױ($@-Ieѩt- h\^ȭ YET.* ,_edё'dxd( rs;-u, G8 ё2xd,wFGYwUiwFGATBJ% o$5(l@ZW$@Mx%S RGVi7kY)( M1:2"A %8p_֗/B %El\^趟UfUs%OCHJIٖy1[qW%jWPMR ױ(${=/sy")}*bW潞q|}2z [qy-+J%a'"8%Ѹ趟U?0{& Y%5feݹcG2~O+a*]*O_}}GdtU01o(^WS|L7$RRVx}c4{0okN>HƜ>$dN^潞ݱ>7QƐm(P8psh]Uq_?3ɸAA沒~hӃ1HN \V?/Fs^/HRM- W |: īj4뮪5ȸ"«ܼ׳>ֻ9L 29%  ߐ4Ѭ?L b +w%_(0V\??1uWUՖd̢0(l/4Ҡei_!Q9/P"G϶6k A~?JVFG|1)P0%HxgFGyg}wɘ+%%9 Ia>R~j4뮪xiwX8#zS ^Sߌ'_}dTx +GAZWoFGyg}w@2J"G϶6ͺ*^D2K xIN9CRH^6hO$c}?W+HFWUjtAAYďF͞m?/$ xZa?bt4}~AA沒~dgnRh~ٳ}}K2^AppMGP'趟~d 7l4=FϬI<b,˟O_}}GdWΏW[etOƗszA2 e%!szb4|xq+( o)h\^h|~ihVmo>"o𲈔*1sǎd W 01bOƯ xeg{z3d2 %`+ PY1NGwCo~gm?hnYd\ Nͺ*^d47@ƛ(E0Xm)Fv7n $+An.+ hw{>fwd<)$ Ró6dO'_}}gd>Ba czcQ~j4?m?  ehtİ$j,7;*%9g(z(p>+I_GwYNV T2^X6 qy6l湿ϗU2A9^S W ihtO/>gߍk䌹qh|~ihVmo>"_W%Fswؑߓ`2 cWli_u )|z(h\^j4>|h-4l4?9d2 U2A9n8et4;۪^v )X*•Ƚu^I@ 7cQH 9`t4}}GͪXm} 2 x$ lX~j4w$XO_}}7d E>W۪7Y( eWױ($g{wss|#_@YxBI*A FZ$cV뼒f[y!7cQH~W7'cZWl*Yüx•2݌ܱ#'Xdh~r[oIFW[/Pk^fq|yn(e| YV뼒ej47Ͷ扌7EA N>HƜ>\Ǣ:$szB2`WѬb}$:*8kG(ygw|d̢A}Uќs~d 7l4=F͞m?_1/jďFG~W7~|;wH Y"ն6ӽc}UdgOFGs?0텟i,U(tIc趟6c1%0H8g?o/Ǐݪ[F΍SǏg?o/okFĠY1NG c|a*g}~oN^9?c^1lj *eq` +o7~"(\)6bt4:…E!( V Ԓ^KPpX$;`[ё.cXdH$©w@_@-Kʸxx i:EXx#"hJ(\)#(7Y2ݠ,7ӽmܼ׳;gd?(R S 7fU;xlKA{= W(8 il47znxJ-4HXh]Uq_?D2yhVo=7>b_)WH 8潞qynfU/n2znz/ɘ 7)BlIh47sk4뮪xiw:% AJO')ѬTf1Hj0Xm)E![j k4c];x?` K iP2+ ݹcG2~O+W1|ŶU 1[,i├Iht4:򾸌6 + Ҡpye=\[8 FG6ZUx}1Ft cs\GҾd6@ "(\)$p}!e1:y$ )[%3:ͺ*nϚd<j\ǢTKUhVo=Ǻ$jWPٖX e4q{< jWPj4(\)$ܼr K k$< WO'1>o|`477$M%p ;wHF l*h~K2,aGNIũ2Ѭ=?~1XSW.Uwќ,XGaIc{B2lOyowwVO6{~= 2Jv5:=\潞Ru7QHkhN-ɸ c{HxZZ畄l4^H^5O_VdtUhfϹ%4( C bt4zWyhn/UwxAtؒ<|P:/F?%OC2m}dUc_}UwfϹ4|e [`naq{nXRBaG` *yg}_[YwUK'=綿4|e [@l0:=l7>?޺RBaG߼{^nw}|j{f>eqymNj+K,Z<>6ďxqjo߽{>l7F>+ غRpH'~2\"A"x N "hJ(\)#(p@pё +KdQP@pY9CTBJ8 BFGJHYA I :®/)SG$`(m8/.%|4*x'!i%yR$53:s/]fvE SxY\)X$Oܱ#'x4h~n:ݻlXKpJMR +h]Um}!RǸB-m}1[Iǰ%!ytY|=tu^AY4I%tYlAƵL@YSF{3x FG#琲@-[6hJ(\)FGYlb47\mIFJQ•b4뮪xiw:HR//^FzhnY7wѬMFG#wx8et4[/Fs^χѬMFG#8et4uWU湿۾FG֥FzhnYj7[YwUKF[v7&2fQp bd4㶾OɸZ Iண\_=v x>H, j,ؑihVo=㶾{=4߻L, NAYLߘfU/n2}w>񰛾1H P7(=!4|d4gߍY2Ͼo _8ߏNT eQ￿1:_QӮzobt4z>>?ojOxO?>6c7E7t9%%c}>V[^ߓѻqMS򍄌??~f{a}>Vc=~ߡq&•r=W޽FGv3} ?oj޵+*vͻw%%z A8S?oc徙Xmq۟}5O6(i޽{7ǏC;m?@{a}>Vc=~|h]Ӛy?FGj3} 台ݻws>^XXmW8y¯~7ǏôL_|j{۾'xuAIw}|lt4:~o?u۾Q¥m?m}m}qO텟q E"B܇bm^q۟}5O3A(4RThJ(\)$Foˏ؃c2U֗op텟q EAP< ?=~J Y‡z\?텟1`C1fi֗w4O?=~z)bݼ4v(M~zO?5z[_~<:l/Y~?W.2p~1$ 64*m};z ?%cC Ei_Fo㷿mLyy·m?o)P `C}5_[(F4 湿۾?0zssݹUl Mx NѬzm_͗疌YMe$PRpBo$lhfU/n2ݞ-8JG(ljsvR !`4=/Fswؑߓ` x +|>`( HA5o4_dLMEZv-[ws>XJG;ͷ5?n:$@Yl3k:V4#`C^O_jۓ+BcͷsǎdJI]KL7yũBB|0k~ݘEaxEa$yH6( Yܵ۾9ΒEPRW\jl W۾/ϭܵ۾?0[ܒq+(•X>n`K2tXJܼ׳>Ntd̢AfU/n2[/$jWPb47k c !`Cc4뮪xiwlI PM:$ݹcG2z? 1F|}7b4_dt/n:( /_(lh4l|_:$@Yd繭v=XZBbt4:m}JZ?5J2ZdwIIm}1:ն|{=~m4㶾u^AYl_Un9~J2W= h7>HxZZg$uױ($ݵcwܐ7QHҠ$޽%QyeqBo|b+ F?%ijWf[Y񴢱/`4?9|ŮmwIƓP?0zvǏ}L2D!hN-ɸ +XfxcK2^ӊXZyg}# K p+uݿ{& u K FswolIFeqBo|hݿ4nt4z{<$ZaI>ױ($\?9&IaX$ WQ/" 2(^QRI@q|ynɸZETBJu, Fs^xxn}5Od.K7^I^ baw0kyFG#7ݽ~sԋ e6/1,)԰*E㇏'H'1lt$_ZPY\oqJjXtܼ׳>%,Etj`4{cK2DaXR@ ?l7ɘUp+VL7'Fs{cG2K Pٽ!~e7ɘUp+VL7'Fy!{ZS K h~rݦ1WɕcĐ,/‹S oƇolf[YO_qݫn2, i4;1H(t],'Fũ u^9X$5JmfhӃ1:$ɸZ֔Jj(t3ok~ݸ u^IhgYd|K K P'=\[q+( //(\)$F{3x Fs^7QHliќ[15 @J$FsA2A`+ F<ߍFGnC=sTvHJ2dP6pyPи ,) ;,j >c+ p0{^Ԃ l#p;nk[vdFk[vdόf׶ͮmّhvmˎїFs{#-, ʢ潞Sv-[2xTF<ߍFGnvdEUlaI! JB(=ᇏ'P?lޛ?fㆌ7QP{Otؒq'F?a4=vǚ7Q& v W%Fswx!ժ 5'h~r{3KkW(W^yOscWYoXJ(+;#*%!CYyQOsN>ȘӇ7y%hӃ2`WFs{qCƛ($ K iP潞v;Wph]U&y!cl vhw{>$+u^I02^ f[Y^~j4?9|t? xy~JFBVF\ qjZ&QH6)}N ~<]%Ҡ$d iXygtoUp:$Y8/UlaI! JB*83:Fs^#2fQ^I0z?0{2D!aXRH`4}KCƼA~j4?9|M篿dyMͶ>s&ufxヌb+ FϬ?+ K iP<E2;'Y{^2 p-F󓯸9?VEZ&;z%h~sk0Jv5 AY(FGjϱUFB}F -쨠,-ht}p^X潞vϻѬMFs^Xm潞vϻѬMF<ߍFGGwUZÒB8h~tٽ{=c;wYwUKy׏ vhnvq>v$㰤e1{=c;w2yh]U&y!de`WFss?}d aI! Jl3k:V4cWFW׏HFuIY=nɘ|uTp 4|d4$jWP^PF͞;~dLAijt4z}g~_~`4$ \ϑ?r+2ltߙFG#?0s%5j g[ cQHSs ϶S~|?0[DZɸZu, *8C^ Fj;֗du, (b47x9v$:*8,.Fܱ#o= ?>`479v$~(p ߓ`f[y!;zo4$uY%cM.wFGⳟO*8{EBVXmvY:$~>KY6;jWg? [/FGⳟ_8ī$#۠1:=X|}5_[2ye$pB x^fr<<7۾')}?` Wkr!=?9=x!sP0+ Fs|9}(*8{hVo=cDF[YEVۗFZ$cVۗPhՏwcVۗPl4=$cVPhӃ1Yosz%sPUpܼ׳>#S l,) ߌfUfO2@WYo_ lI Y *8hw{>H Y *8{hӃ-$Yo_ͺnO2旴" @  }y%hw{^Hƛ( vJl7^HxZfcm4w{,\pJٓ+^vnc4?9IƛEc 5`t4wPovm52އ+Z%e䗴Ͷ>3ӽnSI2EAY|O5|iw/)sd+ױ($ ݒF~:7?$cN Ǫ?[1Yo_bUhՏwcVۗPhVo=nynɸZu, Fzy9ֻ9Ld{[ `Cc4뮪ٽ7' K(X~gK2AVۗFsA2AVFs|9}(*8{hVo=/zW=7}O` lhfU7fd?deUp%Vrnϖd*8{ʢfq/-W£E!hVo=/zW=7}O` lhfU7f:(씳hn'2ݠ_ҊX/FswF<ߍFOf{$c#EKo_jt4:m=)Hz*8g? QaΫ eUpёgngy, ߾4:5~SJ7Ȓ°~> Y\SRbt$o +Up%~âL֟I|E ?|'*8{DVۗFGl oUp%~22>/izؒ7Q*A Yo_zdW K\_*8{W%F|}7԰xO+V뼒fxck4̚dlfO2 h;?n*88%5,ޢf{$c#EKi%`/Fox{UWs2!!!:O::O:!*! !45(! +/ 0y0( d!k5!{5__o&  :(͠|(  *"x2y( >28!"9!! og2"">~22 9/4*9 Co&ͦͣ} [ (!e{ͦA8Q0G: x@!\w# (͂ ?(*( .( w^. ^!h6# (?( *( ͂( w#>?> w#ͦ 8 !ɿ .,;:=?*[]<>{}a{ |ʹ}ͽƐ'@'7||}>2ͯ*Bڨ  "og"2>2! ""*B"[Ru*"^#V#^#V#N#FO/o&9O/o&9!9(> (G!9 w#Eͺw}8' RB0 >' RqRR!+ Ͱ R!+ Ͱ r!+ Ͱ r!+ Ͱ r!# Ͱ r!+ Ͱ T]KB!z> S>))0 = | |̀̀DMgo>jB0 7?= H͒<z5a)a<z {0Gɯgo||~}||/g}/o#}o&K[xAJSJDM!b"!6J"DM'd } ) W _}8(8J`9{T]=o`9y ) >' ́ ͬ͗ }>' xˆ }} ˸T}ٕ(0D=z ,= ( ͒ 0%{ , 7 ?(8ͬ x ͆ - r 8˸x ͏  ,-xG}r }مM 9r .>#n0͒ { = - nx ͇ ,-(-˸G,-r }ٕ?M 9.> 8ͬ ?= u+-(>͆ 0ͬ ͆ 8 ?x ͇ , 78ƀ8ƀ8ox٨!دoGOW_gɷɷ|لg{ً_zيWyىOxوG|ٔg{ٛ_zٚWyٙOx٘Gxٸyٹzٺ{ٻ|ټx٨ xx( ?}ٽ }ցr <(r 7{ = |٤g{٣_z٢Wy١Ox٠G{ ͬ ́ }x>' ͬ}ƀ/ƀo -́ }0͎-́ ͎,}l˸ 8 4 ͗ x( - 8́ - 8,́ }l8;*!͗ ! >4ͬ͗ ͗ ͬ--- ́ ,,,-xGg?+2n*8t z~,->' x' ͘}. ͆́ , ! >4,͢- o&0%,͗ }gr }؉}颋.:}8c~I$I~L*͢ٷx˸ }0G,<},-(-́ !>I0 ͗͘ o8 ͆ >' m.`1pF,t6|!wS<.z}[|%FXc~ur1}͆ٯx(<˸ 8 !~J 0.O!>s 8 =  n s͗ ͆ .n 0 ͎-́ OT0 j oD,:j !I}袋.}8c~I$I~L! >ͬ͗ I× nn ͗ = ͆ nf^VNF!DLT\I!!53!r1!͒!> x #-= o˸x͆(- }(x>8(z ,z `iÃ!>' |r |̀>)=|(DMbo˸88x(0 8> ̀x(>-{(ay( z(>. ( {>E>+|(|Dg>-|/ 0:p# ~# +>0w#,-  60#}˸}րogM| .(z = ~> x0w#xG%͇ %͇ ZJDM%͇ = _~65+~hìx-Sx9?+{Η@}|z z gZJDM0{ ,7}o˸? #yO!@9i&?  #?w#?/w#?w#!9! E9!!9~(+Fͺ!"9!(#>2*"| >"2:( Ͷ *w*6 !\$![ (ͦ( #:~CONTRMKBDLSTCAUXUSR>2i:*ˮ~0:*:(@q##pZ* :(  ~* < >26"!"""~>2""v>2>"!"ˮ(!~8>~O6~*" w(6(2(-()(6 (8 0 :(* y(~#+ (( 66 #6 #"*: y~o p .##~ͺ(.6w4._~ =*##55= *[R8*~#"= ͣ}== ͯ}͵}*#w+#~+>*~('k!0(ˮ]k!8ˮ!]~-#8~>27kˮw>O$6̃s #r$ͣ6̏ k ( (ˮ qk(ˮ ( k ˮ*O:~ ##~._q4((=ʦ==ʩ=ʬò*:4^q*##~6ͺ>2}*|(̓|( ̓6-#[RM8( G> A~#*'C! !TRUEFALSE!9N#Y~#( G~#> >    "~(kѻ(( !0 (ˮ!!>2Sz:0:*6##ww#w$w#w:  ##N#F*B>2w#w#[s#r> "~ͮ*-w#ww##> ͮÁ""~>2:ZR0 *4#4>2:ZR> *4 #4(> >22*f(/˦:G(##~++ :O x yC!ͺ Q*:G(##~._.͚f<\=<͚*##w ͮ +4 #4x >>2:G("ͮ"*nˮ*0 SZѷR8@* N#F#s#r, 0})jS\*##w+ N#FB ͮr+s>2!T]>)j)0 0= ]R!#]*^#V#N#F#^#V>2Ͱ:0:*6 #-Nw#Fwq#p#6#w#w#w"~Á>">!DM!":*B:!>(>2>">!"2"~ʰ*w#wx(9* :O *-4 #4!*4 #4 *-N#Fq#pV+^Bq#pSZѷR&* s#r$ s#rL <?*L!\  <( !\$>2>2L:>!(* \$\<(!3: [1ð\!(7"~> 2"S"Ns#FrB(Z#\: \<(?*"}K\! !*}#"}! x \* *>) 2""{_!"*nf}(HR0nf" ^VMDnfutqp*s#r*s#r"* uKB!0>' ~#fo{_"*R0RnfR0KqputsrNF( ^VNF^V*SutKqp R*R(~w~wnf ut"6#K*K*!""*NFy(* "*B0Cnf* [R*"*RS[s#r^#V""6#>O"w2x2*"!F"" &y*"*>2"*"!F"""!\*: Nr!~6go(\R*s#r_2x( s x(T]DMx(R0 U(͝O/o&9q# (!>F0#( ~ ( #]( ~ ( (#}(  i&T-a%â}ͦo*!~6o&|:2 2}:__zѯ2*|KB " z ^C User break+=  I/O Run-time error {ʹ, PC=*ͯNot enough memory Program aborted :ʎ'1!d!->(PRN}2ޕ*ޕ&!YEl!>͛ͺ0 PRNTDF Version 1.0 u!͛ ͛ͺNPRNTDF accepts single-character parameters which may in any order; they may be ͛ͺNlumped together or separated by spaces. No attempt is made to trap illogical ͛ͺCor contradictory choices; an invalid choice terminates the program. ͛ ͛ͺ>PARAMETERS: A,B,C, or D - Drive where DIRFILES.DAT is located ͛ͺ4 (default = current drive) ͛ͺF F - Formfeed (^L) before printing (default = no formfeed) ͛ͺ+ N - No print (default = print) ͛ͺ= S - Screen display (default = no screen display) ͛ͺD T - Text file output (default = no DIRFILES.PRN output) ͛ͺ8 ? - Display this screen (default = no help) ͛ ͛ͺMEXAMPLES: PRNTDF (print DIRFILES.DAT from the current drive with no ͛ͺL formfeed to printer and no screen display -- this ͛ͺ) is the default ͛ͺ ͛ͺL PRNTDF S N (display DIRFILES.DAT on screen with no print --  ͛ͺF same as DIRFILES.COM with no edit function) ͛ͺ ͛ͺL PRNTDF CFS (print DIRFILES.DAT from drive C after a formfeed ͛ͺ; and echo the file to the screen) "ӕ}2Օ*ӕn&}oEI'>͛!"ͺ5* * * * PRNTDF v. 1.0 ERROR: Invalid parameter(s): *Օ&" !*ӕs]'͛ͺ, *Օ&" !ͺ! " ͛ͺ' ... Sending FormFeed (^L) to printer ͛!E(!͛fz("!*}ͣfz("*}*!k͖ }2Ɩ*Ɩ&ARBR(*Ɩ&!:e.͢ =M DIRFILES.DAT=!Ȗ*Ɩ&}2ǖ!}2!( FRg(!}2!(NR{(!}2!(SR(!}2!(TR£(!}2!(?R·(!}2 !(*Ɩ&! !&*#'*#'ͥ'* !&E(!N! * !&E)!Y!!-*!&E')M DIRFILES.DAT!Ȗ)!"*ǖ&AR])*!|g}o!}2 !)BR„)*!|g}o!}2 !)CR«)*!|g}o!}2 !)DR)*!|g}o!}2 !* !&}oE*!!Ȗ:p!p!}2 *!}2*&E-͛ ͛ͺ6PRNTDF Version 1.0 (Copyright 1986 by Steve T. Jones) ͛ *!&E*͛ͺ ... Writing DIRFILES.PRN !ߕM DIRFILES.! :=o !ߕ *!&E*^'*!&E+͛ͺ ... Sending output to printer *!&}oE:+͛ͺ ... No screen display !!x!P; !Ͱ !"!x*!R!P!+n&!*!}oE,!!Pfzʔ,"!x*!R!P*+n&!Eʋ,*!&E,!ͺ!x*!R!P*+n&" *!&EQ,͛!x*!R!P*+n&" *!&Eʋ,!ߕͺ!x*!R!P*+n&" *#æ+*!&Eʮ,!ͺͺ *!&E,͛ͺ *!&E,!ߕͺͺ *!"Z+*!&E-!ߕi Ô->͛!"ͺ* * * * PRNTDF v. 1.0 ERROR:  * !&Ei-͛ͺDrive *ǖ&"ͺ not found Í-͛ͺFile not on drive *ǖ&" !N! * * PRNTDF v. 1.0 ERROR:  * !&E7v͛ͺDrive *ǖ&"ͺ not found >-͛ͺFile not on drivders 10/24/84) >> Loading data file, one moment...$ DIRFILES.DAT file not found...Shall I create it? $ DIRFILES Aborted...$ No Disk Space...$ Disk Full...$ ++ NO FILES ++$ DIRFILES not supported in this area...$DIRFILESDATP 3! 7 ѷ!8$!6# Vz~# c>.~# qAborted...$! #zͱP ‹! ~ ʯPâ7 G~# ³7# !z>:ɇ_~# y^# ~ _#   __ 7!z~A]{]_w#I#I!z:xGw#ix ɀAborted...$! #zͱP ‹! ~ ʯPâ7 G~# ³7# !z>:ɇ_~# y^# !  PRNTDF Version 1.0 Copyright May, 1986 All rights reserved Steve T. Jones East Central College P.O. Box 529 Union, MO 63084 PRNTDF (PRiNT DirFiles.dat) was written to facilitate keeping track of the contents of user group disks. It reads the DIRFILES.DAT file often used by BBS's and other public domain sources to document disk contents. The help screen is reproduced below: ------------------------------------------------------------------------------- PRNTDF Version 1.0 PRNTDF accepts single-character parameters which may in any order; they may be lumped together or separated by spaces. No attempt is made to trap illogical or contradictory choices; an invalid choice terminates the program. PARAMETERS: A,B,C, or D - Drive where DIRFILES.DAT is located (default = current drive) F - Formfeed (^L) before printing (default = no formfeed) N - No print (default = print) S - Screen display (default = no screen display) T - Text file output (default = no DIRFILES.PRN output) ? - Display this screen (default = no help) EXAMPLES: PRNTDF (print DIRFILES.DAT from the current drive with no formfeed to printer and no screen display -- this is the default) PRNTDF S N (display DIRFILES.DAT on screen with no print -- same as DIRFILES.COM with no edit function) PRNTDF CFS (print DIRFILES.DAT from drive C after a formfeed and echo the file to the screen) ------------------------------------------------------------------------------- An invalid parameter causes the program to halt and display the help screen. In this case, however, the first line is replaced with: * * * * PRNTDF v. 1.0 ERROR: Invalid parameter(s): X, X ... If DIRFILES.DAT is not found on the indicated drive, the program halts and displays the help screen with the line below replacing the first line: * * * * PRNTDF v. 1.0 ERROR: File not on drive X If a drive which CP/M does not know about (determined by BDOS function 24) is specified, the following line replaces the first line when the help screen is displayed: * * * * PRNTDF v. 1.0 ERROR: Drive X not found If all goes well, the following message is displayed: PRNTDF Version 1.0 (Copyright 1986 by Steve T. Jones) In addition, the following messages are displayed as appropriate: ... Sending FormFeed (^L) to printer ... Writing DIRFILES.PRN ... Sending output to printer ... No screen display !P*+n&" *!&EQ,͛!x*!R!P*+n&" *!&Eʋ,!ߕͺ!x*!R!P*+n&" *#æ+*!&Eʮ,!ͺͺ *!&E,͛ͺ *!&E,!ߕͺͺ *!"Z+*!&E-!ߕi"DIRFILESDAT???????????!91 <  _ !<“I _Yy! (6 # yp<ʄ#ڏf !Jf !!#s͟6<=!#s͟6! ~/P6 #'P ! ~DwP <! <! ~2> SAD ʖʑÖÜ  _QE Ü> S> P\*õ:PY:š! D>2Ü2Y B0B1 [ Options: C1B1uit, C1B1dit, or C1B1 shows more ] C1C0 $ [ Options: =Quit, =Continue, or ^C aborts while printing ] $>2 > S> P\ ͈:Om!~.#> >.#~.#% > ͟hP>A\͈:O!A~]#N> ]s õ File B2notC2found, check your spelling. $ Just a RETURN while in EDIT will go to the main menu with no changes... $ B0B1 File to C1 edit B1 (RETURN alone exits): C1C0 $: cf !#â â â y y  B0B1 DIRFiles v3.7kp (c)1985 Horn Engineering Associates C0 B3 Kaypro screen and video by Steve Sanders 01/28/86) C3 B2>> Loading data file...C2C1$ DIRFILES.DAT not found... Create new file? B2 C2$ DIRFILES Aborted...$ No Disk Space...$ Disk Full...$ ++ NO FILES ++$ DIRFILES not supported in this area...$DIRFILESDATP H! (7 ѷ!M$!6# k~# x>.~# ˆted...$ N! #P ¤! ~ Pû7 G~# 7# !>:ɇ_~# y^# ~ !_#   __ \!~Aڄ{҄_w#p#p!:Gw# ɀ #P ¤! ~ Pû7 G~# 7# !>:ɇ_~# y^# ~ !! P x R yG ' :w =2w !  PP! P>2w # x ders 10/24/84) >> Loading data file, one moment...$ DIRFILES.DAT file not found...Shall I create it? $ DIRFILES Aborted...$ No Disk Space...$ Disk Full...$ ++ NO FILES ++$ DIRFILES not supported in this area...$DIRFILESDATP 3! 7 ѷ!8$!6# Vz~# c>.~# qAborted...$! #zͱP ‹! ~ ʯPâ7 G~# ³7# !z>:ɇ_~# y^# ~ _#   __ 7!z~A]{]_w#I#I!z:xGw#ix ɀAborted...$! #zͱP ‹! ~ ʯPâ7 G~# ³7# !z>:ɇ_~# y^# !  DIRFiles v3.7 for the Kaypro video-able Models DIRF is a unique utility that builds a directory listing of files on a given drive/user area. You may then go back into the listing and add a one-line description of each file with it's own built-in editor. It creates a file called DIRFILES.DAT on disk that is later referrenced and/or updated when you change file descriptions. THIS VERSION SHOWS ALL FILES REGARDLESS OF STATUS AND FILTERS OUT ALL CP/M ATTRIBUTES FROM THE FILENAMES BEFORE DISPLAY. IT DOES NOT SKIP $SYS OR $R/O FILES AND DOES NOT RESPOND TO THE ZCPR WHEEL BYTE IN ANY MANNER. This is for local use on your personal machine, not for remote use on a RCP/M system. Steve Sanders - Tampa Bay Kaypro UG / DataCOM Super Systems(tm) (813) 791-1454 or 791-1455 300/1200/2400 baud 24 hrs #p#p!:Gw# ɀ #P ¤! ~ Pû7 G~# 7# !>:ɇ_~#DIRF37.ASM]_CkH ;$ D$LLJ9sҼqb P, 7 !SD6yR4PcN)Ð4s@yCNrFaS ;ilc9pʌIc&͘#K(NsX4yAf : ЄSD=Y2p aE(MƂHM 樕3 e!Y2.)aܐ*a+#ަ l3R#F4jF޿Q1d8!s,A4IWS<0bP MToyB>8hq]lBUD Qt5vX$Ql1F1G]L~`25G.8Ey u3CQ>QDT PjQr5Flo\ qjaI]nga@Ӊt6AQ[!FQ$EGb䔆-UEgrFNqVg=Ɲ8uHK E@}DW}ѡ)LADU&~y"qflx}UY, P);]P]c8dHٔNoGƣMqcQh9"Q,sյ7vU`"h놖uh! FyE157Nh]!,zAԍĹU9GdD Nuy`=ZIpgd$jTHD Cf1Z\OZ]X@yR82ShU$!SINPmJy#l7E]lkq WpemQ^ǥ$W2CE$w @* 4hB(OWPE3!5Jr͡,RR>ס/vc秘'T~☢dp7ycvR9D&3)8k D ( %q qz/ (BJanb.D[ ˂XR2 4UVrDe-Rd\.)Ն: 3rz?0?v#""D IpB0iCϸ%4Eɒe:?E*ThέL,B:9e "O,Ua1?;' pЋ)L )\S{ tb^/;[B- RҊNsbL4.z!C&1Qn8C 8RDi׮O)Zv¡6.AuiX3;82[ At(ˡ"6 Id|2!Y_h'%.;`33ɘA^cAY~v.)SiY>q̪SVUxU2S*8+`wA6>#8 NT%IpCP΀` ApfA.rH/@nBJXӵ*A B``# a%Fp$8׵b9  R#< `b&L9P&X+&Zu) 1>F 0P8Sī+93(,28(3kL<< `qGؕkNOx`"JF;! >0,ԀbhKjF ”l9;`g }]eER A3YOF)rM"V[ [9 Z2 {n- *9 $3Av ",0 2®F7lN |vbkLxҭ필IPy/ ~ fLL A@qDD݇qa x}mT[%0A)K JNg<ҹl)L#LNt&'H}L}>R0C`~E7uQMybq4RbwMhaFh|^|-N0OEEq2vM Mb3SNRu)G_wa1HO^B*&{PCeMK4K3 ;M#[4w08O!kcvE]/iԃ$(bux3@d{(N3kL0ONBViR&m@s ؑv pj!;TBeIC= ĊoA T M kAQxudTbNMP:! pGu+#ƃ"q?3Yt2!-0- H/fVe?gdx0mɔu]_D@g яs'8VpC`_mRs ;\8o6hv>C&"wPCI:a& dz?A~#B 2/  +r1>ޣ+OeuaFue'K+3R#P0z?xI3$S=yl3.r]\f,yqSIzѹitU֙][Sp]8E6XٞpgqF&.Wǟ \2jʨP+zMV`a, #Ƙ 5Tɚ8.lə晲!cQh(haW!SH0AI*2"ǒq<)JٗU!юCz),@p1Y%Ki8G%hbpO 7I,`C FrvYT*K'n)j}J2z D?XĒkY2WF`;sCf.xf`N wk8'  Tb]1ҭjOd 9!+Ib3r6fUwcYevf\k*?J`E`T Ld3+trPX+!+uH߶b Js6_"B/# \۠5m hw:n˦k۲Dx5`wy 8uQCPp'อ"yP\H ˪6LuLITڮӥvD~"3Kvna6z↨#Cwo먜)TDFY?HDat24:, 8qv1wXw$1E v;B# 3*jF{Z 4ahy''7'm [AVq:5H!6Z +CSb EL"E1 OzJ5y|[RDDԤwB hw;9W­ʒA@q[xB0SWxE ;*,Q+i8DV bJC 1qEҍ:I U4'|q&ӛge5D!ȬD\fE:Mބ!ڄM(In Π)*MZw:5Q"<T?$L].!fF V;`Mϰꕲf;bmVrC/c)| ;1(cD <.~=Y7.:P`layQ_#x務Kb.8L+imNeex~{^}k(tr 6n;KȔ^=Yw0%ghnmយSeYc< 8/x%.~RƱbngÛ <#9e\ ?;PGX@NiSgEO+󮜐a~Rg2nSտA'B1$ھ.@u!6O2! >o.+Q6Lbj$+'AR@4;eLDBNjot'[*m/>.{7o@y3˾,~+K;(. mjKjyNn/nOPMpύL%Nl@oP:b[j%\yw_?8s fKdb (JRڟn2F '4 єh6|1/Ow_-| =O gA\CR1HijNhfO LCf,ǎE Oc7CN6G`PgKv O7j kT`8kD6'䔲X {u,F/|waƈsKnVKF0GMhCjh`>_-| t5kPD;ikx .NnƠ""ZKLr4.J4˵'ub<U;gdXuSp ٴ'k+Y:>NRt(5f0$;+) P"" A:$Ƭ8CPX !Uŭ^;g!%<}+9t ZK "!խ2uL/]}Z$#l2؄DMjH'_4 &,sV9 $9uf=GP'a!rP0Y0  p?RpgsR1_AN)RMk&kI B=3qva;2l~QVYvTeeaX!س%Ԥ?LAR1x2:G;`YǢ2R1;GŁ>6{;I6ݳMkQdkCp-`y7^6 <L:'m |Q/#,-oqP1`bCL/(rP1Og ZU#a`Ri8g}6WS!rP1 Og ZU#a8Y,WT +rP0YWCR1X2 U5*,r/1ixSC^%D3VcFk ?Rpgsߋ+rP0Y{CO SV1Hdu,iwR*Z~#["6:<+[CAGRtp]{Vf2Og ZU#a8NZkay33ibKfi] qP0Y`r?6m|A(ð8i,rQpbqEpb!C0 ry>.!!rP`A:]HcN~wqxܾ%/ j~NJ>\DqZ@P`%ϻ̺R9u۔hiܷL%NP`%hɥ9ڡygr qP0YWCR1xh/(rP0Y@8-QP?-E^K$pu*h' 1p,pBb!'Pb,pC'0!F >pu*h' 1p,|]'0'h'01pu*h'00p,''@'pE0| *4i&,^ Ѝ3 <>QP\ <0=$('P" aC#o @'fDKTTx*DF:gbr"J+NTDGVA=$<u+:|N*f\#Bݗ-lMZOuMg$ #x<"bb A-.A@~'['E2N pM bs6}p6L/1d2-tvPwK >Y]{^wTn+{} AX `0%JR,f. AX؈Krmw͖V8r8$ AX ᕟ'g ӻ|./|#؈Kz1r8yw_ЬOL3q2YD$Qq>V^yr6,qw6>%VwE"$ l~ȘfYbO+/HYmXӻ̺R"2q X)K{DPo T6fEM]00t"cWu^iS VAFsV/2[rMX#L]kvrP>Rtp(ڞ,><f:hS7{&JP`%c&R$(uf̂?t~~r ƠigBWl'.;%E3qv.`aS3qv~8x3BqF[g'q~]Sk$EV CwonqR4gRiF/|?3wZs6-L\F7ݢiT"6߳YwgfPg%{zWoL#[Rpgs=} ͖~8C(JRиx?lp,֭Pw~yw_ЬO_mϙfKdt޽HEg;MzʀLl3qB@lӻ̺7B΅xΥ6=SK _mưhaUd';C83TTx!F/F,Kd ί:S'ԡy8Lj %(C^ Ж*H>;~B˼C[ QN0+#f-Ͳ|{|U)n"{GͰ(FF۵9:%4-'{Azw* *!S RCSkN!.pM . 188ͳ5Jڋ…[xAB@M\8u<+[CA+\xwR]/ ̋oS,\L<+[CA+\xsKm8 [+7%FPL,w2><+[CA+\xsK8[xDM(<+[CAz<6O22 Njڟ.-{WoLA\蔹ޅ|C˅!!EpC?y* *!HoOڡS* p}] i&,vu*h' 0pu*h' 1p/U(&7Ș^<[[_\`'Pb,pC'`RmmWb,pB0'P"zwAXA LB*̑6'Pb,pC0'`RmmmWb,pB ''>L?[r寍1 h'02pu*h'01p,p$pءM i&,DuG2$= e0  p寍1 h' 2p,p</>'Pb,pC '7'@'A T,!fRmmHTM[Er,p,p$paS,!fRmm'GDqS`~.!'7'@'FPL,!fRmmܘqF>lr,p,p$pM i&,v,v,p+FM+'7'@'M i&,v,v,DՄ<6T#..!'7'@'p* &*!1c gTREH]]6&O * &JNj!Yg :rlq6$Ǽ؍S:r1$aJT䛍DFD6$uvKg+6$pV!`:)1(egMaJoTċ!Yg~`VJAmF ::: M :::6$@aQuF51ae ~hߪ$ H |g$oЊoߪ$ O!Yg~w" 0.U Rͦk* gx"W;aQ^{t,G%lx:K6S;aQ~^M{.~ 0x  Oʇ3U?tߴw{_|Cw۶U~Ϟ-E9]%lx@[vޡt'[qj9RpgyE rsѩ"|cpR4 ]y8PC{w_a~őE"h؈VbӒie0 w1VmO^3w;ٽRpwJq2خvRbN7b'R|^b'bN7_H^"(rƋ:auǓq{)2.g3˾,zʀυ pft)xĢF؈K- 鹋w_Kw_m?םo/'iG>2x2^K2Rӏ8z'ED+r& qtw pf؈K2^^K_cr&bT8Sm(Eѡq2f1-~!oSٰȠ޳RK?4( g뢮벮ረ4( g뢮Jsa!페#~ ՟P|n%4 E 27fA&nP 2RO@/ 7pR8 }oSR%y*2ž?o;1wR-LC~<=_1Sh6|1/C xXaNki &n߽\~-"*nN&b<펨"!fEԄ@F+^&oX {V˜e˙XVFe~ &gH ](J1앯{IhCRtohxep%b-JПaH oc˅!FG%/ʓG#2q=_!1/R(hVp+ `^:9%Uӏwz'2R 0%T`PtwȄƆV7yZ;HiR&2z˼|(ANp7cy)x~ ՟k"lfogr 5%Ur%\YbB&"2uAl4^^K_c;%T`KdQ؈RpqHB%(0'|†y]H"w:SR%H|Ɖ_AvՏ!FhF"Xʓ13sx5YÖ,~+ RYÛb+҉p.J[<ӈݎ^ማ/ 7pR؈VbӲ~Jqѡq§z*sׯJ-**'iZU6pKz ڡyg∛/!FhfҨ"L "bGX Qȴ%NSOƍ~( g~UH*J1i^20U40U80U1`lS5i*02,zjn ϐ ϣ\bT|*Z*tOʇ3sG$asWoL((hl͋gD{zWoL(lwb~A(hl8󶋓{DPCϼ*i:aOnfԫ8J! `Hfo T3B y'of(889!Sfazʀɔ4C]kG񏻲_/_,˘~ v5J.|>cwɥw_hfq K]k뎍!Fȧk&k*Bɛ_31d2]51 +Rϭ }B?T6_oI ==?3sG!Mk&kE(ۉoMk&k3hNd Z׀d{['g~ ommh ?sR`He,3KwMk&k2񏻲U5jDϢ{*i7`h͆sNMbo(n_~\ ZU#aa8Yh_*im }-֪D7ɺHdlw;߫,2tN"p lX:>lr"\ b;4 ); c/ϰ8A yb{ȘR,2I"p *b;,1fk$E"(Ml&+w1m* qp\,FN`s6-_AN)ijc"}q6̜!̅X ˲ fLCk$E0zf\o _Ck$Exb (conf̖<6-nwpxJzfl&ᗫ9miƹ( g`ʖFXg83sǓ%`<>83#AN)nsuȋF`c"}q6fSkVdس%߼691jNr/Q fq2YSJr_%DFfq_2=@aFfqX aZ*-PB N$Kk8E Oc?JT֘k2Mʇ>h5k2ɋ?so)Lhjn _2PaNU21X`%8-Ev)Y%hEv)YU2jyN_1N_2{,'2v+!w:Ş,(!%q(!lJg!%Og!jᄏ__2 xAc;!nie0 _%s뛜OOmϼc[Rj<2Am)gTM&Ϋ uugM@WP`L0kD%3'coC;)EOo؈xAFeM>c%c9f&k?"Q’nvq!"QQA@1+ !YWJrX _1+bn)%x(("a12<`)%x( !% 8_1a)U2< aWP _%36o !%4!؈VbRdU21N< Ē2tJhE6}Mɞ!%#?\!%Og!jyN_1tJhE6}Mɞ!U2y)Y%CJ|)YU2h\A@,2tJhE6}cɗU%snˆտ\;HpxAF!FxAFG!YgX s;pf*$peQ_8UH.n)"-h_2+ba:gr"cxE,tZP!8_1!-0Ş,_2!U2(0S5"-Gî(!U2!%!&!( !U2=`)%)9a:S5؁kȋz!%xî_2 p_%(;-C!_DP fOw2R1;/!PdU"d:AEgLpu%Kb"N`VH.UZ@Ew * pW MYSORT .REL 26 B0 512 4 USQBASE .REL 41 8D 512 4 LDIR23 .SUB 54 6A 256 2 SETDRU .COM 00 DF 6016 47 SETDRU .DOC C5 A4 19456 152 SETDRU .REL C3 E3 7296 57 SETDRU .C A5 C2 7040 55 SDRU1 .MAC 54 81 9216 72 SDRU2 .MAC 61 CD 8576 67 UNSETDRU.COM 31 FA 1408 11 UNSETDRU.C 2F 51 3072 24 DIRF36-S.COM 9D C2 2176 17 DIRFILES Fog Library Disk FOG-CPM.033 Copyright (1988) by Fog International Computer Users Group to the extent not copyrighted by the original author for the exclusive use and enjoyment of its members. Any reproduction or distribution for profit or personal gain is strictly forbidden. For information, contact FOG, P. O. Box 3474, Daly City, CA. 94015-0474. as part of the description of a file indicates that the program is distributed on a "try first, pay if you like it" basis. If you find the program(s) meet your need, please refer to the author's documentation for information on becoming a registered user. Only by registering and paying for the programs you like and use will the authors of such programs continue development. Often, more complete documentation, additional modules, and new releases are available only to registered users. CP/M utility programs. Filename Description -01-08 .88 This is the release date of the disk. -CPM033 .DOC This is the description of the disk contents. DA2 .COM 5BD9 2K ver. 2.0 [DirectoryAttribute 1 of 2] Reads and sets the CP/M flags, displays alphabetized directory with file sizes and much more, and allows user to select on, display, or change attributes. DA2 .DOC 5130 7K ver. 2.0 [DirectoryAttribute 2 of 2] DUMPDIR .COM 1F86 2K ver. 1.20 [DumpDirectory 1 of 3] Displays disk directory by filename and allocation to allow your to find pieces of disk files. MAC source included. DUMPDIR .DOC 6277 1K ver. 1.20 [DumpDirectory 2 of 3] DUMPDIR .MAC 6C99 5K ver. 1.20 [DumpDirectory 3 of 3] LDIR23 .COM 15A6 5K ver. 2.3 [LibraryDirectory 1 of 7] Directory program for squeezed and unsqueezed library (.LBR) files. Source included. Requires MAC (or RMAC) and SYSLIB3 for compilation. LDIR23 .DOC 5920 3K ver. 2.3 [LibraryDirectory 2 of 7] LDIR23 .MQC 95B3 8K ver. 2.3 [LibraryDirectory 3 of 7] MATCHF .REL 4837 1K ver. 2.3 [LibraryDirectory 4 of 7] MYSORT .REL 26B0 1K ver. 2.3 [LibraryDirectory 5 of 7] USQBASE .REL 418D 1K ver. 2.3 [LibraryDirectory 6 of 7] LDIR23 .SUB 546A 1K ver. 2.3 [LibraryDirectory 7 of 7] SETDRU .COM 00DF 6K [Set Drive/User 1 of 8] Allows calling overlays from other drives and/or user areas. Will attach itself to a program or stand alone. C80 source and module to remove SETDRU are both included. SETDRU .DOC C5A4 19K [Set Drive/User 2 of 8] SETDRU .REL C3E3 8K [Set Drive/User 3 of 8] SETDRU .C A5C2 7K [Set Drive/User 4 of 8] SDRU1 .MAC 5481 9K [Set Drive/User 5 of 8] SDRU2 .MAC 61CD 9K [Set Drive/User 6 of 8] UNSETDRU.COM 31FA 2K [Set Drive/User 7 of 8] UNSETDRU.C 2F51 3K [Set Drive/User 8 of 8] DIRF36-S.COM 9DC2 3K ver. 3.6('S) [DIRFILES 1 of 10] Creates a data file for each disk/user area to allow you to better describe each file. Menu-driven program requires very little space. ASseMbler source code is included. DIRFILES.DOC 1BE6 9K ver. 3.6(S) [DIRFILES 2 of 10] DIRF3-S .NOT 07B5 1K ver. 3.6(S) [DIRFILES 3 of 10] DIRF36-S.NOT 130D 1K ver. 3.6(S) [DIRFILES 4 of 10] DIRF36-S.AQM 7EE5 23K ver. 3.6(S) [DIRFILES 5 of 10] PRINTDF .COM 55B8 12K ver. 3.6(S) [DIRFILES 6 of 10] (Version 1.0) Prints DIRFILES.DAT data file. PRNTDF10.DOC 16A0 3K ver. 3.6(S) [DIRFILES 7 of 10] DIRF-KP .COM 00A8 3K ver. 3.6(S) [DIRFILES 8 of 10] Special version for Kaypro "video-able" models. ASseMbler source is included. Note however that this source is in an ARChive (.ARK) file and that the only difference between this and the generic version is a large amount of Kaypro specific code. DIRF-KP .INF 0FF5 1K ver. 3.6(S) [DIRFILES 9 of 10] DIRF37KP.ARK 096F 17K ver. 3.6(S) [DIRFILES 10 of 10] DIRF37 .ASM 34K [DIRF37KP.ARK 1 of 1]  [DumpDirectory 3 of 3] LDIR23 .COM 15A6 5K ver. 2.3 [LibraryDirectory 1 of 7] Directory program for squeezed and unsqueezed library (.LBR) files. Source included. Requires MAC (or RMAC) and SYSLIB3 for compilation. LDIR23 .DOC 5920 3K ver. 2.3 [LibraryDirectory 2 of 7] LDIR23 .MQC 95B3  This is the release date of the disk. CLAS6 FON {4FLETTERS u[*CFONT EXE \)$fCONVPRF EXE `$fDELFONTSHP Pn $DOWNLOADEXE %t^'BDSKSPACEEXE h,l%EFONT EXE \,JFANCFONTPRO tou(FFCONFIGEXE ]e@