Каскадное включение прерываний

Время от времени бывает полезным добавить код к стандартному обработчику прерывания. Каскадное включение – это такая установка в систему нового обработчика прерывания, при которой он получает управление в случае появления аппаратного либо программного прерывания, делает какие-то свои деяния, а потом вызывает старенькый (стандартный) обработчик этого прерывания. К примеру, разглядим Каскадное включение прерываний программки, которые употребляют тот факт, что весь ввод с клавиатуры поступает через функцию 0 прерывания $16 BIOS. Все прерывания ввода с клавиатуры DOS вызывают прерывание BIOS для получения знака из буфера клавиатуры. Потому, если видоизменять прерывание $16 таким макаром, чтоб оно делало дополнительные функции, то неважно какая программка будет получать эти функции Каскадное включение прерываний (при нажатии кнопки) независимо от того, какое прерывание ввода с клавиатуры она употребляет.

Для этого необходимо написать резидентную функцию, которая предшествует либо следует за подходящим прерыванием и может вызываться при вызове прерывания DOS либо BIOS.

К примеру, в случае прерывания $16 необходимо написать функцию (пусть она именуется NewProc) обработки этого Каскадное включение прерываний прерывания и указать на неё вектором $16. Оригинальное значение вектора $16 тем временем переносится в какой-нибудь дополнительный вектор. Тогда новенькая процедура кроме собственных собственных действий вызывает этот вектор, чтоб использовать стандартный обработчик прерывания $16. В новейшей процедуре может содержаться хоть какой код как до, так и после вызова прерывания по старенькому вектору Каскадное включение прерываний. После чего, если какая-либо программка вызывает прерывание $16, управление поначалу передается процедуре NewProc. Она после каких-либо собственных действий вызывает оригинальное прерывание $16 (методом вызова дополнительного вектора), а по его окончании управление ворачивается вспять к NewProc, из которой потом происходит возврат в то место программки, откуда поступил запрос на прерывание $16.

Итак, план Каскадное включение прерываний действий:

1. Сделать новейшую функцию, выполняющую нужные деяния и потом вызывающую вектор прерываний OldVector. Назовем ее NewProc.

Дальше в основной программке:

2. Перенести вектор прерывания для $16 в OldVector (GetIntVec ($16, @OldVector)).

3. Поменять вектор прерывания так, чтоб он указывал на новейшую функцию: (SetIntVec ($16, Addr(NewProc))).

4. Окончить программку, оставляя ее резидентной (Keep).

Ниже Каскадное включение прерываний приведён пример программки, которая обрабатывает прерывание клавиатуры и каждое нажатие на кнопку аккомпанирует звуком. После нажатия на кнопку ESC программка начинает дополнительно выводить коды нажатых кнопок, причём код нажатия и код отжатия различаются на 128 и выводятся в одной строке. Коды последующей нажатой кнопки – на последующей строке и т Каскадное включение прерываний.д. Для того чтоб проверить, является ли еще одно прерывание клавиатуры сигналом отпускания кнопки, употребляется дополнительная переменная c1, в которую сохраняется предшествующее значение, считанное с порта клавиатуры. Если они различаются на 128 – кнопка отпущена.

Перед процедурой – обработчиком прерывания врубается режим «дальней модели», после него он выключается. В конце нового обработчика вызывается стандартный Каскадное включение прерываний обработчик, который за ранее был сохранён под именованием OldKey.

{$M $1000,0,0}

Program Scan_code;

Uses Crt,Dos;

Var

OldKey: Procedure;

c,c1 : Byte;

vkl : Boolean;

{$F+}

Procedure Key; Interrupt; {обработчик прерывания}

Begin

c1:=c;

c:=Port[$60];

If c=1 then {нажали ESC}

vkl:=true;{включён режим отображения кодов нажимаемых клавиш}

If vkl Каскадное включение прерываний Then

Begin

write (' kod=',c,' ');

If c=c1+128 Then Writeln; {отпустили клавишу}

End;

Sound(1000);

Delay(100);

Nosound;

Inline($9C);

