diff --git a/src-main/src/OneBus.cpp b/src-main/src/OneBus.cpp index 6e5f066..6083feb 100644 --- a/src-main/src/OneBus.cpp +++ b/src-main/src/OneBus.cpp @@ -98,12 +98,16 @@ uint8_t CPU_OneBus::Unscramble(uint8_t opcode) { int CPU_OneBus::Save (FILE *out) { int clen =CPU_RP2A03::Save(out); writeBool(EncryptionStatus); + if (RI.INES2_SubMapper == 11) + writeByte(reg4100[0x1C]); return clen; } int CPU_OneBus::Load (FILE *in, int version_id) { int clen =CPU_RP2A03::Load(in, version_id); readBool(EncryptionStatus); + if (RI.INES2_SubMapper == 11) + readByte(reg4100[0x1C]); return clen; } @@ -272,9 +276,14 @@ void APU_OneBus::IntWrite (int Bank, int Addr, int Val) { triangle2.Write(4, Val & 0x4); noise2.Write(4, Val & 0x8); break; - case 0x11C: if (RI.INES2_SubMapper ==10 || RI.INES2_SubMapper ==12 || RI.INES2_SubMapper ==14) dynamic_cast(CPU::CPU[which])->EncryptionStatus =(Val &0x40)? true: false; - //if (RI.INES2_SubMapper ==11) dynamic_cast(CPU::CPU[which])->EncryptionStatus =(Val &0x02)? true: false; - break; + case 0x11C: + if (RI.INES2_SubMapper ==12 || RI.INES2_SubMapper ==14) { + dynamic_cast(CPU::CPU[which])->EncryptionStatus =(Val &0x40)? true: false; + } else if (RI.INES2_SubMapper ==10) { + dynamic_cast(CPU::CPU[which])->EncryptionStatus =(Val & 0x2)? true: false; + } + //if (RI.INES2_SubMapper ==11) dynamic_cast(CPU::CPU[which])->EncryptionStatus =(Val &0x02)? true: false; + break; case 0x169: if (RI.INES2_SubMapper ==13 || RI.INES2_SubMapper ==15) dynamic_cast(CPU::CPU[which])->EncryptionStatus =(Val &1)? false: true; break; diff --git a/src-mappers/src/Hardware/h_OneBus.cpp b/src-mappers/src/Hardware/h_OneBus.cpp index da08729..4781c8e 100644 --- a/src-mappers/src/Hardware/h_OneBus.cpp +++ b/src-mappers/src/Hardware/h_OneBus.cpp @@ -6,7 +6,7 @@ #define SP16EN !!(reg2000[0x10] &0x04) #define SPEXTEN !!(reg2000[0x10] &0x08) #define BKEXTEN !!(reg2000[0x10] &0x10) -#define V16BEN !!(reg2000[0x10] &0x40 && ROM->INES2_SubMapper !=6 || ROM->INES2_SubMapper ==7) +#define V16BEN !!((reg2000[0x10] &0x40 && ROM->INES2_SubMapper !=6) || ROM->INES2_SubMapper ==7) #define COLCOMP !!(reg2000[0x10] &0x80) //#define V16BEN (ROM->ConsoleType ==CONSOLE_VT09 && ROM->INES2_VSFlags ==1) #define VRWB (reg2000[0x18] &0x07) diff --git a/src-mappers/src/iNES/MMC3-based/mapper268.cpp b/src-mappers/src/iNES/MMC3-based/mapper268.cpp index 04c4f76..3de59a7 100644 --- a/src-mappers/src/iNES/MMC3-based/mapper268.cpp +++ b/src-mappers/src/iNES/MMC3-based/mapper268.cpp @@ -33,7 +33,9 @@ void sync (void) { | (reg[1] &0x08? 0x80: 0x00) | (reg[1] &0x04? 0x100: 0x00) | (reg[1] &0x02? 0x200: 0x00) - |((reg[0] &0x30) <<6); + |((reg[0] &0x30) <<6) + |((~reg[1] &0x01) <<12) + ; break; case 4: /* Different arrangement of register 1, PRG A20-A21 in register 0 */ prgMaskGNROM = (reg[3] &0x10? (reg[1] &0x02? 0x03: 0x01): 0x00); diff --git a/src-mappers/src/iNES/OneBus/mapper270.cpp b/src-mappers/src/iNES/OneBus/mapper270.cpp index fbe9c3d..8979ef3 100644 --- a/src-mappers/src/iNES/OneBus/mapper270.cpp +++ b/src-mappers/src/iNES/OneBus/mapper270.cpp @@ -3,8 +3,6 @@ namespace { uint8_t reg4242; -uint8_t reg4118; -#define VA21 (OneBus::reg4100[0x00] &0x0F) void sync () { int OR =0; @@ -16,22 +14,12 @@ void sync () { break; case 3: OR = OneBus::reg4100[0x2C] &0x04? 0x0800: 0x0000; break; - case 4: OR = OneBus::reg4100[0x39] &0x02? 0x0800: 0x0000; - break; default: OR =(OneBus::reg4100[0x2C] &0x06? 0x0800: 0x0000) | - (OneBus::reg4100[0x2C] &0x01? 0x1000: 0x0000) | - (OneBus::reg4100[0x39] &0x02? 0x0800: 0x0000); - break; + (OneBus::reg4100[0x2C] &0x01? 0x1000: 0x0000); + break; } OneBus::syncPRG(0x07FF, OR); - if ( - (VA21 & 0x8) || // CHR-RAM via Outer Bank select (VT4ffx, addressing 16mb+ requires an additional GPIO register) - (reg4242 & 1) || // VT42xx CHR-RAM register - ( - (ROM->INES2_SubMapper == 12) && - (reg4118 & 0x80) - ) - ) { + if (reg4242 & 1) { // VT42xx CHR-RAM register EMU->SetCHR_RAM8(0x00, 0); // 2007 EMU->SetCHR_RAM8(0x20, 0); // BG EMU->SetCHR_RAM8(0x28, 0); // SPR @@ -58,9 +46,6 @@ void MAPINT write4 (int bank, int addr, int val) { if (addr == 0x242) { reg4242 = val; sync(); - } else if (addr == 0x118) { - reg4118 = val; - sync(); } else OneBus::writeAPU(bank, addr, val); } @@ -72,9 +57,7 @@ BOOL MAPINT load (void) { void MAPINT reset (RESET_TYPE resetType) { reg4242 = 0; - reg4118 = 0; OneBus::reg4100[0x2C] = 0; - OneBus::reg4100[0x39] = 0; OneBus::reset(resetType); EMU->SetCPUReadHandler (0x4, read4); @@ -94,7 +77,7 @@ uint16_t mapperNum =270; MapperInfo MapperInfo_270 = { &mapperNum, - _T("VRT VT42xx/4FFx platform"), + _T("VRT VT42xx platform"), COMPAT_FULL, load, reset, diff --git a/src-mappers/src/iNES/OneBus/mapper408.cpp b/src-mappers/src/iNES/OneBus/mapper408.cpp index 98602c3..a1e301f 100644 --- a/src-mappers/src/iNES/OneBus/mapper408.cpp +++ b/src-mappers/src/iNES/OneBus/mapper408.cpp @@ -1,36 +1,299 @@ #include "..\..\DLL\d_iNES.h" #include "..\..\Hardware\h_OneBus.h" +#include "..\..\Hardware\h_MMC1.h" +#include "..\..\Hardware\h_Latch.h" + +#define MODE_MMC3 0 +#define MODE_UNKNOWN 1 +#define MODE_MMC1 2 +#define MODE_UNROM 3 +#define IS_CHR_RAM (OneBus::reg4100[0x00] & 8) +#define MODE ((OneBus::reg4100[0x0B] >> 4) & 3) namespace { +/* for Go Retro Portable */ +class Protection { + const uint8_t* rom; + bool state_data; + bool state_enable; + bool state_clock; + bool state_out_data; + int state_cur; + int state_cmdbits; + int state_cmd; + int state_read_bits; + +public: + Protection(const uint8_t* _rom): + state_cur(0), + state_cmdbits(0), + state_cmd(0), + state_read_bits(0), + rom(_rom), + state_data(false), + state_enable(false), + state_clock(false), + state_out_data(false) + { + } + + bool get_data() { + return state_out_data; + } + + void reset() { + state_cmd = 0; + state_cmdbits = 0; + state_cur = 0; + state_out_data = false; + state_read_bits = 0; + } + + void set_data(bool data) { + state_data = data; + } + + void set_select(bool select) { + if (select != state_enable) + { + if (!select) + { + state_cur = 1; // ready to get command + state_cmdbits = 8; + } + else + { + state_cur = 0; // device not selected? + } + } + + state_enable = select; + } + + void set_clock(bool clock) { + if (clock != state_clock) + { + if (clock) + { + if (state_cur == 1) + { + state_cmd = (state_cmd << 1) | (state_data ? 1 : 0); + state_cmdbits--; + + if (state_cmdbits == 0) + { + if (state_cmd == 0x20) + { + state_cur = 2; + state_read_bits = 0; + } + else + { + state_cur = 0; + } + } + } + else if (state_cur == 2) + { + unsigned char readbyte = rom[state_read_bits >> 3]; + unsigned char readbit = (readbyte >> (~state_read_bits & 7)) & 1; + + state_out_data = readbit; + + state_read_bits++; + } + } + } + + state_clock = clock; + } +}; + +Protection* serialROM =NULL; + void sync () { - OneBus::syncPRG(0x0FFF, 0); - if (OneBus::reg4100[0x00] ==0x6A) { - EMU->SetCHR_RAM8(0x00, 0); // CPU + int OR = 0; + switch (ROM->INES2_SubMapper) { + case 1: // Go Retro Portable (WIP) + OR = (OneBus::reg4100[0x0F] & 0x20) ? 0x0800 : 0x0000; + break; + + default: // Standard VT4FFx platform + OR = ((OneBus::reg4100[0x39] & 0x02) ? 0x0800 : 0x0000) | + ((OneBus::reg4100[0x39] & 0x01) ? 0x1000 : 0x0000); // Custom PCB design + break; + } + + switch (MODE) { + case MODE_MMC3: + OneBus::syncPRG(0x07FF, OR); + OneBus::syncMirror(); + break; + case MODE_MMC1: + OneBus::reg2000[0x16] = (MMC1::getCHRBank(0) << 2) | 0; + OneBus::reg2000[0x17] = (MMC1::getCHRBank(0) << 2) | 2; + OneBus::reg2000[0x12] = (MMC1::getCHRBank(1) << 2) | 0; + OneBus::reg2000[0x13] = (MMC1::getCHRBank(1) << 2) | 1; + OneBus::reg2000[0x14] = (MMC1::getCHRBank(1) << 2) | 2; + OneBus::reg2000[0x15] = (MMC1::getCHRBank(1) << 2) | 3; + OneBus::syncPRG16(MMC1::getPRGBank(0), MMC1::getPRGBank(1), 0x07FF, OR); + MMC1::syncMirror(); + break; + case MODE_UNROM: + OneBus::syncPRG16(Latch::data, 0xFF, 0x07FF, OR); + OneBus::syncMirror(); + break; + //case MODE_CNROM: + // OneBus::reg2000[0x16] = Latch::data << 3 | 0; + // OneBus::reg2000[0x17] = Latch::data << 3 | 2; + // OneBus::reg2000[0x12] = Latch::data << 3 | 4; + // OneBus::reg2000[0x13] = Latch::data << 3 | 5; + // OneBus::reg2000[0x14] = Latch::data << 3 | 6; + // OneBus::reg2000[0x15] = Latch::data << 3 | 7; + // OneBus::syncPRG(0x07FF, OR); + // OneBus::syncMirror(); + // break; + } + + + if (IS_CHR_RAM) { + EMU->SetCHR_RAM8(0x00, 0); // 2007 EMU->SetCHR_RAM8(0x20, 0); // BG EMU->SetCHR_RAM8(0x28, 0); // SPR - } else - OneBus::syncCHR(0x7FFF, 0); - OneBus::syncMirror(); + } else { + OneBus::syncCHR(0x3FFF, OR << 3); + } } -BOOL MAPINT load (void) { +void setMode() { + switch (MODE) { + case MODE_MMC3: + for (int bank = 0x8; bank <= 0xF; bank++) + EMU->SetCPUWriteHandler(bank, OneBus::writeMMC3); + break; + case MODE_MMC1: + for (int bank = 0x8; bank <= 0xF; bank++) + EMU->SetCPUWriteHandler(bank, MMC1::write); + break; + case MODE_UNROM: + /*case MODE_CNROM:*/ + for (int bank = 0x8; bank <= 0xF; bank++) + EMU->SetCPUWriteHandler(bank, Latch::write); + break; + } +} + +int MAPINT read4(int bank, int addr) { + if (serialROM && addr == 0x139) { + return (serialROM->get_data()) ? 0x8 : 0x0; + } + + return OneBus::readAPU(bank, addr); +} + +int MAPINT read4Debug(int bank, int addr) { + if (serialROM && addr == 0x139) { + return (serialROM->get_data()) ? 0x8 : 0x0; + } + + return OneBus::readAPUDebug(bank, addr); +} + +void MAPINT write4(int bank, int addr, int val) { + OneBus::writeAPU(bank, addr, val); + if (addr == 0x10B) setMode(); + + // $4138 = Direction (0: In, 1: Out) + // $4139 = Pins + if (serialROM && addr == 0x139) { + serialROM->set_data(val & 8); + serialROM->set_select(val & 4); + serialROM->set_clock(~val & 2); + } +} + +BOOL MAPINT load(void) { + MMC1::load(sync, MMC1Type::MMC1A); + Latch::load(sync, NULL); OneBus::load(sync); + + if (ROM->PRGROMSize <= 0x100000) // VT4FFx predecessor + MapperInfo_408.Description = _T("Konami Collector's Series: Arcade Advanced"); + else + MapperInfo_408.Description = _T("VRT VT4FFx platform"); + + if ((ROM->INES2_SubMapper == 1) && (ROM->MiscROMSize & 0x0100)) { + serialROM = new Protection(ROM->MiscROMData + ROM->MiscROMSize - 0x0100); + MapperInfo_408.Description = _T("VRT VT4FFx platform (Protected by Serial ROM)"); + } + return TRUE; } +void MAPINT reset(RESET_TYPE resetType) { + OneBus::reg4100[0x38] = 0; + OneBus::reg4100[0x39] = 0; + MMC1::reset(resetType); + Latch::reset(resetType); + OneBus::reset(resetType); + + if (serialROM) { + serialROM->reset(); + } + + EMU->SetCPUReadHandler(0x4, read4); + EMU->SetCPUReadHandlerDebug(0x4, read4Debug); + EMU->SetCPUWriteHandler(0x4, write4); +} + +void MAPINT cpuCycle() { + if (MODE == MODE_MMC1) { + MMC1::cpuCycle(); + } + else if (MODE == MODE_MMC3) { + OneBus::cpuCycle(); + } +} + +void MAPINT ppuCycle(int addr, int scanline, int cycle, int isRendering) { + if (MODE == MODE_MMC3) { + OneBus::ppuCycle(addr, scanline, cycle, isRendering); + } +} + +int MAPINT saveLoad(STATE_TYPE stateMode, int offset, unsigned char* data) { + offset = OneBus::saveLoad(stateMode, offset, data); + offset = MMC1::saveLoad(stateMode, offset, data); + offset = Latch::saveLoad_D(stateMode, offset, data); + if (stateMode == STATE_LOAD) { + setMode(); + sync(); + } + return offset; +} + +void MAPINT unload() { + if (serialROM) { + delete serialROM; + serialROM = NULL; + } + + OneBus::unload(); +} + uint16_t mapperNum =408; } // namespace MapperInfo MapperInfo_408 = { &mapperNum, - _T("Konami Collector's Series: Arcade Advanced"), + _T("VRT VT4FFx platform"), COMPAT_FULL, load, - OneBus::reset, - OneBus::unload, - OneBus::cpuCycle, - OneBus::ppuCycle, - OneBus::saveLoad, + reset, + unload, + cpuCycle, + ppuCycle, + saveLoad, NULL, NULL }; \ No newline at end of file