mini poradnik Action! – „ku pamięci”
Poniższy tekst jest publiczną odpowiedzią dla kolegi Rafała, który zapytał w e-mail o wyjaśnienie dotyczące stosowania w listingach Action! pewnych konstrukcji.
Zapewne prędzej czy później spotka się ciekawy przygód umysł z parą poleceń stosowanych w wielu językach programowania na Atari. Są nimi:
POKE i PEEK
Pierwsza z nich zapisuje wskazany bajt pamięci wartością przekazaną w argumencie, druga zazwyczaj jest funkcją i zwraca odczytaną wartość jako wynik działania tejże funkcji. Dla przykładu w języku Basic najczęściej wygląda to tak:
10 POKE (710,2)
11 PRINT PEEK (710)
Tutaj warto przypomnieć, że język Turbo Basic XL posiada również polecenie pracujące nie na bajcie (8 bitów danych) lecz na słowie (16 bitów danych):
12 DPOKE 709,16911
13 PRINT DPEEK (709)
Teraz Action!. Biblioteka zawarta w kartridżu Action! lub zewnętrzna dostarcza odpowiedniki poleceń z przykładu i są to odpowiednio dla bajtu:
POKE ( RAM, WARTOŚĆ )
gdzie RAM to adres komórki pamięci który zapisujemy WARTOŚCIĄ 16 bitową,X = PEEK ( RAM )
X musi być wcześniej zadeklarowaną zmienną typu Byte, do niej zostanie przepisana zawartość komórki pamięci RAM
Odpowiednikiem operującym na słowie (16 bitów danych) jest:
POKEC ( RAM, WARTOŚĆ )
gdzie RAM to adres słowa w pamięci którą zapisujemy WARTOŚCIĄ,XX = PEEKC ( RAM, WARTOŚĆ )
XX musi być wcześniej zadeklarowaną zmienną typu CARD, do niej będzie przepisana zawartość dwubajtowego słowa o adresie RAM
Przykładowo:
Proc Main()
Byte X
Card XX
Poke (710,2)
X = Peek (710) PrintBE (X)
PokeC (709,16911)
XX = PeekC (709) PrintCE (XX)
Return
Z takiego programu kompilator Action! wygeneruje kod o długości 74 bajtów, lecz żeby taki program działał prawidłowo samodzielnie do kodu trzeba dołączyć kod procedury POKE(), POKEC() i funkcji PEEK() i PEEKC() oraz PRINTBE() i PRINTCE() a co za tym idzie sporą bibliotekę zależnych procedur.
Sama konstrukcja o ile w działaniu prawidłowa jest mało lub wcale nieczytelna w listingu o czym przekonałem się sam niejednokrotnie przeglądając swoje listingi i zastanawiając się co dana komórka pamięci robi. Biorąc do serca wszelkie uwagi i bazując na kilkudziesięcioletnim doświadczeniu zawodowych programistów znacznie lepiej będzie stosować albo bardzo zrozumiałe nazwy zmiennych czy stosowanych komórek pamięci albo stosować nazewnictwo używane np. we wszelkich mapach pamięci Atari. Biorąc to pod uwagę obecny kod stanie się bardziej czytelny:
Proc MAIN()
Card COLPF1S = 709
Byte COLPF2S = 710
COLPF2S = 2
PrintBE (COLPF2S)
COLPF1S = 16911
PrintCE (COLPF1S)
Return
Tym razem listing wygeneruje 40 bajtowy kod, jednakże do jego działania nie będzie potrzebny kod procedury POKE(), POKEC() i funkcji PEEK() i PEEKC() a to skróci cały kod programu jeszcze o kolejne 69 bajtów. Biorąc po uwagę że takich przypisań w listingu programu może być cała masa można sobie wyobrazić jak bardzo taki schemat pisania listingu wpłynie na wielkość programu.
” Cała pamięć jest tablicą „
To zdanie powinien poznać każdy miłośnik języka Action!. Urzekająca genialność tego stwierdzenia objawia się w prostocie użycia.
Na początek deklarujemy tablicę wskazując jej początek na komórkę 0 (zero). Od teraz odwołanie do dowolnego elementu tablicy w rzeczy samej odwoła się do wskazanej komórki pamięci.
PROC MAIN()
DEFINE COLPF1S=”710″
BYTE ARRAY P=0 ; „cala pamiec jest tablica”
P(COLPF1S)=2
PRINTBE ( P(COLPF1S) )
RETURN
Tym razem kod jest niestety dłuższy, za to w zasadzie można by napisać program używając tylko jednej zmiennej. Podobnie można działać z wartością 16 bitową, ale trzeba pamiętać, że w takiej tablicy poruszamy się co 2 bajty oraz troszkę trudniej będzie wyliczać adres słowa. Dla przykładu z początku teraz trzeba nieco „kombinatoryki”:
PROC MAIN()
DEFINE KOLORY=”354″ ; komorki 709 i 710
CARD ARRAY PP=1
PP(KOLORY)=16911
PRINTCE (PP(KOLORY) )
RETURN
Do kompletu Action! posiada jeszcze 3 typy danych „wskaźniki”, możliwość tworzenia struktur typu rekord oraz osadzanie kodu binarnego – co jeszcze poszerza listę możliwości operowania na pamięci.
Jak widać różne zapisy tej samej czynności wynikają z różnych potrzeb, np. program musi być szybki albo kod ma być krótki albo listing ma być prosty, etc. Trudno jednoznacznie orzec jaka metoda będzie najwłaściwsza w konkretnej procedurze, dobrze natomiast pamiętać, że do wyboru są różne możliwości.