ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 04.07.2020
Просмотров: 3192
Скачиваний: 1
адресов буфера неактивного монитора.
Высокий уровень.
В Бейсике надо просто использовать следующий код:
100 'Переключение на монохромный дисплей
110 KEY OFF: CLS
120 WIDTH 40
130 DEF SEG = 0
140 M = PEEK(&H410)
150 POKE &H410,M OR &H30
160 WIDTH 80
170 LOCATE,,1,12,13
180 KEY ON
100 'Переключение на цветной графический дисплей (80 символов)
110 KEY OFF: CLS
120 WIDTH 80
130 DEF SEG = 0
140 M = PEEK(&H410)
150 POKE &H410,(M AND &HCF) OR &H20
160 WIDTH 80
170 SCREEN 0
180 LOCATE,,1,6,7
190 KEY ON
100 'Переключение на EGA (80 символов)
110 KEY OFF: CLS
120 WIDTH 80
130 DEF SEG = 0
140 M = PEEK(&H410)
150 POKE &H410,M AND &HCF
160 WIDTH 80
170 SCREEN 0
180 LOCATE,,1,6,7
190 KEY ON
Измените команды WIDTH и SCREEN, чтобы переключиться на другие
начальные режимы дисплея.
Низкий уровень.
В ассемблере, как и в Бейсике, надо прямо изменить биты 4 и 5
по адресу 0000:0410. Надо сбросить режим дисплея сразу вслед за
изменением.
;---переключение на монохромный монитор
SUB AX,AX ;обнуляем AX
MOV ES,AX ;устанавливаем ES на начало памяти
MOV DL,ES:[410H] ;получаем байт по адресу 0000:0410
OR DL,00110000B ;устанавливаем биты 4 и 5
MOV ES:[410H],DL ;возвращаем байт
MOV AH,0 ;фукция установки режима дисплея
MOV AL,0 ;монохромный режим 80*25
INT 10H ;устанавливаем режим
;---переключение на цветной монитор (40 символов)
SUB AX,AX ;устанавливаем ES на начало памяти
MOV ES,AX ;
MOV DL,ES:[410H] ;берем байт по адресу 0000:0410
AND DL,11001111B ;сбрасываем биты 4 и 5
OR DL,00010000B ;устанавливаем бит 4
MOV ES:[410H],DL ;возвращаем байт
MOV AH,0 ;функция установки режима дисплея
MOV AL,1 ;цветной режим 40*25
INT 10H ;устанавливаем режим
;---переключение на EGA
SUB AX,AX ;устанавливаем ES на начало памяти
MOV ES,AX ;
MOV DL,ES:[410H] ;берем байт по адресу 0000:0410
AND DL,11001111B ;сбрасываем биты 4 и 5
MOV ES:[410H],DL ;возвращаем байт
MOV AH,0 ;функция установки режима дисплея
MOV AL,1 ;цветной режим 40*25
INT 10H ;устанавливаем режим
Раздел 2. Управление курсором.
Курсор служит двум целям. Во-первых, он служит указателем
места на экране, в которое операторы программы посылают свой
вывод. Во-вторых, он обеспечивает видимую точку отсчета на экране
для пользователя программы. Только для второго применения курсор
должен быть видимым. Когда курсор невидим (выключен), то он все
равно указывает на позицию экрана. Это важно, поскольку любой
вывод на экран, поддерживаемый операционной системой, начинается
с текущей позиции курсора.
Курсор генерируется микросхемой контроллера дисплея 6845,
описанной в [4.1.1]. Эта микросхема имеет регистры, устанавливаю-
щие размер и положение курсора. Микросхема 6845 делает только
мерцающий курсор, хотя имеются программные способы создания не-
мерцающего курсора [4.2.6]. Частота мерцания курсора не может
быть изменена. В графических режимах курсор не выводится, хотя
символы позиционируются на экране теми же самыми процедурами
установки курсора, что и в текстовых режимах.
Когда видеосистема работает в режиме, допускающем несколько
дисплейных страниц, то каждая страница имеет свой собственный
курсор и при переключении между страницами восстанавливается
позиция курсора, которую он занимал, когда было последнее обраще-
ние к восстанавливаемой странице. Некоторые режимы дисплея позво-
ляют иметь до 8 дисплейных страниц и соответствующие им позиции
курсора хранятся в наборе восьми 2-байтных переменных в области
данных BIOS, начиная с адреса 0040:0050H. В каждой переменной
младший байт содержит номер столбца, отсчитывая от 0, а старший
байт содержит номер строки, также отсчитывая от 0. Когда исполь-
зуется меньше чем 8 страниц, то используются переменные, располо-
женные в более младших адресах памяти.
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
4.2.2 Относительное позиционирование курсора
Иногда бывает полезным сдвинуть курсор относительно его преды-
дущей позиции: на строку вверх, на три столбца вправо, и т.д.
Достаточно просто использовать для этой цели уже описанное абсо-
лютное позиционирование курсора. Но для удобства MS DOS предос-
тавляет некоторые возможности относительного перемещения курсора.
Средний уровень.
Функции относительного перемещения курсора выполняются
Esc-последовательностями. Это строки, которые выводятся на экран
с помощью функции 9 прерывания 21H. В приложении Д даны основы их
использования. Такие последовательности интерпретируются MS DOS
как команды перемещения курсора, а не вывод символов строки.
Строка начинается с символа Esc (ASCII 27), затем идет символ [,
а символ $ отмечает конец строки. Сама строка состоит из числа
позиций, на которое надо сдвинуться, и кода направления. Чтобы
сдвинуться на 3 позиции:
вверх 3A
вниз 3B
вправо 3C
влево 3D
Числа записываются как коды ASCII. Не преобразуйте, например, 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-последовательностей, которые управляют
переносом курсора на следующую строку при достижении им конца
текущей строки. Когда устанавливается отсутствие переноса, то
лишние символы при выводе отбрасываются. Строка, запрещающая
перенос - Esc [=7h (или как данные, 27,'[=7h'). Для возврата к
режиму автоматического переноса на следующую строку используется
строка Esc [=7l (27,'[=7l').
4.2.3 Включение и выключение курсора.
Курсор генерируется микросхемой 6845. Он функционирует совер-
шенно независимо от видеопамяти. Это значит, что при прямой адре-
сации в память дисплея [4.3.1] программное обеспечение должно
координировать перемещения курсора с вставкой нового символа в
буфер. Отметим, что микросхема 6845 не может ни создавать немер-
цающий курсор, ни изменить частоту его мерцания. В [4.2.6] пока-
зано как сконструировать другие "искусственные" типы курсора.
Высокий уровень.
Интерпретатор Бейсика автоматически выключает курсор при за-
пуске программы. Курсор появляется, когда используется оператор
INPUT, но не в других случаях. Если Вашей программе необходим
курсор, скажем для процедуры INKEY$, то он должен быть включен
установкой третьего параметра оператора LOCATE в 1 (0 снова вык-
лючит его). Напоминаем, что первые два параметра оператора LOCATE
устанавливают строку и столбец, в которых должен выводиться кур-
сор.
100 LOCATE 15,40,1 ;включить курсор, его позиция 15,40
или
100 LOCATE ,,1 ;включить курсор в текущей позиции
и
100 LOCATE ,,0 ;снова выключить курсор
Курсор будет оставаться при последующих появлениях оператора
LOCATE без установки каждый раз третьего параметра. Однако надо
отметить, что операторы INPUT и INPUT$ выключат его после их
выполнения.
Средний уровень.
Ассемблерные программы оставляют курсор включенным, до тех
пор, пока им не указано обратное. Операционная система не предос-
тавляет специальных средств выключения курсора, но это легко
сделать. Надо просто позиционировать курсор за пределы экрана, с
помощью функции 2 прерывания 10H установить его в первую позицию
26-й строки. Помните, что координаты отсчитываются от нуля, так
что этой позиции соответствуют координаты 25,0.
MOV BH,0 ;номер страницы (всегда 0 для монохромного)
MOV DH,25 ;строка
MOV DL,0 ;столбец
MOV AH,2 ;номер функции
INT 10H ;устанавливаем курсор за пределы экрана
Низкий уровень.
Бит 6 регистра 10 микросхемы 6845 [4.1.1] выключает курсор,
когда он установлен в 1, и включает его, когда сброшен в 0. Этот
регистр содержит также значение "начальной строки" для курсора,