Goto... Search.. Hext Change.. Follou Previous 9 глава




old_4a hour db min db sec data stk
dd 0 0,0,':' 0,0,':' 0,0
db ends segment stack dw 128 dup(') ends end main
stk

;Ячейка для исходного вектора;Поле для формирования;строки ASCII с текущим;временем


В примере 3-9 используются несколько команд, отсутствующих в МП 86: команды сохранения в стеке и восстановления всех регистров общего назначения pusha и рора, а также команда сдвига shl с числовым операн­дом. Для того, чтобы эти команды распознавались ассемблером, в про-


Команды и алгоритмы___________________________________________________ 145

грамму включена директива.586 (можно было бы обойтись и директивой.386). В этом случае необходимо оба сегмента объявить с описателем use!6.

Программа состоит из главной процедуры main, процедуры new_4a обработчика прерываний от будильника, а также трех вспомогательных процедур-подпрограмм addjime, add_unit и conv. Главная процедура со­храняет исходный вектор прерывания 4Ah, устанавливает новый обра­ботчик этого прерывания, читает текущее время и устанавливает будиль­ник на время, отстоящее от текущего на 1 секунду, а затем останавлива­ется в ожидании нажатия любой клавиши. Пока программа стоит, обрабатываются прерывания от будильника и в правый верхний угол эк­рана каждую секунду выводится текущее время. После нажатия любой клавиши программа завершается, предварительно сбросив будильник и восстановив исходное содержимое вектора 4Ali.

Легко видеть, что в предложенном варианте программа имеет мало практического смысла, так как она не выполняет, кроме вывода време­ни, никакой полезной работы. В то же время, пока эта программа не за­вершилась, запустить другую программу нельзя, так как DOS является однозадачной системой. Если, однако, написать нашу программу в фор­мате.СОМ и сделать ее резидентной, мы получим возможность запускать любые программы и одновременно наблюдать на экране текущее время. Такого средства в DOS нет, и в какой-то ситуации оно может оказаться полезным. Методика разработки резидентных программ описана выше; читатель может выполнить необходимые преобразования самостоятельно.

Рассмотрим теперь программу обработчика прерываний будильника. Прежде всего в нем командой pusha (push all, сохранить все) сохраняются все регистры общего назначения и, кроме того, два сегментных регистра DS и ES, которые будут использоваться в обработчике. Далее регистр DS настраивается на сегментный адрес того сегмента, в который входит ячейка hour, т.е. фактически на наш* сегмент команд. На первый взгляд это дей­ствие может показаться бессмысленным. Ведь в начале процедуры main в регистр DS уже был помещен адрес нашего сегмента данных data. Зачем же эту операцию повторять' Дело в том, что процедура new_4a, будучи формально обработчиком программного прерывания 4Ап, фактически представляет собой обработчик аппаратного прерывания от часов реаль­ного времени, которое, как и любое аппаратное прерывание, может придти в любой момент времени. В принципе прерываемая программа в этот мо­мент может выполнять любые действия, и содержимое регистра DS мо­жет быть любым. Если же говорить о нашей программе, то она находится в цикле ожидания нажатия клавиши. Этот цикл организует функция ОШ DOS, которая, между прочим, время от времени обращается к своему Драйверу клавиатуры, а тот — к программам BIOS ввода символа с клави­атуры. Вполне вероятно (а на самом деле так оно и есть), что при выпол­нении упомянутых операций используется регистр DS, который в этом случае указывает уже не наш сегмент данных, а не различные системные области. Другими словами, при входе в обработчик прерывания содержи­мое регистра DS неизвестно, и его следует инициализировать заново, обязательно сохранив исходное значение. Если перед выходом из обра-



Глава '3


ботчика это исходное значение не восстановить, будет неминуемо разрух шсна DOS.

Сохранив регистры и настроив DS, мы вызываем функцию 02h пре­рывания 1АИ чтения текущего времени. Время возвращается, как уже го­ворилось, в упакованном двоично-десятичном формате (по две цифры в байте) в регистрах СН (часы), CL (минуты) и DH (секунды). Нам это время понадобится еще раз в конце обработчика для установки будильни­ка заново, и чтобы второй раз не вызывать функцию 02h, полученное время (т.е. содержимое регистров СХ и DX) сохраняется в стеке.

Далее выполняется последовательное преобразование BCD-цифр, состашотощих время, в коды ASCII соответствующих символов. Число часов (две упакованные BCD-цифры) переносится в регистр AL, и вызывается подпрограмма conv, которая преобразует старшую цифру часов в код ASCII и возвращает его в регистре АН. Этот код помещается в объявленную в сегменте данных строку-шаблон hour, в которой заготовлены пустые пока места для символов цифр, составляющих время, а также имеются разде­лительные двоеточия. Для удобства обращения к элементам этой строки, она разделена на части и каждая часть снабжена собственным именем — min для поля минут и sec для поля секунд.

Подпрограмма conv преобразования BCD-цифры в код ASCII состоит всего из трех предложений, не считая заключительной команды rcl. Двух-разрядиос BCD-число перелается в подпрограмму в регистре AL. После об­нуления регистра АН, который будет служить приемником для образова­ния конечного результата, содержимое AL сдвигается командой shl влево на 4 бит, в результате чего старший полубайт регистра AL, т.е. старшая цифра числа, перемещается в регистр АН (рис. 3.10). Двоично-десятичная цифра представляет собой просто двоичное представление цифры; прибав­ление к се коду кода символа "О" (числа ЗОИ) дает код ASCII этой цифры. Мы преобразовали пока только старший полубайт регистра СН. Для выделения младшего полубайта на регистр СН накладывается маска OFh,


АН


AL

| 0101 | 0111 PerHcip.AX до сдвига
5 7 =57 (BCD)


 


АН


AL


 


    0111 |

Регистр.АХ после сдвига


 


ООП 0000


Прибавление '0'= 30h


АН

ООП I 0101 I Регистр АН после прибавления 'О'
3 5 35h = код ASCII
цифры 5

Рис. ЗЛО. Алгоритм работы подпрограммы conv.


Командной алгоритмы___________________________________________________ 147

которая обнуляет старший полубайт, не затрагивая младшего. Прибавле­ние кода ASCII нуля к коду десятичной цифры образует код' ASCII этой цифры, который и переносится затем в строку-шаблон. Описанная про­цедура повторяется затем для регистров CL (минуты) и DH (секунды).

Для вывода строки с временем на экран используется прямое обра­щение в видеопамяти. В регистр ES заносится сегментный адрес видеобу­фера BSOOh, а в регистр DI — требуемое смещение видеопамяти к тому месту, начиная с которого мы хотим вывести строку. В регистр SI заносит­ся адрес строки-источника, в регистр СХ — число шагов, а в регистр АН — выбранный нами атрибут символов (красные символы по синему полю). Поскольку перемещение и по строке-шаблону, и по экрану должно осу­ществляться вперед, командой eld сбрасывается флаг DF. Наконец, цик­лическое выполнение пары команд

lodsb stosw

приводит к выводу в заданное место экрана всей строки hour.

Выполнив вывод на экран текущего времени, надо снова установить будильник. Для этого сначала запрещается работа ранее установленного будильника, восстанавливается текущее время в регистрах DX и СХ, и вызовом процедуры add_time к текущему времени прибавляется 1 секунда. Далее вызовом функции 06h заново устанавливается будильник, восста­навливаются сохраненные в начале программы обработчика регистры, и, наконец, командой irct обработчик завершает свою работу.

Рассмотрим теперь процедуру прибавления 1 к текущему времени. Она состоит из двух компонентов — подпрограммы add_time, которая органи­зует правильное сложение чисел, обозначающих время, чтобы прибавле­ние I секунды к 59 секундам дало 0 секунд и увеличило на 1 число минут {и то же самое для минут) и подпрограммы add_unit, выполняющей при­бавление 1 к упакованному коду BCD.

Подпрограмма add_time переносит число секунд из DH в AL, с помо­щью подпрограммы add_unit увеличивает его на 1 и возвращает в DH. Подпрограмма add_unit сигнализирует установкой флага CF о необходи­мости переноса 1 в следующий разряд времени (число секунд составляло 59). Поэтому после возврата из add_init проверяется флаг CF и, если он сброшен, т.е. следующий разряд времени модифицировать не надо, под­программа addjime завершается. Если же флаг CF устаноатсн, выполня­ется аналогичная процедура прибавления 1 к числу минут, которое нахо­дится в регистре CL. Дачсе опять анализируется флаг CF, и если он уста­новлен (текущее время было 59 мин 59 с), прибавляется 1 к числу часов. Наконец, подпрограмма завершается командой ret.

Подпрограмма add_uuU получаст упакованное двоично-десятичное число, к которому надо прибавить 1, в регистре AL. Командой add к нему Прибавляется 1, после чего в некоторых случаях образуется правильная сумма, а в некоторых — неправильная. Так, I4h + 1 = I5h, что правильно, однако 19h + 1 = IAh, что неверно. Такого двоично-десятичного числа не существует, а после прибавления 1 к 19 должно получиться 20 (и записа-


148_______________________________________________________ Глава 3

но в виде 20h). Коррекцию после сложения BCD-чисел осуществляет ко­манда daa, которая в приведенном примере преобразует lAh в 20h, и которая должна всегда следовать за командой сложения.

Наши двоично-десятичные числа специфичны в том отношении, что они не могут превышать 59. Поэтому после коррекции результат сравнива­ется с 60h. Если сумма меньше 60h, флаг CF сбрасывается и выполняется команда ret. Если сумма равна 60h, регистр AL обнуляется, флаг CF уста­навливается, сигнализируя о переносе 1 в следующий разряд времени (минут или часов) и выполняется та же команда ret. Таким образом, флаг CF процессора в точке возврата из подпрограммы add_unit говорит не о начичии или отсутствии арифметического переноса, а выполняет роль флага «исключительной ситуации» — перехода времени на следующую минуту или на следующий час. Такое нестандартное использование флага CF является общеупотребительным приемом.

3.6. Программирование аппаратных средств

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

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

Режим свободного доступа используется в тех случаях, когда момент обращения к устройству целиком определяется программой. Например, регистры, управляющие работой аппаратуры, обычно доступны в любой момент времени. Программа может в любой момент прочитать содержи­мое этих регистров и определить по нему текущий режим работы устрой­ства, или, наоборот, послать в управляющие регистры требуемую после­довательность команд с целью изменения рабочего режима.


Команды и алгоритмы___________________________________________________ 149

Режим ожидания готовности необходимо использовать в тех случаях, когда после приема некоторой команды устройству требуется определен­ное время для ее выполнения. Например, в последовательный порт, через который компьютер связывается с другими компьютерами или телефон­ной сетью, нельзя посылать следующую порцию информации (байт), пока устройствами последовательного интерфейса не будет отправлена в канал связи предыдущая порция. Режимом ожидания готовности часто пользу­ются для приема информации из измерительной аппаратуры, если требу­ется обеспечить максимальную скорость ее получения.

Режим прерываний является важнейшим способом связи с относи­тельно медленным периферийным оборудованием. В этом случае устрой­ство подключается не только к линиям адресов, данных и управления системной магистрали компьютера, но и к одной из специально выделен­ных линий прерываний. В режиме прерывания устройство само решает, когда ему требуется обслуживание, и посылкой в компьютер сигнала пре­рывания оповещает об этом процессор. Типичным примером является клавиатура, посылающая сигнал прерывания каждый раз, когда пользо­ватель нажимает на ту или иную клавишу. Большая часть штатных уст­ройств компьютера — мышь, диски, таймер и др. — используют режим прерываний. Типичен этот режим также и для связи с измерительной ап­паратурой в тех случаях, когда аппаратура регистрирует относительно ред­кие события, или измерительные данные накапливаются в аппаратуре в течение заметного времени и затем пересылаются в компьютер сразу це­лой пачкой.

Как уже отмечалось в гл. 1, связь с аппаратными средствами самого компьютера, а также с подключаемыми к нему устройствами осуществ­ляется главным образом через адресное пространство ввода-вывода. Это значит, что за каждым устройством закрепляется один или, чаще, не­сколько портов, и программирование устройства осуществляется исклю­чительно с помощью команд in и ou.t (а также ins и outs, если программи-)уемое устройство может посылать данные потоком).

В простейшем случае программирование устройства сводится к вы-толнению единственной команды in в случае чтения из устройства, или out в случае записи в него. Рассмотрим, например, процедуры маскирова­ния и размаскирования аппаратных прерываний. В каждом из двух кон­троллеров прерываний, включаемых в состав компьютера, имеется ре­гистр маски (рис. 3.11). Значение 0 в бите маски разрешает прохождение сигнала прерывания, значение 1 запрещает. Пройдя через маску и через последующие узлы контроллера прерываний (не показанные на рис. 3.11), сигнал прерываний поступает на вход INT микропроцессора. Программи­рование регистров маски осуществляется через порт 21h для ведущего контроллера и Alh для ведомого.

Исходное значение маски устанавливается программами начальной загрузки компьютера в зависимости от конфигурации вычислительной системы. Типичным является значение A8h, показанное на рис. 3.11. При этом значении маски размаскированными оказываются системный тай­мер, клавиатура, мышь, подключенная к первому последовательному порту



Глава з


 



Ah

Таймер. IRQO

Клавиатура. IRQ1

Выход ведомого. IRQ2

Последовательный порт COM2. IRQ3

Последовательны и портСОХП, IRQ4

Параллельный порт LPT2, IRQ5

Гибкий диск, IRQ6

Паралелльный порт LPT1, IRQ7


