Merge branch 'master' into patch-1

This commit is contained in:
sanni 2018-10-14 10:16:07 +02:00 committed by GitHub
commit 4f6f79b3b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 12186 additions and 12187 deletions

View File

@ -1,20 +1,20 @@
#include <EEPROM.h> #include <EEPROM.h>
#include <Arduino.h> // for type definitions #include <Arduino.h> // for type definitions
template <class T> int EEPROM_writeAnything(int ee, const T& value) template <class T> int EEPROM_writeAnything(int ee, const T& value)
{ {
const byte* p = (const byte*)(const void*)&value; const byte* p = (const byte*)(const void*)&value;
unsigned int i; unsigned int i;
for (i = 0; i < sizeof(value); i++) for (i = 0; i < sizeof(value); i++)
EEPROM.write(ee++, *p++); EEPROM.write(ee++, *p++);
return i; return i;
} }
template <class T> int EEPROM_readAnything(int ee, T& value) template <class T> int EEPROM_readAnything(int ee, T& value)
{ {
byte* p = (byte*)(void*)&value; byte* p = (byte*)(void*)&value;
unsigned int i; unsigned int i;
for (i = 0; i < sizeof(value); i++) for (i = 0; i < sizeof(value); i++)
*p++ = EEPROM.read(ee++); *p++ = EEPROM.read(ee++);
return i; return i;
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,499 +1,499 @@
//****************************************** //******************************************
// SEGA MEGA DRIVE MODULE // SEGA MEGA DRIVE MODULE
//****************************************** //******************************************
/****************************************** /******************************************
Variables Variables
*****************************************/ *****************************************/
unsigned long sramEnd; unsigned long sramEnd;
/****************************************** /******************************************
Menu Menu
*****************************************/ *****************************************/
// MD menu items // MD menu items
static const char MDMenuItem1[] PROGMEM = "Read Rom"; static const char MDMenuItem1[] PROGMEM = "Read Rom";
static const char MDMenuItem2[] PROGMEM = "Read Save"; static const char MDMenuItem2[] PROGMEM = "Read Save";
static const char MDMenuItem3[] PROGMEM = "Write Save"; static const char MDMenuItem3[] PROGMEM = "Write Save";
static const char MDMenuItem4[] PROGMEM = "Write Flashcart"; static const char MDMenuItem4[] PROGMEM = "Write Flashcart";
static const char MDMenuItem5[] PROGMEM = "Reset"; static const char MDMenuItem5[] PROGMEM = "Reset";
static const char* const menuOptionsMD[] PROGMEM = {MDMenuItem1, MDMenuItem2, MDMenuItem3, MDMenuItem4, MDMenuItem5}; static const char* const menuOptionsMD[] PROGMEM = {MDMenuItem1, MDMenuItem2, MDMenuItem3, MDMenuItem4, MDMenuItem5};
// Sega start menu // Sega start menu
void segaMenu() { void segaMenu() {
display_Clear(); display_Clear();
display_Update(); display_Update();
setup_MD(); setup_MD();
mode = mode_MD; mode = mode_MD;
} }
void mdMenu() { void mdMenu() {
// create menu with title and 5 options to choose from // create menu with title and 5 options to choose from
unsigned char mainMenu; unsigned char mainMenu;
// Copy menuOptions out of progmem // Copy menuOptions out of progmem
convertPgm(menuOptionsMD, 5); convertPgm(menuOptionsMD, 5);
mainMenu = question_box("MEGA DRIVE Reader", menuOptions, 3, 0); mainMenu = question_box("MEGA DRIVE Reader", menuOptions, 3, 0);
// wait for user choice to come back from the question box menu // wait for user choice to come back from the question box menu
switch (mainMenu) switch (mainMenu)
{ {
case 0: case 0:
display_Clear(); display_Clear();
// Change working dir to root // Change working dir to root
sd.chdir("/"); sd.chdir("/");
readROM_MD(); readROM_MD();
//compare_checksum_MD(); //compare_checksum_MD();
break; break;
case 1: case 1:
display_Clear(); display_Clear();
// Does cartridge have SRAM // Does cartridge have SRAM
if ((saveType == 1) || (saveType == 2)) { if ((saveType == 1) || (saveType == 2)) {
// Change working dir to root // Change working dir to root
sd.chdir("/"); sd.chdir("/");
println_Msg(F("Reading Sram...")); println_Msg(F("Reading Sram..."));
display_Update(); display_Update();
enableSram_MD(1); enableSram_MD(1);
readSram_MD(); readSram_MD();
enableSram_MD(0); enableSram_MD(0);
} }
else { else {
print_Error(F("Cart has no Sram"), false); print_Error(F("Cart has no Sram"), false);
} }
break; break;
case 2: case 2:
display_Clear(); display_Clear();
// Does cartridge have SRAM // Does cartridge have SRAM
if ((saveType == 1) || (saveType == 2)) { if ((saveType == 1) || (saveType == 2)) {
// Change working dir to root // Change working dir to root
sd.chdir("/"); sd.chdir("/");
// Launch file browser // Launch file browser
fileBrowser("Select srm file"); fileBrowser("Select srm file");
display_Clear(); display_Clear();
enableSram_MD(1); enableSram_MD(1);
writeSram_MD(); writeSram_MD();
writeErrors = verifySram_MD(); writeErrors = verifySram_MD();
enableSram_MD(0); enableSram_MD(0);
if (writeErrors == 0) { if (writeErrors == 0) {
println_Msg(F("Sram verified OK")); println_Msg(F("Sram verified OK"));
display_Update(); display_Update();
} }
else { else {
print_Msg(F("Error: ")); print_Msg(F("Error: "));
print_Msg(writeErrors); print_Msg(writeErrors);
println_Msg(F(" bytes ")); println_Msg(F(" bytes "));
print_Error(F("did not verify."), false); print_Error(F("did not verify."), false);
} }
} }
else { else {
print_Error(F("Cart has no Sram"), false); print_Error(F("Cart has no Sram"), false);
} }
break; break;
/*case 3: /*case 3:
// Change working dir to root // Change working dir to root
sd.chdir("/"); sd.chdir("/");
writeFlash_MD(); writeFlash_MD();
// Reset // Reset
wait(); wait();
asm volatile (" jmp 0"); asm volatile (" jmp 0");
break; break;
case 4: case 4:
asm volatile (" jmp 0"); asm volatile (" jmp 0");
break;*/ break;*/
} }
println_Msg(F("")); println_Msg(F(""));
println_Msg(F("Press Button...")); println_Msg(F("Press Button..."));
display_Update(); display_Update();
wait(); wait();
} }
/****************************************** /******************************************
Setup Setup
*****************************************/ *****************************************/
void setup_MD() { void setup_MD() {
// Set Address Pins to Output // Set Address Pins to Output
//A0-A7 //A0-A7
DDRF = 0xFF; DDRF = 0xFF;
//A8-A15 //A8-A15
DDRK = 0xFF; DDRK = 0xFF;
//A16-A23 //A16-A23
DDRL = 0xFF; DDRL = 0xFF;
// Set Control Pins to Output RST(PH0) CS(PH3) WRH(PH4) WRL(PH5) OE(PH6) // Set Control Pins to Output RST(PH0) CS(PH3) WRH(PH4) WRL(PH5) OE(PH6)
DDRH |= (1 << 0) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6); DDRH |= (1 << 0) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6);
// Set TIME(PJ0) to Output // Set TIME(PJ0) to Output
DDRJ |= (1 << 0); DDRJ |= (1 << 0);
// Set Data Pins (D0-D15) to Input // Set Data Pins (D0-D15) to Input
DDRC = 0x00; DDRC = 0x00;
DDRA = 0x00; DDRA = 0x00;
// Setting RST(PH0) CS(PH3) WRH(PH4) WRL(PH5) OE(PH6) HIGH // Setting RST(PH0) CS(PH3) WRH(PH4) WRL(PH5) OE(PH6) HIGH
PORTH |= (1 << 0) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6); PORTH |= (1 << 0) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6);
// Setting TIME(PJ0) HIGH // Setting TIME(PJ0) HIGH
PORTJ |= (1 << 0); PORTJ |= (1 << 0);
delay(200); delay(200);
// Print all the info // Print all the info
getCartInfo_MD(); getCartInfo_MD();
} }
/****************************************** /******************************************
I/O Functions I/O Functions
*****************************************/ *****************************************/
/****************************************** /******************************************
Low level functions Low level functions
*****************************************/ *****************************************/
void writeWord_MD(unsigned long myAddress, word myData) { void writeWord_MD(unsigned long myAddress, word myData) {
PORTF = myAddress & 0xFF; PORTF = myAddress & 0xFF;
PORTK = (myAddress >> 8) & 0xFF; PORTK = (myAddress >> 8) & 0xFF;
PORTL = (myAddress >> 16) & 0xFF; PORTL = (myAddress >> 16) & 0xFF;
PORTC = myData; PORTC = myData;
PORTA = (myData >> 8) & 0xFF; PORTA = (myData >> 8) & 0xFF;
// Arduino running at 16Mhz -> one nop = 62.5ns // Arduino running at 16Mhz -> one nop = 62.5ns
// Wait till output is stable // Wait till output is stable
__asm__("nop\n\t""nop\n\t"); __asm__("nop\n\t""nop\n\t");
// Switch WR(PH5) to LOW // Switch WR(PH5) to LOW
PORTH &= ~(1 << 5); PORTH &= ~(1 << 5);
// Setting CS(PH3) LOW // Setting CS(PH3) LOW
PORTH &= ~(1 << 3); PORTH &= ~(1 << 3);
// Leave WR low for at least 200ns // Leave WR low for at least 200ns
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t"); __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
// Setting CS(PH3) HIGH // Setting CS(PH3) HIGH
PORTH |= (1 << 3); PORTH |= (1 << 3);
// Switch WR(PH5) to HIGH // Switch WR(PH5) to HIGH
PORTH |= (1 << 5); PORTH |= (1 << 5);
// Leave WR high for at least 50ns // Leave WR high for at least 50ns
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t"); __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
} }
word readWord_MD(unsigned long myAddress) { word readWord_MD(unsigned long myAddress) {
PORTF = myAddress & 0xFF; PORTF = myAddress & 0xFF;
PORTK = (myAddress >> 8) & 0xFF; PORTK = (myAddress >> 8) & 0xFF;
PORTL = (myAddress >> 16) & 0xFF; PORTL = (myAddress >> 16) & 0xFF;
// Arduino running at 16Mhz -> one nop = 62.5ns // Arduino running at 16Mhz -> one nop = 62.5ns
__asm__("nop\n\t"); __asm__("nop\n\t");
// Setting CS(PH3) LOW // Setting CS(PH3) LOW
PORTH &= ~(1 << 3); PORTH &= ~(1 << 3);
// Setting OE(PH6) LOW // Setting OE(PH6) LOW
PORTH &= ~(1 << 6); PORTH &= ~(1 << 6);
// Long delay here or there will be read errors // Long delay here or there will be read errors
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t"); __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
// Read // Read
word tempWord = ( ( PINA & 0xFF ) << 8 ) | ( PINC & 0xFF ); word tempWord = ( ( PINA & 0xFF ) << 8 ) | ( PINC & 0xFF );
// Setting CS(PH3) HIGH // Setting CS(PH3) HIGH
PORTH |= (1 << 3); PORTH |= (1 << 3);
// Setting OE(PH6) HIGH // Setting OE(PH6) HIGH
PORTH |= (1 << 6); PORTH |= (1 << 6);
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t"); __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
return tempWord; return tempWord;
} }
// Switch data pins to write // Switch data pins to write
void dataOut_MD() { void dataOut_MD() {
DDRC = 0xFF; DDRC = 0xFF;
DDRA = 0xFF; DDRA = 0xFF;
} }
// Switch data pins to read // Switch data pins to read
void dataIn_MD() { void dataIn_MD() {
DDRC = 0x00; DDRC = 0x00;
DDRA = 0x00; DDRA = 0x00;
} }
/****************************************** /******************************************
MEGA DRIVE functions MEGA DRIVE functions
*****************************************/ *****************************************/
void getCartInfo_MD() { void getCartInfo_MD() {
// Set control // Set control
dataIn_MD(); dataIn_MD();
cartSize = ((long(readWord_MD(0xD2)) << 16) | readWord_MD(0xD3)) + 1; cartSize = ((long(readWord_MD(0xD2)) << 16) | readWord_MD(0xD3)) + 1;
// Check if cart has sram // Check if cart has sram
if ((readWord_MD(0xD8) == 0x5241) && (readWord_MD(0xD9) == 0xF820)) { if ((readWord_MD(0xD8) == 0x5241) && (readWord_MD(0xD9) == 0xF820)) {
// Get sram start and end // Get sram start and end
sramBase = ((long(readWord_MD(0xDA)) << 16) | readWord_MD(0xDB)); sramBase = ((long(readWord_MD(0xDA)) << 16) | readWord_MD(0xDB));
sramEnd = ((long(readWord_MD(0xDC)) << 16) | readWord_MD(0xDD)); sramEnd = ((long(readWord_MD(0xDC)) << 16) | readWord_MD(0xDD));
// Check alignment of sram // Check alignment of sram
if (sramBase == 0x200001) { if (sramBase == 0x200001) {
// low byte // low byte
saveType = 1; saveType = 1;
sramSize = (sramEnd - sramBase + 2) / 2; sramSize = (sramEnd - sramBase + 2) / 2;
// Right shift sram base address so [A21] is set to high 0x200000 = 0b001[0]00000000000000000000 // Right shift sram base address so [A21] is set to high 0x200000 = 0b001[0]00000000000000000000
sramBase = sramBase >> 1; sramBase = sramBase >> 1;
} }
else if (sramBase == 0x200000) { else if (sramBase == 0x200000) {
// high byte // high byte
saveType = 2; saveType = 2;
sramSize = (sramEnd - sramBase + 1) / 2; sramSize = (sramEnd - sramBase + 1) / 2;
// Right shift sram base address so [A21] is set to high 0x200000 = 0b001[0]00000000000000000000 // Right shift sram base address so [A21] is set to high 0x200000 = 0b001[0]00000000000000000000
sramBase = sramBase / 2; sramBase = sramBase / 2;
} }
else else
print_Error(F("Unknown Sram Base"), true); print_Error(F("Unknown Sram Base"), true);
} }
else { else {
// Either no save or eeprom save // Either no save or eeprom save
saveType = 0; saveType = 0;
sramSize = 0; sramSize = 0;
} }
// Get name // Get name
for (byte c = 0; c < 48; c += 2) { for (byte c = 0; c < 48; c += 2) {
// split word // split word
word myWord = readWord_MD((0x150 + c) / 2); word myWord = readWord_MD((0x150 + c) / 2);
byte loByte = myWord & 0xFF; byte loByte = myWord & 0xFF;
byte hiByte = myWord >> 8; byte hiByte = myWord >> 8;
// write to buffer // write to buffer
sdBuffer[c] = hiByte; sdBuffer[c] = hiByte;
sdBuffer[c + 1] = loByte; sdBuffer[c + 1] = loByte;
} }
byte myLength = 0; byte myLength = 0;
for (unsigned int i = 0; i < 48; i++) { for (unsigned int i = 0; i < 48; i++) {
if (((char(sdBuffer[i]) >= 48 && char(sdBuffer[i]) <= 57) || (char(sdBuffer[i]) >= 65 && char(sdBuffer[i]) <= 122)) && myLength < 15) { if (((char(sdBuffer[i]) >= 48 && char(sdBuffer[i]) <= 57) || (char(sdBuffer[i]) >= 65 && char(sdBuffer[i]) <= 122)) && myLength < 15) {
romName[myLength] = char(sdBuffer[i]); romName[myLength] = char(sdBuffer[i]);
myLength++; myLength++;
} }
} }
display_Clear(); display_Clear();
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(romName);
print_Msg(F("Size: ")); print_Msg(F("Size: "));
print_Msg(cartSize * 8 / 1024 / 1024 ); print_Msg(cartSize * 8 / 1024 / 1024 );
println_Msg(F(" MBit")); println_Msg(F(" MBit"));
print_Msg(F("Sram: ")); print_Msg(F("Sram: "));
if (sramSize > 0) { if (sramSize > 0) {
print_Msg(sramSize * 8 / 1024); print_Msg(sramSize * 8 / 1024);
println_Msg(F(" KBit")); println_Msg(F(" KBit"));
} }
else else
println_Msg(F("None")); println_Msg(F("None"));
println_Msg(F(" ")); println_Msg(F(" "));
// Wait for user input // Wait for user input
if (enable_OLED) { if (enable_OLED) {
println_Msg(F("Press Button...")); println_Msg(F("Press Button..."));
display_Update(); display_Update();
wait(); wait();
} }
} }
// Read rom and save to the SD card // Read rom and save to the SD card
void readROM_MD() { void readROM_MD() {
// Set control // Set control
dataIn_MD(); dataIn_MD();
// Get name, add extension and convert to char array for sd lib // Get name, add extension and convert to char array for sd lib
strcpy(fileName, romName); strcpy(fileName, romName);
strcat(fileName, ".MD"); strcat(fileName, ".MD");
// create a new folder // create a new folder
EEPROM_readAnything(10, foldern); EEPROM_readAnything(10, foldern);
sprintf(folder, "MD/ROM/%s/%d", romName, foldern); sprintf(folder, "MD/ROM/%s/%d", romName, foldern);
sd.mkdir(folder, true); sd.mkdir(folder, true);
sd.chdir(folder); sd.chdir(folder);
display_Clear(); display_Clear();
print_Msg(F("Saving to ")); print_Msg(F("Saving to "));
print_Msg(folder); print_Msg(folder);
println_Msg(F("/...")); println_Msg(F("/..."));
display_Update(); display_Update();
// write new folder number back to eeprom // write new folder number back to eeprom
foldern = foldern + 1; foldern = foldern + 1;
EEPROM_writeAnything(10, foldern); EEPROM_writeAnything(10, foldern);
// Open file on sd card // Open file on sd card
if (!myFile.open(fileName, O_RDWR | O_CREAT)) { if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
print_Error(F("SD Error"), true); print_Error(F("SD Error"), true);
} }
word d = 0; word d = 0;
for (unsigned long currBuffer = 0; currBuffer < cartSize / 2; currBuffer += 256) { for (unsigned long currBuffer = 0; currBuffer < cartSize / 2; currBuffer += 256) {
// Blink led // Blink led
if (currBuffer % 16384 == 0) if (currBuffer % 16384 == 0)
PORTB ^= (1 << 4); PORTB ^= (1 << 4);
for (int currWord = 0; currWord < 256; currWord++) { for (int currWord = 0; currWord < 256; currWord++) {
word myWord = readWord_MD(currBuffer + currWord); word myWord = readWord_MD(currBuffer + currWord);
// Split word into two bytes // Split word into two bytes
// Left // Left
sdBuffer[d] = (( myWord >> 8 ) & 0xFF); sdBuffer[d] = (( myWord >> 8 ) & 0xFF);
// Right // Right
sdBuffer[d + 1] = (myWord & 0xFF); sdBuffer[d + 1] = (myWord & 0xFF);
d += 2; d += 2;
} }
myFile.write(sdBuffer, 512); myFile.write(sdBuffer, 512);
d = 0; d = 0;
} }
// Close the file: // Close the file:
myFile.close(); myFile.close();
} }
/****************************************** /******************************************
SRAM functions SRAM functions
*****************************************/ *****************************************/
// Sonic 3 sram enable // Sonic 3 sram enable
void enableSram_MD(boolean enableSram) { void enableSram_MD(boolean enableSram) {
dataOut_MD(); dataOut_MD();
// Set D0 to either 1(enable SRAM) or 0(enable ROM) // Set D0 to either 1(enable SRAM) or 0(enable ROM)
PORTC = enableSram; PORTC = enableSram;
// Strobe TIME(PJ0) LOW to latch the data // Strobe TIME(PJ0) LOW to latch the data
PORTJ &= ~(1 << 0); PORTJ &= ~(1 << 0);
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t"); __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
// Set TIME(PJ0) HIGH // Set TIME(PJ0) HIGH
PORTJ |= (1 << 0); PORTJ |= (1 << 0);
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t"); __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
dataIn_MD(); dataIn_MD();
} }
// Write sram to cartridge // Write sram to cartridge
void writeSram_MD() { void writeSram_MD() {
dataOut_MD(); dataOut_MD();
// Create filepath // Create filepath
sprintf(filePath, "%s/%s", filePath, fileName); sprintf(filePath, "%s/%s", filePath, fileName);
println_Msg(F("Writing...")); println_Msg(F("Writing..."));
println_Msg(filePath); println_Msg(filePath);
display_Update(); display_Update();
// Open file on sd card // Open file on sd card
if (myFile.open(filePath, O_READ)) { if (myFile.open(filePath, O_READ)) {
// Write to the lower byte // Write to the lower byte
if (saveType == 1) { if (saveType == 1) {
for (unsigned long currByte = sramBase; currByte < sramBase + sramSize; currByte++) { for (unsigned long currByte = sramBase; currByte < sramBase + sramSize; currByte++) {
writeWord_MD(currByte, (myFile.read() & 0xFF)); writeWord_MD(currByte, (myFile.read() & 0xFF));
} }
} }
// Write to the upper byte // Write to the upper byte
else if (saveType == 2) { else if (saveType == 2) {
for (unsigned long currByte = sramBase; currByte < sramBase + sramSize; currByte++) { for (unsigned long currByte = sramBase; currByte < sramBase + sramSize; currByte++) {
writeWord_MD(currByte, ((myFile.read() << 8 ) & 0xFF)); writeWord_MD(currByte, ((myFile.read() << 8 ) & 0xFF));
} }
} }
else else
print_Error(F("Unknown save type"), false); print_Error(F("Unknown save type"), false);
// Close the file: // Close the file:
myFile.close(); myFile.close();
println_Msg(F("Done")); println_Msg(F("Done"));
display_Update(); display_Update();
} }
else { else {
print_Error(F("SD Error"), true); print_Error(F("SD Error"), true);
} }
dataIn_MD(); dataIn_MD();
} }
// Read sram and save to the SD card // Read sram and save to the SD card
void readSram_MD() { void readSram_MD() {
dataIn_MD(); dataIn_MD();
// Get name, add extension and convert to char array for sd lib // Get name, add extension and convert to char array for sd lib
strcpy(fileName, romName); strcpy(fileName, romName);
strcat(fileName, ".srm"); strcat(fileName, ".srm");
// create a new folder for the save file // create a new folder for the save file
EEPROM_readAnything(10, foldern); EEPROM_readAnything(10, foldern);
sprintf(folder, "MD/SAVE/%s/%d", romName, foldern); sprintf(folder, "MD/SAVE/%s/%d", romName, foldern);
sd.mkdir(folder, true); sd.mkdir(folder, true);
sd.chdir(folder); sd.chdir(folder);
// write new folder number back to eeprom // write new folder number back to eeprom
foldern = foldern + 1; foldern = foldern + 1;
EEPROM_writeAnything(10, foldern); EEPROM_writeAnything(10, foldern);
// Open file on sd card // Open file on sd card
if (!myFile.open(fileName, O_RDWR | O_CREAT)) { if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
print_Error(F("SD Error"), true); print_Error(F("SD Error"), true);
} }
for (unsigned long currBuffer = sramBase; currBuffer < sramBase + sramSize; currBuffer += 512) { for (unsigned long currBuffer = sramBase; currBuffer < sramBase + sramSize; currBuffer += 512) {
for (int currWord = 0; currWord < 512; currWord++) { for (int currWord = 0; currWord < 512; currWord++) {
word myWord = readWord_MD(currBuffer + currWord); word myWord = readWord_MD(currBuffer + currWord);
if (saveType == 2) { if (saveType == 2) {
// Only use the upper byte // Only use the upper byte
sdBuffer[currWord] = (( myWord >> 8 ) & 0xFF); sdBuffer[currWord] = (( myWord >> 8 ) & 0xFF);
} }
else if (saveType == 1) { else if (saveType == 1) {
// Only use the lower byte // Only use the lower byte
sdBuffer[currWord] = (myWord & 0xFF); sdBuffer[currWord] = (myWord & 0xFF);
} }
} }
myFile.write(sdBuffer, 512); myFile.write(sdBuffer, 512);
} }
// Close the file: // Close the file:
myFile.close(); myFile.close();
print_Msg(F("Saved to ")); print_Msg(F("Saved to "));
print_Msg(folder); print_Msg(folder);
println_Msg(F("/")); println_Msg(F("/"));
display_Update(); display_Update();
} }
unsigned long verifySram_MD() { unsigned long verifySram_MD() {
dataIn_MD(); dataIn_MD();
writeErrors = 0; writeErrors = 0;
// Open file on sd card // Open file on sd card
if (myFile.open(filePath, O_READ)) { if (myFile.open(filePath, O_READ)) {
for (unsigned long currBuffer = sramBase; currBuffer < sramBase + sramSize; currBuffer += 512) { for (unsigned long currBuffer = sramBase; currBuffer < sramBase + sramSize; currBuffer += 512) {
for (int currWord = 0; currWord < 512; currWord++) { for (int currWord = 0; currWord < 512; currWord++) {
word myWord = readWord_MD(currBuffer + currWord); word myWord = readWord_MD(currBuffer + currWord);
if (saveType == 2) { if (saveType == 2) {
// Only use the upper byte // Only use the upper byte
sdBuffer[currWord] = (( myWord >> 8 ) & 0xFF); sdBuffer[currWord] = (( myWord >> 8 ) & 0xFF);
} }
else if (saveType == 1) { else if (saveType == 1) {
// Only use the lower byte // Only use the lower byte
sdBuffer[currWord] = (myWord & 0xFF); sdBuffer[currWord] = (myWord & 0xFF);
} }
} }
// Check sdBuffer content against file on sd card // Check sdBuffer content against file on sd card
for (int i = 0; i < 512; i++) { for (int i = 0; i < 512; i++) {
if (myFile.read() != sdBuffer[i]) { if (myFile.read() != sdBuffer[i]) {
writeErrors++; writeErrors++;
} }
} }
} }
// Close the file: // Close the file:
myFile.close(); myFile.close();
} }
else { else {
print_Error(F("SD Error"), true); print_Error(F("SD Error"), true);
} }
// Return 0 if verified ok, or number of errors // Return 0 if verified ok, or number of errors
return writeErrors; return writeErrors;
} }
//****************************************** //******************************************
// End of File // End of File
//****************************************** //******************************************

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff