Obsah
1. Od reálného režimu k režimu chráněnému na procesorech 80286 a 80386 (2.část)
2. Obsah speciálního registru MSW na čipu 80286
3. Přečtení a zobrazení obsahu registru MSW
4. Obsah speciálního registru CR0 na čipu 80386
5. Přečtení a zobrazení obsahu registru CR0
6. Test, zda se procesor nachází v chráněném režimu
7. Naivní přechod do chráněného režimu
8. Realizace přechodu do chráněného režimu na čipu 80286
9. Realizace přechodu do chráněného režimu na čipu 80386
10. Vymazání instrukční fronty při přechodech mezi režimy
11. Zpětný přechod z chráněného režimu do režimu reálného
12. Pokus o zpětný přechod do reálného režimu na čipu 80286
13. Zpětný přechod do reálného režimu na čipu 80386
14. Přechod do nereálného režimu na mikroprocesorech 80386
15. Nastavení globální tabulky deskriptorů
16. Načtení tabulky deskriptorů s přechodem do chráněného režimu
17. Naplnění cache deskriptorů a návrat zpět do reálného režimu
18. Úplný zdrojový kód programu pro nastavení nereálného režimu
19. Repositář s demonstračními příklady
1. Od reálného režimu k režimu chráněnému na procesorech 80286 a 80386 (2.část)
V dnešním článku o tvorbě aplikací pro platformu IBM PC v DOSu si ukážeme, jakým způsobem lze realizovat přechod z reálného režimu do režimu chráněného (a zpět). Článek uzavřeme příkladem, který nastaví takzvaný nereálný režim, tj. mikroprocesor 80386 se bude nacházet v takovém stavu, že umožní adresovat celý 32bitový rozsah paměti (4GB) bez jakýchkoli omezení, kde se mohou nacházet data (taktéž se někdy setkáme s označením flat mode, ale tento název postupně získal odlišný význam).
Jak již bylo napsáno v perexu článku, přechod do chráněného režimu (a popř. i zpět) na mikroprocesorech Intel se do značné míry podobá nějakému složitému rituálu. Všechny operace (a není jich málo) je totiž nutné vykonat v určitém pevně daném pořadí a navíc naslepo. Ve chvíli přepínání do chráněného režimu totiž nemáme žádné možnosti ladění: debugger, který by mohl být spuštěn v režimu reálném, už není dostupný a cesta ke spuštění debuggeru pro režim chráněný je ještě velmi dlouhá.
Při ladění mikrořadičů si vývojáři pomáhají alespoň blikáním LED připojených na porty, nebo posílají zprávy na řádkový či sedmisegmentový LCD/LED displej přes IIC atd. Ovšem na PC nemáme ani tuto možnost, protože při přepínání do chráněného režimu nelze používat ani I/O porty. A jakákoli chyba je potrestána zamrznutím systému. Navíc toto zamrznutí může nastat až u zákazníků – když například povolíme přerušení příliš brzy, tak pravděpodobnost problémů je sice malá, ale nenulová.
Takže: šťastnou cestu.
2. Obsah speciálního registru MSW na čipu 80286
Mikroprocesory Intel 80286 se v některých ohledech lišily od původních čipů Intel 8086/8088. O jednom rozdílu jsme si již řekli – je jím odlišný způsob generování fyzické adresy, která je 24bitová a nikoli jen 20bitová. S tím souvisí i pokus o zajištění zpětné kompatibility vynulováním hodnoty na dvacátém adresovém vodiči přes (ne)slavnou A20 GATE. Ovšem mikroprocesor 80286 obsahuje i několik dalších registrů se speciálním významem a taktéž (jakoby nebylo instrukcí již tak obrovské množství) speciálními instrukcemi určenými pro čtení a zápis do těchto registrů.
Jedním z těchto speciálních registrů je MSW neboli Machine Status Word. Ten obsahuje bity a bitová pole obsahující informace o stavu mikroprocesoru a vlastně tak doplňuje bity z registru FLAGS. Na čipu Intel 80286 má tento registr šířku šestnáct bitů, ovšem reálný význam má jen spodních pět bitů. Dalších jedenáct bitů je rezervovaných. Význam spodních pěti bitů registru MSW je následující:
Bit | Označení | Význam |
---|---|---|
0 | PE | povolení chráněného režimu (to nás dnes zajímá) |
1 | MP | příznak, že je dostupný matematický koprocesor, na který je nutné čekat (ovlivňuje význam instrukce WAIT) |
2 | EM | příznak emulace matematického koprocesoru (FP instrukce způsobí výjimku, na kterou lze reagovat) |
3 | TS | nastaveno při přepnutí úlohy (v reálném režimu nemá význam) |
4 | ET | rozlišení mezi koprocesorem 80287 a 80387 (popravdě netuším, k čemu je to dobré, prostě Intel, na 286 je vždy nula) |
Pro načtení nové hodnoty do registru MSW se používá nová instrukce LMSW, naopak pro přečtení jeho hodnoty je určena instrukce SMSW. Typicky je nutné nastavit nebo vynulovat jen jediný bit, takže postup je následující:
smsw ax or al, maska ; nastaveni bitu lmsw ax
a:
smsw ax and al, ~maska ; vynulovani bitu lmsw ax
K dispozici jsou přitom základní adresovací režimy – přesuny MSW lze provést buď do 16bitového pracovního registru nebo do paměti:
; Operační kódy instrukcí LMSW a SMSW ; Kompatibilni i s cipem Intel 80286 ;----------------------------------------------------------------------------- BITS 16 ; 16bitovy vystup pro DOS CPU 286 ; specifikace pouziteho instrukcniho souboru ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: lmsw ax lmsw bp lmsw [old_msw] lmsw [old_msw+DI] lmsw [old_msw+DI+0x100] smsw ax smsw bp smsw [old_msw] smsw [old_msw+DI] smsw [old_msw+DI+0x100] ; datova cast old_msw: dw 0
Operační kódy instrukcí:
00000000 0F01F0 lmsw ax 00000003 0F01F5 lmsw bp 00000006 0F0136[2A00] lmsw [old_msw] 0000000B 0F01B5[2A00] lmsw [old_msw+DI] 00000010 0F01B5[2A01] lmsw [old_msw+DI+0x100] 00000015 0F01E0 smsw ax 00000018 0F01E5 smsw bp 0000001B 0F0126[2A00] smsw [old_msw] 00000020 0F01A5[2A00] smsw [old_msw+DI] 00000025 0F01A5[2A01] smsw [old_msw+DI+0x100]
3. Přečtení a zobrazení obsahu registru MSW
Přečtení obsahu speciálního registru MSW je nedestruktivní operací a navíc ji můžeme provést kdykoli (z libovolného režimu). To je ostatně ukázáno i v dnešním prvním demonstračním příkladu, který po svém překladu a spuštění obsah tohoto registru zobrazí v podobě hexadecimální hodnoty:
; Tisk obsahu specialniho registru MSW. ; Kompatibilni i s cipem Intel 80286 ;----------------------------------------------------------------------------- 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: smsw ax ; prenos MSW do registru AX push ax mov al, ah ; nejprve vytiskneme vyssi bajt print_hex al pop ax ; pote vytiskneme nizsi bajt print_hex al wait_key ; cekani na stisk klavesy exit ; navrat do DOSu ; datova cast ; retezec ukonceny znakem $ ; (tato data jsou soucasti vysledneho souboru typu COM) message db 0x01, 0x01, "$" ; prevodni tabulka hodnoty 0-15 na ASCII znak hex_digits db "0123456789abcdef"
Příklad výstupu, který lze získat:
Obrázek 1: Hexadecimální hodnota speciálního registru MSW.
Z vypsaného obsahu je patrné, že je dostupný koprocesor 80387 (není tedy povolená emulace jeho činnosti), systém je v reálném režimu a nedošlo k přepnutí úlohy (to v reálném režimu ani není možné).
4. Obsah speciálního registru CR0 na čipu 80386
Mikroprocesory Intel 80386 se v mnohém odlišují od původních dvou generací čipů 80×86. Došlo i k rozšíření původního šestnáctibitového registru MSW na 32bitový registr nazvaný CR0 (Control Register 0). I když se jedná o 32bitový registr, má význam opět pouze několik bitů, konkrétně sedm bitů. Přitom pět bitů má naprosto stejný význam, jako u MSW (interně se totiž jedná o shodný registr):
Bit | Označení | Význam |
---|---|---|
0 | PE | povolení chráněného režimu (to nás dnes zajímá) |
1 | MP | příznak, že je dostupný matematický koprocesor, na který je nutné čekat (ovlivňuje význam instrukce WAIT) |
2 | EM | příznak emulace matematického koprocesoru (FP instrukce způsobí výjimku, na kterou lze reagovat) |
3 | TS | nastaveno při přepnutí úlohy (v reálném režimu nemá význam) |
4 | ET | rozlišení mezi koprocesorem 80287 a 80387 (popravdě netuším, k čemu je to dobré, prostě Intel) |
5 | NE | řízení způsobu detekce výjimek matematického koprocesoru: buď se zpracují jako přerušení nebo jako výjimky |
6–30 | rezervováno | |
31 | PG | stránkování (paging) povoleno či zakázáno |
Do mikroprocesorů Intel 80286 bylo přidáno jen minimum nových registrů (tedy zejména výše zmíněný MSW), takže se společnost Intel rozhodla, že pro práci s nimi vyhradí nové instrukce LMSW a SMSW. Ovšem u mikroprocesorů Intel 80386 byla situace dosti odlišná, protože nových registrů byla celá řada: řídicí registry CR0 až CR8, ladicí registry DR0 až DR7 (některé ovšem chybí), registry pro testování TR3 až TR7 atd. Nebylo by tedy moudré pro každý z těchto registrů zavádět nové specializované instrukce (ono to tedy nebylo moudré ani u MSW). Proto byla rozšířena sémantika univerzální přenosové instrukce MOV tak, aby bylo možné provést přenosy stylem:
mov EAX, CR0
5. Přečtení a zobrazení obsahu registru CR0
Opět se podívejme na způsob přečtení a zobrazení obsahu registru CR0. Je to snadné – přečteme celou 32bitovou hodnotu tohoto registru a postupně si necháme v hexadecimální podobě vypsat obsahy jednotlivých bajtů tohoto registru. Jedna z možných implementací může vypadat následovně:
mov eax, cr0 ; prenos CR0 do registru EAX shr eax, 24 ; hornich 8 bitu do AL print_hex al mov eax, cr0 ; prenos CR0 do registru EAX shr eax, 16 ; bity 16-23 do AL print_hex al mov eax, cr0 ; prenos CR0 do registru EAX mov al, ah ; bity 8-15 do AL print_hex al mov eax, cr0 ; prenos CR0 do registru EAX print_hex al ; tisk spodnich osmi bitu
Výsledek:
Obrázek 2: Obsah registru CR0 zobrazený v emulátoru PC.
Následuje výpis úplného zdrojového kódu tohoto demonstračního příkladu:
; Tisk obsahu specialniho registru CR0. ; Kompatibilni s cipem Intel 80286 ;----------------------------------------------------------------------------- BITS 16 ; 16bitovy vystup pro DOS CPU 386 ; 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: mov eax, cr0 ; prenos CR0 do registru EAX shr eax, 24 ; hornich 8 bitu do AL print_hex al mov eax, cr0 ; prenos CR0 do registru EAX shr eax, 16 ; bity 16-23 do AL print_hex al mov eax, cr0 ; prenos CR0 do registru EAX mov al, ah ; bity 8-15 do AL print_hex al mov eax, cr0 ; prenos CR0 do registru EAX print_hex al ; tisk spodnich osmi bitu wait_key ; cekani na stisk klavesy exit ; navrat do DOSu ; datova cast ; retezec ukonceny znakem $ ; (tato data jsou soucasti vysledneho souboru typu COM) message db 0x01, 0x01, "$" ; prevodni tabulka hodnoty 0-15 na ASCII znak hex_digits db "0123456789abcdef"
6. Test, zda se procesor nachází v chráněném režimu
Z předchozího textu vyplývá, že můžeme snadno zjistit, zda se mikroprocesor nachází v reálném nebo v chráněném režimu. Tuto operaci provedeme testem nultého bitu registru MSW nebo CR0. Z následujícího příkladu bude patrné, jak se tento test provádí. Nejde o nic složitého (resp. přesněji řečeno většinu operací již dobře známe):
; Otestovani, jestli se mikroprocesor nachazi v chranenem rezimu. ; Kompatibilni i s cipem Intel 80286 ;----------------------------------------------------------------------------- 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 ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: smsw ax ; prenos MSW do registru AX test ax, 0x1 ; test nejnizsiho bitu MSW jz not_prot_mode ; nulovy bit? -> nejsme v chranenem rezimu print in_protected_mode_msg; nenulovy bit? -> jsme v chranenem rezimu jmp end not_prot_mode: print not_in_protected_mode_msg end: wait_key ; cekani na stisk klavesy exit ; navrat do DOSu ; datova cast in_protected_mode_msg: db "Processor already in protected mode", 0x0a, 0x0d, "$" not_in_protected_mode_msg: db "Processor is NOT in protected mode", 0x0a, 0x0d, "$"
Výsledek:
Obrázek 3: Výsledek testu, zda se procesor nachází v chráněném režimu.
7. Naivní přechod do chráněného režimu
Z výše uvedeného popisu speciálních registrů MSW a CR0 by mohlo vyplývat, že přechod do chráněného režimu je snadný – vždyť pouze postačuje nastavit nejnižší bit jednoho z těchto registrů (v závislosti na použité platformě). Pokud je totiž bit PE (Protected Mode Enable(d)) nastaven na jedničku, skutečně dojde k přepnutí mikroprocesoru do chráněného režimu. Jenže v praxi je situace daleko složitější a přechod do chráněného režimu sestává z několika kroků. Ve stručnosti:
- Test, zda se systém již nachází v chráněném režimu. Pokud ano, můžeme končit, protože pravděpodobně další operace nebudou povoleny (nejsme v ringu 0)
- Naplnění globální tabulky deskriptorů (GDT)
- Naplnění struktury s popisem GDT (délka a adresa)
- Zákaz přerušení
- Naplnění tabulky s deskriptory pro přerušovací subrutiny tak, že je nastaven limit na nulu (někdy lze vynechat)
- Nastavení bitu PE v MSW nebo CR0 – tedy skutečný přechod do chráněného režimu
- Provedení (dlouhého) skoku, aby se vymazala instrukční cache (teoreticky není nutné, pokus se zůstává v 16bitovém režimu)
- Načtení segmentových registrů; tím se načte i minule zmíněná cache s deskriptory
- Inicializace SS:SP (zásobník)
- Naplnění tabulky s deskriptory pro přerušovací subrutiny na požadované hodnoty (již bez nulového limitu)
- Povolení přerušení
Tyto operace (s výjimkou modifikace IDT – deskriptory pro přerušovací subrutiny) si ukážeme v dalším textu.
Nejprve si však v dalších dvou kapitolách ukažme naivní přechod do chráněného režimu, kdy vlastně provedeme jen několik kroků z výše zmíněného seznamu. Výsledkem bude „zamrznutý“ systém (což v dobách DOSu a Windows 3.x nebylo nic zvláštního), ovšem zamrznutý v chráněném režimu a nikoli v režimu reálném.
8. Realizace přechodu do chráněného režimu na čipu 80286
Podívejme se nejprve, jak lze realizovat přechod do chráněného režimu na mikroprocesoru Intel 80286.
Nejprve je nutné otestovat, jestli se systém již nenachází v chráněném režimu. Pokud ano, může aplikace jen vypsat zprávu a ukončit se:
smsw ax ; prenos MSW do registru AX test ax, 0x1 ; test nejnizsiho bitu MSW jz not_prot_mode ; nulovy bit? -> nejsme v chranenem rezimu print in_protected_mode_msg jmp end
V případě, že systém není v chráněném režimu, vypíšeme o tom zprávu:
print entering_protected_mode_msg
Dále zakážeme přerušení, nastavíme nultý bit registru MSW a přerušení povolíme:
cli ; zakázat přerušení smsw ax or al, 1 ; nastaveni priznaku chraneneho rezimu lmsw ax ; nyni jsme v chranenem rezimu, ale bez nastavene tabulky deskriptoru ; prakticky jakykoli zapis zpusobi zamrznuti systemu!!! sti ; povolit přerušení
Můžeme i vymazat instrukční cache, i když to není nutné:
jmp .flush_cache_1 ; vymazani instrukcni fronty .flush_cache_1:
Systém poté prakticky ihned „zatuhne“, a to po příchodu jakéhokoli přerušení nebo při pokusu o zavolání funkce DOSu. Ovšem zatuhne v chráněném režimu, což je pokrok :-)
Úplný zdrojový kód tohoto příkladu vypadá následovně:
; Prechod z realneho rezimu do rezimu chraneneho. ; Kompatibilni i s cipem Intel 80286 ;----------------------------------------------------------------------------- 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 ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: smsw ax ; prenos MSW do registru AX test ax, 0x1 ; test nejnizsiho bitu MSW jz not_prot_mode ; nulovy bit? -> nejsme v chranenem rezimu print in_protected_mode_msg jmp end not_prot_mode: ; nenulovy bit? -> jsme v chranenem rezimu print entering_protected_mode_msg cli ; zakázat přerušení smsw ax or al, 1 ; nastaveni priznaku chraneneho rezimu lmsw ax ; nyni jsme v chranenem rezimu, ale bez nastavene tabulky deskriptoru ; prakticky jakykoli zapis zpusobi zamrznuti systemu!!! sti ; povolit přerušení end: wait_key ; cekani na stisk klavesy exit ; navrat do DOSu ; datova cast in_protected_mode_msg: db "Processor already in protected mode - exiting", 0x0a, 0x0d, "$" entering_protected_mode_msg: db "Entering protected mode", 0x0a, 0x0d, "$"
9. Realizace přechodu do chráněného režimu na čipu 80386
A jak vypadá přechod do chráněného režimu v případě mikroprocesoru Intel 80386 (nebo následujících čipech)? Jedná se o prakticky totožnou operaci, ovšem namísto nastavení nulového bitu speciálního registru MSW se nastavuje nulový bit registru CR0:
mov eax, cr0 or al, 1 ; nastaveni priznaku chraneneho rezimu mov cr0, eax
Opět se podívejme na úplný zdrojový kód tohoto demonstračního příkladu:
; Prechod z realneho rezimu do rezimu chraneneho. ; Kompatibilni s cipem Intel 80386 ;----------------------------------------------------------------------------- BITS 16 ; 16bitovy vystup pro DOS CPU 386 ; 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 ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: smsw ax ; prenos MSW do registru AX test ax, 0x1 ; test nejnizsiho bitu MSW jz not_prot_mode ; nulovy bit? -> nejsme v chranenem rezimu print in_protected_mode_msg jmp end not_prot_mode: ; nenulovy bit? -> jsme v chranenem rezimu print entering_protected_mode_msg cli ; zakázat přerušení mov eax, cr0 or al, 1 ; nastaveni priznaku chraneneho rezimu mov cr0, eax jmp .flush_cache_1 ; vymazani instrukcni fronty .flush_cache_1: ; nyni jsme v chranenem rezimu, ale bez nastavene tabulky deskriptoru ; prakticky jakykoli zapis zpusobi zamrznuti systemu!!! sti end: wait_key ; cekani na stisk klavesy exit ; navrat do DOSu ; datova cast in_protected_mode_msg: db "Processor already in protected mode - exiting", 0x0a, 0x0d, "$" entering_protected_mode_msg: db "Entering protected mode", 0x0a, 0x0d, "$"
10. Vymazání instrukční fronty při přechodech mezi režimy
V obou předchozích demonstračních příkladech jsme mohli vidět na první pohled podivnou instrukci. Jednalo se o skok na adresu, která následuje ihned po instrukci skoku:
jmp .flush_cache_1 ; vymazani instrukcni fronty .flush_cache_1:
Proč se však tato instrukce do programu vůbec vkládá, když vlastně zdánlivě nic nedělá? Pro urychlení práce mikroprocesorů Intel se začaly postupně zavádět techniky známé spíše z RISCových mikroprocesorů. Jedna z těchto technik spočívá v existenci fronty instrukcí, do které jsou přednačteny instrukce, které se pravděpodobně budou provádět po právě vykonávané instrukci. Tím se do jisté míry zamezilo čekání na načtení dalších instrukcí, instrukce se mohly začít dekódovat atd. Celá věc má samozřejmě malý háček: pokud se provede instrukce skoku, obsahuje celá fronta špatné instrukce, takže ji je nutné vyprázdnit (a zpomalit výpočet). A právě toto vyprázdnění fronty provede onen na první pohled nadbytečný skok.
11. Zpětný přechod z chráněného režimu do režimu reálného
V chráněném režimu není možné běžným způsobem volat ani služby BIOSu, ale ani služby DOSu. Tyto dva systémy jsou totiž navrženy takovým způsobem, aby jejich služby byly volatelné jen z reálného režimu. Jakým způsobem lze ovšem zařídit, aby aplikace psaná v chráněném režimu například změnila grafický režim (přes BIOS) či pracovala se souborovým systémem (přes DOS)? Evidentně to totiž možné je, protože takových aplikací vznikla celá řada. Jedno z řešení spočívá v tom, že se před voláním BIOSu nebo DOSu vrátíme zpět do reálného režimu, provedeme volání potřebné služby, a vrátíme se zpět do režimu chráněného (s případnou kopií získaných dat atd.). To zní poměrně jednoduše, ovšem na architektuře IBM PC ve skutečnosti nic tak snadné není – na programátora čeká celá řada pastí.
Začneme nyní NEchronologicky čipem Intel 80386. Zde je možné manipulací s registrem CR0, konkrétně s jeho nulovým bitem PE skutečně provést jak přechod do chráněného režimu (již známe), tak i zpětný přechod do režimu reálného. Tento zpětný přechod se provede jednoduše:
mov eax, cr0 and al, ~1 ; zruseni priznaku chraneneho rezimu mov cr0, eax
A opět následuje vymazání instrukční cache:
jmp .flush_cache_2 ; vymazani instrukcni fronty .flush_cache_2:
Vraťme se zpět k mikroprocesoru 80286. Na něm se přechod do reálného režimu provádí touto sekvencí instrukcí:
smsw ax or al, 1 ; nastaveni priznaku chraneneho rezimu lmsw ax
Mohlo by se tedy zdát logické, že vynulováním bitu PE se přepneme zpět do režimu reálného:
smsw ax and al, ~1 ; zruseni priznaku chraneneho rezimu lmsw ax
Malý, vlastně nicotný problém spočívá v tom, že tato operace není mikroprocesory Intel 80286 podporována. Předpokládalo se totiž, že se o chráněný režim bude starat operační systém a aplikace poběží v ringu vyšším než 0 a vůbec nebudou mít důvod se přepínat zpět do režimu reálného. Ovšem DOS mezi takové systémy nepatřil a ani patřit nemohl, protože musel podporovat i tisíce původních aplikací pro reálný režim.
Jak tento problém vyřešit? Podobně, jako v případě A20 GATE: co nedokáže mikroprocesor se muselo „ohnout“ v samotném návrhu a HW PC. U A20 GATE se jednalo o přidání hradla, které bylo možné programově ovládat. A v případě přechodu do reálného režimu zbývala jediná možnost – reset mikroprocesoru! Ovšem tak vhodně provedený reset, aby aplikace mohla běžet i po této obecně destruktivní operaci (musela se upravit rutina zavolaná po resetu). Původní řešení navržené a implementované firmou IBM se nazývá slow reset a spočívá v tom, že signál resetu byl ovládán (opět) řadičem klávesnice – viz například toto řešení. Modernější čipsety dokázaly provádět fast reset jedinou I/O operací.
Později se začala používat metoda nazývaná TRIPLE FAULT. Jednalo se o vyvolání výjimky, která nastala při zpracování jiné výjimky (což se označuje jako double fault). Pokud je ovšem ona druhá výjimka takové povahy, že přetrvá a nelze ji opravit (typicky přetečení zásobníku), nastává triple fault, který je detekován na úrovni HW a při jeho detekci se provede reset. Není tedy nutné používat zdlouhavé nastavení řadiče klávesnice ani se spoléhat na vylepšené čipsety, protože kontrola triple faultu s následným resetem byla součástí PC AT.
12. Pokus o zpětný přechod do reálného režimu na čipu 80286
Podívejme se nyní na to, jak zdánlivě snadno může vypadat pokus o zpětný přechod do reálného režimu na mikroprocesoru Intel 80286. Tento demonstrační příklad nejprve provede přechod do chráněného režimu a poté se pokusí vrátit zpět do režimu reálného. Ovšem již z předchozí kapitoly je zřejmé, že se v tomto případě jedná o marnou snahu – sice jsme v ringu 0, takže právo na změnu režimu máme, ovšem tato operace není na mikroprocesorech Intel 80286 podporována:
; Prechod z realneho rezimu do rezimu chraneneho a zpet. ; Kompatibilni i s cipem Intel 80286 ;----------------------------------------------------------------------------- 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 ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: smsw ax ; prenos MSW do registru AX test ax, 0x1 ; test nejnizsiho bitu MSW jz not_prot_mode ; nulovy bit? -> nejsme v chranenem rezimu print in_protected_mode_msg jmp end not_prot_mode: ; nenulovy bit? -> jsme v chranenem rezimu print entering_protected_mode_msg cli ; zakázat přerušení smsw ax or al, 1 ; nastaveni priznaku chraneneho rezimu lmsw ax jmp .flush_cache_1 ; vymazani instrukcni fronty .flush_cache_1: ; nyni jsme v chranenem rezimu, ale bez nastavene tabulky deskriptoru ; prakticky jakykoli zapis zpusobi zamrznuti systemu!!! ; navrat z chraneneho rezimu ; toto nelze provest tak jednoduse, jak to vypada smsw ax and al, ~1 ; zruseni priznaku chraneneho rezimu lmsw ax jmp .flush_cache_2 ; vymazani instrukcni fronty .flush_cache_2: sti print back_in_real_mode_msg end: wait_key ; cekani na stisk klavesy exit ; navrat do DOSu ; datova cast in_protected_mode_msg: db "Processor already in protected mode - exiting", 0x0a, 0x0d, "$" entering_protected_mode_msg: db "Entering protected mode", 0x0a, 0x0d, "$" back_in_real_mode_msg: db "Back in real mode", 0x0a, 0x0d, "$"
A takto vypadá obrazovka po přepnutí do chráněného režimu a pokusu o návrat do režimu reálného (který ovšem neproběhne, jak již víme):
Obrázek 4: Obrazovka aplikace, která provede přepnutí do chráněného režimu a posléze se pokusí o návrat zpět do režimu reálného na systému s mikroprocesorem Intel 80286. Návrat zpět se evidentně nepovedl.
13. Zpětný přechod do reálného režimu na čipu 80386
Na systémech s mikroprocesorem Intel 80386 lze provést jak přechod do chráněného režimu, tak i návrat do režimu reálného. To je ukázáno na dalším demonstračním příkladu. Ovšem stále se jedná o umělý příklad, který nemá praktické využití, protože jsme nenastavili globální tabulku deskriptorů a nenačetli jsme segmentové registry (což by modifikovalo cache s deskriptory). Nicméně by měl být tento příklad spustitelný a měl by zobrazit jak zprávu o přechodu do chráněného režimu, tak i zprávu o jeho opuštění:
; Prechod z realneho rezimu do rezimu chraneneho a zpet. ; Kompatibilni s cipem Intel 80386 ;----------------------------------------------------------------------------- BITS 16 ; 16bitovy vystup pro DOS CPU 386 ; 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 ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: smsw ax ; prenos MSW do registru AX test ax, 0x1 ; test nejnizsiho bitu MSW jz not_prot_mode ; nulovy bit? -> nejsme v chranenem rezimu print in_protected_mode_msg jmp end not_prot_mode: ; nenulovy bit? -> jsme v chranenem rezimu print entering_protected_mode_msg cli ; zakázat přerušení mov eax, cr0 or al, 1 ; nastaveni priznaku chraneneho rezimu mov cr0, eax jmp .flush_cache_1 ; vymazani instrukcni fronty .flush_cache_1: ; nyni jsme v chranenem rezimu, ale bez nastavene tabulky deskriptoru ; prakticky jakykoli zapis zpusobi zamrznuti systemu!!! mov eax, cr0 and al, ~1 ; zruseni priznaku chraneneho rezimu mov cr0, eax jmp .flush_cache_2 ; vymazani instrukcni fronty .flush_cache_2: sti print back_in_real_mode_msg end: wait_key ; cekani na stisk klavesy exit ; navrat do DOSu ; datova cast in_protected_mode_msg: db "Processor already in protected mode - exiting", 0x0a, 0x0d, "$" entering_protected_mode_msg: db "Entering protected mode", 0x0a, 0x0d, "$" back_in_real_mode_msg: db "Back in real mode", 0x0a, 0x0d, "$"
Obrázek 5: Obrazovka aplikace, která provede přepnutí do chráněného režimu a posléze se pokusí o návrat zpět do režimu reálného na systému s mikroprocesorem Intel 80386.
14. Přechod do nereálného režimu na mikroprocesorech 80386
Ve třetí části dnešního článku si ukážeme praktický (a kupodivu i funkční) příklad. Bude se jednat o utilitu, která dokáže na mikroprocesorech 80386 nastavit takzvaný nereálný režim, resp. jeho jednu variantu. Tato varianta umožní adresovat veškerou paměť až do limitu 4GB jen s využitím 32bitových offsetů. Zbavíme se tedy nutnosti myslet na segmentové registry (ovšem ty se stále budou používat – prostě je budeme zapisovat, toť vše) a adresování bude realizováno jen lineární 32bitovou adresou (pro jednoduchost platí pro segmentové registry ES, FS a GS). Práce s ukazateli se tedy do značné míry zjednoduší a bude možné bez problémů používat datové struktury přesahující hranici 64kB. Pro jednoduchost však nebudeme měnit limity kódového segmentu (i to lze zařídit, ale program se zkomplikuje). Navíc jsou operace s daty 32bitové – ušetří se za prefixové bajty.
Celý postup je následující:
- Test, zda se systém již nachází v chráněném režimu. Pokud ano, máme smůlu a program je ihned ukončen.
- Zákaz přerušení (můžeme ho však zakázat i po naplnění GDT).
- Naplnění globální tabulky deskriptorů (GDT), která bude obsahovat „nulový deskriptor“ a druhý deskriptor bez limitů
- Naplnění struktury s popisem GDT (délka a adresa)
- Uložení obsahu segmentového registru DS, později ho obnovíme (přitom DS=SS)
- Nastavení bitu PE v registru CR0 – tedy skutečný přechod do chráněného režimu
- Provedení skoku na další adresu – vymazání instrukční fronty
- Načtení segmentových registrů; tím se načte i minule zmíněná cache s deskriptory
- Vynulování bitu PE v registru CR0 – tedy návrat do reálného režimu
- Provedení skoku na další adresu – vymazání instrukční fronty
- Inicializace registru SS (zásobník)
- Povolení přerušení
- Ukázka, že lze použít 32bitové adresování přes registr ES nebo FS nebo GS (ale lze i DS, pokud se nezmění cache s deskriptory)
15. Nastavení globální tabulky deskriptorů
Globální tabulka deskriptorů může být uložena kdekoli (resp. kdekoli v konvenční paměti – jinam totiž přístup zatím nemáme) a obsahuje na čipech Intel 80386 následující záznamy, kterých může být až 8191:
Obrázek 6: Ze struktury bitových polí deskriptorů je patrné, jak se nové bity přidávaly k bitům definovaným již u čipů 80286
Zdroj: Intel 80386 Reference Programmer's Manual
Přitom budeme chtít nastavit bitová pole BASE na nulovou adresu a LIMIT na samé jedničky (tedy bez limitu). Taktéž je ovšem nutné nastavit i další bitová pole – typ deskriptoru, přístupová práva, vypnutí stránkování atd. Pro tento účel použijeme pomocné makro, které na základě zadané báze, limitu, přístupových práv a příznaků nastaví osm bajtů deskriptoru (ve kterém jsou tato dlouhá bitová pole rozdělena na kratší části – prostě platforma Wintel):
%define MAKE_GDT_DESC(base, limit, access, flags) \ (((base & 0x00FFFFFF) << 16) | \ ((base & 0xFF000000) << 32) | \ (limit & 0x0000FFFF) | \ ((limit & 0x000F0000) << 32) | \ ((access & 0xFF) << 40) | \ ((flags & 0x0F) << 52))
Do tabulky deskriptorů se na první místo vkládá nulový deskriptor s limitem nastaveným na nulu. Ten slouží pro detekci přístupu do paměti přes NULL ukazatel (což by ovšem bylo možné realizovat i jinými způsoby). A druhý deskriptor bude nastaven takto:
- Bázová adresa: 0×00000000
- Limit: 0×ffffff (s granularitou 4kB)
- Přístupové bity: P=1 (povolení), DPL=0 (ring 0), S=1 (nesystémový segment), X=0 (datový segment, ne kód), C=0 (roste směrem nahoru, nejde o zásobník), R=1 (lze číst), A=0 (to je jedno, nastaví se při prvním přístupu)
- Příznaky G=1 (granularita=4kB), D=1 (32bitové operace), U=0 (nepouživáno HW)
Datovou strukturu s obsahem tabulky deskriptorů tedy můžeme v assembleru naplnit takto:
.start: .null_descriptor: dq 0 .flat_descriptor: dq MAKE_GDT_DESC(0, 0xffffffff, 10010010b, 1100b) ; 32-bit data, granularita 4KB, limit 0xffffffff, base=0
Podívejme se pro zajímavost, jak se volání makra MAKE_GDT_DESC přeložilo do výsledného binárního kódu. Jedná se o osm bajtů začínajících na adrese 125:
116 0000009B 90 align 4 ; pro jistotu: potrebujeme zarovnani na 32 bitu 117 118 global_descriptor_table: 119 FLAT_SEL equ .flat_descriptor - .start 120 121 .start: 122 .null_descriptor: 123 0000009C 0000000000000000 dq 0 124 .flat_descriptor: 125 000000A4 FFFF00000092CF00 dq MAKE_GDT_DESC(0, 0xffffffff, 10010010b, 1100b) 126 ; 32-bit data, granularita 4KB, limit 0xffffffff, base=0 127 .end: 128 129 .gdtr: 130 000000AC 0F00 dw .end - .start - 1 131 ; velikost tabulky deskriptoru -1 132 000000AE [9C000000] dd .start ; tato hodnota se musi upravit v runtime
16. Načtení tabulky deskriptorů s přechodem do chráněného režimu
Do bázové části druhého deskriptoru v tabulce deskriptorů následně uložíme obsah registru DS. To nelze provést přímo v čase překladu, ale až v čase běhu (runtime), protože nevíme, jak bude DS nastaven operačním systémem. A samozřejmě nesmíme zapomenout na vynásobení adresy segmentu šestnácti:
; nastaveni globalni tabulky deskriptoru mov eax, ds ; adresa ulozena v DS (nasobime sestnacti) shl eax, 4 add [global_descriptor_table.gdtr+2], eax ; oprava adresy tabulky deskriptoru
Tabulku deskriptorů načteme instrukcí LGDT (Load Global Descriptor Table). Této instrukci předáme odkaz na jednoduchou strukturu obsahující velikost GDT a její adresu:
; nacteni globalni tabulky deskriptoru lgdt [global_descriptor_table.gdtr]
Nyní již můžeme provést přechod do chráněného režimu:
mov cx, ds ; ulozeni DS, aby se mohl obnovit po navratu z chraneneho rezimu mov eax, cr0 or al, 1 ; nastaveni priznaku chraneneho rezimu mov cr0, eax jmp .flush_cache_1 ; vymazani instrukcni fronty .flush_cache_1:
17. Naplnění cache deskriptorů a návrat zpět do reálného režimu
V chráněném režimu naplníme všechny segmentové registry tak, aby obsahovaly selektor na druhý záznam v tabulce deskriptorů. Tím se naplní i cache deskriptorů (což by se jinak dalo provést trikem s LOADALL, což již známe):
; nyni jsme v 16bitovem chranenem rezimu ; nemenime CS, takze neni nutne prejit do 32bitoveho rezimu mov bx, FLAT_SEL ; druhy zaznam v tabulce deskriptoru mov ss, bx ; SS a DS pro tuto chvili bez limitu (naplni se cache s deskriptory) mov ds, bx mov es, bx ; stejne tak ostatni segmentove registry mov fs, bx ; ty jiz dale nebudeme menit, takze zustane pristup bez limitu mov gs, bx
Systém stále nezamrznul (kupodivu), takže se vrátíme zpět do režimu reálného:
mov eax, cr0 and al, ~1 ; zruseni priznaku chraneneho rezimu mov cr0, eax jmp .flush_cache_2 ; vymazani instrukcni fronty .flush_cache_2: sti
Nyní by mělo být možné například přes registr ES adresovat celou paměť s využitím 32bitové de facto absolutní adresy. Samotný registr ES nebudeme modifikovat – nastavil se v chráněném režimu a jeho obsah (adresa) již není zajímavá, protože důležitá je báze v cache deskriptorů:
attribute equ 0x57<<8 mov word es:[dword 0xb8000+80*10*3+0], attribute | 'U' mov word es:[dword 0xb8000+80*10*3+2], attribute | 'N' mov word es:[dword 0xb8000+80*10*3+4], attribute | 'R' mov word es:[dword 0xb8000+80*10*3+6], attribute | 'E' mov word es:[dword 0xb8000+80*10*3+8], attribute | 'A' mov word es:[dword 0xb8000+80*10*3+10], attribute | 'L'
Obrázek 7: Přístup do VideoRAM přes absolutní 32bitovou adresu.
18. Úplný zdrojový kód programu pro nastavení nereálného režimu
Úplný zdrojový kód demonstračního příkladu, který po svém překladu a spuštění provede nastavení nereálného režimu (přes režim chráněný – nikoli s využitím instrukce LOADALL) vypadá následovně:
; Nastaveni nerealneho rezimu s tim, ze pres registry DS a ES je mozne adresovat celou ; dostupnou pamet (limit 4GB) ; ; Inspirovano: ; https://pastebin.com/68W8cn0d ; (ovsem pozor, tento kod obsahuje chyby): ;----------------------------------------------------------------------------- BITS 16 ; 16bitovy vystup pro DOS CPU 386 ; 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 ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: smsw ax ; prenos MSW do registru AX test ax, 0x1 ; test nejnizsiho bitu MSW jz not_prot_mode ; nulovy bit? -> nejsme v chranenem rezimu print in_protected_mode_msg jmp end not_prot_mode: ; nenulovy bit? -> jsme v chranenem rezimu print entering_protected_mode_msg cli ; nastaveni globalni tabulky deskriptoru mov eax, ds ; adresa ulozena v DS (nasobime sestnacti) shl eax, 4 add [global_descriptor_table.gdtr+2], eax ; oprava adresy tabulky deskriptoru ; nacteni globalni tabulky deskriptoru lgdt [global_descriptor_table.gdtr] mov cx, ds ; ulozeni DS, aby se mohl obnovit po navratu z chraneneho rezimu mov eax, cr0 or al, 1 ; nastaveni priznaku chraneneho rezimu mov cr0, eax jmp .flush_cache_1 ; vymazani instrukcni fronty .flush_cache_1: ; nyni jsme v 16bitovem chranenem rezimu ; nemenime CS, takze neni nutne prejit do 32bitoveho rezimu mov bx, FLAT_SEL ; druhy zaznam v tabulce deskriptoru mov ss, bx ; SS a DS pro tuto chvili bez limitu (naplni se cache s deskriptory) mov ds, bx mov es, bx ; stejne tak ostatni segmentove registry mov fs, bx ; ty jiz dale nebudeme menit, takze zustane pristup bez limitu mov gs, bx mov eax, cr0 and al, ~1 ; zruseni priznaku chraneneho rezimu mov cr0, eax jmp .flush_cache_2 ; vymazani instrukcni fronty .flush_cache_2: ; nyni jsme v nerealnem rezimu mov ss, cx ; obnoveni segmentovych registru mov ds, cx sti print back_in_real_mode_msg ; otestovani nerealneho rezimu ; pristoupime k VideoRAM pres nulty segment, coz by nemelo ; byt v beznem realnem rezimu mozne ; nyni ovsem ES odkazuje na prvni deskriptor s volnym rozsahem attribute equ 0x57<<8 mov word es:[dword 0xb8000+80*10*3+0], attribute | 'U' mov word es:[dword 0xb8000+80*10*3+2], attribute | 'N' mov word es:[dword 0xb8000+80*10*3+4], attribute | 'R' mov word es:[dword 0xb8000+80*10*3+6], attribute | 'E' mov word es:[dword 0xb8000+80*10*3+8], attribute | 'A' mov word es:[dword 0xb8000+80*10*3+10], attribute | 'L' end: wait_key ; cekani na stisk klavesy exit ; navrat do DOSu ; datova cast ; pomocne makro pro vytvoreni jednoho zaznamu v tabulce deskriptoru %define MAKE_GDT_DESC(base, limit, access, flags) \ (((base & 0x00FFFFFF) << 16) | \ ((base & 0xFF000000) << 32) | \ (limit & 0x0000FFFF) | \ ((limit & 0x000F0000) << 32) | \ ((access & 0xFF) << 40) | \ ((flags & 0x0F) << 52)) align 4 ; pro jistotu: potrebujeme zarovnani na 32 bitu global_descriptor_table: FLAT_SEL equ .flat_descriptor - .start .start: .null_descriptor: dq 0 .flat_descriptor: dq MAKE_GDT_DESC(0, 0xffffffff, 10010010b, 1100b) ; 32-bit data, granularita 4KB, limit 0xffffffff, base=0 .end: .gdtr: dw .end - .start - 1 ; velikost tabulky deskriptoru -1 dd .start ; tato hodnota se musi upravit v runtime in_protected_mode_msg: db "Processor already in protected mode - exiting", 0x0a, 0x0d, "$" entering_protected_mode_msg: db "Entering protected mode", 0x0a, 0x0d, "$" back_in_real_mode_msg: db "Back in UNreal mode", 0x0a, 0x0d, "$" ; finito
19. Repositář s demonstračními příklady
Demonstrační příklady napsané v assembleru, které jsou určené pro překlad s využitím assembleru NASM, byly uloženy do Git repositáře, který je dostupný na adrese https://github.com/tisnik/8bit-fame. Jednotlivé demonstrační příklady si můžete v případě potřeby stáhnout i jednotlivě bez nutnosti klonovat celý (dnes již poměrně rozsáhlý) repositář:
# | Příklad | Stručný popis | Adresa |
---|---|---|---|
1 | hello.asm | program typu „Hello world“ naprogramovaný v assembleru pro systém DOS | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hello.asm |
2 | hello_shorter.asm | kratší varianta výskoku z procesu zpět do DOSu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hello_shorter.asm |
3 | hello_wait.asm | čekání na stisk klávesy | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hello_wait.asm |
4 | hello_macros.asm | realizace jednotlivých částí programu makrem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hello_macros.asm |
5 | gfx4_putpixel.asm | vykreslení pixelu v grafickém režimu 4 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_putpixel.asm |
6 | gfx6_putpixel.asm | vykreslení pixelu v grafickém režimu 6 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel.asm |
7 | gfx4_line.asm | vykreslení úsečky v grafickém režimu 4 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_line.asm |
8 | gfx6_line.asm | vykreslení úsečky v grafickém režimu 6 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_line.asm |
9 | gfx6_fill1.asm | vyplnění obrazovky v grafickém režimu, základní varianta | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_fill1.asm |
10 | gfx6_fill2.asm | vyplnění obrazovky v grafickém režimu, varianta s instrukcí LOOP | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_fill2.asm |
11 | gfx6_fill3.asm | vyplnění obrazovky instrukcí REP STOSB | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_fill3.asm |
12 | gfx6_fill4.asm | vyplnění obrazovky, synchronizace vykreslování s paprskem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_fill4.asm |
13 | gfx4_image1.asm | vykreslení rastrového obrázku získaného z binárních dat, základní varianta | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image1.asm |
14 | gfx4_image2.asm | varianta vykreslení rastrového obrázku s využitím instrukce REP MOVSB | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image2.asm |
15 | gfx4_image3.asm | varianta vykreslení rastrového obrázku s využitím instrukce REP MOVSW | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image3.asm |
16 | gfx4_image4.asm | korektní vykreslení všech sudých řádků bitmapy | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image4.asm |
17 | gfx4_image5.asm | korektní vykreslení všech sudých i lichých řádků bitmapy | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image5.asm |
18 | gfx4_image6.asm | nastavení barvové palety před vykreslením obrázku | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image6.asm |
19 | gfx4_image7.asm | nastavení barvové palety před vykreslením obrázku, snížená intenzita barev | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image7.asm |
20 | gfx4_image8.asm | postupná změna barvy pozadí | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image8.asm |
21 | gfx6_putpixel1.asm | vykreslení pixelu, základní varianta se 16bitovým násobením | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel1.asm |
22 | gfx6_putpixel2.asm | vykreslení pixelu, varianta s osmibitovým násobením | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel2.asm |
23 | gfx6_putpixel3.asm | vykreslení pixelu, varianta bez násobení | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel3.asm |
24 | gfx6_putpixel4.asm | vykreslení pixelu přes obrázek, nekorektní chování (přepis obrázku) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel4.asm |
25 | gfx6_putpixel5.asm | vykreslení pixelu přes obrázek, korektní varianta pro bílé pixely | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel5.asm |
26 | cga_text_mode1.asm | standardní textový režim s rozlišením 40×25 znaků | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_mode1.asm |
27 | cga_text_mode3.asm | standardní textový režim s rozlišením 80×25 znaků | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_mode3.asm |
28 | cga_text_mode_intensity.asm | změna významu nejvyššího bitu atributového bajtu: vyšší intenzita namísto blikání | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_mode_intensity.asm |
29 | cga_text_mode_cursor.asm | změna tvaru textového kurzoru | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_mode_cursor.asm |
30 | cga_text_gfx1.asm | zobrazení „rastrové mřížky“: pseudografický režim 160×25 pixelů (interně textový režim) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_gfx1.asm |
31 | cga_text_mode_char_height.asm | změna výšky znaků | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_mode_char_height.asm |
32 | cga_text_160×100.asm | grafický režim 160×100 se šestnácti barvami (interně upravený textový režim) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_160×100.asm |
33 | hercules_text_mode1.asm | využití standardního textového režimu společně s kartou Hercules | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_text_mode1.asm |
34 | hercules_text_mode2.asm | zákaz blikání v textových režimech | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_text_mode2.asm |
35 | hercules_turn_off.asm | vypnutí generování video signálu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_turn_off.asm |
36 | hercules_gfx_mode1.asm | přepnutí karty Hercules do grafického režimu (základní varianta) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_gfx_mode1.asm |
37 | hercules_gfx_mode2.asm | přepnutí karty Hercules do grafického režimu (vylepšená varianta) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_gfx_mode2.asm |
38 | hercules_putpixel.asm | subrutina pro vykreslení jediného pixelu na kartě Hercules | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_putpixel.asm |
39 | ega_text_mode_80×25.asm | standardní textový režim 80×25 znaků na kartě EGA | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_text_mode_80×25.asm |
40 | ega_text_mode_80×43.asm | zobrazení 43 textových řádků na kartě EGA | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_text_mode_80×43.asm |
41 | ega_gfx_mode_320×200.asm | přepnutí do grafického režimu 320×200 pixelů se šestnácti barvami | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_gfx_mode_320×200.asm |
42 | ega_gfx_mode_640×200.asm | přepnutí do grafického režimu 640×200 pixelů se šestnácti barvami | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_gfx_mode_640×200.asm |
43 | ega_gfx_mode_640×350.asm | přepnutí do grafického režimu 640×350 pixelů se čtyřmi nebo šestnácti barvami | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_gfx_mode_640×350.asm |
44 | ega_gfx_mode_bitplanes1.asm | ovládání zápisu do bitových rovin v planárních grafických režimech (základní způsob) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_gfx_mode_bitplanes1.asm |
45 | ega_gfx_mode_bitplanes2.asm | ovládání zápisu do bitových rovin v planárních grafických režimech (rychlejší způsob) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_gfx_mode_bitplanes2.asm |
46 | ega_320×200_putpixel.asm | vykreslení pixelu v grafickém režimu 320×200 pixelů se šestnácti barvami | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_320×200_putpixel.asm |
47 | ega_640×350_putpixel.asm | vykreslení pixelu v grafickém režimu 640×350 pixelů se šestnácti barvami | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_640×350_putpixel.asm |
48 | ega_standard_font.asm | použití standardního fontu grafické karty EGA | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_standard_font.asm |
49 | ega_custom_font.asm | načtení vlastního fontu s jeho zobrazením | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_custom_font.asm |
50 | ega_palette1.asm | změna barvové palety (všech 16 barev) v grafickém režimu 320×200 se šestnácti barvami | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_palette1.asm |
51 | ega_palette2.asm | změna barvové palety (všech 16 barev) v grafickém režimu 640×350 se šestnácti barvami | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_palette2.asm |
52 | ega_palette3.asm | změna všech barev v barvové paletě s využitím programové smyčky | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_palette3.asm |
53 | ega_palette4.asm | změna všech barev, včetně barvy okraje, v barvové paletě voláním funkce BIOSu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_palette4.asm |
54 | vga_text_mode_80×25.asm | standardní textový režim 80×25 znaků na kartě VGA | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_80×25.asm |
55 | vga_text_mode_80×50.asm | zobrazení 50 a taktéž 28 textových řádků na kartě VGA | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_80×50.asm |
56 | vga_text_mode_intensity1.asm | změna chování atributového bitu pro blikání (nebezpečná varianta změny registrů) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_intensity1.asm |
57 | vga_text_mode_intensity2.asm | změna chování atributového bitu pro blikání (bezpečnější varianta změny registrů) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_intensity2.asm |
58 | vga_text_mode_9th_column.asm | modifikace způsobu zobrazení devátého sloupce ve znakových režimech (720 pixelů na řádku) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_9th_column.asm |
59 | vga_text_mode_cursor_shape.asm | změna tvaru textového kurzoru na grafické kartě VGA | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_cursor_shape.asm |
60 | vga_text_mode_custom_font.asm | načtení vlastního fontu s jeho zobrazením | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_custom_font.asm |
61 | vga_gfx_mode_640×480.asm | přepnutí do grafického režimu 640×480 pixelů se šestnácti barvami, vykreslení vzorků | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_640×480.asm |
62 | vga_gfx_mode_320×200.asm | přepnutí do grafického režimu 320×200 pixelů s 256 barvami, vykreslení vzorků | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_320×200.asm |
63 | vga_gfx_mode_palette.asm | změna všech barev v barvové paletě grafické karty VGA | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_palette.asm |
64 | vga_gfx_mode_dac1.asm | využití DAC (neočekávané výsledky) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_dac1.asm |
65 | vga_gfx_mode_dac2.asm | využití DAC (očekávané výsledky) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_dac2.asm |
66 | vga_640×480_putpixel.asm | realizace algoritmu pro vykreslení pixelu v grafickém režimu 640×480 pixelů se šestnácti barvami | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_640×480_putpixel.asm |
67 | vga_320×200_putpixel1.asm | realizace algoritmu pro vykreslení pixelu v grafickém režimu 320×200 s 256 barvami (základní varianta) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_putpixel1.asm |
68 | vga_320×200_putpixel2.asm | realizace algoritmu pro vykreslení pixelu v grafickém režimu 320×200 s 256 barvami (rychlejší varianta) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_putpixel2.asm |
69 | vga_gfx_mode_dac3.asm | přímé využití DAC v grafickém režimu 13h | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_dac3.asm |
70 | vga_gfx_mode_unchained_step1.asm | zobrazení barevných pruhů v režimu 13h | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_unchained_step1.asm |
71 | vga_gfx_mode_unchained_step2.asm | vypnutí zřetězení bitových rovin a změna způsobu adresování pixelů | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_unchained_step2.asm |
72 | vga_gfx_mode_unchained_step3.asm | vykreslení barevných pruhů do vybraných bitových rovin | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_unchained_step3.asm |
73 | vga_gfx_mode_320×400.asm | nestandardní grafický režim s rozlišením 320×400 pixelů a 256 barvami | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_320×400.asm |
74 | vga_320×200_image.asm | zobrazení rastrového obrázku ve standardním grafickém režimu 320×200 pixelů | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_image.asm |
75 | vga_320×200_unchained_image1.asm | zobrazení rastrového obrázku v režimu s nezřetězenými rovinami (nekorektní řešení) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_unchained_image1.asm |
76 | vga_320×200_unchained_image2.asm | zobrazení rastrového obrázku v režimu s nezřetězenými rovinami (korektní řešení) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_unchained_image2.asm |
77 | vga_320×400_unchained_image.asm | zobrazení rastrového obrázku v nestandardním režimu 320×400 pixelů | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×400_unchained_image.asm |
78 | vga_vertical_scroll1.asm | vertikální scrolling na kartě VGA v režimu s rozlišením 320×200 pixelů | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_vertical_scroll1.asm |
79 | vga_vertical_scroll2.asm | vertikální scrolling na kartě VGA v režimu s rozlišením 320×400 pixelů | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_vertical_scroll2.asm |
80 | vga_split_screen1.asm | režim split-screen a scrolling, nefunční varianta | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_split_screen1.asm |
81 | vga_split_screen2.asm | režim split-screen a scrolling, plně funkční varianta | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_split_screen2.asm |
82 | vga_horizontal_scroll1.asm | horizontální scrolling bez rozšíření počtu pixelů na virtuálním řádku | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_horizontal_scroll1.asm |
83 | vga_horizontal_scroll2.asm | horizontální scrolling s rozšířením počtu pixelů na virtuálním řádku | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_horizontal_scroll2.asm |
84 | vga_horizontal_scroll3.asm | jemný horizontální scrolling s rozšířením počtu pixelů na virtuálním řádku | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_horizontal_scroll3.asm |
85 | vga_320×240_image.asm | nastavení grafického režimu Mode-X, načtení a vykreslení obrázku, scrolling | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×240_image.asm |
86 | io.asm | knihovna maker pro I/O operace | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/io.asm |
87 | vga_lib.asm | knihovna maker a podprogramů pro programování karty VGA | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_lib.asm |
88 | vga_320×240_lib.asm | nastavení grafického režimu Mode-X, tentokrát knihovními funkcemi | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×240_lib.asm |
89 | vga_bitblt1.asm | první (naivní) implementace operace BitBLT | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_bitblt1.asm |
90 | vga_bitblt2.asm | operace BitBLT s výběrem bitových rovin pro zápis | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_bitblt2.asm |
91 | vga_bitblt3.asm | operace BitBLT s výběrem bitových rovin pro čtení i zápis | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_bitblt3.asm |
92 | vga_bitblt4.asm | korektní BitBLT pro 16barevný režim, realizace makry | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_bitblt4.asm |
93 | vga_bitblt5.asm | korektní BitBLT pro 16barevný režim, realizace podprogramem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_bitblt5.asm |
94 | vga_bitblt_rotate.asm | zápisový režim s rotací bajtu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_bitblt_rotate.asm |
95 | vga_bitblt_fast.asm | rychlá korektní 32bitová operace typu BitBLT | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_bitblt_fast.asm |
96 | vga_320×400_bitblt1.asm | přenos obrázku v režimu 320×400 operací BitBLT (neúplná varianta) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×400_bitblt1.asm |
97 | vga_320×400_bitblt2.asm | přenos obrázku v režimu 320×400 operací BitBLT (úplná varianta) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×400_bitblt2.asm |
98 | vga_write_modes1.asm | volitelné zápisové režimy grafické karty VGA, zápis bez úpravy latche | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_write_modes1.asm |
99 | vga_write_modes2.asm | volitelné zápisové režimy grafické karty VGA, zápis s modifikací latche | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_write_modes2.asm |
100 | vga_write_modes3.asm | volitelné zápisové režimy grafické karty VGA, cílená modifikace latche vzorkem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_write_modes3.asm |
101 | instruction_jump.asm | použití instrukce JMP | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_jump.asm |
102 | instruction_jnz.asm | použití instrukce JNZ pro realizaci programové smyčky | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_jnz.asm |
103 | instruction_jz_jmp.asm | použití instrukcí JZ a JMP pro realizaci programové smyčky | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_jz_jmp.asm |
104 | instruction_loop.asm | použití instrukce LOOP pro realizaci programové smyčky | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_loop.asm |
105 | instruction_template.asm | šablona všech následujících demonstračních příkladů | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_template.asm |
106 | instruction_print_hex.asm | tisk osmibitové hexadecimální hodnoty | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_print_hex.asm |
107 | instruction_xlat.asm | využití instrukce XLAT pro získání tisknutelné hexadecimální cifry | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_xlat.asm |
108 | instruction_daa.asm | operace součtu s využitím binární i BCD aritmetiky | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_daa.asm |
109 | instruction_daa_sub.asm | instrukce DAA po provedení operace rozdílu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_daa_sub.asm |
110 | instruction_das.asm | instrukce DAS po provedení operace rozdílu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_das.asm |
111 | instruction_aaa.asm | korekce výsledku na jedinou BCD cifru operací AAA | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_aaa.asm |
112 | instruction_mul.asm | ukázka výpočtu součinu dvou osmibitových hodnot | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_mul.asm |
113 | instruction_aam.asm | BCD korekce po výpočtu součinu instrukcí AAM | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_aam.asm |
114 | instruction_stosb.asm | blokový zápis dat instrukcí STOSB | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_stosb.asm |
115 | instruction_rep_stosb.asm | opakované provádění instrukce STOSB | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_rep_stosb.asm |
116 | instruction_lodsb.asm | čtení dat instrukcí LODSB | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_lodsb.asm |
117 | instruction_movsb.asm | přenos jednoho bajtu instrukcí MOVSB | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_movsb.asm |
118 | instruction_rep_movsb.asm | blokový přenos po bajtech instrukcí MOVSB | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_rep_movsb.asm |
119 | instruction_rep_scas.asm | vyhledávání v řetězci instrukcí SCAS | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_rep_scas.asm |
120 | vga_320×200_image_0B.asm | výsledek blokového přenosu ve chvíli, kdy je CX=0 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_image_0B.asm |
121 | vga_320×200_image_64kB.asm | výsledek blokového přenosu ve chvíli, kdy je CX=0×ffff | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_image_64kB.asm |
122 | vga_320×200_image_movsb.asm | blokový přenos v rámci obrazové paměti instrukcí REP MOVSB | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_image_movsb.asm |
123 | vga_320×200_image_movsw.asm | blokový přenos v rámci obrazové paměti instrukcí REP MOVSW | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_image_movsw.asm |
124 | vga_320×200_image_movsd.asm | blokový přenos v rámci obrazové paměti instrukcí REP MOVSD | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_image_movsd.asm |
125 | vga_320×200_image_movsb_forward.asm | blokový přenos překrývajících se bloků paměti (zvyšující se adresy) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_image_movsb_forward.asm |
126 | vga_320×200_image_movsb_backward1.asm | blokový přenos překrývajících se bloků paměti (snižující se adresy, nekorektní nastavení) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_image_movsb_backward1.asm |
127 | vga_320×200_image_movsb_backward2.asm | blokový přenos překrývajících se bloků paměti (snižující se adresy, korektní nastavení) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_image_movsb_backward2.asm |
128 | sound_bell.asm | přehrání zvuku pomocí tisku ASCII znaku BELL | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_bell.asm |
129 | sound_beep.asm | přehrání zvuku o zadané frekvenci na PC Speakeru | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_beep.asm |
130 | sound_play_pitch.asm | přehrání zvuku o zadané frekvenci na PC Speakeru, použití maker | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_play_pitch.asm |
131 | sound_opl2_basic.asm | přehrání komorního A na OPL2 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl2_basic.asm |
132 | sound_opl2_table.asm | přehrání komorního A na OPL2, použití tabulky s hodnotami registrů | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl2_table.asm |
133 | sound_opl2_table2.asm | přepis tabulky s obsahy registrů pro přehrání komorního A | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl2_table2.asm |
134 | sound_key_on.asm | přímé ovládání bitu KEY ON mezerníkem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_key_on.asm |
135 | sound_adsr.asm | nastavení obálky pro tón přehrávaný prvním kanálem | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_adsr.asm |
136 | sound_modulation.asm | řízení frekvence modulátoru klávesami 1 a 0 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_modulation.asm |
137 | keyboard_basic.asm | přímá práce s klávesnicí IBM PC | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/keyboard_basic.asm |
138 | sound_stereo_opl2.asm | stereo zvuk v konfiguraci DualOPL2 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_stereo_opl2.asm |
139 | sound_opl2_multichannel.asm | vícekanálový zvuk na OPL2 (klávesy), delší varianta | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl2_multichannel.asm |
140 | sound_opl2_multichannel2.asm | vícekanálový zvuk na OPL2 (klávesy), kratší varianta | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl2_multichannel2.asm |
141 | sound_opl3_stereo1.asm | stereo výstup na OPL3 (v kompatibilním režimu) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl3_stereo1.asm |
142 | sound_opl3_stereo2.asm | stereo výstup na OPL3 (v režimu OPL3) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl3_stereo2.asm |
143 | sound_opl3_multichannel.asm | vícekanálový zvuk na OPL3 (klávesy) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl3_multichannel.asm |
144 | sound_opl3_waveform1.asm | interaktivní modifikace tvaru vlny u prvního operátoru | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl3_waveform1.asm |
145 | sound_opl3_waveform2.asm | oprava chyby: povolení režimu kompatibilního s OPL3 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl3_waveform2.asm |
146 | sound_opl3_waveform3.asm | vliv tvaru vln na zvukový kanál s FM syntézou | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl3_waveform3.asm |
147 | sound_opl3_waveform4.asm | modifikace tvaru vlny nosné vlny i modulátoru | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl3_waveform4.asm |
148 | sound_opl3_4operators1.asm | výběr AM/FM režimu ve čtyřoperátorovém nastavení | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl3_4operators1.asm |
149 | sound_opl3_4operators2.asm | výběr AM/FM režimu ve čtyřoperátorovém nastavení | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl3_4operators2.asm |
150 | timer_basic.asm | základní obsluha přerušení od časovače/čítače | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/timer_basic.asm |
151 | timer_restore.asm | obnovení původní obsluhy přerušení při ukončování aplikace | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/timer_restore.asm |
152 | timer_restore_better_structure.asm | refaktoring předchozího demonstračního příkladu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/timer_restore_better_structure.asm |
153 | timer_faster_clock.asm | zrychlení čítače na 100 přerušení za sekundu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/timer_faster_clock.asm |
154 | instruction_push_imm.asm | instrukce PUSH s konstantou | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_push_imm.asm |
155 | instruction_imul_imm.asm | instrukce IMUL s konstantou | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_imul_imm.asm |
156 | instruction_into1.asm | instrukce INTO s obsluhou přerušení | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_into1.asm |
157 | instruction_into2.asm | instrukce INTO s obsluhou přerušení | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_into2.asm |
158 | instruction_bound1.asm | instrukce BOUND s obsluhou přerušení (nekorektní řešení) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_bound1.asm |
159 | instruction_bound2.asm | instrukce BOUND s obsluhou přerušení (korektní řešení) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_bound2.asm |
160 | vga_320×200_putpixel286.asm | instrukce bitového posunu s konstantou větší než 1 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_putpixel286.asm |
161 | instruction_push_pop.asm | instrukce PUSH a POP se všemi pracovními registry | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_push_pop.asm |
162 | instruction_push_pop_B.asm | instrukce s novými segmentovými registry | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_push_pop_B.asm |
163 | instruction_near_jz_jmp.asm | blízké skoky | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_near_jz_jmp.asm |
164 | instruction_bsf.asm | nová instrukce BSF | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_bsf.asm |
165 | instruction_bsr.asm | nová instrukce BSR | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_bsr.asm |
166 | instruction_add_32bit.asm | 32bitový součet | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_add_32bit.asm |
167 | instruction_inc_32bit.asm | 32bitová instrukce INC v šestnáctibitovém režimu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_inc_32bit.asm |
168 | instruction_inc_32bit_B.asm | 32bitová instrukce INC v 32bitovém režimu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_inc_32bit_B.asm |
169 | ems_status.asm | zjištění stavu (emulace) paměti EMS | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ems_status.asm |
170 | ems_total_mem.asm | získání celkové kapacity paměti EMS v blocích | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ems_total_mem.asm |
171 | ems_free_mem.asm | získání volné kapacity paměti EMS v blocích | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ems_free_mem.asm |
172 | xms_free_mem.asm | získání volné kapacity paměti XMS v blocích | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/xms_free_mem.asm |
173 | vga_320×200_short_address1.asm | blokový přenos provedený v rámci prostoru segmentu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_short_address1.asm |
174 | vga_320×200_short_address2.asm | rozepsaný blokový přenos provedený v rámci prostoru segmentu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_short_address2.asm |
175 | vga_320×200_short_address3.asm | přenos nelze provést přes hranici offsetu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_short_address3.asm |
176 | vga_320×200_short_address4.asm | přenos nelze provést přes hranici offsetu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_short_address4.asm |
177 | vga_320×200_long_address1.asm | 32bitový blokový přenos | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_long_address1.asm |
178 | vga_320×200_long_address2.asm | rozepsaný 32bitový blokový přenos provedený v rámci prostoru segmentu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_long_address2.asm |
179 | vga_320×200_long_address3.asm | přístup do obrazové paměti přes segment 0×0000 a 32bitový offset | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_long_address3.asm |
180 | vga_320×200_long_address4.asm | otestování, jak lze přenášet data s využitím 32bitového offsetu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_long_address4.asm |
181 | print_msw.asm | přečtení a zobrazení obsahu speciálního registru MSW | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/print_msw.asm |
182 | print_cr0.asm | přečtení a zobrazení obsahu speciálního registru CR0 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/print_cr0.asm |
183 | prot_mode286.asm | přechod do chráněného režimu na čipech Intel 80286 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/prot_mode286.asm |
184 | prot_mode386.asm | přechod do chráněného režimu na čipech Intel 80386 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/prot_mode386.asm |
185 | prot_mode_back_to_real_mode286.asm | přechod mezi reálným režimem a chráněným režimem i zpět na čipech Intel 80286 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/prot_mode_back_to_real_mode286.asm |
186 | prot_mode_back_to_real_mode386.asm | přechod mezi reálným režimem a chráněným režimem i zpět na čipech Intel 80386 | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/prot_mode_back_to_real_mode386.asm |
187 | prot_mode_check.asm | test, zda se mikroprocesor již nachází v chráněném režimu | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/prot_mode_check.asm |
188 | unreal_mode.asm | nastavení nereálného režimu (platné pro Intel 80386) | https://github.com/tisnik/8bit-fame/blob/master/pc-dos/unreal_mode.asm |
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