Jednotliva zadani testu z 36SOJ v *.doc: Test_1.doc Test_2.doc Test_3.doc Test_4.doc Test_5.doc
Sloucena zadani testu z 36SOJ k tisku v *.ps: Test_1.ps Test_2.ps Test_3.ps Test_4.ps Test_5.ps
Spravne odpovedi a zduvodneni odpovedi k testum z 36SOJ: results.txt

STROJOVE ORIENTOVANE JAZYKY

There are 10 types of people in the world. Those who understand binary and those who don't.
Pro inspiraci se muzete podivat na stranky SOJ s resenymi ulohami z lonskeho roku.

Cviceni_1 Cviceni_2 Cviceni_3 Cviceni_4 Cviceni_5 Cviceni_6 Cviceni_7
Cviceni_8 Cviceni_9 Cviceni_10 Cviceni_11 Cviceni_12 Cviceni_13 Cviceni_14
Uloha_1
( segmenty, pristup do pameti, vypis na obrazovku )
Uloha_2
( numericke operace, pole, vstup z klavesnice )
Uloha_3
( textovy mod, hardwarove preruseni, asynchronni udalosti )
Uloha_4
( graficky mod, generator palety, konvolutorni a xorovane textury )
Uloha_5
( alokace pameti, prikazova radka, cteni ze souboru, mys, nasvecovani )
Semestralni_prace
Hodnoceni

Ukazky

Cviceni:

Pavel Cimbal (mail: xcimbal@quick.cz icq: 51599423)

Ctvrtek 7:30 - 9:00 mistnost K310
Ctvrtek 9:15 - 10:45 mistnost K310
Ctvrtek 11:00 - 12:30 mistnost K310
Ctvrtek 12:45 - 14:15 mistnost K310

Nektere z uloh na techto strankach jsou zavazne i pro dalsi cviceni SOJ
(informace poda konkretni vyucujici)


Napln semestru:

Cviceni se stridaji v rytmu laboratorni (ladeni programu u pocitacu) a seminarni (vice teoreticka). Naplni cviceni u pocitacu bude vypracovavani uloh, resp. semestralni prace ve zbytku casu. Odladeny program-uloha (fungujici spustitelny soubor spolu s rozumne okomentovanym zdrojovym textem) se odevzdava bud na konci laboratorniho cviceni, ve kterem byl zadan, nebo na pristim laboratornim cviceni. Od tretiho tydne se na uvod kazdeho seminarniho (nebo laboratorniho) cviceni pise kratky test.

Do konce rijna si take kazdy student vybere zadani semestralni prace (bud nektere z nabidky, nebo sve vlastni, pokud mu bude odsouhlaseno). Semestralni prace se odevzdava v poslednich dvou tydnech semestru, a je tvorena fungujicim spustitelnym programem se zdrojovym textem spolu s referatem (obsahuje zadani, navrzene reseni a pripadne popis nekterych implementacnich zajimavosti). Zazipovanou semestralni praci (spustitelny program, zdrojovy text, pripadne referat, pokud je v elektronicke forme) poslete po odevzdani mailem svemu cvicicimu.

Semestralni praci musite odevzdat a predvest osobne. Pokud jste ale pokrocili coderi, a seminarni cviceni i ulohy by pro vas byly ponizujici, muzete se s nami domluvit i na nejake vlastni individualni praci, namisto uloh, testu a semestralky.

Hodnoceni:

Hodnoceni je formou klasifikovaneho zapoctu. Pro ziskani zapoctu je treba odevzdat vsech 5 uloh a semestralni praci, znamku pak urcuje kvalita semestralky a body z peti testu, psanych v prubehu semestru. Z testu lze celkem ziskat 0..25 bodu, uroven semestralni prace je ohodnocena procenty 0..100 (zde se prihlizi i k pracnosti, takze napr. rozsahly zdrojovy text, z nejakeho duvodu nahle nefungujici, muze dostat klidne i 40, semestralka, co splnuje zadani, 75, vyssi ohodnoceni pak umerne libivosti zpracovani).

skore = 2 * soucet_bodu_z_testu + uroven_semestralni_prace / 2

75..100 = vyborne, 60..74 = velmi dobre, 40..59 = dobre, 0..39 nebo neodevzdana uloha = nevyhovel

Vyslednou znamku muze dale zlepsit napr. plus za odevzdani kratsiho reseni ulohy, nez bylo ukazkove, napsani semestralni prace pod neDOSove prostredi, vymysleni nejake vychytrale rutiny a podobne.


Cviceni 1 (laboratorni):

Pro psani v assembleru pouzivame assemblery, ktere zdrojovy text prelozi bud do moduloveho souboru (z ktereho pak linkerem vytvorime spustitelny soubor), nebo primo do binarni spustitelne podoby. Obvykle se pouziva bud MASM (od Microsoftu, se vsim specifickym, co z toho vyplyva), TASM (rychly, soucasti borlandskych baliku, bohuzel syntakticky misty nelogicky - dedictvi od MASMu, take potrebuje linker) nebo NASM (freewarovy, syntakticky cisty a logicky, nepotrebuje linker, bohuzel ale pomalejsi). Protoze verze 0.98 obsahuje nektere chyby, pouzivejte radsi starsi verzi nasm097.zip. K NASMu take existuje pomerne sugestivne psany help nasmdoc.ps.

Rodina assembleru, odvozena od MASMu, je starsi, a z historickych duvodu obsahuje mnoho matoucich konstrukci, ze kterych neni zcela zrejmy vztah zdrojoveho textu ke generovanemu kodu. Proto je pro zacatecnika snazsi, kdyz zacne psat v NASMu. Pokud si potrebujete osvezit MASMovsky styl syntaxe, muzete pouzit elektronickou verzi knihy The Art of Assembly Language Programming . Dalsi hezky webovy tutorial je Carteruv PC Assembly Tutorial . Pro rychlou pomoc pri psani programu existuje take nekolik elektronickych manualu, jako techhelp.zip (vse je k dispozici i na CSLABu, doufam), SYSMAN nebo ATHELP. Pro prehled o obsazeni V/V prostoru PC je k dispozici jeho temer vycerpavajici popis ports.zip. Pokud vas zajima, jake rutiny se mohou nachazet na prerusovacich vektorech, spolu s jejich detailnim popisem, stahnete si seznam preruseni od Ralfa Browna rbint.tgz. Popis instrukcni sady procesoru i386 naleznete v druhem dile dokumentu The IA-32 Intel Architecture Software Developer's Manual, ale ostatni dily jsou take velmi zajimave.

Programy muzete vytvaret bud pro model "small" jako *.exe soubory, nebo pro model "tiny" jako soubory *.com. Prekladace si muzete otestovat na nasledujicich prikladech:

TASM - vytvoreni EXE souboru:
Stahnete si soubor tasmexe.asm, a ten prelozte pomoci:

tasm tasmexe.asm
tlink tasmexe.obj

TASM - vytvoreni COM souboru:
Stahnete si soubor tasmcom.asm, a ten prelozte pomoci:

tasm tasmcom.asm
tlink /t tasmcom.obj

NASM - vytvoreni COM souboru:
Stahnete si soubor nasmcom.asm, a ten prelozte pomoci:

