diff options
Diffstat (limited to 'src/devices/cpu/m6805/m6805.cpp')
-rw-r--r-- | src/devices/cpu/m6805/m6805.cpp | 450 |
1 files changed, 240 insertions, 210 deletions
diff --git a/src/devices/cpu/m6805/m6805.cpp b/src/devices/cpu/m6805/m6805.cpp index 2aa2ddc54ca..5feef38faef 100644 --- a/src/devices/cpu/m6805/m6805.cpp +++ b/src/devices/cpu/m6805/m6805.cpp @@ -37,27 +37,28 @@ #include "m6805defs.h" #include "6805dasm.h" -#include "debugger.h" - #include <algorithm> -#define OP(name) (&m6805_base_device::name) -#define OP_T(name) (&m6805_base_device::name<true>) -#define OP_F(name) (&m6805_base_device::name<false>) -#define OP_IM(name) (&m6805_base_device::name<addr_mode::IM>) -#define OP_DI(name) (&m6805_base_device::name<addr_mode::DI>) -#define OP_EX(name) (&m6805_base_device::name<addr_mode::EX>) -#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>) +#define OP(name) (&m6805_base_device::name<big>) +#define OPN(name,n) (&m6805_base_device::name<big, n>) +#define OP_T(name) (&m6805_base_device::name<big, true>) +#define OP_F(name) (&m6805_base_device::name<big, false>) +#define OP_IM(name) (&m6805_base_device::name<big, addr_mode::IM>) +#define OP_DI(name) (&m6805_base_device::name<big, addr_mode::DI>) +#define OP_EX(name) (&m6805_base_device::name<big, addr_mode::EX>) +#define OP_IX(name) (&m6805_base_device::name<big, addr_mode::IX>) +#define OP_IX1(name) (&m6805_base_device::name<big, addr_mode::IX1>) +#define OP_IX2(name) (&m6805_base_device::name<big, addr_mode::IX2>) + +#define big false -const m6805_base_device::op_handler_table m6805_base_device::s_hmos_ops = +const m6805_base_device::op_handler_table m6805_base_device::s_hmos_s_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>), + /* 0 */ OPN(brset,0),OPN(brclr,0),OPN(brset,1),OPN(brclr,1),OPN(brset,2),OPN(brclr,2),OPN(brset,3),OPN(brclr,3), + OPN(brset,4),OPN(brclr,4),OPN(brset,5),OPN(brclr,5),OPN(brset,6),OPN(brclr,6),OPN(brset,7),OPN(brclr,7), + /* 1 */ OPN(bset,0), OPN(bclr,0), OPN(bset,1), OPN(bclr,1), OPN(bset,2), OPN(bclr,2), OPN(bset,3), OPN(bclr,3), + OPN(bset,4), OPN(bclr,4), OPN(bset,5), OPN(bclr,5), OPN(bset,6), OPN(bclr,6), OPN(bset,7), OPN(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_T(bil), OP_F(bil), /* 3 */ OP_DI(neg), OP(illegal), OP(illegal), OP_DI(com), OP_DI(lsr), OP(illegal), OP_DI(ror), OP_DI(asr), @@ -88,13 +89,90 @@ const m6805_base_device::op_handler_table m6805_base_device::s_hmos_ops = 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 = +const m6805_base_device::op_handler_table m6805_base_device::s_hc_s_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>), + /* 0 */ OPN(brset,0),OPN(brclr,0),OPN(brset,1),OPN(brclr,1),OPN(brset,2),OPN(brclr,2),OPN(brset,3),OPN(brclr,3), + OPN(brset,4),OPN(brclr,4),OPN(brset,5),OPN(brclr,5),OPN(brset,6),OPN(brclr,6),OPN(brset,7),OPN(brclr,7), + /* 1 */ OPN(bset,0), OPN(bclr,0), OPN(bset,1), OPN(bclr,1), OPN(bset,2), OPN(bclr,2), OPN(bset,3), OPN(bclr,3), + OPN(bset,4), OPN(bclr,4), OPN(bset,5), OPN(bclr,5), OPN(bset,6), OPN(bclr,6), OPN(bset,7), OPN(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_T(bil), OP_F(bil), + /* 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) +}; + +#undef big +#define big true + +const m6805_base_device::op_handler_table m6805_base_device::s_hmos_b_ops = +{ + /* 0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F */ + /* 0 */ OPN(brset,0),OPN(brclr,0),OPN(brset,1),OPN(brclr,1),OPN(brset,2),OPN(brclr,2),OPN(brset,3),OPN(brclr,3), + OPN(brset,4),OPN(brclr,4),OPN(brset,5),OPN(brclr,5),OPN(brset,6),OPN(brclr,6),OPN(brset,7),OPN(brclr,7), + /* 1 */ OPN(bset,0), OPN(bclr,0), OPN(bset,1), OPN(bclr,1), OPN(bset,2), OPN(bclr,2), OPN(bset,3), OPN(bclr,3), + OPN(bset,4), OPN(bclr,4), OPN(bset,5), OPN(bclr,5), OPN(bset,6), OPN(bclr,6), OPN(bset,7), OPN(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_T(bil), OP_F(bil), + /* 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(illegal), OP(illegal), + /* 9 */ OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(tax), + OP(clc), OP(sec), OP(cli), OP(sei), OP(rsp), OP(nop), OP(illegal), OP(txa), + /* A */ OP_IM(suba), OP_IM(cmpa), OP_IM(sbca), OP_IM(cpx), OP_IM(anda), OP_IM(bita), OP_IM(lda), OP(illegal), + OP_IM(eora), OP_IM(adca), OP_IM(ora), OP_IM(adda), OP(illegal), OP(bsr), OP_IM(ldx), OP(illegal), + /* B */ OP_DI(suba), OP_DI(cmpa), OP_DI(sbca), OP_DI(cpx), OP_DI(anda), OP_DI(bita), OP_DI(lda), OP_DI(sta), + OP_DI(eora), OP_DI(adca), OP_DI(ora), OP_DI(adda), OP_DI(jmp), OP_DI(jsr), OP_DI(ldx), OP_DI(stx), + /* C */ OP_EX(suba), OP_EX(cmpa), OP_EX(sbca), OP_EX(cpx), OP_EX(anda), OP_EX(bita), OP_EX(lda), OP_EX(sta), + OP_EX(eora), OP_EX(adca), OP_EX(ora), OP_EX(adda), OP_EX(jmp), OP_EX(jsr), OP_EX(ldx), OP_EX(stx), + /* D */ OP_IX2(suba),OP_IX2(cmpa),OP_IX2(sbca),OP_IX2(cpx), OP_IX2(anda),OP_IX2(bita),OP_IX2(lda), OP_IX2(sta), + OP_IX2(eora),OP_IX2(adca),OP_IX2(ora), OP_IX2(adda),OP_IX2(jmp), OP_IX2(jsr), OP_IX2(ldx), OP_IX2(stx), + /* E */ OP_IX1(suba),OP_IX1(cmpa),OP_IX1(sbca),OP_IX1(cpx), OP_IX1(anda),OP_IX1(bita),OP_IX1(lda), OP_IX1(sta), + OP_IX1(eora),OP_IX1(adca),OP_IX1(ora), OP_IX1(adda),OP_IX1(jmp), OP_IX1(jsr), OP_IX1(ldx), OP_IX1(stx), + /* F */ OP_IX(suba), OP_IX(cmpa), OP_IX(sbca), OP_IX(cpx), OP_IX(anda), OP_IX(bita), OP_IX(lda), OP_IX(sta), + OP_IX(eora), OP_IX(adca), OP_IX(ora), OP_IX(adda), OP_IX(jmp), OP_IX(jsr), OP_IX(ldx), OP_IX(stx) +}; + +const m6805_base_device::op_handler_table m6805_base_device::s_cmos_b_ops = +{ + /* 0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F */ + /* 0 */ OPN(brset,0),OPN(brclr,0),OPN(brset,1),OPN(brclr,1),OPN(brset,2),OPN(brclr,2),OPN(brset,3),OPN(brclr,3), + OPN(brset,4),OPN(brclr,4),OPN(brset,5),OPN(brclr,5),OPN(brset,6),OPN(brclr,6),OPN(brset,7),OPN(brclr,7), + /* 1 */ OPN(bset,0), OPN(bclr,0), OPN(bset,1), OPN(bclr,1), OPN(bset,2), OPN(bclr,2), OPN(bset,3), OPN(bclr,3), + OPN(bset,4), OPN(bclr,4), OPN(bset,5), OPN(bclr,5), OPN(bset,6), OPN(bclr,6), OPN(bset,7), OPN(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_T(bil), OP_F(bil), /* 3 */ OP_DI(neg), OP(illegal), OP(illegal), OP_DI(com), OP_DI(lsr), OP(illegal), OP_DI(ror), OP_DI(asr), @@ -125,13 +203,13 @@ const m6805_base_device::op_handler_table m6805_base_device::s_cmos_ops = OP_IX(eora), OP_IX(adca), OP_IX(ora), OP_IX(adda), OP_IX(jmp), OP_IX(jsr), OP_IX(ldx), OP_IX(stx) }; -const m6805_base_device::op_handler_table m6805_base_device::s_hc_ops = +const m6805_base_device::op_handler_table m6805_base_device::s_hc_b_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>), + /* 0 */ OPN(brset,0),OPN(brclr,0),OPN(brset,1),OPN(brclr,1),OPN(brset,2),OPN(brclr,2),OPN(brset,3),OPN(brclr,3), + OPN(brset,4),OPN(brclr,4),OPN(brset,5),OPN(brclr,5),OPN(brset,6),OPN(brclr,6),OPN(brset,7),OPN(brclr,7), + /* 1 */ OPN(bset,0), OPN(bclr,0), OPN(bset,1), OPN(bclr,1), OPN(bset,2), OPN(bclr,2), OPN(bset,3), OPN(bclr,3), + OPN(bset,4), OPN(bclr,4), OPN(bset,5), OPN(bclr,5), OPN(bset,6), OPN(bclr,6), OPN(bset,7), OPN(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_T(bil), OP_F(bil), /* 3 */ OP_DI(neg), OP(illegal), OP(illegal), OP_DI(com), OP_DI(lsr), OP(illegal), OP_DI(ror), OP_DI(asr), @@ -162,6 +240,10 @@ const m6805_base_device::op_handler_table m6805_base_device::s_hc_ops = OP_IX(eora), OP_IX(adca), OP_IX(ora), OP_IX(adda), OP_IX(jmp), OP_IX(jsr), OP_IX(ldx), OP_IX(stx) }; +#undef big + +// to prevent the possibility of MAME locking up, don't use 0 cycles here +#define XX 4 // illegal opcode unknown cycle count const m6805_base_device::cycle_count_table m6805_base_device::s_hmos_cycles = { @@ -169,14 +251,14 @@ const m6805_base_device::cycle_count_table m6805_base_device::s_hmos_cycles = /*0*/ 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, /*1*/ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, /*2*/ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - /*3*/ 6, 0, 0, 6, 6, 0, 6, 6, 6, 6, 6, 0, 6, 6, 0, 6, - /*4*/ 4, 0, 0, 4, 4, 0, 4, 4, 4, 4, 4, 0, 4, 4, 0, 4, - /*5*/ 4, 0, 0, 4, 4, 0, 4, 4, 4, 4, 4, 0, 4, 4, 0, 4, - /*6*/ 7, 0, 0, 7, 7, 0, 7, 7, 7, 7, 7, 0, 7, 7, 0, 7, - /*7*/ 6, 0, 0, 6, 6, 0, 6, 6, 6, 6, 6, 0, 6, 6, 0, 6, - /*8*/ 9, 6, 0,11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /*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, 8, 2, 0, + /*3*/ 6,XX,XX, 6, 6,XX, 6, 6, 6, 6, 6,XX, 6, 6,XX, 6, + /*4*/ 4,XX,XX, 4, 4,XX, 4, 4, 4, 4, 4,XX, 4, 4,XX, 4, + /*5*/ 4,XX,XX, 4, 4,XX, 4, 4, 4, 4, 4,XX, 4, 4,XX, 4, + /*6*/ 7,XX,XX, 7, 7,XX, 7, 7, 7, 7, 7,XX, 7, 7,XX, 7, + /*7*/ 6,XX,XX, 6, 6,XX, 6, 6, 6, 6, 6,XX, 6, 6,XX, 6, + /*8*/ 9, 6,XX,11,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX, + /*9*/ XX,XX,XX,XX,XX,XX,XX, 2, 2, 2, 2, 2, 2, 2,XX, 2, + /*A*/ 2, 2, 2, 2, 2, 2, 2,XX, 2, 2, 2, 2,XX, 8, 2,XX, /*B*/ 4, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, 4, 3, 7, 4, 5, /*C*/ 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 4, 8, 5, 6, /*D*/ 6, 6, 6, 6, 6, 6, 6, 7, 6, 6, 6, 6, 5, 9, 6, 7, @@ -190,14 +272,14 @@ const m6805_base_device::cycle_count_table m6805_base_device::s_cmos_cycles = /*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, + /*3*/ 5,XX,XX, 5, 5,XX, 5, 5, 5, 5, 5,XX, 5, 4,XX, 5, + /*4*/ 3,XX,XX, 3, 3,XX, 3, 3, 3, 3, 3,XX, 3, 3,XX, 3, + /*5*/ 3,XX,XX, 3, 3,XX, 3, 3, 3, 3, 3,XX, 3, 3,XX, 3, + /*6*/ 6,XX,XX, 6, 6,XX, 6, 6, 6, 6, 6,XX, 6, 5,XX, 6, + /*7*/ 5,XX,XX, 5, 5,XX, 5, 5, 5, 5, 5,XX, 5, 4,XX, 5, + /*8*/ 9, 6,XX,10,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX, 2, 2, + /*9*/ XX,XX,XX,XX,XX,XX,XX, 2, 2, 2, 2, 2, 2, 2,XX, 2, + /*A*/ 2, 2, 2, 2, 2, 2, 2,XX, 2, 2, 2, 2,XX, 6, 2,XX, /*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, @@ -211,14 +293,14 @@ const m6805_base_device::cycle_count_table m6805_base_device::s_hc_cycles = /*0*/ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, /*1*/ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, /*2*/ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - /*3*/ 5, 0, 0, 5, 5, 0, 5, 5, 5, 5, 5, 0, 5, 4, 0, 5, - /*4*/ 3, 0,11, 3, 3, 0, 3, 3, 3, 3, 3, 0, 3, 3, 0, 3, - /*5*/ 3, 0, 0, 3, 3, 0, 3, 3, 3, 3, 3, 0, 3, 3, 0, 3, - /*6*/ 6, 0, 0, 6, 6, 0, 6, 6, 6, 6, 6, 0, 6, 5, 0, 6, - /*7*/ 5, 0, 0, 5, 5, 0, 5, 5, 5, 5, 5, 0, 5, 4, 0, 5, - /*8*/ 9, 6, 0,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, - /*9*/ 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 2, - /*A*/ 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 0, 6, 2, 0, + /*3*/ 5,XX,XX, 5, 5,XX, 5, 5, 5, 5, 5,XX, 5, 4,XX, 5, + /*4*/ 3,XX,11, 3, 3,XX, 3, 3, 3, 3, 3,XX, 3, 3,XX, 3, + /*5*/ 3,XX,XX, 3, 3,XX, 3, 3, 3, 3, 3,XX, 3, 3,XX, 3, + /*6*/ 6,XX,XX, 6, 6,XX, 6, 6, 6, 6, 6,XX, 6, 5,XX, 6, + /*7*/ 5,XX,XX, 5, 5,XX, 5, 5, 5, 5, 5,XX, 5, 4,XX, 5, + /*8*/ 9, 6,XX,10,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX, 2, 2, + /*9*/ XX,XX,XX,XX,XX,XX,XX, 2, 2, 2, 2, 2, 2, 2,XX, 2, + /*A*/ 2, 2, 2, 2, 2, 2, 2,XX, 2, 2, 2, 2,XX, 6, 2,XX, /*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, @@ -226,6 +308,50 @@ const m6805_base_device::cycle_count_table m6805_base_device::s_hc_cycles = /*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_hd6305_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,XX,XX, 5, 5,XX, 5, 5, 5, 5, 5,XX, 5, 4,XX, 5, + /*4*/ 2,XX,XX, 2, 2,XX, 2, 2, 2, 2, 2,XX, 2, 2,XX, 2, + /*5*/ 2,XX,XX, 2, 2,XX, 2, 2, 2, 2, 2,XX, 2, 2,XX, 2, + /*6*/ 6,XX,XX, 6, 6,XX, 6, 6, 6, 6, 6,XX, 6, 5,XX, 6, + /*7*/ 5,XX,XX, 5, 5,XX, 5, 5, 5, 5, 5,XX, 5, 4,XX, 5, + /*8*/ 8, 5,XX,10,XX,XX,XX,XX,XX,XX,XX,XX,XX, 2, 4, 4, + /*9*/ XX,XX,XX,XX,XX,XX,XX, 2, 1, 1, 2, 2, 2, 1,XX, 2, + /*A*/ 2, 2, 2, 2, 2, 2, 2,XX, 2, 2, 2, 2,XX, 5, 2,XX, + /*B*/ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 5, 3, 3, + /*C*/ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 6, 4, 4, + /*D*/ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 6, 5, 5, + /*E*/ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 5, 4, 4, + /*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_hd63705_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,XX,XX, 5, 5,XX, 5, 5, 5, 5, 5,XX, 5, 4,XX, 5, + /*4*/ 2,XX,11, 2, 2,XX, 2, 2, 2, 2, 2,XX, 2, 2,XX, 2, + /*5*/ 2,XX,XX, 2, 2,XX, 2, 2, 2, 2, 2,XX, 2, 2,XX, 2, + /*6*/ 6,XX,XX, 6, 6,XX, 6, 6, 6, 6, 6,XX, 6, 5,XX, 6, + /*7*/ 5,XX,XX, 5, 5,XX, 5, 5, 5, 5, 5,XX, 5, 4,XX, 5, + /*8*/ 9, 6,XX,11,XX,XX,XX,XX,XX,XX,XX,XX,XX, 2, 4, 4, + /*9*/ XX,XX,XX,XX,XX,XX,XX, 2, 1, 1, 2, 2, 2, 1,XX, 2, + /*A*/ 2, 2, 2, 2, 2, 2, 2,XX, 2, 2, 2, 2,XX, 6, 2,XX, + /*B*/ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 6, 3, 3, + /*C*/ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 7, 4, 4, + /*D*/ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 7, 5, 5, + /*E*/ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 6, 4, 4, + /*F*/ 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 2, 6, 3, 4 +}; + +#undef XX // /illegal opcode unknown cc + //------------------------------------------------- // m6809_base_device - constructor @@ -262,8 +388,16 @@ m6805_base_device::m6805_base_device( void m6805_base_device::device_start() { - m_program = &space(AS_PROGRAM); - m_cache = m_program->cache<0, 0, ENDIANNESS_BIG>(); + if (m_params.m_addr_width > 14) { + space(AS_PROGRAM).cache(m_cprogram16); + space(AS_PROGRAM).specific(m_program16); + } else { + space(AS_PROGRAM).cache(m_cprogram13); + space(AS_PROGRAM).specific(m_program13); + } + + m_min_cycles = *std::min_element(std::begin(m_params.m_cycles), std::end(m_params.m_cycles)); + m_max_cycles = *std::max_element(std::begin(m_params.m_cycles), std::end(m_params.m_cycles)); // set our instruction counter set_icountptr(m_icount); @@ -304,10 +438,13 @@ void m6805_base_device::device_reset() m_nmi_state = 0; - /* IRQ disabled */ + // IRQ disabled SEI; - rm16(0xfffe & m_params.m_vector_mask, m_pc); + if (m_params.m_addr_width > 14) + rm16<true>(0xfffe & m_params.m_vector_mask, m_pc); + else + rm16<false>(0xfffe & m_params.m_vector_mask, m_pc); } @@ -356,53 +493,46 @@ bool m6805_base_device::test_il() void m6805_base_device::interrupt_vector() { - rm16(0xfffa & m_params.m_vector_mask, m_pc); + m_pending_interrupts &= ~(1 << M6805_IRQ_LINE); + if (m_params.m_addr_width > 14) + rm16<true>(0xfffa & m_params.m_vector_mask, m_pc); + else + rm16<false>(0xfffa & m_params.m_vector_mask, m_pc); } -/* Generate interrupts */ +// 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. */ + // 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 (BIT(m_pending_interrupts, HD63705_INT_NMI)) + if (m_pending_interrupts != 0 && (CC & IFLAG) == 0) { - pushword(m_pc); - pushbyte(m_x); - pushbyte(m_a); - pushbyte(m_cc); + // standard IRQ + if (m_params.m_addr_width > 14) { + pushword<true>(m_pc); + pushbyte<true>(m_x); + pushbyte<true>(m_a); + pushbyte<true>(m_cc); + } + else + { + pushword<false>(m_pc); + pushbyte<false>(m_x); + pushbyte<false>(m_a); + pushbyte<false>(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); + // no vectors supported, just do the callback to clear irq_state if needed + standard_irq_callback(0, m_pc.w.l); + + interrupt_vector(); 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); - } - } } @@ -424,7 +554,7 @@ std::unique_ptr<util::disasm_interface> m6805_base_device::create_disassembler() // clock into cycles per second //------------------------------------------------- -uint64_t m6805_base_device::execute_clocks_to_cycles(uint64_t clocks) const +uint64_t m6805_base_device::execute_clocks_to_cycles(uint64_t clocks) const noexcept { return (clocks + 3) / 4; } @@ -435,7 +565,7 @@ uint64_t m6805_base_device::execute_clocks_to_cycles(uint64_t clocks) const // count back to raw clocks //------------------------------------------------- -uint64_t m6805_base_device::execute_cycles_to_clocks(uint64_t cycles) const +uint64_t m6805_base_device::execute_cycles_to_clocks(uint64_t cycles) const noexcept { return cycles * 4; } @@ -446,14 +576,9 @@ uint64_t m6805_base_device::execute_cycles_to_clocks(uint64_t cycles) const // cycles it takes for one instruction to execute //------------------------------------------------- -uint32_t m6805_base_device::execute_min_cycles() const +uint32_t m6805_base_device::execute_min_cycles() const noexcept { - // 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; + return m_min_cycles; } @@ -462,28 +587,16 @@ uint32_t m6805_base_device::execute_min_cycles() const // 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 +uint32_t m6805_base_device::execute_max_cycles() const noexcept { - return 9; + return m_max_cycles; } -/* execute instructions on this CPU until icount expires */ +// 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 */ + S = SP_ADJUST( S ); // Taken from CPU_SET_CONTEXT when pointer'ifying do { @@ -494,7 +607,7 @@ void m6805_base_device::execute_run() debugger_instruction_hook(PC); - u8 const ireg = rdop(PC++); + u8 const ireg = m_params.m_addr_width > 14 ? rdop<true>(PC++) : rdop<false>(PC++); (this->*m_params.m_ops[ireg])(); m_icount -= m_params.m_cycles[ireg]; @@ -520,6 +633,7 @@ void m6805_base_device::execute_set_input(int inputnum, int state) /**************************************************************************** * M68HC05EG section ****************************************************************************/ + m68hc05eg_device::m68hc05eg_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : m6805_base_device( mconfig, @@ -527,7 +641,7 @@ m68hc05eg_device::m68hc05eg_device(const machine_config &mconfig, const char *ta owner, clock, M68HC05EG, - { s_hmos_ops, s_hmos_cycles, 13, 0x00ff, 0x00c0, 0xfffc }) // completely wrong, but it preserves existing behaviour + { s_hc_s_ops, s_hc_cycles, 13, 0x00ff, 0x00c0, 0xfffc }) { } @@ -535,7 +649,7 @@ void m68hc05eg_device::device_reset() { m6805_base_device::device_reset(); - rm16(0x1ffe, m_pc); + rm16<false>(0x1ffe, m_pc); } void m68hc05eg_device::interrupt_vector() @@ -543,118 +657,34 @@ void m68hc05eg_device::interrupt_vector() if (BIT(m_pending_interrupts, M68HC05EG_INT_IRQ)) { m_pending_interrupts &= ~(1 << M68HC05EG_INT_IRQ); - rm16(0x1ffa, m_pc); + rm16<false>(0x1ffa, m_pc); } else if (BIT(m_pending_interrupts, M68HC05EG_INT_TIMER)) { m_pending_interrupts &= ~(1 << M68HC05EG_INT_TIMER); - rm16(0x1ff8, m_pc); + rm16<false>(0x1ff8, m_pc); } else if (BIT(m_pending_interrupts, M68HC05EG_INT_CPI)) { m_pending_interrupts &= ~(1 << M68HC05EG_INT_CPI); - rm16(0x1ff6, m_pc); + rm16<false>(0x1ff6, m_pc); } } - -/**************************************************************************** - * HD63705 section - ****************************************************************************/ -hd63705_device::hd63705_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : m6805_base_device(mconfig, - tag, - owner, - clock, - HD63705, - { s_hmos_ops, s_hmos_cycles, 16, 0x017f, 0x0100, 0x1ffa }) -{ -} - -void hd63705_device::device_reset() +u64 m68hc05eg_device::execute_clocks_to_cycles(u64 clocks) const noexcept { - m6805_base_device::device_reset(); - - m_s.w.l = SP_MASK; - - rm16(0x1ffe, m_pc); + return (clocks + 1) / 2; } -void hd63705_device::execute_set_input(int inputnum, int state) +u64 m68hc05eg_device::execute_cycles_to_clocks(u64 cycles) const noexcept { - 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; - } - } - } + return cycles * 2; } -void hd63705_device::interrupt_vector() +std::unique_ptr<util::disasm_interface> m68hc05eg_device::create_disassembler() { - /* Need to add emulation of other interrupt sources here KW-2/4/99 */ - /* This is just a quick patch for Namco System 2 operation */ - - if ((m_pending_interrupts & (1 << HD63705_INT_IRQ1)) != 0) - { - m_pending_interrupts &= ~(1 << HD63705_INT_IRQ1); - rm16(0x1ff8, m_pc); - } - else if ((m_pending_interrupts & (1 << HD63705_INT_IRQ2)) != 0) - { - m_pending_interrupts &= ~(1 << HD63705_INT_IRQ2); - rm16(0x1fec, m_pc); - } - else if ((m_pending_interrupts & (1 << HD63705_INT_ADCONV)) != 0) - { - m_pending_interrupts &= ~(1 << HD63705_INT_ADCONV); - rm16(0x1fea, m_pc); - } - else if ((m_pending_interrupts & (1 << HD63705_INT_TIMER1)) != 0) - { - m_pending_interrupts &= ~(1 << HD63705_INT_TIMER1); - rm16(0x1ff6, m_pc); - } - else if ((m_pending_interrupts & (1 << HD63705_INT_TIMER2)) != 0) - { - m_pending_interrupts &= ~(1 << HD63705_INT_TIMER2); - rm16(0x1ff4, m_pc); - } - else if ((m_pending_interrupts & (1 << HD63705_INT_TIMER3)) != 0) - { - m_pending_interrupts &= ~(1<<HD63705_INT_TIMER3); - rm16(0x1ff2, m_pc); - } - else if ((m_pending_interrupts & (1 << HD63705_INT_PCI)) != 0) - { - m_pending_interrupts &= ~(1 << HD63705_INT_PCI); - rm16(0x1ff0, m_pc); - } - else if ((m_pending_interrupts & (1 << HD63705_INT_SCI)) != 0) - { - m_pending_interrupts &= ~(1 << HD63705_INT_SCI); - rm16(0x1fee, m_pc); - } + return std::make_unique<m68hc05_disassembler>(); } DEFINE_DEVICE_TYPE(M68HC05EG, m68hc05eg_device, "m68hc05eg", "Motorola MC68HC05EG") -DEFINE_DEVICE_TYPE(HD63705, hd63705_device, "hd63705", "Hitachi HD63705") |