V28C: Add support for Fujitsu MSP55LV128 GBA repros

Almost the same as Macronix MX29GL128E but sector size and write buffer are half the size.
Data pins 0 and 1 are also swapped and it still needs 5V to erase correctly.
This commit is contained in:
sanni 2017-09-14 23:09:14 +02:00 committed by GitHub
parent 8e717b39ee
commit 2846203b35
2 changed files with 108 additions and 8 deletions

View File

@ -2,8 +2,8 @@
Cartridge Reader for Arduino Mega2560
Author: sanni
Date: 2017-09-08
Version: V28B
Date: 2017-09-14
Version: V28C
SD lib: https://github.com/greiman/SdFat
LCD lib: https://github.com/adafruit/Adafruit_SSD1306
@ -34,7 +34,7 @@
YamaArashi - GBA flashrom bank switch command
**********************************************************************************/
char ver[5] = "V28B";
char ver[5] = "V28C";
/******************************************
Define Output

View File

@ -2062,7 +2062,7 @@ void idFlashrom_GBA() {
cartSize = 0x2000000;
}
else {
// Send swapped MX29GL128E ID command to flashrom
// Send swapped MX29GL128E/MSP55LV128 ID command to flashrom
writeWord_GAB(0xAAA, 0xAA);
writeWord_GAB(0x555, 0x55);
writeWord_GAB(0xAAA, 0x90);
@ -2071,8 +2071,10 @@ void idFlashrom_GBA() {
// Read flashrom ID
sprintf(flashid, "%02X%02X", ((readWord_GAB(0x2) >> 8) & 0xFF), (readWord_GAB(0x2) & 0xFF));
// MX29GL128E
// MX29GL128E or MSP55LV128
if (strcmp(flashid, "227E") == 0) {
// MX is 0xC2 and MSP is 0x4
romType = (readWord_GAB(0x0) & 0xFF);
cartSize = 0x1000000;
resetMX29GL128E_GBA();
}
@ -2181,6 +2183,29 @@ void eraseIntel4000_GBA() {
}
}
void sectorEraseMSP55LV128_GBA() {
unsigned long lastSector = 0xFFFFFF;
// Erase 256 sectors with 64kbytes each
unsigned long currSector;
for (currSector = 0x0; currSector < lastSector; currSector += 0x10000) {
writeWord_GAB(0xAAA, 0xAA);
writeWord_GAB(0x555, 0x55);
writeWord_GAB(0xAAA, 0x80);
writeWord_GAB(0xAAA, 0xAA);
writeWord_GAB(0x555, 0x55);
writeWord_GAB(currSector, 0x30);
// Read the status register
word statusReg = readWord_GAB(currSector);
while ((statusReg | 0xFF7F) != 0xFFFF) {
statusReg = readWord_GAB(currSector);
}
// Blink LED
PORTB ^= (1 << 4);
}
}
void sectorEraseMX29GL128E_GBA() {
unsigned long lastSector = 0xFFFFFF;
@ -2252,6 +2277,48 @@ void writeIntel4000_GBA() {
}
}
void writeMSP55LV128_GBA() {
for (unsigned long currSector = 0; currSector < fileSize; currSector += 0x10000) {
// Blink led
PORTB ^= (1 << 4);
// Write to flashrom
for (unsigned long currSdBuffer = 0; currSdBuffer < 0x10000; currSdBuffer += 512) {
// Fill SD buffer
myFile.read(sdBuffer, 512);
// Write 16 words at a time
for (int currWriteBuffer = 0; currWriteBuffer < 512; currWriteBuffer += 32) {
// Write Buffer command
writeWord_GAB(0xAAA, 0xAA);
writeWord_GAB(0x555, 0x55);
writeWord_GAB(currSector, 0x25);
// Write word count (minus 1)
writeWord_GAB(currSector, 0xF);
// Write buffer
word currWord;
for (byte currByte = 0; currByte < 32; currByte += 2) {
// Join two bytes into one word
currWord = ( ( sdBuffer[currWriteBuffer + currByte + 1] & 0xFF ) << 8 ) | ( sdBuffer[currWriteBuffer + currByte] & 0xFF );
writeWord_GBA(currSector + currSdBuffer + currWriteBuffer + currByte, currWord);
}
// Confirm write buffer
writeWord_GAB(currSector, 0x29);
// Read the status register
word statusReg = readWord_GAB(currSector + currSdBuffer + currWriteBuffer + 30);
while ((statusReg | 0xFF7F) != (currWord | 0xFF7F)) {
statusReg = readWord_GAB(currSector + currSdBuffer + currWriteBuffer + 30);
}
}
}
}
}
void writeMX29GL128E_GBA() {
for (unsigned long currSector = 0; currSector < fileSize; currSector += 0x20000) {
// Blink led
@ -2344,12 +2411,35 @@ void flashRepro_GBA() {
print_Msg(F(" Size: "));
print_Msg(cartSize / 0x100000);
println_Msg(F("MB"));
// MX29GL128E or MSP55LV128
if (strcmp(flashid, "227E") == 0) {
// MX is 0xC2 and MSP is 0x4
if (romType == 0xC2) {
println_Msg(F("Macronix MX29GL128E"));
}
else if (romType == 0x4) {
println_Msg(F("Fujitsu MSP55LV128"));
}
else {
println_Msg(romType);
print_Error(F("Unknown manufacturer"), true);
}
}
// Intel 4000L0YBQ0
else if (strcmp(flashid, "8802") == 0) {
println_Msg(F("Intel 4000L0YBQ0"));
}
println_Msg("");
println_Msg(F("This will erase your"));
println_Msg(F("Repro Cartridge."));
if (strcmp(flashid, "8802") == 0) {
println_Msg("Please use 3.3V!");
}
else if (strcmp(flashid, "227E") == 0) {
println_Msg("Attention: Use 5V!");
}
println_Msg("");
println_Msg(F("Press Button"));
println_Msg(F("to continue"));
display_Update();
wait();
@ -2392,7 +2482,12 @@ void flashRepro_GBA() {
//else {
println_Msg(F("Erasing..."));
display_Update();
sectorEraseMX29GL128E_GBA();
if (romType == 0xC2) {
sectorEraseMX29GL128E_GBA();
}
else if (romType == 0x4) {
sectorEraseMSP55LV128_GBA();
}
//}
}
@ -2409,7 +2504,12 @@ void flashRepro_GBA() {
writeIntel4000_GBA();
}
else if (strcmp(flashid, "227E") == 0) {
writeMX29GL128E_GBA();
if (romType == 0xC2) {
writeMX29GL128E_GBA();
}
else if (romType == 0x4) {
writeMSP55LV128_GBA();
}
}
// Close the file: