summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/m6809/m6809.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/m6809/m6809.cpp')
-rw-r--r--src/devices/cpu/m6809/m6809.cpp153
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)
{
}