OldKey;

End;

{$F-}

Begin {основная программа}

vkl:=false; {сначала режим отображения кодов выключен}

GetIntVec($9,@OldKey);

SetIntVec($9,Addr(Key));

Keep(0);

End.

Задания на лабораторные работы

Лабораторная работа №1: Обработка прерываний клавиатуры

Теоретический материал

Работой клавиатуры управляет электрическая схема Каскадное включение прерываний, именуемая контроллером клавиатуры. В его функции заходит определение нажатой кнопки и помещение закреплённого за ней кода в выходной регистр (порт) с номером $60. Поступающий в порт код кнопки именуется скан-кодом и является в неком роде её порядковым номером. При всем этом каждой кнопке соответствуют два скан-кода, отличающиеся Каскадное включение прерываний на 128. Наименьший код (код нажатия) засылается в порт $60 при нажатии кнопки, больший код (код отпускания) – при отпускании кнопки. Такая система позволяет, к примеру, в случае, когда буквенная кнопка удерживается в нажатом состоянии (т.е. поступил код нажатия, но в течение некого интервала времени не поступило кода отпускания) перейти Каскадное включение прерываний в режим генерации неоднократного кода нажатия.

Каждое нажатие и каждое отпускание кнопки вызывает сигнал аппаратного прерывания, заставляющий микропроцессор оборвать выполняемую программку и перейти на программку обработки прерывания (ПОП) от клавиатуры, которая вызывается через вектор $09 (её нередко именуют программкой INT $09). Программка INT $09 работает, не считая порта $60, ещё с 2-мя областями оперативки: с Каскадное включение прерываний кольцевым буфером ввода (адреса от $40:$1E до $40:$3D), куда в конце концов помещаются коды ASCII нажатых кнопок, и словом состояния (либо словом флагов) клавиатуры (адресок $40:$17), где фиксируется состояние управляющих кнопок (, , и др. – см. набросок).

Программка INT $09, получив управление в итоге прерывания от клавиатуры, считывает из порта $60 скан Каскадное включение прерываний-код и анализирует его значение. Если он принадлежит управляющей кнопке и представляет собой код нажатия, то в слове флагов клавиатуры устанавливается флаг, соответственный нажатой кнопке (к примеру, при нажатии устанавливается бит 0, при нажатии – бит 1, – бит 2, – бит 3). Если управляющая кнопка отпускается, соответственный ей бит сбрасывается в 0.

При нажатии хоть какой другой кнопки Каскадное включение прерываний программка INT $09 считывает из порта $60 её скан-код нажатия и по таблице трансляции скан-кодов в коды ASCII сформировывает двухбайтовый код, старший б которого содержит скан-код, а младший – код ASCII. При всем этом скан-код охарактеризовывает кнопку, а ASCII-код определяет закреплённый за ней знак Каскадное включение прерываний. Так как за каждой кнопкой закреплено по нескольку знаков (более 2-ух), то каждому скан-коду соответствует несколько ASCII-кодов. При формировании двухбайтового кода программка INT $09 анализирует состояние флагов. К примеру, кнопке соответствует скан-код $10 (десятичное 16), ASCII-код буковкы Q – $51 (81), буковкы q – $71 (113). Если нажата при нажатой кнопке , то будет сформирован двухбайтовый код Каскадное включение прерываний $1051, по другому – код $1071. Если за ранее была нажата кнопка , то итог будет оборотным (включенный режим аннулирует следующее нажатие ).

При формировании двухбайтовых кодов неким особым кнопкам (к примеру, F1 – F10, , , , и т.п.) в таблице трансляции, с которой работает программка INT $09, соответствует нулевой код ASCII. Двухбайтовые коды, имеющие нулевой младший Каскадное включение прерываний б, именуются расширенными кодами ASCII и употребляются для управления программками.

