Консалтинговая компания Консалтер.Ру
Главная Новости Библиотека Исследования Законодательство Консалтинг Бизнес-форумы Контакты

Реклама

Рекомендуем



Консалтер.Ру > Библиотека > Информационные технологии

В.А. Авдеев, В.Ф. Гузик
Компьютеры: шины, контроллеры, периферийные устройства

Учебное пособие. Таганрог: ТРТУ, 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 и т.д. 

Предыдущая

Похожие материалы:
Управление кредитными рисками
Управление конфликтами, стрессами и изменениями (Алесинская Т.В. и др.)
Управление качеством. Термины и определния
Управление логистическими цепями в производстве
Управление маломерным судном судоводителем, не имеющим при себе документов, необходимых для допуска к управлению маломерным судном - КоАП
Управление маркетингом



О сайте   Авторам   Реклама и услуги   Контакты
Copyright © 2007-2021, Консалтер.Ру