fbpx
Kategorie
Publicystyka Zrób to sam

Po 29 latach napisałem program na Commodore 64 [aktualizacja]

Pierwszy komputer PC dostałem od rodziców w roku 1993. Z dnia na dzień porzuciłem wówczas wiernego Commodore 64 ze stacją dysków Oceanic OC-118N. Nagły atak nostalgii sprawił jednak, że po 29 latach wróciłem do tego 8-bitowca, by po raz ostatni napisać coś na tę platformę.

Pomysł na aplikację był prosty – chciałem stworzyć coś, co nie mogłoby powstać w roku 1993. Coś, czego wtedy nie dałoby się nawet wymyślić! Słowem – stworzyłem na C64 program, który korzysta z API dostępnego przez protokół HTTP (specyfikacja HTTP 1.0 została zatwierdzona dopiero w roku 1996). Oto efekt kilku tygodni pracy z retro-sprzętem, na którym kurz osiadał przez dziesięciolecia.

UWAGA! Artykuł był aktualizowany, dodatkowa treść na końcu strony

Zacznijmy od demonstracji gotowego programu „DeepL dla Commodore 64” (bezpośredni link: YouTube)

Co widzimy na tym nagraniu? Czytelnikom przed czterdziestką przyda się mała ściągawka: najpierw wczytuję i wyświetlam zawartość dyskietki, potem ładuję i uruchamiam program. Mrugające poziome pasy to efekt uboczny dekompresji – spakowana apka jest mniejsza i szybciej się ładuje, kosztem niewielkiego opóźnienia przy starcie. Po odpaleniu aplikacji wpisuję w okienku tekst w języku angielskim, zatwierdzam go i po krótkiej chwili widzę tłumaczenie na język niemiecki.

Czy wspominałem już, że od ponad pół roku pracuję w firmie DeepL, która dostarcza najlepszą na świecie usługę maszynowego tłumaczenia tekstów? Jeśli jeszcze nie znasz DeepL, otwórz tę stronę i wklej tam dowolny fragment tekstu. Potem porównaj otrzymane tłumaczenie z tym, co dostaniesz w Google Translate. Gdybym miał obstawiać, który serwis poradził sobie lepiej… Nieważne. I tak nie jestem obiektywny. Wracajmy do tematu.

Zestaw-marzenie każdego dzieciaka w połowie lat ’80, stacja dysków kosztowała więcej niż komputer
foto Bill Bertram, licencja CC BY-SA 2.5

Aplikacja korzysta z REST API: wysyła przez internet tekst do translacji, odbiera tekst wynikowy, wyświetla go na ekranie. DeepL obsługuje 26 różnych języków, ale generator znaków C64 nie byłby w stanie obsłużyć odpowiedniej liczby ogonków i umlautów, ograniczyłem się do angielskiego, niemieckiego i polskiego.

Ale… jak to w ogóle możliwe?

Komputerowi Commodore 64 stuknęły czterdzieste urodziny. Mimo tego cieszy się nadal sporą grupą miłośników – ci zaś nie ustają w wymyślaniu i konstruowaniu kolejnych ulepszeń. Zajrzyjcie na stronę www.c64os.com – znajdziecie tam rozszerzenia pamięci, zamienniki płyt głównych, pamięci masowe, adaptery, przejściówki, konwertery, karty rozszerzeń, alternatywne ROM-y, interfejsy Ethernet i WiFi, szybkie złącza szeregowe i równoległe, multiplikatory portów, urządzenia diagnostyczne, płytki prototypowe i wiele innych.

Przykładowe ulepszenia dla C64

Chyba jasnym jest, że miłośnicy retro-komputerów nie ustępują w niczym maniakom retro-motoryzacji. Skoro jeżdżące po ulicach garbusy czy maluchy są witane życzliwym uśmiechem, to może zaczniemy podobnie reagować na spotykane okazjonalnie ośmiobitowce?

Ethernet

