Exemplo n.º 1
0
		public ColecoVision(CoreComm comm, GameInfo game, byte[] rom, object SyncSettings)
		{
			CoreComm = comm;
			this.SyncSettings = (ColecoSyncSettings)SyncSettings ?? new ColecoSyncSettings();
			bool skipbios = this.SyncSettings.SkipBiosIntro;

			Cpu = new Z80A();
			Cpu.ReadMemory = ReadMemory;
			Cpu.WriteMemory = WriteMemory;
			Cpu.ReadHardware = ReadPort;
			Cpu.WriteHardware = WritePort;

			VDP = new TMS9918A(Cpu);
			PSG = new SN76489();

			// TODO: hack to allow bios-less operation would be nice, no idea if its feasible
			string biosPath = CoreComm.CoreFileProvider.GetFirmwarePath("Coleco", "Bios", true, "Coleco BIOS file is required.");
			BiosRom = File.ReadAllBytes(biosPath);

			// gamedb can overwrite the syncsettings; this is ok
			if (game["NoSkip"])
				skipbios = false;
			LoadRom(rom, skipbios);
			this.game = game;
			SetupMemoryDomains();
		}
Exemplo n.º 2
0
		public Genesis(CoreComm comm, GameInfo game, byte[] rom)
		{
			CoreComm = comm;
			MainCPU = new MC68000();
			SoundCPU = new Z80A();
			YM2612 = new YM2612() { MaxVolume = 23405 };
			PSG = new SN76489() { MaxVolume = 4681 };
			VDP = new GenVDP();
			VDP.DmaReadFrom68000 = ReadWord;
			SoundMixer = new SoundMixer(YM2612, PSG);

			MainCPU.ReadByte = ReadByte;
			MainCPU.ReadWord = ReadWord;
			MainCPU.ReadLong = ReadLong;
			MainCPU.WriteByte = WriteByte;
			MainCPU.WriteWord = WriteWord;
			MainCPU.WriteLong = WriteLong;
			MainCPU.IrqCallback = InterruptCallback;

			// ---------------------- musashi -----------------------
#if MUSASHI
			_vdp = vdpcallback;
			read8 = Read8;
			read16 = Read16;
			read32 = Read32;
			write8 = Write8;
			write16 = Write16;
			write32 = Write32;

			Musashi.RegisterVdpCallback(Marshal.GetFunctionPointerForDelegate(_vdp));
			Musashi.RegisterRead8(Marshal.GetFunctionPointerForDelegate(read8));
			Musashi.RegisterRead16(Marshal.GetFunctionPointerForDelegate(read16));
			Musashi.RegisterRead32(Marshal.GetFunctionPointerForDelegate(read32));
			Musashi.RegisterWrite8(Marshal.GetFunctionPointerForDelegate(write8));
			Musashi.RegisterWrite16(Marshal.GetFunctionPointerForDelegate(write16));
			Musashi.RegisterWrite32(Marshal.GetFunctionPointerForDelegate(write32));
#endif
			// ---------------------- musashi -----------------------

			SoundCPU.ReadMemory = ReadMemoryZ80;
			SoundCPU.WriteMemory = WriteMemoryZ80;
			SoundCPU.WriteHardware = (a, v) => { Console.WriteLine("Z80: Attempt I/O Write {0:X2}:{1:X2}", a, v); };
			SoundCPU.ReadHardware = x => 0xFF;
			SoundCPU.IRQCallback = () => SoundCPU.Interrupt = false;
			Z80Reset = true;
			RomData = new byte[0x400000];
			for (int i = 0; i < rom.Length; i++)
				RomData[i] = rom[i];

			SetupMemoryDomains();
#if MUSASHI
			Musashi.Init();
			Musashi.Reset();
			VDP.GetPC = () => Musashi.PC;
#else
            MainCPU.Reset();
            VDP.GetPC = () => MainCPU.PC;
#endif
			InitializeCartHardware(game);
		}
Exemplo n.º 3
0
		public NES(CoreComm comm, GameInfo game, byte[] rom, object Settings, object SyncSettings)
		{
			byte[] fdsbios = comm.CoreFileProvider.GetFirmware("NES", "Bios_FDS", false);
			if (fdsbios != null && fdsbios.Length == 40976)
			{
				comm.ShowMessage("Your FDS BIOS is a bad dump.  BizHawk will attempt to use it, but no guarantees!  You should find a new one.");
				var tmp = new byte[8192];
				Buffer.BlockCopy(fdsbios, 16 + 8192 * 3, tmp, 0, 8192);
				fdsbios = tmp;
			}

			this.SyncSettings = (NESSyncSettings)SyncSettings ?? new NESSyncSettings();
			this.ControllerSettings = this.SyncSettings.Controls;
			CoreComm = comm;
			CoreComm.CpuTraceAvailable = true;
			BootGodDB.Initialize();
			videoProvider = new MyVideoProvider(this);
			Init(game, rom, fdsbios);
			if (board is FDS)
			{
				CoreComm.UsesDriveLed = true;
				(board as FDS).SetDriveLightCallback((val) => CoreComm.DriveLED = val);
			}
			PutSettings(Settings ?? new NESSettings());
		}
