summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/cop400/cop400.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/cop400/cop400.cpp')
-rw-r--r--src/devices/cpu/cop400/cop400.cpp141
1 files changed, 72 insertions, 69 deletions
diff --git a/src/devices/cpu/cop400/cop400.cpp b/src/devices/cpu/cop400/cop400.cpp
index 6317e4451f8..8b4ffbe3094 100644
--- a/src/devices/cpu/cop400/cop400.cpp
+++ b/src/devices/cpu/cop400/cop400.cpp
@@ -2,9 +2,12 @@
// copyright-holders:Curt Coder
/***************************************************************************
- cop400.c
+ cop400.cpp
- National Semiconductor COP400 Emulator.
+ National Semiconductor COPS(COP400 series) emulator.
+
+ This MCU series was initially briefly known as COPS II, where COPS I was
+ designated to the earlier MM57xx series.
****************************************************************************
@@ -54,7 +57,6 @@
*/
#include "emu.h"
-#include "debugger.h"
#include "cop400.h"
#include "cop410ds.h"
#include "cop420ds.h"
@@ -86,7 +88,9 @@ DEFINE_DEVICE_TYPE(COP446C, cop446c_cpu_device, "cop446c", "National Semiconduct
CONSTANTS
***************************************************************************/
-#define LOG_MICROBUS 0
+#define LOG_MICROBUS (1U << 1)
+#define VERBOSE (0)
+#include "logmacro.h"
// step through skipped instructions in debugger
#define COP_DEBUG_SKIP 0
@@ -96,9 +100,9 @@ DEFINE_DEVICE_TYPE(COP446C, cop446c_cpu_device, "cop446c", "National Semiconduct
MACROS
***************************************************************************/
-#define ROM(a) m_cache->read_byte(a)
-#define RAM_R(a) m_data->read_byte(a)
-#define RAM_W(a, v) m_data->write_byte(a, v)
+#define ROM(a) m_program.read_byte(a)
+#define RAM_R(a) m_data.read_byte(a)
+#define RAM_W(a, v) m_data.write_byte(a, v)
#define IN_G() (m_read_g(0, 0xff) & m_g_mask)
#define IN_L() m_read_l(0, 0xff)
@@ -107,10 +111,10 @@ DEFINE_DEVICE_TYPE(COP446C, cop446c_cpu_device, "cop446c", "National Semiconduct
#define IN_IN() (m_in_mask ? m_read_in(0, 0xff) : 0)
#define OUT_G(v) m_write_g(0, (v) & m_g_mask, 0xff)
-#define OUT_L(v) m_write_l(0, v, 0xff)
+#define OUT_L(v) m_write_l(0, m_l_output = v, 0xff)
#define OUT_D(v) m_write_d(0, (v) & m_d_mask, 0xff)
-#define OUT_SK(v) m_write_sk(v)
-#define OUT_SO(v) m_write_so(v)
+#define OUT_SK(v) m_write_sk(m_sk_output = v)
+#define OUT_SO(v) m_write_so(m_so_output = v)
#define PC m_pc
#define A m_a
@@ -172,17 +176,17 @@ cop400_cpu_device::cop400_cpu_device(const machine_config &mconfig, device_type
: cpu_device(mconfig, type, tag, owner, clock)
, m_program_config("program", ENDIANNESS_LITTLE, 8, program_addr_bits, 0, internal_map_program)
, m_data_config("data", ENDIANNESS_LITTLE, 8, data_addr_bits, 0, internal_map_data) // data width is really 4
- , m_read_l(*this)
- , m_read_l_tristate(*this)
+ , m_read_l(*this, 0)
+ , m_read_l_tristate(*this, 0)
, m_write_l(*this)
- , m_read_g(*this)
+ , m_read_g(*this, 0)
, m_write_g(*this)
, m_write_d(*this)
- , m_read_in(*this)
- , m_read_si(*this)
+ , m_read_in(*this, 0)
+ , m_read_si(*this, 0)
, m_write_so(*this)
, m_write_sk(*this)
- , m_read_cko(*this)
+ , m_read_cko(*this, 0)
, m_cki(COP400_CKI_DIVISOR_16)
, m_cko(COP400_CKO_OSCILLATOR_OUTPUT)
, m_has_microbus(false)
@@ -194,9 +198,9 @@ cop400_cpu_device::cop400_cpu_device(const machine_config &mconfig, device_type
, m_in_mask(in_mask)
{
for (int i = 0; i < 256; i++)
- m_InstLen[i] = 1;
+ m_instlen[i] = 1;
- m_InstLen[0x33] = m_InstLen[0x23] = 2;
+ m_instlen[0x33] = m_instlen[0x23] = 2;
switch (featuremask)
{
@@ -205,8 +209,8 @@ cop400_cpu_device::cop400_cpu_device(const machine_config &mconfig, device_type
for (int r = 0; r < 2; r++)
{
- m_InstLen[0x60 + r] = 2; // JMP
- m_InstLen[0x68 + r] = 2; // JSR
+ m_instlen[0x60 + r] = 2; // JMP
+ m_instlen[0x68 + r] = 2; // JSR
}
break;
@@ -215,8 +219,8 @@ cop400_cpu_device::cop400_cpu_device(const machine_config &mconfig, device_type
for (int r = 0; r < 4; r++)
{
- m_InstLen[0x60 + r] = 2; // JMP
- m_InstLen[0x68 + r] = 2; // JSR
+ m_instlen[0x60 + r] = 2; // JMP
+ m_instlen[0x68 + r] = 2; // JSR
}
break;
@@ -225,8 +229,8 @@ cop400_cpu_device::cop400_cpu_device(const machine_config &mconfig, device_type
for (int r = 0; r < 8; r++)
{
- m_InstLen[0x60 + r] = 2; // JMP
- m_InstLen[0x68 + r] = 2; // JSR
+ m_instlen[0x60 + r] = 2; // JMP
+ m_instlen[0x68 + r] = 2; // JSR
}
break;
@@ -235,8 +239,8 @@ cop400_cpu_device::cop400_cpu_device(const machine_config &mconfig, device_type
for (int r = 0; r < 8; r++)
{
- m_InstLen[0x60 + r] = 2; // JMP
- m_InstLen[0x68 + r] = 2; // JSR
+ m_instlen[0x60 + r] = 2; // JMP
+ m_instlen[0x68 + r] = 2; // JSR
}
break;
@@ -1029,7 +1033,7 @@ void cop400_cpu_device::serial_tick()
}
}
-void cop400_cpu_device::counter_tick()
+TIMER_CALLBACK_MEMBER(cop400_cpu_device::advance_counter)
{
T++;
@@ -1059,46 +1063,21 @@ void cop400_cpu_device::inil_tick()
INITIALIZATION
***************************************************************************/
-void cop400_cpu_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
-{
- switch (id)
- {
- case TIMER_COUNTER:
- counter_tick();
- break;
- }
-}
-
-
void cop400_cpu_device::device_start()
{
- /* find address spaces */
- m_program = &space(AS_PROGRAM);
- m_cache = m_program->cache<0, 0, ENDIANNESS_LITTLE>();
- m_data = &space(AS_DATA);
-
- /* find i/o handlers */
- m_read_l.resolve_safe(0);
- m_read_l_tristate.resolve_safe(0);
- m_write_l.resolve_safe();
- m_read_g.resolve_safe(0);
- m_write_g.resolve_safe();
- m_write_d.resolve_safe();
- m_read_in.resolve_safe(0);
- m_read_si.resolve_safe(0);
- m_write_so.resolve_safe();
- m_write_sk.resolve_safe();
- m_read_cko.resolve_safe(0);
-
- /* allocate counter timer */
+ // find address spaces
+ space(AS_PROGRAM).cache(m_program);
+ space(AS_DATA).specific(m_data);
+
+ // allocate counter timer
m_counter_timer = nullptr;
if (m_has_counter)
{
- m_counter_timer = timer_alloc(TIMER_COUNTER);
+ m_counter_timer = timer_alloc(FUNC(cop400_cpu_device::advance_counter), this);
m_counter_timer->adjust(attotime::zero, 0, attotime::from_ticks(m_cki * 4, clock()));
}
- /* register for state saving */
+ // register for state saving
save_item(NAME(m_pc));
save_item(NAME(m_prevpc));
save_item(NAME(m_sa));
@@ -1111,12 +1090,15 @@ void cop400_cpu_device::device_start()
save_item(NAME(m_q));
save_item(NAME(m_en));
save_item(NAME(m_sio));
+ save_item(NAME(m_si));
+ save_item(NAME(m_so_output));
+ save_item(NAME(m_sk_output));
+ save_item(NAME(m_l_output));
save_item(NAME(m_skl));
save_item(NAME(m_t));
save_item(NAME(m_skip));
save_item(NAME(m_skip_lbi));
save_item(NAME(m_skt_latch));
- save_item(NAME(m_si));
save_item(NAME(m_last_skip));
save_item(NAME(m_in));
save_item(NAME(m_halt));
@@ -1125,7 +1107,7 @@ void cop400_cpu_device::device_start()
save_item(NAME(m_second_byte));
// setup debugger state display
- offs_t pc_mask = m_program->addrmask();
+ offs_t pc_mask = m_program.space().addrmask();
using namespace std::placeholders;
state_add(STATE_GENPC, "GENPC", m_pc).mask(pc_mask).noshow();
@@ -1151,18 +1133,39 @@ void cop400_cpu_device::device_start()
set_icountptr(m_icount);
+ // zerofill
+ m_pc = 0;
+ m_prevpc = 0;
+ m_a = 0;
+ m_b = 0;
+ m_c = 0;
+ m_en = 0;
+ m_g = 0;
m_q = 0;
m_sa = 0;
m_sb = 0;
m_sc = 0;
m_sio = 0;
+ m_skl = 0;
+
+ m_t = 0;
+ m_skt_latch = 0;
+
m_il = 0;
- m_in[0] = m_in[1] = m_in[2] = m_in[3] = 0;
+ memset(m_in, 0, sizeof(m_in));
m_si = 0;
+ m_so_output = 0;
+ m_sk_output = 0;
+ m_l_output = 0;
+
+ m_skip = false;
m_skip_lbi = 0;
m_last_skip = false;
- m_skip = false;
+ m_halt = false;
+ m_idle = false;
+
m_opcode = 0x44;
+ m_second_byte = false;
}
@@ -1265,7 +1268,7 @@ void cop400_cpu_device::execute_run()
// disable interrupts
EN &= ~2;
}
- else if (!m_second_byte && m_InstLen[m_opcode] > 1)
+ else if (!m_second_byte && m_instlen[m_opcode] > 1)
{
m_second_byte = true;
}
@@ -1330,7 +1333,7 @@ void cop400_cpu_device::set_flags(uint8_t flags)
m_skl = BIT(flags, 0);
}
-uint8_t cop400_cpu_device::get_m() const
+uint8_t cop400_cpu_device::get_m()
{
auto dis = machine().disable_side_effects();
return RAM_R(B);
@@ -1384,16 +1387,16 @@ std::unique_ptr<util::disasm_interface> cop400_cpu_device::create_disassembler()
return std::make_unique<cop410_disassembler>();
}
-READ8_MEMBER( cop400_cpu_device::microbus_rd )
+uint8_t cop400_cpu_device::microbus_r()
{
- if (LOG_MICROBUS) logerror("%s %s MICROBUS RD %02x\n", machine().time().as_string(), machine().describe_context(), Q);
+ LOGMASKED(LOG_MICROBUS, "%s %s MICROBUS R %02x\n", machine().time().as_string(), machine().describe_context(), Q);
return Q;
}
-WRITE8_MEMBER( cop400_cpu_device::microbus_wr )
+void cop400_cpu_device::microbus_w(uint8_t data)
{
- if (LOG_MICROBUS) logerror("%s %s MICROBUS WR %02x\n", machine().time().as_string(), machine().describe_context(), data);
+ LOGMASKED(LOG_MICROBUS, "%s %s MICROBUS W %02x\n", machine().time().as_string(), machine().describe_context(), data);
WRITE_G(G & 0xe);