2012-03-07 00:40:20 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.IO;
|
|
|
|
|
|
2013-11-04 00:36:15 +00:00
|
|
|
|
using BizHawk.Common;
|
2013-11-04 01:06:36 +00:00
|
|
|
|
using BizHawk.Emulation.Common;
|
2013-11-04 00:36:15 +00:00
|
|
|
|
|
2012-03-07 00:40:20 +00:00
|
|
|
|
namespace BizHawk
|
|
|
|
|
{
|
2012-04-02 20:55:29 +00:00
|
|
|
|
public partial class Atari2600 : IEmulator
|
2012-03-07 00:40:20 +00:00
|
|
|
|
{
|
|
|
|
|
public string SystemId { get { return "A26"; } }
|
2012-03-30 00:35:15 +00:00
|
|
|
|
public GameInfo game;
|
2012-03-07 00:40:20 +00:00
|
|
|
|
|
2013-08-24 16:54:22 +00:00
|
|
|
|
public string BoardName { get { return mapper.GetType().Name; } }
|
|
|
|
|
|
2012-12-10 00:43:43 +00:00
|
|
|
|
public CoreComm CoreComm { get; private set; }
|
2012-04-02 20:55:29 +00:00
|
|
|
|
public IVideoProvider VideoProvider { get { return tia; } }
|
2012-10-10 00:56:48 +00:00
|
|
|
|
public ISoundProvider SoundProvider { get { return dcfilter; } }
|
sound api changes. added a new ISyncSoundProvider, which works similarly to ISoundProvider except the source (not the sink) determines the number of samples to process. Added facilities to metaspu, dcfilter, speexresampler to work with ISyncSoundProvider. Add ISyncSoundProvider to IEmulator. All IEmulators must provide sync sound, but they need not provide async sound. When async is needed and an IEmulator doesn't provide it, the frontend will wrap it in a vecna metaspu. SNES, GB changed to provide sync sound only. All other emulator cores mostly unchanged; they just provide stub fakesync alongside async, for now. For the moment, the only use of the sync sound is for realtime audio throttling, where it works and sounds quite nice. In the future, sync sound will be supported for AV dumping as well.
2012-10-11 00:44:59 +00:00
|
|
|
|
public ISyncSoundProvider SyncSoundProvider { get { return new FakeSyncSound(dcfilter, 735); } }
|
|
|
|
|
public bool StartAsyncSound() { return true; }
|
|
|
|
|
public void EndAsyncSound() { }
|
2012-03-30 00:35:15 +00:00
|
|
|
|
|
2012-12-10 00:43:43 +00:00
|
|
|
|
public Atari2600(CoreComm comm, GameInfo game, byte[] rom)
|
2012-03-07 00:40:20 +00:00
|
|
|
|
{
|
2012-12-10 00:43:43 +00:00
|
|
|
|
CoreComm = comm;
|
2013-04-16 00:42:57 +00:00
|
|
|
|
var domains = new List<MemoryDomain>(1)
|
|
|
|
|
{
|
2013-11-04 02:11:40 +00:00
|
|
|
|
new MemoryDomain("Main RAM", 128, MemoryDomain.Endian.Little, addr => ram[addr & 127], (addr, value) => ram[addr & 127] = value),
|
|
|
|
|
new MemoryDomain("TIA", 16, MemoryDomain.Endian.Little, addr => tia.ReadMemory((ushort) addr, true),
|
2013-04-16 00:42:57 +00:00
|
|
|
|
(addr, value) => tia.WriteMemory((ushort) addr, value)),
|
2013-11-04 02:11:40 +00:00
|
|
|
|
new MemoryDomain("PIA", 1024, MemoryDomain.Endian.Little, addr => m6532.ReadMemory((ushort) addr, true),
|
2013-04-16 00:42:57 +00:00
|
|
|
|
(addr, value) => m6532.WriteMemory((ushort) addr, value)),
|
2013-11-04 02:11:40 +00:00
|
|
|
|
new MemoryDomain("System Bus", 8192, MemoryDomain.Endian.Little, addr => mapper.PeekMemory((ushort) addr), (addr, value) => { })
|
2013-04-16 00:42:57 +00:00
|
|
|
|
};
|
2013-11-06 02:15:29 +00:00
|
|
|
|
memoryDomains = new MemoryDomainList(domains);
|
2012-12-10 00:43:43 +00:00
|
|
|
|
CoreComm.CpuTraceAvailable = true;
|
2012-03-07 00:40:20 +00:00
|
|
|
|
this.rom = rom;
|
2012-03-30 00:35:15 +00:00
|
|
|
|
this.game = game;
|
|
|
|
|
Console.WriteLine("Game uses mapper " + game.GetOptionsDict()["m"]);
|
2012-03-07 00:40:20 +00:00
|
|
|
|
HardReset();
|
|
|
|
|
}
|
2013-11-11 03:20:33 +00:00
|
|
|
|
|
|
|
|
|
public List<KeyValuePair<string, int>> GetCpuFlagsAndRegisters()
|
|
|
|
|
{
|
2013-11-11 03:44:37 +00:00
|
|
|
|
return new List<KeyValuePair<string, int>>
|
|
|
|
|
{
|
|
|
|
|
new KeyValuePair<string, int>("A", cpu.A),
|
|
|
|
|
new KeyValuePair<string, int>("X", cpu.X),
|
|
|
|
|
new KeyValuePair<string, int>("Y", cpu.Y),
|
|
|
|
|
new KeyValuePair<string, int>("S", cpu.S),
|
|
|
|
|
new KeyValuePair<string, int>("PC", cpu.PC),
|
|
|
|
|
new KeyValuePair<string, int>("Flag C", cpu.FlagC ? 1 : 0),
|
|
|
|
|
new KeyValuePair<string, int>("Flag Z", cpu.FlagZ ? 1 : 0),
|
|
|
|
|
new KeyValuePair<string, int>("Flag I", cpu.FlagI ? 1 : 0),
|
|
|
|
|
new KeyValuePair<string, int>("Flag D", cpu.FlagD ? 1 : 0),
|
|
|
|
|
new KeyValuePair<string, int>("Flag B", cpu.FlagB ? 1 : 0),
|
|
|
|
|
new KeyValuePair<string, int>("Flag V", cpu.FlagV ? 1 : 0),
|
|
|
|
|
new KeyValuePair<string, int>("Flag N", cpu.FlagN ? 1 : 0),
|
|
|
|
|
new KeyValuePair<string, int>("Flag T", cpu.FlagT ? 1 : 0)
|
|
|
|
|
};
|
2013-11-11 03:20:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-11-03 16:29:51 +00:00
|
|
|
|
public void ResetCounters()
|
2012-03-07 00:40:20 +00:00
|
|
|
|
{
|
2012-03-23 02:55:46 +00:00
|
|
|
|
_frame = 0;
|
2012-11-25 15:41:40 +00:00
|
|
|
|
_lagcount = 0;
|
|
|
|
|
_islag = false;
|
2012-03-07 00:40:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static readonly ControllerDefinition Atari2600ControllerDefinition = new ControllerDefinition
|
|
|
|
|
{
|
|
|
|
|
Name = "Atari 2600 Basic Controller",
|
|
|
|
|
BoolButtons =
|
|
|
|
|
{
|
2012-03-22 06:33:28 +00:00
|
|
|
|
"P1 Up", "P1 Down", "P1 Left", "P1 Right", "P1 Button",
|
|
|
|
|
"P2 Up", "P2 Down", "P2 Left", "P2 Right", "P2 Button",
|
2012-03-30 16:40:52 +00:00
|
|
|
|
"Reset", "Select"
|
2012-03-07 00:40:20 +00:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void SyncState(Serializer ser)
|
|
|
|
|
{
|
2012-11-28 18:27:14 +00:00
|
|
|
|
ser.BeginSection("A2600");
|
2012-03-07 00:40:20 +00:00
|
|
|
|
cpu.SyncState(ser);
|
|
|
|
|
ser.Sync("ram", ref ram, false);
|
2012-03-23 02:55:46 +00:00
|
|
|
|
ser.Sync("Lag", ref _lagcount);
|
|
|
|
|
ser.Sync("Frame", ref _frame);
|
2012-07-30 14:42:52 +00:00
|
|
|
|
ser.Sync("IsLag", ref _islag);
|
2012-03-30 02:34:47 +00:00
|
|
|
|
tia.SyncState(ser);
|
|
|
|
|
m6532.SyncState(ser);
|
2012-12-18 20:37:31 +00:00
|
|
|
|
ser.BeginSection("Mapper");
|
2012-03-30 00:35:15 +00:00
|
|
|
|
mapper.SyncState(ser);
|
2012-11-28 18:27:14 +00:00
|
|
|
|
ser.EndSection();
|
2012-12-18 20:37:31 +00:00
|
|
|
|
ser.EndSection();
|
2012-03-07 00:40:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ControllerDefinition ControllerDefinition { get { return Atari2600ControllerDefinition; } }
|
|
|
|
|
public IController Controller { get; set; }
|
|
|
|
|
|
2012-03-23 02:55:46 +00:00
|
|
|
|
public int Frame { get { return _frame; } set { _frame = value; } }
|
|
|
|
|
public int LagCount { get { return _lagcount; } set { _lagcount = value; } }
|
|
|
|
|
public bool IsLagFrame { get { return _islag; } }
|
|
|
|
|
private bool _islag = true;
|
2013-04-16 00:42:57 +00:00
|
|
|
|
private int _lagcount;
|
|
|
|
|
private int _frame;
|
2012-03-07 00:40:20 +00:00
|
|
|
|
|
2012-09-14 22:28:38 +00:00
|
|
|
|
public byte[] ReadSaveRam() { return null; }
|
|
|
|
|
public void StoreSaveRam(byte[] data) { }
|
|
|
|
|
public void ClearSaveRam() { }
|
2012-03-07 00:40:20 +00:00
|
|
|
|
public bool SaveRamModified { get; set; }
|
2012-09-14 22:28:38 +00:00
|
|
|
|
|
|
|
|
|
public bool DeterministicEmulation { get; set; }
|
2012-03-07 00:40:20 +00:00
|
|
|
|
public void SaveStateText(TextWriter writer) { SyncState(Serializer.CreateTextWriter(writer)); }
|
|
|
|
|
public void LoadStateText(TextReader reader) { SyncState(Serializer.CreateTextReader(reader)); }
|
|
|
|
|
public void SaveStateBinary(BinaryWriter bw) { SyncState(Serializer.CreateBinaryWriter(bw)); }
|
|
|
|
|
public void LoadStateBinary(BinaryReader br) { SyncState(Serializer.CreateBinaryReader(br)); }
|
|
|
|
|
|
|
|
|
|
public byte[] SaveStateBinary()
|
|
|
|
|
{
|
|
|
|
|
MemoryStream ms = new MemoryStream();
|
|
|
|
|
BinaryWriter bw = new BinaryWriter(ms);
|
|
|
|
|
SaveStateBinary(bw);
|
|
|
|
|
bw.Flush();
|
|
|
|
|
return ms.ToArray();
|
|
|
|
|
}
|
2012-09-14 22:28:38 +00:00
|
|
|
|
|
2013-05-06 20:51:28 +00:00
|
|
|
|
public bool BinarySaveStatesPreferred { get { return false; } }
|
|
|
|
|
|
2013-11-06 02:15:29 +00:00
|
|
|
|
private readonly MemoryDomainList memoryDomains;
|
|
|
|
|
public MemoryDomainList MemoryDomains { get { return memoryDomains; } }
|
2012-03-07 00:40:20 +00:00
|
|
|
|
public void Dispose() { }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|