PCE: some CDL stuff, not hooked up yet

This commit is contained in:
goyuken 2014-02-09 23:13:11 +00:00
parent 8193e0b281
commit 522f6549ad
9 changed files with 1687 additions and 2 deletions

View File

@ -414,6 +414,7 @@
<Compile Include="Consoles\Nintendo\SNES\SNESGraphicsDecoder.cs" />
<Compile Include="Consoles\PC Engine\ADPCM.cs" />
<Compile Include="Consoles\PC Engine\ArcadeCard.cs" />
<Compile Include="Consoles\PC Engine\CDLMapping.cs" />
<Compile Include="Consoles\PC Engine\MemoryMap.TurboCD.cs" />
<Compile Include="Consoles\PC Engine\MemoryMap.Populous.cs" />
<Compile Include="Consoles\PC Engine\ScsiCDBus.cs" />
@ -452,6 +453,8 @@
<Compile Include="CPUs\CP1610\CP1610.cs" />
<Compile Include="CPUs\CP1610\Disassembler.cs" />
<Compile Include="CPUs\CP1610\Execute.cs" />
<Compile Include="CPUs\HuC6280\CDL.cs" />
<Compile Include="CPUs\HuC6280\CDLOpcodes.cs" />
<Compile Include="CPUs\HuC6280\Disassembler.cs" />
<Compile Include="CPUs\HuC6280\Execute.cs" />
<Compile Include="CPUs\HuC6280\HuC6280.cs" />

View File

