MAMETesters Bugs Fixed:

05928: nbajamex: game crashes / nvram gets corrupted

- Emulated the Acclaim RAX sound board, adding sound to Batman Forever and NBA Jam Extreme [Phil Bennett]

- Hooked up extra NVRAM in NBA Jam Extreme [Phil Bennett]
This commit is contained in:
Phil Bennett 2016-11-06 00:59:59 -07:00
parent 4a096d1ccb
commit fffd464d34
11 changed files with 720 additions and 250 deletions

View File

@ -4574,6 +4574,8 @@ files {
MAME_DIR .. "src/mame/drivers/pse.cpp",
MAME_DIR .. "src/mame/drivers/quizo.cpp",
MAME_DIR .. "src/mame/drivers/quizpun2.cpp",
MAME_DIR .. "src/mame/audio/rax.cpp",
MAME_DIR .. "src/mame/audio/rax.h",
MAME_DIR .. "src/mame/drivers/rbmk.cpp",
MAME_DIR .. "src/mame/drivers/rcorsair.cpp",
MAME_DIR .. "src/mame/drivers/re900.cpp",

View File

@ -19,7 +19,7 @@ static const char *const shift_xop[] = { "SI", "??", "AR", "MR0", "MR1", "MR2",
static const char *const reg_grp[][16] =
{
{ "AX0", "AX1", "MX0", "MX1", "AY0", "AY1", "MY0", "MY1", "SI", "SE", "AR", "MR0", "MR1", "MR2", "SR0", "SR1" },
{ "I0", "I1", "I2", "I3", "M0", "M1", "M2", "M3", "L0", "L1", "L2", "L3", "??", "??", "??", "??" },
{ "I0", "I1", "I2", "I3", "M0", "M1", "M2", "M3", "L0", "L1", "L2", "L3", "??", "??", "PMOVLAY", "DMOVLAY" },
{ "I4", "I5", "I6", "I7", "M4", "M5", "M6", "M7", "L4", "L5", "L6", "L7", "??", "??", "??", "??" },
{ "ASTAT", "MSTAT", "SSTAT", "IMASK", "ICNTL", "CNTR", "SB", "PX", "RX0", "TX0", "RX1", "TX1", "IFC", "OWRCNTR", "??", "??" }
};

View File

@ -434,7 +434,7 @@ void adsp21xx_device::write_reg3(int regnum, int32_t val)
/* clear timer */
if (val & 0x0002) m_irq_latch[ADSP2181_IRQ0] = 0;
if (val & 0x0004) m_irq_latch[ADSP2181_IRQ1] = 0;
/* clear BDMA */
if (val & 0x0008) m_irq_latch[ADSP2181_BDMA] = 0;
if (val & 0x0010) m_irq_latch[ADSP2181_IRQE] = 0;
if (val & 0x0020) m_irq_latch[ADSP2181_SPORT0_RX] = 0;
if (val & 0x0040) m_irq_latch[ADSP2181_SPORT0_TX] = 0;
@ -442,7 +442,7 @@ void adsp21xx_device::write_reg3(int regnum, int32_t val)
/* force timer */
if (val & 0x0200) m_irq_latch[ADSP2181_IRQ0] = 1;
if (val & 0x0400) m_irq_latch[ADSP2181_IRQ1] = 1;
/* force BDMA */
if (val & 0x0800) m_irq_latch[ADSP2181_BDMA] = 1;
if (val & 0x1000) m_irq_latch[ADSP2181_IRQE] = 1;
if (val & 0x2000) m_irq_latch[ADSP2181_SPORT0_RX] = 1;
if (val & 0x4000) m_irq_latch[ADSP2181_SPORT0_TX] = 1;
@ -525,7 +525,7 @@ inline void adsp21xx_device::modify_address(uint32_t ireg, uint32_t mreg)
uint32_t i = m_i[ireg];
uint32_t l = m_l[ireg];
i += m_m[mreg];
i = (i + m_m[mreg]) & 0x3fff;
if (i < base) i += l;
else if (i >= base + l) i -= l;
m_i[ireg] = i;
@ -553,9 +553,10 @@ inline void adsp21xx_device::data_write_dag1(uint32_t op, int32_t val)
else
data_write(i, val);
i += m_m[mreg];
i = (i + m_m[mreg]) & 0x3fff;
if (i < base) i += l;
else if (i >= base + l) i -= l;
m_i[ireg] = i;
}
@ -577,7 +578,7 @@ inline uint32_t adsp21xx_device::data_read_dag1(uint32_t op)
else
res = data_read(i);
i += m_m[mreg];
i = (i + m_m[mreg]) & 0x3fff;
if (i < base) i += l;
else if (i >= base + l) i -= l;
m_i[ireg] = i;
@ -595,7 +596,7 @@ inline void adsp21xx_device::data_write_dag2(uint32_t op, int32_t val)
data_write(i, val);
i += m_m[mreg];
i = (i + m_m[mreg]) & 0x3fff;
if (i < base) i += l;
else if (i >= base + l) i -= l;
m_i[ireg] = i;
@ -612,7 +613,7 @@ inline uint32_t adsp21xx_device::data_read_dag2(uint32_t op)
uint32_t res = data_read(i);
i += m_m[mreg];
i = (i + m_m[mreg]) & 0x3fff;
if (i < base) i += l;
else if (i >= base + l) i -= l;
m_i[ireg] = i;
@ -634,7 +635,7 @@ inline void adsp21xx_device::pgm_write_dag2(uint32_t op, int32_t val)
program_write(i, (val << 8) | m_px);
i += m_m[mreg];
i = (i + m_m[mreg]) & 0x3fff;
if (i < base) i += l;
else if (i >= base + l) i -= l;
m_i[ireg] = i;
@ -654,7 +655,7 @@ inline uint32_t adsp21xx_device::pgm_read_dag2(uint32_t op)
m_px = res;
res >>= 8;
i += m_m[mreg];
i = (i + m_m[mreg]) & 0x3fff;
if (i < base) i += l;
else if (i >= base + l) i -= l;
m_i[ireg] = i;

View File

@ -631,7 +631,7 @@ void adsp21xx_device::device_reset()
// reset interrupts
m_imask = 0;
for (int irq = 0; irq < 8; irq++)
for (int irq = 0; irq < 10; irq++)
m_irq_state[irq] = m_irq_latch[irq] = CLEAR_LINE;
}
@ -986,9 +986,9 @@ void adsp2181_device::check_irqs()
if (check && generate_irq(ADSP2181_IRQL1, 1))
return;
// check IRQL2
check = m_irq_state[ADSP2181_IRQL2];
if (check && generate_irq(ADSP2181_IRQL2, 2))
// check IRQL0
check = m_irq_state[ADSP2181_IRQL0];
if (check && generate_irq(ADSP2181_IRQL0, 2))
return;
// check SPORT0 transmit
@ -1007,6 +1007,9 @@ void adsp2181_device::check_irqs()
return;
// check BDMA interrupt
check = m_irq_latch[ADSP2181_BDMA];
if (check && generate_irq(ADSP2181_BDMA, 6))
return;
// check IRQ1/SPORT1 transmit
check = (m_icntl & 2) ? m_irq_latch[ADSP2181_IRQ1] : m_irq_state[ADSP2181_IRQ1];

