» Главная
eXcode.ru » Статьи » Assembler
» Новости
» Опросы
» Файлы
» Журнал



Пользователей: 0
Гостей: 8





Работа с LFB в DOS





Осознав своё место в мире, постигнув
единство всего сущего, относительность
добра и зла, человек обретает душевное
равновесие и покой, поколебать который
не в силах никакие бури…

Традиции воинских искусств [КЭМПО]

Наверняка всем кто только начинал программировать на Ассемблере, неизбежно приходилось сталкиваться с проблемой вывода на экран в режимах SVGA. Многие использовали банки видеопамяти или перемещение окна, но есть несколько минусов использования такого подхода:
• Нужно написать довольно большую процедуру для вывода точек на экран
• Переключение банков занимает значительное время. (Особенно заметно на 386-ом с VGA картой :) )
Но есть и плюс: переключение банков видеопамяти можно использовать даже на 286-ом, в то время как для работы LFB нужна видеокарта как минимум поддерживающая спецификацию VESA VBE 2.0 и т.д. и т.п.
Не будем забегать вперёд и разберём всё по порядку…
И так, LFB (Linear Frame Buffer) – линейный кадровый буфер, использующийся для отображения видеопамяти на непрерывный кусок адресного пространства. Для работы с видеорежимами и видеокартой используется соответствующее прерывание BIOS – INT 10. Программировать линейный кадровый буфер мы будем в BIG REAL MODE, так как в реальном режиме LFB не используется, за исключением совсем экзотических случаев. Я предполагаю, что вы немного разбираетесь в защищённом режиме (далее PM), селекторах, дескрипторах и прочей бесовщине, а если нет, тоже не беда… Ведь чтобы использовать электрочайник не обязательно в совершенстве знать его устройство, формулы теплового баланса и т.п. :) Если вы готовы, то начнём-с!

Прерывание INT 10

Прежде всего, нам понадобятся несколько функций для переключения режимов и определения номера версии VBE:
INT 10h АН = 4Fh, AL = 00 — Получить общую SVGA-информацию
Ввод: AX = 4F00h
ES:DI = адрес буфера (512 байт)
Вывод: AL = 4Fh, если функция поддерживается
АН = 01, если произошла ошибка
АН = 00, если данные получены и записаны в буфер

Буфер для общей SVGA-информации:
+00h: 4 байта — будет содержать [VESA] после вызова прерывания, чтобы получить поля, начиная с 14h, здесь надо предварительно записать строку [VBE2]
+04h: слово — номер версии VBE в двоично-десятичном формате (0102h — для 1.2, 0200h — для 2.0)
+06h: 4 байта — адрес строки-идентификатора производителя
+0Ah: 4 байта — флаги:
бит 0 — АЦП поддерживает 8-битные цветовые компоненты (см. подфункцию 08h)
бит 1 — видеоадаптер несовместим с VGA
бит 2 — АЦП можно программировать только при обратном ходе луча
бит 3 — поддерживается спецификация аппаратного ускорения графики VBE/AF 1.0
бит 4 — требуется вызов EnableDirectAccess перед использованием LFB
бит 5 — поддерживается аппаратный указатель мыши
бит 6 — поддерживается аппаратное отсечение
бит 7 — поддерживается аппаратное копирование блоков
биты 8 – 31 зарезервированы
+0Eh: 4 байта — адрес списка номеров поддерживаемых видеорежимов (массив слов, последнее слово = FFFFh, после которого обычно следует список нестандартных режимов, также заканчивающийся словом FFFFh)
+12h: слово — объем видеопамяти в 64-килобайтных блоках
+14h: слово — внутренняя версия данной реализации VBE
+16h: 4 байта — адрес строки с названием производителя
+1Ah: 4 байта — адрес строки с названием видеоадаптера
+1Eh: 4 байта — адрес строки с версией видеоадаптера
+22h: слово — версия VBE/AF (BCD, то есть 0100h для 1.0)
+24h: 4 байта — адрес списка номеров режимов, поддерживающих аппаратное ускорение (если бит поддержки VBE/AF установлен в 1)
+28h: 216 байт — зарезервировано VESA
+100h: 256 байт — зарезервировано для внутренних данных VBE. Так, например, в эту область копируются строки с названиями производителя, видеоадаптера, версии и т.д.

