AxibugEmuOnline/AxibugEmuOnline.Client.Transplant/Assets/VirtualNes.Core/Mapper/Mapper176.cs

236 lines
7.9 KiB
C#

//////////////////////////////////////////////////////////////////////////
// Mapper176 ShuQiYu / HengGe / WaiXing //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using BYTE = System.Byte;
namespace VirtualNes.Core
{
public class Mapper176 : Mapper
{
BYTE reg5000;
BYTE reg5001;
BYTE reg5010;
BYTE reg5011;
BYTE reg5013;
BYTE reg5FF1;
BYTE reg5FF2;
BYTE we_sram;
BYTE SBW, sp_rom;
public Mapper176(NES parent) : base(parent)
{
}
public override void Reset()
{
if (PROM_16K_SIZE > 32)
{
SetPROM_32K_Bank(0, 1, (PROM_8K_SIZE / 2) - 2, (PROM_8K_SIZE / 2) - 1); //For 1M byte Cartridge
}
else
{
SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
}
// SetPROM_32K_Bank( PROM_8K_SIZE-4, PROM_8K_SIZE-3, PROM_8K_SIZE-2, PROM_8K_SIZE-1 );
if (VROM_1K_SIZE != 0) SetVROM_8K_Bank(0);
reg5000 = 0;
reg5001 = 0;
reg5010 = 0;
reg5011 = 0;
reg5013 = 0;
reg5FF1 = 0;
reg5FF2 = 0;
we_sram = 0;
SBW = 0;
sp_rom = 0;
uint crc = nes.rom.GetPROM_CRC();
if (crc == 0x095D8678 //[ES-0122] Shuang Yue Zhuan (C)
|| crc == 0xD5F7AAEF)
{ //[ES-XXXX] Shen Feng Jian (C)
sp_rom = 1;
nes.SetSAVERAM_SIZE(32 * 1024);
}
/*
crc == 0x416C07A1 //[ES-1006] Meng Huan Zhi Xing IV (C) & WXN-梦幻之星 √
crc == 0x94782FBD //[ES-1057] San Guo Zhi - Xiong Ba Tian Xia (C)
crc == 0xF9863ADF //[ES-1066] Xi Chu Ba Wang (C)
crc == 0xB511C04B //[ES-1071] San Xia Wu Yi (C)
crc == 0x1923A8C5 //[ES-1087] Shui Hu Shen Shou (C) & WXN-水浒神兽(fix) √
crc == 0x095D8678 //[ES-0122] Shuang Yue Zhuan (C)
crc == 0x8f6ab5ac //WXN-三国忠烈传 √
crc == 0x99051cb5 //WXN-雄霸天下 √
crc == 0xf29c8186 //WXN-大富翁2-上海大亨 √
crc == 0xc768098b //WXN-三侠五义 √
crc == 0x49f22159 //WXN-超级大富翁 √
crc == 0xf354d847 //WXN-格兰帝亚 √
crc == 0x5ee2ef97 //WXN-帝国时代(fix) √
crc == 0x977d22c3 //WXN-破釜沉舟(fix) √
crc == 0xf1d803f3 //WXN-西楚霸王(fix) √
crc == 0x85dd49b6 //WXN-口袋金(fix) √
crc == 0x97b82f53 //WXN-爆笑三国(fix) √
crc == 0xce2ea530 //WXN-宠物翡翠(fix) √
*/
}
//BYTE Mapper176::ReadLow(WORD addr)
public override byte ReadLow(ushort addr)
{
if (sp_rom == 1)
{
if (addr >= 0x6000)
{
switch (we_sram)
{
case 0xE4:
case 0xEC: return WRAM[(addr & 0x1FFF) + 0x0000];
case 0xE5:
case 0xED: return WRAM[(addr & 0x1FFF) + 0x2000];
case 0xE6:
case 0xEE: return WRAM[(addr & 0x1FFF) + 0x4000];
case 0xE7:
case 0xEF: return WRAM[(addr & 0x1FFF) + 0x6000];
default: return CPU_MEM_BANK[addr >> 13][addr & 0x1FFF];
}
}
}
return base.ReadLow(addr);
}
//void Mapper176::WriteLow(WORD addr, BYTE data)
public override void WriteLow(ushort addr, byte data)
{
// DEBUGOUT("Address=%04X Data=%02X\n", addr&0xFFFF, data&0xFF );
switch (addr)
{
case 0x5000:
reg5000 = data;
break;
case 0x5001: //[ES-1006] Meng Huan Zhi Xing IV (C)
reg5001 = data;
if (SBW != 0) SetPROM_32K_Bank(reg5001);
break;
case 0x5010:
reg5010 = data;
if (reg5010 == 0x24) SBW = 1;
break;
case 0x5011:
reg5011 = (byte)(data >> 1);
if (SBW != 0) SetPROM_32K_Bank(reg5011);
break;
case 0x5013:
reg5013 = data;
break;
case 0x5ff1:
reg5FF1 = (byte)(data >> 1);
SetPROM_32K_Bank(reg5FF1);
break;
case 0x5ff2:
reg5FF2 = data;
SetVROM_8K_Bank(reg5FF2);
break;
}
if (sp_rom == 1)
{
if (addr >= 0x6000)
{
switch (we_sram)
{
case 0xE4: //CPU_MEM_BANK
case 0xEC: //CPU_MEM_BANK
WRAM[(addr & 0x1FFF) + 0x0000] = data;
CPU_MEM_BANK[addr >> 13][addr & 0x1FFF] = data;
break;
case 0xE5: //SRAM
case 0xED: //SRAM
WRAM[(addr & 0x1FFF) + 0x2000] = data;
break;
case 0xE6:
case 0xEE:
WRAM[(addr & 0x1FFF) + 0x4000] = data;
break;
case 0xE7:
case 0xEF:
WRAM[(addr & 0x1FFF) + 0x6000] = data;
break;
default:
CPU_MEM_BANK[addr >> 13][addr & 0x1FFF] = data;
break;
}
}
}
else
{
if (addr >= 0x6000)
{
// if ( we_sram == 0 ){
CPU_MEM_BANK[addr >> 13][addr & 0x1FFF] = data;
// }
}
}
}
//void Mapper176::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
// DEBUGOUT("Address=%04X Data=%02X\n", addr&0xFFFF, data&0xFF );
if (addr == 0xa000)
{
data &= 0x03;
if (data == 0) SetVRAM_Mirror(VRAM_VMIRROR);
else if (data == 1) SetVRAM_Mirror(VRAM_HMIRROR);
else if (data == 2) SetVRAM_Mirror(VRAM_MIRROR4L);
else SetVRAM_Mirror(VRAM_MIRROR4H);
}
if (addr == 0xa001)
{
// we_sram = data & 0x03;
we_sram = data;
}
}
//void Mapper176::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
p[0] = reg5000;
p[1] = reg5001;
p[2] = reg5010;
p[3] = reg5011;
p[4] = reg5013;
p[5] = reg5FF1;
p[6] = reg5FF2;
p[7] = we_sram;
p[8] = SBW;
p[9] = sp_rom;
}
//void Mapper176::LoadState(LPBYTE p)
public override void LoadState(byte[] p)
{
reg5000 = p[0];
reg5001 = p[1];
reg5010 = p[2];
reg5011 = p[3];
reg5013 = p[4];
reg5FF1 = p[5];
reg5FF2 = p[6];
we_sram = p[7];
SBW = p[8];
sp_rom = p[9];
}
public override bool IsStateSave()
{
return true;
}
}
}