
- •140010, Г. Люберцы, Московской обл., Октябрьский пр-т, 403.
- •Глава 1. Архитектура реального режима
- •1.1. Память и процессор
- •Глава 1
- •Глава 1
- •1.2. Распределение адресного пространства
- •Глава 1
- •1.3. Регистры процессора
- •Глава 1
- •Глава 1
- •9 7H Шестнадцатернчное обозначение числа
- •Глава 1
- •1.4. Сегментная структура программ
- •Глава 1
- •Глава 1
- •Глава 1
- •1.5. Стек
- •Глава 1
- •1.6. Система прерываний
- •Глава 1
- •Глава I
- •1.7. Система ввода-вывода
- •Глава I
- •Глава 1
- •Глава 2. Основы программирования
- •2.1. Подготовка и отладка программы
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •2.2. Представление данных
- •Глава 2
- •Глава 2
- •2.3. Описание данных
- •Глава 2
- •Глава 2
- •2.4. Структуры и записи
- •Глава 2
- •Глава 2
- •2.5. Способы адресации
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •2.7. Вызовы подпрограмм
- •Глава 2
- •2.8. Макросредства ассемблера
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 3. Команды и алгоритмы
- •Глава 3
- •Глава 3
- •Глава 3
- •Глава 3
- •Глава 3
- •Глава 3
- •Глава 3
- •Глава 3
- •3.2. Циклы и условные переходы
- •Глава 3
- •Глава 3
- •3.3. Обработка строк
- •Глава 3
- •3.4. Использование подпрограмм
- •Глава 3
- •Глава 3
- •3.5. Двоично-десятичные числа
- •Глава 3
- •Глава 3
- •3.6. Программирование аппаратных средств
- •Глава 3
- •37Ah Порт управлсш!я
- •Глава 3
- •Глава 3
- •Глава 4. Расширенные возможности
- •4.1. Архитектурные особенности
- •Глава 4
- •4.2. Дополнительные режимы адресации
- •Глава 4
- •4.3. Использование средств 32-разрядных процессоров в программировании
- •Глава 4
- •Глава 4
- •Глава 4
- •4.4. Основы защищенного режима
- •Глава 4
- •Глава 4
- •Глава 4
- •Глава 4
- •Idiv Деление целых чисел со знаком
- •Imul Умножение целых чисел со знаком
- •In Ввод из порта
- •Inc Инкремент (увеличение на 1)
- •Int Программное прерывание
- •Into Прерывание по переполнению
- •Iret Возврат из прерывания
- •1 Lods Загрузка операнда из строки : lodsb Загрузка байта из строки lodsw Загрузка слова из строки
- •Операнд
- •Xadd память, регистр
- •Xchg Обмен данными между операндами
- •Xlat Табличная трансляция
- •Xor Логическое исключающее или
- •Содержание
Глава 3
Разумеется, в установке, подключаемой к компьютеру через параллельный интерфейс, должно быть предусмотрено устройство сопряжения, воспринимающее и вырабатывающее сигналы обмена с интерфейсом.
Интерфейс Centronics подключается к периферийному устройству (принтеру) с помощью кабеля, содержащего 17 сигнальных линий и несколько линий нуля. Управление интерфейсом осуществляется через три закрепленных за ним порта: порта данных с адресом 378И, порта состояния принтера с адресом 379h и порта управления принтером с адресом 37AU. Порты фактически предстаатяют собой 8-разрядные регистры, биты которых соответствуют сигнштам интерфейса. Некоторые из этих сигналов, конкретно, сигналы портов данных и управления, являются для интерфейса выходными; их должна устанавливать программа, упрашгяющая передачей информации. Другие сигначы, наоборот, поступают из периферийного устройства и отображаются в состоянии закрепленных за ними битов порта состояния; программа должна читать и анализировать эти биты.
На рис. 3.12 показаны порты интерфейса Centronics с указанием сигналов, соответствующим конкретным битам.
378Н Порт данных
76543210
379h Порт состояния 765432 10 |
||
|
1 1 1 |
|
|
|
| |
|
||
|
||
|
||
|
D7...DO Байт данных
ERROR' 0-ошибка
SLCT 1 = принтер выбран
РЕ 1 = нет бумаги
АСК' 1 = готов к приему следующего символа.
если BUSY сброшен BUSY* 0 = принтер занят, 1 = свободен
37Ah Порт управлсш!я
76543210
1 1
STROBE 1 = при посылке байта
AUTO I = LF после CR
INIT 0 = отключение принтера
SLCTIN 1 = выбор принтера
IRQ 1 = разрешение прерываний
Направление передачи
для двунаправленного интерфейса
Рис. 3.12. Порты интерфейса Centronics.
Команды и алгоритмы
153
Программирование параллельного интерфейса требует некоторых сведений о его протоколе, т.е. последовательности и взаимодействии сигна-юв, которыми интерфейс обменивается с подключенным к нему устрой->м. Некоторые из этих сигналов имеют узко специализированное на-шчение и возникают лишь в особых случаях (например, сигнал РЕ — >нец бумаги), другие же принимают обязательное участие в процедуре гередачи данных. К последним относятся 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 мкс. Практически программные задержки часто оказываются не нужны.
154
Глава 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 и работает в режиме прерываний. Нажатие или отпускание любой клавиши, так же, как даже минимальное перемешение по столу, вырабатывает сигналы прерываний, сопровождаемые определенными кодами, которые поступают в порт данных интерфейса. Написав собственный обработчик прерываний для последовательного порта, мы получим возможность выполнять заданные действия, например, при нажатии левой и правой клавиш мыши. Следует подчеркнуть, что эти действия начнут выполняться практически в тот же момент, когда мы нажали на клавишу. В приведенной ниже программе при нажатии левой клавиши в центр экрана выводится цветная надпись «Левая!», а при нажатии правой клавиши — надпись «Правая» другого цвета.
Для того, чтобы приведенная программа работала, следует загрузить драйвер мыши, который инициализирует последовательный интерфейс и саму мышь. В состав этого драйвера входит свой обработчик прерываний. Мы замещаем его адрес в векторе ОСИ адресом нашего обработчика, и поскольку в программе не предусмотрено сцепление обработчиков, на время действия программы стандартная обработка прерываний от мыши отключается. Перед завершением программы содержимое вектора ОСИ восстанавливается, и мышь опять начинает работать, как обычно.
Каждое нажатие (или отпускание) клавиши мыши, так же, как и ее перемещение, в действительности вырабатывают не по одному, а по три последовательных прерывания с рахтичными кодами в порте данных интерфейса. Так, нажатие левой клавиши мыши дает последовательность кодов 60h, 0, 0, нажатие правой клавиши — последовательность 50h, О, О, отпускание любой клавиши — 40h, 0, 0, перемещение вверх — 4Ch, О, 3Fh, перемещение вниз — 40h, О, 1 и т.д. Таким образом, по-настоящему надо было сохранять в обработчике прерываний все три кода и затем анализировать всю последовательность. Мы для простоты ограничились анализом только первого кода. Как видно из приведенного выше перечня, анализ одного кода не дает возможность отличить, например, отпускание клавиши от перемещения вниз.
Коды, генерируемые мышью, могут зависеть от ее типа, что надо учи-|*Тывать при подготовке этого примера. Для получения значений генериру-[емых кодов можно предусмотреть в-обработчике прерываний вывод их на ркран с помощью функции прерывания 10h BIOS, как это было сделано, [например, в примере 3-5, или прямым выводом в видеобуфер. Следует столько иметь в виду, что перехват любого прерывания от последователь-
156