2600: more stuff towards PAL support

This commit is contained in:
goyuken 2014-05-23 15:47:48 +00:00
parent 59440c1d4d
commit 2f7ad6a676
5 changed files with 67 additions and 15 deletions

View File

@ -34,10 +34,17 @@ namespace BizHawk.Emulation.Common
public bool NotInDatabase = true; public bool NotInDatabase = true;
public string FirmwareHash; public string FirmwareHash;
readonly Dictionary<string, string> Options = new Dictionary<string, string>(); Dictionary<string, string> Options = new Dictionary<string, string>();
public GameInfo() { } public GameInfo() { }
public GameInfo Clone()
{
var ret = (GameInfo)MemberwiseClone();
ret.Options = new Dictionary<string, string>(Options);
return ret;
}
public static GameInfo GetNullGame() public static GameInfo GetNullGame()
{ {
return new GameInfo return new GameInfo

View File

@ -71,6 +71,7 @@
<RequiredTargetFramework>3.5</RequiredTargetFramework> <RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference> </Reference>
<Reference Include="System.Drawing" /> <Reference Include="System.Drawing" />
<Reference Include="System.Numerics" />
<Reference Include="System.Windows.Forms" /> <Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq"> <Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework> <RequiredTargetFramework>3.5</RequiredTargetFramework>

View File

@ -279,7 +279,17 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
OnExecFetch = this.ExecFetch OnExecFetch = this.ExecFetch
}; };
_tia = new TIA(this); // TODO: add to game db so we only run DetectPal() on unknown games
bool pal;
if (_game["PAL"])
pal = true;
else if (_game["NTSC"])
pal = false;
else
pal = DetectPal(_game, Rom);
_tia = new TIA(this, pal);
_tia.GetFrameRate(out CoreComm.VsyncNum, out CoreComm.VsyncDen);
// dcfilter coefficent is from real observed hardware behavior: a latched "1" will fully decay by ~170 or so tia sound cycles // 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); _dcfilter = DCFilter.AsISoundProvider(_tia, 256);
@ -326,7 +336,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
_islag = true; _islag = true;
_tia.LineCount = 0; _tia.LineCount = 0;
_tia.BeginAudioFrame(); _tia.BeginAudioFrame();
while (_tia.LineCount < 262) // will be 312 for PAL while (_tia.LineCount < _tia.NominalNumScanlines)
{ {
CycleAdvance(); CycleAdvance();
} }

View File

@ -255,10 +255,17 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
private static bool DetectPal(GameInfo game, byte[] rom) private static bool DetectPal(GameInfo game, byte[] rom)
{ {
// force NTSC mode for the new core we instantiate
var newgame = game.Clone();
if (newgame["PAL"])
newgame.RemoveOption("PAL");
if (!newgame["NTSC"])
newgame.AddOption("NTSC");
// give the emu a minimal of input\output connections so it doesn't crash // give the emu a minimal of input\output connections so it doesn't crash
var comm = new CoreComm(null, null); var comm = new CoreComm(null, null);
comm.InputCallback = new InputCallbackSystem(); comm.InputCallback = new InputCallbackSystem();
using (Atari2600 emu = new Atari2600(new CoreComm(null, null), game, rom, null, null)) using (Atari2600 emu = new Atari2600(new CoreComm(null, null), newgame, rom, null, null))
{ {
emu.Controller = new NullController(); emu.Controller = new NullController();
@ -267,8 +274,9 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
for (int i = 0; i < 71; i++) // run for 71 * 262 lines, since we're in NTSC mode for (int i = 0; i < 71; i++) // run for 71 * 262 lines, since we're in NTSC mode
emu.FrameAdvance(false, false); emu.FrameAdvance(false, false);
int numpal = framecounts.Count((i) => i > 287); int numpal = framecounts.Count((i) => i > 287);
Console.WriteLine("{0} PAL", numpal); bool pal = numpal >= 25;
return numpal >= 25; Console.WriteLine("PAL Detection: {0} lines, {1}", numpal, pal);
return pal;
} }
} }
} }

View File

@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using BizHawk.Common; using BizHawk.Common;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using System.Numerics;
namespace BizHawk.Emulation.Cores.Atari.Atari2600 namespace BizHawk.Emulation.Cores.Atari.Atari2600
{ {
@ -143,6 +144,29 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
#endregion #endregion
// in all cases, the TIA has 228 clocks per scanline
// the NTSC TIA has a clock rate of 3579575hz
// the PAL/SECAM TIA has a clock rate of 3546894hz
private bool _pal;
public int NominalNumScanlines
{
get
{
return _pal ? 312 : 262;
}
}
public void GetFrameRate(out int num, out int den)
{
int clockrate = _pal ? 3546894 : 3579575;
int clocksperframe = 228 * NominalNumScanlines;
int gcd = (int)BigInteger.GreatestCommonDivisor(clockrate, clocksperframe);
num = clockrate / gcd;
den = clocksperframe / gcd;
}
private const int ScreenWidth = 160; private const int ScreenWidth = 160;
private const int MaxScreenHeight = 312; private const int MaxScreenHeight = 312;
@ -156,7 +180,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
private readonly Atari2600 _core; private readonly Atari2600 _core;
private int[] _scanlinebuffer = new int[ScreenWidth * MaxScreenHeight]; private int[] _scanlinebuffer = new int[ScreenWidth * MaxScreenHeight];
private readonly int[] _palette = NTSCPalette; // todo: make this NTSC or PAL, obviously private readonly int[] _palette;
private byte _hsyncCnt; private byte _hsyncCnt;
private int _capChargeStart; private int _capChargeStart;
@ -173,11 +197,13 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
public Audio[] AUD = { new Audio(), new Audio() }; public Audio[] AUD = { new Audio(), new Audio() };
public TIA(Atari2600 core) public TIA(Atari2600 core, bool pal)
{ {
_core = core; _core = core;
_player0.ScanCnt = 8; _player0.ScanCnt = 8;
_player1.ScanCnt = 8; _player1.ScanCnt = 8;
_pal = pal;
_palette = _pal ? PALPalette : NTSCPalette;
} }
public int CurrentScanLine public int CurrentScanLine
@ -209,6 +235,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
public int VirtualWidth public int VirtualWidth
{ {
// TODO: PAL?
get { return 275; } // 275 comes from NTSC specs and the actual pixel clock of a 2600 TIA get { return 275; } // 275 comes from NTSC specs and the actual pixel clock of a 2600 TIA
} }
@ -226,11 +253,10 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
{ {
get get
{ {
// TODO PAL support if (_pal)
//if (false) return _core.Settings.PALBottomLine - _core.Settings.PALTopLine;
// return _core.Settings.PALBottomLine - _core.Settings.PALTopLine; else
//else return _core.Settings.NTSCBottomLine - _core.Settings.NTSCTopLine;
return _core.Settings.NTSCBottomLine - _core.Settings.NTSCTopLine;
} }
} }
@ -595,8 +621,8 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
void OutputFrame(int validlines) void OutputFrame(int validlines)
{ {
int topLine = _core.Settings.NTSCTopLine; int topLine = _pal ? _core.Settings.PALTopLine : _core.Settings.NTSCTopLine;
int bottomLine = _core.Settings.NTSCBottomLine; int bottomLine = _pal ? _core.Settings.PALBottomLine : _core.Settings.NTSCBottomLine;
// if vsync occured unexpectedly early, black out the remainer // if vsync occured unexpectedly early, black out the remainer
for (; validlines < bottomLine; validlines++) for (; validlines < bottomLine; validlines++)