Exemplo n.º 4
0
        public AppleII(CoreComm comm, GameInfo game, byte[] rom, Settings settings)
        {
            GameInfoSet = new List<GameInfo>();

            var ser = new BasicServiceProvider(this);
            ServiceProvider = ser;
            CoreComm = comm;

            _disk1 = rom;
            RomSet.Add(rom);

            _appleIIRom = comm.CoreFileProvider.GetFirmware(
                SystemId, "AppleIIe", true, "The Apple IIe BIOS firmware is required");
            _diskIIRom = comm.CoreFileProvider.GetFirmware(
                SystemId, "DiskII", true, "The DiskII firmware is required");

            _machine = new Machine(_appleIIRom, _diskIIRom);

            _machine.BizInitialize();

            //make a writeable memory stream cloned from the rom.
            //for junk.dsk the .dsk is important because it determines the format from that
            InitDisk();

            //trace logger stuff
            Tracer = new TraceBuffer();
            ser.Register<ITraceable>(Tracer);

            InitSaveStates();
            SetupMemoryDomains();
            PutSettings(settings ?? new Settings());
        }
Exemplo n.º 5
0
		void InitializeSaveRam(GameInfo game)
		{
			if (EepromEnabled)
				return;

			if (game["DisableSaveRam"] || RH_SRamPresent == false)
				return;

			SaveRamEnabled = true;
			SaveRamEveryOtherByte = RH_SRamCode != 0;
			SaveRamStartOffset = RH_SRamStart;
			SaveRamEndOffset = RH_SRamEnd;

			if (game["SaveRamStartOffset"])
				SaveRamStartOffset = game.GetHexValue("SaveRamStartOffset");
			if (game["SaveRamEndOffset"])
				SaveRamEndOffset = game.GetHexValue("SaveRamEndOffset");

			SaveRamLength = (SaveRamEndOffset - SaveRamStartOffset) + 1;

			if (SaveRamEveryOtherByte)
				SaveRamLength = ((SaveRamEndOffset - SaveRamStartOffset) / 2) + 1;

			SaveRAM = new byte[SaveRamLength];

			Console.WriteLine("SaveRAM enabled. Start: ${0:X6} End: ${1:X6} Length: ${2:X} Mode: {3}", SaveRamStartOffset, SaveRamEndOffset, SaveRamLength, RH_SRamInterpretation());
		}
Exemplo n.º 6
0
		public Intellivision(CoreComm comm, GameInfo game, byte[] rom)
		{
			CoreComm = comm;

			Rom = rom;
			Game = game;
			Cart = new Intellicart();
			if (Cart.Parse(Rom) == -1)
			{
				Cart = new Cartridge();
				Cart.Parse(Rom);
			}

			Cpu = new CP1610();
			Cpu.ReadMemory = ReadMemory;
			Cpu.WriteMemory = WriteMemory;
			Cpu.Reset();

			Stic = new STIC();
			Stic.ReadMemory = ReadMemory;
			Stic.WriteMemory = WriteMemory;
			Stic.Reset();

			Psg = new PSG();
			Psg.ReadMemory = ReadMemory;
			Psg.WriteMemory = WriteMemory;

			Connect();

			Cpu.LogData();

			LoadExecutiveRom(CoreComm.CoreFileProvider.GetFirmwarePath("INTV", "EROM", true, "Executive ROM is required."));
			LoadGraphicsRom(CoreComm.CoreFileProvider.GetFirmwarePath("INTV", "GROM", true, "Graphics ROM is required."));
		}
Exemplo n.º 7
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);
		}
Exemplo n.º 8
0
			public void FillPerGameHacks(GameInfo game)
			{
				if (UseDefaultHacks)
				{
					resolution_width = game.GetInt("Jabo_Resolution_Width", -1);
					resolution_height = game.GetInt("Jabo_Resolution_Height", -1);
					clear_mode = (Direct3DClearMode)game.GetInt("Jabo_Clear_Frame", (int)Direct3DClearMode.Default);
				}
			}
Exemplo n.º 9
0
		// framework
		public C64(CoreComm comm, GameInfo game, byte[] rom, string romextension)
		{
			inputFileInfo = new InputFileInfo();
			inputFileInfo.Data = rom;
			inputFileInfo.Extension = romextension;
			CoreComm = comm;
			Init(Region.PAL);
			cyclesPerFrame = board.vic.CyclesPerFrame;
			CoreComm.UsesDriveLed = true;
			SetupMemoryDomains();
			HardReset();
		}
Exemplo n.º 10
0
        // framework
        public C64(CoreComm comm, GameInfo game, byte[] rom, string romextension)
        {
            ServiceProvider = new BasicServiceProvider(this);
            InputCallbacks = new InputCallbackSystem();

            inputFileInfo = new InputFileInfo();
            inputFileInfo.Data = rom;
            inputFileInfo.Extension = romextension;
            CoreComm = comm;
            Init(Region.PAL);
            cyclesPerFrame = board.vic.CyclesPerFrame;
            SetupMemoryDomains();
            HardReset();

            (ServiceProvider as BasicServiceProvider).Register<IVideoProvider>(board.vic);
        }
