mirror of
https://github.com/holub/mame
synced 2025-07-01 16:19:38 +03:00
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
This commit is contained in:
parent
0995b978ac
commit
06e22ce79d
@ -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
|
||||
end
|
||||
|
@ -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 <typename T>
|
||||
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<u16, char const *> 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<u16, char const *> 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<u16, char const *> 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<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(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); }
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 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<m6805_device>;
|
||||
const device_type M68HC05EG = &device_creator<m68hc05eg_device>;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 }
|
||||
|
167
src/devices/cpu/m6805/m68hc05.cpp
Normal file
167
src/devices/cpu/m6805/m68hc05.cpp
Normal file
@ -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);
|
||||
}
|
69
src/devices/cpu/m6805/m68hc05.h
Normal file
69
src/devices/cpu/m6805/m68hc05.h
Normal file
@ -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
|
@ -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) },
|
||||
|
Loading…
Reference in New Issue
Block a user