В.А. Авдеев, В.Ф. Гузик
Компьютеры: шины, контроллеры, периферийные устройства
Учебное пособие. Таганрог: ТРТУ, 2001. - 536 с.
Приложение В. Проверочные задания, основные сведения и примеры программ
Управление курсором
5.1. Формулировка задания
Цель этой работы заключается в изучении принципов образования
различных форм курсора и управления его позиционированием. Разработанная
программа на языке Ассемблера должна выполнять функции 01, 02, 03 прерывания
BIOS INT10h по управлению курсором. При разработке программы использовать
прямой доступ к регистрам контроллера ЭЛТ видеоадаптера.
5.2. Основные сведения
В текстовых режимах курсор предназначен для визуального
наблюдения на экране места размещения символа, т.е. функция курсора состоит в
указании активной части экрана. Формирование курсора и отслеживание его позиции
на экране осуществляет контроллер ЭЛТ, входящий в состав адаптера дисплея. Для
этого контроллер ЭЛТ содержит следующие регистры: регистр R10 (0Аh) начальной строки
развертки курсора, регистр R11 (0Bh) конечной строки развертки курсора, регистр
R14 (0Eh) старшего байта позиции курсора и регистр R15 (0Fh) младшего байта
позиции курсора. Доступ к указанным и другим регистрам контроллера ЭЛТ
осуществляется с помощью регистра индекса (порт 3D4h) и регистра данных (порт
3D5h). Содержимое регистра индекса используется для выбора соответствующего
регистра контроллера ЭЛТ, а через регистр данных выполняется запись (чтение)
данных в выбранный регистр контроллера ЭЛТ. В регистрах R10 и R11 для
формирования размера курсора используются биты 0-4. Доступ к регистрам
контроллера ЭЛТ адаптера VGA (EGA) можно осуществить по команде OUT DX, AX, в
которой в DX задается адрес 3D4h, в AL – номер регистра и в AH – код выводимого
значения.
Рассмотрим
образование различных форм курсора для адаптера VGA. Если символьной позиции
соответствует матрица 8x8, то возможны следующие формы курсора (рис.1).
Рис.1. Демонстрация форм курсора для
различных значений регистров R10 и R11
BIOS в области данных дисплея содержит данные текущей формы
курсора. По адресу 0040:0060h находится байт, указывающий на начальную строку
курсора. Конечная строка курсора содержится в байте, хранящемся по адресу
0040:0061h. При смене значений в регистрах R10 и R11 необходимо модифицировать
эти значения в указанных байтах переменной CUR-MODE. Процедура BIOS изменяет
эту переменную на исходное значение (начальная строка – 0Dh и конечная строка –
00h), т.е. обычно курсор мигает в двух нижних строках развертки.
Так как
матрицы символьных позиций для текстовых режимов имеют различные размеры (8x8,
8x14 и 9x16), то в адаптере VGA выполняется масштабирование (эмуляция) курсора.
Процедура BIOS предусматривает коррекцию формы курсора при смене режимов
(матриц символов с различной высотой) так, чтобы размер курсора не изменялся.
Если в области данных дисплея бит D0 байта, имеющего адрес 0040:0087h, равен
1, то эмуляция запрещена. При сбросе этого бита разрешается эмуляция курсора.
В адаптере
VGA (EGA) биты D6 и D5 (не равные 0) регистра R11 управляют сдвигом курсора
вправо.
Если D6 и D5 равны 01, 10 или 11, то курсор соответственно
сдвигается на одну, две или три символьные позиции относительно позиции,
задаваемой регистрами R14 и R15. Для перемещения курсора в заданное место
необходимо задать соответствующие значения (смещение относительно начала
видеобуфера) в регистрах R14 и R15. Позиция курсора на экране в текстовом
режиме 80x25 определяется числом (N), взятом из диапазона 0-1999. Удобно задавать
позицию курсора номером столбца и номером строки, например, столбец 79 и строка
1. Тогда N = (1x80)+79 = 159, т.е. номер строки (координату X) надо умножить на
80 и прибавить номер столбца (координату Y). При вызове процедур программных
прерываний BIOS или DOS содержимое R14 и R15 заменяется на значения,
хранящиеся в области данных дисплея BIOS, начиная с адреса 0040:0050h. Для
восьми экранных страниц BIOS использует соответственно восемь таких значений,
отражающих текущее положение курсора для каждой из страниц. Каждое такое
значение в старшем байте содержит номер строки, а младший байт – номер столбца
позиции курсора. Независимо от текущей активной страницы можно изменять
значение курсора (выполнять невидимое его позиционирование) другой пассивной
страницы и заполнять ее выводимыми данными. После этого можно осуществить
быстрое переключение на новую активную страницу.
Чтобы
выключить курсор, необходимо в регистр R10 записать код 20h, который задаёт
начальную строку курсора за пределами символьной матрицы. Другой способ состоит
в выводе курсора за пределы экрана, т.е. заключается в использовании регистров
R14 и R15.
Можно
представить другую форму иного курсора (псевдокурсора) путём использования соответствующего
байта атрибута символа и выключения настоящего курсора. В этом случае программа
выводит какой-либо символ, например, с атрибутом мигания в текущую позицию
выключенного курсора.
5.3. Пример выполнения варианта задания
p286
DATA SEGMENT
str_menu0 db
'ПЕРЕМЕЩЕНИЕ КУРСОРА' ;19
str_menu1 db
'ИЗМЕНЕНИЕ КУРСОРА' ;17
str_menu2 db '
ПСЕВДОКУРСОР ' ;17
str_menu3 db
'ВЫХОД' ;5
atr_menu0 db 6Eh ;__
atr_menu1 db 1Eh ; \
atr_menu2 db 1Eh ; |
atr_menu3 db 1Eh ; |\ это байты атрибутов
atr_menu11 db 1Eh ; |/ надписей меню
atr_menu12 db 1Eh ; |
atr_menu21 db 1Eh ; /
atr_menu22 db 1Eh ;--
Cursor_Pos db 00h
C_C_Message
db 'нижняя линия клавиши ¯ , верхняя PgUp PgDn'
M_C_Message
db 'перемещение курсора осуществляется
клавишами ,¯,¬,®,
вкл/выкл - "F5" '
M_D_Message
db 'перемещение мигающего псевдокуpсора осуществляется клавишами ,¯,¬,®'
C_S_Message
db
'
'
Ld db 8
Lu db 0
ULine db 0 ;начальная строка сканирования
DLine db 0 ;конечная строка сканирования
DATA ENDS
CODE SEGMENT
ASSUME CS : CODE, DS : DATA
My_Start:
mov ax,DATA
mov ds,ax
;-------------
очистка экрана и установка своего видео режима (текст 80*25)-------
mov ah,00h
;в ah=00h,в al=03h(видеорежим 80*25)
mov al,03h
int 10h ; установка видеорежима
My_Start1:
;------------------------------
установка на экране синего фона-----------------------------
mov ah,09h
;в ah=09h
mov bh,00h
;в bh=00h (номер экранной страницы)
mov al,'
' ;в al=' '
mov bl,00011111b ;в bl-атрибут
фона
mov cx,7D0h
int 10h ;установка на экране синего фона
;---------------------------
вычерчивание обрамляющей рамки на экране--------------------
mov ah,02h
;в ah=02h
mov dx,01h
;в dx-координаты курсора
int 10h ;установка курсора в заданное
положение
mov ah,09h
;в ah=09h
mov bh,00h
;в bh=00h (номер экранной страницы)
mov al,'-' ;в al='=' (выводимый символ)
mov bl,00011111b
;в bl-атрибут фона
mov cx,78 ;в cx=78(количество повторяющихся знаков)
int 10h ;изображение верхней линии меню
mov ah,02h
mov dh,02 ;в dh=02 (строка)
mov dl,01 ;в dl=01 (колонка)
int 10h ;установка курсора в заданное положение
mov ah,09h
mov cx,78
int 10h ;вычерчивание
промежуточной линии меню
mov ah,02h
mov dh,22
mov dl,01
int 10h ;перемещение курсора в заданное положение
mov ah,09h
mov cx,78
int 10h ;изображение
последующей линии меню
mov ah,02h
mov dh,24
mov dl,01
int 10h ;перемещение курсора в требуемое положение
mov ah,09h
mov bh,00h
mov al,'-'
mov bl,00011111b
mov cx,78
int 10h ;вычерчивание нижней линии меню
mov dx,00h
;перемещение курсора в координаты 0,0
mov al,'|'
mov cx,01h
M_1:
inc dh
mov ah,02h
int 10h ;установка курсора в
необходимое положение
mov ah,09h
int 10h ;изображение вертикальной линии меню
cmp dh,23
jne M_1
mov dl,79
mov dh,00h
M_2:
inc dh
mov ah,02h ;установка курсора для прорисовки следующей
int 10h ;вертикальной линии
mov ah,09h
int 10h ;выдача вертикальной линии на экран
cmp dh,23
jne M_2
mov ah,02h
mov dx,00h ;установка курсора для прорисовки
int 10h ;угловых частей меню
mov ah,0Ah ;в ah=0Ah
mov al,'+'
int 10h ;изображение левой верхней угловой части
mov ah,02h
mov dh,00h
mov dl,79
int 10h ;установка курсора в необходимое положение
mov ah,0Ah
mov al,'+'
int 10h ;изображение правой
верхней угловой части
mov ah,02h
mov dh,24
mov dl,00h
int 10h ;установка курсора в требуемое положение
mov ah,0Ah
mov al,'+'
int 10h ;вычерчивание левой
нижней угловой части
mov ah,02h
mov dh,24
mov dl,79
int 10h ;установка курсора в необходимое положение
mov ah,0Ah
mov al,'+'
int 10h ;вычерчивание правой
нижней угловой части
;---------------------------------------------
заполнение заглавия меню------------------------------------
mov ax,ds
mov es,ax
;при выводе es=ds
Menu_1:
mov bh,00h
;в bh=00h (номер видеостраницы)
mov ah,13h
;в ah=13h (функция)
mov al,01h
;в al=01h (подфункция)
mov dh,01 ;в dh=01 (строка)
mov bp,offset str_menu0 ;в es:bp (начало выводимой строки)
mov bl,atr_menu0 ;в bl-атрибут
mov dl,4 ;в dx-начальная позиция курсора
mov cx,19 ;в cx-длина строки
int 10h ;вывод пункта меню на экран
mov bp,offset
str_menu1
mov bl,atr_menu1
mov dl,26
mov cx,17 ;вывод пункта меню "изменение
курсора"
int 10h ;на экран
mov bp,offset
str_menu2
mov bl,atr_menu2
mov dl,48
mov cx,17 ;вывод пункта меню
"псевдокурсор"
int 10h ;на экран
mov bp,offset str_menu3
mov bl,atr_menu3
mov dl,72
mov cx,5 ;вывод пункта
меню "выход"
int
10h ;на экран
mov ah,02h
mov dh,25
mov dl,80
int 10h ;установка курсора за пределы экрана
;---------------------------------------------
выбор пункта меню---------------------------------------------
Menu_3:
mov ah,08h
;в ah=08h (функция)
int 21h ;ожидание ввода символа
cmp al,13 ;если нажат ENTER, определяется пункт
jne Menu_4 ;меню, на котором остановлен выбор
cmp Cursor_Pos,03h
;если Cursor_Pos=03h,то выход
jne Menu_31 ;из программы
jmp EXIT
Menu_31:
cmp Cursor_Pos,01h ;если Cursor_Pos=01h,то переход
jne Menu_32 ;к процедуре Chang_Cursor,
call Chang_Cursor ;осуществляющей изменение формы курсора
jmp My_Start1
Menu_32:
cmp Cursor_Pos,02h ;если Cursor_Pos=02h,то переход
jne Menu_33 ;к процедуре MoveSCursor,
call MoveSCursor ;осуществляющей создание
псевдокурсора
jmp My_Start
Menu_33:
cmp Cursor_Pos,00h ;если Cursor_Pos=00h,то переход
jne Menu_3 ;к процедуре Move_Cursor,
call Move_Cursor ;осуществляющей перемещение курсора
jmp My_Start1
Menu_4:
cmp al,0
jne Menu_3
mov ah,08h ;в
ah=08h (функция)
int 21h ;ожидание
ввода символа
cmp al,75 ;если нажата стрелка "влево"
jne Menu_5 ;определяется, на каком пункте
меню мы находимся
cmp Cursor_Pos,00h ;если
Cursor_Pos не равен 00h, то
jne Menu_41 ;уменьшаем
позицию курсора на 1
mov Cursor_Pos,03h ;в противном случае Cursor_Pos=03h
jmp Menu_6
Menu_41:
dec Cursor_Pos ;уменьшение Cursor_Pos на 1
jmp Menu_6
Menu_5:
cmp al,77 ;если нажата стрелка
"вправо"
jne Menu_3
cmp Cursor_Pos,03h ;если Cursor_Pos не равен 03h, то
jne Menu_51 ;увеличиваем
позицию курсора на 1
mov Cursor_Pos,00h ;в противном случае Cursor_Pos=00h
jmp Menu_6
Menu_51:
inc Cursor_Pos ;наращивание Cursor_Pos на 1
Menu_6:
cmp Cursor_Pos,00h ;если Cursor_Pos=00h,то
jne Menu_61 ;байт атрибутов
надписей меню равен 6Eh
mov atr_menu0,6Eh
jmp Menu_611
Menu_61:
mov atr_menu0,1Eh ;в противном случае равен 1Eh
Menu_611:
cmp Cursor_Pos,01h ;если Cursor_Pos=01h,то
jne Menu_62 ;байт атрибутов
надписей меню равен 6Eh
mov atr_menu1,6Eh
jmp Menu_621
Menu_62:
mov atr_menu1,1Eh ;в противном случае равен 1Eh
Menu_621:
cmp Cursor_Pos,02h ;если Cursor_Pos=02h,то
jne Menu_63 ;байт атрибутов
надписей меню равен 6Eh
mov atr_menu2,6Eh
jmp Menu_631
Menu_63:
mov atr_menu2,1Eh ;в противном случае равен 1Eh
Menu_631:
cmp Cursor_Pos,03h ;если Cursor_Pos=03h,то
jne Menu_64 ;байт
атрибутов надписей меню равен 6Eh
mov atr_menu3,6Eh
jmp Menu_641
Menu_64:
mov atr_menu3,1Eh ;в противном случае равен 1Eh
Menu_641:
jmp Menu_1
;----------------------------------------------
очистка экрана--------------------------------------------------
EXIT:
mov ah,00h ;в ah=00h
mov al,03h ;в al=03h
(видеорежим)
int 10h ;установка видеорежима
;----------------------------------завершение
программы--------------------------------------------
mov ah,4Ch
int 21h
Chang_Cursor
Proc Near
mov bh,00h ;в bh=00h
(видеостраница)
mov ah,13h
;в ah=13h (функция)
mov al,01h
;в al=01h (подфункция)
mov dh,23
mov bp,offset C_C_Message ;es:bp-начало строки
mov bl,1Eh ;атрибут выводимого Help
mov dl,2 ;в dх- начальная позиция курсора
mov cx,76 ;в cx-количество символов в строке
int 10h ;вывод на экран
контекстного Help
mov ah,02h
mov dh,12 ;в dх-начальная позиция курсора
mov dl,40
int 10h ;устанавливается начальное положение
курсора
mov AH,1
mov CH,Lu
;в CH-начальная строка сканирования
mov CL,Ld
;в CL-конечная строка сканирования
int 10H ;установка размера курсора
;----------------опрашивается
клавиатура---------------------------------------
C_C_1:
mov ah,08h
int 21h ;считывается в al код нажатой клавиши
cmp al,00h
;если al не равно 00h,
je C_C_2 ;то
проверяется нажатие клавиши ESC(выход)
cmp al,27
jne C_C_1
jmp C_C_Exit
C_C_2:
mov ah,08h
int 21h ;считывается в al код нажатой клавиши
cmp al,72 ;проверка на нажатие клавиши
"вверх"
jne C_C_3
cmp Ld,0 ;проверка конечной строки сканирования
je C_C_6 ;на
равенство нулю
dec Ld ;наращивается конечная строка сканирования
jmp C_C_6
C_C_3:
cmp al,80 ;проверка на нажатие клавиши
"вниз"
jne C_C_4
cmp Ld,16 ;проверка конечной строки сканирования
je C_C_6
;на равенство максимальному значению
inc Ld ;уменьшается конечная строка сканирования
jmp C_C_6
C_C_4:
cmp al,73 ;проверка на нажатие клавиши "Page up"
jne C_C_5
cmp Lu,0 ;проверка начальной строки сканирования
je C_C_6 ;на
равенство нулю
dec Lu ;наращивается начальная строка сканирования
jmp C_C_6
C_C_5: ;проверка на нажатие клавиши "Page down"
cmp al,81
jne C_C_6
cmp Lu,16 ;проверка начальной строки
сканирования
je C_C_6 ;на
равенство максимальному значению
inc Lu ;уменьшается начальная строка сканирования
C_C_6:
mov dx,3d4h ;адресация индексного
порта контроллера
mov al,0ah
;выборка 10-го регистра
out dx,al
inc dx ;адресация порта данных контроллера
mov al,Lu
;занесение значения начальной
out dx,al
;строки сканирования
mov dx,3d4h ;адресация индексного
порта контроллера
mov al,0bh
;выборка 11-го регистра
out dx,al
inc dx ;адресация порта данных контроллера
mov al,Ld
;занесение значения конечной
out dx,al ;строки
сканирования
jmp C_C_1
C_C_Exit:
ret
Chang_Cursor
Endp
OldX dw 0 ; координата х предыдущей позиции
курсора
OldY dw 0 ; координата у предыдущей позиции
курсора
Char dw 0 ; сохраненный символ
MoveSCursor Proc Near
mov bh,00h
;в bh=00h (видеостраница)
mov ah,13h
;в ah=13h (функция)
mov al,01 h
;в al=01h (подфункция)
mov dh,23
mov bp,offset M_D_Message;es:bp-начало строки
mov bl,1E ;атрибут выводимого Help
mov dl,2 ;в dх-начальная позиция курсора
mov cx,76 ;в cx-количество символов в строке
int 10h ;вывод на экран контекстного Help
mov dl,40
mov dh,12 ;в dх- начальная позиция курсора
mov ah,02h
int 10h ;устанавливается начальное положение
курсора
;-----------------------------------
сохранение символа в позиции курсора-----------------------------
mov dx,30 ; X- координата курсора
mov [OldX],dx
mov cx,10 ; Y- координата курсора
mov [OldY],cx
call GetChar
mov di,09F2Dh ;прорисовка
курсора
call PutChar
A_31:
mov ah,08h
int 21h ;считывание
в al кода нажатой клавиши
cmp al,27 ;если нажата клавиша ESC, то выход
jne A_33
jmp M_D_EXIT
A_33:
cmp al,0 ;если содержимое al не равно 0,
jne A_31 ;то ожидается повторное нажатие
клавиш
mov ah,08h
int 21h
cmp al,75 ;если нажата клавиша
"влево",
jne A_34
dec dx ;уменьшается значение координаты dx на 1
A_34:
cmp al,77 ;если нажата клавиша
"вправо",
jne A_35
inc dx ;увеличивается значение координаты
dx на 1
A_35: cmp al,80
;если нажата клавиша "вниз",
jne A_36
inc cx ;увеличивается значение координаты
сx на 1
A_36: cmp al,72
;если нажата клавиша "вверх",
jne A_37
dec cx ;уменьшается значение координаты сx на 1
A_37:
;-----------------
восстановление символа в старой позиции---------------
pusha
mov dx,[OldX]
mov cx,[OldY]
mov di,[Char]
call PutChar
popa
call GetChar ;сохранение
символа из новой позиции
mov di,09F2Dh ;прорисовка курсора в
новой позиции
call PutChar
;сохранение
текущих координат курсора, чтобы в дальнейшем восстановить
;---------
символ, находящийся на этом месте------------------------------
mov [OldX],dx
mov [OldY],cx
jmp A_31
M_D_EXIT:
;-------------------
при выходе затирание псевдокуpсоpа------------------
mov dx,[OldX]
mov cx,[OldY]
mov di,[Char]
call PutChar
ret
MoveSCursor
Endp
;-----------
Чтение из видеопамяти символ+атpибут---------------------
;
dx=X cx=Y [Char]=char
GetChar
Proc Near
pusha
push es
;mov ax,cx
imul cx,cx,160 ; cx=cx*160
mov cx,ax
shl dx,1 ; dx=dx*2
add cx,dx ; cx=cx+dx - смещение в видеопамяти
mov bx,cx
push 0B800h
pop es
mov ax,es:[bx]
mov [Char],ax
pop es
popa
ret
GetChar
Endp
;------------
Запись в видеопамять символ+атpибут------------------
;
dx=X cx=Y di=Char
PutChar
Proc Near
pusha
push es
imul cx,cx,160 ; cx=cx*160
shl dx,1 ; dx=dx*2
add cx,dx
; cx=cx+dx - смещение в
видеопамяти
mov bx,cx
push 0B800h
pop es
mov es:[bx],di
pop es
popa
ret
PutChar
Endp
Trigger
db 0 ;флаг нажатия клавиши
Move_Cursor Proc Near ;для исчезновения курсора
mov [Trigger],0
mov [ULine],0 ;начальная строка сканирования
mov [DLine],14 ;конечная строка сканирования
call SetCursorSize
mov bh,00h
;в bh=00h (видеостраница)
mov ah,13h
;в ah=13h (функция)
mov al,01h
;в al=01h (подфункция)
mov dh,23
mov bp,offset M_C_Message ;es:bp-начало строки
mov bl,1Eh ;атрибут выводимого Help
mov dl,2 ;в dх-начальная позиция курсора
mov cx,76 ;в cx-количество символов в строке
int 10h ;вывод на экран контекстного
Help
mov dl,40 ;в dх-начальная позиция курсора
mov dh,12
mov ah,02h
int 10h ;устанавливается начальное положение курсора
A_21: mov ah,08h ;считывание в al кода нажатой клавиши
int 21h
cmp al,27 ;если нажата клавиша esc,то выход
jne A_23
jmp M_C_EXIT
A_23: cmp al,0
;если содержимое al не равно 0,
jne A_21 ;то ожидается повторное нажатие
клавиш
mov ah,08h
int 21h ;считывание в al кода нажатой клавиши
cmp al,3Fh
;если нажата клавиша "F5",то
курсор
jne
Not5 ;исчезает
xor [Trigger],15
Not5:
pusha
mov al,[Trigger]
mov [ULine],al ;начальная строка сканирования
mov [DLine],14 ;конечная строка сканирования
call SetCursorSize ;изменение размеров
курсора
popa
cmp al,75 ;если нажата клавиша "влево"
jne A_24 ;уменьшается координата dl
dec dl
A_24:
cmp al,77 ;если нажата клавиша "влево"
jne A_25 ;увеличивается координата dl
inc dl
A_25:
cmp al,80 ;если нажата клавиша "вниз"
jne A_26 ;увеличивается координата dh
inc dh
A_26:
cmp al,72 ;если нажата клавиша "вверх"
jne A_27 ;уменьшается координата dh
dec dh
A_27:
mov ah,02h
int 10h ;установка месторасположения курсора
jmp A_21
M_C_EXIT:
ret
Move_Cursor
Endp
SetCursorSize
Proc Near
pusha
mov dx,3d4h ;адресация индексного порта
контроллера
mov al,0ah
;выборка 10-го регистра
out dx,al
inc dx ;адресация порта данных контроллера
mov al,[ULine]
;занесение значения начальной
out dx,al
;строки сканирования
mov dx,3d4h ;адресация индексного
порта контроллера
mov al,0bh
;выборка 11-го регистра
out dx,al
inc dx ;адресация порта данных контроллера
mov al,[DLine]
;занесение значения конечной
out dx,al
;строки сканирования
popa
ret
SetCursorSize
Endp
CODE
ENDS
END My_Start
Краткое описание
программы
После запуска программы на экране появляются пункты меню,
которые включают в себя:
1.
Перемещение
курсора;
2.
Изменение
курсора;
3.
Псевдокурсор;
4.
Выход.
Первый пункт подразумевает перемещение курсора по экрану в
зависимости от нажатых клавиш . Перемещая курсор, можно его включать, нажав
клавишу «5» на дополнительной клавиатуре. При повторном нажатии этой клавиши
курсор появляется. С помощью второго пункта можно изменять форму курсора,
используя клавиши ,
«Page up», «Page down».
Под третьим пунктом меню подразумевается создание своего
псевдокурсора с каким-либо
атрибутом. В нашем случае это «-» с атрибутом мигания. Псевдокурсор можно перемещать по экрану с помощью
клавиш .
По нажатию клавиши Esc можно произвести выход из текущего
пункта меню и выбрать следующий, используя Enter.
Для реализации данной программы были использованы следующие
процедуры:
Процедура Chang_Cursor осуществляет изменение размеров курсора.
Входными переменными являются:
-
Lu - начальная строка сканирования;
-
Ld - конечная строка сканирования;
Размеры курсора изменяются от 0 до 16.
Клавишами можно изменить конечную
строку сканирования, а «Page up» и «Page down » - начальную.
Процедура Move_Cursor -
используется для исчезновения курсора по нажатию клавиши «5» на дополнительной
клавиатуре.
Trigger - флаг для отслеживания нажатой клавиши. В случае ее нажатия Trigger=15,
т.е. курсор исчезает. При повторном нажатии Trigger=0, т.е. - появляется.
Процедура SetCursorSize - изменение размеров курсора.
Uline - начальная строка сканирования.
Dline - конечная строка сканирования.
Процедура MoveSCursor используется при создании псевдокурсора.
Входные данные:
· OldX - координата X предыдущей позиции;
· OldY - координата Y предыдущей позиции.
Данная процедура осуществляет следующие действия:
1.
Сохранение
символа в позиции курсора;
2.
Перемещение
курсора в зависимости от нажатых клавиш ;
3.
Восстановление
символа в старой позиции:
dx=[OldX]
cx=[OldY]
di=[Char]
4.
Сохранение
символа из новой позиции и вычерчивание псевдокурсора;
5.
Сохранение
текущих координат курсора для дальнейшего восстановления символа, находящегося
на этом месте:
[OldX]=di
[OldY]=cx
Из
данной процедуры идет обращение к процедурам GetChar, PutChar. При выходе из
пункта «Псевдокурсор» созданный псевдокурсор убирается.
Процедура GetChar – чтение из видеопамяти символа и
атрибута.
Входные переменные: dx = x, cx = Y, [Char]
= char.
Для
определения местонахождения символа в видеопамяти (es:[bx]) необходимо выполнить следующие действия:
cx = cx +160
dx = dx*2
bx = cx
Процедура PutChar – запись в видеопамять символа и атрибута. Использует те же
действия, что и процедура GetChar.
Входные переменные: dx = x, cx = Y, di = char.
5.4. Варианты заданий
В общем случае программа
управления курсорам должна отвечать требованиям четырехуровневого
морфологического графа:
-
установки курсора
в заданную позицию (позиционирование курсора);
-
изменения формы
курсора;
-
выключения и
включения курсора;
-
создания
псевдокурсора (логического курсора).
Морфологический
граф вариантов заданий представлен на рис.2.
Рис. 2. Морфологический граф вариантов заданий
В
программе соответствующего варианта может быть учтено любое расположение
уровней, кроме того, допускается исключение некоторых уровней (не более двух).
Без учета
вершины 11 морфологический граф устанавливает 36 вариантов задания.
Для первого уровня вершина 1 для морфологического графа
определяет позиционирование курсора в соответствии с нажатием выбранных клавиш
клавиатуры (вверх, вниз, влево, вправо). Вершина 2 обуславливает применение в
программе некоторого интерфейса пользователя, указывающего на необходимость
ввода номеров строки и столбца новой позиции курсора. Вершина 3 соответствует
фиксированному позиционированию курсора из одной заданной точки экрана в
другую.
На втором уровне вершины 4 определяет метод выключения
курсора путём задания его координат за пределами экрана, а вершина 5 – путём
записи, например, кода 20h в регистр R10.
Третий
уровень изменения формы курсора, содержащий вершины 6 – 8, аналогичен (по назначению
вершин) первому уровню. Вершина 6 соответствует назначению формы курсора по
нажатию выбранных клавиш, причем начальная строка сдвигается, например,
клавишами вверх и вниз, а конечная строка – клавишами плюс (вверх) и минус
(вниз). Вершина 7 указывает на наличие в программе запросов по вводу с
клавиатуры номеров начальной и конечной строк курсора. Вершина 8 определяет
задание в программе фиксированной формы курсора, отличающейся от начального
размера.
Четвёртый
уровень (вершина 9 - 11) устанавливает типы псевдокурсоров. Вершина 9 соответствует
выводу символа в негативе в позицию невидимого курсора. Вершина 10
обуславливает применение мигающего символа в позиции выключенного курсора, а
вершина 11 (творческий вариант) определяет создание собственного псевдокурсора,
например, в командной строке или путём расширения его на несколько символьных
позиций экрана. Здесь следует напомнить, что для монохромного режима негативное
изображение символа задаётся атрибутом, имеющим код 112, мерцание и
подчёркивание символа – кодом 129, мерцание и обычное изображение – кодом 135,
мерцание и яркий символ – кодом 143 и т.д.
Похожие материалы:
Управление кредитными рисками
Управление конфликтами, стрессами и изменениями (Алесинская Т.В. и др.)
Управление качеством. Термины и определния
Управление логистическими цепями в производстве
Управление маломерным
судном судоводителем, не имеющим при себе документов, необходимых для допуска к
управлению маломерным судном - КоАП
Управление маркетингом
|