Exemplo n.º 11
0
		// get mupenapi internal object
		public VideoPluginSettings GetVPS(GameInfo game, int videoSizeX, int videoSizeY)
		{
			var ret = new VideoPluginSettings(VideoPlugin, videoSizeX, videoSizeY);
			IPluginSettings ips = null;
			switch (VideoPlugin)
			{
				// clone so per game hacks don't overwrite our settings object
				case PluginType.Glide: ips = GlidePlugin.Clone(); break;
				case PluginType.GlideMk2: ips = Glide64mk2Plugin.Clone(); break;
				case PluginType.Rice: ips = RicePlugin.Clone(); break;
				case PluginType.Jabo: ips = JaboPlugin.Clone(); break;
			}

			ips.FillPerGameHacks(game);
			ret.Parameters = ips.GetPluginSettings();
			return ret;
		}
Exemplo n.º 12
0
        public static string FilesystemSafeName(GameInfo game)
        {
            var filesystemSafeName = game.Name.Replace("|", "+");
            filesystemSafeName = RemoveInvalidFileSystemChars(filesystemSafeName);

            // zero 22-jul-2012 - i dont think this is used the same way it used to. game.Name shouldnt be a path, so this stuff is illogical.
            // if game.Name is a path, then someone shouldve made it not-a-path already.
            // return Path.Combine(Path.GetDirectoryName(filesystemSafeName), Path.GetFileNameWithoutExtension(filesystemSafeName));

            // adelikat:
            // This hack is to prevent annoying things like Super Mario Bros..bk2
            if (filesystemSafeName.EndsWith("."))
            {
                return filesystemSafeName.Remove(filesystemSafeName.Length - 1, 1);
            }

            return filesystemSafeName;
        }
Exemplo n.º 13
0
		// 21,477,270  Machine clocks / sec
		//  7,159,090  Cpu cycles / sec

		public PCEngine(CoreComm comm, GameInfo game, byte[] rom, object Settings, object syncSettings)
		{
			CoreComm = comm;
			CoreComm.CpuTraceAvailable = true;

			switch (game.System)
			{
				case "PCE":
					systemid = "PCE";
					Type = NecSystemType.TurboGrafx;
					break;
				case "SGX":
					systemid = "SGX";
					Type = NecSystemType.SuperGrafx;
					break;
			}
			this._settings = (PCESettings)Settings ?? new PCESettings();
			_syncSettings = (PCESyncSettings)syncSettings ?? new PCESyncSettings();
			Init(game, rom);
			SetControllerButtons();
		}
Exemplo n.º 14
0
        public Atari7800(CoreComm comm, GameInfo game, byte[] rom, string GameDBfn)
        {
            ServiceProvider = new BasicServiceProvider(this);
            (ServiceProvider as BasicServiceProvider).Register<IVideoProvider>(avProvider);
            InputCallbacks = new InputCallbackSystem();
            CoreComm = comm;
            byte[] highscoreBIOS = comm.CoreFileProvider.GetFirmware("A78", "Bios_HSC", false, "Some functions may not work without the high score BIOS.");
            byte[] pal_bios = comm.CoreFileProvider.GetFirmware("A78", "Bios_PAL", false, "The game will not run if the correct region BIOS is not available.");
            byte[] ntsc_bios = comm.CoreFileProvider.GetFirmware("A78", "Bios_NTSC", false, "The game will not run if the correct region BIOS is not available.");

            if (EMU7800.Win.GameProgramLibrary.EMU7800DB == null)
            {
                EMU7800.Win.GameProgramLibrary.EMU7800DB = new EMU7800.Win.GameProgramLibrary(new StreamReader(GameDBfn));
            }

            if (rom.Length % 1024 == 128)
            {
                Console.WriteLine("Trimming 128 byte .a78 header...");
                byte[] newrom = new byte[rom.Length - 128];
                Buffer.BlockCopy(rom, 128, newrom, 0, newrom.Length);
                rom = newrom;
            }
            GameInfo = EMU7800.Win.GameProgramLibrary.EMU7800DB.TryRecognizeRom(rom);
            CoreComm.RomStatusDetails = GameInfo.ToString();
            Console.WriteLine("Rom Determiniation from 7800DB:");
            Console.WriteLine(GameInfo.ToString());

            this.rom = rom;
            this.game = game;
            this.hsbios = highscoreBIOS;
            this.bios = GameInfo.MachineType == MachineType.A7800PAL ? pal_bios : ntsc_bios;
            _pal = GameInfo.MachineType == MachineType.A7800PAL || GameInfo.MachineType == MachineType.A2600PAL;

            if (bios == null)
            {
                throw new MissingFirmwareException("The BIOS corresponding to the region of the game you loaded is required to run Atari 7800 games.");
            }

            HardReset();
        }
Exemplo n.º 15
0
			/// <summary>
			/// instatiate an emulator core
			/// </summary>
			/// <param name="comm"></param>
			/// <param name="game"></param>
			/// <param name="rom"></param>
			/// <param name="deterministic"></param>
			/// <param name="settings"></param>
			/// <param name="syncsettings"></param>
			/// <returns></returns>
			public IEmulator Create
			(
				CoreComm comm,
				GameInfo game,
				byte[] rom,
				byte[] file,
				bool deterministic,
				object settings,
				object syncsettings
			)
			{
				object[] o = new object[parammap.Count];
				bp(o, "comm", comm);
				bp(o, "game", game);
				bp(o, "rom", rom);
				bp(o, "file", file);
				bp(o, "deterministic", deterministic);
				bp(o, "settings", settings);
				bp(o, "syncsettings", syncsettings);

				return (IEmulator)CTor.Invoke(o);
			}
