cartreader/Cart_Reader/POKEMINI.ino
Ancyker 2cf7f5dbe7 Cleanup voltage requests
The `setVoltage()` function should be called even when `ENABLE_VSELECT` is disabled because `ENABLE_3V3FIX` also uses it. There is no resource cost to do this as when both options are disabled the compiler will optimize this function out. This just "future proofs" the code so if that function ever does more it doesn't need updated everywhere. This applies to `setup_FlashVoltage()` as well.

The changes to OSCR.cpp are just for code formatting and additional comments to clarify this.
2023-06-26 15:25:54 -04:00

283 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();
calcCRC(fileName, 0x80000, NULL, 0); // 512K
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