2019-02-12 22:13:09 -05:00
|
|
|
#include "stdafx.h"
|
|
|
|
#include "Console.h"
|
|
|
|
#include "Cpu.h"
|
2019-02-16 11:23:01 -05:00
|
|
|
#include "Ppu.h"
|
|
|
|
#include "Spc.h"
|
2019-02-17 15:37:31 -05:00
|
|
|
#include "InternalRegisters.h"
|
2019-02-17 19:54:29 -05:00
|
|
|
#include "ControlManager.h"
|
2019-02-12 22:13:09 -05:00
|
|
|
#include "MemoryManager.h"
|
2019-02-19 21:09:12 -05:00
|
|
|
#include "DmaController.h"
|
2019-02-26 22:27:09 -05:00
|
|
|
#include "BaseCartridge.h"
|
|
|
|
#include "RamHandler.h"
|
2019-02-12 22:13:09 -05:00
|
|
|
#include "Debugger.h"
|
2019-02-15 21:33:13 -05:00
|
|
|
#include "NotificationManager.h"
|
2019-02-16 11:23:01 -05:00
|
|
|
#include "SoundMixer.h"
|
2019-02-13 23:02:43 -05:00
|
|
|
#include "VideoDecoder.h"
|
|
|
|
#include "VideoRenderer.h"
|
|
|
|
#include "DebugHud.h"
|
2019-02-21 17:18:56 -05:00
|
|
|
#include "FrameLimiter.h"
|
2019-02-17 14:42:35 -05:00
|
|
|
#include "MessageManager.h"
|
2019-02-24 12:54:14 -05:00
|
|
|
#include "KeyManager.h"
|
2019-02-12 22:13:09 -05:00
|
|
|
#include "../Utilities/Timer.h"
|
|
|
|
#include "../Utilities/VirtualFile.h"
|
2019-02-21 17:18:56 -05:00
|
|
|
#include "../Utilities/PlatformUtilities.h"
|
2019-02-24 23:53:14 -05:00
|
|
|
#include "../Utilities/FolderUtilities.h"
|
2019-02-12 22:13:09 -05:00
|
|
|
|
2019-02-26 22:27:09 -05:00
|
|
|
Console::~Console()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2019-02-13 23:02:43 -05:00
|
|
|
void Console::Initialize()
|
|
|
|
{
|
2019-02-15 21:33:13 -05:00
|
|
|
_notificationManager.reset(new NotificationManager());
|
2019-02-13 23:02:43 -05:00
|
|
|
_videoDecoder.reset(new VideoDecoder(shared_from_this()));
|
|
|
|
_videoRenderer.reset(new VideoRenderer(shared_from_this()));
|
2019-02-16 11:23:01 -05:00
|
|
|
_soundMixer.reset(new SoundMixer());
|
2019-02-13 23:02:43 -05:00
|
|
|
_debugHud.reset(new DebugHud());
|
|
|
|
|
|
|
|
_videoDecoder->StartThread();
|
|
|
|
_videoRenderer->StartThread();
|
|
|
|
}
|
|
|
|
|
2019-02-16 01:22:31 -05:00
|
|
|
void Console::Release()
|
|
|
|
{
|
|
|
|
Stop();
|
|
|
|
|
|
|
|
_videoDecoder->StopThread();
|
|
|
|
_videoRenderer->StopThread();
|
|
|
|
|
|
|
|
_videoDecoder.reset();
|
|
|
|
_videoRenderer.reset();
|
|
|
|
_debugHud.reset();
|
|
|
|
_notificationManager.reset();
|
|
|
|
}
|
|
|
|
|
2019-02-12 22:13:09 -05:00
|
|
|
void Console::Run()
|
|
|
|
{
|
|
|
|
if(!_cpu) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
_stopFlag = false;
|
2019-02-21 17:18:56 -05:00
|
|
|
uint32_t previousFrameCount = 0;
|
|
|
|
|
|
|
|
FrameLimiter frameLimiter(16.63926405550947);
|
|
|
|
|
|
|
|
PlatformUtilities::EnableHighResolutionTimer();
|
2019-02-12 22:13:09 -05:00
|
|
|
|
2019-02-24 12:54:14 -05:00
|
|
|
uint32_t keyCode = KeyManager::GetKeyCode("Tab");
|
|
|
|
|
2019-02-12 22:13:09 -05:00
|
|
|
auto lock = _runLock.AcquireSafe();
|
|
|
|
while(!_stopFlag) {
|
|
|
|
_cpu->Exec();
|
2019-02-21 17:18:56 -05:00
|
|
|
|
|
|
|
if(previousFrameCount != _ppu->GetFrameCount()) {
|
2019-02-24 12:54:14 -05:00
|
|
|
if(!KeyManager::IsKeyPressed(keyCode)) {
|
|
|
|
frameLimiter.ProcessFrame();
|
|
|
|
frameLimiter.WaitForNextFrame();
|
|
|
|
}
|
2019-02-21 17:18:56 -05:00
|
|
|
previousFrameCount = _ppu->GetFrameCount();
|
|
|
|
}
|
2019-02-12 22:13:09 -05:00
|
|
|
}
|
2019-02-21 17:18:56 -05:00
|
|
|
|
|
|
|
PlatformUtilities::RestoreTimerResolution();
|
2019-02-12 22:13:09 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void Console::Stop()
|
|
|
|
{
|
|
|
|
_stopFlag = true;
|
2019-02-16 08:10:08 -05:00
|
|
|
|
|
|
|
shared_ptr<Debugger> debugger = _debugger;
|
|
|
|
if(debugger) {
|
|
|
|
debugger->Run();
|
|
|
|
}
|
|
|
|
|
2019-02-12 22:13:09 -05:00
|
|
|
_runLock.WaitForRelease();
|
|
|
|
|
2019-02-26 22:27:09 -05:00
|
|
|
//Make sure we release both pointers to destroy the debugger before everything else
|
|
|
|
_debugger.reset();
|
|
|
|
debugger.reset();
|
|
|
|
|
2019-02-12 22:13:09 -05:00
|
|
|
_cpu.reset();
|
2019-02-13 13:32:21 -05:00
|
|
|
_ppu.reset();
|
2019-02-16 11:23:01 -05:00
|
|
|
_spc.reset();
|
2019-02-16 01:16:57 -05:00
|
|
|
_cart.reset();
|
2019-02-17 15:37:31 -05:00
|
|
|
_internalRegisters.reset();
|
2019-02-17 19:54:29 -05:00
|
|
|
_controlManager.reset();
|
2019-02-12 22:13:09 -05:00
|
|
|
_memoryManager.reset();
|
2019-02-19 21:09:12 -05:00
|
|
|
_dmaController.reset();
|
2019-02-24 12:54:14 -05:00
|
|
|
|
|
|
|
_soundMixer->StopAudio();
|
2019-02-12 22:13:09 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void Console::LoadRom(VirtualFile romFile, VirtualFile patchFile)
|
|
|
|
{
|
|
|
|
Stop();
|
|
|
|
|
|
|
|
shared_ptr<BaseCartridge> cart = BaseCartridge::CreateCartridge(romFile, patchFile);
|
|
|
|
if(cart) {
|
2019-02-17 14:42:35 -05:00
|
|
|
MessageManager::ClearLog();
|
2019-02-24 12:54:14 -05:00
|
|
|
|
|
|
|
vector<uint8_t> spcRomData;
|
2019-02-24 23:53:14 -05:00
|
|
|
VirtualFile spcBios(FolderUtilities::CombinePath(FolderUtilities::GetHomeFolder(), "spc700.rom"));
|
2019-02-24 12:54:14 -05:00
|
|
|
if(spcBios.IsValid()) {
|
|
|
|
spcBios.ReadFile(spcRomData);
|
|
|
|
} else {
|
|
|
|
MessageManager::Log("[SPC] spc700.rom not found, cannot launch game.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-02-17 19:54:29 -05:00
|
|
|
_internalRegisters.reset(new InternalRegisters(shared_from_this()));
|
2019-02-13 18:44:39 -05:00
|
|
|
_ppu.reset(new Ppu(shared_from_this()));
|
2019-02-24 12:54:14 -05:00
|
|
|
_spc.reset(new Spc(shared_from_this(), spcRomData));
|
2019-02-15 21:33:13 -05:00
|
|
|
_cart = cart;
|
2019-02-17 19:54:29 -05:00
|
|
|
_controlManager.reset(new ControlManager(shared_from_this()));
|
2019-02-15 00:08:50 -05:00
|
|
|
_memoryManager.reset(new MemoryManager());
|
2019-02-24 19:57:34 -05:00
|
|
|
_dmaController.reset(new DmaController(_memoryManager.get()));
|
2019-02-19 21:09:12 -05:00
|
|
|
|
2019-02-16 01:16:57 -05:00
|
|
|
_memoryManager->Initialize(shared_from_this());
|
2019-02-15 00:08:50 -05:00
|
|
|
|
2019-02-28 16:53:04 -05:00
|
|
|
_cpu.reset(new Cpu(_memoryManager.get()));
|
2019-02-24 12:54:14 -05:00
|
|
|
_memoryManager->IncrementMasterClockValue<160>();
|
2019-02-16 00:47:53 -05:00
|
|
|
|
2019-02-16 08:10:08 -05:00
|
|
|
//if(_debugger) {
|
2019-02-16 00:47:53 -05:00
|
|
|
//Reset debugger if it was running before
|
2019-02-24 12:54:14 -05:00
|
|
|
//auto lock = _debuggerLock.AcquireSafe();
|
|
|
|
//_debugger.reset();
|
|
|
|
//GetDebugger();
|
2019-02-16 08:10:08 -05:00
|
|
|
//}
|
2019-02-12 22:13:09 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-16 11:23:01 -05:00
|
|
|
shared_ptr<SoundMixer> Console::GetSoundMixer()
|
|
|
|
{
|
|
|
|
return _soundMixer;
|
|
|
|
}
|
|
|
|
|
2019-02-13 23:02:43 -05:00
|
|
|
shared_ptr<VideoRenderer> Console::GetVideoRenderer()
|
|
|
|
{
|
|
|
|
return _videoRenderer;
|
|
|
|
}
|
|
|
|
|
|
|
|
shared_ptr<VideoDecoder> Console::GetVideoDecoder()
|
|
|
|
{
|
|
|
|
return _videoDecoder;
|
|
|
|
}
|
|
|
|
|
2019-02-15 21:33:13 -05:00
|
|
|
shared_ptr<NotificationManager> Console::GetNotificationManager()
|
|
|
|
{
|
|
|
|
return _notificationManager;
|
|
|
|
}
|
|
|
|
|
2019-02-13 23:02:43 -05:00
|
|
|
shared_ptr<DebugHud> Console::GetDebugHud()
|
|
|
|
{
|
|
|
|
return _debugHud;
|
|
|
|
}
|
|
|
|
|
2019-02-13 18:44:39 -05:00
|
|
|
shared_ptr<Cpu> Console::GetCpu()
|
|
|
|
{
|
|
|
|
return _cpu;
|
|
|
|
}
|
|
|
|
|
2019-02-13 13:32:21 -05:00
|
|
|
shared_ptr<Ppu> Console::GetPpu()
|
|
|
|
{
|
|
|
|
return _ppu;
|
|
|
|
}
|
|
|
|
|
2019-02-16 11:23:01 -05:00
|
|
|
shared_ptr<Spc> Console::GetSpc()
|
|
|
|
{
|
|
|
|
return _spc;
|
|
|
|
}
|
|
|
|
|
2019-02-15 21:33:13 -05:00
|
|
|
shared_ptr<BaseCartridge> Console::GetCartridge()
|
|
|
|
{
|
|
|
|
return _cart;
|
|
|
|
}
|
|
|
|
|
2019-02-13 23:02:43 -05:00
|
|
|
shared_ptr<MemoryManager> Console::GetMemoryManager()
|
|
|
|
{
|
|
|
|
return _memoryManager;
|
|
|
|
}
|
|
|
|
|
2019-02-17 15:37:31 -05:00
|
|
|
shared_ptr<InternalRegisters> Console::GetInternalRegisters()
|
|
|
|
{
|
|
|
|
return _internalRegisters;
|
|
|
|
}
|
|
|
|
|
2019-02-17 19:54:29 -05:00
|
|
|
shared_ptr<ControlManager> Console::GetControlManager()
|
|
|
|
{
|
|
|
|
return _controlManager;
|
|
|
|
}
|
|
|
|
|
2019-02-19 21:09:12 -05:00
|
|
|
shared_ptr<DmaController> Console::GetDmaController()
|
|
|
|
{
|
|
|
|
return _dmaController;
|
|
|
|
}
|
|
|
|
|
2019-02-16 00:47:53 -05:00
|
|
|
shared_ptr<Debugger> Console::GetDebugger(bool autoStart)
|
2019-02-12 22:13:09 -05:00
|
|
|
{
|
2019-02-16 00:47:53 -05:00
|
|
|
shared_ptr<Debugger> debugger = _debugger;
|
|
|
|
if(!debugger && autoStart) {
|
|
|
|
//Lock to make sure we don't try to start debuggers in 2 separate threads at once
|
|
|
|
auto lock = _debuggerLock.AcquireSafe();
|
|
|
|
debugger = _debugger;
|
|
|
|
if(!debugger) {
|
|
|
|
debugger.reset(new Debugger(shared_from_this()));
|
|
|
|
_debugger = debugger;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return debugger;
|
2019-02-12 22:13:09 -05:00
|
|
|
}
|
|
|
|
|
2019-02-17 15:02:33 -05:00
|
|
|
bool Console::IsRunning()
|
|
|
|
{
|
|
|
|
return _cpu != nullptr;
|
|
|
|
}
|
|
|
|
|
2019-02-12 22:13:09 -05:00
|
|
|
void Console::ProcessCpuRead(uint32_t addr, uint8_t value, MemoryOperationType type)
|
|
|
|
{
|
|
|
|
if(_debugger) {
|
|
|
|
_debugger->ProcessCpuRead(addr, value, type);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Console::ProcessCpuWrite(uint32_t addr, uint8_t value, MemoryOperationType type)
|
|
|
|
{
|
|
|
|
if(_debugger) {
|
|
|
|
_debugger->ProcessCpuWrite(addr, value, type);
|
|
|
|
}
|
|
|
|
}
|