nasm nasmcom.asm -o nasmcom.com

Ke zjistovani chyb v prelozenych spustitelnych programech muzete pouzit borlandsky TD, pripadne k diassemblovani a upravam utilitu HIEW. V pripade nouze muzete vkladat pomocne ladici vypisy. Pro snazsi zacatek psani programu jsou zde sablony pro vytvoreni souboru com a pro vytvoreni souboru exe (oba pro TASM). Take muzete vyuzit davky pro preklad a linkovani mkcom.bat a mkexe.bat (opet TASM).

Na cviceni si nejdriv vyzkousejte, jestli jste schopni prelozit zdrojovy text, a odstranit pripadne problemy. Pak reste nasledujici ulohu:

Uloha 1:

A) [nase reseni - 22 bytu]
Pripravte si podprogram, ktery bude umet nasledujici vec:

Vstup:
Registr AX - jeho obsah je povazovan za unsigned sestnactibitove cislo.
Po zavolani:
Na obrazovce bude na aktualni pozici kurzoru hexadecimalne vypsane toto cislo (tedy 4 znaky, pro cislice vetsi nez 9 pouzijte velka pismena abecedy).

B) [nase reseni - 73 bytu]
Za pouziti podprogramu A) napiste program, ktery na obrazovku za sebou vypise obsah prvnich 100 polozek z tabulky prerusovacich vektoru.

Vstup:
Aktualni obsah tabulky prerusovacich vektoru.
Vystup:
Na obrazovce bude vypsano 100 polozek ve tvaru segment:offset:linearni_adresamezera, odpovidajicich aktualnimu obsahu tabulky prerusovacich vektoru.
Testovaci screenshot:

Hodnoty jednotlivych polozek se mohou lisit podle verze operacniho systemu, aktualne beziciho softwaru nebo hardwarove konfigurace pocitace.

Poznamka: Tabulka prerusovacich vektoru obsahuje 256 ctyrbytovych polozek a nachazi se na samem pocatku pameti, tedy linearni adrese 00000h. Je pristupna napr. po nastaveni segmentoveho registru na 0000h pres offsety v rozsahu 0000h..03ffh. Kazda ctyrbytova polozka pak obsahuje offset (nizsi dva byty) a segment (vyssi dva byty) cilove adresy, kam preruseni skace. Nas zajima jak segment, tak offset, tak i vysledna linearni adresa (16*segment+offset), a proto kazdou polozku vypiseme jako retezec SSSS:OOOO:LLLLLmezera.

Hotovou ulohu muzete predvest bud hned, nebo na pristim laboratornim cviceni (za 14 dnu). That's all. ;) Vzdy po uplynuti teto lhuty se dozvite, jak mela uloha vypadat. Komu se povede napsat kratsi kod, nez bude nas vzorovy (na byty), ziska vsestranne vyuzitelne plus. Pak mu mohou byt prominuty treba nepovedene testy, nebo ma sanci na lepsi znamku na konci semestru.

FAQ 1:

Q: Proc musime psat v assembleru, kdyz je to hrozne nepohodlne, snadno se tam udela chyba, a neni to pak ani prenositelne?
A: Protoze CPU vykonava strojovy kod, a pokud chceme jeho moznosti efektivne vyuzit, meli bychom pripravovat programy primo v nem. I sebemodernejsi kompilator totiz zvlada jen nektere zakladni optimalizace, a vysledek je pak n-nasobne delsi a pomalejsi, nez promyslena strojova rutina. Nejkratsi, nejhezci a nejrychlejsi program lze napsat pouze v assembleru, podivejte se na asmrulez.asm pro NASM, nebo si ho stahnete prelozeny asmrulez.zip, program se ovlada pomoci shiftu. ;)


Cviceni 2 (teoreticke):

Ciselne kody v pocitacich, zpusob prace s cisly v ruznych kodech, aritmetika s cisly, ktera se nevejdou do registru 80x86, vstup a vystup pomoci funkci DOSu. Aritmetika v plovouci radove carce a souvisejici pojmy. Muzete si take predem rozmyslet priklad, ktery se bude resit u tabule:

Priklad: Napiste program, ktery cte z klavesnice zadavane znaky. Vstupujici posloupnost nul a jednicek bude chapana jako binarni cislo, ktere se prepisuje na obrazovku. Po stisku kterekoliv jine klavesy (jine nez 0 nebo 1) se pak vypise dekadicky. Pokud zadna nula ani jednicka nevstoupi, a bude rovnou stisknuta jina klavesa, vypise se 0. Vkladany binarni retezec muze obsahovat az 332 bitu, tedy odpovidajici dekadicke cislo bude maximalne 100 ciferne.

Program lze napsat na 53 bytu, resp. 49, pokud spolehame na vynulovani registru pri zavedeni *.com do pameti. Napocitavani dekadickeho vyjadreni se provadi po vstupu kazdeho bitu, a sice jako dvojnasobek predchoziho vyjadreni plus hodnota nacteneho bitu. Pole s dekadickymi ciframi je alokovano atypicky na zasobniku, a jeho prevod na ASCII kody se provadi az pri vypisu. Zde je zdrojovy text programu bconvert.asm.


Cviceni 3 (laboratorni):

Odevzdani ulohy 1 z prvniho cviceni a zadani ulohy 2. Take se pise prvni z testu.

Test 1:

V testu dostane kazdy 5 otazek, kde ke kazde vzdy budou 4 moznosti a), b) c), d), z toho jen jedina zcela spravna. Na vypracovani testu je zpravidla 15 minut. Jako literatura je povoleno v podstate cokoliv. Jednotlive otazky se budou tykat:

- zakladni rysy i8086 (kolikabitovy a proc, adresove prostory, sada registru, komunikace s periferiemi)
- segmenty a offsety (jak urcuji vyslednou adresu, k cemu slouzi, v jakych muze byt adresa rozsazich)
- soubory *.exe a *.com (cim se lisi, jak se pisi, zpusoby jejich ukoncovani)
- podprogramy a prace s poli (druhy instrukci CALL a RET, pouziti instrukci pro praci s retezci)
- jednoducha nekolikaradkova rutina (poznat, co dela, a jestli je napsana spravne)

Uloha 2:

[nase reseni - 64 bytu]
Pripravte si program, ktery bude umet nasledujici vec:

Vstup:
Na klavesnici zadavana cisla.
Cinnost:
Na obrazovku se vypise znak '>' a program ceka na stisk klaves. Pokud slo o cislice '0'..'9', vypisi se na obrazovku. Pokud slo o jinou hlavesu nez '0'..'9', vypise se znak '=' a za nej hexadecimalni tvar takto nacteneho dekadickeho cisla a program skonci. Program musi byt schopen prevest az 1000 ciferne dekadicke cislo, proto si pro hexadecimalni tvar cisla rezervujte alespon 832 cifer. Vypsany hexadecimalni string muze mit konstantni delku (tedy muze obsahovat pocatecni nuly).
Testovaci screenshot:

Na obrazku vidite vysledek po zadani pomerne velikeho dekadickeho cisla 0123456789..9, ktere uloha prevedla na hexadecimalni tvar. Protoze tolik cifer kalkulacky zpravidla prevadet neumeji, pouzil jsem ke kontrole program bconvert.com (hexadecimalni vystup ulohy 2 jsem binarne natukal coby jeho vstup), ktery jsem dal k dispozici na minulem cviceni.

