Skrytá síla karty VGA: čtecí a zápisové režimy

3. 9. 2024
Doba čtení: 48 minut

Sdílet

 Autor: Pavel Tišnovský
Grafické karty EGA a VGA byly postaveny na konceptu takzvaných bitových rovin. To si vyžádalo podporu různých čtecích a zápisových režimů, jež sice komplikovaly programování, ovšem přinesly velmi rychlé přenosy v rámci video RAM.

Obsah

1. Skrytá síla karty VGA: čtecí a zápisové režimy

2. Grafická operace typu BitBLT

3. První (naivní) implementace operace typu BitBLT

4. Úplný zdrojový kód dnešního prvního demonstračního příkladu

5. Proč vypadá obrazovka po provedení blokového přenosu tak, jak vypadá?

6. Operace BitBLT při povolení zápisu do různých kombinací bitových rovin

7. Úplný zdrojový kód dnešního druhého demonstračního příkladu

8. Stavy obrazovky v jednotlivých fázích druhého demonstračního příkladu

9. Výběr bitové roviny pro čtení

10. Postupné čtení obsahu jednotlivých bitových rovin operací typu BitBLT

11. Úplný zdrojový kód dnešního třetího demonstračního příkladu

12. Stavy obrazovky v jednotlivých fázích třetího demonstračního příkladu

13. Korektní (pomalá) realizace operace typu BitBLT

14. Úplný zdrojový kód dnešního čtvrtého demonstračního příkladu

15. Obrazovka před blokovým přenosem a po provedení blokového přenosu

16. Realizace operace typu BitBLT podprogramem

17. Úplný zdrojový kód dnešního pátého demonstračního příkladu

18. Blokové přenosy s využitím 32bitového záchytného registru latche

19. Repositář s demonstračními příklady

20. Odkazy na Internetu

1. Skrytá síla karty VGA: čtecí a zápisové režimy

Grafické karty VGA (a nutno dodat, že vlastně i původní karty EGA) byly postaveny, jak již dobře víme, na konceptu bitových rovin (bitplanes). Nejlépe je toto členění grafické paměti patrné u režimů se šestnácti barvami, takže se v dalším textu zaměříme především na tyto režimy, i když všechny koncepty lze použít i v režimech s 256 barvami a nezřetězenými rovinami (pro standardní režim 13h to neplatí). Takže si zopakujme základní koncepty EGA a VGA:

  • K dispozici jsou čtyři bitové roviny, každá o velikosti 64kB (což odpovídá virtuálnímu rozlišení 640×819 pixelů).
  • Z logického pohledu tyto roviny leží na sobě (tj. nulté bity na sobě, první bity na sobě atd.)
  • Barvy pixelů jsou v 16barevných režimech zapsány do čtyř bitů, přičemž tyto bity jsou rozděleny do všech čtyř rovin (v každé rovině jediný bit).
  • Fyzicky jsou všechny bitové roviny namapovány do stejného adresního prostoru v segmentu 0×a000 a neexistuje zde tedy jednoznačný vztah adresa==konkrétní osmice bitů.
  • Při čtení se přečte osm bitů z vybrané bitové roviny 0..3. Výběr roviny se provádí přes I/O porty (viz další text).
  • Při zápisu se zapíše osm bitů do vybrané kombinace bitových rovin, tedy například do roviny 1+2, do všech rovin, atd. Výběr se opět provádí přes I/O porty.
  • Při zápisu lze bity rotovat, maskovat je atd.
  • Navíc existuje několik čtecích a zápisových režimů popsaných v dalších textech.
  • Při čtení se ve skutečnosti přečte osm bitů z každé bitové roviny (8×4=32 bitů), které se uloží do záchytného registru (latche). Existuje zápisový režim, který dokáže opět těchto 32bitů zapsat a přenést tak vlastně 4 pixely jedinou strojovou instrukcí (i když se po sběrnici přenese jen 8 bitů). Toto byla velmi silná programátorská technika, ke které se pochopitelně ještě vrátíme.

2. Grafická operace typu BitBLT

Většina historických i poměrně velká část soudobých počítačových her s dvoudimenzionální (2D) grafikou je charakteristická tím, že objekty v těchto hrách jsou reprezentovány s využitím rastrových obrázků (bitmap) o různé velikosti, které se postupně vykreslují do vytvářené dvoudimenzionální scény. Aby bylo přes některé části těchto rastrových obrázků viditelné i pozadí, používají se tři metody pro zajištění úplné či částečné průhlednosti. Buď je stanoveno, že určitá hodnota (tj. barva) pixelů má být zcela průhledná (typicky se jedná o jasně fialovou barvu, která se v typických scénách stejně nikde neobjevuje), dále je alternativně možné jeden bit v hodnotě pixelu použít pro určení průhlednosti (typické pro 16bitovou hloubku), nebo se může stanovit průhlednost pixelů doplněním bitmapy o takzvaný alfa kanál (alpha channel).

06

Obrázek 1: Rastrové obrázky (zde zvětšené), které tvoří základ jedné RPG. Vykreslují se funkcí blit/BitBLT.

S využitím grafické operace blit neboli BitBLT (Bit Block Transfer) lze provádět, jak ostatně její název naznačuje, blokové přenosy bitmap nebo jejich výřezů, popř. v rámci přenosu nad bitmapami provádět různé další operace, například zpracování alfa kanálu. První implementace operace BitBLT byla použita v roce 1975 ve Smalltalku-72 a od té doby ji najdeme prakticky v každé implementaci tohoto programovacího jazyka, která obsahuje i knihovny pro práci s grafikou (mj. se jedná i o Squeak). Pro Smalltalk-74 vytvořil Daniel Ingalls optimalizovanou variantu operace BitBLT implementovanou v mikrokódu. Operace BitBLT se tak stala součástí operačního systému a bylo ji možné volat jak z assembleru, tak i z programů napsaných v jazyce BCPL a samozřejmě i ze Smalltalku (právě tuto implementaci můžeme považovat za vůbec první grafickou akceleraci). Posléze se díky své univerzalitě tato funkce rozšířila i do mnoha dalších operačních systémů a grafických knihoven.

07

Obrázek 2: Hra Warcraft II také používá téměř výhradně bitmapy pro zobrazení budov i postaviček.

Tuto operaci lze implementovat i na kartě VGA, a to hned několika různými způsoby, které si postupně popíšeme.

3. První (naivní) implementace operace typu BitBLT

Naše první (a nutno dodat, že i hodně naivní) implementace výše zmíněné operace typu BitBLT v šestnáctibarevném grafickém režimu karty VGA může vypadat následovně. Budeme se snažit přenést horní polovinu obrazu (240 obrazových řádků) do poloviny spodní, a to bajt po bajtu:

; operace BitBLT z prvni poloviny obrazovky na druhou polovinu
bitblt:
        mov ax, 0xa000      ; video RAM v textovem rezimu
        mov es, ax
        mov ds, ax
        mov di, 640*240/8   ; nyni ES:DI obsahuje adresu pixelu ve video RAM na 240 radku
        xor si, si          ; nyni DS:SI obsahuje adresu prvniho pixelu ve video RAM
 
        mov cx, 640*240/8   ; pocet prenesenych bajtu
        rep movsb           ; blokovy prenos po bajtech
        ret                 ; hotovo

V příkladu nejdříve nastavíme grafický režim, vykreslíme sérii úseček a počkáme na stisk klávesy:

        gfx_mode 0x12         ; nastaveni rezimu 640x480 se sestnacti barvami
        call draw_color_lines
        wait_key              ; cekani na klavesu

Dále nastavíme bitové roviny pro zápis a zavoláme výše uvedený podprogram bitblt:

        select_bitplane 15    ; vyber bitove roviny nebo bitovych rovin
        call bitblt           ; prenos bloku

Po stisku klávesy se program ukončí:

        wait_key              ; cekani na klavesu
        exit                  ; navrat do DOSu

4. Úplný zdrojový kód dnešního prvního demonstračního příkladu

Úplný zdrojový kód dnešního prvního demonstračního příkladu, v němž je volána naivní varianta operace BitBLT, vypadá takto:

; Graficky rezim karty VGA s rozlisenim 640x480 pixelu.
; Zmena barvovych rovin, do kterych se zapisuje.
; Vykresleni barevnych usecek.
; Prenos casti obrazu operaci typu BitBLT.
;
; preklad pomoci:
;     nasm -f bin -o vga.com vga_bitblt_1.asm
;
; nebo pouze:
;     nasm -o vga.com vga_bitblt_1.asm
 
 
;-----------------------------------------------------------------------------
 
; I/O porty karty EGA/VGA
SEQUENCER_INDEX      equ 0x3c4
SEQUENCER_DATA       equ 0x3c5
 
