Skip to content
This repository was archived by the owner on Sep 11, 2023. It is now read-only.

Commit 04310ed

Browse files
committed
Core refactoring (remove static variables) - WIP
1 parent a4ed758 commit 04310ed

File tree

217 files changed

+2862
-2684
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

217 files changed

+2862
-2684
lines changed

Core/A12Watcher.h

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#pragma once
22

33
#include "stdafx.h"
4-
#include "CPU.h"
54
#include "PPU.h"
65
#include "Snapshotable.h"
76

@@ -24,20 +23,19 @@ class A12Watcher : public Snapshotable
2423
Stream(_lastCycle, _cyclesDown);
2524
}
2625

27-
A12StateChange UpdateVramAddress(uint16_t addr)
26+
A12StateChange UpdateVramAddress(uint16_t addr, uint32_t frameCycle)
2827
{
2928
A12StateChange result = A12StateChange::None;
30-
uint32_t cycle = PPU::GetFrameCycle();
3129

3230
if((addr & 0x1000) == 0) {
3331
if(_cyclesDown == 0) {
3432
_cyclesDown = 1;
3533
} else {
36-
if(_lastCycle > cycle) {
34+
if(_lastCycle > frameCycle) {
3735
//We changed frames
38-
_cyclesDown += (89342 - _lastCycle) + cycle;
36+
_cyclesDown += (89342 - _lastCycle) + frameCycle;
3937
} else {
40-
_cyclesDown += (cycle - _lastCycle);
38+
_cyclesDown += (frameCycle - _lastCycle);
4139
}
4240
}
4341
result = A12StateChange::Fall;
@@ -47,7 +45,7 @@ class A12Watcher : public Snapshotable
4745
}
4846
_cyclesDown = 0;
4947
}
50-
_lastCycle = cycle;
48+
_lastCycle = frameCycle;
5149

5250
return result;
5351
}

Core/APU.cpp

Lines changed: 53 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -10,34 +10,27 @@
1010
#include "SoundMixer.h"
1111
#include "MemoryManager.h"
1212

13-
APU* APU::Instance = nullptr;
14-
bool APU::_apuEnabled = true;
15-
16-
APU::APU(MemoryManager* memoryManager)
13+
APU::APU(shared_ptr<Console> console)
1714
{
18-
APU::Instance = this;
19-
20-
_memoryManager = memoryManager;
21-
2215
_nesModel = NesModel::Auto;
23-
2416
_apuEnabled = true;
2517

26-
_mixer.reset(new SoundMixer());
18+
_console = console;
19+
_mixer = _console->GetSoundMixer();
2720

28-
_squareChannel[0].reset(new SquareChannel(AudioChannel::Square1, _mixer.get(), true));
29-
_squareChannel[1].reset(new SquareChannel(AudioChannel::Square2, _mixer.get(), false));
30-
_triangleChannel.reset(new TriangleChannel(AudioChannel::Triangle, _mixer.get()));
31-
_noiseChannel.reset(new NoiseChannel(AudioChannel::Noise, _mixer.get()));
32-
_deltaModulationChannel.reset(new DeltaModulationChannel(AudioChannel::DMC, _mixer.get(), _memoryManager));
33-
_frameCounter.reset(new ApuFrameCounter(&APU::FrameCounterTick));
21+
_squareChannel[0].reset(new SquareChannel(AudioChannel::Square1, _console, _mixer.get(), true));
22+
_squareChannel[1].reset(new SquareChannel(AudioChannel::Square2, _console, _mixer.get(), false));
23+
_triangleChannel.reset(new TriangleChannel(AudioChannel::Triangle, _console, _mixer.get()));
24+
_noiseChannel.reset(new NoiseChannel(AudioChannel::Noise, _console, _mixer.get()));
25+
_deltaModulationChannel.reset(new DeltaModulationChannel(AudioChannel::DMC, _console, _mixer.get()));
26+
_frameCounter.reset(new ApuFrameCounter(_console));
3427

35-
_memoryManager->RegisterIODevice(_squareChannel[0].get());
36-
_memoryManager->RegisterIODevice(_squareChannel[1].get());
37-
_memoryManager->RegisterIODevice(_frameCounter.get());
38-
_memoryManager->RegisterIODevice(_triangleChannel.get());
39-
_memoryManager->RegisterIODevice(_noiseChannel.get());
40-
_memoryManager->RegisterIODevice(_deltaModulationChannel.get());
28+
_console->GetMemoryManager()->RegisterIODevice(_squareChannel[0].get());
29+
_console->GetMemoryManager()->RegisterIODevice(_squareChannel[1].get());
30+
_console->GetMemoryManager()->RegisterIODevice(_frameCounter.get());
31+
_console->GetMemoryManager()->RegisterIODevice(_triangleChannel.get());
32+
_console->GetMemoryManager()->RegisterIODevice(_noiseChannel.get());
33+
_console->GetMemoryManager()->RegisterIODevice(_deltaModulationChannel.get());
4134

4235
Reset(false);
4336
}
@@ -67,20 +60,20 @@ void APU::SetNesModel(NesModel model, bool forceInit)
6760
void APU::FrameCounterTick(FrameType type)
6861
{
6962
//Quarter & half frame clock envelope & linear counter
70-
Instance->_squareChannel[0]->TickEnvelope();
71-
Instance->_squareChannel[1]->TickEnvelope();
72-
Instance->_triangleChannel->TickLinearCounter();
73-
Instance->_noiseChannel->TickEnvelope();
63+
_squareChannel[0]->TickEnvelope();
64+
_squareChannel[1]->TickEnvelope();
65+
_triangleChannel->TickLinearCounter();
66+
_noiseChannel->TickEnvelope();
7467

7568
if(type == FrameType::HalfFrame) {
7669
//Half frames clock length counter & sweep
77-
Instance->_squareChannel[0]->TickLengthCounter();
78-
Instance->_squareChannel[1]->TickLengthCounter();
79-
Instance->_triangleChannel->TickLengthCounter();
80-
Instance->_noiseChannel->TickLengthCounter();
70+
_squareChannel[0]->TickLengthCounter();
71+
_squareChannel[1]->TickLengthCounter();
72+
_triangleChannel->TickLengthCounter();
73+
_noiseChannel->TickLengthCounter();
8174

82-
Instance->_squareChannel[0]->TickSweep();
83-
Instance->_squareChannel[1]->TickSweep();
75+
_squareChannel[0]->TickSweep();
76+
_squareChannel[1]->TickSweep();
8477
}
8578
}
8679

