first cut at auto fast-loading of disk images

- automatically adjusts cpu timing to fastest if drive motor accessed recently and no audio/video
    - TODO: audio output clipping issue when (un)pausing audio outpu
This commit is contained in:
Aaron Culliney 2015-01-11 12:27:39 -08:00
parent cce2bbb0cc
commit 643a431386
5 changed files with 57 additions and 4 deletions

View File

@ -53,6 +53,8 @@ static uint8_t video__int_font[3][0x4000];
int video__current_page; // current visual page
int video__strictcolors = 1;// refactor : should be static
extern volatile bool _vid_dirty;
// Video constants -- sourced from AppleWin
static const bool bVideoScannerNTSC = true;
static const int kHBurstClock = 53; // clock when Color Burst starts
@ -571,6 +573,7 @@ static inline void _plot_lores(uint8_t **d, const uint32_t val) {
#ifdef INTERFACE_CLASSIC
void video_plotchar( int x, int y, int scheme, uint8_t c ) {
_vid_dirty = true;
uint8_t *d;
uint8_t *s;
@ -653,11 +656,13 @@ static inline void _plot_character(const unsigned int font_off, uint8_t *fb_ptr)
static inline void _plot_character0(uint16_t ea, uint8_t b)
{
_vid_dirty = (video__current_page == 0);
_plot_character(b<<7/* *128 */, video__fb1+video__screen_addresses[ea-0x0400]);
}
static inline void _plot_character1(uint16_t ea, uint8_t b)
{
_vid_dirty = (video__current_page == 1);
_plot_character(b<<7/* *128 */, video__fb2+video__screen_addresses[ea-0x0800]);
}
@ -676,6 +681,7 @@ static inline void _plot_80character(const unsigned int font_off, uint8_t *fb_pt
// FIXME TODO NOTE : dup'ing work here?
static inline void _plot_80character0(uint16_t ea, uint8_t b)
{
_vid_dirty = (video__current_page == 0);
b = apple_ii_64k[1][ea];
_plot_80character(b<<6/* *64 */, video__fb1+video__screen_addresses[ea-0x0400]);
b = apple_ii_64k[0][ea];
@ -684,6 +690,7 @@ static inline void _plot_80character0(uint16_t ea, uint8_t b)
static inline void _plot_80character1(uint16_t ea, uint8_t b)
{
_vid_dirty = (video__current_page == 1);
b = apple_ii_64k[1][ea];
_plot_80character(b<<6/* *64 */, video__fb2+video__screen_addresses[ea-0x0800]);
b = apple_ii_64k[0][ea];
@ -718,11 +725,13 @@ static inline void _plot_block(const uint32_t val, uint8_t *fb_ptr) {
/* plot lores block first page */
static inline void _plot_block0(uint16_t ea, uint8_t b)
{
_vid_dirty = (video__current_page == 0);
_plot_block(b, video__fb1+video__screen_addresses[ea-0x0400]);
}
static inline void _plot_block1(uint16_t ea, uint8_t b)
{
_vid_dirty = (video__current_page == 1);
_plot_block(b, video__fb2+video__screen_addresses[ea-0x0800]);
}
@ -803,6 +812,7 @@ static inline void _plot_dhires_pixels(uint8_t idx, uint8_t *fb_ptr) {
// PlotDHires
static inline void _plot_dhires(uint16_t base, uint16_t ea, uint8_t *fb_base) {
_vid_dirty = true;
ea &= ~0x1;
uint16_t memoff = ea - base;
@ -927,6 +937,7 @@ static inline void _plot_hires_pixels(uint8_t *dst, const uint8_t *src) {
// PlotByte
static inline void _plot_hires(uint16_t ea, uint8_t b, bool is_even, uint8_t *fb_ptr) {
uint8_t _buf[DYNAMIC_SZ] = { 0 };
uint8_t *color_buf = (uint8_t *)_buf; // <--- work around for -Wstrict-aliasing
uint8_t *apple2_vmem = (uint8_t *)apple_ii_64k[0];
@ -1025,8 +1036,10 @@ static inline void _draw_hires_graphics(uint16_t ea, uint8_t b, bool is_even, ui
uint8_t *fb_base = NULL;
if (page) {
off -= 0x2000;
_vid_dirty = (video__current_page == 1);
fb_base = video__fb2;
} else {
_vid_dirty = (video__current_page == 0);
fb_base = video__fb1;
}
_plot_hires(ea, b, is_even, fb_base+video__screen_addresses[off]);
@ -1080,6 +1093,10 @@ GLUE_C_WRITE(video__write_2e_odd1_mixed)
_draw_hires_graphics(ea, b, /*even*/false, 1, (SS_TEXT|SS_MIXED));
}
bool video_dirty(void) {
return _vid_dirty;
}
void video_redraw(void) {
// temporarily reset softswitches

View File

@ -47,6 +47,7 @@ static bool alt_speed_enabled = false;
double cpu_scale_factor = 1.0;
double cpu_altscale_factor = 1.0;
bool auto_adjust_speed = true;
int gc_cycles_timer_0 = 0;
int gc_cycles_timer_1 = 0;
@ -54,7 +55,7 @@ int gc_cycles_timer_1 = 0;
volatile uint8_t emul_reinitialize = 0;
pthread_t cpu_thread_id = 0;
static unsigned int g_nCyclesExecuted; // # of cycles executed up to last IO access
static unsigned int g_nCyclesExecuted = 0; // # of cycles executed up to last IO access
// -----------------------------------------------------------------------------
@ -245,21 +246,24 @@ void *cpu_thread(void *dummyptr) {
#if DEBUG_TIMING
dbg_cycles_executed += cpu65_cycle_count;
#endif
#ifdef AUDIO_ENABLED
unsigned int uActualCyclesExecuted = cpu65_cycle_count;
g_dwCyclesThisFrame += uActualCyclesExecuted;
#ifdef AUDIO_ENABLED
MB_UpdateCycles(uActualCyclesExecuted); // Update 6522s (NB. Do this before updating g_nCumulativeCycles below)
#endif
// N.B.: IO calls that depend on accurate timing will update g_nCyclesExecuted
const unsigned int nRemainingCycles = uActualCyclesExecuted - g_nCyclesExecuted;
const int nRemainingCycles = uActualCyclesExecuted - g_nCyclesExecuted;
assert(nRemainingCycles >= 0);
g_nCumulativeCycles += nRemainingCycles;
if (!g_bFullSpeed)
{
#ifdef AUDIO_ENABLED
SpkrUpdate(uActualCyclesExecuted); // play audio
}
#endif
}
if (g_dwCyclesThisFrame >= dwClksPerFrame)
{
@ -274,6 +278,28 @@ void *cpu_thread(void *dummyptr) {
pthread_mutex_unlock(&interface_mutex);
// -UNLOCK--------------------------------------------------------------------------------------- SAMPLE tj
if (auto_adjust_speed) {
deltat = timespec_diff(disk6.motor_time, tj, &negative);
assert(!negative);
if (!g_bFullSpeed &&
#ifdef AUDIO_ENABLED
!Spkr_IsActive() &&
#endif
!video_dirty() && (!disk6.motor_off && (deltat.tv_sec || deltat.tv_nsec > DISK_MOTOR_QUIET_NSECS)) )
{
TIMING_LOG("auto switching to full speed");
_switch_to_fullspeed();
} else if (g_bFullSpeed && (
#ifdef AUDIO_ENABLED
Spkr_IsActive() ||
#endif
video_dirty() || (disk6.motor_off && (deltat.tv_sec || deltat.tv_nsec > DISK_MOTOR_QUIET_NSECS))) )
{
TIMING_LOG("auto switching to regular speed");
_switch_to_regular_speed(alt_speed_enabled ? cpu_altscale_factor : cpu_scale_factor);
}
}
if (!g_bFullSpeed) {
deltat = timespec_diff(ti, tj, &negative);
assert(!negative);

View File

@ -45,6 +45,7 @@ extern int g_nCpuCyclesFeedback;
extern double cpu_scale_factor;
extern double cpu_altscale_factor;
extern bool auto_adjust_speed;
extern pthread_t cpu_thread_id;

View File

@ -34,6 +34,8 @@ enum {
bool safe_to_do_opengl_logging = false;
volatile bool _vid_dirty = true;
static int windowWidth = SCANWIDTH*1.5;
static int windowHeight = SCANHEIGHT*1.5;
@ -649,6 +651,8 @@ static void gldriver_render(void) {
// Draw the CRT object
glDrawElements(GL_TRIANGLES, crtNumElements, crtElementType, 0);
_vid_dirty = false;
#if USE_GLUT
glutSwapBuffers();
#endif

View File

@ -116,6 +116,11 @@ void video_plotchar(int row, int col, int color, uint8_t code);
*/
const uint8_t * const video_current_framebuffer();
/*
* True if anything changed in framebuffer and not yet drawn
*/
bool video_dirty(void);
/*
* VBL routines
*/