Exemplo n.º 16
0
		public GambatteLink(CoreComm comm, GameInfo leftinfo, byte[] leftrom, GameInfo rightinfo, byte[] rightrom, object Settings, object SyncSettings, bool deterministic)
		{
			GambatteLinkSettings _Settings = (GambatteLinkSettings)Settings ?? new GambatteLinkSettings();
			GambatteLinkSyncSettings _SyncSettings = (GambatteLinkSyncSettings)SyncSettings ?? new GambatteLinkSyncSettings();

			CoreComm = comm;
			L = new Gameboy(new CoreComm(comm.ShowMessage, comm.Notify), leftinfo, leftrom, _Settings.L, _SyncSettings.L, deterministic);
			R = new Gameboy(new CoreComm(comm.ShowMessage, comm.Notify), rightinfo, rightrom, _Settings.R, _SyncSettings.R, deterministic);

			// connect link cable
			LibGambatte.gambatte_linkstatus(L.GambatteState, 259);
			LibGambatte.gambatte_linkstatus(R.GambatteState, 259);

			L.Controller = LCont;
			R.Controller = RCont;

			comm.VsyncNum = L.CoreComm.VsyncNum;
			comm.VsyncDen = L.CoreComm.VsyncDen;
			comm.RomStatusAnnotation = null;
			comm.RomStatusDetails = "LEFT:\r\n" + L.CoreComm.RomStatusDetails + "RIGHT:\r\n" + R.CoreComm.RomStatusDetails;
			comm.CpuTraceAvailable = false; // TODO
			comm.NominalWidth = L.CoreComm.NominalWidth + R.CoreComm.NominalWidth;
			comm.NominalHeight = L.CoreComm.NominalHeight;

			Frame = 0;
			LagCount = 0;
			IsLagFrame = false;

			blip_left = new BlipBuffer(1024);
			blip_right = new BlipBuffer(1024);
			blip_left.SetRates(2097152 * 2, 44100);
			blip_right.SetRates(2097152 * 2, 44100);

			SetMemoryDomains();

			L.CoreComm.InputCallback = CoreComm.InputCallback;
			R.CoreComm.InputCallback = CoreComm.InputCallback;
		}
Exemplo n.º 17
0
		// framework
		public C64(CoreComm comm, GameInfo game, byte[] rom, string romextension, object settings, object syncSettings)
		{
			PutSyncSettings((C64SyncSettings)syncSettings ?? new C64SyncSettings());
			PutSettings((C64Settings)settings ?? new C64Settings());

			ServiceProvider = new BasicServiceProvider(this);
			InputCallbacks = new InputCallbackSystem();

		    _inputFileInfo = new InputFileInfo
		    {
		        Data = rom,
		        Extension = romextension
		    };

		    CoreComm = comm;
			Init(SyncSettings.VicType, Settings.BorderType, SyncSettings.SidType, SyncSettings.TapeDriveType, SyncSettings.DiskDriveType);
			_cyclesPerFrame = _board.Vic.CyclesPerFrame;
			SetupMemoryDomains(_board.DiskDrive != null);
            _memoryCallbacks = new MemoryCallbackSystem();
			HardReset();

		    switch (SyncSettings.VicType)
		    {
		        case VicType.Ntsc:
                case VicType.Drean:
                case VicType.NtscOld:
                    Region = DisplayType.NTSC;
		            break;
                case VicType.Pal:
                    Region = DisplayType.PAL;
		            break;
		    }

			((BasicServiceProvider) ServiceProvider).Register<IVideoProvider>(_board.Vic);
            ((BasicServiceProvider) ServiceProvider).Register<IDriveLight>(_board.Serial);
        }
Exemplo n.º 18
0
		public Intellivision(CoreComm comm, GameInfo game, byte[] rom)
		{
			ServiceProvider = new BasicServiceProvider(this);
			CoreComm = comm;

			_rom = rom;
			_gameInfo = game;
			_cart = new Intellicart();
			if (_cart.Parse(_rom) == -1)
			{
				_cart = new Cartridge();
				_cart.Parse(_rom);
			}

			_cpu = new CP1610();
			_cpu.ReadMemory = ReadMemory;
			_cpu.WriteMemory = WriteMemory;
			_cpu.Reset();

			_stic = new STIC();
			_stic.ReadMemory = ReadMemory;
			_stic.WriteMemory = WriteMemory;
			_stic.Reset();
			(ServiceProvider as BasicServiceProvider).Register<IVideoProvider>(_stic);

			_psg = new PSG();
			_psg.ReadMemory = ReadMemory;
			_psg.WriteMemory = WriteMemory;

			Connect();

			_cpu.LogData();

			LoadExecutiveRom(CoreComm.CoreFileProvider.GetFirmware("INTV", "EROM", true, "Executive ROM is required."));
			LoadGraphicsRom(CoreComm.CoreFileProvider.GetFirmware("INTV", "GROM", true, "Graphics ROM is required."));
		}
