summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2017-01-30 22:51:11 +1100
committer Vas Crabb <vas@vastheman.com>2017-01-30 23:10:51 +1100
commit06e22ce79d2bc41ac333ed5cf59ee1c2db5cfd6e (patch)
tree17b6a1dfca9f2ac2e4bcc330acfc408c3a44f8da /src
parent0995b978acbbc3a892595ac110f1d930684a1d52 (diff)
m6805: added skeleton CMOS devices
* Added m146805 and m68hc05 to unidasm * Made opcode tables configurable in m6805_base_device, provided tables for HMOS, CMOS and HC families * Implemented MUL instruction, made unimplemented STOP and WAIT raise fatal error * Added skeleton MC68HC05C4 with RAM and ROM in correct locations in memory map
Diffstat (limited to 'src')
-rw-r--r--src/devices/cpu/m6805/6805dasm.cpp372
-rw-r--r--src/devices/cpu/m6805/6805ops.hxx34
-rw-r--r--src/devices/cpu/m6805/m6805.cpp492
-rw-r--r--src/devices/cpu/m6805/m6805.h88
-rw-r--r--src/devices/cpu/m6805/m6805defs.h60
-rw-r--r--src/devices/cpu/m6805/m68705.cpp16
-rw-r--r--src/devices/cpu/m6805/m68hc05.cpp167
-rw-r--r--src/devices/cpu/m6805/m68hc05.h69
-rw-r--r--src/tools/unidasm.cpp4
9 files changed, 909 insertions, 393 deletions
diff --git a/src/devices/cpu/m6805/6805dasm.cpp b/src/devices/cpu/m6805/6805dasm.cpp
index 010840061e2..6f4934aa755 100644
--- a/src/devices/cpu/m6805/6805dasm.cpp
+++ b/src/devices/cpu/m6805/6805dasm.cpp
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Aaron Giles
+// copyright-holders:Aaron Giles, Vas Crabb
/*
* A quick-hack 68(7)05 disassembler
*
@@ -18,7 +18,7 @@
namespace {
enum class md {
- IMP, // implicit
+ INH, // inherent
BTR, // bit test and relative
BIT, // bit set/clear
REL, // relative
@@ -30,138 +30,96 @@ enum class md {
IX2 // indexed + word offset
};
+enum class lvl {
+ HMOS,
+ CMOS,
+ HC
+};
+
enum op_names {
- adca=0, adda, anda, asl, asla, aslx, asr, asra,
+ adca, adda, anda, asl, asla, aslx, asr, asra,
asrx, bcc, bclr, bcs, beq, bhcc, bhcs, bhi,
bih, bil, bita, bls, bmc, bmi, bms, bne,
bpl, bra, brclr, brn, brset, bset, bsr, clc,
cli, clr, clra, clrx, cmpa, com, coma, comx,
cpx, dec, deca, decx, eora, ill, inc, inca,
incx, jmp, jsr, lda, ldx, lsr, lsra, lsrx,
- neg, nega, negx, nop, ora, rol, rola, rolx,
- ror, rora, rorx, rsp, rti, rts, sbca, sec,
- sei, sta, stx, suba, swi, tax, tst, tsta,
- tstx, txa
-};
-
-char const *const op_name_str[] = {
- "adca", "adda", "anda", "asl", "asla", "aslx", "asr", "asra",
- "asrx", "bcc", "bclr", "bcs", "beq", "bhcc", "bhcs", "bhi",
- "bih", "bil", "bita", "bls", "bmc", "bmi", "bms", "bne",
- "bpl", "bra", "brclr","brn", "brset","bset", "bsr", "clc",
- "cli", "clr", "clra", "clrx", "cmpa", "com", "coma", "comx",
- "cpx", "dec", "deca", "decx", "eora", "*ill", "inc", "inca",
- "incx", "jmp", "jsr", "lda", "ldx", "lsr", "lsra", "lsrx",
- "neg", "nega", "negx", "nop", "ora", "rol", "rola", "rolx",
- "ror", "rora", "rorx", "rsp", "rti", "rts", "sbca", "sec",
- "sei", "sta", "stx", "suba", "swi", "tax", "tst", "tsta",
- "tstx", "txa"
+ mul, neg, nega, negx, nop, ora, rol, rola,
+ rolx, ror, rora, rorx, rsp, rti, rts, sbca,
+ sec, sei, sta, stop, stx, suba, swi, tax,
+ tst, tsta, tstx, txa, wait
};
-struct { u8 op; md mode; } const disasm[0x100] = {
- {brset,md::BTR}, {brclr,md::BTR}, {brset,md::BTR}, {brclr,md::BTR}, // 00
- {brset,md::BTR}, {brclr,md::BTR}, {brset,md::BTR}, {brclr,md::BTR},
- {brset,md::BTR}, {brclr,md::BTR}, {brset,md::BTR}, {brclr,md::BTR},
- {brset,md::BTR}, {brclr,md::BTR}, {brset,md::BTR}, {brclr,md::BTR},
- {bset, md::BIT}, {bclr, md::BIT}, {bset, md::BIT}, {bclr, md::BIT}, // 10
- {bset, md::BIT}, {bclr, md::BIT}, {bset, md::BIT}, {bclr, md::BIT},
- {bset, md::BIT}, {bclr, md::BIT}, {bset, md::BIT}, {bclr, md::BIT},
- {bset, md::BIT}, {bclr, md::BIT}, {bset, md::BIT}, {bclr, md::BIT},
- {bra, md::REL}, {brn, md::REL}, {bhi, md::REL}, {bls, md::REL}, // 20
- {bcc, md::REL}, {bcs, md::REL}, {bne, md::REL}, {beq, md::REL},
- {bhcc, md::REL}, {bhcs, md::REL}, {bpl, md::REL}, {bmi, md::REL},
- {bmc, md::REL}, {bms, md::REL}, {bil, md::REL}, {bih, md::REL},
- {neg, md::DIR}, {ill, md::IMP}, {ill, md::IMP}, {com, md::DIR}, // 30
- {lsr, md::DIR}, {ill, md::IMP}, {ror, md::DIR}, {asr, md::DIR},
- {asl, md::DIR}, {rol, md::DIR}, {dec, md::DIR}, {ill, md::IMP},
- {inc, md::DIR}, {tst, md::DIR}, {ill, md::IMP}, {clr, md::DIR},
- {nega, md::IMP}, {ill, md::IMP}, {ill, md::IMP}, {coma, md::IMP}, // 40
- {lsra, md::IMP}, {ill, md::IMP}, {rora, md::IMP}, {asra, md::IMP},
- {asla, md::IMP}, {rola, md::IMP}, {deca, md::IMP}, {ill, md::IMP},
- {inca, md::IMP}, {tsta, md::IMP}, {ill, md::IMP}, {clra, md::IMP},
- {negx, md::IMP}, {ill, md::IMP}, {ill, md::IMP}, {comx, md::IMP}, // 50
- {lsrx, md::IMP}, {ill, md::IMP}, {rorx, md::IMP}, {asrx, md::IMP},
- {aslx, md::IMP}, {rolx, md::IMP}, {decx, md::IMP}, {ill, md::IMP},
- {incx, md::IMP}, {tstx, md::IMP}, {ill, md::IMP}, {clrx, md::IMP},
- {neg, md::IX1}, {ill, md::IMP}, {ill, md::IMP}, {com, md::IX1}, // 60
- {lsr, md::IX1}, {ill, md::IMP}, {ror, md::IX1}, {asr, md::IX1},
- {asl, md::IX1}, {rol, md::IX1}, {dec, md::IX1}, {ill, md::IMP},
- {inc, md::IX1}, {tst, md::IX1}, {jmp, md::IX1}, {clr, md::IX1},
- {neg, md::IDX}, {ill, md::IMP}, {ill, md::IMP}, {com, md::IDX}, // 70
- {lsr, md::IDX}, {ill, md::IMP}, {ror, md::IDX}, {asr, md::IDX},
- {asl, md::IDX}, {rol, md::IDX}, {dec, md::IDX}, {ill, md::IMP},
- {inc, md::IDX}, {tst, md::IDX}, {jmp, md::IDX}, {clr, md::IDX},
- {rti, md::IMP}, {rts, md::IMP}, {ill, md::IMP}, {swi, md::IMP}, // 80
- {ill, md::IMP}, {ill, md::IMP}, {ill, md::IMP}, {ill, md::IMP},
- {ill, md::IMP}, {ill, md::IMP}, {ill, md::IMP}, {ill, md::IMP},
- {ill, md::IMP}, {ill, md::IMP}, {ill, md::IMP}, {ill, md::IMP},
- {ill, md::IMP}, {ill, md::IMP}, {ill, md::IMP}, {ill, md::IMP}, // 90
- {ill, md::IMP}, {ill, md::IMP}, {ill, md::IMP}, {tax, md::IMP},
- {clc, md::IMP}, {sec, md::IMP}, {cli, md::IMP}, {sei, md::IMP},
- {rsp, md::IMP}, {nop, md::IMP}, {ill, md::IMP}, {txa, md::IMP},
- {suba, md::IMM}, {cmpa, md::IMM}, {sbca, md::IMM}, {cpx, md::IMM}, // a0
- {anda, md::IMM}, {bita, md::IMM}, {lda, md::IMM}, {ill, md::IMP},
- {eora, md::IMM}, {adca, md::IMM}, {ora, md::IMM}, {adda, md::IMM},
- {ill, md::IMP}, {bsr, md::REL}, {ldx, md::IMM}, {ill, md::IMP},
- {suba, md::DIR}, {cmpa, md::DIR}, {sbca, md::DIR}, {cpx, md::DIR}, // b0
- {anda, md::DIR}, {bita, md::DIR}, {lda, md::DIR}, {sta, md::DIR},
- {eora, md::DIR}, {adca, md::DIR}, {ora, md::DIR}, {adda, md::DIR},
- {jmp, md::DIR}, {jsr, md::DIR}, {ldx, md::DIR}, {stx, md::DIR},
- {suba, md::EXT}, {cmpa, md::EXT}, {sbca, md::EXT}, {cpx, md::EXT}, // c0
- {anda, md::EXT}, {bita, md::EXT}, {lda, md::EXT}, {sta, md::EXT},
- {eora, md::EXT}, {adca, md::EXT}, {ora, md::EXT}, {adda, md::EXT},
- {jmp, md::EXT}, {jsr, md::EXT}, {ldx, md::EXT}, {stx, md::EXT},
- {suba, md::IX2}, {cmpa, md::IX2}, {sbca, md::IX2}, {cpx, md::IX2}, // d0
- {anda, md::IX2}, {bita, md::IX2}, {lda, md::IX2}, {sta, md::IX2},
- {eora, md::IX2}, {adca, md::IX2}, {ora, md::IX2}, {adda, md::IX2},
- {jmp, md::IX2}, {jsr, md::IX2}, {ldx, md::IX2}, {stx, md::IX2},
- {suba, md::IX1}, {cmpa, md::IX1}, {sbca, md::IX1}, {cpx, md::IX1}, // e0
- {anda, md::IX1}, {bita, md::IX1}, {lda, md::IX1}, {sta, md::IX1},
- {eora, md::IX1}, {adca, md::IX1}, {ora, md::IX1}, {adda, md::IX1},
- {jmp, md::IX1}, {jsr, md::IX1}, {ldx, md::IX1}, {stx, md::IX1},
- {suba, md::IDX}, {cmpa, md::IDX}, {sbca, md::IDX}, {cpx, md::IDX}, // f0
- {anda, md::IDX}, {bita, md::IDX}, {lda, md::IDX}, {sta, md::IDX},
- {eora, md::IDX}, {adca, md::IDX}, {ora, md::IDX}, {adda, md::IDX},
- {jmp, md::IDX}, {jsr, md::IDX}, {ldx, md::IDX}, {stx, md::IDX}
-};
-
-#if 0
-char const *const opcode_strings[0x0100] =
-{
- "brset0", "brclr0", "brset1", "brclr1", "brset2", "brclr2", "brset3", "brclr3", /*00*/
- "brset4", "brclr4", "brset5", "brclr5", "brset6", "brclr6", "brset7", "brclr7",
- "bset0", "bclr0", "bset1", "bclr1", "bset2", "bclr2", "bset3", "bclr3", /*10*/
- "bset4", "bclr4", "bset5", "bclr5", "bset6", "bclr6", "bset7", "bclr7",
- "bra", "brn", "bhi", "bls", "bcc", "bcs", "bne", "beq", /*20*/
- "bhcc", "bhcs", "bpl", "bmi", "bmc", "bms", "bil", "bih",
- "neg_di", "illegal", "illegal", "com_di", "lsr_di", "illegal", "ror_di", "asr_di", /*30*/
- "asl_di", "rol_di", "dec_di", "illegal", "inc_di", "tst_di", "illegal", "clr_di",
- "nega", "illegal", "illegal", "coma", "lsra", "illegal", "rora", "asra", /*40*/
- "asla", "rola", "deca", "illegal", "inca", "tsta", "illegal", "clra",
- "negx", "illegal", "illegal", "comx", "lsrx", "illegal", "rorx", "asrx", /*50*/
- "aslx", "rolx", "decx", "illegal", "incx", "tstx", "illegal", "clrx",
- "neg_ix1", "illegal", "illegal", "com_ix1", "lsr_ix1", "illegal", "ror_ix1", "asr_ix1", /*60*/
- "asl_ix1", "rol_ix1", "dec_ix1", "illegal", "inc_ix1", "tst_ix1", "jmp_ix1", "clr_ix1",
- "neg_ix", "illegal", "illegal", "com_ix", "lsr_ix", "illegal", "ror_ix", "asr_ix", /*70*/
- "asl_ix", "rol_ix", "dec_ix", "illegal", "inc_ix", "tst_ix", "jmp_ix", "clr_ix",
- "rti", "rts", "illegal", "swi", "illegal", "illegal", "illegal", "illegal", /*80*/
- "illegal", "illegal", "illegal", "illegal", "illegal", "illegal", "illegal", "illegal",
- "illegal", "illegal", "illegal", "illegal", "illegal", "illegal", "illegal", "tax", /*90*/
- "clc", "sec", "cli", "sei", "rsp", "nop", "illegal", "txa",
- "suba_im", "cmpa_im", "sbca_im", "cpx_im", "anda_im", "bita_im", "lda_im", "illegal", /*A0*/
- "eora_im", "adca_im", "ora_im", "adda_im", "illegal", "bsr", "ldx_im", "illegal",
- "suba_di", "cmpa_di", "sbca_di", "cpx_di", "anda_di", "bita_di", "lda_di", "sta_di", /*B0*/
- "eora_di", "adca_di", "ora_di", "adda_di", "jmp_di", "jsr_di", "ldx_di", "stx_di",
- "suba_ex", "cmpa_ex", "sbca_ex", "cpx_ex", "anda_ex", "bita_ex", "lda_ex", "sta_ex", /*C0*/
- "eora_ex", "adca_ex", "ora_ex", "adda_ex", "jmp_ex", "jsr_ex", "ldx_ex", "stx_ex",
- "suba_ix2", "cmpa_ix2", "sbca_ix2", "cpx_ix2", "anda_ix2", "bita_ix2", "lda_ix2", "sta_ix2", /*D0*/
- "eora_ix2", "adca_ix2", "ora_ix2", "adda_ix2", "jmp_ix2", "jsr_ix2", "ldx_ix2", "stx_ix2",
- "suba_ix1", "cmpa_ix1", "sbca_ix1", "cpx_ix1", "anda_ix1", "bita_ix1", "lda_ix1", "sta_ix1", /*E0*/
- "eora_ix1", "adca_ix1", "ora_ix1", "adda_ix1", "jmp_ix1", "jsr_ix1", "ldx_ix1", "stx_ix1",
- "suba_ix", "cmpa_ix", "sbca_ix", "cpx_ix", "anda_ix", "bita_ix", "lda_ix", "sta_ix", /*F0*/
- "eora_ix", "adca_ix", "ora_ix", "adda_ix", "jmp_ix", "jsr_ix", "ldx_ix", "stx_ix"
+#define OP(name, mode) { name, #name, md::mode, lvl::HMOS }
+#define OPC(name, mode) { name, #name, md::mode, lvl::CMOS }
+#define OPHC(name, mode) { name, #name, md::mode, lvl::HC }
+#define ILLEGAL { ill, nullptr, md::INH, lvl::HMOS }
+struct { op_names op; char const *name; md mode; lvl level; } const disasm[0x100] = {
+ OP (brset,BTR), OP (brclr,BTR), OP (brset,BTR), OP (brclr,BTR), // 00
+ OP (brset,BTR), OP (brclr,BTR), OP (brset,BTR), OP (brclr,BTR),
+ OP (brset,BTR), OP (brclr,BTR), OP (brset,BTR), OP (brclr,BTR),
+ OP (brset,BTR), OP (brclr,BTR), OP (brset,BTR), OP (brclr,BTR),
+ OP (bset, BIT), OP (bclr, BIT), OP (bset, BIT), OP (bclr, BIT), // 10
+ OP (bset, BIT), OP (bclr, BIT), OP (bset, BIT), OP (bclr, BIT),
+ OP (bset, BIT), OP (bclr, BIT), OP (bset, BIT), OP (bclr, BIT),
+ OP (bset, BIT), OP (bclr, BIT), OP (bset, BIT), OP (bclr, BIT),
+ OP (bra, REL), OP (brn, REL), OP (bhi, REL), OP (bls, REL), // 20
+ OP (bcc, REL), OP (bcs, REL), OP (bne, REL), OP (beq, REL),
+ OP (bhcc, REL), OP (bhcs, REL), OP (bpl, REL), OP (bmi, REL),
+ OP (bmc, REL), OP (bms, REL), OP (bil, REL), OP (bih, REL),
+ OP (neg, DIR), ILLEGAL , ILLEGAL , OP (com, DIR), // 30
+ OP (lsr, DIR), ILLEGAL , OP (ror, DIR), OP (asr, DIR),
+ OP (asl, DIR), OP (rol, DIR), OP (dec, DIR), ILLEGAL ,
+ OP (inc, DIR), OP (tst, DIR), ILLEGAL , OP (clr, DIR),
+ OP (nega, INH), ILLEGAL , OPHC(mul, INH), OP (coma, INH), // 40
+ OP (lsra, INH), ILLEGAL , OP (rora, INH), OP (asra, INH),
+ OP (asla, INH), OP (rola, INH), OP (deca, INH), ILLEGAL ,
+ OP (inca, INH), OP (tsta, INH), ILLEGAL , OP (clra, INH),
+ OP (negx, INH), ILLEGAL , ILLEGAL , OP (comx, INH), // 50
+ OP (lsrx, INH), ILLEGAL , OP (rorx, INH), OP (asrx, INH),
+ OP (aslx, INH), OP (rolx, INH), OP (decx, INH), ILLEGAL ,
+ OP (incx, INH), OP (tstx, INH), ILLEGAL , OP (clrx, INH),
+ OP (neg, IX1), ILLEGAL , ILLEGAL , OP (com, IX1), // 60
+ OP (lsr, IX1), ILLEGAL , OP (ror, IX1), OP (asr, IX1),
+ OP (asl, IX1), OP (rol, IX1), OP (dec, IX1), ILLEGAL ,
+ OP (inc, IX1), OP (tst, IX1), OP (jmp, IX1), OP (clr, IX1),
+ OP (neg, IDX), ILLEGAL , ILLEGAL , OP (com, IDX), // 70
+ OP (lsr, IDX), ILLEGAL , OP (ror, IDX), OP (asr, IDX),
+ OP (asl, IDX), OP (rol, IDX), OP (dec, IDX), ILLEGAL ,
+ OP (inc, IDX), OP (tst, IDX), OP (jmp, IDX), OP (clr, IDX),
+ OP (rti, INH), OP (rts, INH), ILLEGAL , OP (swi, INH), // 80
+ ILLEGAL , ILLEGAL , ILLEGAL , ILLEGAL ,
+ ILLEGAL , ILLEGAL , ILLEGAL , ILLEGAL ,
+ ILLEGAL , ILLEGAL , OPC (stop, INH), OPC (wait, INH),
+ ILLEGAL , ILLEGAL , ILLEGAL , ILLEGAL , // 90
+ ILLEGAL , ILLEGAL , ILLEGAL , OP (tax, INH),
+ OP (clc, INH), OP (sec, INH), OP (cli, INH), OP (sei, INH),
+ OP (rsp, INH), OP (nop, INH), ILLEGAL , OP (txa, INH),
+ OP (suba, IMM), OP (cmpa, IMM), OP (sbca, IMM), OP (cpx, IMM), // a0
+ OP (anda, IMM), OP (bita, IMM), OP (lda, IMM), ILLEGAL ,
+ OP (eora, IMM), OP (adca, IMM), OP (ora, IMM), OP (adda, IMM),
+ ILLEGAL , OP (bsr, REL), OP (ldx, IMM), ILLEGAL ,
+ OP (suba, DIR), OP (cmpa, DIR), OP (sbca, DIR), OP (cpx, DIR), // b0
+ OP (anda, DIR), OP (bita, DIR), OP (lda, DIR), OP (sta, DIR),
+ OP (eora, DIR), OP (adca, DIR), OP (ora, DIR), OP (adda, DIR),
+ OP (jmp, DIR), OP (jsr, DIR), OP (ldx, DIR), OP (stx, DIR),
+ OP (suba, EXT), OP (cmpa, EXT), OP (sbca, EXT), OP (cpx, EXT), // c0
+ OP (anda, EXT), OP (bita, EXT), OP (lda, EXT), OP (sta, EXT),
+ OP (eora, EXT), OP (adca, EXT), OP (ora, EXT), OP (adda, EXT),
+ OP (jmp, EXT), OP (jsr, EXT), OP (ldx, EXT), OP (stx, EXT),
+ OP (suba, IX2), OP (cmpa, IX2), OP (sbca, IX2), OP (cpx, IX2), // d0
+ OP (anda, IX2), OP (bita, IX2), OP (lda, IX2), OP (sta, IX2),
+ OP (eora, IX2), OP (adca, IX2), OP (ora, IX2), OP (adda, IX2),
+ OP (jmp, IX2), OP (jsr, IX2), OP (ldx, IX2), OP (stx, IX2),
+ OP (suba, IX1), OP (cmpa, IX1), OP (sbca, IX1), OP (cpx, IX1), // e0
+ OP (anda, IX1), OP (bita, IX1), OP (lda, IX1), OP (sta, IX1),
+ OP (eora, IX1), OP (adca, IX1), OP (ora, IX1), OP (adda, IX1),
+ OP (jmp, IX1), OP (jsr, IX1), OP (ldx, IX1), OP (stx, IX1),
+ OP (suba, IDX), OP (cmpa, IDX), OP (sbca, IDX), OP (cpx, IDX), // f0
+ OP (anda, IDX), OP (bita, IDX), OP (lda, IDX), OP (sta, IDX),
+ OP (eora, IDX), OP (adca, IDX), OP (ora, IDX), OP (adda, IDX),
+ OP (jmp, IDX), OP (jsr, IDX), OP (ldx, IDX), OP (stx, IDX)
};
-#endif
template <typename T>
@@ -182,90 +140,142 @@ void format_address(
util::stream_format(stream, "$%0*X", 2 * sizeof(T), address);
}
-} // anonymous namespace
-
-offs_t CPU_DISASSEMBLE_NAME(m6805)(
+offs_t disassemble(
cpu_device *device,
std::ostream &stream,
offs_t pc,
const u8 *oprom,
const u8 *opram,
int options,
+ lvl level,
std::pair<u16, char const *> const symbols[],
std::size_t symbol_count)
{
u8 const code = oprom[0];
- u32 flags = 0;
- switch (disasm[code].op)
+ if (!disasm[code].name || (disasm[code].level > level))
{
- case bsr:
- case jsr:
- flags = DASMFLAG_STEP_OVER;
- break;
- case rts:
- case rti:
- flags = DASMFLAG_STEP_OUT;
- break;
+ util::stream_format(stream, "%-6s$%02X", "fcb", code);
+ return 1 | DASMFLAG_SUPPORTED;
}
+ else
+ {
+ u32 flags;
+ switch (disasm[code].op)
+ {
+ case bsr:
+ case jsr:
+ flags = DASMFLAG_STEP_OVER;
+ break;
+ case rts:
+ case rti:
+ flags = DASMFLAG_STEP_OUT;
+ break;
+ default:
+ flags = 0;
+ }
- util::stream_format(stream, "%-6s", op_name_str[disasm[code].op]);
+ util::stream_format(stream, "%-6s", disasm[code].name);
- int bit;
- u16 ea;
- switch (disasm[code].mode)
- {
- case md::IMP: // implicit
- return 1 | flags | DASMFLAG_SUPPORTED;
+ int bit;
+ u16 ea;
+ switch (disasm[code].mode)
+ {
+ case md::INH: // inherent
+ return 1 | flags | DASMFLAG_SUPPORTED;
- case md::BTR: // bit test and relative branch
- bit = (code >> 1) & 7;
- util::stream_format(stream, "%d,", bit);
- format_address(stream, opram[1], symbols, symbol_count);
- util::stream_format(stream, ",$%03X", pc + 3 + s8(opram[2]));
- return 3 | flags | DASMFLAG_SUPPORTED;
+ case md::BTR: // bit test and relative branch
+ bit = (code >> 1) & 7;
+ util::stream_format(stream, "%d,", bit);
+ format_address(stream, opram[1], symbols, symbol_count);
+ util::stream_format(stream, ",$%03X", pc + 3 + s8(opram[2]));
+ return 3 | flags | DASMFLAG_SUPPORTED;
- case md::BIT: // bit test
- bit = (code >> 1) & 7;
- util::stream_format(stream, "%d,", bit);
- format_address(stream, opram[1], symbols, symbol_count);
- return 2 | flags | DASMFLAG_SUPPORTED;
+ case md::BIT: // bit test
+ bit = (code >> 1) & 7;
+ util::stream_format(stream, "%d,", bit);
+ format_address(stream, opram[1], symbols, symbol_count);
+ return 2 | flags | DASMFLAG_SUPPORTED;
- case md::REL: // relative
- util::stream_format(stream, "$%03X", pc + 2 + s8(opram[1]));
- return 2 | flags | DASMFLAG_SUPPORTED;
+ case md::REL: // relative
+ util::stream_format(stream, "$%03X", pc + 2 + s8(opram[1]));
+ return 2 | flags | DASMFLAG_SUPPORTED;
- case md::IMM: // immediate
- util::stream_format(stream, "#$%02X", opram[1]);
- return 2 | flags | DASMFLAG_SUPPORTED;
+ case md::IMM: // immediate
+ util::stream_format(stream, "#$%02X", opram[1]);
+ return 2 | flags | DASMFLAG_SUPPORTED;
- case md::DIR: // direct (zero page address)
- format_address(stream, opram[1], symbols, symbol_count);
- return 2 | flags | DASMFLAG_SUPPORTED;
+ case md::DIR: // direct (zero page address)
+ format_address(stream, opram[1], symbols, symbol_count);
+ return 2 | flags | DASMFLAG_SUPPORTED;
- case md::EXT: // extended (16 bit address)
- ea = (opram[1] << 8) + opram[2];
- format_address(stream, ea, symbols, symbol_count);
- return 3 | flags | DASMFLAG_SUPPORTED;
+ case md::EXT: // extended (16 bit address)
+ ea = (opram[1] << 8) + opram[2];
+ format_address(stream, ea, symbols, symbol_count);
+ return 3 | flags | DASMFLAG_SUPPORTED;
- case md::IDX: // indexed
- util::stream_format(stream, "(x)");
- return 1 | flags | DASMFLAG_SUPPORTED;
+ case md::IDX: // indexed
+ util::stream_format(stream, "(x)");
+ return 1 | flags | DASMFLAG_SUPPORTED;
- case md::IX1: // indexed + byte (zero page)
- util::stream_format(stream, "(x+$%02X)", opram[1]);
- return 2 | flags | DASMFLAG_SUPPORTED;
+ case md::IX1: // indexed + byte (zero page)
+ util::stream_format(stream, "(x+$%02X)", opram[1]);
+ return 2 | flags | DASMFLAG_SUPPORTED;
- case md::IX2: // indexed + word (16 bit address)
- ea = (opram[1] << 8) + opram[2];
- util::stream_format(stream, "(x+$%04X)", ea);
- return 3 | flags | DASMFLAG_SUPPORTED;
+ case md::IX2: // indexed + word (16 bit address)
+ ea = (opram[1] << 8) + opram[2];
+ util::stream_format(stream, "(x+$%04X)", ea);
+ return 3 | flags | DASMFLAG_SUPPORTED;
+ }
+
+ // if we fall off the switch statement something is very wrong
+ throw false;
}
+}
+
+} // anonymous namespace
+
- // if we fall off the switch statement something is very wrong
- throw false;
+offs_t CPU_DISASSEMBLE_NAME(m6805)(
+ cpu_device *device,
+ std::ostream &stream,
+ offs_t pc,
+ const u8 *oprom,
+ const u8 *opram,
+ int options,
+ std::pair<u16, char const *> const symbols[],
+ std::size_t symbol_count)
+{
+ return disassemble(device, stream, pc, oprom, opram, options, lvl::HMOS, symbols, symbol_count);
+}
+
+offs_t CPU_DISASSEMBLE_NAME(m146805)(
+ cpu_device *device,
+ std::ostream &stream,
+ offs_t pc,
+ const u8 *oprom,
+ const u8 *opram,
+ int options,
+ std::pair<u16, char const *> const symbols[],
+ std::size_t symbol_count)
+{
+ return disassemble(device, stream, pc, oprom, opram, options, lvl::CMOS, symbols, symbol_count);
}
+offs_t CPU_DISASSEMBLE_NAME(m68hc05)(
+ cpu_device *device,
+ std::ostream &stream,
+ offs_t pc,
+ const u8 *oprom,
+ const u8 *opram,
+ int options,
+ std::pair<u16, char const *> const symbols[],
+ std::size_t symbol_count)
+{
+ return disassemble(device, stream, pc, oprom, opram, options, lvl::HC, symbols, symbol_count);
+}
-CPU_DISASSEMBLE(m6805) { return CPU_DISASSEMBLE_NAME(m6805)(device, stream, pc, oprom, opram, options, nullptr, 0); }
+CPU_DISASSEMBLE(m6805) { return CPU_DISASSEMBLE_NAME(m6805) (device, stream, pc, oprom, opram, options, nullptr, 0); }
+CPU_DISASSEMBLE(m146805) { return CPU_DISASSEMBLE_NAME(m146805)(device, stream, pc, oprom, opram, options, nullptr, 0); }
+CPU_DISASSEMBLE(m68hc05) { return CPU_DISASSEMBLE_NAME(m68hc05)(device, stream, pc, oprom, opram, options, nullptr, 0); }
diff --git a/src/devices/cpu/m6805/6805ops.hxx b/src/devices/cpu/m6805/6805ops.hxx
index b00e5181b93..f7082cf8bfa 100644
--- a/src/devices/cpu/m6805/6805ops.hxx
+++ b/src/devices/cpu/m6805/6805ops.hxx
@@ -291,7 +291,14 @@ OP_HANDLER( nega )
// $41 ILLEGAL
-// $42 ILLEGAL
+// $42 MUL inherent 0--0
+OP_HANDLER( mul )
+{
+ u16 const r = u16(A) * X;
+ clr_hc();
+ X = u8(r >> 8);
+ A = u8(r);
+}
// $43 COMA inherent -**1
OP_HANDLER( coma )
@@ -519,17 +526,7 @@ OP_HANDLER( swi )
pushbyte(m_a);
pushbyte(m_cc);
SEI;
- rm16(0xfffc, m_pc);
-}
-
-DERIVED_OP_HANDLER( hd63705, swi )
-{
- pushword(m_pc);
- pushbyte(m_x);
- pushbyte(m_a);
- pushbyte(m_cc);
- SEI;
- rm16(0x1ffa, m_pc);
+ rm16(m_params.m_swi_vector, m_pc);
}
// $84 ILLEGAL
@@ -552,9 +549,18 @@ DERIVED_OP_HANDLER( hd63705, swi )
// $8D ILLEGAL
-// $8E ILLEGAL
+// $8E STOP inherent ----
+OP_HANDLER( stop )
+{
+ fatalerror("m6805: unimplemented STOP");
+}
+
+// $8F WAIT inherent ----
+OP_HANDLER( wait )
+{
+ fatalerror("m6805: unimplemented WAIT");
+}
-// $8F ILLEGAL
// $90 ILLEGAL
diff --git a/src/devices/cpu/m6805/m6805.cpp b/src/devices/cpu/m6805/m6805.cpp
index d41db038d3e..05dfb07e2ef 100644
--- a/src/devices/cpu/m6805/m6805.cpp
+++ b/src/devices/cpu/m6805/m6805.cpp
@@ -49,7 +49,8 @@
#define OP_IX(name) (&m6805_base_device::name<addr_mode::IX>)
#define OP_IX1(name) (&m6805_base_device::name<addr_mode::IX1>)
#define OP_IX2(name) (&m6805_base_device::name<addr_mode::IX2>)
-const m6805_base_device::op_handler_func m6805_base_device::m_hmos_ops[256] =
+
+const m6805_base_device::op_handler_table m6805_base_device::s_hmos_ops =
{
/* 0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F */
/* 0 */ OP(brset<0>),OP(brclr<0>),OP(brset<1>),OP(brclr<1>),OP(brset<2>),OP(brclr<2>),OP(brset<3>),OP(brclr<3>),
@@ -86,8 +87,82 @@ const m6805_base_device::op_handler_func m6805_base_device::m_hmos_ops[256] =
OP_IX(eora), OP_IX(adca), OP_IX(ora), OP_IX(adda), OP_IX(jmp), OP_IX(jsr), OP_IX(ldx), OP_IX(stx)
};
+const m6805_base_device::op_handler_table m6805_base_device::s_cmos_ops =
+{
+ /* 0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F */
+ /* 0 */ OP(brset<0>),OP(brclr<0>),OP(brset<1>),OP(brclr<1>),OP(brset<2>),OP(brclr<2>),OP(brset<3>),OP(brclr<3>),
+ OP(brset<4>),OP(brclr<4>),OP(brset<5>),OP(brclr<5>),OP(brset<6>),OP(brclr<6>),OP(brset<7>),OP(brclr<7>),
+ /* 1 */ OP(bset<0>), OP(bclr<0>), OP(bset<1>), OP(bclr<1>), OP(bset<2>), OP(bclr<2>), OP(bset<3>), OP(bclr<3>),
+ OP(bset<4>), OP(bclr<4>), OP(bset<5>), OP(bclr<5>), OP(bset<6>), OP(bclr<6>), OP(bset<7>), OP(bclr<7>),
+ /* 2 */ OP_T(bra), OP_F(bra), OP_T(bhi), OP_F(bhi), OP_T(bcc), OP_F(bcc), OP_T(bne), OP_F(bne),
+ OP_T(bhcc), OP_F(bhcc), OP_T(bpl), OP_F(bpl), OP_T(bmc), OP_F(bmc), OP(bil), OP(bih),
+ /* 3 */ OP_DI(neg), OP(illegal), OP(illegal), OP_DI(com), OP_DI(lsr), OP(illegal), OP_DI(ror), OP_DI(asr),
+ OP_DI(lsl), OP_DI(rol), OP_DI(dec), OP(illegal), OP_DI(inc), OP_DI(tst), OP(illegal), OP_DI(clr),
+ /* 4 */ OP(nega), OP(illegal), OP(illegal), OP(coma), OP(lsra), OP(illegal), OP(rora), OP(asra),
+ OP(lsla), OP(rola), OP(deca), OP(illegal), OP(inca), OP(tsta), OP(illegal), OP(clra),
+ /* 5 */ OP(negx), OP(illegal), OP(illegal), OP(comx), OP(lsrx), OP(illegal), OP(rorx), OP(asrx),
+ OP(lslx), OP(rolx), OP(decx), OP(illegal), OP(incx), OP(tstx), OP(illegal), OP(clrx),
+ /* 6 */ OP_IX1(neg), OP(illegal), OP(illegal), OP_IX1(com), OP_IX1(lsr), OP(illegal), OP_IX1(ror), OP_IX1(asr),
+ OP_IX1(lsl), OP_IX1(rol), OP_IX1(dec), OP(illegal), OP_IX1(inc), OP_IX1(tst), OP(illegal), OP_IX1(clr),
+ /* 7 */ OP_IX(neg), OP(illegal), OP(illegal), OP_IX(com), OP_IX(lsr), OP(illegal), OP_IX(ror), OP_IX(asr),
+ OP_IX(lsl), OP_IX(rol), OP_IX(dec), OP(illegal), OP_IX(inc), OP_IX(tst), OP(illegal), OP_IX(clr),
+ /* 8 */ OP(rti), OP(rts), OP(illegal), OP(swi), OP(illegal), OP(illegal), OP(illegal), OP(illegal),
+ OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(stop), OP(wait),
+ /* 9 */ OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(tax),
+ OP(clc), OP(sec), OP(cli), OP(sei), OP(rsp), OP(nop), OP(illegal), OP(txa),
+ /* A */ OP_IM(suba), OP_IM(cmpa), OP_IM(sbca), OP_IM(cpx), OP_IM(anda), OP_IM(bita), OP_IM(lda), OP(illegal),
+ OP_IM(eora), OP_IM(adca), OP_IM(ora), OP_IM(adda), OP(illegal), OP(bsr), OP_IM(ldx), OP(illegal),
+ /* B */ OP_DI(suba), OP_DI(cmpa), OP_DI(sbca), OP_DI(cpx), OP_DI(anda), OP_DI(bita), OP_DI(lda), OP_DI(sta),
+ OP_DI(eora), OP_DI(adca), OP_DI(ora), OP_DI(adda), OP_DI(jmp), OP_DI(jsr), OP_DI(ldx), OP_DI(stx),
+ /* C */ OP_EX(suba), OP_EX(cmpa), OP_EX(sbca), OP_EX(cpx), OP_EX(anda), OP_EX(bita), OP_EX(lda), OP_EX(sta),
+ OP_EX(eora), OP_EX(adca), OP_EX(ora), OP_EX(adda), OP_EX(jmp), OP_EX(jsr), OP_EX(ldx), OP_EX(stx),
+ /* D */ OP_IX2(suba),OP_IX2(cmpa),OP_IX2(sbca),OP_IX2(cpx), OP_IX2(anda),OP_IX2(bita),OP_IX2(lda), OP_IX2(sta),
+ OP_IX2(eora),OP_IX2(adca),OP_IX2(ora), OP_IX2(adda),OP_IX2(jmp), OP_IX2(jsr), OP_IX2(ldx), OP_IX2(stx),
+ /* E */ OP_IX1(suba),OP_IX1(cmpa),OP_IX1(sbca),OP_IX1(cpx), OP_IX1(anda),OP_IX1(bita),OP_IX1(lda), OP_IX1(sta),
+ OP_IX1(eora),OP_IX1(adca),OP_IX1(ora), OP_IX1(adda),OP_IX1(jmp), OP_IX1(jsr), OP_IX1(ldx), OP_IX1(stx),
+ /* F */ OP_IX(suba), OP_IX(cmpa), OP_IX(sbca), OP_IX(cpx), OP_IX(anda), OP_IX(bita), OP_IX(lda), OP_IX(sta),
+ OP_IX(eora), OP_IX(adca), OP_IX(ora), OP_IX(adda), OP_IX(jmp), OP_IX(jsr), OP_IX(ldx), OP_IX(stx)
+};
+
+const m6805_base_device::op_handler_table m6805_base_device::s_hc_ops =
+{
+ /* 0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F */
+ /* 0 */ OP(brset<0>),OP(brclr<0>),OP(brset<1>),OP(brclr<1>),OP(brset<2>),OP(brclr<2>),OP(brset<3>),OP(brclr<3>),
+ OP(brset<4>),OP(brclr<4>),OP(brset<5>),OP(brclr<5>),OP(brset<6>),OP(brclr<6>),OP(brset<7>),OP(brclr<7>),
+ /* 1 */ OP(bset<0>), OP(bclr<0>), OP(bset<1>), OP(bclr<1>), OP(bset<2>), OP(bclr<2>), OP(bset<3>), OP(bclr<3>),
+ OP(bset<4>), OP(bclr<4>), OP(bset<5>), OP(bclr<5>), OP(bset<6>), OP(bclr<6>), OP(bset<7>), OP(bclr<7>),
+ /* 2 */ OP_T(bra), OP_F(bra), OP_T(bhi), OP_F(bhi), OP_T(bcc), OP_F(bcc), OP_T(bne), OP_F(bne),
+ OP_T(bhcc), OP_F(bhcc), OP_T(bpl), OP_F(bpl), OP_T(bmc), OP_F(bmc), OP(bil), OP(bih),
+ /* 3 */ OP_DI(neg), OP(illegal), OP(illegal), OP_DI(com), OP_DI(lsr), OP(illegal), OP_DI(ror), OP_DI(asr),
+ OP_DI(lsl), OP_DI(rol), OP_DI(dec), OP(illegal), OP_DI(inc), OP_DI(tst), OP(illegal), OP_DI(clr),
+ /* 4 */ OP(nega), OP(illegal), OP(mul), OP(coma), OP(lsra), OP(illegal), OP(rora), OP(asra),
+ OP(lsla), OP(rola), OP(deca), OP(illegal), OP(inca), OP(tsta), OP(illegal), OP(clra),
+ /* 5 */ OP(negx), OP(illegal), OP(illegal), OP(comx), OP(lsrx), OP(illegal), OP(rorx), OP(asrx),
+ OP(lslx), OP(rolx), OP(decx), OP(illegal), OP(incx), OP(tstx), OP(illegal), OP(clrx),
+ /* 6 */ OP_IX1(neg), OP(illegal), OP(illegal), OP_IX1(com), OP_IX1(lsr), OP(illegal), OP_IX1(ror), OP_IX1(asr),
+ OP_IX1(lsl), OP_IX1(rol), OP_IX1(dec), OP(illegal), OP_IX1(inc), OP_IX1(tst), OP(illegal), OP_IX1(clr),
+ /* 7 */ OP_IX(neg), OP(illegal), OP(illegal), OP_IX(com), OP_IX(lsr), OP(illegal), OP_IX(ror), OP_IX(asr),
+ OP_IX(lsl), OP_IX(rol), OP_IX(dec), OP(illegal), OP_IX(inc), OP_IX(tst), OP(illegal), OP_IX(clr),
+ /* 8 */ OP(rti), OP(rts), OP(illegal), OP(swi), OP(illegal), OP(illegal), OP(illegal), OP(illegal),
+ OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(stop), OP(wait),
+ /* 9 */ OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(tax),
+ OP(clc), OP(sec), OP(cli), OP(sei), OP(rsp), OP(nop), OP(illegal), OP(txa),
+ /* A */ OP_IM(suba), OP_IM(cmpa), OP_IM(sbca), OP_IM(cpx), OP_IM(anda), OP_IM(bita), OP_IM(lda), OP(illegal),
+ OP_IM(eora), OP_IM(adca), OP_IM(ora), OP_IM(adda), OP(illegal), OP(bsr), OP_IM(ldx), OP(illegal),
+ /* B */ OP_DI(suba), OP_DI(cmpa), OP_DI(sbca), OP_DI(cpx), OP_DI(anda), OP_DI(bita), OP_DI(lda), OP_DI(sta),
+ OP_DI(eora), OP_DI(adca), OP_DI(ora), OP_DI(adda), OP_DI(jmp), OP_DI(jsr), OP_DI(ldx), OP_DI(stx),
+ /* C */ OP_EX(suba), OP_EX(cmpa), OP_EX(sbca), OP_EX(cpx), OP_EX(anda), OP_EX(bita), OP_EX(lda), OP_EX(sta),
+ OP_EX(eora), OP_EX(adca), OP_EX(ora), OP_EX(adda), OP_EX(jmp), OP_EX(jsr), OP_EX(ldx), OP_EX(stx),
+ /* D */ OP_IX2(suba),OP_IX2(cmpa),OP_IX2(sbca),OP_IX2(cpx), OP_IX2(anda),OP_IX2(bita),OP_IX2(lda), OP_IX2(sta),
+ OP_IX2(eora),OP_IX2(adca),OP_IX2(ora), OP_IX2(adda),OP_IX2(jmp), OP_IX2(jsr), OP_IX2(ldx), OP_IX2(stx),
+ /* E */ OP_IX1(suba),OP_IX1(cmpa),OP_IX1(sbca),OP_IX1(cpx), OP_IX1(anda),OP_IX1(bita),OP_IX1(lda), OP_IX1(sta),
+ OP_IX1(eora),OP_IX1(adca),OP_IX1(ora), OP_IX1(adda),OP_IX1(jmp), OP_IX1(jsr), OP_IX1(ldx), OP_IX1(stx),
+ /* F */ OP_IX(suba), OP_IX(cmpa), OP_IX(sbca), OP_IX(cpx), OP_IX(anda), OP_IX(bita), OP_IX(lda), OP_IX(sta),
+ OP_IX(eora), OP_IX(adca), OP_IX(ora), OP_IX(adda), OP_IX(jmp), OP_IX(jsr), OP_IX(ldx), OP_IX(stx)
+};
+
-const uint8_t m6805_base_device::m_hmos_cycles[] =
+const m6805_base_device::cycle_count_table m6805_base_device::s_hmos_cycles =
{
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
/*0*/ 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
@@ -108,14 +183,14 @@ const uint8_t m6805_base_device::m_hmos_cycles[] =
/*F*/ 4, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, 4, 3, 7, 4, 5
};
-const uint8_t m6805_base_device::m_cmos_cycles[] =
+const m6805_base_device::cycle_count_table m6805_base_device::s_cmos_cycles =
{
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
/*0*/ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
/*1*/ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
/*2*/ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
/*3*/ 5, 0, 0, 5, 5, 0, 5, 5, 5, 5, 5, 0, 5, 4, 0, 5,
- /*4*/ 3, 0,11, 3, 3, 0, 3, 3, 3, 3, 3, 0, 3, 3, 0, 3,
+ /*4*/ 3, 0, 0, 3, 3, 0, 3, 3, 3, 3, 3, 0, 3, 3, 0, 3,
/*5*/ 3, 0, 0, 3, 3, 0, 3, 3, 3, 3, 3, 0, 3, 3, 0, 3,
/*6*/ 6, 0, 0, 6, 6, 0, 6, 6, 6, 6, 6, 0, 6, 5, 0, 6,
/*7*/ 5, 0, 0, 5, 5, 0, 5, 5, 5, 5, 5, 0, 5, 4, 0, 5,
@@ -129,137 +204,62 @@ const uint8_t m6805_base_device::m_cmos_cycles[] =
/*F*/ 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 2, 5, 3, 4
};
-
-void m6805_base_device::interrupt_vector()
-{
- rm16(0xfffa, m_pc);
-}
-
-void m68hc05eg_device::interrupt_vector()
-{
- if ((m_pending_interrupts & (1 << M68HC05EG_INT_IRQ)) != 0)
- {
- m_pending_interrupts &= ~(1 << M68HC05EG_INT_IRQ);
- rm16(0x1ffa, m_pc);
- }
- else if((m_pending_interrupts & (1 << M68HC05EG_INT_TIMER)) != 0)
- {
- m_pending_interrupts &= ~(1 << M68HC05EG_INT_TIMER);
- rm16(0x1ff8, m_pc);
- }
- else if((m_pending_interrupts & (1 << M68HC05EG_INT_CPI)) != 0)
- {
- m_pending_interrupts &= ~(1 << M68HC05EG_INT_CPI);
- rm16(0x1ff6, m_pc);
- }
-}
-
-void hd63705_device::interrupt_vector()
-{
- /* Need to add emulation of other interrupt sources here KW-2/4/99 */
- /* This is just a quick patch for Namco System 2 operation */
-
- if ((m_pending_interrupts & (1 << HD63705_INT_IRQ1)) != 0)
- {
- m_pending_interrupts &= ~(1 << HD63705_INT_IRQ1);
- rm16(0x1ff8, m_pc);
- }
- else if ((m_pending_interrupts & (1 << HD63705_INT_IRQ2)) != 0)
- {
- m_pending_interrupts &= ~(1 << HD63705_INT_IRQ2);
- rm16(0x1fec, m_pc);
- }
- else if ((m_pending_interrupts & (1 << HD63705_INT_ADCONV)) != 0)
- {
- m_pending_interrupts &= ~(1 << HD63705_INT_ADCONV);
- rm16(0x1fea, m_pc);
- }
- else if ((m_pending_interrupts & (1 << HD63705_INT_TIMER1)) != 0)
- {
- m_pending_interrupts &= ~(1 << HD63705_INT_TIMER1);
- rm16(0x1ff6, m_pc);
- }
- else if ((m_pending_interrupts & (1 << HD63705_INT_TIMER2)) != 0)
- {
- m_pending_interrupts &= ~(1 << HD63705_INT_TIMER2);
- rm16(0x1ff4, m_pc);
- }
- else if ((m_pending_interrupts & (1 << HD63705_INT_TIMER3)) != 0)
- {
- m_pending_interrupts &= ~(1<<HD63705_INT_TIMER3);
- rm16(0x1ff2, m_pc);
- }
- else if ((m_pending_interrupts & (1 << HD63705_INT_PCI)) != 0)
- {
- m_pending_interrupts &= ~(1 << HD63705_INT_PCI);
- rm16(0x1ff0, m_pc);
- }
- else if ((m_pending_interrupts & (1 << HD63705_INT_SCI)) != 0)
- {
- m_pending_interrupts &= ~(1 << HD63705_INT_SCI);
- rm16(0x1fee, m_pc);
- }
-}
-
-/* Generate interrupts */
-void m6805_base_device::interrupt()
+const m6805_base_device::cycle_count_table m6805_base_device::s_hc_cycles =
{
- /* the 6805 latches interrupt requests internally, so we don't clear */
- /* pending_interrupts until the interrupt is taken, no matter what the */
- /* external IRQ pin does. */
-
- if ((m_pending_interrupts & (1 << HD63705_INT_NMI)) != 0)
- {
- pushword(m_pc);
- pushbyte(m_x);
- pushbyte(m_a);
- pushbyte(m_cc);
- SEI;
- /* no vectors supported, just do the callback to clear irq_state if needed */
- standard_irq_callback(0);
-
- rm16(0x1ffc, m_pc);
- m_pending_interrupts &= ~(1 << HD63705_INT_NMI);
-
- m_icount -= 11;
- burn_cycles(11);
- }
- else if((m_pending_interrupts & ((1 << M6805_IRQ_LINE) | HD63705_INT_MASK)) != 0)
- {
- if ((CC & IFLAG) == 0)
- {
- /* standard IRQ */
- pushword(m_pc);
- pushbyte(m_x);
- pushbyte(m_a);
- pushbyte(m_cc);
- SEI;
- /* no vectors supported, just do the callback to clear irq_state if needed */
- standard_irq_callback(0);
-
- interrupt_vector();
-
- m_pending_interrupts &= ~(1 << M6805_IRQ_LINE);
- }
- m_icount -= 11;
- burn_cycles(11);
- }
-}
+ /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
+ /*0*/ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ /*1*/ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ /*2*/ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ /*3*/ 5, 0, 0, 5, 5, 0, 5, 5, 5, 5, 5, 0, 5, 4, 0, 5,
+ /*4*/ 3, 0,11, 3, 3, 0, 3, 3, 3, 3, 3, 0, 3, 3, 0, 3,
+ /*5*/ 3, 0, 0, 3, 3, 0, 3, 3, 3, 3, 3, 0, 3, 3, 0, 3,
+ /*6*/ 6, 0, 0, 6, 6, 0, 6, 6, 6, 6, 6, 0, 6, 5, 0, 6,
+ /*7*/ 5, 0, 0, 5, 5, 0, 5, 5, 5, 5, 5, 0, 5, 4, 0, 5,
+ /*8*/ 9, 6, 0,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2,
+ /*9*/ 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 2,
+ /*A*/ 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 0, 6, 2, 0,
+ /*B*/ 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 2, 5, 3, 4,
+ /*C*/ 4, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, 4, 3, 6, 4, 5,
+ /*D*/ 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 4, 7, 5, 6,
+ /*E*/ 4, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, 4, 3, 6, 4, 5,
+ /*F*/ 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 2, 5, 3, 4
+};
//-------------------------------------------------
// m6809_base_device - constructor
//-------------------------------------------------
-m6805_base_device::m6805_base_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, const device_type type, const char *name, uint32_t addr_width, const char *shortname, const char *source)
+m6805_base_device::m6805_base_device(
+ machine_config const &mconfig,
+ char const *tag,
+ device_t *owner,
+ uint32_t clock,
+ device_type const type,
+ char const *name,
+ configuration_params const &params,
+ char const *shortname,
+ char const *source)
: cpu_device(mconfig, type, name, tag, owner, clock, shortname, source)
- , m_program_config("program", ENDIANNESS_BIG, 8, addr_width)
+ , m_params(params)
+ , m_program_config("program", ENDIANNESS_BIG, 8, params.m_addr_width)
{
}
-m6805_base_device::m6805_base_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, const device_type type, const char *name, uint32_t addr_width, address_map_delegate internal_map, const char *shortname, const char *source)
+m6805_base_device::m6805_base_device(
+ machine_config const &mconfig,
+ char const *tag,
+ device_t *owner,
+ uint32_t clock,
+ device_type const type,
+ char const *name,
+ configuration_params const &params,
+ address_map_delegate internal_map,
+ char const *shortname,
+ char const *source)
: cpu_device(mconfig, type, name, tag, owner, clock, shortname, source)
- , m_program_config("program", ENDIANNESS_BIG, 8, addr_width, 0, internal_map)
+ , m_params(params)
+ , m_program_config("program", ENDIANNESS_BIG, 8, params.m_addr_width, 0, internal_map)
{
}
@@ -285,8 +285,6 @@ void m6805_base_device::device_start()
// register for savestates
save_item(NAME(EA));
- save_item(NAME(SP_MASK));
- save_item(NAME(SP_LOW));
save_item(NAME(A));
save_item(NAME(PC));
save_item(NAME(S));
@@ -299,13 +297,9 @@ void m6805_base_device::device_start()
std::fill(std::begin(m_irq_state), std::end(m_irq_state), 0);
}
-
-
void m6805_base_device::device_reset()
{
m_ea.w.l = 0;
- m_sp_mask = 0x07f;
- m_sp_low = 0x060;
m_pc.w.l = 0;
m_s.w.l = SP_MASK;
m_a = 0;
@@ -334,10 +328,9 @@ void m6805_base_device::device_reset()
const address_space_config *m6805_base_device::memory_space_config(address_spacenum spacenum) const
{
if (spacenum == AS_PROGRAM)
- {
return &m_program_config;
- }
- return nullptr;
+ else
+ return nullptr;
}
@@ -350,17 +343,68 @@ void m6805_base_device::state_string_export(const device_state_entry &entry, std
{
switch (entry.index())
{
- case STATE_GENFLAGS:
- str = string_format("%c%c%c%c%c%c%c%c",
- (m_cc & 0x80) ? '?' : '.',
- (m_cc & 0x40) ? '?' : '.',
- (m_cc & 0x20) ? '?' : '.',
- (m_cc & 0x10) ? 'H' : '.',
- (m_cc & 0x08) ? 'I' : '.',
- (m_cc & 0x04) ? 'N' : '.',
- (m_cc & 0x02) ? 'Z' : '.',
- (m_cc & 0x01) ? 'C' : '.');
- break;
+ case STATE_GENFLAGS:
+ str = string_format("%c%c%c%c%c%c%c%c",
+ (m_cc & 0x80) ? '?' : '.',
+ (m_cc & 0x40) ? '?' : '.',
+ (m_cc & 0x20) ? '?' : '.',
+ (m_cc & 0x10) ? 'H' : '.',
+ (m_cc & 0x08) ? 'I' : '.',
+ (m_cc & 0x04) ? 'N' : '.',
+ (m_cc & 0x02) ? 'Z' : '.',
+ (m_cc & 0x01) ? 'C' : '.');
+ break;
+ }
+}
+
+
+void m6805_base_device::interrupt_vector()
+{
+ rm16(0xfffa, m_pc);
+}
+
+/* Generate interrupts */
+void m6805_base_device::interrupt()
+{
+ /* the 6805 latches interrupt requests internally, so we don't clear */
+ /* pending_interrupts until the interrupt is taken, no matter what the */
+ /* external IRQ pin does. */
+
+ if ((m_pending_interrupts & (1 << HD63705_INT_NMI)) != 0)
+ {
+ pushword(m_pc);
+ pushbyte(m_x);
+ pushbyte(m_a);
+ pushbyte(m_cc);
+ SEI;
+ /* no vectors supported, just do the callback to clear irq_state if needed */
+ standard_irq_callback(0);
+
+ rm16(0x1ffc, m_pc);
+ m_pending_interrupts &= ~(1 << HD63705_INT_NMI);
+
+ m_icount -= 11;
+ burn_cycles(11);
+ }
+ else if((m_pending_interrupts & ((1 << M6805_IRQ_LINE) | HD63705_INT_MASK)) != 0)
+ {
+ if ((CC & IFLAG) == 0)
+ {
+ /* standard IRQ */
+ pushword(m_pc);
+ pushbyte(m_x);
+ pushbyte(m_a);
+ pushbyte(m_cc);
+ SEI;
+ /* no vectors supported, just do the callback to clear irq_state if needed */
+ standard_irq_callback(0);
+
+ interrupt_vector();
+
+ m_pending_interrupts &= ~(1 << M6805_IRQ_LINE);
+ }
+ m_icount -= 11;
+ burn_cycles(11);
}
}
@@ -394,26 +438,10 @@ uint32_t m6805_base_device::disasm_max_opcode_bytes() const
offs_t m6805_base_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options)
{
- extern CPU_DISASSEMBLE( m6805 );
return CPU_DISASSEMBLE_NAME(m6805)(this, stream, pc, oprom, opram, options);
}
-void m6805_device::execute_set_input(int inputnum, int state)
-{
- /* Basic 6805 only has one IRQ line */
- /* See HD63705 specific version */
- if (m_irq_state[0] != state)
- {
- m_irq_state[0] = state;
-
- if (state != CLEAR_LINE)
- {
- m_pending_interrupts |= 1 << M6805_IRQ_LINE;
- }
- }
-}
-
#include "6805ops.hxx"
//-------------------------------------------------
@@ -445,7 +473,12 @@ uint64_t m6805_base_device::execute_cycles_to_clocks(uint64_t cycles) const
uint32_t m6805_base_device::execute_min_cycles() const
{
- return 2;
+ // get the minimum not including the zero placeholders for illegal instructions
+ u32 const result(*std::min_element(
+ std::begin(m_params.m_cycles),
+ std::end(m_params.m_cycles),
+ [] (u8 x, u8 y) { return u8(x - 1) < u8(y - 1); }));
+ return result;
}
@@ -456,7 +489,8 @@ uint32_t m6805_base_device::execute_min_cycles() const
uint32_t m6805_base_device::execute_max_cycles() const
{
- return 10;
+ u32 const result(*std::max_element(std::begin(m_params.m_cycles), std::end(m_params.m_cycles)));
+ return result;
}
@@ -487,23 +521,65 @@ void m6805_base_device::execute_run()
u8 const ireg = rdop(PC++);
- (this->*m_hmos_ops[ireg])();
- m_icount -= m_hmos_cycles[ireg];
- burn_cycles(m_hmos_cycles[ireg]);
+ (this->*m_params.m_ops[ireg])();
+ m_icount -= m_params.m_cycles[ireg];
+ burn_cycles(m_params.m_cycles[ireg]);
}
while (m_icount > 0);
}
+
+void m6805_device::execute_set_input(int inputnum, int state)
+{
+ /* Basic 6805 only has one IRQ line */
+ /* See HD63705 specific version */
+ if (m_irq_state[0] != state)
+ {
+ m_irq_state[0] = state;
+
+ if (state != CLEAR_LINE)
+ {
+ m_pending_interrupts |= 1 << M6805_IRQ_LINE;
+ }
+ }
+}
+
+
+m6805_device::m6805_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : m6805_base_device(
+ mconfig,
+ tag,
+ owner,
+ clock,
+ M6805,
+ "M6805",
+ { s_hmos_ops, s_hmos_cycles, 12, 0x007f, 0x0060, 0xfffc },
+ "m6805",
+ __FILE__)
+{
+}
+
/****************************************************************************
* M68HC05EG section
****************************************************************************/
+m68hc05eg_device::m68hc05eg_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : m6805_base_device(
+ mconfig,
+ tag,
+ owner,
+ clock,
+ M68HC05EG,
+ "M68HC05EG",
+ { s_hmos_ops, s_hmos_cycles, 13, 0x00ff, 0x00c0, 0xfffc }, // completely wrong, but it preserves existing behaviour
+ "m68hc05eg",
+ __FILE__)
+{
+}
+
void m68hc05eg_device::device_reset()
{
m6805_base_device::device_reset();
- m_sp_mask = 0xff;
- m_sp_low = 0xc0;
-
rm16(0x1ffe, m_pc);
}
@@ -520,16 +596,46 @@ void m68hc05eg_device::execute_set_input(int inputnum, int state)
}
}
+void m68hc05eg_device::interrupt_vector()
+{
+ if ((m_pending_interrupts & (1 << M68HC05EG_INT_IRQ)) != 0)
+ {
+ m_pending_interrupts &= ~(1 << M68HC05EG_INT_IRQ);
+ rm16(0x1ffa, m_pc);
+ }
+ else if((m_pending_interrupts & (1 << M68HC05EG_INT_TIMER)) != 0)
+ {
+ m_pending_interrupts &= ~(1 << M68HC05EG_INT_TIMER);
+ rm16(0x1ff8, m_pc);
+ }
+ else if((m_pending_interrupts & (1 << M68HC05EG_INT_CPI)) != 0)
+ {
+ m_pending_interrupts &= ~(1 << M68HC05EG_INT_CPI);
+ rm16(0x1ff6, m_pc);
+ }
+}
+
/****************************************************************************
* HD63705 section
****************************************************************************/
+hd63705_device::hd63705_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : m6805_base_device(mconfig,
+ tag,
+ owner,
+ clock,
+ HD63705,
+ "HD63705",
+ { s_hmos_ops, s_hmos_cycles, 16, 0x017f, 0x0100, 0x1ffa },
+ "hd63705",
+ __FILE__)
+{
+}
+
void hd63705_device::device_reset()
{
m6805_base_device::device_reset();
- m_sp_mask = 0x17f;
- m_sp_low = 0x100;
m_s.w.l = SP_MASK;
rm16(0x1ffe, m_pc);
@@ -563,6 +669,54 @@ void hd63705_device::execute_set_input(int inputnum, int state)
}
}
+void hd63705_device::interrupt_vector()
+{
+ /* Need to add emulation of other interrupt sources here KW-2/4/99 */
+ /* This is just a quick patch for Namco System 2 operation */
+
+ if ((m_pending_interrupts & (1 << HD63705_INT_IRQ1)) != 0)
+ {
+ m_pending_interrupts &= ~(1 << HD63705_INT_IRQ1);
+ rm16(0x1ff8, m_pc);
+ }
+ else if ((m_pending_interrupts & (1 << HD63705_INT_IRQ2)) != 0)
+ {
+ m_pending_interrupts &= ~(1 << HD63705_INT_IRQ2);
+ rm16(0x1fec, m_pc);
+ }
+ else if ((m_pending_interrupts & (1 << HD63705_INT_ADCONV)) != 0)
+ {
+ m_pending_interrupts &= ~(1 << HD63705_INT_ADCONV);
+ rm16(0x1fea, m_pc);
+ }
+ else if ((m_pending_interrupts & (1 << HD63705_INT_TIMER1)) != 0)
+ {
+ m_pending_interrupts &= ~(1 << HD63705_INT_TIMER1);
+ rm16(0x1ff6, m_pc);
+ }
+ else if ((m_pending_interrupts & (1 << HD63705_INT_TIMER2)) != 0)
+ {
+ m_pending_interrupts &= ~(1 << HD63705_INT_TIMER2);
+ rm16(0x1ff4, m_pc);
+ }
+ else if ((m_pending_interrupts & (1 << HD63705_INT_TIMER3)) != 0)
+ {
+ m_pending_interrupts &= ~(1<<HD63705_INT_TIMER3);
+ rm16(0x1ff2, m_pc);
+ }
+ else if ((m_pending_interrupts & (1 << HD63705_INT_PCI)) != 0)
+ {
+ m_pending_interrupts &= ~(1 << HD63705_INT_PCI);
+ rm16(0x1ff0, m_pc);
+ }
+ else if ((m_pending_interrupts & (1 << HD63705_INT_SCI)) != 0)
+ {
+ m_pending_interrupts &= ~(1 << HD63705_INT_SCI);
+ rm16(0x1fee, m_pc);
+ }
+}
+
+
const device_type M6805 = &device_creator<m6805_device>;
const device_type M68HC05EG = &device_creator<m68hc05eg_device>;
const device_type HD63705 = &device_creator<hd63705_device>;
diff --git a/src/devices/cpu/m6805/m6805.h b/src/devices/cpu/m6805/m6805.h
index cdcff22604c..3aa8e08bc99 100644
--- a/src/devices/cpu/m6805/m6805.h
+++ b/src/devices/cpu/m6805/m6805.h
@@ -21,10 +21,6 @@ extern const device_type HD63705;
// Used by core CPU interface
class m6805_base_device : public cpu_device
{
-public:
- // construction/destruction
- m6805_base_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, const device_type type, const char *name, uint32_t addr_width, const char *shortname, const char *source);
-
protected:
// addressing mode selector for opcode handler templates
enum class addr_mode { IM, DI, EX, IX, IX1, IX2 };
@@ -52,13 +48,65 @@ protected:
};
typedef void (m6805_base_device::*op_handler_func)();
+ typedef op_handler_func const op_handler_table[256];
+ typedef u8 const cycle_count_table[256];
+
+ struct configuration_params
+ {
+ configuration_params(
+ op_handler_table &ops,
+ cycle_count_table &cycles,
+ u32 addr_width,
+ u32 sp_mask,
+ u32 sp_floor,
+ u16 swi_vector)
+ : m_ops(ops)
+ , m_cycles(cycles)
+ , m_addr_width(addr_width)
+ , m_sp_mask(sp_mask)
+ , m_sp_floor(sp_floor)
+ , m_swi_vector(swi_vector)
+ {
+ }
+
+ op_handler_table &m_ops;
+ cycle_count_table &m_cycles;
+ u32 m_addr_width;
+ u32 m_sp_mask;
+ u32 m_sp_floor;
+ u16 m_swi_vector;
+ };
// opcode tables
- static op_handler_func const m_hmos_ops[256];
- static u8 const m_hmos_cycles[256];
- static u8 const m_cmos_cycles[256];
+ static op_handler_table s_hmos_ops;
+ static op_handler_table s_cmos_ops;
+ static op_handler_table s_hc_ops;
+ static cycle_count_table s_hmos_cycles;
+ static cycle_count_table s_cmos_cycles;
+ static cycle_count_table s_hc_cycles;
- m6805_base_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, const device_type type, const char *name, uint32_t addr_width, address_map_delegate internal_map, const char *shortname, const char *source);
+ // construction/destruction
+ m6805_base_device(
+ machine_config const &mconfig,
+ char const *tag,
+ device_t *owner,
+ uint32_t clock,
+ device_type const type,
+ char const *name,
+ configuration_params const &params,
+ char const *shortname,
+ char const *source);
+ m6805_base_device(
+ machine_config const &mconfig,
+ char const *tag,
+ device_t *owner,
+ uint32_t clock,
+ device_type const type,
+ char const *name,
+ configuration_params const &params,
+ address_map_delegate internal_map,
+ char const *shortname,
+ char const *source);
// device-level overrides
virtual void device_start() override;
@@ -89,6 +137,7 @@ protected:
void clr_nz() { m_cc &= ~(NFLAG | ZFLAG); }
void clr_nzc() { m_cc &= ~(NFLAG | ZFLAG | CFLAG); }
+ void clr_hc() { m_cc &= ~(HFLAG | CFLAG); }
void clr_hnzc() { m_cc &= ~(HFLAG | NFLAG | ZFLAG | CFLAG); }
// macros for CC -- CC bits affected should be reset before calling
@@ -149,6 +198,7 @@ protected:
template <addr_mode M> void clr();
void nega();
+ void mul();
void coma();
void lsra();
void rora();
@@ -174,7 +224,9 @@ protected:
void rti();
void rts();
- virtual void swi();
+ void swi();
+ void stop();
+ void wait();
void tax();
void txa();
@@ -209,16 +261,14 @@ protected:
virtual void interrupt();
virtual void interrupt_vector();
- const char *m_tag;
+ configuration_params const m_params;
// address spaces
- const address_space_config m_program_config;
+ address_space_config const m_program_config;
// CPU registers
PAIR m_ea; // effective address (should really be a temporary in opcode handlers)
- u32 m_sp_mask; // Stack pointer address mask
- u32 m_sp_low; // Stack pointer low water mark (or floor)
PAIR m_pc; // Program counter
PAIR m_s; // Stack pointer
u8 m_a; // Accumulator
@@ -245,8 +295,7 @@ class m6805_device : public m6805_base_device
{
public:
// construction/destruction
- m6805_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : m6805_base_device(mconfig, tag, owner, clock, M6805, "M6805", 12, "m6805", __FILE__) { }
+ m6805_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
virtual void execute_set_input(int inputnum, int state) override;
@@ -259,8 +308,7 @@ class m68hc05eg_device : public m6805_base_device
{
public:
// construction/destruction
- m68hc05eg_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : m6805_base_device(mconfig, tag, owner, clock, M68HC05EG, "M68HC05EG", 13, "m68hc05eg", __FILE__) { }
+ m68hc05eg_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
// device-level overrides
@@ -277,8 +325,7 @@ class hd63705_device : public m6805_base_device
{
public:
// construction/destruction
- hd63705_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : m6805_base_device(mconfig, tag, owner, clock, HD63705, "HD63705", 16, "hd63705", __FILE__) { }
+ hd63705_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
// device-level overrides
@@ -291,7 +338,6 @@ protected:
// opcodes
virtual void bil() override;
virtual void bih() override;
- virtual void swi() override;
};
#define M6805_IRQ_LINE 0
@@ -331,5 +377,7 @@ protected:
#define HD63705_INT_NMI 0x08
CPU_DISASSEMBLE( m6805 );
+CPU_DISASSEMBLE( m146805 );
+CPU_DISASSEMBLE( m68hc05 );
#endif // MAME_CPU_M6805_M6805_H
diff --git a/src/devices/cpu/m6805/m6805defs.h b/src/devices/cpu/m6805/m6805defs.h
index 84b1c941fc0..670beda2683 100644
--- a/src/devices/cpu/m6805/m6805defs.h
+++ b/src/devices/cpu/m6805/m6805defs.h
@@ -5,13 +5,13 @@
#pragma once
-#define SP_MASK m_sp_mask // stack pointer mask
-#define SP_LOW m_sp_low // stack pointer low water mark
-#define PC m_pc.w.l // program counter lower word
-#define S m_s.w.l // stack pointer lower word
-#define A m_a // accumulator
-#define X m_x // index register
-#define CC m_cc // condition codes
+#define SP_MASK m_params.m_sp_mask // stack pointer mask
+#define SP_LOW m_params.m_sp_floor // stack pointer low water mark
+#define PC m_pc.w.l // program counter lower word
+#define S m_s.w.l // stack pointer lower word
+#define A m_a // accumulator
+#define X m_x // index register
+#define CC m_cc // condition codes
#define EAD m_ea.d
#define EA m_ea.w.l
@@ -116,6 +116,26 @@ inline void m6805_base_device::skipbyte() { rdop_arg(PC++); }
/* Macros for branch instructions */
#define BRANCH(f) do { u8 t; immbyte(t); if (bool(f) == bool(C)) PC += SIGNED(t); } while (false)
+offs_t CPU_DISASSEMBLE_NAME(m146805)(
+ cpu_device *device,
+ std::ostream &stream,
+ offs_t pc,
+ const u8 *oprom,
+ const u8 *opram,
+ int options,
+ std::pair<u16, char const *> const symbols[],
+ std::size_t symbol_count);
+
+offs_t CPU_DISASSEMBLE_NAME(m68hc05)(
+ cpu_device *device,
+ std::ostream &stream,
+ offs_t pc,
+ const u8 *oprom,
+ const u8 *opram,
+ int options,
+ std::pair<u16, char const *> const symbols[],
+ std::size_t symbol_count);
+
offs_t CPU_DISASSEMBLE_NAME(m6805)(
cpu_device *device,
std::ostream &stream,
@@ -139,4 +159,30 @@ inline offs_t CPU_DISASSEMBLE_NAME(m6805)(
return CPU_DISASSEMBLE_NAME(m6805)(device, stream, pc, oprom, opram, options, symbols, N);
}
+template <size_t N>
+inline offs_t CPU_DISASSEMBLE_NAME(m146805)(
+ cpu_device *device,
+ std::ostream &stream,
+ offs_t pc,
+ const u8 *oprom,
+ const u8 *opram,
+ int options,
+ std::pair<u16, char const *> const (&symbols)[N])
+{
+ return CPU_DISASSEMBLE_NAME(m146805)(device, stream, pc, oprom, opram, options, symbols, N);
+}
+
+template <size_t N>
+inline offs_t CPU_DISASSEMBLE_NAME(m68hc05)(
+ cpu_device *device,
+ std::ostream &stream,
+ offs_t pc,
+ const u8 *oprom,
+ const u8 *opram,
+ int options,
+ std::pair<u16, char const *> const (&symbols)[N])
+{
+ return CPU_DISASSEMBLE_NAME(m68hc05)(device, stream, pc, oprom, opram, options, symbols, N);
+}
+
#endif // MAME_CPU_M6805_M6805DEFS_H
diff --git a/src/devices/cpu/m6805/m68705.cpp b/src/devices/cpu/m6805/m68705.cpp
index 01d3195e74d..e4d0c920d5e 100644
--- a/src/devices/cpu/m6805/m68705.cpp
+++ b/src/devices/cpu/m6805/m68705.cpp
@@ -1,3 +1,5 @@
+// license:BSD-3-Clause
+// copyright-holders:Vas Crabb
#include "emu.h"
#include "m68705.h"
#include "m6805defs.h"
@@ -90,7 +92,7 @@ device_type const M68705U3 = &device_creator<m68705u3_device>;
/****************************************************************************
- * MC68705 base device
+ * M68705 base device
****************************************************************************/
/*
@@ -192,7 +194,17 @@ m68705_device::m68705_device(
address_map_delegate internal_map,
char const *shortname,
char const *source)
- : m6805_base_device(mconfig, tag, owner, clock, type, name, addr_width, internal_map, shortname, source)
+ : m6805_base_device(
+ mconfig,
+ tag,
+ owner,
+ clock,
+ type,
+ name,
+ { s_hmos_ops, s_hmos_cycles, addr_width, 0x007f, 0x0060, 0xfffc },
+ internal_map,
+ shortname,
+ source)
, device_nvram_interface(mconfig, *this)
, m_user_rom(*this, DEVICE_SELF, u32(1) << addr_width)
, m_port_open_drain{ false, false, false, false }
diff --git a/src/devices/cpu/m6805/m68hc05.cpp b/src/devices/cpu/m6805/m68hc05.cpp
new file mode 100644
index 00000000000..79ef97f0e9f
--- /dev/null
+++ b/src/devices/cpu/m6805/m68hc05.cpp
@@ -0,0 +1,167 @@
+// license:BSD-3-Clause
+// copyright-holders:Vas Crabb
+#include "emu.h"
+#include "m68hc05.h"
+#include "m6805defs.h"
+
+/****************************************************************************
+ * Configurable logging
+ ****************************************************************************/
+
+//#define VERBOSE (LOG_GENERAL)
+//#define LOG_OUTPUT_FUNC printf
+#include "logmacro.h"
+
+
+namespace {
+
+std::pair<u16, char const *> const m68705c4_syms[] = {
+ { 0x0000, "PORTA" }, { 0x0001, "PORTB" }, { 0x0002, "PORTC" }, { 0x0003, "PORTD" },
+ { 0x0004, "DDRA" }, { 0x0005, "DDRB" }, { 0x0006, "DDRC" },
+ { 0x000a, "SPCR" }, { 0x000b, "SPSR" }, { 0x000c, "SPDR" },
+ { 0x000d, "BAUD" }, { 0x000e, "SCCR1" }, { 0x000f, "SCCR2" }, { 0x0010, "SCSR" }, { 0x0011, "SCDR" },
+ { 0x0012, "TCR" }, { 0x0013, "TSR" },
+ { 0x0014, "ICRH" }, { 0x0015, "ICRL" }, { 0x0016, "OCRH" }, { 0x0017, "OCRL" },
+ { 0x0018, "TRH" }, { 0x0019, "TRL" }, { 0x001a, "ATRH" }, { 0x001b, "ATRL" } };
+
+} // anonymous namespace
+
+
+/****************************************************************************
+ * Global variables
+ ****************************************************************************/
+
+device_type const M68HC05C4 = &device_creator<m68hc05c4_device>;
+
+
+/****************************************************************************
+ * M68HC05 base device
+ ****************************************************************************/
+
+m68hc05_device::m68hc05_device(
+ machine_config const &mconfig,
+ char const *tag,
+ device_t *owner,
+ u32 clock,
+ device_type type,
+ char const *name,
+ address_map_delegate internal_map,
+ char const *shortname,
+ char const *source)
+ : m6805_base_device(
+ mconfig,
+ tag,
+ owner,
+ clock,
+ type,
+ name,
+ { s_hc_ops, s_hc_cycles, 13, 0x00ff, 0x00c0, 0xfffc },
+ internal_map,
+ shortname,
+ source)
+{
+}
+
+void m68hc05_device::execute_set_input(int inputnum, int state)
+{
+ switch (inputnum)
+ {
+ default:
+ if (m_irq_state[inputnum] != state)
+ {
+ m_irq_state[inputnum] = (state == ASSERT_LINE) ? ASSERT_LINE : CLEAR_LINE;
+
+ if (state != CLEAR_LINE)
+ m_pending_interrupts |= 1 << inputnum;
+ }
+ }
+}
+
+uint64_t m68hc05_device::execute_clocks_to_cycles(uint64_t clocks) const
+{
+ return (clocks + 1) / 2;
+}
+
+uint64_t m68hc05_device::execute_cycles_to_clocks(uint64_t cycles) const
+{
+ return cycles * 2;
+}
+
+offs_t m68hc05_device::disasm_disassemble(
+ std::ostream &stream,
+ offs_t pc,
+ const uint8_t *oprom,
+ const uint8_t *opram,
+ uint32_t options)
+{
+ return CPU_DISASSEMBLE_NAME(m68hc05)(this, stream, pc, oprom, opram, options);
+}
+
+
+/****************************************************************************
+ * MC68HC05C4 device
+ ****************************************************************************/
+
+DEVICE_ADDRESS_MAP_START( c4_map, 8, m68hc05c4_device )
+ ADDRESS_MAP_GLOBAL_MASK(0x1fff)
+ ADDRESS_MAP_UNMAP_HIGH
+
+ // 0x0000 PORTA
+ // 0x0001 PORTB
+ // 0x0002 PORTC
+ // 0x0003 PORTD
+ // 0x0004 DDRA
+ // 0x0005 DDRB
+ // 0x0006 DDRC
+ // 0x0007-0x0009 unused
+ // 0x000a SPCR
+ // 0x000b SPSR
+ // 0x000c SPDR
+ // 0x000d BAUD
+ // 0x000e SCCR1
+ // 0x000f SCCR2
+ // 0x0010 SCSR
+ // 0x0011 SCDR
+ // 0x0012 TCR
+ // 0x0013 TDR
+ // 0x0014 ICRH
+ // 0x0015 ICRL
+ // 0x0016 OCRH
+ // 0x0017 OCRL
+ // 0x0018 TRH
+ // 0x0019 TRL
+ // 0x001a ATRH
+ // 0x001b ATRL
+ // 0x001c-0x001f unused
+ AM_RANGE(0x0020, 0x004f) AM_ROM // user ROM
+ AM_RANGE(0x0050, 0x00ff) AM_RAM // RAM/stack
+ AM_RANGE(0x0100, 0x10ff) AM_ROM // user ROM
+ // 0x1100-0x1eff unused
+ AM_RANGE(0x1f00, 0x1fef) AM_ROM // self-check
+ // 0x1ff0-0x1ff3 unused
+ AM_RANGE(0x1ff4, 0x1fff) AM_ROM // user vectors
+ADDRESS_MAP_END
+
+m68hc05c4_device::m68hc05c4_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock)
+ : m68hc05_device(
+ mconfig,
+ tag,
+ owner,
+ clock,
+ M68HC05C4,
+ "MC68HC05C4",
+ address_map_delegate(FUNC(m68hc05c4_device::c4_map), this),
+ "m68hc05c4",
+ __FILE__)
+{
+}
+
+offs_t m68hc05c4_device::disasm_disassemble(
+ std::ostream &stream,
+ offs_t pc,
+ const uint8_t *oprom,
+ const uint8_t *opram,
+ uint32_t options)
+{
+ return CPU_DISASSEMBLE_NAME(m68hc05)(this, stream, pc, oprom, opram, options, m68705c4_syms);
+}
diff --git a/src/devices/cpu/m6805/m68hc05.h b/src/devices/cpu/m6805/m68hc05.h
new file mode 100644
index 00000000000..e32c838360b
--- /dev/null
+++ b/src/devices/cpu/m6805/m68hc05.h
@@ -0,0 +1,69 @@
+// license:BSD-3-Clause
+// copyright-holders:Vas Crabb
+#ifndef MAME_CPU_M6805_M68HC05_H
+#define MAME_CPU_M6805_M68HC05_H
+
+#pragma once
+
+#include "m6805.h"
+
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+extern device_type const M68HC05C4;
+
+
+//**************************************************************************
+// TYPE DECLARATIONS
+//**************************************************************************
+
+// ======================> m68hc05_device
+
+class m68hc05_device : public m6805_base_device
+{
+protected:
+ m68hc05_device(
+ machine_config const &mconfig,
+ char const *tag,
+ device_t *owner,
+ u32 clock,
+ device_type type,
+ char const *name,
+ address_map_delegate internal_map,
+ char const *shortname,
+ char const *source);
+
+ virtual void execute_set_input(int inputnum, int state) override;
+ virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const override;
+ virtual uint64_t execute_cycles_to_clocks(uint64_t cycles) const override;
+
+ virtual offs_t disasm_disassemble(
+ std::ostream &stream,
+ offs_t pc,
+ const uint8_t *oprom,
+ const uint8_t *opram,
+ uint32_t options) override;
+};
+
+
+// ======================> m68hc05c4_device
+
+class m68hc05c4_device : public m68hc05_device
+{
+public:
+ m68hc05c4_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
+
+protected:
+ DECLARE_ADDRESS_MAP(c4_map, 8);
+
+ virtual offs_t disasm_disassemble(
+ std::ostream &stream,
+ offs_t pc,
+ const uint8_t *oprom,
+ const uint8_t *opram,
+ uint32_t options) override;
+};
+
+#endif // MAME_CPU_M6805_M68HC05_H
diff --git a/src/tools/unidasm.cpp b/src/tools/unidasm.cpp
index 0a8c8680438..e360f503790 100644
--- a/src/tools/unidasm.cpp
+++ b/src/tools/unidasm.cpp
@@ -139,6 +139,8 @@ CPU_DISASSEMBLE( m6803 );
CPU_DISASSEMBLE( m68030 );
CPU_DISASSEMBLE( m68040 );
CPU_DISASSEMBLE( m6805 );
+CPU_DISASSEMBLE( m146805 );
+CPU_DISASSEMBLE( m68hc05 );
CPU_DISASSEMBLE( m6808 );
CPU_DISASSEMBLE( m6809 );
CPU_DISASSEMBLE( m68340 );
@@ -311,6 +313,8 @@ static const dasm_table_entry dasm_table[] =
{ "m68030", _16be, 0, CPU_DISASSEMBLE_NAME(m68030) },
{ "m68040", _16be, 0, CPU_DISASSEMBLE_NAME(m68040) },
{ "m6805", _8bit, 0, CPU_DISASSEMBLE_NAME(m6805) },
+ { "m146805", _8bit, 0, CPU_DISASSEMBLE_NAME(m146805) },
+ { "m68hc05", _8bit, 0, CPU_DISASSEMBLE_NAME(m68hc05) },
{ "m6808", _8bit, 0, CPU_DISASSEMBLE_NAME(m6808) },
{ "m6809", _8bit, 0, CPU_DISASSEMBLE_NAME(m6809) },
{ "m68340", _16be, 0, CPU_DISASSEMBLE_NAME(m68340) },