Приобретенный в итоге трансляции двухбайтовый код засылается программкой INT $09 в кольцевой буфер клавиатуры, объем которого составляет 15 машинных слов. Коды знаков извлекаются из буфера по принципу FIFO. За состоянием буфера смотрят два указателя: в хвостовом указателе (слово по адресу $40:$1C Каскадное включение прерываний) хранится адресок первой свободной ячейки, в головном указателе ($40:$1A) – адресок самого старенького кода, принятого с клавиатуры и ещё не нужного программкой. Когда буфер пуст, оба указателя указывают на его первую ячейку. В процессе наполнения буфера хвостовой указатель сдвигается (по 2 б) до последнего адреса и вновь ворачивается на начало – и т Каскадное включение прерываний.д. по кольцу. Аналогично перемещается головной указатель при считывании кодов. Если при заполнении буфера не происходит считывания поступивших в него кодов (readkey), то при вводе более 16 знаков приём новых кодов блокируется, и следующие нажатия на кнопки сопровождаются предупреждающими звуковыми сигналами (переполнение буфера).

Для считывания кода нажатой кнопки выполняемая программка Каскадное включение прерываний вызывает прерывание INT $16, которое активизирует драйвер клавиатуры BIOS. Драйвер считывает из буфера коды, смещая при всем этом головной указатель; таким макаром, программный запрос на ввод с клавиатуры делает приём кода не прямо с клавиатуры, а из кольцевого буфера.

Задание для выполнения лаб. работы №1

Написать программку, которая должна «озвучивать» клавиатуру Каскадное включение прерываний, т.е. после пуска этой программки нажатие хоть какой кнопки на клавиатуре будет сопровождаться звуковым сигналом. Клавиатура при всем этом должна оставаться работоспособной, т.е. продолжать делать свои главные функции в обычном темпе.

Программка должна быть резидентной, т.е. оставаться в памяти после собственного окончания.

В качестве Каскадное включение прерываний пробного варианта продолжительность звукового сигнала и частоту задать константами в программке. Когда будет получена устойчивая работа программки, поменять её таким макаром, чтоб продолжительность звукового сигнала и его частота задавались в качестве характеристик при запуске программки.

Нужно предоставить юзеру возможность «выключать» и «включать» поновой звуковое сопровождение работы кнопок. Использовать для «выключения Каскадное включение прерываний/включения» звука неординарную комбинацию кнопок: сочетание нажатой кнопки с какой-нибудь ещё, к примеру, + …

Контрольные вопросы

1. Как поведёт себя Ваша программка, если в качестве характеристик командной строчки заместо требуемых по заданию продолжительности и частоты будут заданы неправильные значения, к примеру, знаки, строчки знаков, отрицательные либо дробные числа?

2. Как будет работать программка Каскадное включение прерываний, если задавать величину продолжительности звукового сигнала очень большой? Почему?

3. Как можно найти скан-коды требуемых кнопок?

4. В каком случае при нажатии и отпускании кнопки может раздаваться «двойной» сигнал?

5. Проверьте, что произойдет, если надавить кнопку и задерживать её в нажатом состоянии? Варианты – раздаётся неоднократно повторяемый звуковой сигнал, сигнал прозвучал Каскадное включение прерываний один раз. Что необходимо поменять в программке, чтоб она изменила собственный вариант поведения на другой?

6. Изменить программку для того, чтоб при нажатии хоть какой кнопки раздавался звук, соответственный данной в качестве параметра частоте сигнала, а отпускание кнопки аккомпанировал звук более высочайший (выше на 50% от данной частоты).

7. Для неких особых Каскадное включение прерываний кнопок установить продолжительность звукового сигнала большей в 2–3 раза (к примеру, для , либо ) – сделать в программке надлежащие конфигурации.

Лабораторная работа №2:
Управление таймером – операции в реальном времени
(программка «будильник»)

Теоретический материал

Системные часы выдают импульсы 18,2 раза за секунду. 4-байтовый счетчик этих импульсов хранится в памяти по адресу 0040:006C (младший б Каскадное включение прерываний хранится первым). Каждый импульс инициирует прерывания таймера (номер $8), и конкретно это прерывание наращивает показания счётчика. Так как это прерывание аппаратное, оно производится всегда, если только разрешены аппаратные прерывания.

