diff options
author | 2023-03-11 18:56:19 +0100 | |
---|---|---|
committer | 2023-03-13 21:29:37 +0100 | |
commit | 5a5fcd6670c97b83c545877ead11f61b9c9ce8f0 (patch) | |
tree | 3c26cd27294d6025e2a1df8771e3833843e83c88 /src | |
parent | 2461397c80a126d2c689278d3ab30097561acaf5 (diff) |
nforcepc: make required changes to let it boot from floppy disk
The pci devices shared with the xbox have been updated to support dma on
the lpc bus.
The athlon processor has been updated to support writes in the
as_opcodes space.
Diffstat (limited to 'src')
-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(); } |