IL GAME BOY E LE SUE PROTEZIONI
18 Giugno 2023Mouse 1351 FIX
28 Agosto 2023Stanchi di dover comprare o cercare la ROM giusta da cambiare per il vostro Vic20 o C64?
Ora c’è la UNIRETROROM!, una ROM universale che può essere utilizzata come ROM caratteri, basic o kernal per il Commodore 64 o Vic 20.
La configurazione è semplicissima, basta spostare un jumper per passare da una modalità ad un’altra e una volta inserita al posto della ROM guasta il gioco è fatto.
Non è adatta a sostituire la ROM 23128 utilizzata sul C64C, questa infatti ingloba sia la funzionalità del Basic che quella del Kernal. Questa memoria ha un numero di pin maggiore e quindi non compatibile con questa scheda universale.
Per funzionare in modalità caratteri sul Vic20 occorre chiudere un jumper saldandoci una goccia di stagno.
Come costruire la ROM
L’idea di questa memoria universale è nata proprio per avere un solo componente che potesse sostituirne diversi senza dover andare a cercare quello specifico. Utile in caso di riparazioni ma anche se doveste sostituire una memoria guasta.
Questo è lo schema della memoria, è stato realizzato cercando di farla funzionare sulle 2364 e 2332 senza dover configurare diversi jumper. Questi sono il minimo che si possano utilizzare.
Purtroppo nel Vic20 la 2332 (ROM caratteri) utilizza entrambi i segnali CS1 e CS2 in maniera distinta e quindi è stato inserito un piccolo pad da saldare (J2) in caso si utilizzasse il segnale CS2.
Questo succede solo se la si usa come ROM caratteri nel Vic20, nel C64 non occorre perché il segnale CS2 non è usato e rimane sempre al positivo. Nelle altre configurazioni (2364) questo jumper deve essere aperto.
Per la realizzazione potere vedere la pagina GitHub cliccando sul pulsante.
Se volete vedere i video sulla realizzazione e programmazione seguiteci sul canale YouTube.
Come programmare la ROM?
Una volta realizzato il PCB resta solo da programmare la Eeprom con le rom corrette per il sistema che vogliamo utilizzare.
Es. Per il C64 ci sono le sue ROM diverse da quelle del Vic20 e non solo, si potrebbero utilizzare anche versioni diverse da quelle sulla memoria precedete, come una versione più aggiornata del Kernal o una memoria caratteri in un’altra lingua.
Le varie versioni le potete trovare su questo sito:
C64 > http://www.zimmers.net/anonftp/pub/cbm/firmware/computers/c64/
Vic20 > http://www.zimmers.net/anonftp/pub/cbm/firmware/computers/vic20/index.html
La sequenza corretta per realizzare la memoria da scrivere sulla Eeprom è questa di seguito:
#1 Caratteri (4kb) start $0000
#2 Caratteri (4kb) start $1000
#3 Basic (8kb) start $2000
#4 Kernal (8kb) start $4000
E’ necessario scrivere la ROM caratteri due volte perché l’ingresso A12 della memoria potrebbe essere messo al positivo dalla scheda madre.
L’immagine finale, contenente tutte queste ROMs, può essere realizzata concatenando i singoli file .BIN o con un Hex editor.
In alternativa ho realizzato un software apposito per semplificare il lavoro.. MAGICBIN! lo vedremo più sotto.
Per flashare la Eeprom io nel video ho utilizzato il programmatore Xgecu T48, ma va benissimo anche la sua versione più economica, il TL866+ oppure un altro programmatore che scriva le 28HC256.
Se utilizzate il programmatore della Xgecu, l’Xgpro, potete creare il file unico direttamente dal programma per la scrittura della memoria.
Basca scegliere prima la memoria da scrivere, caricare la prima immagine .BIN e ripetere i successivi caricamenti specificando di non sovrascrivere lo spazio non utilizzato e di far iniziare la scrittura sulla ROM (non da file) all’indirizzo libero dopo i dati precedenti. Come so qual è l’indirizzo? Guardate il grafico sopra e ci sono scritti gli indirizzi di partenza e finali di ogni ROM.
Cos'è MagicBIN?
MagicBIN è un software, gratuito, creato appositamente per semplificare il processo di creazione di queste multirom.
Spesso nelle cartucce gioco si possono inserire più immagini di giochi e poi selezionarle tramite un dipswitch o via software.
Per non diventare matti a incastrare tutti i file uno dietro l’altro, ecco che questo software è la soluzione al nostro problema.
Creato specificamente per aggiungere le ROM in successione, con questo software si potrà vedere, quanta memoria rimane libera nella eprom, riordinare i file per cambiare facilmente la successione, verificare il contenuto di ogni ROM e anche vedere graficamente una ROM caratteri. Con gli ultimi aggiornamenti ora è possibile anche modificare a mano ogni byte o disegnare il carattere nel casi si tratti di una memoria caratteri, per ora supportati solo 8×8.
Che ne pensate?
Leggo la ROM con Arduino
Da poco è uscito Arduino R4 e nelle sue versioni troviamo quella Wifi o quella minima.
Beh, quale miglior modo per sfruttare il display matrix integrato nella versione Wifi, se non quella di fargli leggere i caratteri della ROM del C64 per esempio? Vediamo come collegarlo e il programma che serve.
Se non avete visto il video, vi consiglio di guardarlo su YouTube così da avere già un’idea di come funzionano queste memorie, sempre che non lo sappiate già!.
Una brevissima descrizione di come funzionano e cosa fanno:
Le Eprom, dal nome Erasable Programmable Read Only Memory (Memoria di sola lettura, cancellabile e programmabile), sono dotate di una finestra dove si può vedere il chip all’interno che permette di essere cancellato se sottoposta a luce ultravioletta.
Differenti invece le prom che una volta scritte non possono più essere cancellate, oppure le Eeprom che possono essere cancellate tramite un segnale elettrico applicato su un apposito pin, niente più finestra e luce ultravioletta per 15/20min.
Queste memorie sono dotate principalmente (parliamo di quelle parallele) di una serie di pin di ingresso e altri pin di uscita (8 o 16, dipende dai bit in parallelo che utilizza), più altri pin per la gestione della lettura o scrittura del dato o del chip.
Es. durante la fase di lettura basterà comporre l’indirizzo in binario tramite gli ingressi A0-A12 (es: su una 2732, più la memoria è grande e più ingressi occorrono per gestirla), abbassare i segnali di chip enable e output enable e dopo un certo tempo (dipende dalla velocità del chip) avremo in uscita il valore della locazione richiesta.
Vediamo ora come leggere una piccola ROM con Arduino.
Questo è un piccolo esempio per leggere una 2732 o 2764 ma indirizzata non completamente perché con Arduino UNO o anche la versione Nano (quella nello schema) non bastano i pin.
Per risolvere questo problema si può utilizzare Arduino Mega oppure un integrato che converta i segnali in seriale/parallelo.
Per fare questa prova possiamo tranquillamente lasciare gli ingressi non usati della Eprom al GND. Nello schema troviamo anche un pulsante che servirà per far avanzare l’indirizzo di lettura della memoria così da visualizzare tutti i caratteri.
Questo è il codice utilizzato per leggere la ROM.
E’ stato aggiunto l’indirizzo A8 collegato sul pin D13 di Arduino.
/*
* ARDUINO TEST CHARACTER ROM
* BY RETROFIXER
* Pin Layout
*
* Arduino Pin | Circuit
* -------------+-----------
* A0 | EPROM IO0
* A1 | EPROM IO1
* A2 | EPROM IO2
* A3 | EPROM IO3
* A4 | EPROM IO4
* A5 | EPROM IO5
* D0 | EPROM IO6
* D1 | EPROM IO7
* -------------+-----------
* D2 | EPROM A0
* D3 | EPROM A1
* D4 | EPROM A2
* D5 | EPROM A3
* D6 | EPROM A4
* D7 | EPROM A5
* D8 | EPROM A6
* D9 | EPROM A7
* -------------+-----------
* D11 | CE
* D12 | OE
* -------------+-----------
* D10 | BUTTON
* -------------+-----------
* EPROM A8~A12 TO GND, P (pin27) TO VCC
*/
#include "Arduino_LED_Matrix.h"
const unsigned int DELAY_US = 10;
const unsigned int EEPROM_OE = 11;
const unsigned int EEPROM_CE = 12;
const unsigned int BUTTON = 10;
int currentState;
int lastState = HIGH;
int addr=0;
// Data pins (LSB to MSB)
const unsigned int dataPins[] = {A0, A1, A2, A3, A4, A5, 0, 1};
const unsigned int addressPins[] = {2, 3, 4, 5, 6, 7, 8, 9, 13};
//Display
const uint32_t logo[] = {
0xf01fe38,
0xc3003003,
0x8c1fe0f0,
};
byte frame[8][12] = {
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};
ArduinoLEDMatrix matrix;
void setup() {
// init display
matrix.begin();
// Setup Control Pins
pinMode(EEPROM_CE, OUTPUT);
pinMode(EEPROM_OE, OUTPUT);
pinMode(BUTTON, INPUT_PULLUP);
pinMode(13, OUTPUT);
// Setup Address Pins
for (byte i=0;i<9;i++) {
pinMode(addressPins[i],OUTPUT);
digitalWrite(addressPins[i], LOW);
}
// Disable Chip
digitalWrite(EEPROM_CE, HIGH);
digitalWrite(EEPROM_OE, HIGH);
matrix.loadFrame(logo);
delay(3000);
matrix.renderBitmap(frame, 8, 12);
}
void loop() {
//read button
currentState = digitalRead(BUTTON);
if (lastState == HIGH && currentState == LOW) { // button is pressed
lastState = LOW;
}
if(lastState == LOW && currentState == HIGH) { // button is released
lastState = HIGH;
//start
for (int i=addr;i=512) addr=0;
matrix.renderBitmap(frame, 8, 12);
}
delay(10);
}
void setAddress(unsigned int addr) {
for (byte i=0;i<9;i++) {
if((addr&bit(i))>0) {
digitalWrite(addressPins[i],HIGH);
} else {
digitalWrite(addressPins[i],LOW);
}
}
delayMicroseconds(DELAY_US);
digitalWrite(EEPROM_CE,LOW); // Activate Chip Enabled
delayMicroseconds(DELAY_US);
digitalWrite(EEPROM_OE,LOW); // Activate Output Enabled
}
void readData(byte row) {
int myData=0;
for (byte i=0;i<8;i++) {
frame[row][7-i]=0;
if (digitalRead(dataPins[i]) == HIGH) {
myData+=pow(2,i);
frame[row][7-i]=1;
}
}
delayMicroseconds(10);
digitalWrite(EEPROM_CE,HIGH); // Deactivate Chip Enabled
digitalWrite(EEPROM_OE,HIGH); // Deactivate Output Enabled
}