Vectors.PAS

{* Создание обработчика прерываний *}

Unit VECTORS;
Interface
Implementation
Begin
 writeln('Использование COM-порта как таймера под Win');
End.

Program pas;

Uses Vectors.pas; {* Эту строку можно удалить *}
{$R - }
{$S - }
{$C FIXED PRELOAD PERMANENT}
unit Vectors; { ==== }
interface   { ===== }
Uses WinTypes, WinProcs, WinDos, Messages; {* Подключение модулей *}
Var {* Объявление переменных *}
  Old_Vec0B                       : Pointer; { == для запоминания старого вектора == }
  H_Module                        : tHandle; { == модуль, которому будут посылаться }
  { == квантованные сообщения == }
  { = H_Module := GetCurrentTask;
  - внизу в секции инициализации = }

  { == сообщения из обработчика прерываний == }
Function SetMyVector(  Nom_Vec  : Byte; { = номер вектора Intr == }
New_Vector                      : Pointer; { = ук - ль на новый обработчик == }
)                               : Pointer; { == возвращает старый вектор == }
Procedure SetOldVector( Nom_Vec : Byte;
Old_Vec                         : Pointer); { === }
{ === }
{$IFDEF COM1}
{$
Else }

  {$EndIF} { ================== Собственно обработчик прерываний ==================== }
Var {* Объявление переменных *}
  j                                 : Byte;
  nkan                              : Word;
Begin
  j := Port[Baze_Port + $0D]; { == сбросить регистр прерываний == }
  j := Port[Baze_Port + $08]; { == сбросить регистр данных == }
  Port[Baze_Port + $08] := $55; { == снова "зарядить" "прерыватель" == }
  { == передать сообщение == }
  Port[$20] := $20; { == сбросить контроллер прерываний == }
  { == Handler == }
  { == Инициализация COMa, программирование маски и установка вектора ======== }
  Function SetMyVector( New_Handler : Pointer);
  Var {* В работе нам потребуются переменные: *}
    i       : Byte;
    j       : Byte;
    Old_Vec : Pointer;
  Const {* Постоянные значения *}
    Divider = 57; { == задать требуемую величину делителя таймера COMa == }
    Begin
      Port[Baze_Port + $0B] := Port[Baze_Port + $0B] Or $80; { == DLAB := 1 == }
      PortW[Baze_Port + $08] := Divider; { = = 57 - 5 msec;
      23 - 5000 бод (2мсек) = = }

      ^    Port[Baze_Port + $0B] := Port[Baze_Port + $0B] And $7F; { == DLAB := 0 == }
      Port[Baze_Port + $0b] := $03; { == 8бит, 1стоп, без контр == }
      i := Port[Baze_Port + $08];
      asm cli
    End;
    GetIntVec(Nom_Vec, Old_Vec); { == сохранить старый адрес === }
    SetIntVec(Nom_Vec, New_Vector); { == установить адрес п / п === }
    i := Port[$21];
    Port[$21] := (i Or $18); { == установить маску === }
    Port[$21] := Port[$21] And $E7;
    Port[Baze_Port + $0B] := Port[Baze_Port + $0B] And $7F;
    Port[Baze_Port + $09] := 1; { == разрешить прерывания от СОМа === }
    i := Port[Baze_Port + $0E]; { == сброс прерывания от модема == }
    Port[Baze_Port + $0C] := $0B;
    SetMyVector := Old_Vec;
    asm sti
End;
  Port[Baze_Port + $08] := $AA; { == сразу зарядить "прерыватель" == }
  End{ SetMyVector }
  { ========= Восстановить старый обработчик ============================ }
Procedure SetOldVector( Nom_Vec : Byte;
Old_Vec : Pointer);
Begin
asm cli
End;
SetIntVec(Nom_Vec, Old_Vec);
asm sti
End;

End{ =========== }
initialization   { ========== }
h_Module := GetCurrentTask;
End......