Loopy ROM dumping working

This commit is contained in:
Roger Braunstein 2023-07-05 01:29:46 -07:00
parent 7daa114bb9
commit 1a7be97dc1
3 changed files with 68 additions and 59 deletions

View File

@ -1040,6 +1040,7 @@ void mainMenu() {
#ifdef enable_LOOPY #ifdef enable_LOOPY
case 21: case 21:
setup_LOOPY();
loopyMenu(); loopyMenu();
break; break;
#endif #endif

View File

@ -8,6 +8,15 @@ const uint32_t LOOPY_MAP_ROM_ZERO = 0x0E000000;
const uint32_t LOOPY_MAP_SRAM_ZERO = 0x02000000; const uint32_t LOOPY_MAP_SRAM_ZERO = 0x02000000;
const uint32_t LOOPY_SRAM_SIZE = 0x2000; const uint32_t LOOPY_SRAM_SIZE = 0x2000;
// Control pins
const int LOOPY_ROMCE = 42;
const int LOOPY_OE = 43;
const int LOOPY_RAMWE = 6;
const int LOOPY_RAMCS1 = 7;
const int LOOPY_RAMCS2 = A7;
char strbuf[9];
//****************************************** //******************************************
// SETUP // SETUP
//****************************************** //******************************************
@ -20,20 +29,22 @@ void setup_LOOPY() {
// PK1-PK7, PA1-PA7, PC0-PC3, PL0-PL3 // Take whole port and unset the exceptions later // PK1-PK7, PA1-PA7, PC0-PC3, PL0-PL3 // Take whole port and unset the exceptions later
DDRK = DDRA = DDRC = DDRL = 0xFF; DDRK = DDRA = DDRC = DDRL = 0xFF;
// Set Control Pins to Output // Control pins, all active low
// /RAMWE(PH6)/RAMCS2(PH4) pinMode(LOOPY_ROMCE, OUTPUT);
DDRH |= (1 << 6) | (1 << 4); pinMode(LOOPY_OE, OUTPUT);
// /CE(PL7) /OE(PL6) pinMode(LOOPY_RAMWE, OUTPUT);
DDRL |= (1 << 7) | (1 << 6); pinMode(LOOPY_RAMCS1, OUTPUT);
pinMode(LOOPY_RAMCS2, OUTPUT);
digitalWrite(LOOPY_ROMCE, HIGH);
digitalWrite(LOOPY_OE, HIGH);
digitalWrite(LOOPY_RAMWE, HIGH);
digitalWrite(LOOPY_RAMCS1, HIGH);
digitalWrite(LOOPY_RAMCS2, HIGH);
// Set Pins (D0-D15) to Input // Set Pins (D0-D15) to Input
dataIn_LOOPY(); dataIn_LOOPY();
// Reset HIGH (PF7) strcpy(romName, "unknown");
DDRF |= (1 << 7);
PORTF |= (1 << 7);
strcpy(romName, "LOOPY");
getCartInfo_LOOPY(); getCartInfo_LOOPY();
mode = mode_LOOPY; mode = mode_LOOPY;
@ -44,11 +55,12 @@ void setup_LOOPY() {
//****************************************** //******************************************
// Base Menu // Base Menu
static const char loopyMenuItem0[] PROGMEM = "Cart Info";
static const char loopyMenuItem1[] PROGMEM = "Read ROM"; static const char loopyMenuItem1[] PROGMEM = "Read ROM";
static const char loopyMenuItem2[] PROGMEM = "Read SRAM"; static const char loopyMenuItem2[] PROGMEM = "Read SRAM";
static const char loopyMenuItem3[] PROGMEM = "Write SRAM"; static const char loopyMenuItem3[] PROGMEM = "Write SRAM";
//static const char loopyMenuItem4[] PROGMEM = "Reset"; (stored in common strings array) //static const char loopyMenuItem4[] PROGMEM = "Reset"; (stored in common strings array)
static const char* const menuOptionsLOOPY[] PROGMEM = { loopyMenuItem1, loopyMenuItem2, loopyMenuItem3, string_reset2 }; static const char* const menuOptionsLOOPY[] PROGMEM = { loopyMenuItem0, loopyMenuItem1, loopyMenuItem2, loopyMenuItem3, string_reset2 };
void loopyMenu() { void loopyMenu() {
convertPgm(menuOptionsLOOPY, 4); convertPgm(menuOptionsLOOPY, 4);
@ -56,13 +68,19 @@ void loopyMenu() {
switch (mainMenu) { switch (mainMenu) {
case 0: case 0:
display_Clear();
display_Update();
setup_LOOPY();
break;
case 1:
// Read ROM // Read ROM
sd.chdir("/"); sd.chdir("/");
readROM_LOOPY(); readROM_LOOPY();
sd.chdir("/"); sd.chdir("/");
break; break;
case 1: case 2:
// Read SRAM // Read SRAM
if (sramSize) { if (sramSize) {
sd.chdir("/"); sd.chdir("/");
@ -83,7 +101,7 @@ void loopyMenu() {
#endif #endif
break; break;
case 2: case 3:
// Write SRAM // Write SRAM
if (sramSize) { if (sramSize) {
// Change working dir to root // Change working dir to root
@ -113,7 +131,7 @@ void loopyMenu() {
#endif #endif
break; break;
case 3: case 4:
// reset // reset
resetArduino(); resetArduino();
break; break;
@ -213,6 +231,7 @@ void setByte_LOOPY(uint8_t D) {
} }
void writeByte_LOOPY(unsigned long myAddress, byte myData) { void writeByte_LOOPY(unsigned long myAddress, byte myData) {
// TODO Update
setAddress_LOOPY(myAddress); setAddress_LOOPY(myAddress);
__asm__("nop\n\t"); __asm__("nop\n\t");
@ -245,38 +264,23 @@ void writeByte_LOOPY(unsigned long myAddress, byte myData) {
word readWord_LOOPY(unsigned long myAddress) { word readWord_LOOPY(unsigned long myAddress) {
setAddress_LOOPY(myAddress); setAddress_LOOPY(myAddress);
__asm__("nop\n\t"); digitalWrite(LOOPY_ROMCE, LOW);
digitalWrite(LOOPY_OE, LOW);
// Set CS2(PH0), /CS1(PH4), /WE0(PH5) to HIGH // 16mhz = 62.5ns
PORTH |= (1 << 0) | (1 << 4) | (1 << 5); NOP;
// Set /CE(PH3), /OE(PH6) to LOW NOP;
PORTH &= ~(1 << 3) & ~(1 << 6);
__asm__("nop\n\t" word tempWord = getWord_LOOPY();
"nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t");
word tempWord = ((PINA & 0xFF) << 8) | (PINC & 0xFF); digitalWrite(LOOPY_ROMCE, HIGH);
digitalWrite(LOOPY_OE, HIGH);
// Set /CE(PH3), /OE(PH6) to HIGH
PORTH |= (1 << 3) | (1 << 6);
// Setting CS2(PH0) LOW
PORTH &= ~(1 << 0);
__asm__("nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t");
return tempWord; return tempWord;
} }
byte readByte_LOOPY(unsigned long myAddress) { // SRAM BYTE byte readByte_LOOPY(unsigned long myAddress) { // SRAM BYTE
// TODO Update
setAddress_LOOPY(myAddress); setAddress_LOOPY(myAddress);
__asm__("nop\n\t"); __asm__("nop\n\t");
@ -387,17 +391,19 @@ void dataIn_LOOPY() {
//****************************************** //******************************************
void getCartInfo_LOOPY() { void getCartInfo_LOOPY() {
display_Clear();
// Set control // Set control
dataIn_LOOPY(); dataIn_LOOPY();
// Last word of ROM stored as 32-bit pointer at 000004h // Last word of ROM stored as 32-bit pointer at 000004h
// TODO make sure you have endianness right when interpreting this // TODO make sure you have endianness right when interpreting this
uint32_t headerRomSize = ((uint32_t)readWord_LOOPY(0x4) << 16 | (uint32_t)readWord_LOOPY(0x6)); uint32_t headerRomSize = ((uint32_t)readWord_LOOPY(0x4) << 16) | (uint32_t)readWord_LOOPY(0x6);
cartSize = headerRomSize - LOOPY_MAP_ROM_ZERO + 2; cartSize = headerRomSize - LOOPY_MAP_ROM_ZERO + 2;
// Get internal CRC32 from header // Get internal CRC32 from header
uint32_t cartHeaderCrc = (uint32_t)readWord_LOOPY(0x8) << 16 | (uint32_t)readWord_LOOPY(0xA); uint32_t cartHeaderCrc = ((uint32_t)readWord_LOOPY(0x8) << 16) | (uint32_t)readWord_LOOPY(0xA);
snprintf(checksumStr, 8, "%08X", cartHeaderCrc); sprintf(checksumStr, "%08lx", cartHeaderCrc);
// Look up in database // Look up in database
// compareCRC("loopy.txt", cartId, false, 0); // compareCRC("loopy.txt", cartId, false, 0);
@ -406,9 +412,11 @@ void getCartInfo_LOOPY() {
// But this is fine // But this is fine
sramSize = LOOPY_SRAM_SIZE; sramSize = LOOPY_SRAM_SIZE;
display_Clear();
println_Msg(F("Cart Info")); println_Msg(F("Cart Info"));
println_Msg(F(" ")); println_Msg(F(" "));
print_Msg(F("Magic: "));
sprintf(strbuf, "0x%08lx", ((uint32_t)readWord_LOOPY(0) << 16) | (uint32_t)readWord_LOOPY(0x2));
println_Msg(strbuf);
// print_Msg(F("Name: ")); // print_Msg(F("Name: "));
// println_Msg(romName); // println_Msg(romName);
print_Msg(F("CRC32: ")); print_Msg(F("CRC32: "));
@ -461,23 +469,20 @@ void readROM_LOOPY() {
print_FatalError(sd_error_STR); print_FatalError(sd_error_STR);
} }
word d = 0;
uint32_t progress = 0;
draw_progressbar(0, cartSize); draw_progressbar(0, cartSize);
for (unsigned long currBuffer = 0; currBuffer < cartSize / 2; currBuffer += 256) { // sdbuffer size is 512
for (int currWord = 0; currWord < 256; currWord++) { const size_t sdBufferSize = 512;
word myWord = readWord_LOOPY(currBuffer + currWord); for (unsigned long ptr = 0; ptr < cartSize;) {
// Split word into two bytes word myWord = readWord_LOOPY(ptr);
sdBuffer[d] = ((myWord >> 8) & 0xFF); sdBuffer[ptr++ % sdBufferSize] = ((myWord >> 8) & 0xFF);
sdBuffer[d + 1] = (myWord & 0xFF); sdBuffer[ptr++ % sdBufferSize] = (myWord & 0xFF);
d += 2; if (ptr % sdBufferSize == 0) {
myFile.write(sdBuffer, sdBufferSize);
} }
myFile.write(sdBuffer, 512); draw_progressbar(ptr, cartSize);
d = 0;
progress += 512;
draw_progressbar(progress, cartSize);
} }
// TODO this assumes size is divisible by 512
myFile.close(); myFile.close();
// Compare CRC32 to database and rename ROM if found // Compare CRC32 to database and rename ROM if found
@ -499,6 +504,7 @@ void readROM_LOOPY() {
//****************************************** //******************************************
void writeSRAM_LOOPY() { void writeSRAM_LOOPY() {
// TODO UPDATE
dataOut_LOOPY(); dataOut_LOOPY();
sprintf(filePath, "%s/%s", filePath, fileName); sprintf(filePath, "%s/%s", filePath, fileName);
@ -521,6 +527,7 @@ void writeSRAM_LOOPY() {
} }
void readSRAM_LOOPY() { void readSRAM_LOOPY() {
// TODO UPDATE
dataIn_LOOPY(); dataIn_LOOPY();
strcpy(fileName, romName); strcpy(fileName, romName);
@ -552,6 +559,7 @@ void readSRAM_LOOPY() {
} }
unsigned long verifySRAM_LOOPY() { unsigned long verifySRAM_LOOPY() {
// TODO UPDATE
dataIn_LOOPY(); dataIn_LOOPY();
writeErrors = 0; writeErrors = 0;

View File

@ -4,7 +4,7 @@ Anime Land (Japan).bin
HARIHARI Seal Paradise (Japan).bin HARIHARI Seal Paradise (Japan).bin
b82ac7f3 b82ac7f3
Dream Change - Kogane-chan no Fashion Party (Japan).bin Dream Change (Japan).bin
0fb0a794 0fb0a794
Nigaoe Artist (Japan).bin Nigaoe Artist (Japan).bin
@ -13,14 +13,14 @@ ef1b33f3
Wanwan Aijou Monogatari (Japan).bin Wanwan Aijou Monogatari (Japan).bin
10c5f568 10c5f568
Pasocom Collection (Japan).bin PC Collection (Japan).bin
fe3be881 fe3be881
Little Romance (Japan).bin Little Romance (Japan).bin
550616f0 550616f0
Loopy Town no Oheya ga Hoshii! (Japan).bin Loopy Town no Oheya ga Hoshii (Japan).bin
352b4ae6 352b4ae6
Lupiton no Wonder Palette (Japan).bin Lupiton's Wonder Palette (Japan).bin
f4662e66 f4662e66