예제 #1
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);
                }

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

                ServiceProvider = ser;
                CoreComm        = comm;

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

                InitStates();
            }
            catch
            {
                LibmGBA.BizDestroy(core);
                throw;
            }
        }