Compare commits

...
Sign in to create a new pull request.

7 commits

Author SHA1 Message Date
wrapper
38665207e0 Add Go Retro Portable protection (code from MAME) 2026-06-15 00:48:23 +07:00
wrapper
003402a361 VT4FFx stuff now uses Mapper 408 2026-06-14 21:32:27 +07:00
wrapper
41ae4e61be fix s10 2026-06-13 20:57:27 +07:00
wrapper
2227785cb5 submapper 11 savestate fix 2026-06-11 19:08:33 +07:00
wrapper
1e7d3e0457 v16ben 2026-06-10 07:45:49 +07:00
wrapper
c4d5f10b60 fictional smd133c with 64mb 2026-06-10 07:39:16 +07:00
wrapper
efe2e7cd3b 64mb for vt4fff platform 2026-06-01 15:42:31 +07:00
5 changed files with 296 additions and 39 deletions

View file

@ -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_OneBus*>(CPU::CPU[which])->EncryptionStatus =(Val &0x40)? true: false;
//if (RI.INES2_SubMapper ==11) dynamic_cast<CPU::CPU_OneBus*>(CPU::CPU[which])->EncryptionStatus =(Val &0x02)? true: false;
break;
case 0x11C:
if (RI.INES2_SubMapper ==12 || RI.INES2_SubMapper ==14) {
dynamic_cast<CPU::CPU_OneBus*>(CPU::CPU[which])->EncryptionStatus =(Val &0x40)? true: false;
} else if (RI.INES2_SubMapper ==10) {
dynamic_cast<CPU::CPU_OneBus*>(CPU::CPU[which])->EncryptionStatus =(Val & 0x2)? true: false;
}
//if (RI.INES2_SubMapper ==11) dynamic_cast<CPU::CPU_OneBus*>(CPU::CPU[which])->EncryptionStatus =(Val &0x02)? true: false;
break;
case 0x169: if (RI.INES2_SubMapper ==13 || RI.INES2_SubMapper ==15)
dynamic_cast<CPU::CPU_OneBus*>(CPU::CPU[which])->EncryptionStatus =(Val &1)? false: true;
break;

View file

@ -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)

View file

@ -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);

View file

@ -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,

View file

@ -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
};