2015-07-14 21:50:14 -04:00
|
|
|
#pragma once
|
|
|
|
#include "stdafx.h"
|
|
|
|
#include "IMemoryHandler.h"
|
2015-07-17 20:58:57 -04:00
|
|
|
#include "EmulationSettings.h"
|
2015-07-19 22:24:56 -04:00
|
|
|
#include "Snapshotable.h"
|
2016-01-14 01:21:09 -05:00
|
|
|
#include "SoundMixer.h"
|
2015-07-14 21:50:14 -04:00
|
|
|
|
2015-07-14 23:35:30 -04:00
|
|
|
class BaseApuChannel : public IMemoryHandler, public Snapshotable
|
2015-07-14 21:50:14 -04:00
|
|
|
{
|
|
|
|
private:
|
2016-01-14 01:21:09 -05:00
|
|
|
SoundMixer *_mixer;
|
|
|
|
int8_t _lastOutput;
|
2015-07-19 01:30:13 -04:00
|
|
|
uint32_t _previousCycle;
|
2015-07-17 20:58:57 -04:00
|
|
|
AudioChannel _channel;
|
2015-07-21 23:05:27 -04:00
|
|
|
NesModel _nesModel;
|
2015-07-14 21:50:14 -04:00
|
|
|
|
|
|
|
protected:
|
|
|
|
uint16_t _timer = 0;
|
|
|
|
uint16_t _period = 0;
|
2015-07-17 20:58:57 -04:00
|
|
|
|
2015-07-19 01:30:13 -04:00
|
|
|
AudioChannel GetChannel()
|
|
|
|
{
|
|
|
|
return _channel;
|
|
|
|
}
|
|
|
|
|
2015-07-14 21:50:14 -04:00
|
|
|
public:
|
|
|
|
virtual void Clock() = 0;
|
|
|
|
virtual bool GetStatus() = 0;
|
|
|
|
|
2016-01-14 01:21:09 -05:00
|
|
|
BaseApuChannel(AudioChannel channel, SoundMixer *mixer)
|
2015-07-14 21:50:14 -04:00
|
|
|
{
|
2015-07-17 20:58:57 -04:00
|
|
|
_channel = channel;
|
2016-01-14 01:21:09 -05:00
|
|
|
_mixer = mixer;
|
2015-07-14 23:35:30 -04:00
|
|
|
|
2015-07-19 01:30:13 -04:00
|
|
|
Reset(false);
|
2015-07-14 21:50:14 -04:00
|
|
|
}
|
|
|
|
|
2015-07-19 01:30:13 -04:00
|
|
|
virtual void Reset(bool softReset)
|
2015-07-14 21:50:14 -04:00
|
|
|
{
|
2015-07-14 23:35:30 -04:00
|
|
|
_timer = 0;
|
|
|
|
_period = 0;
|
|
|
|
_lastOutput = 0;
|
|
|
|
_previousCycle = 0;
|
2016-01-14 01:21:09 -05:00
|
|
|
_mixer->Reset();
|
2015-07-14 23:35:30 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
virtual void StreamState(bool saving)
|
|
|
|
{
|
2016-01-15 23:51:27 -05:00
|
|
|
if(!saving) {
|
|
|
|
_previousCycle = 0;
|
|
|
|
}
|
|
|
|
|
2016-01-21 00:53:02 -05:00
|
|
|
Stream<int8_t>(_lastOutput);
|
2015-07-14 23:35:30 -04:00
|
|
|
Stream<uint16_t>(_timer);
|
|
|
|
Stream<uint16_t>(_period);
|
2015-07-21 23:05:27 -04:00
|
|
|
Stream<NesModel>(_nesModel);
|
2015-07-14 21:50:14 -04:00
|
|
|
}
|
|
|
|
|
2015-07-21 23:05:27 -04:00
|
|
|
void SetNesModel(NesModel model)
|
|
|
|
{
|
|
|
|
_nesModel = model;
|
|
|
|
}
|
|
|
|
|
|
|
|
NesModel GetNesModel()
|
|
|
|
{
|
|
|
|
return _nesModel;
|
|
|
|
}
|
|
|
|
|
2015-07-14 21:50:14 -04:00
|
|
|
virtual void Run(uint32_t targetCycle)
|
|
|
|
{
|
|
|
|
while(_previousCycle < targetCycle) {
|
|
|
|
if(_timer == 0) {
|
|
|
|
Clock();
|
2016-01-14 01:21:09 -05:00
|
|
|
_timer = _period;
|
2016-01-12 17:16:01 -05:00
|
|
|
_previousCycle++;
|
2015-07-14 21:50:14 -04:00
|
|
|
} else {
|
2016-01-12 17:16:01 -05:00
|
|
|
uint32_t cyclesToRun = targetCycle - _previousCycle;
|
2015-07-14 21:50:14 -04:00
|
|
|
uint16_t skipCount = _timer > cyclesToRun ? cyclesToRun : _timer;
|
|
|
|
_timer -= skipCount;
|
2016-01-12 17:16:01 -05:00
|
|
|
_previousCycle += skipCount;
|
2015-07-14 21:50:14 -04:00
|
|
|
|
|
|
|
if(cyclesToRun == 0) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t ReadRAM(uint16_t addr)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-01-14 01:21:09 -05:00
|
|
|
void AddOutput(int8_t output)
|
2015-07-14 21:50:14 -04:00
|
|
|
{
|
|
|
|
if(output != _lastOutput) {
|
2016-01-14 01:21:09 -05:00
|
|
|
_mixer->AddDelta(_channel, _previousCycle, output - _lastOutput);
|
|
|
|
_lastOutput = output;
|
2015-07-14 21:50:14 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void EndFrame()
|
|
|
|
{
|
|
|
|
_previousCycle = 0;
|
|
|
|
}
|
|
|
|
};
|