F8: some fixes

This commit is contained in:
Asnivor 2019-04-25 23:52:35 +01:00
parent 7d961d85bd
commit 74c6d33f16
9 changed files with 717 additions and 584 deletions

View File

@ -605,10 +605,10 @@
<Compile Include="Consoles\Fairchild\ChannelF\ChannelF.IEmulator.cs" />
<Compile Include="Consoles\Fairchild\ChannelF\ChannelF.IVideoProvider.cs" />
<Compile Include="Consoles\Fairchild\ChannelF\ChannelF.cs" />
<Compile Include="Consoles\Fairchild\ChannelF\F8\F3850.ALU.cs" />
<Compile Include="Consoles\Fairchild\ChannelF\F8\F3850.Disassembler.cs" />
<Compile Include="Consoles\Fairchild\ChannelF\F8\F3850.Tables.cs" />
<Compile Include="Consoles\Fairchild\ChannelF\F8\F3850.Registers.cs" />
<Compile Include="Consoles\Fairchild\ChannelF\F8\F3850.Operations.cs" />
<Compile Include="Consoles\Fairchild\ChannelF\F8\F3850.Execute.cs" />
<Compile Include="Consoles\Fairchild\ChannelF\F8\F3850.cs" />
<Compile Include="Consoles\GCE\Vectrex\Audio.cs" />

View File

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

View File

@ -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;

View File

@ -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
{
/// <summary>
/// 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
/// </summary>
public sealed partial class F3850
{
/// <summary>
/// Clears all status flags (excluding the ICB flag)
/// </summary>
public void ALU_ClearFlags()
{
FlagC = false;
FlagO = false;
FlagS = false;
FlagZ = false;
}
/// <summary>
/// Sets the SIGN and ZERO flags based on the supplied byte
/// </summary>
/// <param name="val"></param>
public void ALU_SetFlags_SZ(ushort src)
{
FlagZ = (byte)Regs[src] == 0;
FlagS = (~((byte)Regs[src]) & 0x80) != 0;
}
/// <summary>
/// Performs addition and sets the CARRY and OVERFLOW flags accordingly
/// </summary>
/// <param name="dest"></param>
/// <param name="src"></param>
/// <param name="carry"></param>
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);
}
/// <summary>
/// Performs addition and sets the CARRY and OVERFLOW flags accordingly WITHOUT saving to destination
/// </summary>
/// <param name="dest"></param>
/// <param name="src"></param>
/// <param name="carry"></param>
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;
}
/// <summary>
/// Performs decimal addition based on the two supplied bytes
/// (looks like this is only used in the AMD operation)
/// </summary>
/// <param name="dest"></param>
/// <param name="src"></param>
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;
}
*/
/// <summary>
/// Right shift 'src' 'shift' positions (zero fill)
/// </summary>
/// <param name="src"></param>
/// <param name="shift"></param>
public void ALU_SR_Func(ushort src, ushort shift)
{
Regs[src] = (ushort)((Regs[src] >> shift) & 0xFF);
ALU_ClearFlags();
ALU_SetFlags_SZ(src);
}
/// <summary>
/// Left shit 'src' 'shift' positions (zero fill)
/// </summary>
/// <param name="src"></param>
/// <param name="shift"></param>
public void ALU_SL_Func(ushort src, ushort shift)
{
Regs[src] = (ushort)((Regs[src] << shift) & 0xFF);
ALU_ClearFlags();
ALU_SetFlags_SZ(src);
}
/// <summary>
/// AND
/// </summary>
/// <param name="dest"></param>
/// <param name="src"></param>
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;
}
*/
}
}

View File

@ -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

View File

@ -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];
}
}
}

View File

@ -69,23 +69,31 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
/// <summary>
/// Temporary Arithmetic Storage
/// </summary>
public ushort ALU = 74;
public ushort ALU0 = 74;
/// <summary>
/// Temporary Arithmetic Storage
/// </summary>
public ushort ALU1 = 75;
/// <summary>
/// Data Bus
/// </summary>
public ushort DB = 75;
public ushort DB = 76;
/// <summary>
/// IO Bus/Latch
/// </summary>
public ushort IO = 76;
public ushort IO = 77;
/// <summary>
/// 0x00 value for arithmetic ops
/// </summary>
public ushort ZERO = 77;
public ushort ZERO = 78;
/// <summary>
/// 0xff value for arithmetic ops
/// 0x01 value for arithmetic ops
/// </summary>
public ushort ONE = 78;
public ushort ONE = 79;
/// <summary>
/// 0xFF value for arithmetic ops
/// </summary>
public ushort BYTE = 80;
/// <summary>
@ -180,6 +188,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
}
Regs[ONE] = 1;
Regs[BYTE] = 0xFF;
}
}
}

View File

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

View File

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