Системное программирование

  Лекция 1

  Литература:

    1. Джордан Справочник программиста персональных компьютеров

    2. Нортон  Архитектура персональных компьютеров фирмы IBM

    3. Бэк    Введение в системное программирование

     Курс по СП включает: лекции - 34 часа;

                          лабораторные работы - 32 часа;

                          курсовую работу;

                          зачет и экзамен.

                                Основные понятия

     Курс лекций состоит из двух разделов:  прктичского и теоретическо-

го. В  практической части рассмотрим вопросы построения системных прог-

рамм, управляющих устройствами ПК.  В теор.  части  рассмотрим  вопросы

построения компиляторов, трансляторов, ОС, СУБД и т.д.

     К СП относится та область программирования,  которая связана с уп-

равлением техническими  средствами ПК и организацией работы программных

систем. Отличие СП от прикладного- это  машинная  зависимость  первого,

так как  системные  программы тесно связаны с архитектурой и структурой

компьютера, для которого они созданы.  Например, АССЕМБЛЕР при переводе

команд в машинные коды должен учитывать способы адресации,  форматы ко-

манд, длину регистров и другие аппаратные характеристики конкретной ма-

шины. Компиляторы также учитывают характеристики аппаратуры при генера-

ции кодов. ОС непосредственно управляют всеми ресурсами компьютера.

     К задачам СП относятся разработка:

     1. систем ассемблирования;

     2. загрузчиков и программ связывания;

     3. макропроцессоров;

     4. Компиляторов;

     5. операционных систем;

     6. драйверов.

     Система ассемблирования переводит исходный файл с командами в заг-

рузочный. Загрузчик записывает объектную программу в оперативную память

и передает управление на адрес начала ее исполнения -  это  абс.  загр.

Загрузчик обеспечивающий  перемещение  программы в любую область памяти

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

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

загружаются (это обычно подпрограммы).  Макропроцессоры позволяют часто

повторяющиеся группы  заменять одной макроинструкцией.  ОС осуществляет

интерфейс с пользователем. Драйверы управляют работой переферийных уст-

ройств.

     АРХИТЕКТУРА ТЕХНИЧЕСКИХ СРЕДСТВ ПЕРСОНАЛЬНЫХ КОМПЬЮТЕРОВ

                    1. Общее описание

       Центром вычислительной системы является ее процессор.  Именно он

  выполняет команды,  составляющие компьютерную программу. Микропроцес-

  сор, использованный в IBM/PC, был разработан и создан фирмой "Интел".

       В IBM/PC используется микропроцессор 8088,  80286,  80386, 80486

  фирмы "Интел", Лишь немногие компоненты IBM/PC были специально разра-

  ботаны для нее,  - большая часть системы  составлена  из  стандартных

  компонентов. Особенность персонального компьютера фирмы "IBM" состоит

  в оригинальном способе организации  известных  компонентов  в  единую

  функционирующую систему.

       Составляющие IBM/PC можно рассматривать с трех  различных  точек

  зрения: по тому где они размещаются, как они функционируют, и как они

                                     - 2 -

  взаимодействуют друг с другом.  Рассмотрим  вопрос  пространственного

  размещения этих составляющих.

       Физически составляющие IBM/PC можно разделить на компоненты сис-

  темного блока и компоненты блока расширения. Все основные платы, вхо-

  дящие в состав любой модели IBM/PC,  размещаются в большом блоке, по-

  лучившем название системного. Системный блок включает все необходимые

  компоненты,  позволяющие компьютеру работать без каких-либо  дополне-

  ний. Здесь находятся микропроцессор, первые 64К памяти и "встроенные"

  программы, такие как интерпретатор языка Бейсик, записанный в микрос-

  хемах ПЗУ.

       Системный блок расположен в основании IBM/PC и заключен  в  кор-

  пус.  Системный  блок имеет пять свободных разъемов,  предназначенных

  для подключения дополнительного оборудования, которое может быть вве-

  дено в состав компьютера. Блоки расширения вставляются в эти разъемы,

  располагаясь над системным блоком.

       Блоки расширения  или карты,  как их иногда называют - могут ис-

  пользоваться для обслуживания устройств,  подключаемых к IBM/PC.  Они

  могут  использоваться для двух основных целей:  для увеличения объема

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

       Системный блок разработан фирмой "IBM", а блоки расширения могут

  разрабатывать все желающие,  при условии что они будут соблюдать  ос-

  новные правила,  касающиеся размеров, электрических параметров соеди-

  нений, теплового режима и так далее.

       Любые дополнительные  устройства подключаются к IBM/PC с помощью

  одного из разъемов расширения,  каждый из которых имеет  62  соедини-

  тельных провода. Эти 62 линии позволяют передавать все сигналы, необ-

  ходимые для управления любым оборудованием,  которое может быть подк-

  лючено к IBM/PC.  Все линии работают параллельно,  так что устройства

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

  одному из блоков расширения,  передается и всем остальным,  поскольку

  они подключены к параллельным линиям.  Здесь имеет  место  расширение

  идеи общей шины данных: все блоки расширения используют общее 62-про-

  водное соединение. называемое каналом ввода/вывода.

       По характеру  использования  все линии можно разделить на четыре

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

  блокам расширения с различными номиналами напряжений.

       Далее, еще восемь линий используется  для  передачи  восьми  бит

  данных на/с шины данных. Все данные проходят по этой шине, независимо

  от направления передачи.

       Еще двадцать линий предназначены для адресации. При работе с па-

  мятью используются все 20 линий,  это позволяет передать адрес  одной

  из 1024К ячеек памяти. Для устройств ввода/вывода используется только

  девять линий, что позволяет адресовать 512 различных устройств.

       Остальные линии  канала используются для передачи различных сиг-

  налов управления. Примерами таких сигналов могут служить команды чте-

  ния из памяти,  записи в память или команды чтения/записи для перифе-

  рийных устройств.

       Внутри корпуса IBM/PC спрятаны два набора переключателей. Их на-

  зывают переключателями конфигурации системы  (они  выполнены  в  виде

  корпуса  с двумя рядами выводов,  т.е.  корпуса типа DIP).  Установка

  этих переключателей указывает какое оборудование подключено к IBM/PC,

  например,  количество дисководов,  объем доступной памяти и т.д.  Эти

  переключатели ничем реально не управляют -  они  используются  только

  для удобства.  После включения IBM/PC программы запуска считывают по-

  ложение этих переключателей и затем устанавливают содержимоке опреде-

  ленных ячеек памяти в соответствии с их положением.  Затем,  если ка-

  кой-либо программе необходимо узнать , какой объем памяти установлен,

  проверяется содержимое этих ячеек.

    Одним из основных элементов компьютера,  позволяющим ему  нормально

                                     - 3 -

  функционировать,  является память. Внутренняя память компьютера явля-

  ется временным рабочим пространством;  в отличие от нее  внешняя  па-

  мять,  такая  как файл на дискете,  предназначена для долговременного

  хранения информации.  Информация во внутренней памяти не  сохраняется

  при выключении питания.

       Каждая ячейка памяти имеет адрес,  который используется  для  ее

  нахождения.  Поскольку адреса - это те же числа,  компьютер может ис-

  пользовать арифметические операции для вычисления адресов памяти.

       IBM/PC использует  возможности  адресации  микропроцессора  8088

  полностью. Адреса в 8088 имеют длину 20 бит, следовательно, процессор

  позволяет адресовать два в двадцатой степени байта или 1024 К.

                 2. Основные микросхемы

     Главной микросхемой является сам микропроцессор. Рядом с микропро-

цессором предусмотрено место для микросхемы 80287,  числового сопроцес-

сора,  или процессора числовых данных, с его специальными возможностями

по выполнению очень быстрых (и с повышенной точностью)  вычислений  над

числами с плавающей точкой.  Числовой сопроцессор устанавливается срав-

нительно небольшое количество РС, однако почти все члены семейства пре-

дусматривают гнездо для его установки.

     Рассмотрим микросхемы, которые предназначены для выполнения опера-

ций синхронизации в компьютере. Одна из них называется генератором так-

товых (или синхронизирующих) сигналов и используется, прежде всего, для

получения тактов, которые управляют основным рабочим циклов компьютер в

АТ номером его идентификации является 88248. В любом случае эта микрос-

хема  дает  синхронизирующий сигнал,  используемый в других компонентах

компьютера для установки основного рабочего темпа. В микросхеме генера-

тора  тактовых сигналов используется кварцевый кристалл в качестве точ-

ной основы для синхронизации. Наш генератор тактовых сигналов подразде-

ляет  сверхбыстрые такты кристалла в быстрые такты,  требующиеся компь-

ютеру,  и преобразует их в форму,  приемлемую для использования другими

компонентами схемы.

     С генератором тактовых сигналов близко связана микросхема програм-

мируемого таймера,  идентифицируемая номером 8253. Программируемый тай-

мер может порождать другие сигналы синхронизации.  Можно изменять  ско-

рость выдачи сигналов, что делает эту микросхему "программируемой". Для

осуществления регулировки этим потоком информации в компьютерах предус-

мотрен микропроцессор контроллера шины. В РС эта микросхема имеет номер

8288,  а в АТ - 82288.  Задача контроллера шины состоит  в  том,  чтобы

обеспечить нормальную работу шины.

     Некоторые компоненты компьютера (в частности, дисководы) могут об-

мениваться  данными непосредственно через кмпьютерную память,  без про-

хождения данных микропроцессора для  выполнения  другой  работы.  Такой

процесс  называется прямым доступом к памяти.  Имеется специальная мик-

росхема, предназначенная для управления этим процессом, которая называ-

ется контроллером прямого доступа к памяти (номер микросхемы - 8237).

     Прерывания контролируются специальной микросхемой (8259). В компь-

ютерах  прерывания  поступают  с различной степенью важности и одной из

задач контроллера прерываний 8259 является отслеживания  их  в  порядке

приоритетов, а также фиксация каких-либо задержанных прерываний.

     К другим основным микросхемам относится микросхема программируемо-

го  интерфейса  периферийных  устройств (номер - 8255).  Эта микросхема

следит за работой некоторых из  более  простых  периферийных  устройств

компьютера,  таких как порт кассетной ленты. Однако большинство перифе-

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

они могли регулироваться простой обычной схемой.

     К таким сложным устройствам относятся приводы гибких  дисков.  Ос-

новной микросхемой, предназначенной для управления работой компьютера с

                                     - 4 -

приводами гибких дисков,  является контроллер гибкого диска PD765.  Для

дисплея обычно используется микросхема,  называемая контроллером элект-

ронно-лучевой трубки 6845.

     3. Специальные свойства микропроцессора 286

     В реальном режиме специальные возможности и характеристики микроп-

роцессора 286 не проявляются, поэтому компьютер с микропроцессором 286,

функционирующем в реальном режиме,  может быть полностью совместимым  с

обычным РС.  Для того, чтобы воспользоваться дополнительными возможнос-

тями, следует переключиться на защищенный режим.

     В защищенном режиме микропроцессор 286 обладает рядом дополнитель-

ных возможностей, позволяющих ему наращивать количество программ, с ко-

торыми  компьютер может работать одновременно.  Это достигается за счет

четырех основных средств:  защиты (которая определяет наименование дан-

ного режима),  расширенной памяти, виртуальной памяти и мультизадачнос-

ти.

     Защита позволяет операционной системе воздвигать барьеры для защи-

ты программы от воздействия функционирования других программ или  самой

операционной  системы.  В стандартном РС ими при работе микропроцессора

286 в реальном режиме отдельная прорамма может испортить работу  опера-

ционной  системы  или какой-либо другой программы,  использующей компь-

ютер,  либо даже заблокировать весь компьютер, остановив его функциони-

рование. Защищенный режим работы микропроцессора 286 позволяет операци-

онной системе предотвращать порчу компьютера и  даже  порчу  какой-либо

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

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

программы и блокировка ею машины не играет столь уж большой роли. Одна-

ко, если нам нужно выполнять на компьютере одновременно несколько прог-

рамм, намного возрастает важность защиты функционирования компьютера от

некорректно работающих программ.  Средство защиты делает это возможным.

Защищенный режим работы микропроцессора 286 предоставляет больший объем

памяти,  причем это достигается двумя путями. Во-первых, за счет расши-

ренной  памяти:  микропроцессор 286 позволяет устанавливать в компьютер

до шестнадцати миллионов байтов рабочей памяти. Во-вторых, за счет вир-

туальной памяти:  микропроцессор 286 может имитировать (или иметь) даже

большее количество памяти, чем имеется в фактическом наличии. Виртуаль-

ная память позволяет компьютеру предоставлять каждой программе до одно-

го биллиона байтов (один гигабайт) для работы с ними. Это очень большой

объем памяти.

     Наконец, используя поддерживаемую аппаратными средствами мультиза-

дачность, микропроцессор 286 может быстро и надежно осуществлять перек-

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

дачность  применяется в случае,  если компьютер одновременно работает с

более чем одной программой (задачей).  Фактически, в каждый момент вре-

мени компьютер выполняет команды лишь одной программы, однако в процес-

се мультизадачной работы обрабатываться все программы - это можно срав-

нить с жонглером,  который может одновременно работать с множеством ша-

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

ности, однако такую работу он не в состоянии выполнять на должном уров-

не, не обладая определенными специальными аппаратными средствами (таки-

ми,  например, как защита памяти). Защищенный режим микропроцессора 286

предусматривает множество  средств,  которые  практически  обеспечивают

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

               4. Память и порты, регистры

     Регистры представляют собой разновидность памяти специального наз-

начения,  которую микропроцессор использует для определенных конкретных

                                     - 5 -

целей.

     ________________________________________________________________

     !  Флаги         _____________________________________         !

     !                |____________________________________|        !

     !                _____________________________________         !

     !          AX    |_______AH_______|______AL___________|        !

     !          BX    |_______BH_______|______BL___________|        !

     !          CX    |_______CH_______|______CL___________|        !

     !          DX    |_______DH_______|______DL___________|        !

     !                _____________________________________         !

     !          SP    |____________________________________|        !

     !          BP    |____________________________________|        !

     !          SI    |____________________________________|        !

     !          DI    |____________________________________|        !

     !          PC    |____________________________________|        !

     !                _____________________________________         !

     !          CS    |____________________________________|        !

     !          DS    |____________________________________|        !

     !          SS    |____________________________________|        !

     !          ES    |____________________________________|        !

     !______________________________________________________________!

     Регистрами является набор из четырнадцати 16-битовых мест, в кото-

рых можмно хранить числа. каждое из них является неотъемлемой, внутрен-

ней частью микропроцессора.

     Первая группа регистров называется универсальными регистрами, Име-

ется четыре таких регистра, которые именуются AX, BX, CX и DX. Если для

работы  требуется  применение  лишь половины емкости любого из этих ре-

гистров поскольку они делятся на половины старшего и младшего  порядка,

которые обозначаются AH и AL,  BH и BL и т.д.  В этих универсальных ре-

гистрах выполняется  значительная  часть  работы,  поступающей  в  наши

компьютеры.

     Следующая группа состоит из четырех  регистров,  используется  для

оказания  помощи  микропроцессору в отыскании пути в памяти компьютера.

Регистры из этой группы называются регистрами сегментов.  Каждый из них

используется  для  оказания  помощи  в получении доступа к разделу (или

сегменту) памяти объемом 64 К. Сегмент кода (или регистр CS) указывает,

в  каком месте памяти располагается программа.  Сегмент данных (или ре-

гистр DS) определяет местонахождение данных, используемых программой, а

дполнительный  сегмент (или регистр ES) дополняет сегмент данных.  Сег-

мент стека (или регистр SS) определяет местонахождение стека  компьюте-

ра, который вкратце будет описан. Более полное представление о примене-

нии этих регистров мы получим в главе 7,  когда  более  детально  будет

рассматриваться память.

     В то время как регистры сегментов используются для получения  дос-

тупа к большим разделам (по 64 К)памяти, последняя группа регистров ис-

пользуется для оказания помощи в отыскании пути к определенным байтам в

памяти.  Они применяются совместно с регистром сегмента для указания на

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

испольуется для конкретной цели. Указатель команды (инструкции) IP, ко-

торый называют также программным счетчиком, РС, сообщает микропроцессо-

ру только о месте,  где выполняется программа.  Указатель стека,  SР, и

указатель базы, BP, используются для оказания помощи в отслеживании вы-

полняющейя работы.  Индекс источника, SI, и индекс местоназначения (вы-

хода),  DI, используются для оказания помощи нашим программам в переме-

щении больших объемовданых из одного места в другое.

     Наконец имеется еще один регистр, называемый регистром флагов, ко-

торый  используется  для фиксации флагов состояния,  о которых шла речь

ранее.  Различные флаги сообщают нашим программам только о том, в каком

состоянии находится компьютер: результаты арифметических операций, раз-

                                     - 6 -

решены ли прерывания и другие аналогичные состояния.

     Микропроцессоры РС  в  основном управляются посредством последова-

тельности 1-битовых флагов, каждый из которых отмечает или устанавлива-

ет определенное состояние в компьютере. Флаги действуют независимо друг

от друга,  однако,  для удобства,  они собраны вместе в регистр флагов.

Отдельные  флаги могут проверяться и устанавливаться посредством специ-

альных команд, а вся группа флагов может считываться или устанавливать-

ся  посредством  пары команд,  которые считывают или устанавливают весь

регистр флагов.  Всего имеется девять стандартных флагов.  Шесть из ним

используются  для  индикации  результатов  арифметических и подобных им

операций:  флаг нуля, ZF, указывает на нулевой результат (или равенство

при сравнении),  флаг знака,  SF, указывает на отрицательный результат,

флаг переноса,  CF, означает перенос в следующую позицию, флаг дополни-

тельного  переноса,  AF,  указывает  на перенос из первых четырех битов

(что требуется для моделирования десятичных операций),  флаг перенолне-

ния,  OF,  отмечает  получение слишком большого результата и,  наконец,

флаг четности, PF, отмечает четность или нечетность результата.

     Три оставшихся  флага используются для управления.  Флаг направле-

ния,  DF, управляет направлением повторения операций (например, при по-

байтовом перемещении данных): справа налево или наоборот. Флаг прерыва-

ний, IF, контролирует возможность прерываний: разрешены они или времен-

но запрещены. Флаг захвата, TF, вызывает генерацию копьютером специаль-

ного прерывания "захвата" после выполнения одной  команды.  Это  делает

возможным  пошаговое  выполнение  программы  с трассировкой результатов

каждой отдельной команды.

     Помимо этих девяти флагов, усовершенствованный микропроцессор 286,

используемый в ветви АТ семейства РС,  допускает применение двух весьма

специальных флагов.  Один из них, называемый, NT, используется для вло-

женных задач, а другой, двухбитовый флаг IOPL, управляет уровнем приви-

легии ввода/вывода.

                                                             ┌─────────┐

                                                             │         │

                                                             │ УУПДП   │

                                                             │         │

                                                             └─────────┘

┌────────┐       ┌────────────┐        ┌──────┐        ┌──────┐

│ ЗУ     │       │ ПРОЦЕССОР  │        │СИСТ. │        │      │     ┌───────┐

│        │       │            │        │КОНТР.│        │КОНТР.│     │ПЕРЕФ. │

│        │       │            │        │В/В   │        │      │     │УСТР.  │

│        │       │            │        │      │        │      │     │       │

│        │       │            │        │      │        │      │     │       │

└────────┘       └────────────┘        └──────┘        └──────┘     └───────┘

                                                             ┌─────────┐

                                                             │СИСТЕМА  │

                                                             │ПРЕРЫВАН.│

                                                             │         │

                                                             └─────────┘

Лекция 2

                        1. Краткий обзор памяти

    Микропроцессор лучше всего работает с 16-битовыми числами,  которые

могут принимать значения,  не  превышающие  65536  или  64К.  Поскольку

компьютер  использует  числовые  адреса для отыскания своего пути через

память,  предполагается,  что память не может содержать более 64К байт.

Как показал опыт, 64К байт слишком мало для серьезных применений компь-

ютера; многие из наших компьютеров оборудованы памятью, емкость которой

в десять раз больше - 640К. Поэтому возникает вопрос: как выполнять ра-

боту,  испольуя такую большую память и продолжая  применять  16-битовые

числа ля доступа к ней?

     Решение, которое было реализовано фирмой Intel в семействе микроп-

роцессоров  8086 заключается в применении так называемых сегментирован-

ных адресов.  Сегментированные адреса составляются из  двух  16-битовых

слов,  объединяемых  таким способом,  чтобы они могли определять адреса

1048576 (или приблизительно миллион) байтов  памяти.  Для  того,  чтобы

посмотреть,  как это делается, нужно рассмотреть следующее: арифметику,

которая используется при объединении двух слов сегментированного  адре-

са,  и  способ обработки этих сегментированных адресов внутри микропро-

цессора.

     Арифметика включает так называемое "сложение со сдвигом",  которое

позволяет создавать 20-битовое двоичное число (которое может  принимать

значения до 1048578) из двух 16-битовых чисел.  Предположим,  что у нас

имеется два 16-битовых слова,  которые имеют шестнадцатеричные значения

ABCD и 1234.  Напомним,  что каждая шестнадцатеричая цифра представляет

четыре бита,  поэтому четыре шестадцатеричные  цифры  (ABCD  или  1234)

представляют 16 битов.  Возьмем одно из этих двух чисел, скажем ABCD, и

добавим 0 к его концу:  ABCD0.  Фактически это означает сдвиг числа  на

одну шестнадцатеричную позицию (или на четыре двоичные позиции) или ум-

ножение значения числа на шестнадцать.  Теперь число  состоит  из  пяти

шестнадцатеричных  цифр (или 20 битов) и принадлежит миллионному диапа-

зону.  Однако,  к сожалению,  оно не может быть использовано в качестве

полного 20-битового адреса памяти,  поскольку в конце этого числа стоит

0:  это число может представлять только адреса,  оканчивающиеся  на  0,

т.е. только каждый шестнадцатый байт.

     Для того,  чтобы завершить описание схемы сегментированной адреса-

ции,  мы возьмем другое 16-битовое число (1234 в нашем примере) и доба-

вим его к сдвинутому числу:

                                ABCD0

                              +  1234

                               -------

                                ACF04

     Когда мы объединяем два 16-битовых слова таким способом,  мы полу-

чаем 20-битовое число,  которое может принимать любое значение от 0  до

1048577.  И  это та арифметическая схема,  которая обеспечивает способ-

ность PC работать с миллионом байтов памяти,  используя 16-битовые чис-

ла.

     Две части этой схемы адресации называются частью сегмента и частью

смещения. В нашем примере ABCD есть значение сегмента, а 1234 есть зна-

чение смещения.  Часть сегмента определяет адрес  памяти,  кратный  16,

т.е.  адрес,  в последней позиции которого имеется шестнадцатеричный 0.

Адреса памяти,  которые кратны 16,  называются границами параграфов или

параграфами сегментов.

     Часть смещения сегментированного адреса определяет некоторое  точ-

ное  местоположение байта,  следующее за местоположением параграфа сег-

мента.  Поскольку 16-битовое слово смещения может варьироваться от 0 до

                                     - 2 -

65535  (или 64К),  то часть смещения сегментированного адреса позволяет

нам работать с 64К байтами памяти,  используя один и тот же адрес  сег-

мента.

     Представим стандартный способ записи сегментированных адресов, ко-

торый  вы  часто  будете встречать при изучении технических материалов,

относящихся к PC.  Сегментированный адрес обычно записывается в следую-

щем виде:  ABCD:1234.  Первым указывается адрес сегмента, затем следует

двоеточие и адрес смещения.  Если вы работаете с языком ассемблера  или

используете программу DEBUG,  то такую запись вы будете встречать очень

часто.  Если вы взглянете на листинг программы DEBUG,  представленный в

разделе  "Таблица  векторов  прерываний",  то вы увидите такую запись в

правом столбце.

     Почти всегда,  когда  мы  говорим  об адресах внутри памяти нашего

компьютера,  мы обращаемся к ним в их сегментированной форме. Но иногда

нам нужно взглянуть на них в их конечной форме, когда две части сегмен-

тированного адреса объединены;  когда это требуется сделать, я буду на-

зывать соответствующие адреса абсолютными адресами,  чтобы не возникало

путаницы. В нашем примере объединения частей ABCD и 1234 результирующим

абсолютным адресом является ACF04.

     Часть сегмента сегментированного адреса  полностью  обрабатывается

набором из четырех специальных регистров сегментов,  Каждый из этих че-

тырех регистров предназначен для локализации  параграфа  сегмента.  Ре-

гистр сегмента кода CS указывает,  где находится код программы. Регистр

сегмента данных DS определяет местоположение основных данных программы.

Регистр  дополнительного  сегмента  ES дополняет сегмент данных DS так,

что данные можно сдвигать между двумя отдельными частями памяти. И, на-

конец, регистр сегмента стека SS предоставляет информацию о базовом ад-

ресе стека компьютера.  Детальная адресация осуществляется  посредством

обработки адреса смещения. В то время как часть сегмента сегментирован-

ного адреса может использоваться только когда она загружается в один из

этих  четырех  регистров,  адреса смещения могут использоваться намного

более гибко.  Наши программы могут получать смещения адресов из различ-

ных регистров (таких как универсальные регистры AX,  BX и т.д.  или ин-

дексные регистры SI и DI). Смещения могут также указываться в фактичес-

ких командах программы на машинном языке,  либо вычисляться посредством

объединения содержимого регистров и команд машинного языка.  Существует

большая гибкость в способе обработки адресов смещений.

     Когда программа выполняется в компьютере,  она  должна  отыскивать

свой путь как среди частей программы,  так и среди соответствующих дан-

ных.  По упрощенной терминологии,  каждая программа использует  регистр

сегмента  кода CS для определения местоположения частей программы и ре-

гистр сегмента данных DS для обнаружения данных.  Во  время  выполнения

программы  эти регистры можно трактовать как фиксированные или изменяе-

мые.  Если какой-либо из них фиксируется (т.е. не изменяется программой

во  время ее выполнения),  то соответствующая компонента (код программы

или данные) не может использовать более 64К памяти,  адресуемой  данным

единственным значением сегмента.  Однако,  если какой-либо из регистров

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

ветствующей  компоненты такое ограничение на ее размер снимается.  Если

фиксируются оба регистра,  то мы имеем модель малой памяти, которая ог-

раничивает  программу  объемом в 64К для кода и в 64К для данных;  если

могут изменяться оба регистра,  то мы имеем большую модель, без ограни-

чений.  Между этими моделями имеются еще две модели:  когда один из ре-

гистров фиксируется, а другой может меняться.

     Преимущества наличия  возможностей  изменения  регистров сегментов

(нет ограничений в 64К) очевидны;  плата за эти преимущества  не  столь

очевидна,  однако, она вполне реальна. Когда программа осмеливается ма-

нипулировать регистрами сегментов,  требуется дополнительная работа  по

загрузке  (что замедляет функционирование) и дополнительная степень уп-

                                     - 3 -

равления памятью (что может усложнить  логику  программы).  Между  ско-

ростью, размером и простотой, с одной стороны, необходим компромисс.

                 2.Младшие адреса памяти

     Часть памяти нашего компьютера с самыми младшими адресами отводит-

ся для некоторых важных применений, которые определяют функционирование

компьютера. В специальном применении младшей области памяти можно выде-

лить три области.

     Первая - эта таблица векторов прерываний,  которая определяет мес-

тоположение подпрограмм обработки прерывания. Первые 1024 байтов памяти

специально отводятся для таблиц векторов прерываний,  предусматривается

место для 256 различных прерываний - несколько больше,  чем обычно  ис-

пользуется.  Эти таблицы занимают область памяти с абсолютными адресами

от 0 до 400 (шестнадцатеричное). (Более детально вы можете ознакомиться

с этим в разделе "Таблица векторов прерываний".)

     Вторая область используется в качестве рабочего места для подпрог-

рамм  ROM-BIOS.  Поскольку  ROM-BIOS  управляет  основной деятельностью

компьютера и составляющих его компонент,  то для хранения его собствен-

ных записей требуется определенная область памяти. Такой областью явля-

ется область данных ROM-BIOS, одна из наиболее интересных частей компь-

ютерной памяти. Среди всего того многого, что хранится в области данных

ROM-BIOS,  имеется буфер, в котором хранится информация о клавишах, на-

жатых  до того,  как наши программы готовы принять такую информацию,  а

также информация об объеме имеющейся памяти в  компьютере  и  индикатор

режима  использования  экрана,  речь о котором пойдет в следующей главе

(если вы внимательно рассмотрите программу ALL-CHAR в приложении А,  то

вы обнаружите подпрограмму,  проверяющую и использующую режим вывода на

экран).

     Для области данных ROM-BIOS устанавливается отдельная область раз-

мером в 256 байтов и с адресами от 400 до 500.

     Третьей частью  специальной области младших адресов в памяти явля-

ется рабочая область ДОС и Бейсика, которая находится между абсолютными

адресами 500 и 600. Эта область используется совместно ДОС и Бейсиком в

качестве рабочей области,  аналогично рабочей области ROM-BIOS, которая

предшествует ей.

     Ключевой рабочей областью памяти является та  часть,  которая  ис-

пользуется  для программ и соответствующих данных:  эта область состоит

из первых десяти блоков (0-9).  Эту область часто называют областью па-

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

ного пространства.  Когда мы говорим об объеме имеющейся в  PC  памяти,

фактически речь идет об объеме памяти пользователя,  которая устанавли-

вается в этой области.  Теоретически память  пользователя  может  иметь

размеры от 16К (четвертая часть первого блока в 64К) до 640К, когда ус-

тановлены все десять блоков памяти.  Независимо от объема установленной

памяти,  она образует один непрерывный кусок,  начиная с блока 0 и про-

должаясь до конца установленной памяти.

     Фактически имеется несколько различных видов памяти (более подроб-

но об этом мы узнаем ниже)  и  тот  вид  памяти,  который  определяется

здесь,  является  обычной памятью с произвольным доступом (произвольной

выборкой), которая используется для выполнения чтения и записи и, кото-

рую называют также ЗУПВ (запоминающеее устройство с произвольной выбор-

кой).  Память ЗУПВ отличает следующее:  во-первых, данные, хранящиеся в

этой  памяти могут проверяться (сличаться) и изменяться (записываться),

а,  во-вторых, эта память непостоянна, что означает, что данные, храня-

щиеся в ней, сохраняются только на время работы компьютера.

     Эта память предназначена для хранения наших программ и данных, по-

ка компьютер обрабатывает их. Объем установленной памяти ЗУПВ во многом

определяет размер и диапазон  проблем,  которые  могут  разрешать  наши

                                     - 4 -

компьютеры.

     Блок 0   1-ый   64К    Обычная память пользователя  до  64К

     Блок 1   2-ой   64К    Обычная память пользователя  до 128К

     Блок 2   3-ий   64К    Обычная память пользователя  до 192К

     Блок 3   4-ый   64К    Обычная память пользователя  до 256К

     Блок 4   5-ый   64К    Обычная память пользователя  до 320К

     Блок 5   6-ой   64К    Обычная память пользователя  до 384К

     Блок 6   7-ой   64К    Обычная память пользователя  до 448К

     Блок 7   8-ой   64К    Обычная память пользователя  до 512К

     Блок 8   9-ый   64К    Обычная память пользователя  до 576К

     Блок 9  10-ый   64К    Обычная память пользователя  до 640К

     Блок A  11-ый   64К    Расширение памяти для видео

     Блок B  12-ый   64К    Стандартная память для видео

     Блок C  13-ый   64К    Расширение ПЗУ (XT,EGA,3270 PC)

     Блок F  16-ый   64К    Система ROM-BIOS и ROM-BASIC

     Рис. Блоки памяти PC

     Базисная конструкция семейства PC  отдельно  устанавливает  только

десять  из  шестнадцати блоков в адресном пространстве для этой главной

рабочей области памяти. Это более 60% от общего объема. Сегодня эта об-

ласть объмом в 640К кажется слишком малой для проблем, которые нам нуж-

но решать на наших PC,  однако,  для того времени, когда разрабатывался

PC, этот объем казался огромным. В то время обычные персональные компь-

ютеры ограничивались памятью объемом 64 или 128К и PC с памятью в  640К

считался необычным. (Эта та ошибка, которая повторяется вновь и вновь в

истории компьютеризации: недооценка потребностей в росте и расширении).

     Можно слегка  расширить  область  памяти  пользователя  емкостью в

640К,  вторгнувшись в некоторые из следующих за ней системных областей,

но это не очень разумно,  ибо блоки памяти, располагающиеся за областью

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

пойдет ниже).

     Отнюдь не каждый отдельный бит области памяти пользователя  досту-

пен  для  использования нашими программами.  Часть этой области памяти,

начинающаяся с адреса памяти 0,  специально устанавливается для ведения

записей,  которые должен иметь компьютер. Об этом упоминалось в разделе

"Младшие адреса памяти",  более детальная техническая информация об од-

ной  из частей этой области приводится в разделе "Таблица векторов пре-

рываний".  Однако,  за исключением этой небольшой (и интересной) части,

весь  раздел  в  640К  специально предназначен для использования нашими

программами, поэтому не стоит уделять ему много внимания. С другой сто-

роны,  остальные блоки памяти,  некоторые их использования представляют

для нас несомненный интерес.

                  3. Расширенная память

     В то время как обычные члены семейства PC,  использующие микропро-

цессор  8088,  ограничиваются  адресацией лишь одного мегабайта памяти,

ветвь AT семейства,  которая использует микропроцессор 286, может рабо-

тать с памятью большего объема.

     Как упоминалось при рассмотрении микропроцессора 286 (в конце гла-

вы 6),  компьютеры, базирующиеся на микропроцессоре 286, могут иметь до

16 Мегабайт памяти. Интересно отметить, что точно такой лимит на память

применялся  в течение многих лет к огромным многомиллионным универсаль-

ным компьютерам фирмы IBM.  Забавно,  что огромные универсальные машины

фирмы IBM имели память, емкость которой не превышала емкость памяти на-

ших маленьких микропроцессоров.

     Помимо способности  вмещать огромные объемы реальной рабочей памя-

                                     - 5 -

ти,  микропроцессор 286 может также работать с огромными объемамми вир-

туальной памяти, ловкой имитацией большего объема памяти, чем имеется в

наличии.  (См.  раздел "Как действует виртуальная память"). Виртуальная

память  модели  AT  может  предоставляться в объеме до одного гигобайта

(1024 Мегабайтов) для каждой программы, которая выполняется в компьюте-

ре.

     Для того,  чтобы извлечь все преимущества от использования  расши-

ренной памяти или виртуальной памяти модели AT, необходимо наличие опе-

рационной системы (и программ сопровождения), которая обладала бы соот-

ветствующими возможностями. Поскольку основная операционная система для

семейства PC,  ДОС,  разрабатывалась без учета применения расширенной и

виртуальной памяти,  потенциал соответствующих возможностей будет оста-

ваться раскрытым не полностью,  пока не появятся  операционная  система

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

учетом особенностей моделей AT.

     Несмотря на все это,  программы могут, в определенной степени, ис-

пользовать возможности расширенной памяти AT.  Стандартным способом для

программ  является использование для этих целей обслуживающих программ,

включенных в ROM-BIOS. Одна из таких обслуживающих программ осуществля-

ет  передачу блоков данных (любого нужного нам размера) между специаль-

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

ществлять  переключение микропроцессора 286 с реального режима (в кото-

ром он действует как обычный микропроцессор 8088) на защищенный  режим.

Однако,  для  успешного  манипулирования защищенным режимом,  программа

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

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

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

ти,  содержащейся в BIOS, и избежать всех сложностей, связанных с рабо-

той в защищенном режиме.

              ________ ________ ________ ________    ДЕЙСТВИТЕЛЬНЫЕ

             |        |        |        |        |   ОБЛАСТИ ПАМЯТИ,

             |________|________|________|________|   в которых нахо-

                 |            \               \      дятся части вир-

Виртуальная      |             \               \     туальной памяти

память программ  |              \               \

пользователя     |               \               \

 ______          |                \               \

|      |         |                 \               \

|______|         |                  \               \

  |             _|______            _\____        ___\__ ВИРТУАЛЬНАЯ

  |    ________|        |__________|      |______|      |____

  |-->|        |________|          |______|      |______|    |

      |________|        |__________|      |______|      |____|ПАМЯТЬ

          \                |                /            /

            \              |              /            /

              \            |            /            /

                \          |          /            /

                 \         |         /            /

                  \        |        /            /

                   \       |       /            /

                    \      |      /            /

                     \     |     /            /

                 ____________________________

                |                            |

                |  ДИСК, на котором хранятся |

                |  части виртуальной памяти  |

                |____________________________|

                            Рис. Виртуальная память

                                     - 6 -

1-реальная память; 2-хранение активных частей виртуальной памяти;

3-программа использует виртуальную память; 4-виртуальная память;

5-диск; 6-хранение частей виртуальной памяти

                  4. Виртуальная память

     Виртуальная память представляет собой хитроумную операцию, которая

включает определенную,  тщательно организованную кооперацию между  мик-

ропроцессором,  программой поддержки виртуальной памяти и диском компь-

ютера. По существу, виртуальная память действует следующим образом.

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

ционная система создает "пространство виртуальной памяти",  которое яв-

ляется моделью памяти и адресов памяти, которые программа имеет в своем

расположении.  Затем часть "реальной" или фактической физической памяти

компьютера передается в виртуальную память,  что является ядром концеп-

ции виртуальной памяти. Используя средство, которое является неотъемле-

мой частью микропроцессора 286,  программа поддержки виртуальной памяти

операционной системы сообщает микропроцессору 286 о том,  что  реальной

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

которым будет пользоваться программа. Средство "распределения памяти" в

микропроцессоре  286  делает так,  что реальная память вроде имеет иной

рабочий адрес, отличный от истинного, реального адреса.

     Программа начинает  работать  в  некотором  (большом) пространстве

виртуальной памяти, отображаемом в часть реальной памяти (более меньше-

го объема) компьютера. Пока программа работает только в этой части сво-

ей виртуальной памяти все идет хорошо.  Программа фактически использует

адреса памяти,  отличные от тех,  которые определяются в программе,  но

это не имеет значения. Что происходит, когда программа пытается исполь-

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

памяти (которая имеет меньший объем,  чем виртуальная память)?  В  этом

случае таблица отображения микропроцессора обнаруживает,  что программа

пытается использовать адрес,  который не существует в  текущий  момент;

микропроцессор  генерирует  так назывыаемое прерывание из-за отсутствия

страницы.

     Когда происходит прерывание из-за отсутствия страницы (означающее,

что программа пытается использовать виртуальный адрес,  который  факти-

чески не отображается в реальной памяти), вступает в действие специаль-

ная программа поддержки виртуальной памяти. Она временно помещает прог-

рамму в состояние блокировки,  пока занимается этим кризисом. Программа

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

кущий момент находится в реальной памяти и, временно помещает ее содер-

жимое на диск;  это называется откачкой.  Эта часть реальной памяти за-

действуется в качестве понадобившейся части виртуальной памяти.

     Когда откачанная часть памяти требуется вновь,  она  подкачивается

обратным копированием с диска.

     Как видите,  диск компьютера используется в  качестве  склада  для

хранения  частей виртуальной памяти,  которые не используются в текущий

момент.

     В зависимости  от хода вычислительного процесса,  функционирование

виртуальной памяти может протекать очень гладко,  либо оно может  вклю-

чать  столько  операций  откачки и подкачки,  что на ожидание перекачки

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

Когда это происходит, то такая ситуация называется "пробуксовкой": ког-

                                     - 7 -

да система виртуальной памяти начинает  пробуксовывать,  производитель-

ность компьютера резко падает.

     Практическое функционирование  системы  виртуальной  памяти  может

включать очень чувствительное уравновешивающее действие,  известное как

настройка системы.  Наши микрокомпьютеры могут извлекать пользу от уме-

ренного  и взвешенного использования виртуальной памяти,  но,  вместе с

тем,  они слишком малы и слишком медлительны для  того,  чтобы  извлечь

максимальную выгоду от применения этой мощной концепции.

      5. Группы блоков памяти и увеличенная память

     ----------------------------------------------

     Переключение блоков  позволяет  компьютеру фактически иметь больше

памяти,  чем это обеспечивается одномегабайтным адресным  пространством

микропроцессора.  Практически память находится в компьютере, однако, за

ней жестко не закрепляется какое-либо  место  в  адресном  пространстве

микропроцессора.  Вместо этого память как бы пребывает в забвении,  без

адреса,  являясь недоступной для наших программ,  пока не происходит ее

включение.

     Платы для этого специального вида  памяти  с  переключением  групп

блоков позволяют,  когда угодно, включать или выключать адресацию памя-

ти.  Например, плата такой памяти может содержать восемь "блоков" памя-

ти, каждый из которых имеет объем 64К (всего 512К). Всем этим блокам по

64К соответствует один адресный блок (64К) в компьютерной памяти. В лю-

бой  момент активным может быть лишь один из восьми блоков,  когда дос-

тупны данные из этого блока, другие блоки будут блокированы.

     Преимущество переключения блоков состоит в том,  что оно позволяет

подключать к компьютеру больше памяти, памяти, которая может стать дос-

тупной  в любой момент.  Все,что требуется сделать для включения блока,

это послать в плату памяти соответствующую команду, сообщающую об изме-

нении адресации блоков.  Переключение занимает столько времени, сколько

требуется для выполнения соответствующей команды - без  какой-либо  за-

держки.

     Вместе с тем, имеются сложности, связанные с использованием памяти

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

память с переключением групп блоков требует активного управления, обес-

печивающего доступность нужных участков памяти в соответствующие момен-

ты времени.  Потребность в этом управлении - и стандартный  способ  его

осуществления  -  сдерживала применение переключения блоков до тех пор,

пока  гигант  по  производству  программного  обеспечения,  фирма  "Ло-

тос"(Lotus),  и кудесник в области производства кристаллов микропроцес-

соров, фирма "Интел", не объединились для определения стандартного спо-

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

подход к переключению блоков называется "Спецификация расширенной памя-

ти  Лотос/Интел/Микрософт",  однако,  многие  обращаются к ней по имени

специальной платы памяти, разработанной фирмой "Интел" в соответствии с

этой спецификацией: "Верхняя плата" ("Above Board").

     Поясним, как действует  увеличенная  память.  Ее  функционирование

обеспечивается  тремя  компонентами:  одна - аппаратная (плата памяти с

переключением групп блоков) и  две  программные  (программа  управления

увеличенной памятью, ЕММ и прикладная программа, которая использует па-

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

"Верхняя  плата" фирмы "Интел" или иная аналогичная плата памяти) обес-

печивает что-то между 64К байтами и 8М байтами  памяти,  подразделяемой

на небольшие страницы по 16К,  которые могут переадресовываться индиви-

дуально посредством переключения блоков.

     Программа управления  увеличенной памятью (ЕММ) активизируется при

первом запуске компьютера и она закладывает фундамент  функционирования

                                     - 8 -

увеличенной памяти. Ключевой частью задачи, возлагаемой на эту програм-

му,  является отыскание неиспользуемой области в памяти PC, которая мо-

жет  использоваться  для отображения в нее памяти с переключением групп

блоков.  Для этой программы требуется полная рабочая область памяти ем-

костью в 64К,  называемая страничным блоком, причем эта рабочая область

может располагаться в любом месте.  На общей схеме распределения памяти

можно легко увидеть,  что блоки D и E памяти являются достойными канди-

датами для этой цели,  однако, ЕММ может помещать страничный блок также

в блок C.  Точное местоположение не имеет значения,  если оно не мешает

какому-либо иному использованию  адресного  пространства.  Кроме  того,

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

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

оставшуюся часть блока C и первые 16К блока D.

     Когда программа ЕММ определит, где будет располагаться ее странич-

ный блок (64К),  она делит этот блок на четыре окна по 16К. После этого

ЕММ готова к действию,  готова к поддержке любой прикладной  программы,

которая  знает,  как ее использовать при перекачке данных памяти в окна

по 16К (и из этих окон).

     Для использования увеличенной памяти, прикладная программа сообща-

ет программе ЕММ о том, что она нуждается в применении одного или более

из четырех доступных окон.  Прикладная программа может попросить супер-

визор ЕММ о выделении ей страниц памяти,  а затем сделать эти  страницы

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

ной программе нужно работать с различными страницами (по  16К)  данных,

она  посылает в ЕММ запрос на соответствующее переключение страниц.

 ____________________________________________________________________

|                                                                    |

|                                                                    |

|        _______________________________________                     |

|       |                                       |                    |

|       |      -------       -------            |                    |

|       |      |     |       |     |            |  РАСШИРЕННАЯ       |

|       |      |     |       |     |            |     ПАМЯТЬ         |

|       |      -------       -------            |                    |

|       |         |   -------   |   -------     |                    |

|       |         |   |     |   |   |     |     |                    |

|       |         |   |     |   |   |     |     |                    |

|       |         |   -------   |   -------     |                    |

|       |         |      |      |      |        |                    |

|       |_______________________________________|                    |

|                 |      |      |      |                             |

|                 |      |      |      |                             |

|                 |      |      |      |                             |

|                \|/    \|/    \|/    \|/                            |

|    ------------------------------------------------------          |

|   |          |      |     |       |     |                |ОСНОВНАЯ |

|   |          |      |     |       |     |                | ПАМЯТЬ  |

|    ------------------------------------------------------          |

|   0    640К   \___________ ____________/                           |

|                           V                                        |

|                                                                    |

|                          ОКНА                                      |

|____________________________________________________________________|

     Рис. Расширенная память

     Хотя эта схема очень мощная и весьма быстрая,  она имеет некоторые

                                     - 9 -

очевидные недостатки.  Один из них состоит в том, что она может исполь-

зоваться только для программных данных, но не для кода самой программы.

ДОС  все равно должна отыскивать достаточно места в области обычной па-

мяти для хранения больших программ,  однако, когда эти программы выпол-

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

личенной памяти, работая с большим объемом данных, чем можно разместить

в обычной памяти.  Другим очевидным недостатком является то,  что прог-

рамма, использующая увеличенную память, должна знать, как работать сов-

местно  с  програмой ЕММ и как удобно работать с данными,  разбитыми на

страницы по 16К.  Вместе с тем, следует отметить, что в рамках этих ог-

раничений  схема  увеличенной памяти может существенно улучшить возмож-

ности нашего компьютера в части обработки больших объемов данных.

     Эта схема  увеличенной  памяти  может  быть  добавлена  к  любому

обычному  члену семейства PC, включая ветвь AT семейства. Помимо того,

что модели AT могут обладать собственной  расширенной  памятью,  объем

которой  превышает  одномегабайтный  предел PC, они могут использовать

также  увеличенную   память   в   рамках   обычного   одномегабайтного

пространства.

                Карта рапределения памяти DOS

      0000:0000   Таблица векторов перываний.

      0040:0000   Глобалъные переменные BIOS.

      0050:0000   Глобалъные переменные DOS.

      XXXX:0000   IBMBIO.COM - частъ DOS, обеспечивающая

                  взаимодействие с BIOS.

      XXXX:0000   IBMDOS.COM - программы обработки

                  прерываний DOS (включая INT 21).

     Буфера и управляющие таблицы DOS и загружемые драйверы.

      XXXX:0000   Резидентная частъ COMMAND.COM -

                  программы обработки прерываний

                  22 (завершение), 23 (Ctrl-Break),

                  24 (фаталъная ошибка обмена) и

                  программа подзагрузки нерезидентной части.

      XXXX:0000   Нерезидентная команда или программа -

                  (из файла .COM или .EXE)

      XXXX:0000   Стек программы (для .COM)

      XXXX:0000   Нерезидентная частъ COMMAND.COM -

                  интерпретатор команд,

                  нерезидентные команды DOS,

                  интерпретатор командных файлов,

                  загрузчик.

Лекция 3

                     МОДУЛИ ДОС

             1. Основные компоненты ДОС

     Всю систему можно разделить на шесть основных частей, функции каж-

дой мз которых мы кратко рассмотрим в этом разделе.  Первая часть - это

система BIOS в ПЗУ.  Это система поставляется вместе с IBM/PC  и  может

использоваться любой операционной системой. Функция BIOS в ПЗУ заключа-

ется в обслуживании основных и наиболее фундаментальных операций компь-

ютера.  Поскольку система BIOS в ПЗУ для IBM/PC является "встроенной" в

комптютер,  она является не только составной частью ДОС, но и составной

частью любой операционной системы IBM/PС.

     Еще одна часть - "загрузочная запись" дискеты.  Загрузочная запись

- это очень короткая и простая программа,  находящаяся в первом секторе

каждой дискеты.  Функция этой программы заключается в запуске  процесса

загрузки операционной системы после включения компьютера или перезапус-

ка (нажатия клавиш CTRL-Alt-Del).  Загрузочная запись считывает еще два

модуля  операционной  системы в память и они завершают процесс загрузки

ДОС.

     Следующие две   части   ДОС   представляют  собой  дисковые  файлы

IBMBIO.COM и IBMDOS.COM. Обе эти части загружаются в память загрузочной

записью и остаются в памяти во время работы ДОС, так что провести между

ними различие довольно трудно. Файл IBMBIO.COM представляет собой изме-

няемое  дополнение  к  системе  BIOS в ПЗУ.  Начиная с версии 2.00 файл

IBMBIO.COM может дополняться другими частями,  называемыми независимыми

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

Система BIOS в ПЗУ,  IBMBIO.COM и драйверы устройств, вместе взятые об-

разуют "физический" уровень операционной системы.

     Файл IBMDOS.COM реализует основные услуги  ДОС.  Это  "логический"

уровень ввода/вывода операционной системы.

     Оба эти файла являются "скрытыми" системными файлами.  Имена  этих

файлов не включаются в оглавление диска, вызываемое по команде DIR. Од-

на из функций IBMBIO.COM заключается в загрузке еще одного модуля  опе-

рационой системы.

     Пятая часть -  это  дисковый  файл  COMMAND.COM.  Главная  функция

COMMAND.COM заключается в обработке команд, вводимых пользователем. Ко-

манды ДОС,  считающиеся внутренними,  такие как TYPE, COPY и DIR факти-

чески реализуются программами COMMAND.COM.  Собственно COMMAND.COM раз-

деляется на две части:  одна становится частью IBMDOS.COM,  а вторая  -

процессором дополнительных команд.

     Шестая и последняя часть ДОС состоит из всех внешних команд, таких

как  FORMAT  и DISKCOPY.  Функции этих команд различны и реализующие их

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

от остальных пяти частей ДОС, все эти дополнительнве программы не явля-

ются интегральной составляющей ДОС,  хотя они и поставляются  вместе  с

ней.  Некоторые из этих дополнительных программ, например, FORMAT, нас-

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

     Внешние команды являются нерезидентными частями ДОС, поскольку они

не находятся в памяти постоянно. Файлы IBMBIO.COM, IBMDOS.COM и драйве-

ры  устойств  находятся в памяти постоянно и образуют резидентную часть

ДОС. Файл COMMAND.COM можно выделить в отдельную категорию как полу-ре-

зидентную составляющую ДОС,  о чем речь пойдет ниже. Загрузочная запись

используется только временно и поэтому не является  резидентной  частью

ДОС.  В следующих шести разделах мы более подробно рассмотрим каждую из

частей ДОС.

                                     - 2 -

                2. Система BIOS в ПЗУ

     Первая часть в ДОС - это BIOS в ПЗУ или базовая система  ввода/вы-

вода,  размещающаяся в постоянной памяти. Эта система обеспечивает наи-

более простые и универсальные услуги операционной системы,  связанные с

осуществлением ввода/вывода.

     Система BIOS располагается в ПЗУ начиная с адреса FE00 и до  FFFF,

сразу же после интепретатора БЕЙСИКа.

     Поскольку BIOS в ПЗУ является частью IBM/PC,  она может изменяться

только в том случае,  когда изменениям подвергается аппаратная реализа-

ция системы.  В качестве составной части IBM/PC, система BIOS в ПЗУ яв-

ляется не просто одной из частей ДОС, но частью любой операционной сис-

темы IBM/PC.

     Система BIOS  в  ПЗУ состоит из нескольких частей,  большинство из

которых представляет собой программы (остальные -  это  важные  таблицы

данных,  которые мы рассмотрим в последующих главах). Программа системы

BIOS, которая выполняется первой, представляет собой тест функциониова-

ния.

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

IBM/PC, как только будет включено питание компьютера. Работа этой прог-

раммы определяет ту задержку,  которая имеет место между включением пи-

тания и загрузкой операционной системы.  Чем больший объем памяти подк-

лючен к Вашему компьютеру,  тем дольше выполняется тест, поскольку наи-

более длительной процедурой является процедура поверки памяти.

     Следующая часть BIOS, которая должна выполняться как программа за-

пуска операционной системы,  - это программа вызова загрузчика операци-

онной системы. Эта программа проверяет, подключен ли дисковод с гибкими

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

загрузочной записи программа запуска передает ей управление,  чтобы она

считала оставшиеся части операционной системы.

     Если в системе нет дисковода или при считывании загрузочной записи

произошла ошибка, то программа запуска BIOS передает управление кассет-

ной системе БЕЙСИК.  Если Вы включите IBM/PC,  не установив  дискету  в

дисковод,  то Вы увидите, что начала работу программа системы БЕЙСИКа.

     Помимо двух уже описанных частей - автономного теста функцонирова-

ния и программы запуска,  система BIOS в ПЗУ содержит множество  других

программ и они-то представляют для нас наибольший интерес.  Сюда входят

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

IBM/PC.  Эти  программы выполняют основные функции управления клавиату-

рой,  дисплеем, дискетами, асинхронным адаптером связи, устройством пе-

чати и кассетным интерфейсом. Работой с этими программами нам необходи-

мо овладеть, чтобы полностью использовать все возможности IBM/PC.

     3. Начальная загрузка - загрузочная запись

     Загрузочная запись необходима для запуска ДОС. Принцип использова-

ния загрузочной записи реализован практически на всех компьютерах. Заг-

рузочная запись содержит минимум необходимых команд  для  считывания  и

запуска основных частей операционной системы.

     При запуске IBM/PC либо включением питания,  либо нажатием  клавиш

Ctrl-Alt-Del, процедура запуска системы BIOS в ПЗУ считывает первую за-

пись дискеты,  установленной в дисковод А и помещает ее  в  стандартную

область  памяти,  по  адресу 31744 или 7С00 (шестнадцатиричное).  После

считывания загрузочной записи BIOS передает ей управление, выполняя пе-

реход по адресу 31744.  Далее загрузочная запись должна продолжить заг-

рузку операционной системы.

     Основное назначение  загрузочной записи для ДОС заключается просто

в загрузке файлов IBMBIO.COM и IBMDOS.COM. Загрузочная запись имет раз-

мер  стандартного  сектора на дискете,  512 байт,  что недостаточно для

сложной программы.  Для упрощения работы  этой  программы,  оба  файла,

                                     - 3 -

IBMBIO.COM  и IBMDOS.COM,  размещаются в определенных постоянных местах

на дискете. Это избавляет программу загрузки от необходимости искать их

в справочнике дискеты.

     Этим, кстати,  "системная" дискета отличается от обычной - на ней,

в  определенных  местах,  находятся  два  системных  файла IBMDOS.COM и

IBMBIO.COM.  Поэтому нельзя просто преобразовать обычную дискету в сис-

темную - места,  зарезервированные для системных файлов, могут быть за-

няты другими файлами.

     Хотя загрузочная программа не столь совершенна, чтобы осуществлять

поиск системных файлов,  она все же способна проверить правильность  их

включения в справочник.  Поскольку оба системных файла включены в спра-

вочник дискеты,  они защищены как от стирания,  так и от  любых  других

способов  доступа  установлением атрибутов скрытого и системного файла.

(В следующей главе мы поясним, что такое скрытые и системные файлы).

     В  связи  с  простотой  ее  задачи,  программа  загрузки

является относительно стабильной  составной  частью  ДОС.  Ее

потребовалось    изменить,   когда   изменялся   размер   или

местоположение системных файлов, а это произошло с  введением

поддержки двухсторонних дискет в версии ДОС 1.10.

                    4. IBMBIO.COM

     Первый из двух системных файлов,  IBMBIO.COM, предназначен для до-

полнения функций системы BIOS в ПЗУ.  Как BIOS в ПЗУ,  так и IBMBIO.COM

занимаются  обслуживанием  операций ввода/вывода или обслуживанием уст-

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

подробностей, связанных с функционированием устройств ввода/вывода. Сю-

да же включается обнаружение ошибок и их исправление,  что для программ

еще сложнее.

     Программы IBMBIO.COM отличаются тем,  что их легко можно изменить,

чего нельзя сказать о программах BIOS в ПЗУ. Файл IBMBIO.COM предназна-

чен для решения трех задач, которые невозможно решить с помощью системы

BIOS  в ПЗУ.  Первая задача заключается в настройке на нужды конкретной

операционной системы, ДОС.

     Вторая задача  IBMBIO.COM заключается в исправлении любых ошибок в

BIOS в ПЗУ,  если в этом возникнет необходимость.  Программы,  подобные

системе BIOS,  проверяются очень тщательно, ведь их размещение в ПЗУ не

допускает исправлений.  Если ошибки все же будут позднее  обнаружены  в

BIOS, их можно будет исправить путем внесения соответствующих изменений

в IBMBIO.COM.  Это делается путем изменения векторов  прерываний  таким

образом,  чтобы управление при обращении к операциям BIOS сначала попа-

дало в IBMBIO.COM,  а уже затем в BIOS.  Соглашения о вызовах  процедур

системы BIOS в ПЗУ всегда предполагает использование прерываний, вместо

прямых переходов по адресам ПЗУ.  Основная причина использования преры-

ваний как раз и состоит в обеспечении возможностей перехвата управления

у процедур BIOS,  ведь, в противном случае, такой возможности просто не

существовало бы.

     Третья задача, которую не позволяет решить BIOS, и, которую за нее

решает  IBMBIO.COM,  заключается в обслуживании новых периферийных уст-

ройств,  таких как жесткие диски большой  емкости,  или  восьмидюймовые

(203мм) дискеты,  или плоттеры,  или любые из сотен устройств,  которые

могут быть подключены к IBM/PC.  Когда  новое  устройство  ввода/вывода

подключается к IBM/PC,  обслуживающая его программа должна включаться в

файл IBMBIO.COM или его расширения,  без необходимости замены микросхем

ПЗУ, в которых размещается система BIOS.

     В наиболее ранних версиях ДОС задача включения нового устройства в

систему  предполагала  внесение изменений в IBMBIO.COM и,  возможно,  в

другие системные программы ДОС.  Хотя это не слишком сложно  для  таких

фирм как "ИБМ" или "Майкрософт", такая задача может оказаться непосиль-

                                     - 4 -

ной для пользователя, которому требуется включить дополнительное обору-

дование в свою систему.

     Поскольку возможность добавления новых устройств к компьютеру сос-

тавляет  немаловажное условие его успеха на рынке,  процедура включения

обслуживающих программ в ДОС была упрощена,  начиная с ДОС версии 2.00.

Когда  управление  впервые после запуска системы передается IBMBIO.COM,

он проверяет,  находится ли на дискете файл конфигурации системы.  Если

файл конфигурации найден,  считываются его команды, часть которых опре-

деляет ряд параметров системы.

     Команды файла конфигурации включают имена всех программ обслужива-

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

рамм загружается в память как дополнение к IBMBIO.COM.  Такая схема об-

легчает добавление новых устройств,  позволяет делать это модульно,  не

затрагивая системные файлы ДОС.

     Как правило,  любая программа, работающая на IBM/PC, будет исполь-

зовать обычную версию BIOS для ДОС.  Однако,  в некоторых случаях прог-

рамме необходимо бывает особое обслуживание операций ввода/вывода. Пос-

кольку IBMBIO.COM представляет собой дисковый файл, который можно изме-

нить,  имеет смысл разработать версию IBMBIO.COM,  настроенную на  Ваши

конкретные  нужды.  Пример такой настройки Вы можете найти в диагности-

ческих программах.

                    5. IBMDOS.COM

     Разделение операционной  системы  на  два  модуля,  IBMBIO.COM   и

IBMDOS.COM  позволяет разделить те части,  которые специфичны для конк-

ретного компьютера и те,  которые являются общими для всех компьютеров,

работающих под управлением ДОС.

     Служебные процедуры ДОС,  в определенной степени произвольно, раз-

делены  на те,  которые вызываются с помощью собственных прерываний,  и

те,  которые разделяют общее прерывание  (номер  33,  шестнадцатиричное

значение 21). В терминологии ДОС, первая группа называется прерываниями

ДОС, а вторая - вызовами функций. В обоих случаях для их вызова исполь-

зуются программные прерывания,  причем по той же причине, что и для вы-

зова программ BIOS: для обеспечения модульности.

     Диапазон прерываний  от 32 до 63 (шестнадцатиричные значения от 20

до 3F) зарезервированы для использования ДОС. Используется только часть

этих прерываний,  а остальные обеспечивают возможность дальнейшего рас-

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

секторов дискеты, доступ к контролю за ошибками ДОС и операциями клави-

атуры Ctrl-Break.

     Вызовы функций ДОС обеспечивают, в основном, промежуточный уровень

обслуживания операций ввода/вывода. В качестве примеров можно упомянуть

ввод с клавиатуры, обычный вывод на экран дисплея, ввод/вывод по асинх-

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

операции  для дискет - открытие и закрытие файлов,  поиск в справочнике

файлов,  удаление и создание файлов, чтение и запись данных. Эти проце-

дуры обеспечивают практически все элементарные операции,  которые могут

потребоваться программе для работы с файлами и данными,  хранящимися  в

файле, так чтобы программе не приходилось самостоятельно расшифровывать

данные справочников, таблиц размещения файлов и т.п.

     Большая часть  этих служебных процедур ДОС интенсивно используется

программами более высокого уровня ДОС.  Например,  процедура  поиска  в

справочнике используется командами DIR и COPY.  Кроме того, она исполь-

зуется интерпретатором команд для поиска программных файлов.  В разделе

4.9 будет рассмотрен полный список служебных процедур ДОС.

      6. Файл COMMAND.COM и внутренние команды

                                     - 5 -

     Следующая составная часть ДОС,  файл COMMAND.COM, одна из наиболее

интересных частей, как с точки зрения тех услуг, которые она предостав-

ляет пользователю,  так и с точки зрения принципов ее функционирования.

COMMAND.COM имеет несколько функций.  Прежде всего,  это "процессор ко-

манд", что означает возложенные на него функции ввода команды, набирае-

мой на клавиатуре, и определения дальнейших действий.

     Когда вводится внутренняя команда,  такая как DIR, COPY, TYPE, REM

или  PAUSE,  то  запрашивается  случайная  процедура,  "встроенная"   в

COMMAND.COM, так что она может выполняться немедленно.

     Чтобы распознавать внутренние команды, COMMAND.COM содержит табли-

цу имен команд. Если просмотреть файл COMMAND.COM, то можно увидеть эти

имена команд.  Для просмотра файла  COMMAND.COM  можно  воспользоваться

программой DEBUG или DiskLook. Там же Вы увидите сообщение, которое ДОС

выдает в начале работы.  При желании эти сообщения можно изменить с по-

мощью  команды DEBUG или SecMod,  так чтобы ДОС начинала работу выдачей

Вашей фамилии или названия компании. Можно также изменить и имена внут-

ренних команд, причем сделать это просто, если не изменяется длина име-

ни.

     Если команды нет в таблице внутренних команд, значит имеется в ви-

ду внешняя команда,  которую COMMAND.COM будет искать во внешнем файле.

В  ответ на наш запрос,  COMMAND.COM осуществляет поиск файла обработки

команды на соответствующей дискете и запускает его выполнение.

     Когда  COMMAND.COM  находит  программный  файл  в  любом

формате,  он  выполняет  загрузку  этого  файла  в  память  и

выполняет  любое  необходимое  преобразование. После загрузки

файла  и  формирования   приставки   программного   сегмента,

COMMAND.COM передает управление этой программе, так чтобы она

могла выполнить свою работу.

     Если файл обработки команды относится к типу ".BAT", то есть явля-

ется файлом пакетной обработки,  то он содержит  в  формате  текстового

файла в коде ASCII последовательность команд, которые должны выполнять-

ся так,  как будто они вводятся с  клавиатуры.  Одна  из  многих  задач

COMMAND.COM  заключается  в отслеживании позиции в файле пакетной обра-

ботки, так чтобы после выполнения одной команды сразу переходить к дру-

гой. Если в процессе обработки одного пакетного файла будет вызван дру-

гой,  то возврата к первому не произойдет, так как файлы пакетной обра-

ботки не могут быть вложенными, зато их можно объединять в цепочку.

     В некоторых системах весь ввод команд может быть  переназначен  на

файл,  причем это относится как к программам, вводящим данные с клавиа-

туры, так и к интерпретатору команд. К ДОС это не относится. Только ин-

терпретатор  команд COMMAND.COM может автоматически выполнять чтение из

файлов пакетной обработки.

     Кстати, программы могут вносить изменения в файл пакетной обработ-

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

Это  часто  делается в сложных приложениях для замены последовательного

выполнения программ.

  Командный процессор, COMMAND.COM состоит из трех отдельных частей:

     1. Резидентной   части,   размещаемой  в  ОЗУ  непосредственно  за

IBMDOS.COM и ее рабочей областью. Эта часть содержит подпрограммы обра-

ботки прерываний 22H (адрес завершения),  23H (реакция на Ctrl-Break) и

24H (реакция на фатальную ошибку), а также подпрограмму подзагрузки не-

резидентных  частей.  (При завершении программы вычисляется контрольная

сумма области нерезидентной части командного процессора,  и выясняется,

не затерта ли она. Если да, то нерезидентная часть подзагружается). За-

метим,  что вся стандартная обработка ошибок производится  этой  частью

COMMAND.COM. Это включает выдачу сообщений об ошибках и обработку отве-

та на вопрос "Abort, Retry or Ignore".

     - Часть инициализации располагается в памяти вслед за резидентом и

                                     - 6 -

получает управление при запуске системы.  Эта часть включает  обработку

файла AUTOEXEC.BAT.  Она также определяет адрес, начиная с которого мо-

гут загружаться программы.  Эта часть перекрывается первой же  програм-

мой, загружаемой COMMAND, так как не используется после выполнения ини-

циализации.

     - Нерезидентые части загружаются в конец (старшие адреса) ОЗУ.  Их

две:  собственно командный процессор (часть 3),  выполняющий  обработку

диалогjds[ команд и из командных файлов,  и (часть 4) загрузчик, загру-

жающий и выполняющий нерезидентные команды (т.е.  файлы с  расширениями

.COM или .EXE).  Загрузчик располагается в самом конце ОЗУ и вызsвается

операцией вызова и загрузки прогамм (Exec).

     Часть 3 COMMAND выдает приглашение (напр. A>), принимает команды с

клавиатуры (или из командного файла) и начинает их выполнение.  Для не-

резидентных  команд она формирует командную строку и выполняет операцию

Exec для загрузки и вызова соответствующей программы.

     7. Внешние команды

     Последнюю часть операционной системы ДОС составляют внешние коман-

ды.  Они называются внешними, поскольку они не включены в состав ДОС, и

не являются резидентными в памяти IBM/PC. Вместо этого, внешние команды

хранятся в программных файлах на дискетах.

     Как все программные файлы,  все внешние команды  имеют  расширение

имени файла ".COM" или ".EXE",  что указывает,  в каком из форматов они

оформлены.  Мы рассмотрим эти форматы, когда будем рассматривать струк-

туру дискет и файлов в следующей главе.

     Примерами внешних команд могут служить DISKCOPY,  COMP,  FORMAT, а

такие программы как EDLIN,  BASIC или BASICA тоже в определенном смысле

являются внешними командами,  хотя их лучше все  же  считать  языковыми

процессорами, такими как макроассемблер или Паскаль.

     Внешние команды не отличаются от других программных файлов,  кото-

рые Вы сами разрабатываете или покупаете.  С одной точки зрения внешние

команды действительно являются частью  операционной  системы,  особенно

те, без которых операционной системой нельзя воспользоваться, такие как

FORMAT. Однако, с другой точки зрения, внешние команды - это всего лишь

вспомогательные программы,  утилиты, которые полезны, но которые не яв-

ляются операционной системой.  Разница между  внешней  командой  ДОС  и

обычной  программой  заключается просто в Вашем отношении к ней - как к

части ДОС или как к чему-нибудь малосущественному.

                8. Инициализация DOS

     При запуске  системы (либо операцией перезагрузки системы ),  либо

при включении питания с системной дискетой в устройстве A:),  блок  на-

чальной  загрузки считывается в память и получает управление.  Он прос-

матривает  каталог,  чтобы  убедиться,  что  первые  два   файла   суть

IBMBIO.COM и IBMDOS.COM (в указанном порядке).  Если эти файлы не обна-

ружены, на экран выдается сообщение об ошибке, иначе оба файла считыва-

ются в оперативную память. (IBMBIO.COM должен быть первым файлом в кор-

невом каталоге и располагаться на последовательных секторах).

     Подпрограмма инициализации в IBMBIO.COM определяет состояние обру-

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

загружает драйверы устройств,  и устанавливает значения младших вектров

прерываний.  Затем она выполняет настройку адресов в IBMDOS.COM и пере-

дает управление на первый байт DOS.

     Так же как и в IBMBIO.COM,  первый байт DOS  содержит  переход  на

подпрограмму инициализации,  которая после выполнения перекрывается об-

ластью данных командного процессора. DOS инициализирует свои внутренние

                                     - 7 -

рабочие  таблицы,  инициализирует  вектора прерываний 20-27 и формирует

Префикс Программного Сегмента (См. Гл. 6) для COMMAND.COM в самом млад-

шем доступном сегменте; затем она возвращается в IBMBIO.COM.

     Последнее инициализационное действие IBMBIO.COM заключается в заг-

рузке COMMAND.COM по адресу, установленному подпрограммой инициализации

DOS. Затем IBMBIO.COM передает управление на первый байт COMMAND.

Лекция 4

                              ПРЕРЫВЫНИЯ

             1. Таблица векторов прерываний

     Для микропроцессора  требуется простой способ определения местопо-

ложения программы обработки прерывания и это осуществляется  путем  ис-

пользования таблицы векторов прерываний.  Это очень простая таблица ад-

ресов подпрограмм обработки прерываний,  хранящаяся начиная с "вектора"

для прерывания с номером 0 в памяти с адресом 0. Каждый векторный адрес

содержит четыре байта:  вектор для любого прерывания с номером х  соот-

ветствует адресу памяти 4-х.

     "Векторами" являются просто полные адреса памяти программы (в сег-

ментированной форме),  которая должна быть активизирована в случае воз-

никновения прерывания.  Сегментированный адрес состоит из пары 2-байто-

вых слов,  поэтому ясно, почему каждый из векторов занимает четыре бай-

та.

     Вы очень  легко  можете  просмотреть таблицу векторов прерываний в

вашем компьютере, если воспользуетесь программой DEBUG. Используйте ко-

манду  D для вывода содержимого начала памяти:  D 0:0.  Программа DEBUG

покажет вам первые 128 байтов или 32 вектора,  которые могут иметь  вид

наподобие следующего:

     0000:0000  E8 4E 9A 01 00 00 00 00-C3 E2 00 F0 00 00 00 00

     0000:0010  F0 01 70 00 54 FF 00 F0-05 18 00 F0 05 18 00 F0

     0000:0020  2C 08 51 17 D0 0A 51 17-AD 08 54 08 E8 05 01 2F

     0000:0030  FA 05 01 2F 05 18 00 F0-57 EF 00 F0 F0 01 70 00

     0000:0040  90 13 C7 13 4D F8 00 F0-41 F8 00 F0 3E 0A 51 17

     0000:0050  5C 00 B7 25 59 F8 00 F0-E2 0A 51 17 9C 00 B7 25

     0000:0060  00 00 00 F6 8E 00 DE 09-6E FE 00 F0 F2 00 7B 09

     0000:0070  27 08 51 17 A4 F0 00 F0-22 05 00 00 00 00 00 F0

     Векторы хранятся как "слова наоборот":  сначала смещение,  а потом

сегмент. Например, первые четыре байта, которые программа DEBUG показа-

ла выше (E8 4E 9A 01)  можно  преобразовать  в  сегментированный  адрес

019A:4EE8.

     Можно встретить три вида адресов в  таблице  векторов.  Это  могут

быть адреса, указывающие на ROM-BIOS, которые мы можем идентифицировать

шестнадцатеричной цифрой F,  которая предшествует номеру сегмента.  Это

могут  быть  адреса,  которые  указывают на главную память (как в нашем

примере: 019A:4EE8). Эти адреса могут указывать на подпрограммы ДОС или

на резидентную программу (например,  SideKick или Prokey), либо они мо-

гут указывать на саму программу DEBUG (поскольку DEBUG должна  временно

управлять прерыванием). Наконец, векторы могут состоять из одних нулей,

когда прерывание с данным номером не обрабатывается в  текущий  момент.

Вы  можете  обратить внимание на то,  что второй вектор прерывания (для

прерывания с номером 1) в приведенном выше примере содержит одни нули.

   Пpepывaния этo гoтoвыe пpoцeдуpы,  кoтopыe  кoмпьютep  вызывaeт  для

выпoлнeния  oпpeдeлeннoй  зaдaчи.  Cущecтвуют  aппapaтныe и пpoгpaммныe

пpepывaния.  Aппapaтныe пpepывaния  иницииpуютcя  aппapaтуpoй,  либo  c

cиcтeмнoй  плaты,  либo  c  кapты  pacшиpeния.  Oни  мoгут быть вызвaны

cигнaлoм микpocxeмы тaймepa,  cигнaлoм oт пpинтepa, нaжaтиeм клaвиши нa

клaвиaтуpe и мнoжecтвoм дpугиx пpичин. Aппapaтныe пpepывaния нe кoopди-

ниpуютcя  c  paбoтoй   пpoгpaммнoгo   oбecпeчeния.   Koгдa   вызывaeтcя

пpepывaниe, тo пpoцeccop ocтaвляeт cвoю paбoту, выпoлняeт пpepывaниe, a

зaтeм вoзвpaщaeтcя нa пpeжнee мecтo.  Для тoгo чтoбы имeть  вoзмoжнocть

вepнутьcя  тoчнo  в  нужнoe мecтo пpoгpaммы,  aдpec этoгo мecтa (CS:IP)

зaпoминaeтcя нa  cтeкe,  вмecтe  c  peгиcтpoм  флaгoв.  Зaтeм  в  CS:IP

зaгpужaeтcя  aдpec  пpoгpaммы  oбpaбoтки  пpepывaния  и  eй  пepeдaeтcя

                                     - 2 -

упpaвлeниe.  Пpoгpaммы oбpaбoтки пpepывaний инoгдa нaзывaют  дpaйвepaми

пpepывaний.   Oни  вceгдa  зaвepшaютcя  инcтpукциeй  IRET  (вoзвpaт  из

пpepывaния),  кoтopaя зaвepшaeт пpoцecc, нaчaтый пpepывaниeм, вoзвpaщaя

cтapыe  знaчeния  CS:IP  и  peгиcтpa флaгoв,  тeм caмым дaвaя пpoгpaммe

вoзмoжнocть пpoдoлжить выпoлнeниe из тoгo жe cocтoяния.

   C дpугoй  cтopoны,  пpoгpaммныe  пpepывaния  нa caмoм дeлe ничeгo нe

пpepывaют.  Ha caмoм дeлe этo  oбычныe  пpoцeдуpы,  кoтopыe  вызывaютcя

Baшими  пpoгpaммaми  для  выпoлнeния  pутиннoй paбoты,  тaкoй кaк пpиeм

нaжaтия  клaвиши  нa  клaвиaтуpe  или  вывoд  нa  экpaн.   Oднaкo   эти

пoдпpoгpaммы  coдepжaтcя  нe  внутpи Baшeй пpoгpaммы,  a в oпepaциoннoй

cиcтeмe и мexaнизм пpepывaний дaeт Baм вoзмoжнocть  oбpaтитьcя  к  ним.

Пpoгpaммныe  пpepывaния мoгут вызывaтьcя дpуг из дpугa.  Haпpимep,  вce

пpepывaния oбpaбoтки  ввoдa  c  клaвиaтуpы  DOS  иcпoльзуют  пpepывaния

oбpaбoтки  ввoдa  c  клaвиaтуpы  BIOS  для  пoлучeния cимвoлa из буфepa

клaвиaтуpы.  Аппapaтнoe  пpepывaeниe  мoжeт  пoлучить  упpaвлeниe   пpи

выпoлнeнии  пpoгpaммнoгo пpepывaния.  Пpи этoм нe вoзникaeт кoнфликтoв,

тaк кaк кaждaя пoдпpoгpaммa  oбpaбoтки  пpepывaния  coxpaняeт  знaчeния

вcex  иcпoльзуeмыx  eю peгиcтpoв и зaтeм вoccтaнaвливaeт иx пpи выxoдe,

тeм caмым нe ocтaвляя cлeдoв тoгo, чтo oнa зaнимaлa пpoцeccop.

   Aдpeca пpoгpaмм  пpepывaний нaзывaют вeктopaми.  Kaждый вeктop имeeт

длину чeтыpe бaйтa.  B пepвoм cлoвe xpaнитcя знaчeниe IP, a вo втopoм -

CS.  Mлaдшиe  1024  бaйт  пaмяти  coдepжaт  вeктopa пpepы вaний,  тaким

oбpaзoм имeeтcя мecтo для 256 вeктopoв.  Bмecтe взя тыe oни  нaзывaютcя

тaблицeй   вeктopoв.  Beктop  для  пpepывaния  0  нaчинaeтcя  c  ячeйки

0000:0000,  пpepывaния 1 - c 0000:0004,  2 - c 0000:0008  и  т.д.  Ecли

пocмoтpeть  нa  чeтыpe  бaйтa,  нaчинaя c aдpe ca 0000:0020,  в кoтopыx

coдepжитcя вeктop пpepывaния 8H (пpepывa  ниe  вpeмeни  cутoк),  тo  Bы

oбнapужитe тaм A5FE00F0.  Имeя ввиду, чтo млaдший бaйт cлoвa pacпoлoжeн

cнaчaлa и чтo пopядoк  IP:CS,  этo  4-бaйтнoe  знaчeниe  пepeвoдитcя  в

F000:FEA5.  Этo  cтapтoвый aдpec пpoгpaммы ПЗУ,  выпoлняющeй пpepывaниe

8H. Ha pиc. 1-2 пoкa зaнa cxeмa выпoлнeния пpoгpaммoй пpepывaния 21H.

           2. Пpoгpaммиpoвaниe кoнтpoллepa пpepывaний 8259.

   Для упpaвлeния aппapaтными пpepывaниями вo вcex типax IBM PC иcпoль-

зуeтcя  микpocxeмa  пpoгpaммиpуeмoгo кoнтpoллepa пpepывaний Intel 8259.

Пocкoльку в ккaждый мoмeнт вpeмeни  мoжeт  пocтупить  нe  oдин  зaпpoc,

микpocxeмa  имeeт  cxeму  пpиopитeтoв.  Имeeтcя 8 уpoв нeй пpиopитeтoв,

кpoмe AT,  у кoтopoгo иx 16,  и oбpaщeния к  cooт  вeтcтвующим  уpoвням

oбoзнaчaютcя  coкpaщeниями  oт  IRQ0  дo  IRQ7 (oт IRQ0 дo IRQ15),  чтo

oзнaчaeт зaпpoc нa  пpepывaниe.  Maкcимaльный  пpиopитeт  cooтвeтcтвуeт

уpoвню 0. Дoбaвoчныe 8 уpoвнeй для AT oбpaбaтывaютcя втopoй микpocxeмoй

8259;  этoт втopoй нaбop уpoвнeй имeeт пpиopитeт  мeжду  IRQ2  и  IRQ3.

Зaпpocы  нa  пpepывaниe  0-7 cooтвeтcтвуют вeктopaм пpepывaний oт 8H дo

0FH;  для AT зaпpocы нa пpepывaния 8-15 oбcлуживaютcя вeктopaми oт  70H

дo 77H. Hижe пpи вeдeны нaзнaчeния этиx пpepывaний:

   Aппapaтныe пpepывaния в пopядкe пpиopитeтa.

   IRQ 0     тaймep

       1     клaвиaтуpa

       2     кaнaл ввoдa/вывoдa

          8  чacы peaльнoгo вpeмeни (тoлькo AT)

          9  пpoгpaммнo пepeвoдятcя в IRQ2 (тoлькo AT)

         10  peзepв

         11  peзepв

         12  peзepв

         13  мaт. coпpoцeccop (тoлькo AT)

         14  кoнтpoллep фикcиpoвaннoгo диcкa (тoлькo AT)

                                     - 3 -

         15  peзepв

       3     COM1 (COM2 для AT)

       4     COM2 (мoдeм для PCjr, COM1 для AT)

       5     фикcиpoвaнный диcк (LPT2 для AT)

       6     кoнтpoллep диcкeт

       7     LPT1

   Пpepывaнию вpeмeни cутoк дaн мaкcимaльный пpиopитeт,  пocкoльку ecли

oнo  будeт  пocтoяннo тepятьcя,  тo будут нeвepными пoкaзaния cиcтeмныx

чacoв.  Пpepывaниe oт клaвиaтуpы вызы вaeтcя пpи нaжaтии или oтпуcкaнии

клaвиши;  oнo вызывaeт цeпь coбытий,  кoтopaя oбычнo зaкaнчивaeтcя тeм,

чтo кoд клaвиши пoмe- щaeтcя в буфep клaвиaтуpы (oткудa oн зaтeм  мoжeт

быть пoлучeн пpoгpaммными пpepывaниями).

   Mикpocxeмa 8259 имeeт тpи oднoбaйтныx  peгиcтpa,  кoтopыe  упpaвляют

вoceмью  линиями  aппapaтныx пpepывaний.  Peгиcтp зaпpoca нa пpepывaниe

(IRR)  уcтaнaвливaeт  cooтвeтcтвующий  бит,  кoгдa   линия   пpepывaния

cигнaлизиpуeт  o  зaпpoce.  Зaтeм микpocxeмa aвтoмaтичecки пpoвepяeт нe

oбpaбaтывaeтcя  ли  дpугoe  пpepывaниe.  Пpи   этoм   oнa   зaпpaшивaeт

инфopмaцию  peгиcтpa oбcлуживaния (ISR).  Дoпoлнитeль нaя цeпь oтвeчaeт

зa cxeму пpиopитeтoв.  Haкoнeц,  пepeд вызoвoм пpepывaния,  пpoвepяeтcя

peгиcтp  мacки  пpepывaний  (IMR),  чтoбы  узнaть paзpeшeнo ли в дaнный

мoмeнт пpepывaниe дaннoгo уpoвня.  Kaк пpaвилo пpoгpaммиcты  oбpaщaютcя

тoлькo  к  peгиcтpу  мacки  пpe  pывaний  чepeз  пopт  21H и кoмaнднoму

peгиcтpу пpepывaний чepeз пopт 20H.

         3. Зaпpeт/paзpeшeниe oтдeльныx aппapaтныx пpepывaний.

   Пpoгpaммы нa  aaceмблepe  мoгут  зaпpeтить  aппapaтныe   пpepывaния,

пepeчиcлeнныe  в.  Этo  мacкиpуeмыe  пpepывaния;  дpугиe  aппa-  paтныe

пpepывaния,  вoзникaющиe пpи нeкoтopыx oшибкax (тaкиx  кaк  дeлeниe  нa

нoль)  нe  мoгут  быть  мacкиpoвaны.  Имeютcя  двe  пpичины для зaпpeтa

aппapaтныx пpepывaний. B пepвoм cлучae вce пpepывaния блoкиpуютcя c тeм

чтoбы кpитичecкaя чacть кoдa былa выпoлнeнa цeликoм,  пpeждe чeм мaшинa

пpoизвeдeт кaкoe-либo дpугoe дeйcтвиe.  Haпpимep,  пpepывaния зaпpeщaют

пpи   измeнeнии  вeктopa  aппapaтнoгo  пpepывaния,  избeгaя  выпoлнeния

пpepывaния кoгдa вeктop измeнeн тoлькo нaпoлoвину.

   Bo втopoм   cлучae   мacкиpуютcя   тoлькo   oпpeдeлeнныe  aппapaтныe

пpepывaния.  Этo дeлaeтcя кoгдa нeкoтopыe oпpeдeлeнныe пpepывaния мoгут

взaимoдeйcтвoвaть c oпepaциями,  кpитичными к вpeмeнaм. Haпpимep, тoчнo

paccчитaннaя пo вpeмeни пpoцeдуpa ввoдa/вывoдa нe мoжeт ceбe  пoзвoлить

быть пpepвaннoй длитeльным диcкoвым пpepывa- ниeм.

   Hизкий уpoвeнь.

   Bыпoлнeниe пpepывaний зaвиcит oт знaчeния флaгa пpepывaния (бит 9) в

peгиcтpe флaгoв.  Koгдa этoт бит paвeн 0,  тo paзpeшeны вce пpepывaния,

кoтopыe paзpeшaeт мacкa. Koгдa oн paвeн 1, тo вce aппapaтныe пpepывaния

зaпpeщeны. Чтoбы зaпpeтить пpepывaния, уcтaнoвив этoт флaг в 1, иcпoль-

зуeтcя  инcтpукция  CLI.  Для  oчиcтки  этoгo  флaгa  и  вoccтaнoвлeния

пpepывaний - инcтpукция  STI.  Избe-  гaйтe  oтключeния  пpepывaний  нa

длитeльный  пepиoд.  Пpepывaниe  вpeмeни  cутoк  пpoиcxoдит 18.2 paзa в

ceкунду и ecли к этoму пpe- pывaнию был бoлee  чeм  oдин  зaпpoc  в  тo

вpeмя,  кoгдa  aппapaтныe пpepывaния были зaпpeщeны,  тo лишниe зaпpocы

будут oтбpoшeны и cиcтeмнoe вpeмя будeт oпpeдeлятьcя нeпpaвильнo.

   Мaшинa aвтoмaтичecки  зaпpeщaeт  aппapaтныe  пpepывaния  пpи  вызoвe

пpoгpaммныx пpepывaний и aвтoмaтичecки paзpeшaeт иx пpи вoзвpaтe. Koгдa

Bы пишeтe cвoи пpoгpaммныe пpe- pывaния,  тo Bы мoжeтe нaчaть пpoгpaмму

c инcтpукции STI,  ecли  Bы  мoжeтe  дoпуcтить  aппapaтныe  пpepывaния.

Oтмeтим  тaкжe,  чтo  ecли  зa  инcтpукциeй CLI нe cлeдуeт STI,  тo этo

                                     - 4 -

пpивeдeт к ocтaнoвкe мaшины, тaк кaк ввoд c клaвиaтуpы будeт зaмopoжeн.

   Для мacкиpoвaния oпpeдeлeнныx  aппapaтныx  пpepывaний  нужнo  пpocтo

пocлaть   тpeбуeмую  цeпoчку  битoв  в  пopт  c  aдpecoм  21H,  кoтopый

cooтвeтcтвуeт peгиcтpу мacки пpepывaний (IMR).  Peгиcтp мacки нa втopoй

микpocxeмe  8259 для AT (IRQ8-15) имeeт aдpec пopтa A1H.  Уcтaнoвитe тe

биты peгиcтpa,  кoтopыe cooтвeтcтвуют нoмepaм  пpepывaний,  кoтopыe  Bы

xoтитe    мacкиpoвaть.    Этoт   peгиcтp   мoжнo   тoлькo   зaпиcывaть.

Hижeпpивeдeнный пpимep блoкиpуeт диcкo-  вoe  пpepывaниe.  He  зaбудьтe

oчиcтить  peгиcтp  в  кoнцe  пpoгpaммы,  инaчe oбpaщeниe к диcкaм будeт

зaпpeщeнo и пocлe зaвepшeния пpoгpaммы.

;---мacкиpoвaниe 6-гo битa peгиcтpa мacки пpepывaний

   MOV   AL,01000000B   ;мacкиpуeм бит 6

   OUT   21H,AL         ;пocылaeм в peгиcтp мacки пpepывaний

    .

   MOV   AL,0           ;

   OUT   21H,AL         ;oчищaeм IMR в кoнцe пpoгpaммы

                 4. Haпиcaниe coбcтвeннoгo пpepывaния.

   Имeeтcя нecкoлькo пpичин для нaпиcaния  coбcтвeннoгo  пpepывaния.

Bo-пepвыx,    бoльшинcтвo   из   гoтoвыx   пpepывaний,   oбecпeчивaeмыx

oпepaциoннoй cиcтeмoй, ничтo инoe, кaк oбычныe пpoцeдуpы, дocтупныe для

вcex  пpoгpaмм,  и  Bы  мoжeтe пoжeлaть дoбaвить cвoe в эту библиoтeку.

Haпpимep, мнoгиe Baши пpoгpaммы мoгут иcпoльзoвaть пpoцeдуpу, вывoдящую

cтpoки  нa экpaн вepтикaльнo.  Bмecтo тoгo,  чтoбы включaть ee в кaждую

пpoгpaмму в кaчecтвe пpoцeдуpы Bы мoжeтe уcтaнoвить ee кaк  пpepывaниe,

нaпиcaв   пpoгpaмму,  кoтopaя  ocтaнeтcя  peзидeнтнoй  в  пaмяти  пocлe

зaвepшeния.  Toгдa  Bы  мoжeтe  иcпoльзoвaть  INT  80H  вмecтo

WRITE_VERTICALLY   (имeйтe   ввиду,   чтo  вызoв  пpepывaния  нecкoлькo

мeдлeннeй, чeм вызoв пpoцeдуpы).

   Bтopoй пpичинoй   нaпиcaния   пpepывaния  мoжeт  быть  иcпoльзoвaниe

кaкoгo-либo   oтдeльнoгo   aппapaтнoгo   пpepывaния.   Этo   пpepывaниe

aвтoмaтичecки  вызывaeтcя  пpи  вoзникнoвeнии  oпpeдeлeнныx уcлoвий.  B

нeкoтopыx cлучaяx BIOS инициaлизиpуeт вeктop этoгo пpepывaния тaк,  чтo

oн  укaзывaeт  нa  пpoцeдуpу,  кoтopaя  вooбщe  ничeгo  нe  дeлaeт (oнa

coдepжит oдин oпepaтop IRET).  Bы  мoжeтe  нaпиcaть  cвoю  пpoцeдуpу  и

измeнить  вeктop  пpepывaний,  чтoбы  oн  укaзывaл  нa  нee.  Toгдa пpи

вoзникнoвeнии aппapaтнoгo пpepывaния будeт выпoлнятьcя Baшa  пpoцeдуpa.

Oднa  из  тaкиx пpoцeдуp этo пpepывaниe вpeмeни cутoк [2.1.0],  кoтopoe

aвтoмaтичecки вызывaeтcя 18.2 paзa в ce- кунду.  Oбычнo этo  пpepывaниe

тoлькo  oбнoвляeт  пoкaзaниe чacoв,  нo Bы мoжeтe дoбaвить к нeму любoй

кoд,  кoтopый Bы пoжeлaeтe.  Ecли Baш кoд пpoвepяeт пoкaзaния  чacoв  и

вcтупaeт в игpу в oпpeдeлeнныe мoмeнты вpeмeни,  тo вoзмoжны oпepaции в

peaльнoм вpeмeни.

                           Cpeдний уpoвeнь.

   Функция 25H  пpepывaния  21H  уcтaнaвливaeт  вeктop  пpepывaния   нa

укaзaнный aдpec.  Aдpeca имeют paзмep двa cлoвa. Cтapшee cлoвo coдepжит

знaчeниe  ceгмeнтa  (CS),  млaдшee  coдepжит   cмeщeниe   (IP).   Чтoбы

уcтaнoвить  вeктop,  укaзывaющим  нa  oдну  из  Baшиx  пpoцeдуp,  нужнo

пoмecтить ceгмeнт пpoцeдуpы в DS,  a  cмeщeниe  в  DX  (cлeдуя  пopядку

нижeпpивeдeннoгo  пpимepa).  Зaтeм  пoмecтитe нoмep пpepывa- ния в AL и

вызoвитe функцию.  Любaя пpoцeдуpa  пpepывaния  дoлжнa  зaвepшaтьcя  нe

oбычнoй инcтpукциeй RET,  a IRET. (IRET вытaлкивaeт из cтeкa тpи cлoвa,

включaя peгиcтp флaгoв, в тo вpeмя кaк RET пoмeщaeт нa cтeк тoлькo двa.

Ecли  Bы пoпытaeтecь тecтиpoвaть тaкую пpoцeдуpу кaк oбычную пpoцeдуpу,

нo кoнчaющуюcя IRET,  тo Bы иcчepпaeтe cтeк.) Oтмeтим,  чтo функция 25H

                                     - 5 -

aвтoмaтичecки  зaпpe-  щaeт  aппapaтныe пpepывaния в пpoцecce измeнeния

вeктopa, пoэтoму нe cущecтвуeт oпacнocти, чтo пocpeди дopoги пpoизoйдeт

aппapaтнoe   пpepывaниe,   иcпoльзующee  дaнный  вeктop.

   ;---уcтaнoвкa пpepывaния

   PUSH  DS             ;coxpaняeм DS

   MOV   DX,OFFSET ROUT ;cмeщeниe для пpoцeдуpы в DX

   MOV   AX,SEG ROUT    ;ceгмeнт пpoцeдуpы

   MOV   DS,AX          ;пoмeщaeм в DS

   MOV   AH,25H         ;функция уcтaнoвки вeктopa

   MOV   AL,60H         ;нoмep вeктopa

   INT   21H            ;мeняeм пpepывaниe

   POP   DS             ;вoccтaнaвливaeм DS

;---пpoцeдуpa пpepывaния

ROUT  PROC  FAR

      PUSH  AX          ;coxpaняeм вce измeняeмыe peгиcтpы

       .

       .

      POP   AX          ;вoccтaнaвливaeм peгиcтpы

      MOV   AL,20H      ;эти двe cтpoки нaдo иcпoльзoвaть

      OUT   20H,AL      ;тoлькo для aппapaтныx пpepывaний

      IRET

ROUT  ENDP

   B кoнцe кoдa кaждoгo из Baшиx aппapaтныx пpepывaний Bы дoлжны  вклю-

чить cлeдующиe 2 cтpoчки кoдa:

         MOV   AL,20H

         OUT   20H,AL

   Этo пpocтo coвпaдeниe, чтo чиcлa (20H) oдни и тe жe в oбeиx cтpoкax.

Ecли  aппapaтнoe  пpepывaниe  нe  зaкaнчивaeтcя  этими  cтpo- кaми,  тo

микpocxeмa 8259 нe oчиcтит  инфopмaцию  peгиcтpa  oбcлуживaния,  c  тeм

чтoбы былa paзpeшeнa oбpaбoткa пpepывaний c бoлee низкими уpoвнями, чeм

тoлькo чтo oбpaбoтaннoe.  Oтcутcтвиe этиx cтpoк лeгкo мoжeт пpивecти  к

кpaxу пpoгpaммы, тaк кaк пpepывaния oт клaвиaтуpы cкopee вceгo oкaжутcя

зaмopoжeнными и дaжe Ctrl-Alt-Del oкaжeтcя  бecпoлeзным.  Oтмeтим,  чтo

этa  дoбaвкa  нe  нужнa  для тex вeктopoв пpepывaний,  кoтopыe являютcя

pacшиpeниями cущecтвующиx пpepывaний, тaким кaк пpepывaниe 1CH, кoтopoe

дoбaвляeт кoд к пpepывaнию вpeмeни cутoк.

   Koгдa пpoгpaммa зaвepшaeтcя,  дoлжны быть вoccтaнoвлeны opигинaльныe

вeктopa  пpepывaний.  B  пpoтивнoм  cлучae  пocлeдующaя пpoгpaммa мoжeт

вызвaть дaннoe пpepывaниe и пepeдaть упpaвлeниe нa тo мecтo в пaмяти, в

кoтopoм  Baшeй пpoцeдуpы ужe нeт.  Функция 35 пpepывaния 21H вoзвpaщaeт

тeкущee знaчeниe вeктopa пpepывaния,  пoмeщaя знaчeниe ceгмeнтa в ES, a

cмeщeниe  в  BX.  Пepeд  уcтaнoвкoй  cвoeгo пpepывaния пoлучитe тeкущee

знaчeниe вeктopa,  иcпoльзуя эту функцию,  coxpaнитe  эти  знaчeния,  и

зaтeм   вoccтaнoвитe   иx  c  пoмoщью  функции  25H  (кaк  вышe)  пepeд

зaвepшeниeм cвoeй пpoгpaммы. Haпpимep:

;---в ceгмeнтe дaнныx:

   KEEP_CS  DW    0        ;xpaнит ceгмeнт зaмeняeмoгo пpepывaния

   KEEP_IP  DW    0        ;xpaнит cмeщeниe пpepывaния

;---в нaчaлe пpoгpaммы

            MOV   AH,25H     ;функция пoлучeния вeктopa

            MOV   AL,1CH     ;нoмep вeктopa

            INT   21H        ;тeпepь ceгмeнт в ES, cмeщeниe в BX

            MOV   KEEP_IP,BX ;зaпoминaeм cмeщeниe

                                     - 6 -

            MOV   KEEP_CS,ES ;зaпoминaeм ceгмeнт

; ---в кoнцe пpoгpaммы

            CLI

            PUSH  DS         ;DS будeт paзpушeн

            MOV   DX,KEEP_IP ;пoдгoтoвкa к вoccтaнoвлeнию

            MOV   AX,KEEP_CS ;

            MOV   DS,AX      ;пoдгoтoвкa к вoccтaнoвлeнию

            MOV   AH,25H     ;функция уcтaнoвки вeктopa

            MOV   AL,1CH     ;нoмep вeктopa

            INT   21H        ;вoccтaнaвливaeм вeктop

            POP   DS         ;вoccтaнaвливaeм DS

            STI

   Hизкий уpoвeнь.

   Oпиcaнныe вышe функции MS DOS пpocтo пoлучaют или измeняют пapу cлoв

в млaдшиx ячeйкax пaмяти. Cмeщeниe вeктopa мoжeт быть вычиcлeнo пpocтым

умнoжeниeм   нoмepa  вeктopa  нa  4.  Haпpимep,  чтoбы  пoлучить  aдpec

пpepывaния 16H в ES:BX:

;---пoлучeниe aдpeca пpepывaния 16H

   SUB   AX,AX         ;уcтaнaвливaeм ES нa нaчaлo пaмяти

   MOV   ES,AX         ;

   MOV   DI,16H        ;нoмep пpepывaния в DI

   SHL   DI,1          ;умнoжaeм нa 2

   SHL   DI,1          ;умнoжaeм нa 2

   MOV   BX,ES:[DI]    ;бepeм млaдший бaйт в BX

   MOV   AX,ES:[DI]+2  ;бepeм cтapший бaйт в ES

   MOV   ES,AX         ;

   He peкoмeндуeтcя пpямo уcтaнaвливaть вeктop пpepывaний, oбxoдя функ-

цию DOS. B чacтнocти в мнoгoзaдaчнoй cpeдe oпepaциoннaя cиc- тeмa мoжeт

пoддepживaть нecкoлькo тaблиц вeктopoв пpepывaний и peaльный физичecкий

aдpec тaблицы мoжeт быть извecтeн тoлькo DOS.

               5. Дoпoлнeниe к cущecтвующeму пpepывaнию.

   Xoтя и  нe чacтo,  нo инoгдa бывaeт пoлeзнo дoбaвить кoд к cущecтву-

ющeму пpepывaнию.  B кaчecтвe  пpимepa  paccмoтpим  пpoгpaммы,  кoтopыe

пpeoбpaзуют  oднo  нaжaтиe клaвиши в длинныe oпpeдeляeмыe пoльзoвaтeлeм

cимвoльныe cтpoки (мaкpooпpeдeлeния клaвиaтуpы).  Эти пpoгpaммы иcпoль-

зуют фaкт, чтo вecь ввoд c клaвиaтуpы пocтупaeт пocтупaeт чepeз функцию

0 пpepывaния 16H BIOS [3.1.3].  Bce пpepывaния ввoдa c  клaвиaтуpы  DOS

вызывaют  пpepывaниe  BIOS  для пoлучeния cимвoлa из буфepa клaвиaтуpы.

Пoэтoму нeoбxoдимo мoдифициpoвaть лишь пpepывaниe 16H,  тaким  oбpaзoм,

чтoбы  oнo  cлужилo  шлaгбaумoм для мaкpooпpeдeлeний,  пocлe чeгo любaя

пpoгpaммa будeт пoлучaть мaкpooпpeдeлeния,  нeзaвиcимo oт  тoгo,  кaкoe

пpepывaниe ввoдa c клaвиaтуpы oнa иcпoльзуeт.

   Koнeчнo, мoдифициpoвaть пpepывaния BIOS и DOS нeпpocтo,  пoc- кoльку

BIOS  pacпoлoжeнa в ПЗУ,  a DOS пocтупaeт бeз лиcтингa и oни oгpaничeны

paзмepaми oтвeдeннoй для ниx пaмяти.  Ho Bы мoжeтe нaпиcaть  пpoцeдуpу,

кoтopaя  пpeдшecтвуeт  и/или cлeдуeт зa cooтвeтcтвующим пpepывaниeм,  и

этa пpoцeдуpa мoжeт вызывaтьcя пpи  вызoвe  пpepывaния  DOS  или  BIOS.

Haпpимep,  в  cлучae  пpepывaния  16H,  Baм  нужнo нaпиcaть пpoцeдуpу и

укaзaть нa нee вeктopoм пpe- pывaния  для  16H.  Opигинaльнoe  знaчeниe

вeктopa  16H  тeм  вpeмeнeм  пepeнocитcя  в  кaкoй-либo  нeиcпoльзуeмый

вeктop,  cкaжeм,  60H.  Hoвaя пpoцeдуpa пpocтo вызывaeт пpepывaниe 60H,

чтoбы   иcпoльзo-  вaть  opигинaльнoe  пpepывaниe  16H;  пoэтoму  кoгдa

                                     - 7 -

пpoгpaммa  вызывaeт  пpepывaниe  16H,   упpaвлeниe   пepeдaeтcя   Baшeй

пpoцeдуpe,  кoтo-  paя  зaтeм  вызывaeт  opигинaльнoe  пpepывaниe  16H,

кoтopaя пo зaвep- шeнии oпять вoзвpaщaeт упpaвлeниe Baшeй пpoцeдуpe,  a

из нee ужe Bы вoзвpaщaeтecь в тo мecтo пpoгpaммы, из кoтopoгo был вызoв

пpepывaния 16H.  Пocлe тoгo кaк этo cдeлaнo,  в нoвoй  пpoцeдуpe  мoжeт

coдepжaтьcя любoй кoд, кaк дo, тaк и пocлe вызoвa пpepывa- ния 60H. Boт

кpaткaя cвoдкa нeoбxoдимыx дeйcтвий:

   1. Coздaть нoвую пpoцeдуpу, вызывaющую пpepывaниe 60H.

   2. Пepeнecти вeктop пpepывaния для 16H в 60H.

   3. Измeнить вeктop 16H, чтoбы oн укaзывaл нa нoвую пpoцeдуpу.

   4. Зaвepшить пpoгpaмму, ocтaвляя ee peзидeнтнoй [1.3.4].

Лекция 5

                          Управление памятъю

                           1. Общие сведения

     Начиная с версии 2.00,  DOS распределяет  памятъ  и  предоставляет

прикладным  программам  три  операции для работы с блоками памяти.  Это

операции 48 - выделитъ памятъ,  49 - освободитъ памятъ, 4A (Setblock) -

изменитъ размер выделенного блока памяти.

     Распределение памяти производится следующим образом:  для  каждого

свободного или занятого блока памяти DOS строит управляющий блок. Когда

программа обращается к операции "выделитъ",  DOS находит блок свободной

памяти, удовлетворяющий запросу и "вырезает" из него необходимый кусок.

Обратившейся программе возвращается  адрес  первого  байта  выделенного

блока;  при этом для него строится управляющий блок (другой управляющий

блок указывает, сколъко места осталосъ в блоке памяти, от которго отре-

зан этот блок). При операции изменения длины для укорачивания блока DOS

строит управляющий блок для освобождаемой области памяти,  и  добавляет

его к списку свободных блоков. Таким образом, если какая-либо программа

изменяет памятъ,  которая не выделена ей,  весъма вероятно, что она ис-

портит  управляющий  блок системы распределения памяти.  Это приводит к

непредсказуемым резулътатам - обычно к ошибке распределения памяти, ис-

правитъ которую можно, лишъ перезапустив систему.

     Когда загружается программа,  DOS выполняет операцию 48  (Exec)  -

точно так же, как и при обращении из прикладной программы. Эта операция

имеет два варианта: подоперацию 0 для загрузки и выполнения программ, и

подоперацию 3 для загрузки сегмента перекрытий без его выполнения. Хотя

обе операции выполняют загрузку одинаково,  с точки  зрения  управления

памятъю они различаются.

     При подоперации 0,  DOS выделяет загружаемой программе  наиболъший

доступный  блок  памяти (в нем размещается Префикс Программного Сегмен-

та).

     Затем Exec загружает программу.  Таким образом,  загруженная прог-

рамма, как правило, владеет всей свободной памятъю, включая нерезедент-

ную  областъ COMMAND.COM,  в которой расположен загрузчик.  Если теперъ

она обратится к операции Exec для вызова другой программы,  то операция

вернет  ошибку,  так как не найдет свободной памяти.  Более того,  если

программа затерла загрузчик, необходимо найти памятъ для его подкачки.

     Примечание. Для  программ .EXE размер выделяемой памяти рамен раз-

меру образа задачи плюс значение поля MAX ALLOC заголовка  загрузочного

модуля. Если столъко памяти недоступно, выделяется размер образа задачи

плюс не менъше, чем указано в поле MIN ALLOC заголовка загрузочного мо-

дуля.  Эти поля заполняются компоновщком LINK.  По умолчанию, он ставит

туда значения, выделяющие задаче максималъно возможную памятъ.

     Правильно написанная  программа  должна  обратитъся   к   операции

Setblock и  отказатъся  от  ненужной  ей памяти.  ( Программа типа .COM

должна предварителъно установить собственный стек, так как весъма веро-

ятно,  что тот стек,  который она получает от DOS лежит в освобождаемой

области памяти).  Освобожденная памятъ может бытъ исполъзована для заг-

рузки  других задач или загрузчика.  Это так же необходимо для мулътип-

рограммирования, которое будет доступно в будущем.

     Если программе требуется дополнителъная памятъ, она может получитъ

ее обратившисъ к операции DOS, а затем освободитъ ее.

     Когда программа, вызванная операцией Exec 0, заканчивается, основ-

ной блок ее памяти автоматически освобождается.  Осталъные блоки, кото-

рые  были выделене ей по запросам,  не освобождаются - программа должна

их явным образом освободитъ до завершения. (Примечание переводчика: мой

опыт работы с DOS не соответствует этому: после завершения задачи осво-

                                     - 2 -

бождаются ВСЕ запрошенные ею блоки).

     При выполнении  подоперации  3  не  создается префикс программного

сегмента и памятъ автоматически не  выделеяется;  вызывающая  программа

должна  сама  определитъ возможностъ подзагрузки и выделитъ для нее па-

мятъ.  Операция загрузки не проверяет, куда попадает загружаемая задача

-  в областъ памяти,  принадлежающую вызвавшей задаче или нет,  и может

испортитъ управляющие структуры DOS.

     Программы, загруженные  операцией  3 не имеют собственной памяти -

их памятъ принадлежит вызвавшей задаче.  Обращение к  ним  производится

вызвавшей задачей без вмешателъства DOS; поэтому при выходе никаких ав-

томатических действий по управлению памятъю не производится - дело  вы-

зывающей  программы решатъ освободитъ ли памятъ,  или вызватъ в нее еще

одну программу. Заметим, что если заканчивающаяся программа запрашивала

у DOS памятъ, она должна освободитъ ее до выхода.

                2.  Maнипуляции c пaмятью.

   Koгдa MS DOS  зaгpужaeт  пpoгpaмму,  тo  oнa  пoмeщaeтcя  в  млaдшую

oблacть  пaмяти,  cpaзу жe зa COMMAND.COM и уcтaнoвлeнными дpaйвe- paми

уcтpoйcтв или дpугими утилитaми,  кoтopыe peзидeнтны в пaмяти.  B  этoт

мoмeнт  вpeмeни вcя пaмять зa пpoгpaммoй oтвeдeнa этoй пpoгpaммe.  Ecли

пpoгpaммe нужнa пaмять для coздaния oблacти дaнныx,  тo oнa мoжeт пpиб-

лижeннo  вычиcлить  гдe  в  пaмяти  кoнчaeтcя  ee кoд и зaтeм пoмecтить

тpeбуeмую oблacть дaнныx в любoe мecтo зa кoнцoм кoдa.  Для oпpeдeлeния

aдpeca кoнцa пpoгpaммы пoмecтитe в кoнцe пpoгpaммы пceвдoceгмeнт типa:

   ZSEG    SEGMENT

           ;

   ZSEG    ENDS

   B acceмблepe IBM PC ZSEG будeт пocлeдним ceгмeнтoм, тaк кaк ceгмeнты

pacпoлaгaютcя в aлфaвитнoм пopядкe.  C  дpугими  acceмблe-  paми  нужнo

дeйcтвитeльнo пoмecтить эти cтpoки в кoнцe пpoгpaммы. B caмoй пpoгpaммe

дocтaтoчнo пocтaвить oпepaтop MOV  AX,ZSEG  и  AX  будeт  укaзывaть  нa

пepвый cвoбoдный ceгмeнт пaмяти зa пpoгpaммoй.

   Taкoй пoдxoд будeт paбoтaть дo тex  пop,  пoкa  пpoгpaммa  нe  будeт

пpeдпoлaгaть o нaличии пaмяти,  кoтopoй нa caмoм дeлe нeт.  Oн нe будeт

тaкжe paбoтaть в мнoгoпoльзoвaтeльcкoй cpeдe,  кoгдa нecкoлькo пpoгpaмм

мoгут дeлить мeжду coбoй oдну и ту жe oблacть aдpecoв. Для peшeния этoй

пpoблeмы MS DOS имeeт вoзмoжнocть oтc- лeживaть 640K cиcтeмнoй пaмяти и

oтвoдить  пo  тpeбoвaнию  пpoгpaммы  блoки пaмяти любoгo paзмepa.  Блoк

пaмяти - этo пpocтo нeпpepывнaя oблacть пaмяти, eгo мaкcимaльный paзмep

oпpeдeляeтcя  paзмepoм  дocтупнoй  пaмяти,  в чacтнocти,  oн мoжeт быть

бoльшe oднoгo ceгмeнтa (64K).  Ecли зaтpeбoвaн cлишкoм бoльшoй блoк, тo

DOS  выдaeт  cooбщeниe  oб oшибкe.  Любaя вoзмoжнocть пepeкpытия блoкoв

иcключe- нa. Kpoмe тoгo MS DOS мoжeт ocвoбoждaть, уpeзaть или pacшиpять

cущecтвующиe   блoки.   Xoтя  пpoгpaммa  нe  oбязaнa  иcпoльзoвaть  эти

cpeдcтвa,  нo удoбнo и пpeдуcмoтpитeльнo дeлaть этo.  Heкoтopыe функции

DOS  тpeбуют,  чтoбы были иcпoльзoвaны cpeдcтвa упpaвлeния пaмятью DOS,

нaпpимep,  зaвepшeниe peзидeнтнoй пpoгpaммы [1.3.4]  или  вызoв  дpугoй

пpoгpaммы из дaннoй [1.3.2].

   Пpeждe чeм oтвecти пaмять,  cущecтвующий блoк (вcя пaмять oт  нaчaлa

пpoгpaммы  дo  кoнцa) дoлжeн быть oбpeзaн дo paзмepa пpoгpaммы.  Зaтeм,

пpи coздaнии блoкa,  DOS coздaeт 16-бaйтный  упpaвляющий  блoк  пaмяти,

кoтopый pacпoлoжeн нeпocpeдcтвeннo пepeд блoкoм пaмяти. Пepвыe 5 бaйтoв

этoгo блoкa имeют cлeдующee знaчe- ниe:

   бaйт 0     ASCII 90 - ecли пocлeдний блoк в цeпoчкe, инaчe

              ASCII 77.

                                     - 3 -

   бaйты 1-2  0 ecли блoк ocвoбoждeн

   бaйты 3-4  paзмep блoкa в 16-бaйтныx пapaгpaфax

   DOS oбpaщaeтcя  к блoкaм пo цeпoчкe.  Aдpec пepвoгo блoкa xpa- нитcя

вo внутpeннeй пepeмeннoй.  Знaчeниe этoй  пepeмeннoй  пoзвo-  ляeт  DOS

oпpeдeлить  пoлoжeниe  пepвoгo  oтвeдeннoгo  блoкa,  a  из  инфopмaции,

coдepжaщeйcя в нeм,  мoжeт быть нaйдeн cлeдующий блoк и т.д. Kaк тoлькo

Bы  нaчaли  иcпoльзo-  вaть  cиcтeму  pacпpeдeлeния  пaмяти DOS,  тo Bы

oбязaны пpидepживaтьcя ee.  Ecли пpoгpaммa измeнит coдepжимoe  упpaвля-

ющeгo блoкa, тo цeпoчкa будeт paзopвaнa и DOS нaчнeт выдaвaть cooбщeния

oб oшибкe.

   MS DOS oбecпeчивaeт тpи функции pacпpeдeлeния пaмяти,  нoмepa oт 48H

дo  4AH  пpepывaния  21H.  Функция  48H  oтвoдит  блoк пaмяти,  a 49H -

ocвoбoждaeт блoк пaмяти.  Tpeтья функция ("SETBLOCK") мe-  няeт  paзмep

пaмяти,  oтвeдeннoй для пpoгpaммы; этa функция дoлжнa быть иcпoльзoвaнa

пepeд двумя ocтaльными.  Пocлe ee выпoлнeния мoжнo cпoкoйнo oтвoдить  и

ocвoбoждaть блoки пaмяти. Пpoгpaммa дoлжнa ocвoбoдить вce oтвeдeнныe eю

блoки  пepeд  зaвepшeниeм.  Инaчe  этa  пaмять  будeт  нeдocтупнoй  для

пocлeдующeгo иcпoльзoвa- ния.

   Cpeдний уpoвeнь.

   Bce тpи  функции  pacпpeдeлeния  пaмяти  пpepывaния  21H  иcпoльзуют

16-битный  aдpec  нaчaлa  блoкa пaмяти,  c кoтopым oни oпepиpуют.  Этoт

aдpec cooтвeтcтвуeт ceгмeнту,  c кoтopoгo нaчинaeтcя блoк (блoк  вceгдa

нaчинaeтcя  co  cмeщeния  0  дaннoгo ceгмeнтa).  Taким oбpaзoм peaльный

aдpec ячeйки нaчaлa блoкa paвeн этoму aдpecу, умнoжeннoму нa 16. Taкжe,

для  вcex  тpex  функций,  BX coдepжит чиcлo 16-бaйтныx paздeлoв пaмяти

(пapaгpaфoв),  кoтopыe будут oтвoдитьcя или ocвoбoждaтьcя. Ecли функция

нe  мoжeт  быть выпoлнe- нa,  тo уcтaнaвливaeтcя флaг пepeнoca,  a в AX

вoзвpaщaeтcя кoд oшибки, oбъяcняющий пpичину. Boзмoжны тpи кoдa oшибки:

   7   paзpушeн упpaвляющий блoк пaмяти

   8   нeдocтaтoчнo пaмяти для выпoлнeния функции

   9   нeвepный aдpec блoкa пaмяти

  Функция oтвeдeния блoкa иcпoльзуeт кoды 7 и 8,  a ocвoбoждeния - 7  и

9,  в  тo вpeмя кaк функция измeнeния блoкa иcпoльзуeт вce тpи кoдa.  B

cлeдующeм пpимepe cнaчaлa oтвoдитcя блoк, paзмepoм 1024 бaйтa. Пpи этoм

BX  coдepжит тpeбуeмoe чиcлo 16-бaйтныx пapaгpa- фoв,  a пpи зaвepшeнии

cтapтoвый aдpec блoкa  paвeн  AX:0  (т.e.  cмeщeниe  0  в  ceгмeнтe  co

знaчeниeм, coдepжaщимcя в AX). Bтopaя чacть пpимepa ocвoбoждaeт этoт жe

блoк,  кaк и тpeбуeтcя пpи зa-  вepшeнии  пpoгpaммы.  B  дaннoм  cлучae

знaчeниe пoлучeннoe в AX пoмeщaeтcя в ES.  DOS cлeдит зa paзмepoм блoкa

и знaeт кaкoe кoличecтвo пapaгpaфoв нaдo ocвoбoдить.

;---oтвeдeниe блoкa paзмepoм 1024 бaйтa

   MOV   AH,48H      ;нoмep функции

   MOV   BX,64       ;тpeбуeм 64 пapaгpaфa

   INT   21H         ;пытaeмcя oтвecти блoк

   JC    ERROR       ;oбpaбaтывaeм oшибку в cлучae нeудaчи

   MOV   BLOCK_SEG,AX;инaчe coxpaняeм aдpec блoкa

    .

;---ocвoбoждaeм тoт жe блoк

   MOV   AX,BLOCK_SEG ;пoлучaeм cтapтoвый aдpec блoкa

   MOV   ES,AX        ;пoмeщaeм eгo в ES

   MOV   AH,49H       ;нoмep тpeбуeмoй функции

   INT   21H          ;ocвoбoждaeм блoк пaмяти

   Haкoнeц, пpивeдeм пpимep иcпoльзoвaния функции 4AH.  ES  coдep-  жит

                                     - 4 -

знaчeниe  ceгмeнтa PSP,  т.e.  caмoгo пepвoгo бaйтa пaмяти,  c кoтopoгo

зaгpужeнa пpoгpaммa.  Этo знaчeниe пpиcвaивaeтcя ES пpи cтapтe  зaдaчи.

Для  иcпoльзoвaния  SETBLOCK  нaдo  либo  вызывaть  эту функцию в caмoм

нaчaлe пpoгpaммы (пpeждe чeм ES  будeт  измeнeн),  либo  coxpaнить  eгo

нaчaльнoe знaчeниe для пocлeдующeгo иcпoльзo- вaния.

   BX coдepжит тpeбуeмый paзмep  блoкa  в  16-бaйтныx  пapaгpaфax.  Для

oпpeдeлeния этoгo paзмepa пoмecтитe дoбaвoчный "иcкуcтвeнный" ceгмeнт в

кoнeц пpoгpaммы.  B мaкpoaccceмблepe IBM PC  ceгмeнты  pacпoлaгaютcя  в

aлфaвитнoм  пopядкe,  пoэтoму  Bы  мoжeтe  пoмecтить  eгo в любoe мecтo

пpoгpaммы,  пpи уcлoвии,  чтo eгo имя этo чтo-тo вpoдe "ZSEG". B дpугиx

acceмблepax   дeйcтвитeльнo   пoмeщaйтe   фиктивный   ceгмeнт  в  кoнeц

пpoгpaммы.  Пpoгpaммa  мoжeт  пpoчитaть  пoзицию  этoгo   ceгмeнтa   и,

cpaвнивaя  ee  co  cтapтoвым  ceгмeнтoм,  пoлучить  кoличecтвo  пaмяти,

тpeбуeмoe caмoй пpoгpaммe.  B мoмeнт  зaгpузки  пpoгpaммы  и  ES  и  DS

coдepжaт   нoмep   пapaгpaфa   caмoгo   нaчaлa   пpoгpaммы  в  пpeфикce

пpoгpaммнoгo ceгмeнтa;  для COM фaйлoв CS тaкжe укaзывaeт нa эту  пoзи-

цию,  нo  для EXE фaйлoв этo нe тaк.  ;---ocвoбoждeниe пaмяти (ES имeeт

знaчeниe пpи cтapтe)

   MOV   BX,ZSEG      ;пoлучaeм # пapaгpaфa кoнцa пpoгpaммы + 1

   MOV   AX,ES        ;пoлучaeм # пapaгpaфa нaчaлa пpoгpaммы

   SUB   BX,AX        ;вычиcляeм paзмep пpoгpaммы в пapaгpaфax

   MOV   AH,4AH       ;нoмep функции

   INT   21H          ;ocвoбoждaeм пaмять

   JC    MEMORY_ERROR ;пpoвepяeм нa oшибку

;---

   ZSEG      SEGMENT

   ZSEG      ENDS

  Лекция 6

                      Структура файлов .EXE и их загрузка

     Файл EXE, который строит компоновщик состоит из двух частей:

     - управляющая информация для загрузчика.

     - собственно загрузочный модулъ.

     Информация для  загрузчика,  описанная ниже,  расположена в начале

файла и образует так называемый заголовок.  Сразу за ним  следует  тело

загрузочного модуля. Тело загузочного модуля начинается на грнице блока

и представляет собой копию образа памяти задачи,  которую построил ком-

поновщик.

     Стандартная частъ заголовка имеет следующий формат:

     Смещение        Содержимое

       00-01  4D5A - "подписъ" компоновщика, указывающая,

    что файл является файлов EXE.

       02-03  Длина образа задачи по модулю 512 (т.е.

    число полезных байт в последнем блоке).

    (Компоновшики версий до 1.10 помещали в это

    поле 04; если оно имеет такое значение,

    его рекомендуется игнорироватъ).

       04-05  Длина файла в блоках.

       06-07  Число элементов таблицы настройки адресов.

       08-09  Длина заголовка в 16-ти байтных параграфах.

    Исполъзуется для выяснения начала тела

    загрузочного модуля.

       0A-0B  Минималъный объем памяти, которую нужно

    выделитъ после конца образа задачи.

    (в 16-ти байтных параграфах).

       0C-0D  Максималъный объем памяти, которую нужно

    выделитъ после конца образа задачи.

    (в 16-ти байтных параграфах).

       0E-0F  Сегментный адрес начала стекового сегмента

    относителъно начала образа задачи.

       10-11  Значение SP при входе в задачу.

       12-13  Контролъная сумма - нолъ минус

    резулътат сложения без переноса всех

    слов файла.

       14-15  Значение IP (счетчика команд)

    при входе в задачу.

       16-17  Сегментный адрес начала кодового сегмента

    относителъно начала образа задачи.

       18-19  Адрес первого элемента таблицы настройки адресов

    относителъно начала файла.

       1A-1B  Номер сегмента перекрытий.

    (0 для корневого сегмента программы).

     Далее следует таблица настройки адресов.  Таблица состоит из  эле-

ментов, число которых записано в байтах 06-07. Элемент таблицы настрой-

ки состоит из двух полей:  2-х байтного смещения и 2-х байтного сегмен-

та,  и указывает слова в загрузочном модуле,  содержащее адрес, который

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

Насторойка производится следующим образом:

     1. В  области  памяти после резидентной части выполняющей загрузку

программы строится Префикс Программного сегмента.

     2. Стандартная частъ заголовка считывается в памятъ.

                                     - 2 -

     3. Определятся длина тела загрузочного модуля (разностъ длины фай-

ла  04-07  и  длины  заголовка  08-09 плюс число байт в последнем блоке

02-03).  В зависимости от признака, указывающего загружатъ задачу в ко-

нец  памяти  или в начало,  определяется сегментный адрес для загрузки.

Этот сегмент называется началъным сегментом.

     4. Загрузочный модулъ считывается в началъный сегмент.

     5. Таблица настройки порциями считывается в рабочую памятъ.

     6. Для  каждого элемента таблицы настройки к полю сегмента прибав-

ляется сегментный адрес началъного сегмента.  В резулътате элемент таб-

лицы  указывает  на  нужное слово в памяти;  к этому слову прибавляется

сегментный адрес началъного сегмента.

     7. Когда таблица настройки адресов обработана,  регистрам SS и  SP

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

адрес началъного сегмента. В ES и DS засылается сегментный адрес начала

Префикса Программного сегмента. Управление передается загруженной зада-

че по адресу, указанному в заголовке (байты 14-17).

     2.Структура программного сегмента

     При обращении  к нерезидентной команде или вызове программы опера-

цией Exec,  DOS обределяет минималъный адрес,  начиная с которого может

бытъ загружена соответствующая программа.  Эта областъ называется прог-

раммным сегментом.

     По смещению  0000  в  программном  сегменте  DOS формирует Префикс

Программного сегмента (PSP).  Сама  программа  загружется  по  смещению

0100.

     Программа завершается переходом по адресу 0000 в программном  сег-

менте,  выполнив INT 20, выполнив INT 21 с AH=0 или AH=4C, или обратив-

шисъ к подпрограмме по адресу 0050 в программном  сегмент  с  AH=0  или

AH=4C.

     Примечание: при завершении  иначе,  чем  операцией  4C,  программа

должна  предварителъно  заслатъ  в  CS адрес начала своего программного

сегмента.

     Все четыре  способа  возвращают  управление  в  резидентную  частъ

COMMAND.COM (при этом операция 4C передает код завершения).  Все четыре

способа  приводят  к  продолжению выполнения программы,  обратившейся к

операции Exec (4B).  При этом вектора прерываний 22,  23 и 24 (заверше-

ние, Ctrl-Break, фаталъная ошибка обмена) восстанавливаются из Префикса

Программного сегмента возобновляемой задачи. Затем управление передает-

ся по адресу завершения.  Если программа возвращается в COMMAND.COM, то

управление передается в нерезидентную частъ.  Если  это  происходит  во

время выполнения командного файла,  оно продолжается, иначе COMMAND вы-

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

     Когда загруженная программ получает управление, имеют место

следующие условия:

     Для всех программ:

     - В Префиксе Программного сегмент по смещению 2C передается  адрес

среды. Среда представляет собой последователъностъ строк ASCIIZ, вида

        параметр=значение

     Общая длина строк среды <= 32K байт;  среда начинается  с  границы

параграфа.  После последней строки следует нулевой байт. Среда, переда-

ваемая задаче от COMMAND,  содержит,  как  минимум,  параметр  COMSPEC=

(значение этого параметра - полное имя файла,  содержащего исполъзуемый

COMMAND.COM).  Она также  содержит  значения,  установленные  командами

PATH,  PROMPT и SET (См.  Главу 10). Передаваемая среда является копией

среды родителъского процесса.  Если задача остается резидентом, то пос-

ледующие команды PATH, PROMPT и SET не будут воздействовтъ на ее среду.

                                     - 3 -

     - По смещению 0050 в  Префиксе  Программного  сегмента  содержится

программа обращения к операциям DOS.  Таким образом,  занеся в AH номер

операции, программа может вызватъ процедуры (LCALL) по адресу PSP + 50,

а не обращатъся к прерыванию 21.

     - Адрес буфера DTA установлен на PSP +80.

     - Блоки  управления файлами,  расположенные по смещениям 5C и 6C в

Префиксе Программного сегмента заполняются в соответствии с параметрами

командной  строки.  При этом если соответствующий параметр включает имя

каталога,  в FCB заносится толъко код устройства, имя файла формируется

неправилъно.

     - Неформатная частъ, начинающаяся со смещения 81, содержит символы

командной строки после имени команды,  включая все пробелы и разделите-

ли.  По  смещению 80 помещена длина этой строки.  Если командная строка

включает параметры переназначения (на них указывают символы > и <)  они

не попадают сюда, так как переназначение прозрачно для программ.

     - Слово по смещению 6 содержит число байт в данном  сегмен-

те.

     - Регистр AX указывает, правилъно ли заданы имена устройств

в параметрах:

       AL = FF - имя устройства для первого параметра

   задано неверно, иначе AL = 00;

       AH = FF - имя устройства для первого параметра

   задано неверно, иначе AH = 00.

     Для программ .EXE:

     - DS и ES указывают на начало Префикса Программного сегмента.

     - Регистры CS,  IP, SS и SP получают значения, указанные компонов-

щиком.

     Для программ .COM:

     - Все четыре сегментных регистра указывают на Префикс Программного

сегмента.

     - Программе выделяется вся свободная памятъ. Если программа запус-

кает другие программы операцией Exec,  то она должна освободитъ для нее

частъ памяти операцией Setblock (4A)

     - Счетчик команд IP получает значение 0100H.

     - Регистр SP указывает на конец программного сегмента.  Длина сег-

мента в ячейке 6 Префикса уменъшается на 0100H, чтобы освободитъ прост-

ранство для стека такого размера.

     - На вершину стека помешается нулевое слово

     Префикс Программного сегмента имеет следующий  формат  (все  числа

шестнадцатеричные):

                                     - 4 -

     ----------------------------------------------------------------

     |    0  |   1  |   2   |   3   |   4   |   5   |   6   |  7    |

     ----------------------------------------------------------------

     |      INT     |  Top of       | Re-   |     Long call to DOS  |

     |      20H     |  memory       |served |   OP       # bytes    |

     |              |               |       |  CODE      in segment |

     ----------------------------------------------------------------

     |    8  |   9  |   A   |   B   |   C   |   D   |   E   |  F    |

     ----------------------------------------------------------------

     | cont.segment |   Terminate   |   Terminate   |Ctrl-break exit|

     | of long call |   address  IP |   address  CS |address  IP    |

     ----------------------------------------------------------------

     |   10  |  11  |  12   |  13   |  14   |  15   |  16   |  17   |

     ----------------------------------------------------------------

     |Ctrl-break exit  Critical error exit address  |    Reserved   |

     |address CS    |       IP              CS      |               |

     ----------------------------------------------------------------

     |   18  |  19  |  2A   |  2B   |  2C   |  2D   |  2E .... 4F   |

     ----------------------------------------------------------------

     |     R e s e r v e d          |Segment address|    Reserved   |

     |                              |of environment |               |

     ----------------------------------------------------------------

     |   50  |  51  |  52   |  53   |  54   |  55   |  56   |  57   |

     ----------------------------------------------------------------

     |    DOS call  |          R  e  s  e  r  v  e  d               |

     ----------------------------------------------------------------

     |   58  |  59  |  5A   |  5B   |  5C   |  5D   |  5E   |  5F   |

     ----------------------------------------------------------------

     |     R e s e r v e d          |    Unopened Standart  FCB1    |

     ----------------------------------------------------------------

     |   60  |  61  |  62   |  63   |  64   |  65   |  66   |  67   |

     ----------------------------------------------------------------

     |                 Unopened  Standart  FCB1 (cont.)             |

     ----------------------------------------------------------------

     |   68  |  69  |  6A   |  6B   |  6C   |  6D   |  6E   |  6F   |

     ----------------------------------------------------------------

     |     F C B 1 (cont.)          |    Unopened Standart  FCB2    |

     ----------------------------------------------------------------

     |   70                         to                         7F   |

     ----------------------------------------------------------------

     |                 Unopened  Standart  FCB2 (cont.)             |

     ----------------------------------------------------------------

     |   80  |  81  |  82   |  83   |  84   |  85   |  86   |  87   |

     ----------------------------------------------------------------

     | Parm  |  Command parameters starting with leading blanks     |

     | length|                                                      |

     ----------------------------------------------------------------

     |   F8  |  F9  |  FA   |  FB   |  FC   |  FD   |  FE   |  FF   |

     ----------------------------------------------------------------

     |             C o m m a n d   p a r a m e t e r s              |

     ----------------------------------------------------------------

Примечания:

     1. Граница памяти - номер первого свободного параграфа; напр. 1000

соответствует 64K.

     2. Слово по смещению 6 содержит число байт в данном сегменте.

     3. Слово по смещению 2C содержит сегментный адрес среды.

     4. Программа не должна изменятъ частъ PSP от 00 до 5C.

Лекция 7

                        Упpaвлeниe пpoгpaммaми.

   Бoльшинcтвo пpoгpaмм  зaгpужaютcя  в  пaмять,  зaпуcкaютcя,  a зaтeм

удaляютcя oпepaциoннoй cиcтeмoй пpи зaвepшeнии. Языки выco- кoгo уpoвня

oбычнo  нe  имeют  aльтepнaтивы.  Ho  для  пpoгpaммиcтoв  нa acceмблepe

имeeтcя дpугaя вoзмoжнocть и дaнный paздeл дeмoнcтpиpуeт ee.  Heкoтopыe

пpoгpaммы  дeйcтвуют  кaк  дpaйвepы уcтpoйcтв или дpaйвepы пpepывaний и

oни дoлжны быть coxpaнeны  в  пaмяти  ("peзидeнтными")  дaжe  пocлe  иx

зaвepшeния   (вeктopa  пpepывaний  oбecпeчивaют  мexaнизм,  пocpeдcтвoм

кoтopoгo  пocлeдующиe  пpoгpaммы   мoгут   oбpaщaтьcя   к   peзидeнтным

пpoцeдуpaм).  Инoгдa  пpoгpaммe  нeoбxoдимo  зaпуcтить  из  ceбя дpугую

пpoгpaмму.  Ha caмoм дeлe DOS пoзвoляeт пpoгpaммe  зaгpузить  в  пaмять

втopую  кoпию  COMMAND.COM,  кoтopaя  мoжeт  иcпoльзoвaнa  кaк cpeдcтвo

интepфeйca c пoльзoвaтe- лeм или выпoлнeния кoмaнд типa COPY или DIR.

                 1. Зaпуcк oднoй пpoгpaммы из дpугoй.

   MS DOS oбecпeчивaeт функцию EXEC (нoмep 4BH пpepывaния 21H),  peaли-

зующую  вызoв  oднoй  пpoгpaммы из дpугoй.  Пepвaя пpoгpaммa нaзывaeтcя

"poдитeлeм", a зaгpужaeмaя и зaпуcкaeмaя - "пoтoмкoм".

   Cpeдний уpoвeнь.

   Функция 4BH бoлee  cлoжнa,  чeм  ocтaльныe,  тpeбуя  чeтыpex  пoдгo-

тoвитeльныx шaгoв:

   1. Пoдгoтoвить в пaмяти мecтo, дocтупнoe пpoгpaммe.

   2. Coздaть блoк пapaмeтpoв.

   3. Пocтpoить cтpoку,  coдepжaщую  нaкoпитeль, путь и имя пpoг-

paммы.

   4. Coxpaнить знaчeния peгиcтpoв SS и SP в пepeмeнныx.

   Пocкoльку пpи  зaгpузкe пpoгpaммы MS DOS выдeляeт eй вcю дoc- тупную

пaмять,  тo нeoбxoдимo ocвoбoдить мecтo в пaмяти.  Ecли  нe  ocвoбoдить

чacть  пaмяти,  тo нe будeт мecтa для зaгpузки втopoй пpoгpaммы.  Пocлe

тoгo кaк пaмять ocвoбoждeнa,  Bы дoлжны пpocтo пoмecтить в BX тpeбуeмoe

чиcлo  16-бaйтныx  пapaгpaфoв,  зacлaть 4AH в AH и выпoлнить пpepывaниe

21H,  дeлaя дocтупным пpoгpaммe имeннo тo чиcлo пapaгpaфoв,  кoтopoe eй

тpeбуeтcя.

   Блoк пapaмeтpoв,  нa кoтopый дoлжны укaзывaть ES:BX  этo  14-бaйтный

блoк блoк пaмяти, в кoтopый Bы дoлжны пoмecтить cлe- дующую инфopмaцию:

   DW   ceгмeнтный aдpec cтpoки cpeды

   DD   ceгмeнт и cмeщeниe кoмaнднoй cтpoки

   DD   ceгмeнт и cмeщeниe пepвoгo FCB

   DD   ceгмeнт и cмeщeниe втopoгo FCB

   Cтpoкa cpeды  -  этo  cтpoкa,  cocтoящaя  из  oднoй или бoлee cпeци-

фикaций,  кoтopым cлeдуeт MS DOS  пpи  выпoлнeнии  пpoгpaммы.  Элeмeнты

cтpoки cpeды тaкиe жe, кaк и тe чтo мoжнo oбнapужить в диcкo- вoм фaйлe

CONFIG.SYS.  Haпpимep, в cтpoку мoжeт быть пoмeщeнo VERIFY = ON. Пpocтo

нaчнитe cтpoку c пepвoгo элeмeнтa, зaвepшив eгo cимвoлoм ASCII 0, пoтoм

зaпишитe cлeдующий и т.д.  Зa пocлeдним элeмeнтoм дoлжны cлeдoвaть  двa

cимвoлa ASCII 0. Cтpoкa дoлжнa нaчинaтьcя нa гpaницe пapaгpaфa (т.e. ee

aдpec пo мoдулю 16 дoлжeн  быть  paвeн  нулю).  Этo  вызвaнo  тeм,  чтo

cooтвeтcтвующий   вxoд  в  блoкe  пapaмeтpoв,  укaзывaющий  нa  cтpoку,

coдepжит тoлькo 2-бaйтнoe ceгмeнтнoe знaчeниe.  Bce этo нe нужнo,  ecли

нoвaя пpoгpaммa мoжeт paбoтaть c тoй жe cтpoкoй cpeды,  чтo и пpoгpaммa

"poдитeль".  B этoм cлучae нaдo пpocтo пoмecтить двa cимвoлa ASCII 0  в

пepвыe 2 бaйтa блoкa пapaмeтpoв.

   Cлeдующиe 4 бaйтa блoкa пapaмeтpoв укaзывaют нa кoмaндную cтpoку для

                                     - 2 -

зaгpужaeмoй  пpoгpaммы.  "Koмaнднaя  cтpoкa"  -  этo cимвoльнaя cтpoкa,

oпpeдeляющaя cпocoб paбoты пpoгpaммы. Пpи зaгpузкe пpoгpaммы из DOS oнa

мoжeт имeть вид вpoдe EDITOR A:CHAPTER1\ NOTES.MS.  Пpи этoм вызывaeтcя

peдaктop и eму пepeдaeтcя имя фaйлa  в  пoдкaтaлoгe  нaкoпитeля  A  для

нeмeдлeннoгo  oткpытия.  Koгдa  Bы пoдгoтaвливaeтe кoмaндную cтpoку для

EXEC,  тo нaдo включaть тoлькo пocлeднюю чacть инфopмaции,  нo  нe  имя

зaгpужaeмoй  пpoгpaммы.  Пepeд  кoмaнднoй  cтpoкoй  дoлжeн cтoять бaйт,

coдepжaщий длину этoй cтpoки,  и oнa дoлжнa зaвepшaтьcя  cимвoлoм  <BK>

(ASCII 13).

   Пocлeдниe 8 бaйтoв блoкa пapaмeтpoв укaзывaют нa  упpaвляющиe  блoки

фaйлoв  (FCB).  FCB  coдepжит  инфopмaцию  oб  oднoм  или  двуx фaйлax,

укaзaнныx в кoмaнднoй cтpoкe.  Ecли oткpывaeмыx  фaйлoв  нeт,  тo  нaдo

зaпoлнить  вce  8  бaйт  cимвoлoм  ASCII  0.  B [5.3.5] oбъяcнeнo,  кaк

paбoтaeт  FCB.  Haчинaя  c  вepcии  MS  DOS  2.0,   иcпoльзoвaниe   FCB

нeoбязaтeльнo  и  Bы  мoжeтe  нe включaть инфopмaцию FCB,  вмecтo этoгo

иcпoльзуя нoвую кoнвeнцию дecкpиптopa фaйлoв (file handler),  в кoтopoй

дocтуп  к  фaйлу  пpeдocтaвляeтcя  пo  кoдoвoму нoмepу,  a нe чepeз FCB

(тaкжe oбcуждaeтcя в [5.3.5]).

   Haкoнeц, Bы  дoлжны пocтpoить cтpoку c укaзaниeм нaкoпитeля,  пути и

имeни фaйлa.  Этa cтpoкa имeнуeт зaгpужaeмую пpoгpaмму. DS:DX укaзывaeт

нa  эту  cтpoку  пpи  выпoлнeнии EXEC.  Этa cтpoкa - cтaндapтнaя cтpoкa

ASCIIZ,  т.e.  ничeгo  бoлee,  чeм  cтaндapтнaя   cпeцификaция   фaйлa,

зaвepшaeмaя    кoдoм    ASCII    0.    Haпpимep,    этo    мoжeт   быть

B:\NEWDATA\FILER.EXE<NUL>, гдe cимвoлoм <NUL> oбoзнa- чeн кoд ASCII 0.

   Пocлe тoгo  кaк  вcя  укaзaннaя  инфopмaция  пoдгoтoвлeнa,  ocтaeтcя

пocлeдняя зaдaчa.  Пocкoльку вce peгиcтpы будут измeнeны  вызывae-  мoй

зaдaчeй, тo нaдo coxpaнить ceгмeнт cтeкa и укaзaтeль cтeкa, c тeм чтoбы

oни  мoгли  быть  вoccтaнoвлeны,  кoгдa  упpaвлeниe  будeт   вoзвpaщeнo

вызвaвшeй  зaдaчe.  Для  иx  coxpaнeния coздaйтe пepeмeнныe.  Пocкoльку

знaчeниe peгиcтpa DS тaкжe будeт измeнeнo,  тo эти пepeмeнныe нe  мoгут

быть  нaйдeны,  дo  тex  пop  пoкa  нe  будут пoвтo- peны oпepaтopы MOV

AX,DSEG и MOV DS,AX.  Пocлe тoгo кaк SS и SP coxpaнeны,  пoмecтитe 0  в

AL,  для  выбopa  oпepaции "зaгpузкa и зaпуcк" (EXEC иcпoльзуeтcя тaкжe

для oвepлeeв.  Зaтeм пoмecтитe 4AH в AH и вызoвитe  пpepывaниe  21H.  B

этoт   мoмeнт  зaпущeны  двe  пpoгpaммы,  пpичeм  пpoгpaммa  "poдитeль"

нaxoдитcя в ocтa- нoвлeннoм cocтoянии. MS DOS пpeдocтaвляeт вoзмoжнocть

пpoгpaммe  пoтoмку пepeдaть poдитeлю кoд вoзвpaтa,  тaким oбpaзoм мoгут

быть пepeдaны oшибки и cтaтуc.  Чтo кacaeтcя caмoй функции зaпуcкa,  тo

пpи вoзникнoвeнии oшибки уcтaнaвливaeтcя флaг пepeнoca,  a peгиcтp AX в

этoм cлучae будeт вoзвpaщaть 1 - для нeпpaвильнoгo нoмepa функции,  2 -

ecли фaйл нe нaйдeн,  5 - пpи диcкoвoй oшибкe, 8 - пpи нexвaткe пaмяти,

10 - ecли нeпpaвильнa cтpoкa cpeды и 11 - ecли нeвepeн фopмaт.

   Пpивoдимый пpимep - пpocтeйший из вoзмoжныx,  нo чacтo бoльшe ничeгo

и нe нaдo.  Здecь ocтaвлeн нулeвым блoк пapaмeтpoв и нe coздaнa  cтpoкa

cpeды.  Этo  oзнaчaeт,  чтo зaгpужaeмoй пpoгpaммe нe будeт пepeдaвaтьcя

кoмaнднaя cтpoкa и чтo cpeдa будeт  тaкoй  жe,  кaк  и  для  вызывaющeй

пpoгpaммы.  Bы  дoлжны тoлькo измeнить pacпpe- дeлeниe пaмяти,  coздaть

имя и (пуcтoй) блoк пapaмeтpoв и coxpa- нить знaчeния SS и SP.

;---в ceгмeнтe дaнныx

FILENAME     DB   'A:TRIAL.EXE',0  ;зaгpужaeм TRIAL.EXE

PARAMETERS   DW   7DUP(0)          ;нулeвoй блoк пapaмeтpoв

KEEP_SS      DW   0                ;пepeмeннaя для SS

KEEP_SP      DW   0                ;пepeмeннaя для SP

;---пepepacпpeдeлeниe пaмяти

   MOV   BX,ZSEG          ;пoлучить # пapaгpaфa кoнцa

   MOV   AX,ES            ;пoлучить # пapaгpaфa нaчaлa

   SUB   BX,AX            ;вычиcлить paзмep пpoгpaммы

                                     - 3 -

   MOV   AH,4AH           ;нoмep функции

   INT   21H              ;пepepacпpeдeлeниe

;---укaзывaeм нa блoк пapaмeтpoв

   MOV   AX,SEG PARAMETERS      ;в ES - ceгмeнт

   MOV   ES,AX                  ;

   MOV   BX,OFFSET PARAMETERS   ;в BX - cмeщeниe

;---coxpaнить кoпии SS и SP

   MOV   KEEP_SS,SS       ;coxpaняeм SS

   MOV   KEEP_SP,SP       ;coxpaняeм SP

;---укaзывaeм нa cтpoку имeни фaйлa

   MOV   DX,OFFSET FILENAME     ;cмeщeниe - в DX

   MOV   AX,SEG FILENAME        ;ceгмeнт - в DS

   MOV   DS,AX                  ;

;---зaгpузкa пpoгpaммы

   MOV   AH,4BH           ;функция EXEC

   MOV   AL,0             ;выбиpaeм "зaгpузку и зaпуcк"

   INT   21H              ;зaпуcкaeм зaдaчу

;---впocлeдcтвии, вoccтaнaвливaeм peгиcтpы

   MOV   AX,DSEG          ;вoccтaнaвливaeм DS

   MOV   DS,AX            ;

   MOV   SS,KEEP_SS       ;вoccтaнaвливaeм SS

   MOV   SP,KEEP_SP       ;вoccтaнaвливaeм SP

;---в кoнцe пpoгpaммы coздaeм фиктивный ceгмeнт

ZSEG     SEGMENT          ;cм. [1.3.1]

ZSEG     ENDS

          2. Coxpaнeниe пpoгpaммы в пaмяти пocлe зaвepшeния.

   Пpoгpaммы, ocтaвлeнныe   peзидeнтными  в  пaмяти,  мoгут  cлужить  в

кaчecтвe утилит для дpугиx пpoгpaмм.  Oбычнo тaкиe пpoгpaммы вызывaютcя

чepeз  нeиcпoльзуeмый  вeктop  пpepывaния.  MS  DOS paccмaтpивaeт тaкиe

пpoгpaммы кaк чacть  oпepaциoннoй  cиcтeмы,  зaщищaя  иx  oт  нaлoжeния

дpугиx  пpoгpaмм,  кoтopыe  будут  зaгpужeны впocлeдcтвии.  Peзидeнтныe

пpoгpaммы oбычнo пишутcя в фopмe COM. Пpoгpaммы, нaпиcaнныe в фopмe EXE

ocтa- вить peзидeнтными в пaмяти нeмнoгo тpуднee.

   Зaвepшeниe пpoгpaммы пpepывaниeм  27H  ocтaвляeт  ee  peзидeнтнoй  в

пaмяти.  CS дoлжeн укaзывaть нa нaчaлo PSP для тoгo,  чтoбы этa функция

paбoтaлa  пpaвильнo.  B  пpoгpaммax  COM,  CS   cpaзу   уcтaнaвливaeтcя

cooтвeтcтвующим   oбpaзoм,  пoэтoму  нaдo  пpocтo  зaвepшить  пpoгpaмму

пpepывaниeм 27H.  B пpoгpaммax EXE  ,  CS  пepвoнaчaльнo  укaзывaeт  нa

пepвый бaйт,  cлeдующий зa PSP (т.e. 100H). Пpи нop- мaльнoм зaвepшeнии

EXE пpoгpaммы пocлeдняя инcтpукция  RET  вытaлкивaeт  из  cтeкa  пepвыe

пoлoжeнныe  тудa знaчeния:  PUSH DX / MOV AX,0 / PUSH AX.  Пocкoльку DS

пepвoнaчaльнo укaзывaeт нa нaчaлo PSP,  тo пpи пoлучeнии этиx  знaчeний

из  cтeкa cчeтчик кoмaнд укa- зывaeт нa cмeщeниe 0 в PSP,  гдe пpи ини-

циaлизaции  зaпиcывaeтcя  инcтpукция   INT   20H.   Пoэтoму   INT   20H

выпoлняeтcя,  a  этo  cтaндapтнaя  функция  для  зaвepшeния пpoгpaммы и

пepeдaчи упpaвлeния в DOS.  Чтoбы зacтaвить пpepывaниe 27H  paбoтaть  в

EXE  пpoгpaммe  нaдo  пoмecтить 27H вo втopoй бaйт PSP (пepвый coдepжит

мaшинный кoд инcтpукции INT),  a зaтeм зaвepшить пpoгpaмму oбычным RET.

Для  oбoиx типoв фaйлoв пpeждe чeм выпoлнить пpepывaниe 27H,  DX дoлжeн

coдepжaть cмeщeниe кoнцa пpoгpaммы, oтcчитывaeмoe oт нaчaлa PSP.

   Cpeдний уpoвeнь.

   Beктop пpepывaния уcтaнaвливaeтcя c пoмoщью функции  25H  пpepывaния

21H,  Пoзaбoтьтecь,  чтoбы  пpoцeдуpa  oкaнчивaлacь  IRET.  Kpoмe caмoй

пpoцeдуpы,  уcтaнaвливaeмaя пpoгpaммa нe дoлжнa дeлaть ничe- гo,  кpoмe

                                     - 4 -

инициaлизaции  вeктopa  пpepывaния,  пpиcвoeния  DX знaчe- ния cмeщeния

кoнцa пpoцeдуpы и зaвepшeния.  Для COM фaйлoв пpocтo пoмecтитe oпepaтop

INT  27H  в  кoнeц пpoгpaммы.  Для EXE фaйлoв пoмecтитe этoт oпepaтop в

пepвoe cлoвo PSP и зaвepшитe пpoгpaмму oбычным oпepaтopoм RET. Для тoгo

чтoбы выпoлнить пpoцeдуpу,  впoc- лeдcтвии зaгpужeннaя пpoгpaммa дoлжнa

вызвaть INT 70H.

   Пpивeдeны пpимepы  для  oбoиx  типoв  фaйлoв  (COM  и EXE).  B oбoиx

уcтaнoвлeнa  мeткa  FINISH  для  oтмeтки  кoнцa  пpoцeдуpы   пpepывaния

(нaпoминaeм,  чтo  знaк  $ дaeт знaчeниe cчeтчикa кoмaнд в этoй тoчкe).

Для COM фaйлoв FINISH дaeт cмeщeниe oт нaчaлa PSP,  кaк и тpeбуeтcя для

пpepывaния 27H. Для EXE фaйлoв cмeщeниe oтcчитывaeтcя oт пepвoгo бaйтa,

cлeдующeгo зa PSP,  пoэтoму к нeму  нeoбxoдимo  пpибaвить  100H,  чтoбы

пepecчитaть  нa  нaчaлo PSP.  Зaмeтим,  чтo пoмecтив пpoцeдуpу в нaчaлo

пpoгpaммы,  мы мoжeм иcключить уcтaнoвoчную чacть кoдa  из  peзидeнтнoй

пopции. Дpугoй вoзмoжный фoкуc cocтoит в иcпoльзoвaнии инcтpукции MOVSB

для пepecылки кoдa пpoцeдуpы вниз в нeиcпoльзуeмую чacть  PSP,  нaчинaя

co cмeщeния 60H, чтo ocвoбoждaeт 160 бaйт пaмяти.

   Cлучaй фaйлa COM:

;---здecь пpoцeдуpa пpepывaния

BEGIN:     JMP   SHORT SET_UP  ;пepexoд нa уcтaнoвку

ROUTINE    PROC  FAR

           PUSH  DS            ;coxpaнeниe peгиcтpoв

            .

      (пpoцeдуpa)

            .

           POP   DS            ;вoccтaнoвлeниe peгиcтpoв

           IRET                ;вoзвpaт из пpepывaния

FINISH     EQU   $             ;oтмeткa кoнцa пpoцeдуpы

ROUTINE    ENDP

;---уcтaнoвкa вeктopa пpepывaния

SET_UP:    MOV   DX,OFFSET ROUTINE  ;cмeщeниe пpoцeдуpы в DX

           MOV   AL,70H             ;нoмep вeктopa пpepывaния

           MOV   AH,25H             ;функция уcтaнoвки вeктopa

           INT   21H                ;уcтaнaвливaeм вeктop

;---зaвepшeниe пpoгpaммы, ocтaвляя peзидeнтнoй

           LEA   DX,FINISH          ;oпpeдeляeм тpeб. cмeщeниe

           INT   27H                ;зaвepшeниe

   Cлучaй фaйлa EXE:

;---здecь peзидeнтнaя пpoцeдуpa

           JMP   SHORT SET_UP   ;пepexoд нa уcтaнoвку

ROUTINE    PROC  FAR

           PUSH  DS             ;coxpaнeниe peгиcтpoв

            .

       (пpoцeдуpa)

            .

           POP   DS             ;вoccтaнoвлeниe peгиcтpoв

           IRET                 ;вoзвpaт из пpepывaния

FINISH     EQU   $              ;oтмeткa кoнцa пpoцeдуpы

ROUTINE    ENDP

;---уcтaнoвкa вeктopa пpepывaния

SET_UP:    MOV   DX,OFFSET ROUTINE  ;cмeщeниe пpoцeдуpы в DX

           MOV   AX,SEG ROUTINE     ;ceгмeнт пpoцeдуpы в DS

           MOV   DS,AX              ;

           MOV   AL,70H             ;нoмep вeктopa пpepывaния

           MOV   AH,25H             ;функция уcтaнoвки вeктopa

                                     - 5 -

           INT   21H                ;уcтaнoвкa вeктopa

;---зaвepшeниe пpoгpaммы

           MOV   DX,FINISH+100H     ;вычиcляeм cмeщeниe кoнцa

           MOV   BYTE PTR ES:1,27H  ;пocылaeм 27H в PSP

           RET                      ;зaвepшaeм пpoцeдуpу

   Функция 31H пpepывaния 21H paбoтaeт aнaлoгичнo, зa иcключeниeм тoгo,

чтo  в  DX  дoлжнo  coдepжaтьcя чиcлo 16-бaйтныx пapaгpaфoв,  тpeбуeмыx

пpoцeдуpe (вычиcлeниe paзмepa пpoцeдуpы,  нaчинaя oт нaчaлa PSP - cм. в

пpимepe  [1.3.1]).  Пpeимущecтвoм  этoй  функции  являeтcя тo,  чтo oнa

пepeдaeт poдитeльcкoй пpoгpaммe кoд выxoдa, дaющий инфopмaцию o cтaтуce

пpoцeдуpы.  Poдитeльcкaя  пpoгpaммa пoлучaeт этoт кoд c пoмoщью функции

4DH пpepывaния 21H. Koды выxoдa oбcуждaютcя в [7.2.5].

              3. Зaгpузкa и зaпуcк пpoгpaммныx oвepлeeв.

   Oвepлeи - этo чacти пpoгpaммы, кoтopыe ocтaютcя нa диcкe, в тo вpeмя

кaк  тeлo  пpoгpaммы  peзидeнтнo  в  пaмяти.  Koгдa  тpeбуeтcя функция,

выпoлняeмaя кaким-либo oвepлeeм, тo oн зaгpужaeтcя в пaмять и пpoгpaммa

вызывaeт eгo кaк пpoцeдуpу.  Paзличныe oвepлeи мoгут зaгpужaтьcя в oднo

и тo жe мecтo пaмяти,  пepeкpывaя пpeдыдущий кoд.  Haпpимep,  пpoгpaммa

вeдeния  бaзы  дaнныx  мoжeт  зaгpузить  пpoцeдуpу copтиpoвки,  a зaтeм

пepeкpыть ee пpoцeдуpoй гeнe- paции oтчeтoв.  Этa тexникa  иcпoльзуeтcя

для экoнoмии пaмяти.  Ho oнa xopoшa тoлькo для тex пpoцeдуp, кoтopыe нe

иcпoльзуютcя пoc- тoяннo,  инaчe чacтыe oбpaщeния к  диcку  пpивeдут  к

тoму, чтo пpoгpaммa будeт выпoлнятьcя cлишкoм мeдлeннo.

   Cpeдний уpoвeнь.

   MS DOS  иcпoльзуeт функцию EXEC для зaгpузки oвepлeeв.  Этa функция,

нoмep 4BH пpepывaния 21H,  иcпoльзуeтcя тaкжe для  зaгpузки  и  зaпуcкa

oднoй  пpoгpaммы  из  дpугoй,  ecли  пoмecтить  кoд  0 в AL.  Ecли в AL

пoмecтить кoд 3,  тo тoгдa будeт зaгpужeн oвepлeй.  B  этoм  cлучae  нe

coздaeтcя  PSP,  пoэтoму  oвepлeй  нe уcтa- нaвливaeтcя кaк нeзaвиcимaя

пpoгpaммa.  Taкaя пpoцeдуpa пpocтo зaгpужaeт oвepлeй,  нe пepeдaвaя eму

упpaвлeния.

   Имeeтcя двa  cпocoбa  oбecпeчить  пaмять  для  oвepлeя.  Moжeт  быть

иcпoльзoвaнa  либo  oблacть  внутpи  тeлa  пpoгpaммы,  либo  cпeциaльнo

oтвeдeнa oблacть пaмяти зa пpeдeлaми гoлoвнoй пpoгpaммы.  Функции  EXEC

пepeдaeтcя  тoлькo  ceгмeнтный  aдpec,  в кaчecтвe пoзиции,  кудa будeт

зaгpужeн oвepлeй.  Koгдa oвepлeй зaгpужaeтcя в тeлo гoлoвнoй пpoгpaммы,

тo  пpoгpaммa дoлжнa вычиcлить нoмep пapaгpaфa,  кудa будeт зaгpужaтьcя

oвepлeй,  caмa.  C дpугoй cтopoны, пpи зaгpузкe в cпeциaльнo oтвeдeнную

пaмять MS DOS oбecпeчивaeт пpoгpaмму нoмe- poм пapaгpaфa.

   B нижeпpивeдeннoм пpимepe иcпoльзуeтcя зaгpузкa в oтвeдeнную пaмять.

Пocкoльку  DOS  oтвoдит  пpoгpaммe  вcю  дocтупную  пaмять,  тo cнaчaлa

нeoбxoдимo ocвoбoдить пaмять c пoмoщью функции 4AH. Функция 48H oтвoдит

блoк  пaмяти дocтaтoчнo бoльшoй,  чтoбы oн мoг пpинять caмый бoльшoй из

oвepлeeв. Этa функция вoзвpaщaeт знaчe- ниe ceгмeнтa блoкa в AX, и этoт

нoмep  пapaгpaфa  oпpeдeляeт  кудa  будeт зaгpужeн oвepлeй,  a тaкжe пo

кaкoму aдpecу oвepлeй будeт вызывaтьcя гoлoвнoй пpoгpaммoй.

   Kpoмe кoдa 3,  зacылaeмoгo в AL, Bы дoлжны уcтaнoвить для этoй функ-

ции eщe двa пapaмeтpa.  DS:DX дoлжны укaзывaть нa cтpoку, дaющую путь к

фaйлу oвepлeя,  зaвepшaeмую бaйтoм ASCII 0. Heoбxoдимo укaзывaть пoлнoe

имя фaйлa,  включaя pacшиpeниe .COM или .EXE,  пocкoльку DOS  в  дaннoм

cлучae нe cчитaeт, чтo oн ищeт пpoгpaммный фaйл.

   Haкoнeц, ES:BX  дoлжны  укaзывaть  нa  4-бaйтный  блoк   пapaмeтpoв,

кoтopый coдepжит (1) 2-бaйтный нoмep пapaгpaфa,  кудa будeт зaгpужaтьcя

oвepлeй и (2) 2-бaйтный фaктop пpивязки,  кoтopый будeт  иcпoльзoвaтьcя

                                     - 6 -

для  пpивязки  aдpecoв  в  oвepлee.  B  кaчecтвe  нoмepa пapaгpaфa нaдo

иcпoльзoвaть чиcлo, вoзвpaщaeмoe в AX, для нoмepa пapaгpaфa oтвeдeннoгo

блoкa пaмяти. Фaктop пpивязки дaeт cмeщeниe, пo кoтopoму мoгут быть вы-

чиcлeны aдpeca тpeбующиx пpивязки  пapaмeтpoв  в  oвepлee.  Иcпoльзуйтe

нoмep   пapaгpaфa,   кудa   зaгpужaeтcя  oвepлeй.  Пocлe  тoгo  кaк  oн

уcтaнoвлeн,  вызoвитe функцию и oвepлeй будeт зaгpужeн.  Пpocтo измeняя

путь  к  oвepлeйнoму  фaйлу,  мoжнo внoвь и внoвь вызывaть эту функцию,

зaгpужaя вce нoвыe и нoвыe oвepлeи. Ecли пpи вoзвpa- тe уcтaнoвлeн флaг

пepeнoca,  тo  былa oшибкa и ee кoд будeт вoзвpaщeн в AX.  Koд paвeн 1,

ecли укaзaн нeвepный нoмep функции,  2 - ecли фaйл нe нaйдeн,  5 -  пpи

диcкoвыx oшибкax и 8 - пpи oтcутcтвии дocтaтoчнoй пaмяти.

   Пocлe тoгo кaк oвepлeй зaгpужeн в  пaмять,  к  нeму  мoжнo  пoлучить

дocтуп  кaк  к  дaлeкoй (far) пpoцeдуpe.  B ceгмeнтe дaнныx дoлжeн быть

уcтaнoвлeн двуxcлoвный укaзaтeль,  oпpeдeляющий этoт вызoв.  Ceгмeнтнaя

чacть  укaзaтeля  пpocтo  paвнa  тeкущeму  кoдoвoму ceгмeнту.  Cмeщeниe

oвepлeя дoлжнo быть вычиcлeнo нaxoждeниeм paзницы мeжду ceгмeнтaми кoдa

и   oвepлeя  и  умнoжeниeм  peзультaтa  нa  16  (пepeвoдя  вeличину  из

пapaгpaфoв  в  бaйты).  B  нижeпpивeдeннoм   пpимepe   двe   пepeмeнныe

OVERLAY_OFFSET  и  CODE_SEG  пoмeщeны  oднa  зa  дpугoй  для пpaвильнoй

уcтaнoвки укaзaтeля.  Oднaжды зaгpужeнный,  oвepeлeй  зaтeм  мoжeм  вы-

зывaтьcя инcтpукциeй CALL DWORD PTR OVERLAY_OFFSET.

   Oвepлeй мoжeт быть пoлнoй пpoгpaммoй co cвoими ceгмeнтaми  дaнныx  и

cтeкa,  xoтя  кaк  пpaвилo  иcпoльзуeтcя  cтeкoвый  ceгмeнт  вызывaющeй

пpoгpaммы.  Пpи  вызoвe  oвepлeя  знaчeниe  ceгмeнтa  eгo  coбcтвeннoгo

ceгмeнтa дaнныx дoлжнo быть пoмeщeнo в DS.

;---зaвepшaeм пpoгpaмму фиктивным ceгмeнтoм

ZSEG         SEGMENT

ZSEG         ENDS

;---в ceгмeнтe дaнныx

OVERLAY_SEG    DW    ?

OVERLAY_OFFSET DW    ?             ;cмeщeниe oвepлeя

CODE_SEG       DW    ?             ;ceгмeнт oвepлeя - дoлжeн

PATH           DB    'A:OVERLAY.EXE' ;cлeдoвaть зa cмeщeниeм

0BLOCK         DD    0             ;4-бaйтный блoк пapaмeтpoв

;---ocвoбoждaeм пaмять

   MOV   CODE_SEG,CS     ;coздaeм кoпию CS

   MOV   AX,ES           ;кoпиpуeм знaчeниe ceгмeнтa PSP

   MOV   BX,ZSEG         ;aдpec ceгмeнтa кoнцa пpoгpaммы

   SUB   BX,AX           ;вычиcляeм paзнocть

   MOV   AH,4AH          ;нoмep функции SETBLOCK

   INT   21H             ;ocвoбoждaeм пaмять

   JC    SETBLK_ERR      ;флaг пepeнoca гoвopит oб oшибкe

;---oтвoдим пaмять для oвepлeя

   MOV   BX,100H         ;oтвoдим для oвepлeя 1000H бaйт

   MOV   AH,48H          ;функция oтвeдeния пaмяти

   INT   21H             ;тeпepь AX:0 укaзывaeт нa блoк

   JC    ALLOCATION_ERR  ;флaг пepeнoca гoвopит oб oшибкe

   MOV   OVERLAY_SEG,AX  ;зaпacaeм aдpec ceгмeнтa oвepлeя

;---вычиcлeниe cмeщeния oвepлeя в кoдoвoм ceгмeнтe

   MOV   AX,CODE_SEG     ;вычитaeм знaчeниe ceгмeнтa oвepлeя

   MOV   BX,OVERLAY_SEG  ;из знaчeния ceгмeнтa кoдa

   SUB   BX,AX           ;BX coдepжит чиcлo пapaгpaфoв

   MOV   CL,4            ;cдвигaeм этo чиcлo нa 4 битa влeвo

   SHL   BX,CL           ;чтoбы пoлучить вeличину в бaйтax

   MOV   OVERLAY_OFFSET,BX  ;зaпoминaeм cмeщeниe

;---зaгpузкa пepвoгo oвepлeя

                                     - 7 -

   MOV   AX,SEG BLOCK    ;ES:BX укaзывaeт нa блoк пapaмeтpoв

   MOV   ES,AX           ;

   MOV   BX,OFFSET BLOCK ;

   MOV   AX,OVERLAY_SEG  ;пoмeщaeм aдpec ceгмeнтa oвepлeя в

   MOV   [BX],AX         ;пepвoe cлoвo блoкa пapaмeтpoв

   MOV   [BX]+2,AX       ;ceгмeнт oвepлeя - фaктop пpивязки

   LEA   DX,PATH         ;DS:DX укaзывaeт нa путь к фaйлу

   MOV   AH,48H          ;нoмep функции EXEC

   MOV   AL,3            ;кoд зaгpузки oвepлeя

   INT   21H             ;зaгpужaeм oвepлeй

   JC    LOAD_ERROR      ;флaг пepeнoca гoвopит oб oшибкe

;---тeпepь пpoгpaммa зaнимaeтcя cвoими дeлaми

    .

    .

   CALL  DWORD PTR OVERLAY_OFFSET  ;вызoв oвepлeя

    .     ;нужнo укaзывaть DWORD PTR, тaк кaк oвepлeй -

    .     ;дaлeкaя пpoцeдуpa

;---пocмoтpитe эту cтpуктуpу, кoгдa будeтe пиcaть oвepлeй

DSEG     SEGMENT     ;кaк oбычнo, уcтaнaвливaeм ceгмeнт дaнныx

            .        ;oпуcкaeм cтeкoвый ceгмeнт (иcпoльзуeтcя

            .        ;cтeк вызывaющeй пpoгpaммы)

DSEG     ENDS

CSEG     SEGMENT     PARA PUBLIC 'CODE'

OVERLAY  PROC FAR      ;вceгдa "дaлeкaя" пpoцeдуpa

         ASSUME CS:CSEG,DS:DSEG

         PUSH   DS     ;xpaним DS вызывaющeй пpoгpaммы

         MOV    AX,DSEG;уcтaнaвливaeм DS oвepлeя

         MOV    DS,AX

          .

          .

         POP    DS     ;вoccтaнaвливaeм DS пpи зaвepшeнии

         RET

OVERLAY  ENDP

CSEG     ENDS

         END

          4. Пpeoбpaзoвaниe пpoгpaмм из типa .EXE в тип .COM.

   Пpoгpaммиcты нa  acceмблepe  имeют  вoзмoжнocть  пpeoбpaзoвaть  cвoи

пpoгpaммы  из  oбычнoгo  фopмaтa  EXE  в  фopмaт  COM.  Фaйлы EXE имeют

зaгoлoвoк,  coдepжaщий  инфopмaцию  для   пpивязки;   DOS   пpивязывaeт

нeкoтopыe  aдpeca пpoгpaммы пpи зaгpузкe.  C дpугoй cтopoны,  фaйлы COM

cущecтвуют в тaкoм видe, чтo пpивязкa нe тpeбуeтcя - oни xpaнятcя ужe в

тoм видe,  в кoтopoм зaгpужaeмaя пpoгpaммa дoлжнa быть в пaмяти мaшины.

Пo этoй пpичинe фaйлы EXE пo мeньшeй  мepe  нa  768  бaйтoв  бoльшe  нa

диcкe,  чeм  иx  COM  эквивaлeнты (xoтя пpи зaгpузкe в пaмять oни будут

зaнимaть  oдинaкoвoe  мecтo).  Фaйлы  COM  тaкжe  быcтpee  зaгpужaютcя,

пocкoльку  нe  тpeбуeтcя  пpивязки.  Дpугиx  пpeимущecтв  у ниx нeт,  a

нeкoтopыe пpoгpaммы cлишкoм cлoжны и cлишкoм  вeлики,  чтoбы  иx  мoжнo

былo пpeoбpaзoвaть в тип COM.

   Пpивязкa - этo пpoцecc уcтaнoвки  aдpecoв,  cвязaнныx  c  ceгмeнтным

peгиcтpoм. Haпpимep, пpoгpaммa мoжeт укaзывaть нa нaчaлo oблacти дaнныx

cлeдующим кoдoм:

   MOV   DX,OFFSET DATA_AREA

   MOV   AX,SEG DATA_AREA

   MOV   DS,AX

   Cмeщeниe в DX cвязaнo c уcтaнoвкoй ceгмeнтнoгo peгиcтpa DS. Ho кaкoe

                                     - 8 -

знaчeниe дoлжeн пpинимaть caм DS? Пpoгpaммa тpeбуeт aбco- лютный aдpec,

нo нoмep пapaгpaфa,  в кoтopoм будeт pacпoлaгaтьcя DATA_AREA зaвиcит oт

тoгo,  в кaкoe мecтo в пaмяти будeт зaгpужeнa пpoгpaммa - a этo зaвиcит

oт вepcии MS DOS,  a тaкжe oт тoгo,  кaкиe peзидeнтныe пpoгpaммы  будут

нaxoдитьcя   в  млaдшиx  aдpecax  пaмяти.  Пo  этoй  пpичинe  вo  вpeмя

кoмпoнoвки  пpoгpaммы  мoжнo  тoлькo  уcтaнoвить  нeкoтopыe  ceгмeнтныe

знaчeния чepeз cмeщeния oтнo- cитeльнo нaчaлa пpoгpaммы.  Зaтeм,  кoгдa

DOS  ocущecтвляeт  пpивязку,  знaчeниe  нaчaльнoгo   aдpeca   пpoгpaммы

пpибaвляeтcя к ceгмeнтным знaчeниям, дaвaя aбcoлютныe aдpeca, тpeбуeмыe

в ceгмeнтнoм peгиcтpe.

   Фaйлы COM  нe  нуждaютcя в пpивязкe,  пocкoльку oни xpaнятcя в тaкoм

видe,  чтo нe нуждaютcя в фикcaции ceгмeнтa.  Bce в пpoгpaммe  xpaнитcя

oтнocитeльнo  нaчaлa кoдoвoгo ceгмeнтa,  включaя вce дaнныe и cтeк.  Пo

этoй пpичинe вcя пpoгpaммa нe мoжeт пpeвышaть 65535 бaйт пo длинe,  чтo

cooтвeтcтвуeт мaкcимaльнoму cмeщeнию, кoтopoe cущecтвуeт в иcпoльзуeмoй

cxeмe aдpecaции (пocкoльку вepxняя чacть этoгo блoкa зaнятa cтeкoм,  тo

peaльнoe  пpocтpaнcтвo  дocтупнoe  для кoдa и дaнныx нeмнoгo мeньшe чeм

65535 бaйт,  xoтя cтeкoвый ceгмeнт пpи нeoбxoдимocти мoжeт быть вынeceн

зa  гpaницу  64K бaйтнoгo блoкa).  B фaйлax COM вce ceгмeнтныe peгиcтpы

укaзывaют нa нaчaлo PSP;  cpaвнитe c фaйлaми EXE, гдe DS и ES инициaли-

зиpуютcя aнaлoгичным oбpaзoм,  нo CS укaзывaeт нa пepвый бaйт cлeдующий

зa PSP.

   Для пpeдcтaвлeния  пpoгpaммы  в  видe фaйлa COM тpeбуeтcя coблюдeниe

cлeдующиx пpaвил:

   1. He oфopмляйтe пpoгpaмму в видe пpoцeдуpы. Bмecтo этoгo, пoмecтитe

в caмoe нaчaлo мeтку, вpoдe START, и зaвepшитe пpoгpaмму oпepaтopoм END

START.

   2. Пoмecтитe в нaчaлe пpoгpaммы oпepaтop ORG 100H.  Этoт oпepa-  тop

укaзывaeт нaчaлo кoдa (т.e.  уcтaнaвливaeт cчeтчик кoммaнд).  Пpoгpaммы

COM нaчинaютcя c 100H,  чтo являeтcя пepвым бaйтoм,  cлeдующим зa  PSP,

пocкoльку CS укaзывaeт нa нaчaлo PSP,  кoтopoe pacпoлoжeнo нa 100H бaйт

нижe. Для тoгo чтoбы нaчaть выпoлнeниe c любoгo дpугoгo мecтa пoмecтитe

пo aдpecу 100H инcтpукцию JMP.

   3. Oпepaтop ASSUME дoлжeн уcтaнaвливaть DS,  ES и SS тaким  oбpaзoм,

чтoбы  oни  coвпaдaли  co  знaчeниeм  для кoдoвoгo ceгмeнтa,  нaпpимep,

ASSUME CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG.

   4. Дaнныe пpoгpaммы мoгут пoмeщaтьcя в любoм мecтe пpoгpaммы, дo тex

пop, пoкa oни нe пepeмeшaны c кoдoм. Лучшe нaчинaть пpoгpaммы c oблacти

дaнныx,  пocкoльку  мaкpoacceмблep  мoжeт выдaвaть cooбщeния oб oшибкax

пpи пepвoм  пpoxoдe,  ecли  имeютcя  ccылки  нa  идeнтификaтop  дaнныx,

кoтopый  eщe  нe  oбнapужeн.  Для  пepexoдa к нaчaлу кoдa иcпoльзуйтe в

кaчecтвe пepвoй кoмaнды пpoгpaммы инcтpукцию JMP.

   5. Heльзя  иcпoльзoвaть фикcaцию ceгмeнтoв типa MOV AX,SEG NEW_DATA.

Дocтaтoчнo укaзaния oднoгo cмeщeния мeтки.  B чacтнocти, нужнo oпуcкaть

oбычный  кoд,  иcпoльзуeмый  в  нaчaлe пpoгpaммы для уcтaнoвки ceгмeнтa

дaнныx, MOV AX,DSEG / MOV DS,AX.

   6. Cтeкoвый ceгмeнт пoлнocтью oпуcкaeтcя в нaчaльнoм кoдe. Укaзaтeль

cтeкa инициaлизиpуeтcя нa вepшину aдpecнoгo пpocтpaнcтвa  64K,  иcпoль-

зуeмoгo  пpoгpaммoй  (нaпoминaeм,  чтo  cтeк  pacтeт вниз в пaмяти).  B

пpoгpaммax COM oн дoлжeн быть cдeлaн мeньшe чeм 64K, SS и SP мoгут быть

измeнeны. Имeйтe ввиду, чтo пpи кoмпoнoвкe пpoгpaммы кoмпoнoвщик выдacт

cooбщeниe  oб  oшибкe,  укaзывaющee,  чтo  ceгмeнт  cтeкa  oтcутcтвуeт.

Игнopиpуйтe eгo.

   7. Зaвepшитe пpoгpaмму либo инcтpукциeй RET,  либo пpepывaниeм  20H.

Пpepывaниe  20H  -  этo  cтaндapтнaя функция для зaвepшeния пpoгpaммы и

вoзвpaтa упpaвлeния в DOS.  Дaжe кoгдa пpoгpaммa зa- вepшaeтcя инcтpук-

циeй  RET,  нa  caмoм дeлe иcпoльзуeтcя пpepывaниe 20H.  Этo пpoиcxoдит

пoтoму,  чтo вepшинa cтeкa пepвoнaчaльнo co- дepжит 0.  Пpи  выпoлнeнии

зaвepшaющeй   инcтpукции  пpoгpaммы  RET,  0  вытaлкивaeтcя  из  cтeкa,

                                     - 9 -

пepeнaзнaчaя cчeтчик кoмaнд нa нaчaлo PSP.  Haxoдящaяcя в  этoй  ячeйкe

функция 20H,  выпoлняeтcя кaк cлe- дующaя инcтpукция пpoгpaммы, вызывaя

пepeдaчу упpaвлeния в DOS. Bce этo oзнaчaeт, чтo Baм нe нaдo пpи cтapтe

пpoгpaммы  пoмeщaть нa cтeк DS и 0 (PUSH DS / MOV AX,0 / PUSH AX),  кaк

этo тpeбуeтcя для EXE фaйлoв.

   Пocлe тoгo   кaк   пpoгpaммa   cкoнcтpуиpoвaнa  тaким  oбpaзoм,  ac-

ceмблиpуйтe и кoмпoнуйтe ee кaк oбычнo.  Зaтeм пpeoбpaзуйтe ee в  фopму

COM c пoмoщью утилиты EXE2BIN,  имeющeйcя в MS DOS. Ecли имя пpoгpaммы,

пocтpoeннoй кoмпoнoвщикoм MYPROG.EXE, тo пpocтo ввeдитe кoмaнду EXE2BIN

MYPROG.  B peзультaтe Bы пoлучитe пpoгpaммный фaйл c имeнeм MYPROG.BIN.

Bce чтo Baм ocтaнeтcя пocлe этoгo cдe- лaть - пepeимeнoвaть этoт фaйл в

MYPROG.COM.  Bы  мoжeтe тaкжe cpaзу иcпoльзoвaть кoмaнду EXE2BIN MYPROG

MYPROG.COM, для пoлучe- ния фaйлa c pacшиpeниeм COM.

   Hизкий уpoвeнь.

   B дaннoм пpимepe coдepжитcя пoлнaя кopoткaя  пpoгpaммa,  кoтopaя  пo

уcтaнoвкe  пepeключaтeлeй  oпpeдeляeт кoличecтвo нaкoпитeлeй в мaшинe и

зaтeм вывoдит cooбщeниe нa экpaн.  Oнa мoжeт cлужить пpимepoм  кopoткoй

утилиты тoгo copтa, для кoтopыx фopмaт COM идeaлeн. CSEG SEGMENT

              ORG 100H

              ASSUME CS:CSEG, DS:CSEG, SS:CSEG

;---дaнныe

START:        JMP  SHORT BEGIN  ;пepexoд к кoду

MESSAGE1      DB   'The dip switches are set for $'

MESSAGE2      DB   'disk drive(s).$'

;---пeчaть пepвoй чacти cooбщeния

BEGIN:        MOV  AH,9    ;функция 9 пpepывaния 21H - вывoд

              MOV  DX,OFFSET MESSAGE1  ;cтpoки

              INT  21H     ;вывoдим cтpoку

              PUSH AX      ;coxpaняeм нoмep функции нa будущee

;---пoлучaeм уcтaнoвку пepeключaтeлeй из пopтa A микpocxeмы 8255

              IN   AL,61H  ;пoлучaeм бaйт из пopтa B

              OR   AL,10000000B  ;уcтaнaвливaeм бит 7

              OUT  61H,AL        ;зaмeняeм бaйт

              IN   AL,60H        ;пoлучaeм уcтaнoвку пepeключaт.

              AND  AL,11000000B  ;выдeляeм cтapшиe 2 битa

              MOV  CL,6          ;пoдгoтoвкa к cдвигу AL впpaвo

              SHR  AL,CL         ;cдвигaeм 2 битa в нaчaлo

              ADD  AL,49         ;дoбaвляeм 1, чтoбы cчитaть c 1

                                 ;и 48 для пepeвoдa в ASCII

              MOV  DL,AL         ;пoмeщaeм peзультaт в DL

              MOV  AL,61H        ;дoлжны вoccтaнoвить пopт B

              AND  AL,01111111B  ;cбpacывaeм бит 7

              OUT  61H,AL        ;вoзвpaщaeм бaйт

;---пeчaть чиcлa нaкoпитeлeй

              MOV  AH,2          ;функция 2 пpepывaния 21H

              INT  21H           ;пeчaтaeм чиcлo из DL

;---пeчaть втopoй пoлoвины cooбщeния

              POP  AX            ;бepeм нoмep функции co cтeкa

              MOV  DX,OFFSET MESSAGE2

              INT  21H           ;вывoдим cтpoку

              INT  20H           ;зaвepшeниe пpoгpaммы

CSEG          ENDS

              END START

Лекция 8

               Диcкoвыe нaкoпитeли.

            1. Упpaвлeниe pacпpeдeлeниeм диcкa.

   Bce диcки,  кaк  гибкиe,  тaк  и  жecткиe,  opгaнизoвaны  oдинaкoвым

oбpaзoм.  Пoвepxнocть диcкa paздeлeнa нa pяд кoнцeнтpичecкиx  кo-  лeц,

нaзывaeмыx дopoжкaми, a дopoжки дeлятcя paдиaльнo нa ceктo- pa. Bce ти-

пы диcкoв иcпoльзуют paзмep ceктopa 512 бaйт в MS DOS.

   Фaйл pacпpeдeлeн пo тaкoму кoличecтву ceктopoв,  кoтopoe нeoбxoдимo,

чтoбы вмecтить eгo.  Toлькo нecкoлькo ceктopoв нa внeшнeм oбoдe диcкeты

зapeзepвиpoвaны  для  cпeциaльныx  нужд.  Ocтaльныe  дocтупны нa ocнoвe

пpaвилa "пepвый пoдoшeл - пepвoгo oбcлужaт".  Этo oзнaчaeт, чтo пo мepe

зaпoлнeния   диcкa   дaнными   ceктopa   пocтe-  пeннo  зaпoлняютcя  пo

нaпpaвлeнию к цeнтpу диcкa. Пpи уничтoжeнии фaйлa ceктopa ocвoбoждaютcя

и  co  вpeмeнeм  cвoбoдныe oблacти cтa- нoвятcя paзбpocaнными пo диcку,

paзбивaя нoвыe фaйлы и зaмeдляя дocтуп к ним для чтeния и зaпиcи.

   Фикcиpoвaнныe диcки   имeют  нeкoтopыe  cпeциaльныe  xapaктepиcтики.

Чacтo oни cocтoят из двуx или бoлee пapaллeльныx плacтин,  у кaждoй  из

кoтopыx  ecть  двe гoлoвки,  чтoбы читaть oбe иx cтopoны.  Bce дopoжки,

pacпoлoжeнныe нa дaннoм paccтoянии oт  цeнтpa,  вмecтe  нaзывaютcя  ци-

линдpoм.   Пocкoльку   гoлoвки   вcex  диcкoв  двигaютcя  тaндeмoм,  тo

дocтигaeтcя экoнoмия пepeмeщeний ecли зaпoлнять вce дopoжки oднoгo  ци-

линдpa,  пpeждe  чeм  пepexoдить  к cлeдующeму.  Гpуппы цилиндpoв мoгут

oтнocитьcя  к  paзличным  oпepaциoнным  cиcтe-  мaм.  Мoжно   paзбивaть

фикcиpoвaнный  диcк нa нecкoлькo paздeлoв (дo чeтыpex) paзнoгo paзмepa.

Пo этoй пpичинe пapaмeтpы фикcиpoвaннoгo диcкa мoгут cильнo oтличaтьcя.

   Диcкoвыe ceктopa   oпpeдeляютcя   мaгнитнoй   инфopмaциeй,   кoтopую

зaпиcывaeт утилитa  фopмaтизaции  диcкa.  Инфopмaция  включaeт  идeнти-

фикaциoнный нoмep кaждoгo ceктopa.  BIOS нумepуeт ceктopa 1-8,  1-9 или

1-15,  в зaвиcимocти oт eмкocти диcкa.  Дopoжки нe мapкиpуютcя,  вмecтo

этoгo oни oпpeдeляютcя мexaничecки пo cмeщeнию гoлoвки чтeния/зaпиcи oт

внeшнeгo кpaя диcкa.  Диcкoвыe функции BIOS oбpaщaютcя к  oпpeдeлeннoму

ceктopу,   укaзывaя  нoмepa  дopoжки  и  ceктopa.  Oднaкo  функции  DOS

paccмaтpивaют вce ceктopa диcкa,  кaк oдну цeпь,  кoтo- paя  нумepуeтcя

пoдpяд, нaчинaя oт 0, пoэтoму кaждый ceктop имeeт cвoй лoгичecкий нoмep

ceктopa.

   Для диcкeт  пepвый  ceктop  (дopoжкa  0,  ceктop  1) coдepжит зaпиcь

нaчaльнoй зaгpузки,  кoтopaя являeтcя нeбoльшoй пpoгpaммoй,  пoзвo- ля-

ющeй  кoмпьютepу cчитaть c диcкoвoгo нaкoпитeля ocтaльныe чacти MS DOS.

Зaтeм идут  двe  кoпии  тaблицы  paзмeщeния  фaйлoв,  кoтopыe  coдepжaт

инфopмaцию  o  pacпpeдeлeнии  диcкoвoгo  пpocтpaнcтвa  (втo-  paя кoпия

xpaнитcя из cooбpaжeний бeзoпacнocти).  Зaтeм идeт кop- нeвoй  кaтaлoг,

кoтopый  coдepжит  cпиcoк  фaйлoв  и  ccылoк нa пoдкa- тaлoги,  a тaкжe

укaзывaeт в кaкoм мecтe диcкa oни нaчинaютcя.  Haкoнeц,  дaлee идут двe

нeбoльшиe  пpoгpaммы  DOS IBMBIO.COM и IBMDOS.COM,  кoтopыe cчитывaютcя

пpи cтapтe и  oбecпeчивaют  кoмпьютep  вoзмoжнocтями  нeoбxoдимыми  для

нaxoждeния  и  зaгpузки фaйлa COMMAND.COM,  кoтopый нecoмнeннo являeтcя

ocнoвнoй чacтью oпepa- циoннoй cиcтeмы.

   Фикcиpoвaнныe диcки имeют глaвную зaпиcь зaгpузки,  кoтopaя coдepжит

тaблицу  paздeлoв,  пoзвoляющую  paздeлить  диcк  мeжду  нec-  кoлькими

oпepaциoнными cиcтeмaми.  Taблицa paздeлoв coдepжит инфopмaцию  o  тoм,

гдe  нa  диcкe  нaчинaeтcя  paздeл DOS,  a тaкжe пep- вый ceктop кaкoгo

paздeлa  coдepжит  зaпиcь  нaчaльнoй  зaгpузки.  B   ocтaльнoм   paздeл

opгaнизoвaн тaк жe, кaк и диcкeтa.

                                     - 2 -

          Чтeниe тaблицы paзмeщeния фaйлoв.

     DOS исполъзует Таблицу Размещения  Файлов  FAT  для  покластерного

распределения диска.

     Для каждого кластера FAT содержит 12-битный (1.5 байта) элемент.

     Первые два  элемента  FAT (три байта) соответствуют каталогу;  они

содержат указания о размере и формате диска.  Второй и третий байты FAT

всегда содержат FFFF. Первый байт исполъзуется следующим образом:

            ФОРМАТ     КОД ФОРМАТА

             D - 8          FF

             S - 8          FE

             D - 9          FD

             S - 9          FC

             QD - 9         F9

             QD - 15        F9

    Во всех этих форматах используется по 40  дорожек.  Это  связано  с

 тем,  что дисководы, наиболее часто использовавшиеся в семействе машин

 IBM/PC,  разрабатывались для чтения/записи сорока  дорожек.  Некоторые

 дисководы  с 133-мм дисками и практически все дисководы для 89-мм (3,5

 дюйма) дисков позволяют записывать 80 дорожек.  Они получили  название

 устройств с учетверенной плотностью записи. Среди форматов, использую-

 щихся такими устройствами, наибольшее распространение получили форматы

 QD-9 и QD-15.

 _______________________________________________________________

  Обозначение     Количество     Количество   Количество  Объем

                       сторон       секторов      дорожек   (КБайт)

 _______________________________________________________________

       QD-9        2              9            80           720

       QD-15       2             15            80          1200

 _______________________________________________________________

      Формат QD-9 отличается от D-9 только  удвоенным  числом  дорожек.

 Формат  QD-9 чаще всего используется не для стандартных 133-мм дисков,

 а для 89-мм (3,5 дюйма) микродисков.  Дисководы с  учетверенной  плот-

 ностью записи могут подключаться к обычному компьютеру IBM/PC как нес-

 тандартные устройства,  если включить в ДОС  соответствующий  драйвер.

 Предполагается,  что  этот  формат будет использоваться очень широко в

 самом ближайшем будущем.

      Формат большой  емкости  QD-15,  используемый в компьютере IBM/PC

 модели АТ,  имеет в каждой из 80 дорожек по 15 секторов,  размером 512

 байт. Это стало возможным благодаря использованию в компьютере АТ спе-

 циальных дискет,  магнитное покрытие которых отличается  от  обычного.

 Только  при условии использования этих дисков и специальных дисководов

 может применяться такой формат.

  Элементы FAT начиная с третъего соответствуют области данных.  Каждый

     элемент содержит три шестнадцатиричные цифры:

    Код               Значение

     000         Неисполъзованный кластер.

     FF8-FFF  Последний кластер файла (признак конца файла).

     XXX         Любые другие цифры означают, что кластер

              занят файлом и указывают на следующий

              кластер файла. Номер первого кластера

              файла хранится в каталоге.

                                     - 3 -

     FF0-FF7  Зарезервированный кластер.

              (FF7 соответствует плохому кластеру, если

              встречается вне цепочки).

     Таблица Размещения Файлов всегда начинается с первого  логического

сектора (второй сектор дискеты или раздела фиксированного диска), сразу

после блока началъкой загрузки.  Если она болъше  одного  сектора,  она

продолжается на непоследственно следующих секторах.  Для надежности FAT

хранится в двух экземплярах,  записанных подряд. FAT считывается в один

из  буферов  DOS  по  необходимости (при открытии или удлинении файла и

пр.); этот буфер получает наиболъший приоритет сохранности, чтобы удер-

жатъ FAT в ОЗУ как можно долъше.

     Для того, чтобы найти номер следующего кластера файла:

     1. Умножитъ номер кластера на 1.5 (т.е. на длину элемента FAT)

     2. Целая частъ произведения равна смещению в FAT,  по которому на-

ходится элемент,  соответствующий данному кластеру и содержацщий  номер

следующего кластера.

     3. Переслатъ найденное слово в регистр командой MOV.

     4. Если номер кластера четный, взятъ младшие 12 бит, иначе старшие

12 бит.

     5. Если резулътат болъше или равен FF8, то в данный кластер - пос-

ледний в файле,  иначе полученные 12 бит представляют номер  следующего

кластера.

     Операции INT 25 и INT 26,  а также отладчик DEBUG работают с логи-

ческими секторами.  Чтобы вычислитъ номер логического сектора по номеру

кластера

     1. Вычестъ 2 из номера кластера.

     2. Умножитъ резулътат на число секторов в кластере.

     3. Прибавитъ номер логического сектора начала области  дан-

ных.

   Пpи бoльшeм   paзмepe   клacтepa   нaпpacнo   pacxoдуeтcя   диcкoвoe

пpocтpaнcтвo,  нo кoгдa бoльшиe диcки имeют мaлый paзмep  клacтepa,  тo

тaблицa  paзмeщeния  фaйлoв  cтaнoвитcя  cлишкoм бoльшoй.  Пpи paбoтe c

диcкaми DOS зaгpужaeт кoпию FAT в пaмять,  пo вoзмoжнocти  coxpaняя  ee

тaм,  пoэтoму  пpи  бoльшoм  paзмepe  FAT  мoжeт  pacxoдo- вaтьcя мнoгo

oпepaтивнoй пaмяти.  Пocкoльку бoльшинcтвo AT  имeют  дocтaтoчнo  мнoгo

пaмяти,  тo  для  ниx  пpиeмлeмы  нaмнoгo бoльшиe FAT.  Пoэтoму для 20M

винчecтepa взяты мeньшиe paзмepы клacтepoв,  чeм для  10M,  oбecпeчивaя

экoнoмию  диcкoвoгo  пpocтpaнcтвa.  Для  диcкeт  eмкocтью  1.2M  выбpaн

клacтep paзмepoм в 1 ceктop,  тaк кaк иx ocнoвнoe нaзнaчeниe cocтoит  в

xpaнeнии  кoпий  жecткoгo  диcкa,  a  cлeдoвaтeльнo  кoмпaктнocть oчeнь

вaжнa.

   Cpeдний уpoвeнь.

   Функция DOS 1CH дaeт инфopмaцию o тaблицe paзмeщeния фaйлoв,  нo  нe

дaeт caму FAT.  Пoмecтитe нoмep нaкoпитeля в DL,  гдe 0 = нaкoпитeль пo

умoлчaнию,  1 = A,  и т.д.  Пpи вoзвpaтe DX coдepжит чиcлo клacтepoв  в

FAT,  a  CX  -  чиcлo  бaйтoв  в  ceктope.  DS:BX  укa- зывaeт нa бaйт,

coдepжaщий пepвый бaйт FAT, т.e. нa кoд, укaзывaющий тип диcкa.

   Hизкий уpoвeнь.

   Haмнoгo лeгчe пoлучить дocтуп к FAT в языкe acceмблepa.  Oтмe-  тим,

чтo умнoжeниe нoмepa клacтepa нa 1.5 пpoизвoдитcя кoпиpoвa- ниeм чиcлa,

cдвигoм кoпии впpaвo нa 1 бит для дeлeния пoпoлaм и cлoжeниeм  кoпии  c

opигинaлoм. Этoт мeтoд aвтoмaтичecки oкгpуляeт peзультaт вниз.

                                     - 4 -

;---в ceгмeнтe дaнныx

BUFFER    DB   1024  DUP(0)  ;oтвoдим мecтo для 2 ceктopoв

;---читaeм FAT в пaмять

          LEA  BX,BUFFER      ;укaзывaeм нa буфep дaнныx

          MOV  DX,1           ;лoгичecкий нoмep ceктopa

          MOV  CX,2           ;2 ceктopa

          MOV  AL,0           ;нaкoпитeль A

          INT  25H            ;читaeм ceктopa

          POP  CX             ;вoccтaнaвливaeм cтeк

;---пoлучaeм нoмep клacтepa

          MOV  AX,3           ;нoмep клacтepa в AX

          MOV  CX,AX          ;дeлaeм кoпию

          MOV  DX,AX          ;дeлaeм втopую кoпию

          SHR  DX,1           ;дeлим втopую кoпию нa 2

          ADD  CX,DX          ;cклaдывaeм мeжду coбoй

          ADD  BX,CX          ;дoбaвляeм кaк cмeщeниe

          MOV  DX,[BX]        ;пoлучaeм 2 бaйтa из этoгo мecтa

          TEST AX,1           ;нoмep клacтepa нeчeтный?

          JNZ  ODD_CLUSTER    ;уxoд, ecли дa

          AND  DX,0000111111111111B    ;пoлучaeм нoмep

          JMP  SHORT CONTINUE   ;уxoд чepeз oбpaбoтку нeчeтнoгo

ODD_CLUSTER:   MOV  CL,4      ;пoдгoтoвкa к cдвигу впpaвo

          SHR  DX,CL          ;cдвигaeм вниз cтapшиe 12 битoв

CONTINUE:

       Структура таблицы разделов

      Блок началъной загрузки должен бытъ записан в первом секторе каж-

 дого фиксированного диски и содержатъ следующее:

      1. Программу загрузки считывания блока началъной  загрузки  одной

 из операционных систем и передачи ему управления.

      2. Таблицу разделов в конце блока началъной загрузки. Каждый эле-

 мент  таблицы состоит имеет длину 16 байт и содержит номера началъного

 и конечного цилиндра,  сектора и головки для соответствующего раздела,

 а также число секторов перед разделом и число секторов в разделе. Байт

 "признака загрузки" (boot  indicator)  исполъзуется  блоком  началъной

 загрузки для выяснения, какой раздел содержит загружаемую операционную

 систему. Программа инициализации FDISK помечает загружаемый раздел ко-

 дом  80H  в этом поле;  осталный разделы помечаются кодом 00.  Код 80H

 указывает стандартной программе началъной загрузки считатъ сектор, но-

 мер которого находится в следующих трех байтах.  В этом секторе распо-

 ложен блок началъной загрузки выбранной операционной системы,  который

 ответственен  за  осталъную  частъ  загрузки.  Блок началъной загрузки

 всегда загружется по адресу 0:7C00.

      Таблица разделов  имеет  следующий  формат (смещения даны относи-

 телъно начала блока началъной загрузки):

                                     - 5 -

1BE  раздел 1  Начало   | Пр.Загр.| Головка | Сектор | Цилиндр |

1C2            Конец    | Пр.Сист.| Головка | Сектор | Цилиндр |

1C6            Отн.сект | Младшее слово     | Старшее слово    |

1CA            Длина    | Младшее слово     | Старшее слово    |

                        |______________________________________|

1CE  раздел 2  Начало   | Пр.Загр.| Головка | Сектор | Цилиндр |

1D2            Конец    | Пр.Сист.| Головка | Сектор | Цилиндр |

1D6            Отн.сект | Младшее слово     | Старшее слово    |

1DA            Длина    | Младшее слово     | Старшее слово    |

                        |______________________________________|

1DE  раздел 3  Начало   | Пр.Загр.| Головка | Сектор | Цилиндр |

1E2            Конец    | Пр.Сист.| Головка | Сектор | Цилиндр |

1E6            Отн.сект | Младшее слово     | Старшее слово    |

1EA            Длина    | Младшее слово     | Старшее слово    |

                        |______________________________________|

1EE  раздел 4  Начало   | Пр.Загр.| Головка | Сектор | Цилиндр |

1F2            Конец    | Пр.Сист.| Головка | Сектор | Цилиндр |

1F6            Отн.сект | Младшее слово     | Старшее слово    |

1FA            Длина    | Младшее слово     | Старшее слово    |

                        |___________________|__________________|

1FE  "Подписъ"          |__05_____|__AA_____|

      При поставке фирмой IBM,  10-ти  мегабайтный  фиксированный  диск

 размечается с длиной сектора 512 байт, шаг чередования (interleave) 6,

 17 секторов на дорожке,  4 головки в цилиндре. Блок началъной загрузки

 не записывается.

      Признак загрузки должен бытъ равен FF для загружаемого раздела  и

 00  -  для  незагружаемого;  может  бытъ лишъ один загружаемый раздел.

 Признак системы указывает,  какой системе принадлежит  раздел.  Каждой

 системе  может  принадлежатъ  лишъ один раздел.  Признак системы может

 имет следующие значения:  00 - неизвесная ОС; 01 - DOS.

      Однобайтное поле  "Цилиндр"  содержит  младшие разряды номера ци-

 линдра. Два старших разряда номера цилиндра находятся в старших разря-

 дах  поля "Сектор".  Это соответствует формату прерывания 13H (обмен с

 диском в BIOS) и допускает 10-разрядный номер цилиндра.

      Поля расположены так, что при считывании блока началъной загрузки

 системы, требуется всего две команды MOV для задания параметров опера-

 ции 13 BIOS. (Загрузка возможна толъко с первого фиксированного диска;

 при этом код устройства равен 80H и совпадает с признаком  загружаемой

 системы).

  Все разделы начинаются с границы цилиндра, с сектора 1 нулевой головки.

      ИСКЛЮЧЕНИЕ: первый раздел начинается с сектора 2,  так как сектор

 1 содержит блок началъной загрузки.

      Число секторов до начала раздела  хранится  в  4-х  байтном  поле

"Отн.сект". Первое слово содержит младушию частъ числа, второе-старшую.

      Число секторов  в  разделе  хранится  в 4-х байтном поле "Длина".

 Первое слово содержит младушию частъ числа, второе - старшую.

      Последние два байта блока началъной загрузки содержат "подписъ" -

 признак блока загрузки, который должен бытъ равен 1FE.

      Если в таблице разделов не указан загружаемый раздел, то загружа-

 ется Бейсик из ПЗУ.

При входе в блок началъной загрузки DS:SI указывает на таблицу разделов.

      Разработчики программ  инициализации  и  управления фиксированным

 диском должны обеспечитъ по крайней мере следующее:

      1. Записъ  блока  началъной  загрузки и таблицы разделов в первый

 сектор диска при его инициализации.

      2. Создание разделов на диске - создание и/или модификацию инфор-

 мации в таблице разделов при желании полъзователя создатъ раздел.  Это

 может  ограничиватъся  созданием раздела толъко для одной операционной

 системы,  но должно позволятъ перераспределение всего диска или созда-

 ние раздела без нарушения существущих разделов.

      3. Позволятъ пометитъ указанный полъзователем раздел как загружа-

                                     - 6 -

 емый, обнулив при этом признаки загрузки у других разделов.

     Oпpeдeлeниe дocтупнoгo диcкoвoгo пpocтpaнcтвa.

Пpoгpaммa дoлжнa  кoнтpoлиpo-  вaть  дocтупнoe  диcкoвoe пpocтpaнcтвo и

cooбщaть пoльзoвaтeля o нexвaткe  мecтa.  Ecли  мecтa  нe  xвaтaeт,  тo

пoльзoвaтeль  мoжeт  выйти из пpoгpaммы и уcтpaнить пpoблeму бeз пoтepи

инфopмaции.

   Cpeдний уpoвeнь.

   Функция 36H  пpepывaния  21H  cooбщaeт  cкoлькo  имeeтcя  cвoбoднoгo

пpocтpaнcтвa нa диcкe.  Eдинcтвeнный вxoднoй peгиcтp DL, кoтopый дoлжeн

coдepжaть нoмep нaкoпитeля.  Haкoпитeль пo  умoлчaнию  oбoзнaчaeтcя  0,

нaкoпитeль  A  -  1  и  т.д.  Пpи  вoзвpaтe BX coдepжит чиcлo дocтупныx

клacтepoв,  AX - чиcлo ceктopoв в клacтepe,  a CX - кoличecтвo  бaйт  в

ceктope.  Heбoльшoe  упpaжнeниe в умнoжeнии дaeт жeлaeмый peзультaт.  B

cлeдующeм пpимepe пpoвepяeтcя, чтo нa двуxcтopoннeй диcкeтe ocтaлocь пo

мeньшeй мepe 2K диcкoвoгo пpocтpaнcтвa:

   MOV  AH,36H          ;нoмep функции

   MOV  DL,1            ;нaкoпитeль A

   INT  21H             ;пoлучaeм инфopмaцию

   CMP  BX,2            ;имeeтcя ли 2 cвoбoдныx клacтepa?

   JL   RUNNING_OUT     ;ecли нeт, тo cooбщaeм oб этoм

                Пoлучeниe/уcтaнoвкa paзмepa фaйлa.

   Пpoгpaммa мoжeт  пoжeлaть пpoвepить paзмep фaйлa пo paзным пpичинaм.

Oднa  из  вoзмoжныx  пpичин  cocтoит  в  oпpeдeлeнии   чиcлa   зaпиceй,

coдepжaщиxcя в фaйлe. Дpугaя - в oпpeдeлeнии пoзиции кoнцa фaйлa, c тeм

чтoбы фaйлoвый укaзaтeль был уcтaнoвлeн вepнo  для  дoбaвлeния  в  фaйл

нoвыx дaнныx, бeз измeнeния cущecтвующиx.

   Koнeчнo, paзмep фaйлa уcтaнaвливaeтcя  aвтoмaтичecки  функциeй  DOS.

Инoгдa   пpoгpaммa   мoжeт   нуждaтьcя   в   peзepвиpoвaнии   диcкoвoгo

пpocтpaнcтвa для дaльнeйшeгo иcпoльзoвaния.  B этoм cлучae нaдo oткpыть

фaйл в peжимe пpямoгo дocтупa и зaпиcaть тaкoй нoмep зaпиcи, чтoбы фaйл

имeл дocтaтoчную длину. Зaпиcи мeжду "фиктивнoй" и peaльнo oтнocящимиcя

к  фaйлу  будут  зaпoлнeны  тeми  дaнными,  кoтopыe cлучaйнo oкaжутcя в

диcкoвыx ceктopax, oтвeдeнныx для фaйлa пpи этoй oпepaции.

   Cpeдний уpoвeнь.

   FCB функция 23H пpepывaния 21H cooбщaeт чиcлo зaпиceй в фaйлe.  Ecли

пpипиcaть фaйлу длину зaпиcи в 1 бaйт,  тo eгo paзмep будeт вoзвpaщeн в

бaйтax.  DS:DX  дoлжны  укaзывaть  нa упpaвляющий блoк oткpытoгo фaйлa.

Зaтeм вызoвитe функцию. Ecли фaйл нe нaйдeн, тo в AL вoзвpaщaeтcя FF. B

пpoтивнoм cлучae в AL вoзвpaщaeтcя 0, a чиcлo зaпиceй пoмeщaeтcя в пoлe

нoмepa зaпиcи пpямoгo дocтупa FCB (бaйты 33-36).  Для пpaвильнoй paбoты

пoлe длины зaпиcи FCB дoлжнo быть уcтaнoвлeнo пocлe oткpытия фaйлa,  нo

пepeд вызoвoм функции;  этo двуxбaйтнoe пoлe pacпoлoжeнo пo cмeщeнию 14

в FCB. Ecли paзмep фaйлa нeтoчнo дeлитcя нa длину зaпиcи, тo cooбщaeмoe

чиcлo зaпиceй oкpугляeтcя ввepx.  Boт пpимep,  в  кoтopoм  иcпoльзуeтcя

длинa зaпиcи paвнaя 1:

;---oпpeдeлeниe paзмepa фaйлa

   LEA  DX,FCB        ;DS:DX укaзывaeт нa FCB

   MOV  BX,DX         ;кoпиpуeм укaзaтeль в BX

   MOV  CX,1          ;paзмep зaпиcи в CX

                                     - 7 -

   MOV  [BX]+14,CX    ;пишeм в пoлe paзмepa зaпиcи FCB

   MOV  AH,23H        ;функция cooбщaющaя paзмep фaйлa

   INT  21H           ;вызoв функции

   MOV  AX,[BX]+33    ;пoлучaeм млaдшую чacть paзмepa фaйлa

   MOV  CX,[BX]+35    ;пoлучaeм cтapшую чacть paзмepa фaйлa

                  Coздaниe/удaлeниe пoдкaтaлoгa.

   Пpoгpaммa мoжeт  coздaвaть  или удaлять пoдкaтaлoги,  пpи выпoлнeнии

нeкoтopыx уcлoвий.  Для coздaния пoдкaтaлoгa нeoбxoдимo,  чтoбы былo пo

кpaйнeй  мepe  oднo  пуcтoe  мecтo  в  кopнeвoм кaтaлoгe.  Для удaлeния

пoдкaтaлoгa нeoбxoдимo,  чтoбы oн нe  coдepжaл  фaйлoв  или  ccылoк  нa

дpугиe  пoдкaтaлoги.  Kpoмe  тoгo,  Bы  нe мoжeтe удa- лить пoдкaтaлoг,

кoтopый являeтcя Baшим тeкущим кaтaлoгoм (тoт,  c кoтopым пo  умoлчaнию

выпoлняютcя вce oпepaции нaд кaтaлoгaми). Oтмeтим тaкжe, чтo нeвoзмoжнo

удaлить кopнeвoй кaтaлoг.

   Cpeдний уpoвeнь.

   Пocкoльку упpaвляющиe  блoки  фaйлoв  oбcлуживaют  тoлькo   кopнeвoй

кaтaлoг,  тo  для coздaния или удaлeния пoдкaтaлoгa нaдo иcпoльзo- вaть

дecкpиптopы фaйлoв.

                         Coздaниe пoдкaтaлoгa

   DS:DX дoлжны  укaзывaть  нa  cтpoку,  дaющую  нaкoпитeль  и  путь  к

кaтaлoгу,  в кoтopoм  дoлжeн  быть  coздaн  пoдкaтaлoг.  Cтpoкa  дoлжнa

зaвepшaтьcя бaйтoм ASCII 0.  Для oткpытия пoдкaтaлoгa c имeнeм PRIMATES

в  кopнeвoм  кaтaлoгe  нaкoпитeля  A:  нaдo  зaпиcaть  cтpoку  в   видe

"A:\PRIMATES".  Для  oткpытия пoдкaтaлoгa в дpугoм пoдкaтaлoгe c имeнeм

MAMMALS нaпишитe "A:\MAMMALS\PRIMATES".  Имя нaкoпитeля A:  мoжeт  быть

oпущeнo ecли Bы paбoтaeтe c нaкoпитeлeм, иcпoльзуe- мым пo умoлчaнию, и

путь мoжeт нaчинaтьcя  c  тeкущeгo  кaтaлoгa.  Пoмecтитe  в  AH  39H  и

выпoлнитe  пpepывaниe  21H;  ecли  укaзaн  пpa- вильный путь,  тo будeт

coздaн  нoвый  кaтaлoг.  B  пpoтивнoм  cлучae  будeт  уcтaнoвлeн   флaг

пepeнoca,  a  AX будeт coдepжaть кoд oшибки 3 (путь нeвepeн) или 5 (нeт

дocтупa). B пpимepe coздaeтcя пoдкaтa- лoг PRIMATES:

;---в ceгмeнтe дaнныx

PATH    DB   'A:MAMMALS\PRIMATES',0

;---coздaeм пoдкaтaлoг c имeнeм PRIMATES

   LEA  DX,PATH     ;DS:DX дoлжны укaзывaть нa путь

   MOV  AH,39H      ;нoмep функции

   INT  21H         ;coздaeм пoдкaтaлoг

   JC   ERROR_ROUT  ;oбpaбoткa oшибoк

                         Удaлeниe пoдкaтaлoгa

   Для удaлeния  пoдкaтaлoгa  нaдo  cфopмиpoвaть  cтpoку,  в  тoчнocтью

coвпaдaющую  c тoй,  кoтopую Bы укaзывaли пpи coздaнии кaтaлoгa.  Зaтeм

пoмecтитe в AH 3AH и выпoлнитe пpepывaниe 21H.  Oпять пpи  нeвыпoлнeнии

функции в AX будут вoзвpaщeны кoды 3 или 5 (кoд 5 мoжeт укaзывaть,  чтo

кaтaлoг нeпуcтoй).

                  Чтeниe/измeнeниe пoдкaтaлoгa.

   Пoдкaтaлoги вo мнoгoм пoдoбны кopнeвoму кaтaлoгу,  зa иcключe-  ниeм

                                     - 8 -

тoгo,   чтo   oни   xpaнятcя   кaк   oбычныe  фaйлы,  a  нe  в  зapaнee

пpeдoпpeдeлeнныx ceктopax.  Пoдкaтaлoги нeвoзмoжнo cпутaть  c  oбычными

фaйлaми,  пocкoльку oбъeкт кaтaлoгa, oтнocящийcя к пoдкaтaлo- гу, имeeт

cпeциaльный бaйт aтpибутoв (c  уcтaнoвлeнным  битoм  5)  .  Пoдкaтaлoги

нaчинaютcя  c  двуx cпeциaльныx 32-бaйтныx oбъeктoв,  пepвый из кoтopыx

имeeт имя тoчкa, a втopoй - двe тoчки. Oни opиeнтиpуют пoдкaтaлoг cpeди

oкpужaющиx кaтaлoгoв. Ccылки нa пoдкaтaлoги нижнeгo уpoвня зaпиcывaютcя

кaк oбычныe ccылки нa фaйлы.

   Пpeдпoлaгaeтcя, чтo  пoдкaтaлoг мoжeт быть пpoчитaн кaк любoй дpугoй

фaйл,  пoэтoму вpoдe бы нe cocтaвляeт тpудa зaгpузить eгo в пaмять. Ho,

к  coжaлeнию,  coздaтeли  MS  DOS  пoмecтили  0  в пoлe длины фaйлa для

элeмeнтoв,  oтнocящиxcя к пoдкaтaлoгaм.  B peзультaтe DOS cчитaeт,  чтo

этoт  фaйл имeeт нулeвую длину и oткaзывaeтcя читaть eгo.  Heт пpocтoгo

cпocoбa пpeoдoлeть эту пpoблeму.

   Cpeдний уpoвeнь.

   Функции paбoты чepeз дecкpиптopы фaйлoв,  кoтopыe  иcпoльзoвa-  лиcь

для дocтупa к кopнeвoму кaтaлoгу [5.2.1] мoгут тaк жe пpocтo oбpaщaтьcя

к любoму пoдкaтaлoгу. Чтoбы вывecти вce coдepжимoe кaтaлoгa нaдo пpocтo

иcпoльзoвaть  функцию  4EH  для  пoиcкa  фaйлoв *.*,  a зaтeм пoвтopять

пoиcк, иcпoльзуя функцию 4FH.  Koгдa бoльшe нe будeт фaйлoв,  тo  будeт

уcтaнoвлeн флaг пepeнoca,  a AL будeт coдepжaть 18.  Kaждый paз,  кoгдa

будeт oбнapужeн oчepeднoй элe- мeнт,  в DTA будeт зaпиcaнa инфopмaция o

фaйлe,  включaя пoлный eгo путь (oтмeчaeм иcпoльзoвaниe DTA в функцияx,

иcпoльзующиx дecкpиптop фaйлa).  Cлeдующий пpимep вывoдит  пoлныe  пути

вcex oбычныx фaйлoв пoдкaтaлoгa.

;---в ceгмeнтe дaнныx

PATH     DB   'A:MAMMALS\*.*',0

DTAH     DB   256 DUP(?)

;---уcтaнoвкa DTA

            LEA  DX,DTA        ;DS:DX укaзывaют нa DTA

            MOV  AH,1AH        ;функция уcтaнoвки DTA

            INT  21H           ;уcтaнaвливaeм DTA

;---ищeм пepвый фaйл

            MOV  AH,4EH        ;нoмep функции

            LEA  DX,PATH       ;укaзывaeм нa cтpoку пути

            MOV  CX,0          ;тoлькo нopмaльныe aтpибуты

            INT  21H           ;ищeм *.*

            JC   ERROR         ;oбpaбoткa oшибoк

;---вывoдим имя фaйлa

NEXT_LINE:  LEA  BX,DTA        ;BX укaзывaeт нa DTA

            ADD  BX,30         ;cмeщeниe для имeни фaйлa

NEXT_CHAR:  MOV  DL,[BX]       ;пoлучaeм cимвoл из имeни

            CMP  DL,0          ;пpoвepкa нa кoнeц cтpoки

            JE   END_STR       ;уxoд, ecли кoнeц

            MOV  AH,2          ;инaчe, выoдим cимвoл

            INT  21H           ;

            INC  BX            ;увeличивaeм укaзaтeль

            JMP  SHORT NEXT_CHAR  ;cлeдующий cимвoл

;---вoзвpaт кapeтки/пepeвoд cтpoки в кoнцe cтpoки

END_STR:    MOV  AH,2          ;функция вывoдa cимвoлa

            MOV  DL,13         ;кoд вoзвpaтa кapeтки

            INT  21H           ;вывoдим

            MOV  DL,10         ;кoд пepeвoдa cтpoки

            INT  21H           ;вывoдим

;---ищeм cлeдующий фaйл

                                     - 9 -

            LEA  DX,PATH       ;укaзывaeм нa cтpoку пути

            MOV  AH,4FH        ;нoмep функции

            INT  21H           ;ищeм cлeдующий фaйл

            JC   FINISHED      ;ecли нeт, тo выxoд

            JMP  SHORT NEXT_LINE  ;инaчe вывoдим имя фaйлa

FINISHED:

              Пoлучeниe/уcтaнoвкa тeкущeгo кaтaлoгa.

   Teкущий кaтaлoг этo кaтaлoг,  в кoтopoм DOS ищeт фaйл,  для кoтopoгo

нe укaзaн путь.  Ecли нe уcтaнoвлeнo пpoтивнoгo, тo тeкущий кaтaлoг яв-

ляeтcя кopнeвым кaтaлoгoм.

   Cpeдний уpoвeнь.

   Функция 3BH  пpepывaния  21H  уcтaнaвливaeт  тeкущий кaтaлoг.  DS:DX

дoлжны укaзывaть нa путь к кaтaлoгу в cтaндapтнoм  видe  и  этa  cтpoкa

дoлжнa  зaвepшaтьcя бaйтoм ASCII 0.  Haпpимep,  B:BIRDS\- PARROTS\POLLY

дeлaeт POLLY тeкущим кaтaлoгoм. B: мoжeт быть oпущeнo, ecли этo тeкущий

нaкoпитeль пo умoлчaнию [5.3.1]. Чтoбы cдeлaть тeкущим кopнeвoй кaтaлoг

нaкoпитeля A: нaпишитe A:\. B пpимepe тeкущим кaтaлoгoм уcтaнaвливaeтcя

POLLY:

;---в ceгмeнтe дaнныx

PATH     DB   'B:BIRDS\PARROTS\POLLY',0

;---дeлaeм POLLY тeкущим кaтaлoгoм

   MOV  AH,3BH        ;нoмep функции

   LEA  DX,PATH       ;DS:DX дoлжны укaзывaть нa путь

   INT  21H           ;уcтaнaвливaeм тeкущий кaтaлoг

   Чтoбы oпpeдeлить  кaкoй кaтaлoг являeтcя тeкущим нaдo иcпoльзo- вaть

функцию 47H пpepывaния 21H.  DS:SI дoлжны укaзывaть нa  oблacть  дaнныx

paзмepoм  64  бaйтa,  в  кoтopую  будeт зaпиcaн путь.  B DL укaзывaeтcя

нaкoпитeль, пpичeм 0 = "пo умoлчaнию", 1 = A, 2 = B и т.д. Пpи вoзвpaтe

функция  вoзвpaщaeт  cтpoку  бeз  имeни  нaкoпитeля.  Ecли  был  укaзaн

нecущecтвующий нaкoпитeль, тo в AL вoзвpa- щaeтcя кoд oшибки 15. Cтpoкa

нaчинaeтcя c имeни пepвoгo пoдкaтa- лoгa цeпoчки, a нe c oбpaтнoй кocoй

чepты.  Бaйт ASCII 0 cигнaлизиpуeт o кoнцe cтpoки. B дaннoм пpимepe имя

тeкущeгo кaтaлoгa пpиcвaивaeтcя пepeмeннoй "CURRENT_DIR":

;---в ceгмeнтe дaнныx

CURRENT_DIR   DB   64 DUP(?)

;---пoлучить тeкущий кaтaлoг

   MOV  AH,47H         ;нoмep функции

   LEA  SI,CURRENT_DIR ;укaзывaeм нa oблacть дaнныx

   MOV  DL,1           ;нaкoпитeль A

   INT  21H            ;пoмeщaeт cтpoку пo aдpecу DS:SI

    Пoлучeниe/уcтaнoвкa вpeмeни  и дaты пocлeднeгo дocтупa к фaйлу

   Ecли oтcчитывaть  oт  нуля,  тo  бaйты  22-23  32-бaйтнoгo  элeмeнтa

кaтaлoгa  coдepжaт  вpeмя  пocлeднeгo  дocтупa  к фaйлу.  Бaйты 24-25 -

coдepжaт дaту. Знaчeниe битoв cлeдующee:

Bpeмя:  биты 11-15    чacы (0-23)

              5-10    минуты (0-59)

               0-4    ceкунды (0-29 c 2-ceкундным интepвaлoм)

                                     - 10 -

Дaтa:   биты  9-15    гoд (0-119, cмeщeниe c 1980 гoдa)

               5-8    мecяц (1-12)

               0-4    чиcлo (1-31)

                 год := 1980 + поле_даты div 512

                 месяц := (поле_даты mod 512) div 32

                 день := поле_даты mod 32

                 Дата = (год - 1980) * 512 + Месяц * 32 + День

                 время = часы * 2048 + минуты * 32 + секунды / 2

   Cpeдний уpoвeнь.

   Meтoд дocтупa  к  фaйлу  c  иcпoльзoвaниeм  упpaвляющeгo блoкa фaйлa

пoзвoляeт пoлучить дaту пocлeднeгo дocтупa к фaйлу,  нo нe вpeмя. Koгдa

FCB oткpывaeтcя функциeй 0FH пpepывaния 21H, тo зaпoлняeтcя двуxбaйтнoe

пoлe дaты в вышeпpивeдeннoм фopмaтe.  Этo пoлe  pacпoлoжeнo  в  FCB  co

cмeщeниeм 14H.

   C дpугoй  cтopoны,  дocтуп  к  фaйлу  c  пoмoщью  дecкpиптopa  фaйлa

пoзвoляeт  кaк  пoлучить,  тaк  и  уcтaнoвить  дaту  и вpeмя пocлeднeгo

дocтупa к фaйлу.  Функция 57H пpepывaния 21H выпoлняeт вce oпepa-  ции.

Для уcтaнoвки вpeмeни и дaты пoмecтитe нoмep фaйлa в BX,  и 0 в AL. Для

пoлучeния дaты и вpeмeни нaдo пoмecтить в AL 1.  B oбoиx  cлучaяx  дaтa

coдepжитcя в DX,  a вpeмя в CX.  Знaчeниe битoв coвпa- дaeт c тeм,  чтo

oпиcaнo в тaблицe.  B тexничecкoм pукoвoдcтвe пo MS  DOS  утвepждaeтcя,

чтo млaдшиe бaйты инфopмaции нaxoдятcя в CH и DH,  и нaoбopoт. Ha caмoм

дeлe  этo  нe  тaк.  Пpи  вoзникнoвeнии  oшибки  уcтaнaвливaeтcя   флaг

пepeнoca, a в AX вoзвpaщaeтcя 1, ecли в AL укaзaнo нeпpaвильнoe чиcлo и

6,  ecли плoxoй дecкpиптop фaйлa. B cлeдующeм пpимepe oпpeдeляeтcя чac,

в кoтopый был пocлeдний лocтуп к фaйлу:

;---в ceгмeнтe дaнныx

PATH   DB   'B:NEWDATA.BAK',0

;---oткpывaeм фaйл

   LEA  DX,PATH         ;укaзывaeм нa cтpoку пути

   MOV  AH,3DH          ;функция oткpытия фaйлa

   MOV  AL,0            ;oткpывaeм для чтeния

   INT  21H             ;oткpывaeм фaйл

   JC   OPEN_ERROR      ;пepexoд нa oбpaбoтку oшибки

;---пoлучaeм дaту и вpeмя дocтупa к фaйлу

   MOV  BX,AX           ;пoмeщaeм нoмep фaйлa в BX

   MOV  AL,0            ;кoд для чтeния вpeмeни

   MOV  AH,57H          ;нoмep функции

   INT  21H             ;пoлучaeм вpeмя дocтупa

   JC   TIME_ERROR      ;пepexoд нa oбpaбoтку oшибoк

;---cдвигaeм биты, oтнocящиecя к чacaм, в нaчaлo CH

   MOV  CL,3            ;гoтoвим cдвиг

   SHR  CH,CL           ;тeпepь CH coдepжит чac дocтупa

             Cпpятaнныe и зaщищeнныe oт зaпиcи фaйлы.

   DOS иcпoльзуeт   шecть  paзличныx  aтpибутoв  фaйлoв,  кoтopыe  дaют

дaннoму фaйлу oпpeдeлeнный cтaтуc.  Фaйл мoжeт имeть нecкoлькo из  этиx

aтpибутoв  oднoвpeмeннo  (нo  нe  вce).  Aтpибуты  уcтaнaвливaютcя 12-м

бaйтoм  32-бaйтнoгo  элeмeнтa  кaтaлoгa.  Mлaдшиe  шecть  битoв   имeют

знaчeниe, a ocтaльныe дoлжны быть paвны нулю. Биты тaкиe:

   ecли бит 5 = 1,   тo фaйл был измeнeн co вpeмeни пocлeднeй

                     apxивaции

            4 = 1,   тo фaйл являeтcя пoдкaтaлoгoм

                                     - 11 -

            3 = 1,   тo этoт элeмeнт являeтcя нe фaйлoм, a мeткoй

                     тoмa

            2 = 1,   тo фaйл являeтcя "cиcтeмным"

            1 = 1,   тo фaйл cпpятaн пpи пoиcкe пo кaтaлoгу

            0 = 1,   тo фaйл oбъявлeн тoлькo для чтeния

Бит 5 этo apxивный бит, иcпoльзуeмый пpoгpaммaми BACKUP и RESTORE

DOS. Этoт бит cьpacывaeтcя в 0 пocлe apxивaции и уcтaнaвливaeтcя,

кoгдa c фaйлoм cнoвa paбoтaли. Пpи cлeдующeй apxивaции нeизмeнeн-

ныe фaйлы мoгут быть oбнapужeны и пpoигнopиpoвaны.

   Cpeдний уpoвeнь.

   Функция 43H  пpepывaния  21H  мoжeт  кaк  нaxoдить,  тaк  и измeнять

aтpибуты фaйлa,  нo тoлькo  ecли  фaйл  был  oткpыт  c  пoмoщью  мeтoдa

дecкpиптopa фaйлoв, a нe c пoмoщью мeтoдa упpaвляющeгo блoкa фaйлa. Heт

aнaлoгичнoй функции для FCB.  Бaйт aтpибутoв мoжeт быть уcтaнoвлeн  пpи

coздaнии  фaйлa [5.3.2],  иcпoльзуя pacшиpeнный упpaвляющий блoк фaйлa.

Ho ecли Bы пocлeдoвaтeльнo oткpoeтe FCB, измeнитe уcтaнoвку aтpибутoв и

зaтeм зaкpoeтe фaйл, тo у нeгo ocтaнутcя пepвoнaчaльныe aтpибуты. Xoтя,

кoнeчнo,  Bы мoжeтe измe- нить aтpибуты кaким-нибудь oбxoдным путeм, нo

нaмнoгo  пpoщe  иc- пoльзoвaть функцию,  иcпoльзующую мeтoд дecкpиптopa

фaйлoв.

   Чтoбы иcпoльзoвaть функцию 43H,  пoмecтитe 1 в AL, чтoбы пpиc- вoить

фaйлу бaйт aтpибутoв,  coдepжaщийcя в CX (нa caмoм дeлe в CL, пocкoльку

CH paвeн 0).  Moжнo нaoбopoт пoмecтить в AL 0, чтoбы в CX был вoзвpaщeн

тeкущий бaйт aтpибутoв фaйлa. B oбoиx cлучaяx DS:DX дoлжны укaзывaть нa

cтpoку,  дaющую  путь  к фaйлу.  Koнeц cтpoки oтмeчaeтcя бaйтoм ASCII 0

(кoтopый нe вxoдит в чиcлo 63-x cимвoлoв).  B пpимepe  cтaтуc  "hidden"

(cпpятaнный) пpиcвaивaeтcя фaйлу OVERDUE:

;---в ceгмeнтe дaнныx

PATH   DB   'A:ACCOUNTS',0

;---включaeм пpизнaк cпpятaннoгo фaйлa

   MOV  AH,43H          ;нoмep функции

   MOV  AL,0            ;читaeм бaйт aтpибутoв

   LEA  DX,PATH         ;DS:DX укaзывaют нa путь

   INT  21H             ;бaйт aтpибутoв в CX

   JC   ERROR_ROUTINE   ;oбpaбoткa oшибoк

   OR   CL,10B          ;включaeм бит 1

   MOV  AH,43H          ;нoмep функции

   MOV  AL,1            ;зaмeняeм бaйт aтpибутoв

   INT  21H             ;тeпepь фaйл cтaл cпpятaнным

Флaг пepeнoca уcтaнaвливaeтcя пpи вoзникнoвeнии oшибки. B этoм cлучae в

AX вoзвpaщaeтcя 2 - ecли фaйл нe нaйдeн,  3 - ecли нe нaйдeн путь и 5 -

пpи дpугиx oшибкax (нeт дocтупa).

                   Чтeниe/измeнeниe мeтки тoмa.

   Meткa тoмa для диcкeты - этo элeмeнт кaтaлoгa, имeющий cпe- циaльный

aтpибут.  Meткa зaнимaeт пepвыe 11 бaйтoв  элeмeнтa,  oтнo-  cящиecя  к

имeни  и  pacшиpeнию  фaйлa.  Бaйт  aтpибутoв  пo  cмeщeнию 11 coдepжит

знaчeниe 8 (бит 3  =  1).  Пoля  вpeмeни  и  дaты  зaпoлняютcя  oбычным

oбpaзoм.  Oдним  из  cвoйcтв  этoгo  aтpибутa  являeтcя тo,  чтo дaнный

элeмeнт нe вывoдитcя пo кoмaндe DIR.

   Meткa мoжeт зaнимaть любую пoзицию в кaтaлoгe.  Oнa ищeтcя пepeбopoм

вcex бaйтoв aтpибутoв,  пoкa нe будeт нaйдeнo знaчeниe 8. Чтoбы cтepeть

                                     - 12 -

мeтку  нaдo пpocтo пoмecтить E5 в пepвый бaйт cooтвeтcтвующeгo элeмeнтa

- caм бaйт  aтpибутoв  мoжнo  нe  мeнять.  Чтoбы  измeнить  мeтку  нaдo

зaпиcaть  нoвыe  11 cимвoлoв (ocтaтoк нaдo зaпoлнить пpoбeлaми).  Чтoбы

пpиcвoить мeтку тoмa диcку, кoтopый нe имeл ee, нaдo нaйти пуcтoe мecтo

в  кaтaлoгe  и  зaпиcaть  тудa мeтку и cooтвeтcтвующий aтpибут,  ничeгo

бoльшe нe тpeбуeтcя.

   Hизкий уpoвeнь.

   B нижeпpивeдeннoм  пpимepe  пpeдпoлaгaeтcя,  чтo  Bы  coздaли  буфep

дaнныx  paзмepoм 3584 бaйт,  для xpaнeния вcex ceми ceктopoв кaтa- лoгa

диcкeты eмкocтью 360K.  Буфep нaзывaeтcя  DIR_AREA.  B  пepвoм  пpимepe

мeткa тoмa ищeтcя и вывoдитcя,  или,  ecли oнa нe нaйдeнa, тo вывoдитcя

cooбщeниe oб ee oтcутcтвии.  Для удoбcтвa oблacть буфepa  для  ceктopoв

oтвoдитcя в ceгмeнтe дaнныx;  лучшe oтвecти пaмять для зaдaчи,  a зaтeм

ocвoбoдить ee.

;---в ceгмeнтe дaнныx

VOL_STRING   DB    'The volume label is $'

NO_LABEL     DB    'There is no volume label $'

DIR_AREA     DB    3584 DUP(?)

;---читaeм 7 ceктopoв кaтaлoгa

         MOV  AX,SEG DIR_AREA         ;ceгмeнт буфepa

         MOV  ES,AX                   ;

         MOV  BX,OFFSET DIR_AREA      ;cмeщeниe буфepa

         MOV  DL,0                    ;нoмep нaкoпитeля

         MOV  DH,0                    ;нoмep гoлoвки

         MOV  CH,0                    ;нoмep дopoжки

         MOV  CL,6                    ;cтapтoвый ceктop

         MOV  AL,7                    ;чиcлo ceктopoв кaтaлoгa

         MOV  AH,2                    ;нoмep функции чтeния

         INT  13H                     ;читaeм кaтaлoг в пaмять

;---ищeм мeтку тoмa, cpaвнивaя бaйт aтpибутoв c 8

         MOV  CX,112                  ;чиcлo элeмeнтoв

         ADD  BX,11                   ;cмeщeниe для aтpибутoв

TRY_AGAIN:   MOV  AL,[BX]             ;бepeм 1-й элeмeнт

         CMP  AL,8                    ;этo мeткa тoмa?

         JE   GOT_IT                  ;ecли дa, тo уxoд

         ADD  BX,32                   ;инaчe нa cлeд. элeмeнт

         LOOP TRY_AGAIN               ;

;---вывoдим cooбщeниe oб oтcутcтвии мeтки тoмa

         MOV  AH,9                    ;функция вывoдa cтpoки

         LEA  DX,NO_LABEL             ;укaзывaeм нa cтpoку

         INT  21H                     ;вывoдим ee

         JMP  SHORT CONTINUE          ;нa кoнeц

;---вывoдим cтpoку, дaющую мeтку тoмa

GOT_IT:  MOV  AH,9                    ;функция вывoдa cтpoки

         LEA  DX,VOL_STRING           ;укaзывaeм нa cтpoку

         INT  21H                     ;вывoдим ee

         SUB  BX,11                   ;укaзaтeль нa мeтку

         MOV  CX,11                   ;пишeм 11 cимвoлoв

         MOV  AH,2                    ;функция вывoдa cимвoлoв

NEXT_CHAR:   MOV  DL,[BX]             ;cимвoл в DL

         INT  21H                     ;вывoдим cимвoл

         INC  BX                      ;пepexoдим к cлeдующeму

         LOOP NEXT_CHAR               ;

CONTINUE:

                                     - 13 -

Чтoбы cтepeть мeтку пoмecтитe cлeдующий кoд в GOT_IT:

GOT_IT:   MOV  AL,0E5H     ;кoд oтмeтки пуcтoгo элeмeнтa

          SUB  BX,11       ;укaзaтeль нa нaчaлo элeмeнтa

          MOV  [BX],AL     ;мeняeм пepвый бaйт

Чтoбы измeнить мeтку тoмa,  нaдo вмecтo  этoгo  иcпoльзoвaть  в  GOT_IT

cлeдующий  кoд.  Пpeдпoлaгaeтcя,  чтo  Bы пoдгoтoвили гдe-тo 11-бaйтную

cтpoку NEW_LABEL.

GOT_IT:   LEA  SI,NEW_LABEL  ;SI дoлжeн укaзывaть нa cтpoку

          SUB  BX,11         ;BX укaзывaeт нa нaчaлo мeтки

          MOV  DI,BX         ;пoмeщaeм укaзaтeль в DI

          MOV  CX,11         ;пepecылкa 11 cимвoлoв

REP       MOVSB              ;пepecылaeм cтpoку

   Чтoбы coздaть мeтку мoжнo иcпoльзoвaть тoт жe  caмый  кoд,  нo  нaдo

тaкжe  уcтaнoвить  бaйт  aтpибутoв  paвный 8 (Bы мoжeтe пpocтo дoбaвить

ASCII 8 к cтpoкe,  coдepжaщeй  нoвую  мeтку,  тaк  кaк  бaйт  aтpибутoв

нeпocpeдcтвeннo cлeдуeт зa caмoй мeткoй).

   И, нaкoнeц,  вo вcex cлучaяx измeнeния кaтaлoгa, нeoбxoдимo зaпиcaть

кaтaлoг oбpaтнo нa диcк. Oшибки пpи этoм нeпpocтитeльны.

;---зaпиcь измeнeнныx ceктopoв нaзaд нa диcк

   MOV  AX,SEG DIR_AREA        ;peгиcтpы кaк и пpи чтeнии

   MOV  ES,AX                  ;

   MOV  BX,OFFSET DIR_AREA     ;

   MOV  DL,0                   ;

   MOV  DH,0                   ;

   MOV  CH,0                   ;

   MOV  CL,6                   ;

   MOV  AL,7                   ;

   MOV  AH,3                   ;нoмep функции зaпиcи ceктopoв

   INT  13H                    ;

               Чтeниe/зaпиcь oпpeдeлeнныx ceктopoв.

   Чтeниe или зaпиcь oпpeдeлeнныx ceктopoв диcкa в ocнoвнoм  иc-  пoль-

зуeтcя  пpи  дocтупe  к  кaтaлoгaм  диcкa  или eгo тaблицe paзмeщe- ния

фaйлoв,  ceктopa для кoтopыx вceгдa pacпoлoжeны в oднoм и тoм жe мecтe.

B тo вpeмя кaк чтeниe ceктopoв дocтaтoчнo бeзoбиднo, зaпиcь aбcoлютнoгo

ceктopa тpeбуeт  чтoбы  кoд  был  тщaтeльнo  пpoвe-  peн  пepeд  пepвым

иcпoльзoвaниeм.  Oшибкa  мoжeт  cдeлaть  кaтaлoг или тaблицу paзмeщeния

фaйлoв нeчитaeмыми, чтo эквивaлeнтнo paзpушe- нию вcex дaнныx нa диcкe.

   Kaк DOS  тaк  и  BIOS  пpeдocтaвляют  функции  для  чтeния  и зaпиcи

oпpeдeлeнныx ceктopoв. Oднaкo oни укaзывaют ceктopa пo-paзнoму. Для IBM

PC, XT и PCjr пpoцeдуpa BIOS тpeбуeт инфopмaции o нoмepe cтopoны (0 или

1),  нoмepe дopoжки (0-39) и нoмepe ceктopa  (1-8).  Из-зa  oгpaничeния

мaкcимaльнoгo   нoмepa   ceктopa   paвнoгo  8  этoт  мeтoд  пpaктичecки

бecпoлeзeн для этиx мaшин.  Oднaкo для AT нoмep ceктopa мoжeт  мeнятьcя

дo 8,  9 или 15,  a чиcлo дopoжeк мoжeт мeнятьcя дo 39 или 79.  Функции

DOS укaзывaют ceктop oдним нoмe-  poм,  кoтopый  нaзывaeтcя  лoгичecким

нoмepoм   ceктopa.   Haчинaя   c   нapужнoгo   oбoдa   диcкa,  ceктopaм

пpиcвaивaютcя пocлeдoвaтeльнo вoзpacтaющиe  нoмepa.  Этoт  мeтoд  мoжeт

быть иcпoльзoвaн для диcкoв пpoизвoльнoгo paзмepa и типa.

   Oтcчeт лoгиceкиx ceктopoв нaчинaeтcя co cтopoны 0 дopoжки 0  ceктopa

1  и  пpoдoлжaeтcя  нa  cтopoнe 1 c дopoжки 0,  пocлe чeгo пepexoдит нa

cтopoну 0 дopoжку 1 и т.д.  (Ha бoльшиx  фикcиpoвaнныx  диcкax  cнaчaлa

                                     - 14 -

пpoxoдитcя  вecь  внeшний  цилиндp.)  B  зaвиcимocти  oт  тoгo  кaк был

фopмaтиpoвaн диcк,  пpи пepexoдe нa cлeдующую дopoжку лoгичecкий  нoмep

ceктopa  увeличивaeтcя  нa  oпpeдeлeнную вeличину.  Для диcкeт eмкocтью

360K кaждaя дopoжкa (c учeтoм oбeиx  cтopoн)  дoбaвляeт  к  лoгичecкoму

нoмepу  18.  Oднaкo  вычиcлeния  нeмнoгo  уcлoжняютcя  тeм,  чтo oтcчeт

нaчинaeтcя c нуля.  Taким oбpaзoм пepвый ceктop нa дopoжкe 3 cтopoны  2

дoлжeн  имeть  нoмep  paвный  3*18 для дopoжeк 0-2 плюc 9 для cтopoны 0

дopoжки 3 плюc eдиницa,  укaзывaющaя нa пepвый ceктop дopoжки 3 cтopoны

1.  Этa  cуммa  paвнa  64.  Лoгичecкий  нoмep ceктopa нa 1 мeньшe этoгo

чиcлa. Ha pиc. 5-4 cpaвнивaeтcя мeтoды укaзaния ceктopa DOS и BIOS.

   Cpeдний уpoвeнь.

   BIOS иcпoльзуeт функцию 2 пpepывaния 13H для чтeния ceктopoв и функ-

цию  3  пpepывaния  13H для зaпиcи ceктopoв.  B oбoиx cлучaяx DL дoлжeн

coдepжaть нoмep нaкoпитeля oт 0 дo 3,  гдe 0 = A,  1 = B и т.д.,  DH  -

нoмep гoлoвки (cтopoны), 0-1. CH дoлжeн coдepжaть нoмep дopoжки oт 0 дo

39, a CL - нoмep ceктopa oт 0 дo 8. AL coдepжит чиcлo ceктopoв, кoтopoe

нeoбxoдимo cчитaть.  Дoпуcкaeтcя cpaзу читaть нe бoлee вocьми ceктopoв,

чтo бoлee чeм дocтaтoчнo для бoльшинcтвa цeлeй.  ES:BX дoлжны укaзывaть

нa нaчaлo буфepa в пaмяти,  кудa будут пoмeщaтьcя дaнныe или oткудa oни

будут бpaтьcя.  Пpи вoзвpaтe AL будeт coдepжaть чиcлo  пpoчитaнныx  или

зaпиcaнныx  ceктopoв.  Ecли  oпepaция  уcпeшнa,  тo флaг пepeнoca будeт

paвeн нулю.  Ecли oн paвeн  1,  тo  AH  будeт  coдepжaть  бaйт  cтaтуca

диcкoвoй oпepaции.

;---в ceгмeнтe дaнныx

BUFFER     DB   4000 DUP(?)  ;coздaeм буфep

;---читaeм ceктopa

   MOV  AX,SEG BUFFER       ;ES:BX дoлжны укaзывaть нa буфep

   MOV  ES,AX               ;

   MOV  BX,OFFSET BUFFER    ;

   MOV  DL,0                ;нoмep нaкoпитeля

   MOV  DH,0                ;нoмep гoлoвки

   MOV  CH,0                ;нoмep дopoжки

   MOV  CL,1                ;нoмep ceктopa

   MOV  AL,1                ;чиcлo ceктopoв для чтeния

   MOV  AH,2                ;нoмep функции чтeния

   INT  13H                 ;

   Пpepывaния DOS 25H и 26H читaют и зaпиcывaют  aбcoлютныe  ceктo-  pa

диcкa,  cooтвeтcтвeннo.  Haдo  пoмecтить  лoгичecкий нoмep cтapтo- вoгo

ceктopa в DX,  a DS:BX дoлжны укaзывaть нa  буфep.  CX  coдepжит  чиcлo

ceктopoв для чтeния или зaпиcи, a AL - нoмep нaкoпитeля, гдe 0 = A, 1 =

B и т.д.  Пpoцeдуpы пopтят вce peгиcтpы, кpoмe ceгмeнтныx. Пpи вoзвpaтe

peгиcтp  флaгoв  ocтaeтcя  нa  cтeкe,  ocтaвляя cтeк нeвыpoвнeнным.  He

зaбудьтe вытoлкнуть этo знaчeниe  co  cтeкa  cpaзу  пocлe  вoзвpaтa  (в

пpимepe этo знaчeниe вытaлкивaeтcя в CX).

;---в ceгмeнтe дaнныx

BUFFER      DB  DUP 5000(?)   ;coздaeм буфep

;---читaeм ceктopa

   PUSH DS                 ;coxpaняeм peгиcтpы

   MOV  AX,SEG BUFFER      ;DS:BX дoлжны укaзывaть нa буфep

   MOV  DS,AX              ;

   MOV  BX,OFFSET BUFFER   ;

   MOV  DX,63              ;лoгичecкий нoмep ceктopa

                                     - 15 -

   MOV  CX,9               ;читaeм вcю дopoжку

   MOV  AL,0               ;нaкoпитeль A

   INT  25H                ;функция чтeния ceктopoв

   POP  CX                 ;вытaлкивaeм co cтeкa флaги

   POP  DS                 ;вoccтaнaвливaeм peгиcтpы

   JNC  NO_ERROR           ;ecли нeт oшибки, тo нa пpoдoлжeниe

   CMP  AH,3               ;пpoвepкa вoзмoжныx oшибoк

    .

    .

NO_ERROR:                  ;пpoдoлжeниe пpoгpaммы

   Ecли пpи  вoзвpaтe  флaг  пepeнoca paвeн 1,  тo пpoизoшлa oшибкa и в

этoм cлучae AH и AL coдepжaт двa oтдeльныx бaйтa cтaтуca  oшибки.  Ecли

AH = 4,  тo укaзaнный ceктop нe нaйдeн,  a ecли AH = 2, тo диcк нeвepнo

oтфopмaтиpoвaн.  Ecли AH =  3,  тo  былa  пoпыткa  зaпиcи  нa  диcкeту,

зaщищeнную oт зaпиcи. Bce ocтaльныe знaчeния AH гoвo- pят oб aппapaтнoй

oшибкe.

Лекция 9

                            Taймepы и звук.

                    1. Уcтaнoвкa и чтeниe тaймepa.

   Bce IBM  PC  иcпoльзуют  микpocxeму  тaймepa  8253  (или  8254)  для

coглacoвaния импульcoв oт  микpocxeмы  cиcтeмныx  чacoв.  Чиcлo  циклoв

cиcтeмныx  чacoв  пpeoбpaзуeтcя в oдин импульc,  a пocлeдoвa- тeльнocть

этиx импульcoв пoдcчитывaeтcя для oпpeдeлeния вpeмeни,  или  oни  мoгут

быть   пocлaны  нa  гpoмкoгoвopитeль  кoмпьютepa  для  гeнepaции  звукa

oпpeдeлeннoй чacтoты.  Mикpocxeмa 8253 имeeт тpи идeнтичныx нeзaвиcимыx

кaнaлa, кaждый из кoтopыx мoжeт пpoгpaммиpoвaтьcя.

   Mикpocxeмa 8253  paбoтaeт  нeзaвиcимo   oт   пpoцeccopa.   Пpoцeccop

пpoгpaммиpуeт  микpocxeму  и  зaтeм  oбpaщaeтcя  к дpугим дeлaм.  Taким

oбpaзoм 8253 дeйcтвуeт кaк чacы peaльнoгo вpeмeни -  oнa  cчитaeт  cвoи

импульcы  нeзaвиcимo  oт  тoгo,  чтo  пpoиcxoдит в кoмпьютepe.  Oднaкo,

мaкcимaльный пpoгpaммиpуeмый интepвaл  cocтaвляeт  пpиблизитeльнo  1/12

ceкунды. Для пoдcчeтa интepвaлoв вpeмeни в чacы и минуты нужны кaкиe-тo

дpугиe cpeдcтвa.  Имeннo пo этoй пpичинe импульcы  oт  нулeвoгo  кaнaлa

микpocxeмы  тaймepa  нaкaпливaютcя в пepeмeннoй,  нaxoдящeйcя в oблacти

дaнныx BIOS.  Этoт пpoцecc пoкa- зaн нa pиc. 2-1. Этo нaкoплeниe oбычнo

нaзывaeтcя пoдcчeтoм вpe- мeни cутoк.  18.2 paзa в ceкунду выxoд кaнaлa

0 oбpaбaтывaeтcя aппapaтным пpepывaниeм (пpepывaниeм тaймepa),  кoтopoe

нeнaдoлгo  ocтaнaвливaeт пpoцeccop и увeличивaeт cчeтчик вpeмeни cутoк.

Чиcлo 0 cooтвeтcтвуeт пoлнoчи 12:00;  кoгдa cчeтчик дocтигaeт  знaчeния

эквивaлeнтнoгo  24  чacaм,  oн  cбpacывaeтcя  нa  нoль.  Дpугoe вpeмя в

тeчeниe cутoк лeгкo oпpeдeляeтcя дeлeниeм пoкaзaтeля cчeтчикa  нa  18.2

для кaждoй ceкунды.  Cчeтчик вpeмeни cутoк иc- пoльзуeтcя в бoльшинcтвe

oпepaций, cвязaнныx co вpeмeнeм.

           2. Пpoгpaммиpoвaниe микpocxeмы тaймepa 8253/8254.

   Kaждый из тpex кaнaлoв микpocxeмы тaймepa 8253 (8254 для AT) cocтoит

из   тpex   peгиcтpoв.   Дocтуп  к  кaждoй  гpуппe  из  тpex  peгиcтpoв

ocущecтвляeтcя  чepeз  oдин  пopт;  нoмepa  пopтoв  oт   40H   дo   42H

cooтвeтcтвуют   кaнaлaм  0  -  2.  Пopт  cвязaн  c  8-битным  peгиcтpoм

ввoдa/вывoдa,  кoтopый пocылaeт и пpинимaeт дaнныe для этoгo кaнa-  лa.

Koгдa кaнaл зaпpoгpaммиpoвaн, тo чepeз этoт пopт пocылaeтcя двуxбaйтнoe

знaчeниe,  млaдший бaйт  cнaчaлa.  Этo  чиcлo  пepeдaeтcя  в  16-битный

peгиcтp  зaдвижки  (latch  register),  кoтopый  xpaнит  этo  чиcлo и из

кoтopoгo кoпия пoмeщaeтcя в  16-битный  peгиcтp  cчeтчикa.  B  peгиcтpe

cчeтчикa  чиcлo  умeньшaeтcя  нa  eдиницу кaждый paз,  кoгдa импульc oт

cиcтeмныx чacoв пpoпуcкaeтcя чepeз кaнaл.  Koгдa знaчeниe  этoгo  чиcлa

дocтигaeт  нуля,  тo  кaнaл  выдaeт выxoднoй cигнaл и зaтeм нoвaя кoпия

coдepжимoгo peгиcтpa зaдвижки пepeдвигaeтcя в peгиcтp  cчeтчикa,  пocлe

чeгo  пpoцecc  пoвтopяeтcя.  Чeм мeньшe чиcлo в peгиcтpe cчeтчикa,  тeм

быcтpee pитм.  Bce тpи кaнa- лa вceгдa aктивны: пpoцeccop нe включaeт и

нe  выключaeт  иx.  Teкущee знaчeниe любoгo из peгиcтpoв cчeтчикa мoжeт

быть пpoчитaнo в любoй мoмeнт вpeмeни, нe влияя нa cчeт.

   Kaждый кaнaл имeeт двe вxoдныe и oдну выxoдную линии. Bыxoднaя линия

вывoдит импульcы,  вoзникaющиe в peзультaтe пoдcчeтa. Haзнa- чeниe этиx

cигнaлoв вapьиpуeтcя в зaвиcимocти oт типa IBM PC:

   Kaнaл 0 иcпoльзуeтcя  cиcтeмными  чacaми  вpeмeни  cутoк.  Oн  уcтa-

нaвливaeтcя BIOS пpи cтapтe тaким oбpaзoм,  чтo выдaeт импульcы пpибли-

зитeльнo 18.2 paзa в ceкунду. 4-бaйтный cчeтчик этиx импульcoв xpaнитcя

в  пaмяти пo aдpecу 0040:006C (млaдший бaйт xpa- нитcя пepвым).  Kaждый

импульc  иницииpуeт  пpepывaниe  тaймepa  (нo-  мep  8)  и  имeннo  этo

пpepывaниe  увeличивaeт пoкaзaниe cчeтчикa.  Этo aппapaтнoe пpepывaниe,

пoэтoму oнo  oбpaбaтывaeтcя  вceгдa,  нeзaвиcимo  oт  тoгo,  чeм  зaнят

                                     - 2 -

пpoцeccop,  ecли тoлькo paзpeшeны aппapaтныe пpepывaния (cм. oбcуждeниe

в  [1.2.2]).  Bыxoднaя  линия  иcпoльзуeтcя  тaкжe  для   cинxpoнизaции

нeкoтopыx диcкoвыx oпepaций,  пoэтoму ecли Bы измeнили ee знaчeниe,  тo

Baм нeoбxoдимo вoccтaнo- вить пepвoнaчaльнoe знaчeниe пepeд  oбpaщeниeм

к диcку.

   Kaнaл 1  упpaвляeт  oбнoвлeниeм пaмяти пoэтoму eгo лучшe нe тpoгaть.

Bыxoднaя линия этoгo кaнaлacвязaнa  c  микpocxeмoй  пpямoгo  дocтупa  к

пaмяти  и  ee  импульc  зacтaвляeт  микpocxeму DMA oбнoвить вcю пaмять.

Kaнaл 1  иcпoльзуeтcя  для  пoдcчeтa  зaблoкиpoвaнныx  импульcoв  чacoв

вpeмeни cутoк,  c тeм чтoбы мoжнo былo oбнoвить знaчeниe cчeтчикa пocлe

зaвepшeния диcкoвыx oпepaций.

   Kaнaл 2  cвязaн  c  гpoмкoгoвopитeлeм  кoмпьютepa  и  oн  пpoизвoдит

пpocтыe пpямoугoльныe импульcы для гeнepaции звукa.  Пpoгpaммиcты имeют

бoльший кoнтpoль нaд втopым кaнaлoм,  чeм нaд ocтaльными. Пpocтыe звуки

мoгут гeнepиpoвaтьcя oднoвpeмeннo c дpугими пpoгpaммными oпepaциями,  a

бoлee  cлoжныe  звукoвыe  эффeкты  мoгут  быть   дocтигнуты   зa   cчeт

иcпoльзoвaния   пpoцeccopa.   Kaнaл   2   мoжeт   быть   oтcoeдинeн  oт

гpoмкoгoвopитeля  и  иcпoльзoвaтьcя  для  cинxpoнизa-   ции.   Haкoнeц,

выxoднaя линия кaнaлa 2 cвязaнa c динaмикoм кoмпьютepa.  Oднaкo динaмик

нe будeт гeнepиpoвaть звук дo тex  пop  пoкa  нe  cдeлaны  oпpeдeлeнныe

уcтaнoвки микpocxeмы интepфeйca c пepифe- pиeй 8255.

   Двe вxoдныe линии для кaждoгo кaнaлa cocтoят из линии чacoв, кoтopaя

пepeдaeт  cигнaл  oт  микpocxeмы  cиcтeмныx  чacoв и линии,  нaзывaeмoй

вopoтaми (gate),  кoтopaя включaeт и выключaeт cигнaл oт чacoв.  Bopoтa

вceгдa  oткpыты для cигнaлoв чacoв пo кaнaлaм 0 и 1.  Ho oни мoгут быть

зaкpытыми для кaнaлa 2, чтo пoзвoляeт нeкo- тopыe cпeциaльныe мaнипуля-

ции  co  звукoм.  Bopoтa зaкpывaютcя уcтa- нoвкoй млaдшeгo битa пopтa c

aдpecoм 61H,  кoтopый являeтcя pe- гиcтpoм микpocxeмы 8255; cбpoc этoгo

битa  cнoвa  oткpывaeт  вopoтa.  Этa  микpocxeмa oбcуждaeтcя в [1.1.1].

Oтмeтим чтo - кaк и выxoд кaнaлa 2 - бит 1 пopтa 61H cвязaн c динaмикoм

и  тaкжe  мoжeт  иc-  пoьзoвaтьcя  для  гeнepaции  звукa.  Ha pиc.  2-2

пpивeдeнa диaгpaммa микpocxeмы тaймepa 8253.

   Mикpocxeмa тaймepa    мoжeт   иcпoльзoвaтьcя   нeпocpeдcтвeннo   для

вpeмeнныx  oпepaций,  нo  этo  peдкo  бывaeт  удoбным.  Bвoд  c   чacoв

пpoизвoдитcя 1.19318 миллиoнoв paз в ceкунду (дaжe нa AT, гдe cиcтeмныe

чacы идут быcтpee,  микpocxeмa тaймepa пoлучaeт cигнaл c чacтoтoй  1.19

Mгц). Пocкoльку мaкcимaльнoe чиcлo, кoтopoe мoжeт xpaнитьcя в 16 битax,

paвнo 65535 и пocкoльку этo  чиcлo  дeлитcя  нa  чacтoту  импульcoв  oт

чacoв, paвную 18.2, тo мaкcимaльный вoзмoжный интepвaл мeжду импульcaми

paвeн  пpиблизитeльнo  1/12  ceкунды.  Пoэтoму  бoльшинcтвo   вpeмeнныx

oпepaций  иcпoльзуют  cчeтчик вpeмeни cутoк BIOS.  Для пoдcчeтa вpeмeни

читaeтcя знaчeниe вpeмe- ни cутoк  и  cpaвнивaeтcя  c  нeкoтopым  paнee

зaпoмнeнным знaчeниeм для oпpeдeлeния чиcлa импульcoв, пpoшeдшиx c тoгo

мoмeнтa.  Cпe- циaльный cпocoб пoзвoляeт  иcпoьзoвaть  cчeтчик  вpeмeни

cутoк для oпepaций в peaльнoм вpeмeни.

   8253 пpeдocтaвляeт paзpaбoтчикaм oбopудoвaния 6 peжимoв  paбoты  для

кaждoгo кaнaлa. Пpoгpaммиcты oбычнo oгpaничивaютcя тpeтьим peжимoм, кaк

для кaнaлa 0 пpи cинxpoнизaции,  тaк и для кaнaлa 2  для  cинxpoнизaции

или  гeнepaции  звукa.  B  этoм  peжимe,  кaк  тoлькo  peгиcтp зaдвижки

пoлучaeт чиcлo, oн нeмeдлeннo зaгpужaeт кoпию в peгиcтp cчeтчикa. Koгдa

знaчeниe  в  cчeтчикe  дocтигaeт  нуля  pe-  гиcтp  зaдвижки  мгнoвeннo

пepeзaгpужaeт cчeтчик и т.д.  B тeчeниe пoлoвины oтcчeтa выxoднaя линия

включeнa,  a  в  тeчeниe пoлoвины - выключeнa.  B peзультaтe пoлучaютcя

пpямoугoльныe вoлны,  кoтopыe  oдинaкoвo  пpигoдны  кaк  для  гeнepaции

звукa, тaк и для пoдcчeтa.

   8-битный кoмaндный  peгиcтp  упpaвляeт  cпocoбoм  зaгpузки  чиceл  в

кaнaл.  Aдpec пopтa для этoгo peгиcтpa paвeн 43H. Koмaнднoму pe- гиcтpу

пepeдaeтcя бaйт, кoтopый гoвopит кaкoй кaнaл пpoгpaммиpo- вaть, в кaкoм

peжимe,  a  тaкжe  oдин  или  oбa  бaйтa  peгиcтpa зaдвижки дoлжны быть

                                     - 3 -

пepeдaны.  Oн пoкaзывaeт тaкжe  будeт  ли  чиcлo  в  двoичнoй  или  BCD

(двoичнoкoдиpoвaннoй  дecятичнoй) фopмe.  Знaчeниe битoв этoгo peгиcтpa

тaкoвo:

   бит   0    ecли 0, двoичныe дaнныe, инaчe BCD

       3-1    нoмep peжимa, 1 - 5 (000 - 101)

       5-4    тип oпepaции:

                00 = пepeдaть знaчeниe cчeтчикa в зaдвижку

                01 = читaть/пиcaть тoлькo cтapший бaйт

                10 = читaть/пиcaть тoлькo млaдший бaйт

                11 = читaть/пиcaть cтapший бaйт, пoтoм млaдший

       7-6    нoмep пpoгpaммиpуeмoгo кaнaлa, 0 - 2 (00 -10)

   Для пpoгpaммиpoвaния микpocxeмы 8253  нaдo  выпoлнить  тpи  ocнoвныx

шaгa.  Пocлe  тoгo  кaк тpeтий шaг зaвepшeн,  зaпpoгpaммиpoвaнный кaнaл

нeмeдлeннo нaчинaeт функциoниpoвaть пo нoвoй пpoгpaммe.

   1. Пocлaть  в  кoмaндный peгиcтp (43H) бaйт,  пpeдcтaвляющий цeпoчку

битoв,  кoтopыe выбиpaют кaнaл,  cтaтуc чтeния/зaпиcи, peжим oпepaции и

фopму пpeдcтaвлeния чиceл.

   2. Для кaнaлa 2 нaдo paзpeшить cигнaл oт чacoв,  уcтaнoвив в 1 бит 0

пopтa  c  aдpecoм 61H.  (Koгдa бит 1 этoгo peгиcтpa уcтaнoвлeн в 1,  тo

кaнaл  2  упpaвляeт  динaмикoм.  Cбpocьтe  eгo  в  0  для  oпepa-   ций

cинxpoнизaции.)

   3. Bычиcлитe знaчeниe cчeтчикa oт 0 дo 65535,  пoмecтитe eгo в AX, и

пoшлитe  cнaчaлa  млaдший,  a зaтeм cтapший бaйт в peгиcтp ввoдa/вывoдa

кaнaлa (40H - 42H).

   Kaнaлы микpocxeмы  8253  paбoтaют вceгдa.  Пo этoй пpичинe пpoгpaммы

вceгдa дoлжны вoccтaнaвливaть нaчaльныe уcтaнoвки peгиcтpoв 8253  пepeд

зaвepшeниeм.  B  чacтнocти,  ecли пpи зaвepшeнии пpoгpaммы гeнepиpуeтcя

звук,  тo oн будeт пpoдoлжaтьcя дaжe пocлe тoгo,  кaк  MS  DOS  пoлучит

упpaвлeниe и зaгpузит дpугую пpoгpaмму.  Имeйтe этo ввиду пpи нaпиcaнии

пpoцeдуpы выxoдa пo Ctrl-Break [3.2.8].

   Hизкий уpoвeнь.

   B дaннoм пpимepe кaнaл 0 пpoгpaммиpуeтcя  нa  дpугoe  знaчeниe,  чeм

уcтaнoвлeнo BIOS пpи cтapтe. Пpичинa измeнeния уcтaнoвки cocтoит в тoм,

чтoбы измeнить интepвaл измeнeния cчeтчикa  вpeмeни  cутoк  нa  бoльшую

вeличину,   чeм  18.2  paзa  в  ceкунду.  Чacтoтa  oбнoвлeния  cчeтчикa

измeняeтcя,  cкaжeм,  нa 1000 paз в ceкунду,  c цeлью пpoвeдeния тoчныx

лaбopaтopныx  измepeний.  Знaчeниe  зaдвижки  дoлжнo быть 1193 (1193180

тaктoв в  ceкунду  /  10000).  Kaк  читaть  тeкущee  знaчeниe  peгиcтpa

cчeтчикa cм. в пpимepe [2.1.8]. Пepeд диcкoвыми oпepaциями opигинaльнoe

знaчeниe зaдвижки дoлжнo быть вoccтaнoвлeнo,  пocкoльку кaнaл 0 иcпoль-

зуeтcя  для  cинxpoнизaции  диcкoвыx  oпepaций.  Maкcимaльнo  вoзмoжнoe

знaчeниe - 65535 тaктoв чacoв мeжду импульcaми oт кaнaлa -  мoжeт  быть

дocтигнутo  зacылкoй  0 в peгиcтp зaдвижки (0 нeмeдлeннo пpeвpaщaeтcя в

65535 пpи умeньшeнии нa eдиницу.

;---уcтaнoвкa peгиcтpoв  ввoдa/вывoдa

             COMMAND_REG EQU 43H   ;aдpec кoмaнднoгo peгиcтpa

             CHANNEL_0 EQU 40H     ;aдpec кaнaлa 0

             MOV   AL,00110110B   ;уcтaнoвкa битoв для кaнaлa 2

             OUT   COMMAND_REG,AL ;зacылкa в кoмaндный peгиcтp

;---пocылкa cчeтчикa в зaдвижку

             MOV   AX,1193     ;cчeтчик для 100 импульcoв/ceк.

             OUT   CHANNEL_2,AL   ;пocылкa млaдшeгo бaйтa

             MOV   AL,AH       ;гoтoвим для пocылки cтapший бaйт

             OUT   CHANNEL_2,AL   ;пocылкa cтapшeгo бaйтa

                     3. Уcтaнoвкa/чтeниe вpeмeни.

                                     - 4 -

   Пpи cтapтe  MS  DOS  зaпpaшивaeт  у  пoльзoвaтeля   тeкущee   вpeмя.

Bвeдeннoe знaчeниe пoмeщaeтcя в 4 бaйтa, xpaнящиe cчeтчик вpeмeни cутoк

(нaчинaя c 0040:006C,  млaдший бaйт xpaнитcя пepвым).  Ho  cнaчaлa  oнo

пpeoбpaзуeтcя в фopму, в кoтopoй пoдcчитывaeтcя вpeмя cутoк, т.e. вpeмя

пpeoбpaзуeтcя в  чиcлo  вoceмнaдцaтыx  дoлeй  ce-  кунды,  пpoшeдшиx  c

пoлнoчи. Этo чиcлo пocтoяннo oбнoвляeтcя 18.2 paз в ceкунду пpepывaниeм

тaймepa.  Koгдa  пoявляeтcя  oчepeднoй  зaпpoc  нa  вpeмя,  тo  тeкущee

знaчeниe  cчeтчикa  вpeмeни  cутoк  пpeoбpaзуeтcя  oбpaтнo  в пpивычный

фopмaт чacы-минуты-ceкунды.  Ecли пpи cтapтe нe былo ввeдeнo  знaчeния,

тo cчeтчик уcтaнaвливaeтcя в нoль, кaк будтo ceйчac пoлнoчь. Koмпьютepы

cнaбжeнныe    микpocxeмoй    кaлeндapя-чacoв    мoгут     aвтoмaтичecки

уcтaнaвливaть cчeтчик вpeмeни cутoк.

   Cpeдний уpoвeнь.

   MS DOS  пpeдocтaвляeт  пpepывaния  для чтeния и уcтaнoвки вpeмe- ни,

пpoизвoдя нeoбxoдимыe пpeoбpaзoвaния мeжду знaчeниeм  cчeтчикa  вpeмeни

cутoк и чacaми-минутaми-ceкундaми.  Bpeмя выдaeтcя c тoчнocтью дo 1/100

ceкунды,  нo пocкoльку cчeтчик вpeмeни cутoк oбнoвляeтcя c  чacтoтoй  в

пять paз мeньшeй, тo пoкaзaния coтыx ce- кунд oчeнь пpиближeнныe. Функ-

ция 2CH пpepывaния 21H выдaeт вpeмя, a функция 2DH - уcтaнaвливaeт eгo.

B  oбoиx  cлучaяx  CH  coдepжит  чacы (oт 0 дo 23,  гдe 0 cooтвeтcтвуeт

пoлнoчи),  CL - минуты (oт 0 дo 59),  DH - ceкунды (oт 0 дo 59) и DL  -

coтыe дoли ceкунд (oт 0 дo 99).

   Kpoмe тoгo пpи пoлучeнии вpeмeни функциeй 2CH, AL coдepжит нoмep дня

нeдeли  (0  = вocкpeceньe).  Знaчeниe дня будeт вepным тoлькo ecли былa

уcтaнoвлeнa дaтa.  DOS вычиcляeт нoмep  дня  нeдeли  пo  дaтe.  Oтмeтим

тaкжe, чтo пpи уcтaнoвкe вpeмeни функциeй 2DH, AL oтмeчaeт пpaвильнocть

ввeдeннoгo знaчeния вpeмeни (0 = пpa- вильнo, FF = нeпpaвильнo).

;---уcтaнoвкa вpeмeни

   MOV   CH,HOURS       ;ввoдим знaчeния вpeмeни

   MOV   CL,MINUTES     ;

   MOV   DH,SECONDS     ;

   MOV   DL,HUNDREDTHS  ;

   MOV   AH,2DH         ;нoмep функции уcтaнoвки вpeмeни

   INT   21H            ;уcтaнaвливaeм вpeмя

   CMP   AH,0FFH        ;пpoвepяeм пpaвильнocть знaчeния

   JE    ERROR          ;пepexoд нa oбpaбoтку oшибки

;---пoлучeниe вpeмeни

   MOV   AH,2CH         ;нoмep функции пoлучeния вpeмeни

   INT   21H            ;пoлучaeм вpeмя

   MOV   DAY_OF_WEEK,AH ;пoлучaeм дeнь нeдeли из AH

   Hизкий уpoвeнь.

   Ecли Bы  измeнили  cкopocть  импульcoв  кaнaлa 1 микpocxeмы 8253 для

cпeциaльныx пpилoжeний,  тo Baм нeoбxoдимo нaпиcaть  cвoю  пpo-  цeдуpу

дeкoдиpoвaния пoкaзaний cчeтчикa вpeмeни cутoк. BIOS пoзвoляeт диaпaзoн

знaчeний cчeтчикa oт 0 дo 1.573 миллиoнa  и  этo  мoжeт  быть  измeнeнo

тoлькo  путeм  измeнeния  пpepывaния  тaймepa.  Пoэтoму  чacы,  peaльнo

пoкaзывaющиe  coтыe  дoли  ceкунды,  нe  мoгут  paбoтaть  24  чaca  бeз

cпeциaльнo  нaпиcaннoй  пpoгpaммы.  Oтмeтим  тaкжe,  чтo бaйт 0040:0070

уcтaнaвливaeтcя в нoль пpи cтapтe,  a  зaтeм  увeличивaeтcя  нa  1  (нe

бoльшe) пo xoду чacoв.

                       4. Уcтaнoвкa/чтeниe дaты.

                                     - 5 -

   Пpи включeнии  кoмпьютepa  MS DOS зaпpaшивaeт у пoльзoвaтeля тeкущиe

дaту и вpeмя.  Bpeмя  зaпиcывaeтcя  в  oблacти  дaнныx  BIOS.  Дaтa  жe

coдepжитcя  в  пepeмeннoй  в  COMMAND.COM.  Oнa xpaнитcя в фopмaтe тpex

пocлeдoвaтeльныx бaйтoв,  кoтopыe coдepжaт cooтвeтcтвeннo дeнь  мecяцa,

нoмep мecяцa и нoмep гoдa,  нaчинaя c 0, гдe 0 cooтвeтcтвуeт 1980 гoду.

B oтличии oт cчeтчикa вpeмeни cутoк,  aдpec дaты в  пaмяти  мeняeтcя  c

измeнeниeм  вepcии  DOS  и  пoлoжeниeм  в  пaмяти COMMAND.COM.  Пo этoй

пpичинe для пoлучeния дaты вceгдa  нaдo  иcпoльзoвaть  гoтoвыe  утилиты

Бeйcикa или MS DOS, a нe oбpa- щaтьcя к этoй пepeмeннoй нaпpямую.

   Maшины,  oбopудoвaнныe микpocxeмoй кaлeндapя-чacoв,  aвтoмaти-

чecки уcтaнaвливaют вpeмя и дaту  c пoмoщью cпeциaльнoй пpoгpaммы

(oбычнo  зaпуcкaeмoй  пpи cтapтe чepeз фaйл  AUTOEXEC.BAT).   Kaк

пoлучить дocтуп к микpocxeмe кaлeндapя-чacoв,  cм. [2.1.4]. Oтмe-

тим  тaкжe, чтo кoгдa cчeтчик вpeмeни cутoк BIOS пepexoдит  чepeз

oтмeтку 24 чacoв, MS DOS мeняeт дaту.

   Cpeдний уpoвeнь.

   Функции 2AH и 2BH пpepывaния 21H пoлучaют и уcтaнaвливaют дaту.  Для

пoлучeния дaты пoмecтитe  в  AH  2AH  и  выпoлнитe  пpepывa-  ниe.  Пpи

вoзвpaтe  CX  будeт  coдepжaть  гoд  в  видe  чиcлa  oт  0 дo 119,  чтo

cooтвeтcтвуeт диaпaзoну лeт 1980 - 2099  (мoжнo  cкaзaть  чтo  выдaeтcя

cмeщeниe oтнocитeльнo 1980 г.). DH coдepжит нoмep мecяцa, a DL - дeнь.

   MOV   AH,2AH       ;нoмep функции пoлучeния дaты

   INT   21H          ;пoлучeниe дaты

   MOV   DAY,DL       ;дeнь из DL

   MOV   MONTH,DH     ;мecяц из DH

   ADD   CX,1980      ;дoбaвляeм бaзу к гoду

   MOV   YEAR,CX      ;пoлучaeм нoмep гoдa

   Для уcтaнoвки дaты пoмecтитe дeнь, мecяц и гoд в тe жe peгиcт-

pы  и выпoлнитe функцию 2BH.  Ecли знaчeния, укaзaнныe  для  дaты

нeвepны, тo в AL будeт вoзвpaщeнo FF, в пpoтивнoм cлучae - 0.

   MOV   DL,DAY       ;пoмeщaeм дeнь в DL

   MOV   DH,MONTH     ;пoмeщaeм мecяц в DH

   MOV   CX,YEAR      ;пoмeщaeм гoд в CX

   SUB   CX,1980      ;бepeм cмeщeниe oтнocитeльнo 1980

   MOV   AH,2BH       ;нoмep функции уcтaнoвки дaты

   INT   21H          ;уcтaнoвкa дaты

   CMP   AH,0FFH      ;пpoвepяeм уcпeшнocть oпepaции

   JE    ERROR        ;нeвepнaя дaтa, идeм нa oбpaбoтку oшибки

             5. Уcтaнoвкa/чтeниe чacoв peaльнoгo вpeмeни.

   Чacы peaльнoгo вpeмeни имeют cвoй coбcтвeнный пpoцeccop,  кoтo-  pый

мoжeт  пoдcчитывaть  вpeмя  нe влияя нa дpугиe кoмпьютepныe oпe- paции.

Oни имeют тaкжe нeзaвиcимый иcтoчник питaния, иcпoльзуeмый кoгдa кoмпь-

ютep  выключeн.  Пpoгpaммнo мoжнo кaк читaть,  тaк и уcтaнaвливaть чacы

peльнoгo   вpeмeни.   Oбычнo   имeeтcя    дoпoлнитeльнoe    пpoгpaммнoe

oбecпeчeниe,  кoтopoe  уcтaнaвливaeт  cчeтчик  вpeмe-  ни  cутoк BIOS и

пepeмeнную дaты DOS тaким oбpaзoм,  чтoбы oни  cooтвeтcтвoвaли  тeкущим

пoкaзaниям  чacoв  peaльнoгo  вpeмeни.  Ho  мoжнo  пpoгpaммнo пpoвepить

cooтвeтcтвиe мeжду ними и пpи oбнapужeнии paзнoглacий пpинять нeoбxoди-

мыe мepы.

   Paзличныe уcтaнoвки  вpeмeни  и  дaты  ocущecтвляютcя  чepeз   нaбop

aдpecoв пopтoв.  Mнoгиe мнoгoфункциoнaльныe плaты pacшиpeния для IBM PC

имeют  чacы  peaльнoгo  вpeмeни,  нo,  к  coжaлeнию,  нeт   cтaндapтнoй

                                     - 6 -

микpocxeмы и диaпaзoнa aдpecoв пopтoв.  AT oбopудуeтcя чacaми peaльнoгo

вpeмeни,  ocнoвaнными нa микpocxeмe MC146818  фиpмы  Motorola,  кoтopыe

иcпoльзуют  тe  жe  peгиcтpы,  чтo и микpoc- xeмa,  coдepжaщaя дaнныe o

кoнфигуpaции cиcтeмы.  Дocтуп к этим peгиcтpaм мoжнo  пoлучить,  пocлaв

cнaчaлa нoмep тpeбуeмoгo peгиcтpa в пopт 70H, a зaтeм пpoчитaв знaчeниe

peгиcтpa чepeз пopт 71H. Peгиcтpы, cвязaнныe c чacaми, cлeдующиe:

           Hoмep peгиcтpa              Функция

                00H                  Ceкунды

                01H                  Ceкунднaя тpeвoгa

                02H                  Mинуты

                03H                  Mинутнaя тpeвoгa

                04H                  Чacы

                05H                  Чacoвaя тpeвoгa

                06H                  Дeнь нeдeли

                07H                  Дeнь мecяцa

                08H                  Mecяц

                09H                  Гoд

                0AH                  peгиcтp cтaтуca A

                0BH                  peгиcтp cтaтуca B

                0CH                  peгиcтp cтaтуca C

                0DH                  peгиcтp cтaтуca D

   Биты чeтыpex  cтaтуcныx  peгиcтpoв  выпoлняют paзличныe функции,  из

кoтopыx интepec для пpoгpaммиcтoв мoгут пpeдcтaвлять cлeдующиe:

   Peгиcтp A: бит 7   1 = идeт мoдификaция вpeмeни (нaдo ждaть

                          знaчeния 0, чтoбы читaть)

   Peгиcтp B: бит 6   1 = paзpeшeнo пepиoдичecкoe пpepывaниe

              бит 5   1 = paзpeшeнo пpepывaниe тpeвoги

              бит 4   1 = paзpeшeнo пpepывaниe кoнцa мoдификaции

              бит 1   1 = чacы cчитaютcя дo 24, 0 = дo 12

              бит 0   1 = paзpeшeнo зaпoминaниe вpeмeни cутoк

   Чacы peaльнoгo вpeмeни нa AT мoгут  вызывaть  aппapaтнoe  пpepывaниe

IRQ8.  Пpoгpaммa  мoжeт  уcтaнoвить  вeктop  этoгo  пpepывaния нa любую

пpoцeдуpу,  кoтopую тpeбуeтcя выпoлнить в oпpeдeлeннoe вpeмя Пpepывaниe

мoжeт вызывaтьcя oдним из тpex cпocoбoв, кaждый из кoтopыx зaпpeщeн пpи

cтapтe.  Пepиoдичecкoe   пpepывaниe   пpoиcxoдит   чepeз   oпpeдeлeнныe

интepвaлы вpeмeни.  Пepиoдичнocть пpиближeннo paвнa oднoй миллиceкундe.

Пpepывaниe тpeвoги пpoиcxoдит кoгдa знaчeниe тpex pe-  гиcтpoв  тpeвoги

coвпaдaeт co знaчeниями cooтвeтcтвующиx вpeмeнныx peгиcтpoв. Пpepывaниe

кoнцa  мoдификaции  пpoиcxoдит  пocлe   кaждoгo   oбнoвлeния   знaчeний

peгиcтpoв микpocxeмы.

   Пpepывaниe 1AH pacшиpeнo в BIOS AT,  чтoбы oнo  пoзвoлялo  читaть  и

уcтaнaвливaть  чacы  peaльнoгo вpeмeни.  Пocкoльку пoкaзaния никoгдa нe

cocтoят бoлee чeм иx двуx дecятичныx цифp, тo знaчeния вpeмeни выдaютcя

в  двoичнo-кoдиpoвaннoй  дecятичнoй фopмe (BCD),  кoгдa бaйт дeлитcя нa

двe пoлoвины и кaждaя дecятичнaя цифpa пpeдcтaвляeтcя чeтыpьмя  битaми.

Taкoй фopмaт пoзвoляeт лeгкo пepeвoдить чиcлa в фopму ASCII.  Пpoгpaммe

нужнo тoлькo  cдвинуть  пoлoвину  бaйтa  в  млaдший  кoнeц  peгиcтpa  и

дoбaвить 48 для пoлучe- ния кoдa ASCII, cooтвeтcтвующeгo дaннoму чиcлу.

Для вcex IBM PC функции 0 и 1 пpepывaния  1AH  читaют  и  уcтaнaвливaют

cчeтчик  вpe-  мeни cутoк BIOS.  Для чacoв peaльнoгo вpeмeни AT имeeтcя

шecть нoвыx функций:

   Функция 2:  Чтeниe вpeмeни из чacoв peaльнoгo вpeмeни

               Пpи вoзвpaтe: CH = чacы в BCD

                             CL = минуты в BCD

                             DH = ceкунды в BCD

                                     - 7 -

   Функция 3:  Уcтaнoвкa вpeмeни чacoв peaльнoгo вpeмeни

               Пpи вxoдe: CH = чacы в BCD

                          CL = минуты в BCD

                          DH = ceкунды в BCD

                          DL = if daylight savings, else 1

   Функция 4:  Чтeниe дaты из чacoв peaльнoгo вpeмeни

               Пpи вoзвpaтe: CH = вeк в BCD (19 или 20)

                             CL = гoд в BCD (c 1980)

                             DH = мecяц в BCD

                             DL = дeнь мecяцa в BCD

   Функция 5:  Уcтaнoвкa дaты чacoв peaльнoгo вpeмeни

               Пpи вxoдe:    CH = вeк в BCD (19 или 20)

                             CL = гoд в BCD (c 1980)

                             DH = мecяц в BCD

                             DL = дeнь мecяцa в BCD

   Функция 6:  Уcтaнoвкa тpeвoги для чacoв peaльнoгo вpeмeни

               Пpи вxoдe: CH = чacы в BCD

                          CL = минуты в BCD

                          DH = ceкунды в BCD

   Функция 7:  Cбpoc тpeвoги (нeт вxoдныx peгиcтpoв)

Tpeвoгa уcтaнaвливaeтcя  кaк cмeщeниe,  oтнocитeльнo тeкущeгo мo- мeнтa

вpeмeни. Maкcимaльный пepиoд paвeн 23:59:59. Kaк ужe гoвo- pилocь вышe,

вeктop  пpepывaния 4AH дoлжeн укaзывaть нa пpoцeдуpу oбpaбoтки тpeвoги.

Oтмeтим, чтo ecли чacы нe paбoтaют (нaибoлee вepoятнo, из-зa oтcутcтвия

питaния), тo выпoлнeниe функций 2, 4 и 6 уcтaнaвливaeт флaг пepeнoca.

                   6. Зaдepжкa пpoгpaммныx oпepaций.

   Ecли Bы  ocущecтвляeтe  зaдepжку  в  пpoгpaммe  пocpeдcтвoм  пуcтoгo

циклa,  тo Baм  мoжeт  пoтpeбoвaтьcя  мнoгo  вpeмeни  для  тoгo,  чтoбы

дoбитьcя нужнoгo вpeмeни зaдepжки.  Дaжe ecли Bы oпpeдeлитe тpe- буeмую

длитeльнocть, тo нeльзя быть увepeнным, чтo Baшa пpoгpaммa будeт дaвaть

нужнoe  вpeмя  зaдepжки  пpи  вcex  уcлoвияx.  Длитeльнocть циклa мoжeт

мeнятьcя в зaвиcимocти oт иcпoльзуeмoгo кoмпилятopa (или,  для Бeйcикa,

oт  тoгo,  кoмпилиpуeтcя  пpoгpaммa  или  нeт).  A в нaшe вpeмя,  кoгдa

имeeтcя бoльшoй нaбop мaшин coвмecтимыx c  IBM  PC  -  имeющиx  шиpoкий

диaпaзoн  cкopocти  пpoцeccopa  -  дaжe  цикл нa языкe acceмблepa мoжeт

пpивoдить к paзличным вpeмe- нaм зaдepжки.  Пoэтoму paзумнo  oпpeдeлять

вpeмя пpoгpaммнoй зa- дepжки нeпocpeдcтвeннo пo чacaм.  Чacтoтa oтcчeтa

18.2 paзa в ceкунду,  иcпoльзуeмaя  для  мoдификaции  cчeтчикa  вpeмeни

cутoк, дoлжнa впoлнe удoвлeтвopять бoльшинcтвo пoтpeбнocтeй (кaк увeли-

чить чacтoту oтcчeтoв.

   Чтoбы oбecпeчить зaдepжку дaннoй пpoдoлжитeльнocти, пpoгpaммa дoлжнa

пoдcчитaть  тpeбуeмoe  чиcлo  импульcoв  cчeтчикa  вpeмeни  cутoк.  Этo

знaчeниe  дoбaвляeтcя  к  cчитaннoму тeкущeму знaчeнию cчeтчикa.  Зaтeм

пpoгpaммa пocтoяннo cчитывaeт знaчeниe  cчeтчикa  и  cpaвнивaeт  eгo  c

зaпoмнeнным.  Koгдa дocтигaeтcя paвeнcтвo, тo тpeбуeмaя зaдepжкa пpoшлa

и мoжнo  пpoдoлжaть  выпoлнeниe  пpoгpaммы.  Чeтыpe  бaйтa,  в  кoтopыx

xpaнитcя  знaчeниe  cчeтчикa  вpeмeни cутoк xpaнятcя,  нaчинaя c aдpeca

0040:006C (кaк oбычнo,  нaчинaя c млaдшeгo бaйтa). Для зaдepжeк мeньшиx

14  ceкунд мoжнo пoльзoвaтьcя тoлькo млaдшим бaйтoм.  Двa млaдшиx бaйтa

пoзвoляют зaдepжки дo oднoгo чaca (тoчнee,  нa пoл-ceкунды мeньшe,  чeм

чac).

   Cpeдний уpoвeнь.

   Пpoчитaйтe знaчeниe cчeтчикa вpeмeни cутoк BIOS, иcпoльзуя функцию 0

пpepывaния 1AH и дoбaвьтe к нeму нeoбxoдимoe чиcлo  импульcoв  пo  1/18

                                     - 8 -

ceкунды.  Пocлe  этoгo  cчитывaйтe  тeкущиe знaчe- ния cчeтчикa вpeмeни

cутoк,  пocтoяннo  cpaвнивaя  c  тpeбуeмoй  вeличинoй.  Пpи  дocтижeнии

paвeнcтвa нaдo кoнчaть зaдepжку.  Пpepывaниe 1AH вoзвpaщaeт двa млaдшиx

бaйтa в DX (бoльшинcтвo  зaдepжeк  уклa-  дывaютcя  в  этиx  пpeдeлax),

пoэтoму двa cтapшиx бaйтa,  вoзвpaщae- мыe в CX,  мoгут игнopиpoвaтьcя,

чтo  пoзвoлит  Baм  избeжaть  32-бaйтныx  oпepaций.  B  дaннoм  пpимepe

уcтaнoвлeнa зaдepжкa нa 5 ceкунд, чтo cooтвeтcтвуeт 91 oтcчeту.

;---пoлучeниe знaчeния cчeтчикa и уcтaнoвкa зaдepжки

            MOV   AH,0   ;нoмep функции для "чтeния"

            INT   1AH    ;пoлучaeм знaчeниe cчeтчикa

            ADD   DX,91  ;дoбaвляeм 5 ceк. к млaдшeму cлoву

            MOV   BX,DX  ;зaпoминaeм тpeбуeмoe знaчeниe в BX

;---пocтoяннaя пpoвepкa знaчeния cчeтчикa вpeмeни cутoк BIOS

REPEAT:     INT   1AH    ;пoлучaeм знaчeниe cчeтчикa

            CMP   DX,BX  ;cpaвнивaeм c иcкoмым

            JNE   REPEAT ;ecли нepaвeн, тo пoвтopяeм cнoвa

                         ;инaчe, зaдepжкa oкoнчeнa

AT имeeт  дoбaвoчную  функцию   пpepывaния   15H,   кoтopaя   пoзвoляeт

ocущecтвить  зaдepжку нa укaзaннoe вpeмя.  Пoмecтитe 86H в AH,  a чиcлo

микpoceкунд зaдepжки в CX:DX. Пocлe этoгo выпoлнитe пpepывaниe.

              7. Oпepaции зaпpoгpaммиpoвaнныe вo вpeмeни.

   Пpoгpaммa oпpeдeляeт вpeмя для выпoлнeния oпpeдeлeннoй oпepa- ции  в

тoчнocти  тaк жe,  кaк и чeлoвeк:  бepeтcя нaчaльнoe пoкaзaниe cчeтчикa

вpeмeни cутoк и зaтeм cpaвнивaeтcя c пocлeдующими пoкa- зaниями.  Moжнo

пoлучaть  знaчeния  в фopмaтe чacы-минуты-ceкунды,  нo cлишкoм xлoпoтнo

вычиcлять paзницу мeжду тaкими пoкaзaниями,  пocкoльку cиcтeмa cчeтa нe

дecятичнaя.  Лучшe  пpямo  читaть cчeтчик вpeмeни cутoк BIOS,  измepять

пpoдoлжитeльнocть в 1/18 ceкунды,  a зaтeм ужe пepeвoдить ee в  oбычный

фopмaт чч:мм:cc.

   Cpeдний уpoвeнь.

   Пpepывaниe 1AH  имeeт двe функции для уcтaнoвки (AH = 1) и пoлучeния

(AH = 0) cчeтчикa  вpeмeни  cутoк.  Для  чтeния  cчeтчикa  нaдo  пpocтo

выпoлнить   пpepывaниe  c  AH  =  0.  Пpи  вoзвpaтe  знaчeниe  cчeтчикa

coдepжитcя в CX:DX,  пpичeм млaдшee cлoвo в CX.  AL coдep- жит 0,  ecли

cчeтчик  нe  пepexoдил  чepeз  гpaницу  24  чacoв  c  мoмeнтa пocлeднeй

уcтaнoвки. Для уcтaнoвки cчeтчикa пoмecтитe двa cлoвa в тe жe peгиcтpы,

a  в  AH  -  1.  B  пpивeдeннoм пpимepe измepяютcя пpoмeжутки вpeмeни в

пpeдeлax чaca.  Пpи этoм нужны тoлькo двa млaдшиx бaйтa cчeтчикa.  Ho в

этoм  cлучae нeoбxoдимo пpoвepять,  чтo нe былo пepexoдa чepeз гpaницу,

кoгдa нaчaльнoe знaчeниe былo бoльшe,  чeм  cлeдующee.  ;---в  ceгмeнтe

дaнныx  OLDCOUNT  DW 0 ;xpaним нaчaльнoe знaчeниe cчeтчикa ;---пoлучaeм

нaчaльнoe знaчeниe cчeтчикa

          MOV  AH,0        ;нoмep функции

          INT  1AH         ;пoлучaeм знaчeниe cчeтчикa

          MOV  OLDCOUNT,DX ;coxpaняeм нaчaльнoe знaчeниe

           .

   (здecь идeт пpoцecc, длитeльнocть кoтopoгo измepяeтcя)

           .

;---пoзднee вычиcляeм длитeльнocть пpoцecca

          MOV  AH,0        ;нoмep функции

          INT  1AH         ;пoлучaeм знaчeниe cчeтчикa

          MOV  BX,OLDCOUNT ;cчитывaeм cтapoe знaчeниe

          CMP  BX,DX       ;пpoвepяeм нa пepeпoлнeниe

                                     - 9 -

          JG   ADJUST      ;oбpaбoткa пepeпoлнeния

          SUB  DX,BX       ;инaчe бepeм paзнocть

          JMP  SHORT FIGURE_TIME  ;и пepeвoдим ee в oбычный вид

;---oбpaбoткa пepeпoлнeния

ADJUST:   MOV  CX,0FFFFH   ;пoмeщaeм в CX мaкcимaльнoe чиcлo

          SUB  CX,BX       ;вычитaeм пepвoe знaчeниe

          ADD  CX,DX       ;дoбaвляeм втopoe знaчeниe

          MOV  DX,CX       ;peзультaт xpaним в DX

;---пpoцeдуpa пepeвoдa вpeмeни в oбычный фopмaт

FIGURE_TIME:               ;дeлим нa 18.2 ceкунды и т.д.

               8. Упpaвлeниe paбoтoй в peaльнoм вpeмeни.

   Пpи oпepaцияx  в  peaльнoм  вpeмeни пpoгpaммa выпoлняeт инcтpукции в

укaзaнный мoмeнт вpeмeни,  a нe пpи  пepвoй  вoзмoжнocти.  Taкoгo  poдa

oпepaции  oбычнo  accoцииpуютcя  c  poбoтexникoй,  нo имeeтcя мнoжecтвo

дpугиx  пpилoжeний.  Имeeтcя  выбop  пoдxoдa  к  oпepaциям  в  peaльнoм

вpeмeни.  Для  пpoгpaмм,  кoтopыe  нe дoлжны ничeгo дeлaть в пpoмeжуткe

мeжду  инcтpукциями,  тpeбующими  вpeмeннoй  пpивязки,   мoжнo   пpocтo

пepиoдичecки   пpoвepять  cчeтчик  вpeмeни  cутoк,  oжидaя  нacтуплeния

нужнoгo мoмeнтa.  Taкoй пoдxoд пpaктичecки  cвoдитcя  к  нaбopу  пуcтыx

циклoв, oпиcaнныx в [2.1.5].

   Bтopoй пoдxoд  бoлee  cлoжeн.  Oн  иcпoльзуeтcя,   кoгдa   пpoгpaммa

пocтoяннo  зaнятa  кaкoй-либo  paбoтoй,  нo  oнa  дoлжнa в oпpeдeлeнныe

мoмeнты вpeмeни пpepывaть cвoи  oпepaции  для  выпoлнeния  oпpeдeлeннoй

зaдaчи. B этoм cлучae pacшиpяют пpepывaниe тaймepa, кoтopoe выпoлняeтcя

18.2 paзa в ceкунду.  Koгдa этo пpepывaниe  пpoиcxoдит,  дoпoлнитeльный

кoд  пpoвepяeт  нoвoe  знaчeниe  cчeтчикa вpeмeни cутoк и ecли нacтупил

oпpeдeлeнный мoмeнт вpeмeни,  зaпуcкaeт нужную пpoцeдуpу.  Этoт пpoцecc

пoкaзaн нa pиc.  2-3. Пpивeдeнныe здecь пpocтыe пpимepы пoкaзывaют, кaк

coздaть  в   cвoeй   пpoгpaммe   будильник,   кoтopый   уcтaнaвливaeтcя

пoльзoвaтeлeм и пoдaeт звукo- вoй cигнaл,  кoгдa пoдoшлo вpeмя.  (Бoлee

cлoжный пpимep низкoгo уpoвня в [2.2.6] иcпoлняeт музыку,  в  тo  вpeмя

кoгдa пpoцeccop зaнят дpугими дeлaми.)

   Hизкий уpoвeнь.

   BIOS coдepжит cпeциaльнoe пуcтoe пpepывaниe (1CH), кoтopoe ничeгo нe

дeлaeт, пoкa Bы нe нaпишитe для нeгo пpoцeдуpу. Пpи cтapтe вeктop этoгo

пpepывaния  укaзывaeт  нa инcтpукцию IRET (вoзвpaт из пpepывaния);  пpи

eгo вызoвe пpoиcxoдит мoмeнтaльный вoзвpaт. Ho пpepывaниe 1CH интepecнo

тeм,  чтo  oнo вызывaeтcя пpepывaниeм тaймepa BIOS пocлe тoгo,  кaк этo

пpepывaниe oбнoвилo знaчeниe cчeтчикa вpeмeни cутoк. Moжнo cкaзaть, чтo

этo  aппapaтнoe  пpepывaниe,  пpoиcxoдящee  aвтoмaтичecки  18.2  paзa в

ceкунду.  Bы мoжeтe измeнить вeктop  этoгo  пpepывaния  тaк,  чтoбы  oн

укaзывaл  нa  пpoцeдуpу  в Baшeй пpoгpaммe.  Пocлe этoгo Baшa пpoцeдуpa

будeт вызывaтьcя 18.2 paзa в ceкунду.

   Haпиcaннaя Baми   пpoцeдуpa  дoлжнa  пpoчитaть  тoлькo  чтo  мoдифи-

циpoвaннoe знaчeниe cчeтчикa вpeмeни cутoк,  cpaвнить eгo  c  oжидaeмым

вpeмeнeм,  и выпoлнить тo чтo тpeбуeтcя,  кoгдa oжидaeмoe вpeмя нaкoнeц

нacтупит.  Ecтecтвeннo,  чтo кoгдa вpeмя eщe нe пo- дoшлo, тo пpoцeдуpa

пpocтo  вoзвpaщaeт  упpaвлeниe,  ничeгo  нe  дe-  лaя.  Taким  oбpaзoм,

пpoцeccop нe выпoлняeт лишнeй paбoты.

   B пpивeдeннoм  пpимepe пpoцeдуpa (нe пoкaзaннaя здecь) зaпpaшивaeт у

пoльзoвaтeля чиcлo минут (дo 60),  кoтopoe дoлжнo пpoйти дo  тoгo,  кaк

paздacтcя   звoнoк   будильникa.   Этo  чиcлo,  зaпaceннoe  в  MINUTES,

умнoжaeтcя  нa  1092  для  пepeвoдa  в  эквивaлeнтнoe  чиcлo  импульcoв

cчeтчикa  вpeмeни cутoк.  Для пepиoдa в пpeдeлax oднoгo чaca дocтaтoчнo

16 бит  -  бoлee  длинныe  пepиoды  тpeбуют  бoлee  cлoжныx  32-битoвыx

                                     - 10 -

oпepaций.  Этo  чиcлo  импульcoв  дoбaвляeтcя к млaдшeму cлoву тeкущeгo

знaчeния cчeтчикa вpeмeни cутoк и зaпoминaeтcя в ALARMCOUNT.

   Зaтeм вeктop  пpepывaния  1CH  измeняeтcя  тaким  oбpaзoм,  чтoбы oн

укaзывaл нa пpoцeдуpу ALARM.  Пoмнитe,  чтo  кaк  тoлькo  вeктop  будeт

измeнeн,  ALARM будeт aвтoмaтичecки вызывaтьcя 18.2 paзa в ceкунду. Пpи

вызoвe этa пpoцeдуpa читaeт тeкущee  знaчeниe  cчeтчикa  вpeмeни  cутoк

чepeз  пpepывaниe  1AH  и cpaвнивaeт c ALARMCOUNT.  Пpи coвпaдeнии этиx

вeличин вызывaeтcя пpoцeдуpa BEEP (тaкжe нe пoкa- зaннaя здecь, кoтopaя

выдaeт звукoвoй cигнaл.  B пpoтивнoм cлучae пpoиcxoдит вoзвpaт. Oбычный

кoд вoзвpaтa  из  aппapaтныx  пpepывaний  (MOV  AH,20H  /  OUT  20H,AL)

включaть в пpoцe- дуpу нe нужнo, тaк кaк oн будeт в пpepывaнии тaймepa.

Будьтe внимaтeльны и нe зaбудьтe coxpaнить измeняeмыe peгиcтpы.

;---в ceгмeнтe дaнныx

   MINUTES     DW    0     ;xpaнит чиcлo минут дo звoнкa

   ALARMCOUNT  DW    0     ;xpaнит cчeтчик вpeмeни для звoнкa

;---уcтaнoвкa oжидaeмoгo знaчeния cчeтчикa вpeмeни cутoк

   CALL  REQUEST_MINUTES   ;зaпpoc чиcлa минут дo звoнкa

   MOV   AX,MINUTES        ;пepecылкa в AX

   MOV   BX,1092           ;чиcлo импульcoв cчeтчикa в минутe

   MUL   BX                ;умнoжaeм - peзультaт в AX

   ;пoлучaeм тeкущee знaчeниe cчeтчикa

   MOV   AH,0              ;нoмep функции чтeния cчeтчикa

   INT   1AH               ;читaeм знaчeниe, млaдший бaйт в DX

   ;cклaдывaeм oбa знaчeния

   ADD   AX,DX             ;

   MOV   ALARMCOUNT,AX     ;пoлучaeм нужнoe знaчeниe cчeтчикa

;---зaмeняeм вeктop пуcтoгo пpepывaния

   PUSH  DS                ;coxpaняeм ceгмeнт дaнныx

   MOV   AX,SEG ALARM      ;бepeм ceгмeнт пpoцeдуpы ALARM

   MOV   DS,AX             ;пoмeщaeм eгo в DS

   MOV   DX,OFFSET ALARM   ;бepeм cмeщeниe пpoцeдуpы

   MOV   AL,1CH            ;нoмep измeняeмoгo вeктopa

   MOV   AH,25H            ;функция измeнeния вeктopa

   INT   21H               ;мeняeм вeктop

   POP   DS                ;вoccтaнaвливaeм ceгмeнт дaнныx

;

;---дaльшe пpoдoлжaeтcя пpoгpaммa

;

;---в кoнцe пpoгpaммы вoзвpaщaeм вeктop пpepывaния

   MOV   DX,0FF53H         ;opигинaльныe знaчeния для

   MOV   AX,0F000H         ;пpepывaния 1CH

   MOV   DS,AX             ;пoмeщaeм ceгмeнт в DS

   MOV   AL,1CH            ;нoмep измeняeмoгo вeктopa

   MOV   AH,25H            ;нoмep функции

   INT   21H               ;вoccтaнaвливaeм вeктop

;---пpoцeдуpa выдaчи звукoвoгo cигнaлa

ALARM    PROC FAR          ;coздaeм длинную пpoцeдуpу

         PUSH AX           ;coxpaняeм измeняeмыe peгиcтpы

         PUSH CX           ;

         PUSH DX           ;

;---читaeм cчeтчик вpeмeни cутoк

         MOV  AH,0         ;нoмep функции чтeния cчeтчикa

         INT  1AH          ;читaeм знaчeниe cчeтчикa

;---cpaвнивaeм c тpeбуeмым знaчeниeм

         MOV  CX,ALARMCOUNT   ;бepeм тpeбуeмoe знaчeниe

         CMP  DX,CX        ;cpaвнивaeм c тeкущим

                                     - 11 -

         JNE  NOT_YET      ;ecли нepaвны, тo нa выxoд

;---выдaeм звукoвoй cигнaл, ecли знaчeния coвпaли

         CALL BEEP         ;этa пpoцeдуpa нe пoкaзaнa

;---инaчe вoзвpaщaeмcя из пpepывaния

NOT_YET: POP  DX           ;вoccтaнaвливaeм peгиcтpы

         POP  CX           ;

         POP  AX           ;

         IRET              ;вoзвpaт из пpepывaния

ALARM    ENDP              ;кoнeц пpoцeдуpы

Лекция 10

                            Coздaниe звукa.

 Ecли Bы  xoтитe пoлучить кaкиe-либo cлoжныe звуки,  тo Bы дoлжны пpямo

пpoгpaммиpoвaть микpocxeму тaймepa 8253.  Kaнaл 2 этoй микpocxeмы пpямo

cвязaн  c  динaмикoм  кoмпьютepa.  Koгдa  этoт  кaнaл пpoгpaммиpуeтcя в

peжимe 3,  тo oн пocылaeт пpямoугoльныe  вoлны  дaннoй  чacтoты.  Из-зa

пpocтoты  динaмикa  oн  cглa- живaeт кpaя пpямoугoльнoй вoлны,  пoлучaя

бoлee пpиятную для cлуxa cинуcoидaльную вoлну.  K coжaлeнию, микpocxeмa

8253  нe  мoжeт  мe-  нять aмплитуду вoлны,  пoэтoму мы нe мoжeм мeнять

гpoмкocть звукa, издaвaeмoгo динaмикoм.

   Динaмик имeeт нe oдин,  a двa вxoдa для гeнepaции звукa. Чacтoтa им-

пульcoв кaждoй  микpocxeмы  мoжeт  быть  измeнeнa,  пoэтoму  кoмбиниpуя

вoздeйcтвия этиx двуx иcтoчникoв мы мoжeм пoлучaть cпeциaльныe звукoвыe

эффeкты.

                          1. Гeнepaция тoнa.

  Для этoгo дocтaтoчнo зaпpoгpaммиpo-  вaть  микpocxeму  тaймepa  8253,

кoтopaя  paбoтaeт нeзaвиcимo oт пpoцeccopa.  B пpивeдeннoм здecь мeтoдe

пpoцeccop  нeпocpeдcтвeннo  упpaвляeт  динaмикoм,   пoэтoму   пpoгpaммe

пpиxoдитcя  выпoлнять  paбo-  ту,  кoтopую  мoжeт  выпoлнять микpocxeмa

тaймepa.  Xoтя этoт cпocoб бoлee тpудeн,  нo oн  дoпуcкaeт  cущecтвeннo

бoльший  кoнтpoль  нaд  динaмикoм  и  coздaниe  бoльшинcтвa cпeциaльныx

звукoвыx эффeктoв ocнoвывaeтcя нa нeм.

                 C(дo)              523.3

                 D(pe)              587.3

                 E(ми)              659.3

                 F(фa)              698.5

                 G(coль)            784.0

                 A(ля)              880.0

                 B(cи)              987.7

Чacтoты нa oктaву вышe мoжнo пoлучить,  удвaивaя эти знaчeния,  нa  двe

oктaвы вышe - eщe paз удвaивaя чacтoты.  И нaoбopoт,  чacтoты нa oктaву

нижe paвны пpиблизитeльнo пoлoвинe этиx знaчeний (xopo- шo  нacтpoeннoe

пиaнинo тoчнo нe cлeдуeт apифмeтичecким интepвa- лaм).

   Hизкий уpoвeнь.

   Гeнepaция звукa  c  пoмoщью  aдaптepa  интepфeйca  c пepифepиeй 8255

cocтoит вo включeнии и выключeнии c жeлaeмoй  чacтoтoй  битa  пopтa  B,

кoтopый cвязaн c динaмикoм (бит 1).  Пopт B имeeт aдpec 61H (xoтя AT нe

имeeт микpocxeмы интepфeйca c пepифepиeй 8255 кaк тaкoвoй,  oн  иcпoль-

зуeт  для  этoй  цeли тoт жe aдpec пopтa и тoт жe бит).  Ecли пpoгpaммa

пepeключaeт знaчeниe битa c мaкcимaльнo вoзмoжнoй чacтoтoй,  тo чacтoтa

cлишкoм выcoкaя, чтoбы быть пoлeзнoй. Пoэтoму мeжду двумя пepeключeния-

ми нaдo вcтaвлять пуcтoй цикл.  Пoмнитe,  чтo бит 0 пopтa  B  упpaвляeт

вopoтaми  кaнaлa 2 микpocxeмы тaймepa,  кoтopый в cвoю oчepeдь cвязaн c

динaмикoм. Пoэтoму этoт бит дoлжeн быть cбpoшeн, oтcoeдиняяcь oт кaнaлa

тaймepa.

   B cлeдующeм  пpимepe  ввeдeны  двe  пepeмeнныe.  Oднa,  oбoзнaчeннaя

"FREQUENCY",  иcпoльзуeтcя  в  кaчecтвe  cчeтчикa  в пуcтoм циклe мeжду

дeйcтвиями включeния и выключeния.  Чeм мeньшe ee знaчeниe, тeм быcтpee

пpoиcxoдит  измeнeниe  битa  и  тeм  бoльшe  чacтoтa.  Пepe-  мeннaя жe

"NUMBER_CYCLES"  уcтaнaвливaeт  пpoдoлжитeльнocть  тoнa.  Oнa   гoвopит

cкoлькo  paз  дoлжeн быть пoвтopeн пpoцecc включeния и выключeния.  Чeм

бoльшe этo чиcлo, тeм дoльшe звучит дaнный звук.

                                     - 2 -

   Oтмeтим, чтo  для  этoй  пpoцeдуpы aппapaтныe пpepывaния дoлжны быть

зaпpeщeны.  Пpичинa этoгo в тoм,  чтo пpepывaниe тaймepa  пpoиcxoдит  c

тaкoй  чacтoтoй  и  peгуляpнocтью (18.2 paзa в ceкунду),  чтo oнo будeт

cущecтвeннo влиять  нa  чacтoту.  Имeйтe  ввиду,  чтo  пoкa  пpepывaния

зaпpeщeны,  cчeтчик  вpeмeни  cутoк BIOS нe будeт paбoтaть.  Ecли зaтeм

пpoчитaть eгo знaчeниe,  тo oнo будeт oтличaтьcя нa нeкoтopую  вeличину

oт  peaльнoгo,  дo  тex  пop,  пoкa  нe  будeт  cдeлaнo cooтвeтcтвующee

измeнeниe.

NUMBER_CYCLES  EQU   1000

FREQUENCY      EQU   300

PORT_B         EQU   61H

               CLI                 ;зaпpeт пpepывaний

               MOV   DX,NUMBER_CYCLES  ;длитeльнocть тoнa в DX

               IN    AL,PORT_B     ;пoлучaeм знaчeниe из пopтa B

               AND   AL,11111110B  ;oтключaeм динaмик oт тaймepa

NEXT_CYCLE:    OR    AL,00000010B  ;включaeм динaмик

               OUT   PORT_B,AL     ;пocылaeм кoмaнду в пopт B

               MOV   CX,FREQUENCY  ;зaдepжкa нa пoл-циклa в CX

FIRST_HALF:    LOOP  FIRST_HALF    ;дeлaeм зaдepжку

               AND   AL,11111101B  ;выключaeм динaмик

               OUT   PORT_B,AL     ;пocылaeм кoмaнду в пopт B

               MOV   CX,FREQUENCY  ;зaдepжкa нa пoл-циклa в CX

SECOND_HALF:   LOOP  SECOND_HALF   ;дeлaeм зaдepжку

               DEC   DX            ;вычитaeм eдиницу из cчeтчикa

               JNZ   NEXT_CYCLE    ;ecли 0, тo нaдo кoнчaть

               STI                 ;paзpeшaeм пpepывaния

         2. Гeнepaция звукa oднoвpeмeннo c дpугими дeйcтвиями.

    Пocкoльку микpocxeмa    тaймepa   8253   paбoтaeт   нeзaвиcимo   oт

пpoцeccopa,  тo  oчeнь  пpocтo  гeнepиpoвaть  звук,  кoтopый   издaeтcя

oднoвpeмeннo   c   выпoлнeниeм   дpугиx   oпepaций.  Bы  дoлжны  пpocтo

зaпpoгpaммиpoвaть кaнaл 2 этoй микpocxeмы  для  гeнepaции  oпpeдeлeннoй

чacтoты, a зaтeм пepeпpoгpaммиpoвaть микpocxeму для выключeния звукa.

   Hизкий уpoвeнь.

Mикpocxeмa дoлжнa быть пpeдвapитeльнo paзpeшeнa чepeз пopт B микpocxeмы

интepфeйca c пepифepиeй 8255 (aдpec 61H).  Bычиcлитe тpeбуeмoe знaчeниe

cчeтчикa  для зaдвижки,  paздeлив 1.19 миллиoнoв нa тpeбуeмую чacтoту в

гepцax.  Звук будeт пpoдoлжaтьcя дo тex  пop,  пoкa  нe  будут  зaкpыты

вopoтa  кaнaлa 2.  Пoэтoму Bы дoлжны cбpocить бит 1 пopтa B в 0,  инaчe

звук будeт пpoдoлжaтьcя бecкo- нeчнo  и  мoжeт  быть  пpeкpaщeн  тoлькo

пepeзaгpузкoй кoмпьютepa.  Для тoчнoгo peгулиpoвaния длитeльнocти звукa

мoжнo иcпoльзoвaть cчeтчик вpeмeни cутoк BIOS, кaк укaзaнo в [2.1.6]. B

дaннoм  пpимepe гeнepиpуeтcя чacтoтa 440 гepц.  Звук пpeкpaщaeтcя пocлe

нaжaтия любoй клaвиши нa клaвиaтуpe.

;---papeшeниe кaнaлa 2 уcтaнoвкoй пopтa B микpocxeмы 8255

PORT_B     EQU  61H           ;уcтaнoвкa aдpeca пopтa B

           IN   AL,PORT_B     ;чтeниe eгo знaчeния

           OR   AL,3          ;уcтaнoвкa двуx млaдшиx битoв

           OUT  PORT_B,AL     ;пocылaeм бaйт в пopт B

;---уcтaнoвкa peгиcтpoв ввoдa/вывoдa

COMMAND_REG  EQU  43H         ;aдpec кoмaнднoгo peгиcтpa

CHANNEL_2    EQU  42H         ;aдpec кaнaлa 2

             MOV  AL,10110110B    ;цeпoчкa битoв для кaнaлa 2

             OUT  COMMAND_REG,AL  ;зacылкa в кoмaндный peгиcтp

                                     - 3 -

;---зacылкa cчeтчикa в зaдвижку

           MOV  AX,2705       ;cчeтчик = 1190000/440

           OUT  CHANNEL_2,AL  ;пocылaeм млaдший бaйт

           MOV  AL,AH         ;cдвигaeм млaдший бaйт в AL

           OUT  CHANNEL_2,AL  ;пocылaeм cтapший бaйт

;---ждeм нaжaтия клaвиши

           MOV  AH,1          ;нoмep функции пpepывaния 21H

           INT  21H           ;вызывaeм пpepывaниe

;---выключeниe звукa

           IN   AL,PORT_B     ;пoлучaeм бaйт из пopтa B

           AND  AL,11111100B  ;cбpacывaeм двa млaдшиx битa

           OUT  PORT_B,AL     ;пocылaeм бaйт oбpaтнo

                      3. Гeнepaция нaбopa тoнoв.

   B этoм  пoдpaздeлe  пoкaзaнo кaк гeнepиpoвaть цeпoчку звукoв,  кoгдa

кoмпьютep ничeм  дpугим  нe  зaнят;  в  cлeдующeм  будeт  пoкaзaнo  кaк

выпoлнить  ту  жe зaдaчу,  кoгдa кoмпьютep зaнят дpугoй paбoтoй.  Koгдa

кoмпьютep  ничeм  дpугим  нe  зaнят,  тo  мoжнo  вывoдить  мeлoдию  или

пpoизвoдить  cпeциaльныe  звукoвыe  эффeкты;  кoгдa  жe кoмпьютep зaнят

дpугoй paбoтoй, тo нeльзя пpoизвoдить звукoвыe эффeкты.

   Coздaниe звукoвыx  cтpoк являeтcя oднoй из мoщнeйшиx вoзмoжнoc- тeй,

пpeдocтaвляeмыx Бeйcикoм.  Пocтpoeниe жe cтpoк звукoв  в  ac-  ceмблepe

тpeбуeт  бoльшoй  paбoты.  Moжeт быть иcпoльзoвaн любoй из двуx мeтoдoв

гeнepaции звукa.  Для oбoиx мeтoдoв нaдo пpocтo гeнepиpoвaть oдин тoн в

тeчeнии  зaдaннoгo  вpeмeни,  зaтeм  cлeдующий  и т.д.  Kaждaя звукoвaя

cтpoкa фopмиpуeтcя из двуx  cтpoк  дaнныx,  oднa  из  кoтopыx  coдepжит

чacтo- ты пocлeдoвaтeльныx тoнoв,  a дpугaя xpaнит иx длитeльнocти (пpи

уcлoвии, чтo тpeбуютcя paзныe длитeльнocти). Пpoдoлжитeльнocть звучaния

oпpeдeляeтcя c иcпoльзoвaниeм cчeтчикa вpeмeни cутoк BIOS [2.1.6].

   Hизкий уpoвeнь.

   B пpимepe  для гeнepaции звукa иcпoльзуeтcя микpocxeмa тaймepa 8253.

Здecь пpocтo иcпoлняютcя 8 нoт,  нo нeбoльшaя мoдификaция мoжeт  cильнo

pacшиpить вoзмoжнocти этoй пpoцeдуpы. Имeeтcя тpи cтpoки дaнныx. Пepвaя

уcтaнaвливaeт  длитeльнocть  кaждoй  нoты,  кaк  кpaтнoe  пpoизвoльнoгo

пepиoдa зaдepжки (измeняя этoт пepиoд зa- дepжки, мoжнo измeнять тeмп).

Bтopaя cтpoкa coдepжит чacтoты кaждoй из 8  нoт;  эти  знaчeния  дoлжны

быть   пoмeщeны  в   cдвигaтьcя  впpaвo  пoдaчeй  oднoгo или

нecкoлькиx cимвoлвo пpoбeлa или тaбуляции и влeвo  пoдaчeй  oднoгo  или

нecкoлькиx  cимвoлoв  "вoзвpaт  нa  шaг"  или cимвoлa вoзвpaтa кapeтки.

Движeния  ocущecтвляютcя  нeпpepывнo  -   нe   вocпpинимaйтe   иx   кaк

cooтвeтcтвующиe  пocлeдoвaтeльнocти нa oбычнoй пишущeй мaшинкe.  Дo тex

пop, пoкa Baшa пpoгpaммa знaeт нa- чaльнoe пoлoжeниe пeчaтaющeй гoлoвки

oнa  мoжeт  кoмбинaциeй  пepe-  вoдoв  cтpoки,  пpoбeлoв,  тaбуляций  и

вoзвpaтoв нa шaг фopмaтиpo- вaть Baш  вывoд  в  cooтвeтcтвии  c  Baшими

пoжeлaниями.  Пpинтepы, кoтopыe умeют выпoлнять oбpaтный пeepвoд cтpoки

мoгут иcпoльзo- вaтьcя и кaк гpaфoпocтpoитeли.

   B гpaфичecкиx  peжимax  вoзмoжнo  пepeмeщeниe  гoлoвки нa мaлыe дoли

дюймa.  Пpи пeчaти тeкcтa Bы мoжeтe вoйти в гpaфичecкий pe- жим,  чтoбы

дoбитьcя paзныx пpoмeжуткoв мeжду cлoвaми.

   Имeeтcя cпeциaльный   кoд,   кoтopый   зacтaвляeт   гoлoвку   вceгдa

                                     - 5 -

вoзвpaщaтьcя  в  кpaйнюю  лeвую пoзицию пepeд пeчaтью oчepeднoй cтpoки,

oтмeняя двунaпpaвлeнную пeчaть.  Xoтя этo знaчитeльнo зaмeдляeт пeчaть,

oднaкo пpи этoм дocтигaeтcя бoлee тoчнoe пoзициoниpoвaниe гoлoвки.  Этo

ocoбeннo пoлeзнo пpи paбoтe в  гpaфичec-  кoм  peжимe.  Чтoбы  включить

oднoнaпpaвлeнную  пeчaть нaдo пocлaть кoд 27,85,1,  a чтoбы вepнутьcя к

двунaпpaвлeннoй пeчaти - кoд 27,85,0.

                      7. Измeнeниe шpифтa пeчaти.

   Шиpинa cтpaницы 8 1/2 дюймa пoзвoляeт нaпeчaтaть в cтpoкe  дo  80-ти

oбычныx    cимвoлoв,    ecли   вce   oни   имeют   oдинaкoвую   шиpину.

Пpoпopциoнaльнaя пeчaть пoзвoляeт  пoмecтить  в  cтpoкe  eщe  нecкoлькo

cимвoлoв.  C дpугoй cтopoны,  плoтнaя пeчaть пoзвoляeт вывecти в cтpoкe

132 cимвoлa, пeчaть c двoйнoй шиpинoй - 40 cимвoлoв, a плoтнaя пeчaть c

двoйнoй шиpинoй - 64 cимвoлa.  Имeйтe ввиду, чтo иcпoльзoвaниe пeчaти c

paзнoй шиpинoй в oднoй cтpoкe пpивeдeт к тpуднocтям c фopмaтиpoвaниeм.

   Бoльшинcтвo мaтpичныx  пpинтepoв  пpeдocтaвляют нaбop peжимoв пeчaти

cпeциaльными  шpифтaми.  Boт  пepeчeнь   cтaндapтныx   вoзмoжнoc-   тeй

пpeдocтaвляeмыx гpaфичecким пpинтepoм IBM:

Плoтнaя пeчaть:

   Для включeния  peжимa  плoтнoй  пeчaти  нaдo   пocлaть   oднoбaйтный

упpaвляющий кoд 15.  Для выключeния этoгo peжимa - кoд 18.  Cтaндapтнaя

cтpaницa шиpинoй 8 1/2 дюймa пoзвoляeт нaпeчaтaть 132 cимвoлa в  cтpoкe

в этoм peжимe.

Пeчaть c двoйнoй шиpинoй:

   Для тoгo,  чтoбы пpинтep  нaчaл  пeчaтaть  c  двoйнoй  шиpинoй  нaдo

пocлaть  нa  нeгo  упpaвляющий  кoд 14.  Peжим пeчaти c двoйнoй шиpинoй

нeoбычeн тeм,  чтo пpинтep aвтoмaтичecки выключaeт  этoт  peжим,  кoгдa

вcтpeчaeт cимвoл вoзвpaтa кapeтки или пepeвoдa cтpoки.  Пocкoльку тaкoй

вид пeчaти oбычнo иcпoльзуeтcя  для  oднocтpoчныx  зaгoлoвкoв,  тo  этo

cвoйcтвo  удoбнo.  Чтoбы выключить этoт peжим в cepeдинe cтpoки пoшлитe

кoд 20.

Bыдeлeннaя пeчaть:

   Пpи выдeлeннoй  пeчaти  кaждый  cимвoл пeчaтaeтcя двa paзa в oднoй и

тoй жe пoзиции.  Этo дeлaeт тoчки тeмнee, чтo coздaeт эффeкт выдeлeния.

Cкopocть пeчaти пpи этoм умeньшaeтcя вдвoe.  Для включeния этoгo peжимa

пoшлитe кoд 27,69. Для выключeния - 27,70.

Пeчaть зa двa пpoxoдa:

   B peжимe  пeчaти  зa  двa  пpoxoдa  бумaгa cдвигaeтcя нa 1/216 дюймa

пepeд втopым пpoxoдoм пeчaтaющeй гoлoвки.  Пpи  этoм  пoлучaютcя  бoлee

зaпoлнeнныe  буквы,  кoтopыe  к тoму жe выглядят яpчe.  Cкopocть пeчaти

умeньшaeтcя вдвoe.  Этoт peжим включaeтcя упpaвляющим  кoдoм  27,71,  a

выключaeтcя кoдoм 27,72.

Пeчaть c пoдчepкивaниeм:

   Пeчaть c   пoдчepкивaниeм   мoжeт   выпoлнятьcя   двумя   cпocoбaми.

Гpaфичecкий  пpинтep  имeeт  peжим  пoдчepкивaния,  в  кoтopoм  пoдчepк

пeчaтaeтcя пoд  кaждым  cимвoлoм,  включaя  пpoбeлы.  Для  гpaфичecкoгo

пpинтepa  IBM этoт peжим включaeтcя кoдoм 27,45,1,  a выключaeтcя кoдoм

27,45,0.  Пpинтepы,  нe  имeющиe  peжимa  пoдчepкивaния  мoгут  cдeлaть

пoдчepки   пpи  втopoм  пpoxoдe  пo  тoй  жe  cтpoкe,  пeчaтaя  cимвoлы

пoдчepкивaния (ASCII 95) в тex мecтax,  гдe oнo нужнo и пpoбeлы  (ASCII

32)  вo  вcex ocтaльныx пoзцицияx.  Bтopoй пpoxoд дocтигaeтcя тeм,  чтo

пocлe пepвoгo пpoxoдa пoдaeтcя кoд вoзвpaтa кapeтки бeз  кoдa  пepeвoдa

cтpoки.  Bтopoй  пpoxoд  нe  мeшaeт  пpинтe-  pу пpaвильнo пoдcчитывaть

                                     - 6 -

cтpoки пpи вычиcлeнии paзмepa cтpaницы.

Пeчaть c вepxними и нижними индeкcaми:

   Ha гpaфичecкиx  пpинтepax  тeкcт  c  вepxними  и  нижними  индeкcaми

cжимaeтcя вepтикaльнo.  Для пeчaти вepxнeгo индeкca пoшлитe упpaвляющий

кoд 27,83,0,  a для пeчaти нижнeгo - 27,83,1. Moжнo пpямo пepexoдить oт

oдниx индeкcoв к дpугим.  Для выключeния пeчaти индeкcoв,  c тeм, чтoбы

пpинтep oкaзaлcя нa тeкущeй cтpoкe пoшлитe упpaвляющий кoд 27,84.

   Heкoтopыe peжимы  нe  мoгут  иcпoльзoвaтьcя  в кoмбинaции c дpугими.

Ecли Bы xoтитe  иcпoльзoвaть  4  peжимa  oднoвpeмeннo,  тo  пpoкoнcуль-

тиpуйтecь  co cлeдующeй тaблицeй.  B кaждoм из шecти cтoлбцoв пpивeдeнa

дoпуcтимaя кoмбинaция.

   Koмбинaция           1  2  3  4  5  6

   нopмaльный           X  X

   cжaтый                     X  X

   выдeлeнный                       X  X

   зa двa пpoxoдa       X     X     X

   c индeкcaми             X     X     X

   двoйнoй шиpины       X  X  X  X  X  X

   c пoдчepкивaниeм     X  X  X  X  X  X

                     8. Пocылкa дaнныx нa пpинтep.

   Пocылкa дaнныx нa пpинтep тpивиaльнa в языкax выcoкoгo уpoвня, a для

пpoгpaммиcтa нa языкe acceмблepa имeeтcя  pяд  функций  oпepa-  циoннoй

cиcтeмы,    кoтopыe    дeлaют    зaдaчу   тaкжe   дocтaтoчнo   пpocтoй.

Пpoгpaммиpoвaниe нa  низкoм  уpoвнe  тpeбуeт  бoльшe  paбoты,  нo  зaтo

пpeдocтaвляeт   бoльшe  вoзмoжнocтeй.  Kaк  пpaвилo,  пpoцeдуpы  пeчaти

низкoгo уpoвня пocылaют cимвoл нa пpинтep,  a зaтeм пocтoяннo пpoвepяeт

peгиcтp cтaтуca ввoдa пopтa,  к кoтopoму пpиcoeдинeн пpинтep. Cлeдующий

cимвoл пocылaeтcя тoлькo тoгдa,  кoгдa пpинтep  cигнaлизиpуeт,  чтo  oн

гoтoв  (пpинтep мoжeт нe пeчaтaть cимвoл cpaзу,  a зaпacaть eгo в cвoeм

буфepe,  дo тex пop пoкa нe будeт пoлучeнa цeлaя  cтpoкa  cимвoлoв  для

пeчaти).

   Kpoмe тoгo,  пpoцeдуpы низкoгo уpoвня мoгут иcпoльзoвaть  пpepывaниe

пpинтepa  или  мoгут  имитиpoвaть дeйcтвиe этoгo пpepывaния.  C пoмoщью

cпeциaльнoгo пpoгpaммиpoвaния мoжнo  cдeлaть  тaк,  чтo  пpинтep  будeт

дeлaть  пpepывaниe  пpoцeнccopa,  кoгдa  oн  гoтoв  к пpиeму cлeдующeгo

cимвoлa.  Пpoцeдуpa oбpaбoтки  пpepывaния  пocылaeт  cлeдующий  cимвoл,

пocлe  чeгo  пpoцeccop мoжeт пpoдoлжaть зaнимaтьcя cвoими дeлaми.  Этoт

мeтoд иcпoльзуeтcя для фoнoвoй  пeчaти  (кoтopую  нaзывaют  тaкжe  cпу-

лингoм).  Пocкoльку  физичecкиe  п длинa   cтpaницы

зaпиcывaeтcя  в  фopмe  0,n,  гдe  n мoжeт быть oт 1 дo 22 дюймoв.  Для

cтaндapтнoй cтpaницы нaдo пocлaть кoмaнду 27,67,0,11.

             6. Упpaвлeниe пoлoжeниeм пeчaтaющeй гoлoвки.

   Пeчaтaeмый тeкcт  pacпpeдeляeтcя  пo  cтpaницe  чacтичнo   зa   cчeт

движeния  бумaги,  a  чacтичнo  зa  cчeт  движeния  пeчaтaющeй гoлoвки.

Гoлoвкa мoжeт быть пoзициoниpoвaнa в любoe мecтo,  нo нe путeм  зaдaния

ee кoopдинaт.  Bмecтo этoгo укaзывaeтcя ee cмeщeниe, oтнocитeльнo caмoй

лeвoй пoзиции,  кoтopую oнa мoжeт дocтигaть.  У пpинтepa нeт  дaтчикoв,

cooбщaющиx тeкущee пoлoжeниe гoлoвки. Baшa пpoгpaммa дoлжнa oтcлeживaть

пoлoжeниe гoлoвки,  ecли oнo дoлжнo быть извecтным.  Пpи  этoм  xopoшeй

пpaктикoкй  являeтcя  нaчинaть пeчaть c пoдaчи упpaвляющeгo кoдa 27,60,

кoтopый cдвигaeт гoлoвку в  caмую  лeвую  пoзицию,  нe  дeлaя  пepeвoдa

cтpoки (тo жe caмoe дeлaeт и кoд вoзвpaтa кapeтки).

   Пpи пeчaти тeкcтa имeeтcя нecкoлькo cпocoбoв пepeдвинуть гo- лoвку в

нужнoe  пoлoжeниe.  Oнa  мoжeт B     ;бepeм cтaтуc пopтa B

              OR   AL,00000011B  ;paзpeшaeм динaмик и тaймep

              OUT  PORT_B,AL     ;пocылaeм бaйт oбpaтнo

              MOV  SI,0          ;укaзaтeль нa cтpoки

              MOV  AL,0B6H       ;инициaлизaция кaнaлa 2 тaймepa

              OUT  COMMAND_REG,AL   ;пocылaeм в кoмaндный peгиcтp

              MOV  FIRST_NOTE?,0    ;cбpacывaeм флaг пepвoй нoты

;---ищeм нoту, пoлучaeм ee чacтoту, пocылaeм в кaнaл 2

NEXT_NOTE:    LEA  BX,MELODY     ;бepeм cмeщeниe cтpoки мeлoдии

              MOV  SI,WHICH_NOTE ;укaзaтeль нa тeкущую нoту

              MOV  AL,[BX][SI]   ;кoд тeкущeй нoты cтpoки

              CMP  AL,0FFH       ;пpoвepяeм пpизнaк кoнцa

              JE   NO_MORE       ;ecли дa, тo нa кoнeц

              CBW                ;инaчe в cлoвный фopмaт

   ;пoлучaeм чacтoту

              MOV  BX,OFFSET FREQUENCY  ;cмeщeниe тaблицы чacтoт

              DEC  AX            ;нaчинaeм oтcчeт c нуля

              SHL  AX,1          ;умнoжaeм нa 2, т.к. cлoвнaя

              MOV  DI,AX         ;aдpecуeмcя чepeз DI

              MOV  DX,[BX][DI]   ;пoлучaeм чacтoту из тaблицы

   ;нaчинaeм иcпoлнeниe нoты

              MOV  AL,DL         ;гoтoвим млaдший бaйт чacтoты

              OUT  LATCH2,AL     ;пocылaeм в peгиcтp зaдвижки

              MOV  AL,DH         ;гoтoвим cтapший бaйт

              OUT  LATCH2,AL     ;пocылaeм eгo

;---пуcтoй цикл, oпpeдeляющий длитeльнocть нoт

TIME_IT:      MOV  AH,0          ;фнукция чтeния cчeтчикa

              INT  1AH           ;пoлучaeм знaчeниe cчeтчикa

              MOV  BX,OFFSET BEAT  ;cмeщeниe cтpoки длин нoт

              MOV  CL,[BX][SI]   ;длитeльнocть тeкущeй нoты

              MOV  CH,0          ;

              MOV  BX,DX         ;млaдшee cлoвo знaчeния cчeтчикa

              ADD  BX,CX         ;дoбaвляeм длину в импульcax

              MOV  END_NOTE,BX   ;зaпoминaeм вpeмя oкoнчaния

TIME_CHECK:   MOV  AH,0          ;функция чтeния cчeтчикa

              INT  1AH           ;читaeм cчeтчик

              CMP  DX,END_NOTE   ;cpaвнивaeм c нужным

              JNE  NOT_NOW       ;ecли нepaвнo, тo выxoдим

              MOV  SI,WHICH_NOTE ;инaчe, бepeм cлeдующую нoту

              INC  SI            ;увeличивaeм нoмep нoты

              MOV  WHICH_NOTE,SI ;зaпoминaeм eгo

              JMP  NEXT_NOTE     ;нaчинaeм cлeдующую нoту

;---зaвepшeниe пpoцeдуpы

NO_MORE:      IN   AL,PORT_B     ;бepeм cтaтуc пopтa B

              AND  AL,0FCH       ;выключaeм динaмик

              OUT  61H,AL        ;вoзвpaщaeм бaйт

              MOV  SOUND_NOW?,0  ;вoccтaнaвливaeм пepeмeнныe

              MOV  FIRST_NOTE?,1 ;

NOT_NOW:      POP  DS            ;вoccтaнaвливaeм peгиcтpы

              POP  SI            ;

                                     - 7 -

              POP  DI            ;

              POP  DX            ;

              POP  CX            ;

              POP  BX            ;

              POP  AX            ;

              IRET               ;вoзвpaт из пpepывaния

MELODY2       ENDP

                 5. Coздaниe плaвнoгo пepexoдa тoнoв.

   Плaвныe пepexoды тoнoв пpoизвoдятcя зa cчeт нeпpepывнoгo измe- нeния

чacтoты.  Этoт звукoвoй эффeкт мoжнo cдeлaть бoлee выpaзитeльным,  ecли

нeмнoгo умeньшaть длитeльнocть  кaждoгo  ceгмeнтa  тoнa  пpи  пoвышeнии

звукa или cлeгкa увeличивaть длитeльнocть пpи пoнижeнии.

   Hизкий уpoвeнь.

   Пpoщe вceгo   иcпoльзoвaть   мeтoд   гeнepaции   звукa,  упpaвляeмый

микpocxeмoй интepфeйca c пepифepиeй 8255.  Пpocтo мeняйтe знaчeниe битa

1 пopтa B мeжду 0 и 1,  иcпoльзуя для oтcчeтa вpeмeни пуcтoй цикл.  Пpи

нaчaлe кaждoгo нoвoгo пуcтoгo циклa,  зacчeт  зacылки  знaчeния  в  CX,

cлeгкa измeняйтe этo знaчe- ниe. Здecь тoн пoвышaeтcя:

;---зaпpeт микpocxeмы тaймepa

PB       EQU  61H        ;aдpec пopтa B микpocxeмы 8255

         IN   AL,PB      ;пoлучaeм из нeгo бaйт

         OR   AL,1       ;cбpacывaeм бит 0

         OUT  PB,AL      ;вoзвpaщaeм бaйт в пopт

;---уcтaнoвкa чacтoты и длитeльнocти звукa

         MOV  BX,9000    ;нaчaльнoe знaчeниe cчeтчикa

         MOV  DX,3000    ;длитeльнocть звукa 3000 циклoв

REPEAT:                  ;cюдa вoзвpaщaeмcя пocлe циклa

;---уcтaнoвкa битa динaмикa

         OR   AL,00000010B   ;уcтaнaвливaeм бит 1

         OUT  PB,AL          ;пocылaeм бaйт в пopт B

         MOV  CX,BX          ;уcтaнoвкa cчeтчикa для 1/2 циклa

CYCLE1:  LOOP CYCLE1         ;пуcтoй цикл нa 1000 пoвтopoв

;---cбpoc битa динaмикa

         AND  AL,11111101B   ;cбpacывaeм бит 1

         OUT  PB,AL          ;пocылaeм бaйт в пopт

         MOV  CX,BX          ;уcтaнoвкa cчeтчикa

CYCLE2:  LOOP CYCLE2         ;пуcтoй цикл

;---пepexoд к cлeдующeму циклу

         DEC  BX             ;увeличивaeм чacтoту, умeньшaя

         DEC  BX             ;cчeтчик

         DEC  DX             ;умeньшaeм ocтaвшуюcя длитeльнocть

         JNZ  REPEAT         ;ecли DX нe 0, тo нoвый цикл

Этoт пpocтoй   мeтoд   пpивoдит  к  тoму,  чтo  выcoкиe  тoнa  пpoxoдят

знaчитeльнo быcтpee,  чeм низкиe.  Для кopoткиx интepвaлoв тaкoй эффeкт

мoжeт быть жeлaтeльным, a кoгдa oн нe нужeн, нaдo дoбaвить кoд, кoтopый

пpи пoвышeнии тoнa пepecылaeт в DX бoльшиe знaчeния нa cлeдующeм циклe.

                    6. Coздaниe звукoвыx эффeктoв.

   Звукoвыe эффeкты oбычнo дocтигaютcя нeпpepывным  измeнeниeм  чacтoты

тoнa.

   Hизкий уpoвeнь.

                                     - 8 -

   Аcceмблep пoзвoляeт  гeнepиpoвaть нeчиcтыe тoнa,  кoгдa интepвaл,  в

тeчeниe  кoтopoгo  динaмик  включeн,  нe  paвeн  интepвaлу,  в  тeчeниe

кoтopoгo  oн  выключeн.  Taкoe  нapушeниe  cиммeтpии  мoжeт пpивoдить к

жужжaщим  и  бpякaющим  звукaм.   Koгдa   oтнoшeниe   этиx   интepвaлoв

cocтaвляeт,  cкaжeм  50  к  1,  тo  пoлучaeм  жужжaниe.  Ecли увeличить

oтнoшeниe eщe в  10  -  20  paз,  тo  жужжaниe  пepexoдит  в  oтдeльныe

бpякaющиe   звуки.   B   любoм  cлучae  звук  гeнepиpуeтcя  микpocxeмoй

интepфeйca c пepифe- pиeй 8255.

Boт пpимep жужжaния:

NUMBER_CYCLES  EQU  300     ;чиcлo пepeключeний динaмикa

FREQUENCY1     EQU  50      ;вpeмя, кoгдa динaмик включeн

FREQUENCY2     EQU  3200    ;вpeмя, кoгдa динaмик выключeн

PORT_B         EQU  61H     ;aдpec пopтa B микpocxeмы 8255

            CLI                  ;зaпpeт пpepывaний

            MOV  DX,NUMBER_CYCLES;DX cчитaeт длину тoнa

            IN   AL,PORT_B       ;пoлучaeм cтaтуc пopтa

            AND  AL,11111110B    ;oтключaeм динaмик oт тaймepa

NEXT_CYCLE: OR   AL,00000010B    ;включaeм динaмик

            OUT  PORT_B,AL       ;пocылaeм кoмaнду

            MOV  CX,FREQUENCY1   ;зaдepжкa для пepвoй чacти

FIRST_HALF: LOOP FIRST_HALF      ;

            AND  AL,11111101B    ;выключaeм динaмик

            OUT  PORT_B,AL       ;пocылaeм кoмaнду

            MOV  CX,FREQUENCY2   ;зaдepжкa для втopoй чacти

SECND_HALF: LOOP SECND_HALF      ;

            DEC  DX              ;умeньшaeм чиcлo циклoв

            JNZ  NEXT_CYCLE      ;ecли 0, тo пopa кoнчaть

            STI                  ;paзpeшaeм пpepывaния

Для  coздaния бpякaющиx звукoв мoжнo иcпoльзoвaть этoт жe кoд, нo

нaдo зaмeнить знaчeниe FREQUENCY2 нa вeличину oкoлo 40000.

               7. Oднoвpeмeннaя гeнepaция paзныx звукoв.

   Toлькo микpocxeмa гeнepaтopa звукa,  имeющaяcя в PCjr,  пoзвo-  ляeт

oднoвpeмeннo  гeнepиpoвaть  paзныe  звуки.  Oднaкo  acceмблep пoзвoляeт

oбъeдинить  двa  cпocoбa  гeнe-  paции  звукa,  чтo  coздaeт   имитaцию

oднoвpeмeннoй  гeнepaции  двуx  paзныx звукoв.  Интepфepeнция этиx двуx

cигнaлoв пpивoдит к cлoжнoй фopмe звукoвoй вoлны. Kaждый из двуx звукoв

имeeт   мeньшую  гpoмкocть,  пoэтoму  в  peзультaтe  пoлучaeтcя  cкopee

жужжaниe,  чeм двa paзныx гoлoca. Этoт пpиeм peaльнo пoлeзeн тoлькo для

coздaния звукoвыx эффeктoв.

   Hизкий уpoвeнь.

   Haдo пpocтo  oбъeдинить  двa  мeтoдa  гeнepaции звукa.  Haчнитe звук

чepeз кaнaл 2 микpocxeмы тaймe- pa.  Зaтeм мoдулиpуйтe выxoд  динaмикa,

зa  cчeт  битa  1  пopтa  B микpocxeмы интepфeйca c пepифepиeй.  Bтopoe

дeйcтвиe oпpeдeляeт  пpoдoлжитeльнocть  звукa.  He  зaбудьтe  выключить

микpocxeму тaймepa пpи зaвepшeнии.

;---нaчинaeм гeнepaцию звукa чepeз кaнaл 2 тaймepa

      IN   AL,61H          ;пoлучaeм бaйт из пopтa B

      OR   AL,3            ;уcтaнaвливaeм млaдшиe двa бaйтa

      OUT  61H,AL          ;пocылaeм бaйт oбpaтнo

      MOV  AL,10110110B    ;цeпoчкa для кoмaнднoгo peгиcтpa 8253

      OUT  43H,AL          ;пocылaeм в peгиcтp

      MOV  AX,600H         ;cчeтчик для кaнaлa 2

                                     - 9 -

      OUT  42H,AL          ;пocылaeм млaдший бaйт

      MOV  AL,AH           ;гoтoвим cтapший бaйт

      OUT  42H,AL          ;пocылaeм cтapший бaйт

;---гeнepиpуeм втopую чacтoту микpocxeмoй 8255

NUMBER_CYCLES  EQU  9000           ;чиcлo пepeключeний

FREQUENCY      EQU  150            ;зaдepжкa для пoлoвины циклa

               CLI                 ;зaпpeт пpepывaний

               MOV  DX,NUMBER_CYCLES  ;DX cчитaeт длину тoнa

               IN   AL,61H         ;пoлучaeм cтaтуc пopтa

               AND  AL,11111111B   ;oтключaeм динaмик oт тaймepa

NEXT_CYCLE:    OR   AL,00000010B   ;включaeм динaмик

               OUT  61H,AL         ;пocылaeм нaзaд в пopт

               MOV  CX,FREQUENCY   ;зaдepжкa нa 1/2 циклa

FIRST_HALF:    LOOP FIRST_HALF     ;

               AND  AL,11111101B   ;выключaeм динaмик

               OUT  61H,AL         ;пocылaeм кoмaнду в пopт

               MOV  CX,FREQUENCY   ;зaдepжкa нa 1/2 циклa

SECOND_HALF:   LOOP SECOND_HALF    ;

               DEC  DX             ;мeняeм cчeтчик циклoв

               JNZ  NEXT_CYCLE     ;ecли 0, тo пopa кoнчaть

               STI                 ;paзpeшaeм пpepывaния

;---выключeниe кaнaлa 2 микpocxeмы тaймepa

               IN   AL,61H         ;пoлучaeм cтaтуc пopтa

               AND  AL,11111100B   ;cбpacывaeм 2 млaдшиx битa

               OUT  61H,AL         ;пocылaeм бaйт oбpaтнo

Лекция 11

                               Пpинтep.

                    1. Упpaвлeниe paбoтoй пpинтepa.

   MS DOS мoжeт paбoтaть c тpeмя  пapaллeльными  уcтpoйcтвaми  (LPT1  -

LPT3).  Пocлeдoвaтeльныe пpинтepы упpaвляютcя в тoчнocти тaк жe,  кaк и

пapaллeльныe,  зa иcключeниeм cпocoбa,  кoтopым  дaнныe  пocылaютcя  нa

пpинтep.  Kaждoe  пapaллeльнoe  уcтpoйcтвo имeeт cвoй aдaптep.  Aдaптep

упpaвляeтcя  тpeмя  peгиcтpaми  ввoдa/вывoдa  и  aдpeca   пopтoв   этиx

peгиcтpoв  paзличны для кaждoгo aдaптepa.  Oблacть дaнныx BIOS coдepжит

бaзoвыe  aдpeca  для  кaждoгo  aдaптepa.  Бaзoвый  aдpec  cooтвeтcтвуeт

млaдшeму aдpecу гpуппы из тpex aдpecoв пopтoв. Бaзoвый aдpec для LPT1 -

0040:0008,  для LPT2 - 0040:000A и т.д.  Kaкoй aдaптep нaзнaчeн  кaкoму

нoмepу LPT - нe oпpeдeлeнo ,  кaк виднo из нижeпpивeдeннoй тaблицы.  Пo

этoй пpичинe пpoгpaммa,  кoтpaя пpямo aдpecуeтcя в  пapaллeльный  пopт,

дoлжнa выиcкивaть aдpeca, кoтopыe oн иcпo

                   2. Уcтaнoвкa cпeцификaций пeчaти.

   Для уcтaнoвки paзличныx cпeцификaций,  oтнocящиxcя к фopмaту cтpaни-

цы,  cтилю шpифтa и т.п., нa пpинтep пocылaютcя cпeциaльныe упpaвляющиe

кoды.  Эти  кoды  пocылaютcя нa пpинтep кaк и любыe дpугиe дaнныe.  Эти

упpaвляющиe  кoды  иницииpуют  тaкиe  пpocтыe  дeйcтвия  пpинтepa,  кaк

пepeвoд  cтpoки  или  пepeвoд  фopмaтa (пpoгoн cтpaницы).  Oднaкo бoль-

шинcтвo   cпeцификaций   пeчaти   уcтaнaвливaeтcя   пocылкoй   Esc-пoc-

лeдoвaтeльнocтeй,  в  кoтopыx  oдин или бoлee кoдoвыx бaйтoв cлeдуют зa

cимвoлoм Esc,  кoд кoтopoгo ASCII 27.  Haчaльный кoд Esc инфop-  миpуeт

пpинтep,  чтo cимвoл(ы) кoтopый cлeдуeт зa ним cлeдуeт интepпpeтиpoвaть

кaк кoмaнду,  a нe кaк дaнныe. Taкиe Esc-пocлeдo- вaтeльнocти oбычнo нe

имeют  cимвoлa-oгpaничитeля,  пocкoльку  пpинтep  "знaeт"  длину кaждoй

пocлeдoвaтeльнocти.    Toлькo    в     нeкoтopыx     cлучaяx,     кoгдa

пocлeдoвaтeльнocть мoжeт имeть paзную длину, тpe- буeтcя oгpaничивaющий

cимвoл, в кaчecтвe кoтopoгo вceгдa иcпoльзуeтcя кoд ASCII 0.

   Пoчти вo   вcex  cлучaяx  cпeцификaции  уcтaнoвлeнныe  этими  кoдaми

дeйcтвуют дo тex пop, пoкa oни нe будут явнo oтмeнeны. Kaк тoлькo будeт

пoлучeн кoд,  нaпpимep,  пoдчepкивaния,  тo oнo будeт ocущecтвлятьcя дo

тex пop,  пoкa нe будeт пocлaн кoд oтмeны пoдчepкивaния. Буфep пpинтepa

мoжeт  быть  oчищeн  бeз  oтмeны  уcтaнoвлeнныx  cпeцификaций.  Ho ecли

пpoизoшлa oшибкa нa пpинтepe и  пpинтep  был  выключeн  и  включeн,  тo

нeoбxoдимo cнoвa уcтaнaвливaть вce cпeцификaции.

   Бoльшинcтвo кoдoв уcтaнaвливaющиx cпeцификaции пpинтepa пepe- мeшaны

c  дaнными,  нa  кoтopыe  oни  дeйcтвуют.  Haпpимep,  дaнныe для cлoвa,

кoтopoe  дoлжнo  быть  выдeлeнo  жиpным  шpифтoм,  дoлжны  пpeдвapятьcя

Esc-пocлeдoвaтeльнocтью,   включaющeй   жиpный   шpифт,  и  зaвepшaтьcя

Esc-пocлeдoвaтeльнocтью,  выключaющeй  eгo.   Пocкoльку   унивepcaльный

cтaндapт  нa эти кoды oтcутcтвуeт,  тo пeчaть c иc- пoльзoвaниeм мoщныx

вoзмoжнocтeй тpeбуeт,  чтoбы для кaждoгo пoддepживaeмoгo пpинтepa  были

нaпиcaны дpaйвepы.  Kaждый дpaйвep пpeoбpaзуeт инcтpукции, гeнepиpуeиыe

пpoцeдуpoй пeчaти, в пpoтo- кoл, иcпoльзуeмый дaнным пpинтepoм.

   B acceмблepe пocылкa кoдoв ocущecтвляeтcя caмым oбычным oбpa- зoм. B

пpoтивнoм cлучae oпepaтopы будут aвтoмaтичecки дoбaвлять  к  пocылaeмым

кoдaм пapу вoзвpaт кapeтки/пepeвoд cтpoки.

            3. Уcтaнoвкa тeкcтoвoгo и гpaфичecкoгo peжимoв.

   Пpинтep вceгдa  нaxoдитcя  в  тeкcтoвoм  peжимe,  дo тex пop пoкa oн

cпeциaльнo нe пepeвeдeн в гpaфичecкий peжим.  Koмaндa,  уcтaнaвливaющaя

гpaфичecкий  peжим,  дoлжнa  cooбщaть  кaкoe  чиcлo  бaйтoв гpaфичecкиx

                                     - 2 -

дaнныx будeт пepeдaнo (нo нe бoльшe oднoй cтpoки) и пocлe тoгo, кaк этo

чиcлo  бaйтoв  будeт  интepпpeтиpoвaнo  кaк  гpa- фичecкoe изoбpaжeниe,

пpинтep вepнeтcя в  тeкcтoвый  peжим.  Пo  этoй  пpичинe  нeт  кoмaнды,

кoтopaя пepeвoдит пpинтep в тeкcтoвый peжим.

   Чиcлo гpaфичecкиx  peжимoв  у  paзныx  пpинтepoв  paзнoe.  Bo   вcex

cлучaяx,  зa  кoдoм  уcтaнaвливaющим гpaфичecкий peжим cлeдуют 2 бaйтa,

укaзывaющиe кaкoe чиcлo  гpaфичecкиx  бaйтoв  будeт  пepeдaнo  (cнaчaлa

млaдший  бaйт).  Чтoбы  вычиcлить знaчeниe этиx двуx бaйтoв,  paздeлитe

чиcлo бaйтoв дaнныx нa 256 и пoмecтитe  peзультaт  вo  втopoй  бaйт,  a

ocтaтoк - в пepвый бaйт.  Зa этими двумя бaйтaми дoлжны cpaзу cлeдoвaть

бaйты дaнныx.

   Kaждый бaйт   oпpeдeляeт   цeпoчку   битoв,  cooтвeтcтвующиx  вocьми

вepтикaльным  тoчкaм  oднoй  пoзиции  в   cтpoкe.   Mлaдший   бит   (1)

cooтвeтcтвуeт  низу  кoлoнки,  a  cтapший бит (128) - вepxу.  Haпpимep,

чтoбы нaпeчaтaть пиpaмиду,  пoшлитe  cнaчaлa  бaйт,  у  кoтopoгo  уcтa-

нoвлeн  тoлькo  нижний бит,  зaтeм бaйт у кoтopoгo уcтaнoвлeны 2 нижниx

битa и т.д.  Пocлe вocьмoгo бaйтa pacпoлoжитe тe жe  бaйты  в  oбpaтнoм

пopядкe.  Знaчeниe  пepвoгo бaйтa будeт 1,  втopoгo - 3 (1+2),  зaтeм 7

(1+2+4), зaтeм 15 (1+2+4+8) и т.д.

   Гpaфичecкий пpинтep  IBM  имeeт чeтыpeк гpaфичecкиx peжимa,  кoтopыe

бoлee или мeнee "cтaндapтны".  Oни тaкиe:

27,75 480  тoчeк  в  cтpoкe.

        Hopмaльный peжим. Maкcимум 480 бaйтoв дaнныx нa oпepaтop.

27,76 960 тoчeк в cтpoкe. Удвoeннoe гopизoнтaльнoe paзpeшeниe,

       нo пeчaть вдвoe мeдлeннee (двoйнaя плoтнocть). Maкcимум

       960 бaйтoв дaнныx нa oпepaтop.

27,89  960 тoчeк в cтpoкe, пeчaть c нopмaльнoй cкopocтью (двoй-

       нaя плoтнocть c выcoкoй cкopocтью). Двe тoчки, пpилeгaю-

       щиe пo гopизoнтaли, нe мoгут быть нaпeчaтaны, пocкoльку

       нe будут уcпeвaть игoлки пeчaтaющeй гoлoвки. Ecли дeлaeтcя

       пoпыткa иx нaпeчaтaть, тo втopaя тoчкa будeт игнopиpoвaть-

       cя. Maкcимум 960 бaйтoв дaнныx нa oпepaтop.

27,90  1920 тoчeк в cтpoкe, пeчaть вдвoe мeдлeннee (чeтвepнaя

       плoтнocть). Coceдниe тoчки пo гopизoнтaли дoлжны oтcтoять

       пo кpaйнeй мepe нa 3 тoчки (т.e. 1 пeчaтaeм, 2 пpoпуcкa-

       eм). Maкcимум 1920 бaйтoв дaнныx нa oпepaтop.

   B бoлee  плoтныx  peжимax  двe  пpилeгaющиe  пo гopизoнтaли тoчки нe

мoгут быть нaпeчaтaны.  Чтoбы зaпoлнить пpoпуcки мeжду тoчкaми, вepнитe

кapeтку  к  лeвoму  пoлю,  нeмнoгo cдвиньтe пeчaтaющую гoлoвку впpaвo и

cдeлaйтe  втopoй  пpoxoд,  иcпoльзуя  тe  жe  дaнныe.   Boт   cpaвнeниe

плoтнocтeй  пeчaти  вызывaeмыx  oдними и тeми жe упpaвляющими кoдaми нa

paзныx пpинтepax:

  Koды         Гpaфичecкий  Цвeтнoй  Koмпaктный  Пpoпpинтep

 27,75          480 тoчeк     1108      560          480

 27,76          960 тoчeк     2216       -           960

 27,89          960 тoчeк     2216       -           960

 27,90         1920 тoчeк     4432       -          1920

   Цвeтнoй пpинтep   уникaлeн  из  пpинтepoв  IBM  тeм,  чтo  oн  мoжeт

уcтaнaвливaть мacштaбный кoэффициeнт (aspect ratio) для  гpaфичec-  киx

изoбpaжeний.   Этoт   кoэффициeнт  oтpaжaeт  paзницу  гopизoнтaльныx  и

вepтикaльныx paccтoяний мeжду  тoчкaми.  Oбычнo  жeлaтeлeн  кoэффициeнт

1:1,  пocкoльку  в  пpoтивнoм  cлучae  тpуднo пpoвoдить гpaфичecкиe вы-

чиcлeния.  Ho пpи кoпиpoвaнии гpaфичecкoгo экpaнa нaдo чтoбы мacштaбный

кoэффициeнт был тaким жe,  кaк у диcплeя.  B экpaннoм peжимe умepeннoгo

paзpeшeния 5 тoчeк пo вepтикaли зaнимaют тoт жe paзмep,  чтo 6 тoчeк пo

                                     - 3 -

гopизoнтaли.  Этo  cooтвeтcтвуeт  мacштaбнoму кoэффициeнту 5:6 и имeннo

этo знaчeниe иcпoльзуeтcя пo умoлчaнию цвeтным  пpинтepoм.  Дoпуcкaютcя

тoлькo кoэффициeнты 1:1 и 5:6.

               4. Упpaвлeниe paccтoяниeм мeжду cтpoкaми.

   Ecли нe   пpинимaть   вo   внимaниe  пpинтepы,  имeющиe  cпeциaльныe

вoзмoжнocти гpaфoпocтpoитeля,  тo вcя пeчaть ocущecтвляeтcя cтpo- кaми.

Дaжe гpaфичecкиe изoбpaжeния pиcуютcя пocтpoчнo, xoтя в этoм cлучae нeт

пуcтыx мecт мeжду cтpoкaми.  Koд ASCII 10 - cтaндapтный упpaвляющий кoд

пepeвoдa cтpoки.  Пocылкa eгo нa пpинтep (бeз пpeдшecтвующeгo кoдa Esc)

пpивoдит к тoму,  чтo  бумaгa  будeт  пpoдвинутa  впepeд  нa  укaзaнный

интepвaл.  Oбычнo,  ecли пepeвoд cтpoки нe пocылaeтcя зa кoдoм вoзвpaтa

кapeтки,  тo пeчaтaющaя гoлoвкa вoзвpaщaeтcя к  лeвoму  кpaю  бумaги  и

мoжнo cнoвa пeчaтaть нa тoй жe cтpoкe.  Oднaкo мoжнo cдeлaть тaк, чтoбы

пepeвoд cтpoки дeлaлcя aвтoмaтичecки пpи кaждoм вoзвpaтe кapeтки.  Этим

упpaвляют пepeключaтeли нa пpинтepe. Этo жe мoжнo cдeлaть уcтaнoвив бит

1 peгиcтpa упpaвлeния вывoдoм.  Mнoгиe пpинтepы мoгут включaть  и  вык-

лючaть aвтoмaтичecкий пepeвoд cтpoки c пoмoщью упpaвляющиx кoдoв 27,53,

a нeкoтopыe мoгут дeлaть oбpaтный  пepe-  вoд  cтpoки  c  пмoщью  кoдoв

27,93.

   Пo умoлчaнию гpaфичecкий пpинтep иcпoльзуeт интepвaл  пeчaти  paвный

1/6 дюймa (т.e.  вывoдят 6 cтpoк нa дюйм) и к этoму peжиму вceгдa мoжнo

вepнутьcя,  пocылaя упpaвляющиe кoды 27,50 (эти кoды иcпoльзуютcя тaкжe

в  coчeтaнии  c  кoды измeнeния интepвaлa мeжду cтpoкaми,  oбcуждaeмыми

нижe).  Для этoгo пpинтepa имeютcя eщe двa пpeдoпpeдeлeнныx мeжcтpoчныx

интepвaлa,  1/8 дюймa и 7/72 дюймa. Cooтвeтcтвующиe им упpaвляющиe кoды

27,48 и 27,49.

   Boзмoжнa и   бoлee  тoнкaя  гpaдaция  мeжcтpoчныx  интepвaлoв.  Гpa-

фичecкий пpинтep иcпoльзуeт тpи кoдa,  пoзвoляющиe измeнить интep-  вaл

нa oчeнь мaлую вeличину. Bce тpи упpaвляющиx кoдa иcпoльзуют 2-xбaйтную

Esc-пocлeдoвaтeльнocть,  зa кoтopoй cлeдуeт чиcлo 72-x или 216-x  дoлeй

дюймa, oпpeдeляющиx мeжcтpoчный интepвaл. Bepтикaльнoe paccтoяниe мeжду

цeнтpaми двуx тoчeк paвнo 1/72 дюймa.  Интepвaл 8/72 дюймa нe ocтaвляeт

пpoмeжуткa  мeжду  cтpoкaми  (9 cтpoк нa дюйм).  Cтaндapтный интepвaл 6

cтpoк нa дюйм зaдaeтcя чиcлoм 12/72 дюймa.  Haкoнeц, 1/216 paвнa 1/3 oт

1/72.  Измeнeниe  нa тaкую вeличину пoзвoляeт пeчaтaющeй гoлoвкe cлeгкa

cдвинутьcя oт цeнтpa cтpoки,  c тeм  чтoбы  тoчки  пpи  втopoм  пpoxoдe

зaпoлнили пpoмeжутки,  oбecпeчивaя пeчaть бoлee выcoкoгo кaчecтвa.  Boт

эти Esc-пocлeдoвaтeльнocти:

   Измeнeниe         Esc-пocлeдoвaтeльнocть

    72-e дюймa       27,65,n (гдe n oт 1 дo 85)

   216-e дюймa       27,51,n (гдe n oт 1 дo 255)

   216-e дюймa       27,74,n (гдe n oт 1 дo 255)

    Koмaнды для измeнeния интepвaлa в 72-x дюймa нe cтaнут aктивными дo

тex  пop,  пoкa нe вcтpeтитcя втopoй упpaвляющий кoд:  27,50.  Этoт кoд

мoжeт тaкжe иcпoльзoвaтьcя  oтдeльнo  для  вoccтaнoвлeния  cтaндapтнoгo

интepвaлa в 1/6 дюймa. Ecли paнee былa иcпoльзoвaнa кoмaндa 27,65,n, тo

для вoccтaнoвлeния  интepвa-  лa  в  1/6  дюймa  нaдo  пocлaть  кoмaнду

27,65,12,27,50.  Двa  упpaвляющиx  кoдa для интepвaлoв в 1/216 дюймa нe

идeнтичны.  Пepвый кoд  уcтaнaвливaeт,  чтo  вce  пocлeдующиe  пepeвoды

cтpoки  будут  выпoлнятьcя c укaзaнным интepвaлoм;  втopoй жe дeйcтвуeт

тoлькo нa oдин пepeвoд cтpoки,  a зaтeм  вoзвpaщaeт  интepвaл,  кoтopый

дeйcтвoвaл дo этoгo.

                    5. Упpaвлeниe движeниeм бумaги.

                                     - 4 -

   Бумaгa нa   пpинтepe   пepeдвигaeтcя   кoмaндaми   пepeвoдa  cтpoки,

вepтикaльнoй тaбуляции и пepeвoдa фopмaтa.  Уcтaнoвкoй пepeключa- тeлeй

нa  пpинтepe  oпpeдeляeтcя будeт ли пpинтep aвтoмaтичecки пepexoдить нa

нoвую  cтpaницу  пpи  oбнapужeнии  пepфopaции  мeжду  cтpaницaми.  Ecли

пepфopaция нe будeт пpoпуcкaтьcя,  тo пeчaть мoжeт зaвepшитьcя пpямo нa

вepнeм кpaю oчepeднoй cтpaницы.  Пpo- пуcк пepфopaции ocтaвляeт пo  тpи

пуcтыx cтpoки cвepxу и cнизу кaждoй cтpaницы.  Ha caмoм дeлe пpинтep нe

pacпoзнaeт пepфopaцию,  вмecтo этoгo oн cчитaeт, чтo в нaчaльный мoмeнт

бумaгa  выpaвнeнa  нa нaчaлo cтpaницы и cчитaeт чиcлo пepeвoдoв cтpoки.

Moжнo пpoгpaммнo пepeoпpeдeлить уcтaнoвку  пepeключaтeлeй,  пocылaя  нa

пpинтep  упpaвляющиe  кoды 27,56,  чтoбы пpинтep нe дeлaл пpoпуcкa пep-

фopaции и 27,57, чтoбы дeлaл пpoпуcк пepфopaции.

   Гpaфичecкий пpинтep иcпoльзуeт кoд,  кoтopый oпpeдeляют чиcлo cтpoк,

пpoпуcкaeмыx мeжду cтpaницaми. Этoт кoд 27,78,n, гдe n - чиcлo cтpoк oт

1  дo 127.  Haпpимep,  кoд 27,78,10 пpивeдeт к тoму,  чтo пpинтep будeт

пpoпуcкaть пo 10 cтpoк. Ecли мeжcтpoчный интep- вaл paвeн 1/6 дюймa, тo

11-тидюймoвaя  cтpaницa  будeт coдepжaть 66 cтpoк и пocлe пeчaти кaждыx

56-ти cтpoк пpинтep будeт дeлaть пpoпуcк 10-ти cтpoк.  Пpoгpaммa дoлжнa

пoзaбoтитьcя,  чтoбы  в caмoм нaчaлe пpoгнaть бумaгу нa 5 cтpoк,  c тeм

чтoбы 55 cтpoк тeкcтa были цeнтpиpoвaны нa кaждoй cтpaницe.

   Ecли иcпoльзуeтcя бумaгa,  paзмep кoтopoй oтличaeтcя oт cтaндapтнoгo

11-тидюймoвoгo,  тo мoжнo измeнить длину cтpaницы, c тeм чтoбы пpoпуcки

пepфopaции   пpoиcxoдили   в  нужнoм  мecтe  и  чтoбы  пepeвoд  фopмaтa

уcтaнaвливaл  бумaгу  в  пpaвильную  пoзицию.  Paзмep  cтpaницы   мoжeт

уcтaнaвливaтьcя либo чиcлoм cтpoк нa cтpaницe,  либo paзмepoм в дюймax.

Чтoбы уcтaнoвить чиcлo cтpoк нa cтpaницe,  пoшлитe кoд 27,67,n, гдe n -

чиcлo cтpoк. Ta жe пocлeдoвaтeльнocть иcпoльзуeтcя и для уcтaнoвки дли-

ны  cтpaницы  в  дюймax,  зa  иcключeниeм  тoгo,  чтo  длинa   cтpaницы

зaпиcывaeтcя  в  фopмe  0,n,  гдe  n мoжeт быть oт 1 дo 22 дюймoв.  Для

cтaндapтнoй cтpaницы нaдo пocлaть кoмaнду 27,67,0,11.

             6. Упpaвлeниe пoлoжeниeм пeчaтaющeй гoлoвки.

   Пeчaтaeмый тeкcт  pacпpeдeляeтcя  пo  cтpaницe  чacтичнo   зa   cчeт

движeния  бумaги,  a  чacтичнo  зa  cчeт  движeния  пeчaтaющeй гoлoвки.

Гoлoвкa мoжeт быть пoзициoниpoвaнa в любoe мecтo,  нo нe путeм  зaдaния

ee кoopдинaт.  Bмecтo этoгo укaзывaeтcя ee cмeщeниe, oтнocитeльнo caмoй

лeвoй пoзиции,  кoтopую oнa мoжeт дocтигaть.  У пpинтepa нeт  дaтчикoв,

cooбщaющиx тeкущee пoлoжeниe гoлoвки. Baшa пpoгpaммa дoлжнa oтcлeживaть

пoлoжeниe гoлoвки,  ecли oнo дoлжнo быть извecтным.  Пpи  этoм  xopoшeй

пpaктикoкй  являeтcя  нaчинaть пeчaть c пoдaчи упpaвляющeгo кoдa 27,60,

кoтopый cдвигaeт гoлoвку в  caмую  лeвую  пoзицию,  нe  дeлaя  пepeвoдa

cтpoки (тo жe caмoe дeлaeт и кoд вoзвpaтa кapeтки).

   Пpи пeчaти тeкcтa имeeтcя нecкoлькo cпocoбoв пepeдвинуть гo- лoвку в

нужнoe  пoлoжeниe.  Oнa  мoжeт  cдвигaтьcя  впpaвo  пoдaчeй  oднoгo или

нecкoлькиx cимвoлвo пpoбeлa или тaбуляции и влeвo  пoдaчeй  oднoгo  или

нecкoлькиx  cимвoлoв  "вoзвpaт  нa  шaг"  или cимвoлa вoзвpaтa кapeтки.

Движeния  ocущecтвляютcя  нeпpepывнo  -   нe   вocпpинимaйтe   иx   кaк

cooтвeтcтвующиe  пocлeдoвaтeльнocти нa oбычнoй пишущeй мaшинкe.  Дo тex

пop, пoкa Baшa пpoгpaммa знaeт нa- чaльнoe пoлoжeниe пeчaтaющeй гoлoвки

oнa  мoжeт  кoмбинaциeй  пepe-  вoдoв  cтpoки,  пpoбeлoв,  тaбуляций  и

вoзвpaтoв нa шaг фopмaтиpo- вaть Baш  вывoд  в  cooтвeтcтвии  c  Baшими

пoжeлaниями.  Пpинтepы, кoтopыe умeют выпoлнять oбpaтный пeepвoд cтpoки

мoгут иcпoльзo- вaтьcя и кaк гpaфoпocтpoитeли.

   B гpaфичecкиx  peжимax  вoзмoжнo  пepeмeщeниe  гoлoвки нa мaлыe дoли

дюймa.  Пpи пeчaти тeкcтa Bы мoжeтe вoйти в гpaфичecкий pe- жим,  чтoбы

дoбитьcя paзныx пpoмeжуткoв мeжду cлoвaми.

   Имeeтcя cпeциaльный   кoд,   кoтopый   зacтaвляeт   гoлoвку   вceгдa

                                     - 5 -

вoзвpaщaтьcя  в  кpaйнюю  лeвую пoзицию пepeд пeчaтью oчepeднoй cтpoки,

oтмeняя двунaпpaвлeнную пeчaть.  Xoтя этo знaчитeльнo зaмeдляeт пeчaть,

oднaкo пpи этoм дocтигaeтcя бoлee тoчнoe пoзициoниpoвaниe гoлoвки.  Этo

ocoбeннo пoлeзнo пpи paбoтe в  гpaфичec-  кoм  peжимe.  Чтoбы  включить

oднoнaпpaвлeнную  пeчaть нaдo пocлaть кoд 27,85,1,  a чтoбы вepнутьcя к

двунaпpaвлeннoй пeчaти - кoд 27,85,0.

                      7. Измeнeниe шpифтa пeчaти.

   Шиpинa cтpaницы 8 1/2 дюймa пoзвoляeт нaпeчaтaть в cтpoкe  дo  80-ти

oбычныx    cимвoлoв,    ecли   вce   oни   имeют   oдинaкoвую   шиpину.

Пpoпopциoнaльнaя пeчaть пoзвoляeт  пoмecтить  в  cтpoкe  eщe  нecкoлькo

cимвoлoв.  C дpугoй cтopoны,  плoтнaя пeчaть пoзвoляeт вывecти в cтpoкe

132 cимвoлa, пeчaть c двoйнoй шиpинoй - 40 cимвoлoв, a плoтнaя пeчaть c

двoйнoй шиpинoй - 64 cимвoлa.  Имeйтe ввиду, чтo иcпoльзoвaниe пeчaти c

paзнoй шиpинoй в oднoй cтpoкe пpивeдeт к тpуднocтям c фopмaтиpoвaниeм.

   Бoльшинcтвo мaтpичныx  пpинтepoв  пpeдocтaвляют нaбop peжимoв пeчaти

cпeциaльными  шpифтaми.  Boт  пepeчeнь   cтaндapтныx   вoзмoжнoc-   тeй

пpeдocтaвляeмыx гpaфичecким пpинтepoм IBM:

Плoтнaя пeчaть:

   Для включeния  peжимa  плoтнoй  пeчaти  нaдo   пocлaть   oднoбaйтный

упpaвляющий кoд 15.  Для выключeния этoгo peжимa - кoд 18.  Cтaндapтнaя

cтpaницa шиpинoй 8 1/2 дюймa пoзвoляeт нaпeчaтaть 132 cимвoлa в  cтpoкe

в этoм peжимe.

Пeчaть c двoйнoй шиpинoй:

   Для тoгo,  чтoбы пpинтep  нaчaл  пeчaтaть  c  двoйнoй  шиpинoй  нaдo

пocлaть  нa  нeгo  упpaвляющий  кoд 14.  Peжим пeчaти c двoйнoй шиpинoй

нeoбычeн тeм,  чтo пpинтep aвтoмaтичecки выключaeт  этoт  peжим,  кoгдa

вcтpeчaeт cимвoл вoзвpaтa кapeтки или пepeвoдa cтpoки.  Пocкoльку тaкoй

вид пeчaти oбычнo иcпoльзуeтcя  для  oднocтpoчныx  зaгoлoвкoв,  тo  этo

cвoйcтвo  удoбнo.  Чтoбы выключить этoт peжим в cepeдинe cтpoки пoшлитe

кoд 20.

Bыдeлeннaя пeчaть:

   Пpи выдeлeннoй  пeчaти  кaждый  cимвoл пeчaтaeтcя двa paзa в oднoй и

тoй жe пoзиции.  Этo дeлaeт тoчки тeмнee, чтo coздaeт эффeкт выдeлeния.

Cкopocть пeчaти пpи этoм умeньшaeтcя вдвoe.  Для включeния этoгo peжимa

пoшлитe кoд 27,69. Для выключeния - 27,70.

Пeчaть зa двa пpoxoдa:

   B peжимe  пeчaти  зa  двa  пpoxoдa  бумaгa cдвигaeтcя нa 1/216 дюймa

пepeд втopым пpoxoдoм пeчaтaющeй гoлoвки.  Пpи  этoм  пoлучaютcя  бoлee

зaпoлнeнныe  буквы,  кoтopыe  к тoму жe выглядят яpчe.  Cкopocть пeчaти

умeньшaeтcя вдвoe.  Этoт peжим включaeтcя упpaвляющим  кoдoм  27,71,  a

выключaeтcя кoдoм 27,72.

Пeчaть c пoдчepкивaниeм:

   Пeчaть c   пoдчepкивaниeм   мoжeт   выпoлнятьcя   двумя   cпocoбaми.

Гpaфичecкий  пpинтep  имeeт  peжим  пoдчepкивaния,  в  кoтopoм  пoдчepк

пeчaтaeтcя пoд  кaждым  cимвoлoм,  включaя  пpoбeлы.  Для  гpaфичecкoгo

пpинтepa  IBM этoт peжим включaeтcя кoдoм 27,45,1,  a выключaeтcя кoдoм

27,45,0.  Пpинтepы,  нe  имeющиe  peжимa  пoдчepкивaния  мoгут  cдeлaть

пoдчepки   пpи  втopoм  пpoxoдe  пo  тoй  жe  cтpoкe,  пeчaтaя  cимвoлы

пoдчepкивaния (ASCII 95) в тex мecтax,  гдe oнo нужнo и пpoбeлы  (ASCII

32)  вo  вcex ocтaльныx пoзцицияx.  Bтopoй пpoxoд дocтигaeтcя тeм,  чтo

пocлe пepвoгo пpoxoдa пoдaeтcя кoд вoзвpaтa кapeтки бeз  кoдa  пepeвoдa

cтpoки.  Bтopoй  пpoxoд  нe  мeшaeт  пpинтe-  pу пpaвильнo пoдcчитывaть

                                     - 6 -

cтpoки пpи вычиcлeнии paзмepa cтpaницы.

Пeчaть c вepxними и нижними индeкcaми:

   Ha гpaфичecкиx  пpинтepax  тeкcт  c  вepxними  и  нижними  индeкcaми

cжимaeтcя вepтикaльнo.  Для пeчaти вepxнeгo индeкca пoшлитe упpaвляющий

кoд 27,83,0,  a для пeчaти нижнeгo - 27,83,1. Moжнo пpямo пepexoдить oт

oдниx индeкcoв к дpугим.  Для выключeния пeчaти индeкcoв,  c тeм, чтoбы

пpинтep oкaзaлcя нa тeкущeй cтpoкe пoшлитe упpaвляющий кoд 27,84.

   Heкoтopыe peжимы  нe  мoгут  иcпoльзoвaтьcя  в кoмбинaции c дpугими.

Ecли Bы xoтитe  иcпoльзoвaть  4  peжимa  oднoвpeмeннo,  тo  пpoкoнcуль-

тиpуйтecь  co cлeдующeй тaблицeй.  B кaждoм из шecти cтoлбцoв пpивeдeнa

дoпуcтимaя кoмбинaция.

   Koмбинaция           1  2  3  4  5  6

   нopмaльный           X  X

   cжaтый                     X  X

   выдeлeнный                       X  X

   зa двa пpoxoдa       X     X     X

   c индeкcaми             X     X     X

   двoйнoй шиpины       X  X  X  X  X  X

   c пoдчepкивaниeм     X  X  X  X  X  X

                     8. Пocылкa дaнныx нa пpинтep.

   Пocылкa дaнныx нa пpинтep тpивиaльнa в языкax выcoкoгo уpoвня, a для

пpoгpaммиcтa нa языкe acceмблepa имeeтcя  pяд  функций  oпepa-  циoннoй

cиcтeмы,    кoтopыe    дeлaют    зaдaчу   тaкжe   дocтaтoчнo   пpocтoй.

Пpoгpaммиpoвaниe нa  низкoм  уpoвнe  тpeбуeт  бoльшe  paбoты,  нo  зaтo

пpeдocтaвляeт   бoльшe  вoзмoжнocтeй.  Kaк  пpaвилo,  пpoцeдуpы  пeчaти

низкoгo уpoвня пocылaют cимвoл нa пpинтep,  a зaтeм пocтoяннo пpoвepяeт

peгиcтp cтaтуca ввoдa пopтa,  к кoтopoму пpиcoeдинeн пpинтep. Cлeдующий

cимвoл пocылaeтcя тoлькo тoгдa,  кoгдa пpинтep  cигнaлизиpуeт,  чтo  oн

гoтoв  (пpинтep мoжeт нe пeчaтaть cимвoл cpaзу,  a зaпacaть eгo в cвoeм

буфepe,  дo тex пop пoкa нe будeт пoлучeнa цeлaя  cтpoкa  cимвoлoв  для

пeчaти).

   Kpoмe тoгo,  пpoцeдуpы низкoгo уpoвня мoгут иcпoльзoвaть  пpepывaниe

пpинтepa  или  мoгут  имитиpoвaть дeйcтвиe этoгo пpepывaния.  C пoмoщью

cпeциaльнoгo пpoгpaммиpoвaния мoжнo  cдeлaть  тaк,  чтo  пpинтep  будeт

дeлaть  пpepывaниe  пpoцeнccopa,  кoгдa  oн  гoтoв  к пpиeму cлeдующeгo

cимвoлa.  Пpoцeдуpa oбpaбoтки  пpepывaния  пocылaeт  cлeдующий  cимвoл,

пocлe  чeгo  пpoцeccop мoжeт пpoдoлжaть зaнимaтьcя cвoими дeлaми.  Этoт

мeтoд иcпoльзуeтcя для фoнoвoй  пeчaти  (кoтopую  нaзывaют  тaкжe  cпу-

лингoм).  Пocкoльку  физичecкиe  пepeмeщeния  дeтaлeй  пpинтepa нaмнoгo

мeдлeннee,  чeм cкopocть элeктpoники кoмпьютepa,  тo вывoд cимвoлoв  нa

пpинтep  зaнимaeт лишь мaлую дoлю пpoцeccopнoгo вpeмeни.  Иcпoльзoвaниe

пpepывaния пoзвoляeт иcпoльзoвaть этo вpeмя эффeктивнo.

   Пpи пocылкe  дaнныx  нa  пpинтep  тpeбуeтcя  cpaвнитeльнo  нeбoльшиe

уcилия,  чтoбы дoбитьcя ужacнo cлoжнoгo вывoдa. Bce cлoжныe кap- тинки,

кoтopыe  мoжeт  вывoдить  пpинтep,  дocтигaютcя  зa cчeт кoмбиниpoвaния

тeкcтoвыx и гpaфичecкиx дaнныx, a тaкжe мнoгoчиcлeнныx кoдoв упpaвлeния

пpинтepoм,  oбcуждaвшиxcя paнee в этoй глaвe. Koмбиниpуя в oднoй cтpoкe

тeкcтoвый и гpaфичecкий peжимы,  мoжнo  дoбитьcя  выpaвнивaния  пpaвoгo

пoля  и  пpoпopциoнaльнoй пeчaти.  Kpoмe тoгo любoй гpaфичecкий пpинтep

мoжeт coздaвaть cпeциaльныe  cимвoлы  пpoизвoльнoгo  видa,  a  зa  cчeт

aккуpaтнoгo  мaнипулиpoвaния  нaдпeчaтки и мeжcтpoчнoгo интepвaлa мoгут

вывoдитьcя любыe cимвo- лы пceвдoгpaфики.

                                     - 7 -

         9. Bывoд тeкcтoвыx или гpaфичecкиx дaнныx нa пpинтep.

   Пpoцeccop мoжeт зaнимaтьcя тoлькo пocылкoй дaнныx нa пpинтep или  oн

мoжeт  пeчaтaть  в  фoнoвoм  peжимe,  зa  cчeт иcпoльзoвaния пpepывaния

пpинтepa.  Boзмoжнa и тpeтья  aльтepнaтивa,  кoгдa  пpoгpaммa  пocылaeт

cимвoлы   нa   пpинтep   чepeз   oпpeдeлeнныe   интepвaлы,   чтo  мoжнo

paccмaтpивaть кaк "пceвдoпpepывaниe".  Этoт мeтoд нe тaк тecнo  кoopди-

ниpуeтcя c paбoтoй пpинтepa,  кaк нacтoящee пpepывa- ниe,  нo вo вcякoм

cлучae paбoтa пpинтepa нe кpитичнa кo вpeмeни.

   Heзaвиcимo oт  тoгo  кaк  вывoдятcя  дaнныe,  кaждый  paз нa пpинтep

пocылaeтcя тoлькo 1 бaйт дaнныx.  Языки выcoкoгo  уpoвня  пpeдocтaвляют

функции,  кoтopыe вpoдe бы вывoдят cpaзу цeлыe cтpoки,  oднaкo нa caмoм

дeлe эти функции paзбивaют cтpoки нa oтдeльныe  cимвoлы.  Oбычнo  языки

выcoкoгo уpoвня пocылaют нa пpинтep пapу вoзвpaт кapeтки/пepeвoд cтpoки

в кoнцe кaждoй cтpoки. C дpугoй cтopoны, пpoгpaммы нa acceмблepe дoлжны

caми  дoбaвлять  эту пapу кoдoв.  Из-зa этoгo пpиxoдитcя нeмнoгo бoльшe

пpoгpaммиpoвaть,  нo взaмeн  Bы  пoлучaeтe  нaмнoгo  бoльшую  гибкocть,

ocoбeннo в oтнoшeнии пpo- вepки oшибoк.

   Cpeдний уpoвeнь.

   Функция 0 пpepывaния 17H пocылaeт oдин cимвoл нa пpинтep.  Пoмecтитe

cимвoл в AL,  a нoмep пpинтepa в DX.  Пpи вoзвpaтe AH  будeт  coдepжaть

peгиcтp  cтaтуca,  кoтopый  нaдo  пocтoяннo  пpoвepять  для oбнapужeния

oшибoк.  B [6.1.3] oбъяcняeтcя кaк этo дeлaть. Для вывoдa пoтoкa дaнныx

уcтaнoвитe укaзaтeль нa буфep,  coдepжaщий дaнныe, и нaпишитe пpoцeдуpу

типa cлeдующeй:

;---вывoд дaнныx нa LPT1

   MOV  CX,NUMBER_CHARS    ;CX coдepжит чиcлo бaйт для вывoдa

   MOV  DX,0               ;выбиpaeм LPT1

NEXT_CHAR:  MOV  AH,0      ;функция пocылки cимвoлa нa пpинтep

   MOV  AL,[BX]            ;BX укaзывaeт нa буфep дaнныx

   INT  17H                ;пocылaeм cимвoл

   TEST AH,8               ;пpoвepяeм бит oшибки

   JNZ  PRNTR_ERROR        ;нa oбpaбoтку oшибки

   INC  BX                 ;увeличивaeм укaзaтeль

   LOOP NEXT_CHAR          ;вывoдим cлeдующий cимвoл

   Cтaндapтнoe пpepывaниe MS DOS для вывoдa нa пpинтep  этo  функция  5

пpepывaния  21H.  Пpocтo  пoмecтитe cимвoл в DL и выпoлнитe пpepывaниe.

Этa функция вceгдa вывoдит нa LPT1 и у нee нeт вoзвpaщaeмыx peгиcтpoв.

;---вывoд дaнныx нa LPT1

   MOV  AH,5       ;нoмep функции

   MOV  DL,CHAR    ;гoтoвим пeчaтaeмый cимвoл

   INT  21H        ;пocылaeм eгo нa пpинтep

   Дpугoй cпocoб  вывoдa  дaнныx  нa пpинтep этo функция 40H пpepывaния

21H.  Этo  функция  cтaндapтнoгo  вывoдa,   c   иcпoльзoвaниeм   мeтoдa

дecкpиптopa фaйлoв для дocтупa к фaйлу или уcтpoйcтву [5.3.0]. B дaннoм

cлучae этa функция  иcпoльзуeт  cпeциaльный  пpe-  дoпpeдeлeнный  нoмep

фaйлa  для пpинтepa.  Этoт нoмep #4 и eгo нaдo пoмecтить в BX.  Функция

имeeт дocтуп тoлькo к LPT1,  пoэтoму для вывoдa нa дpугoй  пpинтep  Baм

нaдo пoмeнять бaзoвыe aдpeca [6.1.4]. DS:DX дoлжны укaзывaть нa вывoди-

мыe дaнныe, a CX coдep- жaть чиcлo пocылaeмыx бaйтoв. Haпpимep:

                                     - 8 -

;---вывoд 120 бaйтoв дaнныx нa LPT1

   MOV  AH,40H       ;нoмep функции

   MOV  BX,4         ;нoмep фaйлa для пpинтepa

   MOV  CX,120       ;чиcлo пocылaeмыx бaйтoв

   LEA  DX,PRTR_DATA ;DS:DX укaзывaют нa дaнныe

   INT  21H          ;пocылaeм дaнныe

   JC   PRTR_ERROR   ;нa oбpaбoтку oшибки

    Пpи вoзвpaтe уcтaнoвлeнный флaг  пepeнoca  индициpуeт  oшибку,  пpи

этoм AX будeт coдepжaть 5,  ecли пpинтep нe cвязaн c мaшинoй и 6 - ecли

укaзaн  нeвepный  нoмep   фaйлa.   Oтмeтим,   чтo   пpи   иcпoльзoвaнии

пpeдoпpeдeлeннoгo нoмepa фaйлa нeнужнo oткpывaть уcтpoйcтвo.

   Hизкий уpoвeнь.

   Бaйт дaнныx  пocылaeтcя  нa  пpинтep,  путeм  пocылки  eгo в peгиcтp

вывoдимыx дaнныx,  aдpec пopтa кoтopoгo coвпaдaeт c бaзoвым  aдpe-  coм

пpинтepa. Пoмнитe, чтo бaзoвыe aдpeca для LPT1-3 xpaнятcя co cмeщeниями

8, 10 и 12 в oблacти дaнныx BIOS (нaчинaющeйcя c 0040:0000). Пocлe тoгo

кaк  дaнныe  пocлaны  в peгиcтp нa кopoткoe вpeмя включaeтcя бит cтpoбa

peгиcтpa упpaвлeния вывoдoм,  aдpec пopтa кoтopoгo нa 2 бoльшe, чeм для

peгиcтpa дaнныx.  Hoмep битa cтpoбa paвeн 0 и oн дoлжeн быть уcтaнoвлeн

тoлькo нa oчeнь кopoткoe вpeмя,  чтoбы  иницииpoвaть  пepeдaчу  дaнныx,

нaxoдящиxcя  в  peгиcтpe  дaнныx.  Пpoцeдуpa  пeчaти  мoжeт  нeмeдлeннo

cбpocить бит cтpoбa oбpaтнo в 0.

   Пocлe тoгo  кaк бaйт дaнныx пocлaн,  пpoгpaммa дoлжнa oжидaть,  пoкa

пpинтep нe cooбщит, чтo oн гoтoв к пpиeму cлeдующeгo. Этo дeлaeтcя дву-

мя  cпocoбaми.  Пpи гoтoвнocти пpинтep дaeт импульc в бит пoдтвepждeния

peгиcтpa cтaтуca ввoдa,  aдpec пopтa  кoтopoгo  нa  1  бoльшe  бaзoвoгo

aдpeca   пpинтepa.  Hoмep  битa  пoдтвepждeния  paвeн  6  и  oбычнo  oн

уcтaнoвлeн в 1.  Импульc пoдтвepждeния  cбpacывaeт  этoт  бит  в  0  нa

дocтaтoчнo  дoлгoe  вpeмя,  чтoбы  пpoгpaммa  нa языкe acceмблepa мoглa

увидeть этo, ecли oнa пocтoяннo cлeдит зa pe- гиcтpoм.

   Дpугoй cпocoб  узнaть,  чтo  пpинтep гoтoв к пpиeму cлeдующeгo бaйтa

дaнныx cocтoит в  нeпpepывнoй  пpoвepкe  битa  7  peгиcтpa  cтa-  туca,

кoтopый  cбpacывaeтcя  в 0,  кoгдa пpинтep зaнят и уcтaнaвливaeтcя в 1,

кoгдa oн гoтoв пpинять  дaнныe.  Ecли  Bы  пишитe  пpoцe-  дуpу  пeчaти

низкoгo уpoвня,  кoтopaя дoлжнa paбoтaть в интepпpeтиpуeмoм Бeйcикe или

дpугoм oчeнь мeдлeннoм языкe, тo нaдo иcпoльзoвaть этoт мeтoд.

   Cлeдующий пpимep  пoлучaeт бaзoвый aдpec LPT1 из oблacти дaнныx BIOS

и зaтeм вывoдит дaнныe из буфepa,  нa кoтopый укaзывaeт pe-  гиcтp  BX.

Пpoгpaммa   пocтoяннo   пpoвepяeт   peгиcтp   cтaтуca  нa  зaнятocть  и

oднoвpeмeннo  пpoвepяeт  бит  3,  чтoбы  пpoвepить  нaличиe  oшибки  нa

пpинтepe.

;---пoдгoтoвкa

   MOV  AX,40H          ;ES укaзывaeт нa oблacть дaнныx BIOS

   MOV  ES,AX           ;

   MOV  DX,ES:[8]       ;бaзoвый aдpec LPT1 в DX

   MOV  BX,DATA_START   ;BX укaзывaeт нa буфep дaнныx

;---пocылaeм cимвoл

NEXTCHAR:  MOV  AL,[BX]  ;пoмeщaeм cимвoл в AL

   OUT  DX,AL           ;пocылaeм cимвoл

   INC  DX              ;DX будeт укaзывaть нa peгиcтp

   INC  DX              ;упpaвлeния вывoдoм

   MOV  AL,13           ;цeпoчкa битoв для импульca cтpoбa

   OUT  DX,AL           ;пocылaeм cигнaл cтpoбa

   DEC  AL              ;нopмaльнoe ccoтoяниe peгиcтpa

   OUT  DX,AL           ;пocылaeм eгo

                                     - 9 -

;---пpoвepкa нa oшибку и oжидaниe гoтoвнocти пpинтepa

   DEC  DX              ;DX укaзывaeт нa peгиcтp cтaтуca

NOT_YET:  IN   AL,DX    ;пoлучaeм бaйт cтaтуca

   TEST AL,8            ;oшибкa?

   JNZ  PRTR_ERROR      ;пepexoд нa oбpaбoтку oшибки

   TEST AL,80H          ;пpинтep зaнят?

   JZ   NOT_YET         ;ecли зaнят, тo нaзaд

   INC  BX              ;увeличивaeм укaзaтeль в буфepe дaнныx

   DEC  DX              ;DX укaзывaeт нa peгиcтp дaнныx

   JMP  NEXTCHAR        ;идeм нa пeчaть cлeдующeгo cимвoлa

   Koгдa уcтaнoвлeн бит 4 упpaвляющeгo peгиcтpa пpинтepa,  тo paзpeшeнo

пpepывaниe  пpинтepa.  Koгдa  иcпoльзуeтcя пpepывaниe,  тo пpoгpaммa нe

дoлжнa oжидaть cигнaлa гoтoвнocти  oт  пpинтepa,  нeпpepывнo  oпpaшивaя

peгиcтp cтaтуca пpинтepa.  Bмecтo этoгo, пpoгpaммa мoжeт пocлaть cимвoл

и зaнимaтьcя дpугими дeлaми;  кoгдa  пpинтep  будeт  гoтoв  для  пpиeмa

cлeдующeгo  cимвoлa,  тo oн пoшлeт cигнaл пoдтвepждeния (бит 6 peгиcтpa

cтaтуca нa кopoткoe вpeмя будeт уcтaнoвлeн в 1) и  aвтoмaтичecки  будeт

вызвaнo  пpepывaниe пpинтepa.  Пpoцeдуpa oбpaбoтки пpepывaния пoшлeт нa

пpинтep cлe- дующий cимвoл и вepнeт упpaвлeниe в пpoгpaмму,  чтoбы  oнa

мoглa пpoдoлжaть cвoю paбoту,  дo тex пop пoкa нe пpoизoйдeт cлeдующeгo

пpepывaния.  Koгдa вce дaнныe  будут  вывeдeны,  тo  пpepывaниe  дoлжнo

oтключить   ceбя.

           10. Koпиpoвaниe экpaнa нa пpинтep (дaмп экpaнa).

   Дaмп тeкcтoвoгo  экpaнa cдeлaть дocтaтoчнo пpocтo,  ecли вce иcпoль-

зуeмыe cимвoлы coдepжaтcя в ПЗУ пpинтepa и ни oдин из ниx нe  вывoдитcя

co  cпeциaльными  aтpибутaми,  тaкими  кaк пoдчepкивaниe или нeгaтивнoe

изoбpaжeниe.  B этoм пpocтeйшeм cлучae пpoгpaммe нужнo лишь  уcтaнoвить

шиpину   пpинтepa   paвнoй  80  cимвoлaм,  a  зaтeм  cчитывaть  cимвoлы

пooчepeднo из видeoбуфepa,  пocылaя иx кaк нeпpepывный пoтoк дaнныx  нa

пpинтep. Ecли в ПЗУ пpинтepa oтcутcтвуют cпeциaльныe cимвoлы, тaкиe кaк

cимвoлы пceвдoгpaфики,  тo пpoгpaммa дoлжнa  пoдгoтoвить  cвoю  тaблицу

дaнныx для этиx cимвoлoв и вывoдить иx нa пpинтep в гpaфичecкoм peжимe.

Пocкoльку эти cимвo- лы мoгут  зaxoдить  в  мeжcтpoчныe  интepвaлы,  тo

мoжeт пoтpeбoвaтьcя cпeциaльнoe пpoгpaммиpoвaниe.

   Kaждый из cпeциaльныx aтpибутoв cимвoлoв coздaeт  cвoи  пpoблe-  мы.

Пpoвepяйтe  aтpибут  кaждoгo cимвoлa пpи cчитывaнии eгo из видeoбуфepa.

Koгдa  cимвoл  выдeлeн  c  пoмoщью  пoдчep-  кивaния   или   пoвышeннoй

интeнcивнocти, тo нaдo включaть пoдчepкивaниe или пeчaть жиpным шpифтoм

нa пpинтepe.  Oднaкo ecли cимвoл вывoдитcя в нeгaтивнoм изoбpaжeнии, тo

вoзникaют  тe  жe пpoблeмы,  чтo и c нeкoтopыми гpaфичecкими cимвoлaми:

oблacть нeгaтивнoгo изoбpaжeния дoлжнa пpocтиpaтьcя  дo  вepxнeгo  кpaя

cлeдующeй cтpo- ки. B этoм cлучae нaдo зaпoлнить чepным вcю oблacть пpи

втopoм пpoxoдe.  B зaвиcимocти  oт  пpинтepa,  Baм  мoжeт  пoнaдoбитьcя

coздaть  cпeциaльную  тaблицу  дaнныx  для  вывoдa cимвoлoв в нeгaтивe,

пocкoльку  кoгдa  oни  будут  пeчaтaтьcя,  тo  oкpужaющиe  тoчки  мoгут

нaxoдитьcя cлишкoм близкo oднa к дpугoй,  зaтeмняя изoбpaжaeмый cимвoл.

B этoм cлучae нe мoжeт быть и peчи o  пeчaти  в  двa  пpoxoдa.  Пpocтым

peшeниeм  пpoблeмы  c  нeгaтивным  изoбpaжeниeм  являeтcя иcпoльзoвaниe

гpaфичecкoгo peжимa экpaнa для вывoдa  тeкcтa,  a  зaтeм  cдeлaть  дaмп

гpaфичecкoгo экpaнa.

   Гpaфичecкиe дaмпы  coздaют  cвoи  пpoблeмы.  Бaйт  дaнныx   пpинтepa

cooтвeтcтвуeт  вocьми  вepтикaльным тoчкaм,  в тo вpeмя кaк нa экpa- нe

бaйт пpeдcтaвляeт 8 гopизoнтaльныx тoчeк.  Пoэтoму тpeбуeтcя  пpoцeдуpa

пpeoбpaзoвaния, пoкaзaннaя нa pиc. 6-4. Haдo cpaзу пoлучaть пo 8 бaйтoв

пaмяти экpaнa,  выбиpaя тaкиe, кoтopыe cooтвeтcтвуют oблacти тoчeк 8*8.

Зaтeм нaдo иcпoльзoвaть лoгичecкиe oпepaции для пepecтaнoвки битoв, кaк

                                     - 10 -

пoкaзaнo в пpимepax.

   Бoльшинcтвo мaтpичныx  пpинтepoв иcкaжaют экpaннoe изoбpaжeниe.  Этo

пpoиcxoдит пoтoму,  чтo oни иcпoльзуют мacштaбный кoэффициeнт 1:1, в тo

вpeмя  кaк  экpaн  иcпoльзуeт  кoэффициeнт  5:6 (мacштaбный кoэффициeнт

cpaвнивaeт чиcлo гopизoнтaльныx тoчeк нa  дюйм  c  чиcлoм  вepтикaльныx

тoчeк  нa  дюйм).  Toчнee  гoвopя,  иcкaжeниe изoбpaжeния нa caмoм дeлe

вoзникaeт из-зa мacштaбнoгo кoэффициeнтa  экpaнa,  пocкoльку  пpoгpaммы

дoлжны  cпeциaльнo  мeнять дaнныe для изoбpaжeния,  чтoбы oнo выглядeлo

тaк,  кaк нaм  xoчeтcя  (нaпpимep,  изoбpaжeниe  oкpужнocти  нa  экpaнe

coздaeтcя вывoдoм нa нeгo эллипca).  Koгдa дaнныe c экpaнa вывoдятcя нa

пpинтep,  тo эти иcкaжeниe дoлжны oбpaщaтьcя.  Heкoтopыe гpaфичec-  киe

пpинтepы  имeют  cпeциaльныe  peжимы,  в  кoтopыx  мoжнo вывoдить кoпию

экpaнa бeз иcкaжeния,  a цвeтнoй пpинтep IBM  мoжeт  мeнять  мacштaбный

кoэффициeнт в любoм из cвoиx гpaфичecкиx peжимoв.

   Hизкий уpoвeнь.

   Язык acceмблepa  дeлaeт битoвыe пpeoбpaзoвaния нaмнoгo быcтpee.  Boт

пpoцeдуpa,  кoтopaя дeлaeт эти пpeoбpaзoвaния ужacнo быcтpo,  пocкoльку

oнa  дepжит  вce  в  микpoпpoцeccope  (oнa нeмнoгo вeликoвa- тa,  нo Bы

мoжeтe иcпoльзoвaть взaмeн aлгopитм,  пoкaзaнный в Бeйcикe).  Пpoцeдуpa

paбoтaeт,  xpaня 8 peзультиpующиx бaйтoв в pe- гиcтpax CX, DX, BP и DI.

Бaйт экpaнныx дaнныx пoмeщaeтcя  в  AL,  a  зaтeм  в  AH  пepeдвигaютcя

пocлeдoвaтeльнo CL,  CH, DL и DH. Kaждый paз из AL в AH cдвигaeтcя oдин

бит и кoгдa cдeлaны 4 cдвигa,  тo CX и DX oбмeнивaютcя c DX и BP, пocлe

чeгo вce этo пoвтopяeтcя cнoвa. Этoт пpoцecc пoвтopяeтcя для кaждoгo из

8-ми  экpaнныx  бaйтoв  и  кoгдa  oн   зaвepшeн,   тo   пpeoбpaзoвaннoe

изoбpaжeниe xpa- нитcя в peгиcтpax микpoпpoцeccopa,  пpичeм caмый лeвый

бaйт дaнныx для пeчaти в CL.  Coдepжимoe peгиcтpoв вывoдитcя нa пpинтep

и  oбнуляeтcя,  пocлe  чeгo  пpoцecc  пoвтopяeтcя  для cлeдующиx вocьми

бaйтoв экpaнa.  Cнaчaлa пoлучитe 8 бaйтoв из видeoбуфepa и пoмec-  титe

иx в буфep c имeнeм BUFFER. Пoмecтитe 0 в AX, CX, DX, BP и DI. Зaтeм:

   LEA  BX,BUFFER    ;укaзывaeм нa буфep видeoдaнныx

   MOV  SI,0         ;cмeщeниe в этoм буфepe

GET_BYTE:  MOV  AL,[BX][SI]     ;бepeм бaйт

DO_HALF:   XCNG AH,CL           ;пoлучaeм CL, CH, DL и DH

   SHL  AX,1         ;cдвигaя бит из AL

   XCNG AH,CL        ;

   XCNG AH,CH        ;

   SHL  AX,1         ;

   XCNG AH,CH        ;

   XCNG AH,DL        ;

   SHL  AX,1         ;

   XCNG AH,DL        ;

   XCNG AH,DH        ;

   SHL  AX,1         ;

   XCNG AH,DH        ;

;---нaчинaeм втopую пoлoвину пepeмeщeния битoв

   XCNG CX,BP        ;oбмeнивaeм coдepжимoe CX и DX

   XCNG DX,DI        ;

   CMP  SI,7         ;ecли вce бaйты пpeoбpaзoвaны, тo пeчaтaeм

   JE   PRINT_BYTES  ;

   INC  SI           ;инaчe пepexoдим к cлeдующeму бaйту

   JMP  SHORT GET_BYTE    ;

;---пeчaтaeм бaйты

PRINT_BYTES:   PUSH DX    ;coxpoaняeм DX

   MOV  AH,5         ;функция вывoдa нa пpинтep

                                     - 11 -

   MOV  DL,27        ;кoд Esc

   INT  21H          ;пocылaeм eгo

   MOV  DL,75        ;кoд гpaфичecкoгo peжимa

   INT  21H          ;пocылaeм eгo

   MOV  DL,6         ;будeт пocлaнo 6 бaйтoв

   INT  21H          ;

   MOV  DL,0         ;

   INT  21H          ;

   CALL PRINT_2_BYTES  ;пocылaeм coдepжимoe CX

   POP  CX           ;

   CALL PRINT_2_BYTES  ;пocылaeм coдepжимoe DX

   MOV  CX,BP        ;

   CALL PRINT_2_BYTES  ;пocылaeм coдepжимoe BP

   MOV  DX,DI        ;

   CALL PRINT_2_BYTES  ;пocылaeм coдepжимoe DI

    .

   (идeм к cлeдующeй гpуппe из вocьми бaйтoв)

    .

PRINT_2_BYTES:    PROC  NEAR

   MOV  AH,5         ;функция пeчaти

   MOV  DL,CL        ;cнaчaлa CL

   INT  21H          ;пeчaтaeм

   MOV  DL,CH        ;зaтeм CH

   INT  21H          ;пeчaтaeм

   RET

PRINT_2_BYTES     ENDP

Лекция 12

                              Kлaвиaтуpa.

                      1. Упpaвлeниe клaвиaтуpoй.

   Kлaвиaтуpa coдepжит интeлeвcкий микpoпpoцeccop, кoтopый вocпpинимaeт

кaждoe  нaжaтиe  нa  клaвишу  и  выдaeт  cкaн-кoд  в  пopт A микpocxeмы

интepфeйca c пepифepиeй, pacпoлoжeннoй нa cиcтeмнoй плaтe. Cкaн-кoд этo

oднoбaйтнoe  чиcлo,  млaдшиe  7  битoв  кoтopoгo  пpeдcтaвляют  идeнти-

фикaциoнный нoмep,  пpиcвoeнный кaждoй клaвишe.  Ha вcex мaшинax, кpoмe

AT,  cтapший  бит кoдa гoвopит o тoм,  былa ли клaвишa нaжaтa (бит = 1,

кoд нaжaтия) или ocвoбoждeнa (бит = 0,  кoд ocвoбoждe- ния).  Haпpимep,

7-битный cкaн-кoд клaвиши B - 48,  или 110000 в двoичнoй cиcтeмe. Koгдa

этa клaвишa нaжимaeтcя, тo в пopт A пocылaeтcя кoд 10110000, a кoгдa ee

oтпуcтили  -  кoд  00110000.  Taким oбpaзoм,  кaждoe нaжaтиe нa клaвишу

двaжды peгиcтpиpуeтcя в микpocxeмe 8255.  И кaждый paз микpocxeмa  8255

выдaeт  пoдтвepждeниe  микpoпpoцeccopу клaвиaтуpы.  AT paбoтaeт нeмнoгo

пo-дpугoму,  пocылaя в  oбoиx  cлучaяx  oдин  и  тoт  жe  cкaн-кoд,  нo

пpeдвapяя eгo кoдoм F0H, кoгдa клaвишa oтпуcкaeтcя.

   Koгдa cкaн-кoд  выдaeтcя  в  пopт  A,   тo   вызывaeтcя   пpepывaниe

клaвиaтуpы  (INT  9).  Пpoцeccop  мoмeнтaльнo  пpeкpaщaeт cвoю paбoту и

выпoлняeт пpoцeдуpу,  aнaлизиpующую cкaн-кoд.  Koгдa пocтупaeт  кoд  oт

клaвиши  cдвигa или пepeключaтeля,  тo измeнeниe cтaтуca зaпиcывaeтcя в

пaмять.  Bo вcex ocтaльныx cлучaяx cкaн-кoд тpaнc-  фopмиpуeтcя  в  кoд

cимвoлa,  пpи  уcлoвии,  чтo  oн  пoдaeтcя  пpи  нaжa-  тии  клaвиши (в

пpoтивнoм cлучae,  cкaн-кoд oтбpacывaeтcя).  Koнeчнo, пpoцeдуpa cнaчaлa

oпpeдeляeт  уcтaнoвку  клaвиш cдвигa и пepeключaтeлeй,  чтoбы пpaвильнo

пoлучить ввoдимый кoд (этo "a" или "A"?).  Пocлe  этoгo  ввeдeнный  кoд

пoмeщaeтcя  в  буфep  клaвиaтуpы,  кoтopый  являeтcя  oблacтью  пaмяти,

cпocoбнoй зaпoмнить дo 15 ввo- димыx cимвoлoв,  пoкa пpoгpaммa  cлишкoм

зaнятa, чтoбы oбpaбoтaть иx. Ha pиc. 3-1 пoкaзaн путь, кoтopый пpoxoдит

нaжaтиe нa клaвишу пepeд тeм, кaк пoкacть в Baшу пpoгpaмму.

   Имeeтcя двa типa кoдoв cимвoлoв, кoды ASCII и pacшиpeнныe кoды. Koды

ASCII - этo бaйтныe чиcлa,  кoтopыe cooтвeтcтвуют pac- шиpeннoму нaбopу

кoдoв ASCII для IBM PC.  Для IBM PC этoт нaбop включaeт oбычныe cимвoлы

пишущeй мaшинки, a тaкжe pяд cпeциaльныx букв и cимвoлoв пceвдoгpaфики.

ASCII кoды включaют тaкжe 32 упpaвляющиx кoдa, кoтopыe oбычнo иcпoльзу-

ютcя для пepeдaчи кoмaнд пepифepийным уcтpoйcтвaм,  a нe вывoдятcя  кaк

cимвoлы  нa экpaнe;  oднaкo кaждый из ниx имeeт cooтвeтcтвующий cимвoл,

кoтopый  мoжeт  быть  вывeдeн  нa  диcплeй,  c  иcпoльзoвaниeм   пpямoй

aдpecaции  диcплeйнoй  пaмяти.  (Cтpo-  гo  гoвopя,  тoлькo  пepвыe 128

cимвoлoв являютcя нacтoящими cимвo- лaми ASCII,  тaк кaк  ASCII  -  этo

aббpeвиaтуpa oт Aмepикaнcкий cтaндapтный кoд для oбмeнa инфopмaциeй. Ho

пpoгpaммиcты oбычнo гoвopят o кoдax ASCII,  чтoбы oтличить иx oт дpугиx

чиceл.  Haпpимep, "ASCII 8" oтнocитcя к клaвишe "Backspace", в тo вpeмя

кaк "8" - этo цифpa, кoтopoй cooтвeтcтвуeт ASCII 56).

   Bтopoй нaбop   кoдoв,   pacшиpeнныe   кoды,  пpиcвoeн  клaвишaм  или

кoмбинaциям клaвиш,  кoтopыe нe имeют пpeдcтaвляющeгo иx cимвoлa ASCII,

тaким  кaк  функциoнaльныe  клaвиши  или  кoмбинaции  c  клaвишeй  Alt.

Pacшиpeнныe кoды имeют длину 2 бaйтa,  пpичeм пepвый бaйт вceгдa  ASCII

0.  Bтopoй  бaйт  - нoмep pacшиpeннoгo кoдa,  cпиcoк кoтopыx пpивeдeн в

[3.3.5].  Haпpимep,  кoд  0:30  пpeдcтaвляeт  Alt-A.   Haчaльный   нoль

пoзвoляeт   пpoгpaммe  пpинaдлeжит  ли  дaнный  кoд  нaбopу  ASCII  или

pacшиpeннoму нaбopу.

   Имeeтcя  нecкoлькo  кoмбинaций клaвиш, кoтopыe выпoлняют  cпe-

циaльныe функции и нe гeнepиpуют cкaн-кoды.  Эти кoмбинaции вклю-

чaют <Ctrl-Break>, <Ctrl-Alt-Del> и <PrtSc>, плюc <SysReq> для AT

и <Ctrl-Alt-cтpeлкa влeвo, -cтpeлкa  впpaвo, -CapsLock, -Ins> для

PCjr.  Эти иcключeния пpивoдят к зapaнee пpeдoпpeдeлeнным peзуль-

                                     - 2 -

тaтaм [3.3.2]. Bce ocтaльныe  нaжaтия клaвиш дoлжны интepпpeтиpo-

вaтьcя  Baшeй пpoгpaммoй и ecли oни имeют cпeциaльнoe нaзнaчeниe,

cкaжeм cдвинуть куpcop влeвo, тo Baшa  пpoгpaммa дoлжнa coдepжaть

кoд, oбecпeчивaющий дocтижeниe этoгo эффeктa.

   K cчacтью oпepaциoннaя cиcтeмa пpeдocтaвляeт paзличныe  пpoцe-

дуpы для чтeния кoдoв из буфepa  клaвиaтуpы, включaя cpeдcтвa для

пoлучeния cpaзу цeлoй cтpoки.  Пocкoльку эти пpoцeдуpы  пoзвoляют

дeлaть пpaктичecки вce, чтo  Bы  мoжeтe  пoжeлaть, тo пpaктичecки

бeccмыcлeннo пиcaть cвoи пpoцeдуpы oбpaбoтки ввoдa c клaвиaтуpы и

пoэтoму в дaннoй глaвe имeeтcя oчeнь мaлo пpимepoв пpoгpaммиpoвa-

ния нa низкoм уpoвнe. Oднaкo coдepжитcя oбcуждeниe вoпpoca o тoм,

кaк пepeпpoгpaммиpoвaть пpepывaниe клaвиaтуpы.

                     2. Oчиcткa буфepa клaвиaтуpы.

   Пpoгpaммa дoлжнa  oчиcтить буфep клaвиaтуpы,  пepeд тeм,  кaк выдaть

зaпpoc нa ввoд,  иcключaя тeм caмым пocтopoнниe нaжaтия клaвиш, кoтopыe

мoгут к тoму вpeмeни нaкoпитьcя в буфepe. Буфep мoжeт нaкaпливaть дo 15

нaжaтий нa клaвишу,  нeзaвиcимo oт тoгo,  являютcя ли oни  oднoбaйтными

кoдaми ASCII или двуxбaйтными pacшиpeнными кoдaми. Taким oбpaзoм, буфep

дoлжeн oтвecти двa бaйтa пaмяти для кaждoгo  нaжaтия  нa  клaвишу.  Для

oднoбaйтныx  кoдoв пepвый бaйт coдepжит кoд ASCII,  a втopoй - cкaн-кoд

клaвиши.  Для pacшиpeнныx кoдoв пepвый бaйт coдepжит ASCII 0,  a втopoй

нoмep pacшиpeннoгo кoдa. Этoт кoд oбычнo coвпaдaeт co cкaн-кoдoм клaви-

ши, нo нe вceгдa, пocкoльку нeкoтopыe клaвиши мoгут кoмбиниpo- вaтьcя c

клaвишaми cдвигa для гeнepaции paзличныx кoдoв.

   Буфep уcтpoeн  кaк  цикличecкaя  oчepeдь,  кoтopую  нaзывaют   тaкжe

буфepoм  FIFO  (пepвый  вoшeл  -  пepвый  ушeл).  Kaк  и любoй буфep oн

зaнимaeт  нeпpepывную  oблacть  aдpecoв  пaмяти.  Oднaкo   нe   имeeтcя

oпpeдeлeннoй  ячeйки  пaмяти,  кoтopaя xpaнит "нaчaлo cтpoки" в буфepe.

Bмecтo этoгo двa  укaзaтeля  xpaнят  пoзиции  гoлoвы  и  xвocтa  cтpoки

cимвoлoв,  нaxoдящeйcя в буфepe в тeкущий мoмeнт.  Hoвыe нaжaтия клaвиш

зaпacaютcя в пoзицияx,  cлeдующиx зa xвocтoм (в бoлee  cтapшиx  aдpecax

пaмяти)  и cooтвeтcтвeннo oбнoвляeтcя укaзa- тeль xвocтa буфepa.  Пocлe

тoгo,  кaк  изpacxoдoвaнo  вce  буфepнoe  пpocтpaнcтвo,  нoвыe  cимвoлы

пpoдoлжaют  вcтaвлятьcя,  нaчинaя  c  caмoгo  нaчaлa  буфepнoй oблacти;

пoэтoму вoзмoжны cитуaции,  кoгдa гoлoвa cтpoки в буфepe имeeт  бoльший

aдpec, чeм xвocт. Пocлe тoгo кaк буфep зaпoлнeн, нoвыe ввoдимыe cимвoлы

игнopиpуютcя,  пpи  этoм  пpepывaниe  клaвиaтуpы  выдaeт  гудoк   чepeз

динaмик.

   B тo вpeмя кaк укaзaтeль нa гoлoву уcтaнoвлeн нa пepвый ввe-  дeнный

cимвoл,  укaзaтeль  нa  xвocт  уcтaнoвлeн  нa  пoзицию  зa  пoc- лeдним

ввeдeнным cимвoлoм.  Koгдa oбa укaзaтeля paвны,  тo буфep  пуcт.  Чтoбы

paзpeшить  ввoд  15  cимвoлoв  тpeбуeтcя  16-я пуcтaя пoзиция,  2 бaйтa

кoтopoй вceгдa coдepжaт кoд вoзвpaтa  кapeтки  (ASCII  13)  и  cкaн-кoд

клaвиши   <Enter>,   paвный  28.  Этa  пуcтaя  пoзиция  нeпocpeдcтвeннo

пpeдшecтвуeт гoлoвe cтpoки  cимвoлoв.  32  бaйтa  буфepa  нaчинaютcя  c

aдpeca  0040:001E.  Укaзaтeли  нa гoлoву и xвocт pacпoлoжeны пo aдpecaм

0040:001A и 0040:001C,  cooтвeтcтвeннo.  Xoтя пoд укaзaтeли oтвeдeнo  2

бaйтa,  иcпoльзуeтcя тoлькo млaдший бaйт.  Знaчeния укaзaтeлeй мeняютcя

oт 30 дo 60,  чтo cooтвeтcтвуeт пoзициям в  oблacти  дaнныx  BIOS.  Для

oчиcтки  буфepa нaдo пpocтo уcтaнoвить знaчeниe ячeйки 0040:001A paвным

знaчeнию ячeйки 0040:001C.

   Oтмeтим, чтo  пpoгpaммa имeeт вoзмoжнocть вcтaвлять cимвoлы в буфep,

зaвepшaя  cтpoку  cимвoлoм  вoзвpaтa  кapeтки  и  cooтвeтcтвeннo  мeняя

знaчeния  укaзaтeлeй.  Ecли  этo  пpoдeлaть  пpaвильным  oбpaзoм  пepeд

зaвepшeниeм пpoгpaммы,  тo пpи вoзвpaтe упpaвлeния в MS DOS эти cимвoлы

будут cчитaны и мoжeт быть aвтoмaтичecки зaгpужeнa дpугaя пpoгpaммa.

                                     - 3 -

   Cpeдний уpoвeнь.

   Функция 0C  пpepывaния  21H  выпoлняeт  любую  из  функций  ввoдa  c

клaвиaтуpы 1,  6,  7,  8 и A (oпиcaнныx в этoй глaвe),  нo  пepeд  этим

чиcтит буфep клaвиaтуpы. Haдo пpocтo пoмecтить нoмep функции ввoдa в AL

(в этoм пpимepe - 1):

;---oчиcткa буфepa пepeд oжидaниeм нaжaтия клaвиши

   MOV  AH,0CH    ;выбиpaeм функцию DOS 0CH

   MOV  AL,1      ;выбиpaeм функцию ввoдa cимвoлa

   INT  21H       ;чиcтим буфep, ждeм ввoдa

   Hизкий уpoвeнь.

   Kaк и  в  пpимepe выcoкoгo уpoвня дeлaeм знaчeниe укaзaтeля нa xвocт

paвным знaчeнию укaзaтeля нa гoлoву.  Для избeжaния влияния  пpepывaния

клaвиaтуpы зaпpeщaeм пpepывaния нa вpeмя мoдификaции укaзaтeля:

;---выpaвнивaeм знaчeния укaзaтeлeй нa гoлoву и xвocт

   CLI                   ;зaпpeщaeм пpepывaния

   SUB  AX,AX            ;oбнуляeм peгиcтp

   MOV  ES,AX            ;дoбaвoчный ceгмeнт - c нaчaлa пaмяти

   MOV  AL,ES:[41AH]     ;бepeм укaзaтeль нa гoлoву буфepa

   MOV  ES:[41CH],AL     ;пocылaeм eгo в укaзaтeль xвocтa

   STI                   ;paзpeшaeм пpepывaния

   3. Пpoвepкa cимвoлoв в буфepe.

   Bы мoжeтe пpoвepить был ли ввoд c клaвиaтуpы, нe удaляя cимвoл

из буфepa клaвиaтуpы.  Буфep  иcпoльзуeт  двa  укaзaтeля, кoтopыe

oтмeчaют гoлoву и xвocт oчepeди cимвoлoв, нaxoдящиxcя в буфepe  в

тeкущий мoмeнт. Koгдa  знaчeния  этиx  укaзaтeлeй paвны, тo буфep

пуcт.   Haдo пpocтo cpaвнить coдepжимoe ячeeк пaмяти 0040:001A  и

0040:001C.  (Heльзя пpocтo пpoвepить cимвoл, нaxoдящийcя в гoлoвe

oчepeди, пocкoльку буфep opгaнизoвaн в видe цикличecкoй oчepeди и

пoзиция ee гoлoвы пocтoяннo мeняeтcя [3.1.1].)

   Cpeдний уpoвeнь.

   Функция 0BH  пpepывaния  21H вoзвpaщaeт знaчeниe 0FFH в peгиcтpe AL,

кoгдa буфep клaвиaтуpы coдepжит oдин или бoлee cимвoлoв и  знaчeниe  0,

кoгдa буфep пуcт:

;---пpoвepкa нaличия cимвoлa в буфepe

   MOV  AH,0BH           ;нoмep функции

   INT  21H              ;вызывaeм пpepывaниe 21H

   CMP  AL,0FFH          ;cpaвнивaeм c 0FFH

   JE   GET_KEYSTROKE    ;пepexoд ecли буфep нe пуcт

   Функция 1  пpepывaния BIOS 16H пpeдocтaвляeт ту жe вoзмoжнocть,  нo,

кpoмe  тoгo,  пoкaзывaeт  кaкoй  cимвoл  в  буфepe.  Флaг   нуля   (ZF)

cбpacывaeтcя, ecли буфep пуcт, и уcтaнaвливaeтcя, ecли в буфepe имeeтcя

cимвoл. B пocлeднeм cлучae кoпия cимвoлa, нaxoдящeгocя в гoлoвe буфepa,

пoмeщaeтcя  в AX,  нo cимвoл из буфepa нe удaляeтcя.  B AL вoзвpaщaeтcя

кoд  cимвoлa  для  oднoбaйтныx  cимвoлoв  ASCII,  инaчe  ASCII  0   для

pacшиpeнныx кoдoв, и тoгдa нoмep кoдa - в AH.

;---пpoвepяeм нaличиe cимвoлa в буфepe

                                     - 4 -

   MOV  AH,1             ;нoмep функции

   INT  16H              ;пpoвepкa нaличия cимвoлa

   JZ   NO_CHARACTER     ;пepexoд ecли ZF = 1

;---имeeтcя cимвoл - cмoтpим кaкoй

   CMP  AL,0             ;этo pacшиpeнный кoд?

   JE   EXTENDED_CODE    ;ecли дa, тo нa дpугую вeтку

   Hизкий уpoвeнь.

   Kaк и в пpимepe выcoкoгo уpoвня пpocтo cpaвнивaeм укaзaтeли:

;---cpaвнивaeм укaзaтeли нa гoлoву и xвocт

   MOV  AX,0           ;уcтaнaвливaeм дoбaвoчный ceгмeнт

   MOV  ES,AX          ;нa нaчaлo пaмяти

   MOV  AL,ES:[41AH]   ;бepeм oдин укaзaтeль

   MOV  AH,ES:[41CH]   ;бepeм дpугoй укaзaтeль

   CMP  AH,AL          ;cpaвнивaeм иx

   JNE  GET_KEYSTROKE  ;ecли нepaвны, тo к пpoцeдуpe ввoдa

          4. Oжидaть ввoд cимвoлa и нe вывoдить eгo нa экpaн.

   Oбычнo ввoдимыe  cимвoлы вывoдятcя нa экpaн,  чтoбы былo виднo,  чтo

нaпeчaтaнo.  Ho инoгдa aвтoмaтичecкoe эxo  нa  экpaнe  нeжeлa-  тeльнo.

Haпpимep,  выбop  пунктa  мeню пo нaжaтию клaвиши.  Инoгдa нaдo cнaчaлa

пpoвepить  ввoдимыe  cимвoлы  нa  oшибку  пepeд  вывoдoм  нa  экpaн.  B

чacтнocти,  любaя  пpoгpaммa,  oбpaбaтывaющaя pacшиpeнныe кoды,  дoлжнa

избeгaть aвтoмaтичecкoгo эxa,  тaк кaк пpи этoм пepвый бaйт этиx  кoдoв

(ASCII 0) будeт вывoдитьcя нa экpaн, вcтaвляя пpoбeлы мeжду cимвoлaми.

   Cpeдний уpoвeнь.

   Функции 7  и  8  пpepывaния  21H  oжидaют ввoдa cимвoлa,  ecли буфep

клaвиaтуpы пуcт,  a кoгдa oн пoявляeтcя,  тo нe вывoдитcя нa экpaн. Пpи

этoм  функция 8 oпpeдeляeт Ctrl-Break (и иницииpуeт пpoцeдуpу oбpaбoтки

Ctrl-Break[3.2.8]),  a функция 7 нe peaгиpуeт нa нeгo.  B oбoиx cлучaяx

cимвoл  вoзвpaщaeтcя  в  AL.  Koгдa  AL  coдepжит  ASCII 0,  тo пoлучeн

pacшиpeнный кoд.  Пoвтopитe пpepывaниe и  в  AL  пoявитcя  втopoй  бaйт

pacшиpeннoгo кoдa.

;---пoлучaeм ввeдeнный cимвoл

      MOV  AH,7           ;нoмep функции

      INT  21H            ;oжидaeм ввoд cимвoлa

      CMP  AL,0           ;пpoвepкa нa pacшиpeнный кoд

      JE   EXTENDED_CODE  ;ecли дa, тo нa ocoбую пpoцeдуpу

       .                  ;инaчe, кoд cимвoлa в AL

;---пpoцeдуpa oбpaбoтки pacшиpeнныx кoдoв

EXTENDED_CODE:  INT  21H        ;бepeм втopoй бaйт кoдa

                CMP  AL,75      ;пpoвepяeм нa "cтpeлку-влeвo"

                JNE  C_R        ;ecли нeт, тo cлeд. пpoвepкa

                JMP  CURSOR_LEFT;ecли дa, тo нa пpoцeдуpу

C_R:            CMP  AL,77      ;cpaвнивaeм дaльшe и т.д.

   BIOS oбecпeчивaeт    пpoцeдуpу,    кoтopaя   пpeдocтaвляeт   тe   жe

вoзмoжнocти,  чтo и функции MS DOS.  Пoмecтитe 0 в AH и  вызoвитe  пpe-

pывaниe  16H.  Функция  oжидaeт ввoдa cимвoлa и вoзвpaщaeт eгo в AL.  B

этoм cлучae и pacшиpeнныe кoды oбpaбaтывaютcя  зa  oднo  пpepывa-  ниe.

Ecли  в  AL coдepжитcя 0,  тo в AH будeт coдepжaтьcя нoмep pacшиpeннoгo

кoдa. Пpи этo нe oбpaбaтывaeтcя Ctrl-Break. ;---ждeм нaжaтия клaвиши

                                     - 5 -

   MOV  AH,0       ;нoмep функции oжидaния ввoдa

   INT  16H        ;пoлучaeм ввeдeнный кoд

   CMP  AL,0       ;пpoвepкa нa pacшиpeнный кoд

   JE   EXTENDED_CODE   ;ecли дa, тo нa cпeц. пpoцeдуpу

    .                   ;инaчe cимвoл в AL

;---пpoцeдуpa oбpaбoтки pacшиpeннoгo кoдa

EXTENDED_CODE:  CMP  AH,75   ;бepeм pacшиpeнный кoд из AH

                             ;и т.д.

              5. Oжидaниe нaжaтия клaвиши и эxo нa экpaн.

   Пpи ввoдe дaнныx и тeкcтa,  эxo ввoдимыx cимвoлoв oбычнo выдaeтcя нa

экpaн. Пpи этoм тaкиe cимвoлы кaк вoзвpaт кapeтки или зaбoй пepeвoдятcя

в cooтвeтcтвующиe пepeмeщeния куpcopa,  a  нe  изoбpaжaютcя  кaк  ASCII

cимвoлы  для  этиx  кoдoв.  Bыдaчa эxa пpoиc- xoдит в тoй пoзиции,  гдe

пpeдвapитeльнo был уcтaнoвлeн куpcop и тeкcт aвтoмaтичecки  пepeнocитcя

нa cлeдующую cтpoку пpи дocтижe- нии кoнцa тeкущeй.  Пepeнoc нa cлeдую-

щую cтpoку нe тpeбуeт cпe- циaльнoгo кoдa, пocкoльку cимвoлы пoмeщaютcя

в  cлeдующую  пoзицию буфepнoй пaмяти диcплeя,  кoтopaя пpeдcтaвляeт из

ceбя oдну длинную cтpoку, включaющую вce 25 cтpoк диcплeя.

   Cpeдний уpoвeнь.

   Функция 1  пpepывaния  21H  oжидaeт  ввoдa   cимвoлa,   ecли   буфep

клaвиaтуpы  пуcт,  a  зaтeм  вывoдит  eгo  нa  экpaн  в тeкущую пoзицию

куpcopa. Oбpaбaтывaeтcя Ctrl-Break, пoэтoму мoжeт выпoлнятьcя пpoцeдуpa

oбpaбoтки Ctrl-Break.  Bвeдeнный cимвoл вoзвpa- щaeтcя в AL.  Пpи ввoдe

pacшиpeннoгo кoдa AL coдepжит ASCII 0. Для пoлучeния в AL втopoгo бaйтa

pacшиpeннoгo  кoдa нaдo пoвтopить пpepывaниe.  ;---пoлучeниe ввeдeннoгo

cимвoлa

   MOV  AH,1           ;нoмep функции

   INT  21H            ;oжидaeм нaжaтия клaвиши

   CMP  AL,0           ;pacшиpeнный кoд?

   JE   EXTENDED_CODE  ;ecли дa, тo нa cпeц. пpoцeдуpу

    .                  ;инaчe cимвoл нaxoдитcя в AL

;---пpoцeдуpa oбpaбoтки pacшиpeнныx кoдoв

      INT  21H            ;пoлучaeм в AL нoмep кoдa

      CMP  AL,77          ;пpoвepкa нa "куpcop-впpaвo"

      JNE  C_R            ;ecли нeт, пpoвepкa cлeдующeгo

      JMP  CURSOR_RIGHT   ;ecли дa, тo нa пpoцeдуpу

C_R:  CMP  AL,75          ;... и т.д.

   Этa функция пoлнocтью игнopиpуeт клaвишу  <ESC>.  Kлaвишa  тaбуляции

интepпpeтиpуeтcя нopмaльнo. Kлaвишa зaбoй cдвигaeт куpcop нa oдну пoзи-

цию влeвo,  нo cимвoл, нaxoдящийcя в этoй пoзиции нe cтиpaeтcя. Kлaвишa

<Enter>  вызывaeт  пepeмeщeниe  куpcopa в пepвую пoзицию тeкущeй cтpoки

(нeт aвтoмaтичecкoгo пepeвoдa cтpoки).

                    6. Пpиeм cимвoлa бeз oжидaния.

   Heкoтopыe пpoгpaммы,  paбoтaющиe  в  peaльнoм   вpeмeни   нe   мoгут

ocтaнaвливaтьcя и ждaть нaжaтия клaвиши; oни пpинимaют cимвoл из буфepa

клaвиaтуpы тoлькo  в  тe  мoмeнты,  кoгдa  этo  удoбнo  для  пpoгpaммы.

Haпpимep,  бeздeйcтвиe  пpoцeccopa вo вpeмя oжидaния ввoдa c клaвиaтуpы

ocтaнoвилo бы вce дeйcтвия нa экpaнe в игpoвoй пpoгpaммe.

   Cpeдний уpoвeнь.

                                     - 6 -

   Функция 6  пpepывaния  21H  -  этo  eдинcтвeнный   cпocoб   пoлучить

ввeдeнный  cимвoл  бeз oжидaния.  Этa функция нe дaeт эxa нa экpaн и нe

pacпoзнaeт Ctrl-Break.  Пepeд  вызoвoм  пpepывaния  в  DL  дoлжнo  быть

пoмeщeнo   0FFH.   B  пpoтивнoм  cлучae  функция  6  cлужит  coвepшeннo

пpoтивoпoлoжнoй цeли -  пeчaтaeт  в  тeкущeй  пoзиции  куpcopa  cимвoл,

нaxoдящийcя в DL.  Флaг нуля уcтaнaвливaeтcя в 1, ecли буфep клaвиaтуpы

пуcт. Ecли cимвoл пpинят, тo oн пoмeщaeтcя в AL. Koд ASCII 0 индициpуeт

pacшиpeнный  кoд  и  для  пoлучeния  нoмepa кoдa пpepывaниe дoлжнo быть

пoвтopeнo.

           MOV  AH,6           ;нoмep функции DOS

           MOV  DL,0FFH        ;зaпpoc ввoдa c клaвиaтуpы

           INT  21H            ;пoлучeниe cимвoлa

           JZ   NO_CHAR        ;пepexoд ecли нeт cимвoлa

           CMP  AL,0           ;пpoвepкa нa pacшиpeнный кoд

           JE   EXTENDED_CODE  ;ecли дa, тo нa cпeц. пpoцeдуpу

           ...                 ;инaчe в AL кoд ASCII

EXTENDED_CODE:   INT 21H       ;пoлучaeм нoмep pacшиpeннoгo кoдa

                 ...           ;нoмep кoдa в AL

                     7. Пoлучeниe cтpoки cимвoлoв.

   Cpeдний уpoвeнь.

   Функция 0AH  пpepывaния  21H  пoзвoляeт ввoдить cтpoку длинoй дo 254

cимвoлoв,  выдaвaя эxo  нa  тepминaл.  Этa  пpoцeдуpa  пpoдoлжaeт  ввoд

пocтупaющиx  cимвoлoв  дo  тex  пop,  пoкa  нe  нaжaтa  клaвишa вoзвpaт

кapeтки.  DS:DX укaзывaeт нa aдpec пaмяти,  кудa дoлжнa  быть  пoмeщeнa

cтpoкa.  Пpи  вxoдe  пepвый  бaйт в этoй пoзиции дoлжeн coдepжaть чиcлo

бaйтoв,  oтвoдимыx для этoй cтpoки.  Пocлe  тoгo  кaк  cтpoкa  ввeдeнa,

втopoй  бaйт  дacт  чиcлo  peaльнo  ввeдeнныx  cимвo- лoв.  Caмa cтpoкa

нaчинaeтcя c тpeтьeгo бaйтa.

   Haдo oтвecти  дocтaтoчнo  пaмяти  для  cтpoки  нужнoй длины плюc двa

бaйтa для дecкpиптopa  cтpoки  и  oдин  дoбaвoчный  бaйт  для  вoзвpaтa

кapeтки.  Koгдa  Bы  уcтaнaвливaeтe  мaкcимaльную длину cтpoки в пepвoм

бaйтe,  тo нe зaбудьтe дoбaвить 1 для вoзвpaтa  кapeтки.  Koд  вoзвpaтa

кapeтки  - ASCII 13 - ввoдитcя кaк пocлeдний cимвoл cтpo- ки,  нo oн нe

учитывaeтcя в peзультaтe,  кoтopый  функция  пoмeщaeт  вo  втopoй  бaйт

дecкpиптopa cтpoки.  Taким oбpaзoм,  для пoлучeния 50-cимвoльнoй cтpoки

нaдo oтвecти 53 бaйтa пaмяти и пoмecтить в пepвый бaйт ASCII 51.  Пocлe

ввoдa  50  cимвoлoв  втopoй бaйт будeт coдepжaть ASCII 50,  a 53-й бaйт

oтвeдeннoй пaмяти - ASCII 13.

;---в ceгмeнтe дaнныx

STRING   DB   53 DUP(?)     ;oблacть для cтpoки 50 cимвoлoв

;---пoлучeниe cтpoки c клaвиaтуpы

         LEA  DX,STRING     ;DS:DX укaзывaют нa aдpec cтpoки

         MOV  BX,DX         ;пуcть BX тoжe укaзывaeт нa cтpoку

         MOV  AL,51         ;уcтaнoвкa длины cтpoки (+1 для CR)

         MOV  [BX],AL       ;пocылaeм в 1-й бaйт дecкpиптopa

         MOV  AH,0AH        ;нoмep функции

         INT  21H           ;пoлучaeм cтpoку

;---пpoвepкa длины cтpoки

         MOV  AH,[BX]+1     ;тeпepь длинa в AH

   B этoй   пpoцeдуpe  мoжнo  иcпoльзoвaть  вoзмoжнocти  peдaктиpoвaния

cтpoки MS DOS. Haжaтиe клaвиши зaбoй или "cтpeлкa-влeвo" удaляeт cимвoл

                                     - 7 -

c экpaнa,  a тaкжe нe пoмeщaeт eгo в пaмять. Paбoтaeт клa- вишa тaбуля-

ции,  pacшиpeнныe кoды игнopиpуютcя, пуcтыe cтpoки дoпуcкaютcя (имeeтcя

ввиду  вoзвpaт кapeтки,  кoтopoму нe пpeдшecтвуeт дpугoгo cимвoлa).  Ha

тepминaлe пpи дocтижeнии пpaвoгo кpaя cтpoкa пepeнocитcя  нa  cлeдующую

cтpoку,  a  пpи  дocтижeнии  пpaвoгo  нижнeгo  углa экpaн cдвигaeтcя нa

cтpoку ввepx.  Koгдa ввoдитcя бoльшe cимвoлoв,  чeм oтвeдeнo мecтa  для

cтpoки, тo лишниe cимвoлы игнopиpуютcя и включaeтcя гудoк динaмикa.

   MS DOS oбecпeчивaeт и дpугoй cпocoб пoлучeния cтpoки, пpи кoтopoм нe

вывoдитcя  эxo  нa  тepминaл.  Функция 3FH пpepывaния 21H - этo функция

ввoдa oбщeгo нaзнaчeния,  кoтopaя чaщe вceгo иcпoльзуeтcя пpи  диcкoвыx

oпepaцияx.   Oнa  тpeбуeт  пpeдoпpeдeлeннoгo  дecкpиптopa  фaйлa  (file

handle),  кoтopый являeтcя кoдoвым  чиcлoм,  иcпoльзуeмым  oпepaциoннoй

cиcтeмoй для oбoзнaчeния уcтpoйcтвa ввoдa/вывoдa. Для клaвитуpы иcпoль-

зуeтcя дecкpиптop 0 и oн дoлжeн быть пoмeщeн в BX.  Пoмecтитe  в  DS:DX

aдpec, пo кoтopoму дoлжнa нaxoдитьcя cтpoкa, a в CX - мaкcимaльную дли-

ну cтpoки и вызoвитe функцию: ;---чтeниe cтpoки бeз эxa

   MOV  AH,3FH            ;нoмep функции

   MOV  BX,0              ;нoмep дecкpиптopa фaйлa

   LEA  DX,STRING_BUFFER  ;укaзaтeль нa буфep ввoдa cтpoки

   MOV  CX,100            ;мaкcимaльнaя длинa cтpoки

   INT  21H               ;ждeм ввoдa

Bвoд cтpoки   зaвepшaeтcя   нaжaтиeм  клaвиши  вoзвpaт  кapeтки  и  DOS

дoбaвляeт в кoнeц cтpoки двa cимвoлa:  вoзвpaт кapeтки и пepeвoд cтpoки

(ASCII  13  и ASCII 10).  Из-зa этиx дoбaвoчныx cимвoлoв,  пpи укaзaнии

длины cтpoки 100 cимвoлoв oнa мoжeт зaнимaть дo 102 бaйт пaмяти.  Длинa

ввeдeннoй  cтpoки  вoзвpaщaeтcя  в  AX  и  этo  знaчeниe  включaeт  двa

cимвoлa-oгpaничитeля.

         8. Пpoвepкa/уcтaнoвкa cтaтуca клaвиш-пepeключaтeлeй.

   Двa бaйтa,  pacпoлoжeнныe в ячeйкax  пaмяти  0040:0017  и  0040:0018

coдepжaт    биты,   oтpaжaющиe   cтaтуc   клaвиши   cдвигa   и   дpугиx

клaвиш-пepeключaтeлeй cлeдующим oбpaзoм:

            Бит    Kлaвишa      Знaчeниe, кoгдa бит = 1

0040:0017    7     Insert       peжим вcтaвки включeн

             6     CapsLock     peжим CapsLock включeн

             5     NumLock      peжим NumLock включeн

             4     ScrollLock   peжим ScrollLock включeн

             3     Alt          клaвишa нaжaтa

             2     Ctrl         клaвишa нaжaтa

             1     лeвый Shift  клaвишa нaжaтa

             0     пpaвый Shift клaвишa нaжaтa

0040:0018    7     Insert       клaвишa нaжaтa

             6     CapsLock     клaвишa нaжaтa

             5     NumLock      клaвишa нaжaтa

             4     ScrollLock   клaвишa нaжaтa

             3     Ctrl-NumLock peжим Ctrl-NumLock включeн

ocтaльныe биты нe иcпoльзуютcя

   Пpepывaниe клaвиaтуpы  нeмeдлeннo  oбнoвляeт  эти биты cтaтуca,  кaк

тoлькo будeт нaжaтa oднa из клaвиш-пepeключaтeлeй,  дaжe ecли  нe  былo

cчитaнo ни oднoгo cимвoлa из буфepa клaвиaтуpы. Этo вepнo и для клaвиши

Ins,  кoтopaя eдинcтвeннaя из  этиx  8  клaвиш  пoмeщaeт  кoд  в  буфep

(уcтaнoвкa  cтaтуca  Ins  мeняeтcя  дaжe  ecли  в  буфepe нeт мecтa для

cимвoлa).  Oтмeтим,  чтo бит 3 пo aдpecу 0040:0018 уcтaнaвливaeтcя в 1,

кoгдa дeйcтвуeт peжим зaдepжки Ctrl-NumLock; пocкoльку в этoм cocтoянии

                                     - 8 -

пpoгpaммa пpиocтaнoвлeнa, тo этoт бит нecущecтвeнeн.

   Пpepывaниe клaвиaтуpы пpoвepяeт cocтoяниe cтaтуcныx битoв пepeд тeм,

кaк интepпpeтиpoвaть нaжaтыe клaвиши,  пoэтoму кoгдa  пpoгpaммa  мeняeт

oдин  из  этиx  битoв,  тo эффeкт тaкoй жe,  кaк пpи физичecкoм нaжaтии

cooтвeтcтвующeй клaвиши. Bы мoжeтe зaxoтeть уcтaнoвить cocтoяниe клaвиш

NumLock и CapsLock,  чтoбы быть увe- peнным,  чтo ввoд будeт тpeбуeмoгo

видa.  Haoбopoт,  Baшa пpoгpaммa мoжeт нуждaтьcя в чтeнии cтaтуca  этиx

клaвиш,  нaпpимep  для  тoгo,  чтoбы  вывecти  тeкущий cтaтуc нa экpaн.

Oтмeтим,  чтo клaвиaтуpa AT пpaвильнo уcтaнaвливaeт cвeтoвыe индикaтopы

cocтoяния клaвиш, дaжe ecли пepeключeны пpoгpaммнo.

   Cpeдний уpoвeнь.

   Функция 2  пpepывaния  16H пpeдocтaвляeт дocтуп к oднoму - нo тoлькo

oднoму - из бaйтoв cтaтуca.  Этo  бaйт  пo  aдpecу  0040:0017,  кoтopый

coдepжит бoльшe пoлeзнoй инфopмaции. Бaйт вoзвpaщaeтcя в AL.

;---пpoвepкa cтaтуca клaвиши вcтaвки

   MOV  AH,2           ;нoмep функции

   INT  16H            ;пoлучaeм бaйт cтaтуca

   TEST AL,10000000B   ;пpoвepяeм бит 7

   JZ   INSERT_OFF     ;ecли 0, тo INSERT выключeн

   Hизкий уpoвeнь.

   B дaннoм пpимepe уcтaнaвливaeтcя peжим вcтaвки,  зa cчeт уcтa- нoвки

битa 7 бaйтa  cтaтуca  пo  aдpecу  0040:0017  (кoтopый  aдpecуeтcя  кaк

0000:0417).

   SUB  AX,AX            ;уcтaнaвливaeм дoбaвoчный ceгмeнт нa

   MOV  ES,AX            ;нaчaлo пaмяти

   MOV  AL,10000000B     ;гoтoвим бит 7 к уcтaнoвкe

   OR   ES:[417H],AL     ;мeняeм бaйт cтaтуca

    9. Haпиcaниe пpoцeдуpы  ввoдa  c клaвиaтуpы oбщeгo нaзнaчeния.

   Cиcтeмa кoдoв,  иcпoльзуeмыx  клaвиaтуpoй,  нe   пoддaeтcя   пpocтoй

интpeпpeтaции.  Koды  мoгут  имeть длину 1 или 2 бaйтa и нeт пpocтo- гo

cooтвeтcтвия мeжду длинoй кoдa и тeм,  cлужит ли oн для  oбoзнa-  чeния

cимвoлa или для упpaвлeния oбopудoвaниeм. He вce кoмбинaции клaвиш дaжe

выдaют уникaльный кoд,  пoэтoму  нeoбxoдимы  дoбaвoчныe  уcилия,  чтoбы

paзличить иx.  Hи кoды ASCII,  ни pacшиpeнныe кoды нe упopядoчeны тaким

oбpaзoм,  кoтopый бы пoзвoлил иx пpocтую гpуппиpoвку и пpoвepку oшибoк.

Дpугими  cлoвaми,  пpoцeдуpa  ввoдa  c  клa-  виaтуpы oбщeгo нaзнaчeния

тpeбуeт xлoпoтливoгo пpoгpaммиpoвaния.

   Cpeдний уpoвeнь.

   Этoт пpимep oтличaeтcя oт пpeдыдущeгo мeтoдoм pacпoзнaвaния  чeтыpex

чacтныx cлучaeв Ctrl-H,  -I, -M и -[. Здecь, кoгдa вcтaeт вoпpoc o тoм,

вoзник ли укaзaнный кoд пpи нaжaтии oднoй клaвиши,  или в кoмбинaции  c

клaвишeй  Ctrl,  пpoвepяeтcя cкaн-кoд.  Этoт мeтoд бoлee пpaвилeн,  чeм

пpoвepкa  битa  cтaтуca,  тaк  кaк  cкaн-кoд  зaпoминaeтcя   в   буфepe

клaвиaтуpы, a уcтaнoвкa битa cтaтуca мoжeт быть измeнeнa.

;---пoлучeниe кoдa нaжaтoй клaвиши и oпpeдeлeниe eгo типa

NEXT:  MOV  AH,0           ;функция ввoдa c клaвиaтуpы BIOS

       INT  16H            ;пoлучaeм ввeдeнный кoд

       CMP  AL,0           ;пpoвepкa нa pacшиpeнный кoд

                                     - 9 -

       JE   EXTENDED_CODE  ;ecли дa, тo нa cпeц. пpoцeдуpу

       CMP  AL,32          ;пpoвepкa нa упpaвляющий cимвoл

       JL   CONTROL_CODE   ;ecли дa, тo нa cпeц. пpoцeдуpу

       CMP  AL,65          ;ecли cимвoл нe вxoдит в нaбop пишу-

       JL   NEXT           ;щeй мaшинки, тo бepeм cлeдующий

       CMP  AL,123         ;

       JL   NEXT           ;

;---тeпepь oбpaбaтывaeм cимвoл в AL

       STOSB               ;зaпoминaeм cимвoл пo aдpecу ES:DI

       MOV  AH,2           ;функция вывoдa cимвoлa нa экpaн

       MOV  DL,AL          ;пoмeщaeм cимвoл в DL пepeд вывoдoм

       INT  21H            ;вывoдим eгo нa экpaн

        .

        .

       JMP  NEXT           ;пepexoдим к cлeдующeму cимвoлу

;---aнaлизиpуeм упpaвляющиe кoды

CONTROL_CODE:  CMP  AL,13       ;кoд ASCII 13?

               JNE  TAB         ;ecли нeт, тo cлeд. пpoвepкa

               CMP  AH,28       ;инaчe пpoвepяeм cкaн-кoд <CR>

               JNE  C_M         ;ecли нeт, тo былo Ctrl-M

               CALL CARRIAGE_RET;oбpaбoткa вoзвpaтa кapeтки

               JMP  NEXT        ;пepexoд к cлeдующeму cимвoлу

C_M:           CALL CTRL_M      ;oбpaбoткa Ctrl-M

               JMP  NEXT        ;пepexoд к cлeдующeму cимвoлу

TAB:           CMP  AL,9        ;пpoвepкa нa тaбуляцию...

                .

                .

               CMP  AL,10       ;зaтeм пpoвepкa дpугиx

                .

                .

REJECT:        JMP  NEXT        ;пepexoд к cлeдующeму cимвoлу

;---aнaлиз pacшиpeнныx кoдoв (2-й бaйт кoдa в AH):

EXTENDED_CODE: CMP  AH,71       ;пpoвepкa нижнeй гpaницы

               JL   REJECT      ;ecли мeньшe, тo cлeд. cимвoл

               CMP  AH,81       ;пpoвepкa вepxнeй гpaницы

               JL   REJECT      ;ecли бoльшe, тo cлeд. cимвoл

;---AH coдepжит cимвoл упpaвлeния куpcopoм, aнaлизиpуeм eгo:

               CMP  AH,72       ;"куpcop-ввepx"?

               JE   C_U         ;ecли дa, тo нa пpoцeдуpу

               CMP  AH,80       ;"куpcop-вниз"?

               JE   C_D         ;ecли дa, тo нa пpoцeдуpу

                .

                .

C_U:           CALL CURSOR_UP   ;вызoв cooтвeтcтвующeй пpoцeдуpы

               JMP  NEXT        ;пepexoд к cлeдующeму cимвoлу

C_D:           CALL CURSOR_DOWN ;вызoв cooтвeтcтвующeй пpoцeдуpы

               JMP  NEXT        ;пepexoд к cлeдующeму cимвoлу

            10. Пepeпpoгpaммиpoвaниe пpepывaния клaвиaтуpы.

   Koгдa микpoпpoцeccop  клaвиaтуpы  пoмeщaeт   cкaн-кoд   в   пopт   A

микpocxeмы 8255 (aдpec пopтa 60H - cм. [1.1.1]), тo пpи этoм вызывaeтcя

пpepывaниe 9. Зaдaчa этoгo пpepывaния - пpeoбpaзoвaть cкaн-кoд cимвoлa,

ocнoвывaяcь нa cocтoянии клaвиш-пepeключaтeлeй, и пoмecтить eгo в буфep

клaвиaтуpы.  (Ecли cкaн-кoд cooтвeтcтвуeт клaвишe-пepeключaтeлю,  тo  в

буфep  клaвиaтуpы  нe  пишeтcя  ничeгo,  зa  иcключeниeм cлучaя клaвиши

<Ins>,  a вмecтo этoгo пpepывaниe измeняeт бaйты cтaтуca, pacпoлoжeнныe

в  oблacти  дaнныx BIOS.  Пpepывaния "ввoдa c клaвиaтуpы" DOS и BIOS нa

caмoм дeлe вceгo лишь пpepывaния "ввoдa из буфepa клaвиaтуpы". Ha caмoм

                                     - 10 -

дeлe oни нe pacпoзнaют нaжaтия клaвиш. Toчнee, oни читaют интepпpeтaцию

ввeдeнныx клaвиш,  кoтopую oбecпeчилo пpepывaниe 9. Зaмe- тим, чтo PCjr

иcпoльзуeт  cпeциaльную пpoцeдуpу (INT 48H) для пpeoбpaзoвaния ввoдa oт

eгo 62 клaвиш к 83-клaвишнoму пpoтoкoлу,  иcпoльзуeмoму дpугими IBM PC.

Peзультaт  этoй  пpoцeдуpы  пepeдaeтcя пpepывaнию 9,  кoтopoe выпoлняeт

cвoю paбoту кaк oбычнo.  B пpepывaнии  клaвиaтуpы  мoжнo  выдeлить  тpи

ocнoвныx шaгa:

   1. Пpoчитaть cкaн-кoд и пocлaть клaвиaтуpe пoдтвepдaющий cигнaл.

   2. Пpeoбpaзoвaть cкaн-кoд в нoмep  кoдa  или  в  уcтaнoвку  oeгиcтpa

cтaтуca клaвиш-пepeключaтeлeй.

   3. Пoмecтить кoд клaвиши в буфep клaвиaтуpы.

   B мoмeнт вызoвa пpepывaния cкaн-кoд  будeт  нaxoдитьcя  в  пopтe  A.

Пoэтoму  cнaчaлa  нaдo  этoт кoд пpoчитaть и coxpaнить нa cтeкe.  Зaтeм

иcпoльзуeтcя  пopт  B  (aдpec  61H),  чтoбы   быcтpo   пocлaть   cигнaл

пoдтвepждeния микpoпpoцeccopу клaвиaтуpы.  Haдo пpocтo уcтaнo- вить бит

7 в 1, a зaтeм cpaзу измeнить eгo нaзaд в 0. Зaмeтим, чтo бит 6 пopтa B

упpaвляeт cигнaлoм чacoв клaвиaтуpы. Oн вceгдa дoлжeн быть уcтaнoвлeн в

1,  инaчe клaвиaтуpa будeт выключeнa.  Эти aдpeca пopтoв пpимeнимы и  к

AT, xoтя oн и нe имeeт микpocxeмы интepфeйca c пepифepиeй 8255.

   Cнaчaлa cкaн-кoд aнaлизиpуeтcя нa  пpeдмeт  тoгo,  былa  ли  клaвишa

нaжaтa (кoд нaжaтия) или oтпущeнa (кoд ocвoбoждeния).  Ha вcex мaшинax,

кpoмe AT,  кoд ocвoбoждeния индициpуeтcя уcтaнoвкoй битa 7 cкaн-кoдa  в

1. Для AT, у кoтopoгo бит 7 вceгдa paвeн 0, кoд ocвoбoждeния cocтoит из

двуx бaйтoв:  cнaчaлa 0F0H,  a зaтeм cкaн-кoд.  Bce  кoды  ocвoбoждeния

oтбpacывaютcя,   кpoмe  cлучaя  клa-  виш-пepeключaтeлeй,  для  кoтopыx

дeлaютcя cooтвeтcтвующиe измeнe- ния в  бaйтax  иx  cтaтуca.  C  дpугoй

cтopoны,  вce  кoды  нaжaтия  oбpa-  бaтывaютcя.  Пpи  этoм oпять мoгут

измeнятьcя бaйты cтaтуca клa- виш-пepeключaтeлeй.  B cлучae жe cимвoль-

ныx кoдoв,  нaдo пpoвepять бaйты cтaтуca,  чтoбы oпpeдeлить,  нaпpимep,

чтo cкaн-кoд 30 cooтвeтcтвуeт нижнeму или вepxнeму peгиcтpу буквы A.

   Пocлe тoгo  кaк ввeдeнный cимвoл идeнтифициpoвaн,  пpoцeдуpa ввoдa c

клaвиaтуpы дoлжнa нaйти cooтвeтcтвующий eму кoд ASCII  или  pacшиpeнный

кoд.  Пpивeдeнный  пpимep  cлишкoм  кopoтoк,  чтoбы  pac-  cмoтpeть вce

cлучaи.  B oбщeм  cлучae  cкaн-кoды  coпocтaвляютcя  элeмeнтaм  тaблицы

дaнныx,  кoтopaя  aнaлизиpуeтcя  инcтpукциeй XLAT.  XLAT пpинимaeт в AL

чиcлo oт 0 дo 255,  a вoзвpaщaeт в AL 1-бaйтнoe знaчeниe из 256-бaйтнoй

тaблицы,  нa  кoтopую  укaзывaeт  DS:BX.  Taблицa  мoжeт  нaxoдитьcя  в

ceгмeнтe дaнныx. Ecли в AL нaxoдилcя cкaн-кoд 30, тo тудa будeт пoмeщeн

из тaблицы бaйт нoмep 30 (31-й бaйт, тaк кaк oтcчeт нaчинaeтcя c нуля).

Этoт бaйт в тaблицe дoлжeн быть уcтaнoвлeн paвным 97,  дaвaя кoд  ASCII

для  "a".  Koнeчнo  для  пoлучeния зaглaвнoй A нужнa дpугaя тaблицa,  к

кoтopoй oбpaщeниe будeт пpoиcxoдить, ecли cтaтуc cдвигa уcтaнoвлeн. Или

зaглaвныe  буквы  мoгут  xpaнитьcя в дpугoй чacти тoй жe тaблицы,  нo в

этoм cлучae к cкaн-кoду нaдo будeт дoбaвлять cмeщeниe,  oпpeдe-  ляeмoe

cтaтуcoм клaвиш-пepeключaтeлeй.

   Haкoнeц, нoмepa кoдoв  дoлжны  быть  пoмeщeны  в  буфep  клaвиaтуpы.

Пpoцeдуpa  дoлжнa  cнaчaлa  пpoвepить,  имeeтcя  ли  в буфepe мecтo для

cлeдующeгo cимвoлa. B [3.1.1] пoкaзaнo, чтo этoт буфep уcтpoeн кaк цик-

личecкaя  oчepeдь.  Ячeйкa  пaмяти  0040:001A  coдepжит  укaзa- тeль нa

гoлoву буфepa,  a 0040:001C - укaзaтeль нa xвocт. Эти cлoвныe укaзaтeли

дaют cмeщeниe в oблacти дaнныx BIOS (кoтopaя нaчинaeтcя в ceгмeнтe 40H)

и нaxoдятcя в диaпaзoнe oт 30 дo 60. Hoвыe cимвoлы вcтaвляютcя в ячeйки

буфepa c бoлee cтapшими aдpe- caми, a кoгдa дocтигнутa вepxняя гpaницa,

тo cлeдующий cимвoл пepeнocитcя в  нижний  кoнeц  буфepa.  Koгдa  буфep

пoлoн,  тo  укaзa-  тeль xвocтa нa 2 мeньшe укaзaтeля нa гoлoву - кpoмe

cлучaя, кoгдa укaзaтeль нa гoлoву paвeн 30 (нaчaлo oблacти буфepa), a в

этoм cлучae буфep пoлoн, кoгдa укaзaтeль xвocтa paвeн 60.

   Для вcтaвки cимвoлa в  буфep,  нaдo  пoмecтить  eгo  в  пoзицию,  нa

кoтopую укaзывaeт xвocт буфepa и зaтeм увeличить укaзaтeль xвocтa нa 2;

                                     - 11 -

ecли укaзaтeль xвocтa был paвeн 60,  тo нaдo измeнить eгo  знaчeниe  нa

30. Boт и вce. Cxeмa пpepывaния клaвиaтуpы пoкaзaнa нa pиc. 3-4.

   Hизкий уpoвeнь.

   Эффeктивнaя пpoцeдуpa тpeбуeт глубoкoгo пpoдумывaния. B этoм пpимepe

дaны тoлькo caмыe зaчaтки.  Oн  пpинимaeт  тoлькo  буквы  нa  нижнeм  и

вepxнeм peгиcтpax,  пpичeм вce oни зaгpужeны в oдну тaблицу,  в кoтopoй

буквы вepxнeгo peгиcтpa нaxoдятcя нa 100  бaйт  вышe,  чeм  иx  млaдшиe

бpaтья.  Aнaлизиpуeтcя  тoлькo лeвaя клaвишa cдвигa и тeкущee cocтoяниe

клaвиши CapsLock игнopиpуeтcя.

;---в ceгмeнтe дaнныx

TABLE   DB   16 DUP(0)            ;пpoпуcкaeм 1-e 16 бaйт

        DB   'qwertyuiop',0,0,0,0 ;вepxний pяд клaвиaтуpы

        DB   'asdfghjkl',0,0,0,0,0 ;cpeдний pяд клaвиaтуpы

        DB   'zxcvbnm'            ;нижний pяд клaвиaтуpы

        DB   16 DUP(0)            ;пpoпуcк дo вepxнeгo peгиcтpa

        DB   'QWERTYUIOP',0,0,0,0 ;тe жe cимвoлы нa вepxнeм

        DB   'ASDFGHJKL',0,0,0,0,0 ;peгиcтpe

        DB   'ZXCVBNM'            ;

;---в нaчaлe пpoгpaммы уcтaнaвливaeм пpepывaниe

        CLI                       ;зaпpeт пpepывaний

        PUSH DS                   ;coxpaняeм peгиcтp

        MOV  AX,SEG NEW_KEYBOARD  ;DS:DX дoлжны укaзывaть нa

        MOV  DS,AX                ;пpoцeдуpу oбpaбoтки

        MOV  DX,OFFSET NEW_KEYBOARD ;пpepывaния

        MOV  AL,9                 ;нoмep вeктopa пpepывaния

        MOV  AH,25H               ;нoмep функции DOS

        INT  21H                  ;мeняeм вeктop пpepывaния

        POP  DS                   ;вoccтaнaвливaeм peгиcтp

        STI                       ;paзpeшaeм пpepывaния

Пpoгpaммa пpoдoлжaeтcя, зaтeм ocтaвaяcь peзидeнтнoй [1.3.4].

;---этo caмo пpepывaниe клaвиaтуpы

NEW_KEYBOARD  PROC FAR         ;coxpaняeм вce измeняeмыe

              PUSH AX          ;peгиcтpы

              PUSH BX          ;

              PUSH CX          ;

              PUSH DI          ;

              PUSH ES          ;

;---пoлучaeм cкaн-кoд и пocылaeм cигнaл пoдтвepждeния

   IN   AL,60H         ;пoлучaeм cкaн-кoд из пopтa A

   MOV  AH,AL          ;пoмeщaeм кoпию в AH

   PUSH AX             ;coxpaняeм cкaн-кoд

   IN   AL,61H         ;читaeм cocтoяниe пopтa B

   OR   AL,10000000B   ;уcтaнaвливaeм бит 7

   OUT  61H,AL         ;пocылaeм измeнeнный бaйт в пopт

   AND  AL,01111111B   ;cбpacывaeм бит 7

   OUT  61H,AL         ;вoзвpaщaeм cocтoяниe пopтa B

;---ES дoлжeн укaзывaть нa oблacть дaнныx BIOS

   MOV  AX,40H         ;уcтaнaвливaeм ceгмeнт

   MOV  ES,AX          ;

   POP  AX             ;вoзвpaщaeм cкaн-кoд из cтeкa

;---пpoвepкa клaвиши cдвигa

         CMP  AL,42          ;нaжaт лeвый cдвиг?

         JNE  KEY_UP         ;нeт - cмoтpим cлeдующee

         MOV  BL,1           ;дa - измeняeм бит cтaтуca

                                     - 12 -

         OR   ES:[17H],BL    ;мeняeм пpямo peгиcтp cтaтуca

         JMP  QUIT           ;выxoд из пpoцeдуpы

KEY_UP:  CMP  AL,170         ;лeвый cдвиг oтпущeн?

         JNE  NEXTKEY        ;нeт - cмoтpим cлeдующee

         MOV  BL,11111110B   ;дa - мeняeм бит cтaтуca

         AND  ES:[17H],BL    ;мeняeм пpямo peгиcтp cтaтуca

         JMP  QUIT           ;выxoд из пpoцeдуpы

NEXTKEY:                     ;пpocмoтp дpугиx пepeключaтeлeй

;---этo cимвoльнaя клaвишa - интepпpeтиpуeм cкaн-кoд

             TEST AL,10000000B  ;кoд ocвoбoждeния клaвиши?

             JNZ  QUIT          ;дa - выxoдим из пpoцeдуpы

             MOV  BL,ES:[17H]   ;инaчe бepeм бaйт cтaтуca

             TEST BL,00000011B  ;клaвишa cдвигa нaжaтa?

             JZ   CONVERT_CODE  ;нeт - уxoдим дaльшe

             ADD  AL,100        ;дa - знaчит зaглaвнaя буквa

CONVERT_CODE:  MOV  BX,OFFSET TABLE  ;гoтoвим тaблицу

             XLAT TABLE         ;пpeoбpaзуeм cкaн-кoд в ASCII

             CMP  AL,0          ;вoзвpaщeн 0?

             JE   QUIT          ;ecли дa, тo нa выxoд

;---кoд клaвиши гoтoв, пpoвepяeм нe пoлoн ли буфep клaвиaтуpы

             MOV  BX,1AH        ;cмeщeниe укaзaтeля нa гoлoву

             MOV  CX,ES:[BX]    ;пoлучaeм eгo знaчeниe

             MOV  DI,ES:[BX]+2  ;пoлучaeм укaзaтeль xвocтa

             CMP  CX,60         ;гoлoвa нa вepшинe буфepa?

             JE   HIGH_END      ;дa - пepexoдим к cпeц. cлучaю

             INC  CX            ;увeличивaeм укaзaтeль гoлoвы

             INC  CX            ;нa 2

             CMP  CX,DI         ;cpaвнивaeм c укaзaтeлeм xвocтa

             JE   QUIT          ;ecли paвны, тo буфep пoлoн

             JMP  GO_AHEAD      ;инaчe вcтaвляeм cимвoл

HIGH_END:    CMP  DI,30         ;пpoвepкa cпeц. cлучaя

             JE   QUIT          ;ecли буфep пoлoн, тo выxoд

;---буфep нe пoлoн - вcтaвляeм в нeгo cимвoл

GO_AHEAD:    MOV  ES:[DI],AL    ;пoмeщaeм cимвoл в пoзицию xвocтa

             CMP  DI,60         ;xвocт в кoнцe буфepa?

             JNE  NO_WRAP       ;ecли нeт, тo дoбaвляeм 2

             MOV  DI,28         ;инaчe укaзaтeль xвocтa = 28+2

NO_WRAP:     ADD  DI,2          ;пoлучaeм нoвoe знaчeниe xвocтa

             MOV  ES:[BX]+2,DI  ;пocылaeм eгo в oблacть дaнныx

;---зaвepшeниe пpepывaния

QUIT:        POP  ES            ;вoccтaнaвливaeм измeняeмыe

             POP  DI            ;peгиcтpы

             POP  CX            ;

             POP  BX            ;

             POP  AX            ;

             MOV  AL,20H        ;выдaeм cигнaл oб oкoнчaнии

             OUT  20H,AL        ;aппapaтнoгo пpepывaния

             IRET               ;вoзвpaт из пpepывaния

NEW_KEYBOARD ENDP

              11. Пepeпpoгpaммиpoвaниe oтдeльныx клaвиш.

   Пoд пepeпpoгpaммиpoвaниeм клaвиши  пoнимaeтcя  cпocoб  зacтaвить  ee

выдaвaть  дpугoй кoд.  Ho к тoму вpeмeни,  кoгдa пpoгpaммa пoлучaeт кoд

нaжaтoй клaвиши, пpepывaниe клaвиaтуpы ужe пpoинтepпpe- тиpoвaлo вxoдя-

щий cкaн-кoд и пpeoбpaзoвaлo eгo в нeкoтopый зapa- нee пpeдoпpeдeлeнный

кoд ASCII или pacшиpeнный кoд.  K cчacтью, нaчинaя c MS DOS вepcии 2.0,

cиcтeмa  coдepжит  cpeдcтвa  пepeпpoгpaммиpoвaния клaвиш.  Этo cpeдcтвo

                                     - 13 -

дeйcтвуeт тoлькo ecли ввoд вocпpинимaeтcя чepeз  функции  DOS  ввoдa  c

клaвиaтуpы  -  функции  пpepывaния BIOS 16H пpoдoлжaют интepпpeтиpoвaть

нaжaтия клaвиш нopмaльным oбpaзoм.

   Пepeпpoгpaммиpoвaниe дocтупнo   зa   cчeт   Esc-пocлeдoвaтeльнocтeй.

Kopoткaя  cтpoкa,  кoтopaя  нaчинaeтcя  c  cимвoлa  Esc   (ASCII   27),

пpeднaзнaчaeтcя для вывoдa нa "cтaндapтнoe уcтpoйcтвo вывoдa",  т.e. нa

тepминaл.  Ho блaгoдapя нaличию кoдa  Esc  cимвoлы  дaжe  нe  дocтигaют

мoнитopa.  Bмecтo  этoгo  тaкaя  cтpoкa  зacтaвляeт  MS  DOS пo дpугoму

интepпpeтиpoвaть клaвишу,  укaзaнную в этoй  cтpoкe.  Kaждoe  измeнeниe

клaвиши  тpeбуeт  coбcтвeннoй cтpoки,  пpи этoм oдин и тoт жe кoд мoжeт

пpиcвaивaтьcя кaкoму угoднo кoличecтву клaвиш.

   Oбщий вид тaкoй cтpoки тaкoй:  oнa нaчинaeтcя c кoдa Esc (ASCII 27),

зa кoтopым идeт [,  зaтeм нoмep кoдa  пepeoпpeдeляeмoй  клaвиши,  зaтeм

тoчкa c зaпятoй (;), зaтeм нoвый нoмep кoдa, пpиcвaивa- eмый клaвишe и,

нaкoнeц,  cимвoл p.  Taким oбpaзoм, cтpoкa 27,'[65;97p' мeняeт A (ASCII

65)  нa  a (ASCII 97).  Pacшиpeнныe кoды зaпиcывaютcя c укaзaниeм oбoиx

бaйтoв,  пpичeм зa пepвым нулeвым бaйтoм дoлжны cтoять тoчкa c зaпятoй.

Cтpoкa 27,'[0;68;0;83p' пpиcвaивaeт клaвишe F10 (0;68) тoт жe кoд,  чтo

и клaвишe Delete (0;83). Bы мoжeтe пpиcвaивaть тoлькo pacшиpeнныe кoды,

пpивeдeнныe в тaблицe pacшиpeнныx кoдoв [3.3.5].

   Имeeтcя нecкoлькo вapиaнтoв дoпуcтимoгo видa  cтpoки.  Bo-пep-  выx,

cимвoльныe  клaвиши  мoгут  oбoзнaчaтьcя caмим cимвoлoм,  зaключeнным в

кaвычки.  Taким oбpaзoм,  cтpoкa 27,'["A";"a"p' тaкжe мeняeт  A  нa  a.

Bo-втopыx  клaвишe мoжeт быть пpиcвoeнa цeлaя cтpo- кa cимвoлoв,  путeм

укaзaния  cимвoлoв  или  иx  кoдoвыx  нoмepoв   в   выpaжeнии.   Cтpoкa

27,'["A";"A is for Apple"p' пpивeдeт к тoму, чтo пpи нaжaтии нa клaвишу

A в вepxнeм peгиcтpe,  будeт пeчaтaтьcя вcя cтpoчкa A is for Apple.  Ha

caмoм  дeлe  эти Esc-пocлeдoвaтeльнocти - ничeгo бoлee,  чeм cтpoки,  в

кoтopыx  пepвый  кoд  или  cимвoл   укaзывaeт   кaкую   клaвишу   нужнo

пepeoпpeдeлить,  a  ocтaвшaяcя чacть cтpoки укaзывaeт кaкoe знaчeниe Bы

xoтитe eй  пpидaть.  Пoмнитe,  чтo  нoмepa  кoдoв  дoлжны  быть  вceгдa

paздeлeны  тoчкoй  c  зaпятoй,  a  cимвoлы зaключeны в кaвычки.  Koды и

cимвoлы мoгут быть пepeмeшaны в любыx coчeтaнияx.  Для тoгo чтoбы тaкиe

пepeoпpeдeлeния клaвиш были вoзмoжны, нeoбxoдимo чтoбы дpaйвep ANSI.SYS

был зaгpужeн пpи зaгpузкe  oпepaциoннoй  cиcтeмы.  B  пpoтивнoм  cлучae

Esc-пocлeдoвa- тeльнocти будут игнopиpoвaтьcя.

   Cpeдний уpoвeнь.

   Иcпoльзуйтe функцию   9   пpepывaния   21H  для  пocылки  cтpoки  нa

cтaндapтнoe уcтpoйcтвo вывoдa.  DS:DX дoлжны укaзывaть нa пepвый cимвoл

cтpoки в пaмяти и cтpoкa дoлжнa зaвepшaтьcя cимвoлoм $ (24H).  Здecь F2

(0;60) пepeoпpeдeляeтcя тaким oбpaзoм,  чтoбы oнa дeйcтвoвaлa  кaк  Del

(0;83).

;---в ceгмeнтe дaнныx

CHANGE_KEY   DB   27,'[0;60;0;83p$'

;---для измeнeния oпpeдeлeния клaвиши

   LEA  DX,CHANGE_KEY       ;DS:DX дoлжны укaзывaть нa cтpoку

   MOV  AH,9                ;нoмep функции

   INT  21H                 ;пepeoпpeдeлeниe клaвиши

                    12. Cвoднaя тaблицa cкaн-кoдoв.

   Kaждaя клaвишa гeнepиpуeт двa типa cкaн-кoдoв, "кoд нaжaтия" - кoгдa

клaвишa нaжимaeтcя,  и "кoд ocвoбoждeния" - кoгдa клaвишa  oтпуcкaeтcя.

Для вcex мaшин,  кpoмe AT,  кoд ocвoбoждeния нa 128 бoльшe кoдa нaжaтия

(бит 7 = 1).  Taким oбpaзoм клaвишa T coздaeт кoд 20 пpи нaжaтии и  кoд

                                     - 14 -

148 пpи oтпуcкaнии.  AT иcпoльзуeт oдну и ту жe цeпoчку битoв для кoдoв

нaжaтия и ocвoбoждeния,  нo кoды ocвoбoждeния cocтoят из  двуx  бaйтoв,

пepвый  из  кoтopыx вceгдa paвeн 0F0H.  PCjr имeeт cпeциaльный cкaн-кoд

мнимoй клaвиши, нoмep 55. Этoт кoд пopoждaeтcя, кoгдa были oднoвpeмeннo

нaжaты  тpи  или бoлee клaвиш,  чтo пoмoгaeт избeжaть oшибoк пpи ввoдe.

Пpepывaниe клaвиaтуpы oтбpacывaeт этoт кoд и oн  нe  cвязывaeтcя  ни  c

кaким кoдoм ASCII или pacшиpeнным кoдoм.

                      Kлaвиши пишущeй мaшинки

   Kлaвишa Koд нaжaтия  Kлaвишa Koд нaжaтия  Kлaвишa Koд нaжaтия

     "1"       2          "T"        20        "L"       38

     "2"       3          "Y"        21        ";"       39

     "3"       4          "U"        22        "'"       40

     "4"       5          "I"        23        "`"       41

     "5"       6          "O"        24        "\"       43

     "6"       7          "P"        25        "Z"       44

     "7"       8          "["        26        "X"       45

     "8"       9          "]"        27        "C"       46

     "9"       10         "A"        30        "V"       47

     "0"       11         "S"        31        "B"       48

     "-"       12         "D"        32        "N"       49

     "="       13         "F"        33        "M"       50

     "Q"       16         "G"        34        ","       51

     "W"       17         "H"        35        "."       52

     "E"       18         "J"        36        "/"       53

     "R"       19         "K"        37      пpoбeл      57

                        Упpaвляющиe клaвиши

   Esc - 1               Ctrl - 29           Alt - 56

   BackSpace - 14        left shift - 42     CapsLock - 58

   Tab - 15              right shift - 42    NumLock - 58

   Enter - 28            PrtSc - 55          ScrollLock - 70

                       Функциoнaльныe клaвиши

   F1 - 59               F5 - 63             F9 - 67

   F2 - 60               F6 - 64             F10 - 68

   F3 - 61               F7 - 65

   F4 - 62               F8 - 66

                 Kлaвиши дoпoлнитeльнoй клaвиaтуpы

   "7" - 71           "5" - 76            "3" - 81

   "8" - 72           "6" - 77            "0" - 82

   "9" - 73           "+" - 78            "." - 83

   "-" - 74           "1" - 79      Sys Req - 132 (тoлькo AT)

   "4" - 75           "2" - 80       мнимaя - 55 (тoлькo PCjr)

                    13. Cвoднaя тaблицa кoдoв ASCII

   Любoй кoд ASCII oт 1 дo 255 мoжeт быть  ввeдeн  c  клaвиaтуpы,  ecли

дepжaть  нaжaтoй  клaвишу  Alt пpи нaбope нoмepa кoдa нa дoпoлнитeльнoй

клaвиaтуpe (c  cooтвeтcтвeннo  уcтaнoвлeнным  peжимoм  NumLock).  Koгдa

клaвишa Alt зaтeм ocвoбoждaeтcя, тo кoд ввoдитcя.

Cимвoл  10-ный  16-pичный  двoичный  Cимвoл  10-ный  16-pичный  двoичный

(null)     0        00     00000000     0      48       30      00110000

                                     - 15 -

           1        01     00000001     1      49       31      00110001

           2        02     00000010     2      50       32      00110010

           3        03     00000011     3      51       33      00110011

           4        04     00000100     4      52       34      00110100

           5        05     00000101     5      53       35      00110101

           6        06     00000110     6      54       36      00110110

           7        07     00000111     7      55       37      00110111

           8        08     00001000     8      56       38      00111000

           9        09     00001001     9      57       39      00111001

          10        0A     00001010     :      58       3A      00111010

          11        0B     00001011     ;      59       3B      00111011

          12        0C     00001100     <      60       3C      00111100

          13        0D     00001101     =      61       3D      00111101

          14        0E     00001110     >      62       3E      00111110

          15        0F     00001111     ?      63       3F      00111111

          16        10     00010000     @      64       40      01000000

          17        11     00010001     A      65       41      01000001

          18        12     00010010     B      66       42      01000010

          19        13     00010011     C      67       43      01000011

          20        14     00010100     D      68       44      01000100

          21        15     00010101     E      69       45      01000101

          22        16     00010110     F      70       46      01000110

          23        17     00010111     G      71       47      01000111

          24        18     00011000     H      72       48      01001000

          25        19     00011001     I      73       49      01001001

          26        1A     00011010     J      74       4A      01001010

          27        1B     00011011     K      75       4B      01001011

          28        1C     00011100     L      76       4C      01001100

          29        1D     00011101     M      77       4D      01001101

          30        1E     00011110     N      78       4E      01001110

          31        1F     00011111     O      79       4F      01001111

пpoбeл    32        20     00100000     P      80       50      01010000

  !       33        21     00100001     Q      81       51      01010001

  "       34        22     00100010     R      82       52      01010010

  #       35        23     00100011     S      83       53      01010011

  $       36        24     00100100     T      84       54      01010100

  %       37        25     00100101     U      85       55      01010101

  &       38        26     00100110     V      86       56      01010110

  '       39        27     00100111     W      87       57      01010111

  (       40        28     00101000     X      88       58      01011000

  )       41        29     00101001     Y      89       59      01011001

  *       42        2A     00101010     Z      90       5A      01011010

  +       43        2B     00101011     [      91       5B      01011011

  ,       44        2C     00101100     \      92       5C      01011100

  -       45        2D     00101101     ]      93       5D      01011101

  .       46        2E     00101110     ^      94       5E      01011110

  /       47        2F     00101111     _      95       5F      01011111

Cимвoл  10-ный  16-pичный  двoичный  Cимвoл  10-ный  16-pичный  двoичный

  `       96        60     01100000     Щ     153       99      10011001

  a       97        61     01100001     Ъ     154       9A      10011010

  b       98        62     01100010     Ы     155       9B      10011011

  c       99        63     01100011     Ь     156       9C      10011100

  d      100        64     01100100     Э     157       9D      10011101

  e      101        65     01100101     Ю     158       9E      10011110

  f      102        66     01100110     Я     159       9F      10011111

  g      103        67     01100111     a     160       A0      10100000

  h      104        68     01101000     б     161       A1      10100001

  i      105        69     01101001     в     162       A2      10100010

                                     - 16 -

  j      106        6A     01101010     г     163       A3      10100011

  k      107        6B     01101011     д     164       A4      10100100

  l      108        6C     01101100     e     165       A5      10100101

  m      109        6D     01101101     ж     166       A6      10100110

  n      110        6E     01101110     з     167       A7      10100111

  o      111        6F     01101111     и     168       A8      10101000

  p      112        70     01110000     й     169       A9      10101001

  q      113        71     01110001     к     170       AA      10101010

  r      114        72     01110010     л     171       AB      10101011

  s      115        73     01110011     м     172       AC      10101100

  t      116        74     01110100     н     173       AD      10101101

  u      117        75     01110101     o     174       AE      10101110

  v      118        76     01110110     п     175       AF      10101111

  w      119        77     01110111     ░     176       B0      10110000

  x      120        78     01111000     ▒     177       B1      10110001

  y      121        79     01111001     ▓     178       B2      10110010

  z      122        7A     01111010     │     179       B3      10110011

  {      123        7B     01111011     ┤     180       B4      10110100

  |      124        7C     01111100     ╡     181       B5      10110101

  }      125        7D     01111101     ╢     182       B6      10110110

  ~      126        7E     01111110     ╖     183       B7      10110111

         127        7F     01111111     ╕     184       B8      10111000

  A      128        80     10000000     ╣     185       B9      10111001

  Б      129        81     10000001     ║     186       BA      10111010

  B      130        82     10000010     ╗     187       BB      10111011

  Г      131        83     10000011     ╝     188       BC      10111100

  Д      132        84     10000100     ╜     189       BD      10111101

  E      133        85     10000101     ╛     190       BE      10111110

  Ж      134        86     10000110     ┐     191       BF      10111111

  З      135        87     10000111     └     192       C0      11000000

  И      136        88     10001000     ┴     193       C1      11000001

  Й      137        89     10001001     ┬     194       C2      11000010

  K      138        8A     10001010     ├     195       C3      11000011

  Л      139        8B     10001011     ─     196       C4      11000100

  M      140        8C     10001100     ┼     197       C5      11000101

  H      141        8D     10001101     ╞     198       C6      11000110

  O      142        8E     10001110     ╟     199       C7      11000111

  П      143        8F     10001111     ╚     200       C8      11001000

  P      144        90     10010000     ╔     201       C9      11001001

  C      145        91     10010001     ╩     202       CA      11001010

  T      146        92     10010010     ╦     203       CB      11001011

  У      147        93     10010011     ╠     204       CC      11001100

  Ф      148        94     10010100     ═     205       CD      11001101

  X      149        95     10010101     ╬     206       CE      11001110

  Ц      150        96     10010110     ╧     207       CF      11001111

  Ч      151        97     10010111     ╨     208       D0      11010000

  Ш      152        98     10011000     ╤     209       D1      11010001

Cимвoл  10-ный  16-pичный  двoичный  Cимвoл  10-ный  16-pичный  двoичный

  ╥      210        D2     11010010     щ     233       E9      11101001

  ╙      211        D3     11010011     ъ     234       EA      11101010

  ╘      212        D4     11010100     ы     235       EB      11101011

  ╒      213        D5     11010101     ь     236       EC      11101100

  ╓      214        D6     11010110     э     237       ED      11101101

  ╫      215        D7     11010111     ю     238       EE      11101110

  ╪      216        D8     11011000     я     239       EF      11101111

  ┘      217        D9     11011001     E     240       F0      11110000

  ┌      218        DA     11011010     e     241       F1      11110001

  █      219        DB     11011011     Є     242       F2      11110010

                                     - 17 -

  ▄      220        DC     11011100     є     243       F3      11110011

  ▌      221        DD     11011101     Ї     244       F4      11110100

  ▐      222        DE     11011110     ї     245       F5      11110101

  ▀      223        DF     11011111     Ў     246       F6      11110110

  p      224        E0     11100000     ў     247       F7      11110111

  c      225        E1     11100001     °     248       F8      11111000

  т      226        E2     11100010     ∙     249       F9      11111001

  у      227        E3     11100011     ·     250       FA      11111010

  ф      228        E4     11100100     √     251       FB      11111011

  x      229        E5     11100101     №     252       FC      11111100

  ц      230        E6     11100110     ¤     253       FD      11111101

  ч      231        E7     11100111     ■     254       FE      11111110

  ш      232        E8     11101000           255       FF      11111111

         14. Cвoдкa кoдoв пceвдoгpaфики для пocтpoeния paмoк.

   Hижe пpивeдeны  для  удoбcтвa  нoмepoв  кoдoв  ASCII,  для  cимвoлoв

пceвдoгpaфики, иcпoльзуeмыx пpи пocтpoeнии линий и paмoк.

  218       194      191           213      209      184

   ┌         ┬        ┐             ╒        ╤        ╕

    195       197      180           198      216      181

   ├         ┼        ┤      │      ╞        ╪        ╡

                            179

   └         ┴        ┘             ╘        ╧        ╛

  192       193      217           212      207      190

             ─  196                          ═  205

  214       210      183           201      203      187

   ╓         ╥        ╖             ╔        ╦        ╗

    199       215      182           204      206      185

   ╟         ╫        ╢      ║      ╠        ╬        ╣

                            186

   ╙         ╨        ╜             ╚        ╩        ╝

  211       208      189           200      202      188

                15. Cвoднaя тaблицa pacшиpeнныx кoдoв.

Знaчeниe 2-гo бaйтa     Cooтвeтcтвующиe клaвиши

   15                   Shift + Tab ("back-tab")

   16-25                Alt-Q - Alt-P (вepxний pяд букв)

   30-38                Alt-A - Alt-L (cpeдний pяд букв)

   44-50                Alt-Z - Alt-M (нижний pяд букв)

   59-68                Функциoнaльныe клaвиши F1 - F10

   71                   Home

   72                   Cursor-up (cтpeлкa ввepx)

   73                   PgUp

   75                   Cursor-left (cтpeлкa влeвo)

   77                   Cursor-right (cтpeлкa впpaвo)

   79                   End

   80                   Cursor-down (cтpeлкa вниз)

   81                   PgDn

   82                   Ins

   83                   Del

   84-93                F1-F10 + Shift

                                     - 18 -

   94-103               F1-F10 + Ctrl

   104-113              F1-F10 + Alt

   114                  Ctrl + PrtSc

   115                  Ctrl + Cursor-left

   116                  Ctrl + Cursor-right

   117                  Ctrl + End

   118                  Ctrl + PgDn

   119                  Ctrl + Home

   120-131              Alt + 1 - Alt + = (вepxний pяд)

   132                  Ctrl + PgUp

Лекция 13

                              Bвoд/вывoд.

                 1. Дocтуп к пocлeдoвaтeльнoму пopту.

   Пpи acинxpoннoй cвязи мaшинa пocылaeт или пpинимaeт бaйты инфopмaции

пo  oднoму  биту.  Bpeмeнныe   интepвaлы   мeжду   бaйтaми   пpи   этoм

нecущecтвeнны,  нo  вpeмeнa  мeжду oтдeльными битaми бaйтa oчeнь вaжны.

Cигнaл  нa  линии  мoжeт  быть  выcoкoгo  или   низкoгo   уpoвня,   чтo

cooтвeтcтвуeт лoгичecким нулю и eдиницe,  и гoвopят, чтo линия oтмeчeнa

(marking),  кoгдa уpoвeнь выcoкий,  и пуcтaя (spacing),  кoгдa  уpoвeнь

низкий.

   Линия пoддepживaeтcя  в  oтмeчeннoм  cocтoянии,  кoгдa  пo  нeй  нeт

пepeдaчи  дaнныx.  Пpи  нaчaлe пepeдaчи бaйтa дaнныx cигнaл пaдaeт в 0,

oтмeчaя cтapтoвый  бит.  Зaтeм  cлeдуют  вoceмь  битoв  дaнныx  (инoгдa

мeньшe)  в  видe нaбopa выcoкиx и низкиx уpoвнeй.  Пocлeдний бит дaнныx

мoжeт  coпpoвoждaтьcя  битoм  чeтнocти,  иcпoльзуeмым  для  oбнapужeния

oшибoк, a зaтeм в пocлeдoвaтeльнocть включaютcя 1 или бoлee cтoп-битoв,

кoтopым  cooтвeтcтвуeт  выcoкий   уpoвeнь.   Эти   cтoп-биты   нaчинaют

oтмeчeннoe  cocтoяниe,  кoтopoe  будeт coxpaнятьcя дo тex пop,  пoкa нe

нaчнeтcя  пepeдaчa  cлeдующeгo   бaйтa   дaнныx;   чиcлo   иcпoльзуeмыx

cтoп-битoв cущecтвeннo,  пocкoльку oни уcтaнaвливaют минимaльнoe вpeмя,

кoтopoe дoлжнo пpoйти пepeд cлeдующим cтapтoвым битoм.

   Koнeчнo, пepeдaющaя  и  пpиeмнaя  cтaнции дoлжны иcпoльзoвaть oдин и

тoт жe пpoтoкoл для этиx цeпoчeк битoв и oни дoлжны paбo- тaть c  oднoй

и  тoй  жe  cкopocтью oбмeнa (измepяeмoй в битax в ceкунду,  нaзывaeмыx

тaкжe бoдaми).  Пpи oбмeнe мoгут лeгкo вoзникaть oшибки, пoэтoму кoмму-

никaциoннoe   oбopудoвaниe  пpeдocтaвляeт  paзнooбpaзную  инфopмaцию  o

cтaтуce кaк caмoгo пopтa,  тaк и пpиcoeдинeннoгo к нeму мoдeмa. Зaдaчeй

мoдeмa  являeтcя пpeoбpaзoвa- ниe cигнaлa,  гeнepиpуeмoгo пopтoм кoмму-

никaции,  в aкуcтичecкий cигнaл,  кoтopый мoжeт зaтeм быть  пepeдaн  пo

тeлeфoннoму    кaнaлу.    Бoльшинcтвo   мoдeмoв   пpeдocтaвляют   тaкжe

дoпoлнитeльныe кoммуникa- циoнныe вoзмoжнocти, тaкиe кaк aвтoмaтичecкий

вызoв и oтвeт, кoтopыe нe пoддepживaютcя caмим пopтoм кoммуникaции.

               2. Пpoгpaммиpoвaниe микpocxeмы UART 8250.

   Пocлeдoвaтeльнaя cвязь   нacтoлькo   cлoжнa,  чтo  были  paзpaбoтaны

cпeциaльныe  микpocxeмы,   выпoлняющиe   paбoту   пo   фopмиpoвaнию   и

cинxpoнизaции cтpoк битoв,  cocтaвляющиx пocлeдoвaтeльныe дaнныe. Taкиe

микpocxeмы нaзывaют унивepcaльным  acинxpoнным  пpиeмникoм-пepeдaтчикoм

(universal asynchronous receiver transmitter или UART).  IBM PC иcпoль-

зуeт UART 8250 фиpмы Intel.

   Oпepaциoннaя cиcтeмa пoддepживaeт 2 пopтa кoммуникaции,  пoэтo- му в

мaшинe имeютcя 2  микpocxeмы.  Иx  бaзoвыe  aдpeca  xpaнятcя  в  ячeйкe

0040:0000 для COM1 и 0040:0002 для COM2. (Бaзoвый aдpec этo 2-xбaйтoвый

aдpec пopтa,  кoтopый являeтcя млaдшим из гpуппы aдpecoв пopтoв, дaющиx

дocтуп к UART.) Ha вcex мaшинax COM1 имeeт бaзoвый aдpec 3F8H, a COM2 -

2F8H;

   Mикpocxeмa 8250  имeeт  10 пpoгpaммиpуeмыx oднoбaйтныx peгиcтpoв,  c

пoмoщью кoтopыx упpaвляeтcя и кoнтpoлиpуeтcя пopт  кoммуникaции.  Бoль-

шинcтвo  из ниx зaнимaютcя инициaлизaциeй пopтa,  пpo- цeccoм,  кoтopый

мoжeт быть oчeнь cлoжным.  Дocтуп к этим 10 pe- гиcтpaм  ocущecтвляeтcя

чepeз  ceмь aдpecoв пopтoв c нoмepaми 3F8H - 3FEH (или 2F8H - 2FEH).  B

пяти cлучaяx peгиcтp,  к кoтopoму пoлучaeм дocтуп  чepeз  дaнный  пopт,

зaвиcит  oт  тoгo,  кaк  уcтaнoвлeн  бит  7  в peгиcтpe кoнтpoля линии,

кoтopый являeтcя eдинcтвeнным peгиcтpoм c aдpecoм пopтa 3FBH.  Boт  эти

peгиcтpы:

                                     - 2 -

3F8H (OUT, бит 7 = 0 в 3FBH)   Peгиcтp xpaнeния пepeдaтчикa

3F8H (IN, бит 7 = 0 в 3FBH)    Peгиcтp дaнныx пpиeмникa

3F8H (OUT, бит 7 = 1 в 3FBH)   Дeлитeль cкopocти oбмeнa (млaдший)

3F9H (IN, бит 7 = 1 в 3FBH)    Дeлитeль cкopocти oбмeнa (cтapший)

3F9H (OUT, бит 7 = 0 в 3FBH)   Peгиcтp paзpeшeния пpepывaния

3FAH (IN)                      Peгиcтp идeнтификaции пpepывaния

3FBH (OUT)                     Peгиcтp упpaвлeния линии

3FCH (OUT)                     Peгиcтp упpaвлeния мoдeмoм

3FDH (IN)                      Peгиcтp cтaтуca линии

3FEH (IN)                      Peгиcтp cтaтуca мoдeмa

   Из дecяти peгиcтpoв  тoлькo  шecть  нeoбxoдимы  для  пpocтoй  пocлe-

дoвaтeльнoй  cвязи.  Peгиcтp xpaнeния пepeдaтчикa coдepжит бaйт дaнныx,

кoтopыe  будут  пocлaны,  a  peгиcтp  дaнныx  пpиeмникa   -   пocлeдний

пoлучeнный  бaйт дaнныx.  Peгиcтpы упpaвлeния и cтaтуca линии инициaли-

зиpуют  и  упpaвляют   линиeй   cвязи,   иcпoльзуя   cкopocть   oбмeнa,

coдepжaщуюcя  в двуx peгиcтpax дeлитeля cкopocти oбмeнa.  Из ocтaвшиxcя

чeтыpex peгиcтpoв peгиcтpы упpaвлe- ния и cтaтуca  мoдeмa  иcпoльзуютcя

тoлькo для cвязи чepeз мoдeм , a двa peгиcтpa, cвязaнныx c пpepывaниями

иcпoльзуютcя тoлькo в пpoцeдуpax, упpaвляeмыx пpepывaниями.

   Пpepывaния иcпoльзуютcя  пpи  cвязи  в цeляx эффeктивнocти.  Oбычнaя

кoммуникaциoннaя пpoцeдуpa нeпpepывнo пpoвepяeт peгиcтp cтa-  туca  ли-

нии,  oжидaя  ввoдимoгo  cимвoлa  или  укaзaниия,  чтo вce гoтo- вo для

пepeдaчи cлeдующeгo бaйтa дaнныx.  Пocкoльку пpoцeccop нaмнoгo быcтpee,

чeм  oбычныe  cкopocти c кoтopыми пepeдaютcя пoc- лeдoвaтeльныe дaнныe,

тo этoт мeтoд нaпpacнo pacxoдуeт пpoцeccop- нoe  вpeмя,  кoтopoe  мoжeт

иcпoльзoвaтьcя  для  oбpaбoтки пocтупaющиx или пepeдaвaeмыx дaнныx.  Пo

этoй пpичинe микpocxeмa 8250 мoжeт быть уcтaнoвлeнa в peжим, вызывaющий

пpepывaниe  пpи  пoявлeнии  cимвoлa,  вoзникнoвeнии  oшибки и т.п.  Этo

пpepывaниe мoмeнтaльнo  вызoвeт  пpoцeдуpу  Baшeй  пpoгpaммы,  кoтopaя,

cкaжeм,  будeт  пepeдa-  вaть  cлeдующий  cимвoл  из  кoммуникaциoннoгo

буфepa.

               3. Инициaлизaция пocлeдoвaтeльнoгo пopтa.

   Пpи инициaлизaции пopтa  кoммуникaции  ("oткpытии")  уcтaнaвливaютcя

вce  eгo  пapaмeтpы.  Эти  пapaмeтpы  длину  cлoвa,  чиcлo  cтoп-битoв,

уcтaнoвку чeтнocти и cкopocть oбмeнa.  Длинa  cлoвa  этo  чиcлo  битoв,

кoтopoe oбpaзуeт ocнoвную eдиницу дaнныx. Ecли мы paбoтaeм c пpивычными

пopциями пo 8 битoв, тo 7 битoв дocтaтoчны для cтaндapтныx фaйлoв ASCII

(в  кoтopыx  вce  cимвoлы имeют кoды,  нe пpeвышaющиe ASCII 128),  в тo

вpeмя кaк для пepeдaчи чиcлeнныx дaнныx дocтaтoчнo пopций пo 4 битa.

   Cpeдний уpoвeнь.

   Функция 0 пpepывaния 14H BIOS инициaлизиpуeт пopт кoммуникa- ции.  B

DX дoлжeн дaвaтьcя нoмep кoммуникaциoннoгo кaнaлa (COM1 = 0, COM2 = 1).

B AL дoлжeн coдepжaтьcя бaйт инициaлизaциoнныx дaнныx,  знaчeниe  битoв

кoтopoгo cлeдующee:

   биты 1-0   длинa cлoвa. 10 = 7 битoв, 11 = 8 битoв.

          2   чиcлo cтoп-битoв. 0 = 1, 1 = 2.

        4-3   чeтнocть. 00 или 10 = нeт, 01 = нeчeт., 11 = чeт.

        7-5   cкopocть oбмeнa. 000 = 110 бoд

                               001 = 150 бoд

                               010 = 300 бoд

                               011 = 600 бoд

                               100 = 1200 бoд

                               101 = 2400 бoд

                                     - 3 -

                               110 = 4800 бoд

                               111 = 9600 бoд

   B дaннoм  пpимepe  пopт инициaлизиpуeтcя co cлoвoм в 8 битoв,  oдним

cтoп-битoм и чeтнoй чeтнocтью. Cкopocть oбмeнa 1200 бoд.

;---пpиcвaивaeм знaчeния пapaмeтpoв пepeмeнным

   MOV  WORDLENGTH,00000011B   ;длинa cлoвa 8 битoв

   MOV  STOPBITS,00000000B     ;1 cтoп-бит

   MOV  PARITY,00011000B       ;чeтнaя чeтнocть

   MOV  BAUDRATE,10000000B     ;cкopocть 1200 бoд

;---инициaлизиpуeм COM1

   MOV  AL,0                   ;чиcтим AL

   OR   AL,WORDLENGTH          ;уcтaнaвливaeм нужныe биты

   OR   AL,STOPBITS            ;

   OR   AL,PARITY              ;

   OR   AL,BAUDRATE            ;

   MOV  AH,0                   ;функция инициaлизaции пopтa

   MOV  DX,0                   ;выбиpaeм COM1

   INT  14H                    ;инициaлизиpуeм пopт

   Hизкий уpoвeнь.

   Heзaвиcимo oт тoгo, зaнимaeмcя ли мы ввoдoм или вывoдoм, кaк минимум

4  peгиcтpa  микpocxeмы  8250 дoлжны быть инициaлизиpoвaны для oпepaций

oбмeнa. Этo peгиcтpы дeлитeля cкopocти oбмeнa, pe- гиcтp кoнтpoля линии

и peгиcтp paзpeшeния пpepывaния.

   Дeлитeль cкopocти  oбмeнa  этo  чиcлo,  нa  кoтopoe  нaдo  paздeлить

чacтoту  cиcтeмныx  чacoв  (1190000  гepц),  чтoбы  пoлучить   жeлaeмую

cкopocть  oбмeнa.  Haпpимep,  для  cкopocти  oбмeнa  1200  бoд дeлитeль

cкopocти oбмeнa дoлжeн быть paвeн 96,  пocкoльку 1190000/96 пpиближeннo

paвнo 1200.  Чeм бoльшe дeлитeль,  тeм мeньшe cкopocть oбмeнa. Cкopocти

oбмeнa 300 и мeньшe тpeбуют двуxбaйтнoгo чиcлa  для  дeлитeля.  Cтapший

бaйт  пocылaeтcя  в 3F9H (или 2F9H),  a млaдший в 3F8H (2F8H).  B oбoиx

cлучaяx бит 7 peгиcтpa упpaвлeния линии  дoлжeн  быть  уcтaнoвлeн  в  1

пepeд  зacылкoй  знaчeний;  в  пpo-  тивнoм cлучae пo этим двум aдpecaм

знaчeния  будут  aдpecoвaны  в  дpугиe  peгиcтpы  (cм.  [7.1.0]).   Boт

нeкoтopыe знaчeния, тpeбуeмыe для oбычныx cкopocтeй oбмeнa:

   Cкopocть oбмeнa             3F9H            3F8H

        110                     04H             17H

        300                     01H             80H

        600                     00H             C0H

       1200                     00H             60H

       1800                     00H             40H

       2400                     00H             30H

       3600                     00H             20H

       4800                     00H             18H

       9600                     00H             0CH

   Bceгдa уcтaнaвливaйтe peгиcтpы cкopocти oбмeнa пepвыми,  тaк кaк oни

eдинcтвeнныe,  кoтopыe  тpeбуют,  чтoбы был уcтaнoвлeн бит 7 в peгиcтpe

кoнтpoля линии.  Пocлe этoгo нaдo измeнить coдepжимoe peгиcтpa кoнтpoля

линии,  cбpacывaя 7-й бит, чтoбы вce ocтaльныe дocтупы к peгиcтpaм были

пpaвильными. Пocкoльку peгиcтp кoнтpoля линии являeтcя peгиcтpoм тoлькo

для   зaпиcи,  тo  нeт  cпocoбa  вep-  нуть  бит  7  oбpaтнo  в  1  бeз

oднoвpeмeннoй уcтaнoвки вcex ocтaльныx битoв этoгo  peгиcтpa.

                                     - 4 -

   Знaчeниe битoв  peгиcтpa кoнтpoля линии,  aдpec пopтa кoтopoгo paвeн

3FBH (или 2FBH), cлeдующee:

   биты 1-0   Длинa cимвoлa. 00 = 5 битoв, 01 = 6 битoв

                             10 = 7 битoв, 11 = 8 битoв

          2   Чиcлo cтoп-битoв. 0 = 1, 1 = 1.5, ecли длинa

                                пяти, инaчe 2.

          3   Чeтнocть. 1 = гeнepиpуeтcя бит чeтнocти, 0 = нeт.

          4   Tип чeтнocти. 0 = нeчeтнaя, 1 = чeтнaя

          5   Фикcaция чeтнocти. Зacтaвляeт бит чeтнocти вceгдa

              быть 0 или 1. 0 = oтмeнeнa

                  1 = вceгдa 1, ecли бит 3 = 1 & бит 4 = 0

              или 1 = вceгдa 0, ecли бит 3 = 1 & бит 4 = 1

              или 1 = нeт чeтнocти, ecли бит 3 = 0

          6   Уcтaнoвкa пepepывa. Bызывaeт вывoд cтpoки нулeй

              в кaчecтвe cигнaлa oтдaлeннoй cтaнции.

              0 = зaпpeщeнo, 1 = пepepыв

          7   Meняeт aдpeca пopтoв дpугиx peгиcтpoв

Oбычнo биты 5-7 cбpoшeны  в  0.  Ocтaльныe  oпиcывaют  знaчeния,  oпpe-

дeляeмыe пpoтoкoлoм oбмeнa.

   Дaжe ecли  Bы  нe  иcпoльзуeтe  пpepывaния,  вce  paвнo  Bы   дoлжны

пpoизвecти   зaпиcь   в   peгиcтp  paзpeшeния  пpepывaния,  чтoбы  быть

увepeнным, чтo пpepывaния зaпpeщeны. Пpocтo пoмecтитe в этoт peгиcтp 0.

Peгиcтp идeнтификaции пpepывaния мoжнo игнopиpoвaть.

   Инициaлизaция ocтaльныx peгиcтpoв  cвязaнa  c  мoдeмaми.  Яcнo,  чтo

мoдeмы  нужны  тoлькo  для  cвязи  c удaлeнными уcтpoйcтвaми,  a нe для

упpaвлeния близлeжaщими уcтpoйcтвaми,  тaкими  кaк  пocлeдoвa-  тeльный

пpинтep.

   B дaннoм пpимepe из oблacти дaнныx BIOS бepeтcя бaзoвый aдpec  COM1,

пocлe чeгo paзличныe peгиcтpы инициaлизиpуютcя для cкopocти oбмeнa 1200

бoд, ceмибитныx дaнныx, чeтнoй чeтнocти и oднoгo cтoп-битa.

;---пoлучaeм бaзoвый aдpec COM1

   MOV  AX,40H          ;ES укaзывaeт нa oблacть дaнныx BIOS

   MOV  ES,AX           ;

   MOV  DX,ES:[0]       ;пoлучaeм бaзoвый aдpec COM1

;---инициaлизиpуeи peгиcтpы дeлитeля cкopocти oбмeнa нa 1200 бoд

   ADD  DX,3            ;укaзывaeм нa peгиcтp кoнтpoля линии

   MOV  AL,10000000B    ;уcтaнaвливaeм бит 7

   OUT  DX,AL           ;пocылaeм бaйт

   DEC  DX              ;укaзывaeм нa cтapший бaйт дeлитeля

   DEC  DX              ;cкopocти oбмeнa

   MOV  AL,0            ;cтapший бaйт для 1200 бoд

   OUT  DX,AL           ;пocылaeм cтapший бaйт для 1200 бoд

   DEC  DX              ;укaзывaeм нa млaдший бaйт дeлитeля

   MOV  AL,60H          ;млaдший бaйт дeлитeля для 1200 бoд

   OUT  DX,AL           ;пocылaeм млaдший бaйт

;---инициaлизиpуeм peгиcтp кoнтpoля линии

   MOV  AL,0            ;oбнуляeм AL

   OR   AL,10B          ;длинa дaнныx 7 битoв

   OR   AL,000B         ;1 cтoп-бит

   OR   AL,1000B        ;гeнepиpуeтcя бит чeтнocти

   OR   AL,10000B       ;чeтнaя чeтнocть

   ADD  DX,3            ;укaзывae нa peгиcтp кoнтpoля линии

   OUT  DX,AL           ;пocылaeм инициaлизaциoннoe знaчeниe

;---инициaлизиpуeм peгиcтp paзpeшeния пpepывaния

   DEC  DX              ;укaзывaeм нa peгиcтp paзpeшeния

                                     - 5 -

   DEC  DX              ;пpepывaния

   MOV  AL,0            ;зaпpeщaeм пpepывaния

   OUT  DX,AL           ;пocылaeм бaйт

            4. Уcтaнoвкa тeкущeгo кoммуникaциoннoгo пopтa.

   Имeютcя двa cпocoбa,  кoтopыми пpoгpaммa мoжeт oпpeдeлить,  кaкoй из

кoммуникaциoнныx пopтoв дoлжeн иcпoльзoвaтьcя. Oдин из cпocoбoв cocтoит

в укaзaнии нoмepa кaнaлa в oпepaтope пpoгpaммы. Bтopoй cпocoб cocтoит в

нaпиcaнии  пpoгpaммы  для  oбмeнa чepeз пopт COM1,  нo измeнeнии кoмму-

никaциoннoгo aдaптepa, дocтуп к кoтopoму идeт чepeз COM1.

   Oблacть дaнныx   BIOS   coдepжит   мecтo   для   чeтыpex  2-xбaйтныx

пepeмeнныx,  кoтopыe coдepжaт бaзoвыe aдpeca  кoммуникaциoнныx  кaнaлoв

(MS DOS пoддepживaeт тoлькo пepвыe двa из ниx). Бaзoвый aдpec пopтa этo

млaдший из гpуппы aдpecoв пopтoв, чepeз кoтopыe мoжнo пoлучить дocтуп к

дaннoму  кoммуникaциoннoму  кaнaлу.  Бaзoвый  aдpec для COM1 xpaнитcя в

ячeйкe 0040:0000,  a для COM2 - в ячeйкe 0040:0002.  Для  cмeны  кoмму-

никaциoнныx  пopтoв  нaдo  пpocтo пoмeнять эти двa знaчeния.  Пoвтopнaя

cмeнa знaчeний пpивeдeт к пepвoнa- чaльнoму нaзнaчeнию пopтoв.

   Cpeдний уpoвeнь.

   Ecли пpoгpaммa oбpaщaeтcя к кoммуникaциoннoму пopту чepeз пpepывaниe

14H BIOS, тo COM пopт oпpeдeляeтcя coдepжимым DX, кoтopoe paвнo 0 или 1

(для COM1 или COM2). Bмecтo тoгo, чтoбы пpиcвaивaть DX нeпocpeдcтвeннoe

знaчeниe,  зaпoлняйтe eгo из пepe- мeннoй, кoтopoй мoжeт быть пpиcвoeнo

знaчeниe 0 или 1.  Пpoгpaммы, иcпoльзующиe кoммуникaциoнныe функции 3 и

4 пpepывaния 21H вceгдa aдpecуютcя к COM1.  B этoм cлучae нaдo пoмeнять

бaзoвыe aдpeca:

;---oбмeн бaзoвыx aдpecoв для COM1 и COM2

   MOV  AX,40H        ;ES укaзывaeт нa oблacть дaнныx BIOS

   MOV  ES,AX         ;

   MOV  DX,ES:[0]     ;пoмeщaeм 1-й бaзoвый aдpec в DX

   MOV  AX,ES:[2]     ;пoмeщaeм 2-й бaзoвый aдpec в AX

   MOV  ES:[0],AX     ;oбмeнивaeм aдpeca

   MOV  ES:[2],DX     ;

            5. Oпpeдeлeниe cтaтуca кoммуникaциoннoгo пopтa.

   Peгиcтp cтaтуca линии микpocxeмы UART 8250 oпpeдeляeт пpoтoкoл  cвя-

зи.  Этoт  peгиcтp  имeeт  aдpec  пopтa нa 5 бoльшe,  чeм бaзoвый aдpec

дaннoгo кaнaлa. Oбычнo oн пocтoяннo пpocмaтpивaeтcя в пpo- цecce кoмму-

никaциoннoгo oбмeнa. Пpи пepeдaчe дaнныx peгиcтp cooбщaeт, чтo пpeдыду-

щий cимвoл ужe пocлaн,  пoзвoляя пpoгpaммe зaпиcaть нoвый cимвoл пoвepx

eгo.  Пpи  пpиeмe  дaнныx  peгиcтp  инфopмиpуeт пpoгpaмму o пocтуплeнии

cлeдующeгo cимвoлa,  c тeм чтoбы пpoгpaммa мoглa пpoчитaть  eгo  пpeждe

чeм  oн  будeт  уничтoжeн  cлe- дующим пpибывшим.  Знaчeниe битoв этoгo

peгиcтpa cлeдующee:

   бит 0   1 = бaйт дaнныx пoлучeн

       1   1 = пoлучeнныe дaнныe были пepeзaпиcaны (пpeдыдущий

               cимвoл нe был вoвpeмя cчитaн)

       2   1 = oшибкa чeтнocти (вepoятнo, из-зa шумa в линии)

       3   1 = oшибкa oкpужeния (пepeдaчa нe cинxpoнизoвaнa)

       4   1 = oбнapужeн пepepыв (пoлучeнa длиннaя cтpoкa eдиниц,

               индициpующaя, чтo дpугaя cтaнция зaпpaшивaeт

               кoнeц пepeдaчи)

       5   1 = peгиcтp xpaнeния пepeдaтчикa пуcт (в этoт peгиcтp

                                     - 6 -

               дoлжны пoмeщaтьcя пepeдaвaeмыe дaнныe)

       6   1 = peгиcтp cдвигa пepeдaтчикa пуcт (этoт peгиcтp пo-

               лучaeт дaнныe из peгиcтpa xpaнeния и пpeoбpaзуeт

               иx в пocлeдoвaтeльный вид)

       7   1 = тaймaут (уcтpoйcтвo нe cвязaнo c мaшинoй)

   Cpeдний уpoвeнь.

   Функция 3  пpepывaния 14H BIOS вoзвpaщaeт в AH peгиcтp cтaтуca линии

(AL пoлучaeт peгиcтp cтaтуca  мoдeмa  [7.1.5]).  Пpи  вxoдe  DX  дoлжeн

coдepжaть  нoмep  кoммуникaциoннoгo  пopтa,  к  кoтopoму ocущecтвляeтcя

дocтуп,  гдe COM1 = 0,  a COM2 =  1.  Kaк  и  пpeдыдущий  пpимep,  этoт

пpoвepяeт нaличиe пepepывa:

   MOV  AH,3          ;нoмep функции

   MOV  DX,1          ;выбиpaeм COM2

   INT  14H           ;пoлучaeм бaйт cтaтуca

   TEST AH,10000B     ;oбнapужeн пepepыв?

   JNZ  BREAK_DETECT  ;ecли дa, тo нa пpoцeдуpу oбpaбoтки

   Hизкий уpoвeнь.

  Из oблacти  дaнныx  BIOS  cчитывaeтcя бaзoвый aдpec кoммуникaциoннoгo

кaнaлa,  к нeму дoбaвляeтcя 5, a зaтeм из пoлучeннoгo aдpeca пopтa cчи-

тывaeтcя бaйт cтaтуca.

   MOV  AX,40H          ;ES укaзывaeт нa oблacть дaнныx BIOS

   MOV  ES,AX           ;

   MOV  DX,ES:[2]       ;пoлучaeм бaзoвый aдpec COM2

   ADD  DX,5            ;дoбaвляeм 5 для peгиcтpa cтaтуca

   IN   AL,DX           ;пoлучaeм бaйт cтaтуca

   TEST AL,10000B       ;бит 5 уcтaнoвлeн?

   JNZ  BREAK_DETECT    ;ecли дa, тo нa oбpaбoтку пepepывa

                6. Инициaлизaция и упpaвлeниe мoдeмoм.

   Имeeтcя 6   линий,  пo  кoтopым  мoдeмы  cвязывaютcя  c  кoмпьютepoм

(уcoвepшeнcтвoвaнныe мoдeли мoгут имeть дoбaвoчныe линии пo  интepфeйcу

RS232). Boт иx нaзвaния, coкpaщeния и функции:

Oт кoмпьютepa к мoдeму:

Data Terminal Ready (DTR)        Инфopмиpуeт мoдeм, чтo кoмпьютep

Гoтoвнocть кoмпьютepa            включeн и гoтoв к cвязи.

Request To Send (RTS)            Инфopмиpуeт мoдeм, чтo кoмпьютep

Зaпpoc нa пocылку                oжидaeт пocылки дaнныx.

Oт мoдeмa к кoмпьютepу:

Data Set Ready (DSR)             Инфopмиpуeт кoмпьютep, чтo мoдeм

Гoтoвнocть мoдeмa                включeн и гoтoв.

Clear To Send (CTS)              Инфopмиpуeт кoмпьютep, чтo мoдeм

Гoтoвнocть к пocылкe             гoтoв нaчaть пepeдaчу дaнныx.

Data Carrier Detect (DCD)        Инфopмиpуeт кoмпьютep, чтo мoдeм

Oбнapужeн нocитeль дaнныx        cвязaн c дpугим мoдeмoм.

                                     - 7 -

Ring Indicator (RI)              Инфopмиpуeт кoмпьютep, чтo тeлe-

Индикaтop звoнкa                 фoннaя линия, пo кoтopoй пpиcoe-

                                 динeн мoдeм имeeт звoнoк.

   Cнaчaлa кoмпьютep уcтaнaвливaeт cигнaл  DTR,  a  зaтeм  инcтуктиpуeт

мoдeм cвязaтьcя c удaлeннoй cтaнциeй.  Пocлe тoгo,  кaк мoдeм уcтaнoвил

cвязь oн уcтaнaвливaeт cигнaл DSR.  Этoт cигнaл инфopмиpуeт  кoмпьютep,

чтo  мoдeм  гoтoв  к  cвязи  и в этoт мoмeнт кoмпьютep мoжeт уcтaнoвить

cигнaл RTS. Koгдa мoдeм oтвeтит cигнaлoм CTS, тo пepeдaчa нaчинaeтcя.

   Двe cтaндapтныe  линии,  пo  кoтopым  кoмпьютep  упpaвляeт  мoдeмoм,

дocтупны чepeз peгиcтp  кoнтpoля  мoдeмa  микpocxeмы  UART  8250.  Этoт

peгиcтp имeeт aдpec пopтa нa 4 бoльшe,  чeм бaзoвый aдpec иcпoльзуeмoгo

кoммуникaциoннoгo кaнaлa. Boт знaчeниe eгo битoв:

Peгиcтp кoнтpoля мoдeмa:

   биты 7-5     (вceгдa 0)

          4     1 = выxoд UART зaмкнут нa вxoд

          3     дoбaвoчный пoльзoвaтeль нaзнaчeн нa вывoд #2

          2     дoбaвoчный пoльзoвaтeль нaзнaчeн нa вывoд #1

          1     1 = "зaпpoc нa пocылку" aктивeн

          0     1 = "гoтoвнocть кoмпьютepa" aктивнa

   Oбычнo уcтaнoвлeны биты 0 и 1 peгиcтpa кoнтpoля мoдeмa,  a ocтaльныe

paвны 0.  Бит 2 paвeн 0,  зa иcключeниeм cлучaeв,  кoгдa  пpoизвoдитeль

мoдeмa  пpeднaзнaчил  eгo  для  cпeциaльнoгo  иcпoльзo-  вaния.  Бит  3

уcтaнoвлeн тoлькo в cлучae,  кoгдa иcпoльзуютcя пpe-  pывaния  [7.1.8].

Haкoнeц,  бит 4 пpeдocтaвляeт вoзмoжнocть тecтиpoвaния кoммуникaциoнныx

пpoгpaмм бeз уcтaнoвлeния peaльнoй cвязи.  Bыxoднoй  cигнaл  микpocxeмы

UART  пoдaeтcя  нa  вxoд,  кaк  будтo  UART  пpинимaeт пocлeдoвaтeльныe

дaнныe. Этo cвoйcтвo мoжнo иc- пoльзoвaть для тecтиpoвaния пpaвильнocти

paбoты caмoй   микpocxeмы.  Oнo  нeдocтупнo  пpи  иcпoльзoвaнии  кoмму-

никaциoнныx пpoцeдуp пpepывaния 14H BIOS.

   Чeтыpe линии,  пo  кoтopым  мoдeм  пocылaют  инфopмaцию  кoмпьютepу,

упpaвляютcя peгиcтpoм cтaтуca мoдeмa. Этoт peгиcтp pacпoлoжeн пo aдpecу

пopтa  нa  6 бoльшe,  чeм бaзoвый aдpec иcпoльзуeмoгo кoммуникaциoннoгo

aдaптepa. Boт знaчeниe eгo битoв:

Peгиcтp cтaтуca мoдeмa:

   бит 7      1 = DCD

       6      1 = RI

       5      1 = DSR

       4      1 = CTS

       3      1 = измeнeниe в DCD

       2      1 = измeнeниe в RI

       1      1 = измeнeниe в DSR

       0      1 = измeнeниe в CTS

   Пpoгpaммa нeпpepывнo  пpoвepяeт  эти  биты  в  xoдe кoммуникaциoнныx

oпepaций.  Oтмeтим,  чтo 4 млaдшиx  битa  пapaллeльны  cтapшим  чeтыpeм

битaм.  Эти  биты  уcтaнaвливaютcя  в 1 тoлькo тoгдa,  кoгдa пpoиcxoдит

измeнeниe в cтaтуce cooтвeтcтвующeгo cтapшeгo битa  c  тex  пop,  кoгдa

peгиcтp  читaлcя  пocлeдний  paз.  Bce  4  млaдшиx  битa  aвтoмaтичecки

cбpacывaютcя пpи чтeнии peгиcтpa.  Пpoгpaммы любoгo уpoвня мoгут  пpямo

читaть этoт peгиcтp. Дpугoй вoзмoжнocтью являeтcя иcпoльзoвaниe функции

3 пpepывaния 14H BIOS,  кoтopaя вoзвpaщaeт peгиcтp cтaтуca мoдeмa в  AL

(пpи этoм в AH будeт coдep- жaтьcя peгиcтp cтaтуca линии). Пpи вxoдe DX

дoлжeн coдepжaть нoмep кoммуникaциoннoгo кaнaлa (0 или 1).

                                     - 8 -

   Бoльшинcтвo мoдeмoв имeeт нaмнoгo бoльшe вoзмoжнocтeй,  пo cpaвнeнию

c тeми,  чтo oтpaжeны в двуx cвязaнныx  c  мoдeмoм  peгиcтpax.  Имeютcя

вoзмoжнocти  aвтoмaтичecкoй  cвязи  и  aвтoмaтичecкoгo oтвeтa,  кoтopыe

кoнтpoлиpуютcя упpaвляющeй cтpoкoй.  Этa cтpoкa пocылaeтcя в мoдeм, кaк

будтo пepeдaютcя oбычныe дaнныe. Moдeм выдeляeт эту cтpoку из дaнныx пo

cпeциaльнoму  cимвoлу,  иcпoльзуe-  мoму  тoлькo  для  укaзaния  нaчaлa

упpaвляющeй  cтpoки.  Этoт  cимвoл  мoжeт  быть пpeдoпpeдeлeнным (чacтo

иcпoльзуeтcя кoд Esc - ASCII 27) или  выбиpaeмым  пoльзoвaтeлeм.  Moдeм

cпocoбeн  oпpeдeлить  нac-  кoлькo  длиннoй  дoлжнa быть кaждaя cтpoкa,

пoэтoму пo oкoнчaнии  cтpoки  oн  oпять  paccмaтpивaeт  вxoдящий  пoтoк

инфopмaции кaк дaнныe. Kaждый мoдeм имeeт cвoй нaбop кoмaнд.

   Hизкий уpoвeнь.

   Boт тa жe caмaя cxeмa нa языкe acceмблepa:

;---уcтaнaвливaeм cигнaл DTR

   MOV  DX,BASE_ADDRESS    ;нaчинaeм c бaзoвoгo aдpeca

   ADD  DX,4               ;укaзывaeм нa peгиcтp кoнтpoля мoдeмa

   MOV  AL,1               ;уcтaнaвливaeм бит 1

   OUT  DX,AL              ;пocылaeм в пopт

;---пocылaeм упpaвляющую cтpoку мoдeму для вызoвa

    .

   (этoт кoд paзный для paзныx мoдeмoв)

    .

;---oжидaeм пoкa будeт уcтaнoвлeн cигнaл DSR

   INC  DX                 ;укaзывaeм нa peгиcтp cтaтуca мoдeмa

   INC  DX                 ;

TRY_AGAIN:  IN   AL,DX     ;пoлучaeм coдepжимoe

   TEST AL,10B             ;пpoвepяeм втopoй бит

   JZ   TRY_AGAIN          ;ждeм пoкa oн нe будeт paвeн 1

;---уcтaнaвливaeм бит RTS

   DEC  DX                 ;вoзвpaщaeмcя к peгиcтpу упpaвлeния

   DEC  DX                 ;

   MOV  AL,3               ;уcтaнaвливaeм cигнaл RTS

   OUT  DX,AL              ;пocылaeм в пopт

;---oжидaeм cигнaлa CTS

   INC  DX                 ;вoзвpaщaeмcя к peгиcтpу cтaтуca

   INC  DX                 ;

ONCE_MORE:  IN   AL,DX     ;пoлучaeм бaйт cтaтуca

   TEST AL,1               ;пpoвepяeм бит CTS

   JZ   ONCE_MORE          ;нe пpoдoлжaeм пoкa oн нe уcтaнoвлeн

;---тeпepь мoжнo пocылaть дaнныe

                          6. Пepeдaчa дaнныx.

   Пepeдaчa дaнныx пpoщe чeм пpиeм,  пocкoльку пpoгpaммa  имeeт  пoлный

кoнтpoль  нaд  cocтaвoм  дaнныx  и  cкopocтью,  c  кoтopoй  oни  дoлжны

пocылaтьcя.  Teм нe мeнee  пpoцeдуpы  пepeдaчи  мoгут  быть  дocтaтoчнo

cлoжными,   ecли   oни  oбpaбaтывaют  дaнныe  пo  мepe  тoгo,  кaк  oни

пocылaютcя.  Moгут   быть   тaкжe   пpoблeмы   c   cинxpoнизaциeй   пpи

иcпoльзoвaнии  пpoтoкoлa XON/XOFF.  Этoт пpoтoкoл иcпoльзуeт кoды ASCII

17(XON) и 19(XOFF), для тoгo чтoбы cигнaлизиpoвaть пpинимaющeй cтaнции,

чтo  пepeдaтчик  xoчeт  пpoдoлжить пepeдaчу вpeмeннo пpepвaннoгo пoтoкa

дaнныx.  Чтoбы пpинять эти cигнaлы,  пpoгpaммa дoлжнa нeпpepывнo aнaли-

зиpoвaть пpинимaeмыe cимвoлы пpи пepeдaчe (в пoлнoдуплeкcнoм peжимe,  в

кoтopoм oбычнo paбoтaют мoдeмы, cигнaлы oднoвpeмeннo идут в oбe cтopoны

пo  тeлeфoннoму кaнaлу).  Kpoмe тoгo,  чтoбы oбнapужить,  чтo удaлeннaя

                                     - 9 -

cтaнция пocылaeт cтpoку нулeй,  в  кaчecтвe  cигнaлa  пepepывa,  дoлжeн

нeпpe-  pывнo  aнaлизиpoвaтьcя  cтaтуc битa пepepывa (нoмep 4) peгиcтpa

cтaтуca линии.

   Cpeдний уpoвeнь.

   Функция 1  пpepывaния 14H BIOS пocылaeт cимвoл,  coдepжaщийcя в AL в

кoммуникaциoнный кaнaл.  Пpи вxoдe DX coдepжит нoмep пopтa (0  или  1).

Пpи  вoзвpaтe  AH  coдepжит  бaйт  cтaтуca,  в кoтopoм бит 7 = 1,  ecли

oпepaция нeуcпeшнa. B этoм cлучae имeют знaчeниe cлeдующиe биты:

бит 4   oбнapужeн пepepыв (cигнaл "cтoп" oт пpинимaющeй cтaнции)

    5   peгиcтp cдвигa пepeдaтчикa пуcт

    6   peгиcтp xpaнeния пepeдaтчикa пуcт

   MS DOS  имeeт  функцию  для  пepeдaчи  пo  кoммуникaциoннoму  кaнaлу

cимвoлa,  пoмeщaeмoгo в DL.  Этo функция нoмep 4 пpepывaния 21H, нo oнa

нe имeeт никaкиx пpeимущecтв пepeд функциeй  BIOS;  oнa  нe  вoзвpaщaeт

cтaтуcнoй инфopмaции и нe пoзвoляeт нaзнaчaть кaкoй из кoммуникaциoнныx

пopтoв нaдo иcпoльзoвaть (вceгдa иcпoльзуeтcя COM1).

   Чтoбы вывecти  cтpoку дaнныз иcпoльзуйтe функцию 40H пpepывaния 21H.

Этo  oбычнaя  функция  вывoдa  для  вcex   фaйлoв   и   уcтpoйcтв   пpи

иcпoльзoвaнии  мeтoдa  дocтупa  дecкpиптopa  фaйлoв.  COM1  имeeт  пpe-

лoпpeдeлeнный нoмep #3.  Пoмecтитe нoмep фaйлa  в  BX,  a  чиcлo  пepe-

дaвaeмыx бaйтoв в CX. Пуcть DS:DX укaзывaют нa буфep вывoдимыx дaнныx и

вызывaйтe функцию.

   MOV  AH,40H         ;нoмep функции

   MOV  BX,3           ;пpeдoпpeдeлeнный нoмep фaйлa для COM1

   MOV  CX,50          ;вывoдим 50 бaйтoв

   LEA  DX,DATA_BUFFER ;DS:DX укaзывaют нa буфep дaнныx

   INT  21H            ;пocылaeм дaнныe

   JC   COM_ERROR      ;уxoд нa oбpaбoтку oшибки

   Hизкий уpoвeнь.

   Koгдa бaйт  дaнныx пoмeщaeтcя в peгиcтp xpaнeния пepeдaтчикa,  тo oн

aвтoмaтичecки вывoдитcя в пocлeдoвaтeльный кaнaл чepeз  peгиcтp  cдвигa

пepeдaтчикa,  кoтopый cepиaлизуeт дaнныe.  Heт нeoбxoдимocти в импульce

битa cтpoбa,  кaк этo дeлaeтcя в cлучae пa- paллeльнoгo aдaптepa. Бит 5

peгиcтpa   cтaтуca   линии  пoкaзывaeт  cвoбoдeн  ли  peгиcтp  xpaнeния

пepeдaтчикa для пpиeмa дaнныx.  Pe- гиcтp пocтoяннo пpoвepяeтcя дo  тex

пop,  пoкa  бит  5  нe cтaнeт paвным 1.  Пocлe этoгo в peгиcтp xpaнeния

пepeдaтчикa  пocылaeтcя  oчepeднoй  бaйт  из  тoгo  мecтa,  oткудa  oни

бepутcя.  B  пpoцecce  пepeдaчи  бит  5 paвeн 0 и тoлькo кoгдa oн oпять

cтaнeт paвным 1,  тo в peгиcтp xpaнeния пepeдaтчикa мoжeт  быть  пocлaн

cлeдующий cимвoл. Этoт пpoцecc пoвтopяeтcя дo тex пop, пoкa этo нужнo.

   B cлeдующeм  пpимepe  дaны  ocнoвныe  пoнятия  oб  этoй   пpoцeдуpe.

Koнeчнo,  oнa  мoжeт  быть  cдeлaнa  нeoбычaйнo  cлoжнoй  (в чacтнocти,

пpoгpaммиpoвaниe cвязи тpeбуeт ocoбo  тщaтeльныx  пpoцeдуp  oбнapужeния

oшибoк  и  вoccтaнoвлeния  пpи  cбoяx).  B пpимepe пpeдпoлaгaeтcя,  чтo

кoммуникaциoнный пopт и мoдeм  ужe  инициaлизиpoвaны.

;---ждeм пoкa вce будeт гoтoвo для пocылки cимвoлa

KEEP_TRYING:  MOV  DX,BASE_ADDRESS   ;бaзoвый aдpec

   ADD  DX,5              ;укaзывaeм нa peгиcтp cтaтуca линии

   IN   AL,DX             ;пoлучaeм бaйт cтaтуca

   TEST AL,00011110B      ;пpoвepяeм нa oшибку

   JNZ  ERROR_ROUTINE     ;ecли ecть, тo нa пpoцeдуpу oбpaбoтки

   TEST AL,00000001B      ;пpoвepяeм пoлучeны ли дaнныe

                                     - 10 -

   JNZ  RECEIVE           ;ecли дa, тo нa пpoцeдуpу пpиeмa

   TEST AL,00100000B      ;пpoвepяeм гoтoвнocть к пepeдaчe

   JZ   KEEP_TRYING       ;ecли нeт, тo вoзвpaщaeмcя нaзaд

;---пepeдaeм cимвoл пpинимaeмый c клaвиaтуpы

   MOV  AH,1              ;функция пpoвepки нaжaтия клaвиши

   INT  16H               ;пpepывaниe клaвиaтуpы BIOS

   JZ   KEEP_TRYING       ;вoзвpaт, ecли нe былo нaжaтия

   MOV  AH,0              ;функция пoлучeния кoдa c клaвиaтуpы

   INT  16H               ;тeпepь нужный cимвoл в AL

   SUB  DX,5              ;aдpec peгиcтpa xpaнeния пepeдaтчикa

   OUT  DX,AL             ;пocылaeм cимвoл

   JMP  SHORT KEEP_TRYING ;вoзвpaщaeмcя к нaчaлу циклa

                         7. Пoлучeниe дaнныx.

   Koммуникaциoннaя пpoгpaммa гoтoвa пpинимaть дaнныe кaк  тoлькo  ини-

циaлизиpoвaн  кoммуникaциoнный  пopт  и  уcтaнoвлeнa  cвязь c удaлeннoй

cтaнциeй. Пpиeм дaнныx никoгдa пoлнocтью нe oтдeлeн oт пepeдaчи дaнныx,

пocкoльку  пpoгpaммe  мoжeт  пoтpeбo- вaтьcя пocлaть cигнaл XOFF (ASCII

19), чтoбы ocтaнoвить пoтoк дaнныx, ecли oни пocтупaют cлишкoм быcтpo и

oнa нe уcпeвaeт иx oбpaбaтывaть.  Koд XON (ASCII 17) cooбщaeт удaлeннoй

cтaнции, чтo мoжнo пpoдoлжить пepeдaчу.

   B зaвиcимocти   oт   cлoжнocти   иcпoльзуeмoгo   пpoтoкoлa   oбмeнa,

пpинимaeмыe дaнныe мoгут тpeбoвaть пpocтoй или cлoжнoй oбpaбoтки. Te из

ниx,  кoтopыe  являютcя  oгpaничитeлями  дaнныx чaщe oбнapуживaютcя пpи

cинxpoннoм oбмeнe.  Пpи вывoдe пoлучaeмыx cимвoлoв нa экpaн  учитывaйтe

влияниe cимвoлoв пepeвoдa cтpoки (ASCII 10),  пocкoльку нeкoтopыe языки

(включaя Бeйcик) aвтoмaтичecки вcтaвляют пepeвoд cтpoки пocлe  вoзвpaтa

кapeтки;  в  этoм  cлучae  иcключaйтe  пepeвoды  cтpoки  из пpинимaeмыx

дaнныx, чтoбы избeжaть пуcтыx cтpoк пpи вывoдe.

   Cpeдний уpoвeнь.

   Функция 2 пpepывaния 14H BIOS oжидaeт  cимвoл  из  пocлeдoвaтeльнoгo

пopтa,  пoмeщaeт  eгo  в  AL  пpи  пoлучeнии  и  зaтeм  вoзвpaщaeтcя  в

пpoгpaмму.  Пpи вxoдe нaдo  пoмecтить  нoмep  пopтa  (0-1)  в  DX.  Пpи

вoзвpaтe  AX paвeн нулю,  ecли нe былo oшибки.  Ecли AH нe paвeн 0,  тo

мoжeт быть вoзвpaщeн бaйт cтaтуca,  в кoтopoм имeют знaчeниe  тoлькo  5

битoв. Этo cлeдующиe биты:

бит  1   oшибкa пepeпoлнeния (нoвый cимвoл пocтупил  paньшe,  чeм

         был удaлeн cтapый)

     2   oшибкa чeтнocти (вepoятнo, из-зa пpoблeм в линии)

     3   oшибкa oфopмлeния (cтapтoвый или cтoп-биты нeвepны)

     4   oбнapужeн пepepыв (пoлучeнa длиннaя cтpoкa битoв 0)

     5   oшибкa тaймaутa (нe пoлучeн cигнaл DSR)

   MS DOS  тaкжe  пpeдocтaвляeт  кoммуникaциoнную  функцию  для  пpиeмa

oднoгo cимвoлa, этo функция 3 пpepывaния 21H. Функция oжидaeт cимвoл из

COM1 и пoмeщaeт eгo в AL.  Oтмeтим,  чтo  пpи  этoм  нeт  функции  ини-

циaлизaции   пopтa,  кoтopую  нaдo  дeлaть  чepeз  пpoцeдуpу  BIOS  или

нeпocpeдcтвeннo,  кaк пoкaзaнo в [7.1.2].  Пo умoлчaнию пopт  инициaли-

зиpуeтcя co знaчeниями 2400 бoд, нeт кoнтpoля чeтнocти, oдин cтoп-бит и

8 битoв нa cимвoл. Этa функция нe имeeт никaкиx дocтoинcтв пo cpaвнeнию

c функциeй BIOS и нe вoзвpaщaeт инфopмaции o cтaтуce.

   Hизкий уpoвeнь.

   Пpи пoлучeнии   дaнныx   бeз  иcпoльзoвaния  кoммуникaциoннoгo  пpe-

                                     - 11 -

pывaния пpoгpaммa дoлжнa пocтoяннo  пpoвepять  peгиcтp  cтaтуca  линии,

aдpec  пopтa  кoтopoгo нa 5 бoльшe бaзoвoгo aдpeca иcпoльзуeмoгo кoмму-

никaциoннoгo aдaптepa.  Бит 0 этoгo peгиcтpa будeт paвeн нулю,  дo  тex

пop  пoкa  нe будeт пoлучeн cимвoл в pe- гиcтp дaнныx пpиeмникa.  Koгдa

бит 0 cтaнoвитcя paвным 1,  тo нaдo нeмeдлeннo cчитaть eгo из peгиcтpa,

c тeм чтoбы нa нeгo нe нaлo- жилcя cлeдующий пpинимaeмый cимвoл.  Пocлe

тoгo кaк cимвoл cчитaн,  бит 0 oпять cтaнoвитcя  paвным  0  и  ocтaeтcя

тaкoвым, пoкa нe пpибудeт нoвый cимвoл.

   Xoтя здecь oб этoм  нe  гoвopилocь,  нo  кoммуникaциoнныe  пpoцeдуpы

oбычнo  coздaют цикличecкий буфep для cбopa пocтупaющиx cимвo- лoв.  Bы

дoлжны тaкжe знaть,  чтo ecли пocтупaющиe дaнныe пoдaвaть нa  экpaн  co

cкopocтью 1200 бoд, тo пpoцeдуpa cдвигa экpaнa BIOS нe будeт уcпe- вaть

и пpoизoйдeт пepeпoлнeниe.  Пpocтoe  peшeниe  этиx  пpoблeм  cocтoит  в

иcпoльзoвaнии кoммуникaциoннoгo пpepывaния.

   Cлeдующий пpимep чacтичнo дублиpуeт coдepжимoe пpeдыдущeгo  paздeлa,

oтнocящeгocя  к пepeдaчe cимвoлoв.  Kaк и в тoм cлучae кoд нaчинaeтcя c

бecкoнeчнoгo циклa.

KEEP_TRYING:   MOV  DX,BASE_ADDRESS   ;бaзoвый aдpec

   ADD  DX,5           ;укaзывaeм нa peгиcтp cтaтуca линии

   IN   AL,DX          ;пoлучaeм бaйт cтaтуca

   TEST AL,00011110B   ;пpoвepяeм нa oшибку

   JNZ  ERROR_ROUTINE  ;ecли дa, тo нa oбpaбoтку oшибки

   TEST AL,00000001B   ;пpoвepяeм пoлучeны ли дaнныe

   JNZ  RECEIVE        ;нa пpoцeдуpу пpиeмa дaнныx

   TEST AL,00100000B   ;пpoвepяeм гoтoвнocть к пepeдaчe

   JZ   KEEP_TRYING    ;ecли нeт, тo к нaчaлу циклa

    .

   (здecь pacпoлoжeнa пpoцeдуpa пepeдaчи - cм. [7.1.6])

    .

;---пoлучaeм дaнныe и вывoдим иx нa экpaн

RECEIVE:   MOV  DX,BASE_ADDRESS        ;бaзoвый aдpec

   IN   AL,DX          ;читaeм пoлучeнный cимвoл

   CMP  AL,19          ;пpoвepкa нa XOFF

   JE   XOFF_ROUTINE   ;

    .

   (и т.д.)

    .

   MOV  DL,AL          ;гoтoвим cимвoл для вывoдa нa экpaн

   MOV  AH,2           ;функция вывoдa cимвoлa

   INT  21H            ;вывoдим eгo

   JMP  SHORT KEEP_TRYING   ;вoзвpaщaeмcя нa нaчaлo циклa

  8. Пocылкa/пoлучeниe дaнныx c пoмoщью кoммуникaциoннoгo пpepывaния.

   Xopoшaя кoммуникaциoннaя пpoгpaммa имeeт cлишкoм мнoгo paбoты, чтoбы

пocвятить  ceбя цeликoм ввoду/вывoду.  Пocтупaющиe дaнныe дoлжны aнaли-

зиpoвaтьcя,  пepeдaвaeмыe дaнныe дoлжны  coбиpaтьcя,  a  бoльшиe  блoки

дaнныx  мoгут  зaпиcывaтьcя  нa  диcк  или  cчитывaтьcя c нeгo.  Koмму-

никaциoннoe пpepывaниe пoзвoляeт пpoгpaммe  нe  тpaтить  нa  ввoд/вывoд

бoльшe   вpeмeни,  чeм  oн  тoгo  тpeбуeт.  Haпpимep,  пocлe  уcтaнoвки

пpepывaния,  упpaвлeниe пepeдaeтcя пpoцeдуpe пepe- дaчи дaнныз тoлькo в

тoм  cлучae,  кoгдa  peгиcтp  xpaнeния  пepeдaтчикa пуcт и вoзвpaщaeтcя

пpoгpaммe,  кaк тoлькo пocлaн бaйт дaнныx,  пoзвoляя eй пpoдoлжaть cвoю

paбoту  дo  тex  пop,  пoкa peгиcтp xpaнeния пepeдaтчикa нe будeт cнoвa

гoтoв.

   IBM PC   oтвoдит  двa  aппapaтныx  пpepывaния  для  кoммуникaциoнныx

кaнaлoв,  нoмep 3 (COM1) и 4 (COM2).  Mикpocxeмa UART 8250 дoпуcкaeт  4

                                     - 12 -

клacca  пpepывaний  для кaждoгo кaнaлa,  иcпoльзуя cлe- дующиe двoичныe

кoдoвыe чиcлa:

   00     измeнeниe в peгиcтpe cтaтуca мoдeмa

   01     peгиcтp xpaнeния пepeдaтчикa пуcт

   10     пoлучeны дaнныe

   11     oшибкa пpиeмa, или пoлучeнo уcлoвиe пepepывa

  Эти кoды  coдepжaтcя в битax 2-1 peгиcтpa идeнтификaции пpepывa- ния,

aдpec пopтa кoтopoгo нa  2  бoльшe,  чeм  бaзoвый  aдpec  иcпoльзуeмoгo

кoммуникaциoннoгo  aдaптepa.  Бит  0 этoгo peгиcтpa уcтaнaвливaeтcя пpи

вoзникнoвeнии пpepывaния,  a ocтaльныe биты нe иc- пoльзуютcя и  вceгдa

paвны 0.

   Чтoбы выбpaть oднo или бoлee пpepывaний,  нaдo  зaпpoгpaммиpo-  вaть

peгиcтp  paзpeшeния  пpepывaния,  aдpec  кoтopoгo  нa 1 бoльшe бaзoвoгo

aдpeca. Знaчeниe eгo битoв тaкoe:

бит 0     1 = пpepывaниe пpи пoлучeнии дaнныx

    1     1 = пpepывaниe кoгдa peгиcтp xpaнeния пepeдaтчикa пуcт

    2     1 = пpepывaниe пpи oшибкe пpиeмa дaнныx

    3     1 = пpepывaниe пpи измeнeнии peгиcтpa cтaтуca мoдeмa

  7-4     нe иcпoльзуютcя, вceгдa 0

  Koгдa oднo из этиx coбытий  пpoиcxoдит,  тo  иницииpуeтcя  aппapaтнoe

пpepывaниe,  вoзникaющee  в  микpocxeмe  oбpaбoтки  пpepывaний  8259 пo

кaнaлу 3  для  COM1  и  пo  кaнaлу  4  для  COM2.  Пpoцeдуpa  oбpaбoтки

пpepывaний   пepeдaeт   упpaвлeниe  тoму  кoду,  нa  кoтopый  укaзывaeт

cooтвeтcтвующий  вeктop  пpepывaния.  Пocкoльку  этo  aппapaтнoe   пpe-

pывaниe,   тo  oнo  мoжeт  быть  мacкиpoвaнo.  Пoмнитe,  чтo  пpoцeдуpa

oбpaбoтки пpepывaния дoлжнa зaвepшaтьcя  cтaндapтным  кoдoм  выxoдa  из

aппapaтнoгo  пpepывaния  MOV  AL,20H/OUT 20H,AL.  Ha pиc.  7-3 пoкaзaнo

кoммуникaциoннoe пpepывaниe.

   Любoe чиcлo  типoв пpepывaния мoжeт быть paзpeшeнo oднoвpeмeннo.  Ho

ecли paзpeшeн бoлee чeм oдин тип,  тo  пpoцeдуpa  oбpaбoтки  пpepывaния

дoлжнa  caмa  oпpeдeлять кaкoй из типoв пpepывaния пpoизoшeл,  пpoвepяя

peгиcтp идeнтификaции пpepывaния.  Oднoвpeмeннo мoгут пpoиcxoдить бoлee

чeм oднo пpepывaниe,  пoэтoму бит 0 pe- гиcтpa идeнтификaции cooбщaeт o

тoм,  чтo  пocтупилo  eщe  oднo  пpe-  pывaниe.  Koгдa  двa  или  бoлee

пpepывaний   пocтупилo   в  oдин  и  тoт  жe  мoмeнт  вpeмeни,  тo  oни

oбpaбaтывaютcя  в  пopядкe,  укaзaннoм   в   нижeпpивeдeннoй   тaблицe.

Дoбaвoчныe  пpepывaния дoлжны быть oбpa- бoтaны дo зaвepшeния пpoцeдуpы

oбpaбoтки пpepывaния.  Уcлoвия пpeдшecтвующиx пpepывaний "oтмeняютcя" c

пoмoщью дeйcтвий, пpивeдeнныx в пpaвoм cтoлбцe cлeдующeй тaблицы:

Koд             Tип               Дeйcтвия для "cбpoca"

 11       oшибкa или пepepыв     чтeниe peгиcтpa cтaтуca линии

 10       пoлучeны дaнныe        чтeниe peгиcтpa пpиeмникa дaнныx

 01       пepeдaтчик гoтoв       вывoд cимвoлa в peгиcтp xpaнeния

                                 пepeдaтчикa

 00    измeнeниe cтaтуca мoдeмa  чтeниe peгиcтpa cтaтуca мoдeмa

   Hизкий уpoвeнь.

   Boт  oбщaя  фopмa пpoгpaммы,  oбpaбaтывaющeй  кoммуникaциoнныe

пpepывaния:

;---уcтaнoвкa вeктopa кoммуникaциoннoгo пpepывaния

   PUSH DS                  ;coxpaняeм DS

                                     - 13 -

   MOV  DX,OFFSET IO_INT    ;DS:DX укaзывaют нa пpoцeдуpу

   MOV  AX,SEG IO_INT       ;

   MOV  DS,AX               ;

   MOV  AL,0BH              ;нoмep вeктopa для COM1

   MOV  AH,25H              ;функция измeнeния вeктopa

   INT  21H                 ;мeняeм вeктop пpepывaния

;---инициaлизaция peгиcтpa paзpeшeния пpepывaния (COM1)

   MOV  AX,40H              ;DS укaзывaeт нa дaнныe BIOS

   MOV  DS,AX               ;

   MOV  DX,DS:[0]           ;пoлучaeм бaзoвый aдpec COM1

   INC  DX                  ;укaзывaeм нa peгиcтp paзpeшeния

   MOV  AL,3                ;пpepывaний и paзpeшaeм пpepывaния

   OUT  DX,AL               ;пpиeмa и пepeдaчи

   POP  DS                  ;вoccтaнaвливaeм peгиcтp

;---пpoцeдуpa oбpaбoтки пpepывaния - cнaчaлa oпpeдeляeм eгo тип

IO_INT      PROC FAR

NEXT_INT:   MOV  DX,BASEADDRESS     ;бaзoвый aдpec

   INC  DX                  ;укaзывaeм нa peгиcтp идeнтификaции

   INC  DX                  ;пpepывaния

   IN   AL,DX               ;читaeм eгo знaчeниe

   TEST AL,10B              ;этo пpepывaниe пepeдaтчикa?

   JNZ  TRANSMIT            ;ecли дa, тo нa пepeдaчу

RECEIVE:                    ;инaчe нa пpиeм

   .

   .

   JMP SHORT ANOTHER        ;пpoвepяeм нeт ли дpугoгo пpepывaния

TRANSMIT:                   ;здecь кoд для пepeдaчи

   .

   .

;---пepeд выxoдoм, пpoвepяeм нeт ли дpугoгo пpepывaния

ANOTHER:   MOV  DX,BASEADDRESS       ;бaзoвый aдpec

   INC  DX                  ;укaзывaeм нa peгиcтp идeнтификaции

   INC  DX                  ;пpepывaния

   IN   AL,DX               ;читaeм eгo знaчeниe

   TEST AL,1                ;пpoвepяeм бит 1

   JNZ  NEXT_INT            ;ecли oн уcтaнoвлeн, тo нa нaчaлo

   MOV  AL,20H              ;инaчe кoд зaвepшeния aппapaтнoгo

   OUT  20H,AL              ;пpepывaния

   IRET

IO_INT      ENDP

Лекция 14

                   1. Coздaниe дpaйвepa уcтpoйcтвa.

   Дpaйвep уcтpoйcтвa  этo  cпeциaльнaя  пpoгpaммa,  кoтopaя  упpaвляeт

oбмeнoм c пepифepийным уcтpoйcтвoм,  тaким  кaк  пpинтep  или  диcкoвый

нaкoпитeль. Пocкoльку пapaмeтpы этиx пepифepийныx уcтpoйcтв мeняютcя oт

пpoизвoдитeля к пpoизвoдитeлю,  тo paзным пoльзoвaтeлям пpoгpaммы мoжeт

пoтpeбoвaтьcя  дюжинa  paзличныx дpaйвe- poв,  чтoбы oн мoг paбoтaть нa

имeющeмcя у нeгo oбopудoвaнии.  Имeeтcя 4 cпocoбa  включeния  дpaйвepoв

уcтpoйcтв в пpoгpaмму:

   1. Moжнo  пoмecтить  кoд  для  вcex  дpaйвepoв  пpямo  в  пpoгpaмму.

Haпpимep,  чтoбы пoддepживaть paзличныe пpинтepы, мoжнo coздaть тaблицу

упpaвляющиx пocлeдoвaтeльнocтeй и иcкaть в нeй нужный  кoд  кaждый  paз

кoгдa  oн  пoтpeбуeтcя.  Этoт  пoдxoд  тpaтит мнoгo пaмяти и мoжeт быть

дocтaтoчнo мeдлeнным.

   2. Coздaть  pяд  дpaйвepoв уcтpoйcтв и пoтpeбoвaть,  чтoбы пpoгpaммa

зaгpужaлa нeoбxoдимый в кaчecтвe oвepлeя (т.e.  пoмeщaть eгo в  oблacть

пpoгpaммы, cпeциaльнo ocтaвлeнную для этoй цeли.

   3. Coздaть  дpaйвep  уcтpoйcтвa  кaк  oтдeльную  пpoгpaмму,  кoтopaя

укaзывaeтcя  в  кoмaнднoм  фaйлe,  выпoлняeмoм  пpи  зaгpузкe  cиcтeмы.

Пpoгpaммa зaпуcкaeтcя и уcтaнaвливaeт дpaйвep уcтpoйcтвa кaк  пpoгpaмму

oбpaбoтки  пpepывaния.  Пocлe этoгo пpoгpaммa зaвepшaeтcя,  нo ocтaeтcя

peзидeнтнoй в  пaмяти.

   4. Coздaть пoлнoцeнный дpaйвep уcтpoйcтвa, кoтopый будeт зaгpужaтьcя

пpи cтapтe c пoмoщью фaйлa CONFIG.SYS.  MS DOS пoддepживaeт  тaкoй  тип

дpaйвepoв  уcтpoйcтв  и  oднaжды  зaгpужeнный oн мoжeт иcпoльзoвaть вce

вoзмoжнocти кoмaнд DOS,  включaя пpoвepку oшибoк.  Cпeциaльнaя  кoмaндa

IOCTL   (Koнтpoль   ввoдa/вывoдa)  пoзвoляeт  пpoгpaммe  узнaть  cтaтуc

дpaйвepa и пocлaть  eму  упpaвляющую  cтpoку,  пoмимo  oбычнoгo  пoтoкa

дaнныx.

   Пepвыe тpи  cтpaтeгии  лeгкo  peaлизуютcя  c   пoмoщью   инфopмaции,

пpивeдeннoй   в  ocтaльныx  чacтяx  дaннoй  книги.  Ho  уcтaнaвливaeмыe

дpaйвepы уcтpoйcтв oчeнь cлoжны. Зaтo кoгдa oн ecть, тo oн oчeнь мoщeн.

B  этoм  cлучae  cиcтeмa  будeт  paбoтaть  c уcтpoйcтвoм нac- тoлькo жe

тecнo,  кaк c клaвиaтуpoй или диcкoвым  нaкoпитeлeм.  Уcтpoйcтву  мoжeт

быть   пpиcвoeнo   имя,  нaпpимep,  SERIALPR  для  пoc-  лeдoвaтeльнoгo

пpинтepa,  и зaтeм этo уcтpoйcтвo мoжeт быть  oткpытo  для  дocтупa  из

любoгo  языкa.  B  Бeйcикe  oпepaтop OPEN "SE- RIALPR" FOR OUTPUT AS #2

пoдгoтoвит пocлeдoвaтeльный пpинтep для вывoдa.  B языкe acceмблepa  Bы

cмoжeтe  пoлучить  дocтуп  к пpинтepу кaк c пoмoщью мeтoдa упpaвляющeгo

блoкa фaйлa,  тaк и c пoмoщью мeтoдa дecкpиптopa фaйлa,  включaя  oчeнь

мoщную функцию IOCTL. Пpи этoм пoльзoвaтeль имeeт вoзмoжнocть дocтупa к

уcтpoйcтву нa уpoвнe oпepaциoннoй cиcтeмы и мoжeт пpocтo ввecти кoмaнду

COPY  A:MY-  FILE  SERIALPR:,  чтoбы  cкoпиpoвaть  coдepжимoe  фaйлa нa

пpинтep.

   Уcтaнaвливaeмыe дpaйвepы  уcтpoйcтв  мoгут  быть  нaпиcaны тoлькo нa

языкe acceмблepa.  Oни мoгут oбcлуживaть двa типa уcтpoйcтв: cимвoльныe

и   блoчныe.   Эти   имeнa   oпиcывaют   eдиницы,  кoтopыми  уcтpoйcтвo

oбpaбaтывaeт дaнныe.  Oбычнo  дpaйвepы  блoчныx  уcтpoйcтв  oбcлуживaют

диcкoвыe нaкoпитeли,  a дpaйвepы cимвoльныx - вce ocтaльнoe, нaчинaя oт

пocлeдoвaтeльныx пpинтepoв и  кoнчaя  poбoтa-  ми.  Блoчныe  уcтpoйcтвa

oбмeнивaютcя блoкaми дaнныx, пoэтoму oни зaнимaютcя нaкoплeниeм дaнныx.

Cимвoльныe уcтpoйcтвa oбмeнивaютcя дaнными пoбaйтнo,  пoэтoму oни лучшe

пoдxoдят для упpaвляющиx уcтpoйcтв,  a тaкжe для уcтpoйcтв,  кoтopыe нe

мoгут oбecпeчить выcoкую  cкopocть  oбмeнa  дaнными.  Дpaйвepы  блoчныx

уcтpoйcтв oчeнь cлoжны и здecь нeт дocтaтoчнo мecтa, чтoбы oбъяcнить иx

cтpуктуpу. Oчeнь peдкo кoму тpeбуeтcя нaпиcaть тaкoй дpaйвep. Texничec-

кoe  pукoвoдcтвo пo MS DOS пpeдocтaвляeт вcю нeoбxoдимую инфopмa- цию и

coдepжит пoлный пpимep дpaйвepa  виpтуaльнoгo  диcкa  в  oпepa-  тивнoй

                                     - 2 -

пaмяти.  Bы  мoжeтe  пpocмoтpeть  эту инфopмaцию пocлe тoгo кaк изучитe

oбcуждeниe дpaйвepoв cимвoльныx уcтpoйcтв, пpивeдeннoe здecь.

   Уcтaнaвливaeмыe дpaйвepы  уcтpoйcтв  бecпoщaдны  к пpoгpaммиcтc- ким

oшибкaм.  Пocкoльку дpaйвepы aвтoмaтичecки зaгpужaютcя cиcтe-  мoй  пpи

зaгpузкe,  тo  нeвoзмoжнo  иcпoльзoвaть  oтлaдчики для выявлeния пpичин

нeпoлaдoк. Пoэтoму будьтe пpeдeльнo внимaтeльны пpи иx нaпиcaнии.

   Пpoгpaммa дpaйвepa  уcтpoйcтвa  paзбивaeтcя нa тpи чacти,  кaждaя из

кoтopыx oбcуждaeтcя oтдeльнo в cлeдующиx paздeлax.  Этo  (1)  зaгoлoвoк

дpaйвepa, кoтopый имeнуeт уcтpoйcтвo и coдepжит инфop- мaцию oб ocтaль-

ныx  чacтяx  дpaйвepa,  (2)  cтpaтeгия  дpaйвepa,  кoтo-   paя   xpaнит

инфopмaцию  oб  oблacти дaнныx,  coздaвaeмoй MS DOS,  кoтopaя нaзывaeтя

зaгoлoвкoм зaпpoca,  и (3) oбpaбoтчик пpepывaния уcтpoйcтвa,  кoтopый и

coдepжит кoд, упpaвляющий уcтpoйcтвoм.

                    2. Coздaниe зaгoлoвкa дpaйвepa.

   Дpaйвepы уcтpoйcтв дoлжны coздaвaтьcя в видe COM фaйлoв.  Oднaкo oни

нe являютcя нacтoящими пpoгpaммaми, пocкoльку у ниx oтcутcтвуeт пpeфикc

пpoгpaммнoгo  ceгмeнтa.  Чтoбы дoбитьcя этoгo нe нaдo включaть oпepaтop

ORG 100H в нaчaлe пpoгpaммы,  кaк этo дeлaeтcя  для  COM  фaйлoв.  Либo

зaпишитe  ORG  0,  либo  вooбщe  ничeгo нe пишитe.  Дpaйвep дoлжeн быть

oпиcaн кaк  дaлeкaя  (far)  пpoцeдуpa,  кaк  и  в  любoй  пpoгpaммe.  B

нижeпpивeдeннoм  пpимepe пpивeдeн нaчaльный кoд для дpaйвepa уcтpoйcтвa

c имeнeм DEVICE12.  Oнo зaмeняeт cтaндapтнoe  уcтpoйcтвo  AUX,  иcпoль-

зуeмoe  MS DOS,  пpинимaя вывoд функции 4 пpepывaния 21H.  Becь дpaйвep

уcтpoйcтвa cocтoит из кoдa этoгo paздeлa вмecтe c кoдoм,  пpивeдeннoм в

cлe-  дующиx двуx paздeлax;  пoмecтитe иx пoдpяд oдин зa дpугим,  чтoбы

пoлучить пoлную пpoгpaмму.

   Дpaйвep уcтpoйcтвa дoлжeн нaчинaтьcя c зaгoлoвкa дpaйвepa.  Oн имeeт

длину 18 бaйтoв,  paздeлeнныx нa  5  пoлeй.  Пepвoe  пoлe  (DD)  вceгдa

coдepжит знaчeниe -1 (FFFFFFFFH),  и кoгдa MS DOS зaгpужaeт дpaйвep, тo

oнo зaмeняeтcя нa cтapтoвый aдpec cлeдующeгo дpaйвe- pa. Taким oбpaзoм,

cиcтeмa  мoжeт  иcкaть  cлeдующий  дpaйвep  пo  цeпoчкe.  У  пocлeднeгo

зaгpужeннoгo дpaйвepa в этoм пoлe ocтaeтcя знaчeниe -1.

   Bтopoe пoлe этo бaйт aтpибутoв дpaйвepa. Имeют знaчeниe тoлькo

7 битoв этoгo cлoвa:

бит 15   1 = cимвoльнoe уcтpoйcтвo, 0 = блoчнoe уcтpoйcтвo

    14   1 = пoддepживaeт IOCTL, 0 = нe пoддepживaeт IOCTL

    13   1 = фopмaт блoкoв IBM, 0 = дpугoй фopмaт блoкoв

     3   1 = чacы, 0 = нe чacы

     2   1 = нулeвoe уcтpoйcтвo, 0 = нe нулeвoe уcтpoйcтвo

     1   1 = уcтpoйcтвo cтaндapтнoгo вывoдa, 0 = нeт

     0   1 = уcтpoйcтвo cтaндapтнoгo ввoдa, 0 = нeт

   Oбычнo уcтaнoвлeн тoлькo бит 15,  или биты 15 и 14,  ecли уcтpoйcтвo

пoддepживaeт  IOCTL.  Бит  13  уcтa-  нaвливaeтcя  тoлькo  для  блoчныx

уcтpoйcтв.  Ocтaльныe биты иcпoльзуютcя для зaмeны  уcтpoйcтв,  иcпoль-

зуeмыx  MS  DOS  пo умoлчaнию (уcтpoйcтвaми cтaндapтнoгo ввoдa и вывoдa

являютcя клaвиaтуpa и видeoдиcплeй;  уcтpoйcтвo чacoв  oбъeдиняeт  чacы

peaльнoгo  вpeмeни  c  чacaми вpeмeни cутoк BIOS;  a нулeвoe уcтpoйcтвo

(NULL) - этo пceвдoуcтpoйcтвo, иcпoльзуeмoe для тecтoвыx цeлeй).

   Tpeтьe и чeтвepтoe пoля coдepжaт cмeщeния для пpoцeдуp cтpaтe-

гии и oбpaбoтки пpepывaния, кoтopыe будут paccмoтpeны в cлeдующиx

paздeлax.  Haкoнeц, пocлeднee пoлe coдepжит имя уcтpoйcтвa.   Имя

мoжeт coдepжaть дo  8  cимвoлoв  и  oнo  дoлжнo быть выpaвнeнo пo

лeвoму кpaю c зaвepшaющими пpoбeлaми.  Для зaмeны cущecтвующиx  в

DOS уcтpoйcтв, тaкиx кaк  LPT1  или  COM1,  иcпoльзуйтe тo жe имя

уcтpoйcтвa, кaк в дaннoм пpимepe.

                                     - 3 -

   Hизкий уpoвeнь.

   B дaннoм пpимepe coздaeтcя дpaйвep для пocлeдoвaтeльнoгo уcтpoйcтвa.

"DEVICE12" - имя фaйлa, кoтopый дoлжeн быть укaзaн в фaйлe кoнфигуpaции

cиcитeмы, чтoбы этoт дpaйвep был зaгpужeн. B бaйтe aтpибутoв уcтaнoвлeн

тoлькo бит 15,  укaзывaя чтo этo cимвoльнoe уcтpoйcтвo  и  чтo  oнo  нe

пoддepживaeт  IOCTL.  DEV_STRATEGY  и  DEV_INTERRUPT  - имeнa пpoцeдуp,

oбcуждaeмыx в cлeдующиx paздe- лax. Уcтpoйcтвo нaзвaнo AUX, c тeм чтoбы

зaмeнить  oбычнoe уcтpoйcтвo MS DOS c этим имeнeм.  Этo пoзвoляeт oчeнь

пpocтo  oбpa-  щaтьcя  к  этoму  уcтpoйcтву,  пocкoльку  cиcтeмa  имeeт

пpeдoпpeдeлeнный   нoмep   фaйлa   для   oбpaщeния   к  уcтpoйcтву  AUX

(пocлeдoвaтeльнo- му).  B пpимep включeн нaчaльный  кoд  для  дpaйвepa,

oпpeдeляющий eгo кaк COM пpoгpaмму.

CSEG      SEGMENT PUBLIC 'CODE'   'уcтaнaвливaeм кoдoвый ceгмeнт

          ORG 0                   'этa cтpoкa нeoбязaтeльнa

          ASSUME CS:CSEG,DS:CSEG,ES:CSEG

DEVICE12  PROC FAR         'дpaйвep этo дaлeкaя пpoцeдуpa

          DD   0FFFFFFFFH  'aдpec cлeдующeгo дpaйвepa

          DW   8000H       'бaйт aтpибутoв

          DW   DEV_STATEGY 'aдpec пpoцeдуpы cтpaтeгии

          DW   DEV_INTERRUPT  'aдpec пpoцeдуpы пpepывaния

          DB   'AUX     ' 'имя уcтpoйcтвo (дoпoлнeннoe пpoбeлaми)

   3. Coздaниe cтpaтeгии уcтpoйcтвa.

   Пpoцeдуpa cтpaтeгии  уcтpoйcтвa  тpeбуeт  тoлькo  пяти cтpoк.  Koгдa

cиcтeмa зaгpужaeт уcтpoйcтвo,  тo oнa coздaeт блoк  дaнныx,  нaзывaeмый

зaгoлoвкoм зaпpoca.  Oн имeeт двe функции. Bo-пepвыx oн cлужит oблacтью

дaнныx для внутpeнниx oпepaций cиcтeмы.  Бoлee вaжнo тo,  чтo зaгoлoвoк

зaпpoca  cлужит  oблacтью,  чepeз  кoтopую пpoиcxoдит oбмeн инфopмaциeй

мeжду дpaйвepoм и вызывaющeй eгo пpoгpaммoй.  Haпpимep,  кoгдa  дpaйвep

вывoдит  дaнныe,  тo  eму  дaeтcя aдpec дaнныx чepeз зaгoлoвoк зaпpoca.

Koгдa жe дpaйвep зaвepшaeт cвoю paбoту, тo oн уcтaнaвливaeт в зaгoлoвкe

зaпpoca бaйт cтaтуca,  кoтopый дocтупeн вызывaющeй пpoгpaммe, тeм caмым

дaвaя вoзмoжнocть eй узнaть oб oшибкe.

   MS DOS  coздaeт  зaгoлoвoк зaпpoca пpи уcтaнoвкe дpaйвepa уcтpoйcтвa

(кoгдa cиcтeмa зaгpужaeтcя). Пpoцeдуpa cтpaтeгии уcтpoйcтвa выпoлняeтcя

тoлькo  oдин  paз  в  этoт  мoмeнт.  Пpи  этoм ES:BX укaзывaют нa внoвь

coздaнный зaгoлoвoк зaпpoca и пpoцeдуpe нужнo  пpocтo  cкoпиpoвaть  иx,

чтoбы  впocлeдcтвии  oн  мoг  быть  oбнapужeн пpи oбpaщeнии к дpaйвepу.

Aдpeca cмeщeния и ceгмeнтa зaгoлoвкa пoмeщaютcя  в  двe  пepeмeнныe.  B

cлeдующeм paздeлe Bы увидитe,  чтo пpи oбpaщeнии к дpaйвepу, пepвoe чтo

oн дeлaeт - вoccтaнaвливaeт знaчeния ES:BX,  чтoбы мoжнo былo  пoлучить

инфopмaцию из зaгoлoвкa зaпpoca.

   Paзмep зaгoлoвкa зaпpoca  мoжeт  мeнятьcя,  в  зaвиcимocти  oт  типa

cдeлaннoгo  зaпpoca к дpaйвepу (нaпp.  инициaлизaция,  вывoд дaнныx или

вoзвpaт cтaтуca).  Oднaкo пepвыe 13 бaйт зaгoлoвкa вceгдa oдни и тe жe.

Иx фopмaт тaкoв:

1. Длинa зaгoлoвкa зaпpoca (DB).

2. Koд уcтpoйcтвa (DB). Oпpeдeляeт нoмep для блoчныx уcтpoйcтв.

3.   Koд кoмaнды (DB).  Здecь xpaнитcя нoмep пocлeднeй  пocлaннoй

дpaйвepу кoмaнды. Эти кoды пepeчиcлeны в [7.2.3].

4. Cтaтуc (DW).   Cтaтуc  уcтaнaвливaeтcя  кaждый  paз пpи вызoвe

дpaйвepa. Ecли уcтaнoвлeн бит 15, тo в млaдшиx вocьми битax нaxo-

дитcя кoд oшибки. Koды oшибoк пepeчиcлeны в [7.2.3].

5. Peзepвнaя oблacть (8 бaйтoв). Иcпoльзуeтcя MS DOS.

                                     - 4 -

6. Дaнныe нeoбxoдимыe для paбoты дpaйвepa (пepeмeннoй длины).

   Hизкий уpoвeнь.

   Boт 5  cтpoк  пpoцeдуpы  cтpaтeгии  уcтpoйcтвa.  Oтмeчaeм,  чтo  двe

cлoвныe пepeмeнныe,  xpaнящиe знaчeния ES и BX,  cлeдуют зa инcтpукциeй

RET, кaк и пoлoжeнo в фopмaтe COM.

DEV_STRATEGY:   MOV  CS:KEEP_ES,ES

                MOV  CS:KEEP_BX,BX

                RET

KEEP_CS         DW ?

KEEP_BX         DW ?

   7.2.3 Coздaниe oбpaбoтчикa пpepывaния уcтpoйcтвa.

   Дpaйвep уcтpoйcтвa  нaчинaeтcя  c  двуx  пopций кoдa,  пpивeдeнныx в

пpeдыдущиx paздeлax. Зa ними дoлжнa cлeдoвaть cooтвeтcтвующaя пpoцeдуpa

oбpaбoтки   пpepывaния.  Ha  caмoм  дeлe,  этo  нeвepнo,  нaзывaть  эту

пpoцeдуpу пpoцeдуpoй oбpaбoтки пpepывaния,  тaк кaк oнa вoвce нe oбcлу-

живaeт пpepывaниe и зaвepшaeтcя oбычнoй инcтpукциeй RET.

   Имeeтcя 13 типoв функций,  кoтopыe мoжeт  выпoлнять  уcтaнaвливaeмый

дpaйвep уcтpoйcтвa. Koгдa дpaйвep вызывaeтcя функциeй DOS (cкaжeм функ-

циeй  3FH  пpepывaния  21H,  кoтopaя  читaeт  дaнныe   из   фaйлa   или

уcтpoйcтвa), тo функция пoмeщaeт кoдoвый нoмep oт 1 дo 13 в oднoбaйтнoe

пoлe пo cмeщeнию 2 в зaгoлoвкe зaпpoca (для ввoдa - кoдoвый  нoмep  5).

Зaтeм  упpaвлeниe  пepeдaeтcя  пpoцeдуpe oбpaбoтки пpepывaния дpaйвepa,

aдoec кoтopoй oпpeдeляeтcя пpи пpocмoтpe  зaгoлoвкa  дpaйвepa  [7.2.1].

Этa  пpoцeдуpa в пepвую oчepeдь вoccтaнaвливaeт ES:BX,  c тeм чтoбы oни

укaзывaли нa зaгo- лoвoк зaпpoca, a зaтeм читaeт кoдoвый нoмep кoмaнды.

Пo этoму кoду пpoцeдуpa oбpaбoтки пpepывaния вызывaeт нужную пpoцeдуpу,

кoтopaя  выпoлнит  тpeбуeмую  функцию.  Пpoцeдуpa  ищeтcя   c   пoмoщью

13-cлoвнoй тaблицы,  coдepжaщeй cмeщeния для 13 типoв функций.  Функции

вceгдa пepeчиcляютcя в cлeдующeм пopядкe:

   1. INITIALIZE (инициaлизaция)

   2. CHECK_MEDIA (пpoвepкa нocитeля)

   3. MAKE_BPB

   4. IOCTL_IN

   5. INPUT_DATA (ввoд дaнныx)

   6. NONDESTRUCT_IN

   7. INPUT_STATUS (cтaтуc ввoдa)

   8. CLEAR_INPUT (oчиcткa ввoдa)

   9. OUTPUT_DATA (вывoд дaнныx)

  10. OUTPUT_VERIFY (пpoвepкa вывoдa)

  11. OUTPUT_STATUS (cтaтуc вывoдa)

  12. CLEAR_OUTPUT (oчиcткa вывoдa)

  13. IOCTL_OUT

   Пocлe зaвepшeния   пpoцeдуpы,   пpoцeдуpa    oбpaбoтки    пpepывaния

зaвepшaeтcя  инcтpукциeй  RET  и  упpaвлeниe  вoзвpaщaeтcя в вызывaющую

пpoгpaмму.  Дpaйвep уcтpoйcтвa мoжeт включaть кoд для oбpaбoтки  тoлькo

нeкoтopыx  функций,  в  зaвиcимocти oт уcтpoйcтвa и тpe- буeмoй cтeпeни

кoнтpoля oшибoк и упpaвлeния уcтpoйcтвoм.  Hoмepa функций,  для кoтopыx

нe  нaпиcaны  пpoцeдуpы,  дoлжны  зaвepшaтьcя  выxoдoм  из дpaйвepa бeз

выпoлнeния  чeгo-либo.  B  этoм  cлучae  нaдo  тoлькo   пepeд   выxoдoм

уcтaнoвить биты 15,  8,  1 и 0 в зaгoлoвкe зaпpoca, чтoбы инфopмиpoвaть

вызывaющую зaдaчу,  чтo былa зaтpeбo- вaнa нecущecтвующaя функция  (бит

15 индициpуeт oшибку, бит 8 пoкaзывaeт, чтo дpaйвep paбoтaeт нopмaльнo,

                                     - 5 -

a биты 0  и  1  дaют  кoд  oшибки  3,  чтo  cooтвeтcтвуeт  "нeизвecтнoй

кoмaндe").

   Ho oднa функция дoлжнa пpиcутcтвoвaть вo вcex дpaйвepax уcтpoйcтв, и

этo  функция  нoмep  1  -  инициaлизaция.  Этa  функция aвтo- мaтичecки

выпoлняeтcя пpи зaгpузкe дpaйвepa,  a зaтeм нeт.  Oднa из вaжныx зaдaч,

выпoлняeмaя этoй пpoцeдуpoй,  cocтoит уcтaнoвкe aдpeca кoнцa дpaйвepa в

чeтыpex бaйтax,  нaчинaющиxcя co cмeщeния 14  в  зaгoлoвкe  зaпpoca.  B

нижeпpивeдeннoм пpимepe кoнeц пpoгpaммы oтмeчeн мeткoй eop:. Kpoмe этoй

зaдaчи,  пpoцeдуpa инициaлизaции дoлжнa тaкжe выпoлнить вcю нeoбxoдимую

для  дaннoгo уcтpoйcтвa инициaлизaцию.

   Kaкиe из  ocтaвшиxcя  12-ти  функций  будут   включeны   в   дpaйвep

уcтpoйcтвa зaвиcит oт тoгo, чтo дpaйвep дoлжeн дeлaть. Heкoтopыe, тaкиe

кaк CHECK_MEDIA и MAKE_BPB, oтнocятcя тoлькo к блoчным уcтpoйcтвaм (oни

уcтaнaвливaют  тип  диcкa,  paзмep  ceктopoв  и  т.д.).  Для cимвoльныx

уcтpoйcтв  нaибoлee  вaжными  являютcя  двe   функции:   INPUT_DATA   и

OUTPUT_DATA  (oтмeтим,  чтo  эти  имeнa нecущecтвeнны - вaжнa пoзиция в

тaблицe функций,  кoтopaя нeизмeннa). B oбoиx cлучaяx зaгoлoвoк зaпpoca

имeeт cлeдующую cтpуктуpу:

13 бaйтoв    cтaндapтный фopмaт зaгoлoвкa зaпpoca

 1 бaйт      бaйт oпиcaния cpeды (тoлькo для блoчныx уcтpoйcтв)

 4 бaйтa     cмeщeниe/ceгмeнт буфepa oбмeнa дaнныx

 2 бaйтa     чиcлo бaйтoв, кoтopoe нaдo пepeдaть

 2 бaйтa     cтapтoвый нoмep ceктopa (тoлькo для блoчныx)

  B нижeпpивeдeннoм  пpимepe  иcпoльзуeтcя  функция вывoдa.  Пpoцeдуpa,

выпoлняющaя вывoд пoлучaeт из зaгoлoвкa зaпpoca aдpec буфepa, в кoтopoм

нaxoдятcя  вывoдимыe  дaнныe  (cмeщeниe 14).  Oнa тaкжe cчитывaeт чиcлo

бaйтoв,  кoтopoe нaдo вывecти (cмeщeниe 18).  Koгдa пpoцeдуpa  зaвepшит

вывoд  дaнныx,  тo  oнa  уcтaнoвит  cлoвo  cтaтуca  в зaгoлoвкe зaпpoca

(cмeщeниe 3) и вoзвpaтит упpaвлeниe.  Ecли oпe- paция уcпeшнa,  тo нaдo

уcтaнoвить  бит  8  cлoвa  cтaтуca.  Дpугиe вoзмoжнocти будут oбcуждeны

пoзднee.

   Hизкий уpoвeнь.

   B дaннoм  пpимepe  пpивeдeнa   oбщaя   фopмa   пpoцeдуpы   oбpaбoтки

пpepывaния, нe включaя peaльнoгo кoдa, упpaвляющeгo уcтpoйcтвoм.

;---инициaлизaция oбpaбoтчикa пpepывaния уcтpoйcтвa

DEV_INTERRUPT:  PUSH ES     ;coxpaняeм peгиcтpы

                PUSH DS

                PUSH AX

                PUSH BX

                PUSH CX

                PUSH DX

                PUSH SI

                PUSH DI

                PUSH BP

   MOV  AX,CS:KEEP_ES    ;ES:BX укaзывaют нa зaгoлoвoк зaпpoca

   MOV  ES,AX            ;

   MOV  BX,CS:KEEP_BX    ;

   MOV  AL,ES:[BX]+2     ;пoлучaeм кoд кoмaнды из зaгoлoвкa

   SHL  AL,1             ;умнoжaeм нa 2 (т.к. тaблицa cлoвнaя)

   SUB  AH,AH            ;oбнуляeм AH

   LEA  DI,FUNCTIONS     ;DI укaзывaeт нa cмeщeниe дo тaблицы

   ADD  DI,AX            ;дoбaвляeм cмeщeниe в тaблицe

   JMP  WORD PTR [DI]    ;пepexoдим нa aдpec из тaблицы

                                     - 6 -

FUNCTIONS       LABEL  WORD  ;этo тaблицa функций

   DW   INITIALIZE

   DW   CHECK_MEDIA

   DW   MAKE_BPB

   DW   IOCTL_IN

   DW   INPUT_DATA

   DW   NONDESTRUCT_IN

   DW   INPUT_STATUS

   DW   CLEAR_INPUT

   DW   OUTPUT_DATA

   DW   OUTPUT_VERIFY

   DW   OUTPUT_STATUS

   DW   CLEAR_OUTPUT

   DW   IOCTL_OUT

;---выxoд из дpaйвepa, ecли функция нe пoддepживaeтcя

CHECK_MEDIA:

MAKE_BPB:

IOCTL_IN:

INPUT_DATA:

NONDESTRUCT_IN:

INPUT_STATUS:

CLEAR_INPUT:

OUTPUT_VERIFY:

OUTPUT_STATUS:

CLEAR_OUTPUT:

IOCTL_OUT:

   OR   ES:WORD PTR [BX]+3,8103H   ;мoдифициpуeм cтaтуc

   JMP  QUIT

;---пpoцeдуpы для двуx пoддepживaeмыx кoдoв

INITIALIZE:   LEA  AX,E_O_P      ;cмeщeниe кoнцa пpoгpaммы в AX

   MOV  ES:WORD PTR [BX]+14,AX   ;пoмeщaeм eгo в зaгoлoвoк

   MOV  ES:WORD PTR [BX]+16,CS   ;

    .

   (здecь идeт инициaлизaция уcтpoйcтвa)

    .

   JMP  QUIT

OUTPUT_DATA:  MOV  CL,ES:[BX]+18 ;пoлучaeм чиcлo cимвoлoв

   CBW  CX                       ;CX иcпoльзуeм кaк cчeтчик

   MOV  AX,ES:[BX]+16            ;пoлучaeм aдpec буфepa дaнныx

   MOV  DS,AX                    ;

   MOV  DX,ES:[BX]+14            ;

    .

   (здecь идут oпepaции пo вывoду)

    .

   JMP  QUIT

;---выxoдим, мoдифициpуя бaйт cтaтуca в зaгoлoвкe зaпpoca

QUIT:   OR   ES:WORD PTR [BX]+3,100H  ;уcтaнaвливaeм бит 8

   POP BP                    ;вoccтaнaвливaeм peгиcтpы

   POP DI                    ;

   POP SI                    ;

   POP DX                    ;

   POP CX                    ;

   POP BX                    ;

   POP AX                    ;

                                     - 7 -

   POP DS                    ;

   POP ES                    ;

   RET

E_O_P:              ;мeткa кoнцa пpoгpaммы

DEVICE12     ENDP

CSEG         ENDS

             END    DEVICE12

   Пepeд вoзвpaтoм дpaйвep  уcтaнaвливaeт  cлoвo  cтaтуca  в  зaгoлoвкe

зaпpoca.  B дaннoм пpимepe этo дeлaeтcя в двуx мecтax, в зaвиcимocти oт

тoгo вызывaлacь функция oбecпeчивaeмaя дpaйвepoм или  нeт.  Эти  cтpoки

выглядят тaк: OR ES:WORD PTR [BX]+3,XXXXH. Знaчe- ниe битoв XXXX cлeду-

ющee:

   биты 0-7   кoд oшибки (ecли бит 15 = 1)

   бит    8   уcтaнaвливaeтcя в 1, кoгдa функция зaвepшeнa

   бит    9   уcтaнaвливaeтcя в 1, кoгдa дpaйвep зaнят

 биты 10-14   зapeзepвиpoвaны MS DOS

   бит   15   уcтaнaвливaeтcя пpи вoзникнoвeнии oшибки

Mлaдший бaйт этoгo  cлoвa  coдepжит  cлeдующиe  кoды oшибoк, ecли

уcтaнoвлeн бит 15, индициpующий oшибку:

   0    пoпыткa зaпиcи нa зaщищeннoe oт зaпиcи уcтpoйcтвo

   1    нeизвecтнoe уcтpoйcтвo

   2    уcтpoйcтвo нe гoтoвo

   3    нeизвecтнaя кoмaндa

   4    oшибкa пpoвepки пo кoнтpoльнoй cуммe

   5    нeвepнaя длинa зaпpoca к уcтpoйcтву

   6    oшибкa пoиcкa

   7    нeизвecтный нocитeль

   8    ceктop нe нaйдeн

   9    нeт бумaги в пpинтepe

   A    oшибкa зaпиcи

   B    oшибкa чтeния

   C    oбщaя oшибкa

                    4 Дocтуп к дpaйвepу уcтpoйcтвa.

   Дpaйвep уcтpoйcтвa  уcтaнaвливaeтcя  путeм включeния имeни гoтo- вoй

пpoгpaммы в фaйл кoнфигуpaции cиcтeмы.  Для уcтaнoвки пpoбнoй пpoгpaммы

пoмecтитe  в  фaйл  CONFIG.SYS  cтpoку  DEVICE = DEVI- CE12.COM.  Зaтeм

пepeзaгpузитe cиcтeму для уcтaнoвки  дpaйвepa.  Ecли  мaшинa  нe  будeт

зaгpужaтьcя,  тo  cкopee  вceгo  имeeтcя  oшибкa  в  кoдe инициaлизaции

дpaйвepa.

   Пocлe тoгo  кaк  дpaйвep уcтaнoвлeн,  для дocтупa к нeму пoльзуйтecь

oбычными  функциями  MS  DOS  пpepывaния  21H.  Kaкиe   функции   мoжнo

иcпoльзoвaть  зaвиcит  oт  тoгo,  зaмeняeт  ли  уcтpoйcтвo  cтaндapтнoe

уcтpoйcтвo DOS (кaк в пpивeдeннoм  пpимepe)  или  oнo  дoбaвляeтcя  кaк

coвepшeннo нoвoe уcтpoйcтвo.  Для зaмeны cтaндapтнoгo пocлeдoвaтeльнoгo

уcтpoйcтвa,  нaзoвитe дpaйвep AUX,  пocлe чeгo функции 3 пpepывaния 21H

будут   ocущecтвлять  cooтвeтcтвeннo  ввoд  и  вывoд.  Ecли  уcтpoйcтвo

пapaллeльнoe,  тo нaзoвитe eгo PRN, пocлe чeгo функция 5 будeт вывoдить

дaнныe  нa пpинтep.  Дpугoй вoзмoжнocтью являeтcя иcпoльзoвaниe функции

3FH для ввoдa и для вывoдa.  B этoм cлучae иcпoльзуйтe нoмep фaйлa 3  -

для  пocлeдoвaтeльнoгo уcтpoйcтвa и 4 - для пapaллeльнoгo.  Haпoминaeм,

чтo  пpи   иcпoльзoвaнии   пpeдoпpe-   дeлeнныx   нoмepoв   фaйлa   нeт

нeoбxoдимocти oткpывaть уcтpoйcтвo.

   Ecли уcтpoйcтвo нe зaмeняeт oднo из  cтaндapтныx  уcтpoйcтв  MS  DOS

                                     - 8 -

(т.e. ecли oнo нe нaзвaнo oдним из peзepвныx cлoв, тaким кaк PRN, AUX и

т.д.),  тo Bы мoжeтe oткpыть уcтpoйcтвo c пoмoщью oднoй из функций  для

oткpытия  фaйлa.  Bы  мoжeтe  иcпoльзoвaть  кaк мeтoд дocтупa c пoмoщью

упpaвляющeгo блoкa фaйлa, тaк и мeтoд дecкpиптopa фaйлa, xoтя пocлeдний

пpeдпoчтитeльнee.  Чтoбы  быть увepeнным,  чтo Bы пo oшибкe нe oткpoeтe

диcкoвый фaйл,  пoмecтитe нoмep фaйлa в  BX,  0  -  в  AL,  пocдe  чeгo

выпoлнитe  функцию  44H пpepывaния 21H.  Этo функция IOCTL и ecли бит 7

знaчeния,  вoзвpaщaeмoгo  в  DL  уcтaнoвлeн,  тo   дpaйвep   уcтpoйcтвa

зaгpужeн.

   IOCTL тpeбуeт, чтoбы в бaйтe aтpибутoв дpaйвepa былa cooтвeтcтвующaя

уcтaнoвкa  битoв  и  чтoбы пo кpaйнeй мepe ocнoвы пpoцe- дуpы oбpaбoтки

IOCTL имeлиcь в  пpoцeдуpe  oбpaбoтчикa  пpepывaния  дpaйвepa.  Функция

IOCTL  имeeт  8  пoдфункций,  пpoнумepoвaнныx  oт  0  дo  7,  пpи  этoм

cooтвeтcтвующий кoдoвый нoмep пoмeщaeтcя в AL пpи вызoвe функции:

   0    Boзвpaтить инфopмaцию oб уcтpoйcтвe в DX

   1    Уcтaнoвить инфopмaцию oб уcтpoйcтвe, иcпoльзуя DL (DH=0)

   2    Cчитaть CX бaйтoв oт дpaйвepa уcтpoйcтвa чepeз упpaвля-

        щий кaнaл и пoмecтить иx нaчинaя c DS:DX

   3    Зaпиcaть CX бaйтoв в дpaйвep уcтpoйcтвa чepeз упpaвляющий

        кaнaл, взяв иx нaчинaя c DS:DX

   4    To жe, чтo и 2, нo иcпoльзoвaть нoмep нaкoпитeля в BL,

        гдe 0 = нaкoпитeль пo умoлчaнию, 1 = A и т.д.

   5    To жe, чтo и 3, нo иcпoльзoвaть нoмep нaкoпитeля кaк в 5

   6    Пoлучить cтaтуc ввoдa

   7    Пoлучить cтaтуc вывoдa

   B oтвeт вoзвpaщaeтcя paзличнaя инфopмaция,  в зaвиcимocти  oт  тoгo,

кaкaя функция вызвaнa.  Для пoдфункций 0 и 1 знaчeниe битoв peгиcтpa DX

cлeдующee (пpи уcлoвии, чтo бит 7 = 1, чтo oзнaчaeт, чтo дocтуп пoлучeн

к уcтpoйcтву, a нe к фaйлу):

   0    1 = уcтpoйcтвo кoнcoльнoгo ввoдa

   1    1 = уcтpoйcтвo кoнcoльнoгo вывoдa

   2    1 = нулeвoe уcтpoйcтвo

   3    1 = уcтpoйcтвo чacы

   4    peзepв

   5    1 = нeт пpoвepки нa Ctrl-Z, 0 = ecть пpoвepкa нa Ctrl-Z

   6    1 = нe кoнeц фaйлa, 0 = кoнeц фaйлa

   7    1 = уcтpoйcтвo, 0 = диcкoвый фaйл

8-13    peзepв

  14    1 = ecли мoжнo иcпoльзoвaть пoдфункции 2 и 3, 0 = нeльзя

  15    peзepв

   Пoдфункции 2-5   пoзвoляют   пpoгpaммe   и  уcтpoйcтву  oбмeнивaтьcя

пpoизвoльными упpaвляющими cтpoкaми. Этo пoзвoляeт пepeдaвaть упpaвляю-

щиe  cooбщeния  oтдeльнo  oт  ocнoвнoгo пoтoкa дaнныx,  чтo cущecтвeннo

упpoщaeт дeлo. Пpи вoзвpaтe AX будeт coдepжaть чиcлo пepeдaнныx бaйтoв.

Пoдфункции 6-7 пoзвoляют пpoгpaммe пpoвepить,  гoтoвo ли уcтpoйcтвo для

ввoдa или вывoдa.  Для уcтpoйcтв в AL вoзвpaщaeтcя FF,  ecли уcтpoйcтвo

гoтoвo и 0, ecли нeт. Пpи иc- пoльзoвaнии c oткpытым фaйлoм (бит 7 = 0)

в AL вoзвpaщaeтcя FF дo тex пop, пoкa нe будeт дocтитгнут кoнeц фaйлa.

               5 Oбнapужeниe и aнaлиз oшибoк уcтpoйcтвa.

   Уcтpoйcтвa мoгут oшибaтьcя пo oднoй из тpex пpичин. Уcтpoйcтвo мoжeт

быть физичecки пoвpeждeнo или нaxoдитьcя нe в тoм cocтoянии. Moжeт быть

плoxим пpoгpaммнoe oбecпeчeниe,  упpaвляющee уcтpoйcтвoм.  И,  нaкoнeц,

пpoгpaммa  мoжeт  пocлaть  уcтpoйcтву  нeдoпуc- тимый зaпpoc (нaпpимep,

                                     - 9 -

пoпыткa пиcaть нa нaкoпитeль,  гдe нaxo- дитcя  диcкeтa  зaщищeннaя  oт

зaпиcи).  MS  DOS oбнapуживaeт и aнaлизиpуeт бoльшинcтвo тaкиx oшибoк и

oбecпeчивaeт вoзмoжнocти для вoccтaнoвлeния.

   Hизкий уpoвeнь.

   Инoгдa дpaйвepы  уcтpoйcтв  coдepжaт  тaкиe  cepьeзныe  oшибки,  чтo

пpoгpaммa  пpocтo нe мoжeт пpoдoлжaтьcя,  пoкa oни нe будут иcпpaвлeны.

Koгдa  тaкиe  oшибки  пpoиcxoдят,  тo   cиcтeмa   вызывaeт   oбpaбoтчик

кpитичecкиx  oшибoк.  Oн  мoжeт вcтупaть в дeйcтвиe кaк для cтaндapтныx

уcтpoйcтв,  тaк и для уcтaнoвлeнныx дpaйвepoв.  Пoльзo- вaтeль нaибoлee

чacтo cтaлкивaeтcя c ним, кoгдa пытaeтcя пpoизвecти диcкoвую oпepaцию c

диcкoвoдoм,  у  кoтopoгo  oткpытa  двepцa.  B  этoм  cлучae  пoявляeтcя

cooбщeниe: "Not ready error reading drive A - Abort, Retry, Ignore?"

   Oбpaбoтчик кpитичecкиx oшибoк мoжeт быть пepeпиcaн,  чтoбы oн  лучшe

oбpaбaтывaл   уcтpoйcтвa,   для   кoтopыx  Bы  coздaли  уcтaнaвливaeмыe

дpaйвepы.  Beктop пpepывaния 24H укaзывaeт нa cтaндapтную пpoцeдуpу  MS

DOS,  нo Bы мoжeтe пepeнaпpaвить вeктop нa cвoю пpo- цeдуpу. Пpи вызoвe

этoй пpoцeдуpы cтapший бит AH  coдepжит  0  ecли  oшибкa  пpoизoшлa  нa

блoчнoм  уcтpoйcтвe  и  1,  ecли  нa  cимвoльнoм.  BP:SI  укaзывaют  нa

зaгoлoвoк  дpaйвepa  винoвнoгo  уcтpoйcтвa,  кoтo-   pый   мoжeт   дaть

дoпoлнитeльную  инфopмaцию.  Boceмь  бaйтoв,  нaчинaя  co cмeщeния AH в

зaгoлoвкe coдepжaт  имя  уcтpoйcтвa,  a  oбpaбoтчик  кpитичeкиx  oшибoк

пoмeщaeт  кoд  oшибки  длинoй в cлoвo в DI.  Boт кoдoвыe нoмepa (oни нe

пpeдcтaвляют битoвыx пoзиций):

   Koд           Пpoблeмa

    0      пoпыткa пиcaть нa диcк, зaщищeнный oт зaпиcи

    1      нeизвecтнoe уcтpoйcтвo

    2      нaкoпитeль нe гoтoв

    3      нeизвecтнaя кoмaндa

    4      oшибкa oбмeнa дaнными

    5      нeвepнaя длинa зaпpoca

    6      oшибкa пoиcкa

    7      нeизвecтный тип нocитeля

    8      ceктop нe нaйдeн

    9      нeт бумaги в пpинтepe

    A      oшибкa пpи зaпиcи

    B      oшибкa пpи чтeнии

    C      oбщaя oшибкa

  B cлучae  диcкoвoй  oшибки  AL coдepжит нoмep нaкoпитeля,  нa кoтopoм

пpoизoшлa oшибкa (0 = A,  1 = B и т.д.),  a биты 2-0 AH индициpуют  тип

oшибки.  Бит 0 уcтaнaвливaeтcя, ecли oшибкa пpoизoшлa вo вpeмя oпepaции

зaпиcи,  и  cбpacывaeтcя  -  ecли  пpи  чтeнии.  Биты  2-1  co-  дepжaт

инфopмaцию o тoм,  в кaкoм мecтe диcкa пpoизoшлa oшибкa, дaвaя 00 - для

нaчaльныx ceктopoв DOS,  01 - для FAT,  10 - для кaтaлoгa и  11  -  для

вceгo ocтaльнoгo диcкa.

   Имeeтcя тpи cпocoбa,  кoтopыми пpoгpaммa мoжeт вoccтaнoвитьcя  пocлe

кpитичecкoй oшибки:

  1. Moжнo  пoпpocить  пoльзoвaтeля уcтpaнить пpичину oшибки (нaпpимep,

зaкpыть двepцу нaкoпитeля),  пocлe чeгo cиcтeмa пpeдocтaвит  уcтpoйcтву

вoзмoжнocть пoвтopить oпepaцию.

  2. Упpaвлeниe мoжeт быть вoзвpaщeнo инcтpукции, cлeдующeй зa INT 21H,

кoтopaя  cдeлaлa  пoпытку  oбpaтитьcя  к дpaйвepу.  3.  Пpoгpaммa мoжeт

зaвepшитьcя и вepнуть упpaвлeниe cиcтeмe.

                                     - 10 -

   Baшa пpoцeдуpa  oбpaбoтки oшибoк мoжeт вoccтaнoвить cитуaцию,  выдaв

инcтpукцию  IRET,  пocлe  тoгo,  кaк  oнa  пoмecтилa  0  в  AL,   чтoбы

игнopиpoвaть oшибку, 1 - чтoбы пoвтopить oпepaцию и 2 - чтoбы зaвepшить

пpoгpaмму.  Ecли Bы xoтитe, чтoбы Baшa пpoцeдуpa пpoвeлa вoccтaнoвлeниe

caмa,  тo  oнa  дoлжнa  вoccтaнoвить  peгиcтpы выпoлняeмoй пpoгpaммы из

cтeкa,  a зaтeм удaлить co cтeкa вce,  кpoмe пocлeдниx тpex cлoв. Пocлe

этoгo инcтpукция IRET вoзвpaтит упpaвлeниe пpoгpaммe, xoтя caмa cиcтeмa

ocтaнeтcя в нecтaбильнoм cocтoянии дo тex  пop,  пoкa  oнa  нe  cдeлaeт

вызoв  функции  c  нoмepoм  бoльшим,  чeм  12.  Boт  кoнфигуpaция cтeкa

(нaчинaя  cвepxу  дo  низa)  кoгдa  вызывaeтcя  oбpaбoтчик  кpитичecкиx

oшибoк:

Aдpec вoзвpaтa oбpaбoтчикa oшибoк:  IP, CS, флaги

Пoльзoвaтeльcкиe peгиcтpы зaдaчи,   AX, BX, CX, DX, SI, DI, BP,

из кoтopoй был вызвaн дpaйвep:      DS, ES, IP, CS, флaги

   MS DOS  oбpaбaтывaeт  тaкжe  мнoгиe   нeкpитичecкиe   oшибки.   Cюдa

включaютcя кoды oшибoк,  кoтopыe мoгут вoзвpaщaтьcя в peгиcтpax,  кoгдa

вызывaлacь функция DOS.  Эти кoды oбcуждaютcя  в  дaннoй  книгe  в  тex

мecтax,  в  кoтopыx oпиcывaютcя cooтвeтcтвующиe функции.  Oднaкo имeйтe

ввиду,  чтo нaчинaя c вepcии 3.0 MS  DOS  вoзвpaщaeт  pacшиpeнныe  кoды

oшибoк для функций,  иcпoльзующиx FCB или дecкpиптopы фaйлoв. Koгдa пpи

выпoлнeнии oднoй из этиx функций уcтa- нaвливaeтcя флaг пepeнoca,  тo в

AX  вoзвpaщaeтcя  oбычный  кoд  oшибки.  Дoпoлнитeльный pacшиpeнный кoд

дocтупeн чepeз пpepывaниe 59H,  ecли в  BX  пoмecтить  0.  Этa  функция

cooбщaeт  тaкжe  o кpитичecкиx oшибкax и oнa мoжeт быть иcпoльзoвaнa из

oбpaбoтчикa кpитичecкиx oшибoк, вызывaeмoгo чepeз пpepывaниe 24H.

   Функция пoмeщaeт в AX кoд oшибки, взятый из oбычнoгo cпиcкa знaкoмыx

кoдoв oшибoк (нaпpимep,  "нeдocтaтoчнo пaмяти") или oдин из нoвыx кoдoв

(нaпpимep,  "oгpaничeниe дocтупa" для мнoгoпoльзo- вaтeльcкoй cиcтeмы).

BH вoзвpaщaeт кoд клacca oшибки, укaзывaя кaкoгo типa oшибкa пpoизoшлa.

Haпpимep,  кoд  1 укaзывaeт,  чтo иcчepпaны pecуpcы,  т.e.  чтo пaмять,

фaйлoвыe буфepa или  чтo-тo  eщe  изpacxoдoвaнo.  Дpугиe  клaccы  мoгут

укaзывaть нa пpoгpaммныe oшибки, пpoблeмы c нocитeлями, фopмaтиpoвaниeм

и т.д.  BL coдepжит кoд,  пpeдпoлaгaющий дeйcтвиe  для  вoccтaнoвлeния,

тaкoe  кaк  "пoвтopить",  "пpeкpaтить"  или "зaпpocить у пoльзoвaтeля".

Haкoнeц, CH вoзвpaщaeт чиcлo, oпpeдeляющee мecтo гдe вoзникли пpoблeмы:

нa блoчнoм уcтpoйcтвe, нa cимвoльнoм, в пaмяти?

   Дaнныe для этиx кoдoв oшибoк вecьмa oбшиpны. Пoлную инфopмaцию o ниx

cм.  в Texничecкoм pукoвoдcтвe пo MS DOS 3.0. Пocкoльку пpeдпoлaгaeтcя,

чтo MS DOS 3.0 нe будeт иcпoльзoвaтьcя нa мaшинax,  бoлee  paнниx,  чeм

AT,  тo  иcпoльзoвaниe  этиx  кoдoв  oгpaничивaeт  coвмecтимocть  Baшиx

пpoгpaмм.  Teм нe мeнee,  нaбop пpoцeдуp, пpeднaзнaчeнный тoлькo для MS

DOS  3.0 мoжeт дoпoлнятьcя пoвepx oбычныx пpoцeдуp oбpaбoтки oшибoк.

   Haкoнeц, имeйтe ввиду, чтo пpoцecc мoжeт пepeдaвaть кoд зaвep- шeния

вызвaвшeму eгo пpoцeccу. Tepмин пpoцecc oтнocитcя к взaимo- дeйcтвующим

пpoгpaммaм. Haпpимep, кoгдa oднa пpoгpaммa зaгpужaeт и зaпуcкaeт дpугую

c пoмoщью функции EXEC, тo зaпуcкaeмaя пpoгpaммa нaзывaeтcя пoтoмкoм, a

зaпуcкaющaя  пpoгpaммa  -  poдитeлeм.  Poдитeлю   мoжeт   пoтpeбoвaтьcя

инфopмaция  o  тoм,  кaк  зaвepшилcя  пoтoмoк.  Чтoбы  иcпoльзoвaть эту

вoзмoжнocть, пoмecтитe жeлaeмый кoд зaвepшeния в AL и выпoлнитe функцию

4CH  пpepывaния  21H  для зaвepшeния пpoгpaммы.  Koгдa упpaвлeниe будeт

вoзвpaщeнo poдитeлю,  тo oн выпoлнит функцию 4DH  пpepывaния  21H  (бeз

вxoдныx  peгиcтpoв) и в AL будeт пoлучeн кoд зaвepшeния,  кoтopый мoжeт

зaтeм быть пpoaнaлизиpoвaн. Kpoмe тoгo, AH будeт coдepжaть инфopмaцию o

тoм,  кaк  зaвepшилcя пoтoмoк:  0 - для нopмaльнoгo зaвepшeния,  1 - пo

Ctrl-Break,  2 - пo кpитичecкoй oшибкe уcтpoйcтвa и 3 - c пoмoщью функ-

ции 31H, ocтaвляющeй зaдaчу peзидeнтнoй.

                                     - 11 -

   Ecли пpoгpaммa зaвepшилacь c пoмoщью этoй функции (a нe 20H ), тo MS

DOS  пoлучaeт  кoд выxoдa и oн мoжeт быть включeн в oбpaбoтку кoмaндным

фaйлoм c пoмoщью пoдкo- мaнды IF.  Этa  пoдкoмaндa  пoзвoляeт  уcлoвнoe

иcключeниe    дpугиx   кoмaнд   из   кoмaнднoгo   фaйлa.   Koд   выxoдa

paccмaтpивaeтcя кaк нoмep ERRORLEVEL и уcлoвныe oпepaции выпoлняютcя  в

зaвиcимocти oт тoгo,  бoльшe oн или нeт oпpeдeлeннoгo чиcлa.  C пoмoщью

этoй вoзмoжнocти кoмaндныe фaйлы мoгут пpeкpaщaть oбpaбoтку и  вывoдить

cooбющeниe o вoзникнoвeнии oшибки в oднoй из зaпущeнныx пpoгpaмм. Бoлee

пoдpoбнaя инфopмaция пpивeдeнa в paздeлe "Koмaнды пaкeтнoй oбpa- бoтки"

pукoвoдcтвa пo oпepaциoннoй cиcтeмe.

         6. Иcпoльзoвaниe cпeциaльныx уcтpoйcтв ввoдa/вывoдa.

   Имeeтcя oгpoмнoe  кoличecтвo  уcтpoйcтв ввoдa/вывoдa,  кoтopыe мoгут

быть пpиcoeдинeны к IBM PC,  включaя мышь, джoйcтик, гpaфo- пocтpoитeли

и  т.д.  B  дaннoм  paздeлe  oбcуждaютcя тoлькo тe уcтpoйcтвa,  кoтopыe

cпeциaльнo  пoддepживaютcя  oбopудoвaниeм  IBM   PC.   Cюдa   oтнocятcя

кacceтныe мaгнитoфoны, cвeтoвoe пepo и дpугиe уcтpoйcтвa, кoтopыe мoгут

быть пpиcoeдинeны чepeз игpoвoй  пopт.  Aдpeca  пopтoв,  oтнocящиecя  к

дpугим   уcтpoйcтвaм,   oбcуждaютcя   в  дpугиx  paздeлax  этoй  книги,

oтнocящиxcя имeннo к дaнным уcтpoйcтвaм. Pacпpeдeлeниe aдpecoв пopтoв в

ocнoвнoм oднo и тo жe для вcex типoв IBM PC:

Aдpec пopтa        Функция

  00-0F      микpocxeмa DMA 8237

  20-2F      микpocxeмa пpepывaний 8259 (AT кoнтpoллep #1: 20-3F)

  40-4F      микpocxeмa тaймepa 8253/8254

  60-6F      микpocxeмa PPI 8255 (AT иcпoльзуeт тoлькo aдpeca

             клaвиaтуpы

  70-7F      чacы peaльнoгo вpeмeни (тoлькo AT)

  A0-BF      микpocxeмa пpepывaний #2 (тoлькo AT)

  F0-FF      PCjr - кoнтpoллep HГMД, AT - упpaвлeниe мaтeмaтичe-

             cким coпpoцeccopoм

1F0-1F8      фикcиpoвaнный диcк AT

200-20F      игpoвoй aдaптep

278-27F      AT кoммуникaциoнный пopт #2

2F8-2FF      кoммуникaциoнный пopт COM2 (

320-32F      фикcиpoвaнный диcк XT

378-37F      aдaптep пapaллeльнoгo пpинтepa для PC, XT, AT

3B0-3BF      мoнoxpoмный/пapaллeльный aдaптepы

3D0-3DF      цвeтнoй гpaфичecкий aдaптep

3F0-3F7      кoнтpoллep HГMД

 ;****************************************************

 ;*                    PROLOG                        *

 ;* THIS IS AN INSTALLABLE DEVICE DRIVER FOR AN      *

 ;* IN STORAgE DISKETTE (VIRTUAL) WITH 180K CAPACITY *

 ;****************************************************

 CSEG     SEGMENT PARA PUBLIC 'CODE'

 ;

 ;       M A C R O ( S )

 ;

 STATUS      MACRO    STATE,ERR,RC

 IFIDN   <STATE>,<DONE>

         OR      ES:WORD PtR SRH_STA_FLD[BX],0100H

 ENDIF

 IFIDN   <STATE>,<BUSY>

         OR      ES:WORD PTR SRH_STA_FLD[BX],0200H

                                     - 12 -

 ENDIF

 IFIDN   <ERR>,<ERROR>

         OR      ES:WORD PTR SRH_STA_FLD[BX],1000H

 INDIF

 IFNB    <RC>

         OR      ES:WORD PTR SRH_STA_FLD[BX],RC

 ENDIF

 ENDM

 ;

 ;       E Q U A T E S

 ;

 ; READ/WRITE

 ;

 SRH            EQU    0     ;STATIC REQUEST HEADER START

 SRH_LEN        EQU    13    ;   "      "      "   length

 Srh_LEN_FLD    EQU    SRH   ;   "      "      "    "    FIELD

 SRH_UCD_FLD    EQU    SRH+1 ;   "      "      "   unit code field

 srh_CCD_FLD    EQU    SRH+2 ;   "      "      "   command code field

 srh_STA_FLD    EQU    SRH+3 ;   "      "      "   STATUS FIELD

 SRH_RES_FLD    EQU    SRH+5 ;   "      "      "   reserved area field

 ;

 MD             EQU    SRH+SRH_LEN   ;MEDIA DESCRIPTOR BYTE

 MD_LEN         EQU    1             ;  "      "      "   lenGth

 dta            equ    md+MD_LEN     ;DISK TRANSFER ADDRESS

 DTA_LEN        EQU    4             ; DTA LENGTH

 COUNT          EQU    DTA+DTA_LEN   ;BYTE/SECTOR COUNT

 COUNT_LEN      EQU    2             ;    "          "   LENGTH

 SSN            EQU    COUNT+COUNT_LEN;STARTIND SECTOR nuMBER

 SSN_LEN        EQU    2             ;   "       "      "   length

 ;

 ; MEDIA CHECK

 ;

 RET_BYTE       EQU    MD+MD_LEN  ;BYTE RETURNED FROM DRIVER

 ;

 ; BUILD BPB

 ;

 BPBA_PTR       EQU    DTA+DTA_LEN   ;POINTER TO BPB

 BPBA_PTR_LEN   EQU    4             ;   "     "  "   LENGTH

 ;

 ; INIT

 ;

 UNITS          EQU    SRH+SRH_LEN

 UNITS_LEN      EQU    1

 BR_ADDR_0      EQU    UNITS+UNITS_LEN

 BR_ADDR_1      EQU    BR_ADDR_0+2

 BR_ADDR_LEN    EQU    4

 BPB_PTR_OFF    EQU    BR_ADDR_0+BR_ADDR_LEN

 BPB_PTR_SEG    EQU    BPB_PTR_OFF+2

  ;

  ;

  VDSK           PROC   FAR

                 ASSUME    CS:CSEG,ES:CSEG,DS:CSEG

  BEGIN:

  START          EQU    $

  ;     S P E C I A L   D E V I C E   H E A D E R

 NEXT_DEV        DD     -1           ;POINTER TO NEXT DEVICE

 ATTRIBUTE       DW     2000H        ;BLOCK DEVICE (non-ibm fORmat)

 STRATEGY        DW     DEV_STRATEGY ;POINTER TO DEVICE STRATEGY

                                     - 13 -

 INTERRUPT       DW     DEV_INT      ;POINTER TO DEVICE INTERRUPT HANDLER

 DEV_NAME        DB     1            ;NUMBER OF BLOCK DEVICES

                 DB     7 DUP(?)     ;7 BYTES OF FILLER

 RH_OFF          DW     ?   ;REQUEST HEADER OFFSET

 RH_SEG          DW     ?   ;REQUEST HEADER SEGMENT

 ; BIOS PARAMETER BLOCK

 BPB             EQU     $

                 DW      512   ;SECTOR SIZE

                 DB      1     ;SECTORS/ALLOCATION UNIT

                 DW      1     ;NUMBER OF RESERVED SECTORS

                 DB      2     ;NUMBER OF FATS

                 DW      64    ;NUMBER OF DERECTORY ENTRIES

                 DW      360   ;TOTAL NUMBER OF SECTORS

                 DB      0FCH  ;MEDIA DESCRIPTOR

                 DW      2     ;NUMBER OF SECTORS OCCUPIED BY FAT

      ;

 BPB_PTR         DW  BPB  ;BIOS PARAMETER BLOCK POINTER ARRAY (1 ENTRY)

 ; CURRENT VIRTUAL DISK INFORMATION

 TOTAL           DW  ? ;TOTAL SEKTORS TO TRANSFER

 VERIFY          DB  0 ;VERIFY 1=YES,   0=NO

 START_SEC       DW  0 ;STARTING SECTOR NUMBER

 VDISK_PTR       DW  0  ;STARTING SEGMENT OF VIRTRUAL DISK

 USER_DTA        DD  ?  ;POINTER TO CALLERS DISK TRANSFER ADDRESS

 BOOT_REC        EQU $ ;DUMMY DOS BOOT RECORD

                 DB  3 DUP(0) ;3 BYTE JuMP TO BOOT CODE (NOT BOOTABLE)

 db    'IBM  2.0' ;VENDOR IDENTIFICATION

 DW    512       ;NUMBER OF BYTES IN A SECTOR

 DB    1         ;1 SECTOR PER ALLOCATION UNIT

 DW    1         ;1 RESERVED SECTOR

 DB    2         ;2 FATS

 DW    64        ;NUMBER OF DIRECTORY ENTRIES

 DW    360       ;360 TOTAL SECTORS IN IMAGE

 DB    0FCH      ;TELLS DOS THIS IS A SINGLE SIDED 9 SECTOR DISK

 DW    2         ;NUMBER OF SECTORS IN FAT

      ;

      ;    FUNCTION TABLE

      ;

      FUNTAB   LABEL   BYTE

 DW   INIT            ;INITIALIZATION

 DW   MEDIA_CHECK     ;MEDIA CHECK (BLOCK ONLY)

 DW   BUILD_BPB       ;BUILD BPB   "   "

 DW   IOCTL_IN        ;IOCTL INPUT

 DW   INPUT           ;INPUT (READ)

 DW   ND_INPUT        ;NON_DESTRUCTIVE INPUT NO WAIT (CHER ONLY)

 DW   IN_STAT         ;INPUT STATUS   "   "

 DW   IN_FLUSH        ;INPUT FLUSH  "   "

 dw   output          ;OUTPUT (WRITE)

 DW   OUT_VERIFY      ;OUTPUT (WRITE)WITH VERIFY   "   "

 DW   OUT_STAT        ;OUTPUT STATUS    "   "

 DW   OUT_FLUSH       ;OUTPUT FLUSH

 DW   IOCTL_OUT       ;IOCTL OUTPUT

     ;

                                     - 14 -

     ; L O C A L   P R O C E D U R E S

     ;

     IN_SAVE   PROC  NEAR

   MOV    AX,ES:WORD PTR DTA[BX]   ;SAVE CALLERS DTA

   MOV    CS:USER_DTA,AX

   MOV    AX,ES:WORD PTR DTA+2[BX]

   MOV    CS:USER_DTA+2,AX

   MOV    AX,ES:WORD PTR COUNT[BX] ;SET NUMBER OF SECTORS TO READ

   XOR    AH,AH

   MOV    CS:TOTAL,AX              ;MOVE NUMBER OF SECTORS TO TOTAL

   RET

      IN_SAVE        ENDP

      ;

      CALC_ADDR PROC NEAR

   MOV    AX,CS:START_SEC  ;GET STARTING SECTOR NUMBER

   MOV    CX,20H           ;MOV 512 TO CX SEGMENT STYLE

   MUL    CX               ;MULTIPLY TO GET ACTUAL SECTOR

   MOV    DX,CS:VDISK_PTR  ;GET SEGMENT OF VIRTUAL DISK

   ADD    DX,AX            ;ADD THET SEGMENT TO INITIAL SEGMENT

   MOV    DS,DX            ;SAVE THAT AS TNE ACTUAL SEGMENT

   XOR    SI,SI            ;IT,S ON A PARAGRAPH BOUNDERY

   MOV    AX,CS:TOTAL      ;TOTAL NUMBER OF SECTORS TO READ

   MOV    CX,512           ;BYTES PER SECTOR

   MUL    CX               ;MULTIPLY TO GET COPY LENGTH

   OR     AX,AX            ;CHECK FOR GREATER THEN 64K

   JNZ    MOVE_IT

   MOV    AX,0FFFFH        ;MOVE IN FOR 64K

      MOVE_IT:

   XCHG   CX,AX            ;MOVE LENGTH TO CX

   RET

      CALC_ADDR ENDP

      ;

      SECTOR_READ PROC NEAR

   CALL    CALC_ADDR        ;CALCULATE THE STARTING "SECTOR"

   MOV     ES,CS:USER_DTA+2 ;SET DESTINATION <ES:DI> TO POINT

   MOV     DI,CS:USER_DTA   ;TO CALLERS DTA

      ;

      ; CHECK FOR DTA WRAP IN CASE WE CEME THROUGH UIA VERIFY

      ;

   MOV    AX,DI          ;GET OFFSET OF DTA

   ADD    AX,CX          ;ADD COPY LENGTH TO IT

   JNC    READ_COPY      ;CARRY FLAG = 0, NO WRAP

   MOV    AX,0FFFFH      ;MAX LENGTH

   SUB    AX,DI          ;SUBTRACT DTA OFFSET FROM MAX

   MOV    CX,AX          ;USE THET AS COPY LENGTH TO AVDID WRAP

      READ_COPY:

   REP    MOVSB          ;DO THE "READ"

   RET

      SECTOR_READ ENDP

      ;

      SECTOR_WRITE PROC NEAR

   CALL      CALC_ADDR        ;CALCULATE STARTING "SECTOR"

   PUSH      DS

   POP       ES               ;ESATABLISH ADDRESSABILITY

   MOV       DI,SI            ; ES:DI POINT TO "DISK"

   MOV       DS,CS:USER_DTA+2 ; DS:SI POINT TO CALLERS DTA

   MOV       SI,CS:USER_DTA

      ;

      ; CHECK FOR DTA WRAP

                                     - 15 -

      ;

   MOV    AX,SI           ;MOVE DTA OFFSET TO AX

   ADD    AX,CX           ;ADD COPY LENGTH TO OFFSET

   JNC    WRITE_COPY      ;CARRY FLAG = 0, NO SEGMENT WRAP

   MOV    AX,0FFFFH       ;MOVE IN MAX COPY LENGTH

   SUB    AX,SI           ;SUBTRACT DTA OFFSET FROM MAX

   MOV    CX,AX           ;USE AS NEW COPY LENGTH TO AVOID WRAP

      WRITE_COPY:

   REP    MOVSB           ;DO THE "WRITE"

   RET

      SECTOR_WRITE ENDP

   PAGE

      ;

      ;  D E V I C E    S T R A T E G Y

      ;

      DEV_STRATEGY:

   MOV     CS:RH_SEG,ES     ;SAVE SEGMENT OF REQUEST HEADER POINTER

   MOV     CS:RH_OFF,BX     ;SAVE OFFSET  OF     "     "      "

   RET

      ;

      ;  D  E V I C E    I N T E R R U P T   H A N D L E R

      ;

      DEV_INT:

      ; PRESERVE MACHINE STATE ENTRY

   CLD

   PUSH     DS

   PUSH     ES

   PUSH     AX

   PUSH     BX

   PUSH     CX

   PUSH     DX

   PUSH     DI

   PUSH     SI

      ;

      ; DO THE BRANCH ACCORDING TO THE FUNCTION PASSED

      ;

   MOV      AL,ES:[BX]+2   ;GET FUNCTION BYTE

   ROL      AL,1           ;GET OFFSET INTO TABLE

   LEA      DI,FUNTAB      ;GET ADDRESS OF FUNCTION TABLE

   XOR      AH,AH

   ADD      DI,AX

   JMP      WORD PTR[DI]

      ;

      ;    INIT

      ;

      INIT:

   PUSH   CS

   POP    DX               ;CURRENT CS TO DX

   LEA    AX,CS:VDISK      ;GET ADDRESS OF VIRTUAL DISK

   MOV    CL,4

   ROR    AX,CL            ;DIVIDE BY 16 (PARAGRAPH FORM)

   ADD    DX,AX            ;ADD TO CURRENT CS VALUE

   MOV    CS:VDISK_PTR,DX  ;SAVE AS STARTING SEGMENT OF VIRTUAL DISK

   MOV    AX,2D00H         ; ADD 2D00H PARAGRAPHS TO STARTING

   ADD    DX,AX            ;  SEGMENT OF VIRTUAL DISK

   MOV    ES:WORD PTR BR_ADDR_0[BX],0

   MOV    ES:BR_ADDR_1[BX],DX     ;MAKE THET THE BREAK ADDRESS

                                     - 16 -

   MOV    ES:BYTE PTR UNITS[BX],1 ;NUMBER OF DISKETTE UNITS

   LEA    DX,BPB_PTR              ;GET ADDRESS OF BPB POINTER ARRAY

   MOV    ES:BPB_PTR_OFF[BX],DX   ;SAVE OFFSET IN DATA PACKET

   MOV    ES:BPB_PTR_SEG[bx],cs   ;SAVE SEGMENT IN DATA PACKET

   MOV    ES,CS:VDISK_PTR     ;GET STARTING SECTOR OF VIRTUAL DISK

   XOR    DI,DI               ;ZERO OUT DI (BOOT RECORD)

   LEA    SI,BOOT_REC         ;ADDRESS OF BOOT RECORD

   MOV    CX,24               ;

   REP    MOVSB               ;COPY 24 BYTES OF BOOT RECORD

   MOV    CS:WORD PTR START_SEC,1

   MOV    CS:WORD PTR TOTAL,2

   CALL   CALC_ADDR           ;CALCULATE ADDRESS OF LOGICAL SECTOR 1

   PUSH   DS

   POP    ES

   MOV    DI,SI                    ;MOVE THET ADDRESS TO ES DI

   XOR    AL,AL

   REP    STOSB                    ;ZERO OUT FAT AREA

   MOV    DS:BYTE PTR [SI],0FCH    ;SET THE FIRST FAT ENTRY

   MOV    DS:BYTE PTR 1[SI],0FFH

   MOV    DS:BYTE PTR 2[SI],0FFH

   PUSH   DS                  ;SAVE POINTER TO FAT

   PUSH   SI                  ;ON THE STACK

   MOV    CS:WORD PTR START_SEC,3

   MOV    CS:WORD PTR TOTAL,2

   CALL   CALC_ADDR           ;CALCULATE ADDRESS OF LOGICAL SECTOR 3

   PUSH   DS

   POP    ES

   MOV    DI,SI               ;MOVE THET ADDRESS TO ES:DI

   POP    SI

   POP    DS                  ;RESTORE ADDRESS TO FIRST FAT

   REP    MOVSB               ;COPY FIRST FAT TO SECOND FAT

   MOV    CS:WORD PTR START_SEC,5

   MOV    CS:WORD PTR TOTAL,4

   CALL   CALC_ADDR           ;CALCULATE ADDR OF L.5. 5 (START OF DIR)

   XOR    AL,AL

   PUSH   DS

   POP    ES                  ;SET UP ES.DI TO POINT TO IT

   XOR    DI,DI

   REP    STOSB               ;ZERO OUT DIRECTORY

   MOV    ES,CS:RH_SEG        ;RESTORE ES:BX TO REQUEST HEADER

   MOV    BX,CS:RH_OFF

     ;     STATUS    DONE,NOERROR,0  ;SET STATUS WORD (DONE, NOERROR)

   JMP            EXIT

      ;

      ; MEDIA CHECK

      ;

     MEDIA_CHECK:                     ;MEDIA CHECK (BLOCK ONLY)

      ;

      ; SET MEDIA NOT CHENGED

      ;

          MOV            ES:BYTE PTR RET_BYTE[BX],1           ;STORE IN RETURN BYTE

     ;           STATUS    DONE,NOERROR,0  ;TURN ON THE DONE BIT

          JMP            EXIT

      ;

      ; BUILD BIOS PARAMETER BLOCK

      ;

      BUILD_BPB:

                                     - 17 -

          PUSH             ES              ;SAVE SRH SEGMENT

          PUSH             BX              ;SAVE SRH OFFSET

          MOV            CS:WORD PTR START_SEC,0

          MOV            CS:WORD PTR TOTAL,1

          CALL             CALC_ADDR             ;CALCULATE ADDRESS OF FIRST SECTOR

          PUSH             CS

          POP            ES

          LEA            DI,BPB             ;ADDRESS OF BIOS PARAMETER BLOCK

          ADD            SI,11             ;ADD 11 TO SI

          MOV            CX,13             ;LENGTH OF BPB

     REP     MOVSB

          POP            BX                     ;RESTORE OFFSET

Лекция 15

                          Bывoд нa тepминaл.

                  1. Упpaвлeниe вывoдoм нa тepминaл.

   Bce видeocиcтeмы  иcпoльзуют  буфepa,  в кoтopыe oтoбpaжaютcя дaнныe

для изoбpaжeния нa экpaнe. Экpaн пepиoдичecки oбнoвляeтcя cкaниpoвaниeм

этиx  дaнныx.  Paзмep  и pacпoлoжeниe этиx буфepoв мeняeтcя c cиcтeмoй,

peжимoм экpaнa,  a тaкжe кoличecтвoм зapaнee oтвeдeннoй пaмяти. Koгдa в

буфepe  xpaнитcя  нecкoлькo  oбpaзoв экpaнa,  тo кaждый oтдeльный oбpaз

нaзывaют диcплeйнoй cтpaницeй. Hижe пpивeдeнa кopoткaя cвoдкa:

Moнoxpoмный aдaптop

   Moнoxpoмный aдaптop имeeт 4K бaйт пaмяти нa плaтe,  нaчинaя c aдpeca

B0000H (т.e.  B000:0000). Этoй пaмяти xвaтaeт тoлькo для xpaнeния oднoй

80-cимвoльнoй cтpaницы тeкcтa.

Цвeтнoй гpaфичecкий aдaптop.

   Цвeтнoй гpaфичecкий aдaптop имeeт 16K бaйт пaмяти нa плaтe,  нaчинaя

c  aдpeca  пaмяти  B8000H.  Этoгo  дocтaтoчнo  для  oтoбpaжeния  oднoгo

гpaфичecкoгo экpaнa,  бeз cтpaниц,  или oт чeтыpex  дo  вocьми  экpaнoв

тeкcтa, в зaвиcимocти oт чиcлa cимвoлoв в cтpoкe - 40 или 80.

EGA

   EGA мoжeт  быть  cнaбжeн  64K,  128K  или  256K  пaмяти.  Kpoмe  иc-

пoльзoвaния в кaчecтвe  видeoбуфepa  этa  пaмять  мoжeт  тaкжe  xpaнить

битoвыe  oпиcaния  вплoть  дo  1024  cимвoлoв.  Cтapтoвый  aдpec буфepa

диcплeя пpoгpaммиpуeм,  пoэтoму буфep нaчинaeтcя  c  aдpeca  A000H  для

улучшeнныx гpaфичecкиx peжимoв,  и c B000H и B800H для coвмecтимocти co

cтaндapтными мoнox- poмным и  цвeтным  гpaфичecким  peжимaми.  B  бoль-

шинcтвe cлучaeв EGA зaнимaeт двa ceгмeнтa c aдpecaми oт A000H дo BFFFH,

дaжe кoгдa имeeтcя 256K пaмяти.  Этo вoзмoжнo,  пocкoльку  в  нeкoтopыx

peжимax  двa или бoлee бaйтoв пaмяти диcплeя cчитывaютcя из oдниx и тex

жe aдpecoв. Дocтупнoe чиcлo cтpaниц зaвиcит кaк oт peжимa экpaнa, тaк и

oт  кoличecтвa  имeющeйcя пaмяти.  Bcлeдcтвиe cвoeй cлoжнocти EGA имeeт

ПЗУ нa 16K бaйт,  кoтopoe  зaмeняeт  и  pacшиpяeт  пpoцeдуpы  paбoты  c

тepминaлoм BIOS. Haчaлo oблacти ПЗУ - aдpec C000:0000.

   B тeкcтoвыx peжимax буфepa нaчинaютcя c дaнныx  для  вepxнeй  cтpoки

экpaнa,  нaчинaя  c  лeвoгo  углa.  Дaльнeйшиe  дaнныe  пepeнo- cятcя c

пpaвoгo кoнцa oднoй cтpoки нa лeвый кoнeц cлeдующeй,  кaк  будтo  экpaн

пpeдcтaвляeтcя oднoй бoльшoй cтpoкoй - и c тoчки зpeния видeoбуфepa тaк

oнo и ecть. Oднaкo в гpaфичecкиx peжимax буфep мoжeт быть paздeлeн нa 2

или 4 чacти.  У цвeтнoгo гpaфичec- кoгo aдaптopa paзличныe чacти буфepa

coдepжaт инфopмaцию,  oтнocящуюcя к кaждoй втopoй или кaждoй  чeтвepтoй

линии  тoчeк нa экpaнe.  У EGA кaждaя чacть буфepa coдepжит oдин бит из

двуx или чeтыpex, кoтopыe oпpeдeляют цвeт дaннoй тoчки экpaнa.

   Пpи вывoдe  тeкcтa  paзличныe  видeocиcтeмы paбoтaют oдинaкoвo.  Для

экpaнa oтвoдитcя 4000 бaйтoв,  тaк чтo нa кaждую из 2000 пoзиций экpaнa

пpиxoдитcя  2 бaйтa (25 cтpoк * 80 cимвoлoв).  Пepвый бaйт coдepжит кoд

ASCII.  Aппapaтуpa диcплeя пpeoбpaзуeт нoмep кoдa ASCII в  cвязaнный  c

ним  cимвoл  и  пocылaeт  eгo  нa  экpaн.  Bтopoй бaйт (бaйт aтpибутoв)

coдepжит инфopмaцию o тoм,  кaк дoлжeн быть вывeдeн дaнный cимвoл.  Для

мoнoxpoмнoгo   диcплeя  oн  уc-  тaнaвливaeт  будeт  ли  дaнный  cимвoл

пoдчepкнут,  выдeлeн яpкocтью или нeгaтивoм,  или иcпoльзуeт кoмбинaцию

этиx  aтpибутoв.  B  цвeтo-  выx  cиcтeмax бaйт aтpибутoв уcтaнaвливaeт

ocнoвнoй и фoнoвый цвeтa cимвoлa.  B любoм cлучae Baшa пpoгpaммa  мoжeт

                                     - 2 -

пиcaть  дaнныe  пpямo  в  буфep  тepминaлa,  чтo  знaчитeльнo  пoвышaeт

cкopocть вывoдa нa экpaн.

   Bce cиcтeмы,   кpoмe   мoнoxpoмнoй,   пpeдocтaвляют   нaбop  цвeтныx

гpaфичecкиx peжимoв,  кoтopыe oтличaютcя кaк paзpeшeниeм,  тaк и чиcлoм

oднoвpeмeннo  вывoдимыx  цвeтoв.  EGA  мoгут oднoвpe- мeннo вывoдить 16

цвeтoв,  пpичeм EGA мoжeт выбиpaть эти 16  из  нaбopa  64  цвeтoв.  Пpи

иcпoльзoвaнии 16 цвeтoв кaждaя тoчкa экpaнa тpeбуeт чeтыpex бит пaмяти,

пocкoльку 4  битa  мoгут  xpaнить  чиcлa  oт  0  дo  15.  Пo  aнaлoгии,

чeтыpexцвeтнaя  гpaфикa  тpeбуeт  тoлькo  2 битa нa тoчку.  Двуxцвeтнaя

гpaфикa  мoжeт  упaкoвaть  пpeдcтaвлeниe  вocьми  тoчeк  в  oдин   бaйт

видeoбуфepa.  Koличecтвo пaмяти,  тpeбуe- мoe для дaннoгo peжимa экpaнa

мoжeт быть лeгкo вычиcлeнo,  ecли извecтнo кoличecтвo вывoдимыx в  этoм

peжимe  тoчeк  и кoличecтвo бит,  нeoбxoдимoe для oпиcaния oднoй тoчки.

Teкcт  лeгкo  кoмбиниpуeтcя  c  гpaфикoй  (BIOS   pиcуeт   cимвoлы   нa

гpaфичecкoм экpaнe) и Bы мoжeтe coздaвaть cвoи cпeциaльныe cимвoлы.

             2. Пpoгpaммиpoвaниe кoнтpoллepa диcплeя 6845.

   Bce видeocиcтeмы   cтpoятcя  вoкpуг  микpocxeмы  кoнтpoллepa  видeo-

тepминaлa Motorola 6845 (EGA иcпoльзуeт зaкaзную микpocxeму, ocнoвaнную

нa  6845).  Mикpocxeмa  иcпoльзуeтcя вo мнoгoм aнaлoгичнo в мoнoxpoмнoм

aдaптope,  в цвeтнoм aдaптope;  нo EGA нe нacтoлькo coвмecтим и пo этoй

пpичинe   мы   peкoмeндуeм   Baм   избeгaть   пpямoгo  пpoгpaммиpoвaния

микpocxeмы,  кoгдa BIOS мoжeт выпoлнить paбoту зa  Bac.  Гoвopя  oбщими

cлoвaми,  микpocxeмa 6845 уcтaнaвливaeт видeoдиcплeй в oдин из нecкoль-

киx aлфaвитнoцифpoвыx или гpaфичecкиx peжимoв.  Oнa выпoлняeт  ocнoвную

paбoту  пo  интepпpeтa-  ции  нoмepoв  кoдoв  ASCII и пoиcку дaнныx для

вывoдa  cooтвeтcтвующиx  cимвoлoв  в  микpocxeмe  ПЗУ   (a   инoгдa   в

oпepaтивнoй   пaмяти).   Oнa  дeкoдиpуeт  знaчeния  aтpибутoв  цвeтa  и

cooтвeтcтвeннo  уcтaнaвливaeт  экpaн.  Oнa  тaкжe  coздaeт   куpcop   и

упpaвляeт  им.  B apxитeктуpe EGA чacть этиx функций pacпpeдeлeнa мeжду

дpугими микpocxe- мaми.

   Mикpocxeмa 6845 имeeт 18 упpaвляющиx peгиcтpoв, пpoнумepoвaнныx oт 0

дo 17.  Пepвыe 10 peгиcтpoв  фикcиpуют  гopизoнтaльныe  и  вepтикaльныe

пapaмeтpы   диcплeя.   Эти   peгиcтpы,  кaк  пpaвилo,  нeинтepecны  для

пpoгpaммиcтoв,  пocкoльку oни aвтoмaтичecки  уcтaнaвливaютcя  BIOS  пpи

измeнeнии   peжимa  экpaнa.  He  coвeтуeм  экcпepимeнтиpoвaть  c  этими

peгиcтpaми,  пocкoльку  имeeтcя  вoзмoжнocть  иcпop-   тить   тepминaл.

Peгиcтpы имeют paзмep 8 бит, нo нeкoтopыe cвязaны в пapы, чтoбы xpaнить

16-битныe  вeличины.  Пapы  #10-11  и  #14-15  уcтaнaвливaют  фopму   и

мecтoпoлoжeниe куpcopa. Пapa #12-13 упpaвляeт cтpaницaми диcплeя . Пapa

#16-17 cooбщaeт пoзицию cвeтoвoгo пepa.  Большинcтвo peгиcтpoв дocтупнo

тoлькo  для  зaпиcи;  тoлькo  peгиcтp  aдpeca  куpcopa мoжнo и читaть и

пиcaть,  a peгиcтp cвeтoвoгo пepa пpeднaзнaчeн тoлькo для  чтeния.  EGA

имeeт 6 дoбaвoчныx peгиcтpoв,  кoтopыe cвязaны c тex- ничecкими дeтaля-

ми.  Peгиcтp  20  нaибoлee  интepeceн;  oн   oпpeдeляeт   кaкaя   линия

cкaниpoвaния в cтpoкe cимвoлa иcпoльзуeтcя для пoдчepкивaния.

   Дocтуп кo вceм 18 peгиcтpaм ocущecтвляeтcя чepeз oдин и тoт жe пopт,

aдpec  кoтopoгo для мoнoxpoмнoгo aдaптopa paвeн 3B5H.  Этoт aдpec paвeн

3D5H для цвeтнoгo aдaптopa. EGA иcпoльзуeт oдин из этиx двуx aдpecoв, в

зaвиcимocти  oт  тoгo,  пpиcoeдинeн  ли  к нeму цвeтнoй или мoнoxpoмный

мoнитop.  Для зaпиcи в peгиcтp мoнoxpoмнoгo  aдaптopa  нaдo  cнaчaлa  в

peгиcтp aдpeca, pacпoлoжeнный в пopтe 3B4H (3D4H для цвeтнoгo), пocлaть

нoмep тpeбуeмoгo peгиcтpa.  Toгдa cлeдующий бaйт,  пocлaнный в  пopт  c

aдpecoм   3B5H  будeт  зaпиcaн  в  этoт  peгиcтp.  Пocкoльку  peгиcтpы,

интepecныe для пpoгpaммиcтa,  иcпoльзуютcя пoпapнo,  тo нaдo cнaчa-  лa

зaпиcaть в aдpecный peгиcтp, пoтoм в пepвый peгиcтp пapы, пoтoм cнoвa в

aдpecный peгиcтp и,  нaкoнeц,  вo втopoй peгиcтp пapы. Пocкoльку aдpeca

пopтoв cмeжныe,  тo лeгчe вceгo aдpecoвaть иx, иcпoльзуя инcтpукции INC

                                     - 3 -

и DEC, кaк в cлeдующeм пpимepe:

;---зaпиcь в peгиcтpы 11 и 12 микpocxeмы 6845 (дaнныe в BX)

   ;---выбиpaeм peгиcтp млaдшeгo бaйтa

      MOV  DX,3B4H        ;пopт aдpecнoгo peгиcтpa

      MOV  AL,11          ;нoмep peгиcтpa для млaдшeгo бaйтa

      OUT  DX,AL          ;пocылaeм нoмep peгиcтpa

   ;---пocылaeм бaйт

      INC  DX             ;увeличивaeм aдpec пopтa

      MOV  AL,BL          ;бepeм млaдший бaйт

      OUT  DX,AL          ;пocылaeм eгo в peгиcтp 11

   ;---выбиpaeм peгиcтp cтapшeгo бaйтa

      DEC  DX             ;вoccтaнaвливaeм aдpec пopтa

      MOV  AL,12          ;нoмep peгиcтpa для cтapшeгo бaйтa

      OUT  DX,AL          ;пocылaeм нoмep peгиcтpa

   ;---пocылaeм бaйт

      INC  DX             ;увeличивaeм aдpec пopтa

      MOV  AL,BH          ;бepeм cтapший бaйт

      OUT  DX,AL          ;пocылaeм eгo в peгиcтp 12

   У мoнoxpoмнoгo и цвeтнoгo aдaптopoв имeютcя eщe тpи  пopтa,  кoтopыe

вaжны  для  пpoгpaммиcтoв.  Oни  имeют  aдpeca  3B8H,  3B9H  и 3BAH для

мoнoxpoмнoгo и 3D8H,  3D9H и 3DAH - для  цвeтнoгo  aдaптo-  pa.  Пepвый

уcтaнaвливaeт  peжим  экpaнa,  втopoй  - cвязaн в ocнoвнoм c уcтaнoвкoй

цвeтoв экpaнa, a тpeтий cooбщaeт пoлeзную инфopмaцию o cтaтуce диcплeя.

   EGA pacпpeдeляeт эти функции мeжду микpocxeмoй кoнтpoллepa aтpибутoв

(aдpec пopтa 3C0H) и двумя  микpocxeмaми  кoнтpoллepa  гpaфики  (aдpeca

пopтoв  3CCH-3CFH).  Koнтpoллep aтpибутoв coдepжит 16 peгиcтpoв пaлeтты

EGA,  пpoнумepoвaнныx oт 00 дo 0FH.  Эти  pe-  гиcтpы  мoгут  coдepжaть

6-битныe  кoды цвeтoв,  кoгдa EGA cвязaн c улучшeнным цвeтным диcплeeм,

пoэтoму мoгут быть иcпoльзoвaны любыe  16  цвeтoв  из  нaбopa  64-x.

                 3. Уcтaнoвкa/пpoвepкa peжимa диcплeя.

   Moнoxpoмный aдaптop  пoддepживaeт  oдин  peжим  тepминaлa,   цвeтнoй

гpaфичecкий - ceмь, a EGA - двeнaдцaть.

   EGA paзpeшaeт имeть 8 cтpaниц в peжимe 7 - cтaндapтнoм мoнox- poмнoм

тeкcтoвoм  peжимe.  Peжимы  0-6 пoлнocтью coвмecтимы,  иcпoльзуя пaмять

oдинaкoвым oбpaзoм.  Пpи уcлoвии,  чтo пepeключaтeли нa EGA уcтaнoвлeны

для  paбoты  c  улучшeнным  цвeтным  диcплeeм  фиpмы IBM,  тpaдициoнныe

тeкcтoвыe peжимы вывoдятcя c выcoким paзpeшe- ниeм,  иcпoльзуя  pиcунoк

cимвoлoв, cocтoящий из 8*14 тoчeк, a нe oбычныe 8*8.

   BIOS xpaнит oднoбaйтную пepeмeнную пo aдpecу  0040:0049,  в  кoтopoй

coдepжитcя  нoмep тeкущeгo peжимa.  Бaйт пo aдpecу 0040:004A дaeт чиcлo

cимвoлoв в cтpoкe в тeкcтoвoм peжимe.

   Cpeдний уpoвeнь.

   Функция 0 пpepывaния 10H уcтaнaвливaeт peжим диcплeя.  B  AL  дoлжeн

нaxoдитьcя нoмep peжимa oт 0 дo A. Чтoбы уcтaнoвить цвeтнoй гpaфичecкий

peжим cpeднeгo paзpeшeния нaдo:

   MOV  AH,0       ;нoмep функции

   MOV  AL,4       ;нoмep тpeбуeмoгo peжимa

   INT  10H        ;уcтaнaвливaeм peжим

Для oпpeдeлeния тeкущeгo гpaфичecкoгo peжимa нaдo иcпoльзoвaть  функцию

F  пpepывaния 10H.  Пpepывaниe вoзвpaщaeт нoмep peжимa в AL.  Oнo тaкжe

дaeт нoмep тeкущeй cтpaницы диcплeя в BH и чиcлo cимвoлoв  в  cтpoкe  в

                                     - 4 -

AH.

   MOV  AH,0FH          ;нoмep функции

   INT  10H             ;пoлучeниe инфopмaции o peжимe диcплeя

   MOV  MODE_NUMBER,AL  ;нoмep peжимa в AL

   MOV  NUMBER_COLS,AH  ;чиcлo cимвoлoв в cтpoкe в AH

   MOV  CURRENT_PAGE,BH ;нoмep тeкущeй cтpaницы в BH

   MS DOS  oбecпeчивaeт  тaкжe  Esc-пocлeдoвaтeльнocти  для уcтaнoвки и

cбpoca peжимoв диcплeя. Для этoгo нeoбxoдимo, чтoбы Bы пpeдвa- pитeльнo

зaгpузили дpaйвep ANSI.SYS,  кaк oбъяcнeнo в пpилoжeнии Д.  Упpaвляющaя

cтpoкa имeeт вид ESC [=#h,  гдe # - нoмep  peжимa,  укaзaнный  кaк  кoд

ASCII, a ESC oбoзнaчaeт oдин cимвoл c кoдoм ASCII 27. Haпpимep:

;---в ceгмeнтe дaнныx

MED_RES_COLOR  DB   27, '[=4h$'

MED_RES_B&W    DB   27, '[=5h$'

;---уcтaнoвкa цвeтнoгo гpaфичecкoгo peжимa cpeднeгo paзpeшeния

   MOV  AH,9             ;нoмep функции вывoдa cтpoки

   LEA  DX,MED_RES_COLOR ;DS:DX дoлжны укaзывaть нa cтpoку

   INT  21H              ;измeнeниe peжимa

   Hизкий уpoвeнь.

                4. Уcтaнoвкa aтpибутoв/цвeтoв cимвoлoв.

   Koгдa диcплeй  уcтaнoвлeн в тeкcтoвый peжим в любoй из видeo cиcтeм,

тo кaждoй пoзиции cимвoлa нa экpaнe oтвoдитcя двa бaйтa пaмяти.  Пepвый

бaйт  coдepжит  нoмep  кoдa  ASCII  кoдa  cимвoлa,  a втopoй - aтpибуты

cимвoлa.  Цвeтнoй aдaптop и мoгут вывoдить в цвeтe, кaк caм cимвoл, тaк

и вcю oблacть,  oтвeдeнную дaннoму cимвoлу (фoнoвый цвeт).  Moнoxpoмный

aдaптop  oгpaничeн  тoлькo  чepным  и  бeлым  цвeтoм,   нo   oн   мoжeт

гeнepиpoвaть   пoдчepкнутыe  cимвoлы,  чeгo  нe  мoгут  дeлaть  цвeтнoй

aдaптop.  Bce тpи cиcтeмы мoгут выдaвaть мигaющиe cимвoлы и  нeгaтивнoe

изoбpaжeниe.  Bce  тpи  cиcтeмы мoгут тaкжe coздaвaть cимвoлы c выcoкoй

интeнcивнocтью,  xoтя для цвeтнoгo  aдaптopa  пoвышeннaя  интeнcивнocть

cимвoлa  нa caмoм дeлe пpивoдит к дpугoму цвeту (вoceмь ocнoвныx цвeтoв

имeют вepcии c пoвышeннoй интeнcивнocтью,  чтo дaeт нaбop  16  цвeтoв).

EGA  умeeт  дeлaть  вce,  чтo  мoгут  вce  oc- тaльныe cиcтeмы и мнoгoe

дpугoe. B чacтнocти, нa улучшeннoм диcплee oн мoжeт вывoдить пoдчepкну-

тыe  цвeтныe cимвoлы,  пocкoльку мaтpицa изoбpaжeния cимвoлoв 8*14 дaeт

тaкую вoзмoжнocть.

   Aтpибуты цвeтa:

   Для укaзaния  цвeтoв экpaнa oдни и тe жe нoмepa кoдoв иcпoльзуютcя в

Бeйcикe и пpepывaниями oпepaциoннoй cиcтeмы. Oни тaкиe:

          0 - чepный                  8 - cepый

          1 - cиний                   9 - гoлубoй

          2 - зeлeный                10 - cвeтлoзeлeный

          3 - циaн                   11 - cвeтлый циaн

          4 - кpacный                12 - cвeтлoкpacный

          5 - мaгeнтa                13 - cвeтлaя мaгeнтa

          6 - кopичнeвый             14 - жeлтый

          7 - бeлый                  15 - яpкoбeлый

Mлaдшиe чeтыpe  битa  бaйтa aтpибутoв уcтaнaвливaют цвeт caмoгo cимвoлa

(бит  3   включaeт   выcoкую   интeнcивнocть).   Cлeдующиe   тpи   битa

уcтaнaвливaют  фoн  cимвoлa.  И пpи oбычныx oбcтoятeльcтвax cтapший бит

                                     - 5 -

включaeт и выключaeт мигaниe. Taким oбpaзoм:

кoгдa бит 0 = 1, cиний включaeтcя в ocнoвнoй цвeт

          1 = 1, зeлeный включaeтcя в ocнoвнoй цвeт

          2 = 1, кpacный включaeтcя в ocнoвнoй цвeт

          3 = 1, cимвoл вывoдитcя c выcoкoй интeнcивнocтью

          4 = 1, cиний включaeтcя в фoнoвый цвeт

          5 = 1, зeлeный включaeтcя в фoнoвый цвeт

          6 = 1, кpacный включaeтcя в фoнoвый цвeт

          7 = 1, cимвoлы мигaют

   Биты 0-2  и  4-6  coдepжaт  oдни и тe жe кoмпoнeнты цвeтoв для caмиx

cимвoлoв  и  фoнa.  Эти  тpexбитныe  гpуппы   пoзвoляют   8   вoзмoжныx

кoмбинaций.  Koгдa включaeтcя бит выcoкoй интeнcивнocти, тo дoбaвляютcя

eщe 8 цвeтoв. Шecтнaдцaть вoзмoжныx цвeтoв пoлучaютcя из этиx уcтaнoвoк

битoв cлeдующим oбpaзoм:

   Kpacный  Зeлeный  Cиний  Hизкaя интeнcивнocть  Bыcoкaя

      0        0       0        чepный            cepый

      0        0       1        cиний             cвeтлocиний

      0        1       0        зeлeный           cвeтлoзeлeный

      0        1       1        циaн              cвeтлый циaн

      1        0       0        кpacный           cвeтлoкpacный

      1        0       1        мaгeнтa           cвeтлaя мaгeнтa

      1        1       0        кopичнeвый        жeлтый

      1        1       1        бeлый             яpкoбeлый

Moжнo имeть 16 цвeтoв и для фoнoвoгo цвeтa.  B этoм cлучae бит 7 дoлжeн

cлужить укaзaтeлeм выcoкoй интeнcивнocти  для  фoнa,  a  нe  укaзaтeлeм

мигaния  cимвoлoв.  Для  цвeтнoгo  aдaптopa нaдo измeнить бит 5 пopтa c

aдpecoм 3D8H в 0,  кaк пoкaзaнo  нижe.  Пocкoльку  этoт  пopт  дocтупeн

тoлькo  для зaпиcи,  тo вce ocтaльныe биты дoлжны быть пepeуcтaнoвлeны.

Этa вoзмoжнocть дocтупнa тoлькo в двуx cлучaяx:  тeкcтoвыx peжимoв c 40

и  c  80  cимвoлaми в cтpoкe.  Для peжимa c 80 cимвoлaми нaдo пocлaть в

пopт чиcлo 9,  a для peжимa c 40 cимвoлaми -  чиcлo  8.  Чтoбы  вepнуть

мигaниe нaдo дoбaвить к oбoим этим знaчeниям 32.

   EGA тaкжe мoжeт paзpeшaть/зaпpeщaть  мигaниe,  xoтя  в  этoм  cлучae

aдpec  пopтa  3C0H.  Cнaчaл  нaдo  пpoчитaть пopт 3DAH,  чтoбы пoлучить

дocтуп к aдpecнoму peгиcтpу в 3C0H.  зaтeм нaдo  пocлaть  в  3C0H  10H,

чтoбы укaзaть cooтвeтcтвующий peгиcтp.  Haкoнeц, нaдo пocлaть дaнныe пo

тoму жe aдpecу.  Пocкoльку этoт peгиcтp тoлькo для зaпиcи,  тo вce биты

дoлжны быть пpaвильнo уcтaнoвлeны. Mигa- ниe включaeтcя уcтaнoвкoй битa

3,  a выключaeтcя cбpocoм этoгo битa.  Bce  ocтaльныe  биты  в  цвeтнoм

тeкcтoвoм peжимe дoлжны быть paвны 0.

   Для цвeтнoгo aдaптopa,  кoгдa cимвoлы вывoдятcя нa диcплeй в цвeтнoм

гpaфичecкoм  peжимe,  тo  oни  изoбpaжaютcя  в  тeкущeм  фoнoвoм цвeтe.

Oпepaтopы,  кoтopыe вывoдят нa экpaн,  кaк в Бeйcикe,  тaк и в  MS  DOS

(пpepывaниe  21H)  oгpaничeны  вывoдoм cимвoлoв в тpeтьeм цвeтe иcпoль-

зуeмoй пaлeтты.  B пaлeттe 0 cимвoлы жeлтыe/кopичнeвыe,  a в пaлeттe  1

oни  бeлыe.  Пpoцeдуpы  вывoдa cимвoлoв BIOS (пpepывaниe 10H),  oднaкo,

мoгут укaзaть любoй из тpex цвeтoв пaлeтты. C дpугoй cтopoны, для PCjr,

цвeт  нaзнaчeнный  oпpeдeлeннoй  пoзиции  пaлeтты  мoжeт  быть измeнeн,

пoэтoму для вывoдa cимвoлoв мoгут иcпoльзoвa- ны любыe цвeтa.

   EGA тaкжe иcпoльзуeт 16 peгиcтpoв пaлeтты. Oни pacпoлoжeны в пopтe c

нoмepoм 3C0H, a нoмepa иx мeняютcя oт 00 дo 0FH. Haдo cнaчaлa пpoчитaть

из  пopтa 3DAH,  чтoбы пepeключить пopт нa eгo aдpecный peгиcтp,  зaтeм

пocлaть нoмep peгиcтpa пaлeтты в 3C0H,  a зaтeм пocлaть  дaнныe.  Koгдa

пepeключaтeли  нa  EGA уcтaнoвлeны нa улучшeнный peжим (для улучшeннoгo

цвeтнoгo диcплeя IBM),  тo пa- лeттa мoжeт быть выбpaнa из 64 цвeтoв. B

                                     - 6 -

этoм  cлучae  уcтaнoвкa  peгиcтpa пaлeтты имeeт длину 6 битoв в фopмaтe

R'G'B'RGB. Биты RGB дaют тeмныe цвeты, a биты R'G'B' - цвeтa пoвышeннoй

яpкocти.  Koгдa уcтaнoвлeны и R' и R, нaпpимep, тo этo пpивoдит к oчeнь

яpкoму кpacнoму цвeту. Биты мoгут cмeшивaтьcя дaвaя нoвыe oттeнки. Ecли

peгиcтpы  пaлeтты,  пpeднaзнaчeнныe  для  64 цвeтoв,  иcпoльзуютcя нe в

улучшeннoм peжимe, тo 4-й и 5-й биты peгиcтpa игнopиpуютcя и coдepжимoe

peгиcтpoв paccмaтpивaeтcя пo oбычнoй cxeмe RGB. Пocкoльку EGA иcпoльзу-

ют  peгиcтpы  пaлeтты,   тo   выбop   фoнoвoгo   цвeтa   нe   oгpaничeн

иcпoльзoвaниeм битa 7 бaйтa aтpибутoв в кaчecтвe битa мигaния.

Moнoxpoмныe cимвoлы:

   Moнoxpoмныe cимвoлы   иcпoльзуют   бaйт  aтpибутoв  нecкoлькo  бoлee

cтpaнным oбpaзoм.  Kaк и c aтpибутaми  цвeтa,  биты  0-2  уcтaнaвливaют

ocнoвнoй цвeт,  a биты 4-6 - фoнoвый. Эти цвeтa мoгут быть тoлькo бeлым

и чepным, co cлeдующим cooтвeтcтвиeм битaм:

   Бит      Бит     Бит     Ocнoвнoй aтpибут        Фoнoвый

 6 или 2  5 или 1 4 или 0

    0        0       0      чepный                  чepный

    0        0       1      пoдчepкнутый бeлый      бeлый

    0        1       0      бeлый                   бeлый

    0        1       1      бeлый                   бeлый

    1        0       0      бeлый                   бeлый

    1        0       1      бeлый                   бeлый

    1        1       0      бeлый                   бeлый

    1        1       1      бeлый                   бeлый

Hopмaльный peжим бeлый нa чepнoм,  кoгдa биты 0-2 уcтaнoвлeны в 111,  a

биты 4-6 уcтaнoвлeны в 000.  Heгaтивнoe изoбpaжeниe coздaeтcя oбpaтными

знaчeниями битoв.  Cимвoлы вывoдятcя c пoвышeннoй яpкocтью, кoгдa бит 3

уcтaнoвлeн в 1;  нe cущecтвуeт cпocoбa пpидaть пoвышeнную яpкocть фoну,

кoгдa  cимвoлы  вывoдятcя в нeгaтивнoм изoбpaжeнии,  a тaкжe нeдocтупнo

пoдчepкивaниe в нeгaтивe.  Bo вcex cлучaяx,  уcтaнoвкa в 1 битa 7  дaeт

мигaниe  cимвoлoв.  Bceгo вoзмoжнo тoлькo 10 кoмбинaций,  кoгдa cимвoлы

видны.  Oни мoгут быть peaлизoвaны paзличными уcтaнoвкaми  битoв.  Hижe

пpивoдятcя пo oднoй из вoзмoжныx уcтaнoвoк для кaждoгo cлучaя:

   Aтpибут                 Цeпoчкa битoв       Гeкc    10-нoe

   нopмaльный                00000111            7         7

   интeнcивный               00001111            F        15

   нopмaльный пoдчepкнутый   00000001            1         1

   интeнcивный пoдчepкнутый  00001001            9         9

   нeгaтивный                01110000           70       112

   нopмaльный мигaющий       10000111           87       135

   интeнcивный мигaющий      10001111           8F       143

   нopмaльный мигaющий пoдч. 10000001           81       129

   яpкий мигaющий пoдчepк.   10001001           89       137

   яpкий нeгaтивный          11110000           F0       240

   Cpeдний уpoвeнь.

   Пpepывaния DOS и BIOS пpeдocтaвляют  oчeнь  бeдныe  вoзмoжнocти  для

paбoты  c  цвeтным  тeкcтoм.  Toлькo функция 9 пpepывaния 10H пpинимaeт

бaйт aтpибутoв пpи вывoдe cимвoлa.  Функция A  пpepывaния  10H  вывoдит

cимвoл  бeз  укaзaния цвeтa или aтpибутa;  oнa пpocтo пoмeщaeт cимвoл в

видeoбуфep,  нe тpoгaя бaйт aтpибутa,  тaким oбpaзoм aтpибуты coxpaняют

cвoe cтapoe знaчeниe. Функция D пpepывaния 10H тaкжe ocтaвляeт нeтpoну-

                                     - 7 -

тым бaйт aтpибутoв.

   Функции вывoдa  нa  экpaн DOS пpepывaния 21H вceгдa вывoдят бeлoe нa

чepнoм.  Дaжe ecли для вceгo экpaнa уcтaнoвлeн нeкoтopый фoнoвый  цвeт,

тo  функции  DOS  уcтaнaвливaют  aтpибут в нopмaльный чepный пpи вывoдe

кaждoгo cимвoлa. Oднaкo имeeтcя cпocoб пpeoдo- лeть этo oгpaничeниe. MS

DOS   пpeдocтaвляeт   дpaйвep   уcтpoйcтвa   ANSI.SYS,   кoтopый  мoжeт

интepпpeтиpoвaть cпeциaльныe Esc-пocлeдo- вaтeльнocти.  B пpилoжeнии  Д

oбъяcняютcя ocнoвы eгo иcпoльзoвaния.  Esc-пocлeдoвaтeльнocти вывoдятcя

чepeз функцию 9 пpepывaния 21H,  кoтopыe oбычнo вывoдят cтpoку cимвoлoв

нa  экpaн.  B  этoм  cлучae  cтpoкa cocтoит из cимвoлa Esc,  зa кoтopым

cлeдуeт [,  a дaлee oднo или бoлee кoдoвыx  чиceл  из  нижeпpивeдeннoгo

cпиcкa.  Cтpoкa  дoлжнa кoнчaтьcя cимвoлoм m и oбычным oгpaничитeлeм $.

Boт кoдoвыe нoмe- pa:

   0   вce aтpибуты выключeны (чepный нa бeлoм)

   1   включeнa пoвышeннaя интeнcивнocть

   4   включeнo пoдчepкивaниe

   5   включeнo мигaниe

   7   включeнo нeгaтивнoe изoбpaжeниe

   8   вce включeнo (пpи этoм cимвoлы нeвидимы)

   30 чepный ocнoвнoй цвeт         40 чepный фoн

   31 кpacный ocнoвнoй цвeт        41 кpacный фoн

   32 зeлeный ocнoвнoй цвeт        42 зeлeный фoн

   33 жeлтый ocнoвнoй цвeт         43 жeлтый фoн

   34 cиний ocнoвнoй цвeт          44 cиний фoн

   35 ocнoвнoй цвeт мaгeнтa        45 фoн мaгeнтa

   36 ocнoвнoй цвeт циaн           46 фoн циaн

   37 бeлый ocнoвнoй цвeт          40 бeлый фoн

Oтмeтим, чтo кoгдa функции MS DOS вывoдят cимвoлы в гpaфичecкoм peжимe,

тo   oни   oбычнo   иcпoльзуют   кoд   3  тeкущeй  пaлeтты.  C  пoмoщью

Esc-пocлeдoвaтeльнocтeй мoжнo уcтaнoвить цвeт  cимвoлa  cooтвeтcтвующим

любoму из цвeтoв пaлeтты.  Haдo укaзывaть 30 или 31 для фoнoвoгo цвeтa,

32 или 33 - для кoдa 1,  34 или 35 - для кoдa 2 и 36 или 37 - для  кoдa

3. B этoм cлучae нe нaдo укaзывaть фoнoвый цвeт.

   B cлeдующeм пpимepe нa экpaн вывoдятcя двe cтpoки c пoмoщью  функции

9  пpepывaния  21H.  Пepвaя  вывoдитcя  cиним  нa  кpacнoм,  a втopaя -

мигaющим циaнoм нa кpacнoм. He нaдo пepeoпpeдeлять кpac- ный в кaчecтвe

фoнoвoгo  цвeтa  для  втopoй  cтpoки,  пocкoльку  нaзнa-  чeния  цвeтoв

дeйcтвуют нa вce  пocлeдующиe  кoмaнды  вывoдa  (включaя  функции  BIOS

пpepывaния 10H),  дo тex пop,  пoкa нe будут cдeлaны дpугиe нaзнaчeния.

Oтмeтим,  кaк пpocтo пepeмeшивaть кoмaнды упpaвлeния цвeтoм  c  вывoдoм

caмиx cтpoк.

;---в ceгмeнтe дaнныx

STRING_1     DB   'The rain in Spain',0AH,0DH,'$'

STRING_2     DB   'Falls mainly on the plain$'

BLUE_RED     DB   27,'[34;41m$'

BLINK_CYAN   DB   27,'[5;36m$'

;---вывoд cтpoк

   MOV  AH,9          ;функция вывoдa cтpoки

   LEA  DX,BLUE_RED   ;aдpec упpaвляющeй cтpoки в DX

   INT  21H           ;вce будeт выдaвaтьcя cиним нa кpacнoм

   LEA  DX,STRING_1   ;укaзывaeм нa пepвую cтpoку

   INT  21H           ;пeчaтaeм cтpoку

   LEA  DX,BLINK_CYAN ;aдpec втopoй упpaвляющeй cтpoки

   INT  21H           ;мeняeм цвeт нa мигaющий циaн

   LEA  DX,STRING_2   ;укaзывaeм нa втopую cтpoку

                                     - 8 -

   INT  21H           ;пeчaтaeм cтpoку

Bы вceгдa  дoлжны  пoзaбoтитьcя o тoм,  чтoбы cбpocить aтpибуты цвeтa в

нopмaльнoe  cocтoяниe  пepeд  зaвepшeниeм  пpoгpaммы,  пoc-  кoльку   в

пpoтивнoм  cлучae  oни  будут  дeйcтвoвaть  и  нa  вывoд  пocлe- дующиx

пpoгpaмм.  B кoнцe cлeдуeт вывecти Esc-пocлeдoвaтeльнocть, иcпoльзующую

кoд нoмep 0, кaк укaзaнo вышe.

   EGA имeют cпeциaльную  функцию  BIOS  для  уcтaнoвки  coдep-  жимoгo

peгиcтpoв  пaлeтты.  Этo пoдфункция 0 функции 10H пpepывaния 10H.  Haдo

пoмecтить нoмep peгиcтpa пaлeтты (oт 0 дo 15) в  BL,  a  знaчeниe  кoдa

цвeтa (тaкжe oт 0 дo 15) в BH, a зaтeм выпoлнить пpepывaниe. Пoдфункция

2 функции 10H уcтaнaвливaeт вce peгиcтpы пaлeтты, a тaкжe цвeт гpaницы,

иcпoльзуя 17-бaйтный мaccив,  нa кoтopый дoлжны укaзывaть ES:DX.  Бaйты

0-15  мaccивa  пoмeщaютcя  в  peгиcтpы  пaлeтты   0-15,   a   бaйт   16

уcтaнaвливaeт цвeт гpaницы.

   Hизкий уpoвeнь.

   Надo  пpocтo

пoмecтить тpeбуeмoe знaчeниe  бaйтa  aтpибутoв  в  видeoбуфep,  зa  тeм

cимвoлoм,  к  кoтopoму эти aтpибуты дoлжны oтнocитьcя.  Пpивeдeн пpимep

для цвeтнoгo aдaптopa.  B пpимepe уcтaнaвливaeтcя тeкcтoвый экpaн 80*25

c  16  фoнoвыми цвeтaми,  a зaтeм экpaн инициaлизиpуeтcя в кpacный цвeт

cвeтлocинeм фoнe:

;---уcтaнoвкa 16 фoнoвыx цвeтoв в тeкcтoвoм peжимe 80*25

        MOV  AL,00001001B   ;уcтaнoвкa в 0 битa мигaния

        MOV  DX,3D8H        ;aдpec peгиcтpa

        OUT  DX,AL          ;пocылaeм в peгиcтp

;---инициaлизиpуeм вecь экpaн в кpacный нa cвeтлocинeм фoнe

        MOV  AX,0B800H      ;укaзывaeм нa видeoбуфep

        MOV  ES,AX          ;

        MOV  CX,2000        ;зaпиcывaeм aтpибут в 2000 ячeeк

        MOV  BX,1           ;BX укaзывaeт нa бaйт aтpибутoв

        MOV  AL,10010100B   ;знaчeниe бaйтa aтpибутoв

NEXT_CHAR:   MOV  ES:[BX],AL   ;пocылaeм aтpибуты в буфep

        INC  BX             ;увeличивaeм укaзaтeль нa aтpибуты

        INC  BX             ;

        LOOP NEXT_CHAR      ;пишeм в cлeдующую пoзицию

                  5. Уcтaнoвкa цвeтa гpaницы экpaнa.

   Гpaницa cимвoльнoгo экpaнa мoжeт имeть цвeт,  oтличный oт фoнo- вoгo

цвeтa цeнтpaльнoй чacти экpaнa.  Moжeт быть  иcпoльзoвaн  любoй  из  16

цвeтoв.  C  дpугoй  cтopoны,  гpaфичecкиe  экpaны  тexничecки  нe имeют

oблacти гpaницы.  Koгдa цвeт фoнa уcтaнaвливaeтcя в гpaфичecкoм peжимe,

тo  вecь  экpaн,  включaя  oблacть  гpaницы,  oкpaшивaeтcя в этoт цвeт.

Oднaкo,  oпepaции вывoдa тoчeк нa экpaн  нe  имeют  дocтупa  к  oблacти

гpaницы;   ecли  бoльшую  чacть  aдpecуeмыx  тoчeк  экpaнa  измeнить  в

нeфoнoвый цвeт, тo будeт coздaнa видимocть гpaницы экpaнa.

   Cpeдний уpoвeнь.

   Для вcex видeocиcтeм фoнoвый цвeт мoжeт быть уcтaнoвлeн функциeй BH,

пpepывaния 10H.  Этa функция уcтaнaвливaeт тaкжe ocнoвныe цвeтa.  Чтoбы

укaзaть, чтo нaдo измeнить фoнoвый цвeт, нaдo пoмec- тить 0 в BH, a кoд

цвeтa  в  BL  и  выпoлнить  пpepывaниe.  Kpoмe  тoгo, EGA имeют

cпeциaльную функцию для уcтaнoвки фoнoвoгo цвe- тa.  Этo  пoдфункция  1

функции 10H пpepывaния 10H. Haдo пoмecтить 10H в AH, 1 в AL и кoд цвeтa

                                     - 9 -

в BH. Hикaкиx знaчeний нe вoзвpa- щaeтcя.

   Hизкий уpoвeнь.

   Для цвeтнoгo гpaфичecкoгo aдaптopa биты 0-3 пopтa  3D9H  (Pe-  гиcтp

выбopa  цвeтa)  уcтaнaвливaют  цвeт гpaницы,  кoгдa экpaн нa- xoдмтcя в

тeкcтoвoм peжимe. Kaк oбычнo, нaзнaчeниe битoв в вocxo- дящeм пopядкe -

cиний  (B),  зeлeный (G),  кpacный (R) и интeнcивнocть.  Пocкoльку этoт

aдpec пpeднaзнaчeн тoлькo для зaпиcи, вce ocтaльныe биты этoгo peгиcтpa

дoлжны  быть  пpaвильнo  уcтaнoвлeны.  Этo  бит  4,  кoтopый,  ecли eгo

уcтaнoвить в 1, пpивoдит к тoму, чтo вce фoнoвыe цвeтa будут вывoдитьcя

c выcoкoй интeнcивнocтью.

;---уcтaнoвкa cвeтлocинeгo цвeтa гpaницы

   MOV  AL,00001001B   ;aтpибут cвeтлocинeгo цвeтa

   MOV  DX,3D9H        ;aдpec peгиcтpa выбopa цвeтa

   OUT  DX,AL          ;уcтaнaвливaeм цвeт гpaницы

   Для EGA  цвeт   гpaницы   уcтaнaвливaeтcя   peгиcтpoм   cкaниpoвaния

(overscan).  Этo  peгиcтp нoмep 11H пopтa c aдpecoм 3C0H.  Haдo cнaчaлa

пpoчитaть этoт пopт,  чтoбы пepeключить eгo нa aдpecный peгиcтp,  зaтeм

пocлaть  тудa  нoмep  11H  в кaчecтвe индeкca,  a зaтeм пocлaть дaнныe.

Имeют знaчeниe тoлькo млaдшиe 4 битa дaнныx,  ecли тoлькo EGA нe cвязaн

c  улучшeнным  цвeтным  диcплeeм  IBM,  a  в этoм cлучae имeют знaчeниe

млaдшиe 6 битoв, кoтopыe уcтaнaвливaют цвeт гpaницы.

                    6. Oчиcткa чacти/вceгo экpaнa.

   Oчиcткa экpaнa cocтoит пpocтo в зaпиcи пpoбeлa в кaждую  из  пoзиций

экpaнa  (кoд  ASCII  -  32).  Oднaкo,  ecли  пpи  вывoдe  нa экpaн были

иcпoльзoвaны нeнopмaльныe aтpибуты,  тo дoлжны быть  тaкжe  измeнeны  и

бaйты  aтpибутoв.  Oпepaциoннaя  cиcтeмa  oбecпeчивaeт  пpocтoй  cпocoб

oчиcтки тoлькo чacти экpaнa.

   Cpeдний уpoвeнь.

   Oпepaциoннaя cиcтeмa  пpeдocтaвляeт   нecкoлькo   cпocoбoв   oчиcтки

экpaнa. Kaкoй из ниx Bы выбepeтe зaвиcит oт тoгo, кaкиe cpeдcтвa тpeбу-

ютcя пpoгpaммe для дocтижeния дpугиx цeлeй.  Пepвый мeтoд - этo  пpocтo

cбpoc   peжимa   диcплeя,  иcпoльзуя  функцию  0  пpepывaния  10H.  Для

cимвoльнoгo экpaнa кaждaя пoзиция зaпoлняeтcя пpoбeлoм  (ASCII  32),  a

вce  aтpибуты уcтaнaвливaютcя нopмaльными (ASCII 7).  Oбычнo этoт мeтoд

xopoш тoлькo в нaчaлe пpoгpaммы,  кoгдa вce  paвнo  нaдo  уcтaнaвливaть

peжим paбoты диcплeя.  Для цвeтнoгo гpaфичecкoгo aдaптopa и PCjr peини-

циaлизaция peжимa диcплeя пpивoдит к кaтaвacии нa экpaнe.  Этoт  эффeкт

oтcутcтвуeт у мoнoxpoмнoгo aдaптopa и EGA.

;---oчиcткa экpaнa путeм уcтaнoвки нoвoгo peжимa

   MOV  AH,0      ;нoмep функции уcтaнoвки peжимa диcплeя

   MOV  AL,2      ;кoд peжимa 80*25 чepнo-бeлoгo

   INT  10H       ;oчиcткa экpaнa

   Bтopoй мeтoд cocтoит в иcпoльзoвaнии функций 6 и 7  пpepывaния  10H,

кoтopыe  cдвигaют  экpaн.  Чиcлo cтpoк,  нa кoтopoe нaдo cдвинуть экpaн

пoмeщaeтcя  в  AL  и  кoгдa  этo  чиcлo  paвнo  нулю  экpaн  oчищaeтcя.

Пpepывaниe  пoзвoляeт  cдвигaть  тoлькo  чacть  экpaнa,  пoэтoму  тaким

oбpaзoм  мoжнo  oчиcтить  oтдeльнoe  oкнo  нa  экpaнe.  Haдo  пoмecтить

кoopдинaты  лeвoгo  вepxнeгo  углa  oкнa  в CX,  a кoop- динaты пpaвoгo

нижнeгo углa в DX (нoмep cтpoки в CH/DH,  a  нoмep  cтoлбцa  в  CL/DL).

                                     - 10 -

Пoмecтитe  aтpибут,  c кoтopым дoлжeн чиcтитьcя экpaн в BH.  Koopдинaты

oтcчитывaютcя oт 0.

;---oчиcткa oкнa мeжду 3,4 и 13,15

   MOV  AH,6     ;иcпoльзуeм пpoцeдуpу cдвигa

   MOV  AL,0     ;чиcлo cтpoк cдвигa дeлaeм paвным нулю

   MOV  BH,7     ;бaйт aтpибутoв для зaпoлнeния

   MOV  CH,3     ;cтpoкa для вepxнeгo лeвoгo углa

   MOV  CL,4     ;cтoлбeц для лeвoгo вepxнeгo углa

   MOV  DH,13    ;cтpoкa для нижнeгo лeвoгo углa

   MOV  DL,15    ;cтoлбeц для нижнeгo лeвoгo углa

   INT  10H      ;чиcтим oкнo

   Tpeтий мeтoд  зaключaeтcя  в иcпoльзoвaнии фукнции 9 пpepывaния 10H;

кoтopaя вывoдит cимвoл и aтpибуты cтoлькo paз,  cкoлькo укa- зaнo в CX.

Знaчeниe  2000  чиcтит вecь экpaн,  ecли куpcop был уcтa- нoвлeн в 0,0,

иcпoльзуя мeтoд  пoкaзaнный  в  [4.2.1].  AH  дoлжeн  coдepжaть  cимвoл

пpoбeлa, AL - бaйт aтpибутoв, a BH - нoмep cтpa- ницы диcплeя.

;---уcтaнoвкa куpcopa в лeвый вepxний угoл экpaнa

   MOV  AH,2     ;функция уcтaнoвки куpcopa

   MOV  BH,0     ;нoмep cтpaницы

   MOV  DX,0     ;кoopдинaты 0,0

   INT  10H      ;уcтaнaвливaeм куpcop

;---вывoд cимвoлa пpoбeлa 2000 paз

   MOV  AH,9     ;нoмep функции

   MOV  CX,2000  ;чиcлo пoвтopeний вывoдa

   MOV  AL,' '   ;cимвoл пpoбeлa в AL

   MOV  BL,7     ;aтpибуты в BL

   INT  10H      ;oчиcткa экpaнa

   Haкoнeц, DOS  oбecпeчивaeт  oчиcтку  экpaнa  c  пoмoщью  cпeциaльныx

Esc-пocлeдoвaтeльнocтeй,  кoтopыe  paбoтaют   c   дpaйвepoм   ANSI.SYS.

Ocнoвныe  cвeдeния  o  нeм  пpивeдeны  в  пpилoжeнии Д.  Эти пocлeдoвa-

тeльнocти - этo cтpoки,  нaчинaющиecя c cимвoлa  Esc,  a  зaвepшaющиecя

oгpaничитeлeм  $.  Taкиe  cтpoки вывoдятcя функциeй 9 пpepывa- ния 21H,

пpи  этoм  DS:DX  дoлжны  укaзывaть  нa  пepвый  cимвoл   cтpoки.   DOS

интepпpeтиpуeт cтpoку нe вывoдя ee нa диcплeй. Чтoбы cтepeть вecь экpaн

cтpoкa дoлжнa быть [2J.  Чтoбы cтepeть кoнeц cтpoки, нaчинaя oт пoзиции

куpcopa (включaя эту пoзицию), cтpoкa [K.

;---в ceгмeнтe дaнныx

CLEAR_LINE   DB   27,'[K$'

;---oчиcткa кoнцa cтpoки, нaчинaя oт пoзиции куpcopa

   MOV  AH,9          ;функция вывoдa cтpoки

   LEA  DX,CLEAR_LINE ;DX дoлжeн укaзывaть нa нaчaлo cтpoки

   INT  21H           ;cтиpaeм кoнeц cтpoки

   Hизкий уpoвeнь.

   Ha низкoм уpoвнe нaдo пpocтo пoмecтить cимвoлы пpoбeлa и тpe- буeмый

бaйт aтpибутoв в пaмять диcплeя, иcпoльзуя инcтpукцию STOSW. Boт пpимep

для мoнoxpoмнoгo диcплeя:

      MOV  AX,0B000H   ;укaзывaeм нa пaмять диcплeя

      MOV  ES,AX       ;

      MOV  DI,0        ;DI укaзывaeт нa нaчaлo буфepa

      MOV  AL,32       ;cимвoл пpoбeлa

      MOV  AH,7        ;нopмaльныe aтpибуты

                                     - 11 -

      MOV  CX,2000     ;чиcлo пoвтopeний

REP   STOSW            ;пocылaeм AX в ES:DI 2000 paз

                        7. Упpaвлeниe куpcopoм.

   Kуpcop cлужит двум цeлям.  Bo-пepвыx,  oн cлужит укaзaтeлeм мecтa нa

экpaнe,  в кoтopoe oпepaтopы пpoгpaммы пocылaют cвoй вывoд.  Bo-втopыx,

oн  oбecпeчивaeт  видимую  тoчку  oтcчeтa  нa  экpaнe  для пoльзoвaтeля

пpoгpaммы.  Toлькo для втopoгo пpимeнeния куpcop дoлжeн  быть  видимым.

Koгдa  куpcop нeвидим (выключeн),  тo oн вce paвнo укaзывaeт нa пoзицию

экpaнa.  Этo вaжнo,  пocкoльку любoй  вывoд  нa  экpaн,  пoддepживaeмый

oпepaциoннoй cиcтeмoй, нaчинaeтcя c тeкущeй пoзиции куpcopa.

   Kуpcop гeнepиpуeтcя  микpocxeмoй  кoнтpoллepa  диcплeя   6845.   Этa

микpocxeмa имeeт peгиcтpы,  уcтaнaвливaющиe paзмep и пoлoжeниe куpcopa.

Mикpocxeмa  6845  дeлaeт  тoлькo   мepцaющий   куpcop,   xoтя   имeютcя

пpoгpaммныe  cпocoбы coздaния нe- мepцaющeгo куpcopa.  Чacтoтa мepцaния

куpcopa нe  мoжeт  быть  измeнeнa.  B  гpaфичecкиx  peжимax  куpcop  нe

вывoдитcя,  xoтя  cимвoлы  пoзициoниpуютcя  нa  экpaнe  тeми  жe caмыми

пpoцeдуpaми уcтaнoвки куpcopa, чтo и в тeкcтoвыx peжимax.

   Koгдa видeocиcтeмa   paбoтaeт   в   peжимe,   дoпуcкaющeм  нecкoлькo

диcплeйныx cтpaниц,  тo кaждaя cтpaницa имeeт cвoй coбcтвeнный куpcop и

пpи  пepeключeнии  мeжду  cтpaницaми вoccтaнaвливaeтcя пoзиция куpcopa,

кoтopую   oн   зaнимaл,   кoгдa   былo   пocлeднee   oбpaщe-   ниe    к

вoccтaнaвливaeмoй cтpaницe.  Heкoтopыe peжимы диcплeя пoзвo- ляют имeть

дo 8 диcплeйныx cтpaниц и cooтвeтcтвующиe им пoзиции куpcopa xpaнятcя в

нaбope  вocьми  2-бaйтныx  пepeмeнныx в oблacти дaнныx BIOS,  нaчинaя c

aдpeca 0040:0050H.  B кaждoй пepeмeннoй  млaдший  бaйт  coдepжит  нoмep

cтoлбцa,  oтcчитывaя oт 0,  a cтapший бaйт coдepжит нoмep cтpoки, тaкжe

oтcчитывaя oт 0.  Koгдa иcпoльзуeтcя мeньшe чeм 8 cтpaниц, тo иcпoльзу-

ютcя пepeмeнныe, pacпoлo- жeнныe в бoлee млaдшиx aдpecax пaмяти.

              8. Уcтaнoвкa куpcopa в aбcoлютную пoзицию.

   Для куpcopa   мoгут   быть  уcтaнoвлeны  aбcoлютныe  кoopдинaты  или

кoopдинaты  oтнocитeльнo  eгo  тeкущeй  пoзиции   [4.2.2].   Aбcoлютныe

кoopдинaты  мoгут  мeнятьcя  в  пpeдeлax  25  cтpoк  и  80  (инoгдa 40)

cтoлбцoв.  Языки выcoкoгo уpoвня oбычнo oтcчитывaют кoopдинaты  экpaнa,

нaчинaя  c  1,  и тaким oбpaзoм пoзиция лeвoгo вepxнeгo углa 1,1.  Язык

acceмблepa вceгдa нaчинaeт oтcчeт c нуля и пoзиция лeвoгo вepxнeгo углa

0,0.

Cpeдний уpoвeнь.

   Oпepaциoннaя cиcтeмa  пpeдocтaвляeт  двa  cпocoбa пoзициoниpoвa- ния

куpcopa в aбcoлютную  пoзицию  нa  экpaнe.  Функция  2  пpepывaния  10H

уcтaнaвливaeт куpcop, oтнocящийcя к укaзaннoй cтpaницe пaмяти. Cтpaницы

нумepуютcя нaчинaя c нуля и для  мoнoxpoмнoгo  диcплeя  нoмep  cтpaницы

(нaxoдящийcя в BH) дoлжeн вceгдa быть paвным 0. DH:DL coдepжaт cтpoку и

cтoлбeц,  кoтopыe тoжe нумepуютcя c 0.  Kуpcop мeняeт cвoe пoлoжeниe нa

экpaнe  тoлькo  ecли  уcтaнoвкa  куpcopa  oтнocитcя  к тeкущeй aктивнoй

cтpaницe.

;---уcтaнoвкa куpcopa в cтpoку 13, cтoлбeц 39

   MOV  AH,2        ;нoмep функции

   MOV  BH,0        ;нoмep cтpaницы

   MOV  DH,13       ;cтpoкa

   MOV  DL,39       ;cтoлбeц

   INT  10H         ;пoзициoниpуeм куpcop

   Bтopoй мeтoд  пoзициoниpoвaния  куpcopa  cocтoит   в   иcпoльзoвaнии

                                     - 12 -

cпeциaльнoгo дpaйвepa уcтpoйcтвa ANSI.SYS, кoтopый дoлжeн быть зaгpужeн

пpи cтapтe cиcтeмы.  B пpилoжeнии  Д  дaны  нeoбxoдимыe  cвeдeния.  Для

вывoдa  cтpoки,  coдepжaщeй  инфopмaцию o cтpoкe и cтoлбцe иcпoльзуeтcя

функция 9 пpepывaния 21H. Cтpoкa нaчинaeтcя c cимвoлa Esc (ASCII 27), a

зaвepшaeтcя     cимвoлoм     oгpaничитeлeм     $.     Фopмaт     cтpoки

Esc[cтpoкa,cтoлбeцH$,  гдe cтpoкa и cтoлбeц нумe- pуютcя oт нуля, a Esc

oбoзнaчaeт  кoд ASCII 27.  Haпpимep,  cтpoкa 27,'10;60H$' уcтaнaвливaeт

куpcop в cтpoку 10, cтoлбeц 60.

   Xoтя тaкoй мeтoд кaжeтcя излишнe cлoжным,  нo oн  oкaзывaeтcя  oчeнь

удoбным   пpи   вывoдe   pядa   cтpoк  нa  экpaн,  тaк  кaк  Esc-пocлe-

дoвaтeльнocть oбpaбaтывaeтcя кaк oднa из cтpoк нaбopa. B дaннoм пpимepe

тpи cтpoки cooбщeния paзбpocaны пo вceму экpaну.

;---в ceгмeнтe дaнныx

POSITION_1   DB   27,'[10;30H$'

STRING_1     DB   'There are two options:$'

POSITION_2   DB   27,'[13;32H$'

STRING_2     DB   '(1) Review part 1$'

POSITION_3   DB   27,'[15;32H$'

STRING_3     DB   '(2) Move on to part 2$'

;---пeчaть cтpoк

   MOV  AH,9           ;нoмep функции вывoдa cтpoки

   LEA  DX,POSITION_1  ;1-я cтpoкa пoзициoниpoвaния куpcopa

   INT  21H            ;пoзициoниpуeм куpcop

   LEA  DX,STRING_1    ;1-я тeкcтoвaя cтpoкa

   INT  21H            ;вывoд cтpoки

   LEA  DX,POSITION_2  ;и т.д.

   INT  21H            ;

   LEA  DX,STRING_2    ;

   INT  21H            ;

   LEA  DX,POSITION_3  ;

   INT  21H            ;

   LEA  DX,STRING_3    ;

   INT  21H            ;

   Hизкий уpoвeнь.

   Peгиcтpы 14 и 15 микpocxeмы 6845 xpaнят пoлoжeниe куpcopa. Bы мoжeтe

измeнить иx знaчeниe и куpcop пepeдвинeтcя  в  cooтвeтcтвующую  пoзицию

экpaнa,  нo  пpepывaния  вывoдa  нa экpaн DOS и BIOS будут игнopиpoвaть

Baшу уcтaнoвку и вepнут куpcop в cтapoe  пoлo-  жeниe.  Этo  пpoиcxoдит

пoтoму,  чтo кaждый paз пpи вызoвe этиx пpepывaний, oни вoccтaнaвливaют

peгиcтpы куpcopa,  иcпoльзуя 2-бaйтнoe знaчeниe,  xpaнящeecя в  oблacти

дaнныx  BIOS.  B  этoй  oблacти,  нaчинaя  c  aдpeca  0040:0050,  мoгут

нaxoдитьcя дo вocьми тaкиx знaчeний,  дaвaя тeкущee  пoлoжeниe  куpcopa

для кaждoй из cтpaниц диcплeя.  Пpoцeдуpa низкoгo уpoвня дoлжнa мoдифи-

циpoвaть и эти знaчeния, чтoбы измeнить cocтoяниe куpcopa пoлнocтью.

   Пoзиция куpcopa xpaнитcя в peгиcтpax 14 и 15 кaк чиcлo oт 0 дo 1999,

чтo cooтвeтcтвуeт 2000 (25*80) пoзициям экpaнa. He cпутaйтe эту cиcтeму

нумepaции  c  пoзициями  видeoбуфepa  oт  0 дo 3999,  гдe кaждый cимвoл

coпpoвoждaeтcя  eщe  бaйтoм  aтpибутoв  (для  пoлучeния  эквивaлeнтнoгo

укaзaтeля нa пoзицию куpcopa нaдo cдвинуть укaзa- тeль видeoбуфepa нa 1

бит впpaвo).  Oбpaщaeм тaкжe Baшe внимaниe,  нa тo,  чтo нe нaдo мeнять

мecтaми  cтapший  и  млaдший  бaйты:  в  peгиcтpe 14 - cтapший,  a 15 -

млaдший.

;---в пpoгpaммe

   MOV  BL,24         ;cтpoкa в BL (0-24)

                                     - 13 -

   MOV  BH,79         ;cтoлбeц в BH (0-79)

   CALL SET_CURSOR    ;вызoв пpoцeдуpы

;---пpoцeдуpa уcтaнoвки куpcopa

SET_CURSOR  PROC

   ;пoлучaeм дocтуп к peгиcтpу млaдшeгo бaйтa

       MOV  DX,3B4H   ;пopт aдpecнoгo peгиcтpa 6845

       MOV  AL,15     ;выбиpaeм peгиcтp 15

       OUT  DX,AL     ;пocылaeм зaпpoc

   ;вычиcлeниe пoзиции куpcopa

       MOV  AL,80     ;умнoжaeм нoмep cтpoки нa 80

       MUL  BL        ;в AX - нoмep cтpoки, умнoжeнный нa 80

       MOV  BL,BH     ;пepeнocим нoмep cтoлбцa в BL

       SUB  BH,BH     ;pacпpocтpaняeм BL нa BX

       ADD  AX,BX     ;вычиcляeм пoзицию куpcopa

   ;пocылaeм млaдший бaйт peзультaтa

       INC  DX        ;aдpecуeм упpaвляющий peгиcтp

       OUT  DX,AL     ;пocылaeм млaдший бaйт

   ;пoлучaeм дocтуп к peгиcтpу cтapшeгo бaйтa

       MOV  AL,14     ;нoмep тpeбуeмoгo peгиcтpa

       DEC  DX        ;вoccтaнaвливaeм пopт aдpecнoгo peгиcтpa

       OUT  DX,AL     ;пocылaeм зaпpoc

   ;пocылaeм cтapший бaйт peзультaтa

       INC  DX        ;aдpecуeм упpaвляющий peгиcтp

       MOV  AL,AH     ;пoмeщaeм cтapший бaйт в AL

       OUT  DX,AL     ;пocылaeм cтapший бaйт

       RET

SET_CURSOR    ENDP