Obsah
1. Grafická karta Hercules: úspěšná alternativa a konkurence MDA i CGA
3. Základní technické parametry karty Hercules
4. Textový režim karty Hercules
5. První demonstrační příklad: zobrazení textu s atributy kartou Hercules
6. Řídicí registry karty Hercules dostupné přes I/O porty
7. Vypnutí blikání textu, pokud je nejvyšší atributový bit nastavený na jedničku
8. Úplný zdrojový kód dnešního druhého demonstračního příkladu
9. Zákaz generování video signálu
10. Úplný zdrojový kód dnešního třetího demonstračního příkladu
11. Grafický režim karty Hercules
12. Postup pro přepnutí do grafického režimu
13. Úplný zdrojový kód dnešního čtvrtého demonstračního příkladu
14. Vylepšení kódu: efektivnější zápis do registrů CRTC
15. Úplný zdrojový kód dnešního pátého demonstračního příkladu
16. Postup při vykreslení jednoho pixelu v grafickém režimu karty Hercules
17. Předpočet adres jednotlivých obrazových řádků
18. Úplný zdrojový kód dnešního šestého demonstračního příkladu
19. Repositář s demonstračními příklady
1. Grafická karta Hercules: úspěšná alternativa a konkurence MDA i CGA
Obě grafické karty vydané v roce 1981 společností IBM k jejich počítači IBM PC, tj. jak karty MDA, tak i CGA, mají i přes mnohé rozdíly několik společných vlastností. Jedná se totiž v obou případech o karty navržené a prodávané (opět: již od roku 1981) firmou IBM, které jsou vybavené rozhraním pro osmibitovou variantu universální interní sběrnice ISA (Industry Standard Architecture). Obě karty jsou taktéž založeny na již popsaném grafickém řadiči Motorola MC6845, což by sice na první pohled mohlo znamenat určitou míru kompatibility, ale přesný opak byl pravdou – firma IBM u obou karet zvolila odlišné řádkové frekvence (konkrétně 18,432 kHz u karty MDA a nižší frekvenci 15,75 kHz u karty CGA) i jiný typ videosignálů, což ve výsledku vedlo k tomu, že pro každou kartu musel být použitý odlišný monitor (navíc CGA podporovala jak „digitální“ RGBI monitory, tak i monitory akceptující kompozitní video signál).
Obrázek 1: Slavný tuzemský textový editor T602 spuštěný na počítači s grafickou kartou Hercules (viz navazující kapitoly).
Zatímco grafická karta CGA nabízela možnost barevného zobrazení (viz též předchozí tři články, v nichž jsme se touto kartou podrobně zabývali) na úkor menšího – pro mnohé uživatele zcela neakceptovatelného – horizontálního i vertikálního zobrazení, umožňovala sice karta MDA zobrazení velmi dobře čitelného textu, ovšem bez možnosti použití jakéhokoli grafického režimu (pochopitelně až na pseudorežim založený na znacích z rozšířené ASCII).
Obrázek 2: T602 zobrazený kartou CGA (skutečný obraz má ve skutečnosti jen 200 obrazových řádků, nikoli 400, ty byly uměle zvětšeny emulátorem).
V této situaci se, pravděpodobně vůbec poprvé (z hlediska koncového uživatele), projevila jedna z největších předností architektury IBM PC – modularita. Zatímco firma IBM vlastně nijak nereagovala na oprávněné výtky, které od uživatelů přicházely především kvůli vlastnostem grafické karty CGA (i mnohé osmibitové počítače totiž měly grafický subsystém vyřešený mnohem elegantněji), objevil se v roce 1982 konkurenční výrobek – grafická karta Hercules Graphics Card (HGC) firmy Hercules Computer Technology. A i přesto, že Hercules nikdy nebyl podporován v BIOSu, stal se velmi populární alternativou a začal být podporován i velkými výrobci SW.
Obrázek 3: T602 zobrazený kartou EGA v rozlišení 640×350 v šestnácti barvách (touto kartou se budeme zabývat příště).
2. Plná kompatibilita s CGA
Výrobce grafickou kartu Hercules navrhl takovým způsobem, aby ji bylo možné použít s monitorem určeným pro kartu MDA, ovšem včetně možnosti přepnutí do monochromatického grafického režimu s relativně vysokým rozlišením 720×348 pixelů (což je na dobu vzniku velmi slušné a dosti to konkurovalo například pozdějšímu Atari ST s monochromatickým monitorem a rozlišením 640×400 pixelů – oba typy počítačů se v takové konfiguraci používaly ve firmách pro „seriózní práci“, ne na hraní her). Dodržení zpětné kompatibility s kartou MDA nebylo složité – v textovém i grafickém režimu (viz další text) byly použity takové frekvence synchronizačních signálů (řádková a snímková frekvence), která odpovídaly signálům generovaným kartou MDA.
Obrázek 4: Textový editor T602 zobrazený poměrně neznámou kartou MCGA, která v režimu nejvyššího rozlišení 640×480 měla jen jednu bitovou rovinu a tím pádem podporovala pouze dvě barvy (ovšem na druhou stranu s poměrně slušným rozlišením).
I způsob práce Herculesu v textovém režimu se od karty MDA téměř nelišil, což znamenalo, že na této kartě bylo možné provozovat všechny aplikace pracující v textovém režimu (navíc bylo možné s využitím rezidentních programů simulovat i grafické režimy karty CGA, přičemž se jednotlivé barevné odstíny nahrazovaly ditheringem). Především z těchto důvodů byla grafická karta Hercules v první polovině osmdesátých let minulého století velmi oblíbená a do svých sestav ji instalovali i tehdejší přední výrobci osobních počítačů. K velké oblíbenosti přispěla i poměrně nízká cena, takže se karta Hercules používala i v době nástupu grafické karty EGA, jejímž popisem se ovšem dnes zabývat nebudeme (i když čip 6845 velmi zdárně emulovala!).
Obrázek 5: Nejlepší rozlišení i největší počet barev pro textový editor T602 nabízela grafická karta VGA – 640×480 pixelů v šestnácti barvách (editor však využil jen podmnožinu barvové palety, navíc obrazová frekvence nebyla nijak ohromující).
Firma Hercules Computer Technology vytvořila i následníka této grafické karty – Hercules Plus – jenž se odlišoval především v tom, že bylo možné programově měnit znakovou sadu v textovém režimu a docílit tak například zobrazení českých znaků (u původního Herculesu či MDA se znaková sada měnila přeprogramováním paměti EPROM).
3. Základní technické parametry karty Hercules
Grafická karta Hercules je založena, podobně jako oba již popsané grafické adaptéry firmy IBM, na čipu Motorola MC6845, nebo (konkrétně v případě různých klonů) na VLSI obvodu se stejnými vlastnostmi i významem řídicích portů. Jak bude z dalšího popisu patrné, je čip MC6845 v této kartě zapojen a naprogramován poněkud odlišným způsobem než tomu bylo u grafické karty CGA i MDA. Kartu Hercules lze připojit do standardní osmibitové sběrnice ISA (v dokumentaci firmy IBM také označované termínem PC-BUS), přičemž se předpokládalo, že frekvence hodinových signálů této sběrnice bude rovna 4,77 MHz (frekvence základního oscilátoru 14,285 MHz je při generování hodinových signálů dělená třemi). Modernější osobní počítače měly frekvenci hodinových signálů sběrnice ISA zvýšenou na 8, 8.33, 10 či 12 MHz, ovšem při takto vysokých frekvencích mohlo na kartě Hercules docházet k výpadkům dat při zápisu do video paměti.
Na grafické kartě byl kromě řadiče, podpůrných obvodů a video paměti přítomný i jeden paralelní port, což také přispívalo k oblíbenosti Herculesu mezi zákazníky, protože první personální počítače typu IBM PC tyto porty neměly nainstalovány přímo na základní desce a bylo je zapotřebí zvlášť dokupovat (a tím mimo jiné přicházet o jednu pozici na ISA sběrnici, nehledě na relativně vysokou cenu jakýchkoli PC komponent; v případě Herculesu zákazníci měli paralelní port „zdarma“).
Kapacita obrazové paměti byla oproti kartě CGA zvýšena na dvojnásobek, tj. na celých 32 kB. Kromě paměťových modulů tvořících obrazovou paměť byla na kartě nainstalována i paměť typu ROM, popř. EPROM, ve které byla uložena znaková sada, konkrétně bitové podoby znaků (viz další kapitolu). Ovládání grafického čipu bylo prováděno s využitím parametrů ukládaných přes vstupně/výstupní porty umístěné na adresách 0×3b0 až 0×3bf, přičemž na adresy 0×3b4 a 0×3b5 byly namapovány řídicí registry čipu MC6845 (těchto registrů je, jak již víme z předchozích kapitol, celkem osmnáct, ovšem poslední dva registry týkající se světelného pera lze ignorovat). Vhodnou změnou parametrů docházelo k přepínání mezi textovým a grafickým režimem, bylo však možné také měnit parametry zobrazení grafiky (rozlišení, zpoždění synchronizačních signálů, pozice hardwarového textového kurzoru, mikroposun textových řádků apod.), čehož se často používalo při emulaci grafických režimů karty CGA. Některé tyto možnosti si ještě ukážeme v dalším textu.
Čtením stavových bitů z portu 0×3ba bylo možné testovat průběh horizontálního i vertikálního zatemnění (synchronizace používaná například ve hrách) a číst polohu hrotu světelného pera. Vzhledem k tomu, že grafická paměť byla z hlediska mikroprocesoru mapována od adresy b000:0000 do adresy b000:7fff (opět je použit způsob adresování segment:offset), nedocházelo k překryvu s obrazovou pamětí grafické karty CGA a proto lze tyto dvě karty provozovat současně i na jednom počítači (ovšem i toto bylo konfigurovatelné, takže paměť mohla být mapována jak do segmentu 0×b000, tak i do segmentu 0×b800).
Taktéž nedochází k překryvům vstupně/výstupních portů, neboť ty jsou v případě karty CGA umístěny o 16 bajtů výše. Hercules je v případě použití této kombinace využit pro kvalitní zobrazování textu a monochromatické grafiky, CGA pro zobrazení barevné (ehm :-) grafiky. Další poměrně oblíbenou kombinací z pozdější doby byla VGA+Hercules, ovšem v tomto případě Hercules většinou sloužil pro práci v textovém režimu (čehož dokázaly využít IDE firmy Borland, AutoCAD atd.).
4. Textový režim karty Hercules
V×textovém režimu je grafická karta Hercules prakticky stoprocentně kompatibilní s kartou MDA, tj. pracuje se s textem o 80 sloupcích a 25 řádcích, včetně stejného způsobu práce s atributy jednotlivých znaků (podtržení apod.). Text je zobrazován v rozlišení 720 350 pixelů, což umožňuje na jeden znak použít masku o velikosti 9×14 pixelů. Textovou obrazovku lze mapovat buď od adresy b000:0000 nebo od adresy b800:0000. Jedinou nevýhodou textového režimu grafické karty Hercules je fakt, že znaková sada je uložena v paměti EPROM typu 27C64 a nelze ji tedy programově změnit, pouze „přepálit“ (pro zajímavost – všechny Herculesy s „přepálenou“ znakovou sadou, které jsem viděl, používaly kódování Kamenických, viz další odstavec). Tvary znaků jsou v paměti EPROM uloženy tak, jakoby jejich maska měla velikost 8×16 pixelů, avšak pro každý znak se při jeho vykreslování dva řádky ignorují a podle pozice znaku v ASCII tabulce se doplňuje devátý sloupec pixelů, čímž se dostáváme k výsledné masce 9×14 pixelů (devátý sloupec vzniká kopií osmého sloupce u znaků představujících rámečky, jinak je tento sloupec vždy prázdný).
Obrázek 6: Volkov Commander v režimu karty Hercules.
Z výše uvedených informací vyplývá, že pro uložení celé znakové sady by měly dostačovat pouhé čtyři kilobajty, neboť 16 řádků×1 bajt×256 znaků=4096 bajtů. Ovšem vzhledem k tomu, že paměť EPROM 27C64 má kapacitu 8 kB, jsou horní 4 kB nevyužity. Vhodnou hardwarovou úpravou je však možné implementovat dvě znakové sady – u nás se většinou používala originální sada US-ASCII a již zmíněné české znaky v kódu Kamenických. Kromě původní karty Hercules se vyráběla taktéž již zmíněná karta Hercules Plus, která se od původního modelu odlišuje především v tom, že znakovou sadu ukládá do paměti typu (D)RAM a umožňuje tak programově měnit používanou znakovou sadu. U této karty je dokonce možné rozšířit počet znaků ve znakové sadě až na teoretickou hodnotu 212=4096 tím způsobem, že se čtyři bity v atributovém bajtu použijí na definici atributů znaků a zbylé čtyři bity se připojí k osmibitovému ASCII kódu znaku. Ne všechny kódy však mohou být skutečně využity, protože velikost paměti vyhrazené pro znakovou sadu dosahuje 48 kB a ne 64 kB.
Obrázek 7: QBasic v režimu karty Hercules.
5. První demonstrační příklad: zobrazení textu s atributy kartou Hercules
Dnešní první demonstrační příklad je velmi jednoduchý. Ukážeme si v něm vykreslení sady znaků společně s jejich atributy (popředí/pozadí) a porovnáme výsledek získaný na kartě CGA a Herculesu. Nesmíme pouze zapomenout, že na kartě CGA leží textová paměť v segmentu 0×b800, zatímco u Herculesu je to segment 0×b000:
mov ax, 0xb000 mov es, ax mov di, 0 ; nyni ES:DI obsahuje adresu prvniho znaku ve video RAM
Výsledek pro kartu CGA:
Obrázek 8: Text s atributy vykreslený kartou CGA.
Pro počítač s Herculesem získáme mnohem čitelnější text, ovšem (podle očekávání) pouze monochromatický:
Obrázek 9: Text s atributy vykreslený kartou Hercules.
A takto vypadá úplný zdrojový kód dnešního prvního demonstračního příkladu:
; Textovy rezim karty Hercules s rozlisenim 80x25 znaku. ; ; preklad pomoci: ; nasm -f bin -o hercules.com hercules_text_mode_1.asm ; ; nebo pouze: ; nasm -o hercules.com hercules_text_mode_1.asm ;----------------------------------------------------------------------------- ; ukonceni procesu a navrat do DOSu %macro exit 0 mov ah, 0x4c int 0x21 %endmacro ; vyprazdneni bufferu klavesnice a cekani na klavesu %macro wait_key 0 xor ax, ax int 0x16 %endmacro ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: mov ax, 0xb000 mov es, ax mov di, 0 ; nyni ES:DI obsahuje adresu prvniho znaku ve video RAM mov cx, 80*25 ; pocet zapisovanych znaku mov al, 0 ; kod zapisovaneho znaku opak: stosb ; zapis znaku + atributu stosb inc al ; dalsi znak/atribut loop opak ; opakujeme CX-krat wait_key exit
6. Řídicí registry karty Hercules dostupné přes I/O porty
Grafická karta Hercules obsahuje sedm řídicích a stavových registrů (k nimž ovšem můžeme připočítat i registry pro paralelní port). Povšimněte si, že I/O porty těchto registrů se liší od karty CGA, což umožňuje současnou instalaci obou karet:
Port | Význam |
---|---|
3b4 | výběr registru CRTC pro zápis nebo čtení |
3b5 | po výběru CRTC registru se odtud provede zápis či čtení |
3b8 | volba textového/grafického režimu, povolení blikání a video signálu |
3b9 | latch (záchytný registr) světelného pera |
3ba | stavový registr (aktivní VSync, HSync apod.) |
3bb | latch (záchytný registr) světelného pera |
3bf | ochrana před přepnutím do grafického režimu |
První dva I/O porty již známe z popisu karty CGA a ještě se k nim vrátíme v navazujících kapitolách. Ovšem nejdůležitější je port 3b8, jehož jednotlivé bity mají následující význam:
Bit | Význam |
---|---|
0 | × |
1 | 0-textový režim, 1-grafický režim |
2 | × |
3 | 0-paprsek vypnutý, 1-zobrazování |
4 | × |
5 | 0-zákaz blikání pozadí, 1-povolení blikání pozadí (nejvyšší bit atributu) |
6 | × |
7 | 0-video RAM je mapována do segmentu 0×b000, 1-video RAM je mapována do segmentu 0b800 |
7. Vypnutí blikání textu, pokud je nejvyšší atributový bit nastavený na jedničku
Řídicí registr grafické karty Hercules je dostupný na I/O portu 0×3b8, takže si v assembleru vytvoříme symbolické jméno tohoto registru:
hercules_control equ 0x3b8
Pro nastavení jednotlivých bitů tohoto registru použijeme nové makro, které vypadá (a i se tak používá) naprosto triviálně:
; nastaveni ridiciho registru %macro set_control 1 mov dx, hercules_control mov al, %1 ; ridici registr out dx, al %endmacro
Nyní již můžeme zakázat blikání textu, a to zápisem hodnoty 0×08 neboli 0b00001000:
Bit | Význam |
---|---|
0 | 0 |
1 | 0-textový režim |
2 | 0 |
3 | 1-zobrazování |
4 | 0 |
5 | 0-zákaz blikání pozadí |
6 | 0 |
7 | 0-video RAM je mapována do segmentu 0×b000 |
Samotný zápis:
set_control 0x08 ; zakaz blikani
Výsledná textová obrazovka by měla vypadat následovně:
Obrázek 10: Obrazovka se zakázaným blikáním textu.
8. Úplný zdrojový kód dnešního druhého demonstračního příkladu
Úplný zdrojový kód druhého demonstračního příkladu, který modifikuje způsob zobrazení textu (v textovém režimu) vypadá následovně:
; Textovy rezim karty Hercules s rozlisenim 80x25 znaku. ; Zmena zpusobu interpretace sedmeho bitu atributu. ; ; preklad pomoci: ; nasm -f bin -o hercules.com hercules_text_mode_2.asm ; ; nebo pouze: ; nasm -o hercules.com hercules_text_mode_2.asm ;----------------------------------------------------------------------------- ; registry karty Hercules hercules_index equ 0x3b4 hercules_control equ 0x3b8 hercules_status equ 0x3ba hercules_config equ 0x3bf ; 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 ridiciho registru %macro set_control 1 mov dx, hercules_control mov al, %1 ; ridici registr out dx, al %endmacro ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: mov ax, 0xb000 mov es, ax mov di, 0 ; nyni ES:DI obsahuje adresu prvniho znaku ve video RAM mov cx, 80*25 ; pocet zapisovanych znaku mov al, 0 ; kod zapisovaneho znaku opak: stosb ; zapis znaku + atributu stosb inc al ; dalsi znak/atribut loop opak ; opakujeme CX-krat wait_key set_control 0x08 ; zakaz blikani wait_key exit
9. Zákaz generování video signálu
Pro zajímavost se pokusme zakázat generování video signálu. Na skutečné kartě Hercules by měla obrazovka zčernat (nebo zmodrat, v závislosti na jejím typu), ovšem DOSBox – zdá se – bit pro zákaz zobrazování ignoruje:
set_control 0x00 ; zakaz zobrazeni
10. Úplný zdrojový kód dnešního třetího demonstračního příkladu
Opět se podívejme na úplný zdrojový kód dnešního třetího demonstračního příkladu:
; Textovy rezim karty Hercules s rozlisenim 80x25 znaku. ; Vypnuti video signalu. ; ; preklad pomoci: ; nasm -f bin -o hercules.com hercules_turn_off.asm ; ; nebo pouze: ; nasm -o hercules.com hercules_turn_off.asm ;----------------------------------------------------------------------------- ; registry karty Hercules hercules_index equ 0x3b4 hercules_control equ 0x3b8 hercules_status equ 0x3ba hercules_config equ 0x3bf ; 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 ridiciho registru %macro set_control 1 mov dx, hercules_control mov al, %1 ; ridici registr out dx, al %endmacro ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: mov ax, 0xb000 mov es, ax mov di, 0 ; nyni ES:DI obsahuje adresu prvniho znaku ve video RAM mov cx, 80*25 ; pocet zapisovanych znaku mov al, 0 ; kod zapisovaneho znaku opak: stosb ; zapis znaku + atributu stosb inc al ; dalsi znak/atribut loop opak ; opakujeme CX-krat wait_key set_control 0x00 ; zakaz zobrazeni wait_key exit
11. Grafický režim karty Hercules
Grafický režim karty Hercules je, ostatně jako téměř ve všech obdobných případech, mnohem zajímavější a flexibilnější, než režim textový. Hercules podporoval na svou dobu poměrně vysoké rozlišení 720×348 obrazových bodů zobrazovaných černobíle nebo dvoubarevně. Konkrétní barvy použité při zobrazování byly závislé na typu obrazovky monitoru; kromě obligátní kombinace černá+zelená byla mezi výrobci obrazovek oblíbená například kombinace tmavě modrá a světle červená nebo tmavě modrá a žlutá (je to možná zvláštní kombinace, ovšem právě s tou jsme se mohli v tuzemsku setkat poměrně často).
Horizontální rozlišení grafického režimu je stejné, jako v případě režimu textového, protože platí 80 znaků na řádku × 9 horizontálních pixelů na znak = 720 pixelů. Vertikální rozlišení se však liší o dva skenovací řádky. V textovém režimu je vertikální rozlišení, tj. počet obrazových řádků, rovno 350 pixelům, protože platí vztah: 25 textových řádků × 14 skenovacích/obrazových řádků na výšku znaku=350 skenovacích řádků celkem. V grafickém režimu je zvolena hodnota 348 skenovacích řádků především z toho důvodu, že je toto číslo dělitelné čtyřmi, což souvisí s režimem přístupu do obrazové paměti, jehož princip bude popsán v následujícím textu (ostatně změnou řídicích registrů čipu MC6845 lze počet obrazových řádků v určitém rozsahu měnit, takže lze dosáhnout i 350 řádků – pokud vůbec někdo pozná vizuální rozdíl).
Obrázek 11: Hra Simcity v režimu grafické karty Hercules. Z předchozího odstavce je patrné, že konkrétní barvové schéma se liší podle typu monitoru (a mnohé monitory navíc měly tlačítko pro inverzní zobrazení).
12. Postup pro přepnutí do grafického režimu
V případě, že budeme chtít přepnout kartu Hercules do grafického režimu, nemůžeme použít BIOS, protože tato karta není BIOSem podporována. Zbývá nám tedy oblíbený nízkoúrovňový přístup, konkrétně provedení následujících čtyř kroků:
- Povolíme změnu z textového režimu na režim grafický (I/O port 0×3bf)
- Přepneme se do grafického režimu a vypneme zobrazování (I/O port 0×3b8)
- Přeprogramujeme prvních dvanáct řídicích CRTC registrů
- Povolíme zobrazování (I/O port 0×3b8)
Pro změnu portů 0×3bf a 0×3b8 použijeme pomocná makra nazvaná set_config a set_control:
; nastaveni konfiguracniho registru %macro set_config 1 mov dx, hercules_config mov al, %1 ; ridici registr out dx, al %endmacro ; nastaveni ridiciho registru %macro set_control 1 mov dx, hercules_control mov al, %1 ; ridici registr out dx, al %endmacro
Jak však nastavit CRTC registry? Tato informace je téměř ztracena v temných zákoutích internetu (ostatně se jedná o informace z roku 1983), takže si uveďme korektní a podporované hodnoty CRTC registrů (resp. prvních dvanácti registrů, další nemají z hlediska zobrazování grafiky význam). Povšimněte si, že i pro grafický režim pracujeme s jednotkou „znak“ a nikoli „pixel“:
Číslo registru | Hodnota (dec) | Hodnota (hex) | Význam |
---|---|---|---|
0 | 53 | 35 | celkový počet znaků horizontálně – 1, včetně okrajů (tedy nezobrazených znaků) |
1 | 45 | 2d | počet horizontálně zobrazených znaků |
2 | 46 | 2e | horizontální pozice synchronizačního signálu |
3 | 7 | 07 | šířka horizontálního synchronizačního signálu |
4 | 91 | 5b | celkový počet textových řádků (včetně okrajů) |
5 | 2 | 02 | mikroposun textových řádků po jednotlivých obrazových řádcích |
6 | 87 | 57 | zobrazený počet textových řádků (87*4=348 obrazových řádků celkem) |
7 | 87 | 57 | vertikální pozice synchronizačního signálu |
8 | 2 | 2 | režim prokládání (interlace) a posunutí |
9 | 3 | 3 | počet obrazových řádků pro jeden textový řádek – 1 – výška znaku (tedy 4 mikrořádky) |
10 | 0 | 0 | začátek hardwarového kurzoru |
11 | 0 | 0 | konec hardwarového kurzoru |
12 | 0 | 0 | počáteční adresa obrazové paměti (vyšší bajt) |
13 | 0 | 0 | počáteční adresa obrazové paměti (nižší bajt) |
14 | 0 | 0 | adresa kurzoru – vyšší bajt |
15 | 0 | 0 | adresa kurzoru – nižší bajt |
16 | 0 | 0 | adresa světelného pera – vyšší bajt |
17 | 0 | 0 | adresa světelného pera – nižší bajt |
Prvních dvanáct hodnot si uložíme přímo do našeho programu:
gtable: db 35h,2dh,2eh,07h db 5bh,02h,57h,57h db 02h,03h,00h,00h
Jen pro připomenutí, jaký význam mají čítače a hodnoty komparátorů v prvních čtyřech registrech:
1 2 3 4 5 12345678901234567890123456789012345678901234567890123456 ← čítač znaků | || || | běžný viditelný textový řádek || sync || | || || ↑↑ ↑↑ R1 R2 R2+R3=R0
Celý podprogram pro nastavení grafického režimu:
init_graphics: set_config enable set_control graphics ; inicializace ridicich registru cipu Motorola 6845 mov si, gtable ; DS:SI obsahuje adresu tabulky s hodnotami registru mov cx, 12 ; pocet nastavovanych parametru xor ah, ah ; zaciname registrem cislo 0 parms: mov dx, hercules_index ; port pro zapis mov al, ah out dx, al ; zapis cisla registru na port mov dx, hercules_data ; port pro zapis lodsb ; precist hodnotu registru z tabulky out dx, al ; zapis hodnoty registru na port inc ah ; dalsi CRTC registr loop parms ; dalsi iterace set_control graphics + screen_on ; zapnuti obrazovky ret ; vse hotovoa
Podívejme se na výsledek:
Obrázek 12: Byla vyplněna přesně jedna čtvrtina obrazovky – každý čtvrtý řádek (nyní již tedy známe strukturu video RAM).
13. Úplný zdrojový kód dnešního čtvrtého demonstračního příkladu
Úplný zdrojový kód demonstračního příkladu, který provede naprogramování karty Hercules tak, aby se použil grafický režim, vypadá následovně:
; Graficky rezim karty Hercules s rozlisenim 720x348 znaku. ; ; preklad pomoci: ; nasm -f bin -o hercules.com hercules_gfx_mode_1.asm ; ; nebo pouze: ; nasm -o hercules.com hercules_gfx_mode_1.asm ;----------------------------------------------------------------------------- ; registry karty Hercules hercules_index equ 0x3b4 hercules_data equ 0x3b5 hercules_control equ 0x3b8 hercules_status equ 0x3ba hercules_config equ 0x3bf ; ridici bity screen_on equ 0x08 graphics equ 0x02 text equ 0x20 enable equ 0x03 ; 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 konfiguracniho registru %macro set_config 1 mov dx, hercules_config mov al, %1 ; ridici registr out dx, al %endmacro ; nastaveni ridiciho registru %macro set_control 1 mov dx, hercules_control mov al, %1 ; ridici registr out dx, al %endmacro ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: call init_graphics mov ax, 0xb000 mov es, ax mov di, 0 ; nyni ES:DI obsahuje adresu prvniho znaku ve video RAM mov cx, 90*348/4 ; pocet zapisovanych bajtu mov al, 255 ; kod zapisovaneho bajtu opak: stosb ; zapis bajtu loop opak ; opakujeme CX-krat wait_key exit ; hotovo init_graphics: set_config enable set_control graphics ; inicializace ridicich registru cipu Motorola 6845 mov si, gtable ; DS:SI obsahuje adresu tabulky s hodnotami registru mov cx, 12 ; pocet nastavovanych parametru xor ah, ah ; zaciname registrem cislo 0 parms: mov dx, hercules_index ; port pro zapis mov al, ah out dx, al ; zapis cisla registru na port mov dx, hercules_data ; port pro zapis lodsb ; precist hodnotu registru z tabulky out dx, al ; zapis hodnoty registru na port inc ah ; dalsi CRTC registr loop parms ; dalsi iterace set_control graphics + screen_on ; zapnuti obrazovky ret ; vse hotovoa gtable: db 35h,2dh,2eh,07h db 5bh,02h,57h,57h db 02h,03h,00h,00h
14. Vylepšení kódu: efektivnější zápis do registrů CRTC
Zápis do některého řídicího registru CRTC byl v předchozím demonstračním příkladu vyřešen tak, že se nejdříve zapsalo číslo registru na port 3b4 a následně se zapsala hodnota registru na port 3b5:
mov dx, hercules_index ; port pro zapis mov al, ah out dx, al ; zapis cisla registru na port mov dx, hercules_data ; port pro zapis lodsb ; precist hodnotu registru z tabulky out dx, al ; zapis hodnoty registru na port
Jedná se sice o zcela korektní postup, ale můžeme postupovat i odlišným způsobem pokud si uvědomíme, že porty 3b4 a 3b5 leží za sebou. Číslo portu je uloženo v registru DX, takže pouze operacemi inc a dec dosáhneme stejného výsledku, ovšem rychleji a taktéž kratším kódem:
mov al, ah ; zapis cisla registru out dx, al inc dx ; adresa portu datoveho registru lodsb ; precist hodnotu registru z tabulky out dx, al ; zapis hodnoty registru na port dec dx ; obnoveni cisla portu
Instrukce inc a dec jsou každá o dva bajty kratší a taktéž každá o jeden takt rychlejší. Nejedná se tedy o nijak raketové urychlení ani zkrácení, ale programátor alespoň ukázal profesionální znalost „strojáku“.
Výsledek bude totožný, jako tomu bylo v předchozím příkladu:
Obrázek 13: Obrazovka má naprosto stejný obsah, jako tomu bylo na obrázku 11.
15. Úplný zdrojový kód dnešního pátého demonstračního příkladu
Opět se podívejme na úplný zdrojový kód dnes již pátého demonstračního příkladu:
; Graficky rezim karty Hercules s rozlisenim 720x348 znaku. ; ; preklad pomoci: ; nasm -f bin -o hercules.com hercules_gfx_mode_2.asm ; ; nebo pouze: ; nasm -o hercules.com hercules_gfx_mode_2.asm ;----------------------------------------------------------------------------- ; registry karty Hercules hercules_index equ 0x3b4 hercules_data equ 0x3b5 hercules_control equ 0x3b8 hercules_status equ 0x3ba hercules_config equ 0x3bf ; ridici bity screen_on equ 0x08 graphics equ 0x02 text equ 0x20 enable equ 0x03 ; 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 konfiguracniho registru %macro set_config 1 mov dx, hercules_config mov al, %1 ; ridici registr out dx, al %endmacro ; nastaveni ridiciho registru %macro set_control 1 mov dx, hercules_control mov al, %1 ; ridici registr out dx, al %endmacro ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: call init_graphics mov ax, 0xb000 mov es, ax mov di, 0 ; nyni ES:DI obsahuje adresu prvniho znaku ve video RAM mov cx, 90*348/4 ; pocet zapisovanych bajtu mov al, 255 ; kod zapisovaneho bajtu opak: stosb ; zapis bajtu loop opak ; opakujeme CX-krat wait_key exit ; hotovo init_graphics: set_config enable set_control graphics ; inicializace ridicich registru cipu Motorola 6845 mov si, gtable ; DS:SI obsahuje adresu tabulky s hodnotami registru mov dx, hercules_index ; registr pro zapis mov cx, 12 ; pocet nastavovanych parametru xor ah, ah ; zaciname registrem cislo 0 parms: mov al, ah ; zapis cisla registru out dx, al inc dx ; adresa portu datoveho registru lodsb ; precist hodnotu registru z tabulky out dx, al ; zapis hodnoty registru na port inc ah ; dalsi CRTC registr dec dx ; obnoveni cisla portu loop parms ; dalsi iterace set_control graphics + screen_on ; zapnuti obrazovky ret ; vse hotovo gtable: db 35h,2dh,2eh,07h db 5bh,02h,57h,57h db 02h,03h,00h,00h
16. Postup při vykreslení jednoho pixelu v grafickém režimu karty Hercules
Jak se v grafickém režimu karty Hercules vykreslí jeden pixel? Můžeme postupovat podobně, jako v režimu 640×200 karty CGA, ovšem tyto režimy se od sebe odlišují, a to hned ve třech oblastech:
- Horizontální rozlišení je rovno 720 pixelů, což není tak „kulaté“ číslo, jako 640 (při násobení je to jedno, při bitových posunech je to horší).
- Vertikální rozlišení je rovno 348 pixelům, takže případné násobení y-ové souřadnice již musíme provádět se šestnáctibitovými vstupy.
- Obraz je rozdělen nejenom na sudé a liché řádky, ale na řádky dělitelné 4, řádky, kde po dělení 4 získáme 1, 2, popř. 3. Celý výpočet adresy pixelu je tedy nepatrně komplikovanější.
Adresa pro operaci zápisu či čtení pixelu zadaného souřadnicemi x, y se vypočte následovně:
offset = 0x2000 * (y % 4) + 90 * (y >> 2) + (x >> 3)
Index bitu, který se má zapsat či přečíst na výše vypočtené adrese, lze vyjádřit takto:
offset bit = 7 - (x % 8)
I přes určitou komplikovanost je tedy možné se nechat inspirovat kartou CGA:
; Vykresleni pixelu ; AX - x-ova souradnice ; BX - y-ova souradnice (staci len BL) putpixel: mov dx, 0xb800 ; zacatek prvni stranky Video RAM test bx, 1 ; test, zda se jedna o sudy nebo lichy radek na obrazovce jz odd_line add dx, 8192/16 odd_line: mov es, dx ; nyni obsahuje ES bud prvni stranku Video RAM nebo stranku druhou 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 and al, 0xfe ; nejnizsi bit urcuje lichy/sudy radek -> nyni ignorovat 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. Předpočet adres jednotlivých obrazových řádků
Můžeme ovšem postupovat i odlišným způsobem, konkrétně tak, že si adresy začátků jednotlivých obrazových řádků necháme předpočítat do tabulky s 384 šestnáctibitovými hodnotami (offsety). Tyto offsety mohou vypadat následovně (jedná se jen o začátek tabulky):
;offsets into HGC regen buffer for each scan line HGCRegen dw 0,8192,16384,24576,90,8282,16474,24666 dw 180,8372,16564,24756,270,8462,16654,24846 dw 360,8552,16744,24936,450,8642,16834,25026 dw 540,8732,16924,25116,630,8822,17014,25206 dw 720,8912,17104,25296,810,9002,17194,25386 dw 900,9092,17284,25476,990,9182,17374,25566 dw 1080,9272,17464,25656,1170,9362,17554,25746
Povšimněte si, že první řádek má offset roven 0, druhý řádek 8192 (druhá čtvrtina obrazové paměti) atd. Až pátý řádek má offset 90 (odpovídá 720 pixelům) atd. atd.
Výsledný binární soubor se nám sice zvětší, zde konkrétně na 841 bajtů, ovšem samotný výpočet adresy pixelu se zjednoduší a zrychlí:
; vykresleni pixelu ; kod prevzaty z Fractintu a upraveny do podoby kompatibilni s NASMem ; provedeny dalsi optimalizace pro Intel 8086 putpixel: mov si, bx ; y-ova souradnice shl si, 1 ; vypositat offset (v tabulce jsou ulozena slova, ne bajty) lea bx, HGCRegen ; adresa tabulky mov si, [bx+si] ; ziskat adresu obrazoveho radku odpovidajiciho y-ove souradnici
Následuje výpočet adresy v rámci jednoho řádku, což se obejde bez násobení:
mov cx, ax ; uschovat x-ovou souradnici (registr AX se prepise) shr ax, 1 shr ax, 1 shr ax, 1 ; vydelit osmi -> ziskani offsetu v ramci obrazoveho radku add si, ax ; nyni je v ES:SI adresa zapisovaneho bajtu
A následuje klasika, kterou již známe – výpočet masky. Zde navíc máme doplněn kód pro vykreslení černého pixelu (negativní maska):
and cx, 0x07 ; bit v ramci bajtu mov al, 0x80 ; vypocet bitove masky shr al, cl ; bitova maska je nyni v AL mov cx, 0xb000 ; segment video RAM
mov es, cx ; do registru ES
cmp dl, 0 ; ma se vykreslit cerny pixel? je black_pixel ; pokud ano -> skok white_pixel: or es:[si], al ; vykresleni bileho pixelu ret ; konec black_pixel: xor al, 0xff ; inverze masky and es:[si], al ; vykresleni cerneho pixelu ret ; konec
18. Úplný zdrojový kód dnešního šestého demonstračního příkladu
Pokud budeme výše popsanou subrutinu putpixel postupně volat se zvyšujícími se souřadnicemi [x, y], vykreslí se diagonální úsečka:
Obrázek 14: Vykreslení úsečky složené z jednotlivých pixelů.
A takto vypadá úplný text dnešního posledního demonstračního příkladu pro vykreslení pixelů v grafickém režimu karty Hercules:
; Graficky rezim karty Hercules s rozlisenim 720x348 znaku. ; ; preklad pomoci: ; nasm -f bin -o hercules.com hercules_gfx_mode_2.asm ; ; nebo pouze: ; nasm -o hercules.com hercules_gfx_mode_2.asm ;----------------------------------------------------------------------------- ; registry karty Hercules hercules_index equ 0x3b4 hercules_data equ 0x3b5 hercules_control equ 0x3b8 hercules_status equ 0x3ba hercules_config equ 0x3bf ; ridici bity screen_on equ 0x08 graphics equ 0x02 text equ 0x20 enable equ 0x03 ; 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 konfiguracniho registru %macro set_config 1 mov dx, hercules_config mov al, %1 ; ridici registr out dx, al %endmacro ; nastaveni ridiciho registru %macro set_control 1 mov dx, hercules_control mov al, %1 ; ridici registr out dx, al %endmacro ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: call init_graphics mov ax, 0xb000 mov es, ax mov di, 0 ; nyni ES:DI obsahuje adresu prvniho znaku ve video RAM mov cx, 90*348 ; pocet zapisovanych bajtu xor al, al ; kod zapisovaneho bajtu rep stosb ; vymazat obrazovku xor ax, ax ; x-ova souradnice mov cx, 348 ; pocitadlo vykreslenych pixelu opak: mov bx, ax ; y-ova souradnice mov dl, 1 ; barva vykreslovaneho pixelu push ax ; uchovat (tyto registry se v subrutine poskodi) push cx ; uchovat (tyto registry se v subrutine poskodi) call putpixel ; ax=x, bx=y, dl=barva pop cx ; obnovit pop ax ; obnovit inc ax ; x+=1 loop opak ; a dalsi pixel wait_key exit ; hotovo init_graphics: set_config enable set_control graphics ; inicializace ridicich registru cipu Motorola 6845 mov si, gtable ; DS:SI obsahuje adresu tabulky s hodnotami registru mov dx, hercules_index ; registr pro zapis mov cx, 12 ; pocet nastavovanych parametru xor ah, ah ; zaciname registrem cislo 0 parms: mov al, ah ; zapis cisla registru out dx, al inc dx ; adresa portu datoveho registru lodsb ; precist hodnotu registru z tabulky out dx, al ; zapis hodnoty registru na port inc ah ; dalsi CRTC registr dec dx ; obnoveni cisla portu loop parms ; go do another one set_control graphics + screen_on ; zapnuti obrazovky ret ; vse hotovoa gtable: db 35h,2dh,2eh,07h db 5bh,02h,57h,57h db 02h,03h,00h,00h ; vykresleni pixelu ; kod prevzaty z Fractintu a upraveny do podoby kompatibilni s NASMem ; provedeny dalsi optimalizace pro Intel 8086 putpixel: mov si, bx ; y-ova souradnice shl si, 1 ; vypositat offset (v tabulce jsou ulozena slova, ne bajty) lea bx, HGCRegen ; adresa tabulky mov si, [bx+si] ; ziskat adresu obrazoveho radku odpovidajiciho y-ove souradnici mov cx, ax ; uschovat x-ovou souradnici (registr AX se prepise) shr ax, 1 shr ax, 1 shr ax, 1 ; vydelit osmi -> ziskani offsetu v ramci obrazoveho radku add si, ax ; nyni je v ES:SI adresa zapisovaneho bajtu and cx, 0x07 ; bit v ramci bajtu mov al, 0x80 ; vypocet bitove masky shr al, cl ; bitova maska je nyni v AL
mov cx, 0xb000 ; segment video RAM
mov es, cx ; do registru ES
cmp dl, 0 ; ma se vykreslit cerny pixel? je black_pixel ; pokud ano -> skok white_pixel: or es:[si], al ; vykresleni bileho pixelu ret ; konec black_pixel: xor al, 0xff ; inverze masky and es:[si], al ; vykresleni cerneho pixelu ret ; konec ;offsets into HGC regen buffer for each scan line HGCRegen dw 0,8192,16384,24576,90,8282,16474,24666 dw 180,8372,16564,24756,270,8462,16654,24846 dw 360,8552,16744,24936,450,8642,16834,25026 dw 540,8732,16924,25116,630,8822,17014,25206 dw 720,8912,17104,25296,810,9002,17194,25386 dw 900,9092,17284,25476,990,9182,17374,25566 dw 1080,9272,17464,25656,1170,9362,17554,25746 dw 1260,9452,17644,25836,1350,9542,17734,25926 dw 1440,9632,17824,26016,1530,9722,17914,26106 dw 1620,9812,18004,26196,1710,9902,18094,26286 dw 1800,9992,18184,26376,1890,10082,18274,26466 dw 1980,10172,18364,26556,2070,10262,18454,26646 dw 2160,10352,18544,26736,2250,10442,18634,26826 dw 2340,10532,18724,26916,2430,10622,18814,27006 dw 2520,10712,18904,27096,2610,10802,18994,27186 dw 2700,10892,19084,27276,2790,10982,19174,27366 dw 2880,11072,19264,27456,2970,11162,19354,27546 dw 3060,11252,19444,27636,3150,11342,19534,27726 dw 3240,11432,19624,27816,3330,11522,19714,27906 dw 3420,11612,19804,27996,3510,11702,19894,28086 dw 3600,11792,19984,28176,3690,11882,20074,28266 dw 3780,11972,20164,28356,3870,12062,20254,28446 dw 3960,12152,20344,28536,4050,12242,20434,28626 dw 4140,12332,20524,28716,4230,12422,20614,28806 dw 4320,12512,20704,28896,4410,12602,20794,28986 dw 4500,12692,20884,29076,4590,12782,20974,29166 dw 4680,12872,21064,29256,4770,12962,21154,29346 dw 4860,13052,21244,29436,4950,13142,21334,29526 dw 5040,13232,21424,29616,5130,13322,21514,29706 dw 5220,13412,21604,29796,5310,13502,21694,29886 dw 5400,13592,21784,29976,5490,13682,21874,30066 dw 5580,13772,21964,30156,5670,13862,22054,30246 dw 5760,13952,22144,30336,5850,14042,22234,30426 dw 5940,14132,22324,30516,6030,14222,22414,30606 dw 6120,14312,22504,30696,6210,14402,22594,30786 dw 6300,14492,22684,30876,6390,14582,22774,30966 dw 6480,14672,22864,31056,6570,14762,22954,31146 dw 6660,14852,23044,31236,6750,14942,23134,31326 dw 6840,15032,23224,31416,6930,15122,23314,31506 dw 7020,15212,23404,31596,7110,15302,23494,31686 dw 7200,15392,23584,31776,7290,15482,23674,31866 dw 7380,15572,23764,31956,7470,15662,23854,32046 dw 7560,15752,23944,32136,7650,15842,24034,32226 dw 7740,15932,24124,32316
19. Repositář s demonstračními příklady
Demonstrační příklady napsané v assembleru, které jsou určené pro překlad pomocí assembleru NASM, byly uložen do Git repositáře, který je dostupný na adrese https://github.com/tisnik/8bit-fame. Jednotlivé demonstrační příklady si můžete v případě potřeby stáhnout i jednotlivě bez nutnosti klonovat celý (dnes již poměrně rozsáhlý) repositář:
# | Příklad | Stručný popis | Adresa |
---|---|---|---|
1 | hello.asm | program typu „Hello world“ naprogramovaný v assembleru pro systém DOS | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hello.asm |
2 | hello_shorter.asm | kratší varianta výskoku z procesu zpět do DOSu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hello_shorter.asm |
3 | hello_wait.asm | čekání na stisk klávesy | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hello_wait.asm |
4 | hello_macros.asm | realizace jednotlivých částí programu makrem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hello_macros.asm |
5 | gfx4_putpixel.asm | vykreslení pixelu v grafickém režimu 4 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_putpixel.asm |
6 | gfx6_putpixel.asm | vykreslení pixelu v grafickém režimu 6 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel.asm |
7 | gfx4_line.asm | vykreslení úsečky v grafickém režimu 4 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_line.asm |
8 | gfx6_line.asm | vykreslení úsečky v grafickém režimu 6 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_line.asm |
9 | gfx6_fill1.asm | vyplnění obrazovky v grafickém režimu, základní varianta | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_fill1.asm |
10 | gfx6_fill2.asm | vyplnění obrazovky v grafickém režimu, varianta s instrukcí LOOP | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_fill2.asm |
11 | gfx6_fill3.asm | vyplnění obrazovky instrukcí REP STOSB | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_fill3.asm |
12 | gfx6_fill4.asm | vyplnění obrazovky, synchronizace vykreslování s paprskem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_fill4.asm |
13 | gfx4_image1.asm | vykreslení rastrového obrázku získaného z binárních dat, základní varianta | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image1.asm |
14 | gfx4_image2.asm | varianta vykreslení rastrového obrázku s využitím instrukce REP MOVSB | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image2.asm |
15 | gfx4_image3.asm | varianta vykreslení rastrového obrázku s využitím instrukce REP MOVSW | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image3.asm |
16 | gfx4_image4.asm | korektní vykreslení všech sudých řádků bitmapy | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image4.asm |
17 | gfx4_image5.asm | korektní vykreslení všech sudých i lichých řádků bitmapy | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image5.asm |
18 | gfx4_image6.asm | nastavení barvové palety před vykreslením obrázku | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image6.asm |
19 | gfx4_image7.asm | nastavení barvové palety před vykreslením obrázku, snížená intenzita barev | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image7.asm |
20 | gfx4_image8.asm | postupná změna barvy pozadí | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image8.asm |
21 | gfx6_putpixel1.asm | vykreslení pixelu, základní varianta se 16bitovým násobením | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel1.asm |
22 | gfx6_putpixel2.asm | vykreslení pixelu, varianta s osmibitovým násobením | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel2.asm |
23 | gfx6_putpixel3.asm | vykreslení pixelu, varianta bez násobení | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel3.asm |
24 | gfx6_putpixel4.asm | vykreslení pixelu přes obrázek, nekorektní chování (přepis obrázku) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel4.asm |
25 | gfx6_putpixel5.asm | vykreslení pixelu přes obrázek, korektní varianta pro bílé pixely | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel5.asm |
26 | cga_text_mode1.asm | standardní textový režim s rozlišením 40×25 znaků | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_mode1.asm |
27 | cga_text_mode3.asm | standardní textový režim s rozlišením 80×25 znaků | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_mode3.asm |
28 | cga_text_mode_intensity.asm | změna významu nejvyššího bitu atributového bajtu: vyšší intenzita namísto blikání | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_mode_intensity.asm |
29 | cga_text_mode_cursor.asm | změna tvaru textového kurzoru | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_mode_cursor.asm |
30 | cga_text_gfx1.asm | zobrazení „rastrové mřížky“: pseudografický režim 160×25 pixelů (interně textový režim) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_gfx1.asm |
31 | cga_text_mode_char_height.asm | změna výšky znaků | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_mode_char_height.asm |
32 | cga_text_160×100.asm | grafický režim 160×100 se šestnácti barvami (interně upravený textový režim) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_160×100.asm |
33 | hercules_text_mode1.asm | využití standardního textového režimu společně s kartou Hercules | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_text_mode1.asm |
34 | hercules_text_mode2.asm | zákaz blikání v textových režimech | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_text_mode2.asm |
35 | hercules_turn_off.asm | vypnutí generování video signálu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_turn_off.asm |
36 | hercules_gfx_mode1.asm | přepnutí karty Hercules do grafického režimu (základní varianta) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_gfx_mode1.asm |
37 | hercules_gfx_mode2.asm | přepnutí karty Hercules do grafického režimu (vylepšená varianta) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_gfx_mode2.asm |
38 | hercules_putpixel.asm | subrutina pro vykreslení jediného pixelu na kartě Hercules | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_putpixel.asm |
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