mirror of
https://github.com/holub/mame
synced 2025-10-05 08:41:31 +03:00
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:
parent
4a096d1ccb
commit
fffd464d34
@ -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",
|
||||
|
@ -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", "??", "??" }
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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];
|
||||
|
@ -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;
|
||||
|
@ -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
522
src/mame/audio/rax.cpp
Normal 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
94
src/mame/audio/rax.h
Normal 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
|
@ -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 )
|
||||
|
@ -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 )
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user