Obsah
1. Výpočty v systému pevné řádové čárky na platformě IBM PC
2. Jakými způsoby je možné reprezentovat numerické hodnoty v operační paměti počítače?
3. Uložení čísel ve formátu pevné řádové binární tečky
4. Přednosti a zápory formátu pevné řádové tečky
5. Dvojkový doplněk a čísla s pevnou řádovou binární čárkou
6. Základní vlastnosti čísel reprezentovaných v systému pevné řádové čárky
8. Realizace operace součtu v systému pevné řádové čárky
9. Součet realizovaný formou makra
10. Realizace operace součinu: naivní varianta
11. Korektní implementace součinu
12. Úprava operandů před provedením součinu
13. Úprava operandů po provedení součinu
14. Krátká odbočka: jakým způsobem se přeloží FX operace při použití jazyka C
15. Výpočet Mandelbrotovy množiny ve formátu s pevnou řádovou tečkou
16. Základní způsob realizace výpočtů
17. Neoptimalizovaná verze výpočtu Mandelbrotovy množiny
18. Částečně optimalizovaná verze výpočtu Mandelbrotovy množiny
19. Repositář s demonstračními příklady
1. Výpočty v systému pevné řádové čárky na platformě IBM PC
V seriálu o tvorbě her a dem pro úspěšnou i nenáviděnou platformu IBM PC jsme si popsali základní aritmetické instrukce mikroprocesorů řady Intel 80×86. Taktéž jsme si podrobně popsali matematický koprocesor Intel 8087 i jeho následovníky (zejména čipy 80287, 80387). Pokud mělo PC některý z těchto koprocesorů nainstalován, mohlo poměrně rychle provádět operace s hodnotami uloženými v systému plovoucí řádové čárky (FP – Floating Point). Ovšem zdaleka ne všechna PC byla tímto relativně drahým čipem vybavena. Pokud matematický koprocesor nebyl nainstalován, bylo nutné všechny FP operace emulovat, což bylo poměrně pomalé (o řád až dva řády v porovnání s reálným koprocesorem).
I z tohoto důvodu se například v mnoha hrách vůbec FP operace neprováděly a využívala se zde odlišná technika. Ta byla založena na uložení vybrané podmnožiny numerických hodnot v systému pevné řádové (binární) tečky. V tomto článku se budeme záměrně dopouštět drobného prohřešku oproti stávající normě českého jazyka, protože budeme neustále psát o řádové, desetinné a binární tečce a nikoli o čárce – z hlediska anglické terminologie to bude více konzistentní, i když z češtinského hlediska by bylo zcela jistě korektnější psát o řádové čárce, protože se v češtině celá část čísla od části desetinné odděluje právě čárkou a nikoli tečkou, jak je tomu zvykem v anglosaských zemích (programátoři, kterým je tento článek určen především, však tuto skutečnost zcela jistě znají – ostatně IT je plná podobných podivností a nepřesností – „kilobajt“ apod.).
V anglické literatuře se zmíněná forma reprezentace číselných hodnot označuje zkratkou FX nebo FXP (fixed point), zatímco dnes častěji používaná reprezentace v systému plovoucí řádové tečky se všeobecně označuje zkratkou FP (floating point). V jednom článku jsem dokonce místo zkratky FX viděl i zkratku XP (fixed point), ale to bylo před mnoha lety, v době Windows 95, tedy dávno před Windows XP :-).
Dnes si nejprve vysvětlíme princip obou metod použitých pro ukládání podmnožiny racionálních čísel a posléze si také řekneme, jaké výhody a nevýhody jednotlivé principy přináší v každodenní programátorské praxi a ve kterých situacích je vhodnější použít pevnou řádovou čárku. V dalším textu budeme formát pevné binární řádové tečky zkracovat na FX formát a formát používající plovoucí řádovou tečku budeme zapisovat jako FP formát.
2. Jakými způsoby je možné reprezentovat numerické hodnoty v operační paměti počítače?
Při ukládání numerických hodnot do operační paměti počítače poměrně záhy narazíme na některé problémy, z nichž některé souvisí s konečným počtem bitů, které pro uložení dané hodnoty „obětujeme“ a další vycházejí z vlastního způsobu zpracování hodnot mikroprocesorem či matematickým koprocesorem. V konečném počtu bitů je totiž pochopitelně možné uložit pouze konečné množství různých hodnot a je plně v rukou programátora, jak efektivně daný počet bitů využije či naopak promrhá ukládáním nepodstatných informací. Poměrně často se totiž stává, že i program využívající dvojitou či dokonce rozšířenou přesnost čísel při FP operacích (tj. když používá datové typy double a extended/temporary) dává nesprávné výsledky dané nepochopením principu práce FP aritmetiky a přitom je v některých případech možné se přesnějších výsledků dobrat i při použití pouhých 32 bitů, ale s pečlivě vyváženými aritmetickými a bitovými operacemi.
Na druhou stranu nejsou dnes používané mikroprocesory tak univerzálními zařízeními, jak by se na první pohled možná mohlo zdát. Mikroprocesory jsou totiž (většinou) navrženy tak, aby účinně, například v rámci jedné operace či instrukce, zpracovávaly pouze konstantní počet bitů zvolený výrobcem mikroprocesoru. Příkladem mohou být dnes velmi rozšířené procesory řady x86 (x86–64), které jsou velmi dobré při práci s 32 bitovými hodnotami nebo hodnotami 64bitovými, ale při požadavku na aritmetické výpočty probíhající na (řekněme) 21 bitech se veškerá jejich efektivita ztrácí a procesor se širokými vnitřními sběrnicemi, matematickým koprocesorem atd. se potýká s prohazováním jednotlivých bitů (a naopak – mnohé DSP pracují s dvaceti nebo 24 bity a nikoli s 32/64 bity).
Mnohem lepší situace nastane v případě, že se nějaká operace implementuje na programovatelném poli FPGA – zde je možné vytvořit obvody provádějící matematické a logické operace s libovolným počtem bitů, čímž se oproti univerzálním řešením (např. konstantní bitová šířka sběrnice a/nebo registrů) ušetří mnoho plochy těchto velmi zajímavých obvodů (FPGA mohou mimochodem znamenat i velkou šanci pro hnutí open source – pomocí nich by mohlo vznikat, a někde už vzniká open hardware, které by mohlo odstranit závislost na „uzavřených“ síťových a grafických kartách apod.).
Vraťme se však ke způsobům reprezentace číselných hodnot v operační paměti počítače. Nejprve předpokládejme, že pro reprezentaci vlastností určitého objektu či stavu z reálného světa použijeme N binárních číslic (bitů), tj. základních jednotek informace, která může nabývat pouze jedné ze dvou povolených hodnot (ty se značí například symboly yes/no nebo true/false, ale my se budeme spíše držet označení 0 a 1). Pomocí této uspořádané N-tice je možné popsat celkem:
20×21×22 … 2N-1=2N
jednoznačných, tj. navzájem odlišných, stavů. Množina těchto stavů může reprezentovat prakticky jakýkoliv abstraktní či reálný objekt. Přitom si musíme uvědomit, že u této množiny není nikde implicitně řečeno ani myšleno, že se jedná například o celá kladná čísla, to je pouze jedna z mnoha možných interpretací zvolené N-tice (my programátoři máme tendenci považovat celá kladná čísla za přirozenou interpretaci bitové N-tice, to však vychází pouze z našeho pohledu na svět a z našich zkušeností). Reprezentaci momentálního stavu abstraktního či reálného objektu si můžeme představit jako zobrazení z množiny binárních stavů na elementy vzorové (a obecně neuspořádané) množiny. Nejčastěji používanými zobrazeními jsou zobrazení množiny binárních stavů na interval celých kladných čísel (Unsigned Integers), popřípadě na interval celých čísel (Signed Integers).
3. Uložení čísel ve formátu pevné řádové binární tečky
Numerické hodnoty zapsané ve formátu pevné řádové binární tečky se chápou jako podmnožina racionálních čísel, což jsou taková čísla, jejichž hodnoty je možné vyjádřit vztahem:
xFX=a/b a,b leží v Z, b ≠ 0
Číselné hodnoty z uvažované podmnožiny jsou navíc omezeny další podmínkou:
b=2k b leží v Z, k leží v Z+
Protože b je celočíselnou mocninou dvojky (a ne desítky či jiného základu), určuje jeho hodnota n polohu binární tečky v uloženém čísle. Další podmínkou, která má však spíše implementační charakter, je zachování stejného počtu binárních cifer v každém reprezentovaném čísle, což mimo jiné znamená, že všechna čísla mají řádovou binární tečku umístěnou na stejném místě – z této podmínky ostatně plyne i název popisovaného způsobu reprezentace vybrané podmnožiny racionálních čísel (to je zásadní rozdíl oproti FP formátům). Tak jako i v jiných reprezentacích čísel, jsou nulové číslice před první nenulovou cifrou a za poslední nenulovou cifrou nevýznamné, proto je není zapotřebí uvádět (naše příklady jsou ovšem napsány poměrně primitivně a budou vypisovat všechny uložené cifry).
Prakticky může být číselná hodnota v systému pevné řádové tečky uložena na osmi bitech například následujícím způsobem (uvažujeme pouze kladné hodnoty):
Pozice bitu | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
Váha bitu | 24 | 23 | 22 | 21 | 20 | 2-1 | 2-2 | 2-3 |
Desítková váha bitu | 16 | 8 | 4 | 2 | 1 | 0,5 | 0,25 | 0,125 |
4. Přednosti a zápory formátu pevné řádové tečky
Ve výše uvedeném příkladu je pevná binární řádová tečka umístěna vždy napevno mezi třetím a čtvrtým bitem. A vzhledem k tomu, že je tato skutečnost dopředu známá algoritmům, které provádí zpracování čísel (součet, rozdíl, součin, výpočet druhé odmocniny, výpočet goniometrické funkce atd.), není zapotřebí spolu s číslem uchovávat i pozici binární tečky, což výrazně snižuje počet bitů, které je zapotřebí rezervovat pro čísla ze zadaného rozsahu. To je tedy první přednost systému pevné řádové tečky – pokud programátor dokáže dopředu určit rozsah všech zpracovávaných hodnot a požadovanou přesnost, může být výhodné tento systém použít. Programátor také díky explicitním určení polohy řádové tečky může určit, ve kterém místě programu se musí přesnost či rozsah zvýšit a kdy naopak snížit. Lépe se tak využije počet bitů, které můžeme pro uložení jednoho čísla obětovat (typicky je tento počet bitů roven délce slova mikroprocesoru, popř. jeho celočíselnému násobku či naopak podílu).
Jak se dozvíme v následujících kapitolách, je možné základní matematické operace (sčítání, odčítání, násobení a dělení) poměrně jednoduše implementovat i při použití formátu pevné řádové tečky. V případě, že není k dispozici specializovaný (a současně velmi komplikovaný) matematický koprocesor, je mnohdy mnohem jednodušší a rychlejší implementovat matematické operace v FX formátu. To je případ mnoha jednočipových mikroprocesorů (mikrořadičů), signálových procesorů, ale i specializovaných zařízení obsahujících programovatelné obvody CPLD či FPGA. A byl to i případ platformy IBM PC až do (přibližně) roku 1995 (u nás ještě později). Dnes sice mají komplikovanější (a dražší) FPGA implementovanou i jednotku FPU, ale mnohdy je výhodnější použít FPGA bez této jednotky a potřebné operace si do tohoto obvodu „vypálit“ po svém.
Třetí výhodou je fakt, že u FX formátu může programátor navrhnout a posléze také dodržet požadovanou přesnost všech prováděných výpočtů. To je velký rozdíl oproti FP formátu (resp. jeho podmnožinám, které se nejčastěji používají). Jak jsme si již řekli v úvodních kapitolách, není vzácností narazit na aplikace, které používají datové typy float či double a přitom jsou výpočty prováděné v těchto programech zatíženy velkou chybou, protože si programátoři plně neuvědomují některé zásadní limity FP formátu. Kritické jsou například výpočty s peněžními hodnotami, ale i pouhé sčítání čísel, jež se od sebe o mnoho řádů liší, vede k velkým chybám, které dokonce mohou zapříčinit vznik nekonečných smyček, populární dělení nulou atd.
FX formát má však i některé nevýhody. První nevýhoda spočívá v tom, že tento formát není příliš podporován, a to ani po programové stránce (podpora v programovacích jazycích), ani výrobci mikroprocesorů pro počítače PC. Situace je však odlišná v oblasti jednočipových mikropočítačů, signálových procesorů (DSP), řídicích systémů, nebo například u IBM RS 6000, který kromě jednotky FPU obsahuje i FXU – jednotku pro provádění výpočtů v pevné řádové binární čárce. Na platformě x86 je možné pro FX formát použít instrukce MMX resp. v moderních PC spíše SSEx a AVX.
Dále může být použití FX formátu nevýhodné v případě, že se mají zpracovávat numerické hodnoty, které mají velkou dynamiku, tj. poměr mezi nejvyšší a nejnižší absolutní hodnotou. V takovém případě by se mohlo stát, že by se při použití FX formátu muselo pro každé číslo alokovat velké množství bitů, které by mohlo dokonce překročit počet bitů nutných pro FP formát. Také v případě, kdy dopředu nevíme, jaké hodnoty se budou zpracovávat, může být výhodnější použití FP formátu. Zde se však nabízí otázka, ve kterých případech nevíme, jaké hodnoty můžeme na vstupu získat: většinou je již z podstaty úlohy dopředu známé, s čím je možné počítat a které hodnoty jsou naprosto nesmyslné.
Je však pravdou, že takovou analýzu málokdo dělá a když při výpočtech ve floatech dochází k chybám, tak se bez přemýšlení program přepíše na doubly a problém se tak buď odstraní, nebo alespoň odsune na pozdější dobu, například do chvíle, kdy jsou programu předložena reálná data a ne „pouze“ data testovací.
5. Dvojkový doplněk a čísla s pevnou řádovou binární čárkou
V praxi je pochopitelně mnohdy (ale zdaleka ne vždy!) nutné pracovat i se zápornými hodnotami. Zde se typicky využívá takzvaný dvojkový doplněk. Dvojkový doplněk hodnoty x (označovaný zde kvůli nedostatkům HTML symbolem #x) lze získat z jejího jedničkového doplňku ~x (tedy prosté negace všech bitů) velmi jednoduše tak, že se k tomuto doplňku přičte jednotka, tj.:
#x=~x+1=2N-x
Operaci jedničkového i dvojkového doplňku je možné provádět kromě celočíselných reprezentací i u reprezentace v pevné řádové binární čárce. Pokud je N-bitové slovo interpretováno ve vyjádření v pevné řádové čárce, může nabývat hodnot ležících v podmnožině P2 racionálních čísel:
P2=p/2b | –2N-1 ≤ p ≤ 2N-1-1
Podmnožina P2 obsahuje stále 2N prvků, stejně jako podmnožina P1 definovaná v předchozích kapitolách. Novou reprezentaci čísel budu v dalším textu označovat symbolem A(a,b), kde platí a=N-b-1.
Hodnota N-bitového čísla x je v reprezentaci A(a,b) vyjádřena výrazem:
x=1/2b(-2N-1xN-1+∑0N-22nxn)
kde symbol xn značí hodnotu n-tého bitu čísla x. Rozsah čísel reprezentovaných v A(a,b) je možné vyjádřit nerovností:
-2N-1-b ≤ x ≤ 2N-1-b-1/2b
Za zmínku stojí také skutečnost, že počet významových bitů je v reprezentaci A(a,b) vždy o jednotku nižší, než u reprezentace U(a,b). Pro reprezentaci absolutní hodnoty čísla je použito pouze nižších N-1 bitů, nejvyšší bit je díky své funkci označován jako znaménkový bit (sign bit), což je ostatně patrné z podvýrazu -2N-1xN-1.
6. Základní vlastnosti čísel reprezentovaných v systému pevné řádové čárky
V následujících odstavcích jsou vypsány základní vlastnosti numerických hodnot, které jsou reprezentovány v systému s pevnou řádovou binární čárkou. Pravidla jsou uvedena jak pro formát U(a,b) (tj. pouze pro podmnožinu z kladných racionálních čísel), tak i pro formát A(a,b), tj. pro podmnožinu z kladných i záporných racionálních čísel. Každé vlastnosti je věnována samostatná podkapitola.
6.1 Počet bitů
Počet bitů nutných pro uložení číselné hodnoty v reprezentaci U(a,b) je jednoduše roven výsledku výrazu a+b, což mimo jiné značí, že všechny bity daného bitového vektoru jsou beze zbytku použity pro uložení číselné hodnoty (nejsou rezervovány žádné speciální bity). V reprezentaci A(a,b) je počet bitů roven hodnotě a+b+1, protože jeden bit navíc je nutné rezervovat pro uložení znaménka ukládané číselné hodnoty – viz výše zmíněný znaménkový bit.
6.2 Rozsah hodnot
Rozsah hodnot v reprezentaci čísel ve formátu U(a,b) lze vyjádřit vztahem 0≤ x1 ≤ 2a-2-b, pro reprezentaci A(a,b) je rozsah hodnot vyjádřen nerovností: -2a≤ x2 ≤ 2a-2-b, což značí, že ve druhém uvedeném typu reprezentace je možné zaznamenat dvojnásobné množství navzájem odlišných hodnot – tato skutečnost je ostatně dána i větším počtem bitů pro reprezentaci A(a,b) oproti reprezentaci U(a,b) při stejných hodnotách parametrů a i b.
6.3 Platnost aritmetické operace součtu či rozdílu
Platnost aritmetické operace součtu či rozdílu hodnot uložených ve formátu U(a,b) pro kladná čísla U(a1,b1) a U(a2,b2) lze zaručit pouze tehdy, jestliže je a1 rovno a2 a současně b1 rovno b2, tj. obě hodnoty jsou uloženy ve slově (bitovém vektoru) se stejným množstvím (počtem) bitů a poloha řádové binární čárky je konstantní. Pro číselné hodnoty uložené ve druhém popisovaném formátu A(a1,b1) a A(a2,b2) platí stejné podmínky. Pokud není alespoň jedna z podmínek splněna, je nutné před provedením aditivní operace provést konverzi hodnot na shodný formát U(ax, by) resp. A(ax, by).
6.4 Rozsah výsledků po aritmetické operaci sčítání
Rozsah výsledků po aritmetické operaci sčítání dvou číselných hodnot ve formátu U(a,b) lze vyjádřit následujícím způsobem:
U(a,b)+U(a,b)=U(a+1,b)
tj. pro uložení výsledku je obecně zapotřebí vyhradit slovo širší právě o jeden bit. Pro dvě hodnoty ve formátu A(a,b) platí stejný vztah, jelikož se počet bitů obecně také zvyšuje o jednotku bez ohledu na znaménko výsledku:
A(a,b)+A(a,b)=A(a+1,b)
6.5 Rozsah výsledků po provedené aritmetické operaci násobení
Rozsah výsledků po provedené aritmetické operaci násobení dvou libovolných číselných hodnot uložených ve formátu U(a1,b1) a U(a2,b2) je možné vyjádřit následujícím vztahem:
U(a1, b1) × U(a2, b2)=U(a1+a2, b1+b2)
Výše uvedeným vztahem je popsáno, že se při ukládání výsledků takto provedené multiplikativní operace zvyšuje jak počet významových bitů před binární řádovou čárkou, tak i stejnou měrou počet zlomkových bitů, tj. bitů umístěných za binární čárkou. Při provádění multiplikativní operace s číselnými hodnotami uloženými ve formátu A(a1,b1) a A(a2,b2) je situace při ukládání výsledků následující:
A(a1,b1) × A(a2, b2)=A(a1+a2+1, b1+b2)
Tento vztah je poněkud odlišný od vztahu předchozího, ale při bližším rozboru je opět snadno pochopitelný. U číselných hodnot ve formátu A(a,b) je totiž jeden (nejvyšší) bit rezervován pro vyjádření znaménka uložené hodnoty. Po násobení je také nutné vyjádřit znaménko výsledku, ale opětovně pouze na jednom bitu, nikoli na bitech dvou.
7. Praktická část
Praktická část dnešního článku je rozdělena na dvě poloviny. V první polovině si na jednoduchých příkladech ukážeme způsob realizace základních FX operací, konkrétně operace součtu a taktéž operace součinu. A posléze si ukážeme relativně složitější příklady, ve kterých budeme vykreslovat Mandelbrotovu množinu (autorův oblíbený matematický objekt), a to plně s využitím pouze FX operací a s využitím standardního grafického režimu karty VGA s rozlišením 320×200 pixelů a s 256 barvami. Tyto příklady tedy budou bez problémů spustitelné i na IBM PC bez matematického koprocesoru.
8. Realizace operace součtu v systému pevné řádové čárky
Implementačně nejjednodušší je realizace operace součtu nebo rozdílu, protože tuto operaci je možné provést instrukcemi typu ADD, SUB atd., a to bez ohledu na pozici binární řádové tečky. V případě, že budeme pracovat s hodnotami s celkovou šířkou 32 bitů, přičemž 16 bitů je rezervováno pro část před tečkou a 16 bitů pro část za tečkou, je součet triviální – použijeme instrukci ADD s 32bitovými registry použitými ve formě operandů:
;----------------------------------------------------------------------------- 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 P equ 65536 ; poloha desetinne tecky v FX-pointu main: mov eax, 1 * P ; konstanta v FX-pointu: 1.0 print_hex eax mov eax, 1 * P ; konstanta v FX-pointu: 1.0 mov ebx, 2 * P ; konstanta v FX-pointu: 2.0 add eax, ebx ; scitani v FX-pointu print_hex eax mov eax, 1 * P / 2 ; konstanta v FX-pointu: 0.5 print_hex eax mov eax, 3 * P / 2 ; konstanta v FX-pointu: 1.5 print_hex eax mov eax, 1 * P / 2 ; konstanta v FX-pointu: 0.5 mov ebx, 3 * P / 2 ; konstanta v FX-pointu: 1.5 add eax, ebx ; scitani v FX-pointu print_hex eax finish: wait_key ; cekani na klavesu exit ; navrat do DOSu ; datova cast section .data section .bss
Výsledky v surové podobě tak, jak je vypsal příklad:
00010000 00030000 00008000 00018000 00020000
Což lze interpretovat následovně:
0001.0000 ≅ 1.0 0003.0000 ≅ 1.0 + 2.0 = 3.0 0000.8000 ≅ 0.5 0001.8000 ≅ 1.5 0002.0000 ≅ 0.5 + 1.5 = 2.0
9. Součet realizovaný formou makra
Vzhledem k jednoduchosti realizace součtu ve formátu pevné řádové tečky můžeme tuto operaci navrhnout i formou makra, což se v assembleru NASM provádí následujícím způsobem:
%macro fx_add 2 add %1, %2 %endmacro
Celý příklad se potom změní jen nepatrně (expanze makra je podtržena):
;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) %macro fx_add 2 add %1, %2 %endmacro start: jmp main ; skok na zacatek kodu %include "io.asm" ; nacist symboly, makra a podprogramy %include "print.asm" ; nacist symboly, makra a podprogramy P equ 65536 ; poloha desetinne tecky v FX-pointu main: mov eax, 1 * P ; konstanta v FX-pointu: 1.0 print_hex eax mov eax, 1 * P ; konstanta v FX-pointu: 1.0 mov ebx, 2 * P ; konstanta v FX-pointu: 2.0 fx_add eax, ebx ; scitani v FX-pointu print_hex eax mov eax, 1 * P / 2 ; konstanta v FX-pointu: 0.5 mov ebx, 3 * P / 2 ; konstanta v FX-pointu: 1.5 fx_add eax, ebx ; scitani v FX-pointu print_hex eax finish: wait_key ; cekani na klavesu exit ; navrat do DOSu ; datova cast section .data section .bss
Výsledky by nyní měly vypadat následovně:
00010000 ≅ 1.0 00030000 ≅ 3.0 = 1.0 + 2.0 00020000 ≅ 2.0 = 0.5 + 1.5
10. Realizace operace součinu: naivní varianta
Jak jsme mohli vidět v předchozí dvojici kapitol, byla realizace operace součtu s FX hodnotami triviální. Ovšem jak tomu bude u operace součinu? Zkusme si nejdříve i tuto operaci realizovat tím nejvíce naivním způsobem, konkrétně zavoláním instrukce MUL:
;----------------------------------------------------------------------------- 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 P equ 65536 ; poloha desetinne tecky v FX-pointu main: mov eax, 2 * P ; konstanta v FX-pointu: 2.0 print_hex eax mov eax, 3 * P ; konstanta v FX-pointu: 3.0 print_hex eax mov eax, 2 * P ; konstanta v FX-pointu: 1.0 mov ebx, 3 * P ; konstanta v FX-pointu: 2.0 mul ebx ; nasobeni v FX-pointu do EDX:EAX print_hex eax mov eax, 1 * P / 2 ; konstanta v FX-pointu: 0.5 print_hex eax mov eax, 3 * P ; konstanta v FX-pointu: 3.0 print_hex eax mov eax, 1 * P / 2 ; konstanta v FX-pointu: 0.5 mov ebx, 3 * P ; konstanta v FX-pointu: 3.0 mul ebx ; nasobeni v FX-pointu do EDX:EAX print_hex eax finish: wait_key ; cekani na klavesu exit ; navrat do DOSu ; datova cast section .data section .bss
Výsledky nebudou příliš uspokojivé:
00020000 ≅ 2.0 00030000 ≅ 3.0 00000000 ≅ 0.0 ≠ 2.0 * 3.0 00008000 ≅ 0.5 00030000 ≅ 3.0 80000000 ≅ 32768.0 ≠ 1.5 = (0.5 * 3.0)
Vidíme, že tato realizace násobení je zcela evidentně nekorektní.
11. Korektní implementace součinu
Problémy s operací součinu (a vlastně i podílu, i když zde se bude postupovat „opačně“), které jsme mohli vidět v předchozí kapitole, je možné vyřešit dvěma základními způsoby:
- Úpravou operandů před provedením operace součinu s tím, že výsledek bude korektní. Úpravou se zde myslí aritmetický nebo bitový posun operandů doprava o vhodný počet bitů (8, 16 atd. podle pozice řádové tečky).
- Úpravou výsledku po provedení operace součinu, tj. výsledek bude nutné vhodným způsobem opravit/upravit. Tato úprava opět spočívá v aritmetickém nebo bitovém posunu doprava.
Oba výše naznačené způsoby mají své klady i zápory. Při použití prvního způsobu ztrácíme přesnost výpočtů (některé operandy totiž budou po úpravě vynulovány, některé budou naopak nepřesné), ovšem bitová šířka výsledku bude odpovídat bitové šířce operandů (což ovšem na platformě 8086 nemusíme docenit). A naopak druhý způsob je obecně přesnější, ovšem je nutné pracovat s mezivýsledkem, jehož bitová šířka je dvojnásobná oproti bitové šířce operandů, tedy například 64 bitů pro 32 bitové operandy atd.
12. Úprava operandů před provedením součinu
Podívejme se nyní na konkrétní způsob úpravy operandů před provedením operace součinu. Vstupem budou 32bitové operandy, takže pro jejich uložení budou použity 32bitové registry EAX a EBX (80386 a vyšší). Hodnotu každého z těchto operandů posuneme doprava o osm bitů, čímž vlastně snížíme přesnost a i řádová tečka se posune o osm pozic. Následně je možné provést běžný součin a výsledek bude korektní, resp. přesněji řečeno dolní registr výsledku bude korektní (výsledek je totiž obecně 64bitový). Operaci násobení ve formátu FX lze tedy realizovat relativně snadným způsobem:
mov eax, první_operand mov ebx, druhý operand shr eax, 8 ; posun jeste pred nasobenim (ztrata presnosti) shr ebx, 8 ; posun jeste pred nasobenim (ztrata presnosti) mul ebx ; nasobeni v FX-pointu do EDX:EAX
Původní naivní variantu součinu můžeme upravit do této (sice nepřesné, ale rychlé) podoby:
;----------------------------------------------------------------------------- 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 P equ 65536 ; poloha desetinne tecky v FX-pointu main: mov eax, 2 * P ; konstanta v FX-pointu: 2.0 print_hex eax mov eax, 3 * P ; konstanta v FX-pointu: 3.0 print_hex eax mov eax, 2 * P ; konstanta v FX-pointu: 1.0 mov ebx, 3 * P ; konstanta v FX-pointu: 2.0 shr eax, 8 ; posun jeste pred nasobenim (ztrata presnosti) shr ebx, 8 ; posun jeste pred nasobenim (ztrata presnosti) mul ebx ; nasobeni v FX-pointu do EDX:EAX print_hex eax mov eax, 1 * P / 2 ; konstanta v FX-pointu: 0.5 print_hex eax mov eax, 3 * P ; konstanta v FX-pointu: 3.0 print_hex eax mov eax, 1 * P / 2 ; konstanta v FX-pointu: 0.5 mov ebx, 3 * P ; konstanta v FX-pointu: 3.0 shr eax, 8 ; posun jeste pred nasobenim (ztrata presnosti) shr ebx, 8 ; posun jeste pred nasobenim (ztrata presnosti) mul ebx ; nasobeni v FX-pointu do EDX:EAX print_hex eax finish: wait_key ; cekani na klavesu exit ; navrat do DOSu ; datova cast section .data section .bss
Ověřme si, zda výpočty skutečně probíhají podle očekávání:
00020000 ≅ 2.0 00030000 ≅ 3.0 00060000 ≅ 6.0 = 2.0 * 3.0 00008000 ≅ 0.5 00030000 ≅ 3.0 00018000 ≅ 1.5 = 0.5 * 3.0
Z výsledků je patrné, že pro tyto konkrétní operandy skutečně dostaneme správné výsledky. Příště se zaměříme na diskusi o ztrátě přesnosti atd.
13. Úprava operandů po provedení součinu
Můžeme se pokusit implementovat i „opačný“ způsob provedení operace součinu, tj. nejdříve oba operandy vynásobit a teprve poté provést bitový posun. Tato metoda je výhodnější z toho pohledu, že výsledek bude přesnější (bity totiž ztrácíme až po provedení součinu), ovšem nevýhodou je, že operace násobení musí výsledek uložit do dvojnásobného počtu bitů. To konkrétně znamená, že pro dvojici 32bitových operandů bude výsledek 64bitový. Na platformě 80386 je toho možné dosáhnout relativně snadno, protože operace MUL v tomto případě vrátí výsledek ve dvojici registrů EDX:EAX. Tento obsah musíme posunout doprava o šestnáct bitů. To lze provést malým trikem – přesunem šestnáctibitové části výsledku (bity 15 až 23 do bitů 0 až 7) a rotací 32bitového registru o šestnáct bitů (musí se jednat o rotaci, nikoli o posun):
mov eax, první_operand mov ebx, druhý_operand mul ebx ; nasobeni v FX-pointu do EDX:EAX mov ax, dx ; bity 16-32 ror eax, 16 ; prohodit horni a spodni polovinu registru
Praktická realizace takto realizovaného součinu využívajícího FX formát 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 P equ 65536 ; poloha desetinne tecky v FX-pointu main: mov eax, 2 * P ; konstanta v FX-pointu: 2.0 print_hex eax mov eax, 3 * P ; konstanta v FX-pointu: 3.0 print_hex eax mov eax, 2 * P ; konstanta v FX-pointu: 1.0 mov ebx, 3 * P ; konstanta v FX-pointu: 2.0 mul ebx ; nasobeni v FX-pointu do EDX:EAX mov ax, dx ; bity 16-32 ror eax, 16 ; prohodit horni a spodni polovinu registru print_hex eax mov eax, 1 * P / 2 ; konstanta v FX-pointu: 0.5 print_hex eax mov eax, 3 * P ; konstanta v FX-pointu: 3.0 print_hex eax mov eax, 1 * P / 2 ; konstanta v FX-pointu: 0.5 mov ebx, 3 * P ; konstanta v FX-pointu: 3.0 mul ebx ; nasobeni v FX-pointu do EDX:EAX mov ax, dx ; bity 16-32 ror eax, 16 ; prohodit horni a spodni polovinu registru print_hex eax finish: wait_key ; cekani na klavesu exit ; navrat do DOSu ; datova cast section .data section .bss
Opět se podívejme na vypočtené výsledky a pokusme se je analyzovat:
00020000 ≅ 2.0 00030000 ≅ 3.0 00060000 ≅ 6.0 = 2.0 * 3.0 00008000 ≅ 0.5 00030000 ≅ 3.0 00018000 ≅ 1.5 = 0.5 * 3.0
Z výsledků je opět patrné, že jsou korektní.
14. Krátká odbočka: jakým způsobem se přeloží FX operace při použití jazyka C
Jen pro zajímavost se podívejme na to, jak dobře (nebo naopak špatně) jsou přeloženy operace s pevnou řádovou tečkou v případě, pokud pro jejich zápis použijeme programovací jazyk C. Výsledky nemusí dopadnout dobře tehdy, když explicitně nespecifikujeme, že mezivýsledky mohou mít vyšší počet bitů, než operandy (resp. parametry příslušných funkcí). Ostatně se o tom můžeme přesvědčit sami:
#include <stdint.h> uint32_t fx_add(uint32_t x, uint32_t y) { return x+y; } uint32_t fx_mul_1(uint32_t x, uint32_t y) { return (x>>8) * (y>>8); } uint32_t fx_mul_2(uint32_t x, uint32_t y) { return (x*y)>>16; }
Překlad provedený bez optimalizací, tj. s přepínačem -O0:
fx_add(unsigned int, unsigned int): push rbp mov rbp, rsp mov DWORD PTR [rbp-4], edi mov DWORD PTR [rbp-8], esi mov edx, DWORD PTR [rbp-4] mov eax, DWORD PTR [rbp-8] add eax, edx pop rbp ret fx_mul_1(unsigned int, unsigned int): push rbp mov rbp, rsp mov DWORD PTR [rbp-4], edi mov DWORD PTR [rbp-8], esi mov eax, DWORD PTR [rbp-4] shr eax, 8 mov edx, eax mov eax, DWORD PTR [rbp-8] shr eax, 8 imul eax, edx pop rbp ret fx_mul_2(unsigned int, unsigned int): push rbp mov rbp, rsp mov DWORD PTR [rbp-4], edi mov DWORD PTR [rbp-8], esi mov eax, DWORD PTR [rbp-4] imul eax, DWORD PTR [rbp-8] shr eax, 16 pop rbp ret
Překlad provedený s optimalizacemi na výkon, tj. -O9:
fx_add(unsigned int, unsigned int): lea eax, [rdi+rsi] ret fx_mul_1(unsigned int, unsigned int): shr edi, 8 shr esi, 8 mov eax, edi imul eax, esi ret fx_mul_2(unsigned int, unsigned int): imul edi, esi mov eax, edi shr eax, 16 ret
Překlad provedený s optimalizacemi na velikost výsledného kódu, tj. -Os:
fx_add(unsigned int, unsigned int): lea eax, [rdi+rsi] ret fx_mul_1(unsigned int, unsigned int): shr edi, 8 shr esi, 8 mov eax, edi imul eax, esi ret fx_mul_2(unsigned int, unsigned int): imul edi, esi mov eax, edi shr eax, 16 ret
Pochopitelně je možné správným přetypováním dosáhnout kýženého výsledku, ovšem v tomto konkrétním případě si dovolím tvrdit, že assemblerovský kódu bude mnohem čitelnější v porovnání s céčkovou variantou.
15. Výpočet Mandelbrotovy množiny ve formátu s pevnou řádovou tečkou
V závěrečné části dnešního článku si ukážeme, jakým způsobem je možné formát s pevnou řádovou tečkou použít v praxi. Budeme provádět výpočet Mandelbrotovy množiny, který již byl na stránkách Roota realizován mnoha různými způsoby a v mnoha programovacích jazycích. Nyní se ovšem zaměříme na realizaci využívající assembler, reálný režim IBM PC a navíc bude pro vykreslování použit grafický režim karty VGA s rozlišením 320×200 pixelů s 256 barvami (což je z pohledu programátora ten nejjednodušší grafický režim vůbec). Díky použití formátu s pevnou řádovou čárkou není nutné, aby byl nainstalován matematický koprocesor – ten dokonce ani nemusí být emulován, protože není použita ani jedna jeho instrukce. V každém případě by výsledkem měl být přesně tento obraz (bude bitově totožný na všech variantách IBM PC, protože nezáleží na přesnosti FP výpočtů, na jeho zaokrouhlovacích režimech, optimalizacích překladače atd.):
16. Základní způsob realizace výpočtů
V pseudokódu (a Python můžeme v tomto kontextu za pseudokód považovat) může výpočet Mandelbrotovy množiny vypadat následovně. Většina použitých proměnných jsou typu double, pouze proměnná i je typu int/long:
def calc_mandelbrot(width, height, maxiter, palette): cy_ = -1.5 for y in range(height): cx_ = -2.0 for x in range(width): zx1 = 0.0 zy1 = 0.0 i = 0 while i < maxiter: zx2 = zx1 * zx1 zy2 = zy1 * zy1 if zx2 + zy2 > 4.0: break zy1 = 2.0 * zx1 * zy1 + cy_ zx1 = zx2 - zy2 + cx_ i += 1 r = palette[i][0] g = palette[i][1] b = palette[i][2] putpixel(x, y, r, g, b) cx_ += 3.0/width cy_ += 3.0/height
Podívejme se nyní na realizaci některých výše uvedených výpočtů v assembleru s využitím formátu FX.
Proměnná cy_ je na začátku inicializována, další pak nikoli:
section .data cy_ dd MIN ; poloha v komplexni rovine rovine section .bss cx_ resd 1 ; zx1 resd 1 ; zy1 resd 1 ; aktualni poloha v komplexni rovine zx2 resd 1 ; zx2=zx1^2 (aby se to nemuselo pocitat 2x) zy2 resd 1 ; zy2=zy1^2
Realizace výpočtu zx2 = zx1 * zx1:
mov EAX, dword [zx1] ; sar EAX, 8 ; imul EAX ; zx2:=zx1^2 (v X-pointu) mov dword [zx2], EAX ;
Realizace výpočtu zy2 = zy1 * zy1:
mov EAX, dword [zy1] ; sar EAX, 8 ; imul EAX ; zy2:=zy1^2 (v X-pointu) mov dword [zy2], EAX ;
Realizace výpočtů:
zy1 = 2.0 * zx1 * zy1 + cy_ zx1 = zx2 - zy2 + cx_
vypadá následovně:
mov EAX, [zx1] ; sar EAX, 8 ; zx1 div 256 (pro mul v X-pointu) mov EBX, [zy1] ; sar EBX, 7 ; zy1 div 256 * 2 (pro mul v X-pointu) imul EBX ; zy1:=2*zx1*zy1 add EAX, [cy_] ; zy1:=2*zx1*zy1+CY (u Mandelbrota poc.iter.) mov [zy1], EAX ; ulozit novou hodnotu zy1 mov EAX, [zx2] ; sub EAX, [zy2] ; zx2:=zx2-zy2=zx1^2-zy1^2 add EAX, [cx_] ; mov [zx1], EAX ; zx1:=zx1^2-zy1^2+CX
A konečně test, zda zx2+zy2 nepřesáhla hodnotu BAILOUT:
mov EAX, [zx2] ; add EAX, [zy2] ; ==zx1^2+zy1^2 cmp EAX, BAILOUT*P ; kontrola na bailout (abs[Z]<4) jc short iter_loop ; abs[Z]<4 =>dalsi iterace
17. Neoptimalizovaná verze výpočtu Mandelbrotovy množiny
Neoptimalizovaná varianta programu, který po svém spuštění vykreslí Mandelbrotovu množinu, vypadá následovně. Velikost výsledného kódu je 188 bajtů:
;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) ; konstanty P equ 65536 ; poloha desetinne tecky v X-pointu K equ 4*P/256 ; vzdalenost mezi dvema body (krok smycky) L equ 4*P/192 MIN equ -2*P ; minimalni a maximalni hodnota konstant fraktalu ; v komplexni rovine MAXITER equ 40 ; maximalni pocet iteraci BAILOUT equ 4 section .text start: jmp main ; skok na zacatek kodu %include "io.asm" ; nacist symboly, makra a podprogramy main: mov ax, 13h ; graficky rezim 320x200x256 int 10h ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ;: MANDELBROTOVA MNOZINA :: ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: push 0xa000 pop ES ; segment obrazove pameti karty VGA mov DI, 320*8+32 ; zacatek vykreslovani na obrazovce mov BP, 192 ; BP==[x] fraktal bude velikosti 256x192 pixelu mforx: mov dword [cx_], MIN ; od -2 (imaginarni osa) mov SI, 256 ; SI==[y] mfory: mov CL, MAXITER ; maximalni pocet iteraci xor EAX, EAX ; mov dword [zx1], EAX ; nastaveni real.casti zacatku mov dword [zy1], EAX ; nastaveni imag.casti zacatku iter_loop: ; *** iteracni smycka *** mov EAX, dword [zx1] ; sar EAX, 8 ; imul EAX ; zx2:=zx1^2 (v X-pointu) mov dword [zx2], EAX ; mov EAX, dword [zy1] ; sar EAX, 8 ; imul EAX ; zy2:=zy1^2 (v X-pointu) mov dword [zy2], EAX ; mov EAX, [zx1] ; sar EAX, 8 ; zx1 div 256 (pro mul v X-pointu) mov EBX, [zy1] ; sar EBX, 7 ; zy1 div 256 * 2 (pro mul v X-pointu) imul EBX ; zy1:=2*zx1*zy1 add EAX, [cy_] ; zy1:=2*zx1*zy1+CY (u Mandelbrota poc.iter.) mov [zy1], EAX ; ulozit novou hodnotu zy1 mov EAX, [zx2] ; sub EAX, [zy2] ; zx2:=zx2-zy2=zx1^2-zy1^2 add EAX, [cx_] ; mov [zx1], EAX ; zx1:=zx1^2-zy1^2+CX dec CL ; upravit pocitadlo iteraci jz short mpokrac ; konec iteraci ? mov EAX, [zx2] ; add EAX, [zy2] ; ==zx1^2+zy1^2 cmp EAX, BAILOUT*P ; kontrola na bailout (abs[Z]<4) jc short iter_loop ; abs[Z]<4 =>dalsi iterace mpokrac: mov AL, CL ; pocet iteraci add AL, 32 ; posun na vhodne barvy v palete stosb ; vykreslit pixel+posun na dalsi pixel add dword [cx_], K ; cy_:=cy_+K dec si jnz mfory ; Y!=0 ->dalsi radek add DI, 320-256 ; dalsi radek na obrazovce add dword [cy_], L ; cx_:=cx_+K dec BP ; x=x-1 jnz mforx ; X!=0 ->dalsi radek finish: wait_key ; cekani na klavesu exit ; navrat do DOSu section .data cy_ dd MIN ; poloha v komplexni rovine rovine section .bss cx_ resd 1 ; zx1 resd 1 ; zy1 resd 1 ; aktualni poloha v komplexni rovine zx2 resd 1 ; zx2=zx1^2 (aby se to nemuselo pocitat 2x) zy2 resd 1 ; zy2=zy1^2 ; finito
18. Částečně optimalizovaná verze výpočtu Mandelbrotovy množiny
Některé výpočty prováděné v příkladu uvedeném v předchozí kapitole, je možné optimalizovat. Mezivýsledky mohou být uloženy přímo v pracovních registrech, polohu řádové tečky je možné posunout o několik bitů (a zmenšit tak rozsah registrů) a vykreslování může být prováděno přes všech 320 sloupců, což poněkud zjednoduší programovou logiku. Výsledný program bude generovat nepatrně odlišný obrázek a bude kratší (172 bajtů namísto 188 bajtů):
Zdrojový kód demonstračního příkladu byl upraven do této podoby:
;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) ; konstanty P equ 4096 ; poloha desetinne tecky v X-pointu K equ 4*P/256 ; vzdalenost mezi dvema body (krok smycky) L equ 4*P/192 MIN equ -2*P ; minimalni a maximalni hodnota konstant fraktalu ; v komplexni rovine MAXITER equ 40 ; maximalni pocet iteraci BAILOUT equ 4 SLOUPCU equ 320 ; pocet sloupcu na obrazovce section .text start: jmp main ; skok na zacatek kodu %include "io.asm" ; nacist symboly, makra a podprogramy main: mov ax, 13h ; graficky rezim 320x200x256 int 10h ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ;: MANDELBROTOVA MNOZINA :: ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: push 0xa000 pop ES ; segment obrazove pameti karty VGA xor DI, DI ; zacatek vykreslovani na obrazovce mov CL, 6 ; posun pro FX format mforx: mov dword [cx_], MIN ; od -2 (imaginarni osa) mov SI, SLOUPCU ; x mfory: mov CH, MAXITER ; pocet iteraci xor EAX, EAX ; mov EBP, EAX ; nastaveni real.casti zacatku mov dword [zy1], EAX ; nastaveni imag.casti zacatku iter_loop: ; *** iteracni smycka *** mov EAX, EBP ; sar EAX, CL ; imul EAX ; zx2:=zx1^2 (v X-pointu) mov dword [zx2], EAX ; mov EAX, dword [zy1] ; sar EAX, CL ; imul EAX ; zy2:=zy1^2 (v X-pointu) mov dword [zy2], EAX ; mov EAX, EBP ; sar EAX, CL ; zx1 div 256 (pro mul v X-pointu) mov EBX, [zy1] ; sar EBX, 5 ; zy1 div 256 * 2 (pro mul v X-pointu) imul EBX ; zy1:=2*zx1*zy1 add EAX, [cy_] ; zy1:=2*zx1*zy1+CY (u Mandelbrota poc.iter.) mov [zy1], EAX ; ulozit novou hodnotu zy1 mov EAX, [zx2] ; sub EAX, [zy2] ; zx2:=zx2-zy2=zx1^2-zy1^2 add EAX, [cx_] ; mov EBP, EAX ; zx1:=zx1^2-zy1^2+CX dec CH ; pocitadlo iteraci jz short mpokrac ; konec iteraci ? mov EAX, [zx2] ; add EAX, [zy2] ; ==zx1^2+zy1^2 cmp EAX, BAILOUT*P ; kontrola na bailout (abs[Z]<4) jc short iter_loop ; abs[Z]<4 =>dalsi iterace mpokrac: mov AL, CH ; pocet iteraci add AL, 32 ; posun na vhodne barvy v palete stosb ; vykreslit pixel+posun na dalsi pixel add dword [cx_], K ; cy_:=cy_+K dec si jnz short mfory ; Y!=0 ->dalsi radek add dword [cy_], L ; cx_:=cx_+K cmp di, 64000 ; konec obrazku ? jne mforx finish: wait_key ; cekani na klavesu exit ; navrat do DOSu section .data cy_ dd MIN ; poloha v komplexni rovine rovine section .bss cx_ resd 1 ; zy1 resd 1 ; aktualni poloha v komplexni rovine zx2 resd 1 ; zx2=zx1^2 (aby se to nemuselo pocitat 2x) zy2 resd 1 ; zy2=zy1^2 ; finito
19. Repositář s demonstračními příklady
Demonstrační příklady napsané v assembleru, které jsou určené pro překlad s využitím assembleru NASM, byly uloženy do Git repositáře, který je dostupný na adrese https://github.com/tisnik/8bit-fame. Jednotlivé demonstrační příklady si můžete v případě potřeby stáhnout i jednotlivě bez nutnosti klonovat celý (dnes již poměrně rozsáhlý) repositář:
# | Příklad | Stručný popis | Adresa |
---|---|---|---|
1 | hello.asm | program typu „Hello world“ naprogramovaný v assembleru pro systém DOS | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hello.asm |
2 | hello_shorter.asm | kratší varianta výskoku z procesu zpět do DOSu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hello_shorter.asm |
3 | hello_wait.asm | čekání na stisk klávesy | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hello_wait.asm |
4 | hello_macros.asm | realizace jednotlivých částí programu makrem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hello_macros.asm |
5 | gfx4_putpixel.asm | vykreslení pixelu v grafickém režimu 4 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_putpixel.asm |
6 | gfx6_putpixel.asm | vykreslení pixelu v grafickém režimu 6 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel.asm |
7 | gfx4_line.asm | vykreslení úsečky v grafickém režimu 4 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_line.asm |
8 | gfx6_line.asm | vykreslení úsečky v grafickém režimu 6 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_line.asm |
9 | gfx6_fill1.asm | vyplnění obrazovky v grafickém režimu, základní varianta | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_fill1.asm |
10 | gfx6_fill2.asm | vyplnění obrazovky v grafickém režimu, varianta s instrukcí LOOP | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_fill2.asm |
11 | gfx6_fill3.asm | vyplnění obrazovky instrukcí REP STOSB | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_fill3.asm |
12 | gfx6_fill4.asm | vyplnění obrazovky, synchronizace vykreslování s paprskem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_fill4.asm |
13 | gfx4_image1.asm | vykreslení rastrového obrázku získaného z binárních dat, základní varianta | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image1.asm |
14 | gfx4_image2.asm | varianta vykreslení rastrového obrázku s využitím instrukce REP MOVSB | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image2.asm |
15 | gfx4_image3.asm | varianta vykreslení rastrového obrázku s využitím instrukce REP MOVSW | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image3.asm |
16 | gfx4_image4.asm | korektní vykreslení všech sudých řádků bitmapy | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image4.asm |
17 | gfx4_image5.asm | korektní vykreslení všech sudých i lichých řádků bitmapy | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image5.asm |
18 | gfx4_image6.asm | nastavení barvové palety před vykreslením obrázku | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image6.asm |
19 | gfx4_image7.asm | nastavení barvové palety před vykreslením obrázku, snížená intenzita barev | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image7.asm |
20 | gfx4_image8.asm | postupná změna barvy pozadí | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image8.asm |
21 | gfx6_putpixel1.asm | vykreslení pixelu, základní varianta se 16bitovým násobením | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel1.asm |
22 | gfx6_putpixel2.asm | vykreslení pixelu, varianta s osmibitovým násobením | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel2.asm |
23 | gfx6_putpixel3.asm | vykreslení pixelu, varianta bez násobení | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel3.asm |
24 | gfx6_putpixel4.asm | vykreslení pixelu přes obrázek, nekorektní chování (přepis obrázku) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel4.asm |
25 | gfx6_putpixel5.asm | vykreslení pixelu přes obrázek, korektní varianta pro bílé pixely | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel5.asm |
26 | cga_text_mode1.asm | standardní textový režim s rozlišením 40×25 znaků | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_mode1.asm |
27 | cga_text_mode3.asm | standardní textový režim s rozlišením 80×25 znaků | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_mode3.asm |
28 | cga_text_mode_intensity.asm | změna významu nejvyššího bitu atributového bajtu: vyšší intenzita namísto blikání | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_mode_intensity.asm |
29 | cga_text_mode_cursor.asm | změna tvaru textového kurzoru | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_mode_cursor.asm |
30 | cga_text_gfx1.asm | zobrazení „rastrové mřížky“: pseudografický režim 160×25 pixelů (interně textový režim) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_gfx1.asm |
31 | cga_text_mode_char_height.asm | změna výšky znaků | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_mode_char_height.asm |
32 | cga_text_160×100.asm | grafický režim 160×100 se šestnácti barvami (interně upravený textový režim) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_160×100.asm |
33 | hercules_text_mode1.asm | využití standardního textového režimu společně s kartou Hercules | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_text_mode1.asm |
34 | hercules_text_mode2.asm | zákaz blikání v textových režimech | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_text_mode2.asm |
35 | hercules_turn_off.asm | vypnutí generování video signálu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_turn_off.asm |
36 | hercules_gfx_mode1.asm | přepnutí karty Hercules do grafického režimu (základní varianta) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_gfx_mode1.asm |
37 | hercules_gfx_mode2.asm | přepnutí karty Hercules do grafického režimu (vylepšená varianta) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_gfx_mode2.asm |
38 | hercules_putpixel.asm | subrutina pro vykreslení jediného pixelu na kartě Hercules | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_putpixel.asm |
39 | ega_text_mode_80×25.asm | standardní textový režim 80×25 znaků na kartě EGA | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_text_mode_80×25.asm |
40 | ega_text_mode_80×43.asm | zobrazení 43 textových řádků na kartě EGA | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_text_mode_80×43.asm |
41 | ega_gfx_mode_320×200.asm | přepnutí do grafického režimu 320×200 pixelů se šestnácti barvami | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_gfx_mode_320×200.asm |
42 | ega_gfx_mode_640×200.asm | přepnutí do grafického režimu 640×200 pixelů se šestnácti barvami | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_gfx_mode_640×200.asm |
43 | ega_gfx_mode_640×350.asm | přepnutí do grafického režimu 640×350 pixelů se čtyřmi nebo šestnácti barvami | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_gfx_mode_640×350.asm |
44 | ega_gfx_mode_bitplanes1.asm | ovládání zápisu do bitových rovin v planárních grafických režimech (základní způsob) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_gfx_mode_bitplanes1.asm |
45 | ega_gfx_mode_bitplanes2.asm | ovládání zápisu do bitových rovin v planárních grafických režimech (rychlejší způsob) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_gfx_mode_bitplanes2.asm |
46 | ega_320×200_putpixel.asm | vykreslení pixelu v grafickém režimu 320×200 pixelů se šestnácti barvami | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_320×200_putpixel.asm |
47 | ega_640×350_putpixel.asm | vykreslení pixelu v grafickém režimu 640×350 pixelů se šestnácti barvami | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_640×350_putpixel.asm |
48 | ega_standard_font.asm | použití standardního fontu grafické karty EGA | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_standard_font.asm |
49 | ega_custom_font.asm | načtení vlastního fontu s jeho zobrazením | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_custom_font.asm |
50 | ega_palette1.asm | změna barvové palety (všech 16 barev) v grafickém režimu 320×200 se šestnácti barvami | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_palette1.asm |
51 | ega_palette2.asm | změna barvové palety (všech 16 barev) v grafickém režimu 640×350 se šestnácti barvami | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_palette2.asm |
52 | ega_palette3.asm | změna všech barev v barvové paletě s využitím programové smyčky | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_palette3.asm |
53 | ega_palette4.asm | změna všech barev, včetně barvy okraje, v barvové paletě voláním funkce BIOSu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_palette4.asm |
54 | vga_text_mode_80×25.asm | standardní textový režim 80×25 znaků na kartě VGA | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_80×25.asm |
55 | vga_text_mode_80×50.asm | zobrazení 50 a taktéž 28 textových řádků na kartě VGA | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_80×50.asm |
56 | vga_text_mode_intensity1.asm | změna chování atributového bitu pro blikání (nebezpečná varianta změny registrů) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_intensity1.asm |
57 | vga_text_mode_intensity2.asm | změna chování atributového bitu pro blikání (bezpečnější varianta změny registrů) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_intensity2.asm |
58 | vga_text_mode_9th_column.asm | modifikace způsobu zobrazení devátého sloupce ve znakových režimech (720 pixelů na řádku) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_9th_column.asm |
59 | vga_text_mode_cursor_shape.asm | změna tvaru textového kurzoru na grafické kartě VGA | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_cursor_shape.asm |
60 | vga_text_mode_custom_font.asm | načtení vlastního fontu s jeho zobrazením | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_custom_font.asm |
61 | vga_gfx_mode_640×480.asm | přepnutí do grafického režimu 640×480 pixelů se šestnácti barvami, vykreslení vzorků | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_640×480.asm |
62 | vga_gfx_mode_320×200.asm | přepnutí do grafického režimu 320×200 pixelů s 256 barvami, vykreslení vzorků | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_320×200.asm |
63 | vga_gfx_mode_palette.asm | změna všech barev v barvové paletě grafické karty VGA | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_palette.asm |
64 | vga_gfx_mode_dac1.asm | využití DAC (neočekávané výsledky) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_dac1.asm |
65 | vga_gfx_mode_dac2.asm | využití DAC (očekávané výsledky) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_dac2.asm |
66 | vga_640×480_putpixel.asm | realizace algoritmu pro vykreslení pixelu v grafickém režimu 640×480 pixelů se šestnácti barvami | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_640×480_putpixel.asm |
67 | vga_320×200_putpixel1.asm | realizace algoritmu pro vykreslení pixelu v grafickém režimu 320×200 s 256 barvami (základní varianta) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_putpixel1.asm |
68 | vga_320×200_putpixel2.asm | realizace algoritmu pro vykreslení pixelu v grafickém režimu 320×200 s 256 barvami (rychlejší varianta) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_putpixel2.asm |
69 | vga_gfx_mode_dac3.asm | přímé využití DAC v grafickém režimu 13h | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_dac3.asm |
70 | vga_gfx_mode_unchained_step1.asm | zobrazení barevných pruhů v režimu 13h | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_unchained_step1.asm |
71 | vga_gfx_mode_unchained_step2.asm | vypnutí zřetězení bitových rovin a změna způsobu adresování pixelů | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_unchained_step2.asm |
72 | vga_gfx_mode_unchained_step3.asm | vykreslení barevných pruhů do vybraných bitových rovin | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_unchained_step3.asm |
73 | vga_gfx_mode_320×400.asm | nestandardní grafický režim s rozlišením 320×400 pixelů a 256 barvami | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_320×400.asm |
74 | vga_320×200_image.asm | zobrazení rastrového obrázku ve standardním grafickém režimu 320×200 pixelů | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_image.asm |
75 | vga_320×200_unchained_image1.asm | zobrazení rastrového obrázku v režimu s nezřetězenými rovinami (nekorektní řešení) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_unchained_image1.asm |
76 | vga_320×200_unchained_image2.asm | zobrazení rastrového obrázku v režimu s nezřetězenými rovinami (korektní řešení) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_unchained_image2.asm |
77 | vga_320×400_unchained_image.asm | zobrazení rastrového obrázku v nestandardním režimu 320×400 pixelů | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×400_unchained_image.asm |
78 | vga_vertical_scroll1.asm | vertikální scrolling na kartě VGA v režimu s rozlišením 320×200 pixelů | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_vertical_scroll1.asm |
79 | vga_vertical_scroll2.asm | vertikální scrolling na kartě VGA v režimu s rozlišením 320×400 pixelů | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_vertical_scroll2.asm |
80 | vga_split_screen1.asm | režim split-screen a scrolling, nefunční varianta | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_split_screen1.asm |
81 | vga_split_screen2.asm | režim split-screen a scrolling, plně funkční varianta | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_split_screen2.asm |
82 | vga_horizontal_scroll1.asm | horizontální scrolling bez rozšíření počtu pixelů na virtuálním řádku | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_horizontal_scroll1.asm |
83 | vga_horizontal_scroll2.asm | horizontální scrolling s rozšířením počtu pixelů na virtuálním řádku | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_horizontal_scroll2.asm |
84 | vga_horizontal_scroll3.asm | jemný horizontální scrolling s rozšířením počtu pixelů na virtuálním řádku | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_horizontal_scroll3.asm |
85 | vga_320×240_image.asm | nastavení grafického režimu Mode-X, načtení a vykreslení obrázku, scrolling | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×240_image.asm |
86 | io.asm | knihovna maker pro I/O operace | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/io.asm |
87 | vga_lib.asm | knihovna maker a podprogramů pro programování karty VGA | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_lib.asm |
88 | vga_320×240_lib.asm | nastavení grafického režimu Mode-X, tentokrát knihovními funkcemi | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×240_lib.asm |
89 | vga_bitblt1.asm | první (naivní) implementace operace BitBLT | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_bitblt1.asm |
90 | vga_bitblt2.asm | operace BitBLT s výběrem bitových rovin pro zápis | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_bitblt2.asm |
91 | vga_bitblt3.asm | operace BitBLT s výběrem bitových rovin pro čtení i zápis | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_bitblt3.asm |
92 | vga_bitblt4.asm | korektní BitBLT pro 16barevný režim, realizace makry | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_bitblt4.asm |
93 | vga_bitblt5.asm | korektní BitBLT pro 16barevný režim, realizace podprogramem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_bitblt5.asm |
94 | vga_bitblt_rotate.asm | zápisový režim s rotací bajtu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_bitblt_rotate.asm |
95 | vga_bitblt_fast.asm | rychlá korektní 32bitová operace typu BitBLT | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_bitblt_fast.asm |
96 | vga_320×400_bitblt1.asm | přenos obrázku v režimu 320×400 operací BitBLT (neúplná varianta) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×400_bitblt1.asm |
97 | vga_320×400_bitblt2.asm | přenos obrázku v režimu 320×400 operací BitBLT (úplná varianta) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×400_bitblt2.asm |
98 | vga_write_modes1.asm | volitelné zápisové režimy grafické karty VGA, zápis bez úpravy latche | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_write_modes1.asm |
99 | vga_write_modes2.asm | volitelné zápisové režimy grafické karty VGA, zápis s modifikací latche | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_write_modes2.asm |
100 | vga_write_modes3.asm | volitelné zápisové režimy grafické karty VGA, cílená modifikace latche vzorkem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_write_modes3.asm |
101 | instruction_jump.asm | použití instrukce JMP | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_jump.asm |
102 | instruction_jnz.asm | použití instrukce JNZ pro realizaci programové smyčky | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_jnz.asm |
103 | instruction_jz_jmp.asm | použití instrukcí JZ a JMP pro realizaci programové smyčky | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_jz_jmp.asm |
104 | instruction_loop.asm | použití instrukce LOOP pro realizaci programové smyčky | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_loop.asm |
105 | instruction_template.asm | šablona všech následujících demonstračních příkladů | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_template.asm |
106 | instruction_print_hex.asm | tisk osmibitové hexadecimální hodnoty | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_print_hex.asm |
107 | instruction_xlat.asm | využití instrukce XLAT pro získání tisknutelné hexadecimální cifry | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_xlat.asm |
108 | instruction_daa.asm | operace součtu s využitím binární i BCD aritmetiky | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_daa.asm |
109 | instruction_daa_sub.asm | instrukce DAA po provedení operace rozdílu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_daa_sub.asm |
110 | instruction_das.asm | instrukce DAS po provedení operace rozdílu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_das.asm |
111 | instruction_aaa.asm | korekce výsledku na jedinou BCD cifru operací AAA | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_aaa.asm |
112 | instruction_mul.asm | ukázka výpočtu součinu dvou osmibitových hodnot | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_mul.asm |
113 | instruction_aam.asm | BCD korekce po výpočtu součinu instrukcí AAM | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_aam.asm |
114 | instruction_stosb.asm | blokový zápis dat instrukcí STOSB | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_stosb.asm |
115 | instruction_rep_stosb.asm | opakované provádění instrukce STOSB | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_rep_stosb.asm |
116 | instruction_lodsb.asm | čtení dat instrukcí LODSB | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_lodsb.asm |
117 | instruction_movsb.asm | přenos jednoho bajtu instrukcí MOVSB | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_movsb.asm |
118 | instruction_rep_movsb.asm | blokový přenos po bajtech instrukcí MOVSB | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_rep_movsb.asm |
119 | instruction_rep_scas.asm | vyhledávání v řetězci instrukcí SCAS | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_rep_scas.asm |
120 | vga_320×200_image_0B.asm | výsledek blokového přenosu ve chvíli, kdy je CX=0 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_image_0B.asm |
121 | vga_320×200_image_64kB.asm | výsledek blokového přenosu ve chvíli, kdy je CX=0×ffff | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_image_64kB.asm |
122 | vga_320×200_image_movsb.asm | blokový přenos v rámci obrazové paměti instrukcí REP MOVSB | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_image_movsb.asm |
123 | vga_320×200_image_movsw.asm | blokový přenos v rámci obrazové paměti instrukcí REP MOVSW | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_image_movsw.asm |
124 | vga_320×200_image_movsd.asm | blokový přenos v rámci obrazové paměti instrukcí REP MOVSD | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_image_movsd.asm |
125 | vga_320×200_image_movsb_forward.asm | blokový přenos překrývajících se bloků paměti (zvyšující se adresy) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_image_movsb_forward.asm |
126 | vga_320×200_image_movsb_backward1.asm | blokový přenos překrývajících se bloků paměti (snižující se adresy, nekorektní nastavení) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_image_movsb_backward1.asm |
127 | vga_320×200_image_movsb_backward2.asm | blokový přenos překrývajících se bloků paměti (snižující se adresy, korektní nastavení) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_image_movsb_backward2.asm |
128 | sound_bell.asm | přehrání zvuku pomocí tisku ASCII znaku BELL | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_bell.asm |
129 | sound_beep.asm | přehrání zvuku o zadané frekvenci na PC Speakeru | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_beep.asm |
130 | sound_play_pitch.asm | přehrání zvuku o zadané frekvenci na PC Speakeru, použití maker | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_play_pitch.asm |
131 | sound_opl2_basic.asm | přehrání komorního A na OPL2 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl2_basic.asm |
132 | sound_opl2_table.asm | přehrání komorního A na OPL2, použití tabulky s hodnotami registrů | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl2_table.asm |
133 | sound_opl2_table2.asm | přepis tabulky s obsahy registrů pro přehrání komorního A | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl2_table2.asm |
134 | sound_key_on.asm | přímé ovládání bitu KEY ON mezerníkem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_key_on.asm |
135 | sound_adsr.asm | nastavení obálky pro tón přehrávaný prvním kanálem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_adsr.asm |
136 | sound_modulation.asm | řízení frekvence modulátoru klávesami 1 a 0 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_modulation.asm |
137 | keyboard_basic.asm | přímá práce s klávesnicí IBM PC | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/keyboard_basic.asm |
138 | sound_stereo_opl2.asm | stereo zvuk v konfiguraci DualOPL2 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_stereo_opl2.asm |
139 | sound_opl2_multichannel.asm | vícekanálový zvuk na OPL2 (klávesy), delší varianta | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl2_multichannel.asm |
140 | sound_opl2_multichannel2.asm | vícekanálový zvuk na OPL2 (klávesy), kratší varianta | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl2_multichannel2.asm |
141 | sound_opl3_stereo1.asm | stereo výstup na OPL3 (v kompatibilním režimu) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl3_stereo1.asm |
142 | sound_opl3_stereo2.asm | stereo výstup na OPL3 (v režimu OPL3) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl3_stereo2.asm |
143 | sound_opl3_multichannel.asm | vícekanálový zvuk na OPL3 (klávesy) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl3_multichannel.asm |
144 | sound_opl3_waveform1.asm | interaktivní modifikace tvaru vlny u prvního operátoru | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl3_waveform1.asm |
145 | sound_opl3_waveform2.asm | oprava chyby: povolení režimu kompatibilního s OPL3 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl3_waveform2.asm |
146 | sound_opl3_waveform3.asm | vliv tvaru vln na zvukový kanál s FM syntézou | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl3_waveform3.asm |
147 | sound_opl3_waveform4.asm | modifikace tvaru vlny nosné vlny i modulátoru | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl3_waveform4.asm |
148 | sound_opl3_4operators1.asm | výběr AM/FM režimu ve čtyřoperátorovém nastavení | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl3_4operators1.asm |
149 | sound_opl3_4operators2.asm | výběr AM/FM režimu ve čtyřoperátorovém nastavení | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl3_4operators2.asm |
150 | timer_basic.asm | základní obsluha přerušení od časovače/čítače | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/timer_basic.asm |
151 | timer_restore.asm | obnovení původní obsluhy přerušení při ukončování aplikace | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/timer_restore.asm |
152 | timer_restore_better_structure.asm | refaktoring předchozího demonstračního příkladu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/timer_restore_better_structure.asm |
153 | timer_faster_clock.asm | zrychlení čítače na 100 přerušení za sekundu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/timer_faster_clock.asm |
154 | instruction_push_imm.asm | instrukce PUSH s konstantou | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_push_imm.asm |
155 | instruction_imul_imm.asm | instrukce IMUL s konstantou | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_imul_imm.asm |
156 | instruction_into1.asm | instrukce INTO s obsluhou přerušení | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_into1.asm |
157 | instruction_into2.asm | instrukce INTO s obsluhou přerušení | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_into2.asm |
158 | instruction_bound1.asm | instrukce BOUND s obsluhou přerušení (nekorektní řešení) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_bound1.asm |
159 | instruction_bound2.asm | instrukce BOUND s obsluhou přerušení (korektní řešení) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_bound2.asm |
160 | vga_320×200_putpixel286.asm | instrukce bitového posunu s konstantou větší než 1 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_putpixel286.asm |
161 | instruction_push_pop.asm | instrukce PUSH a POP se všemi pracovními registry | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_push_pop.asm |
162 | instruction_push_pop_B.asm | instrukce s novými segmentovými registry | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_push_pop_B.asm |
163 | instruction_near_jz_jmp.asm | blízké skoky | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_near_jz_jmp.asm |
164 | instruction_bsf.asm | nová instrukce BSF | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_bsf.asm |
165 | instruction_bsr.asm | nová instrukce BSR | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_bsr.asm |
166 | instruction_add_32bit.asm | 32bitový součet | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_add_32bit.asm |
167 | instruction_inc_32bit.asm | 32bitová instrukce INC v šestnáctibitovém režimu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_inc_32bit.asm |
168 | instruction_inc_32bit_B.asm | 32bitová instrukce INC v 32bitovém režimu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_inc_32bit_B.asm |
169 | ems_status.asm | zjištění stavu (emulace) paměti EMS | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ems_status.asm |
170 | ems_total_mem.asm | získání celkové kapacity paměti EMS v blocích | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ems_total_mem.asm |
171 | ems_free_mem.asm | získání volné kapacity paměti EMS v blocích | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ems_free_mem.asm |
172 | xms_free_mem.asm | získání volné kapacity paměti XMS v blocích | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/xms_free_mem.asm |
173 | vga_320×200_short_address1.asm | blokový přenos provedený v rámci prostoru segmentu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_short_address1.asm |
174 | vga_320×200_short_address2.asm | rozepsaný blokový přenos provedený v rámci prostoru segmentu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_short_address2.asm |
175 | vga_320×200_short_address3.asm | přenos nelze provést přes hranici offsetu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_short_address3.asm |
176 | vga_320×200_short_address4.asm | přenos nelze provést přes hranici offsetu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_short_address4.asm |
177 | vga_320×200_long_address1.asm | 32bitový blokový přenos | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_long_address1.asm |
178 | vga_320×200_long_address2.asm | rozepsaný 32bitový blokový přenos provedený v rámci prostoru segmentu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_long_address2.asm |
179 | vga_320×200_long_address3.asm | přístup do obrazové paměti přes segment 0×0000 a 32bitový offset | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_long_address3.asm |
180 | vga_320×200_long_address4.asm | otestování, jak lze přenášet data s využitím 32bitového offsetu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_long_address4.asm |
181 | print_msw.asm | přečtení a zobrazení obsahu speciálního registru MSW | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/print_msw.asm |
182 | print_cr0.asm | přečtení a zobrazení obsahu speciálního registru CR0 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/print_cr0.asm |
183 | prot_mode286.asm | přechod do chráněného režimu na čipech Intel 80286 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/prot_mode286.asm |
184 | prot_mode386.asm | přechod do chráněného režimu na čipech Intel 80386 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/prot_mode386.asm |
185 | prot_mode_back_to_real_mode286.asm | přechod mezi reálným režimem a chráněným režimem i zpět na čipech Intel 80286 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/prot_mode_back_to_real_mode286.asm |
186 | prot_mode_back_to_real_mode386.asm | přechod mezi reálným režimem a chráněným režimem i zpět na čipech Intel 80386 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/prot_mode_back_to_real_mode386.asm |
187 | prot_mode_check.asm | test, zda se mikroprocesor již nachází v chráněném režimu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/prot_mode_check.asm |
188 | unreal_mode.asm | nastavení nereálného režimu (platné pro Intel 80386) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/unreal_mode.asm |
189 | float32_constants.asm | vytištění základních FP konstant typu single | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/float32_constants.asm |
190 | float64_constants.asm | vytištění základních FP konstant typu double | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/float64_constants.asm |
191 | fpu_arithmetic.asm | základní aritmetické operace prováděné matematickým koprocesorem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fpu_arithmetic.asm |
192 | fpu_divide_by_zero.asm | dělení nulou matematickým koprocesorem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fpu_divide_by_zero.asm |
193 | fpu_divide_by_neg_zero.asm | dělení záporné hodnoty nulou matematickým koprocesorem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fpu_divide_by_neg_zero.asm |
194 | fpu_divide_by_neg_zero2.asm | dělení hodnoty zápornou nulou matematickým koprocesorem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fpu_divide_by_neg_zero2.asm |
195 | fpu_divide_zero_by_zero.asm | výpočet 0/0 matematickým koprocesorem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fpu_divide_zero_by_zero.asm |
196 | io.asm | pomocná makra pro komunikaci s DOSem a BIOSem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/io.asm |
197 | print.asm | pomocná makra pro tisk FPU hodnot typu single a double v hexadecimálním tvaru | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/print.asm |
198 | fpu_divide.asm | operace podílu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fpu_divide.asm |
199 | fpu_divide_r.asm | operace podílu s prohozenými operandy | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fpu_divide_r.asm |
200 | fpu_sqrt.asm | výpočet druhé odmocniny | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fpu_sqrt.asm |
201 | fpu_sqrt_neg_value.asm | výpočet druhé odmocniny ze záporné hodnoty | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fpu_sqrt_neg_value.asm |
202 | fpu_check.asm | detekce typu matematického koprocesoru | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fpu_check.asm |
203 | fpu_compare.asm | porovnání dvou hodnot s vyhodnocením výsledku | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fpu_compare.asm |
204 | fpu_status_word.asm | tisk obsahu stavového slova koprocesoru | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fpu_status_word.asm |
205 | fpu_status_word_stack.asm | tisk obsahu stavového slova koprocesoru | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fpu_status_word_stack.asm |
206 | svga_info1.asm | zjištění, zda je VBE dostupný | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/svga_info1.asm |
207 | svga_info2.asm | zobrazení základních informací o grafické kartě | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/svga_info2.asm |
208 | svga_info3.asm | výpis OEM řetězce s další informací o kartě | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/svga_info3.asm |
209 | svga_info4.asm | zjištění a výpis čísel všech podporovaných grafických režimů | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/svga_info4.asm |
210 | svga_info5.asm | získání rozlišení, bitové hloubky a struktury obrazových řádků zvoleného grafického režimu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/svga_info5.asm |
211 | svga_info6.asm | základní informace o čtecích a zápisových oknech pro reálný režim | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/svga_info6.asm |
212 | svga_info7.asm | informace o oknech podporovaných grafickým režimem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/svga_info7.asm |
213 | svga_mode0.asm | přepnutí do zvoleného grafického režimu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/svga_mode0.asm |
214 | svga_mode1.asm | vyplnění jediného okna barvami | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/svga_mode1.asm |
215 | svga_mode2.asm | vyplnění čtyř banků barvami | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/svga_mode2.asm |
216 | svga_mode3.asm | otestování, jakým způsobem jsou uloženy pixely v režimu s bitovou hloubkou 24/32 bitů | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/svga_mode3.asm |
217 | svga_pixel_formats1.asm | zjištění formátu uložení pixelů v grafickém režimu s bitovou hloubkou 15 bitů | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/svga_pixel_formats1.asm |
218 | svga_pixel_formats2.asm | zjištění formátu uložení pixelů v grafickém režimu s bitovou hloubkou 16 bitů | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/svga_pixel_formats2.asm |
219 | svga_pixel_formats3.asm | zjištění formátu uložení pixelů v grafickém režimu s bitovou hloubkou 24 nebo 32 bitů | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/svga_pixel_formats3.asm |
220 | svga_palette.asm | nastavení barvové palety v režimu s 256 barvami | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/svga_palette.asm |
221 | svga_640×480_image1.asm | vykreslení rastrového obrázku bez modifikace offsetů na řádcích | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/svga_640×480_image1.asm |
222 | svga_640×480_image2.asm | vykreslení rastrového obrázku s modifikací offsetů na řádcích | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/svga_640×480_image2.asm |
223 | svga_640×480_image3.asm | první realizace subrutiny typu BitBLT | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/svga_640×480_image3.asm |
224 | svga_640×480_image4.asm | vykreslení všech 200 řádků rastrového obrázku | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/svga_640×480_image4.asm |
225 | svga_640×480_image5.asm | vycentrování rastrového obrázku | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/svga_640×480_image5.asm |
226 | svga_640×480_image6.asm | změna počtu pixelů na obrazovém řádku | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/svga_640×480_image6.asm |
227 | svga_text_mode1.asm | nastavení rozšířeného textového režimu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/svga_text_mode1.asm |
228 | svga_text_mode2.asm | přímý přístup do paměti rozšířeného textového režimu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/svga_text_mode2.asm |
229 | svga_text_mode3.asm | nastavení odlišného rozšířeného textového režimu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/svga_text_mode3.asm |
230 | svga_text_mode4.asm | změna tvaru kurzoru v rozšířeném textovém režimu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/svga_text_mode4.asm |
231 | svga_text_mode_info.asm | získání základních informací o textovém režimu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/svga_text_mode_info.asm |
232 | svga_text_modes.asm | tisk všech dostupných textových režimů karet SVGA | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/svga_text_modes.asm |
233 | fx_add1.asm | operace součtu ve formátu s pevnou řádovou tečkou | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fx_add1.asm |
234 | fx_add2.asm | operace součtu ve formátu s pevnou řádovou tečkou, realizace makrem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fx_add2.asm |
235 | fx_mul1.asm | naivní (nekorektní) implementace součinu ve formátu s pevnou řádovou tečkou | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fx_mul1.asm |
236 | fx_mul2.asm | korektní implementace součinu ve formátu s pevnou řádovou tečkou, úprava výsledku | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fx_mul2.asm |
237 | fx_mul3.asm | korektní implementace součinu ve formátu s pevnou řádovou tečkou, úprava operandů | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fx_mul3.asm |
238 | fx.c | implementace základních operací ve formátu s pevnou řádovou tečkou v jazyku C | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fx.c |
239 | fx_O0.asm | překlad příkladu fx.c s vypnutím optimalizací | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fx_O0.asm |
240 | fx_O9.asm | překlad příkladu fx.c se zapnutím optimalizací na výkon | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fx_O9.asm |
241 | fx_Os.asm | překlad příkladu fx.c se zapnutím optimalizací na velikost kódu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fx_Os.asm |
242 | fx_mandel1.asm | výpočet Mandelbrotovy množiny; základní varianta | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fx_mandel1.asm |
243 | fx_mandel2.asm | výpočet Mandelbrotovy množiny; optimalizovaná varianta | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fx_mandel2.asm |
244 | fx_mandel3.asm | výpočet Mandelbrotovy množiny; šestnáctibitová varianta | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fx_mandel3.asm |
245 | fx_julia.asm | výpočet animace Juliovy množiny | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fx_julia.asm |
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 - Why did line printers have 132 columns?
https://retrocomputing.stackexchange.com/questions/7838/why-did-line-printers-have-132-columns - Tabulating machine
https://en.wikipedia.org/wiki/Tabulating_machine - Why do printers print 132 columns on 14 7/8″ paper? It’s history
https://blog.adafruit.com/2019/01/22/why-do-printers-print-132-columns-on-14–7–8-paper-its-history-vintagecomputing-kenshirriff-ibm/ - IBM 1403 (Wikipedia)
https://en.wikipedia.org/wiki/IBM_1403