예제 #1
0
파일: PSP.cs 프로젝트: henke37/BizHawk
		public PSP(CoreComm comm, string isopath)
		{
			ServiceProvider = new BasicServiceProvider(this);
			if (attachedcore != null)
			{
				attachedcore.Dispose();
				attachedcore = null;
			}
			CoreComm = comm;

			logcallback = new PPSSPPDll.LogCB(LogCallbackFunc);

			bool good = PPSSPPDll.init(isopath, logcallback);
			LogFlush();
			if (!good)
				throw new Exception("PPSSPP Init failed!");
			vidhandle = GCHandle.Alloc(screenbuffer, GCHandleType.Pinned);
			PPSSPPDll.setvidbuff(vidhandle.AddrOfPinnedObject());

			CoreComm.VsyncDen = 1;
			CoreComm.VsyncNum = 60;
			CoreComm.RomStatusDetails = "It puts the scythe in the chicken or it gets the abyss again!";

			attachedcore = this;
		}
예제 #2
0
파일: PSP.cs 프로젝트: CadeLaRen/BizHawk
        public PSP(CoreComm comm, string isopath)
        {
            ServiceProvider = new BasicServiceProvider(this);
            if (attachedcore != null)
            {
                attachedcore.Dispose();
                attachedcore = null;
            }
            CoreComm = comm;

            glcontext = CoreComm.RequestGLContext(3, 0, true);
            CoreComm.ActivateGLContext(glcontext);

            logcallback = new PPSSPPDll.LogCB(LogCallbackFunc);

            bool good = PPSSPPDll.BizInit(isopath, logcallback);
            LogFlush();
            if (!good)
                throw new Exception("PPSSPP Init failed!");

            CoreComm.VsyncDen = 1;
            CoreComm.VsyncNum = 60;
            CoreComm.RomStatusDetails = "It puts the scythe in the chicken or it gets the abyss again!";

            attachedcore = this;
        }
예제 #3
0
파일: Meteor.cs 프로젝트: rjb8682/BizHawk-1
		public GBA(CoreComm comm, byte[] file)
		{
			ServiceProvider = new BasicServiceProvider(this);
			Tracer = new TraceBuffer
			{
				Header = "   -Addr--- -Opcode- -Instruction------------------- -R0----- -R1----- -R2----- -R3----- -R4----- -R5----- -R6----- -R7----- -R8----- -R9----- -R10---- -R11---- -R12---- -R13(SP) -R14(LR) -R15(PC) -CPSR--- -SPSR---"
			};

			(ServiceProvider as BasicServiceProvider).Register<ITraceable>(Tracer);

			CoreComm = comm;

			comm.VsyncNum = 262144;
			comm.VsyncDen = 4389;
			comm.NominalWidth = 240;
			comm.NominalHeight = 160;

			byte[] bios = CoreComm.CoreFileProvider.GetFirmware("GBA", "Bios", true, "GBA bios file is mandatory.");

			if (bios.Length != 16384)
				throw new InvalidDataException("GBA bios must be exactly 16384 bytes!");
			if (file.Length > 32 * 1024 * 1024)
				throw new InvalidDataException("Rom file is too big!  No GBA game is larger than 32MB");
			Init();
			LibMeteor.libmeteor_hardreset();
			LibMeteor.libmeteor_loadbios(bios, (uint)bios.Length);
			LibMeteor.libmeteor_loadrom(file, (uint)file.Length);

			SetUpMemoryDomains();
		}
예제 #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());
        }
예제 #5
0
        public Snes9x(CoreComm comm, byte[] rom)
        {
            if (!LibSnes9x.debug_init(rom, rom.Length))
                throw new Exception();

            ServiceProvider = new BasicServiceProvider(this);
            CoreComm = comm;
        }
예제 #6
0
파일: C64.cs 프로젝트: cas1993per/bizhawk
        // 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);
        }
예제 #7
0
        public WonderSwan(CoreComm comm, byte[] file, bool deterministic, object Settings, object SyncSettings)
        {
            ServiceProvider = new BasicServiceProvider(this);
            CoreComm = comm;
            _Settings = (Settings)Settings ?? new Settings();
            _SyncSettings = (SyncSettings)SyncSettings ?? new SyncSettings();

            DeterministicEmulation = deterministic; // when true, remember to force the RTC flag!
            Core = BizSwan.bizswan_new();
            if (Core == IntPtr.Zero)
                throw new InvalidOperationException("bizswan_new() returned NULL!");
            try
            {
                var ss = _SyncSettings.GetNativeSettings();
                if (deterministic)
                    ss.userealtime = false;

                bool rotate = false;

                if (!BizSwan.bizswan_load(Core, file, file.Length, ref ss, ref rotate))
                    throw new InvalidOperationException("bizswan_load() returned FALSE!");

                CoreComm.VsyncNum = 3072000; // master CPU clock, also pixel clock
                CoreComm.VsyncDen = (144 + 15) * (224 + 32); // 144 vislines, 15 vblank lines; 224 vispixels, 32 hblank pixels

                InitISaveRam();

                InitVideo(rotate);
                PutSettings(_Settings);
                InitIMemoryDomains();

                InitIStatable();
                InitDebugCallbacks();
            }
            catch
            {
                Dispose();
                throw;
            }
        }
예제 #8
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();
        }
예제 #9
0
        public LibRetroEmulator(CoreComm nextComm, string modulename)
        {
            ServiceProvider = new BasicServiceProvider(this);

            retro_environment_cb = new LibRetro.retro_environment_t(retro_environment);
            retro_video_refresh_cb = new LibRetro.retro_video_refresh_t(retro_video_refresh);
            retro_audio_sample_cb = new LibRetro.retro_audio_sample_t(retro_audio_sample);
            retro_audio_sample_batch_cb = new LibRetro.retro_audio_sample_batch_t(retro_audio_sample_batch);
            retro_input_poll_cb = new LibRetro.retro_input_poll_t(retro_input_poll);
            retro_input_state_cb = new LibRetro.retro_input_state_t(retro_input_state);

            retro = new LibRetro(modulename);
            try
            {
                CoreComm = nextComm;

                LibRetro.retro_system_info sys = new LibRetro.retro_system_info();
                retro.retro_get_system_info(ref sys);

                if (sys.need_fullpath)
                    throw new ArgumentException("This libretro core needs filepaths");
                if (sys.block_extract)
                    throw new ArgumentException("This libretro needs non-blocked extract");

                retro.retro_set_environment(retro_environment_cb);
                retro.retro_init();
                retro.retro_set_video_refresh(retro_video_refresh_cb);
                retro.retro_set_audio_sample(retro_audio_sample_cb);
                retro.retro_set_audio_sample_batch(retro_audio_sample_batch_cb);
                retro.retro_set_input_poll(retro_input_poll_cb);
                retro.retro_set_input_state(retro_input_state_cb);
            }
            catch
            {
                retro.Dispose();
                throw;
            }
        }
예제 #10
0
        public C64(CoreComm comm, IEnumerable<byte[]> roms, object settings, object syncSettings)
        {
            PutSyncSettings((C64SyncSettings)syncSettings ?? new C64SyncSettings());
            PutSettings((C64Settings)settings ?? new C64Settings());

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

            CoreComm = comm;
            Roms = roms;
            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;
            }

            if (_board.Sid != null)
            {
                SyncSoundProvider = DCFilter.AsISyncSoundProvider(_board.Sid, 512);
            }
            DeterministicEmulation = true;

            ((BasicServiceProvider) ServiceProvider).Register<IVideoProvider>(_board.Vic);
            ((BasicServiceProvider) ServiceProvider).Register<IDriveLight>(this);
        }
예제 #11
0
파일: C64.cs 프로젝트: SaxxonPike/BizHawk
		// 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);
        }
예제 #12
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."));
		}
예제 #13
0
        public NES(CoreComm comm, GameInfo game, byte[] rom, object settings, object syncSettings)
        {
            var ser = new BasicServiceProvider(this);

            ServiceProvider = ser;

            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;
            }

            SyncSettings       = (NESSyncSettings)syncSettings ?? new NESSyncSettings();
            ControllerSettings = SyncSettings.Controls;

            BootGodDb.Initialize();
            videoProvider = new MyVideoProvider(this);
            Init(game, rom, fdsBios);
            if (Board is FDS fds)
            {
                DriveLightEnabled = true;
                fds.SetDriveLightCallback(val => DriveLightOn = val);
                // bit of a hack: we don't have a private gamedb for FDS, but the frontend
                // expects this to be set.
                RomStatus = game.Status;
            }
            PutSettings((NESSettings)settings ?? new NESSettings());

            // we need to put this here because the line directly above will overwrite palette intialization anywhere else
            // TODO: What if settings are later loaded?
            if (_isVS)
            {
                PickVSPalette(cart);
            }

            ser.Register <IDisassemblable>(cpu);

            Tracer = new TraceBuffer {
                Header = cpu.TraceHeader
            };
            ser.Register <ITraceable>(Tracer);
            ser.Register <IVideoProvider>(videoProvider);
            ser.Register <ISoundProvider>(this);
            ser.Register <IStatable>(new StateSerializer(SyncState)
            {
                LoadStateCallback = SetupMemoryDomains
            });

            if (Board is BANDAI_FCG_1 bandai)
            {
                var reader = bandai.reader;
                // not all BANDAI FCG 1 boards have a barcode reader
                if (reader != null)
                {
                    ser.Register(reader);
                }
            }
        }
예제 #14
0
파일: Lynx.cs 프로젝트: Asnivor/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
            {
                _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;
            }
        }
예제 #15
0
        public LibsnesCore(GameInfo game, byte[] romData, byte[] xmlData, CoreComm comm, object settings, object syncSettings)
        {
            var ser = new BasicServiceProvider(this);

            ServiceProvider = ser;

            _tracer = new TraceBuffer
            {
                Header = "65816: PC, mnemonic, operands, registers (A, X, Y, S, D, DB, flags (NVMXDIZC), V, H)"
            };

            ser.Register <IDisassemblable>(new W65816_DisassemblerService());

            _game    = game;
            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();
            }

            _settings     = (SnesSettings)settings ?? new SnesSettings();
            _syncSettings = (SnesSyncSettings)syncSettings ?? new SnesSyncSettings();

            // TODO: pass profile here
            Api = new LibsnesApi(CoreComm.CoreFileProvider.DllPath())
            {
                ReadHook      = ReadHook,
                ExecHook      = ExecHook,
                WriteHook     = WriteHook,
                ReadHook_SMP  = ReadHook_SMP,
                ExecHook_SMP  = ExecHook_SMP,
                WriteHook_SMP = WriteHook_SMP,
            };

            ScanlineHookManager = new MyScanlineHookManager(this);

            _controllerDeck = new LibsnesControllerDeck(_syncSettings);
            _controllerDeck.NativeInit(Api);

            Api.CMD_init();

            Api.QUERY_set_path_request(snes_path_request);

            _scanlineStartCb = 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);

            // start up audio resampler
            InitAudio();
            ser.Register <ISoundProvider>(_resampler);

            // strip header
            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";
                ser.Register <IBoardInfo>(new SGBBoardInfo());

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

                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 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"]?["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.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.
                VsyncNumerator   = 21477272;
                VsyncDenominator = 4 * 341 * 262;
            }
            else
            {
                // http://forums.nesdev.com/viewtopic.php?t=5367&start=19
                VsyncNumerator   = 21281370;
                VsyncDenominator = 4 * 341 * 312;
            }

            Api.CMD_power();

            SetupMemoryDomains(romData, sgbRomData);

            if (CurrentProfile == "Compatibility")
            {
                ser.Register <ITraceable>(_tracer);
            }

            Api.QUERY_set_path_request(null);
            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_audio_sample(_soundcb);
            Api.Seal();
            RefreshPalette();
        }
예제 #16
0
        public A7800Hawk(CoreComm comm, byte[] rom, object settings, object syncSettings)
        {
            var ser = new BasicServiceProvider(this);

            maria = new Maria();
            tia   = new TIA();
            m6532 = new M6532();
            pokey = new Pokey();

            cpu = new MOS6502X <CpuLink>(new CpuLink(this));

            maria = new Maria
            {
                ReadMemory = ReadMemory
            };

            _blip.SetRates(1789773, 44100);

            _settings       = (A7800Settings)settings ?? new A7800Settings();
            _syncSettings   = (A7800SyncSettings)syncSettings ?? new A7800SyncSettings();
            _controllerDeck = new A7800HawkControllerDeck(_syncSettings.Port1, _syncSettings.Port2);

            byte[] highscoreBios = comm.CoreFileProvider.GetFirmware("A78", "Bios_HSC", false, "Some functions may not work without the high score BIOS.");
            byte[] palBios       = comm.CoreFileProvider.GetFirmware("A78", "Bios_PAL", false, "The game will not run if the correct region BIOS is not available.");
            byte[] ntscBios      = comm.CoreFileProvider.GetFirmware("A78", "Bios_NTSC", false, "The game will not run if the correct region BIOS is not available.");

            byte[] header    = new byte[128];
            bool   is_header = false;

            if (rom.Length % 1024 == 128)
            {
                Console.WriteLine("128 byte header detected");
                byte[] newrom = new byte[rom.Length - 128];
                is_header = true;
                Buffer.BlockCopy(rom, 0, header, 0, 128);
                Buffer.BlockCopy(rom, 128, newrom, 0, newrom.Length);
                rom = newrom;
            }

            _isPAL = false;

            // look up hash in gamedb to see what mapper to use
            // if none found default is zero
            // also check for PAL region
            string hash_md5 = null;

            s_mapper = null;
            hash_md5 = "md5:" + rom.HashMD5(0, rom.Length);

            var gi = Database.CheckDatabase(hash_md5);

            if (gi != null)
            {
                var dict = gi.GetOptionsDict();
                if (dict.ContainsKey("PAL"))
                {
                    _isPAL = true;
                }
                if (dict.ContainsKey("board"))
                {
                    s_mapper = dict["board"];
                }
                else
                {
                    throw new Exception("No Board selected for this game");
                }

                // check if the game uses pokey or RAM
                if (dict.ContainsKey("RAM"))
                {
                    int.TryParse(dict["RAM"], out cart_RAM);
                    Console.WriteLine(cart_RAM);
                }

                if (dict.ContainsKey("Pokey"))
                {
                    bool.TryParse(dict["Pokey"], out is_pokey);
                }

                // some games will not function with the high score bios
                // if such a game is being played, tell the user and disable it
                if (dict.ContainsKey("No_HS"))
                {
                    bool.TryParse(dict["No_HS"], out var no_hs);

                    if (no_hs)
                    {
                        Console.WriteLine("This game is incompatible with the High Score BIOS, disabling it");
                        highscoreBios = null;
                    }
                }
            }
            else if (is_header)
            {
                Console.WriteLine("ROM not in DB, inferring mapper info from header");

                byte cart_1 = header[0x35];
                byte cart_2 = header[0x36];

                _isPAL = (header[0x39] > 0);

                if (cart_2.Bit(1))
                {
                    if (cart_2.Bit(3))
                    {
                        s_mapper = "2";
                    }
                    else
                    {
                        s_mapper = "1";
                    }

                    if (cart_2.Bit(2))
                    {
                        cart_RAM = 8;
                    }
                }
                else
                {
                    s_mapper = "0";
                }

                if (cart_2.Bit(0))
                {
                    is_pokey = true;
                }
            }
            else
            {
                throw new Exception("ROM not in gamedb and has no header");
            }

            // some games that use the Super Game mapper only have 4 banks, so let's set a flag to limit bank size
            if (rom.Length < 0x14000)
            {
                small_flag = true;

                // additionally, PAL Karateka  has bank 6 (actually 2) at 0x4000
                if (rom.HashMD5() == "5E0A1E832BBCEA6FACB832FDE23A440A")
                {
                    PAL_Kara = true;
                }
            }

            _rom = rom;

            Reset_Mapper(s_mapper);

            _hsbios = highscoreBios;
            _bios   = _isPAL ? palBios : ntscBios;

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

            // set up palette and frame rate
            if (_isPAL)
            {
                _frameHz       = 50;
                _screen_width  = 320;
                _screen_height = 313;
                _vblanklines   = 20;
                maria._palette = PALPalette;
            }
            else
            {
                _frameHz       = 60;
                _screen_width  = 320;
                _screen_height = 263;
                _vblanklines   = 20;
                maria._palette = NTSCPalette;
            }

            maria.Core = this;
            m6532.Core = this;
            tia.Core   = this;
            pokey.Core = this;

            ser.Register <IVideoProvider>(this);
            ser.Register <ISoundProvider>(this);
            ServiceProvider = ser;

            _tracer = new TraceBuffer {
                Header = cpu.TraceHeader
            };
            ser.Register <ITraceable>(_tracer);
            ser.Register <IStatable>(new StateSerializer(SyncState));
            SetupMemoryDomains();
            ser.Register <IDisassemblable>(cpu);
            HardReset();
        }
