summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/machine/iteagle_fpga.h
blob: 692fd53132435b752089df28f5d2a0c0cfba652a (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
// license:BSD-3-Clause
// copyright-holders:Ted Green
//*************************************
// iteagle fpga device
//*************************************
#ifndef MAME_MACHINE_ITEAGLE_FPGA_H
#define MAME_MACHINE_ITEAGLE_FPGA_H

#include "machine/pci.h"
#include "machine/nvram.h"
#include "machine/eepromser.h"
#include "machine/z80scc.h"
#include "bus/rs232/rs232.h"
#include "screen.h"

// Functional emulation of AMD AM85C30 serial controller
// Two channels, A & B
class iteagle_am85c30
{
public:
	void reset();
	void write_control(uint8_t data, int channel);
	uint8_t read_control(int channel);
	void write_data(uint8_t data, int channel);
	uint8_t read_data(int channel);
	void write_rx_str(int channel, std::string resp);
	std::string get_tx_str(int channel) { return m_serial_tx[channel]; };
	void clear_tx_str(int channel) { m_serial_tx[channel].clear(); };
	bool check_interrupt() { return (m_rr_regs[0][3] != 0); };
private:
	uint8_t m_rr_regs[2][16];
	uint8_t m_wr_regs[2][16];
	std::string m_serial_tx[2];
	std::string m_serial_rx[2];
};

class iteagle_fpga_device : public pci_device
{
public:
	template <typename T, typename U>
	iteagle_fpga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&screen_tag, U &&cpu_tag, int irq_num, int serial_num)
		: iteagle_fpga_device(mconfig, tag, owner, clock)
	{
		set_screen_tag(std::forward<T>(screen_tag));
		set_irq_info(std::forward<U>(cpu_tag), irq_num, serial_num);
	}
	iteagle_fpga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

	void set_init_info(int version, int seq_init) {m_version=version; m_seq_init=seq_init;}
	template <typename T> void set_screen_tag(T &&tag) { m_screen.set_tag(std::forward<T>(tag)); }
	template <typename T> void set_irq_info(T &&tag, const int irq_num, int serial_num)
	{ m_cpu.set_tag(std::forward<T>(tag)); m_irq_num = irq_num; m_serial_irq_num = serial_num; }

	DECLARE_WRITE_LINE_MEMBER(vblank_update);
	void serial_rx_w(uint8_t data);

	enum { IO_SYSTEM, IO_IN1, IO_SW5, IO_NUM };
	template <unsigned N> auto in_callback() { return m_in_cb[N].bind(); }
	auto trackx_callback() { return m_trackx_cb.bind(); }
	auto tracky_callback() { return m_tracky_cb.bind(); }
	auto gunx_callback() { return m_gunx_cb.bind(); }
	auto guny_callback() { return m_guny_cb.bind(); }

protected:
	virtual void device_start() override;
	virtual void device_reset() override;
	virtual void device_timer(emu_timer &timer, device_timer_id id, int param) override;
	virtual void device_add_mconfig(machine_config &config) override;

private:
	required_device<nvram_device> m_rtc;
	optional_device<nvram_device> m_e1_nvram;
	required_device<scc85c30_device> m_scc1;
	required_device<screen_device> m_screen;
	required_device<device_execute_interface> m_cpu;
	devcb_read16::array<3> m_in_cb;
	devcb_read8 m_trackx_cb;
	devcb_read8 m_tracky_cb;
	devcb_read16 m_gunx_cb;
	devcb_read16 m_guny_cb;

	emu_timer *     m_timer;
	int m_irq_num;
	int m_serial_irq_num;

	uint32_t m_fpga_regs[0x20 / 4];
	uint32_t m_rtc_regs[0x800 / 4];
	uint32_t m_e1_nv_data[0x40 / 4];
	uint32_t m_e1_ram[0x10000 / 4];
	uint32_t m_prev_reg;

	uint32_t m_version;
	uint32_t m_seq_init;
	uint32_t m_seq;
	uint32_t m_seq_rem1, m_seq_rem2;

	int m_vblank_state;
	int m_gun_x, m_gun_y;

	iteagle_am85c30 m_serial0_1;
	iteagle_am85c30 m_serial2_3;

	void update_sequence(uint32_t data);
	void update_sequence_eg1(uint32_t data);

	void rtc_map(address_map &map);
	void fpga_map(address_map &map);
	void ram_map(address_map &map);

	uint32_t fpga_r(offs_t offset, uint32_t mem_mask = ~0);
	void fpga_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
	uint32_t rtc_r(offs_t offset, uint32_t mem_mask = ~0);
	void rtc_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);

	uint32_t e1_nvram_r(offs_t offset, uint32_t mem_mask = ~0);
	void e1_nvram_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
	uint32_t e1_ram_r(offs_t offset, uint32_t mem_mask = ~0);
	void e1_ram_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);

	DECLARE_WRITE_LINE_MEMBER(serial_interrupt);
};

class iteagle_eeprom_device : public pci_device {
public:
	iteagle_eeprom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
	// optional information overrides
	virtual void map_extra(uint64_t memory_window_start, uint64_t memory_window_end, uint64_t memory_offset, address_space *memory_space,
							uint64_t io_window_start, uint64_t io_window_end, uint64_t io_offset, address_space *io_space) override;

	void set_info(int sw_version, int hw_version) {m_sw_version=sw_version; m_hw_version=hw_version;}

protected:
	virtual void device_start() override;
	virtual void device_reset() override;
	virtual void device_add_mconfig(machine_config &config) override;

private:
	address_space *m_memory_space;
	uint16_t m_sw_version;
	uint8_t m_hw_version;

	std::array<uint16_t, 0x40> m_iteagle_default_eeprom;

	void eeprom_map(address_map &map);
	uint32_t eeprom_r(offs_t offset, uint32_t mem_mask = ~0);
	void eeprom_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);

	required_device<eeprom_serial_93cxx_device> m_eeprom;
};

// Mimic Cypress CY82C693 Peripheral Controller
class iteagle_periph_device : public pci_device {
public:
	iteagle_periph_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

protected:
	virtual void device_start() override;
	virtual void device_reset() override;
	virtual void device_add_mconfig(machine_config &config) override;

private:
	optional_device<nvram_device> m_rtc;

	uint32_t m_ctrl_regs[0xd0/4];
	uint8_t m_rtc_regs[0x100];

	void ctrl_map(address_map &map);

	uint32_t ctrl_r(offs_t offset, uint32_t mem_mask = ~0);
	void ctrl_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);

};

DECLARE_DEVICE_TYPE(ITEAGLE_FPGA, iteagle_fpga_device)
DECLARE_DEVICE_TYPE(ITEAGLE_EEPROM, iteagle_eeprom_device)
DECLARE_DEVICE_TYPE(ITEAGLE_PERIPH, iteagle_periph_device)

#endif // MAME_MACHINE_ITEAGLE_FPGA_H