Obsah
1. Od grafické karty VGA k vyšším rozlišením i většímu množství barev (3. část)
2. Vykreslení rastrového obrázku v režimech s 256 barvami
3. Nastavení barvové palety přes DAC
4. Blokový přenos celého obrázku do banky video paměti
5. Úplný zdrojový kód dnešního prvního demonstračního příkladu
6. Korektní vykreslení prvních 82 řádků rastrového obrázku
7. Úplný zdrojový kód dnešního druhého demonstračního příkladu
8. Operace typu BitBLT: „bit block transfer“
9. Realizace operace BitBLT specifické pro konkrétní rastrový obrázek
10. Úplný zdrojový kód dnešního třetího demonstračního příkladu
11. Vykreslení rastrového obrázku přesahujícího hranice jednoho paměťového banku
12. Úplný zdrojový kód dnešního čtvrtého demonstračního příkladu
13. Horizontální vycentrování obrázku
14. Úplný zdrojový kód dnešního pátého demonstračního příkladu
15. Nastavení délky logického obrazového řádku
16. Úplný zdrojový kód dnešního šestého demonstračního příkladu
18. Obsah navazující části seriálu
19. Repositář s demonstračními příklady
1. Od grafické karty VGA k vyšším rozlišením i většímu množství barev (3. část)
Jak již bylo napsáno v perexu dnešního článku, v rámci předminulého a minulého článku jsme se (i když ve zjednodušené formě) seznámili s tím, jakým způsobem je možné programově zjistit informace o grafických režimech SVGA karet přes VBE a jak se přistupuje do video paměti. Ovšem právě zde dochází k mnoha více či méně závažným problémům, které je nutné řešit. Týká se to i operace typu BitBLT používané pro přenos rastrových obrázků. Již dopředu je možné odhadnout, že je zapotřebí brát do úvahy formát uložení pixelů (neexistují zde obecně používané standardy), délku obrazového řádku a počet pixelů na jednom obrazovém řádku (což je odlišná informace, než délka řádku). A aby toho nebylo málo, je navíc nutné, minimálně v reálném režimu, realizovat přepínání paměťových banků, protože v jednom okamžiku je přístupné pouze jeden segment, tj. 64 kB, který reprezentuje pouze (velmi) malý výřez obrazové paměti.
2. Vykreslení rastrového obrázku v režimech s 256 barvami
V předchozích demonstračních příkladech jsme po výběru vhodného SVGA režimu pouze na obrazovku vykreslili barevné pruhy. To je sice velmi jednoduchá operace, ale nijak nám neumožňuje si lépe uvědomit, jaká je vlastně organizace video paměti, jaký vliv mají paměťové banky, různé logické délky obrazových řádků atd. Z tohoto důvodu si dnes ukážeme poněkud sofistikovanější postup, který spočívá v tom, že do obrazové paměti vykreslíme předem připravený rastrový obrázek. Ten bude mít rozlišení přesně 320×200 pixelů a využívá barvovou paletu se stupni šedi (což je opět zjednodušení, abychom nemuseli barvovou paletu načítat z paměti, ale mohli ji přímo programově vygenerovat). Samotný rastrový obrázek je v době překladu uložen v binárním souboru image_320×200.bin a do programového kódu ho přidáme nám již známou volbou:
; pridani binarnich dat s rastrovym obrazkem image: incbin "image_320x200.bin"
3. Nastavení barvové palety přes DAC
Další potenciální problém SVGA karet spočívá ve způsobu nastavení barvové palety. Většina karet se snaží zachovat zpětnou kompatibilitu s kartou VGA a umožňovat mapování barvové palety naprogramováním převodní tabulky používané DAC blokem (na konci je totiž trojice D/A převodníků, z toho vyplývá i jméno bloku).
Grafická karta VGA na výstupu (tedy pravděpodobně ještě před výstupními zesilovači) obsahuje obvod DAC neboli číslicově-analogový převodník. Signály R, G, B, které jsou posílány do monitoru, jsou totiž na VGA analogové, což umožnilo i s využitím konektoru s relativně malým počtem pinů (DE-15) posílat informace o 262144 barvových odstínech a později i plné true color (samozřejmě je ale signál zašumněn, frekvenčně omezen atd., takže například na 48bitovou barvovou hloubku a rozlišení QUXGA spíše zapomeňme).
DAC interně obsahuje paměť s organizací 256×18 bitů. Na vstupu je tedy osmibitová hodnota (adresa), na výstupu pak 18 bitů – pro každou barvovou složku 6 bitů. Z toho plyne právě oněch 262144 barvových odstínů: 26×26×26=218=262144. Přeprogramováním této paměti je tedy možné zajistit toho, že VGA monitor zobrazí libovolnou barvu z této škály.
Ukažme si, jak může vypadat nastavení barvové palety tak, aby obsahovala pouze odstíny šedé barvy. Použitý přístup je plně kompatibilní s původní grafickou kartou VGA:
; paleta ve stupnich sedi grayscale_palette: 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 ; posun o dva bity doprava 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 ret ; navrat ze subrutiny
4. Blokový přenos celého obrázku do banky video paměti
Po nastavení 256barevného grafického režimu (například s rozlišením 800×600 pixelů) by do segmentu A000 měl být namapován první paměťový bank video RAM, tj. prvních 64 kilobajtů. Můžeme se tedy pokusit o přenos celého rastrového obrázku, který má velikost 320×200=64000 bajtů, do video RAM a zjistit, jaký vzorek se vlastně zobrazí i jakou část obrazovky jsme vlastně vyplnili:
mov ax, cs mov ds, ax mov si, image ; nyni DS:SI obsahuje adresu prvniho bajtu v obrazku mov ax, 0xa000 ; video RAM v textovem rezimu mov es, ax xor di, di ; nyni ES:DI obsahuje adresu prvniho pixelu ve video RAM mov cx, 320*200/2 ; pocet zapisovanych bajtu (=pixelu) rep movsw ; prenos celeho obrazku
V našem konkrétním případě nastavíme grafický režim s rozlišením právě 800×600 pixelů a bitovou hloubkou 8 bitů na pixel. Výsledek by měl vypadat zhruba následovně (ovšem může se lišit, pokud bude odlišný počet bajtů na řádek):