Zacząłem od pozyskania modułu sprzętowego, potrzebnego do połączenia z siecią komputerową. Użyłem interfejsu RR-Net w wersji MK3, dostępnego tutaj.

RR-Net MK3

Jest to karta sieciowa podłączana do Expansion Port, wyposażona w port RJ-45, działająca z prędkością 10 Mbit/s. W świecie C64 ten model jest de facto standardem. Choć istnieją też specjalizowane karty WiFi, to nie pozwalają na połączenie z „domowym internetem” – stąd wybór starego, dobrego połączenia kablowego.

Internet

Mało kto dziś pamięta, że internet to tzw. sieć sieci. Protokół TCP/IP stał się wspólnym językiem komunikacji komputerów, które lokalnie nadal były połączone np. przez IPX/SPX czy AppleTalk. To właśnie dzięki niemu możliwa stała się globalna komunikacja – jednak w czasach świetności C64 nie było mowy o tym, by w ten sposób ze światem łączyły się domowe mikrokomputery. Ich użytkownicy mogli liczyć co najwyżej na wdzwaniane połączenia modemowe, ale to opowieść na inną okazję.

Tak czy owak Commodore 64 nie ma w standardowym oprogramowaniu niczego, co pozwalałoby na komunikację z innymi komputerami. Szczęśliwie istnieje projekt ip65, stanowiący implementację stosu TCP/IP na komputery z procesorem MOS 6502 (z ciekawostek – ten CPU, wciąż produkowany, kosztuje na Aliexpress dolara za sztukę).

Wśród gotowców, których nie musimy implementować samodzielnie, jest choćby obsługa DNS albo DHCP – czyli coś, co na „dużych” komputerach przyjmujemy dziś jako oczywistość. Cóż, dawniej było inaczej.

REST API

Czego potrzebujemy, by w komunikować się z usługami dostępnymi przez API typu REST? Dwóch komponentów: pierwszy ma odpowiadać za obsługę protokołu HTTP, drugi – za tworzenie i parsowanie komunikatów w formacie JSON. Nie zgadniecie – w obu przypadkach istniał już potrzebny mi kod dla C64!

Biblioteka programistyczna http64 realizuje obsługę żądań i odpowiedzi HTTP. Zestaw transmitowanych nagłówków jest naprawdę minimalny – jednak dzięki temu serwery nie próbują żadnych sztuczek (np. kompresji), tylko obsługują otrzymane żądania w sposób najbardziej podstawowy.

Biblioteka 6502 JSON Parser pomaga nam przy konwersji zestawu znaków ASCII do PETSCII, by przetłumaczony tekst mógł od razu trafić na ekran. Co ciekawe, autor zaimplementował także bibliotekę do testów jednostkowych, co naprawdę przenosi programistów Commodore 64 w XXI wiek. Czekamy na integrację 8-bitowców ze środowiskami Continuous Integration!

Programowanie C64 w roku 2022

Obawiam się, że nie będę w stanie odpowiednio mocno zaakcentować, jak wspaniałych czasów dożyliśmy. Tworzenie oprogramowania na Commodore 64 trzydzieści lat temu wyglądało mniej więcej tak:

  1. resetujesz komputer
  2. wczytujesz z dyskietki program asemblera (minuta czekania), uruchamiasz go
  3. wczytujesz kod źródłowy programu, nad którym pracujesz
  4. wprowadzasz zmiany i ulepszenia, zapisujesz kod źródłowy
  5. uruchamiasz kompilację, tworzone są moduły (pół minuty czekania)
  6. uruchamiasz linkowanie, moduły łączone są w jedną binarkę zapisywaną na dyskietce (pół minuty czekania)
  7. uruchamiasz packer/cruncher, by zredukować rozmiar binarki (opcjonalnie, trzy minuty czekania)
  8. wczytujesz i uruchamiasz linkowany program
  9. coś nie zadziałało jak należy, przejdź do punktu 1