View File

@ -82,8 +82,9 @@ const int ADSP2181_SPORT0_RX = 3; // SPORT0 receive IRQ
const int ADSP2181_SPORT0_TX = 4; // SPORT0 transmit IRQ
const int ADSP2181_TIMER = 5; // internal timer IRQ
const int ADSP2181_IRQE = 6; // IRQE
const int ADSP2181_IRQL1 = 7; // IRQL1
const int ADSP2181_IRQL2 = 8; // IRQL2
const int ADSP2181_BDMA = 7; // BDMA
const int ADSP2181_IRQL1 = 8; // IRQL1
const int ADSP2181_IRQL0 = 9; // IRQL0
// register enumeration
enum
@ -424,8 +425,8 @@ protected:
uint16_t m_imask;
uint8_t m_icntl;
uint16_t m_ifc;
uint8_t m_irq_state[9];
uint8_t m_irq_latch[9];
uint8_t m_irq_state[10];
uint8_t m_irq_latch[10];
// other internal states
int m_icount;

View File

@ -146,6 +146,7 @@ enum
XTAL_16MHz = 16000000, /* Extremely common, used on 100's of PCBs */
XTAL_16_384MHz = 16384000,
XTAL_16_5888MHz = 16588800, /* SM 7238 */
XTAL_16_67MHz = 16670000,
XTAL_16_777216MHz = 16777216, /* Nintendo Game Boy Advance */
XTAL_16_9344MHz = 16934400, /* Usually used to drive 90's Yamaha OPL/FM chips (44100 * 384) */
XTAL_17_36MHz = 17360000, /* OMTI Series 10 SCSI controller */

522
src/mame/audio/rax.cpp Normal file
View File

