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();
}
}