Pierwsze kroki w Action! by TDC 2013-04-19 06:09:14
Niedawno wspominaliśmy o nowej stronie WWW traktującej o
programowaniu w
Turbo BASIC XL i Action!. Dziś stronka ta zwiera już nieco
materiałów dotyczących obu języków, w tym właśnie pojawił się
artykuł dla początkujących, dokładnie opisujący podstawowe kroki,
sposoby programowania, kompilowania w Action! oraz wiele innych
niezbędnych informacji nie tylko dotyczących samego języka, ale
również tego jak programuje się Atari.
Oto artykuł, który powinien ułatwić naukę programowania w Action!
tym którzy jeszcze nic o tym nie wiedzą:
Jeśli chcesz postawić swoje pierwsze kroki w Action! to specjalnie
dla Ciebie przygotowałem ten krótki opis, program przykładowy,
który jest mały, fajny i kształcący.
Zalecam wpisanie własnoręczne do edytora Action! tego kodu, gdyż
warto poznać edytor tego języka, który kiedyś był ewenementem na
Atari i innych komputerach. Dziś się wydaje, że takie funkcje jak
zamiana tekstów, znaczniki, praca w kilku okienkach to zupełna
norma, jednak w czasach gdy powstał Action! edytory były bardzo
słabe (szczególnie na pecetach oraz w Uniksie itp.). Na Atari
najczęściej korzystało się z edytora systemowego, który do
wygodnych nie należy (choć pewnie go znasz jako posiadacz Atari,
np. z Atari BASICa).
Nawet jeśli nie zamierzasz pisać dużo w tym edytorze lub ogólnie na
Atari, to warto zapoznać się z możliwościami tego edytora, zapewne
się to przyda (jest wygodny bo jest na cartridge'u więc nie trzeba
czekać aż się załaduje). A już takim absolutnym minimum jest prosta
umiejętność przełączania się pomiędzy edytorem, a monitorem, opcje
wczytywania/zapisywania plików, czy też operowania na dwóch
okienkach (krótki opis klawiatury znajduje się na końcu tego
opisu). Jeśli jednak Atari to dla Ciebie jest wspaniały komputer
oraz kawał wspaniałej historii to powinieneś ten edytor poznać
znacznie lepiej (kiedyś pisałem w nim nawet artykuły do Bajtka). Po
pierwsze może się on po prostu przydać jako dobry i łatwy w użyciu
edytor tekstowy, po drugie warto wiedzieć, że na Atari był dostępny
tak nowoczesny produkt (w końcu warto znać swój ulubiony komputer i
jego oprogramowanie;)
Podkreślę jeszcze, że klawiszologia tego edytora może się na
pierwszy rzut oka wydawać dziwna (bo nie przypomina nic co było
wcześniej na Atari), jednak zapewniam że jest ona bardzo intuicyjna
i wygodna w użyciu.
Gdy już zapoznasz się ze szczegółowym opisem opcji edytora Action!
oraz własnoręcznie przećwiczysz jak się go używa to nie powinieneś
mieć już problemów z pisaniem następnych programów (opisy edytora
były w starych Bajtkach, można je znaleźć w internecie oraz na
końcu tego tekstu znajduje się przegląd istotniejszych
funkcji).
Wtedy już nie ma potrzeby wpisywania poniższego tekstu programu, a
jedynie wystarczy wcisnąć kombinację klawiszy: Shift+Control+R
(uprzednio instalując plik Action_przyklady.atr
(oraz Pigwa)
w pierwszej stacji tzw. "D1:") i wpisać w pasku na dole ekranu:
przykl1.act. Po zatwierdzeniu klawiszem Return, ujrzymy wczytane
źródło poniższego programu do edytora Action!
MODULE
BYTE A, AN=$D40A, LI=$D40B, KOL=$D01A
,KOL1=$D018, K=764, CZAS=20
PROC TU()
WHILE K<>28
DO
KOL=LI+CZAS AN=1
OD
K=42
RETURN
Aby uruchomić ten program, należy:
1. Przejść do monitora Action! (to taki tryb pracy języka związany
z uruchamianiem programów)
W tym celu należy nacisnąć klawisze Shift+Control+M ("M" jak
monitor).
Tym razem pasek jest na górze ekranu, gdzie miga kursor, teraz
pisać można tylko w tej linii.
2. Skompilować program
Wykonujemy to naciskając klawisz "C" ("C" od ang. compile -
kompilacja programu) i zatwierdzamy Return.
Proces ten może zająć więcej czasu jeśli kompilujemy dłuższy
program lub kompilujemy dane z dyskietki (lub jeszcze gorzej z
kasety ;) ), jednak w tym przypadku kompilacja jest natychmiastowa.
Jest to jeszcze jedna zaleta języka Action! bardzo szybko kompiluje
programy (wolno kompiluje jedynie wersja plikowa tego języka,
której nie należy używać). Przypomnę, że w latach 80. kompilatory
bardzo powoli kompilowały (np. kompilatory języka Pascal itp.) oraz
generowały bardzo powolny i długi kod programu.
Kompilacja zakończona sukcesem w Action! nie powinna wyświetlić
żadnego komunikatu, ekran powinien wyglądać tak jak na powyższym
rysunku, czyli tak jak wyglądał zaraz po przejściu do monitora.
3. Uruchomić program
Aby uruchomić program wpisujemy literę "R" ("R" jak Run - działaj)
i zatwierdzamy klawiszem Return.
Brawo ! Uruchomiłeś swój pierwszy program w Action!
Na ekranie powinniśmy zobaczyć animowane kolorowe rurki (tzw.
bary).
Aby opuścić program, należy nacisnąć klawisz "ESC". Dzięki wpisaniu
odpowiedniego polecenia (K=42), w monitorze Action! pojawia się już
litera "E" (przejście do edytora Action!), którą wystarczy
zatwierdzić klawiszem Return, aby ponownie edytować tzw. kod
źródłowy programu (nazywany w skrócie "źródłem").
Opis źródła programu
Teraz opiszę części, z których się składa nasz program oraz to co i
w którym miejscu jest wykonywane, aby osiągnąć ten efekt, który
jest widoczny po uruchomieniu. Postaramy się też nieco ten program
zmienić.
W pierwszej kolejności pewnie chciałbyś się dowiedzieć z jakich
elementów składa się ten program, gdzie jest jego początek, gdzie
się wykonuje itp. Dlatego postaram się fragment po fragmencie to
wyjaśnić.
Pierwszą komendą, która zaczyna ten program jest
MODULE
O dziwo tak naprawdę ta instrukcja nic nie robi, a jedynie pokazuje
początek programu (modułu). Więc skoro nic nie robi, czy jest
potrzebna? Nie jest, jak zapewne widać w innych przykładach z tej
stronki, to słowo kluczowe możemy w wielu programach pominąć. Nie
będę teraz się rozwodził o tym po co i kiedy jest ono potrzebne,
gdyż w wielu Twoich programach nie będzie to miało znaczenia.
Umówmy się jedynie, że zgodnie z dobrym obyczajem programistycznym
wpisuj MODULE na początku programu i już ;)
Następnym elementem są deklaracje zmiennych (globalnych):
BYTE A, AN=$D40A, LI=$D40B,
KOL=$D01A
,KOL1=$D018, K=764, CZAS=20
Zmienne muszą być deklarowane właśnie w tym miejscu programu.
Dodatkowo w stosunku do BASICa, mamy tutaj bardzo ważną różnicę, w
Action! wszystkie wykorzystane zmienne muszą być zadeklarowane.
A co to jest deklaracja zmiennej ? To jest poinformowanie
kompilatora, że z danej zmiennej będziemy korzystać (choć nie ma co
do tego przymusu). Dodatkowymi bardzo istotnymi informacjami są
nazwy używanych zmiennych, ich typ (np. BYTE, CARD, INT itp.) oraz
ew. wartość początkowa.
W BASICu jest taka zasada, że deklaracja zmiennej następuje w
momencie jej pierwszego użycia, jest to dość wygodne (choć niestety
nie mamy kontroli nad tym procesem). W Action! tak nie jest
i może się to wydawać nieco niewygodne, jednak wiąże się z tym
faktem kilka ciekawych rzeczy, przykładowo precyzyjnie określając
typ zmiennej możemy zaoszczędzić miejsce w pamięci RAM (jest to
nieosiągalne w większości języków BASIC).
Co kompilator robi z tymi zmiennymi? Powyższy kod źródłowy nie
wykonuje właściwie nic podobnie jak MODULE, tzn. nie da się takimi
operacjami deklaracji zmiennych zrobić gry w szachy czy warcaby;)
Jednak jak już pisałem są to bardzo istotne informacje dla
kompilatora. Sam uruchomiony program nic nie robi z tymi zmiennymi,
ale wcześniej robi z nimi coś bardzo istotnego sam kompilator. W
procesie kompilacji przydzielana jest pamięć RAM na każdą z tych
zmiennych. Kompilator wie jakiego typu są zmienne więc proces ten
nie stanowi dla niego żadnego problemu. Z drugiej strony oznacza to
tyle, że jeśli zadeklarujemy zmienną, a jej nie użyjemy to zajmiemy
pamięć na marne - i tak faktycznie będzie !;)
Dodatkowo jeśli w programie ustaliliśmy wartość początkową danej
zmiennej to kompilator podczas kompilacji podstawi tę wartość we
właściwe miejsce pamięci (tam gdzie znajduje się zmienna), może to
wyglądać następująco:
CARD ROK=[2013]
Jeśli zmienna nie zostanie zadeklarowana (często się to zdarza, że
zapomnimy) to kompilator zgłosi nam, że nie zna danej zmiennej
zgłaszając błąd numer 8 (czasami można daną zmienną nieprawidłowo
zapisać itp. a kompilator też jej nie rozpozna).
Następną częścią naszego programu jest jego główna procedura, od
której komputer rozpoczyna uruchomienie programu (jego
wykonywanie):
PROC TU()
(...)
RETURN
Procedura może się nazywać (niemal) dowolnie, w tym przykładzie jej
nazwą jest "tu" (od TUtaj program się uruchamia). "RETURN" oznacza
miejsce gdzie jest wyjście z procedury (jej koniec), czyli w tym
przypadku oznacza to także wyjście z naszego programu (zakończenie
go).
Następnym elementem jest pętla typu "WHILE":
WHILE K<>28
DO
(...)
OD
Po WHILE znajduje się warunek wyjścia z pętli (może on być nigdy
niespełniony, czyli tzw. pętla nieskończona). W tym wypadku jest to
K różne od 28 (różne ma oznaczenie w Action! "<>" tak jak w
BASICu oraz "#" czyli nierówne). Zmienna "K" jest specjalną zmienną
w tym programie, która obsługuje (w prosty sposób) naciśnięte
klawisze, a 28 to kod klawisza ESC.
Innymi słowy ten zapis odczytujemy: wykonuj pętlę dopóki zostanie
naciśnięty klawisz ESC.
Słowa kluczowe DO i OD, są ramami określającymi początek oraz
koniec pętli (np. w C/C++ mamy nawiasy "{" i "}"). Wszystkie
instrukcje, które znajdują się między nimi stanowią treść pętli,
czyli kod który będzie wykonywany tyle razy ile na to zezwolą
warunki końca pętli.
Najistotniejszym elementem programu jest to co znajduje się we
wnętrzu pętli, czyli to co on faktycznie wykonuje (w tym wypadku
zmienia kolory ekranu oraz je animuje):
WHILE K<>28
DO
KOL=LI+CZAS AN=1
OD
Zapis KOL=LI+CZAS, może się wydawać bardzo nieczytelny, o ile nigdy
nie programowałeś na komputerze 8bitowym. Jeśli programowałeś w
asemblerze 6502 to zapewne doskonale wiesz co się tutaj dzieje.
Działanie tego programu jest dość specyficzne i ściśle wiąże się z
konstrukcją sprzętową komputerów Atari (która jest bardzo udana,
nowoczesna i zaawansowana).
Jeśli jednak chcesz się dowiedzieć jak to działa to tu znajduje
się skrócony opis:
Zmienna KOL zostaje przypisana do rejestru odpowiadającego za
kolor ramki obrazu. Wpisując do tej zmiennej jakąkolwiek wartość,
spowoduje to bardzo szybki zapis do odpowiedniego rejestru koloru
Atari (odbędzie się to tak szybko jak w asemblerze).
Zmienna LI wskazuje na sprzętowy rejestr zliczający kolejne linie
obrazu rysowane przez procesor graficzny (oznacza to tyle, że
procesor graficzny ANTIC rysując nową linię, wartość tę przekaże do
KOL czyli koloru ramki obrazu).
Natomiast zmienna CZAS to bardzo ciekawe rozwiązanie, mianowicie
system operacyjny Atari, samodzielnie (bez naszego udziału)
odmierza upływ czasu (np. w pewnym momencie uruchomi "wygaszacz"),
dlatego my ten zwiększający się czas używamy do przesuwania się
kolorów. Oczywiście znak "+" dodaje obie wartości do siebie.
Zapisanie dowolnej wartości do zmiennej AN, spowoduje zatrzymanie
się programu do końca rysowania linii obrazu przez procesor
graficzny. Dzięki temu może dziwnemu dla Ciebie rozwiązaniu
jesteśmy pewni, że kolor jaki ustawiliśmy będzie widoczny przez
całą linię obrazu (cały czas jej trwania). To spowolnienie
faktycznie jest bardzo szybkie (odbywa się na chwilę z czasu
trwania rysowania linii obrazu, a odbywa się to kilkanaście tysięcy
razy na sekundę mimo spowolnienia), ale niezbędne, gdyż w
przeciwnym wypadku zmiany kolorów odbywałyby się dużo, dużo za
szybko (oraz nie byłyby zsynchronizowane z pracą procesora ANTIC,
czyli z procesem tworzenia obrazu).
Nie będę szczegółowo wyjaśniał działania tego wydawałoby się
prostego i krótkiego kodu, gdyż wiąże się to ze sposobem działania
układów graficznych Atari oraz sposobem generowania obrazu na
monitorach CRT. Zdecydowanie warto samodzielnie sobie pogłębić tę
wiedzę.
Jeśli jesteś zdziwiony tym co tutaj zobaczyłeś, to pragnę
podkreślić, że to jest jedna z największych zalet Action! że da się
to zrobić tak łatwo, szybko i wygodnie. Faktycznie w 16 znakach
został zapisany cały główny kod programu, który powoduje
narysowanie barów oraz ich animację ! (a da się to zrobić jeszcze
krócej).
Na koniec przed RETURN znajduje się, komenda:
K=42
Jak już pisałem wcześniej zmienna K jest przypisana do rejestru
(tzw. cienia) o adresie 764, czyli odpowiedzialnego za odczyt
klawiatury. To co tutaj robię to zapisuję do rejestru klawiatury,
to dość dziwne bo jeśli przeczytacie jakąś książkę informatyczną to
będą Was przekonywać, że klawiatura jest urządzeniem tylko do
odczytu :P;)
Faktycznie to taki prosty trik, który symuluje naciśnięcie
klawisza. W tym wypadku ma to na celu ułatwienie pracy z programem,
gdyż po zakończeniu programu z dużym prawdopodobieństwem będziemy
chcieli przejść do edytora Action! aby programować dalej (a jeśli
często robimy coś innego to zmieniając kod tego klawisza można
sobie to ustawić do innego celu). Dlatego teraz po zakończeniu
programu w linii monitora zobaczymy literę "E" tak jakby faktycznie
została naciśnięta na klawiaturze. Więc wystarczy ją jedynie
zatwierdzić "Return" i już jesteśmy ponownie w edytorze.
Szczegóły programu
Warto opisać kilka szczegółów związanych z tym programem. Jeśli
ciebie one teraz nie interesują możesz pominąć ten fragment opisu
przeskakując do rozdziału pt. Zrobimy coś innego ?.
Warto wyjaśnić co jest ustalane podczas deklaracji zmiennych:
BYTE A, AN=$D40A, LI=$D40B,
KOL=$D01A
,KOL1=$D018, K=764, CZAS=20
W tym miejscu informujemy kompilator Action! że chcemy w programie
używać 7 zmiennych (faktycznie korzystamy tylko z 6). Wszystkie
zmienne są typu BYTE, czyli zajmują w pamięci RAM najmniejszą
możliwą wielkość (podstawową) jeden bajt. Wszystkie zmienne są
bardzo specyficzne gdyż są przypisane do konkretnych adresów w
pamięci Atari, z wyjątkiem pierwszej zmiennej o nazwie "A". Ta
pierwsza zmienna jest zwykłą zmienną, czyli możemy ją w programie
używać do dowolnych celów (oraz zmienna ta nie ma ustawionej
wartości początkowej).
Pozostałe zmienne za pomocą znaku równości, przesuwają faktyczne
miejsce, w którym się znajdują na wskazany adres. Oczywiście nie
jest to dziełem przypadku, w tych miejscach w pamięci Atari
znajdują się rejestry (lub tzw. rejestry cienie) odpowiadające za
konkretne zachowania się komputera.
Od tej chwili odczyt z tych zmiennych będzie odczytywał wartość
znajdującą się w danym rejestrze, przykładowo jeśli w miejsce
KOL=LI+CZAS AN=1
Wpiszemy:
A=CZAS
PRINTBE(A)
lub krócej:
PRINTBE(CZAS)
po uruchomieniu programu zobaczymy kolejne odczyty zawartości
rejestru odpowiedzialnego za odmierzanie czasu przez system
operacyjny Atari. Tak się składa akurat w tym momencie, że wartości
te będą się co linijkę zwiększać (najczęściej) o jeden.
Skoro zapisaliśmy, że wszystkie zmienne są typu BYTE to oznacza to
tyle, że z każdej zmiennej możemy odczytać wartość typu bajt oraz
zapisać taką samą (wartości z przedziału 0-255). Dotyczy to również
rejestrów większych od bajtu, jeśli jest taka potrzeba to
oczywiście można odczytywać wartości ze zmiennych zadeklarowanych
jako CARD (dwa bajty, wartości z przedziału 0-65535).
A co jeśli przekroczymy zakres zmiennej?
Nastąpi przepełnienie, które gracze zgodnie ze swoimi obserwacjami
nazywają "przekręceniem licznika". Język Action! nic szczególnego
nie robi jeśli zajdzie taka ewentualność. W skrócie odejmując jeden
od zera otrzymamy 255 (bajt) lub 65535 (dwa bajty czyli CARD). To
że Action! nie reaguje na takie sytuacje ukazuje jego jakość, czyli
że jest to język który służy do tworzenia dobrych, szybkich
programów (to jest podobna cecha jak w językach C/C++).
Powróćmy jednak do zmiennych i rejestrów sprzętowych:
Zmienna AN znajduje się w adresie $D40A (to jest zapis wartości
szesnastkowej, oznaczany też czasami np. 0xD40A, D40Ah lub inaczej
- jeśli nie wiesz o co chodzi polecam przeczytanie i dobre
zapoznanie się z tym, np. wstęp
na Wikipedii). Ten rejestr procesora graficznego ANTIC,
powoduje uaktywnienie linii procesora centralnego MOS 6502, która
go zatrzyma na pewien czas (zapis do tego rejestru powoduje
wyzwolenie tego sygnału).
Zmienna LI bardzo podobnie, jednak zapisuje do niej wartości
procesor graficzny podczas rysowania obrazu, więc my będziemy z
tego rejestru odczytywać wartości, a nie zapisywać.
Zmienna KOL to rejestr koloru (to nie jest rejestr cienia) układu
GTIA, który koloruje obraz tworzony przez procesor graficzny. Zapis
do tej zmiennej spowoduje natychmiastową zmianę koloru obrazu.
Odbywa się to bardzo szybko i jeśli coś nieprawidłowo
zaprogramujemy to takie zapisy mogą wywoływać dziwne efekty migania
obrazu (wiele razy na linię)
Druga zmienna KOL1 to kolejny rejestr koloru, przyda się nam zaraz
do drugiego przykładu animacji.
Zmienna K jest wstawiona (podobno :D :D) pod adres cienia o numerze
764 (czyli tym razem zapis dziesiętny, a nie szesnastkowy), rejestr
ten jest specyficznym rejestrem, gdyż określa się go mianem
rejestru cienia. Oznacza to tyle, że do tego rejestru można
zapisywać i odczytywać wartości bez żadnych problemów (ze zwykłych
rejestrów sprzętowych czasami nie można zapisywać lub odczytywać
itp.) oraz że operacja zapisu będzie wywierała efekt jedynie 50
razy na sekundę (60 dla komputerów działających w systemie
NTSC).
Jeśli żaden klawisz nie został naciśnięty odczyt ze zmiennej K
będzie zwracał wartość 255. Jeśli klawisz został naciśnięty to K
zwróci nam kod naciśniętego klawisza. Następnie gdy już go
odczytamy, należy ten rejestr zresetować wstawiając do niego kod
255 (czyli od tej pory komputer "sądzi", że żaden klawisz nie
został naciśnięty).
Można to podglądać wstawiając podobnie jak wcześniej do wnętrza
pętli (kasując wcześniejszą zawartość):
PRINTBE(K)
Po uruchomieniu i sprawdzeniu widać, że (prawie) każdy klawisz ma
swój kod, a naciśnięcie klawiszy w połączeniu z SHIFT i CONTROL
dają inne kody, co można wykorzystać w swoich programach.
Przerwać taki program można również naciskając klawisz Break
(działa jedynie jeśli w programie wykorzystujemy takie procedury
jak PRINT() i inne znane np. z BASICa).
Zmienna CZAS działa podobnie jak K, z tą różnicą, że pod adresem 20
(zapis dziesiętny) system Atari odmierza czas. Odczyt z tego
rejestru podaje nam aktualny czas jaki odmierzył system (zapis do
tego rejestru jest możliwy).
Przykładowo jeśli zamiast 20 wpiszemy wartość 77 to będziemy mogli
odliczać jaki czas upłynął od ostatniego naciśnięcia klawisza
(służy do odmierzania czasu kiedy uruchomiony zostanie wygaszacz
ekranu). Czas ten jednak jest odmierzany dość specyficznie,
mianowicie wartość jest zwiększana, wtedy kiedy rejestr 20 doliczy
do 255 (czyli nie jest to sekunda, ani minuta itp.).
Skoro już wiemy co i jak może być wykorzystywane za pośrednictwem
tych zmiennych, to może jeszcze raz skupimy się na tym co program
robi w głównej pętli:
KOL=LI+CZAS AN=1
Mamy tutaj dwie oddzielne operacje podstawienia. W pierwszej
odczytywane są wartości ze zmiennych (faktycznie rejestrów) LI oraz
CZAS, sumowane, a następnie wynik jest zapisywany do rejestru
koloru opisanego zmienną KOL.
Wartości zapisywane do tego rejestru mają niejako "aktywne" jedynie
7 bitów (z 8 dostępnych w tym bajcie) co oznacza, że widocznych
kolorów jest maksymalnie 27=128. Konkretnie jest to 16
kolorów w 8 odcieniach - dość sporo jak na komputer 8bitowy (i to
sporo starszy od ZX Spectrum i Commodore 64).
Ostatnia operacja podstawienia, wstawia wartość 1 do rejestru AN,
który właśnie jest "wrażliwy" na operacje zapisu. Jak wyjaśniałem
powoduje to chwilowe zatrzymanie się głównego procesora w celach
wizualnych;)
Dla tego rejestru nie ma znaczenia jaka wartość będzie zapisana.
Istotne jest jedynie aby zaistniała stosowna reakcja, gdy zapis
zostanie stwierdzony.
Następnie dzięki pętli WHILE cała operacja jest wykonywana na
okrągło (bez końca), aż nie przerwiemy tego naciśnięciem klawisza
ESC. Efekt jest taki, że gdy zmieni się wartość rejestrów LI+CZAS
(czyli albo zmiana numeru linii albo zwiększenie czasu) to kolory
zmienią się.
Jeśli zainteresowała Ciebie możliwość wykorzystywania cech
rejestrów sprzętowych Atari w programowaniu to oczywiście pragnę
wyjaśnić, że podobnych rejestrów, które można fajnie wykorzystać
jest bardzo dużo - właściwie rekordowo ! Programowanie tego rodzaju
jest kwintesencją programowania na komputerach takich jak Atari czy
Commodore 64. Jednak sprzęt ten ma do zaoferowania jeszcze więcej,
jeśli już jesteś zachwycony to zapewne ucieszysz się, że na
operowaniu rejestrami zabawa się absolutnie nie kończy. Warto
zapoznać się z wszystkimi trybami graficznymi Atari (procedura
GRAPHICS(n)), sprzętowymi duszkami (wiele można z nimi w Action!
zrobić!), a szczególnej uwagi wymaga program procesora graficznego
ANTIC, tzw. display list, który jest niezwykłym cudem dla każdego
kto się nim miał możliwość pobawić (warto wspomnieć o jego
przerwaniach tzw. DLI).
Aby pogłębić wiedzę odnośnie np. rejestrów Atari, należy zapoznać
się z jakimś opisem tzw. mapa pamięci Atari itp.
Kilka słów o procedurach PRINT()
Jak demonstrowałem wyżej, wstawiając do głównej pętli programu
instrukcję tego rodzaju, można wyświetlać na ekranie jakieś zmiany
w systemie lub w naszym programie podobnie jak ma to miejsce w
BASICach (np. print lub ?). Wyświetlanie takie można zatrzymać na
chwilę kombinacją Control+1 oraz przerwać (program) naciskając
Break.
W Action! znajduje się spora ilość wariantów tej procedury. Jeśli
przykładowo chcemy wyświetlać wartości typu BYTE, możemy napisać
tak:
BYTE CZAS=20, K=764
PROC TU()
WHILE K<>28
DO
PRINTBE(CZAS)
OD
K=42
RETURN
Jeśli chcemy wyświetlać je wypełniając kolejne linie możemy to
zrobić np. tak:
PRINTB(CZAS) PRINT(", ")
Jeśli chcemy wyświetlić (poprzednim sposobem) wartości typu CARD,
robimy to np. tak:
BYTE K=764
CARD ZLICZ=[0]
PROC TU()
WHILE K<>28
DO
PRINTCE(ZLICZ)
ZLICZ==+1
OD
K=42
RETURN
Teraz program będzie odliczał zaczynając od 0 a kończąc na końcu
zakresu zmiennych typu CARD, czyli 65535.
Pewnie już zauważyłeś, że PRINTB() wyświetla zwartość zmiennej typu
BYTE, a PRINTC() wyświetla wartości typu CARD. Natomiast PRINT()
wyświetla tekst bez przejścia kursora do nowej linii, natomiast
PRINTE() z przejściem do nowej linii. Odbywa się to nieco na wzór
roli znaku ";" w BASICach. Można też łączyć wypisywanie wartości z
przejściem do nowej linii: PRINTBE() lub PRINTCE().
Należy podkreślić, że w Action! nie istnieje zapis skrócony "?"
znany z BASICów. Natomiast w to miejsce istnieje możliwość
napisania własnych procedur piszących oraz rysujących, które będą
działały bardzo szybko, mimo braku wykorzystania asemblera (szybkie
procedury piszące są o tyle istotne, że wiele gier powstaje w
trybach tekstowych, np. polskie gry Fred, Misja i wiele
innych).
Zrobimy coś innego ?
A teraz zademonstruję jak łatwo jest ten program (przykład1)
zmodyfikować osiągając zupełnie inny rezultat. Zmieńmy jedynie
zawartość pętli z:
KOL=LI+CZAS AN=1
Na:
KOL1=LI+CZAS AN=1
(po zmiennej KOL został dodany jedynie znak "1", który musi
znajdować się zaraz za KOL bez żadnego odstępu)
Teraz uruchom program i sprawdź co się zmieniło.
Zmieniło się coś? A jakże !;)
Jak widać posiadając taki szkielet programu w Action! zawierający
główną pętlę programu oraz kilka zadeklarowanych zmiennych, mamy
absolutne minimum aby programować dalej. Teraz nawet tak niewielkie
zmiany (zmiana tylko jednego znaku!), mogą w rezultacie dawać
zupełnie inne rezultaty ;)
Witam Ciebie w świecie Action! ;)
Kompilacja programu do pliku
Zapewne chciałbyś umieć ten program zapisać do pliku, aby np.
posłać go znajomemu lub udostępnić w internecie (choć ten program
może jest zbyt prosty aby od razu go zamieszczać ;)
Wykonuje się to bardzo prosto. Przechodzimy do monitora Action!
naciskając klawisze Shift+Control+M, wybieramy opcję C (klawisz "C"
+ Return). Po zakończonej kompilacji wydajemy polecenie zapisania
skompilowanego kodu do pliku wykonywalnego, pisząc np.
W "D:nazwa.xex"
Od tej pory program został zapisany do pliku i można go uruchomić z
poziomu np. DOSa. Najczęściej spotykanymi rozszerzeniami plików
wykonywalnych są "com", "exe" oraz "xex", który przyjął się ze
względu na powszechność emulatorów Atari.
Przed wykonaniem powyższych kroków warto usunąć z końca programu
linię:
K=42
Jest ona niepotrzebna jeśli program ma być uruchamiany nie z
poziomu Action! ale np. DOSa. Kasowanie takiej linii można wykonać
nie tylko poprzez fizyczne skasowanie zawartości linii, można to
też wykonać poleceniem REM (z BASICa), czyli w Action! za pomocą
średnika, a prezentuje się to następująco:
;K=42
Tak rozpoczynająca się linia jest traktowana przez kompilator jakby
nic nie zawierała (konkretnie od znaku średnika jest wszystko
ignorowane do końca linii).
Jeszcze inną opcją jest zamiana na:
K=255
Czyli kasowanie bufora klawiatury, choć to już zależy od tego co
chcesz osiągnąć.
Tu muszę jednak wyjaśnić jedną kwestię. Język Action! od samego
początku został tak zaprojektowany, że miał być dostępny tylko na
cartridge'u (to rzadkość bo zwykle języki programowania się robiło
i dziś robi również, aby się je wczytywało i uruchamiało z plików),
dlatego program zapisany do pliku powyższą metodą, zwykle wymaga
posiadania takiego cartridge. Jednak nie w tym przypadku - program
z pierwszego przykładu nie wykorzystuje nic co się znajduje w
pamięci stałej (ROM) tego języka, więc będzie można go uruchomić na
każdym komputerze Atari (w najgorszym przypadku może jedynie
nastąpić kolizja z jakimś innym DOSem, który będzie sprawiał jakieś
problemy).
Jeśli wykorzystamy w naszym programie jakieś standardowe elementy
języka Action! które znajdują się w pamięci ROM cartridge, to
pojawi się pewien problem. Wtedy trzeba przejść nieco inną
procedurę przygotowania pliku tak aby się uruchamiał u każdego (to
będzie opisane w oddzielnym artykule na stronce Turbo Basic XL &
Action!).
Elementami, które powodują takie problemy są:
1. Używanie procedur bibliotecznych np. PRINT(), GRAPHICS(),
POKE(), PEEK(), PLOT(), DRAWTO(), OPEN() itp.
2. Używanie operacji mnożenia i dzielenia (procesor 6502 nie
posiada takich operacji)
3. Używanie większej ilości parametrów procedur i funkcji niż 3
bajty.
Widać wyraźnie, że nasz program nie wykorzystuje żadnego z wyżej
wymienionych elementów.
Na koniec warto podkreślić, że nasz program z przykładu pierwszego
po kompilacji zajmuje w pamięci jedynie 38 bajtów ! To pokazuje, że
Action! generuje nie tylko kod szybki, ale też mały, a oszczędność
na komputerach 8bitowych jest bardzo istotna.
Dla kontrastu podam, że nic nierobiący program (czyli nie
posiadający żadnych operacji wykonywanych wewnątrz procedury
wykonywanej po uruchomieniu programu) dla dzisiejszego peceta może
zajmować 40-60 kb i więcej (czyli tyle ile ma całkowitej pamięci
Atari 65 XE lub Commodore 64 :P).
Masz jakieś pomysły, chcesz coś jeszcze ciekawego zaprogramować w
Action!?
Teraz już wiesz od czego zacząć, ja mogę już tylko powiedzieć: do
dzieła!;)
Najczęściej używane funkcje Action!
1. monitor:
Wymienię kilka przydatnych operacji jakie są możliwe do wykonania w
trybie monitora.
- komenda X umożliwia wykonanie dowolnej procedury
bibliotecznej Action! (znajdującej się w ROMie cartridge'a z tym
językiem), przykładowo:
X GRAPHICS(0)
X POKE (712,255)
operacje te muszą być napisane zgodnie ze składnią języka (nie
posiadać żadnych błędów, np. muszą być zamknięte wszystkie nawiasy
itp.)
Jest to odpowiednik natychmiastowego wykonania instrukcji w języku
BASIC, czyli wpisanie polecenia bez numeru linii. Jednak w Action!
ma to bardziej cel testujący czy debugujący, niż taki jak w BASICu.
Wynika to z tego, że do tego celu w Action! służy drugie okienko
tekstowe, w którym zawsze możemy napisać jakiś krótki kod i
uruchamiać go przemiennie z tym podstawowym.
- SET - umożliwia wstawienie wartości do podanego adresu,
np.
SET 712=255
- ? - wyświetla wartości zapisane w danym adresie, np.
? 712
W pierwszej kolejności widzimy adres (tu 712), ten sam adres
zapisany szesnastkowo, wartość zapisaną jako znak ATASCII, wartość
zapisaną jako dwa bajty szesnastkowo oraz dwa bajty w zapisie
dziesiętnym
- * - działa podobnie jak "?", ale wyświetla kolejne
bajty.
Zatrzymać ten proces możemy na chwilę naciskając Control+1, a
następnie zwalniamy tą samą kombinacją (to ważne bo inaczej nie
będzie można pisać za pomocą klawiatury!). Przerywamy tryb
monitorowania pamięci klawiszem spacji.
- B - bootowanie języka Action! (kasowanie wszystkich danych
w pamięci)
Z racji swej roli wymaga potwierdzenia klawiszem "Y". Jeśli go
naciśniemy widzimy Action! taki jakby dopiero co został
uruchomiony.
- O - przejście do wyświetlania/zmieniania opcji kompilacji
i edycji
Chcąc zmienić daną opcję wpisujemy odpowiednią wartość (tekstową
lub liczbową), jeśli chcemy pominąć to naciskamy Return, a jeśli
chcemy opuścić tryb zmian opcji naciskamy ESC.
- D - przejście do DOSa
- E - powrót do edytora Action!
2. Edytor:
Shift+Control+Góra - przesunięcie się o jeden ekran w górę
(zależy od aktualnych ustawień wielkości okienka edycyjnego) Shift+Control+Dół - przesunięcie się o jeden ekran w dół
(--"--) Shift+Control+, - przesuwanie podglądu edycji w lewo (nie
działa pod emulatorem Altirra w wersji np. 2.20) Shift+Control+. - przesunięcie podglądu edycji w prawo
(--"--) Shift+Control+E - przeskoczenie do końca tekstu Shift+Control+Return - wstawienie pustej linii lub podział
linii na dwie (w miejscu kursora) Shift+Control+Backspace - połączenie bieżącej linii z linią
znajdującą się wyżej (o ile kursor znajduje się na początku
linii) Shift+Control+T - ustawianie znaczników Shift+Control+U - Undo - działa nieco inaczej niż dziś się
do tego przyzwyczailiśmy. Działa tylko odnośnie aktualnej linii do
czasu aż jej nie opuścimy (czyli przywraca zmianę tej jednej linii
od czasu, gdy przesunięty został na nią kursor) Shift+Delete - kasowanie kolejnych linii oraz wstawianie ich
do "schowka" (odpowiednik Control+X itp.) Shift+Control+P - wstawianie tekstu ze "schowka" do
aktualnego okienka edycyjnego (odpowiednik Control+V itp.) Shift+Control+I - przełączanie się pomiędzy dwoma trybami
edycji INSERT i REPLACE. Pierwszy jest naturalny dla użytkowników
edytorów dla małego Atari, drugi będzie bardziej intuicyjny dla
osób przyzwyczajonych do współczesnych edytorów dla dużych
komputerów Atari, Apple lub pecetów.
Shift+Control+R - wczytanie pliku tekstowego (również
ponowne, czyli dołączenie pliku do tekstu) Shift+Control+W - zapis pliku tekstowego z aktywnego okna
edycyjnego (źródło programu) Shift+Control+1 lub 2 - przejście między oknami
edycji Shift+Control+D - zamknięcie aktywnego okienka (bez zapisu
zawartości)
Clear - kasowanie zawartości aktywnego okienka bez zamykania samego
okienka Shift+Control+M - przejście do monitora Action! Shift+Control+F - szukanie ciągu znaków w tekście programu
(lub innego edytowanego pliku tekstowego) Shift+Control+S - zamiana ciągów znaków
Ciągi tekstowe wpisywane w operacjach takich jak np. R, W, F, S
itp. są zapamiętywane i proponowane po ponownym użyciu. Możemy je
wykorzystać, skasować lub edytować naciskając Backspace.
W edytorze działa też wiele typowych dla Atari kombinacji klawiszy,
jednak mogą one działać nieco inaczej, gdyż edytor Action! został
przemyślany nieco inaczej niż systemowy edytor (czyli został
zaprojektowany bardziej elastycznie, udostępniając wiele nowych
możliwości).
Zachęcam do eksperymentowania, kiedyś Action! stanowił na Atari (i
nie tylko) zupełnie nową jakość, dziś warto o tym wiedzieć oraz
przekonać się o tym własnoręcznie;)
wieczor 2013-04-19 07:22:40
Dlaczego jak zobaczyłem artykuł na 76 ekranów to wiedziałem czyj podpis znajdę na końcu... :P :P :P larek 2013-04-19 09:08:15
Ja, gdy zobaczyłem w tytule słowo "Action!" to już wiedziałem czyj podpis znajdę na końcu ;) arturkb 2013-04-19 09:29:33
O właśnie tego szukałem, dzięki :) wieczor 2013-04-19 09:52:04
@arturkb: podpisu? :D tdc 2013-04-19 17:55:15
Tak, podpis jest najważniejszy :) xxl 2013-04-19 19:58:33
> Konkretnie jest to 16 kolorów w 8 odcieniach - dość sporo jak na komputer 8bitowy (i to sporo młodszy od ZX Spectrum i Commodore 64).
kataryna jest starsza od tych dwoch komputerow.
a odnosnie Action! - brakuje podstawowych informacji np. jak kompilowac program pod konkredny adres, ale to bedzie pewnie w drugim odcinku?
:) pin 2013-04-20 00:01:09
.. żeby działało tylko na xBIOS? - nie ma takiej (logicznie uzasadnionej) konieczności :P tdc 2013-04-20 02:05:26
Dzięki xxl, oczywiście miało być starszy ;)
Nie zakładałem aby kompilacja pod wskazany adres była potrzebna początkującym programistom Action! Wychodziłem z założenia, że muszę tutaj podać rzeczy, które w praktyce się każdemu przydadzą, a kontrola adresu w Action! nie ma takiego znaczenia jak np. w asm, można napisać wiele programów i gier nie wiedząc, że taka możliwość w ogóle istnieje.
Zakładałem, że moje doświadczenie w korzystaniu z tego języka da wartościowe zestawienie tego co faktycznie jest niezbędne aby rozpocząć przygodę z tym językiem. Takiej wiedzy w necie nie ma, natomiast to jak zmienić adres znajduje się w każdym manualu dostępnym w necie itp.
No ale skoro już o to pytasz to należy na początku programu wpisać: SET 14=adres SET $491=adres
W wielu wypadkach wystarczy tylko SET 14=adres tdc 2013-04-20 02:43:43
Jeszcze jedna bardzo przydatna rzecz, wczytywanie do edytora spisu dyskietki (tylko urządzenie D:).
Jeśli nie chcesz przechodzić do DOSa lub Twój DOS jest tak kapryśny, że kasuje zawartość pamięci po wyświetleniu listy plików to pozostaje ostatnia możliwość:
Wciskamy Shift+Control+R i zamiast podawania nazwy pliku wpisujemy, np.
?1:*.*
(gdzie "1" to jest numer dysku D:) Jeśli wykonamy to będąc w drugim okienku edytora Action! to w pierwszym możemy bez problemu kontynuować programowanie, a w drugim mamy stały podgląda zawartości dyskietki. xxl 2013-04-20 10:08:19
> żeby działało tylko na xBIOS? - nie ma takiej (logicznie uzasadnionej) konieczności :P
xBIOS has you!
Pin... zeby mozna bylo pisac programy w Action do umieszczenia na karcie... ale wedlug Ciebie "nie ma takiej (logicznie uzasadnionej) konieczności"
Pin... zeby mozna bylo produkowac wielosegmentowe programy ale wedlug Ciebie "nie ma takiej (logicznie uzasadnionej) konieczności"
Pin... zeby mozna bylo pisac w Action patche do programow lub gier ale wedlug Ciebie "nie ma takiej (logicznie uzasadnionej) konieczności"
Pin... wiecej wyobrazni ;-)
Tdc: a jak umiescic konkretna procedure pod konkretnym adresem? Czy Action moze generowac kod wynikowy z wieloma naglowkami? jhusak 2013-04-20 20:40:36
@tdc, pojechałeś :)
Teraz to już każdy będzie w Action! pisał :D tdc 2013-04-20 21:02:28
@xxl, a Action! jest inna "ideologia" ;) Tam się częściej importuje jakiś zewnętrzny kod i przypisuje go do jakiejś procedury. Dzięki temu jak ktoś chce to może sobie użyć dowolnego innego języka, choć najczęściej jest to oczywiście asm.
Natomiast jakby się uprzeć to można próbować, zrobić coś takiego:
(...)
SET 14=adres SET $491=adres
PROC proc1() (...) RETURN
SET 14=* SET $491=*
PROC proc2() (...) RETURN
Wtedy proc1() będzie pod wskazanym adresem, a pozostały kod rozpoczynający się od proc2() będzie się kompilował w następnym wolnym adresie. Jednak nigdy do niczego to mi nie było potrzebne więc nie wiem czy takie zmienianie adresów będzie działało dla takich wyrwanych z kontekstu procedur. Kiedyś mieliśmy taki zamiar wraz z Konopem, ale w końcu tego nie zrobiliśmy. Jeśli ktoś próbował takich czarów to niech wyjaśni jakie ma doświadczenia w tej materii.
@kuba, sam jesteś tego najlepszym przykładem, wiele gier, dem napisanych w Action! Wtedy nie było na Atari żadnego lepszego języka programowania, a ze świecą szukać takiego na innych kompach.
A co do pisania w Action! to wydaje mi się że jest to język dla atarowych purystów, którzy lubią real sprzęt, prawdziwą klawiaturę oraz oryginalne oprogramowanie. Natomiast jeśli ktoś wybitnie lubi dzisiejsze środowiska to pewnie znacznie lepszym dla niego rozwiązaniem będzie cc65. tdc 2013-04-20 22:56:06
Sprawdziłem, że powyższe nie działa, bo owe SETy zmieniają systemowy wskaźnik Action! więc SET 14=*... nie przywraca go. tdc 2013-04-20 23:08:27
Podłubałem w tym chwilkę i chyba się tego nie da zrobić bo w Action! nie ma takich możliwości jakie są np. w C/C++.
Można zmienić w trakcie kompilacji adres docelowy tak jak pisałem:
SET 14=adres SET $491=adres
I można tak robić w wielu miejscach, wtedy kod zostanie skompilowany w każdym takim przypadku pod wskazany adres (czyli rozrzucamy kod po pamięci operacyjnej). Coś takiego się kompiluje i uruchamia.
Dodatkowo możemy sobie gdzieś zapisać adres na jakim Action! w danym momencie skończył kompilacje (np. przed zmianą adresu), w taki sposób:
SET $6F0=*
Niestety tylko nie wiem jak teraz to przywrócić w trakcie kompilacji.
Wychodzi na to że kod najłatwiej rozczłonkować, gdy nie chcemy potem powrócić pod właściwy adres (czyli ten zapisany w tym przykładzie w $6F0).
Ostatnim rozwiązaniem jest samodzielna kontrola tego co ile zajmuje i sztywne przydzielanie właściwych adresów właściwym fragmentom kodu, ale tutaj zaczynamy się powoli bawić ręcznie w kompilator... pin 2013-04-21 01:12:43
XXL - nie to, by nie było wiadomo co można a czego nie pod Action!. Zastanawiałem się tylko co na tę okazję napiszesz. Zaskoczenia nie było raczej ;)- Taka ot sobie niszowa prowokacyja :D Przepraszam. tdc 2013-04-21 04:11:00
Przyszło mi do głowy takie rozwiązanie, jeśli przykładowo chcemy kompilować kod na 6 stronę, gdzie miejsca jest mało można zrobić tak:
MODULE
BYTE A
(...)
PROC (...) () RETURN
(...)
PROC procedura_pomocnicza() ;procedura zawiera cały kod np. z głównej procedury programu (o ile jest tego dużo) (...) RETURN
PROC (...) () RETURN
SET 14=$600 SET $491=$600
PROC proc1() (...) RETURN
PROC proc2() (...) RETURN
(...)
PROC main() procedura_pomocnicza() RETURN
Dzięki temu główna procedura zostanie skompilowana również na 6 stronę, ale zajmie jedynie 7 bajtów, co może się jeszcze zmieści. damek 2013-04-21 11:12:22
tutorial FORTHa, please! to jest dopiero język mindfucker :) . paptak 2013-04-21 11:38:55
Tego mi właśnie było trzeba. tdc 2013-04-21 16:54:21
@damek, niestety nie znam nikogo kto by się zajmował tym językiem. Jedyne co mogę powiedzieć to że jak ktoś podeśle do mnie taki opis to opublikuję go - kto nas wesprze? ;) Bluki 2013-04-21 23:22:30
A po co cokolwiek pisać lub podsyłać (FORTH), skoro już jest? 1. Biblioteka Atarowca: Jan Ruszczyc, "Poznajemy FORTH" . 2. "Tajemnice Atari" od numeru 1/92 kurs programowania w FORTH. tdc 2013-04-21 23:41:53
Faktycznie, zapomniałem, dzięki Bluki.
Co jednak nie znaczy że ktoś kto się na tym języku zna nie mógłby dla nas przygotować jakiegoś własnego opisu. wieczor 2013-04-22 00:44:47
A o Action! SOETO niczego nie wydało? Przepraszam jeśli gadam bzdury, ale stary jestem i coś mi się tam pod czaszką telepie... Bluki 2013-04-22 01:24:59
Tylko w "Językach programowania" cz. 2, W. Zientary wydanych przez SOETO. Jeżeli opis Action! w tej książce reprezentuje taki sam poziom jak opis TBXL i Microsoft BASIC-a, to nie polecam... tdc 2013-04-22 02:00:39
Jest tam zawarta pewna część informacji zdecydowanie dla początkujących (w Action! a nie w programowaniu).
Jest: opis klawiatury w edytorze (chyba pełny) oraz opcji monitora, opis typów danych, operatorów arytmetycznych, słów kluczowych w Action! (z błędem), opis podstawowych instrukcji z prostymi przykładami, opis procedur bibliotecznych oraz kody błędów (Action! oraz DOSa). tdc 2013-04-24 02:58:23
Do artykułu dodałem filmik z YT, prezentujący lekcję programowania w Action! kod programu jest dostępny na załączonej dyskietce ATR.
Dodatkowo dodałem dodatkowy link do tego pliku ATR tym razem na Pigwie.