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 | a | 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 | c | 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 | c | nahodnou nespracovali cely povodny usek | |
ret | z | ak ano tak koniec rutinky | |
xor | a | 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.