Odtwarzanie programów z kaseciaka commodore64 ma swój smaczek:) Kupno kaset jest jednak coraz trudniejsze, magnetofon mało “przyjazny dla użytkownika” a same nośniki – nie są niezniszczalne. Dlatego wymyślono sd2iec. IEC to szeregowy port komunikacyjny commodore. Umożliwia on łączenie komputera z innymi urządzeniami, np. pamięciami masowymi. sd2iec udostępnia commodore64 zasoby nagrane na karcie sd przez port iec.
Sam sd2iec nie jest jakimś konkretnym urządzeniem. W sieci znajdziecie wiele różnych realizacji. Niektóre są bardziej chałupnicze – a inne to praktycznie gotowe produkty ze sklepowej półki. Ja swoje urządzenie skonstruowałem zgodnie z projektem Larswad na bazie Arduino Mega2560.
Podziękowania…
Projekt opublikowany przez Larswad na https://github.com/Larswad/sd2iec_mega2560 – pomysłu jego i kilku innych osób – którym to bardzo dziękuję:) Tekst oryginalnie ukazał się na moim blogu Elektronika Bez Spięcia (uczymy.edu.pl). W tekście wykorzystałem inne teksty, do których odsyłam Was po więcej szczegółów:
- Czytnik kart SD – Arduino Mega
- Commodore 64: emulator Vice
- Moja pierwsza drukarka 3D – DaVinci MiniMaker
- Windows Subsystem for Linux
Szpej
Do realizacji sd2iec potrzebnych będzie kilka elementów:
- Komputer z linuks – do budowania kodu (możecie też próbować z Windows i Windows Subsystem for Linux albo z maszynami wirtualnymi),
- Arduino Mega2560,
- Moduł czytnika kart SD – z odpowiednią kartą (np. microSD),
- Wtyczka DIN 6 Pin – do znalezienia na portalu aukcyjnym lub sklepach elektronicznych,
- Kilka kabelków połączeniowych.
Dodatkowo pokusiłem się o sklejenie wszystkiego na płytce uniwersalnej, diodki stanu oraz obudowę wydrukowaną na drukarce 3D. Nie jest to konieczne do działania, ale efekt końcowy będzie bardziej spektakularny.
Podłączenie czytnika kart SD
Pracę rozpocząłem od podłączenia czytnika kart SD do Arduino. Obsługę modułu SD opisałem dokładniej w tekście Czytnik kart SD – Arduino Mega. Podłączcie moduł, użyjcie domyślnego przykładu ‘listfiles’ (ze zmianami dla portu CS). Upewnijcie się, czy Arduino poprawnie czyta kartę.
Rozkład pinów (UWAGA: może zależeć od modułu jaki użyjecie):
Pin modułu | Podłącz do AtMega | Uwagi |
CS | 53 | Chip-Select, czasami nazywany SS |
SCK | 52 | Zegar |
MOSI | 51 | Dane idące do modułu |
MISO | 50 | Dane wracające z modułu; w moim egzemplarzu opisano „MOSO”. |
Vcc | +5v | Zasilanie 5v |
GND | GND | Masa |
Port IEC
Żeby podłączyć się do portu IEC, konieczna jest wtyczka DIN o 6 pinach – z jednym umiejscowionym pośrodku. Nie jest ona już popularna, ale można ją jeszcze dostać w niektórych sklepach elektronicznych – albo na popularnym portalu aukcyjnym.
Do wtyczki dolutujcie kabelki. Wystarczy 5 – nie musicie lutować środkowego styku (nie jest używany).
Tutaj pracowałem nad urządzeniem prototypowym, stąd użyłem zakończeń z pinami:
Sam port IEC wygląda tak (pobrano z c-64 wiki):
UWAGA: tak wygląda port z tyłu commodore, nie wtyczka:)
Piny IEC i ich podłączenie do Mega:
Pin | Opis | Sygnał | Uwagi | Arduino Mega |
---|---|---|---|---|
1 | SRQ | IN | Serial Service Request In | 21 |
2 | GND | – | Masa | GND |
3 | ATN | OUT | Początek/koniec transmisji | 18 |
4 | CLK | IN/OUT | Zegar | 20 |
5 | DATA | IN/OUT | Dane | 19 |
6 | RESET | OUT(/IN) | Reset | Nieużywany |
Upewnijcie się, że dobrze podłączacie się do portu commodore. Najłatwiej zacząć od masy:
- wyłączcie commodore,
- wepnijcie wtyczkę z kabelkami do portu iec commodore,
- ustawcie multimetr na sprawdzanie przewodzenia,
- podepnijcie jedną sondę pod kabelek z IEC, który podejrzewacie, że jest masą,
- drugą sondą miernika dotknijcie do masy commodore – np. na przełączniku kanałów.
Jeżeli trafiliście na masę – miernik powinien zasygnalizować przewodzenie (np. zapiszczeć). W ten sposób upewnicie się, że prawidłowo podłączyliście masę.
Zauważcie: na IEC nie ma zasilania. Arduino musicie zasilić zewnętrznie lub np. z portu joystika.
Kompilacja
Wygląda na to, że samo urządzenie macie już gotowe. Czas stworzyć dla niego oprogramowanie. Całą pracę wykonał za nas Larswad. Wystarczy ściągnąć kod, skompilować go i wgrać na Arduino. Pliki źródłowe pobieramy z githuba i kompilujemy:
1 2 3 4 5 6 |
$ git clone https://github.com/Larswad/sd2iec_mega2560.git $ cd sd2iec_mega2560/ $ chmod +x ./scripts/configparser.pl $ chmod +x ./scripts/gcctest.pl $ make CONFIG=configs/config-arduino_mega2560 $ cd obj-m2560-arduino_mega2560/ |
W rezultacie budowania kodu, uzyskacie plik ./obj-m2560-arduino_mega2560/sd2iec.hex. Trzeba go wypalić na Arduino.
Wypalanie kodu na Arduino
Po skompilowaniu kodu, w katalogu: ./sd2iec_mega2560 znajdziecie skrypt flash_arduino.sh. Upewnijcie się, że Wasze Arduino podłączone jest jako /dev/ttyACM0. Przed programowaniem upewnijcie się, że monitor portu szeregowego Arduino IDE jest wyłączony (tak na wypadek, gdybyście mieli Arduino IDE otwarte w tle:)).
Ustawcie prawa do wykonania i uruchomcie skrypt wypalający oprogramowanie sd2iec na Arduino:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
$ chmod +x./scripts/flash_arduino.sh $ ./scripts/flash_arduino.sh avrdude: AVR device initialized and ready to accept instructions Reading | ################################################## | 100% 0.01s avrdude: Device signature = 0x1e9801 (probably m2560) avrdude: reading input file "obj-m2560-arduino_mega2560/sd2iec.hex" avrdude: writing flash (60984 bytes): Writing | ################################################## | 100% 9.79s avrdude: 60984 bytes of flash written avrdude: verifying flash memory against obj-m2560-arduino_mega2560/sd2iec.hex: avrdude: load data flash data from input file obj-m2560-arduino_mega2560/sd2iec.hex: avrdude: input file obj-m2560-arduino_mega2560/sd2iec.hex contains 60984 bytes avrdude: reading on-chip flash data: Reading | ################################################## | 100% 7.81s avrdude: verifying ... avrdude: 60984 bytes of flash verified avrdude: safemode: Fuses OK (E:FD, H:D8, L:FF) avrdude done. Thank you. |
Co bardzo praktyczne, skrypt nie zamazuje bootloadera Arduino. Uruchomcie monitor portu szeregowego (np. z pakietu Arduino IDE). Ustawcie szybkość transmisji na 57600. Na monitorze powinno pojawić się:
1 2 |
xxxXxxxXxxx sd2iec 1.0.0atentdead0 #08 |
Karta SD
Przygotujcie kartę SD. Sformatujcie ją tak, żeby miała tylko jedną partycję fat32 (lub fat16). Na próbę proponuję wgrać program CBM File Browser. To darmowe narzędzie, które przyda się do uruchamiania programów z Waszej karty. Pobierzcie CBM, rozpakujcie. W katalogu ./programs znajdziecie plik “fb64”. Zapiszcie go na karcie SD. Dodajcie kilka programów np. zapisanych w formacie d64 (obrazy dyskietek c64). Przełóżcie kartę do czytnika podłączonego do Arduino. Włączcie commodore i zasilcie Wasz sd2iec (np. z ładowarki USB).
Uwaga: Kolejność włączania powinna być obojętna – przez port szeregowy nie płynie zasilanie. W każdym razie ja próbowałem różnych kombinacji – nic się nie stało. Na wszelki wypadek przypominam, że wszystko robicie na swoją odpowiedzialność:)
Teraz:
1 |
LOAD"$",8 |
…pokaże katalog główny karty SD. Załadujcie i uruchomcie FB64:
1 2 |
LOAD "FB64",8,1 RUN |
Za pomocą klawiszy możecie wybrać obraz dysku (pliki o rozszerzeniu d64) lub plik wykonywalny (pliki prg). Klawisz Return “rozpakuje” obraz lub uruchomi wybrany program. Teraz pozostaje… czekać aż się załaduje:)
UWAGA:
Programy i obrazy dysków które je zawierają mogą być przedmiotem czyjejś własności intelektualnej/majątkowej. Pobieranie ich, kopiowanie czy odtwarzanie może naruszać prawa autorskie. Upewnijcie się co do legalności tego oprogramowania.
Własne programy
Co ciekawe, mogę nagrywać i odtwarzać własne programy. Przykładowo, znany Wam z tekstu o emulatorach, programik do generowania ciągu Fibonacciego (1, 1, 2, 3, 5, 8):
1 2 3 4 5 6 |
10 X=1: Y=0 20 PRINT X 30 A=X 40 X=Y+A 50 Y=A 60 GOTO 20 |
…możecie teraz nagrać swój program na kartę w sd2iec:
1 |
SAVE "FIB.BAS",8 |
A potem go załadować i ponownie uruchomić:
1 2 |
LOAD "FIB.BAS",8 RUN |
Wersja “PRO”
Prototyp powstał jako Arduino Mega podłączone do commodore64 i modułu SD przewodami od płytki stykowej. Nie ma co ukrywać, że w takiej formie był… powiedzmy mało przyjazny dla użytkownika:) Postanowiłem doprowadzić ten projekt do wersji bardziej ‘produkcyjnej’:) Zamiast przewodów stykowych podłączonych bezpośrednio do gniazd Arduino – zlutowałem płytkę. Zamiast elementów ‘latających’ swobodnie – obudowa wydrukowana na drukarce 3D.
Obudowa sd2iec składa się z 2 części:
- dolnej, która “trzyma” Arduino,
- górnej, w której znajduje się płytka czytnika oraz diody.
Całość zaprojektowałem z pomocą SketchUp (https://app.sketchup.com/app). Oba wyeksportowane STL załączyłem do artykułu.
Uwaga: załączone modele to poprawione prototypy – ale nie miałem jeszcze okazji ich wydrukować (wyszedł mi filament:)). Mogą zawierać błędy.
Płytka
Arduino Mega jest na tyle przyjemne, że wszystkie gniazda rozłożone są na rastrze 2.54mm. Dzięki temu nie trzeba kupować dedykowanej płytki prototypowej. Nada się praktycznie każda uniwersalna. Dodatkowo, do zlutowania płytki użyłem kilku gold-pinów, terminale (te mniejsze zielone, na rastrze 2.54mm), kynar i przewody. Przyda się też pistolet na gorący klej do zabezpieczenia kabelków.
Nowy kabel
Rozkład żył i ich podłączenie do wtyczki iec i portów Arduino znajdziecie powyżej. Dodatkowo żyły włożyłem do koszulki termokurczliwej. Kabel jest rozsądnie dłuższy od tego z prototypu – tak, żeby można było bez problemów podłączyć do commodore.
Diody LED
W stosunku doprototypu dodałem 2 diody sygnalizujące zajętość (busy) i błędy urządzenia (dirty). Kod zawiera już funkcje do sterowania nimi, ale domyślnie są wyłączone. W pliku sd2iec_mega2560/src/avr/arch-config.h znajdźcie sekcję:
1 |
#elif CONFIG_HARDWARE_VARIANT == 10 |
Poniżej odszukajcie funkcje:
1 2 3 |
... leds_init(void) ... set_busy_led(uint8_t state) ... set_dirty_led(uint8_t state) |
Czytając kod:
- dirty – PB7 -> pin D13
- dioda busy: PH3 -> pin D6
Kod dla diody busy jest zakomentowany (nieaktywny), można to łatwo naprawić:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
/*** LEDs ***/ // Please don't build single-LED hardware anymore... // Initialize ports for all LEDs static inline void leds_init(void) { // Note: Depending on the chip and register these lines can compile // to one instruction each on AVR. For two bits this is one // instruction shorter than "DDRB |= _BV(PB6) | _BV(PB7);" DDRB or_eq _BV(PB7); // OPTIONAL: Implement a second led (RED one!). //[am] DDRH |= _BV(PH3); } // --- "BUSY" led, recommended color: green (usage similiar to 1541 LED) --- static inline __attribute__((always_inline)) void set_busy_led(uint8_t state) { // OPTIONAL: Attach and implement a green led for BUSY. //VAR_UNUSED(state); //[am] if (state) PORTH and_eq ~_BV(PH3); else PORTH or_eq _BV(PH3); } |
Teraz przebudujcie oprogramowanie i wypalcie na Arduino.
Same diody podłączyłem już na kabelkach stykowych:
- od portu d6 do katody diody (krótsza nóżka)
- od anody diody(dłuższa nóżka) do rezystora i dalej do zasilania +5v Arduino
- od portu d13 do katody drugiej diody
- od anody drugiej diody do rezystora i dalej do zasilania +5v Arduino
Czyli: dłuższe nóżki diod (anody) idą na zasilanie Arduino – krótsze na porty odpowiedzialne za sterowanie diodami. Między portem i katodą lub anodą i zasilaniem musicie szeregowo włączyć rezystor ograniczający prąd na diodzie – np. 360Ω.
Galeria
Podsumowanie
Najważniejsze pytanie: czy to działa? Odpowiedź brzmi… przeważnie:) Generalnie nie zauważyłem problemów z komunikacją. Commodore za każdym razem poprawnie odczytywał zawartość karty sd. Niezależnie czy był to fat32 czy fat16 – nie było problemów z listowaniem zawartości czy otwieraniem obrazów dysków. Testowałem głównie z kartami 8GB.
Nie zdarzył mi się dotychczas błąd związany z samym ładowaniem programów. Pomimo tego, niektóre się nie uruchamiały. Jedne z nich rozbijały się przy samym starcie. Inne – dochodziły do intro, a potem zamrażały system – lub wracały do interpretera basica.
Na szczęście większość startowało bez problemów. Co więcej – wydaje się, że jest to raczej sprawa konkretnego obrazu niż samego urządzenia sd2iec. Być może jest kwestia loaderów – sprawa do wyjaśnienia.
Mimo kilku ślepych uliczek, całość udało się złożyć bez większych problemów i służy dzielnie:)
Jeszcze raz przypominam o prawach autorskich. W sieci jest mnóstwo oprogramowania, które ich nie narusza.
To że nie działa czasami a nie wiadomo dlaczego to nawet zaliczyłbym na plus. Kto miał prawdziwe Commodore ten wie że nawet kichający w pokoju obok ojciec mógł przerwać wczytywanie. Dodałbym jeszcze otwór ze śrubką żeby już urządzenie było 100% realistyczne :D
GOOD JOB!
Z tym kichaniem to chyba o Atari się mówiło. Ja nie miałem problemów z wgrywaniem z kaset. Czasem coś się nie wgrało ale to był przypadek 1/50. :)
Plików komunikatory działają bez zarzutu na sd2iec. To co się wywala to przeważnie dyskowe rzeczy. Dzieje się tak dlatego że stacja to drugi komputer. Ma własny procesor, tam, ROM, porty we/wy. Po załadowaniu głównego pliku program próbuje załadować do stacji loader. Nie widzi bebechów stacji i leci w krzaki. To urządzenie to tylko emulator protokołu IEC. Całą stację emuluje Ultimate albo Pi1541.
@zen: to coś emuluje napęd dyskietek a nie magnetofon, a o ile mnie pamięć nie myli 1541 nie miał żadnej śrubki i kichanie mu nie przeszkadzało :)
Co do zasilania: można by było chyba skorzystać z portu magnetofonu… nie mam już niestety komodorka (a szkoda) więc nie sprawdzę :( Na userporcie też było wyprowadzone zasilanie.
Fani tzw. “demek” na C64 (programów demonstracyjnych) nie będą skakać z radości, bo jak napisał wyżej SRV, dyskietkowe dema mają własny kod uruchamiany częściowo w stacji dysków. Ale do starych gierek kasetowych pomysł świetny!
Mam tylko jedną uwagę co do robienia otworów wentylacyjnych od góry, myślę że lepiej jak się to robi po bokach, lepiej chroni przed kurzem i zalaniem .
Dziękuję, ciekawy pomysł. Generalnie w dziedzinie projektowania 3d muszę się wiele nauczyć:)
Działają jednoplikówki. Dogrywalne jak w demach nie pójdą. Używam od kilku lat głównie do gierek i odtwarzania sidów
Fajne rozwiązanie dla fanów tego klasycznego komputera :) eh ale się na nim grałoooo…
Czy to pójdzie tylko na Mega2560 czy można również wykorzystać UNO (akurat mam kilka UNO, które się nudzą w szufladzie :) )?
Dla czego do wgrania kodu do Arduino nie jest wykorzystywany standardowy program Arduino?