Od reálného režimu k režimu chráněnému na 80286 a 80386

17. 12. 2024
Doba čtení: 65 minut

Sdílet

Autor: Depositphotos
Seznámíme se s vlastnostmi čipů 80286 a 80386, které souvisejí s reálným režimem, nereálným (unreal) režimem a režimem chráněným. Zabývat se budeme cachí s deskriptory segmentů, která se projevuje i v reálném režimu.

Obsah

1. Od reálného režimu k režimu chráněnému na procesorech 80286 a 80386

2. Šestnáctibitové adresy v reálném režimu

3. Šestnáctibitové adresy na čipech druhé a třetí generace 80×86

4. Rozepsání programové smyčky pro blokový přenos mezi dvěma segmenty

5. Offset přesahující hranici segmentu

6. Druhý příklad s offsetem, který přesahuje hranice segmentu

7. Chování mikroprocesoru Intel 80386 v reálném režimu

8. Skrytá část 80286: cache s deskriptory segmentů

9. Cache s deskriptory segmentů v reálném režimu

10. 32bitové adresy v reálném režimu

11. Deskriptory segmentů na čipech 80386

12. Ukázka adresace 32bitovými registry v reálném režimu

13. Rozepsání programové smyčky: přenos po 32bitech, offsety jsou realizovány 32bitovými registry

14. Přístup do obrazové paměti přes segment 0×0000 a 32bitový offset

15. Překročení limitu segmentu s využitím posunu adresy o konstantu

16. Naplnění cache s deskriptory přes „utajenou“ instrukci LOADALL

17. LOADALL na mikroprocesorech 80286

18. LOADALL na mikroprocesorech 80386

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

V předchozím článku o nechvalně známém limitu 640kB RAM dostupné v operačním systému DOS jsme se zmínili o některých technikách, které vývojářům umožňovaly tuto bariéru překročit a využít tak celou dostupnou paměť počítače vybaveného mikroprocesory Intel 80286 a Intel 80386 [*]. Tyto techniky (kromě využití HMA, což nám však přidalo jen 65530 bajtů) nějakým způsobem musely pracovat s novým subsystémem mikroprocesorů – konkrétně se subsystémem určeným pro provozování mikroprocesorů v takzvaném chráněném režimu (protected mode). A – jako obvykle – se i v této oblasti nacházela spousta pastí, ať již způsobených snahou o zpětnou kompatibilitu, tak i „optimalizacemi“ a opomenutími na straně návrhu mikroprocesorů. Na druhou stranu však bylo možné využít různé triky a celý koncept chráněného režimu vhodným způsobem ohnout; tak, že se větší množství operační paměti dalo využít i v režimu reálném.

Poznámka: stále budu psát Intel 80286 a Intel 80386, i když existovali i další výrobci těchto mikroprocesorů. Ti však (tehdy!) nabízeli čipy plně kompatibilní s Intelem na úrovni instrukcí i podporovaných režimů. A i když se mohlo jednat o rychlejší mikroprocesory (Am386DX na 40MHz, IBM 386SLC s větší cache), tito sekundární výrobci stále jen následovali Intel, což se změnilo až mnohem později.

Ještě před tím, než si ukážeme možnosti chráněného režimu, je vhodné si zopakovat, jak se vlastně mikroprocesory chovaly v režimu reálném z pohledu adresování paměti. Protože i v běžném reálném režimu se dají využít některé vlastnosti režimu chráněného – jedná se o takzvané nereálné režimy (unreal mode), což ve skutečnosti nejsou nové režimy činnosti mikroprocesoru, ale ohnutí vlastností subsystému určeného pro chráněný režim.

Poznámka: v článku budu postupovat odlišně, než to bývalo v dokumentaci běžné. Nepopíšu totiž ihned všechny vlastnosti chráněného režimu; to je zbytečně velký skok. Nejdříve se seznámíme s konceptem deskriptorů, které lze docela dobře použít i v režimu reálném a provádět různé (řekněme neoficiální) triky s pamětí. S touto problematikou souvisí i instrukce LOADALL (ve dvou variantách), na níž nelze v souvislosti s čipy 80286 a 80386 zapomenout.

2. Šestnáctibitové adresy v reálném režimu

Vraťme se na chvíli k prapůvodním čipům Intel 8086/8088. Připomeňme si, že tyto čipy měly vyvedených jen dvacet adresových vodičů a dokázaly tak adresovat přesně 1MB paměti. Výpočet adresy probíhal na základě kombinace segmentu a offsetu:

adresa = segment × 16 + offset

Jenže to není přesná (resp. ucelená) informace. Je nutno dodat, jakým způsobem byl vypočítán offset. Mikroprocesory Intel 8086/8088 totiž podporovaly tyto adresovací režimy:

Použitý zápis v assembleru Adresovací režim
přímá adresa (16bit) displacement/direct
   
[BX] register indirect
[SI] register indirect
[DI] register indirect
   
[BX+SI] based indexed mode
[BX+DI] based indexed mode
[BP+SI] based indexed mode
[BP+DI] based indexed mode
   
[BP+offset8_bit] based mode
[BX+offset8_bit] based mode
[SI+offset8_bit] indexed mode
[DI+offset8_bit] indexed mode
   
[BP+offset16_bit] based mode
[BX+offset16_bit] based mode
[SI+offset16_bit] indexed mode
[DI+offset16_bit] indexed mode
   
[BX+SI+offset8_bit] based indexed displacement
[BX+DI+offset8_bit] based indexed displacement
[BP+SI+offset8_bit] based indexed displacement
[BP+DI+offset8_bit] based indexed displacement
   
[BX+SI+offset16_bit] based indexed displacement
[BX+DI+offset16_bit] based indexed displacement
[BP+SI+offset16_bit] based indexed displacement
[BP+DI+offset16_bit] based indexed displacement

Co to znamená v praxi? Řekněme, že v segmentovém registru DS bude uložena nula a v registru BX bude uložena hodnota 0×8000. Následně použijeme instrukci:

mov DS:[BX+0x8000], AL

Otázka zní, do jaké fyzické buňky RAM se uloží obsah registru AL? Máme dvě možnosti výpočtu. Triviální dosazení do vzorce pro výpočet adresy by vedlo k výpočtu:

0x0000 × 16 + 0x8000 + 0x8000 = 0x10000

Ovšem můžeme si také uvědomit, že sčítačka pro offsety je realizována v 16bitové ALU a tedy proběhne spíše něco takového:

0x0000 × 16 + (0x8000 + 0x8000) & 0xffff = 0x00000

Ve skutečnosti je správný druhý výpočet, protože offset je na čipech Intel 8086/8088 vždy šestnáctibitový. To znamená, že veškeré výpočty offsetu uvedené v předchozí tabulce za všech předpokladů vedou k hodnotám v rozsahu 0×0000 až 0×ffff a nikdy tedy nepřekročíme velikost segmentu.

Poznámka: tato vlastnost sice přímo vychází z interní realizace výpočtů adresy na čipech 8086/8088, ovšem později musela být emulována.

3. Šestnáctibitové adresy na čipech druhé a třetí generace 80×86

Mikroprocesory druhé a třetí generace 80×86, tedy jak 80286, tak i 80386, sice interně počítají adresy odlišnými obvody, ovšem stále platí, že když se výpočty offsetu provádí se šestnáctibitovými registry (a pouze za tohoto předpokladu), bude výsledný offset vždy ležet v rozsahu 0×0000 až 0×ffff, tedy v rámci jediného segmentu. Ostatně si tuto vlastnost ukážeme na demonstračních příkladech, které budou své výsledky zobrazovat ve vizuální podobě.

Připomeňme si, že v grafickém režimu 13h karty VGA začíná obrazová paměť na segmentu 0×a000 a má velikost 320×200=64000 bajtů. Můžeme tedy snadno realizovat blokový přenos obrázku z RAM do VideoRAM, a to tak, že zdrojová data budou adresována přes dvojici registrů DS:SI (SI=source index) a cílová adresa bude uložena ve dvojici ES:DI (DI=destination index):

        mov ax, cs
        mov ds, ax
        mov si, image       ; nyni dvojice DS:SI obsahuje adresu prvniho bajtu v obrazku
 
        mov ax, 0xa000      ; (lze i PUSH 0xa000 + POP ES)
    mov es, ax
        xor di, di          ; nyni dvojice ES:DI obsahuje adresu prvniho pixelu ve video RAM   
 
        mov cx, 320*200/2   ; pocet zapisovanych 16bitovych slov (=dvojic pixelu)

Samotný blokový přenos zajistí instrukce REP MOVSW, která používá CX ve funkci počitadla a postupně zvyšuje indexové registry SI a DI:

    rep movsw           ; prenos celeho obrazku po 16bitovych slovech 

Výsledkem by měl být celý obrázek (64000 bajtů) přenesený do obrazové paměti:

Obrázek 1: Výsledek přenosu celého obrázku do obrazové paměti.

Úplný zdrojový kód tohoto demonstračního příkladu vypadá následovně:

; Graficky rezim karty VGA s rozlisenim 320x200 pixelu.
; Vykresleni rastroveho obrazku s explicitnim prenosem po dvou bajtech.
; Pro blokovy prenos se pouziva instrukce REP MOVSW
;
;-----------------------------------------------------------------------------
 
BITS 16         ; 16bitovy vystup pro DOS
CPU  286        ; specifikace pouziteho instrukcniho souboru
 
;-----------------------------------------------------------------------------
 
; ukonceni procesu a navrat do DOSu
%macro exit 0
        mov     ah, 0x4c    ; cislo sluzby DOSu
        int     0x21        ; zavolani sluzby DOSu
%endmacro
 
; vyprazdneni bufferu klavesnice a cekani na klavesu
%macro wait_key 0
        xor     ax, ax      ; cislo sluzby BIOSu
        int     0x16        ; zavolani sluzby BIOSu
%endmacro
 
; nastaveni grafickeho rezimu
%macro gfx_mode 1
        mov     ah, 0       ; cislo sluzby VGA BIOSu
        mov     al, %1      ; cislo grafickeho rezimu
        int     0x10        ; zavolani sluzby BIOSu