Dziś wygląda to mniej-więcej tak:

  1. edytujesz program w swoim ulubionym edytorze pod Windows na PC
  2. skrót klawiszowy wywołuje kompilację, linkowanie, crunchowanie, utworzenie obrazu dyskietki, odpalenie emulatora, automatyczne wczytanie i uruchomienie programu z obrazu dyskietki (łącznie trzy sekundy czekania)
  3. coś nie zadziałało jak należy, zamykasz emulator i wracasz do punktu 1

To nie wszystko!

W czasach wczesnego C64 asemblery zapewniały podstawową relokację kodu, obsługiwały łańcuchy znaków, etykiety skoków i… niewiele więcej. Zapis programu był niebezpiecznie bliski językowi maszynowemu. W dzisiejszych czasach kompilatory skrośne tworzące kod MOS6502 na komputerach PC obsługują makra, instrukcje sterujące pętlami, arytmetykę zmiennoprzecinkową, kompilację warunkową, dziesiątki ostrzeżeń a nawet przekształcenia macierzowe czy osadzanie zasobów graficznych z GIF-ów na PC, konwertowanych przy kompilacji.

Praca, która kiedyś zajęłaby cały kilka dni, dziś zajmuje godzinę. Programista ośmiobitowców sprzed 30 lat, oglądający współczesne narzędzia, czułby się jak sumeryjski skryba ryjący w glinianych tabliczkach, któremu zaprezentowano drukarkę laserową.

Implementacja mojego programu ograniczyła się więc do obsłużenia dwóch pól tekstowych, dwóch comboboxów i jednego przycisku. Cała reszta – TCP/IP, DNS, HTTP, JSON – to gotowce, wystarczyło upakować je w dostępnej pamięci i poznać konwencję przekazywania danych do odpowiednich funkcji.

Interaktywna mapa pamięci C64

Literatura? Jest jej mnóstwo, dostępna zawsze za darmo. W przypadku Commodore 64 publikacje sprzed 15 lat są niemal tak samo aktualne, jak te wczorajsze. Jeśli coś się zmieniło, to chyba tylko sposoby łączenia z siecią – SLIP czy PPP odeszły w przeszłość. Za to mapa pamięci oraz adresy funkcji systemowych pozostają niezmienne od 40 lat.

Przy okazji – dobrze, że istnieje serwis Archive.org, który uratował choć część zasobów Geocities, Google Sites czy rodzimego Free Polbox. Publikacje online stopniowo przestają istnieć, wiemy o tym oglądając martwe linki na stronach porzuconych przez autorów 5, 10 czy 15 lat temu.

Co się nie udało

Największe problemy pojawiły się tam, gdzie… każdy by się ich spodziewał. Szyfrowanie ruchu sieciowego. Dziś codzienność, wszak „goły” protokół HTTP jest piętnowany przez przeglądarki i karany przez wyszukiwarki. I to właśnie w tym miejscu docieramy do granic możliwości C64, czyli do HTTPS.

Mówiąc dokładniej – do protokołu TLS w wersji 1.2. Albo wcześniejszego. Albo dowolnego przedstawiciela rodziny protokołów SSL/TLS. Byłem gotów na każdy kompromis.

Ocena „A” w SSL Labs oznacza protokół TLS 1.2 lub nowszy

Nie czułem się na tyle biegły w kryptografii i programowaniu ośmiobitowców, by samodzielnie przygotować moduł komunikacji TLS na leciwego Commodore’a. Jakieś szanse miałbym, gdyby istniała choć jedna referencyjna implementacja na ośmiobitowce. Aby zwiększyć widoki na sukces, byłem gotów:

  • uwzględnić tylko jeden wybrany ciphersuite
  • użyć niebezpiecznego szyfrowania RC4
  • użyć niebezpiecznej funkcji skrótu MD5
  • użyć klucza długości 56/64 bitów
  • zrezygnować z perfect forward secrecy na rzecz stałych wartości (PSK) w protokole Diffie-Hellmana
  • porzucić weryfikację łańcucha certyfikatów (ufać zawsze i każdemu serwerowi)