Exemplo n.º 19
0
		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;
			}
		}
Exemplo n.º 20
0
		void InitializeCartHardware(GameInfo game)
		{
			LogCartInfo();
			InitializeEeprom(game);
			InitializeSaveRam(game);
		}
Exemplo n.º 21
0
		public PCEngine(CoreComm comm, GameInfo game, Disc disc, object Settings, object syncSettings)
		{
			CoreComm = comm;
			CoreComm.CpuTraceAvailable = true;
			CoreComm.UsesDriveLed = true;
			systemid = "PCECD";
			Type = NecSystemType.TurboCD;
			this.disc = disc;
			this._settings = (PCESettings)Settings ?? new PCESettings();
			_syncSettings = (PCESyncSettings)syncSettings ?? new PCESyncSettings();

			GameInfo biosInfo;
			byte[] rom = CoreComm.CoreFileProvider.GetFirmwareWithGameInfo("PCECD", "Bios", true, out biosInfo,
				"PCE-CD System Card not found. Please check the BIOS settings in Config->Firmwares.");

			if (biosInfo.Status == RomStatus.BadDump)
			{
				CoreComm.ShowMessage(
					"The PCE-CD System Card you have selected is known to be a bad dump. This may cause problems playing PCE-CD games.\n\n"
					+ "It is recommended that you find a good dump of the system card. Sorry to be the bearer of bad news!");
			}
			else if (biosInfo.NotInDatabase)
			{
				CoreComm.ShowMessage(
					"The PCE-CD System Card you have selected is not recognized in our database. That might mean it's a bad dump, or isn't the correct rom.");
			}
			else if (biosInfo["BIOS"] == false)
			{
				//zeromus says: someone please write a note about how this could possibly happen.
				//it seems like this is a relic of using gameDB for storing whether something is a bios? firmwareDB should be handling it now.
				CoreComm.ShowMessage(
					"The PCE-CD System Card you have selected is not a BIOS image. You may have selected the wrong rom. FYI-Please report this to developers, I don't think this error message should happen.");
			}

			if (biosInfo["SuperSysCard"])
			{
				game.AddOption("SuperSysCard");
			}

			if (game["NeedSuperSysCard"] && game["SuperSysCard"] == false)
			{
				CoreComm.ShowMessage(
					"This game requires a version 3.0 System card and won't run with the system card you've selected. Try selecting a 3.0 System Card in the firmware configuration.");
				throw new Exception();
			}

			game.FirmwareHash = rom.HashSHA1();

			Init(game, rom);
			// the default RomStatusDetails don't do anything with Disc
			CoreComm.RomStatusDetails = string.Format("{0}\r\nDisk partial hash:{1}", game.Name, disc.GetHash());
			SetControllerButtons();
		}
Exemplo n.º 22
0
		public LibsnesCore(GameInfo game, byte[] romData, bool deterministicEmulation, byte[] xmlData, CoreComm comm, object Settings, object SyncSettings)
		{
			CoreComm = comm;
			byte[] sgbRomData = null;
			if (game["SGB"])
			{
				if ((romData[0x143] & 0xc0) == 0xc0)
					throw new CGBNotSupportedException();
				sgbRomData = CoreComm.CoreFileProvider.GetFirmware("SNES", "Rom_SGB", true, "SGB Rom is required for SGB emulation.");
				game.FirmwareHash = sgbRomData.HashSHA1();
			}

			this.Settings = (SnesSettings)Settings ?? new SnesSettings();
			this.SyncSettings = (SnesSyncSettings)SyncSettings ?? new SnesSyncSettings();

			api = new LibsnesApi(GetExePath());
			api.CMD_init();
			api.ReadHook = ReadHook;
			api.ExecHook = ExecHook;
			api.WriteHook = WriteHook;

			ScanlineHookManager = new MyScanlineHookManager(this);

			api.CMD_init();

			api.QUERY_set_video_refresh(snes_video_refresh);
			api.QUERY_set_input_poll(snes_input_poll);
			api.QUERY_set_input_state(snes_input_state);
			api.QUERY_set_input_notify(snes_input_notify);
			api.QUERY_set_path_request(snes_path_request);
			
			scanlineStart_cb = new LibsnesApi.snes_scanlineStart_t(snes_scanlineStart);
			tracecb = new LibsnesApi.snes_trace_t(snes_trace);

			soundcb = new LibsnesApi.snes_audio_sample_t(snes_audio_sample);
			api.QUERY_set_audio_sample(soundcb);

			RefreshPalette();

			// start up audio resampler
			InitAudio();

			//strip header
			if(romData != null)
				if ((romData.Length & 0x7FFF) == 512)
				{
					var newData = new byte[romData.Length - 512];
					Array.Copy(romData, 512, newData, 0, newData.Length);
					romData = newData;
				}

			if (game["SGB"])
			{
				IsSGB = true;
				SystemId = "SNES";
				BoardName = "SGB";

				CurrLoadParams = new LoadParams()
				{
					type = LoadParamType.SuperGameBoy,
					rom_xml = null,
					rom_data = sgbRomData,
					rom_size = (uint)sgbRomData.Length,
					dmg_xml = null,
					dmg_data = romData,
					dmg_size = (uint)romData.Length
				};

				if (!LoadCurrent())
					throw new Exception("snes_load_cartridge_normal() failed");
			}
			else
			{
				//we may need to get some information out of the cart, even during the following bootup/load process
				if (xmlData != null)
				{
					romxml = new System.Xml.XmlDocument();
					romxml.Load(new MemoryStream(xmlData));

					//bsnes wont inspect the xml to load the necessary sfc file.
					//so, we have to do that here and pass it in as the romData :/
					if (romxml["cartridge"] != null && romxml["cartridge"]["rom"] != null)
						romData = File.ReadAllBytes(CoreComm.CoreFileProvider.PathSubfile(romxml["cartridge"]["rom"].Attributes["name"].Value));
					else
						throw new Exception("Could not find rom file specification in xml file. Please check the integrity of your xml file");
				}

				SystemId = "SNES";
				CurrLoadParams = new LoadParams()
				{
					type = LoadParamType.Normal,
					xml_data = xmlData,
					rom_data = romData
				};

				if(!LoadCurrent())
					throw new Exception("snes_load_cartridge_normal() failed");
			}

			if (api.QUERY_get_region() == LibsnesApi.SNES_REGION.NTSC)
			{
				//similar to what aviout reports from snes9x and seems logical from bsnes first principles. bsnes uses that numerator (ntsc master clockrate) for sure.
				CoreComm.VsyncNum = 21477272;
				CoreComm.VsyncDen = 4 * 341 * 262;
			}
			else
			{
				//http://forums.nesdev.com/viewtopic.php?t=5367&start=19
				CoreComm.VsyncNum = 21281370;
				CoreComm.VsyncDen = 4 * 341 * 312;
			}

			CoreComm.CpuTraceAvailable = true;

			api.CMD_power();

			SetupMemoryDomains(romData,sgbRomData);

			DeterministicEmulation = deterministicEmulation;
			if (DeterministicEmulation) // save frame-0 savestate now
			{
				MemoryStream ms = new MemoryStream();
				BinaryWriter bw = new BinaryWriter(ms);
				bw.Write(CoreSaveState());
				bw.Write(true); // framezero, so no controller follows and don't frameadvance on load
				// hack: write fake dummy controller info
				bw.Write(new byte[536]);
				bw.Close();
				savestatebuff = ms.ToArray();
			}
		}