@ -0,0 +1,155 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BizHawk.Emulation.Cores.Components.H6280
{
public partial class HuC6280
{
public struct MemMapping
{
public string Name;
public int Offs;
}
public MemMapping[] Mappings; // = new MemMapping[256];
public Dictionary<string, byte[]> CodeDataLog = new Dictionary<string, byte[]>();
/// <summary>
/// create a new empty CodeDataLog to match the Mappings
/// </summary>
public void InitCDL()
{
Dictionary<string, int> sizes = new Dictionary<string, int>();
foreach (var m in Mappings)
{
if (!sizes.ContainsKey(m.Name) || m.Offs >= sizes[m.Name])
sizes[m.Name] = m.Offs;
}
CodeDataLog.Clear();
foreach (var kvp in sizes)
{
// becase we were looking at offsets, and each bank is 8192 big, we need to add that size
CodeDataLog[kvp.Key] = new byte[kvp.Value + 8192];
}
}
[Flags]
enum CDLUsage : byte
{
// was fetched as an opcode
Code = 0x01,
// was read or written as data
Data = 0x02,
// was read and used as a pointer to data via indirect addressing
DataPtr = 0x04,
// was read or written as stack
Stack = 0x08,
// was read or written as data via indirect addressing
IndirectData = 0x10,
// was read and used as function pointer
// NB: there is no "IndirectCode"; all code is marked simply as code regardless of how it is reached
FcnPtr = 0x20,
// was used as a source (either initial or during the loop) of a block xfer
BlockFrom = 0x40,
// was used as a destination (either initial or during the loop) of a block xfer
BlockTo = 0x80
}
void Mark(ushort addr, CDLUsage flag)
{
var m = Mappings[MPR[addr >> 13]];
CodeDataLog[m.Name][addr & 0x1fff | m.Offs] |= (byte)flag;
}
// mark addr as having been fetched for execute
void MarkCode(int addr_)
{
ushort addr = (ushort)addr_;
Mark(addr, CDLUsage.Code);
}
// mark addr as having been seen as data
void MarkAddr(int addr_)
{
ushort addr = (ushort)addr_;
Mark(addr, CDLUsage.Data);
}
// convert address to zero-page, then mark as data
void MarkZP(int addr_)
{
ushort addr = (ushort)(addr_ & 0xff | 0x2000);
Mark(addr, CDLUsage.Data);
}
// convert address to zero-page, then return the pointer stored there
ushort GetIndirect(int addr_)
{
ushort addr = (ushort)(addr_ & 0xff | 0x2000);
return ReadWordPageWrap(addr);
}
// convert address to zero-page, then mark as pointer (two bytes)
void MarkZPPtr(int addr_)
{
ushort addr = (ushort)(addr_ & 0xff | 0x2000);
ushort addr2 = (ushort)(addr & 0xff00 | (addr + 1) & 0x00ff);
Mark(addr, CDLUsage.DataPtr);
Mark(addr2, CDLUsage.DataPtr);
}
// mark address as destination data of an indirect pointer
void MarkIndirect(int addr_)
{
ushort addr = (ushort)addr_;
Mark(addr, CDLUsage.IndirectData);
}
// mark stack space
void MarkPush(int n)
{
for (int i = 0; i < n; i++)
{
ushort addr = (ushort)(S - i);
Mark(addr, CDLUsage.Stack);
}
}
void MarkPop(int n)
{
for (int i = 0; i < n; i++)
{
ushort addr = (ushort)(S + i + 1);
Mark(addr, CDLUsage.Stack);
}
}
// mark addr as function pointer (2 bytes)
void MarkFptr(int addr_)
{
ushort addr = (ushort)addr_;
ushort addr2 = (ushort)(addr & 0xff00 | (addr + 1) & 0x00ff);
Mark(addr, CDLUsage.FcnPtr);
Mark(addr2, CDLUsage.FcnPtr);
}
// block transfer "from"
void MarkBTFrom(int addr_)
{
ushort addr = (ushort)addr_;
Mark(addr, CDLUsage.BlockFrom);
}
// block transfer "to"
void MarkBTTo(int addr_)
{
ushort addr = (ushort)addr_;
Mark(addr, CDLUsage.BlockTo);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BizHawk.Emulation.Cores.Components.H6280;
namespace BizHawk.Emulation.Cores.PCEngine
{
partial class PCEngine
{
static void CDLMappingApplyRange(HuC6280.MemMapping[] mm, string name, int block, int len)
{
for (int i = block, offs = 0; i < 256 && len > offs; i++, offs += 8192)
{
mm[i].Name = name;
mm[i].Offs = offs;
}
}
/// <summary>
/// informs the CPU of the general memory layout, so it can do CDL
/// </summary>
void InitCDLMappings()
{
// todo: arcade card
var mm = new HuC6280.MemMapping[256];
CDLMappingApplyRange(mm, "ROM", 0x00, RomLength);
if (PopulousRAM != null)
CDLMappingApplyRange(mm, "Populous RAM", 0x40, PopulousRAM.Length);
if (SuperRam != null)
CDLMappingApplyRange(mm, "Super RAM", 0x68, SuperRam.Length);
if (CDRam != null)
CDLMappingApplyRange(mm, "CD RAM", 0x80, CDRam.Length);
if (BRAM != null)
CDLMappingApplyRange(mm, "BRAM", 0xf7, BRAM.Length);
{
var rammirrors = new HuC6280.MemMapping { Name = "RAM", Offs = 0 };
mm[0xf9] = mm[0xfa] = mm[0xfb] = rammirrors;
}
CDLMappingApplyRange(mm, "RAM", 0xf8, Ram.Length);
mm[0xff] = new HuC6280.MemMapping { Name = "MMIO", Offs = 0 };
for (int i = 0; i < 256; i++)
{
if (mm[i].Name == null)
mm[i].Name = "UNKNOWN";
}
Cpu.Mappings = mm;
}
}
}

View File

@ -61,4 +61,4 @@ namespace BizHawk.Emulation.Cores.PCEngine
Log.Error("MEM", "UNHANDLED WRITE: {0:X6}:{1:X2}", addr, value);
}
}
}
}

View File

@ -66,4 +66,4 @@ namespace BizHawk.Emulation.Cores.PCEngine
Log.Error("MEM", "UNHANDLED WRITE: {0:X6}:{1:X2}", addr, value);
}
}
}
}

View File

