Консультация № 181187
09.12.2010, 22:23
72.69 руб.
0 13 1
Здравствуйте, уважаемые эксперты! Прошу Вас ответить на следующий вопрос: в режиме опроса определить номер прерывания от клавиатуры.

Обсуждение

давно
Профессионал
304622
583
09.12.2010, 22:45
общий
Хм-м! А что в Паскале Вы называете "режимом опроса"? Вы уверены, что у Вас вопрос по Паскалю, а не по ассемблеру?
Неизвестный
09.12.2010, 23:20
общий
Да, уверен. это задание к лабораторной работе, там приводится пример программы, которая иллюстрирует особенности написания обработчиков прерываний от таймера и клавиатуры, а также программирование контроллера в режиме автоматического завершения прерывания.

{$m,$800,0,0}
program cont_int; { программирование ПКП и }
uses crt; { обработка прерываний }
var i:integer;
procedure scan; interrupt; { обработчик прерывания }
begin от клавиатуры
asm sti end; { разрешить прерывания }
writeln(port[$60]); { обязательное чтение порта }
meml[0:9*4]:=meml[0:$60*4]; { восстановление вектора 9 }
port[$21]:=1; {**} { OCW1:маскирование таймера }
delay(5000); {**} { в течение 5 сек. }
port[$21]:=0; {**} { размаскирование таймера }
delay(5000); { прерывание от таймера прерывает }
{ обработку прерывания от клавиатуры }
port[$20]:=$21; { сброс бита ISR уровня 1 }
meml[0:8*4]:=meml[0:$62*4]; { восстановление вектора 8 }
end; {scan}

procedure tick; interrupt; { обработчик прерывания }
begin { от таймера }
if i>20 then begin
write('8'); { вывод "8" через 1 сек }
i:=0
end else inc(i);
port[$20]:=$20; {* -} { сброс бита ISR наивысшего уровня }
end; {tick}
begin
if meml[0:$61*4]<>12345 then { реализация возможности повторного }
begin { запуска резидентной программы }
meml[0:$62*4]:=meml[0:8*4]; { сохранение системных обработчиков }
meml[0:$60*4]:=meml[0:9*4] { прерываний от таймера и клавиатуры }
meml[0:$61*4]:=12345;
end;
i:=0;
port[$20]:=$11; {ICW1} {* +} { управляющие слова }
port[$21]:=8; {ICW2} {* +} { ICW1 - ICW3 }
port[$21]:=4; {ICW3} {* +} { не изменены }
port[$21]:=3; {1} {ICW4} {* +} { режим автоматического завершения }
meml[0:9*4]:=longint(@scan); { установка обработчика прерывания 9 }
meml[0:8*4]:=longint(@tick); { установка обработчика прерывания 8 }
keep(0) { программа - резидентна }
end.

давно
Профессор
230118
3054
11.12.2010, 22:15
общий
Это ассемблерная вставка, поэтому вопрос лучше отправить в раздел "ассемблер".
Неизвестный
12.12.2010, 18:15
общий
Так что будем делать?
  • Оформлять ассемблерную вставку;
  • уточнять суть вопроса (что такое "режим опроса"? - Вводить "это 16-е прерывание? Ответ: нет");
  • или просто удалить?
Неизвестный
12.12.2010, 18:52
общий
Оформлять ассемблерную вставку
Неизвестный
12.12.2010, 20:24
общий
А делать-то что она должна? Что, как Вы представляете, означает задание в режиме опроса определить номер прерывания от клавиатуры
Неизвестный
12.12.2010, 20:46
общий
контроллер прерываний работает в режиме опроса (устанавливается с помощью OCW3), при нажатии любой клавиши на клавиатуре происходит прерывание от клавиатуры, необходимо вывести номер этого прерывания на экран (номер прерывания по моим предположениям находится в IRR или ISR).
давно
Старший Модератор
31795
6196
13.12.2010, 13:07
общий
Адресаты:
Цитата: Асмик Гаряка
Это ассемблерная вставка, поэтому вопрос лучше отправить в раздел "ассемблер".

Кто Вам это сказал?
Цитата: минифорум
port[$20]:=$20;

это паскалевский эквивалент команд ассемблера EOI(End of Interrupt):
Код:
MOV     AL, 20H
OUT 20H, AL

