mirror of
https://github.com/fadden/6502bench.git
synced 2024-08-14 18:28:57 +00:00
The "affected flags" constants were incorrect for BIT, BRK, COP, RTI, XCE, and the undocmented instructions ANE, DCP, and SAX. The constants are used for the changed-flag summary shown in the info window and the instruction chart. Of greater import: the status flag updater for BIT was incorrectly marking N/V/C as indeterminate instead of N/V/Z. The undocmented instructions ANE, DCP, and SAX were also incorrect. The cycle counts shown in line comments are computed correctly, but the counts shown in the info window and instruction chart were displaying the full set of modifiers, ignoring the CPU type. That's okay for the info window, which spells the modifiers out, though it'd be better if the bits were explicitly marked as being applicable to the current CPU or a different one.
1227 lines
50 KiB
C#
1227 lines
50 KiB
C#
/*
|
|
* Copyright 2018 faddenSoft
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
using System;
|
|
using System.Diagnostics;
|
|
|
|
namespace Asm65 {
|
|
/// <summary>
|
|
/// CPU definition. Includes a set of 256 opcodes.
|
|
/// </summary>
|
|
public class CpuDef {
|
|
/// <summary>
|
|
/// Human-readable name.
|
|
/// </summary>
|
|
public string Name { get; private set; }
|
|
|
|
/// <summary>
|
|
/// Maximum possible address.
|
|
/// </summary>
|
|
public int MaxAddressValue { get; private set; }
|
|
|
|
/// <summary>
|
|
/// Does this CPU have a 16-bit address space?
|
|
/// </summary>
|
|
public bool HasAddr16 { get { return MaxAddressValue <= 0xffff; } }
|
|
|
|
/// <summary>
|
|
/// Does this CPU support the emulation flag (65802/65816)?
|
|
/// </summary>
|
|
public bool HasEmuFlag { get; private set; }
|
|
|
|
/// <summary>
|
|
/// CPU type value.
|
|
/// </summary>
|
|
public CpuType Type { get; private set; }
|
|
|
|
/// <summary>
|
|
/// True if undocumented opcodes are included. (This does not mean that the CPU has
|
|
/// undocumented opcodes, only that they haven't been stripped out if they exist.)
|
|
/// </summary>
|
|
public bool HasUndocumented { get; private set; }
|
|
|
|
/// <summary>
|
|
/// Instruction set, 256 entries.
|
|
/// </summary>
|
|
private OpDef[] mOpDefs;
|
|
|
|
/// <summary>
|
|
/// Cycle counts, 256 entries.
|
|
/// </summary>
|
|
private int[] mCycleCounts;
|
|
|
|
/// <summary>
|
|
/// Cycle count modifiers, 256 entries.
|
|
/// </summary>
|
|
private OpDef.CycleMod[] mCycleMods;
|
|
|
|
/// <summary>
|
|
/// List of "interesting" CPUs. These will be presented in the system definition
|
|
/// file when starting a new project. The actual set of CPUs that are unique (from
|
|
/// our perspective) is much smaller, as most of these can be represented accurately
|
|
/// (for disassembly purposes) by a handful of archetypes.
|
|
/// </summary>
|
|
public enum CpuType {
|
|
CpuUnknown = 0,
|
|
Cpu6502, // Apple ][+
|
|
Cpu6502B, // Atari 800
|
|
Cpu6507, // Atari 2600
|
|
Cpu6502C, // Atari 5200
|
|
Cpu6510, // Commodore 64
|
|
Cpu8502, // Commodore 128
|
|
Cpu2A03, // NES
|
|
|
|
Cpu65C02, // Apple //e
|
|
Cpu65SC02, // Atari Lynx
|
|
|
|
Cpu65802, // ?
|
|
Cpu65816, // Apple IIgs
|
|
Cpu5A22 // SNES
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts a CPU type name string to a CpuType value. Used for deserialization.
|
|
/// </summary>
|
|
/// <param name="name">Case-sensitive CPU name</param>
|
|
/// <returns>CpuType value, or CpuUnknown if name wasn't recognized.</returns>
|
|
public static CpuType GetCpuTypeFromName(string name) {
|
|
switch (name) {
|
|
case "6502": return CpuType.Cpu6502;
|
|
case "6502B": return CpuType.Cpu6502B;
|
|
case "6502C": return CpuType.Cpu6502C;
|
|
case "6507": return CpuType.Cpu6507;
|
|
case "6510": return CpuType.Cpu6510;
|
|
case "8502": return CpuType.Cpu8502;
|
|
case "2A03": return CpuType.Cpu2A03;
|
|
case "65C02": return CpuType.Cpu65C02;
|
|
case "65SC02": return CpuType.Cpu65SC02;
|
|
case "65802": return CpuType.Cpu65802;
|
|
case "65816": return CpuType.Cpu65816;
|
|
case "5A22": return CpuType.Cpu5A22;
|
|
default:
|
|
return CpuType.CpuUnknown;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts a CpuType value to a CPU type name string. Used for serialization.
|
|
/// </summary>
|
|
/// <param name="type">CPU type.</param>
|
|
/// <returns>CPU name string.</returns>
|
|
public static string GetCpuNameFromType(CpuType type) {
|
|
switch (type) {
|
|
case CpuType.Cpu6502: return "6502";
|
|
case CpuType.Cpu6502B: return "6502B";
|
|
case CpuType.Cpu6502C: return "6502C";
|
|
case CpuType.Cpu6507: return "6507";
|
|
case CpuType.Cpu6510: return "6510";
|
|
case CpuType.Cpu8502: return "8502";
|
|
case CpuType.Cpu2A03: return "2A03";
|
|
case CpuType.Cpu65C02: return "65C02";
|
|
case CpuType.Cpu65SC02: return "65SC02";
|
|
case CpuType.Cpu65802: return "65802";
|
|
case CpuType.Cpu65816: return "65816";
|
|
case CpuType.Cpu5A22: return "5A22";
|
|
default:
|
|
return "65??";
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generates a CpuDef that best matches the parameters.
|
|
/// </summary>
|
|
/// <param name="type">Specific CPU we want.</param>
|
|
/// <param name="includeUndocumented">Set to true if "undocumented" opcodes should
|
|
/// be included in the definition.</param>
|
|
/// <returns>Best CpuDef.</returns>
|
|
public static CpuDef GetBestMatch(CpuType type, bool includeUndocumented,
|
|
bool twoByteBrk) {
|
|
// Many 65xx variants boil down to a 6502, 65C02, or 65816, at least as far as
|
|
// a disassembler needs to know. These do not, and would need full definitions:
|
|
//
|
|
// Hudson Soft HuC6280 (PC Engine / TurboGrafx)
|
|
// Commodore CSG 4510 / CSG 65CE02 (Amiga A2232 serial port; 4510 has one
|
|
// additional instruction, so use that as archetype)
|
|
// Rockwell R65C02 (used in ???)
|
|
// Jeri's 65DTV02 (used in C64DTV single-chip computer); same as 6502 with
|
|
// some differences in illegal opcodes
|
|
// Eloraam 65EL02 (defined in a Minecraft-based emulator)
|
|
|
|
CpuDef cpuDef;
|
|
switch (type) {
|
|
case CpuType.Cpu65802:
|
|
case CpuType.Cpu65816:
|
|
case CpuType.Cpu5A22:
|
|
cpuDef = Cpu65816;
|
|
break;
|
|
case CpuType.Cpu65C02:
|
|
case CpuType.Cpu65SC02:
|
|
cpuDef = Cpu65C02;
|
|
break;
|
|
default:
|
|
// 6502, 6502B, 6502C, 6507, 6510, 8502, 2A03
|
|
cpuDef = Cpu6502;
|
|
break;
|
|
}
|
|
|
|
cpuDef.GenerateCycleCounts();
|
|
|
|
// If we don't want undocumented opcodes, strip them out of the definition.
|
|
// Entries are replaced with OpInvalid.
|
|
if (!includeUndocumented) {
|
|
CpuDef stripped = new CpuDef(cpuDef);
|
|
for (int i = 0; i < 256; i++) {
|
|
if (cpuDef.mOpDefs[i].IsUndocumented) {
|
|
stripped.mOpDefs[i] = OpDef.OpInvalid;
|
|
} else {
|
|
stripped.mOpDefs[i] = cpuDef.mOpDefs[i];
|
|
}
|
|
}
|
|
cpuDef = stripped;
|
|
}
|
|
|
|
// If we want two-byte BRKs, replace the entry with the StackInt form. Copy the rest.
|
|
if (twoByteBrk) {
|
|
CpuDef bigBrkDef = new CpuDef(cpuDef);
|
|
bigBrkDef.mOpDefs[0] = OpDef.OpBRK_StackInt;
|
|
for (int i = 1; i < 256; i++) {
|
|
bigBrkDef.mOpDefs[i] = cpuDef.mOpDefs[i];
|
|
}
|
|
cpuDef = bigBrkDef;
|
|
}
|
|
|
|
cpuDef.HasUndocumented = includeUndocumented;
|
|
|
|
return cpuDef;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Constructor.
|
|
/// </summary>
|
|
/// <param name="name">Human-readable name.</param>
|
|
/// <param name="maxAddressValue">Address space bits (16 or 24).</param>
|
|
private CpuDef(string name, int maxAddressValue, bool hasEmuFlag) {
|
|
Name = name;
|
|
MaxAddressValue = maxAddressValue;
|
|
HasEmuFlag = hasEmuFlag;
|
|
HasUndocumented = true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Copy constructor. Does not copy the contents of mOpDefs. Only used internally.
|
|
/// </summary>
|
|
/// <param name="src">Object to copy from.</param>
|
|
private CpuDef(CpuDef src) {
|
|
Name = src.Name;
|
|
MaxAddressValue = src.MaxAddressValue;
|
|
HasEmuFlag = src.HasEmuFlag;
|
|
Type = src.Type;
|
|
mCycleCounts = src.mCycleCounts;
|
|
mCycleMods = src.mCycleMods;
|
|
|
|
mOpDefs = new OpDef[256];
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Returns an entry from the OpDef array for the specified opcode, 0-255.
|
|
/// </summary>
|
|
/// <param name="op">Instruction opcode number (0-255).</param>
|
|
/// <returns>Instruction definition.</returns>
|
|
public OpDef GetOpDef(int op) { return mOpDefs[op]; }
|
|
|
|
/// <summary>
|
|
/// Returns the set of cycle mods for the given instruction that are in effect
|
|
/// for the current CPU.
|
|
/// </summary>
|
|
/// <param name="op">Instruction opcode number (0-255).</param>
|
|
/// <returns>Reduced cycle mod set.</returns>
|
|
public OpDef.CycleMod GetOpCycleMod(int op) { return mCycleMods[op]; }
|
|
|
|
/// <summary>
|
|
/// Indexer. Returns the definition of opcode N.
|
|
/// </summary>
|
|
public OpDef this[int op] {
|
|
get { return mOpDefs[op]; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the number of cycles required to execute the instruction. If the value
|
|
/// is negative, the negated value represents the minimum number of cycles for an
|
|
/// instruction with variable timing.
|
|
///
|
|
/// The value returned will factor in any CPU-specific aspects.
|
|
/// </summary>
|
|
/// <param name="opNum">Instruction opcode value.</param>
|
|
/// <returns>Cycle count.</returns>
|
|
public int GetCycles(int opNum, StatusFlags flags, OpDef.BranchTaken branchTaken,
|
|
bool branchCrossesPage) {
|
|
// The irrelevant modifiers have already been stripped out, e.g. OneIfD1 only
|
|
// affects the 65C02.
|
|
OpDef.CycleMod mods = mCycleMods[opNum];
|
|
int cycles = mCycleCounts[opNum];
|
|
|
|
// Walk through the various cycle mods. If we can evaluate them definitively,
|
|
// do so now and remove them from the set.
|
|
|
|
// The M/X flags are defined to be in one state or the other, even when the flag
|
|
// value is indeterminate, because we have to be able to size immediate operands
|
|
// appropriately. So there's no ambiguity here even when there's ambiguity. We
|
|
// make a similar statement about the E flag.
|
|
if ((mods & OpDef.CycleMod.OneIfM0) != 0) {
|
|
if (!flags.ShortM) {
|
|
cycles++;
|
|
}
|
|
mods &= ~OpDef.CycleMod.OneIfM0;
|
|
}
|
|
if ((mods & OpDef.CycleMod.TwoIfM0) != 0) {
|
|
if (!flags.ShortM) {
|
|
cycles += 2;
|
|
}
|
|
mods &= ~OpDef.CycleMod.TwoIfM0;
|
|
}
|
|
if ((mods & OpDef.CycleMod.OneIfX0) != 0) {
|
|
if (!flags.ShortX) {
|
|
cycles++;
|
|
}
|
|
mods &= ~OpDef.CycleMod.OneIfX0;
|
|
}
|
|
if ((mods & OpDef.CycleMod.OneIfE0) != 0) {
|
|
if (flags.E == 0) {
|
|
cycles++;
|
|
}
|
|
mods &= ~OpDef.CycleMod.OneIfE0;
|
|
}
|
|
|
|
// Some of these can be known, some can't.
|
|
if ((mods & OpDef.CycleMod.OneIfD1) != 0) {
|
|
if (flags.D == 1) {
|
|
cycles++;
|
|
}
|
|
if (flags.D == 0 || flags.D == 1) {
|
|
mods &= ~OpDef.CycleMod.OneIfD1;
|
|
}
|
|
}
|
|
if ((mods & OpDef.CycleMod.OneIfBranchTaken) != 0) {
|
|
if (branchTaken == OpDef.BranchTaken.Always) {
|
|
cycles++;
|
|
}
|
|
if (branchTaken != OpDef.BranchTaken.Indeterminate) {
|
|
mods &= ~OpDef.CycleMod.OneIfBranchTaken;
|
|
}
|
|
}
|
|
if ((mods & OpDef.CycleMod.OneIfBranchPage) != 0) {
|
|
if (branchCrossesPage && flags.E != 0) {
|
|
cycles++; // +1 unless we're in native mode on 65816
|
|
}
|
|
mods &= ~OpDef.CycleMod.OneIfBranchPage;
|
|
}
|
|
|
|
// We can't evaluate OneIfDpNonzero, OneIfIndexPage, or MinusOneIfNoPage.
|
|
// OneIf65C02 was handled earlier.
|
|
// TODO(maybe): in some cases we can know that the index doesn't cross a
|
|
// page boundary by checking the address, e.g. "LDA $2000,X" can't cross.
|
|
|
|
if (mods != 0) {
|
|
// Some unresolved mods remain.
|
|
cycles = -cycles;
|
|
}
|
|
return cycles;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Consistency test.
|
|
/// </summary>
|
|
/// <returns>True on success.</returns>
|
|
public static bool DebugValidate() {
|
|
InternalValidate(Cpu6502);
|
|
InternalValidate(Cpu65C02);
|
|
InternalValidate(Cpu65816);
|
|
Debug.WriteLine("CpuDefs okay");
|
|
return true;
|
|
}
|
|
private static void InternalValidate(CpuDef cdef) {
|
|
for (int i = 0; i < 256; i++) {
|
|
OpDef op = cdef.mOpDefs[i];
|
|
if (op.Opcode != i && op.AddrMode != OpDef.AddressMode.Unknown) {
|
|
throw new Exception("CpuDef for " + cdef.Type + ": entry 0x" +
|
|
i.ToString("x") + " has value " + op.Opcode.ToString("x"));
|
|
}
|
|
if (op.AddrMode != OpDef.AddressMode.Unknown && op.Cycles == 0) {
|
|
throw new Exception("Instruction 0x" + i.ToString("x2") + ": " +
|
|
op + " missing cycles");
|
|
}
|
|
}
|
|
}
|
|
|
|
public override string ToString() {
|
|
return Name + " (has16=" + HasAddr16 + ", hasEmu=" + HasEmuFlag + ", hasUndoc=" +
|
|
HasUndocumented + ")";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generates the mCycleCounts and mCycleMods arrays.
|
|
/// </summary>
|
|
private void GenerateCycleCounts() {
|
|
if (mCycleCounts != null) {
|
|
return;
|
|
}
|
|
mCycleCounts = new int[256];
|
|
mCycleMods = new OpDef.CycleMod[256];
|
|
|
|
// Figure out which mods apply for this CPU.
|
|
OpDef.CycleMod ignoreMask = 0;
|
|
switch (Type) {
|
|
case CpuType.Cpu6502:
|
|
ignoreMask = OpDef.CycleMod.OneIfM0 |
|
|
OpDef.CycleMod.TwoIfM0 |
|
|
OpDef.CycleMod.OneIfX0 |
|
|
OpDef.CycleMod.OneIfDpNonzero |
|
|
OpDef.CycleMod.OneIfD1 |
|
|
OpDef.CycleMod.OneIfE0 |
|
|
OpDef.CycleMod.OneIf65C02 |
|
|
OpDef.CycleMod.MinusOneIfNoPage |
|
|
OpDef.CycleMod.BlockMove;
|
|
break;
|
|
case CpuType.Cpu65C02:
|
|
ignoreMask = OpDef.CycleMod.OneIfM0 |
|
|
OpDef.CycleMod.TwoIfM0 |
|
|
OpDef.CycleMod.OneIfX0 |
|
|
OpDef.CycleMod.OneIfDpNonzero |
|
|
OpDef.CycleMod.OneIfE0 |
|
|
OpDef.CycleMod.BlockMove;
|
|
break;
|
|
case CpuType.Cpu65816:
|
|
ignoreMask = OpDef.CycleMod.OneIfD1 |
|
|
OpDef.CycleMod.OneIf65C02 |
|
|
OpDef.CycleMod.MinusOneIfNoPage;
|
|
break;
|
|
default:
|
|
Debug.Assert(false, "unsupported cpu type " + Type);
|
|
return;
|
|
}
|
|
|
|
// If an instruction has one or more applicable mods, declare it as variable.
|
|
for (int i = 0; i < 256; i++) {
|
|
OpDef op = mOpDefs[i];
|
|
int baseCycles = op.Cycles;
|
|
OpDef.CycleMod mods = op.CycleMods & ~ignoreMask;
|
|
if ((mods & OpDef.CycleMod.OneIf65C02) != 0) {
|
|
// This isn't variable -- the instruction always takes one cycle longer
|
|
// on the 65C02. (Applies to $6C, JMP (addr).)
|
|
Debug.Assert(Type == CpuType.Cpu65C02);
|
|
baseCycles++;
|
|
mods &= ~OpDef.CycleMod.OneIf65C02;
|
|
}
|
|
mCycleCounts[i] = baseCycles;
|
|
mCycleMods[i] = mods;
|
|
}
|
|
}
|
|
|
|
|
|
// Classic MOS 6502, with full set of undocumented opcodes.
|
|
private static CpuDef Cpu6502 { get; } = new CpuDef("MOS 6502", (1 << 16) - 1, false) {
|
|
Type = CpuType.Cpu6502,
|
|
mOpDefs = new OpDef[] {
|
|
OpDef.OpBRK_Implied, // 0x00
|
|
OpDef.OpORA_DPIndexXInd,
|
|
OpDef.GenerateUndoc(0x02, OpDef.OpJAM_Implied),
|
|
OpDef.OpSLO_DPIndexXInd,
|
|
OpDef.GenerateUndoc(0x04, OpDef.OpDOP_DP),
|
|
OpDef.OpORA_DP,
|
|
OpDef.OpASL_DP,
|
|
OpDef.OpSLO_DP,
|
|
OpDef.OpPHP_StackPush, // 0x08
|
|
OpDef.OpORA_Imm,
|
|
OpDef.OpASL_Acc,
|
|
OpDef.GenerateUndoc(0x0b, OpDef.OpANC_Imm),
|
|
OpDef.OpTOP_Abs,
|
|
OpDef.OpORA_Abs,
|
|
OpDef.OpASL_Abs,
|
|
OpDef.OpSLO_Absolute,
|
|
OpDef.OpBPL_PCRel, // 0x10
|
|
OpDef.OpORA_DPIndIndexY,
|
|
OpDef.GenerateUndoc(0x12, OpDef.OpJAM_Implied),
|
|
OpDef.OpSLO_DPIndIndexY,
|
|
OpDef.GenerateUndoc(0x14, OpDef.OpDOP_DPIndexX),
|
|
OpDef.OpORA_DPIndexX,
|
|
OpDef.OpASL_DPIndexX,
|
|
OpDef.OpSLO_DPIndexX,
|
|
OpDef.OpCLC_Implied, // 0x18
|
|
OpDef.OpORA_AbsIndexY,
|
|
OpDef.GenerateUndoc(0x1a, OpDef.OpNOP_Implied),
|
|
OpDef.OpSLO_AbsIndexY,
|
|
OpDef.GenerateUndoc(0x1c, OpDef.OpTOP_AbsIndeX),
|
|
OpDef.OpORA_AbsIndexX,
|
|
OpDef.OpASL_AbsIndexX,
|
|
OpDef.OpSLO_AbsIndexX,
|
|
OpDef.OpJSR_Abs, // 0x20
|
|
OpDef.OpAND_DPIndexXInd,
|
|
OpDef.GenerateUndoc(0x22, OpDef.OpJAM_Implied),
|
|
OpDef.OpRLA_DPIndexXInd,
|
|
OpDef.OpBIT_DP,
|
|
OpDef.OpAND_DP,
|
|
OpDef.OpROL_DP,
|
|
OpDef.OpRLA_DP,
|
|
OpDef.OpPLP_StackPull, // 0x28
|
|
OpDef.OpAND_Imm,
|
|
OpDef.OpROL_Acc,
|
|
OpDef.GenerateUndoc(0x2b, OpDef.OpANC_Imm),
|
|
OpDef.OpBIT_Abs,
|
|
OpDef.OpAND_Abs,
|
|
OpDef.OpROL_Abs,
|
|
OpDef.OpRLA_Absolute,
|
|
OpDef.OpBMI_PCRel, // 0x30
|
|
OpDef.OpAND_DPIndIndexY,
|
|
OpDef.GenerateUndoc(0x32, OpDef.OpJAM_Implied),
|
|
OpDef.OpRLA_DPIndIndexY,
|
|
OpDef.GenerateUndoc(0x34, OpDef.OpDOP_DPIndexX),
|
|
OpDef.OpAND_DPIndexX,
|
|
OpDef.OpROL_DPIndexX,
|
|
OpDef.OpRLA_DPIndexX,
|
|
OpDef.OpSEC_Implied, // 0x38
|
|
OpDef.OpAND_AbsIndexY,
|
|
OpDef.GenerateUndoc(0x3a, OpDef.OpNOP_Implied),
|
|
OpDef.OpRLA_AbsIndexY,
|
|
OpDef.GenerateUndoc(0x3c, OpDef.OpTOP_AbsIndeX),
|
|
OpDef.OpAND_AbsIndexX,
|
|
OpDef.OpROL_AbsIndexX,
|
|
OpDef.OpRLA_AbsIndexX,
|
|
OpDef.OpRTI_StackRTI, // 0x40
|
|
OpDef.OpEOR_DPIndexXInd,
|
|
OpDef.GenerateUndoc(0x42, OpDef.OpJAM_Implied),
|
|
OpDef.OpSRE_DPIndexXInd,
|
|
OpDef.GenerateUndoc(0x44, OpDef.OpDOP_DP),
|
|
OpDef.OpEOR_DP,
|
|
OpDef.OpLSR_DP,
|
|
OpDef.OpSRE_DP,
|
|
OpDef.OpPHA_StackPush, // 0x48
|
|
OpDef.OpEOR_Imm,
|
|
OpDef.OpLSR_Acc,
|
|
OpDef.OpALR_Imm,
|
|
OpDef.OpJMP_Abs,
|
|
OpDef.OpEOR_Abs,
|
|
OpDef.OpLSR_Abs,
|
|
OpDef.OpSRE_Absolute,
|
|
OpDef.OpBVC_PCRel, // 0x50
|
|
OpDef.OpEOR_DPIndIndexY,
|
|
OpDef.GenerateUndoc(0x52, OpDef.OpJAM_Implied),
|
|
OpDef.OpSRE_DPIndIndexY,
|
|
OpDef.GenerateUndoc(0x54, OpDef.OpDOP_DPIndexX),
|
|
OpDef.OpEOR_DPIndexX,
|
|
OpDef.OpLSR_DPIndexX,
|
|
OpDef.OpSRE_DPIndexX,
|
|
OpDef.OpCLI_Implied, // 0x58
|
|
OpDef.OpEOR_AbsIndexY,
|
|
OpDef.GenerateUndoc(0x5a, OpDef.OpNOP_Implied),
|
|
OpDef.OpSRE_AbsIndexY,
|
|
OpDef.GenerateUndoc(0x5c, OpDef.OpTOP_AbsIndeX),
|
|
OpDef.OpEOR_AbsIndexX,
|
|
OpDef.OpLSR_AbsIndexX,
|
|
OpDef.OpSRE_AbsIndexX,
|
|
OpDef.OpRTS_StackRTS, // 0x60
|
|
OpDef.OpADC_DPIndexXInd,
|
|
OpDef.GenerateUndoc(0x62, OpDef.OpJAM_Implied),
|
|
OpDef.OpRRA_DPIndexXInd,
|
|
OpDef.GenerateUndoc(0x64, OpDef.OpDOP_DP),
|
|
OpDef.OpADC_DP,
|
|
OpDef.OpROR_DP,
|
|
OpDef.OpRRA_DP,
|
|
OpDef.OpPLA_StackPull, // 0x68
|
|
OpDef.OpADC_Imm,
|
|
OpDef.OpROR_Acc,
|
|
OpDef.OpARR_Imm,
|
|
OpDef.OpJMP_AbsInd,
|
|
OpDef.OpADC_Abs,
|
|
OpDef.OpROR_Abs,
|
|
OpDef.OpRRA_Absolute,
|
|
OpDef.OpBVS_PCRel, // 0x70
|
|
OpDef.OpADC_DPIndIndexY,
|
|
OpDef.GenerateUndoc(0x72, OpDef.OpJAM_Implied),
|
|
OpDef.OpRRA_DPIndIndexY,
|
|
OpDef.GenerateUndoc(0x74, OpDef.OpDOP_DPIndexX),
|
|
OpDef.OpADC_DPIndexX,
|
|
OpDef.OpROR_DPIndexX,
|
|
OpDef.OpRRA_DPIndexX,
|
|
OpDef.OpSEI_Implied, // 0x78
|
|
OpDef.OpADC_AbsIndexY,
|
|
OpDef.GenerateUndoc(0x7a, OpDef.OpNOP_Implied),
|
|
OpDef.OpRRA_AbsIndexY,
|
|
OpDef.GenerateUndoc(0x7c, OpDef.OpTOP_AbsIndeX),
|
|
OpDef.OpADC_AbsIndexX,
|
|
OpDef.OpROR_AbsIndexX,
|
|
OpDef.OpRRA_AbsIndexX,
|
|
OpDef.GenerateUndoc(0x80, OpDef.OpDOP_Imm), // 0x80
|
|
OpDef.OpSTA_DPIndexXInd,
|
|
OpDef.GenerateUndoc(0x82, OpDef.OpDOP_Imm),
|
|
OpDef.OpSAX_DPIndexXInd,
|
|
OpDef.OpSTY_DP,
|
|
OpDef.OpSTA_DP,
|
|
OpDef.OpSTX_DP,
|
|
OpDef.OpSAX_DP,
|
|
OpDef.OpDEY_Implied, // 0x88
|
|
OpDef.GenerateUndoc(0x89, OpDef.OpDOP_Imm),
|
|
OpDef.OpTXA_Implied,
|
|
OpDef.OpANE_Imm,
|
|
OpDef.OpSTY_Abs,
|
|
OpDef.OpSTA_Abs,
|
|
OpDef.OpSTX_Abs,
|
|
OpDef.OpSAX_Absolute,
|
|
OpDef.OpBCC_PCRel, // 0x90
|
|
OpDef.OpSTA_DPIndIndexY,
|
|
OpDef.GenerateUndoc(0x92, OpDef.OpJAM_Implied),
|
|
OpDef.OpSHA_DPIndIndexY,
|
|
OpDef.OpSTY_DPIndexX,
|
|
OpDef.OpSTA_DPIndexX,
|
|
OpDef.OpSTX_DPIndexY,
|
|
OpDef.OpSAX_DPIndexY,
|
|
OpDef.OpTYA_Implied, // 0x98
|
|
OpDef.OpSTA_AbsIndexY,
|
|
OpDef.OpTXS_Implied,
|
|
OpDef.OpTAS_AbsIndexY,
|
|
OpDef.OpSHY_AbsIndexX,
|
|
OpDef.OpSTA_AbsIndexX,
|
|
OpDef.OpSHX_AbsIndexY,
|
|
OpDef.OpSHA_AbsIndexY,
|
|
OpDef.OpLDY_Imm, // 0xa0
|
|
OpDef.OpLDA_DPIndexXInd,
|
|
OpDef.OpLDX_Imm,
|
|
OpDef.OpLAX_DPIndexXInd,
|
|
OpDef.OpLDY_DP,
|
|
OpDef.OpLDA_DP,
|
|
OpDef.OpLDX_DP,
|
|
OpDef.OpLAX_DP,
|
|
OpDef.OpTAY_Implied, // 0xa8
|
|
OpDef.OpLDA_Imm,
|
|
OpDef.OpTAX_Implied,
|
|
OpDef.OpLAX_Imm,
|
|
OpDef.OpLDY_Abs,
|
|
OpDef.OpLDA_Abs,
|
|
OpDef.OpLDX_Abs,
|
|
OpDef.OpLAX_Absolute,
|
|
OpDef.OpBCS_PCRel, // 0xb0
|
|
OpDef.OpLDA_DPIndIndexY,
|
|
OpDef.GenerateUndoc(0xb2, OpDef.OpJAM_Implied),
|
|
OpDef.OpLAX_DPIndIndexY,
|
|
OpDef.OpLDY_DPIndexX,
|
|
OpDef.OpLDA_DPIndexX,
|
|
OpDef.OpLDX_DPIndexY,
|
|
OpDef.OpLAX_DPIndexY,
|
|
OpDef.OpCLV_Implied, // 0xb8
|
|
OpDef.OpLDA_AbsIndexY,
|
|
OpDef.OpTSX_Implied,
|
|
OpDef.OpLAS_AbsIndexY,
|
|
OpDef.OpLDY_AbsIndexX,
|
|
OpDef.OpLDA_AbsIndexX,
|
|
OpDef.OpLDX_AbsIndexY,
|
|
OpDef.OpLAX_AbsIndexY,
|
|
OpDef.OpCPY_Imm, // 0xc0
|
|
OpDef.OpCMP_DPIndexXInd,
|
|
OpDef.GenerateUndoc(0xc2, OpDef.OpDOP_Imm),
|
|
OpDef.OpDCP_DPIndexXInd,
|
|
OpDef.OpCPY_DP,
|
|
OpDef.OpCMP_DP,
|
|
OpDef.OpDEC_DP,
|
|
OpDef.OpDCP_DP,
|
|
OpDef.OpINY_Implied, // 0xc8
|
|
OpDef.OpCMP_Imm,
|
|
OpDef.OpDEX_Implied,
|
|
OpDef.OpSBX_Imm,
|
|
OpDef.OpCPY_Abs,
|
|
OpDef.OpCMP_Abs,
|
|
OpDef.OpDEC_Abs,
|
|
OpDef.OpDCP_Abs,
|
|
OpDef.OpBNE_PCRel, // 0xd0
|
|
OpDef.OpCMP_DPIndIndexY,
|
|
OpDef.GenerateUndoc(0xd2, OpDef.OpJAM_Implied),
|
|
OpDef.OpDCP_DPIndIndexY,
|
|
OpDef.GenerateUndoc(0xd4, OpDef.OpDOP_DPIndexX),
|
|
OpDef.OpCMP_DPIndexX,
|
|
OpDef.OpDEC_DPIndexX,
|
|
OpDef.OpDCP_DPIndexX,
|
|
OpDef.OpCLD_Implied, // 0xd8
|
|
OpDef.OpCMP_AbsIndexY,
|
|
OpDef.GenerateUndoc(0xda, OpDef.OpNOP_Implied),
|
|
OpDef.OpDCP_AbsIndexY,
|
|
OpDef.GenerateUndoc(0xdc, OpDef.OpTOP_AbsIndeX),
|
|
OpDef.OpCMP_AbsIndexX,
|
|
OpDef.OpDEC_AbsIndexX,
|
|
OpDef.OpDCP_AbsIndexX,
|
|
OpDef.OpCPX_Imm, // 0xe0
|
|
OpDef.OpSBC_DPIndexXInd,
|
|
OpDef.GenerateUndoc(0xe2, OpDef.OpDOP_Imm),
|
|
OpDef.OpISC_DPIndexXInd,
|
|
OpDef.OpCPX_DP,
|
|
OpDef.OpSBC_DP,
|
|
OpDef.OpINC_DP,
|
|
OpDef.OpISC_DP,
|
|
OpDef.OpINX_Implied, // 0xe8
|
|
OpDef.OpSBC_Imm,
|
|
OpDef.OpNOP_Implied,
|
|
OpDef.GenerateUndoc(0xeb, OpDef.OpSBC_Imm),
|
|
OpDef.OpCPX_Abs,
|
|
OpDef.OpSBC_Abs,
|
|
OpDef.OpINC_Abs,
|
|
OpDef.OpISC_Abs,
|
|
OpDef.OpBEQ_PCRel, // 0xf0
|
|
OpDef.OpSBC_DPIndIndexY,
|
|
OpDef.GenerateUndoc(0xf2, OpDef.OpJAM_Implied),
|
|
OpDef.OpISC_DPIndIndexY,
|
|
OpDef.GenerateUndoc(0xf4, OpDef.OpDOP_DPIndexX),
|
|
OpDef.OpSBC_DPIndexX,
|
|
OpDef.OpINC_DPIndexX,
|
|
OpDef.OpISC_DPIndexX,
|
|
OpDef.OpSED_Implied, // 0xf8
|
|
OpDef.OpSBC_AbsIndexY,
|
|
OpDef.GenerateUndoc(0xfa, OpDef.OpNOP_Implied),
|
|
OpDef.OpISC_AbsIndexY,
|
|
OpDef.GenerateUndoc(0xfc, OpDef.OpTOP_AbsIndeX),
|
|
OpDef.OpSBC_AbsIndexX,
|
|
OpDef.OpINC_AbsIndexX,
|
|
OpDef.OpISC_AbsIndexX,
|
|
}
|
|
};
|
|
|
|
|
|
// WDC's 65C02, with new opcodes and a handful of slightly strange NOPs.
|
|
private static CpuDef Cpu65C02 { get; } = new CpuDef("WDC W65C02S", (1 << 16) - 1, false) {
|
|
Type = CpuType.Cpu65C02,
|
|
mOpDefs = new OpDef[] {
|
|
OpDef.OpBRK_Implied, // 0x00
|
|
OpDef.OpORA_DPIndexXInd,
|
|
OpDef.GenerateUndoc(0x02, OpDef.OpLDD_Imm),
|
|
OpDef.GenerateUndoc(0x03, OpDef.OpNOP_65C02),
|
|
OpDef.OpTSB_DP,
|
|
OpDef.OpORA_DP,
|
|
OpDef.OpASL_DP,
|
|
OpDef.GenerateUndoc(0x07, OpDef.OpNOP_65C02),
|
|
OpDef.OpPHP_StackPush, // 0x08
|
|
OpDef.OpORA_Imm,
|
|
OpDef.OpASL_Acc,
|
|
OpDef.GenerateUndoc(0x0b, OpDef.OpNOP_65C02),
|
|
OpDef.OpTSB_Abs,
|
|
OpDef.OpORA_Abs,
|
|
OpDef.OpASL_Abs,
|
|
OpDef.GenerateUndoc(0x0f, OpDef.OpNOP_65C02),
|
|
OpDef.OpBPL_PCRel, // 0x10
|
|
OpDef.OpORA_DPIndIndexY,
|
|
OpDef.OpORA_DPInd,
|
|
OpDef.GenerateUndoc(0x13, OpDef.OpNOP_65C02),
|
|
OpDef.OpTRB_DP,
|
|
OpDef.OpORA_DPIndexX,
|
|
OpDef.OpASL_DPIndexX,
|
|
OpDef.GenerateUndoc(0x17, OpDef.OpNOP_65C02),
|
|
OpDef.OpCLC_Implied, // 0x18
|
|
OpDef.OpORA_AbsIndexY,
|
|
OpDef.OpINC_Acc,
|
|
OpDef.GenerateUndoc(0x1b, OpDef.OpNOP_65C02),
|
|
OpDef.OpTRB_Abs,
|
|
OpDef.OpORA_AbsIndexX,
|
|
OpDef.OpASL_AbsIndexX,
|
|
OpDef.GenerateUndoc(0x1f, OpDef.OpNOP_65C02),
|
|
OpDef.OpJSR_Abs, // 0x20
|
|
OpDef.OpAND_DPIndexXInd,
|
|
OpDef.GenerateUndoc(0x22, OpDef.OpLDD_Imm),
|
|
OpDef.GenerateUndoc(0x23, OpDef.OpNOP_65C02),
|
|
OpDef.OpBIT_DP,
|
|
OpDef.OpAND_DP,
|
|
OpDef.OpROL_DP,
|
|
OpDef.GenerateUndoc(0x27, OpDef.OpNOP_65C02),
|
|
OpDef.OpPLP_StackPull, // 0x28
|
|
OpDef.OpAND_Imm,
|
|
OpDef.OpROL_Acc,
|
|
OpDef.GenerateUndoc(0x2b, OpDef.OpNOP_65C02),
|
|
OpDef.OpBIT_Abs,
|
|
OpDef.OpAND_Abs,
|
|
OpDef.OpROL_Abs,
|
|
OpDef.GenerateUndoc(0x2f, OpDef.OpNOP_65C02),
|
|
OpDef.OpBMI_PCRel, // 0x30
|
|
OpDef.OpAND_DPIndIndexY,
|
|
OpDef.OpAND_DPInd,
|
|
OpDef.GenerateUndoc(0x33, OpDef.OpNOP_65C02),
|
|
OpDef.OpBIT_DPIndexX,
|
|
OpDef.OpAND_DPIndexX,
|
|
OpDef.OpROL_DPIndexX,
|
|
OpDef.GenerateUndoc(0x37, OpDef.OpNOP_65C02),
|
|
OpDef.OpSEC_Implied, // 0x38
|
|
OpDef.OpAND_AbsIndexY,
|
|
OpDef.OpDEC_Acc,
|
|
OpDef.GenerateUndoc(0x3b, OpDef.OpNOP_65C02),
|
|
OpDef.OpBIT_AbsIndexX,
|
|
OpDef.OpAND_AbsIndexX,
|
|
OpDef.OpROL_AbsIndexX,
|
|
OpDef.GenerateUndoc(0x3f, OpDef.OpNOP_65C02),
|
|
OpDef.OpRTI_StackRTI, // 0x40
|
|
OpDef.OpEOR_DPIndexXInd,
|
|
OpDef.GenerateUndoc(0x42, OpDef.OpLDD_Imm),
|
|
OpDef.GenerateUndoc(0x43, OpDef.OpNOP_65C02),
|
|
OpDef.GenerateUndoc(0x44, OpDef.OpLDD_DP),
|
|
OpDef.OpEOR_DP,
|
|
OpDef.OpLSR_DP,
|
|
OpDef.GenerateUndoc(0x47, OpDef.OpNOP_65C02),
|
|
OpDef.OpPHA_StackPush, // 0x48
|
|
OpDef.OpEOR_Imm,
|
|
OpDef.OpLSR_Acc,
|
|
OpDef.GenerateUndoc(0x4b, OpDef.OpNOP_65C02),
|
|
OpDef.OpJMP_Abs,
|
|
OpDef.OpEOR_Abs,
|
|
OpDef.OpLSR_Abs,
|
|
OpDef.GenerateUndoc(0x4f, OpDef.OpNOP_65C02),
|
|
OpDef.OpBVC_PCRel, // 0x50
|
|
OpDef.OpEOR_DPIndIndexY,
|
|
OpDef.OpEOR_DPInd,
|
|
OpDef.GenerateUndoc(0x53, OpDef.OpNOP_65C02),
|
|
OpDef.GenerateUndoc(0x54, OpDef.OpLDD_DPIndexX),
|
|
OpDef.OpEOR_DPIndexX,
|
|
OpDef.OpLSR_DPIndexX,
|
|
OpDef.GenerateUndoc(0x57, OpDef.OpNOP_65C02),
|
|
OpDef.OpCLI_Implied, // 0x58
|
|
OpDef.OpEOR_AbsIndexY,
|
|
OpDef.OpPHY_StackPush,
|
|
OpDef.GenerateUndoc(0x5b, OpDef.OpNOP_65C02),
|
|
OpDef.GenerateUndoc(0x5c, OpDef.OpLDD_Weird),
|
|
OpDef.OpEOR_AbsIndexX,
|
|
OpDef.OpLSR_AbsIndexX,
|
|
OpDef.GenerateUndoc(0x5f, OpDef.OpNOP_65C02),
|
|
OpDef.OpRTS_StackRTS, // 0x60
|
|
OpDef.OpADC_DPIndexXInd,
|
|
OpDef.GenerateUndoc(0x62, OpDef.OpLDD_Imm),
|
|
OpDef.GenerateUndoc(0x63, OpDef.OpNOP_65C02),
|
|
OpDef.OpSTZ_DP,
|
|
OpDef.OpADC_DP,
|
|
OpDef.OpROR_DP,
|
|
OpDef.GenerateUndoc(0x67, OpDef.OpNOP_65C02),
|
|
OpDef.OpPLA_StackPull, // 0x68
|
|
OpDef.OpADC_Imm,
|
|
OpDef.OpROR_Acc,
|
|
OpDef.GenerateUndoc(0x6b, OpDef.OpNOP_65C02),
|
|
OpDef.OpJMP_AbsInd,
|
|
OpDef.OpADC_Abs,
|
|
OpDef.OpROR_Abs,
|
|
OpDef.GenerateUndoc(0x6f, OpDef.OpNOP_65C02),
|
|
OpDef.OpBVS_PCRel, // 0x70
|
|
OpDef.OpADC_DPIndIndexY,
|
|
OpDef.OpADC_DPInd,
|
|
OpDef.GenerateUndoc(0x73, OpDef.OpNOP_65C02),
|
|
OpDef.OpSTZ_DPIndexX,
|
|
OpDef.OpADC_DPIndexX,
|
|
OpDef.OpROR_DPIndexX,
|
|
OpDef.GenerateUndoc(0x77, OpDef.OpNOP_65C02),
|
|
OpDef.OpSEI_Implied, // 0x78
|
|
OpDef.OpADC_AbsIndexY,
|
|
OpDef.OpPLY_StackPull,
|
|
OpDef.GenerateUndoc(0x7b, OpDef.OpNOP_65C02),
|
|
OpDef.OpJMP_AbsIndexXInd,
|
|
OpDef.OpADC_AbsIndexX,
|
|
OpDef.OpROR_AbsIndexX,
|
|
OpDef.GenerateUndoc(0x7f, OpDef.OpNOP_65C02),
|
|
OpDef.OpBRA_PCRel, // 0x80
|
|
OpDef.OpSTA_DPIndexXInd,
|
|
OpDef.GenerateUndoc(0x82, OpDef.OpLDD_Imm),
|
|
OpDef.GenerateUndoc(0x83, OpDef.OpNOP_65C02),
|
|
OpDef.OpSTY_DP,
|
|
OpDef.OpSTA_DP,
|
|
OpDef.OpSTX_DP,
|
|
OpDef.GenerateUndoc(0x87, OpDef.OpNOP_65C02),
|
|
OpDef.OpDEY_Implied, // 0x88
|
|
OpDef.OpBIT_Imm,
|
|
OpDef.OpTXA_Implied,
|
|
OpDef.GenerateUndoc(0x8b, OpDef.OpNOP_65C02),
|
|
OpDef.OpSTY_Abs,
|
|
OpDef.OpSTA_Abs,
|
|
OpDef.OpSTX_Abs,
|
|
OpDef.GenerateUndoc(0x8f, OpDef.OpNOP_65C02),
|
|
OpDef.OpBCC_PCRel, // 0x90
|
|
OpDef.OpSTA_DPIndIndexY,
|
|
OpDef.OpSTA_DPInd,
|
|
OpDef.GenerateUndoc(0x93, OpDef.OpNOP_65C02),
|
|
OpDef.OpSTY_DPIndexX,
|
|
OpDef.OpSTA_DPIndexX,
|
|
OpDef.OpSTX_DPIndexY,
|
|
OpDef.GenerateUndoc(0x97, OpDef.OpNOP_65C02),
|
|
OpDef.OpTYA_Implied, // 0x98
|
|
OpDef.OpSTA_AbsIndexY,
|
|
OpDef.OpTXS_Implied,
|
|
OpDef.GenerateUndoc(0x9b, OpDef.OpNOP_65C02),
|
|
OpDef.OpSTZ_Abs,
|
|
OpDef.OpSTA_AbsIndexX,
|
|
OpDef.OpSTZ_AbsIndexX,
|
|
OpDef.GenerateUndoc(0x9f, OpDef.OpNOP_65C02),
|
|
OpDef.OpLDY_Imm, // 0xa0
|
|
OpDef.OpLDA_DPIndexXInd,
|
|
OpDef.OpLDX_Imm,
|
|
OpDef.GenerateUndoc(0xa3, OpDef.OpNOP_65C02),
|
|
OpDef.OpLDY_DP,
|
|
OpDef.OpLDA_DP,
|
|
OpDef.OpLDX_DP,
|
|
OpDef.GenerateUndoc(0xa7, OpDef.OpNOP_65C02),
|
|
OpDef.OpTAY_Implied, // 0xa8
|
|
OpDef.OpLDA_Imm,
|
|
OpDef.OpTAX_Implied,
|
|
OpDef.GenerateUndoc(0xab, OpDef.OpNOP_65C02),
|
|
OpDef.OpLDY_Abs,
|
|
OpDef.OpLDA_Abs,
|
|
OpDef.OpLDX_Abs,
|
|
OpDef.GenerateUndoc(0xaf, OpDef.OpNOP_65C02),
|
|
OpDef.OpBCS_PCRel, // 0xb0
|
|
OpDef.OpLDA_DPIndIndexY,
|
|
OpDef.OpLDA_DPInd,
|
|
OpDef.GenerateUndoc(0xb3, OpDef.OpNOP_65C02),
|
|
OpDef.OpLDY_DPIndexX,
|
|
OpDef.OpLDA_DPIndexX,
|
|
OpDef.OpLDX_DPIndexY,
|
|
OpDef.GenerateUndoc(0xb7, OpDef.OpNOP_65C02),
|
|
OpDef.OpCLV_Implied, // 0xb8
|
|
OpDef.OpLDA_AbsIndexY,
|
|
OpDef.OpTSX_Implied,
|
|
OpDef.GenerateUndoc(0xbb, OpDef.OpNOP_65C02),
|
|
OpDef.OpLDY_AbsIndexX,
|
|
OpDef.OpLDA_AbsIndexX,
|
|
OpDef.OpLDX_AbsIndexY,
|
|
OpDef.GenerateUndoc(0xbf, OpDef.OpNOP_65C02),
|
|
OpDef.OpCPY_Imm, // 0xc0
|
|
OpDef.OpCMP_DPIndexXInd,
|
|
OpDef.GenerateUndoc(0xc2, OpDef.OpLDD_Imm),
|
|
OpDef.GenerateUndoc(0xc3, OpDef.OpNOP_65C02),
|
|
OpDef.OpCPY_DP,
|
|
OpDef.OpCMP_DP,
|
|
OpDef.OpDEC_DP,
|
|
OpDef.GenerateUndoc(0xc7, OpDef.OpNOP_65C02),
|
|
OpDef.OpINY_Implied, // 0xc8
|
|
OpDef.OpCMP_Imm,
|
|
OpDef.OpDEX_Implied,
|
|
OpDef.GenerateUndoc(0xcb, OpDef.OpNOP_65C02),
|
|
OpDef.OpCPY_Abs,
|
|
OpDef.OpCMP_Abs,
|
|
OpDef.OpDEC_Abs,
|
|
OpDef.GenerateUndoc(0xcf, OpDef.OpNOP_65C02),
|
|
OpDef.OpBNE_PCRel, // 0xd0
|
|
OpDef.OpCMP_DPIndIndexY,
|
|
OpDef.OpCMP_DPInd,
|
|
OpDef.GenerateUndoc(0xd3, OpDef.OpNOP_65C02),
|
|
OpDef.GenerateUndoc(0xd4, OpDef.OpLDD_DPIndexX),
|
|
OpDef.OpCMP_DPIndexX,
|
|
OpDef.OpDEC_DPIndexX,
|
|
OpDef.GenerateUndoc(0xd7, OpDef.OpNOP_65C02),
|
|
OpDef.OpCLD_Implied, // 0xd8
|
|
OpDef.OpCMP_AbsIndexY,
|
|
OpDef.OpPHX_StackPush,
|
|
OpDef.GenerateUndoc(0xdb, OpDef.OpNOP_65C02),
|
|
OpDef.GenerateUndoc(0xdc, OpDef.OpLDD_Absolute),
|
|
OpDef.OpCMP_AbsIndexX,
|
|
OpDef.OpDEC_AbsIndexX,
|
|
OpDef.GenerateUndoc(0xdf, OpDef.OpNOP_65C02),
|
|
OpDef.OpCPX_Imm, // 0xe0
|
|
OpDef.OpSBC_DPIndexXInd,
|
|
OpDef.GenerateUndoc(0xe2, OpDef.OpLDD_Imm),
|
|
OpDef.GenerateUndoc(0xe3, OpDef.OpNOP_65C02),
|
|
OpDef.OpCPX_DP,
|
|
OpDef.OpSBC_DP,
|
|
OpDef.OpINC_DP,
|
|
OpDef.GenerateUndoc(0xe7, OpDef.OpNOP_65C02),
|
|
OpDef.OpINX_Implied, // 0xe8
|
|
OpDef.OpSBC_Imm,
|
|
OpDef.OpNOP_Implied,
|
|
OpDef.GenerateUndoc(0xeb, OpDef.OpNOP_65C02),
|
|
OpDef.OpCPX_Abs,
|
|
OpDef.OpSBC_Abs,
|
|
OpDef.OpINC_Abs,
|
|
OpDef.GenerateUndoc(0xef, OpDef.OpNOP_65C02),
|
|
OpDef.OpBEQ_PCRel, // 0xf0
|
|
OpDef.OpSBC_DPIndIndexY,
|
|
OpDef.OpSBC_DPInd,
|
|
OpDef.GenerateUndoc(0xf3, OpDef.OpNOP_65C02),
|
|
OpDef.GenerateUndoc(0xf4, OpDef.OpLDD_DPIndexX),
|
|
OpDef.OpSBC_DPIndexX,
|
|
OpDef.OpINC_DPIndexX,
|
|
OpDef.GenerateUndoc(0xf7, OpDef.OpNOP_65C02),
|
|
OpDef.OpSED_Implied, // 0xf8
|
|
OpDef.OpSBC_AbsIndexY,
|
|
OpDef.OpPLX_StackPull,
|
|
OpDef.GenerateUndoc(0xfb, OpDef.OpNOP_65C02),
|
|
OpDef.GenerateUndoc(0xfc, OpDef.OpLDD_Absolute),
|
|
OpDef.OpSBC_AbsIndexX,
|
|
OpDef.OpINC_AbsIndexX,
|
|
OpDef.GenerateUndoc(0xff, OpDef.OpNOP_65C02),
|
|
}
|
|
};
|
|
|
|
|
|
// WDC 65802 and 65816. No undocumented opcodes -- all 256 are used.
|
|
private static CpuDef Cpu65816 { get; } = new CpuDef("WDC W65C816S", (1 << 24) - 1, true) {
|
|
Type = CpuType.Cpu65816,
|
|
mOpDefs = new OpDef[] {
|
|
OpDef.OpBRK_Implied, // 0x00
|
|
OpDef.OpORA_DPIndexXInd,
|
|
OpDef.OpCOP_StackInt,
|
|
OpDef.OpORA_StackRel,
|
|
OpDef.OpTSB_DP,
|
|
OpDef.OpORA_DP,
|
|
OpDef.OpASL_DP,
|
|
OpDef.OpORA_DPIndLong,
|
|
OpDef.OpPHP_StackPush, // 0x08
|
|
OpDef.OpORA_ImmLongA,
|
|
OpDef.OpASL_Acc,
|
|
OpDef.OpPHD_StackPush,
|
|
OpDef.OpTSB_Abs,
|
|
OpDef.OpORA_Abs,
|
|
OpDef.OpASL_Abs,
|
|
OpDef.OpORA_AbsLong,
|
|
OpDef.OpBPL_PCRel, // 0x10
|
|
OpDef.OpORA_DPIndIndexY,
|
|
OpDef.OpORA_DPInd,
|
|
OpDef.OpORA_StackRelIndIndexY,
|
|
OpDef.OpTRB_DP,
|
|
OpDef.OpORA_DPIndexX,
|
|
OpDef.OpASL_DPIndexX,
|
|
OpDef.OpORA_DPIndIndexYLong,
|
|
OpDef.OpCLC_Implied, // 0x18
|
|
OpDef.OpORA_AbsIndexY,
|
|
OpDef.OpINC_Acc,
|
|
OpDef.OpTCS_Implied,
|
|
OpDef.OpTRB_Abs,
|
|
OpDef.OpORA_AbsIndexX,
|
|
OpDef.OpASL_AbsIndexX,
|
|
OpDef.OpORA_AbsIndexXLong,
|
|
OpDef.OpJSR_Abs, // 0x20
|
|
OpDef.OpAND_DPIndexXInd,
|
|
OpDef.OpJSR_AbsLong,
|
|
OpDef.OpAND_StackRel,
|
|
OpDef.OpBIT_DP,
|
|
OpDef.OpAND_DP,
|
|
OpDef.OpROL_DP,
|
|
OpDef.OpAND_DPIndLong,
|
|
OpDef.OpPLP_StackPull, // 0x28
|
|
OpDef.OpAND_ImmLongA,
|
|
OpDef.OpROL_Acc,
|
|
OpDef.OpPLD_StackPull,
|
|
OpDef.OpBIT_Abs,
|
|
OpDef.OpAND_Abs,
|
|
OpDef.OpROL_Abs,
|
|
OpDef.OpAND_AbsLong,
|
|
OpDef.OpBMI_PCRel, // 0x30
|
|
OpDef.OpAND_DPIndIndexY,
|
|
OpDef.OpAND_DPInd,
|
|
OpDef.OpAND_StackRelIndIndexY,
|
|
OpDef.OpBIT_DPIndexX,
|
|
OpDef.OpAND_DPIndexX,
|
|
OpDef.OpROL_DPIndexX,
|
|
OpDef.OpAND_DPIndIndexYLong,
|
|
OpDef.OpSEC_Implied, // 0x38
|
|
OpDef.OpAND_AbsIndexY,
|
|
OpDef.OpDEC_Acc,
|
|
OpDef.OpTSC_Implied,
|
|
OpDef.OpBIT_AbsIndexX,
|
|
OpDef.OpAND_AbsIndexX,
|
|
OpDef.OpROL_AbsIndexX,
|
|
OpDef.OpAND_AbsIndexXLong,
|
|
OpDef.OpRTI_StackRTI, // 0x40
|
|
OpDef.OpEOR_DPIndexXInd,
|
|
OpDef.OpWDM_WDM,
|
|
OpDef.OpEOR_StackRel,
|
|
OpDef.OpMVP_BlockMove,
|
|
OpDef.OpEOR_DP,
|
|
OpDef.OpLSR_DP,
|
|
OpDef.OpEOR_DPIndLong,
|
|
OpDef.OpPHA_StackPush, // 0x48
|
|
OpDef.OpEOR_ImmLongA,
|
|
OpDef.OpLSR_Acc,
|
|
OpDef.OpPHK_StackPush,
|
|
OpDef.OpJMP_Abs,
|
|
OpDef.OpEOR_Abs,
|
|
OpDef.OpLSR_Abs,
|
|
OpDef.OpEOR_AbsLong,
|
|
OpDef.OpBVC_PCRel, // 0x50
|
|
OpDef.OpEOR_DPIndIndexY,
|
|
OpDef.OpEOR_DPInd,
|
|
OpDef.OpEOR_StackRelIndIndexY,
|
|
OpDef.OpMVN_BlockMove,
|
|
OpDef.OpEOR_DPIndexX,
|
|
OpDef.OpLSR_DPIndexX,
|
|
OpDef.OpEOR_DPIndIndexYLong,
|
|
OpDef.OpCLI_Implied, // 0x58
|
|
OpDef.OpEOR_AbsIndexY,
|
|
OpDef.OpPHY_StackPush,
|
|
OpDef.OpTCD_Implied,
|
|
OpDef.OpJMP_AbsLong,
|
|
OpDef.OpEOR_AbsIndexX,
|
|
OpDef.OpLSR_AbsIndexX,
|
|
OpDef.OpEOR_AbsIndexXLong,
|
|
OpDef.OpRTS_StackRTS, // 0x60
|
|
OpDef.OpADC_DPIndexXInd,
|
|
OpDef.OpPER_StackPCRelLong,
|
|
OpDef.OpADC_StackRel,
|
|
OpDef.OpSTZ_DP,
|
|
OpDef.OpADC_DP,
|
|
OpDef.OpROR_DP,
|
|
OpDef.OpADC_DPIndLong,
|
|
OpDef.OpPLA_StackPull, // 0x68
|
|
OpDef.OpADC_ImmLongA,
|
|
OpDef.OpROR_Acc,
|
|
OpDef.OpRTL_StackRTL,
|
|
OpDef.OpJMP_AbsInd,
|
|
OpDef.OpADC_Abs,
|
|
OpDef.OpROR_Abs,
|
|
OpDef.OpADC_AbsLong,
|
|
OpDef.OpBVS_PCRel, // 0x70
|
|
OpDef.OpADC_DPIndIndexY,
|
|
OpDef.OpADC_DPInd,
|
|
OpDef.OpADC_StackRelIndIndexY,
|
|
OpDef.OpSTZ_DPIndexX,
|
|
OpDef.OpADC_DPIndexX,
|
|
OpDef.OpROR_DPIndexX,
|
|
OpDef.OpADC_DPIndIndexYLong,
|
|
OpDef.OpSEI_Implied, // 0x78
|
|
OpDef.OpADC_AbsIndexY,
|
|
OpDef.OpPLY_StackPull,
|
|
OpDef.OpTDC_Implied,
|
|
OpDef.OpJMP_AbsIndexXInd,
|
|
OpDef.OpADC_AbsIndexX,
|
|
OpDef.OpROR_AbsIndexX,
|
|
OpDef.OpADC_AbsIndexXLong,
|
|
OpDef.OpBRA_PCRel, // 0x80
|
|
OpDef.OpSTA_DPIndexXInd,
|
|
OpDef.OpBRL_PCRelLong,
|
|
OpDef.OpSTA_StackRel,
|
|
OpDef.OpSTY_DP,
|
|
OpDef.OpSTA_DP,
|
|
OpDef.OpSTX_DP,
|
|
OpDef.OpSTA_DPIndLong,
|
|
OpDef.OpDEY_Implied, // 0x88
|
|
OpDef.OpBIT_ImmLongA,
|
|
OpDef.OpTXA_Implied,
|
|
OpDef.OpPHB_StackPush,
|
|
OpDef.OpSTY_Abs,
|
|
OpDef.OpSTA_Abs,
|
|
OpDef.OpSTX_Abs,
|
|
OpDef.OpSTA_AbsLong,
|
|
OpDef.OpBCC_PCRel, // 0x90
|
|
OpDef.OpSTA_DPIndIndexY,
|
|
OpDef.OpSTA_DPInd,
|
|
OpDef.OpSTA_StackRelIndIndexY,
|
|
OpDef.OpSTY_DPIndexX,
|
|
OpDef.OpSTA_DPIndexX,
|
|
OpDef.OpSTX_DPIndexY,
|
|
OpDef.OpSTA_DPIndIndexYLong,
|
|
OpDef.OpTYA_Implied, // 0x98
|
|
OpDef.OpSTA_AbsIndexY,
|
|
OpDef.OpTXS_Implied,
|
|
OpDef.OpTXY_Implied,
|
|
OpDef.OpSTZ_Abs,
|
|
OpDef.OpSTA_AbsIndexX,
|
|
OpDef.OpSTZ_AbsIndexX,
|
|
OpDef.OpSTA_AbsIndexXLong,
|
|
OpDef.OpLDY_ImmLongXY, // 0xa0
|
|
OpDef.OpLDA_DPIndexXInd,
|
|
OpDef.OpLDX_ImmLongXY,
|
|
OpDef.OpLDA_StackRel,
|
|
OpDef.OpLDY_DP,
|
|
OpDef.OpLDA_DP,
|
|
OpDef.OpLDX_DP,
|
|
OpDef.OpLDA_DPIndLong,
|
|
OpDef.OpTAY_Implied, // 0xa8
|
|
OpDef.OpLDA_ImmLongA,
|
|
OpDef.OpTAX_Implied,
|
|
OpDef.OpPLB_StackPull,
|
|
OpDef.OpLDY_Abs,
|
|
OpDef.OpLDA_Abs,
|
|
OpDef.OpLDX_Abs,
|
|
OpDef.OpLDA_AbsLong,
|
|
OpDef.OpBCS_PCRel, // 0xb0
|
|
OpDef.OpLDA_DPIndIndexY,
|
|
OpDef.OpLDA_DPInd,
|
|
OpDef.OpLDA_StackRelIndIndexY,
|
|
OpDef.OpLDY_DPIndexX,
|
|
OpDef.OpLDA_DPIndexX,
|
|
OpDef.OpLDX_DPIndexY,
|
|
OpDef.OpLDA_DPIndIndexYLong,
|
|
OpDef.OpCLV_Implied, // 0xb8
|
|
OpDef.OpLDA_AbsIndexY,
|
|
OpDef.OpTSX_Implied,
|
|
OpDef.OpTYX_Implied,
|
|
OpDef.OpLDY_AbsIndexX,
|
|
OpDef.OpLDA_AbsIndexX,
|
|
OpDef.OpLDX_AbsIndexY,
|
|
OpDef.OpLDA_AbsIndexXLong,
|
|
OpDef.OpCPY_ImmLongXY, // 0xc0
|
|
OpDef.OpCMP_DPIndexXInd,
|
|
OpDef.OpREP_Imm,
|
|
OpDef.OpCMP_StackRel,
|
|
OpDef.OpCPY_DP,
|
|
OpDef.OpCMP_DP,
|
|
OpDef.OpDEC_DP,
|
|
OpDef.OpCMP_DPIndLong,
|
|
OpDef.OpINY_Implied, // 0xc8
|
|
OpDef.OpCMP_ImmLongA,
|
|
OpDef.OpDEX_Implied,
|
|
OpDef.OpWAI_Implied,
|
|
OpDef.OpCPY_Abs,
|
|
OpDef.OpCMP_Abs,
|
|
OpDef.OpDEC_Abs,
|
|
OpDef.OpCMP_AbsLong,
|
|
OpDef.OpBNE_PCRel, // 0xd0
|
|
OpDef.OpCMP_DPIndIndexY,
|
|
OpDef.OpCMP_DPInd,
|
|
OpDef.OpCMP_StackRelIndIndexY,
|
|
OpDef.OpPEI_StackDPInd,
|
|
OpDef.OpCMP_DPIndexX,
|
|
OpDef.OpDEC_DPIndexX,
|
|
OpDef.OpCMP_DPIndIndexYLong,
|
|
OpDef.OpCLD_Implied, // 0xd8
|
|
OpDef.OpCMP_AbsIndexY,
|
|
OpDef.OpPHX_StackPush,
|
|
OpDef.OpSTP_Implied,
|
|
OpDef.OpJMP_AbsIndLong,
|
|
OpDef.OpCMP_AbsIndexX,
|
|
OpDef.OpDEC_AbsIndexX,
|
|
OpDef.OpCMP_AbsIndexXLong,
|
|
OpDef.OpCPX_ImmLongXY, // 0xe0
|
|
OpDef.OpSBC_DPIndexXInd,
|
|
OpDef.OpSEP_Imm,
|
|
OpDef.OpSBC_StackRel,
|
|
OpDef.OpCPX_DP,
|
|
OpDef.OpSBC_DP,
|
|
OpDef.OpINC_DP,
|
|
OpDef.OpSBC_DPIndLong,
|
|
OpDef.OpINX_Implied, // 0xe8
|
|
OpDef.OpSBC_ImmLongA,
|
|
OpDef.OpNOP_Implied,
|
|
OpDef.OpXBA_Implied,
|
|
OpDef.OpCPX_Abs,
|
|
OpDef.OpSBC_Abs,
|
|
OpDef.OpINC_Abs,
|
|
OpDef.OpSBC_AbsLong,
|
|
OpDef.OpBEQ_PCRel, // 0xf0
|
|
OpDef.OpSBC_DPIndIndexY,
|
|
OpDef.OpSBC_DPInd,
|
|
OpDef.OpSBC_StackRelIndIndexY,
|
|
OpDef.OpPEA_StackAbs,
|
|
OpDef.OpSBC_DPIndexX,
|
|
OpDef.OpINC_DPIndexX,
|
|
OpDef.OpSBC_DPIndIndexYLong,
|
|
OpDef.OpSED_Implied, // 0xf8
|
|
OpDef.OpSBC_AbsIndexY,
|
|
OpDef.OpPLX_StackPull,
|
|
OpDef.OpXCE_Implied,
|
|
OpDef.OpJSR_AbsIndexXInd,
|
|
OpDef.OpSBC_AbsIndexX,
|
|
OpDef.OpINC_AbsIndexX,
|
|
OpDef.OpSBC_AbsIndexXLong
|
|
}
|
|
};
|
|
}
|
|
}
|