Справочник программиста на персональном компьютере фирмы IBM. Вывод на терминал
Страница 12. Установка курсора в абсолютную позицию


     4.2.1 Установка курсора в абсолютную позицию.


   Для курсора могут быть  установлены  абсолютные координаты или
координаты  относительно его текущей позиции [4.2.2].  Абсолютные
координаты могут меняться в  пределах  25  строк и 80 (иногда 40)
столбцов.   Языки высокого уровня обычно  отсчитывают  координаты
экрана, начиная с 1, и таким образом позиция левого верхнего угла
1,1.   Язык  ассемблера всегда начинает отсчет с  нуля и  позиция
левого верхнего угла 0,0.

   Высокий уровень.


   Бейсик нумерует строки от 1 до 25, а столбцы от 1 до 80.  Фор-
мат  оператора LOCATE, который устанавливает позицию курсора  та-
кой: LOCATE строка,столбец.   Если установки курсора не делается,
то  он  переходит  в первую позицию строки после  ввода  возврата
каретки, а сдвиг экрана начинается после того, как будет заполне-
на  24-я строка.  Чтобы вывести в 25-ю строку Вы должны использо-
вать LOCATE  (предварительно  очистив  эту  строку  с помощью KEY
OFF).  Для отмены автоматического сдвига экрана в строках 24 и 25
надо  завершать  оператор PRINT точкой с запятой (чтобы  отменить
сдвиг в позициях 24,80 и 25,80 надо использовать прямое отображе-
ние в память [4.3.1]).  Ниже приведен пример рисования вертикаль-
ной черты с помощью одного  из  символов  псевдографики  в центре
экрана.

100 FOR N = 1 TO 25     'повтор для каждой строки
110 LOCATE N,40         'установка курсора в середину строки
120 PRINT CHR$(186);    'печатаем вертикальную черту
130 NEXT                'переход к следующей строке

Когда  используется  несколько дисплейных  страниц,  то  оператор
LOCATE действует на текущей активной странице памяти.  Если стра-
ница, выводимая в данный момент на монитор, не активна, то  поло-
жение курсора на экране не  меняется.   Отметим, что Бейсик имеет
собственную переменную, хранящую текущее положение курсора.  Если
Вы подключите ассемблерную подпрограмму,  которая изменит положе-
ние курсора, то Бейсик проигнорирует новую позицию курсора, когда
ему будет возвращено управление.

   Средний уровень.


   Операционная  система предоставляет два способа позиционирова-
ния курсора в абсолютную позицию на  экране. Функция 2 прерывания
10H устанавливает курсор, относящийся к указанной странице  памя-
ти. Страницы нумеруются начиная с нуля и для монохромного дисплея
номер  страницы  (находящийся в BH) должен всегда быть равным  0.
DH:DL содержат строку  и  столбец,  которые  тоже нумеруются с 0.
Курсор  меняет  свое  положение на экране только  если  установка
курсора относится к текущей активной странице.

;---установка курсора в строку 13, столбец 39
   MOV  AH,2        ;номер функции
   MOV  BH,0        ;номер страницы
   MOV  DH,13       ;строка
   MOV  DL,39       ;столбец
   INT  10H         ;позиционируем курсор

   Второй метод позиционирования курсора  состоит в использовании
специального  драйвера устройства ANSI.SYS, который  должен  быть
загружен при старте  системы.  В  приложении  Д  даны необходимые
сведения.   Для вывода строки, содержащей информацию о  строке  и
столбце используется функция 9 прерывания 21H.  Строка начинается
с символа Esc (ASCII 27), а завершается символом ограничителем $.
Формат строки  Esc[строка,столбецH$,  где  строка и столбец нуме-
руются  от нуля, а Esc обозначает код ASCII 27.  Например, строка
27,'10;60H$' устанавливает курсор в строку 10, столбец 60.

   Хотя такой метод кажется  излишне  сложным,  но он оказывается
очень удобным при выводе ряда строк на экран, так как  Esc-после-
довательность обрабатывается как  одна из строк набора.  В данном
примере три строки сообщения разбросаны по всему экрану.

;---в сегменте данных
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$'
;---печать строк
   MOV  AH,9           ;номер функции вывода строки
   LEA  DX,POSITION_1  ;1-я строка позиционирования курсора
   INT  21H            ;позиционируем курсор
   LEA  DX,STRING_1    ;1-я текстовая строка
   INT  21H            ;вывод строки
   LEA  DX,POSITION_2  ;и т.д.
   INT  21H            ;
   LEA  DX,STRING_2    ;
   INT  21H            ;
   LEA  DX,POSITION_3  ;
   INT  21H            ;
   LEA  DX,STRING_3    ;
   INT  21H            ;

   Низкий уровень.


   Регистры 14 и 15 микросхемы 6845 хранят положение курсора.  Вы
можете изменить их значение и курсор передвинется в соответствую-
щую  позицию  экрана,  но прерывания вывода на экран  DOS и  BIOS
будут игнорировать Вашу установку  и вернут курсор в старое поло-
жение.   Это  происходит потому, что каждый раз при  вызове  этих
прерываний,  они   восстанавливают   регистры  курсора, используя
2-байтное  значение,  хранящееся в области данных BIOS.   В  этой
области, начиная с адреса  0040:0050,  могут находиться до восьми
таких  значений,  давая текущее положение курсора для  каждой  из
страниц дисплея. Процедура низкого уровня должна модифицировать и
эти значения, чтобы изменить состояние курсора полностью.
   Позиция курсора хранится в регистрах 14 и 15 как число от 0 до
1999, что соответствует 2000 (25*80) позициям экрана. Не спутайте
эту  систему нумерации с позициями видеобуфера от 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

 
« Предыдущая статья   Следующая статья »