Страница 12 из 47
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
|