From 81043839c19697549b5999d22262165cb69e0c70 Mon Sep 17 00:00:00 2001 From: ASNiVOR Date: Thu, 5 Sep 2024 21:47:19 +0100 Subject: [PATCH] [ChannelFHawk] More accurate rates --- .../movie/PlatformFrameRates.cs | 3 + .../Fairchild/ChannelF/ChannelF.IEmulator.cs | 21 ++++- .../Fairchild/ChannelF/ChannelF.ISettable.cs | 2 +- .../ChannelF/ChannelF.IVideoProvider.cs | 83 +++++++++++++------ .../Consoles/Fairchild/ChannelF/ChannelF.cs | 1 + 5 files changed, 82 insertions(+), 28 deletions(-) diff --git a/src/BizHawk.Client.Common/movie/PlatformFrameRates.cs b/src/BizHawk.Client.Common/movie/PlatformFrameRates.cs index a7f11def23..9663de7c40 100644 --- a/src/BizHawk.Client.Common/movie/PlatformFrameRates.cs +++ b/src/BizHawk.Client.Common/movie/PlatformFrameRates.cs @@ -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) diff --git a/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IEmulator.cs b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IEmulator.cs index 60b43d77cd..681de25e83 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IEmulator.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IEmulator.cs @@ -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; diff --git a/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.ISettable.cs b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.ISettable.cs index 15a090cd31..d0e69e000d 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.ISettable.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.ISettable.cs @@ -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; } diff --git a/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IVideoProvider.cs b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IVideoProvider.cs index 630e86d2e0..c572fde69c 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IVideoProvider.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IVideoProvider.cs @@ -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; diff --git a/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.cs b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.cs index c7448cf4f6..7480173018 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.cs @@ -57,6 +57,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF //Array.Copy(rom, 0, Rom, 0, rom.Length); CalcClock(); + SetupVideo(); ser.Register(this); ser.Register(_tracer);