@ -61,6 +61,7 @@
<Reference Include="System.Xml.Linq" />
</ItemGroup>
<ItemGroup>
<Compile Include="HuC6280\CDL.cs" />
<Compile Include="HuC6280\CoreGenerator.cs" />
<Compile Include="HuC6280\Instructions.cs" />
<Compile Include="MOS 6502\CoreGenerator.cs" />

View File

@ -0,0 +1,178 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace HuC6280
{
public partial class CoreGenerator
{
public void GenerateCDL(string file)
{
using (TextWriter w = new StreamWriter(file))
{
w.WriteLine("using System;");
w.WriteLine();
w.WriteLine("// Do not modify this file directly! This is GENERATED code.");
w.WriteLine("// Please open the CpuCoreGenerator solution and make your modifications there.");
w.WriteLine();
w.WriteLine("namespace BizHawk.Emulation.Cores.Components.H6280");
w.WriteLine("{");
w.WriteLine("\tpublic partial class HuC6280");
w.WriteLine("\t{");
w.WriteLine("\t\tvoid CDLOpcode()");
w.WriteLine("\t\t{");
w.WriteLine("\t\t\tbyte tmp8;");
w.WriteLine("\t\t\tbyte opcode = ReadMemory(PC);");
w.WriteLine("\t\t\tswitch (opcode)");
w.WriteLine("\t\t\t{");
for (int i = 0; i < 256; i++)
CDLOpcode(w, i);
w.WriteLine("\t\t\t}");
w.WriteLine("\t\t}");
w.WriteLine("\t}");
w.WriteLine("}");
}
}
void CDLOpcode(TextWriter w, int opcode)
{
// todo: T Flag
var op = Opcodes[opcode];
if (op == null)
{
// nop
w.WriteLine("\t\t\t\tcase 0x{0:X2}: // {1}", opcode, "??");
w.WriteLine("\t\t\t\t\tMarkCode(PC);");
w.WriteLine("\t\t\t\t\tbreak;");
return;
}
w.WriteLine("\t\t\t\tcase 0x{0:X2}: // {1}", opcode, op);
w.WriteLine("\t\t\t\t\tfor (int i = 0; i < {0}; i++)", op.Size);
w.WriteLine("\t\t\t\t\t\tMarkCode(PC + i);");
switch (op.AddressMode)
{
case AddrMode.Implicit:
switch (op.Instruction)
{
case "PHA": // push
case "PHP":
case "PHX":
case "PHY":
w.WriteLine("\t\t\t\t\tMarkPush(1);");
break;
case "PLA": // pop
case "PLP":
case "PLX":
case "PLY":
w.WriteLine("\t\t\t\t\tMarkPop(1);");
break;
case "RTI":
w.WriteLine("\t\t\t\t\tMarkPop(3);");
break;
case "RTS":
w.WriteLine("\t\t\t\t\tMarkPop(2);");
break;
}
break;
case AddrMode.Accumulator:
break;
case AddrMode.Immediate:
break;
case AddrMode.ZeroPage:
w.WriteLine("\t\t\t\t\tMarkZP(ReadMemory((ushort)(PC + 1)));");
break;
case AddrMode.ZeroPageX:
w.WriteLine("\t\t\t\t\tMarkZP(ReadMemory((ushort)(PC + 1)) + X);");
break;
case AddrMode.ZeroPageY:
w.WriteLine("\t\t\t\t\tMarkZP(ReadMemory((ushort)(PC + 1)) + Y);");
break;
case AddrMode.ZeroPageR:
w.WriteLine("\t\t\t\t\tMarkZP(ReadMemory((ushort)(PC + 1)));");
break;
case AddrMode.Absolute:
w.WriteLine("\t\t\t\t\tMarkAddr(ReadWord((ushort)(PC + 1)));");
break;
case AddrMode.AbsoluteX:
w.WriteLine("\t\t\t\t\tMarkAddr(ReadWord((ushort)(PC + 1)) + X);");
break;
case AddrMode.AbsoluteY:
w.WriteLine("\t\t\t\t\tMarkAddr(ReadWord((ushort)(PC + 1)) + Y);");
break;
case AddrMode.Indirect:
w.WriteLine("\t\t\t\t\ttmp8 = ReadMemory((ushort)(PC + 1));");
w.WriteLine("\t\t\t\t\tMarkZPPtr(tmp8);");
w.WriteLine("\t\t\t\t\tMarkIndirect(GetIndirect(tmp8));");
break;
case AddrMode.IndirectX:
w.WriteLine("\t\t\t\t\ttmp8 = (byte)(ReadMemory((ushort)(PC + 1)) + X);");
w.WriteLine("\t\t\t\t\tMarkZPPtr(tmp8);");
w.WriteLine("\t\t\t\t\tMarkIndirect(GetIndirect(tmp8));");
break;
case AddrMode.IndirectY:
w.WriteLine("\t\t\t\t\ttmp8 = ReadMemory((ushort)(PC + 1));");
w.WriteLine("\t\t\t\t\tMarkZPPtr(tmp8);");
w.WriteLine("\t\t\t\t\tMarkIndirect(GetIndirect(tmp8) + Y);");
break;
case AddrMode.Relative:
break;
case AddrMode.BlockMove:
w.WriteLine("\t\t\t\t\tif (!InBlockTransfer)");
w.WriteLine("\t\t\t\t\t{");
w.WriteLine("\t\t\t\t\t\tMarkBTFrom(ReadWord((ushort)(PC + 1)));");
w.WriteLine("\t\t\t\t\t\tMarkBTTo(ReadWord((ushort)(PC + 3)));");
w.WriteLine("\t\t\t\t\t}");
w.WriteLine("\t\t\t\t\telse");
w.WriteLine("\t\t\t\t\t{");
switch (op.Instruction)
{
case "TII":
case "TDD":
case "TIN":
w.WriteLine("\t\t\t\t\t\tMarkBTFrom(btFrom);");
w.WriteLine("\t\t\t\t\t\tMarkBTTo(btTo);");
break;
case "TIA":
w.WriteLine("\t\t\t\t\t\tMarkBTFrom(btFrom);");
w.WriteLine("\t\t\t\t\t\tMarkBTTo(btTo+btAlternator);");
break;
case "TAI":
w.WriteLine("\t\t\t\t\t\tMarkBTFrom(btFrom+btAlternator);");
w.WriteLine("\t\t\t\t\t\tMarkBTTo(btTo);");
break;
}
w.WriteLine("\t\t\t\t\t\t}");
break;
case AddrMode.ImmZeroPage:
w.WriteLine("\t\t\t\t\tMarkZP(ReadMemory((ushort)(PC + 2)));");
break;
case AddrMode.ImmZeroPageX:
w.WriteLine("\t\t\t\t\tMarkZP(ReadMemory((ushort)(PC + 2)) + X);");
break;
case AddrMode.ImmAbsolute:
w.WriteLine("\t\t\t\t\tMarkAddr(ReadWord((ushort)(PC + 2)));");
break;
case AddrMode.ImmAbsoluteX:
w.WriteLine("\t\t\t\t\tMarkAddr(ReadWord((ushort)(PC + 2)) + X);");
break;
case AddrMode.AbsoluteIndirect:
w.WriteLine("\t\t\t\t\tMarkFptr(ReadWord((ushort)(PC + 1)));");
break;
case AddrMode.AbsoluteIndirectX:
w.WriteLine("\t\t\t\t\tMarkFptr(ReadWord((ushort)(PC + 1)) + X);");
break;
}
w.WriteLine("\t\t\t\t\tbreak;");
}
}
}

View File

@ -12,5 +12,6 @@
y.InitOpcodeTable();
y.GenerateDisassembler("../../../BizHawk.Emulation.Cores/CPUs/HuC6280/Disassembler.cs");
y.GenerateExecutor("../../../BizHawk.Emulation.Cores/CPUs/HuC6280/Execute.cs");
y.GenerateCDL("../../../BizHawk.Emulation.Cores/CPUs/HuC6280/CDLOpcodes.cs");
}
}