From 64c117bb504873add7603778ed7942535ba0877c Mon Sep 17 00:00:00 2001 From: AJR Date: Mon, 11 Sep 2017 08:38:25 -0400 Subject: COP400 overhaul - Rewrite the execution control logic to fetch each byte of an instruction separately in one pass of the main loop. This provides EEPROM-compatible timing for the SIO shift register, allowing the 93C46 on quizpun2 to be read and written properly (though its default contents are a bad dump). - Add M pseudo-register (internal RAM referenced by B) to debugger state. - Add T register to debugger state on devices where it only affects SKT. - The SIO state is now displayed in binary when it is defined as a shift register. - Skipped instructions and the SKIP flag can be debugged by compile-time switch (disabled by default). --- src/devices/cpu/cop400/cop400.cpp | 306 +++++++++++++++++++++++------------- src/devices/cpu/cop400/cop400.h | 175 +++++++++++---------- src/devices/cpu/cop400/cop400op.hxx | 94 ++++++----- src/mame/drivers/quizpun2.cpp | 4 +- 4 files changed, 334 insertions(+), 245 deletions(-) diff --git a/src/devices/cpu/cop400/cop400.cpp b/src/devices/cpu/cop400/cop400.cpp index 1db85978414..30b1680150a 100644 --- a/src/devices/cpu/cop400/cop400.cpp +++ b/src/devices/cpu/cop400/cop400.cpp @@ -50,7 +50,6 @@ - COP410L/COP410C - save internal RAM when CKO is RAM power supply pin - COP404L opcode map switching, dual timer, microbus enable - - improve SIO output timing for interface with 93CXX serial EEPROMs */ @@ -85,6 +84,9 @@ DEFINE_DEVICE_TYPE(COP446C, cop446c_cpu_device, "cop446c", "COP446C") #define LOG_MICROBUS 0 +// step through skipped instructions in debugger +#define COP_DEBUG_SKIP 0 + /*************************************************************************** MACROS @@ -181,9 +183,8 @@ cop400_cpu_device::cop400_cpu_device(const machine_config &mconfig, device_type , m_d_mask(d_mask) , m_in_mask(in_mask) { - for (int i = 0; i < 256; i++) { + for (int i = 0; i < 256; i++) m_InstLen[i] = 1; - } m_InstLen[0x33] = m_InstLen[0x23] = 2; @@ -192,7 +193,8 @@ cop400_cpu_device::cop400_cpu_device(const machine_config &mconfig, device_type case COP410_FEATURE: m_opcode_map = COP410_OPCODE_MAP; - for (int r = 0; r < 2; r++) { + for (int r = 0; r < 2; r++) + { m_InstLen[0x60 + r] = 2; // JMP m_InstLen[0x68 + r] = 2; // JSR } @@ -201,7 +203,8 @@ cop400_cpu_device::cop400_cpu_device(const machine_config &mconfig, device_type case COP420_FEATURE: m_opcode_map = COP420_OPCODE_MAP; - for (int r = 0; r < 4; r++) { + for (int r = 0; r < 4; r++) + { m_InstLen[0x60 + r] = 2; // JMP m_InstLen[0x68 + r] = 2; // JSR } @@ -210,7 +213,8 @@ cop400_cpu_device::cop400_cpu_device(const machine_config &mconfig, device_type case COP444L_FEATURE: m_opcode_map = COP444L_OPCODE_MAP; - for (int r = 0; r < 8; r++) { + for (int r = 0; r < 8; r++) + { m_InstLen[0x60 + r] = 2; // JMP m_InstLen[0x68 + r] = 2; // JSR } @@ -219,7 +223,8 @@ cop400_cpu_device::cop400_cpu_device(const machine_config &mconfig, device_type case COP424C_FEATURE: m_opcode_map = COP424C_OPCODE_MAP; - for (int r = 0; r < 8; r++) { + for (int r = 0; r < 8; r++) + { m_InstLen[0x60 + r] = 2; // JMP m_InstLen[0x68 + r] = 2; // JSR } @@ -369,16 +374,39 @@ void cop400_cpu_device::WRITE_G(uint8_t data) OUT_G(G); } +void cop400_cpu_device::WRITE_EN(uint8_t data) +{ + if (EN != data) + { + EN = data; + + if (BIT(EN, 2)) + { + OUT_L(Q); + } + else + { + // tri-state(floating) pins + OUT_L(m_read_l_tristate(0, 0xff)); + } + + sk_update(); + } +} + /*************************************************************************** OPCODE HANDLERS ***************************************************************************/ -#define INSTRUCTION(mnemonic) void (cop400_cpu_device::mnemonic)(uint8_t opcode) +#define INSTRUCTION(mnemonic) void (cop400_cpu_device::mnemonic)(uint8_t operand) #define OP(mnemonic) &cop400_cpu_device::mnemonic INSTRUCTION(illegal) { - logerror("COP400: PC = %03x, Illegal opcode = %02x\n", PC-1, ROM(PC-1)); + if (m_second_byte) + logerror("COP400: PC = %03x, Illegal opcode = %02x %02x\n", m_prevpc, m_opcode, operand); + else + logerror("COP400: PC = %03x, Illegal opcode = %02x\n", m_prevpc, m_opcode); } #include "cop400op.hxx" @@ -426,9 +454,9 @@ const cop400_cpu_device::cop400_opcode_func cop400_cpu_device::COP410_OPCODE_23_ OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) }; -void cop400_cpu_device::cop410_op23(uint8_t opcode) +void cop400_cpu_device::cop410_op23(uint8_t operand) { - uint8_t opcode23 = fetch(); + uint8_t opcode23 = operand; (this->*COP410_OPCODE_23_MAP[opcode23])(opcode23); } @@ -472,9 +500,9 @@ const cop400_cpu_device::cop400_opcode_func cop400_cpu_device::COP410_OPCODE_33_ OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) }; -void cop400_cpu_device::cop410_op33(uint8_t opcode) +void cop400_cpu_device::cop410_op33(uint8_t operand) { - uint8_t opcode33 = fetch(); + uint8_t opcode33 = operand; (this->*COP410_OPCODE_33_MAP[opcode33])(opcode33); } @@ -557,9 +585,9 @@ const cop400_cpu_device::cop400_opcode_func cop400_cpu_device::COP420_OPCODE_23_ OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) }; -void cop400_cpu_device::cop420_op23(uint8_t opcode) +void cop400_cpu_device::cop420_op23(uint8_t operand) { - uint8_t opcode23 = fetch(); + uint8_t opcode23 = operand; (this->*COP420_OPCODE_23_MAP[opcode23])(opcode23); } @@ -603,9 +631,9 @@ const cop400_cpu_device::cop400_opcode_func cop400_cpu_device::COP420_OPCODE_33_ OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) }; -void cop400_cpu_device::cop420_op33(uint8_t opcode) +void cop400_cpu_device::cop420_op33(uint8_t operand) { - uint8_t opcode33 = fetch(); + uint8_t opcode33 = operand; (this->*COP420_OPCODE_33_MAP[opcode33])(opcode33); } @@ -688,9 +716,9 @@ const cop400_cpu_device::cop400_opcode_func cop400_cpu_device::COP444L_OPCODE_23 OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) }; -void cop400_cpu_device::cop444l_op23(uint8_t opcode) +void cop400_cpu_device::cop444l_op23(uint8_t operand) { - uint8_t opcode23 = fetch(); + uint8_t opcode23 = operand; (this->*COP444L_OPCODE_23_MAP[opcode23])(opcode23); } @@ -734,9 +762,9 @@ const cop400_cpu_device::cop400_opcode_func cop400_cpu_device::COP444L_OPCODE_33 OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) }; -void cop400_cpu_device::cop444l_op33(uint8_t opcode) +void cop400_cpu_device::cop444l_op33(uint8_t operand) { - uint8_t opcode33 = fetch(); + uint8_t opcode33 = operand; (this->*COP444L_OPCODE_33_MAP[opcode33])(opcode33); } @@ -819,9 +847,9 @@ const cop400_cpu_device::cop400_opcode_func cop400_cpu_device::COP424C_OPCODE_23 OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) }; -void cop400_cpu_device::cop424c_op23(uint8_t opcode) +void cop400_cpu_device::cop424c_op23(uint8_t operand) { - uint8_t opcode23 = fetch(); + uint8_t opcode23 = operand; (this->*COP424C_OPCODE_23_MAP[opcode23])(opcode23); } @@ -865,9 +893,9 @@ const cop400_cpu_device::cop400_opcode_func cop400_cpu_device::COP424C_OPCODE_33 OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) }; -void cop400_cpu_device::cop424c_op33(uint8_t opcode) +void cop400_cpu_device::cop424c_op33(uint8_t operand) { - uint8_t opcode33 = fetch(); + uint8_t opcode33 = operand; (this->*COP424C_OPCODE_33_MAP[opcode33])(opcode33); } @@ -911,6 +939,24 @@ const cop400_cpu_device::cop400_opcode_func cop400_cpu_device::COP424C_OPCODE_MA OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jid) }; +inline bool cop400_cpu_device::is_control_transfer(uint8_t opcode) +{ + // JP, JSRP, JID or LQID + // (TODO: verify that LQID inhibits interrupts since it transfers control temporarily) + if ((opcode & 0x80) == 0x80) + return true; + + // JMP or JSR + if ((opcode & 0xf0) == 0x60) + return true; + + // RET or RETSK + if ((opcode & 0xfe) == 0x48) + return true; + + return false; +} + /*************************************************************************** TIMER CALLBACKS ***************************************************************************/ @@ -931,10 +977,6 @@ void cop400_cpu_device::serial_tick() OUT_SO(BIT(EN, 3)); - // serial clock - - OUT_SK(SKL); - // serial input m_si <<= 1; @@ -971,17 +1013,6 @@ void cop400_cpu_device::serial_tick() OUT_SO(0); } - // serial clock - - if (SKL) - { - OUT_SK(1); // SYNC - } - else - { - OUT_SK(0); - } - // serial input SIO = ((SIO << 1) | IN_SI()) & 0x0f; @@ -992,7 +1023,8 @@ void cop400_cpu_device::counter_tick() { T++; - if (!T) { + if (!T) + { m_skt_latch = 1; m_idle = false; } @@ -1000,12 +1032,9 @@ void cop400_cpu_device::counter_tick() void cop400_cpu_device::inil_tick() { - uint8_t in; - int i; - - in = IN_IN(); + uint8_t in = IN_IN(); - for (i = 0; i < 4; i++) + for (int i = 0; i < 4; i++) { m_in[i] = (m_in[i] << 1) | BIT(in, i); @@ -1024,17 +1053,9 @@ void cop400_cpu_device::device_timer(emu_timer &timer, device_timer_id id, int p { switch (id) { - case TIMER_SERIAL: - serial_tick(); - break; - case TIMER_COUNTER: counter_tick(); break; - - case TIMER_INIL: - inil_tick(); - break; } } @@ -1059,10 +1080,6 @@ void cop400_cpu_device::device_start() m_write_sk.resolve_safe(); m_read_cko.resolve_safe(0); - /* allocate serial timer */ - m_serial_timer = timer_alloc(TIMER_SERIAL); - m_serial_timer->adjust(attotime::zero, 0, attotime::from_ticks(m_cki, clock())); - /* allocate counter timer */ m_counter_timer = nullptr; if (m_has_counter) @@ -1071,14 +1088,6 @@ void cop400_cpu_device::device_start() m_counter_timer->adjust(attotime::zero, 0, attotime::from_ticks(m_cki * 4, clock())); } - /* allocate IN latch timer */ - m_inil_timer = nullptr; - if (m_has_inil) - { - m_inil_timer = timer_alloc(TIMER_INIL); - m_inil_timer->adjust(attotime::zero, 0, attotime::from_ticks(m_cki, clock())); - } - /* register for state saving */ save_item(NAME(m_pc)); save_item(NAME(m_prevpc)); @@ -1102,6 +1111,8 @@ void cop400_cpu_device::device_start() save_item(NAME(m_in)); save_item(NAME(m_halt)); save_item(NAME(m_idle)); + save_item(NAME(m_opcode)); + save_item(NAME(m_second_byte)); // setup debugger state display offs_t pc_mask = m_program->addrmask(); @@ -1112,18 +1123,20 @@ void cop400_cpu_device::device_start() state_add(COP400_PC, "PC", m_pc).mask(pc_mask); state_add(COP400_SA, "SA", m_sa).mask(pc_mask); state_add(COP400_SB, "SB", m_sb).mask(pc_mask); - if (!(m_featuremask & COP410_FEATURE)) { + if (!(m_featuremask & COP410_FEATURE)) state_add(COP400_SC, "SC", m_sc).mask(pc_mask); - } state_add(COP400_B, "B", m_b); state_add(COP400_A, "A", m_a).mask(0xf); + state_add(COP400_M, "M", m_temp_m).mask(0xf).callimport().callexport(); state_add(COP400_G, "G", m_g).mask(0xf); state_add(COP400_Q, "Q", m_q); - state_add(COP400_SIO, "SIO", m_sio).mask(0xf); + state_add(COP400_SIO, "SIO", m_sio).mask(0xf).formatstr("%4s"); state_add(COP400_EN, "EN", m_en).mask(0xf); - if (m_featuremask & COP424C_FEATURE) { + if (m_has_counter) state_add(COP400_T, "T", m_t); - } +#if COP_DEBUG_SKIP + state_add(COP400_SKIP, "SKIP", m_skip).mask(1); +#endif m_icountptr = &m_icount; @@ -1133,12 +1146,14 @@ void cop400_cpu_device::device_start() m_sc = 0; m_sio = 0; m_flags = 0; + m_temp_m = 0; m_il = 0; m_in[0] = m_in[1] = m_in[2] = m_in[3] = 0; m_si = 0; m_skip_lbi = 0; m_last_skip = false; m_skip = false; + m_opcode = 0x44; } @@ -1154,55 +1169,80 @@ void cop400_cpu_device::device_reset() C = 0; OUT_D(0); EN = 0; + OUT_L(m_read_l_tristate(0, 0xff)); WRITE_G(0); SKL = 1; + OUT_SK(0); T = 0; m_skt_latch = 1; m_halt = false; m_idle = false; + m_second_byte = false; } /*************************************************************************** EXECUTION ***************************************************************************/ -uint8_t cop400_cpu_device::fetch() +void cop400_cpu_device::skip() { - m_icount--; + // skip the next instruction (TODO: this flag can become an output) + m_skip = true; +} - return ROM(PC++); +void cop400_cpu_device::sk_update() +{ + // update SK output after XAS or LEI + if (BIT(EN, 0)) + { + // SK = SKL when EN0 = 1 (binary counter mode) + OUT_SK(SKL); + } + else + { + // SK = clock or 0 when EN0 = 0 (shift register mode) + OUT_SK(0); + } } void cop400_cpu_device::execute_run() { do { - if (!m_skip) { + if (!m_second_byte && (!m_skip || COP_DEBUG_SKIP)) + { // debugger hook m_prevpc = PC; debugger_instruction_hook(this, PC); } // halt logic - if (m_cko == COP400_CKO_HALT_IO_PORT) { + if (m_cko == COP400_CKO_HALT_IO_PORT) m_halt = IN_CKO(); - } - if (m_halt || m_idle) { - m_icount--; - continue; - } + if (!m_halt && !m_idle) + { + if (!BIT(EN, 0) && SKL) + { + // Sync pulse actually has a 50% duty cycle, coinciding with address latch for external program + // This implementation, however, is good enough to interface with 93CXX serial EEPROMs + OUT_SK(0); + OUT_SK(1); + } + + // fetch opcode/operand + uint8_t operand = ROM(PC++); + if (!m_second_byte) + m_opcode = operand; - // fetch opcode - uint8_t opcode = fetch(); - cop400_opcode_func function = m_opcode_map[opcode]; + // check for interrupt when all successive transfer of control instructions and successive LBIs have been completed + if (!m_second_byte && BIT(EN, 1) && BIT(IL, 1) && !is_control_transfer(m_opcode) && !m_skip_lbi) + { + // acknowledge interrupt + IL &= ~2; - // check for interrupt - if (BIT(EN, 1) && BIT(IL, 1)) { - // all successive transfer of control instructions and successive LBIs have been completed - if ((function != OP(jp)) && (function != OP(jmp)) && (function != OP(jsr)) && !m_skip_lbi) { // store skip logic m_last_skip = m_skip; m_skip = false; @@ -1213,31 +1253,53 @@ void cop400_cpu_device::execute_run() // jump to interrupt service routine PC = 0x0ff; - // disable interrupt - EN &= ~0x02; + // disable interrupts + EN &= ~2; } - - IL &= ~2; - } - - if (m_skip) { - // skip instruction - if (m_InstLen[opcode] == 2) { - // fetch second byte - opcode = fetch(); + else if (!m_second_byte && m_InstLen[m_opcode] > 1) + { + m_second_byte = true; + } + else if (m_skip) + { + // finish skipping and execute next instruction + m_skip = false; + m_second_byte = false; + } + else + { + cop400_opcode_func function = m_opcode_map[m_opcode]; + + if (!m_second_byte && (function == OP(jid) || function == OP(lqid))) + { + // JID and LQID must first transfer control and then fetch the operand + // LQID saves the old program counter on the stack; JID doesn't and just jumps again + if (function == OP(lqid)) + PUSH(PC); + + // jump within page to operand at A/M + PC = (PC & 0x700) | (A << 4) | RAM_R(B); + m_second_byte = true; + } + else + { + // execute instruction + (this->*(function))(operand); + + // LBI skip logic + if (m_skip_lbi > 0) + m_skip_lbi--; + + // ready for the next instruction + m_second_byte = false; + } } - m_skip = false; - continue; - } - - // execute instruction - (this->*(function))(opcode); - - // LBI skip logic - if (m_skip_lbi > 0) { - m_skip_lbi--; + serial_tick(); + if (m_has_inil) + inil_tick(); } + m_icount--; } while (m_icount > 0); } @@ -1256,6 +1318,11 @@ void cop400_cpu_device::state_import(const device_state_entry &entry) m_c = BIT(m_flags, 1); m_skl = BIT(m_flags, 0); break; + + case COP400_M: + auto dis = machine().disable_side_effect(); + RAM_W(B, m_temp_m); + break; } } @@ -1266,6 +1333,11 @@ void cop400_cpu_device::state_export(const device_state_entry &entry) case STATE_GENFLAGS: m_flags = (m_skt_latch ? 0x04 : 0x00) | (m_c ? 0x02 : 0x00) | (m_skl ? 0x01 : 0x00); break; + + case COP400_M: + auto dis = machine().disable_side_effect(); + m_temp_m = RAM_R(B); + break; } } @@ -1279,6 +1351,22 @@ void cop400_cpu_device::state_string_export(const device_state_entry &entry, std m_skl ? 'S' : '.', m_skt_latch ? 'T' : '.'); break; + case COP400_SIO: + if (BIT(EN, 0)) + { + // display counter in hex + str = string_format("%X ", m_sio); + } + else + { + // display shift register in binary + str = string_format("%d%d%d%d", + BIT(m_sio, 3), + BIT(m_sio, 2), + BIT(m_sio, 1), + BIT(m_sio, 0)); + } + break; } } diff --git a/src/devices/cpu/cop400/cop400.h b/src/devices/cpu/cop400/cop400.h index 1db27e77228..13461ffe583 100644 --- a/src/devices/cpu/cop400/cop400.h +++ b/src/devices/cpu/cop400/cop400.h @@ -68,11 +68,13 @@ enum COP400_B, COP400_C, COP400_G, + COP400_M, COP400_Q, COP400_EN, COP400_SIO, COP400_SKL, - COP400_T + COP400_T, + COP400_SKIP }; /* input lines */ @@ -224,7 +226,8 @@ protected: uint16_t m_sa, m_sb, m_sc; /* subroutine save registers */ uint8_t m_sio; /* 4-bit shift register and counter */ int m_skl; /* 1-bit latch for SK output */ - uint8_t m_flags; // used for I/O only + uint8_t m_flags; // used for debugger state only + uint8_t m_temp_m; // 4-bit RAM at B (for debugger state only) /* counter */ uint8_t m_t; /* 8-bit timer */ @@ -248,13 +251,13 @@ protected: /* execution logic */ int m_InstLen[256]; /* instruction length in bytes */ int m_icount; /* instruction counter */ + uint8_t m_opcode; /* opcode being executed */ + bool m_second_byte; /* second byte of opcode */ /* timers */ - emu_timer *m_serial_timer; emu_timer *m_counter_timer; - emu_timer *m_inil_timer; - typedef void ( cop400_cpu_device::*cop400_opcode_func ) (uint8_t opcode); + typedef void (cop400_cpu_device::*cop400_opcode_func)(uint8_t operand); const cop400_opcode_func *m_opcode_map; @@ -271,6 +274,8 @@ protected: static const cop400_opcode_func COP424C_OPCODE_33_MAP[256]; static const cop400_opcode_func COP424C_OPCODE_MAP[256]; + inline static bool is_control_transfer(uint8_t opcode); + void serial_tick(); void counter_tick(); void inil_tick(); @@ -279,85 +284,87 @@ protected: void POP(); void WRITE_Q(uint8_t data); void WRITE_G(uint8_t data); - - uint8_t fetch(); - - void illegal(uint8_t opcode); - void asc(uint8_t opcode); - void add(uint8_t opcode); - void aisc(uint8_t opcode); - void clra(uint8_t opcode); - void comp(uint8_t opcode); - void nop(uint8_t opcode); - void rc(uint8_t opcode); - void sc(uint8_t opcode); - void xor_(uint8_t opcode); - void adt(uint8_t opcode); - void casc(uint8_t opcode); - void jid(uint8_t opcode); - void jmp(uint8_t opcode); - void jp(uint8_t opcode); - void jsr(uint8_t opcode); - void ret(uint8_t opcode); - void cop420_ret(uint8_t opcode); - void retsk(uint8_t opcode); - void halt(uint8_t opcode); - void it(uint8_t opcode); - void camq(uint8_t opcode); - void ld(uint8_t opcode); - void lqid(uint8_t opcode); - void rmb0(uint8_t opcode); - void rmb1(uint8_t opcode); - void rmb2(uint8_t opcode); - void rmb3(uint8_t opcode); - void smb0(uint8_t opcode); - void smb1(uint8_t opcode); - void smb2(uint8_t opcode); - void smb3(uint8_t opcode); - void stii(uint8_t opcode); - void x(uint8_t opcode); - void xad(uint8_t opcode); - void xds(uint8_t opcode); - void xis(uint8_t opcode); - void cqma(uint8_t opcode); - void ldd(uint8_t opcode); - void camt(uint8_t opcode); - void ctma(uint8_t opcode); - void cab(uint8_t opcode); - void cba(uint8_t opcode); - void lbi(uint8_t opcode); - void lei(uint8_t opcode); - void xabr(uint8_t opcode); - void cop444l_xabr(uint8_t opcode); - void skc(uint8_t opcode); - void ske(uint8_t opcode); - void skgz(uint8_t opcode); - void skgbz0(uint8_t opcode); - void skgbz1(uint8_t opcode); - void skgbz2(uint8_t opcode); - void skgbz3(uint8_t opcode); - void skmbz0(uint8_t opcode); - void skmbz1(uint8_t opcode); - void skmbz2(uint8_t opcode); - void skmbz3(uint8_t opcode); - void skt(uint8_t opcode); - void ing(uint8_t opcode); - void inl(uint8_t opcode); - void obd(uint8_t opcode); - void omg(uint8_t opcode); - void xas(uint8_t opcode); - void inin(uint8_t opcode); - void cop402m_inin(uint8_t opcode); - void inil(uint8_t opcode); - void ogi(uint8_t opcode); - void cop410_op23(uint8_t opcode); - void cop410_op33(uint8_t opcode); - void cop420_op23(uint8_t opcode); - void cop420_op33(uint8_t opcode); - void cop444l_op23(uint8_t opcode); - void cop444l_op33(uint8_t opcode); - void cop424c_op23(uint8_t opcode); - void cop424c_op33(uint8_t opcode); + void WRITE_EN(uint8_t data); + + void skip(); + void sk_update(); + + void illegal(uint8_t operand); + void asc(uint8_t operand); + void add(uint8_t operand); + void aisc(uint8_t operand); + void clra(uint8_t operand); + void comp(uint8_t operand); + void nop(uint8_t operand); + void rc(uint8_t operand); + void sc(uint8_t operand); + void xor_(uint8_t operand); + void adt(uint8_t operand); + void casc(uint8_t operand); + void jid(uint8_t operand); + void jmp(uint8_t operand); + void jp(uint8_t operand); + void jsr(uint8_t operand); + void ret(uint8_t operand); + void cop420_ret(uint8_t operand); + void retsk(uint8_t operand); + void halt(uint8_t operand); + void it(uint8_t operand); + void camq(uint8_t operand); + void ld(uint8_t operand); + void lqid(uint8_t operand); + void rmb0(uint8_t operand); + void rmb1(uint8_t operand); + void rmb2(uint8_t operand); + void rmb3(uint8_t operand); + void smb0(uint8_t operand); + void smb1(uint8_t operand); + void smb2(uint8_t operand); + void smb3(uint8_t operand); + void stii(uint8_t operand); + void x(uint8_t operand); + void xad(uint8_t operand); + void xds(uint8_t operand); + void xis(uint8_t operand); + void cqma(uint8_t operand); + void ldd(uint8_t operand); + void camt(uint8_t operand); + void ctma(uint8_t operand); + void cab(uint8_t operand); + void cba(uint8_t operand); + void lbi(uint8_t operand); + void lei(uint8_t operand); + void xabr(uint8_t operand); + void cop444l_xabr(uint8_t operand); + void skc(uint8_t operand); + void ske(uint8_t operand); + void skgz(uint8_t operand); + void skgbz0(uint8_t operand); + void skgbz1(uint8_t operand); + void skgbz2(uint8_t operand); + void skgbz3(uint8_t operand); + void skmbz0(uint8_t operand); + void skmbz1(uint8_t operand); + void skmbz2(uint8_t operand); + void skmbz3(uint8_t operand); + void skt(uint8_t operand); + void ing(uint8_t operand); + void inl(uint8_t operand); + void obd(uint8_t operand); + void omg(uint8_t operand); + void xas(uint8_t operand); + void inin(uint8_t operand); + void cop402m_inin(uint8_t operand); + void inil(uint8_t operand); + void ogi(uint8_t operand); + void cop410_op23(uint8_t operand); + void cop410_op33(uint8_t operand); + void cop420_op23(uint8_t operand); + void cop420_op33(uint8_t operand); + void cop444l_op23(uint8_t operand); + void cop444l_op33(uint8_t operand); + void cop424c_op23(uint8_t operand); + void cop424c_op33(uint8_t operand); void skgbz(int bit); void skmbz(int bit); }; diff --git a/src/devices/cpu/cop400/cop400op.hxx b/src/devices/cpu/cop400/cop400op.hxx index 3242973af3d..4886fcf8127 100644 --- a/src/devices/cpu/cop400/cop400op.hxx +++ b/src/devices/cpu/cop400/cop400op.hxx @@ -35,7 +35,7 @@ INSTRUCTION( asc ) if (A > 0xF) { C = 1; - m_skip = true; + skip(); A &= 0xF; } else @@ -80,13 +80,13 @@ INSTRUCTION( add ) INSTRUCTION( aisc ) { - uint8_t y = opcode & 0x0f; + uint8_t y = m_opcode & 0x0f; A = A + y; if (A > 0x0f) { - m_skip = true; + skip(); A &= 0xF; } } @@ -238,7 +238,7 @@ INSTRUCTION( casc ) if (A > 0xF) { C = 1; - m_skip = true; + skip(); A &= 0xF; } else @@ -266,8 +266,6 @@ INSTRUCTION( casc ) INSTRUCTION( jid ) { - PC = (PC & 0x700) | (A << 4) | RAM_R(B); - uint8_t operand = fetch(); PC = (PC & 0x700) | operand; } @@ -287,8 +285,7 @@ INSTRUCTION( jid ) INSTRUCTION( jmp ) { - uint8_t operand = fetch(); - PC = ((opcode & 0x07) << 8) | operand; + PC = ((m_opcode & 0x07) << 8) | operand; } /* @@ -317,18 +314,18 @@ INSTRUCTION( jp ) if (page == 2 || page == 3) { - uint8_t a = opcode & 0x7f; + uint8_t a = m_opcode & 0x7f; PC = (PC & 0x780) | a; } - else if ((opcode & 0xc0) == 0xc0) + else if ((m_opcode & 0xc0) == 0xc0) { - uint8_t a = opcode & 0x3f; + uint8_t a = m_opcode & 0x3f; PC = (PC & 0x7c0) | a; } else { // JSRP - uint8_t a = opcode & 0x3f; + uint8_t a = m_opcode & 0x3f; PUSH(PC); PC = 0x80 | a; } @@ -351,9 +348,8 @@ INSTRUCTION( jp ) INSTRUCTION( jsr ) { - uint8_t operand = fetch(); PUSH(PC); - PC = ((opcode & 0x07) << 8) | operand; + PC = ((m_opcode & 0x07) << 8) | operand; } /* @@ -413,7 +409,7 @@ INSTRUCTION( cop420_ret ) INSTRUCTION( retsk ) { POP(); - m_skip = true; + skip(); } /* @@ -529,7 +525,7 @@ INSTRUCTION( camq ) INSTRUCTION( ld ) { - uint8_t r = opcode & 0x30; + uint8_t r = m_opcode & 0x30; A = RAM_R(B); B = B ^ r; @@ -551,9 +547,6 @@ INSTRUCTION( ld ) INSTRUCTION( lqid ) { - PUSH(PC); - PC = (PC & 0x700) | (A << 4) | RAM_R(B); - uint8_t operand = fetch(); WRITE_Q(operand); POP(); } @@ -641,7 +634,7 @@ INSTRUCTION( smb3 ) { RAM_W(B, RAM_R(B) | 0x8); } INSTRUCTION( stii ) { - uint8_t y = opcode & 0x0f; + uint8_t y = m_opcode & 0x0f; uint16_t Bd; RAM_W(B, y); @@ -667,7 +660,7 @@ INSTRUCTION( stii ) INSTRUCTION( x ) { - uint8_t r = opcode & 0x30; + uint8_t r = m_opcode & 0x30; uint8_t t = RAM_R(B); RAM_W(B, A); @@ -692,7 +685,7 @@ INSTRUCTION( x ) INSTRUCTION( xad ) { - uint8_t rd = opcode & 0x7f; + uint8_t rd = operand & 0x7f; uint8_t t = A; A = RAM_R(rd); @@ -721,7 +714,7 @@ INSTRUCTION( xad ) INSTRUCTION( xds ) { uint8_t t, Bd; - uint8_t r = opcode & 0x30; + uint8_t r = m_opcode & 0x30; t = RAM_R(B); RAM_W(B, A); @@ -732,7 +725,8 @@ INSTRUCTION( xds ) B = B ^ r; - if (Bd == 0x0f) m_skip = true; + if (Bd == 0x0f) + skip(); } /* @@ -756,7 +750,7 @@ INSTRUCTION( xds ) INSTRUCTION( xis ) { uint8_t t, Bd; - uint8_t r = opcode & 0x30; + uint8_t r = m_opcode & 0x30; t = RAM_R(B); RAM_W(B, A); @@ -767,7 +761,8 @@ INSTRUCTION( xis ) B = B ^ r; - if (Bd == 0x00) m_skip = true; + if (Bd == 0x00) + skip(); } /* @@ -806,7 +801,7 @@ INSTRUCTION( cqma ) INSTRUCTION( ldd ) { - uint8_t rd = opcode & 0x7f; + uint8_t rd = operand & 0x7f; A = RAM_R(rd); } @@ -914,13 +909,13 @@ INSTRUCTION( lbi ) if (m_skip_lbi > 1) return; m_skip_lbi++; - if (opcode & 0x80) + if (operand & 0x80) { - B = opcode & 0x7f; + B = operand & 0x7f; } else { - B = (opcode & 0x30) | (((opcode & 0x0f) + 1) & 0x0f); + B = (operand & 0x30) | (((operand & 0x0f) + 1) & 0x0f); } } @@ -940,19 +935,9 @@ INSTRUCTION( lbi ) INSTRUCTION( lei ) { - uint8_t y = opcode & 0x0f; - - EN = y; + uint8_t y = operand & 0x0f; - if (BIT(EN, 2)) - { - OUT_L(Q); - } - else - { - // tri-state(floating) pins - OUT_L(m_read_l_tristate(0, 0xff)); - } + WRITE_EN(y); } /* @@ -1020,7 +1005,8 @@ INSTRUCTION( cop444l_xabr ) INSTRUCTION( skc ) { - if (C == 1) m_skip = true; + if (C == 1) + skip(); } /* @@ -1038,7 +1024,8 @@ INSTRUCTION( skc ) INSTRUCTION( ske ) { - if (A == RAM_R(B)) m_skip = true; + if (A == RAM_R(B)) + skip(); } /* @@ -1056,7 +1043,8 @@ INSTRUCTION( ske ) INSTRUCTION( skgz ) { - if (IN_G() == 0) m_skip = true; + if (IN_G() == 0) + skip(); } /* @@ -1081,7 +1069,8 @@ INSTRUCTION( skgz ) void cop400_cpu_device::skgbz(int bit) { - if (!BIT(IN_G(), bit)) m_skip = true; + if (!BIT(IN_G(), bit)) + skip(); } INSTRUCTION( skgbz0 ) { skgbz(0); } @@ -1111,7 +1100,8 @@ INSTRUCTION( skgbz3 ) { skgbz(3); } void cop400_cpu_device::skmbz(int bit) { - if (!BIT(RAM_R(B), bit)) m_skip = true; + if (!BIT(RAM_R(B), bit)) + skip(); } INSTRUCTION( skmbz0 ) { skmbz(0); } @@ -1137,7 +1127,7 @@ INSTRUCTION( skt ) if (m_skt_latch) { m_skt_latch = 0; - m_skip = true; + skip(); } } @@ -1241,7 +1231,11 @@ INSTRUCTION( xas ) SIO = A; A = t; - SKL = C; + if (SKL != C) + { + SKL = C; + sk_update(); + } } /* @@ -1318,7 +1312,7 @@ INSTRUCTION( inil ) INSTRUCTION( ogi ) { - uint8_t y = opcode & 0x0f; + uint8_t y = operand & 0x0f; WRITE_G(y); } diff --git a/src/mame/drivers/quizpun2.cpp b/src/mame/drivers/quizpun2.cpp index 225fb6bc150..75a8dabf440 100644 --- a/src/mame/drivers/quizpun2.cpp +++ b/src/mame/drivers/quizpun2.cpp @@ -32,7 +32,7 @@ PCB Layout | YM3014 MAHJONG28 | |---------------------------------------------| Notes: - COP - COP402 or COP404 MCU (DIP40, +5V on pin 17, GND on pin 22). + COP - DIP40 identified as COP402 MCU (+5V on pin 17, GND on pin 22). pins 4,3,2 of 93C46 tied to COP pins 23,24,25 All clocks unknown, PCB not working Possibly Z80's @ 4MHz and YM2203 @ 2MHz @@ -655,7 +655,7 @@ ROM_START( quizpun2 ) ROM_LOAD( "u1", 0x00000, 0x10000, CRC(58506040) SHA1(9d8bed2585e8f188a20270fccd9cfbdb91e48599) ) ROM_LOAD( "u2", 0x10000, 0x10000, CRC(9294a19c) SHA1(cd7109262e5f68b946c84aa390108bcc47ee1300) ) - ROM_REGION16_BE( 0x80, "eeprom", 0 ) // EEPROM (tied to the unknown DIP40) + ROM_REGION16_BE( 0x80, "eeprom", 0 ) // EEPROM ROM_LOAD( "93c46", 0x00, 0x80, CRC(4d244cc8) SHA1(6593d5b7ac1ebb77fee4648ad1d3d9b59a25fdc8) BAD_DUMP ) // backup ram error ROM_END -- cgit v1.2.3