summaryrefslogtreecommitdiffstatshomepage
path: root/trunk/src/emu/machine/6526cia.h
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/emu/machine/6526cia.h')
-rw-r--r--trunk/src/emu/machine/6526cia.h269
1 files changed, 269 insertions, 0 deletions
diff --git a/trunk/src/emu/machine/6526cia.h b/trunk/src/emu/machine/6526cia.h
new file mode 100644
index 00000000000..3aee04adcd4
--- /dev/null
+++ b/trunk/src/emu/machine/6526cia.h
@@ -0,0 +1,269 @@
+/**********************************************************************
+
+ MOS 6526/8520 Complex Interface Adapter emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************
+ _____ _____
+ Vss 1 |* \_/ | 40 CNT
+ PA0 2 | | 39 SP
+ PA1 3 | | 38 RS0
+ PA2 4 | | 37 RS1
+ PA3 5 | | 36 RS2
+ PA4 6 | | 35 RS3
+ PA5 7 | | 34 _RES
+ PA6 8 | | 33 DB0
+ PA7 9 | | 32 DB1
+ PB0 10 | MOS6526 | 31 DB2
+ PB1 11 | MOS8520 | 30 DB3
+ PB2 12 | | 29 DB4
+ PB3 13 | | 28 DB5
+ PB4 14 | | 27 DB6
+ PB5 15 | | 26 DB7
+ PB6 16 | | 25 phi2
+ PB7 17 | | 24 _FLAG
+ _PC 18 | | 23 _CS
+ TOD 19 | | 22 R/W
+ Vcc 20 |_____________| 21 _IRQ
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __6526CIA_H__
+#define __6526CIA_H__
+
+#include "emu.h"
+
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_MOS6526R1_ADD(_tag, _clock, _config) \
+ MCFG_DEVICE_ADD(_tag, MOS6526R1, _clock) \
+ MCFG_DEVICE_CONFIG(_config)
+
+#define MCFG_MOS6526R2_ADD(_tag, _clock, _config) \
+ MCFG_DEVICE_ADD(_tag, MOS6526R2, _clock) \
+ MCFG_DEVICE_CONFIG(_config)
+
+#define MCFG_MOS8520_ADD(_tag, _clock, _config) \
+ MCFG_DEVICE_ADD(_tag, MOS8520, _clock) \
+ MCFG_DEVICE_CONFIG(_config)
+
+#define MOS6526_INTERFACE(name) \
+ const mos6526_interface (name)=
+
+#define MOS8520_INTERFACE(name) \
+ const mos6526_interface (name)=
+
+/***************************************************************************
+ TYPE DEFINITIONS
+***************************************************************************/
+
+
+// ======================> mos6526_interface
+
+struct mos6526_interface
+{
+ int m_tod_clock;
+
+ devcb_write_line m_out_irq_cb;
+ devcb_write_line m_out_pc_cb;
+ devcb_write_line m_out_cnt_cb;
+ devcb_write_line m_out_sp_cb;
+
+ devcb_read8 m_in_pa_cb;
+ devcb_write8 m_out_pa_cb;
+
+ devcb_read8 m_in_pb_cb;
+ devcb_write8 m_out_pb_cb;
+};
+
+
+
+// ======================> mos6526_device
+
+class mos6526_device : public device_t,
+ public mos6526_interface
+{
+ friend class dart_channel;
+
+protected:
+ // construction/destruction
+ mos6526_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
+
+public:
+ UINT8 reg_r(UINT8 offset);
+ void reg_w(UINT8 offset, UINT8 data);
+
+ /* port access */
+ UINT8 pa_r(UINT8 offset) { return (m_port[0].m_latch | ~m_port[0].m_ddr); }
+ UINT8 pb_r(UINT8 offset) { return (m_port[1].m_latch | ~m_port[1].m_ddr); }
+
+ /* interrupt request */
+ UINT8 irq_r() { return m_irq; }
+
+ /* time of day clock */
+ void tod_w(UINT8 state) { if(state) clock_tod(); }
+
+ /* serial counter */
+ UINT8 cnt_r() { return m_cnt; }
+ void cnt_w(UINT8 state);
+
+ /* serial port */
+ UINT8 sp_r() { return m_sp; }
+ void sp_w(UINT8 state) { m_sp = state; }
+
+ /* flag */
+ void flag_w(UINT8 state);
+
+ /* port mask */
+ void set_port_mask_value(int port, int data);
+
+protected:
+ // device-level overrides
+ virtual void device_config_complete();
+ virtual void device_start();
+ virtual void device_reset();
+ virtual void device_post_load() { }
+ virtual void device_clock_changed() { }
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
+
+ static TIMER_CALLBACK( timer_proc );
+ static TIMER_CALLBACK( clock_tod_callback );
+
+private:
+ static const device_timer_id TIMER_PC = 0;
+
+ inline attotime cycles_to_time(int c);
+ void update_pc();
+ void update_interrupts();
+ void timer_bump(int timer);
+ void timer_underflow(int timer);
+ void increment();
+ void clock_tod();
+
+ struct cia_timer
+ {
+ public:
+ cia_timer() { }
+
+ UINT16 get_count();
+ void update(int which, INT32 new_count);
+
+ UINT32 m_clock;
+ UINT16 m_latch;
+ UINT16 m_count;
+ UINT8 m_mode;
+ UINT8 m_irq;
+ emu_timer* m_timer;
+ mos6526_device* m_cia;
+ };
+
+ struct cia_port
+ {
+ UINT8 m_ddr;
+ UINT8 m_latch;
+ UINT8 m_in;
+ UINT8 m_out;
+ devcb_resolved_read8 m_read;
+ devcb_resolved_write8 m_write;
+ UINT8 m_mask_value; /* in READ operation the value can be forced by a extern electric circuit */
+ };
+
+ devcb_resolved_write_line m_out_irq_func;
+ devcb_resolved_write_line m_out_pc_func;
+ devcb_resolved_write_line m_out_cnt_func;
+ devcb_resolved_write_line m_out_sp_func;
+
+ cia_port m_port[2];
+ cia_timer m_timer[2];
+
+ /* Time Of the Day clock (TOD) */
+ UINT32 m_tod;
+ UINT32 m_tod_latch;
+ UINT8 m_tod_latched;
+ UINT8 m_tod_running;
+ UINT32 m_alarm;
+
+ /* Interrupts */
+ UINT8 m_icr;
+ UINT8 m_ics;
+ UINT8 m_irq;
+ int m_flag;
+
+ /* Serial */
+ UINT8 m_loaded;
+ UINT8 m_sdr;
+ UINT8 m_sp;
+ UINT8 m_cnt;
+ UINT8 m_shift;
+ UINT8 m_serial;
+
+ emu_timer *m_pc_timer;
+};
+
+class mos6526r1_device : public mos6526_device
+{
+public:
+ mos6526r1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+};
+
+class mos6526r2_device : public mos6526_device
+{
+public:
+ mos6526r2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+};
+
+class mos8520_device : public mos6526_device
+{
+public:
+ mos8520_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+};
+
+
+// device type definition
+extern const device_type MOS6526R1;
+extern const device_type MOS6526R2;
+extern const device_type MOS8520;
+
+
+
+/***************************************************************************
+ FUNCTION PROTOTYPES
+***************************************************************************/
+
+/* register access */
+READ8_DEVICE_HANDLER( mos6526_r );
+WRITE8_DEVICE_HANDLER( mos6526_w );
+
+/* port access */
+READ8_DEVICE_HANDLER( mos6526_pa_r );
+READ8_DEVICE_HANDLER( mos6526_pb_r );
+
+/* interrupt request */
+READ_LINE_DEVICE_HANDLER( mos6526_irq_r );
+
+/* time of day clock */
+WRITE_LINE_DEVICE_HANDLER( mos6526_tod_w );
+
+/* serial counter */
+READ_LINE_DEVICE_HANDLER( mos6526_cnt_r );
+WRITE_LINE_DEVICE_HANDLER( mos6526_cnt_w );
+
+/* serial port */
+READ_LINE_DEVICE_HANDLER( mos6526_sp_r );
+WRITE_LINE_DEVICE_HANDLER( mos6526_sp_w );
+
+/* flag */
+WRITE_LINE_DEVICE_HANDLER( mos6526_flag_w );
+
+/* port mask */
+void cia_set_port_mask_value(device_t *device, int port, int data);
+
+#endif /* __6526CIA_H__ */