; registry karty EGA/VGA
BITPLANE_SELECTOR    equ 0x02   ; sequencer
 
 
; ukonceni procesu a navrat do DOSu
%macro exit 0
        mov     ah, 0x4c
        int     0x21
%endmacro
 
; vyprazdneni bufferu klavesnice a cekani na klavesu
%macro wait_key 0
        xor     ax, ax
        int     0x16
%endmacro
 
; nastaveni grafickeho rezimu
%macro gfx_mode 1
        mov     ah, 0
        mov     al, %1
        int     0x10
%endmacro
 
; vyber bitove roviny
%macro select_bitplane 1
        mov  al, %1         ; bitova rovina
        mov  dx, SEQUENCER_INDEX
        mov  ah, BITPLANE_SELECTOR
        xchg ah, al
        out  dx, ax         ; vyber registru sekvenceru
                            ; a zapis masky bitovych rovin
%endmacro
 
;-----------------------------------------------------------------------------
org  0x100        ; zacatek kodu pro programy typu COM (vzdy se zacina na 256)
 
start:
        gfx_mode 0x12         ; nastaveni rezimu 640x480 se sestnacti barvami
        call draw_color_lines
        wait_key              ; cekani na klavesu
 
        select_bitplane 15    ; vyber bitove roviny nebo bitovych rovin
        call bitblt           ; prenos bloku
        wait_key              ; cekani na klavesu
 
        exit                  ; navrat do DOSu
 
 
; operace BitBLT z prvni poloviny obrazovky na druhou polovinu
bitblt:
        mov ax, 0xa000      ; video RAM v textovem rezimu
        mov es, ax
        mov ds, ax
        mov di, 640*240/8   ; nyni ES:DI obsahuje adresu pixelu ve video RAM na 240 radku
        xor si, si          ; nyni DS:SI obsahuje adresu prvniho pixelu ve video RAM
 
        mov cx, 640*240/8   ; pocet prenesenych bajtu
        rep movsb           ; blokovy prenos po bajtech
        ret                 ; hotovo
 
 
draw_color_lines:
        mov ax, 0xa000      ; video RAM v textovem rezimu
        mov es, ax
        xor di, di          ; nyni ES:DI obsahuje adresu prvniho pixelu ve video RAM
 
        mov ax, 0
.opak:
        mov bx, ax          ; y-ová souřadnice
 
        push ax
        mov cl, 15          ; barva
        call putpixel       ; vykreslení pixelu
        pop ax
 
        push ax
        mov cl,  7          ; barva
        add ax, 10          ; horizontalni posun useky
        call putpixel       ; vykreslení pixelu
        pop ax
 
        push ax
        mov cl,  1          ; barva
        add ax, 20          ; horizontalni posun useky
        call putpixel       ; vykreslení pixelu
        pop ax
 
        push ax
        mov cl,  2          ; barva
        add ax, 30          ; horizontalni posun useky
        call putpixel       ; vykreslení pixelu
        pop ax
 
        push ax
        mov cl,  4          ; barva
        add ax, 40          ; horizontalni posun useky
        call putpixel       ; vykreslení pixelu
        pop ax
 
        inc ax              ; pusun x+=1, y+=1
        cmp ax, 480         ; hranice obrazovky?
        jne .opak           ; ne-opakujeme
        ret                 ; hotovo
 
 
; Vykresleni pixelu
; AX - x-ova souradnice
; BX - y-ova souradnice
; CL - barva
putpixel:
        push ax
        mov al, cl         ; vyber bitove roviny nebo bitovych rovin
        select_bitplane al
        pop ax
 
        mov dx, 0xa000     ; zacatek stranky video RAM
        mov es, dx         ; nyni obsahuje ES stranku video RAM
 
        mov cl, al
        and cl, 7          ; pouze spodni 3 bity x-ove souradnice
 
        shr ax, 1
        shr ax, 1
        shr ax, 1          ; x/8
        mov di, ax         ; horizontalni posun pocitany v bajtech
 
        mov ax, bx         ; y-ova souradnice
        shl ax, 1          ; y*2
        shl ax, 1          ; y*4
        shl ax, 1          ; y*8
        shl ax, 1          ; y*16
        add di, ax         ; pricist cast y-oveho posunu
        shl ax, 1          ; y*32
        shl ax, 1          ; y*64
        add di, ax         ; pricist zbytek y-oveho posunu
                           ; -> y*16 + y*64 = y*80
 
        mov al, 0x80       ; vypocitat masku pixelu
        shr al, cl
        or [es:di], al     ; vlastni vykresleni pixelu
 
        ret                ; hotovo

5. Proč vypadá obrazovka po provedení blokového přenosu tak, jak vypadá?

Nyní zkusme prozkoumat obrazovku PC (nebo emulátoru) před a po provedení naší operace typu BitBLT. První i druhá verze obrazovky budou vypadat následovně:

vga-bitblt-1

Obrázek 3: Obrazovka před provedením operace BitBLT.

vga-bitblt-2

Obrázek 4: Obrazovka po provedení operace BitBLT.

Ideálně by měl obrázek číslo 4 mít ve spodní polovině přesnou kopii horní poloviny, což se však nestalo. Při bližším prozkoumání zjistíme, že bílé úsečky, které byly zkopírovány, mají jednu vlastnost společnou – všechny mají pixely nastavené na jedničku v první bitové rovině, zatímco zbylé úsečky nikoli:

Barva Bitplane 0 Bitplane 1 Bitplane 2 Bitplane 3 Přeneseno?
bílá 1 1 1 1 ano
šedá 1 1 1 0 ano
modrá 1 0 0 0 ano
zelená 0 1 0 0 ne
červená 0 0 1 0 ne

Vše je tedy zřejmé – čtení bajtů (tedy osmic pixelů) probíhalo z první bitové roviny s indexem 0, která obsahuje modrou barvovou složku, pokud pochopitelně nezměníme barvovou paletu. Čtení ze všech bitových rovin v tomto případě nemohlo nastat, protože čteme jeden bajt (osm pixelů, každý pixel jeden bit) a nikoli čtyři bajty; ty se do registru AL skutečně nevejdou.

A důvodem, proč je výsledkem trojice bílých úseček je fakt, že zápis (nikoli čtení) se naopak provádí do všech čtyř bitových rovin, tj. onen bajt v AL je interně rozkopírován na čtyři místa.

6. Operace BitBLT při povolení zápisu do různých kombinací bitových rovin

V rámci dnešního druhého demonstračního příkladu se pokusme o nepatrnou úpravu – budeme stále provádět naši operaci BitBLT, ale před jejím provedením změníme kombinaci bitových rovin pro zápis (nikoli pro čtení – to zatím neumíme). Budeme tedy řídit, jakým způsobem se zapíše celý bajt (osm pixelů) – zda do jedné bitové roviny, více rovin, do všech čtyř rovin či dokonce nikam:

Makro Význam po zavolání
select_bitplane 1 zápis do první bitové roviny (s indexem 0), obsahuje červenou složku
select_bitplane 2 zápis do druhé bitové roviny (s indexem 1), obsahuje zelenou složku
select_bitplane 7 zápis do rovin s indexy 0, 1 a 2, obsahuje RGB složky
select_bitplane 15 zápis do všech čtyř rovin, poslední rovina obsahuje intenzitu barvy

Mezi jednotlivými operacemi typu BibBLT počkáme na stisk klávesy:

        select_bitplane 1     ; vyber bitove roviny nebo bitovych rovin
        call bitblt           ; prenos bloku
        wait_key              ; cekani na klavesu
 
        select_bitplane 2     ; vyber bitove roviny nebo bitovych rovin
        call bitblt           ; prenos bloku
        wait_key              ; cekani na klavesu
 
        select_bitplane 7     ; vyber bitove roviny nebo bitovych rovin
        call bitblt           ; prenos bloku
        wait_key              ; cekani na klavesu
 
        select_bitplane 15    ; vyber bitove roviny nebo bitovych rovin
        call bitblt           ; prenos bloku
        wait_key              ; cekani na klavesu

7. Úplný zdrojový kód dnešního druhého demonstračního příkladu

Zdrojový kód dnešního druhého demonstračního příkladu, v němž se operace typu BitBLT provádí s různými bitovými rovinami pro zápis, vypadá následovně:

; Graficky rezim karty VGA s rozlisenim 640x480 pixelu.
; Zmena barvovych rovin, do kterych se zapisuje.
; Vykresleni barevnych usecek.
; Prenos casti obrazu operaci typu BitBLT.
;
; preklad pomoci:
;     nasm -f bin -o vga.com vga_bitblt_2.asm
;
; nebo pouze:
;     nasm -o vga.com vga_bitblt_2.asm
 
 
;-----------------------------------------------------------------------------
 