예제 #17
0
        public GPGX(CoreComm comm, byte[] rom, DiscSystem.Disc CD, object Settings, object SyncSettings)
        {
            ServiceProvider = new BasicServiceProvider(this);
            // this can influence some things internally (autodetect romtype, etc)
            string romextension = "GEN";

            // three or six button?
            // http://www.sega-16.com/forum/showthread.php?4398-Forgotten-Worlds-giving-you-GAME-OVER-immediately-Fix-inside&highlight=forgotten%20worlds

            //hack, don't use
            if (rom != null && rom.Length > 32 * 1024 * 1024)
            {
                throw new InvalidOperationException("ROM too big!  Did you try to load a CD as a ROM?");
            }

            try
            {
                Elf = new ElfRunner(Path.Combine(comm.CoreFileProvider.DllPath(), "gpgx.elf"), 8 * 1024 * 1024, 36 * 1024 * 1024, 4 * 1024 * 1024);
                if (Elf.ShouldMonitor)
                {
                    Core = BizInvoker.GetInvoker <LibGPGX>(Elf, Elf);
                }
                else
                {
                    Core = BizInvoker.GetInvoker <LibGPGX>(Elf);
                }

                _syncSettings = (GPGXSyncSettings)SyncSettings ?? new GPGXSyncSettings();
                _settings     = (GPGXSettings)Settings ?? new GPGXSettings();

                CoreComm = comm;

                LoadCallback = new LibGPGX.load_archive_cb(load_archive);

                this.romfile = rom;
                this.CD      = CD;
                if (CD != null)
                {
                    this.DiscSectorReader = new DiscSystem.DiscSectorReader(CD);
                    cd_callback_handle    = new LibGPGX.cd_read_cb(CDRead);
                    Core.gpgx_set_cdd_callback(cd_callback_handle);
                }

                LibGPGX.INPUT_SYSTEM system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_NONE;
                LibGPGX.INPUT_SYSTEM system_b = LibGPGX.INPUT_SYSTEM.SYSTEM_NONE;

                switch (_syncSettings.ControlType)
                {
                case ControlType.None:
                default:
                    break;

                case ControlType.Activator:
                    system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_ACTIVATOR;
                    system_b = LibGPGX.INPUT_SYSTEM.SYSTEM_ACTIVATOR;
                    break;

                case ControlType.Normal:
                    system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_MD_GAMEPAD;
                    system_b = LibGPGX.INPUT_SYSTEM.SYSTEM_MD_GAMEPAD;
                    break;

                case ControlType.OnePlayer:
                    system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_MD_GAMEPAD;
                    break;

                case ControlType.Xea1p:
                    system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_XE_A1P;
                    break;

                case ControlType.Teamplayer:
                    system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_TEAMPLAYER;
                    system_b = LibGPGX.INPUT_SYSTEM.SYSTEM_TEAMPLAYER;
                    break;

                case ControlType.Wayplay:
                    system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_WAYPLAY;
                    system_b = LibGPGX.INPUT_SYSTEM.SYSTEM_WAYPLAY;
                    break;

                case ControlType.Mouse:
                    system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_MD_GAMEPAD;
                    // seems like mouse in port 1 would be supported, but not both at the same time
                    system_b = LibGPGX.INPUT_SYSTEM.SYSTEM_MOUSE;
                    break;
                }


                if (!Core.gpgx_init(romextension, LoadCallback, _syncSettings.UseSixButton, system_a, system_b, _syncSettings.Region, _settings.GetNativeSettings()))
                {
                    throw new Exception("gpgx_init() failed");
                }

                {
                    int fpsnum = 60;
                    int fpsden = 1;
                    Core.gpgx_get_fps(ref fpsnum, ref fpsden);
                    CoreComm.VsyncNum = fpsnum;
                    CoreComm.VsyncDen = fpsden;
                    Region            = CoreComm.VsyncRate > 55 ? DisplayType.NTSC : DisplayType.PAL;
                }

                // compute state size
                InitStateBuffers();

                SetControllerDefinition();

                // pull the default video size from the core
                UpdateVideoInitial();

                SetMemoryDomains();

                InputCallback = new LibGPGX.input_cb(input_callback);
                Core.gpgx_set_input_callback(InputCallback);

                if (CD != null)
                {
                    DriveLightEnabled = true;
                }

                // process the non-init settings now
                PutSettings(_settings);

                //TODO - this hits performance, we need to make it controllable
                CDCallback = new LibGPGX.CDCallback(CDCallbackProc);

                InitMemCallbacks();
                KillMemCallbacks();

                Tracer = new GPGXTraceBuffer(this, MemoryDomains, this);
                (ServiceProvider as BasicServiceProvider).Register <ITraceable>(Tracer);

                Elf.Seal();
            }
            catch
            {
                Dispose();
                throw;
            }
        }
예제 #18
0
        public SMS(CoreComm comm, GameInfo game, byte[] rom, SmsSettings settings, SmsSyncSettings syncSettings)
        {
            var ser = new BasicServiceProvider(this);

            ServiceProvider = ser;
            Settings        = (SmsSettings)settings ?? new SmsSettings();
            SyncSettings    = (SmsSyncSettings)syncSettings ?? new SmsSyncSettings();

            IsGameGear   = game.System == "GG";
            IsGameGear_C = game.System == "GG";
            IsSG1000     = game.System == "SG";
            RomData      = rom;

            if (RomData.Length % BankSize != 0)
            {
                Array.Resize(ref RomData, ((RomData.Length / BankSize) + 1) * BankSize);
            }

            RomBanks = (byte)(RomData.Length / BankSize);

            Region = DetermineDisplayType(SyncSettings.DisplayType, game.Region);
            if (game["PAL"] && Region != DisplayType.PAL)
            {
                Region = DisplayType.PAL;
                comm.Notify("Display was forced to PAL mode for game compatibility.");
            }

            if (IsGameGear)
            {
                Region = DisplayType.NTSC;                 // all game gears run at 60hz/NTSC mode
            }

            _region = SyncSettings.ConsoleRegion;
            if (_region == SmsSyncSettings.Regions.Auto)
            {
                _region = DetermineRegion(game.Region);
            }

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

            if (game["Korea"] && _region != SmsSyncSettings.Regions.Korea)
            {
                _region = SmsSyncSettings.Regions.Korea;
                comm.Notify("Region was forced to Korea for game compatibility.");
            }

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

            Cpu = new Z80A
            {
                ReadHardware    = ReadPort,
                WriteHardware   = WritePort,
                FetchMemory     = FetchMemory,
                ReadMemory      = ReadMemory,
                WriteMemory     = WriteMemory,
                MemoryCallbacks = MemoryCallbacks,
                OnExecFetch     = OnExecMemory
            };

            if (game["GG_in_SMS"])
            {
                // skip setting the BIOS because this is a game gear game that puts the system
                // in SMS compatibility mode (it will fail the check sum if played on an actual SMS though.)
                IsGameGear   = false;
                IsGameGear_C = true;
                game.System  = "GG";
                Console.WriteLine("Using SMS Compatibility mode for Game Gear System");
            }

            Vdp = new VDP(this, Cpu, IsGameGear ? VdpMode.GameGear : VdpMode.SMS, Region);
            ser.Register <IVideoProvider>(Vdp);
            PSG    = new SN76489sms();
            YM2413 = new YM2413();
            //SoundMixer = new SoundMixer(YM2413, PSG);
            if (HasYM2413 && game["WhenFMDisablePSG"])
            {
                disablePSG = true;
            }

            BlipL.SetRates(3579545, 44100);
            BlipR.SetRates(3579545, 44100);

            ser.Register <ISoundProvider>(this);

            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 if (game["EEPROM"])
            {
                InitEEPROMMapper();
            }
            else
            {
                InitSegaMapper();
            }

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

                PSG.Set_Panning(ForceStereoByte);
            }

            if (SyncSettings.AllowOverClock && 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" && !game["GG_in_SMS"])
            {
                BiosRom = comm.CoreFileProvider.GetFirmware("SMS", _region.ToString(), false);

                if (BiosRom == null)
                {
                    throw new MissingFirmwareException("No BIOS found");
                }

                if (!game["RequireBios"] && !SyncSettings.UseBios)
                {
                    // we are skipping the BIOS
                    // but only if it won't break the game
                }
                else
                {
                    Port3E = 0xF7;
                }
            }

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

            SetupMemoryDomains();

            //this manages the linkage between the cpu and mapper callbacks so it needs running before bootup is complete
            ((ICodeDataLogger)this).SetCDL(null);

            Tracer = new TraceBuffer {
                Header = Cpu.TraceHeader
            };

            ser.Register(Tracer);
            ser.Register <IDisassemblable>(Cpu);
            ser.Register <IStatable>(new StateSerializer(SyncState));
            Vdp.ProcessOverscan();

            Cpu.ReadMemory  = ReadMemory;
            Cpu.WriteMemory = WriteMemory;

            // Z80 SP initialization
            // stops a few SMS and GG games from crashing
            Cpu.Regs[Cpu.SPl] = 0xF0;
            Cpu.Regs[Cpu.SPh] = 0xDF;

            if (!IsSG1000)
            {
                ser.Register <ISmsGpuView>(new SmsGpuView(Vdp));
            }
        }
예제 #19
0
        public Gameboy(CoreComm comm, GameInfo game, byte[] file, GambatteSettings settings, GambatteSyncSettings syncSettings, bool deterministic)
        {
            var ser = new BasicServiceProvider(this);

            ser.Register <IDisassemblable>(_disassembler);
            ServiceProvider = ser;
            const string TRACE_HEADER = "LR35902: PC, opcode, registers (A, F, B, C, D, E, H, L, LY, SP, CY)";

            Tracer = new TraceBuffer(TRACE_HEADER);
            ser.Register <ITraceable>(Tracer);
            InitMemoryCallbacks();

            ThrowExceptionForBadRom(file);
            BoardName = MapperName(file);

            DeterministicEmulation = deterministic;

            GambatteState = LibGambatte.gambatte_create();

            if (GambatteState == IntPtr.Zero)
            {
                throw new InvalidOperationException($"{nameof(LibGambatte.gambatte_create)}() returned null???");
            }

            Console.WriteLine(game.System);

            try
            {
                _syncSettings = syncSettings ?? new GambatteSyncSettings();

                LibGambatte.LoadFlags flags = LibGambatte.LoadFlags.READONLY_SAV;

                switch (_syncSettings.ConsoleMode)
                {
                case GambatteSyncSettings.ConsoleModeType.GB:
                    break;

                case GambatteSyncSettings.ConsoleModeType.GBC:
                    flags |= LibGambatte.LoadFlags.CGB_MODE;
                    break;

                case GambatteSyncSettings.ConsoleModeType.GBA:
                    flags |= LibGambatte.LoadFlags.CGB_MODE | LibGambatte.LoadFlags.GBA_FLAG;
                    break;

                default:
                    if (game.System == VSystemID.Raw.GBC)
                    {
                        flags |= LibGambatte.LoadFlags.CGB_MODE;
                    }
                    break;
                }

                if (game.System == VSystemID.Raw.SGB)
                {
                    flags &= ~(LibGambatte.LoadFlags.CGB_MODE | LibGambatte.LoadFlags.GBA_FLAG);
                    flags |= LibGambatte.LoadFlags.SGB_MODE;
                    IsSgb  = true;
                }

                if (_syncSettings.MulticartCompat)
                {
                    flags |= LibGambatte.LoadFlags.MULTICART_COMPAT;
                }

                IsCgb = (flags & LibGambatte.LoadFlags.CGB_MODE) == LibGambatte.LoadFlags.CGB_MODE;
                if (_syncSettings.EnableBIOS)
                {
                    FirmwareID fwid = new(
                        IsCgb ? "GBC" : "GB",
                        IsSgb
                                                        ? "SGB2"
                                                        : _syncSettings.ConsoleMode is GambatteSyncSettings.ConsoleModeType.GBA
                                                                ? "AGB"
                                                                : "World");
                    var bios = comm.CoreFileProvider.GetFirmwareOrThrow(fwid, "BIOS Not Found, Cannot Load.  Change SyncSettings to run without BIOS.");                     // https://github.com/TASEmulators/BizHawk/issues/2832 tho
                    if (LibGambatte.gambatte_loadbiosbuf(GambatteState, bios, (uint)bios.Length) != 0)
                    {
                        throw new InvalidOperationException($"{nameof(LibGambatte.gambatte_loadbiosbuf)}() returned non-zero (bios error)");
                    }
                }
                else
                {
                    if (DeterministicEmulation)                     // throw a warning if a movie is being recorded with the bios disabled
                    {
                        comm.ShowMessage("Detected disabled BIOS during movie recording. It is recommended to use a BIOS for movie recording. Change Sync Settings to run with a BIOS.");
                    }
                    flags |= LibGambatte.LoadFlags.NO_BIOS;
                }

                if (LibGambatte.gambatte_loadbuf(GambatteState, file, (uint)file.Length, flags) != 0)
                {
                    throw new InvalidOperationException($"{nameof(LibGambatte.gambatte_loadbuf)}() returned non-zero (is this not a gb or gbc rom?)");
                }

                if (IsSgb)
                {
                    ResetStallTicks = 128 * (2 << 14);
                }
                else if (_syncSettings.EnableBIOS && (_syncSettings.ConsoleMode is GambatteSyncSettings.ConsoleModeType.GBA))
                {
                    ResetStallTicks = 485808;                     // GBA takes 971616 cycles to switch to CGB mode; CGB CPU is inactive during this time.
                }
                else
                {
                    ResetStallTicks = 0;
                }

                // set real default colors (before anyone mucks with them at all)
                PutSettings((GambatteSettings)settings ?? new GambatteSettings());

                InitSound();

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

                InputCallback = new LibGambatte.InputGetter(ControllerCallback);

                LibGambatte.gambatte_setinputgetter(GambatteState, InputCallback);

                InitMemoryDomains();

                RomDetails = $"{game.Name}\r\n{SHA1Checksum.ComputePrefixedHex(file)}\r\n{MD5Checksum.ComputePrefixedHex(file)}\r\n";

                byte[] buff = new byte[32];
                LibGambatte.gambatte_romtitle(GambatteState, buff);
                string romname = System.Text.Encoding.ASCII.GetString(buff);
                Console.WriteLine("Core reported rom name: {0}", romname);

                if (!_syncSettings.EnableBIOS && IsCgb && IsCGBDMGMode())                 // without a bios, we need to set the palette for cgbdmg ourselves
                {
                    int[] cgbDmgColors = new int[] { 0xFFFFFF, 0x7BFF31, 0x0063C5, 0x000000, 0xFFFFFF, 0xFF8484, 0x943A3A, 0x000000, 0xFFFFFF, 0xFF8484, 0x943A3A, 0x000000 };
                    if (file[0x14B] == 0x01 || (file[0x14B] == 0x33 && file[0x144] == '0' && file[0x145] == '1'))                     // Nintendo licencees get special palettes
                    {
                        cgbDmgColors = ColorsFromTitleHash(file);
                    }
                    ChangeDMGColors(cgbDmgColors);
                }

                if (!DeterministicEmulation && _syncSettings.RealTimeRTC)
                {
                    LibGambatte.gambatte_settimemode(GambatteState, false);
                }

                if (DeterministicEmulation)
                {
                    int[] rtcRegs = new int[11];
                    rtcRegs[(int)LibGambatte.RtcRegIndices.Dh] = 0;
                    if (_syncSettings.InternalRTCOverflow)
                    {
                        rtcRegs[(int)LibGambatte.RtcRegIndices.Dh] |= 0x80;
                    }
                    if (_syncSettings.InternalRTCHalt)
                    {
                        rtcRegs[(int)LibGambatte.RtcRegIndices.Dh] |= 0x40;
                    }
                    rtcRegs[(int)LibGambatte.RtcRegIndices.Dh]  |= _syncSettings.InternalRTCDays >> 8;
                    rtcRegs[(int)LibGambatte.RtcRegIndices.Dl]   = _syncSettings.InternalRTCDays & 0xFF;
                    rtcRegs[(int)LibGambatte.RtcRegIndices.H]    = (_syncSettings.InternalRTCHours < 0) ? (_syncSettings.InternalRTCHours + 0x20) : _syncSettings.InternalRTCHours;
                    rtcRegs[(int)LibGambatte.RtcRegIndices.M]    = (_syncSettings.InternalRTCMinutes < 0) ? (_syncSettings.InternalRTCMinutes + 0x40) : _syncSettings.InternalRTCMinutes;
                    rtcRegs[(int)LibGambatte.RtcRegIndices.S]    = (_syncSettings.InternalRTCSeconds < 0) ? (_syncSettings.InternalRTCSeconds + 0x40) : _syncSettings.InternalRTCSeconds;
                    rtcRegs[(int)LibGambatte.RtcRegIndices.C]    = _syncSettings.InternalRTCCycles;
                    rtcRegs[(int)LibGambatte.RtcRegIndices.Dh_L] = 0;
                    if (_syncSettings.LatchedRTCOverflow)
                    {
                        rtcRegs[(int)LibGambatte.RtcRegIndices.Dh_L] |= 0x80;
                    }
                    if (_syncSettings.LatchedRTCHalt)
                    {
                        rtcRegs[(int)LibGambatte.RtcRegIndices.Dh_L] |= 0x40;
                    }
                    rtcRegs[(int)LibGambatte.RtcRegIndices.Dh_L] |= _syncSettings.LatchedRTCDays >> 8;
                    rtcRegs[(int)LibGambatte.RtcRegIndices.Dl_L]  = _syncSettings.LatchedRTCDays & 0xFF;
                    rtcRegs[(int)LibGambatte.RtcRegIndices.H_L]   = _syncSettings.LatchedRTCHours;
                    rtcRegs[(int)LibGambatte.RtcRegIndices.M_L]   = _syncSettings.LatchedRTCMinutes;
                    rtcRegs[(int)LibGambatte.RtcRegIndices.S_L]   = _syncSettings.LatchedRTCSeconds;
                    LibGambatte.gambatte_setrtcregs(GambatteState, rtcRegs);
                }

                LibGambatte.gambatte_setrtcdivisoroffset(GambatteState, _syncSettings.RTCDivisorOffset);

                LibGambatte.gambatte_setcartbuspulluptime(GambatteState, (uint)_syncSettings.CartBusPullUpTime);

                _cdCallback = new LibGambatte.CDCallback(CDCallbackProc);

                ControllerDefinition = CreateControllerDefinition(IsSgb, _syncSettings.FrameLength is GambatteSyncSettings.FrameLengthType.UserDefinedFrames);

                NewSaveCoreSetBuff();
            }
            catch
            {
                Dispose();
                throw;
            }
        }
