Ako sa vam podarilo vyriesit domacu ulohu ? Dufam ze ste sa s nou nemuseli prilis dlho trapit a ze ste ju zdolali raz-dva. Keby nahodou nie vy ste zdolali ulohu ale ona vas, netrapte sa a o to pozornejsie si pozrite riesenie:
Pozorne si vsimnime tento fragment neskomprimovaneho bloku bajtov, ktory sme si uviedli ako priklad na ozrejmenie v minulej lekcii:
77 22 22 55 88...
Pre nas je podstatne to, ze sa tam nachadzaju prave dva za sebou iduce rovnake bajty. A teraz si vsimnime, ako bude tento fragment vyzerat po skomprimovani nasou komprimacnou rutinkou:
77 22 22 0 55 88...
Hned na prvy pohlad vidime, ze skomprimovany fragment je akysi dlhsi ako povodny, neskomprimovany ! Ved by to predsa podla logiky malo byt prave naopak...
Prave tu, na tomto nasom vzorovom priklade sa uplatnil nedostatok tejto komprimovacej metody. Akonahle sa v povodnom bloku nachadzaju prave dva po sebe iduce bajty, komprimacna rutinka za nich hodi este jednu nulu navyse. Teraz si predstavte, ze dany blok, ktory treba skomprimovat bude obsahovat iba taketo dvojice bajtov. Napriklad
22 22 44 44 99 99 66 66
Skomprimovany blok bude vyzerat takto:
22 22 0 44 44 0 99 99 0 66 66 0
Po komprimacii sa nam tento blok nielenze neskratil, ale este aj o celu polovicu svojej dlzky natiahol ! A to je prave ten nedostatok tejto metody.
Preto mudri programatori dali hlavy dohromady a vymysleli novu, ovela lepsiu metodu komprimacie, u ktorej nie je tento nedostatok az taky vyrazny. Tato nova metoda, rovnako ako vsetky predchadzajuce, tiez pouziva princip "identifikacia poctu - pocet - bajt", ale identifikaciu poctu bajtov uklada do skomprimovaneho bloku pomocou uplne inej filozofie ako vsetky predchadzajuce metody, ktore sme si prebrali.
Hned na zaciatku skomprimovaneho bloku sa nachadza bajt so specialnym vyznamom. Dolnych 7 bitov tohto bajtu predstavuje nas pocet (nech je rovny hodnote N) a siedmy bit presne specifikuje coho sa tento pocet vlastne tyka. Ak je tento siedmy bit jednotkovy, potom za tymto specialnym bajtom nasleduje este jeden bajt (nech ma hodnotu B) a obidva bajty hovoria ze v povodnom bloku sa nachadza N rovnakych bajtov s hodnotou B. Ale ak je siedmy bit nulovy, potom to znamena ze za tymto specialnym bajtom nasleduje N bajtov ktore maju rozne hodnoty. Cele to neznamena nic ine ako to ze v povodnom bloku sa nachadzalo N tychto roznych bajtov. Potom opet nasleduje dalsi specialny bajt, za ktorym nasleduju bajty podla jeho siedmeho bitu a takto sa to cele opakuje az do konca skomprimovaneho bloku.
Pocet bajtov 0 nema ziadny vyznam, preto je nulova hodnota dolnych siedmych bitov specialneho bajtu chapana ako hodnota 128. Akonahle sa v povodnom bloku nachadza za sebou viac ako 128 rovnakych bajtov, potom v skomprimovanom bloku bude viac dvojic bajtov, kde kazda dvojica pozostava zo specialneho bajtu a toho bajtu ktory je v povodnom bloku. Cele to najjednoduchsie ozrejmi konkretny priklad. Nech povodny blok vyzera takto:
66 88 99 55 55 55 55 88 88... (200 bajtov 88) ...88 88 33 22
Potom skomprimovany blok bude:
3 66 88 99 132 55 128 88 200 88 2 33 22
Podobne ak je v povodnom bloku za sebou iducich viac ako 128 roznych bajtov, bude v skomprimovanom bloku tolko skupin bajtov na cele so specialnym bajtom kolko je potrebne. Akurat to uz nebudu dvojice.
Tentoraz si vynimocne najprv ukazeme dekomprimacnu rutinku. Jednak preto, lebo je jednoduchsia ako komprimacna a jednak preto, lebo z nej velmi pekne vidno v akom tvare je vlastne ulozeny skomprimovany blok.
dek | ld | hl,#8000 | adresa skomprimovaneho bloku |
ld | de,#4000 | kam ulozit dekomprimovany blok | |
ld | ix,#1b00 | dlzka dekomprimovaneho bloku | |
play | ld | b,(hl) | precitanie stavu minipocitadla |
inc | hl | ukazovatel na dalsiu poziciu | |
bit | 7,b | jedna sa o rovnake alebo rozne bajty ? | |
dd1 | ld | a,(hl) | (precitanie hodnoty bajtu) |
jr | nz,dd2 | ak sa jedna o rad neskomrimovanych | |
inc | hl | roznych bajtov tak zvecsime ukazovatel | |
dd2 | ld | (de),a | ulozenie bajtu do neskompr. bloku |
inc | de | ukazovatel na dalsiu poziciu | |
dec | ix | zmensenie hlavneho pocitadla | |
ex | af,af | uschova hodnoty bajtu | |
ld | a,xh | spracovali sme uz cely povodny | |
or | xl | blok ? | |
ret | z | ak ano tak navrat | |
ex | af,af | obnova hodnoty bajtu | |
res | 7,b | minipocitadlo bude 0..127 | |
djnz | dd1 | a opakujeme potrebny pocet krat | |
jr | z,dd3 | ak sa jednalo o rozne bajty, | |
inc | hl | este posunieme ukazovatel | |
dd3 | jr | play | a skok na zaciatok hlavnej slucky |
Vsimnite si, ze tentoraz sa dlzka povodneho bloku nezadava do registra BC ako to bolo zvykom pri predchadzajucich rutinkach, ale trochu netradicne do registra IX. Keby ste predsa len chceli mat dlzku v registri BC, staci instrukciu LD IX,#1b00 nahradit tymto programcekom:
ld | bc,dlzka | |
push | bc | |
pop | ix |
Tentoraz dostanete na domacu ulohu take volne zamyslenie. Skuste si predstavit, co vsetko musi vykonat komprimacna rutinka a ako musi postupovat, aby mohla skomprimovat blok do takeho tvaru, ktory vie potom tato nasa dekomprimacna rutinka vratit do povodneho stavu.
Vas Busy.