Прерывания таймера принято использовать для организации работы программки в режиме реального времени – для этого требуется написать собственный обработчик прерываний таймера, осуществив его каскадное включение Каскадное включение прерываний (см. общую теоретическую часть к лабораторным работам по теме «Прерывания»). При всем этом комфортно использовать свой особый счётчик, который подсчитывает количество поступивших прерываний (импульсов) таймера. По достижении этим счётчиком неких данных значений можно делать нужные деяния (включать/выключать звуковой сигнал, поменять частоту звука, производить задержку неких операций, запускать Каскадное включение прерываний либо приостанавливать какие-то программки и т.п.).

Таким макаром, в своем обработчике прерываний таймера довольно только изменять значение счётчика импульсов и инспектировать, достигнуло ли оно требуемой величины. Естественно, после выполнения всех нужных действий следует передать управление стандартному обработчику прерываний таймера.

К примеру, если нужно, чтоб некое действие производилось в Каскадное включение прерываний течение 10 секунд, перед его началом следует установить счётчик прерываний в 0, и при каждом импульсе наращивать значение счётчика. Когда счётчик достигнет величины 182, выполнение деяния закончить. Таким макаром можно держать под контролем продолжительность требуемого деяния с точностью до 1-го импульса таймера (1/18,2 толика секунды).

Категорически запрещено в процедуре – обработчике прерываний таймера использовать Каскадное включение прерываний стандартную функцию задержки (delay)!

Задание для выполнения лаб. работы №2

Написать резидентную программку, которая будет работать, как «будильник» – через данный интервал времени издавать маленький звуковой сигнал – «тикать» (к примеру, через 1–2 секунды). По окончании более долгого интервала времени (от нескольких секунд до нескольких минут либо часов) должен раздаваться более Каскадное включение прерываний длительный мелодичный звуковой сигнал, имитирующий звонок будильника.

Продолжительность звукового сигнала – «тиканья» – не должна быть очень большой. Её следует задавать в программке в границах от 1/10 до ½ толики секунды.

По окончании «звонка будильника» «тиканье» должно длиться. «Звонок» должен раздаваться только один раз.

В то время, когда звучит «звонок», не Каскадное включение прерываний должно быть слышно «тиканья» (звонок может продолжаться в течение нескольких секунд, и в этот интервал времени на теоретическом уровне могут попасть звуки «тиканья»).

Для получения эффекта «мелодичного звонка» следует использовать несколько звуковых частот с различной длительностью звучания каждой из их.

Временной интервал, через который должно происходить «тиканье» (в секундах Каскадное включение прерываний – целое число секунд), задавать с клавиатуры в качестве параметра; время, через которое должен прозвонить будильник (в минутках – их число может быть дробным), тоже задавать в качестве параметра. Отсчёт времени для «звонка» вести с момента пуска программки.

Контрольные вопросы

1. Как будет вести себя Ваша программка, если в качестве характеристик командной строчки Каскадное включение прерываний неверно ввести знаки заместо чисел? Либо отрицательное число? Либо в случае неправильного количества характеристик – к примеру, если он будет всего один, либо, напротив, их окажется большее количество, чем необходимо?

2. Может быть ли задавать время длительности звонка с точностью до полуминуты?

3. Какие конфигурации будет нужно сделать в программке, чтоб сделать «звонок Каскадное включение прерываний будильника» звучащим неоднократно, всякий раз опять через таковой же интервал времени, который был задан сначала?

4. Каким образом можно изменять продолжительность звукового сигнала (к примеру, «тиканья») в обработчике прерываний таймера? Какой параметр программки отвечает за длительность сигнала?

5. Добавьте 3-ий параметр для задания длительности «звонка» с клавиатуры.

Лабораторная работа №3: Работа с Каскадное включение прерываний экраном («часы»)

Теоретический материал

