procedure Abort(S :Wrkstring);
begin
  gotoxy(1,33);
  writeln(S);
  halt
end;

procedure HDC_Wait;
begin
  while (port[Hdcstat] and $80) <> 0 do
end;

procedure HDC_Drq;
begin
  while (port[Hdcstat] and $8) = 0 do
end;

procedure HDC_Clear_Drq;
var
  Bt :byte;
begin
  while (port[Hdcstat] and $8) <> 0 do Bt:=port[Hdcdata]
end;

procedure Test_Status(AbortFlg :boolean);
var
  Error :integer;
  S     :Str10;
begin
  if (port[Hdcstat] and $01) <> 0 then
  begin
    Error:=port[Hdcerr];
    if AbortFlg then
    begin
      Str(Error:4,S);
      Abort('Fehler : HDC meldet Fehler :'+S)
    end
    else write(' >',Error,'< ')
  end
end;

procedure HDC_Home;
begin
  port[Hdccmd]:=Restore_CMD;
  HDC_Wait
end;

procedure HDC_Format;
begin
  HDC_Wait;
  port[Hdccmd]:=Format_CMD
end;

procedure HDC_Read_Noretry;
begin
  HDC_Wait;
  port[Hdccmd]:=Read_Fast_CMD
end;

procedure Update_Task_Register(Cylinder,Head,Sector :integer);
begin
  HDC_Wait;
  port[Hdcsdh]:=lo(Sekt_Size or Head or $08);
  port[Hdccyl]:=lo(Cylinder);
  port[Hdccyh]:=hi(Cylinder);
  port[Hdcsek]:=lo(Sector)
end;

procedure Set_SectorCount(Cnt :integer);
begin
  port[Hdcscnt]:=lo(Cnt)
end;

procedure Get_Data_from_HDC;
var
  I :integer;
begin
  HDC_Wait;
  HDC_Drq;
  for I:=0 to Sektor_Laenge div 128 do inline($21/Buffer/$01/$A8/$80/$ED/$B2)
end;

procedure Send_Data_to_HDC;
var
  I :integer;
begin
  HDC_Drq;
  for I:=0 to Sektor_Laenge div 128 do inline($21/Buffer/$01/$A8/$80/$ED/$B3);
  HDC_Wait
end;

procedure HDC_Read;
begin
  HDC_Wait;
  port[Hdccmd]:=Read_CMD;
  Get_Data_from_HDC
end;

procedure HDC_Write;
begin
  HDC_Wait;
  port[Hdccmd]:=Write_CMD;
  Send_Data_to_HDC
end;

procedure HDC_Init;
var
  Dummy :integer;
begin
  Dummy:=port[Hdcstat];
  HDC_Wait;
  case Sektor_Laenge of
    128  : Sekt_Size:=$60;
    256  : Sekt_Size:=$00;
    512  : Sekt_Size:=$20;
    1024 : Sekt_Size:=$40
    else Abort('Interner Fehler : falsche Sektorlaenge !')
  end;
  port[Hdcwpc]:=Precomp_Spur div 4;
  Update_Task_Register(0,0,0);
  HDC_Home
end;

procedure Readsec(Abssec :integer);
var
  I,Kopf,Zylinder,Sektor :integer;
begin
  I:=Abssec div Sektoren_pro_Spur;
  Zylinder:=I div Anzahl_Koepfe;
  Kopf:=I mod Anzahl_Koepfe;
  Sektor:=Abssec mod Sektoren_pro_Spur;
  Update_Task_Register(Zylinder,Kopf,Sektor);
  HDC_Read_Noretry;
  HDC_Wait;
  Get_Data_from_HDC;
  Test_Status(false)
end;

procedure HDC_Deselect;
begin
  port[Hdcsdh]:=$00
end;
