ChannelF: Some progress

This commit is contained in:
Asnivor 2019-04-17 22:28:12 +01:00
parent f0384b7e83
commit 6214de366b
13 changed files with 2084 additions and 233 deletions

View File

@ -595,6 +595,7 @@
</Compile> </Compile>
<Compile Include="Consoles\Belogic\LibUzem.cs" /> <Compile Include="Consoles\Belogic\LibUzem.cs" />
<Compile Include="Consoles\Belogic\Uzem.cs" /> <Compile Include="Consoles\Belogic\Uzem.cs" />
<Compile Include="Consoles\Fairchild\ChannelF\ChannelF.IDebuggable.cs" />
<Compile Include="Consoles\Fairchild\ChannelF\ChannelF.IO.cs" /> <Compile Include="Consoles\Fairchild\ChannelF\ChannelF.IO.cs" />
<Compile Include="Consoles\Fairchild\ChannelF\ChannelF.MemoryDomains.cs" /> <Compile Include="Consoles\Fairchild\ChannelF\ChannelF.MemoryDomains.cs" />
<Compile Include="Consoles\Fairchild\ChannelF\ChannelF.IStatable.cs" /> <Compile Include="Consoles\Fairchild\ChannelF\ChannelF.IStatable.cs" />

View File

@ -0,0 +1,113 @@
using System;
using System.Collections.Generic;
using BizHawk.Common.BufferExtensions;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Consoles.ChannelF
{
public partial class ChannelF : IDebuggable
{
public IDictionary<string, RegisterValue> GetCpuFlagsAndRegisters()
{
var res = new Dictionary<string, RegisterValue>
{
["A"] = CPU.Regs[CPU.A],
["W"] = CPU.Regs[CPU.W],
["ISAR"] = CPU.Regs[CPU.ISAR],
["PC0"] = CPU.RegPC0,
["PC1"] = CPU.RegPC1,
["DC0"] = CPU.RegDC0,
["DB"] = CPU.Regs[CPU.DB],
["IO"] = CPU.Regs[CPU.IO],
["J"] = CPU.Regs[CPU.J],
["H"] = CPU.Regs[CPU.Hl] + (CPU.Regs[CPU.Hh] << 8),
["K"] = CPU.Regs[CPU.Kl] + (CPU.Regs[CPU.Kh] << 8),
["Q"] = CPU.Regs[CPU.Ql] + (CPU.Regs[CPU.Qh] << 8),
["Flag C"] = CPU.FlagC,
["Flag O"] = CPU.FlagO,
["Flag Z"] = CPU.FlagZ,
["Flag S"] = CPU.FlagS,
["Flag I"] = CPU.FlagICB
};
for (int i = 0; i < 64; i++)
{
res.Add("SPR" + i, CPU.Regs[i]);
}
return res;
}
public void SetCpuRegister(string register, int value)
{
if (register.StartsWith("SPR"))
{
var reg = Convert.ToInt32(register.Replace("SPR", ""));
if (reg > 63)
throw new InvalidOperationException();
CPU.Regs[reg] = (ushort) value;
}
else
{
switch (register)
{
default:
throw new InvalidOperationException();
case "A":
CPU.Regs[CPU.A] = (ushort)value;
break;
case "W":
CPU.Regs[CPU.W] = (ushort)value;
break;
case "ISAR":
CPU.Regs[CPU.ISAR] = (ushort)(value & 0x3F);
break;
case "PC0":
CPU.RegPC0 = (ushort)value;
break;
case "PC1":
CPU.RegPC1 = (ushort)value;
break;
case "DC0":
CPU.RegDC0 = (ushort)value;
break;
case "DB":
CPU.Regs[CPU.DB] = (ushort)value;
break;
case "IO":
CPU.Regs[CPU.IO] = (ushort)value;
break;
case "J":
CPU.Regs[CPU.J] = (ushort)value;
break;
case "H":
CPU.Regs[CPU.Hl] = (ushort)(value & 0xFF);
CPU.Regs[CPU.Hh] = (ushort)(value & 0xFF00);
break;
case "K":
CPU.Regs[CPU.Kl] = (ushort)(value & 0xFF);
CPU.Regs[CPU.Kh] = (ushort)(value & 0xFF00);
break;
case "Q":
CPU.Regs[CPU.Ql] = (ushort)(value & 0xFF);
CPU.Regs[CPU.Qh] = (ushort)(value & 0xFF00);
break;
}
}
}
public IMemoryCallbackSystem MemoryCallbacks { get; }
public bool CanStep(StepType type) => false;
[FeatureNotImplemented]
public void Step(StepType type)
{
throw new NotImplementedException();
}
public long TotalExecutedCycles => CPU.TotalExecutedCycles;
}
}

View File

@ -28,6 +28,15 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
public bool FrameAdvance(IController controller, bool render, bool renderSound) public bool FrameAdvance(IController controller, bool render, bool renderSound)
{ {
if (_tracer.Enabled)
{
CPU.TraceCallback = s => _tracer.Put(s);
}
else
{
CPU.TraceCallback = null;
}
while (FrameClock++ < ClockPerFrame) while (FrameClock++ < ClockPerFrame)
{ {
CPU.ExecuteOne(); CPU.ExecuteOne();

View File

@ -14,6 +14,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
public byte[] Cartridge = new byte[0x2000 - 0x800]; public byte[] Cartridge = new byte[0x2000 - 0x800];
public byte[] PortLatch = new byte[64];
public byte ReadBus(ushort addr) public byte ReadBus(ushort addr)
{ {
if (addr < 0x400) if (addr < 0x400)
@ -69,12 +71,12 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
public byte ReadPort(ushort addr) public byte ReadPort(ushort addr)
{ {
return 0xff; return 0x00;
} }
public void WritePort(ushort addr, byte value) public void WritePort(ushort addr, byte value)
{ {
var port = addr & 0x7;
} }
} }
} }

View File

@ -4,7 +4,7 @@ using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Consoles.ChannelF namespace BizHawk.Emulation.Cores.Consoles.ChannelF
{ {
public partial class ChannelF : IVideoProvider public partial class ChannelF : IVideoProvider, IRegionable
{ {
public int _frameHz = 60; public int _frameHz = 60;
@ -22,5 +22,12 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
public int BackgroundColor => unchecked((int)0xFF000000); public int BackgroundColor => unchecked((int)0xFF000000);
public int VsyncNumerator => _frameHz; public int VsyncNumerator => _frameHz;
public int VsyncDenominator => 1; public int VsyncDenominator => 1;
#region IRegionable
public DisplayType Region => DisplayType.NTSC;
#endregion
} }
} }

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using BizHawk.Common.BufferExtensions; using BizHawk.Common.BufferExtensions;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
@ -13,12 +14,42 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
private void SetupMemoryDomains() private void SetupMemoryDomains()
{ {
var domains = new List<MemoryDomain>
{
new MemoryDomainDelegate("System Bus", 0x10000, MemoryDomain.Endian.Big,
(addr) =>
{
if (addr < 0 || addr >= 65536)
{
throw new ArgumentOutOfRangeException();
}
return ReadBus((ushort)addr);
},
(addr, value) =>
{
if (addr < 0 || addr >= 65536)
{
throw new ArgumentOutOfRangeException();
}
WriteBus((ushort)addr, value);
}, 1)
};
SyncAllByteArrayDomains();
memoryDomains = new MemoryDomainList(_byteArrayDomains.Values.Concat(domains).ToList());
(ServiceProvider as BasicServiceProvider)?.Register<IMemoryDomains>(memoryDomains);
_memoryDomainsInit = true;
} }
private void SyncAllByteArrayDomains() private void SyncAllByteArrayDomains()
{ {
SyncByteArrayDomain("BIOS1", BIOS01);
SyncByteArrayDomain("BIOS2", BIOS02);
SyncByteArrayDomain("ROM", Cartridge);
SyncByteArrayDomain("VRAM", FrameBuffer);
} }
private void SyncByteArrayDomain(string name, byte[] data) private void SyncByteArrayDomain(string name, byte[] data)
@ -30,7 +61,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
} }
else else
{ {
var m = new MemoryDomainByteArray(name, MemoryDomain.Endian.Little, data, true, 1); var m = new MemoryDomainByteArray(name, MemoryDomain.Endian.Big, data, false, 1);
_byteArrayDomains.Add(name, m); _byteArrayDomains.Add(name, m);
} }
} }

View File

@ -18,6 +18,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
ServiceProvider = ser; ServiceProvider = ser;
CoreComm = comm; CoreComm = comm;
InputCallbacks = new InputCallbackSystem(); InputCallbacks = new InputCallbackSystem();
MemoryCallbacks = new MemoryCallbackSystem(new[] { "System Bus" });
ControllerDefinition = ChannelFControllerDefinition; ControllerDefinition = ChannelFControllerDefinition;
@ -30,6 +31,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
DummyReadMemory = ReadBus DummyReadMemory = ReadBus
}; };
_tracer = new TraceBuffer { Header = CPU.TraceHeader };
byte[] bios01 = comm.CoreFileProvider.GetFirmware("ChannelF", "ChannelF_sl131253", true); byte[] bios01 = comm.CoreFileProvider.GetFirmware("ChannelF", "ChannelF_sl131253", true);
byte[] bios02 = comm.CoreFileProvider.GetFirmware("ChannelF", "ChannelF_sl131254", true); byte[] bios02 = comm.CoreFileProvider.GetFirmware("ChannelF", "ChannelF_sl131254", true);
@ -41,8 +44,13 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
CalcClock(); CalcClock();
ser.Register<IVideoProvider>(this); ser.Register<IVideoProvider>(this);
ser.Register<ITraceable>(_tracer);
ser.Register<IDisassemblable>(CPU);
SetupMemoryDomains();
} }
public F3850 CPU; public F3850 CPU;
private readonly TraceBuffer _tracer;
} }
} }

View File

