Nestandardní grafické režimy karty VGA

13. 8. 2024
Doba čtení: 49 minut

Sdílet

 Autor: Bullfrog Productions
Po popisu standardních textových i grafických režimů karty VGA se zaměříme na popis režimů nestandardních. Bude se z velké části jednat o různé úpravy grafického režimu 13H s rozlišením 320×200 pixelů a s 256 barvami.

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

4. Cesta k režimu X

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ů

12. Demonstrační příklad: nastavení a použití nestandardního grafického režimu 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

20. Odkazy na Internetu

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ů.

Poznámka: existuje mnoho důvodů pro použití nestandardních režimů. 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. Některé z těchto konceptů si pochopitelně postupně ukážeme.

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

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):

  1. Vypnutí zřetězení bitových rovin, protože v opačném případě nelze využít více, než 65536 pixelů.
  2. 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).
  3. 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.).
  4. Modifikace adresy ve video RAM, od níž se provádí vykreslování. Tím můžeme realizovat scrolling i double či tripple buffering.
  5. Změna počtu bajtů na obrazovém řádku. Typicky nutné při realizaci horizontálního scrollingu.
  6. 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.
  7. 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.
  8. 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.

pc86

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
Poznámka: povšimněte si, jak nám definice vlastních maker ulehčila programování.

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"
Poznámka: zde je vhodné upozornit na to, že celý rastrový obrázek s rozlišením 320×200 pixelů má velikost 64000 bajtů a do kódového segmentu souborů COM lze uložit jen 65536 bajtů (prakticky vlastně ještě o 256 bajtů méně kvůli tomu, kde začíná programový kód). To znamená, že pro vlastní program nám přibližně zbývá „pouhý“ jeden kilobajt; ovšem jeden kilobajt pro assembler (strojový kód) znamená hodně velký prostor – dokonce existují například šachové algoritmy, které se do něj vejdou (a celá řada dem-inter s velikostí 128 bajtů, 256 bajtů nebo právě onen jeden kilobajt). My sice tak sofistikované algoritmy pochopitelně dělat nebudeme, ale bez problémů si s dostupnou pamětí vystačíme.

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ů):

  1. Nastavení grafického režimu 13h zavoláním příslušné služby BIOSu
  2. 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ů).
  3. 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č.
  4. 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ě.

Poznámka: korektní vykreslení rastrového obrázku s lineárně uloženými pixely v grafickém režimu s nezřetězenými rovinami ovšem vyžaduje odlišný přístup.

Ú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:

  1. 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.
  2. 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
Poznámka: mezi jednotlivé smyčky realizující přenos 1/4 obrazu je vloženo čekání na stisk klávesy, aby bylo dobře patrné, jak vlastně celé vykreslení rastrového obrázku probíhá:

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:

bitcoin_skoleni

Obrázek 18: Rastrový obrázek zobrazený v režimu 320×400 pixelů.

