Obsah
1. Specifika instrukční sady mikroprocesorů Intel 8086/8088 (2)
2. Výpis osmibitové hexadecimální hodnoty na obrazovku
4. BCD aritmetika na čipech Intel 8086/8088
5. Operace součtu s využitím binární i BCD aritmetiky
6. Instrukce DAA po provedení operace rozdílu
7. Instrukce DAS po provedení operace rozdílu
8. BCD formát, v němž je každá cifra uložena v celém bajtu
9. Korekce výsledku na jedinou BCD cifru operací AAA
11. Ukázka výpočtu součinu dvou osmibitových hodnot
12. BCD korekce po výpočtu součinu instrukcí AAM
13. Řetězcové a blokové operace podporované mikroprocesory Intel 8086/8088
14. Varianty řetězcových a blokových operací
15. Zápis několika po sobě jdoucích znaků do řetězce
16. Vylepšení předchozího příkladu: opakování instrukce STOSB CX-krát
17. Překlad řetězcových instrukcí s prefixem i bez prefixu
19. Repositář s demonstračními příklady
1. Specifika instrukční sady mikroprocesorů Intel 8086/8088 (2)
V dnešním článku navážeme na úvodní část, přičemž se zaměříme na skutečně specifické instrukce, které byly na mikroprocesorech Intel 8086/8088 podporovány a v šestnáctibitovém a 32bitovém režimu musí být na platformě x86/x86–64(AMD64) podporovány dodnes, a to i na nejmodernějších čipech (ať již přímo nebo v emulované podobě). Bude se v první řadě jednat o instrukce pro BCD aritmetiku (dvě formy, takzvaná „ASCII BCD“ a „packed BCD“) a o „řetězcové instrukce“, které jsou pro platformu 8086 zcela typické a nutno říci, že zjednodušují vývoj v assembleru a zkracují, popř. i zrychlují výsledný strojový kód. Nezapomeneme ale ani na zajímavou instrukci XLAT.
Demonstrační příklady, které budou uvedeny v navazujících kapitolách, jsou založeny na následující šabloně, v níž je definován formát výstupního souboru i podporovaná instrukční sada (jen 8086/8088). Navíc jsou v šabloně definována makra pro ukončení procesu, pro čekání na stisk klávesy (služba BIOSu) a taktéž pro tisk řetězce na obrazovku (služba DOSu):
BITS 16 ; 16bitovy vystup pro DOS CPU 8086 ; specifikace pouziteho instrukcniho souboru ; ukonceni procesu a navrat do DOSu %macro exit 0 ret %endmacro ; vyprazdneni bufferu klavesnice a cekani na klavesu %macro wait_key 0 xor ax, ax int 0x16 %endmacro ; tisk retezce na obrazovku %macro print 1 mov dx, %1 mov ah, 9 int 0x21 %endmacro ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: print message wait_key exit ; retezec ukonceny znakem $ ; (tato data jsou soucasti vysledneho souboru typu COM) message db 0x01, 0x01, 0x0d, 0x0a, "$"
U jednotlivých demonstračních příkladů si budeme uvádět i výsledný strojový kód (bajty ve druhém sloupci za číslem řádku). Ten vypadá pro naši šablonu následovně:
1 BITS 16 ; 16bitovy vystup pro DOS 2 CPU 8086 ; specifikace pouziteho instrukcniho souboru 3 4 ; ukonceni procesu a navrat do DOSu 5 %macro exit 0 6 ret 7 %endmacro 8 9 ; vyprazdneni bufferu klavesnice a cekani na klavesu 10 %macro wait_key 0 11 xor ax, ax 12 int 0x16 13 %endmacro 14 15 ; tisk retezce na obrazovku 16 %macro print 1 17 mov dx, %1 18 mov ah, 9 19 int 0x21 20 %endmacro 21 22 ;----------------------------------------------------------------------------- 23 org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) 24 25 start: 26 print message 17 00000000 BA[0C00] <1> mov dx, %1 18 00000003 B409 <1> mov ah, 9 19 00000005 CD21 <1> int 0x21 27 wait_key 11 00000007 31C0 <1> xor ax, ax 12 00000009 CD16 <1> int 0x16 28 exit 6 0000000B C3 <1> ret 29 30 ; retezec ukonceny znakem $ 31 ; (tato data jsou soucasti vysledneho souboru typu COM) 32 0000000C 01010D0A24 message db 0x01, 0x01, 0x0d, 0x0a, "$"
2. Výpis osmibitové hexadecimální hodnoty na obrazovku
V dalších příkladech budeme pracovat s numerickými hodnotami, takže si ukažme, jakým způsobem lze na obrazovku vytisknout osmibitovou hexadecimální hodnotu. Nebude to nijak těžké. Nejdříve si připravíme řetězec, který budeme tisknout, přičemž první dva znaky tohoto řetězce budeme nahrazovat hexa číslicemi 0–9, a-f. Následují dva znaky pro odřádkování a návrat na začátek řádku a znak dolaru, který řetězec ukončuje (v tomto se DOS „inspiroval“ systémem CP/M):
; retezec ukonceny znakem $ ; (tato data jsou soucasti vysledneho souboru typu COM) message db 0x01, 0x01, 0x0d, 0x0a, "$"
Převod hodnoty 0–15 na hexadecimální číslici lze naprogramovat (to jsme si ukázali u ZX Spectra) nebo lze použít jednoduchou převodní tabulku. ASCII sada totiž po číslici „9“ nenavazuje znakem „A“ nebo „a“, takže v převodní tabulce (nebo programovém kódu) musíme realizovat „přeskok“:
; prevodni tabulka hodnoty 0-15 na ASCII znak hex_digits db "0123456789abcdef"
Nyní se pokusíme převést první (vyšší) číslici uloženou v registru CL na ASCII znak a ten uložit do výše uvedeného řetězce message (zapisujeme do kódového segmentu :-). Postupně si připravíme hodnotu 0–15 v registru BX a využijeme adresovací režim popsaný minule:
xor bh, bh ; vynulovat horni bajt offsetu mov bl, cl ; do BL se vlozi horni hexa cifra and bl, 0xf0 ; není zapotřebí, jen naznačujeme, že se využijí horní 4 bity shr bl, 1 ; horní čtyři bity do dolních čtyř bitů shr bl, 1 shr bl, 1 shr bl, 1 mov al, [hex_digits + bx] ; prevod hodnoty 0-15 na ASCII znak mov [message], al ; zapis ASCII znaku do retezce
Výpis spodní číslice je jednodušší, neboť nemusíme použít bitové posuny:
mov bl, cl ; do BL se vlozi dolni hexa cifra and bl, 0x0f mov al, [hex_digits + bx] ; prevod hodnoty 0-15 na ASCII znak mov [message + 1], al ; zapis ASCII znaku do retezce
Celý výše uvedený kód vložíme do subrutiny nebo do makra. Pro zajímavost použijeme makro (což ale v praxi znamená, že každé použití makra nám celý program „natáhne“ o cca 40 bajtů!):
; tisk hexadecimalni hodnoty %macro print_hex 1 mov cl, %1 ; zapamatovat si predanou hodnotu xor bh, bh ; vynulovat horni bajt offsetu mov bl, cl ; do BL se vlozi horni hexa cifra and bl, 0xf0 ; není zapotřebí, jen naznačujeme, že se využijí horní 4 bity shr bl, 1 shr bl, 1 shr bl, 1 shr bl, 1 mov al, [hex_digits + bx] ; prevod hodnoty 0-15 na ASCII znak mov [message], al ; zapis ASCII znaku do retezce mov bl, cl ; do BL se vlozi dolni hexa cifra and bl, 0x0f mov al, [hex_digits + bx] ; prevod hodnoty 0-15 na ASCII znak mov [message + 1], al ; zapis ASCII znaku do retezce print message %endmacro
Překlad výše uvedeného makra při jeho prvním použití (expanzi):
48 print_hex 0x00 24 00000000 B100 mov cl, %1 25 00000002 30FF xor bh, bh 26 27 00000004 88CB mov bl, cl 28 00000006 80E3F0 and bl, 0xf0 29 00000009 D0EB shr bl, 1 30 0000000B D0EB shr bl, 1 31 0000000D D0EB shr bl, 1 32 0000000F D0EB shr bl, 1 33 34 00000011 8A87[B600] mov al, [hex_digits + bx] 35 00000015 A2[B100] mov [message], al 36 37 00000018 88CB mov bl, cl 38 0000001A 80E30F and bl, 0x0f 39 0000001D 8A87[B600] mov al, [hex_digits + bx] 40 00000021 A2[B200] mov [message + 1], al 41 print message 17 00000024 BA[B100] mov dx, %1 18 00000027 B409 mov ah, 9 19 00000029 CD21 int 0x21
A takto vypadá úplný zdrojový kód dnešního druhého demonstračního příkladu:
BITS 16 ; 16bitovy vystup pro DOS CPU 8086 ; specifikace pouziteho instrukcniho souboru ; ukonceni procesu a navrat do DOSu %macro exit 0 ret %endmacro ; vyprazdneni bufferu klavesnice a cekani na klavesu %macro wait_key 0 xor ax, ax int 0x16 %endmacro ; tisk retezce na obrazovku %macro print 1 mov dx, %1 mov ah, 9 int 0x21 %endmacro ; tisk hexadecimalni hodnoty %macro print_hex 1 mov cl, %1 ; zapamatovat si predanou hodnotu xor bh, bh ; vynulovat horni bajt offsetu mov bl, cl ; do BL se vlozi horni hexa cifra and bl, 0xf0 ; není zapotřebí, jen naznačujeme, že se využijí horní 4 bity shr bl, 1 shr bl, 1 shr bl, 1 shr bl, 1 mov al, [hex_digits + bx] ; prevod hodnoty 0-15 na ASCII znak mov [message], al ; zapis ASCII znaku do retezce mov bl, cl ; do BL se vlozi dolni hexa cifra and bl, 0x0f mov al, [hex_digits + bx] ; prevod hodnoty 0-15 na ASCII znak mov [message + 1], al ; zapis ASCII znaku do retezce print message %endmacro ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: print_hex 0x00 print_hex 0x12 print_hex 0xab print_hex 0xff wait_key exit ; retezec ukonceny znakem $ ; (tato data jsou soucasti vysledneho souboru typu COM) message db 0x01, 0x01, 0x0d, 0x0a, "$" ; prevodni tabulka hodnoty 0-15 na ASCII znak hex_digits db "0123456789abcdef"
3. Instrukce XLAT
Ve skutečnosti je možné převod hexadecimální hodnoty na ASCII řetězec napsat i odlišným způsobem, konkrétně s využitím instrukce XLAT. Tato instrukce dokáže načíst hodnotu z adresy DS : [BX+AL] a uložit výsledek opět do registru AL. To znamená, že takto můžeme relativně snadno realizovat vyhledávací tabulky. Mimochodem: jedná se o jedinou instrukci, v níž je použit registr AL pro výpočet adresy.
Po malých úpravách (změna použitých registrů) bude makro pro převod osmibitové hodnoty na ASCII řetězec s hexadecimální variantou hodnoty vypadat následovně:
mov bx, hex_digits mov cl, %1 ; zapamatovat si predanou hodnotu mov al, cl ; do AL se vlozi horni hexa cifra and al, 0xf0 ; není zapotřebí, jen naznačujeme, že se využijí horní 4 bity shr al, 1 shr al, 1 shr al, 1 shr al, 1 xlat ; prevod hodnoty 0-15 na ASCII znak mov [message], al ; zapis ASCII znaku do retezce mov al, cl ; do BL se vlozi dolni hexa cifra and al, 0x0f xlat ; prevod hodnoty 0-15 na ASCII znak mov [message + 1], al ; zapis ASCII znaku do retezce
Pro úplnost si ukažme, jak vypadá celý zdrojový kód dnešního třetího demonstračního příkladu:
BITS 16 ; 16bitovy vystup pro DOS CPU 8086 ; specifikace pouziteho instrukcniho souboru ; ukonceni procesu a navrat do DOSu %macro exit 0 ret %endmacro ; vyprazdneni bufferu klavesnice a cekani na klavesu %macro wait_key 0 xor ax, ax int 0x16 %endmacro ; tisk retezce na obrazovku %macro print 1 mov dx, %1 mov ah, 9 int 0x21 %endmacro ; tisk hexadecimalni hodnoty %macro print_hex 1 mov bx, hex_digits mov cl, %1 ; zapamatovat si predanou hodnotu mov al, cl ; do AL se vlozi horni hexa cifra and al, 0xf0 ; není zapotřebí, jen naznačujeme, že se využijí horní 4 bity shr al, 1 shr al, 1 shr al, 1 shr al, 1 xlat ; prevod hodnoty 0-15 na ASCII znak mov [message], al ; zapis ASCII znaku do retezce mov al, cl ; do BL se vlozi dolni hexa cifra and al, 0x0f xlat ; prevod hodnoty 0-15 na ASCII znak mov [message + 1], al ; zapis ASCII znaku do retezce print message %endmacro ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: print_hex 0x00 print_hex 0x12 print_hex 0xab print_hex 0xff wait_key exit ; retezec ukonceny znakem $ ; (tato data jsou soucasti vysledneho souboru typu COM) message db 0x01, 0x01, 0x0d, 0x0a, "$" ; prevodni tabulka hodnoty 0-15 na ASCII znak hex_digits db "0123456789abcdef"
4. BCD aritmetika na čipech Intel 8086/8088
Mikroprocesory řady Intel 8086 (a tím pádem i 8088) podporovaly provádění základních aritmetických operací s BCD hodnotami (Binary-Coded Decimal). V tomto případě osmibitové registry obsahují buď pouze jednu cifru (tj. hodnotu 0–9 z možného rozsahu 0–256) nebo dvojici desítkových cifer – první cifra je uložena v horních čtyřech bitech, druhá cifra pochopitelně v dolních čtyřech bitech). Maximální rozsah uložených hodnot tedy nebude 0–255, ale jen 0–99, ovšem výhodou je snadnější převod do tisknutelné podoby, snadné zvětšení počtu cifer atd. S BCD, především s jeho „komprimovanou“ podobou (tedy rozsah 0–99 v jednom bajtu) se setkáme jak v některých čipech (hodiny reálného času, řadiče sedmisegmentových displejů), tak i například v databázových systémech, v některých systémech pro zpracování měny atd.
K dispozici jsou následující instrukce pro práci s BCD:
Instrukce | Operand | Stručný popis instrukce |
---|---|---|
AAA | jedna cifra v bajtu | úprava výsledku součtu na BCD tvar |
AAS | jedna cifra v bajtu | úprava výsledku rozdílu na BCD tvar |
DAA | dvě cifry v bajtu | úprava výsledku součtu na BCD tvar |
DAS | dvě cifry v bajtu | úprava výsledku rozdílu na BCD tvar |
AAM | dvě cifry v bajtu | úprava výsledku součinu na BCD tvar |
AAD | dvě cifry v bajtu | úprava hodnoty před provedením operace dělení |
5. Operace součtu s využitím binární i BCD aritmetiky
Mikroprocesory 8086 se nepřepínají do „režimu binární aritmetiky“ a „režimu BCD“ tak, jako například MOS 6502. Namísto toho se po provedení nějaké aritmetické operace musí explicitně výsledek této operace upravit. Základem je instrukce DAA, která upraví výsledek součtu. Konkrétně to znamená, že pokud dojde k přetečení mezi čtvrtým a pátým bitem (což se nastaví jako jeden z příznaků) nebo je hodnota nižších čtyř bitů větší než 0×0f, přičte se k výsledku šestka, čímž se upraví spodní cifra a zvýší cifra horní. Podobně pokud je hodnota vyšší než 0×99 nebo došlo k přenosu, přičte se k výsledku 0×60. Po provedení instrukce DAA tedy bude registr AL obsahovat hodnotu 0–99 zakódovanou jako dvojici BCD cifer.
Vyzkoušejme si to na čtveřici operací – vždy dvě budou provedeny s binárními hodnotami a dvě s BCD hodnotami:
mov al, 0x49 inc al print_hex al ; vytiskne se 4a (binární) mov al, 0x49 inc al daa print_hex al ; vytiskne se 50 (korektní BCD) mov al, 0x99 inc al print_hex al ; vytiskne se 9a (binární) mov al, 0x99 inc al daa print_hex al ; vytiskne se 00 (korektní BCD, došlo k přetečení, takže vlastně 100)
Úplný zdrojový kód demonstračního příkladu vypadá takto:
BITS 16 ; 16bitovy vystup pro DOS CPU 8086 ; specifikace pouziteho instrukcniho souboru ; ukonceni procesu a navrat do DOSu %macro exit 0 ret %endmacro ; vyprazdneni bufferu klavesnice a cekani na klavesu %macro wait_key 0 xor ax, ax int 0x16 %endmacro ; tisk retezce na obrazovku %macro print 1 mov dx, %1 mov ah, 9 int 0x21 %endmacro ; tisk hexadecimalni hodnoty %macro print_hex 1 mov bx, hex_digits mov cl, %1 ; zapamatovat si predanou hodnotu mov al, cl ; do AL se vlozi horni hexa cifra and al, 0xf0 shr al, 1 shr al, 1 shr al, 1 shr al, 1 xlat ; prevod hodnoty 0-15 na ASCII znak mov [message], al ; zapis ASCII znaku do retezce mov al, cl ; do BL se vlozi dolni hexa cifra and al, 0x0f xlat ; prevod hodnoty 0-15 na ASCII znak mov [message + 1], al ; zapis ASCII znaku do retezce print message %endmacro ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: mov al, 0x49 inc al print_hex al mov al, 0x49 inc al daa print_hex al mov al, 0x99 inc al print_hex al mov al, 0x99 inc al daa print_hex al wait_key exit ; retezec ukonceny znakem $ ; (tato data jsou soucasti vysledneho souboru typu COM) message db 0x01, 0x01, 0x0d, 0x0a, "$" ; prevodni tabulka hodnoty 0-15 na ASCII znak hex_digits db "0123456789abcdef"
6. Instrukce DAA po provedení operace rozdílu
V předchozí kapitole jsme si řekli, že instrukce DAA slouží pro úpravu výsledku operace součtu na BCD tvar. Jak je tomu však ve chvíli, kdy provedeme DAA po operaci rozdílu? Na některých CPU bude výsledek korektní, takže si si zkusme:
mov al, 0x40 sub al, 1 print_hex al ; = 3f, což je korektní v binárním kódu mov al, 0x40 sub al, 1 daa print_hex al ; = 45, což je v BCD špatně xor al, al sub al, 1 print_hex al ; = ff, což je korektní -1 xor al, al sub al, 1 daa print_hex al ; = 65, což je v BCD špatně
Vidíme tedy, že instrukce DAA po operaci rozdílu nebo snížení hodnoty o 1 nedává korektní výsledky, i když nastavuje všechny potřebné příznaky.
Úplný zdrojový kód tohoto demonstračního příkladu vypadá následovně:
BITS 16 ; 16bitovy vystup pro DOS CPU 8086 ; specifikace pouziteho instrukcniho souboru ; ukonceni procesu a navrat do DOSu %macro exit 0 ret %endmacro ; vyprazdneni bufferu klavesnice a cekani na klavesu %macro wait_key 0 xor ax, ax int 0x16 %endmacro ; tisk retezce na obrazovku %macro print 1 mov dx, %1 mov ah, 9 int 0x21 %endmacro ; tisk hexadecimalni hodnoty %macro print_hex 1 mov bx, hex_digits mov cl, %1 ; zapamatovat si predanou hodnotu mov al, cl ; do AL se vlozi horni hexa cifra and al, 0xf0 shr al, 1 shr al, 1 shr al, 1 shr al, 1 xlat ; prevod hodnoty 0-15 na ASCII znak mov [message], al ; zapis ASCII znaku do retezce mov al, cl ; do BL se vlozi dolni hexa cifra and al, 0x0f xlat ; prevod hodnoty 0-15 na ASCII znak mov [message + 1], al ; zapis ASCII znaku do retezce print message %endmacro ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: mov al, 0x40 sub al, 1 print_hex al mov al, 0x40 sub al, 1 daa print_hex al xor al, al sub al, 1 print_hex al xor al, al sub al, 1 daa print_hex al wait_key exit ; retezec ukonceny znakem $ ; (tato data jsou soucasti vysledneho souboru typu COM) message db 0x01, 0x01, 0x0d, 0x0a, "$" ; prevodni tabulka hodnoty 0-15 na ASCII znak hex_digits db "0123456789abcdef"
7. Instrukce DAS po provedení operace rozdílu
Po provedení operace rozdílu je nutné pro získání korektního výsledku reprezentovaného v BCD použít instrukci DAS, která provádí podobné korekce jako DAA (na základě hodnoty horních a spodních čtyř bitů výsledku i příznaků), ovšem namísto toho, aby se k cifrám přičítaly hodnoty 6 a 0×60, se tyto hodnoty odečítají. Opět si tedy ověřme, zda kombinace SUB+DAS (nebo DEC+DAS) poskytne korektní BCD hodnotu:
mov al, 0x40 sub al, 1 print_hex al ; = 3f, což je korektní v binárním kódu mov al, 0x40 sub al, 1 das print_hex al ; = 39, což je v BCD dobře xor al, al sub al, 1 print_hex al ; = ff, což je korektní -1 xor al, al sub al, 1 das print_hex al ; = 99, což je v BCD dobře (0-1 = 99-100)
Pro jistotu si opět uveďme úplný zdrojový kód tohoto demonstračního příkladu:
BITS 16 ; 16bitovy vystup pro DOS CPU 8086 ; specifikace pouziteho instrukcniho souboru ; ukonceni procesu a navrat do DOSu %macro exit 0 ret %endmacro ; vyprazdneni bufferu klavesnice a cekani na klavesu %macro wait_key 0 xor ax, ax int 0x16 %endmacro ; tisk retezce na obrazovku %macro print 1 mov dx, %1 mov ah, 9 int 0x21 %endmacro ; tisk hexadecimalni hodnoty %macro print_hex 1 mov bx, hex_digits mov cl, %1 ; zapamatovat si predanou hodnotu mov al, cl ; do AL se vlozi horni hexa cifra and al, 0xf0 shr al, 1 shr al, 1 shr al, 1 shr al, 1 xlat ; prevod hodnoty 0-15 na ASCII znak mov [message], al ; zapis ASCII znaku do retezce mov al, cl ; do BL se vlozi dolni hexa cifra and al, 0x0f xlat ; prevod hodnoty 0-15 na ASCII znak mov [message + 1], al ; zapis ASCII znaku do retezce print message %endmacro ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: mov al, 0x40 sub al, 1 print_hex al mov al, 0x40 sub al, 1 das print_hex al xor al, al sub al, 1 print_hex al xor al, al sub al, 1 das print_hex al wait_key exit ; retezec ukonceny znakem $ ; (tato data jsou soucasti vysledneho souboru typu COM) message db 0x01, 0x01, 0x0d, 0x0a, "$" ; prevodni tabulka hodnoty 0-15 na ASCII znak hex_digits db "0123456789abcdef"
8. BCD formát, v němž je každá cifra uložena v celém bajtu
Mikroprocesory řady Intel 8086 podporovaly i BCD formát, ve kterém je každá cifra uložena v celém bajtu, tj. bajt může obsahovat pouze hodnoty 0 až 9, zbylých 245 možných hodnot je nevyužito. To pochopitelně představuje značné paměťové nároky, protože například hodnotu 10000 lze uložit do dvou bajtů při použití binárního formátu, do třech bajtů při použití „packed“ BCD, ovšem do celých pěti bajtu při použití zde popisovaného „unpacked“ formátu. Na druhou stranu je například převod hodnoty na ASCII triviální (přičtení konstanty nebo OR konstanty) a obejde se bez bitových posunů, maskování nebo dokonce provedení operace dělení.
Podobně jako pro „packed“ BCD existují instrukce pro korekci výsledku nazvané DAA a DAS, existuje pro „unpacked“ BCD dvojice instrukcí nazvaných AAA a AAS, tedy korekce po součtu, resp. rozdílu.
9. Korekce výsledku na jedinou BCD cifru operací AAA
Nejprve si ukažme korekci výsledku po součtu dvojice BCD hodnot (a je jedno, jestli ve formátu „packed“ nebo „unpacked“) instrukcí AAA. Výsledky porovnáme s korekční instrukcí DAA:
mov al, 8 inc al print_hex al ; = 9 (korektní pro všechny formáty, protože cifra nepřetekla na (1)0) mov al, 9 inc al print_hex al ; = 0a (korektní pro binární formát) mov al, 8 inc al daa print_hex al ; = 9 (korektní pro všechny formáty, protože cifra nepřetekla na (1)0) mov al, 9 inc al daa print_hex al ; = 10 (korektní pro packed BCD) mov al, 8 inc al aaa print_hex al ; = 9 (korektní pro všechny formáty, protože cifra nepřetekla na (1)0) mov al, 9 inc al aaa print_hex al ; = 0 (korektní pro unpacked BCD - došlo k přetečení)
A opět, jak je již zvykem, si uveďme celý příklad:
BITS 16 ; 16bitovy vystup pro DOS CPU 8086 ; specifikace pouziteho instrukcniho souboru ; ukonceni procesu a navrat do DOSu %macro exit 0 ret %endmacro ; vyprazdneni bufferu klavesnice a cekani na klavesu %macro wait_key 0 xor ax, ax int 0x16 %endmacro ; tisk retezce na obrazovku %macro print 1 mov dx, %1 mov ah, 9 int 0x21 %endmacro ; tisk hexadecimalni hodnoty %macro print_hex 1 mov bx, hex_digits mov cl, %1 ; zapamatovat si predanou hodnotu mov al, cl ; do AL se vlozi horni hexa cifra and al, 0xf0 shr al, 1 shr al, 1 shr al, 1 shr al, 1 xlat ; prevod hodnoty 0-15 na ASCII znak mov [message], al ; zapis ASCII znaku do retezce mov al, cl ; do BL se vlozi dolni hexa cifra and al, 0x0f xlat ; prevod hodnoty 0-15 na ASCII znak mov [message + 1], al ; zapis ASCII znaku do retezce print message %endmacro ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: mov al, 8 inc al print_hex al mov al, 9 inc al print_hex al mov al, 8 inc al daa print_hex al mov al, 9 inc al daa print_hex al mov al, 8 inc al aaa print_hex al mov al, 9 inc al aaa print_hex al wait_key exit ; retezec ukonceny znakem $ ; (tato data jsou soucasti vysledneho souboru typu COM) message db 0x01, 0x01, 0x0d, 0x0a, "$" ; prevodni tabulka hodnoty 0-15 na ASCII znak hex_digits db "0123456789abcdef"
10. Operace součinu a podílu
Čipy Intel 8086/8088 již patří do generace mikroprocesorů s implementovanou operací násobení a dělení (tedy součinu a podílu). Zde konkrétně se tyto operace rozlišují podle toho, zda se násobí osmibitové či 16bitové operandy (popř. dělí 32bitový dělitel nebo 16bitový dělitel) a zda má být operace provedena se znaménkem nebo bez znaménka. Tyto operace nejsou v žádném případě rychlé, což ostatně naznačuje i následující tabulka:
Instrukce | Operace | Doba trvání | Stručný popis instrukce |
---|---|---|---|
MUL | AX = AL * 8bit | 70–77 | součin bezznaménkových hodnot |
MUL | DX:AX = AX * 16bit | 118–133 | součin bezznaménkových hodnot |
IMUL | AX = AL * 8bit | 80–98 | součin hodnot se znaménkem |
IMUL | DX:AX = AX * 16bit | 128–154 | součin hodnot se znaménkem |
DIV | AL = AX / 8bit, AH = AX % 8bit | 80–90 | podíl (a zbytek) bezznaménkových hodnot |
DIV | AX = DX:AX / 16bit, DX = DX:AX % 16bit | 144–162 | podíl (a zbytek) bezznaménkových hodnot |
IDIV | AL = AX / 8bit, AH = AX % 8bit | 101–112 | podíl (a zbytek) hodnot se znaménkem |
IDIV | AX = DX:AX / 16bit, DX = DX:AX % 16bit | 165–184 | podíl (a zbytek) hodnot se znaménkem |
I pro tyto operace existují „korekční“ instrukce pro BCD formát, jak si ukážeme níže a taktéž v navazujícím článku.
11. Ukázka výpočtu součinu dvou osmibitových hodnot
Vyzkoušejme si pro zajímavost vynásobit dvě osmibitové hodnoty. Víme již, že jeden z činitelů musí být uložen v registru AL a 16bitový výsledek bude uložen do registru AX. Násobení provedeme instrukcí MUL, což znamená, že jak operandy, tak i výsledek budou bezznaménkové:
mov al, 6 mov ah, 7 mul ah print_hex al
Výsledná vypsaná hodnota bude rovna 2A, což dekadicky skutečně znamená 42 (6×7).
Úplný zdrojový kód tohoto demonstračního příkladu vypadá následovně:
BITS 16 ; 16bitovy vystup pro DOS CPU 8086 ; specifikace pouziteho instrukcniho souboru ; ukonceni procesu a navrat do DOSu %macro exit 0 ret %endmacro ; vyprazdneni bufferu klavesnice a cekani na klavesu %macro wait_key 0 xor ax, ax int 0x16 %endmacro ; tisk retezce na obrazovku %macro print 1 mov dx, %1 mov ah, 9 int 0x21 %endmacro ; tisk hexadecimalni hodnoty %macro print_hex 1 mov bx, hex_digits mov cl, %1 ; zapamatovat si predanou hodnotu mov al, cl ; do AL se vlozi horni hexa cifra and al, 0xf0 shr al, 1 shr al, 1 shr al, 1 shr al, 1 xlat ; prevod hodnoty 0-15 na ASCII znak mov [message], al ; zapis ASCII znaku do retezce mov al, cl ; do BL se vlozi dolni hexa cifra and al, 0x0f xlat ; prevod hodnoty 0-15 na ASCII znak mov [message + 1], al ; zapis ASCII znaku do retezce print message %endmacro ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: mov al, 6 mov ah, 7 mul ah print_hex al wait_key exit ; retezec ukonceny znakem $ ; (tato data jsou soucasti vysledneho souboru typu COM) message db 0x01, 0x01, 0x0d, 0x0a, "$" ; prevodni tabulka hodnoty 0-15 na ASCII znak hex_digits db "0123456789abcdef"
12. BCD korekce po výpočtu součinu instrukcí AAM
Po provedení násobení je výsledek uložen v binárním formátu, jak je to obvyklé. Můžeme ovšem provést nějakou korekci výsledku tak, aby byl součin transformován do BCD? Na platformě Intel 8086/8088 je to možné, protože tato platforma nabízí neobvyklou instrukci nazvanou AAM neboli ASCII Adjust After Multiply. Název této operace je poněkud matoucí, ovšem její funkce je relativně jednoduchá, protože se provedou tyto tři operace:
tmp := AL AH := tmp / imm8 AL := tmp MOD imm8
přičemž platí, že se instrukce AAM přeloží tak, že druhý bajt instrukčního kódu obsahuje konstantu imm8 nastavenou na 10. To znamená, že AAM vypočítá nejnižší cifru výsledku a uloží ji do AL. Hodnotu výsledku podělenou deseti pak uloží do registru AH, takže opakovaným prováděním instrukce AAM můžeme získat jednotlivé cifry. Jednoduché řešení, že?
Podívejme se nyní, jak získáme jednotlivé cifry výsledku operace 6×7. Víme, že se bude jednat o dvouciferný výsledek, takže pouze zobrazíme AL (nižší cifru) a potom AH (výsledek po vydělení 10, nyní přímo vyšší cifru):
BITS 16 ; 16bitovy vystup pro DOS CPU 8086 ; specifikace pouziteho instrukcniho souboru ; ukonceni procesu a navrat do DOSu %macro exit 0 ret %endmacro ; vyprazdneni bufferu klavesnice a cekani na klavesu %macro wait_key 0 xor ax, ax int 0x16 %endmacro ; tisk retezce na obrazovku %macro print 1 mov dx, %1 mov ah, 9 int 0x21 %endmacro ; tisk hexadecimalni hodnoty %macro print_hex 1 mov bx, hex_digits mov cl, %1 ; zapamatovat si predanou hodnotu mov al, cl ; do AL se vlozi horni hexa cifra and al, 0xf0 shr al, 1 shr al, 1 shr al, 1 shr al, 1 xlat ; prevod hodnoty 0-15 na ASCII znak mov [message], al ; zapis ASCII znaku do retezce mov al, cl ; do BL se vlozi dolni hexa cifra and al, 0x0f xlat ; prevod hodnoty 0-15 na ASCII znak mov [message + 1], al ; zapis ASCII znaku do retezce print message %endmacro ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: mov al, 6 mov ah, 7 mul ah ; nasobek aam ; naplni se AX shl ah, 1 ; vysuneme cifru do hornich 4 bitu shl ah, 1 shl ah, 1 shl ah, 1 or al, ah ; spojime dve BCD cifry print_hex al wait_key exit ; retezec ukonceny znakem $ ; (tato data jsou soucasti vysledneho souboru typu COM) message db 0x01, 0x01, 0x0d, 0x0a, "$" ; prevodni tabulka hodnoty 0-15 na ASCII znak hex_digits db "0123456789abcdef"
13. Řetězcové a blokové operace podporované mikroprocesory Intel 8086/8088
Zcela specifickou vlastností mikroprocesorů řady Intel 8086/8088 jsou instrukce určené pro provádění řetězcových a blokových operací. Tyto instrukce dokážou přečíst, popř. zapsat (popř. provést obě operace za sebou) bajt či slovo z adresy určené segmentovým a indexovým registrem, přičemž se příslušným způsobem upraví hodnota indexového registru: zvýší či sníží se o jedničku. Navíc lze prefixem REP (a jeho variantami) zajistit opakování těchto instrukcí, takže je například možné přenést celý řetězec či blok jedinou instrukcí. To znamená velkou úsporu místa (programový kód) a částečně i času (rychlejší provádění instrukcí), ovšem je nutné mít připraveny všechny adresy v příslušných registrech, mít korektně nastaven příznak určující, zda se mají adresy zvyšovat či snižovat a při opakování instrukcí je nutné mít i nastaveno počitadlo. A především – překladače vyšších programovacích jazyků musí být schopné tyto instrukce využít (což se zpočátku nedělo, takže tato vlastnost čipů Intel 8086 nebyla plně využívána).
14. Varianty řetězcových a blokových operací
V instrukčním souboru mikroprocesorů Intel 8086 nalezneme následující instrukce realizující řetězcové a blokové operace, popř. jejich nastavení:
Instrukce | Stručný popis instrukce |
---|---|
CLD | nastaví příznak DF pro určení směru přenosu (nahoru) |
STD | nastaví příznak DF pro určení směru přenosu (dolů) |
LODSB | načtení bajtu do AL z DS : [SI], zvýšení/snížení SI o 1 |
LODSW | načtení slova do AX z DS : [SI], zvýšení/snížení SI o 2 |
STOSB | uložení slova z AL do ES : [DI], zvýšení/snížení DI o 1 |
STOSW | uložení slova z AL do ES : [DI], zvýšení/snížení DI o 2 |
MOVSB | kombinace LODSB + STOSB v jediné instrukci |
MOVSW | kombinace LODSW + STOSW v jediné instrukci |
CMPSB | porovnání dvou bajtů z DS : [SI] a ES : [DI], zvýšení/snížení SI a DI |
CMPSW | porovnání dvou slov z DS : [SI] a ES : [DI], zvýšení/snížení SI a DI |
SCASB | nalezení bajtu v AL na adrese DS : [SI] (mění příznaky) |
SCASW | nalezení bajtu v AX na adrese DS : [SI] (mění příznaky) |
INSB | přečtení bajtu z portu, uložení na ES : [DI], zvýšení/snížení DI |
OUTSB | zápis bajtu na port z DS : [SI], zvýšení/snížení SI |
REP/REPE/REPZ | opakování další operace CX-krát |
REPNE/REPNZ | opakování další operace CX-krát, nebo až bude ZF==1 |
Jednotlivé instrukce i jejich varianty si pochopitelně postupně popíšeme. Taktéž se zmíníme o rychlosti provedení těchto operací, protože to může být v reálných programech kritickým místem.
15. Zápis několika po sobě jdoucích znaků do řetězce
Pokusme se nyní do následujícího řetězce:
; retezec ukonceny znakem $ ; (tato data jsou soucasti vysledneho souboru typu COM) message db "Hello, world!", 0x0d, 0x0a, "$"
zapsat namísto prvního slova pětici hvězdiček, tj. výsledek by měl vypadat takto: „*****, world!\r\n!“
Tuto operaci lze provést následujícím způsobem:
- Do dvojice registrů ES:DI vložíme adresu prvního znaku (tedy znaku „H“)
- Do registru AL vložíme ASCII hodnotu hvězdičky
- (Měl by se nastavit i příznak DF, ten je však při startu korektní)
- Pětkrát zopakujeme instrukci STOSB, která vlastně provede mov ES, AL + inc DI
V assembleru to vypadá následovně (prozatím otrocky opíšeme STOSB pětkrát):
push cs pop es ; ES:DI obsahuje adresu prvniho znaku ve zprave mov di, message mov al, "*" stosb ; zapis hvezdicky a posun adresy stosb ; zapis hvezdicky a posun adresy stosb ; zapis hvezdicky a posun adresy stosb ; zapis hvezdicky a posun adresy stosb ; zapis hvezdicky a posun adresy
Výsledkem bude očekávaný řetězec, což si ostatně můžeme velmi snadno ověřit na reálném PC nebo v DOSBoxu překladem a spuštěním tohoto příkladu:
BITS 16 ; 16bitovy vystup pro DOS CPU 8086 ; specifikace pouziteho instrukcniho souboru ; ukonceni procesu a navrat do DOSu %macro exit 0 ret %endmacro ; vyprazdneni bufferu klavesnice a cekani na klavesu %macro wait_key 0 xor ax, ax int 0x16 %endmacro ; tisk retezce na obrazovku %macro print 1 mov dx, %1 mov ah, 9 int 0x21 %endmacro ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: print message push cs pop es ; ES:DI obsahuje adresu prvniho znaku ve zprave mov di, message mov al, "*" stosb ; zapis hvezdicky a posun adresy stosb ; zapis hvezdicky a posun adresy stosb ; zapis hvezdicky a posun adresy stosb ; zapis hvezdicky a posun adresy stosb ; zapis hvezdicky a posun adresy print message wait_key exit ; retezec ukonceny znakem $ ; (tato data jsou soucasti vysledneho souboru typu COM) message db "Hello, world!", 0x0d, 0x0a, "$"
16. Vylepšení předchozího příkladu: opakování instrukce STOSB CX-krát
Demonstrační příklad z předchozí kapitoly lze upravit takovým způsobem, aby se instrukce STOSB v kódu vyskytovala pouze jedenkrát. Postačuje před ní vložit prefixovou instrukci REP, která zajistí opakování CX-krát. Celý postup by tedy měl vypadat následovně:
- Do dvojice registrů ES:DI vložíme adresu prvního znaku (tedy znaku „H“)
- Do registru AL vložíme ASCII hodnotu hvězdičky
- (Měl by se nastavit i příznak DF, ten je však při startu korektní)
- Do registru CX vložíme konstantu 5
- Spustíme instrukci REP STOSB, která vlastně CX-krát provede mov ES, AL + inc DI
V assembleru lze tuto posloupnost instrukcí realizovat snadno:
push cs pop es ; ES:DI obsahuje adresu prvniho znaku ve zprave mov di, message mov al, "*" mov cx, 5 rep stosb ; zapis peti hvezdicek
Výsledek bude odpovídat předchozímu příkladu.
Pro úplnost si uveďme výpis zdrojového kódu, který je velmi krátký:
BITS 16 ; 16bitovy vystup pro DOS CPU 8086 ; specifikace pouziteho instrukcniho souboru ; ukonceni procesu a navrat do DOSu %macro exit 0 ret %endmacro ; vyprazdneni bufferu klavesnice a cekani na klavesu %macro wait_key 0 xor ax, ax int 0x16 %endmacro ; tisk retezce na obrazovku %macro print 1 mov dx, %1 mov ah, 9 int 0x21 %endmacro ;----------------------------------------------------------------------------- org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) start: print message push cs pop es ; ES:DI obsahuje adresu prvniho znaku ve zprave mov di, message mov al, "*" mov cx, 5 rep stosb ; zapis peti hvezdicek print message wait_key exit ; retezec ukonceny znakem $ ; (tato data jsou soucasti vysledneho souboru typu COM) message db "Hello, world!", 0x0d, 0x0a, "$"
17. Překlad řetězcových instrukcí s prefixem i bez prefixu
Zajímavé bude zjistit, jak jsou vlastně řetězcové instrukce zakódovány ve strojovém kódu a jak jejich kód ovlivňuje použití prefixu REP. Podívejme se tedy nejdříve na výpis strojového kódu příkladu s opakujícími se instrukcemi STOSB:
22 ;----------------------------------------------------------------------------- 23 org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) 24 25 start: 26 print message 17 00000000 BA[1F00] <1> mov dx, %1 18 00000003 B409 <1> mov ah, 9 19 00000005 CD21 <1> int 0x21 27 28 00000007 0E push cs 29 00000008 07 pop es ; ES:DI obsahuje adresu prvniho znaku ve zprave 30 00000009 BF[1F00] mov di, message 31 32 0000000C B02A mov al, "*" 33 34 0000000E AA stosb ; zapis hvezdicky a posun adresy 35 0000000F AA stosb ; zapis hvezdicky a posun adresy 36 00000010 AA stosb ; zapis hvezdicky a posun adresy 37 00000011 AA stosb ; zapis hvezdicky a posun adresy 38 00000012 AA stosb ; zapis hvezdicky a posun adresy 39 40 print message 17 00000013 BA[1F00] <1> mov dx, %1 18 00000016 B409 <1> mov ah, 9 19 00000018 CD21 <1> int 0x21 41 42 wait_key 11 0000001A 31C0 <1> xor ax, ax 12 0000001C CD16 <1> int 0x16 43 exit 6 0000001E C3 <1> ret 44 45 ; retezec ukonceny znakem $ 46 ; (tato data jsou soucasti vysledneho souboru typu COM) 47 0000001F 48656C6C6F2C20776F- message db "Hello, world!", 0x0d, 0x0a, "$" 47 00000028 726C64210D0A24
Z výpisu je patrné, že tak složitá instrukce, jakou STOSB interně je, je zakódována jen jediným bajtem 0×aa.
Ve druhém kroku se podívejme na příklad s instrukcí REP STOSB:
22 ;----------------------------------------------------------------------------- 23 org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256) 24 25 start: 26 print message 17 00000000 BA[1F00] <1> mov dx, %1 18 00000003 B409 <1> mov ah, 9 19 00000005 CD21 <1> int 0x21 27 28 00000007 0E push cs 29 00000008 07 pop es ; ES:DI obsahuje adresu prvniho znaku ve zprave 30 00000009 BF[1F00] mov di, message 31 32 0000000C B02A mov al, "*" 33 0000000E B90500 mov cx, 5 34 00000011 F3AA rep stosb ; zapis peti hvezdicek 35 36 print message 17 00000013 BA[1F00] <1> mov dx, %1 18 00000016 B409 <1> mov ah, 9 19 00000018 CD21 <1> int 0x21 37 38 wait_key 11 0000001A 31C0 <1> xor ax, ax 12 0000001C CD16 <1> int 0x16 39 exit 6 0000001E C3 <1> ret 40 41 ; retezec ukonceny znakem $ 42 ; (tato data jsou soucasti vysledneho souboru typu COM) 43 0000001F 48656C6C6F2C20776F- message db "Hello, world!", 0x0d, 0x0a, "$" 43 00000028 726C64210D0A24
Z výpisu je patrné použití dvou bajtů s hodnotami 0×f3 0×aa. To opět není mnoho a jen to potvrzuje domněnku, že se mělo jednat o centrální instrukce čipu Intel 8086 (tyto instrukce jsou kratší, než běžné MOV nebo INC).
18. Obsah navazujícího článku
V navazujícím článku dokončíme popis instrukčního souboru mikroprocesorů Intel 8086/8088. Zejména si doplníme informaci o řetězcových a blokových instrukcích (doby jejich provedení, některé optimalizace atd.) a taktéž se zmíníme o způsobu kódování instrukcí do strojového kódu.
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 |
20. Odkazy na Internetu
- The Intel 8088 Architecture and Instruction Set
https://people.ece.ubc.ca/~edc/464/lectures/lec4.pdf - x86 Opcode Structure and Instruction Overview
https://pnx.tf/files/x86_opcode_structure_and_instruction_overview.pdf - x86 instruction listings (Wikipedia)
https://en.wikipedia.org/wiki/X86_instruction_listings - x86 assembly language (Wikipedia)
https://en.wikipedia.org/wiki/X86_assembly_language - Intel Assembler (Cheat sheet)
http://www.jegerlehner.ch/intel/IntelCodeTable.pdf - 25 Microchips That Shook the World
https://spectrum.ieee.org/tech-history/silicon-revolution/25-microchips-that-shook-the-world - Chip Hall of Fame: MOS Technology 6502 Microprocessor
https://spectrum.ieee.org/tech-history/silicon-revolution/chip-hall-of-fame-mos-technology-6502-microprocessor - Chip Hall of Fame: Intel 8088 Microprocessor
https://spectrum.ieee.org/tech-history/silicon-revolution/chip-hall-of-fame-intel-8088-microprocessor - Jak se zrodil procesor?
https://www.root.cz/clanky/jak-se-zrodil-procesor/ - Apple II History Home
http://apple2history.org/ - The 8086/8088 Primer
https://www.stevemorse.org/8086/index.html - flat assembler: Assembly language resources
https://flatassembler.net/ - FASM na Wikipedii
https://en.wikipedia.org/wiki/FASM - Fresh IDE FASM inside
https://fresh.flatassembler.net/ - MS-DOS Version 4.0 Programmer's Reference
https://www.pcjs.org/documents/books/mspl13/msdos/dosref40/ - INT 21 – DOS Function Dispatcher (DOS)
https://www.stanislavs.org/helppc/int21.html - DOS API (Wikipedia)
https://en.wikipedia.org/wiki/DOS_API - Bit banging
https://en.wikipedia.org/wiki/Bit_banging - IBM Basic assembly language and successors (Wikipedia)
https://en.wikipedia.org/wiki/IBM_Basic_assembly_language_and_successors - X86 Assembly/Bootloaders
https://en.wikibooks.org/wiki/X86_Assembly/Bootloaders - Počátky grafiky na PC: grafické karty CGA a Hercules
https://www.root.cz/clanky/pocatky-grafiky-na-pc-graficke-karty-cga-a-hercules/ - Co mají společného Commodore PET/4000, BBC Micro, Amstrad CPC i grafické karty MDA, CGA a Hercules?
https://www.root.cz/clanky/co-maji-spolecneho-commodore-pet-4000-bbc-micro-amstrad-cpc-i-graficke-karty-mda-cga-a-hercules/ - Karta EGA: první použitelná barevná grafika na PC
https://www.root.cz/clanky/karta-ega-prvni-pouzitelna-barevna-grafika-na-pc/ - RGB Classic Games
https://www.classicdosgames.com/ - Turbo Assembler (Wikipedia)
https://en.wikipedia.org/wiki/Turbo_Assembler - Microsoft Macro Assembler
https://en.wikipedia.org/wiki/Microsoft_Macro_Assembler - IBM Personal Computer (Wikipedia)
https://en.wikipedia.org/wiki/IBM_Personal_Computer - Intel 8251
https://en.wikipedia.org/wiki/Intel_8251 - Intel 8253
https://en.wikipedia.org/wiki/Intel_8253 - Intel 8255
https://en.wikipedia.org/wiki/Intel_8255 - Intel 8257
https://en.wikipedia.org/wiki/Intel_8257 - Intel 8259
https://en.wikipedia.org/wiki/Intel_8259 - Support/peripheral/other chips – 6800 family
http://www.cpu-world.com/Support/6800.html - Motorola 6845
http://en.wikipedia.org/wiki/Motorola_6845 - The 6845 Cathode Ray Tube Controller (CRTC)
http://www.tinyvga.com/6845 - CRTC operation
http://www.6502.org/users/andre/hwinfo/crtc/crtc.html - 6845 – Motorola CRT Controller
https://stanislavs.org/helppc/6845.html - The 6845 Cathode Ray Tube Controller (CRTC)
http://www.tinyvga.com/6845 - Motorola 6845 and bitwise graphics
https://retrocomputing.stackexchange.com/questions/10996/motorola-6845-and-bitwise-graphics - IBM Monochrome Display Adapter
http://en.wikipedia.org/wiki/Monochrome_Display_Adapter - Color Graphics Adapter
http://en.wikipedia.org/wiki/Color_Graphics_Adapter - Color Graphics Adapter and the Brown color in IBM 5153 Color Display
https://www.aceinnova.com/en/electronics/cga-and-the-brown-color-in-ibm-5153-color-display/ - The Modern Retrocomputer: An Arduino Driven 6845 CRT Controller
https://hackaday.com/2017/05/14/the-modern-retrocomputer-an-arduino-driven-6845-crt-controller/ - flat assembler: Assembly language resources
https://flatassembler.net/ - FASM na Wikipedii
https://en.wikipedia.org/wiki/FASM - Fresh IDE FASM inside
https://fresh.flatassembler.net/ - MS-DOS Version 4.0 Programmer's Reference
https://www.pcjs.org/documents/books/mspl13/msdos/dosref40/ - INT 21 – DOS Function Dispatcher (DOS)
https://www.stanislavs.org/helppc/int21.html - DOS API (Wikipedia)
https://en.wikipedia.org/wiki/DOS_API - IBM Basic assembly language and successors (Wikipedia)
https://en.wikipedia.org/wiki/IBM_Basic_assembly_language_and_successors - X86 Assembly/Arithmetic
https://en.wikibooks.org/wiki/X86_Assembly/Arithmetic - Art of Assembly – Arithmetic Instructions
http://oopweb.com/Assembly/Documents/ArtOfAssembly/Volume/Chapter6/CH06–2.html - ASM Flags
http://www.cavestory.org/guides/csasm/guide/asm_flags.html - Status Register
https://en.wikipedia.org/wiki/Status_register - Linux assemblers: A comparison of GAS and NASM
http://www.ibm.com/developerworks/library/l-gas-nasm/index.html - Programovani v assembleru na OS Linux
http://www.cs.vsb.cz/grygarek/asm/asmlinux.html - Is it worthwhile to learn x86 assembly language today?
https://www.quora.com/Is-it-worthwhile-to-learn-x86-assembly-language-today?share=1 - Why Learn Assembly Language?
http://www.codeproject.com/Articles/89460/Why-Learn-Assembly-Language - Is Assembly still relevant?
http://programmers.stackexchange.com/questions/95836/is-assembly-still-relevant - Why Learning Assembly Language Is Still a Good Idea
http://www.onlamp.com/pub/a/onlamp/2004/05/06/writegreatcode.html - Assembly language today
http://beust.com/weblog/2004/06/23/assembly-language-today/ - Assembler: Význam assembleru dnes
http://www.builder.cz/rubriky/assembler/vyznam-assembleru-dnes-155960cz - Programming from the Ground Up Book – Summary
http://savannah.nongnu.org/projects/pgubook/ - DOSBox
https://www.dosbox.com/ - The C Programming Language
https://en.wikipedia.org/wiki/The_C_Programming_Language - Hercules Graphics Card (HCG)
https://en.wikipedia.org/wiki/Hercules_Graphics_Card - Complete 8086 instruction set
https://content.ctcd.edu/courses/cosc2325/m22/docs/emu8086ins.pdf - Complete 8086 instruction set
https://yassinebridi.github.io/asm-docs/8086_instruction_set.html - 8088 MPH by Hornet + CRTC + DESiRE (final version)
https://www.youtube.com/watch?v=hNRO7lno_DM - Area 5150 by CRTC & Hornet (Party Version) / IBM PC+CGA Demo, Hardware Capture
https://www.youtube.com/watch?v=fWDxdoRTZPc - 80×86 Integer Instruction Set Timings (8088 – Pentium)
http://aturing.umcs.maine.edu/~meadow/courses/cos335/80×86-Integer-Instruction-Set-Clocks.pdf - Colour Graphics Adapter: Notes
https://www.seasip.info/VintagePC/cga.html - Restoring A Vintage CGA Card With Homebrew HASL
https://hackaday.com/2024/06/12/restoring-a-vintage-cga-card-with-homebrew-hasl/ - Demoing An 8088
https://hackaday.com/2015/04/10/demoing-an-8088/ - Video Memory Layouts
http://www.techhelpmanual.com/89-video_memory_layouts.html - Screen Attributes
http://www.techhelpmanual.com/87-screen_attributes.html - IBM PC Family – BIOS Video Modes
https://www.minuszerodegrees.net/video/bios_video_modes.htm - EGA Functions
https://cosmodoc.org/topics/ega-functions/#the-hierarchy-of-the-ega - Why the EGA can only use 16 of its 64 colours in 200-line modes
https://www.reenigne.org/blog/why-the-ega-can-only-use-16-of-its-64-colours-in-200-line-modes/ - How 16 colors saved PC gaming – the story of EGA graphics
https://www.custompc.com/retro-tech/ega-graphics - List of 16-bit computer color palettes
https://en.wikipedia.org/wiki/List_of16-bit_computer_color_palettes - Why were those colors chosen to be the default palette for 256-color VGA?
https://retrocomputing.stackexchange.com/questions/27994/why-were-those-colors-chosen-to-be-the-default-palette-for-256-color-vga - VGA Color Palettes
https://www.fountainware.com/EXPL/vga_color_palettes.htm - Hardware Level VGA and SVGA Video Programming Information Page
http://www.osdever.net/FreeVGA/vga/vga.htm - Hardware Level VGA and SVGA Video Programming Information Page – sequencer
http://www.osdever.net/FreeVGA/vga/seqreg.htm - VGA Basics
http://www.brackeen.com/vga/basics.html - Introduction to VGA Mode ‚X‘
https://web.archive.org/web/20160414072210/http://fly.srk.fer.hr/GDM/articles/vgamodex/vgamx1.html - VGA Mode-X
https://web.archive.org/web/20070123192523/http://www.gamedev.net/reference/articles/article356.asp - Mode-X: 256-Color VGA Magic
https://downloads.gamedev.net/pdf/gpbb/gpbb47.pdf - Instruction Format in 8086 Microprocessor
https://www.includehelp.com/embedded-system/instruction-format-in-8086-microprocessor.aspx - How to use „AND,“ „OR,“ and „XOR“ modes for VGA Drawing
https://retrocomputing.stackexchange.com/questions/21936/how-to-use-and-or-and-xor-modes-for-vga-drawing - VGA Hardware
https://wiki.osdev.org/VGA_Hardware - Programmer's Guide to Yamaha YMF 262/OPL3 FM Music Synthesizer
https://moddingwiki.shikadi.net/wiki/OPL_chip - Does anybody understand how OPL2 percussion mode works?
https://forum.vcfed.org/index.php?threads/does-anybody-understand-how-opl2-percussion-mode-works.60925/ - Yamaha YMF262 OPL3 music – MoonDriver for OPL3 DEMO [Oscilloscope View]
https://www.youtube.com/watch?v=a7I-QmrkAak - Yamaha OPL vs OPL2 vs OPL3 comparison
https://www.youtube.com/watch?v=5knetge5Gs0 - OPL3 Music Crockett's Theme
https://www.youtube.com/watch?v=HXS008pkgSQ - Bad Apple (Adlib Tracker – OPL3)
https://www.youtube.com/watch?v=2lEPH6Y3Luo - FM Synthesis Chips, Codecs and DACs
https://www.dosdays.co.uk/topics/fm_synthesizers.php