dcs: Implemented proper ram bank switch for ADSP2181 systems. (nw)

This commit is contained in:
Ted Green 2016-12-21 18:07:25 -07:00
parent 780732f563
commit e6227e1896
2 changed files with 56 additions and 20 deletions

View File

@ -246,6 +246,7 @@ enum
#define DSIO_DM_PG ((m_dsio.reg[2] >> 0) & 0x7ff)
#define DSIO_BANK_END 0x7ff
/* these macros are used to reference the DENVER ASIC */
#define DENV_DSP_SPEED ((m_dsio.reg[1] >> 2) & 3) /* read only: 1=33.33MHz */
@ -256,6 +257,7 @@ enum
#define DENV_DM_PG ((m_dsio.reg[2] >> 0) & 0x7ff)
#define DENV_BANK_END 0xfff
/*************************************
*
@ -384,11 +386,15 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( dsio_data_map, AS_DATA, 16, dcs_audio_device )
ADDRESS_MAP_UNMAP_HIGH
AM_RANGE(0x0000, 0x03ff) AM_RAMBANK("databank")
AM_RANGE(0x0400, 0x3fdf) AM_RAM
AM_RANGE(0x0000, 0x1fff) AM_DEVICE("data_map_bank", address_map_bank_device, amap16)
AM_RANGE(0x2000, 0x3fdf) AM_RAM AM_SHARE("dcsint_data")
AM_RANGE(0x3fe0, 0x3fff) AM_READWRITE(adsp_control_r, adsp_control_w)
ADDRESS_MAP_END
static ADDRESS_MAP_START( dsio_rambank_map, AS_PROGRAM, 16, dcs_audio_device )
AM_RANGE(0x0000, 0x1fff) AM_RAM
AM_RANGE(0x2000, 0x2000 + DSIO_BANK_END) AM_RAMBANK("databank")
ADDRESS_MAP_END
static ADDRESS_MAP_START( dsio_io_map, AS_IO, 16, dcs_audio_device )
ADDRESS_MAP_UNMAP_HIGH
@ -416,11 +422,16 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( denver_data_map, AS_DATA, 16, dcs_audio_device )
ADDRESS_MAP_UNMAP_HIGH
AM_RANGE(0x0000, 0x07ff) AM_RAMBANK("databank")
AM_RANGE(0x0800, 0x3fdf) AM_RAM
AM_RANGE(0x0000, 0x1fff) AM_DEVICE("data_map_bank", address_map_bank_device, amap16)
AM_RANGE(0x2000, 0x3fdf) AM_RAM AM_SHARE("dcsint_data")
AM_RANGE(0x3fe0, 0x3fff) AM_READWRITE(adsp_control_r, adsp_control_w)
ADDRESS_MAP_END
static ADDRESS_MAP_START(denver_rambank_map, AS_PROGRAM, 16, dcs_audio_device)
AM_RANGE(0x0000, 0x1fff) AM_RAM
AM_RANGE(0x2000, 0x2000 + DENV_BANK_END) AM_RAMBANK("databank")
ADDRESS_MAP_END
static ADDRESS_MAP_START( denver_io_map, AS_IO, 16, dcs_audio_device )
ADDRESS_MAP_UNMAP_HIGH
@ -528,10 +539,18 @@ MACHINE_CONFIG_FRAGMENT( dcs2_audio_dsio )
MCFG_CPU_ADD("dsio", ADSP2181, XTAL_32MHz)
MCFG_ADSP21XX_SPORT_TX_CB(WRITE32(dcs_audio_device, sound_tx_callback)) /* callback for serial transmit */
MCFG_ADSP21XX_TIMER_FIRED_CB(WRITELINE(dcs_audio_device,timer_enable_callback)) /* callback for timer fired */
MCFG_ADSP21XX_DMOVLAY_CB(WRITE32(dcs_audio_device, dmovlay_callback)) // callback for adsp 2181 dmovlay instruction
MCFG_CPU_PROGRAM_MAP(dsio_program_map)
MCFG_CPU_DATA_MAP(dsio_data_map)
MCFG_CPU_IO_MAP(dsio_io_map)
MCFG_DEVICE_ADD("data_map_bank", ADDRESS_MAP_BANK, 0)
MCFG_DEVICE_PROGRAM_MAP(dsio_rambank_map)
MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE)
MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(16)
MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(14)
MCFG_ADDRESS_MAP_BANK_STRIDE(0x2000)
MCFG_TIMER_DEVICE_ADD("dcs_reg_timer", DEVICE_SELF, dcs_audio_device, dcs_irq)
MCFG_TIMER_DEVICE_ADD("dcs_int_timer", DEVICE_SELF, dcs_audio_device, internal_timer_callback)
MCFG_TIMER_DEVICE_ADD("dcs_sport_timer", DEVICE_SELF, dcs_audio_device, sport0_irq) // roadburn needs this to pass harware test
@ -562,6 +581,13 @@ MACHINE_CONFIG_FRAGMENT( dcs2_audio_denver )
MCFG_CPU_DATA_MAP(denver_data_map)
MCFG_CPU_IO_MAP(denver_io_map)
MCFG_DEVICE_ADD("data_map_bank", ADDRESS_MAP_BANK, 0)
MCFG_DEVICE_PROGRAM_MAP(denver_rambank_map)
MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE)
MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(16)
MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(14)
MCFG_ADDRESS_MAP_BANK_STRIDE(0x2000)
MCFG_TIMER_DEVICE_ADD("dcs_reg_timer", DEVICE_SELF, dcs_audio_device, dcs_irq)
MCFG_TIMER_DEVICE_ADD("dcs_int_timer", DEVICE_SELF, dcs_audio_device, internal_timer_callback)
MCFG_TIMER_DEVICE_ADD("dcs_sport_timer", DEVICE_SELF, dcs_audio_device, sport0_irq) // Atlantis driver waits for sport0 rx interrupts
@ -689,8 +715,6 @@ TIMER_CALLBACK_MEMBER( dcs_audio_device::dcs_reset )
/* rev 4: reset the Denver ASIC */
case 4:
m_dmovlay_val = 0;
dmovlay_remap_memory();
denver_reset();
break;
}
@ -822,6 +846,7 @@ dcs_audio_device::dcs_audio_device(const machine_config &mconfig, device_type ty
m_sounddata_words(0),
m_sounddata_banks(0),
m_sounddata_bank(0),
m_ram_map(*this, "data_map_bank"),
m_data_bank(*this, "databank"),
m_rom_page(nullptr),
m_dram_page(nullptr),
@ -845,6 +870,7 @@ dcs_audio_device::dcs_audio_device(const machine_config &mconfig, device_type ty
m_polling_base(nullptr),
m_internal_program_ram(nullptr),
m_external_program_ram(nullptr),
m_internal_data_ram(nullptr),
m_dram_in_mb(0),
m_iram(*this, "iram")
{
@ -928,6 +954,11 @@ void dcs2_audio_device::device_start()
{
m_external_program_ram = (uint32_t *)external_ram->ptr();
}
memory_share *internal_data_ram = memshare("dcsint_data");
if (internal_data_ram != nullptr)
{
m_internal_data_ram = (uint32_t *)internal_ram->ptr();
}
/* find the DCS CPU and the sound ROMs */
m_cpu = subdevice<adsp21xx_device>("dcs2");
@ -937,13 +968,13 @@ void dcs2_audio_device::device_start()
{
m_cpu = subdevice<adsp21xx_device>("dsio");
m_rev = 3;
soundbank_words = 0x400;
soundbank_words = DSIO_BANK_END + 1;
}
if (m_cpu == nullptr)
{
m_cpu = subdevice<adsp21xx_device>("denver");
m_rev = 4;
soundbank_words = 0x800;
soundbank_words = DENV_BANK_END + 1;
}
if (m_cpu != nullptr && !m_cpu->started())
throw device_missing_dependencies();
@ -965,13 +996,9 @@ void dcs2_audio_device::device_start()
/* supports both RAM and ROM variants */
if (m_dram_in_mb != 0)
{
uint32_t ramSize = m_dram_in_mb << (20 - 1);
// Add one extra bank for internal ram in ADSP 2181
if (m_rev == 4)
ramSize += soundbank_words;
m_sounddata = auto_alloc_array(machine(), uint16_t, ramSize);
save_pointer(NAME(m_sounddata), ramSize);
m_sounddata_words = (m_dram_in_mb << 20) / 2;
m_sounddata = auto_alloc_array(machine(), uint16_t, m_sounddata_words);
save_pointer(NAME(m_sounddata), m_sounddata_words);
}
else
{
@ -981,7 +1008,9 @@ void dcs2_audio_device::device_start()
m_sounddata_banks = m_sounddata_words / soundbank_words;
if (m_rev != 2)
{
m_data_bank->configure_entries(0, m_sounddata_banks, m_sounddata, soundbank_words*2);
if (m_ram_map)
m_ram_map->set_bank(0);
m_data_bank->configure_entries(0, m_sounddata_banks, m_sounddata, soundbank_words * 2);
}
@ -1303,6 +1332,8 @@ WRITE16_MEMBER( dcs_audio_device::sdrc_w )
void dcs_audio_device::dsio_reset()
{
memset(&m_dsio, 0, sizeof(m_dsio));
m_dmovlay_val = 0;
dmovlay_remap_memory();
}
@ -1342,7 +1373,7 @@ WRITE16_MEMBER( dcs_audio_device::dsio_w )
/* offset 2 controls RAM pages */
case 2:
dsio.reg[2] = data;
dmovlay_remap_memory();
m_data_bank->set_entry(DSIO_DM_PG % m_sounddata_banks);
break;
}
}
@ -1358,6 +1389,8 @@ WRITE16_MEMBER( dcs_audio_device::dsio_w )
void dcs_audio_device::denver_reset()
{
memset(&m_dsio, 0, sizeof(m_dsio));
m_dmovlay_val = 0;
dmovlay_remap_memory();
}
@ -1370,6 +1403,7 @@ READ16_MEMBER( dcs_audio_device::denver_r )
/* returns 1 for DRAM, 2 for EPROM-based */
result = 0x0001;
}
if (LOG_DCS_IO) logerror("denver: denver_r 0x%x = %04x\n", offset, result);
return result;
}
@ -1417,6 +1451,7 @@ WRITE16_MEMBER( dcs_audio_device::denver_w )
m_fifo_reset_w(1);
break;
}
if (LOG_DCS_IO) logerror("denver: denver_w 0x%x = %04x\n", offset, data);
}
@ -1477,11 +1512,9 @@ void dcs_audio_device::dmovlay_remap_memory()
// Internal ram is bank 0
int bankSel;
if (m_dmovlay_val == 0) {
bankSel = 0;
m_data_bank->set_entry(bankSel);
m_ram_map->set_bank(0);
} else {
bankSel = 1 + (DSIO_DM_PG % m_sounddata_banks);
m_data_bank->set_entry(bankSel);
m_ram_map->set_bank(1);
}
if (LOG_DCS_IO)
logerror("%s dmovlay_remap_memory: Switching data ram location bankSel = %i\n", machine().describe_context(), bankSel);

View File

@ -11,6 +11,7 @@
#include "cpu/adsp2100/adsp2100.h"
#include "sound/dmadac.h"
#include "machine/bankdev.h"
#define MCFG_DCS2_AUDIO_DRAM_IN_MB(_dram_in_mb) \
dcs_audio_device::static_set_dram_in_mb(*device, _dram_in_mb);
@ -167,6 +168,7 @@ protected:
uint32_t m_sounddata_banks;
uint16_t m_sounddata_bank;
optional_device<address_map_bank_device> m_ram_map;
optional_memory_bank m_data_bank;
memory_bank * m_rom_page;
memory_bank * m_dram_page;
@ -203,6 +205,7 @@ protected:
uint16_t *m_polling_base;
uint32_t *m_internal_program_ram;
uint32_t *m_external_program_ram;
uint32_t *m_internal_data_ram;
int m_dmovlay_val;