From 27daa8246469325b917f0bb75c365fe9bf74a16a Mon Sep 17 00:00:00 2001 From: adelikat Date: Sat, 5 Apr 2014 14:13:05 +0000 Subject: [PATCH] Atari 2600 - a round of code cleanup and check in some files I neglected to in the past few commits, remove oldTIA.cs --- .../BizHawk.Emulation.Cores.csproj | 1 - .../Consoles/Atari/2600/Atari2600.Core.cs | 323 +++++---- .../Consoles/Atari/2600/Atari2600.cs | 245 ++++--- .../Consoles/Atari/2600/M6532.cs | 4 +- .../Consoles/Atari/2600/Mappers/Multicart.cs | 30 + .../Consoles/Atari/2600/Mappers/m0840.cs | 2 +- .../Consoles/Atari/2600/Mappers/m2K.cs | 2 +- .../Consoles/Atari/2600/Mappers/m3E.cs | 12 +- .../Consoles/Atari/2600/Mappers/m3F.cs | 8 +- .../Consoles/Atari/2600/Mappers/m4A50.cs | 8 +- .../Consoles/Atari/2600/Mappers/m4K.cs | 2 +- .../Consoles/Atari/2600/Mappers/mAR.cs | 2 +- .../Consoles/Atari/2600/Mappers/mCV.cs | 2 +- .../Consoles/Atari/2600/Mappers/mDPC.cs | 2 +- .../Consoles/Atari/2600/Mappers/mE0.cs | 8 +- .../Consoles/Atari/2600/Mappers/mE7.cs | 6 +- .../Consoles/Atari/2600/Mappers/mEF.cs | 2 +- .../Consoles/Atari/2600/Mappers/mEFSC.cs | 2 +- .../Consoles/Atari/2600/Mappers/mF0.cs | 2 +- .../Consoles/Atari/2600/Mappers/mF4.cs | 2 +- .../Consoles/Atari/2600/Mappers/mF4SC.cs | 2 +- .../Consoles/Atari/2600/Mappers/mF6.cs | 2 +- .../Consoles/Atari/2600/Mappers/mF6SC.cs | 2 +- .../Consoles/Atari/2600/Mappers/mF8.cs | 2 +- .../Consoles/Atari/2600/Mappers/mF8SC.cs | 2 +- .../Consoles/Atari/2600/Mappers/mFA.cs | 2 +- .../Consoles/Atari/2600/Mappers/mFA2.cs | 4 +- .../Consoles/Atari/2600/Mappers/mSB.cs | 16 + .../Consoles/Atari/2600/Mappers/mUA.cs | 2 +- .../Consoles/Atari/2600/Mappers/mX07.cs | 2 +- .../Consoles/Atari/2600/TIA.cs | 446 ++++++------- .../Consoles/Atari/2600/oldTIA.cs | 616 ------------------ 32 files changed, 621 insertions(+), 1142 deletions(-) create mode 100644 BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/Multicart.cs create mode 100644 BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mSB.cs delete mode 100644 BizHawk.Emulation.Cores/Consoles/Atari/2600/oldTIA.cs diff --git a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj index 79d314cdfa..db24d8af9f 100644 --- a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj +++ b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj @@ -206,7 +206,6 @@ - Code diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.Core.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.Core.cs index b3a47e9971..d2c709f9c0 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.Core.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.Core.cs @@ -4,75 +4,33 @@ using BizHawk.Common; using BizHawk.Emulation.Common; using BizHawk.Emulation.Cores.Components.M6502; - namespace BizHawk.Emulation.Cores.Atari.Atari2600 { - partial class Atari2600 + public partial class Atari2600 { - public byte[] rom; - public MOS6502X cpu; - public M6532 m6532; - public TIA tia; - public DCFilter dcfilter; - public byte[] ram = new byte[128]; - public MapperBase mapper; + private TIA _tia; + private DCFilter _dcfilter; + private MapperBase _mapper; + public byte[] Ram; - // The Atari 2600 memory mapper looks something like this...usually + public byte[] Rom { get; private set; } + public MOS6502X Cpu { get; private set; } + public M6532 M6532 { get; private set; } - // N/A Page # - // 000 0000000 000000 - - // 0x0000-0x003F - TIA Registers - // 0x0040-0x007F - TIA Registers (mirror) - // 0x0080-0x00FF - 6532 RAM - - // 0x0100-0x01FF - Mirror of 0x00FF - - // 0x0200-0x023F - TIA Registers (mirror) - // 0x0240-0x027F - TIA Registers (mirror) - - // 0x0280-0x029F - 6532 Registers - // 0x02A0-0x02BF - 6532 Registers (mirror) - // 0x02C0-0x02DF - 6532 Registers (mirror) - // 0x02E0-0x02FF - 6532 Registers (mirror) - - // 0x0300-0x033F - TIA Registers (mirror) - // 0x0340-0x037F - TIA Registers (mirror) - - // 0x0380-0x039F - 6532 Registers (mirror) - // 0x03A0-0x03BF - 6532 Registers (mirror) - // 0x03C0-0x03DF - 6532 Registers (mirror) - // 0x03E0-0x03FF - 6532 Registers (mirror) - - // 0x0400-0x07FF - Mirror of 0x0000-0x03FF - // 0x0800-0x0BFF - Mirror of 0x0000-0x03FF - // 0x0C00-0x0FFF - Mirror of 0x0000-0x03FF - - // 0x1000-0x1FFF - ROM - - // If page# % 4 == 0 or 1, TIA - // If page# % 4 == 2 or 3, 6532 - // if (addr & 0x0200 == 0x0000 && addr & 0x1080 == 0x0080) - // RAM - // else - // registers - // else - // ROM public byte BaseReadMemory(ushort addr) { addr = (ushort)(addr & 0x1FFF); if ((addr & 0x1080) == 0) { - return tia.ReadMemory(addr, false); + return _tia.ReadMemory(addr, false); } - else if ((addr & 0x1080) == 0x0080) + + if ((addr & 0x1080) == 0x0080) { - return m6532.ReadMemory(addr, false); - } - else - { - return rom[addr & 0x0FFF]; + return M6532.ReadMemory(addr, false); } + + return Rom[addr & 0x0FFF]; } public byte BasePeekMemory(ushort addr) @@ -80,16 +38,15 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 addr = (ushort)(addr & 0x1FFF); if ((addr & 0x1080) == 0) { - return tia.ReadMemory(addr, true); + return _tia.ReadMemory(addr, true); } - else if ((addr & 0x1080) == 0x0080) + + if ((addr & 0x1080) == 0x0080) { - return m6532.ReadMemory(addr, true); - } - else - { - return rom[addr & 0x0FFF]; + return M6532.ReadMemory(addr, true); } + + return Rom[addr & 0x0FFF]; } public void BaseWriteMemory(ushort addr, byte value) @@ -97,11 +54,11 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 addr = (ushort)(addr & 0x1FFF); if ((addr & 0x1080) == 0) { - tia.WriteMemory(addr, value); + _tia.WriteMemory(addr, value); } else if ((addr & 0x1080) == 0x0080) { - m6532.WriteMemory(addr, value); + M6532.WriteMemory(addr, value); } else { @@ -111,7 +68,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 public byte ReadMemory(ushort addr) { - byte temp = mapper.ReadMemory((ushort)(addr&0x1FFF)); + var temp = _mapper.ReadMemory((ushort)(addr & 0x1FFF)); CoreComm.MemoryCallbackSystem.CallRead(addr); @@ -120,16 +77,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 public byte PeekMemory(ushort addr) { - byte temp = mapper.ReadMemory((ushort)(addr & 0x1FFF)); + var temp = _mapper.ReadMemory((ushort)(addr & 0x1FFF)); return temp; } public void WriteMemory(ushort addr, byte value) { - mapper.WriteMemory((ushort)(addr & 0x1FFF), value); + _mapper.WriteMemory((ushort)(addr & 0x1FFF), value); - CoreComm.MemoryCallbackSystem.CallWrite((uint)addr); + CoreComm.MemoryCallbackSystem.CallWrite(addr); } public void ExecFetch(ushort addr) @@ -139,166 +96,164 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 public void HardReset() { - //regenerate mapper here to make sure its state is entirely clean - switch (game.GetOptionsDict()["m"]) + // Regenerate mapper here to make sure its state is entirely clean + switch (this._game.GetOptionsDict()["m"]) { case "2IN1": case "4IN1": case "8IN1": case "16IN1": case "32IN1": - mapper = new Multicart(); + _mapper = new Multicart(); break; case "AR": - mapper = new mAR(); + _mapper = new mAR(); break; case "4K": - mapper = new m4K(); + _mapper = new m4K(); break; case "2K": - mapper = new m2K(); + _mapper = new m2K(); break; case "CV": - mapper = new mCV(); + _mapper = new mCV(); break; case "DPC": - mapper = new mDPC(); + _mapper = new mDPC(); break; case "DPC+": - mapper = new mDPCPlus(); + _mapper = new mDPCPlus(); break; case "F8": - mapper = new mF8(); + _mapper = new mF8(); break; case "F8SC": - mapper = new mF8SC(); + _mapper = new mF8SC(); break; case "F6": - mapper = new mF6(); + _mapper = new mF6(); break; case "F6SC": - mapper = new mF6SC(); + _mapper = new mF6SC(); break; case "F4": - mapper = new mF4(); + _mapper = new mF4(); break; case "F4SC": - mapper = new mF4SC(); + _mapper = new mF4SC(); break; case "FE": - mapper = new mFE(); + _mapper = new mFE(); break; case "E0": - mapper = new mE0(); + _mapper = new mE0(); break; case "3F": - mapper = new m3F(); + _mapper = new m3F(); break; case "FA": - mapper = new mFA(); + _mapper = new mFA(); break; case "FA2": - mapper = new mFA2(); + _mapper = new mFA2(); break; case "E7": - mapper = new mE7(); + _mapper = new mE7(); break; case "F0": - mapper = new mF0(); + _mapper = new mF0(); break; case "UA": - mapper = new mUA(); + _mapper = new mUA(); break; - //Homebrew mappers + // Homebrew mappers case "3E": - mapper = new m3E(); + _mapper = new m3E(); break; case "0840": - mapper = new m0840(); + _mapper = new m0840(); break; case "MC": - mapper = new mMC(); + _mapper = new mMC(); break; case "EF": - mapper = new mEF(); + _mapper = new mEF(); break; case "EFSC": - mapper = new mEFSC(); + _mapper = new mEFSC(); break; case "X07": - mapper = new mX07(); + _mapper = new mX07(); break; case "4A50": - mapper = new m4A50(); + _mapper = new m4A50(); break; case "SB": - mapper = new mSB(); + _mapper = new mSB(); break; - default: throw new InvalidOperationException("mapper not supported: " + game.GetOptionsDict()["m"]); + default: throw new InvalidOperationException("mapper not supported: " + this._game.GetOptionsDict()["m"]); } - mapper.core = this; + + _mapper.Core = this; _lagcount = 0; - cpu = new MOS6502X(); - //cpu.debug = true; - cpu.ReadMemory = ReadMemory; - cpu.WriteMemory = WriteMemory; - cpu.PeekMemory = PeekMemory; - cpu.DummyReadMemory = ReadMemory; - cpu.OnExecFetch = ExecFetch; - // Setup TIA - //tia = new TIA(this, frameBuffer); - tia = new TIA(this); + Cpu = new MOS6502X + { + ReadMemory = this.ReadMemory, + WriteMemory = this.WriteMemory, + PeekMemory = this.PeekMemory, + DummyReadMemory = this.ReadMemory, + OnExecFetch = this.ExecFetch + }; + + _tia = new TIA(this); + // dcfilter coefficent is from real observed hardware behavior: a latched "1" will fully decay by ~170 or so tia sound cycles - dcfilter = DCFilter.AsISoundProvider(tia, 256); - // Setup 6532 - m6532 = new M6532(this); + _dcfilter = DCFilter.AsISoundProvider(_tia, 256); - //setup the system state here. for instance.. + M6532 = new M6532(this); + + // Set up the system state here. for instance.. // Read from the reset vector for where to start - cpu.PC = (ushort)(ReadMemory(0x1FFC) + (ReadMemory(0x1FFD) << 8)); //set the initial PC - //cpu.PC = 0x0000; //set the initial PC + Cpu.PC = (ushort)(ReadMemory(0x1FFC) + (ReadMemory(0x1FFD) << 8)); // set the initial PC - // show mapper class on romstatusdetails + // Show mapper class on romstatusdetails CoreComm.RomStatusDetails = - string.Format("{0}\r\nSHA1:{1}\r\nMD5:{2}\r\nMapper Impl \"{3}\"", - game.Name, - Util.Hash_SHA1(rom), Util.Hash_MD5(rom), - mapper.GetType()); + string.Format( + "{0}\r\nSHA1:{1}\r\nMD5:{2}\r\nMapper Impl \"{3}\"", + this._game.Name, + Util.Hash_SHA1(Rom), + Util.Hash_MD5(Rom), + _mapper.GetType()); } public void FrameAdvance(bool render, bool rendersound) { _frame++; _islag = true; - tia.frameComplete = false; - while (tia.frameComplete == false) + _tia.FrameComplete = false; + while (_tia.FrameComplete == false) { - tia.execute(1); - tia.execute(1); - tia.execute(1); + _tia.Execute(1); + _tia.Execute(1); + _tia.Execute(1); - m6532.timer.tick(); + M6532.timer.tick(); if (CoreComm.Tracer.Enabled) - CoreComm.Tracer.Put(cpu.TraceState()); - cpu.ExecuteOne(); - mapper.ClockCpu(); - //if (cpu.PendingCycles <= 0) - //{ - // //Console.WriteLine("Tia clocks: " + tia.scanlinePos + " CPU pending: " + cpu.PendingCycles); - //} - //if (cpu.PendingCycles < 0) - //{ - // Console.WriteLine("------------Something went wrong------------"); - //} - + { + CoreComm.Tracer.Put(Cpu.TraceState()); + } + + Cpu.ExecuteOne(); + _mapper.ClockCpu(); } if (_islag) + { LagCount++; - //if (render == false) return; + } } public byte ReadControls1(bool peek) @@ -306,12 +261,17 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 CoreComm.InputCallback.Call(); byte value = 0xFF; - if (Controller["P1 Up"]) value &= 0xEF; - if (Controller["P1 Down"]) value &= 0xDF; - if (Controller["P1 Left"]) value &= 0xBF; - if (Controller["P1 Right"]) value &= 0x7F; - if (Controller["P1 Button"]) value &= 0xF7; - if(!peek) _islag = false; + if (Controller["P1 Up"]) { value &= 0xEF; } + if (Controller["P1 Down"]) { value &= 0xDF; } + if (Controller["P1 Left"]) { value &= 0xBF; } + if (Controller["P1 Right"]) { value &= 0x7F; } + if (Controller["P1 Button"]) { value &= 0xF7; } + + if (!peek) + { + _islag = false; + } + return value; } @@ -320,47 +280,64 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 CoreComm.InputCallback.Call(); byte value = 0xFF; - if (Controller["P2 Up"]) value &= 0xEF; - if (Controller["P2 Down"]) value &= 0xDF; - if (Controller["P2 Left"]) value &= 0xBF; - if (Controller["P2 Right"]) value &= 0x7F; - if (Controller["P2 Button"]) value &= 0xF7; - if (!peek) _islag = false; + if (Controller["P2 Up"]) { value &= 0xEF; } + if (Controller["P2 Down"]) { value &= 0xDF; } + if (Controller["P2 Left"]) { value &= 0xBF; } + if (Controller["P2 Right"]) { value &= 0x7F; } + if (Controller["P2 Button"]) { value &= 0xF7; } + + if (!peek) + { + _islag = false; + } + return value; } - //private bool bw; - //private bool p0difficulty = true; - //private bool p1difficulty = true; - - //public void SetBw(bool setting) { bw = setting; } - //public void SetP0Diff(bool setting) { p0difficulty = setting; } - //public void SetP1Diff(bool setting) { p1difficulty = setting; } - public byte ReadConsoleSwitches(bool peek) { byte value = 0xFF; bool select = Controller["Select"]; bool reset = Controller["Reset"]; - if (reset) value &= 0xFE; - if (select) value &= 0xFD; - if (SyncSettings.BW) value &= 0xF7; - if (SyncSettings.LeftDifficulty) value &= 0xBF; - if (SyncSettings.RightDifficulty) value &= 0x7F; - if(!peek) _islag = false; + if (reset) { value &= 0xFE; } + if (select) { value &= 0xFD; } + if (SyncSettings.BW) { value &= 0xF7; } + if (SyncSettings.LeftDifficulty) { value &= 0xBF; } + if (SyncSettings.RightDifficulty) { value &= 0x7F; } + + if (!peek) + { + _islag = false; + } + return value; } } public class MapperBase { - public Atari2600 core; - public virtual byte ReadMemory(ushort addr) { return core.BaseReadMemory(addr); } - public virtual byte PeekMemory(ushort addr) { return core.BasePeekMemory(addr); } - public virtual void WriteMemory(ushort addr, byte value) { core.BaseWriteMemory(addr, value); } + public Atari2600 Core { get; set; } + + public virtual byte ReadMemory(ushort addr) + { + return Core.BaseReadMemory(addr); + } + + public virtual byte PeekMemory(ushort addr) + { + return Core.BasePeekMemory(addr); + } + + public virtual void WriteMemory(ushort addr, byte value) + { + Core.BaseWriteMemory(addr, value); + } + public virtual void SyncState(Serializer ser) { } + public virtual void Dispose() { } + public virtual void ClockCpu() { } } } \ No newline at end of file diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.cs index 73ef2dd2e8..e32f8bdad0 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.cs @@ -1,46 +1,58 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.IO; using BizHawk.Common; using BizHawk.Emulation.Common; -using System.ComponentModel; namespace BizHawk.Emulation.Cores.Atari.Atari2600 { public partial class Atari2600 : IEmulator { - public string SystemId { get { return "A26"; } } - public GameInfo game; + private readonly GameInfo _game; + private bool _islag = true; + private int _lagcount; + private int _frame; - public string BoardName { get { return mapper.GetType().Name; } } - - public CoreComm CoreComm { get; private set; } - public IVideoProvider VideoProvider { get { return tia; } } - public ISoundProvider SoundProvider { get { return dcfilter; } } - public ISyncSoundProvider SyncSoundProvider { get { return new FakeSyncSound(dcfilter, 735); } } - public bool StartAsyncSound() { return true; } - public void EndAsyncSound() { } - - public Atari2600(CoreComm comm, GameInfo game, byte[] rom, object Settings, object SyncSettings) + public Atari2600(CoreComm comm, GameInfo game, byte[] rom, object settings, object syncSettings) { + Ram = new byte[128]; CoreComm = comm; - this.Settings = (A2600Settings)Settings ?? A2600Settings.GetDefaults(); - this.SyncSettings = (A2600SyncSettings)SyncSettings ?? A2600SyncSettings.GetDefaults(); + Settings = (A2600Settings)settings ?? A2600Settings.GetDefaults(); + SyncSettings = (A2600SyncSettings)syncSettings ?? A2600SyncSettings.GetDefaults(); - var domains = new List(1) - { - new MemoryDomain("Main RAM", 128, MemoryDomain.Endian.Little, addr => ram[addr], (addr, value) => ram[addr] = value), - new MemoryDomain("TIA", 16, MemoryDomain.Endian.Little, addr => tia.ReadMemory((ushort) addr, true), - (addr, value) => tia.WriteMemory((ushort) addr, value)), - new MemoryDomain("PIA", 1024, MemoryDomain.Endian.Little, addr => m6532.ReadMemory((ushort) addr, true), - (addr, value) => m6532.WriteMemory((ushort) addr, value)), - new MemoryDomain("System Bus", 8192, MemoryDomain.Endian.Little, addr => mapper.PeekMemory((ushort) addr), (addr, value) => { }) - }; - memoryDomains = new MemoryDomainList(domains); + var domains = new List + { + new MemoryDomain( + "Main RAM", + 128, + MemoryDomain.Endian.Little, + addr => Ram[addr], + (addr, value) => Ram[addr] = value), + new MemoryDomain( + "TIA", + 16, + MemoryDomain.Endian.Little, + addr => _tia.ReadMemory((ushort)addr, true), + (addr, value) => this._tia.WriteMemory((ushort)addr, value)), + new MemoryDomain( + "PIA", + 1024, + MemoryDomain.Endian.Little, + addr => M6532.ReadMemory((ushort)addr, true), + (addr, value) => M6532.WriteMemory((ushort)addr, value)), + new MemoryDomain( + "System Bus", + 8192, + MemoryDomain.Endian.Little, + addr => _mapper.PeekMemory((ushort) addr), + (addr, value) => { }) + }; + MemoryDomains = new MemoryDomainList(domains); CoreComm.CpuTraceAvailable = true; - this.rom = rom; - this.game = game; + Rom = rom; + _game = game; if (!game.GetOptionsDict().ContainsKey("m")) { @@ -51,32 +63,39 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 HardReset(); } - public List> GetCpuFlagsAndRegisters() - { - return new List> - { - new KeyValuePair("A", cpu.A), - new KeyValuePair("X", cpu.X), - new KeyValuePair("Y", cpu.Y), - new KeyValuePair("S", cpu.S), - new KeyValuePair("PC", cpu.PC), - new KeyValuePair("Flag C", cpu.FlagC ? 1 : 0), - new KeyValuePair("Flag Z", cpu.FlagZ ? 1 : 0), - new KeyValuePair("Flag I", cpu.FlagI ? 1 : 0), - new KeyValuePair("Flag D", cpu.FlagD ? 1 : 0), - new KeyValuePair("Flag B", cpu.FlagB ? 1 : 0), - new KeyValuePair("Flag V", cpu.FlagV ? 1 : 0), - new KeyValuePair("Flag N", cpu.FlagN ? 1 : 0), - new KeyValuePair("Flag T", cpu.FlagT ? 1 : 0) - }; - } + public string SystemId { get { return "A26"; } } - public void ResetCounters() - { - _frame = 0; - _lagcount = 0; - _islag = false; - } + public string BoardName { get { return _mapper.GetType().Name; } } + + public CoreComm CoreComm { get; private set; } + + public IVideoProvider VideoProvider { get { return _tia; } } + + public ISoundProvider SoundProvider { get { return _dcfilter; } } + + public ISyncSoundProvider SyncSoundProvider { get { return new FakeSyncSound(_dcfilter, 735); } } + + public ControllerDefinition ControllerDefinition { get { return Atari2600ControllerDefinition; } } + + public IController Controller { get; set; } + + public int Frame { get { return _frame; } set { _frame = value; } } + + public int LagCount { get { return _lagcount; } set { _lagcount = value; } } + + public bool IsLagFrame { get { return _islag; } } + + public bool SaveRamModified { get; set; } + + public bool DeterministicEmulation { get; set; } + + public bool BinarySaveStatesPreferred { get { return false; } } + + public A2600Settings Settings { get; private set; } + + public A2600SyncSettings SyncSettings { get; private set; } + + public MemoryDomainList MemoryDomains { get; private set; } public static readonly ControllerDefinition Atari2600ControllerDefinition = new ControllerDefinition { @@ -89,65 +108,114 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 } }; - void SyncState(Serializer ser) + public List> GetCpuFlagsAndRegisters() + { + return new List> + { + new KeyValuePair("A", Cpu.A), + new KeyValuePair("X", Cpu.X), + new KeyValuePair("Y", Cpu.Y), + new KeyValuePair("S", Cpu.S), + new KeyValuePair("PC", Cpu.PC), + new KeyValuePair("Flag C", Cpu.FlagC ? 1 : 0), + new KeyValuePair("Flag Z", Cpu.FlagZ ? 1 : 0), + new KeyValuePair("Flag I", Cpu.FlagI ? 1 : 0), + new KeyValuePair("Flag D", Cpu.FlagD ? 1 : 0), + new KeyValuePair("Flag B", Cpu.FlagB ? 1 : 0), + new KeyValuePair("Flag V", Cpu.FlagV ? 1 : 0), + new KeyValuePair("Flag N", Cpu.FlagN ? 1 : 0), + new KeyValuePair("Flag T", Cpu.FlagT ? 1 : 0) + }; + } + + public bool StartAsyncSound() { return true; } + + public void EndAsyncSound() { } + + public void ResetCounters() + { + _frame = 0; + _lagcount = 0; + _islag = false; + } + + private void SyncState(Serializer ser) { ser.BeginSection("A2600"); - cpu.SyncState(ser); - ser.Sync("ram", ref ram, false); + Cpu.SyncState(ser); + ser.Sync("ram", ref this.Ram, false); ser.Sync("Lag", ref _lagcount); ser.Sync("Frame", ref _frame); ser.Sync("IsLag", ref _islag); - tia.SyncState(ser); - m6532.SyncState(ser); + _tia.SyncState(ser); + M6532.SyncState(ser); ser.BeginSection("Mapper"); - mapper.SyncState(ser); + _mapper.SyncState(ser); ser.EndSection(); ser.EndSection(); } - public ControllerDefinition ControllerDefinition { get { return Atari2600ControllerDefinition; } } - public IController Controller { get; set; } + public byte[] ReadSaveRam() + { + return null; + } - 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; - private int _lagcount; - private int _frame; - - public byte[] ReadSaveRam() { return null; } public void StoreSaveRam(byte[] data) { } + public void ClearSaveRam() { } - public bool SaveRamModified { get; set; } - public bool DeterministicEmulation { 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 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); + var ms = new MemoryStream(); + var bw = new BinaryWriter(ms); SaveStateBinary(bw); bw.Flush(); return ms.ToArray(); } - public bool BinarySaveStatesPreferred { get { return false; } } - - private readonly MemoryDomainList memoryDomains; - public MemoryDomainList MemoryDomains { get { return memoryDomains; } } public void Dispose() { } - public object GetSettings() { return Settings.Clone(); } - public object GetSyncSettings() { return SyncSettings.Clone(); } - public bool PutSettings(object o) { Settings = (A2600Settings)o; return false; } - public bool PutSyncSettings(object o) { SyncSettings = (A2600SyncSettings)o; return false; } + public object GetSettings() + { + return Settings.Clone(); + } - public A2600Settings Settings { get; private set; } - public A2600SyncSettings SyncSettings { get; private set; } + public object GetSyncSettings() + { + return SyncSettings.Clone(); + } + + public bool PutSettings(object o) + { + Settings = (A2600Settings)o; + return false; + } + + public bool PutSyncSettings(object o) + { + SyncSettings = (A2600SyncSettings)o; + return false; + } public class A2600Settings { @@ -164,6 +232,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 { return (A2600Settings)MemberwiseClone(); } + public static A2600Settings GetDefaults() { return new A2600Settings @@ -183,8 +252,10 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 { [Description("Set the TV Type switch on the console to B&W or Color")] public bool BW { get; set; } + [Description("Set the Left Difficulty switch on the console")] public bool LeftDifficulty { get; set; } + [Description("Set the Right Difficulty switch on the console")] public bool RightDifficulty { get; set; } @@ -192,6 +263,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 { return (A2600SyncSettings)MemberwiseClone(); } + public static A2600SyncSettings GetDefaults() { return new A2600SyncSettings @@ -203,5 +275,4 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 } } } - } diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/M6532.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/M6532.cs index 587e48d508..0fd9ad2428 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/2600/M6532.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/2600/M6532.cs @@ -72,7 +72,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 { // Read Ram ushort maskedAddr = (ushort)(addr & 0x007f); - return core.ram[maskedAddr]; + return core.Ram[maskedAddr]; } else { @@ -150,7 +150,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 if (!RS) { ushort maskedAddr = (ushort)(addr & 0x007f); - core.ram[maskedAddr] = value; + core.Ram[maskedAddr] = value; } else { diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/Multicart.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/Multicart.cs new file mode 100644 index 0000000000..34c24b717f --- /dev/null +++ b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/Multicart.cs @@ -0,0 +1,30 @@ +using System; + +namespace BizHawk.Emulation.Cores.Atari.Atari2600 +{ + /* + Mapper used for multi-cart mappers + */ + internal class Multicart : MapperBase + { + public Multicart() + { + throw new NotImplementedException(); + } + + public override byte ReadMemory(ushort addr) + { + if (addr < 0x1000) + { + return base.ReadMemory(addr); + } + + return Core.Rom[addr & 0xFFF]; + } + + public override byte PeekMemory(ushort addr) + { + return ReadMemory(addr); + } + } +} diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/m0840.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/m0840.cs index 51a71e0543..2c0cbb5466 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/m0840.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/m0840.cs @@ -37,7 +37,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 return base.ReadMemory(addr); } - return core.rom[(_bank4K << 12) + (addr & 0xFFF)]; + return Core.Rom[(_bank4K << 12) + (addr & 0xFFF)]; } public override byte ReadMemory(ushort addr) diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/m2K.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/m2K.cs index 9d9321461b..75738a8f5b 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/m2K.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/m2K.cs @@ -9,7 +9,7 @@ return base.ReadMemory(addr); } - return core.rom[addr & 0x7FF]; + return this.Core.Rom[addr & 0x7FF]; } public override byte PeekMemory(ushort addr) diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/m3E.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/m3E.cs index 6ea968bc8c..decbc9e4d4 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/m3E.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/m3E.cs @@ -61,12 +61,12 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 return _ram[(addr & 0x03FF) + (_rambank_1K << 10)] = 0xFF; // Reading from the write port triggers an unwanted write } - return core.rom[(_lowbank_2K << 11) + (addr & 0x07FF)]; + return Core.Rom[(_lowbank_2K << 11) + (addr & 0x07FF)]; } if (addr < 0x2000) // High bank fixed to last 2k of ROM { - return core.rom[(core.rom.Length - 2048) + (addr & 0x07FF)]; + return Core.Rom[(Core.Rom.Length - 2048) + (addr & 0x07FF)]; } return base.ReadMemory(addr); @@ -91,12 +91,12 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 return _ram[(addr & 0x03FF) + (_rambank_1K << 10)]; // Reading from the write port triggers an unwanted write } - return core.rom[(_lowbank_2K << 11) + (addr & 0x07FF)]; + return Core.Rom[(_lowbank_2K << 11) + (addr & 0x07FF)]; } if (addr < 0x2000) // High bank fixed to last 2k of ROM { - return core.rom[(core.rom.Length - 2048) + (addr & 0x07FF)]; + return Core.Rom[(Core.Rom.Length - 2048) + (addr & 0x07FF)]; } return base.ReadMemory(addr); @@ -114,13 +114,13 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 else if (addr == 0x003F) { _hasRam = false; - if ((value << 11) < core.rom.Length) + if ((value << 11) < Core.Rom.Length) { _lowbank_2K = value; } else { - _lowbank_2K = value & (core.rom.Length >> 11); + _lowbank_2K = value & (Core.Rom.Length >> 11); } } diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/m3F.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/m3F.cs index bf27c1ef99..494f8465d9 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/m3F.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/m3F.cs @@ -40,12 +40,12 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 if (addr < 0x17FF) // Low 2k Bank { - return core.rom[(_lowbank_2K << 11) + (addr & 0x07FF)]; + return Core.Rom[(_lowbank_2K << 11) + (addr & 0x07FF)]; } if (addr < 0x2000) // High bank fixed to last 2k of ROM { - return core.rom[(core.rom.Length - 2048) + (addr & 0x07FF)]; + return Core.Rom[(Core.Rom.Length - 2048) + (addr & 0x07FF)]; } return base.ReadMemory(addr); @@ -60,13 +60,13 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 { if (addr < 0x0040) { - if ((value << 11) < core.rom.Length) + if ((value << 11) < Core.Rom.Length) { _lowbank_2K = value; } else { - _lowbank_2K = value & (core.rom.Length >> 11); + _lowbank_2K = value & (Core.Rom.Length >> 11); } } diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/m4A50.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/m4A50.cs index e76ffda37d..4531045267 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/m4A50.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/m4A50.cs @@ -54,23 +54,23 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 { if ((addr & 0x1800) == 0x1000) // 2K region from 0x1000 - 0x17ff { - val = _myIsRomLow ? core.rom[(addr & 0x7ff) + _mySliceLow] + val = _myIsRomLow ? Core.Rom[(addr & 0x7ff) + _mySliceLow] : _myRam[(addr & 0x7ff) + _mySliceLow]; } else if (((addr & 0x1fff) >= 0x1800) && // 1.5K region from 0x1800 - 0x1dff ((addr & 0x1fff) <= 0x1dff)) { - val = _myIsRomMiddle ? core.rom[(addr & 0x7ff) + _mySliceMiddle] + val = _myIsRomMiddle ? Core.Rom[(addr & 0x7ff) + _mySliceMiddle] : _myRam[(addr & 0x7ff) + _mySliceMiddle]; } else if ((addr & 0x1f00) == 0x1e00) // 256B region from 0x1e00 - 0x1eff { - val = _myIsRomHigh ? core.rom[(addr & 0xff) + _mySliceHigh] + val = _myIsRomHigh ? Core.Rom[(addr & 0xff) + _mySliceHigh] : _myRam[(addr & 0xff) + _mySliceHigh]; } else if ((addr & 0x1f00) == 0x1f00) // 256B region from 0x1f00 - 0x1fff { - val = core.rom[(addr & 0xff) + (core.rom.Length - 256)]; + val = Core.Rom[(addr & 0xff) + (Core.Rom.Length - 256)]; if (((_myLastData & 0xe0) == 0x60) && ((_myLastAddress >= 0x1000) || (_myLastAddress < 0x200))) { diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/m4K.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/m4K.cs index 742336b774..c69113009a 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/m4K.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/m4K.cs @@ -9,7 +9,7 @@ return base.ReadMemory(addr); } - return core.rom[addr & 0xFFF]; + return Core.Rom[addr & 0xFFF]; } public override byte PeekMemory(ushort addr) diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mAR.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mAR.cs index 815586e0ea..7e472db7b9 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mAR.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mAR.cs @@ -33,7 +33,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 return base.ReadMemory(addr); } - return core.rom[(_bank4k << 12) + (addr & 0xFFF)]; + return Core.Rom[(_bank4k << 12) + (addr & 0xFFF)]; } public override byte ReadMemory(ushort addr) diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mCV.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mCV.cs index d4cb3deecf..f750f8b908 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mCV.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mCV.cs @@ -34,7 +34,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 if (addr >= 0x1800 && addr < 0x2000) { - return core.rom[(addr & 0x7FF)]; + return Core.Rom[(addr & 0x7FF)]; } return base.ReadMemory(addr); diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mDPC.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mDPC.cs index a39b4f6413..4a0e00e404 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mDPC.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mDPC.cs @@ -329,7 +329,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 } Address(addr); - return core.rom[(bank_4k << 12) + addr]; + return Core.Rom[(bank_4k << 12) + addr]; } public override void WriteMemory(ushort addr, byte value) diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mE0.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mE0.cs index 4f1be72f43..3154b5d56b 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mE0.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mE0.cs @@ -43,20 +43,20 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 if (addr < 0x1400) { - return core.rom[(_toggle1 << 10) + (addr & 0x3FF)]; + return Core.Rom[(_toggle1 << 10) + (addr & 0x3FF)]; } if (addr < 0x1800) { - return core.rom[(_toggle2 << 10) + (addr & 0x3FF)]; + return Core.Rom[(_toggle2 << 10) + (addr & 0x3FF)]; } if (addr < 0x1C00) { - return core.rom[(_toggle3 << 10) + (addr & 0x3FF)]; + return Core.Rom[(_toggle3 << 10) + (addr & 0x3FF)]; } - return core.rom[(7 * 1024) + (addr & 0x3FF)]; // 7 because final bank is always set to last + return Core.Rom[(7 * 1024) + (addr & 0x3FF)]; // 7 because final bank is always set to last } public override byte ReadMemory(ushort addr) diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mE7.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mE7.cs index ae4be01f2e..54dd7a040d 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mE7.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mE7.cs @@ -59,7 +59,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 return _rambank0[addr & 0x3FF]; } - return core.rom[(_rombank_1K * 0x800) + (addr & 0x7FF)]; + return Core.Rom[(_rombank_1K * 0x800) + (addr & 0x7FF)]; } if (addr < 0x1900) // Ram 1 Read port @@ -76,8 +76,8 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 { addr -= 0x1800; addr &= 0x7FF; - int offset = core.rom.Length - 0x0800; - return core.rom[offset + addr]; // Fixed to last 1.5K + int offset = Core.Rom.Length - 0x0800; + return Core.Rom[offset + addr]; // Fixed to last 1.5K } return base.ReadMemory(addr); diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mEF.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mEF.cs index 23deb41b11..3be0321649 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mEF.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mEF.cs @@ -28,7 +28,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 return base.ReadMemory(addr); } - return core.rom[(_toggle << 12) + (addr & 0xFFF)]; + return Core.Rom[(_toggle << 12) + (addr & 0xFFF)]; } public override byte ReadMemory(ushort addr) diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mEFSC.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mEFSC.cs index 470dbb9b82..4e44bcee1e 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mEFSC.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mEFSC.cs @@ -34,7 +34,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 return _ram[(addr & 0x7F)]; } - return core.rom[(_bank4k << 12) + (addr & 0xFFF)]; + return Core.Rom[(_bank4k << 12) + (addr & 0xFFF)]; } public override byte ReadMemory(ushort addr) diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mF0.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mF0.cs index ad14b6f5e3..42f4e4cac4 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mF0.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mF0.cs @@ -37,7 +37,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 return base.ReadMemory(addr); } - return core.rom[(_bank << 12) + (addr & 0xFFF)]; + return Core.Rom[(_bank << 12) + (addr & 0xFFF)]; } public override byte ReadMemory(ushort addr) diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mF4.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mF4.cs index fc16f32e31..d986aef5ac 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mF4.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mF4.cs @@ -26,7 +26,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 return base.ReadMemory(addr); } - return core.rom[(_toggle << 12) + (addr & 0xFFF)]; + return Core.Rom[(_toggle << 12) + (addr & 0xFFF)]; } public override byte ReadMemory(ushort addr) diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mF4SC.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mF4SC.cs index 9d56136fac..a8951e3756 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mF4SC.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mF4SC.cs @@ -33,7 +33,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 return _ram[(addr & 0x7F)]; } - return core.rom[(_bank4k << 12) + (addr & 0xFFF)]; + return Core.Rom[(_bank4k << 12) + (addr & 0xFFF)]; } public override byte ReadMemory(ushort addr) diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mF6.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mF6.cs index 6428693ffd..7b35b9a07c 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mF6.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mF6.cs @@ -27,7 +27,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 return base.ReadMemory(addr); } - return core.rom[(_toggle << 12) + (addr & 0xFFF)]; + return Core.Rom[(_toggle << 12) + (addr & 0xFFF)]; } public override byte ReadMemory(ushort addr) diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mF6SC.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mF6SC.cs index 02d0aa99cb..780dc64c59 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mF6SC.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mF6SC.cs @@ -33,7 +33,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 return _ram[(addr & 0x7F)]; } - return core.rom[(_bank4k << 12) + (addr & 0xFFF)]; + return Core.Rom[(_bank4k << 12) + (addr & 0xFFF)]; } public override byte ReadMemory(ushort addr) diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mF8.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mF8.cs index bf13b68d94..d4c5d39c79 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mF8.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mF8.cs @@ -35,7 +35,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 return base.ReadMemory(addr); } - return core.rom[(_bank_4K << 12) + (addr & 0xFFF)]; + return Core.Rom[(_bank_4K << 12) + (addr & 0xFFF)]; } public override byte ReadMemory(ushort addr) diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mF8SC.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mF8SC.cs index 98933e2589..6ec98d3d1d 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mF8SC.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mF8SC.cs @@ -33,7 +33,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 return _ram[(addr & 0x7F)]; } - return core.rom[(_bank_4K << 12) + (addr & 0xFFF)]; + return Core.Rom[(_bank_4K << 12) + (addr & 0xFFF)]; } public override byte ReadMemory(ushort addr) diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mFA.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mFA.cs index 71848e7685..9d05a6243d 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mFA.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mFA.cs @@ -41,7 +41,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 return _auxRam[addr & 0xFF]; } - return core.rom[(_toggle << 12) + (addr & 0xFFF)]; + return Core.Rom[(_toggle << 12) + (addr & 0xFFF)]; } public override byte ReadMemory(ushort addr) diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mFA2.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mFA2.cs index 3e994e2ea0..969d637ad9 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mFA2.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mFA2.cs @@ -35,7 +35,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 return _auxRam[addr & 0xFF]; } - return core.rom[(_bank4k << 12) + (addr & 0xFFF)]; + return Core.Rom[(_bank4k << 12) + (addr & 0xFFF)]; } public override byte ReadMemory(ushort addr) @@ -82,7 +82,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 if (addr == 0x1FF8) _bank4k = 3; if (addr == 0x1FF9) _bank4k = 4; if (addr == 0x1FFA) _bank4k = 5; - if (addr == 0x1FFB && core.rom.Length == 28 * 1024) // Only available on 28k Roms + if (addr == 0x1FFB && Core.Rom.Length == 28 * 1024) // Only available on 28k Roms { _bank4k = 6; } diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mSB.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mSB.cs new file mode 100644 index 0000000000..d182cb88fe --- /dev/null +++ b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mSB.cs @@ -0,0 +1,16 @@ +using System; + +namespace BizHawk.Emulation.Cores.Atari.Atari2600 +{ + /* + Cartridge class used for SB "SUPERbanking" 128k-256k bankswitched games. + There are either 32 or 64 4K banks. + */ + internal class mSB : MapperBase + { + public mSB() + { + throw new NotImplementedException(); + } + } +} diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mUA.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mUA.cs index 9e73c7cf1a..ff32177347 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mUA.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mUA.cs @@ -28,7 +28,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 return base.ReadMemory(addr); } - return core.rom[(_toggle << 12) + (addr & 0xFFF)]; + return Core.Rom[(_toggle << 12) + (addr & 0xFFF)]; } public override byte ReadMemory(ushort addr) diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mX07.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mX07.cs index 04de1ddbe7..1311ffbe2d 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mX07.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mX07.cs @@ -49,7 +49,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 return base.ReadMemory(addr); } - return core.rom[(_rombank_2K << 12) + (addr & 0xFFF)]; + return Core.Rom[(_rombank_2K << 12) + (addr & 0xFFF)]; } public override byte ReadMemory(ushort addr) diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/TIA.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/TIA.cs index 7fcccb4416..309ece7030 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/2600/TIA.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/2600/TIA.cs @@ -9,13 +9,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 // Emulates the TIA public class TIA : IVideoProvider, ISoundProvider { - public bool frameComplete; - - private readonly Atari2600 core; - private byte hsyncCnt; - private int capChargeStart; - private bool capCharging; - private const byte CXP0 = 0x01; private const byte CXP1 = 0x02; private const byte CXM0 = 0x04; @@ -23,7 +16,32 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 private const byte CXPF = 0x10; private const byte CXBL = 0x20; - struct missileData + private readonly Atari2600 _core; + private byte _hsyncCnt; + private int _capChargeStart; + private bool _capCharging; + + private PlayerData player0; + private PlayerData player1; + private PlayfieldData playField; + private HmoveData hmove; + private BallData ball; + + private bool vblankEnabled; + private bool vsyncEnabled; + + private uint[] scanline = new uint[160]; + + public TIA(Atari2600 core) + { + _core = core; + player0.scanCnt = 8; + player1.scanCnt = 8; + } + + public bool FrameComplete { get; set; } + + private struct MissileData { public bool Enabled; public bool ResetToPlayer; @@ -35,7 +53,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 public bool Tick() { - bool result = false; + var result = false; // At hPosCnt == 0, start drawing the missile, if enabled if (HPosCnt < (1 << Size)) @@ -59,7 +77,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 } } - if (((Number & 0x07) == 0x02 || ((Number & 0x07) == 0x03) || ((Number & 0x07) == 0x06))) + if ((Number & 0x07) == 0x02 || ((Number & 0x07) == 0x03) || ((Number & 0x07) == 0x06)) { if (HPosCnt >= 32 && HPosCnt <= (32 + (1 << Size) - 1) ) { @@ -85,6 +103,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 // Increment the counter HPosCnt++; + // Counter loops at 160 HPosCnt %= 160; @@ -105,9 +124,9 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 } } - struct playerData + private struct PlayerData { - public missileData missile; + public MissileData Missile; public byte grp; public byte dgrp; public byte color; @@ -122,9 +141,9 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 public byte resetCnt; public byte collisions; - public bool tick() + public bool Tick() { - bool result = false; + var result = false; if (scanCnt < 8) { // Make the mask to check the graphic @@ -133,7 +152,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 // Reflect it if needed if (reflect) { - playerMask = (byte)reverseBits(playerMask, 8); + playerMask = (byte)ReverseBits(playerMask, 8); } // Check the graphic (depending on delay) @@ -153,9 +172,9 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 } // Reset missile, if desired - if (scanCnt == 0x04 && hPosCnt <= 16 && missile.ResetToPlayer) + if (scanCnt == 0x04 && hPosCnt <= 16 && Missile.ResetToPlayer) { - missile.HPosCnt = 0; + Missile.HPosCnt = 0; } // Increment counter @@ -170,12 +189,14 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 scanStrchCnt++; scanStrchCnt %= 2; } + // Quad size player else if ((nusiz & 0x07) == 0x07) { scanStrchCnt++; scanStrchCnt %= 4; } + // Single size player else { @@ -186,7 +207,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 { scanCnt++; } - } // At counter position 0 we should start drawing, a pixel late @@ -217,8 +237,10 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 // Reset is no longer in effect reset = false; + // Increment the counter hPosCnt++; + // Counter loops at 160 hPosCnt %= 160; @@ -239,7 +261,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 public void SyncState(Serializer ser) { - missile.SyncState(ser); + Missile.SyncState(ser); ser.Sync("grp", ref grp); ser.Sync("dgrp", ref dgrp); ser.Sync("color", ref color); @@ -254,9 +276,9 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 ser.Sync("resetCnt", ref resetCnt); ser.Sync("collisions", ref collisions); } - }; + } - struct ballData + private struct BallData { public bool enabled; public bool denabled; @@ -264,10 +286,9 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 public byte size; public byte HM; public byte hPosCnt; - public byte collisions; - public bool tick() + public bool Tick() { bool result = false; if (hPosCnt < (1 << size)) @@ -286,6 +307,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 // Increment the counter hPosCnt++; + // Counter loops at 160 hPosCnt %= 160; @@ -304,12 +326,11 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 ser.Sync("collisions", ref collisions); ser.EndSection(); } + } - }; - - struct playfieldData + private struct PlayfieldData { - public UInt32 grp; + public uint grp; public byte pfColor; public byte bkColor; public bool reflect; @@ -326,9 +347,9 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 ser.Sync("priority", ref priority); ser.EndSection(); } - }; + } - struct hmoveData + private struct HmoveData { public bool hmoveEnabled; public bool hmoveJustStarted; @@ -374,60 +395,43 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 } }; - playerData player0; - playerData player1; - playfieldData playField; - hmoveData hmove; - ballData ball; - - - bool vblankEnabled; - bool vsyncEnabled; - private readonly List scanlinesBuffer = new List(); - uint[] scanline = new uint[160]; - private readonly UInt32[] palette = new UInt32[]{ - 0x000000, 0, 0x4a4a4a, 0, 0x6f6f6f, 0, 0x8e8e8e, 0, - 0xaaaaaa, 0, 0xc0c0c0, 0, 0xd6d6d6, 0, 0xececec, 0, - 0x484800, 0, 0x69690f, 0, 0x86861d, 0, 0xa2a22a, 0, - 0xbbbb35, 0, 0xd2d240, 0, 0xe8e84a, 0, 0xfcfc54, 0, - 0x7c2c00, 0, 0x904811, 0, 0xa26221, 0, 0xb47a30, 0, - 0xc3903d, 0, 0xd2a44a, 0, 0xdfb755, 0, 0xecc860, 0, - 0x901c00, 0, 0xa33915, 0, 0xb55328, 0, 0xc66c3a, 0, - 0xd5824a, 0, 0xe39759, 0, 0xf0aa67, 0, 0xfcbc74, 0, - 0x940000, 0, 0xa71a1a, 0, 0xb83232, 0, 0xc84848, 0, - 0xd65c5c, 0, 0xe46f6f, 0, 0xf08080, 0, 0xfc9090, 0, - 0x840064, 0, 0x97197a, 0, 0xa8308f, 0, 0xb846a2, 0, - 0xc659b3, 0, 0xd46cc3, 0, 0xe07cd2, 0, 0xec8ce0, 0, - 0x500084, 0, 0x68199a, 0, 0x7d30ad, 0, 0x9246c0, 0, - 0xa459d0, 0, 0xb56ce0, 0, 0xc57cee, 0, 0xd48cfc, 0, - 0x140090, 0, 0x331aa3, 0, 0x4e32b5, 0, 0x6848c6, 0, - 0x7f5cd5, 0, 0x956fe3, 0, 0xa980f0, 0, 0xbc90fc, 0, - 0x000094, 0, 0x181aa7, 0, 0x2d32b8, 0, 0x4248c8, 0, - 0x545cd6, 0, 0x656fe4, 0, 0x7580f0, 0, 0x8490fc, 0, - 0x001c88, 0, 0x183b9d, 0, 0x2d57b0, 0, 0x4272c2, 0, - 0x548ad2, 0, 0x65a0e1, 0, 0x75b5ef, 0, 0x84c8fc, 0, - 0x003064, 0, 0x185080, 0, 0x2d6d98, 0, 0x4288b0, 0, - 0x54a0c5, 0, 0x65b7d9, 0, 0x75cceb, 0, 0x84e0fc, 0, - 0x004030, 0, 0x18624e, 0, 0x2d8169, 0, 0x429e82, 0, - 0x54b899, 0, 0x65d1ae, 0, 0x75e7c2, 0, 0x84fcd4, 0, - 0x004400, 0, 0x1a661a, 0, 0x328432, 0, 0x48a048, 0, - 0x5cba5c, 0, 0x6fd26f, 0, 0x80e880, 0, 0x90fc90, 0, - 0x143c00, 0, 0x355f18, 0, 0x527e2d, 0, 0x6e9c42, 0, - 0x87b754, 0, 0x9ed065, 0, 0xb4e775, 0, 0xc8fc84, 0, - 0x303800, 0, 0x505916, 0, 0x6d762b, 0, 0x88923e, 0, - 0xa0ab4f, 0, 0xb7c25f, 0, 0xccd86e, 0, 0xe0ec7c, 0, - 0x482c00, 0, 0x694d14, 0, 0x866a26, 0, 0xa28638, 0, - 0xbb9f47, 0, 0xd2b656, 0, 0xe8cc63, 0, 0xfce070, 0 - }; - - public TIA(Atari2600 core) + private readonly uint[] palette = new uint[] { - this.core = core; - player0.scanCnt = 8; - player1.scanCnt = 8; - } + 0x000000, 0, 0x4a4a4a, 0, 0x6f6f6f, 0, 0x8e8e8e, 0, + 0xaaaaaa, 0, 0xc0c0c0, 0, 0xd6d6d6, 0, 0xececec, 0, + 0x484800, 0, 0x69690f, 0, 0x86861d, 0, 0xa2a22a, 0, + 0xbbbb35, 0, 0xd2d240, 0, 0xe8e84a, 0, 0xfcfc54, 0, + 0x7c2c00, 0, 0x904811, 0, 0xa26221, 0, 0xb47a30, 0, + 0xc3903d, 0, 0xd2a44a, 0, 0xdfb755, 0, 0xecc860, 0, + 0x901c00, 0, 0xa33915, 0, 0xb55328, 0, 0xc66c3a, 0, + 0xd5824a, 0, 0xe39759, 0, 0xf0aa67, 0, 0xfcbc74, 0, + 0x940000, 0, 0xa71a1a, 0, 0xb83232, 0, 0xc84848, 0, + 0xd65c5c, 0, 0xe46f6f, 0, 0xf08080, 0, 0xfc9090, 0, + 0x840064, 0, 0x97197a, 0, 0xa8308f, 0, 0xb846a2, 0, + 0xc659b3, 0, 0xd46cc3, 0, 0xe07cd2, 0, 0xec8ce0, 0, + 0x500084, 0, 0x68199a, 0, 0x7d30ad, 0, 0x9246c0, 0, + 0xa459d0, 0, 0xb56ce0, 0, 0xc57cee, 0, 0xd48cfc, 0, + 0x140090, 0, 0x331aa3, 0, 0x4e32b5, 0, 0x6848c6, 0, + 0x7f5cd5, 0, 0x956fe3, 0, 0xa980f0, 0, 0xbc90fc, 0, + 0x000094, 0, 0x181aa7, 0, 0x2d32b8, 0, 0x4248c8, 0, + 0x545cd6, 0, 0x656fe4, 0, 0x7580f0, 0, 0x8490fc, 0, + 0x001c88, 0, 0x183b9d, 0, 0x2d57b0, 0, 0x4272c2, 0, + 0x548ad2, 0, 0x65a0e1, 0, 0x75b5ef, 0, 0x84c8fc, 0, + 0x003064, 0, 0x185080, 0, 0x2d6d98, 0, 0x4288b0, 0, + 0x54a0c5, 0, 0x65b7d9, 0, 0x75cceb, 0, 0x84e0fc, 0, + 0x004030, 0, 0x18624e, 0, 0x2d8169, 0, 0x429e82, 0, + 0x54b899, 0, 0x65d1ae, 0, 0x75e7c2, 0, 0x84fcd4, 0, + 0x004400, 0, 0x1a661a, 0, 0x328432, 0, 0x48a048, 0, + 0x5cba5c, 0, 0x6fd26f, 0, 0x80e880, 0, 0x90fc90, 0, + 0x143c00, 0, 0x355f18, 0, 0x527e2d, 0, 0x6e9c42, 0, + 0x87b754, 0, 0x9ed065, 0, 0xb4e775, 0, 0xc8fc84, 0, + 0x303800, 0, 0x505916, 0, 0x6d762b, 0, 0x88923e, 0, + 0xa0ab4f, 0, 0xb7c25f, 0, 0xccd86e, 0, 0xe0ec7c, 0, + 0x482c00, 0, 0x694d14, 0, 0x866a26, 0, 0xa28638, 0, + 0xbb9f47, 0, 0xd2b656, 0, 0xe8cc63, 0, 0xfce070, 0 + }; public int[] frameBuffer = new int[320 * 262]; public int[] GetVideoBuffer() { return frameBuffer; } @@ -436,31 +440,37 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 public int BufferHeight { get { return 262; } } public int BackgroundColor { get { return 0; } } - public class audio + public class Audio { - /// noise/division control + + // noise/division control public byte AUDC = 0; - /// frequency divider + + // frequency divider public byte AUDF = 1; - /// volume + + // volume public byte AUDV = 0; - /// 2 state counter + // 2 state counter bool sr1 = true; - /// 4 bit shift register + + // 4 bit shift register int sr4 = 0x0f; - /// 5 bit shift register + + // 5 bit shift register int sr5 = 0x1f; - /// 3 state counter + + // 3 state counter int sr3 = 2; - /// counter based off AUDF + // counter based off AUDF byte freqcnt; - /// latched audio value - bool on = true; + // latched audio value + private bool on = true; - bool run_3() + private bool run_3() { sr3++; if (sr3 == 3) @@ -468,10 +478,11 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 sr3 = 0; return true; } + return false; } - bool run_4() + private bool run_4() { bool ret = (sr4 & 1) != 0; bool c = (sr4 & 1) != 0 ^ (sr4 & 2) != 0; @@ -479,7 +490,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 return ret; } - bool run_5() + private bool run_5() { bool ret = (sr5 & 1) != 0; bool c = (sr5 & 1) != 0 ^ (sr5 & 4) != 0; @@ -487,26 +498,27 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 return ret; } - bool one_4() + private bool one_4() { bool ret = (sr4 & 1) != 0; sr4 = (sr4 >> 1) | 8; return ret; } - bool one_5() + + private bool one_5() { bool ret = (sr5 & 1) != 0; sr5 = (sr5 >> 1) | 16; return ret; } - bool run_1() + private bool run_1() { sr1 = !sr1; return !sr1; } - bool run_9() + private bool run_9() { bool ret = (sr4 & 1) != 0; bool c = (sr5 & 1) != 0 ^ (sr4 & 1) != 0; @@ -519,7 +531,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 /// call me approx 31k times a second /// /// 16 bit audio sample - public short cycle() + public short Cycle() { if (++freqcnt == AUDF) { @@ -618,32 +630,23 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 } } - public audio[] AUD = { new audio(), new audio() }; + public Audio[] AUD = { new Audio(), new Audio() }; public void GetSamples(short[] samples) { - short[] moreSamples = new short[523]; + var moreSamples = new short[523]; for (int i = 0; i < moreSamples.Length; i++) { for (int snd = 0; snd < 2; snd++) { - moreSamples[i] += AUD[snd].cycle(); - //moreSamples[i] += (short)(((AUD[snd].sr4 & 0x08) != 0) ? AUD[snd].AUDV * 1092 : 0); + moreSamples[i] += AUD[snd].Cycle(); } - /*if (++freqDiv == (audioFreqDiv * 2)) - { - freqDiv = 0; - myP4 = (byte)(((myP4 & 0x0f) != 0) ? ((myP4 << 1) | ((((myP4 & 0x08) != 0) ? 1 : 0) ^ (((myP4 & 0x04) != 0) ? 1 : 0))) : 1); - } - - moreSamples[i] = (short)(((myP4 & 0x08) != 0) ? 32767 : 0); - */ } for (int i = 0; i < samples.Length / 2; i++) { samples[i * 2] = moreSamples[(int)(((double)moreSamples.Length / (double)(samples.Length / 2)) * i)]; - samples[i * 2 + 1] = samples[i * 2]; + samples[(i * 2) + 1] = samples[i * 2]; } } public void DiscardSamples() { } @@ -651,7 +654,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 // Execute TIA cycles - public void execute(int cycles) + public void Execute(int cycles) { // Still ignoring cycles... @@ -660,16 +663,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 // ---- Things that happen only in the drawing section ---- // TODO: Remove this magic number (17). It depends on the HMOVE - if ((hsyncCnt / 4) >= (hmove.lateHBlankReset ? 19 : 17)) + if ((_hsyncCnt / 4) >= (hmove.lateHBlankReset ? 19 : 17)) { // TODO: Remove this magic number - if ((hsyncCnt / 4) >= 37) + if ((_hsyncCnt / 4) >= 37) { rightSide = true; } // The bit number of the PF data which we want - int pfBit = ((hsyncCnt / 4) - 17) % 20; + int pfBit = ((_hsyncCnt / 4) - 17) % 20; // Create the mask for the bit we want // Note that bits are arranged 0 1 2 3 4 .. 19 @@ -678,7 +681,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 // Reverse the mask if on the right and playfield is reflected if (rightSide && playField.reflect) { - pfMask = reverseBits(pfMask, 20); + pfMask = ReverseBits(pfMask, 20); } // Calculate collisions @@ -691,29 +694,29 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 // ---- Player 0 ---- - collisions |= (player0.tick() ? CXP0 : (byte)0x00); + collisions |= (player0.Tick() ? CXP0 : (byte)0x00); // ---- Missile 0 ---- - collisions |= (player0.missile.Tick() ? CXM0 : (byte)0x00); + collisions |= (player0.Missile.Tick() ? CXM0 : (byte)0x00); // ---- Player 1 ---- - collisions |= (player1.tick() ? CXP1 : (byte)0x00); + collisions |= (player1.Tick() ? CXP1 : (byte)0x00); // ---- Missile 0 ---- - collisions |= (player1.missile.Tick() ? CXM1 : (byte)0x00); + collisions |= (player1.Missile.Tick() ? CXM1 : (byte)0x00); // ---- Ball ---- - collisions |= (ball.tick() ? CXBL : (byte)0x00); + collisions |= (ball.Tick() ? CXBL : (byte)0x00); // Pick the pixel color from collisions uint pixelColor = 0x000000; - if (core.Settings.ShowBG) + if (_core.Settings.ShowBG) { pixelColor = palette[playField.bkColor]; } - if ((collisions & CXPF) != 0 && core.Settings.ShowPlayfield) + if ((collisions & CXPF) != 0 && _core.Settings.ShowPlayfield) { if (playField.score) { @@ -735,7 +738,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 if ((collisions & CXBL) != 0) { ball.collisions |= collisions; - if (core.Settings.ShowBall) + if (_core.Settings.ShowBall) { pixelColor = palette[playField.pfColor]; } @@ -743,8 +746,8 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 if ((collisions & CXM1) != 0) { - player1.missile.Collisions |= collisions; - if (core.Settings.ShowMissle2) + player1.Missile.Collisions |= collisions; + if (_core.Settings.ShowMissle2) { pixelColor = palette[player1.color]; } @@ -753,7 +756,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 if ((collisions & CXP1) != 0) { player1.collisions |= collisions; - if (core.Settings.ShowPlayer2) + if (_core.Settings.ShowPlayer2) { pixelColor = palette[player1.color]; } @@ -761,8 +764,8 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 if ((collisions & CXM0) != 0) { - player0.missile.Collisions |= collisions; - if (core.Settings.ShowMissle1) + player0.Missile.Collisions |= collisions; + if (_core.Settings.ShowMissle1) { pixelColor = palette[player0.color]; } @@ -771,24 +774,17 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 if ((collisions & CXP0) != 0) { player0.collisions |= collisions; - if (core.Settings.ShowPlayer1) + if (_core.Settings.ShowPlayer1) { pixelColor = palette[player0.color]; } } - if (playField.priority && (collisions & CXPF) != 0 && core.Settings.ShowPlayfield) + if (playField.priority && (collisions & CXPF) != 0 && _core.Settings.ShowPlayfield) { if (playField.score) { - if (!rightSide) - { - pixelColor = palette[player0.color]; - } - else - { - pixelColor = palette[player1.color]; - } + pixelColor = !rightSide ? palette[player0.color] : palette[player1.color]; } else { @@ -804,7 +800,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 // Add the pixel to the scanline // TODO: Remove this magic number (68) - scanline[hsyncCnt - 68] = pixelColor; + scanline[_hsyncCnt - 68] = pixelColor; } @@ -833,7 +829,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 hmove.hmoveCnt = 0; - //hmove.hmoveCnt++; hmove.hmoveJustStarted = false; hmove.lateHBlankReset = true; hmove.decCntEnabled = false; @@ -851,7 +846,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 if (((15 - hmove.player0Cnt) ^ ((player0.HM & 0x07) | ((~(player0.HM & 0x08)) & 0x08))) != 0x0F) { // "Clock-Stuffing" - player0.tick(); + player0.Tick(); // Increase by 1, max of 15 hmove.player0Cnt++; @@ -869,10 +864,10 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 { } // If the move counter still has a bit in common with the HM register - if (((15 - hmove.missile0Cnt) ^ ((player0.missile.Hm & 0x07) | ((~(player0.missile.Hm & 0x08)) & 0x08))) != 0x0F) + if (((15 - hmove.missile0Cnt) ^ ((player0.Missile.Hm & 0x07) | ((~(player0.Missile.Hm & 0x08)) & 0x08))) != 0x0F) { // "Clock-Stuffing" - player0.missile.Tick(); + player0.Missile.Tick(); // Increase by 1, max of 15 hmove.missile0Cnt++; @@ -891,7 +886,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 if (((15 - hmove.player1Cnt) ^ ((player1.HM & 0x07) | ((~(player1.HM & 0x08)) & 0x08))) != 0x0F) { // "Clock-Stuffing" - player1.tick(); + player1.Tick(); // Increase by 1, max of 15 hmove.player1Cnt++; @@ -906,10 +901,10 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 if (hmove.missile1Latch) { // If the move counter still has a bit in common with the HM register - if (((15 - hmove.missile1Cnt) ^ ((player1.missile.Hm & 0x07) | ((~(player1.missile.Hm & 0x08)) & 0x08))) != 0x0F) + if (((15 - hmove.missile1Cnt) ^ ((player1.Missile.Hm & 0x07) | ((~(player1.Missile.Hm & 0x08)) & 0x08))) != 0x0F) { // "Clock-Stuffing" - player1.missile.Tick(); + player1.Missile.Tick(); // Increase by 1, max of 15 hmove.missile1Cnt++; @@ -927,7 +922,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 if (((15 - hmove.ballCnt) ^ ((ball.HM & 0x07) | ((~(ball.HM & 0x08)) & 0x08))) != 0x0F) { // "Clock-Stuffing" - ball.tick(); + ball.Tick(); // Increase by 1, max of 15 hmove.ballCnt++; @@ -946,7 +941,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 hmove.hmoveDelayCnt = 0; } } - //hmove.hmoveJustStarted = false; + hmove.hmoveCnt++; hmove.hmoveCnt %= 4; } @@ -964,14 +959,12 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 } } - - // Increment the hsync counter - hsyncCnt++; - hsyncCnt %= 228; + _hsyncCnt++; + _hsyncCnt %= 228; // End of the line? Add it to the buffer! - if (hsyncCnt == 0) + if (_hsyncCnt == 0) { hmove.lateHBlankReset = false; scanlinesBuffer.Add(scanline); @@ -984,14 +977,14 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 * that need to be fixed; but it's preferable to not crash the emulator * in such situations */ - outputFrame(); + OutputFrame(); scanlinesBuffer.Clear(); - frameComplete = true; + FrameComplete = true; } } // TODO: Remove the magic numbers from this function to allow for a variable height screen - public void outputFrame() + public void OutputFrame() { for (int row = 0; row < 262; row++) { @@ -999,11 +992,11 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 { if (scanlinesBuffer.Count > row) { - frameBuffer[row * 320 + col] = (int)(scanlinesBuffer[row][col / 2] | 0xFF000000); + frameBuffer[(row * 320) + col] = (int)(scanlinesBuffer[row][col / 2] | 0xFF000000); } else { - frameBuffer[row * 320 + col] = unchecked((int)0xFF000000); + frameBuffer[(row * 320) + col] = unchecked((int)0xFF000000); } } } @@ -1014,41 +1007,49 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 ushort maskedAddr = (ushort)(addr & 0x000F); if (maskedAddr == 0x00) // CXM0P { - return (byte)((((player0.missile.Collisions & CXP1) != 0) ? 0x80 : 0x00) | (((player0.missile.Collisions & CXP0) != 0) ? 0x40 : 0x00)); + return (byte)((((player0.Missile.Collisions & CXP1) != 0) ? 0x80 : 0x00) | (((player0.Missile.Collisions & CXP0) != 0) ? 0x40 : 0x00)); } - else if (maskedAddr == 0x01) // CXM1P + + if (maskedAddr == 0x01) // CXM1P { - return (byte)((((player1.missile.Collisions & CXP0) != 0) ? 0x80 : 0x00) | (((player1.missile.Collisions & CXP1) != 0) ? 0x40 : 0x00)); + return (byte)((((player1.Missile.Collisions & CXP0) != 0) ? 0x80 : 0x00) | (((player1.Missile.Collisions & CXP1) != 0) ? 0x40 : 0x00)); } - else if (maskedAddr == 0x02) // CXP0FB + + if (maskedAddr == 0x02) // CXP0FB { return (byte)((((player0.collisions & CXPF) != 0) ? 0x80 : 0x00) | (((player0.collisions & CXBL) != 0) ? 0x40 : 0x00)); } - else if (maskedAddr == 0x03) // CXP1FB + + if (maskedAddr == 0x03) // CXP1FB { return (byte)((((player1.collisions & CXPF) != 0) ? 0x80 : 0x00) | (((player1.collisions & CXBL) != 0) ? 0x40 : 0x00)); } - else if (maskedAddr == 0x04) // CXM0FB + + if (maskedAddr == 0x04) // CXM0FB { - return (byte)((((player0.missile.Collisions & CXPF) != 0) ? 0x80 : 0x00) | (((player0.missile.Collisions & CXBL) != 0) ? 0x40 : 0x00)); + return (byte)((((player0.Missile.Collisions & CXPF) != 0) ? 0x80 : 0x00) | (((player0.Missile.Collisions & CXBL) != 0) ? 0x40 : 0x00)); } - else if (maskedAddr == 0x05) // CXM1FB + + if (maskedAddr == 0x05) // CXM1FB { - return (byte)((((player1.missile.Collisions & CXPF) != 0) ? 0x80 : 0x00) | (((player1.missile.Collisions & CXBL) != 0) ? 0x40 : 0x00)); + return (byte)((((player1.Missile.Collisions & CXPF) != 0) ? 0x80 : 0x00) | (((player1.Missile.Collisions & CXBL) != 0) ? 0x40 : 0x00)); } - else if (maskedAddr == 0x06) // CXBLPF + + if (maskedAddr == 0x06) // CXBLPF { return (byte)(((ball.collisions & CXPF) != 0) ? 0x80 : 0x00); } - else if (maskedAddr == 0x07) // CXPPMM + + if (maskedAddr == 0x07) // CXPPMM { - return (byte)((((player0.collisions & CXP1) != 0) ? 0x80 : 0x00) | (((player0.missile.Collisions & CXM1) != 0) ? 0x40 : 0x00)); + return (byte)((((player0.collisions & CXP1) != 0) ? 0x80 : 0x00) | (((player0.Missile.Collisions & CXM1) != 0) ? 0x40 : 0x00)); } - else if (maskedAddr == 0x08) // INPT0 + + if (maskedAddr == 0x08) // INPT0 { // Changing the hard coded value will change the paddle position. The range seems to be roughly 0-56000 according to values from stella // 6105 roughly centers the paddle in Breakout - if (capCharging && core.cpu.TotalExecutedCycles - capChargeStart >= 6105) + if (_capCharging && _core.Cpu.TotalExecutedCycles - _capChargeStart >= 6105) { return 0x80; } @@ -1057,13 +1058,15 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 return 0x00; } } - else if (maskedAddr == 0x0C) // INPT4 + + if (maskedAddr == 0x0C) // INPT4 { - return (byte)((core.ReadControls1(peek) & 0x08) != 0 ? 0x80 : 0x00); + return (byte)((_core.ReadControls1(peek) & 0x08) != 0 ? 0x80 : 0x00); } - else if (maskedAddr == 0x0D) // INPT5 + + if (maskedAddr == 0x0D) // INPT5 { - return (byte)((core.ReadControls2(peek) & 0x08) != 0 ? 0x80 : 0x00); + return (byte)((_core.ReadControls2(peek) & 0x08) != 0 ? 0x80 : 0x00); } return 0x00; @@ -1085,53 +1088,55 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 // When VSYNC is disabled, this will be the first line of the new frame // write to frame buffer - outputFrame(); + OutputFrame(); + // Clear all from last frame scanlinesBuffer.Clear(); - //Frame is done - frameComplete = true; + + // Frame is done + FrameComplete = true; vsyncEnabled = false; // Do not reset hsync, since we're on the first line of the new frame - //hsyncCnt = 0; + // hsyncCnt = 0; } } else if (maskedAddr == 0x01) // VBLANK { vblankEnabled = (value & 0x02) != 0; - capCharging = (value & 0x80) == 0; + _capCharging = (value & 0x80) == 0; if ((value & 0x80) == 0) { - capChargeStart = core.cpu.TotalExecutedCycles; + _capChargeStart = _core.Cpu.TotalExecutedCycles; } } else if (maskedAddr == 0x02) // WSYNC { int count = 0; - while (hsyncCnt > 0) + while (_hsyncCnt > 0) { count++; - execute(1); + Execute(1); // Add a cycle to the cpu every 3 TIA clocks (corrects timer error in M6532) if (count % 3 == 0) { - core.m6532.timer.tick(); + _core.M6532.timer.tick(); } } } else if (maskedAddr == 0x04) // NUSIZ0 { player0.nusiz = (byte)(value & 0x37); - player0.missile.Size = (byte)((value & 0x30) >> 4); - player0.missile.Number = (byte)(value & 0x07); + player0.Missile.Size = (byte)((value & 0x30) >> 4); + player0.Missile.Number = (byte)(value & 0x07); } else if (maskedAddr == 0x05) // NUSIZ1 { player1.nusiz = (byte)(value & 0x37); - player1.missile.Size = (byte)((value & 0x30) >> 4); - player1.missile.Number = (byte)(value & 0x07); + player1.Missile.Size = (byte)((value & 0x30) >> 4); + player1.Missile.Number = (byte)(value & 0x07); } else if (maskedAddr == 0x06) // COLUP0 { @@ -1158,42 +1163,42 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 } else if (maskedAddr == 0x0B) // REFP0 { - player0.reflect = ((value & 0x08) != 0); + player0.reflect = (value & 0x08) != 0; } else if (maskedAddr == 0x0C) // REFP1 { - player1.reflect = ((value & 0x08) != 0); + player1.reflect = (value & 0x08) != 0; } else if (maskedAddr == 0x0D) // PF0 { - playField.grp = (UInt32)((playField.grp & 0x0FFFF) + ((reverseBits(value,8) & 0x0F) << 16)); + playField.grp = (uint)((playField.grp & 0x0FFFF) + ((ReverseBits(value, 8) & 0x0F) << 16)); } else if (maskedAddr == 0x0E) // PF1 { - playField.grp = (UInt32)((playField.grp & 0xF00FF) + (value << 8)); + playField.grp = (uint)((playField.grp & 0xF00FF) + (value << 8)); } else if (maskedAddr == 0x0F) // PF2 { - playField.grp = (UInt32)((playField.grp & 0xFFF00) + reverseBits(value,8)); + playField.grp = (uint)((playField.grp & 0xFFF00) + ReverseBits(value,8)); } else if (maskedAddr == 0x10) // RESP0 { // Borrowed from EMU7800. Apparently resetting between 68 and 76 has strange results. - if (hsyncCnt < 69) + if (_hsyncCnt < 69) { player0.hPosCnt = 0; player0.resetCnt = 0; player0.reset = true; } - else if (hsyncCnt == 69) + else if (_hsyncCnt == 69) { player0.resetCnt = 3; } - else if (hsyncCnt == 72) + else if (_hsyncCnt == 72) { player0.resetCnt = 2; } - else if (hsyncCnt == 75) + else if (_hsyncCnt == 75) { player0.resetCnt = 1; } @@ -1201,27 +1206,26 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 { player0.resetCnt = 0; } - //player0.resetCnt = 0; } else if (maskedAddr == 0x11) // RESP1 { // Borrowed from EMU7800. Apparently resetting between 68 and 76 has strange results. // This fixes some graphic glitches with Frostbite - if (hsyncCnt < 69) + if (_hsyncCnt < 69) { player1.hPosCnt = 0; player1.resetCnt = 0; player1.reset = true; } - else if (hsyncCnt == 69) + else if (_hsyncCnt == 69) { player1.resetCnt = 3; } - else if (hsyncCnt == 72) + else if (_hsyncCnt == 72) { player1.resetCnt = 2; } - else if (hsyncCnt == 75) + else if (_hsyncCnt == 75) { player1.resetCnt = 1; } @@ -1229,19 +1233,18 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 { player1.resetCnt = 0; } - //player1.resetCnt = 0; } else if (maskedAddr == 0x12) // RESM0 { - player0.missile.HPosCnt = (byte)(hsyncCnt < 68 ? 160 - 2 : 160 - 4); + player0.Missile.HPosCnt = (byte)(_hsyncCnt < 68 ? 160 - 2 : 160 - 4); } else if (maskedAddr == 0x13) // RESM1 { - player1.missile.HPosCnt = (byte)(hsyncCnt < 68 ? 160 - 2 : 160 - 4); + player1.Missile.HPosCnt = (byte)(_hsyncCnt < 68 ? 160 - 2 : 160 - 4); } else if (maskedAddr == 0x14) // RESBL { - ball.hPosCnt = (byte)(hsyncCnt < 68 ? 160 - 2 : 160 - 4); + ball.hPosCnt = (byte)(_hsyncCnt < 68 ? 160 - 2 : 160 - 4); } else if (maskedAddr == 0x15) // AUDC0 { @@ -1282,11 +1285,11 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 } else if (maskedAddr == 0x1D) // ENAM0 { - player0.missile.Enabled = (value & 0x02) != 0; + player0.Missile.Enabled = (value & 0x02) != 0; } else if (maskedAddr == 0x1E) // ENAM1 { - player1.missile.Enabled = (value & 0x02) != 0; + player1.Missile.Enabled = (value & 0x02) != 0; } else if (maskedAddr == 0x1F) // ENABL { @@ -1302,11 +1305,11 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 } else if (maskedAddr == 0x22) // HMM0 { - player0.missile.Hm = (byte)((value & 0xF0) >> 4); + player0.Missile.Hm = (byte)((value & 0xF0) >> 4); } else if (maskedAddr == 0x23) // HMM1 { - player1.missile.Hm = (byte)((value & 0xF0) >> 4); + player1.Missile.Hm = (byte)((value & 0xF0) >> 4); } else if (maskedAddr == 0x24) // HMBL { @@ -1326,11 +1329,11 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 } else if (maskedAddr == 0x28) // RESMP0 { - player0.missile.ResetToPlayer = (value & 0x02) != 0; + player0.Missile.ResetToPlayer = (value & 0x02) != 0; } else if (maskedAddr == 0x29) // RESMP1 { - player1.missile.ResetToPlayer = (value & 0x02) != 0; + player1.Missile.ResetToPlayer = (value & 0x02) != 0; } else if (maskedAddr == 0x2A) // HMOVE { @@ -1341,22 +1344,22 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 else if (maskedAddr == 0x2B) // HMCLR { player0.HM = 0; - player0.missile.Hm = 0; + player0.Missile.Hm = 0; player1.HM = 0; - player1.missile.Hm = 0; + player1.Missile.Hm = 0; ball.HM = 0; } else if (maskedAddr == 0x2C) // CXCLR { player0.collisions = 0; - player0.missile.Collisions = 0; + player0.Missile.Collisions = 0; player1.collisions = 0; - player1.missile.Collisions = 0; + player1.Missile.Collisions = 0; ball.collisions = 0; } } - static int reverseBits(int value, int bits) + private static int ReverseBits(int value, int bits) { int result = 0; for (int i = 0; i < bits; i++) @@ -1371,7 +1374,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 ser.BeginSection("TIA"); ball.SyncState(ser); hmove.SyncState(ser); - ser.Sync("hsyncCnt", ref hsyncCnt); + ser.Sync("hsyncCnt", ref _hsyncCnt); ser.BeginSection("Player0"); player0.SyncState(ser); ser.EndSection(); @@ -1379,7 +1382,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 player1.SyncState(ser); ser.EndSection(); playField.SyncState(ser); - //ser.Sync("scanline", ref scanline); ser.EndSection(); } } diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/oldTIA.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/oldTIA.cs deleted file mode 100644 index 981ee9ed44..0000000000 --- a/BizHawk.Emulation.Cores/Consoles/Atari/2600/oldTIA.cs +++ /dev/null @@ -1,616 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace BizHawk.Emulation.Cores.Atari.Atari2600 -{ - // Emulates the TIA - public class oldTIA - { - private readonly Atari2600 core; - - public bool audioEnabled = false; - public byte audioFreqDiv = 0; - - UInt32 PF; // PlayField data - byte BKcolor, PFcolor; - bool PFpriority; - bool PFreflect; - bool PFscore; - bool inpt_latching; - bool inpt4; - bool hmoveHappened; - - struct playerData - { - public byte grp; - public byte dgrp; - public byte color; - public byte pos; - public byte HM; - public bool reflect; - public bool delay; -/* - public byte nusiz; -*/ - }; - struct ballMissileData - { - public bool enabled; - public byte pos; - public byte HM; - public byte size; - /* - public bool reset; - public bool delay; - */ - - }; - - ballMissileData ball; - - playerData player0; - playerData player1; - - byte player0copies; - byte player0copy1; - byte player0copy2; - byte player1copies; - byte player1copy1; - byte player1copy2; - - byte P0_collisions; - byte P1_collisions; - byte M0_collisions; - byte M1_collisions; - byte BL_collisions; - - const byte COLP0 = 0x01; - const byte COLP1 = 0x02; - const byte COLM0 = 0x04; - const byte COLM1 = 0x08; - const byte COLPF = 0x10; - const byte COLBL = 0x20; - - bool vblankEnabled; - - readonly int[] frameBuffer; - public bool frameComplete; - - readonly List scanlinesBuffer = new List (); - uint[] scanline = new uint[160]; - public int scanlinePos; - - readonly int[] hmove = new int[] { 0,-1,-2,-3,-4,-5,-6,-7,-8,7,6,5,4,3,2,1 }; - - UInt32[] palette = new UInt32[]{ - 0x000000, 0, 0x4a4a4a, 0, 0x6f6f6f, 0, 0x8e8e8e, 0, - 0xaaaaaa, 0, 0xc0c0c0, 0, 0xd6d6d6, 0, 0xececec, 0, - 0x484800, 0, 0x69690f, 0, 0x86861d, 0, 0xa2a22a, 0, - 0xbbbb35, 0, 0xd2d240, 0, 0xe8e84a, 0, 0xfcfc54, 0, - 0x7c2c00, 0, 0x904811, 0, 0xa26221, 0, 0xb47a30, 0, - 0xc3903d, 0, 0xd2a44a, 0, 0xdfb755, 0, 0xecc860, 0, - 0x901c00, 0, 0xa33915, 0, 0xb55328, 0, 0xc66c3a, 0, - 0xd5824a, 0, 0xe39759, 0, 0xf0aa67, 0, 0xfcbc74, 0, - 0x940000, 0, 0xa71a1a, 0, 0xb83232, 0, 0xc84848, 0, - 0xd65c5c, 0, 0xe46f6f, 0, 0xf08080, 0, 0xfc9090, 0, - 0x840064, 0, 0x97197a, 0, 0xa8308f, 0, 0xb846a2, 0, - 0xc659b3, 0, 0xd46cc3, 0, 0xe07cd2, 0, 0xec8ce0, 0, - 0x500084, 0, 0x68199a, 0, 0x7d30ad, 0, 0x9246c0, 0, - 0xa459d0, 0, 0xb56ce0, 0, 0xc57cee, 0, 0xd48cfc, 0, - 0x140090, 0, 0x331aa3, 0, 0x4e32b5, 0, 0x6848c6, 0, - 0x7f5cd5, 0, 0x956fe3, 0, 0xa980f0, 0, 0xbc90fc, 0, - 0x000094, 0, 0x181aa7, 0, 0x2d32b8, 0, 0x4248c8, 0, - 0x545cd6, 0, 0x656fe4, 0, 0x7580f0, 0, 0x8490fc, 0, - 0x001c88, 0, 0x183b9d, 0, 0x2d57b0, 0, 0x4272c2, 0, - 0x548ad2, 0, 0x65a0e1, 0, 0x75b5ef, 0, 0x84c8fc, 0, - 0x003064, 0, 0x185080, 0, 0x2d6d98, 0, 0x4288b0, 0, - 0x54a0c5, 0, 0x65b7d9, 0, 0x75cceb, 0, 0x84e0fc, 0, - 0x004030, 0, 0x18624e, 0, 0x2d8169, 0, 0x429e82, 0, - 0x54b899, 0, 0x65d1ae, 0, 0x75e7c2, 0, 0x84fcd4, 0, - 0x004400, 0, 0x1a661a, 0, 0x328432, 0, 0x48a048, 0, - 0x5cba5c, 0, 0x6fd26f, 0, 0x80e880, 0, 0x90fc90, 0, - 0x143c00, 0, 0x355f18, 0, 0x527e2d, 0, 0x6e9c42, 0, - 0x87b754, 0, 0x9ed065, 0, 0xb4e775, 0, 0xc8fc84, 0, - 0x303800, 0, 0x505916, 0, 0x6d762b, 0, 0x88923e, 0, - 0xa0ab4f, 0, 0xb7c25f, 0, 0xccd86e, 0, 0xe0ec7c, 0, - 0x482c00, 0, 0x694d14, 0, 0x866a26, 0, 0xa28638, 0, - 0xbb9f47, 0, 0xd2b656, 0, 0xe8cc63, 0, 0xfce070, 0 - }; - - public oldTIA(Atari2600 core, int[] frameBuffer) - { - player1copy2 = 0; - player0copy2 = 0; - this.core = core; - BKcolor = 0x00; - this.frameBuffer = frameBuffer; - scanlinePos = 0; - frameComplete = false; - } - - public void execute(int cycles) - { - // Ignore cycles for now, just do one cycle (three color counts/pixels) - - if (scanlinePos < 68) - { - scanlinePos ++; - // HBLANK - return; - } - - UInt32 PFmask; - - int pixelPos = scanlinePos - 68; - - // First half of screen - if (pixelPos < 80) - { - PFmask = (UInt32)(1 << ((20-1) - (byte)((pixelPos % 80) / 4))); - } - // Second half - else - { - if (PFreflect) - { - PFmask = (UInt32)(1 << ((byte)((pixelPos % 80) / 4))); - } - else - { - PFmask = (UInt32)(1 << ((20 - 1) - (byte)((pixelPos % 80) / 4))); - } - } - - uint color = palette[BKcolor]; - byte collisions = 0; - - if ((PF & PFmask) != 0) - { - color = palette[PFcolor]; - if (PFscore) - { - if (pixelPos < 80) - { - color = palette[player0.color]; - } - else - { - color = palette[player1.color]; - } - } - collisions |= COLPF; - } - - // Ball - if (ball.enabled && pixelPos >= ball.pos && pixelPos < (ball.pos + (1 << ball.size))) - { - color = palette[PFcolor]; - collisions |= COLBL; - } - - // Player 1 - if (pixelPos >= player1.pos && pixelPos < (player1.pos + 8)) - { - byte mask = (byte)(0x80 >> (pixelPos - player1.pos)); - if (player1.reflect) - { - mask = reverseBits(mask); - } - - if (((player1.grp & mask) != 0 && !player1.delay) || ((player1.dgrp & mask) != 0 && player1.delay)) - { - color = palette[player1.color]; - collisions |= COLP1; - } - } - - byte pos = (byte)(player1.pos + player1copy1); - // Player copy 1 - if (player1copies >= 1 && pixelPos >= pos && pixelPos < (pos + 8)) - { - byte mask = (byte)(0x80 >> (pixelPos - pos)); - if (player1.reflect) - { - mask = reverseBits(mask); - } - - if (((player1.grp & mask) != 0 && !player1.delay) || ((player1.dgrp & mask) != 0 && player1.delay)) - { - color = palette[player1.color]; - collisions |= COLP1; - } - } - - pos = (byte)(player1.pos + player1copy2); - // Player copy 2 - if (player1copies >=2 && pixelPos >= pos && pixelPos < (pos + 8)) - { - byte mask = (byte)(0x80 >> (pixelPos - pos)); - if (player1.reflect) - { - mask = reverseBits(mask); - } - - if (((player1.grp & mask) != 0 && !player1.delay) || ((player1.dgrp & mask) != 0 && player1.delay)) - { - color = palette[player1.color]; - collisions |= COLP1; - } - } - - // Player 0 - if (pixelPos >= player0.pos && pixelPos < (player0.pos + 8)) - { - byte mask = (byte)(0x80 >> (pixelPos - player0.pos)); - if (player0.reflect) - { - mask = reverseBits(mask); - } - if (((player0.grp & mask) != 0 && !player0.delay) || ((player0.dgrp & mask) != 0 && player0.delay)) - { - color = palette[player0.color]; - collisions |= COLP0; - } - } - - pos = (byte)(player0.pos + player0copy1); - // Player copy 1 - if (player0copies >= 1 && pixelPos >= pos && pixelPos < (pos + 8)) - { - byte mask = (byte)(0x80 >> (pixelPos - pos)); - if (player0.reflect) - { - mask = reverseBits(mask); - } - - if (((player0.grp & mask) != 0 && !player0.delay) || ((player0.dgrp & mask) != 0 && player0.delay)) - { - color = palette[player0.color]; - collisions |= COLP0; - } - } - - pos = (byte)(player0.pos + player0copy2); - // Player copy 1 - if (player0copies >= 2 && pixelPos >= pos && pixelPos < (pos + 8)) - { - byte mask = (byte)(0x80 >> (pixelPos - pos)); - if (player0.reflect) - { - mask = reverseBits(mask); - } - - if (((player0.grp & mask) != 0 && !player0.delay) || ((player0.dgrp & mask) != 0 && player0.delay)) - { - color = palette[player0.color]; - collisions |= COLP0; - } - } - - if ((PF & PFmask) != 0 && PFpriority) - { - color = palette[PFcolor]; - if (PFscore) - { - if (pixelPos < 80) - { - color = palette[player0.color]; - } - else - { - color = palette[player1.color]; - } - } - collisions |= COLPF; - } - - if (vblankEnabled) - { - color = 0x000000; - } - - P0_collisions |= (((collisions & COLP0) != 0) ? collisions : P0_collisions); - P1_collisions |= (((collisions & COLP1) != 0) ? collisions : P1_collisions); - M0_collisions |= (((collisions & COLM0) != 0) ? collisions : M0_collisions); - M1_collisions |= (((collisions & COLM1) != 0) ? collisions : M1_collisions); - BL_collisions |= (((collisions & COLBL) != 0) ? collisions : BL_collisions); - - if (hmoveHappened && pixelPos >= 0 && pixelPos < 8) - { - color = 0x000000; - } - if (pixelPos >= 8) - { - hmoveHappened = false; - } - scanline[pixelPos] = color; - - scanlinePos++; - if (scanlinePos >= 228) - { - scanlinesBuffer.Add(scanline); - scanline = new uint[160]; - } - scanlinePos %= 228; - - } - - public void outputFrame() - { - for (int row = 0; row < 262; row++) - { - for (int col = 0; col < 320; col++) - { - if (scanlinesBuffer.Count > row) - { - frameBuffer[row * 320 + col] = (int)(scanlinesBuffer[row][col / 2]); - } - else - { - frameBuffer[row * 320 + col] = 0x000000; - } - } - } - } - - public byte ReadMemory(ushort addr, bool peek) - { - ushort maskedAddr = (ushort)(addr & 0x000F); - Console.WriteLine("TIA read: " + maskedAddr.ToString("x")); - if (maskedAddr == 0x02) // CXP0FB - { - return (byte)((((P0_collisions & COLPF) != 0) ? 0x80 : 0x00) | (((P0_collisions & COLBL) != 0) ? 0x40 : 0x00)); - } - else if (maskedAddr == 0x07) // CXPPMM - { - return (byte)((((P0_collisions & COLP1) != 0) ? 0x80 : 0x00) | (((M0_collisions & COLM1) != 0) ? 0x40 : 0x00)); - } - else if (maskedAddr == 0x0C) // INPT4 - { - if (inpt_latching) - { - if (inpt4) - { - inpt4 = ((core.ReadControls1(peek) & 0x08) != 0); - } - } - else - { - inpt4 = ((core.ReadControls1(peek) & 0x08) != 0); - } - return (byte)(inpt4 ? 0x80 : 0x00); - - } - - return 0x80; - } - - public void WriteMemory(ushort addr, byte value) - { - ushort maskedAddr = (ushort)(addr & 0x3f); - Console.WriteLine("TIA write: " + maskedAddr.ToString("x")); - - if (maskedAddr == 0x00) - { - if ((value & 0x02) != 0) - { - Console.WriteLine("TIA VSYNC On"); - // Frame is complete, output to buffer - outputFrame(); - scanlinesBuffer.Clear(); - frameComplete = true; - scanlinePos = 0; - } - else - { - Console.WriteLine("TIA VSYNC Off"); - } - } - else if (maskedAddr == 0x01) - { - vblankEnabled = (value & 0x02) != 0; - if ((value & 0x02) != 0) - { - Console.WriteLine("TIA Vblank On"); - } - else - { - Console.WriteLine("TIA Vblank Off"); - } - inpt_latching = (value & 0x40) != 0; - } - else if (maskedAddr == 0x02) // WSYNC - { - Console.WriteLine("TIA WSYNC"); - while (scanlinePos > 0) - { - execute(1); - } - } - else if (maskedAddr == 0x04) // NUSIZ0 - { - byte size = (byte)(value & 0x07); - switch (size) - { - case 0x00: - player0copies = 0; - break; - case 0x01: - player0copies = 1; - player0copy1 = 16; - break; - case 0x02: - player0copies = 1; - player0copy1 = 32; - break; - case 0x03: - player0copies = 2; - player0copy1 = 16; - player0copy2 = 32; - break; - case 0x06: - player0copies = 2; - player0copy1 = 32; - player0copy2 = 64; - break; - } - } - else if (maskedAddr == 0x05) // NUSIZ1 - { - byte size = (byte)(value & 0x07); - switch (size) - { - case 0x00: - player1copies = 0; - break; - case 0x01: - player1copies = 1; - player1copy1 = 16; - break; - case 0x02: - player1copies = 1; - player1copy1 = 32; - break; - case 0x03: - player1copies = 2; - player1copy1 = 16; - player1copy2 = 32; - break; - case 0x06: - player1copies = 2; - player1copy1 = 32; - player1copy2 = 64; - break; - } - } - else if (maskedAddr == 0x06) // COLUP0 - { - player0.color = (byte)(value & 0xFE); - } - else if (maskedAddr == 0x07) // COLUP1 - { - player1.color = (byte)(value & 0xFE); - } - else if (maskedAddr == 0x08) // COLUPF - { - PFcolor = (byte)(value & 0xFE); - } - else if (maskedAddr == 0x09) // COLUBK - { - BKcolor = (byte)(value & 0xFE); - } - else if (maskedAddr == 0x0A) // CTRLPF - { - PFpriority = (value & 0x04) != 0; - PFreflect = (value & 0x01) != 0; - PFscore = (value & 0x02) != 0; - - ball.size = (byte)((value & 0x30) >> 4); - } - else if (maskedAddr == 0x0B) // REFP0 - { - player0.reflect = ((value & 0x08) != 0); - } - else if (maskedAddr == 0x0C) // REFP1 - { - player1.reflect = ((value & 0x08) != 0); - } - else if (maskedAddr == 0x0D) // PF0 - { - PF = (UInt32)((PF & 0x0FFFF) + ((reverseBits(value) & 0x0F) << 16)); - } - else if (maskedAddr == 0x0E) // PF1 - { - PF = (UInt32)((PF & 0xF00FF) + (value << 8)); - } - else if (maskedAddr == 0x0F) // PF2 - { - PF = (PF & 0xFFF00) + reverseBits(value); - } - else if (maskedAddr == 0x10) // RESP0 - { - player0.pos = (byte)(scanlinePos - 68 + 5); - } - else if (maskedAddr == 0x11) // RESP1 - { - player1.pos = (byte)(scanlinePos - 68 + 5); - } - else if (maskedAddr == 0x14) // RESBL - { - ball.pos = (byte)(scanlinePos - 68 + 4); - } - else if (maskedAddr == 0x15) // AUDC0 - { - audioEnabled = value != 0; - } - else if (maskedAddr == 0x17) // AUDF0 - { - audioFreqDiv = (byte)(value + 1); - } - else if (maskedAddr == 0x1B) // GRP0 - { - player0.grp = value; - player1.dgrp = player1.grp; - } - else if (maskedAddr == 0x1C) // GRP1 - { - player1.grp = value; - player0.dgrp = player0.grp; - } - else if (maskedAddr == 0x1F) // ENABL - { - ball.enabled = (value & 0x02) != 0; - } - else if (maskedAddr == 0x20) // HMP0 - { - player0.HM = (byte)((value & 0xF0) >> 4); - } - else if (maskedAddr == 0x21) // HMP1 - { - player1.HM = (byte)((value & 0xF0) >> 4); - } - else if (maskedAddr == 0x24) // HMBL - { - ball.HM = (byte)((value & 0xF0) >> 4); - } - else if (maskedAddr == 0x25) // VDELP0 - { - player0.delay = (value & 0x01) != 0; - } - else if (maskedAddr == 0x26) // VDELP1 - { - player1.delay = (value & 0x01) != 0; - } - else if (maskedAddr == 0x2A) // HMOVE - { - player0.pos = (byte)(player0.pos + hmove[player0.HM]); - player1.pos = (byte)(player1.pos + hmove[player1.HM]); - ball.pos = (byte)(ball.pos + hmove[ball.HM]); - - player0.HM = 0; - player1.HM = 0; - ball.HM = 0; - - hmoveHappened = true; - } - else if (maskedAddr == 0x2C) // CXCLR - { - P0_collisions = 0; - P1_collisions = 0; - M0_collisions = 0; - M1_collisions = 0; - BL_collisions = 0; - } - } - - public byte reverseBits(byte value) - { - byte result = 0x00; - for (int i = 0; i < 8; i++) - { - result = (byte)(result | (((value >> i) & 0x01 ) << (7-i))); - } - return result; - } - } -} \ No newline at end of file