public A7800Hawk(CoreComm comm, GameInfo game, byte[] rom, string gameDbFn) { var ser = new BasicServiceProvider(this); maria = new Maria(); tia = new TIA(); m6532 = new M6532(); cpu = new MOS6502X { ReadMemory = ReadMemory, WriteMemory = WriteMemory, PeekMemory = ReadMemory, DummyReadMemory = ReadMemory, OnExecFetch = ExecFetch }; maria = new Maria { ReadMemory = ReadMemory }; CoreComm = comm; _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."); 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; } _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"); } } else { throw new Exception("ROM not in gamedb"); } Reset_Mapper(s_mapper); _rom = rom; _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) { maria._frameHz = 50; maria._screen_width = 320; maria._screen_height = 313; maria._palette = PALPalette; } else { maria._frameHz = 60; maria._screen_width = 320; maria._screen_height = 263; maria._palette = NTSCPalette; } maria.Core = this; m6532.Core = this; tia.Core = this; ser.Register <IVideoProvider>(maria); ser.Register <ISoundProvider>(tia); ServiceProvider = ser; _tracer = new TraceBuffer { Header = cpu.TraceHeader }; ser.Register <ITraceable>(_tracer); SetupMemoryDomains(); HardReset(); }
public A7800Hawk(CoreComm comm, GameInfo game, byte[] rom, string gameDbFn, 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 }; CoreComm = comm; _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 no_hs; bool.TryParse(dict["No_HS"], out 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); SetupMemoryDomains(); ser.Register <IDisassemblable>(cpu); HardReset(); }
public A7800Hawk(CoreComm comm, byte[] rom, A7800Hawk.A7800Settings settings, A7800Hawk.A7800SyncSettings 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); var highscoreBios = comm.CoreFileProvider.GetFirmware(new("A78", "Bios_HSC"), "Some functions may not work without the high score BIOS."); var palBios = comm.CoreFileProvider.GetFirmware(new("A78", "Bios_PAL"), "The game will not run if the correct region BIOS is not available."); var ntscBios = comm.CoreFileProvider.GetFirmware(new("A78", "Bios_NTSC"), "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 s_mapper = null; var hash_md5 = MD5Checksum.ComputePrefixedHex(rom); var gi = Database.CheckDatabase(hash_md5); if (gi != null) { var dict = gi.GetOptions(); if (dict.ContainsKey("PAL")) { _isPAL = true; } if (!dict.TryGetValue("board", out s_mapper)) { throw new Exception("No Board selected for this game"); } // check if the game uses pokey or RAM if (dict.TryGetValue("RAM", out var cartRAMStr)) { int.TryParse(cartRAMStr, out cart_RAM); } if (dict.TryGetValue("Pokey", out var pokeyStr)) { bool.TryParse(pokeyStr, out is_pokey); } if (dict.TryGetValue("Pokey_450", out var pokey450Str)) { bool.TryParse(pokey450Str, out is_pokey_450); } // 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.TryGetValue("No_HS", out var noHSStr)) { bool.TryParse(noHSStr, 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; // the homebrew game serpentine requires extra RAM, but in the alternative style if (hash_md5 == RomChecksums.Serpentine) { cart_RAM = 16; } } } else { s_mapper = "0"; } if (cart_2.Bit(0)) { is_pokey = true; } // the homebrew game serpentine requires the pokey chip to be available at the alternative location 0x450 if (cart_2.Bit(6)) { is_pokey_450 = 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 (hash_md5 == RomChecksums.KaratekaPAL) { 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(cpu.TraceHeader); ser.Register <ITraceable>(_tracer); ser.Register <IStatable>(new StateSerializer(SyncState)); SetupMemoryDomains(); ser.Register <IDisassemblable>(cpu); HardReset(); }