{$C-,V- } program pcdisk3d; {adapted from John Friell's PC-DISK by G. Gallo April 17, 1985} { types and vars req'd for disk space and dir procedures } Const blink_yes = true; blink_no = false; yes_no : set of char = ['Y','y','N','n']; max_records = 1000; Type str255 = string[255]; str80 = string[80]; str11 = string[11]; str33 = string[33]; regpack = record ax,bx,cx,dx,bp,si,di,ds,es,flags: integer; end; mem_ptr = ^pointer_type; pointer_type = array [1..2] of integer; word = array [1..2] of char; cat_type = record vol_record : integer; fil : string[11]; sizelo : word; sizehi : word; time : word; date : word; memo : string[33]; end; temp_type = record fil : string[11]; sizelo : word; sizehi : word; time : word; date : word; memo : string[33]; end; Var one_memo, orig_path, fullpathname, catname : str33; asciiz,filez : string[32]; {string input for dir scan} template : str80; Answer,S : str255; id,volume,pathname : str11; R : regpack; pointer,dta,fcb_addr : mem_ptr; bts : real; c1,r1,c2,r2, x, i, y, q, e, w, check_num, drv, crt_reg, z, t4, t1, t2, t3, vol_min, vol_max, cat_num, vol_num : Integer; ok, done, found, changed : Boolean; Ctype,GetType,ch, orig_drive, default_drive : Char; catfile : file of cat_type; cat_array : array [1..max_records] of cat_type; vol_array : array [1..100] of str11; temp_array : array [1..100] of temp_type; dta_area : array [1..130] of byte; fcb : array [-7..36] of char; temp : string[11]; InsertOn,Exitt, Escape, F1,F10, Use_Default : Boolean; {for input routine} (* the following screen and input routines were written by Donald R. Ramsey and Larry Romero and are part of TURBO-UT - a public domain utility package*) procedure Center(S: str255; Col,Row,L: integer); { Center a string on a line of L length beginning at position Col,Row } {** (Col,Row) is row and column to center on **} {** L is the length of the line to center on **} var I: integer; begin gotoXY(Col,Row); for I:= 1 to L do write(' '); gotoXY(Col+(L-Length(S)) div 2,Row); write(S); end; procedure InvVideo( InvStr: str255); { print a string in inverse video } begin textBackground(7);textcolor(0); write(InvStr); textBackground(0) ;textcolor(15); end; procedure Color(BackGnd,Txt: integer); { change the background & text color } begin textBackGround(BackGnd); textColor(Txt); end; function UpcaseStr(S : Str80) : Str80; { convert a string to UpperCase } var P : Integer; begin for P := 1 to Length(S) do S[P] := Upcase(S[P]); UpcaseStr := S; end; procedure StripSpaces(S: str33; var NewStr: str33); {strip spaces from the end of a string} begin S:=S+' '; NewStr := copy(S,1,pos(' ',S)-1); end; procedure Beep(Tone,Duration : integer); begin Sound(Tone); Delay(Duration); NoSound; end; procedure Say_Cap_Num; { Display Caps, Num, Insert in inverse video on line 25 of Video } var Value : integer; begin window(1,1,80,25); Value := Mem[0000:1047]; { test for caps, numbers, & cursor cntrl } gotoXY(65,25); Case Value of 0 : begin LowVideo; write(' '); Inserton:= false; end; 32 : begin LowVideo; write(' '); InvVideo('NUM'); Clreol; InsertOn:= false; end; 64 : begin InvVideo('CAPS'); Clreol; InsertOn:= false; end; 96 : begin InvVideo('CAPS'); write(' '); InvVideo('NUM'); Clreol; InsertOn:=false; end; 128 : begin LowVideo; write(' '); InvVideo('Insert');InsertOn:=true; end; 160 : begin LowVideo; write(' '); InvVideo('NUM');write(' '); InvVideo('Insert'); InsertOn:=true; end; 192 : begin InvVideo('CAPS'); write(' '); InvVideo('Insert'); InsertOn:=true; end; 224 : begin InvVideo('CAPS'); write(' ');InvVideo('NUM'); write(' '); InvVideo('Insert'); InsertOn:= true; end; end; { Case } Window (c1,r1,c2,r2); end; procedure Set_Cap_Num(Caps,Num,Insert : Char); { Set the Cap Lock, Number Lock, and Ins Keys as desired } var J : integer; begin if Insert='I' then J:=128 else J:=0; Case Caps of 'C': begin if Num='N' then MemW[0000:1047]:= 96+J else MemW[0000:1047]:= 64+J; end; ' ': begin if Num='N' then MemW[0000:1047]:= 32+J else MemW[0000:1047]:= 0+J; end; end; { Case } end; {.pa} procedure Ck_edit_key(var Ch: Char); { test for an IBM Cursor control or Function key } begin read(kbd,Ch); begin {see if IBM specific key pressed} case Ch of 'H': Ch:=^E ; { up-arrow } 'P': Ch:=^X ; { dn-arrow } 'M': Ch:=^D ; { rt-arrow } 'K': Ch:=^S ; { left-arr } 'S': Ch:=#127 ; { Del } 'R': Ch:=^V ; { insert } 'G': Ch:=^G ; { Home } 'O': Ch:=^O ; { End } 'I': Ch:=^R ; { Pg-Up } 'Q': Ch:=#00 ; { Pg-Dn } ';': Ch:=^a ; { F1 } '<': Ch:=^b ; { F2 } '=': Ch:=^c ; { F3 } '>': Ch:=^d ; { F4 } '?': Ch:=^e ; { F5 } '@': Ch:=^f ; { F6 } 'A': Ch:=^g ; { F7 } 'B': Ch:=^h ; { F8 } 'C': Ch:=^i ; { F9 } 'D': Ch:=^j ; { F10 } 'u': Ch:=#117 ; {ctrl-end } end; {Case Ch} end; {IBM check} end; {Ck_edit_key} procedure Get_Template(Template_num:integer; var template: str80); { Templates are specified by the Programmer } begin Case Template_num of 1 : template := ''; 2 : template := ''; end; end; procedure Input(Typ: Char ; { Type of input } Default: str255 ; { Default string } Col,Row: integer ; { Where start line } Mlen: integer ; { Max length } UpperCase:Boolean ; { True if auto Upcase } var F1,F10 : boolean); { Returned true if F1 or F10 } {-- requires Global procedures: Say_Cap_Num, Set_Cap_Num, Color, Ck_edit_key, Beep, Get_template } var X,J,LastValue: integer; OkChars,temp : set of Char; DF : boolean; {-------------------------- local procedures ---------------------------} procedure GotoX; begin GotoXY(X+Col-1,Row); end; procedure Ck_Cap_Num; { test for caps, numbers, & cursor cntrl } var Value : integer; begin repeat Value := Mem[0000:1047]; if LastValue<>value then begin LastValue:=Value; Say_Cap_Num; GotoX; end; until keypressed; end; procedure PosX; begin while copy(template,X,1)<>#95 do begin Answer:=Answer + copy(template,X,1); X:=X+1; GotoX; end; end; procedure Del_Ans; begin Answer:=''; X:=1; GotoX; write(template); GotoX; PosX; end; {------------------------ end local procedures ------------------------} begin if Typ='A'then OKChars:=[' '..'}'] else OKChars:=['0'..'9','+','-','.']; Temp := OKChars; color(7,0); DF:= false; Case Typ of 'A','N','$': begin fillchar(template,80,#95); template:=copy(template,1,Mlen); if Typ='$' then begin X:=0; GotoX; HighVideo; write('$'); end; end; 'F': begin Get_template(Mlen,template); Mlen := length(template); if copy(template,1,1)<>#95 then DF:= true; end; end; if Typ = 'A' then if uppercase then Set_Cap_Num('C',' ',' ') else Set_Cap_Num(' ',' ','I') else Set_Cap_Num(' ','N',' '); Color(7,0); Answer := ''; F1:=false; F10:=false; if Default<>'' then begin X:=1; GotoX; write(template); GotoX; write(default); Answer:=Default; end else Del_Ans; LastValue:=Mem[0000:1047]; Say_Cap_Num; GotoX; repeat Ck_Cap_Num; read(kbd,Ch); Color(7,0); if (keypressed) and (Ch<>'p') and (Ch<>'q') then Ck_edit_key(Ch); if (Typ='F') and (X=1) and (Default<>'') and (Ch<>^1) and (Ch<>#13) then Del_Ans; case Ch of ^[: begin Del_Ans end; { ESC pressed } ^D: begin { Move cursor right : rt-arr } X:=X+1; if (X>length(Answer)+1) or (X>Mlen) then X:=X-1; GotoX; end; ^S: begin { Move cursor left : left-arr } if Typ='F' then Del_Ans else begin X:=X-1; if X<1 then X:=1; GotoX; end; end; ^O: begin { Move cursor to end of line } X:=Length(Answer)+1; if X>Mlen then X:=Mlen; GotoX; end; ^G: begin { Move cursor to beginning of line } X:=1; GotoX; end; ^H: begin { Delete left char: BS } if Typ='F' then Del_Ans else begin X:=X-1; if (Length(Answer)>0) and (X>0) then begin Delete(Answer,X,1); GotoX; Write(copy(Answer,X,(Length(Answer)-X+1)),#95); GotoX; end else X:=1; end; { Typ <> 'F' } end; #117: begin {delete end of line} i := (mlen-x); delete(answer,X,i); for e := 0 to i do write(#95); gotox; end; #127: begin { Delete } Delete(Answer,X,1); Write(copy(Answer,X,Length(Answer)-X+1),#95); GotoX; end; ^a : begin { F1 pressed } F1 := true; exitt := true; Answer:= default; end; ^M : exitt := true; ^j : begin F10 := true; exitt := true; Answer := default; end; else if (length(Answer)+1 <= Mlen) or (not InsertOn) then begin { non-IBM char } if Ch in OkChars then begin if InsertOn then begin if length(Answer) < Mlen then begin { OK to insert } insert(Ch,Answer,X); Case Typ of 'A','N','$' : write(copy(Answer,X,Length(Answer)-X+1)); 'F' : Write(Ch); end; {Case} end; { OK to insert } end else { end InsertOn } if X <= Mlen then begin write(Ch); if X>length(Answer) then Answer:=Answer+Ch else Answer[X]:=Ch; end; { processing this key } if X+1 <= Mlen then X:=X+1; if (X > Length(Answer)) and (template[X]<>#95) then PosX; end { OkChars } else if (Ch<> ^V) then Beep(300,150); { beep if invalid char and ch is not Insert key } GotoX; end; { non IBM key } if (typ<>'F') and (length(Answer)+1 > Mlen) and (Ch <> ^V) then Beep(600,100); end; { CASE!!! } until exitt = true; Color(0,15); X:=1; gotoX; write(Answer); { erase part of template that is left } X:=length(Answer)+1; GotoX; for J:= 1 to Mlen-x+1 do write(' '); exitt := false; Color(0,15); if (DF) and (length(Answer)=1) then begin gotoXY(col,row); write(' '); Answer:=''; end; end; { end Input Procedure } {--------------------- Procedures -----------------------------} {---- begin code from original PC-DISK---------} procedure set_fcb; forward; procedure get_vol; forward; procedure save_catalog; forward; procedure keycontinue; begin write(' Tap any key to continue'); read (kbd,ch); CLRSCR; end; procedure log_new_drive(ch:char); {gg} begin ch := upcase(ch); CHDIR(ch+':'); default_drive := ch; end; Procedure drawbox_ibm (x1,y1,x2,y2,FG,BG : Integer; boxname : str80; blnk : boolean); Begin window (x1,y1,x2,y1+1); textbackground(BG); GotoXY(1,1); x := x2-x1; if length(boxname) > x then boxname[0] := chr(x-4); textcolor(FG); Write('U'); if blnk then textcolor(FG + blink) else textcolor(fg); write (boxname); textcolor(FG); for q := x1+length(boxname)+1 to x2-1 do Write('M'); Write('8'); for q := 2 to y2-y1 do Begin window (x1,y1,x2,y1+q+1); GotoXY(1,q); Write('3'); if blnk then clreol; GotoXY(x2-x1+1,q); Write('3'); end; Window(x1,y1,x2,y2+1); gotoXY(1,y2-y1+1); Write('T'); for q := x1+1 to x2-1 do Write('M'); Write('>'); end; function upcase11(strng : str11) : str11; var temp : str11; x : integer; begin temp := ''; for x := 1 to length(strng) do temp := temp + upcase(strng[x]); upcase11 := temp; end; procedure GetPath; {gg} begin Getdir(0,fullpathname); if length(fullpathname) = 3 then pathname := 'ROOT ' else pathname := copy(fullpathname,4,11); pathname := upcaseStr(pathname); for x := 1 to (11-length(PATHNAME)) do pathname := pathname+' '; end; Procedure drawbox (x1,y1,x2,y2,FG,BG : Integer; boxname : str80; blnk : boolean); Begin Drawbox_IBM (x1,y1,x2,y2,FG,BG,boxname,blnk); Window (x1+1,y1+1,x2-1,y2-1); c1:=x1+1; r1:=y1+1; c2:=x2-1; r2:=y2-1; Clrscr; end; procedure load_catalog; begin drawbox (30,15,78,22,lightcyan,black,'[ Catalog Load ]',blink_no); volume := ''; get_vol; if volume <> '' then begin cat_num := 0; writeln ('Loading from file ',catname); set_fcb; assign (catfile, catname); {$I-} reset (catfile); {$I+} ok := (ioresult=0); if not ok then begin rewrite (catfile); writeln ('File not found, Creating a new one. '); end else begin cat_num := 0; vol_num := 0; while (not eof(catfile)) and (cat_num < max_records + 1) do begin cat_num := cat_num + 1; read (catfile, cat_array[cat_num]); if cat_array[cat_num].vol_record > vol_num then begin writeln ('Invalid record found and discarded.'); cat_num := cat_num - 1; end else if cat_array[cat_num].vol_record = -1 then { vol label record } begin vol_num := vol_num + 1; vol_array[vol_num] := cat_array[cat_num].fil; end; end; writeln (cat_num,' file entries loaded, ',max_records - cat_num,' empty.'); writeln (vol_num,' volume entries loaded, ',100-vol_num,' empty.'); end; close (catfile); end else begin writeln('Cannot catalog a disk without a Volume Label.'); writeln('A)dd one from the Main Menu.'); end; keycontinue; end; procedure ChangeDir; {gg} begin drawbox (2,15,68,19,lightcyan,black,'[ Change Directory ]',blink_no); GetPath; writeln(' Current Directory is ',fullpathname); Write(' Enter name of new directory: '); input('A','',wherex,wherey,33,true,f1,f10); IF LENGTH(ANSWER) = 0 THEN begin writeln; write(' No change.'); delay(900); EXIT; end; {$I-} ChDir(answer); {$I+} If IOResult<>0 Then begin Writeln; Write(' *** Cannot access that path - '); keycontinue; Exit; end else writeln; Write(' Done.'); GetPath; delay( 900 ); end; procedure ChangeDrive; {gg} var ch : char; begin drawbox (4,15,35,19,lightcyan,black,'[ Change Drive ]',blink_no); writeln(' Current drive is: ', default_drive+':'); write(' Enter new drive: '); repeat read(KBD,ch); ch := upcase(ch); if not (ch in ['A'..'E',#13]) then write(^G) else writeln(ch); until ch in ['A'..'E',#13]; if ch = #13 then write(' No change.') else begin log_new_drive(ch); write(' Done.'); end; delay(900); end; Procedure init; {changed: no longer calls Screen_on Screen_off, which seemed to hang some systems (I don't know what it did??) and is now called after every change of catalog. gg} Begin done := False; changed := false; catname := ''; cat_num := 0; vol_num := 0; end; procedure save_catalog; begin drawbox (40,15,78,23,lightcyan,black,'[ Save Catalog ]',blink_no); writeln; writeln ('Saving to file ',catname); set_fcb; close (catfile); assign (catfile, catname); rewrite (catfile); x := 0; if cat_num = 0 then writeln ('No entries to save, aborted.') else begin while x < cat_num do begin x := x + 1; write (catfile, cat_array[x]); end; end; close (catfile); writeln; writeln (x,' entries saved, ',max_records-x,' empty.'); KEYCONTINUE; if Ctype = 'F' then log_new_drive(orig_drive); init; end; Procedure big_exit; begin if changed then begin drawbox (15,10,65,16,white,red,'[ Warning! ]',blink_yes); writeln; center (' Catalog '+catname+' has been changed!',1,2,49); center (' Do you want to Save [Y/N] ? ',1,3,49); repeat read (kbd,ch); until ch in yes_no; if upcase(ch) = 'Y' then save_catalog; end; done := true; end; procedure set_dta; begin {-- Set DTA address --} pointer := addr(dta_area); r.ds := seg(pointer^); r.dx := ofs(pointer^); r.ax := $1A shl 8; MsDos(R); end; procedure get_dta; begin {-- Get DTA address in ES:BX --} r.ax := 0; r.es := 0; r.bx := 0; r.ax := $2F shl 8; MsDos(R); dta := ptr(r.es,r.bx); end; procedure set_fcb; begin {-- Set up an unopened FCB --} for x := -7 to 36 do fcb[x] := #0; fcb[-7] := #255; fcb[-1] := #0; filez := '*.*' + #0; pointer := addr(filez[1]); r.ds := seg(pointer^); r.si := ofs(pointer^); pointer := addr(fcb[0]); r.es := seg(pointer^); r.di := ofs(pointer^); r.ax := $29 shl 8; msdos(R); set_dta; get_dta; end; procedure msdos12; begin set_dta; pointer := addr(fcb[-7]); r.ds := seg(pointer^); r.dx := ofs(pointer^); r.ax := $12 shl 8; { go after the next matching entry } msdos(R); end; procedure msdos11(x : integer); begin set_fcb; fcb[-7] := #255; fcb[-1] := chr(x); pointer := addr(fcb[-7]); r.ds := seg(pointer^); r.dx := ofs(pointer^); r.ax := $11 shl 8; msdos(R); end; procedure get_vol; begin volume := ''; msdos11(8); if (r.ax and 255) = 0 then begin for x := 8 to 18 do volume := volume + chr(mem[seg(dta^):ofs(dta^)+x]); writeln('Volume is ',volume); writeln('Directory is ',fullpathname); end else writeln ('Disk has no Volume Label!'); end; procedure delete_volume; var vnum : integer; begin drawbox (2,5,78,24,white,black,'[ Delete Volume ]',blink_yes); writeln (' Select the volume to be deleted by entering the number'); writeln (' associated with the Volume Label.'); for x := 1 to vol_num do write (' ',x:2,')',vol_array[x]:11); writeln; repeat write ('Enter volume number (<0> quits):'); readln (vnum); until (vnum >= 0) and (vnum <= vol_num); if vnum = 0 then exit; writeln; write ('Delete volume ',vol_array[vnum],' [Y/N] ? '); repeat read (kbd,ch); until ch in yes_no; if upcase(ch) = 'Y' then begin writeln ('Deleting volume ',vol_array[vnum]); vol_min := 0; vol_max := 0; t2 := 0; { count files found on disk } for x := 1 to cat_num do if (cat_array[x].vol_record = vnum) and (vol_min = 0) then vol_min := x - 1 else if (vol_min <> 0 ) and (vol_max = 0) and (cat_array[x].vol_record <> vnum) then vol_max := x - 1 ; if vol_max = 0 then vol_max := cat_num; t1 := vol_max - vol_min + 1; for x := (vol_max + t2-t1 + 1) to (cat_num + t2 - t1) do cat_array[x] := cat_array[x -(t2-t1)]; if vnum = vol_num then cat_num := vol_min - 1 else cat_num := x; { now renumber the cat_array } vol_num := 0; for x := 1 to cat_num do begin if cat_array[x].vol_record = -1 then begin vol_num := vol_num + 1; vol_array[vol_num] := cat_array[x].fil; end else cat_array[x].vol_record := vol_num; end; end else writeln ('Aborted.'); write (' Press any key to continue '); read(kbd,ch); end; procedure show_dta(x1,y1 : integer); var t1,t2,d1,d2,hour,minutes,seconds,dd,mm,yy : integer; bytes : real; begin for x := 8 to 15 do write(chr(mem[x1:y1+x])); write (' '); for x := 16 to 18 do write(chr(mem[x1:y1+x])); write (' '); t1 := mem[x1:y1+30]; t2 := mem[x1:y1+31]; d1 := mem[x1:y1+32]; d2 := mem[x1:y1+33]; bytes := mem[x1:y1+37]*256.0; bytes := bytes + mem[x1:y1+36]; bytes := bytes + mem[x1:y1+38] * 65536.0; write (bytes:6:0,' '); hour := (t2 and 249) shr 3; if hour > 12 then hour := hour - 12; minutes := ((t2 and 7) shl 3) + ((t1 and 224) shr 5); write (hour:2,':'); if minutes < 10 then write ('0'); write (minutes); mm := ((d2 and 1) shl 3) + ((d1 and 224) shr 5); dd := (d1 and 31); yy := 80 + ((d2 and 255) shr 1); write (' '); if mm < 10 then write ('0'); write (mm,'-'); if dd < 10 then write ('0'); write (dd,'-'); write (yy:2); end; Function Free_Space( Drive_letter : Char) : Real; {changed to reflect the available space on a hard drive} var Tracks, { number of available Tracks } TotalTracks, { number of total Tracks } Drive, { Drive number } Bytes, { number of Bytes in one sector } Sectors : Integer; { number of total Sectors } Used : Real; procedure DiskStatus( Drive : integer; var Tracks, TotalTracks, Bytes, Sectors : integer ); var Regs : RegPack; begin Regs.AX := $3600; { Get Disk free space } Regs.DX := Drive; { Store Drive number } MSDos( Regs ); { Call MSDos to get disk info } Tracks := Regs.BX; { Get number of Tracks Used } TotalTracks := Regs.DX; { " " " total Tracks } Bytes := Regs.CX; { " " " Bytes per sector } Sectors := Regs.AX { " " " Sectors per cluster } END; { of proc DiskStatus } begin { main body of function Free_Space } Drive := 0; { Initialize Drive } drive_letter := upcase(drive_letter); case drive_letter of 'A'..'E' : drive := ord(drive_letter)-ord('A')+1; else drive := 0; end; DiskStatus( Drive, Tracks, TotalTracks, Bytes, Sectors ); Free_Space := (( Sectors * Bytes * 1.0 ) * Tracks ); end; { of function Free_Space } procedure dir2; var x : integer; bytes : real; begin drawbox (1,5,39,24,white,black,'[ Dir ]',blink_yes); x := 2; GETPATH; get_vol; set_fcb; msdos11(3); if (r.ax and 255) = 0 then begin while (r.ax and 255) = 0 do begin x := x + 1; write (' '); show_dta (seg(dta^),ofs(dta^)); writeln; if x/17 = int(x/17) then keycontinue; msdos12; end end else writeln ('Disk is Empty!'); bytes := free_space(default_drive); writeln (' Free space = ',bytes:6:0,' bytes'); write (' Press any key to continue'); read (kbd,ch); end; procedure update_disk; begin drawbox (10,7,70,24,white,black,'[ Update Disk ]',blink_no); found := false; writeln; writeln ('Place disk in drive ',default_drive,' and press any key...'); read (kbd,ch); id := ''; get_vol; getpath; {gg} if length(catname) = 0 then begin {refuse update if no writeln('No catalog loaded.'); catalog loaded gg.} keycontinue; exit; end; if volume <> '' then begin if (length(fullpathname) > 14) and (Ctype = 'T') then begin {gg} writeln; writeln('Pathname longer than eleven characters.'); write('Enter an identifying label for this directory: '); input('A','',wherex,wherey,11,true,f1,f10); pathname := answer; end; {scan the catalog for volume} if Ctype = 'T' then id := pathname {if tree-structured or individual catalog use ID} else id := volume; { use volume } writeln; changed := true; for x := 1 to vol_num do begin if vol_array[x] = id then begin found := true; t1 := x; t4 := x; end; end; if found then { Do a selective update/delete function } begin writeln ('Disk is already cataloged, performing update.'); writeln; vol_min := 0; vol_max := 0; t2 := 0; { count files found on disk } for x := 1 to cat_num do if (cat_array[x].vol_record = t1) and (vol_min = 0) then vol_min := x else if (vol_min <> 0 ) and (vol_max = 0) and (cat_array[x].vol_record <> t1) then vol_max := x - 1 ; if vol_max = 0 then vol_max := cat_num; msdos11(3); if (r.ax and 255) = 0 then begin while (r.ax and 255) = 0 do begin {q1} t2 := t2 + 1; temp := ''; for x := 8 to 18 do temp := temp + chr(mem[seg(dta^):ofs(dta^)+x]); temp_array[t2].fil := temp; temp_array[t2].sizelo[1] := chr(mem[seg(dta^):ofs(dta^)+36]); temp_array[t2].sizelo[2] := chr(mem[seg(dta^):ofs(dta^)+37]); temp_array[t2].sizehi[1] := chr(mem[seg(dta^):ofs(dta^)+38]); temp_array[t2].sizehi[2] := chr(mem[seg(dta^):ofs(dta^)+39]); temp_array[t2].time[1] := chr(mem[seg(dta^):ofs(dta^)+30]); temp_array[t2].time[2] := chr(mem[seg(dta^):ofs(dta^)+31]); temp_array[t2].date[1] := chr(mem[seg(dta^):ofs(dta^)+32]); temp_array[t2].date[2] := chr(mem[seg(dta^):ofs(dta^)+33]); {-- now find old entry if any --} found := false; for x := vol_min to vol_max do begin if cat_array[x].fil = temp then begin found := true; t3 := x; end; end; if not found then begin write (temp,' Memo > '); Input('A','',wherex,wherey,33,true,F1,F10); writeln; temp_array[t2].memo := answer; end else begin write (TEMP,' Memo > '); input('A',cat_array[t3].memo,wherex,wherey,33,true,F1,F10); temp_array[t2].memo := answer; writeln; end; msdos12; end end; writeln ('Updating catalog.. One moment...'); t1 := vol_max - vol_min + 1; if t1 < t2 then begin {check to see if we will overrun the array} if (cat_num + (t2 - t1)) > max_records then begin writeln ('Maximum of ',max_records,' files exceeded by ',cat_num + t2 - t1 - max_records,'.'); writeln ('Truncating to ',max_records); end; {move the file up t2 - t1 records} for x := (cat_num + t2 - t1) downto (vol_max + t2-t1 + 1) do cat_array[x] := cat_array[x - t2+t1]; cat_num := cat_num + t2 - t1; {insert temp array} for x := 1 to t2 do begin cat_array[x + vol_min - 1].fil := temp_array[x].fil; cat_array[x + vol_min - 1].sizelo := temp_array[x].sizelo; cat_array[x + vol_min - 1].sizehi := temp_array[x].sizehi; cat_array[x + vol_min - 1].time := temp_array[x].time; cat_array[x + vol_min - 1].date := temp_array[x].date; cat_array[x + vol_min - 1].memo := temp_array[x].memo; cat_array[x + vol_min - 1].vol_record := t4; end; end else {the temp will fil in the old slot} if t1 > t2 then begin {insert temp array at vol_min} for x := 1 to t2 do begin cat_array[x + vol_min - 1].fil := temp_array[x].fil; cat_array[x + vol_min - 1].sizelo := temp_array[x].sizelo; cat_array[x + vol_min - 1].sizehi := temp_array[x].sizehi; cat_array[x + vol_min - 1].time := temp_array[x].time; cat_array[x + vol_min - 1].date := temp_array[x].date; cat_array[x + vol_min - 1].memo := temp_array[x].memo; cat_array[x + vol_min - 1].vol_record := t4; end; { move the array down to meet it } for x := (vol_max + t2-t1 + 1) to (cat_num + t2 - t1) do cat_array[x] := cat_array[x -(t2-t1)]; cat_num := x; end else { the replacement array is an exact match !} for x := 1 to t2 do begin cat_array[x + vol_min - 1].fil := temp_array[x].fil; cat_array[x + vol_min - 1].sizelo := temp_array[x].sizelo; cat_array[x + vol_min - 1].sizehi := temp_array[x].sizehi; cat_array[x + vol_min - 1].time := temp_array[x].time; cat_array[x + vol_min - 1].date := temp_array[x].date; cat_array[x + vol_min - 1].memo := temp_array[x].memo; cat_array[x + vol_min - 1].vol_record := t4; end; end else { Do a Complete Add function } begin msdos11(3); if (r.ax and 255) = 0 then begin if Ctype = 'T' then id := pathname else id := volume; cat_num := cat_num + 1; vol_num := vol_num + 1; vol_array[vol_num] := id; cat_array[cat_num].vol_record := -1; { -1 means this is a vol entry } cat_array[cat_num].fil := id; cat_array[cat_num].memo := 'Volume Label'; while ((r.ax and 255) = 0) and (cat_num < max_records + 1) do begin cat_num := cat_num + 1; temp := ''; for x := 8 to 18 do temp := temp + chr(mem[seg(dta^):ofs(dta^)+x]); write (temp,' '); write (' Memo > '); Input('A','',wherex,wherey,33,true,F1,F10); one_memo := answer; writeln; cat_array[cat_num].vol_record := vol_num; cat_array[cat_num].fil := temp; cat_array[cat_num].sizelo[1] := chr(mem[seg(dta^):ofs(dta^)+36]); cat_array[cat_num].sizelo[2] := chr(mem[seg(dta^):ofs(dta^)+37]); cat_array[cat_num].sizehi[1] := chr(mem[seg(dta^):ofs(dta^)+38]); cat_array[cat_num].sizehi[2] := chr(mem[seg(dta^):ofs(dta^)+39]); cat_array[cat_num].time[1] := chr(mem[seg(dta^):ofs(dta^)+30]); cat_array[cat_num].time[2] := chr(mem[seg(dta^):ofs(dta^)+31]); cat_array[cat_num].date[1] := chr(mem[seg(dta^):ofs(dta^)+32]); cat_array[cat_num].date[2] := chr(mem[seg(dta^):ofs(dta^)+33]); cat_array[cat_num].memo := one_memo; msdos12; end; end else writeln ('Disk has no files!'); end; if cat_num = max_records then writeln ('The catalog is full.'); end else begin writeln (' Cannot catalog a disk without a Volume Label.'); writeln (' A)dd one from the Main Menu.'); end; writeln; write (' Press any key to continue'); read (kbd,ch); end; function upcase33(strng : str33) : str33; var temp : str33; x : integer; begin temp := ''; for x := 1 to length(strng) do temp := temp + upcase(strng[x]); upcase33 := temp; end; procedure scan_comments; var scanner : string[33]; bytes : real; t1,t2,d1,d2,hour,minutes,mm,dd,yy,y : integer; begin drawbox (7,6,70,10,lightcyan,black,'[ Scan Memos ]',blink_no); y := 0; write ('Enter string to scan for: '); input('A','',wherex,wherey,33,true,f1,f10); scanner := answer; drawbox (1,1,80,24,cyan,black, '[Volume ] [Filename ] [Size] [Tm] [ Date ] [------------ Memo -----------]',blink_no); scanner := upcase33(scanner); for x := 1 to cat_num do if cat_array[x].vol_record = -1 then ID := cat_array[x].fil else begin if pos(scanner, upcase33(cat_array[x].memo)) > 0 then begin y := y + 1; write (id:11); write (' ',cat_array[x].fil:11); bytes := ord(cat_array[x].sizelo[2]) * 256.0; bytes := bytes + ord(cat_array[x].sizelo[1]); bytes := bytes + ord(cat_array[x].sizehi[1]) * 65536.0; write (' ',bytes:6:0); t1 := ord(cat_array[x].time[1]); t2 := ord(cat_array[x].time[2]); d1 := ord(cat_array[x].date[1]); d2 := ord(cat_array[x].date[2]); hour := (t2 and 249) shr 3; if hour = 0 then write (' 00') else if hour < 10 then write (' 0',hour) else write (' ',hour); minutes := ((t2 and 7) shl 3) + ((t1 and 224) shr 5); if minutes < 10 then write ('0'); write (minutes); mm := ((d2 and 1) shl 3) + ((d1 and 224) shr 5); dd := (d1 and 31); yy := 80 + ((d2 and 255) shr 1); write (' '); if mm < 10 then write ('0'); write (mm,'-'); if dd < 10 then write ('0'); write (dd,'-'); write (yy:2); write (' ',cat_array[x].memo); if length(cat_array[x].memo) < 33 then writeln; if y/21 = int(y/21) then keycontinue; end; end; writeln; write ('End of catalog. Press any key to continue'); read (kbd,ch); end; procedure scan_files; var scanner : string[11]; bytes : real; t1,t2,d1,d2,hour,minutes,mm,dd,yy,y: integer; begin drawbox (7,6,70,10,lightcyan,black,'[ Scan Filenames ]',blink_no); y := 0; write ('Enter string to scan for: '); input('A','',wherex,wherey,11,true,f1,f10); scanner := answer; drawbox (1,1,80,24,cyan,black, '[Volume ] [Filename ] [Size] [Tm] [ Date ] [------------ Memo -----------]',blink_no); scanner := upcase11(scanner); for x := 1 to cat_num do if cat_array[x].vol_record = -1 then ID := cat_array[x].fil else begin if pos(scanner, upcase11(cat_array[x].fil)) > 0 then begin y := y + 1; write (id:11); write (' ',cat_array[x].fil:11); bytes := ord(cat_array[x].sizelo[2]) * 256.0; bytes := bytes + ord(cat_array[x].sizelo[1]); bytes := bytes + ord(cat_array[x].sizehi[1]) * 65536.0; write (' ',bytes:6:0); t1 := ord(cat_array[x].time[1]); t2 := ord(cat_array[x].time[2]); d1 := ord(cat_array[x].date[1]); d2 := ord(cat_array[x].date[2]); hour := (t2 and 249) shr 3; if hour = 0 then write (' 00') else if hour < 10 then write (' 0',hour) else write (' ',hour); minutes := ((t2 and 7) shl 3) + ((t1 and 224) shr 5); if minutes < 10 then write ('0'); write (minutes); mm := ((d2 and 1) shl 3) + ((d1 and 224) shr 5); dd := (d1 and 31); yy := 80 + ((d2 and 255) shr 1); write (' '); if mm < 10 then write ('0'); write (mm,'-'); if dd < 10 then write ('0'); write (dd,'-'); write (yy:2); write (' ',cat_array[x].memo); if length(cat_array[x].memo) < 33 then writeln; if y/21 = int(y/21) then keycontinue; end; end; writeln; write ('End of catalog. Press any key to continue'); read (kbd,ch); end; procedure vol_disk; var newvol : str11; begin drawbox (3,15,55,20,lightgreen,black,'[ Volume Disk ]',blink_no); volume := ''; msdos11(8); if (r.ax and 255) = 0 then begin for x := 8 to 18 do volume := volume + chr(mem[seg(dta^):ofs(dta^)+x]); writeln ('Current Volume is ',volume); write ('Are you sure you want to change ? '); repeat read (kbd,ch); until ch in yes_no; if upcase(ch) = 'Y' then begin writeln; write ('Enter new Volume Label >'); input('A','',wherex,wherey,11,true,f1,f10); newvol := answer; for x := length(newvol) to 11 do newvol := newvol + ' '; for x := 17 to 28 do fcb[x] := newvol[x-16]; pointer := addr(fcb[-7]); r.ds := seg(pointer^); r.dx := ofs(pointer^); r.ax := $17 shl 8; msdos(R); end end else begin write ('Enter new Volume Label >'); input('A','',wherex,wherey,11,true,f1,f10); newvol := answer; for x := length(newvol) to 11 do newvol := newvol + ' '; for x := 1 to 11 do fcb[x] := newvol[x]; pointer := addr(fcb[-7]); r.ds := seg(pointer^); r.dx := ofs(pointer^); r.ax := $16 shl 8; msdos(R); end; end; procedure scan_submenu; begin drawbox(1,5,80,9,lightred,black,'[ Scan Sub-Menu ]',blink_no); writeln ; write (' 1) Filenames 2) Memos 3) Exit Your choice? '); repeat read (kbd,ch); until ch in ['1'..'3']; case ch of '1' : scan_files; '2' : scan_comments; end; end; Procedure Indtype; {gg} begin drawbox(20,15,78,22,lightcyan,black,'[ Catalog Load ]',blink_no); Ctype := 'T'; GetPath; Get_Vol; if pathname = 'ROOT ' then begin catname := copy(volume,1,11); stripspaces(catname,catname); catname := catname+'.CAT'; end else begin stripspaces(pathname,catname); catname := catname+'.CAT'; end; writeln; write('Enter name of catalog: '); input('A',catname,24,whereY,33,true,F1,F10); catname := answer; writeln; Load_Catalog; end; procedure TreeType; {gg} begin Ctype := 'T'; drawbox (20,15,78,22,lightcyan,black,'[ Catalog Load ]',blink_no); writeln; write('Enter name of catalog: '); input('A',default_drive+':\TREELIB.CAT',24,2,33,true,F1,F10); catname := answer; writeln; GetPath; Load_Catalog; end; procedure FlopType; {gg} begin Ctype := 'F'; drawbox (20,15,78,22,lightcyan,black,'[ Catalog Load ]',blink_no); writeln; write('Enter name of catalog: '); input('A',default_drive+':\FLOPLIB.CAT',24,2,33,true,F1,F10); catname := answer; orig_drive := default_drive; writeln; write(' Drive to catalog: '); repeat read(kbd,ch); ch := upcase(ch); if not (ch in ['A'..'E']) then beep(350,150); until ch in ['A'..'E']; write(ch+':'); Log_New_Drive(Ch); GetPath; Load_Catalog; end; procedure Load_Type; {gg} begin if changed then begin drawbox (10,17,70,22,white,red,'[ Warning! ]',blink_yes); center(' Catalog '+catname+' has been changed!',1,2,59); center (' Do you want to Save [Y/N] ? ',1,3,59); repeat read (kbd,ch); until ch in yes_no; if upcase(ch) = 'Y' then save_catalog end; INIT; getdir(0,fullpathname); default_drive := fullpathname[1]; drawbox(2,17,78,22,lightred,black,'[ Load Catalog ]',blink_no); writeln ; writeln (' T)ree Structured Library F)loppy Library D)irectory Catalog E)xit'); writeln; write(' Your choice ? '); repeat read (kbd,ch); ch := upcase(ch); until ch in ['T','F','D','E']; write(ch); case ch of 'T' : TreeType; 'F' : FlopType; 'D' : IndType; end; end; procedure show_catalog; begin drawbox (1,5,30,24,white,black,'[ show ]',blink_no); for x := 1 to cat_num do begin writeln (x,' ',cat_array[x].vol_record,' ',cat_array[x].fil); if x/17 = int(x/17) then keycontinue; end; keycontinue; end; procedure Help; begin drawbox(1,1,80,24,white,black,'[ Help Screen ]', blink_no); writeln; writeln(' PCDISK is adapted from John Friel IIIs Disk cataloger. If you find it'); writeln(' of value please send your contribution to him at: '); writeln(' The Forbin Project, 715 Walnut Street, Cedar Falls, Iowa 50613.'); writeln; writeln; writeln(' COMMANDS:'); writeln; writeln(' L)oad Catalog submenu:'); writeln(' T)ree - useful for keeping track of a hard disk'); writeln(' F)loppy - useful for keeping track of up to 1000 files on 100 floppies'); writeln(' D)irectory - for a catalog of the current drive or directory'); writeln(' U)pdate - presents existing file descriptions for editing or addition'); writeln(' F)ilenames - Lists only the filenames in the catalog'); writeln(' R)eview - search for a string (in filenames or memos)'); writeln(' A)dd - create or change a volume label on the current drive'); writeln(' E)rase - removes the specified volume from memory'); writeln(' D)ir - shows directory of current drive/disk'); writeln; writeln(' If you have questions about, or discover bugs in, this version of '); writeln(' PCDISK, please address them to G. Gallo at PCSI - 1-212-924-6598'); keycontinue; end; procedure options; begin Drawbox (1,1,80,4,brown,black,'',blink_yes); textcolor(lightgreen); Writeln (' PC-Disk Version 3.0D '); Write (' (c) The Forbin Project - revised by G.G. 23 May 1985 '); drawbox(1,5,80,15,yellow,black,'[ Main Menu ]',blink_no); writeln; writeln (' L)oad Catalog R)eview Catalog in Memory'); writeln (' U)pdate Catalog in Memory A)dd/Change Volume Label'); writeln (' S)ave Catalog to Disk E)rase a Volume from Memory'); writeln (' D)isk Directory H)elp Screen'); writeln (' C)hange Current Directory F)ilenames in Catalog'); writeln (' N)ew Drive Q)uit PC-Disk'); writeln; write (' Your choice: '); gotoxy (41,9); repeat read (kbd,ch); Ch := upcase(ch); until ch in ['L','C','D','U','S','N','R','A','H','F','E','O','I','Q']; write(ch); case ch of 'L' : load_type; 'C' : changedir; 'D' : dir2; 'U' : update_disk; 'S' : save_catalog; 'R' : scan_submenu; 'A' : vol_disk; 'H' : help; 'E' : delete_volume; 'F' : show_catalog; 'N' : changedrive; 'Q' : big_exit; end; { case } end; begin {main} clrscr; init; getdir(0,fullpathname); orig_path := fullpathname; default_drive := fullpathname[1]; repeat options; until done; chdir(orig_path); window(1,1,80,25); clrscr; end.  .