@ -13,10 +13,309 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
/// </summary> /// </summary>
public sealed partial class F3850 : IDisassemblable public sealed partial class F3850 : IDisassemblable
{ {
static string Result(string format, Func<ushort, byte> read, ref ushort addr)
{
//d immediately succeeds the opcode
//n immediate succeeds the opcode and the displacement (if present)
//nn immediately succeeds the opcode and the displacement (if present)
if (format.IndexOf("nn") != -1) format = format.Replace("nn", $"{read(addr++) << 8 + (read(addr++)):X4}h"); // MSB is read first
if (format.IndexOf("n") != -1) format = format.Replace("n", $"{read(addr++):X2}h");
if (format.IndexOf("+d") != -1) format = format.Replace("+d", "d");
if (format.IndexOf("d") != -1)
{
var b = unchecked((sbyte)read(addr++));
format = format.Replace("d", $"{(b < 0 ? '-' : '+')}{(b < 0 ? -b : b):X2}h");
}
return format;
}
readonly static string[] mnemonics = new string[]
{
"LR A, KU", // 0x00
"LR A, KL", // 0x01
"LR A, QU", // 0x02
"LR A, QL", // 0x03
"LR KU, A", // 0x04
"LR KL, A", // 0x05
"LR QU, A", // 0x06
"LR QL, A", // 0x07
"LR K, P", // 0x08
"LR P, K", // 0x09
"LR A, IS", // 0x0A
"LR IS, A", // 0x0B
"PK", // 0x0C
"LR P0, Q", // 0x0D
"LR Q, DC", // 0x0E
"LR DC, Q", // 0x0F
"LR DC, H", // 0x10
"LR H, DC", // 0x11
"SR 1", // 0x12
"SL 1", // 0x13
"SR 4", // 0x14
"SL 4", // 0x15
"LM", // 0x16
"ST", // 0x17
"COM", // 0x18
"LNK", // 0x19
"DI", // 0x1A
"EI", // 0x1B
"POP", // 0x1C
"LR W, J", // 0x1D
"LR J, W", // 0x1E
"INC", // 0x1F
"LI n", // 0x20
"NI n", // 0x21
"IO n", // 0x22
"XI n", // 0x23
"AI n", // 0x24
"CI n", // 0x25
"IN n", // 0x26
"OUT n", // 0x27
"PI nn", // 0x28
"JMP nn", // 0x29
"DCI nn", // 0x2A
"NOP", // 0x2B
"XDC", // 0x2C
"ILLEGAL", // 0x2D
"ILLEGAL", // 0x2E
"ILLEGAL", // 0x2F
"DS r00", // 0x30
"DS r01", // 0x31
"DS r02", // 0x32
"DS r03", // 0x33
"DS r04", // 0x34
"DS r05", // 0x35
"DS r06", // 0x36
"DS r07", // 0x37
"DS r08", // 0x38
"DS r09", // 0x39
"DS r10", // 0x3A
"DS r11", // 0x3B
"DS ISAR", // 0x3C
"DS ISAR INC", // 0x3D
"DS ISAR DEC", // 0x3E
"ILLEGAL", // 0x3F
"LR A, r00", // 0x40
"LR A, r01", // 0x41
"LR A, r02", // 0x42
"LR A, r03", // 0x43
"LR A, r04", // 0x44
"LR A, r05", // 0x45
"LR A, r06", // 0x46
"LR A, r07", // 0x47
"LR A, r08", // 0x48
"LR A, r09", // 0x49
"LR A, r10", // 0x4A
"LR A, r11", // 0x4B
"LR A, ISAR", // 0x4C
"LR A, ISAR INC", // 0x4D
"LR A, ISAR DEC", // 0x4E
"ILLEGAL", // 0x4F
"LR r00, A", // 0x50
"LR r01, A", // 0x51
"LR r02, A", // 0x52
"LR r03, A", // 0x53
"LR r04, A", // 0x54
"LR r05, A", // 0x55
"LR r06, A", // 0x56
"LR r07, A", // 0x57
"LR r08, A", // 0x58
"LR r09, A", // 0x59
"LR r10, A", // 0x5A
"LR r11, A", // 0x5B
"LR ((ISAR)), A", // 0x5C
"LR (ISAR), A INC", // 0x5D
"LR (ISAR), A DEC", // 0x5E
"ILLEGAL", // 0x5F
"LISU 0x00", // 0x60
"LISU 0x08", // 0x61
"LISU 0x10", // 0x62
"LISU 0x18", // 0x63
"LISU 0x20", // 0x64
"LISU 0x28", // 0x65
"LISU 0x30", // 0x66
"LISU 0x38", // 0x67
"LISU 0x00", // 0x68
"LISU 0x01", // 0x69
"LISU 0x02", // 0x6A
"LISU 0x03", // 0x6B
"LISU 0x04", // 0x6C
"LISU 0x05", // 0x6D
"LISU 0x06", // 0x6E
"LISU 0x07", // 0x6F
"LIS 0x0", // 0x70
"LIS 0x01", // 0x71
"LIS 0x2", // 0x72
"LIS 0x3", // 0x73
"LIS 0x4", // 0x74
"LIS 0x5", // 0x75
"LIS 0x6", // 0x76
"LIS 0x7", // 0x77
"LIS 0x8", // 0x78
"LIS 0x9", // 0x79
"LIS 0xA", // 0x7A
"LIS 0xB", // 0x7B
"LIS 0xC", // 0x7C
"LIS 0xD", // 0x7D
"LIS 0xE", // 0x7E
"LIS 0xF", // 0x7F
"BT 0", // 0x80
"BT 1", // 0x81
"BT 2", // 0x82
"BT 3", // 0x83
"BT 4", // 0x84
"BT 5", // 0x85
"BT 6", // 0x86
"BT 7", // 0x87
"AM", // 0x88
"AMD", // 0x89
"NM", // 0x8A
"OM", // 0x8B
"XM", // 0x8C
"CM", // 0x8D
"ADC", // 0x8E
"BR7 n", // 0x8F
"BF 0x0 n", // 0x90
"BF 0x1 n", // 0x91
"BF 0x2 n", // 0x92
"BF 0x3 n", // 0x93
"BF 0x4 n", // 0x94
"BF 0x5 n", // 0x95
"BF 0x6 n", // 0x96
"BF 0x7 n", // 0x97
"BF 0x8 n", // 0x98
"BF 0x9 n", // 0x99
"BF 0xA n", // 0x9A
"BF 0xB n", // 0x9B
"BF 0xC n", // 0x9C
"BF 0xD n", // 0x9D
"BF 0xE n", // 0x9E
"BF 0xF n", // 0x9F
"INS 0", // 0xA0
"INS 1", // 0xA1
"ILLEGAL", // 0xA2
"ILLEGAL", // 0xA3
"INS 4", // 0xA4
"INS 5", // 0xA5
"INS 6", // 0xA6
"INS 7", // 0xA7
"INS 8", // 0xA8
"INS 9", // 0xA9
"INS 10", // 0xAA
"INS 11", // 0xAB
"INS 12", // 0xAC
"INS 13", // 0xAD
"INS 14", // 0xAE
"INS 16", // 0xAF
"OUTS 0", // 0xB0
"OUTS 1", // 0xB1
"ILLEGAL", // 0xB2
"ILLEGAL", // 0xB3
"OUTS 4", // 0xB4
"OUTS 5", // 0xB5
"OUTS 6", // 0xB6
"OUTS 7", // 0xB7
"OUTS 8", // 0xB8
"OUTS 9", // 0xB9
"OUTS 10", // 0xBA
"OUTS 11", // 0xBB
"OUTS 12", // 0xBC
"OUTS 13", // 0xBD
"OUTS 14", // 0xBE
"OUTS 15", // 0xBF
"AS r00", // 0xC0
"AS r01", // 0xC1
"AS r02", // 0xC2
"AS r03", // 0xC3
"AS r04", // 0xC4
"AS r05", // 0xC5
"AS r06", // 0xC6
"AS r07", // 0xC7
"AS r08", // 0xC8
"AS r09", // 0xC9
"AS r10", // 0xCA
"AS r11", // 0xCB
"AS ISAR", // 0xCC
"AS ISAR INC", // 0xCD
"AS ISAR DEC", // 0xCE
"ILLEGAL", // 0xCF
"ASD r00", // 0xD0
"ASD r01", // 0xD1
"ASD r02", // 0xD2
"ASD r03", // 0xD3
"ASD r04", // 0xD4
"ASD r05", // 0xD5
"ASD r06", // 0xD6
"ASD r07", // 0xD7
"ASD r08", // 0xD8
"ASD r09", // 0xD9
"ASD r10", // 0xDA
"ASD r11", // 0xDB
"ASD ISAR", // 0xDC
"ASD ISAR INC", // 0xDD
"ASD ISAR DEC", // 0xDE
"ILLEGAL", // 0xDF
"XS r00", // 0xE0
"XS r01", // 0xE1
"XS r02", // 0xE2
"XS r03", // 0xE3
"XS r04", // 0xE4
"XS r05", // 0xE5
"XS r06", // 0xE6
"XS r07", // 0xE7
"XS r08", // 0xE8
"XS r09", // 0xE9
"XS r10", // 0xEA
"XS r11", // 0xEB
"XS ISAR", // 0xEC
"XS ISAR INC", // 0xED
"XS ISAR DEC", // 0xEE
"ILLEGAL", // 0xEF
"NS r00", // 0xF0
"NS r01", // 0xF1
"NS r02", // 0xF2
"NS r03", // 0xF3
"NS r04", // 0xF4
"NS r05", // 0xF5
"NS r06", // 0xF6
"NS r07", // 0xF7
"NS r08", // 0xF8
"NS r09", // 0xF9
"NS r10", // 0xFA
"NS r11", // 0xFB
"NS ISAR", // 0xFC
"NS ISAR INC", // 0xFD
"NS ISAR DEC", // 0xFE
"ILLEGAL", // 0xFF
};
public string Disassemble(ushort addr, Func<ushort, byte> read, out int size)
{
ushort start_addr = addr;
ushort extra_inc = 0;
byte A = read(addr++);
string format;
format = mnemonics[A];
string temp = Result(format, read, ref addr);
size = addr - start_addr;
if (addr < start_addr)
{
size = (0x10000 + addr) - start_addr;
}
return temp;
}
#region IDisassemblable #region IDisassemblable
#endregion
public string Cpu public string Cpu
{ {
get { return "F3850"; } get { return "F3850"; }
@ -35,11 +334,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
public string Disassemble(MemoryDomain m, uint addr, out int length) public string Disassemble(MemoryDomain m, uint addr, out int length)
{ {
length = 0; string ret = Disassemble((ushort)addr, a => m.PeekByte(a), out length);
string ret = "";// Disassemble((ushort)addr, a => m.PeekByte(a), out length);
return ret; return ret;
} }
#endregion
} }
} }

View File

