mirror of
https://github.com/fadden/6502bench.git
synced 2024-12-01 22:50:35 +00:00
824add17e8
In a recent survey, three out of four cross assemblers surveyed recommended not using opcode mnemonics to their patients who use labels. We now remap labels like "AND" and "jmp", using the label map that's part of the label localizer. We skip the step for Merlin 32, which is perfectly happy to assemble "JMP JMP JMP". Also, fixed a bug in MaskLeadingUnderscores that could hang the source generator thread.
1201 lines
49 KiB
C#
1201 lines
49 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) {
|
|
// 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:
|
|
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;
|
|
}
|
|
|
|
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. (We could
|
|
/// probably just make this the class indexer.)
|
|
/// </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 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
|
|
}
|
|
};
|
|
}
|
|
}
|