На вход IN Т процессора


Маска ведущего контроллера

прерываний, порт 21h

Рис. 3.11. Регистр маски ведущего контроллера прерываний.

СОМ1, гибкий диск, а также выход от ведомого контроллера, подключа­емый ко входу IRQ2 ведущего. Замаскированы оба парачлельного порта (принтер, подключаемый к порту LPT1, обычно не использует прерыва­ний, а второй параллельный порт часто просто отсутствует) и второй последовательный порт, к которому ничего не подключено. Другими сло­вами, размаскировано все нужное, и замаскировано все ненужное.

В'ряде случаев возникает необходимость замаскировать прерывания от системного таймера, который является единственным постоянно актив­ным источником прерываний. Такая ситуация типична, в частности, для автоматизированных измерительных систем, в которых недопустимо пре­рывать поток данных, поступающих от измерительной установки в ком­пьютер. Любое прерывание процесса приема данных может привесит к потере части принимаемой информации и нарушению работы установки. Для запрета прерываний от таймера надо выполнить такую последова­тельность команд:

in AL,21h;Чтсние регистра маски

or AL,1;Установка I в битс О

out 21h,AL;3апись нового значения маски

Восстановление исходного состояния вычислительной системы с разре­шенными прерываниями от таймера осуществляется следующим образом:-

