cartreader/Cart_Reader/POKEMINI.ino
2023-07-28 15:32:54 +02:00

284 lines
7.0 KiB
C++

//******************************************
// POKEMON MINI MODULE
//******************************************
#ifdef enable_POKE
// Pokemon Mini
// Cartridge Pinout
// 32P 0.5mm pitch
// NOTE: Console SMD connector - 33P 1.0mm pitch
//
// TOP ROW BOTTOM ROW
// +----------+
// VCC (3.3V) -| B1 |
// | A1 |- VCC (3.3V)
// A20 -| B2 |
// | A2 |- A9/A19
// A8/A18 -| B3 |
// | A3 |- A7/A17
// A6/A16 -| B4 |
// | A4 |- A5/A15
// A4/A14 -| B5 |
// | A5 |- A3/A13
// A2/A12 -| B6 |
// | A6 |- A1/A11
// A0/A10 -| B7 |
// | A7 |- VCC (3.3V)
// HALE -| B8 |
// | -- |
// LALE -| B9 |
// | A8 |- GND
// D0 -| B10 |
// | A9 |- D1
// D2 -| B11 |
// | A10 |- D3
// D4 -| B12 |
// | A11 |- D5
// D6 -| B13 |
// | A12 |- D7
// OE -| B14 |
// | A13 |- IRQ
// WE -| B15 |
// | A14 |- CS
// CARD_N -| B16 |
// | A15 |- GND
// GND -| B17 |
// +----------+
//
// TOP
// +----------------------------------------------------------------------------+
// | B17 B16 B15 B14 B13 B12 B11 B10 B9 B8 B7 B6 B5 B4 B3 B2 B1 |
// LEFT | | RIGHT
// | A15 A14 A13 A12 A11 A10 A9 A8 --- A7 A6 A5 A4 A3 A2 A1 |
// +----------------------------------------------------------------------------+
// BOTTOM
// CONTROL PINS:
// HALE(PH0) - SNES RESET
// CS(PH3) - SNES /CS
// LALE(PH4) - SNES /IRQ
// WE(PH5) - SNES /WR
// OE(PH6) - SNES /RD
// NOTE: SET VOLTAGE TO 3.3V
//******************************************
// Defines
//******************************************
#define HALE_ENABLE PORTH |= (1 << 0) // LATCH HIGH ADDRESS
#define HALE_DISABLE PORTH &= ~(1 << 0)
#define LALE_ENABLE PORTH |= (1 << 4) // LATCH LOW ADDRESS
#define LALE_DISABLE PORTH &= ~(1 << 4)
#define CS_ENABLE PORTH |= (1 << 3) // CHIP SELECT
#define CS_DISABLE PORTH &= ~(1 << 3)
#define WE_ENABLE PORTH |= (1 << 5) // WRITE ENABLE
#define WE_DISABLE PORTH &= ~(1 << 5)
#define OE_ENABLE PORTH |= (1 << 6) // OUTPUT ENABLE
#define OE_DISABLE PORTH &= ~(1 << 6)
//******************************************
// Menu
//******************************************
// Base Menu
static const char pokeMenuItem1[] PROGMEM = "Read ROM";
static const char* const menuOptionsPOKE[] PROGMEM = { pokeMenuItem1, string_reset2 };
void pokeMenu() {
convertPgm(menuOptionsPOKE, 2);
uint8_t mainMenu = question_box(F("POKEMON MINI MENU"), menuOptions, 2, 0);
switch (mainMenu) {
case 0:
// Read ROM
sd.chdir("/");
readROM_POKE();
sd.chdir("/");
break;
case 1:
// reset
resetArduino();
break;
}
}
//******************************************
// SETUP
//******************************************
void setup_POKE() {
// Request 3.3V
setVoltage(VOLTS_SET_3V3);
// Set Address Pins to Output
// Pokemon Mini uses A0-A9 (DUAL A10-A19) + A20 (CONNECT TO SNES A10) [A11-A23 UNUSED]
//A0-A7
DDRF = 0xFF;
//A8-A15
DDRK = 0xFF;
//A16-A23
DDRL = 0xFF;
// Set Control Pins to Output
// LALE(PH0) ---(PH1) CS(PH3) HALE(PH4) WE(PH5) OE(PH6)
DDRH |= (1 << 0) | (1 << 1) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6);
// Set TIME(PJ0) to Output (UNUSED)
DDRJ |= (1 << 0);
// Set Pins (D0-D7) to Input
DDRC = 0x00;
// Setting Control Pins to LOW (DISABLE)
// LALE(PH0) CS(PH3) HALE(PH4) WE(PH5) OE(PH6)
PORTH &= ~(1 << 0) & ~(1 << 3) & ~(1 << 4) & ~(1 << 5) & ~(1 << 6);
// SET CS HIGH
PORTH |= (1 << 3); // CS HIGH (ENABLE)
// Set Unused Data Pins (PA0-PA7) to Output
DDRA = 0xFF;
// Set Unused Pins HIGH
PORTA = 0xFF;
PORTH |= (1 << 1); // CPUCLK(PH1)
PORTL = 0xFF; // A16-A23
PORTJ |= (1 << 0); // TIME(PJ0)
strcpy(romName, "POKEMINI");
mode = mode_POKE;
}
//******************************************
// READ DATA
//******************************************
uint8_t readData_POKE(uint32_t addr) {
// Address Lines A0-A20 = 1MB (ALL ROMS ARE 512K)
// 100000 = 1 0000 0000 0000 0000 0000 = 100 0000 0000|00 0000 0000
// High Address A10-A20
PORTF = (addr >> 10) & 0xFF; // A10-A17
PORTK = (addr >> 18) & 0x07; // A18-A20
HALE_ENABLE; // LATCH HIGH ADDRESS
NOP;
NOP;
HALE_DISABLE;
// Low Address A0-A9
PORTF = addr & 0xFF; // A0-A7
PORTK = (addr >> 8) & 0x03; // A8-A9
LALE_ENABLE; // LATCH LOW ADDRESS
NOP;
NOP;
// Read Enable
OE_ENABLE; // OE HIGH
NOP;
NOP;
NOP;
NOP;
NOP;
// Data
uint8_t ret = PINC;
// Read Disable
OE_DISABLE; // OE LOW
NOP;
NOP;
NOP;
NOP;
LALE_DISABLE;
return ret;
}
//******************************************
// WRITE DATA
//******************************************
void writeData_POKE(uint32_t addr, uint8_t data) {
// High Address A10-A20
PORTF = (addr >> 10) & 0xFF; // A10-A17
PORTK = (addr >> 18) & 0x07; // A18-A20
HALE_ENABLE; // LATCH HIGH ADDRESS
NOP;
NOP;
HALE_DISABLE;
// Low Address A0-A9
PORTF = addr & 0xFF; // A0-A7
PORTK = (addr >> 8) & 0x03; // A8-A9
LALE_ENABLE; // LATCH LOW ADDRESS
// Set Data to Output
DDRC = 0xFF;
PORTC = data;
// Write Enable
WE_ENABLE; // WE HIGH
NOP;
NOP;
NOP;
NOP;
NOP;
// Write Disable
WE_DISABLE; // OE LOW
NOP;
NOP;
NOP;
NOP;
LALE_DISABLE;
// Reset Data to Input
DDRC = 0x00;
}
//******************************************
// READ ROM
//******************************************
void readROM_POKE() {
strcpy(fileName, romName);
strcat(fileName, ".min");
// create a new folder for storing rom file
EEPROM_readAnything(0, foldern);
sprintf(folder, "POKE/ROM/%d", foldern);
sd.mkdir(folder, true);
sd.chdir(folder);
display_Clear();
print_STR(saving_to_STR, 0);
print_Msg(folder);
println_Msg(F("/..."));
display_Update();
// open file on sdcard
if (!myFile.open(fileName, O_RDWR | O_CREAT))
print_FatalError(sd_error_STR);
// write new folder number back to EEPROM
foldern++;
EEPROM_writeAnything(0, foldern);
for (uint32_t addr = 0; addr < 0x80000; addr += 512) { // 512K
for (int w = 0; w < 512; w++) {
uint8_t temp = readData_POKE(addr + w);
sdBuffer[w] = temp;
}
myFile.write(sdBuffer, 512);
}
myFile.close();
compareCRC("pkmn.txt", 0, 1, 0);
println_Msg(F(""));
// Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update();
wait();
}
#endif