Poznámka: na tomto místě nás může napadnout, proč vlastně nezobrazit nějaký obrázek se skutečným rozlišením 320×400 pixelů? Problém je jediný – takový obrázek už nedokážeme vložit do souborů typu COM a proto je nutné buď použít formát EXE (interně mnohem složitější) nebo využít služby DOSu pro načtení dat z externího souboru. K tomuto problému se ještě vrátíme – není komplikovaný, ale vyžaduje určitou znalost toho, jak DOS pracuje se soubory a jak se volají jeho služby.
; 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

  1. The Intel 8088 Architecture and Instruction Set
    https://people.ece.ubc.ca/~ed­c/464/lectures/lec4.pdf
  2. x86 Opcode Structure and Instruction Overview
    https://pnx.tf/files/x86_op­code_structure_and_instruc­tion_overview.pdf
  3. x86 instruction listings (Wikipedia)
    https://en.wikipedia.org/wi­ki/X86_instruction_listin­gs
  4. x86 assembly language (Wikipedia)
    https://en.wikipedia.org/wi­ki/X86_assembly_language
  5. Intel Assembler (Cheat sheet)
    http://www.jegerlehner.ch/in­tel/IntelCodeTable.pdf
  6. 25 Microchips That Shook the World
    https://spectrum.ieee.org/tech-history/silicon-revolution/25-microchips-that-shook-the-world
  7. Chip Hall of Fame: MOS Technology 6502 Microprocessor
    https://spectrum.ieee.org/tech-history/silicon-revolution/chip-hall-of-fame-mos-technology-6502-microprocessor
  8. Chip Hall of Fame: Intel 8088 Microprocessor
    https://spectrum.ieee.org/tech-history/silicon-revolution/chip-hall-of-fame-intel-8088-microprocessor
  9. Jak se zrodil procesor?
    https://www.root.cz/clanky/jak-se-zrodil-procesor/
  10. Apple II History Home
    http://apple2history.org/
  11. The 8086/8088 Primer
    https://www.stevemorse.or­g/8086/index.html
  12. flat assembler: Assembly language resources
    https://flatassembler.net/
  13. FASM na Wikipedii
    https://en.wikipedia.org/wiki/FASM
  14. Fresh IDE FASM inside
    https://fresh.flatassembler.net/
  15. MS-DOS Version 4.0 Programmer's Reference
    https://www.pcjs.org/docu­ments/books/mspl13/msdos/dos­ref40/
  16. INT 21 – DOS Function Dispatcher (DOS)
    https://www.stanislavs.or­g/helppc/int21.html
  17. DOS API (Wikipedia)
    https://en.wikipedia.org/wiki/DOS_API
  18. Bit banging
    https://en.wikipedia.org/wi­ki/Bit_banging
  19. IBM Basic assembly language and successors (Wikipedia)
    https://en.wikipedia.org/wi­ki/IBM_Basic_assembly_lan­guage_and_successors
  20. X86 Assembly/Bootloaders
    https://en.wikibooks.org/wi­ki/X86_Assembly/Bootloaders
  21. Počátky grafiky na PC: grafické karty CGA a Hercules
    https://www.root.cz/clanky/pocatky-grafiky-na-pc-graficke-karty-cga-a-hercules/
  22. 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/
  23. Karta EGA: první použitelná barevná grafika na PC
    https://www.root.cz/clanky/karta-ega-prvni-pouzitelna-barevna-grafika-na-pc/
  24. RGB Classic Games
    https://www.classicdosgames.com/
  25. Turbo Assembler (Wikipedia)
    https://en.wikipedia.org/wi­ki/Turbo_Assembler
  26. Microsoft Macro Assembler
    https://en.wikipedia.org/wi­ki/Microsoft_Macro_Assembler
  27. IBM Personal Computer (Wikipedia)
    https://en.wikipedia.org/wi­ki/IBM_Personal_Computer
  28. Intel 8251
    https://en.wikipedia.org/wi­ki/Intel_8251
  29. Intel 8253
    https://en.wikipedia.org/wi­ki/Intel_8253
  30. Intel 8255
    https://en.wikipedia.org/wi­ki/Intel_8255
  31. Intel 8257
    https://en.wikipedia.org/wi­ki/Intel_8257
  32. Intel 8259
    https://en.wikipedia.org/wi­ki/Intel_8259
  33. Support/peripheral/other chips – 6800 family
    http://www.cpu-world.com/Support/6800.html
  34. Motorola 6845
    http://en.wikipedia.org/wi­ki/Motorola_6845
  35. The 6845 Cathode Ray Tube Controller (CRTC)
    http://www.tinyvga.com/6845
  36. CRTC operation
    http://www.6502.org/users/an­dre/hwinfo/crtc/crtc.html
  37. 6845 – Motorola CRT Controller
    https://stanislavs.org/hel­ppc/6845.html
  38. The 6845 Cathode Ray Tube Controller (CRTC)
    http://www.tinyvga.com/6845
  39. Motorola 6845 and bitwise graphics
    https://retrocomputing.stac­kexchange.com/questions/10996/mo­torola-6845-and-bitwise-graphics
  40. IBM Monochrome Display Adapter
    http://en.wikipedia.org/wi­ki/Monochrome_Display_Adap­ter
  41. Color Graphics Adapter
    http://en.wikipedia.org/wi­ki/Color_Graphics_Adapter
  42. Color Graphics Adapter and the Brown color in IBM 5153 Color Display
    https://www.aceinnova.com/en/e­lectronics/cga-and-the-brown-color-in-ibm-5153-color-display/
  43. The Modern Retrocomputer: An Arduino Driven 6845 CRT Controller
    https://hackaday.com/2017/05/14/the-modern-retrocomputer-an-arduino-driven-6845-crt-controller/
  44. flat assembler: Assembly language resources
    https://flatassembler.net/
  45. FASM na Wikipedii
    https://en.wikipedia.org/wiki/FASM
  46. Fresh IDE FASM inside
    https://fresh.flatassembler.net/
  47. MS-DOS Version 4.0 Programmer's Reference
    https://www.pcjs.org/docu­ments/books/mspl13/msdos/dos­ref40/
  48. INT 21 – DOS Function Dispatcher (DOS)
    https://www.stanislavs.or­g/helppc/int21.html
  49. DOS API (Wikipedia)
    https://en.wikipedia.org/wiki/DOS_API
  50. IBM Basic assembly language and successors (Wikipedia)
    https://en.wikipedia.org/wi­ki/IBM_Basic_assembly_lan­guage_and_successors
  51. X86 Assembly/Arithmetic
    https://en.wikibooks.org/wi­ki/X86_Assembly/Arithmetic
  52. Art of Assembly – Arithmetic Instructions
    http://oopweb.com/Assembly/Do­cuments/ArtOfAssembly/Volu­me/Chapter6/CH06–2.html
  53. ASM Flags
    http://www.cavestory.org/gu­ides/csasm/guide/asm_flag­s.html
  54. Status Register
    https://en.wikipedia.org/wi­ki/Status_register
  55. Linux assemblers: A comparison of GAS and NASM
    http://www.ibm.com/develo­perworks/library/l-gas-nasm/index.html
  56. Programovani v assembleru na OS Linux
    http://www.cs.vsb.cz/gryga­rek/asm/asmlinux.html
  57. Is it worthwhile to learn x86 assembly language today?
    https://www.quora.com/Is-it-worthwhile-to-learn-x86-assembly-language-today?share=1
  58. Why Learn Assembly Language?
    http://www.codeproject.com/Ar­ticles/89460/Why-Learn-Assembly-Language
  59. Is Assembly still relevant?
    http://programmers.stackex­change.com/questions/95836/is-assembly-still-relevant
  60. Why Learning Assembly Language Is Still a Good Idea
    http://www.onlamp.com/pub/a/on­lamp/2004/05/06/writegreat­code.html
  61. Assembly language today
    http://beust.com/weblog/2004/06/23/as­sembly-language-today/
  62. Assembler: Význam assembleru dnes
    http://www.builder.cz/rubri­ky/assembler/vyznam-assembleru-dnes-155960cz
  63. Programming from the Ground Up Book – Summary
    http://savannah.nongnu.or­g/projects/pgubook/
  64. DOSBox
    https://www.dosbox.com/
  65. The C Programming Language
    https://en.wikipedia.org/wi­ki/The_C_Programming_Langu­age
  66. Hercules Graphics Card (HCG)
    https://en.wikipedia.org/wi­ki/Hercules_Graphics_Card
  67. Complete 8086 instruction set
    https://content.ctcd.edu/cou­rses/cosc2325/m22/docs/emu8086in­s.pdf
  68. Complete 8086 instruction set
    https://yassinebridi.github.io/asm-docs/8086_instruction_set.html
  69. 8088 MPH by Hornet + CRTC + DESiRE (final version)
    https://www.youtube.com/wat­ch?v=hNRO7lno_DM
  70. Area 5150 by CRTC & Hornet (Party Version) / IBM PC+CGA Demo, Hardware Capture
    https://www.youtube.com/wat­ch?v=fWDxdoRTZPc
  71. 80×86 Integer Instruction Set Timings (8088 – Pentium)
    http://aturing.umcs.maine­.edu/~meadow/courses/cos335/80×86-Integer-Instruction-Set-Clocks.pdf
  72. Colour Graphics Adapter: Notes
    https://www.seasip.info/Vin­tagePC/cga.html
  73. Restoring A Vintage CGA Card With Homebrew HASL
    https://hackaday.com/2024/06/12/res­toring-a-vintage-cga-card-with-homebrew-hasl/
  74. Demoing An 8088
    https://hackaday.com/2015/04/10/de­moing-an-8088/
  75. Video Memory Layouts
    http://www.techhelpmanual.com/89-video_memory_layouts.html
  76. Screen Attributes
    http://www.techhelpmanual.com/87-screen_attributes.html
  77. IBM PC Family – BIOS Video Modes
    https://www.minuszerodegre­es.net/video/bios_video_mo­des.htm
  78. EGA Functions
    https://cosmodoc.org/topics/ega-functions/#the-hierarchy-of-the-ega
  79. 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/
  80. How 16 colors saved PC gaming – the story of EGA graphics
    https://www.custompc.com/retro-tech/ega-graphics
  81. List of 16-bit computer color palettes
    https://en.wikipedia.org/wi­ki/List_of16-bit_computer_color_palettes
  82. Why were those colors chosen to be the default palette for 256-color VGA?
    https://retrocomputing.stac­kexchange.com/questions/27994/why-were-those-colors-chosen-to-be-the-default-palette-for-256-color-vga
  83. VGA Color Palettes
    https://www.fountainware.com/EX­PL/vga_color_palettes.htm
  84. Hardware Level VGA and SVGA Video Programming Information Page
    http://www.osdever.net/Fre­eVGA/vga/vga.htm
  85. Hardware Level VGA and SVGA Video Programming Information Page – sequencer
    http://www.osdever.net/Fre­eVGA/vga/seqreg.htm
  86. VGA Basics
    http://www.brackeen.com/vga/ba­sics.html
  87. Introduction to VGA Mode ‚X‘
    https://web.archive.org/web/20160414072210/htt­p://fly.srk.fer.hr/GDM/ar­ticles/vgamodex/vgamx1.html
  88. VGA Mode-X
    https://web.archive.org/web/20070123192523/htt­p://www.gamedev.net/referen­ce/articles/article356.asp
  89. Mode-X: 256-Color VGA Magic
    https://downloads.gamedev­.net/pdf/gpbb/gpbb47.pdf
ikonka

Zajímá vás toto téma? Chcete se o něm dozvědět víc?

Objednejte si upozornění na nově vydané články do vašeho mailu. Žádný článek vám tak neuteče.

Autor článku

Vystudoval VUT FIT a v současné době pracuje na projektech vytvářených v jazycích Python a Go.