; I/O porty karty EGA/VGA
SEQUENCER_INDEX      equ 0x3c4
SEQUENCER_DATA       equ 0x3c5
 
; registry karty EGA/VGA
BITPLANE_SELECTOR    equ 0x02   ; sequencer
 
 
; ukonceni procesu a navrat do DOSu
%macro exit 0
        mov     ah, 0x4c
        int     0x21
%endmacro
 
; vyprazdneni bufferu klavesnice a cekani na klavesu
%macro wait_key 0
        xor     ax, ax
        int     0x16
%endmacro
 
; nastaveni grafickeho rezimu
%macro gfx_mode 1
        mov     ah, 0
        mov     al, %1
        int     0x10
%endmacro
 
; vyber bitove roviny
%macro select_bitplane 1
        mov  al, %1         ; bitova rovina
        mov  dx, SEQUENCER_INDEX
        mov  ah, BITPLANE_SELECTOR
        xchg ah, al
        out  dx, ax         ; vyber registru sekvenceru
                            ; a zapis masky bitovych rovin
%endmacro
 
;-----------------------------------------------------------------------------
org  0x100        ; zacatek kodu pro programy typu COM (vzdy se zacina na 256)
 
start:
        gfx_mode 0x12         ; nastaveni rezimu 640x480 se sestnacti barvami
        call draw_color_lines
        wait_key              ; cekani na klavesu
 
        select_bitplane 1     ; vyber bitove roviny nebo bitovych rovin
        call bitblt           ; prenos bloku
        wait_key              ; cekani na klavesu
 
        select_bitplane 2     ; vyber bitove roviny nebo bitovych rovin
        call bitblt           ; prenos bloku
        wait_key              ; cekani na klavesu
 
        select_bitplane 7     ; vyber bitove roviny nebo bitovych rovin
        call bitblt           ; prenos bloku
        wait_key              ; cekani na klavesu
 
        select_bitplane 15    ; vyber bitove roviny nebo bitovych rovin
        call bitblt           ; prenos bloku
        wait_key              ; cekani na klavesu
 
        exit                  ; navrat do DOSu
 
 
; operace BitBLT z prvni poloviny obrazovky na druhou polovinu
bitblt:
        mov ax, 0xa000      ; video RAM v textovem rezimu
        mov es, ax
        mov ds, ax
        mov di, 640*240/8   ; nyni ES:DI obsahuje adresu pixelu ve video RAM na 240 radku
        xor si, si          ; nyni DS:SI obsahuje adresu prvniho pixelu ve video RAM
 
        mov cx, 640*240/8   ; pocet prenesenych bajtu
        rep movsb           ; blokovy prenos po bajtech
        ret                 ; hotovo
 
 
draw_color_lines:
        mov ax, 0xa000      ; video RAM v textovem rezimu
        mov es, ax
        xor di, di          ; nyni ES:DI obsahuje adresu prvniho pixelu ve video RAM
 
        mov ax, 0
.opak:
        mov bx, ax          ; y-ová souřadnice
 
        push ax
        mov cl, 15          ; barva
        call putpixel       ; vykreslení pixelu
        pop ax
 
        push ax
        mov cl,  7          ; barva
        add ax, 10          ; horizontalni posun useky
        call putpixel       ; vykreslení pixelu
        pop ax
 
        push ax
        mov cl,  1          ; barva
        add ax, 20          ; horizontalni posun useky
        call putpixel       ; vykreslení pixelu
        pop ax
 
        push ax
        mov cl,  2          ; barva
        add ax, 30          ; horizontalni posun useky
        call putpixel       ; vykreslení pixelu
        pop ax
 
        push ax
        mov cl,  4          ; barva
        add ax, 40          ; horizontalni posun useky
        call putpixel       ; vykreslení pixelu
        pop ax
 
        inc ax              ; pusun x+=1, y+=1
        cmp ax, 480         ; hranice obrazovky?
        jne .opak           ; ne-opakujeme
        ret                 ; hotovo
 
 
; Vykresleni pixelu
; AX - x-ova souradnice
; BX - y-ova souradnice
; CL - barva
putpixel:
        push ax
        mov al, cl         ; vyber bitove roviny nebo bitovych rovin
        select_bitplane al
        pop ax
 
        mov dx, 0xa000     ; zacatek stranky video RAM
        mov es, dx         ; nyni obsahuje ES stranku video RAM
 
        mov cl, al
        and cl, 7          ; pouze spodni 3 bity x-ove souradnice
 
        shr ax, 1
        shr ax, 1
        shr ax, 1          ; x/8
        mov di, ax         ; horizontalni posun pocitany v bajtech
 
        mov ax, bx         ; y-ova souradnice
        shl ax, 1          ; y*2
        shl ax, 1          ; y*4
        shl ax, 1          ; y*8
        shl ax, 1          ; y*16
        add di, ax         ; pricist cast y-oveho posunu
        shl ax, 1          ; y*32
        shl ax, 1          ; y*64
        add di, ax         ; pricist zbytek y-oveho posunu
                           ; -> y*16 + y*64 = y*80
 
        mov al, 0x80       ; vypocitat masku pixelu
        shr al, cl
        or [es:di], al     ; vlastni vykresleni pixelu
 
        ret                ; hotovo

8. Stavy obrazovky v jednotlivých fázích druhého demonstračního příkladu

Způsob činnosti našeho druhého příkladu, v němž se využívá operace typu BitBLT, je poměrně dobře popsatelný při pohledu na obsahy obrazovky, které získáme:

vga-bitblt-3

Obrázek 6: Takto vypadá původní obsah obrazovky po vykreslení série různobarevných úseček.

vga-bitblt-4

Obrázek 7: Výsledek čtení obsahu první bitové roviny (bitplane 0) se zápisem do první bitové roviny. V tomto případě se přenese pouze modrá barvová složka, která je součástí prvních tří úseček.

vga-bitblt-5

Obrázek 8: Výsledek čtení obsahu první bitové roviny (opět), ovšem nyní se bajty zapisují do druhé roviny. Nastaví se tedy navíc ještě zelená složka, a to pochopitelně u všech již zobrazených pixelů (obsah bitových rovin 0 a 1 bude ve spodní části obrázku shodný).

vga-bitblt-6

Obrázek 9: Nyní zapisujeme do prvních tří bitových rovin obsah první bitové roviny (bitplane 0). Z modré barvové složky se tedy nyní stane šedá barva (R=1, G=1, B=1, intenzita=0).

vga-bitblt-7

Obrázek 10: A konečně zapisujeme do všech tří bitových rovin obsah první roviny (tedy modré složky). Výsledkem jsou tři bílé úsečky (R=1, G=1, B=1, intenzita=1).

9. Výběr bitové roviny pro čtení

Aby bylo možné provést přenos celé části obrazu (tedy s věrnou kopií barev), budeme muset přenést odpovídající data ze všech čtyř bitových rovin. Nejdříve se podívejme na pomalý, ovšem dobře pochopitelný způsob: přenos vždy jedné vybrané bitové roviny. Již víme, jakým způsobem se vybírají roviny (tedy přesněji řečeno jejich libovolná kombinace) pro zápis – jedná se o čtveřici bitů tvořících masku, v níž každý bit odpovídá jedné bitové rovině. Pro volbu bitové roviny pro čtení však nepotřebujeme čtyři bity, ale jen bity dva, protože (logicky) dokážeme osmibitovou operací čtení přečíst pouze jeden vybraný bajt (tedy osmici pixelů) a nikoli 4×8 bitů. I z tohoto důvodu je v řídicích registrech karty VGA dostupný i registr nazvaný Read Map Select Register, v němž mají význam jen nejnižší dva bity: obsahují index bitové roviny 0..3.

Tento registr je součástí grafického řadiče a jeho hodnotu (tedy bitovou rovinu určenou pro čtení) specifikujeme pomocí makra:

; vyber bitove roviny pro cteni
%macro select_bitplane_for_read 1
        mov  dx, GRAPHICS_REGISTER
        mov  al, READ_MAP_SELECT
        out  dx, al         ; vyber VGA registru pro zapis
        inc  dx,
        mov  al, %1         ; zmena VGA registru
        out  dx, al
%endmacro

Toto makro využívá dvě nové konstanty – adresu I/O portu grafického řadiče a indexu registru Read Map Select Register:

; I/O porty karty EGA/VGA
GRAPHICS_REGISTER    equ 0x3ce
 
; registry karty EGA/VGA
READ_MAP_SELECT      equ 0x04   ; graphics register

Současně přejmenujeme makro pro výběr roviny (rovin) pro zápis, aby jeho název explicitně obsahoval i prováděnou operaci:

