summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--src/devices/cpu/i386/athlon.cpp41
-rw-r--r--src/devices/cpu/i386/athlon.h3
-rw-r--r--src/mame/pc/nforcepc.cpp42
-rw-r--r--src/mame/pc/nforcepc.h4
-rw-r--r--src/mame/shared/xbox.cpp12
-rw-r--r--src/mame/shared/xbox.h3
-rw-r--r--src/mame/shared/xbox_nv2a.cpp1
-rw-r--r--src/mame/shared/xbox_nv2a.h1
-rw-r--r--src/mame/shared/xbox_pci.cpp214
-rw-r--r--src/mame/shared/xbox_pci.h80
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(); }