%endmacro
 
; paleta ve stupnich sedi
%macro grayscale_palette 0
        mov ax, 0x1010      ; cislo sluzby a podsluzby VGA BIOSu
        xor bl, bl          ; index barvy
next_dac:
        mov ch, bl          ; prvni barvova slozka
        shr ch, 1
        shr ch, 1
        mov cl, ch          ; druha barvova slozka
        mov dh, ch          ; treti barvova slozka
        int 0x10            ; modifikace mapovani v DAC
        inc bl              ; zvysit index v DAC
        jnz next_dac        ; nastavit dalsi barvu, dokud nedosahneme hodnoty 256
%endmacro
 
;-----------------------------------------------------------------------------
org  0x100        ; zacatek kodu pro programy typu COM (vzdy se zacina na 256)
 
start:
        gfx_mode 0x13       ; nastaveni rezimu 320x200 s 256 barvami
        grayscale_palette   ; nastaveni palety se stupni sedi
 
        mov ax, cs
        mov ds, ax
        mov si, image       ; nyni dvojice DS:SI obsahuje adresu prvniho bajtu v obrazku
 
        mov ax, 0xa000      ; (lze i PUSH 0xa000 + POP ES)
    mov es, ax
        xor di, di          ; nyni dvojice ES:DI obsahuje adresu prvniho pixelu ve video RAM   
 
        mov cx, 320*200/2   ; pocet zapisovanych 16bitovych slov (=dvojic pixelu)
    rep movsw           ; prenos celeho obrazku po 16bitovych slovech 
 
        wait_key            ; cekani na stisk klavesy
        exit                ; navrat do DOSu
 
; pridani binarnich dat s rastrovym obrazkem
image:
    incbin "image_320x200.bin"

4. Rozepsání programové smyčky pro blokový přenos mezi dvěma segmenty

Blokový přenos byl v předchozím příkladu realizován jedinou instrukcí:

    rep movsw           ; prenos celeho obrazku po 16bitovych slovech 

Tuto instrukci si pro další účely můžeme rozepsat do programové smyčky, v níž se postupně načítají šestnáctibitová slova z adresy DS a ukládají se na adresu ES tak, jak to již bylo popsáno. Indexové registry se zvyšují o dvojku, protože přenos provádím po šestnácti bitech a nikoli po osmi bitech. A nakonec instrukce LOOP snižuje počitadlo v CX a provádí skok v případě, že se ještě nedosáhlo nuly:

move_loop:                  ; prenos celeho obrazku po 16bitovych slovech
    mov ax, ds:[si]     ; nacteni dvou bajtu
    mov es:[di], ax     ; ulozeni dvou bajtu
    add si, 2           ; posun offsetu
    add di, 2
    loop move_loop      ; opakujeme

Výsledkem bude naprosto stejný obrázek, i když samotný blokový přenos bude pomalejší (to ovšem bez profileru nepoznáme):

Obrázek 2: Výsledek blokového přenosu by měl být naprosto totožný s prvním obrázkem.

Opět si pro úplnost ukažme celý zdrojový kód tohoto příkladu:

; Graficky rezim karty VGA s rozlisenim 320x200 pixelu.
; Vykresleni rastroveho obrazku s explicitnim prenosem po dvou bajtech.
; Pro blokovy prenos se pouziva programova smycka
;-----------------------------------------------------------------------------
 
BITS 16         ; 16bitovy vystup pro DOS
CPU  286        ; specifikace pouziteho instrukcniho souboru
 
;-----------------------------------------------------------------------------
 
; ukonceni procesu a navrat do DOSu
%macro exit 0
        mov     ah, 0x4c    ; cislo sluzby DOSu
        int     0x21        ; zavolani sluzby DOSu
%endmacro
 
; vyprazdneni bufferu klavesnice a cekani na klavesu
%macro wait_key 0
        xor     ax, ax      ; cislo sluzby BIOSu
        int     0x16        ; zavolani sluzby BIOSu
%endmacro
 
; nastaveni grafickeho rezimu
%macro gfx_mode 1
        mov     ah, 0       ; cislo sluzby VGA BIOSu
        mov     al, %1      ; cislo grafickeho rezimu
        int     0x10        ; zavolani sluzby BIOSu
%endmacro
 
; paleta ve stupnich sedi
%macro grayscale_palette 0
        mov ax, 0x1010      ; cislo sluzby a podsluzby VGA BIOSu
        xor bl, bl          ; index barvy
next_dac:
        mov ch, bl          ; prvni barvova slozka
        shr ch, 1
        shr ch, 1
        mov cl, ch          ; druha barvova slozka
        mov dh, ch          ; treti barvova slozka
        int 0x10            ; modifikace mapovani v DAC
        inc bl              ; zvysit index v DAC
        jnz next_dac        ; nastavit dalsi barvu, dokud nedosahneme hodnoty 256
%endmacro
 
;-----------------------------------------------------------------------------
org  0x100        ; zacatek kodu pro programy typu COM (vzdy se zacina na 256)
 
start:
        gfx_mode 0x13       ; nastaveni rezimu 320x200 s 256 barvami
        grayscale_palette   ; nastaveni palety se stupni sedi
 
        mov ax, cs
        mov ds, ax
        mov si, image       ; nyni dvojice DS:SI obsahuje adresu prvniho bajtu v obrazku
 
        mov ax, 0xa000      ; (lze i PUSH 0xa000 + POP ES)
    mov es, ax
        xor di, di          ; nyni dvojice ES:DI obsahuje adresu prvniho pixelu ve video RAM   
 
        mov cx, 320*200/2   ; pocet zapisovanych 16bitovych slov (=dvojic pixelu)
 
move_loop:                  ; prenos celeho obrazku po 16bitovych slovech
    mov ax, ds:[si]     ; nacteni dvou bajtu
    mov es:[di], ax     ; ulozeni dvou bajtu
    add si, 2           ; posun offsetu
    add di, 2
    loop move_loop      ; opakujeme
 
        wait_key            ; cekani na stisk klavesy
        exit                ; navrat do DOSu
 
; pridani binarnich dat s rastrovym obrazkem
image:
    incbin "image_320x200.bin"

5. Offset přesahující hranici segmentu

V obou předchozích příkladech ležela první cílová adresa na začátku segmentu 0×a000. Konkrétně segmentový registr ES obsahoval hodnotu 0×a000 (segment) a registr DI nulu:

        mov ax, 0xa000      ; (lze i PUSH 0xa000 + POP ES)
    mov es, ax
        xor di, di          ; nyni dvojice ES:DI obsahuje adresu prvniho pixelu ve video RAM   

Co se však stane v případě, že nastavíme segmentový registr na hodnotu 0×9800 a budeme ukládat data s offsetem 0×8000? Nejdříve nastavíme segmentový registr:

        mov ax, 0x9800
    mov es, ax
        xor di, di          ; nyni ES:DI obsahuje adresu Video RAM-32kB

A následně upravíme programovou smyčku tak, aby se k obsahu registru DI přidal ještě offset 0×8000:

move_loop:                     ; prenos celeho obrazku po 16bitovych slovech
    mov ax, ds:[si]        ; nacteni dvou bajtu
    mov es:[di+0x8000], ax ; ulozeni dvou bajtu, ovsem musime se posunouto 32kB nahoru
    add si, 2              ; posun offsetu
    add di, 2
    loop move_loop         ; opakujeme

Výsledný obrázek naznačuje, co se stalo. První polovina obrázku byla přenesena bez problémů, protože DI+0×8000 vracel šestnáctibitovou hodnotu menší než 0×10000 (tedy hodnotu ležící v segmentu 0×9800), ovšem druhá polovina byla přenesena nikoli do obrazové paměti, ale na začátek segmentu 0×9800 (což bychom dělat neměli – nevíme, co se zde nachází!).

Obrázek 3: Do VideoRAM se přenesla jen polovina obrázku, druhá polovina je „ztracena“ v adresovém rozsahu 0×98000 až 0×9ffff.

Platí tedy, že i když se segmenty 0×9800 a 0×a000 částečně (přesně polovinou) svého adresového prostoru překrývají, nemůžeme je jednoduše zaměnit s tím, že použijeme vhodně upravený offset – tento offset totiž nikdy nepřekročí šestnáctibitový rozsah.

Úplný zdrojový kód tohoto příkladu:

; Graficky rezim karty VGA s rozlisenim 320x200 pixelu.
; Vykresleni rastroveho obrazku s explicitnim prenosem po dvou bajtech.
; Pro blokovy prenos se pouziva programova smycka
;-----------------------------------------------------------------------------
 
BITS 16         ; 16bitovy vystup pro DOS
CPU  286        ; specifikace pouziteho instrukcniho souboru
 
;-----------------------------------------------------------------------------
 
; ukonceni procesu a navrat do DOSu
%macro exit 0
        mov     ah, 0x4c    ; cislo sluzby DOSu
        int     0x21        ; zavolani sluzby DOSu
%endmacro
 
; vyprazdneni bufferu klavesnice a cekani na klavesu
%macro wait_key 0
        xor     ax, ax      ; cislo sluzby BIOSu
        int     0x16        ; zavolani sluzby BIOSu
%endmacro
 
; nastaveni grafickeho rezimu
%macro gfx_mode 1
        mov     ah, 0       ; cislo sluzby VGA BIOSu
        mov     al, %1      ; cislo grafickeho rezimu
        int     0x10        ; zavolani sluzby BIOSu
%endmacro
 
; paleta ve stupnich sedi
%macro grayscale_palette 0
        mov ax, 0x1010      ; cislo sluzby a podsluzby VGA BIOSu
        xor bl, bl          ; index barvy
next_dac:
        mov ch, bl          ; prvni barvova slozka
        shr ch, 1
        shr ch, 1
        mov cl, ch          ; druha barvova slozka
        mov dh, ch          ; treti barvova slozka
        int 0x10            ; modifikace mapovani v DAC
        inc bl              ; zvysit index v DAC
        jnz next_dac        ; nastavit dalsi barvu, dokud nedosahneme hodnoty 256
