+6502 mode
In 6502 mode (which is the default) the assembler accepts all regular "legal"
6502 mnemonics and addressing modes.
-6502X mode
+6502X mode
6502X mode is an extension to the normal 6502 mode. In this mode, several
mnemonics for undocumented instructions of the NMOS 6502 CPUs are accepted.
@@ -492,7 +505,7 @@ for them.
-DTV mode
+DTV mode
The C64DTV CPU is based on the 6510, but adds some instructions, and does not
support all undocumented instructions.
@@ -520,7 +533,7 @@ Supported undocumented instructions:
-65SC02 mode
+65SC02 mode
65SC02 mode supports all regular 6502 instructions, plus the following:
@@ -555,7 +568,7 @@ $fa plx
-65C02 mode
+65C02 mode
65C02 mode supports all "official" W65C02 opcodes.
@@ -576,7 +589,7 @@ $db stp wait for reset
-4510 mode
+4510 mode
The 4510 is a microcontroller that is the core of the Commodore C65 aka C64DX.
It contains among other functions a slightly modified 65CE02/4502 CPU, to allow
@@ -607,8 +620,13 @@ For more information about the Commodore C65/C64DX and the 4510 CPU, see
and
.
+45GS02 mode
-HUC6280 mode
+The 45GS02 is a microcontroller that is the core of the MEGA65.
+It is an extension of the 4510 CPU and adds 32-bit addressing and a 32-bit
+pseudo register Q that is comprised of the four registers A, X, Y, and Z.
+
+HUC6280 mode
The HUC6280 is a superset of the R65C02. It adds some other instructions:
@@ -644,7 +662,7 @@ $f4 set
Note that this CPU does not implement wai and stp .
-M740 mode
+M740 mode
The M740 is a microcontroller by Mitsubishi, which was marketed for embedded
devices in the mid 80s. It is a superset of 6502, and a subset of 65SC02, plus
@@ -654,7 +672,7 @@ For more information about the M740 Controllers, see
.
-65816 mode
+65816 mode
In 65816 mode, several aliases are accepted, in addition to the official
mnemonics:
@@ -682,7 +700,7 @@ or two far addresses whose high byte will be used.
-sweet16 mode
+sweet16 mode
SWEET 16 is an interpreter for a pseudo 16 bit CPU written by Steve Wozniak
for the Apple ][ machines. It is available in the Apple ][ ROM. ca65 can
@@ -3399,6 +3417,12 @@ See: , command).
+.IFP45GS02
+
+ Conditional assembly: Check if the assembler is currently in 45GS02 mode
+ (see command).
+
+
.IFP816
Conditional assembly: Check if the assembler is currently in 65816 mode
@@ -3782,8 +3806,9 @@ See: , command line option.
See: , , and
-
+ name=".PSC02">, ,
+ , and
+
.P02X
@@ -3802,19 +3827,30 @@ See: , , , and
-
+ name=".PSC02">, ,
+ , and
+
+.P45GS02
+
+ Enable the 45GS02 instruction set. This is a superset of the 4510, 65C02, and
+ 6502 instruction sets.
+
+ See: , , ,
+ , and
+
+
.P816
Enable the 65816 instruction set. This is a superset of the 65SC02 and
6502 instruction sets.
See: , , and
-
-
+ name=".PSC02">, ,
+ , and
+
.PAGELEN, .PAGELENGTH
@@ -3841,9 +3877,9 @@ See: , , , and
-
-
+ name=".PSC02">, ,
+ , and
+
.PDTV
@@ -3946,9 +3982,9 @@ See: , , , and
-
-
+ name=".PC02">, ,
+ , and
+
.PUSHCHARMAP
@@ -4195,7 +4231,7 @@ See: , command line option,
- namely: 6502, 6502X, 6502DTV, 65SC02, 65C02, 65816, 4510, HuC6280 and m740.
+ namely: 6502, 6502X, 6502DTV, 65SC02, 65C02, 65816, 4510, 45GS02, HuC6280 and m740.
See: ,
,
@@ -4209,6 +4245,7 @@ See: , ,
,
,
+ ,
,
,
@@ -4948,6 +4985,7 @@ each supported CPU a constant similar to
CPU_SWEET16
CPU_HUC6280
CPU_4510
+ CPU_45GS02
CPU_6502DTV
CPU_M740
@@ -4964,6 +5002,7 @@ another constant is defined:
CPU_ISET_SWEET16
CPU_ISET_HUC6280
CPU_ISET_4510
+ CPU_ISET_45GS02
CPU_ISET_6502DTV
CPU_ISET_M740
diff --git a/doc/da65.sgml b/doc/da65.sgml
index b72cd9b66..7300d3d71 100644
--- a/doc/da65.sgml
+++ b/doc/da65.sgml
@@ -110,22 +110,18 @@ Here is a description of all the command line options:
Set the CPU type. The option takes a parameter, which may be one of
- - 6502
-
- 6502x
-
- 6502dtv
-
- 65sc02
-
- 65c02
-
- 65816
-
- huc6280
-
- 4510
-
- m740
+
- 6502 - NMOS 6502 (all legal instructions)
+
- 6502X - NMOS 6502 with all undocumented instructions
+
- 6502DTV - the emulated CPU of the C64DTV device
+
- 65SC02 - first CMOS instruction set (no bit manipulation, no wai/stp)
+
- 65C02 - full CMOS instruction set (has bit manipulation and wai/stp)
+
- 65816 - the CPU of the SNES, and the SCPU
+
- HuC6280 - the CPU of the PC engine
+
- 4510 - the CPU of the Commodore C65
+
- 45GS02 - the CPU of the Commodore MEGA65
+
- M740 - a Microcontroller by Mitsubishi
- 6502x is for the NMOS 6502 with unofficial opcodes. 6502dtv is for the
- emulated CPU of the C64DTV device. huc6280 is the CPU of the PC engine.
- 4510 is the CPU of the Commodore C65. 65816 is the CPU of the SNES. M740 is a
- Microcontroller by Mitsubishi.
-
-F, --formfeeds
@@ -248,23 +244,79 @@ Here is a description of all the command line options:
Supported CPUs
+With the command line option , the
+disassembler may be told which CPU to support:
+
+
+ [ - NMOS 6502 (all legal instructions)
+ ][ - NMOS 6502 with all undocumented instructions
+ ][ - the emulated CPU of the C64DTV device
+ ][ - first CMOS instruction set (no bit manipulation, no wai/stp)
+ ][ - full CMOS instruction set (has bit manipulation and wai/stp)
+ ][ - the CPU of the SNES, and the SCPU
+ ][ - the CPU of the PC engine
+ ][ - the CPU of the Commodore C65
+ ][ - the CPU of the Commodore MEGA65
+ ][ - a Microcontroller by Mitsubishi
+ ]
+
+for more details on the various CPUs, see .
+
+
+6502 mode
+
The default (no CPU given on the command line or in the , the
-disassembler may be told to recognize either the 65SC02 or 65C02 CPUs. The
-latter understands the same opcodes as the former, plus 16 additional bit
-manipulation and bit test-and-branch commands. Using 6502x as CPU the illegal
-opcodes of 6502 CPU are detected and displayed. 6502dtv setting recognizes the
-emulated CPU instructions of the C64DTV device.
+6502X mode
+Using 6502X as CPU the illegal opcodes of 6502 CPU are detected and displayed.
+
+
+DTV mode
+
+6502DTV setting recognizes the emulated CPU instructions of the C64DTV device.
+
+
+65SC02 mode
+
+The first CMOS instruction set, without bit manipulation or wai/stp.
+
+
+65C02 mode
+
+The 65C02 understands the same opcodes as the 65SC02, plus 16 additional bit
+manipulation and bit test-and-branch commands.
+
+This mode also supports wai/stp.
+
+
+4510 mode
When disassembling 4510 code, due to handling of 16-bit wide branches, da65
can produce output that can not be re-assembled, when one or more of those
branches point outside of the disassembled memory. This can happen when text
or binary data is processed.
+
+45GS02 mode
+
+All compound instructions are supported.
+
+
+HUC6280 mode
+
+All special opcodes are supported.
+
+
+M740 mode
+
+All special opcodes are supported.
+
+
+65816 mode
+
The 65816 support requires annotating ranges with the M and X flag states.
This can be recorded with an emulator that supports Code and Data Logging,
for example. Disassemble one bank at a time.
diff --git a/src/ca65/condasm.c b/src/ca65/condasm.c
index a65fbebba..c63e54e3a 100644
--- a/src/ca65/condasm.c
+++ b/src/ca65/condasm.c
@@ -414,6 +414,16 @@ void DoConditionals (void)
CalcOverallIfCond ();
break;
+ case TOK_IFP45GS02:
+ D = AllocIf (".IFP45GS02", 1);
+ NextTok ();
+ if (IfCond) {
+ SetIfCond (D, GetCPU() == CPU_45GS02);
+ }
+ ExpectSep ();
+ CalcOverallIfCond ();
+ break;
+
case TOK_IFP816:
D = AllocIf (".IFP816", 1);
NextTok ();
@@ -507,6 +517,7 @@ int CheckConditionals (void)
case TOK_IFP02:
case TOK_IFP02X:
case TOK_IFP4510:
+ case TOK_IFP45GS02:
case TOK_IFP816:
case TOK_IFPC02:
case TOK_IFPDTV:
diff --git a/src/ca65/ea65.c b/src/ca65/ea65.c
index da11b268a..898b344ca 100644
--- a/src/ca65/ea65.c
+++ b/src/ca65/ea65.c
@@ -101,6 +101,9 @@ void GetEA (EffAddr* A)
if (TokIsSep (CurTok.Tok)) {
A->AddrModeSet = AM65_IMPLICIT;
+ if (GetCPU () == CPU_45GS02) {
+ A->AddrModeSet |= AM65_Q;
+ }
} else if (CurTok.Tok == TOK_HASH) {
@@ -114,6 +117,11 @@ void GetEA (EffAddr* A)
NextTok ();
A->AddrModeSet = AM65_ACCU;
+ } else if (CurTok.Tok == TOK_Q) {
+
+ NextTok ();
+ A->AddrModeSet = AM65_Q;
+
} else if (CurTok.Tok == IndirectEnter) {
/* One of the indirect modes */
@@ -160,8 +168,19 @@ void GetEA (EffAddr* A)
}
} else {
/* (adr) */
- A->AddrModeSet = (CPU == CPU_4510) ? AM65_ABS_IND
- : AM65_ABS_IND | AM65_ABS_IND_LONG | AM65_DIR_IND;
+ switch (CPU) {
+ case CPU_4510:
+ A->AddrModeSet = AM65_ABS_IND;
+ break;
+
+ case CPU_45GS02:
+ A->AddrModeSet = AM65_ABS_IND | AM65_DIR_IND;
+ break;
+
+ default:
+ A->AddrModeSet = AM65_ABS_IND | AM65_ABS_IND_LONG | AM65_DIR_IND;
+ break;
+ }
}
}
@@ -175,8 +194,14 @@ void GetEA (EffAddr* A)
if (CurTok.Tok == TOK_COMMA) {
/* [dir],y */
NextTok ();
- Consume (TOK_Y, "'Y' expected");
- A->AddrModeSet = AM65_DIR_IND_LONG_Y;
+ if (GetCPU () == CPU_45GS02) {
+ Consume (TOK_Z, "'Z' expected");
+ A->AddrModeSet = AM65_32BIT_BASE_IND_Z;
+ }
+ else {
+ Consume (TOK_Y, "'Y' expected");
+ A->AddrModeSet = AM65_DIR_IND_LONG_Y;
+ }
} else {
/* [dir] */
A->AddrModeSet = AM65_DIR_IND_LONG | AM65_ABS_IND_LONG;
diff --git a/src/ca65/instr.c b/src/ca65/instr.c
index f94740dcb..c19be11b2 100644
--- a/src/ca65/instr.c
+++ b/src/ca65/instr.c
@@ -154,6 +154,12 @@ static void PutAll (const InsDesc* Ins);
static void Put4510 (const InsDesc* Ins);
/* Handle instructions of 4510 not matching any EATab */
+static void Put45GS02 (const InsDesc* Ins);
+/* Handle [adr],z instructions of 45GS02 */
+
+static void Put45GS02_Q (const InsDesc* Ins);
+/* Handle Q instructions of 45GS02 */
+
static void PutSweet16 (const InsDesc* Ins);
/* Handle a generic sweet16 instruction */
@@ -758,6 +764,170 @@ static const struct {
}
};
+
+/* Instruction table for the 45GS02 */
+static const struct {
+ unsigned Count;
+ InsDesc Ins[149];
+} InsTab45GS02 = {
+ /* CAUTION: table must be sorted for bsearch */
+ sizeof (InsTab45GS02.Ins) / sizeof (InsTab45GS02.Ins[0]),
+ {
+/* BEGIN SORTED.SH */
+ { "ADC", 0x4080A66C, 0x60, 0, Put45GS02 },
+ { "ADCQ", 0x0000140C, 0x60, 13, Put45GS02_Q },
+ { "AND", 0x4080A66C, 0x20, 0, Put45GS02 },
+ { "ANDQ", 0x0000140C, 0x20, 13, Put45GS02_Q },
+ { "ASL", 0x0000006e, 0x02, 1, PutAll },
+ { "ASLQ", 0x800000ee, 0x00, 14, Put45GS02_Q },
+ { "ASR", 0x00000026, 0x43, 0, Put4510 },
+ { "ASRQ", 0x80000026, 0x40, 15, Put45GS02_Q },
+ { "ASW", 0x00000008, 0xcb, 6, PutAll },
+ { "BBR0", 0x00000000, 0x0F, 0, PutBitBranch },
+ { "BBR1", 0x00000000, 0x1F, 0, PutBitBranch },
+ { "BBR2", 0x00000000, 0x2F, 0, PutBitBranch },
+ { "BBR3", 0x00000000, 0x3F, 0, PutBitBranch },
+ { "BBR4", 0x00000000, 0x4F, 0, PutBitBranch },
+ { "BBR5", 0x00000000, 0x5F, 0, PutBitBranch },
+ { "BBR6", 0x00000000, 0x6F, 0, PutBitBranch },
+ { "BBR7", 0x00000000, 0x7F, 0, PutBitBranch },
+ { "BBS0", 0x00000000, 0x8F, 0, PutBitBranch },
+ { "BBS1", 0x00000000, 0x9F, 0, PutBitBranch },
+ { "BBS2", 0x00000000, 0xAF, 0, PutBitBranch },
+ { "BBS3", 0x00000000, 0xBF, 0, PutBitBranch },
+ { "BBS4", 0x00000000, 0xCF, 0, PutBitBranch },
+ { "BBS5", 0x00000000, 0xDF, 0, PutBitBranch },
+ { "BBS6", 0x00000000, 0xEF, 0, PutBitBranch },
+ { "BBS7", 0x00000000, 0xFF, 0, PutBitBranch },
+ { "BCC", 0x00020000, 0x90, 0, PutPCRel8 },
+ { "BCS", 0x00020000, 0xb0, 0, PutPCRel8 },
+ { "BEQ", 0x00020000, 0xf0, 0, PutPCRel8 },
+ { "BIT", 0x00A0006C, 0x00, 2, PutAll },
+ { "BITQ", 0x0000000c, 0x20, 15, Put45GS02_Q },
+ { "BMI", 0x00020000, 0x30, 0, PutPCRel8 },
+ { "BNE", 0x00020000, 0xd0, 0, PutPCRel8 },
+ { "BPL", 0x00020000, 0x10, 0, PutPCRel8 },
+ { "BRA", 0x00020000, 0x80, 0, PutPCRel8 },
+ { "BRK", 0x00000001, 0x00, 0, PutAll },
+ { "BSR", 0x00040000, 0x63, 0, PutPCRel4510 },
+ { "BVC", 0x00020000, 0x50, 0, PutPCRel8 },
+ { "BVS", 0x00020000, 0x70, 0, PutPCRel8 },
+ { "CLC", 0x00000001, 0x18, 0, PutAll },
+ { "CLD", 0x00000001, 0xd8, 0, PutAll },
+ { "CLE", 0x00000001, 0x02, 0, PutAll },
+ { "CLI", 0x00000001, 0x58, 0, PutAll },
+ { "CLV", 0x00000001, 0xb8, 0, PutAll },
+ { "CMP", 0x4080A66C, 0xc0, 0, Put45GS02 },
+ { "CMPQ", 0x0000140C, 0xC0, 13, Put45GS02_Q },
+ { "CPX", 0x0080000C, 0xe0, 1, PutAll },
+ { "CPY", 0x0080000C, 0xc0, 1, PutAll },
+ { "CPZ", 0x0080000C, 0xd0, 1, Put4510 },
+ { "DEA", 0x00000001, 0x00, 3, PutAll }, /* == DEC */
+ { "DEC", 0x0000006F, 0x00, 3, PutAll },
+ { "DEQ", 0x800000ee, 0xc0, 14, Put45GS02_Q },
+ { "DEW", 0x00000004, 0xc3, 9, PutAll },
+ { "DEX", 0x00000001, 0xca, 0, PutAll },
+ { "DEY", 0x00000001, 0x88, 0, PutAll },
+ { "DEZ", 0x00000001, 0x3B, 0, PutAll },
+ { "EOM", 0x00000001, 0xea, 0, PutAll },
+ { "EOR", 0x4080A66C, 0x40, 0, Put45GS02 },
+ { "EORQ", 0x0000140C, 0x40, 13, Put45GS02_Q },
+ { "INA", 0x00000001, 0x00, 4, PutAll }, /* == INC */
+ { "INC", 0x0000006f, 0x00, 4, PutAll },
+ { "INQ", 0x800000ee, 0xe0, 14, Put45GS02_Q },
+ { "INW", 0x00000004, 0xe3, 9, PutAll },
+ { "INX", 0x00000001, 0xe8, 0, PutAll },
+ { "INY", 0x00000001, 0xc8, 0, PutAll },
+ { "INZ", 0x00000001, 0x1B, 0, PutAll },
+ { "JMP", 0x00010808, 0x4c, 6, PutAll },
+ { "JSR", 0x00010808, 0x20, 7, Put4510 },
+ { "LBCC", 0x00040000, 0x93, 0, PutPCRel4510 },
+ { "LBCS", 0x00040000, 0xb3, 0, PutPCRel4510 },
+ { "LBEQ", 0x00040000, 0xf3, 0, PutPCRel4510 },
+ { "LBMI", 0x00040000, 0x33, 0, PutPCRel4510 },
+ { "LBNE", 0x00040000, 0xd3, 0, PutPCRel4510 },
+ { "LBPL", 0x00040000, 0x13, 0, PutPCRel4510 },
+ { "LBRA", 0x00040000, 0x83, 0, PutPCRel4510 },
+ { "LBVC", 0x00040000, 0x53, 0, PutPCRel4510 },
+ { "LBVS", 0x00040000, 0x73, 0, PutPCRel4510 },
+ { "LDA", 0x4090A66C, 0xa0, 0, Put45GS02 },
+ { "LDQ", 0x4000140C, 0xa0, 13, Put45GS02_Q },
+ { "LDX", 0x0080030C, 0xa2, 1, PutAll },
+ { "LDY", 0x0080006C, 0xa0, 1, PutAll },
+ { "LDZ", 0x00800048, 0xa3, 1, Put4510 },
+ { "LSR", 0x0000006F, 0x42, 1, PutAll },
+ { "LSRQ", 0x800000ee, 0x40, 14, Put45GS02_Q },
+ { "MAP", 0x00000001, 0x5C, 0, PutAll },
+ { "NEG", 0x00000001, 0x42, 0, PutAll },
+ { "NOP", 0x00000001, 0xea, 0, PutAll }, /* == EOM */
+ { "ORA", 0x4080A66C, 0x00, 0, Put45GS02 },
+ { "ORQ", 0x0000140C, 0x00, 13, Put45GS02_Q },
+ { "PHA", 0x00000001, 0x48, 0, PutAll },
+ { "PHD", 0x08000008, 0xf4, 1, PutAll }, /* == PHW */
+ { "PHP", 0x00000001, 0x08, 0, PutAll },
+ { "PHW", 0x08000008, 0xf4, 1, PutAll },
+ { "PHX", 0x00000001, 0xda, 0, PutAll },
+ { "PHY", 0x00000001, 0x5a, 0, PutAll },
+ { "PHZ", 0x00000001, 0xdb, 0, PutAll },
+ { "PLA", 0x00000001, 0x68, 0, PutAll },
+ { "PLP", 0x00000001, 0x28, 0, PutAll },
+ { "PLX", 0x00000001, 0xfa, 0, PutAll },
+ { "PLY", 0x00000001, 0x7a, 0, PutAll },
+ { "PLZ", 0x00000001, 0xfb, 0, PutAll },
+ { "RMB0", 0x00000004, 0x07, 1, PutAll },
+ { "RMB1", 0x00000004, 0x17, 1, PutAll },
+ { "RMB2", 0x00000004, 0x27, 1, PutAll },
+ { "RMB3", 0x00000004, 0x37, 1, PutAll },
+ { "RMB4", 0x00000004, 0x47, 1, PutAll },
+ { "RMB5", 0x00000004, 0x57, 1, PutAll },
+ { "RMB6", 0x00000004, 0x67, 1, PutAll },
+ { "RMB7", 0x00000004, 0x77, 1, PutAll },
+ { "ROL", 0x0000006F, 0x22, 1, PutAll },
+ { "ROLQ", 0x800000ee, 0x20, 14, Put45GS02_Q },
+ { "ROR", 0x0000006F, 0x62, 1, PutAll },
+ { "RORQ", 0x800000ee, 0x60, 14, Put45GS02_Q },
+ { "ROW", 0x00000008, 0xeb, 6, PutAll },
+ { "RTI", 0x00000001, 0x40, 0, PutAll },
+ { "RTN", 0x00800000, 0x62, 1, PutAll },
+ { "RTS", 0x00000001, 0x60, 0, PutAll },
+ { "SBC", 0x4080A66C, 0xe0, 0, Put45GS02 },
+ { "SBCQ", 0x0000140C, 0xe0, 13, Put45GS02_Q },
+ { "SEC", 0x00000001, 0x38, 0, PutAll },
+ { "SED", 0x00000001, 0xf8, 0, PutAll },
+ { "SEE", 0x00000001, 0x03, 0, PutAll },
+ { "SEI", 0x00000001, 0x78, 0, PutAll },
+ { "SMB0", 0x00000004, 0x87, 1, PutAll },
+ { "SMB1", 0x00000004, 0x97, 1, PutAll },
+ { "SMB2", 0x00000004, 0xA7, 1, PutAll },
+ { "SMB3", 0x00000004, 0xB7, 1, PutAll },
+ { "SMB4", 0x00000004, 0xC7, 1, PutAll },
+ { "SMB5", 0x00000004, 0xD7, 1, PutAll },
+ { "SMB6", 0x00000004, 0xE7, 1, PutAll },
+ { "SMB7", 0x00000004, 0xF7, 1, PutAll },
+ { "STA", 0x4010A66C, 0x80, 0, Put45GS02 },
+ { "STQ", 0x0000140C, 0x80, 13, Put45GS02_Q },
+ { "STX", 0x0000030c, 0x82, 1, Put4510 },
+ { "STY", 0x0000006c, 0x80, 1, Put4510 },
+ { "STZ", 0x0000006c, 0x04, 5, PutAll },
+ { "TAB", 0x00000001, 0x5b, 0, PutAll },
+ { "TAX", 0x00000001, 0xaa, 0, PutAll },
+ { "TAY", 0x00000001, 0xa8, 0, PutAll },
+ { "TAZ", 0x00000001, 0x4b, 0, PutAll },
+ { "TBA", 0x00000001, 0x7b, 0, PutAll },
+ { "TRB", 0x0000000c, 0x10, 1, PutAll },
+ { "TSB", 0x0000000c, 0x00, 1, PutAll },
+ { "TSX", 0x00000001, 0xba, 0, PutAll },
+ { "TSY", 0x00000001, 0x0b, 0, PutAll },
+ { "TXA", 0x00000001, 0x8a, 0, PutAll },
+ { "TXS", 0x00000001, 0x9a, 0, PutAll },
+ { "TYA", 0x00000001, 0x98, 0, PutAll },
+ { "TYS", 0x00000001, 0x2b, 0, PutAll },
+ { "TZA", 0x00000001, 0x6b, 0, PutAll },
+/* END SORTED.SH */
+ }
+};
+
+
/* Instruction table for the 65816 */
static const struct {
unsigned Count;
@@ -1192,6 +1362,7 @@ static const InsTable* InsTabs[CPU_COUNT] = {
(const InsTable*) &InsTabHuC6280,
(const InsTable*) &InsTabm740, /* Mitsubishi 740 */
(const InsTable*) &InsTab4510,
+ (const InsTable*) &InsTab45GS02,
};
const InsTable* InsTab = (const InsTable*) &InsTab6502;
@@ -1199,85 +1370,103 @@ const InsTable* InsTab = (const InsTable*) &InsTab6502;
** addressing mode. (The value in the table is ORed with the base opcode)
** NOTE: each table has one entry per addressing mode!
*/
-static unsigned char EATab[14][AM65I_COUNT] = {
+static unsigned char EATab[16][AM65I_COUNT] = {
{ /* Table 0 (sec, sed, seo, set, slw, sta, stp, tax, tay, tsx, txa, txs, tya) */
0x00, 0x00, 0x05, 0x0D, 0x0F, 0x15, 0x1D, 0x1F,
0x00, 0x19, 0x12, 0x00, 0x07, 0x11, 0x17, 0x01,
0x00, 0x00, 0x00, 0x03, 0x13, 0x09, 0x00, 0x09,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00
},
- { /* Table 1 (rol, ror, stx, sty, tst) */
+ { /* Table 1 (rol, ror, stx, sty, tst, cpx, cpy) */
0x08, 0x08, 0x04, 0x0C, 0x00, 0x14, 0x1C, 0x00,
0x14, 0x1C, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x00, 0x00, 0x00
+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00
},
{ /* Table 2 (bit) */
0x00, 0x00, 0x24, 0x2C, 0x0F, 0x34, 0x3C, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
},
{ /* Table 3 (dec, dea) */
0x3A, 0x3A, 0xC6, 0xCE, 0x00, 0xD6, 0xDE, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
},
{ /* Table 4 (inc) */
0x1A, 0x1A, 0xE6, 0xEE, 0x00, 0xF6, 0xFE, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
},
{ /* Table 5 (stz) */
0x00, 0x00, 0x60, 0x98, 0x00, 0x70, 0x9E, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
},
{ /* Table 6 (jmp, rrf) */
0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00,
0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x90, 0x00, 0x00, 0x00
+ 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00
},
{ /* Table 7 (jsr) */
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
},
{ /* Table 8 */
0x00, 0x40, 0x01, 0x41, 0x00, 0x09, 0x49, 0x00,
0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
},
{ /* Table 9 (dew, inw) */
0x00, 0x00, 0x00, 0x10, 0x00, 0x20, 0x30, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
},
{ /* Table 10 (NOPs, clbX, sebX) */
0xea, 0x00, 0x04, 0x0c, 0x00, 0x14, 0x1c, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
},
{ /* Table 11 (LAX) */
0x08, 0x08, 0x04, 0x0C, 0x00, 0x14, 0x1C, 0x00,
0x14, 0x1C, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
- 0x00, 0x00, 0x80, 0x00, 0x00, 0x00
+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00
},
{ /* Table 12 (m740: JMP) */
0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xb2, 0x6c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
},
+ { /* Table 13 (Q) */
+ 0x00, 0x00, 0x05, 0x0D, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x12, 0x00, 0x12, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00
+ },
+ { /* Table 14 (45GS02: ASLQ) */
+ 0x0a, 0x0a, 0x06, 0x0e, 0x00, 0x16, 0x1e, 0x00,
+ 0x00, 0x00, 0x12, 0x00, 0x12, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a
+ },
+ { /* Table 15 (45GS02: ASRQ) */
+ 0x03, 0x03, 0x04, 0x0c, 0x00, 0x14, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03
+ }
};
/* Table to build the effective SWEET16 opcode from a base opcode and an
@@ -1325,6 +1514,8 @@ unsigned char ExtBytes[AM65I_COUNT] = {
2, /* Immidiate word */
2, /* Direct, Relative short */
1, /* Special Page */
+ 1, /* [Direct],z */
+ 0, /* Q */
};
/* Table that encodes the additional bytes for each SWEET16 instruction */
@@ -1968,9 +2159,7 @@ static void PutAll (const InsDesc* Ins)
-static void Put4510 (const InsDesc* Ins)
-/* Handle all other instructions, with modifications for 4510 */
-{
+static void Emit4510 (EffAddr* A) {
/* The 4510 uses all 256 possible opcodes, so the last ones were crammed
** in where an opcode was still undefined. As a result, some of those
** don't follow any rules for encoding the addressmodes. So the EATab
@@ -1990,25 +2179,91 @@ static void Put4510 (const InsDesc* Ins)
** $d0 -> $c2 : CPZ #$00
** $fc -> $23 : JSR ($1234,X)
*/
+ switch (A->Opcode) {
+ case 0x47:
+ A->Opcode = 0x44;
+ break;
+ case 0x57:
+ A->Opcode = 0x54;
+ break;
+ case 0x93:
+ A->Opcode = 0x82;
+ break;
+ case 0x9C:
+ A->Opcode = 0x8B;
+ break;
+ case 0x9E:
+ A->Opcode = 0x9B;
+ break;
+ case 0xAF:
+ A->Opcode = 0xAB;
+ break;
+ case 0xBF:
+ A->Opcode = 0xBB;
+ break;
+ case 0xB3:
+ A->Opcode = 0xE2;
+ break;
+ case 0xD0:
+ A->Opcode = 0xC2;
+ break;
+ case 0xFC:
+ A->Opcode = 0x23;
+ break;
+ default: /* Keep opcode as it is */ break;
+ }
+
+ /* No error, output code */
+ EmitCode (A);
+}
+
+
+
+static void Put4510 (const InsDesc* Ins)
+/* Handle all other instructions, with modifications for 4510 */
+{
EffAddr A;
/* Evaluate the addressing mode used */
if (EvalEA (Ins, &A)) {
- switch (A.Opcode) {
- case 0x47: A.Opcode = 0x44; break;
- case 0x57: A.Opcode = 0x54; break;
- case 0x93: A.Opcode = 0x82; break;
- case 0x9C: A.Opcode = 0x8B; break;
- case 0x9E: A.Opcode = 0x9B; break;
- case 0xAF: A.Opcode = 0xAB; break;
- case 0xBF: A.Opcode = 0xBB; break;
- case 0xB3: A.Opcode = 0xE2; break;
- case 0xD0: A.Opcode = 0xC2; break;
- case 0xFC: A.Opcode = 0x23; break;
- default: /* Keep opcode as it is */ break;
- }
+ Emit4510 (&A);
+ }
+}
- /* No error, output code */
+
+
+static void Put45GS02 (const InsDesc* Ins)
+/* Handle all other instructions, with modifications for 45GS02 */
+{
+ EffAddr A;
+
+ if (EvalEA (Ins, &A)) {
+ if (A.AddrModeSet == AM65_32BIT_BASE_IND_Z) {
+ Emit0 (0xEA); /* NOP prefix */
+ }
+ Emit4510 (&A);
+ }
+}
+
+
+
+static void Put45GS02_Q (const InsDesc* Ins)
+{
+ EffAddr A;
+
+ if (EvalEA (Ins, &A)) {
+ Emit0 (0x42);
+ Emit0 (0x42);
+ if ((A.AddrModeBit == AM65_DIR_IND_LONG) ||
+ (A.AddrModeBit == AM65_32BIT_BASE_IND_Z)) {
+ Emit0 (0xEA); /* NOP prefix */
+ }
+ if (A.Opcode == 0xea) {
+ A.Opcode = 0x1a;
+ }
+ else if (A.Opcode == 0xca) {
+ A.Opcode = 0x3a;
+ }
EmitCode (&A);
}
}
diff --git a/src/ca65/instr.h b/src/ca65/instr.h
index 8e0900c77..9c91fd0cf 100644
--- a/src/ca65/instr.h
+++ b/src/ca65/instr.h
@@ -59,35 +59,37 @@
** available on these CPUs are removed before doing any checks.
*/
#define AM65_IMPLICIT 0x00000003UL /* IMP */
-#define AM65_ACCU 0x00000002UL /* A, BIT, A */
-#define AM65_DIR 0x00000004UL /* ZP, BIT, ZP */
+#define AM65_ACCU 0x00000002UL /* A */
+#define AM65_DIR 0x00000004UL /* ZP */
#define AM65_ABS 0x00000008UL /* ABS */
-#define AM65_ABS_LONG 0x00000010UL /* -- */
+#define AM65_ABS_LONG 0x00000010UL /* adr */
#define AM65_DIR_X 0x00000020UL /* ZP,X */
#define AM65_ABS_X 0x00000040UL /* ABS, X */
-#define AM65_ABS_LONG_X 0x00000080UL /* -- */
+#define AM65_ABS_LONG_X 0x00000080UL /* adr,x */
#define AM65_DIR_Y 0x00000100UL /* ZP, Y */
#define AM65_ABS_Y 0x00000200UL /* ABS, Y */
-#define AM65_DIR_IND 0x00000400UL /* (ZP IND) */
-#define AM65_ABS_IND 0x00000800UL /* (IND) */
-#define AM65_DIR_IND_LONG 0x00001000UL /* -- */
-#define AM65_DIR_IND_Y 0x00002000UL /* IND, Y */
-#define AM65_DIR_IND_LONG_Y 0x00004000UL /* -- */
-#define AM65_DIR_X_IND 0x00008000UL /* IND, X */
-#define AM65_ABS_X_IND 0x00010000UL /* -- */
+#define AM65_DIR_IND 0x00000400UL /* (ZP) or (ZP),z (4510 / 45GS02) */
+#define AM65_ABS_IND 0x00000800UL /* (ABS) */
+#define AM65_DIR_IND_LONG 0x00001000UL /* [ABS] (65816) */
+#define AM65_DIR_IND_Y 0x00002000UL /* (ZP),y */
+#define AM65_DIR_IND_LONG_Y 0x00004000UL /* [adr],y (not 45GS02) */
+#define AM65_DIR_X_IND 0x00008000UL /* (ZP,x) */
+#define AM65_ABS_X_IND 0x00010000UL /* (ABS,x) */
#define AM65_REL 0x00020000UL /* REL */
-#define AM65_REL_LONG 0x00040000UL /* -- */
-#define AM65_STACK_REL 0x00080000UL /* SP ? */
-#define AM65_STACK_REL_IND_Y 0x00100000UL /* ? */
+#define AM65_REL_LONG 0x00040000UL /* LONGREL */
+#define AM65_STACK_REL 0x00080000UL /* adr,s */
+#define AM65_STACK_REL_IND_Y 0x00100000UL /* (rel,s),y */
#define AM65_IMM_ACCU 0x00200000UL
#define AM65_IMM_INDEX 0x00400000UL
#define AM65_IMM_IMPLICIT 0x00800000UL /* IMM */
-#define AM65_BLOCKMOVE 0x01000000UL /* -- */
-#define AM65_BLOCKXFER 0x02000000UL /* -- */
-#define AM65_ABS_IND_LONG 0x04000000UL /* -- */
+#define AM65_BLOCKMOVE 0x01000000UL
+#define AM65_BLOCKXFER 0x02000000UL
+#define AM65_ABS_IND_LONG 0x04000000UL /* (adr) [dir] */
#define AM65_IMM_IMPLICIT_WORD 0x08000000UL /* PHW #$1234 (4510 only) */
#define AM65_ZP_REL 0x10000000UL /* ZP, REL (m740) */
#define AM65_SPECIAL_PAGE 0x20000000UL /* $FFxx (m740) */
+#define AM65_32BIT_BASE_IND_Z 0x40000000UL /* LDA [$nn],Z (45GS02 only) */
+#define AM65_Q 0x80000000UL /* Q (45GS02 only) */
/* Bitmask for all ZP operations that have correspondent ABS ops */
#define AM65_SET_ZP (AM65_DIR | AM65_DIR_X | AM65_DIR_Y | AM65_DIR_IND | AM65_DIR_X_IND)
@@ -138,7 +140,9 @@
#define AM65I_IMM_IMPLICIT_WORD 27
#define AM65I_ZP_REL 28
#define AM65I_SPECIAL_PAGE 29
-#define AM65I_COUNT 30
+#define AM65I_32BIT_BASE_IND_Z 30
+#define AM65I_Q 31
+#define AM65I_COUNT 32
diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c
index 6cad9ed51..7e52ecb5e 100644
--- a/src/ca65/pseudo.c
+++ b/src/ca65/pseudo.c
@@ -1594,6 +1594,14 @@ static void DoP4510 (void)
+static void DoP45GS02 (void)
+/* Switch to 45GS02 CPU */
+{
+ SetCPU (CPU_45GS02);
+}
+
+
+
static void DoPDTV (void)
/* Switch to C64DTV CPU */
{
@@ -2151,6 +2159,7 @@ static CtrlDesc CtrlCmdTab [] = {
{ ccKeepToken, DoConditionals }, /* .IFP02 */
{ ccKeepToken, DoConditionals }, /* .IFP02X */
{ ccKeepToken, DoConditionals }, /* .IFP4510 */
+ { ccKeepToken, DoConditionals }, /* .IFP45GS02 */
{ ccKeepToken, DoConditionals }, /* .IFP816 */
{ ccKeepToken, DoConditionals }, /* .IFPC02 */
{ ccKeepToken, DoConditionals }, /* .IFPDTV */
@@ -2186,6 +2195,7 @@ static CtrlDesc CtrlCmdTab [] = {
{ ccNone, DoP02 }, /* .P02 */
{ ccNone, DoP02X }, /* .P02X */
{ ccNone, DoP4510 }, /* .P4510 */
+ { ccNone, DoP45GS02 }, /* .P45GS02 */
{ ccNone, DoP816 }, /* .P816 */
{ ccNone, DoPageLength }, /* .PAGELEN, .PAGELENGTH */
{ ccNone, DoUnexpected }, /* .PARAMCOUNT */
diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c
index 0d90ddc7f..dd0209856 100644
--- a/src/ca65/scanner.c
+++ b/src/ca65/scanner.c
@@ -223,6 +223,7 @@ struct DotKeyword {
{ ".IFP02", TOK_IFP02 },
{ ".IFP02X", TOK_IFP02X },
{ ".IFP4510", TOK_IFP4510 },
+ { ".IFP45GS02", TOK_IFP45GS02 },
{ ".IFP816", TOK_IFP816 },
{ ".IFPC02", TOK_IFPC02 },
{ ".IFPDTV", TOK_IFPDTV },
@@ -263,6 +264,7 @@ struct DotKeyword {
{ ".P02", TOK_P02 },
{ ".P02X", TOK_P02X },
{ ".P4510", TOK_P4510 },
+ { ".P45GS02", TOK_P45GS02 },
{ ".P816", TOK_P816 },
{ ".PAGELEN", TOK_PAGELENGTH },
{ ".PAGELENGTH", TOK_PAGELENGTH },
@@ -1279,12 +1281,19 @@ Again:
break;
case 'S':
- if ((CPU == CPU_4510) || (CPU == CPU_65816)) {
+ if ((CPU == CPU_4510) || (CPU == CPU_45GS02) || (CPU == CPU_65816)) {
CurTok.Tok = TOK_S;
return;
}
break;
+ case 'Q':
+ if (CPU == CPU_45GS02) {
+ CurTok.Tok = TOK_Q;
+ return;
+ }
+ break;
+
case 'X':
CurTok.Tok = TOK_X;
return;
@@ -1299,7 +1308,7 @@ Again:
CurTok.Tok = TOK_OVERRIDE_ZP;
return;
} else {
- if (CPU == CPU_4510) {
+ if ((CPU == CPU_4510) || (CPU == CPU_45GS02)) {
CurTok.Tok = TOK_Z;
return;
}
@@ -1311,7 +1320,7 @@ Again:
}
break;
case 2:
- if ((CPU == CPU_4510) &&
+ if ((CPU == CPU_4510 || CPU == CPU_45GS02) &&
(toupper (SB_AtUnchecked (&CurTok.SVal, 0)) == 'S') &&
(toupper (SB_AtUnchecked (&CurTok.SVal, 1)) == 'P')) {
diff --git a/src/ca65/token.h b/src/ca65/token.h
index d4fa3a697..9ca7ea657 100644
--- a/src/ca65/token.h
+++ b/src/ca65/token.h
@@ -68,6 +68,7 @@ typedef enum token_t {
TOK_Y, /* Y register */
TOK_Z, /* Z register */
TOK_S, /* S register */
+ TOK_Q, /* Q pseudo register */
TOK_REG, /* Sweet16 R.. register (in sweet16 mode) */
TOK_ASSIGN, /* := */
@@ -195,6 +196,7 @@ typedef enum token_t {
TOK_IFP02,
TOK_IFP02X,
TOK_IFP4510,
+ TOK_IFP45GS02,
TOK_IFP816,
TOK_IFPC02,
TOK_IFPDTV,
@@ -230,6 +232,7 @@ typedef enum token_t {
TOK_P02,
TOK_P02X,
TOK_P4510,
+ TOK_P45GS02,
TOK_P816,
TOK_PAGELENGTH,
TOK_PARAMCOUNT,
diff --git a/src/common/cpu.c b/src/common/cpu.c
index b55a5ab00..2c29eb1c4 100644
--- a/src/common/cpu.c
+++ b/src/common/cpu.c
@@ -63,6 +63,7 @@ const char* CPUNames[CPU_COUNT] = {
"huc6280",
"m740",
"4510",
+ "45GS02"
};
/* Tables with CPU instruction sets */
@@ -78,6 +79,7 @@ const unsigned CPUIsets[CPU_COUNT] = {
CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02 | CPU_ISET_HUC6280,
CPU_ISET_6502 | CPU_ISET_M740,
CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02 | CPU_ISET_4510,
+ CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02 | CPU_ISET_4510 | CPU_ISET_45GS02,
};
diff --git a/src/common/cpu.h b/src/common/cpu.h
index 2e75feaaf..6d8b72469 100644
--- a/src/common/cpu.h
+++ b/src/common/cpu.h
@@ -58,6 +58,7 @@ typedef enum {
CPU_HUC6280, /* Used in PC engine */
CPU_M740, /* Mitsubishi 740 series MCUs */
CPU_4510, /* CPU of C65 */
+ CPU_45GS02, /* CPU of MEGA65 */
CPU_COUNT /* Number of different CPUs */
} cpu_t;
@@ -74,6 +75,7 @@ enum {
CPU_ISET_HUC6280 = 1 << CPU_HUC6280,
CPU_ISET_M740 = 1 << CPU_M740,
CPU_ISET_4510 = 1 << CPU_4510,
+ CPU_ISET_45GS02 = 1 << CPU_45GS02
};
/* CPU used */
diff --git a/src/da65.vcxproj b/src/da65.vcxproj
index 9d2b0ded6..6610f907c 100644
--- a/src/da65.vcxproj
+++ b/src/da65.vcxproj
@@ -94,6 +94,7 @@
+
@@ -119,6 +120,7 @@
+
@@ -136,4 +138,4 @@
-
\ No newline at end of file
+
diff --git a/src/da65/handler.c b/src/da65/handler.c
index 45c152697..84229594f 100644
--- a/src/da65/handler.c
+++ b/src/da65/handler.c
@@ -47,6 +47,7 @@
#include "handler.h"
#include "labels.h"
#include "opctable.h"
+#include "opc45GS02.h"
#include "output.h"
@@ -226,6 +227,82 @@ void OH_Implicit (const OpcDesc* D)
+void OH_Implicit_ea_45GS02 (const OpcDesc* D)
+/* handle disassembling EOM prefixed opcodes, $ea $xx */
+{
+ /* Get byte after EOM */
+ unsigned opc = GetCodeByte (PC+1);
+ static const char *mnemonics[8] = {
+ "ora", "and", "eor", "adc", "sta", "lda", "cmp", "sbc"
+ };
+
+ if ((opc & 0x1f) == 0x12) {
+ unsigned zp = GetCodeByte (PC+2);
+
+ Indent (MCol);
+ Output ("%s", mnemonics[(opc >> 5) & 7]);
+
+ Indent (ACol);
+ Output ("[$%02X],z", zp);
+
+ /* Add the code stuff as comment */
+ LineComment (PC, 3);
+
+ /* End the line */
+ LineFeed ();
+ } else {
+ OH_Implicit (D);
+ }
+}
+
+
+
+void OH_Implicit_42_45GS02 (const OpcDesc* D)
+/* handle disassembling NEG NEG prefixed opcodes, $42 42 ($ea) $xx */
+{
+ /* Get bytes after NEG */
+ unsigned n1 = GetCodeByte (PC+1);
+ unsigned opc = GetCodeByte (PC+2);
+ /* NEG:NEG:NOP (42 42 ea) prefix */
+ static const char *mnemonics[8] = {
+ "orq", "andq", "eorq", "adcq", "stq", "ldq", "cmpq", "sbcq"
+ };
+
+ if (n1 == 0x42) {
+ /* detected 0x42 0x42 */
+ if (opc == 0xea) {
+ /* detected 0x42 0x42 0xea */
+ unsigned opc = GetCodeByte (PC+3);
+ if ((opc & 0x1f) == 0x12) {
+ unsigned zp = GetCodeByte (PC+4);
+
+ Indent (MCol);
+ Output ("%s", mnemonics[(opc >> 5) & 7]);
+
+ Indent (ACol);
+ Output ("[$%02X]", zp); /* with or without ,z ? */
+
+ /* Add the code stuff as comment */
+ LineComment (PC, 5);
+
+ /* End the line */
+ LineFeed ();
+ return;
+ }
+ } else {
+ /* use another table for these */
+ const OpcDesc* NewDesc = &OpcTable_45GS02_extended[opc];
+ NewDesc->Handler (NewDesc);
+ return;
+ }
+ }
+
+ /* no prefix detected */
+ OH_Implicit (D);
+}
+
+
+
void OH_Immediate (const OpcDesc* D)
{
OneLine (D, "#$%02X", GetCodeByte (PC+1));
@@ -276,6 +353,20 @@ void OH_Direct (const OpcDesc* D)
+void OH_Direct_Q (const OpcDesc* D)
+{
+ /* Get the operand */
+ unsigned Addr = GetCodeByte (PC+3);
+
+ /* Generate a label in pass 1 */
+ GenerateLabel (D->Flags, Addr);
+
+ /* Output the line */
+ OneLine (D, "%s", GetAddrArg (D->Flags, Addr));
+}
+
+
+
void OH_DirectX (const OpcDesc* D)
{
/* Get the operand */
@@ -290,6 +381,20 @@ void OH_DirectX (const OpcDesc* D)
+void OH_DirectX_Q (const OpcDesc* D)
+{
+ /* Get the operand */
+ unsigned Addr = GetCodeByte (PC+3);
+
+ /* Generate a label in pass 1 */
+ GenerateLabel (D->Flags, Addr);
+
+ /* Output the line */
+ OneLine (D, "%s,x", GetAddrArg (D->Flags, Addr));
+}
+
+
+
void OH_DirectY (const OpcDesc* D)
{
/* Get the operand */
@@ -318,6 +423,20 @@ void OH_Absolute (const OpcDesc* D)
+void OH_Absolute_Q (const OpcDesc* D)
+{
+ /* Get the operand */
+ unsigned Addr = GetCodeWord (PC+3);
+
+ /* Generate a label in pass 1 */
+ GenerateLabel (D->Flags, Addr);
+
+ /* Output the line */
+ OneLine (D, "%s%s", GetAbsOverride (D->Flags, Addr), GetAddrArg (D->Flags, Addr));
+}
+
+
+
void OH_AbsoluteX (const OpcDesc* D)
{
/* Get the operand */
@@ -332,6 +451,20 @@ void OH_AbsoluteX (const OpcDesc* D)
+void OH_AbsoluteX_Q (const OpcDesc* D)
+{
+ /* Get the operand */
+ unsigned Addr = GetCodeWord (PC+3);
+
+ /* Generate a label in pass 1 */
+ GenerateLabel (D->Flags, Addr);
+
+ /* Output the line */
+ OneLine (D, "%s%s,x", GetAbsOverride (D->Flags, Addr), GetAddrArg (D->Flags, Addr));
+}
+
+
+
void OH_AbsoluteY (const OpcDesc* D)
{
/* Get the operand */
@@ -472,6 +605,20 @@ void OH_DirectIndirectZ (const OpcDesc* D)
+void OH_DirectIndirectZ_Q (const OpcDesc* D)
+{
+ /* Get the operand */
+ unsigned Addr = GetCodeByte (PC+3);
+
+ /* Generate a label in pass 1 */
+ GenerateLabel (D->Flags, Addr);
+
+ /* Output the line */
+ OneLine (D, "(%s),z", GetAddrArg (D->Flags, Addr));
+}
+
+
+
void OH_DirectXIndirect (const OpcDesc* D)
{
/* Get the operand */
@@ -531,6 +678,8 @@ void OH_BitBranch (const OpcDesc* D)
xfree (BranchLabel);
}
+
+
void OH_BitBranch_m740 (const OpcDesc* D)
/* zp, rel
** NOTE: currently is part of the instruction
diff --git a/src/da65/handler.h b/src/da65/handler.h
index fb0c40200..fc82595c6 100644
--- a/src/da65/handler.h
+++ b/src/da65/handler.h
@@ -103,6 +103,15 @@ void OH_AccumulatorBitBranch (const OpcDesc*);
void OH_JmpDirectIndirect (const OpcDesc* D);
void OH_SpecialPage (const OpcDesc*);
+/* 45GS02 */
+void OH_Direct_Q (const OpcDesc*);
+void OH_DirectIndirectZ_Q (const OpcDesc* D);
+void OH_Absolute_Q (const OpcDesc* D);
+void OH_AbsoluteX_Q (const OpcDesc* D);
+void OH_DirectX_Q (const OpcDesc* D);
+void OH_Implicit_ea_45GS02 (const OpcDesc* D);
+void OH_Implicit_42_45GS02 (const OpcDesc* D);
+
/* Handlers for special instructions */
void OH_Rts (const OpcDesc*);
void OH_JmpAbsolute (const OpcDesc*);
diff --git a/src/da65/main.c b/src/da65/main.c
index 67a01dc3b..545cc657b 100644
--- a/src/da65/main.c
+++ b/src/da65/main.c
@@ -59,6 +59,7 @@
#include "infofile.h"
#include "labels.h"
#include "opctable.h"
+#include "opc45GS02.h"
#include "output.h"
#include "scanner.h"
#include "segment.h"
@@ -360,6 +361,51 @@ static void OptVersion (const char* Opt attribute ((unused)),
+static unsigned HandleChangedLength(const OpcDesc* D, unsigned PC)
+/* Instructions that have flSizeChanges set may use a different size than what
+** the table says. This function adjusts the PC accordingly, so after this only
+** the size from the table needs to be added to make up for the correct value
+*/
+{
+ if (D->Flags & flSizeChanges) {
+ if (CPU == CPU_45GS02) {
+ if (D->Handler == OH_Implicit_42_45GS02) {
+ if (GetCodeByte (PC+1) == 0x42) {
+ /* NEG:NEG prefix (0x42 0x42) */
+ unsigned opc = GetCodeByte (PC+2);
+ if (opc == 0xea) {
+ /* 42 42 ea */
+ if ((GetCodeByte (PC+3) & 0x1f) == 0x12) {
+ PC += 4;
+ }
+ } else {
+ /* 42 42 xx */
+ const OpcDesc* ED = &OpcTable_45GS02_extended[opc];
+ if (ED->Handler != OH_Illegal) {
+ PC += (ED->Size - 1);
+ }
+ }
+ }
+ } else if (D->Handler == OH_Implicit_ea_45GS02) {
+ /* NOP prefix (0xea) */
+ if ((GetCodeByte (PC+1) & 0x1f) == 0x12) {
+ PC += 2;
+ }
+ }
+ } else if (CPU == CPU_65816) {
+ if ((D->Handler == OH_Immediate65816M &&
+ GetAttr (PC) & atMem16) ||
+ (D->Handler == OH_Immediate65816X &&
+ GetAttr (PC) & atIdx16)) {
+ PC++;
+ }
+ }
+ }
+ return PC;
+}
+
+
+
static void OneOpcode (unsigned RemainingBytes)
/* Disassemble one opcode */
{
@@ -435,6 +481,7 @@ static void OneOpcode (unsigned RemainingBytes)
++PC;
} else {
D->Handler (D);
+ PC = HandleChangedLength (D, PC);
PC += D->Size;
}
break;
@@ -466,14 +513,8 @@ static void OneOpcode (unsigned RemainingBytes)
}
/* Output the insn */
D->Handler (D);
- if (CPU == CPU_65816 && (D->Flags & flSizeChanges)) {
- if ((D->Handler == OH_Immediate65816M &&
- GetAttr (PC) & atMem16) ||
- (D->Handler == OH_Immediate65816X &&
- GetAttr (PC) & atIdx16)) {
- PC++;
- }
- }
+
+ PC = HandleChangedLength (D, PC);
PC += D->Size;
break;
}
diff --git a/src/da65/opc45GS02.c b/src/da65/opc45GS02.c
new file mode 100644
index 000000000..21650f53d
--- /dev/null
+++ b/src/da65/opc45GS02.c
@@ -0,0 +1,565 @@
+/*****************************************************************************/
+/* */
+/* opc45GS02.c */
+/* */
+/* 45GS10 opcode description table */
+/* */
+/* */
+/* */
+/* (C) 2003-2011, Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
+/* */
+/* */
+/* This software is provided 'as-is', without any expressed or implied */
+/* warranty. In no event will the authors be held liable for any damages */
+/* arising from the use of this software. */
+/* */
+/* Permission is granted to anyone to use this software for any purpose, */
+/* including commercial applications, and to alter it and redistribute it */
+/* freely, subject to the following restrictions: */
+/* */
+/* 1. The origin of this software must not be misrepresented; you must not */
+/* claim that you wrote the original software. If you use this software */
+/* in a product, an acknowledgment in the product documentation would be */
+/* appreciated but is not required. */
+/* 2. Altered source versions must be plainly marked as such, and must not */
+/* be misrepresented as being the original software. */
+/* 3. This notice may not be removed or altered from any source */
+/* distribution. */
+/* */
+/*****************************************************************************/
+
+
+
+/* da65 */
+#include "handler.h"
+#include "opc45GS02.h"
+
+
+
+/*****************************************************************************/
+/* Data */
+/*****************************************************************************/
+
+
+
+/* Descriptions for all compound instructions with NEG:NEG prefix (0x42 0x42) */
+const OpcDesc OpcTable_45GS02_extended[256] = {
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $00 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $01 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $02 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $03 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $04 */
+ { "orq", 2+2, flUseLabel, OH_Direct_Q }, /* $05 */
+ { "aslq", 2+2, flUseLabel, OH_Direct_Q }, /* $06 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $07 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $08 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $09 */
+ { "aslq", 1+2, flNone, OH_Accumulator }, /* $0a */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $0b */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $0c */
+ { "orq", 3+2, flUseLabel|flAbsOverride, OH_Absolute_Q }, /* $0d */
+ { "aslq", 3+2, flUseLabel, OH_Absolute_Q }, /* $0e */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $0f */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $10 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $11 */
+ { "orq", 2+2, flUseLabel, OH_DirectIndirectZ_Q }, /* $12 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $13 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $14 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $15 */
+ { "aslq", 2+2, flUseLabel, OH_DirectX_Q }, /* $16 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $17 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $18 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $19 */
+ { "inq", 1+2, flNone, OH_Accumulator }, /* $1a */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $1b */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $1c */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $1d */
+ { "aslq", 3+2, flUseLabel|flAbsOverride, OH_AbsoluteX_Q }, /* $1e */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $1f */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $20 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $21 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $22 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $23 */
+ { "bitq", 2+2, flUseLabel, OH_Direct_Q }, /* $24 */
+ { "andq", 2+2, flUseLabel, OH_Direct_Q }, /* $25 */
+ { "rolq", 2+2, flUseLabel, OH_Direct_Q }, /* $26 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $27 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $28 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $29 */
+ { "rolq", 1+2, flNone, OH_Accumulator }, /* $2a */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $2b */
+ { "bitq", 3+2, flUseLabel|flAbsOverride, OH_Absolute_Q }, /* $2c */
+ { "andq", 3+2, flUseLabel|flAbsOverride, OH_Absolute_Q }, /* $2d */
+ { "rolq", 3+2, flUseLabel|flAbsOverride, OH_Absolute_Q }, /* $2e */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $2f */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $30 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $31 */
+ { "andq", 2+2, flUseLabel, OH_DirectIndirectZ_Q }, /* $32 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $33 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $34 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $35 */
+ { "rolq", 2+2, flUseLabel, OH_DirectX_Q }, /* $36 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $37 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $38 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $39 */
+ { "deq", 1+2, flNone, OH_Accumulator }, /* $3a */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $3b */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $3c */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $3d */
+ { "rolq", 3+2, flUseLabel|flAbsOverride, OH_AbsoluteX_Q }, /* $3e */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $3f */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $40 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $41 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $42 */
+ { "asrq", 1+2, flNone, OH_Accumulator }, /* $43 */
+ { "asrq", 2+2, flUseLabel, OH_Direct_Q }, /* $44 */
+ { "eorq", 2+2, flUseLabel, OH_Direct_Q }, /* $45 */
+ { "lsrq", 2+2, flUseLabel, OH_Direct_Q }, /* $46 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $47 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $48 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $49 */
+ { "lsrq", 1+2, flNone, OH_Accumulator }, /* $4a */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $4b */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $4c */
+ { "eorq", 3+2, flUseLabel|flAbsOverride, OH_Absolute_Q }, /* $4d */
+ { "lsrq", 3+2, flUseLabel|flAbsOverride, OH_Absolute_Q }, /* $4e */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $4f */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $50 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $51 */
+ { "eorq", 2+2, flUseLabel, OH_DirectIndirectZ_Q }, /* $52 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $53 */
+ { "asrq", 2+2, flUseLabel, OH_DirectX_Q }, /* $54 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $55 */
+ { "lsrq", 2+2, flUseLabel, OH_DirectX_Q }, /* $56 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $57 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $58 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $59 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $5a */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $5b */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $5c */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $5d */
+ { "lsrq", 3+2, flUseLabel|flAbsOverride, OH_AbsoluteX_Q }, /* $5e */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $5f */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $60 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $61 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $62 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $63 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $64 */
+ { "adcq", 2+2, flUseLabel, OH_Direct_Q }, /* $65 */
+ { "rorq", 2+2, flUseLabel, OH_Direct_Q }, /* $66 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $67 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $68 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $69 */
+ { "rorq", 1+2, flNone, OH_Accumulator }, /* $6a */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $6b */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $6c */
+ { "adcq", 3+2, flUseLabel|flAbsOverride, OH_Absolute_Q }, /* $6d */
+ { "rorq", 3+2, flUseLabel, OH_Absolute_Q }, /* $6e */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $6f */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $70 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $71 */
+ { "adcq", 2+2, flUseLabel, OH_DirectIndirectZ_Q }, /* $72 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $73 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $74 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $75 */
+ { "rorq", 2+2, flUseLabel, OH_DirectX_Q }, /* $76 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $77 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $78 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $79 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $7a */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $7b */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $7c */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $7d */
+ { "rorq", 3+2, flUseLabel|flAbsOverride, OH_AbsoluteX_Q }, /* $7e */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $7f */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $80 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $81 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $82 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $83 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $84 */
+ { "stq", 2+2, flUseLabel, OH_Direct_Q }, /* $85 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $86 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $87 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $88 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $89 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $8a */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $8b */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $8c */
+ { "stq", 3+2, flUseLabel|flAbsOverride, OH_Absolute_Q }, /* $8d */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $8e */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $8f */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $90 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $91 */
+ { "stq", 2+2, flUseLabel, OH_DirectIndirectZ_Q }, /* $92 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $93 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $94 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $95 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $96 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $97 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $98 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $99 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $9a */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $9b */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $9c */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $9d */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $9e */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $9f */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $a0 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $a1 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $a2 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $a3 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $a4 */
+ { "ldq", 2+2, flUseLabel, OH_Direct_Q }, /* $a5 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $a6 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $a7 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $a8 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $a9 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $aa */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $ab */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $ac */
+ { "ldq", 3+2, flUseLabel|flAbsOverride, OH_Absolute_Q }, /* $ad */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $ae */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $af */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $b0 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $b1 */
+ { "ldq", 2+2, flUseLabel, OH_DirectIndirectZ_Q }, /* $b2 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $b3 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $b4 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $b5 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $b6 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $b7 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $b8 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $b9 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $ba */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $bb */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $bc */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $bd */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $be */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $bf */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $c0 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $c1 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $c2 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $c3 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $c4 */
+ { "cmpq", 2+2, flUseLabel, OH_Direct_Q }, /* $c5 */
+ { "deq", 2+2, flUseLabel, OH_Direct_Q }, /* $c6 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $c7 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $c8 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $c9 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $ca */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $cb */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $cc */
+ { "cmpq", 3+2, flUseLabel|flAbsOverride, OH_Absolute_Q }, /* $cd */
+ { "deq", 3+2, flUseLabel|flAbsOverride, OH_Absolute_Q }, /* $ce */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $cf */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $d0 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $d1 */
+ { "cmpq", 2+2, flUseLabel, OH_DirectIndirectZ_Q }, /* $d2 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $d3 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $d4 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $d5 */
+ { "deq", 2+2, flUseLabel, OH_DirectX_Q }, /* $d6 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $d7 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $d8 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $d9 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $da */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $db */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $dc */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $dd */
+ { "deq", 3+2, flUseLabel|flAbsOverride, OH_AbsoluteX_Q }, /* $de */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $df */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $e0 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $e1 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $e2 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $e3 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $e4 */
+ { "sbcq", 2+2, flUseLabel, OH_Direct_Q }, /* $e5 */
+ { "inq", 2+2, flUseLabel, OH_Direct_Q }, /* $e6 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $e7 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $e8 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $e9 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $ea */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $eb */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $ec */
+ { "sbcq", 3+2, flUseLabel|flAbsOverride, OH_Absolute_Q }, /* $ed */
+ { "inq", 3+2, flUseLabel|flAbsOverride, OH_Absolute_Q }, /* $ee */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $ef */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $f0 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $f1 */
+ { "sbcq", 2+2, flUseLabel, OH_DirectIndirectZ_Q }, /* $f2 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $f3 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $f4 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $f5 */
+ { "inq", 2+2, flUseLabel, OH_DirectX_Q }, /* $f6 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $f7 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $f8 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $f9 */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $fa */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $fb */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $fc */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $fd */
+ { "inq", 3+2, flUseLabel|flAbsOverride, OH_AbsoluteX_Q }, /* $fe */
+ { "", 1+2, flIllegal, OH_Illegal, }, /* $ff */
+};
+
+const OpcDesc OpcTable_45GS02[256] = {
+ { "brk", 1, flNone, OH_Implicit }, /* $00 */
+ { "ora", 2, flUseLabel, OH_DirectXIndirect }, /* $01 */
+ { "cle", 1, flNone, OH_Implicit }, /* $02 */
+ { "see", 1, flNone, OH_Implicit }, /* $03 */
+ { "tsb", 2, flUseLabel, OH_Direct }, /* $04 */
+ { "ora", 2, flUseLabel, OH_Direct }, /* $05 */
+ { "asl", 2, flUseLabel, OH_Direct }, /* $06 */
+ { "rmb0", 2, flUseLabel, OH_Direct }, /* $07 */
+ { "php", 1, flNone, OH_Implicit }, /* $08 */
+ { "ora", 2, flNone, OH_Immediate }, /* $09 */
+ { "asl", 1, flNone, OH_Accumulator }, /* $0a */
+ { "tsy", 1, flNone, OH_Implicit }, /* $0b */
+ { "tsb", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $0c */
+ { "ora", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $0d */
+ { "asl", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $0e */
+ { "bbr0", 3, flUseLabel, OH_BitBranch }, /* $0f */
+ { "bpl", 2, flLabel, OH_Relative }, /* $10 */
+ { "ora", 2, flUseLabel, OH_DirectIndirectY }, /* $11 */
+ { "ora", 2, flUseLabel, OH_DirectIndirectZ }, /* $12 */
+ { "lbpl", 3, flLabel, OH_RelativeLong4510 }, /* $13 */
+ { "trb", 2, flUseLabel, OH_Direct }, /* $14 */
+ { "ora", 2, flUseLabel, OH_DirectX }, /* $15 */
+ { "asl", 2, flUseLabel, OH_DirectX }, /* $16 */
+ { "rmb1", 2, flUseLabel, OH_Direct }, /* $17 */
+ { "clc", 1, flNone, OH_Implicit }, /* $18 */
+ { "ora", 3, flUseLabel, OH_AbsoluteY }, /* $19 */
+ { "inc", 1, flNone, OH_Accumulator }, /* $1a */
+ { "inz", 1, flNone, OH_Implicit }, /* $1b */
+ { "trb", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $1c */
+ { "ora", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $1d */
+ { "asl", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $1e */
+ { "bbr1", 3, flUseLabel, OH_BitBranch }, /* $1f */
+ { "jsr", 3, flLabel, OH_Absolute }, /* $20 */
+ { "and", 2, flUseLabel, OH_DirectXIndirect }, /* $21 */
+ { "jsr", 3, flLabel, OH_JmpAbsoluteIndirect }, /* $22 */
+ { "jsr", 3, flLabel, OH_JmpAbsoluteXIndirect }, /* $23 */
+ { "bit", 2, flUseLabel, OH_Direct }, /* $24 */
+ { "and", 2, flUseLabel, OH_Direct }, /* $25 */
+ { "rol", 2, flUseLabel, OH_Direct }, /* $26 */
+ { "rmb2", 2, flUseLabel, OH_Direct }, /* $27 */
+ { "plp", 1, flNone, OH_Implicit }, /* $28 */
+ { "and", 2, flNone, OH_Immediate }, /* $29 */
+ { "rol", 1, flNone, OH_Accumulator }, /* $2a */
+ { "tys", 1, flNone, OH_Implicit }, /* $2b */
+ { "bit", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $2c */
+ { "and", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $2d */
+ { "rol", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $2e */
+ { "bbr2", 3, flUseLabel, OH_BitBranch }, /* $2f */
+ { "bmi", 2, flLabel, OH_Relative }, /* $30 */
+ { "and", 2, flUseLabel, OH_DirectIndirectY }, /* $31 */
+ { "and", 2, flUseLabel, OH_DirectIndirectZ }, /* $32 */
+ { "lbmi", 3, flLabel, OH_RelativeLong4510 }, /* $33 */
+ { "bit", 2, flUseLabel, OH_DirectX }, /* $34 */
+ { "and", 2, flUseLabel, OH_DirectX }, /* $35 */
+ { "rol", 2, flUseLabel, OH_DirectX }, /* $36 */
+ { "rmb3", 2, flUseLabel, OH_Direct }, /* $37 */
+ { "sec", 1, flNone, OH_Implicit }, /* $38 */
+ { "and", 3, flUseLabel, OH_AbsoluteY }, /* $39 */
+ { "dec", 1, flNone, OH_Accumulator }, /* $3a */
+ { "dez", 1, flNone, OH_Implicit }, /* $3b */
+ { "bit", 3, flUseLabel, OH_AbsoluteX }, /* $3c */
+ { "and", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $3d */
+ { "rol", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $3e */
+ { "bbr3", 3, flUseLabel, OH_BitBranch }, /* $3f */
+ { "rti", 1, flNone, OH_Rts }, /* $40 */
+ { "eor", 2, flUseLabel, OH_DirectXIndirect }, /* $41 */
+ { "neg", 1, flSizeChanges, OH_Implicit_42_45GS02 }, /* $42 */
+ { "asr", 1, flNone, OH_Accumulator }, /* $43 */
+ { "asr", 2, flUseLabel, OH_Direct }, /* $44 */
+ { "eor", 2, flUseLabel, OH_Direct }, /* $45 */
+ { "lsr", 2, flUseLabel, OH_Direct }, /* $46 */
+ { "rmb4", 2, flUseLabel, OH_Direct }, /* $47 */
+ { "pha", 1, flNone, OH_Implicit }, /* $48 */
+ { "eor", 2, flNone, OH_Immediate }, /* $49 */
+ { "lsr", 1, flNone, OH_Accumulator }, /* $4a */
+ { "taz", 1, flNone, OH_Implicit }, /* $4b */
+ { "jmp", 3, flLabel, OH_JmpAbsolute }, /* $4c */
+ { "eor", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $4d */
+ { "lsr", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $4e */
+ { "bbr4", 3, flUseLabel, OH_BitBranch }, /* $4f */
+ { "bvc", 2, flLabel, OH_Relative }, /* $50 */
+ { "eor", 2, flUseLabel, OH_DirectIndirectY }, /* $51 */
+ { "eor", 2, flUseLabel, OH_DirectIndirectZ }, /* $52 */
+ { "lbvc", 3, flLabel, OH_RelativeLong4510 }, /* $53 */
+ { "asr", 2, flUseLabel, OH_DirectX }, /* $54 */
+ { "eor", 2, flUseLabel, OH_DirectX }, /* $55 */
+ { "lsr", 2, flUseLabel, OH_DirectX }, /* $56 */
+ { "rmb5", 2, flUseLabel, OH_Direct }, /* $57 */
+ { "cli", 1, flNone, OH_Implicit }, /* $58 */
+ { "eor", 3, flUseLabel, OH_AbsoluteY }, /* $59 */
+ { "phy", 1, flNone, OH_Implicit }, /* $5a */
+ { "tab", 1, flNone, OH_Implicit }, /* $5b */
+ { "map", 1, flNone, OH_Implicit }, /* $5c */
+ { "eor", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $5d */
+ { "lsr", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $5e */
+ { "bbr5", 3, flUseLabel, OH_BitBranch }, /* $5f */
+ { "rts", 1, flNone, OH_Rts }, /* $60 */
+ { "adc", 2, flUseLabel, OH_DirectXIndirect }, /* $61 */
+ { "rtn", 2, flNone, OH_Immediate }, /* $62 */
+ { "bsr", 3, flLabel, OH_RelativeLong4510 }, /* $63 */
+ { "stz", 2, flUseLabel, OH_Direct }, /* $64 */
+ { "adc", 2, flUseLabel, OH_Direct }, /* $65 */
+ { "ror", 2, flUseLabel, OH_Direct }, /* $66 */
+ { "rmb6", 2, flUseLabel, OH_Direct, }, /* $67 */
+ { "pla", 1, flNone, OH_Implicit }, /* $68 */
+ { "adc", 2, flNone, OH_Immediate }, /* $69 */
+ { "ror", 1, flNone, OH_Accumulator }, /* $6a */
+ { "tza", 1, flNone, OH_Implicit }, /* $6b */
+ { "jmp", 3, flLabel, OH_JmpAbsoluteIndirect }, /* $6c */
+ { "adc", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $6d */
+ { "ror", 3, flUseLabel, OH_Absolute }, /* $6e */
+ { "bbr6", 3, flUseLabel, OH_BitBranch }, /* $6f */
+ { "bvs", 2, flLabel, OH_Relative }, /* $70 */
+ { "adc", 2, flUseLabel, OH_DirectIndirectY }, /* $71 */
+ { "adc", 2, flUseLabel, OH_DirectIndirectZ }, /* $72 */
+ { "lbvs", 3, flLabel, OH_RelativeLong4510 }, /* $73 */
+ { "stz", 2, flUseLabel, OH_DirectX }, /* $74 */
+ { "adc", 2, flUseLabel, OH_DirectX }, /* $75 */
+ { "ror", 2, flUseLabel, OH_DirectX }, /* $76 */
+ { "rmb7", 2, flUseLabel, OH_Direct }, /* $77 */
+ { "sei", 1, flNone, OH_Implicit }, /* $78 */
+ { "adc", 3, flUseLabel, OH_AbsoluteY }, /* $79 */
+ { "ply", 1, flNone, OH_Implicit }, /* $7a */
+ { "tba", 1, flNone, OH_Implicit }, /* $7b */
+ { "jmp", 3, flLabel, OH_AbsoluteXIndirect }, /* $7c */
+ { "adc", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $7d */
+ { "ror", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $7e */
+ { "bbr7", 3, flUseLabel, OH_BitBranch }, /* $7f */
+ { "bra", 2, flLabel, OH_Relative }, /* $80 */
+ { "sta", 2, flUseLabel, OH_DirectXIndirect }, /* $81 */
+ { "sta", 2, flNone, OH_StackRelativeIndirectY4510}, /* $82 */
+ { "lbra", 3, flLabel, OH_RelativeLong4510 }, /* $83 */
+ { "sty", 2, flUseLabel, OH_Direct }, /* $84 */
+ { "sta", 2, flUseLabel, OH_Direct }, /* $85 */
+ { "stx", 2, flUseLabel, OH_Direct }, /* $86 */
+ { "smb0", 2, flUseLabel, OH_Direct }, /* $87 */
+ { "dey", 1, flNone, OH_Implicit }, /* $88 */
+ { "bit", 2, flNone, OH_Immediate }, /* $89 */
+ { "txa", 1, flNone, OH_Implicit }, /* $8a */
+ { "sty", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $8b */
+ { "sty", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $8c */
+ { "sta", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $8d */
+ { "stx", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $8e */
+ { "bbs0", 3, flUseLabel, OH_BitBranch }, /* $8f */
+ { "bcc", 2, flLabel, OH_Relative }, /* $90 */
+ { "sta", 2, flUseLabel, OH_DirectIndirectY }, /* $91 */
+ { "sta", 2, flUseLabel, OH_DirectIndirectZ }, /* $92 */
+ { "lbcc", 3, flLabel, OH_RelativeLong4510 }, /* $93 */
+ { "sty", 2, flUseLabel, OH_DirectX }, /* $94 */
+ { "sta", 2, flUseLabel, OH_DirectX }, /* $95 */
+ { "stx", 2, flUseLabel, OH_DirectY }, /* $96 */
+ { "smb1", 2, flUseLabel, OH_Direct }, /* $97 */
+ { "tya", 1, flNone, OH_Implicit }, /* $98 */
+ { "sta", 3, flUseLabel, OH_AbsoluteY }, /* $99 */
+ { "txs", 1, flNone, OH_Implicit }, /* $9a */
+ { "stx", 3, flUseLabel|flAbsOverride, OH_AbsoluteY }, /* $9b */
+ { "stz", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $9c */
+ { "sta", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $9d */
+ { "stz", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $9e */
+ { "bbs1", 3, flUseLabel, OH_BitBranch }, /* $9f */
+ { "ldy", 2, flNone, OH_Immediate }, /* $a0 */
+ { "lda", 2, flUseLabel, OH_DirectXIndirect }, /* $a1 */
+ { "ldx", 2, flNone, OH_Immediate }, /* $a2 */
+ { "ldz", 2, flNone, OH_Immediate }, /* $a3 */
+ { "ldy", 2, flUseLabel, OH_Direct }, /* $a4 */
+ { "lda", 2, flUseLabel, OH_Direct }, /* $a5 */
+ { "ldx", 2, flUseLabel, OH_Direct }, /* $a6 */
+ { "smb2", 2, flUseLabel, OH_Direct }, /* $a7 */
+ { "tay", 1, flNone, OH_Implicit }, /* $a8 */
+ { "lda", 2, flNone, OH_Immediate }, /* $a9 */
+ { "tax", 1, flNone, OH_Implicit }, /* $aa */
+ { "ldz", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ab */
+ { "ldy", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ac */
+ { "lda", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ad */
+ { "ldx", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ae */
+ { "bbs2", 3, flUseLabel, OH_BitBranch }, /* $af */
+ { "bcs", 2, flLabel, OH_Relative }, /* $b0 */
+ { "lda", 2, flUseLabel, OH_DirectIndirectY }, /* $b1 */
+ { "lda", 2, flUseLabel, OH_DirectIndirectZ }, /* $b2 */
+ { "lbcs", 3, flLabel, OH_RelativeLong4510 }, /* $b3 */
+ { "ldy", 2, flUseLabel, OH_DirectX }, /* $b4 */
+ { "lda", 2, flUseLabel, OH_DirectX }, /* $b5 */
+ { "ldx", 2, flUseLabel, OH_DirectY }, /* $b6 */
+ { "smb3", 2, flUseLabel, OH_Direct }, /* $b7 */
+ { "clv", 1, flNone, OH_Implicit }, /* $b8 */
+ { "lda", 3, flUseLabel, OH_AbsoluteY }, /* $b9 */
+ { "tsx", 1, flNone, OH_Implicit }, /* $ba */
+ { "ldz", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $bb */
+ { "ldy", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $bc */
+ { "lda", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $bd */
+ { "ldx", 3, flUseLabel|flAbsOverride, OH_AbsoluteY }, /* $be */
+ { "bbs3", 3, flUseLabel, OH_BitBranch }, /* $bf */
+ { "cpy", 2, flNone, OH_Immediate }, /* $c0 */
+ { "cmp", 2, flUseLabel, OH_DirectXIndirect }, /* $c1 */
+ { "cpz", 2, flNone, OH_Immediate }, /* $c2 */
+ { "dew", 2, flUseLabel, OH_Direct }, /* $c3 */
+ { "cpy", 2, flUseLabel, OH_Direct }, /* $c4 */
+ { "cmp", 2, flUseLabel, OH_Direct }, /* $c5 */
+ { "dec", 2, flUseLabel, OH_Direct }, /* $c6 */
+ { "smb4", 2, flUseLabel, OH_Direct }, /* $c7 */
+ { "iny", 1, flNone, OH_Implicit }, /* $c8 */
+ { "cmp", 2, flNone, OH_Immediate }, /* $c9 */
+ { "dex", 1, flNone, OH_Implicit }, /* $ca */
+ { "asw", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $cb */
+ { "cpy", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $cc */
+ { "cmp", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $cd */
+ { "dec", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ce */
+ { "bbs4", 3, flUseLabel, OH_BitBranch }, /* $cf */
+ { "bne", 2, flLabel, OH_Relative }, /* $d0 */
+ { "cmp", 2, flUseLabel, OH_DirectIndirectY }, /* $d1 */
+ { "cmp", 2, flUseLabel, OH_DirectIndirectZ }, /* $d2 */
+ { "lbne", 3, flLabel, OH_RelativeLong4510 }, /* $d3 */
+ { "cpz", 2, flUseLabel, OH_Direct }, /* $d4 */
+ { "cmp", 2, flUseLabel, OH_DirectX }, /* $d5 */
+ { "dec", 2, flUseLabel, OH_DirectX }, /* $d6 */
+ { "smb5", 2, flUseLabel, OH_Direct }, /* $d7 */
+ { "cld", 1, flNone, OH_Implicit }, /* $d8 */
+ { "cmp", 3, flUseLabel, OH_AbsoluteY }, /* $d9 */
+ { "phx", 1, flNone, OH_Implicit }, /* $da */
+ { "phz", 1, flNone, OH_Implicit }, /* $db */
+ { "cpz", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $dc */
+ { "cmp", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $dd */
+ { "dec", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $de */
+ { "bbs5", 3, flUseLabel, OH_BitBranch }, /* $df */
+ { "cpx", 2, flNone, OH_Immediate }, /* $e0 */
+ { "sbc", 2, flUseLabel, OH_DirectXIndirect }, /* $e1 */
+ { "lda", 2, flNone, OH_StackRelativeIndirectY4510}, /* $e2 */
+ { "inw", 2, flUseLabel, OH_Direct }, /* $e3 */
+ { "cpx", 2, flUseLabel, OH_Direct }, /* $e4 */
+ { "sbc", 2, flUseLabel, OH_Direct }, /* $e5 */
+ { "inc", 2, flUseLabel, OH_Direct }, /* $e6 */
+ { "smb6", 2, flUseLabel, OH_Direct }, /* $e7 */
+ { "inx", 1, flNone, OH_Implicit }, /* $e8 */
+ { "sbc", 2, flNone, OH_Immediate }, /* $e9 */
+ { "eom", 1, flSizeChanges, OH_Implicit_ea_45GS02 }, /* $ea */
+ { "row", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $eb */
+ { "cpx", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ec */
+ { "sbc", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ed */
+ { "inc", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ee */
+ { "bbs6", 3, flUseLabel, OH_BitBranch }, /* $ef */
+ { "beq", 2, flLabel, OH_Relative }, /* $f0 */
+ { "sbc", 2, flUseLabel, OH_DirectIndirectY }, /* $f1 */
+ { "sbc", 2, flUseLabel, OH_DirectIndirectZ }, /* $f2 */
+ { "lbeq", 3, flLabel, OH_RelativeLong4510 }, /* $f3 */
+ { "phw", 3, flNone, OH_ImmediateWord }, /* $f4 */
+ { "sbc", 2, flUseLabel, OH_DirectX }, /* $f5 */
+ { "inc", 2, flUseLabel, OH_DirectX }, /* $f6 */
+ { "smb7", 2, flUseLabel, OH_Direct }, /* $f7 */
+ { "sed", 1, flNone, OH_Implicit }, /* $f8 */
+ { "sbc", 3, flUseLabel, OH_AbsoluteY }, /* $f9 */
+ { "plx", 1, flNone, OH_Implicit }, /* $fa */
+ { "plz", 1, flNone, OH_Implicit }, /* $fb */
+ { "phw", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $fc */
+ { "sbc", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $fd */
+ { "inc", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $fe */
+ { "bbs7", 3, flUseLabel, OH_BitBranch }, /* $ff */
+};
diff --git a/src/da65/opc45GS02.h b/src/da65/opc45GS02.h
new file mode 100644
index 000000000..624e4bbd9
--- /dev/null
+++ b/src/da65/opc45GS02.h
@@ -0,0 +1,58 @@
+/*****************************************************************************/
+/* */
+/* opc45GS02.h */
+/* */
+/* 45GS10 opcode description table */
+/* */
+/* */
+/* */
+/* (C) 2003 Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
+/* */
+/* */
+/* This software is provided 'as-is', without any expressed or implied */
+/* warranty. In no event will the authors be held liable for any damages */
+/* arising from the use of this software. */
+/* */
+/* Permission is granted to anyone to use this software for any purpose, */
+/* including commercial applications, and to alter it and redistribute it */
+/* freely, subject to the following restrictions: */
+/* */
+/* 1. The origin of this software must not be misrepresented; you must not */
+/* claim that you wrote the original software. If you use this software */
+/* in a product, an acknowledgment in the product documentation would be */
+/* appreciated but is not required. */
+/* 2. Altered source versions must be plainly marked as such, and must not */
+/* be misrepresented as being the original software. */
+/* 3. This notice may not be removed or altered from any source */
+/* distribution. */
+/* */
+/*****************************************************************************/
+
+
+
+#ifndef OPC45GS02_H
+#define OPC45GS02_H
+
+
+
+#include "opcdesc.h"
+
+
+
+/*****************************************************************************/
+/* Data */
+/*****************************************************************************/
+
+
+
+/* Descriptions for all opcodes */
+extern const OpcDesc OpcTable_45GS02[256];
+extern const OpcDesc OpcTable_45GS02_extended[256];
+
+
+/* End of opc45GS02.h */
+
+#endif
diff --git a/src/da65/opctable.c b/src/da65/opctable.c
index d9068d253..445f8880c 100644
--- a/src/da65/opctable.c
+++ b/src/da65/opctable.c
@@ -36,6 +36,7 @@
/* da65 */
#include "error.h"
#include "opc4510.h"
+#include "opc45GS02.h"
#include "opc6502.h"
#include "opc6502x.h"
#include "opc6502dtv.h"
@@ -78,6 +79,7 @@ void SetOpcTable (cpu_t CPU)
case CPU_HUC6280: OpcTable = OpcTable_HuC6280; break;
case CPU_M740: OpcTable = OpcTable_M740; break;
case CPU_4510: OpcTable = OpcTable_4510; break;
+ case CPU_45GS02: OpcTable = OpcTable_45GS02; break;
default: Error ("Unsupported CPU");
}
}
diff --git a/test/asm/cpudetect/45GS02-cpudetect.ref b/test/asm/cpudetect/45GS02-cpudetect.ref
new file mode 100644
index 000000000..e9aa843cd
Binary files /dev/null and b/test/asm/cpudetect/45GS02-cpudetect.ref differ
diff --git a/test/asm/cpudetect/allinst.inc b/test/asm/cpudetect/allinst.inc
index ab266915e..8e27a5429 100644
--- a/test/asm/cpudetect/allinst.inc
+++ b/test/asm/cpudetect/allinst.inc
@@ -636,7 +636,7 @@ LABEL3:
.endif
-; The 4502 is a superset of the 65CE02. Opcode 5c (originally a "4-byte NOP
+; The 4510 is a superset of the 65CE02. Opcode 5c (originally a "4-byte NOP
; reserved for future expansion") has been changed to the "map" instruction,
; now using implied addressing.
;
@@ -651,14 +651,98 @@ LABEL3:
map ; $5c ("4-byte NOP reserved for future expansion" on 65CE02)
asw $1234 ; $cb (wai on W65C02)
phz ; $db (stp on W65C02)
+ eom ; $ea "end of mapping" - but really just a NOP
.endscope
.endif
-; TODO: MEGA65
-; The m65 instruction set extends the 4502 instruction set using prefix bytes.
-; Therefore, the "normal" opcode table is the same as for the 4502 cpu
+; The 45GS02 instruction set extends the 4510 instruction set using prefix bytes.
+; Therefore, the "normal" opcode table is the same as for the 4510 cpu
+
+.if (.cpu .bitand CPU_ISET_45GS02)
+ .scope
+
+ orq $12 ; $42 $42 $05
+ aslq $12 ; $42 $42 $06
+ aslq ; $42 $42 $0a
+ orq $1234 ; $42 $42 $0d
+ aslq $1234 ; $42 $42 $0e
+ orq ($12) ; $42 $42 $12
+ aslq $12,x ; $42 $42 $16
+ inq ; $42 $42 $1a
+ aslq $1234,x ; $42 $42 $1e
+ bitq $12 ; $42 $42 $24
+ andq $12 ; $42 $42 $25
+ rolq $12 ; $42 $42 $26
+ rolq ; $42 $42 $2a
+ bitq $1234 ; $42 $42 $2c
+ andq $1234 ; $42 $42 $2d
+ rolq $1234 ; $42 $42 $2e
+ andq ($12) ; $42 $42 $32
+ rolq $12, x ; $42 $42 $36
+ deq ; $42 $42 $3a
+ rolq $1234, x ; $42 $42 $3e
+ asrq ; $42 $42 $43
+ asrq $12 ; $42 $42 $44
+ eorq $12 ; $42 $42 $45
+ lsrq $12 ; $42 $42 $46
+ lsrq ; $42 $42 $4a
+ eorq $1234 ; $42 $42 $4d
+ lsrq $1234 ; $42 $42 $4e
+ eorq ($12) ; $42 $42 $52
+ asrq $12, x ; $42 $42 $54
+ lsrq $12, x ; $42 $42 $56
+ lsrq $1234, x ; $42 $42 $5e
+ adcq $12 ; $42 $42 $65
+ rorq $12 ; $42 $42 $66
+ rorq ; $42 $42 $6a
+ adcq $1234 ; $42 $42 $6d
+ rorq $1234 ; $42 $42 $6e
+ adcq ($12) ; $42 $42 $72
+ rorq $12, x ; $42 $42 $76
+ rorq $1234, x ; $42 $42 $7e
+ stq $12 ; $42 $42 $85
+ stq $1234 ; $42 $42 $8d
+ stq ($12) ; $42 $42 $92
+ ldq $12 ; $42 $42 $a5
+ ldq $1234 ; $42 $42 $ad
+ ldq ($12), z ; $42 $42 $b2
+ cmpq $12 ; $42 $42 $c5
+ deq $12 ; $42 $42 $c6
+ cmpq $1234 ; $42 $42 $cd
+ deq $1234 ; $42 $42 $ce
+ cmpq ($12) ; $42 $42 $d2
+ deq $12, x ; $42 $42 $d6
+ deq $1234, x ; $42 $42 $de
+ sbcq $12 ; $42 $42 $e5
+ inq $12 ; $42 $42 $e6
+ sbcq $1234 ; $42 $42 $ed
+ inq $1234 ; $42 $42 $ee
+ sbcq ($12) ; $42 $42 $f2
+ inq $12, x ; $42 $42 $f6
+ inq $1234, x ; $42 $42 $fe
+
+ ora [$12], z ; $ea $12
+ and [$12], z ; $ea $32
+ eor [$12], z ; $ea $52
+ adc [$12], z ; $ea $72
+ sta [$12], z ; $ea $92
+ lda [$12], z ; $ea $b2
+ cmp [$12], z ; $ea $d2
+ sbc [$12], z ; $ea $f2
+
+ orq [$12] ; $42 $42 $ea $12
+ andq [$12] ; $42 $42 $ea $32
+ eorq [$12] ; $42 $42 $ea $52
+ adcq [$12] ; $42 $42 $ea $72
+ stq [$12] ; $42 $42 $ea $92
+ ldq [$12], z ; $42 $42 $ea $b2
+ cmpq [$12] ; $42 $42 $ea $d2
+ sbcq [$12] ; $42 $42 $ea $f2
+
+ .endscope
+.endif
; The HUC6280 is a superset of the R65C02. It adds some other instructions:
diff --git a/test/asm/cpudetect/cpudetect.s b/test/asm/cpudetect/cpudetect.s
index a017e652d..545e2fa56 100644
--- a/test/asm/cpudetect/cpudetect.s
+++ b/test/asm/cpudetect/cpudetect.s
@@ -28,6 +28,10 @@
taz
.endif
+.ifp45GS02
+ orq $1234
+.endif
+
.ifpdtv
sac #$00
.endif
@@ -76,6 +80,10 @@
.byte 0,"CPU_ISET_4510"
.endif
+.if (.cpu .bitand CPU_ISET_45GS02)
+ .byte 0,"CPU_ISET_45GS02"
+.endif
+
.if (.cpu .bitand CPU_ISET_6502DTV)
.byte 0,"CPU_ISET_6502DTV"
.endif
@@ -98,5 +106,6 @@
.pc02
.p816
.p4510
+.p45GS02
.pdtv
.pm740
diff --git a/test/asm/opcodes/45GS02-opcodes.ref b/test/asm/opcodes/45GS02-opcodes.ref
new file mode 100644
index 000000000..a4a78d46c
Binary files /dev/null and b/test/asm/opcodes/45GS02-opcodes.ref differ
diff --git a/test/asm/opcodes/45GS02-opcodes.s b/test/asm/opcodes/45GS02-opcodes.s
new file mode 100644
index 000000000..6d42b80c4
--- /dev/null
+++ b/test/asm/opcodes/45GS02-opcodes.s
@@ -0,0 +1,377 @@
+.setcpu "45GS02"
+
+ brk
+ ora ($05,x)
+ cle
+ see
+ tsb $02
+ ora $02
+ asl $02
+ rmb0 $02
+ php
+ ora #$01
+ asl
+ tsy
+ tsb $1234
+ ora $1234
+ asl $1234
+ bbr0 $02,*+$34
+
+ bpl *+$32
+ ora ($06),y
+ ora ($07),z
+ lbpl *+$3133 ; bpl *+$3133
+ trb $02
+ ora $03,x
+ asl $03,x
+ rmb1 $02
+ clc
+ ora $1456,y
+ inc
+ inz
+ trb $1234
+ ora $1345,x
+ asl $1345,x
+ bbr1 $02,*+$34
+
+ jsr $1234
+ and ($05,x)
+ jsr ($2345)
+ jsr ($2456,x)
+ bit $02
+ and $02
+ rol $02
+ rmb2 $02
+ plp
+ and #$01
+ rol
+ tys
+ bit $1234
+ and $1234
+ rol $1234
+ bbr2 $02,*+$34
+
+ bmi *+$32
+ and ($06),y
+ and ($07),z
+ lbmi *+$3133 ; bmi *+$3133
+ bit $03,x
+ and $03,x
+ rol $03,x
+ rmb3 $02
+ sec
+ and $1456,y
+ dec
+ dez
+ bit $1345,x
+ and $1345,x
+ rol $1345,x
+ bbr3 $02,*+$34
+
+ rti
+ eor ($05,x)
+ neg
+ asr
+ asr $02
+ eor $02
+ lsr $02
+ rmb4 $02
+ pha
+ eor #$01
+ lsr
+ taz
+ jmp $1234
+ eor $1234
+ lsr $1234
+ bbr4 $02,*+$34
+
+ bvc *+$32
+ eor ($06),y
+ eor ($07),z
+ lbvc *+$3133 ; bvc *+$3133
+ asr $03,x
+ eor $03,x
+ lsr $03,x
+ rmb5 $02
+ cli
+ eor $1456,y
+ phy
+ tab
+ map
+ eor $1345,x
+ lsr $1345,x
+ bbr5 $02,*+$34
+
+ rts
+ adc ($05,x)
+ rtn #$09
+ bsr *+$3133
+ stz $02
+ adc $02
+ ror $02
+ rmb6 $02
+ pla
+ adc #$01
+ ror
+ tza
+ jmp ($2345)
+ adc $1234
+ ror $1234
+ bbr6 $02,*+$34
+
+ bvs *+$32
+ adc ($06),y
+ adc ($07),z
+ lbvs *+$3133 ; bvs *+$3133
+ stz $03,x
+ adc $03,x
+ ror $03,x
+ rmb7 $02
+ sei
+ adc $1456,y
+ ply
+ tba
+ jmp ($2456,x)
+ adc $1345,x
+ ror $1345,x
+ bbr7 $02,*+$34
+
+ bra *+$32
+ sta ($05,x)
+ sta ($0f,s),y
+ sta ($0f,sp),y
+ lbra *+$3133 ; bra *+$3133
+ sty $02
+ sta $02
+ stx $02
+ smb0 $02
+ dey
+ bit #$01
+ txa
+ sty $1345,x
+ sty $1234
+ sta $1234
+ stx $1234
+ bbs0 $02,*+$34
+
+ bcc *+$32
+ sta ($06),y
+ sta ($07),z
+ lbcc *+$3133 ; bcc *+$3133
+ sty $03,x
+ sta $03,x
+ stx $04,y
+ smb1 $02
+ tya
+ sta $1456,y
+ txs
+ stx $1456,y
+ stz $1234
+ sta $1345,x
+ stz $1345,x
+ bbs1 $02,*+$34
+
+ ldy #$01
+ lda ($05,x)
+ ldx #$01
+ ldz #$01
+ ldy $02
+ lda $02
+ ldx $02
+ smb2 $02
+ tay
+ lda #$01
+ tax
+ ldz $1234
+ ldy $1234
+ lda $1234
+ ldx $1234
+ bbs2 $02,*+$34
+
+ bcs *+$32
+ lda ($06),y
+ lda ($07),z
+ lbcs *+$3133 ; bcs *+$3133
+ ldy $03,x
+ lda $03,x
+ ldx $04,y
+ smb3 $02
+ clv
+ lda $1456,y
+ tsx
+ ldz $1345,x
+ ldy $1345,x
+ lda $1345,x
+ ldx $1456,y
+ bbs3 $02,*+$34
+
+ cpy #$01
+ cmp ($05,x)
+ cpz #$01
+ dew $02
+ cpy $02
+ cmp $02
+ dec $02
+ smb4 $02
+ iny
+ cmp #$01
+ dex
+ asw $1234
+ cpy $1234
+ cmp $1234
+ dec $1234
+ bbs4 $02,*+$34
+
+ bne *+$32
+ cmp ($06),y
+ cmp ($07),z
+ lbne *+$3133 ; bne *+$3133
+ cpz $02
+ cmp $03,x
+ dec $03,x
+ smb5 $02
+ cld
+ cmp $1456,y
+ phx
+ phz
+ cpz $1234
+ cmp $1345,x
+ dec $1345,x
+ bbs5 $02,*+$34
+
+ cpx #$01
+ sbc ($05,x)
+ lda ($0f,s),y
+ lda ($0f,sp),y
+ inw $02
+ cpx $02
+ sbc $02
+ inc $02
+ smb6 $02
+ inx
+ sbc #$01
+ eom
+ nop
+ row $1234
+ cpx $1234
+ sbc $1234
+ inc $1234
+ bbs6 $02,*+$34
+
+ beq *+$32
+ sbc ($06),y
+ sbc ($07),z
+ lbeq *+$3133 ; beq *+$3133
+ phd #$089a
+ phw #$089a
+ sbc $03,x
+ inc $03,x
+ smb7 $02
+ sed
+ sbc $1456,y
+ plx
+ plz
+ phd $1234
+ phw $1234
+ sbc $1345,x
+ inc $1345,x
+ bbs7 $02,*+$34
+
+ adc [$12],z
+
+ adcq $12
+ adcq $3456
+ adcq ($78)
+ adcq [$9a]
+
+ and [$12],z
+
+ andq $12
+ andq $3456
+ andq ($78)
+ andq [$9a]
+
+ aslq $12
+ aslq
+ aslq $3456
+ aslq $78,x
+ aslq $9abc,x
+
+ asrq
+ asrq $12
+ asrq $34,x
+
+ bitq $12
+ bitq $3456
+
+ cmp [$12],z
+
+ cmpq $12
+ cmpq $3456
+ cmpq ($78)
+ cmpq [$9a]
+
+ deq
+ deq $12
+ deq $3456
+ deq $78,x
+ deq $9abc,x
+
+ eor [$12],z
+
+ eorq $12
+ eorq $3456
+ eorq ($78)
+ eorq [$9a]
+
+ inq
+ inq $12
+ inq $3456
+ inq $78,x
+ inq $9abc,x
+
+ lda [$12],z
+
+ ldq $12
+ ldq $3456
+ ldq ($78),z
+ ldq [$9a],z
+
+ lsrq $12
+ lsrq
+ lsrq $3456
+ lsrq $78,x
+ lsrq $9abc,x
+
+ ora [$12],z
+
+ orq $12
+ orq $3456
+ orq ($78)
+ orq [$9a]
+
+ rolq $12
+ rolq
+ rolq $3456
+ rolq $78,x
+ rolq $9abc,x
+
+ rorq $12
+ rorq
+ rorq $3456
+ rorq $78,x
+ rorq $9abc,x
+
+ sbc [$12],z
+
+ sbcq $12
+ sbcq $3456
+ sbcq ($78)
+ sbcq [$9a]
+
+ sta [$12],z ; EA 92 12
+
+ stq $12
+ stq $3456
+ stq ($78)
+ stq [$9a]
diff --git a/test/dasm/45GS02-disass.s b/test/dasm/45GS02-disass.s
new file mode 100644
index 000000000..1ed174a2f
--- /dev/null
+++ b/test/dasm/45GS02-disass.s
@@ -0,0 +1,381 @@
+.setcpu "45GS02"
+
+ZP = $12
+ABS = $1234
+
+ brk
+ ora ($05,x)
+ cle
+ see
+ tsb $02
+ ora $02
+ asl $02
+ rmb0 $02
+ php
+ ora #$01
+ asl
+ tsy
+ tsb $1234
+ ora $1234
+ asl $1234
+ bbr0 $02, L0
+L0:
+ bpl L0
+ ora ($06),y
+ ora ($07),z
+ lbpl *+$3133 ; bpl *+$3133
+ trb $02
+ ora $03,x
+ asl $03,x
+ rmb1 $02
+ clc
+ ora $1456,y
+ inc
+ inz
+ trb $1234
+ ora $1345,x
+ asl $1345,x
+ bbr1 $02,L1
+L1:
+ jsr $1234
+ and ($05,x)
+ jsr ($2345)
+ jsr ($2456,x)
+ bit $02
+ and $02
+ rol $02
+ rmb2 $02
+ plp
+ and #$01
+ rol
+ tys
+ bit $1234
+ and $1234
+ rol $1234
+ bbr2 $02,L2
+L2:
+ bmi L2
+ and ($06),y
+ and ($07),z
+ lbmi *+$3133 ; bmi *+$3133
+ bit $03,x
+ and $03,x
+ rol $03,x
+ rmb3 $02
+ sec
+ and $1456,y
+ dec
+ dez
+ bit $1345,x
+ and $1345,x
+ rol $1345,x
+ bbr3 $02,L3
+L3:
+ rti
+ eor ($05,x)
+ neg
+ asr
+ asr $02
+ eor $02
+ lsr $02
+ rmb4 $02
+ pha
+ eor #$01
+ lsr
+ taz
+ jmp $1234
+ eor $1234
+ lsr $1234
+ bbr4 $02,L4
+L4:
+ bvc L4
+ eor ($06),y
+ eor ($07),z
+ lbvc *+$3133 ; bvc *+$3133
+ asr $03,x
+ eor $03,x
+ lsr $03,x
+ rmb5 $02
+ cli
+ eor $1456,y
+ phy
+ tab
+ map
+ eor $1345,x
+ lsr $1345,x
+ bbr5 $02,L5
+L5:
+ rts
+ adc ($05,x)
+ rtn #$09
+ bsr *+$3133
+ stz $02
+ adc $02
+ ror $02
+ rmb6 $02
+ pla
+ adc #$01
+ ror
+ tza
+ jmp ($2345)
+ adc $1234
+ ror $1234
+ bbr6 $02,L6
+L6:
+ bvs L6
+ adc ($06),y
+ adc ($07),z
+ lbvs *+$3133 ; bvs *+$3133
+ stz $03,x
+ adc $03,x
+ ror $03,x
+ rmb7 $02
+ sei
+ adc $1456,y
+ ply
+ tba
+ jmp ($2456,x)
+ adc $1345,x
+ ror $1345,x
+ bbr7 $02,L7
+L7:
+ bra L7
+ sta ($05,x)
+ sta ($0f,s),y
+ sta ($0f,sp),y
+ lbra *+$3133 ; bra *+$3133
+ sty $02
+ sta $02
+ stx $02
+ smb0 $02
+ dey
+ bit #$01
+ txa
+ sty $1345,x
+ sty $1234
+ sta $1234
+ stx $1234
+ bbs0 $02,L8
+L8:
+ bcc L8
+ sta ($06),y
+ sta ($07),z
+ lbcc *+$3133 ; bcc *+$3133
+ sty $03,x
+ sta $03,x
+ stx $04,y
+ smb1 $02
+ tya
+ sta $1456,y
+ txs
+ stx $1456,y
+ stz $1234
+ sta $1345,x
+ stz $1345,x
+ bbs1 $02,L9
+L9:
+ ldy #$01
+ lda ($05,x)
+ ldx #$01
+ ldz #$01
+ ldy $02
+ lda $02
+ ldx $02
+ smb2 $02
+ tay
+ lda #$01
+ tax
+ ldz $1234
+ ldy $1234
+ lda $1234
+ ldx $1234
+ bbs2 $02,L10
+L10:
+ bcs L10
+ lda ($06),y
+ lda ($07),z
+ lbcs *+$3133 ; bcs *+$3133
+ ldy $03,x
+ lda $03,x
+ ldx $04,y
+ smb3 $02
+ clv
+ lda $1456,y
+ tsx
+ ldz $1345,x
+ ldy $1345,x
+ lda $1345,x
+ ldx $1456,y
+ bbs3 $02,L11
+L11:
+ cpy #$01
+ cmp ($05,x)
+ cpz #$01
+ dew $02
+ cpy $02
+ cmp $02
+ dec $02
+ smb4 $02
+ iny
+ cmp #$01
+ dex
+ asw $1234
+ cpy $1234
+ cmp $1234
+ dec $1234
+ bbs4 $02,L12
+L12:
+ bne L12
+ cmp ($06),y
+ cmp ($07),z
+ lbne *+$3133 ; bne *+$3133
+ cpz $02
+ cmp $03,x
+ dec $03,x
+ smb5 $02
+ cld
+ cmp $1456,y
+ phx
+ phz
+ cpz $1234
+ cmp $1345,x
+ dec $1345,x
+ bbs5 $02,L13
+L13:
+ cpx #$01
+ sbc ($05,x)
+ lda ($0f,s),y
+ lda ($0f,sp),y
+ inw $02
+ cpx $02
+ sbc $02
+ inc $02
+ smb6 $02
+ inx
+ sbc #$01
+ eom
+ nop
+ row $1234
+ cpx $1234
+ sbc $1234
+ inc $1234
+ bbs6 $02,L14
+L14:
+ beq L14
+ sbc ($06),y
+ sbc ($07),z
+ lbeq *+$3133 ; beq *+$3133
+ phd #$089a
+ phw #$089a
+ sbc $03,x
+ inc $03,x
+ smb7 $02
+ sed
+ sbc $1456,y
+ plx
+ plz
+ phd $1234
+ phw $1234
+ sbc $1345,x
+ inc $1345,x
+ bbs7 $02,L15
+L15:
+
+ adc [$12],z
+
+ adcq $12
+ adcq $3456
+ adcq ($78)
+ adcq [$9a]
+
+ and [$12],z
+
+ andq $12
+ andq $3456
+ andq ($78)
+ andq [$9a]
+
+ aslq $12
+ aslq
+ aslq $3456
+ aslq $78,x
+ aslq $9abc,x
+
+ asrq
+ asrq $12
+ asrq $34,x
+
+ bitq $12
+ bitq $3456
+
+ cmp [$12],z
+
+ cmpq $12
+ cmpq $3456
+ cmpq ($78)
+ cmpq [$9a]
+
+ deq
+ deq $12
+ deq $3456
+ deq $78,x
+ deq $9abc,x
+
+ eor [$12],z
+
+ eorq $12
+ eorq $3456
+ eorq ($78)
+ eorq [$9a]
+
+ inq
+ inq $12
+ inq $3456
+ inq $78,x
+ inq $9abc,x
+
+ lda [$12],z
+
+ ldq $12
+ ldq $3456
+ ldq ($78),z
+ ldq [$9a],z
+
+ lsrq $12
+ lsrq
+ lsrq $3456
+ lsrq $78,x
+ lsrq $9abc,x
+
+ ora [$12],z
+
+ orq $12
+ orq $3456
+ orq ($78)
+ orq [$9a]
+
+ rolq $12
+ rolq
+ rolq $3456
+ rolq $78,x
+ rolq $9abc,x
+
+ rorq $12
+ rorq
+ rorq $3456
+ rorq $78,x
+ rorq $9abc,x
+
+ sbc [$12],z
+
+ sbcq $12
+ sbcq $3456
+ sbcq ($78)
+ sbcq [$9a]
+
+ sta [$12],z ; EA 92 12
+
+ stq $12
+ stq $3456
+ stq ($78)
+ stq [$9a]
diff --git a/test/dasm/6502-disass.s b/test/dasm/6502-disass.s
new file mode 100644
index 000000000..794eead76
--- /dev/null
+++ b/test/dasm/6502-disass.s
@@ -0,0 +1,8 @@
+
+ .setcpu "6502"
+
+ .repeat 256, cnt
+
+ .byte 0 + cnt, $02, $ea, $00
+
+ .endrepeat
diff --git a/test/dasm/6502DTV-disass.s b/test/dasm/6502DTV-disass.s
new file mode 100644
index 000000000..5254923c5
--- /dev/null
+++ b/test/dasm/6502DTV-disass.s
@@ -0,0 +1,188 @@
+.setcpu "6502DTV"
+
+ brk
+ ora ($12,x)
+ nop $12
+ ora $12
+ asl $12
+ php
+ ora #$12
+ asl a
+ anc #$12
+ nop $3456
+ ora $3456
+ asl $3456
+ bpl *+2
+ ora ($12),y
+ bra *+2
+ nop $12,x
+ ora $12,x
+ asl $12,x
+ clc
+ ora $3456,y
+ nop $3456,x
+ ora $3456,x
+ asl $3456,x
+ jsr $3456
+ and ($12,x)
+ rla ($12,x)
+ bit $12
+ and $12
+ rol $12
+ rla $12
+ plp
+ and #$12
+ rol a
+ bit $3456
+ and $3456
+ rol $3456
+ rla $3456
+ bmi *+2
+ and ($12),y
+ sac #$12
+ rla ($12),y
+ and $12,x
+ rol $12,x
+ rla $12,x
+ sec
+ and $3456,y
+ rla $3456,y
+ and $3456,x
+ rol $3456,x
+ rla $3456,x
+ rti
+ eor ($12,x)
+ sir #$12
+ eor $12
+ lsr $12
+ pha
+ eor #$12
+ lsr a
+ alr #$12
+ jmp $3456
+ eor $3456
+ lsr $3456
+ bvc *+2
+ eor ($12),y
+ eor $12,x
+ lsr $12,x
+ cli
+ eor $3456,x
+ lsr $3456,x
+ rts
+ adc ($12,x)
+ rra ($12,x)
+ adc $12
+ ror $12
+ rra $12
+ pla
+ adc #$12
+ ror a
+ arr #$12
+ jmp ($3456)
+ adc $3456
+ ror $3456
+ rra $3456
+ bvs *+2
+ adc ($12),y
+ rra ($12),y
+ adc $12,x
+ ror $12,x
+ rra $12,x
+ sei
+ adc $3456,y
+ rra $3456,y
+ adc $3456,x
+ ror $3456,x
+ rra $3456,x
+ nop #$12
+ sta ($12,x)
+ sty $12
+ sta $12
+ stx $12
+ dey
+ txa
+ sty $3456
+ sta $3456
+ stx $3456
+ bcc *+2
+ sta ($12),y
+ sty $12,x
+ sta $12,x
+ stx $12,y
+ tya
+ sta $3456,y
+ txs
+ shy $3456,x
+ sta $3456,x
+ shx $3456,y
+ ldy #$12
+ lda ($12,x)
+ ldx #$12
+ lax ($12,x)
+ ldy $12
+ lda $12
+ ldx $12
+ lax $12
+ tay
+ lda #$12
+ tax
+ lax #$12
+ ldy $3456
+ lda $3456
+ ldx $3456
+ lax $3456
+ bcs *+2
+ lda ($12),y
+ lax ($12),y
+ ldy $12,x
+ lda $12,x
+ ldx $12,y
+ lax $12,y
+ clv
+ lda $3456,y
+ tsx
+ las $3456,y
+ ldy $3456,x
+ lda $3456,x
+ ldx $3456,y
+ lax $3456,y
+ cpy #$12
+ cmp ($12,x)
+ cpy $12
+ cmp $12
+ dec $12
+ iny
+ cmp #$12
+ dex
+ axs #$12
+ cpy $3456
+ cmp $3456
+ dec $3456
+ bne *+2
+ cmp ($12),y
+ cmp $12,x
+ dec $12,x
+ cld
+ cmp $3456,y
+ cmp $3456,x
+ dec $3456,x
+ cpx #$12
+ sbc ($12,x)
+ cpx $12
+ sbc $12
+ inc $12
+ inx
+ sbc #$12
+ nop
+ cpx $3456
+ sbc $3456
+ inc $3456
+ beq *+2
+ sbc ($12),y
+ sbc $12,x
+ inc $12,x
+ sed
+ sbc $3456,y
+ sbc $3456,x
+ inc $3456,x
diff --git a/test/dasm/6502X-disass.s b/test/dasm/6502X-disass.s
new file mode 100644
index 000000000..f102144c4
--- /dev/null
+++ b/test/dasm/6502X-disass.s
@@ -0,0 +1,30 @@
+
+ .setcpu "6502X"
+
+ .repeat 256, cnt
+
+ ; generate a pattern with all opcodes. however, for the full cycle to work,
+ ; we must take care of the "duplicate" opcodes, ie use only the favourite one.
+ .if ((cnt & $0f) = $02)
+ .byte $02 ; all JAM
+ .elseif ((cnt & $1f) = $1a)
+ .byte $ea ; all NOP
+ .elseif (cnt = $2b)
+ .byte $0b ; both ANC #imm
+ .elseif (cnt = $89)
+ .byte $80 ; both NOP #imm
+ .elseif (cnt = $eb)
+ .byte $e9 ; both SBC #imm
+ .elseif (cnt = $34) || (cnt = $54) || (cnt = $74) || (cnt = $d4) || (cnt = $f4)
+ .byte $14 ; all NOP zp, x
+ .elseif (cnt = $3c) || (cnt = $5c) || (cnt = $7c) || (cnt = $dc) || (cnt = $fc)
+ .byte $1c ; all NOP abs, x
+ .elseif (cnt = $44) || (cnt = $64)
+ .byte $04 ; all NOP zp
+ .else
+ .byte cnt
+ .endif
+
+ .byte $02, $ea, $00
+
+ .endrepeat
diff --git a/test/dasm/65C02-disass.s b/test/dasm/65C02-disass.s
new file mode 100644
index 000000000..0613921d5
--- /dev/null
+++ b/test/dasm/65C02-disass.s
@@ -0,0 +1,214 @@
+.setcpu "65C02"
+
+ brk
+ ora ($12,x)
+ tsb $12
+ ora $12
+ asl $12
+ rmb0 $12
+ php
+ ora #$12
+ asl a
+ tsb $3456
+ ora $3456
+ asl $3456
+ bbr0 $12,*+2
+ bpl *+2
+ ora ($12),y
+ ora ($12)
+ trb $12
+ ora $12,x
+ asl $12,x
+ rmb1 $12
+ clc
+ ora $3456,y
+ inc a
+ trb $3456
+ ora $3456,x
+ asl $3456,x
+ bbr1 $12,*+2
+ jsr $3456
+ and ($12,x)
+ bit $12
+ and $12
+ rol $12
+ rmb2 $12
+ plp
+ and #$12
+ rol a
+ bit $3456
+ and $3456
+ rol $3456
+ bbr2 $12,*+2
+ bmi *+2
+ and ($12),y
+ and ($12)
+ bit $12,x
+ and $12,x
+ rol $12,x
+ rmb3 $12
+ sec
+ and $3456,y
+ dec a
+ bit $3456,x
+ and $3456,x
+ rol $3456,x
+ bbr3 $12,*+2
+ rti
+ eor ($12,x)
+ eor $12
+ lsr $12
+ rmb4 $12
+ pha
+ eor #$12
+ lsr a
+ jmp $3456
+ eor $3456
+ lsr $3456
+ bbr4 $12,*+2
+ bvc *+2
+ eor ($12),y
+ eor ($12)
+ eor $12,x
+ lsr $12,x
+ rmb5 $12
+ cli
+ eor $3456,y
+ phy
+ eor $3456,x
+ lsr $3456,x
+ bbr5 $12,*+2
+ rts
+ adc ($12,x)
+ stz $12
+ adc $12
+ ror $12
+ rmb6 $12
+ pla
+ adc #$12
+ ror a
+ jmp ($3456)
+ adc $3456
+ ror $3456
+ bbr6 $12,*+2
+ bvs *+2
+ adc ($12),y
+ adc ($12)
+ stz $12,x
+ adc $12,x
+ ror $12,x
+ rmb7 $12
+ sei
+ adc $3456,y
+ ply
+ jmp ($3456,x)
+ adc $3456,x
+ ror $3456,x
+ bbr7 $12,*+2
+ bra *+2
+ sta ($12,x)
+ sty $12
+ sta $12
+ stx $12
+ smb0 $12
+ dey
+ bit #$12
+ txa
+ sty $3456
+ sta $3456
+ stx $3456
+ bbs0 $12,*+2
+ bcc *+2
+ sta ($12),y
+ sta ($12)
+ sty $12,x
+ sta $12,x
+ stx $12,y
+ smb1 $12
+ tya
+ sta $3456,y
+ txs
+ stz $3456
+ sta $3456,x
+ stz $3456,x
+ bbs1 $12,*+2
+ ldy #$12
+ lda ($12,x)
+ ldx #$12
+ ldy $12
+ lda $12
+ ldx $12
+ smb2 $12
+ tay
+ lda #$12
+ tax
+ ldy $3456
+ lda $3456
+ ldx $3456
+ bbs2 $12,*+2
+ bcs *+2
+ lda ($12),y
+ lda ($12)
+ ldy $12,x
+ lda $12,x
+ ldx $12,y
+ smb3 $12
+ clv
+ lda $3456,y
+ tsx
+ ldy $3456,x
+ lda $3456,x
+ ldx $3456,y
+ bbs3 $12,*+2
+ cpy #$12
+ cmp ($12,x)
+ cpy $12
+ cmp $12
+ dec $12
+ smb4 $12
+ iny
+ cmp #$12
+ dex
+ cpy $3456
+ cmp $3456
+ dec $3456
+ bbs4 $12,*+2
+ bne *+2
+ cmp ($12),y
+ cmp ($12)
+ cmp $12,x
+ dec $12,x
+ smb5 $12
+ cld
+ cmp $3456,y
+ phx
+ cmp $3456,x
+ dec $3456,x
+ bbs5 $12,*+2
+ cpx #$12
+ sbc ($12,x)
+ cpx $12
+ sbc $12
+ inc $12
+ smb6 $12
+ inx
+ sbc #$12
+ nop
+ cpx $3456
+ sbc $3456
+ inc $3456
+ bbs6 $12,*+2
+ beq *+2
+ sbc ($12),y
+ sbc ($12)
+ sbc $12,x
+ inc $12,x
+ smb7 $12
+ sed
+ sbc $3456,y
+ plx
+ sbc $3456,x
+ inc $3456,x
+L0:
+ bbs7 $12,L0
+ nop
diff --git a/test/dasm/65SC02-disass.s b/test/dasm/65SC02-disass.s
new file mode 100644
index 000000000..46e96aaf9
--- /dev/null
+++ b/test/dasm/65SC02-disass.s
@@ -0,0 +1,181 @@
+.setcpu "65SC02"
+
+ brk
+ ora ($12,x)
+ tsb $12
+ ora $12
+ asl $12
+ php
+ ora #$12
+ asl a
+ tsb $3456
+ ora $3456
+ asl $3456
+ bpl *+2
+ ora ($12),y
+ ora ($12)
+ trb $12
+ ora $12,x
+ asl $12,x
+ clc
+ ora $3456,y
+ inc a
+ trb $3456
+ ora $3456,x
+ asl $3456,x
+ jsr $3456
+ and ($12,x)
+ bit $12
+ and $12
+ rol $12
+ plp
+ and #$12
+ rol a
+ bit $3456
+ and $3456
+ rol $3456
+ bmi *+2
+ and ($12),y
+ and ($12)
+ bit $12,x
+ and $12,x
+ rol $12,x
+ sec
+ and $3456,y
+ dec a
+ bit $3456,x
+ and $3456,x
+ rol $3456,x
+ rti
+ eor ($12,x)
+ eor $12
+ lsr $12
+ pha
+ eor #$12
+ lsr a
+ jmp $3456
+ eor $3456
+ lsr $3456
+ bvc *+2
+ eor ($12),y
+ eor ($12)
+ eor $12,x
+ lsr $12,x
+ cli
+ eor $3456,y
+ phy
+ eor $3456,x
+ lsr $3456,x
+ rts
+ adc ($12,x)
+ stz $12
+ adc $12
+ ror $12
+ pla
+ adc #$12
+ ror a
+ jmp ($3456)
+ adc $3456
+ ror $3456
+ bvs *+2
+ adc ($12),y
+ adc ($12)
+ stz $12,x
+ adc $12,x
+ ror $12,x
+ sei
+ adc $3456,y
+ ply
+ jmp ($3456,x)
+ adc $3456,x
+ ror $3456,x
+ bra *+2
+ sta ($12,x)
+ sty $12
+ sta $12
+ stx $12
+ dey
+ bit #$12
+ txa
+ sty $3456
+ sta $3456
+ stx $3456
+ bcc *+2
+ sta ($12),y
+ sta ($12)
+ sty $12,x
+ sta $12,x
+ stx $12,y
+ tya
+ sta $3456,y
+ txs
+ stz $3456
+ sta $3456,x
+ stz $3456,x
+ ldy #$12
+ lda ($12,x)
+ ldx #$12
+ ldy $12
+ lda $12
+ ldx $12
+ tay
+ lda #$12
+ tax
+ ldy $3456
+ lda $3456
+ ldx $3456
+ bcs *+2
+ lda ($12),y
+ lda ($12)
+ ldy $12,x
+ lda $12,x
+ ldx $12,y
+ clv
+ lda $3456,y
+ tsx
+ ldy $3456,x
+ lda $3456,x
+ ldx $3456,y
+ cpy #$12
+ cmp ($12,x)
+ cpy $12
+ cmp $12
+ dec $12
+ iny
+ cmp #$12
+ dex
+ cpy $3456
+ cmp $3456
+ dec $3456
+ bne *+2
+ cmp ($12),y
+ cmp ($12)
+ cmp $12,x
+ dec $12,x
+ cld
+ cmp $3456,y
+ phx
+ cmp $3456,x
+ dec $3456,x
+ cpx #$12
+ sbc ($12,x)
+ cpx $12
+ sbc $12
+ inc $12
+ inx
+ sbc #$12
+ nop
+ cpx $3456
+ sbc $3456
+ inc $3456
+ beq *+2
+ sbc ($12),y
+ sbc ($12)
+ sbc $12,x
+ inc $12,x
+ sed
+ sbc $3456,y
+ plx
+ sbc $3456,x
+ inc $3456,x
+
diff --git a/test/dasm/huc6280-disass.s b/test/dasm/huc6280-disass.s
new file mode 100644
index 000000000..4ae7b067d
--- /dev/null
+++ b/test/dasm/huc6280-disass.s
@@ -0,0 +1,250 @@
+.setcpu "huc6280"
+
+ brk
+ ora ($12,x)
+ sxy
+ st0 #$12
+ tsb $12
+ ora $12
+ asl $12
+ rmb0 $12
+ php
+ ora #$12
+ asl a
+ tsb $3456
+ ora $3456
+ asl $3456
+ bbr0 $12,L0
+L0:
+ bpl *+2
+ ora ($12),y
+ ora ($12)
+ st1 #$12
+ trb $12
+ ora $12,x
+ asl $12,x
+ rmb1 $12
+ clc
+ ora $3456,y
+ inc a
+ trb $3456
+ ora $3456,x
+ asl $3456,x
+ bbr1 $12,L1
+L1:
+ jsr $3456
+ and ($12,x)
+ sax
+ st2 #$12
+ bit $12
+ and $12
+ rol $12
+ rmb2 $12
+ plp
+ and #$12
+ rol a
+ bit $3456
+ and $3456
+ rol $3456
+ bbr2 $12,L2
+L2:
+ bmi *+2
+ and ($12),y
+ and ($12)
+ bit $12,x
+ and $12,x
+ rol $12,x
+ rmb3 $12
+ sec
+ and $3456,y
+ dec a
+ bit $3456,x
+ and $3456,x
+ rol $3456,x
+ bbr3 $12,L3
+L3:
+ rti
+ eor ($12,x)
+ say
+ tma #$02
+ bsr *+2
+ eor $12
+ lsr $12
+ rmb4 $12
+ pha
+ eor #$12
+ lsr a
+ jmp $3456
+ eor $3456
+ lsr $3456
+ bbr4 $12,L4
+L4:
+ bvc *+2
+ eor ($12),y
+ eor ($12)
+ tam #$12
+ csl
+ eor $12,x
+ lsr $12,x
+ rmb5 $12
+ cli
+ eor $3456,y
+ phy
+ eor $3456,x
+ lsr $3456,x
+ bbr5 $12,L5
+L5:
+ rts
+ adc ($12,x)
+ cla
+ stz $12
+ adc $12
+ ror $12
+ rmb6 $12
+ pla
+ adc #$12
+ ror a
+ jmp ($3456)
+ adc $3456
+ ror $3456
+ bbr6 $12,L6
+L6:
+ bvs *+2
+ adc ($12),y
+ adc ($12)
+ tii $3333,$7373,$1111
+ stz $12,x
+ adc $12,x
+ ror $12,x
+ rmb7 $12
+ sei
+ adc $3456,y
+ ply
+ jmp ($3456,x)
+ adc $3456,x
+ ror $3456,x
+ bbr7 $12,L7
+L7:
+ bra *+2
+ sta ($12,x)
+ clx
+ tst #$12,$EA
+ sty $12
+ sta $12
+ stx $12
+ smb0 $12
+ dey
+ bit #$12
+ txa
+ sty $3456
+ sta $3456
+ stx $3456
+ bbs0 $12,LS0
+LS0:
+ bcc *+2
+ sta ($12),y
+ sta ($12)
+ tst #$12,$EAEA
+ sty $12,x
+ sta $12,x
+ stx $12,y
+ smb1 $12
+ tya
+ sta $3456,y
+ txs
+ stz $3456
+ sta $3456,x
+ stz $3456,x
+ bbs1 $12,LS1
+LS1:
+ ldy #$12
+ lda ($12,x)
+ ldx #$12
+ tst #$12,$EA,x
+ ldy $12
+ lda $12
+ ldx $12
+ smb2 $12
+ tay
+ lda #$12
+ tax
+ ldy $3456
+ lda $3456
+ ldx $3456
+ bbs2 $12,LS2
+LS2:
+ bcs *+2
+ lda ($12),y
+ lda ($12)
+ tst #$12,$EAEA,x
+ ldy $12,x
+ lda $12,x
+ ldx $12,y
+ smb3 $12
+ clv
+ lda $3456,y
+ tsx
+ ldy $3456,x
+ lda $3456,x
+ ldx $3456,y
+ bbs3 $12,LS3
+LS3:
+ cpy #$12
+ cmp ($12,x)
+ cly
+ tdd $3333,$C3C3,$1111
+ cpy $12
+ cmp $12
+ dec $12
+ smb4 $12
+ iny
+ cmp #$12
+ dex
+ cpy $3456
+ cmp $3456
+ dec $3456
+ bbs4 $12,LS4
+LS4:
+ bne *+2
+ cmp ($12),y
+ cmp ($12)
+ tin $3333,$D3D3,$1111
+ cmp $12,x
+ dec $12,x
+ smb5 $12
+ cld
+ cmp $3456,y
+ phx
+ cmp $3456,x
+ dec $3456,x
+ bbs5 $12,LS5
+LS5:
+ cpx #$12
+ sbc ($12,x)
+ tia $3333,$E3E3,$1111
+ cpx $12
+ sbc $12
+ inc $12
+ smb6 $12
+ inx
+ sbc #$12
+ nop
+ cpx $3456
+ sbc $3456
+ inc $3456
+ bbs6 $12,LS6
+LS6:
+ beq *+2
+ sbc ($12),y
+ sbc ($12)
+ tai $3333,$F3F3,$1111
+ sbc $12,x
+ inc $12,x
+ smb7 $12
+ sed
+ sbc $3456,y
+ plx
+ sbc $3456,x
+ inc $3456,x
+LS7:
+ bbs7 $12,LS7
diff --git a/test/dasm/m740-disass.s b/test/dasm/m740-disass.s
new file mode 100644
index 000000000..ea0f19f8d
--- /dev/null
+++ b/test/dasm/m740-disass.s
@@ -0,0 +1,8 @@
+
+ .setcpu "M740"
+
+ .repeat 256, cnt
+
+ .byte 0 + cnt, $12, $02, $ea
+
+ .endrepeat
diff --git a/test/dasm/readme.txt b/test/dasm/readme.txt
new file mode 100644
index 000000000..9e001ec8c
--- /dev/null
+++ b/test/dasm/readme.txt
@@ -0,0 +1,9 @@
+
+Per CPU, a test binary is produced (using the assembler), which should contain
+all possible instructions. That file is then disassembled, and assembled again,
+and finally the resulting binary compared with the binary produced in the first
+step.
+
+Given that we assume the assembler works (this is tested in other/previous
+tests), this proves that the disassembler works, and can produce output that the
+assembler will understand - and produce an identical binary from.