@ -18,8 +18,6 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
public ushort[] cur_instr = new ushort[MaxInstructionLength]; // fixed size - do not change at runtime public ushort[] cur_instr = new ushort[MaxInstructionLength]; // fixed size - do not change at runtime
public ushort[] cur_romc = new ushort[MaxInstructionLength]; // fixed size - do not change at runtime public ushort[] cur_romc = new ushort[MaxInstructionLength]; // fixed size - do not change at runtime
public byte opcode; public byte opcode;
public byte databus;
public ushort iobus;
public void FetchInstruction() public void FetchInstruction()
{ {
@ -49,19 +47,240 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
case 0x15: SHIFT_L(4); break; // Shift (A) left four bit positions (zero fill) case 0x15: SHIFT_L(4); break; // Shift (A) left four bit positions (zero fill)
case 0x16: LM(); break; // A <- ((DC0)) case 0x16: LM(); break; // A <- ((DC0))
case 0x17: ST(); break; // (DC) <- (A) case 0x17: ST(); break; // (DC) <- (A)
case 0x18: COM(); break; // A <- A ^ 255 case 0x18: COM(); break; // A <- A XOR 255 (complement A)
case 0x1A: DI(); break; // Clear ICB case 0x1A: DI(); break; // Clear ICB
case 0x1B: EI(); break; // Set ICB case 0x1B: EI(); break; // Set ICB
case 0x1C: POP(); break; // PC0 <- PC1 case 0x1C: POP(); break; // PC0 <- PC1
case 0x1D: LR_W_J(); break; // W <- (r9) case 0x1D: LR_W_J(); break; // W <- (r9)
case 0x1E: LR_J_W(); break; // r9 <- (W) case 0x1E: LR_J_W(); break; // r9 <- (W)
case 0x1F: INC(); break; // A <- (A) + 1 case 0x1F: INC(); break; // A <- (A) + 1
case 0x20: LI(); break; // A <- H'aa'
case 0x21: NI(); break; // A <- (A) AND H'aa'
case 0x22: OI(); break; // A <- (A) OR H'aa'
case 0x23: XI(); break; // A <- (A) XOR H'aa'
case 0x24: AI(); break; // A <- (A) + H'aa'
case 0x25: CI(); break; // H'aa' + (A) + 1 (modify flags without saving result)
case 0x26: IN(); break; // DB <- PP; A <- (I/O Port PP)
case 0x27: OUT(); break; // DB <- PP; I/O Port PP <- (A)
case 0x28: PI(); break; // A <- H'ii'; PC1 <- (PC0) + 1; PC0l <- H'jj'; PC0h <- (A)
case 0x29: JMP(); break; // A <- H'ii'; PC0l <- H'jj'; PC0h <- (A)
case 0x2A: DCI(); break; // DC0h <- ii; increment PC0; DC0l <- jj; increment PC0
case 0x2B: NOP(); break; // No operation (4 cycles - fetch next opcode)
case 0x2C: XDC(); break; // DC0 <-> DC1
case 0x30: DS(0); break; // SR <- (SR) + H'FF'
case 0x31: DS(1); break; // SR <- (SR) + H'FF'
case 0x32: DS(2); break; // SR <- (SR) + H'FF'
case 0x33: DS(3); break; // SR <- (SR) + H'FF'
case 0x34: DS(4); break; // SR <- (SR) + H'FF'
case 0x35: DS(5); break; // SR <- (SR) + H'FF'
case 0x36: DS(6); break; // SR <- (SR) + H'FF'
case 0x37: DS(7); break; // SR <- (SR) + H'FF'
case 0x38: DS(8); break; // SR <- (SR) + H'FF'
case 0x39: DS(9); break; // SR <- (SR) + H'FF'
case 0x3A: DS(10); break; // SR <- (SR) + H'FF'
case 0x3B: DS(11); break; // SR <- (SR) + H'FF'
case 0x3C: DS_ISAR(); break; // SR <- (SR) + H'FF' (SR pointed to by the ISAR)
case 0x3D: DS_ISAR_INC(); break; // SR <- (SR) + H'FF' (SR pointed to by the ISAR); ISAR incremented
case 0x3E: DS_ISAR_DEC(); break; // SR <- (SR) + H'FF' (SR pointed to by the ISAR); ISAR decremented
case 0x40: LR_A_R(0); break; // A <- (SR)
case 0x41: LR_A_R(1); break; // A <- (SR)
case 0x42: LR_A_R(2); break; // A <- (SR)
case 0x43: LR_A_R(3); break; // A <- (SR)
case 0x44: LR_A_R(4); break; // A <- (SR)
case 0x45: LR_A_R(5); break; // A <- (SR)
case 0x46: LR_A_R(6); break; // A <- (SR)
case 0x47: LR_A_R(7); break; // A <- (SR)
case 0x48: LR_A_R(8); break; // A <- (SR)
case 0x49: LR_A_R(9); break; // A <- (SR)
case 0x4A: LR_A_R(10); break; // A <- (SR)
case 0x4B: LR_A_R(11); break; // A <- (SR)
case 0x4C: LR_A_ISAR(); break; // A <- (SR) (SR pointed to by the ISAR)
case 0x4D: LR_A_ISAR_INC(); break; // A <- (SR) (SR pointed to by the ISAR); ISAR incremented
case 0x4E: LR_A_ISAR_DEC(); break; // A <- (SR) (SR pointed to by the ISAR); ISAR decremented
case 0x50: LR_R_A(0); break; // SR <- (A)
case 0x51: LR_R_A(1); break; // SR <- (A)
case 0x52: LR_R_A(2); break; // SR <- (A)
case 0x53: LR_R_A(3); break; // SR <- (A)
case 0x54: LR_R_A(4); break; // SR <- (A)
case 0x55: LR_R_A(5); break; // SR <- (A)
case 0x56: LR_R_A(6); break; // SR <- (A)
case 0x57: LR_R_A(7); break; // SR <- (A)
case 0x58: LR_R_A(8); break; // SR <- (A)
case 0x59: LR_R_A(9); break; // SR <- (A)
case 0x5A: LR_R_A(10); break; // SR <- (A)
case 0x5B: LR_R_A(11); break; // SR <- (A)
case 0x5C: LR_ISAR_A(); break; // SR <- (A) (SR pointed to by the ISAR)
case 0x5D: LR_ISAR_A_INC(); break; // SR <- (A) (SR pointed to by the ISAR); ISAR incremented
case 0x5E: LR_ISAR_A_DEC(); break; // SR <- (A) (SR pointed to by the ISAR); ISAR decremented
case 0x60: LISU(0); break; // ISARU <- 0'e' (octal)
case 0x61: LISU(8); break; // ISARU <- 0'e' (octal)
case 0x62: LISU(16); break; // ISARU <- 0'e' (octal)
case 0x63: LISU(24); break; // ISARU <- 0'e' (octal)
case 0x64: LISU(32); break; // ISARU <- 0'e' (octal)
case 0x65: LISU(40); break; // ISARU <- 0'e' (octal)
case 0x66: LISU(48); break; // ISARU <- 0'e' (octal)
case 0x67: LISU(56); break; // ISARU <- 0'e' (octal)
case 0x68: LISL(0); break; // ISARL <- 0'e' (octal)
case 0x69: LISL(1); break; // ISARL <- 0'e' (octal)
case 0x6A: LISL(2); break; // ISARL <- 0'e' (octal)
case 0x6B: LISL(3); break; // ISARL <- 0'e' (octal)
case 0x6C: LISL(4); break; // ISARL <- 0'e' (octal)
case 0x6D: LISL(5); break; // ISARL <- 0'e' (octal)
case 0x6E: LISL(6); break; // ISARL <- 0'e' (octal)
case 0x6F: LISL(7); break; // ISARL <- 0'e' (octal)
case 0x70: LIS(0); break; // A <- H'0a'
case 0x71: LIS(1); break; // A <- H'0a'
case 0x72: LIS(2); break; // A <- H'0a'
case 0x73: LIS(3); break; // A <- H'0a'
case 0x74: LIS(4); break; // A <- H'0a'
case 0x75: LIS(5); break; // A <- H'0a'
case 0x76: LIS(6); break; // A <- H'0a'
case 0x77: LIS(7); break; // A <- H'0a'
case 0x78: LIS(8); break; // A <- H'0a'
case 0x79: LIS(9); break; // A <- H'0a'
case 0x7a: LIS(10); break; // A <- H'0a'
case 0x7b: LIS(11); break; // A <- H'0a'
case 0x7c: LIS(12); break; // A <- H'0a'
case 0x7d: LIS(13); break; // A <- H'0a'
case 0x7e: LIS(14); break; // A <- H'0a'
case 0x7f: LIS(15); break; // A <- H'0a'
case 0x80: BT(0); break; // Test operand against W (Branching instruction)
case 0x81: BT(1); break; // Test operand against W (Branching instruction)
case 0x82: BT(2); break; // Test operand against W (Branching instruction)
case 0x83: BT(3); break; // Test operand against W (Branching instruction)
case 0x84: BT(4); break; // Test operand against W (Branching instruction)
case 0x85: BT(5); break; // Test operand against W (Branching instruction)
case 0x86: BT(6); break; // Test operand against W (Branching instruction)
case 0x87: BT(7); break; // Test operand against W (Branching instruction)
case 0x88: AM(); break; // A <- (A) + ((DC0))Binary; DC0 <- (DC0) + 1
case 0x89: AMD(); break; // A <- (A) + ((DC0))Decimal; DC0 <- (DC0) + 1
case 0x8A: NM(); break; // A <- (A) AND ((DC0)); DC0 <- (DC0) + 1
case 0x8B: OM(); break; // A <- (A) OR ((DC0)); DC0 <- (DC0) + 1
case 0x8C: XM(); break; // A <- (A) XOR ((DC0)); DC0 <- (DC0) + 1
case 0x8D: CM(); break; // Set status flags on basis of: ((DC)) + (A) + 1; DC0 <- (DC0) + 1; DC <- (DC) + (A)
case 0x8E: ADC(); break; // DC <- (DC) + (A)
case 0x8F: BR7(); break; // DC <- (DC) + (A)
case 0x90: BF(0); break; // PC0 <- PC0+n+1
case 0x91: BF(1); break; // PC0 <- PC0+n+1
case 0x92: BF(2); break; // PC0 <- PC0+n+1
case 0x93: BF(3); break; // PC0 <- PC0+n+1
case 0x94: BF(4); break; // PC0 <- PC0+n+1
case 0x95: BF(5); break; // PC0 <- PC0+n+1
case 0x96: BF(6); break; // PC0 <- PC0+n+1
case 0x97: BF(7); break; // PC0 <- PC0+n+1
case 0x98: BF(8); break; // PC0 <- PC0+n+1
case 0x99: BF(9); break; // PC0 <- PC0+n+1
case 0x9A: BF(10); break; // PC0 <- PC0+n+1
case 0x9B: BF(11); break; // PC0 <- PC0+n+1
case 0x9C: BF(12); break; // PC0 <- PC0+n+1
case 0x9D: BF(13); break; // PC0 <- PC0+n+1
case 0x9E: BF(14); break; // PC0 <- PC0+n+1
case 0x9F: BF(15); break; // PC0 <- PC0+n+1
case 0xA0: INS_0(0); break; // A <- (I/O Port 0 or 1)
case 0xA1: INS_0(1); break; // A <- (I/O Port 0 or 1)
case 0xA4: INS_1(4); break; // DB <- Port Address (4 thru 15)
case 0xA5: INS_1(5); break; // DB <- Port Address (4 thru 15)
case 0xA6: INS_1(6); break; // DB <- Port Address (4 thru 15)
case 0xA7: INS_1(7); break; // DB <- Port Address (4 thru 15)
case 0xA8: INS_1(8); break; // DB <- Port Address (4 thru 15)
case 0xA9: INS_1(9); break; // DB <- Port Address (4 thru 15)
case 0xAA: INS_1(10); break; // DB <- Port Address (4 thru 15)
case 0xAB: INS_1(11); break; // DB <- Port Address (4 thru 15)
case 0xAC: INS_1(12); break; // DB <- Port Address (4 thru 15)
case 0xAD: INS_1(13); break; // DB <- Port Address (4 thru 15)
case 0xAE: INS_1(14); break; // DB <- Port Address (4 thru 15)
case 0xAF: INS_1(15); break; // DB <- Port Address (4 thru 15)
case 0xB0: OUTS_0(0); break; // I/O Port 0 or 1 <- (A)
case 0xB1: OUTS_0(1); break; // I/O Port 0 or 1 <- (A)
case 0xB4: OUTS_1(4); break; // DB <- Port Address (4 thru 15)
case 0xB5: OUTS_1(5); break; // DB <- Port Address (4 thru 15)
case 0xB6: OUTS_1(6); break; // DB <- Port Address (4 thru 15)
case 0xB7: OUTS_1(7); break; // DB <- Port Address (4 thru 15)
case 0xB8: OUTS_1(8); break; // DB <- Port Address (4 thru 15)
case 0xB9: OUTS_1(9); break; // DB <- Port Address (4 thru 15)
case 0xBA: OUTS_1(10); break; // DB <- Port Address (4 thru 15)
case 0xBB: OUTS_1(11); break; // DB <- Port Address (4 thru 15)
case 0xBC: OUTS_1(12); break; // DB <- Port Address (4 thru 15)
case 0xBD: OUTS_1(13); break; // DB <- Port Address (4 thru 15)
case 0xBE: OUTS_1(14); break; // DB <- Port Address (4 thru 15)
case 0xBF: OUTS_1(15); break; // DB <- Port Address (4 thru 15)
case 0xC0: AS(0); break; // A <- (A) + (r) Binary
case 0xC1: AS(1); break; // A <- (A) + (r) Binary
case 0xC2: AS(2); break; // A <- (A) + (r) Binary
case 0xC3: AS(3); break; // A <- (A) + (r) Binary
case 0xC4: AS(4); break; // A <- (A) + (r) Binary
case 0xC5: AS(5); break; // A <- (A) + (r) Binary
case 0xC6: AS(6); break; // A <- (A) + (r) Binary
case 0xC7: AS(7); break; // A <- (A) + (r) Binary
case 0xC8: AS(8); break; // A <- (A) + (r) Binary
case 0xC9: AS(9); break; // A <- (A) + (r) Binary
case 0xCA: AS(10); break; // A <- (A) + (r) Binary
case 0xCB: AS(11); break; // A <- (A) + (r) Binary
case 0xCC: AS_IS(); break; // A <- (A) + (r addressed via ISAR) Binary
case 0xCD: AS_IS_INC(); break; // A <- (A) + (r addressed via ISAR) Binary; Increment ISAR
case 0xCE: AS_IS_DEC(); break; // A <- (A) + (r addressed via ISAR) Binary; Decrement ISAR
case 0xD0: ASD(0); break; // A <- (A) + (r) Decimal
case 0xD1: ASD(1); break; // A <- (A) + (r) Decimal
case 0xD2: ASD(2); break; // A <- (A) + (r) Decimal
case 0xD3: ASD(3); break; // A <- (A) + (r) Decimal
case 0xD4: ASD(4); break; // A <- (A) + (r) Decimal
case 0xD5: ASD(5); break; // A <- (A) + (r) Decimal
case 0xD6: ASD(6); break; // A <- (A) + (r) Decimal
case 0xD7: ASD(7); break; // A <- (A) + (r) Decimal
case 0xD8: ASD(8); break; // A <- (A) + (r) Decimal
case 0xD9: ASD(9); break; // A <- (A) + (r) Decimal
case 0xDA: ASD(10); break; // A <- (A) + (r) Decimal
case 0xDB: ASD(11); break; // A <- (A) + (r) Decimal
case 0xDC: ASD_IS(); break; // A <- (A) + (r addressed via ISAR) Decimal
case 0xDD: ASD_IS_INC(); break; // A <- (A) + (r addressed via ISAR) Decimal; Increment ISAR
case 0xDE: ASD_IS_DEC(); break; // A <- (A) + (r addressed via ISAR) Decimal; Decrement ISAR
case 0xE0: XS(0); break; // A <- (A) XOR (r)
case 0xE1: XS(1); break; // A <- (A) XOR (r)
case 0xE2: XS(2); break; // A <- (A) XOR (r)
case 0xE3: XS(3); break; // A <- (A) XOR (r)
case 0xE4: XS(4); break; // A <- (A) XOR (r)
case 0xE5: XS(5); break; // A <- (A) XOR (r)
case 0xE6: XS(6); break; // A <- (A) XOR (r)
case 0xE7: XS(7); break; // A <- (A) XOR (r)
case 0xE8: XS(8); break; // A <- (A) XOR (r)
case 0xE9: XS(9); break; // A <- (A) XOR (r)
case 0xEA: XS(10); break; // A <- (A) XOR (r)
case 0xEB: XS(11); break; // A <- (A) XOR (r)
case 0xEC: XS_IS(); break; // A <- (A) XOR (r addressed via ISAR)
case 0xED: XS_IS_INC(); break; // A <- (A) XOR (r addressed via ISAR); Increment ISAR
case 0xEE: XS_IS_DEC(); break; // A <- (A) XOR (r addressed via ISAR); Decrement ISAR
case 0xF0: NS(0); break; // A <- (A) XOR (r)
case 0xF1: NS(1); break; // A <- (A) XOR (r)
case 0xF2: NS(2); break; // A <- (A) XOR (r)
case 0xF3: NS(3); break; // A <- (A) XOR (r)
case 0xF4: NS(4); break; // A <- (A) XOR (r)
case 0xF5: NS(5); break; // A <- (A) XOR (r)
case 0xF6: NS(6); break; // A <- (A) XOR (r)
case 0xF7: NS(7); break; // A <- (A) XOR (r)
case 0xF8: NS(8); break; // A <- (A) XOR (r)
case 0xF9: NS(9); break; // A <- (A) XOR (r)
case 0xFA: NS(10); break; // A <- (A) XOR (r)
case 0xFB: NS(11); break; // A <- (A) XOR (r)
case 0xFC: NS_IS(); break; // A <- (A) XOR (r addressed via ISAR)
case 0xFD: NS_IS_INC(); break; // A <- (A) XOR (r addressed via ISAR); Increment ISAR
case 0xFE: NS_IS_DEC(); break; // A <- (A) XOR (r addressed via ISAR); Decrement ISAR
default: ILLEGAL(); break; // Illegal Opcode default: ILLEGAL(); break; // Illegal Opcode
} }
} }
} }
} }

