Помощь - Поиск - Пользователи - Календарь
Полная версия: Графика 24 бит
Форум «Всё о Паскале» > Современный Паскаль и другие языки > Ассемблер > Избранное
Dark
Приветствую вас, тут я буду рассказывать об основах программирования графики 24 бит. Возможно, я также сподвигнусь написать игрушку, пока что - первоначально в планах наподобии King Bounty =) [в 24 битах... круто =) ]
Dark
Введение.

Видеорежимы direct color были введены начиная со стандарта VESA 1.2
Главное отличие этих режимов от режимов VESA 256 цветов - это то, что они не используют палитру. Это избавляет от манипуляций с регистрами видеокарточки, и при добавлении новых рисунков на экран можно не бояться порчи изображения в целом.

Код точки 24 бита занимает 32 бита, кроме базовых цветов (RGB) в него входит пустой байт

Разряды
24-31 16-23 9-15 0-8
-------------------------------------------------------------------------------------------
|резервный| Красный | Зеленый | Синий |
| байт | цвет | цвет | цвет |
-------------------------------------------------------------------------------------------

Стоит напомнить =), что в силу архитектуры Intel двойное слово хранится задом наперед - т.е. 1вым будет синий цвет, и т.д.


Недостатки режима 24 бита:

1. трехбайтный код не обрабатывается командами процессора, поэтому приходиться разбивать на 2 действия - вывод байта и вывод слова.
2. Размер сегмента кратен двойке - поэтому в него не помещается целое количество трехбайтовых точек. У одной из них [первой или последней] будет искажение - т.е. надо проверять сколько до конца сегмента

надеюсь =) понятно...
Dark
Все программы, которые я пишу, я буду писать либо в Turbo Assembler, либо в TP

Первым делом - установка режима.

VESA режимы, котрые нам подходят [24/32 bit]

Код режима Разрешение экрана размер строки(в байтах)

10Fh 320*200 960/1280
112h 640*480 1290/2560
115р 800*600 2400/3200
118h 1024*768 3072/4096
11Bh 1280*1024 3840/5120

Я все время буду работать с режимом 800*600.

Ну начнем мы с информационных функций:

1. Запрос общих данных 4F00h

Входные данные

ES:DI адрес(указатель) массива на 256 байт, который будет заполняться информацией о видеокарте.

Первые 20 байт заполняются следующими данными:

СМЕЩЕНИЕ ПО МАССИВУ РАЗМЕР(байт) ДАННЫЕ

00h 4 'VESA'
04h 2 версия VESA
06h 4 адрес строки фирмы-изготовителя
0Ah 4 СпецСвойства
0Eh 4 Адрес начала списка информации о поддерживаемых режимах
12H 2 Объем памяти видеокарточки (в блоках по 64 Кб)


- Версия VESA, указывается номер версии и ее редакция. Записана в виде 0102 для VESA 1.2
- Строка фирмы-изготовителя. Коды формата ASII, строка заканчивется 0 (стандарт ASIIZ)
- Спецсвойста я описывать не буду, либо опишу потом - они пока что интереса не представляют.
- Признаком конца списка режимов является код 0FFFFh

Анализ Спецсвойст и списка видеорежимов не очень целесообразен.

Остальные байты в резерве.

простейшая програмка, выводящая всю информацию, получаемую этим прерыванием:

;   Тест видеокарты на Vesa Extension
;  
;


   DOSSEG
   .MODEL SMALL
   .STACK 200h
   .DATA

Buffer      db  255 dup(?)

TVesaSig     db 13
      db 10
      db 13
      db 10
      db  'VesaSig: $'

       TVesaVer     db 13
      db 10
      db  'VesaVer: $'

       TOEMStr      db 13
      db 10
      db  'OEMStr: $'

      TCapabilities db 13
      db 10
      db  'Capabilities: $'

       TModeList    db 13
      db 10
      db  'ModeListPtr: $'

       TMemPresent  db 13
      db 10
      db  'MemPresent: $'

VesaSig      db  5 dup(?)
       VesaVer      db  6 dup(?)
       OEMStrSeg    db  5 dup(?)
       OEMStrOfs    db  5 dup(?)
      Capabilities  db  9 dup(?)
       ModeListSeg  db  5 dup(?)
       ModeListOfs  db  5 dup(?)
       MemPresent   db  5 dup(?)
                       
   .CODE

jmp Start

outstr:
mov ah,9
int 21h
retn

wdigtostr:;word digital to string IN: al - dig  OUT: dx - 2 char
 xor dx,dx
 mov dl,al
 shl dx,4
 shr dl,4
 add dx,3030h
 cmp dl,39h
 jle M1     ; BCD + 30 = char or BCD + 37=char [if BCD>09]
 add dl,7
M1:
 cmp dh,39h ; BCD + 30 = char or BCD + 37=char [if BCD>09]
 jle M2
 add dh,7
M2:
retn
 
START:

;получение информации

   mov     ax,seg Buffer
   mov     es,ax        
   mov     di,offset Buffer  
   mov     ax,4f00h    
   int     10h      
   mov     byte ptr es:[di+20],'$'

;преобразование в печатный вид

