summaryrefslogtreecommitdiffstatshomepage
path: root/trunk/src/emu/machine/mc6852.c
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/emu/machine/mc6852.c')
-rw-r--r--trunk/src/emu/machine/mc6852.c370
1 files changed, 370 insertions, 0 deletions
diff --git a/trunk/src/emu/machine/mc6852.c b/trunk/src/emu/machine/mc6852.c
new file mode 100644
index 00000000000..47c02acaa2a
--- /dev/null
+++ b/trunk/src/emu/machine/mc6852.c
@@ -0,0 +1,370 @@
+/**********************************************************************
+
+ Motorola MC6852 Synchronous Serial Data Adapter emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+/*
+
+ TODO:
+
+ - FIFO
+ - receive
+ - transmit
+ - parity
+ - 1-sync-character mode
+ - 2-sync-character mode
+ - external sync mode
+ - interrupts
+
+*/
+
+#include "emu.h"
+#include "mc6852.h"
+#include "machine/devhelpr.h"
+
+
+// device type definition
+const device_type MC6852 = &device_creator<mc6852_device>;
+
+
+//**************************************************************************
+// MACROS / CONSTANTS
+//**************************************************************************
+
+#define LOG 0
+
+
+#define S_RDA 0x01
+#define S_TDRA 0x02
+#define S_DCD 0x04
+#define S_CTS 0x08
+#define S_TUF 0x10
+#define S_RX_OVRN 0x20
+#define S_PE 0x40
+#define S_IRQ 0x80
+
+
+#define C1_RX_RS 0x01
+#define C1_TX_RS 0x02
+#define C1_STRIP_SYNC 0x04
+#define C1_CLEAR_SYNC 0x08
+#define C1_TIE 0x10
+#define C1_RIE 0x20
+#define C1_AC_MASK 0xc0
+#define C1_AC_C2 0x00
+#define C1_AC_C3 0x40
+#define C1_AC_SYNC 0x80
+#define C1_AC_TX_FIFO 0xc0
+
+
+#define C2_PC1 0x01
+#define C2_PC2 0x02
+#define C2_1_2_BYTE 0x04
+#define C2_WS_MASK 0x38
+#define C2_WS_6_E 0x00
+#define C2_WS_6_O 0x08
+#define C2_WS_7 0x10
+#define C2_WS_8 0x18
+#define C2_WS_7_E 0x20
+#define C2_WS_7_O 0x28
+#define C2_WS_8_E 0x30
+#define C2_WS_8_O 0x38
+#define C2_TX_SYNC 0x40
+#define C2_EIE 0x80
+
+
+#define C3_E_I_SYNC 0x01
+#define C3_1_2_SYNC 0x02
+#define C3_CLEAR_CTS 0x04
+#define C3_CTUF 0x08
+
+
+//**************************************************************************
+// INLINE HELPERS
+//**************************************************************************
+
+inline void mc6852_device::receive()
+{
+}
+
+inline void mc6852_device::transmit()
+{
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// mc6852_device - constructor
+//-------------------------------------------------
+
+mc6852_device::mc6852_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, MC6852, "MC6852", tag, owner, clock)
+{
+}
+
+
+//-------------------------------------------------
+// device_config_complete - perform any
+// operations now that the configuration is
+// complete
+//-------------------------------------------------
+
+void mc6852_device::device_config_complete()
+{
+ // inherit a copy of the static data
+ const mc6852_interface *intf = reinterpret_cast<const mc6852_interface *>(static_config());
+ if (intf != NULL)
+ *static_cast<mc6852_interface *>(this) = *intf;
+
+ // or initialize to defaults if none provided
+ else
+ {
+ memset(&m_in_rx_data_cb, 0, sizeof(m_in_rx_data_cb));
+ memset(&m_out_tx_data_cb, 0, sizeof(m_out_tx_data_cb));
+ memset(&m_out_irq_cb, 0, sizeof(m_out_irq_cb));
+ memset(&m_in_cts_cb, 0, sizeof(m_in_cts_cb));
+ memset(&m_in_dcd_cb, 0, sizeof(m_in_dcd_cb));
+ memset(&m_out_sm_dtr_cb, 0, sizeof(m_out_sm_dtr_cb));
+ memset(&m_out_tuf_cb, 0, sizeof(m_out_tuf_cb));
+ }
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void mc6852_device::device_start()
+{
+ // resolve callbacks
+ m_in_rx_data_func.resolve(m_in_rx_data_cb, *this);
+ m_out_tx_data_func.resolve(m_out_tx_data_cb, *this);
+ m_out_irq_func.resolve(m_out_irq_cb, *this);
+ m_in_cts_func.resolve(m_in_cts_cb, *this);
+ m_in_dcd_func.resolve(m_in_dcd_cb, *this);
+ m_out_sm_dtr_func.resolve(m_out_sm_dtr_cb, *this);
+ m_out_tuf_func.resolve(m_out_tuf_cb, *this);
+
+ if (m_rx_clock > 0)
+ {
+ m_rx_timer = timer_alloc(TIMER_RX);
+ m_rx_timer->adjust(attotime::zero, 0, attotime::from_hz(m_rx_clock));
+ }
+
+ if (m_tx_clock > 0)
+ {
+ m_tx_timer = timer_alloc(TIMER_TX);
+ m_tx_timer->adjust(attotime::zero, 0, attotime::from_hz(m_tx_clock));
+ }
+
+ // register for state saving
+ save_item(NAME(m_status));
+ save_item(NAME(m_cr));
+ save_item(NAME(m_scr));
+ save_item(NAME(m_rx_fifo));
+ save_item(NAME(m_tx_fifo));
+ save_item(NAME(m_tdr));
+ save_item(NAME(m_tsr));
+ save_item(NAME(m_rdr));
+ save_item(NAME(m_rsr));
+ save_item(NAME(m_cts));
+ save_item(NAME(m_dcd));
+ save_item(NAME(m_sm_dtr));
+ save_item(NAME(m_tuf));
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void mc6852_device::device_reset()
+{
+ /* set receiver shift register to all 1's */
+ m_rsr = 0xff;
+
+ /* reset and inhibit receiver/transmitter sections */
+ m_cr[0] |= (C1_TX_RS | C1_RX_RS);
+}
+
+
+//-------------------------------------------------
+// device_timer - handler timer events
+//-------------------------------------------------
+
+void mc6852_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+{
+ switch (id)
+ {
+ case TIMER_RX:
+ receive();
+ break;
+
+ case TIMER_TX:
+ transmit();
+ break;
+ }
+}
+
+
+//-------------------------------------------------
+// read -
+//-------------------------------------------------
+
+READ8_MEMBER( mc6852_device::read )
+{
+ UINT8 data = 0;
+
+ if (BIT(offset, 0))
+ {
+ /* receive data FIFO */
+ }
+ else
+ {
+ /* status */
+ data = m_status;
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// write -
+//-------------------------------------------------
+
+WRITE8_MEMBER( mc6852_device::write )
+{
+ if (BIT(offset, 0))
+ {
+ switch (m_cr[0] & C1_AC_MASK)
+ {
+ case C1_AC_C2:
+ /* control 2 */
+ m_cr[1] = data;
+ break;
+
+ case C1_AC_C3:
+ /* control 3 */
+ m_cr[2] = data;
+ break;
+
+ case C1_AC_SYNC:
+ /* sync code */
+ m_scr = data;
+ break;
+
+ case C1_AC_TX_FIFO:
+ /* transmit data FIFO */
+ break;
+ }
+ }
+ else
+ {
+ /* receiver reset */
+ if (data & C1_RX_RS)
+ {
+ /* When Rx Rs is set, it clears the receiver
+ control logic, sync logic, error logic, Rx Data FIFO Control,
+ Parity Error status bit, and DCD interrupt. The Receiver Shift
+ Register is set to ones.
+ */
+
+ if (LOG) logerror("MC6852 '%s' Receiver Reset\n", tag());
+
+ m_status &= ~(S_RX_OVRN | S_PE | S_DCD | S_RDA);
+ m_rsr = 0xff;
+ }
+
+ /* transmitter reset */
+ if (data & C1_TX_RS)
+ {
+ /* When Tx Rs is set, it clears the transmitter
+ control section, Transmitter Shift Register, Tx Data FIFO
+ Control (the Tx Data FIFO can be reloaded after one E clock
+ pulse), the Transmitter Underflow status bit, and the CTS interrupt,
+ and inhibits the TDRA status bit (in the one-sync-character
+ and two-sync-character modes).*/
+
+ if (LOG) logerror("MC6852 '%s' Transmitter Reset\n", tag());
+
+ m_status &= ~(S_TUF | S_CTS | S_TDRA);
+ }
+
+ if (LOG)
+ {
+ if (data & C1_STRIP_SYNC) logerror("MC6852 '%s' Strip Synchronization Characters\n", tag());
+ if (data & C1_CLEAR_SYNC) logerror("MC6852 '%s' Clear Synchronization\n", tag());
+ }
+
+ m_cr[0] = data;
+ }
+}
+
+
+//-------------------------------------------------
+// rx_clk_w -
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( mc6852_device::rx_clk_w )
+{
+ if (state) receive();
+}
+
+
+//-------------------------------------------------
+// tx_clk_w -
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( mc6852_device::tx_clk_w )
+{
+ if (state) transmit();
+}
+
+
+//-------------------------------------------------
+// cts_w -
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( mc6852_device::cts_w )
+{
+ m_cts = state;
+}
+
+
+//-------------------------------------------------
+// dcd_w -
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( mc6852_device::dcd_w )
+{
+ m_dcd = state;
+}
+
+
+//-------------------------------------------------
+// sm_dtr_r -
+//-------------------------------------------------
+
+READ_LINE_MEMBER( mc6852_device::sm_dtr_r )
+{
+ return m_sm_dtr;
+}
+
+
+//-------------------------------------------------
+// tuf_r -
+//-------------------------------------------------
+
+READ_LINE_MEMBER( mc6852_device::tuf_r )
+{
+ return m_tuf;
+}