Poznamka: V praxi se casto vyskytuji pripady, kdy je treba prevest dlouhe dekadicke cislo do binarni podoby, a neztratit presnost. Pak nezbyva nez implementovat algoritmus pro prevod mezi soustavami nad velkym binarnim vektorem. Zde se primo nabizi nasobici algoritmus, takze staci zhotovit rutinu pro nasobeni dlouheho binarniho cisla deseti, a rutinu pro pricteni cisla v rozsahu 0..9 k tomuto binarnimu cislu. Takove pole si tedy zpocatku musime vynulovat, pote pri kazde zadane cifre jeho obsah vynasobme deseti a cifru pricteme. Pri skonceni zadavani pak muzeme takovy vektor jednoduse hexadecimalne vypsat za pouziti podprogramu z ulohy 1. Algoritmy pro postupne nasobeni a scitani dlouhych cisel naleznete, pokud si je nepamatujete, v ucebnici matematiky pro prvni stupen zakladni skoly ;). Ulohu lze resit i jinak, napr. realizaci nasobiciho a scitaciho algoritmu v jedinem pruchodu, a podobne. Zkraceni lze dosahnout take rozdelenim binarniho mezitvaru na ctyrbitove nibbly odpovidajici primo hexadecimalnim cifram a podobne.

Hotovou ulohu muzete predvest bud hned, nebo na pristim laboratornim cviceni (za 14 dnu). Az dobehne termin pro dalkare k vypracovani uloh 1 a 2, dozvite se, jak mela uloha vypadat. Komu se povede napsat kratsi kod, nez bude nas vzorovy (na byty), ziska vsestranne vyuzitelne plus. Pak mu mohou byt prominuty treba nepovedene testy, nebo ma sanci na lepsi znamku na konci semestru.

Hotova uloha se odevzdava na pristim laboratornim cviceni (za 14 dni).


Cviceni 4 (teoreticke):

Mapa pametoveho a V/V prostoru PC, softwarove a hardwarove preruseni. Zpusob programovani obsluznych rutin, prace s radicem preruseni. Take byste si meli vybrat semestralni praci z uvedene nabidky.

Priklad: Ukazeme si, jak napsat jednoduchy emulator terminalu, za pouziti znalosti o funkci hardwaroveho preruseni od serioveho portu. Terminal pri stisku klavesy posila znak na seriovou linku (do modemu, linuxoveho serveru ci jednoduse do druheho PC, kde bude bezet take tento program - jejich propojeni pak bude prekrizenym tzv. nullmodem kabelem). Take chceme, aby byly prichozi znaky bufferovany (pokud se nestihaji z nejakeho duvodu vypisovat, neztrati se, pokud ovsem vystaci buffer). Program se ukonci stiskem klavesy Esc. Zde je zdrojovy text programu pro TASM smallcom.asm. Netvrdim, ze je nejoptimalnejsi (126 bytu), uz ma svych hezkych par let, ale zatim jsem nevidel nic podobne kratkeho.

FAQ 2:

Q: Kdyz predvadim ulohu, ukaze se DOSove okenko s vystupem jen na chvilku, a kdyz vystup presmeruji do souboru stylem muj_prog.com >vystup.txt, obsahuje pak soubor vystup.txt po zobrazeni v notepadu nejake divne znaky, ktere urcite program neprodukoval.
A: Bud si nastavte vlastnosti DOSPromptu tak, aby se okno po skonceni ulohy hned nezaviralo, nebo jednoduse pridejte tesne pred ukonceni programu instrukce MOV AH,08h INT 21h, ktere zajisti cekani na stisk klavesy. Spatne zobrazovane znaky v notepadu jsou zpusobene praktikami nejmenovane redmondske firmy, ktera si vyznam ridicich znaku 0ah (LF) a 0dh (CR) vyklada po svem. Pro zalomeni radku proto pouzivejte vyhradne sekvenci (CR)(LF), sekvence (LF)(CR) nebude podobnymi editory zobrazena spravne.


Cviceni 5 (laboratorni):

Odevzdani ulohy 2 ze tretiho cviceni a zadani ulohy 3. Take se pise druhy z testu. Koho zaujaly moznosti celociselne aritmetiky, muze se podivat, jak napocitat tabulku funkce sinus, a to jen za pouziti nasobeni a scitani. Vysledny kod sine.asm ma jen 26 bytu.

Test 2:

V testu dostane kazdy 5 otazek, kde ke kazde vzdy budou 4 moznosti a), b) c), d), z toho jedina spravna. Na vypracovani testu je 15 minut. Jako literatura je povoleno v podstate cokoliv. Jednotlive otazky se budou tykat:

- segmenty a offsety (jak urcuji vyslednou fyzickou adresu, jake instrukce pouzivaji ktere segmenty)
- rotace a aritmetika (jak souvisi typy shiftu a rotaci s aritmetickymi ukony a doplnkovym kodem)
- nasobeni a deleni (jak a k cemu se daji vyuzit instrukce pro nasobeni a deleni)
- doplnkovy kod (pouziti doplnkoveho kodu, jak je potom nastaveno carry)
- jednoducha nekolikaradkova obsluha preruseni (poznat, co dela, a jestli je napsana spravne)

Uloha 3:

[nase reseni - 117 bytu]
Napiste program, ktery bude umet nasledujici vec:

Vstup:
Stisky klaves na klavesnici.
Cinnost:
Program po spusteni zjisti aktualni zobrazovaci rezim, zapamatuje si jej, a prepne do sestnactibarevneho textoveho rezimu 40x25 znaku. Dale si program zapamatuje hodnotu na prerusovacim vektoru pro IRQ1, a presmeruje vektor na vlastni obsluznou rutinu. V ramci obsluhy se vzdy pri prichodu preruseni cely obsah obrazovky odroluje o 4 znaky vlevo, a do praveho dolniho rohu se barevne hexadecimalne vypise scancode, prevzaty od klavesnice nactenim portu 60h. Format vypisu je tvoren ctyrmi ASCII znaky, a sice znakem 0b3h (svisla oddelovaci cara), dvema hexa ciframi vyjadrujicimi nactenou hodnotu scancodu, a nakonec znak sipky. Sipka smeruje pro pripad scancodu 0..127 dolu (kod 019h), a pro scancody 128..255 nahoru (kod 018h). Barvu papiru urcuji posledni tri bity scancodu. Barva inkoustu svisle oddelovaci cary je stejna jako barva papiru pri minulem vypisu, a pro dalsi znaky je pak dana komplementem poslednich ctyr bitu nacteneho scancode. Po stisku klavesy Esc program vrati zpet puvodni hodnotu vektoru, prepne do puvodniho grafickeho modu, a ukonci se.
Testovaci screenshot:

