home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga MA Magazine 1997 #3
/
amigamamagazinepolishissue03-1
/
ma_1995
/
07
/
ami37
< prev
next >
Wrap
Text File
|
1997-04-15
|
9KB
|
311 lines
POWER PACKER W AMOSIE
<lead>Od redakcji: ludzie zwiâzani z komputerami od dawna
borykajâ sië z problemem wolnego miejsca na dyskietkach. Dlatego
teû kilka mâdrych osób wymyôliîo kiedyô, ûe moûna zaoszczëdziê
nieco miejsca na noônikach, upakowujâc zapisane na nich
informacje. I tak powstaîy róûne programy, sîuûâce temu celowi. W
artykule tym chciaîbym opisaê, w jaki sposób z poziomu AMOS-a,
moûna rozpakowaê plik, spakowany Power Packerem.
<a>Îukasz Szelâg
<txt>Najpierw opiszë format spakowanych danych:
Identyfikator -- (4 bajty) -- 'PP20' lub 'PX20'.
Efektywnoôê -- (4 bajty) -- $09090909 -- najszybsza, $090a0a0a --
ôrednia, $090a0b0b -- dobra, $090a0c0c -- bardzo dobra, $090a0c0d
-- najlepsza
Suma kontrolna -- (2 bajty) -- tylko dla danych zakodowanych.
Spakowane dane (dîugoôê).
Fecrunch info -- (4 bajty).
Identyfikator informuje nas o tym, czy plik zostaî spakowany
Power Packerem. Nas interesowaê bëdzie nagîówek 'PP20' ('PX20'
odnosi sië do danych spakowanych i zakodowanych). Po
identyfikatorze nastëpuje informacja o efektywnoôci, z jakâ
zostaîy spakowane dane (w wypadku 'PX20' dochodzi jeszcze suma
kontrolna, która sîuûy do sprawdzenia poprawnoôci wprowadzanego
hasîa). Nastëpnie mamy spakowane dane, a po nich, tzw. decrunch
info, które zawiera m.in. dîugoôê danych po rozpakowaniu.
Na samym poczâtku naszej procedury odczytamy z pliku informacjë o
dîugoôci danych spakowanych oraz dîugoôci danych po rozpakowaniu.
Dîugoôê danych spakowanych to po prostu dîugoôê pliku, który
chcemy rozpakowaê. Moûna jâ odczytaê w nastëpujâcy sposób:
<l>Open In 1,_SOURCE$ : Rem otwieramy plik
PACK_LEN=Lof(1) : Rem odczytujemy jego dîugoôê
Close 1 : Rem a teraz go zamykamy
<txt>Dobrze by byîo, ûeby nasza procedura sprawdziîa, czy ma do
czynienia z formatem pliku spakowanego Power Packerem. Moûemy
wiëc dopisaê linië:
<l>Open In 1,_SOURCE$ : Rem otwieramy plik
If Input$(1,4)<>'PP20' Then Pop Proc[-1] : Rem sprawdzamy czy 'PP20'
PACK_LEN=Lof(1) : Rem odczytujemy jego dîugoôê
Close 1 : Rem zamykamy plik
<txt>W wypadku, gdy plik nie byî spakowany, opuszczamy procedurë,
która na wyjôciu poinformuje o bîëdzie (zmienna Param).
Teraz musimy jeszcze odczytaê, a wîaôciwie obliczyê dîugoôê
danych po rozpakowaniu. Jak juû na poczâtku wspomniaîem (w
trakcie omawiania formatu danych), 4 bajty, liczâc od koïca
pliku, jest umieszczona informacja (pole decrunch info) o
dîugoôci danych po rozpakowaniu. Informacja ta jest umieszczona
na bitach od 8. do 31., tak wiëc po odczytaniu wartoôci z pola
decrunch info, musimy të wartoôê przesunâê na pozycjë bitów od 0.
do 23., inaczej mówiâc podzieliê przez 256.
Najpierw odczytajmy pole decrunch info. W tym celu musimy zmieniê
pozycjë czytania z pliku na pozycjë dîugoôê pliku -- 4 i odczytaê
4 znaki:
<l>Pof(1)=_PACK_LEN-4 : Rem nowa pozycja czytania
A$=Input$(1,4) : Rem odczytanie 4 znaków
<txt>Zmienna A$ zawiera 4 znaki, które po zamianie na liczbë
4-bajtowâ i podzieleniu przez 256, dadzâ nam dîugoôê danych po
rozpakowaniu:
<l>_UNPACK_LEN=Leek(Varptr(A$))/256
<txt>Tak wiëc nasza procedura wyglâda nastëpujâco:
<l>Open In 1,_SOURCE$ : Rem otwieramy plik
If Input$(1,4)<>'PP20' Then Pop Proc[-1] : Rem sprawdzamy czy 'PP20'
_PACK_LEN=Lof(1) : Rem odczytujemy jego dîugoôê
Pof(1)=_PACK_LEN-4 : Rem nowa pozycja czytania
A$=Input$(1,4) : Rem odczytanie 4 znaków
_UNPACK_LEN=Leek(Varptr(A$))/256 : Rem obliczamy dîugoôê
Close 1 : Rem zamykamy plik
<txt>Nastëpna czynnoôê to przydzielenie pamiëci na bufor dla
rozpakowania danych. Bufor ten powinien byê zwiëkszony o tzw.
margines bezpieczeïstwa (8 bajtów). Wynika to z tego, ûe adres,
pod którym bëdâ rozpakowane dane, musi byê wiëkszy o co najmiej 8
bajtów niû adres spakowanych danych. Zatem bëdziemy potrzebowali
_UNPACK_LEN+16 bajtów pamiëci (4 bajty identyfikatora plus 4
bajty efektywnoôci plus dîugoôê danych po rozpakowaniu plus 8
bajtów marginesu bezpieczeïstwa). Po przydzieleniu bufora pamiëci
wczytamy do niego zawartoôê spakowanego pliku:
<l>Reserve As Chip Data _BANK,_UNPACK_LEN+16 : Rem przydzielenie pamiëci
Bload _SOURCE$,Start(_BANK) : Rem wczytanie danych
<txt>Do rozpakowania danych w buforze sîuûy funkcja (z biblioteki
powerpacker.library):
<l>ppDecrunchBuffer (endcrun,decrbuf,efficiency,color)
A0 A1 A2 D0
<txt>Jak widaê, funkcja ta wymaga podania czterech parametrów:
endcrun (A0) -- adres przedostatniego bajtu spakowanych danych,
decrbuf (A1) -- adres, pod którym dane bëdâ rozpakowane,
efficiency (A2) -- efektywnoôê, z jakâ zostaîy spakowane dane,
color (D0) -- efekt, towarzyszâcy rozpakowywaniu:
DECR_COL0 (0) -- kolor tîa,
DECR_COL1 (1) -- kolor liter,
DECR_POINTER (2) -- kolor wskaúnika,
DECR_SCROLL (3) -- przesuwanie ekranu na boki,
DECR_NONE (4) -- nic sië nie dzieje.
Najpierw otworzymy bibliotekë powerpacker.library za pomocâ
instrukcji Lib Open (biblioteka ta powinna byê dostëpna dla
systemu):
<l>Lib Open 1,"powerpacker.library",0 : Rem otwarcie biblioteki
<txt>Kolejnâ czynnoôciâ bëdzie wypeînienie rejestrów adresowych
od A0 do A2 i rejestru danych D0 odpowiednimi wartoôciami. W
rejestrze A0 powinien sië znaleúê adres przedostatniego bajtu
spakowanych danych, natomiast w rejestrze A1 adres, pod którym
dane bëdâ rozpakowane, a wiëc:
<l>Areg(0)=Start(_BANK)+_PACK_LEN : Rem endcrun
Areg(1)=Start(_BANK)+16 : Rem decrbuf
<txt>Rejestr adresowy A2 powinien zawieraê adres efektywnoôci, z
jakâ zostaîy spakowane dane. Pole efektywnoôê znajduje sië o 4
bajty od poczâtku wczytanych danych, zatem:
<l>Areg(2)=Start(_BANK)+4 : Rem adres efektywnoôci
<txt>Pozostaje nam jeszcze wypeînienie rejestru D0 numerem efektu
(0-4), który bëdzie towarzyszyî rozpakowywaniu danych:
<l>Dreg(0)=_EFFECT : Rem numer efektu
<txt>Po tych czynnoôciach moûemy wywoîaê funkcjë ppDecrunchBuffer
(jest ona umieszczona o 36 bajtów od bazy biblioteki):
<l>_ERROR=Lib Call(1,-36) : Rem wywoîanie funkcji
<txt>Jeûeli operacja zostanie przeprowadzona bezbîëdnie, to
zmienna _ERROR bëdzie zawieraê wartoôê $FFFF (65535).
I to juû wîaôciwie wszystko. Zamykamy naszâ bibliotekë, nagrywamy
rozpakowane dane i zwalniamy przydzielonâ pamiëê:
<l>Lib Close 1 : Rem zamkniëcie biblioteki nagranie rozpakowanych danych
Bsave _DEST$,Start(_BANK)+16 To Start(_BANK)+Length(_BANK)
Erase _BANK : Rem zwolnienie pamiëci
<txt>Wszystkim ûyczë miîego rozpakowywania, a poniûej
przedstawiam kompletnâ procedurë.
<l>Procedure _PPDECRUNCH_FILE[_SOURCE$,_DEST$,_EFFECT,_BANK]
'
' **************************************************************
' * Coder : Îukasz Szelâg *
' * Version: 1.0 *
' * Date : 1994.07.29 *
' * Comment: Procedura rozpakowuje plik _SOURCE$ spakowany *
' * Power Packerem. Zmienna _DEST$ okreôla nazwë, *
' * pod jakâ zostanie nagrany rozpakowany plik, *
' * natomiast zmienna _EFFECT okreôla numer efektu, *
' * jaki towarzyszyê bëdzie rozpakowywaniu danych *
' * (0-kolor tîa, 1-kolor liter, 2-kolor wskaúnika, *
' * 3-przesuwanie ekranu na boki, 4-bez efektu). *
' * Zmienna _BANK, okreôla numer banku pamiëci, *
' * jaki bëdzie wykorzystany na wczytanie danych. *
' * W przypadku wystâpienia bîëdu zmienna Param *
' * na wyjôciu z procedury zwróci wartoôê ujemnâ. *
' **************************************************************
'
' odczytanie z pliku informacji o dîugoôci danych
' spakowanych i dîugoôci danych rozpakowanych
'
Open In 1,_SOURCE$
If Input$(1,4)<>'PP20' Then Pop Proc[-1]
_PACK_LEN=Lof(1)
Pof(1)=_PACK_LEN-4
A$=Input$(1,4)
_UNPACK_LEN=Leek(Varptr(A$))/256
Close 1
'
' zarezerwowanie pamiëci na bufor i wczytanie danych
Reserve As Chip Data _BANK,_UNPACK_LEN+16
Bload _SOURCE$,Start(_BANK)
'
' otwarcie biblioteki
Lib Open 1,"powerpacker.library",0
'
' adres poprzedzajâcy ostatni bajt spakowanych danych
Areg(0)=Start(_BANK)+_PACK_LEN
'
' adres, gdzie bëdâ rozpakowywane dane (musi byê przynajmniej o
' 8 razy wiëkszy niû poczâtek spakowanych danych)
Areg(1)=Start(_BANK)+16
'
' adres efektywnoôci, z jakâ zostaîy spakowane dane
Areg(2)=Start(_BANK)+4
'
' efekt, jaki bëdzie uûyty podczas rozpakowywania
Dreg(0)=_EFFECT
'
' wywoîanie funkcji ppDecrunchBuffer
_ERROR=Lib Call(1,-36)
'
' zamnkniëcie biblioteki
Lib Close 1
'
' nagranie rozpakowanych danych i zwolnienie pamiëci
Bsave _DEST$,Start(_BANK)+16 To Start(_BANK)+Length(_BANK)
Erase _BANK
'
End Proc[65535-_ERROR]