Jednoducha dekomprimacia

   V minulej lekcii sme sa zacali zaoberat komprimacnymi rutinkami. Hned sme si jednu aj ukazali. Rutinku sme spravili tak, aby mala v registroch HL,DE,BC presne take vstupne parametre ako LDIR. Ked sa vsak na tuto rutinku pozornejsie pozrieme, ukaze sa ze nielen vstupne hodnoty, ale aj vystupne hodnoty registrov HL,DE,BC su take iste ako pri LDIR. Pravda, az na jeden maly rozdiel - register DE ukazujuci na cielovy usek pameti nenarastie o pocet bajtov zadany na zaciatku do registra BC, ale len o tolko bajtov, kolko je potrebne na ulozenie skomprimovaneho povodneho useku. Urcite nebude pre vas ziadny problem vyuzit tuto informaciu na to, aby ste zistili, ze kolko vlastne zabera tento skomprimovane usek.

   Problem komprimacie sme teda rutinkou z minulej lekcie uspesne vyriesili a dany usek pameti mame skomprimovany. Ale cele by to bolo nanic, keby sme nemohli z tohto skomprimovaneho useku dostat zase povodny. Prave tento druhy problem sa nazyva dekomprimacia (tiez niekedy depack) a riesi ho nasa dnesna rutinka - nazvime ju preto dekomprimacna rutinka.

   Vstupe hodnoty do rutinky su opet take iste ako pri LDIR - cize HL ukazuje na zdrojovy, skomprimovany usek, DE ukazuje kam sa ma povodny usek ulozit a BC je dlzka tohto povodneho useku.

   Rutinka pracuje tak, ze kopiruje pamet presne tak isto ako LDIR ale s jednym malym, ale zato velmi podstatnym rozdielom. Ked narazi na bajt v ktorom je napisana nula, tak nacita este jeden bajt a do cielovej oblasti neulozi tieto dva bajty, ale tolko nulovych bajtov, aku ma hodnotu tento druhy bajt. Ak ma hodnotu nula, tak to znamena, ze rutinka ulozi 256 nulovych bajtov. Vsimnime si, ze vystupne hodnoty v registroch HL,DE,BC sa spravaju podobne ako pri komprimacnej rutinke z minulej lekcie.

   Informacia identifikujuca pocet, konkretne v nasej rutinke ten nulovy bajt, ktory nas v skomprimovanom useku upozornuje na to, ze za nim nasleduje skutocny pocet nul sa odborne nazyva znackovy bajt. Z toho je aj odvodeny nazov tejto komprimacie - je to komprimacia so znacovym bajtom nula.

   Ako priklad vstupnych hodnot si zvolme take hodnoty, aby sme zase naspet dostali to, co sme v minulej lekcii skomprimovali. Teda adresa povodneho useku pameti (ktory chceme ziskat) bude #4000, jeho dlzka bude #1800 a adresa skomprimovaneho useku bude #8000. Na pocitaci ZX Spektrum a kompatibilnych typoch povodny usek znamena pixlovu cast videoramky, a preto obrazok, ktory sme v minulej lekcii skomprimovali dnes zase dostaneme do povodneho stavu - dekomprimujeme ho.

unpack ld hl,#8000 Priklad adresy skomprimovaneho useku 
 ld de,#4000 Priklad adresy povodneho useku 
 ld bc,#1800 Priklad dlzky povodneho useku 
deklop ld a,(hl) Vezme bajt zo skomprimovaneho useku 
 ldi  skopiruje ho do povodneho useku 
 or je to nulovy bajt ? 
 jr z,dekpck ak ano tak skok na osetrenie nuly 
dekend ld a,b ak nie tak test ci sme uz 
 or spracvali cely usek 
 jr nz,deklop ak nie tak pokracujeme dalsim bajtom 
 ret  ak ano tak koniec rutinky 
dekpck ld a,(hl) za nulou nasleduje pocet tychto nul 
 inc hl posun ukazovatela na dalsi bajt 
 ld xh,a xh bude pocitadlo nul 
deknul dec xh treba vytvorit este dake nuly ? 
 jr z,dekend ak nie tak koniec osetrenia nuly 
 ld a,b ak ano tak este skontrolujeme ci sme uz 
 or nahodnou nespracovali cely povodny usek 
 ret ak ano tak koniec rutinky 
 xor ak nie tak vyrobime nulu 
 ld (de),a a ulozime je do povodneho useku 
 inc de posunutie 
 dec bc ukazovatelov 
 jr deknul a v slucke vytvarame dalsie nuly 

   Na domacu ulohu si tentoraz skuste sami napisat komprimacnu a dekomprimacnu rutinku ktora bude namiesto nulovych bajtov komprimovat bajty s hodnotou 255 (alebo si zvolte nejaku inu hodnotu). Nezabudnite na spravny znackovy bajt !

   V buducej lekcii si ukazeme uz trochu narocnejsie, ale vo vecsine pripadov aj ovela ucinnejsie komprimacne rutinky, ktore sa vo velkej miere vyuzivaju v praxi.

Vas Busy.

Nazad / back , predchadzajuca a dalsia lekcia