Nejprve jsem vypnul NumLock, a pak spustil program. Pri spusteni programu jsem stisknul Enter trosku lezerneji, takze k jeho uvolneni doslo az pri behu programu a proto obsluha preruseni zareagovala vypsanim scancodu 09ch "uvolneni Enter" v prislusnych barvach. Pak jsem stiskl olivovy Insert, Mezernik, vytukal slovo coin a stiskl Esc. Pred ukoncenim Esc vypadala obrazovka tak, jak vidite na obrazku vyse. Protoze jsou barvy textoveho rezimu nastavovany BIOSem karty pri jeho inicializaci, mohou se jejich odstiny (ne ale barvy samotne) mirne lisit.

Poznamka: Aktualni graficky mod zjistime napr. funkci BIOSu MOV AH,0Fh; INT 10h, kde je cislo modu vraceno v registru AL. Sestnactibarevny textovy mod 40x25 znaku ma cislo 1 a zapneme jej napr. pomoci MOV AL,1; MOV AH,00h; INT 10h ;). Prerusovaci vektor pro IRQ1 je standardne mapovan na INT9, takze jde o nacteni a prenastaveni polozky s indexem 9 v tabulce vektoru. Je treba zajistit, aby prenastaveni probehlo okamzite a zadne preruseni nebylo vyvolano nad neuplne nastavenym vektorem - to zajistime napr. vyuzitim funkci DOSu pro cteni a nastavovani vektoru (funkce 035h a 025h), nebo zapisem celeho dvojslova naraz (pozor, to lze ale az od 386+), a nebo globalnim zakazanim preruseni (CLI a STI) nebo jeho maskovanim (port 021h) po dobu modifikace. Obsluha preruseni nesmi zmenit obsah zadneho registru z prave preruseneho programu (protoze nevime, jaky bezici kod byl prave prerusen, musi byt zkratka po jejim skonceni vsechny registry v puvodnim stavu), a nesmi zrovnatak spolehat na konkretni hodnotu v zadnem registru, s vyjimkou CS:IP (ktere byly nahrany pri vyvolani obsluhy z vektoru a jedine jsou spravne). Proto musi obsluha s hlavnim programem, pokud to je nutne (napr. zde znameni pro ukonceni programu), komunikovat vyhradne pres zvolene misto v pameti, ktere je nejsnazsi umistit nekam do codesegmentu (a na promennou pristupovat ve stylu MOV AL,[CS:promenna], coz nam ale v *.com nijak zvlast nevadi). Obsluha nesmi ani volat zadnou funkci DOSu mensi nez 0ch (tyto funkce vstupuji do nereentrantni sekce na INT28h, kde se kod v dobe prichodu IRQ casto nachazi), a proto budeme znaky vypisovat primym zapisem do VideoRAM textoveho rezimu, viz FAQ nize. Odrolovani o 4 znakove pozice provedeme napr. jako presunuti bloku 2*(40*25-4) bytu z VideoRAM, zacinajiciho na offsetu 8, na pocatek videoram. Byvalou obsluhu, na kterou puvodne ukazoval vektor, nijak volat nebudeme (neni to zadouci, znaky si totiz zpracovavame sami a z BIOSu by je tak jako tak po dobu behu nikdo neodebiral, takze by zacal pipat kvuli preplneni sve klavesove fronty). Samotny scancode lze ziskat tak, aby byl platny, jen v ramci obsluhy IRQ1 (proto preruseni vyuzivame), a sice nactenim portu 60h. Jakykoli dalsi samanismus je v dobe emulovanych DOSPromptu silne nezadouci (nenechte se zmast SYSManem nebo AT-Helpem). Co mozna nejblize ke konci obsluhy (za dodrzeni vyse uvedenych omezeni) pak odhlasime radici provedeni preruseni pomoci MOV AL,20h; OUT 20h, AL. Z obsluhy se vracime pomoci instrukce IRET. Pokud pouzivame instrukce pro praci s retezci, je nutne si uvedomit, ze pri vstupu do obsluzne rutiny lze spolehat pouze na hodnoty v CS:IP, a tedy ani obsah FLAGS neni definovan.

Hotova uloha se odevzdava na pristim laboratornim cviceni (za 14 dni).

FAQ 3:

Q: Jak se nastavuje barva znaku v textovem rezimu, a jak to mam udelat pres sluzby DOSu nebo BIOSu, kdyz je v obsluze klavesnicoveho preruseni nemohu volat?
A: Pomoci sluzeb DOSu a BIOSu se obvykle atributy ani nenastavuji. Videopamet vetsiny textovych rezimu (napr. rezimu cislo 3, pokud jsme v jinem, prepneme do nej MOV AX,3; INT 10h) je na fyzicke adrese 0b8000h. Obvykle k ni pristupujeme tak, ze si registr ES nastavime na 0b800h, a pomoci registru DI a instrukci STOSB nebo STOSW do pameti zapisujeme. Kazdy zobrazitelny znak v tomto modu obsazuje ve videopameti 2 sousedni byty. V prvnim je primo jeho ASCII kod, v druhem zakodovana jeho barva. Znaky jsou ve videoram usporadany zleva doprava a pak po radcich dolu, takze napr. tretimu znaku ve ctvrtem radku prislusi bytova dvojice na offsetu 484 od zacatku videopameti. Barva znaku je kodovana v druhem bytu zpusobem [F,Rp,Gp,Bp,H,Ri,Gi,Bi], kde bit F zapina blikani, bit H zvyseny jas inkoustu, a RGB jsou slozky barvy bud papiru (s indexem p) nebo inkoustu (s indexem i).


Cviceni 6 (teoreticke):

Rezimy grafickeho adapteru a prace s grafikou pomoci primeho pristupu do videopameti. Zpusoby prace s paletami, generatory palet. Princip stinove videopameti.

Priklad: Ukazeme si, jak nagenerovat a zobrazit baletu pro rezim 320x200. Rutina generuje paletu 16 zakladnich sytych odstinu, ktere pak linearne v sestnacti krocich zesvetluje az k jasne bile. Takova paleta se hodi napr. pro texturovani sestnactibarevnou texturou, ktera pokryva nasvecovane 3D teleso. Pak textura urci spodni 4 bity indexu barvy, a jas horni ctyri bity. Zde je zdrojovy text programu pro NASM lastpall.asm. Rutina pomoci generatoru pseudonahodnych cisel urci krok v rozsahu 1 az 4, a ten pak odcita od plneho vybuzeni 63 slozky R, G nebo B dane barvy. Postupne tak napocita hodnotu vsech 16 jasu slozky barvy, a po trech opakovanich vnitrniho cyklu jsou tak urceny jasy jedne z 16 sytych barev. Protoze systych barev je 16, povede se cyklus 48 krat. Polozky se ukladaji do pomocneho pole, v poradi, v jakem se pak posilaji do VGA adapteru. Protoze index nastavovane barvy se po vyslani 3 bytu (R, G a B) automaticky inkrementuje, muzeme po nastaveni indexu 0 vyslat na port 03c9h vsech 768 bajtu instrukci REP OUTSB (dostupna od i80286).


Cviceni 7 (laboratorni):

Odevzdani ulohy 3 z pateho cviceni a zadani ulohy 4. Take se pise treti z testu.

Test 3:

V testu dostane kazdy 5 otazek, kde ke kazde vzdy budou 4 moznosti a), b) c), d), z toho jedina spravna. Na vypracovani testu je 15 minut. Jako literatura je povoleno v podstate cokoliv. Jednotlive otazky se budou tykat:

