1
0
mirror of https://github.com/fadden/6502bench.git synced 2025-01-02 03:29:51 +00:00

Rename undocumented 6502 opcodes to match Unintended Opcodes doc

These *almost* match what cc65 has, and are accepted as primary or
aliases by 64tass.

This combines the LAX and LXA operations.  LXA is the immediate
form of LAX, and behaves somewhat differently (and is unstable).
I was treating them as two separate operations with independent
mnemonics, but that doesn't seem to be the preferred way to
handle it.

The cc65 generator wasn't generating LAX before; now it does.  This
required nudging the width disambiguator, as LAX is a second
example of an instruction with both DP,Y and ABS,Y operands.

(issue #20)
This commit is contained in:
Andy McFadden 2018-10-05 14:07:57 -07:00
parent 2d1ef37a13
commit a23c7e5ab6
7 changed files with 121 additions and 120 deletions

View File

@ -410,7 +410,7 @@ namespace Asm65 {
mOpDefs = new OpDef[] {
OpDef.OpBRK_StackInt, // 0x00
OpDef.OpORA_DPIndexXInd,
OpDef.GenerateUndoc(0x02, OpDef.OpHLT_Implied),
OpDef.GenerateUndoc(0x02, OpDef.OpJAM_Implied),
OpDef.OpSLO_DPIndexXInd,
OpDef.GenerateUndoc(0x04, OpDef.OpDOP_DP),
OpDef.OpORA_DP,
@ -426,7 +426,7 @@ namespace Asm65 {
OpDef.OpSLO_Absolute,
OpDef.OpBPL_PCRel, // 0x10
OpDef.OpORA_DPIndIndexY,
OpDef.GenerateUndoc(0x12, OpDef.OpHLT_Implied),
OpDef.GenerateUndoc(0x12, OpDef.OpJAM_Implied),
OpDef.OpSLO_DPIndIndexY,
OpDef.GenerateUndoc(0x14, OpDef.OpDOP_DPIndexX),
OpDef.OpORA_DPIndexX,
@ -442,7 +442,7 @@ namespace Asm65 {
OpDef.OpSLO_AbsIndexX,
OpDef.OpJSR_Abs, // 0x20
OpDef.OpAND_DPIndexXInd,
OpDef.GenerateUndoc(0x22, OpDef.OpHLT_Implied),
OpDef.GenerateUndoc(0x22, OpDef.OpJAM_Implied),
OpDef.OpRLA_DPIndexXInd,
OpDef.OpBIT_DP,
OpDef.OpAND_DP,
@ -458,7 +458,7 @@ namespace Asm65 {
OpDef.OpRLA_Absolute,
OpDef.OpBMI_PCRel, // 0x30
OpDef.OpAND_DPIndIndexY,
OpDef.GenerateUndoc(0x32, OpDef.OpHLT_Implied),
OpDef.GenerateUndoc(0x32, OpDef.OpJAM_Implied),
OpDef.OpRLA_DPIndIndexY,
OpDef.GenerateUndoc(0x34, OpDef.OpDOP_DPIndexX),
OpDef.OpAND_DPIndexX,
@ -474,7 +474,7 @@ namespace Asm65 {
OpDef.OpRLA_AbsIndexX,
OpDef.OpRTI_StackRTI, // 0x40
OpDef.OpEOR_DPIndexXInd,
OpDef.GenerateUndoc(0x42, OpDef.OpHLT_Implied),
OpDef.GenerateUndoc(0x42, OpDef.OpJAM_Implied),
OpDef.OpSRE_DPIndexXInd,
OpDef.GenerateUndoc(0x44, OpDef.OpDOP_DP),
OpDef.OpEOR_DP,
@ -483,14 +483,14 @@ namespace Asm65 {
OpDef.OpPHA_StackPush, // 0x48
OpDef.OpEOR_Imm,
OpDef.OpLSR_Acc,
OpDef.OpASR_Imm,
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.OpHLT_Implied),
OpDef.GenerateUndoc(0x52, OpDef.OpJAM_Implied),
OpDef.OpSRE_DPIndIndexY,
OpDef.GenerateUndoc(0x54, OpDef.OpDOP_DPIndexX),
OpDef.OpEOR_DPIndexX,
@ -506,7 +506,7 @@ namespace Asm65 {
OpDef.OpSRE_AbsIndexX,
OpDef.OpRTS_StackRTS, // 0x60
OpDef.OpADC_DPIndexXInd,
OpDef.GenerateUndoc(0x62, OpDef.OpHLT_Implied),
OpDef.GenerateUndoc(0x62, OpDef.OpJAM_Implied),
OpDef.OpRRA_DPIndexXInd,
OpDef.GenerateUndoc(0x64, OpDef.OpDOP_DP),
OpDef.OpADC_DP,
@ -522,7 +522,7 @@ namespace Asm65 {
OpDef.OpRRA_Absolute,
OpDef.OpBVS_PCRel, // 0x70
OpDef.OpADC_DPIndIndexY,
OpDef.GenerateUndoc(0x72, OpDef.OpHLT_Implied),
OpDef.GenerateUndoc(0x72, OpDef.OpJAM_Implied),
OpDef.OpRRA_DPIndIndexY,
OpDef.GenerateUndoc(0x74, OpDef.OpDOP_DPIndexX),
OpDef.OpADC_DPIndexX,
@ -554,7 +554,7 @@ namespace Asm65 {
OpDef.OpSAX_Absolute,
OpDef.OpBCC_PCRel, // 0x90
OpDef.OpSTA_DPIndIndexY,
OpDef.GenerateUndoc(0x92, OpDef.OpHLT_Implied),
OpDef.GenerateUndoc(0x92, OpDef.OpJAM_Implied),
OpDef.OpSHA_DPIndIndexY,
OpDef.OpSTY_DPIndexX,
OpDef.OpSTA_DPIndexX,
@ -563,7 +563,7 @@ namespace Asm65 {
OpDef.OpTYA_Implied, // 0x98
OpDef.OpSTA_AbsIndexY,
OpDef.OpTXS_Implied,
OpDef.OpSHS_AbsIndexY,
OpDef.OpTAS_AbsIndexY,
OpDef.OpSHY_AbsIndexX,
OpDef.OpSTA_AbsIndexX,
OpDef.OpSHX_AbsIndexY,
@ -579,14 +579,14 @@ namespace Asm65 {
OpDef.OpTAY_Implied, // 0xa8
OpDef.OpLDA_Imm,
OpDef.OpTAX_Implied,
OpDef.OpLXA_Imm,
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.OpHLT_Implied),
OpDef.GenerateUndoc(0xb2, OpDef.OpJAM_Implied),
OpDef.OpLAX_DPIndIndexY,
OpDef.OpLDY_DPIndexX,
OpDef.OpLDA_DPIndexX,
@ -595,7 +595,7 @@ namespace Asm65 {
OpDef.OpCLV_Implied, // 0xb8
OpDef.OpLDA_AbsIndexY,
OpDef.OpTSX_Implied,
OpDef.OpLAE_AbsIndexY,
OpDef.OpLAS_AbsIndexY,
OpDef.OpLDY_AbsIndexX,
OpDef.OpLDA_AbsIndexX,
OpDef.OpLDX_AbsIndexY,
@ -618,7 +618,7 @@ namespace Asm65 {
OpDef.OpDCP_Abs,
OpDef.OpBNE_PCRel, // 0xd0
OpDef.OpCMP_DPIndIndexY,
OpDef.GenerateUndoc(0xd2, OpDef.OpHLT_Implied),
OpDef.GenerateUndoc(0xd2, OpDef.OpJAM_Implied),
OpDef.OpDCP_DPIndIndexY,
OpDef.GenerateUndoc(0xd4, OpDef.OpDOP_DPIndexX),
OpDef.OpCMP_DPIndexX,
@ -635,11 +635,11 @@ namespace Asm65 {
OpDef.OpCPX_Imm, // 0xe0
OpDef.OpSBC_DPIndexXInd,
OpDef.GenerateUndoc(0xe2, OpDef.OpDOP_Imm),
OpDef.OpISB_DPIndexXInd,
OpDef.OpISC_DPIndexXInd,
OpDef.OpCPX_DP,
OpDef.OpSBC_DP,
OpDef.OpINC_DP,
OpDef.OpISB_DP,
OpDef.OpISC_DP,
OpDef.OpINX_Implied, // 0xe8
OpDef.OpSBC_Imm,
OpDef.OpNOP_Implied,
@ -647,23 +647,23 @@ namespace Asm65 {
OpDef.OpCPX_Abs,
OpDef.OpSBC_Abs,
OpDef.OpINC_Abs,
OpDef.OpISB_Abs,
OpDef.OpISC_Abs,
OpDef.OpBEQ_PCRel, // 0xf0
OpDef.OpSBC_DPIndIndexY,
OpDef.GenerateUndoc(0xf2, OpDef.OpHLT_Implied),
OpDef.OpISB_DPIndIndexY,
OpDef.GenerateUndoc(0xf2, OpDef.OpJAM_Implied),
OpDef.OpISC_DPIndIndexY,
OpDef.GenerateUndoc(0xf4, OpDef.OpDOP_DPIndexX),
OpDef.OpSBC_DPIndexX,
OpDef.OpINC_DPIndexX,
OpDef.OpISB_DPIndexX,
OpDef.OpISC_DPIndexX,
OpDef.OpSED_Implied, // 0xf8
OpDef.OpSBC_AbsIndexY,
OpDef.GenerateUndoc(0xfa, OpDef.OpNOP_Implied),
OpDef.OpISB_AbsIndexY,
OpDef.OpISC_AbsIndexY,
OpDef.GenerateUndoc(0xfc, OpDef.OpTOP_AbsIndeX),
OpDef.OpSBC_AbsIndexX,
OpDef.OpINC_AbsIndexX,
OpDef.OpISB_AbsIndexX,
OpDef.OpISC_AbsIndexX,
}
};

View File

@ -302,7 +302,8 @@ namespace Asm65 {
// and STX doesn't have AbsIndexY. So this is only ambiguous for LDX.
// We want to compare by opcode instance, rather than the byte code
// numeric value, to manage different instruction sets.
if (this == OpLDX_AbsIndexY) {
// (This also applies to the undocumented LAX instruction.)
if (this == OpLDX_AbsIndexY || this == OpLAX_AbsIndexY) {
return true;
}
return false;
@ -2644,12 +2645,12 @@ namespace Asm65 {
// most cases it's pretty stable, in others the behavior can differ between CPU
// variants.
//
// There is no generally agreed-upon set of mnemonics for these instructions. The
// mnemonics "XAS" and "AXS" sometimes mean one thing and sometimes another. I've
// chosen a set that seems reasonable. If a consensus is reached, the mnemonics
// are easy enough to change throughout (yay Visual Studio refactoring).
// There is no universally agreed-upon set of mnemonics for these instructions. The
// mnemonics "XAS" and "AXS" sometimes mean one thing and sometimes another. The
// reference I've chosen to use as primary is "NMOS 6510 Unintended Opcodes":
// https://csdb.dk/release/?id=161035
//
// References:
// Other references:
// http://nesdev.com/undocumented_opcodes.txt
// http://visual6502.org/wiki/index.php?title=6502_all_256_Opcodes
// http://www.ffd2.com/fridge/docs/6502-NMOS.extra.opcodes
@ -2667,6 +2668,13 @@ namespace Asm65 {
Mnemonic = OpName.ANE,
Effect = FlowEffect.Cont
};
private static OpDef OpALR = new OpDef() {
IsUndocumented = true,
Mnemonic = OpName.ALR,
Effect = FlowEffect.Cont,
FlagsAffected = FlagsAffected_NZC,
StatusFlagUpdater = FlagUpdater_NZC
};
private static OpDef OpARR = new OpDef() {
IsUndocumented = true,
Mnemonic = OpName.ARR,
@ -2674,13 +2682,6 @@ namespace Asm65 {
FlagsAffected = FlagsAffected_NVZC,
StatusFlagUpdater = FlagUpdater_NVZC
};
private static OpDef OpASR = new OpDef() {
IsUndocumented = true,
Mnemonic = OpName.ASR,
Effect = FlowEffect.Cont,
FlagsAffected = FlagsAffected_NZC,
StatusFlagUpdater = FlagUpdater_NZC
};
private static OpDef OpDCP = new OpDef() {
IsUndocumented = true,
Mnemonic = OpName.DCP,
@ -2693,21 +2694,21 @@ namespace Asm65 {
Mnemonic = OpName.DOP,
Effect = FlowEffect.Cont
};
private static OpDef OpHLT = new OpDef() {
private static OpDef OpJAM = new OpDef() {
IsUndocumented = true,
Mnemonic = OpName.HLT,
Mnemonic = OpName.JAM,
Effect = FlowEffect.NoCont
};
private static OpDef OpISB = new OpDef() {
private static OpDef OpISC = new OpDef() {
IsUndocumented = true,
Mnemonic = OpName.ISB,
Mnemonic = OpName.ISC,
Effect = FlowEffect.Cont,
FlagsAffected = FlagsAffected_NVZC,
StatusFlagUpdater = FlagUpdater_NVZC
};
private static OpDef OpLAE = new OpDef() {
private static OpDef OpLAS = new OpDef() {
IsUndocumented = true,
Mnemonic = OpName.LAE,
Mnemonic = OpName.LAS,
Effect = FlowEffect.Cont,
FlagsAffected = FlagsAffected_NZ,
StatusFlagUpdater = FlagUpdater_NZ
@ -2719,13 +2720,13 @@ namespace Asm65 {
FlagsAffected = FlagsAffected_NZ,
StatusFlagUpdater = FlagUpdater_NZ
};
private static OpDef OpLXA = new OpDef() {
IsUndocumented = true,
Mnemonic = OpName.LXA,
Effect = FlowEffect.Cont,
FlagsAffected = FlagsAffected_NZ,
StatusFlagUpdater = FlagUpdater_NZ
};
//private static OpDef OpLXA = new OpDef() {
// IsUndocumented = true,
// Mnemonic = OpName.LXA,
// Effect = FlowEffect.Cont,
// FlagsAffected = FlagsAffected_NZ,
// StatusFlagUpdater = FlagUpdater_NZ
//};
private static OpDef OpRLA = new OpDef() {
IsUndocumented = true,
Mnemonic = OpName.RLA,
@ -2759,9 +2760,9 @@ namespace Asm65 {
Mnemonic = OpName.SHA,
Effect = FlowEffect.Cont
};
private static OpDef OpSHS = new OpDef() {
private static OpDef OpTAS = new OpDef() {
IsUndocumented = true,
Mnemonic = OpName.SHS,
Mnemonic = OpName.TAS,
Effect = FlowEffect.Cont
};
private static OpDef OpSHX = new OpDef() {
@ -3018,42 +3019,42 @@ namespace Asm65 {
AddrMode = AddressMode.AbsIndexX,
CycDef = 7
};
public static readonly OpDef OpISB_DPIndexXInd = new OpDef(OpISB) {
public static readonly OpDef OpISC_DPIndexXInd = new OpDef(OpISC) {
Opcode = 0xe3,
AddrMode = AddressMode.DPIndexXInd,
CycDef = 8
};
public static readonly OpDef OpISB_DP = new OpDef(OpISB) {
public static readonly OpDef OpISC_DP = new OpDef(OpISC) {
Opcode = 0xe7,
AddrMode = AddressMode.DP,
CycDef = 5
};
public static readonly OpDef OpISB_Abs = new OpDef(OpISB) {
public static readonly OpDef OpISC_Abs = new OpDef(OpISC) {
Opcode = 0xef,
AddrMode = AddressMode.Abs,
CycDef = 6
};
public static readonly OpDef OpISB_DPIndIndexY = new OpDef(OpISB) {
public static readonly OpDef OpISC_DPIndIndexY = new OpDef(OpISC) {
Opcode = 0xf3,
AddrMode = AddressMode.DPIndIndexY,
CycDef = 8
};
public static readonly OpDef OpISB_DPIndexX = new OpDef(OpISB) {
public static readonly OpDef OpISC_DPIndexX = new OpDef(OpISC) {
Opcode = 0xf7,
AddrMode = AddressMode.DPIndexX,
CycDef = 6
};
public static readonly OpDef OpISB_AbsIndexY = new OpDef(OpISB) {
public static readonly OpDef OpISC_AbsIndexY = new OpDef(OpISC) {
Opcode = 0xfb,
AddrMode = AddressMode.AbsIndexY,
CycDef = 7
};
public static readonly OpDef OpISB_AbsIndexX = new OpDef(OpISB) {
public static readonly OpDef OpISC_AbsIndexX = new OpDef(OpISC) {
Opcode = 0xff,
AddrMode = AddressMode.AbsIndexX,
CycDef = 7
};
public static readonly OpDef OpASR_Imm = new OpDef(OpASR) {
public static readonly OpDef OpALR_Imm = new OpDef(OpALR) {
Opcode = 0x4b,
AddrMode = AddressMode.Imm,
CycDef = 2
@ -3068,7 +3069,7 @@ namespace Asm65 {
AddrMode = AddressMode.Imm,
CycDef = 2
};
public static readonly OpDef OpLXA_Imm = new OpDef(OpLXA) {
public static readonly OpDef OpLAX_Imm = new OpDef(OpLAX) {
Opcode = 0xab,
AddrMode = AddressMode.Imm,
CycDef = 2
@ -3103,12 +3104,12 @@ namespace Asm65 {
AddrMode = AddressMode.AbsIndexX,
CycDef = 4 | (int)(CycleMod.OneIfIndexPage)
};
public static readonly OpDef OpHLT_Implied = new OpDef(OpHLT) {
public static readonly OpDef OpJAM_Implied = new OpDef(OpJAM) {
// multiple opcodes
AddrMode = AddressMode.Implied,
CycDef = 1
};
public static readonly OpDef OpSHS_AbsIndexY = new OpDef(OpSHS) {
public static readonly OpDef OpTAS_AbsIndexY = new OpDef(OpTAS) {
Opcode = 0x9b,
AddrMode = AddressMode.AbsIndexY,
CycDef = 5
@ -3138,7 +3139,7 @@ namespace Asm65 {
AddrMode = AddressMode.Imm,
CycDef = 2
};
public static readonly OpDef OpLAE_AbsIndexY = new OpDef(OpLAE) {
public static readonly OpDef OpLAS_AbsIndexY = new OpDef(OpLAS) {
Opcode = 0xbb,
AddrMode = AddressMode.AbsIndexY,
CycDef = 4 | (int)(CycleMod.OneIfIndexPage)

View File

@ -210,27 +210,27 @@ namespace Asm65 {
{ OpName.XCE, "Exchange Carry and Emulation Bits" },
// MOS 6502 undocumented ops
{ OpName.ALR, "AND and Shift Right" },
{ OpName.ANC, "AND Accumulator With Value and Set Carry" },
{ OpName.ANE, "Transfer Index X to Accumulator and AND" },
{ OpName.ARR, "AND and Rotate Right" },
{ OpName.ASR, "AND and Shift Right" },
{ OpName.DCP, "Decrement and Compare" },
{ OpName.DOP, "Double-Byte NOP" },
{ OpName.HLT, "Halt CPU" },
{ OpName.ISB, "Increment and Subtract" },
{ OpName.LAE, "Load Acc, X, and Stack Pointer with Memory AND Stack Pointer" },
{ OpName.ISC, "Increment and Subtract" },
{ OpName.JAM, "Halt CPU" },
{ OpName.LAS, "Load Acc, X, and Stack Pointer with Memory AND Stack Pointer" },
{ OpName.LAX, "Load Accumulator and Index X" },
{ OpName.LXA, "OR, AND, and Transfer to X" },
//{ OpName.LXA, "OR, AND, and Transfer to X" },
{ OpName.RLA, "Rotate Left and AND" },
{ OpName.RRA, "Rotate Right and Add" },
{ OpName.SAX, "Store Accumulator AND Index X" }, // AXS
{ OpName.SBX, "AND Acc With Index X, Subtract, and Store in X" }, // SAX
{ OpName.SHA, "AND Acc With Index X and High Byte, and Store" }, // AXA
{ OpName.SHS, "AND Acc with Index X, Transfer to Stack, AND High Byte" }, // TAS
{ OpName.SHX, "AND Acc With Index X and High Byte, and Store" }, // XAS
{ OpName.SHY, "AND Acc With Index Y and High Byte, and Store" }, // SAY
{ OpName.SLO, "Shift Left and OR" },
{ OpName.SRE, "Shift right and EOR" },
{ OpName.TAS, "AND Acc with Index X, Transfer to Stack, AND High Byte" },
{ OpName.TOP, "Triple-Byte NOP" },
// WDC 65C02 undocumented
@ -561,25 +561,24 @@ namespace Asm65 {
//
// 6502 undocumented instructions.
//
// References:
// http://www.ffd2.com/fridge/docs/6502-NMOS.extra.opcodes
// http://nesdev.com/undocumented_opcodes.txt
// (See OpDef for a list of references.)
//
{ OpName.ANC,
"AND byte with accumulator. If result is negative then carry is set." +
"\r\n\r\nAlt mnemonic: AAC"
},
{ OpName.ANE,
"Transfer X register to accumulator, then AND accumulator with value." +
"Transfer X register to accumulator, then AND accumulator with value. " +
"This opcode is unstable." +
"\r\n\r\nAlt mnemonic: XAA"
},
{ OpName.ARR,
"AND byte with accumulator, then rotate one bit right. Equivalent to " +
"AND + ROR."
},
{ OpName.ASR,
{ OpName.ALR,
"AND byte with accumulator, then shift right one bit. Equivalent to AND + LSR." +
"\r\n\r\nAlt mnemonic: ALR"
"\r\n\r\nAlt mnemonic: ASR"
},
{ OpName.DCP,
"Decrement memory location, then compare result to accumulator. Equivalent " +
@ -590,28 +589,29 @@ namespace Asm65 {
"Double-byte no-operation." +
"\r\n\r\nAlt mnemonic: NOP / SKB"
},
{ OpName.HLT,
"Crash the CPU, halting execution and ignoring interrupts." +
"\r\n\r\nAlt mnemonic: KIL / JAM"
},
{ OpName.ISB,
{ OpName.ISC,
"Increment memory, then subtract memory from accumulator with borrow. " +
"Equivalent to INC + SBC." +
"\r\n\r\nAlt mnemonic: ISC / INS"
},
{ OpName.LAE,
{ OpName.JAM,
"Crash the CPU, halting execution and ignoring interrupts." +
"\r\n\r\nAlt mnemonic: KIL / JAM"
},
{ OpName.LAS,
"AND memory with stack pointer, then transfer result to accumulator, " +
"X register, and stack pointer. (Note: possibly unreliable.)" +
"\r\n\r\nAlt mnemonic: LAR / LAS"
"\r\n\r\nAlt mnemonic: LAE / LAR"
},
{ OpName.LAX,
"Load accumulator and X register from memory. Equivalent to LDA + LDX."
},
{ OpName.LXA,
"Load accumulator and X register from memory. Equivalent to LDA + LDX." +
"\r\n\r\nThe immediate mode is unstable. It " +
/*},
{ OpName.LXA,*/
"ORs accumulator with a value, ANDs result with immediate value, then stores " +
"the result in accumulator and X register." +
"the result in accumulator and X register. " +
"Equivalent to ORA + AND + TAX." +
"\r\n\r\nAlt mnemonic: ATX / OAL"
"\r\n\r\nAlt mnemonic: LXA / ATX / OAL"
},
{ OpName.RLA,
"Rotate memory one bit left, then AND accumulator with memory. Equivalent " +
@ -633,13 +633,7 @@ namespace Asm65 {
},
{ OpName.SHA,
"AND X register with accumulator, then AND result with 7 and store." +
"\r\n\r\nAlt mnemonic: AXA"
},
{ OpName.SHS,
"AND X register with accumulator, without changing the contents of either" +
"register, and transfer to stack pointer. Then " +
"AND stack pointer with high byte of operand + 1." +
"\r\n\r\nAlt mnemonic: XAS / TAS"
"\r\n\r\nAlt mnemonic: AHX, AXA"
},
{ OpName.SHX,
"AND X register with the high byte of the argument + 1, and store the result." +
@ -659,6 +653,12 @@ namespace Asm65 {
"LSR + EOR." +
"\r\n\r\nAlt mnemonic: LSE"
},
{ OpName.TAS,
"AND X register with accumulator, without changing the contents of either " +
"register, and transfer to stack pointer. Then " +
"AND stack pointer with high byte of operand + 1." +
"\r\n\r\nAlt mnemonic: SHS / XAS"
},
{ OpName.TOP,
"Triple-byte no-operation. This actually performs a load." +
"\r\n\r\nAlt mnemonic: NOP / SKW"

View File

@ -121,25 +121,24 @@ namespace Asm65 {
// Undocumented 6502 instructions.
public const string ANC = "anc";
public const string ANE = "ane";
public const string ALR = "alr";
public const string ARR = "arr";
public const string ASR = "asr";
public const string DCP = "dcp";
public const string DOP = "dop";
public const string HLT = "hlt";
public const string ISB = "isb";
public const string LAE = "lae";
public const string ISC = "isc";
public const string JAM = "jam";
public const string LAS = "las";
public const string LAX = "lax";
public const string LXA = "lxa";
public const string RLA = "rla";
public const string RRA = "rra";
public const string SAX = "sax";
public const string SBX = "sbx";
public const string SHA = "sha";
public const string SHS = "shs";
public const string SHX = "shx";
public const string SHY = "shy";
public const string SLO = "slo";
public const string SRE = "sre";
public const string TAS = "tas";
public const string TOP = "top";
// Undocumented 65C02 instructions.

View File

@ -222,30 +222,31 @@ namespace SourceGen.AsmGen {
/// <summary>
/// Map the mnemonics we chose for undocumented opcodes to the cc65 mnemonics.
/// After switching to the Unintended Opcodes mnemonics there's almost no difference.
///
/// We don't include the double- and triple-byte NOPs here, as cc65 doesn't
/// appear to have a definition for them (as of 2.17).
/// </summary>
private static Dictionary<string, string> sUndocMap = new Dictionary<string, string>() {
{ OpName.ASR, "alr" }, // imm 0x4b
{ OpName.ALR, "alr" }, // imm 0x4b
{ OpName.ANC, "anc" }, // imm 0x0b (and others)
{ OpName.ANE, "ane" }, // imm 0x8b
{ OpName.ARR, "arr" }, // imm 0x6b
{ OpName.SBX, "axs" }, // imm 0xcb
{ OpName.DCP, "dcp" }, // abs 0xcf
{ OpName.ISB, "isc" }, // abs 0xef
{ OpName.HLT, "jam" }, // abs 0x02 (and others)
{ OpName.LAE, "las" }, // abs,y 0xbb
{ OpName.LXA, "lax" }, // imm 0xab
{ OpName.ISC, "isc" }, // abs 0xef
{ OpName.JAM, "jam" }, // abs 0x02 (and others)
{ OpName.LAS, "las" }, // abs,y 0xbb
{ OpName.LAX, "lax" }, // imm 0xab; abs 0xaf
{ OpName.RLA, "rla" }, // abs 0x2f
{ OpName.RRA, "rra" }, // abs 0x6f
{ OpName.SAX, "sax" }, // abs 0x8f
{ OpName.SBX, "axs" }, //* imm 0xcb
{ OpName.SHA, "sha" }, // abs,y 0x9f
{ OpName.SHX, "shx" }, // abs,y 0x9e
{ OpName.SHY, "shy" }, // abs,x 0x9c
{ OpName.SLO, "slo" }, // abs 0x0f
{ OpName.SRE, "sre" }, // abs 0x4f
{ OpName.SHS, "tas" }, // abs,y 0x9b
{ OpName.TAS, "tas" }, // abs,y 0x9b
};
// IGenerator
@ -258,7 +259,7 @@ namespace SourceGen.AsmGen {
} else if (op.IsUndocumented) {
if (sUndocMap.TryGetValue(op.Mnemonic, out string newValue)) {
if ((op.Mnemonic == OpName.ANC && op.Opcode != 0x0b) ||
(op.Mnemonic == OpName.HLT && op.Opcode != 0x02)) {
(op.Mnemonic == OpName.JAM && op.Opcode != 0x02)) {
// There are multiple opcodes for the same thing. cc65 outputs
// one specific thing, so we need to match that, and just do a hex
// dump for the others.

View File

@ -196,11 +196,11 @@ L1169: sha ($ff),y
ldy #$ff
lda ($ff,x)
ldx #$ff
.byte $a3,$ff
lax ($ff,x)
ldy $ff
lda $ff
ldx $ff
.byte $a7,$ff
lax $ff
tay
lda #$ff
tax
@ -208,16 +208,16 @@ L1169: sha ($ff),y
ldy $feff
lda $feff
ldx $feff
.byte $af,$ff,$fe
lax $feff
bcs L11AB
L11AB: lda ($ff),y
.byte $b2
L11AE: .byte $b3,$ff
L11AE: lax ($ff),y
ldy $ff,x
lda $ff,x
ldx $ff,y
.byte $b7,$ff
lax $ff,y
clv
lda $feff,y
tsx
@ -225,7 +225,7 @@ L11AE: .byte $b3,$ff
ldy $feff,x
lda $feff,x
ldx $feff,y
.byte $bf,$ff,$fe
lax $feff,y
cpy #$ff
cmp ($ff,x)
.byte $c2,$ff

View File

@ -196,11 +196,11 @@ L1169: sha ($00),y
ldy #$00
lda ($00,x)
ldx #$00
.byte $a3,$00
lax ($00,x)
ldy $00
lda $00
ldx $00
.byte $a7,$00
lax $00
tay
lda #$00
tax
@ -208,16 +208,16 @@ L1169: sha ($00),y
ldy a:$0000
lda a:$0000
ldx a:$0000
.byte $af,$00,$00
lax a:$0000
bcs L11AB
L11AB: lda ($00),y
.byte $b2
L11AE: .byte $b3,$00
L11AE: lax ($00),y
ldy $00,x
lda $00,x
ldx $00,y
.byte $b7,$00
lax $00,y
clv
lda $0000,y
tsx
@ -225,7 +225,7 @@ L11AE: .byte $b3,$00
ldy a:$0000,x
lda a:$0000,x
ldx a:$0000,y
.byte $bf,$00,$00
lax a:$0000,y
cpy #$00
cmp ($00,x)
.byte $c2,$00