예제 #20
0
        public O2Hawk(CoreComm comm, GameInfo game, byte[] rom, /*string gameDbFn,*/ object settings, object syncSettings)
        {
            var ser = new BasicServiceProvider(this);

            cpu = new I8048
            {
                ReadMemory      = ReadMemory,
                WriteMemory     = WriteMemory,
                PeekMemory      = PeekMemory,
                DummyReadMemory = ReadMemory,
                ReadPort        = ReadPort,
                WritePort       = WritePort,
                OnExecFetch     = ExecFetch,
            };

            serialport = new SerialPort();

            _settings       = (O2Settings)settings ?? new O2Settings();
            _syncSettings   = (O2SyncSettings)syncSettings ?? new O2SyncSettings();
            _controllerDeck = new O2HawkControllerDeck("O2 Controller", "O2 Controller");

            byte[] Bios = null;

            Bios = comm.CoreFileProvider.GetFirmware("O2", "BIOS", true, "BIOS Not Found, Cannot Load");
            ppu  = new PPU();

            if (Bios == null)
            {
                throw new MissingFirmwareException("Missing Odyssey2 Bios");
            }

            _bios = Bios;

            Buffer.BlockCopy(rom, 0x100, header, 0, 0x50);

            Console.WriteLine("MD5: " + rom.HashMD5(0, rom.Length));
            Console.WriteLine("SHA1: " + rom.HashSHA1(0, rom.Length));
            _rom = rom;
            Setup_Mapper();

            _frameHz = 60;

            ppu.Core        = this;
            cpu.Core        = this;
            serialport.Core = this;

            ser.Register <IVideoProvider>(this);
            ser.Register <ISoundProvider>(ppu);
            ServiceProvider = ser;

            _settings     = (O2Settings)settings ?? new O2Settings();
            _syncSettings = (O2SyncSettings)syncSettings ?? new O2SyncSettings();

            _tracer = new TraceBuffer {
                Header = cpu.TraceHeader
            };
            ser.Register <ITraceable>(_tracer);
            ser.Register <IStatable>(new StateSerializer(SyncState));
            SetupMemoryDomains();
            HardReset();

            /*
             * for (int i = 0; i < 64; i++)
             * {
             *      cpu.Regs[i] = (byte)i;
             * }
             *
             *
             * for (int j = 0; j < 0x80; j++)
             * {
             *      RAM[j] = (byte)j;
             * }
             *
             * for (int k = 0; k < 0x100; k++)
             * {
             *      ppu.WriteReg(k, (byte)k);
             * }
             */
        }
예제 #21
0
파일: GPGX.cs 프로젝트: xy2iii/BizHawk
        public GPGX(CoreComm comm, byte[] rom, IEnumerable <Disc> cds, object settings, object syncSettings)
        {
            ServiceProvider = new BasicServiceProvider(this);
            // this can influence some things internally (autodetect romtype, etc)
            string romextension = "GEN";

            // three or six button?
            // http://www.sega-16.com/forum/showthread.php?4398-Forgotten-Worlds-giving-you-GAME-OVER-immediately-Fix-inside&highlight=forgotten%20worlds

            //hack, don't use
            if (rom != null && rom.Length > 32 * 1024 * 1024)
            {
                throw new InvalidOperationException("ROM too big!  Did you try to load a CD as a ROM?");
            }

            _elf = new PeRunner(new PeRunnerOptions
            {
                Path                = comm.CoreFileProvider.DllPath(),
                Filename            = "gpgx.wbx",
                SbrkHeapSizeKB      = 512,
                SealedHeapSizeKB    = 36 * 1024,
                InvisibleHeapSizeKB = 4 * 1024,
                PlainHeapSizeKB     = 64,
                MmapHeapSizeKB      = 1 * 1024
            });

            using (_elf.EnterExit())
            {
                Core          = BizInvoker.GetInvoker <LibGPGX>(_elf, _elf, CallingConventionAdapters.Waterbox);
                _syncSettings = (GPGXSyncSettings)syncSettings ?? new GPGXSyncSettings();
                _settings     = (GPGXSettings)settings ?? new GPGXSettings();

                CoreComm = comm;

                LoadCallback = new LibGPGX.load_archive_cb(load_archive);

                _romfile = rom;

                if (cds != null)
                {
                    _cds               = cds.ToArray();
                    _cdReaders         = cds.Select(c => new DiscSectorReader(c)).ToArray();
                    cd_callback_handle = new LibGPGX.cd_read_cb(CDRead);
                    Core.gpgx_set_cdd_callback(cd_callback_handle);
                    DriveLightEnabled = true;
                }

                LibGPGX.INPUT_SYSTEM system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_NONE;
                LibGPGX.INPUT_SYSTEM system_b = LibGPGX.INPUT_SYSTEM.SYSTEM_NONE;

                switch (_syncSettings.ControlType)
                {
                case ControlType.None:
                default:
                    break;

                case ControlType.Activator:
                    system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_ACTIVATOR;
                    system_b = LibGPGX.INPUT_SYSTEM.SYSTEM_ACTIVATOR;
                    break;

                case ControlType.Normal:
                    system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_MD_GAMEPAD;
                    system_b = LibGPGX.INPUT_SYSTEM.SYSTEM_MD_GAMEPAD;
                    break;

                case ControlType.OnePlayer:
                    system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_MD_GAMEPAD;
                    break;

                case ControlType.Xea1p:
                    system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_XE_A1P;
                    break;

                case ControlType.Teamplayer:
                    system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_TEAMPLAYER;
                    system_b = LibGPGX.INPUT_SYSTEM.SYSTEM_TEAMPLAYER;
                    break;

                case ControlType.Wayplay:
                    system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_WAYPLAY;
                    system_b = LibGPGX.INPUT_SYSTEM.SYSTEM_WAYPLAY;
                    break;

                case ControlType.Mouse:
                    system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_MD_GAMEPAD;
                    // seems like mouse in port 1 would be supported, but not both at the same time
                    system_b = LibGPGX.INPUT_SYSTEM.SYSTEM_MOUSE;
                    break;
                }

                if (!Core.gpgx_init(romextension, LoadCallback, _syncSettings.UseSixButton, system_a, system_b, _syncSettings.Region, _syncSettings.GetNativeSettings()))
                {
                    throw new Exception($"{nameof(Core.gpgx_init)}() failed");
                }

                {
                    int fpsnum = 60;
                    int fpsden = 1;
                    Core.gpgx_get_fps(ref fpsnum, ref fpsden);
                    VsyncNumerator   = fpsnum;
                    VsyncDenominator = fpsden;
                    Region           = VsyncNumerator / VsyncDenominator > 55 ? DisplayType.NTSC : DisplayType.PAL;
                }

                // when we call Seal, ANY pointer passed from managed code must be 0.
                // this is so the initial state is clean
                // the only two pointers set so far are LoadCallback, which the core zeroed itself,
                // and CdCallback
                Core.gpgx_set_cdd_callback(null);
                _elf.Seal();
                Core.gpgx_set_cdd_callback(cd_callback_handle);

                SetControllerDefinition();

                // pull the default video size from the core
                UpdateVideo();

                SetMemoryDomains();

                InputCallback = new LibGPGX.input_cb(input_callback);
                Core.gpgx_set_input_callback(InputCallback);

                // process the non-init settings now
                PutSettings(_settings);

                //TODO - this hits performance, we need to make it controllable
                CDCallback = new LibGPGX.CDCallback(CDCallbackProc);

                InitMemCallbacks();
                KillMemCallbacks();

                Tracer = new GPGXTraceBuffer(this, MemoryDomains, this);
                (ServiceProvider as BasicServiceProvider).Register <ITraceable>(Tracer);
            }

            _romfile = null;
        }
예제 #22
0
파일: Genesis.cs 프로젝트: henke37/BizHawk
		public Genesis(CoreComm comm, GameInfo game, byte[] rom)
		{
			ServiceProvider = new BasicServiceProvider(this);
			CoreComm = comm;
			MainCPU = new MC68000();
			SoundCPU = new Z80A();
			YM2612 = new YM2612() { MaxVolume = 23405 };
			PSG = new SN76489() { MaxVolume = 4681 };
			VDP = new GenVDP();
			VDP.DmaReadFrom68000 = ReadWord;
			(ServiceProvider as BasicServiceProvider).Register<IVideoProvider>(VDP);
			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);
		}
예제 #23
0
        public GBHawkLink4x(CoreLoadParameters <GBLink4xSettings, GBLink4xSyncSettings> lp)
        {
            if (lp.Roms.Count != 4)
            {
                throw new InvalidOperationException("Wrong number of roms");
            }

            var ser = new BasicServiceProvider(this);

            Link4xSettings     = (GBLink4xSettings)lp.Settings ?? new GBLink4xSettings();
            Link4xSyncSettings = (GBLink4xSyncSettings)lp.SyncSettings ?? new GBLink4xSyncSettings();
            _controllerDeck    = new GBHawkLink4xControllerDeck(GBHawkLink4xControllerDeck.DefaultControllerName, GBHawkLink4xControllerDeck.DefaultControllerName,
                                                                GBHawkLink4xControllerDeck.DefaultControllerName, GBHawkLink4xControllerDeck.DefaultControllerName);

            var tempSetA = new GBHawk.GBHawk.GBSettings();
            var tempSetB = new GBHawk.GBHawk.GBSettings();
            var tempSetC = new GBHawk.GBHawk.GBSettings();
            var tempSetD = new GBHawk.GBHawk.GBSettings();

            var tempSyncA = new GBHawk.GBHawk.GBSyncSettings();
            var tempSyncB = new GBHawk.GBHawk.GBSyncSettings();
            var tempSyncC = new GBHawk.GBHawk.GBSyncSettings();
            var tempSyncD = new GBHawk.GBHawk.GBSyncSettings();

            tempSyncA.ConsoleMode = Link4xSyncSettings.ConsoleMode_A;
            tempSyncB.ConsoleMode = Link4xSyncSettings.ConsoleMode_B;
            tempSyncC.ConsoleMode = Link4xSyncSettings.ConsoleMode_C;
            tempSyncD.ConsoleMode = Link4xSyncSettings.ConsoleMode_D;

            tempSyncA.GBACGB = Link4xSyncSettings.GBACGB;
            tempSyncB.GBACGB = Link4xSyncSettings.GBACGB;
            tempSyncC.GBACGB = Link4xSyncSettings.GBACGB;
            tempSyncD.GBACGB = Link4xSyncSettings.GBACGB;

            tempSyncA.RTCInitialTime = Link4xSyncSettings.RTCInitialTime_A;
            tempSyncB.RTCInitialTime = Link4xSyncSettings.RTCInitialTime_B;
            tempSyncC.RTCInitialTime = Link4xSyncSettings.RTCInitialTime_C;
            tempSyncD.RTCInitialTime = Link4xSyncSettings.RTCInitialTime_D;
            tempSyncA.RTCOffset      = Link4xSyncSettings.RTCOffset_A;
            tempSyncB.RTCOffset      = Link4xSyncSettings.RTCOffset_B;
            tempSyncC.RTCOffset      = Link4xSyncSettings.RTCOffset_C;
            tempSyncD.RTCOffset      = Link4xSyncSettings.RTCOffset_D;

            A = new GBHawk.GBHawk(lp.Comm, lp.Roms[0].Game, lp.Roms[0].RomData, tempSetA, tempSyncA);
            B = new GBHawk.GBHawk(lp.Comm, lp.Roms[1].Game, lp.Roms[1].RomData, tempSetB, tempSyncB);
            C = new GBHawk.GBHawk(lp.Comm, lp.Roms[2].Game, lp.Roms[2].RomData, tempSetC, tempSyncC);
            D = new GBHawk.GBHawk(lp.Comm, lp.Roms[3].Game, lp.Roms[3].RomData, tempSetD, tempSyncD);

            ser.Register <IVideoProvider>(this);
            ser.Register <ISoundProvider>(this);

            _tracer = new TraceBuffer {
                Header = A.cpu.TraceHeader
            };
            ser.Register(_tracer);

            ServiceProvider = ser;

            _aStates = A.ServiceProvider.GetService <IStatable>();
            _bStates = B.ServiceProvider.GetService <IStatable>();
            _cStates = C.ServiceProvider.GetService <IStatable>();
            _dStates = D.ServiceProvider.GetService <IStatable>();

            SetupMemoryDomains();

            HardReset();
        }
