Obsah
1. Algoritmus CORDIC a numerické formáty s pevnou řádovou čárkou
2. Výpočet délky vektoru pomocí algoritmu CORDIC
3. První demonstrační příklad: výpočet délky vektoru
4. Výpočet logaritmu algoritmem CORDIC
5. Druhý demonstrační příklad: výpočet přirozeného logaritmu
6. Výsledky získané předchozím příkladem
7. Algoritmus CORDIC s hodnotami uloženými ve formátu pevné řádové binární čárky
8. Realizace funkce určené pro naplnění tabulky atans[] (arkustangenty vhodně zvolených úhlů)
9. Výpočet goniometrické funkce tan s využitím algoritmu CORDIC: neoptimalizovaná varianta výpočtu
10. Celý demonstrační příklad: výpočet funkce tan s využitím algoritmu CORDIC
11. Výsledky výpočtu funkce tan: absolutní a relativní chyby
12. Výpočet goniometrické funkce tan s využitím algoritmu CORDIC – optimalizovaná varianta výpočtů
13. Celý demonstrační příklad: výpočet funkce tan s využitím algoritmu CORDIC
14. Výsledky výpočtu funkce tan: absolutní a relativní chyby
15. Způsob překladu algoritmu CORDIC do assembleru
16. Výpočet goniometrické funkce sin
17. Výsledky výpočtu funkce sin: absolutní a relativní chyby, statistiky
18. Repositář s demonstračními příklady
1. Algoritmus CORDIC a numerické formáty s pevnou řádovou čárkou
V předchozích článcích jsme si uvedli, jakým způsobem je možné algoritmus CORDIC (COordinate ROtation DIgital Computer) použít pro výpočet goniometrických funkcí s hodnotami uloženými ve formátu plovoucí řádové binární čárky (FP). Tentýž algoritmus je však po mírné modifikaci možné použít i při práci s formátem pevné řádové binární čárky (FX) a dá se říci, že teprve zde se plně ukazuje jeho implementační jednoduchost a současně i velká vyjadřovací síla – pomocí jednoho iteračního postupu je možné vypočítat poměrně velké množství navzájem značně odlišných funkcí, přičemž paměťové nároky algoritmu jsou minimální a rovnají se tabulce s cca deseti až dvaceti prvky s rozsahem 32 (popř. pouze 16) bitů. To je výhodné především při implementaci na mikrořadičích (oblíbená řada 8051, PICy, řada 68HC11 atd.) a také při práci s programovatelnými obvody typu FPGA.
Dnes se budeme zabývat právě tímto problémem. Nejdříve si však v kapitolách 2–6 ukážeme, jak lze CORDIC po úpravách použít i pro další (sofistikovanější) výpočty, například pro výpočet délky vektoru, výpočet hyperbolických funkcí, ale i pro výpočet logaritmů.
2. Výpočet délky vektoru pomocí algoritmu CORDIC
Délka vektoru (pro jednoduchost zůstaneme v rovině) se kupodivu počítá naprosto stejným způsobem, jako funkce arkustangenty. Je tomu tak z toho důvodu, že se arkustangenta iterativně vypočítá pootočením vstupního vektoru do polohy, ve které má y-ovou souřadnici nulovou. To však logicky znamená, že jeho x-ová souřadnice odpovídá délce vektoru, protože platí:
d=sqrt(x2+y2)=sqrt(x2+0)=sqrt(x2)=x
To tedy znamená, že se minule uvedená funkce pro výpočet arkustangenty je po malých úpravách použitelná i pro výpočet délky vektoru. Postačuje ji jen upravit tak, že se výsledná hodnota xi (vzniklá po i iteracích) vynásobí konstantou Ki stejným způsobem, jaký jsme prováděli u výpočtů funkcí sin() a cos() v předchozím pokračování tohoto seriálu.
Vlastnosti algoritmu CORDIC, díky které je možné jednoduše spočítat délku vektoru, není (resp. přesněji řečeno nebyla) široce známa, proto některé FPU pro tuto činnost ani neobsahují instrukci, což je škoda, zejména při práci s grafikou, kde se délky velmi často počítají a je pro ně nutné použít dvojici násobení, jedno sečítání a k tomu ještě druhou odmocninu, tj. poměrně zdlouhavé a složité operace.
3. První demonstrační příklad: výpočet délky vektoru
Po překladu a spuštění dnešního prvního demonstračního příkladu se zobrazí tabulka s délkami vektorů, jejichž souřadnice postupně nabývají hodnot od nuly do desíti (včetně):
// -------------------------------------------------------- // Výpočet délky vektoru pomocí iteračního algoritmu // CORDIC. // -------------------------------------------------------- #include <math.h> #include <stdio.h> #ifndef M_PI #define M_PI 3.14159265358979323846 #endif // maximální počet iterací při běhu algoritmu #define MAX_ITER 20 // "zesílení" při rotacích #define K 0.6073 // tabulka arkustangentu úhlů double atans[MAX_ITER]; // tabulka záporných celočíselných mocnin hodnoty 2 double pows[MAX_ITER]; // naplnění tabulek atans[] a pows[] void createTables(void) { int i; for (i = 0; i < MAX_ITER; i++) { double p = pow(2.0, -i); atans[i] = atan(p); pows[i] = p; } } // výpočet velikosti vektoru pomocí algoritmu CORDIC double mag_cordic(double y, double x) { int i; double x0 = x; // nastavení počátečních podmínek double y0 = y; double xn; double delta = 0.0; for (i = 0; i < MAX_ITER; i++) { // iterační smyčka if (y0 > 0) { // kladná polorovina => rotace doleva xn = x0 + y0 * pows[i]; y0 -= x0 * pows[i]; delta += atans[i]; } else { // záporná polorovina => rotace doprava xn = x0 - y0 * pows[i]; y0 += x0 * pows[i]; delta -= atans[i]; } x0 = xn; } return x0 * K; // délka vektoru } int main(void) { double x, y; createTables(); printf("%f\n", mag_cordic(3, 4)); // výpočet Pythagorova trojúhelníka for (y=0.0; y<=10.0; y+=1.0) { // tabulka velikostí různých vektorů for (x=0.0; x<=10.0; x+=1.0) { printf("%5.2f ", mag_cordic(x,y)); } putchar('\n'); } return 0; } // finito
Povšimněte si, že přesnost výpočtů je poměrně velká, například pro vektor (6,8) je prakticky přesně vypočtena délka 10:
d(x,y) | 0,00 | 1,00 | 2,00 | 3,00 | 4,00 | 5,00 | 6,00 | 7,00 | 8,00 | 9,00 | 10,00 |
---|---|---|---|---|---|---|---|---|---|---|---|
0,00 | 0,00 | 1,00 | 2,00 | 3,00 | 4,00 | 5,00 | 6,00 | 7,00 | 8,00 | 9,00 | 10,00 |
1,00 | 1,00 | 1,41 | 2,24 | 3,16 | 4,12 | 5,10 | 6,08 | 7,07 | 8,06 | 9,06 | 10,05 |
2,00 | 2,00 | 2,24 | 2,83 | 3,61 | 4,47 | 5,39 | 6,33 | 7,28 | 8,25 | 9,22 | 10,20 |
3,00 | 3,00 | 3,16 | 3,61 | 4,24 | 5,00 | 5,83 | 6,71 | 7,62 | 8,54 | 9,49 | 10,44 |
4,00 | 4,00 | 4,12 | 4,47 | 5,00 | 5,66 | 6,40 | 7,21 | 8,06 | 8,94 | 9,85 | 10,77 |
5,00 | 5,00 | 5,10 | 5,39 | 5,83 | 6,40 | 7,07 | 7,81 | 8,60 | 9,43 | 10,30 | 11,18 |
6,00 | 6,00 | 6,08 | 6,33 | 6,71 | 7,21 | 7,81 | 8,49 | 9,22 | 10,00 | 10,82 | 11,66 |
7,00 | 7,00 | 7,07 | 7,28 | 7,62 | 8,06 | 8,60 | 9,22 | 9,90 | 10,63 | 11,40 | 12,21 |
8,00 | 8,00 | 8,06 | 8,25 | 8,54 | 8,94 | 9,43 | 10,00 | 10,63 | 11,31 | 12,04 | 12,81 |
9,00 | 9,00 | 9,06 | 9,22 | 9,49 | 9,85 | 10,30 | 10,82 | 11,40 | 12,04 | 12,73 | 13,45 |
10,00 | 10,00 | 10,05 | 10,20 | 10,44 | 10,77 | 11,18 | 11,66 | 12,21 | 12,81 | 13,45 | 14,14 |
4. Výpočet logaritmu algoritmem CORDIC
Algoritmus CORDIC ve své prapůvodní podobě pracoval na principu rotace vektoru v běžném L2 prostoru. Díky tomu bylo možné počítat goniometrické funkce, délky vektorů atd. Ovšem například výpočty hyperbolických funkcí nebo logaritmů vyžadují více či méně podstatné úpravy algoritmu, které spočívají v tom, že se (snadno pochopitelné) rotace nahradí odlišnými operacemi. Ovšem princip činnosti CORDICu zůstává stále stejný – máme k dispozici předpočítanou tabulku hodnot (původně úhlů) vypočtenou tak, aby jeden sloupec obsahoval mocniny dvou nebo podobné velmi snadno spočitatelné hodnoty. A snažíme se vektorem postupně „otočit“ tak, aby jedna z jeho složek byla nulová. Ze druhé složky je poté odvozena výsledná hodnota.
Pro zajímavost se podívejme na způsob výpočtu hodnoty přirozeného logaritmu (se základem e), opět s využitím upraveného algoritmu CORDIC. Sice se jedná o výpočet odlišný od (například) výpočtu goniometrických funkcí, ovšem původní myšlenka s postupnými rotacemi zůstává zachována (dokonce i včetně úpravy výsledné hodnoty vynásobením konstantou log(2)):
// výpočet logaritmu algoritmem CORDIC double log_cordic(double a) { const double three_eigth = 0.375; int sk, expo; double sum = tabm[0]; double x = 2.0 * frexpf (a, &expo); double ex2 = 1.0; // dvojková mocnina int k; for (k = 0; k < MAXITER; k++) { sk = 0; // zjistit směr rotace if ((x - 1.0) < (-three_eigth * ex2)) { sk = +1; } if ((x - 1.0) >= (+three_eigth * ex2)) { sk = -1; } ex2 /= 2.0; if (sk == 1) { // přímá rotace x = x + x * ex2; sum = sum - tabp [k]; } if (sk == -1) { // opačná rotace x = x - x * ex2; sum = sum - tabm [k]; } } return expo * K + sum; // přepočet logaritmu }
Povšimněte si, že tento výpočet závisí na dvojici tabulek tabm a tabp. Jejich obsah je možné vypočítat buď při inicializaci programu, nebo může program obsahovat již předpočtené hodnoty (viz například Problems with CORDIC for Logarithm in C):
// ln(1+2*(-i)) double tabp[MAXITER] = { 0.40546510810816, 0.22314355131421, 0.11778303565638, 0.06062462181643, 0.03077165866675, 0.01550418653597, 0.00778214044205, 0.00389864041566, 0.00195122013126, 0.00097608597306, }; // ln(1-2*(-i)) double tabm[MAXITER] = { -0.69314718055995, -0.28768207245178, -0.13353139262452, -0.06453852113757, -0.03174869831458, -0.01574835696814, -0.00784317746103, -0.00391389932114, -0.00195503483580, -0.00097703964783, };
5. Druhý demonstrační příklad: výpočet přirozeného logaritmu
Úplný zdrojový kód dnešního druhého demonstračního příkladu vypadá následovně:
// -------------------------------------------------------- // Výpočet hodnot funkce log() pomocí iteračního // algoritmu CORDIC. // -------------------------------------------------------- #include <math.h> #include <stdio.h> #include <stdlib.h> // maximální počet iterací při běhu algoritmu #define MAXITER 10 // "zesílení" při rotacích (odpovídá ln(2)) #define K 0.69314718056 // ln(1+2*(-i)) double tabp[MAXITER] = { 0.40546510810816, 0.22314355131421, 0.11778303565638, 0.06062462181643, 0.03077165866675, 0.01550418653597, 0.00778214044205, 0.00389864041566, 0.00195122013126, 0.00097608597306, }; // ln(1-2*(-i)) double tabm[MAXITER] = { -0.69314718055995, -0.28768207245178, -0.13353139262452, -0.06453852113757, -0.03174869831458, -0.01574835696814, -0.00784317746103, -0.00391389932114, -0.00195503483580, -0.00097703964783, }; // výpočet logaritmu algoritmem CORDIC double log_cordic(double a) { const double three_eigth = 0.375; int sk, expo; double sum = tabm[0]; double x = 2.0 * frexpf (a, &expo); double ex2 = 1.0; // dvojková mocnina int k; for (k = 0; k < MAXITER; k++) { sk = 0; // zjistit směr rotace if ((x - 1.0) < (-three_eigth * ex2)) { sk = +1; } if ((x - 1.0) >= (+three_eigth * ex2)) { sk = -1; } ex2 /= 2.0; if (sk == 1) { // přímá rotace x = x + x * ex2; sum = sum - tabp [k]; } if (sk == -1) { // opačná rotace x = x - x * ex2; sum = sum - tabm [k]; } } return expo * K + sum; // přepočet logaritmu } int main(void) { double a = M_E - 2.0; // "pěkná" počáteční hodnota for (; a<=2.0*M_E; a+=0.1) { double log_value = log_cordic(a); double log_correct = log(a); double log_error = fabs(log_correct - log_value); // tisk výsledků printf("%5.3f\t%12.10f\t%12.10f\t%8.3f%%\n", a, log_value, log_error, (log_value != 0.0) ? 100.0 * log_error / fabs(log_value) : 0.0); } return 0; } // finito
6. Výsledky získané předchozím příkladem
Po spuštění demonstračního příkladu uvedeného v předchozí kapitole získáme tabulku se vstupními hodnotami x (v rozsahu od e-2 do 2e), vypočtené přirozené logaritmy vstupních hodnot, absolutní chybu i chybu relativní:
x | log(x) | absolutní chyba | relativní chyba |
---|---|---|---|
0.718 | –0.3311283747 | 0.0002351065 | 0.071% |
0.818 | –0.2007169448 | 0.0001684767 | 0.084% |
0.918 | –0.0855043232 | 0.0002533904 | 0.296% |
1.018 | 0.0177033937 | 0.0004133313 | 2.335% |
1.118 | 0.1122001024 | 0.0004066767 | 0.362% |
1.218 | 0.1972628335 | 0.0001786953 | 0.091% |
1.318 | 0.2760012935 | 0.0003279501 | 0.119% |
1.418 | 0.3492932894 | 0.0001528696 | 0.044% |
1.518 | 0.4172221868 | 0.0003571327 | 0.086% |
1.618 | 0.4817607079 | 0.0003957212 | 0.082% |
1.718 | 0.5406938477 | 0.0006310069 | 0.117% |
1.818 | 0.5978522616 | 0.0000397433 | 0.007% |
1.918 | 0.6516717826 | 0.0002418782 | 0.037% |
2.018 | 0.7019674015 | 0.0002791680 | 0.040% |
2.118 | 0.7499035651 | 0.0007017367 | 0.094% |
2.218 | 0.7968839580 | 0.0001510129 | 0.019% |
2.318 | 0.8404757138 | 0.0003506063 | 0.042% |
2.418 | 0.8826278755 | 0.0004294242 | 0.049% |
2.518 | 0.9241185343 | 0.0005416794 | 0.059% |
2.618 | 0.9623977642 | 0.0001205478 | 0.013% |
2.718 | 1.0004915131 | 0.0004915131 | 0.049% |
2.818 | 1.0366095515 | 0.0004821330 | 0.047% |
2.918 | 1.0707784472 | 0.0002165810 | 0.020% |
3.018 | 1.1044812266 | 0.0002065119 | 0.019% |
3.118 | 1.1372700939 | 0.0000120602 | 0.001% |
3.218 | 1.1690197478 | 0.0001721243 | 0.015% |
3.318 | 1.2001045670 | 0.0006574396 | 0.055% |
3.418 | 1.2289814442 | 0.0001565913 | 0.013% |
3.518 | 1.2578018827 | 0.0001708708 | 0.014% |
3.618 | 1.2862147211 | 0.0002154409 | 0.017% |
3.718 | 1.3131033699 | 0.0001583176 | 0.012% |
3.818 | 1.3400185197 | 0.0002179814 | 0.016% |
3.918 | 1.3659154520 | 0.0002622034 | 0.019% |
4.018 | 1.3902082662 | 0.0006461393 | 0.046% |
4.118 | 1.4160918450 | 0.0006558006 | 0.046% |
4.218 | 1.4391521071 | 0.0002757884 | 0.019% |
4.318 | 1.4626826045 | 0.0001749937 | 0.012% |
4.418 | 1.4851554604 | 0.0005954335 | 0.040% |
4.518 | 1.5081449786 | 0.0000131835 | 0.001% |
4.618 | 1.5296239718 | 0.0003987656 | 0.026% |
4.718 | 1.5515744578 | 0.0001297438 | 0.008% |
4.818 | 1.5719417606 | 0.0004756368 | 0.030% |
4.918 | 1.5929729045 | 0.0000136569 | 0.001% |
5.018 | 1.6133518175 | 0.0002642076 | 0.016% |
5.118 | 1.6334714200 | 0.0006526177 | 0.040% |
5.218 | 1.6526451471 | 0.0004769511 | 0.029% |
5.318 | 1.6710491332 | 0.0001011534 | 0.006% |
5.418 | 1.6897247963 | 0.0000539631 | 0.003% |
7. Algoritmus CORDIC s hodnotami uloženými ve formátu pevné řádové binární čárky
Hlavním tématem dnešního článku je přepis algoritmu CORDIC do podoby, ve které se již nepoužije matematický koprocesor (a tedy ani datové typy float či double), ale výpočty budou probíhat na běžné celočíselné aritmeticko-logické jednotce.
Před vlastním uvedením implementace algoritmu CORDIC s čísly uloženými ve formátu pevné řádové binární čárky je zapotřebí provést náležitou přípravu, protože formát FX (většinou) není ani mikroprocesory ani překladači podporován. Z tohoto důvodu si v této kapitole pro připomenutí uvedeme všechny základní aritmetické funkce určené pro práci s formátem FX. Jedná se o funkce fx_add(), fx_sub(), fx_mul() a fx_div() (tyto funkce byly podrobněji vysvětleny v předchozím díle). Kromě toho jsou uvedena i těla dalších pomocných funkcí, zejména fx_print() i maker určených pro převod stupňů na radiány a naopak. Pomocí konstant A a B je určen rozsah a přesnost numerických hodnot uložených ve formátu fx – ten je v naší implementaci shodný s třicetidvoubitovým datovým typem signed int, jelikož potřebujeme pracovat jak s kladnými, tak i se zápornými hodnotami.
#include <stdlib.h> #include <stdio.h> #include <math.h> /* počet míst před a za binární řádovou tečkou */ #define A 16 #define B 16 /* Ludolfovo číslo */ #ifndef M_PI #define M_PI 3.14159265358979323846 #endif /* maximální počet iterací při běhu algoritmu */ #define MAX_ITER 16 /* "zesílení" při rotacích */ #define K 0.6073 /* převody mezi stupni a radiány */ #define rad2deg(rad) ((rad)*180.0/M_PI) #define deg2rad(deg) ((deg)/180.0*M_PI) /* datový typ, se kterým budeme pracovat */ typedef signed int fx; /* hlavičky použitých funkcí */ void fx_print(fx x); fx fp2fx(double x); double fx2fp(fx x); /* tabulka arkustangentu úhlů */ fx atans[MAX_ITER]; /* tabulka záporných celočíselných mocnin hodnoty 2 */ fx pows[MAX_ITER]; /* * Tisk numerické hodnoty uložené ve formátu pevné * řádové binární čárky (FX) */ void fx_print(fx x) { int i; int val=x; /* pomocná proměnná pro převod do dvojkové soustavy */ printf("bin: "); for (i=0; i<A+B; i++) { /* převod na řetězec bitů (do dvojkové soustavy) */ putchar(!!(val & (1<<(A+B-1)))+'0'); /* výpis hodnoty aktuálně nejvyššího bitu */ if (i==B-1) putchar('.'); /* po řádové binární čárce vypsat značku */ val=val<<1; /* posun na další (méně významný) bit */ } printf(" hex: %08x fp: %+11.5f\n", x, fx2fp(x)); } /* * Převod z formátu plovoucí řádové binární čárky (FP) * do formátu pevné řádové binární čárky (FX) */ fx fp2fx(double x) { return (fx)(x*(2<<(B-1))); } /* * Převod z celočíselného formátu (integer) * do formátu pevné řádové binární čárky (FX) */ fx int2fx(int x) { return (fx)(x<<B); } /* * Převod z formátu pevné řádové binární čárky (FX) * do formátu plovoucí řádové binární čárky (FP) */ double fx2fp(fx x) { return (double)x/(2<<(B-1)); } /* * Součet dvou hodnot uložených ve shodném formátu * pevné binární řádové čárky (FX) */ fx fx_add(fx x, fx y) { return x+y; } /* * Rozdíl dvou hodnot uložených ve shodném formátu * pevné binární řádové čárky (FX) */ fx fx_sub(fx x, fx y) { return x-y; } /* * Součin dvou hodnot uložených ve shodném formátu * pevné binární řádové čárky (FX) */ fx fx_mul(fx x, fx y) { fx result=(x>>(B/2))*(y>>(B/2)); return result; } /* * Podíl dvou hodnot uložených ve shodném formátu * pevné binární řádové čárky (FX) */ fx fx_div(fx x, fx y) { fx result=x/(y>>(B/2)); return result<<(B/2); }
8. Realizace funkce určené pro naplnění tabulky atans[] (arkustangenty vhodně zvolených úhlů)
Podobně jako při implementaci algoritmu CORDIC pro hodnoty ve formátu FP (tedy s plovoucí řádovou čárkou), i v případě práce s formátem FX je nutné některé hodnoty předpočítat. Opět se jedná o tabulku atans[] obsahující arkustangenty vybraných úhlů. Kromě toho naplníme i tabulku pows[], ve které jsou uloženy záporné mocniny čísla 2. Jak však uvidíme v dalším textu, není v případě FX výpočtů tato tabulka využita a algoritmus CORDIC se z tohoto důvodu poněkud zjednoduší. Funkce pro výpočet obou zmiňovaných tabulek vypadá následovně:
/* * Vytvoření tabulky pro výpočet goniometrických * funkcí pomocí algoritmu CORDIC */ void fx_create_tables(void) { int i; for (i=0; i<MAX_ITER; i++) { double p=pow(2.0, -i); atans[i]=fp2fx(atan(p)); pows[i]=fp2fx(p); } }
To, zda je tabulka korektně naplněna, je možné otestovat velmi jednoduše:
/* kontrolní výpis tabulky atans[] */ for (i=0; i<MAX_ITER; i++) printf("%d\t%f\n", i, fx2fp(rad2deg(atans[i])));
Výsledkem běhu předchozího testu je tabulka hodnot arkustangent úhlů (zhruba) odpovídajících FP verzi:
Index | Hodnota úhlu |
---|---|
0 | 44.999252 |
1 | 26.564514 |
2 | 14.035431 |
3 | 7.124374 |
4 | 3.575729 |
5 | 1.789612 |
6 | 0.894363 |
7 | 0.446747 |
8 | 0.222931 |
9 | 0.111023 |
10 | 0.055069 |
11 | 0.027100 |
12 | 0.013107 |
13 | 0.006119 |
14 | 0.002609 |
15 | 0.000870 |
S takto připravenou tabulkou je možné pokračovat v dalších výpočtech.
9. Výpočet goniometrické funkce tan s využitím algoritmu CORDIC: neoptimalizovaná varianta výpočtu
Pravděpodobně nejjednodušším výpočtem, který je možné s využitím algoritmu CORDIC provést, je vyjádření tangenty zadaného úhlu. Nejprve si uvedeme neoptimalizovanou verzi, která vznikla v podstatě přímým převodem minule uvedené implementace určené pro FP reprezentaci (viz jedenáctou kapitolu). Převod spočívá v náhradě aritmetických funkcí za jejich ekvivalenty s pevnou řádovou tečkou:
/* výpočet funkce tan() pro zadaný úhel delta */ // (neoptimalizovaná verze) fx fx_tan_cordic(fx delta) { int i; /* nastavení počátečních podmínek */ fx x0=fp2fx(1.0); fx y0=fp2fx(0.0); fx xn; if (delta==0) return 0; /* ošetření nulového úhlu */ for (i=0; i<MAX_ITER; i++) { /* iterační smyčka */ if (delta<0) { /* úhel je záporný => rotace doleva */ xn=fx_add(x0, fx_mul(y0, pows[i])); y0=fx_sub(y0, fx_mul(x0, pows[i])); delta=fx_add(delta, atans[i]); } else { /* úhel je kladný => rotace doprava */ xn=fx_sub(x0, fx_mul(y0, pows[i])); y0=fx_add(y0, fx_mul(x0, pows[i])); delta=fx_sub(delta, atans[i]); } x0=xn; /* printf("%i\t%+f\t%+f\t%+f\n", i, fx2fp(x0), fx2fp(y0), fx2fp(delta)); */ } if (x0==0) /* ošetření tangenty pravého úhlu */ if (y0<0) return 0; else return 0; else return fx_div(y0,x0); /* vrátit výsledek operace */ }
Výše uvedenou funkci fx_tan_cordic si můžeme jednoduchým způsobem otestovat. Postačí použít programovou smyčku, ve které se počítají tangenty úhlů v rozsahu 0°..89° spolu s vyjádřením absolutních a relativních chyb vzniklých použitím algoritmu CORDIC a bitově omezené FP reprezentace:
/* výpis tabulky tangent úhlů v rozsahu 0..89° */ for (i=0; i<90; i++) { /* výpočetní smyčka */ delta=deg2rad(i); /* převod úhlu na radiány */ tanfx=fx_tan_cordic(fp2fx(delta)); /* aplikace algoritmu CORDIC */ tanval=fx2fp(tanfx); /* výpočet funkce tan */ tanerr=fabs(tanval-tan(delta)); /* výpočet absolutních chyb */ /* tisk výsledků */ printf("%02d\t%14.10f\t%14.10f\t%12.10f\t%8.3f%%\n", i, tanval, tan(delta), tanerr, tanerr==0 ? 0:100.0*tanerr/tan(delta)); }
10. Celý demonstrační příklad: výpočet funkce tan s využitím algoritmu CORDIC
#include <stdlib.h> #include <stdio.h> #include <math.h> /* počet míst před a za binární řádovou tečkou */ #define A 16 #define B 16 /* Ludolfovo číslo */ #ifndef M_PI #define M_PI 3.14159265358979323846 #endif /* maximální počet iterací při běhu algoritmu */ #define MAX_ITER 16 /* "zesílení" při rotacích */ #define K_float 0.6073 /* převody mezi stupni a radiány */ #define rad2deg(rad) ((rad) * 180.0 / M_PI) #define deg2rad(deg) ((deg) / 180.0 * M_PI) /* datový typ, se kterým budeme pracovat */ typedef signed int fx; /* hlavičky použitých funkcí */ void fx_print(fx x); fx fp2fx(double x); double fx2fp(fx x); /* tabulka arkustangentu úhlů */ fx atans[MAX_ITER]; /* tabulka záporných celočíselných mocnin hodnoty 2 */ fx pows[MAX_ITER]; /* * Tisk numerické hodnoty uložené ve formátu pevné * řádové binární čárky (FX) */ void fx_print(fx x) { int i; int val = x; /* pomocná proměnná pro převod do dvojkové soustavy */ printf("bin: "); for (i = 0; i < A + B; i++) { /* převod na řetězec bitů (do dvojkové soustavy) */ putchar(!!(val & (1 << (A + B - 1))) + '0'); /* výpis hodnoty aktuálně nejvyššího bitu */ if (i == B - 1) putchar('.'); /* po řádové binární čárce vypsat značku */ val = val << 1; /* posun na další (méně významný) bit */ } printf(" hex: %08x fp: %+11.5f\n", x, fx2fp(x)); } /* * Převod z formátu plovoucí řádové binární čárky (FP) * do formátu pevné řádové binární čárky (FX) */ fx fp2fx(double x) { return (fx) (x * (2 << (B - 1))); } /* * Převod z celočíselného formátu (integer) * do formátu pevné řádové binární čárky (FX) */ fx int2fx(int x) { return (fx) (x << B); } /* * Převod z formátu pevné řádové binární čárky (FX) * do formátu plovoucí řádové binární čárky (FP) */ double fx2fp(fx x) { return (double) x / (2 << (B - 1)); } /* * Součet dvou hodnot uložených ve shodném formátu * pevné binární řádové čárky (FX) */ fx fx_add(fx x, fx y) { return x + y; } /* * Rozdíl dvou hodnot uložených ve shodném formátu * pevné binární řádové čárky (FX) */ fx fx_sub(fx x, fx y) { return x - y; } /* * Součin dvou hodnot uložených ve shodném formátu * pevné binární řádové čárky (FX) */ fx fx_mul(fx x, fx y) { fx result = (x >> (B / 2)) * (y >> (B / 2)); return result; } /* * Podíl dvou hodnot uložených ve shodném formátu * pevné binární řádové čárky (FX) */ fx fx_div(fx x, fx y) { fx result = x / (y >> (B / 2)); return result << (B / 2); } /* * Vytvoření tabulky pro výpočet goniometrických * funkcí pomocí algoritmu CORDIC */ void fx_create_tables(void) { int i; for (i = 0; i < MAX_ITER; i++) { double p = pow(2.0, -i); atans[i] = fp2fx(atan(p)); pows[i] = fp2fx(p); } } /* výpočet funkce tan() pro zadaný úhel delta */ /* (neoptimalizovaná verze) */ fx fx_tan_cordic(fx delta) { int i; /* nastavení počátečních podmínek */ fx x0 = fp2fx(1.0); fx y0 = fp2fx(0.0); fx xn; if (delta == 0) return 0; /* ošetření nulového úhlu */ for (i = 0; i < MAX_ITER; i++) { /* iterační smyčka */ if (delta < 0) { /* úhel je záporný => rotace doleva */ xn = fx_add(x0, fx_mul(y0, pows[i])); y0 = fx_sub(y0, fx_mul(x0, pows[i])); delta = fx_add(delta, atans[i]); } else { /* úhel je kladný => rotace doprava */ xn = fx_sub(x0, fx_mul(y0, pows[i])); y0 = fx_add(y0, fx_mul(x0, pows[i])); delta = fx_sub(delta, atans[i]); } x0 = xn; /* printf("%i\t%+f\t%+f\t%+f\n", i, fx2fp(x0), fx2fp(y0), fx2fp(delta)); */ } if (x0 == 0) /* ošetření tangenty pravého úhlu */ if (y0 < 0) return 0; else return 0; else return fx_div(y0, x0); /* vrátit výsledek operace */ } int main(void) { int i; fx tanfx; double delta; /* úhel, ze kterého se funkce počítá */ double tan_value; /* absolutní chyby */ double tan_error; /* relativní chyby */ fx_create_tables(); /* výpis tabulky tangent úhlů v rozsahu 0..89° */ for (i=0; i<90; i++) { /* výpočetní smyčka */ delta=deg2rad(i); /* převod úhlu na radiány */ tanfx=fx_tan_cordic(fp2fx(delta)); /* aplikace algoritmu CORDIC */ tan_value=fx2fp(tanfx); /* výpočet funkce tan */ tan_error=fabs(tan_value-tan(delta)); /* výpočet absolutních chyb */ /* tisk výsledků */ printf("%02d\t%14.10f\t%14.10f\t%12.10f\t%8.3f%%\n", i, tan_value, tan(delta), tan_error, tan_error==0 ? 0:100.0*tan_error/tan(delta)); } return 0; } // finito
11. Výsledky výpočtu funkce tan: absolutní a relativní chyby
V tabulce s výsledky si všimněte, že pro některé úhly je vzniklá chyba rovna až deseti procentům. Je to způsobeno nízkým rozlišením použitého FX formátu, zejména hodnot arctan() těch nejmenších úhlů, a chybu již není možné snížit ani zvýšením počtu iterací (ten je nastaven na hodnotu šestnáct, to odpovídá počtu bitů za binární řádovou čárkou):
Úhel | tan podle CORDIC | tan podle FPU | absolutní chyba | relativní chyba |
---|---|---|---|---|
00 | 0.0000000000 | 0.0000000000 | 0.0000000000 | 0.000% |
01 | 0.0156250000 | 0.0174550649 | 0.0018300649 | 10.484% |
02 | 0.0312500000 | 0.0349207695 | 0.0036707695 | 10.512% |
03 | 0.0468750000 | 0.0524077793 | 0.0055327793 | 10.557% |
04 | 0.0703125000 | 0.0699268119 | 0.0003856881 | 0.552% |
05 | 0.0859375000 | 0.0874886635 | 0.0015511635 | 1.773% |
06 | 0.1015625000 | 0.1051042353 | 0.0035417353 | 3.370% |
07 | 0.1171875000 | 0.1227845609 | 0.0055970609 | 4.558% |
08 | 0.1406250000 | 0.1405408347 | 0.0000841653 | 0.060% |
09 | 0.1562500000 | 0.1583844403 | 0.0021344403 | 1.348% |
10 | 0.1718750000 | 0.1763269807 | 0.0044519807 | 2.525% |
11 | 0.1914062500 | 0.1943803091 | 0.0029740591 | 1.530% |
12 | 0.2148437500 | 0.2125565617 | 0.0022871883 | 1.076% |
13 | 0.2304687500 | 0.2308681911 | 0.0003994411 | 0.173% |
14 | 0.2460937500 | 0.2493280028 | 0.0032342528 | 1.297% |
15 | 0.2656250000 | 0.2679491924 | 0.0023241924 | 0.867% |
16 | 0.2890625000 | 0.2867453858 | 0.0023171142 | 0.808% |
17 | 0.3046875000 | 0.3057306815 | 0.0010431815 | 0.341% |
18 | 0.3242187500 | 0.3249196962 | 0.0007009462 | 0.216% |
19 | 0.3398437500 | 0.3443276133 | 0.0044838633 | 1.302% |
20 | 0.3671875000 | 0.3639702343 | 0.0032172657 | 0.884% |
21 | 0.3828125000 | 0.3838640350 | 0.0010515350 | 0.274% |
22 | 0.4023437500 | 0.4040262258 | 0.0016824758 | 0.416% |
23 | 0.4218750000 | 0.4244748162 | 0.0025998162 | 0.612% |
24 | 0.4414062500 | 0.4452286853 | 0.0038224353 | 0.859% |
25 | 0.4687500000 | 0.4663076582 | 0.0024423418 | 0.524% |
26 | 0.4882812500 | 0.4877325886 | 0.0005486614 | 0.112% |
27 | 0.5078125000 | 0.5095254495 | 0.0017129495 | 0.336% |
28 | 0.5273437500 | 0.5317094317 | 0.0043656817 | 0.821% |
29 | 0.5546875000 | 0.5543090515 | 0.0003784485 | 0.068% |
30 | 0.5781250000 | 0.5773502692 | 0.0007747308 | 0.134% |
31 | 0.5976562500 | 0.6008606190 | 0.0032043690 | 0.533% |
32 | 0.6171875000 | 0.6248693519 | 0.0076818519 | 1.229% |
33 | 0.6523437500 | 0.6494075932 | 0.0029361568 | 0.452% |
34 | 0.6718750000 | 0.6745085168 | 0.0026335168 | 0.390% |
35 | 0.6953125000 | 0.7002075382 | 0.0048950382 | 0.699% |
36 | 0.7226562500 | 0.7265425280 | 0.0038862780 | 0.535% |
37 | 0.7539062500 | 0.7535540501 | 0.0003521999 | 0.047% |
38 | 0.7812500000 | 0.7812856265 | 0.0000356265 | 0.005% |
39 | 0.8085937500 | 0.8097840332 | 0.0011902832 | 0.147% |
40 | 0.8320312500 | 0.8390996312 | 0.0070683812 | 0.842% |
41 | 0.8750000000 | 0.8692867378 | 0.0057132622 | 0.657% |
42 | 0.8984375000 | 0.9004040443 | 0.0019665443 | 0.218% |
43 | 0.9296875000 | 0.9325150861 | 0.0028275861 | 0.303% |
44 | 0.9570312500 | 0.9656887748 | 0.0086575248 | 0.897% |
45 | 0.9921875000 | 1.0000000000 | 0.0078125000 | 0.781% |
46 | 1.0390625000 | 1.0355303138 | 0.0035321862 | 0.341% |
47 | 1.0742187500 | 1.0723687100 | 0.0018500400 | 0.173% |
48 | 1.1093750000 | 1.1106125148 | 0.0012375148 | 0.111% |
49 | 1.1445312500 | 1.1503684072 | 0.0058371572 | 0.507% |
50 | 1.2031250000 | 1.1917535926 | 0.0113714074 | 0.954% |
51 | 1.2421875000 | 1.2348971565 | 0.0072903435 | 0.590% |
52 | 1.2812500000 | 1.2799416322 | 0.0013083678 | 0.102% |
53 | 1.3203125000 | 1.3270448216 | 0.0067323216 | 0.507% |
54 | 1.3867187500 | 1.3763819205 | 0.0103368295 | 0.751% |
55 | 1.4335937500 | 1.4281480067 | 0.0054457433 | 0.381% |
56 | 1.4843750000 | 1.4825609685 | 0.0018140315 | 0.122% |
57 | 1.5351562500 | 1.5398649638 | 0.0047087138 | 0.306% |
58 | 1.6132812500 | 1.6003345290 | 0.0129467210 | 0.809% |
59 | 1.6718750000 | 1.6642794824 | 0.0075955176 | 0.456% |
60 | 1.7265625000 | 1.7320508076 | 0.0054883076 | 0.317% |
61 | 1.7929687500 | 1.8040477553 | 0.0110790053 | 0.614% |
62 | 1.9023437500 | 1.8807264653 | 0.0216172847 | 1.149% |
63 | 1.9765625000 | 1.9626105055 | 0.0139519945 | 0.711% |
64 | 2.0585937500 | 2.0503038416 | 0.0082899084 | 0.404% |
65 | 2.1406250000 | 2.1445069205 | 0.0038819205 | 0.181% |
66 | 2.2656250000 | 2.2460367739 | 0.0195882261 | 0.872% |
67 | 2.3789062500 | 2.3558523658 | 0.0230538842 | 0.979% |
68 | 2.4882812500 | 2.4750868534 | 0.0131943966 | 0.533% |
69 | 2.6015625000 | 2.6050890647 | 0.0035265647 | 0.135% |
70 | 2.7265625000 | 2.7474774195 | 0.0209149195 | 0.761% |
71 | 2.9296875000 | 2.9042108777 | 0.0254766223 | 0.877% |
72 | 3.0820312500 | 3.0776835372 | 0.0043477128 | 0.141% |
73 | 3.2460937500 | 3.2708526185 | 0.0247588685 | 0.757% |
74 | 3.4570312500 | 3.4874144438 | 0.0303831938 | 0.871% |
75 | 3.7695312500 | 3.7320508076 | 0.0374804424 | 1.004% |
76 | 4.0468750000 | 4.0107809335 | 0.0360940665 | 0.900% |
77 | 4.3203125000 | 4.3314758743 | 0.0111633743 | 0.258% |
78 | 4.6289062500 | 4.7046301095 | 0.0757238595 | 1.610% |
79 | 5.2382812500 | 5.1445540160 | 0.0937272340 | 1.822% |
80 | 5.7656250000 | 5.6712818196 | 0.0943431804 | 1.664% |
81 | 6.3046875000 | 6.3137515147 | 0.0090640147 | 0.144% |
82 | 7.0703125000 | 7.1153697224 | 0.0450572224 | 0.633% |
83 | 8.3710937500 | 8.1443464280 | 0.2267473220 | 2.784% |
84 | 9.7500000000 | 9.5143644542 | 0.2356355458 | 2.477% |
85 | 11.3476562500 | 11.4300523028 | 0.0823960528 | 0.721% |
86 | 14.0117187500 | 14.3006662567 | 0.2889475067 | 2.021% |
87 | 20.0468750000 | 19.0811366877 | 0.9657383123 | 5.061% |
88 | 30.0937500000 | 28.6362532829 | 1.4574967171 | 5.090% |
89 | 60.2109375000 | 57.2899616308 | 2.9209758692 | 5.099% |
12. Výpočet goniometrické funkce tan s využitím algoritmu CORDIC – optimalizovaná varianta výpočtů
V případě, že se nad výše uvedenou funkcí fx_tan_cordic() zamyslíme, pravděpodobně zjistíme, že se v ní zbytečně provádí některé aritmetické operace. Zejména se jedná o průběžné násobení koeficienty uloženými v tabulce pows[]. Tato tabulka měla svůj význam při práci s FP formátem, u formátu FX však ztrácí prakticky všechny své výhody, protože násobení zápornou mocninou čísla 2 je vlastně totožné s bitovým posunem doprava. Optimalizovaná funkce pro výpočet tangenty úhlu algoritmem CORDIC vypadá následovně:
/* výpočet funkce tan() pro zadaný úhel delta */ /* optimalizovaná varianta */ fx fx_tan_cordic_optim(fx delta) { int i; /* nastavení počátečních podmínek */ fx x0=int2fx(1); fx y0=0; fx xn; if (delta==0) return 0; /* ošetření nulového úhlu */ for (i=0; i<MAX_ITER; i++) { /* iterační smyčka */ if (delta<0) { /* úhel je záporný => rotace doleva */ xn=fx_add(x0, y0>>i); /* místo násobení bitový posuv */ y0=fx_sub(y0, x0>>i); delta=fx_add(delta, atans[i]); } else { /* úhel je kladný => rotace doprava */ xn=fx_sub(x0, y0>>i); y0=fx_add(y0, x0>>i); delta=fx_sub(delta, atans[i]); } x0=xn; } if (x0==0) /* ošetření tangenty pravého úhlu */ if (y0<0) return 0; else return 0; else return fx_div(y0,x0); /* vrátit výsledek operace */ }
(Pokud by někdo pocítil potřebu provádět další optimalizace, nabízí se zde použití MMX či lépe SSEx instrukcí s paralelním výpočtem obou alternativních větví). Za povšimnutí stojí fakt, že se v iterační smyčce používají pouze aritmetické operace součtu, rozdílu a bitového posuvu. Kromě toho se i při inicializaci hodnot x0 a y0 používá pouze celočíselná aritmetika, tj. ve výpočtech se vůbec nevyskytuje volání instrukcí matematického koprocesoru. Tato absence složitých a implementačně náročných operací představuje další z důvodů velké oblíbenosti algoritmu CORDIC v komunitě vývojářů pro malé mikrořadiče a mikroprocesory.
13. Celý demonstrační příklad: výpočet funkce tan s využitím algoritmu CORDIC
#include <stdlib.h> #include <stdio.h> #include <math.h> /* počet míst před a za binární řádovou tečkou */ #define A 16 #define B 16 /* Ludolfovo číslo */ #ifndef M_PI #define M_PI 3.14159265358979323846 #endif /* maximální počet iterací při běhu algoritmu */ #define MAX_ITER 16 /* "zesílení" při rotacích */ #define K_float 0.6073 /* převody mezi stupni a radiány */ #define rad2deg(rad) ((rad) * 180.0 / M_PI) #define deg2rad(deg) ((deg) / 180.0 * M_PI) /* datový typ, se kterým budeme pracovat */ typedef signed int fx; /* hlavičky použitých funkcí */ void fx_print(fx x); fx fp2fx(double x); double fx2fp(fx x); /* tabulka arkustangentu úhlů */ fx atans[MAX_ITER]; /* tabulka záporných celočíselných mocnin hodnoty 2 */ fx pows[MAX_ITER]; /* * Tisk numerické hodnoty uložené ve formátu pevné * řádové binární čárky (FX) */ void fx_print(fx x) { int i; int val = x; /* pomocná proměnná pro převod do dvojkové soustavy */ printf("bin: "); for (i = 0; i < A + B; i++) { /* převod na řetězec bitů (do dvojkové soustavy) */ putchar(!!(val & (1 << (A + B - 1))) + '0'); /* výpis hodnoty aktuálně nejvyššího bitu */ if (i == B - 1) putchar('.'); /* po řádové binární čárce vypsat značku */ val = val << 1; /* posun na další (méně významný) bit */ } printf(" hex: %08x fp: %+11.5f\n", x, fx2fp(x)); } /* * Převod z formátu plovoucí řádové binární čárky (FP) * do formátu pevné řádové binární čárky (FX) */ fx fp2fx(double x) { return (fx) (x * (2 << (B - 1))); } /* * Převod z celočíselného formátu (integer) * do formátu pevné řádové binární čárky (FX) */ fx int2fx(int x) { return (fx) (x << B); } /* * Převod z formátu pevné řádové binární čárky (FX) * do formátu plovoucí řádové binární čárky (FP) */ double fx2fp(fx x) { return (double) x / (2 << (B - 1)); } /* * Součet dvou hodnot uložených ve shodném formátu * pevné binární řádové čárky (FX) */ fx fx_add(fx x, fx y) { return x + y; } /* * Rozdíl dvou hodnot uložených ve shodném formátu * pevné binární řádové čárky (FX) */ fx fx_sub(fx x, fx y) { return x - y; } /* * Součin dvou hodnot uložených ve shodném formátu * pevné binární řádové čárky (FX) */ fx fx_mul(fx x, fx y) { fx result = (x >> (B / 2)) * (y >> (B / 2)); return result; } /* * Podíl dvou hodnot uložených ve shodném formátu * pevné binární řádové čárky (FX) */ fx fx_div(fx x, fx y) { fx result = x / (y >> (B / 2)); return result << (B / 2); } /* * Vytvoření tabulky pro výpočet goniometrických * funkcí pomocí algoritmu CORDIC */ void fx_create_tables(void) { int i; for (i = 0; i < MAX_ITER; i++) { double p = pow(2.0, -i); atans[i] = fp2fx(atan(p)); pows[i] = fp2fx(p); } } /* výpočet funkce tan() pro zadaný úhel delta */ /* (optimalizovaná verze) */ fx fx_tan_cordic_optim(fx delta) { int i; /* nastavení počátečních podmínek */ fx x0 = int2fx(1); fx y0 = 0; fx xn; if (delta == 0) return 0; /* ošetření nulového úhlu */ for (i = 0; i < MAX_ITER; i++) { /* iterační smyčka */ if (delta < 0) { /* úhel je záporný => rotace doleva */ xn = fx_add(x0, y0 >> i); /* místo násobení bitový posuv */ y0 = fx_sub(y0, x0 >> i); delta = fx_add(delta, atans[i]); } else { /* úhel je kladný => rotace doprava */ xn = fx_sub(x0, y0 >> i); y0 = fx_add(y0, x0 >> i); delta = fx_sub(delta, atans[i]); } x0 = xn; } if (x0 == 0) /* ošetření tangenty pravého úhlu */ if (y0 < 0) return 0; else return 0; else return fx_div(y0, x0); /* vrátit výsledek operace */ } int main(void) { int i; fx tanfx; double delta; /* úhel, ze kterého se funkce počítá */ double tan_value; /* absolutní chyby */ double tan_error; /* relativní chyby */ fx_create_tables(); /* výpis tabulky tangent úhlů v rozsahu 0..89° */ for (i=0; i<90; i++) { /* výpočetní smyčka */ delta=deg2rad(i); /* převod úhlu na radiány */ tanfx=fx_tan_cordic_optim(fp2fx(delta)); /* aplikace algoritmu CORDIC */ tan_value=fx2fp(tanfx); /* výpočet funkce tan */ tan_error=fabs(tan_value-tan(delta)); /* výpočet absolutních chyb */ /* tisk výsledků */ printf("%02d\t%14.10f\t%14.10f\t%12.10f\t%8.3f%%\n", i, tan_value, tan(delta), tan_error, tan_error==0 ? 0:100.0*tan_error/tan(delta)); } return 0; } // finito
14. Výsledky výpočtu funkce tan: absolutní a relativní chyby
V případě, že výše uvedenou funkci fx_tan_cordic_optim() podrobíme stejnému testu, jako funkci fx_tan_cordic(), dostaneme následující (do značné míry podobné) výsledky:
Úhel | tan podle CORDIC | tan podle FPU | absolutní chyba | relativní chyba |
---|---|---|---|---|
00 | 0.0000000000 | 0.0000000000 | 0.0000000000 | 0.000% |
01 | 0.0156250000 | 0.0174550649 | 0.0018300649 | 10.484% |
02 | 0.0312500000 | 0.0349207695 | 0.0036707695 | 10.512% |
03 | 0.0507812500 | 0.0524077793 | 0.0016265293 | 3.104% |
04 | 0.0664062500 | 0.0699268119 | 0.0035205619 | 5.035% |
05 | 0.0859375000 | 0.0874886635 | 0.0015511635 | 1.773% |
06 | 0.1015625000 | 0.1051042353 | 0.0035417353 | 3.370% |
07 | 0.1210937500 | 0.1227845609 | 0.0016908109 | 1.377% |
08 | 0.1406250000 | 0.1405408347 | 0.0000841653 | 0.060% |
09 | 0.1562500000 | 0.1583844403 | 0.0021344403 | 1.348% |
10 | 0.1757812500 | 0.1763269807 | 0.0005457307 | 0.309% |
11 | 0.1914062500 | 0.1943803091 | 0.0029740591 | 1.530% |
12 | 0.2109375000 | 0.2125565617 | 0.0016190617 | 0.762% |
13 | 0.2304687500 | 0.2308681911 | 0.0003994411 | 0.173% |
14 | 0.2460937500 | 0.2493280028 | 0.0032342528 | 1.297% |
15 | 0.2656250000 | 0.2679491924 | 0.0023241924 | 0.867% |
16 | 0.2851562500 | 0.2867453858 | 0.0015891358 | 0.554% |
17 | 0.3046875000 | 0.3057306815 | 0.0010431815 | 0.341% |
18 | 0.3242187500 | 0.3249196962 | 0.0007009462 | 0.216% |
19 | 0.3437500000 | 0.3443276133 | 0.0005776133 | 0.168% |
20 | 0.3632812500 | 0.3639702343 | 0.0006889843 | 0.189% |
21 | 0.3828125000 | 0.3838640350 | 0.0010515350 | 0.274% |
22 | 0.4023437500 | 0.4040262258 | 0.0016824758 | 0.416% |
23 | 0.4218750000 | 0.4244748162 | 0.0025998162 | 0.612% |
24 | 0.4453125000 | 0.4452286853 | 0.0000838147 | 0.019% |
25 | 0.4648437500 | 0.4663076582 | 0.0014639082 | 0.314% |
26 | 0.4882812500 | 0.4877325886 | 0.0005486614 | 0.112% |
27 | 0.5078125000 | 0.5095254495 | 0.0017129495 | 0.336% |
28 | 0.5312500000 | 0.5317094317 | 0.0004594317 | 0.086% |
29 | 0.5546875000 | 0.5543090515 | 0.0003784485 | 0.068% |
30 | 0.5742187500 | 0.5773502692 | 0.0031315192 | 0.542% |
31 | 0.5976562500 | 0.6008606190 | 0.0032043690 | 0.533% |
32 | 0.6250000000 | 0.6248693519 | 0.0001306481 | 0.021% |
33 | 0.6484375000 | 0.6494075932 | 0.0009700932 | 0.149% |
34 | 0.6718750000 | 0.6745085168 | 0.0026335168 | 0.390% |
35 | 0.6992187500 | 0.7002075382 | 0.0009887882 | 0.141% |
36 | 0.7265625000 | 0.7265425280 | 0.0000199720 | 0.003% |
37 | 0.7539062500 | 0.7535540501 | 0.0003521999 | 0.047% |
38 | 0.7812500000 | 0.7812856265 | 0.0000356265 | 0.005% |
39 | 0.8085937500 | 0.8097840332 | 0.0011902832 | 0.147% |
40 | 0.8398437500 | 0.8390996312 | 0.0007441188 | 0.089% |
41 | 0.8671875000 | 0.8692867378 | 0.0020992378 | 0.241% |
42 | 0.8984375000 | 0.9004040443 | 0.0019665443 | 0.218% |
43 | 0.9296875000 | 0.9325150861 | 0.0028275861 | 0.303% |
44 | 0.9648437500 | 0.9656887748 | 0.0008450248 | 0.088% |
45 | 1.0000000000 | 1.0000000000 | 0.0000000000 | 0.000% |
46 | 1.0351562500 | 1.0355303138 | 0.0003740638 | 0.036% |
47 | 1.0742187500 | 1.0723687100 | 0.0018500400 | 0.173% |
48 | 1.1093750000 | 1.1106125148 | 0.0012375148 | 0.111% |
49 | 1.1523437500 | 1.1503684072 | 0.0019753428 | 0.172% |
50 | 1.1953125000 | 1.1917535926 | 0.0035589074 | 0.299% |
51 | 1.2343750000 | 1.2348971565 | 0.0005221565 | 0.042% |
52 | 1.2812500000 | 1.2799416322 | 0.0013083678 | 0.102% |
53 | 1.3281250000 | 1.3270448216 | 0.0010801784 | 0.081% |
54 | 1.3789062500 | 1.3763819205 | 0.0025243295 | 0.183% |
55 | 1.4296875000 | 1.4281480067 | 0.0015394933 | 0.108% |
56 | 1.4843750000 | 1.4825609685 | 0.0018140315 | 0.122% |
57 | 1.5429687500 | 1.5398649638 | 0.0031037862 | 0.202% |
58 | 1.6015625000 | 1.6003345290 | 0.0012279710 | 0.077% |
59 | 1.6640625000 | 1.6642794824 | 0.0002169824 | 0.013% |
60 | 1.7382812500 | 1.7320508076 | 0.0062304424 | 0.360% |
61 | 1.8046875000 | 1.8040477553 | 0.0006397447 | 0.035% |
62 | 1.8867187500 | 1.8807264653 | 0.0059922847 | 0.319% |
63 | 1.9648437500 | 1.9626105055 | 0.0022332445 | 0.114% |
64 | 2.0585937500 | 2.0503038416 | 0.0082899084 | 0.404% |
65 | 2.1445312500 | 2.1445069205 | 0.0000243295 | 0.001% |
66 | 2.2500000000 | 2.2460367739 | 0.0039632261 | 0.176% |
67 | 2.3632812500 | 2.3558523658 | 0.0074288842 | 0.315% |
68 | 2.4882812500 | 2.4750868534 | 0.0131943966 | 0.533% |
69 | 2.6054687500 | 2.6050890647 | 0.0003796853 | 0.015% |
70 | 2.7500000000 | 2.7474774195 | 0.0025225805 | 0.092% |
71 | 2.9062500000 | 2.9042108777 | 0.0020391223 | 0.070% |
72 | 3.0820312500 | 3.0776835372 | 0.0043477128 | 0.141% |
73 | 3.2773437500 | 3.2708526185 | 0.0064911315 | 0.198% |
74 | 3.4921875000 | 3.4874144438 | 0.0047730562 | 0.137% |
75 | 3.7343750000 | 3.7320508076 | 0.0023241924 | 0.062% |
76 | 4.0468750000 | 4.0107809335 | 0.0360940665 | 0.900% |
77 | 4.3671875000 | 4.3314758743 | 0.0357116257 | 0.824% |
78 | 4.7382812500 | 4.7046301095 | 0.0336511405 | 0.715% |
79 | 5.1718750000 | 5.1445540160 | 0.0273209840 | 0.531% |
80 | 5.6835937500 | 5.6712818196 | 0.0123119304 | 0.217% |
81 | 6.4023437500 | 6.3137515147 | 0.0885922353 | 1.403% |
82 | 7.1953125000 | 7.1153697224 | 0.0799427776 | 1.124% |
83 | 8.2031250000 | 8.1443464280 | 0.0587785720 | 0.722% |
84 | 9.5273437500 | 9.5143644542 | 0.0129792958 | 0.136% |
85 | 11.6640625000 | 11.4300523028 | 0.2340101972 | 2.047% |
86 | 14.5000000000 | 14.3006662567 | 0.1993337433 | 1.394% |
87 | 19.1328125000 | 19.0811366877 | 0.0516758123 | 0.271% |
88 | 30.0898437500 | 28.6362532829 | 1.4535904671 | 5.076% |
89 | 60.2109375000 | 57.2899616308 | 2.9209758692 | 5.099% |
15. Způsob překladu algoritmu CORDIC do assembleru
Zajímavé bude zjistit, jakým způsobem se vlastně funkce fx_tan_cordic_optim přeloží do assembleru, pochopitelně v případě, že jsou povoleny optimalizace. Taktéž zjistíme, jak a kdy jsou pomocné funkce pro provádění FX operací (součet, rozdíl atd.) vkládány do kódu a kdy jsou naopak volány:
Překlad s optimalizacemi na co nejkratší kód:
fx_tan_cordic_optim: test edi, edi je .L21 mov edx, edi xor ecx, ecx xor eax, eax mov edi, 65536 .L24: mov r9d, eax mov r8d, edi mov esi, DWORD PTR atans[0+rcx*4] sar r9d, cl sar r8d, cl test edx, edx jns .L22 add edi, r9d sub eax, r8d add edx, esi jmp .L23 .L22: sub edi, r9d add eax, r8d sub edx, esi .L23: inc rcx cmp rcx, 16 jne .L24 test edi, edi je .L21 sar edi, 8 cdq idiv edi sal eax, 8 mov edi, eax .L21: mov eax, edi ret
Překlad s povolením agresivních optimalizací s rozbalením smyčky vede k dlouhému, ovšem velmi rychlému kódu:
fx_tan_cordic_optim: xor eax, eax test edi, edi je .L19 mov edx, edi js .L21 mov ecx, 65536 sub edx, DWORD PTR atans[rip] mov eax, ecx sar eax test edx, edx js .L23 .L58: mov esi, 65536 add ecx, 32768 sub edx, DWORD PTR atans[rip+4] sub esi, eax mov edi, ecx mov eax, esi sar edi, 2 sar eax, 2 test edx, edx js .L25 .L59: sub esi, edi add ecx, eax sub edx, DWORD PTR atans[rip+8] mov edi, ecx mov eax, esi sar edi, 3 sar eax, 3 test edx, edx js .L27 .L60: sub esi, edi add ecx, eax sub edx, DWORD PTR atans[rip+12] mov edi, ecx mov eax, esi sar edi, 4 sar eax, 4 test edx, edx js .L29 .L61: sub esi, edi add ecx, eax sub edx, DWORD PTR atans[rip+16] mov edi, ecx mov eax, esi sar edi, 5 sar eax, 5 test edx, edx js .L31 .L62: sub esi, edi add ecx, eax sub edx, DWORD PTR atans[rip+20] mov edi, ecx mov eax, esi sar edi, 6 sar eax, 6 test edx, edx js .L33 .L63: sub esi, edi add ecx, eax sub edx, DWORD PTR atans[rip+24] mov edi, ecx mov eax, esi sar edi, 7 sar eax, 7 test edx, edx js .L35 .L64: sub esi, edi add ecx, eax sub edx, DWORD PTR atans[rip+28] mov edi, ecx mov eax, esi sar edi, 8 sar eax, 8 test edx, edx js .L37 .L65: sub esi, edi add ecx, eax sub edx, DWORD PTR atans[rip+32] mov edi, ecx mov eax, esi sar edi, 9 sar eax, 9 test edx, edx js .L39 .L66: sub esi, edi add ecx, eax sub edx, DWORD PTR atans[rip+36] mov edi, ecx mov eax, esi sar edi, 10 sar eax, 10 test edx, edx js .L41 .L67: sub esi, edi add ecx, eax sub edx, DWORD PTR atans[rip+40] mov edi, ecx mov eax, esi sar edi, 11 sar eax, 11 test edx, edx js .L43 .L68: sub esi, edi add ecx, eax sub edx, DWORD PTR atans[rip+44] mov edi, ecx mov eax, esi sar edi, 12 sar eax, 12 test edx, edx js .L45 .L69: sub esi, edi add ecx, eax sub edx, DWORD PTR atans[rip+48] mov edi, ecx mov eax, esi sar edi, 13 sar eax, 13 test edx, edx js .L47 .L70: sub esi, edi add ecx, eax sub edx, DWORD PTR atans[rip+52] mov edi, ecx mov eax, esi sar edi, 14 sar eax, 14 test edx, edx js .L49 .L71: sub esi, edi add ecx, eax sub edx, DWORD PTR atans[rip+56] .L50: mov r8d, ecx mov r9d, esi mov eax, esi sar r8d, 15 sar r9d, 15 sub eax, r8d add r8d, esi lea edi, [r9+rcx] test edx, edx cmovs eax, r8d sub ecx, r9d test edx, edx cmovs edi, ecx test eax, eax je .L19 sar eax, 8 mov ecx, eax mov eax, edi cdq idiv ecx sal eax, 8 .L19: ret .L21: mov ecx, -65536 add edx, DWORD PTR atans[rip] mov eax, ecx sar eax test edx, edx jns .L58 .L23: lea esi, [rax+65536] sub ecx, 32768 add edx, DWORD PTR atans[rip+4] mov edi, ecx mov eax, esi sar edi, 2 sar eax, 2 test edx, edx jns .L59 .L25: add esi, edi sub ecx, eax add edx, DWORD PTR atans[rip+8] mov edi, ecx mov eax, esi sar edi, 3 sar eax, 3 test edx, edx jns .L60 .L27: add esi, edi sub ecx, eax add edx, DWORD PTR atans[rip+12] mov edi, ecx mov eax, esi sar edi, 4 sar eax, 4 test edx, edx jns .L61 .L29: add esi, edi sub ecx, eax add edx, DWORD PTR atans[rip+16] mov edi, ecx mov eax, esi sar edi, 5 sar eax, 5 test edx, edx jns .L62 .L31: add esi, edi sub ecx, eax add edx, DWORD PTR atans[rip+20] mov edi, ecx mov eax, esi sar edi, 6 sar eax, 6 test edx, edx jns .L63 .L33: add esi, edi sub ecx, eax add edx, DWORD PTR atans[rip+24] mov edi, ecx mov eax, esi sar edi, 7 sar eax, 7 test edx, edx jns .L64 .L35: add esi, edi sub ecx, eax add edx, DWORD PTR atans[rip+28] mov edi, ecx mov eax, esi sar edi, 8 sar eax, 8 test edx, edx jns .L65 .L37: add esi, edi sub ecx, eax add edx, DWORD PTR atans[rip+32] mov edi, ecx mov eax, esi sar edi, 9 sar eax, 9 test edx, edx jns .L66 .L39: add esi, edi sub ecx, eax add edx, DWORD PTR atans[rip+36] mov edi, ecx mov eax, esi sar edi, 10 sar eax, 10 test edx, edx jns .L67 .L41: add esi, edi sub ecx, eax add edx, DWORD PTR atans[rip+40] mov edi, ecx mov eax, esi sar edi, 11 sar eax, 11 test edx, edx jns .L68 .L43: add esi, edi sub ecx, eax add edx, DWORD PTR atans[rip+44] mov edi, ecx mov eax, esi sar edi, 12 sar eax, 12 test edx, edx jns .L69 .L45: add esi, edi sub ecx, eax add edx, DWORD PTR atans[rip+48] mov edi, ecx mov eax, esi sar edi, 13 sar eax, 13 test edx, edx jns .L70 .L47: add esi, edi sub ecx, eax add edx, DWORD PTR atans[rip+52] mov edi, ecx mov eax, esi sar edi, 14 sar eax, 14 test edx, edx jns .L71 .L49: add esi, edi sub ecx, eax add edx, DWORD PTR atans[rip+56] jmp .L50
Opět si povšimněte, že každé rozbalené tělo smyčky obsahuje jen základní aritmetické operace a posuny.
16. Výpočet goniometrické funkce sin
Výpočet goniometrické funkce sin() pomocí algoritmu CORDIC je při použití formátu pevné řádové binární čárky velmi snadný a současně i přímočarý. Dokonce je možné říci, že výpočet je oproti verzi používající plovoucí řádovou čárku jednodušší, a to z toho důvodu, že se místo pomocné tabulky s druhými mocninami čísla dvě přímo používá operace pro aritmetický posuv doprava (ten je podporován přímo centrální procesorovou jednotkou, jedná se tedy o znatelné zrychlení celého výpočtu). Při implementaci algoritmu CORDIC v programovacím jazyku C může funkce pro výpočet sinu vypadat následovně (připomeňme si, že výsledek je uložen v y-ové složce orotovaného vektoru r):
/* výpočet funkce sin() pro zadaný úhel delta */ fx fx_sin_cordic_optim(fx delta) { int i; static fx K_fx=(fx)(K_float*(2<<(B-1))); /* nastavení počátečních podmínek */ fx x0=int2fx(1); fx y0=0; fx xn; for (i=0; i<MAX_ITER; i++) { /* iterační smyčka */ if (delta<0) { /* úhel je záporný => rotace doleva */ xn=fx_add(x0, y0>>i); /* místo násobení bitový posuv */ y0=fx_sub(y0, x0>>i); delta=fx_add(delta, atans[i]); } else { /* úhel je kladný => rotace doprava */ xn=fx_sub(x0, y0>>i); y0=fx_add(y0, x0>>i); delta=fx_sub(delta, atans[i]); } x0=xn; } return fx_mul(y0, K_fx); /* opravit "zesílení" výsledku */ }
17. Výsledky výpočtu funkce sin: absolutní a relativní chyby, statistiky
Výše uvedenou céčkovskou funkci fx_sin_cordic_optim() si můžeme otestovat na výpočtu úhlů ležících v prvním kvadrantu, tj. od 0° do 90°. Kromě vypočtených hodnot je u každého úhlu uvedena i hodnota vypočtená pomocí FPU, dále pak absolutní a relativní chyba. Tučně jsou zvýrazněny ty relativní chyby, které jsou menší než jedno procento:
Úhel | sin() dle CORDIC | sin() dle FPU | absolutní chyba | relativní chyba |
---|---|---|---|---|
00 | 0.0000000000 | 0.0000000000 | 0.0000000000 | 0.000% |
01 | 0.0165557861 | 0.0174524064 | 0.0008966203 | 5.138% |
02 | 0.0331115723 | 0.0348994967 | 0.0017879244 | 5.123% |
03 | 0.0520324707 | 0.0523359562 | 0.0003034855 | 0.580% |
04 | 0.0685882568 | 0.0697564737 | 0.0011682169 | 1.675% |
05 | 0.0851440430 | 0.0871557427 | 0.0020116998 | 2.308% |
06 | 0.1040649414 | 0.1045284633 | 0.0004635219 | 0.443% |
07 | 0.1206207275 | 0.1218693434 | 0.0012486159 | 1.025% |
08 | 0.1371765137 | 0.1391731010 | 0.0019965873 | 1.435% |
09 | 0.1537322998 | 0.1564344650 | 0.0027021652 | 1.727% |
10 | 0.1726531982 | 0.1736481777 | 0.0009949794 | 0.573% |
11 | 0.1892089844 | 0.1908089954 | 0.0016000110 | 0.839% |
12 | 0.2057647705 | 0.2079116908 | 0.0021469203 | 1.033% |
13 | 0.2223205566 | 0.2249510543 | 0.0026304977 | 1.169% |
14 | 0.2388763428 | 0.2419218956 | 0.0030455528 | 1.259% |
15 | 0.2577972412 | 0.2588190451 | 0.0010218039 | 0.395% |
16 | 0.2743530273 | 0.2756373558 | 0.0012843285 | 0.466% |
17 | 0.2909088135 | 0.2923717047 | 0.0014628912 | 0.500% |
18 | 0.3074645996 | 0.3090169944 | 0.0015523948 | 0.502% |
19 | 0.3240203857 | 0.3255681545 | 0.0015477687 | 0.475% |
20 | 0.3405761719 | 0.3420201433 | 0.0014439715 | 0.422% |
21 | 0.3571319580 | 0.3583679495 | 0.0012359915 | 0.345% |
22 | 0.3713226318 | 0.3746065934 | 0.0032839616 | 0.877% |
23 | 0.3878784180 | 0.3907311285 | 0.0028527105 | 0.730% |
24 | 0.4044342041 | 0.4067366431 | 0.0023024390 | 0.566% |
25 | 0.4209899902 | 0.4226182617 | 0.0016282715 | 0.385% |
26 | 0.4351806641 | 0.4383711468 | 0.0031904827 | 0.728% |
27 | 0.4517364502 | 0.4539904997 | 0.0022540495 | 0.496% |
28 | 0.4659271240 | 0.4694715628 | 0.0035444388 | 0.755% |
29 | 0.4824829102 | 0.4848096202 | 0.0023267101 | 0.480% |
30 | 0.4966735840 | 0.5000000000 | 0.0033264160 | 0.665% |
31 | 0.5132293701 | 0.5150380749 | 0.0018087048 | 0.351% |
32 | 0.5274200439 | 0.5299192642 | 0.0024992203 | 0.472% |
33 | 0.5416107178 | 0.5446390350 | 0.0030283172 | 0.556% |
34 | 0.5558013916 | 0.5591929035 | 0.0033915119 | 0.607% |
35 | 0.5699920654 | 0.5735764364 | 0.0035843709 | 0.625% |
36 | 0.5841827393 | 0.5877852523 | 0.0036025130 | 0.613% |
37 | 0.5983734131 | 0.6018150232 | 0.0034416101 | 0.572% |
38 | 0.6125640869 | 0.6156614753 | 0.0030973884 | 0.503% |
39 | 0.6267547607 | 0.6293203910 | 0.0025656303 | 0.408% |
40 | 0.6385803223 | 0.6427876097 | 0.0042072874 | 0.655% |
41 | 0.6527709961 | 0.6560590290 | 0.0032880329 | 0.501% |
42 | 0.6669616699 | 0.6691306064 | 0.0021689364 | 0.324% |
43 | 0.6787872314 | 0.6819983601 | 0.0032111286 | 0.471% |
44 | 0.6906127930 | 0.6946583705 | 0.0040455775 | 0.582% |
45 | 0.7048034668 | 0.7071067812 | 0.0023033144 | 0.326% |
46 | 0.7166290283 | 0.7193398003 | 0.0027107720 | 0.377% |
47 | 0.7284545898 | 0.7313537016 | 0.0028991118 | 0.396% |
48 | 0.7402801514 | 0.7431448255 | 0.0028646741 | 0.385% |
49 | 0.7521057129 | 0.7547095802 | 0.0026038673 | 0.345% |
50 | 0.7615661621 | 0.7660444431 | 0.0044782810 | 0.585% |
51 | 0.7733917236 | 0.7771459615 | 0.0037542378 | 0.483% |
52 | 0.7852172852 | 0.7880107536 | 0.0027934685 | 0.354% |
53 | 0.7946777344 | 0.7986355100 | 0.0039577757 | 0.496% |
54 | 0.8065032959 | 0.8090169944 | 0.0025136985 | 0.311% |
55 | 0.8159637451 | 0.8191520443 | 0.0031882992 | 0.389% |
56 | 0.8254241943 | 0.8290375726 | 0.0036133782 | 0.436% |
57 | 0.8348846436 | 0.8386705679 | 0.0037859244 | 0.451% |
58 | 0.8443450928 | 0.8480480962 | 0.0037030034 | 0.437% |
59 | 0.8538055420 | 0.8571673007 | 0.0033617587 | 0.392% |
60 | 0.8632659912 | 0.8660254038 | 0.0027594126 | 0.319% |
61 | 0.8703613281 | 0.8746197071 | 0.0042583790 | 0.487% |
62 | 0.8798217773 | 0.8829475929 | 0.0031258155 | 0.354% |
63 | 0.8869171143 | 0.8910065242 | 0.0040894099 | 0.459% |
64 | 0.8940124512 | 0.8987940463 | 0.0047815951 | 0.532% |
65 | 0.9034729004 | 0.9063077870 | 0.0028348866 | 0.313% |
66 | 0.9105682373 | 0.9135454576 | 0.0029772203 | 0.326% |
67 | 0.9176635742 | 0.9205048535 | 0.0028412792 | 0.309% |
68 | 0.9223937988 | 0.9271838546 | 0.0047900557 | 0.517% |
69 | 0.9294891357 | 0.9335804265 | 0.0040912908 | 0.438% |
70 | 0.9365844727 | 0.9396926208 | 0.0031081481 | 0.331% |
71 | 0.9413146973 | 0.9455185756 | 0.0042038783 | 0.445% |
72 | 0.9460449219 | 0.9510565163 | 0.0050115944 | 0.527% |
73 | 0.9531402588 | 0.9563047560 | 0.0031644972 | 0.331% |
74 | 0.9578704834 | 0.9612616959 | 0.0033912125 | 0.353% |
75 | 0.9626007080 | 0.9659258263 | 0.0033251183 | 0.344% |
76 | 0.9673309326 | 0.9702957263 | 0.0029647937 | 0.306% |
77 | 0.9696960449 | 0.9743700648 | 0.0046740199 | 0.480% |
78 | 0.9744262695 | 0.9781476007 | 0.0037213312 | 0.380% |
79 | 0.9767913818 | 0.9816271834 | 0.0048358016 | 0.493% |
80 | 0.9815216064 | 0.9848077530 | 0.0032861466 | 0.334% |
81 | 0.9838867188 | 0.9876883406 | 0.0038016218 | 0.385% |
82 | 0.9862518311 | 0.9902680687 | 0.0040162377 | 0.406% |
83 | 0.9886169434 | 0.9925461516 | 0.0039292083 | 0.396% |
84 | 0.9909820557 | 0.9945218954 | 0.0035398397 | 0.356% |
85 | 0.9909820557 | 0.9961946981 | 0.0052126424 | 0.523% |
86 | 0.9933471680 | 0.9975640503 | 0.0042168823 | 0.423% |
87 | 0.9933471680 | 0.9986295348 | 0.0052823668 | 0.529% |
88 | 0.9957122803 | 0.9993908270 | 0.0036785467 | 0.368% |
89 | 0.9957122803 | 0.9998476952 | 0.0041354149 | 0.414% |
90 | 0.9957122803 | 1.0000000000 | 0.0042877197 | 0.429% |
Statistické vlastnosti výpočtu
Počet iterací: | 16 |
Součet absolutních chyb: | 0.270 |
Součet relativních chyb: | 59.119% |
Průměrná absolutní chyba: | 0.003 |
Průměrná relativní chyba: | 0.650% |
18. Repositář s demonstračními příklady
# | 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_mul4.asm | násobení malých hodnot s korektním výsledkem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fx_mul4.asm |
239 | fx_mul5.asm | násobení příliš malých hodnot s nekorektním výsledkem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fx_mul5.asm |
240 | fx_mul6.asm | násobení malých hodnot omezené na 2n-bitové hodnoty | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fx_mul6.asm |
241 | 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 |
242 | 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 |
243 | 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 |
244 | 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 |
245 | 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 |
246 | fx_mandel2.asm | výpočet Mandelbrotovy množiny; optimalizovaná varianta | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fx_mandel2.asm |
247 | fx_mandel3.asm | výpočet Mandelbrotovy množiny; základní šestnáctibitová varianta | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fx_mandel3.asm |
248 | fx_mandel4.asm | výpočet Mandelbrotovy množiny; šestnáctibitová varianta s vyšší přesností | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fx_mandel4.asm |
249 | fx_mandel5.asm | výpočet Mandelbrotovy množiny; šestnáctibitová varianta s vyšší přesností, ale malým rozsahem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fx_mandel5.asm |
250 | fx_julia.asm | výpočet animace Juliovy množiny | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fx_julia.asm |
251 | sqrt_fp.c | iterativní výpočet druhé odmocniny, FP varianta | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sqrt_fp.c |
252 | sqrt_fx.c | iterativní výpočet druhé odmocniny, FX varianta | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sqrt_fx.c |
253 | sin_fp.c | výpočet hodnoty sinu na základě prvních členů Taylorova rozvoje | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sin_fp.c |
254 | cordic_fp_sin_cos.c | úplný zdrojový kód programu pro výpočet funkcí sin a cos algoritmem CORDIC | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cordic_fp_sin_cos.c |
255 | cordic_fp_tan.c | výpočet tangenty s využitím algoritmu CORDIC | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cordic_fp_tan.c |
256 | cordic_fp_arctan.c | výpočet arkustangenty s využitím algoritmu CORDIC | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cordic_fp_arctan.c |
19. Literatura
- Andraka, Ray: „A survey of CORDIC algorithms for FPGA based computers“,
ACM, 1998 - Despain, A.M.:„Fourier Transform Computations Using CORDIC Iterations“,
IEEE Transactions on Computers, Volume 23, strany 993–1001, 1974 - Mazenc C., Merrheim, X., Muller, J.M.: „Computing Functions Arccos and Arcsin Using CORDIC“,
IEEE Transactions on Computers, Volume 42, strany 118–122, 1993 - Volder, Jack: „Binary computation algorithms for coordinate rotation and function generation“,
Convair Report IAR-1, 1956 - Volder, Jack: „The CORDIC Trigonometric Computing Technique“,
IRE Transactions on Electronic Computing, Vol EC-8, strany 330–334, 1959 - NVIDIA Corporation: „Floating-Point Specials on the GPU“,
2005 - Grant R. Griffin: CORDIC FAQ,
http://www.dspguru.com/info/faqs/cordic.htm - Andraka Consulting Group, Inc.: What is all this CORDIC stuff anyhow?,
http://www.andraka.com/cordic.htm - Cyliax Ingo: CORDIC (COordinate Rotation DIgital Computer), the swiss army knife for computing math functions…
http://www.ee.ualberta.ca/courses/ee401/microboard/cordic_CCink.html
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