Od reálného režimu k režimu chráněnému na procesorech 80286 a 80386 (2.část)

31. 12. 2024
Doba čtení: 63 minut

Sdílet

Autor: Depositphotos
Přechod do chráněného režimu (a zpět) na mikroprocesorech Intel se podobá složitému rituálu. Všechny operace je nutné vykonat v určitém pořadí a naslepo: bez možnosti ladění nebo sledování činnosti PC.

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

20. Odkazy na Internetu

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
Poznámka: nejvíce starostí tedy Intelu způsoboval volitelný matematický koprocesor a jeho emulace i rozdílné chování 80287 od 80387.

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 CR0CR8, ladicí registry DR0DR7 (některé ovšem chybí), registry pro testování TR3TR7 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
Poznámka: další přímé operace s těmito registry však nebyly možné – tedy ani maskování pomocí AND nebo OR!

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:

  1. 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)
  2. Naplnění globální tabulky deskriptorů (GDT)
  3. Naplnění struktury s popisem GDT (délka a adresa)
  4. Zákaz přerušení
  5. Naplnění tabulky s deskriptory pro přerušovací subrutiny tak, že je nastaven limit na nulu (někdy lze vynechat)
  6. Nastavení bitu PEMSW nebo CR0 – tedy skutečný přechod do chráněného režimu
  7. Provedení (dlouhého) skoku, aby se vymazala instrukční cache (teoreticky není nutné, pokus se zůstává v 16bitovém režimu)
  8. Načtení segmentových registrů; tím se načte i minule zmíněná cache s deskriptory
  9. Inicializace SS:SP (zásobník)
  10. Naplnění tabulky s deskriptory pro přerušovací subrutiny na požadované hodnoty (již bez nulového limitu)
  11. 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
Poznámka: test, zda se systém nachází v chráněném režimu, může stále používat MSW.

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.

Poznámka: v praxi se při přepínání do chráněného režimu provádí ještě jeden podobný skok. Tentokrát se jedná o skok dlouhý (far jump), jehož cílem je naplnění registru CS. Sice stejnou hodnotou, jakou tento registr již obsahoval, ale víme, že každá změna segmentového registru naplní i příslušnou skrytou část (deskriptor) v cache deskriptorů. To má zásadní význam především u 386, kde je možné přepnutí do 32bitového režimu.

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:
Poznámka: samozřejmě to není tak jednoduché, neboť je nutné nastavit tabulku deskriptorů, mít zakázané přerušení v době přepínání režimů atd. Ovšem cesta je celkem zřejmá.

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í:

  1. 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.
  2. Zákaz přerušení (můžeme ho však zakázat i po naplnění GDT).
  3. Naplnění globální tabulky deskriptorů (GDT), která bude obsahovat „nulový deskriptor“ a druhý deskriptor bez limitů
  4. Naplnění struktury s popisem GDT (délka a adresa)
  5. Uložení obsahu segmentového registru DS, později ho obnovíme (přitom DS=SS)
  6. Nastavení bitu PE v registru CR0 – tedy skutečný přechod do chráněného režimu
  7. Provedení skoku na další adresu – vymazání instrukční fronty
  8. Načtení segmentových registrů; tím se načte i minule zmíněná cache s deskriptory
  9. Vynulování bitu PE v registru CR0 – tedy návrat do reálného režimu
  10. Provedení skoku na další adresu – vymazání instrukční fronty
  11. Inicializace registru SS (zásobník)
  12. Povolení přerušení
  13. 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.

