mirror of
https://github.com/sanni/cartreader.git
synced 2025-01-15 06:29:08 +01:00
Moves loopy db into loopy.ino, adds format sram option
This commit is contained in:
parent
2b5168f144
commit
0d7b51806a
@ -609,34 +609,6 @@ void rewind_line(FsFile& readfile, byte count = 1) {
|
|||||||
readfile.seekCur(1);
|
readfile.seekCur(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool setRomName(const char* database, char* crcStr, int stripExtensionChars = 4) {
|
|
||||||
//Search for CRC32 in file
|
|
||||||
char gamename[96];
|
|
||||||
char crc_search[9];
|
|
||||||
bool found;
|
|
||||||
|
|
||||||
//go to root
|
|
||||||
sd.chdir();
|
|
||||||
if (!myFile.open(database, O_READ)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
//Search for same CRC in list
|
|
||||||
while (myFile.available()) {
|
|
||||||
//Read 2 lines (game name and CRC)
|
|
||||||
get_line(gamename, &myFile, sizeof(gamename));
|
|
||||||
get_line(crc_search, &myFile, sizeof(crc_search));
|
|
||||||
skip_line(&myFile); //Skip every 3rd line
|
|
||||||
|
|
||||||
if (strcmp(crc_search, crcStr) == 0) {
|
|
||||||
found = true;
|
|
||||||
strlcpy(romName, gamename, strlen(gamename) - stripExtensionChars + 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
myFile.close();
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate CRC32 if needed and compare it to CRC read from database
|
// Calculate CRC32 if needed and compare it to CRC read from database
|
||||||
boolean compareCRC(const char* database, uint32_t crc32sum, boolean renamerom, int offset) {
|
boolean compareCRC(const char* database, uint32_t crc32sum, boolean renamerom, int offset) {
|
||||||
char crcStr[9];
|
char crcStr[9];
|
||||||
|
@ -1,6 +1,59 @@
|
|||||||
//******************************************
|
//******************************************
|
||||||
// CASIO LOOPY MODULE
|
// CASIO LOOPY MODULE
|
||||||
//******************************************
|
//******************************************
|
||||||
|
// Loopy
|
||||||
|
// Cartridge Pinout
|
||||||
|
// 90P 2.1mm pitch connector
|
||||||
|
//
|
||||||
|
// +--------+
|
||||||
|
// +5V -| 1 90 |- D11
|
||||||
|
// -| 2 89 |- +5V
|
||||||
|
// -| 3 88 |- D9
|
||||||
|
// -| 4 87 |-
|
||||||
|
// -| 5 86 |- D7
|
||||||
|
// -| 6 85 |- D5
|
||||||
|
// -| 7 84 |- D15
|
||||||
|
// -| 8 83 |- D13
|
||||||
|
// RAMCS1 -| 9 82 |- D12
|
||||||
|
// -| 10 81 |- D1
|
||||||
|
// RAMWE -| 11 80 |-
|
||||||
|
// -| 12 79 |-
|
||||||
|
// GND -| 13 78 |- A2
|
||||||
|
// +5V -| 14 77 |- A4
|
||||||
|
// -| 15 76 |- A19
|
||||||
|
// -| 16 75 |- GND
|
||||||
|
// -| 17 74 |- A18
|
||||||
|
// -| 18 73 |- A16
|
||||||
|
// -| 19 72 |- A17
|
||||||
|
// -| 20 71 |- A14
|
||||||
|
// -| 21 70 |- A5
|
||||||
|
// A12 -| 22 69 |- A7
|
||||||
|
// A10 -| 23 68 |- A9
|
||||||
|
// A8 -| 24 67 |- A11
|
||||||
|
// A6 -| 25 66 |-
|
||||||
|
// A13 -| 26 65 |-
|
||||||
|
// A15 -| 27 64 |-
|
||||||
|
// A20 -| 28 63 |-
|
||||||
|
// +5V -| 29 62 |-
|
||||||
|
// A3 -| 30 61 |-
|
||||||
|
// A21 -| 31 60 |- CLK
|
||||||
|
// A1 -| 32 59 |-
|
||||||
|
// A0 -| 33 58 |-
|
||||||
|
// -| 34 57 |- +5V
|
||||||
|
// D0 -| 35 56 |- OE
|
||||||
|
// RESET -| 36 55 |-
|
||||||
|
// D2 -| 37 54 |- ROMCE
|
||||||
|
// D3 -| 38 53 |-
|
||||||
|
// D14 -| 39 52 |-
|
||||||
|
// D4 -| 40 51 |-
|
||||||
|
// D6 -| 41 50 |-
|
||||||
|
// D8 -| 42 49 |-
|
||||||
|
// -| 43 48 |-
|
||||||
|
// D10 -| 44 47 |- GND
|
||||||
|
// GND -| 45 46 |-
|
||||||
|
// +--------+
|
||||||
|
//
|
||||||
|
// * Blank pins have various uses depending on cartridge but are not necessary for dumping.
|
||||||
// IMPORTANT: All data are stored as BIG-ENDIAN. Many ROM dumps online are little endian.
|
// IMPORTANT: All data are stored as BIG-ENDIAN. Many ROM dumps online are little endian.
|
||||||
// See https://github.com/kasamikona/Loopy-Tools/blob/master/ROM%20Structure.md
|
// See https://github.com/kasamikona/Loopy-Tools/blob/master/ROM%20Structure.md
|
||||||
//
|
//
|
||||||
@ -23,8 +76,8 @@ const int LOOPY_RESET = A7;
|
|||||||
uint32_t loopyChecksum;
|
uint32_t loopyChecksum;
|
||||||
uint32_t loopyChecksumStart;
|
uint32_t loopyChecksumStart;
|
||||||
uint32_t loopyChecksumEnd;
|
uint32_t loopyChecksumEnd;
|
||||||
// Whether the cart was found (by checksum) in the database
|
|
||||||
bool loopyCartRecognized;
|
char loopyRomNameLong[64];
|
||||||
|
|
||||||
//******************************************
|
//******************************************
|
||||||
// SETUP
|
// SETUP
|
||||||
@ -54,7 +107,6 @@ void setup_LOOPY() {
|
|||||||
// Set Pins (D0-D15) to Input
|
// Set Pins (D0-D15) to Input
|
||||||
dataIn_LOOPY();
|
dataIn_LOOPY();
|
||||||
|
|
||||||
strcpy(romName, "unknown");
|
|
||||||
getCartInfo_LOOPY();
|
getCartInfo_LOOPY();
|
||||||
|
|
||||||
mode = mode_LOOPY;
|
mode = mode_LOOPY;
|
||||||
@ -69,14 +121,15 @@ static const char loopyMenuItem0[] PROGMEM = "Refresh Cart";
|
|||||||
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 = "Format SRAM";
|
||||||
static const char* const menuOptionsLOOPY[] PROGMEM = { loopyMenuItem0, loopyMenuItem1, loopyMenuItem2, loopyMenuItem3, string_reset2 };
|
static const char* const menuOptionsLOOPY[] PROGMEM = { loopyMenuItem0, loopyMenuItem1, loopyMenuItem2, loopyMenuItem3, loopyMenuItem4, string_reset2 };
|
||||||
|
|
||||||
void loopyMenu() {
|
void loopyMenu() {
|
||||||
convertPgm(menuOptionsLOOPY, 4);
|
convertPgm(menuOptionsLOOPY, 5);
|
||||||
uint8_t mainMenu = question_box(F("CASIO LOOPY MENU"), menuOptions, 4, 0);
|
uint8_t mainMenu = question_box(F("CASIO LOOPY MENU"), menuOptions, 5, 0);
|
||||||
display_Clear();
|
display_Clear();
|
||||||
display_Update();
|
display_Update();
|
||||||
|
bool waitForInput = false;
|
||||||
|
|
||||||
switch (mainMenu) {
|
switch (mainMenu) {
|
||||||
case 0:
|
case 0:
|
||||||
@ -88,6 +141,7 @@ void loopyMenu() {
|
|||||||
sd.chdir("/");
|
sd.chdir("/");
|
||||||
readROM_LOOPY();
|
readROM_LOOPY();
|
||||||
sd.chdir("/");
|
sd.chdir("/");
|
||||||
|
waitForInput = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
@ -97,13 +151,7 @@ void loopyMenu() {
|
|||||||
display_Update();
|
display_Update();
|
||||||
readSRAM_LOOPY();
|
readSRAM_LOOPY();
|
||||||
sd.chdir("/");
|
sd.chdir("/");
|
||||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
waitForInput = true;
|
||||||
// Wait for user input
|
|
||||||
// Prints string out of the common strings array either with or without newline
|
|
||||||
print_STR(press_button_STR, 1);
|
|
||||||
display_Update();
|
|
||||||
wait();
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
@ -123,21 +171,33 @@ void loopyMenu() {
|
|||||||
print_STR(_bytes_STR, 1);
|
print_STR(_bytes_STR, 1);
|
||||||
print_Error(did_not_verify_STR);
|
print_Error(did_not_verify_STR);
|
||||||
}
|
}
|
||||||
|
waitForInput = true;
|
||||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
|
||||||
// Wait for user input
|
|
||||||
// Prints string out of the common strings array either with or without newline
|
|
||||||
print_STR(press_button_STR, 1);
|
|
||||||
display_Update();
|
|
||||||
wait();
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
|
// Format SRAM
|
||||||
|
println_Msg(F("Formatting SRAM..."));
|
||||||
|
display_Update();
|
||||||
|
formatSRAM_LOOPY();
|
||||||
|
waitForInput = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5:
|
||||||
// reset
|
// reset
|
||||||
resetArduino();
|
resetArduino();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||||
|
if (waitForInput) {
|
||||||
|
// Wait for user input
|
||||||
|
println_Msg(F(""));
|
||||||
|
// Prints string out of the common strings array either with or without newline
|
||||||
|
print_STR(press_button_STR, 1);
|
||||||
|
display_Update();
|
||||||
|
wait();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//******************************************
|
//******************************************
|
||||||
@ -181,11 +241,7 @@ void setAddress_LOOPY(unsigned long A) {
|
|||||||
| (bitRead(A, 8) << 1)
|
| (bitRead(A, 8) << 1)
|
||||||
| (bitRead(A, 10) << 2)
|
| (bitRead(A, 10) << 2)
|
||||||
| (bitRead(A, 12) << 3);
|
| (bitRead(A, 12) << 3);
|
||||||
// PL0 A5
|
// CAUTION PORTL is shared, writing to PORTL indiscriminately will mess with CE/OE
|
||||||
// PL1 A7
|
|
||||||
// PL2 A9
|
|
||||||
// PL3 A11
|
|
||||||
// CAUTION PORTL is shared!
|
|
||||||
// D42 PL7 CE
|
// D42 PL7 CE
|
||||||
// D43 PL6 OE
|
// D43 PL6 OE
|
||||||
// D44 PL5
|
// D44 PL5
|
||||||
@ -221,7 +277,6 @@ uint16_t getWord_LOOPY() {
|
|||||||
// D15 PJ0 D13
|
// D15 PJ0 D13
|
||||||
// A4 PF4 D14
|
// A4 PF4 D14
|
||||||
// D4 PG5 D15
|
// D4 PG5 D15
|
||||||
|
|
||||||
return bitRead(PINK, 0)
|
return bitRead(PINK, 0)
|
||||||
| (bitRead(PINA, 0) << 1)
|
| (bitRead(PINA, 0) << 1)
|
||||||
| (bitRead(PINF, 6) << 2)
|
| (bitRead(PINF, 6) << 2)
|
||||||
@ -252,6 +307,7 @@ uint8_t getByte_LOOPY() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setByte_LOOPY(uint8_t D) {
|
void setByte_LOOPY(uint8_t D) {
|
||||||
|
// Since D lines are spread among so many ports, this is far more legible, and only used for SRAM
|
||||||
digitalWrite(A8, bitRead(D, 0));
|
digitalWrite(A8, bitRead(D, 0));
|
||||||
digitalWrite(22, bitRead(D, 1));
|
digitalWrite(22, bitRead(D, 1));
|
||||||
digitalWrite(A6, bitRead(D, 2));
|
digitalWrite(A6, bitRead(D, 2));
|
||||||
@ -332,8 +388,7 @@ void dataOut_LOOPY() {
|
|||||||
// // PF0-PF6
|
// // PF0-PF6
|
||||||
// DDRF |= 0b0111111;
|
// DDRF |= 0b0111111;
|
||||||
|
|
||||||
// TODO we could really only control the lower bits since we never write words just bytes
|
// Only bothering to change lower bits since we never write words just bytes
|
||||||
|
|
||||||
pinMode(A8, OUTPUT);
|
pinMode(A8, OUTPUT);
|
||||||
pinMode(22, OUTPUT);
|
pinMode(22, OUTPUT);
|
||||||
pinMode(A6, OUTPUT);
|
pinMode(A6, OUTPUT);
|
||||||
@ -388,6 +443,31 @@ void dataIn_LOOPY() {
|
|||||||
// CART INFO
|
// CART INFO
|
||||||
//******************************************
|
//******************************************
|
||||||
|
|
||||||
|
// A little different than many games, loopy DB stores the checksum present in the header, so we can determine the rom name before saving, without renaming
|
||||||
|
bool setRomName_LOOPY(const char* database, char* crcStr, int stripExtensionChars = 4) {
|
||||||
|
char gamename[96];
|
||||||
|
char crc_search[9];
|
||||||
|
bool found;
|
||||||
|
|
||||||
|
sd.chdir();
|
||||||
|
if (!myFile.open(database, O_READ)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
while (myFile.available()) {
|
||||||
|
get_line(gamename, &myFile, sizeof(gamename));
|
||||||
|
get_line(crc_search, &myFile, sizeof(crc_search));
|
||||||
|
skip_line(&myFile); //Skip every 3rd line
|
||||||
|
if (strcmp(crc_search, crcStr) == 0) {
|
||||||
|
found = true;
|
||||||
|
strlcpy(loopyRomNameLong, gamename, strlen(gamename) - stripExtensionChars + 1);
|
||||||
|
strcpy(romName, loopyRomNameLong);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
myFile.close();
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
void getCartInfo_LOOPY() {
|
void getCartInfo_LOOPY() {
|
||||||
display_Clear();
|
display_Clear();
|
||||||
|
|
||||||
@ -412,12 +492,14 @@ void getCartInfo_LOOPY() {
|
|||||||
sprintf(checksumStr, "%08lX", loopyChecksum);
|
sprintf(checksumStr, "%08lX", loopyChecksum);
|
||||||
|
|
||||||
// Look up in database
|
// Look up in database
|
||||||
loopyCartRecognized = setRomName("loopy.txt", checksumStr);
|
strcpy(loopyRomNameLong, "LOOPY");
|
||||||
|
strcpy(romName, loopyRomNameLong);
|
||||||
|
setRomName_LOOPY("loopy.txt", checksumStr);
|
||||||
|
|
||||||
println_Msg(F("Cart Info"));
|
println_Msg(F("Cart Info"));
|
||||||
println_Msg(F(" "));
|
println_Msg(F(" "));
|
||||||
print_Msg(F("Name: "));
|
print_Msg(F("Name: "));
|
||||||
println_Msg(romName);
|
println_Msg(loopyRomNameLong);
|
||||||
print_Msg(F("Checksum: "));
|
print_Msg(F("Checksum: "));
|
||||||
println_Msg(checksumStr);
|
println_Msg(checksumStr);
|
||||||
print_Msg(F("Size: "));
|
print_Msg(F("Size: "));
|
||||||
@ -514,19 +596,6 @@ void readROM_LOOPY() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
display_Update();
|
display_Update();
|
||||||
|
|
||||||
// Compare CRC32 to database and rename ROM if found
|
|
||||||
// Arguments: database name, precalculated crc string or 0 to calculate, rename rom or not, starting offset
|
|
||||||
//compareCRC("loopy.txt", 0, 1, 0x80);
|
|
||||||
|
|
||||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
|
||||||
// Wait for user input
|
|
||||||
println_Msg(F(""));
|
|
||||||
// Prints string out of the common strings array either with or without newline
|
|
||||||
print_STR(press_button_STR, 1);
|
|
||||||
display_Update();
|
|
||||||
wait();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//******************************************
|
//******************************************
|
||||||
@ -573,6 +642,27 @@ void writeSRAM_LOOPY() {
|
|||||||
dataIn_LOOPY();
|
dataIn_LOOPY();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void formatSRAM_LOOPY() {
|
||||||
|
dataIn_LOOPY();
|
||||||
|
digitalWrite(LOOPY_ROMCE, HIGH);
|
||||||
|
digitalWrite(LOOPY_RAMCS1, LOW);
|
||||||
|
digitalWrite(LOOPY_RESET, HIGH);
|
||||||
|
digitalWrite(LOOPY_OE, LOW);
|
||||||
|
|
||||||
|
for (unsigned long currByte = 0; currByte < sramSize; currByte++) {
|
||||||
|
writeByte_LOOPY(currByte, 0);
|
||||||
|
if (currByte % 512 == 0) {
|
||||||
|
blinkLED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
digitalWrite(LOOPY_RAMCS1, HIGH);
|
||||||
|
digitalWrite(LOOPY_OE, HIGH);
|
||||||
|
dataIn_LOOPY();
|
||||||
|
print_STR(done_STR, 1);
|
||||||
|
display_Update();
|
||||||
|
}
|
||||||
|
|
||||||
void readSRAM_LOOPY() {
|
void readSRAM_LOOPY() {
|
||||||
dataIn_LOOPY();
|
dataIn_LOOPY();
|
||||||
|
|
||||||
@ -644,6 +734,3 @@ unsigned long verifySRAM_LOOPY() {
|
|||||||
return writeErrors;
|
return writeErrors;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
//******************************************
|
|
||||||
// End of File
|
|
||||||
//******************************************
|
|
36
sd/loopy.txt
36
sd/loopy.txt
@ -1,26 +1,26 @@
|
|||||||
Anime Land (Japan).bin
|
Anime Land.bin
|
||||||
3FD9713B
|
98A0597D
|
||||||
|
|
||||||
HARIHARI Seal Paradise (Japan).bin
|
HARIHARI Seal Paradise.bin
|
||||||
B82AC7F3
|
7CB100B3
|
||||||
|
|
||||||
Dream Change (Japan).bin
|
Dream Change.bin
|
||||||
0FB0A794
|
F6D41645
|
||||||
|
|
||||||
Nigaoe Artist (Japan).bin
|
Nigaoe Artist.bin
|
||||||
EF1B33F3
|
2046476F
|
||||||
|
|
||||||
Wanwan Aijou Monogatari (Japan).bin
|
Wanwan Aijou Monogatari.bin
|
||||||
10C5F568
|
D90FE762
|
||||||
|
|
||||||
PC Collection (Japan).bin
|
PC Collection.bin
|
||||||
FE3BE881
|
F294F931
|
||||||
|
|
||||||
Little Romance (Japan).bin
|
Little Romance.bin
|
||||||
550616F0
|
6A410BB2
|
||||||
|
|
||||||
Loopy Town no Oheya ga Hoshii (Japan).bin
|
Loopy Town no Oheya ga Hoshii.bin
|
||||||
352B4AE6
|
8373E9DD
|
||||||
|
|
||||||
Lupiton's Wonder Palette (Japan).bin
|
Lupiton's Wonder Palette.bin
|
||||||
F4662E66
|
6E00CE71
|
||||||
|
Loading…
x
Reference in New Issue
Block a user