// The SuperGrafx has 32K of RAM and a different port configuration to allow // I/O access to VDC1, VDC2, and the VPC. byte ReadMemorySGX(int addr) { if (addr < 0xFFFFF) // read ROM return RomData[addr % RomLength]; if (addr >= 0x1F0000 && addr < 0x1F8000) // read RAM return Ram[addr & 0x7FFF]; if (addr >= 0x1FE000) // hardware page. { if (addr < 0x1FE400) { addr &= 0x1F; if (addr <= 0x07) return VDC1.ReadVDC(addr); if (addr <= 0x0F) return VPC.ReadVPC(addr); if (addr <= 0x17) return VDC2.ReadVDC(addr); return 0xFF; } if (addr < 0x1FE800) { Cpu.PendingCycles--; return VCE.ReadVCE(addr); } if (addr < 0x1FEC00) return IOBuffer; if (addr < 0x1FF000) { IOBuffer = (byte)(Cpu.ReadTimerValue() | (IOBuffer & 0x80)); return IOBuffer; } if (addr >= 0x1FF000 && addr < 0x1FF400) { IOBuffer = ReadInput(); return IOBuffer; } if ((addr & ~1) == 0x1FF400) return IOBuffer; if (addr == 0x1FF402) { IOBuffer = Cpu.IRQControlByte; return IOBuffer; } if (addr == 0x1FF403) { IOBuffer = (byte)(Cpu.ReadIrqStatus() | (IOBuffer & 0xF8)); return IOBuffer; } } Log.Error("MEM", "UNHANDLED READ: {0:X6}", addr); return 0xFF; }
void WriteMemorySGX(int addr, byte value) { if (addr >= 0x1F0000 && addr < 0x1F8000) // write RAM. Ram[addr & 0x7FFF] = value; else if (addr >= 0x1FE000) // hardware page. { if (addr < 0x1FE400) { addr &= 0x1F; if (addr <= 0x07) VDC1.WriteVDC(addr, value); else if (addr <= 0x0F) VPC.WriteVPC(addr, value); else if (addr <= 0x17) VDC2.WriteVDC(addr, value); } else if (addr < 0x1FE800) { Cpu.PendingCycles--; VCE.WriteVCE(addr, value); } else if (addr < 0x1FEC00) { IOBuffer = value; PSG.WritePSG((byte)addr, value, Cpu.TotalExecutedCycles); } else if (addr == 0x1FEC00) { IOBuffer = value; Cpu.WriteTimer(value); } else if (addr == 0x1FEC01) { IOBuffer = value; Cpu.WriteTimerEnable(value); } else if (addr >= 0x1FF000 && addr < 0x1FF400) { IOBuffer = value; WriteInput(value); } else if (addr == 0x1FF402) { IOBuffer = value; Cpu.WriteIrqControl(value); } else if (addr == 0x1FF403) { IOBuffer = value; Cpu.WriteIrqStatus(); } else Log.Error("MEM", "unhandled hardware write [{0:X6}] : {1:X2}", addr, value); } else Log.Error("MEM", "UNHANDLED WRITE: {0:X6}:{1:X2}", addr, value); }
private byte ReadMemoryPopulous(int addr) { if (addr >= 0x80000 && addr < 0x88000) { return(PopulousRAM[addr & 0x7FFF]); } if (addr < 0xFFFFF) // read ROM { return(RomData[addr % RomLength]); } if (addr >= 0x1F0000 && addr < 0x1F8000) // read RAM { return(Ram[addr & 0x1FFF]); } if (addr >= 0x1FE000) // hardware page. { if (addr < 0x1FE400) { return(VDC1.ReadVDC(addr)); } if (addr < 0x1FE800) { Cpu.PendingCycles--; return(VCE.ReadVCE(addr)); } if (addr < 0x1FEC00) { return(IOBuffer); } if (addr < 0x1FF000) { IOBuffer = (byte)(Cpu.ReadTimerValue() | (IOBuffer & 0x80)); return(IOBuffer); } if (addr >= 0x1FF000 && addr < 0x1FF400) { IOBuffer = ReadInput(); return(IOBuffer); } if ((addr & ~1) == 0x1FF400) { return(IOBuffer); } if (addr == 0x1FF402) { IOBuffer = Cpu.IRQControlByte; return(IOBuffer); } if (addr == 0x1FF403) { IOBuffer = (byte)(Cpu.ReadIrqStatus() | (IOBuffer & 0xF8)); return(IOBuffer); } } Log.Error("MEM", "UNHANDLED READ: {0:X6}", addr); return(0xFF); }
public VPC(PCEngine pce, VDC vdc1, VDC vdc2, VCE vce, HuC6280 cpu) { PCE = pce; VDC1 = vdc1; VDC2 = vdc2; VCE = vce; CPU = cpu; // latch initial video buffer FrameBuffer = vdc1.GetVideoBuffer(); FrameWidth = vdc1.BufferWidth; FrameHeight = vdc1.BufferHeight; }
public VDC(PCEngine pce, HuC6280 cpu, VCE vce) { this.pce = pce; this.cpu = cpu; this.vce = vce; RenderBackgroundScanline = RenderBackgroundScanlineUnsafe; Registers[HSR] = 0x00FF; Registers[HDR] = 0x00FF; Registers[VPR] = 0xFFFF; Registers[VCR] = 0xFFFF; ReadBuffer = 0xFFFF; }
public VPC(PCEngine pce, VDC vdc1, VDC vdc2, VCE vce, HuC6280 cpu) { PCE = pce; VDC1 = vdc1; VDC2 = vdc2; VCE = vce; CPU = cpu; // latch initial video buffer FrameBuffer = vdc1.GetVideoBuffer(); FrameWidth = vdc1.BufferWidth; FrameHeight = vdc1.BufferHeight; }
public VDC(PCEngine pce, HuC6280 cpu, VCE vce) { this.pce = pce; this.cpu = cpu; this.vce = vce; RenderBackgroundScanline = RenderBackgroundScanlineUnsafe; Registers[HSR] = 0x00FF; Registers[HDR] = 0x00FF; Registers[VPR] = 0xFFFF; Registers[VCR] = 0xFFFF; ReadBuffer = 0xFFFF; }
byte ReadMemory(int addr) { if (addr < 0xFFFFF) // read ROM { return(RomData[addr % RomLength]); } if (addr >= 0x1F0000 && addr < 0x1F8000) // read RAM { return(Ram[addr & 0x1FFF]); } if (addr >= 0x1FE000) // hardware page. { if (addr < 0x1FE400) { return(VDC1.ReadVDC(addr)); } if (addr < 0x1FE800) { Cpu.PendingCycles--; return(VCE.ReadVCE(addr)); } if (addr < 0x1FEC00) { return(IOBuffer); } if (addr < 0x1FF000) { IOBuffer = (byte)(Cpu.ReadTimerValue() | (IOBuffer & 0x80)); return(IOBuffer); } if (addr >= 0x1FF000 && addr < 0x1FF400) { IOBuffer = ReadInput(); return(IOBuffer); } if ((addr & ~1) == 0x1FF400) { return(IOBuffer); } if (addr == 0x1FF402) { IOBuffer = Cpu.IRQControlByte; return(IOBuffer); } if (addr == 0x1FF403) { IOBuffer = (byte)(Cpu.ReadIrqStatus() | (IOBuffer & 0xF8)); return(IOBuffer); } if (addr >= 0x1FF800) { return(ReadCD(addr)); } } if (addr >= 0x1EE000 && addr <= 0x1EE7FF) // BRAM { if (BramEnabled && BramLocked == false) { return(BRAM[addr & 0x7FF]); } return(0xFF); } //CoreComm.MemoryCallbackSystem.CallRead((uint)addr); Log.Error("MEM", "UNHANDLED READ: {0:X6}", addr); return(0xFF); }
void WriteMemory(int addr, byte value) { if (addr >= 0x1F0000 && addr < 0x1F8000) // write RAM. { Ram[addr & 0x1FFF] = value; } else if (addr >= 0x1FE000) // hardware page. { if (addr < 0x1FE400) { VDC1.WriteVDC(addr, value); } else if (addr < 0x1FE800) { Cpu.PendingCycles--; VCE.WriteVCE(addr, value); } else if (addr < 0x1FEC00) { IOBuffer = value; PSG.WritePSG((byte)addr, value, Cpu.TotalExecutedCycles); } else if (addr == 0x1FEC00) { IOBuffer = value; Cpu.WriteTimer(value); } else if (addr == 0x1FEC01) { IOBuffer = value; Cpu.WriteTimerEnable(value); } else if (addr >= 0x1FF000 && addr < 0x1FF400) { IOBuffer = value; WriteInput(value); } else if (addr == 0x1FF402) { IOBuffer = value; Cpu.WriteIrqControl(value); } else if (addr == 0x1FF403) { IOBuffer = value; Cpu.WriteIrqStatus(); } else if (addr >= 0x1FF800) { WriteCD(addr, value); } else { Log.Error("MEM", "unhandled hardware write [{0:X6}] : {1:X2}", addr, value); } } else if (addr >= 0x1EE000 && addr <= 0x1EE7FF) // BRAM { if (BramEnabled && BramLocked == false) { BRAM[addr & 0x7FF] = value; SaveRamModified = true; } } else { Log.Error("MEM", "UNHANDLED WRITE: {0:X6}:{1:X2}", addr, value); } //CoreComm.MemoryCallbackSystem.CallWrite((uint)addr); }
void Init(GameInfo game, byte[] rom) { Controller = NullController.GetNullController(); Cpu = new HuC6280(CoreComm); VCE = new VCE(); VDC1 = new VDC(this, Cpu, VCE); PSG = new HuC6280PSG(); SCSI = new ScsiCDBus(this, disc); Cpu.Logger = (s) => CoreComm.Tracer.Put(s); if (TurboGrafx) { Ram = new byte[0x2000]; Cpu.ReadMemory21 = ReadMemory; Cpu.WriteMemory21 = WriteMemory; Cpu.WriteVDC = VDC1.WriteVDC; soundProvider = PSG; CDAudio = new CDAudio(null, 0); } else if (SuperGrafx) { VDC2 = new VDC(this, Cpu, VCE); VPC = new VPC(this, VDC1, VDC2, VCE, Cpu); Ram = new byte[0x8000]; Cpu.ReadMemory21 = ReadMemorySGX; Cpu.WriteMemory21 = WriteMemorySGX; Cpu.WriteVDC = VDC1.WriteVDC; soundProvider = PSG; CDAudio = new CDAudio(null, 0); } else if (TurboCD) { Ram = new byte[0x2000]; CDRam = new byte[0x10000]; ADPCM = new ADPCM(this, SCSI); Cpu.ReadMemory21 = ReadMemoryCD; Cpu.WriteMemory21 = WriteMemoryCD; Cpu.WriteVDC = VDC1.WriteVDC; CDAudio = new CDAudio(disc); SetCDAudioCallback(); PSG.MaxVolume = short.MaxValue * 3 / 4; SoundMixer = new SoundMixer(PSG, CDAudio, ADPCM); SoundSynchronizer = new MetaspuSoundProvider(ESynchMethod.ESynchMethod_V); soundProvider = SoundSynchronizer; Cpu.ThinkAction = (cycles) => { SCSI.Think(); ADPCM.Think(cycles); }; } if (rom.Length == 0x60000) { // 384k roms require special loading code. Why ;_; // In memory, 384k roms look like [1st 256k][Then full 384k] RomData = new byte[0xA0000]; var origRom = rom; for (int i = 0; i < 0x40000; i++) RomData[i] = origRom[i]; for (int i = 0; i < 0x60000; i++) RomData[i + 0x40000] = origRom[i]; RomLength = RomData.Length; } else if (rom.Length > 1024 * 1024) { // If the rom is bigger than 1 megabyte, switch to Street Fighter 2 mapper Cpu.ReadMemory21 = ReadMemorySF2; Cpu.WriteMemory21 = WriteMemorySF2; RomData = rom; RomLength = RomData.Length; // user request: current value of the SF2MapperLatch on the tracelogger Cpu.Logger = (s) => CoreComm.Tracer.Put(string.Format("{0:X1}:{1}", SF2MapperLatch, s)); } else { // normal rom. RomData = rom; RomLength = RomData.Length; } if (game["BRAM"] || Type == NecSystemType.TurboCD) { BramEnabled = true; BRAM = new byte[2048]; // pre-format BRAM. damn are we helpful. BRAM[0] = 0x48; BRAM[1] = 0x55; BRAM[2] = 0x42; BRAM[3] = 0x4D; BRAM[4] = 0x00; BRAM[5] = 0x88; BRAM[6] = 0x10; BRAM[7] = 0x80; } if (game["SuperSysCard"]) SuperRam = new byte[0x30000]; if (game["ArcadeCard"]) { ArcadeRam = new byte[0x200000]; ArcadeCard = true; ArcadeCardRewindHack = _settings.ArcadeCardRewindHack; for (int i = 0; i < 4; i++) ArcadePage[i] = new ArcadeCardPage(); } if (game["PopulousSRAM"]) { PopulousRAM = new byte[0x8000]; Cpu.ReadMemory21 = ReadMemoryPopulous; Cpu.WriteMemory21 = WriteMemoryPopulous; } // the gamedb can force sprite limit on, ignoring settings if (game["ForceSpriteLimit"] || game.NotInDatabase) ForceSpriteLimit = true; if (game["CdVol"]) CDAudio.MaxVolume = int.Parse(game.OptionValue("CdVol")); if (game["PsgVol"]) PSG.MaxVolume = int.Parse(game.OptionValue("PsgVol")); if (game["AdpcmVol"]) ADPCM.MaxVolume = int.Parse(game.OptionValue("AdpcmVol")); // the gamedb can also force equalizevolumes on if (TurboCD && (_settings.EqualizeVolume || game["EqualizeVolumes"] || game.NotInDatabase)) SoundMixer.EqualizeVolumes(); // Ok, yes, HBlankPeriod's only purpose is game-specific hax. // 1) At least they're not coded directly into the emulator, but instead data-driven. // 2) The games which have custom HBlankPeriods work without it, the override only // serves to clean up minor gfx anomalies. // 3) There's no point in haxing the timing with incorrect values in an attempt to avoid this. // The proper fix is cycle-accurate/bus-accurate timing. That isn't coming to the C# // version of this core. Let's just acknolwedge that the timing is imperfect and fix // it in the least intrusive and most honest way we can. if (game["HBlankPeriod"]) VDC1.HBlankCycles = game.GetIntValue("HBlankPeriod"); // This is also a hack. Proper multi-res/TV emulation will be a native-code core feature. if (game["MultiResHack"]) VDC1.MultiResHack = game.GetIntValue("MultiResHack"); Cpu.ResetPC(); SetupMemoryDomains(); }
private void SyncState(Serializer ser) { ser.BeginSection("PCEngine"); Cpu.SyncState(ser); VCE.SyncState(ser); VDC1.SyncState(ser, 1); PSG.SyncState(ser); if (SuperGrafx) { VPC.SyncState(ser); VDC2.SyncState(ser, 2); } if (TurboCD) { ADPCM.SyncState(ser); CDAudio.SyncState(ser); SCSI.SyncState(ser); ser.Sync("CDRAM", ref CDRam, false); if (SuperRam != null) { ser.Sync("SuperRAM", ref SuperRam, false); } if (ArcadeCard) { ArcadeCardSyncState(ser); } } ser.Sync("RAM", ref Ram, false); ser.Sync("IOBuffer", ref IOBuffer); ser.Sync("CdIoPorts", ref CdIoPorts, false); ser.Sync("BramLocked", ref BramLocked); ser.Sync("Frame", ref frame); ser.Sync("Lag", ref _lagCount); ser.Sync("IsLag", ref _isLag); if (Cpu.ReadMemory21 == ReadMemorySF2) { ser.Sync("SF2MapperLatch", ref SF2MapperLatch); } if (PopulousRAM != null) { ser.Sync("PopulousRAM", ref PopulousRAM, false); } if (BRAM != null) { ser.Sync("BRAM", ref BRAM, false); } ser.EndSection(); if (ser.IsReader) { SyncAllByteArrayDomains(); } }
void WriteMemoryCD(int addr, byte value) { if (addr >= 0x1F0000 && addr < 0x1F8000) // write RAM. { Ram[addr & 0x1FFF] = value; } else if (addr >= 0x100000 && addr < 0x110000) // write CD-RAM { CDRam[addr & 0xFFFF] = value; } else if (addr >= 0xD0000 && addr < 0x100000 && SuperRam != null) // Super SysCard RAM { SuperRam[addr - 0xD0000] = value; } else if (addr >= 0x1FE000) // hardware page. { if (addr < 0x1FE400) { VDC1.WriteVDC(addr, value); } else if (addr < 0x1FE800) { Cpu.PendingCycles--; VCE.WriteVCE(addr, value); } else if (addr < 0x1FEC00) { IOBuffer = value; PSG.WritePSG((byte)addr, value, Cpu.TotalExecutedCycles); } else if (addr == 0x1FEC00) { IOBuffer = value; Cpu.WriteTimer(value); } else if (addr == 0x1FEC01) { IOBuffer = value; Cpu.WriteTimerEnable(value); } else if (addr >= 0x1FF000 && addr < 0x1FF400) { IOBuffer = value; WriteInput(value); } else if (addr == 0x1FF402) { IOBuffer = value; Cpu.WriteIrqControl(value); } else if (addr == 0x1FF403) { IOBuffer = value; Cpu.WriteIrqStatus(); } else if (addr >= 0x1FF800) { WriteCD(addr, value); } else { Log.Error("MEM", "unhandled hardware write [{0:X6}] : {1:X2}", addr, value); } } else if (addr >= 0x80000 && addr < 0x88000 && ArcadeCard) // Arcade Card { var page = ArcadePage[(addr >> 13) & 3]; ArcadeRam[page.EffectiveAddress] = value; page.Increment(); } else if (addr >= 0x1EE000 && addr <= 0x1EE7FF) // BRAM { if (BramEnabled && BramLocked == false) { BRAM[addr & 0x7FF] = value; SaveRamModified = true; } } else { Log.Error("MEM", "UNHANDLED WRITE: {0:X6}:{1:X2}", addr, value); } }
private void PCETileViewer_Load(object sender, EventArgs e) { vce = emu.VCE; }
private void WriteMemorySF2(int addr, byte value) { if ((addr & 0x1FFC) == 0x1FF0) { // Set SF2 pager. SF2MapperLatch = (byte)(addr & 0x03); if (SF2UpdateCDLMappings) { CDLMappingApplyRange(Cpu.Mappings, "ROM", 0x40, 0x80000, (SF2MapperLatch + 1) * 0x80000); } return; } if (addr >= 0x1F0000 && addr < 0x1F8000) // write RAM. { Ram[addr & 0x1FFF] = value; } else if (addr >= 0x1FE000) // hardware page. { if (addr < 0x1FE400) { VDC1.WriteVDC(addr, value); } else if (addr < 0x1FE800) { Cpu.PendingCycles--; VCE.WriteVCE(addr, value); } else if (addr < 0x1FEC00) { IOBuffer = value; PSG.WritePSG((byte)addr, value, Cpu.TotalExecutedCycles); } else if (addr == 0x1FEC00) { IOBuffer = value; Cpu.WriteTimer(value); } else if (addr == 0x1FEC01) { IOBuffer = value; Cpu.WriteTimerEnable(value); } else if (addr >= 0x1FF000 && addr < 0x1FF400) { IOBuffer = value; WriteInput(value); } else if (addr == 0x1FF402) { IOBuffer = value; Cpu.WriteIrqControl(value); } else if (addr == 0x1FF403) { IOBuffer = value; Cpu.WriteIrqStatus(); } else { Log.Error("MEM", "unhandled hardware write [{0:X6}] : {1:X2}", addr, value); } } else { Log.Error("MEM", "UNHANDLED WRITE: {0:X6}:{1:X2}", addr, value); } }
public void Restart() { if (!(Global.Emulator is PCEngine)) { Close(); return; } emu = (PCEngine)Global.Emulator; vce = emu.VCE; if (emu.SystemId == "SGX") { checkBoxVDC2.Enabled = true; } else { checkBoxVDC2.Enabled = false; checkBoxVDC2.Checked = false; } checkBoxVDC2_CheckedChanged(null, null); }
byte ReadMemoryCD(int addr) { if (addr < 0x80000) // read ROM { return(RomData[addr % RomLength]); } if (addr >= 0x1F0000 && addr < 0x1F8000) // read RAM { return(Ram[addr & 0x1FFF]); } if (addr >= 0x100000 && addr < 0x110000) // read CD RAM { return(CDRam[addr & 0xFFFF]); } if (addr >= 0xD0000 && addr < 0x100000 && SuperRam != null) // Super SysCard RAM { return(SuperRam[addr - 0xD0000]); } if (addr >= 0x1FE000) // hardware page. { if (addr < 0x1FE400) { return(VDC1.ReadVDC(addr)); } if (addr < 0x1FE800) { Cpu.PendingCycles--; return(VCE.ReadVCE(addr)); } if (addr < 0x1FEC00) { return(IOBuffer); } if (addr < 0x1FF000) { IOBuffer = (byte)(Cpu.ReadTimerValue() | (IOBuffer & 0x80)); return(IOBuffer); } if (addr >= 0x1FF000 && addr < 0x1FF400) { IOBuffer = ReadInput(); return(IOBuffer); } if ((addr & ~1) == 0x1FF400) { return(IOBuffer); } if (addr == 0x1FF402) { IOBuffer = Cpu.IRQControlByte; return(IOBuffer); } if (addr == 0x1FF403) { IOBuffer = (byte)(Cpu.ReadIrqStatus() | (IOBuffer & 0xF8)); return(IOBuffer); } if (addr >= 0x1FF800) { return(ReadCD(addr)); } } if (addr >= 0x80000 && addr < 0x88000 && ArcadeCard) { var page = ArcadePage[(addr >> 13) & 3]; byte value = ArcadeRam[page.EffectiveAddress]; page.Increment(); return(value); } if (addr >= 0x1EE000 && addr <= 0x1EE7FF) // BRAM { if (BramEnabled && BramLocked == false) { return(BRAM[addr & 0x7FF]); } return(0xFF); } Log.Error("MEM", "UNHANDLED READ: {0:X6}", addr); return(0xFF); }
private void Init(GameInfo game, byte[] rom) { Cpu = new HuC6280(MemoryCallbacks); VCE = new VCE(); VDC1 = new VDC(this, Cpu, VCE); PSG = new HuC6280PSG(735); SCSI = new ScsiCDBus(this, disc); Cpu.Logger = s => Tracer.Put(s); if (TurboGrafx) { Ram = new byte[0x2000]; Cpu.ReadMemory21 = ReadMemory; Cpu.WriteMemory21 = WriteMemory; Cpu.WriteVDC = VDC1.WriteVDC; _soundProvider = PSG; CDAudio = new CDAudio(null, 0); } else if (SuperGrafx) { VDC2 = new VDC(this, Cpu, VCE); VPC = new VPC(this, VDC1, VDC2, VCE, Cpu); Ram = new byte[0x8000]; Cpu.ReadMemory21 = ReadMemorySGX; Cpu.WriteMemory21 = WriteMemorySGX; Cpu.WriteVDC = VDC1.WriteVDC; _soundProvider = PSG; CDAudio = new CDAudio(null, 0); } else if (TurboCD) { Ram = new byte[0x2000]; CDRam = new byte[0x10000]; ADPCM = new ADPCM(this, SCSI); Cpu.ReadMemory21 = ReadMemoryCD; Cpu.WriteMemory21 = WriteMemoryCD; Cpu.WriteVDC = VDC1.WriteVDC; CDAudio = new CDAudio(disc); SetCDAudioCallback(); PSG.MaxVolume = short.MaxValue * 3 / 4; SoundMixer = new SoundMixer(735, PSG, CDAudio, ADPCM); _soundProvider = SoundMixer; Cpu.ThinkAction = cycles => { SCSI.Think(); ADPCM.Think(cycles); }; } if (rom.Length == 0x60000) { // 384k roms require special loading code. Why ;_; // In memory, 384k roms look like [1st 256k][Then full 384k] RomData = new byte[0xA0000]; var origRom = rom; for (int i = 0; i < 0x40000; i++) { RomData[i] = origRom[i]; } for (int i = 0; i < 0x60000; i++) { RomData[i + 0x40000] = origRom[i]; } RomLength = RomData.Length; } else if (rom.Length > 1024 * 1024) { // If the rom is bigger than 1 megabyte, switch to Street Fighter 2 mapper Cpu.ReadMemory21 = ReadMemorySF2; Cpu.WriteMemory21 = WriteMemorySF2; RomData = rom; RomLength = RomData.Length; // user request: current value of the SF2MapperLatch on the tracelogger Cpu.Logger = s => Tracer.Put(new TraceInfo { Disassembly = $"{SF2MapperLatch:X1}:{s}", RegisterInfo = "" }); } else { // normal rom. RomData = rom; RomLength = RomData.Length; } if (game["BRAM"] || Type == NecSystemType.TurboCD) { BramEnabled = true; BRAM = new byte[2048]; // pre-format BRAM. damn are we helpful. BRAM[0] = 0x48; BRAM[1] = 0x55; BRAM[2] = 0x42; BRAM[3] = 0x4D; BRAM[4] = 0x00; BRAM[5] = 0x88; BRAM[6] = 0x10; BRAM[7] = 0x80; } if (game["SuperSysCard"]) { SuperRam = new byte[0x30000]; } if (game["ArcadeCard"]) { ArcadeRam = new byte[0x200000]; ArcadeCard = true; ArcadeCardRewindHack = Settings.ArcadeCardRewindHack; for (int i = 0; i < 4; i++) { ArcadePage[i] = new ArcadeCardPage(); } } if (game["PopulousSRAM"]) { PopulousRAM = new byte[0x8000]; Cpu.ReadMemory21 = ReadMemoryPopulous; Cpu.WriteMemory21 = WriteMemoryPopulous; } // the gamedb can force sprite limit on, ignoring settings if (game["ForceSpriteLimit"] || game.NotInDatabase) { ForceSpriteLimit = true; } if (game["CdVol"]) { CDAudio.MaxVolume = int.Parse(game.OptionValue("CdVol")); } if (game["PsgVol"]) { PSG.MaxVolume = int.Parse(game.OptionValue("PsgVol")); } if (game["AdpcmVol"]) { ADPCM.MaxVolume = int.Parse(game.OptionValue("AdpcmVol")); } // the gamedb can also force equalizevolumes on if (TurboCD && (Settings.EqualizeVolume || game["EqualizeVolumes"] || game.NotInDatabase)) { SoundMixer.EqualizeVolumes(); } // Ok, yes, HBlankPeriod's only purpose is game-specific hax. // 1) At least they're not coded directly into the emulator, but instead data-driven. // 2) The games which have custom HBlankPeriods work without it, the override only // serves to clean up minor gfx anomalies. // 3) There's no point in haxing the timing with incorrect values in an attempt to avoid this. // The proper fix is cycle-accurate/bus-accurate timing. That isn't coming to the C# // version of this core. Let's just acknolwedge that the timing is imperfect and fix // it in the least intrusive and most honest way we can. if (game["HBlankPeriod"]) { VDC1.HBlankCycles = game.GetIntValue("HBlankPeriod"); } // This is also a hack. Proper multi-res/TV emulation will be a native-code core feature. if (game["MultiResHack"]) { VDC1.MultiResHack = game.GetIntValue("MultiResHack"); } Cpu.ResetPC(); Tracer = new TraceBuffer { Header = Cpu.TraceHeader }; var ser = new BasicServiceProvider(this); ServiceProvider = ser; ser.Register <ITraceable>(Tracer); ser.Register <IDisassemblable>(Cpu); ser.Register <IVideoProvider>((IVideoProvider)VPC ?? VDC1); ser.Register <ISoundProvider>(_soundProvider); ser.Register <IStatable>(new StateSerializer(SyncState)); SetupMemoryDomains(); }
public void Restart() { vce = emu.VCE; if (emu.SystemId == "SGX") { checkBoxVDC2.Enabled = true; } else { checkBoxVDC2.Enabled = false; checkBoxVDC2.Checked = false; } checkBoxVDC2_CheckedChanged(null, null); }