Аппаратный курсор мыши

Тема в разделе "WASM.ASSEMBLER", создана пользователем dess, 22 авг 2008.

  1. dess

    dess New Member

    Публикаций:
    0
    Регистрация:
    22 авг 2008
    Сообщения:
    46
    Всем привет ! Пожалуйста, подскажите, как включить и управлять аппаратным курсором в графическом видеорежиме !? Как это происходит: через порты, память, или еще как-либо ???
     
  2. dess

    dess New Member

    Публикаций:
    0
    Регистрация:
    22 авг 2008
    Сообщения:
    46
    Объясню: на ассемблере пишу графический интерфейс, видеорежим 4118h (VBE2.0), 1024x768x32. Сейчас парюсь над програмным курсором, но в идеале, не хотелось бы тратить драгоценное процессорное время на перерисовку старого и нового курсоров, если видеокарта позволяет это сделать аппаратно. Но в И-нете по этой теме к сожалению найти ничего не удалось.
     
  3. Vov4ick

    Vov4ick Владимир

    Публикаций:
    0
    Регистрация:
    8 окт 2006
    Сообщения:
    581
    Адрес:
    МО
    Кажется в сети, возможно даже на этом форуме пробегали исходники под конкретную карточку. Насколько я помню, в разных моделях по-разному делается.
    Гугол выдаёт много ссылок на вражеском языке, но кажется всё больше о проблемах с этим курсором.
     
  4. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Вот есть описание для древнющей Sis карточки с 4Мб видеооперативки :)
    Когда то даже работало по этому описанию, но давно и исходники утеряны...
     
  5. CyberManiac

    CyberManiac New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2003
    Сообщения:
    2.473
    Адрес:
    Russia
    Вечность назад пытался чего-то замутить с аппаратным курсором на S3 Virge DX (VESA 2.0) в VESA-режимах, и вынес из этого только одно: с аппаратными курсорами там была полная джоппа: в одних режимах работало, в других - не работало. Короче, лотерея. Так что программный курсор придётся делать по-любому.
     
  6. dess

    dess New Member

    Публикаций:
    0
    Регистрация:
    22 авг 2008
    Сообщения:
    46
    Всем привет ! Огромная спасиба за советы и описание к карточке, покумекую на досуге ! Я так увлёкся программным курсором, что забыл обо всём на свете :) Курсор так быстро и банально перерисовывается, что незаметно никакого мерцания =) Правда вся засада ешё в переди, когда начнёт обновляться объектная графическая система. Я и не думал, что с аппаратным курсором всё так сложно и не стандартно. Ну да ладно. Всем спасиба !
     
  7. KKorolev

    KKorolev New Member

    Публикаций:
    0
    Регистрация:
    27 авг 2011
    Сообщения:
    3
    Отправил на васм заметку по этому вопросу, но ее не публикуют, поэтому отвечаю здесь:
    -------------------------------------------------------------------------------------------

    К.Королев
    Аппаратная генерация курсора

    Опять встретился вопрос о том, как сгенерировать аппаратный курсор в графических режимах дисплея и, хотя развитие видеосистем ушло далеко вперед в направлении Windows и индустрии игр и предлагаемая заметка, возможно, утратила свою актуальность, она может оказаться интересной хотя бы из соображений присущей человеку любознательности.
    Самостоятельная аппаратная генерация курсора (АГК) может понадобиться, если ПО разрабатывается под некоторую ОС, не имеющую инструментов поддержки драйверов устройств, кроме обычных программ-резидентов с обращением к ним через инструкцию INT, хотя ПЗУ видеоадаптера, которое BIOS копирует в теневое ОЗУ по физическому адресу 0C0000h, и можно считать драйвером устройства. Для создания же тандема «мышь-курсор» в MS-DOS, например, грузятся программы-резиденты, но они курсор «отрисовывают», т.к. стандарта на АГК нет, а каждый производитель видеосистем проявляет в этом деле потрясающую воображение изобретательность.
    Поэтому покажем, как АГК выполняется на стареньком видеоадаптере ViRGE/DX/GX (PCI) от S3. Для этого необходимо:
    1. Написать программу, работающую в защищенном режиме процессора. Лучше всего, если это будет программа с 32-битной адресацией. Тогда при соответствующей установке лимита сегмент данных может покрыть все адресное пространство, включая и то, которое находится за пределами ОЗУ (виртуальное). В этом случае все сегментные регистры данных будут содержать один и тот же селектор (или это можно сделать один раз самим) и не надо будет заботиться об их загрузке. Это нужно для реализации следующего пункта.
    2. Установить графический режим с линейным кадровым буфером (LFB), скажем, 640х480х256 (8-битный цвет), когда видеопамять, она же LFB, представляет собой непрерывную (могут быть исключения) последовательность байтов и при 32-битной адресации легко добраться до любого байта. Попутно определим объем видеопамяти (через INT 10h, AH=4Fh VBE) и размер видео-ПЗУ (в случае ViRGE/DX/GX он равен 64*512 байтов). Физические адреса LFB - это 32-битные числа из отрезка [80000000h,0FFFFFFFFh].
    3. Наконец - сама генерация. В сегменте данных надо описать массив из 32 двойных слов, чтобы получить обычный курсор-стрелку:

    CursorArrow dd 0000FF7Fh ;1
    dd 0000FF3Fh
    dd 0040FF1Fh
    dd 0060FF0Fh
    dd 0070FF07h
    dd 0078FF03h
    dd 007CFF01h
    dd 007EFF00h
    dd 007F7F00h
    dd 807F3F00h
    dd 007C1F00h
    dd 006CFF01h
    dd 0046FF10h
    dd 0006FF30h
    dd 00037F78h
    dd 00037FF8h
    dd 80013FFCh
    dd 80013FFCh
    dd 00007FFEh
    dd 0000FFFFh
    dd 0000FFFFh
    dd 0000FFFFh
    dd 0000FFFFh
    dd 0000FFFFh
    dd 0000FFFFh
    dd 0000FFFFh
    dd 0000FFFFh
    dd 0000FFFFh
    dd 0000FFFFh
    dd 0000FFFFh
    dd 0000FFFFh
    dd 0000FFFFh ;32

    . . . . . . . . . . . . . . . . . . .

    ;-----------------------------------------------------------------
    ; Работа с регистрами ЭЛТ (через порт 3D4h).
    ; Для ViRGE/DX/GX цвет заполнения и цвет контура курсора-стрелки
    ; определяются цветами, установленными в регистрах палитры.
    ; Поэтому цвета заполнения и контура можно сделать любыми.
    ;-----------------------------------------------------------------
    mov dx,3D4h
    mov al,45h
    out dx,al
    short jmp+2 ; или db 0EBh,0
    inc dl
    in al,dx ; не прочитав, не запишете!
    dec dl
    mov ah,FillColor ; цвет заполнения - его номер в палитре из 256-ти цветов
    mov al,4Ah ; номер регистра
    out dx,ax ; запись в регистр
    short jmp+2
    mov al,45h
    out dx,al
    short jmp+2
    inc dl
    in al,dx ; не прочитав, не запишете!
    short jmp+2
    dec dl
    mov ah,BorderColor ; цвет контура - его номер в палитре из 256-ти цветов
    mov al,4Bh ; номер регистра
    out dx,ax ; запись в регистр
    call DrawCursor ; рисуем курсор, см.ниже
    ;--- разрешаем аппаратную генерацию
    mov ax,0E04Dh
    out dx,ax
    short jmp+2
    mov ax,0145h
    out dx,ax
    call MoveCursor ; перемещаем в нужное место экрана, см.ниже
    call ShowCursor ; делаем курсор видимым, см.ниже
    . . . . . . . . . . . . . . . . . . .
    Теперь приведем подпрограммы DrawCursor, MoveCursor и ShowCursor.
    ;---------------------------------------------------
    А. DrawCursor: здесь нужен LFB, его конец
    ;A-- начало -----------------------------------
    mov esi,offset CursorArrow
    mov edi,LinearAddrLFB ;это смещение от базы селектора, загруженного
    ;в сегментные регистры данных, до начала LFB,
    ;т.е. до начала видеопамяти
    add edi,VideoMemSize ;плюс размер видеопамяти
    sub edi,512*64 ;минус размер видео-ПЗУ
    mov ecx,20h ;размер массива CursorArrow
    mov ebx,0000FFFFh ;это просто для экономии (а на самом деле это
    ;так называемая XOR-маска)
    cld
    NEXT:
    lodsd ;загружаем из массива CursorArrow и
    stosd ;пишем в LFB, т.е., фактически, в видеопамять,
    ;в ее конец
    mov eax,ebx
    stosd
    stosd
    stosd
    loop NEXT
    mov ecx,80h
    rep stosd ;ликвидируем черную дырку на экране
    ;A-- конец -----------------------------------


    ;---------------------------------------------------
    ;B. MoveCursor: перемещает курсор в заданную точку экрана.
    ;После генерации курсора достаточно пользоваться только
    ;подпрограммой его перемещения.
    ;B-- начало -----------------------------------
    ; Здесь xMcur, yMcur - обычные экранные координаты курсора (типа WORD)
    ; и опять регистры ЭЛТ.

    mov dx,3D4h
    mov bx,xMcur
    mov al,47h
    mov ah,bl
    out dx,ax
    short jmp+2
    dec al ;=46h
    mov ah,bh
    out dx,ax
    short jmp+2
    mov bx,yMcur
    mov al,49h
    mov ah,bl
    out dx,ax
    short jmp+2
    dec al ;=48h
    mov ah,bh
    out dx,ax
    ;B-- конец -----------------------------------

    ;---------------------------------------------------
    C. ShowCursor: делает курсор видимым опять через регистры ЭЛТ.
    ;С-- начало -----------------------------------
    mov dx,3D4h
    mov ax,004Eh ; значение 3F4Eh сделает курсор невидимым
    out dx,ax
    short jmp+2
    mov ax,004Fh
    out dx,ax ; курсор появился на экране
    ;С-- конец -----------------------------------

    Это все, т.е. далее можно пользоваться только подпрограммой перемещения курсора MoveCursor. Позаботьтесь сами о сохранении регистров там, где это нужно. Курсор вы получите, но на самом деле есть еще нюансы. Так, приведенный выше массив CursorArrow является AND-маской, а есть еще и XOR-маска, значение которой у нас было постоянно и равнялось 0000FFFFh: посмотрите в Windows SDK функцию CreateCursor(). Курсор будет генерироваться независимо от установленного графического режима (конечно, не 16-цветного с битовыми плоскостями). Главное, чтобы режим был с LFB. Существенным недостатком приведенного способа АГК является использование регистров ЭЛТ. Этот недостаток, хотя он и преодолим, становится заметен при установке на ПК нескольких видеоадаптеров, т.к. обращение к регистрам ЭЛТ идет по одному и тому же порту.
    Как уже говорилось, приемы АГК для разных видеосистем (даже одного и того же производителя) могут сильно отличаться. Например, вообще могут не использоваться LFB (что, однако, не означает, что без LFB можно обойтись) и регистры ЭЛТ, да и маски AND и XOR могут выглядеть совсем иначе. Может использоваться не конец, а начало (!) LFB (видеопамяти), так что вывод на экран придется делать не с нулевой видеостраницы, а с первой. Могут использоваться память и порты, найти которые можно только во внутренних конфигурационных регистрах видеоплаты используя мост шины PCI (например, Matrox и наследники). Цвета контура и заливки могут устанавливаться иначе. Например, для видеоплаты Trio/3D/2X (AGP) от той же S3 цвета задаются как 256 оттенков серого. Короче, следует быть готовыми ко всяким неожиданностям. Еще для распознавания видеоплаты нужно создать небольшую подсистему Plug&Play (опять нужен мост, но этот сервис доступен через функцию 0B1h прерывания 1Ah BIOS), а по мере узнавания способов АГК для новых видеоплат нужно будет добавлять все новые функции инициализации и перемещения курсора. Впрочем, последнее не проблема.
    Аппаратный курсор – вещь очень удобная, но при этом желательно написать свой обработчик прерывания от мыши, т.к. загрузка резидентов, например, MOUSE.COM или IMMOUSE.COM с последующими вызовами INT 33h окажется бесполезной. При этом надо еще учесть, что эти резиденты работают в реальном режиме процессора, тогда как ваша программа будет работать в защищенном.Таким образом, объем работ потребуется солидный, но если его выполнить, то результат будет ощутимый.
    Код для АГК оказывается довольно компактным и его вполне можно было бы реализовать, как еще одну подфункцию функции 4Fh для INT 10h, ведь стандарт VBE пока поддерживается, но это не вписывается в драйверную концепцию современных ОС.
    Источники информации по АГК указать нельзя по причине их отсутствия, хотя встречаются описания АГК, например, для видеоплат ATI со ссылкой на исходники драйверов под Linux. В остальных же случаях придется пользоваться Windows+WinIce и, конечно, иметь при этом конкретную видеоплату с ее драйвером. Вместо защищенного режима можно использовать и нереальный, но для полноценной программы он не годится.
    Что касается LFB, то можно посмотреть две замечательные книжки:
    1. Зубков С.В. Assembler для DOS, Windows и Unix.-М: ДМК, 2000.
    2. Кулаков В. Программирование на аппаратном уровне: специальный справочник.
    2-е издание.-СПб.: Питер, 2003.