@@ -95,11 +88,11 @@ uint8_t APU::ReadRAM(uint16_t addr)
9588
status |= _triangleChannel->GetStatus() ? 0x04 : 0x00;
9689
status |= _noiseChannel->GetStatus() ? 0x08 : 0x00;
9790
status |= _deltaModulationChannel->GetStatus() ? 0x10 : 0x00;
98-
status |= CPU::HasIRQSource(IRQSource::FrameCounter) ? 0x40 : 0x00;
99-
status |= CPU::HasIRQSource(IRQSource::DMC) ? 0x80 : 0x00;
91+
status |= _console->GetCpu()->HasIrqSource(IRQSource::FrameCounter) ? 0x40 : 0x00;
92+
status |= _console->GetCpu()->HasIrqSource(IRQSource::DMC) ? 0x80 : 0x00;
10093

10194
//Reading $4015 clears the Frame Counter interrupt flag.
102-
CPU::ClearIRQSource(IRQSource::FrameCounter);
95+
_console->GetCpu()->ClearIrqSource(IRQSource::FrameCounter);
10396

10497
return status;
10598
}
@@ -111,7 +104,7 @@ void APU::WriteRAM(uint16_t addr, uint8_t value)
111104

112105
//Writing to $4015 clears the DMC interrupt flag.
113106
//This needs to be done before setting the enabled flag for the DMC (because doing so can trigger an IRQ)
114-
CPU::ClearIRQSource(IRQSource::DMC);
107+
_console->GetCpu()->ClearIrqSource(IRQSource::DMC);
115108

116109
_squareChannel[0]->SetEnabled((value & 0x01) == 0x01);
117110
_squareChannel[1]->SetEnabled((value & 0x02) == 0x02);
@@ -153,19 +146,17 @@ void APU::Run()
153146
}
154147
}
155148

156-
void APU::StaticRun()
149+
void APU::SetNeedToRun()
157150
{
158-
Instance->Run();
151+
_needToRun = true;
159152
}
160153

161154
bool APU::NeedToRun(uint32_t currentCycle)
162155
{
163-
if(ApuLengthCounter::NeedToRun()) {
164-
return true;
165-
}
166-
167-
if(_deltaModulationChannel->NeedToRun()) {
156+
if(_needToRun || _deltaModulationChannel->NeedToRun()) {
157+
//Need to run whenever we alter the length counters
168158
//Need to run every cycle when DMC is running to get accurate emulation (CPU stalling, interaction with sprite DMA, etc.)
159+
_needToRun = false;
169160
return true;
170161
}
171162

@@ -203,6 +194,21 @@ void APU::EndFrame()
203194
_previousCycle = 0;
204195
}
205196

197+
void APU::ProcessCpuClock()
198+
{
199+
if(_apuEnabled) {
200+
if(EmulationSettings::GetOverclockRate() == 100 || !EmulationSettings::GetOverclockAdjustApu()) {
201+
Exec();
202+
} else {
203+
_cyclesNeeded += 1.0 / ((double)EmulationSettings::GetOverclockRate() / 100.0);
204+
while(_cyclesNeeded >= 1.0) {
205+
Exec();
206+
_cyclesNeeded--;
207+
}
208+
}
209+
}
210+
}
211+
206212
void APU::Reset(bool softReset)
207213
{
208214
_apuEnabled = true;
@@ -239,7 +245,7 @@ void APU::StreamState(bool saving)
239245

240246
void APU::AddExpansionAudioDelta(AudioChannel channel, int16_t delta)
241247
{
242-
Instance->_mixer->AddDelta(channel, Instance->_currentCycle, delta);
248+
_mixer->AddDelta(channel, _currentCycle, delta);
243249
}
244250

245251
void APU::SetApuStatus(bool enabled)
@@ -256,9 +262,9 @@ bool APU::IsApuEnabled()
256262
return _apuEnabled;
257263
}
258264

259-
void APU::WriteDmc4011(uint8_t value)
265+
void APU::FillDmcReadBuffer()
260266
{
261-
Instance->_deltaModulationChannel->WriteRAM(0x4011, value);
267+
_deltaModulationChannel->FillReadBuffer();
262268
}
263269

264270
ApuState APU::GetState()
@@ -271,4 +277,4 @@ ApuState APU::GetState()
271277
state.Square2 = _squareChannel[1]->GetState();
272278
state.Triangle = _triangleChannel->GetState();
273279
return state;
274-
}
280+
}

