summaryrefslogtreecommitdiffstats
path: root/src/mame/machine/midwayic.h
blob: 8d764d34999a19669aa376ef2932c1b02be45572 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/***************************************************************************

    Emulation of various Midway ICs

***************************************************************************/
#ifndef MAME_MACHINE_MIDWAY_IC_H
#define MAME_MACHINE_MIDWAY_IC_H

#pragma once


#include "audio/cage.h"
#include "audio/dcs.h"
#include "cpu/pic16c5x/pic16c5x.h"

/* 1st generation Midway serial PIC - simulation*/

class midway_serial_pic_device : public device_t
{
public:
	// construction/destruction
	midway_serial_pic_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

	void set_upper(int upper) { m_upper = upper; }

	DECLARE_READ8_MEMBER( read );
	DECLARE_WRITE8_MEMBER( write );
	DECLARE_READ8_MEMBER( status_r );
	DECLARE_WRITE_LINE_MEMBER( reset_w );

protected:
	midway_serial_pic_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);

	// device-level overrides
	virtual void device_start() override;

	void generate_serial_data(int upper);
	void serial_register_state();

	uint8_t   m_data[16]; // reused by other devices
	int     m_upper;
private:
	uint8_t   m_buff;
	uint8_t   m_idx;
	uint8_t   m_status;
	uint8_t   m_bits;
	uint8_t   m_ormask;
};


// device type definition
DECLARE_DEVICE_TYPE(MIDWAY_SERIAL_PIC, midway_serial_pic_device)

#define MCFG_MIDWAY_SERIAL_PIC_UPPER(_upper) \
	downcast<midway_serial_pic_device &>(*device).set_upper(_upper);

/* 1st generation Midway serial PIC - emulation */

class midway_serial_pic_emu_device : public device_t
{
public:
	// construction/destruction
	midway_serial_pic_emu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

protected:
	midway_serial_pic_emu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);

	// device-level overrides
	virtual void device_add_mconfig(machine_config &config) override;
	virtual void device_start() override;

private:
	DECLARE_READ8_MEMBER(read_a);
	DECLARE_READ8_MEMBER(read_b);
	DECLARE_READ8_MEMBER(read_c);
	DECLARE_WRITE8_MEMBER(write_a);
	DECLARE_WRITE8_MEMBER(write_b);
	DECLARE_WRITE8_MEMBER(write_c);
};


// device type definition
DECLARE_DEVICE_TYPE(MIDWAY_SERIAL_PIC_EMU, midway_serial_pic_emu_device)



/* 2nd generation Midway serial/NVRAM/RTC PIC */

// ======================> midway_serial_pic2_device

class midway_serial_pic2_device : public midway_serial_pic_device, public device_nvram_interface
{
public:
	// construction/destruction
	midway_serial_pic2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

	void set_yearoffs(int yearoffs) { m_yearoffs = yearoffs; }

	DECLARE_READ8_MEMBER( read );
	DECLARE_WRITE8_MEMBER( write );
	DECLARE_READ8_MEMBER( status_r );

	void set_default_nvram(const uint8_t *nvram);

protected:
	midway_serial_pic2_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);

	// device-level overrides
	virtual void device_start() override;

	// device_nvram_interface overrides
	virtual void nvram_default() override;
	virtual void nvram_read(emu_file &file) override;
	virtual void nvram_write(emu_file &file) override;

private:

	void pic_register_state();
	TIMER_CALLBACK_MEMBER( reset_timer );

	uint16_t  m_latch;
	attotime m_latch_expire_time;
	uint8_t   m_state;
	uint8_t   m_index;
	uint8_t   m_total;
	uint8_t   m_nvram_addr;
	uint8_t   m_buffer[0x10];
	uint8_t   m_nvram[0x100];
	uint8_t   m_default_nvram[0x100];
	uint8_t   m_time_buf[8];
	uint8_t   m_time_index;
	uint8_t   m_time_just_written;
	uint16_t  m_yearoffs;
	emu_timer *m_time_write_timer;
};


// device type definition
DECLARE_DEVICE_TYPE(MIDWAY_SERIAL_PIC2, midway_serial_pic2_device)

#define MCFG_MIDWAY_SERIAL_PIC2_UPPER   MCFG_MIDWAY_SERIAL_PIC_UPPER

#define MCFG_MIDWAY_SERIAL_PIC2_YEAR_OFFS(_yearoffs) \
	downcast<midway_serial_pic2_device &>(*device).set_yearoffs(_yearoffs);

/* I/O ASIC connected to 2nd generation PIC */

// ======================> midway_ioasic_device

class midway_ioasic_device : public midway_serial_pic2_device
{
public:
	// construction/destruction
	midway_ioasic_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

