Merge pull request #800 from laoo/ASAP_POKEY

ASAP POKEY small fix and refactorings
This commit is contained in:
tildearrow 2022-12-23 01:52:41 -05:00 committed by GitHub
commit 66f2b05287
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 46 additions and 42 deletions

View File

@ -96,16 +96,16 @@ void DivPlatformPOKEY::acquireMZ(short* buf, size_t start, size_t len) {
void DivPlatformPOKEY::acquireASAP(short* buf, size_t start, size_t len) { void DivPlatformPOKEY::acquireASAP(short* buf, size_t start, size_t len) {
while (!writes.empty()) { while (!writes.empty()) {
QueuedWrite w=writes.front(); QueuedWrite w=writes.front();
altASAP->write(w.addr, w.val); altASAP.write(w.addr, w.val);
writes.pop(); writes.pop();
} }
for (size_t h=start; h<start+len; h++) { for (size_t h=start; h<start+len; h++) {
if (++oscBufDelay>=2) { if (++oscBufDelay>=2) {
oscBufDelay=0; oscBufDelay=0;
buf[h]=altASAP->sampleAudio(oscBuf); buf[h]=altASAP.sampleAudio(oscBuf);
} else { } else {
buf[h]=altASAP->sampleAudio(); buf[h]=altASAP.sampleAudio();
} }
} }
} }
@ -396,7 +396,7 @@ DivDispatchOscBuffer* DivPlatformPOKEY::getOscBuffer(int ch) {
unsigned char* DivPlatformPOKEY::getRegisterPool() { unsigned char* DivPlatformPOKEY::getRegisterPool() {
if (useAltASAP) { if (useAltASAP) {
return const_cast<unsigned char*>(altASAP->getRegisterPool()); return const_cast<unsigned char*>(altASAP.getRegisterPool());
} else { } else {
return regPool; return regPool;
} }
@ -418,7 +418,7 @@ void DivPlatformPOKEY::reset() {
} }
if (useAltASAP) { if (useAltASAP) {
altASAP->reset(); altASAP.reset();
} else { } else {
ResetPokeyState(&pokey); ResetPokeyState(&pokey);
} }
@ -454,10 +454,7 @@ void DivPlatformPOKEY::setFlags(const DivConfig& flags) {
for (int i=0; i<4; i++) { for (int i=0; i<4; i++) {
oscBuf[i]->rate=rate/2; oscBuf[i]->rate=rate/2;
} }
if (altASAP) { altASAP.init(chipClock,rate);
delete altASAP;
}
altASAP=new AltASAP::Pokey(chipClock,rate);
} else { } else {
rate=chipClock; rate=chipClock;
for (int i=0; i<4; i++) { for (int i=0; i<4; i++) {
@ -479,7 +476,6 @@ int DivPlatformPOKEY::init(DivEngine* p, int channels, int sugRate, const DivCon
dumpWrites=false; dumpWrites=false;
skipRegisterWrites=false; skipRegisterWrites=false;
oscBufDelay=0; oscBufDelay=0;
altASAP=NULL;
for (int i=0; i<4; i++) { for (int i=0; i<4; i++) {
isMuted[i]=false; isMuted[i]=false;
oscBuf[i]=new DivDispatchOscBuffer; oscBuf[i]=new DivDispatchOscBuffer;
@ -488,7 +484,7 @@ int DivPlatformPOKEY::init(DivEngine* p, int channels, int sugRate, const DivCon
if (!useAltASAP) { if (!useAltASAP) {
MZPOKEYSND_Init(&pokey); MZPOKEYSND_Init(&pokey);
} }
setFlags(flags); setFlags(flags);
reset(); reset();
return 6; return 6;
@ -498,9 +494,6 @@ void DivPlatformPOKEY::quit() {
for (int i=0; i<4; i++) { for (int i=0; i<4; i++) {
delete oscBuf[i]; delete oscBuf[i];
} }
if (altASAP) {
delete altASAP;
}
} }
void DivPlatformPOKEY::setAltASAP(bool value) { void DivPlatformPOKEY::setAltASAP(bool value) {

View File

@ -52,7 +52,7 @@ class DivPlatformPOKEY: public DivDispatch {
bool audctlChanged; bool audctlChanged;
unsigned char oscBufDelay; unsigned char oscBufDelay;
PokeyState pokey; PokeyState pokey;
AltASAP::Pokey* altASAP; AltASAP::Pokey altASAP;
bool useAltASAP; bool useAltASAP;
unsigned char regPool[16]; unsigned char regPool[16];
friend void putDispatchChip(void*,int); friend void putDispatchChip(void*,int);

View File

@ -37,6 +37,9 @@ static constexpr int64_t CNT_MAX = std::numeric_limits<int64_t>::max() & ~7;
static constexpr int MuteFrequency = 1; static constexpr int MuteFrequency = 1;
static constexpr int MuteInit = 2; static constexpr int MuteInit = 2;
static constexpr int MuteSerialInput = 8; static constexpr int MuteSerialInput = 8;
//just some magick value to match the audio level of mzpokeysnd
static constexpr int16_t MAGICK_VOLUME_BOOSTER = 160;
static constexpr int16_t MAGICK_OSC_VOLUME_BOOSTER = 4;
struct PokeyBase struct PokeyBase
{ {
@ -219,15 +222,15 @@ public:
int32_t volume = value & 0x0f; int32_t volume = value & 0x0f;
if ( ( value & 0x10 ) != 0 ) if ( ( value & 0x10 ) != 0 )
{ {
mDelta = volume; mDelta = volume * MAGICK_VOLUME_BOOSTER;
} }
else else
{ {
muteUltrasound( cycle ); muteUltrasound( cycle );
if ( mDelta > 0 ) if ( mDelta > 0 )
mDelta = volume; mDelta = volume * MAGICK_VOLUME_BOOSTER;
else else
mDelta = -volume; mDelta = -volume * MAGICK_VOLUME_BOOSTER;
} }
} }
@ -283,9 +286,9 @@ public:
PokeyPimpl( uint32_t pokeyClock, uint32_t sampleRate ) : PokeyBase{}, mQueue{ std::make_unique<ActionQueue>() }, PokeyPimpl( uint32_t pokeyClock, uint32_t sampleRate ) : PokeyBase{}, mQueue{ std::make_unique<ActionQueue>() },
mAudioChannels{ AudioChannel{ *mQueue, 0u }, AudioChannel{ *mQueue, 1u }, AudioChannel{ *mQueue, 2u }, AudioChannel{ *mQueue, 3u } }, mAudioChannels{ AudioChannel{ *mQueue, 0u }, AudioChannel{ *mQueue, 1u }, AudioChannel{ *mQueue, 2u }, AudioChannel{ *mQueue, 3u } },
mRegisterPool{}, mPokeyClock{ pokeyClock * 8 }, mTick{}, mNextTick{}, mSampleRate{ sampleRate }, mSamplesRemainder{}, mRegisterPool{}, mTick{}, mNextTick{},
mReloadCycles1{ 28 }, mReloadCycles3{ 28 }, mDivCycles{ 28 }, mReloadCycles1{ 28 }, mReloadCycles3{ 28 }, mDivCycles{ 28 }, mSampleRate{ sampleRate }, mSamplesRemainder{},
mTicksPerSample{ mPokeyClock / mSampleRate, mPokeyClock % mSampleRate } mTicksPerSample{ ( pokeyClock * 8 ) / mSampleRate, ( pokeyClock * 8 ) % mSampleRate }
{ {
std::fill_n( mRegisterPool.data(), mRegisterPool.size(), (uint8_t)0xff ); std::fill_n( mRegisterPool.data(), mRegisterPool.size(), (uint8_t)0xff );
enqueueSampling(); enqueueSampling();
@ -468,7 +471,7 @@ public:
for ( int i = 0; i < 4; i++ ) for ( int i = 0; i < 4; i++ )
mAudioChannels[i].doStimer( cycle ); mAudioChannels[i].doStimer( cycle );
break; break;
case 0x0f: case 0x0f:
{ {
if ( value == mSkctl ) if ( value == mSkctl )
break; break;
@ -501,10 +504,10 @@ public:
if ( oscb != nullptr ) if ( oscb != nullptr )
{ {
oscb[0]->data[oscb[0]->needle++]=ch0; oscb[0]->data[oscb[0]->needle++]=ch0 * MAGICK_OSC_VOLUME_BOOSTER;
oscb[1]->data[oscb[1]->needle++]=ch1; oscb[1]->data[oscb[1]->needle++]=ch1 * MAGICK_OSC_VOLUME_BOOSTER;
oscb[2]->data[oscb[2]->needle++]=ch2; oscb[2]->data[oscb[2]->needle++]=ch2 * MAGICK_OSC_VOLUME_BOOSTER;
oscb[3]->data[oscb[3]->needle++]=ch3; oscb[3]->data[oscb[3]->needle++]=ch3 * MAGICK_OSC_VOLUME_BOOSTER;
} }
enqueueSampling(); enqueueSampling();
@ -598,45 +601,53 @@ private:
std::array<uint8_t, 4 * 2 + 1> mRegisterPool; std::array<uint8_t, 4 * 2 + 1> mRegisterPool;
uint32_t mPokeyClock;
uint64_t mTick; uint64_t mTick;
uint64_t mNextTick; uint64_t mNextTick;
int64_t mReloadCycles1;
int64_t mReloadCycles3;
int64_t mDivCycles;
uint32_t mSampleRate; uint32_t mSampleRate;
uint32_t mSamplesRemainder; uint32_t mSamplesRemainder;
int mReloadCycles1;
int mReloadCycles3;
int mDivCycles;
std::pair<uint32_t, uint32_t> mTicksPerSample; std::pair<uint32_t, uint32_t> mTicksPerSample;
}; };
//Initializing periods with safe defaults
Pokey::Pokey( uint32_t pokeyClock, uint32_t sampleRate ) : mPokey{ std::make_unique<PokeyPimpl>( mPokeyClock, mSampleRate ) }, mPokeyClock{ pokeyClock }, mSampleRate{ sampleRate } Pokey::Pokey() : mPokeyClock{ (uint32_t)COLOR_NTSC / 2 }, mSampleRate{ mPokeyClock / 7 }, mPokey{}
{ {
} }
void Pokey::init( uint32_t pokeyClock, uint32_t sampleRate )
{
mPokey.reset();
mPokeyClock = pokeyClock;
mSampleRate = sampleRate;
}
void Pokey::reset()
{
mPokey = std::make_unique<PokeyPimpl>( mPokeyClock, mSampleRate );
}
Pokey::~Pokey() Pokey::~Pokey()
{ {
} }
void Pokey::write( uint8_t address, uint8_t value ) void Pokey::write( uint8_t address, uint8_t value )
{ {
assert( mPokey );
mPokey->write( address, value ); mPokey->write( address, value );
} }
int16_t Pokey::sampleAudio( DivDispatchOscBuffer** oscb ) int16_t Pokey::sampleAudio( DivDispatchOscBuffer** oscb )
{ {
return mPokey->sampleAudio( oscb ) * 160; //just some magick value to match the audio level of mzpokeysnd assert( mPokey );
return mPokey->sampleAudio( oscb );
} }
uint8_t const* Pokey::getRegisterPool() uint8_t const* Pokey::getRegisterPool()
{ {
assert( mPokey );
return mPokey->getRegisterPool(); return mPokey->getRegisterPool();
} }
void Pokey::reset()
{
mPokey = std::make_unique<PokeyPimpl>( mPokeyClock, mSampleRate );
}
} }

View File

@ -15,7 +15,8 @@ class Pokey
{ {
public: public:
Pokey( uint32_t pokeyClock, uint32_t sampleRate ); Pokey();
void init( uint32_t pokeyClock, uint32_t sampleRate );
~Pokey(); ~Pokey();
void write( uint8_t address, uint8_t value ); void write( uint8_t address, uint8_t value );
@ -26,10 +27,9 @@ public:
void reset(); void reset();
private: private:
std::unique_ptr<PokeyPimpl> mPokey;
uint32_t mPokeyClock; uint32_t mPokeyClock;
uint32_t mSampleRate; uint32_t mSampleRate;
std::unique_ptr<PokeyPimpl> mPokey;
}; };
} }