diff options
Diffstat (limited to 'src/devices/cpu/m6800/m6800.cpp')
-rw-r--r-- | src/devices/cpu/m6800/m6800.cpp | 366 |
1 files changed, 210 insertions, 156 deletions
diff --git a/src/devices/cpu/m6800/m6800.cpp b/src/devices/cpu/m6800/m6800.cpp index c5e26e43564..580a9798ea4 100644 --- a/src/devices/cpu/m6800/m6800.cpp +++ b/src/devices/cpu/m6800/m6800.cpp @@ -1,55 +1,30 @@ // license:BSD-3-Clause // copyright-holders:Aaron Giles -/*** m6800: Portable 6800 class emulator ************************************* +/*** m6800: Portable 6800 class emulator ************************************* - m68xx.c +m68xx.cpp - References: +References: - 6809 Simulator V09, By L.C. Benschop, Eindhoven The Netherlands. + 6809 Simulator V09, By L.C. Benschop, Eindhoven The Netherlands. - m6809: Portable 6809 emulator, DS (6809 code in MAME, derived from - the 6809 Simulator V09) + m6809: Portable 6809 emulator, DS (6809 code in MAME, derived from + the 6809 Simulator V09) - 6809 Microcomputer Programming & Interfacing with Experiments" - by Andrew C. Staugaard, Jr.; Howard W. Sams & Co., Inc. + 6809 Microcomputer Programming & Interfacing with Experiments" + by Andrew C. Staugaard, Jr.; Howard W. Sams & Co., Inc. - System dependencies: uint16_t must be 16 bit unsigned int - uint8_t must be 8 bit unsigned int - uint32_t must be more than 16 bits - arrays up to 65536 bytes must be supported - machine must be twos complement +System dependencies: u16 must be 16 bit unsigned int + u8 must be 8 bit unsigned int + u32 must be more than 16 bits + arrays up to 65536 bytes must be supported + machine must be twos complement -History -991031 ZV - Added NSC-8105 support - -990319 HJB - Fixed wrong LSB/MSB order for push/pull word. - Subtract .extra_cycles at the beginning/end of the exectution loops. - -990316 HJB - Renamed to 6800, since that's the basic CPU. - Added different cycle count tables for M6800/2/8, M6801/3 and m68xx. - -990314 HJB - Also added the M6800 subtype. - -990311 HJB - Added _info functions. Now uses static m6808_Regs struct instead - of single statics. Changed the 16 bit registers to use the generic - PAIR union. Registers defined using macros. Split the core into - four execution loops for M6802, M6803, M6808 and HD63701. - TST, TSTA and TSTB opcodes reset carry flag. TODO: - Verify invalid opcodes for the different CPU types. - Add proper credits to _info functions. - Integrate m6808_Flags into the registers (multiple m6808 type CPUs?) - -990301 HJB - Modified the interrupt handling. No more pending interrupt checks. - WAI opcode saves state, when an interrupt is taken (IRQ or OCI), - the state is only saved if not already done by WAI. +- verify invalid opcodes for the different CPU types +- add 6802 nvram (only in case VCC STANDBY is connected to battery) +- cleanups (difficult to do maintenance work right now) +- (see m6801.cpp for 6801-specific TODO) *****************************************************************************/ @@ -89,12 +64,15 @@ TODO: */ #include "emu.h" -#include "debugger.h" #include "m6800.h" +#include "6800dasm.h" + +#define LOG_IRQ (1U << 1) -#define VERBOSE 0 +//#define VERBOSE (LOG_IRQ) +#include "logmacro.h" -#define LOG(x) do { if (VERBOSE) logerror x; } while (0) +#define LOGIRQ(...) LOGMASKED(LOG_IRQ, __VA_ARGS__) #define pPPC m_ppc @@ -121,26 +99,26 @@ TODO: /****************************************************************************/ /* Read a byte from given memory location */ /****************************************************************************/ -#define RM(Addr) ((unsigned)m_program->read_byte(Addr)) +#define RM(Addr) (m_program.read_byte(Addr)) /****************************************************************************/ /* Write a byte to given memory location */ /****************************************************************************/ -#define WM(Addr,Value) (m_program->write_byte(Addr,Value)) +#define WM(Addr,Value) (m_program.write_byte(Addr,Value)) /****************************************************************************/ /* M6800_RDOP() is identical to M6800_RDMEM() except it is used for reading */ /* opcodes. In case of system with memory mapped I/O, this function can be */ /* used to greatly speed up emulation */ /****************************************************************************/ -#define M_RDOP(Addr) ((unsigned)m_opcodes_cache->read_byte(Addr)) +#define M_RDOP(Addr) (m_copcodes.read_byte(Addr)) /****************************************************************************/ /* M6800_RDOP_ARG() is identical to M6800_RDOP() but it's used for reading */ /* opcode arguments. This difference can be used to support systems that */ /* use different encoding mechanisms for opcodes and opcode arguments */ /****************************************************************************/ -#define M_RDOP_ARG(Addr) ((unsigned)m_cache->read_byte(Addr)) +#define M_RDOP_ARG(Addr) (m_cprogram.read_byte(Addr)) /* macros to access memory */ #define IMMBYTE(b) b = M_RDOP_ARG(PCD); PC++ @@ -151,17 +129,6 @@ TODO: #define PULLBYTE(b) S++; b = RM(SD) #define PULLWORD(w) S++; w.d = RM(SD)<<8; S++; w.d |= RM(SD) -/* operate one instruction for */ -#define ONE_MORE_INSN() { \ - uint8_t ireg; \ - pPPC = pPC; \ - debugger_instruction_hook(PCD); \ - ireg=M_RDOP(PCD); \ - PC++; \ - (this->*m_insn[ireg])(); \ - increment_counter(m_cycles[ireg]); \ -} - /* CC masks HI NZVC 7654 3210 */ #define CLR_HNZVC CC&=0xd0 @@ -174,8 +141,8 @@ TODO: /* macros for CC -- CC bits affected should be reset before calling */ #define SET_Z(a) if(!(a))SEZ -#define SET_Z8(a) SET_Z((uint8_t)(a)) -#define SET_Z16(a) SET_Z((uint16_t)(a)) +#define SET_Z8(a) SET_Z(u8(a)) +#define SET_Z16(a) SET_Z(u16(a)) #define SET_N8(a) CC|=(((a)&0x80)>>4) #define SET_N16(a) CC|=(((a)&0x8000)>>12) #define SET_H(a,b,r) CC|=((((a)^(b)^(r))&0x10)<<1) @@ -184,7 +151,7 @@ TODO: #define SET_V8(a,b,r) CC|=((((a)^(b)^(r)^((r)>>1))&0x80)>>6) #define SET_V16(a,b,r) CC|=((((a)^(b)^(r)^((r)>>1))&0x8000)>>14) -const uint8_t m6800_cpu_device::flags8i[256]= /* increment */ +const u8 m6800_cpu_device::flags8i[256]= /* increment */ { 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, @@ -205,7 +172,7 @@ const uint8_t m6800_cpu_device::flags8i[256]= /* increment */ }; -const uint8_t m6800_cpu_device::flags8d[256]= /* decrement */ +const u8 m6800_cpu_device::flags8d[256]= /* decrement */ { 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, @@ -234,15 +201,15 @@ const uint8_t m6800_cpu_device::flags8d[256]= /* decrement */ #define SET_FLAGS8(a,b,r) {SET_N8(r);SET_Z8(r);SET_V8(a,b,r);SET_C8(r);} #define SET_FLAGS16(a,b,r) {SET_N16(r);SET_Z16(r);SET_V16(a,b,r);SET_C16(r);} -/* for treating an uint8_t as a signed int16_t */ -#define SIGNED(b) ((int16_t)(b&0x80?b|0xff00:b)) +/* for treating an u8 as a signed s16 */ +#define SIGNED(b) (s16(b&0x80?b|0xff00:b)) /* Macros for addressing modes */ #define DIRECT IMMBYTE(EAD) #define IMM8 EA=PC++ #define IMM16 {EA=PC;PC+=2;} #define EXTENDED IMMWORD(m_ea) -#define INDEXED {EA=X+(uint8_t)M_RDOP_ARG(PCD);PC++;} +#define INDEXED {EA=X+(u8)M_RDOP_ARG(PCD);PC++;} /* macros to set status flags */ #if defined(SEC) @@ -275,10 +242,13 @@ const uint8_t m6800_cpu_device::flags8d[256]= /* decrement */ #define NXORV ((CC&0x08)^((CC&0x02)<<2)) #define NXORC ((CC&0x08)^((CC&0x01)<<3)) -/* Note: don't use 0 cycles here for invalid opcodes so that we don't */ -/* hang in an infinite loop if we hit one */ -#define XX 5 // invalid opcode unknown cc -const uint8_t m6800_cpu_device::cycles_6800[256] = +/* include the opcode functions */ +#include "6800ops.hxx" + +// to prevent the possibility of MAME locking up, don't use 0 cycles here +#define XX 4 // illegal opcode unknown cycle count + +const u8 m6800_cpu_device::cycles_6800[256] = { /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ /*0*/ XX, 2,XX,XX,XX,XX, 2, 2, 4, 4, 2, 2, 2, 2, 2, 2, @@ -299,10 +269,10 @@ const uint8_t m6800_cpu_device::cycles_6800[256] = /*F*/ 4, 4, 4,XX, 4, 4, 4, 5, 4, 4, 4, 4,XX,XX, 5, 6 }; -const uint8_t m6800_cpu_device::cycles_nsc8105[256] = +const u8 m6800_cpu_device::cycles_nsc8105[256] = { /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ - /*0*/ 5,XX, 2,XX,XX, 2,XX, 2, 4, 2, 4, 2, 2, 2, 2, 2, + /*0*/ XX,XX, 2,XX,XX, 2,XX, 2, 4, 2, 4, 2, 2, 2, 2, 2, /*1*/ 2,XX, 2,XX,XX, 2,XX, 2,XX,XX, 2, 2,XX,XX,XX,XX, /*2*/ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, /*3*/ 4, 4, 4, 4, 4, 4, 4, 4,XX,XX, 5,10,XX, 9,XX,12, @@ -313,27 +283,101 @@ const uint8_t m6800_cpu_device::cycles_nsc8105[256] = /*8*/ 2,XX,XX, 2, 2, 2,XX, 2, 2, 2, 2,XX, 2,XX, 2, 2, /*9*/ 2,XX,XX, 2, 2, 2,XX, 2, 2, 2, 2,XX, 2,XX, 2, 2, /*A*/ 7,XX,XX, 7, 7, 7,XX, 7, 7, 7, 7,XX, 7, 4, 7, 7, - /*B*/ 6,XX,XX, 6, 6, 6,XX, 6, 6, 6, 6, 5, 6, 3, 6, 6, + /*B*/ 6,XX, 6, 6, 6, 6,XX, 6, 6, 6, 6, 6, 6, 3, 6, 6, /*C*/ 2, 2, 2,XX, 2, 2, 2, 3, 2, 2, 2, 2,XX, 3,XX, 4, /*D*/ 3, 3, 3,XX, 3, 3, 3, 4, 3, 3, 3, 3,XX, 4,XX, 5, /*E*/ 5, 5, 5,XX, 5, 5, 5, 6, 5, 5, 5, 5, 5, 6,XX, 7, /*F*/ 4, 4, 4,XX, 4, 4, 4, 5, 4, 4, 4, 4, 4, 5,XX, 6 }; -#undef XX // /invalid opcode unknown cc +#undef XX // /illegal opcode unknown cc + + +const m6800_cpu_device::op_func m6800_cpu_device::m6800_insn[0x100] = { +// 0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F +&m6800_cpu_device::illegl1,&m6800_cpu_device::nop, &m6800_cpu_device::illegl1,&m6800_cpu_device::illegl1,&m6800_cpu_device::illegl1,&m6800_cpu_device::illegl1,&m6800_cpu_device::tap, &m6800_cpu_device::tpa, // 0 +&m6800_cpu_device::inx, &m6800_cpu_device::dex, &m6800_cpu_device::clv, &m6800_cpu_device::sev, &m6800_cpu_device::clc, &m6800_cpu_device::sec, &m6800_cpu_device::cli, &m6800_cpu_device::sei, +&m6800_cpu_device::sba, &m6800_cpu_device::cba, &m6800_cpu_device::illegl1,&m6800_cpu_device::illegl1,&m6800_cpu_device::illegl1,&m6800_cpu_device::illegl1,&m6800_cpu_device::tab, &m6800_cpu_device::tba, // 1 +&m6800_cpu_device::illegl1,&m6800_cpu_device::daa, &m6800_cpu_device::illegl1,&m6800_cpu_device::aba, &m6800_cpu_device::illegl1,&m6800_cpu_device::illegl1,&m6800_cpu_device::illegl1,&m6800_cpu_device::illegl1, +&m6800_cpu_device::bra, &m6800_cpu_device::brn, &m6800_cpu_device::bhi, &m6800_cpu_device::bls, &m6800_cpu_device::bcc, &m6800_cpu_device::bcs, &m6800_cpu_device::bne, &m6800_cpu_device::beq, // 2 +&m6800_cpu_device::bvc, &m6800_cpu_device::bvs, &m6800_cpu_device::bpl, &m6800_cpu_device::bmi, &m6800_cpu_device::bge, &m6800_cpu_device::blt, &m6800_cpu_device::bgt, &m6800_cpu_device::ble, +&m6800_cpu_device::tsx, &m6800_cpu_device::ins, &m6800_cpu_device::pula, &m6800_cpu_device::pulb, &m6800_cpu_device::des, &m6800_cpu_device::txs, &m6800_cpu_device::psha, &m6800_cpu_device::pshb, // 3 +&m6800_cpu_device::illegl1,&m6800_cpu_device::rts, &m6800_cpu_device::illegl1,&m6800_cpu_device::rti, &m6800_cpu_device::illegl1,&m6800_cpu_device::illegl1,&m6800_cpu_device::wai, &m6800_cpu_device::swi, +&m6800_cpu_device::nega, &m6800_cpu_device::illegl1,&m6800_cpu_device::illegl1,&m6800_cpu_device::coma, &m6800_cpu_device::lsra, &m6800_cpu_device::illegl1,&m6800_cpu_device::rora, &m6800_cpu_device::asra, // 4 +&m6800_cpu_device::asla, &m6800_cpu_device::rola, &m6800_cpu_device::deca, &m6800_cpu_device::illegl1,&m6800_cpu_device::inca, &m6800_cpu_device::tsta, &m6800_cpu_device::illegl1,&m6800_cpu_device::clra, +&m6800_cpu_device::negb, &m6800_cpu_device::illegl1,&m6800_cpu_device::illegl1,&m6800_cpu_device::comb, &m6800_cpu_device::lsrb, &m6800_cpu_device::illegl1,&m6800_cpu_device::rorb, &m6800_cpu_device::asrb, // 5 +&m6800_cpu_device::aslb, &m6800_cpu_device::rolb, &m6800_cpu_device::decb, &m6800_cpu_device::illegl1,&m6800_cpu_device::incb, &m6800_cpu_device::tstb, &m6800_cpu_device::illegl1,&m6800_cpu_device::clrb, +&m6800_cpu_device::neg_ix, &m6800_cpu_device::illegl2,&m6800_cpu_device::illegl2,&m6800_cpu_device::com_ix, &m6800_cpu_device::lsr_ix, &m6800_cpu_device::illegl2,&m6800_cpu_device::ror_ix, &m6800_cpu_device::asr_ix, // 6 +&m6800_cpu_device::asl_ix, &m6800_cpu_device::rol_ix, &m6800_cpu_device::dec_ix, &m6800_cpu_device::illegl2,&m6800_cpu_device::inc_ix, &m6800_cpu_device::tst_ix, &m6800_cpu_device::jmp_ix, &m6800_cpu_device::clr_ix, +&m6800_cpu_device::neg_ex, &m6800_cpu_device::illegl3,&m6800_cpu_device::illegl3,&m6800_cpu_device::com_ex, &m6800_cpu_device::lsr_ex, &m6800_cpu_device::illegl3,&m6800_cpu_device::ror_ex, &m6800_cpu_device::asr_ex, // 7 +&m6800_cpu_device::asl_ex, &m6800_cpu_device::rol_ex, &m6800_cpu_device::dec_ex, &m6800_cpu_device::illegl3,&m6800_cpu_device::inc_ex, &m6800_cpu_device::tst_ex, &m6800_cpu_device::jmp_ex, &m6800_cpu_device::clr_ex, +&m6800_cpu_device::suba_im,&m6800_cpu_device::cmpa_im,&m6800_cpu_device::sbca_im,&m6800_cpu_device::illegl2,&m6800_cpu_device::anda_im,&m6800_cpu_device::bita_im,&m6800_cpu_device::lda_im, &m6800_cpu_device::sta_im, // 8 +&m6800_cpu_device::eora_im,&m6800_cpu_device::adca_im,&m6800_cpu_device::ora_im, &m6800_cpu_device::adda_im,&m6800_cpu_device::cmpx_im,&m6800_cpu_device::bsr, &m6800_cpu_device::lds_im, &m6800_cpu_device::sts_im, +&m6800_cpu_device::suba_di,&m6800_cpu_device::cmpa_di,&m6800_cpu_device::sbca_di,&m6800_cpu_device::illegl2,&m6800_cpu_device::anda_di,&m6800_cpu_device::bita_di,&m6800_cpu_device::lda_di, &m6800_cpu_device::sta_di, // 9 +&m6800_cpu_device::eora_di,&m6800_cpu_device::adca_di,&m6800_cpu_device::ora_di, &m6800_cpu_device::adda_di,&m6800_cpu_device::cmpx_di,&m6800_cpu_device::jsr_di, &m6800_cpu_device::lds_di, &m6800_cpu_device::sts_di, +&m6800_cpu_device::suba_ix,&m6800_cpu_device::cmpa_ix,&m6800_cpu_device::sbca_ix,&m6800_cpu_device::illegl2,&m6800_cpu_device::anda_ix,&m6800_cpu_device::bita_ix,&m6800_cpu_device::lda_ix, &m6800_cpu_device::sta_ix, // A +&m6800_cpu_device::eora_ix,&m6800_cpu_device::adca_ix,&m6800_cpu_device::ora_ix, &m6800_cpu_device::adda_ix,&m6800_cpu_device::cmpx_ix,&m6800_cpu_device::jsr_ix, &m6800_cpu_device::lds_ix, &m6800_cpu_device::sts_ix, +&m6800_cpu_device::suba_ex,&m6800_cpu_device::cmpa_ex,&m6800_cpu_device::sbca_ex,&m6800_cpu_device::illegl3,&m6800_cpu_device::anda_ex,&m6800_cpu_device::bita_ex,&m6800_cpu_device::lda_ex, &m6800_cpu_device::sta_ex, // B +&m6800_cpu_device::eora_ex,&m6800_cpu_device::adca_ex,&m6800_cpu_device::ora_ex, &m6800_cpu_device::adda_ex,&m6800_cpu_device::cmpx_ex,&m6800_cpu_device::jsr_ex, &m6800_cpu_device::lds_ex, &m6800_cpu_device::sts_ex, +&m6800_cpu_device::subb_im,&m6800_cpu_device::cmpb_im,&m6800_cpu_device::sbcb_im,&m6800_cpu_device::illegl2,&m6800_cpu_device::andb_im,&m6800_cpu_device::bitb_im,&m6800_cpu_device::ldb_im, &m6800_cpu_device::stb_im, // C +&m6800_cpu_device::eorb_im,&m6800_cpu_device::adcb_im,&m6800_cpu_device::orb_im, &m6800_cpu_device::addb_im,&m6800_cpu_device::illegl3,&m6800_cpu_device::illegl3,&m6800_cpu_device::ldx_im, &m6800_cpu_device::stx_im, +&m6800_cpu_device::subb_di,&m6800_cpu_device::cmpb_di,&m6800_cpu_device::sbcb_di,&m6800_cpu_device::illegl2,&m6800_cpu_device::andb_di,&m6800_cpu_device::bitb_di,&m6800_cpu_device::ldb_di, &m6800_cpu_device::stb_di, // D +&m6800_cpu_device::eorb_di,&m6800_cpu_device::adcb_di,&m6800_cpu_device::orb_di, &m6800_cpu_device::addb_di,&m6800_cpu_device::illegl2,&m6800_cpu_device::illegl2,&m6800_cpu_device::ldx_di, &m6800_cpu_device::stx_di, +&m6800_cpu_device::subb_ix,&m6800_cpu_device::cmpb_ix,&m6800_cpu_device::sbcb_ix,&m6800_cpu_device::illegl2,&m6800_cpu_device::andb_ix,&m6800_cpu_device::bitb_ix,&m6800_cpu_device::ldb_ix, &m6800_cpu_device::stb_ix, // E +&m6800_cpu_device::eorb_ix,&m6800_cpu_device::adcb_ix,&m6800_cpu_device::orb_ix, &m6800_cpu_device::addb_ix,&m6800_cpu_device::illegl2,&m6800_cpu_device::illegl2,&m6800_cpu_device::ldx_ix, &m6800_cpu_device::stx_ix, +&m6800_cpu_device::subb_ex,&m6800_cpu_device::cmpb_ex,&m6800_cpu_device::sbcb_ex,&m6800_cpu_device::illegl3,&m6800_cpu_device::andb_ex,&m6800_cpu_device::bitb_ex,&m6800_cpu_device::ldb_ex, &m6800_cpu_device::stb_ex, // F +&m6800_cpu_device::eorb_ex,&m6800_cpu_device::adcb_ex,&m6800_cpu_device::orb_ex, &m6800_cpu_device::addb_ex,&m6800_cpu_device::illegl3,&m6800_cpu_device::illegl3,&m6800_cpu_device::ldx_ex, &m6800_cpu_device::stx_ex +}; + +const m6800_cpu_device::op_func m6800_cpu_device::nsc8105_insn[0x100] = { +// 0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F +&m6800_cpu_device::illegl1,&m6800_cpu_device::illegl1,&m6800_cpu_device::nop, &m6800_cpu_device::illegl1,&m6800_cpu_device::illegl1,&m6800_cpu_device::tap, &m6800_cpu_device::illegl1,&m6800_cpu_device::tpa, // 0 +&m6800_cpu_device::inx, &m6800_cpu_device::clv, &m6800_cpu_device::dex, &m6800_cpu_device::sev, &m6800_cpu_device::clc, &m6800_cpu_device::cli, &m6800_cpu_device::sec, &m6800_cpu_device::sei, +&m6800_cpu_device::sba, &m6800_cpu_device::illegl1,&m6800_cpu_device::cba, &m6800_cpu_device::illegl1,&m6800_cpu_device::illegl1,&m6800_cpu_device::tab, &m6800_cpu_device::illegl1,&m6800_cpu_device::tba, // 1 +&m6800_cpu_device::illegl1,&m6800_cpu_device::illegl1,&m6800_cpu_device::daa, &m6800_cpu_device::aba, &m6800_cpu_device::illegl1,&m6800_cpu_device::illegl1,&m6800_cpu_device::illegl1,&m6800_cpu_device::illegl1, +&m6800_cpu_device::bra, &m6800_cpu_device::bhi, &m6800_cpu_device::brn, &m6800_cpu_device::bls, &m6800_cpu_device::bcc, &m6800_cpu_device::bne, &m6800_cpu_device::bcs, &m6800_cpu_device::beq, // 2 +&m6800_cpu_device::bvc, &m6800_cpu_device::bpl, &m6800_cpu_device::bvs, &m6800_cpu_device::bmi, &m6800_cpu_device::bge, &m6800_cpu_device::bgt, &m6800_cpu_device::blt, &m6800_cpu_device::ble, +&m6800_cpu_device::tsx, &m6800_cpu_device::pula, &m6800_cpu_device::ins, &m6800_cpu_device::pulb, &m6800_cpu_device::des, &m6800_cpu_device::psha, &m6800_cpu_device::txs, &m6800_cpu_device::pshb, // 3 +&m6800_cpu_device::illegl1,&m6800_cpu_device::illegl1,&m6800_cpu_device::rts, &m6800_cpu_device::rti, &m6800_cpu_device::illegl1,&m6800_cpu_device::wai, &m6800_cpu_device::illegl1,&m6800_cpu_device::swi, +&m6800_cpu_device::suba_im,&m6800_cpu_device::sbca_im,&m6800_cpu_device::cmpa_im,&m6800_cpu_device::illegl1,&m6800_cpu_device::anda_im,&m6800_cpu_device::lda_im, &m6800_cpu_device::bita_im,&m6800_cpu_device::sta_im, // 4 +&m6800_cpu_device::eora_im,&m6800_cpu_device::ora_im, &m6800_cpu_device::adca_im,&m6800_cpu_device::adda_im,&m6800_cpu_device::cmpx_im,&m6800_cpu_device::lds_im, &m6800_cpu_device::bsr, &m6800_cpu_device::sts_im, +&m6800_cpu_device::suba_di,&m6800_cpu_device::sbca_di,&m6800_cpu_device::cmpa_di,&m6800_cpu_device::illegl1,&m6800_cpu_device::anda_di,&m6800_cpu_device::lda_di, &m6800_cpu_device::bita_di,&m6800_cpu_device::sta_di, // 5 +&m6800_cpu_device::eora_di,&m6800_cpu_device::ora_di, &m6800_cpu_device::adca_di,&m6800_cpu_device::adda_di,&m6800_cpu_device::cmpx_di,&m6800_cpu_device::lds_di, &m6800_cpu_device::jsr_di, &m6800_cpu_device::sts_di, +&m6800_cpu_device::suba_ix,&m6800_cpu_device::sbca_ix,&m6800_cpu_device::cmpa_ix,&m6800_cpu_device::illegl1,&m6800_cpu_device::anda_ix,&m6800_cpu_device::lda_ix, &m6800_cpu_device::bita_ix,&m6800_cpu_device::sta_ix, // 6 +&m6800_cpu_device::eora_ix,&m6800_cpu_device::ora_ix, &m6800_cpu_device::adca_ix,&m6800_cpu_device::adda_ix,&m6800_cpu_device::cmpx_ix,&m6800_cpu_device::lds_ix, &m6800_cpu_device::jsr_ix, &m6800_cpu_device::sts_ix, +&m6800_cpu_device::suba_ex,&m6800_cpu_device::sbca_ex,&m6800_cpu_device::cmpa_ex,&m6800_cpu_device::illegl1,&m6800_cpu_device::anda_ex,&m6800_cpu_device::lda_ex, &m6800_cpu_device::bita_ex,&m6800_cpu_device::sta_ex, // 7 +&m6800_cpu_device::eora_ex,&m6800_cpu_device::ora_ex, &m6800_cpu_device::adca_ex,&m6800_cpu_device::adda_ex,&m6800_cpu_device::cmpx_ex,&m6800_cpu_device::lds_ex, &m6800_cpu_device::jsr_ex, &m6800_cpu_device::sts_ex, +&m6800_cpu_device::nega, &m6800_cpu_device::illegl1,&m6800_cpu_device::illegl1,&m6800_cpu_device::coma, &m6800_cpu_device::lsra, &m6800_cpu_device::rora, &m6800_cpu_device::illegl1,&m6800_cpu_device::asra, // 8 +&m6800_cpu_device::asla, &m6800_cpu_device::deca, &m6800_cpu_device::rola, &m6800_cpu_device::illegl1,&m6800_cpu_device::inca, &m6800_cpu_device::illegl1,&m6800_cpu_device::tsta, &m6800_cpu_device::clra, +&m6800_cpu_device::negb, &m6800_cpu_device::illegl1,&m6800_cpu_device::illegl1,&m6800_cpu_device::comb, &m6800_cpu_device::lsrb, &m6800_cpu_device::rorb, &m6800_cpu_device::illegl1,&m6800_cpu_device::asrb, // 9 +&m6800_cpu_device::aslb, &m6800_cpu_device::decb, &m6800_cpu_device::rolb, &m6800_cpu_device::illegl1,&m6800_cpu_device::incb, &m6800_cpu_device::illegl1,&m6800_cpu_device::tstb, &m6800_cpu_device::clrb, +&m6800_cpu_device::neg_ix, &m6800_cpu_device::illegl1,&m6800_cpu_device::illegl1,&m6800_cpu_device::com_ix, &m6800_cpu_device::lsr_ix, &m6800_cpu_device::ror_ix, &m6800_cpu_device::illegl1,&m6800_cpu_device::asr_ix, // A +&m6800_cpu_device::asl_ix, &m6800_cpu_device::dec_ix, &m6800_cpu_device::rol_ix, &m6800_cpu_device::illegl1,&m6800_cpu_device::inc_ix, &m6800_cpu_device::jmp_ix, &m6800_cpu_device::tst_ix, &m6800_cpu_device::clr_ix, +&m6800_cpu_device::neg_ex, &m6800_cpu_device::illegl1,&m6800_cpu_device::stx_nsc,&m6800_cpu_device::com_ex, &m6800_cpu_device::lsr_ex, &m6800_cpu_device::ror_ex, &m6800_cpu_device::illegl1,&m6800_cpu_device::asr_ex, // B +&m6800_cpu_device::asl_ex, &m6800_cpu_device::dec_ex, &m6800_cpu_device::rol_ex, &m6800_cpu_device::btst_ix,&m6800_cpu_device::inc_ex, &m6800_cpu_device::jmp_ex, &m6800_cpu_device::tst_ex, &m6800_cpu_device::clr_ex, +&m6800_cpu_device::subb_im,&m6800_cpu_device::sbcb_im,&m6800_cpu_device::cmpb_im,&m6800_cpu_device::illegl1,&m6800_cpu_device::andb_im,&m6800_cpu_device::ldb_im, &m6800_cpu_device::bitb_im,&m6800_cpu_device::stb_im, // C +&m6800_cpu_device::eorb_im,&m6800_cpu_device::orb_im, &m6800_cpu_device::adcb_im,&m6800_cpu_device::addb_im,&m6800_cpu_device::illegl1,&m6800_cpu_device::ldx_im, &m6800_cpu_device::illegl1,&m6800_cpu_device::stx_im, +&m6800_cpu_device::subb_di,&m6800_cpu_device::sbcb_di,&m6800_cpu_device::cmpb_di,&m6800_cpu_device::illegl1,&m6800_cpu_device::andb_di,&m6800_cpu_device::ldb_di, &m6800_cpu_device::bitb_di,&m6800_cpu_device::stb_di, // D +&m6800_cpu_device::eorb_di,&m6800_cpu_device::orb_di, &m6800_cpu_device::adcb_di,&m6800_cpu_device::addb_di,&m6800_cpu_device::illegl1,&m6800_cpu_device::ldx_di, &m6800_cpu_device::illegl1,&m6800_cpu_device::stx_di, +&m6800_cpu_device::subb_ix,&m6800_cpu_device::sbcb_ix,&m6800_cpu_device::cmpb_ix,&m6800_cpu_device::illegl1,&m6800_cpu_device::andb_ix,&m6800_cpu_device::ldb_ix, &m6800_cpu_device::bitb_ix,&m6800_cpu_device::stb_ix, // E +&m6800_cpu_device::eorb_ix,&m6800_cpu_device::orb_ix, &m6800_cpu_device::adcb_ix,&m6800_cpu_device::addb_ix,&m6800_cpu_device::adcx_im,&m6800_cpu_device::ldx_ix, &m6800_cpu_device::illegl1,&m6800_cpu_device::stx_ix, +&m6800_cpu_device::subb_ex,&m6800_cpu_device::sbcb_ex,&m6800_cpu_device::cmpb_ex,&m6800_cpu_device::illegl1,&m6800_cpu_device::andb_ex,&m6800_cpu_device::ldb_ex, &m6800_cpu_device::bitb_ex,&m6800_cpu_device::stb_ex, // F +&m6800_cpu_device::eorb_ex,&m6800_cpu_device::orb_ex, &m6800_cpu_device::adcb_ex,&m6800_cpu_device::addb_ex,&m6800_cpu_device::addx_ex,&m6800_cpu_device::ldx_ex, &m6800_cpu_device::illegl1,&m6800_cpu_device::stx_ex +}; -DEFINE_DEVICE_TYPE(M6800, m6800_cpu_device, "m6800", "Motorola M6800") -DEFINE_DEVICE_TYPE(M6802, m6802_cpu_device, "m6802", "Motorola M6802") -DEFINE_DEVICE_TYPE(M6808, m6808_cpu_device, "m6808", "Motorola M6808") + +DEFINE_DEVICE_TYPE(M6800, m6800_cpu_device, "m6800", "Motorola MC6800") +DEFINE_DEVICE_TYPE(M6802, m6802_cpu_device, "m6802", "Motorola MC6802") +DEFINE_DEVICE_TYPE(M6808, m6808_cpu_device, "m6808", "Motorola MC6808") DEFINE_DEVICE_TYPE(NSC8105, nsc8105_cpu_device, "nsc8105", "NSC8105") -m6800_cpu_device::m6800_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +m6800_cpu_device::m6800_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : m6800_cpu_device(mconfig, M6800, tag, owner, clock, m6800_insn, cycles_6800, address_map_constructor()) { } -m6800_cpu_device::m6800_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, const op_func *insn, const uint8_t *cycles, address_map_constructor internal) +m6800_cpu_device::m6800_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, const op_func *insn, const u8 *cycles, address_map_constructor internal) : cpu_device(mconfig, type, tag, owner, clock) , m_program_config("program", ENDIANNESS_BIG, 8, 16, 0, internal) , m_decrypted_opcodes_config("program", ENDIANNESS_BIG, 8, 16, 0) @@ -342,29 +386,43 @@ m6800_cpu_device::m6800_cpu_device(const machine_config &mconfig, device_type ty { } -m6802_cpu_device::m6802_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +m6802_cpu_device::m6802_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : m6802_cpu_device(mconfig, M6802, tag, owner, clock, m6800_insn, cycles_6800) { } -m6802_cpu_device::m6802_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, const op_func *insn, const uint8_t *cycles) - : m6800_cpu_device(mconfig, type, tag, owner, clock, insn, cycles, address_map_constructor()) +m6802_cpu_device::m6802_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, const op_func *insn, const u8 *cycles) + : m6800_cpu_device(mconfig, type, tag, owner, clock, insn, cycles, address_map_constructor(FUNC(m6802_cpu_device::ram_map), this)) + , m_ram_enable(true) +{ +} + +void m6802_cpu_device::ram_map(address_map &map) { + if (m_ram_enable) + map(0x0000, 0x007f).ram(); } -m6808_cpu_device::m6808_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +m6808_cpu_device::m6808_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : m6802_cpu_device(mconfig, M6808, tag, owner, clock, m6800_insn, cycles_6800) { + set_ram_enable(false); +} + +void m6808_cpu_device::device_validity_check(validity_checker &valid) const +{ + if (m_ram_enable) + osd_printf_error("MC6808 should not have internal RAM enabled\n"); } -nsc8105_cpu_device::nsc8105_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +nsc8105_cpu_device::nsc8105_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : m6802_cpu_device(mconfig, NSC8105, tag, owner, clock, nsc8105_insn, cycles_nsc8105) { } device_memory_interface::space_config_vector m6800_cpu_device::memory_space_config() const { - if(has_configured_map(AS_OPCODES)) + if (has_configured_map(AS_OPCODES)) return space_config_vector { std::make_pair(AS_PROGRAM, &m_program_config), std::make_pair(AS_OPCODES, &m_decrypted_opcodes_config) @@ -375,27 +433,29 @@ device_memory_interface::space_config_vector m6800_cpu_device::memory_space_conf }; } -uint32_t m6800_cpu_device::RM16(uint32_t Addr ) +u32 m6800_cpu_device::RM16(u32 Addr) { - uint32_t result = RM(Addr) << 8; - return result | RM((Addr+1)&0xffff); + u32 result = RM(Addr) << 8; + return result | RM((Addr+1) & 0xffff); } -void m6800_cpu_device::WM16(uint32_t Addr, PAIR *p ) +void m6800_cpu_device::WM16(u32 Addr, PAIR *p) { - WM( Addr, p->b.h ); - WM( (Addr+1)&0xffff, p->b.l ); + WM(Addr, p->b.h); + WM((Addr+1) & 0xffff, p->b.l); } /* IRQ enter */ -void m6800_cpu_device::enter_interrupt(const char *message,uint16_t irq_vector) +void m6800_cpu_device::enter_interrupt(const char *message, u16 irq_vector) { - LOG((message)); - if( m_wai_state & (M6800_WAI|M6800_SLP) ) + int cycles_to_eat = 0; + + LOGIRQ("Take %s interrupt\n", message); + + if (m_wai_state & M6800_WAI) { - if( m_wai_state & M6800_WAI ) - m_icount -= 4; - m_wai_state &= ~(M6800_WAI|M6800_SLP); + cycles_to_eat = 4; + m_wai_state &= ~M6800_WAI; } else { @@ -404,44 +464,41 @@ void m6800_cpu_device::enter_interrupt(const char *message,uint16_t irq_vector) PUSHBYTE(A); PUSHBYTE(B); PUSHBYTE(CC); - m_icount -= 12; + cycles_to_eat = 12; } SEI; - PCD = RM16( irq_vector ); -} - + PCD = RM16(irq_vector); + increment_counter(cycles_to_eat); +} /* check the IRQ lines for pending interrupts */ -void m6800_cpu_device::CHECK_IRQ_LINES() +void m6800_cpu_device::check_irq_lines() { - // TODO: IS3 interrupt - if (m_nmi_pending) { - if(m_wai_state & M6800_SLP) - m_wai_state &= ~M6800_SLP; - + m_wai_state &= ~M6800_SLP; m_nmi_pending = false; - enter_interrupt("take NMI\n", 0xfffc); + enter_interrupt("NMI", 0xfffc); } - else + else if (check_irq1_enabled()) { - if( m_irq_state[M6800_IRQ_LINE] != CLEAR_LINE ) - { /* standard IRQ */ - if(m_wai_state & M6800_SLP) - m_wai_state &= ~M6800_SLP; - - if( !(CC & 0x10) ) - { - enter_interrupt("take IRQ1\n", 0xfff8); - standard_irq_callback(M6800_IRQ_LINE); - } + /* standard IRQ */ + m_wai_state &= ~M6800_SLP; + + if (!(CC & 0x10)) + { + standard_irq_callback(M6800_IRQ_LINE, m_pc.w.l); + enter_interrupt("IRQ1", 0xfff8); } - else - if( !(CC & 0x10) ) - m6800_check_irq2(); } + else + check_irq2(); +} + +bool m6800_cpu_device::check_irq1_enabled() +{ + return m_irq_state[M6800_IRQ_LINE] != CLEAR_LINE; } void m6800_cpu_device::increment_counter(int amount) @@ -449,32 +506,29 @@ void m6800_cpu_device::increment_counter(int amount) m_icount -= amount; } -void m6800_cpu_device::EAT_CYCLES() +void m6800_cpu_device::eat_cycles() { - increment_counter(m_icount); + if (m_icount > 0) + increment_counter(m_icount); } -/* include the opcode prototypes and function pointer tables */ -#include "6800tbl.hxx" - -/* include the opcode functions */ -#include "6800ops.hxx" - void m6800_cpu_device::device_start() { - m_program = &space(AS_PROGRAM); - m_cache = m_program->cache<0, 0, ENDIANNESS_BIG>(); - m_opcodes = has_space(AS_OPCODES) ? &space(AS_OPCODES) : m_program; - m_opcodes_cache = m_opcodes->cache<0, 0, ENDIANNESS_BIG>(); + space(AS_PROGRAM).cache(m_cprogram); + space(has_space(AS_OPCODES) ? AS_OPCODES : AS_PROGRAM).cache(m_copcodes); + space(AS_PROGRAM).specific(m_program); + m_ppc.d = 0; m_pc.d = 0; m_s.d = 0; m_x.d = 0; m_d.d = 0; m_cc = 0; m_wai_state = 0; - m_irq_state[0] = m_irq_state[1] = m_irq_state[2] = 0; + m_nmi_state = 0; + m_nmi_pending = 0; + std::fill(std::begin(m_irq_state), std::end(m_irq_state), 0); save_item(NAME(m_ppc.w.l)); save_item(NAME(m_pc.w.l)); @@ -523,13 +577,12 @@ void m6800_cpu_device::state_string_export(const device_state_entry &entry, std: void m6800_cpu_device::device_reset() { m_cc = 0xc0; - SEI; /* IRQ disabled */ - PCD = RM16( 0xfffe ); + SEI; /* IRQ disabled */ + PCD = RM16(0xfffe); m_wai_state = 0; m_nmi_state = 0; m_nmi_pending = 0; - m_irq_state[M6800_IRQ_LINE] = 0; } @@ -544,39 +597,40 @@ void m6800_cpu_device::execute_set_input(int irqline, int state) break; default: - LOG(("set_irq_line %d,%d\n", irqline, state)); m_irq_state[irqline] = state; break; } } -/**************************************************************************** - * Execute cycles CPU cycles. Return number of cycles really executed - ****************************************************************************/ + void m6800_cpu_device::execute_run() { - uint8_t ireg; - - CHECK_IRQ_LINES(); /* HJB 990417 */ + check_irq_lines(); - CLEANUP_COUNTERS(); + cleanup_counters(); do { - if( m_wai_state & (M6800_WAI|M6800_SLP) ) + if (m_wai_state & (M6800_WAI | M6800_SLP)) { - EAT_CYCLES(); + debugger_wait_hook(); + eat_cycles(); } else { - pPPC = pPC; - debugger_instruction_hook(PCD); - ireg=M_RDOP(PCD); - PC++; - (this->*m_insn[ireg])(); - increment_counter(m_cycles[ireg]); + execute_one(); } - } while( m_icount>0 ); + } while (m_icount > 0); +} + +void m6800_cpu_device::execute_one() +{ + pPPC = pPC; + debugger_instruction_hook(PCD); + u8 ireg = M_RDOP(PCD); + PC++; + (this->*m_insn[ireg])(); + increment_counter(m_cycles[ireg]); } std::unique_ptr<util::disasm_interface> m6800_cpu_device::create_disassembler() |