V4.7: Increase SA1 compatibility

Somehow a lower clock seems to work better, maybe the clock generator draws less power this way?!
This commit is contained in:
sanni 2020-03-19 18:21:41 +01:00
parent 83aacd4c66
commit aa4621a54d
2 changed files with 55 additions and 32 deletions

View File

@ -2,8 +2,8 @@
Cartridge Reader for Arduino Mega2560 Cartridge Reader for Arduino Mega2560
Author: sanni Author: sanni
Date: 17.03.2020 Date: 19.03.2020
Version: 4.6 Version: 4.7
SD lib: https://github.com/greiman/SdFat SD lib: https://github.com/greiman/SdFat
LCD lib: https://github.com/adafruit/Adafruit_SSD1306 LCD lib: https://github.com/adafruit/Adafruit_SSD1306
@ -43,7 +43,7 @@
**********************************************************************************/ **********************************************************************************/
#include <SdFat.h> #include <SdFat.h>
char ver[5] = "4.6"; char ver[5] = "4.7";
/****************************************** /******************************************
Options Options
@ -57,7 +57,7 @@ char ver[5] = "4.6";
#define enable_OLED #define enable_OLED
// Skip OLED start-up animation // Skip OLED start-up animation
#define fast_start //#define fast_start
// Enable the second button // Enable the second button
#define enable_Button2 #define enable_Button2

View File

@ -361,29 +361,36 @@ void setup_Snes() {
//PORTJ &= ~(1 << 0); //PORTJ &= ~(1 << 0);
// Adafruit Clock Generator // Adafruit Clock Generator
clockgen.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0); // last number is the clock correction factor which is custom for each clock generator
// Use multimeter with frequency counter (probe between SNES Pin 56 and GND) and adjust correction until you measure exactly 3.072Mhz clockgen.init(SI5351_CRYSTAL_LOAD_8PF, 0, -16000);
//clockgen.set_correction(-200000, SI5351_PLL_INPUT_XO);
clockgen.set_pll(SI5351_PLL_FIXED, SI5351_PLLA);
clockgen.set_pll(SI5351_PLL_FIXED, SI5351_PLLB);
clockgen.set_freq(2147727200ULL, SI5351_CLK0);
clockgen.set_freq(357954500ULL, SI5351_CLK1);
clockgen.set_freq(307200000ULL, SI5351_CLK2);
// start outputting master clock, CIC clock // Set clocks to 4Mhz/1Mhz for better SA-1 unlocking
clockgen.set_freq(100000000ULL, SI5351_CLK1); // CPU
clockgen.set_freq(100000000ULL, SI5351_CLK2); // CIC
clockgen.set_freq(400000000ULL, SI5351_CLK0); // EXT
// Start outputting master clock, CIC clock
clockgen.output_enable(SI5351_CLK1, 0); // no CPU clock yet; seems to affect SA-1 success a lot clockgen.output_enable(SI5351_CLK1, 0); // no CPU clock yet; seems to affect SA-1 success a lot
clockgen.output_enable(SI5351_CLK2, 1); // CIC clock (should go before master clock) clockgen.output_enable(SI5351_CLK2, 1); // CIC clock (should go before master clock)
clockgen.output_enable(SI5351_CLK0, 1); // master clock clockgen.output_enable(SI5351_CLK0, 1); // master clock
delay(8);
// Wait for clock generator
clockgen.update_status();
delay(500);
// Start CIC by outputting a low signal to cicrstPin(PG1) // Start CIC by outputting a low signal to cicrstPin(PG1)
PORTG &= ~(1 << 1); PORTG &= ~(1 << 1);
// Wait for CIC reset // Wait for CIC reset
delay(320); delay(500);
// Print all the info // Print all the info
getCartInfo_SNES(); getCartInfo_SNES();
//Set clocks to standard or else SA-1 sram writing will fail
clockgen.set_freq(2147727200ULL, SI5351_CLK0);
clockgen.set_freq(357954500ULL, SI5351_CLK1);
clockgen.set_freq(307200000ULL, SI5351_CLK2);
} }
/****************************************** /******************************************
@ -733,15 +740,31 @@ void checkAltConf() {
myFile.close(); myFile.close();
} }
// Read header information // Read header
boolean checkcart_SNES() { boolean checkcart_SNES() {
// set control to read // set control to read
dataIn(); dataIn();
// Get Checksum as string uint16_t c = 0;
sprintf(checksumStr, "%02X%02X", readBank_SNES(0, 65503), readBank_SNES(0, 65502)); uint16_t headerStart = 0xFFC0;
uint16_t currByte = headerStart;
byte snesHeader[64] = { 0 };
PORTL = 0;
while (c < 64) {
PORTF = (currByte & 0xFF);
PORTK = ((currByte >> 8) & 0xFF);
romType = readBank_SNES(0, 0xFFD5); NOP; NOP; NOP; NOP; NOP; NOP; NOP; NOP; NOP; NOP; NOP; NOP;
snesHeader[c] = PINC;
c++;
currByte++;
}
// Get Checksum as string
sprintf(checksumStr, "%02X%02X", snesHeader[0xFFDF - headerStart], snesHeader[0xFFDE - headerStart]);
romType = snesHeader[0xFFD5 - headerStart];
if ((romType >> 5) != 1) { // Detect invalid romType byte due to too long ROM name (22 chars) if ((romType >> 5) != 1) { // Detect invalid romType byte due to too long ROM name (22 chars)
romType = LO; // LoROM // Krusty's Super Fun House (U) 1.0 & Contra 3 (U) romType = LO; // LoROM // Krusty's Super Fun House (U) 1.0 & Contra 3 (U)
} }
@ -756,10 +779,10 @@ boolean checkcart_SNES() {
} }
// Check RomSpeed // Check RomSpeed
romSpeed = (readBank_SNES(0, 65493) >> 4); romSpeed = (snesHeader[0xFFD5 - headerStart] >> 4);
// Check RomChips // Check RomChips
romChips = readBank_SNES(0, 65494); romChips = snesHeader[0xFFD6 - headerStart];
if (romChips == 69) { if (romChips == 69) {
romSize = 48; romSize = 48;
@ -767,7 +790,7 @@ boolean checkcart_SNES() {
romType = HI; romType = HI;
} }
else if (romChips == 243) { else if (romChips == 243) {
cx4Type = readBank_SNES(0, 65481) & 0xF; cx4Type = snesHeader[0xFFC9 - headerStart] & 0xF;
if (cx4Type == 2) { // X2 if (cx4Type == 2) { // X2
romSize = 12; romSize = 12;
numBanks = 48; numBanks = 48;
@ -787,7 +810,7 @@ boolean checkcart_SNES() {
} }
else { else {
// Check RomSize // Check RomSize
byte romSizeExp = readBank_SNES(0, 65495) - 7; byte romSizeExp = snesHeader[0xFFD7 - headerStart] - 7;
romSize = 1; romSize = 1;
while (romSizeExp--) while (romSizeExp--)
romSize *= 2; romSize *= 2;
@ -806,8 +829,8 @@ boolean checkcart_SNES() {
// Get name // Get name
byte myByte = 0; byte myByte = 0;
byte myLength = 0; byte myLength = 0;
for (unsigned int i = 65472; i < 65492; i++) { for (unsigned int i = 0xFFC0; i < 0xFFD4; i++) {
myByte = readBank_SNES(0, i); myByte = snesHeader[i - headerStart];
if (((char(myByte) >= 48 && char(myByte) <= 57) || (char(myByte) >= 65 && char(myByte) <= 122)) && myLength < 15) { if (((char(myByte) >= 48 && char(myByte) <= 57) || (char(myByte) >= 65 && char(myByte) <= 122)) && myLength < 15) {
romName[myLength] = char(myByte); romName[myLength] = char(myByte);
myLength++; myLength++;
@ -822,7 +845,7 @@ boolean checkcart_SNES() {
romName[3] = 'C'; romName[3] = 'C';
romName[4] = '-'; romName[4] = '-';
for (unsigned int i = 0; i < 4; i++) { for (unsigned int i = 0; i < 4; i++) {
myByte = readBank_SNES(0, 0xFFB2 + i); myByte = snesHeader[0xFFB2 + i - headerStart];
if (((char(myByte) >= 48 && char(myByte) <= 57) || (char(myByte) >= 65 && char(myByte) <= 122)) && myLength < 4) { if (((char(myByte) >= 48 && char(myByte) <= 57) || (char(myByte) >= 65 && char(myByte) <= 122)) && myLength < 4) {
romName[myLength + 5] = char(myByte); romName[myLength + 5] = char(myByte);
myLength++; myLength++;
@ -844,8 +867,8 @@ boolean checkcart_SNES() {
byte sramSizeExp; byte sramSizeExp;
if ((romChips == 19) || (romChips == 20) || (romChips == 21) || (romChips == 26)) { if ((romChips == 19) || (romChips == 20) || (romChips == 21) || (romChips == 26)) {
// SuperFX // SuperFX
if (readBank_SNES(0, 0x7FDA) == 0x33) { if (snesHeader[0x7FDA - headerStart] == 0x33) {
sramSizeExp = readBank_SNES(0, 0x7FBD); sramSizeExp = snesHeader[0x7FBD - headerStart];
} }
else { else {
if (strncmp(romName, "STARFOX2", 8) == 0) { if (strncmp(romName, "STARFOX2", 8) == 0) {
@ -858,7 +881,7 @@ boolean checkcart_SNES() {
} }
else { else {
// No SuperFX // No SuperFX
sramSizeExp = readBank_SNES(0, 0xFFD8); sramSizeExp = snesHeader[0xFFD8 - headerStart];
} }
// Calculate sramSize // Calculate sramSize
@ -874,13 +897,13 @@ boolean checkcart_SNES() {
} }
// Check Cart Country // Check Cart Country
//int cartCountry = readBank_SNES(0, 65497); //int cartCountry = snesHeader[0xFFD9 - headerStart];
// ROM Version // ROM Version
romVersion = readBank_SNES(0, 65499); romVersion = snesHeader[0xFFDB - headerStart];
// Test if checksum is equal to reverse checksum // Test if checksum is equal to reverse checksum
if (((word(readBank_SNES(0, 65500)) + (word(readBank_SNES(0, 65501)) * 256)) + (word(readBank_SNES(0, 65502)) + (word(readBank_SNES(0, 65503)) * 256))) == 65535 ) { if (((word(snesHeader[0xFFDC - headerStart]) + (word(snesHeader[0xFFDD - headerStart]) * 256)) + (word(snesHeader[0xFFDE - headerStart]) + (word(snesHeader[0xFFDF - headerStart]) * 256))) == 65535 ) {
if (strcmp("0000", checksumStr) == 0) { if (strcmp("0000", checksumStr) == 0) {
return 0; return 0;
} }