Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 01.11.2010, 19:35   #1
Kingdom_Reborn
Форумчанин
 
Регистрация: 21.10.2010
Сообщений: 130
По умолчанию Резидент на Borland Pascal.

Такой вопрос. Есть обработчики прерываний клавиатуры и системного таймера. Вся работа обработчика таймера заключается в прибавлении единицы к некоторой переменной T с каждым прерыванием. Когда у меня T становится равным некоторому K, то нужно вызвать некоторую процедуру P и занулить T. Каким образом сделать, чтобы программа была резидентной и по условию из обработчиков прерываний процедуры вызывать нельзя...
Kingdom_Reborn вне форума Ответить с цитированием
Старый 01.11.2010, 19:47   #2
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Уверены, что Вам нужен именно резидент?! Под MS DOS?

копайте в сторону TerminateAndStayResident

абстрактный пример программы (только не спрашивайте, для чего она и что она делает ))
(ну ладно, вообще-то, это руссификатор древнего матричного принтера, у которого кодовая таблица была какая-то левая, перехватывает 17-е прерывание DOS):
Код:
{$S-,R-,V-,I-,B-,F-}
program PrinterDriver;
uses
  Dos,
  TpInt,
  TpTsr,
  printer;

const
  ProgName: string[13] = 'PRDRV V1.0';
  MyIsrHandle = 15;
  MainKey = $082D;

var
  Russs:boolean;
  PtrToF:pointer;

{$F+}
procedure MyIsr(BP:word);Interrupt;
const
  ESC = 27;

var
  Regs:IntRegisters absolute BP;
  _AL : byte;
  Russ: boolean absolute Russs;

begin

  if Regs.AH = $00 then begin
    if ((((Regs.AL>=128) and (Regs.AL<=175)) or
        ((Regs.AL>=224) and (Regs.AL<=239))) and (not Russ)) then begin
      _AL:=Regs.AL;
      Russ:=True;
      Regs.AL:=ESC;
      EmulateInt(Regs,Isr_Array[MyIsrHandle].OrigAddr);
      Regs.AL:=37;
      Regs.AH:=$00;
      EmulateInt(Regs,Isr_Array[MyIsrHandle].OrigAddr);
      Regs.AL:=1;
      Regs.AH:=$00;
      EmulateInt(Regs,Isr_Array[MyIsrHandle].OrigAddr);
      Regs.AL:=_AL;
      Regs.AH:=$00;
    end else if ((Regs.AL>63) and ( Regs.AL<128) and Russ) then begin
      _AL:=Regs.AL;
      Russ:=False;
      Regs.AL:=ESC;
      EmulateInt(Regs,Isr_Array[MyIsrHandle].OrigAddr);
      Regs.AL:=37;
      Regs.AH:=$00;
      EmulateInt(Regs,Isr_Array[MyIsrHandle].OrigAddr);
      Regs.AL:=0;
      Regs.AH:=$00;
      EmulateInt(Regs,Isr_Array[MyIsrHandle].OrigAddr);
      Regs.AL:=_AL;
      Regs.AH:=$00;
    end;
  end;
  if Regs.AL>=128 then begin
    if Regs.AL<=175 then Regs.AL:=Regs.AL-64;
    if ((Regs.AL>=224) and (Regs.AL<=239)) then Regs.AL:=Regs.AL-112;
  end;
  EmulateInt(Regs,Isr_Array[MyIsrHandle].OrigAddr);
end;

begin
  writeln ('Copyrigth (c) 1991 by Sikorskij S.G. < MHTS >',progname);
  if not InitVector($17, MyIsrHandle, @MyIsr ) then
    writeln('Can`t to replase interrap vector');

   if ModuleInstalled(ProgName) then begin
     writeln('Abort.Program is resident');
     Halt;
   end;
   Russs:=False;
   InstallModule(ProgName,Nil);
   writeln('Module installed');

  {Initialize main resident procedure}
{  if not DefinePop(MainKey, @DRV, Ptr(SSeg, SPtr), True) then
    writeln('error'); }

  {terminate and stay resident}
  if not TerminateAndStayResident(ParagraphsToKeep+10, 0) then
    writeln('Can`t to stay resident');

