summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/gt64xxx.h
blob: 3b7139855306d0ad51b1a9be0f00bd39396a1cff (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
// license:BSD-3-Clause
// copyright-holders: Aaron Giles, Ted Green
// Galileo GT-64xxx System Controller
// Skeleton code based off seattle machine driver.
// TODO:
// Need PCI to be able to have a target delay (pci bus stall) a dma transfer
// Configurable byte swapping on cpu and pci busses.

#ifndef MAME_MACHINE_GT64XXX_H
#define MAME_MACHINE_GT64XXX_H

#include "pci.h"
#include "cpu/mips/mips3.h"

// Supports R4600/4650/4700/R5000 CPUs
#define MCFG_GT64010_ADD(_tag,  _cpu_tag, _clock, _irq_num) \
	MCFG_PCI_HOST_ADD(_tag, GT64XXX, 0x11ab0146, 0x03, 0x00000000) \
	downcast<gt64xxx_device *>(device)->set_cpu_tag(_cpu_tag); \
	downcast<gt64xxx_device *>(device)->set_clock(_clock); \
	downcast<gt64xxx_device *>(device)->set_irq_num(_irq_num);

// Supports the following 32-bit bus CPUs:
// IDT RC4640 and RC4650 (in 32-bit mode)
// QED RM523X
// NEC/Toshiba VR4300
#define MCFG_GT64111_ADD(_tag,  _cpu_tag, _clock, _irq_num) \
	MCFG_PCI_DEVICE_ADD(_tag, GT64XXX, 0x414611ab, 0x10, 0x058000, 0x00000000) \
	downcast<gt64xxx_device *>(device)->set_cpu_tag(_cpu_tag); \
	downcast<gt64xxx_device *>(device)->set_clock(_clock); \
	downcast<gt64xxx_device *>(device)->set_irq_num(_irq_num);

#define MCFG_GT64XXX_SET_BE_CPU(_be) \
	downcast<gt64xxx_device *>(device)->set_be(_be);

#define MCFG_GT64XXX_IRQ_ADD(_irq_num) \
	downcast<gt64xxx_device *>(device)->set_irq_info(_irq_num);

#define MCFG_GT64XXX_SET_CS(_cs_num, _map) \
	downcast<gt64xxx_device *>(device)->set_map(_cs_num, address_map_delegate(ADDRESS_MAP_NAME(_map), #_map), owner);

#define MCFG_GT64XX_SET_SIMM(_index, _size) \
	downcast<gt64xxx_device *>(device)->set_simm_size(_index, _size);

#define MCFG_GT64XX_SET_SIMM0(_size) \
	downcast<gt64xxx_device *>(device)->set_simm0_size(_size);

#define MCFG_GT64XX_SET_SIMM1(_size) \
	downcast<gt64xxx_device *>(device)->set_simm1_size(_size);

/*************************************
 *  Structures
 *************************************/
class gt64xxx_device : public pci_host_device {
public:
	gt64xxx_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

	virtual void reset_all_mappings() override;
	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_cpu_tag(const char *tag) { cpu_tag = tag;}
	void set_clock(const uint32_t clock) {m_clock = clock;}
	void set_be(const int be) {m_be = be;}
	void set_autoconfig(const int autoconfig) {m_autoconfig = autoconfig;}
	void set_irq_num(const int irq_num) {m_irq_num = irq_num;}
	virtual DECLARE_ADDRESS_MAP(config_map, 32) override;
	void set_simm_size(const int index, const int size) { m_simm_size[index] = size; };
	void set_simm0_size(const int size) { m_simm_size[0] = size; };
	void set_simm1_size(const int size) { m_simm_size[1] = size; };

	DECLARE_WRITE_LINE_MEMBER(pci_stall);

	// pci bus
	DECLARE_READ32_MEMBER(  pci_config_r);
	DECLARE_WRITE32_MEMBER( pci_config_w);

	// cpu bus
	DECLARE_READ32_MEMBER (cpu_if_r);
	DECLARE_WRITE32_MEMBER(cpu_if_w);

	DECLARE_READ32_MEMBER (master_mem0_r);
	DECLARE_WRITE32_MEMBER(master_mem0_w);

	DECLARE_READ32_MEMBER (master_mem1_r);
	DECLARE_WRITE32_MEMBER(master_mem1_w);

	DECLARE_READ32_MEMBER (master_io_r);
	DECLARE_WRITE32_MEMBER(master_io_w);

	// devices
	DECLARE_READ32_MEMBER (ras_0_r);
	DECLARE_WRITE32_MEMBER(ras_0_w);
	DECLARE_READ32_MEMBER(ras_1_r);
	DECLARE_WRITE32_MEMBER(ras_1_w);
	DECLARE_READ32_MEMBER(ras_2_r);
	DECLARE_WRITE32_MEMBER(ras_2_w);
	DECLARE_READ32_MEMBER(ras_3_r);
	DECLARE_WRITE32_MEMBER(ras_3_w);
	DECLARE_READ32_MEMBER (cs_0_r);
	DECLARE_WRITE32_MEMBER(cs_0_w);

	// Enums
	enum proc_addr_bank {ADDR_RAS1_0, ADDR_RAS3_2, ADDR_CS2_0, ADDR_CS3_BCS, ADDR_PCI_IO, ADDR_PCI_MEM0, ADDR_PCI_MEM1, ADDR_NUM};

	void set_map(int id, const address_map_delegate &map, device_t *device);
	void postload();

protected:
	address_space *m_cpu_space;
	virtual std::vector<std::pair<int, const address_space_config *>> memory_space_config() const override;
	virtual void device_start() override;
	virtual void device_reset() override;


private:
	static constexpr int AS_PCI_MEM = 1;
	static constexpr int AS_PCI_IO = 2;

	struct galileo_timer
	{
		emu_timer *     timer;
		uint32_t          count;
		uint8_t           active;
	};

	struct galileo_addr_map
	{
		uint32_t low_addr;
		uint32_t high_addr;
		address_space* space;
		galileo_addr_map() : low_addr(0xffffffff), high_addr(0x0) {}
	};

	mips3_device *m_cpu;
	const char *cpu_tag;
	uint32_t m_clock;
	int m_be, m_autoconfig;
	int m_irq_num;
	int m_simm_size[4];

	int m_pci_stall_state;
	int m_retry_count;
	int m_pci_cpu_stalled;
	uint32_t m_cpu_stalled_offset;
	uint32_t m_cpu_stalled_data;
	uint32_t m_cpu_stalled_mem_mask;

	address_space_config m_mem_config, m_io_config;

	required_memory_region m_romRegion;
	optional_memory_region m_updateRegion;

	DECLARE_ADDRESS_MAP(cpu_map, 32);
	DECLARE_ADDRESS_MAP(empty, 32);

	void map_cpu_space();

	uint32_t m_prev_addr;
	/* raw register data */
	uint32_t          m_reg[0xd00/4];

	/* timer info */
	galileo_timer   m_timer[4];
	TIMER_CALLBACK_MEMBER(timer_callback);

	/* DMA info */
	int8_t            m_dma_active;

	// Ram
	std::vector<uint32_t> m_ram[4];

	// Chip Select
	device_t *m_cs_devices[4];
	address_map_delegate m_cs_maps[4];

	void update_irqs();

	int m_last_dma;
	emu_timer* m_dma_timer;
	galileo_addr_map dma_addr_map[proc_addr_bank::ADDR_NUM];
	int dma_fetch_next(address_space &space, int which);
	TIMER_CALLBACK_MEMBER(perform_dma);
	address_space* dma_decode_address(uint32_t &addr);
};

DECLARE_DEVICE_TYPE(GT64XXX, gt64xxx_device)

#endif // MAME_MACHINE_GT64XXX_H