mirror of
https://github.com/sanni/cartreader.git
synced 2024-11-24 05:29:17 +01:00
V20 Changed N64 timing a bit
Hopefully I didn't break anything :x
This commit is contained in:
parent
94a7337d22
commit
6bcdc9526c
@ -2,15 +2,15 @@
|
|||||||
Cartridge Reader for Arduino Mega2560
|
Cartridge Reader for Arduino Mega2560
|
||||||
|
|
||||||
Author: sanni
|
Author: sanni
|
||||||
Date: 2017-01-12
|
Date: 2017-01-29
|
||||||
Version: V19L
|
Version: V20
|
||||||
|
|
||||||
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
|
||||||
Clockgen: https://github.com/etherkit/Si5351Arduino
|
Clockgen: https://github.com/etherkit/Si5351Arduino
|
||||||
RGB Tools lib: https://github.com/joushx/Arduino-RGB-Tools
|
RGB Tools lib: https://github.com/joushx/Arduino-RGB-Tools
|
||||||
|
|
||||||
Compiled with Arduino 1.6.11
|
Compiled with Arduino 1.8.0
|
||||||
|
|
||||||
Thanks to:
|
Thanks to:
|
||||||
MichlK - ROM-Reader for Super Nintendo
|
MichlK - ROM-Reader for Super Nintendo
|
||||||
@ -34,7 +34,7 @@
|
|||||||
YamaArashi - GBA flashrom bank switch command
|
YamaArashi - GBA flashrom bank switch command
|
||||||
|
|
||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
char ver[5] = "V19L";
|
char ver[5] = "V20";
|
||||||
|
|
||||||
/******************************************
|
/******************************************
|
||||||
Define Output
|
Define Output
|
||||||
|
@ -104,8 +104,8 @@ void setup_GB() {
|
|||||||
|
|
||||||
// Set Data Pins (D0-D7) to Input
|
// Set Data Pins (D0-D7) to Input
|
||||||
DDRC = 0x00;
|
DDRC = 0x00;
|
||||||
// Enable Internal Pullups
|
// Disable Internal Pullups
|
||||||
//PORTC = 0xFF;
|
PORTC = 0x00;
|
||||||
|
|
||||||
// Print start page
|
// Print start page
|
||||||
getCartInfo_GB();
|
getCartInfo_GB();
|
||||||
@ -244,6 +244,12 @@ void setup_GB() {
|
|||||||
/******************************************
|
/******************************************
|
||||||
Low level functions
|
Low level functions
|
||||||
*****************************************/
|
*****************************************/
|
||||||
|
// Switch data pins to read
|
||||||
|
void dataIn_GB() {
|
||||||
|
// Set to Input
|
||||||
|
DDRC = 0x00;
|
||||||
|
}
|
||||||
|
|
||||||
byte readByte_GB(word myAddress) {
|
byte readByte_GB(word myAddress) {
|
||||||
PORTF = myAddress & 0xFF;
|
PORTF = myAddress & 0xFF;
|
||||||
PORTK = (myAddress >> 8) & 0xFF;
|
PORTK = (myAddress >> 8) & 0xFF;
|
||||||
@ -390,7 +396,7 @@ void readROM_GB() {
|
|||||||
dataOut();
|
dataOut();
|
||||||
// Set ROM bank
|
// Set ROM bank
|
||||||
writeByte_GB(0x2100, y);
|
writeByte_GB(0x2100, y);
|
||||||
dataIn();
|
dataIn_GB();
|
||||||
if (y > 1) {
|
if (y > 1) {
|
||||||
addr = 0x4000;
|
addr = 0x4000;
|
||||||
}
|
}
|
||||||
@ -525,7 +531,7 @@ void readSRAM_GB() {
|
|||||||
writeByte_GB(0x4000, bank);
|
writeByte_GB(0x4000, bank);
|
||||||
|
|
||||||
// Read RAM
|
// Read RAM
|
||||||
dataIn();
|
dataIn_GB();
|
||||||
for (addr = 0xA000; addr <= endaddr; addr = addr + 64) {
|
for (addr = 0xA000; addr <= endaddr; addr = addr + 64) {
|
||||||
uint8_t readData[64];
|
uint8_t readData[64];
|
||||||
for (int i = 0; i < 64; i++) {
|
for (int i = 0; i < 64; i++) {
|
||||||
@ -537,7 +543,7 @@ void readSRAM_GB() {
|
|||||||
dataOut();
|
dataOut();
|
||||||
// Disable RAM
|
// Disable RAM
|
||||||
writeByte_GB(0x0000, 0x00);
|
writeByte_GB(0x0000, 0x00);
|
||||||
dataIn();
|
dataIn_GB();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
print_Error(F("Cart has no SRAM"), false);
|
print_Error(F("Cart has no SRAM"), false);
|
||||||
@ -616,7 +622,7 @@ void writeSRAM_GB() {
|
|||||||
print_Error(F("Cart has no SRAM"), false);
|
print_Error(F("Cart has no SRAM"), false);
|
||||||
}
|
}
|
||||||
// Set pins to input
|
// Set pins to input
|
||||||
dataIn();
|
dataIn_GB();
|
||||||
|
|
||||||
// Close the file:
|
// Close the file:
|
||||||
myFile.close();
|
myFile.close();
|
||||||
@ -665,7 +671,7 @@ unsigned long verifySRAM_GB() {
|
|||||||
writeByte_GB(0x4000, bank);
|
writeByte_GB(0x4000, bank);
|
||||||
|
|
||||||
// Read RAM
|
// Read RAM
|
||||||
dataIn();
|
dataIn_GB();
|
||||||
for (addr = 0xA000; addr <= endaddr; addr = addr + 64) {
|
for (addr = 0xA000; addr <= endaddr; addr = addr + 64) {
|
||||||
//fill sdBuffer
|
//fill sdBuffer
|
||||||
myFile.read(sdBuffer, 64);
|
myFile.read(sdBuffer, 64);
|
||||||
@ -679,7 +685,7 @@ unsigned long verifySRAM_GB() {
|
|||||||
dataOut();
|
dataOut();
|
||||||
// Disable RAM
|
// Disable RAM
|
||||||
writeByte_GB(0x0000, 0x00);
|
writeByte_GB(0x0000, 0x00);
|
||||||
dataIn();
|
dataIn_GB();
|
||||||
}
|
}
|
||||||
// Close the file:
|
// Close the file:
|
||||||
myFile.close();
|
myFile.close();
|
||||||
@ -716,7 +722,7 @@ void writeFlash_GB() {
|
|||||||
romType = myFile.read();
|
romType = myFile.read();
|
||||||
romSize = myFile.read();
|
romSize = myFile.read();
|
||||||
// Go back to file beginning
|
// Go back to file beginning
|
||||||
myFile.seekCur(0);
|
myFile.seekSet(0);
|
||||||
|
|
||||||
numBanks = 2; // Default 32K
|
numBanks = 2; // Default 32K
|
||||||
if (romSize == 1) {
|
if (romSize == 1) {
|
||||||
@ -759,8 +765,10 @@ void writeFlash_GB() {
|
|||||||
// Set data pins to output
|
// Set data pins to output
|
||||||
dataOut();
|
dataOut();
|
||||||
|
|
||||||
// Set ROM bank 1
|
// Set ROM bank hi 0
|
||||||
writeByte_GB(0x2100, 1);
|
writeByte_GB(0x3000, 0);
|
||||||
|
// Set ROM bank low 0
|
||||||
|
writeByte_GB(0x2000, 0);
|
||||||
delay(100);
|
delay(100);
|
||||||
|
|
||||||
// Reset flash
|
// Reset flash
|
||||||
@ -772,7 +780,7 @@ void writeFlash_GB() {
|
|||||||
writeByte_GB(0x2aa, 0x55);
|
writeByte_GB(0x2aa, 0x55);
|
||||||
writeByte_GB(0x555, 0x90);
|
writeByte_GB(0x555, 0x90);
|
||||||
|
|
||||||
dataIn();
|
dataIn_GB();
|
||||||
|
|
||||||
// Read the two id bytes into a string
|
// Read the two id bytes into a string
|
||||||
sprintf(flashid, "%02X%02X", readByte_GB(0), readByte_GB(1));
|
sprintf(flashid, "%02X%02X", readByte_GB(0), readByte_GB(1));
|
||||||
@ -781,7 +789,7 @@ void writeFlash_GB() {
|
|||||||
println_Msg(F("MBM29F033C"));
|
println_Msg(F("MBM29F033C"));
|
||||||
print_Msg(F("Banks: "));
|
print_Msg(F("Banks: "));
|
||||||
print_Msg(numBanks);
|
print_Msg(numBanks);
|
||||||
println_Msg(F("/256"));
|
println_Msg(F("/255"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
}
|
||||||
else if (strcmp(flashid, "0141") == 0) {
|
else if (strcmp(flashid, "0141") == 0) {
|
||||||
@ -821,7 +829,7 @@ void writeFlash_GB() {
|
|||||||
writeByte_GB(0x2aa, 0x55);
|
writeByte_GB(0x2aa, 0x55);
|
||||||
writeByte_GB(0x555, 0x10);
|
writeByte_GB(0x555, 0x10);
|
||||||
|
|
||||||
dataIn();
|
dataIn_GB();
|
||||||
|
|
||||||
// Read the status register
|
// Read the status register
|
||||||
byte statusReg = readByte_GB(0);
|
byte statusReg = readByte_GB(0);
|
||||||
@ -839,32 +847,25 @@ void writeFlash_GB() {
|
|||||||
println_Msg(F("Blankcheck"));
|
println_Msg(F("Blankcheck"));
|
||||||
display_Update();
|
display_Update();
|
||||||
|
|
||||||
unsigned int addr = 0;
|
|
||||||
|
|
||||||
// Read x number of banks
|
// Read x number of banks
|
||||||
for (int y = 1; y < numBanks; y++) {
|
for (int currBank = 0; currBank < numBanks; currBank++) {
|
||||||
// Blink led
|
// Blink led
|
||||||
PORTB ^= (1 << 4);
|
PORTB ^= (1 << 4);
|
||||||
|
|
||||||
dataOut();
|
dataOut();
|
||||||
|
|
||||||
// Set ROM bank
|
// Set ROM bank
|
||||||
writeByte_GB(0x2100, y);
|
writeByte_GB(0x2000, currBank);
|
||||||
dataIn();
|
dataIn();
|
||||||
|
|
||||||
if (y > 1) {
|
for (unsigned int currAddr = 0x4000; currAddr < 0x7FFF; currAddr += 512) {
|
||||||
addr = 0x4000;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (; addr <= 0x7FFF; addr += 512) {
|
|
||||||
uint8_t readData[512];
|
uint8_t readData[512];
|
||||||
for (int i = 0; i < 512; i++) {
|
for (int currByte = 0; currByte < 512; currByte++) {
|
||||||
readData[i] = readByte_GB(addr + i);
|
readData[currByte] = readByte_GB(currAddr + currByte);
|
||||||
}
|
}
|
||||||
for (int j = 0; j < 512; j++) {
|
for (int j = 0; j < 512; j++) {
|
||||||
if (readData[j] != 0xFF) {
|
if (readData[j] != 0xFF) {
|
||||||
println_Msg(F("Not empty"));
|
println_Msg(F("Not empty"));
|
||||||
display_Update();
|
|
||||||
print_Error(F("Erase failed"), true);
|
print_Error(F("Erase failed"), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -875,42 +876,37 @@ void writeFlash_GB() {
|
|||||||
display_Update();
|
display_Update();
|
||||||
|
|
||||||
// Write flash
|
// Write flash
|
||||||
addr = 0;
|
|
||||||
dataOut();
|
dataOut();
|
||||||
|
|
||||||
for (int y = 1; y < numBanks; y++) {
|
for (int currBank = 0; currBank < numBanks; currBank++) {
|
||||||
// Blink led
|
// Blink led
|
||||||
PORTB ^= (1 << 4);
|
PORTB ^= (1 << 4);
|
||||||
|
|
||||||
// Set ROM bank
|
// Set ROM bank
|
||||||
writeByte_GB(0x2100, y);
|
writeByte_GB(0x2000, currBank);
|
||||||
|
|
||||||
if (y > 1) {
|
for (unsigned int currAddr = 0x4000; currAddr < 0x7FFF; currAddr += 512) {
|
||||||
addr = 0x4000;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (; addr <= 0x7FFF; addr += 512) {
|
|
||||||
myFile.read(sdBuffer, 512);
|
myFile.read(sdBuffer, 512);
|
||||||
|
|
||||||
for (int c = 0; c < 512; c++) {
|
for (int currByte = 0; currByte < 512; currByte++) {
|
||||||
// Write command sequence
|
// Write command sequence
|
||||||
writeByte_GB(0x555, 0xaa);
|
writeByte_GB(0x555, 0xaa);
|
||||||
writeByte_GB(0x2aa, 0x55);
|
writeByte_GB(0x2aa, 0x55);
|
||||||
writeByte_GB(0x555, 0xa0);
|
writeByte_GB(0x555, 0xa0);
|
||||||
// Write current byte
|
// Write current byte
|
||||||
writeByte_GB(addr + c, sdBuffer[c]);
|
writeByte_GB(currAddr + currByte, sdBuffer[currByte]);
|
||||||
|
|
||||||
// Set data pins to input
|
// Set data pins to input
|
||||||
dataIn();
|
dataIn();
|
||||||
|
|
||||||
// Switch CS(PH3) and RD(PH6) to LOW
|
// Setting CS(PH3) and OE/RD(PH6) LOW
|
||||||
PORTH &= ~((1 << 3) | (1 << 6));
|
PORTH &= ~((1 << 3) | (1 << 6));
|
||||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
|
|
||||||
|
|
||||||
// Busycheck
|
// Busy check
|
||||||
while ((PINC & 0x80) != (sdBuffer[c] & 0x80)) {
|
while ((PINC & 0x80) != (sdBuffer[currByte] & 0x80)) {
|
||||||
}
|
}
|
||||||
// Switch CS(PH3) and RD(PH6) to HIGH
|
|
||||||
|
// Switch CS(PH3) and OE/RD(PH6) to HIGH
|
||||||
PORTH |= (1 << 3) | (1 << 6);
|
PORTH |= (1 << 3) | (1 << 6);
|
||||||
|
|
||||||
// Set data pins to output
|
// Set data pins to output
|
||||||
@ -918,14 +914,56 @@ void writeFlash_GB() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Set data pins to input again
|
|
||||||
dataIn();
|
|
||||||
|
|
||||||
|
// Set data pins to input again
|
||||||
|
dataIn_GB();
|
||||||
|
|
||||||
|
println_Msg(F("Verifying"));
|
||||||
|
display_Update();
|
||||||
|
|
||||||
|
// Go back to file beginning
|
||||||
|
myFile.seekSet(0);
|
||||||
|
unsigned int addr = 0;
|
||||||
|
writeErrors = 0;
|
||||||
|
|
||||||
|
// Verify flashrom
|
||||||
|
for (int y = 1; y < numBanks; y++) {
|
||||||
|
// Set ROM bank
|
||||||
|
dataOut();
|
||||||
|
writeByte_GB(0x2100, y);
|
||||||
|
dataIn_GB();
|
||||||
|
|
||||||
|
// Blink led
|
||||||
|
PORTB ^= (1 << 4);
|
||||||
|
|
||||||
|
if (y > 1) {
|
||||||
|
addr = 0x4000;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; addr <= 0x7FFF; addr = addr + 512) {
|
||||||
|
// Fill sdBuffer
|
||||||
|
myFile.read(sdBuffer, 512);
|
||||||
|
// Compare
|
||||||
|
for (int i = 0; i < 512; i++) {
|
||||||
|
if (readByte_GB(addr + i) != sdBuffer[i]) {
|
||||||
|
writeErrors++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// Close the file:
|
// Close the file:
|
||||||
myFile.close();
|
myFile.close();
|
||||||
|
|
||||||
println_Msg(F("Done"));
|
if (writeErrors == 0) {
|
||||||
display_Update();
|
println_Msg(F("OK"));
|
||||||
|
display_Update();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print_Msg(F("Error: "));
|
||||||
|
print_Msg(writeErrors);
|
||||||
|
println_Msg(F(" bytes "));
|
||||||
|
print_Error(F("did not verify."), false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
println_Msg(F("Can't open file"));
|
println_Msg(F("Can't open file"));
|
||||||
|
@ -277,6 +277,9 @@ void setup_N64_Cart() {
|
|||||||
// Activate Internal Pullup Resistors
|
// Activate Internal Pullup Resistors
|
||||||
//PORTH |= (1 << 4);
|
//PORTH |= (1 << 4);
|
||||||
|
|
||||||
|
// Wait until all is stable
|
||||||
|
delay(500);
|
||||||
|
|
||||||
// Print start page
|
// Print start page
|
||||||
getCartInfo_N64();
|
getCartInfo_N64();
|
||||||
if (cartSize != 0) {
|
if (cartSize != 0) {
|
||||||
@ -365,27 +368,33 @@ void setAddress_N64(unsigned long myAddress) {
|
|||||||
PORTF = myAdrHighOut & 0xFF;
|
PORTF = myAdrHighOut & 0xFF;
|
||||||
PORTK = (myAdrHighOut >> 8) & 0xFF;
|
PORTK = (myAdrHighOut >> 8) & 0xFF;
|
||||||
|
|
||||||
// Leave ale_H and ale_L high for ~120ns
|
// Leave ale_H high for additional 120ns
|
||||||
__asm__("nop\n\t""nop\n\t");
|
__asm__("nop\n\t""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;
|
||||||
|
|
||||||
// Leave ale_L high for another ~110ns
|
// Leave ale_L high for ~180ns
|
||||||
__asm__("nop\n\t""nop\n\t");
|
__asm__("nop\n\t""nop\n\t""nop\n\t");
|
||||||
|
|
||||||
// Pull ale_L(PC0) low
|
// Pull ale_L(PC0) low
|
||||||
PORTC &= ~(1 << 0);
|
PORTC &= ~(1 << 0);
|
||||||
|
|
||||||
// Wait ~1000ns before read
|
// Leave address pins stable for a little bit
|
||||||
__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""nop\n\t");
|
__asm__("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();
|
||||||
|
|
||||||
|
// 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");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read one word out of the cartridge
|
// Read one word out of the cartridge
|
||||||
@ -393,21 +402,15 @@ word readWord_N64() {
|
|||||||
// Pull read(PH6) low
|
// Pull read(PH6) low
|
||||||
PORTH &= ~(1 << 6);
|
PORTH &= ~(1 << 6);
|
||||||
|
|
||||||
// Wait ~100ns
|
// Wait ~300ns
|
||||||
__asm__("nop\n\t""nop\n\t");
|
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
|
||||||
|
|
||||||
// Join bytes from PINF and PINK into a word
|
// Join bytes from PINF and PINK into a word
|
||||||
word tempWord = ( ( PINK & 0xFF ) << 8 ) | ( PINF & 0xFF );
|
word tempWord = ( ( PINK & 0xFF ) << 8 ) | ( PINF & 0xFF );
|
||||||
|
|
||||||
// Wait ~200ns
|
|
||||||
__asm__("nop\n\t""nop\n\t""nop\n\t");
|
|
||||||
|
|
||||||
// Pull read(PH6) high
|
// Pull read(PH6) high
|
||||||
PORTH |= (1 << 6);
|
PORTH |= (1 << 6);
|
||||||
|
|
||||||
// Wait ~60ns
|
|
||||||
__asm__("nop\n\t");
|
|
||||||
|
|
||||||
return tempWord;
|
return tempWord;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user