PCE: some CDL stuff, not hooked up yet
This commit is contained in:
parent
8193e0b281
commit
522f6549ad
|
@ -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" />
|
||||
|
|
|
@ -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
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -61,4 +61,4 @@ namespace BizHawk.Emulation.Cores.PCEngine
|
|||
Log.Error("MEM", "UNHANDLED WRITE: {0:X6}:{1:X2}", addr, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,4 +66,4 @@ namespace BizHawk.Emulation.Cores.PCEngine
|
|||
Log.Error("MEM", "UNHANDLED WRITE: {0:X6}:{1:X2}", addr, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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;");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue