////////////////////////////////////////////////////////////////////////// // 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; } */ memset(reg, 0, 8); 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() { } } }