Для организации прекрасного интерфейса меж юзером и программкой время от времени требуется поменять форму курсора (сделать его утолщенным, величиной в целый знак либо вообщем невидимым). Каждый знак растрового шрифта, каким является системный шрифт текстового режима, изображается в границах матрицы 8*8. Курсор, так же, как и знаки, изображается Каскадное включение прерываний одной либо несколькими строчками матрицы шрифта. Полосы сканирования нумеруются сверху вниз, начиная с 0. Тогда курсор для шрифта 8*8 может иметь восемь разных форм:

невидимый курсор стандартный курсор полный курсор формы курсора промежной толщины

Рис. 2. Формы курсора
Установка формы курсора производится при помощи предопределенного типа Registers, дающего доступ к регистрам Каскадное включение прерываний микропроцессора, и стандартной процедуры вызова программных прерываний Intr из модуля Dos. Для установки формы курсора требуется в регистр AH занести код функции $01 прерывания $10, в регистр CH занести номер исходной полосы сканирования, а в регистр CL – номер конечной полосы сканирования и вызвать прерывание $10 при помощи процедуры Intr.

Таким макаром, процедура задания размера курсора Каскадное включение прерываний может иметь вид:

Procedure SetCurSize(BegLine, EndLine: Byte);

Var Regs:Registers;

Begin

With Regs Do

Begin

AH:=$01; CH:=BegLine; CL:=EndLine;

End;

Intr($10,Regs);

End;

Если необходимо сделать курсор невидимым, в качестве исходной полосы следует задать значение $20 (значение конечной полосы можно задавать $00). Для курсора стандартного размера значения исходной и конечной линий должны Каскадное включение прерываний быть равны $06 и $07 соответственно: вызов SetCurSize($06, $07).

Задание для выполнения лаб. работы №3

Написать программку «часы», которая будет однократно перехватывать показания системных часов и от их вести отсчет времени, используя свой счетчик прерываний таймера (в качестве базы может быть применен обработчик прерываний таймера из предшествующей работы). Показания времени – часы, минутки, секунды Каскадное включение прерываний – следует выводить в данном месте экрана. Формат вывода: xx:xx:xx. Обновление показаний времени делать дискретно, через данное количество секунд.

Программка должна работать резидентно. При обновлении показаний времени курсор не должен быть виден, не считая того, вывод показаний времени не должен нарушать обычной работы юзера.

Часы должны работать Каскадное включение прерываний точно! Для обеспечения этого, во-1-х, нужно держать в голове о том, что количество импульсов (либо «тиков») таймера за секунду – число дробное. Как следует, на одной секунде может появляться некая погрешность, которую может быть убрать на 5 секундах (когда пройдет целое количество импульсов). Во-2-х, нужно учесть, что Каскадное включение прерываний малая величина, отраженная в показаниях часов – это секунды. Но программка может быть запущена сначала секунды (прошел 1 импульс) либо же в конце (прошло 18 импульсов). Если начинать отсчет «тиков» таймера с нуля, может появиться погрешность величиной практически за секунду. Как следует, при установке исходного значения счетчика импульсов таймера нужно учесть ещё и толики Каскадное включение прерываний секунды (один из характеристик стандартной процедуры GetTime), переведя их в соответственное количество импульсов.

Величину дискрета, также координаты местоположения часов на дисплее задавать с клавиатуры в качестве характеристик командной строчки (т.е. программка обязана иметь три параметра) при запуске программки.

Контрольные вопросы

1. Как будет вести себя Ваша программка, если в Каскадное включение прерываний качестве характеристик командной строчки неверно ввести знаки заместо чисел? Либо отрицательные числа?

2. Каковой предельный спектр конфигурации координат часов на дисплее? Как поведёт себя Ваша программка, если задать значение х = 78? y=25?

3. Как ведёт себя курсор при работе данной программки?

4. Верно ли работают Ваши часы? Для проверки правильности их работы Каскадное включение прерываний запустите программку пару раз (2–3 раза), размещая при всем этом часы в примыкающих строчках экрана:

а) С интервалом меж пусками в пару минут, величину дискрета при всем этом оставляя неизменной. Совпадают ли показания часов?

б) С различной величиной дискрета. Совпадают ли показания часов (в определенные моменты)?

