applen: add --log, --ntsc, and log time till first $C000 access.
This commit is contained in:
parent
7529f5c659
commit
35a81f8009
7 changed files with 97 additions and 24 deletions
|
@ -47,6 +47,7 @@ add_library(appleii SHARED
|
|||
linux/duplicates/Joystick.cpp
|
||||
linux/duplicates/Frame.cpp
|
||||
linux/duplicates/SerialComms.cpp
|
||||
linux/duplicates/Applewin.cpp
|
||||
|
||||
Z80VICE/z80.cpp
|
||||
Z80VICE/z80mem.cpp
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
#include <ncurses.h>
|
||||
|
||||
#include <boost/program_options.hpp>
|
||||
|
@ -37,8 +36,10 @@ namespace
|
|||
bool createMissingDisks;
|
||||
std::string snapshot;
|
||||
int memclear;
|
||||
bool log;
|
||||
bool benchmark;
|
||||
bool headless;
|
||||
bool ntsc;
|
||||
bool saveConfigurationOnExit;
|
||||
|
||||
bool run; // false if options include "-h"
|
||||
|
@ -70,7 +71,9 @@ namespace
|
|||
|
||||
po::options_description emulatorDesc("Emulator");
|
||||
emulatorDesc.add_options()
|
||||
("log", "Log to AppleWin.log")
|
||||
("headless,hl", "Headless: disable video")
|
||||
("ntsc,nt", "NTSC: execute NTSC code")
|
||||
("benchmark,b", "Benchmark emulator");
|
||||
desc.add(emulatorDesc);
|
||||
|
||||
|
@ -113,6 +116,8 @@ namespace
|
|||
|
||||
options.benchmark = vm.count("benchmark") > 0;
|
||||
options.headless = vm.count("headless") > 0;
|
||||
options.log = vm.count("log") > 0;
|
||||
options.ntsc = vm.count("ntsc") > 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -128,7 +133,7 @@ namespace
|
|||
}
|
||||
}
|
||||
|
||||
bool ContinueExecution(const bool updateVideo)
|
||||
bool ContinueExecution(const EmulatorOptions & options)
|
||||
{
|
||||
const auto start = std::chrono::steady_clock::now();
|
||||
|
||||
|
@ -144,7 +149,9 @@ namespace
|
|||
|
||||
const DWORD uCyclesToExecute = fExecutionPeriodClks;
|
||||
|
||||
const bool bVideoUpdate = false;
|
||||
const bool bVideoUpdate = options.ntsc;
|
||||
g_bFullSpeed = !bVideoUpdate;
|
||||
|
||||
const DWORD uActualCyclesExecuted = CpuExecute(uCyclesToExecute, bVideoUpdate);
|
||||
g_dwCyclesThisFrame += uActualCyclesExecuted;
|
||||
|
||||
|
@ -156,6 +163,12 @@ namespace
|
|||
{
|
||||
case KEY_F(2):
|
||||
{
|
||||
g_bRestart = false;
|
||||
return false;
|
||||
}
|
||||
case KEY_F(3):
|
||||
{
|
||||
g_bRestart = true;
|
||||
return false;
|
||||
}
|
||||
case KEY_F(12):
|
||||
|
@ -173,35 +186,39 @@ namespace
|
|||
const UINT dwClksPerFrame = NTSC_GetCyclesPerFrame();
|
||||
if (g_dwCyclesThisFrame >= dwClksPerFrame)
|
||||
{
|
||||
g_dwCyclesThisFrame -= dwClksPerFrame;
|
||||
if (updateVideo)
|
||||
g_dwCyclesThisFrame = g_dwCyclesThisFrame % dwClksPerFrame;
|
||||
if (!options.headless)
|
||||
{
|
||||
VideoRedrawScreen();
|
||||
}
|
||||
}
|
||||
|
||||
const auto end = std::chrono::steady_clock::now();
|
||||
const auto diff = end - start;
|
||||
const long us = std::chrono::duration_cast<std::chrono::microseconds>(diff).count();
|
||||
|
||||
const double coeff = exp(-0.000001 * nExecutionPeriodUsec); // 0.36 after 1 second
|
||||
|
||||
g_relativeSpeed = g_relativeSpeed * coeff + double(us) / double(nExecutionPeriodUsec) * (1.0 - coeff);
|
||||
|
||||
if (!sg_Disk2Card.IsConditionForFullSpeed())
|
||||
if (!options.headless)
|
||||
{
|
||||
if (us < nExecutionPeriodUsec)
|
||||
const auto end = std::chrono::steady_clock::now();
|
||||
const auto diff = end - start;
|
||||
const long us = std::chrono::duration_cast<std::chrono::microseconds>(diff).count();
|
||||
|
||||
const double coeff = exp(-0.000001 * nExecutionPeriodUsec); // 0.36 after 1 second
|
||||
|
||||
g_relativeSpeed = g_relativeSpeed * coeff + double(us) / double(nExecutionPeriodUsec) * (1.0 - coeff);
|
||||
|
||||
if (!sg_Disk2Card.IsConditionForFullSpeed())
|
||||
{
|
||||
usleep(nExecutionPeriodUsec - us);
|
||||
if (us < nExecutionPeriodUsec)
|
||||
{
|
||||
usleep(nExecutionPeriodUsec - us);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void EnterMessageLoop(const bool updateVideo)
|
||||
void EnterMessageLoop(const EmulatorOptions & options)
|
||||
{
|
||||
while (ContinueExecution(updateVideo))
|
||||
LogFileTimeUntilFirstKeyReadReset();
|
||||
while (ContinueExecution(options))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
@ -238,9 +255,6 @@ namespace
|
|||
|
||||
int foo(int argc, const char * argv [])
|
||||
{
|
||||
g_fh = fopen("/tmp/applewin.txt", "w");
|
||||
setbuf(g_fh, NULL);
|
||||
|
||||
EmulatorOptions options;
|
||||
options.memclear = g_nMemoryClearType;
|
||||
const bool run = getEmulatorOptions(argc, argv, options);
|
||||
|
@ -248,6 +262,11 @@ namespace
|
|||
if (!run)
|
||||
return 1;
|
||||
|
||||
if (options.log)
|
||||
{
|
||||
LogInit();
|
||||
}
|
||||
|
||||
InitializeRegistry("applen.conf");
|
||||
|
||||
g_nMemoryClearType = options.memclear;
|
||||
|
@ -296,11 +315,10 @@ namespace
|
|||
if (options.benchmark)
|
||||
{
|
||||
VideoBenchmark(&VideoRedrawScreen);
|
||||
g_bRestart = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
EnterMessageLoop(!options.headless);
|
||||
EnterMessageLoop(options);
|
||||
}
|
||||
sg_Mouse.Uninitialize();
|
||||
sg_Mouse.Reset();
|
||||
|
|
|
@ -369,7 +369,7 @@ void FrameRefreshStatus(int x, bool)
|
|||
|
||||
void NVideoInitialize()
|
||||
{
|
||||
VideoReinitialize();
|
||||
VideoInitialize();
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
initscr();
|
||||
|
@ -540,6 +540,7 @@ BYTE KeybGetKeycode ()
|
|||
|
||||
BYTE KeybReadData()
|
||||
{
|
||||
LogFileTimeUntilFirstKeyRead();
|
||||
return nextKey;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,3 +7,6 @@ void SetWindowTitle();
|
|||
void getScreenData(uint8_t * & data, int & width, int & height, int & sx, int & sy, int & sw, int & sh);
|
||||
|
||||
extern int g_nAltCharSetOffset; // alternate character set
|
||||
|
||||
void LogFileTimeUntilFirstKeyReadReset(void);
|
||||
void LogFileTimeUntilFirstKeyRead(void);
|
||||
|
|
40
source/linux/duplicates/Applewin.cpp
Normal file
40
source/linux/duplicates/Applewin.cpp
Normal file
|
@ -0,0 +1,40 @@
|
|||
#include "StdAfx.h"
|
||||
#include "Memory.h"
|
||||
#include "Log.h"
|
||||
#include "Common.h"
|
||||
#include "CPU.h"
|
||||
|
||||
static bool bLogKeyReadDone = false;
|
||||
static DWORD dwLogKeyReadTickStart;
|
||||
|
||||
void LogFileTimeUntilFirstKeyReadReset(void)
|
||||
{
|
||||
if (!g_fh)
|
||||
return;
|
||||
|
||||
dwLogKeyReadTickStart = GetTickCount();
|
||||
|
||||
bLogKeyReadDone = false;
|
||||
}
|
||||
|
||||
// Log the time from emulation restart/reboot until the first key read: BIT $C000
|
||||
// . AZTEC.DSK (DOS 3.3) does prior LDY $C000 reads, but the BIT $C000 is at the "Press any key" message
|
||||
// . Phasor1.dsk / ProDOS 1.1.1: PC=E797: B1 50: LDA ($50),Y / "Select an Option:" message
|
||||
// . Rescue Raiders v1.3,v1.5: PC=895: LDA $C000 / boot to intro
|
||||
void LogFileTimeUntilFirstKeyRead(void)
|
||||
{
|
||||
if (!g_fh || bLogKeyReadDone)
|
||||
return;
|
||||
|
||||
if ( (mem[regs.pc-3] != 0x2C) // AZTEC: bit $c000
|
||||
&& !((regs.pc-2) == 0xE797 && mem[regs.pc-2] == 0xB1 && mem[regs.pc-1] == 0x50) // Phasor1: lda ($50),y
|
||||
&& !((regs.pc-3) == 0x0895 && mem[regs.pc-3] == 0xAD) // Rescue Raiders v1.3,v1.5: lda $c000
|
||||
)
|
||||
return;
|
||||
|
||||
DWORD dwTime = GetTickCount() - dwLogKeyReadTickStart;
|
||||
|
||||
LogFileOutput("Time from emulation reboot until first $C000 access: %d msec\n", dwTime);
|
||||
|
||||
bLogKeyReadDone = true;
|
||||
}
|
|
@ -19,6 +19,15 @@ DWORD timeGetTime()
|
|||
return now.tv_usec / 1000;
|
||||
}
|
||||
|
||||
/// Returns the number of ticks since an undefined time (usually system startup).
|
||||
DWORD GetTickCount()
|
||||
{
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
const uint64_t ticks = (uint64_t)(ts.tv_nsec / 1000000) + ((uint64_t)ts.tv_sec * 1000ull);
|
||||
return ticks;
|
||||
}
|
||||
|
||||
void GetLocalTime(SYSTEMTIME *t)
|
||||
{
|
||||
timespec ts;
|
||||
|
|
|
@ -26,4 +26,5 @@ int GetDateFormat(LCID Locale, DWORD dwFlags, CONST SYSTEMTIME *lpDate, LPCSTR l
|
|||
int GetTimeFormat(LCID Locale, DWORD dwFlags, CONST SYSTEMTIME *lpTime, LPCSTR lpFormat, LPSTR lpTimeStr, int cchTime);
|
||||
|
||||
DWORD timeGetTime();
|
||||
DWORD GetTickCount();
|
||||
void GetLocalTime(SYSTEMTIME *t);
|
||||
|
|
Loading…
Add table
Reference in a new issue