예제 #24
0
파일: VBANext.cs 프로젝트: lenalia/BizHawk
        public VBANext(byte[] file, CoreComm comm, GameInfo game, bool deterministic, object syncsettings)
        {
            var ser = new BasicServiceProvider(this);

            ser.Register <IDisassemblable>(new ArmV4Disassembler());
            ServiceProvider = ser;

            CoreComm = comm;

            byte[] biosfile = CoreComm.CoreFileProvider.GetFirmware("GBA", "Bios", true, "GBA bios file is mandatory.");
            if (file.Length > 32 * 1024 * 1024)
            {
                throw new ArgumentException("ROM is too big to be a GBA ROM!");
            }
            if (biosfile.Length != 16 * 1024)
            {
                throw new ArgumentException("BIOS file is not exactly 16K!");
            }

            var FES = new LibVBANext.FrontEndSettings
            {
                saveType        = (LibVBANext.FrontEndSettings.SaveType)game.GetInt("saveType", 0),
                flashSize       = (LibVBANext.FrontEndSettings.FlashSize)game.GetInt("flashSize", 0x10000),
                enableRtc       = game.GetInt("rtcEnabled", 0) != 0,
                mirroringEnable = game.GetInt("mirroringEnabled", 0) != 0
            };

            Console.WriteLine("GameDB loaded settings: saveType={0}, flashSize={1}, rtcEnabled={2}, mirroringEnabled={3}",
                              FES.saveType, FES.flashSize, FES.enableRtc, FES.mirroringEnable);

            _syncSettings          = (SyncSettings)syncsettings ?? new SyncSettings();
            DeterministicEmulation = deterministic;

            FES.skipBios       = _syncSettings.SkipBios;
            FES.RTCUseRealTime = _syncSettings.RTCUseRealTime;
            FES.RTCwday        = (int)_syncSettings.RTCInitialDay;
            FES.RTCyear        = _syncSettings.RTCInitialTime.Year % 100;
            FES.RTCmonth       = _syncSettings.RTCInitialTime.Month - 1;
            FES.RTCmday        = _syncSettings.RTCInitialTime.Day;
            FES.RTChour        = _syncSettings.RTCInitialTime.Hour;
            FES.RTCmin         = _syncSettings.RTCInitialTime.Minute;
            FES.RTCsec         = _syncSettings.RTCInitialTime.Second;
            if (DeterministicEmulation)
            {
                // FES.skipBios = false; // this is OK; it is deterministic and probably accurate
                FES.RTCUseRealTime = false;
            }

            Core = LibVBANext.Create();
            if (Core == IntPtr.Zero)
            {
                throw new InvalidOperationException("Create() returned nullptr!");
            }
            try
            {
                if (!LibVBANext.LoadRom(Core, file, (uint)file.Length, biosfile, (uint)biosfile.Length, FES))
                {
                    throw new InvalidOperationException("LoadRom() returned false!");
                }

                Tracer = new TraceBuffer()
                {
                    Header = "ARM7: PC, machine code, mnemonic, operands, registers (r0-r16)"
                };
                ser.Register <ITraceable>(Tracer);

                CoreComm.VsyncNum      = 262144;
                CoreComm.VsyncDen      = 4389;
                CoreComm.NominalWidth  = 240;
                CoreComm.NominalHeight = 160;

                GameCode = Encoding.ASCII.GetString(file, 0xac, 4);
                Console.WriteLine("Game code \"{0}\"", GameCode);

                _savebuff  = new byte[LibVBANext.BinStateSize(Core)];
                _savebuff2 = new byte[_savebuff.Length + 13];
                InitMemoryDomains();
                InitRegisters();
                InitCallbacks();

                // todo: hook me up as a setting
                SetupColors();
            }
            catch
            {
                Dispose();
                throw;
            }
        }
예제 #25
0
        public GBHawk(CoreComm comm, GameInfo game, byte[] rom, /*string gameDbFn,*/ object settings, object syncSettings)
        {
            var ser = new BasicServiceProvider(this);

            cpu = new LR35902
            {
                ReadMemory      = ReadMemory,
                WriteMemory     = WriteMemory,
                PeekMemory      = PeekMemory,
                DummyReadMemory = ReadMemory,
                OnExecFetch     = ExecFetch,
                SpeedFunc       = SpeedFunc,
            };

            timer      = new Timer();
            audio      = new Audio();
            serialport = new SerialPort();

            CoreComm = comm;

            _settings       = (GBSettings)settings ?? new GBSettings();
            _syncSettings   = (GBSyncSettings)syncSettings ?? new GBSyncSettings();
            _controllerDeck = new GBHawkControllerDeck(_syncSettings.Port1);

            byte[] Bios = null;

            // Load up a BIOS and initialize the correct PPU
            if (_syncSettings.ConsoleMode == GBSyncSettings.ConsoleModeType.Auto)
            {
                if (game.System == "GB")
                {
                    Bios = comm.CoreFileProvider.GetFirmware("GB", "World", true, "BIOS Not Found, Cannot Load");
                    ppu  = new GB_PPU();
                }
                else
                {
                    Bios   = comm.CoreFileProvider.GetFirmware("GBC", "World", true, "BIOS Not Found, Cannot Load");
                    ppu    = new GBC_PPU();
                    is_GBC = true;
                }
            }
            else if (_syncSettings.ConsoleMode == GBSyncSettings.ConsoleModeType.GB)
            {
                Bios = comm.CoreFileProvider.GetFirmware("GB", "World", true, "BIOS Not Found, Cannot Load");
                ppu  = new GB_PPU();
            }
            else
            {
                Bios   = comm.CoreFileProvider.GetFirmware("GBC", "World", true, "BIOS Not Found, Cannot Load");
                ppu    = new GBC_PPU();
                is_GBC = true;
            }

            if (Bios == null)
            {
                throw new MissingFirmwareException("Missing Gamboy Bios");
            }

            _bios = Bios;

            // Here we modify the BIOS if GBA mode is set (credit to ExtraTricky)
            if (is_GBC && _syncSettings.GBACGB)
            {
                for (int i = 0; i < 13; i++)
                {
                    _bios[i + 0xF3] = (byte)((GBA_override[i] + _bios[i + 0xF3]) & 0xFF);
                }
            }

            // CPU needs to know about GBC status too
            cpu.is_GBC = is_GBC;

            Buffer.BlockCopy(rom, 0x100, header, 0, 0x50);

            string hash_md5 = null;

            hash_md5 = "md5:" + rom.HashMD5(0, rom.Length);
            Console.WriteLine(hash_md5);

            _rom = rom;
            Setup_Mapper();

            _frameHz = 60;

            timer.Core      = this;
            audio.Core      = this;
            ppu.Core        = this;
            serialport.Core = this;

            ser.Register <IVideoProvider>(this);
            ser.Register <ISoundProvider>(audio);
            ServiceProvider = ser;

            _settings     = (GBSettings)settings ?? new GBSettings();
            _syncSettings = (GBSyncSettings)syncSettings ?? new GBSyncSettings();

            _tracer = new TraceBuffer {
                Header = cpu.TraceHeader
            };
            ser.Register <ITraceable>(_tracer);

            SetupMemoryDomains();
            HardReset();

            iptr0 = Marshal.AllocHGlobal(VRAM.Length + 1);
            iptr1 = Marshal.AllocHGlobal(OAM.Length + 1);
            iptr2 = Marshal.AllocHGlobal(color_palette.Length * 8 * 8 + 1);
            iptr3 = Marshal.AllocHGlobal(color_palette.Length * 8 * 8 + 1);

            _scanlineCallback = null;
        }
예제 #26
0
파일: GPGX.cs 프로젝트: SaxxonPike/BizHawk
		public GPGX(CoreComm comm, byte[] rom, DiscSystem.Disc CD, object Settings, object SyncSettings)
		{
			ServiceProvider = new BasicServiceProvider(this);
			// this can influence some things internally
			string romextension = "GEN";

			// three or six button?
			// http://www.sega-16.com/forum/showthread.php?4398-Forgotten-Worlds-giving-you-GAME-OVER-immediately-Fix-inside&highlight=forgotten%20worlds

			//hack, don't use
			if (rom != null && rom.Length > 32 * 1024 * 1024)
			{
				throw new InvalidOperationException("ROM too big!  Did you try to load a CD as a ROM?");
			}

			try
			{
				_syncSettings = (GPGXSyncSettings)SyncSettings ?? new GPGXSyncSettings();

				CoreComm = comm;
				if (AttachedCore != null)
				{
					AttachedCore.Dispose();
					AttachedCore = null;
				}
				AttachedCore = this;

				LoadCallback = new LibGPGX.load_archive_cb(load_archive);

				this.romfile = rom;
				this.CD = CD;
				this.DiscSectorReader = new DiscSystem.DiscSectorReader(CD);

				LibGPGX.INPUT_SYSTEM system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_NONE;
				LibGPGX.INPUT_SYSTEM system_b = LibGPGX.INPUT_SYSTEM.SYSTEM_NONE;

				switch (_syncSettings.ControlType)
				{
					case ControlType.None:
					default:
						break;
					case ControlType.Activator:
						system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_ACTIVATOR;
						system_b = LibGPGX.INPUT_SYSTEM.SYSTEM_ACTIVATOR;
						break;
					case ControlType.Normal:
						system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_MD_GAMEPAD;
						system_b = LibGPGX.INPUT_SYSTEM.SYSTEM_MD_GAMEPAD;
						break;
					case ControlType.OnePlayer:
						system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_MD_GAMEPAD;
						break;
					case ControlType.Xea1p:
						system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_XE_A1P;
						break;
					case ControlType.Teamplayer:
						system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_TEAMPLAYER;
						system_b = LibGPGX.INPUT_SYSTEM.SYSTEM_TEAMPLAYER;
						break;
					case ControlType.Wayplay:
						system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_WAYPLAY;
						system_b = LibGPGX.INPUT_SYSTEM.SYSTEM_WAYPLAY;
						break;
					case ControlType.Mouse:
						system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_MD_GAMEPAD;
						// seems like mouse in port 1 would be supported, but not both at the same time
						system_b = LibGPGX.INPUT_SYSTEM.SYSTEM_MOUSE;
						break;
				}


				if (!LibGPGX.gpgx_init(romextension, LoadCallback, this._syncSettings.UseSixButton, system_a, system_b, this._syncSettings.Region))
					throw new Exception("gpgx_init() failed");

				{
					int fpsnum = 60;
					int fpsden = 1;
					LibGPGX.gpgx_get_fps(ref fpsnum, ref fpsden);
					CoreComm.VsyncNum = fpsnum;
					CoreComm.VsyncDen = fpsden;
					Region = CoreComm.VsyncRate > 55 ? DisplayType.NTSC : DisplayType.PAL;
				}

				// compute state size
				{
					byte[] tmp = new byte[LibGPGX.gpgx_state_max_size()];
					int size = LibGPGX.gpgx_state_size(tmp, tmp.Length);
					if (size <= 0)
						throw new Exception("Couldn't Determine GPGX internal state size!");
					_savebuff = new byte[size];
					_savebuff2 = new byte[_savebuff.Length + 13];
					Console.WriteLine("GPGX Internal State Size: {0}", size);
				}

				SetControllerDefinition();

				// pull the default video size from the core
				UpdateVideoInitial();

				SetMemoryDomains();

				InputCallback = new LibGPGX.input_cb(input_callback);
				LibGPGX.gpgx_set_input_callback(InputCallback);

				if (CD != null)
					DriveLightEnabled = true;

				PutSettings((GPGXSettings)Settings ?? new GPGXSettings());

				//TODO - this hits performance, we need to make it controllable
				CDCallback = new LibGPGX.CDCallback(CDCallbackProc);

				InitMemCallbacks();
				KillMemCallbacks();

				Tracer = new CallbackBasedTraceBuffer(this);
				(ServiceProvider as BasicServiceProvider).Register<ITraceable>(Tracer);
			}
			catch
			{
				Dispose();
				throw;
			}
		}
예제 #27
0
파일: SMS.cs 프로젝트: retr0s4ge/BizHawk
        public SMS(CoreComm comm, GameInfo game, byte[] rom, object settings, object syncSettings)
        {
            ServiceProvider = new BasicServiceProvider(this);
            Settings        = (SMSSettings)settings ?? new SMSSettings();
            SyncSettings    = (SMSSyncSettings)syncSettings ?? new SMSSyncSettings();
            CoreComm        = comm;
            MemoryCallbacks = new MemoryCallbackSystem(new[] { "System Bus" });

            IsGameGear   = game.System == "GG";
            IsGameGear_C = game.System == "GG";
            IsSG1000     = game.System == "SG";
            RomData      = rom;

            if (RomData.Length % BankSize != 0)
            {
                Array.Resize(ref RomData, ((RomData.Length / BankSize) + 1) * BankSize);
            }

            RomBanks = (byte)(RomData.Length / BankSize);

            Region = DetermineDisplayType(SyncSettings.DisplayType, game.Region);
            if (game["PAL"] && Region != DisplayType.PAL)
            {
                Region = DisplayType.PAL;
                CoreComm.Notify("Display was forced to PAL mode for game compatibility.");
            }

            if (IsGameGear)
            {
                Region = DisplayType.NTSC;                 // all game gears run at 60hz/NTSC mode
            }

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

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

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

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

            Cpu = new Z80A()
            {
                ReadHardware    = ReadPort,
                WriteHardware   = WritePort,
                FetchMemory     = FetchMemory,
                ReadMemory      = ReadMemory,
                WriteMemory     = WriteMemory,
                MemoryCallbacks = MemoryCallbacks,
                OnExecFetch     = OnExecMemory
            };


            if (game["GG_in_SMS"])
            {
                // skip setting the BIOS because this is a game gear game that puts the system
                // in SMS compatibility mode (it will fail the check sum if played on an actual SMS though.)
                IsGameGear   = false;
                IsGameGear_C = true;
                game.System  = "GG";
                Console.WriteLine("Using SMS Compatibility mode for Game Gear System");
            }

            Vdp = new VDP(this, Cpu, IsGameGear ? VdpMode.GameGear : VdpMode.SMS, Region);
            (ServiceProvider as BasicServiceProvider).Register <IVideoProvider>(Vdp);
            PSG        = new SN76489();
            YM2413     = new YM2413();
            SoundMixer = new SoundMixer(YM2413, PSG);
            if (HasYM2413 && game["WhenFMDisablePSG"])
            {
                SoundMixer.DisableSource(PSG);
            }

            ActiveSoundProvider = HasYM2413 ? (IAsyncSoundProvider)SoundMixer : PSG;
            _fakeSyncSound      = new FakeSyncSound(ActiveSoundProvider, 735);
            (ServiceProvider as BasicServiceProvider).Register <ISoundProvider>(_fakeSyncSound);

            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 if (game["EEPROM"])
            {
                InitEEPROMMapper();
            }
            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") && !game["GG_in_SMS"])
            {
                BiosRom = comm.CoreFileProvider.GetFirmware("SMS", RegionStr, false);

                if (BiosRom == null)
                {
                    throw new MissingFirmwareException("No BIOS found");
                }
                else if (!game["RequireBios"] && !SyncSettings.UseBIOS)
                {
                    // we are skipping the BIOS
                    // but only if it won't break the game
                }
                else
                {
                    Port3E = 0xF7;
                }
            }

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

            SetupMemoryDomains();

            //this manages the linkage between the cpu and mapper callbacks so it needs running before bootup is complete
            ((ICodeDataLogger)this).SetCDL(null);

            InputCallbacks = new InputCallbackSystem();

            Tracer = new TraceBuffer {
                Header = Cpu.TraceHeader
            };

            var serviceProvider = ServiceProvider as BasicServiceProvider;

            serviceProvider.Register <ITraceable>(Tracer);
            serviceProvider.Register <IDisassemblable>(Cpu);
            Vdp.ProcessOverscan();

            Cpu.ReadMemory  = ReadMemory;
            Cpu.WriteMemory = WriteMemory;
        }
