Merge pull request #50 from jiyunomegami/master

V5.4: Merge Commits by jiyunomegami
This commit is contained in:
sanni 2020-07-04 23:09:34 +02:00 committed by GitHub
commit 750a7043fc
16 changed files with 524 additions and 117 deletions

View File

@ -45,22 +45,7 @@
char ver[5] = "5.3";
/******************************************
Options
******************************************/
// Change mainMenu to snsMenu, mdMenu, n64Menu, gbxMenu, pcsMenu,
// flashMenu, nesMenu or smsMenu for single slot Cart Readers
#define startMenu mainMenu
// Comment out to change to Serial Output
// be sure to change the Arduino Serial Monitor to no line ending
#define enable_OLED
// Skip OLED start-up animation
//#define fast_start
// Enable the second button
#define enable_Button2
#include "options.h"
/******************************************
Libraries
@ -365,6 +350,56 @@ static const uint8_t PROGMEM sig [] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
//******************************************
// Data used by multiple modules
//******************************************
// CRC32 lookup table // 256 entries
static const uint32_t crc_32_tab[] PROGMEM = { /* CRC polynomial 0xedb88320 */
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
/******************************************
Menu
*****************************************/
@ -453,21 +488,29 @@ void mainMenu() {
addonsMenu();
break;
#ifdef enable_SNES
case 1:
snsMenu();
break;
#endif
#ifdef enable_MD
case 2:
mdMenu();
break;
#endif
#ifdef enable_N64
case 3:
n64Menu();
break;
#endif
#ifdef enable_GBX
case 4:
gbxMenu();
break;
#endif
case 5:
aboutScreen();
@ -490,35 +533,47 @@ void addonsMenu() {
// wait for user choice to come back from the question box menu
switch (addonsMenu)
{
#ifdef enable_NES
case 0:
nesMenu();
break;
#endif
#ifdef enable_FLASH
case 1:
flashMenu();
break;
#endif
#ifdef enable_PCE
case 2:
pcsMenu();
break;
#endif
#ifdef enable_SMS
case 3:
smsMenu();
break;
#endif
#ifdef enable_WS
case 4:
display_Clear();
display_Update();
setup_WS();
mode = mode_WS;
break;
#endif
#ifdef enable_NGP
case 5:
display_Clear();
display_Update();
setup_NGP();
mode = mode_NGP;
break;
#endif
case 6:
resetArduino();
@ -762,6 +817,19 @@ void print_Msg(String string) {
#endif
}
void print_Msg_PaddedHexByte(byte message) {
if (message < 16) print_Msg(0, HEX);
print_Msg(message, HEX);
}
void print_Msg_PaddedHex32(unsigned long message) {
print_Msg_PaddedHexByte((message >> 24) & 0xFF);
print_Msg_PaddedHexByte((message >> 16) & 0xFF);
print_Msg_PaddedHexByte((message >> 8) & 0xFF);
print_Msg_PaddedHexByte((message >> 0) & 0xFF);
}
void println_Msg(String string) {
#ifdef enable_OLED
display.println(string);
@ -1124,10 +1192,13 @@ void wait_btn() {
// get input button
int b = checkButton();
#ifdef enable_N64
// Send some clock pulses to the Eeprom in case it locked up
if ((mode == mode_N64_Cart) && ((saveType == 5) || (saveType == 6))) {
pulseClock_N64(1);
}
#endif
// if the cart readers input button is pressed shortly
if (b == 1) {
errorLvl = 0;
@ -1455,15 +1526,22 @@ page:
Main loop
*****************************************/
void loop() {
#ifdef enable_N64
if (mode == mode_N64_Controller) {
n64ControllerMenu();
}
else if (mode == mode_N64_Cart) {
n64CartMenu();
}
#else
if (1 == 0) { }
#endif
#ifdef enable_SNES
else if (mode == mode_SNES) {
snesMenu();
}
#endif
#ifdef enable_FLASH
else if (mode == mode_FLASH8) {
flashromMenu8();
}
@ -1473,42 +1551,62 @@ void loop() {
else if (mode == mode_EPROM) {
epromMenu();
}
#endif
#ifdef enable_NP
else if (mode == mode_SFM) {
sfmMenu();
}
#endif
#ifdef enable_GBX
else if (mode == mode_GB) {
gbMenu();
}
else if (mode == mode_GBA) {
gbaMenu();
}
#endif
#ifdef enable_NP
else if (mode == mode_SFM_Flash) {
sfmFlashMenu();
}
else if (mode == mode_SFM_Game) {
sfmGameOptions();
}
#endif
#ifdef enable_GBX
else if (mode == mode_GBM) {
gbmMenu();
}
#endif
else if (mode == mode_MD_Cart) {
mdCartMenu();
}
#ifdef enable_PCE
else if (mode == mode_PCE) {
pceMenu();
}
#endif
#ifdef enable_SV
else if (mode == mode_SV) {
svMenu();
}
#endif
#ifdef enable_NES
else if (mode == mode_NES) {
nesMenu();
}
#endif
#ifdef enable_SMS
else if (mode == mode_SMS) {
smsMenu();
}
#endif
#ifdef enable_MD
else if (mode == mode_SEGA_CD) {
segaCDMenu();
}
#endif
#ifdef enable_GBX
else if (mode == mode_GB_GBSmart) {
gbSmartMenu();
}
@ -1518,12 +1616,17 @@ void loop() {
else if (mode == mode_GB_GBSmart_Game) {
gbSmartGameOptions();
}
#endif
#ifdef enable_WS
else if (mode == mode_WS) {
wsMenu();
}
#endif
#ifdef enable_NGP
else if (mode == mode_NGP) {
ngpMenu();
}
#endif
else {
display_Clear();
println_Msg(F("Menu Error"));

View File

@ -2,6 +2,9 @@
// FLASHROM MODULE
//******************************************
#include "options.h"
#ifdef enable_FLASH
/******************************************
Variables
*****************************************/
@ -2370,6 +2373,8 @@ void print_Eprom(int numBytes) {
display_Update();
}
#endif
//******************************************
// End of File
//******************************************

View File

@ -2,6 +2,9 @@
// GAME BOY MODULE
//******************************************
#include "options.h"
#ifdef enable_GBX
/******************************************
Variables
*****************************************/
@ -1062,6 +1065,8 @@ void writeFlash_GB(byte MBC) {
}
}
#endif
//******************************************
// End of File
//******************************************

View File

@ -2,6 +2,9 @@
// GAME BOY ADVANCE MODULE
//******************************************
#include "options.h"
#ifdef enable_GBX
/******************************************
Variables
*****************************************/
@ -2636,6 +2639,8 @@ void flashRepro_GBA() {
}
}
#endif
//******************************************
// End of File
//******************************************

View File

@ -2,6 +2,10 @@
// GB SMART MODULE
// Supports 32M cart with LH28F016SUT flash
//******************************************
#include "options.h"
#ifdef enable_GBX
#define GB_SMART_GAMES_PER_PAGE 6
/******************************************
@ -771,3 +775,5 @@ uint8_t gbSmartGetResizeParam(uint8_t rom_size, uint8_t sram_size)
return (sram_size | rom_size);
}
#endif

View File

@ -3,6 +3,9 @@
//******************************************
// Writes to Sega CD Backup RAM Cart require an extra wire from MRES (B02) to VRES (B27)
#include "options.h"
#ifdef enable_MD
/******************************************
Variables
*****************************************/
@ -136,6 +139,7 @@ void mdMenu() {
mode = mode_SEGA_CD;
break;
#ifdef enable_FLASH
case 2:
display_Clear();
display_Update();
@ -180,6 +184,7 @@ void mdMenu() {
display_Update();
wait();
break;
#endif
case 3:
resetArduino();
@ -219,7 +224,7 @@ void mdCartMenu() {
case 1:
display_Clear();
// Does cartridge have SRAM
if ((saveType == 1) || (saveType == 2) || (saveType == 3)) {
if ((saveType == 1) || (saveType == 2) || (saveType == 3) || (saveType == 5)) {
// Change working dir to root
sd.chdir("/");
println_Msg(F("Reading Sram..."));
@ -236,7 +241,7 @@ void mdCartMenu() {
case 2:
display_Clear();
// Does cartridge have SRAM
if ((saveType == 1) || (saveType == 2) || (saveType == 3)) {
if ((saveType == 1) || (saveType == 2) || (saveType == 3) || (saveType == 5)) {
// Change working dir to root
sd.chdir("/");
// Launch file browser
@ -575,8 +580,11 @@ void getCartInfo_MD() {
// 4 = 128KB (2045 Blocks) Sega CD Backup RAM Cart
// 6 = 512KB (8189 Blocks) Ultra CD Backup RAM Cart (Aftermarket)
word bramCheck = readWord_MD(0x00);
if (((bramCheck == 0x0004) && (chksum == 0x0004)) || ((bramCheck == 0x0006) && (chksum == 0x0006)))
bramSize = pow(2, bramCheck) * 0x2000;
if ( (((bramCheck & 0xFF) == 0x04) && ((chksum & 0xFF) == 0x04))
|| (((bramCheck & 0xFF) == 0x06) && ((chksum & 0xFF) == 0x06))) {
unsigned long p = 1 << (bramCheck & 0xFF);
bramSize = p * 0x2000L;
}
if (saveType != 4) { // NOT SERIAL EEPROM
// Check if cart has sram
saveType = 0;
@ -600,6 +608,10 @@ void getCartInfo_MD() {
sramSize = (sramEnd - sramBase + 2) / 2;
// Right shift sram base address so [A21] is set to high 0x200000 = 0b001[0]00000000000000000000
sramBase = sramBase >> 1;
if (chksum == 0x5D33 && sramEnd == 0x203FFF) { // Dragon Slayer Eiyuu Densetsu
// the high byte read as zero
saveType = 5; // BOTH
}
}
else if (sramBase == 0x200000) {
// high byte
@ -716,12 +728,20 @@ void getCartInfo_MD() {
println_Msg(F(" "));
print_Msg(F("Name: "));
println_Msg(romName);
print_Msg(F("bramCheck: "));
print_Msg_PaddedHexByte(bramCheck >> 8);
print_Msg_PaddedHexByte(bramCheck & 0x00ff);
println_Msg(F(""));
if (bramSize > 0) {
print_Msg(F("bramSize(KB): "));
println_Msg(bramSize >> 10);
}
print_Msg(F("Size: "));
print_Msg(cartSize * 8 / 1024 / 1024 );
println_Msg(F(" MBit"));
print_Msg(F("ChkS: "));
print_Msg((chksum >> 8), HEX);
print_Msg((chksum & 0x00ff), HEX);
print_Msg_PaddedHexByte((chksum >> 8));
print_Msg_PaddedHexByte((chksum & 0x00ff));
println_Msg(F(""));
if (saveType == 4) {
print_Msg(F("Serial EEPROM: "));
@ -958,6 +978,14 @@ void writeSram_MD() {
writeWord_MD(currByte, ((myFile.read() << 8 ) & 0xFF));
}
}
// Write to both bytes
else if (saveType == 5) {
for (unsigned long currByte = sramBase; currByte < sramBase + sramSize; currByte++) {
word w0 = (myFile.read() & 0xFF); // skip
word w1 = (myFile.read() & 0xFF);
writeWord_MD(currByte, w1);
}
}
else
print_Error(F("Unknown save type"), false);
@ -1007,12 +1035,16 @@ void readSram_MD() {
// Only use the lower byte
sdBuffer[currWord] = (myWord & 0xFF);
}
else { // saveType == 3 (BOTH)
else if (saveType == 3) { // BOTH
sdBuffer[currWord * 2] = (( myWord >> 8 ) & 0xFF);
sdBuffer[(currWord * 2) + 1] = (myWord & 0xFF);
}
else if (saveType == 5) { // duplicate the lower byte
sdBuffer[(currWord * 2) + 0] = (myWord & 0xFF);
sdBuffer[(currWord * 2) + 1] = (myWord & 0xFF);
}
}
if (saveType == 3)
if (saveType == 3 || saveType == 5)
myFile.write(sdBuffer, 512);
else
myFile.write(sdBuffer, 256);
@ -1062,6 +1094,7 @@ unsigned long verifySram_MD() {
return writeErrors;
}
#ifdef enable_FLASH
//******************************************
// Flashrom Functions
//******************************************
@ -1248,6 +1281,7 @@ void verifyFlash_MD() {
display_Update();
}
}
#endif
// Delay between write operations based on status register
void busyCheck_MD() {
@ -2008,6 +2042,8 @@ void readRealtec_MD() {
myFile.close();
}
#endif
//******************************************
// End of File
//******************************************

View File

@ -2,6 +2,9 @@
// NINTENDO 64 MODULE
//******************************************
#include "options.h"
#ifdef enable_N64
/******************************************
Defines
*****************************************/
@ -1643,53 +1646,6 @@ void printCartInfo_N64() {
}
}
// CRC32 lookup table // 256 entries
static const uint32_t crc_32_tab[] PROGMEM = { /* CRC polynomial 0xedb88320 */
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
// improved strcmp function that ignores case to prevent checksum comparison issues
int strcicmp(char const * a, char const * b)
{
@ -3846,6 +3802,8 @@ unsigned long verifyGameshark_N64() {
}
}
#endif
//******************************************
// End of File
//******************************************

View File

@ -5,6 +5,9 @@
// also based on "CoolArduino" by HardWareMan
// Pinout changes: LED and CIRAM_A10
#include "options.h"
#ifdef enable_NES
//Line Content
//26 Supported Mappers
//101 Defines
@ -2163,17 +2166,13 @@ void readCHR() {
case 26: // 128K/256K
banks = int_pow(2, chrsize) * 4;
write_prg_byte(0xB003, 0); // PPU Banking Mode 0
for (int i = 0; i < banks; i += 8) {
write_prg_byte(0xD000, i); // CHR Bank 0
write_prg_byte(0xB003, 0x00);
for (int i = 0; i < banks; i += 4) {
write_prg_byte(0xD000, i + 0); // CHR Bank 0
write_prg_byte(0xD002, i + 1); // CHR Bank 1
write_prg_byte(0xD001, i + 2); // CHR Bank 2
write_prg_byte(0xD003, i + 3); // CHR Bank 3
write_reg_byte(0xE000, i + 4); // CHR Bank 4 [WRITE RAM SAFE]
write_reg_byte(0xE002, i + 5); // CHR Bank 5 [WRITE RAM SAFE]
write_reg_byte(0xE001, i + 6); // CHR Bank 6 [WRITE RAM SAFE]
write_reg_byte(0xE003, i + 7); // CHR Bank 7 [WRITE RAM SAFE]
for (word address = 0x0; address < 0x2000; address += 512) { // 1K Banks
for (word address = 0x0; address < 0x1000; address += 512) { // 1K Banks
dumpCHR(address);
}
}
@ -3284,6 +3283,8 @@ void writeFLASH() {
filePath[0] = '\0'; // Reset filePath
}
#endif
//******************************************
// End of File
//******************************************

View File

@ -2,6 +2,9 @@
// NGP MODULE
//******************************************
#include "options.h"
#ifdef enable_NGP
static const char ngpMenuItem1[] PROGMEM = "Read Rom";
static const char ngpMenuItemReset[] PROGMEM = "Reset";
static const char* const menuOptionsNGP[] PROGMEM = {ngpMenuItem1, ngpMenuItemReset};
@ -236,3 +239,5 @@ uint8_t readByte_NGP(uint32_t addr) {
return data;
}
#endif

View File

@ -3,6 +3,9 @@
//******************************************
// (GB Memory starts at around line 1740)
#include "options.h"
#ifdef enable_NP
/******************************************
SF Memory Cassette
******************************************/
@ -216,6 +219,7 @@ void sfmGameOptions() {
}
}
#ifdef enable_FLASH
void sfmFlashMenu() {
// create menu with title and 6 options to choose from
unsigned char flashSubMenu;
@ -453,6 +457,7 @@ void sfmFlashMenu() {
wait();
}
}
#endif
// Read the games from the menu area
void getGames() {
@ -2615,6 +2620,8 @@ void writeMapping_GBM() {
}
}
#endif
//******************************************
// End of File
//******************************************

View File

@ -11,6 +11,9 @@
//
//******************************************
#include "options.h"
#ifdef enable_PCE
/******************************************
Defines
*****************************************/
@ -844,6 +847,7 @@ void pceMenu() {
wait();
}
#endif
//******************************************
// End of File

View File

@ -2,6 +2,9 @@
// SEGA MASTER SYSTEM MODULE
//******************************************
#include "options.h"
#ifdef enable_MD
/******************************************
Variables
*****************************************/
@ -11,15 +14,22 @@
*****************************************/
// MD menu items
static const char SMSMenuItem1[] PROGMEM = "Read Rom";
static const char SMSMenuItem2[] PROGMEM = "Reset";
static const char* const menuOptionsSMS[] PROGMEM = {SMSMenuItem1, SMSMenuItem2};
static const char SMSMenuItem2[] PROGMEM = "Read from SRAM";
static const char SMSMenuItem3[] PROGMEM = "Write to SRAM";
static const char SMSMenuItem4[] PROGMEM = "Toggle Retrode Mode";
static const char SMSMenuItem5[] PROGMEM = "Reset";
static const char* const menuOptionsSMS[] PROGMEM = {SMSMenuItem1, SMSMenuItem2, SMSMenuItem3, SMSMenuItem4, SMSMenuItem5};
void smsMenu() {
// Set retrode_mode to true when using a retrode SMS/GG adapter
static bool retrode_mode = false;
void _smsMenu() {
// create menu with title and 2 options to choose from
unsigned char mainMenu;
// Copy menuOptions out of progmem
convertPgm(menuOptionsSMS, 2);
mainMenu = question_box(F("Sega Master System"), menuOptions, 2, 0);
int noptions = sizeof(menuOptionsSMS) / sizeof(menuOptionsSMS[0]);
convertPgm(menuOptionsSMS, noptions);
mainMenu = question_box(retrode_mode ? F("SMS/GG Retrode:YES") : F("SMS/GG Retrode:NO"), menuOptions, noptions, 0);
// wait for user choice to come back from the question box menu
switch (mainMenu)
@ -34,16 +44,43 @@ void smsMenu() {
break;
case 1:
display_Clear();
mode = mode_SMS;
setup_SMS();
// Change working dir to root
sd.chdir("/");
readSRAM_SMS();
break;
case 2:
display_Clear();
mode = mode_SMS;
setup_SMS();
// Change working dir to root
sd.chdir("/");
writeSRAM_SMS();
break;
case 3:
retrode_mode = !retrode_mode;
break;
case 4:
// Reset
resetArduino();
break;
}
println_Msg(retrode_mode ? F("Retrode Mode On") : F("Retrode Mode Off"));
println_Msg(F(""));
println_Msg(F("Press Button..."));
display_Update();
wait();
}
void smsMenu() {
for (;;) _smsMenu();
}
/******************************************
Setup
*****************************************/
@ -56,15 +93,35 @@ void setup_SMS() {
//A15
DDRH |= (1 << 3);
// Set Control Pins to Output RST(PH0) WR(PH5) OE(PH6)
DDRH |= (1 << 0) | (1 << 5) | (1 << 6);
// CE(PL1)
DDRL |= (1 << 1);
if (retrode_mode) {
// Revert changes from the other mode
PORTH &= ~((1 << 0) | (1 << 3) | (1 << 5));
PORTL &= ~(1 << 1);
DDRH &= ~((1 << 0) | (1 << 5));
DDRL &= ~((1 << 1));
// Set Control Pins to Output OE(PH6)
DDRH |= (1 << 6);
// WR(PL5) and RD(PL6)
DDRL |= (1 << 5) | (1 << 6);
// Setting RST(PH0) WR(PH5) OE(PH6) HIGH
PORTH |= (1 << 0) | (1 << 5) | (1 << 6);
// CE(PL1)
PORTL |= (1 << 1);
// Setting OE(PH6) HIGH
PORTH |= (1 << 6);
// Setting WR(PL5) and RD(PL6) HIGH
PORTL |= (1 << 5) | (1 << 6);
} else {
// Revert changes from the other mode
PORTL &= ~((1 << 5) | (1 << 6));
DDRL &= ~((1 << 5) | (1 << 6));
// Set Control Pins to Output RST(PH0) WR(PH5) OE(PH6)
DDRH |= (1 << 0) | (1 << 5) | (1 << 6);
// CE(PL1)
DDRL |= (1 << 1);
// Setting RST(PH0) WR(PH5) OE(PH6) HIGH
PORTH |= (1 << 0) | (1 << 5) | (1 << 6);
// CE(PL1)
PORTL |= (1 << 1);
}
// ROM has 16KB banks which can be mapped to one of three slots via register writes
// Register Slot Address space
@ -88,61 +145,111 @@ void setup_SMS() {
Low level functions
*****************************************/
void writeByte_SMS(word myAddress, byte myData) {
// Set Data Pins (D0-D7) to Output
DDRC = 0xFF;
if (retrode_mode) {
// Set Data Pins (D8-D15) to Output
DDRA = 0xFF;
} else {
// Set Data Pins (D0-D7) to Output
DDRC = 0xFF;
}
// Set address
PORTF = myAddress & 0xFF;
PORTK = (myAddress >> 8) & 0xFF;
PORTH = (PORTH & 0b11110111) | ((myAddress >> 12) & 0b00001000);
if (!retrode_mode) {
// CE(PH3) and OE(PH6) are connected
PORTH = (PORTH & 0b11110111) | ((myAddress >> 12) & 0b00001000);
}
// Output data
PORTC = myData;
if (retrode_mode) {
PORTA = myData;
} else {
PORTC = myData;
}
// Arduino running at 16Mhz -> one nop = 62.5ns
// Wait till output is stable
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
// Switch CE(PL1) and WR(PH5) to LOW
PORTL &= ~(1 << 1);
PORTH &= ~(1 << 5);
if (retrode_mode) {
// Switch WR(PL5) and OE/CE(PH6) to LOW
PORTL &= ~(1 << 5);
PORTH &= ~(1 << 6);
} else {
// Switch CE(PL1) and WR(PH5) to LOW
PORTL &= ~(1 << 1);
PORTH &= ~(1 << 5);
}
// Leave WE low for at least 60ns
// Leave WR low for at least 60ns
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
// Switch CE(PL1) and WR(PH5) to HIGH
PORTH |= (1 << 5);
PORTL |= (1 << 1);
if (retrode_mode) {
// Switch WR(PL5) and OE/CE(PH6) to HIGH
PORTH |= (1 << 6);
PORTL |= (1 << 5);
} else {
// Switch CE(PL1) and WR(PH5) to HIGH
PORTH |= (1 << 5);
PORTL |= (1 << 1);
}
// Leave WE 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");
// Set Data Pins (D0-D7) to Input
DDRC = 0x00;
if (retrode_mode) {
// Set Data Pins (D8-D15) to Input
DDRA = 0x00;
} else {
// Set Data Pins (D0-D7) to Input
DDRC = 0x00;
}
}
byte readByte_SMS(word myAddress) {
// Set Data Pins (D0-D7) to Input
DDRC = 0x00;
if (retrode_mode) {
// Set Data Pins (D8-D15) to Input
DDRA = 0x00;
} else {
// Set Data Pins (D0-D7) to Input
DDRC = 0x00;
}
// Set Address
PORTF = myAddress & 0xFF;
PORTK = (myAddress >> 8) & 0xFF;
PORTH = (PORTH & 0b11110111) | ((myAddress >> 12) & 0b00001000);
if (!retrode_mode) {
// CE(PH3) and OE(PH6) are connected
PORTH = (PORTH & 0b11110111) | ((myAddress >> 12) & 0b00001000);
}
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
// Switch CE(PL1) and OE(PH6) to LOW
PORTL &= ~(1 << 1);
PORTH &= ~(1 << 6);
if (retrode_mode) {
// Switch RD(PL6) and OE(PH6) to LOW
PORTL &= ~(1 << 6);
PORTH &= ~(1 << 6);
} else {
// Switch CE(PL1) and OE(PH6) to LOW
PORTL &= ~(1 << 1);
PORTH &= ~(1 << 6);
}
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
// Read
byte tempByte = PINC;
byte tempByte = retrode_mode ? PINA : PINC;
// Switch CE(PL1) and OE(PH6) to HIGH
PORTH |= (1 << 6);
PORTL |= (1 << 1);
if (retrode_mode) {
// Switch RD(PL6) and OE(PH6) to HIGH
PORTH |= (1 << 6);
PORTL |= (1 << 6);
} else {
// Switch CE(PL1) and OE(PH6) to HIGH
PORTH |= (1 << 6);
PORTL |= (1 << 1);
}
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
@ -186,7 +293,11 @@ void getCartInfo_SMS() {
cartSize = 128 * 1024UL;
break;
case 0x0:
cartSize = 256 * 1024UL;
if (retrode_mode) {
cartSize = 512 * 1024UL;
} else {
cartSize = 256 * 1024UL;
}
break;
case 0x1:
cartSize = 512 * 1024UL;
@ -280,6 +391,113 @@ void readROM_SMS() {
myFile.close();
}
// Read SRAM and save to the SD card
void readSRAM_SMS() {
// Get name, add extension and convert to char array for sd lib
strcpy(fileName, romName);
strcat(fileName, ".SAV");
// create a new folder
EEPROM_readAnything(0, foldern);
sprintf(folder, "SMS/SAVE/%s/%d", romName, foldern);
sd.mkdir(folder, true);
sd.chdir(folder);
display_Clear();
print_Msg(F("Saving to "));
print_Msg(folder);
println_Msg(F("/..."));
display_Update();
// write new folder number back to eeprom
foldern = foldern + 1;
EEPROM_writeAnything(0, foldern);
// Open file on sd card
if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
print_Error(F("SD Error"), true);
}
// Write the whole 32KB
// When there is only 8KB of SRAM, the contents should be duplicated
word bankSize = 16 * 1024UL;
for (byte currBank = 0x0; currBank < 2; currBank++) {
writeByte_SMS(0xFFFC, 0x08 | (currBank << 2));
// Blink led
PORTB ^= (1 << 4);
// Read 16KB from slot 2 which starts at 0x8000
for (word currBuffer = 0; currBuffer < bankSize; currBuffer += 512) {
// Fill SD buffer
for (int currByte = 0; currByte < 512; currByte++) {
sdBuffer[currByte] = readByte_SMS(0x8000 + currBuffer + currByte);
}
myFile.write(sdBuffer, 512);
}
}
// Close the file:
myFile.close();
}
void writeSRAM_SMS() {
display_Clear();
if (false) {
print_Error(F("DISABLED"), false);
}
else {
fileBrowser(F("Select file"));
sd.chdir();
sprintf(filePath, "%s/%s", filePath, fileName);
display_Clear();
println_Msg(F("Restoring from "));
println_Msg(filePath);
println_Msg(fileName);
display_Update();
if (myFile.open(filePath, O_READ)) {
// Get SRAM size from file, with a maximum of 32KB
uint32_t sramSize = myFile.fileSize();
if (sramSize > (32 * 1024)) {
sramSize = 32 * 1024;
}
print_Msg(F("sramSize: "));
print_Msg(sramSize);
println_Msg(F(""));
word bankSize = 16 * 1024;
for (word address = 0x0; address < sramSize; address += 512) {
byte currBank = address >= bankSize ? 1 : 0;
word page_address = address - (currBank * bankSize);
writeByte_SMS(0xFFFC, 0x08 | (currBank << 2));
// Blink led
PORTB ^= (1 << 4);
myFile.read(sdBuffer, 512);
for (int x = 0; x < 512; x++) {
writeByte_SMS(0x8000 + page_address + x, sdBuffer[x]);
}
}
myFile.close();
// Blink led
PORTB ^= (1 << 4);
println_Msg(F(""));
println_Msg(F("DONE"));
display_Update();
}
else {
print_Error(F("SD ERROR"), true);
}
}
display_Clear();
sd.chdir(); // root
filePath[0] = '\0'; // Reset filePath
}
#endif
//******************************************
// End of File
//******************************************

View File

@ -2,6 +2,9 @@
// SUPER NINTENDO MODULE
//******************************************
#include "options.h"
#ifdef enable_SNES
/******************************************
Defines
*****************************************/
@ -86,6 +89,7 @@ void snsMenu() {
mode = mode_SV;
break;
#ifdef enable_FLASH
case 3:
display_Clear();
display_Update();
@ -105,6 +109,7 @@ void snsMenu() {
wait();
mode = mode_FLASH8;
break;
#endif
case 5:
resetArduino();
@ -1312,6 +1317,7 @@ void writeSRAM (boolean browseFile) {
// Set RST RD WR to High and CS to Low
controlOut_SNES();
int sramBanks = 0;
// LoRom
if (romType == LO) {
// Sram size
@ -2095,6 +2101,8 @@ boolean eraseSRAM (byte b) {
display_Update();
}
#endif
//******************************************
// End of File
//******************************************

View File

@ -4,6 +4,9 @@
// Added BSX Sram, copied from skamans enhanced sketch //sanni
//******************************************
#include "options.h"
#ifdef enable_SV
/******************************************
Satellaview 8M Memory Pack
******************************************/
@ -665,6 +668,8 @@ void eraseAll_SV(void)
writeBank_SV(0xC0, 0x0000, 0xFF); //Teriminate
}
#endif
//******************************************
// End of File
//******************************************

View File

@ -22,6 +22,9 @@
// C46 : INT (for RTC alarm interrupt)
// C47 : CLK (384KHz on WS)
#include "options.h"
#ifdef enable_WS
/******************************************
Menu
*****************************************/
@ -1261,3 +1264,5 @@ void dataOut_WS()
DDRC = 0xff;
DDRA = 0xff;
}
#endif

36
Cart_Reader/options.h Normal file
View File

@ -0,0 +1,36 @@
/******************************************
Options
******************************************/
// Change mainMenu to snsMenu, mdMenu, n64Menu, gbxMenu, pcsMenu,
// flashMenu, nesMenu or smsMenu for single slot Cart Readers
#define startMenu mainMenu
// Comment out to change to Serial Output
// be sure to change the Arduino Serial Monitor to no line ending
#define enable_OLED
// Skip OLED start-up animation
//#define fast_start
// Enable the second button
#define enable_Button2
// define enable_XXX to enable
#define enable_MD
#define enable_SMS
#define enable_PCE
#define enable_NES
#define enable_SNES
#define enable_SV
#define enable_NP
#define enable_GBX
#define enable_N64
#define enable_WS
#define enable_NGP
#define enable_FLASH