- mapovani videopameti (umisteni v adresovem prostoru a jeji velikost, pro textovy rezim 03h a graficky 13h)
- vyznam bytu videopameti (jak urcuji zobrazeny znak, barvu, nebo pixel v grafickem modu 320x200)
- techniky prace s videoram (synchronizace s paprskem, stinova videoram)
- paleta (nastavovani palety, mozne rozsahy RGB slozek jednotlivych barev)
- jednoducha rutina zapisujici do videoram (poznat, co dela, a jestli je napsana spravne)

Uloha 4:

[nase reseni - 128 bytu]

Napiste program, ktery bude umet nasledujici vec:

Vstup:
Stisk libovolne klavesy program ukonci (s navratem do puvodniho rezimu graficke karty).
Cinnost:

1) Program zinicializuje graficky rezim 320x200 256 barev (13h) a nastavi linearni VGA paletu tmavocervena-fialova-sedomodra-bezova-zluta. Slozky R a G se v palete meni linearne od pocatecni po koncovou hodnotu, slozka B pak kvadraticky. Podivejte se do poznamky na podrobny popis generovani palety.

2) Pomoci generatoru pseudonahodnych cisel vyplnte celou videoRAM konvolutorni texturou. Podrobny popis generatoru je uveden take v poznamce.

3) Urcite oblasti obrazu, vymezene hyperbolickymi krivkami, prekryjte texturou s ctvercovite fraktalovym ornamentem. Popis algoritmu je opet uveden v poznamce.

Testovaci screenshot:

Po spusteni programu byste meli videt zhruba tento obrazek.

Poznamka: Akcoli se zda byt uloha velmi tezkou, opak je pravdou. Pozorne si prectete nasledujici tri odstavce, a zjistite, ze programovani v assembleru skyta narozdil od vyssich programovacich jazyku v podstate neomezene moznosti optimalni implementace cehokoliv:

1) Paleta VGA definuje jednotlive barvy pomoci slozek RGB, kde je kazda z nich vyjadrena sestibitovym cislem. Nastaveni jednotlivych barev se provadi tak, ze na port 03c8h outneme index vybrane barvy, a na port 03c9h pak jeji R, G a B slozky (tri outy za sebou). Pokud chceme nastavit i nasledujici barvu, muzeme vyuzit toho, ze se index automaticky vzdy po zapsani vsech tri slozek zinkrementuje, a tedy rovnou outovat dalsi tri slozky pro pristi barvu. Jina moznost je pouzit BIOSove sluzby cislo 1010h na Int 10h. Pozor ale, BIOS po dobu nastavovani na urcitou dobu zhasne obraz, coz muze pri castych zmenach palety pusobit rusive. Protoze maji slozky palety jen sestibitovy rozsah, kdezto paleta obsahuje 256 barev, je nutne pri napocitavani slozek pouzivat necela cisla. Konkretne v nasi uloze je [R,G,B] pocatecni tmavocervene barvy (s indexem 0) [24,0,0] a [R,G,B] koncove zlute barvy (index 255) [63,63,36]. Pokud se ma cervena a zelena slozka mezi pocatecni a koncovou hodnotou menit linearne, znamena to, ze prvni barvu nastavime jako [R,G,B]=[24,0,0], a u kazde dalsi pak zvysime slozku R o (64-24)/256 a slozku G o 64/256 (uvazoval jsem zde hypotetickou barvu [64,64,36] za koncem palety pro urceni nejvetsiho pouzitelneho prirustku). S temito zlomky pak pocitame jednoduse tak, ze jen scitame citatele (opakovane do sestnactibitoveho registru pricitame 40 resp. 64), a zohledneni zlomku provedeme vydelenim tohoto kumulativniho souctu cislem 256 (tedy vezmeme hodnotu z vyssiho bytu registru - podivejte se, v jakych registrech pozaduje RGB slozky BIOSova sluzba 1010h, a zda toho nejde vyuzit ;). Linearne se menici paleta je ovsem ponekud fadni, a generuje jen dva zakladni odstiny a prechod mezi nimi. Skutecne zajimave palety vyzaduji alespon v jedne ze slozek nemonotonni prubeh - treba kvadratickou funkci. Protoze ma parabola na svych krajich pomerne ostre stoupani, byla zvolena slozka B, tedy jasove nejmene vyznamna slozka, kde tyto pripadne skokove prirustky nebudou prilis vadit. Tedy, modra slozka ma pro barvu s indexem i hodnotu B = (164/256)*i - (1/512)*i^2. Modrou slozku budeme pocitat stejnym zpusobem jako R a G, a sice pridavanim prirustku ke kumulovane hodnote. Prirustek zde urcime zderivovanim funkce, a zjistime ze nejde o konstantu, ale vyraz (164-i)/256. Budeme tedy v kazdem kroku do kumulativniho registru pripocitavat postupne se zmensujici prirustek, a zlomek opet zohlednime tim, ze hodnotu B vezmeme z vyssiho bytu registru. Snadno se lze presvedcit, ze funkce nabyva maxima pro index 164, kdy dosahne hodnoty 52, a pro posledni barvu s indexem 255 bude mit hodnotu 36, tedy presne podle zadani. Cely generator jde tedy napsat do jednoho cyklu, obsahujiciho jen nekolik scitani a dekrement ;).

2) Generatory pseudonahodnych cisel v assembleru zpravidla realizujeme coby LCG (linearni kongruencni generatory), coz je zkratka pro rovnice typu X[i+1] = ( A*X[i] + B ) mod C. Pro spravnou funkci generatoru nesmi byt A, B ani C navzajem soudelna cisla, coby cislo C pak pouzivame bud 256 nebo 65536, kde nam omezeny bitovy rozsah registru bez osetrovani pretekani sam modulo zajisti. Pocatecni hodnote X[0] se rika seminko (seed), a ovlivnuje startovaci pozici v nasledne periode pseudonahodnych cisel. Spravne navrzene LCG by melo mit pokud mozno plnou periodu (projit kazde z 256 nebo 65536 cisel prave jednou, nez se zacne posloupnost opakovat). Generator nasi textury bude klonem LCG generatoru - se starou hodnotou v registru AX provedeme AX=AX*11; AL=AL+AH; AL=AL and 01111111. Ziskame tak novou nahodnou hodnotu v registru AX. Pocatecni hodnotou registru AX[0] (seminkem) je cislo 40960. Protoze nam staci osmibitova nahodna cisla, upotrebime z nahodneho cisla v registru AX pouze registr AL. Protoze nabyva hodnot 0 az 127 (diky andovani), ale my chceme nahodna cislo se stredni hodnotou 1 (viz nize), budeme je pouzivat zmensene o 63. Takto ziskanymi cisly pak vyplnte po radcich videoRAM (treba za pouziti stosb). Vznikly obrazec bude pripominat chaosovite hemzeni pixelu, nicmene s urcitymi rysy strukturovanosti (danymi ne zcela nahodnou povahou pseudonahodnych cisel). Proto musime z obrazku odfiltrovat sum, aby se tyto struktury zaostrily. Na odfiltrovani pouzijeme konvolucni filtr, ktery v podstate kazdy pixel nahradi vazenym prumerem okolnich pixelu. Vhodne voleny vyber okolnich pixelu dovoli zapsat cele prumerovani do jedine kratke cyklicke operace. V nasem pripade projdeme videoram opet po radcich zleva doprava a pak dolu, a k hodnote kazdeho pixelu pricteme hodnoty jeho leveho a horniho souseda, vysledek vydelime dvema, a ulozime zpet. Tim se aktualni bod stava prumerem svych dvou sousedu, mirne snizenym ci zvysenym podle nahodne hodnoty. Vypocet lze provadet bud v sestnactibitove aritmetice (potrebujeme mit rozsah -63..+64 pro nahodna cisla a 0..255 pro jasy pixelu), nebo i v osmibitove, kde ale musime dat pozor na vhodne zohlednovani carry (pri pricitani nahodneho cisla carry budeme preventivne ignorovat, pri pricteni druheho souseda ho jiz zohlednime). Pak se posuneme k dalsimu pixelu. Pouzitym poradim prumerovacich operaci, typu aritmetiky nebo uvazovani ci neuvazovani prvniho radku obrazu se muze konkretni podoba textury mirne lisit, ale vzdy pujde o vyhlazenou souvislou texturu zcela bez rusivych diskretnich nahodnych bodu.

