From fffd464d345a6368cda7d90945d3409151218a06 Mon Sep 17 00:00:00 2001
From: Phil Bennett
Date: Sun, 6 Nov 2016 00:59:59 -0700
Subject: [PATCH] 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]
---
scripts/target/mame/arcade.lua | 2 +
src/devices/cpu/adsp2100/2100dasm.cpp | 2 +-
src/devices/cpu/adsp2100/2100ops.hxx | 19 +-
src/devices/cpu/adsp2100/adsp2100.cpp | 11 +-
src/devices/cpu/adsp2100/adsp2100.h | 9 +-
src/emu/drivers/xtal.h | 1 +
src/mame/audio/rax.cpp | 522 ++++++++++++++++++++++++++
src/mame/audio/rax.h | 94 +++++
src/mame/drivers/stv.cpp | 177 +--------
src/mame/drivers/zn.cpp | 107 +++---
src/mame/includes/stv.h | 26 +-
11 files changed, 720 insertions(+), 250 deletions(-)
create mode 100644 src/mame/audio/rax.cpp
create mode 100644 src/mame/audio/rax.h
diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua
index 6b515e2d399..2b099d410b0 100644
--- a/scripts/target/mame/arcade.lua
+++ b/scripts/target/mame/arcade.lua
@@ -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",
diff --git a/src/devices/cpu/adsp2100/2100dasm.cpp b/src/devices/cpu/adsp2100/2100dasm.cpp
index 40540c93111..1508d360c81 100644
--- a/src/devices/cpu/adsp2100/2100dasm.cpp
+++ b/src/devices/cpu/adsp2100/2100dasm.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", "??", "??" }
};
diff --git a/src/devices/cpu/adsp2100/2100ops.hxx b/src/devices/cpu/adsp2100/2100ops.hxx
index c027c3514a2..0b9aded2a22 100644
--- a/src/devices/cpu/adsp2100/2100ops.hxx
+++ b/src/devices/cpu/adsp2100/2100ops.hxx
@@ -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;
diff --git a/src/devices/cpu/adsp2100/adsp2100.cpp b/src/devices/cpu/adsp2100/adsp2100.cpp
index 2da39e6e2f3..617f2324540 100644
--- a/src/devices/cpu/adsp2100/adsp2100.cpp
+++ b/src/devices/cpu/adsp2100/adsp2100.cpp
@@ -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];
diff --git a/src/devices/cpu/adsp2100/adsp2100.h b/src/devices/cpu/adsp2100/adsp2100.h
index d17b0cd55f5..f5e43700b0f 100644
--- a/src/devices/cpu/adsp2100/adsp2100.h
+++ b/src/devices/cpu/adsp2100/adsp2100.h
@@ -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;
diff --git a/src/emu/drivers/xtal.h b/src/emu/drivers/xtal.h
index 8747ec25c0f..01c232cf2fa 100644
--- a/src/emu/drivers/xtal.h
+++ b/src/emu/drivers/xtal.h
@@ -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 */
diff --git a/src/mame/audio/rax.cpp b/src/mame/audio/rax.cpp
new file mode 100644
index 00000000000..ca285659913
--- /dev/null
+++ b/src/mame/audio/rax.cpp
@@ -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("dacl");
+ m_dmadac[1] = subdevice("dacr");
+
+ m_reg_timer[0] = subdevice("adsp_reg_timer0");
+ m_dma_timer = subdevice("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 - 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 );
+}
+
diff --git a/src/mame/audio/rax.h b/src/mame/audio/rax.h
new file mode 100644
index 00000000000..e284771f79a
--- /dev/null
+++ b/src/mame/audio/rax.h
@@ -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 m_cpu;
+ required_shared_ptr 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 m_data_in;
+ required_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
diff --git a/src/mame/drivers/stv.cpp b/src/mame/drivers/stv.cpp
index 7f0d26a3212..a347a848f93 100644
--- a/src/mame/drivers/stv.cpp
+++ b/src/mame/drivers/stv.cpp
@@ -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 )
diff --git a/src/mame/drivers/zn.cpp b/src/mame/drivers/zn.cpp
index 8c6a5554f7b..816ee52fcee 100644
--- a/src/mame/drivers/zn.cpp
+++ b/src/mame/drivers/zn.cpp
@@ -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 m_fx1b_fram;
+ std::unique_ptr m_nbajamex_sram;
+
+ uint32_t m_nbajamex_rombank[2];
uint16_t m_vt83c461_latch;
@@ -146,6 +153,7 @@ private:
optional_device m_cbaj_fifo2;
optional_device m_mb3773;
optional_device m_zoom;
+ optional_device m_rax;
optional_device m_vt83c461;
optional_device m_soundlatch;
optional_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(0x80000);
+ machine().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 )
diff --git a/src/mame/includes/stv.h b/src/mame/includes/stv.h
index 7f52a22d59b..96525ff87b8 100644
--- a/src/mame/includes/stv.h
+++ b/src/mame/includes/stv.h
@@ -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 m_adsp;
- optional_shared_ptr 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 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 m_cryptdevice;
optional_device m_5838crypt;
- optional_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);