Niestety, nawet tak uproszczony kod dla architektur 32-bitowych zajmuje kilkadziesiąt kilobajtów, w przypadku Commodore byłoby to istotnie więcej – tak z powodu arytmetyki na mniejszych zakresach, jak i wskutek dostępności zaledwie trzech rejestrów CPU. Do tego dochodzi obowiązkowe 16 KB na bufory wejścia-wyjścia. Na pecetach śmiesznie mało, na C64 to ćwierć całej przestrzeni adresowej.

Nawet udana implementacja wymagałaby zapewne dynamicznego doczytywania kodu z dyskietki – najpierw ładowalibyśmy moduł SSL/TLS by zainicjować połączenie i ustalić klucz szyfrowania, potem moduł ten wymieniamy na właściwy program korzystający z ustanowionego klucza.

przewodnik po każdym bajcie połączenia TLS 1.2

Miałem jednak większy problem – procesor C64 jest taktowany zegarem 1 MHz. Przy takiej prędkości handshake nawet przy użyciu przestarzałych, ale prostszych obliczeniowo wariantów SSL, trwałby kilkadziesiąt sekund, co wielokrotnie przekracza stosowane powszechnie limity czasu na nawiązanie połączenia. TLS z szyframi AES oraz 3DES odpadają w przedbiegach. Może właśnie dlatego nie udało mi się znaleźć ani jednej wzmianki, by ktokolwiek zaimplementował SSL/TLS na komputerach z procesorem MOS 6502.

Brak obsługi nowych protokołów na starych komputerach i systemach nikogo zresztą nie dziwi. TLS 1.0 został wycofany z użycia w roku 2018, nowszych wersji nie potrafiły obsłużyć m.in. systemy Windows Vista (2007), Windows Server 2008, iOS 4 (2010) czy Android 4.1 (2013).

Koniec końców musiałem więc użyć serwera proxy, z którym moja aplikacja komunikowała się bez szyfrowania.

Podsumowanie

Projekt „DeepL dla Commodore 64” to raczej mój ostatni kontakt z programowaniem ośmiobitowców. Eksperyment był dość ciekawy, ale… inne projekty czekające w kolejce mogą być jeszcze ciekawsze. Jedno wiem na pewno – co jakiś czas wyciągnę z piwnicy C64 z napędem dyskietek, by pograć w The Great Giana Sisters, Pirates!, Supremacy czy Defender of the Crown!

Aktualizacja #1 [01-04-2022, 15:55]

Okazuje się, że nie wszystkie artykuły publikowane pierwszego kwietnia są takie całkiem prawdziwe. Otóż:

  • Nie mam pojęcia, jakie losy spotkały mojego C-64. Jeśli nie został komuś podarowany, może odnajdę go kiedyś w piwnicy rodziców
  • Nie wróciłem po 29 latach do programowania ośmiobitowców. Skorzystałem jedynie z edytora online PETSCII by przygotować serię ekranów, które można przekonwertować na aplikację odpalaną w emulatorze
  • Nie napisałem ani linijki kodu odpowiedzialnej za cokolwiek zaś animacja demonstrująca działanie mojego rzekomego programu powstała w Davinci Resolve z klipów nagranych w emulatorze
  • Film wyeksportowany z Resolve był zbyt ładny i czysty, więc „postarzyłem” go przy pomocy programu apki SuperCRT
  • Projekt nie zajął kilku tygodni, lecz jeden wieczór
PETSCII – edytor ekranów, duszków, generatora znaków
Davinci Resolve, praca w toku
SuperCRT w akcji

Nie miejcie do siebie żalu, jeśli mi uwierzyliście. Pisałem tak, abym sam mógł sobie uwierzyć. No i codziennie gdzieś na świecie jest Prima Aprilis.

A jeśli chcecie dotknąć prawdziwych ośmiobitowców oraz obejrzeć inne cuda techniki cyfrowej, zajrzyjcie do wrocławskiego Muzeum Gry i Komputery Minionej Ery. Muzeum nie jest duże, ale starsi ludzie powinni zarezerwować sobie na zwiedzanie co najmniej godzinę. Natężenie nostalgii jest nie do opisania.



