summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/machine/midwayic.h
blob: a10988714b01bf69126bdc4bf697138384e7f6a8 (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
// 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; }

	u8 read();
	void write(u8 data);
	u8 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;
	virtual void device_reset() override;
	virtual ioport_constructor device_input_ports() const override;

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

	required_ioport m_io_serial_digit;

	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;
};


// device type definition
DECLARE_DEVICE_TYPE(MIDWAY_SERIAL_PIC, midway_serial_pic_device)

/* 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);

	u8 read();
	void write(u8 data);
	u8 status_r();
	DECLARE_WRITE_LINE_MEMBER(reset_w);

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:
	required_device<pic16c57_device> m_pic;

	u8 read_c();
	void write_c(u8 data);

	u8 m_command;
	u8 m_data_out;
	u8 m_clk;
	u8 m_status;
};


// 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; }

	u8 read();
	void write(u8 data);
	u8 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)

/* 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; }
	auto irq_handler() { return m_irq_callback.bind(); }
	auto serial_tx_handler() { return m_serial_tx_cb.bind(); }
	auto aux_output_handler() { return m_aux_output_cb.bind(); }

	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);
	uint16_t fifo_r();
	uint16_t fifo_status_r(address_space &space);

	DECLARE_WRITE_LINE_MEMBER(ioasic_input_empty);
	DECLARE_WRITE_LINE_MEMBER(ioasic_output_full);

	uint32_t read(address_space &space, offs_t offset);
	void write(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
	uint32_t packed_r(address_space &space, offs_t offset, uint32_t mem_mask = ~0);
	void packed_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);

	void cage_irq_handler(uint8_t data);

	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)

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