mirror of
https://github.com/holub/mame
synced 2025-07-05 18:08:04 +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/6805ops.hxx",
|
||||||
MAME_DIR .. "src/devices/cpu/m6805/m68705.cpp",
|
MAME_DIR .. "src/devices/cpu/m6805/m68705.cpp",
|
||||||
MAME_DIR .. "src/devices/cpu/m6805/m68705.h",
|
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
|
end
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// license:BSD-3-Clause
|
// license:BSD-3-Clause
|
||||||
// copyright-holders:Aaron Giles
|
// copyright-holders:Aaron Giles, Vas Crabb
|
||||||
/*
|
/*
|
||||||
* A quick-hack 68(7)05 disassembler
|
* A quick-hack 68(7)05 disassembler
|
||||||
*
|
*
|
||||||
@ -18,7 +18,7 @@
|
|||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
enum class md {
|
enum class md {
|
||||||
IMP, // implicit
|
INH, // inherent
|
||||||
BTR, // bit test and relative
|
BTR, // bit test and relative
|
||||||
BIT, // bit set/clear
|
BIT, // bit set/clear
|
||||||
REL, // relative
|
REL, // relative
|
||||||
@ -30,139 +30,97 @@ enum class md {
|
|||||||
IX2 // indexed + word offset
|
IX2 // indexed + word offset
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class lvl {
|
||||||
|
HMOS,
|
||||||
|
CMOS,
|
||||||
|
HC
|
||||||
|
};
|
||||||
|
|
||||||
enum op_names {
|
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,
|
asrx, bcc, bclr, bcs, beq, bhcc, bhcs, bhi,
|
||||||
bih, bil, bita, bls, bmc, bmi, bms, bne,
|
bih, bil, bita, bls, bmc, bmi, bms, bne,
|
||||||
bpl, bra, brclr, brn, brset, bset, bsr, clc,
|
bpl, bra, brclr, brn, brset, bset, bsr, clc,
|
||||||
cli, clr, clra, clrx, cmpa, com, coma, comx,
|
cli, clr, clra, clrx, cmpa, com, coma, comx,
|
||||||
cpx, dec, deca, decx, eora, ill, inc, inca,
|
cpx, dec, deca, decx, eora, ill, inc, inca,
|
||||||
incx, jmp, jsr, lda, ldx, lsr, lsra, lsrx,
|
incx, jmp, jsr, lda, ldx, lsr, lsra, lsrx,
|
||||||
neg, nega, negx, nop, ora, rol, rola, rolx,
|
mul, neg, nega, negx, nop, ora, rol, rola,
|
||||||
ror, rora, rorx, rsp, rti, rts, sbca, sec,
|
rolx, ror, rora, rorx, rsp, rti, rts, sbca,
|
||||||
sei, sta, stx, suba, swi, tax, tst, tsta,
|
sec, sei, sta, stop, stx, suba, swi, tax,
|
||||||
tstx, txa
|
tst, tsta, tstx, txa, wait
|
||||||
};
|
};
|
||||||
|
|
||||||
char const *const op_name_str[] = {
|
#define OP(name, mode) { name, #name, md::mode, lvl::HMOS }
|
||||||
"adca", "adda", "anda", "asl", "asla", "aslx", "asr", "asra",
|
#define OPC(name, mode) { name, #name, md::mode, lvl::CMOS }
|
||||||
"asrx", "bcc", "bclr", "bcs", "beq", "bhcc", "bhcs", "bhi",
|
#define OPHC(name, mode) { name, #name, md::mode, lvl::HC }
|
||||||
"bih", "bil", "bita", "bls", "bmc", "bmi", "bms", "bne",
|
#define ILLEGAL { ill, nullptr, md::INH, lvl::HMOS }
|
||||||
"bpl", "bra", "brclr","brn", "brset","bset", "bsr", "clc",
|
struct { op_names op; char const *name; md mode; lvl level; } const disasm[0x100] = {
|
||||||
"cli", "clr", "clra", "clrx", "cmpa", "com", "coma", "comx",
|
OP (brset,BTR), OP (brclr,BTR), OP (brset,BTR), OP (brclr,BTR), // 00
|
||||||
"cpx", "dec", "deca", "decx", "eora", "*ill", "inc", "inca",
|
OP (brset,BTR), OP (brclr,BTR), OP (brset,BTR), OP (brclr,BTR),
|
||||||
"incx", "jmp", "jsr", "lda", "ldx", "lsr", "lsra", "lsrx",
|
OP (brset,BTR), OP (brclr,BTR), OP (brset,BTR), OP (brclr,BTR),
|
||||||
"neg", "nega", "negx", "nop", "ora", "rol", "rola", "rolx",
|
OP (brset,BTR), OP (brclr,BTR), OP (brset,BTR), OP (brclr,BTR),
|
||||||
"ror", "rora", "rorx", "rsp", "rti", "rts", "sbca", "sec",
|
OP (bset, BIT), OP (bclr, BIT), OP (bset, BIT), OP (bclr, BIT), // 10
|
||||||
"sei", "sta", "stx", "suba", "swi", "tax", "tst", "tsta",
|
OP (bset, BIT), OP (bclr, BIT), OP (bset, BIT), OP (bclr, BIT),
|
||||||
"tstx", "txa"
|
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>
|
template <typename T>
|
||||||
void format_address(
|
void format_address(
|
||||||
@ -182,22 +140,28 @@ void format_address(
|
|||||||
util::stream_format(stream, "$%0*X", 2 * sizeof(T), address);
|
util::stream_format(stream, "$%0*X", 2 * sizeof(T), address);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // anonymous namespace
|
|
||||||
|
|
||||||
|
offs_t disassemble(
|
||||||
offs_t CPU_DISASSEMBLE_NAME(m6805)(
|
|
||||||
cpu_device *device,
|
cpu_device *device,
|
||||||
std::ostream &stream,
|
std::ostream &stream,
|
||||||
offs_t pc,
|
offs_t pc,
|
||||||
const u8 *oprom,
|
const u8 *oprom,
|
||||||
const u8 *opram,
|
const u8 *opram,
|
||||||
int options,
|
int options,
|
||||||
|
lvl level,
|
||||||
std::pair<u16, char const *> const symbols[],
|
std::pair<u16, char const *> const symbols[],
|
||||||
std::size_t symbol_count)
|
std::size_t symbol_count)
|
||||||
{
|
{
|
||||||
u8 const code = oprom[0];
|
u8 const code = oprom[0];
|
||||||
|
|
||||||
u32 flags = 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)
|
switch (disasm[code].op)
|
||||||
{
|
{
|
||||||
case bsr:
|
case bsr:
|
||||||
@ -208,15 +172,17 @@ offs_t CPU_DISASSEMBLE_NAME(m6805)(
|
|||||||
case rti:
|
case rti:
|
||||||
flags = DASMFLAG_STEP_OUT;
|
flags = DASMFLAG_STEP_OUT;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
flags = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
util::stream_format(stream, "%-6s", op_name_str[disasm[code].op]);
|
util::stream_format(stream, "%-6s", disasm[code].name);
|
||||||
|
|
||||||
int bit;
|
int bit;
|
||||||
u16 ea;
|
u16 ea;
|
||||||
switch (disasm[code].mode)
|
switch (disasm[code].mode)
|
||||||
{
|
{
|
||||||
case md::IMP: // implicit
|
case md::INH: // inherent
|
||||||
return 1 | flags | DASMFLAG_SUPPORTED;
|
return 1 | flags | DASMFLAG_SUPPORTED;
|
||||||
|
|
||||||
case md::BTR: // bit test and relative branch
|
case md::BTR: // bit test and relative branch
|
||||||
@ -266,6 +232,50 @@ offs_t CPU_DISASSEMBLE_NAME(m6805)(
|
|||||||
// if we fall off the switch statement something is very wrong
|
// if we fall off the switch statement something is very wrong
|
||||||
throw false;
|
throw false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
|
||||||
|
offs_t CPU_DISASSEMBLE_NAME(m6805)(
|
||||||
|
cpu_device *device,
|
||||||
|
std::ostream &stream,
|
||||||
|
offs_t pc,
|
||||||
|
const u8 *oprom,
|
||||||
|
const u8 *opram,
|
||||||
|
int options,
|
||||||
|
std::pair<u16, char const *> const symbols[],
|
||||||
|
std::size_t symbol_count)
|
||||||
|
{
|
||||||
|
return disassemble(device, stream, pc, oprom, opram, options, lvl::HMOS, symbols, symbol_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
offs_t CPU_DISASSEMBLE_NAME(m146805)(
|
||||||
|
cpu_device *device,
|
||||||
|
std::ostream &stream,
|
||||||
|
offs_t pc,
|
||||||
|
const u8 *oprom,
|
||||||
|
const u8 *opram,
|
||||||
|
int options,
|
||||||
|
std::pair<u16, char const *> const symbols[],
|
||||||
|
std::size_t symbol_count)
|
||||||
|
{
|
||||||
|
return disassemble(device, stream, pc, oprom, opram, options, lvl::CMOS, symbols, symbol_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
offs_t CPU_DISASSEMBLE_NAME(m68hc05)(
|
||||||
|
cpu_device *device,
|
||||||
|
std::ostream &stream,
|
||||||
|
offs_t pc,
|
||||||
|
const u8 *oprom,
|
||||||
|
const u8 *opram,
|
||||||
|
int options,
|
||||||
|
std::pair<u16, char const *> const symbols[],
|
||||||
|
std::size_t symbol_count)
|
||||||
|
{
|
||||||
|
return disassemble(device, stream, pc, oprom, opram, options, lvl::HC, symbols, symbol_count);
|
||||||
|
}
|
||||||
|
|
||||||
CPU_DISASSEMBLE(m6805) { return CPU_DISASSEMBLE_NAME(m6805) (device, stream, pc, oprom, opram, options, nullptr, 0); }
|
CPU_DISASSEMBLE(m6805) { return CPU_DISASSEMBLE_NAME(m6805) (device, stream, pc, oprom, opram, options, nullptr, 0); }
|
||||||
|
CPU_DISASSEMBLE(m146805) { return CPU_DISASSEMBLE_NAME(m146805)(device, stream, pc, oprom, opram, options, nullptr, 0); }
|
||||||
|
CPU_DISASSEMBLE(m68hc05) { return CPU_DISASSEMBLE_NAME(m68hc05)(device, stream, pc, oprom, opram, options, nullptr, 0); }
|
||||||
|
@ -291,7 +291,14 @@ OP_HANDLER( nega )
|
|||||||
|
|
||||||
// $41 ILLEGAL
|
// $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
|
// $43 COMA inherent -**1
|
||||||
OP_HANDLER( coma )
|
OP_HANDLER( coma )
|
||||||
@ -519,17 +526,7 @@ OP_HANDLER( swi )
|
|||||||
pushbyte(m_a);
|
pushbyte(m_a);
|
||||||
pushbyte(m_cc);
|
pushbyte(m_cc);
|
||||||
SEI;
|
SEI;
|
||||||
rm16(0xfffc, m_pc);
|
rm16(m_params.m_swi_vector, m_pc);
|
||||||
}
|
|
||||||
|
|
||||||
DERIVED_OP_HANDLER( hd63705, swi )
|
|
||||||
{
|
|
||||||
pushword(m_pc);
|
|
||||||
pushbyte(m_x);
|
|
||||||
pushbyte(m_a);
|
|
||||||
pushbyte(m_cc);
|
|
||||||
SEI;
|
|
||||||
rm16(0x1ffa, m_pc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// $84 ILLEGAL
|
// $84 ILLEGAL
|
||||||
@ -552,9 +549,18 @@ DERIVED_OP_HANDLER( hd63705, swi )
|
|||||||
|
|
||||||
// $8D ILLEGAL
|
// $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
|
// $90 ILLEGAL
|
||||||
|
|
||||||
|
@ -49,7 +49,8 @@
|
|||||||
#define OP_IX(name) (&m6805_base_device::name<addr_mode::IX>)
|
#define OP_IX(name) (&m6805_base_device::name<addr_mode::IX>)
|
||||||
#define OP_IX1(name) (&m6805_base_device::name<addr_mode::IX1>)
|
#define OP_IX1(name) (&m6805_base_device::name<addr_mode::IX1>)
|
||||||
#define OP_IX2(name) (&m6805_base_device::name<addr_mode::IX2>)
|
#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/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>),
|
/* 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)
|
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 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,
|
/*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
|
/*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 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,
|
/*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()
|
void m6805_base_device::interrupt_vector()
|
||||||
{
|
{
|
||||||
rm16(0xfffa, m_pc);
|
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()
|
void m68hc05eg_device::interrupt_vector()
|
||||||
{
|
{
|
||||||
if ((m_pending_interrupts & (1 << M68HC05EG_INT_IRQ)) != 0)
|
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()
|
void hd63705_device::interrupt_vector()
|
||||||
{
|
{
|
||||||
/* Need to add emulation of other interrupt sources here KW-2/4/99 */
|
/* 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 M6805 = &device_creator<m6805_device>;
|
||||||
const device_type M68HC05EG = &device_creator<m68hc05eg_device>;
|
const device_type M68HC05EG = &device_creator<m68hc05eg_device>;
|
||||||
|
@ -21,10 +21,6 @@ extern const device_type HD63705;
|
|||||||
// Used by core CPU interface
|
// Used by core CPU interface
|
||||||
class m6805_base_device : public cpu_device
|
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:
|
protected:
|
||||||
// addressing mode selector for opcode handler templates
|
// addressing mode selector for opcode handler templates
|
||||||
enum class addr_mode { IM, DI, EX, IX, IX1, IX2 };
|
enum class addr_mode { IM, DI, EX, IX, IX1, IX2 };
|
||||||
@ -52,13 +48,65 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
typedef void (m6805_base_device::*op_handler_func)();
|
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
|
// opcode tables
|
||||||
static op_handler_func const m_hmos_ops[256];
|
static op_handler_table s_hmos_ops;
|
||||||
static u8 const m_hmos_cycles[256];
|
static op_handler_table s_cmos_ops;
|
||||||
static u8 const m_cmos_cycles[256];
|
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
|
// device-level overrides
|
||||||
virtual void device_start() override;
|
virtual void device_start() override;
|
||||||
@ -89,6 +137,7 @@ protected:
|
|||||||
|
|
||||||
void clr_nz() { m_cc &= ~(NFLAG | ZFLAG); }
|
void clr_nz() { m_cc &= ~(NFLAG | ZFLAG); }
|
||||||
void clr_nzc() { m_cc &= ~(NFLAG | ZFLAG | CFLAG); }
|
void clr_nzc() { m_cc &= ~(NFLAG | ZFLAG | CFLAG); }
|
||||||
|
void clr_hc() { m_cc &= ~(HFLAG | CFLAG); }
|
||||||
void clr_hnzc() { m_cc &= ~(HFLAG | NFLAG | ZFLAG | CFLAG); }
|
void clr_hnzc() { m_cc &= ~(HFLAG | NFLAG | ZFLAG | CFLAG); }
|
||||||
|
|
||||||
// macros for CC -- CC bits affected should be reset before calling
|
// macros for CC -- CC bits affected should be reset before calling
|
||||||
@ -149,6 +198,7 @@ protected:
|
|||||||
template <addr_mode M> void clr();
|
template <addr_mode M> void clr();
|
||||||
|
|
||||||
void nega();
|
void nega();
|
||||||
|
void mul();
|
||||||
void coma();
|
void coma();
|
||||||
void lsra();
|
void lsra();
|
||||||
void rora();
|
void rora();
|
||||||
@ -174,7 +224,9 @@ protected:
|
|||||||
|
|
||||||
void rti();
|
void rti();
|
||||||
void rts();
|
void rts();
|
||||||
virtual void swi();
|
void swi();
|
||||||
|
void stop();
|
||||||
|
void wait();
|
||||||
|
|
||||||
void tax();
|
void tax();
|
||||||
void txa();
|
void txa();
|
||||||
@ -209,16 +261,14 @@ protected:
|
|||||||
virtual void interrupt();
|
virtual void interrupt();
|
||||||
virtual void interrupt_vector();
|
virtual void interrupt_vector();
|
||||||
|
|
||||||
const char *m_tag;
|
configuration_params const m_params;
|
||||||
|
|
||||||
// address spaces
|
// address spaces
|
||||||
const address_space_config m_program_config;
|
address_space_config const m_program_config;
|
||||||
|
|
||||||
// CPU registers
|
// CPU registers
|
||||||
PAIR m_ea; // effective address (should really be a temporary in opcode handlers)
|
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_pc; // Program counter
|
||||||
PAIR m_s; // Stack pointer
|
PAIR m_s; // Stack pointer
|
||||||
u8 m_a; // Accumulator
|
u8 m_a; // Accumulator
|
||||||
@ -245,8 +295,7 @@ class m6805_device : public m6805_base_device
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// construction/destruction
|
// construction/destruction
|
||||||
m6805_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
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__) { }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void execute_set_input(int inputnum, int state) override;
|
virtual void execute_set_input(int inputnum, int state) override;
|
||||||
@ -259,8 +308,7 @@ class m68hc05eg_device : public m6805_base_device
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// construction/destruction
|
// construction/destruction
|
||||||
m68hc05eg_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
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__) { }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// device-level overrides
|
// device-level overrides
|
||||||
@ -277,8 +325,7 @@ class hd63705_device : public m6805_base_device
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// construction/destruction
|
// construction/destruction
|
||||||
hd63705_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
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__) { }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// device-level overrides
|
// device-level overrides
|
||||||
@ -291,7 +338,6 @@ protected:
|
|||||||
// opcodes
|
// opcodes
|
||||||
virtual void bil() override;
|
virtual void bil() override;
|
||||||
virtual void bih() override;
|
virtual void bih() override;
|
||||||
virtual void swi() override;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define M6805_IRQ_LINE 0
|
#define M6805_IRQ_LINE 0
|
||||||
@ -331,5 +377,7 @@ protected:
|
|||||||
#define HD63705_INT_NMI 0x08
|
#define HD63705_INT_NMI 0x08
|
||||||
|
|
||||||
CPU_DISASSEMBLE( m6805 );
|
CPU_DISASSEMBLE( m6805 );
|
||||||
|
CPU_DISASSEMBLE( m146805 );
|
||||||
|
CPU_DISASSEMBLE( m68hc05 );
|
||||||
|
|
||||||
#endif // MAME_CPU_M6805_M6805_H
|
#endif // MAME_CPU_M6805_M6805_H
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define SP_MASK m_sp_mask // stack pointer mask
|
#define SP_MASK m_params.m_sp_mask // stack pointer mask
|
||||||
#define SP_LOW m_sp_low // stack pointer low water mark
|
#define SP_LOW m_params.m_sp_floor // stack pointer low water mark
|
||||||
#define PC m_pc.w.l // program counter lower word
|
#define PC m_pc.w.l // program counter lower word
|
||||||
#define S m_s.w.l // stack pointer lower word
|
#define S m_s.w.l // stack pointer lower word
|
||||||
#define A m_a // accumulator
|
#define A m_a // accumulator
|
||||||
@ -116,6 +116,26 @@ inline void m6805_base_device::skipbyte() { rdop_arg(PC++); }
|
|||||||
/* Macros for branch instructions */
|
/* Macros for branch instructions */
|
||||||
#define BRANCH(f) do { u8 t; immbyte(t); if (bool(f) == bool(C)) PC += SIGNED(t); } while (false)
|
#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)(
|
offs_t CPU_DISASSEMBLE_NAME(m6805)(
|
||||||
cpu_device *device,
|
cpu_device *device,
|
||||||
std::ostream &stream,
|
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);
|
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
|
#endif // MAME_CPU_M6805_M6805DEFS_H
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
// license:BSD-3-Clause
|
||||||
|
// copyright-holders:Vas Crabb
|
||||||
#include "emu.h"
|
#include "emu.h"
|
||||||
#include "m68705.h"
|
#include "m68705.h"
|
||||||
#include "m6805defs.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,
|
address_map_delegate internal_map,
|
||||||
char const *shortname,
|
char const *shortname,
|
||||||
char const *source)
|
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)
|
, device_nvram_interface(mconfig, *this)
|
||||||
, m_user_rom(*this, DEVICE_SELF, u32(1) << addr_width)
|
, m_user_rom(*this, DEVICE_SELF, u32(1) << addr_width)
|
||||||
, m_port_open_drain{ false, false, false, false }
|
, 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( m68030 );
|
||||||
CPU_DISASSEMBLE( m68040 );
|
CPU_DISASSEMBLE( m68040 );
|
||||||
CPU_DISASSEMBLE( m6805 );
|
CPU_DISASSEMBLE( m6805 );
|
||||||
|
CPU_DISASSEMBLE( m146805 );
|
||||||
|
CPU_DISASSEMBLE( m68hc05 );
|
||||||
CPU_DISASSEMBLE( m6808 );
|
CPU_DISASSEMBLE( m6808 );
|
||||||
CPU_DISASSEMBLE( m6809 );
|
CPU_DISASSEMBLE( m6809 );
|
||||||
CPU_DISASSEMBLE( m68340 );
|
CPU_DISASSEMBLE( m68340 );
|
||||||
@ -311,6 +313,8 @@ static const dasm_table_entry dasm_table[] =
|
|||||||
{ "m68030", _16be, 0, CPU_DISASSEMBLE_NAME(m68030) },
|
{ "m68030", _16be, 0, CPU_DISASSEMBLE_NAME(m68030) },
|
||||||
{ "m68040", _16be, 0, CPU_DISASSEMBLE_NAME(m68040) },
|
{ "m68040", _16be, 0, CPU_DISASSEMBLE_NAME(m68040) },
|
||||||
{ "m6805", _8bit, 0, CPU_DISASSEMBLE_NAME(m6805) },
|
{ "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) },
|
{ "m6808", _8bit, 0, CPU_DISASSEMBLE_NAME(m6808) },
|
||||||
{ "m6809", _8bit, 0, CPU_DISASSEMBLE_NAME(m6809) },
|
{ "m6809", _8bit, 0, CPU_DISASSEMBLE_NAME(m6809) },
|
||||||
{ "m68340", _16be, 0, CPU_DISASSEMBLE_NAME(m68340) },
|
{ "m68340", _16be, 0, CPU_DISASSEMBLE_NAME(m68340) },
|
||||||
|
Loading…
Reference in New Issue
Block a user