示例#1
0
		// Code

		void InitializeEeprom(GameInfo game)
		{
			if (game["EEPROM"] == false)
				return;

			EepromEnabled = true;
			EepromAddrMask = game.GetHexValue("EEPROM_ADDR_MASK");
			EepromSize = EepromAddrMask + 1;

			var t = game.OptionValue("SDA_IN").Split(':');
			SdaInAddr = int.Parse(t[0], NumberStyles.HexNumber);
			SdaInBit = int.Parse(t[1]);

			t = game.OptionValue("SDA_OUT").Split(':');
			SdaOutAddr = int.Parse(t[0], NumberStyles.HexNumber);
			SdaOutBit = int.Parse(t[1]);

			t = game.OptionValue("SCL").Split(':');
			SclAddr = int.Parse(t[0], NumberStyles.HexNumber);
			SclBit = int.Parse(t[1]);

			SaveRAM = new byte[EepromSize];

			Console.WriteLine("EEPROM enabled. Size: ${0:X} SDA_IN: ${1:X}:{2} SDA_OUT: ${3:X}:{4}, SCL: ${5:X}:{6}",
				EepromSize, SdaInAddr, SdaInBit, SdaOutAddr, SdaOutBit, SclAddr, SclBit);
		}
示例#2
0
文件: Lynx.cs 项目: CadeLaRen/BizHawk
		public Lynx(byte[] file, GameInfo game, CoreComm comm)
		{
			ServiceProvider = new BasicServiceProvider(this);
			CoreComm = comm;

			byte[] bios = CoreComm.CoreFileProvider.GetFirmware("Lynx", "Boot", true, "Boot rom is required");
			if (bios.Length != 512)
				throw new MissingFirmwareException("Lynx Bootrom must be 512 bytes!");

			int pagesize0 = 0;
			int pagesize1 = 0;
			byte[] realfile = null;

			{
				var ms = new MemoryStream(file, false);
				var br = new BinaryReader(ms);
				string header = Encoding.ASCII.GetString(br.ReadBytes(4));
				int p0 = br.ReadUInt16();
				int p1 = br.ReadUInt16();
				int ver = br.ReadUInt16();
				string cname = Encoding.ASCII.GetString(br.ReadBytes(32)).Trim();
				string mname = Encoding.ASCII.GetString(br.ReadBytes(16)).Trim();
				int rot = br.ReadByte();

				ms.Position = 6;
				string bs93 = Encoding.ASCII.GetString(br.ReadBytes(6));
				if (bs93 == "BS93")
					throw new InvalidOperationException("Unsupported BS93 Lynx ram image");

				if (header == "LYNX" && (ver & 255) == 1)
				{
					Console.WriteLine("Processing Handy-Lynx header");
					pagesize0 = p0;
					pagesize1 = p1;
					Console.WriteLine("TODO: Rotate {0}", rot);
					Console.WriteLine("Cart: {0} Manufacturer: {1}", cname, mname);
					realfile = new byte[file.Length - 64];
					Buffer.BlockCopy(file, 64, realfile, 0, realfile.Length);
					Console.WriteLine("Header Listed banking: {0} {1}", p0, p1);
				}
				else
				{
					Console.WriteLine("No Handy-Lynx header found!  Assuming raw rom image.");
					realfile = file;
				}

			}

			if (game.OptionPresent("pagesize0"))
			{
				pagesize0 = int.Parse(game.OptionValue("pagesize0"));
				pagesize1 = int.Parse(game.OptionValue("pagesize1"));
				Console.WriteLine("Loading banking options {0} {1} from gamedb", pagesize0, pagesize1);
			}

			if (pagesize0 == 0 && pagesize1 == 0)
			{
				switch (realfile.Length)
				{
					case 0x10000: pagesize0 = 0x100; break;
					case 0x20000: pagesize0 = 0x200; break; //
					case 0x40000: pagesize0 = 0x400; break; // all known good dumps fall in one of these three categories
					case 0x80000: pagesize0 = 0x800; break; //

					case 0x30000: pagesize0 = 0x200; pagesize1 = 0x100; break;
					case 0x50000: pagesize0 = 0x400; pagesize1 = 0x100; break;
					case 0x60000: pagesize0 = 0x400; pagesize1 = 0x200; break;
					case 0x90000: pagesize0 = 0x800; pagesize1 = 0x100; break;
					case 0xa0000: pagesize0 = 0x800; pagesize1 = 0x200; break;
					case 0xc0000: pagesize0 = 0x800; pagesize1 = 0x400; break;
					case 0x100000: pagesize0 = 0x800; pagesize1 = 0x800; break;
				}
				Console.WriteLine("Auto-guessed banking options {0} {1}", pagesize0, pagesize1);
			}

			Core = LibLynx.Create(realfile, realfile.Length, bios, bios.Length, pagesize0, pagesize1, false);
			try
			{
				CoreComm.VsyncNum = 16000000; // 16.00 mhz refclock
				CoreComm.VsyncDen = 16 * 105 * 159;

				savebuff = new byte[LibLynx.BinStateSize(Core)];
				savebuff2 = new byte[savebuff.Length + 13];

				int rot = game.OptionPresent("rotate") ? int.Parse(game.OptionValue("rotate")) : 0;
				LibLynx.SetRotation(Core, rot);
				if ((rot & 1) != 0)
				{
					BufferWidth = HEIGHT;
					BufferHeight = WIDTH;
				}
				else
				{
					BufferWidth = WIDTH;
					BufferHeight = HEIGHT;
				}
				SetupMemoryDomains();
			}
			catch
			{
				Dispose();
				throw;
			}
		}
