diff --git a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj index 22e5ff52a4..375e04e43d 100644 --- a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj +++ b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj @@ -605,10 +605,10 @@ + - diff --git a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IO.cs b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IO.cs index 1a53e983bf..0df6d3e1a0 100644 --- a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IO.cs +++ b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IO.cs @@ -76,7 +76,9 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF public void WritePort(ushort addr, byte value) { - var port = addr & 0x7; + PortLatch[addr] = value; + + VID_PortIN(addr, value); } } } diff --git a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IVideoProvider.cs b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IVideoProvider.cs index d8d3307a63..a009e491e0 100644 --- a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IVideoProvider.cs +++ b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.IVideoProvider.cs @@ -12,6 +12,14 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF public int[] GetVideoBuffer() { + int row; + int col; + int color; + int pal; + + + + return _vidbuffer; } @@ -24,6 +32,42 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF public int VsyncDenominator => 1; + private int[] colors = { 0x101010, 0xFDFDFD, 0x5331FF, 0x5DCC02, 0xF33F4B, 0xE0E0E0, 0xA6FF91, 0xD0CEFF }; + private int[] palette = {0,1,1,1, 7,2,4,3, 6,2,4,3, 5,2,4,3}; + private int[] buffer = new int[8192]; + + int ARM = 0; + int X = 0; + int Y = 0; + int Color = 2; + + public void VID_PortIN(ushort port, byte val) + { + switch (port) + { + case 0: // ARM + val &= 0x60; + if (val == 0x40 && ARM == 0x60) // Strobed + { + // Write to display buffer + buffer[(Y << 7) + X] = Color; + } + ARM = val; + break; + + case 1: // Set Color (bits 6 and 7) + Color = ((val ^ 0xFF) >> 6) & 3; + break; + case 4: // X coordinate, inverted (bits 0-6) + X = (val ^ 0xFF) & 0x7F; + break; + case 5: // Y coordinate, inverted (bits 0-5) + Y = (val ^ 0xFF) & 0x3F; + break; + } + } + + #region IRegionable public DisplayType Region => DisplayType.NTSC; diff --git a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.ALU.cs b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.ALU.cs new file mode 100644 index 0000000000..002452e1cd --- /dev/null +++ b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.ALU.cs @@ -0,0 +1,319 @@ +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_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); + ALU_SetFlags_SZ(tmp); + + 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) + { + 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; + } + */ + + /// + /// 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) + { + // TODO + Regs[dest] = (ushort)(Regs[dest] ^ Regs[src]); + FlagZ = Regs[dest] == 0; + FlagC = false; + FlagO = false; + FlagS = Regs[dest] > 127; + } + */ + + public void ADDS_Func(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 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) + { + // 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.Execute.cs b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Execute.cs index 1388066c80..f1a5283654 100644 --- a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Execute.cs +++ b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Execute.cs @@ -47,7 +47,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF case 0x15: SHIFT_L(4); break; // Shift (A) left four bit positions (zero fill) case 0x16: LM(); break; // A <- ((DC0)) case 0x17: ST(); break; // (DC) <- (A) - case 0x18: COM(); break; // A <- A XOR 255 (complement A) + case 0x18: COM(); break; // A <- A XOR 255 (complement A) + case 0x19: LNK(); break; // A <- (A) + (C) case 0x1A: DI(); break; // Clear ICB case 0x1B: EI(); break; // Set ICB case 0x1C: POP(); break; // PC0 <- PC1 diff --git a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Operations.cs b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Operations.cs deleted file mode 100644 index 2d33637bec..0000000000 --- a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Operations.cs +++ /dev/null @@ -1,300 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using BizHawk.Common; -using BizHawk.Common.NumberExtensions; -using BizHawk.Emulation.Common; - -namespace BizHawk.Emulation.Cores.Consoles.ChannelF -{ - public sealed partial class F3850 - { - 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 LR8_IO_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]; - } - - // update flags - FlagO = false; - FlagC = false; - FlagZ = (Regs[dest] & 0xFF) == 0; - FlagS = Regs[dest] > 127; - } - - public void SZ_FLAG_TEST(ushort value) - { - // SZ only - FlagO = false; - FlagC = false; - FlagZ = (value & 0xFF) == 0; - FlagS = value > 127; - } - - public void SR_Func(ushort src, ushort index) - { - int shft = (Regs[src] >> index) & 0xFF; - FlagO = false; - FlagC = false; - FlagZ = shft == 0; - FlagS = (~shft & 0x80) != 0; - Regs[src] = (ushort)shft; - } - - public void SL_Func(ushort src, ushort index) - { - int shft = (Regs[src] << index) & 0xFF; - FlagO = false; - FlagC = false; - FlagZ = shft == 0; - FlagS = (~shft & 0x80) != 0; - Regs[src] = (ushort)shft; - } - - public void ADD8_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; - } - - public void ADDS_Func(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 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; - } - - // binary addition performed and flags set accordingly - int Reg16_d = Regs[dest]; - Reg16_d += Regs[src]; - ushort ans = (ushort)(Reg16_d & 0xFF); - - FlagC = tmp.Bit(8); - FlagZ = (tmp & 0xFF) == 0; - - FlagO = (Regs[dest].Bit(7) == Regs[src].Bit(7)) && (Regs[dest].Bit(7) != ans.Bit(7)); - FlagS = ans > 127; - - 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 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; - } - - public void 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; - } - - public void AND8_Func(ushort dest, ushort src) - { - Regs[dest] = (ushort)(Regs[dest] & Regs[src]); - - FlagZ = Regs[dest] == 0; - FlagC = false; - FlagO = false; - FlagS = Regs[dest] > 127; - } - - public void OR8_Func(ushort dest, ushort src) - { - Regs[dest] = (ushort)(Regs[dest] | Regs[src]); - FlagZ = Regs[dest] == 0; - FlagC = false; - FlagO = false; - FlagS = Regs[dest] > 127; - } - - public void XOR8_Func(ushort dest, ushort src) - { - Regs[dest] = (ushort)(Regs[dest] ^ Regs[src]); - FlagZ = Regs[dest] == 0; - FlagC = false; - FlagO = false; - FlagS = Regs[dest] > 127; - } - - public void 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 COM_Func(ushort src) - { - byte b = (byte)Regs[src]; - var r = (byte)~b; - FlagO = false; - FlagC = false; - FlagZ = r == 0; - FlagS = (~r & 0x80) != 0; - Regs[src] = (ushort)r; - } - */ - - public void IN_Func(ushort dest, ushort src) - { - Regs[dest] = ReadHardware(Regs[src]); - - FlagZ = Regs[dest] == 0; - FlagO = false; - FlagC = false; - FlagS = Regs[dest].Bit(7); - } - - public void OUT_Func(ushort dest, ushort src) - { - WriteHardware(Regs[dest], (byte) Regs[src]); - } - - - public void Read_Func(ushort dest, ushort src) - { - Regs[dest] = Regs[src]; - } - } -} 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 f47c03521b..6e5e057dd4 100644 --- a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Registers.cs +++ b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Registers.cs @@ -69,23 +69,31 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF /// /// Temporary Arithmetic Storage /// - public ushort ALU = 74; + public ushort ALU0 = 74; + /// + /// Temporary Arithmetic Storage + /// + public ushort ALU1 = 75; /// /// Data Bus /// - public ushort DB = 75; + public ushort DB = 76; /// /// IO Bus/Latch /// - public ushort IO = 76; + public ushort IO = 77; /// /// 0x00 value for arithmetic ops /// - public ushort ZERO = 77; + public ushort ZERO = 78; /// - /// 0xff value for arithmetic ops + /// 0x01 value for arithmetic ops /// - public ushort ONE = 78; + public ushort ONE = 79; + /// + /// 0xFF value for arithmetic ops + /// + public ushort BYTE = 80; /// @@ -180,6 +188,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF } Regs[ONE] = 1; + Regs[BYTE] = 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 4a1ca15be2..7bd4680a4f 100644 --- a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Tables.cs +++ b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Tables.cs @@ -364,7 +364,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF { PopulateCURINSTR( // S - OP_XOR8C, A, ONE, // A <- A XOR 0xFF + OP_COM, // A <- A XOR 0xFF (compliment accumulator) ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, END); @@ -454,7 +454,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF { PopulateCURINSTR( // S - OP_INC8, A, // A <- A + 1 + OP_INC8, A, ONE, // A <- A + 1 ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, END); @@ -466,9 +466,9 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF // L ROMC_03_L, // DB <- ((PC0)); PC0++ IDLE, - IDLE, + OP_CLEAR_FLAGS, OP_LR8, A, DB, // A <- (DB) - IDLE, + OP_SET_FLAGS_SZ, A, IDLE, // S ROMC_00_S, // DB <- ((PC0)); PC0++ @@ -534,9 +534,9 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF // L ROMC_03_L, // DB <- ((PC0)); PC0++ IDLE, - IDLE, + OP_CLEAR_FLAGS, OP_ADD8, A, DB, // A <- (A) + (DB) - IDLE, + OP_SET_FLAGS_SZ, A, IDLE, // S ROMC_00_S, // DB <- ((PC0)); PC0++ @@ -551,8 +551,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF // L ROMC_03_L, // DB <- ((PC0)); PC0++ IDLE, - IDLE, - OP_CI, A, // Set flags for A <- (A) + (DB) + 1 (do not store result in A) + OP_CLEAR_FLAGS, + OP_CI, A, DB, // Set flags for A <- (A) + (DB) + 1 (do not store result in A) IDLE, IDLE, // S @@ -580,16 +580,16 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF ROMC_03_L, // DB/IO <- ((PC0)); PC0++ IDLE, IDLE, - IDLE, + OP_CLEAR_FLAGS, IDLE, IDLE, // L ROMC_1B, // DB <- ((IO)); IDLE, IDLE, - OP_LR8_IO, A, DB, // A <- (DB) - IDLE, + OP_LR8, A, DB, // A <- (DB) IDLE, + OP_SET_FLAGS_SZ, A, // S ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, @@ -751,52 +751,55 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF { PopulateCURINSTR( // L - OP_SUB8, rIndex, ONE, - IDLE, + OP_CLEAR_FLAGS, + OP_ADD8, rIndex, BYTE, + OP_SET_FLAGS_SZ, rIndex, ROMC_00_L, // DB <- ((PC0)); PC0++ IDLE, - IDLE, END); } private void DS_ISAR() { PopulateCURINSTR( // L - OP_DS_IS, - IDLE, + OP_CLEAR_FLAGS, + OP_ADD8, Regs[ISAR], BYTE, // r[ISAR] = r[ISAR] + 0xff + OP_SET_FLAGS_SZ, Regs[ISAR], ROMC_00_L, // DB <- ((PC0)); PC0++ IDLE, - IDLE, END); } private void DS_ISAR_INC() { PopulateCURINSTR( - OP_DS_IS, // L - OP_IS_INC, - ROMC_00_L, - IDLE, - IDLE, + // L + OP_CLEAR_FLAGS, + OP_ADD8, Regs[ISAR], BYTE, // r[ISAR] = r[ISAR] + 0xff + OP_SET_FLAGS_SZ, Regs[ISAR], + OP_IS_INC, // Inc ISAR + ROMC_00_L, // DB <- ((PC0)); PC0++ END); } private void DS_ISAR_DEC() { PopulateCURINSTR( - OP_DS_IS, // L - OP_IS_DEC, - ROMC_00_L, - IDLE, - IDLE, + // L + OP_CLEAR_FLAGS, + OP_ADD8, Regs[ISAR], BYTE, // r[ISAR] = r[ISAR] + 0xff + OP_SET_FLAGS_SZ, Regs[ISAR], + OP_IS_DEC, // Dec ISAR + ROMC_00_L, // DB <- ((PC0)); PC0++ END); } private void LR_A_R(ushort rIndex) { PopulateCURINSTR( - OP_LR8, A, rIndex, // S - ROMC_00_S, + // S + OP_LR8, A, rIndex, // A <- (rIndex) + ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, END); } @@ -804,8 +807,9 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF private void LR_A_ISAR() { PopulateCURINSTR( - OP_LR_A_IS, A, // S - ROMC_00_S, + // S + OP_LR8, A, Regs[ISAR], // A <- ((ISAR)) + ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, END); } @@ -813,26 +817,29 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF private void LR_A_ISAR_INC() { PopulateCURINSTR( - OP_LR_A_IS, A, // S - OP_IS_INC, - ROMC_00_S, + // S + OP_LR8, A, Regs[ISAR], // A <- ((ISAR)) + OP_IS_INC, // Inc ISAR + ROMC_00_S, // DB <- ((PC0)); PC0++ END); } private void LR_A_ISAR_DEC() { PopulateCURINSTR( - OP_LR_A_IS, A, // S - OP_IS_DEC, - ROMC_00_S, + // S + OP_LR8, A, Regs[ISAR], // A <- ((ISAR)) + OP_IS_DEC, // Dec ISAR + ROMC_00_S, // DB <- ((PC0)); PC0++ END); } private void LR_R_A(ushort rIndex) { PopulateCURINSTR( - OP_LR8, rIndex, A, // S - ROMC_00_S, + // S + OP_LR8, rIndex, A, // rIndex <- (A) + ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, END); } @@ -840,8 +847,9 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF private void LR_ISAR_A() { PopulateCURINSTR( - OP_LR_IS_A, A, // S - ROMC_00_S, + // S + OP_LR8, Regs[ISAR], A, // rIndex <- (A) + ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, END); } @@ -849,26 +857,29 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF private void LR_ISAR_A_INC() { PopulateCURINSTR( - OP_LR_IS_A, A, // S - OP_IS_INC, - ROMC_00_S, + // S + OP_LR8, Regs[ISAR], A, // rIndex <- (A) + OP_IS_INC, // Inc ISAR + ROMC_00_S, // DB <- ((PC0)); PC0++ END); } private void LR_ISAR_A_DEC() { PopulateCURINSTR( - OP_LR_IS_A, A, // S - OP_IS_DEC, - ROMC_00_S, + // S + OP_LR8, Regs[ISAR], A, // rIndex <- (A) + OP_IS_DEC, // Dec ISAR + ROMC_00_S, // DB <- ((PC0)); PC0++ END); } private void LISU(ushort octal) { PopulateCURINSTR( - OP_LISU, octal, // S - ROMC_00_S, + // S + OP_LISU, octal, // set the upper octal ISAR bits (b3,b4,b5) + ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, END); } @@ -876,8 +887,9 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF private void LISL(ushort octal) { PopulateCURINSTR( - OP_LISL, octal, // S - ROMC_00_S, + // S + OP_LISL, octal, // set the lower octal ISAR bits (b0,b1,b2) + ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, END); } @@ -885,8 +897,9 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF private void LIS(ushort index) { PopulateCURINSTR( - OP_LR8, A, index, // S - ROMC_00_S, + // S + OP_LR8, A, index, // A <- index + ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, END); } @@ -894,22 +907,25 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF private void BT(ushort index) { PopulateCURINSTR( - ROMC_1C_S, // S + // S + ROMC_1C_S, // Idle IDLE, IDLE, - OP_BT, index); // no END as there is branching logic within OP_BT + OP_BT, index); // no END as there is branching logic within OP_BT } private void AM() { PopulateCURINSTR( - ROMC_02, // L + // L + ROMC_02, // DB <- ((DC0)); DC0++ + OP_CLEAR_FLAGS, IDLE, + OP_ADD8, A, DB, // A <- (DB) + OP_SET_FLAGS_SZ, A, IDLE, - OP_ADD8, A, DB, - IDLE, - IDLE, - ROMC_00_S, // S + // S + ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, IDLE, END); @@ -918,13 +934,15 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF private void AMD() { PopulateCURINSTR( - ROMC_02, // L + // L + ROMC_02, // DB <- ((DC0)); DC0++ IDLE, IDLE, - OP_ADD8D, A, DB, + OP_ADD8D, A, DB, // A <- (A) + (DB) decimal IDLE, IDLE, - ROMC_00_S, // S + // S + ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, IDLE, END); @@ -933,13 +951,15 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF private void NM() { PopulateCURINSTR( - ROMC_02, // L + // 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, - IDLE, - IDLE, - ROMC_00_S, // S + // S + ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, IDLE, END); @@ -948,13 +968,15 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF private void OM() { PopulateCURINSTR( - ROMC_02, // L + // 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, - IDLE, - IDLE, - ROMC_00_S, // S + // S + ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, IDLE, END); @@ -963,13 +985,15 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF private void XM() { PopulateCURINSTR( - ROMC_02, // L + // L + ROMC_02, // DB <- ((DC0)); DC0++ IDLE, + OP_CLEAR_FLAGS, + OP_XOR8, A, DB, // A <- (A) XOR (DB) + OP_SET_FLAGS_SZ, A, IDLE, - OP_XOR8, A, DB, - IDLE, - IDLE, - ROMC_00_S, // S + // S + ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, IDLE, END); @@ -978,13 +1002,15 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF private void CM() { PopulateCURINSTR( - ROMC_02, // L + // L + ROMC_02, // DB <- ((DC0)); DC0++ + IDLE, + OP_CLEAR_FLAGS, + OP_CI, A, IDLE, IDLE, - OP_CM, - IDLE, - IDLE, - ROMC_00_S, // S + // S + ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, IDLE, END); @@ -993,13 +1019,15 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF private void ADC() { PopulateCURINSTR( - OP_LR8, DB, A, // L + // L + OP_LR8, DB, A, // DB <- (A) IDLE, IDLE, ROMC_0A, IDLE, IDLE, - ROMC_00_S, // S + // S + ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, IDLE, END); @@ -1014,20 +1042,23 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF private void BF(ushort index) { PopulateCURINSTR( - ROMC_1C_S, // S + // S + ROMC_1C_S, // Idle IDLE, IDLE, - OP_BF, index); // no END as there is branching logic within OP_BF + OP_BF, index); // no END as there is branching logic within OP_BF } private void INS_0(ushort index) { PopulateCURINSTR( - ROMC_1C_S, // S - IDLE, - OP_IN, A, index, - IDLE, - ROMC_00_S, // S + // S + ROMC_1C_S, // Idle + OP_CLEAR_FLAGS, + OP_IN, A, index, // A <- ((Port index - 0/1)) + OP_SET_FLAGS_SZ, A, + // S + ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, IDLE, END); @@ -1035,20 +1066,25 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF private void INS_1(ushort index) { + Regs[IO] = index; // latch port index early + PopulateCURINSTR( - ROMC_1C_L, // L + // L + ROMC_1C_L, // Idle IDLE, IDLE, - OP_LR8, IO, index, IDLE, IDLE, - ROMC_1B, // L IDLE, + // L + ROMC_1B, // DB <- ((IO)) IDLE, - OP_LR8_IO, A, DB, + OP_CLEAR_FLAGS, + OP_LR8, A, DB, // A <- (DB) + OP_SET_FLAGS_SZ, A, IDLE, - IDLE, - ROMC_00_S, // S + // S + ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, IDLE, END); @@ -1057,11 +1093,13 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF private void OUTS_0(ushort index) { PopulateCURINSTR( - ROMC_1C_S, // S + // S + ROMC_1C_S, // Idle IDLE, - OP_OUT, index, A, + OP_OUT, index, A, // Port <- (A) IDLE, - ROMC_00_S, // S + // S + ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, IDLE, END); @@ -1069,20 +1107,25 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF private void OUTS_1(ushort index) { + Regs[IO] = index; // latch port index early + PopulateCURINSTR( - ROMC_1C_L, // L + // L + ROMC_1C_L, // Idle IDLE, IDLE, - OP_LR8, IO, index, - OP_LR8, DB, A, + OP_LR8, DB, A, // DB <- (A) IDLE, - ROMC_1A, // L + IDLE, + // L + ROMC_1A, // ((IO)) <- (DB) IDLE, IDLE, IDLE, IDLE, IDLE, - ROMC_00_S, // S + // S + ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, IDLE, END); @@ -1090,48 +1133,59 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF private void AS(ushort rIndex) { + ALU_ClearFlags(); // clear flags early (as not enough cycle space for commands) + PopulateCURINSTR( - OP_ADD8, A, rIndex, // S - ROMC_00_S, - IDLE, + // S + OP_ADD8, A, rIndex, // A <- (A) + (rIndex) + OP_SET_FLAGS_SZ, A, + ROMC_00_S, // DB <- ((PC0)); PC0++ END); } private void AS_IS() { PopulateCURINSTR( - OP_AS_IS, // S - ROMC_00_S, + // S + OP_CLEAR_FLAGS, + OP_AS_IS, // A <- (A) + ((ISAR)); setSZ IDLE, + ROMC_00_S, // DB <- ((PC0)); PC0++ END); } private void AS_IS_INC() { PopulateCURINSTR( - OP_AS_IS, // S - OP_IS_INC, - ROMC_00_S, + // S + OP_CLEAR_FLAGS, + OP_AS_IS, // A <- (A) + ((ISAR)); setSZ + OP_IS_INC, // Inc ISAR + ROMC_00_S, // DB <- ((PC0)); PC0++ END); } private void AS_IS_DEC() { PopulateCURINSTR( - OP_AS_IS, // S - OP_IS_DEC, - ROMC_00_S, + // S + OP_CLEAR_FLAGS, + OP_AS_IS, // A <- (A) + ((ISAR)); setSZ + OP_IS_DEC, // Dec ISAR + ROMC_00_S, // DB <- ((PC0)); PC0++ END); } private void ASD(ushort rIndex) { PopulateCURINSTR( - ROMC_1C_S, // S + // S + ROMC_1C_S, // Idle IDLE, OP_ADD8D, A, rIndex, IDLE, - ROMC_00_S, // S + // S + ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, IDLE, END); @@ -1140,11 +1194,13 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF private void ASD_IS() { PopulateCURINSTR( - ROMC_1C_S, // S + // S + ROMC_1C_S, // Idle IDLE, - OP_ASD_IS, + OP_ADD8D, A, Regs[ISAR], IDLE, - ROMC_00_S, // S + // S + ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, IDLE, END); @@ -1153,11 +1209,13 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF private void ASD_IS_INC() { PopulateCURINSTR( - ROMC_1C_S, // S + // S + ROMC_1C_S, // Idle IDLE, - OP_ASD_IS, - OP_IS_INC, - ROMC_00_S, // S + OP_ADD8D, A, Regs[ISAR], + OP_IS_INC, // Inc ISAR + // S + ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, IDLE, END); @@ -1166,11 +1224,13 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF private void ASD_IS_DEC() { PopulateCURINSTR( - ROMC_1C_S, // S + // S + ROMC_1C_S, // Idle IDLE, - OP_ASD_IS, - OP_IS_DEC, - ROMC_00_S, // S + OP_ADD8D, A, Regs[ISAR], + OP_IS_DEC, // Dec ISAR + // S + ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, IDLE, END); @@ -1179,17 +1239,20 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF private void XS(ushort rIndex) { PopulateCURINSTR( - OP_XOR8, A, rIndex, // S - ROMC_00_S, - IDLE, + // S + OP_CLEAR_FLAGS, + OP_XOR8, A, rIndex, // A <- (A) XOR (reg) + OP_SET_FLAGS_SZ, A, + ROMC_00_S, // DB <- ((PC0)); PC0++ END); } private void XS_IS() { PopulateCURINSTR( - OP_XS_IS, // S - ROMC_00_S, + // S + OP_XS_IS, // A <- (A) XOR ((ISAR)) + ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, END); } @@ -1197,35 +1260,41 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF private void XS_IS_INC() { PopulateCURINSTR( - OP_XS_IS, // S - OP_IS_INC, - ROMC_00_S, + // S + OP_XS_IS, // A <- (A) XOR ((ISAR)) + OP_IS_INC, // Inc ISAR + ROMC_00_S, // DB <- ((PC0)); PC0++ END); } private void XS_IS_DEC() { PopulateCURINSTR( - OP_XS_IS, // S - OP_IS_DEC, - ROMC_00_S, + // S + OP_XS_IS, // A <- (A) XOR ((ISAR)) + OP_IS_DEC, // Dec ISAR + ROMC_00_S, // DB <- ((PC0)); PC0++ END); } private void NS(ushort rIndex) { + ALU_ClearFlags(); // clear flags early (as not enough cycle space for commands) + PopulateCURINSTR( - OP_AND8, A, rIndex, // S - ROMC_00_S, - IDLE, + // S + OP_AND8, A, rIndex, // A <- (A) AND (reg) + OP_SET_FLAGS_SZ, A, + ROMC_00_S, // DB <- ((PC0)); PC0++ END); } private void NS_IS() { PopulateCURINSTR( - OP_NS_IS, // S - ROMC_00_S, + // S + OP_NS_IS, // A <- (A) AND ((ISAR)) + ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, END); } @@ -1233,18 +1302,22 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF private void NS_IS_INC() { PopulateCURINSTR( - OP_NS_IS, // S - OP_IS_INC, - ROMC_00_S, + // S + OP_NS_IS, // A <- (A) AND ((ISAR)) + OP_IS_INC, // Inc ISAR + ROMC_00_S, // DB <- ((PC0)); PC0++ + IDLE, END); } private void NS_IS_DEC() { PopulateCURINSTR( - OP_NS_IS, // S - OP_IS_DEC, - ROMC_00_S, + // S + OP_NS_IS, // A <- (A) AND ((ISAR)) + OP_IS_DEC, // Dec ISAR + ROMC_00_S, // DB <- ((PC0)); PC0++ + 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 0cf4ebe0a4..df96c4aa1c 100644 --- a/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.cs +++ b/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.cs @@ -39,18 +39,9 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF public sealed partial class F3850 { // operations that can take place in an instruction - - //public const ushort OP = 1; - //public const ushort LR_8 = 2; - //public const ushort LR_16 = 3; - - - public const ushort ROMC_00_S = 40; - public const ushort ROMC_00_L = 41; public const ushort ROMC_01 = 1; public const ushort ROMC_02 = 2; public const ushort ROMC_03_S = 3; - public const ushort ROMC_03_L = 33; public const ushort ROMC_04 = 4; public const ushort ROMC_05 = 5; public const ushort ROMC_06 = 6; @@ -76,10 +67,13 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF public const ushort ROMC_1A = 26; public const ushort ROMC_1B = 27; public const ushort ROMC_1C_S = 28; - public const ushort ROMC_1C_L = 34; 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 ushort IDLE = 0; public const ushort END = 51; @@ -94,30 +88,24 @@ 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_XOR8C = 110; + public const ushort OP_COM = 110; public const ushort OP_ADD8 = 111; public const ushort OP_CI = 112; - public const ushort OP_LR8_IO = 113; - public const ushort OP_DS_IS = 114; - public const ushort OP_IS_INC = 115; - public const ushort OP_IS_DEC = 116; - public const ushort OP_LR_A_IS = 117; - public const ushort OP_LR_IS_A = 118; - public const ushort OP_LISU = 119; - public const ushort OP_LISL = 120; - public const ushort OP_BT = 121; - public const ushort OP_ADD8D = 122; - public const ushort OP_CM = 123; - public const ushort OP_BR7 = 124; - public const ushort OP_BF = 125; - public const ushort OP_IN = 126; - public const ushort OP_OUT = 127; - public const ushort OP_AS_IS = 128; - public const ushort OP_ASD_IS = 129; - public const ushort OP_XS_IS = 130; - public const ushort OP_NS_IS = 131; - public const ushort OP_AFTEST = 132; - public const ushort OP_SUB8 = 133; + 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_CLEAR_FLAGS = 126; + public const ushort OP_SET_FLAGS_SZ = 127; public F3850() @@ -147,6 +135,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF IDLE, END); + ALU_ClearFlags(); FlagICB = false; } @@ -202,6 +191,16 @@ 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++]); @@ -209,27 +208,35 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF // Shift register n bit positions to the right (zero fill) case OP_SHFT_R: - SR_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + ALU_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: - SL_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + ALU_SL_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); break; // x <- (x) ADD y case OP_ADD8: - ADD8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + ALU_ADD8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); break; // x <- (x) ADD y (decimal) case OP_ADD8D: - ADD8D_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + ALU_ADD8D_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); break; // A <- (A) + (C) case OP_LNK: - ADD8_Func(Regs[A], (ushort)(FlagC ? 1 : 0)); + bool fc = FlagC; + ALU_ClearFlags(); + + if (fc) + { + ALU_ADD8_Func(A, ONE); + } + + ALU_SetFlags_SZ(A); break; // Clear ICB status bit @@ -244,46 +251,38 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF // x <- (y) XOR DB case OP_XOR8: - XOR8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + ALU_XOR8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); break; // x <- (y) XOR DB (complement accumulator) - case OP_XOR8C: - XOR8C_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + case OP_COM: + Regs[A] = (byte)~Regs[A]; + ALU_ClearFlags(); + ALU_SetFlags_SZ(A); break; // x <- (x) + 1 case OP_INC8: - INC8_Func(cur_instr[instr_pntr++]); + ALU_ClearFlags(); + ALU_ADD8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + ALU_SetFlags_SZ(A); break; // x <- (y) & DB case OP_AND8: - AND8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + ALU_AND8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); break; // x <- (y) | DB case OP_OR8: - OR8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + ALU_OR8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); break; // DB + (x) + 1 (modify flags without saving result) case OP_CI: - var tmpX = cur_instr[instr_pntr++]; - var tmpOperand = Regs[DB]; - INC8_Func(tmpX); - ADD8_Func(tmpOperand, tmpX); - break; - - // load one register into another (or databus) - // ALU also runs flag status checking - case OP_LR8_IO: - LR8_IO_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); - break; - - // DS op performed indirectly on the ScratchPad register pointed to by the ISAR - case OP_DS_IS: - SUB8_Func(Regs[ISAR], ONE); + Regs[ALU0] = (byte)~Regs[cur_instr[instr_pntr++]]; + ALU_ADD8_Func(ALU0, DB, true); + ALU_SetFlags_SZ(ALU0); break; // ISAR is incremented @@ -296,26 +295,14 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF Regs[ISAR] = (ushort)((Regs[ISAR] & 0x38) | ((Regs[ISAR] - 1) & 0x07)); break; - // x <- (SR) (as pointed to by ISAR) - case OP_LR_A_IS: - LR8_Func(cur_instr[instr_pntr++], Regs[ISAR]); - break; - - // x <- (SR) (as pointed to by ISAR) - case OP_LR_IS_A: - LR8_Func(Regs[ISAR], cur_instr[instr_pntr++]); - break; - // set the upper octal ISAR bits (b3,b4,b5) case OP_LISU: - var isVala = (Regs[ISAR] & 0x07) | cur_instr[instr_pntr++]; - Regs[ISAR] = (ushort)(isVala & 0x3F); + Regs[ISAR] = (ushort) (((Regs[ISAR] & 0x07) | cur_instr[instr_pntr++]) & 0x3F); break; // set the lower octal ISAR bits (b0,b1,b2) case OP_LISL: - var isValb = (Regs[ISAR] & 0x38) | cur_instr[instr_pntr++]; - Regs[ISAR] = (ushort)(isValb & 0x3F); + Regs[ISAR] = (ushort) (((Regs[ISAR] & 0x38) | cur_instr[instr_pntr++]) & 0x3F); break; // test operand against status register @@ -324,13 +311,15 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF if ((Regs[W] & cur_instr[instr_pntr++]) != 0) { PopulateCURINSTR( - ROMC_01, // L + // L + ROMC_01, IDLE, IDLE, IDLE, IDLE, IDLE, - ROMC_00_S, // S + // S + ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, IDLE, END); @@ -338,35 +327,32 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF else { PopulateCURINSTR( - ROMC_03_S, // S + // S + ROMC_03_S, IDLE, IDLE, IDLE, - ROMC_00_S, // S + // S + ROMC_00_S, // DB < -((PC0)); PC0++ IDLE, IDLE, END); } break; - - // DC0 - A - set status only - case OP_CM: - var tmpDB = Regs[DB]; - var tmpA = Regs[A]; - SUB8_Func(tmpDB, tmpA); - break; - + // Branch based on ISARL case OP_BR7: instr_pntr = 0; if ((Regs[ISAR] & 7) == 7) { PopulateCURINSTR( - ROMC_03_S, // S + // S + ROMC_03_S, // DB/IO <- ((PC0)); PC0++ //IDLE, <- lose a cycle that was stolen in the table IDLE, IDLE, - ROMC_00_S, // S + // S + ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, IDLE, END); @@ -374,13 +360,14 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF else { PopulateCURINSTR( - ROMC_01, // L + // L + ROMC_01, //IDLE, <- lose a cycle that was stolen in the table IDLE, IDLE, IDLE, IDLE, - ROMC_00_S, // S + ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, IDLE, END); @@ -393,11 +380,13 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF if ((Regs[W] & cur_instr[instr_pntr++]) != 0) { PopulateCURINSTR( - ROMC_03_S, // S + // S + ROMC_03_S, // DB/IO <- ((PC0)); PC0++ IDLE, IDLE, IDLE, - ROMC_00_S, // S + // S + ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, IDLE, END); @@ -405,13 +394,15 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF else { PopulateCURINSTR( - ROMC_01, // L + // L + ROMC_01, IDLE, IDLE, IDLE, IDLE, IDLE, - ROMC_00_S, // S + // S + ROMC_00_S, // DB <- ((PC0)); PC0++ IDLE, IDLE, END); @@ -421,7 +412,6 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF // A <- (I/O Port 0 or 1) case OP_IN: Regs[cur_instr[instr_pntr++]] = ReadHardware(cur_instr[instr_pntr++]); - //IN_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); break; // I/O Port 0 or 1 <- (A) @@ -432,42 +422,33 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF // Add the content of the SR register addressed by ISAR to A (Binary) case OP_AS_IS: - ADD8_Func(A, Regs[ISAR]); - break; - - // Add the content of the SR register addressed by ISAR to A (Decimal) - case OP_ASD_IS: - ADD8D_Func(A, Regs[ISAR]); + 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: - XOR8_Func(A, Regs[ISAR]); + 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: - AND8_Func(A, Regs[ISAR]); - break; - - // Set flags based on accumulator - case OP_AFTEST: - break; - - // subtraction - case OP_SUB8: - SUB8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + 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. // CYCLE LENGTH: S case ROMC_00_S: - Regs[DB] = ReadMemory(RegPC0++); + Read_Func(DB, PC0l, PC0h); + RegPC0++; break; // instruction fetch @@ -475,14 +456,15 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF // then all devices increments the content of PC0. // CYCLE LENGTH: L case ROMC_00_L: - Regs[DB] = ReadMemory(RegPC0++); + Read_Func(DB, PC0l, PC0h); + RegPC0++; break; // The device whose address space includes the contents of the PC0 register must place on the data bus the contents of the memory location // addressed by by PC0; then all devices add the 8-bit value on the data bus, as a signed binary number, to PC0 // CYCLE LENGTH: L case ROMC_01: - Regs[DB] = ReadMemory(RegPC0); + Read_Func(DB, PC0l, PC0h); ADDS_Func(PC0l, PC0h, DB, ZERO); break; @@ -490,20 +472,23 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF // of the memory location addressed by DC0; then all devices increment DC0 // CYCLE LENGTH: L case ROMC_02: - Regs[DB] = ReadMemory(RegDC0++); + Read_Func(DB, DC0l, DC0h); + RegDC0++; break; // Similar to 0x00, except that it is used for Immediate Operand fetches (using PC0) instead of instruction fetches // CYCLE LENGTH: S case ROMC_03_S: - Regs[DB] = ReadMemory(RegPC0++); + Read_Func(DB, PC0l, PC0h); + RegPC0++; Regs[IO] = Regs[DB]; break; // Similar to 0x00, except that it is used for Immediate Operand fetches (using PC0) instead of instruction fetches // CYCLE LENGTH: L case ROMC_03_L: - Regs[DB] = ReadMemory(RegPC0++); + Read_Func(DB, PC0l, PC0h); + RegPC0++; Regs[IO] = Regs[DB]; break; @@ -516,7 +501,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF // Store the data bus contents into the memory location pointed to by DC0; increment DC0 // CYCLE LENGTH: L case ROMC_05: - WriteMemory(RegDC0++, (byte)Regs[DB]); + Write_Func(DC0l, DC0h, DB); break; // Place the high order byte of DC0 on the data bus @@ -563,7 +548,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF // onto the data bus; then all devices move the value that has just been placed on the data bus into the low order byte of PC0 // CYCLE LENGTH: L case ROMC_0C: - Regs[DB] = ReadMemory(RegPC0); + Read_Func(DB, PC0l, PC0h); Regs[PC0l] = Regs[DB]; break; @@ -577,7 +562,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF // The value on the data bus is then moved to the low order byte of DC0 by all devices // CYCLE LENGTH: L case ROMC_0E: - Regs[DB] = ReadMemory(RegPC0); + Read_Func(DB, PC0l, PC0h); Regs[DC0l] = Regs[DB]; break; @@ -596,7 +581,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF // All devices must then move the contents of the data bus to the upper byte of DC0 // CYCLE LENGTH: L case ROMC_11: - Regs[DB] = ReadMemory(RegPC0); + Read_Func(DB, PC0l, PC0h); Regs[DC0h] = Regs[DB]; break; @@ -662,7 +647,6 @@ 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]); Regs[DB] = ReadHardware(Regs[IO]); break; @@ -779,6 +763,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF ser.BeginSection(nameof(F3850)); ser.Sync(nameof(Regs), ref Regs, false); ser.Sync(nameof(cur_instr), ref cur_instr, false); + ser.Sync(nameof(instr_pntr), ref instr_pntr); ser.EndSection(); } }