3) Pro posledni cast ulohy budeme videoRAM povazovat za pole 320x200 pixelu, levy horni pixel ma souradnice [X,Y]=[0,0], pravy horni [319,0], levy dolni [0,199] a pravy dolni [319,199]. Takto chapane souradnice nam umozni snadno prevadet dvojici [X,Y] na adresu pixelu (adresa=X+320*Y) nebo naopak adresu na souradnice (Y=adresa div 320; X=adresa mod 320). Nyni pro kazdy bod obrazovky P[X,Y] spocitame hodnotu vyrazu ((1/4)*X^2 - Y^2). Pokud bude vysledek (obsah sestnactibitoveho registru s vysledkem nyni chapeme jako cislo bez znamenka) v rozsahu 0..16383 nebo 32768..49151, ulozime do pixelu hodnotu (X xor Y) (resp. spodnich 8 bitu z teto hodnoty, protoze muze byt i vetsi nez je rozsah osmibitoveho cisla). Jinak nechame pixel nezmeneny. Pri pocitani s kvadraty souradnic staci pouzivat osmibitove nasobeni, a jeho sestnactibitove vysledky pak odecist. Urceni, zda se cislo nachazi v danem intervalu, jde pak realizovat prostym otestovanim jednoho z jeho bitu. Tim je uloha hotova.

FAQ 4:

Q: Co je to Bressenhamuv algoritmus a jak se na nej da prijit?
A: Bressenhamuv algoritmus se pouziva ve vetsine systemu, kde je treba kreslit caru bud do matice diskretnich pixelu, nebo pomoci sekvence diskretnich kroku (napriklad posunu pisatka plotteru). Algoritmus pracuje s celymi cisly a vystaci s operacemi scitani, odcitani a rotace doprava. Ukolem je nakreslit caru z bodu [X0,Y0] do bodu [X1,Y1]. Pokud takovou caru kreslime, zacneme nakreslenim pocatecniho bodu. Potom provedeme VZDY posun ve smeru osy, kam ma cara delsi prumet (prumet do osy X je ABS(X1-X0) a prumet do osy Y ABS(Y1-Y0)), a OBCAS i posun ve smeru zbyvajici osy. Pak se vzdy kresli dalsi bod, a cyklus se opakuje tolikrat, kolik pixelu mel delsi prumet. Otazkou je, jak zjistovat, kdy posun ve zbyvajicim smeru provest. Reseni je intuitivni - pokud mame ve smeru delsiho prumetu provest D kroku a ve smeru zbyvajici osy K kroku, meli bychom spravne pri kazdem posunu ve smeru D udelat vzdy zaroven i K/D posunu ve zbylem smeru. Protoze posuny jde delat minimalne o 1, musime pockat, az se nam ze zlomku K/D nastrada cislo vetsi nez 1/2, a pak muzeme provest 1 posun ve smeru K. Nastradane cislo pak o 1 zmensime. Protoze procesor pracuje s celymi cisly a ne se zlomky, musime tuto aritmetiku na cela cisla nejak prevest. Nejjednodussi je pamatovat si bokem hodnotu jmenovatele (cislo D), a pracovat jen s citateli. Odecteni jednicky od nastradaneho cisla pak provedeme odectenim D, a porovnani nastradaneho cisla s 1/2 provedeme jako porovnani s cislem D/2. Celou zalezitost jde dale upravit tak, ze porovnani nahradime pretecenim po pricteni citatele k nastradane hodnote (tu pak inicializujeme na -D/2) a podobne. Bressenhamuv algoritmus se odvozuje obvykle zcela jinak, ale protoze je tato filozofie obsazena v mnoha rutinach, ktere s grafikou vubec nesouvisi (mixovani zvuku, zvetsovani, vypocet goniometrickych funkci), nabizim vam toto vysvetleni (doufam, ze jsem to vylozil dostatecne lidsky :).


Cviceni 8 (teoreticke):

Syntakticke (ne)moznosti assembleru, pouzivani procedur a maker. Duvody pro (ne)pouziti maker, vliv na kvalitu a efektivitu vysledneho kodu.

Priklad: Pomoci maker zkusime zjednodusit (?!) nektere ulohy z minula. Zbytek cviceni bude venovan problemum ohledne reseni vasich semestralnich praci a nekterym castym chybam pri reseni uloh.


Cviceni 9 (laboratorni):

Odevzdani ulohy 4 ze sedmeho cviceni a zadani ulohy 5. Take se pise ctvrty z testu.

Test 4:

V testu dostane kazdy 5 otazek, kde ke kazde vzdy budou 4 moznosti a), b) c), d), z toho jedina spravna. Na vypracovani testu je 15 minut. Jako literatura je povoleno v podstate cokoliv. V testu jsou zrecyklovany otazky, ktere delaly v minulych trech testech nejvice problemu.

Uloha 5:

A) [nase reseni - 248 bytu]
Napiste program, ktery bude umet nasledujici vec:

Vstup:
Program je ovladan prostrednictvim mysi a argumentu z prikazove radky pri spusteni. Program realizuje softwarove nasvecovani vyskove mapy v rezimu 320x200 256 barev.
Cinnost:

1) Program si pomoci sluzby DOSu 04ah zaalokuje navazujicich 64KiB na stinovou videoram, a pripadne i dalsi potrebnou pamet. Pokud se alokace nezdari, program se rovnou ukonci. Podrobnosti k alokaci jsou uvedeny v poznamce.

2) Argument z prikazove radky povazujte za jmeno souboru, ktery se pokusite otevrit. Pokud se otevreni nezdari, program rovnou skonci. Podrobnosti v poznamce.

3) Soubor obsahuje vyskovou mapu ve formatu dvoudimenzionalniho pole bytu o 321 sloupcich a 201 radcich, celkem tedy 64521 bytu, ulozeneho po radcich zleva doprava a dolu. Cely jej nactete do pameti, a pokud se nepodari nacist potrebny pocet bytu, program rovnou skonci. Podrobnosti opet v poznamce.

