summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/machine/midwayic.h
blob: 707988ce60e379fcb3999c086e1994c5647df0c3 (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
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/***************************************************************************

    Emulation of various Midway ICs

***************************************************************************/

#ifndef __MIDWAY_IC__
#define __MIDWAY_IC__

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

/* 1st generation Midway serial PIC */

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);
	midway_serial_pic_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source);

	static void static_set_upper(device_t &device, int upper) { downcast<midway_serial_pic_device &>(device).m_upper = upper; }

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

protected:
	// 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
extern const device_type MIDWAY_SERIAL_PIC;

#define MCFG_MIDWAY_SERIAL_PIC_UPPER(_upper) \
	midway_serial_pic_device::static_set_upper(*device, _upper);

/* 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);
	midway_serial_pic2_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source);

	static void static_set_yearoffs(device_t &device, int yearoffs) { downcast<midway_serial_pic2_device &>(device).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:
	// 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
extern const device_type MIDWAY_SERIAL_PIC2;

#define MCFG_MIDWAY_SERIAL_PIC2_UPPER   MCFG_MIDWAY_SERIAL_PIC_UPPER

#define MCFG_MIDWAY_SERIAL_PIC2_YEAR_OFFS(_yearoffs) \
	midway_serial_pic2_device::static_set_yearoffs(*device, _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);

	static void static_set_shuffle(device_t &device, uint8_t shuffle) { downcast<midway_ioasic_device &>(device).m_shuffle_type = shuffle; }
	static void static_set_shuffle_default(device_t &device, uint8_t shuffle) { downcast<midway_ioasic_device &>(device).m_shuffle_default = shuffle; }
	static void static_set_auto_ack(device_t &device, uint8_t auto_ack) { downcast<midway_ioasic_device &>(device).m_auto_ack = auto_ack; }
	template<class _Object> static devcb_base &set_irqhandler_callback(device_t &device, _Object object) { return downcast<midway_ioasic_device &>(device).m_irq_callback.set_callback(object); }

	void set_shuffle_state(int state);
	void fifo_w(uint16_t data);
	void fifo_full_w(uint16_t data);
	void output_w(uint32_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 ioasic_reset();

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

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


	uint32_t  m_reg[16];
	uint8_t   m_has_dcs;
	uint8_t   m_has_cage;
	device_t *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;

	atari_cage_device *m_cage;
	dcs_audio_device *m_dcs;
};


// device type definition
extern const device_type MIDWAY_IOASIC;

#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) \
	midway_ioasic_device::static_set_shuffle(*device, _shuffle);

#define MCFG_MIDWAY_IOASIC_SHUFFLE_DEFAULT(_shuffle) \
	midway_ioasic_device::static_set_shuffle_default(*device, _shuffle);

#define MCFG_MIDWAY_IOASIC_IRQ_CALLBACK(_write) \
	devcb = &midway_ioasic_device::set_irqhandler_callback(*device, DEVCB_##_write);

#define MCFG_MIDWAY_IOASIC_AUTO_ACK(_ack) \
	midway_ioasic_device::static_set_auto_ack(*device, _ack);


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