diff options
Diffstat (limited to 'src/devices/cpu/cop400/cop400.cpp')
-rw-r--r-- | src/devices/cpu/cop400/cop400.cpp | 141 |
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); |