Arduino GameBoy cart Reader/Writer
Introduzione:
Recentemente, rispolverando la mia collezione di retro games Nintendo, ho notato con mio grande dispiacere che alcune cartucce di gioco (ferme da più di dieci anni) risultavano completamente vuote, prive dei dati di gioco collezionati in età puerile. (all’interno delle cartucce di gioco è presente una batteria tampone che ha lo scopo di mantenere in memoria il salvataggio; quando la batteria si esaurisce, inevitabilmente si perde il salvataggio).
A quel punto sorse spontanea la domanda: come posso fare un backup dei salvataggi dei miei vecchi giochi?
Certo, esistono già dei lettori di cartucce, ma sono difficili da reperire, e spesso molto costosi… così ho optato per una soluzione più economica e amatoriale:

Arduino sembrava essere l’ideale per questo tipo di progetto, così tentai di costruire un mio proprio prototipo di lettore di cartucce per GameBoy.
Analisi del progetto
[ssbluelist]
- Il primo passo verso la realizzazione del progetto è quello di aprire una cartuccia di gioco per analizzarne la struttura interna;
- Secondo passo: estrapolare il Pinout e capire come interfacciare la cartuccia di gioco e la nostra board Arduino;
- Terzo passo: realizzare la prima interfaccia hardware e software;
- Quarto passo: riguarda il lato software: riuscire a leggere i dati dalla cartuccia;
- Quindo passo: realizzare l’interfaccia software dal lato pc in modo da salvare i dati letti dal nostro Arduino;
- Sesto passo consiste nel scrivere i dati salvati precedentemente nel computer nella cartuccia di gioco;
- Conclusioni.
[/ssbluelist]
Primo passo: Inside the Gameboy
Per prima cosa diamo uno sguardo all’interno della cartuccia di gioco per analizzarne la struttura:

[sstoggles] [sstoggle title=”Componenti”]ROM dove sono contenuti i dati del gioco
RAM dove è contenuto il salvataggio del gioco
MBC controllo dei banchi di memoria, gestisce e alloca grandi spazi di memoria
Timer Chip mantiente la data e l’ora (presente solo in alcune cartucce)
Batteria[/sstoggle][/sstoggles]
Secondo passo: Cartridge Pinout
La cartuccia di gioco presenta un’interfaccia a 32 Pin:

[sstoggles] [sstoggle title=”PinOut”]VCC – Alimentazione (5 volts)
CLK – Clock
~WR – se Low AND RD Low, possiamo scrivere sulla SRAM
~RD – se low AND WR High, possiamo leggere la ROM e la SRAM
CS_SRAM – se abilitato, seleziona la SRAM in scrittura
A0 – A15 – 16 linee di indirizzo della ROM (a seconda della configurazione anche della SRAM ed altri componenti)
D0 – D7 – le 8 linee dati attraverso le quali leggiamo/scriviamo la ROM/SRAM.
Reset – provoca un Reset dei componenti (abilitato Low)
Audio in – (non in uso)
GND – Massa
[/sstoggle][/sstoggles]
Terzo passo: Arduino Interface
Analizzando la struttura della cartuccia e il suo pinout abbiamo visto come il GameBoy possa allocare solamente indirizzi dati a 16 bit (ricordiamo le 16 linee dati A0-A15). Questo significa (in teoria, ma vedremo che in realtà non è così) che la capacità massima di allocamento è 2^16 byte = 65,536 bytes
Dal momento che questi 16 indirizzi controllano anche l’accesso alla sRAM e a tutti gli altri componenti della cartuccia, in realtà solamente gli indirizzi compresi tra 0x0000 e 0x777f sono dedicati alla ROM (gli indirizzi sono espressi base esadecimale), per un totale di 32,767 bytes su cui lavorare.
Il primo gioco per GameBoy mai realizzato fu “Tetris“, la cartuccia era provvista solamente di una ROM da 32,767 bytes, una quantità di spazio più che sufficiente per i giochi dell’epoca (lontano 1989).
Il GameBoy prende piede nel vecchio e nel nuovo continente, la tecnologia avanza, e 32kbyte di spazio cominciano ad essere pochi: la Nintendo introduce un nuovo chip nei suoi progetti, L’ MBC (Memory Bank Controller). Questo chip risolse totalmente il problema di spazio all’interno delle cartucce (uno standard mantenuto fino all’avvento del GameBoy Color): come ci suggerisce il nome, infatti, il circuito integrato funge da controllore di banchi di memoria; con opportuni accorgimenti e collegamenti, è in grado di pilotare ROM con 21 linee di indirizzo, allocando fino a 8Megabytes! (ultima versione MBC5)
Quello che ci rimane da fare ora è creare un collegamento tra la cartuccia e il nostro Arduino:

