diff options
-rw-r--r-- | src/devices/cpu/i386/athlon.cpp | 41 | ||||
-rw-r--r-- | src/devices/cpu/i386/athlon.h | 3 | ||||
-rw-r--r-- | src/mame/pc/nforcepc.cpp | 42 | ||||
-rw-r--r-- | src/mame/pc/nforcepc.h | 4 | ||||
-rw-r--r-- | src/mame/shared/xbox.cpp | 12 | ||||
-rw-r--r-- | src/mame/shared/xbox.h | 3 | ||||
-rw-r--r-- | src/mame/shared/xbox_nv2a.cpp | 1 | ||||
-rw-r--r-- | src/mame/shared/xbox_nv2a.h | 1 | ||||
-rw-r--r-- | src/mame/shared/xbox_pci.cpp | 214 | ||||
-rw-r--r-- | src/mame/shared/xbox_pci.h | 80 |
10 files changed, 375 insertions, 26 deletions
diff --git a/src/devices/cpu/i386/athlon.cpp b/src/devices/cpu/i386/athlon.cpp index dddfa80fa35..947b9a3868f 100644 --- a/src/devices/cpu/i386/athlon.cpp +++ b/src/devices/cpu/i386/athlon.cpp @@ -32,7 +32,7 @@ void athlonxp_device::device_start() space(AS_OPCODES).specific(m_opcodes); space(AS_DATA).cache(mmacache32); - space(AS_OPCODES).install_read_handler(0, 0xffffffff, read32sm_delegate(*this, FUNC(athlonxp_device::debug_read_memory))); + space(AS_OPCODES).install_readwrite_handler(0, 0xffffffff, read32s_delegate(*this, FUNC(athlonxp_device::debug_read_memory)), write32s_delegate(*this, FUNC(athlonxp_device::debug_write_memory))); build_x87_opcode_table(); build_opcode_table(OP_I386 | OP_FPU | OP_I486 | OP_PENTIUM | OP_PPRO | OP_MMX | OP_SSE); @@ -188,7 +188,7 @@ int athlonxp_device::address_mode(offs_t address) return 1; } -u32 athlonxp_device::debug_read_memory(offs_t offset) +u32 athlonxp_device::debug_read_memory(offs_t offset, u32 mask) { offs_t address = offset << 2; int mode = check_cacheable(address); @@ -204,11 +204,42 @@ u32 athlonxp_device::debug_read_memory(offs_t offset) int offset = (address & 63); data = cache.search<CacheRead>(address); if (data) - return *(u32 *)(data + offset); + return *(u32 *)(data + offset) & mask; } + // if the address is not cached, the state of the cache is not modified if (address_mode<1>(address)) - return m_data.read_dword(address); - return m_program->read_dword(address); + return m_data.read_dword(address) & mask; + return m_program->read_dword(address) & mask; +} + +void athlonxp_device::debug_write_memory(offs_t offset, uint32_t value, uint32_t mask) +{ + offs_t address = offset << 2; + int mode = check_cacheable(address); + bool nocache = false; + u8 *data; + + if ((mode & 7) == 0) + nocache = true; + if (mode & 1) + nocache = true; + if (nocache == false) + { + int offset = (address & 63); + data = cache.search<CacheWrite>(address); + // if the address is cached, the only change is that + // the relative cacheline is set as dirty and its contents modified + if (data) + { + *(u32 *)(data + offset) = (*(u32 *)(data + offset) & ~mask) | (value & mask); + return; + } + } + // if the address is not cached, the state of the cache is not modified + if (address_mode<1>(address)) + m_data.write_dword(address, value, mask); + else + m_program->write_dword(address, value, mask); } template <class dt, offs_t xorle> diff --git a/src/devices/cpu/i386/athlon.h b/src/devices/cpu/i386/athlon.h index 69cc6d84794..9d7acbbe6da 100644 --- a/src/devices/cpu/i386/athlon.h +++ b/src/devices/cpu/i386/athlon.h @@ -52,7 +52,8 @@ private: uint32_t program_read_cache(offs_t address, uint32_t mask); void program_write_cache(offs_t address, uint32_t data, uint32_t mask); - u32 debug_read_memory(offs_t offset); + u32 debug_read_memory(offs_t offset, u32 mask); + void debug_write_memory(offs_t offset, uint32_t value, uint32_t mask); address_space_config m_data_config; address_space_config m_opcodes_config; diff --git a/src/mame/pc/nforcepc.cpp b/src/mame/pc/nforcepc.cpp index 75062287e2c..0f4bd4c53c9 100644 --- a/src/mame/pc/nforcepc.cpp +++ b/src/mame/pc/nforcepc.cpp @@ -33,6 +33,7 @@ #include "bus/rs232/terminal.h" #include "cpu/i386/athlon.h" #include "machine/pci-ide.h" +#include "bus/isa/isa.h" #include "video/virge_pci.h" @@ -598,7 +599,10 @@ void it8703f_device::write_fdd_configuration_register(int index, int data) } } if (index == 0x74) + { + assign_dma_channels(); logerror("Set FDD dma channel %d\n", configuration_registers[LogicalDevice::FDC][0x74]); + } } void it8703f_device::write_parallel_configuration_register(int index, int data) @@ -624,7 +628,10 @@ void it8703f_device::write_parallel_configuration_register(int index, int data) } } if (index == 0x74) + { + assign_dma_channels(); logerror("Set LPT dma channel %d\n", configuration_registers[LogicalDevice::Parallel][0x74]); + } } void it8703f_device::write_serial1_configuration_register(int index, int data) @@ -1030,10 +1037,39 @@ void it8703f_device::map_extra(address_space *memory_space, address_space *io_sp map_keyboard_addresses(); } -void it8703f_device::set_host(int index, lpcbus_host_interface *host) +void it8703f_device::set_host(int device_index, lpcbus_host_interface *host) { lpchost = host; - lpcindex = index; + lpcindex = device_index; + lpchost->assign_virtual_line(24 + configuration_registers[LogicalDevice::FDC][0x74], lpcindex); + lpchost->assign_virtual_line(24 + configuration_registers[LogicalDevice::Parallel][0x74], lpcindex); +} + +uint32_t it8703f_device::dma_transfer(int channel, dma_operation operation, dma_size size, uint32_t data) +{ + uint32_t ret = 0; + + if (enabled_logical[LogicalDevice::FDC] == true) + if (channel == configuration_registers[LogicalDevice::FDC][0x74]) + { + if (operation == dma_operation::WRITE) + ret = (uint32_t)floppy_controller_fdcdev->dma_r(); + else if (operation == dma_operation::READ) + floppy_controller_fdcdev->dma_w((uint8_t)data); + else if (operation == dma_operation::END) + floppy_controller_fdcdev->tc_w(data == ASSERT_LINE); + } + if (enabled_logical[LogicalDevice::Parallel] == true) + if (channel == configuration_registers[LogicalDevice::Parallel][0x74]) + printf("it8703f_device::dma_transfer LPT channel %d op %d size %d\n", channel, (int)operation, (int)size); + return ret; +} + +void it8703f_device::assign_dma_channels() +{ + lpchost->assign_virtual_line(-1, lpcindex); // remove assigments + lpchost->assign_virtual_line(24 + configuration_registers[LogicalDevice::FDC][0x74], lpcindex); + lpchost->assign_virtual_line(24 + configuration_registers[LogicalDevice::Parallel][0x74], lpcindex); } /* @@ -1171,6 +1207,7 @@ void nforcepc_state::nforcepc(machine_config &config) isa.smi().set_inputline(":maincpu", INPUT_LINE_SMI); isa.boot_state_hook().set(FUNC(nforcepc_state::boot_state_award_w)); isa.interrupt_output().set(FUNC(nforcepc_state::maincpu_interrupt)); + isa.set_dma_space("maincpu", AS_OPCODES); it8703f_device &ite(IT8703F(config, "pci:01.0:0", 0)); ite.pin_reset().set_inputline("maincpu", INPUT_LINE_RESET); ite.pin_gatea20().set_inputline("maincpu", INPUT_LINE_A20); @@ -1199,6 +1236,7 @@ void nforcepc_state::nforcepc(machine_config &config) mcpx_ide_device &ide(MCPX_IDE(config, "pci:09.0", 0, 0x10430c11)); // 10de:01bc NVIDIA Corporation nForce IDE ide.pri_interrupt_handler().set("pci:01.0", FUNC(mcpx_isalpc_device::irq14)); ide.sec_interrupt_handler().set("pci:01.0", FUNC(mcpx_isalpc_device::irq15)); + ide.set_bus_master_space("maincpu", AS_OPCODES); ide.subdevice<ide_controller_32_device>("ide1")->options(ata_devices, "hdd", nullptr, true); ide.subdevice<ide_controller_32_device>("ide2")->options(ata_devices, "cdrom", nullptr, true); NV2A_AGP(config, "pci:1e.0", 0, 0x10de01b7, 0xb2); // 10de:01b7 NVIDIA Corporation nForce AGP to PCI Bridge diff --git a/src/mame/pc/nforcepc.h b/src/mame/pc/nforcepc.h index 7dee2c67dc1..f923d8051e9 100644 --- a/src/mame/pc/nforcepc.h +++ b/src/mame/pc/nforcepc.h @@ -190,7 +190,8 @@ class it8703f_device : public device_t, public lpcbus_device_interface public: it8703f_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); virtual void map_extra(address_space *memory_space, address_space *io_space) override; - virtual void set_host(int index, lpcbus_host_interface *host) override; + virtual void set_host(int device_index, lpcbus_host_interface *host) override; + virtual uint32_t dma_transfer(int channel, dma_operation operation, dma_size size, uint32_t data) override; virtual void device_add_mconfig(machine_config &config) override; auto pin_reset() { return pin_reset_callback.bind(); } @@ -326,6 +327,7 @@ private: uint16_t read_serial1_configuration_register(int index) { return configuration_registers[LogicalDevice::Serial1][index]; } uint16_t read_serial2_configuration_register(int index) { return configuration_registers[LogicalDevice::Serial2][index]; } uint16_t read_keyboard_configuration_register(int index) { return configuration_registers[LogicalDevice::Keyboard][index]; } + void assign_dma_channels(); }; DECLARE_DEVICE_TYPE(IT8703F, it8703f_device) diff --git a/src/mame/shared/xbox.cpp b/src/mame/shared/xbox.cpp index 4c1bd217039..5762abbc439 100644 --- a/src/mame/shared/xbox.cpp +++ b/src/mame/shared/xbox.cpp @@ -822,10 +822,16 @@ void xbox_superio_device::map_extra(address_space *memory_space, address_space * io_space->install_device(0, 0xffff, *this, &xbox_superio_device::internal_io_map); } -void xbox_superio_device::set_host(int index, lpcbus_host_interface *host) +void xbox_superio_device::set_host(int device_index, lpcbus_host_interface *host) { lpchost = host; - lpcindex = index; + lpcindex = device_index; +} + +uint32_t xbox_superio_device::dma_transfer(int channel, dma_operation operation, dma_size size, uint32_t data) +{ + logerror("LPC dma transfer attempted on channel %d\n", channel); + return 0; } void xbox_superio_device::device_start() @@ -969,6 +975,7 @@ void xbox_base_state::xbox_base(machine_config &config) NV2A_RAM(config, "pci:00.3", 0, 128); // 128 megabytes MCPX_ISALPC(config, "pci:01.0", 0, 0).interrupt_output().set(FUNC(xbox_base_state::maincpu_interrupt)); XBOX_SUPERIO(config, "pci:01.0:0", 0); + subdevice<mcpx_isalpc_device>("pci:01.0")->set_dma_space(m_maincpu, AS_PROGRAM); MCPX_SMBUS(config, "pci:01.1", 0, 0).interrupt_handler().set("pci:01.0", FUNC(mcpx_isalpc_device::irq11)); //.set(FUNC(xbox_base_state::smbus_interrupt_changed)); XBOX_PIC16LC(config, "pci:01.1:110", 0); // these 3 are on smbus number 1 XBOX_CX25871(config, "pci:01.1:145", 0); @@ -981,6 +988,7 @@ void xbox_base_state::xbox_base(machine_config &config) MCPX_AC97_MODEM(config, "pci:06.1", 0); PCI_BRIDGE(config, "pci:08.0", 0, 0x10de01b8, 0); MCPX_IDE(config, "pci:09.0", 0, 0).pri_interrupt_handler().set("pci:01.0", FUNC(mcpx_isalpc_device::irq14)); //.set(FUNC(xbox_base_state::ide_interrupt_changed)); + subdevice<mcpx_ide_device>("pci:09.0")->set_bus_master_space(m_maincpu, AS_PROGRAM); NV2A_AGP(config, "pci:1e.0", 0, 0x10de01b7, 0); NV2A_GPU(config, "pci:1e.0:00.0", 0, m_maincpu).interrupt_handler().set("pci:01.0", FUNC(mcpx_isalpc_device::irq3)); //.set(FUNC(xbox_base_state::nv2a_interrupt_changed)); diff --git a/src/mame/shared/xbox.h b/src/mame/shared/xbox.h index 94970626b0d..ddd56a441c2 100644 --- a/src/mame/shared/xbox.h +++ b/src/mame/shared/xbox.h @@ -81,7 +81,8 @@ class xbox_superio_device : public device_t, public lpcbus_device_interface public: xbox_superio_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); virtual void map_extra(address_space *memory_space, address_space *io_space) override; - virtual void set_host(int index, lpcbus_host_interface *host) override; + virtual uint32_t dma_transfer(int channel, dma_operation operation, dma_size size, uint32_t data) override; + virtual void set_host(int device_index, lpcbus_host_interface *host) override; uint8_t read(offs_t offset); void write(offs_t offset, uint8_t data); diff --git a/src/mame/shared/xbox_nv2a.cpp b/src/mame/shared/xbox_nv2a.cpp index 52e1d784df8..d299e57705e 100644 --- a/src/mame/shared/xbox_nv2a.cpp +++ b/src/mame/shared/xbox_nv2a.cpp @@ -1,7 +1,6 @@ // license:BSD-3-Clause // copyright-holders:Samuele Zannoli #include "emu.h" -#include "video/poly.h" #include "bitmap.h" #include "xbox_nv2a.h" #include <bitset> diff --git a/src/mame/shared/xbox_nv2a.h b/src/mame/shared/xbox_nv2a.h index feae8059a53..e1804d810cd 100644 --- a/src/mame/shared/xbox_nv2a.h +++ b/src/mame/shared/xbox_nv2a.h @@ -8,7 +8,6 @@ #pragma once -#include "machine/pic8259.h" #include "video/poly.h" class vertex_program_disassembler { diff --git a/src/mame/shared/xbox_pci.cpp b/src/mame/shared/xbox_pci.cpp index 23149e53e96..f6f55af9bba 100644 --- a/src/mame/shared/xbox_pci.cpp +++ b/src/mame/shared/xbox_pci.cpp @@ -8,7 +8,6 @@ #include "machine/pci.h" #include "machine/idectrl.h" -#include "machine/ds128x.h" #include <functional> @@ -106,12 +105,15 @@ void mcpx_isalpc_device::lpc_io(address_map &map) void mcpx_isalpc_device::internal_io_map(address_map &map) { + map(0x0000, 0x000f).rw("dma8237_1", FUNC(am9517a_device::read), FUNC(am9517a_device::write)); map(0x0020, 0x0023).rw("pic8259_1", FUNC(pic8259_device::read), FUNC(pic8259_device::write)); map(0x0040, 0x0043).rw("pit8254", FUNC(pit8254_device::read), FUNC(pit8254_device::write)); map(0x0061, 0x0061).rw(FUNC(mcpx_isalpc_device::portb_r), FUNC(mcpx_isalpc_device::portb_w)); map(0x0070, 0x0073).rw("rtc", FUNC(ds12885ext_device::read_extended), FUNC(ds12885ext_device::write_extended)); map(0x0080, 0x0080).w(FUNC(mcpx_isalpc_device::boot_state_w)); + map(0x0081, 0x008f).rw(FUNC(mcpx_isalpc_device::dma_page_r), FUNC(mcpx_isalpc_device::dma_page_w)); map(0x00a0, 0x00a3).rw("pic8259_2", FUNC(pic8259_device::read), FUNC(pic8259_device::write)); + map(0x00c0, 0x00df).rw(FUNC(mcpx_isalpc_device::dma2_r), FUNC(mcpx_isalpc_device::dma2_w)); map(0x00e0, 0x00e3).nopw(); } @@ -139,7 +141,10 @@ mcpx_isalpc_device::mcpx_isalpc_device(const machine_config &mconfig, const char m_boot_state_hook(*this), pic8259_1(*this, "pic8259_1"), pic8259_2(*this, "pic8259_2"), + m_dma8237_1(*this, "dma8237_1"), + m_dma8237_2(*this, "dma8237_2"), pit8254(*this, "pit8254"), + m_dma_space(*this, finder_base::DUMMY_TAG, -1, 32), m_pm1_status(0), m_pm1_enable(0), m_pm1_control(0), @@ -152,7 +157,11 @@ mcpx_isalpc_device::mcpx_isalpc_device(const machine_config &mconfig, const char m_refresh(false), m_pit_out2(0), m_spkrdata(0), - m_channel_check(0) + m_channel_check(0), + m_dma_eop(0), + m_dma_high_byte(0xff), + m_dma_channel(-1), + m_page_offset(0) { } @@ -170,6 +179,8 @@ void mcpx_isalpc_device::device_start() command_mask = 0x01be; for (int a = 0; a < 16; a++) lpcdevices[a] = nullptr; + for (int a = 0; a < 8; a++) + m_lineowners[a] = -1; for (device_t &d : subdevices()) { const char *t = d.basetag(); @@ -214,6 +225,39 @@ void mcpx_isalpc_device::device_add_mconfig(machine_config &config) pic8259_2.out_int_callback().set(pic8259_1, FUNC(pic8259_device::ir2_w)); pic8259_2.in_sp_callback().set_constant(0); + am9517a_device &dma8237_2(AM9517A(config, "dma8237_2", XTAL(14'318'181) / 3)); + dma8237_2.out_hreq_callback().set(FUNC(mcpx_isalpc_device::dma2_hreq_w)); + dma8237_2.in_memr_callback().set(FUNC(mcpx_isalpc_device::dma_read_word)); + dma8237_2.out_memw_callback().set(FUNC(mcpx_isalpc_device::dma_write_word)); + dma8237_2.in_ior_callback<1>().set(FUNC(mcpx_isalpc_device::dma2_ior1_r)); + dma8237_2.in_ior_callback<2>().set(FUNC(mcpx_isalpc_device::dma2_ior2_r)); + dma8237_2.in_ior_callback<3>().set(FUNC(mcpx_isalpc_device::dma2_ior3_r)); + dma8237_2.out_iow_callback<1>().set(FUNC(mcpx_isalpc_device::dma2_iow1_w)); + dma8237_2.out_iow_callback<2>().set(FUNC(mcpx_isalpc_device::dma2_iow2_w)); + dma8237_2.out_iow_callback<3>().set(FUNC(mcpx_isalpc_device::dma2_iow3_w)); + dma8237_2.out_dack_callback<0>().set(FUNC(mcpx_isalpc_device::dma2_dack0_w)); + dma8237_2.out_dack_callback<1>().set(FUNC(mcpx_isalpc_device::dma2_dack1_w)); + dma8237_2.out_dack_callback<2>().set(FUNC(mcpx_isalpc_device::dma2_dack2_w)); + dma8237_2.out_dack_callback<3>().set(FUNC(mcpx_isalpc_device::dma2_dack3_w)); + + am9517a_device &dma8237_1(AM9517A(config, "dma8237_1", XTAL(14'318'181) / 3)); + dma8237_1.out_hreq_callback().set(dma8237_2, FUNC(am9517a_device::dreq0_w)); + dma8237_1.out_eop_callback().set(FUNC(mcpx_isalpc_device::dma1_eop_w)); + dma8237_1.in_memr_callback().set(FUNC(mcpx_isalpc_device::dma_read_byte)); + dma8237_1.out_memw_callback().set(FUNC(mcpx_isalpc_device::dma_write_byte)); + dma8237_1.in_ior_callback<0>().set(FUNC(mcpx_isalpc_device::dma1_ior0_r)); + dma8237_1.in_ior_callback<1>().set(FUNC(mcpx_isalpc_device::dma1_ior1_r)); + dma8237_1.in_ior_callback<2>().set(FUNC(mcpx_isalpc_device::dma1_ior2_r)); + dma8237_1.in_ior_callback<3>().set(FUNC(mcpx_isalpc_device::dma1_ior3_r)); + dma8237_1.out_iow_callback<0>().set(FUNC(mcpx_isalpc_device::dma1_iow0_w)); + dma8237_1.out_iow_callback<1>().set(FUNC(mcpx_isalpc_device::dma1_iow1_w)); + dma8237_1.out_iow_callback<2>().set(FUNC(mcpx_isalpc_device::dma1_iow2_w)); + dma8237_1.out_iow_callback<3>().set(FUNC(mcpx_isalpc_device::dma1_iow3_w)); + dma8237_1.out_dack_callback<0>().set(FUNC(mcpx_isalpc_device::dma1_dack0_w)); + dma8237_1.out_dack_callback<1>().set(FUNC(mcpx_isalpc_device::dma1_dack1_w)); + dma8237_1.out_dack_callback<2>().set(FUNC(mcpx_isalpc_device::dma1_dack2_w)); + dma8237_1.out_dack_callback<3>().set(FUNC(mcpx_isalpc_device::dma1_dack3_w)); + pit8254_device &pit8254(PIT8254(config, "pit8254", 0)); pit8254.set_clk<0>(1125000); /* heartbeat IRQ */ pit8254.out_handler<0>().set(FUNC(mcpx_isalpc_device::pit8254_out0_changed)); @@ -226,9 +270,8 @@ void mcpx_isalpc_device::device_add_mconfig(machine_config &config) ds12885.irq().set(pic8259_2, FUNC(pic8259_device::ir0_w)); /* - More devices are needed: + More devices needed: 82093 compatible I/O APIC - dual 8237 DMA controllers */ } @@ -413,6 +456,7 @@ void mcpx_isalpc_device::debug_generate_irq(int irq, int state) void mcpx_isalpc_device::set_virtual_line(int line, int state) { + // support up to 16 irq lines if (line < 16) { switch (line) @@ -465,23 +509,175 @@ void mcpx_isalpc_device::set_virtual_line(int line, int state) } return; } -/* Will be updated to support dma + // support up to 8 drq lines line = line - 16; - if (line < 4) + if (line < 8) { switch (line) { case 0: + m_dma8237_1->dreq0_w(state); break; case 1: + m_dma8237_1->dreq1_w(state); break; case 2: + m_dma8237_1->dreq2_w(state); break; case 3: + m_dma8237_1->dreq3_w(state); break; - } + case 5: + m_dma8237_2->dreq1_w(state); + break; + case 6: + m_dma8237_2->dreq2_w(state); + break; + case 7: + m_dma8237_2->dreq3_w(state); + break; + } } -*/ + // next would be the 8 dack lines + line = line - 8; +} + +void mcpx_isalpc_device::assign_virtual_line(int line, int device_index) +{ + if (line == -1) + { + for (int a = 0; a < 8; a++) + if (m_lineowners[a] == device_index) + m_lineowners[a] = -1; + return; + } + if (line < 24) + return; + line = line - 24; + m_lineowners[line] = device_index; // dma dreq line/channel "line" used by lpc device "device_index" +} + +void mcpx_isalpc_device::set_dma_channel(int channel, bool state) +{ + if (!state) // dack line low + { + m_dma_channel = channel; + switch (m_dma_channel) + { + case 0: + m_page_offset = (offs_t)m_dma_page[0x07] << 16; + break; + case 1: + m_page_offset = (offs_t)m_dma_page[0x03] << 16; + break; + case 2: + m_page_offset = (offs_t)m_dma_page[0x01] << 16; + break; + case 3: + m_page_offset = (offs_t)m_dma_page[0x02] << 16; + break; + case 5: + m_page_offset = (offs_t)m_dma_page[0x0b] << 16; + break; + case 6: + m_page_offset = (offs_t)m_dma_page[0x09] << 16; + break; + case 7: + m_page_offset = (offs_t)m_dma_page[0x0a] << 16; + break; + } + if (m_dma_eop) + signal_dma_end(channel, 1); // ASSERT_LINE + } + else // dack line high + { + if (m_dma_channel == channel) + { + m_dma_channel = -1; + if (m_dma_eop) + signal_dma_end(channel, 0); + } + } +} + +void mcpx_isalpc_device::send_dma_byte(int channel, uint8_t value) +{ + lpcbus_device_interface *dev = lpcdevices[m_lineowners[channel]]; + + dev->dma_transfer(channel, lpcbus_device_interface::dma_operation::READ, lpcbus_device_interface::dma_size::BYTE, value); +} + +void mcpx_isalpc_device::send_dma_word(int channel, uint16_t value) +{ + lpcbus_device_interface *dev = lpcdevices[m_lineowners[channel]]; + + dev->dma_transfer(channel, lpcbus_device_interface::dma_operation::READ, lpcbus_device_interface::dma_size::WORD, value); +} + +uint8_t mcpx_isalpc_device::get_dma_byte(int channel) +{ + lpcbus_device_interface *dev = lpcdevices[m_lineowners[channel]]; + + return (uint8_t)dev->dma_transfer(channel, lpcbus_device_interface::dma_operation::WRITE, lpcbus_device_interface::dma_size::BYTE, 0); +} + +uint16_t mcpx_isalpc_device::get_dma_word(int channel) +{ + lpcbus_device_interface *dev = lpcdevices[m_lineowners[channel]]; + + return (uint16_t)dev->dma_transfer(channel, lpcbus_device_interface::dma_operation::WRITE, lpcbus_device_interface::dma_size::WORD, 0); +} + +void mcpx_isalpc_device::signal_dma_end(int channel, int tc) +{ + lpcbus_device_interface *dev = lpcdevices[m_lineowners[channel]]; + + dev->dma_transfer(channel, lpcbus_device_interface::dma_operation::END, lpcbus_device_interface::dma_size::BYTE, tc); +} + +uint8_t mcpx_isalpc_device::dma_page_r(offs_t offset) +{ + return m_dma_page[offset + 1]; +} + +void mcpx_isalpc_device::dma_page_w(offs_t offset, uint8_t data) +{ + m_dma_page[offset + 1] = data; +} + +uint8_t mcpx_isalpc_device::dma_read_byte(offs_t offset) +{ + if (m_dma_channel == -1) + return 0xff; + + return m_dma_space->read_byte(m_page_offset + offset); +} + +void mcpx_isalpc_device::dma_write_byte(offs_t offset, uint8_t data) +{ + if (m_dma_channel == -1) + return; + + m_dma_space->write_byte(m_page_offset + offset, data); +} + +uint8_t mcpx_isalpc_device::dma_read_word(offs_t offset) +{ + if (m_dma_channel == -1) + return 0xff; + + uint16_t result = m_dma_space->read_word((m_page_offset & 0xfe0000) | (offset << 1)); + m_dma_high_byte = result >> 8; + + return result; +} + +void mcpx_isalpc_device::dma_write_word(offs_t offset, uint8_t data) +{ + if (m_dma_channel == -1) + return; + + m_dma_space->write_word((m_page_offset & 0xfe0000) | (offset << 1), (m_dma_high_byte << 8) | data); } void mcpx_isalpc_device::remap() @@ -1246,11 +1442,9 @@ void mcpx_ide_device::device_add_mconfig(machine_config &config) { bus_master_ide_controller_device &ide1(BUS_MASTER_IDE_CONTROLLER(config, "ide1", 0)); ide1.irq_handler().set(FUNC(mcpx_ide_device::ide_pri_interrupt)); - ide1.set_bus_master_space(":maincpu", AS_PROGRAM); bus_master_ide_controller_device &ide2(BUS_MASTER_IDE_CONTROLLER(config, "ide2", 0)); ide2.irq_handler().set(FUNC(mcpx_ide_device::ide_sec_interrupt)); - ide2.set_bus_master_space(":maincpu", AS_PROGRAM); } void mcpx_ide_device::map_extra(uint64_t memory_window_start, uint64_t memory_window_end, uint64_t memory_offset, address_space *memory_space, diff --git a/src/mame/shared/xbox_pci.h b/src/mame/shared/xbox_pci.h index 23c1cb43c37..d8b64e33543 100644 --- a/src/mame/shared/xbox_pci.h +++ b/src/mame/shared/xbox_pci.h @@ -10,7 +10,10 @@ #include "machine/pci.h" #include "machine/pci-ide.h" +#include "machine/pic8259.h" #include "machine/pit8253.h" +#include "machine/ds128x.h" +#include "machine/am9517a.h" /* * Host @@ -78,19 +81,33 @@ DECLARE_DEVICE_TYPE(NV2A_RAM, nv2a_ram_device) class lpcbus_host_interface { public: virtual void set_virtual_line(int line, int state) = 0; + virtual void assign_virtual_line(int line, int device_index) = 0; virtual void remap() = 0; }; class lpcbus_device_interface { public: + enum class dma_operation { + READ = 1, + WRITE = 2, + END = 4 + }; + enum class dma_size { + BYTE = 1, + WORD = 2, + DWORD = 4 + }; virtual void map_extra(address_space *memory_space, address_space *io_space) = 0; - virtual void set_host(int index, lpcbus_host_interface *host) = 0; + virtual void set_host(int device_index, lpcbus_host_interface *host) = 0; + virtual uint32_t dma_transfer(int channel, dma_operation operation, dma_size size, uint32_t data) = 0; }; class mcpx_isalpc_device : public pci_device, public lpcbus_host_interface { public: mcpx_isalpc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, uint32_t subsystem_id); mcpx_isalpc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + template <typename T> void set_dma_space(T &&bmtag, int bmspace) { m_dma_space.set_tag(std::forward<T>(bmtag), bmspace); } + template <bool R> void set_dma_space(const address_space_finder<R> &finder) { m_dma_space.set_tag(finder); } auto smi() { return m_smi_callback.bind(); } auto interrupt_output() { return m_interrupt_output.bind(); } @@ -100,18 +117,58 @@ public: void debug_generate_irq(int irq, int state); virtual void set_virtual_line(int line, int state) override; + virtual void assign_virtual_line(int line, int device_index) override; virtual void remap() override; uint32_t acpi_r(offs_t offset, uint32_t mem_mask = ~0); void acpi_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); void boot_state_w(uint8_t data); + uint8_t dma_page_r(offs_t offset); + void dma_page_w(offs_t offset, uint8_t data); + uint8_t dma_read_byte(offs_t offset); + void dma_write_byte(offs_t offset, uint8_t data); + uint8_t dma_read_word(offs_t offset); + void dma_write_word(offs_t offset, uint8_t data); + void set_dma_channel(int channel, bool state); + void send_dma_byte(int channel, uint8_t value); + void send_dma_word(int channel, uint16_t value); + uint8_t get_dma_byte(int channel); + uint16_t get_dma_word(int channel); + void signal_dma_end(int channel, int tc); + uint8_t dma2_r(offs_t offset) { return m_dma8237_2->read(offset / 2); } + void dma2_w(offs_t offset, uint8_t data) { m_dma8237_2->write(offset / 2, data); } + uint8_t dma1_ior0_r() { return get_dma_byte(0); } + uint8_t dma1_ior1_r() { return get_dma_byte(1); } + uint8_t dma1_ior2_r() { return get_dma_byte(2); } + uint8_t dma1_ior3_r() { return get_dma_byte(3); } + uint8_t dma2_ior1_r() { uint16_t const result = get_dma_word(5); m_dma_high_byte = result >> 8; return result; } + uint8_t dma2_ior2_r() { uint16_t const result = get_dma_word(6); m_dma_high_byte = result >> 8; return result; } + uint8_t dma2_ior3_r() { uint16_t const result = get_dma_word(7); m_dma_high_byte = result >> 8; return result; } + void dma1_iow0_w(uint8_t data) { send_dma_byte(0, data); } + void dma1_iow1_w(uint8_t data) { send_dma_byte(1, data); } + void dma1_iow2_w(uint8_t data) { send_dma_byte(2, data); } + void dma1_iow3_w(uint8_t data) { send_dma_byte(3, data); } + void dma2_iow1_w(uint8_t data) { send_dma_word(5, (m_dma_high_byte << 8) | data); } + void dma2_iow2_w(uint8_t data) { send_dma_word(6, (m_dma_high_byte << 8) | data); } + void dma2_iow3_w(uint8_t data) { send_dma_word(7, (m_dma_high_byte << 8) | data); } + DECLARE_WRITE_LINE_MEMBER(irq1); DECLARE_WRITE_LINE_MEMBER(irq3); DECLARE_WRITE_LINE_MEMBER(irq11); DECLARE_WRITE_LINE_MEMBER(irq10); DECLARE_WRITE_LINE_MEMBER(irq14); DECLARE_WRITE_LINE_MEMBER(irq15); + DECLARE_WRITE_LINE_MEMBER(dma2_hreq_w) { m_dma8237_2->hack_w(state); } + DECLARE_WRITE_LINE_MEMBER(dma1_eop_w) { m_dma_eop = state; if (m_dma_channel != -1) signal_dma_end(m_dma_channel, state & 1); } + DECLARE_WRITE_LINE_MEMBER(dma1_dack0_w) { set_dma_channel(0, state); } + DECLARE_WRITE_LINE_MEMBER(dma1_dack1_w) { set_dma_channel(1, state); } + DECLARE_WRITE_LINE_MEMBER(dma1_dack2_w) { set_dma_channel(2, state); } + DECLARE_WRITE_LINE_MEMBER(dma1_dack3_w) { set_dma_channel(3, state); } + DECLARE_WRITE_LINE_MEMBER(dma2_dack0_w) { m_dma8237_1->hack_w(state ? 0 : 1); } + DECLARE_WRITE_LINE_MEMBER(dma2_dack1_w) { set_dma_channel(5, state); } + DECLARE_WRITE_LINE_MEMBER(dma2_dack2_w) { set_dma_channel(6, state); } + DECLARE_WRITE_LINE_MEMBER(dma2_dack3_w) { set_dma_channel(7, state); } protected: virtual void device_start() override; @@ -120,8 +177,8 @@ protected: 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; - DECLARE_WRITE_LINE_MEMBER(interrupt_ouptut_changed); uint8_t get_slave_ack(offs_t offset); + DECLARE_WRITE_LINE_MEMBER(interrupt_ouptut_changed); DECLARE_WRITE_LINE_MEMBER(pit8254_out0_changed); DECLARE_WRITE_LINE_MEMBER(pit8254_out1_changed); DECLARE_WRITE_LINE_MEMBER(pit8254_out2_changed); @@ -140,7 +197,10 @@ private: devcb_write8 m_boot_state_hook; required_device<pic8259_device> pic8259_1; required_device<pic8259_device> pic8259_2; + required_device<am9517a_device> m_dma8237_1; + required_device<am9517a_device> m_dma8237_2; required_device<pit8254_device> pit8254; + required_address_space m_dma_space; uint16_t m_pm1_status; uint16_t m_pm1_enable; @@ -152,11 +212,17 @@ private: uint8_t m_smi_command_port; uint8_t m_gpio_mode[26]; lpcbus_device_interface *lpcdevices[16]; + int m_lineowners[8]; uint8_t m_speaker; bool m_refresh; uint8_t m_pit_out2; uint8_t m_spkrdata; uint8_t m_channel_check; + int m_dma_eop; + uint8_t m_dma_page[0x10]; + uint8_t m_dma_high_byte; + int m_dma_channel; + offs_t m_page_offset; }; DECLARE_DEVICE_TYPE(MCPX_ISALPC, mcpx_isalpc_device) @@ -391,6 +457,16 @@ class mcpx_ide_device : public pci_device { public: mcpx_ide_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, uint32_t subsystem_id); mcpx_ide_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + template <typename T> void set_bus_master_space(T &&bmtag, int bmspace) + { + subdevice<bus_master_ide_controller_device>(m_pri.finder_tag())->set_bus_master_space(bmtag, bmspace); + subdevice<bus_master_ide_controller_device>(m_sec.finder_tag())->set_bus_master_space(bmtag, bmspace); + } + template <bool R> void set_bus_master_space(const address_space_finder<R> &finder) + { + subdevice<bus_master_ide_controller_device>(m_pri.finder_tag())->set_bus_master_space(finder); + subdevice<bus_master_ide_controller_device>(m_sec.finder_tag())->set_bus_master_space(finder); + } auto pri_interrupt_handler() { return m_pri_interrupt_handler.bind(); } auto sec_interrupt_handler() { return m_sec_interrupt_handler.bind(); } |