Dzisiejszy odcinek wspomnień z dzieciństwa należy do
Adama
"Golem XIV" Milewskiego. Adam miał nieodpartą chęć
zrealizowania pewnego programu w Turbo Basicu i ta sprawa męczyła
go przez wiele lat. Ponieważ my się tu zajmujemy rozwiązywaniem
męczących spraw z przeszłości :), artykuł Adama znalazł należne
sobie miejsce. Dalej już niech snuje swoją opowieść sam autor:
Chciałbym tu opowiedzieć historię mojej fascynacji Atari oraz
niebudzącym poważania językiem programowania – Atari BASIC.
Przygoda rozpoczęta wiele lat temu znalazła swój epilog dopiero
niedawno i to w chwili, kiedy nie spodziewałem się, że do niej
wrócę. Zacznijmy od początku.
Historia
W roku 1994, w trakcie moich studiów na Wydziale Fizyki UMK w
Toruniu, poznałem faceta o ksywie
Olo, który posiadał
komputer Atari 800 XL ze stacją dyskietek LDW2000. Pochodziliśmy z
tego samego miasta, przy czym ja na uczelnię dojeżdżałem, a on
mieszkał na stancji. Co jakiś czas jednak pakował Atarynkę, stację
i zielony monitor do wielkiej torby i przywoził do domu rodzinnego.
Dzięki temu udało mi się parę razy wypożyczyć ten sprzęt na dłuższy
czas. Mając mikrokomputer Atari można było bawić się grami do
zanudzenia, jak i próbować wykorzystać go w bardziej ambitny
sposób, w czym doskonale pomagała stacja dysków. Ponadto Olo,
oprócz masy gier, miał również spory zapas branżowych czasopism
oraz książkę o Atari BASIC.
BASIC i wykresy 3D
Początki moich zabaw w programowanie związane były z przepisywaniem
programów z książki oraz "Tajemnic Atari". Irytowało mnie jednak,
gdy po kilkudziesięciu minutach wklepywania tysięcy liczb i liter,
mogłem sobie jedynie pograć w prostą odwracankę w trybie znakowym.
Bardziej podobały mi się wszelkie perełki w rodzaju konkursu „5
linii” czy „szósta strona”, gdzie w oszczędnej formie ludzie robili
niesamowite rzeczy z komputerem. Ja też postanowiłem napisać coś
fajnego. Wybór padł na program do rysowania wykresów 3D w oparciu o
równania typu: z=sin(x)+cos(y); w różnych wariacjach.
Mój program bazował na przykładzie, który znalazłem bodajże w
"Bajtku", dla komputera Commodore. Właściwie należy powiedzieć, iż
był to program do rysowania jednego konkretnego wykresu - zaszytego
w algorytmie wyliczającym. Stworzenie programu, w którym podawałoby
się własny wzór, było dla mnie zbyt ambitne. Mimo to praca nad nim
dostarczyła mi wiele frajdy. Niestety jego główną wadą był czas
wykonywania, który wahał się w okolicy 20 minut. Oczywiście w w
tamtym czasie normą było powiedzenie: "Uruchom program komendą RUN
i idź zaparzyć sobie herbatę/kawę lub wyskocz na piwo".
Bez wątpienia program wymagał dodatkowych poprawek. Zacząłem więc
kombinować z jego przyśpieszeniem w ramach wiedzy, jaką posiadałem
na temat Atari BASIC oraz funkcji trygonometrycznych. Oj, było tego
sporo... między innymi:
- optymalizacje pętli, która według pierwotnego zapisu,
wielokrotnie liczyła te same wartości.
- obliczanie wartości sinus i cosinus do dwóch tabel w osobnej
pętli na początku program (sięganie do tabeli w pętli rysującej
wykres było szybsze niż wielokrotne liczenie sinusów). Ponadto
wyłączenie obrazu w trakcie tych obliczeń znacząco przyśpieszało
program. Można było oczywiście wyłączyć go również w trakcie
rysowania i oglądać dopiero efekt, ale cały smak leżał w
obserwowaniu procesu rysowania.
- zastosowanie różnych sztuczek przydatnych w BASIC-u typu:
pisanie w jednej linii, itp.
W ostateczności listing się skomplikował - ale program działał
szybciej. Jedyną jego wadą był już tylko włączony przez kilka minut
obraz, kiedy obliczały się sinusy i cosinusy. Ostateczne circa 9
minut to był sukces!
Pożegnanie z Atari
Moje studia skończyły się po pierwszym semestrze, choć znajomość z
Olo przetrwała jeszcze jakiś czas. Kiedy zacząłem pracować, a Olo
przeniósł się na inne studia, nasze kontakty ustały. Parę razy
spotkaliśmy się jeszcze „na mieście”. W trakcie jednego z tych
spotkań okazało się, że Olo przekazał młodszym kuzynom komputer
wraz z dyskietkami i w ten sposób efekty moich prac przepadły. Był
to oczywiście ów program "Wykresy 3D", ale także prosta gra (o
której chciałbym kiedyś napisać - może ktoś ją przełoży na kod
maszynowy).
W trakcie użytkowania Atari oraz później, męczyło mnie jedno
pytanie: jak szybko mój program działałby napisany w innym języku
programowania? Interesowały mnie zwłaszcza Pascal, assembler oraz
inne odmiany BASICa (szczególnie Turbo BASIC). Kod maszynowy
wydawał mi się zbyt trudny, zaś Pascal i Turbo BASIC były dla mnie
niedostępne w okresie użytkowania Atari. Jednakże przez wszystkie
te lata odczuwałem wielką potrzebę by sprawdzić, jak szybko mój
program działałby chociażby w mitycznym i „4 razy szybszym” Turbo
BASIC'u.
Zaspokojenie ;)
Mimo korzystania z emulatora Atari pod Windows i Linux nigdy nie
pokusiłem się o zaspokojenie mojej ciekawości, głównie z powodu
braku oryginalnego programu i konieczności odtworzenia go na nowo.
Jednakże pod koniec 2007 roku trafiłem na opis programu "Wykresy
3D" z "Bajtka" (Marcin Borowski, Trójwymiarowe wykresy, Bajtek nr
8/88, strony 24-25). Postanowiłem więc, że zrealizuję moje marzenie
sprzed lat - sprawdzę, jak bardzo szybszy od Atari BASIC jest Turbo
BASIC, czyli ile czasu zaoszczędziłbym kiedyś stosując ten drugi,
zamiast pierwszego.
Stało się – przepisałem program - nie jest on dokładnie tym sprzed
lat, ale robi to samo, tylko na nieco prostszym równaniu. Program,
przetestowałem w różnych wariacjach na emulatorze Atari800Win 4.0
ze standardowymi ROM'ami i pamięcią ustawioną na 320 KB (compy) na
Atari BASIC'u i Turbo BASIC'u XL 2.0.
Pierwotny, nieoptymalizowany listing programu wygląda
następująco:
5 POKE 18,0:POKE 19,0:POKE 20,0
10 PI=3.14159
15 A=COS(PI/4)
20 DIM M(255)
25 GRAPHICS 8
30 COLOR 1
35 REM POKE 559,0:REM WYLACZENIE OBRAZU
40 FOR Y=1 TO 141 STEP 5
45 E=A*Y
50 C=(Y-70)*(Y-70)
55 FOR X=1 TO 141
60 D=X-70
65 Z=60*EXP(-1.0E-03*(C+D*D))
70 X1=X+E
75 Y1=Z+E
80 IF Y1>=M(X1) THEN M(X1)=Y1:PLOT X1,160-Y1
85 NEXT X
90 NEXT Y
95 PRINT INT((PEEK(18)*65536+PEEK(19)*256+PEEK(20))/50)
100 REM POKE 559,34:REM WLACZENIE OBRAZU
105 FOR S=0 TO 254:M(S)=0:NEXT S:REM LINIA 105 ZBEDNA W TURBO
BASIC
Program zoptymalizowany wygląda zaś tak:
5 POKE 18,0:POKE 19,0:POKE 20,0
10 A=COS(3.14159/4)
15 DIM M(255)
20 GRAPHICS 8:COLOR 1
25 REM POKE 559,0:REM WYLACZENIE OBRAZU
30 FOR Y=1 TO 141 STEP 5:E=A*Y:C=(Y-70)*(Y-70)
35 FOR X=1 TO 141:D=X-70:Y1=E+60*EXP(-1.0E-03*(C+D*D)):X1=X+E
40 IF Y1>=M(X1) THEN M(X1)=Y1:PLOT X1,160-Y1
45 NEXT X:NEXT Y
50 PRINT INT((PEEK(18)*65536+PEEK(19)*256+PEEK(20))/50)
55 REM POKE 559,34:REM WLACZENIE OBRAZU
60 FOR S=0 TO 254:M(S)=0:NEXT S:REM LINIA 60 ZBEDNA W TURBO
BASIC
Jak widać, nie było tu dużo do „optymalizowania”, a to ze względu
na małą złożoność obliczeń w pętli głównej oraz brak
skomplikowanych obliczeń sinusów i cosinusów. Ponadto w Turbo
BASIC'u nie trzeba stosować czyszczenia tablicy M(), co robione
jest odpowiednio w liniach 105 i 60 (konieczne w Atari BASIC'u
jeśli chcemy uruchamiać program wielokrotnie). Jak widać w listingu
dodano też rozkazy POKE 559,0 i POKE 559,34 odpowiedzialne za
wyłączenie obrazu i włączenie go w celu prezentacji wyników. Wyniki
testów prezentuje poniższa tabela:
język programowania |
optymalizacja |
wyłączony ekran |
czas |
1. Atari BASIC |
nie |
nie |
9m 29s |
2. Atari BASIC |
nie |
tak |
7m 07s |
3. Atari BASIC |
tak |
nie |
9m 19s |
4. Atari BASIC |
tak |
tak |
7m 00s |
5. Turbo BASIC 2.0 XL |
nie |
nie |
2m 48s |
6. Turbo BASIC 2.0 XL |
nie |
tak |
2m 06s |
7. Turbo BASIC 2.0 XL |
tak |
nie |
2m 44s |
8. Turbo BASIC 2.0 XL |
tak |
tak |
2m 03s |
Wnioski
Istnieje przepaść pomiędzy czasem wykonywania się programu pomiędzy
dwoma testowanymi odmianami tego samego języka. Sam za siebie mówi
fakt, iż zoptymalizowany program uruchomiony na Atari BASIC (przy
wyłączonym obrazie) nawet nie zbliża się do prędkości wykonywania
programu w Turbo BASIC XL (bez optymalizacji i zabaw z ANTIC'em).
Jak można było się spodziewać, wyłączenie obrazu daje spory
przyrost prędkości, jednakże kosztem pozbawienia się przyjemności z
oglądania powstającego rysunku. Natomiast optymalizacja kodu nie
daje wiele w tym konkretnym przypadku. Wygląda na to, iż
kilkanaście lat temu „straciłem” sporo czasu bawiąc się Atari
BASIC, różnica pomiędzy 9 minutami 29 sekundami i 2 minutami 48
sekundami w wersji nieoptymalizowanej jest dość spora. Szkoda,
wielka szkoda, że nie miałem wtedy Turbo BASIC'a.
Epilog
Dziś odczuwam wielką ulgę patrząc na te wyniki. Ta sentymentalna
zadra zniknęła z mojego życia, pozostawiając już tylko same dobre
wspomnienia. Pewnie chciałbym odtworzyć mój pierwotny program,
który rysował bardziej skomplikowane wykresy, pewnie chciałbym
wiedzieć jak szybko zadziałałby przepisany na PASCAL'a i po
kompilacji – ale nie jest to już tak ważne. Gdzieś we mnie
natomiast drzemie jeszcze potrzeba odtworzenia gry, która była na
bardzo zaawansowanym etapie. Może kiedyś...