Il problema più grande che ho dovuto affrontare è stato quello della mancanza dei pin: la cartuccia, come abbiamo visto, è provvista di 32 pin, mentre Arduino possiede solamente 13 pin digitali (di cui 2 usati per la trasmissione seriale) e 5 analogici, come risolvete tale problema? Shift Registers!
[ideabox]Usando due ShiftRegisters 74LS595N collegati in serie serie, siamo in grado di pilotare fino a 16 uscite digitali utilizzando solamente 2 pin digitali del nostro Arduino (i2c bus).[/ideabox]
Quarto passo: Arduino Software
Ecco forse la parte più difficile, realizzare il software Arduino: prima di tutto schematizziamo il funzionamento del nostro programma e cosa ci interessa che faccia.
- Arduino attende l’inserimento della cartuccia.
- Una volta rilevata la cartuccia procede verificando il Checksum, per decretarne la validità e il corretto inserimento
- Arduino legge tutti gli attributi dell’Header (tutte le informazioni peculiari della cartuccia: nome gioco, grandezza rom, ram etc.) e le invia al computer.
- Il software attende in risposta dal computer uno dei seguenti comandi: Leggi ROM, Leggi sRAM, Scrivi sRam
- Ricomincia il ciclo del programma.
Qui un estratto dell’algoritmo usato per il Checksum (situato all’indirizzo 0x014d della ROM):
original source from TheNintendoGameboy:
x=0:FOR i=0134h TO 014Ch:x=x-MEM[i]-1:NEXT from my Arduino software: // Wait for serial input while (Serial.available() <= 0) { //coltrollo cartuccia inserita correttamente (checksum) int checksum = readbank0Address(0x014D) ; int x = 0; for (int addr = 0x0134; addr <= 0x014C; addr++) { x = x - readbank0Address(addr) - 1 ; } if ((x & 0xFF) == checksum) { digitalWrite(greenled, HIGH); } else digitalWrite(redled, HIGH); delay (50) ;
Qui in Allegato il codice sorgente completo.
Quinto passo: Computer Software
Analizzato il lato Arduino, passiamo ora al lato Computer:
Ho realizzato il software computer in Phyton basandomi su quello realizzato da InsideGadgets, ampliandolo, adattandolo alla mia board Arduino e perfezionandolo.
Il software funziona nel seguente modo:
- Il software attende la riposta dalla board Arduino.
- Una volta rilevata la Board Arduino, il software invia la richiesta dell’Header della cartuccia e stampa a schermo la risposta.
- A questo punto l’utente può scegliere tra varie opzioni: Leggi ROM – Leggi sRAM – Scrivi sRAM – Ricomincia loop programma.
- Il software invia il comando ad Arduino e salva i dati con il nome di intestazione del gioco della cartuccia
- Ricomincia il ciclo del programma.
Qui uno screenshoot del programma in esecuzione:
[ssbluelist]
Il necessario:
- Interprete python: Download
- Plugin python serial 2.6: Download
- Sorgente completa del programma per computer: Download
[/ssbluelist]
Conclusioni:
Fonti e ispiratori:
Per qualunqu dubbio o domanda non esitate a commentare 😉