summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author AJR <ajrhacker@users.noreply.github.com>2017-09-11 08:38:25 -0400
committer AJR <ajrhacker@users.noreply.github.com>2017-09-11 08:41:45 -0400
commit64c117bb504873add7603778ed7942535ba0877c (patch)
tree636b0b3944c8d7dff751e5da0bb07621d77d2d00
parent154d80715e70a472ff5ba4b51e2ec67856f9b164 (diff)
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).
-rw-r--r--src/devices/cpu/cop400/cop400.cpp306
-rw-r--r--src/devices/cpu/cop400/cop400.h175
-rw-r--r--src/devices/cpu/cop400/cop400op.hxx94
-rw-r--r--src/mame/drivers/quizpun2.cpp4
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