diff --git a/BizHawk.Emulation/BizHawk.Emulation.csproj b/BizHawk.Emulation/BizHawk.Emulation.csproj index 91ccb77ab7..3f059f14f0 100644 --- a/BizHawk.Emulation/BizHawk.Emulation.csproj +++ b/BizHawk.Emulation/BizHawk.Emulation.csproj @@ -76,6 +76,8 @@ + + diff --git a/BizHawk.Emulation/Consoles/Atari/2600/Atari2600.Core.cs b/BizHawk.Emulation/Consoles/Atari/2600/Atari2600.Core.cs new file mode 100644 index 0000000000..170c56c9c1 --- /dev/null +++ b/BizHawk.Emulation/Consoles/Atari/2600/Atari2600.Core.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.IO; + +namespace BizHawk +{ + partial class Atari2600 + { + public byte[] ram = new byte[128]; + public byte[] rom; + public BizHawk.Emulation.CPUs.M6502.MOS6502 cpu; + + public byte ReadMemory(ushort addr) + { + return 0xFF; + } + + public void WriteMemory(ushort addr, byte value) + { + } + + public void HardReset() + { + cpu = new Emulation.CPUs.M6502.MOS6502(); + cpu.ReadMemory = ReadMemory; + cpu.WriteMemory = WriteMemory; + + //setup the system state here. for instance.. + cpu.PC = 0x0123; //set the initial PC + } + + public void FrameAdvance(bool render) + { + //clear the framebuffer (hack code) + if (render == false) return; + for (int i = 0; i < 256 * 192; i++) + frameBuffer[i] = 0; //black + + //run one frame's worth of cpu cyclees (i.e. do the emulation!) + //this should generate the framebuffer as it goes. + } + } +} \ No newline at end of file diff --git a/BizHawk.Emulation/Consoles/Atari/2600/Atari2600.cs b/BizHawk.Emulation/Consoles/Atari/2600/Atari2600.cs new file mode 100644 index 0000000000..8bf4e57451 --- /dev/null +++ b/BizHawk.Emulation/Consoles/Atari/2600/Atari2600.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; +using System.IO; + +namespace BizHawk +{ + public partial class Atari2600 : IEmulator, IVideoProvider, ISoundProvider + { + public string SystemId { get { return "A26"; } } + + private int[] frameBuffer = new int[256 * 192]; + public CoreInputComm CoreInputComm { get; set; } + public CoreOutputComm CoreOutputComm { get; private set; } + public IVideoProvider VideoProvider { get { return this; } } + public ISoundProvider SoundProvider { get { return this; } } + public Atari2600(GameInfo game, byte[] rom) + { + var domains = new List(1); + domains.Add(new MemoryDomain("Main RAM", 1, Endian.Little, addr => 0, (a, v) => { })); + memoryDomains = domains.AsReadOnly(); + CoreOutputComm = new CoreOutputComm(); + CoreInputComm = new CoreInputComm(); + this.rom = rom; + HardReset(); + } + public void ResetFrameCounter() + { + Frame = 0; + } + + public static readonly ControllerDefinition Atari2600ControllerDefinition = new ControllerDefinition + { + Name = "Atari 2600 Basic Controller", + BoolButtons = + { + "P1 Up", "P1 Down", "P1 Left", "P1 Right", "P1 Button" + } + }; + + void SyncState(Serializer ser) + { + cpu.SyncState(ser); + ser.Sync("ram", ref ram, false); + } + + public ControllerDefinition ControllerDefinition { get { return Atari2600ControllerDefinition; } } + public IController Controller { get; set; } + + public int Frame { get; set; } + public int LagCount { get { return 0; } set { return; } } + public bool IsLagFrame { get { return false; } } + + public byte[] SaveRam { get { return new byte[0]; } } + public bool DeterministicEmulation { get; set; } + public bool SaveRamModified { get; set; } + 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(); + } + public int[] GetVideoBuffer() { return frameBuffer; } + public int BufferWidth { get { return 256; } } + public int BufferHeight { get { return 192; } } + public int BackgroundColor { get { return 0; } } + public void GetSamples(short[] samples) { } + public void DiscardSamples() { } + public int MaxVolume { get; set; } + private IList memoryDomains; + public IList MemoryDomains { get { return memoryDomains; } } + public MemoryDomain MainMemory { get { return memoryDomains[0]; } } + public void Dispose() { } + } + +} diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/IC_74x377.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/IC_74x377.cs index d3acd82f7d..22121c3431 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/IC_74x377.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/IC_74x377.cs @@ -57,6 +57,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo { byte old_value = value; value &= ReadPRG(addr); + //Bible Adventures (Unl) (V1.3) [o1].nes will exercise this bus conflict, but not really test it. (works without bus conflict emulation Debug.Assert(old_value == value, "Found a test case of Discrete_74x377 bus conflict. please report."); } diff --git a/BizHawk.Emulation/Database/Database.cs b/BizHawk.Emulation/Database/Database.cs index de035ed5e2..8cfa1bf66e 100644 --- a/BizHawk.Emulation/Database/Database.cs +++ b/BizHawk.Emulation/Database/Database.cs @@ -136,6 +136,7 @@ namespace BizHawk case ".GEN": case ".SMD": Game.System = "GEN"; break; case ".NES": Game.System = "NES"; break; + case ".A26": Game.System = "A26"; break; } Game.Name = Path.GetFileNameWithoutExtension(fileName).Replace('_', ' '); diff --git a/BizHawk.MultiClient/Config.cs b/BizHawk.MultiClient/Config.cs index d465edb390..a91ad69340 100644 --- a/BizHawk.MultiClient/Config.cs +++ b/BizHawk.MultiClient/Config.cs @@ -21,6 +21,9 @@ GenesisController[0] = new GenControllerTemplate(true); GenesisAutoController[0] = new GenControllerTemplate(true); + Atari2600Controller[0] = new Atari2600ControllerTemplate(true); + Atari2600AutoController[0] = new Atari2600ControllerTemplate(true); + NESAutoController[0] = new NESControllerTemplate(false); NESAutoController[1] = new NESControllerTemplate(false); NESAutoController[2] = new NESControllerTemplate(false); @@ -440,15 +443,19 @@ public SMSControllerTemplate[] SMSAutoController = new SMSControllerTemplate[2]; // PCEngine Settings - public bool PceSpriteLimit = false; - public bool PceEqualizeVolume = false; - public bool PceArcadeCardRewindHack = true; + public bool PceSpriteLimit = false; + public bool PceEqualizeVolume = false; + public bool PceArcadeCardRewindHack = true; public PCEControllerTemplate[] PCEController = new PCEControllerTemplate[5]; public PCEControllerTemplate[] PCEAutoController = new PCEControllerTemplate[5]; // Genesis Settings - public GenControllerTemplate[] GenesisController = new GenControllerTemplate[1]; - public GenControllerTemplate[] GenesisAutoController = new GenControllerTemplate[1]; + public GenControllerTemplate[] GenesisController = new GenControllerTemplate[1]; + public GenControllerTemplate[] GenesisAutoController = new GenControllerTemplate[1]; + + //Atari 2600 Settings + public Atari2600ControllerTemplate[] Atari2600Controller = new Atari2600ControllerTemplate[1]; + public Atari2600ControllerTemplate[] Atari2600AutoController = new Atari2600ControllerTemplate[1]; //GameBoy Settings public NESControllerTemplate GameBoyController = new NESControllerTemplate(true); @@ -661,6 +668,31 @@ } } + + public class Atari2600ControllerTemplate + { + public string Up = ""; + public string Down = ""; + public string Left = ""; + public string Right = ""; + public string Button = ""; + public bool Enabled; + + public Atari2600ControllerTemplate() { } + public Atari2600ControllerTemplate(bool defaults) + { + if (defaults) + { + Enabled = true; + Up = "UpArrow, J1 Up"; + Down = "DownArrow, J1 Down"; + Left = "LeftArrow, J1 Left"; + Right = "RightArrow, J1 Right"; + Button = "Z, J1 B1"; + } + } + } + public class TI83ControllerTemplate { public string _0; diff --git a/BizHawk.MultiClient/Global.cs b/BizHawk.MultiClient/Global.cs index 02fb09138f..ebeaa269d9 100644 --- a/BizHawk.MultiClient/Global.cs +++ b/BizHawk.MultiClient/Global.cs @@ -22,6 +22,7 @@ namespace BizHawk.MultiClient public static Controller TI83Controls; public static Controller NESControls; public static Controller GBControls; + public static Controller Atari2600Controls; public static Controller NullControls; public static CheatList CheatList; @@ -31,6 +32,7 @@ namespace BizHawk.MultiClient public static AutofireController AutofirePCEControls; public static AutofireController AutofireGBControls; public static AutofireController AutofireGenControls; + public static AutofireController AutofireAtari2600Controls; public static readonly Dictionary> BUTTONS = new Dictionary>() { @@ -80,7 +82,15 @@ namespace BizHawk.MultiClient {"GRAPH", "G"}, {"TRACE", "t"}, {"ZOOM", "Z"}, {"WINDOW", "W"}, {"Y", "Y"}, {"2ND", "&"}, {"MODE", "O"}, {"DEL", "D"}, {"COMMA", ","}, {"SIN", "S"} } + }, + { + "Atari 2600 Basic Controller", new Dictionary() + { + {"Up", "U"}, {"Down", "D"}, {"Left", "L"}, {"Right", "R"}, {"Button", "B"} + } } + + }; public static readonly Dictionary> COMMANDS = new Dictionary>() { @@ -95,7 +105,7 @@ namespace BizHawk.MultiClient public static readonly Dictionary PLAYERS = new Dictionary() { {"Gameboy Controller", 1}, {"Genesis 3-Button Controller", 2}, {"NES Controller", 4}, - {"PC Engine Controller", 5}, {"SMS Controller", 2}, {"TI83 Controller", 1} + {"PC Engine Controller", 5}, {"SMS Controller", 2}, {"TI83 Controller", 1}, {"Atari 2600 Basic Controller", 1} }; /// diff --git a/BizHawk.MultiClient/MainForm.cs b/BizHawk.MultiClient/MainForm.cs index 12272cd77d..42c558d427 100644 --- a/BizHawk.MultiClient/MainForm.cs +++ b/BizHawk.MultiClient/MainForm.cs @@ -651,17 +651,21 @@ namespace BizHawk.MultiClient genControls.BindMulti("P1 Start", Global.Config.GenesisController[0].Start); Global.GenControls = genControls; - var agenControls = new AutofireController(Genesis.GenesisController); - agbControls.Autofire = true; - genControls.BindMulti("P1 Up", Global.Config.GenesisAutoController[0].Up); - genControls.BindMulti("P1 Left", Global.Config.GenesisAutoController[0].Left); - genControls.BindMulti("P1 Right", Global.Config.GenesisAutoController[0].Right); - genControls.BindMulti("P1 Down", Global.Config.GenesisAutoController[0].Down); - genControls.BindMulti("P1 A", Global.Config.GenesisAutoController[0].A); - genControls.BindMulti("P1 B", Global.Config.GenesisAutoController[0].B); - genControls.BindMulti("P1 C", Global.Config.GenesisAutoController[0].C); - genControls.BindMulti("P1 Start", Global.Config.GenesisAutoController[0].Start); - Global.AutofireGenControls = agenControls; + var a2600Controls = new Controller(Atari2600.Atari2600ControllerDefinition); + a2600Controls.BindMulti("P1 Up", Global.Config.Atari2600Controller[0].Up); + a2600Controls.BindMulti("P1 Left", Global.Config.Atari2600Controller[0].Left); + a2600Controls.BindMulti("P1 Right", Global.Config.Atari2600Controller[0].Right); + a2600Controls.BindMulti("P1 Down", Global.Config.Atari2600Controller[0].Down); + a2600Controls.BindMulti("P1 Button", Global.Config.Atari2600Controller[0].Button); + Global.Atari2600Controls = a2600Controls; + + var autofireA2600Controls = new AutofireController(Atari2600.Atari2600ControllerDefinition); + autofireA2600Controls.BindMulti("P1 Up", Global.Config.Atari2600Controller[0].Up); + autofireA2600Controls.BindMulti("P1 Left", Global.Config.Atari2600Controller[0].Left); + autofireA2600Controls.BindMulti("P1 Right", Global.Config.Atari2600Controller[0].Right); + autofireA2600Controls.BindMulti("P1 Down", Global.Config.Atari2600Controller[0].Down); + autofireA2600Controls.BindMulti("P1 Button", Global.Config.Atari2600Controller[0].Button); + Global.AutofireAtari2600Controls = autofireA2600Controls; var TI83Controls = new Controller(TI83.TI83Controller); TI83Controls.BindMulti("0", Global.Config.TI83Controller[0]._0); @@ -843,6 +847,10 @@ namespace BizHawk.MultiClient Global.ActiveController = Global.SMSControls; Global.AutoFireController = Global.AutofireSMSControls; break; + case "A26": + Global.ActiveController = Global.Atari2600Controls; + Global.AutoFireController = Global.AutofireAtari2600Controls; + break; case "PCE": case "PCECD": Global.ActiveController = Global.PCEControls; @@ -1036,6 +1044,9 @@ namespace BizHawk.MultiClient if (Global.Config.SmsSpriteLimit) game.AddOption("SpriteLimit"); nextEmulator = new SMS(game, rom.RomData); break; + case "A26": + nextEmulator = new Atari2600(game, rom.FileData); + break; case "PCE": case "PCECD": case "SGX":