summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/audio/rax.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/audio/rax.cpp')
-rw-r--r--src/mame/audio/rax.cpp519
1 files changed, 0 insertions, 519 deletions
diff --git a/src/mame/audio/rax.cpp b/src/mame/audio/rax.cpp
deleted file mode 100644
index 79c7a4bacea..00000000000
--- a/src/mame/audio/rax.cpp
+++ /dev/null
@@ -1,519 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Phil Bennett
-/***************************************************************************
-
- Acclaim RAX Sound Board
-
-****************************************************************************/
-
-#include "emu.h"
-#include "rax.h"
-#include "speaker.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
- *
- *************************************/
-
-void acclaim_rax_device::data_w(uint16_t data)
-{
- m_data_in->write(data);
- m_cpu->set_input_line(ADSP2181_IRQL0, ASSERT_LINE);
- machine().scheduler().boost_interleave(attotime::zero, attotime::from_usec(5));
-}
-
-
-uint16_t acclaim_rax_device::data_r()
-{
- m_adsp_snd_pf0 = 1;
- return m_data_out->read();
-}
-
-
-/*************************************
- *
- * Internal
- *
- *************************************/
-
-uint16_t acclaim_rax_device::adsp_control_r(offs_t offset)
-{
- 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;
-}
-
-void acclaim_rax_device::adsp_control_w(offs_t offset, uint16_t data)
-{
- 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], 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], 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], src_word);
-
- ++src_addr;
- ++m_control_regs[BDMA_INT_ADDR_REG];
- --count;
- }
- }
- }
- else
- {
- // TODO: last stage in Batman Forever!?
- // page = 0, dir = 1, type = 1, src_addr = 0xfd
- fatalerror("%s DMA to byte memory!",this->tag());
- }
-
- 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)
- {
- m_dmadac[1]->enable(0);
- }
- break;
-
- case S0_AUTOBUF_REG:
- /* autobuffer off: nuke the timer, and disable the DAC */
- if ((data & 0x0002) == 0)
- {
- m_dmadac[0]->enable(0);
- m_reg_timer->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->pulse_input_line(INPUT_LINE_RESET, attotime::zero);
- else
- m_cpu->pulse_input_line(ADSP2181_BDMA, m_cpu->minimum_quantum_time());
-
- 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);
-}
-
-void acclaim_rax_device::ram_bank_w(uint16_t data)
-{
- // Note: The PCB has two unstuffed RAM locations
- m_data_bank = data & 3;
- update_data_ram_bank();
-}
-
-void acclaim_rax_device::rom_bank_w(uint16_t data)
-{
- m_rom_bank = data;
-}
-
-uint16_t acclaim_rax_device::host_r()
-{
- m_cpu->set_input_line(ADSP2181_IRQL0, CLEAR_LINE);
- return m_data_in->read();
-}
-
-void acclaim_rax_device::host_w(uint16_t data)
-{
- m_data_out->write(data);
- m_adsp_snd_pf0 = 0;
-}
-
-
-/*************************************
- *
- * CPU memory map & config
- *
- *************************************/
-
-void acclaim_rax_device::adsp_program_map(address_map &map)
-{
- map.unmap_value_high();
- map(0x0000, 0x3fff).ram().share("adsp_pram");
-}
-
-void acclaim_rax_device::adsp_data_map(address_map &map)
-{
- map.unmap_value_high();
- map(0x0000, 0x1fff).bankrw("databank");
- map(0x2000, 0x3fdf).ram(); // Internal RAM
- map(0x3fe0, 0x3fff).rw(FUNC(acclaim_rax_device::adsp_control_r), FUNC(acclaim_rax_device::adsp_control_w));
-}
-
-void acclaim_rax_device::adsp_io_map(address_map &map)
-{
- map.unmap_value_high();
- map(0x0000, 0x0000).w(FUNC(acclaim_rax_device::ram_bank_w));
- map(0x0001, 0x0001).w(FUNC(acclaim_rax_device::rom_bank_w));
- map(0x0003, 0x0003).rw(FUNC(acclaim_rax_device::host_r), FUNC(acclaim_rax_device::host_w));
-}
-
-
-void acclaim_rax_device::device_start()
-{
- m_program = &m_cpu->space(AS_PROGRAM);
- m_data = &m_cpu->space(AS_DATA);
-
- // 1 bank for internal
- m_banked_ram = make_unique_clear<uint16_t[]>(0x2000 * 5);
- membank("databank")->configure_entries(0, 5, &m_banked_ram[0], 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);
- reg += m_incs[which];
- }
-
- for (int i = 0; i < 2; i++)
- {
- m_dmadac[i]->flush();
- m_dmadac[i]->transfer(i, 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);
- for (auto &dmadac : m_dmadac)
- {
- dmadac->set_frequency(sample_period.as_hz());
- dmadac->enable(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->adjust(period, 0, period);
- }
-}
-
-void acclaim_rax_device::adsp_sound_tx_callback(offs_t offset, uint32_t data)
-{
- int which = offset;
-
- if (which != 0)
- return;
-
- int autobuf_reg = which ? S1_AUTOBUF_REG : S0_AUTOBUF_REG; // "which" must equal 0 here, invalid test: Coverity 315932
-
- /* check if SPORT1 is enabled */
- if (m_control_regs[SYSCONTROL_REG] & (which ? 0x0800 : 0x1000)) /* bit 11 */ // invalid test here too
- {
- /* 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 */
- for (auto &dmadac : m_dmadac)
- dmadac->enable(0);
-
- /* remove timer */
- m_reg_timer->reset();
-}
-
-void acclaim_rax_device::dmovlay_callback(uint32_t data)
-{
- if (data > 1)
- {
- fatalerror("dmovlay_callback: Error! dmovlay called with value = %X\n", data);
- }
- else
- {
- m_dmovlay_val = data;
- update_data_ram_bank();
- }
-}
-
-
-DEFINE_DEVICE_TYPE(ACCLAIM_RAX, acclaim_rax_device, "rax_audio", "Acclaim RAX")
-
-//-------------------------------------------------
-// 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, tag, owner, clock)
- , m_cpu(*this, "adsp")
- , m_dmadac(*this, { "dacl", "dacr" })
- , m_reg_timer(*this, "adsp_reg_timer")
- , m_dma_timer(*this, "adsp_dma_timer")
- , m_adsp_pram(*this, "adsp_pram")
- , m_adsp_data_bank(*this, "databank")
- , m_rom(*this, DEVICE_SELF)
- , m_data_in(*this, "data_in")
- , m_data_out(*this, "data_out")
-{
-
-}
-
-//-------------------------------------------------
-// device_add_mconfig - add device configuration
-//-------------------------------------------------
-
-void acclaim_rax_device::device_add_mconfig(machine_config &config)
-{
- ADSP2181(config, m_cpu, XTAL(16'670'000));
- m_cpu->sport_tx().set(FUNC(acclaim_rax_device::adsp_sound_tx_callback)); /* callback for serial transmit */
- m_cpu->dmovlay().set(FUNC(acclaim_rax_device::dmovlay_callback)); /* callback for adsp 2181 dmovlay instruction */
- m_cpu->set_addrmap(AS_PROGRAM, &acclaim_rax_device::adsp_program_map);
- m_cpu->set_addrmap(AS_DATA, &acclaim_rax_device::adsp_data_map);
- m_cpu->set_addrmap(AS_IO, &acclaim_rax_device::adsp_io_map);
-
- TIMER(config, "adsp_reg_timer").configure_generic(FUNC(acclaim_rax_device::adsp_irq0));
- TIMER(config, "adsp_dma_timer").configure_generic(FUNC(acclaim_rax_device::dma_timer_callback));
-
- GENERIC_LATCH_16(config, m_data_in);
- GENERIC_LATCH_16(config, m_data_out);
-
- SPEAKER(config, "lspeaker").front_left();
- SPEAKER(config, "rspeaker").front_right();
-
- DMADAC(config, "dacl").add_route(ALL_OUTPUTS, "lspeaker", 1.0);
- DMADAC(config, "dacr").add_route(ALL_OUTPUTS, "rspeaker", 1.0);
-}
-