diff --git a/src/cpu.S b/src/cpu.S index 174bf088..44e3f399 100644 --- a/src/cpu.S +++ b/src/cpu.S @@ -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 diff --git a/src/cpu.h b/src/cpu.h index 9986903b..4509fe5a 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -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; diff --git a/src/interface.c b/src/interface.c index 5dec2d48..af640a3d 100644 --- a/src/interface.c +++ b/src/interface.c @@ -29,6 +29,7 @@ #include #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, " ", 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) ? " " : " ", TEMPSIZE-1); } - else - if (in_drive) + else if (in_drive) { strncat(temp, (drive == 0) ? " " : " ", 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(); } + diff --git a/src/interface.h b/src/interface.h index fad68e3e..d6011646 100644 --- a/src/interface.h +++ b/src/interface.h @@ -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(); diff --git a/src/keys.c b/src/keys.c index ada92a36..05baf6a1 100644 --- a/src/keys.c +++ b/src/keys.c @@ -20,12 +20,14 @@ #include #include +#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 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); } } diff --git a/src/keys.h b/src/keys.h index 92a30f1f..d2017165 100644 --- a/src/keys.h +++ b/src/keys.h @@ -73,6 +73,7 @@ #define kPGDN 164 #define kEND 165 +extern pthread_mutex_t interface_mutex; #ifdef PC_JOYSTICK extern int js_fd; diff --git a/src/misc.c b/src/misc.c index d4138086..3faa24bc 100644 --- a/src/misc.c +++ b/src/misc.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -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; itag && 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), diff --git a/src/timing.c b/src/timing.c index 7fa1b5ff..3f35b2c9 100644 --- a/src/timing.c +++ b/src/timing.c @@ -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 diff --git a/src/timing.h b/src/timing.h index 9678f149..e0916234 100644 --- a/src/timing.h +++ b/src/timing.h @@ -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(); diff --git a/src/xvideo.c b/src/xvideo.c index 755ef6a2..f06bfe3c 100644 --- a/src/xvideo.c +++ b/src/xvideo.c @@ -739,7 +739,7 @@ void video_init() { } doShm=0; - soundAllowed=0; + //soundAllowed=0; FIXME TODO enforce this ... } }