mirror of
https://github.com/sanni/cartreader.git
synced 2024-11-27 23:14:14 +01:00
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:
parent
83aacd4c66
commit
aa4621a54d
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user