Mассив port, также как массив portw - позволяет получить доступ к портам (впервом случае байт, во втором - слово).
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Старший Модератор
31795
6196
13.12.2010, 14:54
общий
Нажата клавиша, соответсвующие биты в регистрах контролера IRR(Interrupt Request Register)=1 ISR(Interrupt Service Register)=0, IMR(Interrupt Mask Register) пока не расматриваем. Контролер выставил сигнал INTR и ожидает поступления сигнала от процессора INTA. Как только сигнал INTA будет получен сбрасывается IRR=0 и устанавливается ISR=1 и начинается обработка, т.е. считывается ISR контролера и передается управление соответсвующему обработчику, в данном случае клавиатуры. Значения битов IRR ставятся вне зависимости от состояния контролера. Если выставлен соответсвующий бит IMR, то сигнал INTR, при установке IRR блокируется. Кому интересно, блок-схема контролера 8259:



Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Профессионал
304622
583
13.12.2010, 15:30
общий
Адресаты:
А мне вот что любопытно? Что значит "определить номер прерывания от клавиатуры"? Разве от клавиатуры могут быть разные прерывания? Я тут , конечно, дилетант. Но смотрю книгу Нортона, смотрю TECHHELP -- вижу только про INT 09H и скэн-коды. Что я не понимаю?
Неизвестный
13.12.2010, 16:59
общий
Адресаты:
Да нет, в том-то и хитрость, что нужно сказать, определить этот номер программно
давно
Старший Модератор
31795
6196
13.12.2010, 17:31
общий
Адресаты:
Тут вопрос больше по программированию на уровне портов. Сами по себе оболочки BIOS и DOS предоставляют стандартизированые интерфейсы работы с железом. Запустил функцию с таким-то номером и нужными входными данными и всё работа сделана. Работа с контролерами, с помощью команд IN/OUT, заставляет изучать особенности каждого контролера(клавиатуры, FDD, HDD и т.д.). К примеру этот контролер(8259) может работать с 8080 и 8086/8088 процессорами, выбор нужного режима работы производится при его инициализации.

Цитата: Сергей Бендер
Что значит "определить номер прерывания от клавиатуры"? Разве от клавиатуры могут быть разные прерывания?

Аппратное прерывание от клавиатуры(варианты с двумя клавами нерасматриваем, всё касеется только схемотехники IBMх86 и её клонов) может быть только одно и приходить оно будет на IR1(см. блок схему)), на IR0 будет приходить прерывание таймера, которое имеет высший приоритет. Если замаскировать IR0, то прерывание от клавиатуры будет с наивысшим приоритетом.


Что касается самого вопроса:
Цитата: OSDev Wiki:Программируемый контроллер прерываний
Режим программного опроса

Режим программного опроса (Poll Mode) предназначен для чисто программного получения и обработки запросов прерываний. Для его организации внешние прерывания процессора должны быть запрещены путём сброса флага IF.
Чтобы проверить наличие незамаскированного запроса прерывания, программа выдаёт контроллеру управляющее слово операций 3 (OCW3), в котором установлен 2-й разряд (бит программного опроса). Получив такую команду, контроллер прерываний, если имеются незамаскированные запросы прерываний, выбирает самый приоритетный из них, сбрасывает соответствующий ему разряд IRR и устанавливает разряд ISR, после чего запоминает номер линии IRQ для этого запроса. Когда процессор впервые после выдачи OCW3 произведёт чтение из контроллера прерываний, ему будет возвращён байт, старший бит которого будет содержать единицу, если на момент выдачи OCW3 имелся незамаскированный запрос прерыания, и нуль в противном случае. Если запрос прерывания был, младшие три бита этого байта будут содержать код линии IRQ, по которой поступил данный запрос.
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Старший Модератор
31795
6196
16.12.2010, 21:26
общий
это ответ
Здравствуйте, Alexkharkov!

Смотрите приложение.
Линия IRQ1 маскируется. В обработчике таймера маска снимается, т.к. управляющее слово операций 3 (OCW3), с установленым битом программного опроса позволяет получить только немаскированные прерывания. Масирование прерывания клавитуры нужно для того, чтобы стандартный обработчик клавиатуры не получил управление в перерывах между вызовами обработчика таймера. При каждом вызове обработчика таймера выводится число - 7, признак отсутствия прерывания.
вопросы задавайте в мини-форум.
Удачи!

Приложение:
program q01;
var
a,b:byte;
c:word;
z:longint;
procedure aa;interrupt;
begin
port[$21]:=0;{снимаем маску}
c:=$FFFF;while c>0 do dec(c);{цикл задержки}
port[$20]:=$0C;{режим опроса}
a:=port[$20];{считываем значение}
if a > $7F then b:= a and $7F;
write(a,' ');{контрольный вывод}
c:=$FFFF;while c>0 do dec(c);{цикл задержки}
port[$21]:=2;{ставим маску}
port[$20]:=$20;{завершаем прерывание}
end;
begin
z:=meml[0:4*8];{старый обработчик}
port[$20]:=$11;
port[$21]:=8;
port[$21]:=4;
port[$21]:=3;
c:=$FFFF;while c>0 do dec(c);{цикл задержки}
port[$21]:=2;{маскируем}
meml[0:8*4]:=longint(@aa);{ставим свой обработчик}
repeat
c:=$FFFF;while c>0 do dec(c);{цикл задержки}
until b>0;
port[$21]:=0;{снимаем маску}
meml[0:4*8]:=z;{востанавливаем старый обработчик}
write(b);{выводим номер линии}
readln;
end.
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Форма ответа