예제 #28
0
        public ZXSpectrum(CoreComm comm, IEnumerable <byte[]> files, List <GameInfo> game, object settings, object syncSettings, bool?deterministic)
        {
            var ser = new BasicServiceProvider(this);

            ServiceProvider = ser;
            InputCallbacks  = new InputCallbackSystem();
            MemoryCallbacks = new MemoryCallbackSystem(new[] { "System Bus" });

            CoreComm = comm;

            _gameInfo = game;

            _cpu = new Z80A();

            _tracer = new TraceBuffer {
                Header = _cpu.TraceHeader
            };

            _files = files?.ToList() ?? new List <byte[]>();

            if (settings == null)
            {
                settings = new ZXSpectrumSettings();
            }
            if (syncSettings == null)
            {
                syncSettings = new ZXSpectrumSyncSettings();
            }

            PutSyncSettings((ZXSpectrumSyncSettings)syncSettings ?? new ZXSpectrumSyncSettings());
            PutSettings((ZXSpectrumSettings)settings ?? new ZXSpectrumSettings());

            List <JoystickType> joysticks = new List <JoystickType>();

            joysticks.Add(((ZXSpectrumSyncSettings)syncSettings as ZXSpectrumSyncSettings).JoystickType1);
            joysticks.Add(((ZXSpectrumSyncSettings)syncSettings as ZXSpectrumSyncSettings).JoystickType2);
            joysticks.Add(((ZXSpectrumSyncSettings)syncSettings as ZXSpectrumSyncSettings).JoystickType3);

            deterministicEmulation = ((ZXSpectrumSyncSettings)syncSettings as ZXSpectrumSyncSettings).DeterministicEmulation;

            if (deterministic != null && deterministic == true)
            {
                if (deterministicEmulation == false)
                {
                    CoreComm.Notify("Forcing Deterministic Emulation");
                }

                deterministicEmulation = deterministic.Value;
            }

            MachineType = SyncSettings.MachineType;

            switch (MachineType)
            {
            case MachineType.ZXSpectrum16:
                ControllerDefinition = ZXSpectrumControllerDefinition;
                Init(MachineType.ZXSpectrum16, SyncSettings.BorderType, SyncSettings.TapeLoadSpeed, _files, joysticks);
                break;

            case MachineType.ZXSpectrum48:
                ControllerDefinition = ZXSpectrumControllerDefinition;
                Init(MachineType.ZXSpectrum48, SyncSettings.BorderType, SyncSettings.TapeLoadSpeed, _files, joysticks);
                break;

            case MachineType.ZXSpectrum128:
                ControllerDefinition = ZXSpectrumControllerDefinition;
                Init(MachineType.ZXSpectrum128, SyncSettings.BorderType, SyncSettings.TapeLoadSpeed, _files, joysticks);
                break;

            case MachineType.ZXSpectrum128Plus2:
                ControllerDefinition = ZXSpectrumControllerDefinition;
                Init(MachineType.ZXSpectrum128Plus2, SyncSettings.BorderType, SyncSettings.TapeLoadSpeed, _files, joysticks);
                break;

            case MachineType.ZXSpectrum128Plus2a:
                ControllerDefinition = ZXSpectrumControllerDefinition;
                Init(MachineType.ZXSpectrum128Plus2a, SyncSettings.BorderType, SyncSettings.TapeLoadSpeed, _files, joysticks);
                break;

            case MachineType.ZXSpectrum128Plus3:
                ControllerDefinition = ZXSpectrumControllerDefinition;
                Init(MachineType.ZXSpectrum128Plus3, SyncSettings.BorderType, SyncSettings.TapeLoadSpeed, _files, joysticks);
                break;

            case MachineType.Pentagon128:
                ControllerDefinition = ZXSpectrumControllerDefinition;
                Init(MachineType.Pentagon128, SyncSettings.BorderType, SyncSettings.TapeLoadSpeed, _files, joysticks);
                break;

            default:
                throw new InvalidOperationException("Machine not yet emulated");
            }

            _cpu.MemoryCallbacks = MemoryCallbacks;

            HardReset = _machine.HardReset;
            SoftReset = _machine.SoftReset;

            _cpu.FetchMemory   = _machine.ReadMemory;
            _cpu.ReadMemory    = _machine.ReadMemory;
            _cpu.WriteMemory   = _machine.WriteMemory;
            _cpu.ReadHardware  = _machine.ReadPort;
            _cpu.WriteHardware = _machine.WritePort;
            _cpu.FetchDB       = _machine.PushBus;
            _cpu.OnExecFetch   = _machine.CPUMon.OnExecFetch;

            ser.Register <ITraceable>(_tracer);
            ser.Register <IDisassemblable>(_cpu);
            ser.Register <IVideoProvider>(_machine.ULADevice);

            // initialize sound mixer and attach the various ISoundProvider devices
            SoundMixer = new SoundProviderMixer((int)(32767 / 10), "System Beeper", (ISoundProvider)_machine.BuzzerDevice);
            SoundMixer.AddSource((ISoundProvider)_machine.TapeBuzzer, "Tape Audio");
            if (_machine.AYDevice != null)
            {
                SoundMixer.AddSource(_machine.AYDevice, "AY-3-3912");
            }

            // set audio device settings
            if (_machine.AYDevice != null && _machine.AYDevice.GetType() == typeof(AY38912))
            {
                ((AY38912)_machine.AYDevice as AY38912).PanningConfiguration = ((ZXSpectrumSettings)settings as ZXSpectrumSettings).AYPanConfig;
                _machine.AYDevice.Volume = ((ZXSpectrumSettings)settings as ZXSpectrumSettings).AYVolume;
            }

            if (_machine.BuzzerDevice != null)
            {
                ((Beeper)_machine.BuzzerDevice as Beeper).Volume = ((ZXSpectrumSettings)settings as ZXSpectrumSettings).EarVolume;
            }

            if (_machine.TapeBuzzer != null)
            {
                ((Beeper)_machine.TapeBuzzer as Beeper).Volume = ((ZXSpectrumSettings)settings as ZXSpectrumSettings).TapeVolume;
            }

            DCFilter dc = new DCFilter(SoundMixer, 512);

            ser.Register <ISoundProvider>(dc);

            HardReset();
            SetupMemoryDomains();
        }
예제 #29
0
 public NullEmulator(CoreComm comm)
 {
     ServiceProvider = new BasicServiceProvider(this);
     CoreComm        = comm;
 }
예제 #30
0
        public Gameboy(CoreComm comm, GameInfo game, byte[] file, object settings, object syncSettings, bool deterministic)
        {
            var ser = new BasicServiceProvider(this);

            ser.Register <IDisassemblable>(new GBDisassembler());
            ServiceProvider = ser;
            Tracer          = new TraceBuffer
            {
                Header = "Z80: PC, opcode, registers (A, B, C, D, E, F, H, L, LY, SP, CY)"
            };
            ser.Register <ITraceable>(Tracer);
            InitMemoryCallbacks();
            CoreComm = comm;

            comm.RomStatusAnnotation = null;
            comm.RomStatusDetails    = null;
            comm.NominalWidth        = 160;
            comm.NominalHeight       = 144;

            ThrowExceptionForBadRom(file);
            BoardName = MapperName(file);

            DeterministicEmulation = deterministic;

            GambatteState = LibGambatte.gambatte_create();

            if (GambatteState == IntPtr.Zero)
            {
                throw new InvalidOperationException($"{nameof(LibGambatte.gambatte_create)}() returned null???");
            }

            Console.WriteLine(game.System);

            try
            {
                _syncSettings = (GambatteSyncSettings)syncSettings ?? new GambatteSyncSettings();

                LibGambatte.LoadFlags flags = 0;

                switch (_syncSettings.ConsoleMode)
                {
                case GambatteSyncSettings.ConsoleModeType.GB:
                    flags |= LibGambatte.LoadFlags.FORCE_DMG;
                    break;

                case GambatteSyncSettings.ConsoleModeType.GBC:
                    break;

                default:
                    if (game.System == "GB")
                    {
                        flags |= LibGambatte.LoadFlags.FORCE_DMG;
                    }
                    break;
                }

                if (_syncSettings.GBACGB)
                {
                    flags |= LibGambatte.LoadFlags.GBA_CGB;
                }

                if (_syncSettings.MulticartCompat)
                {
                    flags |= LibGambatte.LoadFlags.MULTICART_COMPAT;
                }

                if (LibGambatte.gambatte_load(GambatteState, file, (uint)file.Length, flags) != 0)
                {
                    throw new InvalidOperationException($"{nameof(LibGambatte.gambatte_load)}() returned non-zero (is this not a gb or gbc rom?)");
                }

                byte[] Bios;
                if ((flags & LibGambatte.LoadFlags.FORCE_DMG) == LibGambatte.LoadFlags.FORCE_DMG)
                {
                    Bios  = comm.CoreFileProvider.GetFirmware("GB", "World", true, "BIOS Not Found, Cannot Load");
                    IsCgb = false;
                }
                else
                {
                    Bios  = comm.CoreFileProvider.GetFirmware("GBC", "World", true, "BIOS Not Found, Cannot Load");
                    IsCgb = true;
                }
                if (LibGambatte.gambatte_loadbios(GambatteState, Bios, (uint)Bios.Length) != 0)
                {
                    throw new InvalidOperationException($"{nameof(LibGambatte.gambatte_loadbios)}() returned non-zero (bios error)");
                }

                // set real default colors (before anyone mucks with them at all)
                PutSettings((GambatteSettings)settings ?? new GambatteSettings());

                InitSound();

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

                InputCallback = new LibGambatte.InputGetter(ControllerCallback);

                LibGambatte.gambatte_setinputgetter(GambatteState, InputCallback);

                InitMemoryDomains();

                CoreComm.RomStatusDetails = $"{game.Name}\r\nSHA1:{file.HashSHA1()}\r\nMD5:{file.HashMD5()}\r\n";

                byte[] buff = new byte[32];
                LibGambatte.gambatte_romtitle(GambatteState, buff);
                string romname = System.Text.Encoding.ASCII.GetString(buff);
                Console.WriteLine("Core reported rom name: {0}", romname);

                if (!DeterministicEmulation && _syncSettings.RealTimeRTC)
                {
                    LibGambatte.gambatte_settimemode(GambatteState, false);
                }
                LibGambatte.gambatte_setrtcdivisoroffset(GambatteState, _syncSettings.RTCDivisorOffset);

                _cdCallback = new LibGambatte.CDCallback(CDCallbackProc);

                NewSaveCoreSetBuff();
            }
            catch
            {
                Dispose();
                throw;
            }
        }
예제 #31
0
파일: SMS.cs 프로젝트: budzikt/BizHawk
        public SMS(CoreComm comm, GameInfo game, byte[] rom, object settings, object syncSettings)
        {
            ServiceProvider = new BasicServiceProvider(this);
            Settings        = (SMSSettings)settings ?? new SMSSettings();
            SyncSettings    = (SMSSyncSettings)syncSettings ?? new SMSSyncSettings();
            CoreComm        = comm;
            MemoryCallbacks = new MemoryCallbackSystem();

            IsGameGear = game.System == "GG";
            IsSG1000   = game.System == "SG";
            RomData    = rom;
            Tracer     = new TraceBuffer();
            (ServiceProvider as BasicServiceProvider).Register <ITraceable>(Tracer);
            if (RomData.Length % BankSize != 0)
            {
                Array.Resize(ref RomData, ((RomData.Length / BankSize) + 1) * BankSize);
            }
            RomBanks = (byte)(RomData.Length / BankSize);

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

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

            if (game["Japan"] && RegionStr != "Japan")
            {
                RegionStr = "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;
            Cpu.MemoryCallbacks = MemoryCallbacks;

            Vdp = new VDP(this, Cpu, IsGameGear ? VdpMode.GameGear : VdpMode.SMS, Region);
            (ServiceProvider as BasicServiceProvider).Register <IVideoProvider>(Vdp);
            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", RegionStr, false);
                if (BiosRom != null && (game["RequireBios"] || SyncSettings.UseBIOS))
                {
                    Port3E = 0xF7;
                }

                if (BiosRom == null && game["RequireBios"])
                {
                    throw new MissingFirmwareException("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();

            //this manages the linkage between the cpu and mapper callbacks so it needs running before bootup is complete
            ((ICodeDataLogger)this).SetCDL(null);

            (ServiceProvider as BasicServiceProvider).Register <IDisassemblable>(new Disassembler());
        }
예제 #32
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;
			}
		}
예제 #33
0
        public N64(CoreComm comm, GameInfo game, byte[] file, object settings, object syncSettings)
        {
            ServiceProvider = new BasicServiceProvider(this);
            InputCallbacks  = new InputCallbackSystem();

            _memorycallbacks.CallbackAdded   += AddBreakpoint;
            _memorycallbacks.CallbackRemoved += RemoveBreakpoint;

            int SaveType = 0;

            if (game.OptionValue("SaveType") == "EEPROM_16K")
            {
                SaveType = 1;
            }

            CoreComm = comm;

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

            _disableExpansionSlot = _syncSettings.DisableExpansionSlot;

            // Override the user's expansion slot setting if it is mentioned in the gamedb (it is mentioned but the game MUST have this setting or else not work
            if (game.OptionValue("expansionpak") != null && game.OptionValue("expansionpak") == "1")
            {
                _disableExpansionSlot = false;
                IsOverridingUserExpansionSlotSetting = true;
            }

            byte country_code = file[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;
            }

            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, file, videosettings, SaveType, (int)coreType, _disableExpansionSlot);
            });

            // Order is important because the register with the mupen core
            _videoProvider = new N64VideoProvider(api, videosettings);
            _audioProvider = new N64Audio(api);
            _inputProvider = new N64Input(this.AsInputPollable(), api, comm, this._syncSettings.Controllers);
            (ServiceProvider as BasicServiceProvider).Register <IVideoProvider>(_videoProvider);
            (ServiceProvider as BasicServiceProvider).Register <ISoundProvider>(_audioProvider.Resampler);

            switch (Region)
            {
            case DisplayType.NTSC:
                _videoProvider.VsyncNumerator   = 60000;
                _videoProvider.VsyncDenominator = 1001;
                break;

            default:
                _videoProvider.VsyncNumerator   = 50;
                _videoProvider.VsyncDenominator = 1;
                break;
            }

            string rsp;

            switch (_syncSettings.Rsp)
            {
            default:
            case N64SyncSettings.RspType.Rsp_Hle:
                rsp = "mupen64plus-rsp-hle.dll";
                break;
                //case N64SyncSettings.RspType.Rsp_cxd4:
                //	rsp = "mupen64plus-rsp-cxd4.dll";
                //	break;
            }

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

            InitMemoryDomains();
            //if (_syncSettings.Core != N64SyncSettings.CoreType.Dynarec)
            {
                ConnectTracer();
                SetBreakpointHandler();
            }

            api.AsyncExecuteEmulator();

            // Hack: Saving a state on frame 0 has been shown to not be sync stable. Advance past that frame to avoid the problem.
            // Advancing 2 frames was chosen to deal with a problem with the dynamic recompiler. The dynarec seems to take 2 frames to set
            // things up correctly. If a state is loaded on frames 0 or 1 mupen tries to access null pointers and the emulator crashes, so instead
            // advance past both to again avoid the problem.
            api.frame_advance();
            api.frame_advance();

            SetControllerButtons();
        }