; vyber bitove roviny nebo bitovych rovin pro zapis
%macro select_bitplanes_for_write 1
        mov  al, %1         ; bitova rovina
        mov  dx, SEQUENCER_INDEX
        mov  ah, BITPLANE_SELECTOR
        xchg ah, al
        out  dx, ax         ; vyber registru sekvenceru
                            ; a zapis masky bitovych rovin
%endmacro

10. Postupné čtení obsahu jednotlivých bitových rovin operací typu BitBLT

Ukažme si nyní, jak bude vypadat výsledek operace typu BitBLT ve chvíli, kdy budeme zapisovat do všech čtyř bitových rovin současně (a tedy výsledkem bude vždy černá nebo bílá barva pixelů):

        select_bitplanes_for_write 15 ; vyber vsech bitovych rovin pro zapis

Ovšem čtení z bitových rovin provedeme postupně – nejprve pro první rovinu (0), dále pro rovinu druhou atd. A mezi jednotlivými operacemi BitBLT bude program čekat na stisk klávesy:

        select_bitplane_for_read 0    ; vyber bitove roviny pro cteni
        call bitblt                   ; prenos bloku
        wait_key                      ; cekani na klavesu
 
        select_bitplane_for_read 1    ; vyber bitove roviny pro cteni
        call bitblt                   ; prenos bloku
        wait_key                      ; cekani na klavesu
 
        select_bitplane_for_read 2    ; vyber bitove roviny pro cteni
        call bitblt                   ; prenos bloku
        wait_key                      ; cekani na klavesu
 
        select_bitplane_for_read 3    ; vyber bitove roviny pro cteni
        call bitblt                   ; prenos bloku
        wait_key                      ; cekani na klavesu

11. Úplný zdrojový kód dnešního třetího demonstračního příkladu

Dnešní třetí demonstrační příklad, jehož základní činnost byla popsána v předchozích dvou kapitolách, vypadá následovně:

; Graficky rezim karty VGA s rozlisenim 640x480 pixelu.
; Zmena barvovych rovin, do kterych se zapisuje.
; Vykresleni barevnych usecek.
; Prenos casti obrazu operaci typu BitBLT.
; Vyber bitovych rovin pro zapis.
; Vyber bitove roviny pro cteni.
;
; preklad pomoci:
;     nasm -f bin -o vga.com vga_bitblt_3.asm
;
; nebo pouze:
;     nasm -o vga.com vga_bitblt_3.asm
 
 
;-----------------------------------------------------------------------------
 
; I/O porty karty EGA/VGA
GRAPHICS_REGISTER    equ 0x3ce
SEQUENCER_INDEX      equ 0x3c4
SEQUENCER_DATA       equ 0x3c5
 
; registry karty EGA/VGA
BITPLANE_SELECTOR    equ 0x02   ; sequencer
READ_MAP_SELECT      equ 0x04   ; graphics register
 
 
; ukonceni procesu a navrat do DOSu
%macro exit 0
        mov     ah, 0x4c
        int     0x21
%endmacro
 
; vyprazdneni bufferu klavesnice a cekani na klavesu
%macro wait_key 0
        xor     ax, ax
        int     0x16
%endmacro
 
; nastaveni grafickeho rezimu
%macro gfx_mode 1
        mov     ah, 0
        mov     al, %1
        int     0x10
%endmacro
 
; vyber bitove roviny nebo bitovych rovin pro zapis
%macro select_bitplanes_for_write 1
        mov  al, %1         ; bitova rovina
        mov  dx, SEQUENCER_INDEX
        mov  ah, BITPLANE_SELECTOR
        xchg ah, al
        out  dx, ax         ; vyber registru sekvenceru
                            ; a zapis masky bitovych rovin
%endmacro
 
; vyber bitove roviny pro cteni
%macro select_bitplane_for_read 1
        mov  dx, GRAPHICS_REGISTER
        mov  al, READ_MAP_SELECT
        out  dx, al         ; vyber VGA registru pro zapis
        inc  dx,
        mov  al, %1         ; zmena VGA registru
        out  dx, al
%endmacro
 
;-----------------------------------------------------------------------------
org  0x100        ; zacatek kodu pro programy typu COM (vzdy se zacina na 256)
 
start:
        gfx_mode 0x12         ; nastaveni rezimu 640x480 se sestnacti barvami
        call draw_color_lines
        wait_key              ; cekani na klavesu
 
        select_bitplanes_for_write 15 ; vyber vsech bitovych rovin pro zapis
 
        select_bitplane_for_read 0    ; vyber bitove roviny pro cteni
        call bitblt                   ; prenos bloku
        wait_key                      ; cekani na klavesu
 
        select_bitplane_for_read 1    ; vyber bitove roviny pro cteni
        call bitblt                   ; prenos bloku
        wait_key                      ; cekani na klavesu
 
        select_bitplane_for_read 2    ; vyber bitove roviny pro cteni
        call bitblt                   ; prenos bloku
        wait_key                      ; cekani na klavesu
 
        select_bitplane_for_read 3    ; vyber bitove roviny pro cteni
        call bitblt                   ; prenos bloku
        wait_key                      ; cekani na klavesu
 
        exit                  ; navrat do DOSu
 
 
; operace BitBLT z prvni poloviny obrazovky na druhou polovinu
bitblt:
        mov ax, 0xa000      ; video RAM v textovem rezimu
        mov es, ax
        mov ds, ax
        mov di, 640*240/8   ; nyni ES:DI obsahuje adresu pixelu ve video RAM na 240 radku
        xor si, si          ; nyni DS:SI obsahuje adresu prvniho pixelu ve video RAM
 
        mov cx, 640*240/8   ; pocet prenesenych bajtu
        rep movsb           ; blokovy prenos po bajtech
        ret                 ; hotovo
 
 
draw_color_lines:
        mov ax, 0xa000      ; video RAM v textovem rezimu
        mov es, ax
        xor di, di          ; nyni ES:DI obsahuje adresu prvniho pixelu ve video RAM
 
        mov ax, 0
.opak:
        mov bx, ax          ; y-ová souřadnice
 
        push ax
        mov cl, 15          ; barva
        call putpixel       ; vykreslení pixelu
        pop ax
 
        push ax
        mov cl,  7          ; barva
        add ax, 10          ; horizontalni posun useky
        call putpixel       ; vykreslení pixelu
        pop ax
 
        push ax
        mov cl,  1          ; barva
        add ax, 20          ; horizontalni posun useky
        call putpixel       ; vykreslení pixelu
        pop ax
 
        push ax
        mov cl,  2          ; barva
        add ax, 30          ; horizontalni posun useky
        call putpixel       ; vykreslení pixelu
        pop ax
 
        push ax
        mov cl,  4          ; barva
        add ax, 40          ; horizontalni posun useky
        call putpixel       ; vykreslení pixelu
        pop ax
 
        inc ax              ; pusun x+=1, y+=1
        cmp ax, 480         ; hranice obrazovky?
        jne .opak           ; ne-opakujeme
        ret                 ; hotovo
 
 
; Vykresleni pixelu
; AX - x-ova souradnice
; BX - y-ova souradnice
; CL - barva
putpixel:
        push ax
        mov al, cl         ; vyber bitove roviny nebo bitovych rovin
        select_bitplanes_for_write al
        pop ax
 
        mov dx, 0xa000     ; zacatek stranky video RAM
        mov es, dx         ; nyni obsahuje ES stranku video RAM
 
        mov cl, al
        and cl, 7          ; pouze spodni 3 bity x-ove souradnice
 
        shr ax, 1
        shr ax, 1
        shr ax, 1          ; x/8
        mov di, ax         ; horizontalni posun pocitany v bajtech
 
        mov ax, bx         ; y-ova souradnice
        shl ax, 1          ; y*2
        shl ax, 1          ; y*4
        shl ax, 1          ; y*8
        shl ax, 1          ; y*16
        add di, ax         ; pricist cast y-oveho posunu
        shl ax, 1          ; y*32
        shl ax, 1          ; y*64
        add di, ax         ; pricist zbytek y-oveho posunu
                           ; -> y*16 + y*64 = y*80
 
        mov al, 0x80       ; vypocitat masku pixelu
        shr al, cl
        or [es:di], al     ; vlastni vykresleni pixelu
 
        ret                ; hotovo

12. Stavy obrazovky v jednotlivých fázích třetího demonstračního příkladu

Podobně, jako tomu bylo u druhého demonstračního příkladu, si i nyní ukážeme obsahy obrazovek vykreslovaných třetím příkladem. Připomeňme si, že se provádělo čtení z různých bitových rovin, ovšem zápis byl vždy proveden do všech čtyř bitových rovin, takže výsledkem bude – nezávisle na zdroji – nějaký černobílý obrazec (barvy „zmizí“):

vga-bitblt-8

Obrázek 11: Původní obrázek s pěticí barevných úseček.

vga-bitblt-9

