Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

прерывания от клавивтуры

32K
30 мая 2010 года
paska
26 / / 06.02.2009
Здравствуйте. Подскажите пожалуйста как правильно считывать код нажатой клавиши из порта 60. Пишу программу которая при нажатии на определенную клавишу должна подавать сигнал на системный динамик. Но почему то не работает.

Код:
{$M $1000,0,0}
Program Scan_code;
Uses Crt,Dos;
Var
    cod1,cod2,duration,frequency:integer;
    OldKey: Procedure;
    c,c1  : Byte;
    vkl   : Boolean;
{$F+}
Procedure Key; Interrupt;  
Begin
     if((Port[$60] < $80) and (Port[60]=$1071)) then //если нажата
клавиша "q" то подаем сигнал
      begin
       Sound(frequency);
       Delay(duration);
       NoSound;
      end
     else
      begin
       Sound(0);
       Delay(0);
       NoSound;
      end;

  Inline($9C);
  OldKey;
End;
{$F-}
Begin
  if ParamCount <> 2 then
  begin
  writeln('maisentry parameter!!!');
  writeln('will enter <duration of the signal> <frequency of the signal>');
  exit;
  end;
  val(paramStr(1),duration,cod1);
  val(paramStr(2),frequency,cod2);
  if (cod1 <> 0) or (cod2 <> 0) then
  begin
  writeln('maisentry parameter!!!');
  writeln('will enter <duration of the signal> <frequency of the signal>');
  exit;
  end
  else
  begin
vkl:=false;
  GetIntVec($9,@OldKey);
  SetIntVec($9,Addr(Key));
  Keep(0);
  end;
End.
399
30 мая 2010 года
KIV
432 / / 20.01.2009
Вы читаете порт два раза. А данные в нём есть только один раз. Надо так:
Код:
Procedure Key; Interrupt;  
var Key: Byte;
Begin
     Key := Port[$60];
     if Key=код_клавиши then //если нажата
клавиша "q" то подаем сигнал
      begin
       Sound(frequency);
       Delay(duration);
       NoSound;
      end;
  Inline($9C);
  OldKey;
End;

К тому же зачем проверять сначала меньше ли число 0x80, а затем равно ли оно 0x1071? Во-первых, достаточно оставить только равенство - в неравенстве тут смысла нет. Во-вторых, 0x1071 > 0x80. И в-третьих, скан-код клавиши Q отнюдь не 0x1071. Это ещё не все замечания.
 
Код:
Sound(0);
Delay(0);
NoSound;

Зачем? Особенно зачем Delay(0)?
И наконец как вы вызываете старый обработчик прерывания? Как как, а так его вызывать нельзя. Это же не процедура. На что-то в этом роде:
 
Код:
asm
    pushf
    call far OldKey
end;

UPD:
 
Код:
Inline($9C);

Если это pushf, то обработчик вы, скорее всего, вызываете правильно. Только вот работать он не будет, т. к. вы уже считали символ из порта клавиатуры. Порт клавиатуры позволяет считать очередной символ из внитреннего буфера клавиатуры. Если вы прочитали его один раз, то в следующий раз там будет уже другой символ (если пользователь нажал две клавиши до того ка программа начала их считывать) или ничего не будет (как правило именно так, потому что программа должна успеть обработать нажатия быстрее, чем пользователь будет успевать наживать клавиши).
Таким образом если вы читаете сами порт 0x60, то вызывать старый обработчик уже не получится - только самим выполнить его работу. Чтобы не делать за него его работу можно сначала вызвать его, а потом посмотреть буфер клавиатуры (самим посмотреть, а не считать из него клавишу с помощью BIOS или DOS).
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог