Ejemplo n.º 1
0
        // 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;
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        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;
        }
Ejemplo n.º 5
0
        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;
        }
Ejemplo n.º 6
0
		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;
		}
Ejemplo n.º 7
0
        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;
        }
Ejemplo n.º 8
0
        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);
        }
Ejemplo n.º 9
0
        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);
        }
Ejemplo n.º 10
0
		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();
		}
Ejemplo n.º 11
0
        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();
            }
        }
Ejemplo n.º 12
0
        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);
            }
        }
Ejemplo n.º 13
0
		private void PCETileViewer_Load(object sender, EventArgs e)
		{
			vce = emu.VCE;
		}
Ejemplo n.º 14
0
        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);
            }
        }
Ejemplo n.º 15
0
		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);
		}
Ejemplo n.º 16
0
        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);
        }
Ejemplo n.º 17
0
        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();
        }
Ejemplo n.º 18
0
		public void Restart()
		{
			vce = emu.VCE;

			if (emu.SystemId == "SGX")
			{
				checkBoxVDC2.Enabled = true;
			}
			else
			{
				checkBoxVDC2.Enabled = false;
				checkBoxVDC2.Checked = false;
			}
			checkBoxVDC2_CheckedChanged(null, null);
		}