INT 10h АН = 4FH, AL = 02 — Установить режим
Ввод: AX=4F02h
ВХ = номер режима:
биты 0 – 6 — собственно номер режима
бит 7 — видеопамять не очищается при установке режима, если все следующие биты — нули
бит 8 — стандартный VBE SVGA-режим
бит 9 — нестандартный SVGA-режим
биты 10 – 12 — зарезервированы
бит 13 — режим использует аппаратное ускорение
бит 14 — режим использует LFB
бит 15 — видеопамять не очищается при установке режима
Кроме того, специальный номер режима 81FFh соответствует доступу ко всей видеопамяти и может использоваться для сохранения ее содержимого.
Вывод: AL = 4Fh, если функция поддерживается
АН = 00, если режим установлен
АН = 01 или 02, если произошла ошибка

Вот номера всех стандартных режимов (в скобках указан размер требуемой памяти):
4-битные режимы (16 цветов):
VGA
• 012h: 640x480 (64 Кб)
VESA VBE 1.0
• 102h: 800x600 (256 Кб)
• 104h: 1024x768 (192 Кб)
• 106h: 1280x1024 (768 Кб)
Каждый пиксель описывается одним битом, для вывода цветного изображения требуется программирование видеоадаптера на уровне портов ввода-вывода.
8-битные режимы (256 цветов):
VGA
• 013h: 320x200 (64 Кб)
VBE 1.0
• 100h: 640x400 (256 Кб)
• 101h: 640x480 (320 Кб)
• 103h: 800x600 (512 Кб)
• 105h: 1024x768 (768 Кб)
• 107h: 1280x1024 (1,3 Мб)
VBE 2.0
• 120h: 1600x1200 (1,9 Мб)
Каждый пиксель описывается ровно одним байтом. Значение байта — номер цвета из палитры, значения цветов которой можно изменять, например, вызывая подфункцию 09 видеофункции 4Fh.
15-битные режимы (32 К цветов):
VBE 1.2
• 10Dh: 320x200 (128 Кб)
• 110h: 640x480 (768 Кб)
• 113h: 800x600 (1 Мб)
• 116h: 1024x768 (1,5 Мб)
• 119h: 1280x1024 (2,5 Мб)
VBE 2.0
• 121h: 1600x1200 (3,8 Мб)
Каждый пиксель описывается ровно одним словом (16 бит), в котором биты 0 – 4 содержат значение синей компоненты цвета, биты 5 – 9 — зеленой, а биты 10 – 14 — красной. Бит 15 не используется.
16-битные режимы (64 К цветов):
VBE 1.2
• 10Eh: 320x200 (128 Кб)
• 111h: 640x480 (768 Кб)
• 114h: 800x600 (1 Мб)
• 117h: 1024x768 (1,5 Мб)
• 11Ah: 1280x1024 (2,5 Мб)
VBE 2.0
• 121h: 1600x1200 (3,8 Мб)
Так же как и в 15-битных режимах, каждый пиксель описывается ровно одним словом. Обычно биты 0 – 4 (5 бит) содержат значение синей компоненты, биты 5 – 10 (6 бит) — зеленой, а биты 11 – 15 (5 бит) — красной. В нестандартных режимах число бит, отводимое для каждого цвета, может отличаться, так что при их использовании следует вызвать подфункцию 01 видеофункции 4Fh и получить информацию о видеорежиме, включающую битовые маски и битовые смещения для цветов.
24-битные и 32-битные режимы (16 М цветов):
VBE 1.2
• 10Fh: 320x200 (192 Кб)
• 112h: 640x480 (1 Мб)
• 115h: 800x600 (1,4 Мб)
• 118h: 1024x768 (2,3 Мб)
• 11Bh: 1280x1024 (3,7 Мб)
VBE 2.0
• 122h: 1600x1200 (7,7 Мб)
В режимах с 24-битным и 32-битным цветом каждому пикселю на экране соответствуют три байта и одно двойное слово (4 байта). Если видеорежим использует модель памяти 6 (Direct Color), то младший байт (байт 0) содержит значение синего цвета, байт 1 содержит значение зеленого, байт 2 — значение красного, а байт 3 — в 32-битных режимах резервный и используется либо для выравнивания, либо содержит значение для альфа-канала. Некоторые видеорежимы могут использовать не Direct Color, a YUV (модель памяти 7) — здесь младший байт соответствует насыщенности красного, байт 1 — насыщенности синего, а байт 2 — яркости.
INT 10h АН = 4Fh, AL = 01 — Получить информацию о режиме
Ввод: AX = 4F01h
СХ = номер SVGA-режима (бит 14 соответствует использованию LFB, бит 13 — аппаратному ускорению)
ES:DI = адрес буфера для информации о режиме (256 байт)
Вывод: AL = 4Fh, если функция поддерживается
АН = 01, если произошла ошибка
АН = 00, если данные получены и записаны в буфер

