Obsah
1. Kvantitativní a kvalitativní vývoj mikroprocesorů z rodiny 80×86
2. První čtyři generace: od původního Intelu 8086 až k 80486DX4
3. Splňuje rodina 80×86 Moorův zákon?
4. Interní optimalizace: zlepšující se rychlost vykonávání instrukcí
5. Nové instrukce podporované čipem Intel 80186
7. Ukázka použití instrukce PUSH konstanta
9. Ukázka použití instrukcí PUSHA a POPA
10. Znaménkové násobení konstantou
11. Použití instrukce pro znaménkové násobení konstantou
12. Krátká odbočka: instrukce INTO
13. Provedení aritmetické operace s testem na přetečení výsledku
14. Instrukce BOUND pro test, zda index nepřesahuje meze pole
15. Naivní, ovšem nekorektní přerušovací rutina pro instrukci BOUND
16. Korektní varianta přerušovací rutiny pro instrukci BOUND
17. Bitové posuny a rotace o konstantu větší než 1
18. Nepodporované instrukce: POP CS
19. Repositář s demonstračními příklady
1. Kvantitativní a kvalitativní vývoj mikroprocesorů z rodiny 80×86
Prozatím jsme v tomto seriálu v naprosté většině demonstračních příkladů využívali instrukční sadu původních šestnáctibitových mikroprocesorů Intel 8086 a Intel 8088 (ty jsou z hlediska instrukcí i jejich délky prakticky totožné). Připomeňme si, že se dnes jedná o historické čipy, které byly na trh uvedeny v letech 1978 a 1979. O přibližně dva roky později použila společnost IBM mikroprocesor Intel 8088 jako základní prvek osobního mikropočítače IBM PC, z něhož se postupně vyvinula celá platforma PC, jež se dodnes vyvíjí a používá (se všemi výhodami a zápornými vlastnostmi tohoto vývoje).
Ovšem postupně se vyvíjely i mikroprocesory odvozené od původního poměrně primitivního Intelu 8086 (resp. jeho ořezané varianty Intel 8088). Rozšiřovala se instrukční sada o nové instrukce a adresovací režimy, přidávaly se nové pracovní registry, přidávaly se nové režimy činnosti mikroprocesoru (chráněný režim 286, odlišný chráněný režim 386, virtuální režim) atd. Ovšem současně se kromě těchto kvantitativních změn vylepšovala i interní architektura mikroprocesorů, což například vedlo k urychlení instrukcí. U řady instrukcí jsme tak postupně došli od jejich vykonání v několika desítkách strojových cyklů například na jediný strojový cyklus a poté na možnost dokončit v jednom cyklu více souběžně prováděných instrukcí.
2. První čtyři generace: od původního Intelu 8086 až k 80486DX4
V řadě x86 nalezneme několik desítek (dnes možná i několik set) různých mikroprocesorů. Zaměřme se tedy nejprve na první čtyři generace řady x86, která začíná již výše zmíněným mikroprocesorem Intel 8086 a končí mikroprocesorem 80486DX4, jenž je z pohledu frekvence přibližně dvacetkrát rychlejší, než původní 8086, ovšem díky optimalizacím ve skutečnosti dosahuje více než osmdesátinásobného(!) výpočetního výkonu v porovnání s první verzí 8086 (nehledě na to, že v 80486DX4 je i matematický koprocesor a rapidně se zvýšilo i množství adresovatelné paměti).
Podívejme se na následující tabulku, v níž jsou vypsány všechny důležité mikroprocesory řady x86 (neboli, pokud použijeme alternativní označení, rodiny 80×86) vyráběné společností Intel a patřící do prvních čtyř generací:
Mikroprocesor | Rok uvedení | Frekvence (MHz) | Tranzistorů | Poznámka |
---|---|---|---|---|
8086 | 1978 | 5, 8, 10 | 29000 | praotec celé rodiny 80×86 |
8088 | 1979 | 4,77 a 8 | 29000 | byl použit v původním IBM PC |
80186 | 1982 | 6 | 55000 | využíván jako mikrořadič, nikoli jako procesor v počítačích |
80188 | 1982 | 6 | 55000 | varianta 80186 s osmibitovou vnější sběrnicí |
80286 | 1982 | 6, 8, 12,5, 16, 20, 25 | 134000 | použit v PC AT |
80386DX | 1985 | 16, 20, 25, 33 | 275000 | první 32bitový čip z rodiny 80×86 |
80386SX | 1988 | 16, 20, 25, 33 | 275000 | varianta 80386DX se šestnáctibitovou datovou sběrnicí |
80386SL | 1990 | 20, 25 | 855000 | obsahuje i cache a řadiče sběrnice a paměti |
80486DX | 1989 | 25, 33, 50 | 1200000 | cca 50× výkonnější, než původní 8088 |
80486SX | 1991 | 16, 20, 25, 33 | 1185000 | bez povoleného matematického koprocesoru (nebo zcela bez FPU) |
80486DX2 | 1992 | 40, 50, 66 | 1185000 | dvojnásobná interní frekvence oproti frekvenci externí |
80486SL | 1992 | 20, 25, 33 | 1400000 | určeno pro notebooky |
80486DX4 | 1994 | 75, 100 | 1600000 | trojnásobná (!) interní frekvence oproti frekvenci externí |
3. Splňuje rodina 80×86 Moorův zákon?
Do tabulky uvedené v předchozí kapitole byly zapsány i přibližné počty tranzistorů u jednotlivých typů mikroprocesorů. Vzhledem k tomu, že se jedná o mikroprocesory společnosti Intel, jejímž zakladatelem je Gordon Moore, bude zajímavé zjistit, jestli i mikroprocesory řady x86 dobře odpovídají Moorovu zákonu, který říká (říkal), že každé dva roky dochází ke zdvojnásobení počtu tranzistorů na čipech s velkou integrací (a sem mikroprocesory pochopitelně spadají). Zkusme si tedy vykreslit grafy s počty tranzistorů u prvních čtyř generací mikroprocesorů řady x86 a současně teoretické počty tranzistorů odpovídajících Moorovu zákonu v případě, že v roce 1978 začneme s 10000 tranzistory resp. s 25000 tranzistory (začneme tedy o něco níže, než 29000 tranzistorů u původního Intelu 8086).
Zobrazíme si jak graf s lineárním měřítkem na vertikální ose, tak i přehlednější graf, který má na vertikální ose měřítko logaritmické:
Obrázek 1: Počet tranzistorů na mikroprocesorech rodiny 80×86 vs. Moorův zákon (lineární měřítko na y-ové ose).
Obrázek 2: Počet tranzistorů na mikroprocesorech rodiny 80×86 vs. Moorův zákon (logaritmické měřítko na y-ové ose).
4. Interní optimalizace: zlepšující se rychlost vykonávání instrukcí
Postupně rostoucí počet tranzistorů sám o sobě ovšem nic nevypovídá o skutečné rychlosti mikroprocesoru, protože do značné míry záleží na tom, jakým způsobem jsou tyto tranzistory využity. Postupně rostoucí kvalita implementace instrukcí (například přidáním nové specializované sčítačky pro výpočty adres, přidání fronty instrukcí, možnost takzvaného prefetchingu instrukcí, implementace RISCové pipeline atd.) vedla k tomu, že se postupně snižoval počet cyklů nutných pro dokončení instrukcí. To tedy znamená, že i když mohl být jak mikroprocesor Intel 8086, tak i Intel 80286 provozován na stejné frekvenci 8MHz, bude 80286 ve skutečnosti rychlejší. Ukažme si to například na základní instrukci součtu dvou osmibitových nebo šestnáctibitových hodnot – ADD. Délka výpočtů se odlišuje podle typů operandů a taktéž podle typu mikroprocesoru (čím menší číslo je v tabulce uvedeno, tím lépe):
Operandy | 8086/88 | 186 | 286 | 386 | 486 | Pentium |
---|---|---|---|---|---|---|
reg, reg | 3 | 3 | 2 | 2 | 1 | 1 |
mem, reg | 24+EA | 10 | 7 | 7 | 3 | 3 |
reg, mem | 13+EA | 10 | 7 | 6 | 2 | 2 |
reg, imm | 4 | 4 | 3 | 2 | 1 | 1 |
mem, imm | 23+EA | 16 | 7 | 7 | 3 | 3 |
acc, imm | 4 | 4 | 3 | 2 | 1 | 1 |
Přičemž u čipů 8086/8088 se přidává několik cyklů pro EA neboli pro výpočet efektivní adresy:
Adresování | Počet cyklů EA |
---|---|
reg+offset | 5 |
přímá adresa | 6 |
BP+DI nebo BX+SI | 7 |
BX+DI nebo BP+SI | 8 |
BP+DI+disp nebo BX+SI+disp | 11 |
BX+DI+disp nebo BP+SI+disp | 12 |
Navíc, pokud se mění (explicitně specifikuje) segmentový registr, je nutné přičíst další dva hodinové cykly.
5. Nové instrukce podporované čipem Intel 80186
Po mikroprocesorech Intel 8086 a Intel 8088 (1978 a 1979) následoval v roce 1982 mikroprocesor Intel 80186. Ten se používal spíše ve funkci mikrořadiče, takže z pohledu vývoje IBM PC je poněkud méně zajímavý. Ovšem důležité je, že právě do 80186 byly přidány některé instrukce, které v původní instrukční sadě relativně citelně chyběly. Jedná se o instrukce, o nichž se stále (chybně) píše jako o instrukcích přidaných až v 80286. Ovšem ve skutečnosti byly do 80286 přidány „jen“ instrukce související s chráněným režimem.
V následující tabulce jsou vypsány ty instrukce, které bylo možné použít již v mikroprocesoru 80186:
Instrukce | Operandy | Stručný popis |
---|---|---|
IMUL | konstanta | násobení se znaménkem se specifikací konstanty jako druhého operandu |
PUSH | konstanta | uložení šestnáctibitové hodnoty na zásobník |
PUSHA | uložení pracovních registrů na zásobník | |
POPA | obnovení pracovních registrů ze zásobníku | |
INS | (implicitní DX) | přečtení bajtu nebo slova z portu do ES, zvýšení DI |
OUTS | (implicitní DX) | zápis bajtu nebo slova z DS na port, zvýšení SI |
ENTER | size, počet | nastavení zásobníkového rámce |
LEAVE | obnovení SP a BP do doby před instrukcí ENTER | |
BOUND | registr, paměť | kontrola, zda hodnota uložená v registru nepřesahuje limity |
RCL/RCR/ROL/ROR/SHL/SHR/SAL/SAR | registr, konstanta | rotace nebo bitový posun o zadaný počet bitů doleva nebo doprava |
6. Instrukce PUSH konstanta
První novou instrukcí, s níž se dnes setkáme, je instrukce PUSH konstanta, což je varianta instrukce určené pro uložení nějaké hodnoty na zásobník. Původní čipy 8086/8088 podporovaly uložení obsahu libovolného šestnáctibitového registru, uložení obsahu segmentového registru nebo uložení šestnáctibitové hodnoty přečtené z paměti. Nová forma podporuje i uložení šestnáctibitové konstanty.
Instrukci PUSH, která dokáže na zásobník uložit šestnáctibitovou konstantu, můžeme použít například ve chvíli, kdy je zapotřebí konstantu přenést do nějakého segmentového registru. Taková operace by se mohla provést instrukcí MOV, jenže varianta MOV segment_registr, konstanta není dostupná, a to ani v dalších třech generacích čipů rodiny 80×86.
7. Ukázka použití instrukce PUSH konstanta
Podívejme se na příklad, který jsme si již v tomto seriálu ukazovali. Tento příklad po svém spuštění naplní obrazovou paměť v textovém režimu různými hodnotami znaků+atributů. Přitom se obrazová paměť adresuje přes segmentový registr ES. V původní variantě jsme prováděli naplnění ES takto:
mov ax, 0xb800 ; video RAM v textovem rezimu mov es, ax
Nyní provedeme odlišnou sekvenci operací a nezničíme si tak obsah registru AX (ovšem na úkor rychlosti – tato varianta trvá delší počet cyklů):
push 0xb800 ; video RAM v textovem rezimu pop es
Délka obou řešení je rozdílná, protože druhé řešení je o jeden bajt kratší:
B800B8 mov ax, 0xb800 8EC0 mov es, ax 6800B8 push 0xb800 07 pop es
Upravený zdrojový kód demonstračního příkladu vypadá následovně:
;----------------------------------------------------------------------------- BITS 16 ; 16bitovy vystup pro DOS CPU 286 ; specifikace pouziteho instrukcniho souboru ;----------------------------------------------------------------------------- ; ukonceni procesu a navrat do DOSu %macro exit 0 mov ah, 0x4c int 0x21 %endmacro ; vyprazdneni bufferu klavesnice a cekani na klavesu %macro wait_key 0 xor ax, ax int 0x16 %endmacro ; nastaveni grafickeho rezimu %macro gfx_mode 1 mov ah, 0 mov al, %1 int 0x10 %endmacro ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: gfx_mode 3 ; nastaveni standardniho textoveho rezimu 80x25 znaku push 0xb800 ; video RAM v textovem rezimu pop es mov di, 0 ; nyni ES:DI obsahuje adresu prvniho znaku ve video RAM mov cx, 80*25 ; pocet zapisovanych znaku mov al, 0 ; kod zapisovaneho znaku opak: stosb ; zapis znaku + atributu stosb inc al ; dalsi znak/atribut loop opak ; opakujeme CX-krat mov dx, 0x3d8 ; port s rizenim graficke palety mov al, 0x18 ; pozadi neblika, meni se intenzita out dx, al ; pres port 0x3d9 wait_key mov dx, 0x3d8 ; port s rizenim graficke palety mov al, 0x38 ; pozadi opet blika, nizka intenzita out dx, al ; pres port 0x3d9 wait_key wait_key ; cekani na klavesu exit ; navrat do DOSu
8. Instrukce PUSHA a POPA
V mnoha situacích se setkáme s nutností uložení většího množství registrů na zásobník. Tato operace trvá na 80186 deset cyklů a na 80286 tři cykly. Pokud je zapotřebí uložit více registrů, použije se více těchto instrukcí a časy se pochopitelně sčítají. Instrukce PUSHA naproti tomu uloží všechny pracovní registry v pořadí AX, CX, DX, BX, SP, BP, SI, DI a celková doba jejího trvání je 36 resp. 17 cyklů (v dalších generacích ještě méně).
Podobně instrukce POP jednoho registru trvá 10 resp. 5 cyklů pro každý registr, zatímco POPA provede obnovení registrů v pořadí DI, SI, BP, SP, BX, DX, CX, AX a celková doba jejího trvání je 51 resp. 19 cyklů. To znamená, že pokud ukládáme/obnovujeme čtyři nebo více registrů, je výhodnější použít PUSHA+POPA, což je i mnohem kratší řešení z pohledu délky strojového kódu.
9. Ukázka použití instrukcí PUSHA a POPA
S instrukcemi PUSHA a POPA jsme se setkali při programování obsluhy nějakého přerušení. Typická přerušovací rutina totiž na svém začátku uloží všechny v ní použité registry na zásobník a na konci je zase obnoví. V případě, že se nám nechce sledovat, které registry uložit (a poté obnovit) sekvencí instrukcí PUSH a posléze POP, nebo pokud je registrů větší množství, použijeme právě PUSHA a POPA. Připomeňme si, jak taková rutina může vypadat:
int8_handler: ; nova obsluha preruseni pusha ; ulozit vsechny registry print_char 't' ; t=tick mov al, 0x20 out 0x20, al ; oznameni, ze preruseni je u konce radici preruseni popa ; obnovit vsechny registry sti ; povoleni maskovatelnych preruseni iret ; navrat z preruseni
Způsob překladu do strojového kódu naznačuje, jak krátké (z pohledu obsazení paměti) tyto instrukce ve skutečnosti jsou:
int8_handler: ; nova obsluha preruseni 60 pusha ; ulozit vsechny registry print_char 't' ; t=tick B402 mov ah, 0x02 B274 mov dl, %1 CD21 int 0x21 B020 mov al, 0x20 E620 out 0x20, al ; oznameni, ze preruseni je u konce radici preruseni 61 popa ; obnovit vsechny registry FB sti ; povoleni maskovatelnych preruseni CF iret ; navrat z preruseni
10. Znaménkové násobení konstantou
Další nová varianta instrukce, se kterou jsme se mohli setkat u čipů Intel 80186 (a samozřejmě i u všech mikroprocesorů, které následovaly) je násobení se znaménkem, v podobě, kdy je druhým operandem konstanta a kdy je specifikován i registr, do kterého se má uložit výsledek. Jedná se o instrukci IMUL, která má velké množství variant. Vypišme si jen osmibitové a šestnáctibitové varianty. V poznámce je uvedeno, od jakého čipu jsou tyto varianty dostupné:
IMUL reg8 IMUL reg16 IMUL mem8 IMUL mem16 IMUL reg16, konstanta ; od 286 IMUL reg16, reg16, konstanta ; od 186 IMUL reg16, mem16, konstanta ; od 186 IMUL reg16, reg16 ; od 386 IMUL reg16, mem16 ; od 386
11. Použití instrukce pro znaménkové násobení konstantou
Vlastní použití instrukce IMUL reg16, reg16, konstanta je snadné, jak je to ostatně patrné i z následujícího demonstračního příkladu, v němž vynásobíme obsah registru BX dvěma, takže výsledkem bude hexadecimální hodnota 0×06:
; Instrukcni soubor mikroprocesoru Intel 80286. ; Test instrukce IMUL s konstantnim operandem. ; ;----------------------------------------------------------------------------- BITS 16 ; 16bitovy vystup pro DOS CPU 286 ; specifikace pouziteho instrukcniho souboru ; ukonceni procesu a navrat do DOSu %macro exit 0 ret %endmacro ; vyprazdneni bufferu klavesnice a cekani na klavesu %macro wait_key 0 xor ax, ax int 0x16 %endmacro ; tisk retezce na obrazovku %macro print 1 mov dx, %1 mov ah, 9 int 0x21 %endmacro ; tisk hexadecimalni hodnoty %macro print_hex 1 mov bx, hex_digits mov cl, %1 ; zapamatovat si predanou hodnotu mov al, cl ; do AL se vlozi horni hexa cifra and al, 0xf0 shr al, 1 shr al, 1 shr al, 1 shr al, 1 xlat ; prevod hodnoty 0-15 na ASCII znak mov [message], al ; zapis ASCII znaku do retezce mov al, cl ; do BL se vlozi dolni hexa cifra and al, 0x0f xlat ; prevod hodnoty 0-15 na ASCII znak mov [message + 1], al ; zapis ASCII znaku do retezce print message %endmacro ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: xor ax, ax ; výsledný registr mov bx, 0x03 ; první operand imul ax, bx, 2 ; násobení konstantou print_hex al ; výsledek je v AX wait_key exit ; retezec ukonceny znakem $ ; (tato data jsou soucasti vysledneho souboru typu COM) message db 0x01, 0x01, 0x0d, 0x0a, "$" ; prevodni tabulka hodnoty 0-15 na ASCII znak hex_digits db "0123456789abcdef"
Výše uvedená varianta IMUL je přeložena do tříbajtové sekvence:
58 00000000 31C0 xor ax, ax ; výsledný registr 59 00000002 BB0300 mov bx, 0x03 ; první operand 60 00000005 6BC302 imul ax, bx, 2 ; násobení konstantou
12. Krátká odbočka: instrukce INTO
Ještě před popisem dalších instrukcí, které byly přidány do instrukčního souboru mikroprocesoru Intel 80186 se na chvíli zastavme u instrukce původního Intelu 8086, kterou jsme si ještě nepopsali. Jedná se o instrukci nazvanou INTO, což je instrukce, jejíž mnemotechnická zkratka vznikla ze slov „(call) interrupt procedure if overflow“. Tato instrukce zkontroluje obsah příznakového bitu overflow (OF) a pokud je tento bit nastaven, vyvolá se přerušení číslo 4, tj. provede se vlastně instrukce INT 4. Tuto instrukci tedy může do programového kódu vkládat například překladač vyššího programovacího jazyka ve chvíli, kdy je povolena kontrola přetečení výsledků (příkladem může být Pascal atd.) a kdy se má vždy vyvolat stejná přerušovací rutina. Není tedy nutné provádět instrukce JO/JNO, které jsou zbytečně dlouhé, protože instrukce INTO je zakódována do jediného bajtu.
13. Provedení aritmetické operace s testem na přetečení výsledku
Vyzkoušejme si nyní, jak vlastně může vypadat obsluha přerušení, která vypíše nějaké hlášení ve chvíli, kdy při výpočtech dojde k přetečení:
int4_handler: ; obsluha preruseni cislo 4 pusha ; ulozit vsechny registry print overflow_msg popa ; obnovit vsechny registry sti ; povoleni maskovatelnych preruseni iret ; navrat z preruseni
Tuto přerušovací rutinu musíme pochopitelně zapsat do tabulky vektorů přerušení:
INT_4_VECTOR equ 4*4 ; adresa vektoru preruseni xor ax, ax mov es, ax mov di, INT_4_VECTOR ; ES:DI obsahuje adresu, na ktere je adresa obsluhy preruseni 4 cli ; zakaz preruseni lea ax, int4_handler ; zmena offsetove casti adresy mov es:[di], ax mov ax, cs ; zmena segmentove casti adresy mov es:[di+2], ax sti ; povoleni preruseni
A následně již můžeme po výpočtech použít instrukci INTO pro test, zda došlo k přetečení či nikoli:
mov al, 10 add al, al ; soucet dvou hodnot into ; test na preteceni -> vyvolani preruseni
popř.
mov al, 100 add al, al ; soucet dvou hodnot into ; test na preteceni -> vyvolani preruseni
14. Instrukce BOUND pro test, zda index nepřesahuje meze pole
Další instrukcí určenou primárně pro strojový kód generovaný překladači vyšších programovacích jazyků je instrukce nazvaná BOUND. Tato instrukce kontroluje, zda nějaký šestnáctibitový index uložený v libovolném pracovním registru nepřesahuje dolní nebo horní mez rozsahu pole, přičemž tento rozsah je uložen v operační paměti na specifikované adrese (první dva bajty obsahují dolní index, další dva bajty obsahují index horní). Představme si například zdrojový kód napsaný v Pascalu, v němž je možné specifikovat horní i dolní meze indexů polí:
arr : Array[10..20] Of Integer;
Povolené indexy tedy začínají od 10 a končí u 20. Pokud je pole v operační paměti uloženo takovým způsobem, že první čtyři bajty obsahují meze indexů polí (což je poměrně triviální a přitom praktický způsob uložení pole) a pokud je index, s nímž pracujeme, uložen například v registru AX, můžeme zkontrolovat, jestli je index korektní, takto:
bound ax, [pole]
V případě, že index leží v potřebném rozsahu, instrukce po 35(!) taktech skončí. Pokud však index leží mimo rozsah, vyvolá se přerušení INT 5 (nikoli INT 4, jako u INTO). A samozřejmě i na tuto skutečnost můžeme potřebným způsobem reagovat vlastní přerušovací rutinou.
15. Naivní, ovšem nekorektní přerušovací rutina pro instrukci BOUND
Zkusme si nyní zaregistrovat rutinu nazvanou int5_handler, která bude zavolána ve chvíli, kdy dojde k přerušení číslo 5, ať již vlivem instrukce INT 5 nebo nepřímo přes instrukci BOUND. Samotná registrace takové rutiny se nijak neliší od registrace rutiny pro přerušení číslo 4, pochopitelně se však bude provádět zápis na jiné místo tabulky přerušovacích vektorů:
INT_5_VECTOR equ 5*4 ; adresa vektoru preruseni xor ax, ax mov es, ax mov di, INT_5_VECTOR ; ES:DI obsahuje adresu, na ktere je adresa obsluhy preruseni 5 cli ; zakaz preruseni lea ax, int5_handler ; zmena offsetove casti adresy mov es:[di], ax mov ax, cs ; zmena segmentove casti adresy mov es:[di+2], ax sti ; povoleni preruseni
První verze rutiny s obsluhou přerušení může vypadat následovně – pouze vypíšeme zprávu „index out of bounds!“ a subrutinu následně ukončíme:
int5_handler: ; obsluha preruseni cislo 5 pusha ; ulozit vsechny registry print index_out_of_bounds_msg popa ; obnovit vsechny registry sti ; povoleni maskovatelnych preruseni iret ; navrat z preruseni -> nyni se vracime zpet na instrukci BOUND
Pokusme se nyní tuto subrutinu zavolat – index 100 leží mimo povolený rozsah 0 až 99:
mov ax, 100 ; nacteni indexu bound ax, [bounds] ; test indexu bounds dw 0, 99
Pokud takto upravený demonstrační příklad přeložíme a spustíme, začne se na terminál neustále dokola vypisovat zpráva:
index out of bounds! index out of bounds! index out of bounds! ... ... ...
Proč tomu tak je a jak bude možné tento příklad opravit, si řekneme v navazující kapitole. Nyní bude pro úplnost ukázán celý zdrojový kód tohoto demonstračního příkladu:
; Instrukcni soubor mikroprocesoru Intel 80286. ; Instrukce BOUND - nekorektni verze programu. ;----------------------------------------------------------------------------- BITS 16 ; 16bitovy vystup pro DOS CPU 286 ; specifikace pouziteho instrukcniho souboru INT_5_VECTOR equ 5*4 ; adresa vektoru preruseni ;----------------------------------------------------------------------------- ; ukonceni procesu a navrat do DOSu %macro exit 0 ret %endmacro ; vyprazdneni bufferu klavesnice a cekani na klavesu %macro wait_key 0 xor ax, ax int 0x16 %endmacro ; tisk retezce na obrazovku %macro print 1 mov dx, %1 mov ah, 9 int 0x21 %endmacro ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: xor ax, ax mov es, ax mov di, INT_5_VECTOR ; ES:DI obsahuje adresu, na ktere je adresa obsluhy preruseni 5 cli ; zakaz preruseni lea ax, int5_handler ; zmena offsetove casti adresy mov es:[di], ax mov ax, cs ; zmena segmentove casti adresy mov es:[di+2], ax sti ; povoleni preruseni mov ax, 100 ; nacteni indexu bound ax, [bounds] ; test indexu print done_msg ; vypis zpravy, ze koncime wait_key exit ; a skutecne skoncime int5_handler: ; obsluha preruseni cislo 5 pusha ; ulozit vsechny registry print index_out_of_bounds_msg popa ; obnovit vsechny registry sti ; povoleni maskovatelnych preruseni iret ; navrat z preruseni -> nyni se vracime zpet na instrukci BOUND ;----------------------------------------------------------------------------- bounds dw 0, 99 ; retezec ukonceny znakem $ ; (tato data jsou soucasti vysledneho souboru typu COM) index_out_of_bounds_msg db "index out of bounds!", 13, 10, "$" ; retezec ukonceny znakem $ ; (tato data jsou soucasti vysledneho souboru typu COM) done_msg db "done.", 13, 10, "$"
16. Korektní varianta přerušovací rutiny pro instrukci BOUND
Důvod, proč jsme se ocitli de facto v nekonečné smyčce, spočívá v tom, že instrukce BOUND před vyvoláním přerušovací rutiny uloží na zásobník adresu instrukce BOUND a nikoli adresu následující instrukce. To znamená, že po dokončení přerušovací rutiny instrukcí IRET se znovu provede test indexu 100 na meze 0..99 a znovu se vyvolá ta stejná subrutina. Musíme se tedy vrátit nikoli přímo na instrukci BOUND, ale za ni. Tato instrukce má délku čtyř bajtů (operační kód + bajt s určením registru + dva bajty s adresou), takže musíme ze zásobníku získat původní adresu a tu zvýšit o hodnotu 4. Jedno z možných řešení může vypadat následovně:
int5_handler: ; obsluha preruseni cislo 5 pusha ; ulozit vsechny registry print index_out_of_bounds_msg popa ; obnovit vsechny registry pop ax add ax, 4 ; preskocit samotnou instrukci BOUND push ax sti ; povoleni maskovatelnych preruseni iret ; navrat z preruseni -> nyni se ovsem vracime ZA instrukci BOUND
Nyní už by se při spuštění programu mělo na terminálu objevit pouze:
index out of bounds! done.
Následuje úplný výpis zdrojového kódu tohoto demonstračního příkladu:
; Instrukcni soubor mikroprocesoru Intel 80286. ; Instrukce BOUND - korektni verze programu. ;----------------------------------------------------------------------------- BITS 16 ; 16bitovy vystup pro DOS CPU 286 ; specifikace pouziteho instrukcniho souboru INT_5_VECTOR equ 5*4 ; adresa vektoru preruseni ;----------------------------------------------------------------------------- ; ukonceni procesu a navrat do DOSu %macro exit 0 ret %endmacro ; vyprazdneni bufferu klavesnice a cekani na klavesu %macro wait_key 0 xor ax, ax int 0x16 %endmacro ; tisk retezce na obrazovku %macro print 1 mov dx, %1 mov ah, 9 int 0x21 %endmacro ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: xor ax, ax mov es, ax mov di, INT_5_VECTOR ; ES:DI obsahuje adresu, na ktere je adresa obsluhy preruseni 5 cli ; zakaz preruseni lea ax, int5_handler ; zmena offsetove casti adresy mov es:[di], ax mov ax, cs ; zmena segmentove casti adresy mov es:[di+2], ax sti ; povoleni preruseni mov ax, 99 ; nacteni indexu bound ax, [bounds] ; test indexu mov ax, 100 ; nacteni indexu bound ax, [bounds] ; test indexu mov ax, 101 ; nacteni indexu bound ax, [bounds] ; test indexu print done_msg ; vypis zpravy, ze koncime wait_key exit ; a skutecne skoncime int5_handler: ; obsluha preruseni cislo 5 pusha ; ulozit vsechny registry print index_out_of_bounds_msg popa ; obnovit vsechny registry pop ax add ax, 4 ; preskocit samotnou instrukci BOUND push ax sti ; povoleni maskovatelnych preruseni iret ; navrat z preruseni -> nyni se ovsem vracime ZA instrukci BOUND ;----------------------------------------------------------------------------- bounds dw 0, 99 ; retezec ukonceny znakem $ ; (tato data jsou soucasti vysledneho souboru typu COM) index_out_of_bounds_msg db "index out of bounds!", 13, 10, "$" ; retezec ukonceny znakem $ ; (tato data jsou soucasti vysledneho souboru typu COM) done_msg db "done.", 13, 10, "$"
17. Bitové posuny a rotace o konstantu větší než 1
Mikroprocesory Intel 8086 a Intel 8088 podporovaly úplnou sadu instrukcí pro bitové posuny a rotace:
Instrukce | Význam |
---|---|
SHL | posun bitů doleva |
SAL | aritmetický posun bitů doleva (stejné jako předchozí instrukce) |
SHR | bitový posun doprava |
SAR | aritmetický posun doprava |
ROL | rotace doleva |
ROR | rotace doprava |
RCL | rotace doleva přes Carry |
RCR | rotace doprava přes Carry |
Posun či rotace je přitom provedena o jeden bit nebo o CL bitů (CL je spodních osm bitů registru CX). U mikroprocesorů 80186 byla navíc přidána možnost posunů a rotací o n bitů, kde n je celočíselná konstanta. Program je tedy možné zkrátit, ovšem pozor je nutné dát na to, že zatímco rotace/posun o jeden bit trvá 2 takty, rotace/posun o n bitů trvá 5+n taktů, což například v praxi znamená, že posun doprava o dva bity je výhodnější provést dvojicí instrukci SHR registr, 1 a nikoli jedinou instrukcí SHR registr, 2.
Podívejme se nyní na úpravu subrutiny pro obarvení pixelu v režimu 320×200×256, v níž namísto několika posunů o jeden bit použijeme posuny o větší počet bitů:
; Vykresleni pixelu ; AX - x-ova souradnice ; BX - y-ova souradnice (staci len BL) ; CL - barva putpixel: mov dx, 0xa000 ; zacatek stranky video RAM mov es, dx ; nyni obsahuje ES stranku video RAM mov di, ax ; horizontalni posun pocitany v bajtech mov ax, bx ; y-ova souradnice shl ax, 6 ; y*64 add di, ax ; pricist cast y-oveho posunu shl ax, 2 ; y*256 add di, ax ; pricist zbytek y-oveho posunu ; -> y*64 + y*256 = y*320 mov [es:di], cl ; vlastni vykresleni pixelu ret
Celý program, který nastaví grafický režim 320×200×256 a následně vykreslí několik úseček, lze upravit následovně:
; Graficky rezim karty VGA s rozlisenim 320x200 pixelu. ; Pouziti predpocitane tabulky. ; Vykresleni barevnych usecek. ; Urceno pro 80286 a vyssi. ; ;----------------------------------------------------------------------------- BITS 16 ; 16bitovy vystup pro DOS CPU 286 ; specifikace pouziteho instrukcniho souboru ;----------------------------------------------------------------------------- ; ukonceni procesu a navrat do DOSu %macro exit 0 mov ah, 0x4c int 0x21 %endmacro ; vyprazdneni bufferu klavesnice a cekani na klavesu %macro wait_key 0 xor ax, ax int 0x16 %endmacro ; nastaveni grafickeho rezimu %macro gfx_mode 1 mov ah, 0 mov al, %1 int 0x10 %endmacro ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: gfx_mode 0x13 ; nastaveni rezimu 320x200 s 256 barvami push 0xa000 ; video RAM v textovem rezimu pop es xor di, di ; nyni ES:DI obsahuje adresu prvniho pixelu ve video RAM mov ax, 0 opak: mov bx, ax ; y-ová souřadnice push ax mov cl, al ; barva call putpixel ; vykreslení pixelu pop ax push ax mov cl, al ; barva add ax, 10 ; horizontalni posun useky call putpixel ; vykreslení pixelu pop ax push ax mov cl, al ; barva add ax, 20 ; horizontalni posun useky call putpixel ; vykreslení pixelu pop ax inc ax ; pusun x+=1, y+=1 cmp ax, 200 ; hranice obrazovky? jne opak ; ne-opakujeme wait_key ; cekani na klavesu exit ; navrat do DOSu ; Vykresleni pixelu ; AX - x-ova souradnice ; BX - y-ova souradnice (staci len BL) ; CL - barva putpixel: mov dx, 0xa000 ; zacatek stranky video RAM mov es, dx ; nyni obsahuje ES stranku video RAM mov di, ax ; horizontalni posun pocitany v bajtech mov ax, bx ; y-ova souradnice shl ax, 6 ; y*64 add di, ax ; pricist cast y-oveho posunu shl ax, 2 ; y*256 add di, ax ; pricist zbytek y-oveho posunu ; -> y*64 + y*256 = y*320 mov [es:di], cl ; vlastni vykresleni pixelu ret
18. Nepodporované instrukce: POP CS
V rámci postupného rozšiřování instrukční sady mikroprocesorů rodiny 80×86 se ukázalo, že některé instrukce nejsou užitečné a je tak možné jejich instrukční kód použít pro odlišné účely. Při přechodu z Intelu 8086/8088 na 80186/80286 došlo k jediné takové úpravě, která se konkrétně týkala instrukce POP CS s operačním kódem 0×0F. Tato instrukce ze zásobníku přečte šestnáctibitovou hodnotu a tu vloží do segmentového registru CS, čímž se ovlivní i adresa další instrukce, která se má přečíst z adresy CS:IP. POP CS sama o sobě prakticky nedává smysl, protože většinou bude na zásobníku plná adresa segment:offset a v tomto případě lze použít plnohodnotný „dlouhý“ RET. Proto byla instrukce POP CS odstraněna a její operační kód je v novějších typech mikroprocesorů použit pro odlišné účely.
Assemblery nás většinou budou varovat, pokud se POP CS pokusíme použít a současně budeme specifikovat, že cílový procesor je odlišný od původního 8086. Nicméně příslušný instrukční kód většinou do výsledného binárního programu vloží:
; Instrukcni soubor mikroprocesoru Intel 80386. ; ;----------------------------------------------------------------------------- BITS 16 ; 16bitovy vystup pro DOS CPU 286 ; specifikace pouziteho instrukcniho souboru ; ukonceni procesu a navrat do DOSu %macro exit 0 ret %endmacro ; vyprazdneni bufferu klavesnice a cekani na klavesu %macro wait_key 0 xor ax, ax int 0x16 %endmacro ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: push cs push ds push ss push es pop es pop ss pop ds pop cs wait_key exit
Ve výsledném programu (resp. v binárním souboru typu COM) bude na třicátém pátém bajtu skutečně operační kód instrukce POP CS:
35 00000007 0F pop cs
Nicméně současně nás bude assembler varovat, že výsledek nebude plně kompatibilní s cílovým procesorem:
35 ****************** warning: instruction obsolete and removed from the target CPU [-w+obsolete-removed]
Pro úplnost – takto vypadá výpis listingu vytvořeného assemblerem při překladu:
1 ; Instrukcni soubor mikroprocesoru Intel 80386. 2 ; 7 ;----------------------------------------------------------------------------- 8 9 BITS 16 ; 16bitovy vystup pro DOS 10 CPU 286 ; specifikace pouziteho instrukcniho souboru 11 12 ; ukonceni procesu a navrat do DOSu 13 %macro exit 0 14 ret 15 %endmacro 16 17 ; vyprazdneni bufferu klavesnice a cekani na klavesu 18 %macro wait_key 0 19 xor ax, ax 20 int 0x16 21 %endmacro 22 23 ;----------------------------------------------------------------------------- 24 org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) 25 26 start: 27 00000000 0E push cs 28 00000001 1E push ds 29 00000002 16 push ss 30 00000003 06 push es 31 32 00000004 07 pop es 33 00000005 17 pop ss 34 00000006 1F pop ds 35 00000007 0F pop cs 35 ****************** warning: instruction obsolete and removed from the target CPU [-w+obsolete-removed] 36 37 wait_key 19 00000008 31C0 <1> xor ax, ax 20 0000000A CD16 <1> int 0x16 38 14 0000000C C3 <1> ret
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 |
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/