@ -0,0 +1,522 @@
// license:BSD-3-Clause
// copyright-holders:Phil Bennett
/***************************************************************************
Acclaim RAX Sound Board
****************************************************************************/
#include "emu.h"
#include "rax.h"
/*************************************
*
* Constants
*
*************************************/
/* These are some of the control registers. We don't use them all */
enum
{
IDMA_CONTROL_REG = 0, /* 3fe0 */
BDMA_INT_ADDR_REG, /* 3fe1 */
BDMA_EXT_ADDR_REG, /* 3fe2 */
BDMA_CONTROL_REG, /* 3fe3 */
BDMA_WORD_COUNT_REG, /* 3fe4 */
PROG_FLAG_DATA_REG, /* 3fe5 */
PROG_FLAG_CONTROL_REG, /* 3fe6 */
S1_AUTOBUF_REG = 15, /* 3fef */
S1_RFSDIV_REG, /* 3ff0 */
S1_SCLKDIV_REG, /* 3ff1 */
S1_CONTROL_REG, /* 3ff2 */
S0_AUTOBUF_REG, /* 3ff3 */
S0_RFSDIV_REG, /* 3ff4 */
S0_SCLKDIV_REG, /* 3ff5 */
S0_CONTROL_REG, /* 3ff6 */
S0_MCTXLO_REG, /* 3ff7 */
S0_MCTXHI_REG, /* 3ff8 */
S0_MCRXLO_REG, /* 3ff9 */
S0_MCRXHI_REG, /* 3ffa */
TIMER_SCALE_REG, /* 3ffb */
TIMER_COUNT_REG, /* 3ffc */
TIMER_PERIOD_REG, /* 3ffd */
WAITSTATES_REG, /* 3ffe */
SYSCONTROL_REG /* 3fff */
};
/*************************************
*
* Interface
*
*************************************/
WRITE16_MEMBER( acclaim_rax_device::data_w )
{
m_data_in->write(space, 0, data, 0xffff);
m_cpu->set_input_line(ADSP2181_IRQL0, ASSERT_LINE);
machine().scheduler().boost_interleave(attotime::zero, attotime::from_usec(5));
}
READ16_MEMBER( acclaim_rax_device::data_r )
{
m_adsp_snd_pf0 = 1;
return m_data_out->read(space, 0);
}
/*************************************
*
* Internal
*
*************************************/
READ16_MEMBER( acclaim_rax_device::adsp_control_r )
{
uint16_t res = 0;
switch (offset)
{
case PROG_FLAG_DATA_REG:
res = m_adsp_snd_pf0;
break;
default:
res = m_control_regs[offset];
}
return res;
}
WRITE16_MEMBER( acclaim_rax_device::adsp_control_w )
{
m_control_regs[offset] = data;
switch (offset)
{
case 0x1:
m_control_regs[BDMA_INT_ADDR_REG] = data & 0x3fff;
break;
case 0x2:
m_control_regs[BDMA_EXT_ADDR_REG] = data & 0x3fff;
break;
case 0x3:
m_control_regs[BDMA_CONTROL_REG] = data & 0xff0f;
break;
case 0x4:
{
m_control_regs[BDMA_WORD_COUNT_REG] = data & 0x3fff;
const uint8_t * adsp_rom = m_rom + m_rom_bank * 0x400000;
uint32_t page = (m_control_regs[BDMA_CONTROL_REG] >> 8) & 0xff;
uint32_t dir = (m_control_regs[BDMA_CONTROL_REG] >> 2) & 1;
uint32_t type = m_control_regs[BDMA_CONTROL_REG] & 3;
uint32_t src_addr = (page << 14) | m_control_regs[BDMA_EXT_ADDR_REG];
uint32_t count = m_control_regs[BDMA_WORD_COUNT_REG];
address_space* addr_space = (type == 0 ? m_program : m_data);
if (dir == 0)
{
if (type == 0)
{
while (count)
{
uint32_t src_dword = (adsp_rom[src_addr + 0] << 16) | (adsp_rom[src_addr + 1] << 8) | adsp_rom[src_addr + 2];
addr_space->write_dword(m_control_regs[BDMA_INT_ADDR_REG] * 4, src_dword);
src_addr += 3;
++m_control_regs[BDMA_INT_ADDR_REG];
--count;
}
}
else if (type == 1)
{
while (count)
{
uint16_t src_word = (adsp_rom[src_addr + 0] << 8) | adsp_rom[src_addr + 1];
addr_space->write_word(m_control_regs[BDMA_INT_ADDR_REG] * 2, src_word);
src_addr += 2;
++m_control_regs[BDMA_INT_ADDR_REG];
--count;
}
}
else
{
int shift = type == 2 ? 8 : 0;
while (count)
{
uint16_t src_word = adsp_rom[src_addr] << shift;
addr_space->write_word(m_control_regs[BDMA_INT_ADDR_REG] * 2, src_word);
++src_addr;
++m_control_regs[BDMA_INT_ADDR_REG];
--count;
}
}
}
else
{
fatalerror("DMA to byte memory!");
}
attotime word_period = attotime::from_hz(m_cpu->unscaled_clock());
attotime period = word_period * (data & 0x3fff) * 1;
m_dma_timer->adjust(period, src_addr, period);
break;
}
case S1_AUTOBUF_REG:
/* autobuffer off: nuke the timer, and disable the DAC */
if ((data & 0x0002) == 0)
{
dmadac_enable(&m_dmadac[1], 1, 0);
}
break;
case S0_AUTOBUF_REG:
/* autobuffer off: nuke the timer, and disable the DAC */
if ((data & 0x0002) == 0)
{
dmadac_enable(&m_dmadac[0], 1, 0);
m_reg_timer[0]->reset();
}
break;
case S1_CONTROL_REG:
if (((data >> 4) & 3) == 2)
fatalerror("DCS: Oh no!, the data is compressed with u-law encoding\n");
if (((data >> 4) & 3) == 3)
fatalerror("DCS: Oh no!, the data is compressed with A-law encoding\n");
break;
case PROG_FLAG_DATA_REG:
logerror("PFLAGS: %x\n", data);
break;
case PROG_FLAG_CONTROL_REG:
logerror("PFLAG CTRL: %x\n", data);
break;
default:
logerror("Unhandled register: %x %x\n", 0x3fe0 + offset, data);
}
}
TIMER_DEVICE_CALLBACK_MEMBER( acclaim_rax_device::dma_timer_callback )
{
/* Update external address count and page */
m_control_regs[BDMA_WORD_COUNT_REG] = 0;
m_control_regs[BDMA_EXT_ADDR_REG] = param & 0x3fff;
m_control_regs[BDMA_CONTROL_REG] &= ~0xff00;
m_control_regs[BDMA_CONTROL_REG] |= ((param >> 14) & 0xff) << 8;
if (m_control_regs[BDMA_CONTROL_REG] & 8)
m_cpu->set_input_line(INPUT_LINE_RESET, PULSE_LINE);
else
m_cpu->machine().driver_data()->generic_pulse_irq_line(*m_cpu, ADSP2181_BDMA, 1);
timer.adjust(attotime::never);
}
void acclaim_rax_device::update_data_ram_bank()
{
if (m_dmovlay_val == 0)
membank("databank")->set_entry(0);
else
membank("databank")->set_entry(1 + m_data_bank);
}
WRITE16_MEMBER( acclaim_rax_device::ram_bank_w )
{
// Note: The PCB has two unstuffed RAM locations
m_data_bank = data & 3;
update_data_ram_bank();
}
WRITE16_MEMBER( acclaim_rax_device::rom_bank_w )
{
m_rom_bank = data;
}
READ16_MEMBER( acclaim_rax_device::host_r )
{
m_cpu->set_input_line(ADSP2181_IRQL0, CLEAR_LINE);
return m_data_in->read(space, 0);
}
WRITE16_MEMBER( acclaim_rax_device::host_w )
{
m_data_out->write(space, 0, data, 0xffff);
m_adsp_snd_pf0 = 0;
}
/*************************************
*
* CPU memory map & config
*
*************************************/
static ADDRESS_MAP_START( adsp_program_map, AS_PROGRAM, 32, acclaim_rax_device )
ADDRESS_MAP_UNMAP_HIGH
AM_RANGE(0x0000, 0x3fff) AM_RAM AM_SHARE("adsp_pram")
ADDRESS_MAP_END
static ADDRESS_MAP_START( adsp_data_map, AS_DATA, 16, acclaim_rax_device )
ADDRESS_MAP_UNMAP_HIGH
AM_RANGE(0x0000, 0x1fff) AM_RAMBANK("databank")
AM_RANGE(0x2000, 0x3fdf) AM_RAM // Internal RAM
AM_RANGE(0x3fe0, 0x3fff) AM_READWRITE(adsp_control_r, adsp_control_w)
ADDRESS_MAP_END
static ADDRESS_MAP_START( adsp_io_map, AS_IO, 16, acclaim_rax_device )
ADDRESS_MAP_UNMAP_HIGH
AM_RANGE(0x0000, 0x0000) AM_WRITE(ram_bank_w)
AM_RANGE(0x0001, 0x0001) AM_WRITE(rom_bank_w)
AM_RANGE(0x0003, 0x0003) AM_READWRITE(host_r, host_w)
ADDRESS_MAP_END
void acclaim_rax_device::device_start()
{
m_rom = (uint8_t *)machine().root_device().memregion("rax")->base();
m_program = &m_cpu->space(AS_PROGRAM);
m_data = &m_cpu->space(AS_DATA);
m_dmadac[0] = subdevice<dmadac_sound_device>("dacl");
m_dmadac[1] = subdevice<dmadac_sound_device>("dacr");
m_reg_timer[0] = subdevice<timer_device>("adsp_reg_timer0");
m_dma_timer = subdevice<timer_device>("adsp_dma_timer");
// 1 bank for internal
membank("databank")->configure_entries(0, 5, auto_alloc_array(machine(), uint16_t, 0x2000 * 5), 0x2000*sizeof(uint16_t));
}
void acclaim_rax_device::device_reset()
{
/* Load 32 program words (96 bytes) via BDMA */
for (int i = 0; i < 32; i ++)
{
uint32_t word;
word = m_rom[i*3 + 0] << 16;
word |= m_rom[i*3 + 1] << 8;
word |= m_rom[i*3 + 2];
m_adsp_pram[i] = word;
}
m_adsp_snd_pf0 = 1;
m_rom_bank = 0;
/* initialize our state structure and install the transmit callback */
m_size[0] = 0;
m_incs[0] = 0;
m_ireg[0] = 0;
/* initialize the ADSP control regs */
memset(m_control_regs, 0, sizeof(m_control_regs));
m_dmovlay_val = 0;
m_data_bank = 0;
update_data_ram_bank();
}
void acclaim_rax_device::adsp_irq(int which)
{
if (which != 0)
return;
/* get the index register */
int reg = m_cpu->state_int(ADSP2100_I0 + m_ireg[which]);
/* copy the current data into the buffer */
int count = m_size[which] / (4 * (m_incs[which] ? m_incs[which] : 1));
int16_t buffer[0x100];
for (uint32_t i = 0; i < count; i++)
{
buffer[i] = m_data->read_word(reg * 2);
reg += m_incs[which];
}
dmadac_transfer(&m_dmadac[0], 2, 1, 2, count/2, buffer);
/* check for wrapping */
if (reg >= m_ireg_base[which] + m_size[which])
{
/* reset the base pointer */
reg = m_ireg_base[which];
}
m_cpu->set_state_int(ADSP2100_I0 + m_ireg[which], reg);
}
TIMER_DEVICE_CALLBACK_MEMBER( acclaim_rax_device::adsp_irq0 )
{
adsp_irq(0);
}
void acclaim_rax_device::recompute_sample_rate(int which)
{
/* calculate how long until we generate an interrupt */
/* frequency the time per each bit sent */
attotime sample_period = attotime::from_hz(m_cpu->unscaled_clock()) * (1 * (m_control_regs[which ? S1_SCLKDIV_REG : S0_SCLKDIV_REG] + 1));
/* now put it down to samples, so we know what the channel frequency has to be */
sample_period = sample_period * (16 * 1);
dmadac_set_frequency(&m_dmadac[0], 2, ATTOSECONDS_TO_HZ(sample_period.attoseconds()));
dmadac_enable(&m_dmadac[0], 2, 1);
/* fire off a timer which will hit every half-buffer */
if (m_incs[which])
{
attotime period = (sample_period * m_size[which]) / (4 * 2 * m_incs[which]);
m_reg_timer[which]->adjust(period, 0, period);
}
}
WRITE32_MEMBER(acclaim_rax_device::adsp_sound_tx_callback)
{
int which = offset;
if (which != 0)
return;
int autobuf_reg = which ? S1_AUTOBUF_REG : S0_AUTOBUF_REG;
/* check if SPORT1 is enabled */
if (m_control_regs[SYSCONTROL_REG] & (which ? 0x0800 : 0x1000)) /* bit 11 */
{
/* we only support autobuffer here (which is what this thing uses), bail if not enabled */
if (m_control_regs[autobuf_reg] & 0x0002) /* bit 1 */
{
/* get the autobuffer registers */
int mreg, lreg;
uint16_t source;
m_ireg[which] = (m_control_regs[autobuf_reg] >> 9) & 7;
mreg = (m_control_regs[autobuf_reg] >> 7) & 3;
mreg |= m_ireg[which] & 0x04; /* msb comes from ireg */
lreg = m_ireg[which];
/* now get the register contents in a more legible format */
/* we depend on register indexes to be continuous (which is the case in our core) */
source = m_cpu->state_int(ADSP2100_I0 + m_ireg[which]);
m_incs[which] = m_cpu->state_int(ADSP2100_M0 + mreg);
m_size[which] = m_cpu->state_int(ADSP2100_L0 + lreg);
/* get the base value, since we need to keep it around for wrapping */
source -= m_incs[which];
/* make it go back one so we dont lose the first sample */
m_cpu->set_state_int(ADSP2100_I0 + m_ireg[which], source);
/* save it as it is now */
m_ireg_base[which] = source;
/* recompute the sample rate and timer */
recompute_sample_rate(which);
return;
}
else
logerror( "ADSP SPORT1: trying to transmit and autobuffer not enabled!\n" );
}
/* if we get there, something went wrong. Disable playing */
dmadac_enable(&m_dmadac[0], 2, 0);
/* remove timer */
m_reg_timer[which]->reset();
}
WRITE32_MEMBER(acclaim_rax_device::dmovlay_callback)
{
if (data < 0 || data > 1)
{
fatalerror("dmovlay_callback: Error! dmovlay called with value = %X\n", data);
}
else
{
m_dmovlay_val = data;
update_data_ram_bank();
}
}
/*************************************
*
* Machine Driver
*
*************************************/
MACHINE_CONFIG_FRAGMENT( rax )
MCFG_CPU_ADD("adsp", ADSP2181, XTAL_16_67MHz)
MCFG_ADSP21XX_SPORT_TX_CB(WRITE32(acclaim_rax_device, adsp_sound_tx_callback)) /* callback for serial transmit */
MCFG_ADSP21XX_DMOVLAY_CB(WRITE32(acclaim_rax_device, dmovlay_callback)) // callback for adsp 2181 dmovlay instruction
MCFG_CPU_PROGRAM_MAP(adsp_program_map)
MCFG_CPU_DATA_MAP(adsp_data_map)
MCFG_CPU_IO_MAP(adsp_io_map)
MCFG_TIMER_DEVICE_ADD("adsp_reg_timer0", DEVICE_SELF, acclaim_rax_device, adsp_irq0)
MCFG_TIMER_DEVICE_ADD("adsp_dma_timer", DEVICE_SELF, acclaim_rax_device, dma_timer_callback)
MCFG_GENERIC_LATCH_16_ADD("data_in")
MCFG_GENERIC_LATCH_16_ADD("data_out")
MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
MCFG_SOUND_ADD("dacl", DMADAC, 0)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 1.0)
MCFG_SOUND_ADD("dacr", DMADAC, 0)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 1.0)
MACHINE_CONFIG_END
const device_type ACCLAIM_RAX = &device_creator<acclaim_rax_device>;
//-------------------------------------------------
// acclaim_rax_device - constructor
//-------------------------------------------------
acclaim_rax_device::acclaim_rax_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, ACCLAIM_RAX, "Acclaim RAX", tag, owner, clock, "rax_audio", __FILE__),
m_cpu(*this, "adsp"),
m_adsp_pram(*this, "adsp_pram"),
m_adsp_data_bank(*this, "databank"),
m_data_in(*this, "data_in"),
m_data_out(*this, "data_out")
{
}
//-------------------------------------------------
// machine_config_additions - device-specific
// machine configurations
//-------------------------------------------------
machine_config_constructor acclaim_rax_device::device_mconfig_additions() const
{
return MACHINE_CONFIG_NAME( rax );
}