View File

@ -11,6 +11,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
{ {
public sealed partial class F3850 public sealed partial class F3850
{ {
/*
private void IncrementBySignedByte(ushort dest, byte src) private void IncrementBySignedByte(ushort dest, byte src)
{ {
if (src >= 0x80) if (src >= 0x80)
@ -34,8 +35,9 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
dest += (byte)(src & 0x80); dest += (byte)(src & 0x80);
} }
} }
*/
public void LoadReg_Func(ushort dest, ushort src) public void LR8_Func(ushort dest, ushort src)
{ {
if (dest == DB) if (dest == DB)
{ {
@ -53,7 +55,31 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
} }
} }
public void ShiftRight_Func(ushort src, ushort index) 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
{
Regs[dest] = Regs[src];
}
// update flags
FlagO = false;
FlagC = false;
FlagZ = (Regs[dest] & 0xFF) == 0;
FlagS = Regs[dest] > 127;
}
public void SR_Func(ushort src, ushort index)
{ {
int shft = (Regs[src] >> index) & 0xFF; int shft = (Regs[src] >> index) & 0xFF;
FlagO = false; FlagO = false;
@ -63,7 +89,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
Regs[src] = (ushort)shft; Regs[src] = (ushort)shft;
} }
public void ShiftLeft_Func(ushort src, ushort index) public void SL_Func(ushort src, ushort index)
{ {
int shft = (Regs[src] << index) & 0xFF; int shft = (Regs[src] << index) & 0xFF;
FlagO = false; FlagO = false;
@ -73,17 +99,6 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
Regs[src] = (ushort)shft; Regs[src] = (ushort)shft;
} }
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 ADD8_Func(ushort dest, ushort src) public void ADD8_Func(ushort dest, ushort src)
{ {
int Reg16_d = Regs[dest]; int Reg16_d = Regs[dest];
@ -100,6 +115,104 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
Regs[dest] = ans; 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;
}
public void INC8_Func(ushort src) public void INC8_Func(ushort src)
{ {
int Reg16_d = Regs[src]; int Reg16_d = Regs[src];
@ -116,6 +229,74 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
FlagO = Regs[src] == 0x80; 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) public void Read_Func(ushort dest, ushort src)
{ {
Regs[dest] = Regs[src]; Regs[dest] = Regs[src];

View File

@ -14,127 +14,79 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
/// </summary> /// </summary>
public sealed partial class F3850 public sealed partial class F3850
{ {
/// <summary>
/// Accumulator
/// </summary>
public ushort A = 0;
/// <summary>
/// Status Register
/// </summary>
public ushort W = 1;
/// <summary>
/// Indirect Scratchpad Address Register
/// (6bit)
/// </summary>
public ushort ISAR = 2;
/// <summary>
/// Primary Program Counter (low byte)
/// </summary>
public ushort PC0l = 3;
/// <summary>
/// Primary Program Counter (high byte)
/// </summary>
public ushort PC0h = 4;
/// <summary>
/// Backup Program Counter (low byte)
/// </summary>
public ushort PC1l = 5;
/// <summary>
/// Backup Program Counter (high byte)
/// </summary>
public ushort PC1h = 6;
/// <summary>
/// Data Counter (low byte)
/// </summary>
public ushort DC0l = 7;
/// <summary>
/// Data counter (high byte)
/// </summary>
public ushort DC0h = 8;
/// <summary>
/// Temporary Arithmetic Storage
/// </summary>
public ushort ALU = 9;
/// <summary>
/// Data Bus
/// </summary>
public ushort DB = 10;
/// <summary>
/// IO Bus
/// </summary>
public ushort IO = 11;
/// <summary> /// <summary>
/// Registers (counters and scratchpad) /// Registers (counters and scratchpad)
/// </summary> /// </summary>
public ushort[] Regs = new ushort[100]; public ushort[] Regs = new ushort[100];
// scratchpad registers // scratchpad registers live in Regs 0-64
public ushort SR0 = 20; public ushort J = 9;
public ushort SR1 = 21; public ushort Hh = 10;
public ushort SR2 = 22; public ushort Hl = 11;
public ushort SR3 = 23; public ushort Kh = 12;
public ushort SR4 = 24; public ushort Kl = 13;
public ushort SR5 = 25; public ushort Qh = 14;
public ushort SR6 = 26; public ushort Ql = 15;
public ushort SR7 = 27;
public ushort SR8 = 28; // Internal CPU counters kept after the scratchpad for ease of implementation
public ushort SR9 = 29; /// <summary>
public ushort SR10 = 30; /// Accumulator
public ushort SR11 = 31; /// </summary>
public ushort SR12 = 32; public ushort A = 65;
public ushort SR13 = 33; /// <summary>
public ushort SR14 = 34; /// Status Register
public ushort SR15 = 35; /// </summary>
public ushort SR16 = 36; public ushort W = 66;
public ushort SR17 = 37; /// <summary>
public ushort SR18 = 38; /// Indirect Scratchpad Address Register
public ushort SR19 = 39; /// (6bit)
public ushort SR20 = 40; /// </summary>
public ushort SR21 = 41; public ushort ISAR = 67;
public ushort SR22 = 42; /// <summary>
public ushort SR23 = 43; /// Primary Program Counter (high byte)
public ushort SR24 = 44; /// </summary>
public ushort SR25 = 45; public ushort PC0h = 68;
public ushort SR26 = 46; /// <summary>
public ushort SR27 = 47; /// Primary Program Counter (low byte)
public ushort SR28 = 48; /// </summary>
public ushort SR29 = 49; public ushort PC0l = 69;
public ushort SR30 = 50; /// <summary>
public ushort SR31 = 51; /// Backup Program Counter (high byte)
public ushort SR32 = 52; /// </summary>
public ushort SR33 = 53; public ushort PC1h = 70;
public ushort SR34 = 54; /// <summary>
public ushort SR35 = 55; /// Backup Program Counter (low byte)
public ushort SR36 = 56; /// </summary>
public ushort SR37 = 57; public ushort PC1l = 71;
public ushort SR38 = 58; /// <summary>
public ushort SR39 = 59; /// Data counter (high byte)
public ushort SR40 = 60; /// </summary>
public ushort SR41 = 61; public ushort DC0h = 72;
public ushort SR42 = 62; /// <summary>
public ushort SR43 = 63; /// Data Counter (low byte)
public ushort SR44 = 64; /// </summary>
public ushort SR45 = 65; public ushort DC0l = 73;
public ushort SR46 = 66; /// <summary>
public ushort SR47 = 67; /// Temporary Arithmetic Storage
public ushort SR48 = 68; /// </summary>
public ushort SR49 = 69; public ushort ALU = 74;
public ushort SR50 = 70; /// <summary>
public ushort SR51 = 71; /// Data Bus
public ushort SR52 = 72; /// </summary>
public ushort SR53 = 73; public ushort DB = 75;
public ushort SR54 = 74; /// <summary>
public ushort SR55 = 75; /// IO Bus/Latch
public ushort SR56 = 76; /// </summary>
public ushort SR57 = 77; public ushort IO = 76;
public ushort SR58 = 78; /// <summary>
public ushort SR59 = 79; /// 0x00 value for arithmetic ops
public ushort SR60 = 80; /// </summary>
public ushort SR61 = 81; public ushort ZERO = 77;
public ushort SR62 = 82; /// <summary>
public ushort SR63 = 83; /// 0xff value for arithmetic ops
public ushort SR64 = 84; /// </summary>
public ushort BYTE = 78;
/// <summary> /// <summary>
/// Status Register - Sign Flag /// Status Register - Sign Flag
@ -226,6 +178,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
{ {
Regs[i] = 0; Regs[i] = 0;
} }
Regs[BYTE] = 0xff;
} }
} }
} }

View File

@ -16,7 +16,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
private void LR_A_KU() private void LR_A_KU()
{ {
PopulateCURINSTR( PopulateCURINSTR(
OP_LR_8, A, SR12, // S OP_LR8, A, Kh, // S
ROMC_00_S, ROMC_00_S,
IDLE, IDLE,
END); END);
@ -25,7 +25,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
private void LR_A_KL() private void LR_A_KL()
{ {
PopulateCURINSTR( PopulateCURINSTR(
OP_LR_8, A, SR13, // S OP_LR8, A, Kl, // S
ROMC_00_S, ROMC_00_S,
IDLE, IDLE,
END); END);
@ -34,7 +34,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
private void LR_A_QU() private void LR_A_QU()
{ {
PopulateCURINSTR( PopulateCURINSTR(
OP_LR_8, A, SR14, // S OP_LR8, A, Qh, // S
ROMC_00_S, ROMC_00_S,
IDLE, IDLE,
END); END);
@ -43,7 +43,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
private void LR_A_QL() private void LR_A_QL()
{ {
PopulateCURINSTR( PopulateCURINSTR(
OP_LR_8, A, SR15, // S OP_LR8, A, Ql, // S
ROMC_00_S, ROMC_00_S,
IDLE, IDLE,
END); END);
@ -52,7 +52,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
private void LR_KU_A() private void LR_KU_A()
{ {
PopulateCURINSTR( PopulateCURINSTR(
OP_LR_8, SR12, A, // S OP_LR8, Kh, A, // S
ROMC_00_S, ROMC_00_S,
IDLE, IDLE,
END); END);
@ -61,7 +61,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
private void LR_KL_A() private void LR_KL_A()
{ {
PopulateCURINSTR( PopulateCURINSTR(
OP_LR_8, SR13, A, // S OP_LR8, Kl, A, // S
ROMC_00_S, ROMC_00_S,
IDLE, IDLE,
END); END);
@ -70,7 +70,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
private void LR_QU_A() private void LR_QU_A()
{ {
PopulateCURINSTR( PopulateCURINSTR(
OP_LR_8, SR14, A, // S OP_LR8, Qh, A, // S
ROMC_00_S, ROMC_00_S,
IDLE, IDLE,
END); END);
@ -79,7 +79,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
private void LR_QL_A() private void LR_QL_A()
{ {
PopulateCURINSTR( PopulateCURINSTR(
OP_LR_8, SR15, A, // S OP_LR8, Ql, A, // S
ROMC_00_S, ROMC_00_S,
IDLE, IDLE,
END); END);
@ -91,13 +91,13 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
ROMC_07, // L ROMC_07, // L
IDLE, IDLE,
IDLE, IDLE,
OP_LR_8, SR12, DB, OP_LR8, Kh, DB,
IDLE, IDLE,
IDLE, IDLE,
ROMC_0B, // L ROMC_0B, // L
IDLE, IDLE,
IDLE, IDLE,
OP_LR_8, SR13, DB, OP_LR8, Kl, DB,
IDLE, IDLE,
IDLE, IDLE,
ROMC_00_S, // S ROMC_00_S, // S
@ -109,13 +109,13 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
private void LR_P_K() private void LR_P_K()
{ {
PopulateCURINSTR( PopulateCURINSTR(
OP_LR_8, DB, SR12, // L OP_LR8, DB, Kh, // L
IDLE, IDLE,
IDLE, IDLE,
ROMC_15, ROMC_15,
IDLE, IDLE,
IDLE, IDLE,
OP_LR_8, DB, SR13, // L OP_LR8, DB, Kl, // L
IDLE, IDLE,
IDLE, IDLE,
ROMC_18, ROMC_18,
@ -130,7 +130,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
private void LR_A_IS() private void LR_A_IS()
{ {
PopulateCURINSTR( PopulateCURINSTR(
OP_LR_8, A, ISAR, // S OP_LR8, A, ISAR, // S
ROMC_00_S, ROMC_00_S,
IDLE, IDLE,
END); END);
@ -139,7 +139,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
private void LR_IS_A() private void LR_IS_A()
{ {
PopulateCURINSTR( PopulateCURINSTR(
OP_LR_8, ISAR, A, // S OP_LR8, ISAR, A, // S
ROMC_00_S, ROMC_00_S,
IDLE, IDLE,
END); END);
@ -148,13 +148,13 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
private void LR_PK() private void LR_PK()
{ {
PopulateCURINSTR( PopulateCURINSTR(
OP_LR_8, DB, SR13, // L OP_LR8, DB, Kh, // L
IDLE, IDLE,
IDLE, IDLE,
ROMC_12, ROMC_12,
IDLE, IDLE,
IDLE, IDLE,
OP_LR_8, DB, SR12, // L OP_LR8, DB, Kl, // L
IDLE, IDLE,
IDLE, IDLE,
ROMC_14, ROMC_14,
@ -169,13 +169,13 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
private void LR_P0_Q() private void LR_P0_Q()
{ {
PopulateCURINSTR( PopulateCURINSTR(
OP_LR_8, DB, SR15, // L OP_LR8, DB, Ql, // L
IDLE, IDLE,
IDLE, IDLE,
ROMC_17, ROMC_17,
IDLE, IDLE,
IDLE, IDLE,
OP_LR_8, DB, SR14, // L OP_LR8, DB, Qh, // L
IDLE, IDLE,
IDLE, IDLE,
ROMC_14, ROMC_14,
@ -193,13 +193,13 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
ROMC_06, // L ROMC_06, // L
IDLE, IDLE,
IDLE, IDLE,
OP_LR_8, SR14, DB, OP_LR8, Qh, DB,
IDLE, IDLE,
IDLE, IDLE,
ROMC_09, // L ROMC_09, // L
IDLE, IDLE,
IDLE, IDLE,
OP_LR_8, SR15, DB, OP_LR8, Ql, DB,
IDLE, IDLE,
IDLE, IDLE,
ROMC_00_S, // S ROMC_00_S, // S
@ -211,13 +211,13 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
private void LR_DC_Q() private void LR_DC_Q()
{ {
PopulateCURINSTR( PopulateCURINSTR(
OP_LR_8, DB, SR14, // L OP_LR8, DB, Qh, // L
IDLE, IDLE,
IDLE, IDLE,
ROMC_16, ROMC_16,
IDLE, IDLE,
IDLE, IDLE,
OP_LR_8, DB, SR15, // L OP_LR8, DB, Ql, // L
IDLE, IDLE,
IDLE, IDLE,
ROMC_19, ROMC_19,
@ -232,13 +232,13 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
private void LR_DC_H() private void LR_DC_H()
{ {
PopulateCURINSTR( PopulateCURINSTR(
OP_LR_8, DB, SR10, // L OP_LR8, DB, Hh, // L
IDLE, IDLE,
IDLE, IDLE,
ROMC_16, ROMC_16,
IDLE, IDLE,
IDLE, IDLE,
OP_LR_8, DB, SR11, // L OP_LR8, DB, Hl, // L
IDLE, IDLE,
IDLE, IDLE,
ROMC_19, ROMC_19,
@ -256,13 +256,13 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
ROMC_06, // L ROMC_06, // L
IDLE, IDLE,
IDLE, IDLE,
OP_LR_8, SR10, DB, OP_LR8, Hh, DB,
IDLE, IDLE,
IDLE, IDLE,
ROMC_09, // L ROMC_09, // L
IDLE, IDLE,
IDLE, IDLE,
OP_LR_8, SR11, DB, OP_LR8, Hl, DB,
IDLE, IDLE,
IDLE, IDLE,
ROMC_00_S, // S ROMC_00_S, // S
@ -295,7 +295,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
ROMC_02, // L ROMC_02, // L
IDLE, IDLE,
IDLE, IDLE,
OP_LR_8, DB, A, OP_LR8, DB, A,
IDLE, IDLE,
IDLE, IDLE,
ROMC_00_S, // S ROMC_00_S, // S
@ -307,7 +307,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
private void ST() private void ST()
{ {
PopulateCURINSTR( PopulateCURINSTR(
OP_LR_8, DB, A, // L OP_LR8, DB, A, // L
IDLE, IDLE,
IDLE, IDLE,
ROMC_05, ROMC_05,
@ -322,7 +322,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
private void COM() private void COM()
{ {
PopulateCURINSTR( PopulateCURINSTR(
OP_COM, // S OP_XOR8C, A, DB, // S
ROMC_00_S, ROMC_00_S,
IDLE, IDLE,
END); END);
@ -381,7 +381,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
PopulateCURINSTR( PopulateCURINSTR(
ROMC_1C_S, // S ROMC_1C_S, // S
IDLE, IDLE,
OP_LR_8, W, SR9, OP_LR8, W, J,
IDLE, IDLE,
ROMC_00_S, // S ROMC_00_S, // S
IDLE, IDLE,
@ -392,7 +392,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
private void LR_J_W() private void LR_J_W()
{ {
PopulateCURINSTR( PopulateCURINSTR(
OP_LR_8, SR9, W, // S OP_LR8, J, W, // S
ROMC_00_S, ROMC_00_S,
IDLE, IDLE,
END); END);
@ -407,6 +407,96 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
END); END);
} }
private void LI()
{
PopulateCURINSTR(
ROMC_03_L, // L
IDLE,
IDLE,
OP_LR8, A, DB,
IDLE,
IDLE,
ROMC_00_S, // S
IDLE,
IDLE,
END);
}
private void NI()
{
PopulateCURINSTR(
ROMC_03_L, // L
IDLE,
IDLE,
OP_AND8, A, DB,
IDLE,
IDLE,
ROMC_00_S, // S
IDLE,
IDLE,
END);
}
private void OI()
{
PopulateCURINSTR(
ROMC_03_L, // L
IDLE,
IDLE,
OP_OR8, A, DB,
IDLE,
IDLE,
ROMC_00_S, // S
IDLE,
IDLE,
END);
}
private void XI()
{
PopulateCURINSTR(
ROMC_03_L, // L
IDLE,
IDLE,
OP_XOR8, A, DB,
IDLE,
IDLE,
ROMC_00_S, // S
IDLE,
IDLE,
END);
}
private void AI()
{
PopulateCURINSTR(
ROMC_03_L, // L
IDLE,
IDLE,
OP_ADD8, A, DB,
IDLE,
IDLE,
ROMC_00_S, // S
IDLE,
IDLE,
END);
}
private void CI()
{
PopulateCURINSTR(
ROMC_03_L, // L
IDLE,
IDLE,
OP_CI, A,
IDLE,
IDLE,
ROMC_00_S, // S
IDLE,
IDLE,
END);
}
private void ILLEGAL() private void ILLEGAL()
{ {
@ -416,5 +506,655 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
IDLE, IDLE,
END); END);
} }
private void IN()
{
PopulateCURINSTR(
ROMC_03_L, // L
IDLE,
IDLE,
IDLE,
IDLE,
IDLE,
ROMC_1B, // L
IDLE,
IDLE,
OP_LR8_IO, A, DB,
IDLE,
IDLE,
ROMC_00_S, // S
IDLE,
IDLE,
END);
}
private void OUT()
{
PopulateCURINSTR(
ROMC_03_L, // L
IDLE,
IDLE,
OP_LR8, DB, A,
IDLE,
IDLE,
ROMC_1A, // L
IDLE,
IDLE,
IDLE,
IDLE,
IDLE,
ROMC_00_S, // S
IDLE,
IDLE,
END);
}
private void PI()
{
PopulateCURINSTR(
ROMC_03_L, // L
IDLE,
IDLE,
OP_LR8, A, DB,
IDLE,
IDLE,
ROMC_0D, // S
IDLE,
IDLE,
IDLE,
ROMC_0C, // L
IDLE,
IDLE,
OP_LR8, DB, A,
IDLE,
IDLE,
ROMC_14, // L
IDLE,
IDLE,
IDLE,
IDLE,
IDLE,
ROMC_00_S, // S
IDLE,
IDLE,
END);
}
private void JMP()
{
PopulateCURINSTR(
ROMC_03_L, // L
IDLE,
IDLE,
OP_LR8, A, DB,
IDLE,
IDLE,
ROMC_0C, // L
IDLE,
IDLE,
OP_LR8, DB, A,
IDLE,
IDLE,
ROMC_14, // L
IDLE,
IDLE,
IDLE,
IDLE,
IDLE,
ROMC_00_S, // S
IDLE,
IDLE,
END);
}
private void DCI()
{
PopulateCURINSTR(
ROMC_11, // L
IDLE,
IDLE,
IDLE,
IDLE,
IDLE,
ROMC_03_S, // S
IDLE,
IDLE,
IDLE,
ROMC_0E, // L
IDLE,
IDLE,
IDLE,
IDLE,
IDLE,
ROMC_03_S, // S
IDLE,
IDLE,
IDLE,
ROMC_00_S, // S
IDLE,
IDLE,
END);
}
private void NOP()
{
PopulateCURINSTR(
ROMC_00_S, // S
IDLE,
IDLE,
END);
}
private void XDC()
{
PopulateCURINSTR(
ROMC_1D, // S
IDLE,
IDLE,
IDLE,
ROMC_00_S, // S
IDLE,
IDLE,
END);
}
private void DS(ushort rIndex)
{
PopulateCURINSTR(
OP_LR8, rIndex, BYTE, // L
IDLE,
ROMC_00_L,
IDLE,
IDLE,
END);
}
private void DS_ISAR()
{
PopulateCURINSTR(
OP_DS_IS, // L
IDLE,
ROMC_00_L,
IDLE,
IDLE,
END);
}
private void DS_ISAR_INC()
{
PopulateCURINSTR(
OP_DS_IS, // L
OP_IS_INC,
ROMC_00_L,
IDLE,
IDLE,
END);
}
private void DS_ISAR_DEC()
{
PopulateCURINSTR(
OP_DS_IS, // L
OP_IS_DEC,
ROMC_00_L,
IDLE,
IDLE,
END);
}
private void LR_A_R(ushort rIndex)
{
PopulateCURINSTR(
OP_LR8, A, rIndex, // S
ROMC_00_S,
IDLE,
END);
}
private void LR_A_ISAR()
{
PopulateCURINSTR(
OP_LR_A_IS, A, // S
ROMC_00_S,
IDLE,
END);
}
private void LR_A_ISAR_INC()
{
PopulateCURINSTR(
OP_LR_A_IS, A, // S
OP_IS_INC,
ROMC_00_S,
END);
}
private void LR_A_ISAR_DEC()
{
PopulateCURINSTR(
OP_LR_A_IS, A, // S
OP_IS_DEC,
ROMC_00_S,
END);
}
private void LR_R_A(ushort rIndex)
{
PopulateCURINSTR(
OP_LR8, rIndex, A, // S
ROMC_00_S,
IDLE,
END);
}
private void LR_ISAR_A()
{
PopulateCURINSTR(
OP_LR_IS_A, A, // S
ROMC_00_S,
IDLE,
END);
}
private void LR_ISAR_A_INC()
{
PopulateCURINSTR(
OP_LR_IS_A, A, // S
OP_IS_INC,
ROMC_00_S,
END);
}
private void LR_ISAR_A_DEC()
{
PopulateCURINSTR(
OP_LR_IS_A, A, // S
OP_IS_DEC,
ROMC_00_S,
END);
}
private void LISU(ushort octal)
{
PopulateCURINSTR(
OP_LISU, octal, // S
ROMC_00_S,
IDLE,
END);
}
private void LISL(ushort octal)
{
PopulateCURINSTR(
OP_LISL, octal, // S
ROMC_00_S,
IDLE,
END);
}
private void LIS(ushort index)
{
PopulateCURINSTR(
OP_LR8, A, index, // S
ROMC_00_S,
IDLE,
END);
}
private void BT(ushort index)
{
PopulateCURINSTR(
ROMC_1C_S, // S
IDLE,
IDLE,
OP_BT, index); // no END as there is branching logic within OP_BT
}
private void AM()
{
PopulateCURINSTR(
ROMC_02, // L
IDLE,
IDLE,
OP_ADD8, A, DB,
IDLE,
IDLE,
ROMC_00_S, // S
IDLE,
IDLE,
END);
}
private void AMD()
{
PopulateCURINSTR(
ROMC_02, // L
IDLE,
IDLE,
OP_ADD8D, A, DB,
IDLE,
IDLE,
ROMC_00_S, // S
IDLE,
IDLE,
END);
}
private void NM()
{
PopulateCURINSTR(
ROMC_02, // L
IDLE,
IDLE,
OP_AND8, A, DB,
IDLE,
IDLE,
ROMC_00_S, // S
IDLE,
IDLE,
END);
}
private void OM()
{
PopulateCURINSTR(
ROMC_02, // L
IDLE,
IDLE,
OP_OR8, A, DB,
IDLE,
IDLE,
ROMC_00_S, // S
IDLE,
IDLE,
END);
}
private void XM()
{
PopulateCURINSTR(
ROMC_02, // L
IDLE,
IDLE,
OP_XOR8, A, DB,
IDLE,
IDLE,
ROMC_00_S, // S
IDLE,
IDLE,
END);
}
private void CM()
{
PopulateCURINSTR(
ROMC_02, // L
IDLE,
IDLE,
OP_CM,
IDLE,
IDLE,
ROMC_00_S, // S
IDLE,
IDLE,
END);
}
private void ADC()
{
PopulateCURINSTR(
OP_LR8, DB, A, // L
IDLE,
IDLE,
ROMC_0A,
IDLE,
IDLE,
ROMC_00_S, // S
IDLE,
IDLE,
END);
}
private void BR7()
{
PopulateCURINSTR(
OP_BR7); // no END as there is branching logic within OP_BR7
}
private void BF(ushort index)
{
PopulateCURINSTR(
ROMC_1C_S, // S
IDLE,
IDLE,
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
IDLE,
IDLE,
END);
}
private void INS_1(ushort index)
{
PopulateCURINSTR(
ROMC_1C_L, // L
IDLE,
IDLE,
OP_LR8, IO, index,
IDLE,
IDLE,
ROMC_1B, // L
IDLE,
IDLE,
OP_LR8_IO, A, DB,
IDLE,
IDLE,
ROMC_00_S, // S
IDLE,
IDLE,
END);
}
private void OUTS_0(ushort index)
{
PopulateCURINSTR(
ROMC_1C_S, // S
IDLE,
OP_OUT, index, A,
IDLE,
ROMC_00_S, // S
IDLE,
IDLE,
END);
}
private void OUTS_1(ushort index)
{
PopulateCURINSTR(
ROMC_1C_L, // L
IDLE,
IDLE,
OP_LR8, IO, index,
OP_LR8, DB, A,
IDLE,
ROMC_1A, // L
IDLE,
IDLE,
IDLE,
IDLE,
IDLE,
ROMC_00_S, // S
IDLE,
IDLE,
END);
}
private void AS(ushort rIndex)
{
PopulateCURINSTR(
OP_ADD8, A, rIndex, // S
ROMC_00_S,
IDLE,
END);
}
private void AS_IS()
{
PopulateCURINSTR(
OP_AS_IS, // S
ROMC_00_S,
IDLE,
END);
}
private void AS_IS_INC()
{
PopulateCURINSTR(
OP_AS_IS, // S
OP_IS_INC,
ROMC_00_S,
END);
}
private void AS_IS_DEC()
{
PopulateCURINSTR(
OP_AS_IS, // S
OP_IS_DEC,
ROMC_00_S,
END);
}
private void ASD(ushort rIndex)
{
PopulateCURINSTR(
ROMC_1C_S, // S
IDLE,
OP_ADD8D, A, rIndex,
IDLE,
ROMC_00_S, // S
IDLE,
IDLE,
END);
}
private void ASD_IS()
{
PopulateCURINSTR(
ROMC_1C_S, // S
IDLE,
OP_ASD_IS,
IDLE,
ROMC_00_S, // S
IDLE,
IDLE,
END);
}
private void ASD_IS_INC()
{
PopulateCURINSTR(
ROMC_1C_S, // S
IDLE,
OP_ASD_IS,
OP_IS_INC,
ROMC_00_S, // S
IDLE,
IDLE,
END);
}
private void ASD_IS_DEC()
{
PopulateCURINSTR(
ROMC_1C_S, // S
IDLE,
OP_ASD_IS,
OP_IS_DEC,
ROMC_00_S, // S
IDLE,
IDLE,
END);
}
private void XS(ushort rIndex)
{
PopulateCURINSTR(
OP_XOR8, A, rIndex, // S
ROMC_00_S,
IDLE,
END);
}
private void XS_IS()
{
PopulateCURINSTR(
OP_XS_IS, // S
ROMC_00_S,
IDLE,
END);
}
private void XS_IS_INC()
{
PopulateCURINSTR(
OP_XS_IS, // S
OP_IS_INC,
ROMC_00_S,
END);
}
private void XS_IS_DEC()
{
PopulateCURINSTR(
OP_XS_IS, // S
OP_IS_DEC,
ROMC_00_S,
END);
}
private void NS(ushort rIndex)
{
PopulateCURINSTR(
OP_AND8, A, rIndex, // S
ROMC_00_S,
IDLE,
END);
}
private void NS_IS()
{
PopulateCURINSTR(
OP_NS_IS, // S
ROMC_00_S,
IDLE,
END);
}
private void NS_IS_INC()
{
PopulateCURINSTR(
OP_NS_IS, // S
OP_IS_INC,
ROMC_00_S,
END);
}
private void NS_IS_DEC()
{
PopulateCURINSTR(
OP_NS_IS, // S
OP_IS_DEC,
ROMC_00_S,
END);
}
} }
} }

View File

@ -1,9 +1,11 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using BizHawk.Common; using BizHawk.Common;
using BizHawk.Common.NumberExtensions;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Consoles.ChannelF namespace BizHawk.Emulation.Cores.Consoles.ChannelF
@ -82,14 +84,38 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
public const ushort IDLE = 0; public const ushort IDLE = 0;
public const ushort END = 51; public const ushort END = 51;
public const ushort OP_LR_8 = 100; public const ushort OP_LR8 = 100;
public const ushort OP_SHFT_R = 101; public const ushort OP_SHFT_R = 101;
public const ushort OP_SHFT_L = 102; public const ushort OP_SHFT_L = 102;
public const ushort OP_COM = 103; public const ushort OP_LNK = 103;
public const ushort OP_LNK = 104; public const ushort OP_DI = 104;
public const ushort OP_DI = 105; public const ushort OP_EI = 105;
public const ushort OP_EI = 106; public const ushort OP_INC8 = 106;
public const ushort OP_INC8 = 107; 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_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 F3850() public F3850()
@ -104,14 +130,17 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
instr_pntr = 0; instr_pntr = 0;
PopulateCURINSTR( PopulateCURINSTR(
ROMC_08, // S ROMC_1C_S, // S
IDLE,
IDLE,
IDLE,
ROMC_08, // L
IDLE, IDLE,
IDLE, IDLE,
IDLE, IDLE,
IDLE, IDLE,
IDLE, IDLE,
ROMC_00_S, ROMC_00_S, // S
IDLE,
IDLE, IDLE,
IDLE, IDLE,
END); END);
@ -160,7 +189,9 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
{ {
// always the last tick within an opcode instruction cycle // always the last tick within an opcode instruction cycle
case END: case END:
opcode = databus; OnExecFetch?.Invoke(RegPC0);
TraceCallback?.Invoke(State());
opcode = (byte)Regs[DB];
instr_pntr = 0; instr_pntr = 0;
FetchInstruction(); FetchInstruction();
break; break;
@ -170,23 +201,28 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
break; break;
// load one register into another (or databus) // load one register into another (or databus)
case OP_LR_8: case OP_LR8:
LoadReg_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); LR8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break; break;
// Shift register n bit positions to the right (zero fill) // Shift register n bit positions to the right (zero fill)
case OP_SHFT_R: case OP_SHFT_R:
ShiftRight_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); SR_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break; break;
// Shift register n bit positions to the left (zero fill) // Shift register n bit positions to the left (zero fill)
case OP_SHFT_L: case OP_SHFT_L:
ShiftLeft_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); SL_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break; break;
// A <- A ^ 255 // x <- (x) ADD y
case OP_COM: case OP_ADD8:
COM_Func(A); 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++]);
break; break;
// A <- (A) + (C) // A <- (A) + (C)
@ -194,18 +230,222 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
ADD8_Func(Regs[A], (ushort)(FlagC ? 1 : 0)); ADD8_Func(Regs[A], (ushort)(FlagC ? 1 : 0));
break; break;
// Clear ICB status bit
case OP_DI: case OP_DI:
FlagICB = false; FlagICB = false;
break; break;
// Set ICB status bit
case OP_EI: case OP_EI:
FlagICB = true; FlagICB = true;
break; break;
// x <- (y) XOR DB
case OP_XOR8:
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++]);
break;
// x <- (x) + 1
case OP_INC8: case OP_INC8:
INC8_Func(cur_instr[instr_pntr++]); INC8_Func(cur_instr[instr_pntr++]);
break; break;
// x <- (y) & DB
case OP_AND8:
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++]);
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:
LR8_Func(Regs[ISAR], Regs[BYTE]);
break;
// ISAR is incremented
case OP_IS_INC:
Regs[ISAR] = (ushort)((Regs[ISAR]& 0x38) | ((Regs[ISAR] + 1) & 0x07));
break;
// ISAR is decremented
case OP_IS_DEC:
Regs[ISAR] = (ushort)((Regs[ISAR] & 0x38) | ((Regs[ISAR] - 1) & 0x07));
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);
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);
break;
// test operand against status register
case OP_BT:
instr_pntr = 0;
if ((Regs[W] & cur_instr[instr_pntr++]) != 0)
{
PopulateCURINSTR(
ROMC_01, // L
IDLE,
IDLE,
IDLE,
IDLE,
IDLE,
ROMC_00_S, // S
IDLE,
IDLE,
END);
}
else
{
PopulateCURINSTR(
ROMC_03_S, // S
IDLE,
IDLE,
IDLE,
ROMC_00_S, // S
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
//IDLE, <- lose a cycle that was stolen in the table
IDLE,
IDLE,
ROMC_00_S, // S
IDLE,
IDLE,
END);
}
else
{
PopulateCURINSTR(
ROMC_01, // L
//IDLE, <- lose a cycle that was stolen in the table
IDLE,
IDLE,
IDLE,
IDLE,
ROMC_00_S, // S
IDLE,
IDLE,
END);
}
break;
// PC0 <- PC0+n+1
case OP_BF:
instr_pntr = 0;
if ((Regs[W] & cur_instr[instr_pntr++]) != 0)
{
PopulateCURINSTR(
ROMC_03_S, // S
IDLE,
IDLE,
IDLE,
ROMC_00_S, // S
IDLE,
IDLE,
END);
}
else
{
PopulateCURINSTR(
ROMC_01, // L
IDLE,
IDLE,
IDLE,
IDLE,
IDLE,
ROMC_00_S, // S
IDLE,
IDLE,
END);
}
break;
// A <- (I/O Port 0 or 1)
case OP_IN:
IN_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
// I/O Port 0 or 1 <- (A)
case OP_OUT:
OUT_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
// Add the content of the SR register addressed by ISAR to A (Binary)
case OP_AS_IS:
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]);
break;
// XOR the content of the SR register addressed by ISAR to A
case OP_XS_IS:
XOR8_Func(A, Regs[ISAR]);
break;
// AND the content of the SR register addressed by ISAR to A
case OP_NS_IS:
AND8_Func(A, Regs[ISAR]);
break;
// instruction fetch // instruction fetch
@ -213,7 +453,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
// then all devices increments the content of PC0. // then all devices increments the content of PC0.
// CYCLE LENGTH: S // CYCLE LENGTH: S
case ROMC_00_S: case ROMC_00_S:
databus = ReadMemory(RegPC0++); Regs[DB] = ReadMemory(RegPC0++);
break; break;
// instruction fetch // instruction fetch
@ -221,36 +461,36 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
// then all devices increments the content of PC0. // then all devices increments the content of PC0.
// CYCLE LENGTH: L // CYCLE LENGTH: L
case ROMC_00_L: case ROMC_00_L:
databus = ReadMemory(RegPC0++); Regs[DB] = ReadMemory(RegPC0++);
break; 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 // 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 // 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 // CYCLE LENGTH: L
case ROMC_01: case ROMC_01:
databus = ReadMemory(RegPC0); Regs[DB] = ReadMemory(RegPC0);
IncrementBySignedByte(RegPC0, databus); ADDS_Func(PC0l, PC0h, DB, ZERO);
break; break;
// The device whose DC0 address addresses a memory word within the address space of that device must place on the data bus the contents // The device whose DC0 address addresses a memory word within the address space of that device must place on the data bus the contents
// of the memory location addressed by DC0; then all devices increment DC0 // of the memory location addressed by DC0; then all devices increment DC0
// CYCLE LENGTH: L // CYCLE LENGTH: L
case ROMC_02: case ROMC_02:
databus = ReadMemory(RegDC0++); Regs[DB] = ReadMemory(RegDC0++);
break; break;
// Similar to 0x00, except that it is used for Immediate Operand fetches (using PC0) instead of instruction fetches // Similar to 0x00, except that it is used for Immediate Operand fetches (using PC0) instead of instruction fetches
// CYCLE LENGTH: S // CYCLE LENGTH: S
case ROMC_03_S: case ROMC_03_S:
databus = ReadMemory(RegPC0++); Regs[DB] = ReadMemory(RegPC0++);
iobus = databus; Regs[IO] = Regs[DB];
break; break;
// Similar to 0x00, except that it is used for Immediate Operand fetches (using PC0) instead of instruction fetches // Similar to 0x00, except that it is used for Immediate Operand fetches (using PC0) instead of instruction fetches
// CYCLE LENGTH: L // CYCLE LENGTH: L
case ROMC_03_L: case ROMC_03_L:
databus = ReadMemory(RegPC0++); Regs[DB] = ReadMemory(RegPC0++);
iobus = databus; Regs[IO] = Regs[DB];
break; break;
// Copy the contents of PC1 into PC0 // Copy the contents of PC1 into PC0
@ -262,19 +502,19 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
// Store the data bus contents into the memory location pointed to by DC0; increment DC0 // Store the data bus contents into the memory location pointed to by DC0; increment DC0
// CYCLE LENGTH: L // CYCLE LENGTH: L
case ROMC_05: case ROMC_05:
WriteMemory(RegDC0++, databus); WriteMemory(RegDC0++, (byte)Regs[DB]);
break; break;
// Place the high order byte of DC0 on the data bus // Place the high order byte of DC0 on the data bus
// CYCLE LENGTH: L // CYCLE LENGTH: L
case ROMC_06: case ROMC_06:
databus = (byte)Regs[DC0h]; Regs[DB] = (byte)Regs[DC0h];
break; break;
// Place the high order byte of PC1 on the data bus // Place the high order byte of PC1 on the data bus
// CYCLE LENGTH: L // CYCLE LENGTH: L
case ROMC_07: case ROMC_07:
databus = (byte)Regs[PC1h]; Regs[DB] = (byte)Regs[PC1h];
break; break;
// All devices copy the contents of PC0 into PC1. The CPU outputs zero on the data bus in this ROMC state. // All devices copy the contents of PC0 into PC1. The CPU outputs zero on the data bus in this ROMC state.
@ -282,7 +522,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
// CYCLE LENGTH: L // CYCLE LENGTH: L
case ROMC_08: case ROMC_08:
RegPC1 = RegPC0; RegPC1 = RegPC0;
databus = 0; Regs[DB] = 0;
Regs[PC0h] = 0; Regs[PC0h] = 0;
Regs[PC0l] = 0; Regs[PC0l] = 0;
break; break;
@ -290,27 +530,27 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
// The device whose address space includes the contents of the DC0 register must place the low order byte of DC0 onto the data bus // The device whose address space includes the contents of the DC0 register must place the low order byte of DC0 onto the data bus
// CYCLE LENGTH: L // CYCLE LENGTH: L
case ROMC_09: case ROMC_09:
databus = (byte)Regs[DC0l]; Regs[DB] = (byte)Regs[DC0l];
break; break;
// All devices add the 8-bit value on the data bus, treated as a signed binary number, to the data counter // All devices add the 8-bit value on the data bus, treated as a signed binary number, to the data counter
// CYCLE LENGTH: L // CYCLE LENGTH: L
case ROMC_0A: case ROMC_0A:
IncrementBySignedByte(RegDC0, databus); ADDS_Func(DC0l, DC0h, DB, ZERO);
break; break;
// The device whose address space includes the value in PC1 must place the low order byte of PC1 on the data bus // The device whose address space includes the value in PC1 must place the low order byte of PC1 on the data bus
// CYCLE LENGTH: L // CYCLE LENGTH: L
case ROMC_0B: case ROMC_0B:
databus = (byte)Regs[PC1l]; Regs[DB] = (byte)Regs[PC1l];
break; break;
// The device whose address space includes the contents of the PC0 register must place the contents of the memory word addressed by PC0 // The device whose address space includes the contents of the PC0 register must place the contents of the memory word addressed by PC0
// 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 // 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 // CYCLE LENGTH: L
case ROMC_0C: case ROMC_0C:
databus = ReadMemory(RegPC0); Regs[DB] = ReadMemory(RegPC0);
Regs[PC0l] = databus; Regs[PC0l] = Regs[DB];
break; break;
// All devices store in PC1 the current contents of PC0, incremented by 1; PC1 is unaltered // All devices store in PC1 the current contents of PC0, incremented by 1; PC1 is unaltered
@ -323,8 +563,8 @@ 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 // The value on the data bus is then moved to the low order byte of DC0 by all devices
// CYCLE LENGTH: L // CYCLE LENGTH: L
case ROMC_0E: case ROMC_0E:
databus = ReadMemory(RegPC0); Regs[DB] = ReadMemory(RegPC0);
Regs[DC0l] = databus; Regs[DC0l] = Regs[DB];
break; break;
// The interrupting device with the highest priority must place the low order byte of the interrupt vector on the data bus. // The interrupting device with the highest priority must place the low order byte of the interrupt vector on the data bus.
@ -332,27 +572,25 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
// CYCLE LENGTH: L // CYCLE LENGTH: L
case ROMC_0F: case ROMC_0F:
throw new NotImplementedException("ROMC 0x0F not implemented"); throw new NotImplementedException("ROMC 0x0F not implemented");
break;
// Inhibit any modification to the interrupt priority logic // Inhibit any modification to the interrupt priority logic
// CYCLE LENGTH: L // CYCLE LENGTH: L
case ROMC_10: case ROMC_10:
throw new NotImplementedException("ROMC 0x10 not implemented"); throw new NotImplementedException("ROMC 0x10 not implemented");
break;
// The device whose memory space includes the contents of PC0 must place the contents of the addressed memory word on the data bus. // The device whose memory space includes the contents of PC0 must place the contents of the addressed memory word on the data bus.
// All devices must then move the contents of the data bus to the upper byte of DC0 // All devices must then move the contents of the data bus to the upper byte of DC0
// CYCLE LENGTH: L // CYCLE LENGTH: L
case ROMC_11: case ROMC_11:
databus = ReadMemory(RegPC0); Regs[DB] = ReadMemory(RegPC0);
Regs[DC0h] = databus; Regs[DC0h] = Regs[DB];
break; break;
// All devices copy the contents of PC0 into PC1. All devices then move the contents of the data bus into the low order byte of PC0 // All devices copy the contents of PC0 into PC1. All devices then move the contents of the data bus into the low order byte of PC0
// CYCLE LENGTH: L // CYCLE LENGTH: L
case ROMC_12: case ROMC_12:
RegPC1 = RegPC0; RegPC1 = RegPC0;
Regs[PC0l] = databus; Regs[PC0l] = Regs[DB];
break; break;
// The interrupting device with the highest priority must move the high order half of the interrupt vector onto the data bus. // The interrupting device with the highest priority must move the high order half of the interrupt vector onto the data bus.
@ -361,49 +599,48 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
// CYCLE LENGTH: L // CYCLE LENGTH: L
case ROMC_13: case ROMC_13:
throw new NotImplementedException("ROMC 0x13 not implemented"); throw new NotImplementedException("ROMC 0x13 not implemented");
break;
// All devices move the contents of the data bus into the high order byte of PC0 // All devices move the contents of the data bus into the high order byte of PC0
// CYCLE LENGTH: L // CYCLE LENGTH: L
case ROMC_14: case ROMC_14:
Regs[PC0h] = databus; Regs[PC0h] = Regs[DB];
break; break;
// All devices move the contents of the data bus into the high order byte of PC1 // All devices move the contents of the data bus into the high order byte of PC1
// CYCLE LENGTH: L // CYCLE LENGTH: L
case ROMC_15: case ROMC_15:
Regs[PC1h] = databus; Regs[PC1h] = Regs[DB];
break; break;
// All devices move the contents of the data bus into the high order byte of DC0 // All devices move the contents of the data bus into the high order byte of DC0
// CYCLE LENGTH: L // CYCLE LENGTH: L
case ROMC_16: case ROMC_16:
Regs[DC0h] = databus; Regs[DC0h] = Regs[DB];
break; break;
// All devices move the contents of the data bus into the low order byte of PC0 // All devices move the contents of the data bus into the low order byte of PC0
// CYCLE LENGTH: L // CYCLE LENGTH: L
case ROMC_17: case ROMC_17:
Regs[PC0l] = databus; Regs[PC0l] = Regs[DB];
break; break;
// All devices move the contents of the data bus into the low order byte of PC1 // All devices move the contents of the data bus into the low order byte of PC1
// CYCLE LENGTH: L // CYCLE LENGTH: L
case ROMC_18: case ROMC_18:
Regs[PC1l] = databus; Regs[PC1l] = Regs[DB];
break; break;
// All devices move the contents of the data bus into the low order byte of DC0 // All devices move the contents of the data bus into the low order byte of DC0
// CYCLE LENGTH: L // CYCLE LENGTH: L
case ROMC_19: case ROMC_19:
Regs[DC0l] = databus; Regs[DC0l] = Regs[DB];
break; break;
// During the prior cycle, an I/O port timer or interrupt control register was addressed; the device containing the addressed // During the prior cycle, an I/O port timer or interrupt control register was addressed; the device containing the addressed
// port must move the current contents of the data bus into the addressed port // port must move the current contents of the data bus into the addressed port
// CYCLE LENGTH: L // CYCLE LENGTH: L
case ROMC_1A: case ROMC_1A:
WriteHardware(iobus, databus); WriteHardware(Regs[IO], (byte)Regs[DB]);
break; break;
// During the prior cycle, the data bus specified the address of an I/O port. The device containing the addressed I/O port // During the prior cycle, the data bus specified the address of an I/O port. The device containing the addressed I/O port
@ -411,7 +648,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
// registers cannot be read back onto the data bus) // registers cannot be read back onto the data bus)
// CYCLE LENGTH: L // CYCLE LENGTH: L
case ROMC_1B: case ROMC_1B:
databus = ReadHardware(iobus); Regs[DB] = ReadHardware(Regs[IO]);
break; break;
// None // None
@ -433,19 +670,71 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
// The device whose address space includes the contents of PC0 must place the low order byte of PC0 onto the data bus // The device whose address space includes the contents of PC0 must place the low order byte of PC0 onto the data bus
// CYCLE LENGTH: L // CYCLE LENGTH: L
case ROMC_1E: case ROMC_1E:
databus = (byte)Regs[PC0l]; Regs[DB] = (byte)Regs[PC0l];
break; break;
// The device whose address space includes the contents of PC0 must place the high order byte of PC0 onto the data bus // The device whose address space includes the contents of PC0 must place the high order byte of PC0 onto the data bus
// CYCLE LENGTH: L // CYCLE LENGTH: L
case ROMC_1F: case ROMC_1F:
databus = (byte)Regs[PC0h]; Regs[DB] = (byte)Regs[PC0h];
break; break;
} }
TotalExecutedCycles++; TotalExecutedCycles++;
} }
public Action<TraceInfo> TraceCallback;
public string TraceHeader => "F3850: PC, machine code, mnemonic, operands, registers (R0, R1, R2, R3, R4, R5, R6, R7, R8, J, HU, HL, KU, KL, QU, QL, Cy), flags (IOZCS)";
public TraceInfo State(bool disassemble = true)
{
int bytes_read = 0;
string disasm = disassemble ? Disassemble(RegPC0, ReadMemory, out bytes_read) : "---";
string byte_code = null;
for (ushort i = 0; i < bytes_read; i++)
{
byte_code += ReadMemory((ushort)(RegPC0 + i)).ToHexString(2);
if (i < (bytes_read - 1))
{
byte_code += " ";
}
}
return new TraceInfo
{
Disassembly = string.Format(
"{0:X4}: {1} {2}",
RegPC0,
byte_code.PadRight(12),
disasm.PadRight(26)),
RegisterInfo = string.Format(
"R0:{0:X2} R1:{1:X2} R2:{2:X2} R3:{3:X2} R4:{4:X2} R5:{5:X2} R6:{6:X2} R7:{7:X2} R8:{8:X2} J:{9:X2} HU:{10:X2} HL:{11:X2} KU:{12:X2} KL:{13:X2} QU:{14:X2} QL:{15:X2} Cy:{16} {17}{18}{19}{20}{21}",
Regs[0],
Regs[1],
Regs[2],
Regs[3],
Regs[4],
Regs[5],
Regs[6],
Regs[7],
Regs[8],
Regs[J],
Regs[Hh],
Regs[Hl],
Regs[Kh],
Regs[Kl],
Regs[Qh],
Regs[Ql],
TotalExecutedCycles,
FlagICB ? "I" : "i",
FlagO ? "O" : "o",
FlagZ ? "Z" : "z",
FlagC ? "C" : "c",
FlagS ? "S" : "s")
};
}
/// <summary> /// <summary>
/// Optimization method to set cur_instr /// Optimization method to set cur_instr
@ -473,7 +762,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
public void SyncState(Serializer ser) public void SyncState(Serializer ser)
{ {
ser.BeginSection(nameof(F3850)); ser.BeginSection(nameof(F3850));
ser.Sync(nameof(Regs), ref Regs, false);
ser.Sync(nameof(cur_instr), ref cur_instr, false);
ser.EndSection(); ser.EndSection();
} }
} }