Lite refactor video timing

This commit is contained in:
Aaron Culliney 2018-04-07 11:32:52 -07:00
parent 6ed0100291
commit aa41c89e68
5 changed files with 45 additions and 48 deletions

View File

@ -2368,7 +2368,7 @@ void MB_UpdateCycles(ULONG uExecutedCycles)
if(g_SoundcardType == CT_Empty)
return;
timing_checkpoint_cycles();
timing_checkpointCycles();
unsigned long uCycles = cycles_count_total - g_uLastCumulativeCycles;
g_uLastCumulativeCycles = cycles_count_total;
#if MB_TRACING
@ -2385,6 +2385,9 @@ void MB_UpdateCycles(ULONG uExecutedCycles)
_ASSERT(uCycles < 0x10000);
#endif
uint16_t nClocks = (uint16_t) uCycles;
if (nClocks == 0) {
return;
}
for(int i=0; i<NUM_SY6522; i++)
{

View File

@ -445,6 +445,8 @@ void speaker_flush(void) {
ASSERT_ON_CPU_THREAD();
timing_checkpointCycles();
if (is_fullspeed) {
cycles_quiet_time = cycles_count_total;
speaker_going_silent = false;
@ -514,7 +516,7 @@ GLUE_C_READ(speaker_toggle)
{
ASSERT_ON_CPU_THREAD();
timing_checkpoint_cycles();
timing_checkpointCycles();
#if SPEAKER_TRACING
// output cycle count delta when toggled

View File

@ -1377,7 +1377,6 @@ unsigned long video_clearDirty(unsigned long flags) {
// References to Jim Sather's books are given as eg:
// UTAIIe:5-7,P3 (Understanding the Apple IIe, chapter 5, page 7, Paragraph 3)
extern unsigned int CpuGetCyclesThisVideoFrame(void);
uint16_t video_scanner_get_address(bool *vblBarOut) {
const bool SW_HIRES = (run_args.softswitches & SS_HIRES);
const bool SW_TEXT = (run_args.softswitches & SS_TEXT);
@ -1386,7 +1385,7 @@ uint16_t video_scanner_get_address(bool *vblBarOut) {
const bool SW_MIXED = (run_args.softswitches & SS_MIXED);
// get video scanner position
unsigned int nCycles = CpuGetCyclesThisVideoFrame();
unsigned int nCycles = timing_currentVideoFrameCycles();
// machine state switches
int nHires = (SW_HIRES && !SW_TEXT) ? 1 : 0;

View File

@ -9,28 +9,6 @@
*
*/
/*
* 65c02 CPU timing support. Source inspired/derived from AppleWin.
*
* Simplified timing loop for each execution period:
*
* ..{...+....[....|..................|.........]....^....|....^....^....}......
* ti MBB CHK CHK MBE CHX SPK MBX tj ZZZ
*
* - ti : timing sample begin (lock out interface thread)
* - tj : timing sample end (unlock interface thread)
* - [ : cpu65_run()
* - ] : cpu65_run() finished
* - CHK : incoming timing_checkpoint_cycles() call from IO (bumps cycles_count_total)
* - CHX : update remainder of timing_checkpoint_cycles() for execution period
* - MBB : Mockingboard begin
* - MBE : Mockingboard end/flush (output)
* - MBX : Mockingboard end video frame (output)
* - SPK : Speaker output
* - ZZZ : housekeeping+sleep (or not)
*
*/
#include "common.h"
#define DEBUG_TIMING (!defined(NDEBUG) && 0) // enable to print timing stats
@ -42,18 +20,12 @@
#define DISK_MOTOR_QUIET_NSECS 2000000
// VBL constants?
#define uCyclesPerLine 65 // 25 cycles of HBL & 40 cycles of HBL'
#define uVisibleLinesPerFrame (64*3) // 192
#define uLinesPerFrame (262) // 64 in each third of the screen & 70 in VBL
#define dwClksPerFrame (uCyclesPerLine * uLinesPerFrame) // 17030
// cycle counting
double cycles_persec_target = CLK_6502;
unsigned long cycles_count_total = 0; // Running at spec ~1MHz, this will approach overflow in ~4000secs (for 32bit architectures)
int cycles_speaker_feedback = 0;
static int32_t cycles_checkpoint_count = 0;
static unsigned int g_dwCyclesThisFrame = 0;
static unsigned int cycles_this_frame = 0;
// scaling and speed adjustments
#if !MOBILE_DEVICE
@ -144,7 +116,7 @@ void reinitialize(void) {
#endif
cycles_count_total = 0;
g_dwCyclesThisFrame = 0;
cycles_this_frame = 0;
#if TESTING
extern unsigned long (*testing_getCyclesCount)(void);
if (testing_getCyclesCount) {
@ -352,11 +324,11 @@ cpu_runloop:
#if DEBUG_TIMING
dbg_cycles_executed += run_args.cpu65_cycle_count;
#endif
g_dwCyclesThisFrame += run_args.cpu65_cycle_count;
cycles_this_frame += run_args.cpu65_cycle_count;
if (is_debugging) {
debugging_cycles -= run_args.cpu65_cycle_count;
timing_checkpoint_cycles();
timing_checkpointCycles();
if (c_debugger_should_break() || (debugging_cycles <= 0)) {
int err = 0;
@ -380,12 +352,13 @@ cpu_runloop:
MB_UpdateCycles();
timing_checkpoint_cycles();
timing_checkpointCycles();
speaker_flush(); // play audio
if (g_dwCyclesThisFrame >= dwClksPerFrame) {
g_dwCyclesThisFrame -= dwClksPerFrame;
// video frame counter overflow ...
if (cycles_this_frame >= CYCLES_FRAME) {
cycles_this_frame -= CYCLES_FRAME;
MB_EndOfVideoFrame();
}
@ -536,15 +509,14 @@ void timing_stopCPU(void) {
}
}
unsigned int CpuGetCyclesThisVideoFrame(void) {
unsigned int timing_currentVideoFrameCycles(void) {
ASSERT_ON_CPU_THREAD();
timing_checkpoint_cycles();
return g_dwCyclesThisFrame + cycles_checkpoint_count;
timing_checkpointCycles();
return cycles_this_frame + cycles_checkpoint_count;
}
// Called when an IO-reg is accessed & accurate global cycle count info is needed
void timing_checkpoint_cycles(void) {
// Called when accurate global cycle count info is needed
void timing_checkpointCycles(void) {
ASSERT_ON_CPU_THREAD();
const int32_t d = run_args.cpu65_cycle_count - cycles_checkpoint_count;

View File

@ -33,7 +33,6 @@
#define EXECUTION_PERIOD_NSECS 1000000UL // NANOSECONDS_PER_SECOND / EXECUTION_CHURN_RATE
// timing values cribbed from AppleWin ... reference: Sather's _Understanding the Apple IIe_
// TODO: revisit this if/when attempting to actually sync up VBL/VSYNC to actual device vsync
// 14318181.81...
#define _M14 (157500000.0 / 11.0)
@ -43,6 +42,19 @@
#define CLK_6502 ((_M14 * 65.0) / 912.0)
#define CLK_6502_INT ((unsigned int)CLK_6502)
// HBL & VBL constants
// UtAIIe:3-13 "There are exactly 17030 (65 x 262) 6502 cycles in every television scan of an American Apple"
#define CYCLES_HBL 25
#define CYCLES_VIS_BEGIN CYCLES_HBL
#define CYCLES_VIS 40
#define CYCLES_SCANLINE (CYCLES_HBL + CYCLES_VIS) // 65
#define SCANLINES_VBL 70
#define SCANLINES_MIX (20*8) // 160
#define SCANLINES_VIS (64*3) // 192
#define SCANLINES_VBL_BEGIN SCANLINES_VIS
#define SCANLINES_FRAME (SCANLINES_VBL + SCANLINES_VIS) // 262
#define CYCLES_FRAME (CYCLES_SCANLINE * SCANLINES_FRAME) // 17030
#define CPU_SCALE_SLOWEST 0.25
#define CPU_SCALE_FASTEST_PIVOT 4.0
#define CPU_SCALE_FASTEST (CPU_SCALE_FASTEST_PIVOT + 0.0625)
@ -118,12 +130,21 @@ void cpu_resume(void);
*/
bool cpu_isPaused(void);
// ----------------------------------------------------------------------------
// Video frame and IRQ fine-grained timing.
/*
* checkpoints current cycle count and updates total (for timing-dependent I/O)
* Get current cycles count within this video frame
*/
void timing_checkpoint_cycles(void);
unsigned int timing_currentVideoFrameCycles() CALL_ON_CPU_THREAD;
/*
* Checkpoints current cycle count and updates total (for timing-dependent I/O)
*/
void timing_checkpointCycles(void) CALL_ON_CPU_THREAD;
// ----------------------------------------------------------------------------
// save/restore state
bool timing_saveState(StateHelper_s *helper);