94
src/mame/audio/rax.h Normal file
View File

@ -0,0 +1,94 @@
// license:BSD-3-Clause
// copyright-holders:Phil Bennett
/***************************************************************************
Acclaim RAX Sound Board
****************************************************************************/
#ifndef __ACCLAIM_H__
#define __ACCLAIM_H__
#include "cpu/adsp2100/adsp2100.h"
#include "machine/gen_latch.h"
#include "sound/dmadac.h"
class acclaim_rax_device : public device_t
{
public:
// construction/destruction
acclaim_rax_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
READ16_MEMBER( data_r );
WRITE16_MEMBER( data_w );
READ16_MEMBER(adsp_control_r);
WRITE16_MEMBER(adsp_control_w);
WRITE16_MEMBER(ram_bank_w);
WRITE16_MEMBER(rom_bank_w);
READ16_MEMBER(host_r);
WRITE16_MEMBER(host_w);
void update_data_ram_bank();
void adsp_irq(int which);
void recompute_sample_rate(int which);
WRITE32_MEMBER(adsp_sound_tx_callback);
TIMER_DEVICE_CALLBACK_MEMBER(adsp_irq0);
TIMER_DEVICE_CALLBACK_MEMBER(sport0_irq);
WRITE32_MEMBER(dmovlay_callback);
required_device<adsp2181_device> m_cpu;
required_shared_ptr<uint32_t> m_adsp_pram;
required_memory_bank m_adsp_data_bank;
uint32_t m_adsp_snd_pf0;
struct
{
uint16_t bdma_internal_addr;
uint16_t bdma_external_addr;
uint16_t bdma_control;
uint16_t bdma_word_count;
} m_adsp_regs;
address_space *m_program;
address_space *m_data;
uint16_t m_control_regs[32];
uint8_t* m_rom;
/* sound output */
uint16_t m_size[2];
uint16_t m_incs[2];
dmadac_sound_device *m_dmadac[2];
timer_device *m_reg_timer[2];
timer_device *m_sport_timer;
uint32_t m_ireg[2];
uint16_t m_ireg_base[2];
uint32_t m_data_bank;
uint32_t m_rom_bank;
uint32_t m_dmovlay_val;
required_device<generic_latch_16_device> m_data_in;
required_device<generic_latch_16_device> m_data_out;
timer_device *m_dma_timer;
TIMER_DEVICE_CALLBACK_MEMBER( dma_timer_callback );
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
virtual machine_config_constructor device_mconfig_additions() const override;
};
// device type definition
extern const device_type ACCLAIM_RAX;
#endif

