Obsah
1. Skrytá síla karty VGA: čtecí a zápisové režimy
2. Grafická operace typu BitBLT
3. První (naivní) implementace operace typu BitBLT
4. Úplný zdrojový kód dnešního prvního demonstračního příkladu
5. Proč vypadá obrazovka po provedení blokového přenosu tak, jak vypadá?
6. Operace BitBLT při povolení zápisu do různých kombinací bitových rovin
7. Úplný zdrojový kód dnešního druhého demonstračního příkladu
8. Stavy obrazovky v jednotlivých fázích druhého demonstračního příkladu
9. Výběr bitové roviny pro čtení
10. Postupné čtení obsahu jednotlivých bitových rovin operací typu BitBLT
11. Úplný zdrojový kód dnešního třetího demonstračního příkladu
12. Stavy obrazovky v jednotlivých fázích třetího demonstračního příkladu
13. Korektní (pomalá) realizace operace typu BitBLT
14. Úplný zdrojový kód dnešního čtvrtého demonstračního příkladu
15. Obrazovka před blokovým přenosem a po provedení blokového přenosu
16. Realizace operace typu BitBLT podprogramem
17. Úplný zdrojový kód dnešního pátého demonstračního příkladu
18. Blokové přenosy s využitím 32bitového záchytného registru latche
19. Repositář s demonstračními příklady
1. Skrytá síla karty VGA: čtecí a zápisové režimy
Grafické karty VGA (a nutno dodat, že vlastně i původní karty EGA) byly postaveny, jak již dobře víme, na konceptu bitových rovin (bitplanes). Nejlépe je toto členění grafické paměti patrné u režimů se šestnácti barvami, takže se v dalším textu zaměříme především na tyto režimy, i když všechny koncepty lze použít i v režimech s 256 barvami a nezřetězenými rovinami (pro standardní režim 13h to neplatí). Takže si zopakujme základní koncepty EGA a VGA:
- K dispozici jsou čtyři bitové roviny, každá o velikosti 64kB (což odpovídá virtuálnímu rozlišení 640×819 pixelů).
- Z logického pohledu tyto roviny leží na sobě (tj. nulté bity na sobě, první bity na sobě atd.)
- Barvy pixelů jsou v 16barevných režimech zapsány do čtyř bitů, přičemž tyto bity jsou rozděleny do všech čtyř rovin (v každé rovině jediný bit).
- Fyzicky jsou všechny bitové roviny namapovány do stejného adresního prostoru v segmentu 0×a000 a neexistuje zde tedy jednoznačný vztah adresa==konkrétní osmice bitů.
- Při čtení se přečte osm bitů z vybrané bitové roviny 0..3. Výběr roviny se provádí přes I/O porty (viz další text).
- Při zápisu se zapíše osm bitů do vybrané kombinace bitových rovin, tedy například do roviny 1+2, do všech rovin, atd. Výběr se opět provádí přes I/O porty.
- Při zápisu lze bity rotovat, maskovat je atd.
- Navíc existuje několik čtecích a zápisových režimů popsaných v dalších textech.
- Při čtení se ve skutečnosti přečte osm bitů z každé bitové roviny (8×4=32 bitů), které se uloží do záchytného registru (latche). Existuje zápisový režim, který dokáže opět těchto 32bitů zapsat a přenést tak vlastně 4 pixely jedinou strojovou instrukcí (i když se po sběrnici přenese jen 8 bitů). Toto byla velmi silná programátorská technika, ke které se pochopitelně ještě vrátíme.
2. Grafická operace typu BitBLT
Většina historických i poměrně velká část soudobých počítačových her s dvoudimenzionální (2D) grafikou je charakteristická tím, že objekty v těchto hrách jsou reprezentovány s využitím rastrových obrázků (bitmap) o různé velikosti, které se postupně vykreslují do vytvářené dvoudimenzionální scény. Aby bylo přes některé části těchto rastrových obrázků viditelné i pozadí, používají se tři metody pro zajištění úplné či částečné průhlednosti. Buď je stanoveno, že určitá hodnota (tj. barva) pixelů má být zcela průhledná (typicky se jedná o jasně fialovou barvu, která se v typických scénách stejně nikde neobjevuje), dále je alternativně možné jeden bit v hodnotě pixelu použít pro určení průhlednosti (typické pro 16bitovou hloubku), nebo se může stanovit průhlednost pixelů doplněním bitmapy o takzvaný alfa kanál (alpha channel).
Obrázek 1: Rastrové obrázky (zde zvětšené), které tvoří základ jedné RPG. Vykreslují se funkcí blit/BitBLT.
S využitím grafické operace blit neboli BitBLT (Bit Block Transfer) lze provádět, jak ostatně její název naznačuje, blokové přenosy bitmap nebo jejich výřezů, popř. v rámci přenosu nad bitmapami provádět různé další operace, například zpracování alfa kanálu. První implementace operace BitBLT byla použita v roce 1975 ve Smalltalku-72 a od té doby ji najdeme prakticky v každé implementaci tohoto programovacího jazyka, která obsahuje i knihovny pro práci s grafikou (mj. se jedná i o Squeak). Pro Smalltalk-74 vytvořil Daniel Ingalls optimalizovanou variantu operace BitBLT implementovanou v mikrokódu. Operace BitBLT se tak stala součástí operačního systému a bylo ji možné volat jak z assembleru, tak i z programů napsaných v jazyce BCPL a samozřejmě i ze Smalltalku (právě tuto implementaci můžeme považovat za vůbec první grafickou akceleraci). Posléze se díky své univerzalitě tato funkce rozšířila i do mnoha dalších operačních systémů a grafických knihoven.
Obrázek 2: Hra Warcraft II také používá téměř výhradně bitmapy pro zobrazení budov i postaviček.
Tuto operaci lze implementovat i na kartě VGA, a to hned několika různými způsoby, které si postupně popíšeme.
3. První (naivní) implementace operace typu BitBLT
Naše první (a nutno dodat, že i hodně naivní) implementace výše zmíněné operace typu BitBLT v šestnáctibarevném grafickém režimu karty VGA může vypadat následovně. Budeme se snažit přenést horní polovinu obrazu (240 obrazových řádků) do poloviny spodní, a to bajt po bajtu:
; operace BitBLT z prvni poloviny obrazovky na druhou polovinu bitblt: mov ax, 0xa000 ; video RAM v textovem rezimu mov es, ax mov ds, ax mov di, 640*240/8 ; nyni ES:DI obsahuje adresu pixelu ve video RAM na 240 radku xor si, si ; nyni DS:SI obsahuje adresu prvniho pixelu ve video RAM mov cx, 640*240/8 ; pocet prenesenych bajtu rep movsb ; blokovy prenos po bajtech ret ; hotovo
V příkladu nejdříve nastavíme grafický režim, vykreslíme sérii úseček a počkáme na stisk klávesy:
gfx_mode 0x12 ; nastaveni rezimu 640x480 se sestnacti barvami call draw_color_lines wait_key ; cekani na klavesu
Dále nastavíme bitové roviny pro zápis a zavoláme výše uvedený podprogram bitblt:
select_bitplane 15 ; vyber bitove roviny nebo bitovych rovin call bitblt ; prenos bloku
Po stisku klávesy se program ukončí:
wait_key ; cekani na klavesu exit ; navrat do DOSu
4. Úplný zdrojový kód dnešního prvního demonstračního příkladu
Úplný zdrojový kód dnešního prvního demonstračního příkladu, v němž je volána naivní varianta operace BitBLT, vypadá takto:
; Graficky rezim karty VGA s rozlisenim 640x480 pixelu. ; Zmena barvovych rovin, do kterych se zapisuje. ; Vykresleni barevnych usecek. ; Prenos casti obrazu operaci typu BitBLT. ; ; preklad pomoci: ; nasm -f bin -o vga.com vga_bitblt_1.asm ; ; nebo pouze: ; nasm -o vga.com vga_bitblt_1.asm ;----------------------------------------------------------------------------- ; I/O porty karty EGA/VGA SEQUENCER_INDEX equ 0x3c4 SEQUENCER_DATA equ 0x3c5 ; registry karty EGA/VGA BITPLANE_SELECTOR equ 0x02 ; sequencer ; 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 ; vyber bitove roviny %macro select_bitplane 1 mov al, %1 ; bitova rovina mov dx, SEQUENCER_INDEX mov ah, BITPLANE_SELECTOR xchg ah, al out dx, ax ; vyber registru sekvenceru ; a zapis masky bitovych rovin %endmacro ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: gfx_mode 0x12 ; nastaveni rezimu 640x480 se sestnacti barvami call draw_color_lines wait_key ; cekani na klavesu select_bitplane 15 ; vyber bitove roviny nebo bitovych rovin call bitblt ; prenos bloku wait_key ; cekani na klavesu exit ; navrat do DOSu ; operace BitBLT z prvni poloviny obrazovky na druhou polovinu bitblt: mov ax, 0xa000 ; video RAM v textovem rezimu mov es, ax mov ds, ax mov di, 640*240/8 ; nyni ES:DI obsahuje adresu pixelu ve video RAM na 240 radku xor si, si ; nyni DS:SI obsahuje adresu prvniho pixelu ve video RAM mov cx, 640*240/8 ; pocet prenesenych bajtu rep movsb ; blokovy prenos po bajtech ret ; hotovo draw_color_lines: 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, 15 ; barva call putpixel ; vykreslení pixelu pop ax push ax mov cl, 7 ; barva add ax, 10 ; horizontalni posun useky call putpixel ; vykreslení pixelu pop ax push ax mov cl, 1 ; barva add ax, 20 ; horizontalni posun useky call putpixel ; vykreslení pixelu pop ax push ax mov cl, 2 ; barva add ax, 30 ; horizontalni posun useky call putpixel ; vykreslení pixelu pop ax push ax mov cl, 4 ; barva add ax, 40 ; 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 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 select_bitplane al 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 ; hotovo
5. Proč vypadá obrazovka po provedení blokového přenosu tak, jak vypadá?
Nyní zkusme prozkoumat obrazovku PC (nebo emulátoru) před a po provedení naší operace typu BitBLT. První i druhá verze obrazovky budou vypadat následovně:
Obrázek 3: Obrazovka před provedením operace BitBLT.
Obrázek 4: Obrazovka po provedení operace BitBLT.
Ideálně by měl obrázek číslo 4 mít ve spodní polovině přesnou kopii horní poloviny, což se však nestalo. Při bližším prozkoumání zjistíme, že bílé úsečky, které byly zkopírovány, mají jednu vlastnost společnou – všechny mají pixely nastavené na jedničku v první bitové rovině, zatímco zbylé úsečky nikoli:
Barva | Bitplane 0 | Bitplane 1 | Bitplane 2 | Bitplane 3 | Přeneseno? |
---|---|---|---|---|---|
bílá | 1 | 1 | 1 | 1 | ano |
šedá | 1 | 1 | 1 | 0 | ano |
modrá | 1 | 0 | 0 | 0 | ano |
zelená | 0 | 1 | 0 | 0 | ne |
červená | 0 | 0 | 1 | 0 | ne |
Vše je tedy zřejmé – čtení bajtů (tedy osmic pixelů) probíhalo z první bitové roviny s indexem 0, která obsahuje modrou barvovou složku, pokud pochopitelně nezměníme barvovou paletu. Čtení ze všech bitových rovin v tomto případě nemohlo nastat, protože čteme jeden bajt (osm pixelů, každý pixel jeden bit) a nikoli čtyři bajty; ty se do registru AL skutečně nevejdou.
A důvodem, proč je výsledkem trojice bílých úseček je fakt, že zápis (nikoli čtení) se naopak provádí do všech čtyř bitových rovin, tj. onen bajt v AL je interně rozkopírován na čtyři místa.
6. Operace BitBLT při povolení zápisu do různých kombinací bitových rovin
V rámci dnešního druhého demonstračního příkladu se pokusme o nepatrnou úpravu – budeme stále provádět naši operaci BitBLT, ale před jejím provedením změníme kombinaci bitových rovin pro zápis (nikoli pro čtení – to zatím neumíme). Budeme tedy řídit, jakým způsobem se zapíše celý bajt (osm pixelů) – zda do jedné bitové roviny, více rovin, do všech čtyř rovin či dokonce nikam:
Makro | Význam po zavolání |
---|---|
select_bitplane 1 | zápis do první bitové roviny (s indexem 0), obsahuje červenou složku |
select_bitplane 2 | zápis do druhé bitové roviny (s indexem 1), obsahuje zelenou složku |
select_bitplane 7 | zápis do rovin s indexy 0, 1 a 2, obsahuje RGB složky |
select_bitplane 15 | zápis do všech čtyř rovin, poslední rovina obsahuje intenzitu barvy |
Mezi jednotlivými operacemi typu BibBLT počkáme na stisk klávesy:
select_bitplane 1 ; vyber bitove roviny nebo bitovych rovin call bitblt ; prenos bloku wait_key ; cekani na klavesu select_bitplane 2 ; vyber bitove roviny nebo bitovych rovin call bitblt ; prenos bloku wait_key ; cekani na klavesu select_bitplane 7 ; vyber bitove roviny nebo bitovych rovin call bitblt ; prenos bloku wait_key ; cekani na klavesu select_bitplane 15 ; vyber bitove roviny nebo bitovych rovin call bitblt ; prenos bloku wait_key ; cekani na klavesu
7. Úplný zdrojový kód dnešního druhého demonstračního příkladu
Zdrojový kód dnešního druhého demonstračního příkladu, v němž se operace typu BitBLT provádí s různými bitovými rovinami pro zápis, vypadá následovně:
; Graficky rezim karty VGA s rozlisenim 640x480 pixelu. ; Zmena barvovych rovin, do kterych se zapisuje. ; Vykresleni barevnych usecek. ; Prenos casti obrazu operaci typu BitBLT. ; ; preklad pomoci: ; nasm -f bin -o vga.com vga_bitblt_2.asm ; ; nebo pouze: ; nasm -o vga.com vga_bitblt_2.asm ;----------------------------------------------------------------------------- ; I/O porty karty EGA/VGA SEQUENCER_INDEX equ 0x3c4 SEQUENCER_DATA equ 0x3c5 ; registry karty EGA/VGA BITPLANE_SELECTOR equ 0x02 ; sequencer ; 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 ; vyber bitove roviny %macro select_bitplane 1 mov al, %1 ; bitova rovina mov dx, SEQUENCER_INDEX mov ah, BITPLANE_SELECTOR xchg ah, al out dx, ax ; vyber registru sekvenceru ; a zapis masky bitovych rovin %endmacro ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: gfx_mode 0x12 ; nastaveni rezimu 640x480 se sestnacti barvami call draw_color_lines wait_key ; cekani na klavesu select_bitplane 1 ; vyber bitove roviny nebo bitovych rovin call bitblt ; prenos bloku wait_key ; cekani na klavesu select_bitplane 2 ; vyber bitove roviny nebo bitovych rovin call bitblt ; prenos bloku wait_key ; cekani na klavesu select_bitplane 7 ; vyber bitove roviny nebo bitovych rovin call bitblt ; prenos bloku wait_key ; cekani na klavesu select_bitplane 15 ; vyber bitove roviny nebo bitovych rovin call bitblt ; prenos bloku wait_key ; cekani na klavesu exit ; navrat do DOSu ; operace BitBLT z prvni poloviny obrazovky na druhou polovinu bitblt: mov ax, 0xa000 ; video RAM v textovem rezimu mov es, ax mov ds, ax mov di, 640*240/8 ; nyni ES:DI obsahuje adresu pixelu ve video RAM na 240 radku xor si, si ; nyni DS:SI obsahuje adresu prvniho pixelu ve video RAM mov cx, 640*240/8 ; pocet prenesenych bajtu rep movsb ; blokovy prenos po bajtech ret ; hotovo draw_color_lines: 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, 15 ; barva call putpixel ; vykreslení pixelu pop ax push ax mov cl, 7 ; barva add ax, 10 ; horizontalni posun useky call putpixel ; vykreslení pixelu pop ax push ax mov cl, 1 ; barva add ax, 20 ; horizontalni posun useky call putpixel ; vykreslení pixelu pop ax push ax mov cl, 2 ; barva add ax, 30 ; horizontalni posun useky call putpixel ; vykreslení pixelu pop ax push ax mov cl, 4 ; barva add ax, 40 ; 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 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 select_bitplane al 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 ; hotovo
8. Stavy obrazovky v jednotlivých fázích druhého demonstračního příkladu
Způsob činnosti našeho druhého příkladu, v němž se využívá operace typu BitBLT, je poměrně dobře popsatelný při pohledu na obsahy obrazovky, které získáme:
Obrázek 6: Takto vypadá původní obsah obrazovky po vykreslení série různobarevných úseček.
Obrázek 7: Výsledek čtení obsahu první bitové roviny (bitplane 0) se zápisem do první bitové roviny. V tomto případě se přenese pouze modrá barvová složka, která je součástí prvních tří úseček.
Obrázek 8: Výsledek čtení obsahu první bitové roviny (opět), ovšem nyní se bajty zapisují do druhé roviny. Nastaví se tedy navíc ještě zelená složka, a to pochopitelně u všech již zobrazených pixelů (obsah bitových rovin 0 a 1 bude ve spodní části obrázku shodný).
Obrázek 9: Nyní zapisujeme do prvních tří bitových rovin obsah první bitové roviny (bitplane 0). Z modré barvové složky se tedy nyní stane šedá barva (R=1, G=1, B=1, intenzita=0).
Obrázek 10: A konečně zapisujeme do všech tří bitových rovin obsah první roviny (tedy modré složky). Výsledkem jsou tři bílé úsečky (R=1, G=1, B=1, intenzita=1).
9. Výběr bitové roviny pro čtení
Aby bylo možné provést přenos celé části obrazu (tedy s věrnou kopií barev), budeme muset přenést odpovídající data ze všech čtyř bitových rovin. Nejdříve se podívejme na pomalý, ovšem dobře pochopitelný způsob: přenos vždy jedné vybrané bitové roviny. Již víme, jakým způsobem se vybírají roviny (tedy přesněji řečeno jejich libovolná kombinace) pro zápis – jedná se o čtveřici bitů tvořících masku, v níž každý bit odpovídá jedné bitové rovině. Pro volbu bitové roviny pro čtení však nepotřebujeme čtyři bity, ale jen bity dva, protože (logicky) dokážeme osmibitovou operací čtení přečíst pouze jeden vybraný bajt (tedy osmici pixelů) a nikoli 4×8 bitů. I z tohoto důvodu je v řídicích registrech karty VGA dostupný i registr nazvaný Read Map Select Register, v němž mají význam jen nejnižší dva bity: obsahují index bitové roviny 0..3.
Tento registr je součástí grafického řadiče a jeho hodnotu (tedy bitovou rovinu určenou pro čtení) specifikujeme pomocí makra:
; vyber bitove roviny pro cteni %macro select_bitplane_for_read 1 mov dx, GRAPHICS_REGISTER mov al, READ_MAP_SELECT out dx, al ; vyber VGA registru pro zapis inc dx, mov al, %1 ; zmena VGA registru out dx, al %endmacro
Toto makro využívá dvě nové konstanty – adresu I/O portu grafického řadiče a indexu registru Read Map Select Register:
; I/O porty karty EGA/VGA GRAPHICS_REGISTER equ 0x3ce ; registry karty EGA/VGA READ_MAP_SELECT equ 0x04 ; graphics register
Současně přejmenujeme makro pro výběr roviny (rovin) pro zápis, aby jeho název explicitně obsahoval i prováděnou operaci:
; vyber bitove roviny nebo bitovych rovin pro zapis %macro select_bitplanes_for_write 1 mov al, %1 ; bitova rovina mov dx, SEQUENCER_INDEX mov ah, BITPLANE_SELECTOR xchg ah, al out dx, ax ; vyber registru sekvenceru ; a zapis masky bitovych rovin %endmacro
10. Postupné čtení obsahu jednotlivých bitových rovin operací typu BitBLT
Ukažme si nyní, jak bude vypadat výsledek operace typu BitBLT ve chvíli, kdy budeme zapisovat do všech čtyř bitových rovin současně (a tedy výsledkem bude vždy černá nebo bílá barva pixelů):
select_bitplanes_for_write 15 ; vyber vsech bitovych rovin pro zapis
Ovšem čtení z bitových rovin provedeme postupně – nejprve pro první rovinu (0), dále pro rovinu druhou atd. A mezi jednotlivými operacemi BitBLT bude program čekat na stisk klávesy:
select_bitplane_for_read 0 ; vyber bitove roviny pro cteni call bitblt ; prenos bloku wait_key ; cekani na klavesu select_bitplane_for_read 1 ; vyber bitove roviny pro cteni call bitblt ; prenos bloku wait_key ; cekani na klavesu select_bitplane_for_read 2 ; vyber bitove roviny pro cteni call bitblt ; prenos bloku wait_key ; cekani na klavesu select_bitplane_for_read 3 ; vyber bitove roviny pro cteni call bitblt ; prenos bloku wait_key ; cekani na klavesu
11. Úplný zdrojový kód dnešního třetího demonstračního příkladu
Dnešní třetí demonstrační příklad, jehož základní činnost byla popsána v předchozích dvou kapitolách, vypadá následovně:
; Graficky rezim karty VGA s rozlisenim 640x480 pixelu. ; Zmena barvovych rovin, do kterych se zapisuje. ; Vykresleni barevnych usecek. ; Prenos casti obrazu operaci typu BitBLT. ; Vyber bitovych rovin pro zapis. ; Vyber bitove roviny pro cteni. ; ; preklad pomoci: ; nasm -f bin -o vga.com vga_bitblt_3.asm ; ; nebo pouze: ; nasm -o vga.com vga_bitblt_3.asm ;----------------------------------------------------------------------------- ; I/O porty karty EGA/VGA GRAPHICS_REGISTER equ 0x3ce SEQUENCER_INDEX equ 0x3c4 SEQUENCER_DATA equ 0x3c5 ; registry karty EGA/VGA BITPLANE_SELECTOR equ 0x02 ; sequencer READ_MAP_SELECT equ 0x04 ; graphics register ; 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 ; vyber bitove roviny nebo bitovych rovin pro zapis %macro select_bitplanes_for_write 1 mov al, %1 ; bitova rovina mov dx, SEQUENCER_INDEX mov ah, BITPLANE_SELECTOR xchg ah, al out dx, ax ; vyber registru sekvenceru ; a zapis masky bitovych rovin %endmacro ; vyber bitove roviny pro cteni %macro select_bitplane_for_read 1 mov dx, GRAPHICS_REGISTER mov al, READ_MAP_SELECT out dx, al ; vyber VGA registru pro zapis inc dx, mov al, %1 ; zmena VGA registru out dx, al %endmacro ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: gfx_mode 0x12 ; nastaveni rezimu 640x480 se sestnacti barvami call draw_color_lines wait_key ; cekani na klavesu select_bitplanes_for_write 15 ; vyber vsech bitovych rovin pro zapis select_bitplane_for_read 0 ; vyber bitove roviny pro cteni call bitblt ; prenos bloku wait_key ; cekani na klavesu select_bitplane_for_read 1 ; vyber bitove roviny pro cteni call bitblt ; prenos bloku wait_key ; cekani na klavesu select_bitplane_for_read 2 ; vyber bitove roviny pro cteni call bitblt ; prenos bloku wait_key ; cekani na klavesu select_bitplane_for_read 3 ; vyber bitove roviny pro cteni call bitblt ; prenos bloku wait_key ; cekani na klavesu exit ; navrat do DOSu ; operace BitBLT z prvni poloviny obrazovky na druhou polovinu bitblt: mov ax, 0xa000 ; video RAM v textovem rezimu mov es, ax mov ds, ax mov di, 640*240/8 ; nyni ES:DI obsahuje adresu pixelu ve video RAM na 240 radku xor si, si ; nyni DS:SI obsahuje adresu prvniho pixelu ve video RAM mov cx, 640*240/8 ; pocet prenesenych bajtu rep movsb ; blokovy prenos po bajtech ret ; hotovo draw_color_lines: 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, 15 ; barva call putpixel ; vykreslení pixelu pop ax push ax mov cl, 7 ; barva add ax, 10 ; horizontalni posun useky call putpixel ; vykreslení pixelu pop ax push ax mov cl, 1 ; barva add ax, 20 ; horizontalni posun useky call putpixel ; vykreslení pixelu pop ax push ax mov cl, 2 ; barva add ax, 30 ; horizontalni posun useky call putpixel ; vykreslení pixelu pop ax push ax mov cl, 4 ; barva add ax, 40 ; 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 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 select_bitplanes_for_write al 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 ; hotovo
12. Stavy obrazovky v jednotlivých fázích třetího demonstračního příkladu
Podobně, jako tomu bylo u druhého demonstračního příkladu, si i nyní ukážeme obsahy obrazovek vykreslovaných třetím příkladem. Připomeňme si, že se provádělo čtení z různých bitových rovin, ovšem zápis byl vždy proveden do všech čtyř bitových rovin, takže výsledkem bude – nezávisle na zdroji – nějaký černobílý obrazec (barvy „zmizí“):
Obrázek 11: Původní obrázek s pěticí barevných úseček.
Obrázek 12: Čtení z první bitové roviny (bitplane 0) znamená, že se přečetla jen modrá barvová složka (první tři úsečky) a převedla se na bílou barvu (zápisem do všech čtyř bitových rovin).
Obrázek 13: Čtení ze druhé bitové roviny (bitplane 1) znamenalo přečtení zelené barvové složky. Ta je nastavena pro první, druhou a čtvrtou úsečku (viz obrázek číslo 10).
Obrázek 14: Čtení ze třetí bitové roviny (bitplane 2) znamenalo přečtení červené barvové složky.
Obrázek 15: Čtení ze čtvrté barvové roviny (bitplane 3) znamenalo přečtení intenzity. Ta je nastavena pouze pro pixely v první úsečce.
13. Korektní (pomalá) realizace operace typu BitBLT
Jak by tedy měla vypadat korektně naprogramovaná operace typu BitBLT? Protože prozatím neznáme další potřebné triky (využití latche atd.), budeme muset přenos barev pixelů provést čtyřikrát – pro každou bitovou rovinu zvlášť. Jedná se o tento postup:
- Čtení z roviny 0, zápis jen do roviny 0
- Čtení z roviny 1, zápis jen do roviny 1
- Čtení z roviny 2, zápis jen do roviny 2
- Čtení z roviny 3, zápis jen do roviny 3
Následuje neefektivní způsob zápisu těchto operací voláním příslušných maker. V dalších kapitolách si uvedeme kratší a nepatrně rychlejší způsob zápisu:
select_bitplane_for_read 0 ; vyber prvni bitove roviny pro cteni select_bitplanes_for_write 1 ; vyber prvni bitove roviny pro zapis call bitblt ; prenos bloku select_bitplane_for_read 1 ; vyber druhe bitove roviny pro cteni select_bitplanes_for_write 2 ; vyber druhe bitove roviny pro zapis call bitblt ; prenos bloku select_bitplane_for_read 2 ; vyber treti bitove roviny pro cteni select_bitplanes_for_write 4 ; vyber treti bitove roviny pro zapis call bitblt ; prenos bloku select_bitplane_for_read 3 ; vyber ctvrte bitove roviny pro cteni select_bitplanes_for_write 8 ; vyber ctvrte bitove roviny pro zapis call bitblt ; prenos bloku
14. Úplný zdrojový kód dnešního čtvrtého demonstračního příkladu
Opět se podívejme na úplný zdrojový kód demonstračního příkladu, jenž byl popsán v předchozích kapitolách. Tento příklad nyní vypadá následovně:
; Graficky rezim karty VGA s rozlisenim 640x480 pixelu. ; Zmena barvovych rovin, do kterych se zapisuje. ; Vykresleni barevnych usecek. ; Prenos casti obrazu operaci typu BitBLT - nyni jiz korektni. ; Vyber bitovych rovin pro zapis. ; Vyber bitove roviny pro cteni. ; ; preklad pomoci: ; nasm -f bin -o vga.com vga_bitblt_4.asm ; ; nebo pouze: ; nasm -o vga.com vga_bitblt_4.asm ;----------------------------------------------------------------------------- ; I/O porty karty EGA/VGA GRAPHICS_REGISTER equ 0x3ce SEQUENCER_INDEX equ 0x3c4 SEQUENCER_DATA equ 0x3c5 ; registry karty EGA/VGA BITPLANE_SELECTOR equ 0x02 ; sequencer READ_MAP_SELECT equ 0x04 ; graphics register ; 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 ; vyber bitove roviny nebo bitovych rovin pro zapis %macro select_bitplanes_for_write 1 mov al, %1 ; bitova rovina mov dx, SEQUENCER_INDEX mov ah, BITPLANE_SELECTOR xchg ah, al out dx, ax ; vyber registru sekvenceru ; a zapis masky bitovych rovin %endmacro ; vyber bitove roviny pro cteni %macro select_bitplane_for_read 1 mov dx, GRAPHICS_REGISTER mov al, READ_MAP_SELECT out dx, al ; vyber VGA registru pro zapis inc dx, mov al, %1 ; zmena VGA registru out dx, al %endmacro ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: gfx_mode 0x12 ; nastaveni rezimu 640x480 se sestnacti barvami call draw_color_lines wait_key ; cekani na klavesu select_bitplane_for_read 0 ; vyber prvni bitove roviny pro cteni select_bitplanes_for_write 1 ; vyber prvni bitove roviny pro zapis call bitblt ; prenos bloku wait_key ; cekani na klavesu select_bitplane_for_read 1 ; vyber druhe bitove roviny pro cteni select_bitplanes_for_write 2 ; vyber druhe bitove roviny pro zapis call bitblt ; prenos bloku wait_key ; cekani na klavesu select_bitplane_for_read 2 ; vyber treti bitove roviny pro cteni select_bitplanes_for_write 4 ; vyber treti bitove roviny pro zapis call bitblt ; prenos bloku wait_key ; cekani na klavesu select_bitplane_for_read 3 ; vyber ctvrte bitove roviny pro cteni select_bitplanes_for_write 8 ; vyber ctvrte bitove roviny pro zapis call bitblt ; prenos bloku wait_key ; cekani na klavesu exit ; navrat do DOSu ; operace BitBLT z prvni poloviny obrazovky na druhou polovinu bitblt: mov ax, 0xa000 ; video RAM v textovem rezimu mov es, ax mov ds, ax mov di, 640*240/8 ; nyni ES:DI obsahuje adresu pixelu ve video RAM na 240 radku xor si, si ; nyni DS:SI obsahuje adresu prvniho pixelu ve video RAM mov cx, 640*240/8 ; pocet prenesenych bajtu rep movsb ; blokovy prenos po bajtech ret ; hotovo draw_color_lines: 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, 15 ; barva call putpixel ; vykreslení pixelu pop ax push ax mov cl, 7 ; barva add ax, 10 ; horizontalni posun useky call putpixel ; vykreslení pixelu pop ax push ax mov cl, 1 ; barva add ax, 20 ; horizontalni posun useky call putpixel ; vykreslení pixelu pop ax push ax mov cl, 2 ; barva add ax, 30 ; horizontalni posun useky call putpixel ; vykreslení pixelu pop ax push ax mov cl, 4 ; barva add ax, 40 ; 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 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 select_bitplanes_for_write al 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 ; hotovo
15. Obrazovka před blokovým přenosem a po provedení blokového přenosu
Postupný přenos obsahu jednotlivých bitových rovin je zcela jednoduché si vizualizovat – postačuje totiž mezi jednotlivé přenosy vložit expanzi makra pro čekání na stisk klávesy: Můžeme tak sledovat, jak přesně jednotlivé operace vypadají na obrazovce:
Obrázek 16: Stav obrazovky ještě před zahájením blokových přenosů.
Obrázek 17: V prvním kroku se korektně přenesl obsah první bitové roviny (bitplane 0) s modrou složkou (mezitím byla modrá „odebrána“ z pravé dolní části obrazu).
Obrázek 18: Ve druhém kroku se korektně přenesl obsah druhé bitové roviny (bitplane 1) se zelenou složkou. Nyní tedy vidíme kombinace modré a zelené.
Obrázek 19: Ve třetím kroku se korektně přenesl obsah třetí bitové roviny (bitplane 2) s červenou složkou. Nyní tedy vidíme kombinace modré, zelené a červené, ovšem vše s nízkou intenzitou. V pravé dolní části obrazu zbyla pouze jediná šedá úsečka – černé pixely s vysokou intenzitou.
Obrázek 20: Dokončení přenosu obsahu čtvrté bitové roviny (bitplane 3). Nyní je již vše zcela korektní.
16. Realizace operace typu BitBLT podprogramem
Postupná expanze maker pro výběr bitových rovin pro čtení a zápis i postupné volání „naivní“ operace BitBLT ve skutečnosti vede ke zbytečně dlouhému i relativně pomalému kódu. Proto si ukažme, jakým způsobem je možné tento problém vyřešit poněkud lepším způsobem. Nejprve si nadefinujeme pole osmi konstant typu byte. Tyto konstanty obsahují index roviny pro čtení následovaný bitovým polem s rovinami pro zápis. To celé se opakuje 4×:
Rovina pro čtení | Bitové pole s rovinami pro zápis |
---|---|
0 | 1 = 0b0001 |
1 | 2 = 0b0010 |
2 | 4 = 0b0100 |
3 | 8 = 0b1000 |
V assembleru je zápis tohoto neměnného pole snadný:
.regs: db 0, 1, 1, 2, 2, 4, 3, 8
Dále si nadefinujeme podprogram pro přenos části vybrané bitové roviny blokovou operací typu rep movsb (nebo i po slovech). To již velmi dobře známe:
bitblt_one_bitplane: mov di, 640*240/8 ; nyni ES:DI obsahuje adresu pixelu ve video RAM na 240 radku xor si, si ; nyni DS:SI obsahuje adresu prvniho pixelu ve video RAM mov cx, 640*240/8 ; pocet prenesenych bajtu rep movsb ; blokovy prenos po bajtech ret ; hotovo
Celá operace BitBLT nastaví (jedenkrát!) segmentové registry a postupně provede čtyři blokové přenosy s využitím již výše nadefinovaného pole .regs:
; operace BitBLT z prvni poloviny obrazovky na druhou polovinu bitblt: mov ax, 0xa000 ; video RAM v textovem rezimu mov es, ax mov ds, ax mov bx, .regs ; tabulka s mapovanim cteni->zapis mov cx, 4 ; pocet bitovych rovin pro prenos .all_bitplanes: mov dx, GRAPHICS_REGISTER mov al, READ_MAP_SELECT mov ah, cs:[bx] ; nacteni indexu bitove roviny inc bx ; posun v tabulce out dx, ax ; vyber bitove roviny pro cteni mov dx, SEQUENCER_INDEX mov al, BITPLANE_SELECTOR mov ah, cs:[bx] ; vyber bitovych rovin pro zapis inc bx ; posun v tabulce out dx, ax ; vyber registru sekvenceru ; a zapis masky bitovych rovin push cx call bitblt_one_bitplane pop cx loop .all_bitplanes ret
17. Úplný zdrojový kód dnešního pátého demonstračního příkladu
Dnešní pátý a současně i poslední demonstrační příklad vypadá následovně:
; Graficky rezim karty VGA s rozlisenim 640x480 pixelu. ; Zmena barvovych rovin, do kterych se zapisuje. ; Vykresleni barevnych usecek. ; Prenos casti obrazu operaci typu BitBLT - nyni jiz korektni. ; Vyber bitovych rovin pro zapis. ; Vyber bitove roviny pro cteni. ; ; preklad pomoci: ; nasm -f bin -o vga.com vga_bitblt_5.asm ; ; nebo pouze: ; nasm -o vga.com vga_bitblt_5.asm ;----------------------------------------------------------------------------- ; I/O porty karty EGA/VGA GRAPHICS_REGISTER equ 0x3ce SEQUENCER_INDEX equ 0x3c4 SEQUENCER_DATA equ 0x3c5 ; registry karty EGA/VGA BITPLANE_SELECTOR equ 0x02 ; sequencer READ_MAP_SELECT equ 0x04 ; graphics register ; 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 ; vyber bitove roviny nebo bitovych rovin pro zapis %macro select_bitplanes_for_write 1 mov al, %1 ; bitova rovina mov dx, SEQUENCER_INDEX mov ah, BITPLANE_SELECTOR xchg ah, al out dx, ax ; vyber registru sekvenceru ; a zapis masky bitovych rovin %endmacro ; vyber bitove roviny pro cteni %macro select_bitplane_for_read 1 mov dx, GRAPHICS_REGISTER mov al, READ_MAP_SELECT out dx, al ; vyber VGA registru pro zapis inc dx, mov al, %1 ; zmena VGA registru out dx, al %endmacro ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: gfx_mode 0x12 ; nastaveni rezimu 640x480 se sestnacti barvami call draw_color_lines wait_key ; cekani na klavesu call bitblt ; prenos bloku wait_key ; cekani na klavesu exit ; navrat do DOSu ; operace BitBLT z prvni poloviny obrazovky na druhou polovinu bitblt: mov ax, 0xa000 ; video RAM v textovem rezimu mov es, ax mov ds, ax mov bx, .regs ; tabulka s mapovanim cteni->zapis mov cx, 4 ; pocet bitovych rovin pro prenos .all_bitplanes: mov dx, GRAPHICS_REGISTER mov al, READ_MAP_SELECT mov ah, cs:[bx] ; nacteni indexu bitove roviny inc bx ; posun v tabulce out dx, ax ; vyber bitove roviny pro cteni mov dx, SEQUENCER_INDEX mov al, BITPLANE_SELECTOR mov ah, cs:[bx] ; vyber bitovych rovin pro zapis inc bx ; posun v tabulce out dx, ax ; vyber registru sekvenceru ; a zapis masky bitovych rovin push cx call bitblt_one_bitplane pop cx loop .all_bitplanes ret .regs: db 0, 1, 1, 2, 2, 4, 3, 8 bitblt_one_bitplane: mov di, 640*240/8 ; nyni ES:DI obsahuje adresu pixelu ve video RAM na 240 radku xor si, si ; nyni DS:SI obsahuje adresu prvniho pixelu ve video RAM mov cx, 640*240/8 ; pocet prenesenych bajtu rep movsb ; blokovy prenos po bajtech ret ; hotovo draw_color_lines: 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, 15 ; barva call putpixel ; vykreslení pixelu pop ax push ax mov cl, 7 ; barva add ax, 10 ; horizontalni posun useky call putpixel ; vykreslení pixelu pop ax push ax mov cl, 1 ; barva add ax, 20 ; horizontalni posun useky call putpixel ; vykreslení pixelu pop ax push ax mov cl, 2 ; barva add ax, 30 ; horizontalni posun useky call putpixel ; vykreslení pixelu pop ax push ax mov cl, 4 ; barva add ax, 40 ; 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 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 select_bitplanes_for_write al 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 ; hotovo
18. Blokové přenosy s využitím 32bitového záchytného registru latche
I přesto, že je výše uvedené řešení blokového přenosu efektivnější, než expanze mnoha maker, zdaleka se nejedná o rychlou operaci, protože data se přenáší mezi videopamětí přes CPU a tedy i přes sběrnici. I při využití 16bitového přenosu je tedy nutné vždy načíst data z video paměti, přenést je do CPU a následně je zapsat zpět do video paměti.
I z tohoto důvodu je v grafické kartě VGA implementován takzvaný záchytný registr neboli latch, který má šířku 32 bitů. Při čtení z video RAM se – nezávisle na vybrané bitové rovině – do latche přečte obsah všech čtyř bitových rovin, konkrétně z každé roviny jeden bajt. A při zápisu lze zvolit takový režim, že se bude ignorovat bajt poslaný z CPU a namísto něho se využije oněch 32 bitů z latche. Výsledkem je, že i když se fyzicky bude přenášet jen jediný bajt, interně karta VGA přenese 32 bitů a tedy zkopíruje osm pixelů (16barevné režimy) nebo čtyři pixely (256barevné režimy). Tímto konceptem, jenž se uplatnil při vykreslování spritů atd., se budeme zabývat příště.
19. Repositář s demonstračními příklady
Demonstrační příklady napsané v assembleru, které jsou určené pro překlad s využitím assembleru NASM, byly uloženy 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 |
69 | vga_gfx_mode_dac3.asm | přímé využití DAC v grafickém režimu 13h | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_dac3.asm |
70 | vga_gfx_mode_unchained_step1.asm | zobrazení barevných pruhů v režimu 13h | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_unchained_step1.asm |
71 | vga_gfx_mode_unchained_step2.asm | vypnutí zřetězení bitových rovin a změna způsobu adresování pixelů | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_unchained_step2.asm |
72 | vga_gfx_mode_unchained_step3.asm | vykreslení barevných pruhů do vybraných bitových rovin | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_unchained_step3.asm |
73 | vga_gfx_mode_320×400.asm | nestandardní grafický režim s rozlišením 320×400 pixelů a 256 barvami | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_320×400.asm |
74 | vga_320×200_image.asm | zobrazení rastrového obrázku ve standardním grafickém režimu 320×200 pixelů | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_image.asm |
75 | vga_320×200_unchained_image1.asm | zobrazení rastrového obrázku v režimu s nezřetězenými rovinami (nekorektní řešení) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_unchained_image1.asm |
76 | vga_320×200_unchained_image2.asm | zobrazení rastrového obrázku v režimu s nezřetězenými rovinami (korektní řešení) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_unchained_image2.asm |
77 | vga_320×400_unchained_image.asm | zobrazení rastrového obrázku v nestandardním režimu 320×400 pixelů | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×400_unchained_image.asm |
78 | vga_vertical_scroll1.asm | vertikální scrolling na kartě VGA v režimu s rozlišením 320×200 pixelů | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_vertical_scroll1.asm |
79 | vga_vertical_scroll2.asm | vertikální scrolling na kartě VGA v režimu s rozlišením 320×400 pixelů | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_vertical_scroll2.asm |
80 | vga_split_screen1.asm | režim split-screen a scrolling, nefunční varianta | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_split_screen1.asm |
81 | vga_split_screen2.asm | režim split-screen a scrolling, plně funkční varianta | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_split_screen2.asm |
82 | vga_horizontal_scroll1.asm | horizontální scrolling bez rozšíření počtu pixelů na virtuálním řádku | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_horizontal_scroll1.asm |
83 | vga_horizontal_scroll2.asm | horizontální scrolling s rozšířením počtu pixelů na virtuálním řádku | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_horizontal_scroll2.asm |
84 | vga_horizontal_scroll3.asm | jemný horizontální scrolling s rozšířením počtu pixelů na virtuálním řádku | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_horizontal_scroll3.asm |
85 | vga_320×240_image.asm | nastavení grafického režimu Mode-X, načtení a vykreslení obrázku, scrolling | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×240_image.asm |
86 | io.asm | knihovna maker pro I/O operace | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/io.asm |
87 | vga_lib.asm | knihovna maker a podprogramů pro programování karty VGA | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_lib.asm |
88 | vga_320×240_lib.asm | nastavení grafického režimu Mode-X, tentokrát knihovními funkcemi | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×240_lib.asm |
89 | vga_bitblt1.asm | první (naivní) implementace operace BitBLT | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_bitblt1.asm |
90 | vga_bitblt2.asm | operace BitBLT s výběrem bitových rovin pro zápis | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_bitblt2.asm |
91 | vga_bitblt3.asm | operace BitBLT s výběrem bitových rovin pro čtení i zápis | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_bitblt3.asm |
92 | vga_bitblt4.asm | korektní BitBLT pro 16barevný režim, realizace makry | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_bitblt4.asm |
93 | vga_bitblt5.asm | korektní BitBLT pro 16barevný režim, realizace podprogramem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_bitblt5.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 - Instruction Format in 8086 Microprocessor
https://www.includehelp.com/embedded-system/instruction-format-in-8086-microprocessor.aspx - How to use „AND,“ „OR,“ and „XOR“ modes for VGA Drawing
https://retrocomputing.stackexchange.com/questions/21936/how-to-use-and-or-and-xor-modes-for-vga-drawing - VGA Hardware
https://wiki.osdev.org/VGA_Hardware