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
|
||||
|
||||
Author: sanni
|
||||
Date: 17.03.2020
|
||||
Version: 4.6
|
||||
Date: 19.03.2020
|
||||
Version: 4.7
|
||||
|
||||
SD lib: https://github.com/greiman/SdFat
|
||||
LCD lib: https://github.com/adafruit/Adafruit_SSD1306
|
||||
@ -43,7 +43,7 @@
|
||||
**********************************************************************************/
|
||||
#include <SdFat.h>
|
||||
|
||||
char ver[5] = "4.6";
|
||||
char ver[5] = "4.7";
|
||||
|
||||
/******************************************
|
||||
Options
|
||||
@ -57,7 +57,7 @@ char ver[5] = "4.6";
|
||||
#define enable_OLED
|
||||
|
||||
// Skip OLED start-up animation
|
||||
#define fast_start
|
||||
//#define fast_start
|
||||
|
||||
// Enable the second button
|
||||
#define enable_Button2
|
||||
|
@ -361,29 +361,36 @@ void setup_Snes() {
|
||||
//PORTJ &= ~(1 << 0);
|
||||
|
||||
// Adafruit Clock Generator
|
||||
clockgen.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0);
|
||||
// Use multimeter with frequency counter (probe between SNES Pin 56 and GND) and adjust correction until you measure exactly 3.072Mhz
|
||||
//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);
|
||||
// last number is the clock correction factor which is custom for each clock generator
|
||||
clockgen.init(SI5351_CRYSTAL_LOAD_8PF, 0, -16000);
|
||||
|
||||
// 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_CLK2, 1); // CIC clock (should go before 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)
|
||||
PORTG &= ~(1 << 1);
|
||||
|
||||
// Wait for CIC reset
|
||||
delay(320);
|
||||
delay(500);
|
||||
|
||||
// Print all the info
|
||||
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();
|
||||
}
|
||||
|
||||
// Read header information
|
||||
// Read header
|
||||
boolean checkcart_SNES() {
|
||||
// set control to read
|
||||
dataIn();
|
||||
|
||||
// Get Checksum as string
|
||||
sprintf(checksumStr, "%02X%02X", readBank_SNES(0, 65503), readBank_SNES(0, 65502));
|
||||
uint16_t c = 0;
|
||||
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)
|
||||
romType = LO; // LoROM // Krusty's Super Fun House (U) 1.0 & Contra 3 (U)
|
||||
}
|
||||
@ -756,10 +779,10 @@ boolean checkcart_SNES() {
|
||||
}
|
||||
|
||||
// Check RomSpeed
|
||||
romSpeed = (readBank_SNES(0, 65493) >> 4);
|
||||
romSpeed = (snesHeader[0xFFD5 - headerStart] >> 4);
|
||||
|
||||
// Check RomChips
|
||||
romChips = readBank_SNES(0, 65494);
|
||||
romChips = snesHeader[0xFFD6 - headerStart];
|
||||
|
||||
if (romChips == 69) {
|
||||
romSize = 48;
|
||||
@ -767,7 +790,7 @@ boolean checkcart_SNES() {
|
||||
romType = HI;
|
||||
}
|
||||
else if (romChips == 243) {
|
||||
cx4Type = readBank_SNES(0, 65481) & 0xF;
|
||||
cx4Type = snesHeader[0xFFC9 - headerStart] & 0xF;
|
||||
if (cx4Type == 2) { // X2
|
||||
romSize = 12;
|
||||
numBanks = 48;
|
||||
@ -787,7 +810,7 @@ boolean checkcart_SNES() {
|
||||
}
|
||||
else {
|
||||
// Check RomSize
|
||||
byte romSizeExp = readBank_SNES(0, 65495) - 7;
|
||||
byte romSizeExp = snesHeader[0xFFD7 - headerStart] - 7;
|
||||
romSize = 1;
|
||||
while (romSizeExp--)
|
||||
romSize *= 2;
|
||||
@ -806,8 +829,8 @@ boolean checkcart_SNES() {
|
||||
// Get name
|
||||
byte myByte = 0;
|
||||
byte myLength = 0;
|
||||
for (unsigned int i = 65472; i < 65492; i++) {
|
||||
myByte = readBank_SNES(0, i);
|
||||
for (unsigned int i = 0xFFC0; i < 0xFFD4; i++) {
|
||||
myByte = snesHeader[i - headerStart];
|
||||
if (((char(myByte) >= 48 && char(myByte) <= 57) || (char(myByte) >= 65 && char(myByte) <= 122)) && myLength < 15) {
|
||||
romName[myLength] = char(myByte);
|
||||
myLength++;
|
||||
@ -822,7 +845,7 @@ boolean checkcart_SNES() {
|
||||
romName[3] = 'C';
|
||||
romName[4] = '-';
|
||||
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) {
|
||||
romName[myLength + 5] = char(myByte);
|
||||
myLength++;
|
||||
@ -844,8 +867,8 @@ boolean checkcart_SNES() {
|
||||
byte sramSizeExp;
|
||||
if ((romChips == 19) || (romChips == 20) || (romChips == 21) || (romChips == 26)) {
|
||||
// SuperFX
|
||||
if (readBank_SNES(0, 0x7FDA) == 0x33) {
|
||||
sramSizeExp = readBank_SNES(0, 0x7FBD);
|
||||
if (snesHeader[0x7FDA - headerStart] == 0x33) {
|
||||
sramSizeExp = snesHeader[0x7FBD - headerStart];
|
||||
}
|
||||
else {
|
||||
if (strncmp(romName, "STARFOX2", 8) == 0) {
|
||||
@ -858,7 +881,7 @@ boolean checkcart_SNES() {
|
||||
}
|
||||
else {
|
||||
// No SuperFX
|
||||
sramSizeExp = readBank_SNES(0, 0xFFD8);
|
||||
sramSizeExp = snesHeader[0xFFD8 - headerStart];
|
||||
}
|
||||
|
||||
// Calculate sramSize
|
||||
@ -874,13 +897,13 @@ boolean checkcart_SNES() {
|
||||
}
|
||||
|
||||
// Check Cart Country
|
||||
//int cartCountry = readBank_SNES(0, 65497);
|
||||
//int cartCountry = snesHeader[0xFFD9 - headerStart];
|
||||
|
||||
// ROM Version
|
||||
romVersion = readBank_SNES(0, 65499);
|
||||
romVersion = snesHeader[0xFFDB - headerStart];
|
||||
|
||||
// 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) {
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user