Compare commits
22 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 43a55517d1 | |||
| 81e0023fac | |||
|
|
ca30f4a15a | ||
|
|
eea980be67 | ||
|
|
7f9e9da658 | ||
|
|
f592f73056 | ||
|
|
da2e6d6734 | ||
|
|
a28f9f663f | ||
|
|
72ea065bcc | ||
|
|
1edbe899bb | ||
|
|
12895f0cc9 | ||
|
|
778f9112ea | ||
|
|
44441fe20b | ||
|
|
45e0d330b2 | ||
|
|
c847e29fd5 | ||
|
|
38665207e0 | ||
|
|
003402a361 | ||
|
|
41ae4e61be | ||
|
|
2227785cb5 | ||
|
|
1e7d3e0457 | ||
|
|
c4d5f10b60 | ||
|
|
efe2e7cd3b |
13 changed files with 597 additions and 71 deletions
|
|
@ -38,7 +38,7 @@
|
|||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -285,6 +285,24 @@ void CPU_VT369_Sound::RunCycle (void) {
|
|||
}
|
||||
|
||||
void CPU_VT369_Sound::Reset (void) {
|
||||
MemGet(PC);
|
||||
MemGet(PC);
|
||||
MemGet(0x100 | SP--);
|
||||
MemGet(0x100 | SP--);
|
||||
MemGet(0x100 | SP--);
|
||||
FI = 1;
|
||||
dataBank =0;
|
||||
PCL = MemGet(0x1FFC);
|
||||
PCH = MemGet(0x1FFD);
|
||||
WantTimerIRQ =WantIRQ =WantNMI =0;
|
||||
EnableDMA =FALSE;
|
||||
vt369TimerPeriod =0;
|
||||
vt369TimerControl =0;
|
||||
CycleCount =0;
|
||||
updatePrescaler();
|
||||
}
|
||||
|
||||
void CPU_VT369_Sound::ResetSoft (void) {
|
||||
MemGet(PC);
|
||||
MemGet(PC);
|
||||
MemGet(0x100 | SP--);
|
||||
|
|
@ -518,7 +536,7 @@ void APU_VT369::IntWrite (int bank, int addr, int val) {
|
|||
}
|
||||
break;
|
||||
case 0x162:
|
||||
if (val ==0x0D && !Settings::VT369SoundHLE) CPU::CPU[1]->Reset();
|
||||
if (val == 0x0D && !Settings::VT369SoundHLE) dynamic_cast<CPU::CPU_VT369_Sound*>(CPU::CPU[1])->ResetSoft();
|
||||
break;
|
||||
case 0x169:
|
||||
if (RI.INES2_SubMapper ==13 || RI.INES2_SubMapper ==15)
|
||||
|
|
@ -577,6 +595,11 @@ void APU_VT369::Reset (void) {
|
|||
vt369TimerPeriod =0;
|
||||
vt369TimerControl =0;
|
||||
vt369LastPeriod =0;
|
||||
|
||||
reg4100[0x1C] = 0;
|
||||
reg4100[0x1F] = 0;
|
||||
reg4100[0x62] = 0;
|
||||
|
||||
updatePrescaler();
|
||||
// Default DMA values, to allow NES games to run in VT369 5.37 MHz mode
|
||||
vt369DMARequest.transferLength =256;
|
||||
|
|
@ -811,6 +834,15 @@ void APU_VT369::Run (void) {
|
|||
namespace PPU {
|
||||
void PPU_VT369::Reset (void) {
|
||||
PPU_OneBus::Reset();
|
||||
|
||||
reg2000[0x1C] = 0;
|
||||
reg2000[0x1D] = 0;
|
||||
reg2000[0x1E] = 0;
|
||||
reg2000[0x50] = 0;
|
||||
|
||||
for (int i = 0; i < 0xa; i++)
|
||||
reg2000[0x40 + i] = 0;
|
||||
|
||||
GetGFXPtr();
|
||||
}
|
||||
|
||||
|
|
@ -1054,6 +1086,7 @@ void PPU_VT369::Run (void) {
|
|||
}
|
||||
}
|
||||
|
||||
#define IS36PC_HACK (reg2000[0x50] & 1)
|
||||
void PPU_VT369::RunNoSkipEnhanced (int NumTicks) {
|
||||
register unsigned char TC;
|
||||
register unsigned char *CurTileData;
|
||||
|
|
@ -1116,7 +1149,7 @@ void PPU_VT369::RunNoSkipEnhanced (int NumTicks) {
|
|||
case 192: case 200: case 208: case 216: case 224: case 232: case 240: case 248:
|
||||
case 320: case 328:
|
||||
if (reg4100[0x06] &2) VRAMAddr &=~0xC00; // Idiosyncratic implementation of one-screen mirroring.
|
||||
RenderAddr =0x2000 | VRAMAddr &0xFFF; // Fetch name table byte
|
||||
RenderAddr =0x2000 | ((VRAMAddr &0xFFF) << (IS36PC_HACK ? 1 : 0)); // Fetch name table byte;
|
||||
RenderData[0] =CHRPointer[RenderAddr >>10][RenderAddr &0x3FF];
|
||||
break;
|
||||
case 1: case 9: case 17: case 25: case 33: case 41: case 49: case 57:
|
||||
|
|
@ -1131,8 +1164,14 @@ void PPU_VT369::RunNoSkipEnhanced (int NumTicks) {
|
|||
case 130: case 138: case 146: case 154: case 162: case 170: case 178: case 186:
|
||||
case 194: case 202: case 210: case 218: case 226: case 234: case 242: case 250:
|
||||
case 322: case 330:
|
||||
RenderAddr =0x23C0 | VRAMAddr &0xC00 | VRAMAddr >>4 &0x38 | VRAMAddr >>2 &0x07; // Fetch attribute table byte
|
||||
RenderData[1] =CHRPointer[RenderAddr >>10][RenderAddr &0x3FF] >>(VRAMAddr >>4 &4 | VRAMAddr &2) &3;
|
||||
if (IS36PC_HACK) {
|
||||
RenderAddr =0x2001 | ((VRAMAddr &0xFFF) << 1); // Fetch name table byte;
|
||||
RenderData[1] =CHRPointer[RenderAddr >>10][RenderAddr &0x3FF];
|
||||
}
|
||||
else {
|
||||
RenderAddr =0x23C0 | VRAMAddr &0xC00 | VRAMAddr >>4 &0x38 | VRAMAddr >>2 &0x07; // Fetch attribute table byte
|
||||
RenderData[1] =CHRPointer[RenderAddr >>10][RenderAddr &0x3FF] >>(VRAMAddr >>4 &4 | VRAMAddr &2) &3;
|
||||
}
|
||||
break;
|
||||
case 3: case 11: case 19: case 27: case 35: case 43: case 51: case 59:
|
||||
case 67: case 75: case 83: case 91: case 99: case 107: case 115: case 123:
|
||||
|
|
@ -1810,6 +1849,7 @@ int PPU_VT369::Save (FILE *out) {
|
|||
writeByte(reg2000[0x1D]);
|
||||
writeByte(reg2000[0x1E]);
|
||||
writeByte(reg4100[0x06]);
|
||||
writeByte(reg2000[0x50]);
|
||||
return clen;
|
||||
}
|
||||
|
||||
|
|
@ -1822,6 +1862,7 @@ int PPU_VT369::Load (FILE *in, int version_id) {
|
|||
readByte(reg2000[0x1D]);
|
||||
readByte(reg2000[0x1E]);
|
||||
readByte(reg4100[0x06]);
|
||||
readByte(reg2000[0x50]);
|
||||
return clen;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ public:
|
|||
void ExecOp (void) override;
|
||||
void RunCycle (void) override;
|
||||
void Reset (void) override;
|
||||
void ResetSoft (void);
|
||||
int readReg (int);
|
||||
void writeReg (int, int);
|
||||
void DoTimerIRQ (void);
|
||||
|
|
|
|||
|
|
@ -35,10 +35,10 @@
|
|||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Platform)'=='x64'" Label="Configuration">
|
||||
<PlatformToolset>Windows7.1SDK</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
|
|
|
|||
|
|
@ -35,10 +35,10 @@
|
|||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Platform)'=='x64'" Label="Configuration">
|
||||
<PlatformToolset>Windows7.1SDK</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
|
|
@ -92,6 +92,9 @@
|
|||
<EnableCOMDATFolding Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</EnableCOMDATFolding>
|
||||
<LinkTimeCodeGeneration Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||
</Link>
|
||||
<Link>
|
||||
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Release|x64'">kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\src\Hardware\Hash.cpp" />
|
||||
|
|
|
|||
|
|
@ -35,10 +35,10 @@
|
|||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Platform)'=='x64'" Label="Configuration">
|
||||
<PlatformToolset>Windows7.1SDK</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
|
|
|
|||
|
|
@ -35,10 +35,10 @@
|
|||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Platform)'=='x64'" Label="Configuration">
|
||||
<PlatformToolset>Windows7.1SDK</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -178,8 +178,50 @@ void syncCHR (int AND, int OR) {
|
|||
|
||||
void syncMirror () {
|
||||
switch (HV) {
|
||||
case 0: EMU->Mirror_V(); break;
|
||||
case 1: EMU->Mirror_H(); break;
|
||||
case 0:
|
||||
if ((reg2000[0x50] & 1) && (reg2000[0x1E] & 0x08) && ROM->ConsoleType == CONSOLE_VT369) {
|
||||
// 0x2000-0x27ff
|
||||
EMU->SetCHR_NT1(0x8, 0);
|
||||
EMU->SetCHR_NT1(0x9, 1);
|
||||
|
||||
// 0x2800-0x2fff
|
||||
EMU->SetCHR_NT1(0xA, 2);
|
||||
EMU->SetCHR_NT1(0xB, 3);
|
||||
|
||||
// 0x3000-0x37ff
|
||||
EMU->SetCHR_NT1(0xC, 0);
|
||||
EMU->SetCHR_NT1(0xD, 1);
|
||||
|
||||
// 0x3800-0x38ff
|
||||
EMU->SetCHR_NT1(0xE, 2);
|
||||
EMU->SetCHR_NT1(0xF, 3);
|
||||
}
|
||||
else {
|
||||
EMU->Mirror_V();
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if ((reg2000[0x50] & 1) && (reg2000[0x1E] & 0x08) && ROM->ConsoleType == CONSOLE_VT369) {
|
||||
// 0x2000-0x27ff
|
||||
EMU->SetCHR_NT1(0x8, 0);
|
||||
EMU->SetCHR_NT1(0x9, 1);
|
||||
|
||||
// 0x2800-0x2fff
|
||||
EMU->SetCHR_NT1(0xA, 0);
|
||||
EMU->SetCHR_NT1(0xB, 1);
|
||||
|
||||
// 0x3000-0x37ff
|
||||
EMU->SetCHR_NT1(0xC, 2);
|
||||
EMU->SetCHR_NT1(0xD, 3);
|
||||
|
||||
// 0x3800-0x38ff
|
||||
EMU->SetCHR_NT1(0xE, 2);
|
||||
EMU->SetCHR_NT1(0xF, 3);
|
||||
}
|
||||
else {
|
||||
EMU->Mirror_H();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
|
@ -5,28 +5,85 @@ namespace {
|
|||
class SerialROM: public SerialDevice {
|
||||
int bitPosition;
|
||||
uint8_t command;
|
||||
uint8_t curState;
|
||||
uint8_t lateResponse;
|
||||
const uint8_t* rom;
|
||||
const uint8_t* lateResponseData;
|
||||
public:
|
||||
SerialROM(const uint8_t* _rom):
|
||||
SerialROM(const uint8_t* _rom, const uint8_t* _lateResponse) :
|
||||
bitPosition(0),
|
||||
command(0),
|
||||
rom(_rom) {
|
||||
lateResponse(0),
|
||||
curState(0),
|
||||
rom(_rom),
|
||||
lateResponseData(_lateResponse) {
|
||||
}
|
||||
void setPins(bool select, bool newClock, bool newData) {
|
||||
if (select)
|
||||
state =0;
|
||||
else
|
||||
// EMU->DbgOut(L"Select: %02d, Clock: %02d, Data: %02d", select, newClock, newData);
|
||||
|
||||
if (select) {
|
||||
state = 0;
|
||||
curState = 0;
|
||||
} else if (!select && curState == 0) {
|
||||
curState = 1;
|
||||
}
|
||||
|
||||
if (!clock && newClock) {
|
||||
if (state <8) {
|
||||
command =command <<1 | newData*1;
|
||||
if (state == 7) EMU->DbgOut(L"Command: %02X", command);
|
||||
if (++state ==8 && command !=0x30)
|
||||
state =0;
|
||||
else
|
||||
bitPosition =0;
|
||||
} else {
|
||||
output =rom[bitPosition >>3] >>(7 -(bitPosition &7)) &1? true: false;
|
||||
if (++bitPosition >=256 *8) state =0;
|
||||
switch (curState) {
|
||||
case 1:
|
||||
command = (command << 1) | (newData * 1);
|
||||
if (state == 7)
|
||||
EMU->DbgOut(L"Command: %02X", command);
|
||||
|
||||
if (++state == 8) {
|
||||
switch (command) {
|
||||
case 0x30:
|
||||
bitPosition = 0;
|
||||
curState = 2;
|
||||
break;
|
||||
|
||||
case 0x10:
|
||||
if (lateResponseData != NULL) {
|
||||
state = 0;
|
||||
curState = 3;
|
||||
command = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
state = 0;
|
||||
curState = 255;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
output = rom[bitPosition >> 3] >> (7 - (bitPosition & 7)) & 1 ? true : false;
|
||||
if (++bitPosition >= (256 * 8)) {
|
||||
state = 0;
|
||||
curState = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
command = (command << 1) | (newData * 1);
|
||||
if (state == 7)
|
||||
EMU->DbgOut(L"Late Response Command: %02X", command);
|
||||
|
||||
if (++state == 8) {
|
||||
bitPosition = 0;
|
||||
curState = 4;
|
||||
lateResponse = lateResponseData[command];
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
output = lateResponse >> (7 - (bitPosition & 7)) & 1 ? true : false;
|
||||
if (++bitPosition >= 8) {
|
||||
state = 0;
|
||||
curState = 255;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
clock =newClock;
|
||||
|
|
@ -34,6 +91,42 @@ public:
|
|||
};
|
||||
|
||||
SerialROM* serialROM =NULL;
|
||||
uint8_t latch_4144[4];
|
||||
uint8_t latch_414c[4];
|
||||
uint8_t latch_41e4[4];
|
||||
uint8_t latch_41eb;
|
||||
int lcd_id_offset;
|
||||
int lcd_id_len;
|
||||
uint8_t pcase_resp[16];
|
||||
uint8_t pcase_write_hist[2];
|
||||
|
||||
uint8_t vt3xx_36pcase_gpio_bus_latch()
|
||||
{
|
||||
return (latch_414c[0x3] & 0x1f) | ((latch_41e4[0x03] & 0x1c) << 3);
|
||||
}
|
||||
|
||||
uint8_t vt3xx_36pcase_gpio_bus_r()
|
||||
{
|
||||
if (lcd_id_offset < lcd_id_len)
|
||||
return pcase_resp[lcd_id_offset];
|
||||
|
||||
return vt3xx_36pcase_gpio_bus_latch();
|
||||
}
|
||||
|
||||
void vt3xx_36pcase_gpio_bus_w()
|
||||
{
|
||||
pcase_write_hist[0] = pcase_write_hist[1];
|
||||
pcase_write_hist[1] = vt3xx_36pcase_gpio_bus_latch();
|
||||
|
||||
if ((pcase_write_hist[0] == 0x00) && (pcase_write_hist[1] == 0x00))
|
||||
{
|
||||
// The menu waits for this two-byte response before applying the LCD/GPIO table at f7d6.
|
||||
pcase_resp[0] = 0x93;
|
||||
pcase_resp[1] = 0x35;
|
||||
lcd_id_offset = 0;
|
||||
lcd_id_len = 2;
|
||||
}
|
||||
}
|
||||
|
||||
void sync () {
|
||||
OneBus::syncPRG(0x0FFF, 0);
|
||||
|
|
@ -44,21 +137,110 @@ void sync () {
|
|||
BOOL MAPINT load (void) {
|
||||
iNES_SetSRAM();
|
||||
OneBus::load(sync);
|
||||
if (ROM->MiscROMSize &0x0100) serialROM =new SerialROM(ROM->MiscROMData +ROM->MiscROMSize -0x0100);
|
||||
if (ROM->INES2_SubMapper == 3 && (ROM->MiscROMSize & 0x0200)) {
|
||||
serialROM = new SerialROM(ROM->MiscROMData + ROM->MiscROMSize - 0x0200, ROM->MiscROMData + ROM->MiscROMSize - 0x0100);
|
||||
}
|
||||
else if (ROM->MiscROMSize & 0x0100) {
|
||||
serialROM = new SerialROM(ROM->MiscROMData + ROM->MiscROMSize - 0x0100, NULL);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int MAPINT read4(int bank, int addr) {
|
||||
if (ROM->INES2_SubMapper == 3) {
|
||||
if (addr >= 0x144 && addr < 0x148) {
|
||||
return latch_4144[addr & 3];
|
||||
}
|
||||
else if (addr >= 0x14c && addr < 0x150) {
|
||||
if (addr == 0x14f) {
|
||||
return (latch_414c[addr & 3] & 0xe0) | (vt3xx_36pcase_gpio_bus_r() & 0x1f);
|
||||
}
|
||||
return latch_414c[addr & 3];
|
||||
}
|
||||
else if (addr >= 0x1e4 && addr < 0x1e8) {
|
||||
if (addr == 0x1e7) {
|
||||
return (latch_41e4[addr & 3] & 0xe3) | ((vt3xx_36pcase_gpio_bus_r() >> 3) & 0x1c);
|
||||
}
|
||||
return latch_41e4[addr & 3];
|
||||
}
|
||||
else if (addr == 0x15c) {
|
||||
return 0x10;
|
||||
}
|
||||
}
|
||||
|
||||
return OneBus::readAPU(bank, addr);
|
||||
}
|
||||
|
||||
int MAPINT read4Debug(int bank, int addr) {
|
||||
if (ROM->INES2_SubMapper == 3) {
|
||||
if (addr >= 0x144 && addr < 0x148) {
|
||||
return latch_4144[addr & 3];
|
||||
}
|
||||
else if (addr >= 0x14c && addr < 0x150) {
|
||||
if (addr == 0x14f) {
|
||||
return (latch_414c[addr & 3] & 0xe0) | (vt3xx_36pcase_gpio_bus_r() & 0x1f);
|
||||
}
|
||||
return latch_414c[addr & 3];
|
||||
}
|
||||
else if (addr >= 0x1e4 && addr < 0x1e8) {
|
||||
if (addr == 0x1e7) {
|
||||
return (latch_41e4[addr & 3] & 0xe3) | ((vt3xx_36pcase_gpio_bus_r() >> 3) & 0x1c);
|
||||
}
|
||||
return latch_41e4[addr & 3];
|
||||
}
|
||||
else if (addr == 0x15c) {
|
||||
return 0x10;
|
||||
}
|
||||
}
|
||||
|
||||
return OneBus::readAPUDebug(bank, addr);
|
||||
}
|
||||
|
||||
void MAPINT write4(int bank, int addr, int val) {
|
||||
if (ROM->INES2_SubMapper == 3) {
|
||||
if (addr >= 0x144 && addr < 0x148) {
|
||||
int old = latch_4144[addr & 3];
|
||||
latch_4144[addr & 3] = val;
|
||||
|
||||
if (addr == 0x147 && !(old & 0x20) && (val & 0x20)) {
|
||||
vt3xx_36pcase_gpio_bus_w();
|
||||
}
|
||||
}
|
||||
else if (addr >= 0x14c && addr < 0x150) {
|
||||
latch_414c[addr & 3] = val;
|
||||
}
|
||||
else if (addr >= 0x1e4 && addr < 0x1e8) {
|
||||
latch_41e4[addr & 3] = val;
|
||||
}
|
||||
else if (addr == 0x1eb) {
|
||||
int old = latch_41eb;
|
||||
latch_41eb = val;
|
||||
|
||||
if (!(old & 0x10) && (val & 0x10)) {
|
||||
if (lcd_id_offset < lcd_id_len)
|
||||
lcd_id_offset++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OneBus::writeAPU(bank, addr, val);
|
||||
}
|
||||
|
||||
void MAPINT reset (RESET_TYPE resetType) {
|
||||
OneBus::reset(resetType);
|
||||
if (serialROM) {
|
||||
serialROM->reset();
|
||||
switch(ROM->INES2_SubMapper) {
|
||||
case 0: OneBus::gpio[2].attachSerialDevice({ serialROM, 4, 3, 5 }); break;
|
||||
case 0: case 3: OneBus::gpio[2].attachSerialDevice({ serialROM, 4, 3, 5 }); break;
|
||||
case 1: OneBus::gpio[1].attachSerialDevice({ serialROM, 8, 7, 6 }); break;
|
||||
case 2: OneBus::gpio[5].attachSerialDevice({ serialROM, 0, 0, 4 }); break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
EMU->SetCPUReadHandler(0x4, read4);
|
||||
EMU->SetCPUReadHandlerDebug(0x4, read4Debug);
|
||||
EMU->SetCPUWriteHandler(0x4, write4);
|
||||
}
|
||||
|
||||
void MAPINT unload () {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue