Obsah
1. Standardní grafické režimy karty VGA
2. Grafický režim 12H s rozlišením 640×480 pixelů se 16 barvami
3. Grafický režim 13H s rozlišením 320×200 pixelů s 256 barvami
4. Tabulka se všemi standardními grafickými režimy podporovanými BIOSem
5. Všechny standardní grafické režimy z pohledu programátora
6. První demonstrační příklad: přepnutí do režimu 12H a vykreslení vzorků na obrazovku
7. Druhý demonstrační příklad: vyplnění obrazovky v režimu 13H
8. Barvová paleta v režimu 12H (640×480)
9. Třetí demonstrační příklad: změna celé barvové palety v režimu 12H
10. DAC – číslicově-analogový převodník
11. Dvojí mapování barev v režimu 12H
12. Korektní změna zobrazení barev v režimu 12H
13. Demonstrační příklad: korektní změna zobrazení barev
14. Vykreslení jednotlivých pixelů v režimu 12H
15. Demonstrační příklad: vykreslení pixelů v režimu 12H
16. Vykreslení jednotlivých pixelů v režimu 13H: krátká nebo rychlá varianta?
17. Demonstrační příklad: vykreslení pixelů s využitím operace aritmetických posunů (bez násobení)
18. Dnešní poslední demonstrační příklad: náhrada násobení za vyhledávací tabulku
19. Repositář s demonstračními příklady
1. Standardní i nestandardní grafické režimy karty VGA
V předchozím článku jsme si řekli, že grafická karta VGA je zpětně kompatibilní s kartami MDA, CGA i EGA. Týká se to samozřejmě i grafických režimů, což znamená, že řídicí registry karty VGA umožňovaly takové nastavení, které vedlo k emulaci všech grafických režimů nabízených kartami CGA i EGA, samozřejmě včetně struktury video paměti (režim sudá/lichá u karty CGA, bitové roviny karty EGA, 64barevná paleta této karty atd.).
Navíc je možné pomocí služeb VGA BIOSu nastavit dva nové standardní grafické režimy, které budou popsány v navazujících kapitolách. I přes tyto stejné znaky však karta VGA používala odlišný konektor pro připojení monitorů i odlišné signály. Například barvonosné signály již byly analogové, což konektoru VGA umožnilo „přežít“ až do dnešní doby.
Obrázek 1: Klasický dungeon Ishar využívající grafický režim s rozlišením 320×200 pixelů a 256 barev.
Obrázek 2: Slavná hra Master of Orion (první a podle mého názoru nejlepší díl) taktéž využívá režim 320×200×256.
2. Grafický režim 12H s rozlišením 640×480 pixelů se 16 barvami
První z oficiálně podporovaných grafických režimů karty VGA nabízí rozlišení 640×480 pixelů při možnosti zobrazení maximálně šestnácti barev. V podstatě se jedná o rozšíření grafického režimu karty EGA s rozlišením 640×350 pixelů, protože „pouze“ došlo ke zvýšení vertikálního rozlišení, které je umožněno vyššími frekvencemi krystalů, které generují jak oba synchronizační signály (horizontální i vertikální), tak i hodinový signál použitý při přístupu do obrazové paměti (pixel clock), který je v případě tohoto režimu roven 25,175 MHz.
Obrázek 3: Mnoho aplikací i některé hry využívaly šestnáctibarevný režim s rozlišením 640×480 pixelů. Například Incredible Machines (ve skutečnosti byl u této hry režim částečně modifikován, takže neměl přesně 480 obrazových řádků, ovšem základem je standardní BIOSovský režim).
Podobně jako u karty EGA, i v grafickém režimu VGA 640×480×16 je obrazová paměť rozdělena do čtyř bitových rovin mapovaných z hlediska mikroprocesoru (přesněji řečeno mikroprocesoru běžícího v reálném režimu) do segmentu 0×a000:0000 až 0×a000:ffff. Čtení či zápis dat do bitových rovin není prováděn přímo, protože mezi mikroprocesor a obrazovou paměť jsou vloženy takzvané záchytné registry (latch) řízené pomocí několika konfiguračních registrů.
Obrázek 4: Další hra pracující v režimu 640×480×16 (zde bylo vertikální rozlišení sníženo úpravou HW registrů VGA).
Existuje několik navzájem odlišných režimů práce těchto registrů, z nichž pravděpodobně nejpoužívanějším režimem je čtení či zápis dat vždy pouze do jedné bitové roviny. Při zápisu je však možné data současně zapisovat do libovolné kombinace bitových rovin, takže například vymazání obrazovky lze v praxi provést pouze zápisem 640×480/8=38400 bajtů (zápis do všech čtyř bitových rovin současně) namísto skutečně přemazaných 640×480/2=153600 bajtů. Tento grafický režim má ještě jedno prvenství – jedná se o první oficiální grafický režim počítačů IBM PC, jehož pixely měly čtvercový tvar, což umožnilo zjednodušit některé algoritmy (například vykreslení kružnice Bresenhamovým algoritmem není nutné modifikovat s ohledem na nečtvercové pixely).
Obrázek 5: Do třetice grafický režim 640×480×16 – hra Warlords II (pozdější vydaná verze Warlords II Deluxe již do jisté míry podporovala grafické karty SVGA a 256 barev).
3. Grafický režim 13H s rozlišením 320×200 pixelů s 256 barvami
Druhý standardní grafický režim karty VGA, který je známý též pod jménem „mód 13H“ nabízel programátorům i uživatelům rozlišení 320×200 pixelů, ovšem počet současně zobrazitelných barev byl roven 256 z celkového počtu 218=262144 dostupných barevných odstínů. Tento grafický režim vznikl zvláštním „ohnutím“ HW karty VGA, konkrétně takzvaným zřetězením (chaining) všech čtyř bitových rovin tak, že barva prvního pixelu (osm bitů) je zapsána do první bitové roviny (první bajt), barva druhého pixelu do druhé roviny (druhý bajt), třetí pixel (překvapivě) do třetí bitové roviny, čtvrtý pixel do poslední bitové roviny, barva pátého pixelu opět do první roviny (pátý bajt) atd. – viz též obrázek číslo 6, na kterém je naznačena jak kombinace bitových rovin, tak i metoda zobrazení pixelů na obrazovce.
Obrázek 6: Struktura obrazové paměti v grafickém režimu 13H.
Z pohledu programátora však zřetězení znamenalo, že pixely byly uloženy lineárně za sebou, což je ten nejjednodušší způsob organizace obrazové paměti (framebufferu), kterému lze velmi snadno porozumět a používat. Při zřetězení bitových rovin je totiž sice celých 75% obrazové paměti nevyužito, protože v každé bitové rovině je adresovatelný vždy každý čtvrtý bajt, ale z hlediska procesoru se celá obrazová paměť jeví jako pole 320×200=64000 bajtů, přičemž každý bajt představuje index barvy jednoho pixelu – v reálném režimu procesoru 80×86 si snad nelze představit jednodušší strukturu obrazové paměti :-), takže není divu, že se tento grafický režim stal velmi populární.
Obrázek 7: DOSová varianta slavné hry Civilizace taktéž dokáže využívat režim 320×200×256 (popř. i jen 16 barev na starších systémech).
Obrázek 8: Další screenshot slavné hry Civilizace.
4. Tabulka se všemi standardními grafickými režimy podporovanými BIOSem
Nyní si již můžeme doplnit tabulku se standardními textovými a grafickými režimy podporovanými BIOSem o další režimy karty VGA. Jedná se o finální verzi tabulky, protože se vznikem SVGA již firma IBM neměla takovou pozici, aby byly nové režimy zavedeny do standardního BIOSu a navíc byla diverzita nových režimů příliš velká a vývoj poměrně rychlý na standardizaci (víc viz v samostatném článku):
Číslo (AL) | Karty | Monitory | Typ | Rozlišení | Barvy | Segment | |
---|---|---|---|---|---|---|---|
00 | CGA, EGA | kompozitní | text | 40×25 | mono, 16 barev | 0×b800 | |
01 | CGA, EGA | kompozitní, RGBI, EGA | text | 40×25 | mono, 16 barev | 0×b800 | |
02 | CGA, EGA | kompozitní | text | 80×25 | mono, 16 barev | 0×b800 | |
03 | CGA, EGA | kompozitní, RGBI, EGA | text | 80×25 | mono, 16 barev | 0×b800 | |
04 | CGA, EGA | kompozitní, RGBI, EGA | grafika | 320×200 | 4 | 0×b800 | |
05 | CGA, EGA | kompozitní | grafika | 320×200 | 4 | 0×b800 | |
06 | CGA, EGA | kompozitní, RGBI, EGA | grafika | 640×200 | 2 | 0×b800 | |
07 | MDA, EGA | TTL mono (MDA) | text | 80×25 | mono+intenzita | 0×b000 | |
N/A | Hercules | TTL mono (MDA) | grafika | 720×348 | mono | 0×b000 nebo 0×b800 | |
0d | EGA | EGA | grafika | 320×200 | 16 | 0×a000 | |
0e | EGA | EGA | grafika | 640×200 | 16 | 0×a000 | |
0f | EGA | TTL mono (MDA), EGA | grafika | 640×350 | 3 (BW) | 0×a000 | |
10 | EGA | EGA | grafika | 640×350 | 4 nebo 16 | 0×a000 | |
11 | VGA | VGA (analog) | grafika | 640×480 | 2 | 0×a000 | |
12 | VGA | VGA (analog) | grafika | 640×480 | 16 | 0×a000 | |
13 | VGA | VGA (analog) | grafika | 320×200 | 256 | 0×a000 |
5. Všechny standardní grafické režimy z pohledu programátora
Na všechny grafické režimy podporované BIOSem (+ režim Herculesu) se můžeme podívat i z pohledu programátora. Zajímat nás bude začátek obrazové paměti (segment), způsob prokládání obrazových řádků, formát pixelů (zda jsou hodnoty uloženy v po sobě jdoucích bitech, nebo „kolmo“ v bitových rovinách), počet bitových rovin a taktéž to, zda jsou bitové roviny zřetězeny či nikoli:
# | Číslo (AL) | Karty | Rozlišení | Barvy | Segment | Prokládání řádků | Formát pixelů | Bitových rovin | Zřetězení |
---|---|---|---|---|---|---|---|---|---|
1 | 04 | CGA, EGA | 320×200 | 4 | 0×b800 | 2:1 | packed | 1 | ne |
2 | 05 | CGA, EGA | 320×200 | 4 | 0×b800 | 2:1 | packed | 1 | ne |
3 | 06 | CGA, EGA | 640×200 | 2 | 0×b800 | 2:1 | packed | 1 | ne |
4 | N/A | Hercules | 720×348 | mono | 0×b000 nebo 0×b800 | 4:1 | packed | 1 | ne |
5 | 0d | EGA | 320×200 | 16 | 0×a000 | 1:1 | planar | 4 | ne |
6 | 0e | EGA | 640×200 | 16 | 0×a000 | 1:1 | planar | 4 | ne |
7 | 0f | EGA | 640×350 | 3 (BW) | 0×a000 | 1:1 | planar | 2 | ne |
8 | 10 | EGA | 640×350 | 4 nebo 16 | 0×a000 | 1:1 | planar | 2 nebo 4 | ne |
9 | 11 | VGA | 640×480 | 2 | 0×a000 | 1:1 | planar | 1 | ne |
10 | 12 | VGA | 640×480 | 16 | 0×a000 | 1:1 | planar | 4 | ne |
11 | 13 | VGA | 320×200 | 256 | 0×a000 | 1:1 | packed | 4 | ano |
6. První demonstrační příklad: přepnutí do režimu 12H a vykreslení vzorků na obrazovku
Dnešní první demonstrační příklad ukazuje základní způsob použití režimu 640×480 se šestnácti barvami. Tento režim se ovládá naprosto stejně jako režim 640×350×16 karty EGA, pouze se zvýšil počet obrazových řádek a obsazená kapacita každé bitové roviny je rovna 38400 bajtům.
Obrázek 9: Výsledek běhu prvního demonstračního příkladu.
Úplný zdrojový kód prvního demonstračního příkladu:
; Graficky rezim karty VGA s rozlisenim 640x480 pixelu. ; ; preklad pomoci: ; nasm -f bin -o vga.com vga_gfx_mode_640x480.asm ; ; nebo pouze: ; nasm -o vga.com vga_gfx_mode_640x480.asm ;----------------------------------------------------------------------------- ; ukonceni procesu a navrat do DOSu %macro exit 0 mov ah, 0x4c int 0x21 %endmacro ; vyprazdneni bufferu klavesnice a cekani na klavesu %macro wait_key 0 xor ax, ax int 0x16 %endmacro ; nastaveni grafickeho rezimu %macro gfx_mode 1 mov ah, 0 mov al, %1 int 0x10 %endmacro ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: gfx_mode 0x12 ; nastaveni rezimu 640x480 se sestnacti barvami mov ax, 0xa000 ; video RAM v textovem rezimu mov es, ax mov di, 0 ; nyni ES:DI obsahuje adresu prvniho pixelu ve video RAM mov cx, 640*480/8 ; pocet zapisovanych pixelu (ovsem pocitano v bajtech) mov al, 0 ; kod pixelu opak: stosb ; zapis vzorku inc al ; dalsi pixel loop opak ; opakujeme CX-krat wait_key ; cekani na klavesu exit ; navrat do DOSu
7. Druhý demonstrační příklad: vyplnění obrazovky v režimu 13H
V režimu 13H je vše snadné díky linearitě obrazové paměti a faktu, že každý pixel je uložen přesně v jednom bajtu. Vyplnění 320×200=64000 pixelů různými barvami lze tedy realizovat například takto:
mov ax, 0xa000 ; video RAM v textovem rezimu mov es, ax mov di, 0 ; nyni ES:DI obsahuje adresu prvniho pixelu ve video RAM mov cx, 320*200 ; pocet zapisovanych pixelu (pixel==bajt) mov al, 0 ; kod pixelu opak: stosb ; zapis barvy pixelu inc al ; dalsi pixel loop opak ; opakujeme CX-krat
Obrázek 10: Výsledek běhu druhého demonstračního příkladu.
Úplný zdrojový kód druhého demonstračního příkladu vypadá následovně:
; Graficky rezim karty VGA s rozlisenim 320x200 pixelu. ; ; preklad pomoci: ; nasm -f bin -o vga.com vga_gfx_mode_320x200.asm ; ; nebo pouze: ; nasm -o vga.com vga_gfx_mode_320x200.asm ;----------------------------------------------------------------------------- ; ukonceni procesu a navrat do DOSu %macro exit 0 mov ah, 0x4c int 0x21 %endmacro ; vyprazdneni bufferu klavesnice a cekani na klavesu %macro wait_key 0 xor ax, ax int 0x16 %endmacro ; nastaveni grafickeho rezimu %macro gfx_mode 1 mov ah, 0 mov al, %1 int 0x10 %endmacro ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: gfx_mode 0x13 ; nastaveni rezimu 320x200 s 256 barvami mov ax, 0xa000 ; video RAM v textovem rezimu mov es, ax mov di, 0 ; nyni ES:DI obsahuje adresu prvniho pixelu ve video RAM mov cx, 320*200 ; pocet zapisovanych pixelu (pixel==bajt) mov al, 0 ; kod pixelu opak: stosb ; zapis barvy pixelu inc al ; dalsi pixel loop opak ; opakujeme CX-krat wait_key ; cekani na klavesu exit ; navrat do DOSu
8. Barvová paleta v režimu 12H (640×480)
Grafická karta VGA sice podporuje 262144 barvových odstínů, ovšem na druhou stranu zachovává kompatibilitu s kartou EGA, která nabízela 64 barvových odstínů. To je patrné i z toho, jak se nastavuje barvová paleta v režimu 12H, tedy v režimu s rozlišením 640×480 pixelů se 16 barvami. Tento grafický režim je totiž do značné míry považován za pouhé „vylepšení“ EGA režimu 640×200 nebo 640×350 pixelů, taktéž se 16 barvami.
Pokusme se tedy o změnu barvové palety s využitím původní funkce EGA BIOSu, který akceptoval barvy ze škály 64 barvových odstínů:
Obrázek 11: Barevné pruhy před změnou barvové palety.
Obrázek 12: Barevné pruhy po změně barvové palety.
Použijeme funkci 0×10 a podfunkci 0×02 EGA/VGA BIOSu, které předáme tabulku s barvami:
mov ax, cs mov es, ax mov dx, palette ; ES:BX obsahuje adresu barvove palety mov ax, 0x1002 ; cislo sluzby a podsluzby BIOSu int 0x10 ; volani sluzby BIOSu
Samotná tabulka obsahuje 17 barev (16 barev pro kreslení, navíc včetně barvy okrajů obrazovky), přičemž každá barvová složka R, G, B je uložena ve dvou bitech (povolení 1/3 intenzity a povolení 2/3 intenzity dané složky):
palette: ; barvova paleta i s barvou okraje db 0b000000 ; cerna (pozadi) db 0b111000 ; tmave seda db 0b000111 ; svetle seda db 0b111111 ; bila db 0b010000 ; tmave zelena db 0b000010 ; stredne zelena db 0b010010 ; svetle zelena db 0b100000 ; tmave cervena db 0b000100 ; stredne cervena db 0b100100 ; svetle cervena db 0b001000 ; tmave modra db 0b000001 ; stredne modra db 0b001001 ; svetle modra db 0b110000 ; tmave hneda db 0b000110 ; svetle hneda db 0b110110 ; zluta db 0b111111 ; okraj
9. Třetí demonstrační příklad: změna celé barvové palety v režimu 12H
Úplný zdrojový kód demonstračního příkladu popsaného v předchozí kapitole vypadá následovně:
; Graficky rezim karty VGA s rozlisenim 640x480 pixelu. ; Zmena barvovych rovin, do kterych se zapisuje. ; Konfigurace barvove palety jedinym volanim prislusne sluzby. ; ; preklad pomoci: ; nasm -f bin -o vga.com vga_palette_4.asm ; ; nebo pouze: ; nasm -o vga.com vga_palette_4.asm ;----------------------------------------------------------------------------- ; registry karty EGA/VGA ega_controller equ 0x3c4 bitplane_selector equ 0x02 ; ukonceni procesu a navrat do DOSu %macro exit 0 mov ah, 0x4c int 0x21 %endmacro ; vyprazdneni bufferu klavesnice a cekani na klavesu %macro wait_key 0 xor ax, ax int 0x16 %endmacro ; nastaveni grafickeho rezimu %macro gfx_mode 1 mov ah, 0 mov al, %1 int 0x10 %endmacro ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: gfx_mode 0x12 ; nastaveni rezimu 640x480 se sestnacti barvami mov ax, 0xa000 ; video RAM v textovem rezimu mov es, ax xor di, di ; nyni ES:DI obsahuje adresu prvniho pixelu ve video RAM xor al, al ; maska bitovych rovin mov cl, 16 ; pocitadlo barevnych pruhu opak: call draw_block_into_bitplanes loop opak wait_key ; cekani na klavesu mov ax, cs mov es, ax mov dx, palette ; ES:BX obsahuje adresu barvove palety mov ax, 0x1002 ; cislo sluzby a podsluzby BIOSu int 0x10 ; volani sluzby BIOSu wait_key ; cekani na klavesu exit ; navrat do DOSu palette: ; barvova paleta i s barvou okraje db 0b000000 ; cerna (pozadi) db 0b111000 ; tmave seda db 0b000111 ; svetle seda db 0b111111 ; bila db 0b010000 ; tmave zelena db 0b000010 ; stredne zelena db 0b010010 ; svetle zelena db 0b100000 ; tmave cervena db 0b000100 ; stredne cervena db 0b100100 ; svetle cervena db 0b001000 ; tmave modra db 0b000001 ; stredne modra db 0b001001 ; svetle modra db 0b110000 ; tmave hneda db 0b000110 ; svetle hneda db 0b110110 ; zluta db 0b111111 ; okraj select_bitplane: mov dx, ega_controller mov ah, bitplane_selector xchg ah, al out dx, ax ; vyber registru sekvenceru ; a zapis masky bitovych rovin ret ; hotovo draw_block_into_bitplanes: push ax push cx call select_bitplane; maska bitovych rovin call draw_block add di, 640*4/8 ; posun o nekolik radku nize pop cx pop ax inc al ; zmena masky ret ; hotovo draw_block: mov cx, 640*12/4 ; pocet zapisovanych pixelu (ovsem pocitano v bajtech) mov al, 0xff ; kod pixelu rep stosb ret
10. DAC – číslicově-analogový převodník
Grafická karta VGA na výstupu (tedy pravděpodobně ještě před výstupními zesilovači) obsahuje obvod DAC neboli číslicově-analogový převodník. Signály R, G, B, které jsou posílány do monitoru, jsou totiž na VGA analogové, což umožnilo i s využitím konektoru s relativně malým počtem pinů (DE-15) posílat informace o 262144 barvových odstínech a později i plné true color (samozřejmě je ale signál zašumněn, frekvenčně omezen atd., takže například na 48bitovou barvovou hloubku a rozlišení QUXGA spíše zapomeňme).
DAC interně obsahuje paměť s organizací 256×18 bitů. Na vstupu je tedy osmibitová hodnota (adresa), na výstupu pak 18 bitů – pro každou barvovou složku 6 bitů. Z toho plyne právě oněch 262144 barvových odstínů: 26×26×26=218=262144. Přeprogramováním této paměti je tedy možné zajistit toho, že VGA monitor zobrazí libovolnou barvu z této škály.
DAC lze naprogramovat buď přes příslušné HW porty, nebo jednodušeji přes BIOS, konkrétně službou 0×10, podslužbou 0×10:
mov ax, 0x1010 ; služba a podslužba VGA BIOSu mov ch, xxx ; hodnota zelené složky 0..63 mov cl, xxx ; hodnota modré složky 0..63 mov dh, xxx ; hodnota zelené složky 0..63 int 0x10 ; modifikace mapovani v DAC
11. Dvojí mapování barev v režimu 12H
V 16barevných režimech se interně provádí dvojí mapování barvy. Index barvy (0..15) je převeden nám již známým způsobem na šestibitovou hodnotu. A tato hodnota vstupuje do DAC, kde je přemapována na jednu barvu z 262144 odstínů. To znamená, že pouhé přeprogramování DAC beze změny palety nedá na výstupu očekávaný výsledek.
Pokusme se například změnit konfiguraci tak, aby se zobrazilo 16 pruhů ve stupních šedi. Pokud pouze změníme DAC (všechny tři složky budou totožné a budou růst od 0 do 63), bude výsledek následující:
Obrázek 13: Pruhy s výchozím nastavením VGA.
Obrázek 14: Výsledek pokusu o zobrazení pruhů ve stupních šedi.
Problém spočívá v tom, že například změna barvy na indexu 10 v DAC nemění barvu číslo 10 v obrázku. Protože tato barva je přemapována jinam ještě před vstupem do DAC.
Příklad, který vykreslil obrázky 13 a 14, vypadá následovně:
; Graficky rezim karty VGA s rozlisenim 640x480 pixelu. ; Zmena barvovych rovin, do kterych se zapisuje. ; Zmena hodnot ulozenych v DAC. ; ; preklad pomoci: ; nasm -f bin -o vga.com vga_gfx_mode_dac_1.asm ; ; nebo pouze: ; nasm -o vga.com vga_gfx_mode_dac_1.asm ;----------------------------------------------------------------------------- ; registry karty EGA/VGA ega_controller equ 0x3c4 bitplane_selector equ 0x02 ; ukonceni procesu a navrat do DOSu %macro exit 0 mov ah, 0x4c int 0x21 %endmacro ; vyprazdneni bufferu klavesnice a cekani na klavesu %macro wait_key 0 xor ax, ax int 0x16 %endmacro ; nastaveni grafickeho rezimu %macro gfx_mode 1 mov ah, 0 mov al, %1 int 0x10 %endmacro ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: gfx_mode 0x12 ; nastaveni rezimu 640x480 se sestnacti barvami mov ax, 0xa000 ; video RAM v textovem rezimu mov es, ax xor di, di ; nyni ES:DI obsahuje adresu prvniho pixelu ve video RAM xor al, al ; maska bitovych rovin mov cl, 16 ; pocitadlo barevnych pruhu opak: call draw_block_into_bitplanes loop opak wait_key ; cekani na klavesu xor bx, bx ; index barvy v DAC mov ax, 0x1010 next_dac: mov ch, bl shl ch, 1 shl ch, 1 ; index (0-15)*4 -> 0..60 mov cl, ch ; nastavit i ostatni slozky mov dh, ch ; nastavit i ostatni slozky int 0x10 ; modifikace mapovani v DAC inc bl ; zvysit index v DAC cmp bl, 16 jnz next_dac wait_key ; cekani na klavesu exit ; navrat do DOSu select_bitplane: mov dx, ega_controller mov ah, bitplane_selector xchg ah, al out dx, ax ; vyber registru sekvenceru ; a zapis masky bitovych rovin ret ; hotovo draw_block_into_bitplanes: push ax push cx call select_bitplane; maska bitovych rovin call draw_block add di, 640*4/8 ; posun o nekolik radku nize pop cx pop ax inc al ; zmena masky ret ; hotovo draw_block: mov cx, 640*12/4 ; pocet zapisovanych pixelu (ovsem pocitano v bajtech) mov al, 0xff ; kod pixelu rep stosb ret
12. Korektní změna zobrazení barev v režimu 12H
Dvojímu mapování barev, které způsobilo výše zmíněné problémy, lze zamezit buď konfigurací VGA nebo úpravou barvové palety (16 barev) tak, aby obsahovala barvy zakódované ho hodnot 0b000000 až 0b001111, a to bez ohledu na to, jak tato barva vypadá na EGA – ihned totiž tyto barvy pozměníme přímo v DACu. Celý postup ukazuje následující trojice snímků:
Obrázek 15: Výchozí paleta šestnácti barev kompatibilní s CGA, EGA i VGA.
Obrázek 16: Změna palety tak, aby kódy barev 0×rrggbb byly v rozsahu 0×000000 až 0×001111, což si ukáže „divné“ barvy, ty ovšem budou v DAC směřovat do prvních šestnácti míst tabulky.
Obrázek 17: Následuje přímá modifikace paměti DAC, takže získáme stupně šedi tak, jak to vyžadujeme.
Oproti předchozímu demonstračnímu příkladu tedy pouze pozměníme barvovou paletu, to je vše:
xor bl, bl ; index barvy next_color: mov bh, bl ; hodnota barvy stejna jako index mov ax, 0x1000 ; cislo sluzby a podsluzby BIOSu int 0x10 ; volani sluzby BIOSu pro zmenu jedne barvy inc bl ; zvysit index barvy cmp bl, 16 ; cela paleta? jnz next_color ; ne? tak opakujeme
13. Demonstrační příklad: korektní změna zobrazení barev
Úplný demonstrační příklad, který korektně zobrazí pruhy vyvedené ve stupních šedi, vypadá následovně:
; Graficky rezim karty VGA s rozlisenim 640x480 pixelu. ; Zmena barvovych rovin, do kterych se zapisuje. ; Konfigurace barvove palety jedinym volanim prislusne sluzby. ; Zmena hodnot ulozenych v DAC a korektnim mapovanim barev. ; ; preklad pomoci: ; nasm -f bin -o vga.com vga_gfx_mode_dac_2.asm ; ; nebo pouze: ; nasm -o vga.com vga_gfx_mode_dac_2.asm ;----------------------------------------------------------------------------- ; registry karty EGA/VGA ega_controller equ 0x3c4 bitplane_selector equ 0x02 ; ukonceni procesu a navrat do DOSu %macro exit 0 mov ah, 0x4c int 0x21 %endmacro ; vyprazdneni bufferu klavesnice a cekani na klavesu %macro wait_key 0 xor ax, ax int 0x16 %endmacro ; nastaveni grafickeho rezimu %macro gfx_mode 1 mov ah, 0 mov al, %1 int 0x10 %endmacro ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: gfx_mode 0x12 ; nastaveni rezimu 640x480 se sestnacti barvami mov ax, 0xa000 ; video RAM v textovem rezimu mov es, ax xor di, di ; nyni ES:DI obsahuje adresu prvniho pixelu ve video RAM xor al, al ; maska bitovych rovin mov cl, 16 ; pocitadlo barevnych pruhu opak: call draw_block_into_bitplanes loop opak wait_key ; cekani na klavesu xor bl, bl ; index barvy next_color: mov bh, bl ; hodnota barvy stejna jako index mov ax, 0x1000 ; cislo sluzby a podsluzby BIOSu int 0x10 ; volani sluzby BIOSu pro zmenu jedne barvy inc bl ; zvysit index barvy cmp bl, 16 ; cela paleta? jnz next_color ; ne? tak opakujeme wait_key ; cekani na klavesu xor bx, bx ; index barvy v DAC mov ax, 0x1010 next_dac: mov ch, bl shl ch, 1 shl ch, 1 ; index (0-15)*4 -> 0..60 mov cl, ch ; nastavit i ostatni slozky mov dh, ch ; nastavit i ostatni slozky int 0x10 ; modifikace mapovani v DAC inc bl ; zvysit index v DAC cmp bl, 16 jnz next_dac wait_key ; cekani na klavesu exit ; navrat do DOSu select_bitplane: mov dx, ega_controller mov ah, bitplane_selector xchg ah, al out dx, ax ; vyber registru sekvenceru ; a zapis masky bitovych rovin ret ; hotovo draw_block_into_bitplanes: push ax push cx call select_bitplane; maska bitovych rovin call draw_block add di, 640*4/8 ; posun o nekolik radku nize pop cx pop ax inc al ; zmena masky ret ; hotovo draw_block: mov cx, 640*12/4 ; pocet zapisovanych pixelu (ovsem pocitano v bajtech) mov al, 0xff ; kod pixelu rep stosb ret
14. Vykreslení jednotlivých pixelů v režimu 12H
Jak již víme z předchozího textu, režim 12H (640×480×16) je až na rozdílný počet obrazových řádků prakticky shodný režimem karty EGA 640×350×16. To znamená, že naši subrutinu (podprogram) pro vykreslení pixelů vlastně vůbec nemusíme měnit, protože jsme do ní nezahrnuli test na nejmenší a největší možné souřadnice. Subrutina nejdříve vybere vhodnou bitovou rovinu či roviny pro zápis na základě předané barvy a následně v každé z těchto rovin změní jediný bit – což je pomalá operace, neboť vyžaduje čtení (pomalé a s novými CPU ještě pomalejší operace) a následný zápis. Celkově zabere vykreslení jediného pixelu stovky taktů CPU; přesný počet závisí nejenom na použitém CPU (8088, 80186, …), ale i na rychlosti konkrétní karty VGA – zejména se to týká již zmíněné operace čtení:
select_bitplane: mov dx, ega_controller mov ah, bitplane_selector xchg ah, al out dx, ax ; vyber registru sekvenceru ; a zapis masky bitovych rovin ret ; hotovo ; Vykresleni pixelu ; AX - x-ova souradnice ; BX - y-ova souradnice ; CL - barva putpixel: push ax mov al, cl ; vyber bitove roviny nebo bitovych rovin call select_bitplane pop ax mov dx, 0xa000 ; zacatek stranky video RAM mov es, dx ; nyni obsahuje ES stranku video RAM mov cl, al and cl, 7 ; pouze spodni 3 bity x-ove souradnice shr ax, 1 shr ax, 1 shr ax, 1 ; x/8 mov di, ax ; horizontalni posun pocitany v bajtech mov ax, bx ; y-ova souradnice shl ax, 1 ; y*2 shl ax, 1 ; y*4 shl ax, 1 ; y*8 shl ax, 1 ; y*16 add di, ax ; pricist cast y-oveho posunu shl ax, 1 ; y*32 shl ax, 1 ; y*64 add di, ax ; pricist zbytek y-oveho posunu ; -> y*16 + y*64 = y*80 mov al, 0x80 ; vypocitat masku pixelu shr al, cl or [es:di], al ; vlastni vykresleni pixelu ret
Výsledná obrazovka může vypadat následovně:
Obrázek 18: Sada pixelů vykreslených v grafickém režimu 640×480×16.
15. Demonstrační příklad: vykreslení pixelů v režimu 12H
Úplný demonstrační příklad, který vykreslí sadu pixelů v režimu 12H, vypadá následovně (a opět – příliš se neliší od kódů, které jsme si již podrobně popsali):
; Graficky rezim karty VGA s rozlisenim 640x480 pixelu. ; Zmena barvovych rovin, do kterych se zapisuje. ; Vykresleni barevnych usecek. ; ; preklad pomoci: ; nasm -f bin -o vga.com vga_640x480_putpixel.asm ; ; nebo pouze: ; nasm -o vga.com vga_640x480_putpixel.asm ;----------------------------------------------------------------------------- ; registry karty EGA/VGA ega_controller equ 0x3c4 bitplane_selector equ 0x02 ; ukonceni procesu a navrat do DOSu %macro exit 0 mov ah, 0x4c int 0x21 %endmacro ; vyprazdneni bufferu klavesnice a cekani na klavesu %macro wait_key 0 xor ax, ax int 0x16 %endmacro ; nastaveni grafickeho rezimu %macro gfx_mode 1 mov ah, 0 mov al, %1 int 0x10 %endmacro ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: gfx_mode 0x12 ; nastaveni rezimu 640x480 se sestnacti barvami mov ax, 0xa000 ; video RAM v textovem rezimu mov es, ax xor di, di ; nyni ES:DI obsahuje adresu prvniho pixelu ve video RAM mov ax, 0 opak: mov bx, ax ; y-ová souřadnice push ax mov cl, 10 ; barva call putpixel ; vykreslení pixelu pop ax push ax mov cl, 11 ; barva add ax, 10 ; horizontalni posun useky call putpixel ; vykreslení pixelu pop ax push ax mov cl, 12 ; barva add ax, 20 ; horizontalni posun useky call putpixel ; vykreslení pixelu pop ax inc ax ; pusun x+=1, y+=1 cmp ax, 480 ; hranice obrazovky? jne opak ; ne-opakujeme wait_key ; cekani na klavesu exit ; navrat do DOSu select_bitplane: mov dx, ega_controller mov ah, bitplane_selector xchg ah, al out dx, ax ; vyber registru sekvenceru ; a zapis masky bitovych rovin ret ; hotovo ; Vykresleni pixelu ; AX - x-ova souradnice ; BX - y-ova souradnice ; CL - barva putpixel: push ax mov al, cl ; vyber bitove roviny nebo bitovych rovin call select_bitplane pop ax mov dx, 0xa000 ; zacatek stranky video RAM mov es, dx ; nyni obsahuje ES stranku video RAM mov cl, al and cl, 7 ; pouze spodni 3 bity x-ove souradnice shr ax, 1 shr ax, 1 shr ax, 1 ; x/8 mov di, ax ; horizontalni posun pocitany v bajtech mov ax, bx ; y-ova souradnice shl ax, 1 ; y*2 shl ax, 1 ; y*4 shl ax, 1 ; y*8 shl ax, 1 ; y*16 add di, ax ; pricist cast y-oveho posunu shl ax, 1 ; y*32 shl ax, 1 ; y*64 add di, ax ; pricist zbytek y-oveho posunu ; -> y*16 + y*64 = y*80 mov al, 0x80 ; vypocitat masku pixelu shr al, cl or [es:di], al ; vlastni vykresleni pixelu ret
16. Vykreslení jednotlivých pixelů v režimu 13H: krátká nebo rychlá varianta?
Postup při vykreslení pixelu v grafickém režimu 13H, tedy v rozlišení 320×200 s 256 barvami, je prakticky velmi jednoduchý, mnohem jednodušší (a rychlejší), než v 16barevných režimech:
- Do segmentového registru ES se vloží segment video RAM, tedy 0×a0000
- Do adresového registru DI se vloží výsledek operace x + y × 320
- Na adresu [ES:DI] se uloží barva pixelu (v našem případě předaná v registru CL)
Zbývá nám vyřešit druhý bod, protože násobení je pomalá operace, konkrétně trvá 118–133 taktů na Intelu 8088 a teprve na Intelu 80286 se snižuje na rozumných 21 taktů. Násobení nahradíme bitovým posunem a nejrychlejší na Intelu 8088 opět vychází posun o jednotlivé bity:
mov ax, bx ; y-ova souradnice shl ax, 1 ; y*2 shl ax, 1 ; y*4 shl ax, 1 ; y*8 shl ax, 1 ; y*16 shl ax, 1 ; y*32 shl ax, 1 ; y*64 add di, ax ; pricist cast y-oveho posunu shl ax, 1 ; y*128 shl ax, 1 ; y*256
Operace MOV trvá dva cykly, operace ADD tři cykly a SHL dva cykly (vše na 8088), takže tento výpočet bude trvat: 9×2+3=21 cyklů.
Celý podprogram pro vykreslení pixelu je velmi krátký v porovnání s předchozími řešeními:
; Vykresleni pixelu ; AX - x-ova souradnice ; BX - y-ova souradnice (staci len BL) ; CL - barva putpixel: mov dx, 0xa000 ; zacatek stranky video RAM mov es, dx ; nyni obsahuje ES stranku video RAM mov di, ax ; horizontalni posun pocitany v bajtech mov ax, bx ; y-ova souradnice shl ax, 1 ; y*2 shl ax, 1 ; y*4 shl ax, 1 ; y*8 shl ax, 1 ; y*16 shl ax, 1 ; y*32 shl ax, 1 ; y*64 add di, ax ; pricist cast y-oveho posunu shl ax, 1 ; y*128 shl ax, 1 ; y*256 add di, ax ; pricist zbytek y-oveho posunu ; -> y*64 + y*256 = y*320 mov [es:di], cl ; vlastni vykresleni pixelu ret
Pro zajímavost si porovnejme vykreslení v pixelu v režimu 12H a 13H:
; Vykresleni pixelu ; Vykresleni pixelu ; AX - x-ova souradnice ; AX - x-ova souradnice ; BX - y-ova souradnice | ; BX - y-ova souradnice (staci len BL) ; CL - barva ; CL - barva putpixel: putpixel: push ax < mov al, cl < call select_bitplane < pop ax < < mov dx, 0xa000 mov dx, 0xa000 mov es, dx mov es, dx mov cl, al < and cl, 7 < < shr ax, 1 < shr ax, 1 < shr ax, 1 < mov di, ax mov di, ax mov ax, bx mov ax, bx shl ax, 1 shl ax, 1 shl ax, 1 shl ax, 1 shl ax, 1 shl ax, 1 shl ax, 1 shl ax, 1 > shl ax, 1 > shl ax, 1 add di, ax add di, ax shl ax, 1 shl ax, 1 shl ax, 1 shl ax, 1 add di, ax add di, ax mov al, 0x80 | mov [es:di], cl shr al, cl < or [es:di], al < ret ret
Ovšem celou operaci se můžeme pokusit ještě více urychlit, v tomto případě za cenu vyšší spotřeby operační paměti. Násobky 320 si totiž můžeme uložit do předpočítané tabulky, která bude mít 200 hodnot. Každá hodnota je uložena ve dvou bajtech, takže budeme potřebovat 400 bajtů operační paměti. Ovšem vlastní výpočet se „scvrkne“ na zdvojnásobení hodnoty registru BX (tři cykly) a načtení offsetu z tabulky (2+12+8 cyklů), celkem je tedy namísto násobení potřeba 25 cyklů na mikroprocesoru 8088. To je více, než v předchozím případě, ovšem již na 80816 se situace změní, protože posledních 8 cyklů není zapotřebí (výpočet efektivní adresy probíhá paralelně). A na 80286 je výpočet ještě kratší, k tomu se však ještě vrátíme. Poučení: optimalizace pro jeden typ procesoru mnohdy na platformě 8086 znamená zhoršení výsledku na jiném typu mikroprocesoru:
; Vykresleni pixelu ; AX - x-ova souradnice ; BX - y-ova souradnice (staci len BL) ; CL - barva putpixel: mov dx, 0xa000 ; zacatek stranky video RAM mov es, dx ; nyni obsahuje ES stranku video RAM mov di, ax ; horizontalni posun pocitany v bajtech add bx, bx ; adresujeme slova, ne bajty mov si, offsets mov ax, [si+bx] ; nacist y-ovy posun z tabulky add di, ax ; pricist y-ovy posun mov [es:di], cl ; vlastni vykresleni pixelu ret
17. Demonstrační příklad: vykreslení pixelů s využitím operace aritmetických posunů (bez násobení)
Ukažme si nyní pro úplnost celý kód demonstračního příkladu, který po svém překladu a spuštění (na reálném HW nebo v DOSBoxu) vykreslí sadu pixelů v grafickém režimu 320×200 pixelů. Adresy pixelů jsou přitom vypočteny bez použití operace násobení; namísto něho se využívají bitové posuny. Obrazovka by měla vypadat následovně:
Obrázek 19: Sada pixelů vykreslených v grafickém režimu 320×200×256.
Zdrojový kód tohoto příkladu vypadá následovně:
; Graficky rezim karty VGA s rozlisenim 320x200 pixelu. ; Vykresleni barevnych usecek. ; ; preklad pomoci: ; nasm -f bin -o vga.com vga_320x200_putpixel_1.asm ; ; nebo pouze: ; nasm -o vga.com vga_320x200_putpixel_1.asm ;----------------------------------------------------------------------------- ; ukonceni procesu a navrat do DOSu %macro exit 0 mov ah, 0x4c int 0x21 %endmacro ; vyprazdneni bufferu klavesnice a cekani na klavesu %macro wait_key 0 xor ax, ax int 0x16 %endmacro ; nastaveni grafickeho rezimu %macro gfx_mode 1 mov ah, 0 mov al, %1 int 0x10 %endmacro ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: gfx_mode 0x13 ; nastaveni rezimu 320x200 se sestnacti barvami mov ax, 0xa000 ; video RAM v textovem rezimu mov es, ax xor di, di ; nyni ES:DI obsahuje adresu prvniho pixelu ve video RAM mov ax, 0 opak: mov bx, ax ; y-ová souřadnice push ax mov cl, al ; barva call putpixel ; vykreslení pixelu pop ax push ax mov cl, al ; barva add ax, 10 ; horizontalni posun useky call putpixel ; vykreslení pixelu pop ax push ax mov cl, al ; barva add ax, 20 ; horizontalni posun useky call putpixel ; vykreslení pixelu pop ax inc ax ; pusun x+=1, y+=1 cmp ax, 200 ; hranice obrazovky? jne opak ; ne-opakujeme wait_key ; cekani na klavesu exit ; navrat do DOSu ; Vykresleni pixelu ; AX - x-ova souradnice ; BX - y-ova souradnice (staci len BL) ; CL - barva putpixel: mov dx, 0xa000 ; zacatek stranky video RAM mov es, dx ; nyni obsahuje ES stranku video RAM mov di, ax ; horizontalni posun pocitany v bajtech mov ax, bx ; y-ova souradnice shl ax, 1 ; y*2 shl ax, 1 ; y*4 shl ax, 1 ; y*8 shl ax, 1 ; y*16 shl ax, 1 ; y*32 shl ax, 1 ; y*64 add di, ax ; pricist cast y-oveho posunu shl ax, 1 ; y*128 shl ax, 1 ; y*256 add di, ax ; pricist zbytek y-oveho posunu ; -> y*64 + y*256 = y*320 mov [es:di], cl ; vlastni vykresleni pixelu ret
18. Dnešní poslední demonstrační příklad: náhrada násobení za vyhledávací tabulku
V dnešním posledním demonstračním příkladu nahradíme operaci násobení (resp. sekvenci aritmetických posunů) za přečtení hodnoty offsetu z vyhledávací tabulky na základě předané y-ové souřadnice. Výsledek by měl být zcela totožný s předchozím demonstračním příkladem a měl by vypadat takto:
Obrázek 20: Sada pixelů vykreslená novým algoritmem založeným na vyhledávací tabulce.
Úplný zdrojový kód dnešního posledního demonstračního příkladu vypadá následovně:
; Graficky rezim karty VGA s rozlisenim 320x200 pixelu. ; Pouziti predpocitane tabulky. ; Vykresleni barevnych usecek. ; ; preklad pomoci: ; nasm -f bin -o vga.com vga_320x200_putpixel_2.asm ; ; nebo pouze: ; nasm -o vga.com vga_320x200_putpixel_2.asm ;----------------------------------------------------------------------------- ; ukonceni procesu a navrat do DOSu %macro exit 0 mov ah, 0x4c int 0x21 %endmacro ; vyprazdneni bufferu klavesnice a cekani na klavesu %macro wait_key 0 xor ax, ax int 0x16 %endmacro ; nastaveni grafickeho rezimu %macro gfx_mode 1 mov ah, 0 mov al, %1 int 0x10 %endmacro ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: gfx_mode 0x13 ; nastaveni rezimu 320x200 se sestnacti barvami mov ax, 0xa000 ; video RAM v textovem rezimu mov es, ax xor di, di ; nyni ES:DI obsahuje adresu prvniho pixelu ve video RAM mov ax, 0 opak: mov bx, ax ; y-ová souřadnice push ax push bx mov cl, al ; barva call putpixel ; vykreslení pixelu pop bx pop ax push ax push bx mov cl, al ; barva add ax, 10 ; horizontalni posun useky call putpixel ; vykreslení pixelu pop bx pop ax inc ax ; pusun x+=1, y+=1 cmp ax, 200 ; hranice obrazovky? jne opak ; ne-opakujeme wait_key ; cekani na klavesu exit ; navrat do DOSu ; Vykresleni pixelu ; AX - x-ova souradnice ; BX - y-ova souradnice (staci len BL) ; CL - barva putpixel: mov dx, 0xa000 ; zacatek stranky video RAM mov es, dx ; nyni obsahuje ES stranku video RAM mov di, ax ; horizontalni posun pocitany v bajtech add bx, bx ; adresujeme slova, ne bajty mov si, offsets mov ax, [si+bx] ; nacist y-ovy posun z tabulky add di, ax ; pricist y-ovy posun mov [es:di], cl ; vlastni vykresleni pixelu ret offsets: dw 0, 320,640,960,1280,1600,1920,2240,2560,2880,3200,3520,3840,4160,4480,4800,5120, dw 5440,5760,6080,6400,6720,7040,7360,7680,8000,8320,8640,8960,9280,9600,9920,10240, dw 10560,10880,11200,11520,11840,12160,12480,12800,13120,13440,13760,14080,14400,14720,15040,15360, dw 15680,16000,16320,16640,16960,17280,17600,17920,18240,18560,18880,19200,19520,19840,20160,20480, dw 20800,21120,21440,21760,22080,22400,22720,23040,23360,23680,24000,24320,24640,24960,25280,25600, dw 25920,26240,26560,26880,27200,27520,27840,28160,28480,28800,29120,29440,29760,30080,30400,30720, dw 31040,31360,31680,32000,32320,32640,32960,33280,33600,33920,34240,34560,34880,35200,35520,35840, dw 36160,36480,36800,37120,37440,37760,38080,38400,38720,39040,39360,39680,40000,40320,40640,40960, dw 41280,41600,41920,42240,42560,42880,43200,43520,43840,44160,44480,44800,45120,45440,45760,46080, dw 46400,46720,47040,47360,47680,48000,48320,48640,48960,49280,49600,49920,50240,50560,50880,51200, dw 51520,51840,52160,52480,52800,53120,53440,53760,54080,54400,54720,55040,55360,55680,56000,56320, dw 56640,56960,57280,57600,57920,58240,58560,58880,59200,59520,59840,60160,60480,60800,61120,61440, dw 61760,62080,62400,62720,63040,63360,63680,
19. Repositář s demonstračními příklady
Demonstrační příklady napsané v assembleru, které jsou určené pro překlad pomocí assembleru NASM, byly uložen do Git repositáře, který je dostupný na adrese https://github.com/tisnik/8bit-fame. Jednotlivé demonstrační příklady si můžete v případě potřeby stáhnout i jednotlivě bez nutnosti klonovat celý (dnes již poměrně rozsáhlý) repositář:
# | Příklad | Stručný popis | Adresa |
---|---|---|---|
1 | hello.asm | program typu „Hello world“ naprogramovaný v assembleru pro systém DOS | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hello.asm |
2 | hello_shorter.asm | kratší varianta výskoku z procesu zpět do DOSu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hello_shorter.asm |
3 | hello_wait.asm | čekání na stisk klávesy | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hello_wait.asm |
4 | hello_macros.asm | realizace jednotlivých částí programu makrem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hello_macros.asm |
5 | gfx4_putpixel.asm | vykreslení pixelu v grafickém režimu 4 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_putpixel.asm |
6 | gfx6_putpixel.asm | vykreslení pixelu v grafickém režimu 6 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel.asm |
7 | gfx4_line.asm | vykreslení úsečky v grafickém režimu 4 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_line.asm |
8 | gfx6_line.asm | vykreslení úsečky v grafickém režimu 6 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_line.asm |
9 | gfx6_fill1.asm | vyplnění obrazovky v grafickém režimu, základní varianta | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_fill1.asm |
10 | gfx6_fill2.asm | vyplnění obrazovky v grafickém režimu, varianta s instrukcí LOOP | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_fill2.asm |
11 | gfx6_fill3.asm | vyplnění obrazovky instrukcí REP STOSB | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_fill3.asm |
12 | gfx6_fill4.asm | vyplnění obrazovky, synchronizace vykreslování s paprskem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_fill4.asm |
13 | gfx4_image1.asm | vykreslení rastrového obrázku získaného z binárních dat, základní varianta | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image1.asm |
14 | gfx4_image2.asm | varianta vykreslení rastrového obrázku s využitím instrukce REP MOVSB | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image2.asm |
15 | gfx4_image3.asm | varianta vykreslení rastrového obrázku s využitím instrukce REP MOVSW | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image3.asm |
16 | gfx4_image4.asm | korektní vykreslení všech sudých řádků bitmapy | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image4.asm |
17 | gfx4_image5.asm | korektní vykreslení všech sudých i lichých řádků bitmapy | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image5.asm |
18 | gfx4_image6.asm | nastavení barvové palety před vykreslením obrázku | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image6.asm |
19 | gfx4_image7.asm | nastavení barvové palety před vykreslením obrázku, snížená intenzita barev | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image7.asm |
20 | gfx4_image8.asm | postupná změna barvy pozadí | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image8.asm |
21 | gfx6_putpixel1.asm | vykreslení pixelu, základní varianta se 16bitovým násobením | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel1.asm |
22 | gfx6_putpixel2.asm | vykreslení pixelu, varianta s osmibitovým násobením | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel2.asm |
23 | gfx6_putpixel3.asm | vykreslení pixelu, varianta bez násobení | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel3.asm |
24 | gfx6_putpixel4.asm | vykreslení pixelu přes obrázek, nekorektní chování (přepis obrázku) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel4.asm |
25 | gfx6_putpixel5.asm | vykreslení pixelu přes obrázek, korektní varianta pro bílé pixely | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel5.asm |
26 | cga_text_mode1.asm | standardní textový režim s rozlišením 40×25 znaků | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_mode1.asm |
27 | cga_text_mode3.asm | standardní textový režim s rozlišením 80×25 znaků | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_mode3.asm |
28 | cga_text_mode_intensity.asm | změna významu nejvyššího bitu atributového bajtu: vyšší intenzita namísto blikání | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_mode_intensity.asm |
29 | cga_text_mode_cursor.asm | změna tvaru textového kurzoru | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_mode_cursor.asm |
30 | cga_text_gfx1.asm | zobrazení „rastrové mřížky“: pseudografický režim 160×25 pixelů (interně textový režim) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_gfx1.asm |
31 | cga_text_mode_char_height.asm | změna výšky znaků | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_mode_char_height.asm |
32 | cga_text_160×100.asm | grafický režim 160×100 se šestnácti barvami (interně upravený textový režim) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_160×100.asm |
33 | hercules_text_mode1.asm | využití standardního textového režimu společně s kartou Hercules | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_text_mode1.asm |
34 | hercules_text_mode2.asm | zákaz blikání v textových režimech | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_text_mode2.asm |
35 | hercules_turn_off.asm | vypnutí generování video signálu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_turn_off.asm |
36 | hercules_gfx_mode1.asm | přepnutí karty Hercules do grafického režimu (základní varianta) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_gfx_mode1.asm |
37 | hercules_gfx_mode2.asm | přepnutí karty Hercules do grafického režimu (vylepšená varianta) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_gfx_mode2.asm |
38 | hercules_putpixel.asm | subrutina pro vykreslení jediného pixelu na kartě Hercules | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_putpixel.asm |
39 | ega_text_mode_80×25.asm | standardní textový režim 80×25 znaků na kartě EGA | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_text_mode_80×25.asm |
40 | ega_text_mode_80×43.asm | zobrazení 43 textových řádků na kartě EGA | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_text_mode_80×43.asm |
41 | ega_gfx_mode_320×200.asm | přepnutí do grafického režimu 320×200 pixelů se šestnácti barvami | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_gfx_mode_320×200.asm |
42 | ega_gfx_mode_640×200.asm | přepnutí do grafického režimu 640×200 pixelů se šestnácti barvami | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_gfx_mode_640×200.asm |
43 | ega_gfx_mode_640×350.asm | přepnutí do grafického režimu 640×350 pixelů se čtyřmi nebo šestnácti barvami | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_gfx_mode_640×350.asm |
44 | ega_gfx_mode_bitplanes1.asm | ovládání zápisu do bitových rovin v planárních grafických režimech (základní způsob) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_gfx_mode_bitplanes1.asm |
45 | ega_gfx_mode_bitplanes2.asm | ovládání zápisu do bitových rovin v planárních grafických režimech (rychlejší způsob) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_gfx_mode_bitplanes2.asm |
46 | ega_320×200_putpixel.asm | vykreslení pixelu v grafickém režimu 320×200 pixelů se šestnácti barvami | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_320×200_putpixel.asm |
47 | ega_640×350_putpixel.asm | vykreslení pixelu v grafickém režimu 640×350 pixelů se šestnácti barvami | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_640×350_putpixel.asm |
48 | ega_standard_font.asm | použití standardního fontu grafické karty EGA | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_standard_font.asm |
49 | ega_custom_font.asm | načtení vlastního fontu s jeho zobrazením | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_custom_font.asm |
50 | ega_palette1.asm | změna barvové palety (všech 16 barev) v grafickém režimu 320×200 se šestnácti barvami | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_palette1.asm |
51 | ega_palette2.asm | změna barvové palety (všech 16 barev) v grafickém režimu 640×350 se šestnácti barvami | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_palette2.asm |
52 | ega_palette3.asm | změna všech barev v barvové paletě s využitím programové smyčky | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_palette3.asm |
53 | ega_palette4.asm | změna všech barev, včetně barvy okraje, v barvové paletě voláním funkce BIOSu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_palette4.asm |
54 | vga_text_mode_80×25.asm | standardní textový režim 80×25 znaků na kartě VGA | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_80×25.asm |
55 | vga_text_mode_80×50.asm | zobrazení 50 a taktéž 28 textových řádků na kartě VGA | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_80×50.asm |
56 | vga_text_mode_intensity1.asm | změna chování atributového bitu pro blikání (nebezpečná varianta změny registrů) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_intensity1.asm |
57 | vga_text_mode_intensity2.asm | změna chování atributového bitu pro blikání (bezpečnější varianta změny registrů) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_intensity2.asm |
58 | vga_text_mode_9th_column.asm | modifikace způsobu zobrazení devátého sloupce ve znakových režimech (720 pixelů na řádku) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_9th_column.asm |
59 | vga_text_mode_cursor_shape.asm | změna tvaru textového kurzoru na grafické kartě VGA | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_cursor_shape.asm |
60 | vga_text_mode_custom_font.asm | načtení vlastního fontu s jeho zobrazením | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_custom_font.asm |
61 | vga_gfx_mode_640×480.asm | přepnutí do grafického režimu 640×480 pixelů se šestnácti barvami, vykreslení vzorků | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_640×480.asm |
62 | vga_gfx_mode_320×200.asm | přepnutí do grafického režimu 320×200 pixelů s 256 barvami, vykreslení vzorků | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_320×200.asm |
63 | vga_gfx_mode_palette.asm | změna všech barev v barvové paletě grafické karty VGA | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_palette.asm |
64 | vga_gfx_mode_dac1.asm | využití DAC (neočekávané výsledky) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_dac1.asm |
65 | vga_gfx_mode_dac2.asm | využití DAC (očekávané výsledky) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_dac2.asm |
66 | vga_640×480_putpixel.asm | realizace algoritmu pro vykreslení pixelu v grafickém režimu 640×480 pixelů se šestnácti barvami | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_640×480_putpixel.asm |
67 | vga_320×200_putpixel1.asm | realizace algoritmu pro vykreslení pixelu v grafickém režimu 320×200 s 256 barvami (základní varianta) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_putpixel1.asm |
68 | vga_320×200_putpixel2.asm | realizace algoritmu pro vykreslení pixelu v grafickém režimu 320×200 s 256 barvami (rychlejší varianta) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_putpixel2.asm |
20. Odkazy na Internetu
- The Intel 8088 Architecture and Instruction Set
https://people.ece.ubc.ca/~edc/464/lectures/lec4.pdf - x86 Opcode Structure and Instruction Overview
https://pnx.tf/files/x86_opcode_structure_and_instruction_overview.pdf - x86 instruction listings (Wikipedia)
https://en.wikipedia.org/wiki/X86_instruction_listings - x86 assembly language (Wikipedia)
https://en.wikipedia.org/wiki/X86_assembly_language - Intel Assembler (Cheat sheet)
http://www.jegerlehner.ch/intel/IntelCodeTable.pdf - 25 Microchips That Shook the World
https://spectrum.ieee.org/tech-history/silicon-revolution/25-microchips-that-shook-the-world - Chip Hall of Fame: MOS Technology 6502 Microprocessor
https://spectrum.ieee.org/tech-history/silicon-revolution/chip-hall-of-fame-mos-technology-6502-microprocessor - Chip Hall of Fame: Intel 8088 Microprocessor
https://spectrum.ieee.org/tech-history/silicon-revolution/chip-hall-of-fame-intel-8088-microprocessor - Jak se zrodil procesor?
https://www.root.cz/clanky/jak-se-zrodil-procesor/ - Apple II History Home
http://apple2history.org/ - The 8086/8088 Primer
https://www.stevemorse.org/8086/index.html - flat assembler: Assembly language resources
https://flatassembler.net/ - FASM na Wikipedii
https://en.wikipedia.org/wiki/FASM - Fresh IDE FASM inside
https://fresh.flatassembler.net/ - MS-DOS Version 4.0 Programmer's Reference
https://www.pcjs.org/documents/books/mspl13/msdos/dosref40/ - INT 21 – DOS Function Dispatcher (DOS)
https://www.stanislavs.org/helppc/int21.html - DOS API (Wikipedia)
https://en.wikipedia.org/wiki/DOS_API - Bit banging
https://en.wikipedia.org/wiki/Bit_banging - IBM Basic assembly language and successors (Wikipedia)
https://en.wikipedia.org/wiki/IBM_Basic_assembly_language_and_successors - X86 Assembly/Bootloaders
https://en.wikibooks.org/wiki/X86_Assembly/Bootloaders - Počátky grafiky na PC: grafické karty CGA a Hercules
https://www.root.cz/clanky/pocatky-grafiky-na-pc-graficke-karty-cga-a-hercules/ - Co mají společného Commodore PET/4000, BBC Micro, Amstrad CPC i grafické karty MDA, CGA a Hercules?
https://www.root.cz/clanky/co-maji-spolecneho-commodore-pet-4000-bbc-micro-amstrad-cpc-i-graficke-karty-mda-cga-a-hercules/ - Karta EGA: první použitelná barevná grafika na PC
https://www.root.cz/clanky/karta-ega-prvni-pouzitelna-barevna-grafika-na-pc/ - RGB Classic Games
https://www.classicdosgames.com/ - Turbo Assembler (Wikipedia)
https://en.wikipedia.org/wiki/Turbo_Assembler - Microsoft Macro Assembler
https://en.wikipedia.org/wiki/Microsoft_Macro_Assembler - IBM Personal Computer (Wikipedia)
https://en.wikipedia.org/wiki/IBM_Personal_Computer - Intel 8251
https://en.wikipedia.org/wiki/Intel_8251 - Intel 8253
https://en.wikipedia.org/wiki/Intel_8253 - Intel 8255
https://en.wikipedia.org/wiki/Intel_8255 - Intel 8257
https://en.wikipedia.org/wiki/Intel_8257 - Intel 8259
https://en.wikipedia.org/wiki/Intel_8259 - Support/peripheral/other chips – 6800 family
http://www.cpu-world.com/Support/6800.html - Motorola 6845
http://en.wikipedia.org/wiki/Motorola_6845 - The 6845 Cathode Ray Tube Controller (CRTC)
http://www.tinyvga.com/6845 - CRTC operation
http://www.6502.org/users/andre/hwinfo/crtc/crtc.html - 6845 – Motorola CRT Controller
https://stanislavs.org/helppc/6845.html - The 6845 Cathode Ray Tube Controller (CRTC)
http://www.tinyvga.com/6845 - Motorola 6845 and bitwise graphics
https://retrocomputing.stackexchange.com/questions/10996/motorola-6845-and-bitwise-graphics - IBM Monochrome Display Adapter
http://en.wikipedia.org/wiki/Monochrome_Display_Adapter - Color Graphics Adapter
http://en.wikipedia.org/wiki/Color_Graphics_Adapter - Color Graphics Adapter and the Brown color in IBM 5153 Color Display
https://www.aceinnova.com/en/electronics/cga-and-the-brown-color-in-ibm-5153-color-display/ - The Modern Retrocomputer: An Arduino Driven 6845 CRT Controller
https://hackaday.com/2017/05/14/the-modern-retrocomputer-an-arduino-driven-6845-crt-controller/ - flat assembler: Assembly language resources
https://flatassembler.net/ - FASM na Wikipedii
https://en.wikipedia.org/wiki/FASM - Fresh IDE FASM inside
https://fresh.flatassembler.net/ - MS-DOS Version 4.0 Programmer's Reference
https://www.pcjs.org/documents/books/mspl13/msdos/dosref40/ - INT 21 – DOS Function Dispatcher (DOS)
https://www.stanislavs.org/helppc/int21.html - DOS API (Wikipedia)
https://en.wikipedia.org/wiki/DOS_API - IBM Basic assembly language and successors (Wikipedia)
https://en.wikipedia.org/wiki/IBM_Basic_assembly_language_and_successors - X86 Assembly/Arithmetic
https://en.wikibooks.org/wiki/X86_Assembly/Arithmetic - Art of Assembly – Arithmetic Instructions
http://oopweb.com/Assembly/Documents/ArtOfAssembly/Volume/Chapter6/CH06–2.html - ASM Flags
http://www.cavestory.org/guides/csasm/guide/asm_flags.html - Status Register
https://en.wikipedia.org/wiki/Status_register - Linux assemblers: A comparison of GAS and NASM
http://www.ibm.com/developerworks/library/l-gas-nasm/index.html - Programovani v assembleru na OS Linux
http://www.cs.vsb.cz/grygarek/asm/asmlinux.html - Is it worthwhile to learn x86 assembly language today?
https://www.quora.com/Is-it-worthwhile-to-learn-x86-assembly-language-today?share=1 - Why Learn Assembly Language?
http://www.codeproject.com/Articles/89460/Why-Learn-Assembly-Language - Is Assembly still relevant?
http://programmers.stackexchange.com/questions/95836/is-assembly-still-relevant - Why Learning Assembly Language Is Still a Good Idea
http://www.onlamp.com/pub/a/onlamp/2004/05/06/writegreatcode.html - Assembly language today
http://beust.com/weblog/2004/06/23/assembly-language-today/ - Assembler: Význam assembleru dnes
http://www.builder.cz/rubriky/assembler/vyznam-assembleru-dnes-155960cz - Programming from the Ground Up Book – Summary
http://savannah.nongnu.org/projects/pgubook/ - DOSBox
https://www.dosbox.com/ - The C Programming Language
https://en.wikipedia.org/wiki/The_C_Programming_Language - Hercules Graphics Card (HCG)
https://en.wikipedia.org/wiki/Hercules_Graphics_Card - Complete 8086 instruction set
https://content.ctcd.edu/courses/cosc2325/m22/docs/emu8086ins.pdf - Complete 8086 instruction set
https://yassinebridi.github.io/asm-docs/8086_instruction_set.html - 8088 MPH by Hornet + CRTC + DESiRE (final version)
https://www.youtube.com/watch?v=hNRO7lno_DM - Area 5150 by CRTC & Hornet (Party Version) / IBM PC+CGA Demo, Hardware Capture
https://www.youtube.com/watch?v=fWDxdoRTZPc - 80×86 Integer Instruction Set Timings (8088 – Pentium)
http://aturing.umcs.maine.edu/~meadow/courses/cos335/80×86-Integer-Instruction-Set-Clocks.pdf - Colour Graphics Adapter: Notes
https://www.seasip.info/VintagePC/cga.html - Restoring A Vintage CGA Card With Homebrew HASL
https://hackaday.com/2024/06/12/restoring-a-vintage-cga-card-with-homebrew-hasl/ - Demoing An 8088
https://hackaday.com/2015/04/10/demoing-an-8088/ - Video Memory Layouts
http://www.techhelpmanual.com/89-video_memory_layouts.html - Screen Attributes
http://www.techhelpmanual.com/87-screen_attributes.html - IBM PC Family – BIOS Video Modes
https://www.minuszerodegrees.net/video/bios_video_modes.htm - EGA Functions
https://cosmodoc.org/topics/ega-functions/#the-hierarchy-of-the-ega - Why the EGA can only use 16 of its 64 colours in 200-line modes
https://www.reenigne.org/blog/why-the-ega-can-only-use-16-of-its-64-colours-in-200-line-modes/ - How 16 colors saved PC gaming – the story of EGA graphics
https://www.custompc.com/retro-tech/ega-graphics - List of 16-bit computer color palettes
https://en.wikipedia.org/wiki/List_of16-bit_computer_color_palettes - Why were those colors chosen to be the default palette for 256-color VGA?
https://retrocomputing.stackexchange.com/questions/27994/why-were-those-colors-chosen-to-be-the-default-palette-for-256-color-vga - VGA Color Palettes
https://www.fountainware.com/EXPL/vga_color_palettes.htm - Hardware Level VGA and SVGA Video Programming Information Page
http://www.osdever.net/FreeVGA/vga/vga.htm - Hardware Level VGA and SVGA Video Programming Information Page – sequencer
http://www.osdever.net/FreeVGA/vga/seqreg.htm - VGA Basics
http://www.brackeen.com/vga/basics.html - Introduction to VGA Mode ‚X‘
https://web.archive.org/web/20160414072210/http://fly.srk.fer.hr/GDM/articles/vgamodex/vgamx1.html - VGA Mode-X
https://web.archive.org/web/20070123192523/http://www.gamedev.net/reference/articles/article356.asp - Mode-X: 256-Color VGA Magic
https://downloads.gamedev.net/pdf/gpbb/gpbb47.pdf