Exemplo n.º 23
0
        public static string GetCheatsPath(GameInfo game)
        {
            var pathEntry = Global.Config.PathEntries[game.System, "Cheats"] ??
                            Global.Config.PathEntries[game.System, "Base"];

            return MakeAbsolutePath(pathEntry.Path, game.System);
        }
Exemplo n.º 24
0
        public static string ScreenshotPrefix(GameInfo game)
        {
            var name = FilesystemSafeName(game);

            var pathEntry = Global.Config.PathEntries[game.System, "Screenshots"] ??
                            Global.Config.PathEntries[game.System, "Base"];

            return Path.Combine(MakeAbsolutePath(pathEntry.Path, game.System), name);
        }
Exemplo n.º 25
0
        public static string SaveStatePrefix(GameInfo game)
        {
            var name = FilesystemSafeName(game);

            // Neshawk and Quicknes have incompatible savestates, store the name to keep them separate
            if (Global.Emulator.SystemId == "NES")
            {
                name += "." + Global.Emulator.Attributes().CoreName;
            }

            // Bsnes profiles have incompatible savestates so save the profile name
            if (Global.Emulator is LibsnesCore)
            {
                name += "." + (Global.Emulator as LibsnesCore).CurrentProfile;
            }

            if (Global.Emulator.SystemId == "GBA")
            {
                name += "." + Global.Emulator.Attributes().CoreName;
            }

            if (Global.MovieSession.Movie.IsActive)
            {
                name += "." + Path.GetFileNameWithoutExtension(Global.MovieSession.Movie.Filename);
            }

            var pathEntry = Global.Config.PathEntries[game.System, "Savestates"] ??
                            Global.Config.PathEntries[game.System, "Base"];

            return Path.Combine(MakeAbsolutePath(pathEntry.Path, game.System), name);
        }
Exemplo n.º 26
0
        public static string SaveRamPath(GameInfo game)
        {
            var name = FilesystemSafeName(game);
            if (Global.MovieSession.Movie.IsActive)
            {
                name += "." + Path.GetFileNameWithoutExtension(Global.MovieSession.Movie.Filename);
            }

            var pathEntry = Global.Config.PathEntries[game.System, "Save RAM"] ??
                            Global.Config.PathEntries[game.System, "Base"];

            return Path.Combine(MakeAbsolutePath(pathEntry.Path, game.System), name) + ".SaveRAM";
        }
