diff options
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 |
commit | efe9ac40f685ecdaf55c65d4923222b5661860e6 (patch) | |
tree | 6a5d4b624da8c05229702cb430259eb60278916a | |
parent | fa467244bf7fb4a1adb8aa8ea4f2db7b3501d8f8 (diff) |
pps41: add serial i/o
-rw-r--r-- | src/devices/cpu/pps41/mm75.h | 3 | ||||
-rw-r--r-- | src/devices/cpu/pps41/mm76op.cpp | 4 | ||||
-rw-r--r-- | src/devices/cpu/pps41/pps41base.cpp | 54 | ||||
-rw-r--r-- | src/devices/cpu/pps41/pps41base.h | 19 |
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; |