Core/APU.h

Lines changed: 17 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,24 @@
66
#include "Snapshotable.h"
77
#include "EmulationSettings.h"
88

9-
class MemoryManager;
9+
class Console;
1010
class SquareChannel;
1111
class TriangleChannel;
1212
class NoiseChannel;
1313
class DeltaModulationChannel;
1414
class ApuFrameCounter;
1515
class SoundMixer;
16+
class Debugger;
1617
enum class FrameType;
1718
enum class NesModel;
1819

1920
class APU : public Snapshotable, public IMemoryHandler
2021
{
22+
friend ApuFrameCounter;
23+
2124
private:
22-
static APU* Instance;
23-
static bool _apuEnabled;
25+
bool _apuEnabled;
26+
bool _needToRun;
2427

2528
uint32_t _previousCycle;
2629
uint32_t _currentCycle;
@@ -29,11 +32,9 @@ class APU : public Snapshotable, public IMemoryHandler
2932
unique_ptr<TriangleChannel> _triangleChannel;
3033
unique_ptr<NoiseChannel> _noiseChannel;
3134
unique_ptr<DeltaModulationChannel> _deltaModulationChannel;
32-
3335
unique_ptr<ApuFrameCounter> _frameCounter;
3436

35-
MemoryManager* _memoryManager;
36-
37+
shared_ptr<Console> _console;
3738
shared_ptr<SoundMixer> _mixer;
3839

3940
NesModel _nesModel;
@@ -42,19 +43,16 @@ class APU : public Snapshotable, public IMemoryHandler
4243

4344
private:
4445
__forceinline bool NeedToRun(uint32_t currentCycle);
45-
void Run();
4646

47-
static void FrameCounterTick(FrameType type);
47+
void FrameCounterTick(FrameType type);
4848

4949
protected:
5050
void StreamState(bool saving) override;
5151

5252
public:
53-
APU(MemoryManager* memoryManager);
53+
APU(shared_ptr<Console> console);
5454
~APU();
5555

56-
void EndFrame();
57-
5856
void Reset(bool softReset);
5957
void SetNesModel(NesModel model, bool forceInit = false);
6058

@@ -65,26 +63,13 @@ class APU : public Snapshotable, public IMemoryHandler
6563
ApuState GetState();
6664

6765
void Exec();
66+
void ProcessCpuClock();
67+
void Run();
68+
void EndFrame();
6869

69-
__forceinline static void ExecStatic()
70-
{
71-
if(APU::_apuEnabled) {
72-
if(EmulationSettings::GetOverclockRate() == 100 || !EmulationSettings::GetOverclockAdjustApu()) {
73-
Instance->Exec();
74-
} else {
75-
Instance->_cyclesNeeded += 1.0 / ((double)EmulationSettings::GetOverclockRate() / 100.0);
76-
while(Instance->_cyclesNeeded >= 1.0) {
77-
Instance->Exec();
78-
Instance->_cyclesNeeded--;
79-
}
80-
}
81-
}
82-
}
83-
84-
static void StaticRun();
85-
86-
static void AddExpansionAudioDelta(AudioChannel channel, int16_t delta);
87-
static void SetApuStatus(bool enabled);
88-
static bool IsApuEnabled();
89-
static void WriteDmc4011(uint8_t value);
70+
void AddExpansionAudioDelta(AudioChannel channel, int16_t delta);
71+
void SetApuStatus(bool enabled);
72+
bool IsApuEnabled();
73+
void FillDmcReadBuffer();
74+
void SetNeedToRun();
9075
};

Core/ApuEnvelope.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22
#include "stdafx.h"
33
#include "ApuLengthCounter.h"
4+
#include "Console.h"
45

56
class ApuEnvelope : public ApuLengthCounter
67
{
@@ -15,7 +16,7 @@ class ApuEnvelope : public ApuLengthCounter
1516
uint8_t _counter = 0;
1617

1718
protected:
18-
ApuEnvelope(AudioChannel channel, SoundMixer* mixer) : ApuLengthCounter(channel, mixer)
19+
ApuEnvelope(AudioChannel channel, shared_ptr<Console> console, SoundMixer* mixer) : ApuLengthCounter(channel, console, mixer)
1920
{
2021
}
2122

0 commit comments

Comments
 (0)