mirror of
https://github.com/mauiaaron/apple2.git
synced 2025-03-21 05:32:04 +00:00
Lite refactor video timing
This commit is contained in:
parent
6ed0100291
commit
aa41c89e68
@ -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++)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
54
src/timing.c
54
src/timing.c
@ -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;
|
||||
|
27
src/timing.h
27
src/timing.h
@ -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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user