%endmacro
 
;-----------------------------------------------------------------------------
org  0x100        ; zacatek kodu pro programy typu COM (vzdy se zacina na 256)
 
start:
        gfx_mode 0x13       ; nastaveni rezimu 320x200 s 256 barvami
        grayscale_palette   ; nastaveni palety se stupni sedi
 
        mov ax, cs
        mov ds, ax
        mov si, image       ; nyni dvojice DS:SI obsahuje adresu prvniho bajtu v obrazku
 
        mov ax, 0x9800
    mov es, ax
        xor di, di          ; nyni ES:DI obsahuje adresu Video RAM-32kB
 
        mov cx, 320*200/2      ; pocet zapisovanych 16bitovych slov (=dvojic pixelu)
 
move_loop:                     ; prenos celeho obrazku po 16bitovych slovech
    mov ax, ds:[si]        ; nacteni dvou bajtu
    mov es:[di+0x8000], ax ; ulozeni dvou bajtu, ovsem musime se posunouto 32kB nahoru
    add si, 2              ; posun offsetu
    add di, 2
    loop move_loop         ; opakujeme
 
        wait_key            ; cekani na stisk klavesy
        exit                ; navrat do DOSu
 
; pridani binarnich dat s rastrovym obrazkem
image:
    incbin "image_320x200.bin"

6. Druhý příklad s offsetem, který přesahuje hranice segmentu

Možná ještě názornější bude následující demonstrační příklad, v němž budeme barvy pixelů ukládat do segmentu 0×a000, tedy skutečně přímo do obrazové paměti:

        mov ax, 0xa000
    mov es, ax
        xor di, di          ; nyni ES:DI obsahuje adresu Video RAM+32kB

Nicméně si zvolíme posun o 320×100 bajtů od začátku segmentu s Video RAM, což znamená, že první vykreslený pixel bude začínat na začátku stého prvního řádku:

move_loop:                     ; prenos celeho obrazku po 16bitovych slovech
    mov ax, ds:[si]        ; nacteni dvou bajtu
posun equ 320*100              ; vypocet posunu o 100 obrazovych radku
    mov es:[di+posun], ax  ; ulozeni dvou bajtu s posunem
    add si, 2              ; posun offsetu
    add di, 2
    loop move_loop         ; opakujeme

Výsledek bude následující – do spodní poloviny obrazovky se vykreslí prvních 100 řádků rastrového obrázku. Dalších 1536 pixelů se vykreslí do neviditelné části RAM (mezi offsety 64000 až 65535) a zbylé pixely (cca 95 obrazových řádků) „přetečou“ na začátek obrazovky:

Obrázek 4: Vykreslované pixely, pokud jsou ukládány do segmentu 0×a000, nikdy nepřekročí hranice Video RAM. Po dosažení konce segmentu se pixely začnou zapisovat opět od jeho začátku.

Opět jsme tedy nedokázali překročit hranici jednoho segmentu.

; Graficky rezim karty VGA s rozlisenim 320x200 pixelu.
; Vykresleni rastroveho obrazku s explicitnim prenosem po dvou bajtech.
; Pro blokovy prenos se pouziva programova smycka, ovsem pro posunuty segment.
;-----------------------------------------------------------------------------
 
BITS 16         ; 16bitovy vystup pro DOS
CPU  286        ; specifikace pouziteho instrukcniho souboru
 
;-----------------------------------------------------------------------------
 
; ukonceni procesu a navrat do DOSu
%macro exit 0
        mov     ah, 0x4c    ; cislo sluzby DOSu
        int     0x21        ; zavolani sluzby DOSu
%endmacro
 
; vyprazdneni bufferu klavesnice a cekani na klavesu
%macro wait_key 0
        xor     ax, ax      ; cislo sluzby BIOSu
        int     0x16        ; zavolani sluzby BIOSu
%endmacro
 
; nastaveni grafickeho rezimu
%macro gfx_mode 1
        mov     ah, 0       ; cislo sluzby VGA BIOSu
        mov     al, %1      ; cislo grafickeho rezimu
        int     0x10        ; zavolani sluzby BIOSu
%endmacro
 
; paleta ve stupnich sedi
%macro grayscale_palette 0
        mov ax, 0x1010      ; cislo sluzby a podsluzby VGA BIOSu
        xor bl, bl          ; index barvy
next_dac:
        mov ch, bl          ; prvni barvova slozka
        shr ch, 1
        shr ch, 1
        mov cl, ch          ; druha barvova slozka
        mov dh, ch          ; treti barvova slozka
        int 0x10            ; modifikace mapovani v DAC
        inc bl              ; zvysit index v DAC
        jnz next_dac        ; nastavit dalsi barvu, dokud nedosahneme hodnoty 256
%endmacro
 
;-----------------------------------------------------------------------------
org  0x100        ; zacatek kodu pro programy typu COM (vzdy se zacina na 256)
 
start:
        gfx_mode 0x13       ; nastaveni rezimu 320x200 s 256 barvami
        grayscale_palette   ; nastaveni palety se stupni sedi
 
        mov ax, cs
        mov ds, ax
        mov si, image       ; nyni dvojice DS:SI obsahuje adresu prvniho bajtu v obrazku
 
        mov ax, 0xa000
    mov es, ax
        xor di, di          ; nyni ES:DI obsahuje adresu Video RAM+32kB
 
        mov cx, 320*200/2      ; pocet zapisovanych 16bitovych slov (=dvojic pixelu)
 
move_loop:                     ; prenos celeho obrazku po 16bitovych slovech
    mov ax, ds:[si]        ; nacteni dvou bajtu
posun equ 320*100              ; vypocet posunu o 100 obrazovych radku
    mov es:[di+posun], ax  ; ulozeni dvou bajtu s posunem
    add si, 2              ; posun offsetu
    add di, 2
    loop move_loop         ; opakujeme
 
        wait_key            ; cekani na stisk klavesy
        exit                ; navrat do DOSu
 
; pridani binarnich dat s rastrovym obrazkem
image:
    incbin "image_320x200.bin"

7. Chování mikroprocesoru Intel 80386 v reálném režimu

Po krátkém (ale jak dále uvidíme, tak důležitém) zopakování způsobu adresování mikroprocesorů Intel 8086/8088 se přeneseme o pár let dále, konkrétně k čipům 80386. Víme již, že tyto čipy nabízely programátorům další dva segmentové registry FS a GS, což bude důležité zejména v chráněném režimu. Ovšem pro nás zajímavější je fakt, že se rozšířily všechny pracovní registry ze šestnácti bitů na 32 bitů:

32bitový registr Spodních 16 bitů Rozdělení horní/dolní bajt Funkce registru
EAX AX AH/AL akumulátor
EBX BX BH/BL bázový registr
ECX CX CH/CL čítač
EDX DX DH/DL datový registr
       
ESP SP   ukazatel na vrchol zásobníku
EBP BP   báze zásobníkového rámce
ESI SI   indexový registr pro zdroj dat
EDI DI   indexový registr pro cíl dat
       
EIP IP   ukazatel na prováděnou instrukci

Co to znamená v praxi? Nyní můžeme při adresování používat 32bitové offsety, a to i v reálném 16bitovém režimu! A i výpočet offsetu probíhá s využitím 32bitové sčítačky a nikoli sčítačky 16bitové. Znamená to tedy, že konečně můžeme překročit hranici 1MB a vlastně adresovat až 4GB RAM? Tak jednoduché nám to Intel neudělal, a to kvůli jedné prozatím nezmíněné vlastnosti 80286, která byla přenesena i do čipu 80386. Takže se v následující kapitole ještě jednou vraťme k 80286.

8. Skrytá část 80286: cache s deskriptory segmentů

V předchozím článku jsme si mj. řekli, že mikroprocesory 80286 byly prvními čipy z rodiny 80×86, které implementovaly chráněný režim (protected mode). V tomto novém režimu, do kterého se ale musely mikroprocesory explicitně přepnout, se změnilo adresování, zejména část týkající se segmentu. Nyní totiž hodnota uložená v segmentovém registru nespecifikovala přímou adresu (resp. její část), ale (poněkud zjednodušeně řečeno) index to tabulky deskriptorů (descriptor table). Tato tabulka obsahovala takzvané deskriptory, přičemž pro každý deskriptor bylo vyhrazeno osm bajtů, z nichž bylo ovšem na 80286 využito jen šest bajtů. Prozatím nás nebudou zajímat podrobnosti, jak přesně jsou hodnoty v tabulce deskriptorů uloženy, ale alespoň si řekněme, jaké informace každý deskriptor obsahuje:

Označení Počet bitů Stručný popis
Base 24 adresa začátku segmentu kdekoli v prostoru 16MB
Limits 16 velikost segmentu (lze mít menší segment než 64kB)
Control bits 6 řízení práv k segmentu
DPL 2 úroveň oprávnění 0–3 (tzv. ring)

Samozřejmě by nebylo efektivní, aby se při každém přístupu do paměti četlo těchto šest bajtů stále z tabulky deskriptorů. A ani to nebylo nutné, protože pokud každý záznam odpovídal hodnotě segmentu, bylo možné pro každou aktuálně používanou hodnotu segmentu uložit oněch šest bajtů do interních registrů mikroprocesoru – a na 80286 byly k dispozici čtyři segmentové registry, takže mikroprocesor musel obsahovat pouze 4×6 bajtů interní cache s hodnotami deskriptorů. Ovšem kvůli potřebám chráněného režimu (aby nebylo možné ochranu obejít) by tyto interní registry neměly být přístupné programátorům.

9. Cache s deskriptory segmentů v reálném režimu