in AL,21h.;Чтснис регистра маски, =

and AL,OFEh;Установка 0 в битс О

out 21h,AL;3апись нового значения;маски

Другим примером использования режима свободного доступа к уст­ройству яштлстся программирование энергонезависимой КМОП-микро-схемы, включающей в себя часы реального времени, о которых уже гово­рилось в разделе 5 этой главы, а также информацию о конфигурации ком­пьютера и в некоторых случаях пароль. Общий объем КМОП-памяти составляет 64 байт (от ООп до 3Fli); доступ к байтам КМОП-памяти осу­ществляется через порты 70h и 71h,

В КМОП-микросхеме реализован способ обращения к ее отдельным ячейкам, широко используемой в микропроцессорной технике. Если про-


манды и алгоритмы



траммировать КМОП-память прямым образом, для обращения к ее 64 ячейкам в адресном пространстве ввода-вывода пришлось бы выделить 64 адреса. Для сокращения числа используемых адресов в состав микросхемы введены два служебных регистра — адресный и данных. В адресный регистр (порт 70h) заносится номер той ячейки КМОП-памяти, к которой требу­ется обращение. После этого чтение регистра данных (порт 71h) позволя­ет прочитать содержимое выбранной ячейки, а запись в регистр данных выполняет передачу данного в эту ячейку. Приведем полный текст про­граммы, которая читает содержимое ячейки с номером ODh. В ней хранит­ся состояние батареи, питающей КМОП-микросхему. Если бит 7 этой ячейки установлен, батарея исправна; если этот бит сброшен, напряже­ние батареи упало ниже допустимого предела,.и ее надо менять.


ячейки КМОП-микросхемы cs:code ;Будем читать ячейку ODh;3адание номера ячейки;чтение из ячейки; Проверка бита 7;Бит 7=1, перейти на ОК;Бит 7 = 0, питания нет;Выведем в знак этого;Символ минус;Переход на завершение;Батарея в порядке,;выведем в знак этого;символ плюс

;Пример 3-10. Чтение code segment

assume main proc

mov AL,ODh

out 70h,AL

in AL,71h