4) Otestujte, zda je pritomny ovladac mysi na Int 33h. Pokud nebude detekovan, program rovnou skonci.

5) Zapamatujte si aktualni graficky rezim a prepnete do rezimu 320x200 256 barev. Nastavte kvadraticko-linearni paletu od tmavomodre pres cervenou a zlutou do bile.

6) Pro ovladac mysi nastavte limity pro osu X na 0-319 a pro osu Y na 0-199.

7) Podle polohy mysi vzdy do stinove videoRAM vykreslete nasvicenou vyskovou mapu, a pri zacatku zpetneho behu paprsku se tato oblast prekopiruje do realne videoRAM. Pri stisku leveho tlacitka na mysi obnovime puvodni graficky mod a ukoncime program, jinak opakujeme v nekonecne smycce bod 7). Podrobnosti nize v poznamce.

Testovaci screenshot:

Po spusteni programu nad souborem uloha5.raw byste meli videt pri nastaveni mysi do praveho dolniho rohu uvedeny obrazek. Pokud vam program bude spravne fungovat, spustte jej nad souborem question.raw. Objekt v tomto souboru je pomerne znamy, a kdo ho jako prvni spravne identifikuje (posle mi mail se spravnou odpovedi, zdrojovym textem, prelozenou ulohou a screenshotem, aby bylo jasne, ze nejde o produkt pluginu z nejakeho kresliciho programu), dostane velke plus (tedy stupen nahoru - studenti, kteri jiz maji za 1, jsou mimo soutez). Prvnim uspesnym resitelem byl J. Sejtko, odhalil ve vyskove mape znamy obrazek tvare z Marsu, porizeny sondou Viking, a ziskava plus.

Nova hadanka: Soubory query.raw a matter.raw povazujte za specificke osmibitove vyskove mapy 321x201 bodu, tedy tentyz format jako soubory pro ulohu 5. Vhodnym vyuzitim ulohy 5 (nebo vlastnim specializovanym algoritmem) se v nich pokuste nalezt skryte obrazy. Soubor query.raw obsahuje dva celoplosne obrazky, soubor matter.raw dokonce tri celoplosne obrazky. Za kazdy objeveny obrazek dostane resitel velke plus (stupen nahoru). Desifrovane obrazky posilejte mailem jako program, ktery po spusteni nad souborem obrazek ukaze (tedy zdrojovy text, prelozeny program a ukazkovy screenshot, abych mohl rychle posoudit, jestli je vase reseni spravne - snazte se o co nejuplnejsi dekodovani, objekt musi byt zcela zrejmy a rozpoznatelny - nezretelne, neuplne nebo navzajem se prolinajici obrazky nebudou akceptovany, vzdy lze ziskat obrazek v dostatecne kvalite). Pro uplnost dodavam, ze kodovani je provedeno na fyzikalnich principech, a tedy informaci nese skutecne jen a jen vyska konkretnich bodu (fyzicky zrealizovany model takove reliefni mapy by tedy stale obsahoval kyzenou informaci a byla by mozne ji z nej vycist). Pan R. Zitta objevil prvni obrazek z mapy query.raw, a sice query1.png, a take prvni obrazek z vyskove mapy matter.raw matter1.png. Ziskava tak dva velke plusy. Zbyvajici tri obrazky query2.jpg, matter2.jpg a matter3.jpg objevil a spravne vyfiltroval pan T. Mechura, a ziskava tak 3 velke plusy.

Poznamka: Toto je posledni uloha, a meli byste ji odevzdat kdykoli do vanoc, nebo i po vanocich.

1) Protoze program, spousteny v DOSu nebo DOSPromptu, dostane po svem startu vzdy veskerou volnou pamet, nelze jiz alokovat zadnou dalsi. Bohuzel, neda se jednoduse zjistit, kolik takove pameti nam vlastne system prenechal, a ani kde se nachazi. Proto se ji musime nejprve zbavit (dealokovat), a pak pozadat znovu o prideleni (alokaci) presne potrebneho mnozstvi. Obe akce naraz zajistuje DOSovska sluzba 04ah (realloc) na Int 21h, kde pomoci ES ukazeme na pocatek existujiciho pametoveho bloku (segmentova adresa), a v BX uvedeme, kolik paragrafu (sestnactibytovych useku) souvisle za sebou v tomto bloku pozadujeme. Pokud neni mozne alokaci provest, sluzba vrati carry. V nasem pripade tedy pouzijeme puvodni hodnotu ES, a v BX budeme pozadovat 8192 paragrafu (ponechame si 64KiB aktualniho segmentu a chceme jeste 64KiB navazujici pameti). Do navazujici pameti pak budeme pristupovat napr. pres ES, ktere si poposuneme tak, aby ukazovalo na pocatek navazujiciho bloku (pricteme 4096).

2) Argumenty z prikazove radky se nachazi v takzvanem PSP (prefixu programoveho segmentu). U souboru *.com je PSP ulozen v pocatecnich 256 bytech aktualniho segmentu (proto davame org 256), u souboru *.exe je nize. V obou pripadech na nej ale po startu aplikace ukazuje DS i ES (pokud uz pocatecni hodnoty DS ani ES nemame, zjistime jeho pozici napr. pomoci funkce DOSu 051h). Na offsetu 80h v PSP lezi delka argumentu (pocet znaku), nasledovana argumenty samotnymi. Argumenty jsou ukonceny znakem 0dh (pokud se nam nehodi, musime si jeho pozici najit, a prepsat jej). Pokud je argument alespon jedno pismeno, vlozi pred nej DOS (ale treba i Turbo-Debugger) jeste automaticky mezeru, takze tim argumenty standardne poposune az na offset 82h (Windows2000 bez servicepacku 3 tento posun ale jaksi neprovadeji, takze bud upgradujte, nebo piste pred argumenty nejaky "vycpavkovy" znak, tato chyba se muze objevovat i v nekterych ranych verzich WindowsXP). Soubor pak otevrete funkci DOSu 03dh, a pokud se volani vrati s nastavenym carry, ukoncite program.

3) Pomoci DOSove funkce 03fh nactete obsah souboru do pameti (vejde se bez nesnazi hned za kod do aktualniho segmentu *.comu, pokud jste ho tedy psali alespon trochu rozumne, jinak byste si museli pripadne zaalokovat jeste extra 64KiB blok navic). Po navratu z volani zkontrolujeme, jestli nedoslo k chybe, a zda se shoduje presne pozadovany pocet bytu. V pripade chyby nebo neshody program ukoncime. Soubor jako takovy nemusime explicitne zavirat, pri ukonceni programu to udela system tak jako tak za nas.

4) Volanim funkce 0000h na Int 33h zdetekujeme ovladac mysi, a pokud nebude nalezen, program rovnou ukoncime.

5) Funkci 0fh na Int 10h zjistime aktualni graficky rezim, zapamatujeme si jej, pak zinicializujeme rezim 013h, a vygenerujeme paletu. Barva s indexem 0 ma slozky [R,G,B] nastaveny na [0,0,18]. Barva s indexem i ma slozky nastaveny na [ (180/256)*i - (1/512)*(i^2) , 1/4*i , 18 - (82/256)*i + (1/512)*(i^2) ]. Pokud si funkci kazde slozky zderivujete, zjistite, ze jde opet jen o konstantni a linearni funkce podle promenne i, a tedy jen mirne poupravite generator z ulohy 4.