Буфер для информации о SVGA-режиме:
+00h: слово — атрибуты режима:
бит 0 — режим присутствует
бит 1 — дополнительная информация (смещения 12h – 1Eh) присутствует (для VBE 2.0 эта информация обязательна и бит всегда установлен)
бит 2 — поддерживается вывод текста на экран средствами BIOS
бит 3 — режим цветной
бит 4 — режим графический
бит 5 — режим несовместим с VGA
бит 6 — переключение банков не поддерживается
бит 7 — LFB не поддерживается
бит 8 — не определен
бит 9 — (для VBE/AF) приложения должны вызвать EnableDirectAccess, прежде чем переключать банки
+02h: байт — атрибуты окна А:
бит 1 — окно существует
бит 2 — чтение из окна разрешено
бит 3 — запись в окно разрешена
+03h: байт — атрибуты окна В
+04h: слово — гранулярность окна — число килобайтов, которому всегда кратен адрес начала окна в видеопамяти (обычно 64)
+06h: слово — размер окна в килобайтах (обычно 64)
+08h: слово — сегментный адрес окна А (обычно A000h)
+0Ah: слово — сегментный адрес окна В
+0Ch: 4 байта — адрес процедуры перемещения окна (аналог подфункции 05h, но выполняется быстрее)
+10h: слово — число целых байт в логической строке
+12h: слово — ширина в пикселях (для графики) или символах (для текста)
+14h: слово — высота в пикселях (для графики) или символах (для текста)
+16h: байт — высота символов в пикселях
+17h: байт — ширина символов в пикселях
+18h: байт — число плоскостей памяти (4 — для 16-цветных режимов, 1 — для обычных, число переключений банков, требуемое для доступа ко всем битам (4 или 8), — для модели памяти 5)
+19h: байт — число бит на пиксель
+1Ah: байт — число банков для режимов, в которых строки группируются в банки (2 — для CGA, 4 — для HGC)
+1Bh: байт — модель памяти:
00h — текст
01h — CGA-графика
02h — HGC-графика
03h — EGA-графика (16 цветов)
04h — VGA-графика (256 цветов в одной плоскости)
05h — Режим X (256 цветов в разных плоскостях)
06h — RGB (15-битные и выше)
07h — YUV
08h – 0Fh — зарезервированы VESA
10h – FFh — нестандартные модели
+1Ch: байт — размер банка в килобайтах (8 — для CGA и HGC, 0 — для остальных)
+1Dh: байт — число видеостраниц
+1Eh: байт — зарезервирован
+1Fh: байт — битовая маска красной компоненты
+20h: байт — первый бит красной компоненты
+21h: байт — битовая маска зеленой компоненты
+22h: байт — первый бит зеленой компоненты
+23h: байт — битовая маска синей компоненты
+24h: байт — первый бит синей компоненты
+25h: байт — битовая маска зарезервированной компоненты
+26h: байт — первый бит зарезервированной компоненты
+27h: байт — дополнительные флаги:
бит 0: —поддерживается перепрограммирование цветов (подфункция 09h)
бит 1 — приложение может использовать биты в зарезервированной компоненте
+28h: 4 байта — физический адрес начала LFB
+2Ch: 4 байта — смещение от начала LFB, указывающее на первый байт после конца участка памяти, отображающейся на экране
+30h: слово — размер памяти в LFB, не отображающейся на экране, в килобайтах
+32h: 206 байт — зарезервировано

