Possible DIY USB Genesis/MD Reader/writer
-
- Very interested
- Posts: 60
- Joined: Wed Mar 12, 2014 11:11 pm
- Location: Michigan
- Contact:
Possible DIY USB Genesis/MD Reader/writer
I eventually want to make a fully capable reader/writer supporting many mappers, roms and rams, but for now I spent the night working on this.
It is a Gen/MD cart reader and writer based on the Arduino MEGA using the EXTernal MEMory interface. I have used the exmem interface for normal external RAM expansion, but I think it would be nice to use as a reader and writer for both 16-bit Mask ROMs/EEPROMs and 8-bit SRAM/serial eeprom.
Does anyone think this would not work? Can I use three latches in this fashion to emulate a 16-bit data bus?
Obviously I would have to tie the second and third latch enable pins to an IO on the arduino and a few other miscellaneous pins such as !TIME, but I like the way it looks so far.
It is a Gen/MD cart reader and writer based on the Arduino MEGA using the EXTernal MEMory interface. I have used the exmem interface for normal external RAM expansion, but I think it would be nice to use as a reader and writer for both 16-bit Mask ROMs/EEPROMs and 8-bit SRAM/serial eeprom.
Does anyone think this would not work? Can I use three latches in this fashion to emulate a 16-bit data bus?
Obviously I would have to tie the second and third latch enable pins to an IO on the arduino and a few other miscellaneous pins such as !TIME, but I like the way it looks so far.
-
- Very interested
- Posts: 745
- Joined: Sat Dec 15, 2007 7:49 am
- Location: Kazakhstan, Pavlodar
-
- Very interested
- Posts: 60
- Joined: Wed Mar 12, 2014 11:11 pm
- Location: Michigan
- Contact:
-
- Very interested
- Posts: 745
- Joined: Sat Dec 15, 2007 7:49 am
- Location: Kazakhstan, Pavlodar
Here:
Full range 3 bytes addres used. A0 is not used, A1 connected to VA1 and so thru A23->VA23.
Code: Select all
// Cold reset
void DoColdReset()
// MRES/VRES --______--
{
PORTB = 0xFF;
PORTD = 0x00;
delay(1000);
PORTD = 0x03;
}
// Warm reset
void DoWarmReset()
// VRES --______--
{
PORTB = 0xFF;
PORTD = 0x02;
delay(100);
PORTD = 0x03;
}
// Read word
word DoReadWord(long Adr)
// ASEL - $000000..$7FFFFF
// CE0 - $000000..$3FFFFF
// TIME - $A13000..$A130FF
// AS --________--
// CTRL --________--
// CAS0 --________--
// CAS2 ------____--
{
byte Cmd, Adm, Adh;
word Result;
Adm = (Adr >> 8) & 0xFF; Adh = (Adr >> 16) & 0xFF;
PORTF = Adr & 0xFF; PORTK = Adm; PORTL = Adh;
Cmd = 0xEE; PORTB = 0xFF;
if ((Adh & 0x80) == 0x00) { Cmd = Cmd & 0xDF; }
if ((Adh & 0xC0) == 0x00) { Cmd = Cmd & 0xBF; }
if ((Adh == 0xA1) & (Adm == 0x30)) { Cmd = Cmd & 0x7F; }
PORTB = Cmd; Cmd = Cmd & 0xFD; Result = PINC; PORTB = Cmd;
// Three times for required delay
Result = (PINA << 8) | PINC;
Result = (PINA << 8) | PINC;
Result = (PINA << 8) | PINC;
PORTB = 0xFF;
return (Result);
}
// Write word
void DoWriteWord(long Adr, word Data)
// ASEL - $000000..$7FFFFF
// CE0 - $000000..$3FFFFF
// TIME - $A13000..$A130FF
// AS --____________--
// CTRL --____________--
// LWR -------_______--
// UWR -------_______--
{
byte Cmd, Adm, Adh;
Adm = (Adr >> 8) & 0xFF; Adh = (Adr >> 16) & 0xFF;
PORTF = Adr & 0xFF; PORTK = Adm; PORTL = Adh;
Cmd = 0xEF; PORTB = 0xFF;
if ((Adh & 0x80) == 0x00) { Cmd = Cmd & 0xDF; }
if ((Adh & 0xC0) == 0x00) { Cmd = Cmd & 0xBF; }
if ((Adh == 0xA1) & (Adm == 0x30)) { Cmd = Cmd & 0x7F; }
PORTB = Cmd;
DDRA = 0xFF; PORTA = lowByte(Data); DDRC = 0xFF; PORTC = highByte(Data);
PORTB = Cmd; Cmd = Cmd & 0xF3; PORTB = Cmd;
PORTB = 0xFF; DDRA = 0x00; PORTA = 0xFF; DDRC = 0x00; PORTC = 0xFF;
}
// Write low byte (D0-D7)
void DoWriteLow(long Adr, byte Data)
// ASEL - $000000..$7FFFFF
// CE0 - $000000..$3FFFFF
// TIME - $A13000..$A130FF
// AS --____________--
// CTRL --____________--
// LWR -------_______--
// UWR ----------------
{
byte Cmd, Adm, Adh;
Adm = (Adr >> 8) & 0xFF; Adh = (Adr >> 16) & 0xFF;
PORTF = Adr & 0xFF; PORTK = Adm; PORTL = Adh;
Cmd = 0xEF; PORTB = 0xFF;
if ((Adh & 0x80) == 0x00) { Cmd = Cmd & 0xDF; }
if ((Adh & 0xC0) == 0x00) { Cmd = Cmd & 0xBF; }
if ((Adh == 0xA1) & (Adm == 0x30)) { Cmd = Cmd & 0x7F; }
PORTB = Cmd;
DDRA = 0xFF; PORTA = Data; DDRC = 0x00; PORTC = 0xFF;
PORTB = Cmd; Cmd = Cmd & 0xFB; PORTB = Cmd;
PORTB = 0xFF; DDRA = 0x00; PORTA = 0xFF;
}
// Write high byte (D8-D15)
void DoWriteHigh(long Adr, byte Data)
// ASEL - $000000..$7FFFFF
// CE0 - $000000..$3FFFFF
// TIME - $A13000..$A130FF
// AS --____________--
// CTRL --____________--
// LWR ----------------
// UWR -------_______--
{
byte Cmd, Adm, Adh;
Adm = (Adr >> 8) & 0xFF; Adh = (Adr >> 16) & 0xFF;
PORTF = Adr & 0xFF; PORTK = Adm; PORTL = Adh;
Cmd = 0xEF; PORTB = 0xFF;
if ((Adh & 0x80) == 0x00) { Cmd = Cmd & 0xDF; }
if ((Adh & 0xC0) == 0x00) { Cmd = Cmd & 0xBF; }
if ((Adh == 0xA1) & (Adm == 0x30)) { Cmd = Cmd & 0x7F; }
PORTB = Cmd;
DDRA = 0x00; PORTA = 0xFF; DDRC = 0xFF; PORTC = Data;
PORTB = Cmd; Cmd = Cmd & 0xF7; PORTB = Cmd;
PORTB = 0xFF; DDRC = 0x00; PORTC = 0xFF;
}
You might also be interested ArDUMPino and SGCExplorer from Bruno Freitas.
www.brunofreitas.com/node/31
www.brunofreitas.com/node/42
I have the latter and the firmware is easily modifiable to poke & dump heavily protected cartridges.
www.brunofreitas.com/node/31
www.brunofreitas.com/node/42
I have the latter and the firmware is easily modifiable to poke & dump heavily protected cartridges.
-
- Very interested
- Posts: 60
- Joined: Wed Mar 12, 2014 11:11 pm
- Location: Michigan
- Contact:
Thanks a load! I am definitely going to look at this code and see if I want to go that path. Having no extra IC's would be a great goal. My main concern was the speed, and that is why I went with the EXMEM direction. 32k/s is fast enough for me though!HardWareMan wrote:Here:Full range 3 bytes addres used. A0 is not used, A1 connected to VA1 and so thru A23->VA23.Code: Select all
// Cold reset void DoColdReset() // MRES/VRES --______-- { PORTB = 0xFF; PORTD = 0x00; delay(1000); PORTD = 0x03; } // Warm reset void DoWarmReset() // VRES --______-- { PORTB = 0xFF; PORTD = 0x02; delay(100); PORTD = 0x03; } // Read word word DoReadWord(long Adr) // ASEL - $000000..$7FFFFF // CE0 - $000000..$3FFFFF // TIME - $A13000..$A130FF // AS --________-- // CTRL --________-- // CAS0 --________-- // CAS2 ------____-- { byte Cmd, Adm, Adh; word Result; Adm = (Adr >> 8) & 0xFF; Adh = (Adr >> 16) & 0xFF; PORTF = Adr & 0xFF; PORTK = Adm; PORTL = Adh; Cmd = 0xEE; PORTB = 0xFF; if ((Adh & 0x80) == 0x00) { Cmd = Cmd & 0xDF; } if ((Adh & 0xC0) == 0x00) { Cmd = Cmd & 0xBF; } if ((Adh == 0xA1) & (Adm == 0x30)) { Cmd = Cmd & 0x7F; } PORTB = Cmd; Cmd = Cmd & 0xFD; Result = PINC; PORTB = Cmd; // Three times for required delay Result = (PINA << 8) | PINC; Result = (PINA << 8) | PINC; Result = (PINA << 8) | PINC; PORTB = 0xFF; return (Result); } // Write word void DoWriteWord(long Adr, word Data) // ASEL - $000000..$7FFFFF // CE0 - $000000..$3FFFFF // TIME - $A13000..$A130FF // AS --____________-- // CTRL --____________-- // LWR -------_______-- // UWR -------_______-- { byte Cmd, Adm, Adh; Adm = (Adr >> 8) & 0xFF; Adh = (Adr >> 16) & 0xFF; PORTF = Adr & 0xFF; PORTK = Adm; PORTL = Adh; Cmd = 0xEF; PORTB = 0xFF; if ((Adh & 0x80) == 0x00) { Cmd = Cmd & 0xDF; } if ((Adh & 0xC0) == 0x00) { Cmd = Cmd & 0xBF; } if ((Adh == 0xA1) & (Adm == 0x30)) { Cmd = Cmd & 0x7F; } PORTB = Cmd; DDRA = 0xFF; PORTA = lowByte(Data); DDRC = 0xFF; PORTC = highByte(Data); PORTB = Cmd; Cmd = Cmd & 0xF3; PORTB = Cmd; PORTB = 0xFF; DDRA = 0x00; PORTA = 0xFF; DDRC = 0x00; PORTC = 0xFF; } // Write low byte (D0-D7) void DoWriteLow(long Adr, byte Data) // ASEL - $000000..$7FFFFF // CE0 - $000000..$3FFFFF // TIME - $A13000..$A130FF // AS --____________-- // CTRL --____________-- // LWR -------_______-- // UWR ---------------- { byte Cmd, Adm, Adh; Adm = (Adr >> 8) & 0xFF; Adh = (Adr >> 16) & 0xFF; PORTF = Adr & 0xFF; PORTK = Adm; PORTL = Adh; Cmd = 0xEF; PORTB = 0xFF; if ((Adh & 0x80) == 0x00) { Cmd = Cmd & 0xDF; } if ((Adh & 0xC0) == 0x00) { Cmd = Cmd & 0xBF; } if ((Adh == 0xA1) & (Adm == 0x30)) { Cmd = Cmd & 0x7F; } PORTB = Cmd; DDRA = 0xFF; PORTA = Data; DDRC = 0x00; PORTC = 0xFF; PORTB = Cmd; Cmd = Cmd & 0xFB; PORTB = Cmd; PORTB = 0xFF; DDRA = 0x00; PORTA = 0xFF; } // Write high byte (D8-D15) void DoWriteHigh(long Adr, byte Data) // ASEL - $000000..$7FFFFF // CE0 - $000000..$3FFFFF // TIME - $A13000..$A130FF // AS --____________-- // CTRL --____________-- // LWR ---------------- // UWR -------_______-- { byte Cmd, Adm, Adh; Adm = (Adr >> 8) & 0xFF; Adh = (Adr >> 16) & 0xFF; PORTF = Adr & 0xFF; PORTK = Adm; PORTL = Adh; Cmd = 0xEF; PORTB = 0xFF; if ((Adh & 0x80) == 0x00) { Cmd = Cmd & 0xDF; } if ((Adh & 0xC0) == 0x00) { Cmd = Cmd & 0xBF; } if ((Adh == 0xA1) & (Adm == 0x30)) { Cmd = Cmd & 0x7F; } PORTB = Cmd; DDRA = 0x00; PORTA = 0xFF; DDRC = 0xFF; PORTC = Data; PORTB = Cmd; Cmd = Cmd & 0xF7; PORTB = Cmd; PORTB = 0xFF; DDRC = 0x00; PORTC = 0xFF; }
Yes, I have seen both of those and the first one has too many components for what i would like to make. The second one uses a teensy ++ which are very expensive compared to the MEGA. I just bought three Teensy 2.0 for another project, but they are too limited.Eke wrote:You might also be interested ArDUMPino and SGCExplorer from Bruno Freitas.
www.brunofreitas.com/node/31
www.brunofreitas.com/node/42
I have the latter and the firmware is easily modifiable to poke & dump heavily protected cartridges.
Thanks for the links though.
If you use expander, you'll won't need a lot of pin (i2c ones)
I tried this one myself
http://gendev.spritesmind.net/wip/2011/ ... perwriter/
(and yes, it's a teensy, but anything with the i2c pins we'll do it)
I tried this one myself
http://gendev.spritesmind.net/wip/2011/ ... perwriter/
(and yes, it's a teensy, but anything with the i2c pins we'll do it)
-
- Very interested
- Posts: 60
- Joined: Wed Mar 12, 2014 11:11 pm
- Location: Michigan
- Contact:
-
- Very interested
- Posts: 60
- Joined: Wed Mar 12, 2014 11:11 pm
- Location: Michigan
- Contact:
-
- Very interested
- Posts: 60
- Joined: Wed Mar 12, 2014 11:11 pm
- Location: Michigan
- Contact:
Small update. I can now read the content of carts directly to the PC!
I am simply using bit manipulation within loops and pin arrays. I need to clean up the code first and write some intelligent functions (read header first, check for cart/backwards cart, etc) and then I can write a simple GUI and make it capable of writing to carts.
Thanks again for all of the help folks.
I am simply using bit manipulation within loops and pin arrays. I need to clean up the code first and write some intelligent functions (read header first, check for cart/backwards cart, etc) and then I can write a simple GUI and make it capable of writing to carts.
Thanks again for all of the help folks.
while cleaning the forum, I also found this post which could help you :
viewtopic.php?p=20062#20062
viewtopic.php?p=20062#20062