summaryrefslogtreecommitdiffstatshomepage
path: root/trunk/src/emu/machine/z80sio.h
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/emu/machine/z80sio.h')
-rw-r--r--trunk/src/emu/machine/z80sio.h174
1 files changed, 174 insertions, 0 deletions
diff --git a/trunk/src/emu/machine/z80sio.h b/trunk/src/emu/machine/z80sio.h
new file mode 100644
index 00000000000..c1141251036
--- /dev/null
+++ b/trunk/src/emu/machine/z80sio.h
@@ -0,0 +1,174 @@
+/***************************************************************************
+
+ Z80 SIO (Z8440) implementation
+
+ Copyright Nicola Salmoria and the MAME Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+***************************************************************************/
+
+#ifndef __Z80SIO_H__
+#define __Z80SIO_H__
+
+#include "cpu/z80/z80daisy.h"
+
+
+//**************************************************************************
+// DEVICE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_Z80SIO_ADD(_tag, _clock, _intrf) \
+ MCFG_DEVICE_ADD(_tag, Z80SIO, _clock) \
+ MCFG_DEVICE_CONFIG(_intrf)
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+
+// ======================> z80sio_interface
+
+struct z80sio_interface
+{
+ void (*m_irq_cb)(device_t *device, int state);
+ write8_device_func m_dtr_changed_cb;
+ write8_device_func m_rts_changed_cb;
+ write8_device_func m_break_changed_cb;
+ write8_device_func m_transmit_cb;
+ int (*m_receive_poll_cb)(device_t *device, int channel);
+};
+
+
+
+// ======================> z80sio_device
+
+class z80sio_device : public device_t,
+ public device_z80daisy_interface,
+ public z80sio_interface
+{
+public:
+ // construction/destruction
+ z80sio_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // control register I/O
+ UINT8 control_read(int ch) { return m_channel[ch].control_read(); }
+ void control_write(int ch, UINT8 data) { m_channel[ch].control_write(data); }
+
+ // data register I/O
+ UINT8 data_read(int ch) { return m_channel[ch].data_read(); }
+ void data_write(int ch, UINT8 data) { m_channel[ch].data_write(data); }
+
+ // communication line I/O
+ int dtr(int ch) { return m_channel[ch].dtr(); }
+ int rts(int ch) { return m_channel[ch].rts(); }
+ void set_cts(int ch, int state) { m_channel[ch].set_cts(state); }
+ void set_dcd(int ch, int state) { m_channel[ch].set_dcd(state); }
+ void receive_data(int ch, int data) { m_channel[ch].receive_data(data); }
+
+private:
+ // device-level overrides
+ virtual void device_config_complete();
+ virtual void device_start();
+ virtual void device_reset();
+
+ // device_z80daisy_interface overrides
+ virtual int z80daisy_irq_state();
+ virtual int z80daisy_irq_ack();
+ virtual void z80daisy_irq_reti();
+
+ // internal helpers
+ void update_interrupt_state();
+
+ // a single SIO channel
+ class sio_channel
+ {
+ public:
+ sio_channel();
+
+ void start(z80sio_device *device, int index);
+ void reset();
+
+ UINT8 control_read();
+ UINT8 data_read();
+ void control_write(UINT8 data);
+ void data_write(UINT8 data);
+
+ int dtr();
+ int rts();
+ void set_cts(int state);
+ void set_dcd(int state);
+ void receive_data(int data);
+
+ private:
+ void set_interrupt(int type);
+ void clear_interrupt(int type);
+ attotime compute_time_per_character();
+
+ static TIMER_CALLBACK( static_change_input_line ) { reinterpret_cast<sio_channel *>(ptr)->change_input_line(param >> 1, param & 1); }
+ void change_input_line(int line, int state);
+
+ static TIMER_CALLBACK( static_serial_callback ) { reinterpret_cast<sio_channel *>(ptr)->serial_callback(); }
+ void serial_callback();
+
+ public:
+ UINT8 m_regs[8]; // 8 writeable registers
+
+ private:
+ z80sio_device *m_device; // pointer back to our device
+ int m_index; // our channel index
+ UINT8 m_status[4]; // 3 readable registers
+ int m_inbuf; // input buffer
+ int m_outbuf; // output buffer
+ bool m_int_on_next_rx; // interrupt on next rx?
+ emu_timer * m_receive_timer; // timer to clock data in
+ UINT8 m_receive_buffer[16]; // buffer for incoming data
+ UINT8 m_receive_inptr; // index of data coming in
+ UINT8 m_receive_outptr; // index of data going out
+ };
+
+ // internal state
+ sio_channel m_channel[2]; // 2 channels
+ UINT8 m_int_state[8]; // interrupt states
+
+ static const UINT8 k_int_priority[];
+};
+
+
+// device type definition
+extern const device_type Z80SIO;
+
+
+
+//**************************************************************************
+// CONTROL/DATA REGISTER READ/WRITE
+//**************************************************************************
+
+// register access (A1=C/_D A0=B/_A)
+READ8_DEVICE_HANDLER( z80sio_cd_ba_r );
+WRITE8_DEVICE_HANDLER( z80sio_cd_ba_w );
+
+// register access (A1=B/_A A0=C/_D)
+READ8_DEVICE_HANDLER( z80sio_ba_cd_r );
+WRITE8_DEVICE_HANDLER( z80sio_ba_cd_w );
+
+WRITE8_DEVICE_HANDLER( z80sio_c_w );
+READ8_DEVICE_HANDLER( z80sio_c_r );
+
+WRITE8_DEVICE_HANDLER( z80sio_d_w );
+READ8_DEVICE_HANDLER( z80sio_d_r );
+
+
+//**************************************************************************
+// CONTROL LINE READ/WRITE
+//**************************************************************************
+
+READ8_DEVICE_HANDLER( z80sio_get_dtr );
+READ8_DEVICE_HANDLER( z80sio_get_rts );
+WRITE8_DEVICE_HANDLER( z80sio_set_cts );
+WRITE8_DEVICE_HANDLER( z80sio_set_dcd );
+WRITE8_DEVICE_HANDLER( z80sio_receive_data );
+
+
+#endif