예제 #34
0
        public MGBAHawk(byte[] file, CoreComm comm, SyncSettings syncSettings, Settings settings, bool deterministic)
        {
            _syncSettings          = syncSettings ?? new SyncSettings();
            _settings              = settings ?? new Settings();
            DeterministicEmulation = deterministic;

            byte[] bios = comm.CoreFileProvider.GetFirmware("GBA", "Bios", false);
            DeterministicEmulation &= bios != null;

            if (DeterministicEmulation != deterministic)
            {
                throw new InvalidOperationException("A BIOS is required for deterministic recordings!");
            }
            if (!DeterministicEmulation && bios != null && !_syncSettings.RTCUseRealTime && !_syncSettings.SkipBios)
            {
                // in these situations, this core is deterministic even though it wasn't asked to be
                DeterministicEmulation = true;
            }

            if (bios != null && bios.Length != 16384)
            {
                throw new InvalidOperationException("BIOS must be exactly 16384 bytes!");
            }
            core = LibmGBA.BizCreate(bios);
            if (core == IntPtr.Zero)
            {
                throw new InvalidOperationException("BizCreate() returned NULL!  Bad BIOS?");
            }
            try
            {
                if (!LibmGBA.BizLoad(core, file, file.Length))
                {
                    throw new InvalidOperationException("BizLoad() returned FALSE!  Bad ROM?");
                }

                if (!DeterministicEmulation && _syncSettings.SkipBios)
                {
                    LibmGBA.BizSkipBios(core);
                }


                CreateMemoryDomains(file.Length);
                var ser = new BasicServiceProvider(this);
                ser.Register <IDisassemblable>(new ArmV4Disassembler());
                ser.Register <IMemoryDomains>(MemoryDomains);

                ServiceProvider = ser;
                CoreComm        = comm;

                CoreComm.VsyncNum      = 262144;
                CoreComm.VsyncDen      = 4389;
                CoreComm.NominalWidth  = 240;
                CoreComm.NominalHeight = 160;

                InitStates();
            }
            catch
            {
                LibmGBA.BizDestroy(core);
                throw;
            }
        }
예제 #35
0
        public ZXSpectrum(
            CoreLoadParameters <ZXSpectrumSettings, ZXSpectrumSyncSettings> lp)
        {
            var ser = new BasicServiceProvider(this);

            ServiceProvider = ser;
            CoreComm        = lp.Comm;

            _gameInfo = lp.Roms.Select(r => r.Game).ToList();

            _cpu = new Z80A();

            _tracer = new TraceBuffer {
                Header = _cpu.TraceHeader
            };

            _files = lp.Roms.Select(r => r.RomData).ToList();

            var settings     = lp.Settings ?? new ZXSpectrumSettings();
            var syncSettings = lp.SyncSettings ?? new ZXSpectrumSyncSettings();

            PutSyncSettings(lp.SyncSettings);
            PutSettings(lp.Settings);

            var joysticks = new List <JoystickType>
            {
                ((ZXSpectrumSyncSettings)syncSettings).JoystickType1,
                ((ZXSpectrumSyncSettings)syncSettings).JoystickType2,
                ((ZXSpectrumSyncSettings)syncSettings).JoystickType3
            };

            DeterministicEmulation = ((ZXSpectrumSyncSettings)syncSettings).DeterministicEmulation;

            if (lp.DeterministicEmulationRequested)
            {
                if (!DeterministicEmulation)
                {
                    CoreComm.Notify("Forcing Deterministic Emulation");
                }

                DeterministicEmulation = lp.DeterministicEmulationRequested;
            }

            MachineType = SyncSettings.MachineType;

            switch (MachineType)
            {
            case MachineType.ZXSpectrum16:
                ControllerDefinition = ZXSpectrumControllerDefinition;
                Init(MachineType.ZXSpectrum16, SyncSettings.BorderType, SyncSettings.TapeLoadSpeed, _files, joysticks);
                break;

            case MachineType.ZXSpectrum48:
                ControllerDefinition = ZXSpectrumControllerDefinition;
                Init(MachineType.ZXSpectrum48, SyncSettings.BorderType, SyncSettings.TapeLoadSpeed, _files, joysticks);
                break;

            case MachineType.ZXSpectrum128:
                ControllerDefinition = ZXSpectrumControllerDefinition;
                Init(MachineType.ZXSpectrum128, SyncSettings.BorderType, SyncSettings.TapeLoadSpeed, _files, joysticks);
                break;

            case MachineType.ZXSpectrum128Plus2:
                ControllerDefinition = ZXSpectrumControllerDefinition;
                Init(MachineType.ZXSpectrum128Plus2, SyncSettings.BorderType, SyncSettings.TapeLoadSpeed, _files, joysticks);
                break;

            case MachineType.ZXSpectrum128Plus2a:
                ControllerDefinition = ZXSpectrumControllerDefinition;
                Init(MachineType.ZXSpectrum128Plus2a, SyncSettings.BorderType, SyncSettings.TapeLoadSpeed, _files, joysticks);
                break;

            case MachineType.ZXSpectrum128Plus3:
                ControllerDefinition = ZXSpectrumControllerDefinition;
                Init(MachineType.ZXSpectrum128Plus3, SyncSettings.BorderType, SyncSettings.TapeLoadSpeed, _files, joysticks);
                break;

            case MachineType.Pentagon128:
                ControllerDefinition = ZXSpectrumControllerDefinition;
                Init(MachineType.Pentagon128, SyncSettings.BorderType, SyncSettings.TapeLoadSpeed, _files, joysticks);
                break;

            default:
                throw new InvalidOperationException("Machine not yet emulated");
            }

            _cpu.MemoryCallbacks = MemoryCallbacks;

            HardReset = _machine.HardReset;
            SoftReset = _machine.SoftReset;

            _cpu.FetchMemory   = _machine.ReadMemory;
            _cpu.ReadMemory    = _machine.ReadMemory;
            _cpu.WriteMemory   = _machine.WriteMemory;
            _cpu.ReadHardware  = _machine.ReadPort;
            _cpu.WriteHardware = _machine.WritePort;
            _cpu.FetchDB       = _machine.PushBus;
            _cpu.OnExecFetch   = _machine.CPUMon.OnExecFetch;

            ser.Register <ITraceable>(_tracer);
            ser.Register <IDisassemblable>(_cpu);
            ser.Register <IVideoProvider>(_machine.ULADevice);

            // initialize sound mixer and attach the various ISoundProvider devices
            SoundMixer = new SyncSoundMixer(targetSampleCount: 882);
            SoundMixer.PinSource(_machine.BuzzerDevice, "System Beeper", (int)(32767 / 10));
            SoundMixer.PinSource(_machine.TapeBuzzer, "Tape Audio", (int)(32767 / 10));
            if (_machine.AYDevice != null)
            {
                SoundMixer.PinSource(_machine.AYDevice, "AY-3-3912");
            }

            // set audio device settings
            if (_machine.AYDevice != null && _machine.AYDevice.GetType() == typeof(AY38912))
            {
                ((AY38912)_machine.AYDevice).PanningConfiguration = ((ZXSpectrumSettings)settings).AYPanConfig;
                _machine.AYDevice.Volume = ((ZXSpectrumSettings)settings).AYVolume;
            }

            if (_machine.BuzzerDevice != null)
            {
                _machine.BuzzerDevice.Volume = ((ZXSpectrumSettings)settings).EarVolume;
            }

            if (_machine.TapeBuzzer != null)
            {
                _machine.TapeBuzzer.Volume = ((ZXSpectrumSettings)settings).TapeVolume;
            }

            DCFilter dc = new DCFilter(SoundMixer, 512);

            ser.Register <ISoundProvider>(dc);
            ser.Register <IStatable>(new StateSerializer(SyncState));
            HardReset();
            SetupMemoryDomains();
        }
예제 #36
0
        public O2Hawk(CoreComm comm, GameInfo game, byte[] rom, O2Settings settings, O2SyncSettings syncSettings)
        {
            var ser = new BasicServiceProvider(this);

            cpu = new I8048
            {
                ReadMemory      = ReadMemory,
                WriteMemory     = WriteMemory,
                PeekMemory      = PeekMemory,
                DummyReadMemory = ReadMemory,
                ReadPort        = ReadPort,
                WritePort       = WritePort,
                OnExecFetch     = ExecFetch,
            };

            _settings     = settings ?? new O2Settings();
            _syncSettings = syncSettings ?? new O2SyncSettings();

            is_G7400 = _syncSettings.G7400_Enable;

            _controllerDeck = new O2HawkControllerDeck("O2 Controller", "O2 Controller", is_G7400);

            _bios = comm.CoreFileProvider.GetFirmwareOrThrow(new("O2", is_G7400 ? "BIOS-G7400" : "BIOS-O2"), "BIOS Not Found, Cannot Load");

            Buffer.BlockCopy(rom, 0x100, header, 0, 0x50);

            Console.WriteLine("MD5: " + rom.HashMD5(0, rom.Length));
            Console.WriteLine("SHA1: " + rom.HashSHA1(0, rom.Length));
            _rom = rom;

            if (game["XROM"])
            {
                is_XROM = true;
            }
            Setup_Mapper();

            _frameHz = 60;

            ser.Register <IVideoProvider>(this);
            ServiceProvider = ser;

            _tracer = new TraceBuffer(cpu.TraceHeader);
            ser.Register(_tracer);
            ser.Register <IStatable>(new StateSerializer(SyncState));
            SetupMemoryDomains();
            cpu.SetCallbacks(ReadMemory, PeekMemory, PeekMemory, WriteMemory);

            // set up differences between PAL and NTSC systems
            if ((game.Region == "US" || game.Region == "EU-US" || game.Region == null) && !is_G7400)
            {
                is_pal     = false;
                pic_height = 240;
                _frameHz   = 60;

                ppu = new NTSC_PPU();
            }
            else
            {
                is_pal     = true;
                pic_height = 240;
                _frameHz   = 50;
                ppu        = new PAL_PPU();
            }

            ppu.Core = this;
            ppu.set_region(is_pal, is_G7400);
            ser.Register <ISoundProvider>(ppu);

            _vidbuffer   = new int[372 * pic_height];
            frame_buffer = new int[320 * pic_height];

            HardReset();
        }
예제 #37
0
        public MSX(CoreComm comm, GameInfo game, byte[] rom, object settings, object syncSettings)
        {
            ServiceProvider = new BasicServiceProvider(this);
            Settings        = (MSXSettings)settings ?? new MSXSettings();
            SyncSettings    = (MSXSyncSettings)syncSettings ?? new MSXSyncSettings();

            RomData = rom;
            int size = RomData.Length;

            if (RomData.Length % BankSize != 0)
            {
                Array.Resize(ref RomData, ((RomData.Length / BankSize) + 1) * BankSize);
            }

            // we want all ROMS to be multiples of 64K for easy memory mapping later
            if (RomData.Length != 0x10000)
            {
                Array.Resize(ref RomData, 0x10000);
            }

            // if the original was not 64 or 48 k, move it (may need to do this case by case)

            if (size == 0x8000)
            {
                for (int i = 0x7FFF; i >= 0; i--)
                {
                    RomData[i + 0x4000] = RomData[i];
                }
                for (int i = 0; i < 0x4000; i++)
                {
                    RomData[i] = 0;
                }
            }

            if (size == 0x4000)
            {
                for (int i = 0; i < 0x4000; i++)
                {
                    RomData[i + 0x4000] = RomData[i];
                    RomData[i + 0x8000] = RomData[i];
                    RomData[i + 0xC000] = RomData[i];
                }
            }

            Bios = comm.CoreFileProvider.GetFirmware("MSX", "bios_jp", false, "BIOS Not Found, Cannot Load");

            if (Bios == null)
            {
                Bios = comm.CoreFileProvider.GetFirmware("MSX", "bios_test_ext", true, "BIOS Not Found, Cannot Load");
            }
            //Basic = comm.CoreFileProvider.GetFirmware("MSX", "basic_test", true, "BIOS Not Found, Cannot Load");


            Basic = new byte[0x4000];

            MSX_Pntr = LibMSX.MSX_create();

            LibMSX.MSX_load_bios(MSX_Pntr, Bios, Basic);
            LibMSX.MSX_load(MSX_Pntr, RomData, (uint)RomData.Length, 0, RomData, (uint)RomData.Length, 0);

            blip.SetRates(3579545, 44100);

            (ServiceProvider as BasicServiceProvider).Register <ISoundProvider>(this);

            SetupMemoryDomains();

            Header_Length     = LibMSX.MSX_getheaderlength(MSX_Pntr);
            Disasm_Length     = LibMSX.MSX_getdisasmlength(MSX_Pntr);
            Reg_String_Length = LibMSX.MSX_getregstringlength(MSX_Pntr);

            var newHeader = new StringBuilder(Header_Length);

            LibMSX.MSX_getheader(MSX_Pntr, newHeader, Header_Length);

            Console.WriteLine(Header_Length + " " + Disasm_Length + " " + Reg_String_Length);

            Tracer = new TraceBuffer {
                Header = newHeader.ToString()
            };

            var serviceProvider = ServiceProvider as BasicServiceProvider;

            serviceProvider.Register <ITraceable>(Tracer);
            serviceProvider.Register <IStatable>(new StateSerializer(SyncState));

            current_controller = SyncSettings.Contr_Setting == MSXSyncSettings.ContrType.Keyboard ? MSXControllerKB : MSXControllerJS;
        }
