summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/audio/acan.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/audio/acan.cpp')
-rw-r--r--src/mame/audio/acan.cpp296
1 files changed, 0 insertions, 296 deletions
diff --git a/src/mame/audio/acan.cpp b/src/mame/audio/acan.cpp
deleted file mode 100644
index 0df726ad8c9..00000000000
--- a/src/mame/audio/acan.cpp
+++ /dev/null
@@ -1,296 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Ryan Holtz, superctr
-/***************************************************************************
-
- Super A'Can sound driver
-
- Currently has a number of unknown registers and functionality.
-
-****************************************************************************/
-
-#include "emu.h"
-#include "acan.h"
-
-#define VERBOSE (1)
-#include "logmacro.h"
-
-// device type definition
-DEFINE_DEVICE_TYPE(ACANSND, acan_sound_device, "acansound", "Super A'Can Audio")
-
-acan_sound_device::acan_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : device_t(mconfig, ACANSND, tag, owner, clock)
- , device_sound_interface(mconfig, *this)
- , m_stream(nullptr)
- , m_timer(nullptr)
- , m_timer_irq_handler(*this)
- , m_dma_irq_handler(*this)
- , m_ram_read(*this)
- , m_active_channels(0)
- , m_dma_channels(0)
-{
-}
-
-
-void acan_sound_device::device_start()
-{
- m_stream = stream_alloc(0, 2, clock() / 16 / 5);
- m_mix = std::make_unique<int32_t[]>((clock() / 16 / 5) * 2);
- m_timer = timer_alloc(0);
-
- m_timer_irq_handler.resolve_safe();
- m_dma_irq_handler.resolve_safe();
- m_ram_read.resolve_safe(0);
-
- // register for savestates
- save_item(NAME(m_active_channels));
- save_item(NAME(m_dma_channels));
- save_item(STRUCT_MEMBER(m_channels, pitch));
- save_item(STRUCT_MEMBER(m_channels, length));
- save_item(STRUCT_MEMBER(m_channels, start_addr));
- save_item(STRUCT_MEMBER(m_channels, curr_addr));
- save_item(STRUCT_MEMBER(m_channels, end_addr));
- save_item(STRUCT_MEMBER(m_channels, addr_increment));
- save_item(STRUCT_MEMBER(m_channels, frac));
- save_item(STRUCT_MEMBER(m_channels, register9));
- save_item(STRUCT_MEMBER(m_channels, envelope));
- save_item(STRUCT_MEMBER(m_channels, volume));
- save_item(STRUCT_MEMBER(m_channels, volume_l));
- save_item(STRUCT_MEMBER(m_channels, volume_r));
- save_item(STRUCT_MEMBER(m_channels, one_shot));
- save_item(NAME(m_regs));
-}
-
-void acan_sound_device::device_reset()
-{
- m_active_channels = 0;
- m_dma_channels = 0;
- std::fill(std::begin(m_regs), std::end(m_regs), 0);
-
- m_timer->reset();
- m_timer_irq_handler(0);
- m_dma_irq_handler(0);
-}
-
-void acan_sound_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
-{
- if (m_regs[0x14] & 0x40)
- {
- m_timer_irq_handler(1);
-
- // Update frequency
- uint16_t period = (m_regs[0x12] << 8) + m_regs[0x11];
- m_timer->adjust(clocks_to_attotime(10 * (0x10000 - period)), 0);
- }
-}
-
-void acan_sound_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs)
-{
- std::fill_n(&m_mix[0], outputs[0].samples() * 2, 0);
-
- for (int i = 0; i < 16 && m_active_channels != 0; i++)
- {
- if (BIT(m_active_channels, i))
- {
- acan_channel &channel = m_channels[i];
- int32_t *mixp = &m_mix[0];
-
- for (int s = 0; s < outputs[0].samples(); s++)
- {
- uint8_t data = m_ram_read(channel.curr_addr) + 0x80;
- int16_t sample = (int16_t)(data << 8);
-
- channel.frac += channel.addr_increment;
- channel.curr_addr += (uint16_t)(channel.frac >> 16);
- channel.frac = (uint16_t)channel.frac;
-
- *mixp++ += (sample * channel.volume_l) >> 8;
- *mixp++ += (sample * channel.volume_r) >> 8;
-
- if (channel.curr_addr >= channel.end_addr)
- {
- if (channel.register9)
- {
- m_dma_irq_handler(1);
- keyon_voice(i);
- }
- else if (channel.one_shot)
- {
- m_active_channels &= ~(1 << i);
- }
- else
- {
- channel.curr_addr -= channel.length;
- }
- }
- }
- }
- }
-
- int32_t *mixp = &m_mix[0];
- for (int i = 0; i < outputs[0].samples(); i++)
- {
- outputs[0].put_int(i, *mixp++, 32768 << 4);
- outputs[1].put_int(i, *mixp++, 32768 << 4);
- }
-}
-
-uint8_t acan_sound_device::read(offs_t offset)
-{
- if (offset == 0x14)
- {
- // acknowledge timer IRQ?
- m_timer_irq_handler(0);
- }
- else if (offset == 0x16)
- {
- // acknowledge DMA IRQ?
- m_dma_irq_handler(0);
- }
- return m_regs[offset];
-}
-
-void acan_sound_device::keyon_voice(uint8_t voice)
-{
- acan_channel &channel = m_channels[voice];
- channel.curr_addr = channel.start_addr << 6;
- channel.end_addr = channel.curr_addr + channel.length;
-
- m_active_channels |= (1 << voice);
-
- //printf("Keyon voice %d\n", voice);
-}
-
-void acan_sound_device::write(offs_t offset, uint8_t data)
-{
- const uint8_t upper = (offset >> 4) & 0x0f;
- const uint8_t lower = offset & 0x0f;
-
- m_regs[offset] = data;
-
- switch (upper)
- {
- case 0x1:
- switch (lower)
- {
- case 0x1: // Timer frequency (low byte)
- LOG("%s: Sound timer frequency (low byte) = %02x\n", machine().describe_context(), data);
- break;
-
- case 0x2: // Timer frequency (high byte)
- LOG("%s: Sound timer frequency (high byte) = %02x\n", machine().describe_context(), data);
- break;
-
- case 0x4: // Timer control
- // The meaning of the data that is actually written is unknown
- LOG("%s: Sound timer control = %02x\n", machine().describe_context(), data);
- if (BIT(data, 7))
- {
- // Update frequency
- uint16_t period = (m_regs[0x12] << 8) + m_regs[0x11];
- m_timer->adjust(clocks_to_attotime(10 * (0x10000 - period)), 0);
- }
- break;
-
- case 0x6: // DMA-driven channel flags?
- // The meaning of the data that is actually written is unknown
- m_dma_channels = data << 8;
- LOG("%s: DMA-driven channel flag(?) = %02x\n", machine().describe_context(), data);
- break;
-
- case 0x7: // Keyon/keyoff
- {
- LOG("%s: Sound key control, voice %02x key%s\n", machine().describe_context(), data & 0xf, (data & 0xf0) ? "on" : "off");
- const uint16_t mask = 1 << (data & 0xf);
- if (data & 0xf0)
- {
- keyon_voice(data & 0xf);
- }
- else
- {
- m_active_channels &= ~mask;
- }
- break;
- }
-
- default:
- LOG("Unknown sound register: %02x = %02x\n", offset, data);
- break;
- }
- break;
-
- case 0x2: // Pitch (low byte)
- {
- acan_channel &channel = m_channels[lower];
- channel.pitch &= 0xff00;
- channel.pitch |= data;
- channel.addr_increment = (uint32_t)channel.pitch << 6;
- break;
- }
-
- case 0x3: // Pitch (high byte)
- {
- acan_channel &channel = m_channels[lower];
- channel.pitch &= 0x00ff;
- channel.pitch |= data << 8;
- channel.addr_increment = (uint32_t)channel.pitch << 6;
- break;
- }
-
- case 0x5: // Waveform length
- {
- acan_channel &channel = m_channels[lower];
- channel.length = 0x40 << ((data & 0x0e) >> 1);
- channel.one_shot = BIT(data, 0);
- LOG("%s: Waveform length and attributes (voice %02x): %02x\n", machine().describe_context(), lower, data);
- break;
- }
-
- case 0x6: // Waveform address (divided by 0x40, high byte)
- {
- acan_channel &channel = m_channels[lower];
- channel.start_addr &= 0x00ff;
- channel.start_addr |= data << 8;
- LOG("%s: Waveform address (high) (voice %02x): %02x, will be %04x\n", machine().describe_context(), lower, data, channel.start_addr << 6);
- break;
- }
-
- case 0x7: // Waveform address (divided by 0x40, low byte)
- {
- acan_channel &channel = m_channels[lower];
- channel.start_addr &= 0xff00;
- channel.start_addr |= data;
- LOG("%s: Waveform address (low) (voice %02x): %02x, will be %04x\n", machine().describe_context(), lower, data, channel.start_addr << 6);
- break;
- }
-
- case 0x9: // Unknown (set to 0xFF for DMA-driven channels)
- {
- acan_channel &channel = m_channels[lower];
- channel.register9 = data;
- LOG("%s: Unknown voice register 9 (voice %02x): %02x\n", machine().describe_context(), lower, data);
- break;
- }
-
- case 0xa: // Envelope Parameters? (not yet known)
- case 0xb:
- case 0xc:
- case 0xd:
- m_channels[lower].envelope[upper - 0xa] = data;
- LOG("%s: Envelope parameter %d (voice %02x) = %02x\n", machine().describe_context(), upper - 0xa, lower, data);
- break;
-
- case 0xe: // Volume
- {
- acan_channel &channel = m_channels[lower];
- channel.volume = data;
- channel.volume_l = (data & 0xf0) | (data >> 4);
- channel.volume_r = (data & 0x0f) | (data << 4);
- LOG("%s: Volume register (voice %02x) = = %02x\n", machine().describe_context(), lower, data);
- break;
- }
-
- default:
- LOG("Unknown sound register: %02x = %02x\n", offset, data);
- break;
- }
-}