From 88faf7bec1a3af5d3ffc8817271dbd1ff2957fc2 Mon Sep 17 00:00:00 2001 From: arbee Date: Sun, 5 Apr 2015 09:58:57 -0400 Subject: [PATCH] More iteagle improvements: [Ted Green] - PCI: allow BAR of 0; change "invalid" from 0 to -1 - vrc4373: implement bus-master DMA - es1373: Do some processing and DMA, and issue IRQs --- src/emu/machine/pci.c | 4 +- src/emu/machine/vrc4373.c | 63 ++++++++- src/emu/machine/vrc4373.h | 15 +- src/emu/sound/es1373.c | 276 +++++++++++++++++++++++++++++-------- src/emu/sound/es1373.h | 95 ++++++++++--- src/mame/drivers/iteagle.c | 42 +++++- 6 files changed, 408 insertions(+), 87 deletions(-) diff --git a/src/emu/machine/pci.c b/src/emu/machine/pci.c index 04d217d41f0..cc2ee6b0f65 100644 --- a/src/emu/machine/pci.c +++ b/src/emu/machine/pci.c @@ -81,7 +81,7 @@ void pci_device::device_start() status = 0x0000; for(int i=0; i<6; i++) { - bank_infos[i].adr = 0; + bank_infos[i].adr = -1; bank_infos[i].size = 0; bank_infos[i].flags = 0; bank_reg_infos[i].bank = -1; @@ -257,7 +257,7 @@ void pci_device::map_device(UINT64 memory_window_start, UINT64 memory_window_end { for(int i=0; i; @@ -217,14 +217,14 @@ READ32_MEMBER (vrc4373_device::target1_r) { UINT32 result = m_cpu->space(AS_PROGRAM).read_dword(m_target1_laddr | (offset*4), mem_mask); if (LOG_NILE_TARGET) - logerror("%06X:nile target1 read from offset %02X = %08X & %08X\n", space.device().safe_pc(), offset*4, result, mem_mask); + logerror("%08X:nile target1 read from offset %02X = %08X & %08X\n", m_cpu->device_t::safe_pc(), offset*4, result, mem_mask); return result; } WRITE32_MEMBER (vrc4373_device::target1_w) { m_cpu->space(AS_PROGRAM).write_dword(m_target1_laddr | (offset*4), data, mem_mask); if (LOG_NILE_TARGET) - logerror("%06X:nile target1 write to offset %02X = %08X & %08X\n", space.device().safe_pc(), offset*4, data, mem_mask); + logerror("%08X:nile target1 write to offset %02X = %08X & %08X\n", m_cpu->device_t::safe_pc(), offset*4, data, mem_mask); } // PCI Target Window 2 @@ -232,16 +232,38 @@ READ32_MEMBER (vrc4373_device::target2_r) { UINT32 result = m_cpu->space(AS_PROGRAM).read_dword(m_target2_laddr | (offset*4), mem_mask); if (LOG_NILE_TARGET) - logerror("%06X:nile target2 read from offset %02X = %08X & %08X\n", space.device().safe_pc(), offset*4, result, mem_mask); + logerror("%08X:nile target2 read from offset %02X = %08X & %08X\n", m_cpu->device_t::safe_pc(), offset*4, result, mem_mask); return result; } WRITE32_MEMBER (vrc4373_device::target2_w) { m_cpu->space(AS_PROGRAM).write_dword(m_target2_laddr | (offset*4), data, mem_mask); if (LOG_NILE_TARGET) - logerror("%06X:nile target2 write to offset %02X = %08X & %08X\n", space.device().safe_pc(), offset*4, data, mem_mask); + logerror("%08X:nile target2 write to offset %02X = %08X & %08X\n", m_cpu->device_t::safe_pc(), offset*4, data, mem_mask); } +// DMA Transfer +void vrc4373_device::dma_transfer(int which) +{ + if (LOG_NILE) + logerror("%08X:nile Start dma PCI: %08X MEM: %08X Words: %X\n", m_cpu->space(AS_PROGRAM).device().safe_pc(), m_cpu_regs[NREG_DMA_CPAR], m_cpu_regs[NREG_DMA_CMAR], m_cpu_regs[NREG_DMA_REM]); + int pciSel = (m_cpu_regs[NREG_DMACR1+which*0xC] & DMA_MIO) ? AS_DATA : AS_IO; + UINT32 mem_mask = 0xffffffff; + while (m_cpu_regs[NREG_DMA_REM]>0) { + if (0 && LOG_NILE) + logerror("dma_transfer PCI: %08X Mem: %08X Words Remaining: %X\n", m_cpu_regs[NREG_DMA_CPAR], m_cpu_regs[NREG_DMA_CMAR], m_cpu_regs[NREG_DMA_REM]); + if (m_cpu_regs[NREG_DMACR1+which*0xC]&DMA_RW) { + // Read data from PCI and write to local + m_cpu->space(AS_PROGRAM).write_dword(m_cpu_regs[NREG_DMA_CMAR], this->space(pciSel).read_dword(m_cpu_regs[NREG_DMA_CPAR], mem_mask), mem_mask); + } else { + // Read data from local and write to PCI + this->space(pciSel).write_dword(m_cpu_regs[NREG_DMA_CPAR], m_cpu->space(AS_PROGRAM).read_dword(m_cpu_regs[NREG_DMA_CMAR], mem_mask), mem_mask); + } + m_cpu_regs[NREG_DMA_CMAR] += 0x4; + m_cpu_regs[NREG_DMA_CPAR] += 0x4; + m_cpu_regs[NREG_DMA_REM]--; + } +} // CPU I/F READ32_MEMBER (vrc4373_device::cpu_if_r) { @@ -253,6 +275,15 @@ READ32_MEMBER (vrc4373_device::cpu_if_r) case NREG_PCICDR: result = config_data_r(space, offset); break; + case NREG_DMACR1: + case NREG_DMACR2: + // Clear busy and go on read + if (m_cpu_regs[NREG_DMA_REM]==0) { + int which = (offset-NREG_DMACR1)>>3; + m_cpu_regs[NREG_DMACR1+which*0xc] &= ~DMA_BUSY; + m_cpu_regs[NREG_DMACR1+which*0xc] &= ~DMA_GO; + } + break; default: break; } @@ -266,7 +297,8 @@ WRITE32_MEMBER(vrc4373_device::cpu_if_w) if (LOG_NILE) logerror("%06X:nile write to offset %02X = %08X & %08X\n", space.device().safe_pc(), offset*4, data, mem_mask); - UINT32 modData; + UINT32 modData, oldData; + oldData = m_cpu_regs[offset]; COMBINE_DATA(&m_cpu_regs[offset]); switch (offset) { case NREG_PCIMW1: @@ -312,6 +344,23 @@ WRITE32_MEMBER(vrc4373_device::cpu_if_w) case NREG_PCICDR: pci_host_device::config_data_w(space, offset, data); break; + case NREG_DMACR1: + case NREG_DMACR2: + // Start when DMA_GO bit is set + if (!(oldData & DMA_GO) && (data & DMA_GO)) { + int which = (offset-NREG_DMACR1)>>3; + // Check to see DMA is not already started + if (!(data&DMA_BUSY)) { + // Set counts and address + m_cpu_regs[NREG_DMA_CPAR] = m_cpu_regs[NREG_DMAPCI1+which*0xC]; + m_cpu_regs[NREG_DMA_CMAR] = m_cpu_regs[NREG_DMAMAR1+which*0xC]; + m_cpu_regs[NREG_DMA_REM] = (data & DMA_BLK_SIZE)>>2; + m_cpu_regs[NREG_DMACR1+which*0xc] |= DMA_BUSY; + // Start the transfer + dma_transfer(which); + } + } + break; case NREG_BMCR: if ((data>>3)&0x1) { m_ram_size = 1<<22; // 4MB diff --git a/src/emu/machine/vrc4373.h b/src/emu/machine/vrc4373.h index 998bea71832..c34170d02d6 100644 --- a/src/emu/machine/vrc4373.h +++ b/src/emu/machine/vrc4373.h @@ -38,13 +38,24 @@ #define NREG_DRAMRCR (0x058/4) #define NREG_BOOTWP (0x05C/4) #define NREG_PCIEAR (0x060/4) -#define NREG_DMA_WR (0x064/4) +#define NREG_DMA_REM (0x064/4) #define NREG_DMA_CMAR (0x068/4) #define NREG_DMA_CPAR (0x06C/4) #define NREG_PCIRC (0x070/4) #define NREG_PCIEN (0x074/4) #define NREG_PMIR (0x078/4) +#define DMA_BUSY 0x80000000 +#define DMA_INT_EN 0x40000000 +#define DMA_RW 0x20000000 +#define DMA_GO 0x10000000 +#define DMA_SUS 0x08000000 +#define DMA_INC 0x04000000 +#define DMA_MIO 0x02000000 +#define DMA_RST 0x01000000 +#define DMA_BLK_SIZE 0x000fffff + + class vrc4373_device : public pci_host_device { public: vrc4373_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); @@ -86,6 +97,7 @@ protected: virtual const address_space_config *memory_space_config(address_spacenum spacenum) const; virtual void device_start(); virtual void device_reset(); + void dma_transfer(int which); private: cpu_device *m_cpu; @@ -108,6 +120,7 @@ private: UINT32 m_pci1_laddr, m_pci2_laddr, m_pci_io_laddr; UINT32 m_target1_laddr, m_target2_laddr; + }; diff --git a/src/emu/sound/es1373.c b/src/emu/sound/es1373.c index aae26ba93f9..58fca2c9116 100644 --- a/src/emu/sound/es1373.c +++ b/src/emu/sound/es1373.c @@ -1,6 +1,16 @@ #include "es1373.h" #define LOG_ES (1) +#define LOG_ES_REG (0) + +static MACHINE_CONFIG_FRAGMENT( es1373 ) + MCFG_TIMER_DRIVER_ADD_PERIODIC("sound_timer", es1373_device, es_timer_callback, attotime::from_hz(44100/16384)) +MACHINE_CONFIG_END + +machine_config_constructor es1373_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( es1373 ); +} const device_type ES1373 = &device_creator; @@ -9,12 +19,21 @@ DEVICE_ADDRESS_MAP_START(map, 32, es1373_device) ADDRESS_MAP_END es1373_device::es1373_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : pci_device(mconfig, ES1373, "Creative Labs Ensoniq AudioPCI97 ES1373", tag, owner, clock, "es1373", __FILE__) + : pci_device(mconfig, ES1373, "Creative Labs Ensoniq AudioPCI97 ES1373", tag, owner, clock, "es1373", __FILE__), + m_irq_num(-1) { } +void es1373_device::set_irq_info(const char *tag, const int irq_num) +{ + m_cpu_tag = tag; + m_irq_num = irq_num; +} + void es1373_device::device_start() { + //m_cpu = machine().device(":maincpu"); + m_cpu = machine().device(m_cpu_tag); pci_device::device_start(); add_map(0x40, M_IO, FUNC(es1373_device::map)); } @@ -25,6 +44,144 @@ void es1373_device::device_reset() memset(m_es_regs, 0, sizeof(m_es_regs)); memset(m_ac97_regs, 0, sizeof(m_ac97_regs)); m_ac97_regs[0] = 0x0800; + // Reset ADC channel info + m_adc.enable = false; + m_adc.int_en = false; + m_adc.loop_en = false; + m_adc.initialized = false; + m_adc.buf_count = 0; + m_adc.buf_size = 0; + m_adc.buf_rptr = 0x20; + m_adc.buf_wptr = 0x20; + // Reset DAC1 channel info + m_dac1.enable = false; + m_dac1.int_en = false; + m_dac1.loop_en = false; + m_dac1.initialized = false; + m_dac1.buf_count = 0; + m_dac1.buf_size = 0; + m_dac1.buf_rptr = 0x0; + m_dac1.buf_wptr = 0x0; + // Reset DAC2 channel info + m_dac2.enable = false; + m_dac2.int_en = false; + m_dac2.loop_en = false; + m_dac2.initialized = false; + m_dac2.buf_count = 0; + m_dac2.buf_size = 0; + m_dac2.buf_rptr = 0x10; + m_dac2.buf_wptr = 0x10; +} + +void es1373_device::map_extra(UINT64 memory_window_start, UINT64 memory_window_end, UINT64 memory_offset, address_space *memory_space, + UINT64 io_window_start, UINT64 io_window_end, UINT64 io_offset, address_space *io_space) +{ + m_memory_space = memory_space; +} + +TIMER_DEVICE_CALLBACK_MEMBER(es1373_device::es_timer_callback) +{ + // Only transfer PCI data if bus mastering is enabled + if (command & 0x4) { + if (m_dac2.enable && (!(m_dac2.buf_rptr&0x7))) { + transfer_pci_audio(m_dac2, ES_PCI_READ); + } + if (m_dac2.pci_count>8) { + m_dac2.initialized = true; + } + } + if (m_dac2.enable) { + // The initalized is to signal that inital buffer has been written + if (m_dac2.buf_count<=m_dac2.buf_size && m_dac2.initialized) { + // Send data to sound??? + // sound = m_sound_cache[chan.buf_rptr] + if (0 && LOG_ES) + logerror("%X: DAC2 buf_count: %i buf_size: %X buf_rptr: %X buf_wptr: %X\n", machine().device("maincpu")->safe_pc(), + m_dac2.buf_count, m_dac2.buf_size, m_dac2.buf_rptr, m_dac2.buf_wptr); + if (m_dac2.buf_count==m_dac2.buf_size) { + if (m_dac2.int_en) { + m_es_regs[ES_INT_CS_STATUS] |= ICSTATUS_DAC2_INT_MASK; + if (LOG_ES) + logerror("%X: es_timer_callback Setting DAC2 interrupt\n", machine().device("maincpu")->safe_pc()); + } + if (m_dac2.loop_en) { + // Keep playing + m_dac2.buf_count = m_dac2.buf_count + 1 - 4; // Should check SCTRL_P2_END_MASK + } else { + // Stop + //m_dac2.enable = false; + } + } else { + m_dac2.buf_count++; + } + m_dac2.buf_rptr++; + if (!(m_dac2.buf_rptr&0xf)) { + m_dac2.buf_rptr -= 0x10; + } + } + } + if (m_adc.enable) { + if (m_adc.buf_count<=m_adc.buf_size) { + if (LOG_ES) + logerror("%s: ADC buf_count: %i buf_size: %i buf_rptr: %i buf_wptr: %i\n", machine().describe_context(), + m_adc.buf_count, m_adc.buf_size, m_adc.buf_rptr, m_adc.buf_wptr); + if (m_adc.int_en && m_adc.buf_count==m_adc.buf_size) { + m_es_regs[ES_INT_CS_STATUS] |= ICSTATUS_ADC_INT_MASK; + if (LOG_ES) + logerror("%s: es_timer_callback Setting ADC interrupt\n", tag()); + } + m_adc.buf_count++; + m_adc.buf_wptr++; + if (!(m_adc.buf_wptr&0xf)) { + m_adc.buf_wptr -= 0x10; + } + } + } + // PCI Write Transfer + if (command & 0x4) { + if (m_adc.enable && (!(m_adc.buf_wptr&0x7))) { + transfer_pci_audio(m_adc, ES_PCI_WRITE); + } + } + if (m_es_regs[ES_INT_CS_STATUS]&(ICSTATUS_DAC1_INT_MASK|ICSTATUS_DAC2_INT_MASK|ICSTATUS_ADC_INT_MASK)) { + m_es_regs[ES_INT_CS_STATUS] |= ICSTATUS_INTR_MASK; + // Assert interrupt + //m_cpu->set_input_line(ES_IRQ_NUM, ASSERT_LINE); + if (m_irq_num!=-1) { + m_cpu->set_input_line(m_irq_num, ASSERT_LINE); + } + } +} + +void es1373_device::transfer_pci_audio(chan_info& chan, int type) +{ + UINT32 pci_addr, data; + pci_addr = chan.pci_addr + (chan.pci_count<<2); + if (type==ES_PCI_READ) { + // Transfer from PCI to sound cache + // Always transfer 8 longwords + for (int i=0; i<8 && (chan.pci_count<=chan.pci_size); i++) { + data = m_memory_space->read_dword(pci_addr, 0xffffffff); + m_sound_cache[chan.buf_wptr++] = data; + if (!(chan.buf_wptr&0xf)) { + chan.buf_wptr -= 0x10; + } + chan.pci_count++; + pci_addr += 4; + } + } else { + // Transfer from sound cache to PCI + // Always transfer 8 longwords + for (int i=0; i<8 && chan.pci_count<=chan.pci_size; i++) { + data = m_sound_cache[chan.buf_rptr++]; + m_memory_space->write_dword(pci_addr, data); + if (!(chan.buf_rptr&0xf)) { + chan.buf_rptr -= 0x10; + } + chan.pci_count++; + pci_addr += 4; + } + } } READ32_MEMBER (es1373_device::reg_r) @@ -33,62 +190,51 @@ READ32_MEMBER (es1373_device::reg_r) switch (offset) { case ES_CODEC: break; + case ES_DAC2_CNT: + result = ((m_dac2.buf_size-m_dac2.buf_count)<<16) | m_dac2.buf_size; + break; case ES_HOST_IF0: // 0x30 + result = m_sound_cache[(m_es_regs[ES_MEM_PAGE]<<2) | 0x0]; switch (m_es_regs[ES_MEM_PAGE]&0xf) { case 0xc: - result = m_dac1_fr.pci_addr; + result = m_dac1.pci_addr; break; case 0xd: - result = m_adc_fr.pci_addr; + result = m_adc.pci_addr; break; - case 0xe: - case 0xf: - logerror("%06X:ES1373 Read UART offset %02X & %08X\n", space.device().safe_pc(), offset*4, mem_mask); default: break; } break; case ES_HOST_IF1: // 0x34 + result = m_sound_cache[(m_es_regs[ES_MEM_PAGE]<<2) | 0x1]; switch (m_es_regs[ES_MEM_PAGE]&0xf) { case 0xc: - result = (m_dac1_fr.curr_count<<16) | m_dac1_fr.buff_size; + result = (m_dac1.pci_count<<16) | m_dac1.pci_size; break; case 0xd: - result = (m_adc_fr.curr_count<<16) | m_adc_fr.buff_size; + result = (m_adc.pci_count<<16) | m_adc.pci_size; break; - case 0xe: - case 0xf: - logerror("%06X:ES1373 write UART offset %02X & %08X\n", space.device().safe_pc(), offset*4, mem_mask); default: break; } break; case ES_HOST_IF2: // 0x38 + result = m_sound_cache[(m_es_regs[ES_MEM_PAGE]<<2) | 0x2]; switch (m_es_regs[ES_MEM_PAGE]&0xf) { case 0xc: - result = m_dac2_fr.pci_addr; + result = m_dac2.pci_addr; break; - case 0xd: - logerror("%06X:ES1373 read Unknown place offset %02X & %08X\n", space.device().safe_pc(), offset*4, mem_mask); - break; - case 0xe: - case 0xf: - logerror("%06X:ES1373 read UART offset %02X & %08X\n", space.device().safe_pc(), offset*4, mem_mask); default: break; } break; case ES_HOST_IF3: // 0x3C + result = m_sound_cache[(m_es_regs[ES_MEM_PAGE]<<2) | 0x3]; switch (m_es_regs[ES_MEM_PAGE]&0xf) { case 0xc: - result = (m_dac2_fr.curr_count<<16) | m_dac2_fr.buff_size; + result = ((m_dac2.pci_count)<<16) | m_dac2.pci_size; break; - case 0xd: - logerror("%06X:ES1373 read Unknown place offset %02X & %08X\n", space.device().safe_pc(), offset*4, mem_mask); - break; - case 0xe: - case 0xf: - logerror("%06X:ES1373 read UART offset %02X & %08X\n", space.device().safe_pc(), offset*4, mem_mask); default: break; } @@ -96,8 +242,8 @@ READ32_MEMBER (es1373_device::reg_r) default: break; } - if (LOG_ES) - logerror("%06X:ES1373 read from offset %02X = %08X & %08X\n", space.device().safe_pc(), offset*4, result, mem_mask); + if (LOG_ES_REG) + logerror("%08X:ES1373 read from offset %02X = %08X & %08X\n", machine().device("maincpu")->safe_pc(), offset*4, result, mem_mask); return result; } @@ -105,6 +251,11 @@ WRITE32_MEMBER(es1373_device::reg_w) { COMBINE_DATA(&m_es_regs[offset]); switch (offset) { + case ES_INT_CS_CTRL: + m_dac1.enable = (m_es_regs[ES_INT_CS_CTRL] & ICCTRL_DAC1_EN_MASK); + m_dac2.enable = (m_es_regs[ES_INT_CS_CTRL] & ICCTRL_DAC2_EN_MASK); + m_adc.enable = (m_es_regs[ES_INT_CS_CTRL] & ICCTRL_ADC_EN_MASK); + break; case ES_SRC_IF: if (data&(1<<24)) { // Write to Sample Rate Converter Ram @@ -123,65 +274,78 @@ WRITE32_MEMBER(es1373_device::reg_w) m_ac97_regs[(data>>16)&0x7f] = data&0xFFFF; } break; + case ES_SERIAL_CTRL: + m_adc.loop_en = !(m_es_regs[ES_SERIAL_CTRL] & SCTRL_R1_LOOP_MASK); + m_dac2.loop_en = !(m_es_regs[ES_SERIAL_CTRL] & SCTRL_P2_LOOP_MASK); + m_dac1.loop_en = !(m_es_regs[ES_SERIAL_CTRL] & SCTRL_P1_LOOP_MASK); + m_adc.int_en = m_es_regs[ES_SERIAL_CTRL] & SCTRL_R1_INT_EN_MASK; + m_dac2.int_en = m_es_regs[ES_SERIAL_CTRL] & SCTRL_P2_INT_EN_MASK; + m_dac1.int_en = m_es_regs[ES_SERIAL_CTRL] & SCTRL_P1_INT_EN_MASK; + if (!m_adc.int_en) m_es_regs[ES_INT_CS_STATUS] &= ~ICSTATUS_ADC_INT_MASK; + if (!m_dac1.int_en) m_es_regs[ES_INT_CS_STATUS] &= ~ICSTATUS_DAC1_INT_MASK; + if (!m_dac2.int_en) m_es_regs[ES_INT_CS_STATUS] &= ~ICSTATUS_DAC2_INT_MASK; + // Clear the summary interrupt and irq line + if (!(m_es_regs[ES_INT_CS_STATUS]&(ICSTATUS_DAC1_INT_MASK|ICSTATUS_DAC2_INT_MASK|ICSTATUS_ADC_INT_MASK))) { + // Deassert interrupt + if (m_es_regs[ES_INT_CS_STATUS]&ICSTATUS_INTR_MASK && m_irq_num!=-1) { + m_cpu->set_input_line(m_irq_num, CLEAR_LINE); + m_es_regs[ES_INT_CS_STATUS] &= ~ICSTATUS_INTR_MASK; + if (LOG_ES) + logerror("%X: es1373_device::reg_w Clearing interrupt\n", machine().device("maincpu")->safe_pc()); + } + } + if (LOG_ES_REG) + logerror("%s: es1373_device::reg_w adc_int_en: %i dac1_int_en: %i dac2_int_en: %i\n", tag(), m_adc.int_en, m_dac1.int_en, m_dac2.int_en); + break; + case ES_DAC2_CNT: + m_dac2.buf_count = 0; + m_dac2.buf_size = data&0xffff; + break; case ES_HOST_IF0: // 0x30 + m_sound_cache[(m_es_regs[ES_MEM_PAGE]<<2) | 0x0] = data; switch (m_es_regs[ES_MEM_PAGE]&0xf) { case 0xc: - m_dac1_fr.pci_addr = data; + m_dac1.pci_addr = data; break; case 0xd: - m_adc_fr.pci_addr = data; + m_adc.pci_addr = data; break; - case 0xe: - case 0xf: - logerror("%06X:ES1373 write UART offset %02X = %08X & %08X\n", space.device().safe_pc(), offset*4, data, mem_mask); default: break; } break; case ES_HOST_IF1: // 0x34 + m_sound_cache[(m_es_regs[ES_MEM_PAGE]<<2) | 0x1] = data; switch (m_es_regs[ES_MEM_PAGE]&0xf) { case 0xc: - m_dac1_fr.curr_count = (data>>16)&0xffff; - m_dac1_fr.buff_size = data&0xffff; + m_dac1.pci_count = (data>>16)&0xffff; + m_dac1.pci_size = data&0xffff; break; case 0xd: - m_adc_fr.curr_count = (data>>16)&0xffff; - m_adc_fr.buff_size = data&0xffff; + m_adc.pci_count = (data>>16)&0xffff; + m_adc.pci_size = data&0xffff; break; - case 0xe: - case 0xf: - logerror("%06X:ES1373 write UART offset %02X = %08X & %08X\n", space.device().safe_pc(), offset*4, data, mem_mask); default: break; } break; case ES_HOST_IF2: // 0x38 + m_sound_cache[(m_es_regs[ES_MEM_PAGE]<<2) | 0x2] = data; switch (m_es_regs[ES_MEM_PAGE]&0xf) { case 0xc: - m_dac2_fr.pci_addr = data; + m_dac2.pci_addr = data; break; - case 0xd: - logerror("%06X:ES1373 write Unknown place offset %02X = %08X & %08X\n", space.device().safe_pc(), offset*4, data, mem_mask); - break; - case 0xe: - case 0xf: - logerror("%06X:ES1373 write UART offset %02X = %08X & %08X\n", space.device().safe_pc(), offset*4, data, mem_mask); default: break; } break; case ES_HOST_IF3: // 0x3C + m_sound_cache[(m_es_regs[ES_MEM_PAGE]<<2) | 0x3] = data; switch (m_es_regs[ES_MEM_PAGE]&0xf) { case 0xc: - m_dac2_fr.curr_count = (data>>16)&0xffff; - m_dac2_fr.buff_size = data&0xffff; + m_dac2.pci_count = (data>>16)&0xffff; + m_dac2.pci_size = data&0xffff; break; - case 0xd: - logerror("%06X:ES1373 write Unknown place offset %02X = %08X & %08X\n", space.device().safe_pc(), offset*4, data, mem_mask); - break; - case 0xe: - case 0xf: - logerror("%06X:ES1373 write UART offset %02X = %08X & %08X\n", space.device().safe_pc(), offset*4, data, mem_mask); default: break; } @@ -190,7 +354,7 @@ WRITE32_MEMBER(es1373_device::reg_w) break; } - if (LOG_ES) - logerror("%06X:ES1373 write to offset %02X = %08X & %08X\n", space.device().safe_pc(), offset*4, data, mem_mask); + if (LOG_ES_REG) + logerror("%08X:ES1373 write to offset %02X = %08X & %08X\n", machine().device("maincpu")->safe_pc(), offset*4, data, mem_mask); } diff --git a/src/emu/sound/es1373.h b/src/emu/sound/es1373.h index 46a2e4180d3..7b909530f40 100644 --- a/src/emu/sound/es1373.h +++ b/src/emu/sound/es1373.h @@ -5,57 +5,116 @@ #include "machine/pci.h" +// No interrupts #define MCFG_ES1373_ADD(_tag) \ MCFG_PCI_DEVICE_ADD(_tag, ES1373, 0x12741371, 0x04, 0x040100, 0x12741371) +#define MCFG_ES1373_IRQ_ADD(_cpu_tag, _irq_num) \ + downcast(device)->set_irq_info(_cpu_tag, _irq_num); + /* Ensonic ES1373 registers 0x00-0x3f */ #define ES_INT_CS_CTRL (0x00/4) #define ES_INT_CS_STATUS (0x04/4) -#define ES_UART_DATA (0x08/4) -#define ES_UART_STATUS (0x09/4) -#define ES_UART_CTRL (0x09/4) -#define ES_UART_RSVD (0x0A/4) -#define ES_MEM_PAGE (0x0C/4) +#define ES_UART_DATA (0x08/4) +#define ES_UART_STATUS (0x09/4) +#define ES_UART_CTRL (0x09/4) +#define ES_UART_RSVD (0x0A/4) +#define ES_MEM_PAGE (0x0C/4) #define ES_SRC_IF (0x10/4) -#define ES_CODEC (0x14/4) -#define ES_LEGACY (0x18/4) -#define ES_CHAN_CTRL (0x1C/4) +#define ES_CODEC (0x14/4) +#define ES_LEGACY (0x18/4) +#define ES_CHAN_CTRL (0x1C/4) #define ES_SERIAL_CTRL (0x20/4) #define ES_DAC1_CNT (0x24/4) #define ES_DAC2_CNT (0x28/4) #define ES_ADC_CNT (0x2C/4) -#define ES_ADC_CNT (0x2C/4) #define ES_HOST_IF0 (0x30/4) #define ES_HOST_IF1 (0x34/4) #define ES_HOST_IF2 (0x38/4) #define ES_HOST_IF3 (0x3C/4) -struct frame_reg { - UINT32 pci_addr; - UINT16 curr_count; - UINT16 buff_size; - frame_reg() : pci_addr(0), curr_count(0), buff_size(0) {} +// Interrupt/Chip Select Control Register (ES_INT_CS_CTRL) bits +#define ICCTRL_ADC_STOP_MASK 0x00002000 +#define ICCTRL_DAC1_EN_MASK 0x00000040 +#define ICCTRL_DAC2_EN_MASK 0x00000020 +#define ICCTRL_ADC_EN_MASK 0x00000010 +#define ICCTRL_UART_EN_MASK 0x00000008 +#define ICCTRL_JYSTK_EN_MASK 0x00000004 + +// Interrupt/Chip Select Status Register (ES_INT_CS_STATUS) bits +#define ICSTATUS_INTR_MASK 0x80000000 +#define ICSTATUS_DAC1_INT_MASK 0x00000004 +#define ICSTATUS_DAC2_INT_MASK 0x00000002 +#define ICSTATUS_ADC_INT_MASK 0x00000001 + +// Serial Interface Control Register (ES_SERIAL_CTRL) bits +#define SCTRL_P2_END_MASK 0x00380000 +#define SCTRL_P2_START_MASK 0x00070000 +#define SCTRL_R1_LOOP_MASK 0x00008000 +#define SCTRL_P2_LOOP_MASK 0x00004000 +#define SCTRL_P1_LOOP_MASK 0x00002000 +#define SCTRL_P2_PAUSE_MASK 0x00001000 +#define SCTRL_P1_PAUSE_MASK 0x00000800 +#define SCTRL_R1_INT_EN_MASK 0x00000400 +#define SCTRL_P2_INT_EN_MASK 0x00000200 +#define SCTRL_P1_INT_EN_MASK 0x00000100 +#define SCTRL_P1_RELOAD_MASK 0x00000080 +#define SCTRL_P2_STOP_MASK 0x00000040 +#define SCTRL_R1_S_MASK 0x00000030 +#define SCTRL_P2_S_MASK 0x0000000C +#define SCTRL_P1_S_MASK 0x00000003 + +#define ES_PCI_READ 0 +#define ES_PCI_WRITE 1 + +struct chan_info { + bool enable; + bool int_en; + bool loop_en; + bool initialized; + UINT32 samp_size; // Size of one sample in log2(bytes) + UINT32 buf_wptr; // Address to sample cache memory + UINT32 buf_rptr; // Address to sample cache memory + UINT16 buf_count; // Number of samples that have been played + UINT16 buf_size; // Number of samples minus one to play + UINT32 pci_addr; // PCI Addresss for system memory accesses + UINT16 pci_count; // Number of 32 bits transfered + UINT16 pci_size; // Total number of words (32 bits) minus one in system memory }; class es1373_device : public pci_device { public: es1373_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + virtual void map_extra(UINT64 memory_window_start, UINT64 memory_window_end, UINT64 memory_offset, address_space *memory_space, + UINT64 io_window_start, UINT64 io_window_end, UINT64 io_offset, address_space *io_space); + + void set_irq_info(const char *tag, const int irq_num); DECLARE_READ32_MEMBER (reg_r); DECLARE_WRITE32_MEMBER(reg_w); - + TIMER_DEVICE_CALLBACK_MEMBER(es_timer_callback); + // optional information overrides + virtual machine_config_constructor device_mconfig_additions() const; protected: virtual void device_start(); virtual void device_reset(); + address_space *m_memory_space; + //virtual const address_space_config *memory_space_config(address_spacenum spacenum) const; private: + const char *m_cpu_tag; + cpu_device *m_cpu; + int m_irq_num; DECLARE_ADDRESS_MAP(map, 32); UINT16 m_ac97_regs[0x80]; UINT32 m_es_regs[0x10]; + UINT32 m_sound_cache[0x40]; UINT16 m_src_ram[0x80]; - frame_reg m_dac1_fr; - frame_reg m_dac2_fr; - frame_reg m_adc_fr; + chan_info m_dac1; + chan_info m_dac2; + chan_info m_adc; + void transfer_pci_audio(chan_info& chan, int type); + }; extern const device_type ES1373; diff --git a/src/mame/drivers/iteagle.c b/src/mame/drivers/iteagle.c index 9d541054843..ca81879909d 100644 --- a/src/mame/drivers/iteagle.c +++ b/src/mame/drivers/iteagle.c @@ -135,6 +135,7 @@ static MACHINE_CONFIG_START( gtfore, iteagle_state ) MCFG_ITEAGLE_FPGA_ADD( ":pci:06.0") MCFG_ITEAGLE_IDE_ADD( ":pci:06.1") MCFG_ES1373_ADD( ":pci:07.0") + MCFG_ES1373_IRQ_ADD( ":maincpu", MIPS3_IRQ3) MCFG_VOODOO_ADD( ":pci:09.0") MCFG_ITEAGLE_EEPROM_ADD( ":pci:0a.0") @@ -161,7 +162,43 @@ static INPUT_PORTS_START( iteagle ) PORT_DIPSETTING(0x1, "Medium" ) PORT_DIPSETTING(0x0, "Low" ) PORT_DIPSETTING(0x2, "Low_Alt" ) - PORT_DIPNAME( 0xC, 0x0, "Always" ) + + PORT_START("SW51") + PORT_DIPNAME( 0x3, 0x0, "Mode" ) + PORT_DIPSETTING(0x0, "Normal" ) + PORT_DIPSETTING(0x1, "Operator" ) + + PORT_START("IN1") + PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_COIN1 ) + PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_START1 ) + PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME( "Left" ) + PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME( "Right" ) + PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME( "Fly By" ) + PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME( "Backspin" ) + PORT_BIT( 0x00c0, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_COIN2 ) + PORT_BIT( 0xfe00, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("SYSTEM") + PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_SERVICE ) + PORT_SERVICE_NO_TOGGLE( 0x0002, IP_ACTIVE_HIGH ) + PORT_BIT( 0x00fc, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_VOLUME_UP ) + PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_VOLUME_DOWN ) + PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_BILL1 ) + PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x3000, IP_ACTIVE_HIGH, IPT_UNKNOWN ) + PORT_DIPNAME( 0xC000, 0xC000, "Voltage" ) + PORT_DIPSETTING(0xC000, "OK" ) + PORT_DIPSETTING(0x8000, "Low" ) + PORT_DIPSETTING(0x4000, "High" ) + PORT_DIPSETTING(0x0000, "Not Detected" ) + + PORT_START("TRACKX1") + PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_X ) PORT_SENSITIVITY(25) PORT_KEYDELTA(32) PORT_REVERSE PORT_PLAYER(1) + + PORT_START("TRACKY1") + PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_Y ) PORT_SENSITIVITY(25) PORT_KEYDELTA(32) PORT_PLAYER(1) PORT_START("VERSION") PORT_DIPNAME( 0x0F00, 0x0000, "GAME" ) @@ -243,12 +280,11 @@ INPUT_PORTS_END ROM_LOAD( "17s20lpc_sb4.u26", 0x000000, 0x008000, CRC(62c4af8a) SHA1(6eca277b9c66a401990599e98fdca64a9e38cc9a) ) \ ROM_LOAD( "17s20lpc_sb5.u26", 0x008000, 0x008000, CRC(c88b9d42) SHA1(b912d0fc50ecdc6a198c626f6e1644e8405fac6e) ) \ ROM_LOAD( "17s50a_red1.u26", 0x010000, 0x020000, CRC(f5cf3187) SHA1(83b4a14de9959e5a776d97d424945d43501bda7f) ) \ - ROM_REGION( 0x80, "eeprom", 0 ) \ - ROM_COPY( "fpga", 0x0, 0x0, 0x80 ) \ ROM_REGION( 0x2000, "pals", 0 ) \ ROM_LOAD( "e2-card1.u22.jed", 0x000000, 0x000bd1, CRC(9d1e1ace) SHA1(287d6a30e9f32137ef4eba54f0effa092c97a6eb) ) \ ROM_LOAD( "e2-res3.u117.jed", 0x001000, 0x000bd1, CRC(4f1ff45a) SHA1(213cbdd6cd37ad9b5bfc9545084892a68d29f5ff) ) + ROM_START( iteagle ) EAGLE_BIOS