From 06e22ce79d2bc41ac333ed5cf59ee1c2db5cfd6e Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Mon, 30 Jan 2017 22:51:11 +1100 Subject: [PATCH] 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 --- scripts/src/cpu.lua | 4 +- src/devices/cpu/m6805/6805dasm.cpp | 400 ++++++------- src/devices/cpu/m6805/6805ops.hxx | 34 +- src/devices/cpu/m6805/m6805.cpp | 882 +++++++++++++++++------------ src/devices/cpu/m6805/m6805.h | 88 ++- src/devices/cpu/m6805/m6805defs.h | 60 +- src/devices/cpu/m6805/m68705.cpp | 16 +- src/devices/cpu/m6805/m68hc05.cpp | 167 ++++++ src/devices/cpu/m6805/m68hc05.h | 69 +++ src/tools/unidasm.cpp | 4 + 10 files changed, 1121 insertions(+), 603 deletions(-) create mode 100644 src/devices/cpu/m6805/m68hc05.cpp create mode 100644 src/devices/cpu/m6805/m68hc05.h diff --git a/scripts/src/cpu.lua b/scripts/src/cpu.lua index 72a7ffea3fa..477dac60840 100644 --- a/scripts/src/cpu.lua +++ b/scripts/src/cpu.lua @@ -1339,6 +1339,8 @@ if (CPUS["M6805"]~=null) then MAME_DIR .. "src/devices/cpu/m6805/6805ops.hxx", MAME_DIR .. "src/devices/cpu/m6805/m68705.cpp", MAME_DIR .. "src/devices/cpu/m6805/m68705.h", + MAME_DIR .. "src/devices/cpu/m6805/m68hc05.cpp", + MAME_DIR .. "src/devices/cpu/m6805/m68hc05.h", } end @@ -2430,4 +2432,4 @@ end if (CPUS["CLIPPER"]~=null or _OPTIONS["with-tools"]) then table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/clipper/clipperd.cpp") -end \ No newline at end of file +end 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,139 +30,97 @@ 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 + 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 }; -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" +#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) }; -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" -}; -#endif - template void format_address( @@ -182,6 +140,100 @@ void format_address( util::stream_format(stream, "$%0*X", 2 * sizeof(T), address); } + +offs_t disassemble( + cpu_device *device, + std::ostream &stream, + offs_t pc, + const u8 *oprom, + const u8 *opram, + int options, + lvl level, + std::pair const symbols[], + std::size_t symbol_count) +{ + u8 const code = oprom[0]; + + if (!disasm[code].name || (disasm[code].level > level)) + { + 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", disasm[code].name); + + 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::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::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::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::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; + } + + // if we fall off the switch statement something is very wrong + throw false; + } +} + } // anonymous namespace @@ -195,77 +247,35 @@ offs_t CPU_DISASSEMBLE_NAME(m6805)( std::pair const symbols[], std::size_t symbol_count) { - u8 const code = oprom[0]; - - u32 flags = 0; - switch (disasm[code].op) - { - case bsr: - case jsr: - flags = DASMFLAG_STEP_OVER; - break; - case rts: - case rti: - flags = DASMFLAG_STEP_OUT; - break; - } - - util::stream_format(stream, "%-6s", op_name_str[disasm[code].op]); - - int bit; - u16 ea; - switch (disasm[code].mode) - { - case md::IMP: // implicit - 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::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::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::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::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; - } - - // if we fall off the switch statement something is very wrong - throw false; + 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 const symbols[], + std::size_t symbol_count) +{ + return disassemble(device, stream, pc, oprom, opram, options, lvl::CMOS, symbols, symbol_count); +} -CPU_DISASSEMBLE(m6805) { return CPU_DISASSEMBLE_NAME(m6805)(device, stream, pc, oprom, opram, options, nullptr, 0); } +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 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(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) #define OP_IX1(name) (&m6805_base_device::name) #define OP_IX2(name) (&m6805_base_device::name) -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 uint8_t m6805_base_device::m_hmos_cycles[] = +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 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,7 +183,28 @@ 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, 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, + /*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 +}; + +const m6805_base_device::cycle_count_table m6805_base_device::s_hc_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, @@ -130,11 +226,376 @@ const uint8_t m6805_base_device::m_cmos_cycles[] = }; +//------------------------------------------------- +// m6809_base_device - constructor +//------------------------------------------------- + +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_params(params) + , m_program_config("program", ENDIANNESS_BIG, 8, params.m_addr_width) +{ +} + +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_params(params) + , m_program_config("program", ENDIANNESS_BIG, 8, params.m_addr_width, 0, internal_map) +{ +} + + + +void m6805_base_device::device_start() +{ + m_program = &space(AS_PROGRAM); + m_direct = &m_program->direct(); + + // set our instruction counter + m_icountptr = &m_icount; + + // register our state for the debugger + state_add(STATE_GENPC, "GENPC", m_pc.w.l).noshow(); + state_add(STATE_GENPCBASE, "CURPC", m_pc.w.l).noshow(); + state_add(STATE_GENFLAGS, "GENFLAGS", m_cc).callimport().callexport().formatstr("%8s").noshow(); + state_add(M6805_A, "A", m_a).mask(0xff); + state_add(M6805_PC, "PC", m_pc.w.l).mask(0xffff); + state_add(M6805_S, "S", m_s.w.l).mask(0xff); + state_add(M6805_X, "X", m_x).mask(0xff); + state_add(M6805_CC, "CC", m_cc).mask(0xff); + + // register for savestates + save_item(NAME(EA)); + save_item(NAME(A)); + save_item(NAME(PC)); + save_item(NAME(S)); + save_item(NAME(X)); + save_item(NAME(CC)); + save_item(NAME(m_pending_interrupts)); + save_item(NAME(m_irq_state)); + save_item(NAME(m_nmi_state)); + + 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_pc.w.l = 0; + m_s.w.l = SP_MASK; + m_a = 0; + m_x = 0; + m_cc = 0; + m_pending_interrupts = 0; + + m_nmi_state = 0; + + m_program = &space(AS_PROGRAM); + m_direct = &m_program->direct(); + + /* IRQ disabled */ + SEI; + + rm16(0xfffe, m_pc); +} + + +//------------------------------------------------- +// memory_space_config - return the configuration +// of the specified address space, or nullptr if +// the space doesn't exist +//------------------------------------------------- + +const address_space_config *m6805_base_device::memory_space_config(address_spacenum spacenum) const +{ + if (spacenum == AS_PROGRAM) + return &m_program_config; + else + return nullptr; +} + + +//------------------------------------------------- +// state_string_export - export state as a string +// for the debugger +//------------------------------------------------- + +void m6805_base_device::state_string_export(const device_state_entry &entry, std::string &str) const +{ + 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; + } +} + + 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); + } +} + + +//------------------------------------------------- +// disasm_min_opcode_bytes - return the length +// of the shortest instruction, in bytes +//------------------------------------------------- + +uint32_t m6805_base_device::disasm_min_opcode_bytes() const +{ + return 1; +} + + +//------------------------------------------------- +// disasm_max_opcode_bytes - return the length +// of the longest instruction, in bytes +//------------------------------------------------- + +uint32_t m6805_base_device::disasm_max_opcode_bytes() const +{ + return 3; +} + + +//------------------------------------------------- +// disasm_disassemble - call the disassembly +// helper function +//------------------------------------------------- + +offs_t m6805_base_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +{ + return CPU_DISASSEMBLE_NAME(m6805)(this, stream, pc, oprom, opram, options); +} + + +#include "6805ops.hxx" + +//------------------------------------------------- +// execute_clocks_to_cycles - convert the raw +// clock into cycles per second +//------------------------------------------------- + +uint64_t m6805_base_device::execute_clocks_to_cycles(uint64_t clocks) const +{ + return (clocks + 3) / 4; +} + + +//------------------------------------------------- +// execute_cycles_to_clocks - convert a cycle +// count back to raw clocks +//------------------------------------------------- + +uint64_t m6805_base_device::execute_cycles_to_clocks(uint64_t cycles) const +{ + return cycles * 4; +} + + +//------------------------------------------------- +// execute_min_cycles - return minimum number of +// cycles it takes for one instruction to execute +//------------------------------------------------- + +uint32_t m6805_base_device::execute_min_cycles() const +{ + // 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; +} + + +//------------------------------------------------- +// execute_max_cycles - return maximum number of +// cycles it takes for one instruction to execute +//------------------------------------------------- + +uint32_t m6805_base_device::execute_max_cycles() const +{ + u32 const result(*std::max_element(std::begin(m_params.m_cycles), std::end(m_params.m_cycles))); + return result; +} + + +//------------------------------------------------- +// execute_input_lines - return the number of +// input/interrupt lines +//------------------------------------------------- + +uint32_t m6805_base_device::execute_input_lines() const +{ + return 9; +} + + +/* execute instructions on this CPU until icount expires */ +void m6805_base_device::execute_run() +{ + S = SP_ADJUST( S ); /* Taken from CPU_SET_CONTEXT when pointer'afying */ + + do + { + if (m_pending_interrupts != 0) + { + interrupt(); + } + + debugger_instruction_hook(this, PC); + + u8 const ireg = rdop(PC++); + + (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(); + + rm16(0x1ffe, m_pc); +} + +void m68hc05eg_device::execute_set_input(int inputnum, int state) +{ + if (m_irq_state[inputnum] != state) + { + m_irq_state[inputnum] = state; + + if (state != CLEAR_LINE) + { + m_pending_interrupts |= 1 << inputnum; + } + } +} + void m68hc05eg_device::interrupt_vector() { if ((m_pending_interrupts & (1 << M68HC05EG_INT_IRQ)) != 0) @@ -154,6 +615,60 @@ void m68hc05eg_device::interrupt_vector() } } + +/**************************************************************************** + * 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_s.w.l = SP_MASK; + + rm16(0x1ffe, m_pc); +} + +void hd63705_device::execute_set_input(int inputnum, int state) +{ + if (inputnum == INPUT_LINE_NMI) + { + if (m_nmi_state != state) + { + m_nmi_state = state; + + if (state != CLEAR_LINE) + { + m_pending_interrupts |= 1 << HD63705_INT_NMI; + } + } + } + else if (inputnum <= HD63705_INT_ADCONV) + { + if (m_irq_state[inputnum] != state) + { + m_irq_state[inputnum] = state; + + if (state != CLEAR_LINE) + { + m_pending_interrupts |= 1 << inputnum; + } + } + } +} + void hd63705_device::interrupt_vector() { /* Need to add emulation of other interrupt sources here KW-2/4/99 */ @@ -201,367 +716,6 @@ void hd63705_device::interrupt_vector() } } -/* 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); - } -} - - -//------------------------------------------------- -// 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) - : cpu_device(mconfig, type, name, tag, owner, clock, shortname, source) - , m_program_config("program", ENDIANNESS_BIG, 8, 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) - : cpu_device(mconfig, type, name, tag, owner, clock, shortname, source) - , m_program_config("program", ENDIANNESS_BIG, 8, addr_width, 0, internal_map) -{ -} - - - -void m6805_base_device::device_start() -{ - m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); - - // set our instruction counter - m_icountptr = &m_icount; - - // register our state for the debugger - state_add(STATE_GENPC, "GENPC", m_pc.w.l).noshow(); - state_add(STATE_GENPCBASE, "CURPC", m_pc.w.l).noshow(); - state_add(STATE_GENFLAGS, "GENFLAGS", m_cc).callimport().callexport().formatstr("%8s").noshow(); - state_add(M6805_A, "A", m_a).mask(0xff); - state_add(M6805_PC, "PC", m_pc.w.l).mask(0xffff); - state_add(M6805_S, "S", m_s.w.l).mask(0xff); - state_add(M6805_X, "X", m_x).mask(0xff); - state_add(M6805_CC, "CC", m_cc).mask(0xff); - - // 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)); - save_item(NAME(X)); - save_item(NAME(CC)); - save_item(NAME(m_pending_interrupts)); - save_item(NAME(m_irq_state)); - save_item(NAME(m_nmi_state)); - - 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; - m_x = 0; - m_cc = 0; - m_pending_interrupts = 0; - - m_nmi_state = 0; - - m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); - - /* IRQ disabled */ - SEI; - - rm16(0xfffe, m_pc); -} - - -//------------------------------------------------- -// memory_space_config - return the configuration -// of the specified address space, or nullptr if -// the space doesn't exist -//------------------------------------------------- - -const address_space_config *m6805_base_device::memory_space_config(address_spacenum spacenum) const -{ - if (spacenum == AS_PROGRAM) - { - return &m_program_config; - } - return nullptr; -} - - -//------------------------------------------------- -// state_string_export - export state as a string -// for the debugger -//------------------------------------------------- - -void m6805_base_device::state_string_export(const device_state_entry &entry, std::string &str) const -{ - 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; - } -} - - -//------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes -//------------------------------------------------- - -uint32_t m6805_base_device::disasm_min_opcode_bytes() const -{ - return 1; -} - - -//------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t m6805_base_device::disasm_max_opcode_bytes() const -{ - return 3; -} - - -//------------------------------------------------- -// disasm_disassemble - call the disassembly -// helper function -//------------------------------------------------- - -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" - -//------------------------------------------------- -// execute_clocks_to_cycles - convert the raw -// clock into cycles per second -//------------------------------------------------- - -uint64_t m6805_base_device::execute_clocks_to_cycles(uint64_t clocks) const -{ - return (clocks + 3) / 4; -} - - -//------------------------------------------------- -// execute_cycles_to_clocks - convert a cycle -// count back to raw clocks -//------------------------------------------------- - -uint64_t m6805_base_device::execute_cycles_to_clocks(uint64_t cycles) const -{ - return cycles * 4; -} - - -//------------------------------------------------- -// execute_min_cycles - return minimum number of -// cycles it takes for one instruction to execute -//------------------------------------------------- - -uint32_t m6805_base_device::execute_min_cycles() const -{ - return 2; -} - - -//------------------------------------------------- -// execute_max_cycles - return maximum number of -// cycles it takes for one instruction to execute -//------------------------------------------------- - -uint32_t m6805_base_device::execute_max_cycles() const -{ - return 10; -} - - -//------------------------------------------------- -// execute_input_lines - return the number of -// input/interrupt lines -//------------------------------------------------- - -uint32_t m6805_base_device::execute_input_lines() const -{ - return 9; -} - - -/* execute instructions on this CPU until icount expires */ -void m6805_base_device::execute_run() -{ - S = SP_ADJUST( S ); /* Taken from CPU_SET_CONTEXT when pointer'afying */ - - do - { - if (m_pending_interrupts != 0) - { - interrupt(); - } - - debugger_instruction_hook(this, PC); - - u8 const ireg = rdop(PC++); - - (this->*m_hmos_ops[ireg])(); - m_icount -= m_hmos_cycles[ireg]; - burn_cycles(m_hmos_cycles[ireg]); - } - while (m_icount > 0); -} - -/**************************************************************************** - * M68HC05EG section - ****************************************************************************/ -void m68hc05eg_device::device_reset() -{ - m6805_base_device::device_reset(); - - m_sp_mask = 0xff; - m_sp_low = 0xc0; - - rm16(0x1ffe, m_pc); -} - -void m68hc05eg_device::execute_set_input(int inputnum, int state) -{ - if (m_irq_state[inputnum] != state) - { - m_irq_state[inputnum] = state; - - if (state != CLEAR_LINE) - { - m_pending_interrupts |= 1 << inputnum; - } - } -} - - -/**************************************************************************** - * HD63705 section - ****************************************************************************/ -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); -} - -void hd63705_device::execute_set_input(int inputnum, int state) -{ - if (inputnum == INPUT_LINE_NMI) - { - if (m_nmi_state != state) - { - m_nmi_state = state; - - if (state != CLEAR_LINE) - { - m_pending_interrupts |= 1 << HD63705_INT_NMI; - } - } - } - else if (inputnum <= HD63705_INT_ADCONV) - { - if (m_irq_state[inputnum] != state) - { - m_irq_state[inputnum] = state; - - if (state != CLEAR_LINE) - { - m_pending_interrupts |= 1 << inputnum; - } - } - } -} const device_type M6805 = &device_creator; const device_type M68HC05EG = &device_creator; 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 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 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 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 +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 const (&symbols)[N]) +{ + return CPU_DISASSEMBLE_NAME(m146805)(device, stream, pc, oprom, opram, options, symbols, N); +} + +template +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 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; /**************************************************************************** - * 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 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; + + +/**************************************************************************** + * 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) },