summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/sh/sh_sci.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/sh/sh_sci.h')
-rw-r--r--src/devices/cpu/sh/sh_sci.h151
1 files changed, 151 insertions, 0 deletions
diff --git a/src/devices/cpu/sh/sh_sci.h b/src/devices/cpu/sh/sh_sci.h
new file mode 100644
index 00000000000..3c36a346254
--- /dev/null
+++ b/src/devices/cpu/sh/sh_sci.h
@@ -0,0 +1,151 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+/***************************************************************************
+
+ sh_sci.h
+
+ SH Serial Communications Interface
+
+
+***************************************************************************/
+
+#ifndef MAME_CPU_SH_SH_SCI_H
+#define MAME_CPU_SH_SH_SCI_H
+
+#pragma once
+
+class sh7042_device;
+class sh_intc_device;
+
+class sh_sci_device : public device_t {
+public:
+ sh_sci_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+ template<typename T, typename U> sh_sci_device(const machine_config &mconfig, const char *tag, device_t *owner, int id, T &&cpu, U &&intc, int eri, int rxi, int txi, int tei)
+ : sh_sci_device(mconfig, tag, owner, 0)
+ {
+ m_cpu.set_tag(std::forward<T>(cpu));
+ m_intc.set_tag(std::forward<U>(intc));
+ m_id = id;
+ m_eri_int = eri;
+ m_rxi_int = rxi;
+ m_txi_int = txi;
+ m_tei_int = tei;
+ }
+
+ void do_set_external_clock_period(const attotime &_period);
+
+ void smr_w(u8 data);
+ u8 smr_r();
+ void brr_w(u8 data);
+ u8 brr_r();
+ void scr_w(u8 data);
+ u8 scr_r();
+ void tdr_w(u8 data);
+ u8 tdr_r();
+ void ssr_w(u8 data);
+ u8 ssr_r();
+ u8 rdr_r();
+ void scmr_w(u8 data);
+ u8 scmr_r();
+
+ void do_rx_w(int state);
+ void do_clk_w(int state);
+
+ u64 internal_update(u64 current_time);
+
+protected:
+ enum {
+ ST_IDLE, ST_START, ST_BIT, ST_PARITY, ST_STOP, ST_LAST_TICK
+ };
+
+ static const char *const state_names[];
+
+ enum {
+ CLK_TX = 1,
+ CLK_RX = 2
+ };
+
+ enum {
+ INTERNAL_ASYNC,
+ INTERNAL_ASYNC_OUT,
+ EXTERNAL_ASYNC,
+ EXTERNAL_RATE_ASYNC,
+ INTERNAL_SYNC_OUT,
+ EXTERNAL_SYNC,
+ EXTERNAL_RATE_SYNC
+ };
+
+ enum {
+ SMR_CA = 0x80,
+ SMR_CHR = 0x40,
+ SMR_PE = 0x20,
+ SMR_OE = 0x10,
+ SMR_STOP = 0x08,
+ SMR_MP = 0x04,
+ SMR_CKS = 0x03,
+
+ SCR_TIE = 0x80,
+ SCR_RIE = 0x40,
+ SCR_TE = 0x20,
+ SCR_RE = 0x10,
+ SCR_MPIE = 0x08,
+ SCR_TEIE = 0x04,
+ SCR_CKE = 0x03,
+ SCR_CKE1 = 0x02,
+ SCR_CKE0 = 0x01,
+
+ SSR_TDRE = 0x80,
+ SSR_RDRF = 0x40,
+ SSR_ORER = 0x20,
+ SSR_FER = 0x10,
+ SSR_PER = 0x08,
+ SSR_TEND = 0x04,
+ SSR_MPB = 0x02,
+ SSR_MPBT = 0x01
+ };
+
+ required_device<sh7042_device> m_cpu;
+ required_device<sh_intc_device> m_intc;
+ attotime m_external_clock_period;
+ double m_external_to_internal_ratio, m_internal_to_external_ratio;
+
+ int m_id, m_eri_int, m_rxi_int, m_txi_int, m_tei_int;
+
+ int m_tx_state, m_rx_state, m_tx_bit, m_rx_bit, m_clock_state, m_tx_parity, m_rx_parity, m_tx_clock_counter, m_rx_clock_counter;
+ u32 m_clock_mode;
+ bool m_ext_clock_value, m_rx_value;
+
+ u8 m_rdr, m_tdr, m_smr, m_scr, m_ssr, m_brr, m_rsr, m_tsr;
+ u64 m_clock_event, m_clock_step, m_divider;
+
+ std::string m_last_clock_message;
+
+ void device_start() override ATTR_COLD;
+ void device_reset() override ATTR_COLD;
+
+ TIMER_CALLBACK_MEMBER(sync_tick);
+
+ void clock_start(int mode);
+ void clock_stop(int mode);
+ void clock_update();
+
+ void tx_start();
+ void tx_async_tick();
+ void tx_async_step();
+ void tx_sync_tick();
+ void tx_sync_step();
+
+ void rx_start();
+ void rx_done();
+ void rx_async_tick();
+ void rx_async_step();
+ void rx_sync_tick();
+ void rx_sync_step();
+
+ bool is_sync_start() const;
+ bool has_recv_error() const;
+};
+
+DECLARE_DEVICE_TYPE(SH_SCI, sh_sci_device)
+
+#endif // MAME_CPU_SH_SH_SCI_H