示例#3
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();
		}
示例#4
0
文件: N64.cs 项目: ddugovic/RASuite
		/// <summary>
		/// Create mupen64plus Emulator
		/// </summary>
		/// <param name="comm">Core communication object</param>
		/// <param name="game">Game information of game to load</param>
		/// <param name="rom">Rom that should be loaded</param>
		/// <param name="SyncSettings">N64SyncSettings object</param>
		public N64(CoreComm comm, GameInfo game, byte[] rom, object settings, object syncSettings)
		{
			int SaveType = 0;
			if (game.OptionValue("SaveType") == "EEPROM_16K")
			{
				SaveType = 1;
			}

			CoreComm = comm;

			_syncSettings = (N64SyncSettings)syncSettings ?? new N64SyncSettings();
			_settings = (N64Settings)settings ?? new N64Settings();

			byte country_code = rom[0x3E];
			switch (country_code)
			{
				// PAL codes
				case 0x44:
				case 0x46:
				case 0x49:
				case 0x50:
				case 0x53:
				case 0x55:
				case 0x58:
				case 0x59:
					_display_type = DisplayType.PAL;
					break;

				// NTSC codes
				case 0x37:
				case 0x41:
				case 0x45:
				case 0x4a:
				default: // Fallback for unknown codes
					_display_type = DisplayType.NTSC;
					break;
			}
			switch (DisplayType)
			{
				case DisplayType.NTSC:
					comm.VsyncNum = 60000;
					comm.VsyncDen = 1001;
					break;
				default:
					comm.VsyncNum = 50;
					comm.VsyncDen = 1;
					break;
			}

			StartThreadLoop();

			var videosettings = _syncSettings.GetVPS(game, _settings.VideoSizeX, _settings.VideoSizeY);
			var coreType = _syncSettings.Core;

			//zero 19-apr-2014 - added this to solve problem with SDL initialization corrupting the main thread (I think) and breaking subsequent emulators (for example, NES)
			//not sure why this works... if we put the plugin initializations in here, we get deadlocks in some SDL initialization. doesnt make sense to me...
			RunThreadAction(() =>
			{
				api = new mupen64plusApi(this, rom, videosettings, SaveType, (int)coreType);
			});

			// Order is important because the register with the mupen core
			_videoProvider = new N64VideoProvider(api, videosettings);
			_audioProvider = new N64Audio(api);
			_inputProvider = new N64Input(api, comm, this._syncSettings.Controllers);


			string rsp = _syncSettings.Rsp == N64SyncSettings.RspType.Rsp_Hle ?
				"mupen64plus-rsp-hle.dll" :
				"mupen64plus-rsp-z64-hlevideo.dll";

			api.AttachPlugin(mupen64plusApi.m64p_plugin_type.M64PLUGIN_RSP, rsp);

			InitMemoryDomains();
			RefreshMemoryCallbacks();

			api.AsyncExecuteEmulator();
			SetControllerButtons();
		}
