mirror of
https://github.com/sanni/cartreader.git
synced 2024-11-14 17:05:08 +01:00
V22B Improved N64 timing once more
This should fix reading of N64 repro carts
This commit is contained in:
parent
82c69924e3
commit
4adb7c7506
@ -2,8 +2,8 @@
|
|||||||
Cartridge Reader for Arduino Mega2560
|
Cartridge Reader for Arduino Mega2560
|
||||||
|
|
||||||
Author: sanni
|
Author: sanni
|
||||||
Date: 2017-02-24
|
Date: 2017-02-25
|
||||||
Version: V22A
|
Version: V22B
|
||||||
|
|
||||||
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
|
||||||
@ -34,7 +34,7 @@
|
|||||||
YamaArashi - GBA flashrom bank switch command
|
YamaArashi - GBA flashrom bank switch command
|
||||||
|
|
||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
char ver[5] = "V22A";
|
char ver[5] = "V22B";
|
||||||
|
|
||||||
/******************************************
|
/******************************************
|
||||||
Define Output
|
Define Output
|
||||||
|
@ -264,7 +264,7 @@ void setup_N64_Cart() {
|
|||||||
DDRH |= (1 << 0) | (1 << 5) | (1 << 6);
|
DDRH |= (1 << 0) | (1 << 5) | (1 << 6);
|
||||||
DDRC |= (1 << 0) | (1 << 1);
|
DDRC |= (1 << 0) | (1 << 1);
|
||||||
// Pull RESET(PH0) low until we are ready
|
// Pull RESET(PH0) low until we are ready
|
||||||
PORTH &= ~(1 << 0);
|
//PORTH &= ~(1 << 0);
|
||||||
// Output a high signal on WR(PH5) RD(PH6), pins are active low therefore everything is disabled now
|
// Output a high signal on WR(PH5) RD(PH6), pins are active low therefore everything is disabled now
|
||||||
PORTH |= (1 << 5) | (1 << 6);
|
PORTH |= (1 << 5) | (1 << 6);
|
||||||
// Pull aleL(PC0) low and aleH(PC1) high
|
// Pull aleL(PC0) low and aleH(PC1) high
|
||||||
@ -281,31 +281,20 @@ void setup_N64_Cart() {
|
|||||||
// Activate Internal Pullup Resistors
|
// Activate Internal Pullup Resistors
|
||||||
//PORTH |= (1 << 4);
|
//PORTH |= (1 << 4);
|
||||||
|
|
||||||
/* Adafruit Clock Generator
|
|
||||||
//clockgen.set_correction(-29000);
|
|
||||||
clockgen.set_correction(0);
|
|
||||||
clockgen.init(SI5351_CRYSTAL_LOAD_8PF, 0);
|
|
||||||
clockgen.set_pll(SI5351_PLL_FIXED, SI5351_PLLA);
|
|
||||||
//clockgen.set_pll(SI5351_PLL_FIXED, SI5351_PLLB);
|
|
||||||
clockgen.set_freq(200000000ULL, SI5351_PLL_FIXED, SI5351_CLK1);
|
|
||||||
clockgen.output_enable(SI5351_CLK0, 0);
|
|
||||||
clockgen.output_enable(SI5351_CLK1, 1);
|
|
||||||
clockgen.output_enable(SI5351_CLK2, 0);
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Wait until all is stable
|
// Wait until all is stable
|
||||||
delay(300);
|
delay(300);
|
||||||
|
|
||||||
// Pull RESET(PH0) high
|
// Pull RESET(PH0) high
|
||||||
PORTH |= (1 << 0);
|
//PORTH |= (1 << 0);
|
||||||
delay(10);
|
//delay(10);
|
||||||
|
|
||||||
// Print start page
|
// Print start page
|
||||||
getCartInfo_N64();
|
getCartInfo_N64();
|
||||||
if (cartSize != 0) {
|
if (cartSize != 0) {
|
||||||
println_Msg(F("N64 Cartridge Info"));
|
println_Msg(F("N64 Cartridge Info"));
|
||||||
println_Msg(F(""));
|
println_Msg(F(""));
|
||||||
printName();
|
print_Msg(F("Name: "));
|
||||||
|
println_Msg(romName);
|
||||||
print_Msg(F("ID: "));
|
print_Msg(F("ID: "));
|
||||||
print_Msg(cartID);
|
print_Msg(cartID);
|
||||||
print_Msg(F(" Size: "));
|
print_Msg(F(" Size: "));
|
||||||
@ -343,7 +332,8 @@ void setup_N64_Cart() {
|
|||||||
else {
|
else {
|
||||||
println_Msg(F("GAMEPAK ERROR"));
|
println_Msg(F("GAMEPAK ERROR"));
|
||||||
println_Msg("");
|
println_Msg("");
|
||||||
printName();
|
print_Msg(F("Name: "));
|
||||||
|
println_Msg(romName);
|
||||||
print_Msg(F("ID: "));
|
print_Msg(F("ID: "));
|
||||||
println_Msg(cartID);
|
println_Msg(cartID);
|
||||||
println_Msg("");
|
println_Msg("");
|
||||||
@ -384,21 +374,20 @@ void setAddress_N64(unsigned long myAddress) {
|
|||||||
|
|
||||||
// Switch WR(PH5) RD(PH6) ale_L(PC0) ale_H(PC1) to high (since the pins are active low)
|
// Switch WR(PH5) RD(PH6) ale_L(PC0) ale_H(PC1) to high (since the pins are active low)
|
||||||
PORTH |= (1 << 5) | (1 << 6);
|
PORTH |= (1 << 5) | (1 << 6);
|
||||||
PORTC |= (1 << 0) | (1 << 1);
|
PORTC |= (1 << 1);
|
||||||
|
__asm__("nop\n\t");
|
||||||
|
PORTC |= (1 << 0);
|
||||||
|
|
||||||
// Output high part to address pins
|
// Output high part to address pins
|
||||||
PORTF = myAdrHighOut & 0xFF;
|
PORTF = myAdrHighOut & 0xFF;
|
||||||
PORTK = (myAdrHighOut >> 8) & 0xFF;
|
PORTK = (myAdrHighOut >> 8) & 0xFF;
|
||||||
|
|
||||||
// Leave ale_H high for additional 125ns
|
// Leave ale_H high for additional 62.5ns
|
||||||
__asm__("nop\n\t""nop\n\t");
|
__asm__("nop\n\t");
|
||||||
|
|
||||||
// Pull ale_H(PC1) low
|
// Pull ale_H(PC1) low
|
||||||
PORTC &= ~(1 << 1);
|
PORTC &= ~(1 << 1);
|
||||||
|
|
||||||
// Leave address pins stable for a little bit
|
|
||||||
//__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
|
|
||||||
|
|
||||||
// Output low part to address pins
|
// Output low part to address pins
|
||||||
PORTF = myAdrLowOut & 0xFF;
|
PORTF = myAdrLowOut & 0xFF;
|
||||||
PORTK = (myAdrLowOut >> 8) & 0xFF;
|
PORTK = (myAdrLowOut >> 8) & 0xFF;
|
||||||
@ -409,8 +398,8 @@ void setAddress_N64(unsigned long myAddress) {
|
|||||||
// Pull ale_L(PC0) low
|
// Pull ale_L(PC0) low
|
||||||
PORTC &= ~(1 << 0);
|
PORTC &= ~(1 << 0);
|
||||||
|
|
||||||
// Wait ~1000ns just to be sure address is set
|
// Wait ~600ns just to be sure address is set
|
||||||
__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""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");
|
||||||
|
|
||||||
// Set data pins to input
|
// Set data pins to input
|
||||||
adIn_N64();
|
adIn_N64();
|
||||||
@ -1181,65 +1170,37 @@ void getCartInfo_N64() {
|
|||||||
|
|
||||||
// Read rom ID
|
// Read rom ID
|
||||||
void idCart() {
|
void idCart() {
|
||||||
// Set address
|
// Set the address
|
||||||
setAddress_N64(romBase + 0x3A);
|
setAddress_N64(romBase);
|
||||||
|
// Read first 64 bytes of rom
|
||||||
// Split word
|
for (int c = 0; c < 64; c += 2) {
|
||||||
word myWord = readWord_N64();
|
|
||||||
byte loByte = myWord & 0xFF;
|
|
||||||
byte hiByte = myWord >> 8;
|
|
||||||
|
|
||||||
// First letter is always N or C
|
|
||||||
cartID[0] = loByte;
|
|
||||||
|
|
||||||
// Split word
|
|
||||||
myWord = readWord_N64();
|
|
||||||
loByte = myWord & 0xFF;
|
|
||||||
hiByte = myWord >> 8;
|
|
||||||
|
|
||||||
// Game ID
|
|
||||||
cartID[1] = char(hiByte);
|
|
||||||
cartID[2] = char(loByte);
|
|
||||||
|
|
||||||
// Split word
|
|
||||||
myWord = readWord_N64();
|
|
||||||
loByte = myWord & 0xFF;
|
|
||||||
hiByte = myWord >> 8;
|
|
||||||
|
|
||||||
// Country Code
|
|
||||||
cartID[3] = char(hiByte);
|
|
||||||
|
|
||||||
// Get rom version
|
|
||||||
romVersion = loByte;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read name out of rom
|
|
||||||
void printName() {
|
|
||||||
// Set the address for the next 512 bytes
|
|
||||||
setAddress_N64(romBase + 0x20);
|
|
||||||
|
|
||||||
// Dump name into 8.3 compatible format
|
|
||||||
byte myLength = 0;
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < 20; i += 2) {
|
|
||||||
// split word
|
// split word
|
||||||
word myWord = readWord_N64();
|
word myWord = readWord_N64();
|
||||||
byte loByte = myWord & 0xFF;
|
byte loByte = myWord & 0xFF;
|
||||||
byte hiByte = myWord >> 8;
|
byte hiByte = myWord >> 8;
|
||||||
|
|
||||||
if (((char(hiByte) >= 48 && char(hiByte) <= 57) || (char(hiByte) >= 65 && char(hiByte) <= 122)) && myLength < 8) {
|
// write to buffer
|
||||||
romName[myLength] = char(hiByte);
|
sdBuffer[c] = hiByte;
|
||||||
myLength++;
|
sdBuffer[c + 1] = loByte;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((char(loByte) >= 48 && char(loByte) <= 57) || (char(loByte) >= 65 && char(loByte) <= 122)) && myLength < 8) {
|
// Get cart id
|
||||||
romName[myLength] = char(loByte);
|
cartID[0] = sdBuffer[0x3B];
|
||||||
|
cartID[1] = sdBuffer[0x3C];
|
||||||
|
cartID[2] = sdBuffer[0x3D];
|
||||||
|
cartID[3] = sdBuffer[0x3E];
|
||||||
|
|
||||||
|
// Get rom version
|
||||||
|
romVersion = sdBuffer[0x3F];
|
||||||
|
|
||||||
|
// Get name in 8.3 compatible format
|
||||||
|
byte myLength = 0;
|
||||||
|
for (unsigned int i = 0; i < 20; i++) {
|
||||||
|
if (((char(sdBuffer[0x20 + i]) >= 48 && char(sdBuffer[0x20 + i]) <= 57) || (char(sdBuffer[0x20 + i]) >= 65 && char(sdBuffer[0x20 + i]) <= 122)) && myLength < 8) {
|
||||||
|
romName[myLength] = char(sdBuffer[0x20 + i]);
|
||||||
myLength++;
|
myLength++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
print_Msg(F("Name: "));
|
|
||||||
println_Msg(romName);
|
|
||||||
display_Update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************
|
/******************************************
|
||||||
|
Loading…
Reference in New Issue
Block a user