Exemplo n.º 27
0
        public static GameInfo GetGameInfo(byte[] romData, string fileName)
        {
            CompactGameInfo cgi;
            var             hash = $"{CRC32.Calculate(romData):X8}";

            if (DB.TryGetValue(hash, out cgi))
            {
                return(new GameInfo(cgi));
            }

            hash = romData.HashMD5();
            if (DB.TryGetValue(hash, out cgi))
            {
                return(new GameInfo(cgi));
            }

            hash = romData.HashSHA1();
            if (DB.TryGetValue(hash, out cgi))
            {
                return(new GameInfo(cgi));
            }

            // rom is not in database. make some best-guesses
            var game = new GameInfo
            {
                Hash          = hash,
                Status        = RomStatus.NotInDatabase,
                NotInDatabase = true
            };

            Console.WriteLine(
                "Game was not in DB. CRC: {0:X8} MD5: {1}",
                CRC32.Calculate(romData),
                System.Security.Cryptography.MD5.Create().ComputeHash(romData).BytesToHexString());

            var ext = Path.GetExtension(fileName)?.ToUpperInvariant();

            switch (ext)
            {
            case ".NES":
            case ".UNF":
            case ".FDS":
                game.System = "NES";
                break;

            case ".SFC":
            case ".SMC":
                game.System = "SNES";
                break;

            case ".GB":
                game.System = "GB";
                break;

            case ".GBC":
                game.System = "GBC";
                break;

            case ".GBA":
                game.System = "GBA";
                break;

            case ".SMS":
                game.System = "SMS";
                break;

            case ".GG":
                game.System = "GG";
                break;

            case ".SG":
                game.System = "SG";
                break;

            case ".GEN":
            case ".MD":
            case ".SMD":
                game.System = "GEN";
                break;

            case ".PSF":
            case ".MINIPSF":
                game.System = "PSX";
                break;

            case ".PCE":
                game.System = "PCE";
                break;

            case ".SGX":
                game.System = "SGX";
                break;

            case ".A26":
                game.System = "A26";
                break;

            case ".A78":
                game.System = "A78";
                break;

            case ".COL":
                game.System = "Coleco";
                break;

            case ".INT":
                game.System = "INTV";
                break;

            case ".PRG":
            case ".D64":
            case ".T64":
            case ".G64":
            case ".CRT":
                game.System = "C64";
                break;

            case ".TZX":
            case ".PZX":
            case ".CSW":
            case ".WAV":
                game.System = "ZXSpectrum";
                break;

            case ".CDT":
                game.System = "AmstradCPC";
                break;

            case ".TAP":
                byte[] head = romData.Take(8).ToArray();
                if (System.Text.Encoding.Default.GetString(head).Contains("C64-TAPE"))
                {
                    game.System = "C64";
                }
                else
                {
                    game.System = "ZXSpectrum";
                }
                break;

            case ".Z64":
            case ".V64":
            case ".N64":
                game.System = "N64";
                break;

            case ".DEBUG":
                game.System = "DEBUG";
                break;

            case ".WS":
            case ".WSC":
                game.System = "WSWAN";
                break;

            case ".LNX":
                game.System = "Lynx";
                break;

            case ".83P":
                game.System = "83P";
                break;

            case ".DSK":
                var dId = new DSKIdentifier(romData);
                game.System = dId.IdentifiedSystem;
                break;

            case ".PO":
            case ".DO":
                game.System = "AppleII";
                break;

            case ".VB":
                game.System = "VB";
                break;

            case ".NGP":
            case ".NGC":
                game.System = "NGP";
                break;

            case ".O2":
                game.System = "O2";
                break;

            case ".UZE":
                game.System = "UZE";
                break;

            case ".32X":
                game.System = "32X";
                game.AddOption("32X", "true");
                break;

            case ".VEC":
                game.System = "VEC";
                game.AddOption("VEC", "true");
                break;

            // refactor to use mame db (output of "mame -listxml" command)
            // there's no good definition for Arcade anymore, so we might limit to coin-based machines?
            case ".ZIP":
                game.System = "Arcade";
                break;
            }

            game.Name = Path.GetFileNameWithoutExtension(fileName)?.Replace('_', ' ');

            // If filename is all-caps, then attempt to proper-case the title.
            if (!string.IsNullOrWhiteSpace(game.Name) && game.Name == game.Name.ToUpperInvariant())
            {
                game.Name = Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(game.Name.ToLower());
            }

            return(game);
        }
Exemplo n.º 28
0
		public XmlGame()
		{
			Assets = new List<KeyValuePair<string, byte[]>>();
			AssetFullPaths = new List<string>();
			GI = new GameInfo();
		}
Exemplo n.º 29
0
		public byte[] GetFirmwareWithGameInfo(string sysID, string firmwareID, bool required, out GameInfo gi, string msg = null)
		{
			string path;
			byte[] ret = GetFirmwareWithPath(sysID, firmwareID, required, msg, out path);
			if (ret != null && path != null)
			{
				gi = Database.GetGameInfo(ret, path);
			}
			else
			{
				gi = null;
			}
			return ret;
		}