Proč se však o deskriptorech zmiňujeme v souvislosti s běžným reálným režimem? Ukazuje se totiž, že tato cache má vliv i v reálném režimu, což je dosti překvapující, ale jedná se o vlastnost, která se projeví zejména u třetí generace 80×86. Na mikroprocesorech Intel 80286 se v reálném režimu (podle dostupných informací! – nejedná se totiž o oficiálně zdokumentované chování) využívá z každého ze čtyř deskriptorů bitové pole limits. V této šestnáctibitové hodnotě je uložena maximální hodnota platného offsetu. Co to znamená v praxi? Pokud by tato hodnota byla nastavena na řekněme 0×7fff, znamenalo by to, že se daný segment resp. jeho adresovatelná část, zmenší na offsety od 0×0000 do 0×7fff (včetně), zatímco při přístupu na offset 0×8000 až 0×ffff dojde k výjimce typu General protection fault (kterou však nemá v čistém DOSu kdo zpracovat!).

Obrázek 5: Výjimky dokážou zachytit takzvané DOS extendery; což ovšem platí pro programy pracující v chráněném režimu.

To je ovšem problematické chování, protože čipy 80286 vlastně nejsou zpětně kompatibilní s původní řadou 8086. Aby se zachovalo zdání kompatibility, jsou v průběhu inicializace 80286 limity všech čtyř deskriptorů uložených v cache nastaveny na hodnotu 0×ffff, takže se na první pohled zdá vše v pořádku, protože i 80286 dodržuje vlastnost zmíněnou výše – výpočty offsetů probíhají v šestnácti bitech a nikdy tedy nedokážou překročit právě onu hodnotu 0×ffff.

10. 32bitové adresy v reálném režimu

V předchozí kapitole jsme si naznačili, že za cenu jistého úsilí se Intelu podařilo zachovat zdání, že reálný režim je stále ten „starý dobrý“ reálný režim. Ale na další problémy již bylo zaděláno – a to ve chvíli, kdy se v rámci čipu 80386 přešlo na 32bitové offsetové registry (resp. všechny pracovní registry byly rozšířeny na 32bitů, včetně registrů použitých pro výpočet offsetu). Nastala totiž tato otázka – jak se má čip přesně chovat ve chvíli, kdy se provádí následující instrukce:

mov ax, [ebx + 0x12345678]

Obrázek 6: Schéma výpočtu adresy vypadalo skvěle: konečně můžeme využít celých 4GB a se stránkováním ještě více. Praxe bývala odlišná.
Zdroj: Intel 80386 Reference Programmer's Manual

Bylo možné definovat několik různých scénářů chování:

  1. Specifikuje se, že z 32bitových registrů se použije jen spodních 16 bitů a totéž pro konstanty
  2. Specifikuje se, že se v případě, že jakákoli část adresy přesáhne 16 bitů, vyhodí výjimka
  3. Specifikuje se, že se v případě, že výsledný offset přesáhne 16 bitů, vyhodí výjimka
  4. Ponechá se 32bitové chování (tedy něco, čeho lze dosáhnout nereálným režimem)

Vybrána nakonec byla druhá možnost, což znamenalo, že onen skvělý nový (drahý) čip, který byl v reklamách označován za 32bitovou revoluci, se stále v DOSu (a v mnoha překladačích) choval jako 80286. Navíc se přidala nová vlastnost, na kterou mohli narazit programátoři, kteří si přáli využít „dlouhé 32bitové adresy“ – při překročení hranice 64kB došlo buď k zamrznutí systému, nebo k jinému problému, a to v závislosti na konkrétní konfiguraci (zda je použit správce paměti, zda běží nějaký extender atd.).

11. Deskriptory segmentů na čipech 80386

I na čipech 80386 je v chráněném režimu použita tabulka deskriptorů. A opět platí, že přímo v mikroprocesorech 80386 existuje cache pro deskriptory odpovídající všem segmentovým registrům. Nyní je těchto deskriptorů šest a nikoli jen čtyři, a to z toho důvodu, že kromě původních segmentových registrů CS, DS, ES a SS byly přidány i dva nové segmentové registry nazvané FS a GS.

To je ovšem spíše kosmetická změna. Důležitější je, že nyní má deskriptor obsazených všech osm bajtů a nikoli jen šest bajtů. Proč tomu tak je? Zvětšil se počet bitů pro bázovou adresu segmentu, a to na plných 32 bitů (rozsah 4GB – opět je zde prostor pro novou A32 GATE namísto původní A20 GATE :-). A taktéž se zvětšil počet bitů pro limit, a to z původních 16 bitů (maximální limit 0×ffff) na 20 bitů, ovšem s tím, že se namísto bajtů může limit nastavit i v celých stránkách (to se přepíná dalším bitem).

Obrázek 7: 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

Důležité je, že se limity opět projeví i v reálném režimu a Intel zachoval původní hodnotu limitů – tedy je zde zapsána hodnota 0×ffff. V praxi to tedy znamená, že překročení velikosti offsetu nad tuto hranici dojde k výjimce a tím pádem (obecně) k pádu aplikace pracující v reálném režimu.

12. Ukázka adresace 32bitovými registry v reálném režimu

Demonstrační příklad ze třetí kapitoly si můžeme snadno přepsat do podoby, ve které se použijí 32bitové přenosy:

        mov cx, 320*200/4   ; pocet zapisovanych 32bitovych slov (=ctveric pixelu)
    rep movsd           ; prenos celeho obrazku po 32bitovych slovech 

Podle toho, zda je použit prefix 0×67, se navíc rozhoduje, zda budou adresy specifikovány ve dvojicích DS a ES nebo se použijí dvojice DS a ES.

Obrázek 8: Výsledek 32bitového přenosu by se neměl nijak lišit od šestnáctibitového přenosu.

Úplný zdrojový kód tohoto příkladu vypadá následovně:

; Graficky rezim karty VGA s rozlisenim 320x200 pixelu.
; Vykresleni rastroveho obrazku s explicitnim prenosem po ctyrech bajtech.
; Pro blokovy prenos se pouziva instrukce REP MOVSD
;
;-----------------------------------------------------------------------------
 
BITS 16         ; 16bitovy vystup pro DOS
CPU  386        ; specifikace pouziteho instrukcniho souboru
 
;-----------------------------------------------------------------------------
 
; ukonceni procesu a navrat do DOSu
%macro exit 0
        mov     ah, 0x4c    ; cislo sluzby DOSu
        int     0x21        ; zavolani sluzby DOSu
%endmacro
 
; vyprazdneni bufferu klavesnice a cekani na klavesu
%macro wait_key 0
        xor     ax, ax      ; cislo sluzby BIOSu
        int     0x16        ; zavolani sluzby BIOSu
%endmacro
 
; nastaveni grafickeho rezimu
%macro gfx_mode 1
        mov     ah, 0       ; cislo sluzby VGA BIOSu
        mov     al, %1      ; cislo grafickeho rezimu
        int     0x10        ; zavolani sluzby BIOSu
%endmacro
 
; paleta ve stupnich sedi
%macro grayscale_palette 0
        mov ax, 0x1010      ; cislo sluzby a podsluzby VGA BIOSu
        xor bl, bl          ; index barvy
next_dac:
        mov ch, bl          ; prvni barvova slozka
        shr ch, 1
        shr ch, 1
        mov cl, ch          ; druha barvova slozka
        mov dh, ch          ; treti barvova slozka
        int 0x10            ; modifikace mapovani v DAC
        inc bl              ; zvysit index v DAC
        jnz next_dac        ; nastavit dalsi barvu, dokud nedosahneme hodnoty 256
%endmacro
 
;-----------------------------------------------------------------------------
org  0x100        ; zacatek kodu pro programy typu COM (vzdy se zacina na 256)
 
start:
        gfx_mode 0x13       ; nastaveni rezimu 320x200 s 256 barvami
        grayscale_palette   ; nastaveni palety se stupni sedi
 
        mov ax, cs
        mov ds, ax
        mov esi, image      ; nyni dvojice DS:ESI obsahuje adresu prvniho bajtu v obrazku
 
        mov ax, 0xa000      ; (lze i PUSH 0xa000 + POP ES)
    mov es, ax
        xor edi, edi        ; nyni dvojice ES:EDI obsahuje adresu prvniho pixelu ve video RAM   
 
        mov cx, 320*200/4   ; pocet zapisovanych 32bitovych slov (=ctveric pixelu)
    rep movsd           ; prenos celeho obrazku po 32bitovych slovech 
 
        wait_key            ; cekani na stisk klavesy
        exit                ; navrat do DOSu
 
; pridani binarnich dat s rastrovym obrazkem
image:
    incbin "image_320x200.bin"

13. Rozepsání programové smyčky: přenos po 32bitech, offsety jsou realizovány 32bitovými registry

Blokový přenos rep movsd si opět můžeme přepsat do podoby běžné programové smyčky. Nejdříve nastavíme zdrojové a cílové adresy, tentokrát ovšem použijeme 32bitové offsetové registry:

        mov ax, cs
        mov ds, ax
        mov esi, image      ; nyni dvojice DS:ESI obsahuje adresu prvniho bajtu v obrazku
 
        mov ax, 0xa000      ; (lze i PUSH 0xa000 + POP ES)
    mov es, ax
        xor edi, edi        ; nyni dvojice ES:EDI obsahuje adresu prvniho pixelu ve video RAM   

Dále nastavíme počet opakování smyčky:

        mov cx, 320*200/4   ; pocet zapisovanych 32bitovych slov (=ctveric pixelu)

A nakonec nám zbývá realizace této smyčky. Opět si povšimněte použití 32bitových offsetů (ovšem ty nikdy nepřesáhnou limit 64kB segmentu):

move_loop:                  ; prenos celeho obrazku po 32bitovych slovech
    mov eax, ds:[esi]   ; nacteni ctyr bajtu
    mov es:[edi], eax   ; ulozeni ctyr bajtu
    add esi, 4          ; posun offsetu
    add edi, 4
    loop move_loop      ; opakujeme

Úplný zdrojový kód tohoto příkladu vypadá následovně:

; Graficky rezim karty VGA s rozlisenim 320x200 pixelu.
; Vykresleni rastroveho obrazku s explicitnim prenosem po ctyrech bajtech.
; Pro blokovy prenos se pouziva programova smycka
;
;-----------------------------------------------------------------------------
 