{$F-}
end.
сорри... Тут используется библиотечка TurboPower
без неё надо копать в сторону:
Код:
    {go resident}
    Regs.AH := $31;          {DOS Keep function}
    Regs.AL := ExitCode;     {return code for DOS}
    Regs.DX := ParasToKeep;  {paragraphs to keep}
    MsDos(Regs);

Последний раз редактировалось Serge_Bliznykov; 01.11.2010 в 19:57.
Serge_Bliznykov вне форума Ответить с цитированием
Старый 01.11.2010, 20:27   #3
Kingdom_Reborn
Форумчанин
 
Регистрация: 21.10.2010
Сообщений: 130
По умолчанию

Спасибо, а можно что-нибудь по проще, а то долго разбираться...

В общем у меня такой код:

Код:
...

procedure P; Forward;

{$F+}
procedure TimerHandler;
Interrupt;
begin
  Inc(Time);
  if T = K then
  begin
    T := 0;
    P;
  end;
  Inline($9C);
  OldTimerHandler;
end;
{$F-}

begin
  ...
  GetIntVec($8, @OldTimerHandler);
  SetIntVec($8, Addr(TimerHandler));
  ...
  Keep(0);
end.
Мне нужно исключить из TimerHandler вызов процедуры P.
Когда я пишу что-то типа
Код:
...

procedure P; Forward;

{$F+}
procedure TimerHandler;
Interrupt;
begin
  Inc(Time);
  Inline($9C);
  OldTimerHandler;
end;
{$F-}

begin
  ...
  GetIntVec($8, @OldTimerHandler);
  SetIntVec($8, Addr(TimerHandler));
  ...
  while True do
    if T = K then
    begin
      T := 0;
      P;
    end;  
end.
то у меня по очевидным причинам программа как бы "виснет", т. е. в командной строке ничего набрать нельзя... А нужно чтобы во время работы программы консоль функционировала в нормальном режиме
Kingdom_Reborn вне форума Ответить с цитированием
Старый 01.11.2010, 21:00   #4
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

так правильно виснет!

Вы же напишите код процедуры вместо P (внутри обработчика прерывания:
Код:
procedure TimerHandler;
Interrupt;
begin
  Inc(Time);
  if T = K then
  begin
    T := 0;

    Тут ваш код из процедуры P

  end;


  Inline($9C);
  OldTimerHandler;
end;
Serge_Bliznykov вне форума Ответить с цитированием
Старый 01.11.2010, 21:29   #5
Kingdom_Reborn
Форумчанин
 
Регистрация: 21.10.2010
Сообщений: 130
По умолчанию

Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
так правильно виснет!

Вы же напишите код процедуры вместо P (внутри обработчика прерывания:
Код:
procedure TimerHandler;
Interrupt;
begin
  Inc(Time);
  if T = K then
  begin
    T := 0;

    Тут ваш код из процедуры P

  end;


  Inline($9C);
  OldTimerHandler;
end;
да я бы с радостью, но только это по условию нельзя...
Kingdom_Reborn вне форума Ответить с цитированием
Старый 02.11.2010, 10:56   #6
Kingdom_Reborn
Форумчанин
 
Регистрация: 21.10.2010
Сообщений: 130
Вопрос

Товарищи, тема всё ещё актуальна, может есть у кого какие идеи? Преподаватель говорит, что из обработчика прерываний таймера не должно быть никаких вызовов процедур, тем более тех, что требуют значительное время на выполнение, он говорит, что с помощью обработчика прерываний таймера нужно считать только время, а вызов процедур осуществлять в основной программе в бесконечном цикле... Я лично не представляю, как с использованием бесконечного цикла оставить работоспособной консоль, она у меня справедливо блокируется...
Kingdom_Reborn вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Borland Pascal лаб. Павел Тихомиров Помощь студентам 12 24.11.2010 11:11
Задачи на Borland Pascal Lerik09 Помощь студентам 6 20.10.2009 19:43
Borland Pascal 8. Ошибочка...:( spein Помощь студентам 5 27.02.2009 17:19
Нужен Borland Pascal 7.0? kuzmich Паскаль, Turbo Pascal, PascalABC.NET 6 08.12.2007 11:21
BP: Borland Pascal DruidD Помощь студентам 6 29.05.2007 20:06