[ChannelFHawk] More accurate rates

This commit is contained in:
ASNiVOR 2024-09-05 21:47:19 +01:00
parent 6d05b9874c
commit 81043839c1
5 changed files with 82 additions and 28 deletions

View File

@ -78,6 +78,9 @@ namespace BizHawk.Client.Common
["O2_PAL"] = 89478485.0 / 1800319, // 49.70146124103561646574857011
["TIC80"] = 60,
["ChannelF"] = 60.5307257846, // (3579545 * 8 / 7) / (256 * 264)
["ChannelF_PAL"] = 50.0801282051, // 4000000 / (256 * 312)
};
public static double GetFrameRate(string systemId, bool pal)

View File

@ -12,14 +12,31 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
public bool DeterministicEmulation { get; set; }
private double cpuFreq => region == RegionType.NTSC ? 1.7897725 : 2.000000;
private double refreshRate => region == RegionType.NTSC ? 60 : 50;
private double cpuFreq;
private double refreshRate => region == RegionType.NTSC ? 60.5307257846 : 50.0801282051;
public int ClockPerFrame;
public int FrameClock = 0;
private void CalcClock()
{
// CPU speeds from https://en.wikipedia.org/wiki/Fairchild_Channel_F
if (Region == DisplayType.NTSC)
{
cpuFreq = 1.7897725;
}
else
{
if (version == ConsoleVersion.ChannelF)
{
cpuFreq = 2.0;
}
else if (version == ConsoleVersion.ChannelF_II)
{
cpuFreq = 1.9704972;
}
}
var c = ((cpuFreq * 1000000) / refreshRate);
ClockPerFrame = (int) c;

View File

@ -59,7 +59,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
[DefaultValue(RegionType.NTSC)]
public RegionType Region { get; set; }
[DisplayName("Version")]
[Description("Both versions are the same from an emulation perspective. Channel F II has a very slightly different BIOS to Channel F")]
[Description("Channel F II has a very slightly different BIOS to Channel F and a slightly slower CPU in the PAL version compared to v1")]
[DefaultValue(ConsoleVersion.ChannelF)]
public ConsoleVersion Version { get; set; }

View File

@ -39,9 +39,18 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
private int latch_x;
private int latch_y;
private readonly int[] frameBuffer = new int[128 * 64];
private int scanlineRepeats;
private int[] frameBuffer;
private int[] outputBuffer;
private void BuildFrame()
public void SetupVideo()
{
scanlineRepeats = Region == DisplayType.NTSC ? 4 : 5;
frameBuffer = new int[128 * 64];
outputBuffer = new int[128 * 2 * 64 * scanlineRepeats];
}
private void BuildFrameFromRAM()
{
for (int r = 0; r < 64; r++)
{
@ -59,42 +68,66 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
}
}
private void ExpandFrame()
{
int initialWidth = 128;
int initialHeight = 64;
//public int _frameHz => region == RegionType.NTSC ? 60 : 50;
public int[] CroppedBuffer = new int[102 * 58];
public int VirtualWidth => BufferWidth * 4;
public int VirtualHeight => (int)(BufferHeight * 1.43) * 4;
public int BufferWidth => 102; //128
public int BufferHeight => 58; //64
for (int lines = 0; lines < initialHeight; lines++)
{
for (int i = 0; i < scanlineRepeats; i++)
{
for (int x = 0; x < initialWidth; x++)
{
for (int j = 0; j < 2; j++)
{
outputBuffer[(lines * scanlineRepeats + i) * initialWidth * 2 + x * 2 + j] = FPalette[frameBuffer[lines * initialWidth + x]];
}
}
}
}
}
public int lBorder => 8;
public int rBorder => 52;
public int tBorder => 8;
public int bBorder => 4;
public int VirtualWidth => (int)((BufferWidth - lBorder - rBorder) * 2.2);
public int VirtualHeight => Region == DisplayType.NTSC ? BufferHeight - tBorder - bBorder : (int)((BufferHeight - tBorder - bBorder) * 0.8);
public int BufferWidth => 256 - lBorder - rBorder;
public int BufferHeight => (64 * scanlineRepeats) - tBorder - bBorder;
public int BackgroundColor => Colors.ARGB(0xFF, 0xFF, 0xFF);
public int VsyncNumerator => (int)refreshRate;
public int VsyncDenominator => 1;
public int[] GetVideoBuffer()
public int[] TrimOutputBuffer(int[] buff, int leftTrim, int topTrim, int rightTrim, int bottomTrim)
{
BuildFrame();
int initialWidth = 128 * 2;
int initialHeight = 64 * scanlineRepeats;
int newWidth = initialWidth - leftTrim - rightTrim;
int newHeight = initialHeight - topTrim - bottomTrim;
var lBorderWidth = 4;
var rBorderWidth = 128 - 102 - lBorderWidth;
var tBorderHeight = 4;
var bBorderHeight = 64 - 58 - tBorderHeight;
var startP = 128 * tBorderHeight;
var endP = 128 * bBorderHeight;
int[] trimmedBuffer = new int[newWidth * newHeight];
int index = 0;
for (int i = startP; i < frameBuffer.Length - endP; i += 128)
for (int y = 0; y < newHeight; y++)
{
for (int p = lBorderWidth; p < 128 - rBorderWidth; p++)
for (int x = 0; x < newWidth; x++)
{
if (index == CroppedBuffer.Length)
break;
CroppedBuffer[index++] = FPalette[frameBuffer[i + p]];
trimmedBuffer[y * newWidth + x] = buff[(y + topTrim) * initialWidth + (x + leftTrim)];
}
}
return CroppedBuffer;
return trimmedBuffer;
}
public int[] GetVideoBuffer()
{
BuildFrameFromRAM();
ExpandFrame();
return TrimOutputBuffer(outputBuffer, lBorder, tBorder, rBorder, bBorder);
}
public DisplayType Region => region == RegionType.NTSC ? DisplayType.NTSC : DisplayType.PAL;

View File

@ -57,6 +57,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
//Array.Copy(rom, 0, Rom, 0, rom.Length);
CalcClock();
SetupVideo();
ser.Register<IVideoProvider>(this);
ser.Register<ITraceable>(_tracer);