240 lines
5.2 KiB
C#
240 lines
5.2 KiB
C#
//////////////////////////////////////////////////////////////////////////
|
||
// Mapper163 NanJing Games //
|
||
//////////////////////////////////////////////////////////////////////////
|
||
using static VirtualNes.MMU;
|
||
using static VirtualNes.Core.CPU;
|
||
using INT = System.Int32;
|
||
using BYTE = System.Byte;
|
||
using System;
|
||
using Codice.CM.Client.Differences;
|
||
|
||
namespace VirtualNes.Core
|
||
{
|
||
public class Mapper163 : Mapper
|
||
{
|
||
//BYTE strobe;
|
||
//BYTE security;
|
||
//BYTE trigger;
|
||
//BYTE rom_type;
|
||
|
||
//BYTE reg[2];
|
||
BYTE laststrobe, trigger;
|
||
BYTE[] reg = new byte[8];
|
||
public Mapper163(NES parent) : base(parent)
|
||
{
|
||
/*
|
||
reg[1] = 0xFF;
|
||
strobe = 1;
|
||
security = trigger = reg[0] = 0x00;
|
||
rom_type = 0;
|
||
SetPROM_32K_Bank(15);
|
||
|
||
DWORD crc = nes.rom.GetPROM_CRC();
|
||
if( crc == 0xb6a10d5d ) { // Hu Lu Jin Gang (NJ039) (Ch) [dump]
|
||
SetPROM_32K_Bank(0);
|
||
}
|
||
if( crc == 0xf52468e7 ) { // San Guo Wu Shuang - Meng Jiang Zhuan (NJ047) (Ch) [dump]
|
||
rom_type = 1;
|
||
}
|
||
*/
|
||
|
||
MemoryUtility.ZEROMEMORY(reg, reg.Length);
|
||
laststrobe = 1;
|
||
SetPROM_32K_Bank((reg[0] << 4) | (reg[1] & 0xF));
|
||
//SetPROM_32K_Bank(0);
|
||
SetCRAM_8K_Bank(0);
|
||
}
|
||
|
||
//BYTE Mapper163::ReadLow(WORD A)
|
||
public override byte ReadLow(ushort A)
|
||
{
|
||
/*
|
||
if((addr>=0x5000 && addr<0x6000))
|
||
{
|
||
switch (addr & 0x7700)
|
||
{
|
||
case 0x5100:
|
||
return security;
|
||
break;
|
||
case 0x5500:
|
||
if(trigger)
|
||
return security;
|
||
else
|
||
return 0;
|
||
break;
|
||
}
|
||
return 4;
|
||
}
|
||
else if( addr>=0x6000 ) {
|
||
return CPU_MEM_BANK[addr>>13][addr&0x1FFF];
|
||
}
|
||
return Mapper::ReadLow( addr );
|
||
*/
|
||
if ((A < 0x6000) && (A >= 0x5000))
|
||
{
|
||
switch (A & 0x7700)
|
||
{
|
||
case 0x5100: return (byte)(reg[2] | reg[0] | reg[1] | reg[3] ^ 0xff); break;
|
||
case 0x5500:
|
||
if (trigger != 0)
|
||
return (byte)(reg[2] | reg[1]); // Lei Dian Huang Bi Ka Qiu Chuan Shuo (NJ046) may broke other games
|
||
else
|
||
return 0;
|
||
}
|
||
return 4;
|
||
}
|
||
else
|
||
return base.ReadLow(A);
|
||
}
|
||
|
||
//void Mapper163::WriteLow(WORD A, BYTE V)
|
||
public override void WriteLow(ushort A, byte V)
|
||
{
|
||
/*
|
||
if((addr>=0x4020 && addr<0x6000))
|
||
{
|
||
DEBUGOUT("W %.4X %.2X\n",addr,data);
|
||
if(addr==0x5101){
|
||
if(strobe && !data){
|
||
trigger ^= 1;
|
||
// trigger ^= 0xFF;
|
||
}
|
||
strobe = data;
|
||
}else if(addr==0x5100 && data==6){
|
||
SetPROM_32K_Bank(3);
|
||
}
|
||
else{
|
||
switch (addr & 0x7300)
|
||
{
|
||
case 0x5000:
|
||
reg[1]=data;
|
||
SetPROM_32K_Bank( (reg[1] & 0xF) | (reg[0] << 4) );
|
||
if(!(reg[1]&0x80)&&(nes.ppu.GetScanlineNo()<128))
|
||
SetCRAM_8K_Bank(0);
|
||
if(rom_type==1) SetCRAM_8K_Bank(0);
|
||
break;
|
||
case 0x5200:
|
||
reg[0]=data;
|
||
SetPROM_32K_Bank( (reg[1] & 0xF) | (reg[0] << 4) );
|
||
break;
|
||
case 0x5300:
|
||
security=data;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
else if( addr>=0x6000 ) {
|
||
CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data;
|
||
}
|
||
*/
|
||
if ((A < 0x6000) && (A >= 0x5000))
|
||
{
|
||
if (A == 0x5300)
|
||
{
|
||
A = (ushort)(A + 1 - 1);
|
||
}
|
||
|
||
if (A == 0x5101)
|
||
{
|
||
if (laststrobe != 0 && V == 0)
|
||
{
|
||
trigger ^= 1;
|
||
}
|
||
laststrobe = V;
|
||
}
|
||
else if (A == 0x5100 && V == 6) //damn thoose protected games
|
||
SetPROM_32K_Bank(3);
|
||
else
|
||
{
|
||
switch (A & 0x7300)
|
||
{
|
||
case 0x5200: reg[0] = V; SetPROM_32K_Bank((reg[0] << 4) | reg[1] & 0xF); SetCRAM_8K_Bank(0); break;
|
||
case 0x5000: reg[1] = V; SetPROM_32K_Bank((reg[0] << 4) | reg[1] & 0xF); SetCRAM_8K_Bank(0); if ((reg[1] & 0x80) == 0 && (nes.GetScanline() < 128)) SetCRAM_8K_Bank(0); break;
|
||
case 0x5300: reg[2] = V; break;
|
||
case 0x5100: reg[3] = V; SetPROM_32K_Bank((reg[0] << 4) | reg[1] & 0xF); SetCRAM_8K_Bank(0); break;
|
||
}
|
||
}
|
||
}
|
||
//071
|
||
else if ((A & 0xFF00) == 0x4800)
|
||
{
|
||
//512KרÓÃ
|
||
if (PROM_8K_SIZE == 64)
|
||
{
|
||
reg[A & 3] = V;
|
||
if (A == 0x4802)
|
||
SetPROM_32K_Bank(((reg[1] >> 1) & 3) | (reg[2] << 2));
|
||
}
|
||
}
|
||
else
|
||
base.WriteLow(A, V);
|
||
}
|
||
|
||
//void Mapper163::HSync(int scanline)
|
||
public override void HSync(int scanline)
|
||
{
|
||
//sline = scanline;
|
||
/*
|
||
if( (reg[1]&0x80) && nes.ppu.IsDispON() ) {
|
||
if(scanline==127){
|
||
SetCRAM_4K_Bank(0, 1);
|
||
SetCRAM_4K_Bank(4, 1);
|
||
}
|
||
if (rom_type==1){
|
||
if(scanline<127){
|
||
SetCRAM_4K_Bank(0, 0);
|
||
SetCRAM_4K_Bank(4, 0);
|
||
}
|
||
}else{
|
||
if(scanline==239){
|
||
SetCRAM_4K_Bank(0, 0);
|
||
SetCRAM_4K_Bank(4, 0);
|
||
}
|
||
}
|
||
}
|
||
*/
|
||
if ((reg[1] & 0x80) != 0)
|
||
{
|
||
if (scanline == 239)
|
||
{
|
||
SetCRAM_4K_Bank(0, 0);
|
||
SetCRAM_4K_Bank(4, 0);
|
||
}
|
||
else if (scanline == 127)
|
||
{
|
||
SetCRAM_4K_Bank(0, 1);
|
||
SetCRAM_4K_Bank(4, 1);
|
||
}
|
||
}
|
||
}
|
||
|
||
//void Mapper163::SaveState(LPBYTE p)
|
||
public override void SaveState(byte[] p)
|
||
{
|
||
//p[0] = reg[0];
|
||
//p[1] = reg[1];
|
||
for (byte i = 0; i < 8; i++)
|
||
p[i] = reg[i];
|
||
p[8] = laststrobe;
|
||
p[9] = trigger;
|
||
}
|
||
|
||
//void Mapper163::LoadState(LPBYTE p)
|
||
public override void LoadState(byte[] p)
|
||
{
|
||
|
||
//reg[0] = p[0];
|
||
//reg[1] = p[1];
|
||
for (byte i = 0; i < 8; i++)
|
||
reg[i] = p[i];
|
||
laststrobe = p[8];
|
||
trigger = p[9];
|
||
}
|
||
|
||
public override void Reset()
|
||
{
|
||
}
|
||
|
||
}
|
||
}
|