diff options
Diffstat (limited to 'src/devices/bus/pci/trident_4dwavedx.cpp')
| -rw-r--r-- | src/devices/bus/pci/trident_4dwavedx.cpp | 189 |
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) +{ +} |
