////////////////////////////////////////////////////////////////////////// // Mapper176 ShuQiYu / HengGe / WaiXing // ////////////////////////////////////////////////////////////////////////// using static VirtualNes.MMU; using static VirtualNes.Core.CPU; using INT = System.Int32; using BYTE = System.Byte; using System; 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; } } }