6) Pomoci funkci ovladace 0007h a 0008h na Int 33h nastavte limity pro souradnice X a Y. V ose X v rozsahu 0-319, a v ose Y 0-199. Tento krok je nutny k tomu, aby byly souradnice z mysi v rozumnem rozsahu, primo zpracovatelnem aritmetikou procesoru x86.

7) Pro posledni cast ulohy budeme stinovou videoRAM povazovat za pole 320x200 pixelu, levy horni pixel ma souradnice [X,Y]=[0,0], pravy horni [319,0], levy dolni [0,199] a pravy dolni [319,199]. Takto chapane souradnice nam umozni snadno prevadet dvojici [X,Y] na adresu pixelu (adresa=X+320*Y) nebo naopak adresu na souradnice (Y=adresa div 320; X=adresa mod 320). Obdobne chapeme i pole vyskove mapy H[X,Y], ktere jsme nacetli ze souboru. Nyni pro kazdy bod stinove obrazovky P[X,Y] spocitame, jaky jas L mu ma s ohledem na vyskovou mapu (kterou povazujeme za pole 321x201 bytovych hodnot) a aktualni pozici svetelneho zdroje (mys, souradnice mysi Xm a Ym zjistite vzdy jen jednorazove pred pocitanim kazdeho noveho snimku, aby se pri rychlem pohybu pro jednotlive body nelisily) nalezet. Tento jas se sklada ze tri dilcich slozek, a sice staticke slozky Ls, polohove slozky Lp a gradientni slozky Lg. Prvni slozka Ls je konstantni a ma velikost KONST_S (KONST_S je symbolicka konstanta, definovana jako KONST_S equ 254). Druha slozka Lp je rovna [(Xm-X)^2 + (Ym-Y)^2]/KONST_P (KONST_P definujte jako 360). Treti slozka Lg je dana jako [(H[X,Y-1]-H[X,Y])*(Ym-Y) + (H[X,Y]-H[X+1,Y])*(Xm-X)]/KONST_G (KONST_G zadejte jako 24). Dejte pozor na spravnou praci s carry, protoze ackoli jsou body H bezznaminkova osmibitova cisla, jejich rozdil jiz muze byt zaporny, a zrovnatak rozdily aktualni souradnice a souradnice mysi. Pouzivejte tedy beznou sestnactibitovou aritmetiku a take instrukce idiv a imul. Nakonec spocitejte vyraz Ls+Lg-Lp a vysledek oriznete do rozsahu 0..255 (tzv. saturacni aritmetika - pokud vam vyjde vice nez 255, bude vysledek stale 255, a pokud mene nez nula, bude vysledek stale nula). Zbyle vysledne cislo je primo hodnotou pixelu (vesmes linearni paleta nam zajistuje potrebnou umeru mezi hodnotou pixelu a jeho jasem). Po zpracovani vsech 320*200 bodu v obrazu (protoze je pole H o 1 vetsi v obou rozmerech, neni treba osetrovat okrajove chovani, a budeme jej povazovat za pole s indexy 0..320 x -1..199) pockame na vertikalni navrat paprsku (na portu 03dah se pri opakovanem nacitani bit 3 zmeni z nuly do jednicky), a pak prekopirujeme celou stinovou videoRAM do realne videoRAM. Pokud nebyl zjisten stisk leveho tlacitka mysi, opakujeme cely bod 7), jinak obnovime graficky mod a program ukoncime.

Tato uloha zdaleka neni tak tezka, jak vypada, a vysledny efekt stoji za to. Protoze jsme konstanty KONST_S, KONST_P a KONST_G definovali symbolicky, jiste pro vas nebude problem menit parametry hotoveho programu, a docilit zajimavejsich efektu.

FAQ 5:

Q: Neni v dnesni dobe, kdy mame gigabyty pameti a gigahertzove procesory, spolu s modernimi kompilatory, lepsi psat vsechno ve vyssim jazyce, citelneji a prenositelne, treba v Jave?
A: Misto odpovedi se podivejte sem: http://194.203.40.36/~sm/blog/2004/08/just-best-quote-of-day-so-far.html. Prirovnani navic trosku kulha vzhledem k nezbytnosti nabobtnaleho environmentu Javy a jeji povestne nestabilite, takze skutecnost je jeste horsi ;).


Cviceni 10 (teoreticke):

Zohledneni realneho casu v assemblerovskych aplikacich, prace s citacem 8253-5. Aspekty pouziti 8253-5 vzhledem k vnitrnim hodinam DOSu a systemum Windows.

Priklad: U tabule budou reseny priklady na praci s realnym casem pomoci obsluhy preruseni od 8253-5. Zbytek cviceni bude venovan problemum ohledne reseni vasich semestralnich praci a nekterym castym chybam pri reseni uloh.


Cviceni 11 (laboratorni):

Prvni vlna odevzdani ulohy 5 z devateho cviceni. Take se pise paty, posledni z testu.

Test 5:

V testu dostane kazdy 5 otazek, kde ke kazde vzdy budou 4 moznosti a), b) c), d), z toho jedina spravna. Na vypracovani testu je 15 minut. Jako literatura je povoleno v podstate cokoliv. Jednotlive otazky se budou tykat:

- zpusoby pristupu do I/O prostoru (po bytu, wordu, dusledky)
- zohledneni realneho casu v programech na PC (casovac 8253, nevyhody ostatnich metod)
- priznaky a aritmetika (jak aritmeticke instrukce nastavuji priznaky)
- assembler versus vyssi programovaci jazyky (otazka zadarmo)
- kratka rutina zpracovavajici pole (poznat, co dela)


Cviceni 12 (odpada - cast jeho naplne se presune na cviceni 10 a 11):

Odevzdani ulohy 5 z devateho cviceni. Take se pisi chybejici testy.

Dalsi cast cviceni bude venovana diskum v PC a jejich ovladani pomoci BIOSu a primeho pristupu. Dale limity kapacit disku, moznosti rozhrani IDE. Vyvraceni nekterych naprosto nesmyslnych ale o to vic zazitych fam o velkych discich a reseni problemu s pristupem k temto mediim. Pro ukazku primeho pristupu k disku si muzete stahnout program ideinf.asm, ktery analyzuje diskove a CD-ROM jednotky na primarnim kanalu, bezchybne a to az do kapacity 128GB, narozdil od BIOSu. Je treba jej spoustet v DOSu, Windows odstinuji porty IDE radice. Je psany v TASMu (jeden z mych hrichu mladi). Zbytek cviceni bude venovan problemum ohledne semestralnich praci a odevzdavani semestralek ci uloh.


Cviceni 13 (odevzdavaci):

Opozdene odevzdani ulohy 5 z devateho cviceni. Odevzdavaji se take semestralky (predposledni sance), nebo si doplnit, co vam chybi (tesy, ulohy), pripadne zkonzultovat problemy ohledne semestralek.


Cviceni 14 (odevzdavaci, zapoctove):

Posledni moznost odevzdani ulohy 5 z devateho cviceni. Odevzdavaji se take semestralky (oficialne posledni moznost, neoficialne pak ... ).