push ds
   mov     ax,seg  Buffer
   mov     ds,ax
   mov     si,offset Buffer
   mov     ax,seg  VesaSig
   mov     es,ax        
   mov     di,offset VesaSig
   mov     cx,4
   rep     movsb
   mov     byte ptr es:[di],'$'

   mov     di,offset VesaVer
   lodsw
   call    wdigtostr
   mov     byte ptr es:[di+3],dh
   mov     byte ptr es:[di+4],dl
   mov     byte ptr es:[di+2],'.'
   mov     al,ah
   call    wdigtostr
   mov     byte ptr es:[di],dh
   mov     byte ptr es:[di+1],dl
   mov     byte ptr es:[di+5],'$'

   mov     di,offset OEMStrOfs
   lodsw
   call    wdigtostr
   mov     byte ptr es:[di+2],dh
   mov     byte ptr es:[di+3],dl
   mov     al,ah
   call    wdigtostr
   mov     byte ptr es:[di],dh
   mov     byte ptr es:[di+1],dl
   mov     byte ptr es:[di+4],'$'

   mov     di,offset OEMStrSeg
   lodsw
   call    wdigtostr
   mov     byte ptr es:[di+2],dh
   mov     byte ptr es:[di+3],dl
   mov     al,ah
   call    wdigtostr
   mov     byte ptr es:[di],dh
   mov     byte ptr es:[di+1],dl
   mov     byte ptr es:[di+4],'$'

   mov     di,offset Capabilities

   lodsw
   call    wdigtostr
   mov     byte ptr es:[di+6],dh
   mov     byte ptr es:[di+7],dl
   mov     al,ah
   call    wdigtostr
   mov     byte ptr es:[di+4],dh
   mov     byte ptr es:[di+5],dl

   lodsw
   call    wdigtostr
   mov     byte ptr es:[di+2],dh
   mov     byte ptr es:[di+3],dl
   mov     al,ah
   call    wdigtostr
   mov     byte ptr es:[di],dh
   mov     byte ptr es:[di+1],dl
   mov     byte ptr es:[di+8],'$'

   mov     di,offset ModeListOfs
   lodsw
   call    wdigtostr
   mov     byte ptr es:[di+2],dh
   mov     byte ptr es:[di+3],dl
   mov     al,ah
   call    wdigtostr
   mov     byte ptr es:[di],dh
   mov     byte ptr es:[di+1],dl
   mov     byte ptr es:[di+4],'$'

   mov     di,offset ModeListSeg
   lodsw
   call    wdigtostr
   mov     byte ptr es:[di+2],dh
   mov     byte ptr es:[di+3],dl
   mov     al,ah
   call    wdigtostr
   mov     byte ptr es:[di],dh
   mov     byte ptr es:[di+1],dl
   mov     byte ptr es:[di+4],'$'

   mov     di,offset MemPresent
   lodsw
   call    wdigtostr
   mov     byte ptr es:[di+2],dh
   mov     byte ptr es:[di+3],dl
   mov     al,ah
   call    wdigtostr
   mov     byte ptr es:[di],dh
   mov     byte ptr es:[di+1],dl
   mov     byte ptr es:[di+4],'$'


   mov     dx,offset Buffer
   call    outstr

   mov     dx,offset TVesaSig
   call    outstr

   mov     dx,offset VesaSig
   call    outstr

   mov     dx,offset TVesaVer
   call    outstr

   mov     dx,offset VesaVer
   call    outstr

   mov     dx,offset TOEMStr
   call    outstr

   mov     dx,offset OEMStrSeg
   call    outstr

   mov ah,2
   mov dl,':'
   int 21h

   mov     dx,offset OEMStrOfs
   call    outstr

   mov     dx,offset TCapabilities
   call    outstr

   mov     dx,offset Capabilities
   call    outstr

   mov     dx,offset TModeList
   call    outstr

   mov     dx,offset ModeListSeg
   call    outstr

   mov ah,2
   mov dl,':'
   int 21h

   mov     dx,offset ModeListOfs
   call    outstr

   mov     dx,offset TMemPresent
   call    outstr

   mov     dx,offset MemPresent
   call    outstr

pop ds
   mov     ax,4c00h    
   int     21h        

END START



Обратите внимание - первая строка - в виде билеберды потому что функции BIOS и DOS работают ТОЛЬКО с ASCII строками, поэтому мне пришлось написать дополнительно функцию, преобразующую слово в BCD слово, а затем BCD слово в символ. Если кто то знает более легкий путь, пусть сообщит сюда, мне.

Следующая фаза - получение информации о режиме.
О ней в другом выпуске.

Мне интересны любые вопросы и коментарии, которые вы можете предложить.
|Пытался запихнуть в архив - не удалось, форум не хочет его грузить =( попытаюсь ночью
FreeMan
Неоптимально.... Посмотреть хотя бы на то, что везде через es работа. Это, вроде, + такт и + байт(не проверял). надо через ds. А так не присматривался. Посмотрю, тогда напишу больше.
Dark
Если бы пригляделся - увидел бы что ds используется одновременно с es

или ты про что то другое?
FreeMan
Так блин я ж и говорю. замени lodsw, поставь через es, а всё остальное через ds imho будет оптимальнее + у тебя она что в tiny не влазит? пихай все переменные в секцию кода.
используй неиспользуемую часть переменной buffer.
Dark
smile.gif просто разные подходы к программированию

Я ж не учу оптимизированности... Хотя, ты прав, она не помешает

Но иногда - оптимизированность мешает пониманию...
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.