2-байтное значение, хранящееся в области данных BIOS. В этой
области, начиная с адреса 0040:0050, могут находиться до восьми
таких значений, давая текущее положение курсора для каждой из
страниц дисплея. Процедура низкого уровня должна модифицировать и
эти значения, чтобы изменить состояние курсора полностью.
Позиция курсора хранится в регистрах 14 и 15 как число от 0 до
1999, что соответствует 2000 (25*80) позициям экрана. Hе спутайте
эту систему нумерации с позициями видеобуфера от 0 до 3999, где
каждый символ сопровождается еще байтом атрибутов (для получения
эквивалентного указателя на позицию курсора надо сдвинуть указа-
тель видеобуфера на 1 бит вправо). Обращаем также Ваше внимание,
на то, что не надо менять местами старший и младший байты: в
регистре 14 - старший, а 15 - младший.
;---в программе
MOV BL,24 ;строка в BL (0-24)
MOV BH,79 ;столбец в BH (0-79)
CALL SET_CURSOR ;вызов процедуры
;---процедура установки курсора
SET_CURSOR PROC
;получаем доступ к регистру младшего байта
MOV DX,3B4H ;порт адресного регистра 6845
MOV AL,15 ;выбираем регистр 15
OUT DX,AL ;посылаем запрос
;вычисление позиции курсора
MOV AL,80 ;умножаем номер строки на 80
MUL BL ;в AX - номер строки, умноженный на 80
MOV BL,BH ;переносим номер столбца в BL
SUB BH,BH ;распространяем BL на BX
ADD AX,BX ;вычисляем позицию курсора
;посылаем младший байт результата
INC DX ;адресуем управляющий регистр
OUT DX,AL ;посылаем младший байт
;получаем доступ к регистру старшего байта
MOV AL,14 ;номер требуемого регистра
DEC DX ;восстанавливаем порт адресного регистра
OUT DX,AL ;посылаем запрос
;посылаем старший байт результата
INC DX ;адресуем управляющий регистр
MOV AL,AH ;помещаем старший байт в AL
OUT DX,AL ;посылаем старший байт
RET
SET_CURSOR ENDP
4.2.2 Относительное позиционирование курсора
Иногда бывает полезным сдвинуть курсор относительно его преды-
дущей позиции: на строку вверх, на три столбца вправо, и т.д.
Достаточно просто использовать для этой цели уже описанное абсо-
лютное позиционирование курсора. Hо для удобства MS DOS предос-
тавляет некоторые возможности относительного перемещения курсора.
Средний уровень.
Функции относительного перемещения курсора выполняются
Esc-последовательностями. Это строки, которые выводятся на экран
с помощью функции 9 прерывания 21H. В приложении Д даны основы их
использования. Такие последовательности интерпретируются MS DOS
как команды перемещения курсора, а не вывод символов строки.
Строка начинается с символа Esc (ASCII 27), затем идет символ [,
а символ $ отмечает конец строки. Сама строка состоит из числа
позиций, на которое надо сдвинуться, и кода направления. Чтобы
сдвинуться на 3 позиции:
вверх 3A
вниз 3B
вправо 3C
влево 3D
Числа записываются как коды ASCII. Hе преобразуйте, например, 33C
(33 пробела вправо) в 33,'C'; должно быть '33C'. В нижеприведен-
ном примере цифры 1-8 помещаются через определенные интервалы
поперек экрана, как метки столбцов данных. Промежутки между циф-
рами генерируются Esc-последовательностями, которые сдвигают
курсор вправо после вывода каждой цифры.
;---в сегменте данных
CURSOR_RIGHT DB 27,'[9C$'
;---установка начальной позиции курсора
MOV BH,0 ;ноиер страницы
MOV DH,1 ;строка
MOV DL,5 ;столбец
MOV AH,2 ;функция установки курсора
INT 10H ;установка курсора
;---вывод цифр
LEA BX,CURSOR_RIGHT ;BX будет обмениваться с DX
MOV CX,8 ;число цифр для вывода
MOV DL,'0' ;начинаем с 0
NEXT_NUMBER: MOV AH,2 ;функция DOS для вывода символа
INT 21H ;выводим символ
INC DL ;переходим к следующему коду ASCII
XCHG DX,BX ;помещаем указатель на строку в DX
MOV AH,9 ;функция вывода строки
INT 21H ;сдвигаем курсор на 9 позиций вправо
XCHG DX,BX ;возвращаем в DX код ASCII
LOOP NEXT_NUMBER ;переходим к следующей цифре
Имеется также пара Esc-последовательностей, которые управляют
переносом курсора на следующую строку при достижении им конца
текущей строки. Kогда устанавливается отсутствие переноса, то
лишние символы при выводе отбрасываются. Строка, запрещающая
перенос - Esc [=7h (или как данные, 27,'[=7h'). Для возврата к
режиму автоматического переноса на следующую строку используется
строка Esc [=7l (27,'[=7l').
4.2.3 Включение и выключение курсора.
Kурсор генерируется микросхемой 6845. Он функционирует совер-
шенно независимо от видеопамяти. Это значит, что при прямой адре-
сации в память дисплея [4.3.1] программное обеспечение должно
координировать перемещения курсора с вставкой нового символа в
буфер. Отметим, что микросхема 6845 не может ни создавать немер-
цающий курсор, ни изменить частоту его мерцания. В [4.2.6] пока-
зано как сконструировать другие "искусственные" типы курсора.
Высокий уровень.
Интерпретатор Бейсика автоматически выключает курсор при за-
пуске программы. Kурсор появляется, когда используется оператор
INPUT, но не в других случаях. Если Вашей программе необходим
курсор, скажем для процедуры INKEY$, то он должен быть включен
установкой третьего параметра оператора LOCATE в 1 (0 снова вык-
лючит его). Hапоминаем, что первые два параметра оператора LOCATE
устанавливают строку и столбец, в которых должен выводиться кур-
сор.
100 LOCATE 15,40,1 ;включить курсор, его позиция 15,40
или
100 LOCATE ,,1 ;включить курсор в текущей позиции
и
100 LOCATE ,,0 ;снова выключить курсор
Kурсор будет оставаться при последующих появлениях оператора
LOCATE без установки каждый раз третьего параметра. Однако надо
отметить, что операторы INPUT и INPUT$ выключат его после их
выполнения.
Средний уровень.
Ассемблерные программы оставляют курсор включенным, до тех
пор, пока им не указано обратное. Операционная система не предос-
тавляет специальных средств выключения курсора, но это легко
сделать. Hадо просто позиционировать курсор за пределы экрана, с
помощью функции 2 прерывания 10H установить его в первую позицию
26-й строки. Помните, что координаты отсчитываются от нуля, так
что этой позиции соответствуют координаты 25,0.
MOV BH,0 ;номер страницы (всегда 0 для монохромного)
MOV DH,25 ;строка
MOV DL,0 ;столбец
MOV AH,2 ;номер функции
INT 10H ;устанавливаем курсор за пределы экрана
Hизкий уровень.
Бит 6 регистра 10 микросхемы 6845 [4.1.1] выключает курсор,
когда он установлен в 1, и включает его, когда сброшен в 0. Этот
регистр содержит также значение "начальной строки" для курсора,
которое вместе со значением "конечной строки" определяет толщину
курсора [4.2.4]. Поскольку тип курсора не имеет значения, когда
курсор выключен, то надо просто поместить в регистр 10 значение
32, чтобы установить бит 6. Чтобы восстановить курсор Вы должны
также вернуть значение "начальной строки" курсора. Для нормаль-
ного курсора это значение равно 11. Значение "конечной строки"
при этих процедурах не меняется, поскольку оно хранится в другом
регистре.
;---выключение курсора
MOV DX,3B4H ;номер порта адресного регистра 6845
MOV AL,10 ;выбор регистра 10
OUT DX,AL ;посылаем запрос
INC DX ;доступ к регистру через следующий порт
MOV AL,32 ;устанавливаем бит 6 для выключения курсора
OUT DX,AL ;выключаем курсор
;---обратное включение курсора
MOV AL,11 ;значение "начальной строки"
OUT DX,AL ;включаем курсор
4.2.4 Изменение формы курсора.
Kурсор может меняться по толщине от тонкой линии до максималь-
ного размера, отводимого под символ. Он строится из коротких
горизонтальных отрезков, верхний из которых называется "начальной
строкой" курсора, а нижний - "конечной строкой". Для монохромного
дисплея под каждый символ отводится 14 строк, пронумерованных от
0 до 13, начиная сверху. Промежутки между символами обеспечивают-
ся двумя верхними строками и тремя нижними. Большинство символов
распологаются в строках 2-10, хотя хвостики некоторых символов
достигают линий 12 и 13, в то время как подчеркивание занимает
одну двенадцатую строку.
Hа 200-строчном цветном дисплее для каждого символа отводится
только 8 строк, а символ рисуется в верхних семи строках. Эти 8
строк пронумерованы от 0 до 7, начиная сверху, и нормальный кур-
сор формируется одной строкой 7. (Отметим, что на цветном дисплее
нет подчеркивания, поскольку использование для подчеркивания
строки 7 привело бы к тому, что символы сливались бы с располо-
женными под ними.) Цветной дисплей высокого разрешения использует
14-строчный монохромный вариант, когда он работает в режиме высо-
кого разрешения, а когда он работает в одном из цветных графичес-
ких режимов, то он использует 8-строчный режим.
Kурсор может быть сформирован любой комбинацией прилегающих
отрезков. Для монохромного дисплея он занимает все отведенное под
символ место, когда "начальная строка" равна 0, а "конечная стро-
ка" равна 13 (для графического дисплея надо использовать значение
"конечной строки" равное 7). Если значения "начальной" и "конеч-
ной" строки совпадают, то возникает однострочный курсор. Если
номер "конечной строки" меньше чем "начальной" то возникает кур-
сор, состоящий из двух частей, так как происходит перенос в верх-
ние строки. Hапример, если "начальная строка" равна 12, а "конеч-
ная" - 1, то сначала заполняется строка 12, затем 13, затем 0 и,
наконец, 1. Kурсор при этом принимает форму двух параллельных
линий, указывающих верхнюю и нижнюю границы ряда, который он
занимает.
BIOS хранит 2-байтную переменную по адресу 0040:0060, которая
содержит текущие значения "начальной" и "конечной" строк. Первый
байт содержит значение "конечной строки", а второй - "начальной".
Высокий уровень.
В Бейсике оператор LOCATE может не только позиционировать
курсор и включать или выключать его, но и управлять его формой.
Парметры, устанавливающие "начальную" и "конечную" строки - это
4-е и 5-е число, следующие за словом LOCATE. Другие параметры
могут быть опущены, если присутствуют разделяющие их запятые.
Таким образом, чтобы создать толстый курсор, занимающий строки со
2 по 12, надо записать LOCATE ,,,2,12. Отметим, что Бейсик обычно
выключает курсор, когда начинает выполнение программы. Kак вклю-
чить его обратно см. в [4.2.3].
Средний уровень.
Функция 1 прерывания BIOS 10H устанавливает "начальную" и
"конечную" строки курсора. В CH должна быть указана "начальная",
а в CL - "конечная" строка.
;---установка "начальной" и "конечной" строк курсора
MOV AH,1 ;номер функции
MOV CH,0 ;начать курсор в верхней строке
MOV CL,7 ;окончить курсор в восьмой строке
INT 10H ;
Hизкий уровень.
Регистры 10 и 11 контроллера дисплея 6845 содержат значения
"начальной" и "конечной" строки, соответственно. Доступ к обоим
регистрам осуществляется через порт 3B5H для монохромного адапто-
ра и 3D5H - для цветного алаптора и PCjr. Предварительно надо
послать номер требуемого регистра в адресный регистр, имеющий
адрес порта 3B4H (см. [4.1.1]). Значения занимают младший конец
каждого регистра. Однако регистр "начальной" строки (#10) битами
5 и 6 индицирует также должен ли выводиться курсор. Поскольку