bitcoin školení listopad 24

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_mov­sb_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_mov­sb_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_mov­sb_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_mo­de286.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_mo­de386.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

  1. The Intel 8088 Architecture and Instruction Set
    https://people.ece.ubc.ca/~ed­c/464/lectures/lec4.pdf
  2. x86 Opcode Structure and Instruction Overview
    https://pnx.tf/files/x86_op­code_structure_and_instruc­tion_overview.pdf
  3. x86 instruction listings (Wikipedia)
    https://en.wikipedia.org/wi­ki/X86_instruction_listin­gs
  4. x86 assembly language (Wikipedia)
    https://en.wikipedia.org/wi­ki/X86_assembly_language
  5. Intel Assembler (Cheat sheet)
    http://www.jegerlehner.ch/in­tel/IntelCodeTable.pdf
  6. 25 Microchips That Shook the World
    https://spectrum.ieee.org/tech-history/silicon-revolution/25-microchips-that-shook-the-world
  7. Chip Hall of Fame: MOS Technology 6502 Microprocessor
    https://spectrum.ieee.org/tech-history/silicon-revolution/chip-hall-of-fame-mos-technology-6502-microprocessor
  8. Chip Hall of Fame: Intel 8088 Microprocessor
    https://spectrum.ieee.org/tech-history/silicon-revolution/chip-hall-of-fame-intel-8088-microprocessor
  9. Jak se zrodil procesor?
    https://www.root.cz/clanky/jak-se-zrodil-procesor/
  10. Apple II History Home
    http://apple2history.org/
  11. The 8086/8088 Primer
    https://www.stevemorse.or­g/8086/index.html
  12. flat assembler: Assembly language resources
    https://flatassembler.net/
  13. FASM na Wikipedii
    https://en.wikipedia.org/wiki/FASM
  14. Fresh IDE FASM inside
    https://fresh.flatassembler.net/
  15. MS-DOS Version 4.0 Programmer's Reference
    https://www.pcjs.org/docu­ments/books/mspl13/msdos/dos­ref40/
  16. DOS API (Wikipedia)
    https://en.wikipedia.org/wiki/DOS_API
  17. Bit banging
    https://en.wikipedia.org/wi­ki/Bit_banging
  18. IBM Basic assembly language and successors (Wikipedia)
    https://en.wikipedia.org/wi­ki/IBM_Basic_assembly_lan­guage_and_successors
  19. X86 Assembly/Bootloaders
    https://en.wikibooks.org/wi­ki/X86_Assembly/Bootloaders
  20. Počátky grafiky na PC: grafické karty CGA a Hercules
    https://www.root.cz/clanky/pocatky-grafiky-na-pc-graficke-karty-cga-a-hercules/
  21. 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/
  22. Karta EGA: první použitelná barevná grafika na PC
    https://www.root.cz/clanky/karta-ega-prvni-pouzitelna-barevna-grafika-na-pc/
  23. RGB Classic Games
    https://www.classicdosgames.com/
  24. Turbo Assembler (Wikipedia)
    https://en.wikipedia.org/wi­ki/Turbo_Assembler
  25. Microsoft Macro Assembler
    https://en.wikipedia.org/wi­ki/Microsoft_Macro_Assembler
  26. IBM Personal Computer (Wikipedia)
    https://en.wikipedia.org/wi­ki/IBM_Personal_Computer
  27. Intel 8251
    https://en.wikipedia.org/wi­ki/Intel_8251
  28. Intel 8253
    https://en.wikipedia.org/wi­ki/Intel_8253
  29. Intel 8255
    https://en.wikipedia.org/wi­ki/Intel_8255
  30. Intel 8257
    https://en.wikipedia.org/wi­ki/Intel_8257
  31. Intel 8259
    https://en.wikipedia.org/wi­ki/Intel_8259
  32. Support/peripheral/other chips – 6800 family
    http://www.cpu-world.com/Support/6800.html
  33. Motorola 6845
    http://en.wikipedia.org/wi­ki/Motorola_6845
  34. The 6845 Cathode Ray Tube Controller (CRTC)
    http://www.tinyvga.com/6845
  35. CRTC operation
    http://www.6502.org/users/an­dre/hwinfo/crtc/crtc.html
  36. The 6845 Cathode Ray Tube Controller (CRTC)
    http://www.tinyvga.com/6845
  37. Motorola 6845 and bitwise graphics
    https://retrocomputing.stac­kexchange.com/questions/10996/mo­torola-6845-and-bitwise-graphics
  38. IBM Monochrome Display Adapter
    http://en.wikipedia.org/wi­ki/Monochrome_Display_Adap­ter
  39. Color Graphics Adapter
    http://en.wikipedia.org/wi­ki/Color_Graphics_Adapter
  40. Color Graphics Adapter and the Brown color in IBM 5153 Color Display
    https://www.aceinnova.com/en/e­lectronics/cga-and-the-brown-color-in-ibm-5153-color-display/
  41. The Modern Retrocomputer: An Arduino Driven 6845 CRT Controller
    https://hackaday.com/2017/05/14/the-modern-retrocomputer-an-arduino-driven-6845-crt-controller/
  42. flat assembler: Assembly language resources
    https://flatassembler.net/
  43. FASM na Wikipedii
    https://en.wikipedia.org/wiki/FASM
  44. Fresh IDE FASM inside
    https://fresh.flatassembler.net/
  45. MS-DOS Version 4.0 Programmer's Reference
    https://www.pcjs.org/docu­ments/books/mspl13/msdos/dos­ref40/
  46. DOS API (Wikipedia)
    https://en.wikipedia.org/wiki/DOS_API
  47. IBM Basic assembly language and successors (Wikipedia)
    https://en.wikipedia.org/wi­ki/IBM_Basic_assembly_lan­guage_and_successors
  48. X86 Assembly/Arithmetic
    https://en.wikibooks.org/wi­ki/X86_Assembly/Arithmetic
  49. Art of Assembly – Arithmetic Instructions
    http://oopweb.com/Assembly/Do­cuments/ArtOfAssembly/Volu­me/Chapter6/CH06–2.html
  50. ASM Flags
    http://www.cavestory.org/gu­ides/csasm/guide/asm_flag­s.html
  51. Status Register
    https://en.wikipedia.org/wi­ki/Status_register
  52. Linux assemblers: A comparison of GAS and NASM
    http://www.ibm.com/develo­perworks/library/l-gas-nasm/index.html
  53. Programovani v assembleru na OS Linux
    http://www.cs.vsb.cz/gryga­rek/asm/asmlinux.html
  54. Is it worthwhile to learn x86 assembly language today?
    https://www.quora.com/Is-it-worthwhile-to-learn-x86-assembly-language-today?share=1
  55. Why Learn Assembly Language?
    http://www.codeproject.com/Ar­ticles/89460/Why-Learn-Assembly-Language
  56. Is Assembly still relevant?
    http://programmers.stackex­change.com/questions/95836/is-assembly-still-relevant
  57. Why Learning Assembly Language Is Still a Good Idea
    http://www.onlamp.com/pub/a/on­lamp/2004/05/06/writegreat­code.html
  58. Assembly language today
    http://beust.com/weblog/2004/06/23/as­sembly-language-today/
  59. Assembler: Význam assembleru dnes
    http://www.builder.cz/rubri­ky/assembler/vyznam-assembleru-dnes-155960cz
  60. Programming from the Ground Up Book – Summary
    http://savannah.nongnu.or­g/projects/pgubook/
  61. DOSBox
    https://www.dosbox.com/
  62. The C Programming Language
    https://en.wikipedia.org/wi­ki/The_C_Programming_Langu­age
  63. Hercules Graphics Card (HCG)
    https://en.wikipedia.org/wi­ki/Hercules_Graphics_Card
  64. Complete 8086 instruction set
    https://content.ctcd.edu/cou­rses/cosc2325/m22/docs/emu8086in­s.pdf
  65. Complete 8086 instruction set
    https://yassinebridi.github.io/asm-docs/8086_instruction_set.html
  66. 8088 MPH by Hornet + CRTC + DESiRE (final version)
    https://www.youtube.com/wat­ch?v=hNRO7lno_DM
  67. Area 5150 by CRTC & Hornet (Party Version) / IBM PC+CGA Demo, Hardware Capture
    https://www.youtube.com/wat­ch?v=fWDxdoRTZPc
  68. 80×86 Integer Instruction Set Timings (8088 – Pentium)
    http://aturing.umcs.maine­.edu/~meadow/courses/cos335/80×86-Integer-Instruction-Set-Clocks.pdf
  69. Colour Graphics Adapter: Notes
    https://www.seasip.info/Vin­tagePC/cga.html
  70. Restoring A Vintage CGA Card With Homebrew HASL
    https://hackaday.com/2024/06/12/res­toring-a-vintage-cga-card-with-homebrew-hasl/
  71. Demoing An 8088
    https://hackaday.com/2015/04/10/de­moing-an-8088/
  72. Video Memory Layouts
    http://www.techhelpmanual.com/89-video_memory_layouts.html
  73. Screen Attributes
    http://www.techhelpmanual.com/87-screen_attributes.html
  74. IBM PC Family – BIOS Video Modes
    https://www.minuszerodegre­es.net/video/bios_video_mo­des.htm
  75. EGA Functions
    https://cosmodoc.org/topics/ega-functions/#the-hierarchy-of-the-ega
  76. 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/
  77. How 16 colors saved PC gaming – the story of EGA graphics
    https://www.custompc.com/retro-tech/ega-graphics
  78. List of 16-bit computer color palettes
    https://en.wikipedia.org/wi­ki/List_of16-bit_computer_color_palettes
  79. Why were those colors chosen to be the default palette for 256-color VGA?
    https://retrocomputing.stac­kexchange.com/questions/27994/why-were-those-colors-chosen-to-be-the-default-palette-for-256-color-vga
  80. VGA Color Palettes
    https://www.fountainware.com/EX­PL/vga_color_palettes.htm
  81. Hardware Level VGA and SVGA Video Programming Information Page
    http://www.osdever.net/Fre­eVGA/vga/vga.htm
  82. Hardware Level VGA and SVGA Video Programming Information Page – sequencer
    http://www.osdever.net/Fre­eVGA/vga/seqreg.htm
  83. VGA Basics
    http://www.brackeen.com/vga/ba­sics.html
  84. Introduction to VGA Mode ‚X‘
    https://web.archive.org/web/20160414072210/htt­p://fly.srk.fer.hr/GDM/ar­ticles/vgamodex/vgamx1.html
  85. VGA Mode-X
    https://web.archive.org/web/20070123192523/htt­p://www.gamedev.net/referen­ce/articles/article356.asp
  86. Mode-X: 256-Color VGA Magic
    https://downloads.gamedev­.net/pdf/gpbb/gpbb47.pdf
  87. Instruction Format in 8086 Microprocessor
    https://www.includehelp.com/embedded-system/instruction-format-in-8086-microprocessor.aspx
  88. How to use „AND,“ „OR,“ and „XOR“ modes for VGA Drawing
    https://retrocomputing.stac­kexchange.com/questions/21936/how-to-use-and-or-and-xor-modes-for-vga-drawing
  89. VGA Hardware
    https://wiki.osdev.org/VGA_Hardware
  90. Programmer's Guide to Yamaha YMF 262/OPL3 FM Music Synthesizer
    https://moddingwiki.shika­di.net/wiki/OPL_chip
  91. Does anybody understand how OPL2 percussion mode works?
    https://forum.vcfed.org/in­dex.php?threads/does-anybody-understand-how-opl2-percussion-mode-works.60925/
  92. Yamaha YMF262 OPL3 music – MoonDriver for OPL3 DEMO [Oscilloscope View]
    https://www.youtube.com/watch?v=a7I-QmrkAak
  93. Yamaha OPL vs OPL2 vs OPL3 comparison
    https://www.youtube.com/wat­ch?v=5knetge5Gs0
  94. OPL3 Music Crockett's Theme
    https://www.youtube.com/wat­ch?v=HXS008pkgSQ
  95. Bad Apple (Adlib Tracker – OPL3)
    https://www.youtube.com/wat­ch?v=2lEPH6Y3Luo
  96. FM Synthesis Chips, Codecs and DACs
    https://www.dosdays.co.uk/to­pics/fm_synthesizers.php
  97. The Zen Challenge – YMF262 OPL3 Original (For an upcoming game)
    https://www.youtube.com/wat­ch?v=6JlFIFz1CFY
  98. [adlib tracker II techno music – opl3] orbit around alpha andromedae I
    https://www.youtube.com/wat­ch?v=YqxJCu_WFuA
  99. [adlib tracker 2 music – opl3 techno] hybridisation process on procyon-ii
    https://www.youtube.com/wat­ch?v=daSV5mN0sJ4
  100. Hyper Duel – Black Rain (YMF262 OPL3 Cover)
    https://www.youtube.com/wat­ch?v=pu_mzRRq8Ho
  101. IBM 5155–5160 Technical Reference
    https://www.minuszerodegre­es.net/manuals/IBM/IBM_5155_5160_Techni­cal_Reference_6280089_MAR86­.pdf
  102. a ymf262/opl3+pc speaker thing i made
    https://www.youtube.com/watch?v=E-Mx0lEmnZ0
  103. [OPL3] Like a Thunder
    https://www.youtube.com/wat­ch?v=MHf06AGr8SU
  104. (PC SPEAKER) bad apple
    https://www.youtube.com/wat­ch?v=LezmKIIHyUg
  105. Powering devices from PC parallel port
    http://www.epanorama.net/cir­cuits/lptpower.html
  106. Magic Mushroom (demo pro PC s DOSem)
    http://www.crossfire-designs.de/download/articles/sou­ndcards//mushroom.rar
  107. Píseň Magic Mushroom – originál
    http://www.crossfire-designs.de/download/articles/sou­ndcards/speaker_mushroom_con­verted.mp3
  108. Píseň Magic Mushroom – hráno na PC Speakeru
    http://www.crossfire-designs.de/download/articles/sou­ndcards/speaker_mushroom_spe­aker.mp3
  109. Pulse Width Modulation (PWM) Simulation Example
    http://decibel.ni.com/content/docs/DOC-4599
  110. Resistor/Pulse Width Modulation DAC
    http://www.k9spud.com/trax­mod/pwmdac.php
  111. Class D Amplifier
    http://en.wikipedia.org/wi­ki/Electronic_amplifier#Clas­s_D
  112. Covox Speech Thing / Disney Sound Source (1986)
    http://www.crossfire-designs.de/index.php?lang=en&what=ar­ticles&name=showarticle.htm&ar­ticle=soundcards/&page=5
  113. Covox Digital-Analog Converter (Rusky, obsahuje schémata)
    http://phantom.sannata.ru/kon­kurs/netskater002.shtml
  114. PC-GPE on the Web
    http://bespin.org/~qz/pc-gpe/
  115. Keyboard Synthesizer
    http://www.solarnavigator­.net/music/instruments/ke­yboards.htm
  116. FMS – Fully Modular Synthesizer
    http://fmsynth.sourceforge.net/
  117. Javasynth
    http://javasynth.sourceforge.net/
  118. Software Sound Synthesis & Music Composition Packages
    http://www.linux-sound.org/swss.html
  119. Mx44.1 Download Page (software synthesizer for linux)
    http://hem.passagen.se/ja_linux/
  120. Software synthesizer
    http://en.wikipedia.org/wi­ki/Software_synthesizer
  121. Frequency modulation synthesis
    http://en.wikipedia.org/wi­ki/Frequency_modulation_syn­thesis
  122. Yamaha DX7
    http://en.wikipedia.org/wi­ki/Yamaha_DX7
  123. Wave of the Future
    http://www.wired.com/wired/ar­chive/2.03/waveguides_pr.html
  124. Analog synthesizer
    http://en.wikipedia.org/wi­ki/Analog_synthesizer
  125. Minimoog
    http://en.wikipedia.org/wiki/Minimoog
  126. Moog synthesizer
    http://en.wikipedia.org/wi­ki/Moog_synthesizer
  127. Tutorial for Frequency Modulation Synthesis
    http://www.sfu.ca/~truax/fmtut.html
  128. An Introduction To FM
    http://ccrma.stanford.edu/sof­tware/snd/snd/fm.html
  129. John Chowning
    http://en.wikipedia.org/wi­ki/John_Chowning
  130. I'm Impressed, Adlib Music is AMAZING!
    https://www.youtube.com/wat­ch?v=PJNjQYp1ras
  131. Milinda- Diode Milliampere ( OPL3 )
    https://www.youtube.com/wat­ch?v=oNhazT5HG0E
  132. Dune 2 – Roland MT-32 Soundtrack
    https://www.youtube.com/wat­ch?v=kQADZeB-z8M
  133. Interrupts
    https://wiki.osdev.org/In­terrupts#Types_of_Interrup­ts
  134. Assembly8086SoundBlasterDma­SingleCycleMode
    https://github.com/leonardo-ono/Assembly8086SoundBlas­terDmaSingleCycleMode/blob/mas­ter/sbsc.asm
  135. Interrupts in 8086 microprocessor
    https://www.geeksforgeeks­.org/interrupts-in-8086-microprocessor/
  136. Interrupt Structure of 8086
    https://www.eeeguide.com/interrupt-structure-of-8086/
  137. A20 line
    https://en.wikipedia.org/wi­ki/A20_line
  138. Extended memory
    https://en.wikipedia.org/wi­ki/Extended_memory#eXtended_Me­mory_Specification_(XMS)
  139. Expanded memory
    https://en.wikipedia.org/wi­ki/Expanded_memory
  140. Protected mode
    https://en.wikipedia.org/wi­ki/Protected_mode
  141. Virtual 8086 mode
    https://en.wikipedia.org/wi­ki/Virtual_8086_mode
  142. Unreal mode
    https://en.wikipedia.org/wi­ki/Unreal_mode
  143. DOS memory management
    https://en.wikipedia.org/wi­ki/DOS_memory_management
  144. Upper memory area
    https://en.wikipedia.org/wi­ki/Upper_memory_area
  145. Removing the Mystery from SEGMENT : OFFSET Addressing
    https://thestarman.pcminis­try.com/asm/debug/Segments­.html
  146. Segment descriptor
    https://en.wikipedia.org/wi­ki/Segment_descriptor
  147. 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/qu­estions/45094696/when-using-a-32-bit-register-to-address-memory-in-the-real-mode-contents-of-the
  148. A Brief History of Unreal Mode
    https://www.os2museum.com/wp/a-brief-history-of-unreal-mode/
  149. Segment Limits
    https://wiki.osdev.org/Segment_Limits
  150. How do 32 bit addresses in real mode work?
    https://forum.osdev.org/vi­ewtopic.php?t=30642
  151. The LOADALL Instruction by Robert Collins
    https://www.rcollins.org/ar­ticles/loadall/tspec_a3_doc­.html
  152. How do you put a 286 in Protected Mode?
    https://retrocomputing.stac­kexchange.com/questions/7683/how-do-you-put-a-286-in-protected-mode
  153. Control register
    https://en.wikipedia.org/wi­ki/Control_register
  154. CPU Registers x86
    https://wiki.osdev.org/CPU_Re­gisters_x86
  155. x86 Assembly/Protected Mode
    https://en.wikibooks.org/wi­ki/X86_Assembly/Protected_Mo­de
  156. MSW: Machine Status Word
    https://web.itu.edu.tr/kes­gin/mul06/intel/intel_msw­.html
ikonka

Zajímá vás toto téma? Chcete se o něm dozvědět víc?

Objednejte si upozornění na nově vydané články do vašeho mailu. Žádný článek vám tak neuteče.

Autor článku

Vystudoval VUT FIT a v současné době pracuje na projektech vytvářených v jazycích Python a Go.