Если есть погрешности, откорректируйте программку для Каскадное включение прерываний их устранения.

Лабораторная работа №4:
Эмуляция работы параллельных процессов на примере
схемы «производитель–потребитель»

Теоретический материал

В мультипрограммных вычислительных системах осуществляется параллельная работа нескольких программных приложений. Этот параллелизм может быть физическим, когда происходит одновременная работа нескольких физических устройств, либо логическим, когда осуществляется псевдопараллельное выполнение приложений за счет резвого переключения микропроцессора с Каскадное включение прерываний 1-го приложения на другое.

Логический параллелизм реализуется методом использования режима квантования, когда каждой из выполняющихся задач выделяется некий (маленькой) квант процессорного времени. Обычно величина этого кванта составляется несколько 10-ов миллисекунд. При всем этом для наружного наблюдающего создается полная видимость одновременности работы выполняющихся задач.

Логический параллелизм может быть организован средствами операционной Каскадное включение прерываний системы либо же самим программером средством использования обработчика прерываний таймера.

При реализации мультипрограммной работы средствами ОС прерывание работы текущего потока сопровождается сохранением его контекста для следующего корректного возврата в прерванную программку (см. в лекциях раздел 1.5 «Прерывания»). В случае искусственной организации программером параллельного режима работы потоков прерывание потока, обычно, осуществляется Каскадное включение прерываний в заблаговременно определенных местах. Потому для корректного продолжения работы при следующем получении управления может быть использовать глобальные переменные, а управление переключениями производить с помощью таймера.

Одной из традиционных схем теории ОС является схема «производитель-потребитель». Каждый процесс в вычислительной системе может быть охарактеризован числом и типом ресурсов, которые он Каскадное включение прерываний употребляет (потребляет) и высвобождает (производит). Независимо от определенного типа ресурсов для описания поведения таких процессов употребляется схема «производитель-потребитель». Процесс-производитель производит информацию и потом добавляет ее в буферную память; наряду с этим процесс-потребитель конфискует информацию из буферной памяти и потом обрабатывает ее. К примеру, потребителем может являться Каскадное включение прерываний процесс вывода, удаляющий запись асинхронно из буферной памяти и печатающий ее, а производителем – процесс, выполняющий некоторые вычисления и помещающий результаты в буферную память.

Задание для выполнения лаб. работы №4

Написать программку, которая будет эмулировать параллельную работу неких потоков. Потоки должны работать циклически. В качестве модели использовать схему «производитель Каскадное включение прерываний – потребитель». Один поток (производитель) может помещать случайные (либо какие-то определенные – к примеру, только четные числа либо квадраты целых чисел и т.п.) числа в буфер (массив данного размера), для наглядности поток-производитель должен эти числа выводить на экран. Другой поток (потребитель) конфискует числа из этого буфера. Для Каскадное включение прерываний контроля также делать вывод на экран чисел, взятых потоком-потребителем из буфера. Вывод различными потоками делать в различные строчки и/либо различным цветом; дополнительно выводить на экран индикатор того, какой конкретно поток работает в реальный момент, также содержимое буфера и текущий процент его заполненности.

На дисплее параллельная работа потоков может быть представлена Каскадное включение прерываний последующим образом:

Верхняя строчка (производитель): ячейка для вывода текущего сгенерированного числа, признак активности потока (слово, знак, цвет), сообщение о переполнении буфера в случае этого действия. Может быть, ещё какая-то нужная информация, к примеру, номер заполняемой ячейки.

Нижняя (либо 2-ая) строчка (потребитель): ячейка для вывода текущего Каскадное включение прерываний прочитанного числа, признак активности потока (слово, знак, цвет), сообщение о пустом буфере в случае этого действия. Может быть, информация о номере считываемой из буфера ячейки.

Посреди экрана: сам буфер, в который числа добавляются потоком-производителем и из которого считываются (удаляются либо перекрашиваются, попадая при всем этом в его ячейку в нижней Каскадное включение прерываний строке экрана) потоком-потребителем. Считывание чисел можно создавать по принципу стека либо очереди. При считывании по принципу очереди после окончания работы потребителя какое-то количество чисел из начала буфера пропадет, как следует, буфер будет передвигаться по экрану и в некий момент его будет нужно переписать поновой, от начала.

