summaryrefslogtreecommitdiffstatshomepage
path: root/trunk/src/emu/cpu/m6800/6800dasm.c
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/emu/cpu/m6800/6800dasm.c')
-rw-r--r--trunk/src/emu/cpu/m6800/6800dasm.c280
1 files changed, 280 insertions, 0 deletions
diff --git a/trunk/src/emu/cpu/m6800/6800dasm.c b/trunk/src/emu/cpu/m6800/6800dasm.c
new file mode 100644
index 00000000000..712de231159
--- /dev/null
+++ b/trunk/src/emu/cpu/m6800/6800dasm.c
@@ -0,0 +1,280 @@
+/*
+ * A quick-hack 6803/6808 disassembler
+ *
+ * Note: this is not the good and proper way to disassemble anything, but it works
+ *
+ * I'm afraid to put my name on it, but I feel obligated:
+ * This code written by Aaron Giles (agiles@sirius.com) for the MAME project
+ *
+ * History:
+ * 990314 HJB
+ * The disassembler knows about valid opcodes for M6800/1/2/3/8 and HD63701.
+ * 990302 HJB
+ * Changed the string array into a table of opcode names (or tokens) and
+ * argument types. This second try should give somewhat better results.
+ * Named the undocumented HD63701YO opcodes $12 and $13 'asx1' and 'asx2',
+ * since 'add contents of stack to x register' is what they do.
+ *
+ */
+
+#include "emu.h"
+#include "debugger.h"
+#include "m6800.h"
+
+enum addr_mode {
+ inh, /* inherent */
+ rel, /* relative */
+ imb, /* immediate (byte) */
+ imw, /* immediate (word) */
+ dir, /* direct address */
+ imd, /* HD63701YO: immediate, direct address */
+ ext, /* extended address */
+ idx, /* x + byte offset */
+ imx, /* HD63701YO: immediate, x + byte offset */
+ sx1 /* HD63701YO: undocumented opcodes: byte from (s+1) */
+};
+
+enum op_names {
+ aba=0, abx, adca, adcb, adda, addb, addd, aim,
+ anda, andb, asl, asla, aslb, asld, asr, asra,
+ asrb, bcc, bcs, beq, bge, bgt, bhi, bita,
+ bitb, ble, bls, blt, bmi, bne, bpl, bra,
+ brn, bsr, bvc, bvs, cba, clc, cli, clr,
+ clra, clrb, clv, cmpa, cmpb, cmpx, com, coma,
+ comb, daa, dec, deca, decb, des, dex, eim,
+ eora, eorb, ill, inc, inca, incb, ins, inx,
+ jmp, jsr, lda, ldb, ldd, lds, ldx, lsr,
+ lsra, lsrb, lsrd, mul, neg, nega, negb, nop,
+ oim, ora, orb, psha, pshb, pshx, pula, pulb,
+ pulx, rol, rola, rolb, ror, rora, rorb, rti,
+ rts, sba, sbca, sbcb, sec, sev, sta, stb,
+ _std, sei, sts, stx, suba, subb, subd, swi,
+ wai, tab, tap, tba, tim, tpa, tst, tsta,
+ tstb, tsx, txs, asx1, asx2, xgdx, addx, adcx
+};
+
+static const char *const op_name_str[] = {
+ "aba", "abx", "adca", "adcb", "adda", "addb", "addd", "aim",
+ "anda", "andb", "asl", "asla", "aslb", "asld", "asr", "asra",
+ "asrb", "bcc", "bcs", "beq", "bge", "bgt", "bhi", "bita",
+ "bitb", "ble", "bls", "blt", "bmi", "bne", "bpl", "bra",
+ "brn", "bsr", "bvc", "bvs", "cba", "clc", "cli", "clr",
+ "clra", "clrb", "clv", "cmpa", "cmpb", "cmpx", "com", "coma",
+ "comb", "daa", "dec", "deca", "decb", "des", "dex", "eim",
+ "eora", "eorb", "illegal","inc", "inca", "incb", "ins", "inx",
+ "jmp", "jsr", "lda", "ldb", "ldd", "lds", "ldx", "lsr",
+ "lsra", "lsrb", "lsrd", "mul", "neg", "nega", "negb", "nop",
+ "oim", "ora", "orb", "psha", "pshb", "pshx", "pula", "pulb",
+ "pulx", "rol", "rola", "rolb", "ror", "rora", "rorb", "rti",
+ "rts", "sba", "sbca", "sbcb", "sec", "sev", "sta", "stb",
+ "std", "sei", "sts", "stx", "suba", "subb", "subd", "swi",
+ "wai", "tab", "tap", "tba", "tim", "tpa", "tst", "tsta",
+ "tstb", "tsx", "txs", "asx1", "asx2", "xgdx", "addx", "adcx"
+};
+
+/*
+ * This table defines the opcodes:
+ * byte meaning
+ * 0 token (menmonic)
+ * 1 addressing mode
+ * 2 invalid opcode for 1:6800/6802/6808, 2:6801/6803, 4:HD63701
+ */
+
+static const UINT8 table[0x102][3] = {
+ {ill, inh,7},{nop, inh,0},{ill, inh,7},{ill, inh,7},/* 00 */
+ {lsrd,inh,1},{asld,inh,1},{tap, inh,0},{tpa, inh,0},
+ {inx, inh,0},{dex, inh,0},{clv, inh,0},{sev, inh,0},
+ {clc, inh,0},{sec, inh,0},{cli, inh,0},{sei, inh,0},
+ {sba, inh,0},{cba, inh,0},{asx1,sx1,0},{asx2,sx1,0},/* 10 */
+ {ill, inh,7},{ill, inh,7},{tab, inh,0},{tba, inh,0},
+ {xgdx,inh,3},{daa, inh,0},{ill, inh,7},{aba, inh,0},
+ {ill, inh,7},{ill, inh,7},{ill, inh,7},{ill, inh,7},
+ {bra, rel,0},{brn, rel,0},{bhi, rel,0},{bls, rel,0},/* 20 */
+ {bcc, rel,0},{bcs, rel,0},{bne, rel,0},{beq, rel,0},
+ {bvc, rel,0},{bvs, rel,0},{bpl, rel,0},{bmi, rel,0},
+ {bge, rel,0},{blt, rel,0},{bgt, rel,0},{ble, rel,0},
+ {tsx, inh,0},{ins, inh,0},{pula,inh,0},{pulb,inh,0},/* 30 */
+ {des, inh,0},{txs, inh,0},{psha,inh,0},{pshb,inh,0},
+ {pulx,inh,1},{rts, inh,0},{abx, inh,1},{rti, inh,0},
+ {pshx,inh,1},{mul, inh,1},{wai, inh,0},{swi, inh,0},
+ {nega,inh,0},{ill, inh,7},{ill, inh,7},{coma,inh,0},/* 40 */
+ {lsra,inh,0},{ill, inh,7},{rora,inh,0},{asra,inh,0},
+ {asla,inh,0},{rola,inh,0},{deca,inh,0},{ill, inh,7},
+ {inca,inh,0},{tsta,inh,0},{ill, inh,7},{clra,inh,0},
+ {negb,inh,0},{ill, inh,7},{ill, inh,7},{comb,inh,0},/* 50 */
+ {lsrb,inh,0},{ill, inh,7},{rorb,inh,0},{asrb,inh,0},
+ {aslb,inh,0},{rolb,inh,0},{decb,inh,0},{ill, inh,7},
+ {incb,inh,0},{tstb,inh,0},{ill, inh,7},{clrb,inh,0},
+ {neg, idx,0},{aim, imx,3},{oim, imx,3},{com, idx,0},/* 60 */
+ {lsr, idx,0},{eim, imx,3},{ror, idx,0},{asr, idx,0},
+ {asl, idx,0},{rol, idx,0},{dec, idx,0},{tim, imx,3},
+ {inc, idx,0},{tst, idx,0},{jmp, idx,0},{clr, idx,0},
+ {neg, ext,0},{aim, imd,3},{oim, imd,3},{com, ext,0},/* 70 */
+ {lsr, ext,0},{eim, imd,3},{ror, ext,0},{asr, ext,0},
+ {asl, ext,0},{rol, ext,0},{dec, ext,0},{tim, imd,3},
+ {inc, ext,0},{tst, ext,0},{jmp, ext,0},{clr, ext,0},
+ {suba,imb,0},{cmpa,imb,0},{sbca,imb,0},{subd,imw,1},/* 80 */
+ {anda,imb,0},{bita,imb,0},{lda, imb,0},{sta, imb,0},
+ {eora,imb,0},{adca,imb,0},{ora, imb,0},{adda,imb,0},
+ {cmpx,imw,0},{bsr, rel,0},{lds, imw,0},{sts, imw,0},
+ {suba,dir,0},{cmpa,dir,0},{sbca,dir,0},{subd,dir,1},/* 90 */
+ {anda,dir,0},{bita,dir,0},{lda, dir,0},{sta, dir,0},
+ {eora,dir,0},{adca,dir,0},{ora, dir,0},{adda,dir,0},
+ {cmpx,dir,0},{jsr, dir,0},{lds, dir,0},{sts, dir,0},
+ {suba,idx,0},{cmpa,idx,0},{sbca,idx,0},{subd,idx,1},/* a0 */
+ {anda,idx,0},{bita,idx,0},{lda, idx,0},{sta, idx,0},
+ {eora,idx,0},{adca,idx,0},{ora, idx,0},{adda,idx,0},
+ {cmpx,idx,0},{jsr, idx,0},{lds, idx,0},{sts, idx,0},
+ {suba,ext,0},{cmpa,ext,0},{sbca,ext,0},{subd,ext,1},/* b0 */
+ {anda,ext,0},{bita,ext,0},{lda, ext,0},{sta, ext,0},
+ {eora,ext,0},{adca,ext,0},{ora, ext,0},{adda,ext,0},
+ {cmpx,ext,0},{jsr, ext,0},{lds, ext,0},{sts, ext,0},
+ {subb,imb,0},{cmpb,imb,0},{sbcb,imb,0},{addd,imw,1},/* c0 */
+ {andb,imb,0},{bitb,imb,0},{ldb, imb,0},{stb, imb,0},
+ {eorb,imb,0},{adcb,imb,0},{orb, imb,0},{addb,imb,0},
+ {ldd, imw,1},{_std,imw,1},{ldx, imw,0},{stx, imw,0},
+ {subb,dir,0},{cmpb,dir,0},{sbcb,dir,0},{addd,dir,1},/* d0 */
+ {andb,dir,0},{bitb,dir,0},{ldb, dir,0},{stb, dir,0},
+ {eorb,dir,0},{adcb,dir,0},{orb, dir,0},{addb,dir,0},
+ {ldd, dir,1},{_std,dir,1},{ldx, dir,0},{stx, dir,0},
+ {subb,idx,0},{cmpb,idx,0},{sbcb,idx,0},{addd,idx,1},/* e0 */
+ {andb,idx,0},{bitb,idx,0},{ldb, idx,0},{stb, idx,0},
+ {eorb,idx,0},{adcb,idx,0},{orb, idx,0},{addb,idx,0},
+ {ldd, idx,1},{_std,idx,1},{ldx, idx,0},{stx, idx,0},
+ {subb,ext,0},{cmpb,ext,0},{sbcb,ext,0},{addd,ext,1},/* f0 */
+ {andb,ext,0},{bitb,ext,0},{ldb, ext,0},{stb, ext,0},
+ {eorb,ext,0},{adcb,ext,0},{orb, ext,0},{addb,ext,0},
+ {ldd, ext,1},{_std,ext,1},{ldx, ext,0},{stx, ext,0},
+
+ /* extra instruction $fc for NSC-8105 */
+ {addx,ext,0},
+ /* extra instruction $ec for NSC-8105 */
+ {adcx,imb,0}
+};
+
+/* some macros to keep things short */
+#define OP oprom[0]
+#define ARG1 opram[1]
+#define ARG2 opram[2]
+#define ARGW (opram[1]<<8) + opram[2]
+
+static unsigned Dasm680x (int subtype, char *buf, unsigned pc, const UINT8 *oprom, const UINT8 *opram)
+{
+ UINT32 flags = 0;
+ int invalid_mask;
+ int code = OP;
+ UINT8 opcode, args, invalid;
+
+ switch( subtype )
+ {
+ case 6800: case 6802: case 6808: case 8105:
+ invalid_mask = 1;
+ break;
+ case 6801: case 6803:
+ invalid_mask = 2;
+ break;
+ default:
+ invalid_mask = 4;
+ }
+
+ /* NSC-8105 is a special case */
+ if (subtype == 8105)
+ {
+ /* swap bits */
+ code = (code & 0x3c) | ((code & 0x41) << 1) | ((code & 0x82) >> 1);
+
+ /* and check for extra instruction */
+ if (code == 0xfc) code = 0x0100;
+ if (code == 0xec) code = 0x0101;
+ }
+
+ opcode = table[code][0];
+ args = table[code][1];
+ invalid = table[code][2];
+
+ if (opcode == bsr || opcode == jsr)
+ flags = DASMFLAG_STEP_OVER;
+ else if (opcode == rti || opcode == rts)
+ flags = DASMFLAG_STEP_OUT;
+
+ if ( invalid & invalid_mask ) /* invalid for this cpu type ? */
+ {
+ strcpy(buf, "illegal");
+ return 1 | flags | DASMFLAG_SUPPORTED;
+ }
+
+ buf += sprintf(buf, "%-5s", op_name_str[opcode]);
+
+ switch( args )
+ {
+ case rel: /* relative */
+ sprintf (buf, "$%04X", pc + (INT8)ARG1 + 2);
+ return 2 | flags | DASMFLAG_SUPPORTED;
+ case imb: /* immediate (byte) */
+ sprintf (buf, "#$%02X", ARG1);
+ return 2 | flags | DASMFLAG_SUPPORTED;
+ case imw: /* immediate (word) */
+ sprintf (buf, "#$%04X", ARGW);
+ return 3 | flags | DASMFLAG_SUPPORTED;
+ case idx: /* indexed + byte offset */
+ sprintf (buf, "(x+$%02X)", ARG1 );
+ return 2 | flags | DASMFLAG_SUPPORTED;
+ case imx: /* immediate, indexed + byte offset */
+ sprintf (buf, "#$%02X,(x+$%02x)", ARG1, ARG2 );
+ return 3 | flags | DASMFLAG_SUPPORTED;
+ case dir: /* direct address */
+ sprintf (buf, "$%02X", ARG1 );
+ return 2 | flags | DASMFLAG_SUPPORTED;
+ case imd: /* immediate, direct address */
+ sprintf (buf, "#$%02X,$%02X", ARG1, ARG2);
+ return 3 | flags | DASMFLAG_SUPPORTED;
+ case ext: /* extended address */
+ sprintf (buf, "$%04X", ARGW);
+ return 3 | flags | DASMFLAG_SUPPORTED;
+ case sx1: /* byte from address (s + 1) */
+ sprintf (buf, "(s+1)");
+ return 1 | flags | DASMFLAG_SUPPORTED;
+ default:
+ return 1 | flags | DASMFLAG_SUPPORTED;
+ }
+}
+
+CPU_DISASSEMBLE( m6800 )
+{
+ return Dasm680x(6800,buffer,pc,oprom,opram);
+}
+
+CPU_DISASSEMBLE( m6801 )
+{
+ return Dasm680x(6801,buffer,pc,oprom,opram);
+}
+
+CPU_DISASSEMBLE( m6802 )
+{
+ return Dasm680x(6802,buffer,pc,oprom,opram);
+}
+
+CPU_DISASSEMBLE( m6803 )
+{
+ return Dasm680x(6803,buffer,pc,oprom,opram);
+}
+
+CPU_DISASSEMBLE( m6808 )
+{
+ return Dasm680x(6808,buffer,pc,oprom,opram);
+}
+
+CPU_DISASSEMBLE( hd6301 )
+{
+ return Dasm680x(6301,buffer,pc,oprom,opram);
+}
+
+CPU_DISASSEMBLE( hd63701 )
+{
+ return Dasm680x(63701,buffer,pc,oprom,opram);
+}
+
+CPU_DISASSEMBLE( nsc8105 )
+{
+ return Dasm680x(8105,buffer,pc,oprom,opram);
+}