예제 #38
0
파일: GPGX.cs 프로젝트: CadeLaRen/BizHawk
        public GPGX(CoreComm comm, byte[] rom, DiscSystem.Disc CD, object Settings, object SyncSettings)
        {
            ServiceProvider = new BasicServiceProvider(this);
            // this can influence some things internally (autodetect romtype, etc)
            string romextension = "GEN";

            // three or six button?
            // http://www.sega-16.com/forum/showthread.php?4398-Forgotten-Worlds-giving-you-GAME-OVER-immediately-Fix-inside&highlight=forgotten%20worlds

            //hack, don't use
            if (rom != null && rom.Length > 32 * 1024 * 1024)
            {
                throw new InvalidOperationException("ROM too big!  Did you try to load a CD as a ROM?");
            }

            try
            {
                Elf = new ElfRunner(Path.Combine(comm.CoreFileProvider.DllPath(), "gpgx.elf"), 8 * 1024 * 1024, 36 * 1024 * 1024, 4 * 1024 * 1024);
                if (Elf.ShouldMonitor)
                    Core = BizInvoker.GetInvoker<LibGPGX>(Elf, Elf);
                else
                    Core = BizInvoker.GetInvoker<LibGPGX>(Elf);

                _syncSettings = (GPGXSyncSettings)SyncSettings ?? new GPGXSyncSettings();
                _settings = (GPGXSettings)Settings ?? new GPGXSettings();

                CoreComm = comm;

                LoadCallback = new LibGPGX.load_archive_cb(load_archive);

                this.romfile = rom;
                this.CD = CD;
                if (CD != null)
                {
                    this.DiscSectorReader = new DiscSystem.DiscSectorReader(CD);
                    cd_callback_handle = new LibGPGX.cd_read_cb(CDRead);
                    Core.gpgx_set_cdd_callback(cd_callback_handle);
                }

                LibGPGX.INPUT_SYSTEM system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_NONE;
                LibGPGX.INPUT_SYSTEM system_b = LibGPGX.INPUT_SYSTEM.SYSTEM_NONE;

                switch (_syncSettings.ControlType)
                {
                    case ControlType.None:
                    default:
                        break;
                    case ControlType.Activator:
                        system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_ACTIVATOR;
                        system_b = LibGPGX.INPUT_SYSTEM.SYSTEM_ACTIVATOR;
                        break;
                    case ControlType.Normal:
                        system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_MD_GAMEPAD;
                        system_b = LibGPGX.INPUT_SYSTEM.SYSTEM_MD_GAMEPAD;
                        break;
                    case ControlType.OnePlayer:
                        system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_MD_GAMEPAD;
                        break;
                    case ControlType.Xea1p:
                        system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_XE_A1P;
                        break;
                    case ControlType.Teamplayer:
                        system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_TEAMPLAYER;
                        system_b = LibGPGX.INPUT_SYSTEM.SYSTEM_TEAMPLAYER;
                        break;
                    case ControlType.Wayplay:
                        system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_WAYPLAY;
                        system_b = LibGPGX.INPUT_SYSTEM.SYSTEM_WAYPLAY;
                        break;
                    case ControlType.Mouse:
                        system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_MD_GAMEPAD;
                        // seems like mouse in port 1 would be supported, but not both at the same time
                        system_b = LibGPGX.INPUT_SYSTEM.SYSTEM_MOUSE;
                        break;
                }

                if (!Core.gpgx_init(romextension, LoadCallback, _syncSettings.UseSixButton, system_a, system_b, _syncSettings.Region, _settings.GetNativeSettings()))
                    throw new Exception("gpgx_init() failed");

                {
                    int fpsnum = 60;
                    int fpsden = 1;
                    Core.gpgx_get_fps(ref fpsnum, ref fpsden);
                    CoreComm.VsyncNum = fpsnum;
                    CoreComm.VsyncDen = fpsden;
                    Region = CoreComm.VsyncRate > 55 ? DisplayType.NTSC : DisplayType.PAL;
                }

                // compute state size
                InitStateBuffers();

                SetControllerDefinition();

                // pull the default video size from the core
                UpdateVideoInitial();

                SetMemoryDomains();

                InputCallback = new LibGPGX.input_cb(input_callback);
                Core.gpgx_set_input_callback(InputCallback);

                if (CD != null)
                    DriveLightEnabled = true;

                // process the non-init settings now
                PutSettings(_settings);

                //TODO - this hits performance, we need to make it controllable
                CDCallback = new LibGPGX.CDCallback(CDCallbackProc);

                InitMemCallbacks();
                KillMemCallbacks();

                Tracer = new GPGXTraceBuffer(this, MemoryDomains, this);
                (ServiceProvider as BasicServiceProvider).Register<ITraceable>(Tracer);

                Elf.Seal();
            }
            catch
            {
                Dispose();
                throw;
            }
        }
예제 #39
0
        public VectrexHawk(CoreComm comm, GameInfo game, byte[] rom, /*string gameDbFn,*/ object settings, object syncSettings)
        {
            var ser = new BasicServiceProvider(this);

            cpu = new MC6809
            {
                ReadMemory      = ReadMemory,
                WriteMemory     = WriteMemory,
                PeekMemory      = PeekMemory,
                DummyReadMemory = ReadMemory,
                OnExecFetch     = ExecFetch,
            };

            audio      = new Audio();
            ppu        = new PPU();
            serialport = new SerialPort();

            CoreComm = comm;

            _settings       = (VectrexSettings)settings ?? new VectrexSettings();
            _syncSettings   = (VectrexSyncSettings)syncSettings ?? new VectrexSyncSettings();
            _controllerDeck = new VectrexHawkControllerDeck(_syncSettings.Port1, _syncSettings.Port2);

            byte[] Bios = null;
            byte[] Mine = null;

            Bios  = comm.CoreFileProvider.GetFirmware("Vectrex", "Bios", true, "BIOS Not Found, Cannot Load");
            _bios = Bios;

            Mine      = comm.CoreFileProvider.GetFirmware("Vectrex", "Minestorm", true, "Minestorm Not Found, Cannot Load");
            minestorm = Mine;

            Console.WriteLine("SHA1:" + rom.HashSHA1(0, rom.Length));

            _rom = rom;

            // If the game is minstorm, then no cartridge is inserted, retun 0xFF
            if (rom.HashSHA1(0, rom.Length) == "65D07426B520DDD3115D40F255511E0FD2E20AE7")
            {
                _rom = new byte[0x8000];

                for (int i = 0; i < 0x8000; i++)
                {
                    _rom[i] = 0xFF;
                }
            }

            // mirror games that are too small
            if (_rom.Length < 0x8000)
            {
                _rom = new byte[0x8000];

                for (int i = 0; i < 0x8000 / rom.Length; i++)
                {
                    for (int j = 0; j < rom.Length; j++)
                    {
                        _rom[j + i * rom.Length] = rom[j];
                    }
                }
            }

            // RAM appears to power up to either random values or 0xFF, otherwise all the asteroids in minestorm are on the same side if RAM[0x7E]=0
            for (int i = 0; i < RAM.Length; i++)
            {
                RAM[i] = 0xFF;
            }

            Setup_Mapper();

            _frameHz = 50;

            audio.Core      = this;
            ppu.Core        = this;
            serialport.Core = this;

            ser.Register <IVideoProvider>(this);
            ser.Register <ISoundProvider>(audio);
            ServiceProvider = ser;

            _settings     = (VectrexSettings)settings ?? new VectrexSettings();
            _syncSettings = (VectrexSyncSettings)syncSettings ?? new VectrexSyncSettings();

            _tracer = new TraceBuffer {
                Header = cpu.TraceHeader
            };
            ser.Register <ITraceable>(_tracer);

            SetupMemoryDomains();
            HardReset();

            cpu.SetCallbacks(ReadMemory, PeekMemory, PeekMemory, WriteMemory);
        }
예제 #40
0
        //[CoreConstructor("GB", "GBC")]
        public GBHawkLink3x(CoreComm comm, GameInfo game_L, byte[] rom_L, GameInfo game_C, byte[] rom_C, GameInfo game_R, byte[] rom_R, /*string gameDbFn,*/ object settings, object syncSettings)
        {
            var ser = new BasicServiceProvider(this);

            Link3xSettings     = (GBLink3xSettings)settings ?? new GBLink3xSettings();
            Link3xSyncSettings = (GBLink3xSyncSettings)syncSettings ?? new GBLink3xSyncSettings();
            _controllerDeck    = new GBHawkLink3xControllerDeck(GBHawkLink3xControllerDeck.DefaultControllerName, GBHawkLink3xControllerDeck.DefaultControllerName, GBHawkLink3xControllerDeck.DefaultControllerName);

            CoreComm = comm;

            var temp_set_L = new GBHawk.GBHawk.GBSettings();
            var temp_set_C = new GBHawk.GBHawk.GBSettings();
            var temp_set_R = new GBHawk.GBHawk.GBSettings();

            var temp_sync_L = new GBHawk.GBHawk.GBSyncSettings();
            var temp_sync_C = new GBHawk.GBHawk.GBSyncSettings();
            var temp_sync_R = new GBHawk.GBHawk.GBSyncSettings();

            temp_sync_L.ConsoleMode = Link3xSyncSettings.ConsoleMode_L;
            temp_sync_C.ConsoleMode = Link3xSyncSettings.ConsoleMode_C;
            temp_sync_R.ConsoleMode = Link3xSyncSettings.ConsoleMode_R;

            temp_sync_L.GBACGB = Link3xSyncSettings.GBACGB;
            temp_sync_C.GBACGB = Link3xSyncSettings.GBACGB;
            temp_sync_R.GBACGB = Link3xSyncSettings.GBACGB;

            temp_sync_L.RTCInitialTime = Link3xSyncSettings.RTCInitialTime_L;
            temp_sync_C.RTCInitialTime = Link3xSyncSettings.RTCInitialTime_C;
            temp_sync_R.RTCInitialTime = Link3xSyncSettings.RTCInitialTime_R;
            temp_sync_L.RTCOffset      = Link3xSyncSettings.RTCOffset_L;
            temp_sync_C.RTCOffset      = Link3xSyncSettings.RTCOffset_C;
            temp_sync_R.RTCOffset      = Link3xSyncSettings.RTCOffset_R;

            L = new GBHawk.GBHawk(new CoreComm(comm.ShowMessage, comm.Notify)
            {
                CoreFileProvider = comm.CoreFileProvider
            },
                                  game_L, rom_L, temp_set_L, temp_sync_L);

            C = new GBHawk.GBHawk(new CoreComm(comm.ShowMessage, comm.Notify)
            {
                CoreFileProvider = comm.CoreFileProvider
            },
                                  game_C, rom_C, temp_set_C, temp_sync_C);

            R = new GBHawk.GBHawk(new CoreComm(comm.ShowMessage, comm.Notify)
            {
                CoreFileProvider = comm.CoreFileProvider
            },
                                  game_R, rom_R, temp_set_R, temp_sync_R);

            ser.Register <IVideoProvider>(this);
            ser.Register <ISoundProvider>(this);

            _tracer = new TraceBuffer {
                Header = L.cpu.TraceHeader
            };
            ser.Register <ITraceable>(_tracer);

            ServiceProvider = ser;

            SetupMemoryDomains();

            HardReset();
        }
