mirror of
https://github.com/mauiaaron/apple2.git
synced 2025-01-10 23:29:43 +00:00
we no longer use timers with setitimer and SIGVTALRM, that's so nineties...
instead spin off a cpu_thread and have it ping the main render thread as needed
This commit is contained in:
parent
c51018a2bb
commit
18c3f5f698
@ -352,9 +352,7 @@ void c_periodic_update(int dummysig) {
|
||||
*/
|
||||
void enter_debugger(void)
|
||||
{
|
||||
setitimer(ITIMER_VIRTUAL,&timer_off,0);
|
||||
c_do_debugging();
|
||||
setitimer(ITIMER_VIRTUAL,&timer_on,0);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
|
@ -73,8 +73,6 @@
|
||||
#define kPGDN 164
|
||||
#define kEND 165
|
||||
|
||||
#define TIMER_DELAY 30000L
|
||||
|
||||
|
||||
#ifdef PC_JOYSTICK
|
||||
extern int js_fd;
|
||||
|
54
src/misc.c
54
src/misc.c
@ -19,6 +19,8 @@
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/io.h>
|
||||
@ -32,9 +34,7 @@
|
||||
#include "cpu.h"
|
||||
#include "glue.h"
|
||||
#include "prefs.h"
|
||||
|
||||
const struct itimerval timer_off = {{0,0},{0,0}};
|
||||
const struct itimerval timer_on = {{0,TIMER_DELAY},{0,TIMER_DELAY}};
|
||||
#include "timing.h"
|
||||
|
||||
/* ----------------------------------
|
||||
internal apple2 variables
|
||||
@ -45,6 +45,9 @@ static unsigned char apple_ii_rom[12288];
|
||||
static unsigned char apple_iie_rom[32768]; /* //e */
|
||||
#endif
|
||||
|
||||
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
|
||||
|
||||
/* in debugger.c */
|
||||
extern int breakpoints[];
|
||||
extern int watchpoints[];
|
||||
@ -704,10 +707,6 @@ static void c_initialize_firsttime()
|
||||
/* initialize the video system */
|
||||
video_init();
|
||||
|
||||
/* Enable periodic updates */
|
||||
signal(SIGVTALRM,c_periodic_update);
|
||||
setitimer(ITIMER_VIRTUAL,&timer_on,0);
|
||||
|
||||
reinitialize();
|
||||
}
|
||||
|
||||
@ -715,29 +714,38 @@ void c_read_random() {
|
||||
random_value = (unsigned char)(rand() >> 8);
|
||||
}
|
||||
|
||||
static void cpu_thread (void *dummyptr) {
|
||||
|
||||
do {
|
||||
cpu65_run();
|
||||
reinitialize();
|
||||
} while (1);
|
||||
}
|
||||
|
||||
static void main_thread (void *dummyptr) {
|
||||
do {
|
||||
// sleep waiting for the cpu thread to ping us that it's sleeping...
|
||||
pthread_mutex_lock(&mutex);
|
||||
pthread_cond_wait(&cond, &mutex);
|
||||
pthread_mutex_unlock(&mutex);
|
||||
|
||||
c_periodic_update(0);
|
||||
} while (1);
|
||||
}
|
||||
|
||||
int main(int sargc, char *sargv[])
|
||||
{
|
||||
int i;
|
||||
|
||||
argc = sargc;
|
||||
argv = sargv;
|
||||
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
/*
|
||||
if (strcmp(argv[i], "-vga") == 0)
|
||||
force_vga_mode = 1;
|
||||
*/
|
||||
}
|
||||
|
||||
load_settings(); /* user prefs */
|
||||
c_initialize_firsttime(); /* init svga graphics and vm */
|
||||
timing_initialize();
|
||||
|
||||
for (;;) {
|
||||
/* execute the emulator */
|
||||
cpu65_run();
|
||||
// spin off cpu thread
|
||||
pthread_t thread1;
|
||||
pthread_create(&thread1, NULL, (void *) &cpu_thread, (void *)NULL);
|
||||
|
||||
reinitialize();
|
||||
}
|
||||
/* never reached */
|
||||
// enter main render thread
|
||||
main_thread(NULL);
|
||||
}
|
||||
|
@ -39,8 +39,6 @@
|
||||
#define SW_IOUDIS 0xC07E
|
||||
#endif
|
||||
|
||||
extern const struct itimerval timer_on,timer_off;
|
||||
|
||||
/* Text characters */
|
||||
extern const unsigned char ucase_glyphs[0x200];
|
||||
extern const unsigned char lcase_glyphs[0x100];
|
||||
|
22
src/timing.c
22
src/timing.c
@ -15,8 +15,9 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#define DEFAULT_SLEEP 60
|
||||
#define DEFAULT_SLEEP 120
|
||||
|
||||
static unsigned int sleep_hz = DEFAULT_SLEEP; // sleep intervals per sec
|
||||
static unsigned long cpu_target_hz = APPLE2_HZ; // target clock speed
|
||||
@ -28,6 +29,9 @@ static unsigned long cycle=0;
|
||||
static long sleep_adjust=0;
|
||||
static long sleep_adjust_inc=0;
|
||||
|
||||
extern pthread_mutex_t mutex;
|
||||
extern pthread_cond_t cond;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// assuming end > start, returns end - start
|
||||
@ -66,16 +70,30 @@ void timing_set_sleep_hz (unsigned int hz) {
|
||||
/*
|
||||
* Throttles the 65c02 CPU down to a target frequency of X.
|
||||
* Currently set to target the Apple //e @ 1.02MHz
|
||||
*
|
||||
* This is called from cpu65_run() on the cpu-thread
|
||||
*/
|
||||
void timing_throttle () {
|
||||
++cycle;
|
||||
|
||||
static time_t severe_lag=0;
|
||||
|
||||
if ((cycle%cycles_interval) == 0) {
|
||||
|
||||
// wake render thread as we go to sleep
|
||||
pthread_mutex_lock(&mutex);
|
||||
pthread_cond_signal(&cond);
|
||||
pthread_mutex_unlock(&mutex);
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &tj);
|
||||
deltat = timespec_diff(ti, tj);
|
||||
ti=tj;
|
||||
if (deltat.tv_sec != 0) {
|
||||
// severely lagging ...
|
||||
// severely lagging, don't bother sleeping ...
|
||||
if (severe_lag < time(NULL)) {
|
||||
severe_lag = time(NULL)+2;
|
||||
fprintf(stderr, "Severe lag detected...\n");
|
||||
}
|
||||
} else {
|
||||
deltat.tv_nsec = processing_interval - deltat.tv_nsec + sleep_adjust_inc;
|
||||
nanosleep(&deltat, NULL); // NOTE: spec says will return right away if deltat.tv_nsec value < 0 ...
|
||||
|
Loading…
x
Reference in New Issue
Block a user