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
This commit is contained in:
arbee 2015-04-05 09:58:57 -04:00
parent 29d96af74d
commit 88faf7bec1
6 changed files with 408 additions and 87 deletions

View File

@ -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<bank_count; i++) {
bank_info &bi = bank_infos[i];
if(!bi.adr)
if(bi.adr==-1)
continue;
if(UINT32(bi.adr) == UINT32(~(bi.size - 1)))
continue;

View File

@ -1,8 +1,8 @@
#include "vrc4373.h"
#define LOG_NILE (1)
#define LOG_NILE (0)
#define LOG_NILE_MASTER (0)
#define LOG_NILE_TARGET (1)
#define LOG_NILE_TARGET (0)
const device_type VRC4373 = &device_creator<vrc4373_device>;
@ -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

View File

@ -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;
};

View File

@ -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<es1373_device>;
@ -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<cpu_device>(":maincpu");
m_cpu = machine().device<cpu_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);
}

View File

@ -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<es1373_device *>(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;

View File

@ -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