var   _filepos,i:LONGINT;
    sector,track,B1:BYTE;
    infile,outfile:file of byte;


function absolute_adress(free_track, free_block:longint):longint;
 { the func computes back the _absolute_ adress from track and block number.
  We overdefinied the input variables from byte type to longint type, coz we
  will multiply them! At the higher track values (8) it causes big problems,
  e.g. the _filepos=absolute... will give back negative adress! }
begin
  if free_track<18 then absolute_adress:=(free_track-1)*21*256+(free_block)*256;
  if (free_track>18) and (free_track<25) then
     absolute_adress:=17*21*256+(free_track-1-17)*19*256+(free_block)*256;
  if (free_track>=25) and (free_track<31) then
     absolute_adress:=17*21*256+7*19*256+(free_track-1-17-7)*18*256+
     (free_block)*256;
  if (free_track>=31) then
     absolute_adress:=17*21*256+7*19*256+6*18*256+
      (free_track-1-17-7-6)*17*256+(free_block)*256;
end;

procedure dir_format;
var  unformatted_dir_array:array [1..18] of array [1..256] of byte;
     just_written_phisical_dir_block:byte;
     which_block_is_the_next:byte;
     block_we_now_read:byte;
     i,j:integer;
begin
_filepos:=$16600;
seek(infile,_filepos);
for i:=1 to 18 do
    for j:=1 to 256 do read(infile,unformatted_dir_array[i,j]);

_filepos:=$16600;
seek(infile,_filepos);

b1:=0;
for i:=1 to 4608 do write(infile,b1);  { erasing the prev dir area! }

_filepos:=$16600;
seek(infile,_filepos);


just_written_phisical_dir_block:=1;    { at 12-01 }
which_block_is_the_next:=1;
block_we_now_read:=1;

repeat
which_block_is_the_next:=unformatted_dir_array
               [block_we_now_read,2];
if which_block_is_the_next<>255 then unformatted_dir_array
               [block_we_now_read,2]:=just_written_phisical_dir_block+1;
                  { points to the NEXT PHISICAL dir block! }
for i:=1 to 256 do write(infile,unformatted_dir_array
               [block_we_now_read,i]);
inc(just_written_phisical_dir_block);               { check the next block }
block_we_now_read:=which_block_is_the_next;
until which_block_is_the_next=255;
end;



begin
 if paramcount<>1 then begin
                       writeln('You must supply the name of the virtual disk image! Aborting...');
                       exit;
                       end;

  ASSIGN(INFILE,PARAMSTR(1));
  RESET(INFILE);

  ASSIGN(OUTFILE,'out.fil');
  REwrite(OUTFILE);

WRITELN(' This program reads from the parameter- virtual disk file, prompts for');
writeln('the file to be restored to binary format and stores it in OUT.FIL DOS-file.');
WRITELN(' It''s the simpliest way to save files from virtual C64 files. E.g. if you');
writeln('have just read a full disc image with c642c64s, you can save individual');
writeln('files from it to store on an other disk image, or store in T64 format.');
WRITELN;
WRITELN(' The program is PUBLIC DOMAIN.');
WRITELN;
WRITELN(' COPYRIGHT BY WERNER ZSOLT. The source is freely modifiable');
WRITELN;
WRITELN(' Contact adress:  MTTT022@URSUS.BKE.HU   (Internet),');
writeln('                  36/1/1823513           (Voice & 14400 sHiTModem)');

writeln('Wait, formatting...');
DIR_FORMAT;   { WE MAKE ORDER IN DIR AREA SO WE WON'T FIND ANY PROBLEMS
                WHEN THE FIRST DIR BLOCK IS ON 12-01 AND THE SECOND 12-04
                ETC... NOW THE SECOND WILL BE ON 12-02, THE THIRD ON 12-03
                AND SO ON. IT MAKES LINEAR DIR SEARCH POSSIBLE! }

writeln(' Please enter the number of file to convert!');
read(b1);
dec(b1);

seek(infile,91651+32*b1);    { track }
read(infile,track);
read(infile,sector);
_filepos:=absolute_adress(track,sector);
seek(infile,_filepos);
 writeln(track,'  sector:  ',sector,'  filepos:',_filepos);

repeat

 read(infile,track);
 read(infile,sector);
 writeln(track,'  sector:  ',sector,'  filepos:',_filepos);
 for i:=1 to 254 do begin
    read(infile,b1);
    write(outfile,b1);
      end;
_filepos:=absolute_adress(track,sector);
seek(infile,_filepos);
until (track=0);

close(outfile);
end.
