diff options
author | athrxx | 2019-10-28 00:49:23 +0100 |
---|---|---|
committer | athrxx | 2019-12-18 20:50:39 +0100 |
commit | 900dcc4de57e68ed11409de13138adb3ca549814 (patch) | |
tree | 26cabd51a3b4896edb135776d6699258236c56b5 /audio | |
parent | 711034b74dd291286943a5b4aa17077ef05a39b2 (diff) | |
download | scummvm-rg350-900dcc4de57e68ed11409de13138adb3ca549814.tar.gz scummvm-rg350-900dcc4de57e68ed11409de13138adb3ca549814.tar.bz2 scummvm-rg350-900dcc4de57e68ed11409de13138adb3ca549814.zip |
AUDIO: (FM-TOWNS/PC-98) - improve timer flags handling
Timers should be reset only the first time the enable flag is sent. This also requires some updates to drivers which didn't send these flags accurately.
Diffstat (limited to 'audio')
-rw-r--r-- | audio/softsynth/fmtowns_pc98/towns_pc98_driver.cpp | 8 | ||||
-rw-r--r-- | audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp | 36 |
2 files changed, 29 insertions, 15 deletions
diff --git a/audio/softsynth/fmtowns_pc98/towns_pc98_driver.cpp b/audio/softsynth/fmtowns_pc98/towns_pc98_driver.cpp index ed1b85170b..4a93d42454 100644 --- a/audio/softsynth/fmtowns_pc98/towns_pc98_driver.cpp +++ b/audio/softsynth/fmtowns_pc98/towns_pc98_driver.cpp @@ -1242,6 +1242,8 @@ void TownsPC98_AudioDriver::reset() { _sfxData = 0; _pc98a->reset(); + setMusicTempo(84); + setSfxTempo(654); for (int i = 0; i < _numChanFM; i++) _channels[i]->reset(); @@ -1404,13 +1406,15 @@ void TownsPC98_AudioDriver::startSoundEffect() { void TownsPC98_AudioDriver::setMusicTempo(uint8 tempo) { writeReg(0, 0x26, tempo); - writeReg(0, 0x27, 0x33); + writeReg(0, 0x27, 0x3D); + writeReg(0, 0x27, 0x3F); } void TownsPC98_AudioDriver::setSfxTempo(uint16 tempo) { writeReg(0, 0x24, tempo & 0xff); writeReg(0, 0x25, tempo >> 8); - writeReg(0, 0x27, 0x33); + writeReg(0, 0x27, 0x3E); + writeReg(0, 0x27, 0x3F); } const uint8 TownsPC98_AudioDriver::_channelPreset[36] = { diff --git a/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp b/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp index 0ecf0e45c9..558c389ebd 100644 --- a/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp +++ b/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp @@ -981,10 +981,10 @@ TownsPC98_FmSynth::TownsPC98_FmSynth(Audio::Mixer *mixer, EmuType type) : } TownsPC98_FmSynth::~TownsPC98_FmSynth() { - Common::StackLock lock(_mutex); if (_ready) deinit(); + Common::StackLock lock(_mutex); delete _ssg; #ifndef DISABLE_PC98_RHYTHM_CHANNEL delete _prc; @@ -1065,7 +1065,7 @@ void TownsPC98_FmSynth::reset() { _waitCycleRemainder = 0; #endif - writeReg(0, 0x27, 0x33); + writeReg(0, 0x27, 0x30); if (_ssg) _ssg->reset(); @@ -1147,18 +1147,28 @@ int TownsPC98_FmSynth::readBuffer(int16 *buffer, const int numSamples) { int render = inSamplesLeft; for (int i = 0; i < 2; i++) { - if (_timers[i].enabled && _timers[i].cb) { + if (_timers[i].enabled) { if (!_timers[i].smpTillCb) { + int spc = i ? ((0x100 - _timers[i].value) << 4) << _rateScale : (0x400 - _timers[i].value) << _rateScale; + if (spc < 1) + spc = 1; + + _timers[i].smpPerCb = (int32)spc; + _timers[i].smpPerCbRem = (uint32)((spc - (float)_timers[i].smpPerCb) * 1000000.0f); + if (_timers[i].cb) { if (_timers[i].cb->isValid()) (*_timers[i].cb)(); - } + } + _timers[i].smpTillCb = _timers[i].smpPerCb; _timers[i].smpTillCbRem += _timers[i].smpPerCbRem; - if (_timers[i].smpTillCbRem >= 1000000) { + while (_timers[i].smpTillCbRem >= 1000000) { _timers[i].smpTillCb++; _timers[i].smpTillCbRem -= 1000000; } + + _timers[i].enabled = _registers[0x27][0] & (4 << i); } render = MIN(render, _timers[i].smpTillCb); } @@ -1428,7 +1438,7 @@ void TownsPC98_FmSynth::writeRegInternal(uint8 part, uint8 regAddress, uint8 val // Timer B _timers[1].value = value & 0xff; } else if (l == 7) { - if (value & 1) { + if ((value & 1) && !_timers[0].enabled) { int spc = (0x400 - _timers[0].value) << _rateScale; if (spc < 1) { warning("TownsPC98_FmSynth: Invalid Timer A setting: %d", _timers[0].value); @@ -1440,11 +1450,11 @@ void TownsPC98_FmSynth::writeRegInternal(uint8 part, uint8 regAddress, uint8 val _timers[0].smpTillCb = _timers[0].smpPerCb; _timers[0].smpTillCbRem = _timers[0].smpPerCbRem; _timers[0].enabled = true; - } else { + } else if (!(value & 1)) { _timers[0].enabled = false; } - if (value & 2) { + if ((value & 2) && !_timers[1].enabled) { int spc = ((0x100 - _timers[1].value) << 4) << _rateScale; if (spc < 1) { warning("TownsPC98_FmSynth: Invalid Timer B setting: %d", _timers[1].value); @@ -1456,18 +1466,18 @@ void TownsPC98_FmSynth::writeRegInternal(uint8 part, uint8 regAddress, uint8 val _timers[1].smpTillCb = _timers[1].smpPerCb; _timers[1].smpTillCbRem = _timers[1].smpPerCbRem; _timers[1].enabled = true; - } else { + } else if (!(value & 2)) { _timers[1].enabled = false; } if (value & 0x10) { - _timers[0].smpTillCb = _timers[0].smpPerCb; - _timers[0].smpTillCbRem = _timers[0].smpPerCbRem; + // clear timer a over flag + // Unneeded / not implemented for ScummVM } if (value & 0x20) { - _timers[1].smpTillCb = _timers[1].smpPerCb; - _timers[1].smpTillCbRem = _timers[1].smpPerCbRem; + // clear timer b over flag + // Unneeded / not implemented for ScummVM } } else if (l == 2) { |