program HdFormat;
const
  {$I HDCDEF.INC}
  Track_Length = 10416;
  Cr           = #$0D;
  Esc          = #$1B;
type
  Wrkstring = string[80];
  Str10     = string[10];
var
  Gap3_Len  :integer;
  Sekt_Size :integer;
  Buffer    :array[1..1024] of byte;
  Maxtrack  :integer;
  Maxsek    :integer;
  I,Inter   :integer;
  Ch        :char;

{$I HDCROUT.INC}

procedure Compute_Gap3_Len;
var
  K :integer;
begin
  if Inter = 1 then K:=25 else K:=0;
  Gap3_Len:=round((2*Speedvar*Sektor_Laenge)/100)+K;
  writeln; writeln;
  writeln(' Gap3-Laenge = ',Gap3_Len)
end;

procedure Checkspace;
var
  K1,K2 :integer;
begin
  K1:=43;
  K2:=Gap3_Len;
  K1:=K1+Sektor_Laenge+K2;
  K1:=Sektoren_pro_Spur*K1;
  if K1 > Track_Length then Abort('Fehler : gewaehltes Format ist zu lang fuer eine Spur !')
end;

procedure Clear_Buffer;
var
  I :integer;
begin
  for I:=1 to Sektor_Laenge do Buffer[I]:=$E5
end;

procedure Setup_Buffer;
var
  First,Sek_Num,I :integer;
begin
  writeln;
  repeat
    write(' Interleaving Faktor eingeben [1..',Sektoren_pro_Spur,'] : ');
    readln(Inter)
  until (Inter > 0) and (Inter <= Sektoren_pro_Spur);
  for I:=1 to (2*Sektor_Laenge)+1 do Buffer[I]:=0;
  First:=0;
  Sek_Num:=0;
  for I:=0 to Sektoren_pro_Spur-1 do
  begin
    Buffer[2*Sek_Num+2]:=lo(I);
    Sek_Num:=Sek_Num+Inter;
    if Sek_Num >= Sektoren_pro_Spur then
    begin
      First:=First+1;
      Sek_Num:=First
    end
  end;
  writeln;
  for I:=1 to Sektoren_pro_Spur do write(Buffer[2*I]:2,' ')
end;

procedure Formatiere_Spur(Spur :integer);
var
  Zylinder,Kopf :integer;
  Tmp           :integer;
begin
  Tmp:=Gap3_Len-3;
  if Tmp < 0 then Tmp:=0;
  Zylinder:=Spur div Anzahl_Koepfe;
  Kopf:=Spur mod Anzahl_Koepfe;
  write(chr($0D),' Zylinder = ',Zylinder:4,' Kopf = ',(Kopf+1):1);
  Update_Task_Register(Zylinder,Kopf,Tmp);
  Set_Sectorcount(Sektoren_pro_Spur);
  HDC_Format;
  Send_Data_to_HDC;
  Test_Status(true)
end;

procedure Fuelle_Sektoren(Spur :integer);
var
  Zylinder,Kopf,Sektor :integer;
begin
  Zylinder:=Spur div Anzahl_Koepfe;
  Kopf:=Spur mod Anzahl_Koepfe;
  write(chr($0D),' Zylinder = ',Zylinder:4,' Kopf = ',(Kopf+1):1);
  for Sektor:=0 to Sektoren_pro_Spur-1 do
  begin
    Update_Task_Register(Zylinder,Kopf,Sektor);
    Set_Sectorcount(0);
    HDC_Write;
    Test_Status(false);
    HDC_Read;
    Test_Status(false)
  end
end;

procedure Init_Format;
begin
  Setup_Buffer;
  Compute_Gap3_Len;
  Checkspace;
  HDC_Init;
  Maxtrack:=Anzahl_Koepfe*Anzahl_Zylinder
end;

procedure DoFormat;
var
  Spur                   :integer;
  Kopf_u,Kopf_o          :integer;
  Spur_u,Spur_o          :integer;
  Sektor_u,Sektor_o      :integer;
  Kopf_l,Spur_l,Sektor_l :integer;
begin
  Init_Format;
  writeln; writeln(' Formatierbereichs-Eingabe');
  repeat
    write(' Kopf (1-',Anzahl_Koepfe:1,') : ');
    read(Kopf_u); write('-'); read(Kopf_o); writeln
  until (Kopf_u > 0) and (Kopf_o <= Anzahl_Koepfe);
  repeat
    write(' Spur (0-',Anzahl_Zylinder:3,') : ');
    read(Spur_u); write('-'); read(Spur_o); writeln
  until (Spur_u >= 0) and (Spur_o <= Anzahl_Zylinder);
  writeln;
  writeln(' Das Formatieren beginnt : ');
  for Spur_l:=Spur_u to Spur_o do
  begin
    for Kopf_l:=Kopf_u-1 to Kopf_o-1 do
    begin
      Spur:=(Kopf_l and (Anzahl_Koepfe-1)) or (Spur_l*Anzahl_Koepfe);
      Formatiere_Spur(Spur)
    end
  end;
  writeln;
  writeln(' Disk ist formatiert . ');
  writeln;
  writeln(' Die Sektoren werden jetzt mit 0E5H gefuellt : ');
  Clear_Buffer;
  for Spur_l:=Spur_o downto Spur_u do
  begin
    for Kopf_l:=Kopf_o-1 downto Kopf_u-1 do
    begin
      Spur:=(Kopf_l and (Anzahl_Koepfe-1)) or (Spur_l*Anzahl_Koepfe);
      Fuelle_Sektoren(Spur)
    end
  end;
  writeln; writeln;
  writeln('Formatierung beendet')
end;

begin
  clrscr;
  writeln('Hard-Disk-Formatter [V1.0]');
  writeln;
  writeln('A C H T U N G :');
  writeln('Mit dem Formatieren gehen alle Daten auf der Hard-Disk verloren !');
  writeln('Ist dies unerwuenscht, so kann jetzt mit <ESC> beendet werden.');
  writeln('Der Formatiervorgang selbst kann nur mit ^S^C abgebrochen werden !');
  writeln('Bitte Kaffee aufsetzen. (Das Formatieren dauert...)');
  writeln;
  writeln(' Mit <CR> wird das Formatieren gestartet.');
  writeln;
  write(' <ESC> oder <CR> jetzt eingeben : ');
  if keypressed then read(kbd,Ch);
  read(kbd,Ch);
  writeln;
  if Ch = Cr then DoFormat
  else
  begin
    writeln;
    writeln('Formatieren wurde abgebrochen !')
  end;
  HDC_Deselect
end.
