mirror of
https://github.com/sanni/cartreader.git
synced 2024-12-27 21:41:52 +01:00
Add support for MBC30 flash cart by HDR (thx to ManCloud)
Two issues were resolved: - this flashcart uses the Audio-In pin instead of the WR pin - Writing 4MB gets stuck after bank 170 and needed the SRAM to be mapped (same as MBC5)
This commit is contained in:
parent
5f3983b36c
commit
f947fb4e3f
@ -10,6 +10,7 @@
|
||||
word sramBanks;
|
||||
word romBanks;
|
||||
word lastByte = 0;
|
||||
boolean audioWE = 0;
|
||||
|
||||
/******************************************
|
||||
Menu
|
||||
@ -32,14 +33,20 @@ static const char GBMenuItem3[] PROGMEM = "Write Save";
|
||||
static const char* const menuOptionsGB[] PROGMEM = { GBMenuItem1, GBMenuItem2, GBMenuItem3, string_reset2 };
|
||||
|
||||
// GB Flash items
|
||||
static const char GBFlashItem1[] PROGMEM = "29F Cart (MBC3)";
|
||||
static const char GBFlashItem2[] PROGMEM = "29F Cart (MBC5)";
|
||||
static const char GBFlashItem3[] PROGMEM = "29F Cart (CAM)";
|
||||
static const char GBFlashItem4[] PROGMEM = "CFI Cart";
|
||||
static const char GBFlashItem5[] PROGMEM = "CFI Cart and Save";
|
||||
static const char GBFlashItem6[] PROGMEM = "GB Smart";
|
||||
//static const char GBFlashItem7[] PROGMEM = "Reset"; (stored in common strings array)
|
||||
static const char* const menuOptionsGBFlash[] PROGMEM = { GBFlashItem1, GBFlashItem2, GBFlashItem3, GBFlashItem4, GBFlashItem5, GBFlashItem6, string_reset2 };
|
||||
static const char GBFlashItem1[] PROGMEM = "29F016/32/33 Cart";
|
||||
static const char GBFlashItem2[] PROGMEM = "CFI Cart";
|
||||
static const char GBFlashItem3[] PROGMEM = "CFI Cart and Save";
|
||||
static const char GBFlashItem4[] PROGMEM = "GB Smart";
|
||||
//static const char GBFlashItem5[] PROGMEM = "Reset"; (stored in common strings array)
|
||||
static const char* const menuOptionsGBFlash[] PROGMEM = { GBFlashItem1, GBFlashItem2, GBFlashItem3, GBFlashItem4, string_reset2 };
|
||||
|
||||
// 29F Flash items
|
||||
static const char GBFlash29Item1[] PROGMEM = "DIY MBC3 (WR)";
|
||||
static const char GBFlash29Item2[] PROGMEM = "DIY MBC5 (WR)";
|
||||
static const char GBFlash29Item3[] PROGMEM = "HDR MBC30 (Audio)";
|
||||
static const char GBFlash29Item4[] PROGMEM = "HDR GameBoy Cam";
|
||||
//static const char GBFlashItem5[] PROGMEM = "Reset"; (stored in common strings array)
|
||||
static const char* const menuOptionsGBFlash29[] PROGMEM = { GBFlash29Item1, GBFlash29Item2, GBFlash29Item3, GBFlash29Item4, string_reset2 };
|
||||
|
||||
// Pelican Codebreaker, Brainboy, and Monster Brain Operation Menu
|
||||
static const char PelicanRead[] PROGMEM = "Read Device";
|
||||
@ -78,14 +85,24 @@ void gbxMenu() {
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// create submenu with title and 7 options to choose from
|
||||
// create submenu with title and 5 options to choose from
|
||||
unsigned char gbFlash;
|
||||
// Copy menuOptions out of progmem
|
||||
convertPgm(menuOptionsGBFlash, 7);
|
||||
gbFlash = question_box(F("Select type"), menuOptions, 7, 0);
|
||||
convertPgm(menuOptionsGBFlash, 5);
|
||||
gbFlash = question_box(F("Select type"), menuOptions, 5, 0);
|
||||
|
||||
// wait for user choice to come back from the question box menu
|
||||
switch (gbFlash) {
|
||||
case 0:
|
||||
//29F Menu
|
||||
// create submenu with title and 5 options to choose from
|
||||
unsigned char gbFlash29;
|
||||
// Copy menuOptions out of progmem
|
||||
convertPgm(menuOptionsGBFlash29, 5);
|
||||
gbFlash29 = question_box(F("Select MBC"), menuOptions, 5, 0);
|
||||
|
||||
// wait for user choice to come back from the question box menu
|
||||
switch (gbFlash29) {
|
||||
case 0:
|
||||
//Flash MBC3
|
||||
display_Clear();
|
||||
@ -125,6 +142,32 @@ void gbxMenu() {
|
||||
break;
|
||||
|
||||
case 2:
|
||||
//Also pulse Audio-In during writes
|
||||
display_Clear();
|
||||
display_Update();
|
||||
setup_GB();
|
||||
mode = mode_GB;
|
||||
|
||||
//Setup Audio-In(PH4) as Output
|
||||
DDRH |= (1 << 4);
|
||||
// Output a high signal on Audio-In(PH4)
|
||||
PORTH |= (1 << 4);
|
||||
//Tell writeByte_GB function to pulse Audio-In too
|
||||
audioWE = 1;
|
||||
|
||||
// Change working dir to root
|
||||
sd.chdir("/");
|
||||
//MBC5
|
||||
writeFlash29F_GB(3, 1);
|
||||
// Reset
|
||||
// Prints string out of the common strings array either with or without newline
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
wait();
|
||||
resetArduino();
|
||||
break;
|
||||
|
||||
case 3:
|
||||
//Flash GB Camera
|
||||
display_Clear();
|
||||
display_Update();
|
||||
@ -168,7 +211,13 @@ void gbxMenu() {
|
||||
resetArduino();
|
||||
break;
|
||||
|
||||
case 3:
|
||||
case 4:
|
||||
resetArduino();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// Flash CFI
|
||||
display_Clear();
|
||||
display_Update();
|
||||
@ -196,7 +245,7 @@ void gbxMenu() {
|
||||
resetArduino();
|
||||
break;
|
||||
|
||||
case 4:
|
||||
case 2:
|
||||
// Flash CFI and Save
|
||||
display_Clear();
|
||||
display_Update();
|
||||
@ -271,7 +320,7 @@ void gbxMenu() {
|
||||
resetArduino();
|
||||
break;
|
||||
|
||||
case 5:
|
||||
case 3:
|
||||
// Flash GB Smart
|
||||
display_Clear();
|
||||
display_Update();
|
||||
@ -279,7 +328,7 @@ void gbxMenu() {
|
||||
mode = mode_GB_GBSmart;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
case 4:
|
||||
resetArduino();
|
||||
break;
|
||||
}
|
||||
@ -535,6 +584,11 @@ void setup_GB() {
|
||||
// Output a low signal on RST(PH0) to initialize MMC correctly
|
||||
PORTH &= ~((1 << 0) | (1 << 1));
|
||||
|
||||
// Set Audio-In(PH4) to Input
|
||||
DDRH &= ~(1 << 4);
|
||||
// Enable Internal Pullup
|
||||
PORTH |= (1 << 4);
|
||||
|
||||
// Set Data Pins (D0-D7) to Input
|
||||
DDRC = 0x00;
|
||||
// Enable Internal Pullups
|
||||
@ -542,7 +596,7 @@ void setup_GB() {
|
||||
|
||||
delay(400);
|
||||
|
||||
// RST(PH0) to H
|
||||
// RST(PH0) to HIGH
|
||||
PORTH |= (1 << 0);
|
||||
|
||||
// Print start page
|
||||
@ -757,6 +811,9 @@ void writeByte_GB(int myAddress, byte myData) {
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
|
||||
if (audioWE)
|
||||
// Pull Audio-In(PH4) low
|
||||
PORTH &= ~(1 << 4);
|
||||
// Pull WR(PH5) low
|
||||
PORTH &= ~(1 << 5);
|
||||
|
||||
@ -766,8 +823,12 @@ void writeByte_GB(int myAddress, byte myData) {
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
|
||||
if (audioWE)
|
||||
// Pull Audio-In(PH4) HIGH
|
||||
PORTH |= (1 << 4);
|
||||
// Pull WR(PH5) HIGH
|
||||
PORTH |= (1 << 5);
|
||||
|
||||
// Leave WR high for at least 50ns
|
||||
__asm__("nop\n\t"
|
||||
"nop\n\t"
|
||||
@ -2055,6 +2116,9 @@ void writeFlash29F_GB(byte MBC, boolean flashErase) {
|
||||
}
|
||||
|
||||
if (MBC == 3) {
|
||||
if (audioWE)
|
||||
println_Msg(F("Writing flash MBC30 (Audio)"));
|
||||
else
|
||||
println_Msg(F("Writing flash MBC3"));
|
||||
display_Update();
|
||||
|
||||
@ -2073,6 +2137,9 @@ void writeFlash29F_GB(byte MBC, boolean flashErase) {
|
||||
|
||||
// Set ROM bank
|
||||
writeByte_GB(0x2100, currBank);
|
||||
if (romBanks > 128)
|
||||
// Map SRAM Bank to prevent getting stuck at 0x2A8000
|
||||
writeByte_GB(0x4000, 0x0);
|
||||
|
||||
if (currBank > 0) {
|
||||
currAddr = 0x4000;
|
||||
@ -2094,7 +2161,25 @@ void writeFlash29F_GB(byte MBC, boolean flashErase) {
|
||||
PORTH &= ~(1 << 6);
|
||||
|
||||
// Busy check
|
||||
//byte count = 0;
|
||||
while ((PINC & 0x80) != (sdBuffer[currByte] & 0x80)) {
|
||||
/*
|
||||
// Debug
|
||||
count++;
|
||||
__asm__("nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
if (count > 250) {
|
||||
println_Msg("");
|
||||
print_Msg(F("Bank: "));
|
||||
print_Msg(currBank);
|
||||
print_Msg(F(" Addr: "));
|
||||
println_Msg(currAddr + currByte);
|
||||
display_Update();
|
||||
wait();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// Switch OE/RD(PH6) to HIGH
|
||||
|
Loading…
Reference in New Issue
Block a user