Obsah
1. Pokročilejší SSE operace: přeskupení, promíchání a rozbalování prvků vektorů
2. Instrukce pro proložení prvků dvou vektorů
3. Demonstrační příklad: proložení prvků dvou vektorů instrukcí UNPCKHPS
4. Demonstrační příklad: proložení prvků dvou vektorů instrukcí UNPCKLPS
5. Instrukce SHUFPS – shuffling a promíchání prvků vektorů
6. Demonstrační příklad: použití instrukce SHUFPS
7. SSE instrukce pro konverzi dat
8. Demonstrační příklad: konverze celého čísla na hodnotu typu single
9. Demonstrační příklad: konverze hodnoty typu single na celé číslo
10. Konverze hodnot, které nelze přesně převést na celé číslo
11. Konverze speciálních FP hodnot na celá čísla
12. Řídicí a stavový registr MXCSR
13. Přečtení obsahu registru MXCSR
15. Nastavení režimu zaokrouhlování
16. Denormalizované hodnoty vs. nula
17. Příloha: doplnění příkladu ukazujícího kódování všech SSE instrukcí
18. Seznam všech popsaných instrukcí SSE
19. Repositář s demonstračními příklady
1. Pokročilejší SSE operace: přeskupení, promíchání a rozbalování prvků vektorů
V dnešním článku (konečně) dokončíme popis rozšíření instrukční sady SSE. Ukážeme si některé netriviální operace, které je možné provádět se skaláry a především s vektory. Jedná se o konverzní operace (kde můžeme narazit na některé problematické hodnoty) a taktéž o rozbalování a zabalování prvků vektorů, prokládání prvků vektorů atd. Ve druhé části článku se seznámíme se stavovým a řídicím registrem pojmenovaným MXCSR. Ten slouží pro nastavení způsobu provádění numerických operací s hodnotami typu single (režim zaokrouhlení atd.), ale obsahuje i příznakové bity, z nichž je možné vyčíst například to, že došlo k přetečení hodnot (při konverzích), k dělení nulou atd. Tento 32bitový registr tedy slouží k podobným účelům, jako šestnáctibitové registry matematického koprocesoru: stavové slovo a řídicí slovo (SW, CW).
2. Instrukce pro proložení prvků dvou vektorů
První dvě instrukce, s nimiž se v dnešním článku seznámíme, se jmenují UNPCKHPS a UNPCKLPS. Tyto dvě instrukce mají na vstupu (jako své operandy) dvojici vektorů, z nichž každý obsahuje čtyři prvky typu float/single. Tyto prvky si opět můžeme označit x3, x2, x1, x0 pro první vektor a y3, y2, y1, y0 pro vektor druhý. Instrukce nazvaná UNPCKHPS (znak H je odvozený od slova high) z těchto osmi vstupních hodnot vytvoří vektor [x2, y2, x3, y3], což znamená promíchání obou vektorů, resp. přesněji řečeno jejich horních polovin. A podobně instrukce UNPCKLPS vytvoří vektor [x0, y0, x1, y1], tedy vektor složený z nižších polovin obou vstupních (zdrojových) vektorů.
Vizuálně vypadají obě operace následovně:
Obrázek 1: Operace provedená instrukcí UNPCKHPS.
Obrázek 2: Operace provedená instrukcí UNPCKLPS.
Tyto instrukce se mnohdy v programovém kódu nachází v párech, protože typicky potřebujeme zpracovat a proložit všechny prvky vektorů – dohromady tedy osm prvků, které je nutné uložit do dvojice cílových registrů.
3. Demonstrační příklad: proložení prvků dvou vektorů instrukcí UNPCKHPS
V dnešním prvním demonstračním příkladu si ukážeme operaci prováděnou instrukcí UNPCKHPS. Její použití je snadné – postačuje naplnit dvojici XMM registrů vektory čtyř numerických hodnot a vykonat instrukci UNPCKHPS. V prvním registru (je to současně registr zdrojový i cílový) bude uložen výsledek celé operace:
[bits 32]
%include "linux_macros.asm"
;-----------------------------------------------------------------------------
section .data
hex_message:
times 8 db '?'
db ' '
hex_message_length equ $ - hex_message
align 16
sse_val_1 dd 0x00000000, 0x11111111, 0x22222222, 0x33333333
sse_val_2 dd 0x44444444, 0x55555555, 0x66666666, 0x77777777
;-----------------------------------------------------------------------------
section .bss
sse_tmp resb 16
;-----------------------------------------------------------------------------
section .text
global _start ; tento symbol ma byt dostupny i linkeru
_start:
mov ebx, sse_val_1
movaps xmm0, [ebx] ; nacteni prvni hodnoty do registru XMM0
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
mov ebx, sse_val_2
movaps xmm1, [ebx] ; nacteni druhe hodnoty do registru XMM1
print_sse_reg_as_hex xmm1 ; tisk hodnoty registru XMM1
unpckhps xmm0, xmm1 ; proložení prvků vektorů
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
exit ; ukonceni procesu
%include "hex2string.asm"
Vzhledem k tomu, že tato instrukce pouze provádí přeskupení prvků bez toto, aby „zkoumala“ jejich obsah, jsem použil hodnoty prvků zapsané přímo v hexadecimální soustavě:
vstup1: 33333333 22222222 11111111 00000000
vstup2: 77777777 66666666 55555555 44444444
-----------------------------------
výsledek: 77777777 33333333 66666666 22222222
Ze zobrazených řádků je patrné, že do cílového vektoru skutečně byly uloženy kombinace vyšších dvojic prvků vektorů.
4. Demonstrační příklad: proložení prvků dvou vektorů instrukcí UNPCKLPS
Ve druhém demonstračním příkladu jednoduše nahradíme instrukci UNPCKHPS za instrukci UNPCKLPS. Měla by se tedy provádět prakticky stejná operace, ovšem nikoli s horními dvojicemi prvků vektorů, ale naopak s nižšími dvojicemi. To si snadno ověříme:
[bits 32]
%include "linux_macros.asm"
;-----------------------------------------------------------------------------
section .data
hex_message:
times 8 db '?'
db ' '
hex_message_length equ $ - hex_message
align 16
sse_val_1 dd 0x00000000, 0x11111111, 0x22222222, 0x33333333
sse_val_2 dd 0x44444444, 0x55555555, 0x66666666, 0x77777777
;-----------------------------------------------------------------------------
section .bss
sse_tmp resb 16
;-----------------------------------------------------------------------------
section .text
global _start ; tento symbol ma byt dostupny i linkeru
_start:
mov ebx, sse_val_1
movaps xmm0, [ebx] ; nacteni prvni hodnoty do registru XMM0
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
mov ebx, sse_val_2
movaps xmm1, [ebx] ; nacteni druhe hodnoty do registru XMM1
print_sse_reg_as_hex xmm1 ; tisk hodnoty registru XMM1
unpcklps xmm0, xmm1 ; proložení prvků vektorů
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
exit ; ukonceni procesu
%include "hex2string.asm"
Výsledky:
vstup1: 33333333 22222222 11111111 00000000
vstup2: 77777777 66666666 55555555 44444444
-----------------------------------
výsledek: 55555555 11111111 44444444 00000000
Ze zobrazených řádků je opět dobře patrné, že do cílového vektoru skutečně byly uloženy kombinace nižších dvojic prvků vektorů.
5. Instrukce SHUFPS – shuffling a promíchání prvků vektorů
Nejsložitější instrukcí, se kterou se v dnešním článku seznámíme, je instrukce nazvaná SHUFPS (prefix SHUF znamená shuffle, suffix PS pak packed single, tedy vektor). Tato instrukce provádí, jak již ostatně její název napovídá, „shuffling“ prvků uložených ve dvou vstupních vektorech s vytvořením cílového vektoru. Vektory přitom obsahují čtveřici hodnot typu single/float. Prvky těchto dvou vektorů si opět můžeme označit symboly x3, x2, x1, x0 pro první vektor a y3, y2, y1, y0 pro vektor druhý, podobně jako při popisu předchozí dvojice instrukcí.
Instrukce SHUFPS vytvoří výsledný vektor se strukturou [yn, yn, xn, xn], přičemž indexy n, které musí být v rozsahu 0..3, jsou umístěny v osmibitové celočíselné konstantě – vždy dva bity pro každý prvek vektoru. Pokud například bude tato konstanta rovna nule (tedy 00 00 00 00), bude výsledkem vektor [y0, y0, x0, x0]:
V případě, že zde bude uloženo například binární číslo 11001001 tedy po rozdělení na dvojice bitů 11 00 10 01, bude výsledný vektor obsahovat prvky [y3, y0, x2, x1]. Jedná se tedy o poměrně univerzální operaci, i když zpočátku může být pochopení chování této instrukce poněkud problematické:
6. Demonstrační příklad: použití instrukce SHUFPS
Vzhledem k tomu, jak je chování instrukce SHUFPS variabilní v závislosti na předané osmibitové konstantě, si v demonstračním příkladu ukážeme několikeré volání této instrukce se stejnými vstupními vektory, ovšem s rozdílnými konstantami:
[bits 32]
%include "linux_macros.asm"
;-----------------------------------------------------------------------------
section .data
hex_message:
times 8 db '?'
db ' '
hex_message_length equ $ - hex_message
align 16
sse_val_1 dd 0x00000000, 0x11111111, 0x22222222, 0x33333333
sse_val_2 dd 0x44444444, 0x55555555, 0x66666666, 0x77777777
;-----------------------------------------------------------------------------
section .bss
sse_tmp resb 16
;-----------------------------------------------------------------------------
section .text
global _start ; tento symbol ma byt dostupny i linkeru
_start:
mov ebx, sse_val_1
movaps xmm0, [ebx] ; nacteni prvni hodnoty do registru XMM0
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
mov ebx, sse_val_2
movaps xmm1, [ebx] ; nacteni druhe hodnoty do registru XMM1
print_sse_reg_as_hex xmm1 ; tisk hodnoty registru XMM1
shufps xmm0, xmm1, 0b00000000 ; proložení prvků vektorů
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
mov ebx, sse_val_1
movaps xmm0, [ebx] ; nacteni prvni hodnoty do registru XMM0
shufps xmm0, xmm1, 0b00000001 ; proložení prvků vektorů
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
mov ebx, sse_val_1
movaps xmm0, [ebx] ; nacteni prvni hodnoty do registru XMM0
shufps xmm0, xmm1, 0b00000010 ; proložení prvků vektorů
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
mov ebx, sse_val_1
movaps xmm0, [ebx] ; nacteni prvni hodnoty do registru XMM0
shufps xmm0, xmm1, 0b00000011 ; proložení prvků vektorů
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
mov ebx, sse_val_1
movaps xmm0, [ebx] ; nacteni prvni hodnoty do registru XMM0
shufps xmm0, xmm1, 0b01010101 ; proložení prvků vektorů
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
mov ebx, sse_val_1
movaps xmm0, [ebx] ; nacteni prvni hodnoty do registru XMM0
shufps xmm0, xmm1, 0b01100110 ; proložení prvků vektorů
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
mov ebx, sse_val_1
movaps xmm0, [ebx] ; nacteni prvni hodnoty do registru XMM0
shufps xmm0, xmm1, 0b00110011 ; proložení prvků vektorů
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
mov ebx, sse_val_1
movaps xmm0, [ebx] ; nacteni prvni hodnoty do registru XMM0
shufps xmm0, xmm1, 0b11111111 ; proložení prvků vektorů
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
exit ; ukonceni procesu
%include "hex2string.asm"
Výsledky po doplnění dalších informací budou vypadat takto:
vstup1: 33333333 22222222 11111111 00000000
vstup2: 77777777 66666666 55555555 44444444
-----------------------------------
konstanta:
00000000 44444444 44444444 00000000 00000000 nakopírují se pouze nejnižší prvky zdrojových vektorů
00000001 44444444 44444444 00000000 11111111 nejnižší prvek výsledku je získán z x1
00000010 44444444 44444444 00000000 22222222 nejnižší prvek výsledku je získán z x2
00000011 44444444 44444444 00000000 33333333 nejnižší prvek výsledku je získán z x3
01010101 55555555 55555555 11111111 11111111 nakopírují se druhé prvky zdrojových vektorů
01100110 55555555 66666666 11111111 22222222 postupně: y1, y2, x1, x2 (prvky se tedy prohazují)
00110011 44444444 77777777 00000000 33333333 postupně: y0, y3, x0, x3 (prvky se tedy prohazují)
11111111 77777777 77777777 33333333 33333333 nakopírují se pouze nejvyšší prvky zdrojových vektorů
7. SSE instrukce určené pro konverzi dat
Při implementaci mnoha algoritmů, především pak při zpracování obrazových dat, popř. zvukových datových toků, se mnohdy programátoři dostanou do situace, v nichž je nutné zkonvertovat vstupní data do odlišného formátu, než v jakém byla původně uložena (příkladem je konverze celočíselných hodnot pixelů na hodnoty single atd.). Pro tyto účely je v instrukční sadě SSE k dispozici celkem šest konverzních instrukcí začínajících prefixem CVT (convert). Všechny tyto instrukce jsou vypsány v tabulce pod tímto odstavcem. Opět platí, že konverze jsou prováděny paralelně, i když v tomto případě kupodivu nikoli se čtyřprvkovými vektory, ale většinou se skalárními hodnotami nebo vektory dvouprvkovými (toto omezení je výsledkem malého počtu bajtů rezervovaného pro uložení adresy v instrukčních slovech):
| # | Instrukce | Konverze z… | Konverze do… |
|---|---|---|---|
| 1 | CVTSI2SS | 1×32bitový integer v paměti či pracovním registru | 1×32bitový single |
| 2 | CVTSS2SI | 1×32bitový single | 1×32bitový integer v pracovním registru (CPU) |
| 3 | CVTTSS2SI | 1×32bitový single | 1×32bitový integer (odseknutí desetinné části) v pracovním registru |
| 4 | CVTPI2PS | 2×32bitový integer | 2×32bitový single |
| 5 | CVTPS2PI | 2×32bitový single | 2×32bitový integer |
| 6 | CVTTPS2PI | 2×32bitový single | 2×32bitový integer (odseknutí desetinné části) v MMX registru |
Některé z těchto instrukcí si opět ukážeme na demonstračních příkladech.
8. Demonstrační příklad: konverze celého čísla na hodnotu typu single
Ukažme si nejprve, jakým způsobem je možné využít instrukci pojmenovanou CVTSI2SS. Název této instrukce napovídá, že se bude provádět konverze skalární hodnoty (poslední znak S) z celého čísla (I) na numerickou hodnotu typu single (I2S). Hodnota, která se má převádět, může být uložena v univerzálním pracovním registru CPU, například v registru EAX. Navíc je nutné myslet na to, že zdrojová hodnota je 32bitovým celým číslem a cílová hodnota je 32bitovým číslem typu single. Ovšem v hodnotě typu single je nutné rezervovat jeden bit na znaménko a osm bitů na exponent. Samotná hodnota mantisy je tedy uložena pouze ve 23 bitech. Obecně tedy bude docházet ke ztrátě přesnosti:
[bits 32]
%include "linux_macros.asm"
;-----------------------------------------------------------------------------
section .data
hex_message:
times 8 db '?'
db ' '
hex_message_length equ $ - hex_message
align 16
;-----------------------------------------------------------------------------
section .bss
sse_tmp resb 16
;-----------------------------------------------------------------------------
section .text
global _start ; tento symbol ma byt dostupny i linkeru
_start:
mov eax, 2
cvtsi2ss xmm0, eax ; konverze jednoho prvku
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
mov eax, 100000
cvtsi2ss xmm0, eax ; konverze jednoho prvku
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
mov eax, 0xffffffff
cvtsi2ss xmm0, eax ; konverze jednoho prvku
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
exit ; ukonceni procesu
%include "hex2string.asm"
Následují výsledky vypsané tímto demonstračním příkladem, k nimž byla dopsána i příslušná FP hodnota typu single:
vstup výsledek uložený v registru XMM0 odpovídající FP hodnota 2 00000000 00000000 00000000 40000000 2.0 (přesná) 100000 00000000 00000000 00000000 47C35000 100000.0 (přesná) 0xffffffff 00000000 00000000 00000000 BF800000 -1,0 (přesná)
9. Demonstrační příklad: konverze hodnoty typu single na celé číslo
Nyní se podívejme na způsob provedení opačné konverze, tj. na převod hodnoty typu single (s plovoucí řádovou čárkou) na 32bitovou celočíselnou hodnotu. V tomto příkladu budeme konvertovat jen „vhodné“ hodnoty, u nichž je zřejmé, že se přesně převedou na celé číslo:
[bits 32]
%include "linux_macros.asm"
;-----------------------------------------------------------------------------
section .data
hex_message:
times 8 db '?'
db ' '
hex_message_length equ $ - hex_message
align 16
sse_val_1 dd 2.0, 3.0, 4.0, 5.0
sse_val_2 dd 10.0, 20.0, 30.0, 40.0
;-----------------------------------------------------------------------------
section .bss
sse_tmp resb 16
;-----------------------------------------------------------------------------
section .text
global _start ; tento symbol ma byt dostupny i linkeru
_start:
mov ebx, sse_val_1
movaps xmm0, [ebx] ; nacteni prvni hodnoty do registru XMM0
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
cvtss2si eax, xmm0 ; konverze jednoho prvku
print_hex eax, 10
mov ebx, sse_val_2
movaps xmm0, [ebx] ; nacteni prvni hodnoty do registru XMM0
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
cvtss2si eax, xmm0 ; konverze jednoho prvku
print_hex eax, 10
exit ; ukonceni procesu
%include "hex2string.asm"
Výsledky, k nimž jsou dopsány komentáře:
vstup: 40A00000 40800000 40400000 40000000 (5,0 4,0 3,0 2,0) výsledek: 00000002 = 2 (int32) vstup: 42200000 41F00000 41A00000 41200000 (40,0 30,0 20,0 10,0) výsledek: 0000000A = 10 (int32)
10. Konverze hodnot, které nelze přesně převést na celé číslo
Některé hodnoty typu single pochopitelně není možné převést na celé číslo se zachováním přesnosti – minimálně dojde k zaokrouhlení a/nebo ořezání hodnot. Zajímavé bude zjistit, jaké je výchozí chování SSE v případě, že nenastavíme odlišný zaokrouhlovací režim. Pokusíme se o postupný převod trojice hodnot 2,4, 2,5 a 2,6 a necháme si vypsat výslednou celočíselnou hodnotu:
[bits 32]
%include "linux_macros.asm"
;-----------------------------------------------------------------------------
section .data
hex_message:
times 8 db '?'
db ' '
hex_message_length equ $ - hex_message
align 16
sse_val_1 dd 2.4, 0.0, 0.0, 0.0
sse_val_2 dd 2.5, 0.0, 0.0, 0.0
sse_val_3 dd 2.6, 0.0, 0.0, 0.0
;-----------------------------------------------------------------------------
section .bss
sse_tmp resb 16
;-----------------------------------------------------------------------------
section .text
global _start ; tento symbol ma byt dostupny i linkeru
_start:
mov ebx, sse_val_1
movaps xmm0, [ebx] ; nacteni prvni hodnoty do registru XMM0
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
cvtss2si eax, xmm0 ; konverze jednoho prvku
print_hex eax, 10
mov ebx, sse_val_2
movaps xmm0, [ebx] ; nacteni prvni hodnoty do registru XMM0
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
cvtss2si eax, xmm0 ; konverze jednoho prvku
print_hex eax, 10
mov ebx, sse_val_3
movaps xmm0, [ebx] ; nacteni prvni hodnoty do registru XMM0
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
cvtss2si eax, xmm0 ; konverze jednoho prvku
print_hex eax, 10
exit ; ukonceni procesu
%include "hex2string.asm"
Po překladu a spuštění tohoto demonstračního příkladu se nejdříve vždy vypíše původní obsah registru XMM, v jehož nejnižším členu je uložena hodnota, která se má zkonvertovat. A na dalším řádku je zobrazena výsledná celočíselná hodnota:
00000000 00000000 00000000 4019999A = 2,4 (nepřesně, ve skutečnosti je hodnota větší) 00000002 00000000 00000000 00000000 40200000 = 2,5 (přesně) 00000002 00000000 00000000 00000000 40266666 = 2,6 (nepřesně, ve skutečnosti je hodnota menší) 00000003
Zajímavý je především způsob konverze hodnoty 2,5, která je převedena na dvojku a nikoli na trojku, jak bychom možná očekávali.
11. Konverze speciálních FP hodnot na celá čísla
Problém zaokrouhlení při konverzi hodnot typu single na celá čísla je zřejmý. Ovšem ještě nás bude zajímat chování SSE subsystému ve chvíli, kdy se pokusíme o převod zvláštních (speciálních) FP hodnot na celá čísla. A o jaké hodnoty se jedná? Především o nekonečna a taktéž o obě varianty NaN. Pro reprezentaci těchto hodnot existuje v Netwide assembleru sada maker, která využijeme v dalším demonstračním příkladu, jehož zdrojový kód vypadá následovně:
[bits 32]
%include "linux_macros.asm"
;-----------------------------------------------------------------------------
section .data
hex_message:
times 8 db '?'
db ' '
hex_message_length equ $ - hex_message
align 16
sse_val_1 dd __Infinity__, 0.0, 0.0, 0.0
sse_val_2 dd __NaN__, 0.0, 0.0, 0.0
sse_val_3 dd __QNaN__, 0.0, 0.0, 0.0
;-----------------------------------------------------------------------------
section .bss
sse_tmp resb 16
;-----------------------------------------------------------------------------
section .text
global _start ; tento symbol ma byt dostupny i linkeru
_start:
mov ebx, sse_val_1
movaps xmm0, [ebx] ; nacteni prvni hodnoty do registru XMM0
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
cvtss2si eax, xmm0 ; konverze jednoho prvku
print_hex eax, 10
mov ebx, sse_val_2
movaps xmm0, [ebx] ; nacteni prvni hodnoty do registru XMM0
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
cvtss2si eax, xmm0 ; konverze jednoho prvku
print_hex eax, 10
mov ebx, sse_val_3
movaps xmm0, [ebx] ; nacteni prvni hodnoty do registru XMM0
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
cvtss2si eax, xmm0 ; konverze jednoho prvku
print_hex eax, 10
exit ; ukonceni procesu
%include "hex2string.asm"
Opět se podívejme na výsledky, které jsou navíc okomentovány:
00000000 00000000 00000000 7F800000 = nekonečno 80000000 00000000 00000000 00000000 7FC00000 = NaN 80000000 00000000 00000000 00000000 7FC00000 = NaN 80000000
Všechny tři speciální FP hodnoty byly převedeny na 0×80000000 (což je hodnota –2147483648, tedy nejmenší celé 32bitové číslo v reprezentaci ve dvojkovém doplňku), což odpovídá chování SSE subsystému v případě, že je zakázáno vyhození výjimky pro nepovolené operace.
12. Řídicí a stavový registr MXCSR
Chování subsystému SSE je ovládáno obsahem řídicího a stavového registru nazvaného MXCSR. Jedná se o 32bitový registr, který obsahuje jak bity ovlivňující konverzi hodnot, zaokrouhlovací režimy atd., tak i několik příznakových bitů, z nichž je možné zjistit, zda například nedošlo k přetečení výsledků nebo k dělení nulou. Podívejme se nyní na význam jednotlivých bitů uložených v tomto registru:
| Bit | Označení | Stručný popis |
|---|---|---|
| 31 | × | rezervováno |
| 30 | × | rezervováno |
| 29 | × | rezervováno |
| 28 | × | rezervováno |
| 27 | × | rezervováno |
| 26 | × | rezervováno |
| 25 | × | rezervováno |
| 24 | × | rezervováno |
| 23 | × | rezervováno |
| 22 | × | rezervováno |
| 21 | × | rezervováno |
| 20 | × | rezervováno |
| 19 | × | rezervováno |
| 18 | × | rezervováno |
| 17 | × | rezervováno |
| 16 | × | rezervováno |
| 15 | FZ | namísto denormalizované hodnoty se vrací nula |
| 14 | RC | zaokrouhlovací režim |
| 13 | RC | zaokrouhlovací režim |
| 12 | PM | maska pro výjimku při snížené přesnosti |
| 11 | UM | maska pro výjimku při podtečení |
| 10 | OM | maska pro výjimku při přetečení |
| 9 | ZM | maska pro výjimku při dělení nulou |
| 8 | DM | maska pro výjimku při denormalizované hodnotě |
| 7 | IM | maska pro výjimku u neplatné operace |
| 6 | × | rezervováno |
| 5 | PE | příznak snížené přesnosti výsledku |
| 4 | UE | příznak podtečení |
| 3 | OR | příznak přetečení |
| 2 | ZE | příznak dělení nulou |
| 1 | DE | příznak denormalizované hodnoty |
| 0 | IE | příznak neplatné operace |
Příznaky jsou takzvaně sticky tj. po jejich nastavení je nutné je explicitně vynulovat instrukcí LDMXCSR (resp. načíst takovou hodnotu, která zajistí, že budou vynulovány). To umožňuje provést sekvenci FP/SIMD operací a až na konci otestovat, zda nedošlo k problematickým výpočtům.
13. Přečtení obsahu registru MXCSR
Přečtení hodnoty z registru MXCSR je snadné, ovšem musíme si uvědomit, že cílovým operandem musí být adresa v paměti a nikoli například nějaký univerzální registr mikroprocesoru. V následujícím demonstračním příkladu získáme hodnotu tohoto registru a necháme si ji vytisknout. Hodnota bude uložena od adresy csr_value:
[bits 32]
%include "linux_macros.asm"
;-----------------------------------------------------------------------------
section .data
hex_message:
times 8 db '?'
db ' '
hex_message_length equ $ - hex_message
;-----------------------------------------------------------------------------
section .bss
csr_value resb 16
;-----------------------------------------------------------------------------
section .text
global _start ; tento symbol ma byt dostupny i linkeru
_start:
mov ebx, csr_value ; adresa s místem pro uložení obsahu registru MXCSR
stmxcsr [ebx] ; uložení hodnoty MXCSR
mov eax, [ebx]
print_hex eax, 10
exit ; ukonceni procesu
%include "hex2string.asm"
Výsledkem by měla být tato výchozí hodnota:
00001F80
14. Zápis do registru MXCSR
Opakem instrukce STMXCSR je instrukce nazvaná LDMXCSR, která přečte hodnotu z paměti a uloží ji do registru MXCSR. Používá se k obnovení předchozího nastavení atd. Použití této instrukce je snadné, jak je to ostatně patrné i z následujícího příkladu:
[bits 32]
%include "linux_macros.asm"
;-----------------------------------------------------------------------------
section .data
csr_reset: dd 0x1f80
;-----------------------------------------------------------------------------
section .bss
;-----------------------------------------------------------------------------
section .text
global _start ; tento symbol ma byt dostupny i linkeru
_start:
mov ebx, csr_reset ; adresa s obsahem registru MXCSR
ldmxcsr [ebx] ; načtení nové hodnoty
exit ; ukonceni procesu
%include "hex2string.asm"
15. Nastavení režimu zaokrouhlování
Dvojice bitů s indexy 13 a 14 uložených v registru MXCSR řídí způsob zaokrouhlování hodnot. Možné jsou tyto čtyři varianty:
| Maska | Význam |
|---|---|
| 0×0000 | nejbližší reprezentovatelná hodnota (pravé zaokrouhlování) |
| 0×2000 | zaokrouhlování směrem k zápornému nekonečnu |
| 0×4000 | zaokrouhlování směrem ke kladnému nekonečnu |
| 0×6000 | zaokrouhlování směrem k nule (z obou směrů) |
16. Denormalizované hodnoty vs. nula
Bitem číslo 15 uloženým v registru MXCSR se řídí způsob práce s denormalizovanými hodnotami, tedy s hodnotami, u nichž není možné nejvyšší bit mantisy mít nastaven na jedničku (exponent je už příliš malý). Tímto bitem lze určit, zda se má v těchto případech do výsledku uložit denormalizovaná hodnota nebo přímo nulová hodnota. Připomeňme si, že tento způsob práce s denormalizovanými hodnotami klasický FPU nedokáže přímo realizovat, i když se pro některé účely jedná o praktické řešení.
17. Příloha: doplnění příkladu ukazujícího kódování všech SSE instrukcí
Již naposledy si ukážeme demonstrační příklad, který sice jako celek postrádá smysl (protože se jedná pouze o náhodnou sekvenci instrukcí), ovšem ukazuje, jakým způsobem jsou zakódovány instrukce SSE. Nově jsem do tohoto příkladu přidal konverzní instrukce a zejména instrukce pro proložení prvků vektorů, shuffling (přeskládání) prvků atd.:
[bits 32]
;-----------------------------------------------------------------------------
section .text
movups xmm0, [ebx] ; nacteni hodnoty do registru XMM0
movaps xmm0, [ebx] ; nacteni hodnoty do registru XMM0
movups xmm0, xmm1 ; prenosy mezi registry
addps xmm0, xmm1 ; soucet prvku vektoru
subps xmm0, xmm1 ; rozdil prvku vektoru
mulps xmm0, xmm1 ; soucin prvku vektoru
divps xmm0, xmm1 ; podil prvku vektoru
maxps xmm0, xmm1 ; vyber vetsich prvku
minps xmm0, xmm1 ; vyber mensich prvku
sqrtps xmm0, xmm0 ; vypocet druhe odmocniny
rcpps xmm0, xmm0 ; vypocet prevracenych hodnot
addss xmm0, xmm1 ; skalarni soucet
subss xmm0, xmm1 ; rozdil skalaru
mulss xmm0, xmm1 ; soucin skalaru
divss xmm0, xmm1 ; podil skalaru
maxss xmm0, xmm1 ; vyber vetsich skalaru
maxss xmm0, xmm1 ; vyber mensich skalaru
cmpeqps xmm0, xmm1 ; porovnani prvku vektoru
cmpltps xmm0, xmm1 ; porovnani prvku vektoru
cmpleps xmm0, xmm1 ; porovnani prvku vektoru
cmpunordps xmm0, xmm1 ; porovnani prvku vektoru
cmpneqps xmm0, xmm1 ; porovnani prvku vektoru
cmpnltps xmm0, xmm1 ; porovnani prvku vektoru
cmpnleps xmm0, xmm1 ; porovnani prvku vektoru
cmpordps xmm0, xmm1 ; porovnani prvku vektoru
unpckhps xmm0, xmm1 ; prolozeni prvku dvou vektoru
unpcklps xmm0, xmm1 ; prolozeni prvku dvou vektoru
shufps xmm0, xmm1, 0b11111111 ; prolozeni prvku dvou vektoru
cvtsi2ss xmm0, eax ; konverze jednoho prvku
cvtss2si eax, xmm0 ; konverze jednoho prvku
ldmxcsr [ebx] ; načtení nové hodnoty
stmxcsr [ebx] ; uložení hodnoty MXCSR
Jednotlivé instrukce z tohoto umělého příkladu se přeloží do strojového kódu následujícím způsobem:
14 section .text
15 00000000 0F1003 movups xmm0, [ebx] ; nacteni hodnoty do registru XMM0
16 00000003 0F2803 movaps xmm0, [ebx] ; nacteni hodnoty do registru XMM0
17 00000006 0F10C1 movups xmm0, xmm1 ; prenosy mezi registry
18
19 00000009 0F58C1 addps xmm0, xmm1 ; soucet prvku vektoru
20 0000000C 0F5CC1 subps xmm0, xmm1 ; rozdil prvku vektoru
21 0000000F 0F59C1 mulps xmm0, xmm1 ; soucin prvku vektoru
22 00000012 0F5EC1 divps xmm0, xmm1 ; podil prvku vektoru
23 00000015 0F5FC1 maxps xmm0, xmm1 ; vyber vetsich prvku
24 00000018 0F5DC1 minps xmm0, xmm1 ; vyber mensich prvku
25 0000001B 0F51C0 sqrtps xmm0, xmm0 ; vypocet druhe odmocniny
26 0000001E 0F53C0 rcpps xmm0, xmm0 ; vypocet prevracenych hodnot
27
28 00000021 F30F58C1 addss xmm0, xmm1 ; skalarni soucet
29 00000025 F30F5CC1 subss xmm0, xmm1 ; rozdil skalaru
30 00000029 F30F59C1 mulss xmm0, xmm1 ; soucin skalaru
31 0000002D F30F5EC1 divss xmm0, xmm1 ; podil skalaru
32 00000031 F30F5FC1 maxss xmm0, xmm1 ; vyber vetsich skalaru
33 00000035 F30F5FC1 maxss xmm0, xmm1 ; vyber mensich skalaru
34
35 00000039 0FC2C100 cmpeqps xmm0, xmm1 ; porovnani prvku vektoru
36 0000003D 0FC2C101 cmpltps xmm0, xmm1 ; porovnani prvku vektoru
37 00000041 0FC2C102 cmpleps xmm0, xmm1 ; porovnani prvku vektoru
38 00000045 0FC2C103 cmpunordps xmm0, xmm1 ; porovnani prvku vektoru
39 00000049 0FC2C104 cmpneqps xmm0, xmm1 ; porovnani prvku vektoru
40 0000004D 0FC2C105 cmpnltps xmm0, xmm1 ; porovnani prvku vektoru
41 00000051 0FC2C106 cmpnleps xmm0, xmm1 ; porovnani prvku vektoru
42 00000055 0FC2C107 cmpordps xmm0, xmm1 ; porovnani prvku vektoru
43
44 00000059 0F15C1 unpckhps xmm0, xmm1 ; prolozeni prvku dvou vektoru
45 0000005C 0F14C1 unpcklps xmm0, xmm1 ; prolozeni prvku dvou vektoru
46 0000005F 0FC6C1FF shufps xmm0, xmm1, 0b11111111 ; prolozeni prvku dvou vektoru
47
48 00000063 F30F2AC0 cvtsi2ss xmm0, eax ; konverze jednoho prvku
49 00000067 F30F2DC0 cvtss2si eax, xmm0 ; konverze jednoho prvku
50
51 0000006B 0FAE13 ldmxcsr [ebx] ; načtení nové hodnoty
52 0000006E 0FAE1B stmxcsr [ebx] ; uložení hodnoty MXCSR
18. Seznam všech popsaných instrukcí SSE
Následuje seznam všech popsaných instrukcí SSE, který se od předchozích dvou článků rozšířil:
| # | Instrukce | Stručný popis instrukce |
|---|---|---|
| 1 | MOVUPS | načtení či zápis 128bitové hodnoty do oblasti paměti, která nemusí být zarovnaná |
| 2 | MOVAPS | načtení či zápis 128bitové hodnoty do paměti, která musí být zarovnaná |
| 3 | ADDSS | součet dolních 32bitů 128bitového vektoru; tyto bity jsou chápány jako hodnota single |
| 4 | ADDPS | součet čtveřice 32bitových hodnot typu single uložených ve 128bitových vektorech |
| 5 | SUBSS | rozdíl dolních 32bitů 128bitového vektoru; tyto bity jsou chápány jako hodnota single |
| 6 | SUBPS | rozdíl čtveřice 32bitových hodnot typu single uložených ve 128bitových vektorech |
| 7 | MULSS | součin dolních 32bitů 128bitového vektoru; tyto bity jsou chápány jako hodnota single |
| 8 | MULPS | součin čtveřice 32bitových hodnot typu single uložených ve 128bitových vektorech |
| 9 | DIVSS | podíl dolních 32bitů 128bitového vektoru; tyto bity jsou chápány jako hodnota single |
| 10 | DIVPS | podíl čtveřice 32bitových hodnot typu single uložených ve 128bitových vektorech |
| 11 | MAXPS | výběr větší hodnoty z každé porovnávané dvojice |
| 12 | MINPS | výběr menší hodnoty z každé porovnávané dvojice |
| 13 | SQRTPS | výpočet druhé odmocniny všech čtyř prvků vstupního vektoru |
| 14 | RCPPS | přibližný výpočet převrácené hodnoty všech čtyř prvků vstupního vektoru |
| 15 | CMPEQPS | porovnání příslušných dvojic prvků vektorů na relaci „je rovno“ |
| 16 | CMPLTPS | porovnání příslušných dvojic prvků vektorů na relaci „menší než“ |
| 17 | CMPLEPS | porovnání příslušných dvojic prvků vektorů na relaci „menší nebo rovno“ |
| 18 | CMPUNORDPS | zjištění, zda jsou dvojice prvků vektorů porovnatelné |
| 19 | CMPNEQPS | porovnání příslušných dvojic prvků vektorů na negaci relace „je rovno“ |
| 20 | CMPNLTPS | porovnání příslušných dvojic prvků vektorů na negaci relace „menší než“ |
| 21 | CMPNLEPS | porovnání příslušných dvojic prvků vektorů na negaci relace „menší nebo rovno“ |
| 22 | CMPORDPS | zjištění, zda jsou dvojice prvků vektorů porovnatelné |
| 23 | CVTSI2SS | konverze 1×32bitový integer v paměti či pracovním registru → 1×32bitový single |
| 24 | CVTSS2SI | konverze 1×32bitový single → 1×32bitový integer v pracovním registru (CPU) |
| 25 | CVTTSS2SI | konverze 1×32bitový single → 1×32bitový integer (odseknutí desetinné části) v pracovním registru |
| 26 | CVTPI2PS | konverze 2×32bitový integer → 2×32bitový single |
| 27 | CVTPS2PI | konverze 2×32bitový single → 2×32bitový integer |
| 28 | CVTTPS2PI | konverze 2×32bitový single → 2×32bitový integer (odseknutí desetinné části) v MMX registru |
| 29 | UNPCKHPS | proložení prvků dvou vektorů, použijí se jen vyšší dvojice prvků z každého vektoru |
| 30 | UNPCKLPS | proložení prvků dvou vektorů, použijí se jen nižší dvojice prvků z každého vektoru |
| 31 | SHUFPS | shuffling a promíchání prvků dvou vektorů |
| 32 | LDMXCSR | načtení nové hodnoty do stavového a řídicího registru MXCSR z paměti |
| 33 | STMXCSR | uložení hodnoty stavového a řídicího registru MXCSR do paměti |
19. Repositář s demonstračními příklady
Demonstrační příklady napsané v assembleru, které jsou určené pro překlad s využitím assembleru NASM, byly uloženy do Git repositáře, který je dostupný na adrese https://github.com/tisnik/8bit-fame. Jednotlivé demonstrační příklady si můžete v případě potřeby stáhnout i jednotlivě bez nutnosti klonovat celý (dnes již poměrně rozsáhlý) repositář:
| # | Příklad | Stručný popis | Adresa |
|---|---|---|---|
| 1 | hello.asm | program typu „Hello world“ naprogramovaný v assembleru pro systém DOS | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hello.asm |
| 2 | hello_shorter.asm | kratší varianta výskoku z procesu zpět do DOSu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hello_shorter.asm |
| 3 | hello_wait.asm | čekání na stisk klávesy | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hello_wait.asm |
| 4 | hello_macros.asm | realizace jednotlivých částí programu makrem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hello_macros.asm |
| 5 | gfx4_putpixel.asm | vykreslení pixelu v grafickém režimu 4 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_putpixel.asm |
| 6 | gfx6_putpixel.asm | vykreslení pixelu v grafickém režimu 6 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel.asm |
| 7 | gfx4_line.asm | vykreslení úsečky v grafickém režimu 4 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_line.asm |
| 8 | gfx6_line.asm | vykreslení úsečky v grafickém režimu 6 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_line.asm |
| 9 | gfx6_fill1.asm | vyplnění obrazovky v grafickém režimu, základní varianta | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_fill1.asm |
| 10 | gfx6_fill2.asm | vyplnění obrazovky v grafickém režimu, varianta s instrukcí LOOP | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_fill2.asm |
| 11 | gfx6_fill3.asm | vyplnění obrazovky instrukcí REP STOSB | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_fill3.asm |
| 12 | gfx6_fill4.asm | vyplnění obrazovky, synchronizace vykreslování s paprskem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_fill4.asm |
| 13 | gfx4_image1.asm | vykreslení rastrového obrázku získaného z binárních dat, základní varianta | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image1.asm |
| 14 | gfx4_image2.asm | varianta vykreslení rastrového obrázku s využitím instrukce REP MOVSB | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image2.asm |
| 15 | gfx4_image3.asm | varianta vykreslení rastrového obrázku s využitím instrukce REP MOVSW | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image3.asm |
| 16 | gfx4_image4.asm | korektní vykreslení všech sudých řádků bitmapy | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image4.asm |
| 17 | gfx4_image5.asm | korektní vykreslení všech sudých i lichých řádků bitmapy | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image5.asm |
| 18 | gfx4_image6.asm | nastavení barvové palety před vykreslením obrázku | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image6.asm |
| 19 | gfx4_image7.asm | nastavení barvové palety před vykreslením obrázku, snížená intenzita barev | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image7.asm |
| 20 | gfx4_image8.asm | postupná změna barvy pozadí | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image8.asm |
| 21 | gfx6_putpixel1.asm | vykreslení pixelu, základní varianta se 16bitovým násobením | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel1.asm |
| 22 | gfx6_putpixel2.asm | vykreslení pixelu, varianta s osmibitovým násobením | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel2.asm |
| 23 | gfx6_putpixel3.asm | vykreslení pixelu, varianta bez násobení | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel3.asm |
| 24 | gfx6_putpixel4.asm | vykreslení pixelu přes obrázek, nekorektní chování (přepis obrázku) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel4.asm |
| 25 | gfx6_putpixel5.asm | vykreslení pixelu přes obrázek, korektní varianta pro bílé pixely | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel5.asm |
| 26 | cga_text_mode1.asm | standardní textový režim s rozlišením 40×25 znaků | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_mode1.asm |
| 27 | cga_text_mode3.asm | standardní textový režim s rozlišením 80×25 znaků | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_mode3.asm |
| 28 | cga_text_mode_intensity.asm | změna významu nejvyššího bitu atributového bajtu: vyšší intenzita namísto blikání | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_mode_intensity.asm |
| 29 | cga_text_mode_cursor.asm | změna tvaru textového kurzoru | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_mode_cursor.asm |
| 30 | cga_text_gfx1.asm | zobrazení „rastrové mřížky“: pseudografický režim 160×25 pixelů (interně textový režim) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_gfx1.asm |
| 31 | cga_text_mode_char_height.asm | změna výšky znaků | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_mode_char_height.asm |
| 32 | cga_text_160×100.asm | grafický režim 160×100 se šestnácti barvami (interně upravený textový režim) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_160×100.asm |
| 33 | hercules_text_mode1.asm | využití standardního textového režimu společně s kartou Hercules | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_text_mode1.asm |
| 34 | hercules_text_mode2.asm | zákaz blikání v textových režimech | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_text_mode2.asm |
| 35 | hercules_turn_off.asm | vypnutí generování video signálu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_turn_off.asm |
| 36 | hercules_gfx_mode1.asm | přepnutí karty Hercules do grafického režimu (základní varianta) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_gfx_mode1.asm |
| 37 | hercules_gfx_mode2.asm | přepnutí karty Hercules do grafického režimu (vylepšená varianta) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_gfx_mode2.asm |
| 38 | hercules_putpixel.asm | subrutina pro vykreslení jediného pixelu na kartě Hercules | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_putpixel.asm |
| 39 | ega_text_mode_80×25.asm | standardní textový režim 80×25 znaků na kartě EGA | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_text_mode_80×25.asm |
| 40 | ega_text_mode_80×43.asm | zobrazení 43 textových řádků na kartě EGA | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_text_mode_80×43.asm |
| 41 | ega_gfx_mode_320×200.asm | přepnutí do grafického režimu 320×200 pixelů se šestnácti barvami | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_gfx_mode_320×200.asm |
| 42 | ega_gfx_mode_640×200.asm | přepnutí do grafického režimu 640×200 pixelů se šestnácti barvami | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_gfx_mode_640×200.asm |
| 43 | ega_gfx_mode_640×350.asm | přepnutí do grafického režimu 640×350 pixelů se čtyřmi nebo šestnácti barvami | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_gfx_mode_640×350.asm |
| 44 | ega_gfx_mode_bitplanes1.asm | ovládání zápisu do bitových rovin v planárních grafických režimech (základní způsob) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_gfx_mode_bitplanes1.asm |
| 45 | ega_gfx_mode_bitplanes2.asm | ovládání zápisu do bitových rovin v planárních grafických režimech (rychlejší způsob) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_gfx_mode_bitplanes2.asm |
| 46 | ega_320×200_putpixel.asm | vykreslení pixelu v grafickém režimu 320×200 pixelů se šestnácti barvami | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_320×200_putpixel.asm |
| 47 | ega_640×350_putpixel.asm | vykreslení pixelu v grafickém režimu 640×350 pixelů se šestnácti barvami | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_640×350_putpixel.asm |
| 48 | ega_standard_font.asm | použití standardního fontu grafické karty EGA | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_standard_font.asm |
| 49 | ega_custom_font.asm | načtení vlastního fontu s jeho zobrazením | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_custom_font.asm |
| 50 | ega_palette1.asm | změna barvové palety (všech 16 barev) v grafickém režimu 320×200 se šestnácti barvami | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_palette1.asm |
| 51 | ega_palette2.asm | změna barvové palety (všech 16 barev) v grafickém režimu 640×350 se šestnácti barvami | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_palette2.asm |
| 52 | ega_palette3.asm | změna všech barev v barvové paletě s využitím programové smyčky | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_palette3.asm |
| 53 | ega_palette4.asm | změna všech barev, včetně barvy okraje, v barvové paletě voláním funkce BIOSu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_palette4.asm |
| 54 | vga_text_mode_80×25.asm | standardní textový režim 80×25 znaků na kartě VGA | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_80×25.asm |
| 55 | vga_text_mode_80×50.asm | zobrazení 50 a taktéž 28 textových řádků na kartě VGA | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_80×50.asm |
| 56 | vga_text_mode_intensity1.asm | změna chování atributového bitu pro blikání (nebezpečná varianta změny registrů) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_intensity1.asm |
| 57 | vga_text_mode_intensity2.asm | změna chování atributového bitu pro blikání (bezpečnější varianta změny registrů) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_intensity2.asm |
| 58 | vga_text_mode_9th_column.asm | modifikace způsobu zobrazení devátého sloupce ve znakových režimech (720 pixelů na řádku) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_9th_column.asm |
| 59 | vga_text_mode_cursor_shape.asm | změna tvaru textového kurzoru na grafické kartě VGA | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_cursor_shape.asm |
| 60 | vga_text_mode_custom_font.asm | načtení vlastního fontu s jeho zobrazením | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_custom_font.asm |
| 61 | vga_gfx_mode_640×480.asm | přepnutí do grafického režimu 640×480 pixelů se šestnácti barvami, vykreslení vzorků | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_640×480.asm |
| 62 | vga_gfx_mode_320×200.asm | přepnutí do grafického režimu 320×200 pixelů s 256 barvami, vykreslení vzorků | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_320×200.asm |
| 63 | vga_gfx_mode_palette.asm | změna všech barev v barvové paletě grafické karty VGA | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_palette.asm |
| 64 | vga_gfx_mode_dac1.asm | využití DAC (neočekávané výsledky) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_dac1.asm |
| 65 | vga_gfx_mode_dac2.asm | využití DAC (očekávané výsledky) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_dac2.asm |
| 66 | vga_640×480_putpixel.asm | realizace algoritmu pro vykreslení pixelu v grafickém režimu 640×480 pixelů se šestnácti barvami | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_640×480_putpixel.asm |
| 67 | vga_320×200_putpixel1.asm | realizace algoritmu pro vykreslení pixelu v grafickém režimu 320×200 s 256 barvami (základní varianta) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_putpixel1.asm |
| 68 | vga_320×200_putpixel2.asm | realizace algoritmu pro vykreslení pixelu v grafickém režimu 320×200 s 256 barvami (rychlejší varianta) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_putpixel2.asm |
| 69 | vga_gfx_mode_dac3.asm | přímé využití DAC v grafickém režimu 13h | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_dac3.asm |
| 70 | vga_gfx_mode_unchained_step1.asm | zobrazení barevných pruhů v režimu 13h | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_unchained_step1.asm |
| 71 | vga_gfx_mode_unchained_step2.asm | vypnutí zřetězení bitových rovin a změna způsobu adresování pixelů | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_unchained_step2.asm |
| 72 | vga_gfx_mode_unchained_step3.asm | vykreslení barevných pruhů do vybraných bitových rovin | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_unchained_step3.asm |
| 73 | vga_gfx_mode_320×400.asm | nestandardní grafický režim s rozlišením 320×400 pixelů a 256 barvami | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_320×400.asm |
| 74 | vga_320×200_image.asm | zobrazení rastrového obrázku ve standardním grafickém režimu 320×200 pixelů | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_image.asm |
| 75 | vga_320×200_unchained_image1.asm | zobrazení rastrového obrázku v režimu s nezřetězenými rovinami (nekorektní řešení) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_unchained_image1.asm |
| 76 | vga_320×200_unchained_image2.asm | zobrazení rastrového obrázku v režimu s nezřetězenými rovinami (korektní řešení) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_unchained_image2.asm |
| 77 | vga_320×400_unchained_image.asm | zobrazení rastrového obrázku v nestandardním režimu 320×400 pixelů | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×400_unchained_image.asm |
| 78 | vga_vertical_scroll1.asm | vertikální scrolling na kartě VGA v režimu s rozlišením 320×200 pixelů | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_vertical_scroll1.asm |
| 79 | vga_vertical_scroll2.asm | vertikální scrolling na kartě VGA v režimu s rozlišením 320×400 pixelů | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_vertical_scroll2.asm |
| 80 | vga_split_screen1.asm | režim split-screen a scrolling, nefunční varianta | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_split_screen1.asm |
| 81 | vga_split_screen2.asm | režim split-screen a scrolling, plně funkční varianta | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_split_screen2.asm |
| 82 | vga_horizontal_scroll1.asm | horizontální scrolling bez rozšíření počtu pixelů na virtuálním řádku | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_horizontal_scroll1.asm |
| 83 | vga_horizontal_scroll2.asm | horizontální scrolling s rozšířením počtu pixelů na virtuálním řádku | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_horizontal_scroll2.asm |
| 84 | vga_horizontal_scroll3.asm | jemný horizontální scrolling s rozšířením počtu pixelů na virtuálním řádku | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_horizontal_scroll3.asm |
| 85 | vga_320×240_image.asm | nastavení grafického režimu Mode-X, načtení a vykreslení obrázku, scrolling | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×240_image.asm |
| 86 | io.asm | knihovna maker pro I/O operace | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/io.asm |
| 87 | vga_lib.asm | knihovna maker a podprogramů pro programování karty VGA | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_lib.asm |
| 88 | vga_320×240_lib.asm | nastavení grafického režimu Mode-X, tentokrát knihovními funkcemi | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×240_lib.asm |
| 89 | vga_bitblt1.asm | první (naivní) implementace operace BitBLT | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_bitblt1.asm |
| 90 | vga_bitblt2.asm | operace BitBLT s výběrem bitových rovin pro zápis | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_bitblt2.asm |
| 91 | vga_bitblt3.asm | operace BitBLT s výběrem bitových rovin pro čtení i zápis | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_bitblt3.asm |
| 92 | vga_bitblt4.asm | korektní BitBLT pro 16barevný režim, realizace makry | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_bitblt4.asm |
| 93 | vga_bitblt5.asm | korektní BitBLT pro 16barevný režim, realizace podprogramem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_bitblt5.asm |
| 94 | vga_bitblt_rotate.asm | zápisový režim s rotací bajtu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_bitblt_rotate.asm |
| 95 | vga_bitblt_fast.asm | rychlá korektní 32bitová operace typu BitBLT | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_bitblt_fast.asm |
| 96 | vga_320×400_bitblt1.asm | přenos obrázku v režimu 320×400 operací BitBLT (neúplná varianta) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×400_bitblt1.asm |
| 97 | vga_320×400_bitblt2.asm | přenos obrázku v režimu 320×400 operací BitBLT (úplná varianta) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×400_bitblt2.asm |
| 98 | vga_write_modes1.asm | volitelné zápisové režimy grafické karty VGA, zápis bez úpravy latche | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_write_modes1.asm |
| 99 | vga_write_modes2.asm | volitelné zápisové režimy grafické karty VGA, zápis s modifikací latche | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_write_modes2.asm |
| 100 | vga_write_modes3.asm | volitelné zápisové režimy grafické karty VGA, cílená modifikace latche vzorkem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_write_modes3.asm |
| 101 | instruction_jump.asm | použití instrukce JMP | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_jump.asm |
| 102 | instruction_jnz.asm | použití instrukce JNZ pro realizaci programové smyčky | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_jnz.asm |
| 103 | instruction_jz_jmp.asm | použití instrukcí JZ a JMP pro realizaci programové smyčky | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_jz_jmp.asm |
| 104 | instruction_loop.asm | použití instrukce LOOP pro realizaci programové smyčky | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_loop.asm |
| 105 | instruction_template.asm | šablona všech následujících demonstračních příkladů | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_template.asm |
| 106 | instruction_print_hex.asm | tisk osmibitové hexadecimální hodnoty | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_print_hex.asm |
| 107 | instruction_xlat.asm | využití instrukce XLAT pro získání tisknutelné hexadecimální cifry | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_xlat.asm |
| 108 | instruction_daa.asm | operace součtu s využitím binární i BCD aritmetiky | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_daa.asm |
| 109 | instruction_daa_sub.asm | instrukce DAA po provedení operace rozdílu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_daa_sub.asm |
| 110 | instruction_das.asm | instrukce DAS po provedení operace rozdílu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_das.asm |
| 111 | instruction_aaa.asm | korekce výsledku na jedinou BCD cifru operací AAA | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_aaa.asm |
| 112 | instruction_mul.asm | ukázka výpočtu součinu dvou osmibitových hodnot | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_mul.asm |
| 113 | instruction_aam.asm | BCD korekce po výpočtu součinu instrukcí AAM | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_aam.asm |
| 114 | instruction_stosb.asm | blokový zápis dat instrukcí STOSB | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_stosb.asm |
| 115 | instruction_rep_stosb.asm | opakované provádění instrukce STOSB | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_rep_stosb.asm |
| 116 | instruction_lodsb.asm | čtení dat instrukcí LODSB | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_lodsb.asm |
| 117 | instruction_movsb.asm | přenos jednoho bajtu instrukcí MOVSB | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_movsb.asm |
| 118 | instruction_rep_movsb.asm | blokový přenos po bajtech instrukcí MOVSB | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_rep_movsb.asm |
| 119 | instruction_rep_scas.asm | vyhledávání v řetězci instrukcí SCAS | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_rep_scas.asm |
| 120 | vga_320×200_image_0B.asm | výsledek blokového přenosu ve chvíli, kdy je CX=0 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_image_0B.asm |
| 121 | vga_320×200_image_64kB.asm | výsledek blokového přenosu ve chvíli, kdy je CX=0×ffff | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_image_64kB.asm |
| 122 | vga_320×200_image_movsb.asm | blokový přenos v rámci obrazové paměti instrukcí REP MOVSB | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_image_movsb.asm |
| 123 | vga_320×200_image_movsw.asm | blokový přenos v rámci obrazové paměti instrukcí REP MOVSW | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_image_movsw.asm |
| 124 | vga_320×200_image_movsd.asm | blokový přenos v rámci obrazové paměti instrukcí REP MOVSD | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_image_movsd.asm |
| 125 | vga_320×200_image_movsb_forward.asm | blokový přenos překrývajících se bloků paměti (zvyšující se adresy) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_image_movsb_forward.asm |
| 126 | vga_320×200_image_movsb_backward1.asm | blokový přenos překrývajících se bloků paměti (snižující se adresy, nekorektní nastavení) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_image_movsb_backward1.asm |
| 127 | vga_320×200_image_movsb_backward2.asm | blokový přenos překrývajících se bloků paměti (snižující se adresy, korektní nastavení) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_image_movsb_backward2.asm |
| 128 | sound_bell.asm | přehrání zvuku pomocí tisku ASCII znaku BELL | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_bell.asm |
| 129 | sound_beep.asm | přehrání zvuku o zadané frekvenci na PC Speakeru | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_beep.asm |
| 130 | sound_play_pitch.asm | přehrání zvuku o zadané frekvenci na PC Speakeru, použití maker | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_play_pitch.asm |
| 131 | sound_opl2_basic.asm | přehrání komorního A na OPL2 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl2_basic.asm |
| 132 | sound_opl2_table.asm | přehrání komorního A na OPL2, použití tabulky s hodnotami registrů | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl2_table.asm |
| 133 | sound_opl2_table2.asm | přepis tabulky s obsahy registrů pro přehrání komorního A | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl2_table2.asm |
| 134 | sound_key_on.asm | přímé ovládání bitu KEY ON mezerníkem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_key_on.asm |
| 135 | sound_adsr.asm | nastavení obálky pro tón přehrávaný prvním kanálem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_adsr.asm |
| 136 | sound_modulation.asm | řízení frekvence modulátoru klávesami 1 a 0 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_modulation.asm |
| 137 | keyboard_basic.asm | přímá práce s klávesnicí IBM PC | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/keyboard_basic.asm |
| 138 | sound_stereo_opl2.asm | stereo zvuk v konfiguraci DualOPL2 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_stereo_opl2.asm |
| 139 | sound_opl2_multichannel.asm | vícekanálový zvuk na OPL2 (klávesy), delší varianta | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl2_multichannel.asm |
| 140 | sound_opl2_multichannel2.asm | vícekanálový zvuk na OPL2 (klávesy), kratší varianta | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl2_multichannel2.asm |
| 141 | sound_opl3_stereo1.asm | stereo výstup na OPL3 (v kompatibilním režimu) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl3_stereo1.asm |
| 142 | sound_opl3_stereo2.asm | stereo výstup na OPL3 (v režimu OPL3) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl3_stereo2.asm |
| 143 | sound_opl3_multichannel.asm | vícekanálový zvuk na OPL3 (klávesy) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl3_multichannel.asm |
| 144 | sound_opl3_waveform1.asm | interaktivní modifikace tvaru vlny u prvního operátoru | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl3_waveform1.asm |
| 145 | sound_opl3_waveform2.asm | oprava chyby: povolení režimu kompatibilního s OPL3 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl3_waveform2.asm |
| 146 | sound_opl3_waveform3.asm | vliv tvaru vln na zvukový kanál s FM syntézou | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl3_waveform3.asm |
| 147 | sound_opl3_waveform4.asm | modifikace tvaru vlny nosné vlny i modulátoru | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl3_waveform4.asm |
| 148 | sound_opl3_4operators1.asm | výběr AM/FM režimu ve čtyřoperátorovém nastavení | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl3_4operators1.asm |
| 149 | sound_opl3_4operators2.asm | výběr AM/FM režimu ve čtyřoperátorovém nastavení | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl3_4operators2.asm |
| 150 | timer_basic.asm | základní obsluha přerušení od časovače/čítače | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/timer_basic.asm |
| 151 | timer_restore.asm | obnovení původní obsluhy přerušení při ukončování aplikace | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/timer_restore.asm |
| 152 | timer_restore_better_structure.asm | refaktoring předchozího demonstračního příkladu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/timer_restore_better_structure.asm |
| 153 | timer_faster_clock.asm | zrychlení čítače na 100 přerušení za sekundu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/timer_faster_clock.asm |
| 154 | instruction_push_imm.asm | instrukce PUSH s konstantou | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_push_imm.asm |
| 155 | instruction_imul_imm.asm | instrukce IMUL s konstantou | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_imul_imm.asm |
| 156 | instruction_into1.asm | instrukce INTO s obsluhou přerušení | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_into1.asm |
| 157 | instruction_into2.asm | instrukce INTO s obsluhou přerušení | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_into2.asm |
| 158 | instruction_bound1.asm | instrukce BOUND s obsluhou přerušení (nekorektní řešení) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_bound1.asm |
| 159 | instruction_bound2.asm | instrukce BOUND s obsluhou přerušení (korektní řešení) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_bound2.asm |
| 160 | vga_320×200_putpixel286.asm | instrukce bitového posunu s konstantou větší než 1 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_putpixel286.asm |
| 161 | instruction_push_pop.asm | instrukce PUSH a POP se všemi pracovními registry | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_push_pop.asm |
| 162 | instruction_push_pop_B.asm | instrukce s novými segmentovými registry | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_push_pop_B.asm |
| 163 | instruction_near_jz_jmp.asm | blízké skoky | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_near_jz_jmp.asm |
| 164 | instruction_bsf.asm | nová instrukce BSF | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_bsf.asm |
| 165 | instruction_bsr.asm | nová instrukce BSR | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_bsr.asm |
| 166 | instruction_add_32bit.asm | 32bitový součet | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_add_32bit.asm |
| 167 | instruction_inc_32bit.asm | 32bitová instrukce INC v šestnáctibitovém režimu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_inc_32bit.asm |
| 168 | instruction_inc_32bit_B.asm | 32bitová instrukce INC v 32bitovém režimu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_inc_32bit_B.asm |
| 169 | ems_status.asm | zjištění stavu (emulace) paměti EMS | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ems_status.asm |
| 170 | ems_total_mem.asm | získání celkové kapacity paměti EMS v blocích | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ems_total_mem.asm |
| 171 | ems_free_mem.asm | získání volné kapacity paměti EMS v blocích | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ems_free_mem.asm |
| 172 | xms_free_mem.asm | získání volné kapacity paměti XMS v blocích | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/xms_free_mem.asm |
| 173 | vga_320×200_short_address1.asm | blokový přenos provedený v rámci prostoru segmentu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_short_address1.asm |
| 174 | vga_320×200_short_address2.asm | rozepsaný blokový přenos provedený v rámci prostoru segmentu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_short_address2.asm |
| 175 | vga_320×200_short_address3.asm | přenos nelze provést přes hranici offsetu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_short_address3.asm |
| 176 | vga_320×200_short_address4.asm | přenos nelze provést přes hranici offsetu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_short_address4.asm |
| 177 | vga_320×200_long_address1.asm | 32bitový blokový přenos | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_long_address1.asm |
| 178 | vga_320×200_long_address2.asm | rozepsaný 32bitový blokový přenos provedený v rámci prostoru segmentu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_long_address2.asm |
| 179 | vga_320×200_long_address3.asm | přístup do obrazové paměti přes segment 0×0000 a 32bitový offset | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_long_address3.asm |
| 180 | vga_320×200_long_address4.asm | otestování, jak lze přenášet data s využitím 32bitového offsetu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_long_address4.asm |
| 181 | print_msw.asm | přečtení a zobrazení obsahu speciálního registru MSW | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/print_msw.asm |
| 182 | print_cr0.asm | přečtení a zobrazení obsahu speciálního registru CR0 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/print_cr0.asm |
| 183 | prot_mode286.asm | přechod do chráněného režimu na čipech Intel 80286 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/prot_mode286.asm |
| 184 | prot_mode386.asm | přechod do chráněného režimu na čipech Intel 80386 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/prot_mode386.asm |
| 185 | prot_mode_back_to_real_mode286.asm | přechod mezi reálným režimem a chráněným režimem i zpět na čipech Intel 80286 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/prot_mode_back_to_real_mode286.asm |
| 186 | prot_mode_back_to_real_mode386.asm | přechod mezi reálným režimem a chráněným režimem i zpět na čipech Intel 80386 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/prot_mode_back_to_real_mode386.asm |
| 187 | prot_mode_check.asm | test, zda se mikroprocesor již nachází v chráněném režimu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/prot_mode_check.asm |
| 188 | unreal_mode.asm | nastavení nereálného režimu (platné pro Intel 80386) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/unreal_mode.asm |
| 189 | float32_constants.asm | vytištění základních FP konstant typu single | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/float32_constants.asm |
| 190 | float64_constants.asm | vytištění základních FP konstant typu double | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/float64_constants.asm |
| 191 | fpu_arithmetic.asm | základní aritmetické operace prováděné matematickým koprocesorem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fpu_arithmetic.asm |
| 192 | fpu_divide_by_zero.asm | dělení nulou matematickým koprocesorem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fpu_divide_by_zero.asm |
| 193 | fpu_divide_by_neg_zero.asm | dělení záporné hodnoty nulou matematickým koprocesorem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fpu_divide_by_neg_zero.asm |
| 194 | fpu_divide_by_neg_zero2.asm | dělení hodnoty zápornou nulou matematickým koprocesorem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fpu_divide_by_neg_zero2.asm |
| 195 | fpu_divide_zero_by_zero.asm | výpočet 0/0 matematickým koprocesorem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fpu_divide_zero_by_zero.asm |
| 196 | io.asm | pomocná makra pro komunikaci s DOSem a BIOSem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/io.asm |
| 197 | print.asm | pomocná makra pro tisk FPU hodnot typu single a double v hexadecimálním tvaru | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/print.asm |
| 198 | fpu_divide.asm | operace podílu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fpu_divide.asm |
| 199 | fpu_divide_r.asm | operace podílu s prohozenými operandy | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fpu_divide_r.asm |
| 200 | fpu_sqrt.asm | výpočet druhé odmocniny | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fpu_sqrt.asm |
| 201 | fpu_sqrt_neg_value.asm | výpočet druhé odmocniny ze záporné hodnoty | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fpu_sqrt_neg_value.asm |
| 202 | fpu_check.asm | detekce typu matematického koprocesoru | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fpu_check.asm |
| 203 | fpu_compare.asm | porovnání dvou hodnot s vyhodnocením výsledku | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fpu_compare.asm |
| 204 | fpu_status_word.asm | tisk obsahu stavového slova koprocesoru | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fpu_status_word.asm |
| 205 | fpu_status_word_stack.asm | tisk obsahu stavového slova koprocesoru | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fpu_status_word_stack.asm |
| 206 | Makefile | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/Makefile | |
| 207 | hex2string.asm | subrutina pro převod 32bitové hexadecimální hodnoty na řetězec | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/hex2string.asm |
| 208 | linux_macros.asm | pomocná makra pro tvorbu aplikací psaných v assembleru pro Linux | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/linux_macros.asm |
| 209 | mmx_init.asm | inicializace subsystému MMX | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_init.asm |
| 210 | mmx_paddb1.asm | zavolání MMX instrukce pro součet vektorů bajtů (bez přetečení) | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_paddb1.asm |
| 211 | mmx_paddb2.asm | zavolání MMX instrukce pro součet vektorů bajtů (s přetečením) | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_paddb2.asm |
| 212 | mmx_paddusb.asm | zavolání MMX instrukce pro součet vektorů bajtů se saturací | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_paddusb.asm |
| 213 | mmx_paddw.asm | zavolání MMX instrukce pro součet vektorů šestnáctibitových slov | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_paddw.asm |
| 214 | mmx_paddd.asm | zavolání MMX instrukce pro součet vektorů 32bitových slov | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_paddd.asm |
| 215 | mmx_paddq.asm | zavolání MMX instrukce pro součet 64bitových slov | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_paddq.asm |
| 216 | mmx_paddx.asm | porovnání operací součtu pro vektory s prvky různých typů | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_paddx.asm |
| 217 | mmx_support.asm | zjištění, zda je MMX podporována | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_support.asm |
| 218 | mmx_paddx_saturation.asm | součet osmiprvkových a čtyřprvkových vektorů se saturací | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_paddx_saturation.asm |
| 219 | mmx_psubx.asm | rozdíl vektorů s různým počtem a šířkou prvků | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_psubx.asm |
| 220 | mmx_pmullw1.asm | součin vektorů prvek po prvku se získáním spodních 16 bitů výsledků (varianta bez přetečení) | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_pmullw1.asm |
| 221 | mmx_pmullw2.asm | součin vektorů prvek po prvku se získáním spodních 16 bitů výsledků (varianta s přetečením) | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_pmullw2.asm |
| 222 | mmx_pmulhw.asm | součin vektorů prvek po prvku se získáním horních 16 bitů výsledků (varianta s přetečením) | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_pmulhw.asm |
| 223 | mmx_pmaddwd.asm | součin vektorů prvek po prvku, součet mezivýsledků | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_pmaddwd.asm |
| 224 | mmx_logical.asm | logické instrukce MMX | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_logical.asm |
| 225 | mmx_shift_left.asm | logické posuny prvků vektorů doleva | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_shift_left.asm |
| 226 | mmx_shift_right.asm | logické posuny prvků vektorů doprava | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_shift_right.asm |
| 227 | mmx_arithmetic_right.asm | aritmetické posuny prvků vektorů doprava | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_arithmetic_right.asm |
| 228 | mmx_cmpeq.asm | porovnání prvků vektorů na rovnost | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_cmpeq.asm |
| 229 | mmx_cmpgt.asm | porovnání prvků vektorů na relaci „větší než“ | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_cmpgt.asm |
| 230 | mmx_unpack_bytes.asm | rozbalení bajtů z vektorů | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_unpack_bytes.asm |
| 231 | mmx_unpack_words.asm | rozbalení slov z vektorů | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_unpack_words.asm |
| 232 | mmx_unpack_dwords.asm | rozbalení dvojslov z vektorů | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_unpack_dwords.asm |
| 233 | mmx_pack_into_bytes1.asm | zabalení vektorů slov do vektoru bajtů | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_pack_into_bytes1.asm |
| 234 | mmx_pack_into_bytes2.asm | řešení přetečení při zabalování vektorů | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_pack_into_bytes2.asm |
| 235 | sse_support.asm | detekce, zda mikroprocesor podporuje instrukce SSE | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_support.asm |
| 236 | sse_instr_formats.asm | instrukční formát SSE | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_instr_formats.asm |
| 237 | sse_value_unaligned1.asm | načtení konstanty do XMM registru (nezarovnaná adresa) | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_value_unaligned1.asm |
| 238 | sse_value_unaligned2.asm | načtení konstanty do XMM registru (nezarovnaná adresa, ovšem vyžadováno je zarovnání) | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_value_unaligned2.asm |
| 239 | sse_value_aligned.asm | načtení konstanty do XMM registru (zarovnaná adresa) | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_value_aligned.asm |
| 240 | sse_addss.asm | skalární součet instrukcí ADDSS | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_addss.asm |
| 241 | sse_addps.asm | vektorový součet instrukcí ADDPS | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_addps.asm |
| 242 | sse_subss.asm | skalární rozdíl instrukcí SUBSS | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_subss.asm |
| 243 | sse_subps.asm | skalární rozdíl instrukcí SUBPS | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_subps.asm |
| 244 | sse_mulps.asm | součin prvků vektorů instrukcí MULPS | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_mulps.asm |
| 245 | sse_divps.asm | podíl prvků vektorů instrukcí DIVPS | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_divps.asm |
| 246 | sse_maxmin.asm | porovnání a výběr větších, resp. menších prvků z dvojice vektorů | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_maxmin.asm |
| 247 | sse_reciprocal.asm | přibližný výpočet převrácené hodnoty | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_reciprocal.asm |
| 248 | sse_sqrt.asm | výpočet druhé odmocniny prvků | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_sqrt.asm |
| 249 | sse_cmpeqps.asm | porovnání prvků vektorů na rovnost | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_cmpeqps.asm |
| 250 | sse_cmpltps.asm | porovnání prvků vektorů na relaci „menší než“ | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_cmpltps.asm |
| 251 | sse_inf_nan.asm | speciální hodnoty nekonečno a NaN v instrukčním souboru SSE | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_inf_nan.asm |
| 252 | sse_ordered.asm | zjištění, které prvky vektorů jsou porovnatelné | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_ordered.asm |
| 253 | sse_unpckhps.asm | proložení prvků dvou vektorů instrukcí UNPCKHPS | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_unpckhps.asm |
| 254 | sse_unpcklps.asm | proložení prvků dvou vektorů instrukcí UNPCKLPS | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_unpcklps.asm |
| 255 | sse_shufps.asm | použití instrukce SHUFPS | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_shufps.asm |
| 256 | sse_cvtsi2ss.asm | konverze celého čísla na hodnotu typu single | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_cvtsi2ss.asm |
| 257 | sse_cvtss2si.asm | konverze hodnoty typu single na celé číslo | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_cvtss2si.asm |
| 258 | sse_cvtss2si_fract.asm | konverze neceločíselných hodnot na celé číslo | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_cvtss2si_fract.asm |
| 258 | sse_cvtss2si_special.asm | konverze speciálních hodnot na celé číslo | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_cvtss2si_special.asm |
| 259 | sse_ldmxcsr.asm | načtení nové hodnoty do stavového a řídicího registru MXCSR z paměti | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_ldmxcsr.asm |
| 260 | sse_stmxcsr.asm | uložení hodnoty stavového a řídicího registru MXCSR do paměti | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_stmxcsr.asm |
20. Odkazy na Internetu
- The Intel 8088 Architecture and Instruction Set
https://people.ece.ubc.ca/~edc/464/lectures/lec4.pdf - x86 Opcode Structure and Instruction Overview
https://pnx.tf/files/x86_opcode_structure_and_instruction_overview.pdf - x86 instruction listings (Wikipedia)
https://en.wikipedia.org/wiki/X86_instruction_listings - x86 assembly language (Wikipedia)
https://en.wikipedia.org/wiki/X86_assembly_language - Intel Assembler (Cheat sheet)
http://www.jegerlehner.ch/intel/IntelCodeTable.pdf - 25 Microchips That Shook the World
https://spectrum.ieee.org/tech-history/silicon-revolution/25-microchips-that-shook-the-world - Chip Hall of Fame: MOS Technology 6502 Microprocessor
https://spectrum.ieee.org/tech-history/silicon-revolution/chip-hall-of-fame-mos-technology-6502-microprocessor - Chip Hall of Fame: Intel 8088 Microprocessor
https://spectrum.ieee.org/tech-history/silicon-revolution/chip-hall-of-fame-intel-8088-microprocessor - Jak se zrodil procesor?
https://www.root.cz/clanky/jak-se-zrodil-procesor/ - Apple II History Home
http://apple2history.org/ - The 8086/8088 Primer
https://www.stevemorse.org/8086/index.html - flat assembler: Assembly language resources
https://flatassembler.net/ - FASM na Wikipedii
https://en.wikipedia.org/wiki/FASM - Fresh IDE FASM inside
https://fresh.flatassembler.net/ - MS-DOS Version 4.0 Programmer's Reference
https://www.pcjs.org/documents/books/mspl13/msdos/dosref40/ - 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 - Bulldozer (microarchitecture)
https://en.wikipedia.org/wiki/Bulldozer_(microarchitecture) - MMX (instruction set)
https://en.wikipedia.org/wiki/MMX_(instruction_set) - Extended MMX
https://en.wikipedia.org/wiki/Extended_MMX - Saturation arithmetic
https://en.wikipedia.org/wiki/Saturation_arithmetic - CMPPS — Compare Packed Single Precision Floating-Point Values
https://www.felixcloutier.com/x86/cmpps - ADDPS — Add Packed Single Precision Floating-Point Values
https://www.felixcloutier.com/x86/addps - SUBPS — Subtract Packed Single Precision Floating-Point Values
https://www.felixcloutier.com/x86/subps - SQRTPS — Square Root of Single Precision Floating-Point Values
https://www.felixcloutier.com/x86/sqrtps - RSQRTPS — Compute Reciprocals of Square Roots of Packed Single Precision Floating-PointValues
https://www.felixcloutier.com/x86/rsqrtps - UNPCKHPS — Unpack and Interleave High Packed Single Precision Floating-Point Values
https://www.felixcloutier.com/x86/unpckhps - UNPCKLPS — Unpack and Interleave Low Packed Single Precision Floating-Point Values
https://www.felixcloutier.com/x86/unpcklps - SHUFPS — Packed Interleave Shuffle of Quadruplets of Single Precision Floating-Point Values
https://www.felixcloutier.com/x86/shufps - CVTSI2SS — Convert Doubleword Integer to Scalar Single Precision Floating-Point Value
https://www.felixcloutier.com/x86/cvtsi2ss - CVTSS2SI — Convert Scalar Single Precision Floating-Point Value to Doubleword Integer
https://www.felixcloutier.com/x86/cvtss2si - CVTTSS2SI — Convert With Truncation Scalar Single Precision Floating-Point Value to Integer
https://www.felixcloutier.com/x86/cvttss2si - CVTPI2PS — Convert Packed Dword Integers to Packed Single Precision Floating-Point Values
https://www.felixcloutier.com/x86/cvtpi2ps - CVTPS2PI — Convert Packed Single Precision Floating-Point Values to Packed Dword Integers
https://www.felixcloutier.com/x86/cvtps2pi - CVTTPS2PI — Convert With Truncation Packed Single Precision Floating-Point Values to PackedDword Integers
https://www.felixcloutier.com/x86/cvttps2pi