Exemplo n.º 30
0
			public void FillPerGameHacks(GameInfo game)
			{
				if (UseDefaultHacks)
				{
					alt_tex_size = game.GetBool("Glide_alt_tex_size", false);
					buff_clear = game.GetBool("Glide_buff_clear", true);
					decrease_fillrect_edge = game.GetBool("Glide_decrease_fillrect_edge", false);
					detect_cpu_write = game.GetBool("Glide_detect_cpu_write", false);
					fb_clear = game.GetBool("Glide_fb_clear", false);
					fb_hires = game.GetBool("Glide_fb_clear", true);
					fb_read_alpha = game.GetBool("Glide_fb_read_alpha", false);
					fb_smart = game.GetBool("Glide_fb_smart", false);
					fillcolor_fix = game.GetBool("Glide_fillcolor_fix", false);
					fog = game.GetBool("Glide_fog", true);
					force_depth_compare = game.GetBool("Glide_force_depth_compare", false);
					force_microcheck = game.GetBool("Glide_force_microcheck", false);
					fb_hires_buf_clear = game.GetBool("Glide_fb_hires_buf_clear", true);
					fb_ignore_aux_copy = game.GetBool("Glide_fb_ignore_aux_copy", false);
					fb_ignore_previous = game.GetBool("Glide_fb_ignore_previous", false);
					increase_primdepth = game.GetBool("Glide_increase_primdepth", false);
					increase_texrect_edge = game.GetBool("Glide_increase_texrect_edge", false);
					fb_optimize_texrect = game.GetBool("Glide_fb_optimize_texrect", true);
					fb_optimize_write = game.GetBool("Glide_fb_optimize_write", false);
					PPL = game.GetBool("Glide_PPL", false);
					soft_depth_compare = game.GetBool("Glide_soft_depth_compare", false);
					use_sts1_only = game.GetBool("Glide_use_sts1_only", false);
					wrap_big_tex = game.GetBool("Glide_wrap_big_tex", false);

					depth_bias = game.GetInt("Glide_depth_bias", 20);
					filtering = game.GetInt("Glide_filtering", 1);
					fix_tex_coord = game.GetInt("Glide_fix_tex_coord", 0);
					lodmode = game.GetInt("Glide_lodmode", 0);

					stipple_mode = game.GetInt("Glide_stipple_mode", 2);
					stipple_pattern = game.GetInt("Glide_stipple_pattern", 1041204192);
					swapmode = game.GetInt("Glide_swapmode", 1);
					enable_hacks_for_game = game.GetInt("Glide_enable_hacks_for_game", 0);
				}
			}
Exemplo n.º 31
0
        public static GameInfo GetGameInfo(byte[] romData, string fileName)
        {
            CompactGameInfo cgi;
            var             hash = string.Format("{0:X8}", CRC32.Calculate(romData));

            if (db.TryGetValue(hash, out cgi))
            {
                return(new GameInfo(cgi));
            }

            hash = romData.HashMD5();
            if (db.TryGetValue(hash, out cgi))
            {
                return(new GameInfo(cgi));
            }

            hash = romData.HashSHA1();
            if (db.TryGetValue(hash, out cgi))
            {
                return(new GameInfo(cgi));
            }

            // rom is not in database. make some best-guesses
            var game = new GameInfo
            {
                Hash          = hash,
                Status        = RomStatus.NotInDatabase,
                NotInDatabase = true
            };

            Console.WriteLine(
                "Game was not in DB. CRC: {0:X8} MD5: {1}",
                CRC32.Calculate(romData),
                System.Security.Cryptography.MD5.Create().ComputeHash(romData).BytesToHexString());

            var ext = Path.GetExtension(fileName).ToUpperInvariant();

            switch (ext)
            {
            case ".NES":
            case ".UNF":
            case ".FDS":
                game.System = "NES";
                break;

            case ".SFC":
            case ".SMC":
                game.System = "SNES";
                break;

            case ".GB":
                game.System = "GB";
                break;

            case ".GBC":
                game.System = "GBC";
                break;

            case ".GBA":
                game.System = "GBA";
                break;

            case ".SMS":
                game.System = "SMS";
                break;

            case ".GG":
                game.System = "GG";
                break;

            case ".SG":
                game.System = "SG";
                break;

            case ".GEN":
            case ".MD":
            case ".SMD":
                game.System = "GEN";
                break;

            case ".PSF":
            case ".MINIPSF":
                game.System = "PSX";
                break;

            case ".PCE":
                game.System = "PCE";
                break;

            case ".SGX":
                game.System = "SGX";
                break;

            case ".A26":
                game.System = "A26";
                break;

            case ".A78":
                game.System = "A78";
                break;

            case ".COL":
                game.System = "Coleco";
                break;

            case ".INT":
                game.System = "INTV";
                break;

            case ".PRG":
            case ".D64":
            case ".T64":
            case ".G64":
            case ".CRT":
            case ".TAP":
                game.System = "C64";
                break;

            case ".Z64":
            case ".V64":
            case ".N64":
                game.System = "N64";
                break;

            case ".DEBUG":
                game.System = "DEBUG";
                break;

            case ".WS":
            case ".WSC":
                game.System = "WSWAN";
                break;

            case ".LNX":
                game.System = "Lynx";
                break;

            case ".83P":
                game.System = "83P";
                break;

            case ".DSK":
            case ".PO":
            case ".DO":
                game.System = "AppleII";
                break;
            }

            game.Name = Path.GetFileNameWithoutExtension(fileName).Replace('_', ' ');

            // If filename is all-caps, then attempt to proper-case the title.
            if (game.Name == game.Name.ToUpperInvariant())
            {
                game.Name = Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(game.Name.ToLower());
            }

            return(game);
        }
Exemplo n.º 32
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();
		}