Výsledek blokového přenosu rastrového obrázku s rozlišením 320×200 pixelů do grafického režimu karty SVGA.
5. Ú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, po jehož překladu a spuštění se do obrazové paměti překopíruje obsah rastrového obrázku, vypadá následovně:
;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: jmp main ; skok na zacatek kodu %include "io.asm" ; nacist symboly, makra a podprogramy %include "print.asm" ; nacist symboly, makra a podprogramy main: push ds pop es ; nastaveni CS=DS=ES mov bx, 0x103 ; cislo rezimu mov ax, 0x4f02 ; nastaveni grafickeho rezimu int 0x10 cmp ax, 0x004f ; test, zda bylo volani funkce BIOSu uspesne jne failed success: call grayscale_palette ; nastaveni palety se stupni sedi mov ax, cs mov ds, ax mov si, image ; nyni DS:SI obsahuje adresu prvniho bajtu v obrazku mov ax, 0xa000 ; video RAM v textovem rezimu mov es, ax xor di, di ; nyni ES:DI obsahuje adresu prvniho pixelu ve video RAM mov cx, 320*200/2 ; pocet zapisovanych bajtu (=pixelu) rep movsw ; prenos celeho obrazku jmp finish failed: print_string failed_msg finish: wait_key ; cekani na klavesu exit ; navrat do DOSu set_video_window: ; ocekava se, ze DL je nastaven korektne! mov ax, 0x4f05 ; nastaveni okna mov bx, 0x0000 ; okno A int 0x10 ; volani VBE ret ; navrat ze subrutiny ; paleta ve stupnich sedi grayscale_palette: 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 ret ; navrat ze subrutiny ; datova cast section .data success_msg: db "Success", 0x0a, 0x0d, "$" failed_msg: db "Failed", 0x0a, 0x0d, "$" ; pridani binarnich dat s rastrovym obrazkem image: incbin "image_320x200.bin"
6. Korektní vykreslení prvních 82 řádků rastrového obrázku
Pokusme se nyní náš rastrový obrázek vykreslit korektně, což ovšem není zcela triviální. Nejprve se zaměříme na korektní zápis do jediného paměťového banku. Ten má typicky velikost 64kB a zabírá celý segment A000. Pro rozlišení 800×600 pixelů a 256 barev má jeden obrazový řádek délku 800 bajtů a celkem je tedy do segmentu namapováno 65536/800 neboli 81/82 obrazových řádků (celých 81 řádků a prakticky celý 82. řádek bez posledních 64 bajtů – to si snadno ověříte zpětným výpočtem). Náš rastrový obrázek má na každém řádku jen 320 bajtů a proto budeme postupovat následovně:
- Vykreslíme (přeneseme) 320 bajtů z obrázku do obrazové paměti
- Zvýšíme cílový ukazatel o 800–320 bajtů, tedy přeskočíme zbývající pixely na obrazovém řádku
- Celý proces zopakujeme 82× a korektně tak vykreslíme prvních 82 řádků obrázku
Nejprve zapíšeme do registrů DS:SI adresu prvního bajtu zdrojového obrázku:
mov ax, cs mov ds, ax mov si, image ; nyni DS:SI obsahuje adresu prvniho bajtu v obrazku
Následně do registrů ES:DI zapíšeme adresu prvního bajtu v obrazové paměti:
mov ax, 0xa000 ; video RAM v textovem rezimu mov es, ax xor di, di ; offset na zacatek video RAM
A konečně budeme 82× opakovat přenos 320 bajtů (160 slov) s úpravou registru DI tak, aby se ukazatel posunul na začátek dalšího obrazového řádku:
mov al, 82 ; počitadlo obrazových řádků next_line: mov cx, 320/2 ; pocet zapisovanych bajtu (=pixelu) rep movsw ; prenos jednoho obrazoveho radku add di, 800-320 ; preskocit zbytek obrazoveho radku dec al ; snizit pocitadlo radku jnz next_line
Výsledek již bude vypadat korektně, ovšem stále se bude jednat pouze o 82 obrazových řádků:
7. Úplný zdrojový kód dnešního druhého demonstračního příkladu
Úplný zdrojový kód příkladu, který po svém překladu a spuštění vykreslí obrázek uvedený v předchozí kapitole, vypadá následovně:
;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: jmp main ; skok na zacatek kodu %include "io.asm" ; nacist symboly, makra a podprogramy %include "print.asm" ; nacist symboly, makra a podprogramy main: push ds pop es ; nastaveni CS=DS=ES mov bx, 0x103 ; cislo rezimu mov ax, 0x4f02 ; nastaveni grafickeho rezimu int 0x10 cmp ax, 0x004f ; test, zda bylo volani funkce BIOSu uspesne jne failed success: call grayscale_palette ; nastaveni palety se stupni sedi mov ax, cs mov ds, ax mov si, image ; nyni DS:SI obsahuje adresu prvniho bajtu v obrazku mov ax, 0xa000 ; video RAM v textovem rezimu mov es, ax xor di, di ; offset na zacatek video RAM mov al, 82 next_line: mov cx, 320/2 ; pocet zapisovanych bajtu (=pixelu) rep movsw ; prenos jednoho obrazoveho radku add di, 800-320 ; preskocit zbytek obrazoveho radku dec al ; snizit pocitadlo radku jnz next_line jmp finish failed: print_string failed_msg finish: wait_key ; cekani na klavesu exit ; navrat do DOSu set_video_window: ; ocekava se, ze DL je nastaven korektne! mov ax, 0x4f05 ; nastaveni okna mov bx, 0x0000 ; okno A int 0x10 ; volani VBE ret ; navrat ze subrutiny ; paleta ve stupnich sedi grayscale_palette: 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 ret ; navrat ze subrutiny ; datova cast section .data success_msg: db "Success", 0x0a, 0x0d, "$" failed_msg: db "Failed", 0x0a, 0x0d, "$" ; pridani binarnich dat s rastrovym obrazkem image: incbin "image_320x200.bin"
8. Operace typu BitBLT: „bit block transfer“
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 běžný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).
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 už 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.
9. Realizace operace BitBLT specifické pro konkrétní rastrový obrázek
Můžeme se pokusit o realizaci vlastní operace typu BitBLT. Tato realizace zahrnuje (v tom nejjednodušším případě) přenos celého obrazového řádku na obrazovku a korektní „přeskok“ na další řádek. Jedná se o operace, které jsme již použili ve druhém demonstračním příkladu, takže nám pouze zbývá jejich realizace formou subrutiny (podprogramu). V tom nejjednodušším případě bude subrutina vyžadovat předání parametrů v pracovních registrech:
Registr(y) | Význam |
---|---|
DS:SI | adresa prvního pixelu zdrojového obrázku |
DI | adresa pixelu v rámci segmentu A000 (bank video paměti) |
AL | počet řádků, které se mají přenést |
V tom nejjednodušším případě je offset, o který je nutné přeskočit v obrazové paměti, přímo součástí těla subrutiny – viz řádek s instrukcí ADD DI, 800–320. Pochopitelně je však možné tuto hodnotu (typu slovo) předat v dalším pracovním registru, například v registru DX, který není v subrutině použit:
bitblt: push 0xa000 ; video RAM v textovem rezimu pop es next_line: mov cx, 320/2 ; pocet zapisovanych bajtu (=pixelu) rep movsw ; prenos jednoho obrazoveho radku add di, 800-320 ; preskocit zbytek obrazoveho radku dec al ; snizit pocitadlo radku jnz next_line ret ; navrat ze subrutiny
Způsob volání subrutiny BitBLT pro vykreslení prvních 82 řádků obrázku:
eov ax, cs mov ds, ax mov si, image ; nyni DS:SI obsahuje adresu prvniho bajtu v obrazku xor di, di ; offset na zacatek video RAM mov al, 82 ; pocet prenesenych radku call bitblt ; zavolat subrutinu pro blokovy prenos
10. Úplný zdrojový kód dnešního třetího demonstračního příkladu
Způsob začlenění výše uvedené subrutiny do uceleného demonstračního příkladu vypadá takto:
;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: jmp main ; skok na zacatek kodu %include "io.asm" ; nacist symboly, makra a podprogramy %include "print.asm" ; nacist symboly, makra a podprogramy main: push ds pop es ; nastaveni CS=DS=ES mov bx, 0x103 ; cislo rezimu mov ax, 0x4f02 ; nastaveni grafickeho rezimu int 0x10 cmp ax, 0x004f ; test, zda bylo volani funkce BIOSu uspesne jne failed success: call grayscale_palette ; nastaveni palety se stupni sedi mov ax, cs mov ds, ax mov si, image ; nyni DS:SI obsahuje adresu prvniho bajtu v obrazku xor di, di ; offset na zacatek video RAM mov al, 82 ; pocet prenesenych radku call bitblt ; zavolat subrutinu pro blokovy prenos jmp finish failed: print_string failed_msg finish: wait_key ; cekani na klavesu exit ; navrat do DOSu bitblt: push 0xa000 ; video RAM v textovem rezimu pop es next_line: mov cx, 320/2 ; pocet zapisovanych bajtu (=pixelu) rep movsw ; prenos jednoho obrazoveho radku add di, 800-320 ; preskocit zbytek obrazoveho radku dec al ; snizit pocitadlo radku jnz next_line ret ; navrat ze subrutiny set_video_window: ; ocekava se, ze DL je nastaven korektne! mov ax, 0x4f05 ; nastaveni okna mov bx, 0x0000 ; okno A int 0x10 ; volani VBE ret ; navrat ze subrutiny ; paleta ve stupnich sedi grayscale_palette: 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 ret ; navrat ze subrutiny ; datova cast section .data success_msg: db "Success", 0x0a, 0x0d, "$" failed_msg: db "Failed", 0x0a, 0x0d, "$" ; pridani binarnich dat s rastrovym obrazkem image: incbin "image_320x200.bin"
11. Vykreslení rastrového obrázku přesahujícího hranice jednoho paměťového banku
Vraťme se nyní k první verzi subrutiny bitblt. Tato subrutina je schválně napsaná takovým způsobem, aby vhodným způsobem upravila hodnoty registrů SI (zdrojový obrázek) a DI (video RAM). Současně se provede přenos AL řádků:
bitblt: push 0xa000 ; video RAM v textovem rezimu pop es next_line: mov cx, 320/2 ; pocet zapisovanych bajtu (=pixelu) rep movsw ; prenos jednoho obrazoveho radku add di, 800-320 ; preskocit zbytek obrazoveho radku dec al ; snizit pocitadlo radku jnz next_line ret ; navrat ze subrutiny
To znamená, že pokud budeme korektně přepínat paměťové banky video RAM (počítejme s velikostí 64kB), bude možné postupně vykreslit celý obrázek. Přenést (vykreslit) prvních 82 řádků již umíme, takže pro jistotu přidejme kód pro přepnutí banku (segment A000) na hodnotu 0:
mov dx, 0 ; cislo pametoveho banku video pameti call set_video_window ; nastaveni pametoveho banku xor di, di ; offset na zacatek video RAM mov al, 82 ; pocet prenesenych radku call bitblt ; zavolat subrutinu pro blokovy prenos
Současně s návratem ze subrutiny bitblt došlo k úpravě registrů SI a DI, takže se můžeme pokusit o vykreslení dalších 82 řádků. Registr SI bude obsahovat korektní hodnotu, ovšem hodnotu DI je nutné vhodným způsobem upravit, protože obecně paměťové banky video RAM nekončí na konci/začátku obrazových řádků. Přepnutím paměťového banku na dalších 64kB je nutné provést přesun na 82×800 (o tolik se registr změnil při přenosu prvních 82 řádků) a od této hodnoty odečteme 65536. Nevadí, že dochází k přenosům/přetečení, protože výsledek bude korektní – posun o 64 bajtů (v rámci paměťového banku – nejedná se o horizontální pozici!).
Následující sekvence instrukcí vykreslí dalších 82 obrazových řádků:
mov dx, 1 ; cislo pametoveho banku video pameti call set_video_window ; nastaveni pametoveho banku mov di, 82*800-65536 ; offset na zacatek video RAM mov al, 82 ; pocet prenesenych radku call bitblt ; zavolat subrutinu pro blokovy prenos
Naprosto stejným postupem vykreslíme zbytek obrázku. Jeho výška je rovna 200 pixelům a už jsme v předchozích dvou krocích vykreslili 2×82 řádků, takže výpočet bude vypadat takto (posun o 128 bajtů + vykreslení 36 řádků):
mov dx, 2 ; cislo pametoveho banku video pameti call set_video_window ; nastaveni pametoveho banku mov di, 2*82*800-65536*2 ; offset na zacatek video RAM mov al, 200-82*2 ; pocet prenesenych radku call bitblt ; zavolat subrutinu pro blokovy prenos
Nyní by se na obrazovce měl nacházet celý obrázek:
12. Úplný zdrojový kód dnešního čtvrtého demonstračního příkladu
Zdrojový kód dnešního čtvrtého demonstračního příkladu, který po svém spuštění vykreslil předchozí obrázek, vypadá následovně:
;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: jmp main ; skok na zacatek kodu %include "io.asm" ; nacist symboly, makra a podprogramy %include "print.asm" ; nacist symboly, makra a podprogramy main: push ds pop es ; nastaveni CS=DS=ES mov bx, 0x103 ; cislo rezimu mov ax, 0x4f02 ; nastaveni grafickeho rezimu int 0x10 cmp ax, 0x004f ; test, zda bylo volani funkce BIOSu uspesne jne failed success: call grayscale_palette ; nastaveni palety se stupni sedi mov ax, cs mov ds, ax mov si, image ; nyni DS:SI obsahuje adresu prvniho bajtu v obrazku mov dx, 0 ; cislo pametoveho banku video pameti call set_video_window ; nastaveni pametoveho banku xor di, di ; offset na zacatek video RAM mov al, 82 ; pocet prenesenych radku call bitblt ; zavolat subrutinu pro blokovy prenos mov dx, 1 ; cislo pametoveho banku video pameti call set_video_window ; nastaveni pametoveho banku mov di, 82*800-65536 ; offset na zacatek video RAM mov al, 82 ; pocet prenesenych radku call bitblt ; zavolat subrutinu pro blokovy prenos mov dx, 2 ; cislo pametoveho banku video pameti call set_video_window ; nastaveni pametoveho banku mov di, 2*82*800-65536*2 ; offset na zacatek video RAM mov al, 200-82*2 ; pocet prenesenych radku call bitblt ; zavolat subrutinu pro blokovy prenos jmp finish failed: print_string failed_msg finish: wait_key ; cekani na klavesu exit ; navrat do DOSu bitblt: push 0xa000 ; video RAM v textovem rezimu pop es next_line: mov cx, 320/2 ; pocet zapisovanych bajtu (=pixelu) rep movsw ; prenos jednoho obrazoveho radku add di, 800-320 ; preskocit zbytek obrazoveho radku dec al ; snizit pocitadlo radku jnz next_line ret ; navrat ze subrutiny set_video_window: ; ocekava se, ze DL je nastaven korektne! mov ax, 0x4f05 ; nastaveni okna mov bx, 0x0000 ; okno A int 0x10 ; volani VBE ret ; navrat ze subrutiny ; paleta ve stupnich sedi grayscale_palette: 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 ret ; navrat ze subrutiny ; datova cast section .data success_msg: db "Success", 0x0a, 0x0d, "$" failed_msg: db "Failed", 0x0a, 0x0d, "$" ; pridani binarnich dat s rastrovym obrazkem image: incbin "image_320x200.bin"
13. Horizontální vycentrování obrázku
Rastrový obrázek se prozatím vykreslil do levého horního rohu obrazovky. Jak je nutné postupovat v případě, kdy například budeme vyžadovat jeho vycentrování? Ve skutečnosti to nemusí být nic složitého, protože pouze potřebujeme posunout počáteční hodnotu registru DI tak, aby se celý obrázek (320 pixelů na šířku) vykreslil doprostřed obrazovky, která má na šířku 800 pixelů. To je snadné, protože pro nultý bank se pozice (v pixelech resp. bajtech) vypočte takto:
xcenter equ 800/2-320/2
Tedy konkrétně pro prvních 82 řádků:
mov dx, 0 ; cislo pametoveho banku video pameti call set_video_window ; nastaveni pametoveho banku xcenter equ 800/2-320/2 mov di, xcenter ; offset na zacatek video RAM mov al, 82 ; pocet prenesenych radku call bitblt ; zavolat subrutinu pro blokovy prenos
Posun je ovšem nutné připočítat i pro další paměťové banky (a nezáleží přitom na tom, že dochází k přetečení mezivýsledků):
mov dx, 1 ; cislo pametoveho banku video pameti call set_video_window ; nastaveni pametoveho banku mov di, xcenter+82*800-65536 ; offset na zacatek video RAM mov al, 82 ; pocet prenesenych radku call bitblt ; zavolat subrutinu pro blokovy prenos
Dtto pro třetí banku (banku s indexem 2):
mov dx, 2 ; cislo pametoveho banku video pameti call set_video_window ; nastaveni pametoveho banku mov di, xcenter+2*82*800-65536*2 ; offset na zacatek video RAM mov al, 200-82*2 ; pocet prenesenych radku call bitblt ; zavolat subrutinu pro blokovy prenos
Opět se podívejme na výsledek, který tímto postupem získáme:
14. Úplný zdrojový kód dnešního pátého demonstračního příkladu
Již popáté si ukážeme, jak vypadá úplný zdrojový kód demonstračního příkladu, kterým byl vykreslen obrázek z předchozí kapitoly:
;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: jmp main ; skok na zacatek kodu %include "io.asm" ; nacist symboly, makra a podprogramy %include "print.asm" ; nacist symboly, makra a podprogramy main: push ds pop es ; nastaveni CS=DS=ES mov bx, 0x103 ; cislo rezimu mov ax, 0x4f02 ; nastaveni grafickeho rezimu int 0x10 cmp ax, 0x004f ; test, zda bylo volani funkce BIOSu uspesne jne failed success: call grayscale_palette ; nastaveni palety se stupni sedi mov ax, cs mov ds, ax mov si, image ; nyni DS:SI obsahuje adresu prvniho bajtu v obrazku mov dx, 0 ; cislo pametoveho banku video pameti call set_video_window ; nastaveni pametoveho banku xcenter equ 800/2-320/2 mov di, xcenter ; offset na zacatek video RAM mov al, 82 ; pocet prenesenych radku call bitblt ; zavolat subrutinu pro blokovy prenos mov dx, 1 ; cislo pametoveho banku video pameti call set_video_window ; nastaveni pametoveho banku mov di, xcenter+82*800-65536 ; offset na zacatek video RAM mov al, 82 ; pocet prenesenych radku call bitblt ; zavolat subrutinu pro blokovy prenos mov dx, 2 ; cislo pametoveho banku video pameti call set_video_window ; nastaveni pametoveho banku mov di, xcenter+2*82*800-65536*2 ; offset na zacatek video RAM mov al, 200-82*2 ; pocet prenesenych radku call bitblt ; zavolat subrutinu pro blokovy prenos jmp finish failed: print_string failed_msg finish: wait_key ; cekani na klavesu exit ; navrat do DOSu bitblt: push 0xa000 ; video RAM v textovem rezimu pop es next_line: mov cx, 320/2 ; pocet zapisovanych bajtu (=pixelu) rep movsw ; prenos jednoho obrazoveho radku add di, 800-320 ; preskocit zbytek obrazoveho radku dec al ; snizit pocitadlo radku jnz next_line ret ; navrat ze subrutiny set_video_window: ; ocekava se, ze DL je nastaven korektne! mov ax, 0x4f05 ; nastaveni okna mov bx, 0x0000 ; okno A int 0x10 ; volani VBE ret ; navrat ze subrutiny ; paleta ve stupnich sedi grayscale_palette: 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 ret ; navrat ze subrutiny ; datova cast section .data success_msg: db "Success", 0x0a, 0x0d, "$" failed_msg: db "Failed", 0x0a, 0x0d, "$" ; pridani binarnich dat s rastrovym obrazkem image: incbin "image_320x200.bin"
15. Nastavení délky logického obrazového řádku
Prozatím jsme předpokládali, že délka obrazového řádku (v bajtech) odpovídá horizontálnímu rozlišení obrazovky, samozřejmě za předpokladu, že se jedná o 256barevné režimy. Ovšem ve skutečnosti tak tomu být nemusí a délka řádku může být delší (například 1024 bajtů). Některé grafické karty byly dokonce konfigurovatelné a bylo tak možné délku řádku změnit. Pro tento účel se používala VBE služba 0×4f, s číslem podslužby 0×06. Tato služba vrátila aktuálně nastavenou délku řádku popř. ji umožňovala změnit. Podívejme se nyní na způsob volání:
Vstup: AH = 4Fh Služby SVGA AL = 06h Podslužba pro přečtení či nastavení délky obrazového řádku BL = 01h Požadavek na vrácení aktuální hodnoty Výstup: AL = 4Fh pokud je služba podporována, jinak odlišná hodnota AH = 00h pokud je volání úspěšné, jinak hodnota 01h BX = počet bajtů na obrazovém řádku CX = počet pixelů na obrazovém řádku DX = počet obrazových řádků
Nastavení se provádí takto:
Vstup: AH = 4Fh Služby SVGA AL = 06h Podslužba pro přečtení či nastavení délky obrazového řádku BL = 00h Požadavek na změnu délky obrazového řádku CX = ?? Požadovaná délka řádku v pixelech Výstup: AL = 4Fh pokud je služba podporována, jinak odlišná hodnota AH = 00h pokud je volání úspěšné, jinak hodnota 01h BX = počet bajtů na obrazovém řádku CX = počet pixelů na obrazovém řádku DX = počet obrazových řádků
V kódu by mohlo nastavení délky obrazového řádku vypadat takto:
mov ax, 0x4f06 ; nastaveni nebo precteni delky logickeho radku mov bl, 00 ; operace nastaveni mov cx, 1024 ; delka radku cmp ax, 0x004f ; test, zda bylo volani funkce BIOSu uspesne jne failed
16. Úplný zdrojový kód dnešního šestého demonstračního příkladu
Podívejme se nyní na způsob změny délky obrazového řádku v praxi:
;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: jmp main ; skok na zacatek kodu %include "io.asm" ; nacist symboly, makra a podprogramy %include "print.asm" ; nacist symboly, makra a podprogramy main: push ds pop es ; nastaveni CS=DS=ES mov bx, 0x103 ; cislo rezimu mov ax, 0x4f02 ; nastaveni grafickeho rezimu int 0x10 cmp ax, 0x004f ; test, zda bylo volani funkce BIOSu uspesne jne failed mov ax, 0x4f06 ; nastaveni nebo precteni delky logickeho radku mov bl, 00 ; operace nastaveni mov cx, 800 ; delka radku cmp ax, 0x004f ; test, zda bylo volani funkce BIOSu uspesne jne failed success: call grayscale_palette ; nastaveni palety se stupni sedi mov ax, cs mov ds, ax mov si, image ; nyni DS:SI obsahuje adresu prvniho bajtu v obrazku mov dx, 0 ; cislo pametoveho banku video pameti call set_video_window ; nastaveni pametoveho banku xcenter equ 800/2-320/2 mov di, xcenter ; offset na zacatek video RAM mov al, 82 ; pocet prenesenych radku call bitblt ; zavolat subrutinu pro blokovy prenos mov dx, 1 ; cislo pametoveho banku video pameti call set_video_window ; nastaveni pametoveho banku mov di, xcenter+82*800-65536 ; offset na zacatek video RAM mov al, 82 ; pocet prenesenych radku call bitblt ; zavolat subrutinu pro blokovy prenos mov dx, 2 ; cislo pametoveho banku video pameti call set_video_window ; nastaveni pametoveho banku mov di, xcenter+2*82*800-65536*2 ; offset na zacatek video RAM mov al, 200-82*2 ; pocet prenesenych radku call bitblt ; zavolat subrutinu pro blokovy prenos jmp finish failed: print_string failed_msg finish: wait_key ; cekani na klavesu exit ; navrat do DOSu bitblt: push 0xa000 ; video RAM v textovem rezimu pop es next_line: mov cx, 320/2 ; pocet zapisovanych bajtu (=pixelu) rep movsw ; prenos jednoho obrazoveho radku add di, 800-320 ; preskocit zbytek obrazoveho radku dec al ; snizit pocitadlo radku jnz next_line ret ; navrat ze subrutiny set_video_window: ; ocekava se, ze DL je nastaven korektne! mov ax, 0x4f05 ; nastaveni okna mov bx, 0x0000 ; okno A int 0x10 ; volani VBE ret ; navrat ze subrutiny ; paleta ve stupnich sedi grayscale_palette: 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 ret ; navrat ze subrutiny ; datova cast section .data success_msg: db "Success", 0x0a, 0x0d, "$" failed_msg: db "Failed", 0x0a, 0x0d, "$" ; pridani binarnich dat s rastrovym obrazkem image: incbin "image_320x200.bin"
17. Textové režimy SVGA karet
Prozatím jsme se zabývali především grafickými režimy, které byly nabízeny SVGA kartami a které byly navíc podporovány rozšířením BIOSu (VBE). Ovšem nesmíme zapomenout na to, že většina SVGA karet umožňovala využití textových režimů, přičemž původní sada textových režimů (40×25 znaků, 80×25 znaků, 80×43 znaků a 80×50 znaků) byla rozšířena o režimy s větším počtem textových řádků a/nebo i větším počtem sloupců. Typicky bylo možné na jednom textovém řádku zobrazit až 132 znaků a počet textových řádků se zvyšoval až na 60.
Zajímavé je, že i tyto (de facto nestandardní) textové režimy udržovaly velmi dobrou zpětnou kompatibilitu, která v tomto případě nesahá pouze ke kartě VGA, ale až ke kartám CGA a MDA. Typicky byly znaky a jejich atributy ukládány do segmentu 0×b8000 a dokonce byly emulovány i některé řídicí registry grafického řadiče, což například umožňovalo manipulace s textovým kurzorem atd. Výsledkem bylo, že relativně velké množství aplikací tyto nové textové režimy podporovalo, a přitom se z vývojářského hlediska nejednalo o větší problém (na rozdíl, jak již víme, od grafických režimů).
18. Obsah navazující části seriálu
V další části seriálu o tvorbě her a multimediálních aplikací pro platformu IBM PC se zaměříme právě na textové režimy, které jsou podporovány většinou SVGA karet. Ukážeme si i některé aplikace, které tyto režimy dokázaly (více či méně úspěšně) využít. A pochopitelně se budeme zabývat i zpětnou kompatibilitou s původní sérii grafických karet pro platformu IBM PC: od CGA a MDA přes kartu EGA až k (relativně) dlouhodobému standardu VGA.
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ý (v současnosti již poměrně rozsáhlý) repositář:
20. Odkazy na Internetu
- VESA BIOS Extensions
https://en.wikipedia.org/wiki/VESA_BIOS_Extensions - Video Electronics Standards Association
https://en.wikipedia.org/wiki/Video_Electronics_Standards_Association - DJGPP (Wikipedia)
https://cs.wikipedia.org/wiki/DJGPP - DJGPP home page
http://www.delorie.com/djgpp/ - DJGPP Zip File Picker
http://www.delorie.com/djgpp/zip-picker.html - 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/ - 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 - 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/ - 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 - Programmer's Guide to Yamaha YMF 262/OPL3 FM Music Synthesizer
https://moddingwiki.shikadi.net/wiki/OPL_chip - Does anybody understand how OPL2 percussion mode works?
https://forum.vcfed.org/index.php?threads/does-anybody-understand-how-opl2-percussion-mode-works.60925/ - Yamaha YMF262 OPL3 music – MoonDriver for OPL3 DEMO [Oscilloscope View]
https://www.youtube.com/watch?v=a7I-QmrkAak - Yamaha OPL vs OPL2 vs OPL3 comparison
https://www.youtube.com/watch?v=5knetge5Gs0 - OPL3 Music Crockett's Theme
https://www.youtube.com/watch?v=HXS008pkgSQ - Bad Apple (Adlib Tracker – OPL3)
https://www.youtube.com/watch?v=2lEPH6Y3Luo - FM Synthesis Chips, Codecs and DACs
https://www.dosdays.co.uk/topics/fm_synthesizers.php - The Zen Challenge – YMF262 OPL3 Original (For an upcoming game)
https://www.youtube.com/watch?v=6JlFIFz1CFY - [adlib tracker II techno music – opl3] orbit around alpha andromedae I
https://www.youtube.com/watch?v=YqxJCu_WFuA - [adlib tracker 2 music – opl3 techno] hybridisation process on procyon-ii
https://www.youtube.com/watch?v=daSV5mN0sJ4 - Hyper Duel – Black Rain (YMF262 OPL3 Cover)
https://www.youtube.com/watch?v=pu_mzRRq8Ho - IBM 5155–5160 Technical Reference
https://www.minuszerodegrees.net/manuals/IBM/IBM_5155_5160_Technical_Reference_6280089_MAR86.pdf - a ymf262/opl3+pc speaker thing i made
https://www.youtube.com/watch?v=E-Mx0lEmnZ0 - [OPL3] Like a Thunder
https://www.youtube.com/watch?v=MHf06AGr8SU - (PC SPEAKER) bad apple
https://www.youtube.com/watch?v=LezmKIIHyUg - Powering devices from PC parallel port
http://www.epanorama.net/circuits/lptpower.html - Magic Mushroom (demo pro PC s DOSem)
http://www.crossfire-designs.de/download/articles/soundcards//mushroom.rar - Píseň Magic Mushroom – originál
http://www.crossfire-designs.de/download/articles/soundcards/speaker_mushroom_converted.mp3 - Píseň Magic Mushroom – hráno na PC Speakeru
http://www.crossfire-designs.de/download/articles/soundcards/speaker_mushroom_speaker.mp3 - Pulse Width Modulation (PWM) Simulation Example
http://decibel.ni.com/content/docs/DOC-4599 - Resistor/Pulse Width Modulation DAC
http://www.k9spud.com/traxmod/pwmdac.php - Class D Amplifier
http://en.wikipedia.org/wiki/Electronic_amplifier#Class_D - Covox Speech Thing / Disney Sound Source (1986)
http://www.crossfire-designs.de/index.php?lang=en&what=articles&name=showarticle.htm&article=soundcards/&page=5 - Covox Digital-Analog Converter (Rusky, obsahuje schémata)
http://phantom.sannata.ru/konkurs/netskater002.shtml - PC-GPE on the Web
http://bespin.org/~qz/pc-gpe/ - Keyboard Synthesizer
http://www.solarnavigator.net/music/instruments/keyboards.htm - FMS – Fully Modular Synthesizer
http://fmsynth.sourceforge.net/ - Javasynth
http://javasynth.sourceforge.net/ - Software Sound Synthesis & Music Composition Packages
http://www.linux-sound.org/swss.html - Mx44.1 Download Page (software synthesizer for linux)
http://hem.passagen.se/ja_linux/ - Software synthesizer
http://en.wikipedia.org/wiki/Software_synthesizer - Frequency modulation synthesis
http://en.wikipedia.org/wiki/Frequency_modulation_synthesis - Yamaha DX7
http://en.wikipedia.org/wiki/Yamaha_DX7 - Wave of the Future
http://www.wired.com/wired/archive/2.03/waveguides_pr.html - Analog synthesizer
http://en.wikipedia.org/wiki/Analog_synthesizer - Minimoog
http://en.wikipedia.org/wiki/Minimoog - Moog synthesizer
http://en.wikipedia.org/wiki/Moog_synthesizer - Tutorial for Frequency Modulation Synthesis
http://www.sfu.ca/~truax/fmtut.html - An Introduction To FM
http://ccrma.stanford.edu/software/snd/snd/fm.html - John Chowning
http://en.wikipedia.org/wiki/John_Chowning - I'm Impressed, Adlib Music is AMAZING!
https://www.youtube.com/watch?v=PJNjQYp1ras - Milinda- Diode Milliampere ( OPL3 )
https://www.youtube.com/watch?v=oNhazT5HG0E - Dune 2 – Roland MT-32 Soundtrack
https://www.youtube.com/watch?v=kQADZeB-z8M - Interrupts
https://wiki.osdev.org/Interrupts#Types_of_Interrupts - Assembly8086SoundBlasterDmaSingleCycleMode
https://github.com/leonardo-ono/Assembly8086SoundBlasterDmaSingleCycleMode/blob/master/sbsc.asm - Interrupts in 8086 microprocessor
https://www.geeksforgeeks.org/interrupts-in-8086-microprocessor/ - Interrupt Structure of 8086
https://www.eeeguide.com/interrupt-structure-of-8086/ - A20 line
https://en.wikipedia.org/wiki/A20_line - Extended memory
https://en.wikipedia.org/wiki/Extended_memory#eXtended_Memory_Specification_(XMS) - Expanded memory
https://en.wikipedia.org/wiki/Expanded_memory - Protected mode
https://en.wikipedia.org/wiki/Protected_mode - Virtual 8086 mode
https://en.wikipedia.org/wiki/Virtual_8086_mode - Unreal mode
https://en.wikipedia.org/wiki/Unreal_mode - DOS memory management
https://en.wikipedia.org/wiki/DOS_memory_management - Upper memory area
https://en.wikipedia.org/wiki/Upper_memory_area - Removing the Mystery from SEGMENT : OFFSET Addressing
https://thestarman.pcministry.com/asm/debug/Segments.html - Segment descriptor
https://en.wikipedia.org/wiki/Segment_descriptor - When using a 32-bit register to address memory in the real mode, contents of the register must never exceed 0000FFFFH. Why?
https://stackoverflow.com/questions/45094696/when-using-a-32-bit-register-to-address-memory-in-the-real-mode-contents-of-the - A Brief History of Unreal Mode
https://www.os2museum.com/wp/a-brief-history-of-unreal-mode/ - Segment Limits
https://wiki.osdev.org/Segment_Limits - How do 32 bit addresses in real mode work?
https://forum.osdev.org/viewtopic.php?t=30642 - The LOADALL Instruction by Robert Collins
https://www.rcollins.org/articles/loadall/tspec_a3_doc.html - How do you put a 286 in Protected Mode?
https://retrocomputing.stackexchange.com/questions/7683/how-do-you-put-a-286-in-protected-mode - Control register
https://en.wikipedia.org/wiki/Control_register - CPU Registers x86
https://wiki.osdev.org/CPU_Registers_x86 - x86 Assembly/Protected Mode
https://en.wikibooks.org/wiki/X86_Assembly/Protected_Mode - MSW: Machine Status Word
https://web.itu.edu.tr/kesgin/mul06/intel/intel_msw.html - 80×87 Floating Point Opcodes
http://www.techhelpmanual.com/876–80×87_floating_point_opcodes.html - Page Translation
https://pdos.csail.mit.edu/6.828/2005/readings/i386/s05_02.htm - 80386 Paging and Segmenation
https://stackoverflow.com/questions/38229741/80386-paging-and-segmenation - 80386 Memory Management
https://tldp.org/LDP/khg/HyperNews/get/memory/80386mm.html - DOSEMU
http://www.dosemu.org/ - Intel 80386, a revolutionary CPU
https://www.xtof.info/intel80386.html - PAI Unit 3 Paging in 80386 Microporcessor
https://www.slideshare.net/KanchanPatil34/pai-unit-3-paging-in-80386-microporcessor - 64 Terabytes of virtual memory for 32-bit x86 using segmentation: how?
https://stackoverflow.com/questions/5444984/64-terabytes-of-virtual-memory-for-32-bit-x86-using-segmentation-how - Pi in the Pentium: reverse-engineering the constants in its floating-point unit
http://www.righto.com/2025/01/pentium-floating-point-ROM.html - Simply FPU
http://www.website.masmforum.com/tutorials/fptute/ - Art of Assembly language programming: The 80×87 Floating Point Coprocessors
https://courses.engr.illinois.edu/ece390/books/artofasm/CH14/CH14–3.html - Art of Assembly language programming: The FPU Instruction Set
https://courses.engr.illinois.edu/ece390/books/artofasm/CH14/CH14–4.html - INTEL 80387 PROGRAMMER'S REFERENCE MANUAL
http://www.ragestorm.net/downloads/387intel.txt - x86 Instruction Set Reference: FLD
http://x86.renejeschke.de/html/file_module_x86_id100.html - x86 Instruction Set Reference: FLD1/FLDL2T/FLDL2E/FLDPI/FLDLG2/FLDLN2/FLDZ
http://x86.renejeschke.de/html/file_module_x86_id101.html - X86 Assembly/Arithmetic
https://en.wikibooks.org/wiki/X86_Assembly/Arithmetic - 8087 Numeric Data Processor
https://www.eeeguide.com/8087-numeric-data-processor/ - Data Types and Instruction Set of 8087 co-processor
https://www.eeeguide.com/data-types-and-instruction-set-of-8087-co-processor/ - 8087 instruction set and examples
https://studylib.net/doc/5625221/8087-instruction-set-and-examples - GCC documentation: Extensions to the C Language Family
https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html#C-Extensions - GCC documentation: Using Vector Instructions through Built-in Functions
https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html - SSE (Streaming SIMD Extentions)
http://www.songho.ca/misc/sse/sse.html - Timothy A. Chagnon: SSE and SSE2
http://www.cs.drexel.edu/~tc365/mpi-wht/sse.pdf - Intel corporation: Extending the Worldr's Most Popular Processor Architecture
http://download.intel.com/technology/architecture/new-instructions-paper.pdf - SIMD architectures:
http://arstechnica.com/old/content/2000/03/simd.ars/ - Tour of the Black Holes of Computing!: Floating Point
http://www.cs.hmc.edu/~geoff/classes/hmc.cs105…/slides/class02_floats.ppt - 3Dnow! Technology Manual
AMD Inc., 2000 - Intel MMXTM Technology Overview
Intel corporation, 1996 - MultiMedia eXtensions
http://softpixel.com/~cwright/programming/simd/mmx.phpi - AMD K5 („K5“ / „5k86“)
http://www.pcguide.com/ref/cpu/fam/g5K5-c.html - Sixth Generation Processors
http://www.pcguide.com/ref/cpu/fam/g6.htm - Great Microprocessors of the Past and Present
http://www.cpushack.com/CPU/cpu1.html - Very long instruction word (Wikipedia)
http://en.wikipedia.org/wiki/Very_long_instruction_word - CPU design (Wikipedia)
http://en.wikipedia.org/wiki/CPU_design - Grafické karty a grafické akcelerátory (14)
https://www.root.cz/clanky/graficke-karty-a-graficke-akceleratory-14/ - Grafické karty a grafické akcelerátory (15)
https://www.root.cz/clanky/graficke-karty-a-graficke-akceleratory-15/ - Grafické karty a grafické akcelerátory (16)
https://www.root.cz/clanky/graficke-karty-a-graficke-akceleratory-16/ - VESA Video Modes
https://wiki.osdev.org/VESA_Video_Modes - Introduction to VESA programming
http://www.monstersoft.com/tutorial1/VESA_intro.html - Guide: VBE 2.0 graphics modes
https://delorie.com/djgpp/doc/ug/graphics/vbe20.html - NASM instruction list
https://userpages.cs.umbc.edu/chang/cs313/nasmdoc/html/nasmdocb.html - BitBlt function (wingdi.h)
https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-bitblt - SetDIBitsToDevice function (wingdi.h)
https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-setdibitstodevice