From 47a5ce279804c2c1d152b31b10c5398dbca1ff41 Mon Sep 17 00:00:00 2001 From: Asnivor Date: Tue, 7 May 2019 14:43:36 +0100 Subject: [PATCH 1/2] ChannelF: some more changes --- .../BizHawk.Emulation.Cores.csproj | 6 +- .../Computers/SinclairSpectrum/Machine/ULA.cs | 2 +- .../Consoles/Fairchild/ChannelF/Cart.cs | 16 + .../ChannelF/ChannelF.Controllers.cs | 147 ++++++- .../Fairchild/ChannelF/ChannelF.IEmulator.cs | 7 +- .../Fairchild/ChannelF/ChannelF.IO.cs | 85 ---- .../Fairchild/ChannelF/ChannelF.IStatable.cs | 10 +- .../ChannelF/ChannelF.IVideoProvider.cs | 118 ++---- .../ChannelF/ChannelF.MemoryDomains.cs | 4 +- .../Consoles/Fairchild/ChannelF/ChannelF.cs | 4 +- .../Fairchild/ChannelF/F8/F3850.ALU.cs | 111 +---- .../ChannelF/F8/F3850.Disassembler.cs | 92 ++-- .../Fairchild/ChannelF/F8/F3850.Execute.cs | 82 ++-- .../Fairchild/ChannelF/F8/F3850.Operations.cs | 281 +++++++++++++ .../Fairchild/ChannelF/F8/F3850.Registers.cs | 4 + .../Fairchild/ChannelF/F8/F3850.Tables.cs | 192 ++++++--- .../Consoles/Fairchild/ChannelF/F8/F3850.cs | 397 ++++++++++-------- .../Consoles/Fairchild/ChannelF/Memory.cs | 55 +++ .../Consoles/Fairchild/ChannelF/Ports.cs | 188 +++++++++ .../Consoles/Fairchild/ChannelF/Video.cs | 120 ++++++ 20 files changed, 1307 insertions(+), 614 deletions(-) create mode 100644 BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Cart.cs delete mode 100644 BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IO.cs create mode 100644 BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Operations.cs create mode 100644 BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Memory.cs create mode 100644 BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Ports.cs create mode 100644 BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Video.cs diff --git a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj index 375e04e43d..5ed3b20e4f 100644 --- a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj +++ b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj @@ -596,7 +596,6 @@ - @@ -605,12 +604,17 @@ + + + + + diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ULA.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ULA.cs index df7541189e..6ab1341a93 100644 --- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ULA.cs +++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ULA.cs @@ -940,7 +940,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum return croppedBuffer; case ZXSpectrum.BorderType.None: - // all border sizes now 24 + // all border sizes now 0 var lR__ = BorderLeftWidth; var rR__ = BorderRightWidth; var tR__ = BorderTopHeight; diff --git a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Cart.cs b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Cart.cs new file mode 100644 index 0000000000..d2d52dda5b --- /dev/null +++ b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Cart.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BizHawk.Emulation.Cores.Consoles.ChannelF +{ + /// + /// Cartridge and related functions + /// + public partial class ChannelF + { + public byte[] Rom = new byte[4096]; + } +} diff --git a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.Controllers.cs b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.Controllers.cs index b0fa1ec6bb..80a2ae7931 100644 --- a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.Controllers.cs +++ b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.Controllers.cs @@ -1,12 +1,127 @@ using System; using System.Collections.Generic; +using System.Windows.Forms; using BizHawk.Common.BufferExtensions; +using BizHawk.Common.NumberExtensions; using BizHawk.Emulation.Common; namespace BizHawk.Emulation.Cores.Consoles.ChannelF { public partial class ChannelF { + public bool[] StateConsole = new bool[4]; + public string[] ButtonsConsole = new string[] + { + "TIME", "MODE", "HOLD", "START" + }; + public byte DataConsole + { + get + { + int w = 0; + for (int i = 0; i < 4; i++) + { + byte mask = (byte) (1 << i); + w = StateConsole[i] ? w | mask : w & ~mask; + } + + return (byte)(w & 0xFF); + } + } + + public bool[] StateRight = new bool[8]; + public string[] ButtonsRight = new string[] + { + "Right", "Left", "Back", "Forward", "CCW", "CW", "Pull", "Push" + }; + public byte DataRight + { + get + { + int w = 0; + for (int i = 0; i < 8; i++) + { + byte mask = (byte)(1 << i); + w = StateRight[i] ? w | mask : w & ~mask; + } + + return (byte)(w & 0xFF); + } + } + + public bool[] StateLeft = new bool[8]; + public string[] ButtonsLeft = new string[] + { + "Right", "Left", "Back", "Forward", "CCW", "CW", "Pull", "Push" + }; + public byte DataLeft + { + get + { + int w = 0; + for (int i = 0; i < 8; i++) + { + byte mask = (byte)(1 << i); + w = StateLeft[i] ? w | mask : w & ~mask; + } + + return (byte)(w & 0xFF); + } + } + + + /// + /// Cycles through all the input callbacks + /// This should be done once per frame + /// + public bool PollInput() + { + bool noInput = true; + + InputCallbacks.Call(); + + lock (this) + { + for (int i = 0; i < ButtonsConsole.Length; i++) + { + var key = ButtonsConsole[i]; + bool prevState = StateConsole[i]; // CTRLConsole.Bit(i); + bool currState = _controller.IsPressed(key); + if (currState != prevState) + { + StateConsole[i] = currState; + noInput = false; + } + } + + for (int i = 0; i < ButtonsRight.Length; i++) + { + var key = "P1 " + ButtonsRight[i]; + bool prevState = StateRight[i]; + bool currState = _controller.IsPressed(key); + if (currState != prevState) + { + StateRight[i] = currState; + noInput = false; + } + } + + for (int i = 0; i < ButtonsLeft.Length; i++) + { + var key = "P2 " + ButtonsLeft[i]; + bool prevState = StateLeft[i]; + bool currState = _controller.IsPressed(key); + if (currState != prevState) + { + StateLeft[i] = currState; + noInput = false; + } + } + } + + return noInput; + } + public ControllerDefinition ChannelFControllerDefinition { get @@ -14,23 +129,13 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF ControllerDefinition definition = new ControllerDefinition(); definition.Name = "ChannelF Controller"; + string pre = "P1 "; + // sticks - List stickL = new List - { - // P1 (left) stick - "P1 Up", "P1 Down", "P1 Left", "P1 Right", "P1 Button Up", "P1 Button Down", "P1 Rotate Left", "P1 Rotate Right" - }; - - foreach (var s in stickL) - { - definition.BoolButtons.Add(s); - definition.CategoryLabels[s] = "Left Controller"; - } - List stickR = new List { - // P1 (left) stick - "P2 Up", "P2 Down", "P2 Left", "P2 Right", "P2 Button Up", "P2 Button Down", "P2 Rotate Left", "P2 Rotate Right" + // P1 (right) stick + pre + "Forward", pre + "Back", pre + "Left", pre + "Right", pre + "CCW", pre + "CW", pre + "Pull", pre + "Push" }; foreach (var s in stickR) @@ -39,6 +144,20 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF definition.CategoryLabels[s] = "Right Controller"; } + pre = "P2 "; + + List stickL = new List + { + // P2 (left) stick + pre + "Forward", pre + "Back", pre + "Left", pre + "Right", pre + "CCW", pre + "CW", pre + "Pull", pre + "Push" + }; + + foreach (var s in stickL) + { + definition.BoolButtons.Add(s); + definition.CategoryLabels[s] = "Left Controller"; + } + // console List consoleButtons = new List { diff --git a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IEmulator.cs b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IEmulator.cs index 026fb361fb..4ce4fcaaa9 100644 --- a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IEmulator.cs +++ b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IEmulator.cs @@ -22,12 +22,15 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF private void CalcClock() { - var c = (cpuFreq * 1000000) / refreshRate; + var c = ((cpuFreq * 1000000) / refreshRate) * 4; ClockPerFrame = (int) c; } public bool FrameAdvance(IController controller, bool render, bool renderSound) { + _controller = controller; + _isLag = false; + if (_tracer.Enabled) { CPU.TraceCallback = s => _tracer.Put(s); @@ -37,6 +40,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF CPU.TraceCallback = null; } + _isLag = PollInput(); + while (FrameClock++ < ClockPerFrame) { CPU.ExecuteOne(); diff --git a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IO.cs b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IO.cs deleted file mode 100644 index 7aa343ee03..0000000000 --- a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IO.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using BizHawk.Common.BufferExtensions; -using BizHawk.Emulation.Common; - -namespace BizHawk.Emulation.Cores.Consoles.ChannelF -{ - - public partial class ChannelF - { - public byte[] BIOS01 = new byte[1024]; - public byte[] BIOS02 = new byte[1024]; - - public byte[] FrameBuffer = new byte[0x2000]; - - public byte[] Cartridge = new byte[0x2000 - 0x800]; - - public byte[] PortLatch = new byte[64]; - - public byte ReadBus(ushort addr) - { - if (addr < 0x400) - { - // Rom0 - return BIOS01[addr]; - } - else if (addr < 0x800) - { - // Rom1 - return BIOS02[addr - 0x400]; - } - else if (addr < 0x2000) - { - // Cart - return 0; - return Cartridge[addr - 0x800]; - } - else if (addr < 0x2000 + 2048) - { - // Framebuffer - return FrameBuffer[addr - 0x2000]; - } - else - { - return 0xFF; - } - } - - public void WriteBus(ushort addr, byte value) - { - if (addr < 0x400) - { - // Rom0 - } - else if (addr < 0x800) - { - // Rom1 - } - else if (addr < 0x2000) - { - // Cart - } - else if (addr < 0x2000 + 2048) - { - // Framebuffer - FrameBuffer[addr - 0x2000] = value; - } - else - { - - } - } - - public byte ReadPort(ushort addr) - { - return 0x00; - } - - public void WritePort(ushort addr, byte value) - { - PortLatch[addr] = value; - - VID_PortIN(addr, value); - } - } -} diff --git a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IStatable.cs b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IStatable.cs index d0c2cd3208..101f1fd378 100644 --- a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IStatable.cs +++ b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IStatable.cs @@ -41,7 +41,15 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF private void SyncState(Serializer ser) { - + ser.BeginSection("ChannelF"); + ser.Sync(nameof(VRAM), ref VRAM, false); + ser.Sync(nameof(_colour), ref _colour); + ser.Sync(nameof(_x), ref _x); + ser.Sync(nameof(_y), ref _y); + ser.Sync(nameof(_arm), ref _arm); + ser.Sync(nameof(ControllersEnabled), ref ControllersEnabled); + CPU.SyncState(ser); + ser.EndSection(); /* byte[] core = null; diff --git a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IVideoProvider.cs b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IVideoProvider.cs index 4efe72af28..d67cdd1a94 100644 --- a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IVideoProvider.cs +++ b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IVideoProvider.cs @@ -7,95 +7,61 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF { public partial class ChannelF : IVideoProvider, IRegionable { - public static readonly int[] FPalette = - { - Colors.ARGB(0x10, 0x10, 0x10), // Black - Colors.ARGB(0xFD, 0xFD, 0xFD), // White - Colors.ARGB(0xFF, 0x31, 0x53), // Red - Colors.ARGB(0x02, 0xCC, 0x5D), // Green - Colors.ARGB(0x4B, 0x3F, 0xF3), // Blue - Colors.ARGB(0xE0, 0xE0, 0xE0), // Gray - Colors.ARGB(0x91, 0xFF, 0xA6), // BGreen - Colors.ARGB(0xCE, 0xD0, 0xFF), // BBlue - }; - - public static readonly int[] CMap = - { - 0, 1, 1, 1, - 7, 4, 2, 3, - 5, 4, 2, 3, - 6, 4, 2, 3, - }; - public int _frameHz = 60; - public int[] _vidbuffer = new int[108 * 64]; + public int[] CroppedBuffer = new int[(128*64) * 2]; //new int[102 * 58]; - public int[] GetVideoBuffer() - { - int colour; - int a = 0; - int pOff; - - // rows - for (int y = 0; y < 64; y++) - { - pOff = ((FrameBuffer[(y * 128) + 125] & 0x3) & 0x02) | ((FrameBuffer[(y * 128) + 126] & 0x3) >> 1) << 2; - - for (int x = a; x < a + 128; x++) - { - colour = pOff + (FrameBuffer[x | (y << 7)] & 0x03); - var yM = y * 64; - _vidbuffer[yM + x] = FPalette[CMap[colour]]; - } - } - - return _vidbuffer; - } + #region IVideoProvider public int VirtualWidth => BufferWidth * 2; - public int VirtualHeight => BufferHeight * 2; - public int BufferWidth => 108; // 102 - public int BufferHeight => 64; // 58 - public int BackgroundColor => unchecked((int)0xFF000000); + public int VirtualHeight => (int)((double)BufferHeight * 1.5) * 2; + public int BufferWidth => 128;// 102; + public int BufferHeight => 64; // 58; + public int BackgroundColor => Colors.ARGB(0x00, 0x00, 0x00); public int VsyncNumerator => _frameHz; public int VsyncDenominator => 1; - private int row = 0; - private int col = 0; - private byte value = 0; - - public void VID_PortIN(ushort port, byte val) + public int[] GetVideoBuffer() { - switch (port) + BuildFrame(); + /* + for (int i = 0; i < frameBuffer.Length; i++) { - case 0: - - int o; - PortLatch[port] = val; - if ((val & 0x20) != 0) - { - o = (row * 128) + col; - FrameBuffer[o] = value; - } - break; - - case 1: // Set Color (bits 6 and 7) - PortLatch[port] = val; - value = (byte)(((val ^ 0xFF) >> 6) & 0x03); - break; - case 4: // X coordinate, inverted (bits 0-6) - PortLatch[2] = val; - col = (val | 0x80) ^ 0xFF; - break; - case 5: // Y coordinate, inverted (bits 0-5) - PortLatch[3] = val; - //sound TODO - row = (val | 0xC0) ^ 0xFF; - break; + CroppedBuffer[i] = frameBuffer[i]; + CroppedBuffer[i + frameBuffer.Length] = frameBuffer[i]; } + + return CroppedBuffer; + */ + return frameBuffer; + + // crop to visible area + var lR = 4; + var rR = 128 - BufferWidth - lR; + var tR = 4; + var bR = 64 - BufferHeight - tR; + var sW = 128 - lR - rR; + var startP = 128 * tR; + var endP = 128 * bR; + + int index2 = 0; + + // line by line + for (int i = startP; i < CroppedBuffer.Length - endP; i += sW + lR + rR) + { + // each pixel in each line + for (int p = lR; p < sW + lR + rR - rR; p++) + { + if (index2 == CroppedBuffer.Length) + break; + CroppedBuffer[index2++] = frameBuffer[i + p]; + } + } + + return CroppedBuffer; } + #endregion #region IRegionable diff --git a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.MemoryDomains.cs b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.MemoryDomains.cs index af0370f03b..0f62cab512 100644 --- a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.MemoryDomains.cs +++ b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.MemoryDomains.cs @@ -48,8 +48,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF { SyncByteArrayDomain("BIOS1", BIOS01); SyncByteArrayDomain("BIOS2", BIOS02); - SyncByteArrayDomain("ROM", Cartridge); - SyncByteArrayDomain("VRAM", FrameBuffer); + SyncByteArrayDomain("ROM", Rom); + SyncByteArrayDomain("VRAM", VRAM); } private void SyncByteArrayDomain(string name, byte[] data) diff --git a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.cs b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.cs index 3c088e0341..7e19c5f260 100644 --- a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.cs +++ b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.cs @@ -1,4 +1,5 @@ using System; +using BizHawk.Common; using BizHawk.Common.BufferExtensions; using BizHawk.Emulation.Common; @@ -39,7 +40,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF BIOS01 = bios01; BIOS02 = bios02; - Array.Copy(rom, 0, Cartridge, 0, rom.Length); + Array.Copy(rom, 0, Rom, 0, rom.Length); CalcClock(); @@ -52,5 +53,6 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF public F3850 CPU; private readonly TraceBuffer _tracer; + public IController _controller; } } diff --git a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.ALU.cs b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.ALU.cs index ccc6d9f234..70858f7576 100644 --- a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.ALU.cs +++ b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.ALU.cs @@ -25,7 +25,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF /// /// Clears all status flags (excluding the ICB flag) /// - public void ALU_ClearFlags() + public void ALU_ClearFlags_() { FlagC = false; FlagO = false; @@ -37,19 +37,19 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF /// Sets the SIGN and ZERO flags based on the supplied byte /// /// - public void ALU_SetFlags_SZ(ushort src) + public void ALU_SetFlags_SZ_(ushort src) { FlagZ = (byte)Regs[src] == 0; FlagS = (~((byte)Regs[src]) & 0x80) != 0; } - + /* /// /// Performs addition and sets the CARRY and OVERFLOW flags accordingly /// /// /// /// - public void ALU_ADD8_Func(ushort dest, ushort src, bool carry = false) + public void ALU_ADD8_Func_(ushort dest, ushort src, bool carry = false) { byte d = (byte)Regs[dest]; byte s = (byte)Regs[src]; @@ -61,6 +61,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF Regs[dest] = (ushort)(result & 0xFF); } + */ /// /// Performs addition and sets the CARRY and OVERFLOW flags accordingly WITHOUT saving to destination @@ -84,49 +85,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF /// /// /// - public void ALU_ADD8D_Func(ushort dest, ushort src) - { - // from MAME f8.cpp (BSD-3) - // https://github.com/mamedev/mame/blob/97b67170277437131adf6ed4d60139c172529e4f/src/devices/cpu/f8/f8.cpp#L264 - byte d = (byte)Regs[dest]; - byte s = (byte)Regs[src]; - byte tmp = (byte)(d + s); - - byte c = 0; // high order carry - byte ic = 0; // low order carry - - if (((d + s) & 0xFF0) > 0xF0) - { - c = 1; - } - - if ((d & 0x0F) + (s & 0x0F) > 0x0F) - { - ic = 1; - } - - ALU_ClearFlags(); - ALU_ADD8_FLAGSONLY_Func(dest, src); - Regs[ALU0] = tmp; - ALU_SetFlags_SZ(ALU0); - - if (c == 0 && ic == 0) - { - tmp = (byte)(((tmp + 0xa0) & 0xf0) + ((tmp + 0x0a) & 0x0f)); - } - - if (c == 0 && ic == 1) - { - tmp = (byte)(((tmp + 0xa0) & 0xf0) + (tmp & 0x0f)); - } - - if (c == 1 && ic == 0) - { - tmp = (byte)((tmp & 0xf0) + ((tmp + 0x0a) & 0x0f)); - } - - Regs[dest] = tmp; - } + public void ALU_SUB8_Func(ushort dest, ushort src) { @@ -169,55 +128,18 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF } */ - /// - /// Right shift 'src' 'shift' positions (zero fill) - /// - /// - /// - public void ALU_SR_Func(ushort src, ushort shift) - { - Regs[src] = (ushort)((Regs[src] >> shift) & 0xFF); - ALU_ClearFlags(); - ALU_SetFlags_SZ(src); - } - - /// - /// Left shit 'src' 'shift' positions (zero fill) - /// - /// - /// - public void ALU_SL_Func(ushort src, ushort shift) - { - Regs[src] = (ushort)((Regs[src] << shift) & 0xFF); - ALU_ClearFlags(); - ALU_SetFlags_SZ(src); - } + /// /// AND /// /// /// - public void ALU_AND8_Func(ushort dest, ushort src) - { - ALU_ClearFlags(); - Regs[dest] = (ushort)(Regs[dest] & Regs[src]); - ALU_SetFlags_SZ(dest); - } + - public void ALU_OR8_Func(ushort dest, ushort src) - { - ALU_ClearFlags(); - Regs[dest] = (ushort)(Regs[dest] | Regs[src]); - ALU_SetFlags_SZ(dest); - } + - public void ALU_XOR8_Func(ushort dest, ushort src) - { - ALU_ClearFlags(); - Regs[dest] = (ushort)(Regs[dest] ^ Regs[src]); - ALU_SetFlags_SZ(dest); - } + /* public void ALU_XOR8C_Func(ushort dest, ushort src) { @@ -264,16 +186,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF Regs[dest_h] &= 0xFF; } - public void Read_Func(ushort dest, ushort src_l, ushort src_h) - { - Regs[dest] = ReadMemory((ushort)(Regs[src_l] | (Regs[src_h]) << 8)); - } - - public void Write_Func(ushort dest_l, ushort dest_h, ushort src) - { - WriteMemory((ushort)(Regs[dest_l] | (Regs[dest_h] << 8)), (byte)Regs[src]); - } - + + /* public void LR8_Func(ushort dest, ushort src) { if (dest == DB) @@ -296,6 +210,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF Regs[dest] = Regs[src]; } } + */ /* public void ALU_INC8_Func(ushort src) diff --git a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Disassembler.cs b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Disassembler.cs index bba6c4a581..223eba1a51 100644 --- a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Disassembler.cs +++ b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Disassembler.cs @@ -19,7 +19,13 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF //n immediate succeeds the opcode and the displacement (if present) //nn immediately succeeds the opcode and the displacement (if present) - if (format.IndexOf("nn") != -1) format = format.Replace("nn", $"{read(addr++) << 8 + (read(addr++)):X4}h"); // MSB is read first + if (format.IndexOf("nn") != -1) + { + format = format.Replace("nn", read(addr++) + .ToString("X2") + read(addr++) + .ToString("X2") + "h"); // MSB is read first + } + if (format.IndexOf("n") != -1) format = format.Replace("n", $"{read(addr++):X2}h"); if (format.IndexOf("+d") != -1) format = format.Replace("+d", "d"); @@ -67,13 +73,13 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF "LR W, J", // 0x1D "LR J, W", // 0x1E "INC", // 0x1F - "LI n", // 0x20 - "NI n", // 0x21 - "IO n", // 0x22 - "XI n", // 0x23 - "AI n", // 0x24 - "CI n", // 0x25 - "IN n", // 0x26 + "LI n", // 0x20 + "NI n", // 0x21 + "OI n", // 0x22 + "XI n", // 0x23 + "AI n", // 0x24 + "CI n", // 0x25 + "IN n", // 0x26 "OUT n", // 0x27 "PI nn", // 0x28 "JMP nn", // 0x29 @@ -111,9 +117,9 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF "LR A, r09", // 0x49 "LR A, r10", // 0x4A "LR A, r11", // 0x4B - "LR A, ISAR", // 0x4C - "LR A, ISAR INC", // 0x4D - "LR A, ISAR DEC", // 0x4E + "LR A, (ISAR)", // 0x4C + "LR A, (ISAR) INC", // 0x4D + "LR A, (ISAR) DEC", // 0x4E "ILLEGAL", // 0x4F "LR r00, A", // 0x50 "LR r01, A", // 0x51 @@ -131,38 +137,38 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF "LR (ISAR), A INC", // 0x5D "LR (ISAR), A DEC", // 0x5E "ILLEGAL", // 0x5F - "LISU 0x00", // 0x60 - "LISU 0x08", // 0x61 - "LISU 0x10", // 0x62 - "LISU 0x18", // 0x63 - "LISU 0x20", // 0x64 - "LISU 0x28", // 0x65 - "LISU 0x30", // 0x66 - "LISU 0x38", // 0x67 - "LISU 0x00", // 0x68 - "LISU 0x01", // 0x69 - "LISU 0x02", // 0x6A - "LISU 0x03", // 0x6B - "LISU 0x04", // 0x6C - "LISU 0x05", // 0x6D - "LISU 0x06", // 0x6E - "LISU 0x07", // 0x6F - "LIS 0x0", // 0x70 - "LIS 0x01", // 0x71 - "LIS 0x2", // 0x72 - "LIS 0x3", // 0x73 - "LIS 0x4", // 0x74 - "LIS 0x5", // 0x75 - "LIS 0x6", // 0x76 - "LIS 0x7", // 0x77 - "LIS 0x8", // 0x78 - "LIS 0x9", // 0x79 - "LIS 0xA", // 0x7A - "LIS 0xB", // 0x7B - "LIS 0xC", // 0x7C - "LIS 0xD", // 0x7D - "LIS 0xE", // 0x7E - "LIS 0xF", // 0x7F + "LISU 0", // 0x60 + "LISU 1", // 0x61 + "LISU 2", // 0x62 + "LISU 3", // 0x63 + "LISU 4", // 0x64 + "LISU 5", // 0x65 + "LISU 6", // 0x66 + "LISU 7", // 0x67 + "LISL 0", // 0x68 + "LISL 1", // 0x69 + "LISL 2", // 0x6A + "LISL 3", // 0x6B + "LISL 4", // 0x6C + "LISL 5", // 0x6D + "LISL 6", // 0x6E + "LISL 7", // 0x6F + "LIS 0", // 0x70 + "LIS 1", // 0x71 + "LIS 2", // 0x72 + "LIS 3", // 0x73 + "LIS 4", // 0x74 + "LIS 5", // 0x75 + "LIS 6", // 0x76 + "LIS 7", // 0x77 + "LIS 8", // 0x78 + "LIS 9", // 0x79 + "LIS A", // 0x7A + "LIS B", // 0x7B + "LIS C", // 0x7C + "LIS D", // 0x7D + "LIS E", // 0x7E + "LIS F", // 0x7F "BT 0", // 0x80 "BT 1", // 0x81 "BT 2", // 0x82 diff --git a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Execute.cs b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Execute.cs index f1a5283654..8a2f952e67 100644 --- a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Execute.cs +++ b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Execute.cs @@ -119,22 +119,22 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF case 0x5D: LR_ISAR_A_INC(); break; // SR <- (A) (SR pointed to by the ISAR); ISAR incremented case 0x5E: LR_ISAR_A_DEC(); break; // SR <- (A) (SR pointed to by the ISAR); ISAR decremented - case 0x60: LISU(0); break; // ISARU <- 0'e' (octal) - case 0x61: LISU(8); break; // ISARU <- 0'e' (octal) - case 0x62: LISU(16); break; // ISARU <- 0'e' (octal) - case 0x63: LISU(24); break; // ISARU <- 0'e' (octal) - case 0x64: LISU(32); break; // ISARU <- 0'e' (octal) - case 0x65: LISU(40); break; // ISARU <- 0'e' (octal) - case 0x66: LISU(48); break; // ISARU <- 0'e' (octal) - case 0x67: LISU(56); break; // ISARU <- 0'e' (octal) - case 0x68: LISL(0); break; // ISARL <- 0'e' (octal) - case 0x69: LISL(1); break; // ISARL <- 0'e' (octal) - case 0x6A: LISL(2); break; // ISARL <- 0'e' (octal) - case 0x6B: LISL(3); break; // ISARL <- 0'e' (octal) - case 0x6C: LISL(4); break; // ISARL <- 0'e' (octal) - case 0x6D: LISL(5); break; // ISARL <- 0'e' (octal) - case 0x6E: LISL(6); break; // ISARL <- 0'e' (octal) - case 0x6F: LISL(7); break; // ISARL <- 0'e' (octal) + case 0x60: LISU(0); break; // ISARU <- 0'e' (octal) + case 0x61: LISU(1); break; // ISARU <- 0'e' (octal) + case 0x62: LISU(2); break; // ISARU <- 0'e' (octal) + case 0x63: LISU(3); break; // ISARU <- 0'e' (octal) + case 0x64: LISU(4); break; // ISARU <- 0'e' (octal) + case 0x65: LISU(5); break; // ISARU <- 0'e' (octal) + case 0x66: LISU(6); break; // ISARU <- 0'e' (octal) + case 0x67: LISU(7); break; // ISARU <- 0'e' (octal) + case 0x68: LISL(0); break; // ISARL <- 0'e' (octal) + case 0x69: LISL(1); break; // ISARL <- 0'e' (octal) + case 0x6A: LISL(2); break; // ISARL <- 0'e' (octal) + case 0x6B: LISL(3); break; // ISARL <- 0'e' (octal) + case 0x6C: LISL(4); break; // ISARL <- 0'e' (octal) + case 0x6D: LISL(5); break; // ISARL <- 0'e' (octal) + case 0x6E: LISL(6); break; // ISARL <- 0'e' (octal) + case 0x6F: LISL(7); break; // ISARL <- 0'e' (octal) case 0x70: LIS(0); break; // A <- H'0a' case 0x71: LIS(1); break; // A <- H'0a' @@ -152,14 +152,14 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF case 0x7d: LIS(13); break; // A <- H'0a' case 0x7e: LIS(14); break; // A <- H'0a' case 0x7f: LIS(15); break; // A <- H'0a' - case 0x80: BT(0); break; // Test operand against W (Branching instruction) - case 0x81: BT(1); break; // Test operand against W (Branching instruction) - case 0x82: BT(2); break; // Test operand against W (Branching instruction) - case 0x83: BT(3); break; // Test operand against W (Branching instruction) - case 0x84: BT(4); break; // Test operand against W (Branching instruction) - case 0x85: BT(5); break; // Test operand against W (Branching instruction) - case 0x86: BT(6); break; // Test operand against W (Branching instruction) - case 0x87: BT(7); break; // Test operand against W (Branching instruction) + case 0x80: BT(0); break; // Branch on true - test operand against W register + case 0x81: BT(1); break; // Branch if positive (sign bit is set) + case 0x82: BT(2); break; // Branch on carry (carry bit is set) + case 0x83: BT(3); break; // Branch on true - test operand against W register + case 0x84: BT(4); break; // Branch on zero (zero bit is set) + case 0x85: BT(5); break; // Branch on true - test operand against W register + case 0x86: BT(6); break; // Branch on true - test operand against W register + case 0x87: BT(7); break; // Branch on true - test operand against W register case 0x88: AM(); break; // A <- (A) + ((DC0))Binary; DC0 <- (DC0) + 1 case 0x89: AMD(); break; // A <- (A) + ((DC0))Decimal; DC0 <- (DC0) + 1 case 0x8A: NM(); break; // A <- (A) AND ((DC0)); DC0 <- (DC0) + 1 @@ -167,23 +167,23 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF case 0x8C: XM(); break; // A <- (A) XOR ((DC0)); DC0 <- (DC0) + 1 case 0x8D: CM(); break; // Set status flags on basis of: ((DC)) + (A) + 1; DC0 <- (DC0) + 1; DC <- (DC) + (A) case 0x8E: ADC(); break; // DC <- (DC) + (A) - case 0x8F: BR7(); break; // DC <- (DC) + (A) - case 0x90: BF(0); break; // PC0 <- PC0+n+1 - case 0x91: BF(1); break; // PC0 <- PC0+n+1 - case 0x92: BF(2); break; // PC0 <- PC0+n+1 - case 0x93: BF(3); break; // PC0 <- PC0+n+1 - case 0x94: BF(4); break; // PC0 <- PC0+n+1 - case 0x95: BF(5); break; // PC0 <- PC0+n+1 - case 0x96: BF(6); break; // PC0 <- PC0+n+1 - case 0x97: BF(7); break; // PC0 <- PC0+n+1 - case 0x98: BF(8); break; // PC0 <- PC0+n+1 - case 0x99: BF(9); break; // PC0 <- PC0+n+1 - case 0x9A: BF(10); break; // PC0 <- PC0+n+1 - case 0x9B: BF(11); break; // PC0 <- PC0+n+1 - case 0x9C: BF(12); break; // PC0 <- PC0+n+1 - case 0x9D: BF(13); break; // PC0 <- PC0+n+1 - case 0x9E: BF(14); break; // PC0 <- PC0+n+1 - case 0x9F: BF(15); break; // PC0 <- PC0+n+1 + case 0x8F: BR7(); break; // Branch on ISAR (any of the low 3 bits of ISAR are reset) + case 0x90: BF(0); break; // Unconditional branch (always) + case 0x91: BF(1); break; // Branch if negative (sign bit is reset) + case 0x92: BF(2); break; // Branch if no carry (carry bit is reset) + case 0x93: BF(3); break; // Branch on false - test operand against W register + case 0x94: BF(4); break; // Branch on not zero (zero bit is reset) + case 0x95: BF(5); break; // Branch on false - test operand against W register + case 0x96: BF(6); break; // Branch on false - test operand against W register + case 0x97: BF(7); break; // Branch on false - test operand against W register + case 0x98: BF(8); break; // Branch if no overflow (OVF bit is reset) + case 0x99: BF(9); break; // Branch on false - test operand against W register + case 0x9A: BF(10); break; // Branch on false - test operand against W register + case 0x9B: BF(11); break; // Branch on false - test operand against W register + case 0x9C: BF(12); break; // Branch on false - test operand against W register + case 0x9D: BF(13); break; // Branch on false - test operand against W register + case 0x9E: BF(14); break; // Branch on false - test operand against W register + case 0x9F: BF(15); break; // Branch on false - test operand against W register case 0xA0: INS_0(0); break; // A <- (I/O Port 0 or 1) case 0xA1: INS_0(1); break; // A <- (I/O Port 0 or 1) diff --git a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Operations.cs b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Operations.cs new file mode 100644 index 0000000000..7698d0060a --- /dev/null +++ b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Operations.cs @@ -0,0 +1,281 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using BizHawk.Common.NumberExtensions; + +namespace BizHawk.Emulation.Cores.Consoles.ChannelF +{ + /// + /// ALU Operations + /// + public sealed partial class F3850 + { + public void Read_Func(ushort dest, ushort src_l, ushort src_h) + { + Regs[dest] = ReadMemory((ushort)(Regs[src_l] | (Regs[src_h]) << 8)); + } + + public void Write_Func(ushort dest_l, ushort dest_h, ushort src) + { + WriteMemory((ushort)(Regs[dest_l] | (Regs[dest_h] << 8)), (byte)Regs[src]); + } + + public void IN_Func(ushort dest, ushort src) + { + Regs[dest] = ReadHardware(Regs[src]); + } + + public void LR_A_IO_Func(ushort dest, ushort src) + { + // helper method that simulates transferring DB to accumulator (as part of an IN operation) + // this sets flags accordingly + // dest should always == A and src should always == DB for this function + + // overflow and carry unconditionally reset + FlagO = false; + FlagC = false; + + Regs[dest] = Regs[src]; + + FlagZ = Regs[dest] == 0; + + // Sign SET if MSB == 0 (positive signed number) + FlagS = Regs[dest].Bit(7) == false; + + // ICB flag not affected + } + + public void ClearFlags_Func() + { + FlagC = false; + FlagO = false; + FlagS = false; + FlagZ = false; + } + + public void LR_Func(ushort dest, ushort src) + { + if (dest == DB) + { + // byte storage + Regs[dest] = (ushort)(Regs[src] & 0xFF); + } + else if (dest == W) + { + // mask for status register + Regs[dest] = (ushort)(Regs[src] & 0x1F); + } + else if (dest == ISAR) + { + // mask for ISAR register + Regs[dest] = (ushort)(Regs[src] & 0x3F); + } + else + { + Regs[dest] = Regs[src]; + } + } + + /// + /// Right shift 'src' 'shift' positions (zero fill) + /// + /// + /// + public void SR_Func(ushort src, ushort shift) + { + // overflow and carry unconditionally reset + FlagO = false; + FlagC = false; + + Regs[src] = (ushort)((Regs[src] >> shift) & 0xFF); + + FlagZ = Regs[src] == 0; + + // Sign SET if MSB == 0 (positive signed number) + FlagS = Regs[src].Bit(7) == false; + + // ICB flag not affected + } + + /// + /// Left shit 'src' 'shift' positions (zero fill) + /// + /// + /// + public void SL_Func(ushort src, ushort shift) + { + // overflow and carry unconditionally reset + FlagO = false; + FlagC = false; + + Regs[src] = (ushort)((Regs[src] << shift) & 0xFF); + + FlagZ = Regs[src] == 0; + + // Sign SET if MSB == 0 (positive signed number) + FlagS = Regs[src].Bit(7) == false; + + // ICB flag not affected + } + + public void ADD_Func(ushort dest, ushort src) + { + // addition of 2 signed bytes + ushort dest16 = Regs[dest]; + + dest16 += Regs[src]; + + FlagC = dest16.Bit(8); + FlagZ = (dest16 & 0xFF) == 0; + + ushort ans = (ushort)(dest16 & 0xFF); + + // Sign SET if MSB == 0 (positive signed number) + FlagS = ans.Bit(7) == false; + + // overflow based on carry out of bit6 XOR carry out of bit7 + var b6c = dest16 >> 7; + var b7c = dest16 >> 8; + FlagO = (b6c ^ b7c) != 0; + + Regs[dest] = ans; + } + + public void SUB_Func(ushort dest, ushort src) + { + Regs[ALU0] = (ushort)((Regs[src] ^ 0xff) + 1); + ADD_Func(dest, ALU0); + } + + public void ADDD_Func(ushort dest, ushort src) + { + var d = Regs[dest]; + var s = Regs[src]; + var bcdRes = d + s; + + var carryIntermediate = ((d & 0x0F) + (s & 0x0F)) > 0x0F; + var carryUpper = bcdRes >= 0x100; + + // temporary storage and set flags + Regs[ALU0] = Regs[dest]; + Regs[ALU1] = Regs[src]; + ADD_Func(ALU0, ALU1); + + if (!carryIntermediate) + { + bcdRes = (bcdRes & 0xF0) | ((bcdRes + 0x0A) & 0x0F); + } + + if (!carryUpper) + { + bcdRes = (bcdRes + 0xA0); + } + + Regs[dest] = (ushort)(bcdRes & 0xFF); + } + + public void CI_Func() + { + // compare immediate + // we need to achieve DB - A + 1 + // flags set - results not stored + var comp = ((Regs[A] ^ 0xFF) + 1); + Regs[ALU0] = (ushort)comp; + ADD_Func(DB, ALU0); + } + + public void ADDD_Func_(ushort dest, ushort src) + { + // from MAME f8.cpp (BSD-3) + // https://github.com/mamedev/mame/blob/97b67170277437131adf6ed4d60139c172529e4f/src/devices/cpu/f8/f8.cpp#L264 + byte d = (byte)Regs[dest]; + byte s = (byte)Regs[src]; + byte tmp = (byte)(d + s); + + byte c = 0; // high order carry + byte ic = 0; // low order carry + + if (((d + s) & 0xFF0) > 0xF0) + { + c = 1; + } + + if ((d & 0x0F) + (s & 0x0F) > 0x0F) + { + ic = 1; + } + + //ALU_ClearFlags(); + ALU_ADD8_FLAGSONLY_Func(dest, src); + Regs[ALU0] = tmp; + //ALU_SetFlags_SZ(ALU0); + + if (c == 0 && ic == 0) + { + tmp = (byte)(((tmp + 0xa0) & 0xf0) + ((tmp + 0x0a) & 0x0f)); + } + + if (c == 0 && ic == 1) + { + tmp = (byte)(((tmp + 0xa0) & 0xf0) + (tmp & 0x0f)); + } + + if (c == 1 && ic == 0) + { + tmp = (byte)((tmp & 0xf0) + ((tmp + 0x0a) & 0x0f)); + } + + Regs[dest] = tmp; + } + + public void AND_Func(ushort dest, ushort src) + { + // overflow and carry unconditionally reset + FlagO = false; + FlagC = false; + + Regs[dest] = (ushort)(Regs[dest] & Regs[src]); + + FlagZ = Regs[src] == 0; + + // Sign SET if MSB == 0 (positive signed number) + FlagS = Regs[src].Bit(7) == false; + + // ICB flag not affected + } + + public void OR_Func(ushort dest, ushort src) + { + // overflow and carry unconditionally reset + FlagO = false; + FlagC = false; + + Regs[dest] = (ushort)(Regs[dest] | Regs[src]); + + FlagZ = Regs[src] == 0; + + // Sign SET if MSB == 0 (positive signed number) + FlagS = Regs[src].Bit(7) == false; + + // ICB flag not affected + } + + public void XOR_Func(ushort dest, ushort src) + { + // overflow and carry unconditionally reset + FlagO = false; + FlagC = false; + + Regs[dest] = (ushort)(Regs[dest] ^ Regs[src]); + + FlagZ = Regs[src] == 0; + + // Sign SET if MSB == 0 (positive signed number) + FlagS = Regs[src].Bit(7) == false; + + // ICB flag not affected + } + } +} diff --git a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Registers.cs b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Registers.cs index 6e5e057dd4..b426d9d4e4 100644 --- a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Registers.cs +++ b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Registers.cs @@ -189,6 +189,10 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF Regs[ONE] = 1; Regs[BYTE] = 0xFF; + + // testing only - fill scratchpad with 0xff + for (int i = 0; i < 64; i++) + Regs[i] = 0xff; } } } diff --git a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Tables.cs b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Tables.cs index 7bd4680a4f..ef80c0e7a7 100644 --- a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Tables.cs +++ b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Tables.cs @@ -190,8 +190,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF { PopulateCURINSTR( // L - OP_LR8, DB, Ql, // DB <- (r15) - IDLE, + OP_LR8, DB, Ql, // DB <- (r15) + OP_EI, // Set ICB Flag IDLE, ROMC_17, // PC0l <- (DB) IDLE, @@ -364,7 +364,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF { PopulateCURINSTR( // S - OP_COM, // A <- A XOR 0xFF (compliment accumulator) + OP_XOR8, A, BYTE, // A <- A XOR 0xFF (compliment accumulator) + //OP_COM, // A <- A XOR 0xFF (compliment accumulator) ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, END); @@ -420,7 +421,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF IDLE, // S ROMC_00_S, // DB <- ((PC0)); PC0++ - IDLE, + OP_EI, // Set ICB Flag IDLE, END); } @@ -435,7 +436,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF IDLE, // S ROMC_00_S, // DB <- ((PC0)); PC0++ - IDLE, + OP_EI, // Set ICB Flag IDLE, END); } @@ -466,9 +467,9 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF // L ROMC_03_L, // DB <- ((PC0)); PC0++ IDLE, - OP_CLEAR_FLAGS, + IDLE, //OP_CLEAR_FLAGS, OP_LR8, A, DB, // A <- (DB) - OP_SET_FLAGS_SZ, A, + IDLE, //OP_SET_FLAGS_SZ, A, IDLE, // S ROMC_00_S, // DB <- ((PC0)); PC0++ @@ -534,9 +535,9 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF // L ROMC_03_L, // DB <- ((PC0)); PC0++ IDLE, - OP_CLEAR_FLAGS, + IDLE, OP_ADD8, A, DB, // A <- (A) + (DB) - OP_SET_FLAGS_SZ, A, + IDLE, IDLE, // S ROMC_00_S, // DB <- ((PC0)); PC0++ @@ -551,8 +552,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF // L ROMC_03_L, // DB <- ((PC0)); PC0++ IDLE, - OP_CLEAR_FLAGS, - OP_CI, A, DB, // Set flags for A <- (A) + (DB) + 1 (do not store result in A) + IDLE, + OP_CI, // Set flags for A <- (DB) + (-A) + 1 (do not store result in A) IDLE, IDLE, // S @@ -580,16 +581,16 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF ROMC_03_L, // DB/IO <- ((PC0)); PC0++ IDLE, IDLE, - OP_CLEAR_FLAGS, + IDLE, IDLE, IDLE, // L ROMC_1B, // DB <- ((IO)); IDLE, IDLE, - OP_LR8, A, DB, // A <- (DB) + OP_LR_A_DB_IO, A, DB, // A <- (DB) - flags set as result of IN or INS operation + IDLE, IDLE, - OP_SET_FLAGS_SZ, A, // S ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, @@ -616,7 +617,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF IDLE, // S ROMC_00_S, // DB <- ((PC0)); PC0++ - IDLE, + OP_EI, // Set ICB Flag IDLE, END); } @@ -652,7 +653,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF IDLE, // S ROMC_00_S, // DB <- ((PC0)); PC0++ - IDLE, + OP_EI, // Set ICB Flag IDLE, END); } @@ -683,7 +684,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF IDLE, // S ROMC_00_S, // DB <- ((PC0)); PC0++ - IDLE, + OP_EI, // Set ICB Flag IDLE, END); } @@ -749,11 +750,15 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF private void DS(ushort rIndex) { + // only scratch registers 0-16 + rIndex = (ushort)(rIndex & 0x0F); + PopulateCURINSTR( // L - OP_CLEAR_FLAGS, - OP_ADD8, rIndex, BYTE, - OP_SET_FLAGS_SZ, rIndex, + IDLE, + OP_SUB8, rIndex, ONE, + //OP_ADD8, rIndex, BYTE, + IDLE, ROMC_00_L, // DB <- ((PC0)); PC0++ IDLE, END); @@ -762,9 +767,9 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF { PopulateCURINSTR( // L - OP_CLEAR_FLAGS, - OP_ADD8, Regs[ISAR], BYTE, // r[ISAR] = r[ISAR] + 0xff - OP_SET_FLAGS_SZ, Regs[ISAR], + IDLE, + OP_SUB8, Regs[ISAR], ONE, // r[ISAR] = r[ISAR] + 0xff + IDLE, ROMC_00_L, // DB <- ((PC0)); PC0++ IDLE, END); @@ -774,9 +779,9 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF { PopulateCURINSTR( // L - OP_CLEAR_FLAGS, - OP_ADD8, Regs[ISAR], BYTE, // r[ISAR] = r[ISAR] + 0xff - OP_SET_FLAGS_SZ, Regs[ISAR], + IDLE, + OP_SUB8, Regs[ISAR], ONE, // r[ISAR] = r[ISAR] + 0xff + IDLE, OP_IS_INC, // Inc ISAR ROMC_00_L, // DB <- ((PC0)); PC0++ END); @@ -786,9 +791,9 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF { PopulateCURINSTR( // L - OP_CLEAR_FLAGS, - OP_ADD8, Regs[ISAR], BYTE, // r[ISAR] = r[ISAR] + 0xff - OP_SET_FLAGS_SZ, Regs[ISAR], + IDLE, + OP_SUB8, Regs[ISAR], ONE, // r[ISAR] = r[ISAR] + 0xff + IDLE, OP_IS_DEC, // Dec ISAR ROMC_00_L, // DB <- ((PC0)); PC0++ END); @@ -796,6 +801,9 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF private void LR_A_R(ushort rIndex) { + // only scratch registers 0-16 + rIndex = (ushort)(rIndex & 0x0F); + PopulateCURINSTR( // S OP_LR8, A, rIndex, // A <- (rIndex) @@ -836,6 +844,9 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF private void LR_R_A(ushort rIndex) { + // only scratch registers 0-16 + rIndex = (ushort)(rIndex & 0x0F); + PopulateCURINSTR( // S OP_LR8, rIndex, A, // rIndex <- (A) @@ -898,7 +909,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF { PopulateCURINSTR( // S - OP_LR8, A, index, // A <- index + OP_LIS, index, // A <- index ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, END); @@ -918,11 +929,11 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF { PopulateCURINSTR( // L - ROMC_02, // DB <- ((DC0)); DC0++ - OP_CLEAR_FLAGS, + ROMC_02, // DB <- ((DC0)); DC0++ + IDLE, + IDLE, + OP_ADD8, A, DB, // A <- (DB) IDLE, - OP_ADD8, A, DB, // A <- (DB) - OP_SET_FLAGS_SZ, A, IDLE, // S ROMC_00_S, // DB <- ((PC0)); PC0++ @@ -954,9 +965,9 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF // L ROMC_02, // DB <- ((DC0)); DC0++ IDLE, - OP_CLEAR_FLAGS, - OP_AND8, A, DB, // A <- (A) AND (DB) - OP_SET_FLAGS_SZ, A, + IDLE, + OP_AND8, A, DB, // A <- (A) AND (DB) + IDLE, IDLE, // S ROMC_00_S, // DB <- ((PC0)); PC0++ @@ -971,9 +982,9 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF // L ROMC_02, // DB <- ((DC0)); DC0++ IDLE, - OP_CLEAR_FLAGS, - OP_OR8, A, DB, // A <- (A) OR (DB) - OP_SET_FLAGS_SZ, A, + IDLE, + OP_OR8, A, DB, // A <- (A) OR (DB) + IDLE, IDLE, // S ROMC_00_S, // DB <- ((PC0)); PC0++ @@ -988,9 +999,9 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF // L ROMC_02, // DB <- ((DC0)); DC0++ IDLE, - OP_CLEAR_FLAGS, + IDLE, OP_XOR8, A, DB, // A <- (A) XOR (DB) - OP_SET_FLAGS_SZ, A, + IDLE, IDLE, // S ROMC_00_S, // DB <- ((PC0)); PC0++ @@ -1005,7 +1016,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF // L ROMC_02, // DB <- ((DC0)); DC0++ IDLE, - OP_CLEAR_FLAGS, + IDLE, OP_CI, A, IDLE, IDLE, @@ -1054,9 +1065,9 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF PopulateCURINSTR( // S ROMC_1C_S, // Idle - OP_CLEAR_FLAGS, - OP_IN, A, index, // A <- ((Port index - 0/1)) - OP_SET_FLAGS_SZ, A, + IDLE, + OP_IN, A, index, // A <- ((Port index - 0/1)) + OP_LR_A_DB_IO, A, A, // A <- (A) - flags set as result of IN or INS operation // S ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, @@ -1079,9 +1090,9 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF // L ROMC_1B, // DB <- ((IO)) IDLE, - OP_CLEAR_FLAGS, - OP_LR8, A, DB, // A <- (DB) - OP_SET_FLAGS_SZ, A, + IDLE, + OP_LR_A_DB_IO, A, DB, // A <- (DB) - flags set as result of IN or INS operation + IDLE, IDLE, // S ROMC_00_S, // DB <- ((PC0)); PC0++ @@ -1126,19 +1137,20 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF IDLE, // S ROMC_00_S, // DB <- ((PC0)); PC0++ - IDLE, + OP_EI, // Set ICB Flag IDLE, END); } private void AS(ushort rIndex) { - ALU_ClearFlags(); // clear flags early (as not enough cycle space for commands) + // only scratch registers 0-15 + rIndex = (ushort) (rIndex & 0x0F); PopulateCURINSTR( // S - OP_ADD8, A, rIndex, // A <- (A) + (rIndex) - OP_SET_FLAGS_SZ, A, + OP_ADD8, A, rIndex, // A <- (A) + (rIndex) + IDLE, ROMC_00_S, // DB <- ((PC0)); PC0++ END); } @@ -1147,8 +1159,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF { PopulateCURINSTR( // S - OP_CLEAR_FLAGS, - OP_AS_IS, // A <- (A) + ((ISAR)); setSZ + IDLE, + OP_ADD8, A, Regs[ISAR], // A <- (A) + ((ISAR)); IDLE, ROMC_00_S, // DB <- ((PC0)); PC0++ END); @@ -1158,8 +1170,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF { PopulateCURINSTR( // S - OP_CLEAR_FLAGS, - OP_AS_IS, // A <- (A) + ((ISAR)); setSZ + IDLE, + OP_ADD8, A, Regs[ISAR], // A <- (A) + ((ISAR)); OP_IS_INC, // Inc ISAR ROMC_00_S, // DB <- ((PC0)); PC0++ END); @@ -1169,8 +1181,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF { PopulateCURINSTR( // S - OP_CLEAR_FLAGS, - OP_AS_IS, // A <- (A) + ((ISAR)); setSZ + IDLE, + OP_ADD8, A, Regs[ISAR], // A <- (A) + ((ISAR)); OP_IS_DEC, // Dec ISAR ROMC_00_S, // DB <- ((PC0)); PC0++ END); @@ -1178,6 +1190,9 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF private void ASD(ushort rIndex) { + // only scratch registers 0-15 + rIndex = (ushort)(rIndex & 0x0F); + PopulateCURINSTR( // S ROMC_1C_S, // Idle @@ -1238,11 +1253,14 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF private void XS(ushort rIndex) { + // only scratch registers 0-15 + rIndex = (ushort)(rIndex & 0x0F); + PopulateCURINSTR( // S - OP_CLEAR_FLAGS, - OP_XOR8, A, rIndex, // A <- (A) XOR (reg) - OP_SET_FLAGS_SZ, A, + IDLE, + OP_XOR8, A, rIndex, // A <- (A) XOR (reg) + IDLE, ROMC_00_S, // DB <- ((PC0)); PC0++ END); } @@ -1251,7 +1269,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF { PopulateCURINSTR( // S - OP_XS_IS, // A <- (A) XOR ((ISAR)) + OP_XOR8, A, Regs[ISAR], // A <- (A) XOR ((ISAR)) ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, END); @@ -1261,7 +1279,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF { PopulateCURINSTR( // S - OP_XS_IS, // A <- (A) XOR ((ISAR)) + OP_XOR8, A, Regs[ISAR], // A <- (A) XOR ((ISAR)) OP_IS_INC, // Inc ISAR ROMC_00_S, // DB <- ((PC0)); PC0++ END); @@ -1271,7 +1289,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF { PopulateCURINSTR( // S - OP_XS_IS, // A <- (A) XOR ((ISAR)) + OP_XOR8, A, Regs[ISAR], // A <- (A) XOR ((ISAR)) OP_IS_DEC, // Dec ISAR ROMC_00_S, // DB <- ((PC0)); PC0++ END); @@ -1279,12 +1297,13 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF private void NS(ushort rIndex) { - ALU_ClearFlags(); // clear flags early (as not enough cycle space for commands) + // only scratch registers 0-15 + rIndex = (ushort)(rIndex & 0x0F); PopulateCURINSTR( // S OP_AND8, A, rIndex, // A <- (A) AND (reg) - OP_SET_FLAGS_SZ, A, + IDLE, ROMC_00_S, // DB <- ((PC0)); PC0++ END); } @@ -1293,7 +1312,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF { PopulateCURINSTR( // S - OP_NS_IS, // A <- (A) AND ((ISAR)) + OP_AND8, A, Regs[ISAR], // A <- (A) AND ((ISAR)) ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, END); @@ -1303,7 +1322,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF { PopulateCURINSTR( // S - OP_NS_IS, // A <- (A) AND ((ISAR)) + OP_AND8, A, Regs[ISAR], // A <- (A) AND ((ISAR)) OP_IS_INC, // Inc ISAR ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, @@ -1314,11 +1333,44 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF { PopulateCURINSTR( // S - OP_NS_IS, // A <- (A) AND ((ISAR)) + OP_AND8, A, Regs[ISAR], // A <- (A) AND ((ISAR)) OP_IS_DEC, // Dec ISAR ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, END); } + + + private void DO_BRANCH() + { + PopulateCURINSTR( + // L + IDLE, + ROMC_01, // forward or backward displacement + IDLE, + IDLE, + IDLE, + IDLE, + // S + ROMC_00_S, // DB <- ((PC0)); PC0++ + IDLE, + IDLE, + END); + } + + private void DONT_BRANCH() + { + PopulateCURINSTR( + // S + IDLE, + ROMC_03_S, // immediate operand fetch + IDLE, + IDLE, + // S + ROMC_00_S, // DB <- ((PC0)); PC0++ + IDLE, + IDLE, + END); + } } } diff --git a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.cs b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.cs index 42d0ac06c2..3e0b240769 100644 --- a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.cs +++ b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; +using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using BizHawk.Common; @@ -88,7 +89,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF public const ushort OP_AND8 = 107; public const ushort OP_OR8 = 108; public const ushort OP_XOR8 = 109; - public const ushort OP_COM = 110; + //public const ushort OP_COM = 110; + public const ushort OP_SUB8 = 110; public const ushort OP_ADD8 = 111; public const ushort OP_CI = 112; public const ushort OP_IS_INC = 113; @@ -101,11 +103,14 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF public const ushort OP_BF = 120; public const ushort OP_IN = 121; public const ushort OP_OUT = 122; - public const ushort OP_AS_IS = 123; - public const ushort OP_XS_IS = 124; - public const ushort OP_NS_IS = 125; - public const ushort OP_CLEAR_FLAGS = 126; - public const ushort OP_SET_FLAGS_SZ = 127; + //public const ushort OP_AS_IS = 123; + //public const ushort OP_XS_IS = 124; + //public const ushort OP_NS_IS = 125; + public const ushort OP_LR_A_DB_IO = 126; + public const ushort OP_DS = 127; + //public const ushort OP_CLEAR_FLAGS = 126; + //public const ushort OP_SET_FLAGS_SZ = 127; + public const ushort OP_LIS = 128; public F3850() @@ -135,7 +140,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF IDLE, END); - ALU_ClearFlags(); + ClearFlags_Func(); FlagICB = false; } @@ -191,52 +196,51 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF case IDLE: break; - // clears all flags except for ICB - case OP_CLEAR_FLAGS: - ALU_ClearFlags(); - break; - - // sets SIGN and CARRY flags based upon the supplied value - case OP_SET_FLAGS_SZ: - ALU_SetFlags_SZ(cur_instr[instr_pntr++]); - break; - // load one register into another (or databus) case OP_LR8: - LR8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + LR_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + break; + + // load DB into A (as a part of an IN or INS instruction) + case OP_LR_A_DB_IO: + LR_A_IO_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + break; + + // loads supplied index value into register + case OP_LIS: + Regs[ALU1] = (ushort)(cur_instr[instr_pntr++] & 0x0F); + LR_Func(A, ALU1); break; // Shift register n bit positions to the right (zero fill) case OP_SHFT_R: - ALU_SR_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + SR_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); break; // Shift register n bit positions to the left (zero fill) case OP_SHFT_L: - ALU_SL_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + SL_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); break; // x <- (x) ADD y case OP_ADD8: - ALU_ADD8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + ADD_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + break; + + // x <- (x) MINUS y + case OP_SUB8: + SUB_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); break; // x <- (x) ADD y (decimal) case OP_ADD8D: - ALU_ADD8D_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + ADDD_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); break; // A <- (A) + (C) case OP_LNK: - bool fc = FlagC; - ALU_ClearFlags(); - - if (fc) - { - ALU_ADD8_Func(A, ONE); - } - - ALU_SetFlags_SZ(A); + Regs[ALU0] = (ushort)(FlagC ? 1 : 0); + ADD_Func(A, ALU0); break; // Clear ICB status bit @@ -251,38 +255,27 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF // x <- (y) XOR DB case OP_XOR8: - ALU_XOR8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); - break; - - // x <- (y) XOR DB (complement accumulator) - case OP_COM: - Regs[A] = (byte)~Regs[A]; - ALU_ClearFlags(); - ALU_SetFlags_SZ(A); + XOR_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); break; // x <- (x) + 1 case OP_INC8: - ALU_ClearFlags(); - ALU_ADD8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); - ALU_SetFlags_SZ(A); + ADD_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); break; // x <- (y) & DB case OP_AND8: - ALU_AND8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + AND_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); break; // x <- (y) | DB case OP_OR8: - ALU_OR8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + OR_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); break; // DB + (x) + 1 (modify flags without saving result) case OP_CI: - Regs[ALU0] = (byte)~Regs[cur_instr[instr_pntr++]]; - ALU_ADD8_Func(ALU0, DB, true); - ALU_SetFlags_SZ(ALU0); + CI_Func(); break; // ISAR is incremented @@ -297,124 +290,178 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF // set the upper octal ISAR bits (b3,b4,b5) case OP_LISU: - Regs[ISAR] = (ushort) (((Regs[ISAR] & 0x07) | cur_instr[instr_pntr++]) & 0x3F); + Regs[ISAR] = (ushort)((((Regs[ISAR] & 0x07) | (cur_instr[instr_pntr++] & 0x07) << 3)) & 0x3F); break; // set the lower octal ISAR bits (b0,b1,b2) case OP_LISL: - Regs[ISAR] = (ushort) (((Regs[ISAR] & 0x38) | cur_instr[instr_pntr++]) & 0x3F); + Regs[ISAR] = (ushort) (((Regs[ISAR] & 0x38) | (cur_instr[instr_pntr++] & 0x07)) & 0x3F); break; - // test operand against status register + // decrement scratchpad byte + //case OP_DS: + //SUB_Func(cur_instr[instr_pntr++], ONE); + //break; + + // Branch on TRUE case OP_BT: - if ((Regs[W] & cur_instr[instr_pntr++]) != 0) + bool branchBT = false; + switch (cur_instr[instr_pntr++]) { - instr_pntr = 0; - PopulateCURINSTR( - // L - ROMC_01, - IDLE, - IDLE, - IDLE, - IDLE, - IDLE, - // S - ROMC_00_S, // DB <- ((PC0)); PC0++ - IDLE, - IDLE, - END); - } - else - { - instr_pntr = 0; - PopulateCURINSTR( - // S - ROMC_03_S, - IDLE, - IDLE, - IDLE, - // S - ROMC_00_S, // DB < -((PC0)); PC0++ - IDLE, - IDLE, - END); + case 0: + // do not branch + break; + + case 1: + // branch if positive (sign bit is set) + if (FlagS) branchBT = true; + break; + + case 2: + // branch on carry (carry bit is set) + if (FlagC) branchBT = true; + break; + + case 3: + // branch if positive or on carry + if (FlagS || FlagC) branchBT = true; + break; + + case 4: + // branch if zero (zero bit is set) + if (FlagZ) branchBT = true; + break; + + case 5: + // branch if positive (same as t==1) + if (FlagS) branchBT = true; + break; + + case 6: + // branch if zero or on carry + if (FlagZ || FlagC) branchBT = true; + break; + case 7: + // branch if positive or on carry (same as t==3) + if (FlagS || FlagC) branchBT = true; + break; } + + instr_pntr = 0; + if (branchBT) DO_BRANCH(); + else DONT_BRANCH(); break; - // Branch based on ISARL + // Branch on ISARL case OP_BR7: - if ((Regs[ISAR] & 7) == 7) + instr_pntr = 1; // lose a cycle + if (!Regs[ISAR].Bit(0) || !Regs[ISAR].Bit(1) || !Regs[ISAR].Bit(2)) { - instr_pntr = 0; - PopulateCURINSTR( - // S - ROMC_03_S, // DB/IO <- ((PC0)); PC0++ - //IDLE, <- lose a cycle that was stolen in the table - IDLE, - IDLE, - // S - ROMC_00_S, // DB <- ((PC0)); PC0++ - IDLE, - IDLE, - END); + DO_BRANCH(); } else { - instr_pntr = 0; - PopulateCURINSTR( - // L - ROMC_01, - //IDLE, <- lose a cycle that was stolen in the table - IDLE, - IDLE, - IDLE, - IDLE, - ROMC_00_S, // DB <- ((PC0)); PC0++ - IDLE, - IDLE, - END); + DONT_BRANCH(); } break; - // PC0 <- PC0+n+1 + // Branch on FALSE case OP_BF: - if ((Regs[W] & cur_instr[instr_pntr++]) != 0) + bool branchBF = false; + switch (cur_instr[instr_pntr++]) { - instr_pntr = 0; - PopulateCURINSTR( - // S - ROMC_03_S, // DB/IO <- ((PC0)); PC0++ - IDLE, - IDLE, - IDLE, - // S - ROMC_00_S, // DB <- ((PC0)); PC0++ - IDLE, - IDLE, - END); - } - else - { - instr_pntr = 0; - PopulateCURINSTR( - // L - ROMC_01, - IDLE, - IDLE, - IDLE, - IDLE, - IDLE, - // S - ROMC_00_S, // DB <- ((PC0)); PC0++ - IDLE, - IDLE, - END); + case 0: + // unconditional branch relative + branchBF = true; + break; + + case 1: + // branch on negative (sign bit is reset) + if (!FlagS) branchBF = true; + break; + + case 2: + // branch if no carry (carry bit is reset) + if (!FlagC) branchBF = true; + break; + + case 3: + // branch if no carry and negative + if (!FlagC && !FlagS) branchBF = true; + break; + + case 4: + // branch if not zero (zero bit is reset) + if (!FlagZ) branchBF = true; + break; + + case 5: + // same as t==1 + if (!FlagS) branchBF = true; + break; + + case 6: + // branch if no carry and result is no zero + if (!FlagC && !FlagZ) branchBF = true; + break; + + case 7: + // same as t==3 + if (!FlagS && !FlagC) branchBF = true; + break; + + case 8: + // branch if there is no overflow (OVF bit is reset) + if (!FlagO) branchBF = true; + break; + + case 9: + // branch if negative and no overflow + if (!FlagS && !FlagO) branchBF = true; + break; + + case 0xA: + // branch if no overflow and no carry + if (!FlagO && !FlagC) branchBF = true; + break; + + case 0xB: + // branch if no overflow, no carry & negative + if (!FlagO && !FlagC && !FlagS) branchBF = true; + break; + + case 0xC: + // branch if no overflow and not zero + if (!FlagO && !FlagZ) branchBF = true; + break; + + case 0xD: + // same as t==9 + if (!FlagS && !FlagO) branchBF = true; + break; + + case 0xE: + // branch if no overflow, no carry & not zero + if (!FlagO && !FlagC && !FlagZ) branchBF = true; + break; + + case 0xF: + // same as t=0xB + if (!FlagO && !FlagC && !FlagS) branchBF = true; + break; } + + instr_pntr = 0; + if (branchBF) DO_BRANCH(); + else DONT_BRANCH(); break; // A <- (I/O Port 0 or 1) case OP_IN: - Regs[cur_instr[instr_pntr++]] = ReadHardware(cur_instr[instr_pntr++]); + instr_pntr++; // dest == A + Regs[ALU0] = cur_instr[instr_pntr++]; // src + IN_Func(A, ALU0); + //Regs[cur_instr[instr_pntr++]] = ReadHardware(cur_instr[instr_pntr++]); break; // I/O Port 0 or 1 <- (A) @@ -423,28 +470,6 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF //OUT_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); break; - // Add the content of the SR register addressed by ISAR to A (Binary) - case OP_AS_IS: - ALU_ClearFlags(); - ALU_ADD8_Func(A, Regs[ISAR]); - ALU_SetFlags_SZ(A); - break; - - // XOR the content of the SR register addressed by ISAR to A - case OP_XS_IS: - ALU_ClearFlags(); - ALU_XOR8_Func(A, Regs[ISAR]); - ALU_SetFlags_SZ(A); - break; - - // AND the content of the SR register addressed by ISAR to A - case OP_NS_IS: - ALU_ClearFlags(); - ALU_AND8_Func(A, Regs[ISAR]); - ALU_SetFlags_SZ(A); - break; - - // instruction fetch // The device whose address space includes the contents of the PC0 register must place on the data bus the op code addressed by PC0; // then all devices increments the content of PC0. @@ -650,7 +675,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF // registers cannot be read back onto the data bus) // CYCLE LENGTH: L case ROMC_1B: - Regs[DB] = ReadHardware(Regs[IO]); + IN_Func(DB, IO); + //Regs[DB] = ReadHardware(Regs[IO]); break; // None @@ -687,7 +713,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF public Action TraceCallback; - public string TraceHeader => "F3850: PC, machine code, mnemonic, operands, registers (R0, R1, R2, R3, R4, R5, R6, R7, R8, J, HU, HL, KU, KL, QU, QL, Cy), flags (IOZCS)"; + public string TraceHeader => "F3850: PC, machine code, mnemonic, operands, flags (IOZCS), registers (PC1, DC0, A, ISAR, DB, IO, J, H, K, Q, R00-R63), Cycles"; public TraceInfo State(bool disassemble = true) { @@ -713,29 +739,40 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF byte_code.PadRight(12), disasm.PadRight(26)), RegisterInfo = string.Format( - "R0:{0:X2} R1:{1:X2} R2:{2:X2} R3:{3:X2} R4:{4:X2} R5:{5:X2} R6:{6:X2} R7:{7:X2} R8:{8:X2} J:{9:X2} HU:{10:X2} HL:{11:X2} KU:{12:X2} KL:{13:X2} QU:{14:X2} QL:{15:X2} Cy:{16} {17}{18}{19}{20}{21}", - Regs[0], - Regs[1], - Regs[2], - Regs[3], - Regs[4], - Regs[5], - Regs[6], - Regs[7], - Regs[8], + "Flags:{75}{76}{77}{78}{79} " + + "PC1:{0:X4} DC0:{1:X4} A:{2:X2} ISAR:{3:X2} DB:{4:X2} IO:{5:X2} J:{6:X2} H:{7:X4} K:{8:X4} Q:{9:X4} " + + "R0:{10:X2} R1:{11:X2} R2:{12:X2} R3:{13:X2} R4:{14:X2} R5:{15:X2} R6:{16:X2} R7:{17:X2} R8:{18:X2} R9:{19:X2} " + + "R10:{20:X2} R11:{21:X2} R12:{22:X2} R13:{23:X2} R14:{24:X2} R15:{25:X2} R16:{26:X2} R17:{27:X2} R18:{28:X2} R19:{29:X2} " + + "R20:{30:X2} R21:{31:X2} R22:{32:X2} R23:{33:X2} R24:{34:X2} R25:{35:X2} R26:{36:X2} R27:{37:X2} R28:{38:X2} R29:{39:X2} " + + "R30:{40:X2} R31:{41:X2} R32:{42:X2} R33:{43:X2} R34:{44:X2} R35:{45:X2} R36:{46:X2} R37:{47:X2} R38:{48:X2} R39:{49:X2} " + + "R40:{50:X2} R41:{51:X2} R42:{52:X2} R43:{53:X2} R44:{54:X2} R45:{55:X2} R46:{56:X2} R47:{57:X2} R48:{58:X2} R49:{59:X2} " + + "R50:{60:X2} R51:{61:X2} R52:{62:X2} R53:{63:X2} R54:{64:X2} R55:{65:X2} R56:{66:X2} R57:{67:X2} R58:{68:X2} R59:{69:X2} " + + "R60:{70:X2} R61:{71:X2} R62:{72:X2} R63:{73:X2} " + + "Cy:{74}", + RegPC1, + RegDC0, + Regs[A], + Regs[ISAR], + Regs[DB], + Regs[IO], Regs[J], - Regs[Hh], - Regs[Hl], - Regs[Kh], - Regs[Kl], - Regs[Qh], - Regs[Ql], + (ushort)(Regs[Hl] | (Regs[Hh] << 8)), + (ushort)(Regs[Kl] | (Regs[Kh] << 8)), + (ushort)(Regs[Ql] | (Regs[Qh] << 8)), + Regs[0], Regs[1], Regs[2], Regs[3], Regs[4], Regs[5], Regs[6], Regs[7], Regs[8], Regs[9], + Regs[10], Regs[11], Regs[12], Regs[13], Regs[14], Regs[15], Regs[16], Regs[17], Regs[18], Regs[19], + Regs[20], Regs[21], Regs[22], Regs[23], Regs[24], Regs[25], Regs[26], Regs[27], Regs[28], Regs[29], + Regs[30], Regs[31], Regs[32], Regs[33], Regs[34], Regs[35], Regs[36], Regs[37], Regs[38], Regs[39], + Regs[40], Regs[41], Regs[42], Regs[43], Regs[44], Regs[45], Regs[46], Regs[47], Regs[48], Regs[49], + Regs[50], Regs[51], Regs[52], Regs[53], Regs[54], Regs[55], Regs[56], Regs[57], Regs[58], Regs[59], + Regs[60], Regs[61], Regs[62], Regs[63], TotalExecutedCycles, FlagICB ? "I" : "i", FlagO ? "O" : "o", FlagZ ? "Z" : "z", FlagC ? "C" : "c", - FlagS ? "S" : "s") + FlagS ? "S" : "s"), + }; } diff --git a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Memory.cs b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Memory.cs new file mode 100644 index 0000000000..6cf6ced0ca --- /dev/null +++ b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Memory.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BizHawk.Emulation.Cores.Consoles.ChannelF +{ + /// + /// Memory and related functions + /// + public partial class ChannelF + { + public byte[] BIOS01 = new byte[1024]; + public byte[] BIOS02 = new byte[1024]; + + /// + /// Simulates reading a byte of data from the address space + /// + /// + /// + public byte ReadBus(ushort addr) + { + if (addr < 0x400) + { + // Rom0 + return BIOS01[addr]; + } + else if (addr < 0x800) + { + // Rom1 + return BIOS02[addr - 0x400]; + } + else if (addr < 0x2000) + { + // Cart + return 0; + return Rom[addr - 0x800]; + } + + return 0xFF; + } + + /// + /// Simulates writing a byte of data to the address space (in its default configuration, there is no writeable RAM in the + /// Channel F addressable through the address space) + /// + /// + /// + public void WriteBus(ushort addr, byte value) + { + + } + } +} diff --git a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Ports.cs b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Ports.cs new file mode 100644 index 0000000000..079f952168 --- /dev/null +++ b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Ports.cs @@ -0,0 +1,188 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Remoting.Messaging; +using System.Text; +using System.Threading.Tasks; +using BizHawk.Common.NumberExtensions; + +namespace BizHawk.Emulation.Cores.Consoles.ChannelF +{ + /// + /// Ports and related functions + /// + public partial class ChannelF + { + /// + /// The Channel F has 4 8-bit IO ports connected. + /// CPU - ports 0 and 1 + /// PSU - ports 4 and 5 + /// (the second PSU has no IO ports wired up) + /// + public byte[] PortLatch = new byte[4]; + + public bool ControllersEnabled; + + public const int PORT0 = 0; + public const int PORT1 = 1; + public const int PORT4 = 2; + public const int PORT5 = 3; + + /// + /// CPU attempts to read data byte from the requested port + /// + /// + /// + public byte ReadPort(ushort addr) + { + byte port = (byte) (addr & 0x07); + + switch (port) + { + // Console buttons + // b0: TIME + // b1: MODE + // b2: HOLD + // b3: START + case 0: + return (byte)((DataConsole ^ 0xFF) & 0x0F); + + // Right controller + // b0: RIGHT + // b1: LEFT + // b2: BACK + // b3: FORWARD + // b4: CCW + // b5: CW + // b6: PULL + // b7: PUSH + case 1: + if (ControllersEnabled) + { + return (byte)((DataRight ^ 0xFF) & 0xFF); + } + return 0; + + // Left controller + // b0: RIGHT + // b1: LEFT + // b2: BACK + // b3: FORWARD + // b4: CCW + // b5: CW + // b6: PULL + // b7: PUSH + case 4: + if (ControllersEnabled) + { + return (byte)((DataLeft ^ 0xFF) & 0xFF); + } + return 0; + } + + return 0xFF; + } + + /// + /// CPU attempts to write data to the requested port (latch) + /// + /// + /// + public void WritePort(ushort addr, byte value) + { + byte port = (byte)(addr & 0x07); + + switch (port) + { + case 0: + + ControllersEnabled = (value & 0x40) == 0; + + var val = value & 0x60; + if (val == 0x40)// && _arm == 0x60) + { + VRAM[(128 * _y) + _x] = (byte)_colour; + } + + /* + + // RAM WRT - A pulse here executes a write to video RAM + bool ramWrt = value.Bit(5); + + // Enable data from controllers (1 equals enable) + // also needs pulse to write to video RAM + bool controllerDataEnable = value.Bit(6); + + if (ramWrt || controllerDataEnable) + { + // triggered write to VRAM + var yxIndex = (_y * 128) + _x; + var byteIndex = yxIndex / 4; + var byteRem = yxIndex % 4; + + switch (byteRem) + { + case 0: + VRAM[byteIndex] |= (byte) _colour; + break; + case 1: + VRAM[byteIndex] |= (byte) (_colour << 2); + break; + case 2: + VRAM[byteIndex] |= (byte)(_colour << 4); + break; + case 3: + VRAM[byteIndex] |= (byte)(_colour << 6); + break; + } + + } + */ + + _arm = value; + + PortLatch[PORT0] = value; + + break; + + case 1: + + // Write Data0 - indicates that valid data is present for both VRAM ODD0 and EVEN0 + bool data0 = value.Bit(6); + // Write Data1 - indicates that valid data is present for both VRAM ODD1 and EVEN1 + bool data1 = value.Bit(7); + + _colour = ((value ^ 0xff) >> 6) & 0x03; + + PortLatch[PORT1] = value; + + break; + + case 4: + + // video horizontal position + // 0 - video select + // 1-6 - horiz A-F + + _x = (value ^ 0xff) & 0x7f; + + PortLatch[PORT4] = value; + + break; + + + case 5: + + // video vertical position and sound + // 0-5 - Vertical A-F + // 6 - Tone AN, 7 - Tone BN + + _y = (value ^ 0xff) & 0x3f; + + PortLatch[PORT5] = value; + + break; + } + } + } +} diff --git a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Video.cs b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Video.cs new file mode 100644 index 0000000000..864e228c2a --- /dev/null +++ b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Video.cs @@ -0,0 +1,120 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using BizHawk.Common; + +namespace BizHawk.Emulation.Cores.Consoles.ChannelF +{ + /// + /// Video related functions + /// + public partial class ChannelF + { + /// + /// 128x64 pixels - 8192x2bits (2 KB) + /// For the purposes of this core we will use 8192 bytes and just & 0x03 + /// + public byte[] VRAM = new byte[(128 * 64)]; + + public static readonly int[] FPalette = + { + Colors.ARGB(0x10, 0x10, 0x10), // Black + Colors.ARGB(0xFD, 0xFD, 0xFD), // White + Colors.ARGB(0xFF, 0x31, 0x53), // Red + Colors.ARGB(0x02, 0xCC, 0x5D), // Green + Colors.ARGB(0x4B, 0x3F, 0xF3), // Blue + Colors.ARGB(0xE0, 0xE0, 0xE0), // Gray + Colors.ARGB(0x91, 0xFF, 0xA6), // BGreen + Colors.ARGB(0xCE, 0xD0, 0xFF), // BBlue + }; + + public static readonly int[] CMap = + { + 0, 1, 1, 1, + 7, 4, 2, 3, + 5, 4, 2, 3, + 6, 4, 2, 3, + }; + + private int _colour = 2; + private int _x; + private int _y; + private int _arm; + + private int[] frameBuffer = new int[128 * 64]; + + private void BuildFrame() + { + // rows + int counter = 0; + for (int row = 0; row < 64; row++) + { + // columns 125 and 126 hold the palette index modifier for the entire row + var rIndex = 64 * row; + var c125 = (VRAM[rIndex + 125] & 0x02) >> 1; + var c126 = (VRAM[rIndex + 126] & 0x03); + var pModifier = ((c125 | c126) << 2) & 0x0C; + + // columns + for (int col = 0; col < 128; col++, counter++) + { + int colour = (VRAM[rIndex + col]) & 0x03; + var finalColorIndex = pModifier | colour; + var paletteLookup = CMap[finalColorIndex & 0x0f] & 0x07; + frameBuffer[counter] = FPalette[paletteLookup]; + } + } + } + + private void BuildFrame1() + { + int cnt = 0; + // rows + for (int row = 0; row < 64; row++) + { + var yIndex = row * 128; + var yByte = yIndex / 4; + + // last byte for this row contains palette modifier + var pModifier = (byte)(VRAM[yByte + 31] & 0x0C); + + // columns + for (int col = 0; col < 128; col++) + { + var fbIndex = (row * 64) + col; + + var xByte = col / 4; + var xRem = col % 4; + var xyByte = yByte + xByte; + + // each byte contains 4 pixel colour values, b0b1, b2b3, b4b5, b6b7 + int colour = 0; + + switch (xRem) + { + case 0: + colour = VRAM[xyByte] & 0x03; + break; + case 1: + colour = VRAM[xyByte] & 0x0C; + break; + case 2: + colour = VRAM[xyByte] & 0x30; + break; + case 3: + colour = VRAM[xyByte] & 0xC0; + break; + } + + var finalColorIndex = pModifier | colour; + var paletteLookup = CMap[finalColorIndex & 0x0f] & 0x07; + frameBuffer[fbIndex] = FPalette[paletteLookup]; + + cnt++; + } + } + } + } +} From 038bab2bff4e000fbe9b43fb6e24cf0ae69b4c16 Mon Sep 17 00:00:00 2001 From: Asnivor Date: Wed, 8 May 2019 09:48:01 +0100 Subject: [PATCH 2/2] ChannelF: more bugfixes and disam update --- .../BizHawk.Emulation.Cores.csproj | 2 +- .../Consoles/Fairchild/ChannelF/Audio.cs | 108 ++++++++ .../ChannelF/ChannelF.IDebuggable.cs | 26 +- .../Fairchild/ChannelF/ChannelF.IEmulator.cs | 4 +- .../ChannelF/ChannelF.IVideoProvider.cs | 55 ++-- .../Consoles/Fairchild/ChannelF/ChannelF.cs | 1 + .../Fairchild/ChannelF/F8/F3850.ALU.cs | 235 ------------------ .../ChannelF/F8/F3850.Disassembler.cs | 48 ++-- .../Fairchild/ChannelF/F8/F3850.Execute.cs | 4 +- .../Fairchild/ChannelF/F8/F3850.Operations.cs | 74 +++--- .../Fairchild/ChannelF/F8/F3850.Registers.cs | 70 +++--- .../Fairchild/ChannelF/F8/F3850.Tables.cs | 50 ++-- .../Consoles/Fairchild/ChannelF/F8/F3850.cs | 192 +++++++------- .../Consoles/Fairchild/ChannelF/Memory.cs | 2 +- .../Consoles/Fairchild/ChannelF/Ports.cs | 123 ++++----- .../Consoles/Fairchild/ChannelF/Video.cs | 72 ++---- 16 files changed, 447 insertions(+), 619 deletions(-) create mode 100644 BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Audio.cs delete mode 100644 BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.ALU.cs diff --git a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj index 5ed3b20e4f..ef1d8c3a49 100644 --- a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj +++ b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj @@ -605,13 +605,13 @@ - + diff --git a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Audio.cs b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Audio.cs new file mode 100644 index 0000000000..6390adea4a --- /dev/null +++ b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Audio.cs @@ -0,0 +1,108 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using BizHawk.Common; +using BizHawk.Emulation.Common; + +namespace BizHawk.Emulation.Cores.Consoles.ChannelF +{ + /// + /// Audio related functions + /// + public partial class ChannelF : ISoundProvider + { + private double SampleRate = 44100; + private int SamplesPerFrame; + private double Period; + private double CyclesPerSample; + + + private int tone = 0; + + private double[] tone_freqs = new double[] { 0, 1000, 500, 120 }; + private double amplitude = 0; + private double decay = 0.998; + private double time = 0; + private double cycles = 0; + private int samplePos = 0; + private int lastCycle = 0; + + private BlipBuffer _blip; + + private short[] SampleBuffer; + + private void SetupAudio() + { + Period = (double)1 / SampleRate; + SamplesPerFrame = (int)(SampleRate / refreshRate); + CyclesPerSample = (double)ClockPerFrame / (double)SamplesPerFrame; + SampleBuffer = new short[SamplesPerFrame]; + _blip = new BlipBuffer(SamplesPerFrame); + _blip.SetRates(ClockPerFrame * refreshRate, SampleRate); + } + + private void AudioChange() + { + if (tone == 0) + { + // silence + } + else + { + int SamplesPerWave = (int)(SampleRate / tone_freqs[tone]); + double RadPerSample = (Math.PI * 2) / (double) SamplesPerWave; + double SinVal = 0; + + int NumSamples = (int)(((double)FrameClock - (double)lastCycle) / CyclesPerSample); + + int startPos = lastCycle; + + for (int i = 0; i < NumSamples; i++) + { + SinVal = Math.Sin(RadPerSample * (double) (i * SamplesPerWave)); + _blip.AddDelta((uint)startPos, (int) (Math.Floor(SinVal * 127) + 128) * 1024); + startPos += (int)CyclesPerSample; + } + } + } + + public bool CanProvideAsync => false; + + public SyncSoundMode SyncMode => SyncSoundMode.Sync; + + public void SetSyncMode(SyncSoundMode mode) + { + if (mode != SyncSoundMode.Sync) + throw new InvalidOperationException("Only Sync mode is supported."); + } + + public void GetSamplesAsync(short[] samples) + { + throw new NotSupportedException("Async is not available"); + } + + public void DiscardSamples() + { + SampleBuffer = new short[SamplesPerFrame]; + samplePos = 0; + lastCycle = 0; + } + + public void GetSamplesSync(out short[] samples, out int nsamp) + { + AudioChange(); + + _blip.EndFrame((uint)ClockPerFrame); + nsamp = _blip.SamplesAvailable(); + samples = new short[nsamp * 2]; + _blip.ReadSamples(samples, nsamp, true); + + for (int i = 0; i < nsamp * 2; i += 2) + { + samples[i + 1] = samples[i]; + } + } + } +} diff --git a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IDebuggable.cs b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IDebuggable.cs index 16a48c9684..ee961bcf67 100644 --- a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IDebuggable.cs +++ b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IDebuggable.cs @@ -47,7 +47,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF if (reg > 63) throw new InvalidOperationException(); - CPU.Regs[reg] = (ushort) value; + CPU.Regs[reg] = (byte) value; } else { @@ -56,13 +56,13 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF default: throw new InvalidOperationException(); case "A": - CPU.Regs[CPU.A] = (ushort)value; + CPU.Regs[CPU.A] = (byte)value; break; case "W": - CPU.Regs[CPU.W] = (ushort)value; + CPU.Regs[CPU.W] = (byte)value; break; case "ISAR": - CPU.Regs[CPU.ISAR] = (ushort)(value & 0x3F); + CPU.Regs[CPU.ISAR] = (byte)(value & 0x3F); break; case "PC0": CPU.RegPC0 = (ushort)value; @@ -74,25 +74,25 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF CPU.RegDC0 = (ushort)value; break; case "DB": - CPU.Regs[CPU.DB] = (ushort)value; + CPU.Regs[CPU.DB] = (byte)value; break; case "IO": - CPU.Regs[CPU.IO] = (ushort)value; + CPU.Regs[CPU.IO] = (byte)value; break; case "J": - CPU.Regs[CPU.J] = (ushort)value; + CPU.Regs[CPU.J] = (byte)value; break; case "H": - CPU.Regs[CPU.Hl] = (ushort)(value & 0xFF); - CPU.Regs[CPU.Hh] = (ushort)(value & 0xFF00); + CPU.Regs[CPU.Hl] = (byte)(value & 0xFF); + CPU.Regs[CPU.Hh] = (byte)(value & 0xFF00); break; case "K": - CPU.Regs[CPU.Kl] = (ushort)(value & 0xFF); - CPU.Regs[CPU.Kh] = (ushort)(value & 0xFF00); + CPU.Regs[CPU.Kl] = (byte)(value & 0xFF); + CPU.Regs[CPU.Kh] = (byte)(value & 0xFF00); break; case "Q": - CPU.Regs[CPU.Ql] = (ushort)(value & 0xFF); - CPU.Regs[CPU.Qh] = (ushort)(value & 0xFF00); + CPU.Regs[CPU.Ql] = (byte)(value & 0xFF); + CPU.Regs[CPU.Qh] = (byte)(value & 0xFF00); break; } } diff --git a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IEmulator.cs b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IEmulator.cs index 4ce4fcaaa9..fa44fd2e45 100644 --- a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IEmulator.cs +++ b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IEmulator.cs @@ -22,8 +22,10 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF private void CalcClock() { - var c = ((cpuFreq * 1000000) / refreshRate) * 4; + var c = ((cpuFreq * 1000000) / refreshRate); ClockPerFrame = (int) c; + + SetupAudio(); } public bool FrameAdvance(IController controller, bool render, bool renderSound) diff --git a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IVideoProvider.cs b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IVideoProvider.cs index d67cdd1a94..5393e91dcf 100644 --- a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IVideoProvider.cs +++ b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IVideoProvider.cs @@ -9,14 +9,14 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF { public int _frameHz = 60; - public int[] CroppedBuffer = new int[(128*64) * 2]; //new int[102 * 58]; + public int[] CroppedBuffer = new int[102 * 58]; #region IVideoProvider public int VirtualWidth => BufferWidth * 2; - public int VirtualHeight => (int)((double)BufferHeight * 1.5) * 2; - public int BufferWidth => 128;// 102; - public int BufferHeight => 64; // 58; + public int VirtualHeight => (int)((double)BufferHeight * 1.3) * 2; + public int BufferWidth => 102; //128 + public int BufferHeight => 58; //64 public int BackgroundColor => Colors.ARGB(0x00, 0x00, 0x00); public int VsyncNumerator => _frameHz; public int VsyncDenominator => 1; @@ -24,41 +24,32 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF public int[] GetVideoBuffer() { BuildFrame(); - /* - for (int i = 0; i < frameBuffer.Length; i++) + + 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 index = 0; + + for (int i = startP; i < frameBuffer.Length - endP; i += 128) { - CroppedBuffer[i] = frameBuffer[i]; - CroppedBuffer[i + frameBuffer.Length] = frameBuffer[i]; - } - - return CroppedBuffer; - */ - return frameBuffer; - - // crop to visible area - var lR = 4; - var rR = 128 - BufferWidth - lR; - var tR = 4; - var bR = 64 - BufferHeight - tR; - var sW = 128 - lR - rR; - var startP = 128 * tR; - var endP = 128 * bR; - - int index2 = 0; - - // line by line - for (int i = startP; i < CroppedBuffer.Length - endP; i += sW + lR + rR) - { - // each pixel in each line - for (int p = lR; p < sW + lR + rR - rR; p++) + for (int p = lBorderWidth; p < 128 - rBorderWidth; p++) { - if (index2 == CroppedBuffer.Length) + if (index == CroppedBuffer.Length) break; - CroppedBuffer[index2++] = frameBuffer[i + p]; + + CroppedBuffer[index++] = FPalette[frameBuffer[i + p]]; } } return CroppedBuffer; + + //return frameBuffer; + + } #endregion diff --git a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.cs b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.cs index 7e19c5f260..78a54ecc79 100644 --- a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.cs +++ b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.cs @@ -47,6 +47,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF ser.Register(this); ser.Register(_tracer); ser.Register(CPU); + ser.Register(this); SetupMemoryDomains(); } diff --git a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.ALU.cs b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.ALU.cs deleted file mode 100644 index 70858f7576..0000000000 --- a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.ALU.cs +++ /dev/null @@ -1,235 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using BizHawk.Common.NumberExtensions; - -namespace BizHawk.Emulation.Cores.Consoles.ChannelF -{ - /// - /// ALU Operations - /// The arithmetic and logic unit provides all data manipulating logic for the F3850. - /// It contains logic that operates on a single 8-bit source data work or combines two 8-bit words of source data - /// to generate a single 8-bit result. Additional information is reported in status flags, where appropriate. - /// - /// Operations Performed: - /// * Addition - /// * Compare - /// * AND - /// * OR - /// * XOR - /// - public sealed partial class F3850 - { - /// - /// Clears all status flags (excluding the ICB flag) - /// - public void ALU_ClearFlags_() - { - FlagC = false; - FlagO = false; - FlagS = false; - FlagZ = false; - } - - /// - /// Sets the SIGN and ZERO flags based on the supplied byte - /// - /// - public void ALU_SetFlags_SZ_(ushort src) - { - FlagZ = (byte)Regs[src] == 0; - FlagS = (~((byte)Regs[src]) & 0x80) != 0; - } - /* - /// - /// Performs addition and sets the CARRY and OVERFLOW flags accordingly - /// - /// - /// - /// - public void ALU_ADD8_Func_(ushort dest, ushort src, bool carry = false) - { - byte d = (byte)Regs[dest]; - byte s = (byte)Regs[src]; - byte c = carry ? (byte)1 : (byte)0; - ushort result = (ushort)(d + s + c); - - FlagC = (result & 0x100) != 0; - FlagO = ((d ^ result) & (s ^ result) & 0x80) != 0; - - Regs[dest] = (ushort)(result & 0xFF); - } - */ - - /// - /// Performs addition and sets the CARRY and OVERFLOW flags accordingly WITHOUT saving to destination - /// - /// - /// - /// - public void ALU_ADD8_FLAGSONLY_Func(ushort dest, ushort src) - { - byte d = (byte)Regs[dest]; - byte s = (byte)Regs[src]; - ushort result = (ushort)(d + s); - - FlagC = (result & 0x100) != 0; - FlagO = ((d ^ result) & (s ^ result) & 0x80) != 0; - } - - /// - /// Performs decimal addition based on the two supplied bytes - /// (looks like this is only used in the AMD operation) - /// - /// - /// - - - public void ALU_SUB8_Func(ushort dest, ushort src) - { - byte d = (byte)Regs[dest]; - byte s = (byte)Regs[src]; - ushort result = (ushort)(d - s); - - FlagC = (result & 0x100) != 0; - FlagO = ((d ^ result) & (s ^ result) & 0x80) != 0; - - int Reg16_d = Regs[dest]; - Reg16_d -= Regs[src]; - - FlagC = Reg16_d.Bit(8); - FlagZ = (Reg16_d & 0xFF) == 0; - - ushort ans = (ushort)(Reg16_d & 0xFF); - - FlagO = (Regs[dest].Bit(7) != Regs[src].Bit(7)) && (Regs[dest].Bit(7) != ans.Bit(7)); - FlagS = ans > 127; - - Regs[dest] = ans; - } - - /* - public void ALU_SUB8_Func(ushort dest, ushort src) - { - int Reg16_d = Regs[dest]; - Reg16_d -= Regs[src]; - - FlagC = Reg16_d.Bit(8); - FlagZ = (Reg16_d & 0xFF) == 0; - - ushort ans = (ushort)(Reg16_d & 0xFF); - - FlagO = (Regs[dest].Bit(7) != Regs[src].Bit(7)) && (Regs[dest].Bit(7) != ans.Bit(7)); - FlagS = ans > 127; - - Regs[dest] = ans; - } - */ - - - - /// - /// AND - /// - /// - /// - - - - - - /* - public void ALU_XOR8C_Func(ushort dest, ushort src) - { - // TODO - Regs[dest] = (ushort)(Regs[dest] ^ Regs[src]); - FlagZ = Regs[dest] == 0; - FlagC = false; - FlagO = false; - FlagS = Regs[dest] > 127; - } - */ - - public void ADDS_FuncX(ushort dest_l, ushort dest_h, ushort src_l, ushort src_h) - { - int Reg16_d = Regs[dest_l]; - int Reg16_s = Regs[src_l]; - - Reg16_d += Reg16_s; - - ushort temp = 0; - - // since this is signed addition, calculate the high byte carry appropriately - // note that flags are unaffected by this operation - if (Reg16_s.Bit(7)) - { - if (((Reg16_d & 0xFF) >= Regs[dest_l])) - { - temp = 0xFF; - } - else - { - temp = 0; - } - } - else - { - temp = (ushort)(Reg16_d.Bit(8) ? 1 : 0); - } - - ushort ans_l = (ushort)(Reg16_d & 0xFF); - - Regs[dest_l] = ans_l; - Regs[dest_h] += temp; - Regs[dest_h] &= 0xFF; - } - - - /* - public void LR8_Func(ushort dest, ushort src) - { - if (dest == DB) - { - // byte storage - Regs[dest] = (ushort)(Regs[src] & 0xFF); - } - else if (dest == W) - { - // mask for status register - Regs[dest] = (ushort)(Regs[src] & 0x1F); - } - else if (dest == ISAR) - { - // mask for ISAR register - Regs[dest] = (ushort)(Regs[src] & 0x3F); - } - else - { - Regs[dest] = Regs[src]; - } - } - */ - - /* - public void ALU_INC8_Func(ushort src) - { - int Reg16_d = Regs[src]; - Reg16_d += 1; - - FlagC = Reg16_d.Bit(8); - FlagZ = (Reg16_d & 0xFF) == 0; - - ushort ans = (ushort)(Reg16_d & 0xFF); - - Regs[src] = ans; - - FlagS = Regs[src].Bit(7); - FlagO = Regs[src] == 0x80; - } - */ - - - } -} diff --git a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Disassembler.cs b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Disassembler.cs index 223eba1a51..f3e4510f89 100644 --- a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Disassembler.cs +++ b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Disassembler.cs @@ -169,14 +169,14 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF "LIS D", // 0x7D "LIS E", // 0x7E "LIS F", // 0x7F - "BT 0", // 0x80 - "BT 1", // 0x81 - "BT 2", // 0x82 - "BT 3", // 0x83 - "BT 4", // 0x84 - "BT 5", // 0x85 - "BT 6", // 0x86 - "BT 7", // 0x87 + "BT NOBRANCH", // 0x80 + "BP d", // 0x81 + "BC d", // 0x82 + "BP or C d", // 0x83 + "BZ d", // 0x84 + "BP d", // 0x85 + "BZ or C d", // 0x86 + "BP or C d", // 0x87 "AM", // 0x88 "AMD", // 0x89 "NM", // 0x8A @@ -185,22 +185,22 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF "CM", // 0x8D "ADC", // 0x8E "BR7 n", // 0x8F - "BF 0x0 n", // 0x90 - "BF 0x1 n", // 0x91 - "BF 0x2 n", // 0x92 - "BF 0x3 n", // 0x93 - "BF 0x4 n", // 0x94 - "BF 0x5 n", // 0x95 - "BF 0x6 n", // 0x96 - "BF 0x7 n", // 0x97 - "BF 0x8 n", // 0x98 - "BF 0x9 n", // 0x99 - "BF 0xA n", // 0x9A - "BF 0xB n", // 0x9B - "BF 0xC n", // 0x9C - "BF 0xD n", // 0x9D - "BF 0xE n", // 0x9E - "BF 0xF n", // 0x9F + "BF UNCON d", // 0x90 + "BN d", // 0x91 + "BNC d", // 0x92 + "BNC & deg d", // 0x93 + "BNZ d", // 0x94 + "BN d", // 0x95 + "BNC & dZ d", // 0x96 + "BNC & deg d", // 0x97 + "BNO d", // 0x98 + "BN & dO d", // 0x99 + "BNO & dC d", // 0x9A + "BNO & dC & deg d", // 0x9B + "BNO & dZ d", // 0x9C + "BN & dO d", // 0x9D + "BNO & dC & dZ d", // 0x9E + "BNO & dC & deg d", // 0x9F "INS 0", // 0xA0 "INS 1", // 0xA1 "ILLEGAL", // 0xA2 diff --git a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Execute.cs b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Execute.cs index 8a2f952e67..7c5ae0e707 100644 --- a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Execute.cs +++ b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Execute.cs @@ -15,8 +15,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF public long TotalExecutedCycles; public int instr_pntr = 0; - public ushort[] cur_instr = new ushort[MaxInstructionLength]; // fixed size - do not change at runtime - public ushort[] cur_romc = new ushort[MaxInstructionLength]; // fixed size - do not change at runtime + public byte[] cur_instr = new byte[MaxInstructionLength]; // fixed size - do not change at runtime + public byte[] cur_romc = new byte[MaxInstructionLength]; // fixed size - do not change at runtime public byte opcode; public void FetchInstruction() diff --git a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Operations.cs b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Operations.cs index 7698d0060a..648f3120d3 100644 --- a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Operations.cs +++ b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Operations.cs @@ -12,22 +12,22 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF /// public sealed partial class F3850 { - public void Read_Func(ushort dest, ushort src_l, ushort src_h) + public void Read_Func(byte dest, byte src_l, byte src_h) { Regs[dest] = ReadMemory((ushort)(Regs[src_l] | (Regs[src_h]) << 8)); } - public void Write_Func(ushort dest_l, ushort dest_h, ushort src) + public void Write_Func(byte dest_l, byte dest_h, byte src) { - WriteMemory((ushort)(Regs[dest_l] | (Regs[dest_h] << 8)), (byte)Regs[src]); + WriteMemory((ushort)(Regs[dest_l] | (Regs[dest_h] << 8)), Regs[src]); } - public void IN_Func(ushort dest, ushort src) + public void IN_Func(byte dest, byte src) { Regs[dest] = ReadHardware(Regs[src]); } - public void LR_A_IO_Func(ushort dest, ushort src) + public void LR_A_IO_Func(byte dest, byte src) { // helper method that simulates transferring DB to accumulator (as part of an IN operation) // this sets flags accordingly @@ -55,22 +55,22 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF FlagZ = false; } - public void LR_Func(ushort dest, ushort src) + public void LR_Func(byte dest, byte src) { if (dest == DB) { // byte storage - Regs[dest] = (ushort)(Regs[src] & 0xFF); + Regs[dest] = (byte)(Regs[src] & 0xFF); } else if (dest == W) { // mask for status register - Regs[dest] = (ushort)(Regs[src] & 0x1F); + Regs[dest] = (byte)(Regs[src] & 0x1F); } else if (dest == ISAR) { // mask for ISAR register - Regs[dest] = (ushort)(Regs[src] & 0x3F); + Regs[dest] = (byte)(Regs[src] & 0x3F); } else { @@ -83,13 +83,13 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF /// /// /// - public void SR_Func(ushort src, ushort shift) + public void SR_Func(byte src, byte shift) { // overflow and carry unconditionally reset FlagO = false; FlagC = false; - Regs[src] = (ushort)((Regs[src] >> shift) & 0xFF); + Regs[src] = (byte)((Regs[src] >> shift) & 0xFF); FlagZ = Regs[src] == 0; @@ -104,13 +104,13 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF /// /// /// - public void SL_Func(ushort src, ushort shift) + public void SL_Func(byte src, byte shift) { // overflow and carry unconditionally reset FlagO = false; FlagC = false; - Regs[src] = (ushort)((Regs[src] << shift) & 0xFF); + Regs[src] = (byte)((Regs[src] << shift) & 0xFF); FlagZ = Regs[src] == 0; @@ -120,7 +120,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF // ICB flag not affected } - public void ADD_Func(ushort dest, ushort src) + public void ADD_Func_(byte dest, byte src) { // addition of 2 signed bytes ushort dest16 = Regs[dest]; @@ -140,16 +140,32 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF var b7c = dest16 >> 8; FlagO = (b6c ^ b7c) != 0; - Regs[dest] = ans; + Regs[dest] = (byte)ans; } - public void SUB_Func(ushort dest, ushort src) + public void ADD_Func(byte dest, byte src) { - Regs[ALU0] = (ushort)((Regs[src] ^ 0xff) + 1); + // addition of 2 signed bytes + var sD = Regs[dest] & 0x80; + var sS = Regs[src] & 0x80; + var res = Regs[dest] + Regs[src]; + var sR = res & 0x80; + + FlagS = !((res & 0x80) > 0); + FlagZ = (res & 0xff) == 0; + FlagO = (sD == sS && sD != sR); + FlagC = (res & 0x100) > 0; + + Regs[dest] = (byte) (res & 0xff); + } + + public void SUB_Func(byte dest, byte src) + { + Regs[ALU0] = (byte)((Regs[src] ^ 0xff) + 1); ADD_Func(dest, ALU0); } - public void ADDD_Func(ushort dest, ushort src) + public void ADDD_Func(byte dest, byte src) { var d = Regs[dest]; var s = Regs[src]; @@ -173,7 +189,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF bcdRes = (bcdRes + 0xA0); } - Regs[dest] = (ushort)(bcdRes & 0xFF); + Regs[dest] = (byte)(bcdRes & 0xFF); } public void CI_Func() @@ -182,10 +198,11 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF // we need to achieve DB - A + 1 // flags set - results not stored var comp = ((Regs[A] ^ 0xFF) + 1); - Regs[ALU0] = (ushort)comp; - ADD_Func(DB, ALU0); + Regs[ALU0] = (byte)comp; + Regs[ALU1] = Regs[DB]; + ADD_Func(ALU1, ALU0); } - + /* public void ADDD_Func_(ushort dest, ushort src) { // from MAME f8.cpp (BSD-3) @@ -229,14 +246,15 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF Regs[dest] = tmp; } + */ - public void AND_Func(ushort dest, ushort src) + public void AND_Func(byte dest, byte src) { // overflow and carry unconditionally reset FlagO = false; FlagC = false; - Regs[dest] = (ushort)(Regs[dest] & Regs[src]); + Regs[dest] = (byte)(Regs[dest] & Regs[src]); FlagZ = Regs[src] == 0; @@ -246,13 +264,13 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF // ICB flag not affected } - public void OR_Func(ushort dest, ushort src) + public void OR_Func(byte dest, byte src) { // overflow and carry unconditionally reset FlagO = false; FlagC = false; - Regs[dest] = (ushort)(Regs[dest] | Regs[src]); + Regs[dest] = (byte)(Regs[dest] | Regs[src]); FlagZ = Regs[src] == 0; @@ -262,13 +280,13 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF // ICB flag not affected } - public void XOR_Func(ushort dest, ushort src) + public void XOR_Func(byte dest, byte src) { // overflow and carry unconditionally reset FlagO = false; FlagC = false; - Regs[dest] = (ushort)(Regs[dest] ^ Regs[src]); + Regs[dest] = (byte)(Regs[dest] ^ Regs[src]); FlagZ = Regs[src] == 0; diff --git a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Registers.cs b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Registers.cs index b426d9d4e4..c084cc402f 100644 --- a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Registers.cs +++ b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Registers.cs @@ -17,83 +17,83 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF /// /// Registers (counters and scratchpad) /// - public ushort[] Regs = new ushort[100]; + public byte[] Regs = new byte[100]; // scratchpad registers live in Regs 0-64 - public ushort J = 9; - public ushort Hh = 10; - public ushort Hl = 11; - public ushort Kh = 12; - public ushort Kl = 13; - public ushort Qh = 14; - public ushort Ql = 15; + public byte J = 9; + public byte Hh = 10; + public byte Hl = 11; + public byte Kh = 12; + public byte Kl = 13; + public byte Qh = 14; + public byte Ql = 15; // Internal CPU counters kept after the scratchpad for ease of implementation /// /// Accumulator /// - public ushort A = 65; + public byte A = 65; /// /// Status Register /// - public ushort W = 66; + public byte W = 66; /// /// Indirect Scratchpad Address Register /// (6bit) /// - public ushort ISAR = 67; + public byte ISAR = 67; /// /// Primary Program Counter (high byte) /// - public ushort PC0h = 68; + public byte PC0h = 68; /// /// Primary Program Counter (low byte) /// - public ushort PC0l = 69; + public byte PC0l = 69; /// /// Backup Program Counter (high byte) /// - public ushort PC1h = 70; + public byte PC1h = 70; /// /// Backup Program Counter (low byte) /// - public ushort PC1l = 71; + public byte PC1l = 71; /// /// Data counter (high byte) /// - public ushort DC0h = 72; + public byte DC0h = 72; /// /// Data Counter (low byte) /// - public ushort DC0l = 73; + public byte DC0l = 73; /// /// Temporary Arithmetic Storage /// - public ushort ALU0 = 74; + public byte ALU0 = 74; /// /// Temporary Arithmetic Storage /// - public ushort ALU1 = 75; + public byte ALU1 = 75; /// /// Data Bus /// - public ushort DB = 76; + public byte DB = 76; /// /// IO Bus/Latch /// - public ushort IO = 77; + public byte IO = 77; /// /// 0x00 value for arithmetic ops /// - public ushort ZERO = 78; + public byte ZERO = 78; /// /// 0x01 value for arithmetic ops /// - public ushort ONE = 79; + public byte ONE = 79; /// /// 0xFF value for arithmetic ops /// - public ushort BYTE = 80; + public byte BYTE = 80; /// @@ -102,7 +102,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF public bool FlagS { get { return (Regs[W] & 0x01) != 0; } - set { Regs[W] = (ushort)((Regs[W] & ~0x01) | (value ? 0x01 : 0x00)); } + set { Regs[W] = (byte)((Regs[W] & ~0x01) | (value ? 0x01 : 0x00)); } } /// @@ -111,7 +111,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF public bool FlagC { get { return (Regs[W] & 0x02) != 0; } - set { Regs[W] = (ushort)((Regs[W] & ~0x02) | (value ? 0x02 : 0x00)); } + set { Regs[W] = (byte)((Regs[W] & ~0x02) | (value ? 0x02 : 0x00)); } } /// @@ -120,7 +120,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF public bool FlagZ { get { return (Regs[W] & 0x04) != 0; } - set { Regs[W] = (ushort)((Regs[W] & ~0x04) | (value ? 0x04 : 0x00)); } + set { Regs[W] = (byte)((Regs[W] & ~0x04) | (value ? 0x04 : 0x00)); } } /// @@ -129,7 +129,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF public bool FlagO { get { return (Regs[W] & 0x08) != 0; } - set { Regs[W] = (ushort)((Regs[W] & ~0x08) | (value ? 0x08 : 0x00)); } + set { Regs[W] = (byte)((Regs[W] & ~0x08) | (value ? 0x08 : 0x00)); } } /// @@ -138,7 +138,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF public bool FlagICB { get { return (Regs[W] & 0x10) != 0; } - set { Regs[W] = (ushort)((Regs[W] & ~0x10) | (value ? 0x10 : 0x00)); } + set { Regs[W] = (byte)((Regs[W] & ~0x10) | (value ? 0x10 : 0x00)); } } /// @@ -149,8 +149,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF get { return (ushort)(Regs[PC0l] | (Regs[PC0h] << 8)); } set { - Regs[PC0l] = (ushort)(value & 0xFF); - Regs[PC0h] = (ushort)((value >> 8) & 0xFF); + Regs[PC0l] = (byte)(value & 0xFF); + Regs[PC0h] = (byte)((value >> 8) & 0xFF); } } @@ -162,8 +162,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF get { return (ushort)(Regs[PC1l] | (Regs[PC1h] << 8)); } set { - Regs[PC1l] = (ushort)(value & 0xFF); - Regs[PC1h] = (ushort)((value >> 8) & 0xFF); + Regs[PC1l] = (byte)(value & 0xFF); + Regs[PC1h] = (byte)((value >> 8) & 0xFF); } } @@ -175,8 +175,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF get { return (ushort)(Regs[DC0l] | (Regs[DC0h] << 8)); } set { - Regs[DC0l] = (ushort)(value & 0xFF); - Regs[DC0h] = (ushort)((value >> 8) & 0xFF); + Regs[DC0l] = (byte)(value & 0xFF); + Regs[DC0h] = (byte)((value >> 8) & 0xFF); } } diff --git a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Tables.cs b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Tables.cs index ef80c0e7a7..8273969482 100644 --- a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Tables.cs +++ b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Tables.cs @@ -306,7 +306,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF END); } - private void SHIFT_R(ushort index) + private void SHIFT_R(byte index) { PopulateCURINSTR( // S @@ -316,7 +316,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF END); } - private void SHIFT_L(ushort index) + private void SHIFT_L(byte index) { PopulateCURINSTR( // S @@ -748,10 +748,10 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF END); } - private void DS(ushort rIndex) + private void DS(byte rIndex) { // only scratch registers 0-16 - rIndex = (ushort)(rIndex & 0x0F); + rIndex = (byte)(rIndex & 0x0F); PopulateCURINSTR( // L @@ -799,10 +799,10 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF END); } - private void LR_A_R(ushort rIndex) + private void LR_A_R(byte rIndex) { // only scratch registers 0-16 - rIndex = (ushort)(rIndex & 0x0F); + rIndex = (byte)(rIndex & 0x0F); PopulateCURINSTR( // S @@ -842,10 +842,10 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF END); } - private void LR_R_A(ushort rIndex) + private void LR_R_A(byte rIndex) { // only scratch registers 0-16 - rIndex = (ushort)(rIndex & 0x0F); + rIndex = (byte)(rIndex & 0x0F); PopulateCURINSTR( // S @@ -885,7 +885,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF END); } - private void LISU(ushort octal) + private void LISU(byte octal) { PopulateCURINSTR( // S @@ -895,7 +895,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF END); } - private void LISL(ushort octal) + private void LISL(byte octal) { PopulateCURINSTR( // S @@ -905,7 +905,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF END); } - private void LIS(ushort index) + private void LIS(byte index) { PopulateCURINSTR( // S @@ -915,7 +915,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF END); } - private void BT(ushort index) + private void BT(byte index) { PopulateCURINSTR( // S @@ -1050,7 +1050,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF OP_BR7); // no END as there is branching logic within OP_BR7 } - private void BF(ushort index) + private void BF(byte index) { PopulateCURINSTR( // S @@ -1060,7 +1060,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF OP_BF, index); // no END as there is branching logic within OP_BF } - private void INS_0(ushort index) + private void INS_0(byte index) { PopulateCURINSTR( // S @@ -1075,7 +1075,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF END); } - private void INS_1(ushort index) + private void INS_1(byte index) { Regs[IO] = index; // latch port index early @@ -1101,7 +1101,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF END); } - private void OUTS_0(ushort index) + private void OUTS_0(byte index) { PopulateCURINSTR( // S @@ -1116,7 +1116,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF END); } - private void OUTS_1(ushort index) + private void OUTS_1(byte index) { Regs[IO] = index; // latch port index early @@ -1142,10 +1142,10 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF END); } - private void AS(ushort rIndex) + private void AS(byte rIndex) { // only scratch registers 0-15 - rIndex = (ushort) (rIndex & 0x0F); + rIndex = (byte) (rIndex & 0x0F); PopulateCURINSTR( // S @@ -1188,10 +1188,10 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF END); } - private void ASD(ushort rIndex) + private void ASD(byte rIndex) { // only scratch registers 0-15 - rIndex = (ushort)(rIndex & 0x0F); + rIndex = (byte)(rIndex & 0x0F); PopulateCURINSTR( // S @@ -1251,10 +1251,10 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF END); } - private void XS(ushort rIndex) + private void XS(byte rIndex) { // only scratch registers 0-15 - rIndex = (ushort)(rIndex & 0x0F); + rIndex = (byte)(rIndex & 0x0F); PopulateCURINSTR( // S @@ -1295,10 +1295,10 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF END); } - private void NS(ushort rIndex) + private void NS(byte rIndex) { // only scratch registers 0-15 - rIndex = (ushort)(rIndex & 0x0F); + rIndex = (byte)(rIndex & 0x0F); PopulateCURINSTR( // S diff --git a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.cs b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.cs index 3e0b240769..1532d09ba0 100644 --- a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.cs +++ b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.cs @@ -40,77 +40,77 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF public sealed partial class F3850 { // operations that can take place in an instruction - public const ushort ROMC_01 = 1; - public const ushort ROMC_02 = 2; - public const ushort ROMC_03_S = 3; - public const ushort ROMC_04 = 4; - public const ushort ROMC_05 = 5; - public const ushort ROMC_06 = 6; - public const ushort ROMC_07 = 7; - public const ushort ROMC_08 = 8; - public const ushort ROMC_09 = 9; - public const ushort ROMC_0A = 10; - public const ushort ROMC_0B = 11; - public const ushort ROMC_0C = 12; - public const ushort ROMC_0D = 13; - public const ushort ROMC_0E = 14; - public const ushort ROMC_0F = 15; - public const ushort ROMC_10 = 16; - public const ushort ROMC_11 = 17; - public const ushort ROMC_12 = 18; - public const ushort ROMC_13 = 19; - public const ushort ROMC_14 = 20; - public const ushort ROMC_15 = 21; - public const ushort ROMC_16 = 22; - public const ushort ROMC_17 = 23; - public const ushort ROMC_18 = 24; - public const ushort ROMC_19 = 25; - public const ushort ROMC_1A = 26; - public const ushort ROMC_1B = 27; - public const ushort ROMC_1C_S = 28; - public const ushort ROMC_1D = 29; - public const ushort ROMC_1E = 30; - public const ushort ROMC_1F = 31; - public const ushort ROMC_00_S = 32; - public const ushort ROMC_00_L = 33; - public const ushort ROMC_03_L = 34; - public const ushort ROMC_1C_L = 35; + public const byte ROMC_01 = 1; + public const byte ROMC_02 = 2; + public const byte ROMC_03_S = 3; + public const byte ROMC_04 = 4; + public const byte ROMC_05 = 5; + public const byte ROMC_06 = 6; + public const byte ROMC_07 = 7; + public const byte ROMC_08 = 8; + public const byte ROMC_09 = 9; + public const byte ROMC_0A = 10; + public const byte ROMC_0B = 11; + public const byte ROMC_0C = 12; + public const byte ROMC_0D = 13; + public const byte ROMC_0E = 14; + public const byte ROMC_0F = 15; + public const byte ROMC_10 = 16; + public const byte ROMC_11 = 17; + public const byte ROMC_12 = 18; + public const byte ROMC_13 = 19; + public const byte ROMC_14 = 20; + public const byte ROMC_15 = 21; + public const byte ROMC_16 = 22; + public const byte ROMC_17 = 23; + public const byte ROMC_18 = 24; + public const byte ROMC_19 = 25; + public const byte ROMC_1A = 26; + public const byte ROMC_1B = 27; + public const byte ROMC_1C_S = 28; + public const byte ROMC_1D = 29; + public const byte ROMC_1E = 30; + public const byte ROMC_1F = 31; + public const byte ROMC_00_S = 32; + public const byte ROMC_00_L = 33; + public const byte ROMC_03_L = 34; + public const byte ROMC_1C_L = 35; - public const ushort IDLE = 0; - public const ushort END = 51; + public const byte IDLE = 0; + public const byte END = 51; - public const ushort OP_LR8 = 100; - public const ushort OP_SHFT_R = 101; - public const ushort OP_SHFT_L = 102; - public const ushort OP_LNK = 103; - public const ushort OP_DI = 104; - public const ushort OP_EI = 105; - public const ushort OP_INC8 = 106; - public const ushort OP_AND8 = 107; - public const ushort OP_OR8 = 108; - public const ushort OP_XOR8 = 109; - //public const ushort OP_COM = 110; - public const ushort OP_SUB8 = 110; - public const ushort OP_ADD8 = 111; - public const ushort OP_CI = 112; - public const ushort OP_IS_INC = 113; - public const ushort OP_IS_DEC = 114; - public const ushort OP_LISU = 115; - public const ushort OP_LISL = 116; - public const ushort OP_BT = 117; - public const ushort OP_ADD8D = 118; - public const ushort OP_BR7 = 119; - public const ushort OP_BF = 120; - public const ushort OP_IN = 121; - public const ushort OP_OUT = 122; - //public const ushort OP_AS_IS = 123; - //public const ushort OP_XS_IS = 124; - //public const ushort OP_NS_IS = 125; - public const ushort OP_LR_A_DB_IO = 126; - public const ushort OP_DS = 127; - //public const ushort OP_CLEAR_FLAGS = 126; - //public const ushort OP_SET_FLAGS_SZ = 127; - public const ushort OP_LIS = 128; + public const byte OP_LR8 = 100; + public const byte OP_SHFT_R = 101; + public const byte OP_SHFT_L = 102; + public const byte OP_LNK = 103; + public const byte OP_DI = 104; + public const byte OP_EI = 105; + public const byte OP_INC8 = 106; + public const byte OP_AND8 = 107; + public const byte OP_OR8 = 108; + public const byte OP_XOR8 = 109; + //public const byte OP_COM = 110; + public const byte OP_SUB8 = 110; + public const byte OP_ADD8 = 111; + public const byte OP_CI = 112; + public const byte OP_IS_INC = 113; + public const byte OP_IS_DEC = 114; + public const byte OP_LISU = 115; + public const byte OP_LISL = 116; + public const byte OP_BT = 117; + public const byte OP_ADD8D = 118; + public const byte OP_BR7 = 119; + public const byte OP_BF = 120; + public const byte OP_IN = 121; + public const byte OP_OUT = 122; + //public const byte OP_AS_IS = 123; + //public const byte OP_XS_IS = 124; + //public const byte OP_NS_IS = 125; + public const byte OP_LR_A_DB_IO = 126; + public const byte OP_DS = 127; + //public const byte OP_CLEAR_FLAGS = 126; + //public const byte OP_SET_FLAGS_SZ = 127; + public const byte OP_LIS = 128; public F3850() @@ -208,7 +208,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF // loads supplied index value into register case OP_LIS: - Regs[ALU1] = (ushort)(cur_instr[instr_pntr++] & 0x0F); + Regs[ALU1] = (byte)(cur_instr[instr_pntr++] & 0x0F); LR_Func(A, ALU1); break; @@ -239,7 +239,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF // A <- (A) + (C) case OP_LNK: - Regs[ALU0] = (ushort)(FlagC ? 1 : 0); + Regs[ALU0] = (byte)(FlagC ? 1 : 0); ADD_Func(A, ALU0); break; @@ -280,22 +280,22 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF // ISAR is incremented case OP_IS_INC: - Regs[ISAR] = (ushort)((Regs[ISAR]& 0x38) | ((Regs[ISAR] + 1) & 0x07)); + Regs[ISAR] = (byte)((Regs[ISAR]& 0x38) | ((Regs[ISAR] + 1) & 0x07)); break; // ISAR is decremented case OP_IS_DEC: - Regs[ISAR] = (ushort)((Regs[ISAR] & 0x38) | ((Regs[ISAR] - 1) & 0x07)); + Regs[ISAR] = (byte)((Regs[ISAR] & 0x38) | ((Regs[ISAR] - 1) & 0x07)); break; // set the upper octal ISAR bits (b3,b4,b5) case OP_LISU: - Regs[ISAR] = (ushort)((((Regs[ISAR] & 0x07) | (cur_instr[instr_pntr++] & 0x07) << 3)) & 0x3F); + Regs[ISAR] = (byte)((((Regs[ISAR] & 0x07) | (cur_instr[instr_pntr++] & 0x07) << 3)) & 0x3F); break; // set the lower octal ISAR bits (b0,b1,b2) case OP_LISL: - Regs[ISAR] = (ushort) (((Regs[ISAR] & 0x38) | (cur_instr[instr_pntr++] & 0x07)) & 0x3F); + Regs[ISAR] = (byte) (((Regs[ISAR] & 0x38) | (cur_instr[instr_pntr++] & 0x07)) & 0x3F); break; // decrement scratchpad byte @@ -333,8 +333,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF break; case 5: - // branch if positive (same as t==1) - if (FlagS) branchBT = true; + // branch if positive and zero + if (FlagS || FlagZ) branchBT = true; break; case 6: @@ -342,8 +342,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF if (FlagZ || FlagC) branchBT = true; break; case 7: - // branch if positive or on carry (same as t==3) - if (FlagS || FlagC) branchBT = true; + // branch if positive or on carry or zero + if (FlagS || FlagC || FlagZ) branchBT = true; break; } @@ -355,13 +355,13 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF // Branch on ISARL case OP_BR7: instr_pntr = 1; // lose a cycle - if (!Regs[ISAR].Bit(0) || !Regs[ISAR].Bit(1) || !Regs[ISAR].Bit(2)) + if (Regs[ISAR].Bit(0) && Regs[ISAR].Bit(1) && Regs[ISAR].Bit(2)) { - DO_BRANCH(); + DONT_BRANCH(); } else { - DONT_BRANCH(); + DO_BRANCH(); } break; @@ -396,8 +396,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF break; case 5: - // same as t==1 - if (!FlagS) branchBF = true; + // branch if not zero and negative + if (!FlagS && !FlagZ) branchBF = true; break; case 6: @@ -406,8 +406,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF break; case 7: - // same as t==3 - if (!FlagS && !FlagC) branchBF = true; + // branch if not zero, carry and sign + if (!FlagS && !FlagC && !FlagZ) branchBF = true; break; case 8: @@ -436,8 +436,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF break; case 0xD: - // same as t==9 - if (!FlagS && !FlagO) branchBF = true; + // branch if no overflow, not zero and neg + if (!FlagS && !FlagO && !FlagZ) branchBF = true; break; case 0xE: @@ -446,8 +446,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF break; case 0xF: - // same as t=0xB - if (!FlagO && !FlagC && !FlagS) branchBF = true; + // all neg + if (!FlagO && !FlagC && !FlagS && FlagZ) branchBF = true; break; } @@ -461,13 +461,11 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF instr_pntr++; // dest == A Regs[ALU0] = cur_instr[instr_pntr++]; // src IN_Func(A, ALU0); - //Regs[cur_instr[instr_pntr++]] = ReadHardware(cur_instr[instr_pntr++]); break; // I/O Port 0 or 1 <- (A) case OP_OUT: - WriteHardware(cur_instr[instr_pntr++], (byte)cur_instr[instr_pntr++]); - //OUT_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + WriteHardware(cur_instr[instr_pntr++], (byte)Regs[cur_instr[instr_pntr++]]); break; // instruction fetch @@ -779,10 +777,10 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF /// /// Optimization method to set cur_instr /// - private void PopulateCURINSTR(ushort d0 = 0, ushort d1 = 0, ushort d2 = 0, ushort d3 = 0, ushort d4 = 0, ushort d5 = 0, ushort d6 = 0, ushort d7 = 0, ushort d8 = 0, - ushort d9 = 0, ushort d10 = 0, ushort d11 = 0, ushort d12 = 0, ushort d13 = 0, ushort d14 = 0, ushort d15 = 0, ushort d16 = 0, ushort d17 = 0, ushort d18 = 0, - ushort d19 = 0, ushort d20 = 0, ushort d21 = 0, ushort d22 = 0, ushort d23 = 0, ushort d24 = 0, ushort d25 = 0, ushort d26 = 0, ushort d27 = 0, ushort d28 = 0, - ushort d29 = 0, ushort d30 = 0, ushort d31 = 0, ushort d32 = 0, ushort d33 = 0, ushort d34 = 0, ushort d35 = 0, ushort d36 = 0, ushort d37 = 0) + private void PopulateCURINSTR(byte d0 = 0, byte d1 = 0, byte d2 = 0, byte d3 = 0, byte d4 = 0, byte d5 = 0, byte d6 = 0, byte d7 = 0, byte d8 = 0, + byte d9 = 0, byte d10 = 0, byte d11 = 0, byte d12 = 0, byte d13 = 0, byte d14 = 0, byte d15 = 0, byte d16 = 0, byte d17 = 0, byte d18 = 0, + byte d19 = 0, byte d20 = 0, byte d21 = 0, byte d22 = 0, byte d23 = 0, byte d24 = 0, byte d25 = 0, byte d26 = 0, byte d27 = 0, byte d28 = 0, + byte d29 = 0, byte d30 = 0, byte d31 = 0, byte d32 = 0, byte d33 = 0, byte d34 = 0, byte d35 = 0, byte d36 = 0, byte d37 = 0) { cur_instr[0] = d0; cur_instr[1] = d1; cur_instr[2] = d2; cur_instr[3] = d3; cur_instr[4] = d4; cur_instr[5] = d5; diff --git a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Memory.cs b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Memory.cs index 6cf6ced0ca..41fbd55593 100644 --- a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Memory.cs +++ b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Memory.cs @@ -34,7 +34,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF else if (addr < 0x2000) { // Cart - return 0; + //return 0; return Rom[addr - 0x800]; } diff --git a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Ports.cs b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Ports.cs index 079f952168..acf9373e9e 100644 --- a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Ports.cs +++ b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Ports.cs @@ -35,9 +35,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF /// public byte ReadPort(ushort addr) { - byte port = (byte) (addr & 0x07); - - switch (port) + switch (addr) { // Console buttons // b0: TIME @@ -45,7 +43,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF // b2: HOLD // b3: START case 0: - return (byte)((DataConsole ^ 0xFF) & 0x0F); + return (byte)((DataConsole ^ 0xff) | PortLatch[PORT0]); // Right controller // b0: RIGHT @@ -57,11 +55,16 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF // b6: PULL // b7: PUSH case 1: - if (ControllersEnabled) + byte ed1; + if ((PortLatch[PORT0] & 0x40) == 0) { - return (byte)((DataRight ^ 0xFF) & 0xFF); + ed1 = DataRight; } - return 0; + else + { + ed1 = (byte) (0xC0 | DataRight); + } + return (byte) ((ed1 ^ 0xff) | PortLatch[PORT1]); // Left controller // b0: RIGHT @@ -73,14 +76,23 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF // b6: PULL // b7: PUSH case 4: - if (ControllersEnabled) + byte ed4; + if ((PortLatch[PORT0] & 0x40) == 0) { - return (byte)((DataLeft ^ 0xFF) & 0xFF); + ed4 = DataLeft; } + else + { + ed4 = 0xff; + } + return (byte)((ed4 ^ 0xff) | PortLatch[PORT4]); + + case 5: + return (byte) (0 | PortLatch[PORT5]); + + default: return 0; } - - return 0xFF; } /// @@ -90,97 +102,70 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF /// public void WritePort(ushort addr, byte value) { - byte port = (byte)(addr & 0x07); - - switch (port) + switch (addr) { case 0: - - ControllersEnabled = (value & 0x40) == 0; - - var val = value & 0x60; - if (val == 0x40)// && _arm == 0x60) - { - VRAM[(128 * _y) + _x] = (byte)_colour; - } - - /* - - // RAM WRT - A pulse here executes a write to video RAM - bool ramWrt = value.Bit(5); - - // Enable data from controllers (1 equals enable) - // also needs pulse to write to video RAM - bool controllerDataEnable = value.Bit(6); - - if (ramWrt || controllerDataEnable) - { - // triggered write to VRAM - var yxIndex = (_y * 128) + _x; - var byteIndex = yxIndex / 4; - var byteRem = yxIndex % 4; - - switch (byteRem) - { - case 0: - VRAM[byteIndex] |= (byte) _colour; - break; - case 1: - VRAM[byteIndex] |= (byte) (_colour << 2); - break; - case 2: - VRAM[byteIndex] |= (byte)(_colour << 4); - break; - case 3: - VRAM[byteIndex] |= (byte)(_colour << 6); - break; - } - - } - */ - - _arm = value; - PortLatch[PORT0] = value; - + if ((value & 0x20) != 0) + { + var offset = _x + (_y * 128); + VRAM[offset] = (byte)(_colour); + } break; case 1: + PortLatch[PORT1] = value; + // Write Data0 - indicates that valid data is present for both VRAM ODD0 and EVEN0 bool data0 = value.Bit(6); // Write Data1 - indicates that valid data is present for both VRAM ODD1 and EVEN1 bool data1 = value.Bit(7); - _colour = ((value ^ 0xff) >> 6) & 0x03; - - PortLatch[PORT1] = value; - + //_colour = ((value) >> 6) & 3; + _colour = ((value ^ 0xff) >> 6) & 0x3; break; case 4: + PortLatch[PORT4] = value; + _x = (value ^ 0xff) & 0x7f; + //_x = (value | 0x80) ^ 0xFF; + /* // video horizontal position // 0 - video select // 1-6 - horiz A-F - _x = (value ^ 0xff) & 0x7f; + - PortLatch[PORT4] = value; + */ break; case 5: + PortLatch[PORT5] = value; + //_y = (value & 31); // ^ 0xff; + //_y = (value | 0xC0) ^ 0xff; + + //_y = (value ^ 0xff) & 0x1f; + // video vertical position and sound // 0-5 - Vertical A-F // 6 - Tone AN, 7 - Tone BN _y = (value ^ 0xff) & 0x3f; - PortLatch[PORT5] = value; - + // audio + var aVal = ((value >> 6) & 0x03); // (value & 0xc0) >> 6; + if (aVal != tone) + { + tone = aVal; + time = 0; + amplitude = 1; + AudioChange(); + } break; } } diff --git a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Video.cs b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Video.cs index 864e228c2a..9c26fec92f 100644 --- a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Video.cs +++ b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Video.cs @@ -1,4 +1,5 @@ using System; +using System.CodeDom; using System.Collections.Generic; using System.Linq; using System.Text; @@ -20,6 +21,10 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF public static readonly int[] FPalette = { + /* + 0x101010, 0xFDFDFD, 0x5331FF, 0x5DCC02, 0xF33F4B, 0xE0E0E0, 0xA6FF91, 0xD0CEFF + */ + Colors.ARGB(0x10, 0x10, 0x10), // Black Colors.ARGB(0xFD, 0xFD, 0xFD), // White Colors.ARGB(0xFF, 0x31, 0x53), // Red @@ -28,6 +33,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF Colors.ARGB(0xE0, 0xE0, 0xE0), // Gray Colors.ARGB(0x91, 0xFF, 0xA6), // BGreen Colors.ARGB(0xCE, 0xD0, 0xFF), // BBlue + }; public static readonly int[] CMap = @@ -52,67 +58,21 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF for (int row = 0; row < 64; row++) { // columns 125 and 126 hold the palette index modifier for the entire row - var rIndex = 64 * row; - var c125 = (VRAM[rIndex + 125] & 0x02) >> 1; + var rIndex = 128 * row; + var c125 = (VRAM[rIndex + 125] & 0x03); var c126 = (VRAM[rIndex + 126] & 0x03); - var pModifier = ((c125 | c126) << 2) & 0x0C; + var pModifier = (((c126 & 0x02) | c125 >> 1) << 2); + + pModifier = ((VRAM[(row << 7) + 125] & 2) >> 1) | (VRAM[(row << 7) + 126] & 3); + pModifier = (pModifier << 2) & 0xc; // columns for (int col = 0; col < 128; col++, counter++) { - int colour = (VRAM[rIndex + col]) & 0x03; - var finalColorIndex = pModifier | colour; - var paletteLookup = CMap[finalColorIndex & 0x0f] & 0x07; - frameBuffer[counter] = FPalette[paletteLookup]; - } - } - } - - private void BuildFrame1() - { - int cnt = 0; - // rows - for (int row = 0; row < 64; row++) - { - var yIndex = row * 128; - var yByte = yIndex / 4; - - // last byte for this row contains palette modifier - var pModifier = (byte)(VRAM[yByte + 31] & 0x0C); - - // columns - for (int col = 0; col < 128; col++) - { - var fbIndex = (row * 64) + col; - - var xByte = col / 4; - var xRem = col % 4; - var xyByte = yByte + xByte; - - // each byte contains 4 pixel colour values, b0b1, b2b3, b4b5, b6b7 - int colour = 0; - - switch (xRem) - { - case 0: - colour = VRAM[xyByte] & 0x03; - break; - case 1: - colour = VRAM[xyByte] & 0x0C; - break; - case 2: - colour = VRAM[xyByte] & 0x30; - break; - case 3: - colour = VRAM[xyByte] & 0xC0; - break; - } - - var finalColorIndex = pModifier | colour; - var paletteLookup = CMap[finalColorIndex & 0x0f] & 0x07; - frameBuffer[fbIndex] = FPalette[paletteLookup]; - - cnt++; + int cl = (VRAM[(row << 7) + col]) & 0x3; + frameBuffer[(row << 7) + col] = CMap[pModifier | cl] & 0x7; + //var nCol = pModifier + (VRAM[col | (row << 7)] & 0x03); + //frameBuffer[counter] = FPalette[CMap[nCol]]; } } }