Support for new timing model

This is part 2 of 2

    * Handles UI changes to support new delay model, added ability to toggle to
      alternate speed scale

    * Code cleanups
This commit is contained in:
Aaron Culliney 2013-10-06 01:31:58 -07:00
parent 41a1f3d598
commit 527c04e41f
12 changed files with 364 additions and 291 deletions

View File

@ -24,7 +24,6 @@
.comm SN(cpu65_vmem),524288,4096
.comm SN(cpu65_flags_encode),256
.comm SN(cpu65_flags_decode),256
.comm SN(cpu65_delay),4
.comm SN(cpu65__opcodes),1024
.comm SN(cpu65__signal),1
.comm SN(cpu65_do_reboot),1

View File

@ -74,7 +74,6 @@ extern struct cpu65_extra cpu65_debug;
extern unsigned char cpu65_flags_encode[256];
extern unsigned char cpu65_flags_decode[256];
extern unsigned int cpu65_delay;
extern int16_t cpu65_cycle_count;
extern int16_t cpu65_cycles_to_execute;
extern uint8_t cpu65_do_reboot;

View File

@ -29,6 +29,7 @@
#include <time.h>
#include "interface.h"
#include "timing.h"
#include "keys.h"
#include "disk.h"
#include "misc.h"
@ -94,7 +95,7 @@ void c_load_interface_font()
/* -------------------------------------------------------------------------
c_interface_print()
------------------------------------------------------------------------- */
void c_interface_print( int x, int y, int cs, char *s )
void c_interface_print( int x, int y, int cs, const char *s )
{
int i;
@ -444,7 +445,7 @@ NEXTDIR:
curpos = entries - 1;
}
for (;; )
for (;;)
{
for (i = 0; i < 17; i++)
{
@ -478,13 +479,11 @@ NEXTDIR:
strncat(temp, " <gz>", TEMPSIZE-1);
}
/* write protected disk in drive? */
else
if ((in_drive) && (disk6.disk[drive].protected))
else if ((in_drive) && (disk6.disk[drive].protected))
{
strncat(temp, (drive == 0) ? " <r1>" : " <r2>", TEMPSIZE-1);
}
else
if (in_drive)
else if (in_drive)
{
strncat(temp, (drive == 0) ? " <rw1>" : " <rw2>", TEMPSIZE-1);
}
@ -517,8 +516,7 @@ NEXTDIR:
{
}
}
else
if (ch == kDOWN) /* Arrow down */
else if (ch == kDOWN) /* Arrow down */
{
if (curpos < entries - 1)
{
@ -528,8 +526,7 @@ NEXTDIR:
{
}
}
else
if (ch == kPGDN) /* Page down */
else if (ch == kPGDN) /* Page down */
{
curpos += 16;
if (curpos > entries - 1)
@ -537,8 +534,7 @@ NEXTDIR:
curpos = entries - 1;
}
}
else
if (ch == kPGUP) /* Page up */
else if (ch == kPGUP) /* Page up */
{
curpos -= 16;
if (curpos < 0)
@ -546,18 +542,15 @@ NEXTDIR:
curpos = 0;
}
}
else
if (ch == kHOME) /* Home */
else if (ch == kHOME) /* Home */
{
curpos = 0;
}
else
if (ch == kEND) /* End */
else if (ch == kEND) /* End */
{
curpos = entries - 1;
}
else
if (ch == kESC) /* ESC */
else if (ch == kESC) /* ESC */
{
for (i = 0; i < entries; i++)
{
@ -568,8 +561,7 @@ NEXTDIR:
c_interface_exit();
return;
}
else
if ((ch == 13) || (toupper(ch) == 'W')) /* Return */
else if ((ch == 13) || (toupper(ch) == 'W')) /* Return */
{
int len, cmpr = 0;
@ -642,8 +634,7 @@ NEXTDIR:
disk_path[len] = '\0';
}
}
else
if (strcmp(".", namelist[curpos]->d_name))
else if (strcmp(".", namelist[curpos]->d_name))
{
snprintf(disk_path + len, DISKSIZE-len, "/%s",
namelist[curpos]->d_name);
@ -679,8 +670,7 @@ NEXTDIR:
continue;
}
}
else
if (!pid) /* child process */
else if (!pid) /* child process */
{ /* privileged mode - gzip in place */
if (execl("/bin/gzip", "/bin/gzip",
"-d", temp, NULL) == -1)
@ -733,8 +723,7 @@ NEXTDIR:
continue;
}
}
else
if (!pid) /* child process */
else if (!pid) /* child process */
{ /* privileged mode - gzip in place */
if (execl("/bin/gzip", "/bin/gzip",
disk6.disk[drive].file_name, NULL) == -1)
@ -790,19 +779,52 @@ NEXTDIR:
c_interface_parameters()
------------------------------------------------------------------------- */
#define NUM_OPTIONS 14
#define SAVE_SETTINGS 12
#define QUIT_EMULATOR 13
#define PATH_OPTION 1
#define CALIBRATE_OPTION 6
typedef enum interface_enum_t {
OPT_CPU = 0,
OPT_ALTCPU,
OPT_PATH,
OPT_MODE,
OPT_COLOR,
OPT_SOUND,
OPT_JOYSTICK,
OPT_CALIBRATE, // (NOP)
OPT_JS_RANGE,
OPT_ORIGIN_X,
OPT_ORIGIN_Y,
OPT_JS_SENSE,
OPT_JS_SAMPLE,
OPT_SAVE,
OPT_QUIT,
NUM_OPTIONS
} interface_enum_t;
static const char *options[] =
{
" CPU% : ", /* 0 */
" ALT CPU% : ", /* 0 */
" Path : ",
" Mode : ",
" Color : ",
" Sound : ",
" Joystick : ", /* 5 */
" Calibrate ",
" JS Range : ",
" Origin X : ",
" Origin Y : ",
" JS Sens. : ", /* 10 */
" JS Sample: ",
" Save Prefs ",
" Quit "
};
void c_interface_parameters()
{
static char screen[24][41] =
{ "||||||||||||||||||||||||||||||||||||||||",
"| Apple II Emulator for Linux |",
"| Originally by |",
"| Alexander Jean-Claude Bottema |",
"| |",
"| Apple // Emulator for *nix |",
"| |",
"||||||||||||||||||||||||||||||||||||||||",
"| |",
"| |",
@ -815,34 +837,19 @@ void c_interface_parameters()
"| |",
"||||||||||||||||||||||||||||||||||||||||",
"| F1 F2: Slot6 Drive A, Drive B |",
"| F4 : Pause Emulation |",
"| F5 : Keyboard Layout |",
"| F9 : Toggle Max Speed |",
"| F4 : Toggle Pause Emulation |",
"| F5 : View Keyboard Layout |",
"| F9 : Toggle Btwn CPU% / ALT CPU% |",
"| F10 : This Menu |",
"||||||||||||||||||||||||||||||||||||||||",
"| Use arrow keys (or Return) to modify |",
"| parameters. (Press ESC to exit menu) |",
"||||||||||||||||||||||||||||||||||||||||" };
static char *options[NUM_OPTIONS] =
{ " Speed : ", /* 0 */
" Path : ",
" Mode : ",
" Color : ",
" Sound : ",
" Joystick : ", /* 5 */
" Calibrate ",
" JS Range : ",
" Origin X : ",
" Origin Y : ",
" JS Sens. : ", /* 10 */
" JS Sample: ",
" Save ",
" Quit " };
int i;
int ch;
static int option = 0;
static interface_enum_t option = OPT_CPU;
static int cur_y = 0, cur_off = 0, cur_x = 0, cur_pos = 0;
int current_mode = apple_mode;
@ -857,7 +864,7 @@ void c_interface_parameters()
c_interface_print( 0, i, 2,screen[ i ] );
}
for (;; )
for (;;)
{
for (i = 0; i < 9; i++)
{
@ -871,64 +878,95 @@ void c_interface_parameters()
switch (i + cur_off)
{
case 0:
snprintf(temp, TEMPSIZE, "%03d",
MAX_APPLE_DELAY + 1 - cpu65_delay);
case OPT_CPU:
if (cpu_scale_factor >= CPU_SCALE_FASTEST)
{
snprintf(temp, TEMPSIZE, "Fastest");
}
else
{
snprintf(temp, TEMPSIZE, "%d%%", (int)(cpu_scale_factor * 100.0));
}
break;
case 1:
case OPT_ALTCPU:
if (cpu_altscale_factor >= CPU_SCALE_FASTEST)
{
snprintf(temp, TEMPSIZE, "Fastest");
}
else
{
snprintf(temp, TEMPSIZE, "%d%%", (int)(cpu_altscale_factor * 100.0));
}
break;
case OPT_PATH:
strncpy(temp, disk_path + cur_pos, 24);
temp[24] = '\0';
break;
case 2:
case OPT_MODE:
sprintf(temp, "%s", (apple_mode == 0) ? "][+ " :
(apple_mode == 1) ? "][+ undocumented" :
"//e ");
break;
case 3:
case OPT_COLOR:
sprintf(temp, "%s", (color_mode == 0) ? "Black/White " :
(color_mode == 1) ? "Lazy Color " :
(color_mode == 2) ? "Color " :
(color_mode == 3) ? "Lazy Interp." :
"Interpolated");
break;
case 4:
case OPT_SOUND:
sprintf(temp, "%s", (sound_mode == 0) ? "Off " :
"PC speaker");
break;
case 5:
case OPT_JOYSTICK:
sprintf(temp, "%s", (joy_mode == JOY_KYBD) ? "Linear " :
(joy_mode == JOY_DIGITAL) ? "Digital " :
(joy_mode == JOY_PCJOY) ? "PC Joystick" :
"Off ");
break;
case 6: /* calibrate joystick */
case OPT_CALIBRATE:
strcpy( temp, "" );
break;
case 7:
case OPT_JS_RANGE:
sprintf(temp, "%02x", joy_range);
break;
case 8:
case OPT_ORIGIN_X:
sprintf(temp, "%02x", joy_center_x);
break;
case 9:
case OPT_ORIGIN_Y:
sprintf(temp, "%02x", joy_center_y);
break;
case 10:
case OPT_JS_SENSE:
sprintf(temp, "%03d%%", joy_step );
break;
case 11:
case OPT_JS_SAMPLE:
#ifdef PC_JOYSTICK
sprintf(temp, "%ld", js_timelimit);
#else
sprintf(temp, "%s", "");
#endif
break;
case SAVE_SETTINGS: /* save settings */
case OPT_SAVE:
strcpy( temp, "" );
break;
case QUIT_EMULATOR: /* quit emulator */
case OPT_QUIT:
strcpy( temp, "" );
break;
default:
break;
}
@ -961,13 +999,13 @@ void c_interface_parameters()
{
if (temp[ j ] == '\0')
{
video_plotchar( 14 + j, 5+i, option==1,' ' );
video_plotchar( 14 + j, 5+i, option==OPT_PATH,' ' );
j++;
break;
}
else
{
video_plotchar( 14 + j, 5+i, option==1,
video_plotchar( 14 + j, 5+i, option==OPT_PATH,
temp[ j ]);
}
@ -993,8 +1031,7 @@ void c_interface_parameters()
{
option--; /* only dec option */
}
else
if (option > 0)
else if (option > 0)
{
option--; /* dec option */
cur_y--; /* and dec y position */
@ -1005,16 +1042,14 @@ void c_interface_parameters()
cur_y = 8; /* wrap to last y position */
}
}
else
if (ch == kDOWN) /* Arrow down */
else if (ch == kDOWN) /* Arrow down */
{
if (cur_y < 8)
{
option++; /* inc option */
cur_y++; /* and inc y position */
}
else
if (option < NUM_OPTIONS-1)
else if (option < NUM_OPTIONS-1)
{
option++; /* only inc option */
}
@ -1023,39 +1058,46 @@ void c_interface_parameters()
cur_y = option = 0; /* wrap both to first */
}
}
else
if (ch == kLEFT) /* Arrow left */
else if (ch == kLEFT) /* Arrow left */
{
switch (option)
{
case 0: /* inc speed */
if (cpu65_delay < MAX_APPLE_DELAY)
case OPT_CPU:
cpu_scale_factor -= (cpu_scale_factor <= 1.0) ? CPU_SCALE_STEP_DIV : CPU_SCALE_STEP;
if (cpu_scale_factor < CPU_SCALE_SLOWEST)
{
cpu65_delay++;
cpu_scale_factor = CPU_SCALE_SLOWEST;
}
break;
case 1: /* path */
case OPT_ALTCPU:
cpu_altscale_factor -= (cpu_altscale_factor <= 1.0) ? CPU_SCALE_STEP_DIV : CPU_SCALE_STEP;
if (cpu_altscale_factor < CPU_SCALE_SLOWEST)
{
cpu_altscale_factor = CPU_SCALE_SLOWEST;
}
break;
case OPT_PATH:
if (cur_x > 0)
{
cur_x--;
}
else
if (cur_pos > 0)
else if (cur_pos > 0)
{
cur_pos--;
}
break;
case 2: /* apple mode */
case OPT_MODE:
apple_mode--;
if (apple_mode < 0)
{
apple_mode = 2;
}
break;
case 3: /* color mode */
case OPT_COLOR:
if (color_mode == 0)
{
color_mode = 4;
@ -1064,9 +1106,9 @@ void c_interface_parameters()
{
--color_mode;
}
break;
case 4: /* sound mode */
case OPT_SOUND:
if (sound_mode == 0)
{
sound_mode = 1;
@ -1075,86 +1117,97 @@ void c_interface_parameters()
{
--sound_mode;
}
break;
case 5: /* joystick mode */
case OPT_JOYSTICK:
#ifdef PC_JOYSTICK
if (joy_mode == 0)
{
joy_mode = 3;
}
#else
if (joy_mode == 0)
{
joy_mode = 2;
}
#endif
else
{
--joy_mode;
}
break;
case 6: /* calibrate */
case OPT_CALIBRATE:
break;
case 7: /* range */
case OPT_JS_RANGE:
if (joy_range > 10)
{
--joy_range;
joy_center_x = joy_range/2;
joy_center_y = joy_range/2;
}
break;
case 8: /* origin x */
case OPT_ORIGIN_X:
if (joy_center_x > 0)
{
joy_center_x--;
}
break;
case 9: /* origin y */
case OPT_ORIGIN_Y:
if (joy_center_y > 0)
{
joy_center_y--;
}
break;
case 10: /* sensitivity */
case OPT_JS_SENSE:
if (joy_step > 1)
{
joy_step--;
}
break;
case 11:
case OPT_JS_SAMPLE:
#ifdef PC_JOYSTICK
if (js_timelimit > 2) /* joystick sample rate */
if (js_timelimit > 2)
{
--js_timelimit;
}
#endif
break;
case SAVE_SETTINGS: /* save settings */
case QUIT_EMULATOR: /* quit emulator */
case OPT_SAVE:
case OPT_QUIT:
break;
default:
break;
}
}
else
if (ch == kRIGHT) /* Arrow right */
else if (ch == kRIGHT) /* Arrow right */
{
switch (option)
{
case 0: /* dec speed */
if (cpu65_delay > 1)
case OPT_CPU:
cpu_scale_factor += (cpu_scale_factor < 1.0) ? CPU_SCALE_STEP_DIV : CPU_SCALE_STEP;
if (cpu_scale_factor >= CPU_SCALE_FASTEST)
{
cpu65_delay--;
cpu_scale_factor = CPU_SCALE_FASTEST;
}
break;
case 1: /* path */
case OPT_ALTCPU:
cpu_altscale_factor += (cpu_altscale_factor < 1.0) ? CPU_SCALE_STEP_DIV : CPU_SCALE_STEP;
if (cpu_altscale_factor >= CPU_SCALE_FASTEST)
{
cpu_altscale_factor = CPU_SCALE_FASTEST;
}
break;
case OPT_PATH:
if (cur_x < 23)
{
if (disk_path[cur_pos + cur_x] != '\0')
@ -1162,102 +1215,104 @@ void c_interface_parameters()
cur_x++;
}
}
else
if (disk_path[cur_pos + cur_x] != '\0')
else if (disk_path[cur_pos + cur_x] != '\0')
{
cur_pos++;
}
break;
case 2: /* apple mode */
case OPT_MODE:
apple_mode++;
if (apple_mode > 2)
{
apple_mode = 0;
}
break;
case 3: /* color mode */
case OPT_COLOR:
color_mode++;
if (color_mode > 4)
{
color_mode = 0;
}
break;
case 4: /* sound mode */
case OPT_SOUND:
sound_mode++;
if (sound_mode > 1)
{
sound_mode = 0;
}
break;
case 5: /* joystick mode */
case OPT_JOYSTICK:
#ifdef PC_JOYSTICK
if (joy_mode == 3)
{
joy_mode = 0;
}
#else
if (joy_mode == 2)
{
joy_mode = 0;
}
#endif
else
{
++joy_mode;
}
break;
case 6: /* calibrate */
case OPT_CALIBRATE:
break;
case 7: /* range */
case OPT_JS_RANGE:
if (joy_range < 256)
{
++joy_range;
joy_center_x = joy_range/2;
joy_center_y = joy_range/2;
}
break;
case 8: /* origin x */
case OPT_ORIGIN_X:
if (joy_center_x < joy_range-1)
{
joy_center_x++;
}
break;
case 9: /* origin y */
case OPT_ORIGIN_Y:
if (joy_center_y < joy_range-1)
{
joy_center_y++;
}
break;
case 10: /* sensitivity */
case OPT_JS_SENSE:
if (joy_step < 100)
{
joy_step++;
}
break;
case 11: /* joystick sample rate */
case OPT_JS_SAMPLE:
#ifdef PC_JOYSTICK
js_timelimit++;
#endif
break;
case SAVE_SETTINGS: /* save settings */
case QUIT_EMULATOR: /* quit emulator */
case OPT_SAVE:
case OPT_QUIT:
break;
default:
break;
}
}
else
if (ch == kESC) /* exit menu */
else if (ch == kESC) /* exit menu */
{
c_initialize_sound();
timing_initialize();
video_set(0); /* redo colors */
#ifdef PC_JOYSTICK
if (joy_mode == JOY_PCJOY)
@ -1285,7 +1340,7 @@ void c_interface_parameters()
else
{
/* got a normal character setting path */
if (ch >= ' ' && ch < 127 && option == PATH_OPTION)
if (ch >= ' ' && ch < 127 && option == OPT_PATH)
{
int i;
@ -1301,16 +1356,14 @@ void c_interface_parameters()
{
cur_x++;
}
else
if (disk_path[cur_pos + cur_x] != '\0')
else if (disk_path[cur_pos + cur_x] != '\0')
{
cur_pos++;
}
}
/* Backspace or delete setting path */
if ((ch == 127 || ch == 8) && (cur_pos + cur_x - 1 >= 0) &&
(option == 1))
if ((ch == 127 || ch == 8) && (cur_pos + cur_x - 1 >= 0) && (option == OPT_PATH))
{
int i;
@ -1323,8 +1376,7 @@ void c_interface_parameters()
{
cur_x--;
}
else
if (cur_pos > 0)
else if (cur_pos > 0)
{
cur_pos--;
}
@ -1332,25 +1384,28 @@ void c_interface_parameters()
#ifdef PC_JOYSTICK
/* calibrate joystick */
if ((ch == 13) && (option == CALIBRATE_OPTION))
if ((ch == 13) && (option == OPT_CALIBRATE))
{
c_calibrate_joystick();
}
#endif
/* save settings */
if ((ch == 13) && (option == SAVE_SETTINGS))
if ((ch == 13) && (option == OPT_SAVE))
{
save_settings();
c_interface_print( 1, 22, 0, " --> Saved. <-- " );
video_sync(0);
c_usleep();
c_interface_print( 0, 22, 2, screen[ 22 ] );
}
/* quit apple II simulator */
if (ch == 13 && option == QUIT_EMULATOR)
if (ch == 13 && option == OPT_QUIT)
{
int ch;
c_interface_print(
1, 22, 0, " Are you sure? (Y/N) " );
c_interface_print( 1, 22, 0, " Are you sure? (Y/N) " );
while ((ch = c_mygetch(1)) == -1)
{
}
@ -1363,14 +1418,12 @@ void c_interface_parameters()
#ifdef PC_JOYSTICK
c_close_joystick();
#endif
printf("Linux! ...and there were much rejoicing! "
"oyeeeeh...\n");
LOG("Linux! ...and there were much rejoicing! oyeeeeh...\n");
video_shutdown();
exit( 0 );
}
c_interface_print( 0, 22, 2, screen[ 22 ] );
}
}
}
@ -1514,3 +1567,4 @@ void c_interface_keyboard_layout()
c_interface_exit();
}

View File

@ -17,7 +17,7 @@
#ifndef A2_INTERFACE_H
#define A2_INTERFACE_H
void c_interface_print( int x, int y, int cs, char *s );
void c_interface_print( int x, int y, int cs, const char *s );
void c_interface_redo_bottom(); /* bit of a HACK? */
void c_load_interface_font();
void c_interface_keyboard_layout();

View File

@ -20,12 +20,14 @@
#include <unistd.h>
#include <linux/keyboard.h>
#include "common.h"
#include "keys.h"
#include "misc.h"
#include "video.h"
#include "interface.h"
#include "cpu.h"
#include "prefs.h"
#include "timing.h"
/* from misc.c */
extern uid_t user, privileged;
@ -40,6 +42,8 @@ unsigned char joy_button0 = 0;
unsigned char joy_button1 = 0;
unsigned char joy_button2 = 0;
pthread_mutex_t interface_mutex = PTHREAD_MUTEX_INITIALIZER;
#ifdef PC_JOYSTICK
#include <linux/joystick.h>
int x_val, y_val;
@ -199,7 +203,6 @@ static int apple_iie_keymap_shift_ctrl[128] =
-1, -1, -1, -1, -1, -1, -1, kF4 /* pause */, /* 112-119 */
-1, -1, -1, -1, -1, -1, -1, -1 }; /* 120-127 */
static unsigned short max_speed = 0;
static char key_pressed[ 256 ];
@ -243,19 +246,28 @@ void c_periodic_update(int dummysig) {
joy_y = joy_center_y;
break;
case kF1:
pthread_mutex_lock(&interface_mutex);
c_interface_select_diskette( 0 );
pthread_mutex_unlock(&interface_mutex);
break;
case kF2:
pthread_mutex_lock(&interface_mutex);
c_interface_select_diskette( 1 );
pthread_mutex_unlock(&interface_mutex);
break;
case kF4:
pthread_mutex_lock(&interface_mutex);
while (c_mygetch(1) == -1)
{
struct timespec ts = { .tv_sec=0, .tv_nsec=1 };
nanosleep(&ts, NULL);
} /*busy loop*/
pthread_mutex_unlock(&interface_mutex);
break;
case kF5:
pthread_mutex_lock(&interface_mutex);
c_interface_keyboard_layout();
pthread_mutex_unlock(&interface_mutex);
break;
case kF7:
cpu65_interrupt(EnterDebugSig);
@ -266,23 +278,15 @@ void c_periodic_update(int dummysig) {
break;
#endif
case kF9:
if (max_speed != 0)
{
cpu65_delay = max_speed, max_speed = 0;
}
else
{
max_speed = cpu65_delay, cpu65_delay = 1;
}
pthread_mutex_lock(&interface_mutex);
timing_toggle_cpu_speed();
pthread_mutex_unlock(&interface_mutex);
break;
case kF10:
if (max_speed != 0)
{
cpu65_delay = max_speed, max_speed = 0;
}
case kF10:
pthread_mutex_lock(&interface_mutex);
c_interface_parameters();
pthread_mutex_unlock(&interface_mutex);
break;
}
}
@ -341,8 +345,7 @@ void c_periodic_update(int dummysig) {
}
#ifdef PC_JOYSTICK
else
if ((joy_mode == JOY_PCJOY) && !(js_fd < 0))
else if ((joy_mode == JOY_PCJOY) && !(js_fd < 0))
{
if (read(js_fd, &js, JS_RETURN) == -1)
{
@ -387,8 +390,7 @@ void c_periodic_update(int dummysig) {
}
}
#endif
else
if (joy_mode == JOY_OFF)
else if (joy_mode == JOY_OFF)
{
joy_x = joy_y = 256;
}
@ -424,20 +426,17 @@ void c_read_raw_key(int scancode, int pressed) {
{
keymap = apple_iie_keymap_shift_ctrl;
}
else
if (key_pressed[ SCODE_L_CTRL ] || /* ctrl */
else if (key_pressed[ SCODE_L_CTRL ] || /* ctrl */
key_pressed[ SCODE_R_CTRL ])
{
keymap = apple_iie_keymap_ctrl;
}
else
if (key_pressed[ SCODE_L_SHIFT ] || /* shift */
else if (key_pressed[ SCODE_L_SHIFT ] || /* shift */
key_pressed[ SCODE_R_SHIFT ])
{
keymap = apple_iie_keymap_shifted;
}
else
if (caps_lock) /* caps lock */
else if (caps_lock) /* caps lock */
{
keymap = apple_iie_keymap_caps;
}
@ -453,8 +452,7 @@ void c_read_raw_key(int scancode, int pressed) {
{
keymap = apple_ii_keymap_ctrl;
}
else
if (key_pressed[ SCODE_L_SHIFT ] ||
else if (key_pressed[ SCODE_L_SHIFT ] ||
key_pressed[ SCODE_R_SHIFT ])
{
keymap = apple_ii_keymap_shifted;
@ -515,6 +513,8 @@ int c_mygetch(int block)
{
while (next_key == -1)
{
static struct timespec ts = { .tv_sec=0, .tv_nsec=33333333 };
nanosleep(&ts, NULL); // 30Hz framerate
video_sync(1);
}
}

View File

@ -73,6 +73,7 @@
#define kPGDN 164
#define kEND 165
extern pthread_mutex_t interface_mutex;
#ifdef PC_JOYSTICK
extern int js_fd;

View File

@ -20,7 +20,6 @@
#include <stdlib.h>
#include <signal.h>
#include <time.h>
#include <pthread.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/io.h>
@ -35,6 +34,8 @@
#include "glue.h"
#include "prefs.h"
#include "timing.h"
#include "speaker.h"
#include "soundcore.h"
/* ----------------------------------
internal apple2 variables
@ -43,9 +44,6 @@
static unsigned char apple_ii_rom[12288];
static unsigned char apple_iie_rom[32768]; /* //e */
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
/* in debugger.c */
extern int breakpoints[];
extern int watchpoints[];
@ -600,17 +598,22 @@ void c_initialize_apple_ii_memory()
}
/* -------------------------------------------------------------------------
void c_initialize_sound()
void c_initialize_sound_hooks()
------------------------------------------------------------------------- */
void c_initialize_sound()
void c_initialize_sound_hooks()
{
int i;
for (i = 0xC030; i < 0xC040; i++)
for (int i = 0xC030; i < 0xC040; i++)
{
cpu65_vmem[i].r = cpu65_vmem[i].w =
(sound_mode && soundAllowed) ? read_speaker_toggle_pc : ram_nop;
cpu65_vmem[i].r = cpu65_vmem[i].w = (sound_mode) ? read_speaker_toggle_pc : ram_nop;
}
}
void c_disable_sound_hooks()
{
for (int i = 0xC030; i < 0xC040; i++)
{
cpu65_vmem[i].r = ram_nop;
}
}
@ -644,7 +647,7 @@ void c_initialize_vm() {
c_initialize_font(); /* font already read in */
c_initialize_apple_ii_memory(); /* read in rom memory */
c_initialize_tables(); /* read/write memory jump tables */
c_initialize_sound(); /* sound system */
c_initialize_sound_hooks(); /* sound system */
c_init_6(); /* drive ][, slot 6 */
c_initialize_iie_switches(); /* set the //e softswitches */
@ -658,10 +661,12 @@ void c_initialize_vm() {
void c_initialize_firsttime()
------------------------------------------------------------------------- */
static void reinitialize(void)
void reinitialize(void)
{
int i;
cpu65_do_reboot=1;
/* reset the watchpoints and breakpoints */
for (i=0; i<MAX_BRKPTS; i++)
{
@ -695,29 +700,22 @@ static void reinitialize(void)
cpu65_set(CPU65_NMOS|CPU65_FAULT);
}
timing_initialize();
}
static void c_initialize_firsttime()
{
/* get IO permission for speaker port. */
if (/*ioperm(0x42, 1, 1) ||*/ ioperm(0x61, 1, 1))
{
perror("ioperm");
printf("cannot get port access to PC speaker.\n");
printf("sound will not be used.\n");
soundAllowed=0;
}
else
{
soundAllowed=1;
}
/* read in system files and calculate system defaults */
c_load_interface_font();
/* initialize the video system */
video_init();
// TODO FIXME : sound system never released ...
DSInit();
SpkrInitialize();
//MB_Initialize();
reinitialize();
}
@ -729,28 +727,17 @@ void c_read_random() {
random_value = (unsigned char)rand_r(&seed);
}
static void cpu_thread(void *dummyptr) {
do
{
LOG("cpu_thread : entering cpu65_run()...");
cpu65_run();
reinitialize();
} while (1);
}
static void main_thread(void *dummyptr) {
struct timespec abstime = { .tv_sec=0, .tv_nsec=8333333 }; // 120Hz
struct timespec sleeptime = { .tv_sec=0, .tv_nsec=8333333 }; // 120Hz
do
{
// sleep waiting for the cpu thread to ping us to render
pthread_mutex_lock(&mutex);
pthread_cond_timedwait(&cond, &mutex, &abstime);
pthread_mutex_unlock(&mutex);
nanosleep(&sleeptime, NULL);
c_periodic_update(0);
} while (1);
}
extern void cpu_thread(void *dummyptr);
int main(int sargc, char *sargv[])
{
argc = sargc;
@ -758,12 +745,11 @@ int main(int sargc, char *sargv[])
load_settings(); /* user prefs */
c_initialize_firsttime(); /* init svga graphics and vm */
timing_initialize();
// spin off cpu thread
pthread_t thread1;
pthread_create(&thread1, NULL, (void *) &cpu_thread, (void *)NULL);
// enter main render thread
// continue with main render thread
main_thread(NULL);
}

View File

@ -50,7 +50,6 @@ unsigned char apple_ii_64k[2][65536]; /* 128k memory */
unsigned char language_card[2][8192], language_banks[2][8192];
/* misc stuff */
int soundAllowed;
unsigned char random_value;
/* global ref to commandline args */
@ -124,10 +123,12 @@ extern int softswitches;
misc.c functions
------------------------------------------------------------------------- */
void c_initialize_sound();
void c_initialize_sound_hooks();
void c_disable_sound_hooks();
void c_initialize_font();
void c_initialize_vm();
void c_read_random();
void reinitialize();
/* virtual memory compacter */

View File

@ -25,10 +25,12 @@
#include "prefs.h"
#include "keys.h"
#include "interface.h"
#include "timing.h"
#include "cpu.h"
#define PRM_NONE 0
#define PRM_SPEED 1
#define PRM_ALTSPEED 101
#define PRM_MODE 2
#define PRM_DISK_PATH 3
#define PRM_HIRES_COLOR 4
@ -76,6 +78,7 @@ struct match_table
static const struct match_table prefs_table[] =
{
{ "speed", PRM_SPEED },
{ "altspeed", PRM_ALTSPEED },
{ "mode", PRM_MODE },
{ "path", PRM_DISK_PATH },
{ "disk path", PRM_DISK_PATH },
@ -143,8 +146,7 @@ static const struct match_table joy_input_table[] =
/* Find the number assigned to KEYWORD in a match table PARADIGM. If no match,
* then the value associated with the terminating entry is used as a
* default. */
static int
match(const struct match_table *paradigm, const char *keyword)
static int match(const struct match_table *paradigm, const char *keyword)
{
while (paradigm->tag && strcasecmp(paradigm->tag, keyword))
{
@ -173,8 +175,7 @@ static const char *reverse_match(const struct match_table *paradigm, int key)
/* Eat leading and trailing whitespace of string X. The old string is
* overwritten and a new pointer is returned.
*/
static char *
clean_string(char *x)
static char * clean_string(char *x)
{
size_t y;
@ -196,8 +197,7 @@ clean_string(char *x)
}
/* Load the configuration. Must be called *once* at start. */
void
load_settings(void)
void load_settings(void)
{
/* set system defaults before user defaults. */
strcpy(disk_path, "./disks");
@ -246,30 +246,35 @@ load_settings(void)
parameter = clean_string(parameter);
argument = clean_string(argument);
switch (match(prefs_table, parameter))
int main_match = match(prefs_table, parameter);
switch (main_match)
{
case PRM_NONE:
fprintf(stderr, "Unrecognized config parameter `%s'", parameter);
break;
case PRM_SPEED:
case PRM_ALTSPEED:
{
int x;
x = strtol(argument, 0, 0);
if (x < 0)
double x = strtod(argument, NULL);
if (x > CPU_SCALE_FASTEST)
{
x = 0;
x = CPU_SCALE_FASTEST;
}
cpu65_delay = MAX_APPLE_DELAY - x + 1;
if (cpu65_delay < 1)
else if (x < CPU_SCALE_SLOWEST)
{
cpu65_delay = 1;
x = CPU_SCALE_SLOWEST;
}
if (main_match == PRM_SPEED)
{
cpu_scale_factor = x;
}
else
{
cpu_altscale_factor = x;
}
break;
}
break;
case PRM_MODE:
apple_mode = match(modes_table, argument);
@ -437,7 +442,8 @@ save_settings(void)
}
fprintf(config_file,
"speed = %d\n"
"speed = %0.2lf\n"
"altspeed = %0.2lf\n"
"mode = %s\n"
"disk path = %s\n"
"color = %s\n"
@ -448,7 +454,8 @@ save_settings(void)
"origin_y = %d\n"
"sensitivity = %d%%\n"
"system path = %s\n",
MAX_APPLE_DELAY + 1 - cpu65_delay,
cpu_scale_factor,
cpu_altscale_factor,
reverse_match(modes_table, apple_mode),
disk_path,
reverse_match(color_table, color_mode),

View File

@ -30,7 +30,10 @@ double g_fCurrentCLK6502 = CLK_6502;
bool g_bFullSpeed = false; // HACK TODO FIXME : prolly shouldn't be global anymore -- don't think it's necessary for speaker/soundcore/etc anymore ...
uint64_t g_nCumulativeCycles = 0; // cumulative cycles since emulator (re)start
int g_nCpuCyclesFeedback = 0;
static bool alt_speed_enabled = false;
double cpu_scale_factor = 1.0;
double cpu_altscale_factor = 1.0;
static unsigned int g_nCyclesExecuted; // # of cycles executed up to last IO access
@ -83,41 +86,15 @@ static inline struct timespec timespec_add(struct timespec start, unsigned long
return start;
}
bool timing_is_fullspeed()
static void _timing_initialize(double scale)
{
return g_bFullSpeed;
}
void timing_enable_fullspeed()
{
if (!g_bFullSpeed)
{
g_bFullSpeed = true;
c_disable_sound_hooks();
timing_initialize();
}
}
void timing_enable_regular_speed()
{
if (g_bFullSpeed)
{
g_bFullSpeed = false;
c_initialize_sound_hooks();
timing_initialize();
}
}
void timing_initialize()
{
if (g_bFullSpeed)
{
LOG("timing_initialize() emulation at fullspeed ...");
return;
}
g_fCurrentCLK6502 = CLK_6502 * cpu_scale_factor;
g_fCurrentCLK6502 = CLK_6502 * scale;
// this is extracted out of SetClksPerSpkrSample -- speaker.c
g_fClksPerSpkrSample = (double) (UINT) (g_fCurrentCLK6502 / (double)SPKR_SAMPLE_RATE);
SpkrReinitialize();
@ -125,6 +102,58 @@ void timing_initialize()
LOG("timing_initialize() ... ClockRate:%0.2lf ClockCyclesPerSpeakerSample:%0.2lf", g_fCurrentCLK6502, g_fClksPerSpkrSample);
}
static void _switch_to_fullspeed(double scale)
{
if (!g_bFullSpeed)
{
g_bFullSpeed = true;
c_disable_sound_hooks();
}
}
static void _switch_to_regular_speed(double scale)
{
if (g_bFullSpeed)
{
g_bFullSpeed = false;
c_initialize_sound_hooks();
}
_timing_initialize(scale);
}
void timing_toggle_cpu_speed()
{
alt_speed_enabled = !alt_speed_enabled;
if (alt_speed_enabled)
{
if (cpu_altscale_factor >= CPU_SCALE_FASTEST)
{
_switch_to_fullspeed(cpu_altscale_factor);
}
else
{
_switch_to_regular_speed(cpu_altscale_factor);
}
}
else
{
if (cpu_scale_factor >= CPU_SCALE_FASTEST)
{
_switch_to_fullspeed(cpu_scale_factor);
}
else
{
_switch_to_regular_speed(cpu_scale_factor);
}
}
}
void timing_initialize()
{
_timing_initialize(cpu_scale_factor);
}
void cpu_thread(void *dummyptr) {
struct timespec deltat;
struct timespec t0; // the target timer

View File

@ -32,7 +32,7 @@
#define CLK_6502 ((_M14 * 65.0) / 912.0)
#define CPU_SCALE_SLOWEST 0.25
#define CPU_SCALE_FASTEST 4.005
#define CPU_SCALE_FASTEST 4.05
#define CPU_SCALE_STEP_DIV 0.01
#define CPU_SCALE_STEP 0.05
@ -43,14 +43,11 @@ extern bool g_bFullSpeed;
extern uint64_t g_nCumulativeCycles;
extern int g_nCpuCyclesFeedback;
extern double cpu_scale_factor;
extern double cpu_altscale_factor;
struct timespec timespec_diff(struct timespec start, struct timespec end, bool *negative);
bool timing_is_fullspeed();
void timing_enable_fullspeed();
void timing_enable_regular_speed();
void timing_toggle_cpu_speed();
void timing_initialize();

View File

@ -739,7 +739,7 @@ void video_init() {
}
doShm=0;
soundAllowed=0;
//soundAllowed=0; FIXME TODO enforce this ...
}
}