1 // license:BSD-3-Clause
2 // copyright-holders:Curt Coder
3 /**********************************************************************
4 
5     MOS 6526/8520 Complex Interface Adapter emulation
6 
7 **********************************************************************
8                             _____   _____
9                    Vss   1 |*    \_/     | 40  CNT
10                    PA0   2 |             | 39  SP
11                    PA1   3 |             | 38  RS0
12                    PA2   4 |             | 37  RS1
13                    PA3   5 |             | 36  RS2
14                    PA4   6 |             | 35  RS3
15                    PA5   7 |             | 34  _RES
16                    PA6   8 |             | 33  DB0
17                    PA7   9 |             | 32  DB1
18                    PB0  10 |   MOS6526   | 31  DB2
19                    PB1  11 |   MOS8520   | 30  DB3
20                    PB2  12 |             | 29  DB4
21                    PB3  13 |             | 28  DB5
22                    PB4  14 |             | 27  DB6
23                    PB5  15 |             | 26  DB7
24                    PB6  16 |             | 25  phi2
25                    PB7  17 |             | 24  _FLAG
26                    _PC  18 |             | 23  _CS
27                    TOD  19 |             | 22  R/W
28                    Vcc  20 |_____________| 21  _IRQ
29 
30                             _____   _____
31                   FCO*   1 |*    \_/     | 48  FDO*
32                    TED   2 |             | 47  FCI*
33                   phi0   3 |             | 46  FDI*
34                  CLKIN   4 |             | 45  IRQ
35                  CTRLO   5 |             | 44  RSET
36                  CTRLI   6 |             | 43
37                   phi2   7 |             | 42
38                     D7   8 |             | 41  INDEX*
39                     D6   9 |             | 40  WG2*
40                     D5  10 |             | 39  WPRT*
41                     D4  11 |             | 38  RPULSE
42                    GND  12 |   MOS5710   | 37  Q
43                    Vcc  13 |             | 36  Vcc
44                     D3  14 |             | 35  GND
45                     D2  15 |             | 34  CS3*
46                     D1  16 |             | 33  CS2*
47                     D0  17 |             | 32  CS1*
48                    A15  18 |             | 31  R/W*
49                    A14  19 |             | 30  OSC
50                    A13  20 |             | 29  XTL1
51                    A12  21 |             | 28  XTL2
52                    A10  22 |             | 27  A0
53                     A4  23 |             | 26  A1
54                     A3  24 |_____________| 25  A2
55 
56 **********************************************************************/
57 
58 #ifndef MAME_MACHINE_MOS6526_H
59 #define MAME_MACHINE_MOS6526_H
60 
61 #pragma once
62 
63 
64 //**************************************************************************
65 //  TYPE DEFINITIONS
66 //**************************************************************************
67 
68 // ======================> mos6526_device
69 
70 class mos6526_device :  public device_t,
71 						public device_execute_interface
72 {
73 public:
74 	// construction/destruction
75 	mos6526_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
76 
set_tod_clock(int clock)77 	void set_tod_clock(int clock) { m_tod_clock = clock; }
78 
irq_wr_callback()79 	auto irq_wr_callback() { return m_write_irq.bind(); }
cnt_wr_callback()80 	auto cnt_wr_callback() { return m_write_cnt.bind(); }
sp_wr_callback()81 	auto sp_wr_callback() { return m_write_sp.bind(); }
pa_rd_callback()82 	auto pa_rd_callback() { return m_read_pa.bind(); }
pa_wr_callback()83 	auto pa_wr_callback() { return m_write_pa.bind(); }
pb_rd_callback()84 	auto pb_rd_callback() { return m_read_pb.bind(); }
pb_wr_callback()85 	auto pb_wr_callback() { return m_write_pb.bind(); }
pc_wr_callback()86 	auto pc_wr_callback() { return m_write_pc.bind(); }
87 
88 	uint8_t read(offs_t offset);
89 	void write(offs_t offset, uint8_t data);
90 
pa_r()91 	uint8_t pa_r() { return m_pa; }
pb_r()92 	uint8_t pb_r() { return m_pb; }
93 
DECLARE_READ_LINE_MEMBER(sp_r)94 	DECLARE_READ_LINE_MEMBER( sp_r ) { return m_sp; }
95 	DECLARE_WRITE_LINE_MEMBER( sp_w );
DECLARE_READ_LINE_MEMBER(cnt_r)96 	DECLARE_READ_LINE_MEMBER( cnt_r ) { return m_cnt; }
97 	DECLARE_WRITE_LINE_MEMBER( cnt_w );
98 	DECLARE_WRITE_LINE_MEMBER( flag_w );
DECLARE_READ_LINE_MEMBER(irq_r)99 	DECLARE_READ_LINE_MEMBER( irq_r ) { return m_irq; }
100 	DECLARE_WRITE_LINE_MEMBER( tod_w );
101 
102 protected:
103 	enum
104 	{
105 		TYPE_6526,
106 		TYPE_6526A,
107 		TYPE_8520,
108 		TYPE_5710
109 	};
110 
111 	mos6526_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint32_t variant);
112 
113 	// device-level overrides
114 	virtual void device_start() override;
115 	virtual void device_reset() override;
116 	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
117 	virtual void execute_run() override;
118 
119 	int m_icount;
120 	const int m_variant;
121 	int m_tod_clock;
122 
123 	inline void update_interrupt();
124 	inline void update_pa();
125 	inline void update_pb();
126 	inline void set_cra(uint8_t data);
127 	inline void set_crb(uint8_t data);
128 	inline void serial_input();
129 	inline void serial_output();
130 	inline void clock_ta();
131 	inline void clock_tb();
132 	inline void clock_pipeline();
133 	inline uint8_t bcd_increment(uint8_t value);
134 	virtual inline void clock_tod();
135 	inline uint8_t read_tod(int offset);
136 	inline void write_tod(int offset, uint8_t data);
137 	inline void synchronize();
138 
139 	devcb_write_line   m_write_irq;
140 	devcb_write_line   m_write_pc;
141 	devcb_write_line   m_write_cnt;
142 	devcb_write_line   m_write_sp;
143 	devcb_read8        m_read_pa;
144 	devcb_write8       m_write_pa;
145 	devcb_read8        m_read_pb;
146 	devcb_write8       m_write_pb;
147 
148 	// interrupts
149 	bool m_irq;
150 	int m_ir0;
151 	int m_ir1;
152 	uint8_t m_icr;
153 	uint8_t m_imr;
154 	bool m_icr_read;
155 
156 	// peripheral ports
157 	int m_pc;
158 	int m_flag;
159 	uint8_t m_pra;
160 	uint8_t m_prb;
161 	uint8_t m_ddra;
162 	uint8_t m_ddrb;
163 	uint8_t m_pa;
164 	uint8_t m_pb;
165 	uint8_t m_pa_in;
166 	uint8_t m_pb_in;
167 
168 	// serial
169 	int m_sp;
170 	int m_cnt;
171 	uint8_t m_sdr;
172 	uint8_t m_shift;
173 	bool m_sdr_empty;
174 	int m_bits;
175 
176 	// timers
177 	int m_ta_out;
178 	int m_tb_out;
179 	int m_ta_pb6;
180 	int m_tb_pb7;
181 	int m_count_a0;
182 	int m_count_a1;
183 	int m_count_a2;
184 	int m_count_a3;
185 	int m_load_a0;
186 	int m_load_a1;
187 	int m_load_a2;
188 	int m_oneshot_a0;
189 	int m_count_b0;
190 	int m_count_b1;
191 	int m_count_b2;
192 	int m_count_b3;
193 	int m_load_b0;
194 	int m_load_b1;
195 	int m_load_b2;
196 	int m_oneshot_b0;
197 	uint16_t m_ta;
198 	uint16_t m_tb;
199 	uint16_t m_ta_latch;
200 	uint16_t m_tb_latch;
201 	uint8_t m_cra;
202 	uint8_t m_crb;
203 
204 	// time-of-day
205 	int m_tod_count;
206 	uint32_t m_tod;
207 	uint32_t m_tod_latch;
208 	uint32_t m_alarm;
209 	bool m_tod_stopped;
210 	bool m_tod_latched;
211 	emu_timer *m_tod_timer;
212 };
213 
214 
215 // ======================> mos6526a_device
216 
217 class mos6526a_device : public mos6526_device
218 {
219 public:
220 	mos6526a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
221 };
222 
223 
224 // ======================> mos8520_device
225 
226 class mos8520_device : public mos6526_device
227 {
228 public:
229 	mos8520_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
230 
231 	uint8_t read(offs_t offset);
232 	void write(offs_t offset, uint8_t data);
233 
234 protected:
235 	virtual inline void clock_tod() override;
236 };
237 
238 
239 // ======================> mos5710_device
240 
241 class mos5710_device : public mos6526_device
242 {
243 public:
244 	mos5710_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
245 
246 	//uint8_t read(offs_t offset);
247 	//void write(offs_t offset, uint8_t data);
248 };
249 
250 
251 // device type definition
252 DECLARE_DEVICE_TYPE(MOS6526,  mos6526_device)
253 DECLARE_DEVICE_TYPE(MOS6526A, mos6526a_device)
254 DECLARE_DEVICE_TYPE(MOS8520,  mos8520_device)
255 DECLARE_DEVICE_TYPE(MOS5710,  mos5710_device)
256 
257 #endif // MAME_MACHINE_MOS6526_H
258