Atari 65XE - Reaktywacja
Ostatnio odkopałem w garażu stare 8 bitowe ustrojstwo - Atari 65XE. Był to pierwszy komputer z jakim miałem styczność w ogóle, no i... wzięło mnie na sentymenty. Wiem, że jest na DP kilka sentymentalnych osób, więc postanowiłem opisać swoje boje z próbą uruchomienia tego starocia - może ktoś sobie przypomni swoje stare miłe dzieje. Nie było łatwo - brak zasilacza, stare wtyki, niecałkiem sprawny sprzęt (po tylu latach chyba miał prawo?) skutecznie utrudniały mi to jedno spojrzenie na magiczny napis: READY. W końcu dopiąłem swego, a jak tego dokonałem, to poniżej.
Gdzie mój zasilacz?
Szperając w garażu odkopałem wspomnianą wcześniej Atarynkę, joysticki, magnetofon -wszystko gra, ale co z zasilaniem? Bezowocnie zakończyły się próby odnalezienia czarnego magicznego, oryginalnego zasilacza, co zmusiło mnie do poszperania w internecie i rozwiania wątpliwości, jaki prąd jest potrzebny aby uruchomić muzealny już sprzęt. O dziwo, sporo jest materiału w sieci dotyczącego Atari - niektóre nadal aktualizowane i rozwijane! Przestudiowałem kilka schematów, poczytałem kilka publikacji i doszedłem do wniosku, że poczciwa Atarynka jest zasilana napięciem 5V, a żeby wszystko poprawnie działało wystarczy 3A - wiem skąd wziąć przynajmniej taki prąd, tylko jak to podłączyć? Wtyczka od zasilania ma 7 pinów O_o - skąd się dowiedzieć, który to +, a który -? Z pomocą przyszły schematy Atari dostępne w sieci i moja analiza wnętrza tego komputerka ;) Uznałem, że lepiej będzie się upewnić, zanim puszczę z dymem zabytek muzealny :) Do czego udało mi się dojść, obrazuje poniższa rycina:
Skoro wiadomo już co gdzie podpiąć, to teraz pomyślmy skąd wziąć żądane napięcie. Tutaj pomogłem sobie współczesnym rozwiązaniem - zasilacz ATX od zwykłego PC. Patrząc na wtyczkę od tegoż zasilacza (MOLEX), widzimy wszystko czego nam potrzeba: czerwony kabelek to właśnie +5V, a czarny to masa. Zrobiłem pajęczynkę i połączyłem MOLEX'a z Atarynką.
Ktoś wie, jak zmusić zasilacz ATX do pracy bez komputera? Podpowiedź na poniższym screen'ie:
Atari na chodzie, ale co z obrazem?
No właśnie, gdzie upragniony napis READY? Tutaj, po dłuższej diagnozie, doszedłem do wniosku, że uszkodzone jest gniazdo TV‑OUT. Podjąłem próbę podłączenia TV przez wyjście na monitor. Dorwałem przejściówkę do starej klawiatury DIN/PS-2, podłączyłem do niej kabelek S‑Video i wpiąłem to do TV - teoria głosi, że powinno zadziałać ;) Owszem zadziałało, ale niezbędne, do poprawnego wyświetlania, okazało się podłączenie (gdziekolwiek) kabelka z wyjścia TV‑OUT - widać taka specyfika usterki... Mniejsza o to. Oczom moim ukazał się blue-screen (w tym przypadku to radosna nowina ;) ) z napisem READY.
8‑bitowa machina ruszyła co dalej?
Dalej, aby upewnić się, że wszystko gra, uruchomiłem sekwencje testów komputera: SELF TEST (ktoś pamięta kombinacje klawiszy do wejścia w to?). Testy przeszły poprawnie - nie byłem zdziwiony, bo Atari to hardy sprzęt.
W międzyczasie, surfując trochę po sieci, przypomniałem sobie odrobinkę ATARI BASIC. Nie zostały mi się żadne gry - nic to, napiszę sobie sam :)
No to jedziemy z kodem. Nie muszę chyba nikomu przypominać, jak ważna jest numeracja linii. Pamiętacie Robbo? Więc do dzieła! Stworzymy sobie jednoplanszowe Robbo w trybie tekstowym, a co :)
Najpierw przygotujmy sobie planszę. Plansza o wymiarach 22x21 (zauważycie, że gdzieś mi wcięło linię 102 - późno było) umieszczona w jednym stringu. Będę wkładać do tego stringa po 22 znaki (szerokość planszy), żeby mi było łatwiej potem planszę układać:
89 REM ------ PRZYGOTOWANIE PLANSZY -- 90 DIM L$(900):REM REZERWUJEMY PAMIEC 100 L$(1)= "%%%%%%%%%%%%%%%%%%%%%%" 101 L$(23)= "%$ # % %# # #%" 103 L$(45)= "%#$#%#$% %$ $% % # # %" 104 L$(67)= "% #% #% $ %# # #%" 105 L$(89)= "%$ $% % % # # %" 106 L$(111)="%# %##%%#%%%# $# #$$%" 107 L$(133)="%$# # %% %$ %% # # %" 108 L$(155)="% # # $%% %%%% # #%" 109 L$(177)="%%%% %%%%%%% %$ %# # %" 110 L$(199)="% # # $% $ # ##%$# #%" 111 L$(221)="%$# ## # % # # %" 112 L$(243)="%# # #$ % $##%% % # #%" 113 L$(265)="% # $#$% # $%$ %# # %" 114 L$(287)="%%%%%%%%%%$ %%% % # #%" 115 L$(309)="% #$ ##$%$ %%% %%" 116 L$(331)="% %% %% $% #%% % %" 117 L$(353)="%$% % % % % %$ % $% %" 118 L$(375)="% %% %% % #%% %$% %" 119 L$(397)="%#%$% % %# %$# % $%" 120 L$(419)="% #$ #$ $$%" 121 L$(441)="%%%%%%%%%%%%%%%%%%%%%%"
Na potrzeby wpisu zmieniłem ładne murki i serduszka na % i $. Kod w atari wyglądał mniej więcej tak:
Jak uzyskać takie znaczki na Atarynce, chyba nie muszę przypominać ;)
Co dalej? Dalej odpalimy grafikę :) przypiszemy zmiennym wartości i naniesiemy planszę na ekran:
499 REM ----- USTAWIENIE EKRANU ------ 500 GRAPHICS 0+16 510 POKE 752,1:REM -WYLACZAMY KURSOR-- 520 SETCOLOR 2,0,0:REM - CZARNE TLO -- 599 REM ----- PRZYPISANIE WARTOSCI --- 600 X=2:Y=2:REM -POZYCJA BOHATERA ---- 610 SERCA=40:REM - DO ZEBRANIA ------- 699 REM ------ RYSOWANIE PLANSZY ----- 700 FOR I=0 TO 20:REM -21 LINIJEK ---- 710 POSITION 0,I:REM -ZACZYNAMY W ROGU 720 ? L$ (I*22+1,I*22+22) 730 NEXT I 740 POSITION 23,5:? "SERDUSZKA: " 750 POSITION 34,5:? " " 760 POSITION 34,5:? SERCA
następnie zapętlimy program i wykonamy obsługę joysticka. Zmienna SEQ jest potrzebna do animacji bohatera, którym kierujemy joystickiem. Spust joy'a służy do restartu gry. Pętla FOR/NEXT służy do spowolnienia:
999 REM ----- PETLA GLOWNA ----------- 1000 SEQ=SEQ+1:POSITIONX,Y 1010 IF SEQ=5 THEN SEQ=1 1020 IF SEQ=1 THEN ? "/" 1030 IF SEQ=2 THEN ? "-" 1040 IF SEQ=3 THEN ? "\" 1050 IF SEQ=4 THEN ? "|" 1099 REM ---- OBSLUGA JOYSTICKA ------ 1100 IF STICK(0)=7 THEN GOTO 2000 1110 IF STICK(0)=11 THEN GOTO 3000 1120 IF STICK(0)=13 THEN GOTO 4000 1130 IF STICK(0)=14 THEN GOTO 5000 1140 IF STRIG(0)=0 THEN GOTO 100 1200 FOR I=1 TO 15 1210 DELAY=1 1230 NEXT I 1250 GOTO 1000:REM -KONIEC PETLI GL.--
Teraz zajmiemy się przesuwaniem bohatera w prawo. Linia 2000 sprawdza, czy możliwy jest ruch w prawo, czy nie ma tam muru. Linia 2010 Sprawdza, czy nie chcemy czasami przesunąć kratki. Linia 2200 sprawdza, czy jest miejsce do przesunięcia kratki. Linijka 2820 sprawdza, czy nie natrafiliśmy na serduszko (tutaj dolara).
1999 REM - RUCH W PRAWO -------------- 2000 IF L$((X+1)+1+Y*22,(X+1)+1+Y*22="%" THEN GOTO 1200 2010 IF L$((X+1)+1+Y*22,(X+1)+1+Y*22="#" THEN GOTO 2200 2100 GOTO 2700 2200 IF L$((X+2)+1+Y*22,(X+2)+1+Y*22<>" " THEN GOTO 1200 2209 REM ----- PRZESUWAMY KLOCEK ----- 2210 L$((X+2)+1+Y*22,(X+2)+1+Y*22="#" 2220 L$((X+1)+1+Y*22,(X+1)+1+Y*22=" " 2230 POSITION X+2,Y:? "#" 2240 POSITION X+1,Y:? "-" 2700 REM ----- PRZESUWAMY BOHATERA --- 2720 FOR I=1 TO 15 2730 DELAY=1 2740 NEXT I 2800 POSITION X,Y:? " " 2810 X=X+1 2819 REM ----- MOZE SERDUSZKO? ------- 2820 IF L$(X+1+Y*22,X+1+Y*22)="$" THEN GOTO 6000 2900 GOTO 1200
Analogicznie postępujemy z ruchem w lewo:
2999 REM - RUCH W LEWO --------------- 3000 IF L$((X-1)+1+Y*22,(X-1)+1+Y*22="%" THEN GOTO 1200 3010 IF L$((X-1)+1+Y*22,(X-1)+1+Y*22="#" THEN GOTO 3200 3100 GOTO 3700 3200 IF L$((X-2)+1+Y*22,(X-2)+1+Y*22<>" " THEN GOTO 1200 3209 REM ----- PRZESUWAMY KLOCEK ----- 3210 L$((X-2)+1+Y*22,(X-2)+1+Y*22="#" 3220 L$((X-1)+1+Y*22,(X-1)+1+Y*22=" " 3230 POSITION X-2,Y:? "#" 3240 POSITION X-1,Y:? "-" 3700 REM ----- PRZESUWAMY BOHATERA --- 3720 FOR I=1 TO 15 3730 DELAY=1 3740 NEXT I 3800 POSITION X,Y:? " " 3810 X=X-1 3819 REM ----- MOZE SERDUSZKO? ------- 3820 IF L$(X+1+Y*22,X+1+Y*22)="$" THEN GOTO 6000 3900 GOTO 1200
oraz z ruchem w dół i górę:
3999 REM - RUCH W DOL ---------------- 4000 IF L$((X+1)+(Y+1)*22,(X+1)+(Y+1)*22="%" THEN GOTO 1200 4010 IF L$((X+1)+(Y+1)*22,(X+1)+(Y+1)*22="#" THEN GOTO 4200 4100 GOTO 4700 4200 IF L$((X+1)+(Y+2)*22,(X+1)+(Y+2)*22<>" " THEN GOTO 1200 4209 REM ----- PRZESUWAMY KLOCEK ----- 4210 L$((X+1)+(Y+2)*22,(X+1)+(Y+2)*22="#" 4220 L$((X+1)+(Y+1)*22,(X+1)+(Y+1)*22=" " 4230 POSITION X,Y+2:? "#" 4240 POSITION X,Y+1:? "|" 4700 REM ----- PRZESUWAMY BOHATERA --- 4720 FOR I=1 TO 15 4730 DELAY=1 4740 NEXT I 4800 POSITION X,Y:? " " 4810 Y=Y+1 4819 REM ----- MOZE SERDUSZKO? ------- 4820 IF L$(X+1+Y*22,X+1+Y*22)="$" THEN GOTO 6000 4900 GOTO 1200 4999 REM - RUCH W GORE --------------- 5000 IF L$((X+1)+(Y-1)*22,(X+1)+(Y-1)*22="%" THEN GOTO 1200 5010 IF L$((X+1)+(Y-1)*22,(X+1)+(Y-1)*22="#" THEN GOTO 5200 5100 GOTO 5700 5200 IF L$((X+1)+(Y-2)*22,(X+1)+(Y-2)*22<>" " THEN GOTO 1200 5209 REM ----- PRZESUWAMY KLOCEK ----- 5210 L$((X+1)+(Y-2)*22,(X+1)+(Y-2)*22="#" 5220 L$((X+1)+(Y-1)*22,(X+1)+(Y-1)*22=" " 5230 POSITION X,Y-2:? "#" 5240 POSITION X,Y-1:? "|" 5700 REM ----- PRZESUWAMY BOHATERA --- 5720 FOR I=1 TO 15 5730 DELAY=1 5740 NEXT I 5800 POSITION X,Y:? " " 5810 Y=Y-1 5819 REM ----- MOZE SERDUSZKO? ------- 5820 IF L$(X+1+Y*22,X+1+Y*22)="$" THEN GOTO 6000 5900 GOTO 1200
Pozostało jeszcze obsłużyć zbieranie serduszek i sprawdzić, czy wszystkie nie zostały przypadkiem zebrane:
5999 REM --- WEZ SERDUSZKO ----------- 6000 SERCA=SERCA-1 6010 L$(X+1+Y*22,X+1+Y*22)=" " 6020 POSITION 34,5:? " " 6030 POSITION 34,5:? SERCA 6040 IF SERCA=0 THEN GOTO 6200 6100 GOTO 1200 6200 POSITION 2,10:? "GRATULACJE! ZEBRALES WSZYSTKIE SERCA!" 6210 POSITION 8,12:? "PUSH TRIGGER TO PLAY AGAIN" 6220 IF STRIG(0)=0 THEN GOTO 100 6300 GOTO 6220
I teraz możemy zagrać w naszą własnoręcznie utworzoną gierkę wpisując komendę RUN:
Wybaczcie, ale filmik robiłem późno, słabym sprzętem, przy słabym oświetleniu i osłabionym organiźmie - dzięki za wyrozumiałość, pozdrawiam. Aaaaa, i wszystkiego dobrego w Nowym 2014 (sic!) Roku!