示例#5
0
文件: SMS.cs 项目: ddugovic/RASuite
		public SMS(CoreComm comm, GameInfo game, byte[] rom, object settings, object syncSettings)
		{
			Settings = (SMSSettings)settings ?? new SMSSettings();
			SyncSettings = (SMSSyncSettings)syncSettings ?? new SMSSyncSettings();
			CoreComm = comm;

			IsGameGear = game.System == "GG";
			IsSG1000 = game.System == "SG";
		    RomData = rom;
            CoreComm.CpuTraceAvailable = true;
            
            if (RomData.Length % BankSize != 0)
                Array.Resize(ref RomData, ((RomData.Length / BankSize) + 1) * BankSize);
            RomBanks = (byte)(RomData.Length / BankSize);

            DisplayType = DetermineDisplayType(SyncSettings.DisplayType, game.Region);
			if (game["PAL"] && DisplayType != DisplayType.PAL)
			{
				DisplayType = DisplayType.PAL;
				CoreComm.Notify("Display was forced to PAL mode for game compatibility.");
			}
			if (IsGameGear) 
				DisplayType = DisplayType.NTSC; // all game gears run at 60hz/NTSC mode
			CoreComm.VsyncNum = DisplayType == DisplayType.NTSC ? 60 : 50;
			CoreComm.VsyncDen = 1;

			Region = SyncSettings.ConsoleRegion;
			if (Region == "Auto") Region = DetermineRegion(game.Region);

			if (game["Japan"] && Region != "Japan")
			{
				Region = "Japan";
				CoreComm.Notify("Region was forced to Japan for game compatibility.");
			}

            if ((game.NotInDatabase || game["FM"]) && SyncSettings.EnableFM && !IsGameGear)
                HasYM2413 = true;

            if (Controller == null)
                Controller = NullController.GetNullController();

            Cpu = new Z80A();
            Cpu.RegisterSP = 0xDFF0;
            Cpu.ReadHardware = ReadPort;
            Cpu.WriteHardware = WritePort;

            Vdp = new VDP(this, Cpu, IsGameGear ? VdpMode.GameGear : VdpMode.SMS, DisplayType);
            PSG = new SN76489();
            YM2413 = new YM2413();
            SoundMixer = new SoundMixer(YM2413, PSG);
            if (HasYM2413 && game["WhenFMDisablePSG"])
                SoundMixer.DisableSource(PSG);
            ActiveSoundProvider = HasYM2413 ? (ISoundProvider)SoundMixer : PSG;

            SystemRam = new byte[0x2000];

			if (game["CMMapper"])
				InitCodeMastersMapper();
			else if (game["CMMapperWithRam"])
				InitCodeMastersMapperRam();
			else if (game["ExtRam"])
				InitExt2kMapper(int.Parse(game.OptionValue("ExtRam")));
			else if (game["KoreaMapper"])
				InitKoreaMapper();
			else if (game["MSXMapper"])
				InitMSXMapper();
			else if (game["NemesisMapper"])
				InitNemesisMapper();
			else if (game["TerebiOekaki"])
				InitTerebiOekaki();
			else
				InitSegaMapper();

            if (Settings.ForceStereoSeparation && !IsGameGear)
            {
                if (game["StereoByte"])
                {
                    ForceStereoByte = byte.Parse(game.OptionValue("StereoByte"));
                }
				PSG.StereoPanning = ForceStereoByte;
            }

            if (SyncSettings.AllowOverlock && game["OverclockSafe"])
                Vdp.IPeriod = 512;

            if (Settings.SpriteLimit)
                Vdp.SpriteLimit = true;

			if (game["3D"])
				IsGame3D = true;

			if (game["BIOS"])
			{
				Port3E = 0xF7; // Disable cartridge, enable BIOS rom
				InitBiosMapper();
			}
			else if (game.System == "SMS")
			{
				BiosRom = comm.CoreFileProvider.GetFirmware("SMS", Region, false);
				if (BiosRom != null && (game["RequireBios"] || SyncSettings.UseBIOS))
					Port3E = 0xF7;

				if (BiosRom == null && game["RequireBios"])
					CoreComm.Notify("BIOS image not available. This game requires BIOS to function.");
				if (SyncSettings.UseBIOS && BiosRom == null)
					CoreComm.Notify("BIOS was selected, but rom image not available. BIOS not enabled.");
			}

			if (game["SRAM"])
				SaveRAM = new byte[int.Parse(game.OptionValue("SRAM"))];
			else if (game.NotInDatabase)
				SaveRAM = new byte[0x8000];

			SetupMemoryDomains();
		}
示例#6
0
文件: TI83.cs 项目: ddugovic/RASuite
		public TI83(CoreComm comm, GameInfo game, byte[] rom, object Settings)
		{
			PutSettings(Settings ?? new TI83Settings());

			CoreComm = comm;
			cpu.ReadMemory = ReadMemory;
			cpu.WriteMemory = WriteMemory;
			cpu.ReadHardware = ReadHardware;
			cpu.WriteHardware = WriteHardware;
			cpu.IRQCallback = IRQCallback;
			cpu.NMICallback = NMICallback;

			this.rom = rom;
			LinkPort = new Link(this);

			//different calculators (different revisions?) have different initPC. we track this in the game database by rom hash
			//if( *(unsigned long *)(m_pRom + 0x6ce) == 0x04D3163E ) m_Regs.PC.W = 0x6ce; //KNOWN
			//else if( *(unsigned long *)(m_pRom + 0x6f6) == 0x04D3163E ) m_Regs.PC.W = 0x6f6; //UNKNOWN

			if (game["initPC"])
				startPC = ushort.Parse(game.OptionValue("initPC"), NumberStyles.HexNumber);

			HardReset();
			SetupMemoryDomains();
		}