summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/pci/trident_4dwavedx.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bus/pci/trident_4dwavedx.cpp')
-rw-r--r--src/devices/bus/pci/trident_4dwavedx.cpp189
1 files changed, 189 insertions, 0 deletions
diff --git a/src/devices/bus/pci/trident_4dwavedx.cpp b/src/devices/bus/pci/trident_4dwavedx.cpp
new file mode 100644
index 00000000000..4dc92d1968a
--- /dev/null
+++ b/src/devices/bus/pci/trident_4dwavedx.cpp
@@ -0,0 +1,189 @@
+// license:BSD-3-Clause
+// copyright-holders:
+/**************************************************************************************************
+
+Trident 4DWAVE-DX
+
+AC'97 v1.x (fixed 48 kHz)
+
+TODO:
+- win98se throws a BSoD 0e (page fault) on "Trident Legacy Audio" installation;
+- non-working in DOS beyond basic PCI identification
+ i.e. wants SB emulation in MS-DOS 7, in turn can't set proper interrupt line (goes BLASTER=I255)
+
+**************************************************************************************************/
+
+#include "emu.h"
+#include "trident_4dwavedx.h"
+
+#define VERBOSE (LOG_GENERAL)
+//#define LOG_OUTPUT_FUNC osd_printf_info
+
+#include "logmacro.h"
+
+
+DEFINE_DEVICE_TYPE(TRIDENT_4DWAVEDX, trident_4dwavedx_device, "trident_4dwavedx", "Trident 4D Wave-DX sound card")
+
+
+trident_4dwavedx_device::trident_4dwavedx_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
+ : pci_card_device(mconfig, type, tag, owner, clock)
+{
+}
+
+trident_4dwavedx_device::trident_4dwavedx_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : trident_4dwavedx_device(mconfig, TRIDENT_4DWAVEDX, tag, owner, clock)
+{
+ set_ids(0x10232000, 0x00, 0x040100, 0x10232000);
+}
+
+void trident_4dwavedx_device::device_add_mconfig(machine_config &config)
+{
+ // TODO: SigmaTel STAC9704T or STAC9700T
+}
+
+void trident_4dwavedx_device::device_start()
+{
+ pci_card_device::device_start();
+
+ add_map( 256, M_IO, FUNC(trident_4dwavedx_device::io_map));
+ add_map( 4*1024, M_MEM, FUNC(trident_4dwavedx_device::mmio_map));
+
+ // INTA#
+ intr_pin = 1;
+ intr_line = 0x00;
+
+ // TODO: max_lat = 0x05, min_gnt = 0x02
+
+ save_item(NAME(m_ddma_config));
+ save_item(NAME(m_legacy_control));
+ save_item(NAME(m_power_state));
+ save_item(STRUCT_MEMBER(m_interrupt_snoop, enable));
+ save_item(STRUCT_MEMBER(m_interrupt_snoop, vector));
+
+ save_item(NAME(m_asr4));
+ save_item(NAME(m_asr5));
+ save_item(NAME(m_asr6));
+}
+
+void trident_4dwavedx_device::device_reset()
+{
+ pci_card_device::device_reset();
+
+ command = 0x0000;
+ command_mask = 7;
+ // Medium DEVSEL#, support cap list
+ status = 0x0210;
+
+ m_ddma_config = m_legacy_control = 0;
+ m_power_state = 0;
+ m_interrupt_snoop.enable = false;
+ m_interrupt_snoop.vector = 0;
+
+ m_asr4 = 0;
+ m_asr5 = 0x04;
+ m_asr6 = 0x02;
+
+ remap_cb();
+}
+
+u8 trident_4dwavedx_device::capptr_r()
+{
+ return 0x48;
+}
+
+void trident_4dwavedx_device::config_map(address_map &map)
+{
+ pci_card_device::config_map(map);
+ // DDMA config
+ map(0x40, 0x43).lrw32(
+ NAME([this] (offs_t offset, u32 mem_mask) {
+ LOG("PCI 40h: DDMA config read (mask %08x)\n", mem_mask);
+ return m_ddma_config;
+ }),
+ NAME([this] (offs_t offset, u32 data, u32 mem_mask) {
+ COMBINE_DATA(&m_ddma_config);
+ // knock off Legacy DMA Transfer Size Control
+ m_ddma_config &= ~(3 << 1);
+ LOG("PCI 40h: %08x & %08x\n", data, mem_mask);
+ LOG("\tDDMA config write: address %08x Extended Address %d Slave Channel Access %d\n"
+ , m_ddma_config >> 4, BIT(m_ddma_config, 3), BIT(m_ddma_config, 0));
+ })
+ );
+// map(0x44, 0x44) Legacy I/O Base
+// map(0x45, 0x45) Legacy DMA
+// map(0x46, 0x46) Legacy Control
+ map(0x44, 0x47).lrw32(
+ NAME([this] (offs_t offset, u32 mem_mask) {
+ LOG("PCI 44h: legacy control read (mask %08x)\n", mem_mask);
+ return m_legacy_control;
+ }),
+ NAME([this] (offs_t offset, u32 data, u32 mem_mask) {
+ COMBINE_DATA(&m_legacy_control);
+ m_legacy_control &= 0x0006'03ff;
+ LOG("PCI 44h: %08x & %08x\n", data, mem_mask);
+ LOG("\tLegacy I/O base: %02x Legacy DMA: %02x Audio Engine Reset: %d Writable subsystem %d\n"
+ , m_legacy_control & 0xff
+ , (m_legacy_control >> 8) & 3
+ , BIT(m_legacy_control, 18)
+ , BIT(m_legacy_control, 17)
+ );
+ })
+ );
+
+ // Power Management v1.0, D2 and D1 support, no PME#
+ map(0x48, 0x4b).lr32(NAME([] () { return 0x0601'0001; }));
+ map(0x4c, 0x4f).lrw32(
+ NAME([this] (offs_t offset) { return m_power_state; }),
+ NAME([this] (offs_t offset, u32 data, u32 mem_mask) {
+ if (ACCESSING_BITS_0_7)
+ {
+ LOG("PM Power State D%d\n", data & 3);
+ m_power_state = data & 3;
+ }
+ })
+ );
+
+ map(0x50, 0x53).lrw32(
+ NAME([this] (offs_t offset, u32 mem_mask) { return m_interrupt_snoop.enable | (m_interrupt_snoop.vector << 8); }),
+ NAME([this] (offs_t offset, u32 data, u32 mem_mask) {
+ LOG("PCI 50h: %08x & %08x\n", data, mem_mask);
+ if (ACCESSING_BITS_0_7)
+ {
+ m_interrupt_snoop.enable = !!BIT(data, 0);
+ LOG("\tInterrupt snoop enable %d\n", m_interrupt_snoop.enable);
+ }
+ if (ACCESSING_BITS_8_15)
+ {
+ m_interrupt_snoop.vector = (data >> 8) & 0xff;
+ LOG("\tInterrupt snoop vector %02x\n", m_interrupt_snoop.vector);
+ }
+ })
+ );
+}
+
+void trident_4dwavedx_device::io_map(address_map &map)
+{
+ map(0x5c, 0x5f).lrw32(
+ NAME([this] (offs_t offset) {
+ return m_asr4 | (m_asr5 << 16) | (m_asr6 << 24);
+ }),
+ NAME([this] (offs_t offset, u32 data, u32 mem_mask) {
+ if (ACCESSING_BITS_0_7)
+ m_asr4 = data & 0xff;
+ if (ACCESSING_BITS_16_23)
+ {
+ m_asr5 = (data >> 16) & 0xff;
+ LOG("ASR5: SB ESP Version High %02x\n", m_asr5);
+ }
+ if (ACCESSING_BITS_24_31)
+ {
+ m_asr6 = (data >> 24) & 0xff;
+ LOG("ASR6: SB ESP Version High %02x\n", m_asr6);
+ }
+ })
+ );
+}
+
+void trident_4dwavedx_device::mmio_map(address_map &map)
+{
+}