From 52962a28a7b368fc1c697d80a439cc53beba6f8b Mon Sep 17 00:00:00 2001 From: PsyK0p4T <87064902+PsyK0p4T@users.noreply.github.com> Date: Fri, 16 Jun 2023 09:17:21 +0200 Subject: [PATCH] Update MD.ino Add support for Virtua Racing (E/U/J) All credits go to Sanni for initial ideas, and Prominos for researches and code. --- Cart_Reader/MD.ino | 89 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 81 insertions(+), 8 deletions(-) diff --git a/Cart_Reader/MD.ino b/Cart_Reader/MD.ino index 73ba38b..ce3e6df 100644 --- a/Cart_Reader/MD.ino +++ b/Cart_Reader/MD.ino @@ -13,6 +13,7 @@ word addrhi; word addrlo; word chksum; boolean is32x = 0; +boolean isSVP = 0; //*********************************************** // EEPROM SAVE TYPES @@ -183,6 +184,11 @@ void mdLoadConf() { } #endif +void pulse_clock(int n) { + for (int i=0; i use similar access delay of 6 x 62.5 = 375ns NOP; @@ -572,6 +590,12 @@ word readWord_MD(unsigned long myAddress) { PORTH |= (1 << 3); // Setting OE(PH6) HIGH PORTH |= (1 << 6); + // Setting AS(PJ1) HIGH + PORTJ |= (1 << 1); + // Setting ASEL(PG5) HIGH + PORTG |= (1 << 5); + // Pulse CLK(PH1), needed for SVP enhanced carts + pulse_clock(10); // these 6x nop delays have been here before, unknown what they mean NOP; @@ -718,6 +742,12 @@ void getCartInfo_MD() { id[c + 1] = loByte; } + //Identify games using SVP chip + if (!strncmp("GM MK-1229 ", id, 11) || !strncmp("GM G-7001 ", id, 11)) // Virtua Racing (E/U/J) + isSVP = 1; + else + isSVP = 0; + // Fix cartridge sizes according to no-intro database if (cartSize == 0x400000) { switch (chksum) { @@ -1414,6 +1444,14 @@ void readROM_MD() { PORTH &= ~(1 << 3); // Setting OE(PH6) LOW PORTH &= ~(1 << 6); + // Setting AS(PJ1) LOW + PORTJ &= ~(1 << 1); + // Setting ASEL(PG5) LOW + PORTG &= ~(1 << 5); + // Pulse CLK(PH1) + if(isSVP) + pulse_clock(10); + // most MD ROMs are 200ns, comparable to SNES > use similar access delay of 6 x 62.5 = 375ns NOP; NOP; @@ -1430,6 +1468,13 @@ void readROM_MD() { PORTH |= (1 << 3); // Setting OE(PH6) HIGH PORTH |= (1 << 6); + // Setting AS(PJ1) HIGH + PORTJ |= (1 << 1); + // Setting ASEL(PG5) HIGH + PORTG |= (1 << 5); + // Pulse CLK(PH1) + if(isSVP) + pulse_clock(10); // Skip first 256 words if (((currBuffer == 0) && (currWord >= 256)) || (currBuffer > 0)) { @@ -1463,6 +1508,14 @@ void readROM_MD() { PORTH &= ~(1 << 3); // Setting OE(PH6) LOW PORTH &= ~(1 << 6); + // Setting AS(PJ1) LOW + PORTJ &= ~(1 << 1); + // Setting ASEL(PG5) LOW + PORTG &= ~(1 << 5); + // Pulse CLK(PH1) + if(isSVP) + pulse_clock(10); + // most MD ROMs are 200ns, comparable to SNES > use similar access delay of 6 x 62.5 = 375ns NOP; NOP; @@ -1479,6 +1532,13 @@ void readROM_MD() { PORTH |= (1 << 3); // Setting OE(PH6) HIGH PORTH |= (1 << 6); + // Setting AS(PJ1) HIGH + PORTJ |= (1 << 1); + // Setting ASEL(PG5) HIGH + PORTG |= (1 << 5); + // Pulse CLK(PH1) + if(isSVP) + pulse_clock(10); // Skip first 256 words if (((currBuffer == 0) && (currWord >= 256)) || (currBuffer > 0)) { @@ -1513,6 +1573,14 @@ void readROM_MD() { PORTH &= ~(1 << 3); // Setting OE(PH6) LOW PORTH &= ~(1 << 6); + // Setting AS(PJ1) LOW + PORTJ &= ~(1 << 1); + // Setting ASEL(PG5) LOW + PORTG &= ~(1 << 5); + // Pulse CLK(PH1) + if(isSVP) + PORTH ^= (1 << 1); + // most MD ROMs are 200ns, comparable to SNES > use similar access delay of 6 x 62.5 = 375ns NOP; NOP; @@ -1529,6 +1597,13 @@ void readROM_MD() { PORTH |= (1 << 3); // Setting OE(PH6) HIGH PORTH |= (1 << 6); + // Setting AS(PJ1) HIGH + PORTJ |= (1 << 1); + // Setting ASEL(PG5) HIGH + PORTG |= (1 << 5); + // Pulse CLK(PH1) + if(isSVP) + PORTH ^= (1 << 1); calcCKSSonic2 += ((buffer[d] << 8) | buffer[d + 1]); d += 2; @@ -2012,7 +2087,6 @@ void EepromInit(byte eepmode) { // Acclaim Type 2 PORTL = 0x10; // ADDR A16-A23 PORTA = 0x00; // DATA D8-D15 PORTH |= (1 << 0); // /RES HIGH - PORTC = eepmode; // EEPROM Switch: 0 = Enable (Read EEPROM), 1 = Disable (Read ROM) PORTH &= ~(1 << 3); // CE LOW PORTH &= ~(1 << 4) & ~(1 << 5); // /UDSW + /LDSW LOW @@ -2250,7 +2324,6 @@ void EepromSet1() { } } - void EepromDevice() { // 24C02+ EepromSet1(); EepromSet0();