Cześć!
Odkąd wszedłem w posiadanie Famicoma zastanawiałem się jak to jest grać w Arkanoid w sposób jaki mieli na myśli twórcy, czyli z dedykowanym kontrolerem dołączonym do gry w oficjalnej dystrybucji. Taki kontroler był zbudowany z dwóch timerów, licznika oraz rejestru przesuwnego (
https://www.nesdev.org/wiki/Arkanoid_controller#Hardware).
Przeglądając internet natrafiłem na
projekt repliki kontrolera dla portu gry na komputery MSX, opartym na mikrokontrolerze ATtiny85. Ponieważ kontrolery w wersji dla MSX i Famicoma nie różnią się zbytnio od siebie, w teorii powinno być możliwe dostosowanie projektu pod Famicoma.
Z przyjemnością mogę stwierdzić, że to się udało, a efekt prac zamieściłem na swoim
GitHubie.
Co jest potrzebne?- 1 x Płytka Digispark ATtiny85
- 1 x Potencjometr liniowy 10kΩ 1/8W
- 1 x Rezystor 1kΩ 1/8W
- 1 x Przycisk (przełącznik ON-OFF chwilowy)
- 1 x Kabel DA-15
- 1 x Plastikowa obudowa 97x63x30mm (takiej użyłem ja, jednak oryginał jest dużo dłuższy)
Wszystkie komponenty za wyjątkiem kabla kupiłem w Botlandzie (to nie jest reklama). Kabel DA-15 to zwykły przedłużacz dla portu rozszerzeń dla Famicoma lub kontrolera dla Neo-Geo do dostania na Aliexpress.
Schemat połączenia![](https://i.imgur.com/4fmavbm.png)
![](https://i.imgur.com/o7zzvmQ.png)
Do pinu P3 płytki Digispark podłączony jest potencjometr i napięcie na tym pinie jest mierzone przez przetwornik analogowo-cyfrowy. Gdy gra chce zresetować i uruchomić na na nowo zliczanie aktualnej pozycji paletki, wartość "1" jest pisana pod adres $4016, aby zaraz potem być wyzerowana - to z kolei zapala pin 12 podłączony do pinu płytki pod nazwą P1. W oryginalnym kontrolerze, przez krótki czas po wyzerowaniu licznika (ok. 7 ms) stara wartość była trzymana w rejestrze przesuwnym - dlaczego to jest istotne opowiem zaraz.
Gra odczytuję pozycję paletki odpytując adres $4017 i bit 1. Każde takie odczytanie generuje impuls na pinie 9 (pin P2 na płytce), który w zamierzeniu był podłączony do rejestru przesuwnego i powodował przesunięcie bitowe o 1. Żeby odczytać 8-bitową wartość należało odpytać adres $4017 osiem razy - informacja była zapalana na pinie 7 (P0 na płytce). Ponieważ implementacja w grze sprowadzała się do odczytu pozycji zaraz po wysłania impulsu do resetu licznika, przez krótki czas były dostępne stare dane. Aby stare i nowe bity nie nakładały się na siebie w połowie, zastosowałem sztuczne opóźnienie o ok. 3 ms - jest to pierwsza istotna zmiana względem oryginału z MSX. Pin 13 jest podłączony rezystorem podciągającym bezpośrednio z przyciskiem - gdy przycisk jest wciśnięty, stan niski jest wysyłany do konsoli sygnalizując oddanie strzału, w przeciwnym wypadku otrzymywany jest ciągły stan wysoki - odzwierciedla to odczyt z adresu $4016, bit 1.
Piny P4 i P5 są niewykorzystane. Warto wspomnieć, że w klonach Digispark, stan niski na P5 powoduje reset mikrokontrolera, więc najprościej było wykorzystać inne piny - na przykład P3 lub P4 - jednak one są też używane do komunikacji USB, więc po podłączeniu potencjometra płytka nie była wykrywana w komputerze. W moim przypadku pomogło ustawienie gałki na 50% przed każdym programowaniem.
Liniowość potencjometra liniowego - albo jego brakPo testowym odpaleniu Arkanoida zauważyłem, że paletka coraz wolnej się porusza im bardziej zbliża się do lewej ściany. Analogicznie przyspiesza im bardziej trzyma się prawej strony. Próbkując pozycję w gałki różnych miejscach i notując wartość wyjściową narysowałem charakterystykę wyjściową, która nie napawa optymizmem:
![](https://i.imgur.com/pRdzwGO.png)
Korzystając ze skryptu w Pythonie napisanego na kolanie sporządziłem wykres, który ma pokazać jakie wartości wyjściowe przesłać do konsoli na podstawie odczytu z ADC:
![](https://i.imgur.com/X6ep91I.png)
Pomiędzy punktami pomiaru zastosowałem interpolację liniową - na podstawie 14 próbek wygenerowałem 1024 wartości odpowiadających 10-bitowej rozdzielczości przetwornika. Tak naprawdę rejestr przesuwny może zwrócić 9 bitów danych, jednak najmniej znaczący bit jest odrzucany przez grę, stąd w programie przesunięcie bitowe jest o zaledwie jeden (zakres na wyjściu do konsoli 0-511).
Skrypt generuje gotową tablicę przeszukiwań do wklejenia w kod źródłowy. Po jego zastosowaniu, paletka porusza się w końcu w sposób liniowy. Jednak należy mieć na uwadze, że różne potencjometry reklamowane przez producentów mogą mieć różną charakterystykę i konieczne może być dokonanie własnoręcznych pomiarów i wygenerowanie własnej tablicy LUT.
A tak wygląda końcowy projekt ;p![](https://i.imgur.com/UDQEvdU.jpeg)
![](https://i.imgur.com/oRQ6jpq.jpeg)
![](https://i.imgur.com/RVyTQDc.jpeg)
![](https://i.imgur.com/MITR18N.jpeg)
Link do projektu:
https://github.com/kkusz/avrkanoid-famiPS. Do grania wymagana jest japońska wersja Arkanoida, która jest również zawarta w składance 168-in-1. Można jednak w łatwy sposób spatchować amerykańską wersję, aby obsługiwała Famicomową wersję kontrolera, dla zainteresowanych mogę załączyć patcha do ROM-u.
PS2. Nadal mam trudności z przejściem trzeciego poziomu nieważne w jakiej wersji. ;p