diff options
Diffstat (limited to 'src/devices/cpu/m6809/m6809.cpp')
-rw-r--r-- | src/devices/cpu/m6809/m6809.cpp | 153 |
1 files changed, 91 insertions, 62 deletions
diff --git a/src/devices/cpu/m6809/m6809.cpp b/src/devices/cpu/m6809/m6809.cpp index f9ceda47ddc..e8c93b3a46c 100644 --- a/src/devices/cpu/m6809/m6809.cpp +++ b/src/devices/cpu/m6809/m6809.cpp @@ -22,6 +22,10 @@ History: +January 2023 tlindner: + Add 6809 undocumented opcodes as described here: + https://github.com/hoglet67/6809Decoder/wiki/Undocumented-6809-Behaviours + July 2016 ErikGav: Unify with 6309 pairs and quads (A+B=D, E+F=W, D+W=Q) @@ -104,7 +108,6 @@ March 2013 NPW: *****************************************************************************/ #include "emu.h" -#include "debugger.h" #include "m6809.h" #include "m6809inl.h" #include "6x09dasm.h" @@ -114,7 +117,9 @@ March 2013 NPW: // PARAMETERS //************************************************************************** -#define LOG_INTERRUPTS 0 +#define LOG_INTERRUPTS (1U << 1) +#define VERBOSE (0) +#include "logmacro.h" // turn off 'unreferenced label' errors #if defined(__GNUC__) @@ -137,9 +142,11 @@ DEFINE_DEVICE_TYPE(M6809, m6809_device, "m6809", "MC6809 (legacy)") // m6809_base_device - constructor //------------------------------------------------- -m6809_base_device::m6809_base_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, const device_type type, int divider) - : cpu_device(mconfig, type, tag, owner, clock), +m6809_base_device::m6809_base_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, const device_type type, int divider) : + cpu_device(mconfig, type, tag, owner, clock), m_lic_func(*this), + m_vector_read_func(*this, 0), + m_syncack_write_func(*this), m_program_config("program", ENDIANNESS_BIG, 8, 16), m_sprogram_config("decrypted_opcodes", ENDIANNESS_BIG, 8, 16), m_clock_divider(divider) @@ -156,13 +163,9 @@ void m6809_base_device::device_start() if (!m_mintf) m_mintf = std::make_unique<mi_default>(); - m_mintf->m_program = &space(AS_PROGRAM); - m_mintf->m_sprogram = has_space(AS_OPCODES) ? &space(AS_OPCODES) : m_mintf->m_program; - - m_mintf->m_cache = m_mintf->m_program->cache<0, 0, ENDIANNESS_BIG>(); - m_mintf->m_scache = m_mintf->m_sprogram->cache<0, 0, ENDIANNESS_BIG>(); - - m_lic_func.resolve_safe(); + space(AS_PROGRAM).cache(m_mintf->cprogram); + space(AS_PROGRAM).specific(m_mintf->program); + space(has_space(AS_OPCODES) ? AS_OPCODES : AS_PROGRAM).cache(m_mintf->csprogram); // register our state for the debugger state_add(STATE_GENPCBASE, "CURPC", m_ppc.w).callimport().noshow(); @@ -185,15 +188,28 @@ void m6809_base_device::device_start() // initialize variables m_cc = 0; m_pc.w = 0; + m_ppc.w = 0; m_s.w = 0; m_u.w = 0; m_q.q = 0; m_x.w = 0; m_y.w = 0; m_dp = 0; - m_reg = 0; + m_temp.w = 0; + m_opcode = 0; + m_reg8 = nullptr; m_reg16 = nullptr; + m_reg = 0; + m_nmi_line = false; + m_nmi_asserted = false; + m_firq_line = false; + m_irq_line = false; + m_lds_encountered = false; + + m_state = 0; + m_cond = false; + m_free_run = false; // setup regtable save_item(NAME(m_pc.w)); @@ -207,6 +223,7 @@ void m6809_base_device::device_start() save_item(NAME(m_cc)); save_item(NAME(m_temp.w)); save_item(NAME(m_opcode)); + save_item(NAME(m_nmi_asserted)); save_item(NAME(m_nmi_line)); save_item(NAME(m_firq_line)); @@ -217,6 +234,7 @@ void m6809_base_device::device_start() save_item(NAME(m_addressing_mode)); save_item(NAME(m_reg)); save_item(NAME(m_cond)); + save_item(NAME(m_free_run)); // set our instruction counter set_icountptr(m_icount); @@ -236,14 +254,14 @@ void m6809_base_device::device_reset() m_firq_line = false; m_irq_line = false; m_lds_encountered = false; + m_free_run = false; m_dp = 0x00; // reset direct page register m_cc |= CC_I; // IRQ disabled m_cc |= CC_F; // FIRQ disabled - m_pc.b.h = space(AS_PROGRAM).read_byte(VECTOR_RESET_FFFE + 0); - m_pc.b.l = space(AS_PROGRAM).read_byte(VECTOR_RESET_FFFE + 1); + set_ea(VECTOR_RESET_FFFE); // reset sub-instruction state reset_state(); @@ -395,7 +413,7 @@ std::unique_ptr<util::disasm_interface> m6809_base_device::create_disassembler() // clock into cycles per second //------------------------------------------------- -uint64_t m6809_base_device::execute_clocks_to_cycles(uint64_t clocks) const +uint64_t m6809_base_device::execute_clocks_to_cycles(uint64_t clocks) const noexcept { return (clocks + m_clock_divider - 1) / m_clock_divider; } @@ -406,7 +424,7 @@ uint64_t m6809_base_device::execute_clocks_to_cycles(uint64_t clocks) const // count back to raw clocks //------------------------------------------------- -uint64_t m6809_base_device::execute_cycles_to_clocks(uint64_t cycles) const +uint64_t m6809_base_device::execute_cycles_to_clocks(uint64_t cycles) const noexcept { return cycles * m_clock_divider; } @@ -417,7 +435,7 @@ uint64_t m6809_base_device::execute_cycles_to_clocks(uint64_t cycles) const // cycles it takes for one instruction to execute //------------------------------------------------- -uint32_t m6809_base_device::execute_min_cycles() const +uint32_t m6809_base_device::execute_min_cycles() const noexcept { return 1; } @@ -428,32 +446,20 @@ uint32_t m6809_base_device::execute_min_cycles() const // cycles it takes for one instruction to execute //------------------------------------------------- -uint32_t m6809_base_device::execute_max_cycles() const +uint32_t m6809_base_device::execute_max_cycles() const noexcept { return 19; } //------------------------------------------------- -// execute_input_lines - return the number of -// input/interrupt lines -//------------------------------------------------- - -uint32_t m6809_base_device::execute_input_lines() const -{ - return 3; -} - - -//------------------------------------------------- // execute_set_input - act on a changed input/ // interrupt line //------------------------------------------------- void m6809_base_device::execute_set_input(int inputnum, int state) { - if (LOG_INTERRUPTS) - logerror("%s: inputnum=%s state=%d totalcycles=%d\n", machine().describe_context(), inputnum_string(inputnum), state, (int) attotime_to_clocks(machine().time())); + LOGMASKED(LOG_INTERRUPTS, "%s: inputnum=%s state=%d totalcycles=%d\n", machine().describe_context(), inputnum_string(inputnum), state, attotime_to_clocks(machine().time())); switch(inputnum) { @@ -493,28 +499,51 @@ const char *m6809_base_device::inputnum_string(int inputnum) //------------------------------------------------- -// read_exgtfr_register +// read_tfr_register //------------------------------------------------- -m6809_base_device::exgtfr_register m6809_base_device::read_exgtfr_register(uint8_t reg) +uint16_t m6809_base_device::read_tfr_exg_816_register(uint8_t reg) { - exgtfr_register result; - result.byte_value = 0xFF; - result.word_value = 0x00FF; + uint16_t result; switch(reg & 0x0F) { - case 0: result.word_value = m_q.r.d; break; // D - case 1: result.word_value = m_x.w; break; // X - case 2: result.word_value = m_y.w; break; // Y - case 3: result.word_value = m_u.w; break; // U - case 4: result.word_value = m_s.w; break; // S - case 5: result.word_value = m_pc.w; break; // PC - case 8: result.byte_value = m_q.r.a; break; // A - case 9: result.byte_value = m_q.r.b; break; // B - case 10: result.byte_value = m_cc; break; // CC - case 11: result.byte_value = m_dp; break; // DP + case 0: result = m_q.r.d; break; // D + case 1: result = m_x.w; break; // X + case 2: result = m_y.w; break; // Y + case 3: result = m_u.w; break; // U + case 4: result = m_s.w; break; // S + case 5: result = m_pc.w; break; // PC + case 8: result = ((uint16_t)0xff00) | m_q.r.a; break; // A + case 9: result = ((uint16_t)0xff00) | m_q.r.b; break; // B + case 10: result = ((uint16_t)m_cc) << 8 | m_cc; break; // CC + case 11: result = ((uint16_t)m_dp) << 8 | m_dp; break; // DP + default: result = 0xffff; break; } + + return result; +} + + +uint16_t m6809_base_device::read_exg_168_register(uint8_t reg) +{ + uint16_t result; + + switch(reg & 0x0F) + { + case 0: result = m_q.r.d; break; // D + case 1: result = m_x.w; break; // X + case 2: result = m_y.w; break; // Y + case 3: result = m_u.w; break; // U + case 4: result = m_s.w; break; // S + case 5: result = m_pc.w; break; // PC + case 8: result = ((uint16_t)0xff00) | m_q.r.a; break; // A + case 9: result = ((uint16_t)0xff00) | m_q.r.b; break; // B + case 10: result = ((uint16_t)0xff00) | m_cc; break; // CC + case 11: result = ((uint16_t)0xff00) | m_dp; break; // DP + default: result = 0xffff; break; + } + return result; } @@ -523,20 +552,20 @@ m6809_base_device::exgtfr_register m6809_base_device::read_exgtfr_register(uint8 // write_exgtfr_register //------------------------------------------------- -void m6809_base_device::write_exgtfr_register(uint8_t reg, m6809_base_device::exgtfr_register value) +void m6809_base_device::write_exgtfr_register(uint8_t reg, uint16_t value) { switch(reg & 0x0F) { - case 0: m_q.r.d = value.word_value; break; // D - case 1: m_x.w = value.word_value; break; // X - case 2: m_y.w = value.word_value; break; // Y - case 3: m_u.w = value.word_value; break; // U - case 4: m_s.w = value.word_value; break; // S - case 5: m_pc.w = value.word_value; break; // PC - case 8: m_q.r.a = value.byte_value; break; // A - case 9: m_q.r.b = value.byte_value; break; // B - case 10: m_cc = value.byte_value; break; // CC - case 11: m_dp = value.byte_value; break; // DP + case 0: m_q.r.d = value; break; // D + case 1: m_x.w = value; break; // X + case 2: m_y.w = value; break; // Y + case 3: m_u.w = value; break; // U + case 4: m_s.w = value; break; // S + case 5: m_pc.w = value; break; // PC + case 8: m_q.r.a = (uint8_t)value; break; // A + case 9: m_q.r.b = (uint8_t)value; break; // B + case 10: m_cc = (uint8_t)value; break; // CC + case 11: m_dp = (uint8_t)value; break; // DP } } @@ -581,23 +610,23 @@ void m6809_base_device::execute_run() uint8_t m6809_base_device::mi_default::read(uint16_t adr) { - return m_program->read_byte(adr); + return program.read_byte(adr); } uint8_t m6809_base_device::mi_default::read_opcode(uint16_t adr) { - return m_scache->read_byte(adr); + return csprogram.read_byte(adr); } uint8_t m6809_base_device::mi_default::read_opcode_arg(uint16_t adr) { - return m_cache->read_byte(adr); + return cprogram.read_byte(adr); } void m6809_base_device::mi_default::write(uint16_t adr, uint8_t val) { - m_program->write_byte(adr, val); + program.write_byte(adr, val); } @@ -618,7 +647,7 @@ mc6809_device::mc6809_device(const machine_config &mconfig, const char *tag, dev //------------------------------------------------- mc6809e_device::mc6809e_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : m6809_base_device(mconfig, tag, owner, clock, MC6809E, 1) + : m6809_base_device(mconfig, tag, owner, clock, MC6809E, 1) { } |