From ac398ac31bd670ff554f5cd6a414f5e3c317953e Mon Sep 17 00:00:00 2001 From: Christian Speckner Date: Wed, 27 Feb 2019 23:41:08 +0100 Subject: [PATCH] Profiling. --- src/emucore/ProfilingRunner.cxx | 83 ++++++++++++++++++- src/emucore/ProfilingRunner.hxx | 17 ++++ .../tia/frame-manager/DummyFrameManager.hxx | 25 ++++++ 3 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 src/emucore/tia/frame-manager/DummyFrameManager.hxx diff --git a/src/emucore/ProfilingRunner.cxx b/src/emucore/ProfilingRunner.cxx index 288f3f3cf..b928e63f6 100644 --- a/src/emucore/ProfilingRunner.cxx +++ b/src/emucore/ProfilingRunner.cxx @@ -15,13 +15,42 @@ // this file, and for a DISCLAIMER OF ALL WARRANTIES. //============================================================================ +#include + #include "ProfilingRunner.hxx" #include "FSNode.hxx" #include "CartDetector.hxx" #include "Cart.hxx" #include "MD5.hxx" +#include "Control.hxx" +#include "M6502.hxx" +#include "M6532.hxx" +#include "TIA.hxx" +#include "ConsoleTiming.hxx" +#include "DummyFrameManager.hxx" +#include "System.hxx" +#include "Joystick.hxx" +#include "Random.hxx" +#include "DispatchResult.hxx" + +using namespace std::chrono; + +namespace { + static constexpr uInt32 RUNTIME_DEFAULT = 60; + static constexpr uInt32 cyclesPerSecond = 262 * 76 * 60; + + void updateProgress(uInt32 from, uInt32 to) { + while (from < to) { + if (from % 10 == 0 && from > 0) cout << from << "%"; + else cout << "."; + + cout.flush(); + + from++; + } + } +} -static constexpr uInt32 RUNTIME_DEFAULT = 60; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ProfilingRunner::ProfilingRunner(int argc, char* argv[]) @@ -83,5 +112,57 @@ bool ProfilingRunner::runOne(const ProfilingRun run) return false; } + IO consoleIO; + Random rng(0); + Event event; + DummyFrameManager frameManager; + + M6502 cpu(mySettings); + M6532 riot(consoleIO, mySettings); + TIA tia(consoleIO, []() { return ConsoleTiming::ntsc; }, mySettings); + System system(rng, cpu, riot, tia, *cartridge); + + consoleIO.myLeftControl = make_unique(Controller::Left, event, system); + consoleIO.myRightControl = make_unique(Controller::Right, event, system); + consoleIO.mySwitches = make_unique(event, myProps, mySettings); + + tia.setFrameManager(&frameManager); + tia.bindToControllers(); + cartridge->setStartBankFromPropsFunc([]() { return -1; }); + + system.initialize(); + system.reset(); + + uInt64 cycles = 0; + uInt64 cyclesTarget = run.runtime * cyclesPerSecond; + + DispatchResult dispatchResult; + dispatchResult.setOk(0); + + uInt32 percent = 0; + (cout << "0%").flush(); + + time_point tp = high_resolution_clock::now(); + + while (cycles < cyclesTarget && dispatchResult.getStatus() == DispatchResult::Status::ok) { + tia.update(dispatchResult); + cycles += dispatchResult.getCycles(); + + uInt32 percentNow = std::min((100 * cycles) / cyclesTarget, static_cast(100)); + updateProgress(percent, percentNow); + + percent = percentNow; + } + + double realtimeUsed = duration_cast>(high_resolution_clock::now () - tp).count(); + + if (dispatchResult.getStatus() != DispatchResult::Status::ok) { + cout << endl << "ERROR: emulation failed after " << cycles << " cycles"; + return false; + } + + (cout << "100%" << endl).flush(); + cout << "real time: " << realtimeUsed << " seconds" << endl; + return true; } diff --git a/src/emucore/ProfilingRunner.hxx b/src/emucore/ProfilingRunner.hxx index 18bdaea3f..6c63de49a 100644 --- a/src/emucore/ProfilingRunner.hxx +++ b/src/emucore/ProfilingRunner.hxx @@ -18,8 +18,13 @@ #ifndef PROFILING_RUNNER #define PROFILING_RUNNER +class Control; +class Switches; + #include "bspf.hxx" #include "Settings.hxx" +#include "ConsoleIO.hxx" +#include "Props.hxx" class ProfilingRunner { public: @@ -35,6 +40,16 @@ class ProfilingRunner { uInt32 runtime; }; + struct IO: public ConsoleIO { + Controller& leftController() const override { return *myLeftControl; } + Controller& rightController() const override { return *myRightControl; } + Switches& switches() const override { return *mySwitches; } + + unique_ptr myLeftControl; + unique_ptr myRightControl; + unique_ptr mySwitches; + }; + private: bool runOne(const ProfilingRun run); @@ -44,6 +59,8 @@ class ProfilingRunner { vector profilingRuns; Settings mySettings; + + Properties myProps; }; #endif // PROFILING_RUNNER diff --git a/src/emucore/tia/frame-manager/DummyFrameManager.hxx b/src/emucore/tia/frame-manager/DummyFrameManager.hxx new file mode 100644 index 000000000..9668f8b1d --- /dev/null +++ b/src/emucore/tia/frame-manager/DummyFrameManager.hxx @@ -0,0 +1,25 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +//============================================================================ + +#ifndef TIA_DUMMY_FRAME_MANAGER +#define TIA_DUMMY_FRAME_MANAGER + +#include "AbstractFrameManager.hxx" + +class DummyFrameManager: public AbstractFrameManager {}; + +#endif // TIA_DUMMY_FRAME_MANAGER