diff options
Diffstat (limited to 'src/devices/sound/ad1848.cpp')
-rw-r--r-- | src/devices/sound/ad1848.cpp | 52 |
1 files changed, 32 insertions, 20 deletions
diff --git a/src/devices/sound/ad1848.cpp b/src/devices/sound/ad1848.cpp index 5db5b3ded2d..b9395d23360 100644 --- a/src/devices/sound/ad1848.cpp +++ b/src/devices/sound/ad1848.cpp @@ -5,9 +5,8 @@ // TODO: Emulate pin-compatible Crystal Semiconductor CS4231 and its extra Mode 2 features #include "emu.h" -#include "sound/ad1848.h" +#include "ad1848.h" -#include "sound/volt_reg.h" #include "speaker.h" @@ -24,27 +23,21 @@ ad1848_device::ad1848_device(const machine_config &mconfig, const char *tag, dev void ad1848_device::device_add_mconfig(machine_config &config) { - SPEAKER(config, "lspeaker").front_left(); - SPEAKER(config, "rspeaker").front_right(); - DAC_16BIT_R2R(config, m_ldac, 0).add_route(ALL_OUTPUTS, "lspeaker", 0.5); // unknown DAC - DAC_16BIT_R2R(config, m_rdac, 0).add_route(ALL_OUTPUTS, "rspeaker", 0.5); // unknown DAC - voltage_regulator_device &vref(VOLTAGE_REGULATOR(config, "vref", 0)); - vref.add_route(0, "ldac", 1.0, DAC_VREF_POS_INPUT); - vref.add_route(0, "ldac", -1.0, DAC_VREF_NEG_INPUT); - vref.add_route(0, "rdac", 1.0, DAC_VREF_POS_INPUT); - vref.add_route(0, "rdac", -1.0, DAC_VREF_NEG_INPUT); + SPEAKER(config, "speaker", 2).front(); + DAC_16BIT_R2R(config, m_ldac, 0).add_route(ALL_OUTPUTS, "speaker", 0.5, 0); // unknown DAC + DAC_16BIT_R2R(config, m_rdac, 0).add_route(ALL_OUTPUTS, "speaker", 0.5, 1); // unknown DAC } void ad1848_device::device_start() { - m_timer = timer_alloc(0, nullptr); - m_irq_cb.resolve_safe(); - m_drq_cb.resolve_safe(); + m_timer = timer_alloc(FUNC(ad1848_device::update_tick), this); + save_item(NAME(m_regs.idx)); save_item(NAME(m_addr)); save_item(NAME(m_stat)); save_item(NAME(m_sam_cnt)); + save_item(NAME(m_calibration_cycles)); save_item(NAME(m_samples)); save_item(NAME(m_count)); save_item(NAME(m_play)); @@ -59,12 +52,13 @@ void ad1848_device::device_reset() m_addr = 0; m_stat = 0; m_sam_cnt = 0; + m_calibration_cycles = 0; m_samples = 0; m_play = false; m_irq = false; } -READ8_MEMBER(ad1848_device::read) +uint8_t ad1848_device::read(offs_t offset) { switch(offset) { @@ -80,7 +74,7 @@ READ8_MEMBER(ad1848_device::read) return 0; } -WRITE8_MEMBER(ad1848_device::write) +void ad1848_device::write(offs_t offset, uint8_t data) { static constexpr int div_factor[] = {3072, 1536, 896, 768, 448, 384, 512, 2560}; switch(offset) @@ -103,9 +97,17 @@ WRITE8_MEMBER(ad1848_device::write) break; case 9: { + // auto-calibration + if (m_mce && BIT(data, 3)) + { + logerror("set auto-calibration\n"); + m_regs.init |= 0x20; + m_calibration_cycles = 384; + } + m_play = (data & 1) ? true : false; // FIXME: provide external configuration for XTAL1 (24.576 MHz) and XTAL2 (16.9344 MHz) inputs - attotime rate = m_play ? attotime::from_hz(((m_regs.dform & 1) ? 16.9344_MHz_XTAL : 24.576_MHz_XTAL) + attotime rate = (m_play || BIT(m_regs.init, 5)) ? attotime::from_hz(((m_regs.dform & 1) ? 16.9344_MHz_XTAL : 24.576_MHz_XTAL) / div_factor[(m_regs.dform >> 1) & 7]) : attotime::never; m_timer->adjust(rate, 0 , rate); m_drq_cb(m_play ? ASSERT_LINE : CLEAR_LINE); @@ -127,13 +129,13 @@ WRITE8_MEMBER(ad1848_device::write) } } -READ8_MEMBER(ad1848_device::dack_r) +uint8_t ad1848_device::dack_r() { m_drq_cb(CLEAR_LINE); return 0; // not implemented } -WRITE8_MEMBER(ad1848_device::dack_w) +void ad1848_device::dack_w(uint8_t data) { if(!m_play) return; @@ -162,8 +164,18 @@ WRITE8_MEMBER(ad1848_device::dack_w) m_drq_cb(CLEAR_LINE); } -void ad1848_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +TIMER_CALLBACK_MEMBER(ad1848_device::update_tick) { + // auto-calibration + if (BIT(m_regs.init, 5)) + { + if (--m_calibration_cycles == 0) + { + logerror("calibration finished\n"); + m_regs.init &= ~0x20; + } + } + if(!m_play) return; switch(m_regs.dform >> 4) |