	void set_shuffle(uint8_t shuffle) { m_shuffle_type = shuffle; }
	void set_shuffle_default(uint8_t shuffle) { m_shuffle_default = shuffle; }
	void set_auto_ack(uint8_t auto_ack) { m_auto_ack = auto_ack; }
	template <class Object> devcb_base &set_irqhandler_callback(Object &&cb) { return m_irq_callback.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_serial_tx_callback(Object &&cb) { return m_serial_tx_cb.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_aux_output_callback(Object &&cb) { return m_aux_output_cb.set_callback(std::forward<Object>(cb)); }

	void set_shuffle_state(int state);
	void fifo_w(uint16_t data);
	void fifo_full_w(uint16_t data);

	DECLARE_WRITE_LINE_MEMBER(fifo_reset_w);
	DECLARE_READ16_MEMBER(fifo_r);
	DECLARE_READ16_MEMBER(fifo_status_r);

	DECLARE_WRITE_LINE_MEMBER(ioasic_input_empty);
	DECLARE_WRITE_LINE_MEMBER(ioasic_output_full);

	DECLARE_READ32_MEMBER( read );
	DECLARE_WRITE32_MEMBER( write );
	DECLARE_READ32_MEMBER( packed_r );
	DECLARE_WRITE32_MEMBER( packed_w );

	DECLARE_WRITE8_MEMBER(cage_irq_handler);

	void serial_rx_w(u8 data);

	void ioasic_reset();

protected:
	// device-level overrides
	virtual void device_start() override;

private:
	void ioasic_register_state();
	void update_ioasic_irq();

	required_ioport m_io_dips;
	required_ioport m_io_system;
	required_ioport m_io_in1;
	required_ioport m_io_in2;

	devcb_write8    m_serial_tx_cb;
	devcb_write32   m_aux_output_cb;

	uint32_t  m_reg[16];
	uint8_t   m_has_dcs;
	uint8_t   m_has_cage;
	cpu_device *m_dcs_cpu;
	uint8_t   m_shuffle_type;
	uint8_t   m_shuffle_default;
	uint8_t   m_shuffle_active;
	const uint8_t *   m_shuffle_map;
	devcb_write8 m_irq_callback;
	uint8_t   m_irq_state;
	uint16_t  m_sound_irq_state;
	uint8_t   m_auto_ack;
	uint8_t   m_force_fifo_full;

	uint16_t  m_fifo[512];
	uint16_t  m_fifo_in;
	uint16_t  m_fifo_out;
	uint16_t  m_fifo_bytes;
	offs_t  m_fifo_force_buffer_empty_pc;

	optional_device<atari_cage_device> m_cage;
	optional_device<dcs_audio_device> m_dcs;
};


// device type definition
DECLARE_DEVICE_TYPE(MIDWAY_IOASIC, midway_ioasic_device)

#define MCFG_MIDWAY_IOASIC_UPPER    MCFG_MIDWAY_SERIAL_PIC_UPPER

#define MCFG_MIDWAY_IOASIC_YEAR_OFFS MCFG_MIDWAY_SERIAL_PIC2_YEAR_OFFS

#define MCFG_MIDWAY_IOASIC_SHUFFLE(_shuffle) \
	downcast<midway_ioasic_device &>(*device).set_shuffle(_shuffle);

#define MCFG_MIDWAY_IOASIC_SHUFFLE_DEFAULT(_shuffle) \
	downcast<midway_ioasic_device &>(*device).set_shuffle_default(_shuffle);

#define MCFG_MIDWAY_IOASIC_IRQ_CALLBACK(_write) \
	downcast<midway_ioasic_device &>(*device).set_irqhandler_callback(DEVCB_##_write);

#define MCFG_MIDWAY_IOASIC_AUTO_ACK(_ack) \
	downcast<midway_ioasic_device &>(*device).set_auto_ack(_ack);

#define MCFG_MIDWAY_IOASIC_OUT_TX_CB(_devcb) \
	downcast<midway_ioasic_device &>(*device).set_serial_tx_callback(DEVCB_##_devcb);

#define MCFG_MIDWAY_IOASIC_AUX_OUT_CB(_devcb) \
	downcast<midway_ioasic_device &>(*device).set_aux_output_callback(DEVCB_##_devcb);


enum
{
	MIDWAY_IOASIC_STANDARD = 0,
	MIDWAY_IOASIC_BLITZ99,
	MIDWAY_IOASIC_CARNEVIL,
	MIDWAY_IOASIC_CALSPEED,
	MIDWAY_IOASIC_MACE,
	MIDWAY_IOASIC_GAUNTDL,
	MIDWAY_IOASIC_VAPORTRX,
	MIDWAY_IOASIC_SFRUSHRK,
	MIDWAY_IOASIC_HYPRDRIV
};

#endif // MAME_MACHINE_MIDWAY_IC_H