summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author hap <happppp@users.noreply.github.com>2021-03-09 18:06:04 +0100
committer hap <happppp@users.noreply.github.com>2021-03-09 18:06:04 +0100
commitefe9ac40f685ecdaf55c65d4923222b5661860e6 (patch)
tree6a5d4b624da8c05229702cb430259eb60278916a
parentfa467244bf7fb4a1adb8aa8ea4f2db7b3501d8f8 (diff)
pps41: add serial i/o
-rw-r--r--src/devices/cpu/pps41/mm75.h3
-rw-r--r--src/devices/cpu/pps41/mm76op.cpp4
-rw-r--r--src/devices/cpu/pps41/pps41base.cpp54
-rw-r--r--src/devices/cpu/pps41/pps41base.h19
4 files changed, 71 insertions, 9 deletions
diff --git a/src/devices/cpu/pps41/mm75.h b/src/devices/cpu/pps41/mm75.h
index 39a14245cae..669225ca8c5 100644
--- a/src/devices/cpu/pps41/mm75.h
+++ b/src/devices/cpu/pps41/mm75.h
@@ -42,6 +42,9 @@ public:
protected:
virtual void device_start() override;
+ virtual u32 execute_input_lines() const noexcept override { return 2; }
+ virtual void execute_set_input(int line, int state) override { if (line < 2) mm76_device::execute_set_input(line, state); }
+
// opcode handlers
virtual void op_ios() override;
virtual void op_i2c() override;
diff --git a/src/devices/cpu/pps41/mm76op.cpp b/src/devices/cpu/pps41/mm76op.cpp
index cd674ef1176..f01dfc77fbf 100644
--- a/src/devices/cpu/pps41/mm76op.cpp
+++ b/src/devices/cpu/pps41/mm76op.cpp
@@ -175,12 +175,14 @@ void mm76_device::op_xas()
u8 a = m_a;
m_a = m_s;
m_s = a;
+ m_write_sdo(BIT(m_s, 3));
}
void mm76_device::op_lsa()
{
// LSA: load S from A
m_s = m_a;
+ m_write_sdo(BIT(m_s, 3));
}
@@ -413,7 +415,7 @@ void mm76_device::op_oa()
void mm76_device::op_ios()
{
// IOS: start serial I/O
- op_todo();
+ m_sclock_count = 8;
}
void mm76_device::op_i1()
diff --git a/src/devices/cpu/pps41/pps41base.cpp b/src/devices/cpu/pps41/pps41base.cpp
index 9c9786403c0..7250383e664 100644
--- a/src/devices/cpu/pps41/pps41base.cpp
+++ b/src/devices/cpu/pps41/pps41base.cpp
@@ -40,7 +40,6 @@ TODO:
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 MM78LA
*/
@@ -62,7 +61,9 @@ pps41_base_device::pps41_base_device(const machine_config &mconfig, device_type
m_read_d(*this),
m_write_d(*this),
m_read_r(*this),
- m_write_r(*this)
+ m_write_r(*this),
+ m_write_sdo(*this),
+ m_write_ssc(*this)
{ }
@@ -83,6 +84,8 @@ void pps41_base_device::device_start()
m_write_d.resolve_safe();
m_read_r.resolve_safe(0xff);
m_write_r.resolve_safe();
+ m_write_sdo.resolve_safe();
+ m_write_ssc.resolve_safe();
// init RAM with 0xf
for (int i = 0; i <= m_datamask; i++)
@@ -108,16 +111,21 @@ void pps41_base_device::device_start()
m_prev_c = 0;
m_c_in = 0;
m_c_delay = false;
- m_s = 0;
m_x = 0;
m_skip = false;
m_skip_count = 0;
+ m_s = 0;
+ m_sdi = 0;
+ m_sclock_in = 0;
+ m_sclock_count = 0;
+ m_ss_pending = false;
+
m_d_pins = 10;
m_d_mask = (1 << m_d_pins) - 1;
m_d_output = 0;
m_r_output = 0;
- m_int_line[0] = m_int_line[1] = 1;
+ m_int_line[0] = m_int_line[1] = 0;
m_int_ff[0] = m_int_ff[1] = 0;
// register for savestates
@@ -140,11 +148,16 @@ void pps41_base_device::device_start()
save_item(NAME(m_prev_c));
save_item(NAME(m_c_in));
save_item(NAME(m_c_delay));
- save_item(NAME(m_s));
save_item(NAME(m_x));
save_item(NAME(m_skip));
save_item(NAME(m_skip_count));
+ save_item(NAME(m_s));
+ save_item(NAME(m_sdi));
+ save_item(NAME(m_sclock_in));
+ save_item(NAME(m_sclock_count));
+ save_item(NAME(m_ss_pending));
+
save_item(NAME(m_d_output));
save_item(NAME(m_r_output));
save_item(NAME(m_int_line));
@@ -187,6 +200,11 @@ void pps41_base_device::device_reset()
// clear outputs
m_write_r(m_r_output = 0xff);
m_write_d(m_d_output = 0);
+
+ m_s = 0;
+ m_sclock_count = 0;
+ m_write_sdo(0);
+ m_write_ssc(0);
}
@@ -214,6 +232,17 @@ void pps41_base_device::execute_set_input(int line, int state)
m_int_line[1] = state;
break;
+ case PPS41_INPUT_LINE_SDI:
+ m_sdi = state;
+ break;
+
+ case PPS41_INPUT_LINE_SSC:
+ // serial shift pending on falling edge
+ if (!state && m_sclock_in)
+ m_ss_pending = true;
+ m_sclock_in = state;
+ break;
+
default:
break;
}
@@ -227,6 +256,21 @@ void pps41_base_device::execute_set_input(int line, int state)
void pps41_base_device::cycle()
{
m_icount--;
+
+ // clock serial i/o
+ m_ss_pending = m_ss_pending || bool(m_sclock_count & 1);
+
+ if (m_sclock_count)
+ {
+ m_sclock_count--;
+ m_write_ssc(m_sclock_count & 1);
+ }
+ if (m_ss_pending)
+ {
+ m_ss_pending = false;
+ m_s = (m_s << 1 | m_sdi) & 0xf;
+ m_write_sdo(BIT(m_s, 3));
+ }
}
void pps41_base_device::increment_pc()
diff --git a/src/devices/cpu/pps41/pps41base.h b/src/devices/cpu/pps41/pps41base.h
index e5f8029a4ac..ce60c6692ce 100644
--- a/src/devices/cpu/pps41/pps41base.h
+++ b/src/devices/cpu/pps41/pps41base.h
@@ -16,7 +16,9 @@
enum
{
PPS41_INPUT_LINE_INT0 = 0,
- PPS41_INPUT_LINE_INT1
+ PPS41_INPUT_LINE_INT1,
+ PPS41_INPUT_LINE_SDI, // serial data input
+ PPS41_INPUT_LINE_SSC // serial shift clock
};
@@ -37,6 +39,10 @@ public:
auto read_r() { return m_read_r.bind(); }
auto write_r() { return m_write_r.bind(); }
+ // serial data/clock
+ auto write_sdo() { return m_write_sdo.bind(); }
+ auto write_ssc() { return m_write_ssc.bind(); }
+
protected:
// construction/destruction
pps41_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data);
@@ -48,7 +54,7 @@ protected:
// device_execute_interface overrides
virtual u32 execute_min_cycles() const noexcept override { return 1; }
virtual u32 execute_max_cycles() const noexcept override { return 2; }
- virtual u32 execute_input_lines() const noexcept override { return 2; }
+ virtual u32 execute_input_lines() const noexcept override { return 4; }
virtual void execute_set_input(int line, int state) override;
virtual void execute_run() override;
virtual void execute_one() = 0;
@@ -78,6 +84,8 @@ protected:
devcb_write16 m_write_d;
devcb_read8 m_read_r;
devcb_write8 m_write_r;
+ devcb_write_line m_write_sdo;
+ devcb_write_line m_write_ssc;
// internal state, regs
u16 m_pc;
@@ -100,11 +108,16 @@ protected:
int m_prev_c;
int m_c_in;
bool m_c_delay;
- u8 m_s;
u8 m_x;
bool m_skip;
int m_skip_count;
+ u8 m_s;
+ int m_sdi;
+ int m_sclock_in;
+ int m_sclock_count;
+ bool m_ss_pending;
+
int m_d_pins;
u16 m_d_mask;
u16 m_d_output;