Отдельной строчкой Каскадное включение прерываний либо в углу экрана показывать процент заполненности буфера.

Предугадать обработку критичных ситуаций:

1) Случай, когда потребителю предоставлено управление, а буфер данных пуст – тогда активный поток должен впрямую дать управление производителю, а сам уйти в режим ожидания. При всем этом вопрос с квантом времени для производителя может быть решён по Каскадное включение прерываний-разному. К примеру, остаток недоработанного потребителем кванта может быть передан производителю, или ему может быть выделен новый квант времени.

2) Случай, когда управление предоставлено производителю, а буфер полон и записывать результаты некуда – поток-производитель должен заблокироваться до возникновения свободного места в буфере и запустить поток-потребитель. Вопрос с квантом может Каскадное включение прерываний решаться аналогично.

Для того чтоб было может быть пронаблюдать работу потоков в замедленном режиме, в каждом из потоков следует поставить дополнительную задержку (стандартный delay), величину которой задавать с клавиатуры при запуске программки, в качестве параметра командной строчки. При запуске без характеристик выводить сообщение примерного вида: «Программа запущена Каскадное включение прерываний со стандартной задержкой, величина которой =…» и формат пуска программки для задания хотимой задержки.

Потоки при работе чередуются случайным образом; регламентировать их работу при помощи таймера (выделять каждому кванты времени, величина которых тоже случайна – в неком спектре). При всем этом может складываться ситуация, что один и тот же поток пару Каскадное включение прерываний раз попорядку получит управление. Таймер по окончании выделенного сгустку кванта времени изменяет статус этого потока с активного на пассивный, в итоге чего внутренний цикл этого потока должен закончиться.

Снутри обработчика прерываний таймера не может находиться вызовов процедур – потоков! Вызовы процедур должны происходить в нескончаемом цикле в основной программке. В обработчик Каскадное включение прерываний прерываний таймера вообщем нельзя включать никакие деяния, требующие долгого выполнения, к примеру, вызовы повторяющихся процедур, либо процедур, работающих с графикой либо с диском.

Для выхода из программки предугадать какую-то специальную кнопку либо комбинацию кнопок (выбор по желанию программера), информация о ней должна быть известна юзеру – помещена на дисплее Каскадное включение прерываний. При нажатии этой кнопки происходит окончание работы потока-производителя, а поток-потребитель окончит свою работу, только когда буфер будет исчерпан, т.е. выработанная информация будет на сто процентов применена.

Контрольные вопросы

1. Как поведет себя программка, если первым будет выбираться на выполнение поток-потребитель?

2. Каким образом можно сделать ценность тому либо другому Каскадное включение прерываний сгустку? Используя только датчик случайных чисел? Добавьте возможность задания приоритета в форме параметра командной строчки.

3. Может быть ли добавление в ту же программку новых потоков? Измените программку таким макаром, чтоб можно было при ее запуске указывать требуемое количество потоков. При всем этом функции каждого потока определяются случайным Каскадное включение прерываний образом. Т.е. может получиться несколько потребителей и один производитель, либо напротив… В последней ситуации – все производители либо все потребители. Как поведёт себя программка в схожем случае?

Лабораторная работа №5:
Работа с видеопамятью ("экран")

Теоретический материал

При работе с экраном часто появляются ситуации, когда нужно воззвание к видеопамяти впрямую по абсолютным адресам. Структура видеопамяти Каскадное включение прерываний для текстовых режимов довольно ординарна. Для представления каждого знакоместа отводится два б: 1-ый б хранит отображаемый знак, 2-ой б – его цветовые атрибуты. Таким макаром, в текстовом режиме для хранения вида всего экрана употребляется 80´25´2 = 4000 б. Адресок начала видеопамяти в общем пространстве оперативки компьютера равен $B800:$0000 для Каскадное включение прерываний всех текстовых режимов (не считая режима Mono). Простой метод получить доступ к видеопамяти:

