Рисование пикселей в графическом режиме VESA - PullRequest
0 голосов
/ 26 мая 2018

Как нарисовать пиксель в графическом режиме VESA?

Я пытаюсь прервать 10h функцию 0ch, но она не работает.Что не так?

(Примечание: я написал этот код в синтаксисе NASM и протестировал его с помощью qemu)

; Code:
Mov ax, 4F02h
Mov bx, 0105h ; 1024x768 pixels
Int 10h

Mov ah, 0ch ; Draw pixel function
Mov cx, 2           ; column
Mov dx, 3           ; row
Mov bh, 0    
Mov bl, 00000101b   ; colour
Int 10h

Jmp $            ; jump forever
Times 510-($-$$) db 0
Dw 0xaa55

1 Ответ

0 голосов
/ 26 мая 2018

Функция Int 10h / AH = 0Ch должна работать даже при использовании режима VESA VBE.

Убедитесь, что используете его правильно, цвет пикселя переходит в al.

;Set video mode
mov ax, 4f02h
mov bx, 105h
int 10h

;Draw pixel
mov ax, 0c09h    ;09h = Blue
mov cx, 2 
mov dx, 3     
xor bx, bx   
int 10h

Технически, вы должны использовать Int 10h / AX = 4F01h для полученияинформация о режиме видео, включая бит 2 (поддерживается 2 выход BIOS ) поля атрибуты режима , чтобы проверить, будут ли работать функции BIOS.

Запись изображения с высоким разрешением с использованием функции BIOS может быть слишком медленной, возможно, стоит инвестировать в запись непосредственно в линейный или оконный буфер кадров.
Запись в линейный кадровый буфер, вероятно, потребует использования Нереальный режим , этого можно избежать, используя оконный кадровый буфер.
Это, помимо того, что медленнее, также более громоздко.

Вот очень простая программа, которая заполняет 30 строк ужасным оттенком серого.
Обратите внимание , что я снял все проверки ради компактности и ясности, которые я сделал много предположений, чтобы избежать математики.
Это плохая практика, я использовал ее только для прототипирования .
Я настоятельно рекомендую вам прочитать всю возвращенную информациюInt 10h/AX=4F01h и используйте эту информацию, чтобы выбрать правильное окно, выполнить правильное заполнение и вычисления.

BITS 16

ORG 100h

mov ax, ds
mov es, ax 

;Set video mode
mov ax, 4f02h
mov bx, 105h
int 10h

;Get video mode info
mov ax, 4f01h
mov cx, 105h
mov di, modeInfo 
int 10h

;Assume first window is valid 
mov ax, WORD [es:modeInfo + 08h]
mov es, ax

;Example of how to change the window 
mov ax, 4f05h
xor bx, bx
mov dx, 5       ;This is granularity units
int 10h

xor di, di 
mov al, 0f1h
mov cx, 3*1024*20

rep stosb

;Wait for key
xor ax, ax
int 16h

;Restore DOS text mode
mov ax, 0003h
int 10h

;Exit
mov ax, 4c00h
int 21h

modeInfo    TIMES 256 db 0

Это в синтаксисе NASM, я обычно использую TASM (вне привязанности) для программ DOS, но этокогда я спешил.
Результат -

A grey band in the, more or less, middle of a black screen

Помните, что, как правило, каждая развертка может быть дополнена (размерscanline возвращается в информации о режиме видео).
Для линии сканирования шириной 1024 пикселя с 3x8bpp у нас есть 3072 байта / линия сканирования, так как это делится на 4, заполнение вероятно не произойдет.
Окно начала адресаs задается в единице гранулярности (также содержится в информации о режиме видео), общий кадровый буфер составляет 1024x768x3 байта = 2,25 МБ, при условии отсутствия заполнения.
Размер окна также находится в информации о режиме видео.

Всего этого достаточно для записи в кадровый буфер.
Линейный кадровый буфер легче обрабатывать (заполнение - это еще один аспект, который необходимо учитывать) после установки нереального режима.

...