1 // license:BSD-3-Clause
2 // copyright-holders:Samuele Zannoli
3 #ifndef MAME_INCLUDES_XBOX_PCI_H
4 #define MAME_INCLUDES_XBOX_PCI_H
5
6 #pragma once
7
8 #include "machine/pit8253.h"
9 #include "xbox_nv2a.h"
10 #include "xbox_usb.h"
11
12 /*
13 * Host
14 */
15
16 class nv2a_host_device : public pci_host_device {
17 public:
18 template <typename T>
nv2a_host_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock,T && cpu_tag)19 nv2a_host_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&cpu_tag)
20 : nv2a_host_device(mconfig, tag, owner, clock)
21 {
22 set_ids_host(0x10de02a5, 0, 0);
23 set_cpu_tag(std::forward<T>(cpu_tag));
24 }
25 nv2a_host_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
26 virtual void map_extra(uint64_t memory_window_start, uint64_t memory_window_end, uint64_t memory_offset, address_space *memory_space,
27 uint64_t io_window_start, uint64_t io_window_end, uint64_t io_offset, address_space *io_space) override;
set_cpu_tag(T && cpu_tag)28 template <typename T> void set_cpu_tag(T &&cpu_tag) { cpu.set_tag(std::forward<T>(cpu_tag)); }
29
30 protected:
31 virtual void device_start() override;
32 virtual void device_reset() override;
33
34 private:
35 required_device<device_memory_interface> cpu;
36 };
37
DECLARE_DEVICE_TYPE(NV2A_HOST,nv2a_host_device)38 DECLARE_DEVICE_TYPE(NV2A_HOST, nv2a_host_device)
39
40 /*
41 * Ram
42 */
43
44 class nv2a_ram_device : public pci_device {
45 public:
46 nv2a_ram_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, int memory_size)
47 : nv2a_ram_device(mconfig, tag, owner, clock)
48 {
49 ram_size = memory_size;
50 }
51 nv2a_ram_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
52
53 virtual void config_map(address_map &map) override;
54
55 virtual void map_extra(uint64_t memory_window_start, uint64_t memory_window_end, uint64_t memory_offset, address_space *memory_space,
56 uint64_t io_window_start, uint64_t io_window_end, uint64_t io_offset, address_space *io_space) override;
57
58 protected:
59 virtual void device_start() override;
60
61 uint32_t config_register_r();
62 void config_register_w(uint32_t data);
63
64 private:
65 int ram_size;
66 std::vector<uint32_t> ram;
67 };
68
DECLARE_DEVICE_TYPE(NV2A_RAM,nv2a_ram_device)69 DECLARE_DEVICE_TYPE(NV2A_RAM, nv2a_ram_device)
70
71 /*
72 * LPC Bus
73 */
74
75 class lpcbus_host_interface {
76 public:
77 virtual void set_virtual_line(int line, int state) = 0;
78 virtual void remap() = 0;
79 };
80
81 class lpcbus_device_interface {
82 public:
83 virtual void map_extra(address_space *memory_space, address_space *io_space) = 0;
84 virtual void set_host(int index, lpcbus_host_interface *host) = 0;
85 };
86
87 class mcpx_isalpc_device : public pci_device, public lpcbus_host_interface {
88 public:
89 mcpx_isalpc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, uint32_t subsystem_id);
90 mcpx_isalpc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
91
smi()92 auto smi() { return m_smi_callback.bind(); }
interrupt_output()93 auto interrupt_output() { return m_interrupt_output.bind(); }
boot_state_hook()94 auto boot_state_hook() { return m_boot_state_hook.bind(); }
95
96 uint32_t acknowledge();
97 void debug_generate_irq(int irq, int state);
98
99 virtual void set_virtual_line(int line, int state) override;
100 virtual void remap() override;
101
102 uint32_t acpi_r(offs_t offset, uint32_t mem_mask = ~0);
103 void acpi_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
104 void boot_state_w(uint8_t data);
105
106 DECLARE_WRITE_LINE_MEMBER(irq1);
107 DECLARE_WRITE_LINE_MEMBER(irq3);
108 DECLARE_WRITE_LINE_MEMBER(irq11);
109 DECLARE_WRITE_LINE_MEMBER(irq10);
110 DECLARE_WRITE_LINE_MEMBER(irq14);
111 DECLARE_WRITE_LINE_MEMBER(irq15);
112
113 protected:
114 virtual void device_start() override;
115 virtual void device_reset() override;
116 virtual void device_add_mconfig(machine_config &config) override;
117 virtual void map_extra(uint64_t memory_window_start, uint64_t memory_window_end, uint64_t memory_offset, address_space *memory_space,
118 uint64_t io_window_start, uint64_t io_window_end, uint64_t io_offset, address_space *io_space) override;
119
120 DECLARE_WRITE_LINE_MEMBER(interrupt_ouptut_changed);
121 uint8_t get_slave_ack(offs_t offset);
122 DECLARE_WRITE_LINE_MEMBER(pit8254_out0_changed);
123 DECLARE_WRITE_LINE_MEMBER(pit8254_out1_changed);
124 DECLARE_WRITE_LINE_MEMBER(pit8254_out2_changed);
125
126 private:
127 void internal_io_map(address_map &map);
128 void lpc_io(address_map &map);
129 void update_smi_line();
130 void speaker_set_spkrdata(uint8_t data);
131
132 uint8_t portb_r();
133 void portb_w(uint8_t data);
134
135 devcb_write_line m_smi_callback;
136 devcb_write_line m_interrupt_output;
137 devcb_write8 m_boot_state_hook;
138 required_device<pic8259_device> pic8259_1;
139 required_device<pic8259_device> pic8259_2;
140 required_device<pit8254_device> pit8254;
141
142 uint16_t m_pm1_status;
143 uint16_t m_pm1_enable;
144 uint16_t m_pm1_control;
145 uint16_t m_pm1_timer;
146 uint16_t m_gpe0_status;
147 uint16_t m_gpe0_enable;
148 uint16_t m_global_smi_control;
149 uint8_t m_smi_command_port;
150 uint8_t m_gpio_mode[26];
151 lpcbus_device_interface *lpcdevices[16];
152 uint8_t m_speaker;
153 bool m_refresh;
154 uint8_t m_pit_out2;
155 uint8_t m_spkrdata;
156 uint8_t m_channel_check;
157 };
158
DECLARE_DEVICE_TYPE(MCPX_ISALPC,mcpx_isalpc_device)159 DECLARE_DEVICE_TYPE(MCPX_ISALPC, mcpx_isalpc_device)
160
161 /*
162 * SMBus
163 */
164
165 class smbus_interface {
166 public:
167 virtual int execute_command(int command, int rw, int data) = 0;
168 };
169
170 class mcpx_smbus_device : public pci_device {
171 public:
172 mcpx_smbus_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, uint32_t subsystem_id);
173 mcpx_smbus_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
174
interrupt_handler()175 auto interrupt_handler() { return m_interrupt_handler.bind(); }
176
177 uint32_t smbus0_r(offs_t offset, uint32_t mem_mask = ~0);
178 void smbus0_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
179 uint32_t smbus1_r(offs_t offset, uint32_t mem_mask = ~0);
180 void smbus1_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
181
182 protected:
183 virtual void device_start() override;
184 virtual void device_reset() override;
185
186 virtual void config_map(address_map &map) override;
187
188 private:
189 devcb_write_line m_interrupt_handler;
190 struct smbus_state {
191 int status;
192 int control;
193 int address;
194 int data;
195 int command;
196 int rw;
197 smbus_interface *devices[128];
198 uint32_t words[256 / 4];
199 } smbusst[2];
200 void smbus_io0(address_map &map);
201 void smbus_io1(address_map &map);
202 void smbus_io2(address_map &map);
203 uint32_t smbus_read(int bus, offs_t offset, uint32_t mem_mask);
204 void smbus_write(int bus, offs_t offset, uint32_t data, uint32_t mem_mask);
minimum_grant_r()205 uint8_t minimum_grant_r() { return 3; }
maximum_latency_r()206 uint8_t maximum_latency_r() { return 1; }
207 };
208
DECLARE_DEVICE_TYPE(MCPX_SMBUS,mcpx_smbus_device)209 DECLARE_DEVICE_TYPE(MCPX_SMBUS, mcpx_smbus_device)
210
211 /*
212 * OHCI USB Controller
213 */
214 class usb_function_device;
215 class mcpx_ohci_device : public pci_device {
216 public:
217 mcpx_ohci_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, uint32_t subsystem_id);
218 mcpx_ohci_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
219 void set_hack_callback(std::function<void(void)> hack) { hack_callback = hack; }
220 void plug_usb_device(int port, device_usb_ohci_function_interface *function);
221
222 auto interrupt_handler() { return m_interrupt_handler.bind(); }
223
224 uint32_t ohci_r(offs_t offset);
225 void ohci_w(offs_t offset, uint32_t data);
226
227 protected:
228 virtual void device_start() override;
229 virtual void device_reset() override;
230 virtual void device_config_complete() override;
231 virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
232
233 virtual void config_map(address_map &map) override;
234
235 private:
236 ohci_usb_controller *ohci_usb;
237 devcb_write_line m_interrupt_handler;
238 emu_timer *timer;
239 required_device<cpu_device> maincpu;
240 std::function<void(void)> hack_callback;
241 void ohci_mmio(address_map &map);
242 struct dev_t {
243 device_usb_ohci_function_interface *dev;
244 int port;
245 } connecteds[4];
246 int connecteds_count;
247 uint8_t minimum_grant_r() { return 3; }
248 uint8_t maximum_latency_r() { return 1; }
249 };
250
DECLARE_DEVICE_TYPE(MCPX_OHCI,mcpx_ohci_device)251 DECLARE_DEVICE_TYPE(MCPX_OHCI, mcpx_ohci_device)
252
253 /*
254 * Ethernet
255 */
256
257 class mcpx_eth_device : public pci_device {
258 public:
259 mcpx_eth_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
260
261 uint32_t eth_r();
262 void eth_w(uint32_t data);
263 uint32_t eth_io_r();
264 void eth_io_w(uint32_t data);
265
266 protected:
267 virtual void device_start() override;
268 virtual void device_reset() override;
269
270 private:
271 void eth_mmio(address_map &map);
272 void eth_io(address_map &map);
273 };
274
DECLARE_DEVICE_TYPE(MCPX_ETH,mcpx_eth_device)275 DECLARE_DEVICE_TYPE(MCPX_ETH, mcpx_eth_device)
276
277 /*
278 * Audio Processing Unit
279 */
280
281 class mcpx_apu_device : public pci_device {
282 public:
283 template <typename T>
284 mcpx_apu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, uint32_t subsystem_id, T &&cpu_tag)
285 : mcpx_apu_device(mconfig, tag, owner, clock)
286 {
287 set_ids(0x10de01b0, 0xc2, 0x040100, subsystem_id);
288 set_cpu_tag(std::forward<T>(cpu_tag));
289 }
290 mcpx_apu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
291 template <typename T> void set_cpu_tag(T &&cpu_tag) { cpu.set_tag(std::forward<T>(cpu_tag)); }
292
293 uint32_t apu_r(offs_t offset, uint32_t mem_mask = ~0);
294 void apu_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
295
296 protected:
297 virtual void device_start() override;
298 virtual void device_reset() override;
299 virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
300
301 virtual void config_map(address_map &map) override;
302
303 private:
304 required_device<device_memory_interface> cpu;
305 // APU contains 3 dsps: voice processor (VP) global processor (GP) encode processor (EP)
306 struct apu_state {
307 uint32_t memory[0x60000 / 4];
308 uint32_t gpdsp_sgaddress; // global processor scatter-gather
309 uint32_t gpdsp_sgblocks;
310 uint32_t gpdsp_address;
311 uint32_t epdsp_sgaddress; // encoder processor scatter-gather
312 uint32_t epdsp_sgblocks;
313 uint32_t epdsp_sgaddress2;
314 uint32_t epdsp_sgblocks2;
315 int voice_number;
316 uint32_t voices_heap_blockaddr[1024];
317 uint64_t voices_active[4]; //one bit for each voice: 1 playing 0 not
318 uint32_t voicedata_address;
319 int voices_frequency[256]; // sample rate
320 int voices_position[256]; // position in samples * 1000
321 int voices_position_start[256]; // position in samples * 1000
322 int voices_position_end[256]; // position in samples * 1000
323 int voices_position_increment[256]; // position increment every 1ms * 1000
324 emu_timer *timer;
325 address_space *space;
326 } apust;
327 void apu_mmio(address_map &map);
328 uint8_t minimum_grant_r() { return 1; }
329 uint8_t maximum_latency_r() { return 0xc; }
330 };
331
DECLARE_DEVICE_TYPE(MCPX_APU,mcpx_apu_device)332 DECLARE_DEVICE_TYPE(MCPX_APU, mcpx_apu_device)
333
334 /*
335 * AC97 Audio Controller
336 */
337
338 class mcpx_ac97_audio_device : public pci_device {
339 public:
340 mcpx_ac97_audio_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, uint32_t subsystem_id);
341 mcpx_ac97_audio_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
342
343 uint32_t ac97_audio_r(offs_t offset, uint32_t mem_mask = ~0);
344 void ac97_audio_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
345 uint32_t ac97_audio_io0_r();
346 void ac97_audio_io0_w(uint32_t data);
347 uint32_t ac97_audio_io1_r();
348 void ac97_audio_io1_w(uint32_t data);
349
350 protected:
351 virtual void device_start() override;
352 virtual void device_reset() override;
353
354 virtual void config_map(address_map &map) override;
355
356 private:
357 struct ac97_state {
358 uint32_t mixer_regs[0x84 / 4];
359 uint32_t controller_regs[0x40 / 4];
360 } ac97st;
361 void ac97_mmio(address_map &map);
362 void ac97_io0(address_map &map);
363 void ac97_io1(address_map &map);
364 uint8_t minimum_grant_r() { return 2; }
365 uint8_t maximum_latency_r() { return 5; }
366 };
367
DECLARE_DEVICE_TYPE(MCPX_AC97_AUDIO,mcpx_ac97_audio_device)368 DECLARE_DEVICE_TYPE(MCPX_AC97_AUDIO, mcpx_ac97_audio_device)
369
370 /*
371 * AC97 Modem Controller
372 */
373
374 class mcpx_ac97_modem_device : public pci_device {
375 public:
376 mcpx_ac97_modem_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
377 };
378
DECLARE_DEVICE_TYPE(MCPX_AC97_MODEM,mcpx_ac97_modem_device)379 DECLARE_DEVICE_TYPE(MCPX_AC97_MODEM, mcpx_ac97_modem_device)
380
381 /*
382 * IDE Controller
383 */
384
385 class mcpx_ide_device : public pci_device {
386 public:
387 mcpx_ide_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, uint32_t subsystem_id);
388 mcpx_ide_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
389
390 auto pri_interrupt_handler() { return m_pri_interrupt_handler.bind(); }
391 auto sec_interrupt_handler() { return m_sec_interrupt_handler.bind(); }
392
393 void class_rev_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
394 uint8_t pri_read_cs1_r();
395 void pri_write_cs1_w(uint8_t data);
396 uint8_t sec_read_cs1_r();
397 void sec_write_cs1_w(uint8_t data);
398
399 protected:
400 virtual void device_start() override;
401 virtual void device_reset() override;
402 virtual void device_add_mconfig(machine_config &config) override;
403 virtual void map_extra(uint64_t memory_window_start, uint64_t memory_window_end, uint64_t memory_offset, address_space *memory_space,
404 uint64_t io_window_start, uint64_t io_window_end, uint64_t io_offset, address_space *io_space) override;
405
406 virtual void config_map(address_map &map) override;
407
408 private:
409 required_device<bus_master_ide_controller_device> m_pri;
410 required_device<bus_master_ide_controller_device> m_sec;
411 devcb_write_line m_pri_interrupt_handler;
412 devcb_write_line m_sec_interrupt_handler;
413 void ide_pri_command(address_map &map);
414 void ide_pri_control(address_map &map);
415 void ide_sec_command(address_map &map);
416 void ide_sec_control(address_map &map);
417 void ide_io(address_map &map);
418 DECLARE_WRITE_LINE_MEMBER(ide_pri_interrupt);
419 DECLARE_WRITE_LINE_MEMBER(ide_sec_interrupt);
420 uint8_t minimum_grant_r() { return 3; }
421 uint8_t maximum_latency_r() { return 1; }
422 };
423
DECLARE_DEVICE_TYPE(MCPX_IDE,mcpx_ide_device)424 DECLARE_DEVICE_TYPE(MCPX_IDE, mcpx_ide_device)
425
426
427 /*
428 * AGP Bridge
429 */
430
431 class nv2a_agp_device : public agp_bridge_device {
432 public:
433 nv2a_agp_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, uint32_t main_id, uint32_t revision)
434 : nv2a_agp_device(mconfig, tag, owner, clock)
435 {
436 set_ids_bridge(main_id, revision);
437 }
438 nv2a_agp_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
439
440 void config_map(address_map& map) override;
441
442 uint32_t unknown_r(offs_t offset, uint32_t mem_mask = ~0);
443 void unknown_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
444
445 protected:
446 virtual void device_start() override;
447 virtual void device_reset() override;
448 };
449
DECLARE_DEVICE_TYPE(NV2A_AGP,nv2a_agp_device)450 DECLARE_DEVICE_TYPE(NV2A_AGP, nv2a_agp_device)
451
452 /*
453 * NV2A 3D Accelerator
454 */
455
456 class nv2a_gpu_device : public agp_device {
457 public:
458 template <typename T>
459 nv2a_gpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&cpu_tag)
460 : nv2a_gpu_device(mconfig, tag, owner, clock)
461 {
462 set_cpu_tag(std::forward<T>(cpu_tag));
463 }
464 nv2a_gpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
465 template <typename T> void set_cpu_tag(T &&cpu_tag) { cpu.set_tag(std::forward<T>(cpu_tag)); }
466 nv2a_renderer *debug_get_renderer() { return nvidia_nv2a; }
467
468 auto interrupt_handler() { return m_interrupt_handler.bind(); }
469
470 uint32_t geforce_r(offs_t offset, uint32_t mem_mask = ~0);
471 void geforce_w(address_space &space, offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
472 uint32_t nv2a_mirror_r(offs_t offset, uint32_t mem_mask = ~0);
473 void nv2a_mirror_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
474
475 protected:
476 virtual void device_start() override;
477 virtual void device_reset() override;
478
479 private:
480 nv2a_renderer *nvidia_nv2a;
481 required_device<device_memory_interface> cpu;
482 devcb_write_line m_interrupt_handler;
483 address_space *m_program;
484 void nv2a_mmio(address_map &map);
485 void nv2a_mirror(address_map &map);
486 };
487
488 DECLARE_DEVICE_TYPE(NV2A_GPU, nv2a_gpu_device)
489
490 #endif // MAME_INCLUDES_XBOX_PCI_H
491