var video : array[1..4000] of byte absolute $B800:$0000;

Но существенно удобнее и нагляднее использовать более адекватное отражение в программке структуры видеопамяти. Так, информацию лучше представить в виде структуры с 2-мя полями, а заместо одномерного массива использовать Каскадное включение прерываний двумерный:

type video = array[1..25,1..80] of

Record

symbol : char;

attr : byte;

end;

var memory: video absolute $B800:$0000;

Наличие в программке схожих описаний сводит все операции вывода на экран к записи значений в массив memory. Так же просто может осуществляться анализ текущего состояния экрана средством считывания значений из массива memory.

Заметим, что показанные деяния никак не Каскадное включение прерываний оказывают влияние на положение курсора, в то время как процедуры write и writeln приводят к его перемещению. Не считая того, воззвание к видеопамяти позволяет решить делему, связанную с записью знака в позицию с координатами 80,25. Выполнение последующего куска программки:

GotoXY(80,25);

Write('a');

всегда приводит к сдвигу экрана Каскадное включение прерываний на одну строчку ввысь и следующей установке курсора в позицию 1,25, что исказит уже построенную на дисплее картину. Если же заместо приведенного куска использовать оператор memory[25][80].symbol:='a'; то никакого сдвига экрана не произойдет и положение курсора не поменяется.

Задание для выполнения лаб. работы №5

Написать программку, которая будет работать с видеопамятью Каскадное включение прерываний. Можно выполнить хоть какое из приведенных ниже заданий. Независимо от определенного задания программка должна работать резидентно. Текст, присутствовавший на дисплее до пуска программки, не должен портиться никаким образом.

В программке следует использовать два обработчика прерываний – прерываний таймера и прерываний клавиатуры. Прерывания таймера регламентируют скорость перемещения объекта, при этом параметр, характеризующий величину Каскадное включение прерываний скорости, нужно задавать с клавиатуры при запуске программки. Информация о параметре, задающем скорость движения, должна выводиться на экран при запуске программки без характеристик.

В случае смещения строк на дисплее (нажатие кнопки ENTER) не должно происходить никаких ненужных эффектов – раздвоения рисунки, дублирования строк либо их частей…

Вариант 5(1)«Свободное движение»:

Темный Каскадное включение прерываний (либо цветной) квадратик (либо другой объект) «летает» по экрану, содержащему некий текст, и отражается от границ экрана. Движение длится до нажатия кнопки либо некой необычной композиции кнопок.

Вариант 5(2)«Управляемое движение»:

Перемещение управляемого темного (либо цветного) квадратика (либо другого объекта) по экрану, содержащему некий текст. Управление объектом следует Каскадное включение прерываний производить при помощи клавиш-стрелок в купе с , либо , обрабатывать их нажатие при помощи прерываний клавиатуры. Однократное нажатие управляющей композиции кнопок меняет направление движения объекта, а скорость его движения определяется таймером. Объект должен передвигаться циклически – «уйдя» за правую границу экрана, должен показаться слева, и т.д.

Вариант 5(3)«Бегущая строка»:

По Каскадное включение прерываний экрану, содержащему некую информацию, «бежит» текстовая строчка. Положение строчки и её текст следует задавать параметрами. Строчка «бежит» справа влево, при всем этом по мере того, как 1-ые знаки строчки скрываются за границей экрана, они должны появляться из-за его правой границы (т.е. экран вроде бы замкнут).

Контрольные Каскадное включение прерываний вопросы

1. Какова структура видеопамяти в текстовом режиме?

2. Как комфортно организовать воззвание к хоть какой точке экрана?

3. Каким образом можно поменять цвет выводимого знака? Цвет фона?

4. Какие деяния нужно сделать для восстановления прежнего состояния экрана после каких-либо его конфигураций?


kartochka-opredelitel-rabot.html
kartochka-polzovatelya-vremennih.html
kartochka-ucheta-sudejskoj-deyatelnosti-sportivnogo-sudi.html