Реализация.

И так, мы изучили достаточно, чтобы приступить непосредственно к программированию. Собирать всё будем в TASM 5.0. Как уже было сказано выше, для каждого режима свой алгоритм вывода точки, будем использовать в нашем примере 640X480X32 бита или 112h, но т.к мы используем LFB, то необходимо бит 14, номера режима, установить в 1. Так же неплохо было бы, сделать проверку на наличие VBE 2.0 и выше. И конечно же не нужно забывать о двух дескрипторах: нулевом и 16-бином, лимитом в 4 Гб. Вроде всё. Вот наконец код, который переводит экран в режим 112h, и выводит точку красного цвета:



; LFB.asm
; Простенькая программа, демонстрирующая работу с LFB
; Компиляция:
; tasm.exe /m LFB.asm
; Линк:
; tlink.exe /x /3 LFB.obj

.386p ; 32-битные регистры появились на 386
LFB_seg segment para public "code" use16 ; Наш сегмент
assume CS:LFB_seg,DS:LFB_seg,SS:LFB_seg ; Код, данные, стек
; находятся в одном сегменте
start:

; Этот блок кода отвечает за переход в BIG REAL MODE
; мы не будем на нём подробно останавливаться…

push cs
pop ds
mov eax,cr0
test al,1
jz no_V86
mov dx,offset v86_msg
err_exit:
mov ah,9
int 21h
mov ah,4Ch
int 21h
v86_msg db "Error!Bad mode in v86!$"
win_msg db "Error!Windows is runing!$"
no_V86:
mov ax,1600h
int 2Fh
test al,al
jz no_windows
mov dx,offset win_msg
jmp err_exit
no_windows:
xor eax,eax
mov ax,cs
shl eax,4
add ax,offset GDT
mov gdt_base,eax
lgdt fword ptr gdtr
cli
mov eax,cr0
or al,1
mov cr0,eax
jmp start_PM

start_PM:
mov ax,8
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax

mov eax,cr0
and al,0FEh
mov cr0,eax
jmp exit_PM

exit_PM:
xor ax,ax
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
sti
mov ax,cs
mov ds,ax
; Всё, теперь мы в BIG REAL MODE
; Нам нужны некоторые сегментные регистры
push ds
pop es
; Получаем общую SVGA информацию
mov ax,4F00h
; Сохраняем её в буфере
mov di,offset Video_Buffer
int 10h
; Считываем номер версии VBE в BX
mov bx,word ptr [Video_Buffer+04h]
; Если он ниже чем 2.0
cmp bx,0200h
; Выдать сообщение об ошибке
jl Not_support_LFB
; Иначе переходим далее
jmp Next_step
Not_support_LFB:
mov ah,9
mov dx,offset Error
int 21h
ret
Next_step:

; Получаем информацию о режиме
mov ax,4F01h
mov cx,4112h
mov es:edi,offset Info_Buffer
int 10h
; Записываем физический адрес начала LFB в ESI
mov esi,dword ptr [Info_Buffer+028h]
push esi
; Устанавливаем режим
mov ax,4F02h
mov bx,4112h
int 10h
pop esi
; Теперь выводим точку

mov X_scr,640
mov Pos_X,100
mov Pos_Y,100
mov Cr_Red,255
mov Cr_Blue,0
mov Cr_Green,0
mov Cr_Alpha,0
call pset32bit
; Ожидание нажатия клавиши
mov ah,1
int 21h
; Выход
mov ah,4Ch
int 21h

; Процедура вывода точки на экран

pset32bit proc
pusha
; В общем случае формула выглядит так:
; X_scr * Pos_Y * Количество компонент цвета + Pos_X * Количество компонент цвета

mov eax,Pos_Y
mov ebx,X_scr
imul eax,ebx
imul eax,4
mov ebx,Pos_X
imul ebx,4
add eax,ebx
xor ecx,ecx
xor ebx,ebx
mov cl,Cr_Blue
mov ch,Cr_Green
mov bl,Cr_Red
mov bh,Cr_Alpha
mov byte ptr fs:[esi+eax],cl
inc eax
mov byte ptr fs:[esi+eax],ch
inc eax
mov byte ptr fs:[esi+eax],bl
inc eax
mov byte ptr fs:[esi+eax],bh
popa
ret
pset32bit endp
; Начало области данных