Obrázek 12: Čtení z první bitové roviny (bitplane 0) znamená, že se přečetla jen modrá barvová složka (první tři úsečky) a převedla se na bílou barvu (zápisem do všech čtyř bitových rovin).

vga-bitblt-10

Obrázek 13: Čtení ze druhé bitové roviny (bitplane 1) znamenalo přečtení zelené barvové složky. Ta je nastavena pro první, druhou a čtvrtou úsečku (viz obrázek číslo 10).

vga-bitblt-11

Obrázek 14: Čtení ze třetí bitové roviny (bitplane 2) znamenalo přečtení červené barvové složky.

vga-bitblt-12

Obrázek 15: Čtení ze čtvrté barvové roviny (bitplane 3) znamenalo přečtení intenzity. Ta je nastavena pouze pro pixely v první úsečce.

13. Korektní (pomalá) realizace operace typu BitBLT

Jak by tedy měla vypadat korektně naprogramovaná operace typu BitBLT? Protože prozatím neznáme další potřebné triky (využití latche atd.), budeme muset přenos barev pixelů provést čtyřikrát – pro každou bitovou rovinu zvlášť. Jedná se o tento postup:

  1. Čtení z roviny 0, zápis jen do roviny 0
  2. Čtení z roviny 1, zápis jen do roviny 1
  3. Čtení z roviny 2, zápis jen do roviny 2
  4. Čtení z roviny 3, zápis jen do roviny 3

Následuje neefektivní způsob zápisu těchto operací voláním příslušných maker. V dalších kapitolách si uvedeme kratší a nepatrně rychlejší způsob zápisu:

        select_bitplane_for_read 0    ; vyber prvni bitove roviny pro cteni
        select_bitplanes_for_write 1  ; vyber prvni bitove roviny pro zapis
        call bitblt                   ; prenos bloku
 
        select_bitplane_for_read 1    ; vyber druhe bitove roviny pro cteni
        select_bitplanes_for_write 2  ; vyber druhe bitove roviny pro zapis
        call bitblt                   ; prenos bloku
 
        select_bitplane_for_read 2    ; vyber treti bitove roviny pro cteni
        select_bitplanes_for_write 4  ; vyber treti bitove roviny pro zapis
        call bitblt                   ; prenos bloku
 
        select_bitplane_for_read 3    ; vyber ctvrte bitove roviny pro cteni
        select_bitplanes_for_write 8  ; vyber ctvrte bitove roviny pro zapis
        call bitblt                   ; prenos bloku

14. Úplný zdrojový kód dnešního čtvrtého demonstračního příkladu

Opět se podívejme na úplný zdrojový kód demonstračního příkladu, jenž byl popsán v předchozích kapitolách. Tento příklad nyní vypadá následovně:

; Graficky rezim karty VGA s rozlisenim 640x480 pixelu.
; Zmena barvovych rovin, do kterych se zapisuje.
; Vykresleni barevnych usecek.
; Prenos casti obrazu operaci typu BitBLT - nyni jiz korektni.
; Vyber bitovych rovin pro zapis.
; Vyber bitove roviny pro cteni.
;
; preklad pomoci:
;     nasm -f bin -o vga.com vga_bitblt_4.asm
;
; nebo pouze:
;     nasm -o vga.com vga_bitblt_4.asm
 
 
;-----------------------------------------------------------------------------
 
; I/O porty karty EGA/VGA
GRAPHICS_REGISTER    equ 0x3ce
SEQUENCER_INDEX      equ 0x3c4
SEQUENCER_DATA       equ 0x3c5
 
; registry karty EGA/VGA
BITPLANE_SELECTOR    equ 0x02   ; sequencer
READ_MAP_SELECT      equ 0x04   ; graphics register
 
 
; ukonceni procesu a navrat do DOSu
%macro exit 0
        mov     ah, 0x4c
        int     0x21
%endmacro
 
; vyprazdneni bufferu klavesnice a cekani na klavesu
%macro wait_key 0
        xor     ax, ax
        int     0x16
%endmacro
 
; nastaveni grafickeho rezimu
%macro gfx_mode 1
        mov     ah, 0
        mov     al, %1
        int     0x10
%endmacro
 
; vyber bitove roviny nebo bitovych rovin pro zapis
%macro select_bitplanes_for_write 1
        mov  al, %1         ; bitova rovina
        mov  dx, SEQUENCER_INDEX
        mov  ah, BITPLANE_SELECTOR
        xchg ah, al
        out  dx, ax         ; vyber registru sekvenceru
                            ; a zapis masky bitovych rovin
%endmacro
 
; vyber bitove roviny pro cteni
%macro select_bitplane_for_read 1
        mov  dx, GRAPHICS_REGISTER
        mov  al, READ_MAP_SELECT
        out  dx, al         ; vyber VGA registru pro zapis
        inc  dx,
        mov  al, %1         ; zmena VGA registru
        out  dx, al
%endmacro
 
;-----------------------------------------------------------------------------
org  0x100        ; zacatek kodu pro programy typu COM (vzdy se zacina na 256)
 
start:
        gfx_mode 0x12         ; nastaveni rezimu 640x480 se sestnacti barvami
        call draw_color_lines
        wait_key              ; cekani na klavesu
 
 
        select_bitplane_for_read 0    ; vyber prvni bitove roviny pro cteni
        select_bitplanes_for_write 1  ; vyber prvni bitove roviny pro zapis
        call bitblt                   ; prenos bloku
        wait_key                      ; cekani na klavesu
 
        select_bitplane_for_read 1    ; vyber druhe bitove roviny pro cteni
        select_bitplanes_for_write 2  ; vyber druhe bitove roviny pro zapis
        call bitblt                   ; prenos bloku
        wait_key                      ; cekani na klavesu
 
        select_bitplane_for_read 2    ; vyber treti bitove roviny pro cteni
        select_bitplanes_for_write 4  ; vyber treti bitove roviny pro zapis
        call bitblt                   ; prenos bloku
        wait_key                      ; cekani na klavesu
 
        select_bitplane_for_read 3    ; vyber ctvrte bitove roviny pro cteni
        select_bitplanes_for_write 8  ; vyber ctvrte bitove roviny pro zapis
        call bitblt                   ; prenos bloku
        wait_key                      ; cekani na klavesu
 
        exit                  ; navrat do DOSu
 
 
; operace BitBLT z prvni poloviny obrazovky na druhou polovinu
bitblt:
        mov ax, 0xa000      ; video RAM v textovem rezimu
        mov es, ax
        mov ds, ax
        mov di, 640*240/8   ; nyni ES:DI obsahuje adresu pixelu ve video RAM na 240 radku
        xor si, si          ; nyni DS:SI obsahuje adresu prvniho pixelu ve video RAM
 
        mov cx, 640*240/8   ; pocet prenesenych bajtu
        rep movsb           ; blokovy prenos po bajtech
        ret                 ; hotovo
 
 
draw_color_lines:
        mov ax, 0xa000      ; video RAM v textovem rezimu
        mov es, ax
        xor di, di          ; nyni ES:DI obsahuje adresu prvniho pixelu ve video RAM
 
        mov ax, 0
.opak:
        mov bx, ax          ; y-ová souřadnice
 
        push ax
        mov cl, 15          ; barva
        call putpixel       ; vykreslení pixelu
        pop ax
 
        push ax
        mov cl,  7          ; barva
        add ax, 10          ; horizontalni posun useky
        call putpixel       ; vykreslení pixelu
        pop ax
 
        push ax
        mov cl,  1          ; barva
        add ax, 20          ; horizontalni posun useky
        call putpixel       ; vykreslení pixelu
        pop ax
 
        push ax
        mov cl,  2          ; barva
        add ax, 30          ; horizontalni posun useky
        call putpixel       ; vykreslení pixelu
        pop ax
 
        push ax
        mov cl,  4          ; barva
        add ax, 40          ; horizontalni posun useky
        call putpixel       ; vykreslení pixelu
        pop ax
 
        inc ax              ; pusun x+=1, y+=1
        cmp ax, 480         ; hranice obrazovky?
        jne .opak           ; ne-opakujeme
        ret                 ; hotovo
 
 
; Vykresleni pixelu
; AX - x-ova souradnice
; BX - y-ova souradnice
; CL - barva
putpixel:
        push ax
        mov al, cl         ; vyber bitove roviny nebo bitovych rovin
        select_bitplanes_for_write al
        pop ax
 
        mov dx, 0xa000     ; zacatek stranky video RAM
        mov es, dx         ; nyni obsahuje ES stranku video RAM
 
        mov cl, al
        and cl, 7          ; pouze spodni 3 bity x-ove souradnice
 
        shr ax, 1
        shr ax, 1
        shr ax, 1          ; x/8
        mov di, ax         ; horizontalni posun pocitany v bajtech
 
        mov ax, bx         ; y-ova souradnice
        shl ax, 1          ; y*2
        shl ax, 1          ; y*4
        shl ax, 1          ; y*8
        shl ax, 1          ; y*16
        add di, ax         ; pricist cast y-oveho posunu
        shl ax, 1          ; y*32
        shl ax, 1          ; y*64
        add di, ax         ; pricist zbytek y-oveho posunu
                           ; -> y*16 + y*64 = y*80
 
        mov al, 0x80       ; vypocitat masku pixelu
        shr al, cl
        or [es:di], al     ; vlastni vykresleni pixelu
 
        ret                ; hotovo

