Atari 2600 - a round of cleanup, nothing useful here
This commit is contained in:
parent
209142bea1
commit
81ca8479f5
|
@ -177,6 +177,7 @@
|
|||
<Compile Include="Consoles\Atari\2600\Atari2600.cs" />
|
||||
<Compile Include="Consoles\Atari\2600\Atari2600.Core.cs" />
|
||||
<Compile Include="Consoles\Atari\2600\Atari2600.RomHeuristics.cs" />
|
||||
<Compile Include="Consoles\Atari\2600\Atari2600.Settings.cs" />
|
||||
<Compile Include="Consoles\Atari\2600\Mappers\m0840.cs" />
|
||||
<Compile Include="Consoles\Atari\2600\Mappers\m3E.cs" />
|
||||
<Compile Include="Consoles\Atari\2600\Mappers\m3F.cs" />
|
||||
|
|
|
@ -11,6 +11,8 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
private TIA _tia;
|
||||
private DCFilter _dcfilter;
|
||||
private MapperBase _mapper;
|
||||
private bool _hardResetSignal;
|
||||
|
||||
public byte[] Ram;
|
||||
|
||||
public byte[] Rom { get; private set; }
|
||||
|
@ -117,7 +119,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
|
||||
private static MapperBase SetMultiCartMapper(int romLength, int gameTotal)
|
||||
{
|
||||
switch(romLength / gameTotal)
|
||||
switch (romLength / gameTotal)
|
||||
{
|
||||
case 1024 * 2: // 2K
|
||||
return new Multicart2K(gameTotal);
|
||||
|
@ -296,8 +298,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
Cpu.PC = (ushort)(ReadMemory(0x1FFC) + (ReadMemory(0x1FFD) << 8)); // set the initial PC
|
||||
}
|
||||
|
||||
private bool _hardResetSignal;
|
||||
|
||||
public void FrameAdvance(bool render, bool rendersound)
|
||||
{
|
||||
_frame++;
|
||||
|
@ -308,6 +308,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
{
|
||||
CycleAdvance();
|
||||
}
|
||||
|
||||
_tia.CompleteAudioFrame();
|
||||
|
||||
if (_hardResetSignal)
|
||||
|
|
|
@ -0,0 +1,141 @@
|
|||
using System;
|
||||
using System.ComponentModel;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||
{
|
||||
public partial class Atari2600
|
||||
{
|
||||
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 class A2600Settings
|
||||
{
|
||||
[JsonIgnore]
|
||||
private int _ntscTopLine = 24;
|
||||
|
||||
[JsonIgnore]
|
||||
private int _ntscBottomLine = 248;
|
||||
|
||||
[JsonIgnore]
|
||||
private int _palTopLine = 24;
|
||||
|
||||
[JsonIgnore]
|
||||
private int _palBottomLine = 296;
|
||||
|
||||
[Description("Sets whether or not the Background layer will be displayed")]
|
||||
public bool ShowBG { get; set; }
|
||||
|
||||
[Description("Sets whether or not the Player 1 layer will be displayed")]
|
||||
public bool ShowPlayer1 { get; set; }
|
||||
|
||||
[Description("Sets whether or not the Player 2 layer will be displayed")]
|
||||
public bool ShowPlayer2 { get; set; }
|
||||
|
||||
[Description("Sets whether or not the Missle 1 layer will be displayed")]
|
||||
public bool ShowMissle1 { get; set; }
|
||||
|
||||
[Description("Sets whether or not the Missle 2 layer will be displayed")]
|
||||
public bool ShowMissle2 { get; set; }
|
||||
|
||||
[Description("Sets whether or not the Ball layer will be displayed")]
|
||||
public bool ShowBall { get; set; }
|
||||
|
||||
[Description("Sets whether or not the Playfield layer will be displayed")]
|
||||
public bool ShowPlayfield { get; set; }
|
||||
|
||||
public int NTSCTopLine
|
||||
{
|
||||
get { return this._ntscTopLine; }
|
||||
set { _ntscTopLine = Math.Min(64, Math.Max(value, 0)); }
|
||||
}
|
||||
|
||||
public int NTSCBottomLine
|
||||
{
|
||||
get { return _ntscBottomLine; }
|
||||
set { _ntscBottomLine = Math.Min(260, Math.Max(value, 192)); }
|
||||
}
|
||||
|
||||
public int PALTopLine
|
||||
{
|
||||
get { return this._palTopLine; }
|
||||
set { this._palTopLine = Math.Min(64, Math.Max(value, 0)); }
|
||||
}
|
||||
|
||||
public int PALBottomLine
|
||||
{
|
||||
get { return this._palBottomLine; }
|
||||
set { this._palBottomLine = Math.Min(310, Math.Max(value, 192)); }
|
||||
}
|
||||
|
||||
public int BackgroundColor { get; set; }
|
||||
|
||||
public A2600Settings Clone()
|
||||
{
|
||||
return (A2600Settings)MemberwiseClone();
|
||||
}
|
||||
|
||||
public static A2600Settings GetDefaults()
|
||||
{
|
||||
return new A2600Settings
|
||||
{
|
||||
ShowBG = true,
|
||||
ShowPlayer1 = true,
|
||||
ShowPlayer2 = true,
|
||||
ShowMissle1 = true,
|
||||
ShowMissle2 = true,
|
||||
ShowBall = true,
|
||||
ShowPlayfield = true,
|
||||
BackgroundColor = 0
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public class A2600SyncSettings
|
||||
{
|
||||
[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; }
|
||||
|
||||
public A2600SyncSettings Clone()
|
||||
{
|
||||
return (A2600SyncSettings)MemberwiseClone();
|
||||
}
|
||||
|
||||
public static A2600SyncSettings GetDefaults()
|
||||
{
|
||||
return new A2600SyncSettings
|
||||
{
|
||||
BW = false,
|
||||
LeftDifficulty = true,
|
||||
RightDifficulty = true
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,14 +1,11 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||
{
|
||||
[CoreAttributes(
|
||||
|
@ -167,7 +164,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
};
|
||||
}
|
||||
|
||||
// TODO: rewrite GetCpuFlagsAndRegisters this way
|
||||
public Dictionary<string, int> GetCpuFlagsAndRegisters()
|
||||
{
|
||||
return new Dictionary<string, int>
|
||||
|
@ -256,118 +252,5 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
}
|
||||
|
||||
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 class A2600Settings
|
||||
{
|
||||
// todo: descriptions
|
||||
public bool ShowBG { get; set; }
|
||||
public bool ShowPlayer1 { get; set; }
|
||||
public bool ShowPlayer2 { get; set; }
|
||||
public bool ShowMissle1 { get; set; }
|
||||
public bool ShowMissle2 { get; set; }
|
||||
public bool ShowBall { get; set; }
|
||||
public bool ShowPlayfield { get; set; }
|
||||
|
||||
public int NTSCTopLine
|
||||
{
|
||||
get { return _NTSCTopLine; }
|
||||
set { _NTSCTopLine = Math.Min(64, Math.Max(value, 0)); }
|
||||
}
|
||||
public int NTSCBottomLine
|
||||
{
|
||||
get { return _NTSCBottomLine; }
|
||||
set { _NTSCBottomLine = Math.Min(260, Math.Max(value, 192)); }
|
||||
}
|
||||
[JsonIgnore]
|
||||
private int _NTSCTopLine = 24;
|
||||
[JsonIgnore]
|
||||
private int _NTSCBottomLine = 248;
|
||||
|
||||
public int PALTopLine
|
||||
{
|
||||
get { return _PALTopLine; }
|
||||
set { _PALTopLine = Math.Min(64, Math.Max(value, 0)); }
|
||||
}
|
||||
public int PALBottomLine
|
||||
{
|
||||
get { return _PALBottomLine; }
|
||||
set { _PALBottomLine = Math.Min(310, Math.Max(value, 192)); }
|
||||
}
|
||||
[JsonIgnore]
|
||||
private int _PALTopLine = 24;
|
||||
[JsonIgnore]
|
||||
private int _PALBottomLine = 296;
|
||||
|
||||
public int BackgroundColor { get; set; }
|
||||
|
||||
public A2600Settings Clone()
|
||||
{
|
||||
return (A2600Settings)MemberwiseClone();
|
||||
}
|
||||
|
||||
public static A2600Settings GetDefaults()
|
||||
{
|
||||
return new A2600Settings
|
||||
{
|
||||
ShowBG = true,
|
||||
ShowPlayer1 = true,
|
||||
ShowPlayer2 = true,
|
||||
ShowMissle1 = true,
|
||||
ShowMissle2 = true,
|
||||
ShowBall = true,
|
||||
ShowPlayfield = true,
|
||||
BackgroundColor = 0
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public class A2600SyncSettings
|
||||
{
|
||||
[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; }
|
||||
|
||||
public A2600SyncSettings Clone()
|
||||
{
|
||||
return (A2600SyncSettings)MemberwiseClone();
|
||||
}
|
||||
|
||||
public static A2600SyncSettings GetDefaults()
|
||||
{
|
||||
return new A2600SyncSettings
|
||||
{
|
||||
BW = false,
|
||||
LeftDifficulty = true,
|
||||
RightDifficulty = true
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,9 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
// Emulates the TIA
|
||||
public partial class TIA : IVideoProvider, ISoundProvider
|
||||
{
|
||||
private const int ScreenWidth = 160;
|
||||
private const int MaxScreenHeight = 312;
|
||||
|
||||
private const byte CXP0 = 0x01;
|
||||
private const byte CXP1 = 0x02;
|
||||
private const byte CXM0 = 0x04;
|
||||
|
@ -90,25 +93,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
get { return _vsyncEnabled; }
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
_hsyncCnt = 0;
|
||||
_capChargeStart = 0;
|
||||
_capCharging = false;
|
||||
_vblankEnabled = false;
|
||||
_vsyncEnabled = false;
|
||||
_scanline = new uint[160];
|
||||
|
||||
_player0 = new PlayerData();
|
||||
_player1 = new PlayerData();
|
||||
_playField = new PlayfieldData();
|
||||
_hmove = new HMoveData();
|
||||
_ball = new BallData();
|
||||
|
||||
_player0.ScanCnt = 8;
|
||||
_player1.ScanCnt = 8;
|
||||
}
|
||||
|
||||
public bool FrameComplete { get; set; }
|
||||
public int MaxVolume { get; set; }
|
||||
|
||||
|
@ -148,6 +132,25 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
return FrameBuffer;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
_hsyncCnt = 0;
|
||||
_capChargeStart = 0;
|
||||
_capCharging = false;
|
||||
_vblankEnabled = false;
|
||||
_vsyncEnabled = false;
|
||||
_scanline = new uint[160];
|
||||
|
||||
_player0 = new PlayerData();
|
||||
_player1 = new PlayerData();
|
||||
_playField = new PlayfieldData();
|
||||
_hmove = new HMoveData();
|
||||
_ball = new BallData();
|
||||
|
||||
_player0.ScanCnt = 8;
|
||||
_player1.ScanCnt = 8;
|
||||
}
|
||||
|
||||
// Execute TIA cycles
|
||||
public void Execute(int cycles)
|
||||
{
|
||||
|
@ -480,9 +483,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
|
||||
public int[] FrameBuffer = new int[ScreenWidth * MaxScreenHeight];
|
||||
|
||||
private const int ScreenWidth = 160;
|
||||
private const int MaxScreenHeight = 312;
|
||||
|
||||
public void OutputFrame()
|
||||
{
|
||||
var topLine = _core.Settings.NTSCTopLine;
|
||||
|
@ -870,12 +870,10 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
return result;
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// Audio bits
|
||||
// =========================================================================
|
||||
#region Audio bits
|
||||
|
||||
enum AudioRegister : byte { AUDC, AUDF, AUDV }
|
||||
struct QueuedCommand
|
||||
private enum AudioRegister : byte { AUDC, AUDF, AUDV }
|
||||
private struct QueuedCommand
|
||||
{
|
||||
public int Time;
|
||||
public byte Channel;
|
||||
|
@ -883,8 +881,8 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
public byte Value;
|
||||
}
|
||||
|
||||
int frameStartCycles, frameEndCycles;
|
||||
Queue<QueuedCommand> commands = new Queue<QueuedCommand>(4096);
|
||||
private int frameStartCycles, frameEndCycles;
|
||||
private Queue<QueuedCommand> commands = new Queue<QueuedCommand>(4096);
|
||||
|
||||
public void BeginAudioFrame()
|
||||
{
|
||||
|
@ -896,18 +894,24 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
frameEndCycles = _core.Cpu.TotalExecutedCycles;
|
||||
}
|
||||
|
||||
void WriteAudio(byte channel, AudioRegister register, byte value)
|
||||
private void WriteAudio(byte channel, AudioRegister register, byte value)
|
||||
{
|
||||
commands.Enqueue(new QueuedCommand { Channel = channel, Register = register, Value = value, Time = _core.Cpu.TotalExecutedCycles - frameStartCycles });
|
||||
}
|
||||
|
||||
void ApplyAudioCommand(QueuedCommand cmd)
|
||||
private void ApplyAudioCommand(QueuedCommand cmd)
|
||||
{
|
||||
switch (cmd.Register)
|
||||
{
|
||||
case AudioRegister.AUDC: AUD[cmd.Channel].AUDC = cmd.Value; break;
|
||||
case AudioRegister.AUDF: AUD[cmd.Channel].AUDF = cmd.Value; break;
|
||||
case AudioRegister.AUDV: AUD[cmd.Channel].AUDV = cmd.Value; break;
|
||||
case AudioRegister.AUDC:
|
||||
AUD[cmd.Channel].AUDC = cmd.Value;
|
||||
break;
|
||||
case AudioRegister.AUDF:
|
||||
AUD[cmd.Channel].AUDF = cmd.Value;
|
||||
break;
|
||||
case AudioRegister.AUDV:
|
||||
AUD[cmd.Channel].AUDV = cmd.Value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -917,22 +921,25 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
|
||||
int elapsedCycles = frameEndCycles - frameStartCycles;
|
||||
if (elapsedCycles == 0)
|
||||
{
|
||||
elapsedCycles = 1; // better than diving by zero
|
||||
}
|
||||
|
||||
int start = 0;
|
||||
while (commands.Count > 0)
|
||||
{
|
||||
var cmd = commands.Dequeue();
|
||||
int pos = ((cmd.Time * samples31khz.Length) / elapsedCycles);
|
||||
int pos = (cmd.Time * samples31khz.Length) / elapsedCycles;
|
||||
pos = Math.Min(pos, samples31khz.Length); // sometimes the cpu timestamp of the write is > frameEndCycles
|
||||
GetSamplesImmediate(samples31khz, start, pos - start);
|
||||
start = pos;
|
||||
ApplyAudioCommand(cmd);
|
||||
}
|
||||
|
||||
GetSamplesImmediate(samples31khz, start, samples31khz.Length - start);
|
||||
|
||||
// convert from 31khz to 44khz
|
||||
for (int i = 0; i < samples.Length / 2; i++)
|
||||
for (var i = 0; i < samples.Length / 2; i++)
|
||||
{
|
||||
samples[i * 2] = samples31khz[(int)(((double)samples31khz.Length / (double)(samples.Length / 2)) * i)];
|
||||
samples[(i * 2) + 1] = samples[i * 2];
|
||||
|
@ -941,7 +948,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
|
||||
public void GetSamplesImmediate(short[] samples, int start, int len)
|
||||
{
|
||||
for (int i = start; i < start + len; i++)
|
||||
for (var i = start; i < start + len; i++)
|
||||
{
|
||||
samples[i] += AUD[0].Cycle();
|
||||
samples[i] += AUD[1].Cycle();
|
||||
|
@ -953,8 +960,8 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
commands.Clear();
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
|
||||
#endregion
|
||||
|
||||
public void SyncState(Serializer ser)
|
||||
{
|
||||
ser.BeginSection("TIA");
|
||||
|
|
Loading…
Reference in New Issue