예제 #41
0
        void Init(GameInfo game, byte[] rom)
        {
            Controller = NullController.GetNullController();
            Cpu        = new HuC6280(MemoryCallbacks);
            VCE        = new VCE();
            VDC1       = new VDC(this, Cpu, VCE);
            PSG        = new HuC6280PSG();
            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(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) => Tracer.Put(new TraceInfo
                {
                    Disassembly  = string.Format("{0:X1}:{1}", SF2MapperLatch, 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);
            SetupMemoryDomains();
        }
예제 #42
0
        public GPGX(CoreComm comm, byte[] rom, DiscSystem.Disc CD, object Settings, object SyncSettings)
        {
            ServiceProvider = new BasicServiceProvider(this);
            // this can influence some things internally
            string romextension = "GEN";

            // three or six button?
            // http://www.sega-16.com/forum/showthread.php?4398-Forgotten-Worlds-giving-you-GAME-OVER-immediately-Fix-inside&highlight=forgotten%20worlds

            //hack, don't use
            //romfile = File.ReadAllBytes(@"D:\encodes\bizhawksrc\output\SANIC CD\PierSolar (E).bin");
            if (rom != null && rom.Length > 16 * 1024 * 1024)
            {
                throw new InvalidOperationException("ROM too big!  Did you try to load a CD as a ROM?");
            }

            try
            {
                _SyncSettings = (GPGXSyncSettings)SyncSettings ?? new GPGXSyncSettings();

                CoreComm = comm;
                if (AttachedCore != null)
                {
                    AttachedCore.Dispose();
                    AttachedCore = null;
                }
                AttachedCore = this;

                LoadCallback = new LibGPGX.load_archive_cb(load_archive);

                this.romfile          = rom;
                this.CD               = CD;
                this.DiscSectorReader = new DiscSystem.DiscSectorReader(CD);

                LibGPGX.INPUT_SYSTEM system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_NONE;
                LibGPGX.INPUT_SYSTEM system_b = LibGPGX.INPUT_SYSTEM.SYSTEM_NONE;

                switch (this._SyncSettings.ControlType)
                {
                case ControlType.None:
                default:
                    break;

                case ControlType.Activator:
                    system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_ACTIVATOR;
                    system_b = LibGPGX.INPUT_SYSTEM.SYSTEM_ACTIVATOR;
                    break;

                case ControlType.Normal:
                    system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_MD_GAMEPAD;
                    system_b = LibGPGX.INPUT_SYSTEM.SYSTEM_MD_GAMEPAD;
                    break;

                case ControlType.OnePlayer:
                    system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_MD_GAMEPAD;
                    break;

                case ControlType.Xea1p:
                    system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_XE_A1P;
                    break;

                case ControlType.Teamplayer:
                    system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_TEAMPLAYER;
                    system_b = LibGPGX.INPUT_SYSTEM.SYSTEM_TEAMPLAYER;
                    break;

                case ControlType.Wayplay:
                    system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_WAYPLAY;
                    system_b = LibGPGX.INPUT_SYSTEM.SYSTEM_WAYPLAY;
                    break;

                case ControlType.Mouse:
                    system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_MD_GAMEPAD;
                    // seems like mouse in port 1 would be supported, but not both at the same time
                    system_b = LibGPGX.INPUT_SYSTEM.SYSTEM_MOUSE;
                    break;
                }


                if (!LibGPGX.gpgx_init(romextension, LoadCallback, this._SyncSettings.UseSixButton, system_a, system_b, this._SyncSettings.Region))
                {
                    throw new Exception("gpgx_init() failed");
                }

                {
                    int fpsnum = 60;
                    int fpsden = 1;
                    LibGPGX.gpgx_get_fps(ref fpsnum, ref fpsden);
                    CoreComm.VsyncNum = fpsnum;
                    CoreComm.VsyncDen = fpsden;
                    Region            = CoreComm.VsyncRate > 55 ? DisplayType.NTSC : DisplayType.PAL;
                }

                // compute state size
                {
                    byte[] tmp  = new byte[LibGPGX.gpgx_state_max_size()];
                    int    size = LibGPGX.gpgx_state_size(tmp, tmp.Length);
                    if (size <= 0)
                    {
                        throw new Exception("Couldn't Determine GPGX internal state size!");
                    }
                    savebuff  = new byte[size];
                    savebuff2 = new byte[savebuff.Length + 13];
                    Console.WriteLine("GPGX Internal State Size: {0}", size);
                }

                SetControllerDefinition();

                // pull the default video size from the core
                update_video_initial();

                SetMemoryDomains();

                InputCallback = new LibGPGX.input_cb(input_callback);
                LibGPGX.gpgx_set_input_callback(InputCallback);

                if (CD != null)
                {
                    DriveLightEnabled = true;
                }

                PutSettings((GPGXSettings)Settings ?? new GPGXSettings());

                InitMemCallbacks();
                KillMemCallbacks();
            }
            catch
            {
                Dispose();
                throw;
            }
        }
        public Gameboy(CoreComm comm, GameInfo game, byte[] file, Gameboy.GambatteSettings settings, Gameboy.GambatteSyncSettings syncSettings, bool deterministic)
        {
            var ser = new BasicServiceProvider(this);

            ser.Register <IDisassemblable>(new GBDisassembler());
            ServiceProvider = ser;
            Tracer          = new TraceBuffer
            {
                Header = "Z80: PC, opcode, registers (A, B, C, D, E, F, H, L, LY, SP, CY)"
            };
            ser.Register <ITraceable>(Tracer);
            InitMemoryCallbacks();

            ThrowExceptionForBadRom(file);
            BoardName = MapperName(file);

            DeterministicEmulation = deterministic;

            GambatteState = LibGambatte.gambatte_create();

            if (GambatteState == IntPtr.Zero)
            {
                throw new InvalidOperationException($"{nameof(LibGambatte.gambatte_create)}() returned null???");
            }

            Console.WriteLine(game.System);

            try
            {
                _syncSettings = (GambatteSyncSettings)syncSettings ?? new GambatteSyncSettings();

                LibGambatte.LoadFlags flags = 0;

                switch (_syncSettings.ConsoleMode)
                {
                case GambatteSyncSettings.ConsoleModeType.GB:
                    flags |= LibGambatte.LoadFlags.FORCE_DMG;
                    break;

                case GambatteSyncSettings.ConsoleModeType.GBC:
                    break;

                case GambatteSyncSettings.ConsoleModeType.GBA:
                    flags |= LibGambatte.LoadFlags.GBA_CGB;
                    break;

                default:
                    if (game.System == "GB")
                    {
                        flags |= LibGambatte.LoadFlags.FORCE_DMG;
                    }
                    break;
                }

                if (_syncSettings.MulticartCompat)
                {
                    flags |= LibGambatte.LoadFlags.MULTICART_COMPAT;
                }

                if (LibGambatte.gambatte_load(GambatteState, file, (uint)file.Length, flags) != 0)
                {
                    throw new InvalidOperationException($"{nameof(LibGambatte.gambatte_load)}() returned non-zero (is this not a gb or gbc rom?)");
                }

                byte[] bios;
                string biosSystemId;
                string biosId;
                if ((flags & LibGambatte.LoadFlags.FORCE_DMG) == LibGambatte.LoadFlags.FORCE_DMG)
                {
                    biosSystemId = "GB";
                    biosId       = "World";
                    IsCgb        = false;
                }
                else
                {
                    biosSystemId = "GBC";
                    biosId       = _syncSettings.ConsoleMode == GambatteSyncSettings.ConsoleModeType.GBA ? "AGB" : "World";
                    IsCgb        = true;
                }

                if (_syncSettings.EnableBIOS)
                {
                    bios = comm.CoreFileProvider.GetFirmware(biosSystemId, biosId, true, "BIOS Not Found, Cannot Load.  Change SyncSettings to run without BIOS.");
                }
                else
                {
                    var builtinBios = (biosSystemId, biosId) switch {
                        ("GB", "World") => Resources.FastDmgBoot,
                        ("GBC", "World") => Resources.FastCgbBoot,
                        ("GBC", "AGB") => Resources.FastAgbBoot,
                        (_, _) => throw new Exception("Internal GB Error (BIOS??)"),
                    };
                    bios = BizHawk.Common.Util.DecompressGzipFile(new MemoryStream(builtinBios.Value, false));
                }

                if (LibGambatte.gambatte_loadbios(GambatteState, bios, (uint)bios.Length) != 0)
                {
                    throw new InvalidOperationException($"{nameof(LibGambatte.gambatte_loadbios)}() returned non-zero (bios error)");
                }

                // set real default colors (before anyone mucks with them at all)
                PutSettings((GambatteSettings)settings ?? new GambatteSettings());

                InitSound();

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

                InputCallback = new LibGambatte.InputGetter(ControllerCallback);

                LibGambatte.gambatte_setinputgetter(GambatteState, InputCallback);

                InitMemoryDomains();

                RomDetails = $"{game.Name}\r\nSHA1:{file.HashSHA1()}\r\nMD5:{file.HashMD5()}\r\n";

                byte[] buff = new byte[32];
                LibGambatte.gambatte_romtitle(GambatteState, buff);
                string romname = System.Text.Encoding.ASCII.GetString(buff);
                Console.WriteLine("Core reported rom name: {0}", romname);

                if (!DeterministicEmulation && _syncSettings.RealTimeRTC)
                {
                    LibGambatte.gambatte_settimemode(GambatteState, false);
                }
                LibGambatte.gambatte_setrtcdivisoroffset(GambatteState, _syncSettings.RTCDivisorOffset);

                _cdCallback = new LibGambatte.CDCallback(CDCallbackProc);

                NewSaveCoreSetBuff();
            }
예제 #44
0
        public GPGX(CoreLoadParameters <GPGXSettings, GPGXSyncSettings> lp)
        {
            LoadCallback   = new LibGPGX.load_archive_cb(load_archive);
            _inputCallback = new LibGPGX.input_cb(input_callback);
            InitMemCallbacks();             // ExecCallback, ReadCallback, WriteCallback
            CDCallback         = new LibGPGX.CDCallback(CDCallbackProc);
            cd_callback_handle = new LibGPGX.cd_read_cb(CDRead);

            ServiceProvider = new BasicServiceProvider(this);
            // this can influence some things internally (autodetect romtype, etc)
            string romextension = "GEN";

            // three or six button?
            // http://www.sega-16.com/forum/showthread.php?4398-Forgotten-Worlds-giving-you-GAME-OVER-immediately-Fix-inside&highlight=forgotten%20worlds

            //hack, don't use
            if (lp.Roms.FirstOrDefault()?.RomData.Length > 32 * 1024 * 1024)
            {
                throw new InvalidOperationException("ROM too big!  Did you try to load a CD as a ROM?");
            }

            _elf = new WaterboxHost(new WaterboxOptions
            {
                Path                       = lp.Comm.CoreFileProvider.DllPath(),
                Filename                   = "gpgx.wbx",
                SbrkHeapSizeKB             = 512,
                SealedHeapSizeKB           = 4 * 1024,
                InvisibleHeapSizeKB        = 4 * 1024,
                PlainHeapSizeKB            = 34 * 1024,
                MmapHeapSizeKB             = 1 * 1024,
                SkipCoreConsistencyCheck   = lp.Comm.CorePreferences.HasFlag(CoreComm.CorePreferencesFlags.WaterboxCoreConsistencyCheck),
                SkipMemoryConsistencyCheck = lp.Comm.CorePreferences.HasFlag(CoreComm.CorePreferencesFlags.WaterboxMemoryConsistencyCheck),
            });

            var callingConventionAdapter = CallingConventionAdapters.MakeWaterbox(new Delegate[]
            {
                LoadCallback, _inputCallback, ExecCallback, ReadCallback, WriteCallback,
                CDCallback, cd_callback_handle,
            }, _elf);

            using (_elf.EnterExit())
            {
                Core          = BizInvoker.GetInvoker <LibGPGX>(_elf, _elf, callingConventionAdapter);
                _syncSettings = lp.SyncSettings ?? new GPGXSyncSettings();
                _settings     = lp.Settings ?? new GPGXSettings();

                CoreComm = lp.Comm;

                _romfile = lp.Roms.FirstOrDefault()?.RomData;

                if (lp.Discs.Count > 0)
                {
                    _cds       = lp.Discs.Select(d => d.DiscData).ToArray();
                    _cdReaders = _cds.Select(c => new DiscSectorReader(c)).ToArray();
                    Core.gpgx_set_cdd_callback(cd_callback_handle);
                    DriveLightEnabled = true;
                }

                LibGPGX.INPUT_SYSTEM system_a = SystemForSystem(_syncSettings.ControlTypeLeft);
                LibGPGX.INPUT_SYSTEM system_b = SystemForSystem(_syncSettings.ControlTypeRight);

                var initResult = Core.gpgx_init(romextension, LoadCallback, _syncSettings.GetNativeSettings(lp.Game));

                if (!initResult)
                {
                    throw new Exception($"{nameof(Core.gpgx_init)}() failed");
                }

                {
                    int fpsnum = 60;
                    int fpsden = 1;
                    Core.gpgx_get_fps(ref fpsnum, ref fpsden);
                    VsyncNumerator   = fpsnum;
                    VsyncDenominator = fpsden;
                    Region           = VsyncNumerator / VsyncDenominator > 55 ? DisplayType.NTSC : DisplayType.PAL;
                }

                // when we call Seal, ANY pointer passed from managed code must be 0.
                // this is so the initial state is clean
                // the only two pointers set so far are LoadCallback, which the core zeroed itself,
                // and CdCallback
                Core.gpgx_set_cdd_callback(null);
                _elf.Seal();
                Core.gpgx_set_cdd_callback(cd_callback_handle);

                SetControllerDefinition();

                // pull the default video size from the core
                UpdateVideo();

                SetMemoryDomains();

                Core.gpgx_set_input_callback(_inputCallback);

                // process the non-init settings now
                PutSettings(_settings);

                KillMemCallbacks();

                _tracer = new GPGXTraceBuffer(this, _memoryDomains, this);
                (ServiceProvider as BasicServiceProvider).Register <ITraceable>(_tracer);
            }

            _romfile = null;
        }
예제 #45
0
        public Gameboy(CoreComm comm, GameInfo game, byte[] file, object Settings, object SyncSettings, bool deterministic)
        {
            var ser = new BasicServiceProvider(this);

            ser.Register <IDisassemblable>(new GBDisassembler());
            ServiceProvider = ser;
            Tracer          = new TraceBuffer
            {
                Header = "Z80: PC, opcode, registers (A, B, C, D, E, F, H, L, LY, SP, CY)"
            };
            ser.Register <ITraceable>(Tracer);
            InitMemoryCallbacks();
            CoreComm = comm;

            comm.VsyncNum            = 262144;
            comm.VsyncDen            = 4389;
            comm.RomStatusAnnotation = null;
            comm.RomStatusDetails    = null;
            comm.NominalWidth        = 160;
            comm.NominalHeight       = 144;

            ThrowExceptionForBadRom(file);
            BoardName = MapperName(file);

            DeterministicEmulation = deterministic;

            GambatteState = LibGambatte.gambatte_create();

            if (GambatteState == IntPtr.Zero)
            {
                throw new InvalidOperationException("gambatte_create() returned null???");
            }

            try
            {
                this._syncSettings = (GambatteSyncSettings)SyncSettings ?? new GambatteSyncSettings();
                // copy over non-loadflag syncsettings now; they won't take effect if changed later
                zerotime      = (uint)this._syncSettings.RTCInitialTime;
                real_rtc_time = DeterministicEmulation ? false : this._syncSettings.RealTimeRTC;

                LibGambatte.LoadFlags flags = 0;

                if (this._syncSettings.ForceDMG)
                {
                    flags |= LibGambatte.LoadFlags.FORCE_DMG;
                }
                if (this._syncSettings.GBACGB)
                {
                    flags |= LibGambatte.LoadFlags.GBA_CGB;
                }
                if (this._syncSettings.MulticartCompat)
                {
                    flags |= LibGambatte.LoadFlags.MULTICART_COMPAT;
                }

                if (LibGambatte.gambatte_load(GambatteState, file, (uint)file.Length, GetCurrentTime(), flags) != 0)
                {
                    throw new InvalidOperationException("gambatte_load() returned non-zero (is this not a gb or gbc rom?)");
                }

                // set real default colors (before anyone mucks with them at all)
                PutSettings((GambatteSettings)Settings ?? new GambatteSettings());

                InitSound();

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

                InputCallback = new LibGambatte.InputGetter(ControllerCallback);

                LibGambatte.gambatte_setinputgetter(GambatteState, InputCallback);

                InitMemoryDomains();

                CoreComm.RomStatusDetails = string.Format("{0}\r\nSHA1:{1}\r\nMD5:{2}\r\n",
                                                          game.Name,
                                                          file.HashSHA1(),
                                                          file.HashMD5());

                {
                    byte[] buff = new byte[32];
                    LibGambatte.gambatte_romtitle(GambatteState, buff);
                    string romname = System.Text.Encoding.ASCII.GetString(buff);
                    Console.WriteLine("Core reported rom name: {0}", romname);
                }

                TimeCallback = new LibGambatte.RTCCallback(GetCurrentTime);
                LibGambatte.gambatte_setrtccallback(GambatteState, TimeCallback);

                CDCallback = new LibGambatte.CDCallback(CDCallbackProc);

                NewSaveCoreSetBuff();
            }
            catch
            {
                Dispose();
                throw;
            }
        }
예제 #46
0
        public Gameboy(CoreComm comm, GameInfo game, byte[] file, object settings, object syncSettings, bool deterministic)
        {
            var ser = new BasicServiceProvider(this);

            ser.Register <IDisassemblable>(new GBDisassembler());
            ServiceProvider = ser;
            Tracer          = new TraceBuffer
            {
                Header = "Z80: PC, opcode, registers (A, B, C, D, E, F, H, L, LY, SP, CY)"
            };
            ser.Register <ITraceable>(Tracer);
            InitMemoryCallbacks();
            CoreComm = comm;

            comm.RomStatusAnnotation = null;
            comm.RomStatusDetails    = null;
            comm.NominalWidth        = 160;
            comm.NominalHeight       = 144;

            ThrowExceptionForBadRom(file);
            BoardName = MapperName(file);

            DeterministicEmulation = deterministic;

            GambatteState = LibGambatte.gambatte_create();

            if (GambatteState == IntPtr.Zero)
            {
                throw new InvalidOperationException("gambatte_create() returned null???");
            }

            Console.WriteLine(game.System);

            byte[] BiosRom;

            if (game.System == "GB")
            {
                BiosRom = comm.CoreFileProvider.GetFirmware("GB", "World", false);
            }
            else
            {
                BiosRom = comm.CoreFileProvider.GetFirmware("GBC", "World", false);
            }

            int bios_length = BiosRom == null ? 0 : BiosRom.Length;

            try
            {
                _syncSettings = (GambatteSyncSettings)syncSettings ?? new GambatteSyncSettings();

                // copy over non-loadflag syncsettings now; they won't take effect if changed later
                zerotime = (uint)_syncSettings.RTCInitialTime;

                real_rtc_time = !DeterministicEmulation && _syncSettings.RealTimeRTC;

                LibGambatte.LoadFlags flags = 0;

                switch (_syncSettings.ConsoleMode)
                {
                case GambatteSyncSettings.ConsoleModeType.GB:
                    flags |= LibGambatte.LoadFlags.FORCE_DMG;
                    // we need to change the BIOS to GB bios
                    if (game.System == "GBC")
                    {
                        BiosRom     = comm.CoreFileProvider.GetFirmware("GB", "World", false);
                        bios_length = BiosRom.Length;
                    }
                    break;

                case GambatteSyncSettings.ConsoleModeType.GBC:
                    BiosRom     = comm.CoreFileProvider.GetFirmware("GBC", "World", false);
                    bios_length = BiosRom.Length;
                    break;

                default:
                    if (game.System == "GB")
                    {
                        flags |= LibGambatte.LoadFlags.FORCE_DMG;
                    }
                    break;
                }

                if (_syncSettings.EnableBIOS && BiosRom == null)
                {
                    throw new MissingFirmwareException("Boot Rom not found");
                }

                // to disable BIOS loading into gambatte, just set bios_length to 0
                if (!_syncSettings.EnableBIOS)
                {
                    bios_length = 0;
                }

                if (_syncSettings.GBACGB)
                {
                    flags |= LibGambatte.LoadFlags.GBA_CGB;
                }

                if (_syncSettings.MulticartCompat)
                {
                    flags |= LibGambatte.LoadFlags.MULTICART_COMPAT;
                }

                if (LibGambatte.gambatte_load(GambatteState, file, (uint)file.Length, BiosRom, (uint)bios_length, GetCurrentTime(), flags) != 0)
                {
                    throw new InvalidOperationException("gambatte_load() returned non-zero (is this not a gb or gbc rom?)");
                }

                // set real default colors (before anyone mucks with them at all)
                PutSettings((GambatteSettings)settings ?? new GambatteSettings());

                InitSound();

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

                InputCallback = new LibGambatte.InputGetter(ControllerCallback);

                LibGambatte.gambatte_setinputgetter(GambatteState, InputCallback);

                InitMemoryDomains();

                CoreComm.RomStatusDetails = $"{game.Name}\r\nSHA1:{file.HashSHA1()}\r\nMD5:{file.HashMD5()}\r\n";

                byte[] buff = new byte[32];
                LibGambatte.gambatte_romtitle(GambatteState, buff);
                string romname = System.Text.Encoding.ASCII.GetString(buff);
                Console.WriteLine("Core reported rom name: {0}", romname);

                TimeCallback = new LibGambatte.RTCCallback(GetCurrentTime);
                LibGambatte.gambatte_setrtccallback(GambatteState, TimeCallback);

                _cdCallback = new LibGambatte.CDCallback(CDCallbackProc);

                NewSaveCoreSetBuff();
            }
            catch
            {
                Dispose();
                throw;
            }
        }