15. Obrazovka před blokovým přenosem a po provedení blokového přenosu

Postupný přenos obsahu jednotlivých bitových rovin je zcela jednoduché si vizualizovat – postačuje totiž mezi jednotlivé přenosy vložit expanzi makra pro čekání na stisk klávesy: Můžeme tak sledovat, jak přesně jednotlivé operace vypadají na obrazovce:

vga-bitblt-13

Obrázek 16: Stav obrazovky ještě před zahájením blokových přenosů.

vga-bitblt-14

Obrázek 17: V prvním kroku se korektně přenesl obsah první bitové roviny (bitplane 0) s modrou složkou (mezitím byla modrá „odebrána“ z pravé dolní části obrazu).

vga-bitblt-15

Obrázek 18: Ve druhém kroku se korektně přenesl obsah druhé bitové roviny (bitplane 1) se zelenou složkou. Nyní tedy vidíme kombinace modré a zelené.

vga-bitblt-16

Obrázek 19: Ve třetím kroku se korektně přenesl obsah třetí bitové roviny (bitplane 2) s červenou složkou. Nyní tedy vidíme kombinace modré, zelené a červené, ovšem vše s nízkou intenzitou. V pravé dolní části obrazu zbyla pouze jediná šedá úsečka – černé pixely s vysokou intenzitou.

vga-bitblt-17

Obrázek 20: Dokončení přenosu obsahu čtvrté bitové roviny (bitplane 3). Nyní je již vše zcela korektní.

16. Realizace operace typu BitBLT podprogramem

Postupná expanze maker pro výběr bitových rovin pro čtení a zápis i postupné volání „naivní“ operace BitBLT ve skutečnosti vede ke zbytečně dlouhému i relativně pomalému kódu. Proto si ukažme, jakým způsobem je možné tento problém vyřešit poněkud lepším způsobem. Nejprve si nadefinujeme pole osmi konstant typu byte. Tyto konstanty obsahují index roviny pro čtení následovaný bitovým polem s rovinami pro zápis. To celé se opakuje 4×:

Rovina pro čtení Bitové pole s rovinami pro zápis
0 1 = 0b0001
1 2 = 0b0010
2 4 = 0b0100
3 8 = 0b1000

V assembleru je zápis tohoto neměnného pole snadný:

.regs:  db 0, 1, 1, 2, 2, 4, 3, 8

Dále si nadefinujeme podprogram pro přenos části vybrané bitové roviny blokovou operací typu rep movsb (nebo i po slovech). To již velmi dobře známe:

bitblt_one_bitplane:
        mov di, 640*240/8   ; nyni ES:DI obsahuje adresu pixelu ve video RAM na 240 radku
        xor si, si          ; nyni DS:SI obsahuje adresu prvniho pixelu ve video RAM
 
        mov cx, 640*240/8   ; pocet prenesenych bajtu
        rep movsb           ; blokovy prenos po bajtech
        ret                 ; hotovo

Celá operace BitBLT nastaví (jedenkrát!) segmentové registry a postupně provede čtyři blokové přenosy s využitím již výše nadefinovaného pole .regs:

; operace BitBLT z prvni poloviny obrazovky na druhou polovinu
bitblt:
        mov ax, 0xa000      ; video RAM v textovem rezimu
        mov es, ax
        mov ds, ax
 
        mov  bx, .regs      ; tabulka s mapovanim cteni->zapis
        mov  cx, 4          ; pocet bitovych rovin pro prenos
 
.all_bitplanes:
        mov  dx, GRAPHICS_REGISTER
        mov  al, READ_MAP_SELECT
        mov  ah, cs:[bx]    ; nacteni indexu bitove roviny
        inc  bx             ; posun v tabulce
        out  dx, ax         ; vyber bitove roviny pro cteni
 
        mov  dx, SEQUENCER_INDEX
        mov  al, BITPLANE_SELECTOR
        mov  ah, cs:[bx]    ; vyber bitovych rovin pro zapis
        inc  bx             ; posun v tabulce
        out  dx, ax         ; vyber registru sekvenceru
                            ; a zapis masky bitovych rovin
 
        push cx
        call bitblt_one_bitplane
        pop cx
        loop .all_bitplanes
        ret
Poznámka: pro čtení z .regs je nutné použít registr CS, protože další dva segmentové registry DS a ES ukazují do video paměti.

17. Úplný zdrojový kód dnešního pátého demonstračního příkladu

Dnešní pátý a současně i poslední demonstrační příklad vypadá následovně:

; Graficky rezim karty VGA s rozlisenim 640x480 pixelu.
; Zmena barvovych rovin, do kterych se zapisuje.
; Vykresleni barevnych usecek.
; Prenos casti obrazu operaci typu BitBLT - nyni jiz korektni.
; Vyber bitovych rovin pro zapis.
; Vyber bitove roviny pro cteni.
;
; preklad pomoci:
;     nasm -f bin -o vga.com vga_bitblt_5.asm
;
; nebo pouze:
;     nasm -o vga.com vga_bitblt_5.asm
 
 
;-----------------------------------------------------------------------------
 
; I/O porty karty EGA/VGA
GRAPHICS_REGISTER    equ 0x3ce
SEQUENCER_INDEX      equ 0x3c4
SEQUENCER_DATA       equ 0x3c5
 
; registry karty EGA/VGA
BITPLANE_SELECTOR    equ 0x02   ; sequencer
READ_MAP_SELECT      equ 0x04   ; graphics register
 
 
; ukonceni procesu a navrat do DOSu
%macro exit 0
        mov     ah, 0x4c
        int     0x21
%endmacro
 
; vyprazdneni bufferu klavesnice a cekani na klavesu
%macro wait_key 0
        xor     ax, ax
        int     0x16
%endmacro
 
; nastaveni grafickeho rezimu
%macro gfx_mode 1
        mov     ah, 0
        mov     al, %1
        int     0x10
%endmacro
 
; vyber bitove roviny nebo bitovych rovin pro zapis
%macro select_bitplanes_for_write 1
        mov  al, %1         ; bitova rovina
        mov  dx, SEQUENCER_INDEX
        mov  ah, BITPLANE_SELECTOR
        xchg ah, al
        out  dx, ax         ; vyber registru sekvenceru
                            ; a zapis masky bitovych rovin
%endmacro
 
; vyber bitove roviny pro cteni
%macro select_bitplane_for_read 1
        mov  dx, GRAPHICS_REGISTER
        mov  al, READ_MAP_SELECT
        out  dx, al         ; vyber VGA registru pro zapis
        inc  dx,
        mov  al, %1         ; zmena VGA registru
        out  dx, al
%endmacro
 
;-----------------------------------------------------------------------------
org  0x100        ; zacatek kodu pro programy typu COM (vzdy se zacina na 256)
 
start:
        gfx_mode 0x12         ; nastaveni rezimu 640x480 se sestnacti barvami
        call draw_color_lines
        wait_key              ; cekani na klavesu
 
        call bitblt           ; prenos bloku
        wait_key              ; cekani na klavesu
 
        exit                  ; navrat do DOSu
 
 
; operace BitBLT z prvni poloviny obrazovky na druhou polovinu
bitblt:
        mov ax, 0xa000      ; video RAM v textovem rezimu
        mov es, ax
        mov ds, ax
 
        mov  bx, .regs      ; tabulka s mapovanim cteni->zapis
        mov  cx, 4          ; pocet bitovych rovin pro prenos
 
.all_bitplanes:
        mov  dx, GRAPHICS_REGISTER
        mov  al, READ_MAP_SELECT
        mov  ah, cs:[bx]    ; nacteni indexu bitove roviny
        inc  bx             ; posun v tabulce
        out  dx, ax         ; vyber bitove roviny pro cteni
 
        mov  dx, SEQUENCER_INDEX
        mov  al, BITPLANE_SELECTOR
        mov  ah, cs:[bx]    ; vyber bitovych rovin pro zapis
        inc  bx             ; posun v tabulce
        out  dx, ax         ; vyber registru sekvenceru
                            ; a zapis masky bitovych rovin
 
        push cx
        call bitblt_one_bitplane
        pop cx
        loop .all_bitplanes
        ret
 
