mirror of
https://github.com/mauiaaron/apple2.git
synced 2024-06-26 00:29:27 +00:00
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:
parent
cce2bbb0cc
commit
643a431386
|
@ -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
|
||||
|
|
34
src/timing.c
34
src/timing.c
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue
Block a user