get rid of CpuCoreGenerator as it hasn't been used in a long time, the 6502 is commented out and isn't even the class used anymore, and the HuC6280 is very out of date, we don't do it this way anymore
This commit is contained in:
parent
9d4ef3a3af
commit
f5c5061681
|
@ -1,20 +0,0 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual Studio 2010
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CpuCoreGenerator", "CpuCoreGenerator\CpuCoreGenerator.csproj", "{ED25C59A-0A09-49ED-8CC1-9363576A83A7}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{ED25C59A-0A09-49ED-8CC1-9363576A83A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{ED25C59A-0A09-49ED-8CC1-9363576A83A7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{ED25C59A-0A09-49ED-8CC1-9363576A83A7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{ED25C59A-0A09-49ED-8CC1-9363576A83A7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -1,93 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{ED25C59A-0A09-49ED-8CC1-9363576A83A7}</ProjectGuid>
|
||||
<ProductVersion>9.0.21022</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<OutputType>Exe</OutputType>
|
||||
<NoStandardLibraries>false</NoStandardLibraries>
|
||||
<AssemblyName>CpuCoreGenerator</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<RootNamespace>CpuCoreGenerator</RootNamespace>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<OldToolsVersion>3.5</OldToolsVersion>
|
||||
<UpgradeBackupLocation />
|
||||
<TargetFrameworkProfile />
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="System.Xml" />
|
||||
<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" />
|
||||
<Compile Include="MOS 6502\Instructions.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>Windows Installer 3.1</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
|
||||
<ProjectExtensions>
|
||||
<VisualStudio AllowExistingFolder="true" />
|
||||
</ProjectExtensions>
|
||||
</Project>
|
|
@ -1,177 +0,0 @@
|
|||
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, 1);");
|
||||
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\tMarkCode(PC, {0});", op.Size);
|
||||
|
||||
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;");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,839 +0,0 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace HuC6280
|
||||
{
|
||||
public enum AddrMode
|
||||
{
|
||||
Implicit,
|
||||
Accumulator,
|
||||
Immediate,
|
||||
ZeroPage,
|
||||
ZeroPageX,
|
||||
ZeroPageY,
|
||||
ZeroPageR,
|
||||
Absolute,
|
||||
AbsoluteX,
|
||||
AbsoluteY,
|
||||
AbsoluteIndirect,
|
||||
AbsoluteIndirectX,
|
||||
Indirect,
|
||||
IndirectX,
|
||||
IndirectY,
|
||||
Relative,
|
||||
BlockMove,
|
||||
ImmZeroPage,
|
||||
ImmZeroPageX,
|
||||
ImmAbsolute,
|
||||
ImmAbsoluteX
|
||||
}
|
||||
|
||||
public class OpcodeInfo
|
||||
{
|
||||
public string Instruction;
|
||||
public AddrMode AddressMode;
|
||||
public int Cycles;
|
||||
|
||||
public int Size
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (AddressMode)
|
||||
{
|
||||
case AddrMode.Implicit: return 1;
|
||||
case AddrMode.Accumulator: return 1;
|
||||
case AddrMode.Immediate: return 2;
|
||||
case AddrMode.ZeroPage: return 2;
|
||||
case AddrMode.ZeroPageX: return 2;
|
||||
case AddrMode.ZeroPageY: return 2;
|
||||
case AddrMode.ZeroPageR: return 3;
|
||||
case AddrMode.Absolute: return 3;
|
||||
case AddrMode.AbsoluteX: return 3;
|
||||
case AddrMode.AbsoluteY: return 3;
|
||||
case AddrMode.Indirect: return 2;
|
||||
case AddrMode.IndirectX: return 2;
|
||||
case AddrMode.IndirectY: return 2;
|
||||
case AddrMode.Relative: return 2;
|
||||
case AddrMode.BlockMove: return 7;
|
||||
case AddrMode.ImmZeroPage: return 3;
|
||||
case AddrMode.ImmZeroPageX:return 3;
|
||||
case AddrMode.ImmAbsolute: return 4;
|
||||
case AddrMode.ImmAbsoluteX:return 4;
|
||||
case AddrMode.AbsoluteIndirect: return 3;
|
||||
case AddrMode.AbsoluteIndirectX: return 3;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
switch (AddressMode)
|
||||
{
|
||||
case AddrMode.Implicit: return Instruction;
|
||||
case AddrMode.Accumulator: return Instruction + " A";
|
||||
case AddrMode.Immediate: return Instruction + " #nn";
|
||||
case AddrMode.ZeroPage: return Instruction + " zp";
|
||||
case AddrMode.ZeroPageX: return Instruction + " zp,X";
|
||||
case AddrMode.ZeroPageY: return Instruction + " zp,Y";
|
||||
case AddrMode.Absolute: return Instruction + " addr";
|
||||
case AddrMode.AbsoluteX: return Instruction + " addr,X";
|
||||
case AddrMode.AbsoluteY: return Instruction + " addr,Y";
|
||||
case AddrMode.Indirect: return Instruction + " (addr)";
|
||||
case AddrMode.IndirectX: return Instruction + " (addr,X)";
|
||||
case AddrMode.IndirectY: return Instruction + " (addr),Y";
|
||||
case AddrMode.Relative: return Instruction + " +/-rel";
|
||||
case AddrMode.BlockMove: return Instruction + " src, dest, len";
|
||||
default: return Instruction;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public partial class CoreGenerator
|
||||
{
|
||||
public OpcodeInfo[] Opcodes = new OpcodeInfo[256];
|
||||
|
||||
public void InitOpcodeTable()
|
||||
{
|
||||
// Add with Carry
|
||||
Set(0x69, "ADC", AddrMode.Immediate, 2);
|
||||
Set(0x65, "ADC", AddrMode.ZeroPage, 4);
|
||||
Set(0x75, "ADC", AddrMode.ZeroPageX, 4);
|
||||
Set(0x6D, "ADC", AddrMode.Absolute, 5);
|
||||
Set(0x7D, "ADC", AddrMode.AbsoluteX, 5);
|
||||
Set(0x79, "ADC", AddrMode.AbsoluteY, 5);
|
||||
Set(0x72, "ADC", AddrMode.Indirect, 7);
|
||||
Set(0x61, "ADC", AddrMode.IndirectX, 7);
|
||||
Set(0x71, "ADC", AddrMode.IndirectY, 7);
|
||||
|
||||
// AND
|
||||
Set(0x29, "AND", AddrMode.Immediate, 2);
|
||||
Set(0x25, "AND", AddrMode.ZeroPage, 4);
|
||||
Set(0x35, "AND", AddrMode.ZeroPageX, 4);
|
||||
Set(0x2D, "AND", AddrMode.Absolute, 5);
|
||||
Set(0x3D, "AND", AddrMode.AbsoluteX, 5);
|
||||
Set(0x39, "AND", AddrMode.AbsoluteY, 5);
|
||||
Set(0x32, "AND", AddrMode.Indirect, 7);
|
||||
Set(0x21, "AND", AddrMode.IndirectX, 7);
|
||||
Set(0x31, "AND", AddrMode.IndirectY, 7);
|
||||
|
||||
// Arithmatic Shift Left
|
||||
Set(0x06, "ASL", AddrMode.ZeroPage, 6);
|
||||
Set(0x16, "ASL", AddrMode.ZeroPageX, 6);
|
||||
Set(0x0E, "ASL", AddrMode.Absolute, 7);
|
||||
Set(0x1E, "ASL", AddrMode.AbsoluteX, 7);
|
||||
Set(0x0A, "ASL", AddrMode.Accumulator, 2);
|
||||
|
||||
// Branch on Bit Reset
|
||||
Set(0x0F, "BBR0", AddrMode.ZeroPageR, 6);
|
||||
Set(0x1F, "BBR1", AddrMode.ZeroPageR, 6);
|
||||
Set(0x2F, "BBR2", AddrMode.ZeroPageR, 6);
|
||||
Set(0x3F, "BBR3", AddrMode.ZeroPageR, 6);
|
||||
Set(0x4F, "BBR4", AddrMode.ZeroPageR, 6);
|
||||
Set(0x5F, "BBR5", AddrMode.ZeroPageR, 6);
|
||||
Set(0x6F, "BBR6", AddrMode.ZeroPageR, 6);
|
||||
Set(0x7F, "BBR7", AddrMode.ZeroPageR, 6);
|
||||
|
||||
// Branch on Bit Set
|
||||
Set(0x8F, "BBS0", AddrMode.ZeroPageR, 6);
|
||||
Set(0x9F, "BBS1", AddrMode.ZeroPageR, 6);
|
||||
Set(0xAF, "BBS2", AddrMode.ZeroPageR, 6);
|
||||
Set(0xBF, "BBS3", AddrMode.ZeroPageR, 6);
|
||||
Set(0xCF, "BBS4", AddrMode.ZeroPageR, 6);
|
||||
Set(0xDF, "BBS5", AddrMode.ZeroPageR, 6);
|
||||
Set(0xEF, "BBS6", AddrMode.ZeroPageR, 6);
|
||||
Set(0xFF, "BBS7", AddrMode.ZeroPageR, 6);
|
||||
|
||||
// BIT
|
||||
Set(0x89, "BIT", AddrMode.Immediate, 2);
|
||||
Set(0x24, "BIT", AddrMode.ZeroPage, 4);
|
||||
Set(0x34, "BIT", AddrMode.ZeroPageX, 4);
|
||||
Set(0x2C, "BIT", AddrMode.Absolute, 5);
|
||||
Set(0x3C, "BIT", AddrMode.AbsoluteX, 5);
|
||||
|
||||
// Branch instructions
|
||||
Set(0x10, "BPL", AddrMode.Relative, 2); // Branch on Plus
|
||||
Set(0x30, "BMI", AddrMode.Relative, 2); // Branch on Minus
|
||||
Set(0x50, "BVC", AddrMode.Relative, 2); // Branch on Overflow Clear
|
||||
Set(0x70, "BVS", AddrMode.Relative, 2); // Branch on Overflow Set
|
||||
Set(0x90, "BCC", AddrMode.Relative, 2); // Branch on Carry Clear
|
||||
Set(0xB0, "BCS", AddrMode.Relative, 2); // Branch on Carry Set
|
||||
Set(0xD0, "BNE", AddrMode.Relative, 2); // Branch on Not Equal
|
||||
Set(0xF0, "BEQ", AddrMode.Relative, 2); // Branch on Equal
|
||||
Set(0x80, "BRA", AddrMode.Relative, 4); // Branch Always
|
||||
Set(0x44, "BSR", AddrMode.Relative, 8); // Branch to Subroutine
|
||||
|
||||
// CPU Break
|
||||
Set(0x00, "BRK", AddrMode.Implicit, 8);
|
||||
|
||||
// Compare accumulator
|
||||
Set(0xC9, "CMP", AddrMode.Immediate, 2);
|
||||
Set(0xC5, "CMP", AddrMode.ZeroPage, 4);
|
||||
Set(0xD5, "CMP", AddrMode.ZeroPageX, 4);
|
||||
Set(0xD2, "CMP", AddrMode.Indirect, 7);
|
||||
Set(0xC1, "CMP", AddrMode.IndirectX, 7);
|
||||
Set(0xD1, "CMP", AddrMode.IndirectY, 7);
|
||||
Set(0xCD, "CMP", AddrMode.Absolute, 5);
|
||||
Set(0xDD, "CMP", AddrMode.AbsoluteX, 5);
|
||||
Set(0xD9, "CMP", AddrMode.AbsoluteY, 5);
|
||||
|
||||
// Compare X register
|
||||
Set(0xE0, "CPX", AddrMode.Immediate, 2);
|
||||
Set(0xE4, "CPX", AddrMode.ZeroPage, 4);
|
||||
Set(0xEC, "CPX", AddrMode.Absolute, 5);
|
||||
|
||||
// Compare Y register
|
||||
Set(0xC0, "CPY", AddrMode.Immediate, 2);
|
||||
Set(0xC4, "CPY", AddrMode.ZeroPage, 4);
|
||||
Set(0xCC, "CPY", AddrMode.Absolute, 5);
|
||||
|
||||
// DEC
|
||||
Set(0xC6, "DEC", AddrMode.ZeroPage, 6);
|
||||
Set(0xD6, "DEC", AddrMode.ZeroPageX, 6);
|
||||
Set(0xCE, "DEC", AddrMode.Absolute, 7);
|
||||
Set(0xDE, "DEC", AddrMode.AbsoluteX, 7);
|
||||
Set(0x3A, "DEC", AddrMode.Accumulator, 2);
|
||||
|
||||
// Exclusive OR
|
||||
Set(0x49, "EOR", AddrMode.Immediate, 2);
|
||||
Set(0x45, "EOR", AddrMode.ZeroPage, 4);
|
||||
Set(0x55, "EOR", AddrMode.ZeroPageX, 4);
|
||||
Set(0x52, "EOR", AddrMode.Indirect, 7);
|
||||
Set(0x41, "EOR", AddrMode.IndirectX, 7);
|
||||
Set(0x51, "EOR", AddrMode.IndirectY, 7);
|
||||
Set(0x4D, "EOR", AddrMode.Absolute, 5);
|
||||
Set(0x5D, "EOR", AddrMode.AbsoluteX, 5);
|
||||
Set(0x59, "EOR", AddrMode.AbsoluteY, 5);
|
||||
|
||||
// Flag Instructions
|
||||
Set(0x18, "CLC", AddrMode.Implicit, 2); // Clear Carry
|
||||
Set(0x38, "SEC", AddrMode.Implicit, 2); // Set Carry
|
||||
Set(0x58, "CLI", AddrMode.Implicit, 2); // Clear Interrupt
|
||||
Set(0x78, "SEI", AddrMode.Implicit, 2); // Set Interrupt
|
||||
Set(0xB8, "CLV", AddrMode.Implicit, 2); // Clear Overflow
|
||||
Set(0xD8, "CLD", AddrMode.Implicit, 2); // Clear Decimal
|
||||
Set(0xF8, "SED", AddrMode.Implicit, 2); // Set Decimal
|
||||
Set(0xF4, "SET", AddrMode.Implicit, 2); // Set T flag
|
||||
|
||||
// Additional clear instructions
|
||||
Set(0x62, "CLA", AddrMode.Implicit, 2);
|
||||
Set(0x82, "CLX", AddrMode.Implicit, 2);
|
||||
Set(0xC2, "CLY", AddrMode.Implicit, 2);
|
||||
|
||||
// INC
|
||||
Set(0xE6, "INC", AddrMode.ZeroPage, 6);
|
||||
Set(0xF6, "INC", AddrMode.ZeroPageX, 6);
|
||||
Set(0xEE, "INC", AddrMode.Absolute, 7);
|
||||
Set(0xFE, "INC", AddrMode.AbsoluteX, 7);
|
||||
Set(0x1A, "INC", AddrMode.Accumulator, 2);
|
||||
|
||||
// Jump
|
||||
Set(0x4C, "JMP", AddrMode.Absolute, 4);
|
||||
Set(0x6C, "JMP", AddrMode.AbsoluteIndirect, 7);
|
||||
Set(0x7C, "JMP", AddrMode.AbsoluteIndirectX, 7);
|
||||
|
||||
// Jump to Subroutine
|
||||
Set(0x20, "JSR", AddrMode.Absolute, 7);
|
||||
|
||||
// Load Accumulator
|
||||
Set(0xA9, "LDA", AddrMode.Immediate, 2);
|
||||
Set(0xA5, "LDA", AddrMode.ZeroPage, 4);
|
||||
Set(0xB5, "LDA", AddrMode.ZeroPageX, 4);
|
||||
Set(0xB2, "LDA", AddrMode.Indirect, 7);
|
||||
Set(0xA1, "LDA", AddrMode.IndirectX, 7);
|
||||
Set(0xB1, "LDA", AddrMode.IndirectY, 7);
|
||||
Set(0xAD, "LDA", AddrMode.Absolute, 5);
|
||||
Set(0xBD, "LDA", AddrMode.AbsoluteX, 5);
|
||||
Set(0xB9, "LDA", AddrMode.AbsoluteY, 5);
|
||||
|
||||
// Load X register
|
||||
Set(0xA2, "LDX", AddrMode.Immediate, 2);
|
||||
Set(0xA6, "LDX", AddrMode.ZeroPage, 4);
|
||||
Set(0xB6, "LDX", AddrMode.ZeroPageY, 4);
|
||||
Set(0xAE, "LDX", AddrMode.Absolute, 5);
|
||||
Set(0xBE, "LDX", AddrMode.AbsoluteY, 5);
|
||||
|
||||
// Load Y register
|
||||
Set(0xA0, "LDY", AddrMode.Immediate, 2);
|
||||
Set(0xA4, "LDY", AddrMode.ZeroPage, 4);
|
||||
Set(0xB4, "LDY", AddrMode.ZeroPageX, 4);
|
||||
Set(0xAC, "LDY", AddrMode.Absolute, 5);
|
||||
Set(0xBC, "LDY", AddrMode.AbsoluteX, 5);
|
||||
|
||||
// Logical Shift Right
|
||||
Set(0x46, "LSR", AddrMode.ZeroPage, 6);
|
||||
Set(0x56, "LSR", AddrMode.ZeroPageX, 6);
|
||||
Set(0x4E, "LSR", AddrMode.Absolute, 7);
|
||||
Set(0x5E, "LSR", AddrMode.AbsoluteX, 7);
|
||||
Set(0x4A, "LSR", AddrMode.Accumulator, 2);
|
||||
|
||||
// No Operation
|
||||
Set(0xEA, "NOP", AddrMode.Implicit, 2);
|
||||
|
||||
// Bitwise OR with Accumulator
|
||||
Set(0x09, "ORA", AddrMode.Immediate, 2);
|
||||
Set(0x05, "ORA", AddrMode.ZeroPage, 4);
|
||||
Set(0x15, "ORA", AddrMode.ZeroPageX, 4);
|
||||
Set(0x12, "ORA", AddrMode.Indirect, 7);
|
||||
Set(0x01, "ORA", AddrMode.IndirectX, 7);
|
||||
Set(0x11, "ORA", AddrMode.IndirectY, 7);
|
||||
Set(0x0D, "ORA", AddrMode.Absolute, 5);
|
||||
Set(0x1D, "ORA", AddrMode.AbsoluteX, 5);
|
||||
Set(0x19, "ORA", AddrMode.AbsoluteY, 5);
|
||||
|
||||
// Register instructions
|
||||
Set(0xCA, "DEX", AddrMode.Implicit, 2); // DEC X
|
||||
Set(0x88, "DEY", AddrMode.Implicit, 2); // DEC Y
|
||||
Set(0xE8, "INX", AddrMode.Implicit, 2); // INC X
|
||||
Set(0xC8, "INY", AddrMode.Implicit, 2); // INC Y
|
||||
Set(0x22, "SAX", AddrMode.Implicit, 3); // Swap A and X
|
||||
Set(0x42, "SAY", AddrMode.Implicit, 3); // Swap A and Y
|
||||
Set(0x02, "SXY", AddrMode.Implicit, 3); // Swap X and Y
|
||||
Set(0xAA, "TAX", AddrMode.Implicit, 2); // Transfer A to X
|
||||
Set(0x8A, "TXA", AddrMode.Implicit, 2); // Transfer X to A
|
||||
Set(0xA8, "TAY", AddrMode.Implicit, 2); // Transfer A to Y
|
||||
Set(0x98, "TYA", AddrMode.Implicit, 2); // Transfer Y to A
|
||||
|
||||
// Rotate Left
|
||||
Set(0x26, "ROL", AddrMode.ZeroPage, 6);
|
||||
Set(0x36, "ROL", AddrMode.ZeroPageX, 6);
|
||||
Set(0x2E, "ROL", AddrMode.Absolute, 7);
|
||||
Set(0x3E, "ROL", AddrMode.AbsoluteX, 7);
|
||||
Set(0x2A, "ROL", AddrMode.Accumulator, 2);
|
||||
|
||||
// Rotate Right
|
||||
Set(0x66, "ROR", AddrMode.ZeroPage, 6);
|
||||
Set(0x76, "ROR", AddrMode.ZeroPageX, 6);
|
||||
Set(0x6E, "ROR", AddrMode.Absolute, 7);
|
||||
Set(0x7E, "ROR", AddrMode.AbsoluteX, 7);
|
||||
Set(0x6A, "ROR", AddrMode.Accumulator, 2);
|
||||
|
||||
// Return from Interrupt
|
||||
Set(0x40, "RTI", AddrMode.Implicit, 7);
|
||||
|
||||
// Return from Subroutine
|
||||
Set(0x60, "RTS", AddrMode.Implicit, 7);
|
||||
|
||||
// Subtract with Carry
|
||||
Set(0xE9, "SBC", AddrMode.Immediate, 2);
|
||||
Set(0xE5, "SBC", AddrMode.ZeroPage, 4);
|
||||
Set(0xF5, "SBC", AddrMode.ZeroPageX, 4);
|
||||
Set(0xF2, "SBC", AddrMode.Indirect, 7);
|
||||
Set(0xE1, "SBC", AddrMode.IndirectX, 7);
|
||||
Set(0xF1, "SBC", AddrMode.IndirectY, 7);
|
||||
Set(0xED, "SBC", AddrMode.Absolute, 5);
|
||||
Set(0xFD, "SBC", AddrMode.AbsoluteX, 5);
|
||||
Set(0xF9, "SBC", AddrMode.AbsoluteY, 5);
|
||||
|
||||
// Store Accumulator
|
||||
Set(0x85, "STA", AddrMode.ZeroPage, 4);
|
||||
Set(0x95, "STA", AddrMode.ZeroPageX, 4);
|
||||
Set(0x92, "STA", AddrMode.Indirect, 7);
|
||||
Set(0x81, "STA", AddrMode.IndirectX, 7);
|
||||
Set(0x91, "STA", AddrMode.IndirectY, 7);
|
||||
Set(0x8D, "STA", AddrMode.Absolute, 5);
|
||||
Set(0x9D, "STA", AddrMode.AbsoluteX, 5);
|
||||
Set(0x99, "STA", AddrMode.AbsoluteY, 5);
|
||||
|
||||
// Stack instructions
|
||||
Set(0x9A, "TXS", AddrMode.Implicit, 2); // Transfer X to Stack
|
||||
Set(0xBA, "TSX", AddrMode.Implicit, 2); // Transfer Stack to X
|
||||
Set(0x48, "PHA", AddrMode.Implicit, 3); // Push A
|
||||
Set(0x68, "PLA", AddrMode.Implicit, 4); // Pull A
|
||||
Set(0x08, "PHP", AddrMode.Implicit, 3); // Push P
|
||||
Set(0x28, "PLP", AddrMode.Implicit, 4); // Pull P
|
||||
Set(0xDA, "PHX", AddrMode.Implicit, 3); // Push X
|
||||
Set(0xFA, "PLX", AddrMode.Implicit, 4); // Pull X
|
||||
Set(0x5A, "PHY", AddrMode.Implicit, 3); // Push Y
|
||||
Set(0x7A, "PLY", AddrMode.Implicit, 4); // Pull Y
|
||||
|
||||
// Store X register
|
||||
Set(0x86, "STX", AddrMode.ZeroPage, 4);
|
||||
Set(0x96, "STX", AddrMode.ZeroPageY, 4);
|
||||
Set(0x8E, "STX", AddrMode.Absolute, 5);
|
||||
|
||||
// Store Y register
|
||||
Set(0x84, "STY", AddrMode.ZeroPage, 4);
|
||||
Set(0x94, "STY", AddrMode.ZeroPageX, 4);
|
||||
Set(0x8C, "STY", AddrMode.Absolute, 5);
|
||||
|
||||
// Memory Paging Register instructions
|
||||
Set(0x53, "TAM", AddrMode.Immediate, 5);
|
||||
Set(0x43, "TMA", AddrMode.Immediate, 4);
|
||||
|
||||
// VDC I/O instructions
|
||||
Set(0x03, "ST0", AddrMode.Immediate, 4);
|
||||
Set(0x13, "ST1", AddrMode.Immediate, 4);
|
||||
Set(0x23, "ST2", AddrMode.Immediate, 4);
|
||||
|
||||
// Store Memory To Zero
|
||||
Set(0x64, "STZ", AddrMode.ZeroPage, 4);
|
||||
Set(0x74, "STZ", AddrMode.ZeroPageX, 4);
|
||||
Set(0x9C, "STZ", AddrMode.Absolute, 5);
|
||||
Set(0x9E, "STZ", AddrMode.AbsoluteX, 5);
|
||||
|
||||
// Reset Memory Bit i
|
||||
Set(0x07, "RMB0", AddrMode.ZeroPage, 7);
|
||||
Set(0x17, "RMB1", AddrMode.ZeroPage, 7);
|
||||
Set(0x27, "RMB2", AddrMode.ZeroPage, 7);
|
||||
Set(0x37, "RMB3", AddrMode.ZeroPage, 7);
|
||||
Set(0x47, "RMB4", AddrMode.ZeroPage, 7);
|
||||
Set(0x57, "RMB5", AddrMode.ZeroPage, 7);
|
||||
Set(0x67, "RMB6", AddrMode.ZeroPage, 7);
|
||||
Set(0x77, "RMB7", AddrMode.ZeroPage, 7);
|
||||
|
||||
// Set Memory Bit i
|
||||
Set(0x87, "SMB0", AddrMode.ZeroPage, 7);
|
||||
Set(0x97, "SMB1", AddrMode.ZeroPage, 7);
|
||||
Set(0xA7, "SMB2", AddrMode.ZeroPage, 7);
|
||||
Set(0xB7, "SMB3", AddrMode.ZeroPage, 7);
|
||||
Set(0xC7, "SMB4", AddrMode.ZeroPage, 7);
|
||||
Set(0xD7, "SMB5", AddrMode.ZeroPage, 7);
|
||||
Set(0xE7, "SMB6", AddrMode.ZeroPage, 7);
|
||||
Set(0xF7, "SMB7", AddrMode.ZeroPage, 7);
|
||||
|
||||
// Test and Reset Memory Bit Against Accumulator
|
||||
Set(0x14, "TRB", AddrMode.ZeroPage, 6);
|
||||
Set(0x1C, "TRB", AddrMode.Absolute, 7);
|
||||
|
||||
// Test and Set Memory Bit Against Accumulator
|
||||
Set(0x04, "TSB", AddrMode.ZeroPage, 6);
|
||||
Set(0x0C, "TSB", AddrMode.Absolute, 7);
|
||||
|
||||
// Test and Reset Memory Bits
|
||||
Set(0x83, "TST", AddrMode.ImmZeroPage, 7);
|
||||
Set(0xA3, "TST", AddrMode.ImmZeroPageX, 7);
|
||||
Set(0x93, "TST", AddrMode.ImmAbsolute, 8);
|
||||
Set(0xB3, "TST", AddrMode.ImmAbsoluteX, 8);
|
||||
|
||||
// Cpu Speed instructions
|
||||
Set(0xD4, "CSH", AddrMode.Implicit, 3);
|
||||
Set(0x54, "CSL", AddrMode.Implicit, 3);
|
||||
|
||||
// Block Memory Transfer instructions
|
||||
Set(0xF3, "TAI", AddrMode.BlockMove, 17); // Transfer Alternate Increment
|
||||
Set(0xE3, "TIA", AddrMode.BlockMove, 17); // Transfer Increment Alternate
|
||||
Set(0x73, "TII", AddrMode.BlockMove, 17); // Transfer Increment Increment
|
||||
Set(0xD3, "TIN", AddrMode.BlockMove, 17); // Transfer Increment None
|
||||
Set(0xC3, "TDD", AddrMode.BlockMove, 17); // Transfer Decrement Decrement
|
||||
}
|
||||
|
||||
private void Set(byte value, string instr, AddrMode addressMode, int cycles)
|
||||
{
|
||||
var op = new OpcodeInfo();
|
||||
op.Instruction = instr;
|
||||
op.AddressMode = addressMode;
|
||||
op.Cycles = cycles;
|
||||
if (Opcodes[value] != null)
|
||||
throw new Exception("opcode " + value + " already assigned");
|
||||
Opcodes[value] = op;
|
||||
}
|
||||
|
||||
public void GenerateExecutor(string file)
|
||||
{
|
||||
var w = new StreamWriter(file, false);
|
||||
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(" public partial class HuC6280");
|
||||
w.WriteLine(" {");
|
||||
w.WriteLine(" public bool Debug;");
|
||||
w.WriteLine(" public Action<string> Logger;");
|
||||
w.WriteLine();
|
||||
w.WriteLine(" public void Execute(int cycles)");
|
||||
w.WriteLine(" {");
|
||||
w.WriteLine(" sbyte rel8;");
|
||||
w.WriteLine(" byte value8, temp8, source8;");
|
||||
w.WriteLine(" ushort value16, temp16;");
|
||||
w.WriteLine(" int temp, lo, hi;");
|
||||
w.WriteLine();
|
||||
w.WriteLine(" PendingCycles += cycles;");
|
||||
w.WriteLine(" while (PendingCycles > 0)");
|
||||
w.WriteLine(" {");
|
||||
w.WriteLine(" int lastCycles = PendingCycles;");
|
||||
w.WriteLine();
|
||||
w.WriteLine(" if (IRQ1Assert && FlagI == false && LagIFlag == false && (IRQControlByte & IRQ1Selector) == 0 && InBlockTransfer == false)");
|
||||
w.WriteLine(" {");
|
||||
w.WriteLine(" WriteMemory((ushort)(S-- + 0x2100), (byte)(PC >> 8));");
|
||||
w.WriteLine(" WriteMemory((ushort)(S-- + 0x2100), (byte)PC);");
|
||||
w.WriteLine(" WriteMemory((ushort)(S-- + 0x2100), (byte)(P & (~0x10)));");
|
||||
w.WriteLine(" FlagD = false;");
|
||||
w.WriteLine(" FlagI = true;");
|
||||
w.WriteLine(" PC = ReadWord(IRQ1Vector);");
|
||||
w.WriteLine(" PendingCycles -= 8;");
|
||||
w.WriteLine(" }");
|
||||
w.WriteLine();
|
||||
w.WriteLine(" if (TimerAssert && FlagI == false && LagIFlag == false && (IRQControlByte & TimerSelector) == 0 && InBlockTransfer == false)");
|
||||
w.WriteLine(" {");
|
||||
w.WriteLine(" WriteMemory((ushort)(S-- + 0x2100), (byte)(PC >> 8));");
|
||||
w.WriteLine(" WriteMemory((ushort)(S-- + 0x2100), (byte)PC);");
|
||||
w.WriteLine(" WriteMemory((ushort)(S-- + 0x2100), (byte)(P & (~0x10)));");
|
||||
w.WriteLine(" FlagD = false;");
|
||||
w.WriteLine(" FlagI = true;");
|
||||
w.WriteLine(" PC = ReadWord(TimerVector);");
|
||||
w.WriteLine(" PendingCycles -= 8;");
|
||||
w.WriteLine(" }");
|
||||
w.WriteLine();
|
||||
w.WriteLine(" if (IRQ2Assert && FlagI == false && LagIFlag == false && (IRQControlByte & IRQ2Selector) == 0 && InBlockTransfer == false)");
|
||||
w.WriteLine(" {");
|
||||
w.WriteLine(" WriteMemory((ushort)(S-- + 0x2100), (byte)(PC >> 8));");
|
||||
w.WriteLine(" WriteMemory((ushort)(S-- + 0x2100), (byte)PC);");
|
||||
w.WriteLine(" WriteMemory((ushort)(S-- + 0x2100), (byte)(P & (~0x10)));");
|
||||
w.WriteLine(" FlagD = false;");
|
||||
w.WriteLine(" FlagI = true;");
|
||||
w.WriteLine(" PC = ReadWord(IRQ2Vector);");
|
||||
w.WriteLine(" PendingCycles -= 8;");
|
||||
w.WriteLine(" }");
|
||||
w.WriteLine();
|
||||
w.WriteLine(" IRQControlByte = IRQNextControlByte;");
|
||||
w.WriteLine(" LagIFlag = FlagI;");
|
||||
w.WriteLine();
|
||||
w.WriteLine(" if (Debug) Logger(State());");
|
||||
w.WriteLine(" MemoryCallbacks.CallExecutes(PC);");
|
||||
w.WriteLine(" if (CDLLoggingActive) CDLOpcode();");
|
||||
w.WriteLine();
|
||||
w.WriteLine(" byte opcode = ReadMemory(PC++);");
|
||||
w.WriteLine(" switch (opcode)");
|
||||
w.WriteLine(" {");
|
||||
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
if (Opcodes[i] != null)
|
||||
EmulateOpcode(w, i);
|
||||
}
|
||||
|
||||
w.WriteLine(" default:");
|
||||
w.WriteLine(" Console.WriteLine(\"Unhandled opcode: {0:X2}\", opcode);");
|
||||
w.WriteLine(" break;");
|
||||
w.WriteLine(" }");
|
||||
w.WriteLine();
|
||||
w.WriteLine(" P &= 0xDF; // Clear T flag");
|
||||
w.WriteLine(" AfterClearTFlag: // SET command jumps here");
|
||||
w.WriteLine(" int delta = lastCycles - PendingCycles;");
|
||||
w.WriteLine(" if (LowSpeed)");
|
||||
w.WriteLine(" {");
|
||||
w.WriteLine(" delta *= 4;");
|
||||
w.WriteLine(" PendingCycles = lastCycles - delta;");
|
||||
w.WriteLine(" }");
|
||||
w.WriteLine(" TotalExecutedCycles += delta;");
|
||||
w.WriteLine();
|
||||
w.WriteLine(" if (TimerEnabled)");
|
||||
w.WriteLine(" {");
|
||||
w.WriteLine(" TimerTickCounter += delta;");
|
||||
w.WriteLine(" while (TimerTickCounter >= 1024)");
|
||||
w.WriteLine(" {");
|
||||
w.WriteLine(" TimerValue--;");
|
||||
w.WriteLine(" TimerTickCounter -= 1024;");
|
||||
w.WriteLine(" if (TimerValue == 0xFF)");
|
||||
w.WriteLine(" {");
|
||||
w.WriteLine(" TimerValue = TimerReloadValue;");
|
||||
w.WriteLine(" TimerAssert = true;");
|
||||
w.WriteLine(" }");
|
||||
w.WriteLine(" }");
|
||||
w.WriteLine(" }");
|
||||
w.WriteLine(" ThinkAction(delta);");
|
||||
w.WriteLine(" }");
|
||||
w.WriteLine(" }");
|
||||
w.WriteLine(" }");
|
||||
w.WriteLine("}");
|
||||
w.Close();
|
||||
}
|
||||
|
||||
const string Spaces = " ";
|
||||
|
||||
private void EmulateOpcode(TextWriter w, int opcode)
|
||||
{
|
||||
var op = Opcodes[opcode];
|
||||
w.WriteLine(" case 0x{0:X2}: // {1}", opcode, op);
|
||||
switch (op.Instruction)
|
||||
{
|
||||
case "ADC": ADC(op, w); break;
|
||||
case "AND": AND(op, w); break;
|
||||
case "ASL": ASL(op, w); break;
|
||||
case "BBR0": BB(op, w, 0, false); break;
|
||||
case "BBR1": BB(op, w, 1, false); break;
|
||||
case "BBR2": BB(op, w, 2, false); break;
|
||||
case "BBR3": BB(op, w, 3, false); break;
|
||||
case "BBR4": BB(op, w, 4, false); break;
|
||||
case "BBR5": BB(op, w, 5, false); break;
|
||||
case "BBR6": BB(op, w, 6, false); break;
|
||||
case "BBR7": BB(op, w, 7, false); break;
|
||||
case "BBS0": BB(op, w, 0, true); break;
|
||||
case "BBS1": BB(op, w, 1, true); break;
|
||||
case "BBS2": BB(op, w, 2, true); break;
|
||||
case "BBS3": BB(op, w, 3, true); break;
|
||||
case "BBS4": BB(op, w, 4, true); break;
|
||||
case "BBS5": BB(op, w, 5, true); break;
|
||||
case "BBS6": BB(op, w, 6, true); break;
|
||||
case "BBS7": BB(op, w, 7, true); break;
|
||||
case "BCC": Branch(op, w, "C", false); break;
|
||||
case "BCS": Branch(op, w, "C", true); break;
|
||||
case "BEQ": Branch(op, w, "Z", true); break;
|
||||
case "BIT": BIT(op, w); break;
|
||||
case "BMI": Branch(op, w, "N", true); break;
|
||||
case "BNE": Branch(op, w, "Z", false); break;
|
||||
case "BPL": Branch(op, w, "N", false); break;
|
||||
case "BRA": BRA(op, w); break;
|
||||
case "BRK": BRK(op, w); break;
|
||||
case "BSR": BSR(op, w); break;
|
||||
case "BVC": Branch(op, w, "V", false); break;
|
||||
case "BVS": Branch(op, w, "V", true); break;
|
||||
case "CLA": CLreg(op, w, "A"); break;
|
||||
case "CLC": CLC(op, w); break;
|
||||
case "CLD": CLD(op, w); break;
|
||||
case "CLI": CLI(op, w); break;
|
||||
case "CLV": CLV(op, w); break;
|
||||
case "CLX": CLreg(op, w, "X"); break;
|
||||
case "CLY": CLreg(op, w, "Y"); break;
|
||||
case "CMP": CMP_reg(op, w, "A"); break;
|
||||
case "CPX": CMP_reg(op, w, "X"); break;
|
||||
case "CPY": CMP_reg(op, w, "Y"); break;
|
||||
case "CSH": CSH(op, w); break;
|
||||
case "CSL": CSL(op, w); break;
|
||||
case "DEC": DEC(op, w); break;
|
||||
case "DEX": DEX(op, w); break;
|
||||
case "DEY": DEY(op, w); break;
|
||||
case "EOR": EOR(op, w); break;
|
||||
case "INC": INC(op, w); break;
|
||||
case "INX": INX(op, w); break;
|
||||
case "INY": INY(op, w); break;
|
||||
case "JMP": JMP(op, w); break;
|
||||
case "JSR": JSR(op, w); break;
|
||||
case "LDA": LDA(op, w); break;
|
||||
case "LDX": LDX(op, w); break;
|
||||
case "LDY": LDY(op, w); break;
|
||||
case "LSR": LSR(op, w); break;
|
||||
case "NOP": NOP(op, w); break;
|
||||
case "ORA": ORA(op, w); break;
|
||||
case "PHA": PushReg(op, w, "A"); break;
|
||||
case "PHP": PushReg(op, w, "P"); break;
|
||||
case "PHX": PushReg(op, w, "X"); break;
|
||||
case "PHY": PushReg(op, w, "Y"); break;
|
||||
case "PLA": PullReg(op, w, "A"); break;
|
||||
case "PLP": PLP(op, w); break;
|
||||
case "PLX": PullReg(op, w, "X"); break;
|
||||
case "PLY": PullReg(op, w, "Y"); break;
|
||||
case "ROL": ROL(op, w); break;
|
||||
case "ROR": ROR(op, w); break;
|
||||
case "RTI": RTI(op, w); break;
|
||||
case "RTS": RTS(op, w); break;
|
||||
case "SAX": SAX(op, w); break;
|
||||
case "SAY": SAY(op, w); break;
|
||||
case "SBC": SBC(op, w); break;
|
||||
case "SEC": SEC(op, w); break;
|
||||
case "SED": SED(op, w); break;
|
||||
case "SEI": SEI(op, w); break;
|
||||
case "SET": SET(op, w); break;
|
||||
case "SXY": SXY(op, w); break;
|
||||
case "ST0": ST0(op, w); break;
|
||||
case "ST1": ST1(op, w); break;
|
||||
case "ST2": ST2(op, w); break;
|
||||
case "STA": STA(op, w); break;
|
||||
case "STX": STX(op, w); break;
|
||||
case "STY": STY(op, w); break;
|
||||
case "STZ": STZ(op, w); break;
|
||||
case "TAI": TAI(op, w); break;
|
||||
case "TAM": TAM(op, w); break;
|
||||
case "TAX": TAX(op, w); break;
|
||||
case "TAY": TAY(op, w); break;
|
||||
case "TDD": TDD(op, w); break;
|
||||
case "TIA": TIA(op, w); break;
|
||||
case "TII": TII(op, w); break;
|
||||
case "TIN": TIN(op, w); break;
|
||||
case "TMA": TMA(op, w); break;
|
||||
case "TRB": TRB(op, w); break;
|
||||
case "TSB": TSB(op, w); break;
|
||||
case "TST": TST(op, w); break;
|
||||
case "TSX": TSX(op, w); break;
|
||||
case "TXA": TXA(op, w); break;
|
||||
case "TYA": TYA(op, w); break;
|
||||
case "TXS": TXS(op, w); break;
|
||||
case "RMB0": RMB(op, w, 0); break;
|
||||
case "RMB1": RMB(op, w, 1); break;
|
||||
case "RMB2": RMB(op, w, 2); break;
|
||||
case "RMB3": RMB(op, w, 3); break;
|
||||
case "RMB4": RMB(op, w, 4); break;
|
||||
case "RMB5": RMB(op, w, 5); break;
|
||||
case "RMB6": RMB(op, w, 6); break;
|
||||
case "RMB7": RMB(op, w, 7); break;
|
||||
case "SMB0": SMB(op, w, 0); break;
|
||||
case "SMB1": SMB(op, w, 1); break;
|
||||
case "SMB2": SMB(op, w, 2); break;
|
||||
case "SMB3": SMB(op, w, 3); break;
|
||||
case "SMB4": SMB(op, w, 4); break;
|
||||
case "SMB5": SMB(op, w, 5); break;
|
||||
case "SMB6": SMB(op, w, 6); break;
|
||||
case "SMB7": SMB(op, w, 7); break;
|
||||
default:
|
||||
w.WriteLine("throw new Exception(\"unsupported opcode {0:X2}\");",opcode);
|
||||
break;
|
||||
}
|
||||
if (op.Instruction != "SET" && op.Instruction != "RTI" && op.Instruction != "PLP")
|
||||
w.WriteLine(Spaces + "break;");
|
||||
}
|
||||
|
||||
private void GetValue8(OpcodeInfo op, TextWriter w, string dest)
|
||||
{
|
||||
switch (op.AddressMode)
|
||||
{
|
||||
case AddrMode.Immediate:
|
||||
w.WriteLine(Spaces + dest + " = ReadMemory(PC++);"); break;
|
||||
case AddrMode.ImmZeroPage:
|
||||
case AddrMode.ZeroPage:
|
||||
w.WriteLine(Spaces + dest + " = ReadMemory((ushort)(ReadMemory(PC++)+0x2000));"); break;
|
||||
case AddrMode.ImmZeroPageX:
|
||||
case AddrMode.ZeroPageX:
|
||||
w.WriteLine(Spaces + dest + " = ReadMemory((ushort)(((ReadMemory(PC++)+X)&0xFF)+0x2000));"); break;
|
||||
case AddrMode.ZeroPageY:
|
||||
w.WriteLine(Spaces + dest + " = ReadMemory((ushort)(((ReadMemory(PC++)+Y)&0xFF)+0x2000));"); break;
|
||||
case AddrMode.ImmAbsolute:
|
||||
case AddrMode.Absolute:
|
||||
w.WriteLine(Spaces + dest + " = ReadMemory(ReadWord(PC)); PC += 2;"); break;
|
||||
case AddrMode.ImmAbsoluteX:
|
||||
case AddrMode.AbsoluteX:
|
||||
w.WriteLine(Spaces + dest + " = ReadMemory((ushort)(ReadWord(PC)+X));");
|
||||
w.WriteLine(Spaces + "PC += 2;");
|
||||
break;
|
||||
case AddrMode.AbsoluteY:
|
||||
w.WriteLine(Spaces + dest + " = ReadMemory((ushort)(ReadWord(PC)+Y));");
|
||||
w.WriteLine(Spaces + "PC += 2;");
|
||||
break;
|
||||
case AddrMode.Indirect:
|
||||
w.WriteLine(Spaces + dest + " = ReadMemory(ReadWordPageWrap((ushort)(ReadMemory(PC++)+0x2000)));"); break;
|
||||
case AddrMode.IndirectX:
|
||||
w.WriteLine(Spaces + dest + " = ReadMemory(ReadWordPageWrap((ushort)((byte)(ReadMemory(PC++)+X)+0x2000)));"); break;
|
||||
case AddrMode.IndirectY:
|
||||
w.WriteLine(Spaces + "temp16 = ReadWordPageWrap((ushort)(ReadMemory(PC++)+0x2000));");
|
||||
w.WriteLine(Spaces + dest + " = ReadMemory((ushort)(temp16+Y));");
|
||||
break;
|
||||
default:
|
||||
throw new Exception("p"+op.Instruction);
|
||||
}
|
||||
}
|
||||
|
||||
private void GetAddress(OpcodeInfo op, TextWriter w, string dest)
|
||||
{
|
||||
switch (op.AddressMode)
|
||||
{
|
||||
case AddrMode.ZeroPage:
|
||||
w.WriteLine(Spaces + dest + " = (ushort)(ReadMemory(PC++)+0x2000);"); break;
|
||||
case AddrMode.ZeroPageX:
|
||||
w.WriteLine(Spaces + dest + " = (ushort)(((ReadMemory(PC++)+X)&0xFF)+0x2000);"); break;
|
||||
case AddrMode.ZeroPageY:
|
||||
w.WriteLine(Spaces + dest + " = (ushort)(((ReadMemory(PC++)+Y)&0xFF)+0x2000);"); break;
|
||||
case AddrMode.Absolute:
|
||||
w.WriteLine(Spaces + dest + " = ReadWord(PC); PC += 2;"); break;
|
||||
case AddrMode.AbsoluteX:
|
||||
w.WriteLine(Spaces + dest + " = (ushort)(ReadWord(PC)+X);");
|
||||
w.WriteLine(Spaces + "PC += 2;");
|
||||
break;
|
||||
case AddrMode.AbsoluteY:
|
||||
w.WriteLine(Spaces + dest + " = (ushort)(ReadWord(PC)+Y);");
|
||||
w.WriteLine(Spaces + "PC += 2;");
|
||||
break;
|
||||
case AddrMode.Indirect:
|
||||
w.WriteLine(Spaces + dest + " = ReadWordPageWrap((ushort)(ReadMemory(PC++)+0x2000));"); break;
|
||||
case AddrMode.IndirectX:
|
||||
w.WriteLine(Spaces + dest + " = ReadWordPageWrap((ushort)((byte)(ReadMemory(PC++)+X)+0x2000));"); break;
|
||||
case AddrMode.IndirectY:
|
||||
w.WriteLine(Spaces + "temp16 = ReadWordPageWrap((ushort)(ReadMemory(PC++)+0x2000));");
|
||||
w.WriteLine(Spaces + dest + " = (ushort)(temp16+Y);");
|
||||
break;
|
||||
case AddrMode.Relative:
|
||||
w.WriteLine(Spaces + "rel8 = (sbyte)ReadMemory(PC++);");
|
||||
w.WriteLine(Spaces + dest + " = (ushort)(PC+rel8);");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void GenerateDisassembler(string file)
|
||||
{
|
||||
var w = new StreamWriter(file, false);
|
||||
w.WriteLine("using System;");
|
||||
w.WriteLine("namespace BizHawk.Emulation.Cores.Components.H6280");
|
||||
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("{");
|
||||
w.WriteLine(" public partial class HuC6280");
|
||||
w.WriteLine(" {");
|
||||
w.WriteLine(" public string Disassemble(ushort pc, out int bytesToAdvance)");
|
||||
w.WriteLine(" {");
|
||||
w.WriteLine(" byte op = ReadMemory(pc);");
|
||||
w.WriteLine(" switch (op)");
|
||||
w.WriteLine(" {");
|
||||
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
if (Opcodes[i] != null)
|
||||
DisassembleOpcode(w, i);
|
||||
}
|
||||
w.WriteLine(" }");
|
||||
w.WriteLine(" bytesToAdvance = 1;");
|
||||
w.WriteLine(" return \"???\";");
|
||||
w.WriteLine(" }");
|
||||
w.WriteLine();
|
||||
w.WriteLine(" // avoid slowing down the other disassembler");
|
||||
w.WriteLine(" public static string DisassembleExt(ushort pc, out int bytesToAdvance, Func<ushort, byte> ReadMemory, Func<ushort, ushort> ReadWord)");
|
||||
w.WriteLine(" {");
|
||||
w.WriteLine(" byte op = ReadMemory(pc);");
|
||||
w.WriteLine(" switch (op)");
|
||||
w.WriteLine(" {");
|
||||
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
if (Opcodes[i] != null)
|
||||
DisassembleOpcode(w, i);
|
||||
}
|
||||
w.WriteLine(" }");
|
||||
w.WriteLine(" bytesToAdvance = 1;");
|
||||
w.WriteLine(" return \"???\";");
|
||||
w.WriteLine(" }");
|
||||
w.WriteLine(" }");
|
||||
w.WriteLine("}");
|
||||
w.Close();
|
||||
}
|
||||
|
||||
private void DisassembleOpcode(TextWriter w, int i)
|
||||
{
|
||||
var op = Opcodes[i];
|
||||
w.Write(" case 0x{0:X2}: ", i);
|
||||
|
||||
string mstr;
|
||||
switch (op.AddressMode)
|
||||
{
|
||||
case AddrMode.Implicit: mstr = "\"" + op.Instruction + "\""; break;
|
||||
case AddrMode.Accumulator: mstr = "\"" + op.Instruction + " A\""; break;
|
||||
case AddrMode.Immediate: mstr = "string.Format(\"" + op.Instruction + " #${0:X2}\", ReadMemory(++pc))"; break;
|
||||
case AddrMode.ZeroPage: mstr = "string.Format(\"" + op.Instruction + " ${0:X2}\", ReadMemory(++pc))"; break;
|
||||
case AddrMode.ZeroPageX: mstr = "string.Format(\"" + op.Instruction + " ${0:X2},X\", ReadMemory(++pc))"; break;
|
||||
case AddrMode.ZeroPageY: mstr = "string.Format(\"" + op.Instruction + " ${0:X2},Y\", ReadMemory(++pc))"; break;
|
||||
case AddrMode.ZeroPageR: mstr = "string.Format(\"" + op.Instruction + " ${0:X2},{1}\", ReadMemory(++pc), (sbyte)ReadMemory(++pc))"; break;
|
||||
case AddrMode.Absolute: mstr = "string.Format(\"" + op.Instruction + " ${0:X4}\", ReadWord(++pc))"; break;
|
||||
case AddrMode.AbsoluteX: mstr = "string.Format(\"" + op.Instruction + " ${0:X4},X\", ReadWord(++pc))"; break;
|
||||
case AddrMode.AbsoluteY: mstr = "string.Format(\"" + op.Instruction + " ${0:X4},Y\", ReadWord(++pc))"; break;
|
||||
case AddrMode.Indirect: mstr = "string.Format(\"" + op.Instruction + " (${0:X2})\", ReadMemory(++pc))"; break;
|
||||
case AddrMode.IndirectX: mstr = "string.Format(\"" + op.Instruction + " (${0:X2},X)\", ReadMemory(++pc))"; break;
|
||||
case AddrMode.IndirectY: mstr = "string.Format(\"" + op.Instruction + " (${0:X2}),Y\", ReadMemory(++pc))"; break;
|
||||
case AddrMode.Relative: mstr = "string.Format(\"" + op.Instruction + " {0}\", (sbyte)ReadMemory(++pc))"; break;
|
||||
case AddrMode.BlockMove: mstr = "string.Format(\"" + op.Instruction + " {0:X4},{1:X4},{2:X4}\", ReadWord((ushort)(pc+1)),ReadWord((ushort)(pc+3)),ReadWord((ushort)(pc+5)))"; break;
|
||||
case AddrMode.ImmZeroPage: mstr = "string.Format(\"" + op.Instruction + " #${0:X2}, ${1:X2}\", ReadMemory(++pc), ReadMemory(++pc))"; break;
|
||||
case AddrMode.ImmZeroPageX: mstr = "string.Format(\"" + op.Instruction + " #${0:X2}, ${1:X2},X\", ReadMemory(++pc), ReadMemory(++pc))"; break;
|
||||
case AddrMode.ImmAbsolute: mstr = "string.Format(\"" + op.Instruction + " #${0:X2}, ${1:X4}\", ReadMemory(++pc), ReadWord(++pc))"; break;
|
||||
case AddrMode.ImmAbsoluteX: mstr = "string.Format(\"" + op.Instruction + " #${0:X2}, ${1:X4},X\", ReadMemory(++pc), ReadWord(++pc))"; break;
|
||||
case AddrMode.AbsoluteIndirect: mstr = "string.Format(\"" + op.Instruction + " (${0:X4})\", ReadWord(++pc))"; break;
|
||||
case AddrMode.AbsoluteIndirectX: mstr = "string.Format(\"" + op.Instruction + " (${0:X4},X)\", ReadWord(++pc))"; break;
|
||||
default: mstr = @"""?"""; break;
|
||||
}
|
||||
|
||||
w.Write("bytesToAdvance = {0}; ", op.Size);
|
||||
w.WriteLine("return " + mstr + ";");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,815 +0,0 @@
|
|||
using System.IO;
|
||||
|
||||
namespace HuC6280
|
||||
{
|
||||
public partial class CoreGenerator
|
||||
{
|
||||
private string SetNZ(string val)
|
||||
{
|
||||
return "P = (byte)((P & 0x7D) | TableNZ[" + val + "]);";
|
||||
}
|
||||
|
||||
private void ADC(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
GetValue8(op, w, "value8");
|
||||
w.WriteLine(Spaces + "source8 = FlagT ? ReadMemory((ushort)(0x2000 + X)) : A;");
|
||||
w.WriteLine();
|
||||
w.WriteLine(Spaces + "if ((P & 0x08) != 0) {");
|
||||
w.WriteLine(Spaces + " lo = (source8 & 0x0F) + (value8 & 0x0F) + (FlagC ? 1 : 0);");
|
||||
w.WriteLine(Spaces + " hi = (source8 & 0xF0) + (value8 & 0xF0);");
|
||||
w.WriteLine(Spaces + " if (lo > 0x09) {");
|
||||
w.WriteLine(Spaces + " hi += 0x10;");
|
||||
w.WriteLine(Spaces + " lo += 0x06;");
|
||||
w.WriteLine(Spaces + " }");
|
||||
w.WriteLine(Spaces + " if (hi > 0x90) hi += 0x60;");
|
||||
w.WriteLine(Spaces + " FlagV = (~(source8^value8) & (source8^hi) & 0x80) != 0;");
|
||||
w.WriteLine(Spaces + " FlagC = (hi & 0xFF00) != 0;");
|
||||
w.WriteLine(Spaces + " source8 = (byte) ((lo & 0x0F) | (hi & 0xF0));");
|
||||
w.WriteLine(Spaces + " PendingCycles--;");
|
||||
w.WriteLine(Spaces + "} else {");
|
||||
w.WriteLine(Spaces + " temp = value8 + source8 + (FlagC ? 1 : 0);");
|
||||
w.WriteLine(Spaces + " FlagV = (~(source8 ^ value8) & (source8 ^ temp) & 0x80) != 0;");
|
||||
w.WriteLine(Spaces + " FlagC = temp > 0xFF;");
|
||||
w.WriteLine(Spaces + " source8 = (byte)temp;");
|
||||
w.WriteLine(Spaces + "}");
|
||||
|
||||
w.WriteLine(Spaces + "if (FlagT == false)");
|
||||
w.WriteLine(Spaces + " A = source8;");
|
||||
w.WriteLine(Spaces + "else { ");
|
||||
w.WriteLine(Spaces + " WriteMemory((ushort)(0x2000 + X), source8);");
|
||||
w.WriteLine(Spaces + " PendingCycles -= 3;");
|
||||
w.WriteLine(Spaces + "}");
|
||||
w.WriteLine(Spaces + SetNZ("source8"));
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void AND(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
GetValue8(op, w, "value8");
|
||||
w.WriteLine(Spaces + "if (FlagT == false) { ");
|
||||
w.WriteLine(Spaces + " A &= value8;");
|
||||
w.WriteLine(Spaces + " " + SetNZ("A"));
|
||||
w.WriteLine(Spaces + " PendingCycles -= {0};", op.Cycles);
|
||||
w.WriteLine(Spaces + "} else {");
|
||||
w.WriteLine(Spaces + " temp8 = ReadMemory((ushort)(0x2000 + X));");
|
||||
w.WriteLine(Spaces + " temp8 &= value8;");
|
||||
w.WriteLine(Spaces + " " + SetNZ("temp8"));
|
||||
w.WriteLine(Spaces + " WriteMemory((ushort)(0x2000 + X), temp8);");
|
||||
w.WriteLine(Spaces + " PendingCycles -= {0};", op.Cycles + 3);
|
||||
w.WriteLine(Spaces + "}");
|
||||
}
|
||||
|
||||
private void ASL(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
if (op.AddressMode == AddrMode.Accumulator)
|
||||
{
|
||||
w.WriteLine(Spaces + "FlagC = (A & 0x80) != 0;");
|
||||
w.WriteLine(Spaces + "A = (byte) (A << 1);");
|
||||
w.WriteLine(Spaces + SetNZ("A"));
|
||||
}
|
||||
else
|
||||
{
|
||||
GetAddress(op, w, "value16");
|
||||
w.WriteLine(Spaces + "value8 = ReadMemory(value16);");
|
||||
w.WriteLine(Spaces + "FlagC = (value8 & 0x80) != 0;");
|
||||
w.WriteLine(Spaces + "value8 = (byte)(value8 << 1);");
|
||||
w.WriteLine(Spaces + "WriteMemory(value16, value8);");
|
||||
w.WriteLine(Spaces + SetNZ("value8"));
|
||||
}
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void BB(OpcodeInfo op, TextWriter w, int bit, bool set)
|
||||
{
|
||||
string filter = "";
|
||||
switch (bit)
|
||||
{
|
||||
case 0: filter = "0x01"; break;
|
||||
case 1: filter = "0x02"; break;
|
||||
case 2: filter = "0x04"; break;
|
||||
case 3: filter = "0x08"; break;
|
||||
case 4: filter = "0x10"; break;
|
||||
case 5: filter = "0x20"; break;
|
||||
case 6: filter = "0x40"; break;
|
||||
case 7: filter = "0x80"; break;
|
||||
}
|
||||
string cond = set ? "!=" : "==";
|
||||
|
||||
w.WriteLine(Spaces + "value8 = ReadMemory((ushort)(ReadMemory(PC++)+0x2000));");
|
||||
w.WriteLine(Spaces + "rel8 = (sbyte) ReadMemory(PC++);");
|
||||
w.WriteLine(Spaces + "if ((value8 & "+filter+") "+cond+" 0) {");
|
||||
w.WriteLine(Spaces + " PendingCycles -= 2;");
|
||||
w.WriteLine(Spaces + " PC = (ushort)(PC+rel8);");
|
||||
w.WriteLine(Spaces + "}");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void Branch(OpcodeInfo op, TextWriter w, string flag, bool cond)
|
||||
{
|
||||
GetAddress(op, w, "value16");
|
||||
w.WriteLine(Spaces + "if (Flag" + flag + " == " + cond.ToString().ToLower() + ") {");
|
||||
w.WriteLine(Spaces + " PendingCycles -= 2;");
|
||||
w.WriteLine(Spaces + " PC = value16;");
|
||||
w.WriteLine(Spaces + "}");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void BRA(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
GetAddress(op, w, "PC");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void BRK(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "Console.WriteLine(\"EXEC BRK\");");
|
||||
w.WriteLine(Spaces + "PC++;");
|
||||
w.WriteLine(Spaces + "WriteMemory((ushort)(S-- + 0x2100), (byte)(PC >> 8));");
|
||||
w.WriteLine(Spaces + "WriteMemory((ushort)(S-- + 0x2100), (byte)PC);");
|
||||
w.WriteLine(Spaces + "WriteMemory((ushort)(S-- + 0x2100), (byte)(P & (~0x10)));");
|
||||
w.WriteLine(Spaces + "FlagT = false;");
|
||||
w.WriteLine(Spaces + "FlagB = true;");
|
||||
w.WriteLine(Spaces + "FlagD = false;");
|
||||
w.WriteLine(Spaces + "FlagI = true;");
|
||||
w.WriteLine(Spaces + "PC = ReadWord(IRQ2Vector);");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void BSR(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
GetAddress(op, w, "value16");
|
||||
w.WriteLine(Spaces + "temp16 = (ushort)(PC-1);");
|
||||
w.WriteLine(Spaces + "WriteMemory((ushort)(S-- + 0x2100), (byte)(temp16 >> 8));");
|
||||
w.WriteLine(Spaces + "WriteMemory((ushort)(S-- + 0x2100), (byte)temp16);");
|
||||
w.WriteLine(Spaces + "PC = value16;");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void BIT(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
GetValue8(op, w, "value8");
|
||||
w.WriteLine(Spaces + "FlagN = (value8 & 0x80) != 0;");
|
||||
w.WriteLine(Spaces + "FlagV = (value8 & 0x40) != 0;");
|
||||
w.WriteLine(Spaces + "FlagZ = (A & value8) == 0;");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void CLC(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "FlagC = false;");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void CLD(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "FlagD = false;");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void CLI(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "FlagI = false;");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void CLV(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "FlagV = false;");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void CLreg(OpcodeInfo op, TextWriter w, string reg)
|
||||
{
|
||||
w.WriteLine(Spaces + "{0} = 0;",reg);
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void CMP_reg(OpcodeInfo op, TextWriter w, string reg)
|
||||
{
|
||||
GetValue8(op, w, "value8");
|
||||
w.WriteLine(Spaces + "value16 = (ushort) (" + reg + " - value8);");
|
||||
w.WriteLine(Spaces + "FlagC = (" + reg + " >= value8);");
|
||||
w.WriteLine(Spaces + SetNZ("(byte)value16"));
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void CSH(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "LowSpeed = false;");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void CSL(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "LowSpeed = true;");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void DEC(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
if (op.AddressMode != AddrMode.Accumulator)
|
||||
{
|
||||
GetAddress(op, w, "value16");
|
||||
w.WriteLine(Spaces + "value8 = (byte)(ReadMemory(value16) - 1);");
|
||||
w.WriteLine(Spaces + "WriteMemory(value16, value8);");
|
||||
w.WriteLine(Spaces + SetNZ("value8"));
|
||||
} else {
|
||||
w.WriteLine(Spaces + SetNZ("--A"));
|
||||
}
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void DEX(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + SetNZ("--X"));
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void DEY(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + SetNZ("--Y"));
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void EOR(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
GetValue8(op, w, "value8");
|
||||
w.WriteLine(Spaces + "if (FlagT == false) { ");
|
||||
w.WriteLine(Spaces + " A ^= value8;");
|
||||
w.WriteLine(Spaces + " "+SetNZ("A"));
|
||||
w.WriteLine(Spaces + " PendingCycles -= {0};", op.Cycles);
|
||||
w.WriteLine(Spaces + "} else {");
|
||||
w.WriteLine(Spaces + " temp8 = ReadMemory((ushort)(0x2000 + X));");
|
||||
w.WriteLine(Spaces + " temp8 ^= value8;");
|
||||
w.WriteLine(Spaces + " " + SetNZ("temp8"));
|
||||
w.WriteLine(Spaces + " WriteMemory((ushort)(0x2000 + X), temp8);");
|
||||
w.WriteLine(Spaces + " PendingCycles -= {0};", op.Cycles+3);
|
||||
w.WriteLine(Spaces + "}");
|
||||
}
|
||||
|
||||
private void INC(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
if (op.AddressMode != AddrMode.Accumulator)
|
||||
{
|
||||
GetAddress(op, w, "value16");
|
||||
w.WriteLine(Spaces + "value8 = (byte)(ReadMemory(value16) + 1);");
|
||||
w.WriteLine(Spaces + "WriteMemory(value16, value8);");
|
||||
w.WriteLine(Spaces + SetNZ("value8"));
|
||||
} else {
|
||||
w.WriteLine(Spaces + SetNZ("++A"));
|
||||
}
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void INX(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + SetNZ("++X"));
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void INY(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + SetNZ("++Y"));
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void JMP(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
switch (op.AddressMode)
|
||||
{
|
||||
case AddrMode.Absolute: w.WriteLine(Spaces + "PC = ReadWord(PC);"); break;
|
||||
case AddrMode.AbsoluteIndirect: w.WriteLine(Spaces + "PC = ReadWord(ReadWord(PC));"); break;
|
||||
case AddrMode.AbsoluteIndirectX: w.WriteLine(Spaces + "PC = ReadWord((ushort)(ReadWord(PC)+X));"); break;
|
||||
}
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void JSR(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "temp16 = (ushort)(PC+1);");
|
||||
w.WriteLine(Spaces + "WriteMemory((ushort)(S-- + 0x2100), (byte)(temp16 >> 8));");
|
||||
w.WriteLine(Spaces + "WriteMemory((ushort)(S-- + 0x2100), (byte)temp16);");
|
||||
w.WriteLine(Spaces + "PC = ReadWord(PC);");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void LDA(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
GetValue8(op, w, "A");
|
||||
w.WriteLine(Spaces + SetNZ("A"));
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void LDX(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
GetValue8(op, w, "X");
|
||||
w.WriteLine(Spaces + SetNZ("X"));
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void LDY(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
GetValue8(op, w, "Y");
|
||||
w.WriteLine(Spaces + SetNZ("Y"));
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void LSR(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
if (op.AddressMode == AddrMode.Accumulator)
|
||||
{
|
||||
w.WriteLine(Spaces + "FlagC = (A & 1) != 0;");
|
||||
w.WriteLine(Spaces + "A = (byte) (A >> 1);");
|
||||
w.WriteLine(Spaces + SetNZ("A"));
|
||||
}
|
||||
else
|
||||
{
|
||||
GetAddress(op, w, "value16");
|
||||
w.WriteLine(Spaces + "value8 = ReadMemory(value16);");
|
||||
w.WriteLine(Spaces + "FlagC = (value8 & 1) != 0;");
|
||||
w.WriteLine(Spaces + "value8 = (byte)(value8 >> 1);");
|
||||
w.WriteLine(Spaces + "WriteMemory(value16, value8);");
|
||||
w.WriteLine(Spaces + SetNZ("value8"));
|
||||
}
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void NOP(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void ORA(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
GetValue8(op, w, "value8");
|
||||
|
||||
w.WriteLine(Spaces + "if (FlagT == false)");
|
||||
w.WriteLine(Spaces + "{");
|
||||
w.WriteLine(Spaces + " A |= value8;");
|
||||
w.WriteLine(Spaces + " "+SetNZ("A"));
|
||||
w.WriteLine(Spaces + " PendingCycles -= {0};", op.Cycles);
|
||||
w.WriteLine(Spaces + "} else {");
|
||||
w.WriteLine(Spaces + " source8 = ReadMemory((ushort)(0x2000 + X));");
|
||||
w.WriteLine(Spaces + " source8 |= value8;");
|
||||
w.WriteLine(Spaces + " " + SetNZ("source8"));
|
||||
w.WriteLine(Spaces + " WriteMemory((ushort)(0x2000 + X), source8);");
|
||||
w.WriteLine(Spaces + " PendingCycles -= {0};", op.Cycles+3);
|
||||
w.WriteLine(Spaces + "}");
|
||||
}
|
||||
|
||||
private void PushReg(OpcodeInfo op, TextWriter w, string reg)
|
||||
{
|
||||
w.WriteLine(Spaces + "WriteMemory((ushort)(S-- + 0x2100), {0});", reg);
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void PullReg(OpcodeInfo op, TextWriter w, string reg)
|
||||
{
|
||||
w.WriteLine(Spaces + "{0} = ReadMemory((ushort)(++S + 0x2100));", reg);
|
||||
w.WriteLine(Spaces + SetNZ(reg));
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
|
||||
private void PLP(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "P = ReadMemory((ushort)(++S + 0x2100));");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
w.WriteLine(Spaces + "goto AfterClearTFlag;");
|
||||
}
|
||||
|
||||
private void ROL(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
if (op.AddressMode == AddrMode.Accumulator)
|
||||
{
|
||||
w.WriteLine(Spaces + "temp8 = A;");
|
||||
w.WriteLine(Spaces + "A = (byte)((A << 1) | (P & 1));");
|
||||
w.WriteLine(Spaces + "FlagC = (temp8 & 0x80) != 0;");
|
||||
w.WriteLine(Spaces + SetNZ("A"));
|
||||
}
|
||||
else
|
||||
{
|
||||
GetAddress(op, w, "value16");
|
||||
w.WriteLine(Spaces + "value8 = temp8 = ReadMemory(value16);");
|
||||
w.WriteLine(Spaces + "value8 = (byte)((value8 << 1) | (P & 1));");
|
||||
w.WriteLine(Spaces + "WriteMemory(value16, value8);");
|
||||
w.WriteLine(Spaces + "FlagC = (temp8 & 0x80) != 0;");
|
||||
w.WriteLine(Spaces + SetNZ("value8"));
|
||||
}
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void ROR(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
if (op.AddressMode == AddrMode.Accumulator)
|
||||
{
|
||||
w.WriteLine(Spaces + "temp8 = A;");
|
||||
w.WriteLine(Spaces + "A = (byte)((A >> 1) | ((P & 1)<<7));");
|
||||
w.WriteLine(Spaces + "FlagC = (temp8 & 1) != 0;");
|
||||
w.WriteLine(Spaces + SetNZ("A"));
|
||||
}
|
||||
else
|
||||
{
|
||||
GetAddress(op, w, "value16");
|
||||
w.WriteLine(Spaces + "value8 = temp8 = ReadMemory(value16);");
|
||||
w.WriteLine(Spaces + "value8 = (byte)((value8 >> 1) | ((P & 1)<<7));");
|
||||
w.WriteLine(Spaces + "WriteMemory(value16, value8);");
|
||||
w.WriteLine(Spaces + "FlagC = (temp8 & 1) != 0;");
|
||||
w.WriteLine(Spaces + SetNZ("value8"));
|
||||
}
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void RTI(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "P = ReadMemory((ushort)(++S + 0x2100));");
|
||||
w.WriteLine(Spaces + "PC = ReadMemory((ushort)(++S + 0x2100));");
|
||||
w.WriteLine(Spaces + "PC |= (ushort)(ReadMemory((ushort)(++S + 0x2100)) << 8);");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
w.WriteLine(Spaces + "goto AfterClearTFlag;");
|
||||
}
|
||||
|
||||
private void RTS(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "PC = ReadMemory((ushort)(++S + 0x2100));");
|
||||
w.WriteLine(Spaces + "PC |= (ushort)(ReadMemory((ushort)(++S + 0x2100)) << 8);");
|
||||
w.WriteLine(Spaces + "PC++;");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void SAX(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "temp8 = A;");
|
||||
w.WriteLine(Spaces + "A = X;");
|
||||
w.WriteLine(Spaces + "X = temp8;");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void SAY(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "temp8 = A;");
|
||||
w.WriteLine(Spaces + "A = Y;");
|
||||
w.WriteLine(Spaces + "Y = temp8;");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void SXY(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "temp8 = X;");
|
||||
w.WriteLine(Spaces + "X = Y;");
|
||||
w.WriteLine(Spaces + "Y = temp8;");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void SBC(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
GetValue8(op, w, "value8");
|
||||
w.WriteLine(Spaces + "temp = A - value8 - (FlagC ? 0 : 1);");
|
||||
w.WriteLine(Spaces + "if ((P & 0x08) != 0) {");
|
||||
w.WriteLine(Spaces + " lo = (A & 0x0F) - (value8 & 0x0F) - (FlagC ? 0 : 1);");
|
||||
w.WriteLine(Spaces + " hi = (A & 0xF0) - (value8 & 0xF0);");
|
||||
w.WriteLine(Spaces + " if ((lo & 0xF0) != 0) lo -= 0x06;");
|
||||
w.WriteLine(Spaces + " if ((lo & 0x80) != 0) hi -= 0x10;");
|
||||
w.WriteLine(Spaces + " if ((hi & 0x0F00) != 0) hi -= 0x60;");
|
||||
w.WriteLine(Spaces + " FlagV = ((A ^ value8) & (A ^ temp) & 0x80) != 0;");
|
||||
w.WriteLine(Spaces + " FlagC = (hi & 0xFF00) == 0;");
|
||||
w.WriteLine(Spaces + " A = (byte) ((lo & 0x0F) | (hi & 0xF0));");
|
||||
w.WriteLine(Spaces + " PendingCycles--;");
|
||||
w.WriteLine(Spaces + "} else {");
|
||||
w.WriteLine(Spaces + " FlagV = ((A ^ value8) & (A ^ temp) & 0x80) != 0;");
|
||||
w.WriteLine(Spaces + " FlagC = temp >= 0;");
|
||||
w.WriteLine(Spaces + " A = (byte)temp;");
|
||||
w.WriteLine(Spaces + "}");
|
||||
w.WriteLine(Spaces + SetNZ("A"));
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void SEC(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "FlagC = true;");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void SED(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "FlagD = true;");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void SEI(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "FlagI = true;");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void SET(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(" int a; // TODO remove these extra checks"); // TODO remove these extra checks
|
||||
w.WriteLine(" string b = Disassemble(PC, out a);");
|
||||
w.WriteLine(" if (b.StartsWith(\"ADC\") == false && b.StartsWith(\"EOR\") == false && b.StartsWith(\"AND\") == false && b.StartsWith(\"ORA\") == false)");
|
||||
w.WriteLine(" Console.WriteLine(\"SETTING T FLAG, NEXT INSTRUCTION IS UNHANDLED: {0}\", b);");
|
||||
w.WriteLine(Spaces + "FlagT = true;");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
w.WriteLine(Spaces + "goto AfterClearTFlag;");
|
||||
}
|
||||
|
||||
private void ST0(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
GetValue8(op, w, "value8");
|
||||
w.WriteLine(Spaces + "WriteVDC(0,value8);");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void ST1(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
GetValue8(op, w, "value8");
|
||||
w.WriteLine(Spaces + "WriteVDC(2,value8);");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void ST2(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
GetValue8(op, w, "value8");
|
||||
w.WriteLine(Spaces + "WriteVDC(3,value8);");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void STA(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
GetAddress(op, w, "value16");
|
||||
w.WriteLine(Spaces + "WriteMemory(value16, A);");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void STX(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
GetAddress(op, w, "value16");
|
||||
w.WriteLine(Spaces + "WriteMemory(value16, X);");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void STY(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
GetAddress(op, w, "value16");
|
||||
w.WriteLine(Spaces + "WriteMemory(value16, Y);");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void STZ(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
GetAddress(op, w, "value16");
|
||||
w.WriteLine(Spaces + "WriteMemory(value16, 0);");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void TAM(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
GetValue8(op, w, "value8");
|
||||
w.WriteLine(Spaces + "for (byte reg=0; reg<8; reg++)");
|
||||
w.WriteLine(Spaces + "{");
|
||||
w.WriteLine(Spaces + " if ((value8 & (1 << reg)) != 0)");
|
||||
w.WriteLine(Spaces + " MPR[reg] = A;");
|
||||
w.WriteLine(Spaces + "}");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void TAX(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "X = A;");
|
||||
w.WriteLine(Spaces + SetNZ("X"));
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void TAY(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "Y = A;");
|
||||
w.WriteLine(Spaces + SetNZ("Y"));
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void TMA(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
GetValue8(op, w, "value8");
|
||||
w.WriteLine(Spaces + " if ((value8 & 0x01) != 0) A = MPR[0];");
|
||||
w.WriteLine(Spaces + "else if ((value8 & 0x02) != 0) A = MPR[1];");
|
||||
w.WriteLine(Spaces + "else if ((value8 & 0x04) != 0) A = MPR[2];");
|
||||
w.WriteLine(Spaces + "else if ((value8 & 0x08) != 0) A = MPR[3];");
|
||||
w.WriteLine(Spaces + "else if ((value8 & 0x10) != 0) A = MPR[4];");
|
||||
w.WriteLine(Spaces + "else if ((value8 & 0x20) != 0) A = MPR[5];");
|
||||
w.WriteLine(Spaces + "else if ((value8 & 0x40) != 0) A = MPR[6];");
|
||||
w.WriteLine(Spaces + "else if ((value8 & 0x80) != 0) A = MPR[7];");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void TRB(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
GetAddress(op, w, "value16");
|
||||
w.WriteLine(Spaces + "value8 = ReadMemory(value16);");
|
||||
w.WriteLine(Spaces + "WriteMemory(value16, (byte)(value8 & ~A));");
|
||||
w.WriteLine(Spaces + "FlagN = (value8 & 0x80) != 0;");
|
||||
w.WriteLine(Spaces + "FlagV = (value8 & 0x40) != 0;");
|
||||
w.WriteLine(Spaces + "FlagZ = (A & value8) == 0;");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void TSB(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
GetAddress(op, w, "value16");
|
||||
w.WriteLine(Spaces + "value8 = ReadMemory(value16);");
|
||||
w.WriteLine(Spaces + "WriteMemory(value16, (byte)(value8 | A));");
|
||||
w.WriteLine(Spaces + "FlagN = (value8 & 0x80) != 0;");
|
||||
w.WriteLine(Spaces + "FlagV = (value8 & 0x40) != 0;");
|
||||
w.WriteLine(Spaces + "FlagZ = (A | value8) == 0;");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void TST(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "value8 = ReadMemory(PC++);");
|
||||
GetValue8(op, w, "temp8");
|
||||
w.WriteLine(Spaces + "FlagN = (temp8 & 0x80) != 0;");
|
||||
w.WriteLine(Spaces + "FlagV = (temp8 & 0x40) != 0;");
|
||||
w.WriteLine(Spaces + "FlagZ = (temp8 & value8) == 0;");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void TSX(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "X = S;");
|
||||
w.WriteLine(Spaces + SetNZ("X"));
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void TXA(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "A = X;");
|
||||
w.WriteLine(Spaces + SetNZ("A"));
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void TXS(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "S = X;");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void TYA(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "A = Y;");
|
||||
w.WriteLine(Spaces + SetNZ("A"));
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void RMB(OpcodeInfo op, TextWriter w, int bit)
|
||||
{
|
||||
GetAddress(op, w, "value16");
|
||||
w.WriteLine(Spaces + "value8 = ReadMemory(value16);");
|
||||
w.WriteLine(Spaces + "value8 &= 0x{0:X2};", (byte)(~(1 << bit)));
|
||||
w.WriteLine(Spaces + "WriteMemory(value16, value8);");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void SMB(OpcodeInfo op, TextWriter w, int bit)
|
||||
{
|
||||
GetAddress(op, w, "value16");
|
||||
w.WriteLine(Spaces + "value8 = ReadMemory(value16);");
|
||||
w.WriteLine(Spaces + "value8 |= 0x{0:X2};",(1<<bit));
|
||||
w.WriteLine(Spaces + "WriteMemory(value16, value8);");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void TAI(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "if (InBlockTransfer == false)");
|
||||
w.WriteLine(Spaces + "{");
|
||||
w.WriteLine(Spaces + " InBlockTransfer = true;");
|
||||
w.WriteLine(Spaces + " btFrom = ReadWord(PC); PC += 2;");
|
||||
w.WriteLine(Spaces + " btTo = ReadWord(PC); PC += 2;");
|
||||
w.WriteLine(Spaces + " btLen = ReadWord(PC); PC += 2;");
|
||||
w.WriteLine(Spaces + " btAlternator = 0;");
|
||||
w.WriteLine(Spaces + " PendingCycles -= 14;");
|
||||
w.WriteLine(Spaces + " PC -= 7;");
|
||||
w.WriteLine(Spaces + " break;");
|
||||
w.WriteLine(Spaces + "}");
|
||||
w.WriteLine();
|
||||
w.WriteLine(Spaces + "if (btLen-- != 0)");
|
||||
w.WriteLine(Spaces + "{");
|
||||
w.WriteLine(Spaces + " WriteMemory(btTo++, ReadMemory((ushort)(btFrom + btAlternator)));");
|
||||
w.WriteLine(Spaces + " btAlternator ^= 1;");
|
||||
w.WriteLine(Spaces + " PendingCycles -= 6;");
|
||||
w.WriteLine(Spaces + " PC--;");
|
||||
w.WriteLine(Spaces + " break;");
|
||||
w.WriteLine(Spaces + "}");
|
||||
w.WriteLine();
|
||||
w.WriteLine(Spaces + "InBlockTransfer = false;");
|
||||
w.WriteLine(Spaces + "PendingCycles -= 3;");
|
||||
w.WriteLine(Spaces + "PC += 6;");
|
||||
}
|
||||
|
||||
private void TIA(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "if (InBlockTransfer == false)");
|
||||
w.WriteLine(Spaces + "{");
|
||||
w.WriteLine(Spaces + " InBlockTransfer = true;");
|
||||
w.WriteLine(Spaces + " btFrom = ReadWord(PC); PC += 2;");
|
||||
w.WriteLine(Spaces + " btTo = ReadWord(PC); PC += 2;");
|
||||
w.WriteLine(Spaces + " btLen = ReadWord(PC); PC += 2;");
|
||||
w.WriteLine(Spaces + " btAlternator = 0;");
|
||||
w.WriteLine(Spaces + " PendingCycles -= 14;");
|
||||
w.WriteLine(Spaces + " PC -= 7;");
|
||||
w.WriteLine(Spaces + " break;");
|
||||
w.WriteLine(Spaces + "}");
|
||||
w.WriteLine();
|
||||
w.WriteLine(Spaces + "if (btLen-- != 0)");
|
||||
w.WriteLine(Spaces + "{");
|
||||
w.WriteLine(Spaces + " WriteMemory((ushort)(btTo+btAlternator), ReadMemory(btFrom++));");
|
||||
w.WriteLine(Spaces + " btAlternator ^= 1;");
|
||||
w.WriteLine(Spaces + " PendingCycles -= 6;");
|
||||
w.WriteLine(Spaces + " PC--;");
|
||||
w.WriteLine(Spaces + " break;");
|
||||
w.WriteLine(Spaces + "}");
|
||||
w.WriteLine();
|
||||
w.WriteLine(Spaces + "InBlockTransfer = false;");
|
||||
w.WriteLine(Spaces + "PendingCycles -= 3;");
|
||||
w.WriteLine(Spaces + "PC += 6;");
|
||||
}
|
||||
|
||||
private void TII(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "if (InBlockTransfer == false)");
|
||||
w.WriteLine(Spaces + "{");
|
||||
w.WriteLine(Spaces + " InBlockTransfer = true;");
|
||||
w.WriteLine(Spaces + " btFrom = ReadWord(PC); PC += 2;");
|
||||
w.WriteLine(Spaces + " btTo = ReadWord(PC); PC += 2;");
|
||||
w.WriteLine(Spaces + " btLen = ReadWord(PC); PC += 2;");
|
||||
w.WriteLine(Spaces + " PendingCycles -= 14;");
|
||||
w.WriteLine(Spaces + " PC -= 7;");
|
||||
w.WriteLine(Spaces + " break;");
|
||||
w.WriteLine(Spaces + "}");
|
||||
w.WriteLine();
|
||||
w.WriteLine(Spaces + "if (btLen-- != 0)");
|
||||
w.WriteLine(Spaces + "{");
|
||||
w.WriteLine(Spaces + " WriteMemory(btTo++, ReadMemory(btFrom++));");
|
||||
w.WriteLine(Spaces + " PendingCycles -= 6;");
|
||||
w.WriteLine(Spaces + " PC--;");
|
||||
w.WriteLine(Spaces + " break;");
|
||||
w.WriteLine(Spaces + "}");
|
||||
w.WriteLine();
|
||||
w.WriteLine(Spaces + "InBlockTransfer = false;");
|
||||
w.WriteLine(Spaces + "PendingCycles -= 3;");
|
||||
w.WriteLine(Spaces + "PC += 6;");
|
||||
}
|
||||
|
||||
private void TIN(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "if (InBlockTransfer == false)");
|
||||
w.WriteLine(Spaces + "{");
|
||||
w.WriteLine(Spaces + " InBlockTransfer = true;");
|
||||
w.WriteLine(Spaces + " btFrom = ReadWord(PC); PC += 2;");
|
||||
w.WriteLine(Spaces + " btTo = ReadWord(PC); PC += 2;");
|
||||
w.WriteLine(Spaces + " btLen = ReadWord(PC); PC += 2;");
|
||||
w.WriteLine(Spaces + " PendingCycles -= 14;");
|
||||
w.WriteLine(Spaces + " PC -= 7;");
|
||||
w.WriteLine(Spaces + " break;");
|
||||
w.WriteLine(Spaces + "}");
|
||||
w.WriteLine();
|
||||
w.WriteLine(Spaces + "if (btLen-- != 0)");
|
||||
w.WriteLine(Spaces + "{");
|
||||
w.WriteLine(Spaces + " WriteMemory(btTo, ReadMemory(btFrom++));");
|
||||
w.WriteLine(Spaces + " PendingCycles -= 6;");
|
||||
w.WriteLine(Spaces + " PC--;");
|
||||
w.WriteLine(Spaces + " break;");
|
||||
w.WriteLine(Spaces + "}");
|
||||
w.WriteLine();
|
||||
w.WriteLine(Spaces + "InBlockTransfer = false;");
|
||||
w.WriteLine(Spaces + "PendingCycles -= 3;");
|
||||
w.WriteLine(Spaces + "PC += 6;");
|
||||
}
|
||||
|
||||
private void TDD(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "if (InBlockTransfer == false)");
|
||||
w.WriteLine(Spaces + "{");
|
||||
w.WriteLine(Spaces + " InBlockTransfer = true;");
|
||||
w.WriteLine(Spaces + " btFrom = ReadWord(PC); PC += 2;");
|
||||
w.WriteLine(Spaces + " btTo = ReadWord(PC); PC += 2;");
|
||||
w.WriteLine(Spaces + " btLen = ReadWord(PC); PC += 2;");
|
||||
w.WriteLine(Spaces + " PendingCycles -= 14;");
|
||||
w.WriteLine(Spaces + " PC -= 7;");
|
||||
w.WriteLine(Spaces + " break;");
|
||||
w.WriteLine(Spaces + "}");
|
||||
w.WriteLine();
|
||||
w.WriteLine(Spaces + "if (btLen-- != 0)");
|
||||
w.WriteLine(Spaces + "{");
|
||||
w.WriteLine(Spaces + " WriteMemory(btTo--, ReadMemory(btFrom--));");
|
||||
w.WriteLine(Spaces + " PendingCycles -= 6;");
|
||||
w.WriteLine(Spaces + " PC--;");
|
||||
w.WriteLine(Spaces + " break;");
|
||||
w.WriteLine(Spaces + "}");
|
||||
w.WriteLine();
|
||||
w.WriteLine(Spaces + "InBlockTransfer = false;");
|
||||
w.WriteLine(Spaces + "PendingCycles -= 3;");
|
||||
w.WriteLine(Spaces + "PC += 6;");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,663 +0,0 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace M6502
|
||||
{
|
||||
public enum AddrMode
|
||||
{
|
||||
Implicit,
|
||||
Accumulator,
|
||||
Immediate,
|
||||
ZeroPage,
|
||||
ZeroPageX,
|
||||
ZeroPageY,
|
||||
Absolute,
|
||||
AbsoluteX,
|
||||
AbsoluteX_P, //* page-crossing penalty
|
||||
AbsoluteY,
|
||||
AbsoluteY_P, //* page-crossing penalty
|
||||
Indirect,
|
||||
IndirectX,
|
||||
IndirectY,
|
||||
IndirectY_P, //* page-crossing penalty
|
||||
Relative
|
||||
}
|
||||
|
||||
public class OpcodeInfo
|
||||
{
|
||||
public string Instruction;
|
||||
public AddrMode AddressMode;
|
||||
public int Cycles;
|
||||
|
||||
public int Size
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (AddressMode)
|
||||
{
|
||||
case AddrMode.Implicit: return 1;
|
||||
case AddrMode.Accumulator: return 1;
|
||||
case AddrMode.Immediate: return 2;
|
||||
case AddrMode.ZeroPage: return 2;
|
||||
case AddrMode.ZeroPageX: return 2;
|
||||
case AddrMode.ZeroPageY: return 2;
|
||||
case AddrMode.Absolute: return 3;
|
||||
case AddrMode.AbsoluteX: return 3;
|
||||
case AddrMode.AbsoluteX_P: return 3;
|
||||
case AddrMode.AbsoluteY: return 3;
|
||||
case AddrMode.AbsoluteY_P: return 3;
|
||||
case AddrMode.Indirect: return 3;
|
||||
case AddrMode.IndirectX: return 2;
|
||||
case AddrMode.IndirectY: return 2;
|
||||
case AddrMode.IndirectY_P: return 2;
|
||||
case AddrMode.Relative: return 2;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
switch (AddressMode)
|
||||
{
|
||||
case AddrMode.Implicit: return Instruction;
|
||||
case AddrMode.Accumulator: return Instruction+" A";
|
||||
case AddrMode.Immediate: return Instruction+" #nn";
|
||||
case AddrMode.ZeroPage: return Instruction+" zp";
|
||||
case AddrMode.ZeroPageX: return Instruction + " zp,X";
|
||||
case AddrMode.ZeroPageY: return Instruction + " zp,Y";
|
||||
case AddrMode.Absolute: return Instruction + " addr";
|
||||
case AddrMode.AbsoluteX: return Instruction + " addr,X";
|
||||
case AddrMode.AbsoluteX_P: return Instruction + " addr,X*";
|
||||
case AddrMode.AbsoluteY: return Instruction + " addr,Y";
|
||||
case AddrMode.AbsoluteY_P: return Instruction + " addr,Y*";
|
||||
case AddrMode.Indirect: return Instruction + " (addr)";
|
||||
case AddrMode.IndirectX: return Instruction + " (addr,X)";
|
||||
case AddrMode.IndirectY: return Instruction + " (addr),Y";
|
||||
case AddrMode.IndirectY_P: return Instruction + " (addr),Y*";
|
||||
case AddrMode.Relative: return Instruction + " +/-rel";
|
||||
default: return Instruction;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public partial class CoreGenerator
|
||||
{
|
||||
public OpcodeInfo[] Opcodes = new OpcodeInfo[256];
|
||||
|
||||
// NOTE: page is 256 bytes.
|
||||
|
||||
public void InitOpcodeTable()
|
||||
{
|
||||
// Add with Carry
|
||||
Set(0x69, "ADC", AddrMode.Immediate, 2);
|
||||
Set(0x65, "ADC", AddrMode.ZeroPage , 3);
|
||||
Set(0x75, "ADC", AddrMode.ZeroPageX, 4);
|
||||
Set(0x6D, "ADC", AddrMode.Absolute , 4);
|
||||
Set(0x7D, "ADC", AddrMode.AbsoluteX_P, 4);
|
||||
Set(0x79, "ADC", AddrMode.AbsoluteY_P, 4);
|
||||
Set(0x61, "ADC", AddrMode.IndirectX, 6);
|
||||
Set(0x71, "ADC", AddrMode.IndirectY_P, 5);
|
||||
|
||||
// AND
|
||||
Set(0x29, "AND", AddrMode.Immediate, 2);
|
||||
Set(0x25, "AND", AddrMode.ZeroPage , 3);
|
||||
Set(0x35, "AND", AddrMode.ZeroPageX, 4);
|
||||
Set(0x2D, "AND", AddrMode.Absolute , 4);
|
||||
Set(0x3D, "AND", AddrMode.AbsoluteX_P, 4);
|
||||
Set(0x39, "AND", AddrMode.AbsoluteY_P, 4);
|
||||
Set(0x21, "AND", AddrMode.IndirectX, 6);
|
||||
Set(0x31, "AND", AddrMode.IndirectY_P, 5);
|
||||
|
||||
// Arithmatic Shift Left
|
||||
Set(0x0A, "ASL", AddrMode.Accumulator, 2);
|
||||
Set(0x06, "ASL", AddrMode.ZeroPage , 5);
|
||||
Set(0x16, "ASL", AddrMode.ZeroPageX, 6);
|
||||
Set(0x0E, "ASL", AddrMode.Absolute , 6);
|
||||
Set(0x1E, "ASL", AddrMode.AbsoluteX, 7);
|
||||
|
||||
// BIT
|
||||
Set(0x24, "BIT", AddrMode.ZeroPage, 3);
|
||||
Set(0x2C, "BIT", AddrMode.Absolute, 4);
|
||||
|
||||
// Branch instructions
|
||||
Set(0x10, "BPL", AddrMode.Relative, 2); // Branch on Plus
|
||||
Set(0x30, "BMI", AddrMode.Relative, 2); // Branch on Minus
|
||||
Set(0x50, "BVC", AddrMode.Relative, 2); // Branch on Overflow Clear
|
||||
Set(0x70, "BVS", AddrMode.Relative, 2); // Branch on Overflow Set
|
||||
Set(0x90, "BCC", AddrMode.Relative, 2); // Branch on Carry Clear
|
||||
Set(0xB0, "BCS", AddrMode.Relative, 2); // Branch on Carry Set
|
||||
Set(0xD0, "BNE", AddrMode.Relative, 2); // Branch on Not Equal
|
||||
Set(0xF0, "BEQ", AddrMode.Relative, 2); // Branch on Equal
|
||||
|
||||
// CPU Break
|
||||
Set(0x00, "BRK", AddrMode.Implicit, 7);
|
||||
|
||||
// Compare accumulator
|
||||
Set(0xC9, "CMP", AddrMode.Immediate, 2);
|
||||
Set(0xC5, "CMP", AddrMode.ZeroPage , 3);
|
||||
Set(0xD5, "CMP", AddrMode.ZeroPageX, 4);
|
||||
Set(0xCD, "CMP", AddrMode.Absolute , 4);
|
||||
Set(0xDD, "CMP", AddrMode.AbsoluteX_P, 4);
|
||||
Set(0xD9, "CMP", AddrMode.AbsoluteY_P, 4);
|
||||
Set(0xC1, "CMP", AddrMode.IndirectX, 6);
|
||||
Set(0xD1, "CMP", AddrMode.IndirectY_P, 5);
|
||||
|
||||
// Compare X register
|
||||
Set(0xE0, "CPX", AddrMode.Immediate, 2);
|
||||
Set(0xE4, "CPX", AddrMode.ZeroPage , 3);
|
||||
Set(0xEC, "CPX", AddrMode.Absolute , 4);
|
||||
|
||||
// Compare Y register
|
||||
Set(0xC0, "CPY", AddrMode.Immediate, 2);
|
||||
Set(0xC4, "CPY", AddrMode.ZeroPage , 3);
|
||||
Set(0xCC, "CPY", AddrMode.Absolute , 4);
|
||||
|
||||
// DEC
|
||||
Set(0xC6, "DEC", AddrMode.ZeroPage , 5);
|
||||
Set(0xD6, "DEC", AddrMode.ZeroPageX, 6);
|
||||
Set(0xCE, "DEC", AddrMode.Absolute , 6);
|
||||
Set(0xDE, "DEC", AddrMode.AbsoluteX, 7);
|
||||
|
||||
// Exclusive OR
|
||||
Set(0x49, "EOR", AddrMode.Immediate, 2);
|
||||
Set(0x45, "EOR", AddrMode.ZeroPage , 3);
|
||||
Set(0x55, "EOR", AddrMode.ZeroPageX, 4);
|
||||
Set(0x4D, "EOR", AddrMode.Absolute , 4);
|
||||
Set(0x5D, "EOR", AddrMode.AbsoluteX_P, 4);
|
||||
Set(0x59, "EOR", AddrMode.AbsoluteY_P, 4);
|
||||
Set(0x41, "EOR", AddrMode.IndirectX, 6);
|
||||
Set(0x51, "EOR", AddrMode.IndirectY_P, 5);
|
||||
|
||||
// Flag Instructions
|
||||
Set(0x18, "CLC", AddrMode.Implicit, 2); // Clear Carry
|
||||
Set(0x38, "SEC", AddrMode.Implicit, 2); // Set Carry
|
||||
Set(0x58, "CLI", AddrMode.Implicit, 2); // Clear Interrupt
|
||||
Set(0x78, "SEI", AddrMode.Implicit, 2); // Set Interrupt
|
||||
Set(0xB8, "CLV", AddrMode.Implicit, 2); // Clear Overflow
|
||||
Set(0xD8, "CLD", AddrMode.Implicit, 2); // Clear Decimal
|
||||
Set(0xF8, "SED", AddrMode.Implicit, 2); // Set Decimal
|
||||
|
||||
// INC
|
||||
Set(0xE6, "INC", AddrMode.ZeroPage , 5);
|
||||
Set(0xF6, "INC", AddrMode.ZeroPageX, 6);
|
||||
Set(0xEE, "INC", AddrMode.Absolute , 6);
|
||||
Set(0xFE, "INC", AddrMode.AbsoluteX, 7);
|
||||
|
||||
// Jump
|
||||
Set(0x4C, "JMP", AddrMode.Absolute, 3);
|
||||
Set(0x6C, "JMP", AddrMode.Indirect, 5);
|
||||
|
||||
// Jump to Subroutine
|
||||
Set(0x20, "JSR", AddrMode.Absolute, 6);
|
||||
|
||||
// Load Accumulator
|
||||
Set(0xA9, "LDA", AddrMode.Immediate, 2);
|
||||
Set(0xA5, "LDA", AddrMode.ZeroPage , 3);
|
||||
Set(0xB5, "LDA", AddrMode.ZeroPageX, 4);
|
||||
Set(0xAD, "LDA", AddrMode.Absolute , 4);
|
||||
Set(0xBD, "LDA", AddrMode.AbsoluteX_P, 4);
|
||||
Set(0xB9, "LDA", AddrMode.AbsoluteY_P, 4);
|
||||
Set(0xA1, "LDA", AddrMode.IndirectX, 6);
|
||||
Set(0xB1, "LDA", AddrMode.IndirectY_P, 5);
|
||||
|
||||
// Load X register
|
||||
Set(0xA2, "LDX", AddrMode.Immediate, 2);
|
||||
Set(0xA6, "LDX", AddrMode.ZeroPage , 3);
|
||||
Set(0xB6, "LDX", AddrMode.ZeroPageY, 4);
|
||||
Set(0xAE, "LDX", AddrMode.Absolute , 4);
|
||||
Set(0xBE, "LDX", AddrMode.AbsoluteY_P, 4);
|
||||
|
||||
// Load Y register
|
||||
Set(0xA0, "LDY", AddrMode.Immediate, 2);
|
||||
Set(0xA4, "LDY", AddrMode.ZeroPage , 3);
|
||||
Set(0xB4, "LDY", AddrMode.ZeroPageX, 4);
|
||||
Set(0xAC, "LDY", AddrMode.Absolute , 4);
|
||||
Set(0xBC, "LDY", AddrMode.AbsoluteX_P, 4);
|
||||
|
||||
// Logical Shift Right
|
||||
Set(0x4A, "LSR", AddrMode.Accumulator, 2);
|
||||
Set(0x46, "LSR", AddrMode.ZeroPage , 5);
|
||||
Set(0x56, "LSR", AddrMode.ZeroPageX, 6);
|
||||
Set(0x4E, "LSR", AddrMode.Absolute , 6);
|
||||
Set(0x5E, "LSR", AddrMode.AbsoluteX, 7);
|
||||
|
||||
// No Operation
|
||||
Set(0xEA, "NOP", AddrMode.Implicit, 2);
|
||||
|
||||
// Illegal NOPs
|
||||
Set(0x1A, "NOP", AddrMode.Implicit, 2);
|
||||
Set(0x3A, "NOP", AddrMode.Implicit, 2);
|
||||
Set(0x5A, "NOP", AddrMode.Implicit, 2);
|
||||
Set(0x7A, "NOP", AddrMode.Implicit, 2);
|
||||
Set(0xDA, "NOP", AddrMode.Implicit, 2);
|
||||
Set(0xFA, "NOP", AddrMode.Implicit, 2);
|
||||
Set(0x80, "NOP", AddrMode.Immediate, 2);
|
||||
Set(0x82, "NOP", AddrMode.Immediate, 2);
|
||||
Set(0x89, "NOP", AddrMode.Immediate, 2);
|
||||
Set(0xC2, "NOP", AddrMode.Immediate, 2);
|
||||
Set(0xE2, "NOP", AddrMode.Immediate, 2);
|
||||
Set(0x04, "NOP", AddrMode.ZeroPage, 3);
|
||||
Set(0x44, "NOP", AddrMode.ZeroPage, 3);
|
||||
Set(0x64, "NOP", AddrMode.ZeroPage, 3);
|
||||
Set(0x14, "NOP", AddrMode.ZeroPageX, 4);
|
||||
Set(0x34, "NOP", AddrMode.ZeroPageX, 4);
|
||||
Set(0x54, "NOP", AddrMode.ZeroPageX, 4);
|
||||
Set(0x74, "NOP", AddrMode.ZeroPageX, 4);
|
||||
Set(0xD4, "NOP", AddrMode.ZeroPageX, 4);
|
||||
Set(0xF4, "NOP", AddrMode.ZeroPageX, 4);
|
||||
//do the following issue a read or write? if so, we need to emulate with another instruction
|
||||
Set(0x0C, "NOP", AddrMode.Indirect, 4);
|
||||
Set(0x1C, "NOP", AddrMode.IndirectX, 4);
|
||||
Set(0x3C, "NOP", AddrMode.IndirectX, 4);
|
||||
Set(0x5C, "NOP", AddrMode.IndirectX, 4);
|
||||
Set(0x7C, "NOP", AddrMode.IndirectX, 4);
|
||||
Set(0xDC, "NOP", AddrMode.IndirectX, 4);
|
||||
Set(0xFC, "NOP", AddrMode.IndirectX, 4);
|
||||
|
||||
//undocumented opcodes
|
||||
//RLA:
|
||||
//Set(0x23, "RLA", AddrMode.IndirectX, 8);
|
||||
|
||||
// Bitwise OR with Accumulator
|
||||
Set(0x09, "ORA", AddrMode.Immediate, 2);
|
||||
Set(0x05, "ORA", AddrMode.ZeroPage , 3);
|
||||
Set(0x15, "ORA", AddrMode.ZeroPageX, 4);
|
||||
Set(0x0D, "ORA", AddrMode.Absolute , 4);
|
||||
Set(0x1D, "ORA", AddrMode.AbsoluteX_P, 4);
|
||||
Set(0x19, "ORA", AddrMode.AbsoluteY_P, 4);
|
||||
Set(0x01, "ORA", AddrMode.IndirectX, 6);
|
||||
Set(0x11, "ORA", AddrMode.IndirectY_P, 5);
|
||||
|
||||
// Register instructions
|
||||
Set(0xAA, "TAX", AddrMode.Implicit, 2); // Transfer A to X
|
||||
Set(0x8A, "TXA", AddrMode.Implicit, 2); // Transfer X to A
|
||||
Set(0xCA, "DEX", AddrMode.Implicit, 2); // DEC X
|
||||
Set(0xE8, "INX", AddrMode.Implicit, 2); // INC X
|
||||
Set(0xA8, "TAY", AddrMode.Implicit, 2); // Transfer A to Y
|
||||
Set(0x98, "TYA", AddrMode.Implicit, 2); // Transfer Y to A
|
||||
Set(0x88, "DEY", AddrMode.Implicit, 2); // DEC Y
|
||||
Set(0xC8, "INY", AddrMode.Implicit, 2); // INC Y
|
||||
|
||||
// Rotate Left
|
||||
Set(0x2A, "ROL", AddrMode.Accumulator, 2);
|
||||
Set(0x26, "ROL", AddrMode.ZeroPage , 5);
|
||||
Set(0x36, "ROL", AddrMode.ZeroPageX, 6);
|
||||
Set(0x2E, "ROL", AddrMode.Absolute , 6);
|
||||
Set(0x3E, "ROL", AddrMode.AbsoluteX, 7);
|
||||
|
||||
// Rotate Right
|
||||
Set(0x6A, "ROR", AddrMode.Accumulator, 2);
|
||||
Set(0x66, "ROR", AddrMode.ZeroPage , 5);
|
||||
Set(0x76, "ROR", AddrMode.ZeroPageX, 6);
|
||||
Set(0x6E, "ROR", AddrMode.Absolute , 6);
|
||||
Set(0x7E, "ROR", AddrMode.AbsoluteX, 7);
|
||||
|
||||
// Return from Interrupt
|
||||
Set(0x40, "RTI", AddrMode.Implicit, 6);
|
||||
|
||||
// Return from Subroutine
|
||||
Set(0x60, "RTS", AddrMode.Implicit, 6);
|
||||
|
||||
// Subtract with Carry
|
||||
Set(0xE9, "SBC", AddrMode.Immediate, 2);
|
||||
Set(0xE5, "SBC", AddrMode.ZeroPage , 3);
|
||||
Set(0xF5, "SBC", AddrMode.ZeroPageX, 4);
|
||||
Set(0xED, "SBC", AddrMode.Absolute , 4);
|
||||
Set(0xFD, "SBC", AddrMode.AbsoluteX_P, 4);
|
||||
Set(0xF9, "SBC", AddrMode.AbsoluteY_P, 4);
|
||||
Set(0xE1, "SBC", AddrMode.IndirectX, 6);
|
||||
Set(0xF1, "SBC", AddrMode.IndirectY_P, 5);
|
||||
|
||||
// Store Accumulator
|
||||
Set(0x85, "STA", AddrMode.ZeroPage , 3);
|
||||
Set(0x95, "STA", AddrMode.ZeroPageX, 4);
|
||||
Set(0x8D, "STA", AddrMode.Absolute , 4);
|
||||
Set(0x9D, "STA", AddrMode.AbsoluteX, 5);
|
||||
Set(0x99, "STA", AddrMode.AbsoluteY, 5);
|
||||
Set(0x81, "STA", AddrMode.IndirectX, 6);
|
||||
Set(0x91, "STA", AddrMode.IndirectY, 6);
|
||||
|
||||
// Stack instructions
|
||||
Set(0x9A, "TXS", AddrMode.Implicit, 2); // Transfer X to Stack
|
||||
Set(0xBA, "TSX", AddrMode.Implicit, 2); // Transfer Stack to X
|
||||
Set(0x48, "PHA", AddrMode.Implicit, 3); // Push A
|
||||
Set(0x68, "PLA", AddrMode.Implicit, 4); // Pull A
|
||||
Set(0x08, "PHP", AddrMode.Implicit, 3); // Push P
|
||||
Set(0x28, "PLP", AddrMode.Implicit, 4); // Pull P
|
||||
|
||||
// Store X register
|
||||
Set(0x86, "STX", AddrMode.ZeroPage , 3);
|
||||
Set(0x96, "STX", AddrMode.ZeroPageY, 4);
|
||||
Set(0x8E, "STX", AddrMode.Absolute , 4);
|
||||
|
||||
// Store Y register
|
||||
Set(0x84, "STY", AddrMode.ZeroPage , 3);
|
||||
Set(0x94, "STY", AddrMode.ZeroPageX, 4);
|
||||
Set(0x8C, "STY", AddrMode.Absolute , 4);
|
||||
}
|
||||
|
||||
private void Set(byte value, string instr, AddrMode addressMode, int cycles)
|
||||
{
|
||||
var op = new OpcodeInfo();
|
||||
op.Instruction = instr;
|
||||
op.AddressMode = addressMode;
|
||||
op.Cycles = cycles;
|
||||
if (Opcodes[value] != null)
|
||||
throw new Exception("opcode "+value+" already assigned");
|
||||
Opcodes[value] = op;
|
||||
}
|
||||
|
||||
public void GenerateExecutor(string file)
|
||||
{
|
||||
var w = new StreamWriter(file, false);
|
||||
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.Common.Components.M6502");
|
||||
w.WriteLine("{");
|
||||
w.WriteLine(" public partial class MOS6502");
|
||||
w.WriteLine(" {");
|
||||
w.WriteLine(" public void Execute(int cycles)");
|
||||
w.WriteLine(" {");
|
||||
w.WriteLine(" sbyte rel8;");
|
||||
w.WriteLine(" byte value8, temp8;");
|
||||
w.WriteLine(" ushort value16, temp16;");
|
||||
w.WriteLine(" int temp;");
|
||||
w.WriteLine();
|
||||
w.WriteLine(" PendingCycles += cycles;");
|
||||
w.WriteLine(" while (PendingCycles > 0)");
|
||||
w.WriteLine(" {");
|
||||
w.WriteLine(" if (NMI)");
|
||||
w.WriteLine(" {");
|
||||
w.WriteLine(" TriggerException(ExceptionType.NMI);");
|
||||
w.WriteLine(" NMI = false;");
|
||||
w.WriteLine(" }");
|
||||
w.WriteLine(" if (IRQ && !FlagI)");
|
||||
w.WriteLine(" {");
|
||||
w.WriteLine(" if (SEI_Pending)");
|
||||
w.WriteLine(" FlagI = true;");
|
||||
w.WriteLine(" TriggerException(ExceptionType.IRQ);");
|
||||
w.WriteLine(" }");
|
||||
w.WriteLine(" if (CLI_Pending)");
|
||||
w.WriteLine(" {");
|
||||
w.WriteLine(" FlagI = false;");
|
||||
w.WriteLine(" CLI_Pending = false;");
|
||||
w.WriteLine(" }");
|
||||
w.WriteLine(" if (SEI_Pending)");
|
||||
w.WriteLine(" {");
|
||||
w.WriteLine(" FlagI = true;");
|
||||
w.WriteLine(" SEI_Pending = false;");
|
||||
w.WriteLine(" }");
|
||||
|
||||
w.WriteLine(" if(debug) Console.WriteLine(State());");
|
||||
w.WriteLine("");
|
||||
|
||||
w.WriteLine(" ushort this_pc = PC;");
|
||||
w.WriteLine(" byte opcode = ReadMemory(PC++);");
|
||||
w.WriteLine(" switch (opcode)");
|
||||
w.WriteLine(" {");
|
||||
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
if (Opcodes[i] != null)
|
||||
{
|
||||
EmulateOpcode(w, i);
|
||||
}
|
||||
}
|
||||
|
||||
w.WriteLine(" default:");
|
||||
w.WriteLine(" if(throw_unhandled)");
|
||||
w.WriteLine(" throw new Exception(String.Format(\"Unhandled opcode: {0:X2}\", opcode));");
|
||||
w.WriteLine(" break;");
|
||||
w.WriteLine(" }");
|
||||
w.WriteLine(" }");
|
||||
w.WriteLine(" }");
|
||||
w.WriteLine(" }");
|
||||
w.WriteLine("}");
|
||||
w.Close();
|
||||
}
|
||||
|
||||
const string Spaces = " ";
|
||||
|
||||
private void EmulateOpcode(TextWriter w, int opcode)
|
||||
{
|
||||
var op = Opcodes[opcode];
|
||||
w.WriteLine(" case 0x{0:X2}: // {1}", opcode, op);
|
||||
switch (op.Instruction)
|
||||
{
|
||||
case "ADC": ADC(op, w); break;
|
||||
case "AND": AND(op, w); break;
|
||||
case "ASL": ASL(op, w); break;
|
||||
case "BCC": Branch(op, w, "C", false); break;
|
||||
case "BCS": Branch(op, w, "C", true); break;
|
||||
case "BEQ": Branch(op, w, "Z", true); break;
|
||||
case "BIT": BIT(op, w); break;
|
||||
case "BMI": Branch(op, w, "N", true); break;
|
||||
case "BNE": Branch(op, w, "Z", false); break;
|
||||
case "BPL": Branch(op, w, "N", false); break;
|
||||
case "BRK": w.WriteLine(Spaces + "TriggerException(ExceptionType.BRK);"); break;
|
||||
case "BVC": Branch(op, w, "V", false); break;
|
||||
case "BVS": Branch(op, w, "V", true); break;
|
||||
case "CLC": CLC(op, w); break;
|
||||
case "CLD": CLD(op, w); break;
|
||||
case "CLI": CLI(op, w); break;
|
||||
case "CLV": CLV(op, w); break;
|
||||
case "CMP": CMP_reg(op, w, "A"); break;
|
||||
case "CPX": CMP_reg(op, w, "X"); break;
|
||||
case "CPY": CMP_reg(op, w, "Y"); break;
|
||||
case "DEC": DEC(op, w); break;
|
||||
case "DEX": DEX(op, w); break;
|
||||
case "DEY": DEY(op, w); break;
|
||||
case "EOR": EOR(op, w); break;
|
||||
case "INC": INC(op, w); break;
|
||||
case "INX": INX(op, w); break;
|
||||
case "INY": INY(op, w); break;
|
||||
case "JMP": JMP(op, w); break;
|
||||
case "JSR": JSR(op, w); break;
|
||||
case "LDA": LDA(op, w); break;
|
||||
case "LDX": LDX(op, w); break;
|
||||
case "LDY": LDY(op, w); break;
|
||||
case "LSR": LSR(op, w); break;
|
||||
case "NOP": NOP(op, w); break;
|
||||
case "ORA": ORA(op, w); break;
|
||||
case "PHA": PHA(op, w); break;
|
||||
case "PHP": PHP(op, w); break;
|
||||
case "PLA": PLA(op, w); break;
|
||||
case "PLP": PLP(op, w); break;
|
||||
case "ROL": ROL(op, w); break;
|
||||
case "ROR": ROR(op, w); break;
|
||||
case "RTI": RTI(op, w); break;
|
||||
case "RTS": RTS(op, w); break;
|
||||
case "SBC": SBC(op, w); break;
|
||||
case "SEC": SEC(op, w); break;
|
||||
case "SED": SED(op, w); break;
|
||||
case "SEI": SEI(op, w); break;
|
||||
case "STA": STA(op, w); break;
|
||||
case "STX": STX(op, w); break;
|
||||
case "STY": STY(op, w); break;
|
||||
case "TAX": TAX(op, w); break;
|
||||
case "TAY": TAY(op, w); break;
|
||||
case "TSX": TSX(op, w); break;
|
||||
case "TXA": TXA(op, w); break;
|
||||
case "TYA": TYA(op, w); break;
|
||||
case "TXS": TXS(op, w); break;
|
||||
}
|
||||
w.WriteLine(Spaces+"break;");
|
||||
}
|
||||
|
||||
private void GetValue8(OpcodeInfo op, TextWriter w, string dest)
|
||||
{
|
||||
switch (op.AddressMode)
|
||||
{
|
||||
case AddrMode.Immediate:
|
||||
w.WriteLine(Spaces + dest + " = ReadMemory(PC++);"); break;
|
||||
case AddrMode.ZeroPage:
|
||||
w.WriteLine(Spaces + dest + " = ReadMemory(ReadMemory(PC++));"); break;
|
||||
case AddrMode.ZeroPageX:
|
||||
w.WriteLine(Spaces + dest + " = ReadMemory((byte)(ReadMemory(PC++)+X));"); break;
|
||||
case AddrMode.ZeroPageY:
|
||||
w.WriteLine(Spaces + dest + " = ReadMemory((byte)(ReadMemory(PC++)+Y));"); break;
|
||||
case AddrMode.Absolute:
|
||||
w.WriteLine(Spaces + dest + " = ReadMemory(ReadWord(PC)); PC += 2;"); break;
|
||||
case AddrMode.AbsoluteX_P:
|
||||
w.WriteLine(Spaces + "temp16 = ReadWord(PC);");
|
||||
w.WriteLine(Spaces + dest + " = ReadMemory((ushort)(temp16+X));");
|
||||
w.WriteLine(Spaces + "if ((temp16 & 0xFF00) != ((temp16 + X) & 0xFF00)) ");
|
||||
w.WriteLine(Spaces + " { PendingCycles--; TotalExecutedCycles++; }");
|
||||
w.WriteLine(Spaces + "PC += 2;");
|
||||
break;
|
||||
case AddrMode.AbsoluteX:
|
||||
w.WriteLine(Spaces + dest + " = ReadMemory((ushort)(ReadWord(PC)+X));");
|
||||
w.WriteLine(Spaces + "PC += 2;");
|
||||
break;
|
||||
case AddrMode.AbsoluteY_P:
|
||||
w.WriteLine(Spaces + "temp16 = ReadWord(PC);");
|
||||
w.WriteLine(Spaces + dest + " = ReadMemory((ushort)(temp16+Y));");
|
||||
w.WriteLine(Spaces + "if ((temp16 & 0xFF00) != ((temp16 + Y) & 0xFF00)) ");
|
||||
w.WriteLine(Spaces + " { PendingCycles--; TotalExecutedCycles++; }");
|
||||
w.WriteLine(Spaces + "PC += 2;");
|
||||
break;
|
||||
case AddrMode.AbsoluteY:
|
||||
w.WriteLine(Spaces + dest + " = ReadMemory((ushort)(ReadWord(PC)+Y));");
|
||||
w.WriteLine(Spaces + "PC += 2;");
|
||||
break;
|
||||
case AddrMode.IndirectX:
|
||||
w.WriteLine(Spaces + dest + " = ReadMemory(ReadWordPageWrap((byte)(ReadMemory(PC++)+X)));"); break;
|
||||
case AddrMode.IndirectY:
|
||||
w.WriteLine(Spaces + dest + " = ReadMemory(ReadWordPageWrap((byte)(ReadMemory(PC++)+Y)));"); break;
|
||||
case AddrMode.IndirectY_P:
|
||||
w.WriteLine(Spaces + "temp16 = ReadWordPageWrap(ReadMemory(PC++));");
|
||||
w.WriteLine(Spaces + dest + " = ReadMemory((ushort)(temp16+Y));");
|
||||
w.WriteLine(Spaces + "if ((temp16 & 0xFF00) != ((temp16+Y) & 0xFF00)) ");
|
||||
w.WriteLine(Spaces + " { PendingCycles--; TotalExecutedCycles++; }");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void GetAddress(OpcodeInfo op, TextWriter w, string dest)
|
||||
{
|
||||
// TODO it APPEARS that the +1 opcode penalty applies to all AbsoluteX, AbsoluteY, and IndirectY
|
||||
// but this is not completely clear. the doc has some exceptions, but are they real?
|
||||
switch (op.AddressMode)
|
||||
{
|
||||
case AddrMode.ZeroPage:
|
||||
w.WriteLine(Spaces + dest + " = ReadMemory(PC++);"); break;
|
||||
case AddrMode.ZeroPageX:
|
||||
w.WriteLine(Spaces + dest + " = (byte)(ReadMemory(PC++)+X);"); break;
|
||||
case AddrMode.ZeroPageY:
|
||||
w.WriteLine(Spaces + dest + " = (byte)(ReadMemory(PC++)+Y);"); break;
|
||||
case AddrMode.Absolute:
|
||||
w.WriteLine(Spaces + dest + " = ReadWord(PC); PC += 2;"); break;
|
||||
case AddrMode.AbsoluteX:
|
||||
w.WriteLine(Spaces + dest + " = (ushort)(ReadWord(PC)+X);");
|
||||
w.WriteLine(Spaces + "PC += 2;");
|
||||
break;
|
||||
case AddrMode.AbsoluteX_P:
|
||||
w.WriteLine(Spaces + "temp16 = ReadWord(PC);");
|
||||
w.WriteLine(Spaces + dest + " = (ushort)(temp16+X);");
|
||||
w.WriteLine(Spaces + "if ((temp16 & 0xFF00) != ((temp16 + X) & 0xFF00)) ");
|
||||
w.WriteLine(Spaces + " { PendingCycles--; TotalExecutedCycles++; }");
|
||||
w.WriteLine(Spaces + "PC += 2;");
|
||||
break;
|
||||
case AddrMode.AbsoluteY:
|
||||
w.WriteLine(Spaces + dest + " = (ushort)(ReadWord(PC)+Y);");
|
||||
w.WriteLine(Spaces + "PC += 2;");
|
||||
break;
|
||||
case AddrMode.AbsoluteY_P:
|
||||
w.WriteLine(Spaces + "temp16 = ReadWord(PC);");
|
||||
w.WriteLine(Spaces + dest + " = (ushort)(temp16+Y);");
|
||||
w.WriteLine(Spaces + "if ((temp16 & 0xFF00) != ((temp16 + Y) & 0xFF00)) ");
|
||||
w.WriteLine(Spaces + " { PendingCycles--; TotalExecutedCycles++; }");
|
||||
w.WriteLine(Spaces + "PC += 2;");
|
||||
break;
|
||||
case AddrMode.IndirectX:
|
||||
w.WriteLine(Spaces + "temp8 = (byte)(ReadMemory(PC++) + X);");
|
||||
w.WriteLine(Spaces + dest + " = ReadWordPageWrap(temp8);");
|
||||
break;
|
||||
case AddrMode.IndirectY:
|
||||
w.WriteLine(Spaces + "temp16 = ReadWordPageWrap(ReadMemory(PC++));");
|
||||
w.WriteLine(Spaces + dest + " = (ushort)(temp16+Y);");
|
||||
break;
|
||||
case AddrMode.IndirectY_P:
|
||||
w.WriteLine(Spaces + "temp16 = ReadWordPageWrap(ReadMemory(PC++));");
|
||||
w.WriteLine(Spaces + dest + " = (ushort)(temp16+Y);");
|
||||
w.WriteLine(Spaces + "if ((temp16 & 0xFF00) != ((temp16+Y) & 0xFF00)) ");
|
||||
w.WriteLine(Spaces + " { PendingCycles--; TotalExecutedCycles++; }");
|
||||
break;
|
||||
case AddrMode.Relative:
|
||||
w.WriteLine(Spaces + "rel8 = (sbyte)ReadMemory(PC++);");
|
||||
w.WriteLine(Spaces + dest +" = (ushort)(PC+rel8);");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void GenerateDisassembler(string file)
|
||||
{
|
||||
var w = new StreamWriter(file, false);
|
||||
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.Common.Components.M6502");
|
||||
w.WriteLine("{");
|
||||
w.WriteLine(" public partial class MOS6502");
|
||||
w.WriteLine(" {");
|
||||
w.WriteLine(" public string Disassemble(ushort pc, out int bytesToAdvance)");
|
||||
w.WriteLine(" {");
|
||||
w.WriteLine(" byte op = ReadMemory(pc);");
|
||||
w.WriteLine(" switch (op)");
|
||||
w.WriteLine(" {");
|
||||
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
if (Opcodes[i] != null)
|
||||
DisassembleOpcode(w,i);
|
||||
}
|
||||
|
||||
w.WriteLine(" }");
|
||||
w.WriteLine(" bytesToAdvance = 1;");
|
||||
w.WriteLine(" return \"???\";");
|
||||
w.WriteLine(" }");
|
||||
w.WriteLine(" }");
|
||||
w.WriteLine("}");
|
||||
w.Close();
|
||||
}
|
||||
|
||||
private void DisassembleOpcode(TextWriter w, int i)
|
||||
{
|
||||
var op = Opcodes[i];
|
||||
w.Write(" case 0x{0:X2}: ", i);
|
||||
|
||||
string mstr;
|
||||
switch (op.AddressMode)
|
||||
{
|
||||
case AddrMode.Implicit: mstr = "\""+op.Instruction+"\""; break;
|
||||
case AddrMode.Accumulator: mstr = "\"" + op.Instruction + " A\""; break;
|
||||
case AddrMode.Immediate: mstr = "string.Format(\""+op.Instruction+" #${0:X2}\", ReadMemory(++pc))"; break;
|
||||
case AddrMode.ZeroPage: mstr = "string.Format(\"" + op.Instruction + " ${0:X2}\", ReadMemory(++pc))"; break;
|
||||
case AddrMode.ZeroPageX: mstr = "string.Format(\"" + op.Instruction + " ${0:X2},X\", ReadMemory(++pc))"; break;
|
||||
case AddrMode.ZeroPageY: mstr = "string.Format(\"" + op.Instruction + " ${0:X2},Y\", ReadMemory(++pc))"; break;
|
||||
case AddrMode.Absolute: mstr = "string.Format(\"" + op.Instruction + " ${0:X4}\", ReadWord(++pc))"; break;
|
||||
case AddrMode.AbsoluteX: mstr = "string.Format(\"" + op.Instruction + " ${0:X4},X\", ReadWord(++pc))"; break;
|
||||
case AddrMode.AbsoluteX_P: mstr = "string.Format(\"" + op.Instruction + " ${0:X4},X *\", ReadWord(++pc))"; break;
|
||||
case AddrMode.AbsoluteY: mstr = "string.Format(\"" + op.Instruction + " ${0:X4},Y\", ReadWord(++pc))"; break;
|
||||
case AddrMode.AbsoluteY_P: mstr = "string.Format(\"" + op.Instruction + " ${0:X4},Y *\", ReadWord(++pc))"; break;
|
||||
case AddrMode.Indirect: mstr = "string.Format(\"" + op.Instruction + " (${0:X4})\", ReadWord(++pc))"; break;
|
||||
case AddrMode.IndirectX: mstr = "string.Format(\"" + op.Instruction + " (${0:X2},X)\", ReadMemory(++pc))"; break;
|
||||
case AddrMode.IndirectY: mstr = "string.Format(\"" + op.Instruction + " (${0:X2}),Y\", ReadMemory(++pc))"; break;
|
||||
case AddrMode.IndirectY_P: mstr = "string.Format(\"" + op.Instruction + " (${0:X2}),Y *\", ReadMemory(++pc))"; break;
|
||||
case AddrMode.Relative: mstr = "string.Format(\"" + op.Instruction + " ${0:X4}\", pc+2+(sbyte)ReadMemory(++pc))"; break;
|
||||
default: mstr = @"""?"""; break;
|
||||
}
|
||||
|
||||
// BRK is 2-byte, but it is rarely used. So I don't care about it.
|
||||
w.Write("bytesToAdvance = {0}; ", op.Size);
|
||||
w.WriteLine("return " + mstr + ";");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,417 +0,0 @@
|
|||
using System.IO;
|
||||
|
||||
namespace M6502
|
||||
{
|
||||
public partial class CoreGenerator
|
||||
{
|
||||
private string SetNZ(string val)
|
||||
{
|
||||
return "P = (byte)((P & 0x7D) | TableNZ[" + val + "]);"; // NES version
|
||||
//return "P = (byte)((P & 0x5D) | TableNZ[" + val + "]);"; // PCE version
|
||||
}
|
||||
|
||||
private void ADC(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
GetValue8(op, w, "value8");
|
||||
w.WriteLine(Spaces + "temp = value8 + A + (FlagC ? 1 : 0);");
|
||||
w.WriteLine(Spaces + "FlagV = (~(A ^ value8) & (A ^ temp) & 0x80) != 0;");
|
||||
w.WriteLine(Spaces + "FlagC = temp > 0xFF;");
|
||||
w.WriteLine(Spaces + "A = (byte)temp;");
|
||||
w.WriteLine(Spaces + SetNZ("A"));
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void AND(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
GetValue8(op, w, "value8");
|
||||
w.WriteLine(Spaces + "A &= value8;");
|
||||
w.WriteLine(Spaces + SetNZ("A"));
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void ASL(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
if (op.AddressMode == AddrMode.Accumulator)
|
||||
{
|
||||
w.WriteLine(Spaces + "FlagC = (A & 0x80) != 0;");
|
||||
w.WriteLine(Spaces + "A = (byte) (A << 1);");
|
||||
w.WriteLine(Spaces + SetNZ("A"));
|
||||
} else {
|
||||
GetAddress(op, w, "value16");
|
||||
w.WriteLine(Spaces + "value8 = ReadMemory(value16);");
|
||||
w.WriteLine(Spaces + "FlagC = (value8 & 0x80) != 0;");
|
||||
w.WriteLine(Spaces + "value8 = (byte)(value8 << 1);");
|
||||
w.WriteLine(Spaces + "WriteMemory(value16, value8);");
|
||||
w.WriteLine(Spaces + SetNZ("value8"));
|
||||
}
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void Branch(OpcodeInfo op, TextWriter w, string flag, bool cond)
|
||||
{
|
||||
GetAddress(op, w, "value16");
|
||||
w.WriteLine(Spaces + "if (Flag"+flag+" == "+cond.ToString().ToLower()+") {");
|
||||
w.WriteLine(Spaces + " PendingCycles--; TotalExecutedCycles++;");
|
||||
w.WriteLine(Spaces + " if ((PC & 0xFF00) != (value16 & 0xFF00)) ");
|
||||
w.WriteLine(Spaces + " { PendingCycles--; TotalExecutedCycles++; }");
|
||||
w.WriteLine(Spaces + " PC = value16;");
|
||||
w.WriteLine(Spaces + "}");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void BIT(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
GetValue8(op, w, "value8");
|
||||
w.WriteLine(Spaces + "FlagN = (value8 & 0x80) != 0;");
|
||||
w.WriteLine(Spaces + "FlagV = (value8 & 0x40) != 0;");
|
||||
w.WriteLine(Spaces + "FlagZ = (A & value8) == 0;");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void CLC(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "FlagC = false;");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void CLD(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "FlagD = false;");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void CLI(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "//FlagI = false;");
|
||||
w.WriteLine(Spaces + "CLI_Pending = true;");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void CLV(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "FlagV = false;");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void CMP_reg(OpcodeInfo op, TextWriter w, string reg)
|
||||
{
|
||||
GetValue8(op, w, "value8");
|
||||
w.WriteLine(Spaces + "value16 = (ushort) (" + reg + " - value8);");
|
||||
w.WriteLine(Spaces + "FlagC = (" + reg + " >= value8);");
|
||||
w.WriteLine(Spaces + SetNZ("(byte)value16"));
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void DEC(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
GetAddress(op, w, "value16");
|
||||
w.WriteLine(Spaces + "value8 = (byte)(ReadMemory(value16) - 1);");
|
||||
w.WriteLine(Spaces + "WriteMemory(value16, value8);");
|
||||
w.WriteLine(Spaces + SetNZ("value8"));
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void DEX(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + SetNZ("--X"));
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void DEY(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + SetNZ("--Y"));
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void EOR(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
GetValue8(op, w, "value8");
|
||||
w.WriteLine(Spaces + "A ^= value8;");
|
||||
w.WriteLine(Spaces + SetNZ("A"));
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void INC(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
GetAddress(op, w, "value16");
|
||||
w.WriteLine(Spaces + "value8 = (byte)(ReadMemory(value16) + 1);");
|
||||
w.WriteLine(Spaces + "WriteMemory(value16, value8);");
|
||||
w.WriteLine(Spaces + SetNZ("value8"));
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void INX(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + SetNZ("++X"));
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void INY(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + SetNZ("++Y"));
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void JMP(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
switch (op.AddressMode)
|
||||
{
|
||||
case AddrMode.Absolute: w.WriteLine(Spaces+"PC = ReadWord(PC);"); break;
|
||||
case AddrMode.Indirect: w.WriteLine(Spaces+"PC = ReadWordPageWrap(ReadWord(PC));"); break;
|
||||
}
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void JSR(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "temp16 = (ushort)(PC+1);");
|
||||
w.WriteLine(Spaces + "WriteMemory((ushort)(S-- + 0x100), (byte)(temp16 >> 8));");
|
||||
w.WriteLine(Spaces + "WriteMemory((ushort)(S-- + 0x100), (byte)temp16);");
|
||||
w.WriteLine(Spaces + "PC = ReadWord(PC);");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void LDA(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
GetValue8(op, w, "A");
|
||||
w.WriteLine(Spaces + SetNZ("A"));
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void LDX(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
GetValue8(op, w, "X");
|
||||
w.WriteLine(Spaces + SetNZ("X"));
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void LDY(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
GetValue8(op, w, "Y");
|
||||
w.WriteLine(Spaces + SetNZ("Y"));
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void LSR(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
if (op.AddressMode == AddrMode.Accumulator)
|
||||
{
|
||||
w.WriteLine(Spaces + "FlagC = (A & 1) != 0;");
|
||||
w.WriteLine(Spaces + "A = (byte) (A >> 1);");
|
||||
w.WriteLine(Spaces + SetNZ("A"));
|
||||
} else {
|
||||
GetAddress(op, w, "value16");
|
||||
w.WriteLine(Spaces + "value8 = ReadMemory(value16);");
|
||||
w.WriteLine(Spaces + "FlagC = (value8 & 1) != 0;");
|
||||
w.WriteLine(Spaces + "value8 = (byte)(value8 >> 1);");
|
||||
w.WriteLine(Spaces + "WriteMemory(value16, value8);");
|
||||
w.WriteLine(Spaces + SetNZ("value8"));
|
||||
}
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void NOP(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
// This code is quite insufficient, but at least, we have to increment program counter appropriately.
|
||||
// For immediate addressing mode, it will be correct, and it will fix desyncs of "Puzznic (J)" and "Puzznic (U)".
|
||||
// For other addressing modes, I don't know whether they access memory, so further investigation will be needed.
|
||||
if (op.Size > 1)
|
||||
w.WriteLine(Spaces+"PC += {0};", op.Size-1);
|
||||
w.WriteLine(Spaces+"PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void ORA(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
GetValue8(op, w, "value8");
|
||||
w.WriteLine(Spaces + "A |= value8;");
|
||||
w.WriteLine(Spaces + SetNZ("A"));
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void PHA(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "WriteMemory((ushort)(S-- + 0x100), A);");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void PHP(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "FlagB = true; //why would it do this?? how weird");
|
||||
w.WriteLine(Spaces + "WriteMemory((ushort)(S-- + 0x100), P);");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void PLA(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "A = ReadMemory((ushort)(++S + 0x100));");
|
||||
w.WriteLine(Spaces + SetNZ("A"));
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void PLP(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "//handle I flag differently. sort of a sloppy way to do the job, but it does finish it off.");
|
||||
w.WriteLine(Spaces + "value8 = ReadMemory((ushort)(++S + 0x100));");
|
||||
w.WriteLine(Spaces + "if ((value8 & 0x04) != 0 && !FlagI)");
|
||||
w.WriteLine(Spaces + "\tSEI_Pending = true;");
|
||||
w.WriteLine(Spaces + "if ((value8 & 0x04) == 0 && FlagI)");
|
||||
w.WriteLine(Spaces + "\tCLI_Pending = true;");
|
||||
w.WriteLine(Spaces + "value8 &= unchecked((byte)~0x04);");
|
||||
w.WriteLine(Spaces + "P &= 0x04;");
|
||||
w.WriteLine(Spaces + "P |= value8;");
|
||||
w.WriteLine("FlagT = true;//this seems wrong");//this seems wrong
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void ROL(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
if (op.AddressMode == AddrMode.Accumulator)
|
||||
{
|
||||
w.WriteLine(Spaces + "temp8 = A;");
|
||||
w.WriteLine(Spaces + "A = (byte)((A << 1) | (P & 1));");
|
||||
w.WriteLine(Spaces + "FlagC = (temp8 & 0x80) != 0;");
|
||||
w.WriteLine(Spaces + SetNZ("A"));
|
||||
}
|
||||
else
|
||||
{
|
||||
GetAddress(op, w, "value16");
|
||||
w.WriteLine(Spaces + "value8 = temp8 = ReadMemory(value16);");
|
||||
w.WriteLine(Spaces + "value8 = (byte)((value8 << 1) | (P & 1));");
|
||||
w.WriteLine(Spaces + "WriteMemory(value16, value8);");
|
||||
w.WriteLine(Spaces + "FlagC = (temp8 & 0x80) != 0;");
|
||||
w.WriteLine(Spaces + SetNZ("value8"));
|
||||
}
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void ROR(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
if (op.AddressMode == AddrMode.Accumulator)
|
||||
{
|
||||
w.WriteLine(Spaces + "temp8 = A;");
|
||||
w.WriteLine(Spaces + "A = (byte)((A >> 1) | ((P & 1)<<7));");
|
||||
w.WriteLine(Spaces + "FlagC = (temp8 & 1) != 0;");
|
||||
w.WriteLine(Spaces + SetNZ("A"));
|
||||
}
|
||||
else
|
||||
{
|
||||
GetAddress(op, w, "value16");
|
||||
w.WriteLine(Spaces + "value8 = temp8 = ReadMemory(value16);");
|
||||
w.WriteLine(Spaces + "value8 = (byte)((value8 >> 1) | ((P & 1)<<7));");
|
||||
w.WriteLine(Spaces + "WriteMemory(value16, value8);");
|
||||
w.WriteLine(Spaces + "FlagC = (temp8 & 1) != 0;");
|
||||
w.WriteLine(Spaces + SetNZ("value8"));
|
||||
}
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void RTI(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "P = ReadMemory((ushort)(++S + 0x100));");
|
||||
w.WriteLine("FlagT = true;// this seems wrong");//this seems wrong
|
||||
w.WriteLine(Spaces + "PC = ReadMemory((ushort)(++S + 0x100));");
|
||||
w.WriteLine(Spaces + "PC |= (ushort)(ReadMemory((ushort)(++S + 0x100)) << 8);");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void RTS(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "PC = ReadMemory((ushort)(++S + 0x100));");
|
||||
w.WriteLine(Spaces + "PC |= (ushort)(ReadMemory((ushort)(++S + 0x100)) << 8);");
|
||||
w.WriteLine(Spaces + "PC++;");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void SBC(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
GetValue8(op, w, "value8");
|
||||
w.WriteLine(Spaces + "temp = A - value8 - (FlagC?0:1);");
|
||||
w.WriteLine(Spaces + "FlagV = ((A ^ value8) & (A ^ temp) & 0x80) != 0;");
|
||||
w.WriteLine(Spaces + "FlagC = temp >= 0;");
|
||||
w.WriteLine(Spaces + "A = (byte)temp;");
|
||||
w.WriteLine(Spaces + SetNZ("A"));
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void SEC(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "FlagC = true;");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void SED(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "FlagD = true;");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void SEI(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "//FlagI = true;");
|
||||
w.WriteLine(Spaces + "SEI_Pending = true;");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void STA(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
GetAddress(op, w, "value16");
|
||||
w.WriteLine(Spaces + "WriteMemory(value16, A);");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void STX(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
GetAddress(op, w, "value16");
|
||||
w.WriteLine(Spaces + "WriteMemory(value16, X);");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void STY(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
GetAddress(op, w, "value16");
|
||||
w.WriteLine(Spaces + "WriteMemory(value16, Y);");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void TAX(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "X = A;");
|
||||
w.WriteLine(Spaces + SetNZ("X"));
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void TAY(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "Y = A;");
|
||||
w.WriteLine(Spaces + SetNZ("Y"));
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void TSX(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "X = S;");
|
||||
w.WriteLine(Spaces + SetNZ("X"));
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void TXA(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "A = X;");
|
||||
w.WriteLine(Spaces + SetNZ("A"));
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void TXS(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "S = X;");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
private void TYA(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "A = Y;");
|
||||
w.WriteLine(Spaces + SetNZ("A"));
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
class Program
|
||||
{
|
||||
static void Main()
|
||||
{
|
||||
//We don't currently use this anymore
|
||||
//var x = new M6502.CoreGenerator();
|
||||
//x.InitOpcodeTable();
|
||||
//x.GenerateDisassembler("../../../BizHawk.Emulation.Common/CPUs/MOS 6502X/Disassembler.cs");
|
||||
//x.GenerateExecutor("../../../BizHawk.Emulation.Common/CPUs/MOS 6502X/Execute.cs");
|
||||
|
||||
var y = new HuC6280.CoreGenerator();
|
||||
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");
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("M6502CoreGenerator")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Microsoft")]
|
||||
[assembly: AssemblyProduct("M6502CoreGenerator")]
|
||||
[assembly: AssemblyCopyright("Copyright © Microsoft 2010")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("ab5eef8f-50f4-4c39-af46-8c5ba9404c6b")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
Loading…
Reference in New Issue