BITS 16         ; 16bitovy vystup pro DOS
CPU  386        ; specifikace pouziteho instrukcniho souboru
 
;-----------------------------------------------------------------------------
 
; ukonceni procesu a navrat do DOSu
%macro exit 0
        mov     ah, 0x4c    ; cislo sluzby DOSu
        int     0x21        ; zavolani sluzby DOSu
%endmacro
 
; vyprazdneni bufferu klavesnice a cekani na klavesu
%macro wait_key 0
        xor     ax, ax      ; cislo sluzby BIOSu
        int     0x16        ; zavolani sluzby BIOSu
%endmacro
 
; nastaveni grafickeho rezimu
%macro gfx_mode 1
        mov     ah, 0       ; cislo sluzby VGA BIOSu
        mov     al, %1      ; cislo grafickeho rezimu
        int     0x10        ; zavolani sluzby BIOSu
%endmacro
 
; paleta ve stupnich sedi
%macro grayscale_palette 0
        mov ax, 0x1010      ; cislo sluzby a podsluzby VGA BIOSu
        xor bl, bl          ; index barvy
next_dac:
        mov ch, bl          ; prvni barvova slozka
        shr ch, 1
        shr ch, 1
        mov cl, ch          ; druha barvova slozka
        mov dh, ch          ; treti barvova slozka
        int 0x10            ; modifikace mapovani v DAC
        inc bl              ; zvysit index v DAC
        jnz next_dac        ; nastavit dalsi barvu, dokud nedosahneme hodnoty 256
%endmacro
 
;-----------------------------------------------------------------------------
org  0x100        ; zacatek kodu pro programy typu COM (vzdy se zacina na 256)
 
start:
        gfx_mode 0x13       ; nastaveni rezimu 320x200 s 256 barvami
        grayscale_palette   ; nastaveni palety se stupni sedi
 
        mov ax, cs
        mov ds, ax
        mov esi, image      ; nyni dvojice DS:ESI obsahuje adresu prvniho bajtu v obrazku
 
        mov ax, 0xa000      ; (lze i PUSH 0xa000 + POP ES)
    mov es, ax
        xor edi, edi        ; nyni dvojice ES:EDI obsahuje adresu prvniho pixelu ve video RAM   
 
        mov cx, 320*200/4   ; pocet zapisovanych 32bitovych slov (=ctveric pixelu)
 
move_loop:                  ; prenos celeho obrazku po 32bitovych slovech
    mov eax, ds:[esi]   ; nacteni ctyr bajtu
    mov es:[edi], eax   ; ulozeni ctyr bajtu
    add esi, 4          ; posun offsetu
    add edi, 4
    loop move_loop      ; opakujeme
 
        wait_key            ; cekani na klavesu
        exit                ; navrat do DOSu
 
; pridani binarnich dat s rastrovym obrazkem
image:
    incbin "image_320x200.bin"

14. Přístup do obrazové paměti přes segment 0×0000 a 32bitový offset

Pokusme se nyní předchozí ukázkový příklad upravit takovým způsobem, aby se k Video RAM přistupovalo sice stále přes fyzické adresy 0×a0000–0×afff, ale nyní přes segment 0×0000. To ovšem znamená nutnost použití 32bitového offsetu. Úprava zdrojového kódu je snadná – vynulujeme registr ES a nastavíme offset do registru EDI:

        mov ax, cs
        mov ds, ax
        mov esi, image      ; nyni dvojice DS:ESI obsahuje adresu prvniho bajtu v obrazku
 
        xor ax, ax
    mov es, ax          ; ES=0x0000 !!!
    mov edi, 0xa0000    ; nyni dvojice ES:EDI obsahuje adresu prvniho pixelu ve video RAM   

Dále nastavíme počitadlo opakování smyčky, a to už běžným způsobem:

        mov cx, 320*200/4   ; pocet zapisovanych 32bitovych slov (=ctveric pixelu)

A pokusíme se provést vlastní blokový přenos.

move_loop:                  ; prenos celeho obrazku po 32bitovych slovech
    mov eax, ds:[esi]   ; nacteni ctyr bajtu
    mov es:[edi], eax   ; ulozeni ctyr bajtu
    add esi, 4          ; posun offsetu
    add edi, 4
    loop move_loop      ; opakujeme

Chování aplikace se nyní může ubrat několika směry:

  • V reálném režimu aplikace zamrzne (a uvidíme jen černou obrazovku)
  • V nereálném režimu (a podle všeho ho nastaví i některé verze HIMEM.SYS) se obrázek přenese bez problémů
  • V případě aktivního extenderu závisí na nastavení limitů, ale obecně dojde k pádu kvůli výjimce
  • V případě aktivního režimu V86 (virtuální režim) opět závisí na nastavení limitů
  • DOSBox limity nekontroluje a proto aplikace obrázek přenese bez problémů

Obrázek 9: Výjimka v chráněném režimu zachycená extenderem.

Úplný kód tohoto demonstračního příkladu vypadá následovně:

; Graficky rezim karty VGA s rozlisenim 320x200 pixelu.
; Vykresleni rastroveho obrazku s explicitnim prenosem po ctyrech bajtech.
;-----------------------------------------------------------------------------
 
BITS 16         ; 16bitovy vystup pro DOS
CPU  386        ; specifikace pouziteho instrukcniho souboru
 
;-----------------------------------------------------------------------------
 
; ukonceni procesu a navrat do DOSu
%macro exit 0
        mov     ah, 0x4c    ; cislo sluzby DOSu
        int     0x21        ; zavolani sluzby DOSu
%endmacro
 
; vyprazdneni bufferu klavesnice a cekani na klavesu
%macro wait_key 0
        xor     ax, ax      ; cislo sluzby BIOSu
        int     0x16        ; zavolani sluzby BIOSu
%endmacro
 
; nastaveni grafickeho rezimu
%macro gfx_mode 1
        mov     ah, 0       ; cislo sluzby VGA BIOSu
        mov     al, %1      ; cislo grafickeho rezimu
        int     0x10        ; zavolani sluzby BIOSu
%endmacro
 
; paleta ve stupnich sedi
%macro grayscale_palette 0
        mov ax, 0x1010      ; cislo sluzby a podsluzby VGA BIOSu
        xor bl, bl          ; index barvy
next_dac:
        mov ch, bl          ; prvni barvova slozka
        shr ch, 1
        shr ch, 1
        mov cl, ch          ; druha barvova slozka
        mov dh, ch          ; treti barvova slozka
        int 0x10            ; modifikace mapovani v DAC
        inc bl              ; zvysit index v DAC
        jnz next_dac        ; nastavit dalsi barvu, dokud nedosahneme hodnoty 256
%endmacro
 
;-----------------------------------------------------------------------------
org  0x100        ; zacatek kodu pro programy typu COM (vzdy se zacina na 256)
 
start:
        gfx_mode 0x13       ; nastaveni rezimu 320x200 s 256 barvami
        grayscale_palette   ; nastaveni palety se stupni sedi
 
        mov ax, cs
        mov ds, ax
        mov esi, image      ; nyni dvojice DS:ESI obsahuje adresu prvniho bajtu v obrazku
 
        xor ax, ax
    mov es, ax          ; ES=0x0000 !!!
    mov edi, 0xa0000    ; nyni dvojice ES:EDI obsahuje adresu prvniho pixelu ve video RAM   
 
        mov cx, 320*200/4   ; pocet zapisovanych 32bitovych slov (=ctveric pixelu)
 
move_loop:                  ; prenos celeho obrazku po 32bitovych slovech
    mov eax, ds:[esi]   ; nacteni ctyr bajtu
    mov es:[edi], eax   ; ulozeni ctyr bajtu
    add esi, 4          ; posun offsetu
    add edi, 4
    loop move_loop      ; opakujeme
 
        wait_key            ; cekani na klavesu
        exit                ; navrat do DOSu
 
; pridani binarnich dat s rastrovym obrazkem
image:
    incbin "image_320x200.bin"

15. Překročení limitu segmentu s využitím posunu adresy o konstantu

Taktéž se můžeme pokusit o překročení limitu segmentu „jen o kousek“, a to s využitím konstanty přičtené k registru EDI. Nyní tedy (například) nastavíme segmentový registr ES na hodnotu 0×9800, tj. 32kB před první adresou Video RAM a vynulujeme registr EDI:

        mov ax, 0x9800
    mov es, ax          ; ES=0x9800 !!!
    xor edi, edi        ; nyni ES:EDI obsahuje adresu Video RAM-32kB

Samotná programová smyčka pro provedení blokových přenosů se pochopitelně bude muset modifikovat, protože nyní k registru EDI přičteme konstantu 0×8000, abychom kompenzovali nižší adresu segmentu. Samotný EDI tedy nikdy nepřekročí hodnotu 0×ffff, čímž se zdánlivě vyhneme problému, na který jsme narazili v předchozím příkladu:

move_loop:                       ; prenos celeho obrazku po 32bitovych slovech
    mov eax, ds:[esi]        ; nacteni ctyr bajtu
    mov es:[edi+0x8000], eax ; ulozeni ctyr bajtu, ovsem s offsetem
    add esi, 4               ; posun offsetu
    add edi, 4
    loop move_loop           ; opakujeme

V praxi ovšem po spuštění tohoto programu může dojít ke všem chováním, které již byly popsány v předchozí kapitole: od bezproblémového zobrazení rastrového obrázku přes zamrznutí aplikace až po pád po zachycení HW výjimky.

; Graficky rezim karty VGA s rozlisenim 320x200 pixelu.
; Vykresleni rastroveho obrazku s explicitnim prenosem po ctyrech bajtech.
;
;-----------------------------------------------------------------------------
 
BITS 16         ; 16bitovy vystup pro DOS
CPU  386        ; specifikace pouziteho instrukcniho souboru
 
;-----------------------------------------------------------------------------
 
; ukonceni procesu a navrat do DOSu
%macro exit 0
        mov     ah, 0x4c    ; cislo sluzby DOSu
        int     0x21        ; zavolani sluzby DOSu
%endmacro
 