O autorze: zawodowy programista od 2003 roku, pasjonat bezpieczeństwa informatycznego. Rozwijał systemy finansowe dla NBP, tworzył i weryfikował zabezpieczenia bankowych aplikacji mobilnych, brał udział w pracach nad grą Angry Birds i wyszukiwarką internetową Microsoft Bing.

14 odpowiedzi na “Po 29 latach napisałem program na Commodore 64 [aktualizacja]”

Nie można – z powodów, o których mowa w aktualizacji tekstu…

Szacunek! Zrobiłeś mi dzień. C64 to kawał dzieciństwa wielu z nas, a tu info że jeszcze żyje i takie cuda można robić…

Czytałem z łzami w oczach i wielkim podziwem. Doskonały Prima Aprilis. Dawno nikt mnie tak w konia nie zrobił. Szacunek tylko urósł. Dzięki!

Przeczytałem 2 dni później, nie zwracając uwagi na datę. Jako programista czytałem z dużym zainteresowaniem i bez podejrzenia, że coś jest nie tak. Niby były momenty, gdzie powstawało pytanie „ale jak w takim razie zrobił XYZ?”, ale za chwilę w tekście pojawiał się wiarygodny opis z linkami (których, przyznam, nie sprawdziłem).
Świetne zbadanie tematu i bardzo wiarygodny opis. Jak już doszedłem do aktualizacji i zacząłem czytać co i jak (z lekkim żalem, że to się nie jednak wydarzyło), to siedziałem i tylko gratulowałem po cichu świetnego tekstu na Prima Aprilis. 🙂

Przez kogo? DeepL? Nie, nie jest. Gdyby był, oznaczyłbym go odpowiednio.

„W przypadku Commodore 64 publikacje sprzed 15 lat są niemal tak samo aktualne, jak te wczorajsze.”
Ba! Nawet te 30 letnie są aktualne! 😉
Swoją drogą to fascynujące jak wiele dzieje sie wokół tych 8bitowców dzisiaj, „scena” robi rzeczy o których kiedyś nikomu się nie śniło. Do tego te różne sprzętowe upgrady – no cuda wianki!

Od lekko licząc 10 lat nie widziałem w demach czegoś istotnie nowego, jakiegoś znaczącego kroku czy nowo odkrytych sztuczek. Wskażesz coś?

Zalezy od poziomu podejscia jaki charakteryzuje perspektywe historyczne i informatyczne w programach komodorowskich gdzie polecic warto magazyn komodorowiec z zawartoscia swietnychi rzadkich oraz visualnie efektownych skryptow. Programowanie basicowe na tej platformie uczy jak wyeliminowac bledy w bezposredniej konfrontacji ukladania tekstowego skryptow przekladajacych sie na wspolczesny visual basic czy java.

Sorry, ale moim zdaniem uczenie się assemblera to niezły fioł. Ja na C-64 pisałem wszystko w Basic 2.0 i świetnie działało (włącznie z grami). Assemblera tknąłem dopiero za czasów Win 98 i gdy zobaczyłem jaka to katorga męczyć się z rejestrami, stosami itp. to tylko podziękowałem Panu Bogu, że obdarzył mnie wysoką inteligencją i umiejętnością biegłego programowania w Basicu co przełożyło się na płynne przejście na Visual Basic i zdobycie mistrzostwa dzielnicy w obiektowym programowaniu w ANSI C. W tekście doskonale widać, że autor tez jest inteligentny i nie babrał się w Assemblerze. Bo po co? 👌👏

Mimo to ludzie na świecie programują w językach skryptowych: php, javascript itp. Z tego zespołu: język programowania-komputer-człowiek człowiek jest najwolniejszy. I co z tego wynika? Nic.

Dokładnie, czas procesora dziś jest śmiesznie tani, a najdroższy jest czas ludzkiej pracy nad kodem.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.