diff options
author | 2017-01-30 22:51:11 +1100 | |
---|---|---|
committer | 2017-01-30 23:10:51 +1100 | |
commit | 06e22ce79d2bc41ac333ed5cf59ee1c2db5cfd6e (patch) | |
tree | 17b6a1dfca9f2ac2e4bcc330acfc408c3a44f8da /src | |
parent | 0995b978acbbc3a892595ac110f1d930684a1d52 (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.cpp | 372 | ||||
-rw-r--r-- | src/devices/cpu/m6805/6805ops.hxx | 34 | ||||
-rw-r--r-- | src/devices/cpu/m6805/m6805.cpp | 492 | ||||
-rw-r--r-- | src/devices/cpu/m6805/m6805.h | 88 | ||||
-rw-r--r-- | src/devices/cpu/m6805/m6805defs.h | 60 | ||||
-rw-r--r-- | src/devices/cpu/m6805/m68705.cpp | 16 | ||||
-rw-r--r-- | src/devices/cpu/m6805/m68hc05.cpp | 167 | ||||
-rw-r--r-- | src/devices/cpu/m6805/m68hc05.h | 69 | ||||
-rw-r--r-- | src/tools/unidasm.cpp | 4 |
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 ¶ms, + 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 ¶ms, + 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 ¶ms, + 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 ¶ms, + 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) }, |