; vyprazdneni bufferu klavesnice a cekani na klavesu
%macro wait_key 0
        xor     ax, ax      ; cislo sluzby BIOSu
        int     0x16        ; zavolani sluzby BIOSu
%endmacro
 
; nastaveni grafickeho rezimu
%macro gfx_mode 1
        mov     ah, 0       ; cislo sluzby VGA BIOSu
        mov     al, %1      ; cislo grafickeho rezimu
        int     0x10        ; zavolani sluzby BIOSu
%endmacro
 
; paleta ve stupnich sedi
%macro grayscale_palette 0
        mov ax, 0x1010      ; cislo sluzby a podsluzby VGA BIOSu
        xor bl, bl          ; index barvy
next_dac:
        mov ch, bl          ; prvni barvova slozka
        shr ch, 1
        shr ch, 1
        mov cl, ch          ; druha barvova slozka
        mov dh, ch          ; treti barvova slozka
        int 0x10            ; modifikace mapovani v DAC
        inc bl              ; zvysit index v DAC
        jnz next_dac        ; nastavit dalsi barvu, dokud nedosahneme hodnoty 256
%endmacro
 
;-----------------------------------------------------------------------------
org  0x100        ; zacatek kodu pro programy typu COM (vzdy se zacina na 256)
 
start:
        gfx_mode 0x13       ; nastaveni rezimu 320x200 s 256 barvami
        grayscale_palette   ; nastaveni palety se stupni sedi
 
        mov ax, cs
        mov ds, ax
        mov esi, image      ; nyni dvojice DS:ESI obsahuje adresu prvniho bajtu v obrazku
 
        mov ax, 0x9800
    mov es, ax          ; ES=0x9800 !!!
    xor edi, edi        ; nyni ES:EDI obsahuje adresu Video RAM-32kB
 
        mov cx, 320*200/4   ; pocet zapisovanych 32bitovych slov (=ctveric pixelu)
 
move_loop:                       ; prenos celeho obrazku po 32bitovych slovech
    mov eax, ds:[esi]        ; nacteni ctyr bajtu
    mov es:[edi+0x8000], eax ; ulozeni ctyr bajtu, ovsem s offsetem
    add esi, 4               ; posun offsetu
    add edi, 4
    loop move_loop           ; opakujeme
 
        wait_key            ; cekani na klavesu
        exit                ; navrat do DOSu
 
; pridani binarnich dat s rastrovym obrazkem
image:
    incbin "image_320x200.bin"

16. Naplnění cache s deskriptory přes „utajenou“ instrukci LOADALL

Jedinou oficiální cestou, jakou lze naplnit cache s deskriptory, je nastavení tabulek deskriptorů v operační paměti, přepnutí mikroprocesoru do chráněného režimu a načtení nových adres do segmentových registrů. V tomto případě se načtou příslušné hodnoty z tabulek deskriptorů do cache s deskriptory a nové bázové adresy segmentů i jejich limity začnou být platné. To jsou ovšem poměrně komplikované a taktéž pomalé operace, které navíc následně vyžadují přepnutí zpět do reálného režimu, což není (zejména v případě mikroprocesoru 80286 snadné a vlastně ani oficiálně možné – pro tento účel bylo nutné upravit interní architekturu IBM PC tak, aby se provedl reset mikroprocesoru). Ovšem nakonec se našla ještě zajímavější cesta, jak naplnit cache. Pro tento účel se totiž začala používat instrukce LOADALL.

Jedná se o instrukci, která nebyla oficiálně zdokumentována a byla společnosti Intel navržena primárně pro testovací účely prováděné ještě před instalací mikroprocesoru do základové desky. Ovšem to, že nějaká instrukce není zdokumentována, neznamená, že ji nelze použít, navíc v případě, že spolehlivě pracovala i na čipech vyráběných ostatními firmami (AMD, IBM). Navíc bylo možné tuto instrukci použít i v reálném režimu, bez nutnosti přepínání do režimu chráněného a zpět. V praxi se tedy tato instrukce začala používat dokonce i v samotném DOSu (HIMEM.SYS) a bylo již možné použít pro zavedení takzvaného nereálného režimu (unreal mode).

Na tomto místě je nutné zdůraznit, že instrukce LOADALL pro mikroprocesor 80286 je zcela odlišná od stejně pojmenované instrukce pro 80386. Dokonce se liší i operační kódy těchto instrukcí. Kód pro naplnění cache s deskriptory tedy musel zjistit, na jakém procesoru běží a poté použít odlišné větve v kódu.

17. LOADALL na mikroprocesorech 80286

Nejprve se podívejme, jakou operaci instrukce LOADALL provádí na mikroprocesorech Intel 80286. Operační kód této instrukce je 0f 05, přičemž se nespecifikují žádné operandy. Tato instrukce totiž očekává, že na adrese 0×00800 (tedy například 0080:0000 nebo 0000:0800) bude uloženo 102 bajtů, které se všechny přenesou do viditelných registrů mikroprocesoru, neviditelných registrů (nepřístupných programátorům) a taktéž se načte námi používaná cache s deskriptory (tedy čtyři deskriptory pro čtyři segmentové registry a další čtyři deskriptory pro adresy používané v chráněném režimu). Jedná se o relativně pomalou instrukci, protože její provedení trvá 195 hodinových cyklů. Ovšem díky ní lze snadno zpřístupnit jakýkoli blok rozšířené paměti, a to bez nutnosti blokové kopie dat (což je pochopitelně mnohem delší).

Hodnoty uložené od výše zmíněné adresy 0×00800 mají tento význam:

Adresa Šířka dat Stručný popis
0×00800 16 bitů je vynulován
0×00802 16 bitů je vynulován
0×00804 16 bitů registr MSW
0×00806 16 bitů ?
0×00808 16 bitů je vynulován
0×0080A 16 bitů je vynulován
0×0080C 16 bitů je vynulován
0×0080E 16 bitů je vynulován
0×00810 16 bitů je vynulován
0×00812 16 bitů je vynulován
0×00814 16 bitů je vynulován
0×00816 16 bitů registr TR
0×00818 16 bitů příznakový registr
0×0081A 16 bitů registr IP
0×0081C 16 bitů registr LDT
0×0081E 16 bitů registr DS
0×00820 16 bitů registr SS
0×00822 16 bitů registr CS
0×00824 16 bitů registr ES
0×00826 16 bitů registr DI
0×00828 16 bitů registr SI
0×0082A 16 bitů registr BP
0×0082C 16 bitů registr SP
0×0082E 16 bitů registr BX
0×00830 16 bitů registr DX
0×00832 16 bitů registr CX
0×00834 16 bitů registr AX
0×00836 48 bitů deskriptor pro ES
0×0083C 48 bitů deskriptor pro CS
0×00842 48 bitů deskriptor pro SS
0×00848 48 bitů deskriptor pro DS
0×0084E 48 bitů deskriptor pro GDT
0×00854 48 bitů deskriptor pro LDT
0×0085A 48 bitů deskriptor pro IDT
0×00860 48 bitů deskriptor pro TSS
0×00866 konec konec tabulky

Pokud si tedy tento blok připravíme a budeme pouze měnit deskriptory od adresy 0X00836, je možné si postupně zpřístupnit veškerou nainstalovanou RAM. Není to řešení elegantní, ale funguje.

18. LOADALL na mikroprocesorech 80386

Stejně pojmenovaná (a stejně oficiálně nezdokumentovaná – vlastně ještě více utajovaná) je i instrukce LOADALL určená pro mikroprocesory 80386. Tato instrukce má odlišný operační kód 0F 07 a liší se i vyžadovaná struktura paměti, která je načtena do mikroprocesoru. Navíc se nyní explicitně udává adresa tohoto bloku paměti, a to konkrétně v registrech ES:EDI.

zabbix_tip

Zajímavé je, že bylo zjištěno, že ještě předtím, než se celá struktura načte do paměti, provede mikroprocesor čtení deseti 32bitových slov z adresy ES:EDI+0×100. Proč tomu tak je a kam se tato data ukládají, mi popravdě řečeno není známo. Nicméně se vraťme ke známým faktům – LOADALL opět načte obsahy registrů, kterých je na Intelu 80386 mnohem více. Taktéž se načtou deskriptory, které mají délku osmi bajtů a nikoli šesti bajtů (větší bázové adresy i limity). Podrobnosti o tomto mikroprocesoru (což byl pravděpodobně nejrevolučnější čip řady 80×86 až do doby, kdy vznikla 64bitová instrukční sada) si řekneme příště:

Šířka dat Stručný popis
32 bitů registr CR0
32 bitů příznaky EFLAGS
32 bitů registr EIP
32 bitů registr EDI
32 bitů registr ESI
32 bitů registr EBP
32 bitů registr ESP
32 bitů registr EBX
32 bitů registr EDX
32 bitů registr ECX
32 bitů registr EAX
32 bitů registr DR6
32 bitů registr DR7
32 bitů registr TR
32 bitů registr LDT
32 bitů segmentový registr GS s výplní
32 bitů segmentový registr FS s výplní
32 bitů segmentový registr DS s výplní
32 bitů segmentový registr SS s výplní
32 bitů segmentový registr CS s výplní
32 bitů segmentový registr ES s výplní
96 bitů deskriptor pro registr TSS + výplň 32 bitů
96 bitů deskriptor pro registr IDTD + výplň 32 bitů
96 bitů deskriptor pro registr GDTD + výplň 32 bitů
96 bitů deskriptor pro registr LDTD + výplň 32 bitů
96 bitů deskriptor pro segmentový registr GS + výplň 32 bitů
96 bitů deskriptor pro segmentový registr FS + výplň 32 bitů
96 bitů deskriptor pro segmentový registr DS + výplň 32 bitů
96 bitů deskriptor pro segmentový registr SS + výplň 32 bitů
96 bitů deskriptor pro segmentový registr CS + výplň 32 bitů
96 bitů deskriptor pro segmentový registr ES + výplň 32 bitů

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

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
Neutrální ikona do widgetu na odběr článků ze seriálů

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.

