Imported existing sources
This commit is contained in:
1 parent
b848581174
commit
619ec483e7
69 files changed
+7961
-36
No files matched your search
@@ -0,0 +1,174 @@
|
||||
#include "aputrl.h"
|
||||
|
||||
// Qt includes
|
||||
#include <QDataStream>
|
||||
|
||||
// local includes
|
||||
#include "emusettings.h"
|
||||
#include "apu.h"
|
||||
|
||||
ApuTrl::ApuTrl(Apu &apu) :
|
||||
m_apu(apu)
|
||||
{
|
||||
}
|
||||
|
||||
void ApuTrl::apuTrlHardReset()
|
||||
{
|
||||
m_apuTrlLinerControlFlag = false;
|
||||
m_apuTrlLinerControlReload = 0;
|
||||
m_apuTrlTimer = 0;
|
||||
m_apuTrlLengthEnabled = false;
|
||||
m_apuTrlLengthCounter = 0;
|
||||
m_apuTrlLinerControlReloadFlag = false;
|
||||
m_apuTrlLinerCounter = 0;
|
||||
m_apuTrlOutput = 0;
|
||||
m_apuTrlPeriodDevider = 0;
|
||||
m_apuTrlStep = 0;
|
||||
m_apuTrlIgnoreReload = false;
|
||||
}
|
||||
|
||||
void ApuTrl::apuTrlSoftReset()
|
||||
{
|
||||
apuTrlHardReset();
|
||||
}
|
||||
|
||||
void ApuTrl::apuTrlClock()
|
||||
{
|
||||
static constexpr std::array<quint8, 32> stepSeq {
|
||||
15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
|
||||
};
|
||||
|
||||
m_apuTrlPeriodDevider--;
|
||||
if (m_apuTrlPeriodDevider <= 0)
|
||||
{
|
||||
m_apuTrlPeriodDevider = m_apuTrlTimer + 1;
|
||||
|
||||
if (m_apuTrlLengthCounter > 0 && m_apuTrlLinerCounter > 0)
|
||||
{
|
||||
if (m_apuTrlTimer >= 4)
|
||||
{
|
||||
m_apuTrlStep++;
|
||||
m_apuTrlStep &= 0x1F;
|
||||
if (EmuSettings::Audio::ChannelEnabled::TRL)
|
||||
m_apuTrlOutput = stepSeq[m_apuTrlStep];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ApuTrl::apuTrlClockLength()
|
||||
{
|
||||
if (m_apuTrlLengthCounter > 0 && !m_apuTrlLinerControlFlag)
|
||||
{
|
||||
m_apuTrlLengthCounter--;
|
||||
if (m_apu.regAccessHappened())
|
||||
{
|
||||
// This is not a hack, there is some hidden mechanism in the nes, that do reload and clock stuff
|
||||
if (m_apu.regIoAddr() == 0xB && m_apu.regAccessW())
|
||||
{
|
||||
m_apuTrlIgnoreReload = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ApuTrl::apuTrlClockEnvelope()
|
||||
{
|
||||
if (m_apuTrlLinerControlReloadFlag)
|
||||
{
|
||||
m_apuTrlLinerCounter = m_apuTrlLinerControlReload;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_apuTrlLinerCounter > 0)
|
||||
m_apuTrlLinerCounter--;
|
||||
}
|
||||
if (!m_apuTrlLinerControlFlag)
|
||||
m_apuTrlLinerControlReloadFlag = false;
|
||||
}
|
||||
|
||||
void ApuTrl::apuOnRegister4008()
|
||||
{
|
||||
// Only writes accepted
|
||||
if (!m_apu.regAccessW())
|
||||
return;
|
||||
m_apuTrlLinerControlFlag = (m_apu.regIoDb() & 0x80) == 0x80;
|
||||
m_apuTrlLinerControlReload = m_apu.regIoDb() & 0x7F;
|
||||
}
|
||||
|
||||
void ApuTrl::apuOnRegister4009()
|
||||
{
|
||||
}
|
||||
|
||||
void ApuTrl::apuOnRegister400A()
|
||||
{
|
||||
// Only writes accepted
|
||||
if (!m_apu.regAccessW())
|
||||
return;
|
||||
m_apuTrlTimer = (m_apuTrlTimer & 0x7F00) | m_apu.regIoDb();
|
||||
}
|
||||
|
||||
void ApuTrl::apuOnRegister400B()
|
||||
{
|
||||
// Only writes accepted
|
||||
if (!m_apu.regAccessW())
|
||||
return;
|
||||
m_apuTrlTimer = (m_apuTrlTimer & 0x00FF) | (m_apu.regIoDb() & 0x7) << 8;
|
||||
|
||||
if (m_apuTrlLengthEnabled && !m_apuTrlIgnoreReload)
|
||||
m_apuTrlLengthCounter = m_apu.m_sqDurationTable[m_apu.regIoDb() >> 3];
|
||||
if (m_apuTrlIgnoreReload)
|
||||
m_apuTrlIgnoreReload = false;
|
||||
m_apuTrlLinerControlReloadFlag = true;
|
||||
}
|
||||
|
||||
void ApuTrl::apuTrlOn4015()
|
||||
{
|
||||
m_apuTrlLengthEnabled = (m_apu.regIoDb() & 0x04) != 0;
|
||||
if (!m_apuTrlLengthEnabled)
|
||||
m_apuTrlLengthCounter = 0;
|
||||
}
|
||||
|
||||
void ApuTrl::apuTrlRead4015()
|
||||
{
|
||||
if (m_apuTrlLengthCounter > 0)
|
||||
m_apu.setRegIoDb((m_apu.regIoDb() & 0xFB) | 0x04);
|
||||
}
|
||||
|
||||
void ApuTrl::apuTrlWriteState(QDataStream &dataStream) const
|
||||
{
|
||||
dataStream
|
||||
<< m_apuTrlLinerControlFlag
|
||||
<< m_apuTrlLinerControlReload
|
||||
<< m_apuTrlTimer
|
||||
<< m_apuTrlLengthEnabled
|
||||
<< m_apuTrlLengthCounter
|
||||
<< m_apuTrlLinerControlReloadFlag
|
||||
<< m_apuTrlLinerCounter
|
||||
<< m_apuTrlOutput
|
||||
<< m_apuTrlPeriodDevider
|
||||
<< m_apuTrlStep
|
||||
<< m_apuTrlIgnoreReload;
|
||||
}
|
||||
|
||||
void ApuTrl::apuTrlReadState(QDataStream &dataStream)
|
||||
{
|
||||
dataStream
|
||||
>> m_apuTrlLinerControlFlag
|
||||
>> m_apuTrlLinerControlReload
|
||||
>> m_apuTrlTimer
|
||||
>> m_apuTrlLengthEnabled
|
||||
>> m_apuTrlLengthCounter
|
||||
>> m_apuTrlLinerControlReloadFlag
|
||||
>> m_apuTrlLinerCounter
|
||||
>> m_apuTrlOutput
|
||||
>> m_apuTrlPeriodDevider
|
||||
>> m_apuTrlStep
|
||||
>> m_apuTrlIgnoreReload;
|
||||
}
|
||||
|
||||
qint32 ApuTrl::output() const
|
||||
{
|
||||
return m_apuTrlOutput;
|
||||
}
|
||||
Reference in new issue
Block a user