Записать пиксел экрана...
на ассемблере без прерываний и функций
какой-либо ОС?
Как записать(считать)определенный пиксел экрана
на ассемблере без прерываний и функций
какой-либо ОС?
Це все залежить від відеорежиму Якщо ти використовуєш SVGA з LFB буфером тоді початок відеопамяті по замовчуванню буде 0xD00000(це лінійна адреса) і якщо режим 256 колірний то кожен байт відповідає кольором пікселя. Наприклад запис по адресі [0xD00000] байта 0x04 виведе червону крапку в лівому верхньому кутку.(червоний буде якщо не перепрограмовувати палітру)
А якщо ти використовуєш 32 бітний режим (64kb колоьрів), то кожен піксель адресується трьома байтами RGB плюс байт яскравості(байт яскравості не працює, не використовуй його)
Адрес LFB не является статическим, т.е. на разных машинах может быть разным.
Как записать(считать)определенный пиксел экрана
на ассемблере без прерываний и функций
какой-либо ОС?
Основная проблема - определить адрес ;)
Основная проблема - определить адрес ;)
если бы всё было так просто :)
сам то адрес легко получить (lfb) , а вот писать туда будет посложнее .:D
Почему?
koderAlex
Почему?
Йэх... Ну почему ни кто не читает матчасть, а сразу садится если не ОСь, то драйвер писать? :)
Виртуальный/защищенный режим о чем-нить говорит?
Какая разница, какой режим, если video_address уже замэплен и учитывает все страничные и сегментные преобразования? Иначе его было бы очень просто получить, как уже замтил koderAlex, но для мува он бы решительно не подошел ;)
но для мува он бы решительно не подошел ;)
Ага. А почему?
Ага. А почему?
Страничная адресация о чем-нить говорит? :)
Страничная адресация о чем-нить говорит? :)
Ладно, кто в лес, кто по дрова в общем.
Какая разница, какой режим, если video_address уже замэплен и учитывает все страничные и сегментные преобразования? Иначе его было бы очень просто получить, как уже замтил koderAlex, но для мува он бы решительно не подошел ;)
в защищённом режиме надо попросить систему выделить страницу нужного размера и расположенным но полученному ранее физическому адресу . Если система позволит тебе такое ,то по полученному логическому адресу писать mov(s) [].
если же не прошло то есть обходные манёвры ))
например поиск страницы с нужными физическими адресами ,
поднять привилегиии (если надо )) ) и писать туда (напрямую или через VDMA )
P.S. Artem[color=red]ESC[/color]
если же не прошло то есть обходные манёвры ))
например поиск страницы с нужными физическими адресами ,
поднять привилегиии (если надо )) ) и писать туда (напрямую или через VDMA )
Подскажи, а как получить физический адрес видео памяти?
Используем прерывания VESA. Читаем VBE3.pdf .
Используем порты ввода/вывода для работы с PCI
Ищим видео карту читаем BAR регистры ищим с выставленным битом Prefetchable - это и будет виде память
Используем сервисы ОС. Зависит от ОС.
Используем прерывания VESA. Читаем VBE3.pdf .
Используем порты ввода/вывода для работы с PCI
Ищим видео карту читаем BAR регистры ищим с выставленным битом Prefetchable - это и будет виде память
Используем сервисы ОС. Зависит от ОС.
Кинь какой нить докой в меня, начиная с "Ищим видео карту..."
Есть 4-й способ (под винду)
Открываем ДиректХ, получаем первичную поверхность, лочим, это есть виртуальный адрес видео памяти, от него берем линейный
Сейчас у меня именно так работает
Но хочу избавится от директа
_VMI VIDEO_MEMORY_INFORMATION <?>
;Получаем имя девайса
invoke IoGetDeviceInterfaces, offset GUID_DEVINTERFACE_DISPLAY_ADAPTER, 0, DEVICE_INTERFACE_INCLUDE_NONACTIVE, offset pw
invoke RtlInitUnicodeString, offset uDevName, pw
;подучаем DeviceObject по имени девайса
invoke IoGetDeviceObjectPointer, offset uDevName, FILE_READ_DATA, offset FileObject, offset DeviceObject
invoke ExFreePool, pw
;создаем событие
invoke KeInitializeEvent, offset event, NotificationEvent, FALSE
;атачим дивайс
invoke IoGetAttachedDeviceReference, DeviceObject
mov targetObject, eax
;мапируем видеопамять в виртуальную память
invoke IoBuildDeviceIoControlRequest, IOCTL_VIDEO_MAP_VIDEO_MEMORY, targetObject, offset videoMemory, sizeof VIDEO_MEMORY, offset _VMI, sizeof VIDEO_MEMORY_INFORMATION, FALSE, offset event, offset ioStatusBlock
mov _irp, eax
;проверяем
invoke IoCallDriver, targetObject, _irp
.if eax==STATUS_PENDING
invoke KeWaitForSingleObject, offset event, Executive, KernelMode, FALSE, NULL
.endif
;освобождаем дивайс
invoke ObDereferenceObject, targetObject
;в _VMI.FrameBufferBase имеем виртуальный адрес текущего контекста
[quote=ArtemESC]Как записать(считать)определенный пиксел экрана
на ассемблере без прерываний и функций
какой-либо ОС?[/quote]
[size=1]PS. Если автор в течении недели-двух не появится, придется тему закрыть[/size]
в Win32 это невозможно! про linux нечего не могу сказать, наверно тоже невозможно
Можно просто-напросто через порты выставить режим VGA 640x480x16c, а потом уже считывать/записывать пиксели прямо в стандартно отведенную для этого область физической памяти (0xa0000 вроде бы). Если текущий режим - PM+PG, то еще нужно спроецировать эту память на виртуальную.
например в винде это скорее всего BSOD.
Но, похоже, никто не знает, как это делается точно.
Я уже упоминал что из конфигурационного пространства PCI можно узнать. Где описано? Я могу тебя отправить к снадрату PCI.
Код не проверял писал прямо сдесь. Процедура FindDevice3 отлажена. А вот то что ниже даже и не проверял.
;Функция для поиска устройства по его базовому классу
; EAX -его класс.
; На выходи адрес если нет то -1
;***********************************
FindDevice3 proc
PUSH EBX
PUSH ECX
PUSH EDX
MOV EBX, EAX ; Сохраняем
MOV ECX, 80000000h ; Счетчик он же адрес
@@Label1:
AND ECX, 0FFFFFF00h ; Выравниваем
MOV EAX, ECX
MOV DX, 0CF8h
OUT DX, EAX ; Устанавливаем адрес
MOV DX, 0CFCh
IN EAX, DX ; Читаем регистр
CMP EAX, 0FFFFFFFFh ; Не существующее устройство.
JE @@Label2
ADD ECX, 08 ; Наш Регистр
MOV EAX, ECX
MOV DX, 0CF8h
OUT DX, EAX ; Устанавливаем адрес
MOV DX, 0CFCh
IN EAX, DX ; Читаем регистр
SHR EAX, 24 ;
CMP EAX, EBX
JE @@Label3 ; Ура нашли
@@Label2:
ADD ECX, 256
CMP ECX, 80FFFF00h ; Максимум 256 шин.
JNE @@Label1
MOV ECX, 0FFFFFFFFh ; Не нашли
@@Label3:
XOR EAX, EAX ; Сбрасываем адрес
MOV DX, 0CF8h ; Чтобы не было претензий.
OUT DX, EAX ;
AND ECX,0FFFFFF00h ; Сбрасываем индекс регистра
MOV EAX, ECX
POP EDX
POP ECX
POP EBX
RET
endp
start:
mov EAX,03h ; Ищем видео карту её базовому классу.
call FindDevice3
mov EBX, EAX
ADD EBX, 10h ; 10h-28h 6 BAR регистров
MOV ECX, 6
@@Loop:
MOV EAX,EBX
mov DX, 0CF8h
OUT DX,EAX
mov DX, 0CFCh
IN EAX,DX
AND EAX, 1001b ; БИТ 0=0 адрес в памяти, 1 адрес портов в/в
CMP EAX, 1000b ; Бит 3 Prefetchable отличаем видео память от Memory Mapped I/O
JE @@Found
IN EAX,DX
AND EAX, 111b
CMP EAX, 100b ; 64битный адресс
JNE @@Adr32
ADD EBX, 4 ; стандарт, что тут скажешь
@@Adr32:
ADD EBX, 4
DEC ECX
JNZ @@Loop
@@Found:
MOV EAX,EBX
mov DX, 0CF8h
OUT DX,EAX
mov DX, 0CFCh
IN EAX,DX
AND EAX,0FFFFFFF0h ; Пока о 64битных адресах не слово
end start
Спасиб!
Буду пробовать
(терь понятно куда курить)