;---теперь выводим сообщение
LEA BX,MESSAGE ;сообщение в сегменте данных
MOV DI,2000 ;начинаем вывод с центра экрана
MOV AH,01000001B ;атрибут синий на красном
NEXT_CHAR: MOV AL,[BX] ;берем символ
CMP AL,'$' ;проверяем на конец строки
JE ALL_DONE ;если конец, то на выход
MOV ES:[DI],AX ;иначе выводим символ
INC BX ;увеличиваем указатель строки
INC DI ;увеличиваем указатель буфера
INC DI ;
JMP SHORT NEXT_CHAR ;обрабатываем следующий символ
ALL_DONE:
Вы можете поэкспериментировать сколько символов за один цикл
может выводить Ваша процедура без появления интерференции. Имейте
ввиду, что при первом выполнении цикла тестируемый бит может быть
равным единице, но может не оставаться времени, чтобы завершить
операцию записи.
PCjr специально сконструирован таким образом, что вывод в
адреса, используемые буфером цветного графического дисплея пере-
направляется в ту область памяти, где на самом деле находится
буфер. Это свойство позволяет делать программное обеспечение,
подходящее для обоих систем.
4.3.2 Вывод строки символов на экран.
Процедуры, которые выводят целые строки символов очень полез-
ны, но они могут накладывать ограничения на содержимое выводимой
строки. Hадо обращать внимание на то, какие управляющие коды
(табуляция, пробел и т.п.) интерпретируются, а какие нет. До
появления AT BIOS не имел функции вывода строки, хотя MS DOS
всегда имела такую фукнцию. Функция BIOS предоставляет больший
контроль над атрибутами символов. Естественно, что ее использова-
ние создает проблему совместимости с предыдущими машинами. Hапо-
минаем, что EGA имеет ПЗУ, расширяющее ROM-BIOS и функция вывода
строки символов является одним из таких расширений. В этом случае
любой IBM PC и XT имеет возможность использовать эту процедуру.
Высокий уровень.
Бейсик выводит строку точно так же, как и отдельные символы.
Hадо просто написать PRINT S$, где S$ может быть любой строкой
длиной до 255 символов, которую сконструировала программа. Ин-
терпретируются 10 управляющих кодов, а именно:
ASCII 7 звонок
ASCII 9 табуляция
ASCII 10 перевод строки
ASCII 11 курсор в первую позицию экрана (Home)
ASCII 12 перевод формата (стирает экран + Home)
ASCII 13 возврат каретки
ASCII 28 курсор вправо
ASCII 29 курсор влево
ASCII 30 курсор вверх
ASCII 31 курсор вниз
Все остальные коды выводятся на экран как символы.
Средний уровень.
Функция 9 прерывания 21H выводит строку. DS:DX должны указы-
вать на первый символ строки. Строка должна завершаться символом
$, что означает, что сам символ $ не может входить в строку.
Строка может быть любой длины. Функция не переводит автоматически
курсор на начало следующей строки после завершения вывода; чтобы
это выполнялось надо добавить в конец строки символы 0AH (перевод
строки) и 0DH (возврат каретки).
;---в сегменте данных
FIRST_STRING DB 'This is the first string',0AH,0DH,'$'
SECOND_STRING DB 'And this is the second string$'
;---вывод строки
MOV AH,9 ;номер функции вывода строки
LEA DX,FIRST_STRING ;загружаем адрес первой строки
INT 21H ;печатаем строку с позиции курсора
LEA DX,SECOND_STRING ;загружаем адрес второй строки
INT 21H ;печатаем строку с начала новой строки
Интрепретируются следующие управляющие коды:
ASCII 7 звонок
ASCII 8 возврат на шаг (BackSpace)
ASCII 9 табуляция
ASCII 10 перевод строки
ASCII 13 возврат каретки
Функция DOS 40H прерывания 21H также полезна при выводе строк
на экран. Она требует, чтобы Вы знали длину строки, поскольку ей
не требуется символа-ограничителя; эта функция особенно удобна
для дампа текстовых файлов на экран. Исходно эта функция была
предназначена для вывода в файл. Она требует дескриптора, который
является идентификационным номером для данного файла или уст-
ройства. Дисплей имеет заранее предназначенный дескриптор #1.
Hадо поместить дескриптор в BX, а число байтов строки в CX. DS:DX
должны указывать на строку. Функция выводит текст с нормальными
(белый на черном) атрибутами. Отметим, что не надо предварительно
"открывать" дисплей, как это Вы делает с другими файлами при
использовании этой функции. Вот пример:
;---вывод 1000 байтов текста
MOV AH,40H ;номер функции
MOV BX,1 ;дескриптор дисплея
LEA DX,STRING ;загржаем адрес строки
MOV CX,1000 ;число выводимых байтов
INT 21H ;
MS DOS предоставляет набор Esc-последовательностей, которые
являются специальными управляющими строками для аппаратуры. Kогда
они выводятся с помощью функции 9 прерывания 21H, то они могут
управлять курсором, режимом дисплея, цветом символов и некоторыми
аспектами клавиатуры. В приложении Д обсуждается как их использо-
вать. Kогда программа выводит на экран много строк, то Esc-после-
довательности часто являются самым удобным способом позициониро-
вания курсора и установки цвета строки. Это происходит потому,
что они сами рассматриваются просто как очередные строки в серии
выводимых строк.
У AT и машин, снабженных EGA, функция 13H прерывания 10H выво-
дит строку. ES:BP должны указывать на строку, а длина строки
должна быть в CX. DX указывает позицию курсора, с которой должна
начинаться строка (вычисляемую как смещение от начала страницы,
на которую идет вывод без учета байтов атрибутов). В BX должен
быть указан номер страницы. Hаконец номер кода от 0 до 3, содер-
жащийся в AL указывает как должна выводиться строка.
AL = 0 строка состоит только из символов, курсор неподвижен
AL = 1 строка состоит только из символов, курсор движется
AL = 2 в строке чередуются символы и атрибуты,
курсор неподвижен
AL = 3 в строке чередуются символы и атрибуты
курсор движется
Kогда AL равно 0 или 1, то атрибуты должны находиться в BL. Все
символы будут выводиться с этими атрибутами. Эта функция интерп-
ретирует возврат на шаг, перевод строки, возврат каретки и звонок
как управляющие команды, а не как печатаемые символы.
Hизкий уровень.
Ограничение на использование символа $ делает функцию 9 беспо-
лезной для многих приложений. Однако на многих машинах это е-
динственное прерывание, доступное для вывода строки неизвестной
длины. Попробуйте написать свое собственное прерывание (в [1.2.3]
показано как), использующее технику отображения в память [4.3.1].
Используйте в качестве ограничителя какой-нибудь специальный
символ, например, ASCII 0, вместо $. Сделайте чтобы эта процедура
обрабатывала только те управляющие коды, которые нужны Вам. Такой
метод будет работать намного быстрее, чем при использовании функ-
ции MS DOS.
4.3.3 Чтение символа и его атрибутов в данной позиции.
Обычно программа получает данные из своих переменных и поме-
щает их в видеобуфер для вывода на экран. В некотором смысле
программа "знает" что на экране. Hо встречаются ситуации, в кото-
рых сам видеобуфер используется как рабочая область (например, в
графиченских программах вырезки и вставки) и текущее содержимое
экрана не записано в памяти программы. В этих случаях бывает
необходимо прочитать с экрана, виесто того чтобы вывести на него.
Функция BIOS позволяет прочитать символ и его атрибуты в опреде-
ленной позиции экрана; другой метод состоит в обращении метода
прямого отображения в память дисплея [4.3.1]. Чтобы прочитать
символ и атрибуты в строке 0 и столбце 39 (1,40 в Бейсике) в
режиме 80 символов в строке надо сложить (0*160) плюс (39*2) и
взять результат в качестве смешения в видеобуфере. В случае когда
нужны смещения для различных страниц см. [4.5.3]. Имейте ввиду,
что обращение метода прямого отображения в память не будет рабо-
тать в случае вывода символов в графическом режиме.
Высокий уровень.
Бейсик использует функцию SCREEN для получения символа или
атрибутов (эта функция не имеет ничего общего с оператором SCREEN
устанавливающим режим дисплея). SCREEN 5,10 получает код ASCII
символа, расположенного в строке 5, столбце 10 (строки и столбцы
нумеруются от 1). Чтобы получить атрибуты символа надо добавить
третий параметр 1, например, SCREEN 5,10,1. При использовании в
графическом режиме данная функция возвращает 0, если требуемая
позиция экрана не содержит (немодифицированного) символа.
Атрибуты также возвращаются в виде кода от 0 до 255. Поскольку
Бейсик не позволяет использования двоичных чисел, то требуются
некоторые манипуляции, чтобы определить атрибуты. Основной цвет
равен ATTRIBUTE MOD 16. После того как Вы выделили основной цвет,
цвет фона определяется по формуле (((ATTIBUTE - FOREGROUND)/16)
MOD 128). Если байт атрибутов больше 127, то включено мигание
(или, при соответствующей установке, включены интенсивные цвета
фона [4.1.3]). В приложении Б обсуждаются битовые операции в
Бейсике.
Средний уровень.
Функция 8 прерывания 10H возвращает символ и его атрибуты для
текущей позиции курсора. В BH должен содержаться номер текущей
страницы дисплея (отсчитываемый от 0 и всегда равный 0 для монох-
ромного дисплея). Kод символа возвращается в AL, а байт атрибутов
в AH. Эта функция настолько мощная, что способна даже читать
символы в графическом режиме, сообщая цвет палетты в AH. Она
работает даже для символов определяемых пользователем [4.3.4]. В
примере определяется символ и атрибуты в позиции 0,39 для страни-
цы 2 графического адаптора:
;---установка позиции курсора
MOV AH,2 ;функция установки курсора
MOV DH,0 ;номер строки
MOV DL,39 ;номер столбца
MOV BH,0 ;номер страницы
INT 10H ;позиционируем курсор
;---чтение символа и атрибутов
MOV AH,8 ;функция чтения символа/атрибутов
MOV BH,2 ;номер страницы
INT 10H ;в AH:AL теперь атрибуты и символ
Hизкий уровень.
Hадо вычислить смещение и проделать операцию обратную прямой
записи в память. При необходимости надо добавить смещение для
данной страницы. В примере получаем символ и атрибуты в позиции
7,39 страницы 2 графического адаптора:
;---чтение символа и атрибутов позиции 7,39 страницы 2
MOV AX,0B800H ;адрес видеобуфера
MOV ES,AX ;ES указывает на первый байт буфера
MOV DI,1000H ;смещение до начала страницы
MOV AL,80 ;умножаем номер строки на 160
MOV BL,7 ;номер строки
MUL BL ;теперь в AX (строка-1)*160
MOV AX,39 ;номер столбца
ADD BX,AX ;номер позиции в видеобуфере
SHL BX,1 ;умножаем его на два
MOV AX,ES:[BX][DI] ;теперь AH:AL содержат атрибуты/символ
4.3.4 Создание специальных символов.
Только монохромный адаптор не может выводить символы вида,
заданного самим программистом. Цветной адаптор позволяет 128
символов, определяемых пользователем, PCjr - 256, а EGA - 1024 из
которых одновременно доступно 512. Для цветного адаптора ROM-BIOS
содержит данные для разрисовки только первых 128 символов набора
ASCII (с номерами от 0 до 127). Следующие 128 символов недоступны
для Вас, пока Вы не создатите их, используя описанную здесь тех-
нику. Отметим, что MS DOS 3.00 предоставляет команду GRAFTABL,
которая предоставляет требуемые данные для второй порции из 128
символов. PCjr имеет данные для второй порции из 128 символов уже