'; document.getElementById('preroll-iframe').onload = function () { setupIframe(); } prerollContainer = document.getElementsByClassName('preroll-container-iframe')[0]; } function setupIframe() { prerollDocument = document.getElementById('preroll-iframe').contentWindow.document; let el = prerollDocument.createElement('style'); prerollDocument.head.appendChild(el); el.innerText = "#adContainer>div:nth-of-type(1),#adContainer>div:nth-of-type(1) > iframe { width: 99% !important;height: 99% !important;max-width: 100%;}#videoContent,body{ width:100vw;height:100vh}body{ font-family:'Helvetica Neue',Arial,sans-serif}#videoContent{ overflow:hidden;background:#000}#adMuteBtn{ width:35px;height:35px;border:0;background:0 0;display:none;position:absolute;fill:rgba(230,230,230,1);bottom:20px;right:25px}"; videoContent = prerollDocument.getElementById('contentElement'); videoContent.style.display = 'none'; videoContent.volume = 1; videoContent.muted = false; const playPromise = videoContent.play(); if (playPromise !== undefined) { playPromise.then(function () { console.log('PREROLL sound allowed'); // setUpIMA(true); videoContent.volume = 1; videoContent.muted = false; setUpIMA(); }).catch(function () { console.log('PREROLL sound forbidden'); videoContent.volume = 0; videoContent.muted = true; setUpIMA(); }); } } function setupDimensions() { prerollWidth = Math.min(iinfoPrerollPosition.offsetWidth, 480); prerollHeight = Math.min(iinfoPrerollPosition.offsetHeight, 320); } function setUpIMA() { google.ima.settings.setDisableCustomPlaybackForIOS10Plus(true); google.ima.settings.setLocale('cs'); google.ima.settings.setNumRedirects(10); // Create the ad display container. createAdDisplayContainer(); // Create ads loader. adsLoader = new google.ima.AdsLoader(adDisplayContainer); // Listen and respond to ads loaded and error events. adsLoader.addEventListener( google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED, onAdsManagerLoaded, false); adsLoader.addEventListener( google.ima.AdErrorEvent.Type.AD_ERROR, onAdError, false); // An event listener to tell the SDK that our content video // is completed so the SDK can play any post-roll ads. const contentEndedListener = function () { adsLoader.contentComplete(); }; videoContent.onended = contentEndedListener; // Request video ads. const adsRequest = new google.ima.AdsRequest(); adsRequest.adTagUrl = iinfoVastUrls[iinfoVastUrlIndex]; console.log('Preroll advert: ' + iinfoVastUrls[iinfoVastUrlIndex]); videoContent.muted = false; videoContent.volume = 1; // Specify the linear and nonlinear slot sizes. This helps the SDK to // select the correct creative if multiple are returned. // adsRequest.linearAdSlotWidth = prerollWidth; // adsRequest.linearAdSlotHeight = prerollHeight; adsRequest.nonLinearAdSlotWidth = 0; adsRequest.nonLinearAdSlotHeight = 0; adsLoader.requestAds(adsRequest); } function createAdDisplayContainer() { // We assume the adContainer is the DOM id of the element that will house // the ads. prerollDocument.getElementById('videoContent').style.display = 'none'; adDisplayContainer = new google.ima.AdDisplayContainer( prerollDocument.getElementById('adContainer'), videoContent); } function unmutePrerollAdvert() { adVolume = !adVolume; if (adVolume) { adsManager.setVolume(0.3); prerollDocument.getElementById('adMuteBtn').innerHTML = ''; } else { adsManager.setVolume(0); prerollDocument.getElementById('adMuteBtn').innerHTML = ''; } } function onAdsManagerLoaded(adsManagerLoadedEvent) { // Get the ads manager. const adsRenderingSettings = new google.ima.AdsRenderingSettings(); adsRenderingSettings.restoreCustomPlaybackStateOnAdBreakComplete = true; adsRenderingSettings.loadVideoTimeout = 12000; // videoContent should be set to the content video element. adsManager = adsManagerLoadedEvent.getAdsManager(videoContent, adsRenderingSettings); // Add listeners to the required events. adsManager.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, onAdError); adsManager.addEventListener( google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED, onContentPauseRequested); adsManager.addEventListener( google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED, onContentResumeRequested); adsManager.addEventListener( google.ima.AdEvent.Type.ALL_ADS_COMPLETED, onAdEvent); // Listen to any additional events, if necessary. adsManager.addEventListener(google.ima.AdEvent.Type.LOADED, onAdEvent); adsManager.addEventListener(google.ima.AdEvent.Type.STARTED, onAdEvent); adsManager.addEventListener(google.ima.AdEvent.Type.COMPLETE, onAdEvent); playAds(); } function playAds() { // Initialize the container. Must be done through a user action on mobile // devices. videoContent.load(); adDisplayContainer.initialize(); // setupDimensions(); try { // Initialize the ads manager. Ad rules playlist will start at this time. adsManager.init(1920, 1080, google.ima.ViewMode.NORMAL); // Call play to start showing the ad. Single video and overlay ads will // start at this time; the call will be ignored for ad rules. adsManager.start(); // window.addEventListener('resize', function (event) { // if (adsManager) { // setupDimensions(); // adsManager.resize(prerollWidth, prerollHeight, google.ima.ViewMode.NORMAL); // } // }); } catch (adError) { // An error may be thrown if there was a problem with the VAST response. // videoContent.play(); } } function onAdEvent(adEvent) { const ad = adEvent.getAd(); console.log('Preroll event: ' + adEvent.type); switch (adEvent.type) { case google.ima.AdEvent.Type.LOADED: if (!ad.isLinear()) { videoContent.play(); } prerollDocument.getElementById('adContainer').style.width = '100%'; prerollDocument.getElementById('adContainer').style.maxWidth = '640px'; prerollDocument.getElementById('adContainer').style.height = '360px'; break; case google.ima.AdEvent.Type.STARTED: window.addEventListener('scroll', onActiveView); if (ad.isLinear()) { intervalTimer = setInterval( function () { // Example: const remainingTime = adsManager.getRemainingTime(); // adsManager.pause(); }, 300); // every 300ms } prerollDocument.getElementById('adMuteBtn').style.display = 'block'; break; case google.ima.AdEvent.Type.ALL_ADS_COMPLETED: if (ad.isLinear()) { clearInterval(intervalTimer); } if (prerollLastError === 303) { playYtVideo(); } break; case google.ima.AdEvent.Type.COMPLETE: if (ad.isLinear()) { clearInterval(intervalTimer); } playYtVideo(); break; } } function onAdError(adErrorEvent) { console.log(adErrorEvent.getError()); prerollLastError = adErrorEvent.getError().getErrorCode(); if (!loadNext()) { playYtVideo(); } } function loadNext() { iinfoVastUrlIndex++; if (iinfoVastUrlIndex < iinfoVastUrls.length) { iinfoPrerollPosition.remove(); playPrerollAd(); } else { return false; } adVolume = 1; return true; } function onContentPauseRequested() { videoContent.pause(); } function onContentResumeRequested() { videoContent.play(); } function onActiveView() { if (prerollContainer) { const containerOffset = prerollContainer.getBoundingClientRect(); const windowHeight = window.innerHeight; if (containerOffset.top < windowHeight/1 && containerOffset.bottom > 0.0) { if (prerollPaused) { adsManager.resume(); prerollPaused = false; } return true; } else { if (!prerollPaused) { adsManager.pause(); prerollPaused = true; } } } return false; } function playYtVideo() { iinfoPrerollPosition.remove(); youtubeIframe.style.display = 'block'; youtubeIframe.src += '&autoplay=1&mute=1'; } }
'; document.getElementById('outstream-iframe').onload = function () { setupIframe(); } replayScreen = document.getElementById('iinfoOutstreamReplay'); iinfoOutstreamPosition = document.getElementById('iinfoOutstreamPosition'); outstreamContainer = document.getElementsByClassName('outstream-container')[0]; setupReplayScreen(); } function setupIframe() { outstreamDocument = document.getElementById('outstream-iframe').contentWindow.document; let el = outstreamDocument.createElement('style'); outstreamDocument.head.appendChild(el); el.innerText = "#adContainer>div:nth-of-type(1),#adContainer>div:nth-of-type(1) > iframe { width: 99% !important;height: 99% !important;max-width: 100%;}#videoContent,body{ width:100vw;height:100vh}body{ font-family:'Helvetica Neue',Arial,sans-serif}#videoContent{ overflow:hidden;background:#000}#adMuteBtn{ width:35px;height:35px;border:0;background:0 0;display:none;position:absolute;fill:rgba(230,230,230,1);bottom:-5px;right:25px}"; videoContent = outstreamDocument.getElementById('contentElement'); videoContent.style.display = 'none'; videoContent.volume = 1; videoContent.muted = false; if ( location.href.indexOf('rejstriky.finance.cz') !== -1 || location.href.indexOf('finance-rejstrik') !== -1 || location.href.indexOf('firmy.euro.cz') !== -1 || location.href.indexOf('euro-rejstrik') !== -1 || location.href.indexOf('/rejstrik/') !== -1 || location.href.indexOf('/rejstrik-firem/') !== -1) { outstreamDirectPlayed = true; soundAllowed = true; iinfoVastUrlIndex = 0; } if (!outstreamDirectPlayed) { console.log('OUTSTREAM direct'); setUpIMA(true); } else { if (soundAllowed) { const playPromise = videoContent.play(); if (playPromise !== undefined) { playPromise.then(function () { console.log('OUTSTREAM sound allowed'); setUpIMA(false); }).catch(function () { console.log('OUTSTREAM sound forbidden'); renderBanner(); }); } } else { renderBanner(); } } } function getWrapper() { let articleWrapper = document.querySelector('.rs-outstream-placeholder'); // Outstream Placeholder from RedSys manipulation if (articleWrapper && articleWrapper.style.display !== 'block') { articleWrapper.innerHTML = ""; articleWrapper.style.display = 'block'; } // Don't render OutStream on homepages if (articleWrapper === null) { if (document.querySelector('body.p-index')) { return null; } } if (articleWrapper === null) { articleWrapper = document.getElementById('iinfo-outstream'); } if (articleWrapper === null) { articleWrapper = document.querySelector('.layout-main__content .detail__article p:nth-of-type(6)'); } if (articleWrapper === null) { // Euro, Autobible, Zdravi articleWrapper = document.querySelector('.o-article .o-article__text p:nth-of-type(6)'); } if (articleWrapper === null) { articleWrapper = document.getElementById('sidebar'); } if (!articleWrapper) { console.error("Outstream wrapper of article was not found."); } return articleWrapper; } function setupDimensions() { outstreamWidth = Math.min(iinfoOutstreamPosition.offsetWidth, 480); outstreamHeight = Math.min(iinfoOutstreamPosition.offsetHeight, 320); } /** * Sets up IMA ad display container, ads loader, and makes an ad request. */ function setUpIMA(direct) { google.ima.settings.setDisableCustomPlaybackForIOS10Plus(true); google.ima.settings.setLocale('cs'); google.ima.settings.setNumRedirects(10); // Create the ad display container. createAdDisplayContainer(); // Create ads loader. adsLoader = new google.ima.AdsLoader(adDisplayContainer); // Listen and respond to ads loaded and error events. adsLoader.addEventListener( google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED, onAdsManagerLoaded, false); adsLoader.addEventListener( google.ima.AdErrorEvent.Type.AD_ERROR, onAdError, false); // An event listener to tell the SDK that our content video // is completed so the SDK can play any post-roll ads. const contentEndedListener = function () { adsLoader.contentComplete(); }; videoContent.onended = contentEndedListener; // Request video ads. const adsRequest = new google.ima.AdsRequest(); if (direct) { adsRequest.adTagUrl = directVast; console.log('Outstream DIRECT CAMPAING advert: ' + directVast); videoContent.muted = true; videoContent.volume = 0; outstreamDirectPlayed = true; } else { adsRequest.adTagUrl = iinfoVastUrls[iinfoVastUrlIndex]; console.log('Outstream advert: ' + iinfoVastUrls[iinfoVastUrlIndex]); videoContent.muted = false; videoContent.volume = 1; } // Specify the linear and nonlinear slot sizes. This helps the SDK to // select the correct creative if multiple are returned. // adsRequest.linearAdSlotWidth = outstreamWidth; // adsRequest.linearAdSlotHeight = outstreamHeight; adsRequest.nonLinearAdSlotWidth = 0; adsRequest.nonLinearAdSlotHeight = 0; adsLoader.requestAds(adsRequest); } function setupReplayScreen() { replayScreen.addEventListener('click', function () { iinfoOutstreamPosition.remove(); iinfoVastUrlIndex = 0; outstreamInit(); }); } /** * Sets the 'adContainer' div as the IMA ad display container. */ function createAdDisplayContainer() { // We assume the adContainer is the DOM id of the element that will house // the ads. outstreamDocument.getElementById('videoContent').style.display = 'none'; adDisplayContainer = new google.ima.AdDisplayContainer( outstreamDocument.getElementById('adContainer'), videoContent); } function unmuteAdvert() { adVolume = !adVolume; if (adVolume) { adsManager.setVolume(0.3); outstreamDocument.getElementById('adMuteBtn').innerHTML = ''; } else { adsManager.setVolume(0); outstreamDocument.getElementById('adMuteBtn').innerHTML = ''; } } /** * Loads the video content and initializes IMA ad playback. */ function playAds() { // Initialize the container. Must be done through a user action on mobile // devices. videoContent.load(); adDisplayContainer.initialize(); // setupDimensions(); try { // Initialize the ads manager. Ad rules playlist will start at this time. adsManager.init(1920, 1080, google.ima.ViewMode.NORMAL); // Call play to start showing the ad. Single video and overlay ads will // start at this time; the call will be ignored for ad rules. adsManager.start(); // window.addEventListener('resize', function (event) { // if (adsManager) { // setupDimensions(); // adsManager.resize(outstreamWidth, outstreamHeight, google.ima.ViewMode.NORMAL); // } // }); } catch (adError) { // An error may be thrown if there was a problem with the VAST response. // videoContent.play(); } } /** * Handles the ad manager loading and sets ad event listeners. * @param { !google.ima.AdsManagerLoadedEvent } adsManagerLoadedEvent */ function onAdsManagerLoaded(adsManagerLoadedEvent) { // Get the ads manager. const adsRenderingSettings = new google.ima.AdsRenderingSettings(); adsRenderingSettings.restoreCustomPlaybackStateOnAdBreakComplete = true; adsRenderingSettings.loadVideoTimeout = 12000; // videoContent should be set to the content video element. adsManager = adsManagerLoadedEvent.getAdsManager(videoContent, adsRenderingSettings); // Add listeners to the required events. adsManager.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, onAdError); adsManager.addEventListener( google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED, onContentPauseRequested); adsManager.addEventListener( google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED, onContentResumeRequested); adsManager.addEventListener( google.ima.AdEvent.Type.ALL_ADS_COMPLETED, onAdEvent); // Listen to any additional events, if necessary. adsManager.addEventListener(google.ima.AdEvent.Type.LOADED, onAdEvent); adsManager.addEventListener(google.ima.AdEvent.Type.STARTED, onAdEvent); adsManager.addEventListener(google.ima.AdEvent.Type.COMPLETE, onAdEvent); playAds(); } /** * Handles actions taken in response to ad events. * @param { !google.ima.AdEvent } adEvent */ function onAdEvent(adEvent) { // Retrieve the ad from the event. Some events (for example, // ALL_ADS_COMPLETED) don't have ad object associated. const ad = adEvent.getAd(); console.log('Outstream event: ' + adEvent.type); switch (adEvent.type) { case google.ima.AdEvent.Type.LOADED: // This is the first event sent for an ad - it is possible to // determine whether the ad is a video ad or an overlay. if (!ad.isLinear()) { // Position AdDisplayContainer correctly for overlay. // Use ad.width and ad.height. videoContent.play(); } outstreamDocument.getElementById('adContainer').style.width = '100%'; outstreamDocument.getElementById('adContainer').style.maxWidth = '640px'; outstreamDocument.getElementById('adContainer').style.height = '360px'; break; case google.ima.AdEvent.Type.STARTED: window.addEventListener('scroll', onActiveView); // This event indicates the ad has started - the video player // can adjust the UI, for example display a pause button and // remaining time. if (ad.isLinear()) { // For a linear ad, a timer can be started to poll for // the remaining time. intervalTimer = setInterval( function () { // Example: const remainingTime = adsManager.getRemainingTime(); // adsManager.pause(); }, 300); // every 300ms } outstreamDocument.getElementById('adMuteBtn').style.display = 'block'; break; case google.ima.AdEvent.Type.ALL_ADS_COMPLETED: if (ad.isLinear()) { clearInterval(intervalTimer); } if (outstreamLastError === 303) { if (isBanner) { renderBanner(); } else { replayScreen.style.display = 'flex'; } } break; case google.ima.AdEvent.Type.COMPLETE: // This event indicates the ad has finished - the video player // can perform appropriate UI actions, such as removing the timer for // remaining time detection. if (ad.isLinear()) { clearInterval(intervalTimer); } if (isBanner) { renderBanner(); } else { replayScreen.style.display = 'flex'; } break; } } /** * Handles ad errors. * @param { !google.ima.AdErrorEvent } adErrorEvent */ function onAdError(adErrorEvent) { // Handle the error logging. console.log(adErrorEvent.getError()); outstreamLastError = adErrorEvent.getError().getErrorCode(); if (!loadNext()) { renderBanner(); } } function renderBanner() { if (isBanner) { console.log('Outstream: Render Banner'); iinfoOutstreamPosition.innerHTML = ""; iinfoOutstreamPosition.style.height = "330px"; iinfoOutstreamPosition.appendChild(bannerDiv); } else { console.log('Outstream: Banner is not set'); } } function loadNext() { iinfoVastUrlIndex++; if (iinfoVastUrlIndex < iinfoVastUrls.length) { iinfoOutstreamPosition.remove(); outstreamInit(); } else { return false; } adVolume = 1; return true; } /** * Pauses video content and sets up ad UI. */ function onContentPauseRequested() { videoContent.pause(); // This function is where you should setup UI for showing ads (for example, // display ad timer countdown, disable seeking and more.) // setupUIForAds(); } /** * Resumes video content and removes ad UI. */ function onContentResumeRequested() { videoContent.play(); // This function is where you should ensure that your UI is ready // to play content. It is the responsibility of the Publisher to // implement this function when necessary. // setupUIForContent(); } function onActiveView() { if (outstreamContainer) { const containerOffset = outstreamContainer.getBoundingClientRect(); const windowHeight = window.innerHeight; if (containerOffset.top < windowHeight/1 && containerOffset.bottom > 0.0) { if (outstreamPaused) { adsManager.resume(); outstreamPaused = false; } return true; } else { if (!outstreamPaused) { adsManager.pause(); outstreamPaused = true; } } } return false; } let outstreamInitInterval; if (typeof cpexPackage !== "undefined") { outstreamInitInterval = setInterval(tryToInitializeOutstream, 100); } else { const wrapper = getWrapper(); if (wrapper) { let outstreamInitialized = false; window.addEventListener('scroll', () => { if (!outstreamInitialized) { const containerOffset = wrapper.getBoundingClientRect(); const windowHeight = window.innerHeight; if (containerOffset.top < windowHeight / 1 && containerOffset.bottom > 0.0) { outstreamInit(); outstreamInitialized = true; } } }); } } function tryToInitializeOutstream() { const wrapper = getWrapper(); if (wrapper) { const containerOffset = wrapper.getBoundingClientRect(); const windowHeight = window.innerHeight; if (containerOffset.top < windowHeight / 1 && containerOffset.bottom > 0.0) { if (cpexPackage.adserver.displayed) { clearInterval(outstreamInitInterval); outstreamInit(); } } } else { clearInterval(outstreamInitInterval); } } }
OSZAR »