View File

@ -25,9 +25,6 @@
- danchih / danchiq: currently hangs randomly (regression).
- batmanfr: Missing sound,caused by an extra ADSP chip which is on the cart.The CPU is a
ADSP-2181,and it's the same used by NBA Jam Extreme (ZN game).
- vfremix: when you play as Akira, there is a problem with third match: game doesn't upload all textures
and tiles and doesn't enable display, although gameplay is normal - wait a while to get back
to title screen after losing a match
@ -40,12 +37,11 @@
#include "emu.h"
#include "cpu/sh2/sh2.h"
#include "cpu/m68000/m68000.h"
#include "cpu/adsp2100/adsp2100.h"
#include "cpu/scudsp/scudsp.h"
#include "machine/eepromser.h"
#include "sound/scsp.h"
#include "sound/cdda.h"
#include "sound/dmadac.h"
#include "audio/rax.h"
#include "machine/smpc.h"
#include "machine/stvprot.h"
#include "includes/stv.h"
@ -1004,7 +1000,7 @@ static MACHINE_CONFIG_START( stv, stv_state )
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_VIDEO_ATTRIBUTES(VIDEO_UPDATE_AFTER_VBLANK)
MCFG_SCREEN_RAW_PARAMS(MASTER_CLOCK_320/8, 427, 0, 320, 263, 0, 224)
MCFG_SCREEN_RAW_PARAMS(MASTER_CLOCK_320/8, 427, 0, 352, 263, 0, 224)
MCFG_SCREEN_UPDATE_DRIVER(stv_state, screen_update_stv_vdp2)
MCFG_PALETTE_ADD("palette", 2048+(2048*2))//standard palette + extra memory for rgb brightness.
@ -1056,163 +1052,16 @@ MACHINE_CONFIG_END
WRITE32_MEMBER( stv_state::batmanfr_sound_comms_w )
{
// FIXME
if(ACCESSING_BITS_16_31)
m_soundlatch->write(space, 0, data >> 16, 0x0000ffff);
m_rax->data_w(space, 0, data >> 16, 0x0000ffff);
if(ACCESSING_BITS_0_15)
printf("Warning: write %04x & %08x to lo-word sound communication area\n",data,mem_mask);
}
READ16_MEMBER( stv_state::adsp_control_r )
{
uint16_t res = 0;
switch (offset)
{
case 0x4:
res = m_adsp_regs.bdma_word_count;
break;
/* TODO: is this location correct? */
case 0x5:
res = m_soundlatch->read(space,0);
break;
default:
osd_printf_debug("Unhandled register: %x\n", 0x3fe0 + offset);
}
return res;
}
WRITE16_MEMBER( stv_state::adsp_control_w )
{
switch (offset)
{
case 0x1:
m_adsp_regs.bdma_internal_addr = data & 0x3fff;
break;
case 0x2:
m_adsp_regs.bdma_external_addr = data & 0x3fff;
break;
case 0x3:
m_adsp_regs.bdma_control = data & 0xff0f;
break;
case 0x4:
{
m_adsp_regs.bdma_word_count = data & 0x3fff;
if (data > 0)
{
uint8_t* adsp_rom = (uint8_t*)memregion("adsp")->base();
uint32_t page = (m_adsp_regs.bdma_control >> 8) & 0xff;
uint32_t dir = (m_adsp_regs.bdma_control >> 2) & 1;
uint32_t type = m_adsp_regs.bdma_control & 3;
uint32_t src_addr = (page << 14) | m_adsp_regs.bdma_external_addr;
address_space &addr_space = m_adsp->space((type == 0) ? AS_PROGRAM : AS_DATA);
if (dir == 0)
{
while (m_adsp_regs.bdma_word_count)
{
if (type == 0)
{
uint32_t src_word =(adsp_rom[src_addr + 0] << 16) |
(adsp_rom[src_addr + 1] << 8) |
(adsp_rom[src_addr + 2]);
addr_space.write_dword(m_adsp_regs.bdma_internal_addr * 4, src_word);
src_addr += 3;
m_adsp_regs.bdma_internal_addr ++;
}
else if (type == 1)
{
uint32_t src_word =(adsp_rom[src_addr + 0] << 8) | adsp_rom[src_addr + 1];
addr_space.write_dword(m_adsp_regs.bdma_internal_addr * 2, src_word);
src_addr += 2;
m_adsp_regs.bdma_internal_addr ++;
}
else
{
fatalerror("Unsupported BDMA width\n");
}
--m_adsp_regs.bdma_word_count;
}
}
/* Update external address count and page */
m_adsp_regs.bdma_external_addr = src_addr & 0x3fff;
m_adsp_regs.bdma_control &= ~0xff00;
m_adsp_regs.bdma_control |= ((src_addr >> 14) & 0xff) << 8;
if (m_adsp_regs.bdma_control & 8)
m_adsp->set_input_line(INPUT_LINE_RESET, PULSE_LINE);
}
break;
}
case 5:
osd_printf_debug("PFLAGS: %x\n", data);
break;
default:
osd_printf_debug("Unhandled register: %x %x\n", 0x3fe0 + offset, data);
}
}
static ADDRESS_MAP_START( adsp_program_map, AS_PROGRAM, 32, stv_state )
ADDRESS_MAP_UNMAP_HIGH
AM_RANGE(0x0000, 0x3fff) AM_RAM AM_SHARE("adsp_pram")
ADDRESS_MAP_END
static ADDRESS_MAP_START( adsp_data_map, AS_DATA, 16, stv_state )
ADDRESS_MAP_UNMAP_HIGH
// AM_RANGE(0x0000, 0x03ff) AM_RAMBANK("databank")
AM_RANGE(0x0400, 0x3fdf) AM_RAM
AM_RANGE(0x3fe0, 0x3fff) AM_READWRITE(adsp_control_r, adsp_control_w)
ADDRESS_MAP_END
static ADDRESS_MAP_START( adsp_io_map, AS_IO, 16, stv_state )
ADDRESS_MAP_UNMAP_HIGH
ADDRESS_MAP_END
MACHINE_RESET_MEMBER(stv_state,batmanfr)
{
MACHINE_RESET_CALL_MEMBER(stv);
uint8_t *adsp_boot = (uint8_t*)memregion("adsp")->base();
/* Load 32 program words (96 bytes) via BDMA */
for (int i = 0; i < 32; i ++)
{
uint32_t word;
word = adsp_boot[i*3 + 0] << 16;
word |= adsp_boot[i*3 + 1] << 8;
word |= adsp_boot[i*3 + 2];
m_adsp_pram[i] = word;
}
}
static MACHINE_CONFIG_DERIVED( batmanfr, stv )
MCFG_CPU_ADD("adsp", ADSP2181, 16000000)
MCFG_CPU_PROGRAM_MAP(adsp_program_map)
MCFG_CPU_DATA_MAP(adsp_data_map)
MCFG_CPU_IO_MAP(adsp_io_map)
MCFG_MACHINE_RESET_OVERRIDE(stv_state,batmanfr)
MCFG_GENERIC_LATCH_16_ADD("soundlatch")
MCFG_SOUND_ADD("dac1", DMADAC, 0)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 1.0)
MCFG_SOUND_ADD("dac2", DMADAC, 0)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 1.0)
MCFG_DEVICE_ADD("rax", ACCLAIM_RAX, 0)
MACHINE_CONFIG_END
@ -2766,14 +2615,12 @@ ROM_START( batmanfr )
ROM_LOAD16_WORD_SWAP( "gfx5.u15", 0x1800000, 0x0400000, CRC(e201f830) SHA1(5aa22fcc8f2e153d1abc3aa4050c594b3942ee67) )
ROM_LOAD16_WORD_SWAP( "gfx6.u18", 0x1c00000, 0x0400000, CRC(c6b381a3) SHA1(46431f1e47c084a0bf85535d35af27471653b008) )
ROM_REGION16_LE( 0x80000, "adsp", 0 )
ROM_LOAD( "350snda1.u52", 0x000000, 0x080000, CRC(9027e7a0) SHA1(678df530838b078964a044ce734776f391654e6c) )
ROM_REGION32_BE( 0x800000, "adsp_data", 0 ) /* ADSP code */
ROM_LOAD( "snd0.u48", 0x000000, 0x200000, CRC(02b1927c) SHA1(08b21d8b31b0f15c59fb5bb7eaf425e6fe04f7b5) )
ROM_LOAD( "snd1.u49", 0x200000, 0x200000, CRC(58b18eda) SHA1(7f3105fe04d9c0cdfd76e3323f623a4d0f7dad06) )
ROM_LOAD( "snd2.u50", 0x400000, 0x200000, CRC(51d626d6) SHA1(0e68b79dcb653dcba48121ca2d4f692f90afa85e) )
ROM_LOAD( "snd3.u51", 0x600000, 0x200000, CRC(31af26ae) SHA1(2c9f4c078afec55964b5c2a4d00f5c43f2661a04) )
ROM_REGION16_LE( 0x1000000, "rax", 0 )
ROM_LOAD( "350snda1.u52", 0x000000, 0x080000, CRC(9027e7a0) SHA1(678df530838b078964a044ce734776f391654e6c) )
ROM_LOAD( "snd0.u48", 0x400000, 0x200000, CRC(02b1927c) SHA1(08b21d8b31b0f15c59fb5bb7eaf425e6fe04f7b5) )
ROM_LOAD( "snd1.u49", 0x600000, 0x200000, CRC(58b18eda) SHA1(7f3105fe04d9c0cdfd76e3323f623a4d0f7dad06) )
ROM_LOAD( "snd2.u50", 0x800000, 0x200000, CRC(51d626d6) SHA1(0e68b79dcb653dcba48121ca2d4f692f90afa85e) )
ROM_LOAD( "snd3.u51", 0xa00000, 0x200000, CRC(31af26ae) SHA1(2c9f4c078afec55964b5c2a4d00f5c43f2661a04) )
ROM_END
/*
@ -3534,7 +3381,7 @@ GAME( 1996, stvbios, 0, stv_slot, stv, stv_state, stv, ROT0
/* Playable */
GAME( 1998, astrass, stvbios, stv_5881, stv6b, stv_state, astrass, ROT0, "Sunsoft", "Astra SuperStars (J 980514 V1.002)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
GAME( 1995, bakubaku, stvbios, stv, stv, stv_state, stv, ROT0, "Sega", "Baku Baku Animal (J 950407 V1.000)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS )
GAME( 1996, batmanfr, stvbios, batmanfr, stv, stv_state, batmanfr, ROT0, "Acclaim", "Batman Forever (JUE 960507 V1.000)", MACHINE_NO_SOUND | MACHINE_IMPERFECT_GRAPHICS )
GAME( 1996, batmanfr, stvbios, batmanfr, stv, stv_state, batmanfr, ROT0, "Acclaim", "Batman Forever (JUE 960507 V1.000)", MACHINE_IMPERFECT_GRAPHICS )
GAME( 1996, colmns97, stvbios, stv, stv, stv_state, colmns97, ROT0, "Sega", "Columns '97 (JET 961209 V1.000)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS )
GAME( 1997, cotton2, stvbios, stv, stv, stv_state, cotton2, ROT0, "Success", "Cotton 2 (JUET 970902 V1.000)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS )
GAME( 1998, cottonbm, stvbios, stv, stv, stv_state, cottonbm, ROT0, "Success", "Cotton Boomerang (JUET 980709 V1.000)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS )

View File

@ -30,6 +30,7 @@
#include "sound/qsound.h"
#include "sound/spu.h"
#include "sound/ymf271.h"
#include "audio/rax.h"
#include "audio/taito_zm.h"
#define VERBOSE_LEVEL ( 0 )
@ -52,6 +53,7 @@ public:
m_cbaj_fifo2(*this, "cbaj_fifo2"),
m_mb3773(*this, "mb3773"),
m_zoom(*this, "taito_zoom"),
m_rax(*this, "rax"),
m_vt83c461(*this, "ide"),
m_soundlatch(*this, "soundlatch"),
m_soundlatch16(*this, "soundlatch16"),
@ -90,6 +92,7 @@ public:
DECLARE_WRITE16_MEMBER(acpsx_10_w);
DECLARE_WRITE16_MEMBER(nbajamex_bank_w);
DECLARE_WRITE16_MEMBER(nbajamex_80_w);
DECLARE_WRITE8_MEMBER(nbajamex_backup_w);
DECLARE_READ16_MEMBER(nbajamex_08_r);
DECLARE_READ16_MEMBER(nbajamex_80_r);
DECLARE_WRITE8_MEMBER(coh1001l_bank_w);
@ -104,6 +107,7 @@ public:
DECLARE_READ16_MEMBER(vt83c461_32_r);
DECLARE_WRITE16_MEMBER(vt83c461_32_w);
DECLARE_DRIVER_INIT(coh1000tb);
DECLARE_DRIVER_INIT(nbajamex);
DECLARE_MACHINE_RESET(coh1000c);
DECLARE_MACHINE_RESET(glpracr);
DECLARE_MACHINE_RESET(coh1000ta);
@ -130,6 +134,9 @@ private:
int m_jdredd_gun_mux;
std::unique_ptr<uint8_t[]> m_fx1b_fram;
std::unique_ptr<uint8_t[]> m_nbajamex_sram;
uint32_t m_nbajamex_rombank[2];
uint16_t m_vt83c461_latch;
@ -146,6 +153,7 @@ private:
optional_device<fifo7200_device> m_cbaj_fifo2;
optional_device<mb3773_device> m_mb3773;
optional_device<taito_zoom_device> m_zoom;
optional_device<acclaim_rax_device> m_rax;
optional_device<vt83c461_device> m_vt83c461;
optional_device<generic_latch_8_device> m_soundlatch;
optional_device<generic_latch_16_device> m_soundlatch16;
@ -1853,8 +1861,6 @@ WRITE16_MEMBER(zn_state::acpsx_00_w)
WRITE16_MEMBER(zn_state::nbajamex_bank_w)
{
uint32_t newbank = 0;
verboselog(0, "nbajamex_bank_w( %08x, %08x, %08x )\n", offset, data, mem_mask );
if (offset > 1)
@ -1862,30 +1868,32 @@ WRITE16_MEMBER(zn_state::nbajamex_bank_w)
logerror("Unknown banking offset %x!\n", offset);
}
if (offset == 1)
{
data -= 1;
}
if (data <= 1)
{
newbank = (data * 0x400000);
}
else if (data >= 0x10)
{
data -= 0x10;
newbank = (data * 0x400000);
newbank += 0x200000;
}
m_nbajamex_rombank[offset] = data;
uint32_t bankbase0 = ((m_nbajamex_rombank[0] & 0x10) ? 0x200000 : 0) + (m_nbajamex_rombank[0] & 7) * 0x400000;
uint32_t bankbase1 = ((m_nbajamex_rombank[1] & 0x10) ? 0 : 0x200000) + (m_nbajamex_rombank[1] & 7) * 0x400000;
if (offset == 0)
{
membank( "bankedroms" )->set_base( memregion( "bankedroms" )->base() + newbank);
if (m_nbajamex_rombank[0] == 0)
{
m_maincpu->space(AS_PROGRAM).install_read_bank(0x1f200000, 0x1f207fff, "sram");
membank( "sram" )->set_base( m_nbajamex_sram.get() );
}
else
{
m_maincpu->space(AS_PROGRAM).install_read_bank(0x1f200000, 0x1f7fffff, "bankedroms2");
membank( "bankedroms2" )->set_base( memregion( "bankedroms" )->base() + bankbase1);
}
membank( "bankedroms" )->set_base( memregion( "bankedroms" )->base() + bankbase0);
}
else if (offset == 1)
{
newbank += 0x200000;
membank( "bankedroms2" )->set_base( memregion( "bankedroms" )->base() + newbank);
if (m_nbajamex_rombank[0] != 0)
{
m_maincpu->space(AS_PROGRAM).install_read_bank(0x1f200000, 0x1f7fffff, "bankedroms2");
membank( "bankedroms2" )->set_base( memregion( "bankedroms" )->base() + bankbase1);
}
}
}
@ -1897,26 +1905,29 @@ WRITE16_MEMBER(zn_state::acpsx_10_w)
// all 16 bits goes to the external soundboard's latch (see sound test menu)
WRITE16_MEMBER(zn_state::nbajamex_80_w)
{
verboselog(0, "nbajamex_80_w( %08x, %08x, %08x )\n", offset, data, mem_mask );
psxirq_device *psxirq = (psxirq_device *) machine().device("maincpu:irq");
psxirq->intin10(1);
m_rax->data_w(space, 0, data, 0xffff);
}
READ16_MEMBER(zn_state::nbajamex_08_r)
{
uint32_t data = 0xffffffff;
verboselog(0, "nbajamex_08_r( %08x, %08x, %08x )\n", offset, data, mem_mask );
return data;
// Sound related
verboselog(0, "nbajamex_08_r( %08x, %08x, %08x )\n", offset, 0, mem_mask );
return 0x400;
}
// possibly a readback from the external soundboard?
READ16_MEMBER(zn_state::nbajamex_80_r)
{
uint32_t data = 0xffffffff;
verboselog(0, "nbajamex_80_r( %08x, %08x, %08x )\n", offset, data, mem_mask );
return data;
verboselog(0, "nbajamex_80_r( %08x, %08x, %08x )\n", offset, 0, mem_mask );
return 0xffff;
}
WRITE8_MEMBER(zn_state::nbajamex_backup_w)
{
m_nbajamex_sram[offset] = data;
}
static ADDRESS_MAP_START(coh1000a_map, AS_PROGRAM, 32, zn_state)
AM_RANGE(0x1fbfff00, 0x1fbfff03) AM_WRITE16(acpsx_00_w, 0xffffffff)
AM_RANGE(0x1fbfff10, 0x1fbfff13) AM_WRITE16(acpsx_10_w, 0xffff0000)
@ -1926,7 +1937,7 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START(nbajamex_map, AS_PROGRAM, 32, zn_state)
AM_RANGE(0x1f000000, 0x1f1fffff) AM_ROMBANK("bankedroms")
AM_RANGE(0x1f200000, 0x1f7fffff) AM_ROMBANK("bankedroms2")
AM_RANGE(0x1f200000, 0x1f207fff) AM_WRITE8(nbajamex_backup_w, 0xffffffff)
AM_RANGE(0x1fbfff00, 0x1fbfff07) AM_WRITE16(nbajamex_bank_w, 0xffffffff)
AM_RANGE(0x1fbfff08, 0x1fbfff0b) AM_READ16(nbajamex_08_r, 0xffff)
AM_RANGE(0x1fbfff80, 0x1fbfff83) AM_READWRITE16(nbajamex_80_r, nbajamex_80_w, 0xffff)
@ -1934,10 +1945,16 @@ static ADDRESS_MAP_START(nbajamex_map, AS_PROGRAM, 32, zn_state)
AM_IMPORT_FROM(coh1000a_map)
ADDRESS_MAP_END
DRIVER_INIT_MEMBER(zn_state,nbajamex)
{
m_nbajamex_sram = std::make_unique<uint8_t[]>(0x80000);
machine().device<nvram_device>("71256")->set_base(m_nbajamex_sram.get(), 0x8000);
}
MACHINE_RESET_MEMBER(zn_state,nbajamex)
{
membank( "bankedroms" )->set_base( memregion( "bankedroms" )->base() );
membank( "bankedroms2" )->set_base( memregion( "bankedroms" )->base() + 0x200000 );
}
static ADDRESS_MAP_START(jdredd_map, AS_PROGRAM, 32, zn_state)
@ -1956,7 +1973,9 @@ MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( nbajamex, coh1000a )
MCFG_CPU_MODIFY("maincpu")
MCFG_CPU_PROGRAM_MAP(nbajamex_map)
MCFG_NVRAM_ADD_1FILL("71256")
MCFG_MACHINE_RESET_OVERRIDE(zn_state, nbajamex)
MCFG_DEVICE_ADD("rax", ACCLAIM_RAX, 0)
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( jdredd, coh1000a )
@ -4865,13 +4884,10 @@ ROM_START( nbajamex )
ROM_LOAD16_BYTE( "nba6o.u5", 0x1a00001, 0x200000, CRC(b1dfb42e) SHA1(fb9627e228bf2a744842eb44afbca4a6232cadb2) )
ROM_LOAD16_BYTE( "nba6e.u19", 0x1a00000, 0x200000, CRC(6f17d8c1) SHA1(22cf263efb64cf62030e02b641c485debe75944d) )
ROM_REGION( 0x0a0000, "cpu1", 0 ) /* 512k for the audio CPU, ADSP-2181 (+banks) */
ROM_LOAD( "360snda1.u52", 0x000000, 0x08000, CRC(36d8a628) SHA1(944a01c9128f5e90c7dba3557a3ecb2c5ca90831) )
ROM_CONTINUE( 0x010000, 0x78000 )
ROM_REGION( 0x400000, "unknown", 0 )
ROM_LOAD( "sound0.u48", 0x000000, 0x200000, CRC(38873b67) SHA1(b2f8d32270ae604c099a1b9b71d2e06468c7d4a9) )
ROM_LOAD( "sound1.u49", 0x200000, 0x200000, CRC(57014589) SHA1(d360ff1c52424bd91a5a8d1a2a9c10bf7abb0602) )
ROM_REGION16_LE( 0x800000, "rax", 0 )
ROM_LOAD( "360snda1.u52", 0x000000, 0x080000, CRC(36d8a628) SHA1(944a01c9128f5e90c7dba3557a3ecb2c5ca90831) )
ROM_LOAD( "sound0.u48", 0x400000, 0x200000, CRC(38873b67) SHA1(b2f8d32270ae604c099a1b9b71d2e06468c7d4a9) )
ROM_LOAD( "sound1.u49", 0x600000, 0x200000, CRC(57014589) SHA1(d360ff1c52424bd91a5a8d1a2a9c10bf7abb0602) )
ROM_REGION( 0x8, "cat702_2", 0 )
ROM_LOAD( "ac02", 0x000000, 0x000008, CRC(1412d475) SHA1(c2f62232a261870f58353d09dc0d6ce2ad17a729) )
@ -4898,16 +4914,17 @@ ROM_START( nbajamexa )
ROM_LOAD16_BYTE( "nba6o.u5", 0x1a00001, 0x200000, CRC(b1dfb42e) SHA1(fb9627e228bf2a744842eb44afbca4a6232cadb2) )
ROM_LOAD16_BYTE( "nba6e.u19", 0x1a00000, 0x200000, CRC(6f17d8c1) SHA1(22cf263efb64cf62030e02b641c485debe75944d) )
ROM_REGION( 0x0a0000, "cpu1", 0 ) /* 512k for the audio CPU, ADSP-2181 (+banks) */
ROM_LOAD( "360snda1.u52", 0x000000, 0x08000, CRC(36d8a628) SHA1(944a01c9128f5e90c7dba3557a3ecb2c5ca90831) )
ROM_CONTINUE( 0x010000, 0x78000 )
ROM_REGION( 0x400000, "unknown", 0 )
ROM_LOAD( "sound0.u48", 0x000000, 0x200000, CRC(38873b67) SHA1(b2f8d32270ae604c099a1b9b71d2e06468c7d4a9) )
ROM_LOAD( "sound1.u49", 0x200000, 0x200000, CRC(57014589) SHA1(d360ff1c52424bd91a5a8d1a2a9c10bf7abb0602) )
ROM_REGION( 0x8, "cat702_2", 0 )
ROM_LOAD( "ac02", 0x000000, 0x000008, CRC(1412d475) SHA1(c2f62232a261870f58353d09dc0d6ce2ad17a729) )
ROM_REGION16_LE( 0x800000, "rax", 0 )
ROM_LOAD( "360snda1.u52", 0x000000, 0x080000, CRC(36d8a628) SHA1(944a01c9128f5e90c7dba3557a3ecb2c5ca90831) )
ROM_LOAD( "sound0.u48", 0x400000, 0x200000, CRC(38873b67) SHA1(b2f8d32270ae604c099a1b9b71d2e06468c7d4a9) )
ROM_LOAD( "sound1.u49", 0x600000, 0x200000, CRC(57014589) SHA1(d360ff1c52424bd91a5a8d1a2a9c10bf7abb0602) )
ROM_END
ROM_START( jdredd )
@ -5029,8 +5046,8 @@ GAME( 1996, primrag2, coh1000w, coh1000w, primrag2, driver_device, 0, ROT0,
/* Acclaim */
GAME( 1995, coh1000a, 0, coh1000a, zn, driver_device, 0, ROT0, "Acclaim", "Acclaim PSX", MACHINE_IS_BIOS_ROOT )
GAME( 1996, nbajamex, coh1000a, nbajamex, zn, driver_device, 0, ROT0, "Acclaim", "NBA Jam Extreme (ver. 1.10I)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
GAME( 1996, nbajamexa, nbajamex, nbajamex, zn, driver_device, 0, ROT0, "Acclaim", "NBA Jam Extreme (ver. 1.04)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
GAME( 1996, nbajamex, coh1000a, nbajamex, zn, zn_state, nbajamex, ROT0, "Acclaim", "NBA Jam Extreme (ver. 1.10I)", MACHINE_IMPERFECT_GRAPHICS )
GAME( 1996, nbajamexa, nbajamex, nbajamex, zn, zn_state, nbajamex, ROT0, "Acclaim", "NBA Jam Extreme (ver. 1.04)", MACHINE_IMPERFECT_GRAPHICS )
GAME( 1996, jdredd, coh1000a, jdredd, jdredd, driver_device, 0, ROT0, "Acclaim", "Judge Dredd (Rev C Dec. 17 1997)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
GAME( 1996, jdreddb, jdredd, jdredd, jdredd, driver_device, 0, ROT0, "Acclaim", "Judge Dredd (Rev B Nov. 26 1997)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )

View File

@ -2,18 +2,16 @@
// copyright-holders:David Haywood, Angelo Salese, Olivier Galibert, Mariusz Wojcieszek, R. Belmont
#include "includes/saturn.h"
#include "machine/gen_latch.h"
#include "audio/rax.h"
class stv_state : public saturn_state
{
public:
stv_state(const machine_config &mconfig, device_type type, const char *tag)
: saturn_state(mconfig, type, tag),
m_adsp(*this, "adsp"),
m_adsp_pram(*this, "adsp_pram"),
m_rax(*this, "rax"),
m_cryptdevice(*this, "315_5881"),
m_5838crypt(*this, "315_5838"),
m_soundlatch(*this, "soundlatch")
m_5838crypt(*this, "315_5838")
{
}
@ -91,22 +89,9 @@ public:
DECLARE_MACHINE_START(stv);
DECLARE_MACHINE_RESET(stv);
/* Batman Forever specifics */
optional_device<adsp2181_device> m_adsp;
optional_shared_ptr<uint32_t> m_adsp_pram;
struct
{
uint16_t bdma_internal_addr;
uint16_t bdma_external_addr;
uint16_t bdma_control;
uint16_t bdma_word_count;
} m_adsp_regs;
DECLARE_MACHINE_RESET(batmanfr);
DECLARE_READ16_MEMBER( adsp_control_r );
DECLARE_WRITE16_MEMBER( adsp_control_w );
DECLARE_WRITE32_MEMBER(batmanfr_sound_comms_w);
optional_device<acclaim_rax_device> m_rax;
// protection specific variables and functions (see machine/stvprot.c)
uint32_t m_abus_protenable;
@ -120,11 +105,8 @@ public:
void install_common_protection();
void stv_register_protection_savestates();
optional_device<sega_315_5881_crypt_device> m_cryptdevice;
optional_device<sega_315_5838_comp_device> m_5838crypt;
optional_device<generic_latch_16_device> m_soundlatch; // batmanfr
uint16_t crypt_read_callback(uint32_t addr);
uint16_t crypt_read_callback_ch1(uint32_t addr);
uint16_t crypt_read_callback_ch2(uint32_t addr);