diff --git a/.gitattributes b/.gitattributes index b7a6d6ced97..71ac0b15744 100644 --- a/.gitattributes +++ b/.gitattributes @@ -821,6 +821,8 @@ src/emu/machine/mb87078.c svneol=native#text/plain src/emu/machine/mb87078.h svneol=native#text/plain src/emu/machine/mc146818.c svneol=native#text/plain src/emu/machine/mc146818.h svneol=native#text/plain +src/emu/machine/mc6852.c svneol=native#text/plain +src/emu/machine/mc6852.h svneol=native#text/plain src/emu/machine/mc68901.c svneol=native#text/plain src/emu/machine/mc68901.h svneol=native#text/plain src/emu/machine/microtch.c svneol=native#text/plain diff --git a/src/emu/emu.mak b/src/emu/emu.mak index 5619a125470..0cd5b4ad9eb 100644 --- a/src/emu/emu.mak +++ b/src/emu/emu.mak @@ -188,6 +188,7 @@ EMUMACHINEOBJS = \ $(EMUMACHINE)/mb3773.o \ $(EMUMACHINE)/mb87078.o \ $(EMUMACHINE)/mc146818.o \ + $(EMUMACHINE)/mc6852.o \ $(EMUMACHINE)/mc68901.o \ $(EMUMACHINE)/microtch.o \ $(EMUMACHINE)/msm6242.o \ diff --git a/src/emu/machine/mc6852.c b/src/emu/machine/mc6852.c new file mode 100644 index 00000000000..ee4967b1b3e --- /dev/null +++ b/src/emu/machine/mc6852.c @@ -0,0 +1,385 @@ +/********************************************************************** + + 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" + + + +//************************************************************************** +// 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 + + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +// devices +const device_type MC6852 = mc6852_device_config::static_alloc_device_config; + + + +//************************************************************************** +// DEVICE CONFIGURATION +//************************************************************************** + +GENERIC_DEVICE_CONFIG_SETUP(mc6852, "MC6852") + + +//------------------------------------------------- +// device_config_complete - perform any +// operations now that the configuration is +// complete +//------------------------------------------------- + +void mc6852_device_config::device_config_complete() +{ + // inherit a copy of the static data + const mc6852_interface *intf = reinterpret_cast(static_config()); + if (intf != NULL) + *static_cast(this) = *intf; + + // or initialize to defaults if none provided + else + { + memset(&m_in_rx_data_func, 0, sizeof(m_in_rx_data_func)); + memset(&m_out_tx_data_func, 0, sizeof(m_out_tx_data_func)); + memset(&m_out_irq_func, 0, sizeof(m_out_irq_func)); + memset(&m_in_cts_func, 0, sizeof(m_in_cts_func)); + memset(&m_in_dcd_func, 0, sizeof(m_in_dcd_func)); + memset(&m_out_sm_dtr_func, 0, sizeof(m_out_sm_dtr_func)); + memset(&m_out_tuf_func, 0, sizeof(m_out_tuf_func)); + } +} + + + +//************************************************************************** +// INLINE HELPERS +//************************************************************************** + +inline void mc6852_device::receive() +{ +} + +inline void mc6852_device::transmit() +{ +} + + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// mc6852_device - constructor +//------------------------------------------------- + +mc6852_device::mc6852_device(running_machine &_machine, const mc6852_device_config &config) + : device_t(_machine, config), + m_config(config) +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void mc6852_device::device_start() +{ + // resolve callbacks + devcb_resolve_read_line(&m_in_rx_data_func, &m_config.m_in_rx_data_func, this); + devcb_resolve_write_line(&m_out_tx_data_func, &m_config.m_out_tx_data_func, this); + devcb_resolve_write_line(&m_out_irq_func, &m_config.m_out_irq_func, this); + devcb_resolve_read_line(&m_in_cts_func, &m_config.m_in_cts_func, this); + devcb_resolve_read_line(&m_in_dcd_func, &m_config.m_in_dcd_func, this); + devcb_resolve_write_line(&m_out_sm_dtr_func, &m_config.m_out_sm_dtr_func, this); + devcb_resolve_write_line(&m_out_tuf_func, &m_config.m_out_tuf_func, this); + + if (m_config.m_rx_clock > 0) + { + m_rx_timer = timer_alloc(TIMER_RX); + m_rx_timer->adjust(attotime::zero, 0, attotime::from_hz(m_config.m_rx_clock)); + } + + if (m_config.m_tx_clock > 0) + { + m_tx_timer = timer_alloc(TIMER_TX); + m_tx_timer->adjust(attotime::zero, 0, attotime::from_hz(m_config.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; +} diff --git a/src/emu/machine/mc6852.h b/src/emu/machine/mc6852.h new file mode 100644 index 00000000000..097e01d9303 --- /dev/null +++ b/src/emu/machine/mc6852.h @@ -0,0 +1,164 @@ +/********************************************************************** + + Motorola MC6852 Synchronous Serial Data Adapter emulation + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +********************************************************************** + _____ _____ + Vss 1 |* \_/ | 24 _CTS + Rx DATA 2 | | 23 _DCD + Rx CLK 3 | | 22 D0 + Tx CLK 4 | | 21 D1 + SM/_DTR 5 | | 20 D2 + Tx DATA 6 | MC6852 | 19 D3 + _IRQ 7 | | 18 D4 + TUF 8 | | 17 D5 + _RESET 9 | | 16 D6 + _CS 9 | | 15 D7 + RS 9 | | 14 E + Vcc 10 |_____________| 13 R/_W + +**********************************************************************/ + +#pragma once + +#ifndef __MC6852__ +#define __MC6852__ + +#include "emu.h" + + + +//************************************************************************** +// INTERFACE CONFIGURATION MACROS +//************************************************************************** + +#define MCFG_MC6852_ADD(_tag, _clock, _config) \ + MCFG_DEVICE_ADD((_tag), MC6852, _clock) \ + MCFG_DEVICE_CONFIG(_config) + +#define MC6852_INTERFACE(name) \ + const mc6852_interface (name) = + + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> mc6852_interface + +struct mc6852_interface +{ + UINT32 m_rx_clock; + UINT32 m_tx_clock; + + devcb_read_line m_in_rx_data_func; + devcb_write_line m_out_tx_data_func; + + devcb_write_line m_out_irq_func; + + devcb_read_line m_in_cts_func; + devcb_read_line m_in_dcd_func; + devcb_write_line m_out_sm_dtr_func; + devcb_write_line m_out_tuf_func; +}; + + + +// ======================> mc6852_device_config + +class mc6852_device_config : public device_config, + public mc6852_interface +{ + friend class mc6852_device; + + // construction/destruction + mc6852_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock); + +public: + // allocators + static device_config *static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock); + virtual device_t *alloc_device(running_machine &machine) const; + +protected: + // device_config overrides + virtual void device_config_complete(); +}; + + + +// ======================> mc6852_device + +class mc6852_device : public device_t +{ + friend class mc6852_device_config; + + // construction/destruction + mc6852_device(running_machine &_machine, const mc6852_device_config &_config); + +public: + DECLARE_READ8_MEMBER( read ); + DECLARE_WRITE8_MEMBER( write ); + + DECLARE_WRITE_LINE_MEMBER( rx_clk_w ); + DECLARE_WRITE_LINE_MEMBER( tx_clk_w ); + DECLARE_WRITE_LINE_MEMBER( cts_w ); + DECLARE_WRITE_LINE_MEMBER( dcd_w ); + + DECLARE_READ_LINE_MEMBER( sm_dtr_r ); + DECLARE_READ_LINE_MEMBER( tuf_r ); + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + virtual void device_timer(emu_timer &timer, device_timer_id id, int m_param, void *ptr); + +private: + static const device_timer_id TIMER_RX = 0; + static const device_timer_id TIMER_TX = 1; + + inline void receive(); + inline void transmit(); + + devcb_resolved_read_line m_in_rx_data_func; + devcb_resolved_write_line m_out_tx_data_func; + devcb_resolved_write_line m_out_irq_func; + devcb_resolved_read_line m_in_cts_func; + devcb_resolved_read_line m_in_dcd_func; + devcb_resolved_write_line m_out_sm_dtr_func; + devcb_resolved_write_line m_out_tuf_func; + + // registers + UINT8 m_status; // status register + UINT8 m_cr[3]; // control registers + UINT8 m_scr; // sync code register + UINT8 m_rx_fifo[3]; // receiver FIFO + UINT8 m_tx_fifo[3]; // transmitter FIFO + UINT8 m_tdr; // transmit data register + UINT8 m_tsr; // transmit shift register + UINT8 m_rdr; // receive data register + UINT8 m_rsr; // receive shift register + + int m_cts; // clear to send + int m_dcd; // data carrier detect + int m_sm_dtr; // sync match/data terminal ready + int m_tuf; // transmitter underflow + + // timers + emu_timer *m_rx_timer; + emu_timer *m_tx_timer; + + const mc6852_device_config &m_config; +}; + + +// device type definition +extern const device_type MC6852; + + + +#endif