Вернуться к статье
Листинг 13. Определение времени перехода между дорожками жесткого диска
program JUMP_TIME;

const
      Drive    = $80;
      Head     = $00;
      StartCyl = $00;                  (* номер начального цилиндра *)
      StopCyl  = $4F;                  (* номер конечного цилиндра *)
 type
      Registers = record
                       case boolean
                       of
                          False : (AX,BX,CX,DX,BP,SI,DI,DS,ES,Flags : integer);
                          True  : (AL, AH, BL, BH, CL, CH, DL, DH   : byte)
                  end;
var
      Regs : Registers;
      Mask : byte;
      Time : real;
begin
(* начальное  позиционирование   головок *)
      Regs.AH := $0C;        (* функция перемещения головок *)
      Regs.CX := StartCyl;  (* номер начального цилиндра *)
      Regs.DH := Head;      (* номер выбранной головки *)
      Regs.DL := Drive;       (* логический  номер жесткого диска *)
      Intr ($13, Regs);          (* установка блока головок *)
      if Regs.Flags and 1 <> 0
      then                             (* есть   ошибка,  странно *)
           begin
                 WriteLn ('Ошибка ', Regs.AH);
                 Halt (-1)
           end;
      Regs.AH := $0C;            (* функция перемещения головок *)
      Regs.CX := StopCyl;      (* номер начального цилиндра *)
      Regs.DH := Head;          (* номер выбранной головки *)
      Regs.DL := Drive;           (* логический  номер жесткого диска *)
(* запрет  всех   аппаратных   прерываний *)
      Mask := Port [$21];          (* маска аппаратных прерываний *)
      Port [$21] := $FF;            (* запрет всех  прерываний *)
(* установка счетчика нулевого канала таймера *)
      Port [$43] := $36;               (* выбор нулевого канала таймера: *)
      Port [$40] := $01;               (* младший  байт  делителя *)
      Port [$40] := $00;               (* старший  байт  делителя *)
(* команда на перемещение  блока  головок *)
      Intr ($13, Regs);                (* установка блока головок *)
(* остановка счетчика и чтение результата *)
      Port [$43] := $00;
      Time := 65535.0 - (Port [$40] + Port [$40] * 256.0);
(* восстановление работы нулевого канала таймера *)
      Port [$43] := $36;               (* восстановление нулевого канала *)
      Port [$40] := $00;               (* 0 таймера: делитель = 0 *)
      Port [$40] := $00;
(* размаскирование аппаратных  прерываний *)
      Port [$21] := Mask;            (* восстановление  прерываний *)
      if Regs.Flags and 1 <> 0
      then                             (* есть   ошибка,  странно *)
           begin
                 WriteLn ('Ошибка ', Regs.AH);
                 Halt (-1)
           end;
      WriteLn ('Время перемещения головок = ', Time : 0 : 0);
      Halt (0)
end. (* JUMP_TIME *)

Вернуться к статье