GDT label byte
; Нулевой дескриптор
db 8 dup(0)
; 16-битный 4 Гб сегмент:
db 0FFh,0FFh,0,0,0,10010010b,11001111b,0
; Размер GDT
gdtr dw 16
; Линейный адрес GDT
gdt_base dd ?
Pos_X dd 0 ; Координата X точки
Pos_Y dd 0 ; Координата Y точки
X_scr dd 0 ; Разрешение по X
Cr_Red db 0 ; Красная компонента
Cr_Green db 0 ; Зелёная компонента
Cr_Blue db 0 ; Синяя компонента
Cr_Alpha db 0 ; Альфа
Info_Buffer db 256 dup(0) ; Буфер для информации о режиме
Video_Buffer db 512 dup (0) ; Буфер для общей SVGA информации
Error db "Not support VESA VBE 2.0 or higher!$"
LFB_seg ends
end start

Вот собственно и всё. Если возникнут вопросы по теме, мыльте на Exs42@yandex.ru, я с радостью на них отвечу. Приятного клавишевания.


К началу статьи





Добавил: Exs42Дата публикации: 2006-11-21 23:45:53
Рейтинг статьи:3.27 [Голосов 11]Кол-во просмотров: 11540

Комментарии читателей

Всего комментариев: 2

2006-11-30 00:29:28
Exs42
Почитай книгу Зубкова, там подробно рассказанно о написании дров для дос и винды.

2006-11-29 02:41:22
Che
Круто!!! ТО что я искал. Узнать бы как дрова пишутся. Будет просто супер.!
Ваше имя: *
Текст записи: *
Имя:

Пароль:



Регистрация

Как вы относитесь к рекламе на сайтах.
Отрицательно, терпеть ее не могу!
46% (95)
С пониманием
25% (51)
Пусть будет, если только по делу
15% (32)
Она мне безразлична!
11% (23)
Я ее обожаю!
3% (6)

Проголосовало: 208
Чтобы сообщить о проблеме, возникшей с Вашим компьютером, заполните следующую форму:
1. Опишите вашу проблему:
2. А теперь опишите вашу проблему поточнее:
3. Не забудьте пространно порассуждать о возможных причинах возникновения проблемы: Далее даются варианты ответов. Вам нужно подчеркнуть нужный вариант.
4. Важность проблемы: (незначительная) (незначительная) (незначительная) (обычная)
5. В чем выражается проблема: (зависла) (упала) (рухнула) (странный запах)
6. Ваш компьютер подключен к электросети? (да) (нет)
7. Он включен? (да) (нет)
8. Вы пытались починить его самостоятельно? (да) (нет)
9. И стало еще хуже? (да)
10. Вы просили друга, который знает о компьютерах все, починить ваш компьютер? (да) (нет)
11. И он сделал еще хуже? (да)
12. Вы прочли инструкцию? (да) (нет)
13. Вы уверены, что прочли инструкцию? (может быть) (нет)
14. Вы абсолютно точно уверены что прочли инструкцию? (нет)
15. Если вы прочли инструкцию, вы ее поняли? (да) (нет)
16. Если да, то объясните, почему вы не смогли исправить проблему самостоятельно:
17. Что вы делали с вашим компьютером, когда произошла проблема:
18. Если вы ответили "ничего" тогда объясните, почему компьютер включен:
19. Вы уверены, что не выдумали проблему? (да) (нет)
20. Часы на вашем видеомагнитофоне мигают цифрами 00:00? (да) (что такое видеомагнитофон?)
21. У вас есть книга "ПК для чайников"? (да) (нет)
22. У вас есть независимый свидетель вашей проблемы? (да) (нет)
23. У вас в доме есть электронные устройства, которые работают? (да) (нет)
24. Вы ударили хорошенько по вашему компьютеру? (да) (нет)
25. Ваш компьютер горит? (да) (пока еще нет)
26. Вы можете заняться чем-нибудь еще кроме заполнения данной формы? (да)
Рейтинг: 8.8/10 (9)
Посмотреть все анекдоты