.regs:  db 0, 1, 1, 2, 2, 4, 3, 8
 
bitblt_one_bitplane:
        mov di, 640*240/8   ; nyni ES:DI obsahuje adresu pixelu ve video RAM na 240 radku
        xor si, si          ; nyni DS:SI obsahuje adresu prvniho pixelu ve video RAM
 
        mov cx, 640*240/8   ; pocet prenesenych bajtu
        rep movsb           ; blokovy prenos po bajtech
        ret                 ; hotovo
 
 
draw_color_lines:
        mov ax, 0xa000      ; video RAM v textovem rezimu
        mov es, ax
        xor di, di          ; nyni ES:DI obsahuje adresu prvniho pixelu ve video RAM
 
        mov ax, 0
.opak:
        mov bx, ax          ; y-ová souřadnice
 
        push ax
        mov cl, 15          ; barva
        call putpixel       ; vykreslení pixelu
        pop ax
 
        push ax
        mov cl,  7          ; barva
        add ax, 10          ; horizontalni posun useky
        call putpixel       ; vykreslení pixelu
        pop ax
 
        push ax
        mov cl,  1          ; barva
        add ax, 20          ; horizontalni posun useky
        call putpixel       ; vykreslení pixelu
        pop ax
 
        push ax
        mov cl,  2          ; barva
        add ax, 30          ; horizontalni posun useky
        call putpixel       ; vykreslení pixelu
        pop ax
 
        push ax
        mov cl,  4          ; barva
        add ax, 40          ; horizontalni posun useky
        call putpixel       ; vykreslení pixelu
        pop ax
 
        inc ax              ; pusun x+=1, y+=1
        cmp ax, 480         ; hranice obrazovky?
        jne .opak           ; ne-opakujeme
        ret                 ; hotovo
 
 
; Vykresleni pixelu
; AX - x-ova souradnice
; BX - y-ova souradnice
; CL - barva
putpixel:
        push ax
        mov al, cl         ; vyber bitove roviny nebo bitovych rovin
        select_bitplanes_for_write al
        pop ax
 
        mov dx, 0xa000     ; zacatek stranky video RAM
        mov es, dx         ; nyni obsahuje ES stranku video RAM
 
        mov cl, al
        and cl, 7          ; pouze spodni 3 bity x-ove souradnice
 
        shr ax, 1
        shr ax, 1
        shr ax, 1          ; x/8
        mov di, ax         ; horizontalni posun pocitany v bajtech
 
        mov ax, bx         ; y-ova souradnice
        shl ax, 1          ; y*2
        shl ax, 1          ; y*4
        shl ax, 1          ; y*8
        shl ax, 1          ; y*16
        add di, ax         ; pricist cast y-oveho posunu
        shl ax, 1          ; y*32
        shl ax, 1          ; y*64
        add di, ax         ; pricist zbytek y-oveho posunu
                           ; -> y*16 + y*64 = y*80
 
        mov al, 0x80       ; vypocitat masku pixelu
        shr al, cl
        or [es:di], al     ; vlastni vykresleni pixelu
 
        ret                ; hotovo

18. Blokové přenosy s využitím 32bitového záchytného registru latche

I přesto, že je výše uvedené řešení blokového přenosu efektivnější, než expanze mnoha maker, zdaleka se nejedná o rychlou operaci, protože data se přenáší mezi videopamětí přes CPU a tedy i přes sběrnici. I při využití 16bitového přenosu je tedy nutné vždy načíst data z video paměti, přenést je do CPU a následně je zapsat zpět do video paměti.

bitcoin_skoleni

I z tohoto důvodu je v grafické kartě VGA implementován takzvaný záchytný registr neboli latch, který má šířku 32 bitů. Při čtení z video RAM se – nezávisle na vybrané bitové rovině – do latche přečte obsah všech čtyř bitových rovin, konkrétně z každé roviny jeden bajt. A při zápisu lze zvolit takový režim, že se bude ignorovat bajt poslaný z CPU a namísto něho se využije oněch 32 bitů z latche. Výsledkem je, že i když se fyzicky bude přenášet jen jediný bajt, interně karta VGA přenese 32 bitů a tedy zkopíruje osm pixelů (16barevné režimy) nebo čtyři pixely (256barevné režimy). Tímto konceptem, jenž se uplatnil při vykreslování spritů atd., se budeme zabývat příště.

19. Repositář s demonstračními příklady

Demonstrační příklady napsané v assembleru, které jsou určené pro překlad s využitím assembleru NASM, byly uloženy do Git repositáře, který je dostupný na adrese https://github.com/tisnik/8bit-fame. Jednotlivé demonstrační příklady si můžete v případě potřeby stáhnout i jednotlivě bez nutnosti klonovat celý (dnes již poměrně rozsáhlý) repositář:

# Příklad Stručný popis Adresa
1 hello.asm program typu „Hello world“ naprogramovaný v assembleru pro systém DOS https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hello.asm
2 hello_shorter.asm kratší varianta výskoku z procesu zpět do DOSu https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hello_shorter.asm
3 hello_wait.asm čekání na stisk klávesy https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hello_wait.asm
4 hello_macros.asm realizace jednotlivých částí programu makrem https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hello_macros.asm
       
5 gfx4_putpixel.asm vykreslení pixelu v grafickém režimu 4 https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_putpixel.asm
6 gfx6_putpixel.asm vykreslení pixelu v grafickém režimu 6 https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel.asm
7 gfx4_line.asm vykreslení úsečky v grafickém režimu 4 https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_line.asm
8 gfx6_line.asm vykreslení úsečky v grafickém režimu 6 https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_line.asm
       
9 gfx6_fill1.asm vyplnění obrazovky v grafickém režimu, základní varianta https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_fill1.asm
10 gfx6_fill2.asm vyplnění obrazovky v grafickém režimu, varianta s instrukcí LOOP https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_fill2.asm
11 gfx6_fill3.asm vyplnění obrazovky instrukcí REP STOSB https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_fill3.asm
12 gfx6_fill4.asm vyplnění obrazovky, synchronizace vykreslování s paprskem https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_fill4.asm
       
13 gfx4_image1.asm vykreslení rastrového obrázku získaného z binárních dat, základní varianta https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image1.asm
14 gfx4_image2.asm varianta vykreslení rastrového obrázku s využitím instrukce REP MOVSB https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image2.asm
15 gfx4_image3.asm varianta vykreslení rastrového obrázku s využitím instrukce REP MOVSW https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image3.asm
16 gfx4_image4.asm korektní vykreslení všech sudých řádků bitmapy https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image4.asm
17 gfx4_image5.asm korektní vykreslení všech sudých i lichých řádků bitmapy https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image5.asm
       
18 gfx4_image6.asm nastavení barvové palety před vykreslením obrázku https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image6.asm
19 gfx4_image7.asm nastavení barvové palety před vykreslením obrázku, snížená intenzita barev https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image7.asm
20 gfx4_image8.asm postupná změna barvy pozadí https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image8.asm
       
21 gfx6_putpixel1.asm vykreslení pixelu, základní varianta se 16bitovým násobením https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel1.asm
22 gfx6_putpixel2.asm vykreslení pixelu, varianta s osmibitovým násobením https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel2.asm
23 gfx6_putpixel3.asm vykreslení pixelu, varianta bez násobení https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel3.asm
24 gfx6_putpixel4.asm vykreslení pixelu přes obrázek, nekorektní chování (přepis obrázku) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel4.asm
25 gfx6_putpixel5.asm vykreslení pixelu přes obrázek, korektní varianta pro bílé pixely https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel5.asm
       
26 cga_text_mode1.asm standardní textový režim s rozlišením 40×25 znaků https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_mode1.asm
27 cga_text_mode3.asm standardní textový režim s rozlišením 80×25 znaků https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_mode3.asm
28 cga_text_mode_intensity.asm změna významu nejvyššího bitu atributového bajtu: vyšší intenzita namísto blikání https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_mode_intensity.asm
29 cga_text_mode_cursor.asm změna tvaru textového kurzoru https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_mode_cursor.asm
30 cga_text_gfx1.asm zobrazení „rastrové mřížky“: pseudografický režim 160×25 pixelů (interně textový režim) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_gfx1.asm
31 cga_text_mode_char_height.asm změna výšky znaků https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_mode_char_height.asm
32 cga_text_160×100.asm grafický režim 160×100 se šestnácti barvami (interně upravený textový režim) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_160×100.asm
       
33 hercules_text_mode1.asm využití standardního textového režimu společně s kartou Hercules https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_text_mode1.asm
34 hercules_text_mode2.asm zákaz blikání v textových režimech https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_text_mode2.asm
35 hercules_turn_off.asm vypnutí generování video signálu https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_turn_off.asm
36 hercules_gfx_mode1.asm přepnutí karty Hercules do grafického režimu (základní varianta) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_gfx_mode1.asm
37 hercules_gfx_mode2.asm přepnutí karty Hercules do grafického režimu (vylepšená varianta) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_gfx_mode2.asm
38 hercules_putpixel.asm subrutina pro vykreslení jediného pixelu na kartě Hercules https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_putpixel.asm
       
39 ega_text_mode_80×25.asm standardní textový režim 80×25 znaků na kartě EGA https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_text_mode_80×25.asm
40 ega_text_mode_80×43.asm zobrazení 43 textových řádků na kartě EGA https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_text_mode_80×43.asm
41 ega_gfx_mode_320×200.asm přepnutí do grafického režimu 320×200 pixelů se šestnácti barvami https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_gfx_mode_320×200.asm
42 ega_gfx_mode_640×200.asm přepnutí do grafického režimu 640×200 pixelů se šestnácti barvami https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_gfx_mode_640×200.asm
43 ega_gfx_mode_640×350.asm přepnutí do grafického režimu 640×350 pixelů se čtyřmi nebo šestnácti barvami https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_gfx_mode_640×350.asm
44 ega_gfx_mode_bitplanes1.asm ovládání zápisu do bitových rovin v planárních grafických režimech (základní způsob) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_gfx_mode_bitplanes1.asm
45 ega_gfx_mode_bitplanes2.asm ovládání zápisu do bitových rovin v planárních grafických režimech (rychlejší způsob) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_gfx_mode_bitplanes2.asm
       
46 ega_320×200_putpixel.asm vykreslení pixelu v grafickém režimu 320×200 pixelů se šestnácti barvami https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_320×200_putpixel.asm
47 ega_640×350_putpixel.asm vykreslení pixelu v grafickém režimu 640×350 pixelů se šestnácti barvami https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_640×350_putpixel.asm
       
48 ega_standard_font.asm použití standardního fontu grafické karty EGA https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_standard_font.asm
49 ega_custom_font.asm načtení vlastního fontu s jeho zobrazením https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_custom_font.asm
       
50 ega_palette1.asm změna barvové palety (všech 16 barev) v grafickém režimu 320×200 se šestnácti barvami https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_palette1.asm
51 ega_palette2.asm změna barvové palety (všech 16 barev) v grafickém režimu 640×350 se šestnácti barvami https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_palette2.asm
52 ega_palette3.asm změna všech barev v barvové paletě s využitím programové smyčky https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_palette3.asm
53 ega_palette4.asm změna všech barev, včetně barvy okraje, v barvové paletě voláním funkce BIOSu https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_palette4.asm
       
54 vga_text_mode_80×25.asm standardní textový režim 80×25 znaků na kartě VGA https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_80×25.asm
55 vga_text_mode_80×50.asm zobrazení 50 a taktéž 28 textových řádků na kartě VGA https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_80×50.asm
56 vga_text_mode_intensity1.asm změna chování atributového bitu pro blikání (nebezpečná varianta změny registrů) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_intensity1.asm
57 vga_text_mode_intensity2.asm změna chování atributového bitu pro blikání (bezpečnější varianta změny registrů) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_intensity2.asm
58 vga_text_mode_9th_column.asm modifikace způsobu zobrazení devátého sloupce ve znakových režimech (720 pixelů na řádku) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_9th_column.asm
59 vga_text_mode_cursor_shape.asm změna tvaru textového kurzoru na grafické kartě VGA https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_cursor_shape.asm
60 vga_text_mode_custom_font.asm načtení vlastního fontu s jeho zobrazením https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_custom_font.asm
       
61 vga_gfx_mode_640×480.asm přepnutí do grafického režimu 640×480 pixelů se šestnácti barvami, vykreslení vzorků https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_640×480.asm
62 vga_gfx_mode_320×200.asm přepnutí do grafického režimu 320×200 pixelů s 256 barvami, vykreslení vzorků https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_320×200.asm
63 vga_gfx_mode_palette.asm změna všech barev v barvové paletě grafické karty VGA https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_palette.asm
64 vga_gfx_mode_dac1.asm využití DAC (neočekávané výsledky) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_dac1.asm
65 vga_gfx_mode_dac2.asm využití DAC (očekávané výsledky) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_dac2.asm
       
66 vga_640×480_putpixel.asm realizace algoritmu pro vykreslení pixelu v grafickém režimu 640×480 pixelů se šestnácti barvami https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_640×480_putpixel.asm
67 vga_320×200_putpixel1.asm realizace algoritmu pro vykreslení pixelu v grafickém režimu 320×200 s 256 barvami (základní varianta) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_putpixel1.asm
68 vga_320×200_putpixel2.asm realizace algoritmu pro vykreslení pixelu v grafickém režimu 320×200 s 256 barvami (rychlejší varianta) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_putpixel2.asm
       
69 vga_gfx_mode_dac3.asm přímé využití DAC v grafickém režimu 13h https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_dac3.asm
       
70 vga_gfx_mode_unchained_step1.asm zobrazení barevných pruhů v režimu 13h https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_unchained_step1.asm
71 vga_gfx_mode_unchained_step2.asm vypnutí zřetězení bitových rovin a změna způsobu adresování pixelů https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_unchained_step2.asm
72 vga_gfx_mode_unchained_step3.asm vykreslení barevných pruhů do vybraných bitových rovin https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_unchained_step3.asm
       
73 vga_gfx_mode_320×400.asm nestandardní grafický režim s rozlišením 320×400 pixelů a 256 barvami https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_320×400.asm
74 vga_320×200_image.asm zobrazení rastrového obrázku ve standardním grafickém režimu 320×200 pixelů https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_image.asm
75 vga_320×200_unchained_image1.asm zobrazení rastrového obrázku v režimu s nezřetězenými rovinami (nekorektní řešení) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_unchained_image1.asm
76 vga_320×200_unchained_image2.asm zobrazení rastrového obrázku v režimu s nezřetězenými rovinami (korektní řešení) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_unchained_image2.asm
77 vga_320×400_unchained_image.asm zobrazení rastrového obrázku v nestandardním režimu 320×400 pixelů https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×400_unchained_image.asm
       
78 vga_vertical_scroll1.asm vertikální scrolling na kartě VGA v režimu s rozlišením 320×200 pixelů https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_vertical_scroll1.asm
79 vga_vertical_scroll2.asm vertikální scrolling na kartě VGA v režimu s rozlišením 320×400 pixelů https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_vertical_scroll2.asm
80 vga_split_screen1.asm režim split-screen a scrolling, nefunční varianta https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_split_screen1.asm
81 vga_split_screen2.asm režim split-screen a scrolling, plně funkční varianta https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_split_screen2.asm
82 vga_horizontal_scroll1.asm horizontální scrolling bez rozšíření počtu pixelů na virtuálním řádku https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_horizontal_scroll1.asm
83 vga_horizontal_scroll2.asm horizontální scrolling s rozšířením počtu pixelů na virtuálním řádku https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_horizontal_scroll2.asm
84 vga_horizontal_scroll3.asm jemný horizontální scrolling s rozšířením počtu pixelů na virtuálním řádku https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_horizontal_scroll3.asm
       
85 vga_320×240_image.asm nastavení grafického režimu Mode-X, načtení a vykreslení obrázku, scrolling https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×240_image.asm
       
86 io.asm knihovna maker pro I/O operace https://github.com/tisnik/8bit-fame/blob/master/pc-dos/io.asm
87 vga_lib.asm knihovna maker a podprogramů pro programování karty VGA https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_lib.asm
88 vga_320×240_lib.asm nastavení grafického režimu Mode-X, tentokrát knihovními funkcemi https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×240_lib.asm
       
89 vga_bitblt1.asm první (naivní) implementace operace BitBLT https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_bitblt1.asm
90 vga_bitblt2.asm operace BitBLT s výběrem bitových rovin pro zápis https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_bitblt2.asm
91 vga_bitblt3.asm operace BitBLT s výběrem bitových rovin pro čtení i zápis https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_bitblt3.asm
92 vga_bitblt4.asm korektní BitBLT pro 16barevný režim, realizace makry https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_bitblt4.asm
93 vga_bitblt5.asm korektní BitBLT pro 16barevný režim, realizace podprogramem https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_bitblt5.asm

20. Odkazy na Internetu

  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
  90. Instruction Format in 8086 Microprocessor
    https://www.includehelp.com/embedded-system/instruction-format-in-8086-microprocessor.aspx
  91. How to use „AND,“ „OR,“ and „XOR“ modes for VGA Drawing
    https://retrocomputing.stac­kexchange.com/questions/21936/how-to-use-and-or-and-xor-modes-for-vga-drawing
  92. VGA Hardware
    https://wiki.osdev.org/VGA_Hardware
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.