test AL,80h

jnz ok

mov AH,02h

mov DL,'-'

int 21 h

jmp exit ok: mov AH,02h

mov DL,*+*

int 2 Hi;3авершим программу exit: mov AX,4COOh

hit 21h main endp code ends

end main

Рассмотрим теперь программирование периферийного оборудования в режиме ожидания готовности на примере параллельного интерфейса. В стандартной конфигурации компьютера к параллельному' интерфейсу обыч­но подключается принтер, однако его можно использовать и для связи с нестандартным (измерительным или управляющим) оборудованием.

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



Глава 3


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

Интерфейс Centronics подключается к периферийному устройству (прин­теру) с помощью кабеля, содержащего 17 сигнальных линий и несколько линий нуля. Управление интерфейсом осуществляется через три закреп­ленных за ним порта: порта данных с адресом 378И, порта состояния прин­тера с адресом 379h и порта управления принтером с адресом 37AU. Порты фактически предстаатяют собой 8-разрядные регистры, биты которых со­ответствуют сигнштам интерфейса. Некоторые из этих сигналов, конкрет­но, сигналы портов данных и управления, являются для интерфейса вы­ходными; их должна устанавливать программа, упрашгяющая передачей информации. Другие сигначы, наоборот, поступают из периферийного ус­тройства и отображаются в состоянии закрепленных за ними битов порта состояния; программа должна читать и анализировать эти биты.

На рис. 3.12 показаны порты интерфейса Centronics с указанием сиг­налов, соответствующим конкретным битам.

378Н Порт данных


 

 

 

 

 

 

 

 

379h Порт состояния 765432 10
  1 1 1
    |
 
 
 
 

D7...DO Байт данных

ERROR' 0-ошибка

SLCT 1 = принтер выбран

РЕ 1 = нет бумаги

АСК' 1 = готов к приему следующего символа.

если BUSY сброшен BUSY* 0 = принтер занят, 1 = свободен


37Ah Порт управлсш!я

1 1

STROBE 1 = при посылке байта

AUTO I = LF после CR

INIT 0 = отключение принтера

SLCTIN 1 = выбор принтера

IRQ 1 = разрешение прерываний

Направление передачи

для двунаправленного интерфейса

Рис. 3.12. Порты интерфейса Centronics.


Команды и алгоритмы



Программирование параллельного интерфейса требует некоторых све­дений о его протоколе, т.е. последовательности и взаимодействии сигна-юв, которыми интерфейс обменивается с подключенным к нему устрой->м. Некоторые из этих сигналов имеют узко специализированное на-шчение и возникают лишь в особых случаях (например, сигнал РЕ — >нец бумаги), другие же принимают обязательное участие в процедуре гередачи данных. К последним относятся 8 бит данных и три управляю­щих сигнала STROBE', BUSY и АСК" (рис. 3.13).


Интерфейс Г™"07 -принтер ISTROBE,

|_ Принтер занят \ обработкой байта

Принтер - I BUSY интерфейс

\__ Принтер готов

принять

следующий

байт

Рис. 3.13. Протокол передачи данных для интерфейса Centronics.

Сигнал BUSY считается активным, когда он имеет высокое значение. В противоположность этому активное состояние сигналов STROBE' и АСК' низкое, отчего они и обозначаются с тем или иным дополнительным значком (с чертой наверху, со знаком минус или с апострофом, как у нас). Прослеживая соответствие сигналов интерфейса состоянию битов его портов, необходимо иметь в виду, что для некоторых сигналов (SLCT, РЕ, STROBE) в порты записываются их прямые значения, а для других (ERROR, АСК, BUSY) — инверсные.

Вывод на принтер каждого байта данньгх состоит из трех этапов. Прежде всего программа должна дождаться неактивного состояния сигналов BUSY и АСК (это и есть ожидание готовности устройства). Убедившись, что биты 6 и 7 порта состояния 379h устаноатсны в 1 (см. рис. 3.12), програм­ма посылает в порт данных 378h байт данных, что приводит к установке кода данных на линиях интерфейса D7...DO. Наконец, программа должна установить на короткое время сигнал STROBE, что реализуется путем установки и затем сброса бита 0 порта управления 37Ali. Следующие бай­ты посылаются точно таким же образом.

