summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/devices/cpu/pps41/mm76.h2
-rw-r--r--src/devices/cpu/pps41/mm76op.cpp14
-rw-r--r--src/devices/cpu/pps41/mm78.cpp107
-rw-r--r--src/devices/cpu/pps41/mm78.h23
-rw-r--r--src/devices/cpu/pps41/mm78op.cpp138
-rw-r--r--src/devices/cpu/pps41/pps41base.cpp3
6 files changed, 278 insertions, 9 deletions
diff --git a/src/devices/cpu/pps41/mm76.h b/src/devices/cpu/pps41/mm76.h
index bbad09218b5..82956e1829e 100644
--- a/src/devices/cpu/pps41/mm76.h
+++ b/src/devices/cpu/pps41/mm76.h
@@ -68,7 +68,6 @@ protected:
void ram_w(u8 data);
void pop_pc();
void push_pc();
- void op_tr();
void op_illegal();
void op_todo();
@@ -112,6 +111,7 @@ protected:
virtual void op_tl();
virtual void op_tm();
virtual void op_tml();
+ virtual void op_tr();
virtual void op_nop();
virtual void op_skmea();
diff --git a/src/devices/cpu/pps41/mm76op.cpp b/src/devices/cpu/pps41/mm76op.cpp
index b95944cbd37..65748638f47 100644
--- a/src/devices/cpu/pps41/mm76op.cpp
+++ b/src/devices/cpu/pps41/mm76op.cpp
@@ -33,11 +33,6 @@ void mm76_device::push_pc()
m_stack[0] = m_pc;
}
-void mm76_device::op_tr()
-{
- // TR x: prefix for extended opcode
-}
-
void mm76_device::op_illegal()
{
logerror("unknown opcode $%02X at $%03X\n", m_op, m_prev_pc);
@@ -352,6 +347,11 @@ void mm76_device::op_tml()
m_pc = (~m_prev_op & 0xf) << 6 | (~m_op & 0x3f);
}
+void mm76_device::op_tr()
+{
+ // TR x: prefix for extended opcode
+}
+
void mm76_device::op_nop()
{
// NOP: no operation
@@ -427,7 +427,7 @@ void mm76_device::op_i2c()
void mm76_device::op_int1h()
{
- // INT1H: skip on INT1
+ // INT1H: skip on INT1 high
m_skip = bool(m_int_line[1]);
}
@@ -440,7 +440,7 @@ void mm76_device::op_din1()
void mm76_device::op_int0l()
{
- // INT0L: skip on INT0
+ // INT0L: skip on INT0 low
m_skip = !m_int_line[0];
}
diff --git a/src/devices/cpu/pps41/mm78.cpp b/src/devices/cpu/pps41/mm78.cpp
index 62a013e33d3..3657799e3b4 100644
--- a/src/devices/cpu/pps41/mm78.cpp
+++ b/src/devices/cpu/pps41/mm78.cpp
@@ -106,4 +106,111 @@ void mm78_device::device_reset()
void mm78_device::execute_one()
{
+ if (op_is_tr(m_prev_op) && op_is_tr(m_prev2_op))
+ {
+ // 3-byte opcodes
+ switch (m_op & 0xf0)
+ {
+ case 0x80: case 0x90: case 0xa0: case 0xb0: op_tmlb(); break;
+ case 0xc0: case 0xd0: case 0xe0: case 0xf0: op_tlb(); break;
+
+ default: op_illegal(); break;
+ }
+ }
+ else if (op_is_tr(m_prev_op))
+ {
+ // 2-byte opcodes
+ switch (m_op & 0xf0)
+ {
+ case 0x30: op_tr(); break;
+ case 0x40: op_skbei(); break;
+ case 0x60:
+ if (m_op != 0x60)
+ op_skaei();
+ else
+ op_illegal();
+ break;
+
+ case 0x80: case 0x90: case 0xa0: case 0xb0: op_tml(); break;
+ case 0xc0: case 0xd0: case 0xe0: case 0xf0: op_tl(); break;
+
+ default: op_illegal(); break;
+ }
+ }
+ else
+ {
+ // standard opcodes
+ switch (m_op & 0xf0)
+ {
+ case 0x10: op_lb(); break;
+ case 0x30: op_tr(); break;
+ case 0x40: op_lai(); break;
+ case 0x60:
+ if (m_op != 0x60)
+ op_aisk();
+ else
+ op_i1sk();
+ break;
+
+ case 0x80: case 0x90: case 0xa0: case 0xb0: op_tm(); break;
+ case 0xc0: case 0xd0: case 0xe0: case 0xf0: op_t(); break;
+
+ default:
+ switch (m_op & 0xfc)
+ {
+ case 0x08: case 0x0c: op_eob(); break;
+ case 0x20: op_sb(); break;
+ case 0x24: op_rb(); break;
+ case 0x28: op_skbf(); break;
+ case 0x50: op_l(); break;
+ case 0x54: op_xnsk(); break;
+ case 0x58: op_xdsk(); break;
+ case 0x5c: op_x(); break;
+
+ default:
+ switch (m_op)
+ {
+ case 0x00: op_nop(); break;
+ case 0x01: op_skisl(); break;
+ case 0x02: op_sknc(); break;
+ case 0x03: op_int0h(); break;
+ case 0x04: op_int1l(); break;
+ case 0x05: op_rc(); break;
+ case 0x06: op_sc(); break;
+ case 0x07: op_sag(); break;
+
+ case 0x2c: break; // TAB
+ case 0x2d: op_ios(); break;
+ case 0x2e: op_rtsk(); break;
+ case 0x2f: op_rt(); break;
+
+ case 0x70: op_sos(); break;
+ case 0x71: op_ros(); break;
+ case 0x72: op_ix(); break;
+ case 0x73: op_ox(); break;
+ case 0x74: op_xas(); break;
+ case 0x75: op_lxa(); break;
+ case 0x76: op_lba(); break;
+ case 0x77: op_com(); break;
+ case 0x78: op_i2c(); break;
+ case 0x79: op_xax(); break;
+ case 0x7a: op_xab(); break;
+ case 0x7b: op_ioa(); break;
+ case 0x7c: op_ac(); break;
+ case 0x7d: op_acsk(); break;
+ case 0x7e: op_a(); break;
+ case 0x7f: op_skmea(); break;
+
+ default: op_illegal(); break; // won't happen
+ }
+ break; // 0xff
+
+ }
+ break; // 0xfc
+ }
+ }
+
+ // TAB is delayed by 1 cycle
+ if (m_prev_op == 0x2c)
+ op_tab();
}
diff --git a/src/devices/cpu/pps41/mm78.h b/src/devices/cpu/pps41/mm78.h
index a2262bacdec..c09bee4a0d6 100644
--- a/src/devices/cpu/pps41/mm78.h
+++ b/src/devices/cpu/pps41/mm78.h
@@ -69,6 +69,29 @@ protected:
virtual bool op_is_lai(u8 op) override { return (op & 0xf0) == 0x40; };
// opcode handlers
+ virtual void op_lba() override;
+ virtual void op_acsk() override;
+ virtual void op_aisk() override;
+ virtual void op_sb() override;
+ virtual void op_rb() override;
+ virtual void op_skbf() override;
+
+ virtual void op_sos();
+ virtual void op_ros();
+ virtual void op_skisl();
+
+ virtual void op_sag();
+ virtual void op_lxa();
+ virtual void op_xax();
+ virtual void op_tlb();
+ virtual void op_tmlb();
+ virtual void op_tab();
+ virtual void op_ix();
+ virtual void op_ox();
+ virtual void op_ioa();
+ virtual void op_i1sk();
+ virtual void op_int0h();
+ virtual void op_int1l();
};
class mm78l_device : public mm78_device
diff --git a/src/devices/cpu/pps41/mm78op.cpp b/src/devices/cpu/pps41/mm78op.cpp
index 35f9980b212..6b5ef774481 100644
--- a/src/devices/cpu/pps41/mm78op.cpp
+++ b/src/devices/cpu/pps41/mm78op.cpp
@@ -11,4 +11,142 @@
// changed opcodes
+void mm78_device::op_lba()
+{
+ // LBA: no RAM delay
+ mm76_device::op_lba();
+ m_ram_delay = false;
+}
+
+void mm78_device::op_acsk()
+{
+ // ACSK: skip logic is inverted
+ mm76_device::op_acsk();
+ m_skip = !m_skip;
+}
+
+void mm78_device::op_aisk()
+{
+ // AISK x: don't skip if x=6 (aka DC opcode)
+ mm76_device::op_aisk();
+ if ((m_op & 0xf) == 6)
+ m_skip = false;
+}
+
+void mm78_device::op_sb()
+{
+ // SB x: SB/SOS opcodes are separated
+ ram_w(ram_r() | (1 << (m_op & 3)));
+}
+
+void mm78_device::op_rb()
+{
+ // RB x: RB/ROS opcodes are separated
+ ram_w(ram_r() & ~(1 << (m_op & 3)));
+}
+
+void mm78_device::op_skbf()
+{
+ // SKBF x: SKBF/SKISL opcodes are separated
+ m_skip = !BIT(ram_r(), m_op & 3);
+}
+
+void mm78_device::op_sos()
+{
+ // SOS: SB/SOS opcodes are separated
+ op_todo();
+}
+
+void mm78_device::op_ros()
+{
+ // ROS: RB/ROS opcodes are separated
+ op_todo();
+}
+
+void mm78_device::op_skisl()
+{
+ // SKISL: SKBF/SKISL opcodes are separated
+ op_todo();
+}
+
+
// new opcodes
+
+void mm78_device::op_sag()
+{
+ // SAG: set Bu to 3 for the next cycle
+ m_sag = true;
+}
+
+void mm78_device::op_lxa()
+{
+ // LXA: load X from A
+ m_x = m_a;
+}
+
+void mm78_device::op_xax()
+{
+ // XAX: exchange A with X
+ u8 a = m_a;
+ m_a = m_x;
+ m_x = a;
+}
+
+void mm78_device::op_tlb()
+{
+ // TLB x: transfer long banked
+ op_tl();
+ m_pc |= 0x400;
+}
+
+void mm78_device::op_tmlb()
+{
+ // TMLB x: transfer and mark long banked
+ op_tml();
+ m_pc |= 0x400;
+}
+
+void mm78_device::op_tab()
+{
+ // TAB: table look up transfer
+ m_skip_count = m_a + 1;
+ m_a = 0xf;
+}
+
+void mm78_device::op_ix()
+{
+ // IX: input to X from channel X(aka B)
+ op_todo();
+}
+
+void mm78_device::op_ox()
+{
+ // OX: output from X to channel X(aka B)
+ op_todo();
+}
+
+void mm78_device::op_ioa()
+{
+ // IOA: exchange A with channel A
+ op_todo();
+}
+
+void mm78_device::op_i1sk()
+{
+ // I1SK: add channel 1 to A, skip on no overflow
+ m_a += m_read_p() & 0xf;
+ m_skip = !(m_a & 0x10);
+ m_a &= 0xf;
+}
+
+void mm78_device::op_int0h()
+{
+ // INT0H: skip on INT0 high
+ m_skip = bool(m_int_line[0]);
+}
+
+void mm78_device::op_int1l()
+{
+ // INT1L: skip on INT1 low
+ m_skip = !m_int_line[1];
+}
diff --git a/src/devices/cpu/pps41/pps41base.cpp b/src/devices/cpu/pps41/pps41base.cpp
index 74352464aab..9fdc784c74b 100644
--- a/src/devices/cpu/pps41/pps41base.cpp
+++ b/src/devices/cpu/pps41/pps41base.cpp
@@ -38,9 +38,10 @@ TODO:
but again does not explain why
- documentation is conflicting whether or not MM76/MM75 can (re)set interrupt flip-
flops with SOS/ROS opcodes
+- allowed opcodes after TAB should be limited
- add MCU mask options, there's one for inverting interrupts
- add serial i/o
-- add MM78 opcodes
+- finish MM78 opcodes
- add MM78LA
*/