mirror of
https://github.com/holub/mame
synced 2025-07-03 17:08:39 +03:00
cbus/pc9801_86.cpp: attempt to resolve DAC FIFO under/overflows
This commit is contained in:
parent
878d70d975
commit
d566c8f76b
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
- Test all pcm modes;
|
- Test all pcm modes;
|
||||||
|
- Fix PCM overflow bug properly (CPUENB signal yield host CPU until DAC catches up?)
|
||||||
- Make volume work;
|
- Make volume work;
|
||||||
- Recording;
|
- Recording;
|
||||||
- SpeakBoard: no idea about software that uses this, also board shows a single YM2608B?
|
- SpeakBoard: no idea about software that uses this, also board shows a single YM2608B?
|
||||||
@ -368,14 +369,21 @@ void pc9801_86_device::io_map(address_map &map)
|
|||||||
return 0;
|
return 0;
|
||||||
}),
|
}),
|
||||||
NAME([this] (u8 data) {
|
NAME([this] (u8 data) {
|
||||||
|
// HACK: on overflow make sure to single step the FIFO enough to claim some space back
|
||||||
|
// os2warp3 initializes the full buffer with 0x00 then quickly pretends
|
||||||
|
// that DAC already catched up by the time the actual startup/shutdown chimes are sent.
|
||||||
|
if (queue_count() == QUEUE_SIZE)
|
||||||
|
{
|
||||||
|
dac_transfer();
|
||||||
|
logerror("Warning: $a46c write with FIFO overflow %02x\n", m_pcm_mode);
|
||||||
|
}
|
||||||
|
|
||||||
if(queue_count() < QUEUE_SIZE)
|
if(queue_count() < QUEUE_SIZE)
|
||||||
{
|
{
|
||||||
m_queue[m_head++] = data;
|
m_queue[m_head++] = data;
|
||||||
m_head %= QUEUE_SIZE;
|
m_head %= QUEUE_SIZE;
|
||||||
m_count++;
|
m_count++;
|
||||||
}
|
}
|
||||||
// TODO: what should happen on overflow?
|
|
||||||
// os2warp3 startup / shutdown chimes do this already
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -424,12 +432,8 @@ u8 pc9801_86_device::queue_pop()
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
TIMER_CALLBACK_MEMBER(pc9801_86_device::dac_tick)
|
void pc9801_86_device::dac_transfer()
|
||||||
{
|
{
|
||||||
m_pcm_clk = !m_pcm_clk;
|
|
||||||
if((m_pcm_ctrl & 0x40) || !(m_pcm_ctrl & 0x80))
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch(m_pcm_mode & 0x70)
|
switch(m_pcm_mode & 0x70)
|
||||||
{
|
{
|
||||||
case 0x70: // 8bit stereo
|
case 0x70: // 8bit stereo
|
||||||
@ -461,6 +465,20 @@ TIMER_CALLBACK_MEMBER(pc9801_86_device::dac_tick)
|
|||||||
m_rdac->write(rsample);
|
m_rdac->write(rsample);
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TIMER_CALLBACK_MEMBER(pc9801_86_device::dac_tick)
|
||||||
|
{
|
||||||
|
m_pcm_clk = !m_pcm_clk;
|
||||||
|
if((m_pcm_ctrl & 0x40) || !(m_pcm_ctrl & 0x80))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// TODO: verify underflow
|
||||||
|
// should leave the DACs in whatever state they are or ...?
|
||||||
|
if (!queue_count())
|
||||||
|
return;
|
||||||
|
|
||||||
|
dac_transfer();
|
||||||
if((queue_count() < m_irq_rate) && (m_pcm_ctrl & 0x20))
|
if((queue_count() < m_irq_rate) && (m_pcm_ctrl & 0x20))
|
||||||
{
|
{
|
||||||
m_pcmirq = true;
|
m_pcmirq = true;
|
||||||
|
@ -31,6 +31,9 @@ public:
|
|||||||
pc9801_86_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
pc9801_86_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||||
pc9801_86_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
|
pc9801_86_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
|
||||||
|
|
||||||
|
static constexpr feature_type unemulated_features() { return feature::MICROPHONE; }
|
||||||
|
static constexpr feature_type imperfect_features() { return feature::SOUND; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void io_map(address_map &map) ATTR_COLD;
|
void io_map(address_map &map) ATTR_COLD;
|
||||||
u8 pcm_control_r();
|
u8 pcm_control_r();
|
||||||
@ -74,6 +77,8 @@ private:
|
|||||||
required_device<dac_16bit_r2r_twos_complement_device> m_rdac;
|
required_device<dac_16bit_r2r_twos_complement_device> m_rdac;
|
||||||
std::vector<u8> m_queue;
|
std::vector<u8> m_queue;
|
||||||
emu_timer *m_dac_timer;
|
emu_timer *m_dac_timer;
|
||||||
|
|
||||||
|
void dac_transfer();
|
||||||
};
|
};
|
||||||
|
|
||||||
class pc9801_speakboard_device : public pc9801_86_device
|
class pc9801_speakboard_device : public pc9801_86_device
|
||||||
|
Loading…
Reference in New Issue
Block a user