Obsah
1. Nestandardní grafické režimy karty VGA
2. Použití DAC v grafickém režimu 13H
3. První demonstrační příklad: vytvoření barvové palety přes DAC v režimu 13H
5. Pomocná makra pro změnu konfigurace karty VGA
6. Vykreslení barevných bloků se zapnutým zřetězením bitových rovin
7. Vypnutí zřetězení bitových rovin
8. Vykreslení barevných bloků s vypnutým zřetězením bitových rovin
9. Vykreslení barevných bloků s výběrem bitových rovin, do nichž se provádí zápis
10. Úplný zdrojový kód demonstračního příkladu
11. Nestandardní grafický režim s rozlišením 320×400 pixelů
13. Vykreslení rastrového obrázku ve standardních i nestandardních režimech s 256 barvami
14. Rastrový obrázek ve standardním režimu 13h
15. Výsledek po vypnutí zřetězení bitových rovin
16. Korektní vykreslení rastrového obrázku při vypnutí zřetězení bitových rovin
17. Úplný zdrojový kód příkladu pro vykreslení obrázku při vypnutí zřetězení bitových rovin
18. Zobrazení rastrového obrázku v režimu s rozlišením 320×400 pixelů
19. Repositář s demonstračními příklady
1. Nestandardní grafické režimy karty VGA
V předchozích dvou částech seriálu o tvorbě her a grafických dem na platformě IBM PC jsme se zaměřili na popis standardních textových režimů karty VGA, který byl následovaný popisem standardních grafických režimů. Ovšem grafická karta VGA byla z velké části kompatibilní s předchozími kartami společnosti IBM, tj. s kartami MDA, CGA i EGA. To ovšem znamenalo, že musela být široce konfigurovatelná. Navíc VGA podporovala grafický režim s rozlišením 320×200 pixelů s 256 barvami, jenž zvláštním způsobem kombinoval (řetězil) jednotlivé bitové roviny. Přidán byl i DAC se svou vlastní barvovou paletou. Výsledkem byla grafická karta, na níž bylo možné realizovat prakticky neomezené množství nestandardních grafických režimů (a vlastně i režimů textových). Dnes si ukážeme základy konfigurace těchto režimů.
Obrázek 1: Hra Syndicate využívala jak grafický režim s 256 barvami, tak i režim pouze šestnáctibarevný (viz další screenshoty).
2. Použití DAC v grafickém režimu 13H
V předchozím článku jsme si řekli, že v 16barevných grafických režimech je práce s barvami poněkud problematická, protože se interně provádí dvojí mapování hodnot: hodnota pixelu je nejdříve převedena přes LUT tabulku s 16 barvami na barvové kódy a ty jsou následně poslány do DAC, kde je provedeno druhé mapování. Výsledek je složitý na programování a většinou se řeší tak, že první barvová paleta obsahuje hodnoty 0..15.
Obrázek 2: Herní prostředí hry Syndicate v šestnáctibarevném režimu 640×480.
V grafickém režimu s 256 barvami (to je jen režim 13H) je situace snazší, protože se používá pouze DAC a mapování je snadné: hodnota pixelu 0..255 je v DAC převedena na trojici šestibitových hodnot R, G a B, které jsou přímo poslány do monitoru. A změnu hodnot v DAC již dobře známe:
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
Obrázek 3: Syndicate: futuristické stavby budoucnosti.
3. První demonstrační příklad: vytvoření barvové palety přes DAC v režimu 13H
Dnešní první demonstrační příklad ukazuje využití DAC pro konfiguraci barvové palety ve standardním grafickém režimu 13H. Paleta bude obsahovat několik barvových gradientů, které jsou dobře patrné na následujícím obrázku (každý gradient obsahuje 64 barev a každý obrazový řádek je vykreslen jednou konstantní barvou):
Obrázek 3: Výsledek získaný po překladu a spuštění dnešního prvního demonstračního příkladu: před modifikací DAC se používají standardní barvy.
Obrázek 4: Výsledek získaný po překladu a spuštění dnešního prvního demonstračního příkladu po modifikaci DAC.
Úplný zdrojový kód tohoto demonstračního příkladu vypadá následovně:
; Graficky rezim karty VGA s rozlisenim 320x200 pixelu. ; 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_3.asm ; ; nebo pouze: ; nasm -o vga.com vga_gfx_mode_dac_3.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 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 dl, 0 ; pocitadlo radku opak: call draw_line ; vykresleni radku barvou v DL inc dl ; dalsi barva cmp dl, 199 ; posledni radek na obrazovce? jne opak ; ne? opakujeme wait_key ; cekani na klavesu mov ax, 0x1010 ; cislo sluzby a podsluzby VGA BIOSu xor cl, cl ; hodnoty barvovych slozek xor dh, dh ; -//- next_dac: mov ch, bl ; prvni barvova slozka cmp bl, 64 ; nastavit i dalsi nebo ne? ja skip_g mov cl, ch ; druha barvova slozka skip_g: cmp bl, 128 ; nastavit i dalsi nebo ne? ja skip_b mov dh, ch ; treti barvova slozka skip_b: int 0x10 ; modifikace mapovani v DAC inc bl ; zvysit index v DAC jnz next_dac ; nastavit dalsi barvu, dokud nedosahneme hodnoty 256 wait_key ; cekani na klavesu exit ; navrat do DOSu draw_line: mov cx, 320 ; pocitadlo pixelu na radku mov al, dl ; barva rep stosb ; vyplnit cely radek ret ; hotovo
4. Cesta k režimu X
V navazujících kapitolách se zaměříme na popis některých způsobů modifikace standardního grafického režimu 13h (rozlišení 320×200, 256 barev) tak, aby vznikly další (nestandardní) režimy, které z různých důvodů programátorům více vyhovovaly. O některých důvodech jsme se již zmiňovali v úvodní kapitole. Jedná se například o možnost použití vyššího rozlišení, zobrazení čtvercových pixelů, podporu double bufferingu či dokonce tripple bufferingu, hardwarový horizontální i vertikální scrolling atd.
Modifikace grafického režimu 13h typicky vyžaduje provedení těchto kroků (některé je nutné provést, jiné závisí na výsledném režimu):
- Vypnutí zřetězení bitových rovin, protože v opačném případě nelze využít více, než 65536 pixelů.
- Změnu způsobu adresování pixelů v bitových rovinách tak, aby zápis jednoho bajtu odpovídal změně jednoho pixelu (256 barev) v předem vybrané bitové rovině nebo bitových rovinách (zapisovat lze až 4 pixely současně jedinou bajtovou operací, nebo 8 pixelů operací se 16bitovým slovem).
- Vypnutí dvojího opakování zobrazení každého obrazového řádku. Tímto trikem lze velmi snadno zvětšit vertikální rozlišení z 200 pixelů na 400 pixelů (nebo v režimu X z 240 pixelů na 480 pixelů atd. atd.).
- Modifikace adresy ve video RAM, od níž se provádí vykreslování. Tím můžeme realizovat scrolling i double či tripple buffering.
- Změna počtu bajtů na obrazovém řádku. Typicky nutné při realizaci horizontálního scrollingu.
- Modifikace registru, který umožňuje rozdělit obrazovku na dvě části, z nichž jedna začíná na pevné adrese a druhá na modifikovatelné adrese. Tímto trikem se realizuje režim split screen.
- Modifikace registrů CRTC (čítače a komparátory), čímž můžeme měnit horizontální i vertikální rozlišení, a to až do takové míry, kterou již monitory nemusí dokázat zobrazit.
- Výběr krystalu použitého pro generování pixel clock a nepřímo též řádkové a snímkové frekvence.
Pochopitelně budeme postupovat krok za krokem, protože i například realizace režimu X (Mode-X, X-mode) vyžaduje hned několik různých operací, které nemusí být na první pohled zcela pochopitelné.
5. Pomocná makra pro změnu konfigurace karty VGA
Nejprve si připravíme pomocná makra, která budeme volat při změně konfigurace karty VGA. Prozatím se bude jednat o dvojici maker, jelikož je nutné měnit jak řídicí registry sekvencéru, tak i registry CRTC (ty se snaží být zpětně kompatibilní jak s kartou EGA, tak i CGA, i když ve VGA již nenalezneme řadič Motorola 6845):
; nastaveni jednoho registru sekvenceru %macro set_sequencer_register 2 mov dx, SEQUENCER_INDEX mov al, %1 ; ridici registr out dx, al inc dx mov al, %2 ; hodnota zapisovana do registru out dx, al %endmacro ; nastaveni jednoho CRTC registru %macro set_crtc_register 2 mov dx, CRTC_INDEX mov al, %1 ; ridici registr (CRTC) out dx, al inc dx mov al, %2 ; hodnota zapisovana do registru out dx, al %endmacro
Připravíme si i adresy I/O portů sekvencéru a CRTC, ale i adresy některých důležitých registrů, ke kterým budeme přistupovat:
; registry karty VGA SEQUENCER_INDEX equ 0x3c4 SEQUENCER_DATA equ 0x3c5 CRTC_INDEX equ 0x3d4 CRTC_DATA equ 0x3d5 BITPLANE_SELECTOR equ 0x02 MEMORY_MODE_REGISTER equ 0x04 ; sekvencer UNDERLINE_LOCATION equ 0x14 ; CRTC MODE_CONTROL equ 0x17 ; CRTC
A konečně poslední makro již známe – slouží pro výběr bitové roviny nebo rovin, do kterých se bude provádět zápis barev pixelů:
; 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
6. Vykreslení barevných bloků se zapnutým zřetězením bitových rovin
Vypnutí zřetězení bitových rovin budeme provádět postupně. Nejdříve si připravíme kostru příkladu se všemi potřebnými makry určenými pro konfiguraci grafické karty VGA. V tomto příkladu se nejprve nastaví standardní grafický režim 13H a následně se do něj vykreslí dva barevné bloky, každý o plné šířce 320 pixelů a výšce 25 pixelů. Výsledná obrazovka by měla vypadat následovně:
Obrázek 5: Dva barevné bloky vykreslené s využitím standardního režimu 13H.
Následuje úplný zdrojový kód tohoto demonstračního příkladu:
; Graficky rezim karty VGA s rozlisenim 320x200 pixelu. ; Vypnuti zretezeni bitovych rovin. ; ; preklad pomoci: ; nasm -f bin -o vga.com vga_gfx_mode_unchained_step_1.asm ; ; nebo pouze: ; nasm -o vga.com vga_gfx_mode_unchained_step_1.asm ;----------------------------------------------------------------------------- ; registry karty VGA SEQUENCER_INDEX equ 0x3c4 SEQUENCER_DATA equ 0x3c5 CRTC_INDEX equ 0x3d4 CRTC_DATA equ 0x3d5 BITPLANE_SELECTOR equ 0x02 MEMORY_MODE_REGISTER equ 0x04 ; sekvencer UNDERLINE_LOCATION equ 0x14 ; CRTC MODE_CONTROL equ 0x17 ; CRTC ;----------------------------------------------------------------------------- ; 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 ; nastaveni jednoho registru sekvenceru %macro set_sequencer_register 2 mov dx, SEQUENCER_INDEX mov al, %1 ; ridici registr out dx, al inc dx mov al, %2 ; hodnota zapisovana do registru out dx, al %endmacro ; nastaveni jednoho CRTC registru %macro set_crtc_register 2 mov dx, CRTC_INDEX mov al, %1 ; ridici registr (CRTC) out dx, al inc dx mov al, %2 ; hodnota zapisovana do registru out dx, al %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 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 al, 3 ; kod barvy pixelu call fill_block mov al, 4 ; kod barvy pixelu call fill_block wait_key ; cekani na klavesu exit ; navrat do DOSu fill_block: mov cx, 320*200/8 ; pocet zapisovanych pixelu (pixel==bajt) opak: stosb ; zapis barvy pixelu loop opak ; opakujeme CX-krat ret ; hotovo
7. Vypnutí zřetězení bitových rovin
Naším druhým úkolem bude změna způsobu řetězení bitových rovin (tedy vlastně vypnutí jejich zřetězení) a modifikace způsobu adresování pixelů v těchto rovinách. Připomeňme si, že standardní režim 13h je zvláštní tím (a zcela se vymyká ostatním podporovaným režimům), že barvy pixelů jsou z pohledu programátora uloženy lineárně za sebou, tj. na adrese 0×a000:0000 je barva pixelu v levém horním rohu, na adrese 0×a000:0001 je adresa druhého pixelu na řádku atd. Interně je ovšem první pixel uložen v první bitové rovině, druhý pixel ve druhé rovině, … pátý pixel opět v první rovině atd. Z každé bitové roviny je využita jen 1/4 jejich kapacity.
Obrázek 5: Struktura obrazové paměti v grafickém režimu 13H.
Vypnutím zřetězení dosáhneme toho, že pixely již nebudou z pohledu programátora uloženy lineárně za sebou, což znamená, že přímým adresováním bude možné vybrat vždy čtyři pixely „pod sebou“, tj. podobně jako v režimu 640×480 pixelů (podrobnosti si ukážeme). A navíc je nutné ještě modifikovat způsob adresování modifikací dalších dvou registrů sekvencéru karty VGA. Jedná se o registry a . Celá operace „vypnutí zřetězení“ se tedy realizuje následovně:
gfx_mode 0x13 ; nastaveni rezimu 320x200 s 256 barvami set_sequencer_register MEMORY_MODE_REGISTER, 0x06 ; vypnuti zretezeni + povoleni 256 kB RAM set_crtc_register UNDERLINE_LOCATION, 0x00 ; vypnuti double word rezimu set_crtc_register MODE_CONTROL, 0xe3 ; zapnuti bytoveho rezimu
8. Vykreslení barevných bloků s vypnutým zřetězením bitových rovin
Pokud se nyní pokusíme vykreslit dvojici barevných pruhů přesně tak, jako tomu bylo v příkladu předchozím, bude výsledek vypadat zcela odlišně, protože každý zápis do obrazové paměti v takovém případě změní čtyři pixely (vizuálně uložených vedle sebe, interně uložených „pod sebou“ ve čtyřech bitových rovinách). Nyní se tedy vyplní větší část obrazovky, protože každý zápis změní čtyři pixely:
Obrázek 6: Nyní budou barevné pruhy zobrazeny přes celou obrazovku.
V dalším demonstračním příkladu je realizována výše popsaná operace vypnutí zřetězení bitových rovin a změna způsobu adresování pixelů v bitových rovinách:
; Graficky rezim karty VGA s rozlisenim 320x200 pixelu. ; Vypnuti zretezeni bitovych rovin. ; ; preklad pomoci: ; nasm -f bin -o vga.com vga_gfx_mode_unchained_step_2.asm ; ; nebo pouze: ; nasm -o vga.com vga_gfx_mode_unchained_step_2.asm ;----------------------------------------------------------------------------- ; registry karty VGA SEQUENCER_INDEX equ 0x3c4 SEQUENCER_DATA equ 0x3c5 CRTC_INDEX equ 0x3d4 CRTC_DATA equ 0x3d5 BITPLANE_SELECTOR equ 0x02 MEMORY_MODE_REGISTER equ 0x04 ; sekvencer UNDERLINE_LOCATION equ 0x14 ; CRTC MODE_CONTROL equ 0x17 ; CRTC ;----------------------------------------------------------------------------- ; 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 ; nastaveni jednoho registru sekvenceru %macro set_sequencer_register 2 mov dx, SEQUENCER_INDEX mov al, %1 ; ridici registr out dx, al inc dx mov al, %2 ; hodnota zapisovana do registru out dx, al %endmacro ; nastaveni jednoho CRTC registru %macro set_crtc_register 2 mov dx, CRTC_INDEX mov al, %1 ; ridici registr (CRTC) out dx, al inc dx mov al, %2 ; hodnota zapisovana do registru out dx, al %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 0x13 ; nastaveni rezimu 320x200 s 256 barvami set_sequencer_register MEMORY_MODE_REGISTER, 0x06 ; vypnuti zretezeni + povoleni 256 kB RAM set_crtc_register UNDERLINE_LOCATION, 0x00 ; vypnuti double word rezimu set_crtc_register MODE_CONTROL, 0xe3 ; zapnuti bytoveho rezimu 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 al, 3 ; kod barvy pixelu call fill_block mov al, 4 ; kod barvy pixelu call fill_block wait_key ; cekani na klavesu exit ; navrat do DOSu fill_block: mov cx, 320*200/8 ; pocet zapisovanych pixelu (pixel==bajt) opak: stosb ; zapis barvy pixelu loop opak ; opakujeme CX-krat ret ; hotovo
9. Vykreslení barevných bloků s výběrem bitových rovin, do nichž se provádí zápis
Nyní si vyzkoušejme, jakou výslednou obrazovku získáme v případě, že budeme při vyplňování určovat, která bitová rovina nebo roviny se mají povolit. Nejprve běžným způsobem vyplníme první polovinu obrazovky a poté při vyplňování druhé poloviny nejprve povolíme jedinou bitovou rovinu:
select_bitplane 1 ; zapis jen do jedine bitove roviny mov al, 4 ; kod barvy pixelu call fill_block
Výsledek:
Obrázek 7: Při vybarvování spodní poloviny obrázku byla povolena jediná bitová rovina.
Dále povolme tři bitové roviny – první, druhou a třetí:
sub di, 320*200/8 ; posun zpet select_bitplane 7 ; zapis jen do tri bitovych rovin mov al, 5 ; kod barvy pixelu call fill_block
Výsledek bude odlišný:
Obrázek 8: Při vybarvování spodní poloviny obrázku byly povoleny tři bitové roviny.
A konečně povolíme zápis do všech čtyř bitových rovin:
sub di, 320*200/8 ; posun zpet select_bitplane 15 ; zapis jen vsech ctyr bitovych rovin mov al, 6 ; kod barvy pixelu call fill_block
A takto bude vypadat výsledná podoba obrazovky:
Obrázek 9: Při vybarvování spodní poloviny obrázku byly povoleny všechny čtyři bitové roviny.
10. Úplný zdrojový kód demonstračního příkladu
Opět si uveďme, jak vypadá úplný zdrojový kód příkladu, který po svém překladu a spuštění vykreslí barevné pruhy do vybraných bitových rovin (mezi jednotlivými kroky je zapotřebí stisknout klávesu):
; Graficky rezim karty VGA s rozlisenim 320x200 pixelu. ; Vypnuti zretezeni bitovych rovin. ; ; preklad pomoci: ; nasm -f bin -o vga.com vga_gfx_mode_unchained_step_3.asm ; ; nebo pouze: ; nasm -o vga.com vga_gfx_mode_unchained_step_3.asm ;----------------------------------------------------------------------------- ; registry karty VGA SEQUENCER_INDEX equ 0x3c4 SEQUENCER_DATA equ 0x3c5 CRTC_INDEX equ 0x3d4 CRTC_DATA equ 0x3d5 BITPLANE_SELECTOR equ 0x02 MEMORY_MODE_REGISTER equ 0x04 ; sekvencer UNDERLINE_LOCATION equ 0x14 ; CRTC MODE_CONTROL equ 0x17 ; CRTC ;----------------------------------------------------------------------------- ; 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 ; nastaveni jednoho registru sekvenceru %macro set_sequencer_register 2 mov dx, SEQUENCER_INDEX mov al, %1 ; ridici registr out dx, al inc dx mov al, %2 ; hodnota zapisovana do registru out dx, al %endmacro ; nastaveni jednoho CRTC registru %macro set_crtc_register 2 mov dx, CRTC_INDEX mov al, %1 ; ridici registr (CRTC) out dx, al inc dx mov al, %2 ; hodnota zapisovana do registru out dx, al %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 0x13 ; nastaveni rezimu 320x200 s 256 barvami set_sequencer_register MEMORY_MODE_REGISTER, 0x06 ; vypnuti zretezeni + povoleni 256 kB RAM set_crtc_register UNDERLINE_LOCATION, 0x00 ; vypnuti double word rezimu set_crtc_register MODE_CONTROL, 0xe3 ; zapnuti bytoveho rezimu 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 al, 3 ; kod barvy pixelu call fill_block select_bitplane 1 ; zapis jen do jedine bitove roviny mov al, 4 ; kod barvy pixelu call fill_block wait_key ; cekani na klavesu sub di, 320*200/8 ; posun zpet select_bitplane 7 ; zapis jen do tri bitovych rovin mov al, 5 ; kod barvy pixelu call fill_block wait_key ; cekani na klavesu sub di, 320*200/8 ; posun zpet select_bitplane 15 ; zapis jen vsech ctyr bitovych rovin mov al, 6 ; kod barvy pixelu call fill_block wait_key ; cekani na klavesu exit ; navrat do DOSu fill_block: mov cx, 320*200/8 ; pocet zapisovanych pixelu (pixel==bajt) opak: stosb ; zapis barvy pixelu loop opak ; opakujeme CX-krat ret ; hotovo
11. Nestandardní grafický režim s rozlišením 320×400 pixelů
Ve chvíli, kdy je vypnuté zřetězení bitových rovin, máme k dispozici v každé rovině 64kB paměti, což při 80 pixelech na řádku znamená, že existuje 819 potenciálně zobrazitelných obrazových řádků. Tolik řádků sice monitory VGA nezvládají zobrazit (a ani karta nemá tak rychlé obnovování obrazu), ovšem můžeme velmi snadno provést přepnutí z 200 řádků na 400 řádků. Nejprve se přepneme do režimu s vypnutím zřetězením bitových rovin, což již dobře známe:
set_sequencer_register MEMORY_MODE_REGISTER, 0x06 ; vypnuti zretezeni + povoleni 256 kB RAM set_crtc_register UNDERLINE_LOCATION, 0x00 ; vypnuti double word rezimu set_crtc_register MODE_CONTROL, 0xe3 ; zapnuti bytoveho rezimu
Dále pozměníme bity v CRTC registru MAXIMUM_SCAN_LINE, a to následovně:
Bit | Hodnota | Stručný popis |
---|---|---|
0–4 | 0 | maximum scan line: počet opakování každého řádku-1, musí být nastaveno na nulu |
5 | 0 | start vertical blanking: devátý bit, lze ponechat na 0 |
6 | 1 | line compare: můžeme ponechat na 1 |
7 | 0 | scan doubling: nutno zakázat |
Poslední krok konfigurace karty VGA tedy bude vypadat takto:
set_crtc_register MAXIMUM_SCAN_LINE, 0x40 ; 400 grafickych radku
Výsledky:
Obrázek 10: Barevné pruhy zobrazené v grafickém režimu s rozlišením 320×400 pixelů.
Obrázek 11: Barevné pruhy zobrazené v grafickém režimu s rozlišením 320×400 pixelů.
12. Demonstrační příklad: nastavení a použití nestandardního grafického režimu s rozlišením 320×400 pixelů
Pro úplnost se podívejme na úplný zdrojový kód příkladu, který provede přepnutí do grafického režimu s rozlišením 320×400 pixelů:
; Graficky rezim karty VGA s rozlisenim 320x400 pixelu. ; Vypnuti zretezeni bitovych rovin. ; ; preklad pomoci: ; nasm -f bin -o vga.com vga_gfx_mode_320x400.asm ; ; nebo pouze: ; nasm -o vga.com vga_gfx_mode_320x400.asm ;----------------------------------------------------------------------------- ; registry karty VGA SEQUENCER_INDEX equ 0x3c4 SEQUENCER_DATA equ 0x3c5 CRTC_INDEX equ 0x3d4 CRTC_DATA equ 0x3d5 BITPLANE_SELECTOR equ 0x02 MEMORY_MODE_REGISTER equ 0x04 ; sekvencer UNDERLINE_LOCATION equ 0x14 ; CRTC MODE_CONTROL equ 0x17 ; CRTC MAXIMUM_SCAN_LINE equ 0x09 ; CRTC ;----------------------------------------------------------------------------- ; 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 ; nastaveni jednoho registru sekvenceru %macro set_sequencer_register 2 mov dx, SEQUENCER_INDEX mov al, %1 ; ridici registr out dx, al inc dx mov al, %2 ; hodnota zapisovana do registru out dx, al %endmacro ; nastaveni jednoho CRTC registru %macro set_crtc_register 2 mov dx, CRTC_INDEX mov al, %1 ; ridici registr (CRTC) out dx, al inc dx mov al, %2 ; hodnota zapisovana do registru out dx, al %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 0x13 ; nastaveni rezimu 320x200 s 256 barvami set_sequencer_register MEMORY_MODE_REGISTER, 0x06 ; vypnuti zretezeni + povoleni 256 kB RAM set_crtc_register UNDERLINE_LOCATION, 0x00 ; vypnuti double word rezimu set_crtc_register MODE_CONTROL, 0xe3 ; zapnuti bytoveho rezimu set_crtc_register MAXIMUM_SCAN_LINE, 0x40 ; 400 grafickych radku 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 al, 3 ; kod barvy pixelu call fill_block select_bitplane 1 ; zapis jen do jedine bitove roviny mov al, 4 ; kod barvy pixelu call fill_block wait_key ; cekani na klavesu sub di, 320*200/8 ; posun zpet select_bitplane 7 ; zapis jen do tri bitovych rovin mov al, 5 ; kod barvy pixelu call fill_block wait_key ; cekani na klavesu exit ; navrat do DOSu fill_block: mov cx, 320*200/8 ; pocet zapisovanych pixelu (pixel==bajt) opak: stosb ; zapis barvy pixelu loop opak ; opakujeme CX-krat ret ; hotovo
13. Vykreslení rastrového obrázku ve standardních i nestandardních režimech s 256 barvami
V předchozích demonstračních příkladech jsme po modifikaci původního standardního grafického režimu 13h pouze vykreslili barevné pruhy. To je sice velmi jednoduchá operace, ale nijak nám neumožňuje si lépe uvědomit, jaká je vlastně organizace video paměti. Proto si ukážeme poněkud sofistikovanější postup, který spočívá v tom, že do obrazové paměti vykreslíme předem připravený rastrový obrázek. Ten bude mít rozlišení přesně 320×200 pixelů a využívá barvovou paletu se stupni šedi (což je opět zjednodušení, abychom nemuseli barvovou paletu načítat z paměti, ale mohli ji přímo programově vygenerovat). Samotný rastrový obrázek je v době překladu uložen v binárním souboru image_320×200.bin a do programového kódu ho přidáme nám již známou volbou:
; pridani binarnich dat s rastrovym obrazkem image: incbin "image_320x200.bin"
14. Rastrový obrázek ve standardním režimu 13h
V prvním demonstračním příkladu, v němž se pokusíme o zobrazení rastrového obrázku, využijeme standardní grafický režim 13h. Prováděné operace budou v tomto případě velmi jednoduché, protože je již všechny dobře známe (pouze se adaptujeme na jiný formát uložení pixelů):
- Nastavení grafického režimu 13h zavoláním příslušné služby BIOSu
- Modifikace barvové palety, a to v tomto případě přímo přes DAC, tedy změnou obsahu tabulky s 256 záznamy, přičemž každý záznam má šest bitů pro každou barvovou složku (tedy jedná se o organizaci 256×18 bitů).
- Inicializace registrů použitých při blokovém přenosu obrázku. Jedná se o segmentové registry, registry použité při adresování a taktéž o programový čítač.
- Vlastní přenos hodnot pixelů. Lze provádět po bajtech nebo po šestnáctibitových slovech. Přenos po bajtech využijeme později v nezřetězených grafických režimech. Samozřejmě je však rychlejší přenos po slovech (a teoreticky po 32bitových slovech, což ovšem naráží na omezenou šířku sběrnice ISA).
Výsledek by měl vypadat následovně:
Obrázek 12: Rastrový obrázek vykreslený ve standardním grafickém režimu 13h.
Následuje výpis celého zdrojového kódu tohoto příkladu:
; Graficky rezim karty VGA s rozlisenim 320x200 pixelu. ; Vykresleni rastroveho obrazku. ; ; preklad pomoci: ; nasm -f bin -o vga.com vga_320x200_image.asm ; ; nebo pouze: ; nasm -o vga.com vga_320x200_image.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 ; paleta ve stupnich sedi %macro grayscale_palette 0 mov ax, 0x1010 ; cislo sluzby a podsluzby VGA BIOSu xor bl, bl ; index barvy next_dac: mov ch, bl ; prvni barvova slozka shr ch, 1 shr ch, 1 mov cl, ch ; druha barvova slozka mov dh, ch ; treti barvova slozka int 0x10 ; modifikace mapovani v DAC inc bl ; zvysit index v DAC jnz next_dac ; nastavit dalsi barvu, dokud nedosahneme hodnoty 256 %endmacro ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: gfx_mode 0x13 ; nastaveni rezimu 320x200 se sestnacti barvami grayscale_palette ; nastaveni palety se stupni sedi mov ax, cs mov ds, ax mov si, image ; nyni DS:SI obsahuje adresu prvniho bajtu v obrazku 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 cx, 320*200/2 ; pocet zapisovanych bajtu (=pixelu) rep movsw ; prenos celeho obrazku wait_key ; cekani na klavesu exit ; navrat do DOSu ; pridani binarnich dat s rastrovym obrazkem image: incbin "image_320x200.bin"
15. Výsledek po vypnutí zřetězení bitových rovin
Nyní navážeme na předchozí demonstrační příklad, ovšem ještě před vykreslením rastrového obrázku (tj. před blokovým přenosem) vypneme zřetězení bitových rovin a nastavíme korektní způsob adresování pixelů v bitových rovinách. V tomto případě již víme, jak dopadneme – vždy čtyři sousední pixely budou obsahovat stejnou barvu (zápis je proveden do všech bitových rovin), což pochopitelně vede k nekorektnímu výsledku. Nicméně nám to umožňuje si ověřit, že obrazová paměť je nyní skutečně z pohledu programátora organizována zcela odlišným způsobem, který má svoje výhody, ale i nevýhody.
Při čtení pixelů z obrázku vždy po přečtení (a přenosu) jednoho pixelu další tři pixely přeskočíme:
bitblt: lodsb ; nacist bajt z obrazku add si, 3 ; celkove posun o 4 pixely v obrazku stosb ; ulozit do obrazove pameti loop bitblt ; presunout CX pixelu ret
Obrázek 13: Vykreslení obrázku s nezřetězenými rovinami, zápisy jsou provedeny do všech čtyř rovin současně.
Úplný zdrojový kód tohoto demonstračního příkladu vypadá následovně:
; Graficky rezim karty VGA s rozlisenim 320x200 pixelu. ; Vypnuti zretezeni bitovych rovin. ; Vykresleni rastroveho obrazku do vsech bitovych rovin. ; ; preklad pomoci: ; nasm -f bin -o vga.com vga_320x200_unchained_image_1.asm ; ; nebo pouze: ; nasm -o vga.com vga_320x200_unchained_image_1.asm ;----------------------------------------------------------------------------- ; registry karty VGA SEQUENCER_INDEX equ 0x3c4 SEQUENCER_DATA equ 0x3c5 CRTC_INDEX equ 0x3d4 CRTC_DATA equ 0x3d5 BITPLANE_SELECTOR equ 0x02 MEMORY_MODE_REGISTER equ 0x04 ; sekvencer UNDERLINE_LOCATION equ 0x14 ; CRTC MODE_CONTROL equ 0x17 ; CRTC ; 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 ; nastaveni jednoho registru sekvenceru %macro set_sequencer_register 2 mov dx, SEQUENCER_INDEX mov al, %1 ; ridici registr out dx, al inc dx mov al, %2 ; hodnota zapisovana do registru out dx, al %endmacro ; nastaveni jednoho CRTC registru %macro set_crtc_register 2 mov dx, CRTC_INDEX mov al, %1 ; ridici registr (CRTC) out dx, al inc dx mov al, %2 ; hodnota zapisovana do registru out dx, al %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 ; paleta ve stupnich sedi %macro grayscale_palette 0 mov ax, 0x1010 ; cislo sluzby a podsluzby VGA BIOSu xor bl, bl ; index barvy next_dac: mov ch, bl ; prvni barvova slozka shr ch, 1 shr ch, 1 mov cl, ch ; druha barvova slozka mov dh, ch ; treti barvova slozka int 0x10 ; modifikace mapovani v DAC inc bl ; zvysit index v DAC jnz next_dac ; nastavit dalsi barvu, dokud nedosahneme hodnoty 256 %endmacro ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: gfx_mode 0x13 ; nastaveni rezimu 320x200 se sestnacti barvami grayscale_palette ; nastaveni palety se stupni sedi ; mod 320x200 bez zretezeni rovin set_sequencer_register MEMORY_MODE_REGISTER, 0x06 ; vypnuti zretezeni + povoleni 256 kB RAM set_crtc_register UNDERLINE_LOCATION, 0x00 ; vypnuti double word rezimu set_crtc_register MODE_CONTROL, 0xe3 ; zapnuti bytoveho rezimu mov ax, cs mov ds, ax ; zajistit, ze bude mozne adresovat cely obrazek mov ax, 0xa000 ; video RAM v textovem rezimu mov es, ax xor ax, ax ; offset pixelu call move_image_part; prenest obrazek wait_key ; cekani na klavesu exit ; navrat do DOSu move_image_part: mov si, image ; nyni DS:SI obsahuje adresu prvniho bajtu v obrazku add si, ax ; offset pixelu xor di, di ; nyni ES:DI obsahuje adresu prvniho pixelu ve video RAM mov cx, 320*200/4 ; pocet zapisovanych bajtu (=pixelu) bitblt: lodsb ; nacist bajt z obrazku add si, 3 ; celkove posun o 4 pixely v obrazku stosb ; ulozit do obrazove pameti loop bitblt ; presunout CX pixelu ret ; pridani binarnich dat s rastrovym obrazkem image: incbin "image_320x200.bin"
16. Korektní vykreslení rastrového obrázku při vypnutí zřetězení bitových rovin
Jakým způsobem je tedy možné vykreslit rastrový obrázek, v němž jsou pixely uloženy lineárně za sebou, v grafickém režimu, v němž je nutné sousední pixely ukládat do různých bitových rovin? Existují dvě možná řešení tohoto problému:
- Budeme postupně číst lineárně uložené pixely z obrázku a před každým zápisem takového pixelu do obrazové paměti provedeme přepnutí bitové roviny, do které bude prováděn zápis.
- Nebo naopak budeme obrázek číst čtyřikrát, pokaždé jen každý čtvrtý pixel a zápis se v takovém případě provede vždy do jedné (předem zvolené) bitové roviny. Určitou nevýhodou je, že zde nelze použít blokový přenos instrukcímovsb nebo movsw, ale smyčku je nutné explicitně rozepsat (což je pomalejší řešení).
Vzhledem k tomu, že operace výběru bitové roviny roviny je relativně složitá a časově zdlouhavá (instrukce OUT do dvou portů), je výhodnější omezit frekvenci přepínání bitových rovin. Proto bude lepší použít druhý z naznačených přístupů. Přenos celého obrázku rozdělíme na čtvrtiny (vždy se tedy bude vykreslovat každý čtvrtý pixel) a pro jednoduchost celý algoritmus rozepíšeme takovým způsobem, aby byl co nejvíce pochopitelný. Je však samozřejmě možné celý postup přepsat do podoby vnořených programových smyček a neopakovat tak čtyřikrát prakticky stejnou sekvenci instrukcí (to bude vyžadovat počitadlo smyčky, logiku výběru bitových rovin atd. – asi se to ani nevyplatí):
select_bitplane 1 ; prvni bitplane xor ax, ax ; offset pixelu call move_image_part; prenest obrazek wait_key ; cekani na klavesu select_bitplane 2 ; druha bitplane mov ax, 1 ; offset pixelu call move_image_part; prenest obrazek wait_key ; cekani na klavesu select_bitplane 4 ; treti bitplane mov ax, 2 ; offset pixelu call move_image_part; prenest obrazek wait_key ; cekani na klavesu select_bitplane 8 ; ctvrta bitplane mov ax, 3 ; offset pixelu call move_image_part; prenest obrazek wait_key ; cekani na klavesu
Blokový přenos opět využívá triku s přeskočením třech pixelů následujících po přeneseném pixelu. Nyní je ovšem nutno připočítat počáteční offset (AX):
move_image_part: mov si, image ; nyni DS:SI obsahuje adresu prvniho bajtu v obrazku add si, ax ; offset pixelu xor di, di ; nyni ES:DI obsahuje adresu prvniho pixelu ve video RAM mov cx, 320*200/4 ; pocet zapisovanych bajtu (=pixelu) bitblt: lodsb ; nacist bajt z obrazku add si, 3 ; celkove posun o 4 pixely v obrazku stosb ; ulozit do obrazove pameti loop bitblt ; presunout CX pixelu ret
Obrázek 14: Vykreslení první čtvrtiny obrázku.
Obrázek 15: Vykreslení druhé čtvrtiny obrázku.
Obrázek 16: Vykreslení třetí čtvrtiny obrázku.
Obrázek 17: Stav po vykreslení celého obrázku.
17. Úplný zdrojový kód příkladu pro vykreslení obrázku při vypnutí zřetězení bitových rovin
Opět se pro úplnost podívejme, jak vypadá celý zdrojový kód upravený do podoby popsané v předchozí kapitole:
; Graficky rezim karty VGA s rozlisenim 320x200 pixelu. ; Vypnuti zretezeni bitovych rovin. ; Vykresleni rastroveho obrazku postupne do vsech bitovych rovin. ; ; preklad pomoci: ; nasm -f bin -o vga.com vga_320x200_unchained_image_2.asm ; ; nebo pouze: ; nasm -o vga.com vga_320x200_unchained_image_2.asm ;----------------------------------------------------------------------------- ; registry karty VGA SEQUENCER_INDEX equ 0x3c4 SEQUENCER_DATA equ 0x3c5 CRTC_INDEX equ 0x3d4 CRTC_DATA equ 0x3d5 BITPLANE_SELECTOR equ 0x02 MEMORY_MODE_REGISTER equ 0x04 ; sekvencer UNDERLINE_LOCATION equ 0x14 ; CRTC MODE_CONTROL equ 0x17 ; CRTC ; 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 ; nastaveni jednoho registru sekvenceru %macro set_sequencer_register 2 mov dx, SEQUENCER_INDEX mov al, %1 ; ridici registr out dx, al inc dx mov al, %2 ; hodnota zapisovana do registru out dx, al %endmacro ; nastaveni jednoho CRTC registru %macro set_crtc_register 2 mov dx, CRTC_INDEX mov al, %1 ; ridici registr (CRTC) out dx, al inc dx mov al, %2 ; hodnota zapisovana do registru out dx, al %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 ; paleta ve stupnich sedi %macro grayscale_palette 0 mov ax, 0x1010 ; cislo sluzby a podsluzby VGA BIOSu xor bl, bl ; index barvy next_dac: mov ch, bl ; prvni barvova slozka shr ch, 1 shr ch, 1 mov cl, ch ; druha barvova slozka mov dh, ch ; treti barvova slozka int 0x10 ; modifikace mapovani v DAC inc bl ; zvysit index v DAC jnz next_dac ; nastavit dalsi barvu, dokud nedosahneme hodnoty 256 %endmacro ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: gfx_mode 0x13 ; nastaveni rezimu 320x200 se sestnacti barvami grayscale_palette ; nastaveni palety se stupni sedi ; mod 320x200 bez zretezeni rovin set_sequencer_register MEMORY_MODE_REGISTER, 0x06 ; vypnuti zretezeni + povoleni 256 kB RAM set_crtc_register UNDERLINE_LOCATION, 0x00 ; vypnuti double word rezimu set_crtc_register MODE_CONTROL, 0xe3 ; zapnuti bytoveho rezimu mov ax, cs mov ds, ax ; zajistit, ze bude mozne adresovat cely obrazek mov ax, 0xa000 ; video RAM v textovem rezimu mov es, ax select_bitplane 1 ; prvni bitplane xor ax, ax ; offset pixelu call move_image_part; prenest obrazek wait_key ; cekani na klavesu select_bitplane 2 ; druha bitplane mov ax, 1 call move_image_part; prenest obrazek wait_key ; cekani na klavesu select_bitplane 4 ; treti bitplane mov ax, 2 call move_image_part; prenest obrazek wait_key ; cekani na klavesu select_bitplane 8 ; ctvrta bitplane mov ax, 3 call move_image_part; prenest obrazek wait_key ; cekani na klavesu exit ; navrat do DOSu move_image_part: mov si, image ; nyni DS:SI obsahuje adresu prvniho bajtu v obrazku add si, ax ; offset pixelu xor di, di ; nyni ES:DI obsahuje adresu prvniho pixelu ve video RAM mov cx, 320*200/4 ; pocet zapisovanych bajtu (=pixelu) bitblt: lodsb ; nacist bajt z obrazku add si, 3 ; celkove posun o 4 pixely v obrazku stosb ; ulozit do obrazove pameti loop bitblt ; presunout CX pixelu ret ; pridani binarnich dat s rastrovym obrazkem image: incbin "image_320x200.bin"
18. Zobrazení rastrového obrázku v režimu s rozlišením 320×400 pixelů
V předchozím textu jsme si ukázali, jak snadné je zvýšení počtu obrazových řádků z 200 na 400 – pouze vypneme opakování zobrazení toho stejného řádku. Pokud tedy tuto operaci provedeme před vykreslení obrázku (nebo i po něm, na pořadí nezáleží), získáme tento výsledek:
Obrázek 18: Rastrový obrázek zobrazený v režimu 320×400 pixelů.
; Graficky rezim karty VGA s rozlisenim 320x400 pixelu. ; Vypnuti zretezeni bitovych rovin. ; Vykresleni rastroveho obrazku postupne do vsech bitovych rovin. ; ; preklad pomoci: ; nasm -f bin -o vga.com vga_320x400_unchained_image.asm ; ; nebo pouze: ; nasm -o vga.com vga_320x400_unchained_image.asm ;----------------------------------------------------------------------------- ; registry karty VGA SEQUENCER_INDEX equ 0x3c4 SEQUENCER_DATA equ 0x3c5 CRTC_INDEX equ 0x3d4 CRTC_DATA equ 0x3d5 BITPLANE_SELECTOR equ 0x02 MEMORY_MODE_REGISTER equ 0x04 ; sekvencer UNDERLINE_LOCATION equ 0x14 ; CRTC MODE_CONTROL equ 0x17 ; CRTC MAXIMUM_SCAN_LINE equ 0x09 ; CRTC ; 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 ; nastaveni jednoho registru sekvenceru %macro set_sequencer_register 2 mov dx, SEQUENCER_INDEX mov al, %1 ; ridici registr out dx, al inc dx mov al, %2 ; hodnota zapisovana do registru out dx, al %endmacro ; nastaveni jednoho CRTC registru %macro set_crtc_register 2 mov dx, CRTC_INDEX mov al, %1 ; ridici registr (CRTC) out dx, al inc dx mov al, %2 ; hodnota zapisovana do registru out dx, al %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 ; paleta ve stupnich sedi %macro grayscale_palette 0 mov ax, 0x1010 ; cislo sluzby a podsluzby VGA BIOSu xor bl, bl ; index barvy next_dac: mov ch, bl ; prvni barvova slozka shr ch, 1 shr ch, 1 mov cl, ch ; druha barvova slozka mov dh, ch ; treti barvova slozka int 0x10 ; modifikace mapovani v DAC inc bl ; zvysit index v DAC jnz next_dac ; nastavit dalsi barvu, dokud nedosahneme hodnoty 256 %endmacro ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: gfx_mode 0x13 ; nastaveni rezimu 320x200 se sestnacti barvami grayscale_palette ; nastaveni palety se stupni sedi ; mod 320x200 bez zretezeni rovin set_sequencer_register MEMORY_MODE_REGISTER, 0x06 ; vypnuti zretezeni + povoleni 256 kB RAM set_crtc_register UNDERLINE_LOCATION, 0x00 ; vypnuti double word rezimu set_crtc_register MODE_CONTROL, 0xe3 ; zapnuti bytoveho rezimu set_crtc_register MAXIMUM_SCAN_LINE, 0x40 ; 400 grafickych radku mov ax, cs mov ds, ax ; zajistit, ze bude mozne adresovat cely obrazek mov ax, 0xa000 ; video RAM v textovem rezimu mov es, ax select_bitplane 1 ; prvni bitplane xor ax, ax ; offset pixelu call move_image_part; prenest obrazek wait_key ; cekani na klavesu select_bitplane 2 ; druha bitplane mov ax, 1 call move_image_part; prenest obrazek wait_key ; cekani na klavesu select_bitplane 4 ; treti bitplane mov ax, 2 call move_image_part; prenest obrazek wait_key ; cekani na klavesu select_bitplane 8 ; ctvrta bitplane mov ax, 3 call move_image_part; prenest obrazek wait_key ; cekani na klavesu exit ; navrat do DOSu move_image_part: mov si, image ; nyni DS:SI obsahuje adresu prvniho bajtu v obrazku add si, ax ; offset pixelu mov di, 320*100/4 ; nyni ES:DI obsahuje adresu pixelu ve video RAM mov cx, 320*200/4 ; pocet zapisovanych bajtu (=pixelu) bitblt: lodsb ; nacist bajt z obrazku add si, 3 ; celkove posun o 4 pixely v obrazku stosb ; ulozit do obrazove pameti loop bitblt ; presunout CX pixelu ret ; pridani binarnich dat s rastrovym obrazkem image: incbin "image_320x200.bin"
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 |
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 |
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