Выполняя все эти операции, необходимо учитывать временные ха­рактеристики интерфейса. Сигнал STROBE можно посылать в порт уп­равления не ранее, чем через 0,5 мкс после установки данных, что может потребовать введению в программу небольшой программной задержки {одной или нескольких команд jmp, см. приведенный ниже текст про­граммы). То же относится и к длительности сигнала STROBE, которая не должна быть меньше той же величины 0,5 мкс. Практически программные задержки часто оказываются не нужны.



Глава J


Обратимся еще раз к рис. 3.13. Принтер, сняв с линий данных байт данных, и начав его обработку (вывод на печать или сохранение во внут­ренней памяти), устанавливает ответный сигнал BUSY, действующий все время, пока принтер занят обработкой байта данных. Закончив обработку байта, принтер на некоторое время устанавливает сигнал АСК и сбрасы­вает сигнал BUSY. Окончание сигнала АСК (при сброшенном состоянии сигнала BUSY) говорит интерфейсу об окончании данной операции об­мена и о возможности посылки следующего байта данных. Ввиду кратко­сти сигнала АСК часто оказывается, что ожидать его снятия нет необхо­димости; достаточно дождаться неактивного состояния сигнала BUSY (т.е. 1 в бите 7 порта состояния). Вообще следует заметить, что различные прин­теры могут несколько по-разному выполнять свою часть протокола обме­на. Рассмотренный ниже пример отлаживался на принтере Epson LQ-100.

Приведем текст программы, в которой принтер программируется, как говорят, на физическом уровне, т.е. путем обращения к его портам. Разумеет­ся, в большинстве случаев для вывода на принтер текста из выполняемой программы проще воспользоваться функциями DOS. Однако в некоторых специальных случаях приходится прибегать и к программированию через порты, например, если принтер используется в нестандартном режиме, или параллельный интерфейс служит для связи с нестандартным устройством.

;Пример 3-11. Программирование параллельного интерфейса code segment

assume cs:code


main proc  
  raov CX,10
  mov DX,379h
waitl: : in AL,DX
  and AL,OCOh
  cmp AL,OCh
  jne waitl
sym: mov AL,**'
  mov DX,378h
  out DX.AL
  mov DX,37Ah
  in AL,DX
  jmp S+2
  or AL,1
  out DX,AL
  jmp S+2
  and AL,OFEh
  out DX,AL
  loop sym

;3авершим программу


; Повторить 10 раз

;Порт состояния t

;Чтснис состояния

;Оставим только биты 7 (BUSY)

;и 6 (АСК), замаскировав бит 4 (SLCT)

;BUSY=ACK=1'

;Нст, продолжать опрос порта

;Символ для печати

;Порт данных

;Вывод символа

;Порт управления

;Читаем из порта. Лам CCh

;(SLCT IN =1, INIT=1)

;Нсбольшая задержка

Останавливаем сигнал STROBE

;Впорт

;Небольшая задержка

;Сбрасывасм сигнал STROBE

;Впорт

;Цикл


Команды и алгоритмы___________________________________________________ 155

В приведенном примере предполагается, что принтер выбран и уста­новлен в исходное рабочее состояние, что обычно выполняется автома­тически при его включении. Свидетельством этого будут установленные биты 2 и 3 (SLCT IN и INIT) в порте управления, а также бит 4 (SLCT) в порте состояния. В программе не выполняется анализ байта состояния на натачие ошибки или конца бумаги, что при работе с принтером, во­обще говоря, следует предусматривать.

Третий метод программирования периферийного устройства — режим прерываний — рассмотрим на примере обработки прерывания от мыши. Как известно, мышь обычно подключается к первому последовательному порту СОМ1 и работает в режиме прерываний. Нажатие или отпускание любой клавиши, так же, как даже минимальное перемешение по столу, вырабатывает сигналы прерываний, сопровождаемые определенными кодами, которые поступают в порт данных интерфейса. Написав собствен­ный обработчик прерываний для последовательного порта, мы получим возможность выполнять заданные действия, например, при нажатии ле­вой и правой клавиш мыши. Следует подчеркнуть, что эти действия нач­нут выполняться практически в тот же момент, когда мы нажали на кла­вишу. В приведенной ниже программе при нажатии левой клавиши в центр экрана выводится цветная надпись «Левая!», а при нажатии правой кла­виши — надпись «Правая» другого цвета.



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2016-02-16 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: