Obsah
1. Skrytá síla karty VGA: čtecí a zápisové režimy (dokončení)
2. Bitová rotace při zápisu hodnot do video paměti
3. Úplný zdrojový kód dnešního prvního demonstračního příkladu
4. Vizuální ukázka postupné bitové rotace
5. Využití záchytného registru při blokových přenosech
6. Volba zápisového režimu a blokový přenos po 32 bitech
7. Úplný zdrojový kód dnešního druhého demonstračního příkladu
8. Využití záchytného registru v režimech s 256 barvami
9. Přenos obrázku z horní poloviny obrazovky do dolní poloviny v 256barevném režimu
10. Blokový přenos v 256barevném nezřetězeném režimu bez přímého využití latche
11. Výsledky blokového přenosu
12. Blokový přenos v 256barevném nezřetězeném režimu s využitím latche
13. Výsledky blokového přenosu
14. Logické operace prováděné při zápisu do obrazové paměti
15. Vyplnění části obrazovky s volitelnou aplikací logické operace
16. Vyplnění části obrazovky konstantní barvou při zákazu logických operací
17. Obnova obsahu latche před každým zápisem
18. Nastavení logické operace prováděné při zápisu do obrazové paměti
19. Repositář s demonstračními příklady
1. Skrytá síla karty VGA: čtecí a zápisové režimy (dokončení)
V dnešním článku dokončíme popis programování grafické karty VGA. Ukážeme si, jaké zbylé operace je možné provádět při čtení, resp. při zápisu do obrazové paměti – protože mezi mikroprocesorem a video pamětí leží nejenom (pomalá) sběrnice, ale i několik obvodů na řadiči VGA, které dokážou provádět logické operace, bitové operace, rozkopírování dat do bitových rovin, ale například i zápis hodnot pixelů z takzvaného záchytného registru (latche). Tyto operace se řídí pomocí registrů grafického řadiče dostupného na I/O portu 0×3ce a 0×3cf (volba registru a zápis či čtení informace do/z registru):
Index | Název | Stručný popis |
---|---|---|
00 | Set/Reset | hodnoty bitů v tomto registru se mohou zapsat do bitových rovin (bez ohledu na zapisovaná data) |
01 | Enable Set/Reset | volba, zda se při zápisu mají použít zapisovaná data nebo bity z předchozího registru |
02 | Color Compare | barva 0–15 použitá ve čtecím režimu číslo 1 |
03 | Data Rotate | volba logické operace a rotace bitů (viz další text) |
04 | Read Map Select | volba bitové roviny pro operaci čtení (již známe) |
05 | Graphics Mode | volba čtecích a zápisových režimů, přepnutí do režimu s 256 barvami atd. |
06 | Miscellaneous Graphics | volba adresování video paměti, režimu sudá-lichá atd. |
07 | Color Don't Care | barva 0–15 použitá ve čtecím režimu číslo |
08 | Bit Mask | bitová maska při zápisu (platí pro všechny bitové roviny) |
Zajímavá je kombinace prvních dvou registrů, protože s jejich využitím lze zajistit „kolmý režim“ zápisu. Barva se zapíše do prvního registru (0–15), druhý registr se nastaví na hodnotu 15 a poté lze jedním zápisem (libovolné hodnoty) nastavit barvu sousedních pixelů. Popř. lze ještě použít poslední registr BitMask pro maskování, které pixely se mají změnit. Základní způsob použití lze otestovat na příkladu vga_set_reset.asm.
2. Bitová rotace při zápisu hodnot do video paměti
První operací, kterou si dnes popíšeme, je bitová rotace prováděná při zápisu hodnot do video paměti. Bajty (nikoli celá slova) se totiž před zápisem do video paměti podrobují logickým operacím, které si vysvětlíme dále, a taktéž rotaci o 0 až 7 bitů. Obě tyto operace se konfigurují v řídicím registru nazvaném DATA ROTATE, který má následující strukturu:
+---+---+---+---+---+---+---+---+ | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | +---+---+---+---+---+---+---+---+ | | | |logická| bitová | | | | |operace| rotace | +---+---+---+---+---+---+---+---+
Pro zápis hodnot do tohoto řídicího registru grafické karty VGA použijeme toto makro:
; nastaveni logickeho rezimu pri zapisu %macro write_bit_rotate 1 mov dx, GRAPHICS_REGISTER mov al, DATA_ROTATE out dx, al ; vyber VGA registru pro zapis inc dx, mov al, %1 ; zmena VGA registru out dx, al %endmacro
V demonstračním příkladu budeme provádět operaci BitBLT (tedy blokový přenos) z první poloviny obrazovky do druhé poloviny (obrazovka je vyplněna barevnými úsečkami). Přitom budeme postupně měnit počet rotovaných bitů od 0 (výchozí hodnota) do sedmi. Pro zajímavost použijeme jako počitadlo smyčky osmibitový pracovní registr AH, i když se typicky používá CX nebo pro osmibitové operace CL:
mov ah, 0 .rotate: push ax write_bit_rotate ah ; rotace bitu pri zapisu do bitovych rovin call bitblt ; prenos bloku wait_key ; cekani na klavesu pop ax inc ah cmp ah, 8 jne .rotate
3. Ú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, který při blokovém přenosu provádí bitové rotace bajtů zapisovaných do video paměti, 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. ; Rotace bitu pri zapisu. ; ; preklad pomoci: ; nasm -f bin -o vga.com vga_bitblt_rotate.asm ; ; nebo pouze: ; nasm -o vga.com vga_bitblt_rotate.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 DATA_ROTATE equ 0x03 ; graphics register 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 ; nastaveni logickeho rezimu pri zapisu %macro write_bit_rotate 1 mov dx, GRAPHICS_REGISTER mov al, DATA_ROTATE 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 mov ah, 0 .rotate: push ax write_bit_rotate ah ; rotace bitu pri zapisu do bitovych rovin call bitblt ; prenos bloku wait_key ; cekani na klavesu pop ax inc ah cmp ah, 8 jne .rotate 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 usecky call putpixel ; vykreslení pixelu pop ax push ax mov cl, 1 ; barva add ax, 20 ; horizontalni posun usecky call putpixel ; vykreslení pixelu pop ax push ax mov cl, 2 ; barva add ax, 30 ; horizontalni posun usecky call putpixel ; vykreslení pixelu pop ax push ax mov cl, 4 ; barva add ax, 40 ; horizontalni posun usecky 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
4. Vizuální ukázka postupné bitové rotace
Podívejme se nyní, jak vlastně bitová rotace zapisovaných bajtů vypadá v praxi. Pro rotaci 0 až 7 bitů vypadají výsledné obsahy obrazovek následovně:
Obrázek 1: Původní obrázek, prozatím bez provedení blokového přenosu.
Obrázek 2: Přenos s bitovou rotací o 0 bitů (tedy bez rotace).
Obrázek 3: Přenos s bitovou rotací o 1 bit.
Obrázek 4: Přenos s bitovou rotací o 2 bity.
Obrázek 5: Přenos s bitovou rotací o 3 bity.
Obrázek 6: Přenos s bitovou rotací o 4 bity.
Obrázek 7: Přenos s bitovou rotací o 5 bitů.
Obrázek 8: Přenos s bitovou rotací o 6 bitů.
Obrázek 9: Přenos s bitovou rotací o 7 bitů.
5. Využití záchytného registru při blokových přenosech
Poměrně často se setkáme s nutností přenosu větších bloků dat do viditelné části obrazové paměti. Příkladem může být kurzor myši, ale například i postavy nebo další pohybující se předměty ve hrách. Ovšem grafická karta VGA neobsahuje specializovaný obvod pro blokové přenosy, takže je nutné je realizovat programově („ručně“). Nabízí se dvě řešení. První z těchto řešení spočívá v tom, že se obrazová data (bloky) budou přenášet z operační paměti přes relativně pomalou sběrnici VGA.
A druhá varianta spočívá v tom, že si tyto bloky uložíme do neviditelné části obrazové paměti a přenos bude prováděn z jedná oblasti obrazové paměti do oblasti jiné. To, jak využijeme neviditelnou část obrazové paměti, totiž záleží čistě na nás – může se jednat o druhý či třetí zadní buffer, buffer pro grafické bloky – sprity atd.
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 v této části článku.
6. Volba zápisového režimu a blokový přenos po 32 bitech
Činnost záchytného registru při blokových přenosech lze popsat následovně:
- Při čtení (bajtu!) z předem zvolené bitové roviny se ve skutečnosti přečtou čtyři bajty, z každé bitové roviny jeden.
- Všechny čtyři přečtené bajty se zapíšou do záchytného registru (latche).
- CPU získá pouze hodnotu bajtu z vybrané bitové roviny (to již známe).
- Pokud je zvolen zápisový režim číslo 2, bude se zapisovaný bajt ignorovat a ve skutečnosti se do všech čtyř bitových rovin zapíšou bajty uložené dolatche – zapíše se tedy celých 32 bitů.
Volbu zápisového režimu provedeme tímto pomocným makrem:
; nastaveni zapisoveho rezimu %macro write_mode 1 mov dx, GRAPHICS_REGISTER mov al, GRAPHICS_MODE out dx, al ; vyber VGA registru pro zapis inc dx, mov al, %1 ; zmena VGA registru out dx, al %endmacro
Zápisový režim číslo 2 se volí následovně:
write_mode 0b00000001 ; zapisovy rezim cislo 2 call bitblt ; prenos bloku
Nakonec samotná realizace blokového přenosu (polovina obrazovky) pracuje jen s jednou bitovou rovinou (z pohledu CPU):
; 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ýsledky odpovídají očekávání:
Obrázek 10: Obrazovka před provedením blokového přenosu.
Obrázek 11: Obrazovka po provedení blokového přenosu.
7. Úplný zdrojový kód dnešního druhého demonstračního příkladu
Úplná podoba dnešního druhého demonstračního příkladu s implementací rychlé operace typu BitBLT 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. ; Pro prenos dat se pouziva 32bitovy latch. ; ; preklad pomoci: ; nasm -f bin -o vga.com vga_bitblt_fast.asm ; ; nebo pouze: ; nasm -o vga.com vga_bitblt_fast.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 GRAPHICS_MODE equ 0x05 ; graphics register 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 ; nastaveni zapisoveho rezimu %macro write_mode 1 mov dx, GRAPHICS_REGISTER mov al, GRAPHICS_MODE 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 select_bitplanes_for_write 15 wait_key ; cekani na klavesu write_mode 0b00000001 ; zapisovy rezim cislo 2 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 usecky call putpixel ; vykreslení pixelu pop ax push ax mov cl, 1 ; barva add ax, 20 ; horizontalni posun usecky call putpixel ; vykreslení pixelu pop ax push ax mov cl, 2 ; barva add ax, 30 ; horizontalni posun usecky call putpixel ; vykreslení pixelu pop ax push ax mov cl, 4 ; barva add ax, 40 ; horizontalni posun usecky 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
8. Využití záchytného registru v režimech s 256 barvami
V šestnáctibarevných režimech je záchytný registr použit přesně tak, jak to bylo popsáno v předchozím textu, a umožňuje nám tak přenášet jedinou operací osm sousedních pixelů. V režimech s 256 barvami je situace obdobná, ovšem kvůli odlišné organizaci video paměti se na celou operaci můžeme dívat nepatrně jiným způsobem:
- Při čtení se z každé bitové roviny přečte barva jednoho pixelu. Všechny čtyři přečtené barvy se uloží do latche.
- Při zápisu se čtyři barvy z latche zapíšou do jednotlivých bitových rovin.
Způsob provedené blokové operace s nezřetězených 256 režimech si ukážeme v navazujících kapitolách (ve zřetězeném režimu 13h postrádá význam, protože vždy 3 bajty jsou nevyužity).
9. Přenos obrázku z horní poloviny obrazovky do dolní poloviny v 256barevném režimu
Samotná realizace blokového přenosu rastrového obrázku z horní poloviny obrazovky do dolní poloviny v režimech s 256 barvami a s nezřetězenými rovinami může vypadat následovně. Povšimněte si, že s obrazovou pamětí pracujeme, jakoby nebyla rozdělena na bitové roviny, takže se výsledky přenosu budou odlišovat podle toho, jestli využijeme latch (tedy zápisový režim 2) nebo nikoli. Subrutina je upravena pro grafický režim s rozlišením 320×400 pixelů:
; 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, 320*200/4 ; nyni ES:DI obsahuje adresu pixelu ve video RAM na 200 radku xor si, si ; nyni DS:SI obsahuje adresu prvniho pixelu ve video RAM mov cx, 320*200/4 ; pocet prenesenych bajtu rep movsb ; blokovy prenos po bajtech ret ; hotovo
10. Blokový přenos v 256barevném nezřetězeném režimu bez přímého využití latche
Nejprve se pokusíme o blokový přenos rastrového obrázku v režimu 320×400 při použití zápisového režimu číslo 0, tedy režimu, v němž je nutné vybrat bitovou rovinu (nebo bitové roviny) pro zápis. Před zavoláním subrutiny bitblt nastavíme všechny čtyři bitové roviny pro zápis, takže se každý přečtený pixel rozkopíruje do všech čtyř rovin (a vlastně se tak 4× sníží horizontální rozlišení):
select_bitplane 15 ; vyber vsech bitovych rovin call bitblt ; prenos bloku
A takto vypadá úplný zdrojový kód tohoto demonstračního příkladu:
; Graficky rezim karty VGA s rozlisenim 320x400 pixelu. ; Vypnuti zretezeni bitovych rovin. ; Vykresleni rastroveho obrazku postupne do vsech bitovych rovin. ; Bitovy prenos (nedokonceny). ; ; preklad pomoci: ; nasm -f bin -o vga.com vga_320x400_bitblt_1.asm ; ; nebo pouze: ; nasm -o vga.com vga_320x400_bitblt_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 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 s 256 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 select_bitplane 2 ; druha bitplane mov ax, 1 call move_image_part; prenest obrazek select_bitplane 4 ; treti bitplane mov ax, 2 call move_image_part; prenest obrazek select_bitplane 8 ; ctvrta bitplane mov ax, 3 call move_image_part; prenest obrazek wait_key ; cekani na klavesu select_bitplane 15 ; vyber vsech 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, 320*200/4 ; nyni ES:DI obsahuje adresu pixelu ve video RAM na 200 radku xor si, si ; nyni DS:SI obsahuje adresu prvniho pixelu ve video RAM mov cx, 320*200/4 ; pocet prenesenych bajtu rep movsb ; blokovy prenos po bajtech ret ; hotovo 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) .block_move: lodsb ; nacist bajt z obrazku add si, 3 ; celkove posun o 4 pixely v obrazku stosb ; ulozit do obrazove pameti loop .block_move ; presunout CX pixelu ret ; pridani binarnich dat s rastrovym obrazkem image: incbin "image_320x200.bin"
11. Výsledky blokového přenosu
Podívejme se nyní na výsledky blokového přenosu realizovaného příkladem z předchozí kapitoly:
Obrázek 12: Obrazovka před provedením blokového přenosu obrázku.
Obrázek 13: Obrazovka po provedení blokového přenosu obrázku.
Ze zobrazených výsledků je zřejmé, že se skutečně přečetla jen čtvrtina pixelů, ovšem díky zápisu do všech čtyř bitových rovin se hodnoty každého pixelu zapsaly i do trojice pixelů sousedních (mimochodem: podobný způsob je realizován i v původní hře Doom, pokud se přepnete do režimu s nižším rozlišením).
12. Blokový přenos v 256barevném nezřetězeném režimu s využitím latche
Nyní předchozí demonstrační příklad nepatrně upravíme, a to konkrétně takovým způsobem, že před blokovým přenosem rastrového obrázku nastavíme zápisový režim číslo 2. Současně stále musíme povolit zápis do všech bitových rovin (zkuste si tuto část změnit a uvidíte proč):
select_bitplane 15 ; vyber vsech bitovych rovin write_mode 0b01000001 ; zapisovy rezim cislo 2 call bitblt ; prenos bloku
Opět se podívejme na úplný zdrojový kód takto upraveného příkladu:
; Graficky rezim karty VGA s rozlisenim 320x400 pixelu. ; Vypnuti zretezeni bitovych rovin. ; Vykresleni rastroveho obrazku postupne do vsech bitovych rovin. ; Bitovy prenos (dokonceny). ; ; preklad pomoci: ; nasm -f bin -o vga.com vga_320x400_bitblt_2.asm ; ; nebo pouze: ; nasm -o vga.com vga_320x400_bitblt_2.asm ;----------------------------------------------------------------------------- ; registry karty VGA SEQUENCER_INDEX equ 0x3c4 SEQUENCER_DATA equ 0x3c5 CRTC_INDEX equ 0x3d4 CRTC_DATA equ 0x3d5 GRAPHICS_REGISTER equ 0x3ce BITPLANE_SELECTOR equ 0x02 GRAPHICS_MODE equ 0x05 ; graphics register READ_MAP_SELECT equ 0x04 ; graphics register 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 ; nastaveni zapisoveho rezimu %macro write_mode 1 mov dx, GRAPHICS_REGISTER mov al, GRAPHICS_MODE 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 0x13 ; nastaveni rezimu 320x200 s 256 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 select_bitplane 2 ; druha bitplane mov ax, 1 call move_image_part; prenest obrazek select_bitplane 4 ; treti bitplane mov ax, 2 call move_image_part; prenest obrazek select_bitplane 8 ; ctvrta bitplane mov ax, 3 call move_image_part; prenest obrazek wait_key ; cekani na klavesu select_bitplane 15 ; vyber vsech bitovych rovin write_mode 0b01000001 ; zapisovy rezim cislo 2 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, 320*200/4 ; nyni ES:DI obsahuje adresu pixelu ve video RAM na 200 radku xor si, si ; nyni DS:SI obsahuje adresu prvniho pixelu ve video RAM mov cx, 320*200/4 ; pocet prenesenych bajtu rep movsb ; blokovy prenos po bajtech ret ; hotovo 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) .block_move: lodsb ; nacist bajt z obrazku add si, 3 ; celkove posun o 4 pixely v obrazku stosb ; ulozit do obrazove pameti loop .block_move ; presunout CX pixelu ret ; pridani binarnich dat s rastrovym obrazkem image: incbin "image_320x200.bin"
13. Výsledky blokového přenosu
Nyní již bude celý rastrový obrázek přenesen (resp. přesněji řečeno zkopírován) naprosto bez problémů, což je patrné z následující dvojice screenshotů:
Obrázek 14: Obrazovka před provedením blokového přenosu obrázku.
Obrázek 15: Obrazovka po provedení blokového přenosu obrázku.
14. Logické operace prováděné při zápisu do obrazové paměti
Již v úvodní části dnešního článku jsme si řekli, že před zápisem osmice bitů do obrazové paměti se tyto bity rotují a taktéž se na ně aplikují logické operace, které jsou provedeny mezi zapisovanou hodnotou a hodnotou uloženou v latchi (obsah latche se nezmění). Následně pochopitelně závisí na tom, jak se výsledek interpretuje – pokud je totiž například povolen zápis jen do jediné bitové roviny, využije se jen 8 bitů výsledků a zbylých 24 bitů se bude ignorovat.
Logická operace je specifikována v nám již známém registru DATA_ROTATE ve dvou bitech:
+---+---+---+---+---+---+---+---+ | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | +---+---+---+---+---+---+---+---+ | | | |logická| bitová | | | | |operace| rotace | +---+---+---+---+---+---+---+---+
Význam těchto dvou bitů je následující:
Bit 4 | Bit 3 | Prováděná operace |
---|---|---|
0 | 0 | logická operace se neprovádí (přímý zápis) |
0 | 1 | logická operace AND |
1 | 0 | logická operace OR |
1 | 1 | logická operace XOR |
15. Vyplnění části obrazovky s volitelnou aplikací logické operace
V poslední trojici demonstračních příkladů věnovaných grafické kartě VGA se v 16barevném režimu pokusíme o vykreslení barevných úseček (to již dobře známe) a následně vyplníme spodní polovinu obrazovky několika barevnými plochami (tj. výběrem různé kombinace bitových rovin):
mov ax, 0xa000 ; video RAM v textovem rezimu mov es, ax mov ds, ax xor si, si ; nyni DS:SI obsahuje adresu prvniho pixelu ve video RAM xor di, di ; nyni ES:DI obsahuje adresu prvniho pixelu ve video RAM select_bitplane 0 ; vyber bitove roviny nebo bitovych rovin call fill_screen_area ; vypln casti obrazovky select_bitplane 1 ; vyber bitove roviny nebo bitovych rovin call fill_screen_area ; vypln casti obrazovky select_bitplane 7 ; vyber bitove roviny nebo bitovych rovin call fill_screen_area ; vypln casti obrazovky select_bitplane 8 ; vyber bitove roviny nebo bitovych rovin call fill_screen_area ; vypln casti obrazovky select_bitplane 15 ; vyber bitove roviny nebo bitovych rovin call fill_screen_area ; vypln casti obrazovky
Samotná výplň části obrazovky je řešena jednoduše (později dojde k nutné úpravě):
; vyplneni casti obrazovky fill_screen_area: mov cx, 640*100/8 ; pocet zapisu mov al, 0xff ; zapisovany vzorek rep stosb ; provest vyplneni casti obrazovky (muze se vyuzit latch) ret ; hotovo
Přitom budeme sledovat, jak se bude výsledek lišit podle toho, jakou logickou operaci nastavíme. Ve výchozím stavu je provedení logických operací vypnuto, stejně jako je rotace bitů nastavena na nulu.
16. Vyplnění části obrazovky konstantní barvou při zákazu logických operací
Podívejme se nyní na to, jak vlastně bude vypadat obrazovka v 16barevném grafickém režimu před vyplněním obrazovky (tj. ve chvíli, kdy nakreslíme sadu barevných úseček) a po provedení vyplnění:
Obrázek 16: Původní obrazovka, prozatím před vyplněním.
Obrázek 17: Obrazovka po vyplnění její části „konstantní“ barvou.
Ze screenshotů je patrné, že jsme vlastně vyplnění neprovedli korektně, protože zápis (například) modré barvy pro nás znamenal, že se nastavily pouze bity v první bitové rovině a další roviny jsme při zápisu zcela ignorovali. Úsečky tedy nebyly zcela přemazány, což ovšem v některých případech nevadí – naopak se může jednat o žádoucí efekt.
Úplný kód demonstračního příkladu, který vykreslil obrázky číslo 16 a 17, vypadá následovně:
; Graficky rezim karty VGA s rozlisenim 640x480 pixelu. ; Zmena barvovych rovin, do kterych se zapisuje. ; Vykresleni barevnych usecek. ; Prekresleni s vyuzitim bezneho "MOV" rezimu. ; ; preklad pomoci: ; nasm -f bin -o vga.com vga_write_mode_1.asm ; ; nebo pouze: ; nasm -o vga.com vga_write_mode_1.asm ;----------------------------------------------------------------------------- ; I/O porty karty EGA/VGA SEQUENCER_INDEX equ 0x3c4 SEQUENCER_DATA equ 0x3c5 ; registry karty EGA/VGA BITPLANE_SELECTOR equ 0x02 ; controller ; 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 mov ax, 0xa000 ; video RAM v textovem rezimu mov es, ax mov ds, ax xor si, si ; nyni DS:SI obsahuje adresu prvniho pixelu ve video RAM xor di, di ; nyni ES:DI obsahuje adresu prvniho pixelu ve video RAM select_bitplane 0 ; vyber bitove roviny nebo bitovych rovin call fill_screen_area ; vypln casti obrazovky select_bitplane 1 ; vyber bitove roviny nebo bitovych rovin call fill_screen_area ; vypln casti obrazovky select_bitplane 7 ; vyber bitove roviny nebo bitovych rovin call fill_screen_area ; vypln casti obrazovky select_bitplane 8 ; vyber bitove roviny nebo bitovych rovin call fill_screen_area ; vypln casti obrazovky select_bitplane 15 ; vyber bitove roviny nebo bitovych rovin call fill_screen_area ; vypln casti obrazovky wait_key ; cekani na klavesu exit ; navrat do DOSu ; vyplneni casti obrazovky fill_screen_area: mov cx, 640*100/8 ; pocet zapisu mov al, 0xff ; zapisovany vzorek rep stosb ; provest vyplneni casti obrazovky (muze se vyuzit latch) 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, 10 ; barva call putpixel ; vykreslení pixelu pop ax push ax mov cl, 11 ; barva add ax, 10 ; horizontalni posun usecky call putpixel ; vykreslení pixelu pop ax push ax mov cl, 12 ; barva add ax, 20 ; horizontalni posun usecky 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
17. Obnova obsahu latche před každým zápisem
V předchozím příkladu bylo vyplnění obrazovky realizováno tímto kódem, který do obrazové paměti pouze zapisovat bitový vzorek 0×ff:
; vyplneni casti obrazovky fill_screen_area: mov cx, 640*100/8 ; pocet zapisu mov al, 0xff ; zapisovany vzorek rep stosb ; provest vyplneni casti obrazovky (muze se vyuzit latch) ret ; hotovo
To ovšem znamenalo, že latch stále obsahoval pouze původní hodnotu (z první a současně i poslední operace čtení). Pokud budeme chtít obsah latche (32 bitů) vždy obnovit před každým zápisem, je nutné funkci pro vyplnění obrazovky nepatrně upravit. Před každým zápisem jsou načteny obsahy bitových rovin (na korektním místě na obrazovce) do latche a následně je proveden zápis, s potenciálním využitím logických funkcí atd.:
; vyplneni casti obrazovky fill_screen_area: mov cx, 640*100/8 ; pocet zapisu .loop: lodsb ; precteni hodnot do latche stosb ; provest vyplneni casti obrazovky loop .loop ret ; hotovo
Výsledek bude (podle očekávání) odlišný:
Obrázek 18: Původní obrazovka, prozatím před vyplněním.
Obrázek 19: Obrazovka po vyplnění její části „konstantní“ barvou.
Následuje úplný zdrojový kód tohoto demonstračního příkladu, který vypadá následovně:
; Graficky rezim karty VGA s rozlisenim 640x480 pixelu. ; Zmena barvovych rovin, do kterych se zapisuje. ; Vykresleni barevnych usecek. ; Prekresleni s vyuzitim latche. ; ; preklad pomoci: ; nasm -f bin -o vga.com vga_write_mode_2.asm ; ; nebo pouze: ; nasm -o vga.com vga_write_mode_2.asm ;----------------------------------------------------------------------------- ; I/O porty karty EGA/VGA SEQUENCER_INDEX equ 0x3c4 SEQUENCER_DATA equ 0x3c5 ; registry karty EGA/VGA BITPLANE_SELECTOR equ 0x02 ; controller ; 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 mov ax, 0xa000 ; video RAM v textovem rezimu mov es, ax mov ds, ax xor si, si ; nyni DS:SI obsahuje adresu prvniho pixelu ve video RAM xor di, di ; nyni ES:DI obsahuje adresu prvniho pixelu ve video RAM select_bitplane 0 ; vyber bitove roviny nebo bitovych rovin call fill_screen_area ; vypln casti obrazovky select_bitplane 1 ; vyber bitove roviny nebo bitovych rovin call fill_screen_area ; vypln casti obrazovky select_bitplane 7 ; vyber bitove roviny nebo bitovych rovin call fill_screen_area ; vypln casti obrazovky select_bitplane 8 ; vyber bitove roviny nebo bitovych rovin call fill_screen_area ; vypln casti obrazovky select_bitplane 15 ; vyber bitove roviny nebo bitovych rovin call fill_screen_area ; vypln casti obrazovky wait_key ; cekani na klavesu exit ; navrat do DOSu ; vyplneni casti obrazovky fill_screen_area: mov cx, 640*100/8 ; pocet zapisu .loop: lodsb ; precteni hodnot do latche stosb ; provest vyplneni casti obrazovky loop .loop 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, 10 ; barva call putpixel ; vykreslení pixelu pop ax push ax mov cl, 11 ; barva add ax, 10 ; horizontalni posun usecky call putpixel ; vykreslení pixelu pop ax push ax mov cl, 12 ; barva add ax, 20 ; horizontalni posun usecky 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
18. Nastavení logické operace prováděné při zápisu do obrazové paměti
Nyní, když již víme, jakým způsobem lze obnovit obsah latche, se můžeme pokusit o nastavení vhodné logické operace prováděné při zápisu. Pro volbu logické operace použijeme toto makro:
; nastaveni logickeho rezimu pri zapisu %macro write_logic_mode 1 mov dx, GRAPHICS_REGISTER mov al, DATA_ROTATE out dx, al ; vyber VGA registru pro zapis inc dx, mov al, %1 ; zmena VGA registru out dx, al %endmacro
Připomeňme si, že v registru DATA_ROTATE se volí jak požadovaná logická operace, tak i rotace bitů při zápisu. Logická operace je určena čtvrtým a pátým bitem. Pokusme se nastavit operaci XOR (logické nonekvivalence):
write_logic_mode 0b00110000 ; rezim XOR select_bitplane 0 ; vyber bitove roviny nebo bitovych rovin call fill_screen_area ; vypln casti obrazovky
Výsledek bude (opět zcela podle očekávání) odlišný:
Obrázek 20: Původní obrazovka, prozatím před vyplněním.
Obrázek 21: Obrazovka po vyplnění její části „konstantní“ barvou.
Následuje úplný zdrojový kód dnešního posledního demonstračního příkladu:
; Graficky rezim karty VGA s rozlisenim 640x480 pixelu. ; Zmena barvovych rovin, do kterych se zapisuje. ; Vykresleni barevnych usecek. ; Prekresleni s vyuzitim logickeho rezimu. ; ; preklad pomoci: ; nasm -f bin -o vga.com vga_write_mode_3.asm ; ; nebo pouze: ; nasm -o vga.com vga_write_mode_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 DATA_ROTATE equ 0x03 ; graphics register GRAPHICS_MODE equ 0x05 ; 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 %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 ; nastaveni logickeho rezimu pri zapisu %macro write_logic_mode 1 mov dx, GRAPHICS_REGISTER mov al, DATA_ROTATE 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 mov ax, 0xa000 ; video RAM v textovem rezimu mov es, ax mov ds, ax xor si, si ; nyni DS:SI obsahuje adresu prvniho pixelu ve video RAM xor di, di ; nyni ES:DI obsahuje adresu prvniho pixelu ve video RAM write_logic_mode 0b00110000 ; rezim XOR select_bitplane 0 ; vyber bitove roviny nebo bitovych rovin call fill_screen_area ; vypln casti obrazovky select_bitplane 1 ; vyber bitove roviny nebo bitovych rovin call fill_screen_area ; vypln casti obrazovky select_bitplane 7 ; vyber bitove roviny nebo bitovych rovin call fill_screen_area ; vypln casti obrazovky select_bitplane 8 ; vyber bitove roviny nebo bitovych rovin call fill_screen_area ; vypln casti obrazovky select_bitplane 15 ; vyber bitove roviny nebo bitovych rovin call fill_screen_area ; vypln casti obrazovky wait_key ; cekani na klavesu exit ; navrat do DOSu ; vyplneni casti obrazovky fill_screen_area: mov cx, 640*100/8 ; pocet zapisu .loop: lodsb ; precteni hodnoty do latche mov al, 0xf0 ; zapisovany vzorek stosb ; provest vyplneni casti obrazovky loop .loop 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, 10 ; barva call putpixel ; vykreslení pixelu pop ax push ax mov cl, 11 ; barva add ax, 10 ; horizontalni posun useky call putpixel ; vykreslení pixelu pop ax push ax mov cl, 12 ; barva add ax, 20 ; horizontalni posun useky call putpixel ; vykreslení pixelu pop ax inc ax ; pusun x+=1, y+=1 cmp ax, 480 ; hranice obrazovky? jne .opak ; ne-opakujeme 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
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 |
94 | vga_bitblt_rotate.asm | zápisový režim s rotací bajtu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_bitblt_rotate.asm |
95 | vga_bitblt_fast.asm | rychlá korektní 32bitová operace typu BitBLT | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_bitblt_fast.asm |
96 | vga_320×400_bitblt1.asm | přenos obrázku v režimu 320×400 operací BitBLT (neúplná varianta) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×400_bitblt1.asm |
97 | vga_320×400_bitblt2.asm | přenos obrázku v režimu 320×400 operací BitBLT (úplná varianta) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×400_bitblt2.asm |
98 | vga_write_modes1.asm | volitelné zápisové režimy grafické karty VGA, zápis bez úpravy latche | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_write_modes1.asm |
99 | vga_write_modes2.asm | volitelné zápisové režimy grafické karty VGA, zápis s modifikací latche | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_write_modes2.asm |
100 | vga_write_modes3.asm | volitelné zápisové režimy grafické karty VGA, cílená modifikace latche vzorkem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_write_modes3.asm |
20. Odkazy na Internetu
- The Intel 8088 Architecture and Instruction Set
https://people.ece.ubc.ca/~edc/464/lectures/lec4.pdf - x86 Opcode Structure and Instruction Overview
https://pnx.tf/files/x86_opcode_structure_and_instruction_overview.pdf - x86 instruction listings (Wikipedia)
https://en.wikipedia.org/wiki/X86_instruction_listings - x86 assembly language (Wikipedia)
https://en.wikipedia.org/wiki/X86_assembly_language - Intel Assembler (Cheat sheet)
http://www.jegerlehner.ch/intel/IntelCodeTable.pdf - 25 Microchips That Shook the World
https://spectrum.ieee.org/tech-history/silicon-revolution/25-microchips-that-shook-the-world - Chip Hall of Fame: MOS Technology 6502 Microprocessor
https://spectrum.ieee.org/tech-history/silicon-revolution/chip-hall-of-fame-mos-technology-6502-microprocessor - Chip Hall of Fame: Intel 8088 Microprocessor
https://spectrum.ieee.org/tech-history/silicon-revolution/chip-hall-of-fame-intel-8088-microprocessor - Jak se zrodil procesor?
https://www.root.cz/clanky/jak-se-zrodil-procesor/ - Apple II History Home
http://apple2history.org/ - The 8086/8088 Primer
https://www.stevemorse.org/8086/index.html - flat assembler: Assembly language resources
https://flatassembler.net/ - FASM na Wikipedii
https://en.wikipedia.org/wiki/FASM - Fresh IDE FASM inside
https://fresh.flatassembler.net/ - MS-DOS Version 4.0 Programmer's Reference
https://www.pcjs.org/documents/books/mspl13/msdos/dosref40/ - INT 21 – DOS Function Dispatcher (DOS)
https://www.stanislavs.org/helppc/int21.html - DOS API (Wikipedia)
https://en.wikipedia.org/wiki/DOS_API - Bit banging
https://en.wikipedia.org/wiki/Bit_banging - IBM Basic assembly language and successors (Wikipedia)
https://en.wikipedia.org/wiki/IBM_Basic_assembly_language_and_successors - X86 Assembly/Bootloaders
https://en.wikibooks.org/wiki/X86_Assembly/Bootloaders - Počátky grafiky na PC: grafické karty CGA a Hercules
https://www.root.cz/clanky/pocatky-grafiky-na-pc-graficke-karty-cga-a-hercules/ - Co mají společného Commodore PET/4000, BBC Micro, Amstrad CPC i grafické karty MDA, CGA a Hercules?
https://www.root.cz/clanky/co-maji-spolecneho-commodore-pet-4000-bbc-micro-amstrad-cpc-i-graficke-karty-mda-cga-a-hercules/ - Karta EGA: první použitelná barevná grafika na PC
https://www.root.cz/clanky/karta-ega-prvni-pouzitelna-barevna-grafika-na-pc/ - RGB Classic Games
https://www.classicdosgames.com/ - Turbo Assembler (Wikipedia)
https://en.wikipedia.org/wiki/Turbo_Assembler - Microsoft Macro Assembler
https://en.wikipedia.org/wiki/Microsoft_Macro_Assembler - IBM Personal Computer (Wikipedia)
https://en.wikipedia.org/wiki/IBM_Personal_Computer - Intel 8251
https://en.wikipedia.org/wiki/Intel_8251 - Intel 8253
https://en.wikipedia.org/wiki/Intel_8253 - Intel 8255
https://en.wikipedia.org/wiki/Intel_8255 - Intel 8257
https://en.wikipedia.org/wiki/Intel_8257 - Intel 8259
https://en.wikipedia.org/wiki/Intel_8259 - Support/peripheral/other chips – 6800 family
http://www.cpu-world.com/Support/6800.html - Motorola 6845
http://en.wikipedia.org/wiki/Motorola_6845 - The 6845 Cathode Ray Tube Controller (CRTC)
http://www.tinyvga.com/6845 - CRTC operation
http://www.6502.org/users/andre/hwinfo/crtc/crtc.html - 6845 – Motorola CRT Controller
https://stanislavs.org/helppc/6845.html - The 6845 Cathode Ray Tube Controller (CRTC)
http://www.tinyvga.com/6845 - Motorola 6845 and bitwise graphics
https://retrocomputing.stackexchange.com/questions/10996/motorola-6845-and-bitwise-graphics - IBM Monochrome Display Adapter
http://en.wikipedia.org/wiki/Monochrome_Display_Adapter - Color Graphics Adapter
http://en.wikipedia.org/wiki/Color_Graphics_Adapter - Color Graphics Adapter and the Brown color in IBM 5153 Color Display
https://www.aceinnova.com/en/electronics/cga-and-the-brown-color-in-ibm-5153-color-display/ - The Modern Retrocomputer: An Arduino Driven 6845 CRT Controller
https://hackaday.com/2017/05/14/the-modern-retrocomputer-an-arduino-driven-6845-crt-controller/ - flat assembler: Assembly language resources
https://flatassembler.net/ - FASM na Wikipedii
https://en.wikipedia.org/wiki/FASM - Fresh IDE FASM inside
https://fresh.flatassembler.net/ - MS-DOS Version 4.0 Programmer's Reference
https://www.pcjs.org/documents/books/mspl13/msdos/dosref40/ - INT 21 – DOS Function Dispatcher (DOS)
https://www.stanislavs.org/helppc/int21.html - DOS API (Wikipedia)
https://en.wikipedia.org/wiki/DOS_API - IBM Basic assembly language and successors (Wikipedia)
https://en.wikipedia.org/wiki/IBM_Basic_assembly_language_and_successors - X86 Assembly/Arithmetic
https://en.wikibooks.org/wiki/X86_Assembly/Arithmetic - Art of Assembly – Arithmetic Instructions
http://oopweb.com/Assembly/Documents/ArtOfAssembly/Volume/Chapter6/CH06–2.html - ASM Flags
http://www.cavestory.org/guides/csasm/guide/asm_flags.html - Status Register
https://en.wikipedia.org/wiki/Status_register - Linux assemblers: A comparison of GAS and NASM
http://www.ibm.com/developerworks/library/l-gas-nasm/index.html - Programovani v assembleru na OS Linux
http://www.cs.vsb.cz/grygarek/asm/asmlinux.html - Is it worthwhile to learn x86 assembly language today?
https://www.quora.com/Is-it-worthwhile-to-learn-x86-assembly-language-today?share=1 - Why Learn Assembly Language?
http://www.codeproject.com/Articles/89460/Why-Learn-Assembly-Language - Is Assembly still relevant?
http://programmers.stackexchange.com/questions/95836/is-assembly-still-relevant - Why Learning Assembly Language Is Still a Good Idea
http://www.onlamp.com/pub/a/onlamp/2004/05/06/writegreatcode.html - Assembly language today
http://beust.com/weblog/2004/06/23/assembly-language-today/ - Assembler: Význam assembleru dnes
http://www.builder.cz/rubriky/assembler/vyznam-assembleru-dnes-155960cz - Programming from the Ground Up Book – Summary
http://savannah.nongnu.org/projects/pgubook/ - DOSBox
https://www.dosbox.com/ - The C Programming Language
https://en.wikipedia.org/wiki/The_C_Programming_Language - Hercules Graphics Card (HCG)
https://en.wikipedia.org/wiki/Hercules_Graphics_Card - Complete 8086 instruction set
https://content.ctcd.edu/courses/cosc2325/m22/docs/emu8086ins.pdf - Complete 8086 instruction set
https://yassinebridi.github.io/asm-docs/8086_instruction_set.html - 8088 MPH by Hornet + CRTC + DESiRE (final version)
https://www.youtube.com/watch?v=hNRO7lno_DM - Area 5150 by CRTC & Hornet (Party Version) / IBM PC+CGA Demo, Hardware Capture
https://www.youtube.com/watch?v=fWDxdoRTZPc - 80×86 Integer Instruction Set Timings (8088 – Pentium)
http://aturing.umcs.maine.edu/~meadow/courses/cos335/80×86-Integer-Instruction-Set-Clocks.pdf - Colour Graphics Adapter: Notes
https://www.seasip.info/VintagePC/cga.html - Restoring A Vintage CGA Card With Homebrew HASL
https://hackaday.com/2024/06/12/restoring-a-vintage-cga-card-with-homebrew-hasl/ - Demoing An 8088
https://hackaday.com/2015/04/10/demoing-an-8088/ - Video Memory Layouts
http://www.techhelpmanual.com/89-video_memory_layouts.html - Screen Attributes
http://www.techhelpmanual.com/87-screen_attributes.html - IBM PC Family – BIOS Video Modes
https://www.minuszerodegrees.net/video/bios_video_modes.htm - EGA Functions
https://cosmodoc.org/topics/ega-functions/#the-hierarchy-of-the-ega - Why the EGA can only use 16 of its 64 colours in 200-line modes
https://www.reenigne.org/blog/why-the-ega-can-only-use-16-of-its-64-colours-in-200-line-modes/ - How 16 colors saved PC gaming – the story of EGA graphics
https://www.custompc.com/retro-tech/ega-graphics - List of 16-bit computer color palettes
https://en.wikipedia.org/wiki/List_of16-bit_computer_color_palettes - Why were those colors chosen to be the default palette for 256-color VGA?
https://retrocomputing.stackexchange.com/questions/27994/why-were-those-colors-chosen-to-be-the-default-palette-for-256-color-vga - VGA Color Palettes
https://www.fountainware.com/EXPL/vga_color_palettes.htm - Hardware Level VGA and SVGA Video Programming Information Page
http://www.osdever.net/FreeVGA/vga/vga.htm - Hardware Level VGA and SVGA Video Programming Information Page – sequencer
http://www.osdever.net/FreeVGA/vga/seqreg.htm - VGA Basics
http://www.brackeen.com/vga/basics.html - Introduction to VGA Mode ‚X‘
https://web.archive.org/web/20160414072210/http://fly.srk.fer.hr/GDM/articles/vgamodex/vgamx1.html - VGA Mode-X
https://web.archive.org/web/20070123192523/http://www.gamedev.net/reference/articles/article356.asp - Mode-X: 256-Color VGA Magic
https://downloads.gamedev.net/pdf/gpbb/gpbb47.pdf - Instruction Format in 8086 Microprocessor
https://www.includehelp.com/embedded-system/instruction-format-in-8086-microprocessor.aspx - How to use „AND,“ „OR,“ and „XOR“ modes for VGA Drawing
https://retrocomputing.stackexchange.com/questions/21936/how-to-use-and-or-and-xor-modes-for-vga-drawing - VGA Hardware
https://wiki.osdev.org/VGA_Hardware