exit only from main.c; inline emulate into main

This commit is contained in:
Gwenhael Le Moine 2024-04-24 16:06:24 +02:00
parent ac6dcb93e7
commit 247d0cc133
No known key found for this signature in database
GPG key ID: FDFE3669426707A7
12 changed files with 174 additions and 139 deletions

View file

@ -16,8 +16,6 @@
#define MAX_ARGS 16 #define MAX_ARGS 16
#define BREAKPOINT_HIT 4
#define TAB_SKIP 8 #define TAB_SKIP 8
/* /*
@ -72,16 +70,11 @@
#define UM_PRE 0x10b7c /* Unit Operator prefix */ #define UM_PRE 0x10b7c /* Unit Operator prefix */
#define UM_END 0x10b86 /* Unit Operator _ */ #define UM_END 0x10b86 /* Unit Operator _ */
/*
* exec_flags values
*/
#define EXEC_BKPT 1
int enter_debugger = 0; int enter_debugger = 0;
bool in_debugger = false; bool in_debugger = false;
int exec_flags = 0; int exec_flags = 0;
static int continue_flag; static bool continue_flag;
static char instr[ 100 ]; static char instr[ 100 ];
/* /*
@ -95,14 +88,6 @@ static char instr[ 100 ];
#define DSKTOP_GX 0x806f8 #define DSKTOP_GX 0x806f8
#define DSKBOT_GX 0x806fd #define DSKBOT_GX 0x806fd
/*
* Breakpoint related stuff
*/
#define BP_EXEC 1
#define BP_READ 2
#define BP_WRITE 4
#define BP_RANGE 8
#define MAX_BREAKPOINTS 32 #define MAX_BREAKPOINTS 32
int num_bkpts; int num_bkpts;
@ -3207,7 +3192,7 @@ cmd_tbl[] = {
{0, 0, 0 } {0, 0, 0 }
}; };
static int check_breakpoint( int type, word_20 addr ) int check_breakpoint( int type, word_20 addr )
{ {
struct breakpoint* bp; struct breakpoint* bp;
int i, n; int i, n;
@ -3441,7 +3426,7 @@ static void cmd_break( int argc, char** argv )
} }
} }
static void cmd_continue( int argc, char** argv ) { continue_flag = 1; } static void cmd_continue( int argc, char** argv ) { continue_flag = true; }
static void cmd_delete( int argc, char** argv ) static void cmd_delete( int argc, char** argv )
{ {
@ -3495,14 +3480,6 @@ static void cmd_delete( int argc, char** argv )
} }
} }
static void cmd_exit( int argc, char** argv )
{
if ( confirm( "Exit the emulator WITHOUT saving its state?" ) ) {
printf( "Exit.\n" );
exit( 0 );
}
}
static void cmd_go( int argc, char** argv ) static void cmd_go( int argc, char** argv )
{ {
word_20 addr; word_20 addr;
@ -3590,12 +3567,23 @@ static void cmd_mode( int argc, char** argv )
} }
} }
static void cmd_exit( int argc, char** argv )
{
if ( confirm( "Exit the emulator WITHOUT saving its state?" ) ) {
printf( "Exit.\n" );
save_before_exit = false;
please_exit = true;
}
}
static void cmd_quit( int argc, char** argv ) static void cmd_quit( int argc, char** argv )
{ {
if ( confirm( "Quit the emulator and save its state?" ) ) { if ( confirm( "Quit the emulator and save its state?" ) ) {
printf( "Exit.\n" ); printf( "Exit.\n" );
exit_emulator();
exit( 0 ); save_before_exit = true;
please_exit = true;
} }
} }
@ -4086,8 +4074,7 @@ int debug( void )
if ( config.verbose ) if ( config.verbose )
printf( "usnterrupt (SIGINT) ignored\n" ); printf( "usnterrupt (SIGINT) ignored\n" );
exit_emulator(); please_exit = true;
exit( 1 );
if ( enter_debugger & BREAKPOINT_HIT ) if ( enter_debugger & BREAKPOINT_HIT )
if ( config.verbose ) if ( config.verbose )
@ -4114,7 +4101,7 @@ int debug( void )
stop_timer( RUN_TIMER ); stop_timer( RUN_TIMER );
start_timer( IDLE_TIMER ); start_timer( IDLE_TIMER );
continue_flag = 0; continue_flag = false;
if ( enter_debugger & ILLEGAL_INSTRUCTION ) { if ( enter_debugger & ILLEGAL_INSTRUCTION ) {
printf( "ILLEGAL INSTRUCTION at %.5lX : %s\n", saturn.PC, str_nibbles( saturn.PC, 16 ) ); printf( "ILLEGAL INSTRUCTION at %.5lX : %s\n", saturn.PC, str_nibbles( saturn.PC, 16 ) );
@ -4136,10 +4123,10 @@ int debug( void )
/* /*
* read a command * read a command
*/ */
rl = readline( "x48-debug> " ); rl = readline( "x48ng-debug> " );
if ( rl == ( char* )0 ) { if ( rl == ( char* )0 ) {
continue_flag = 1; continue_flag = true;
continue; continue;
} }
if ( *rl == '\0' ) { if ( *rl == '\0' ) {
@ -4198,7 +4185,7 @@ int debug( void )
} }
in_debugger = false; in_debugger = false;
} while ( !continue_flag ); } while ( !continue_flag && !please_exit );
/* /*
* adjust the hp48's timers * adjust the hp48's timers
@ -4241,20 +4228,3 @@ int debug( void )
return 0; return 0;
} }
void emulate_debug( void )
{
do {
step_instruction();
if ( exec_flags & EXEC_BKPT ) {
if ( check_breakpoint( BP_EXEC, saturn.PC ) ) {
enter_debugger |= BREAKPOINT_HIT;
break;
}
}
if ( schedule_event-- == 0 )
schedule();
} while ( !enter_debugger );
}

View file

@ -11,6 +11,21 @@
#define HP_MNEMONICS 0 #define HP_MNEMONICS 0
#define CLASS_MNEMONICS 1 #define CLASS_MNEMONICS 1
#define BREAKPOINT_HIT 4
/*
* exec_flags values
*/
#define EXEC_BKPT 1
/*
* Breakpoint related stuff
*/
#define BP_EXEC 1
#define BP_READ 2
#define BP_WRITE 4
#define BP_RANGE 8
extern int enter_debugger; extern int enter_debugger;
extern bool in_debugger; extern bool in_debugger;
extern int exec_flags; extern int exec_flags;
@ -18,7 +33,7 @@ extern int exec_flags;
/**************/ /**************/
/* debugger.c */ /* debugger.c */
/**************/ /**************/
extern int check_breakpoint( int type, word_20 addr );
extern int debug( void ); extern int debug( void );
extern void emulate_debug( void );
#endif /* !_DEBUGGER_H */ #endif /* !_DEBUGGER_H */

View file

@ -62,9 +62,6 @@ int set_t1;
long schedule_event = 0; long schedule_event = 0;
long sched_timer1;
long sched_timer2;
long sched_instr_rollover = SCHED_INSTR_ROLLOVER; long sched_instr_rollover = SCHED_INSTR_ROLLOVER;
long sched_receive = SCHED_RECEIVE; long sched_receive = SCHED_RECEIVE;
long sched_adjtime = SCHED_ADJTIME; long sched_adjtime = SCHED_ADJTIME;
@ -2836,49 +2833,3 @@ inline void schedule( void )
ui_get_event(); ui_get_event();
} }
} }
void emulate( void )
{
struct timeval tv;
struct timeval tv2;
struct timezone tz;
reset_timer( T1_TIMER );
reset_timer( RUN_TIMER );
reset_timer( IDLE_TIMER );
set_accesstime();
start_timer( T1_TIMER );
start_timer( RUN_TIMER );
sched_timer1 = t1_i_per_tick = saturn.t1_tick;
sched_timer2 = t2_i_per_tick = saturn.t2_tick;
set_t1 = saturn.timer1;
do {
step_instruction();
for ( int i = 0; i < ( int )( sizeof( saturn.keybuf.rows ) / sizeof( saturn.keybuf.rows[ 0 ] ) ); i++ ) {
if ( saturn.keybuf.rows[ i ] || config.throttle ) {
/* Throttling speed if needed */
gettimeofday( &tv, &tz );
gettimeofday( &tv2, &tz );
while ( ( tv.tv_sec == tv2.tv_sec ) && ( ( tv.tv_usec - tv2.tv_usec ) < 2 ) )
gettimeofday( &tv, &tz );
tv2.tv_usec = tv.tv_usec;
tv2.tv_sec = tv.tv_sec;
break;
}
}
if ( schedule_event < 0 ) {
fprintf( stderr, "bug" );
schedule_event = 0;
}
if ( schedule_event-- <= 0 )
schedule();
} while ( !enter_debugger );
}

View file

@ -18,6 +18,9 @@
#define RAM_SIZE_SX 0x10000 #define RAM_SIZE_SX 0x10000
#define RAM_SIZE_GX 0x40000 #define RAM_SIZE_GX 0x40000
bool please_exit = false;
bool save_before_exit = true;
bool rom_is_new = true; bool rom_is_new = true;
long ram_size; long ram_size;
long port1_size; long port1_size;
@ -998,6 +1001,9 @@ void init_display( void )
void start_emulator( void ) void start_emulator( void )
{ {
please_exit = false;
save_before_exit = true;
/* If files are successfully read => return and let's go */ /* If files are successfully read => return and let's go */
if ( read_files() ) { if ( read_files() ) {
if ( config.resetOnStartup ) if ( config.resetOnStartup )
@ -1016,4 +1022,8 @@ void start_emulator( void )
init_display(); init_display();
} }
void exit_emulator( void ) { write_files(); } void exit_emulator( void )
{
if ( save_before_exit )
write_files();
}

View file

@ -4,6 +4,9 @@
#include <stdint.h> /* int64_t */ #include <stdint.h> /* int64_t */
#include <stdbool.h> #include <stdbool.h>
#define T1_TIMER 0
/* #define T2_TIMER 1 /\* unused? *\/ */
#define DEC 10 #define DEC 10
#define HEX 16 #define HEX 16
@ -307,6 +310,19 @@ extern hpkey_t keyboard[ NB_KEYS ];
extern int annunciators_bits[ NB_ANNUNCIATORS ]; extern int annunciators_bits[ NB_ANNUNCIATORS ];
extern long sched_timer1;
extern long sched_timer2;
extern unsigned long t1_i_per_tick;
extern unsigned long t2_i_per_tick;
extern bool please_exit;
extern bool save_before_exit;
/***************/
/* emu_timer.c */
/***************/
extern void reset_timer( int timer );
/**************/ /**************/
/* emu_init.c */ /* emu_init.c */
/**************/ /**************/
@ -325,9 +341,4 @@ extern void press_key( int hpkey ); /* used in ui_*.c */
extern void release_key( int hpkey ); /* used in ui_*.c */ extern void release_key( int hpkey ); /* used in ui_*.c */
extern void release_all_keys( void ); /* used in ui_*.c */ extern void release_all_keys( void ); /* used in ui_*.c */
/*****************/
/* emu_emulate.c */
/*****************/
extern void emulate( void ); /* used in main.c */
#endif /* !_EMULATOR_H */ #endif /* !_EMULATOR_H */

View file

@ -5,9 +5,6 @@
#define OUT_FIELD 17 #define OUT_FIELD 17
#define T1_TIMER 0
/* #define T2_TIMER 1 /\* unused? *\/ */
extern device_t device; extern device_t device;
extern int set_t1; extern int set_t1;
@ -29,7 +26,6 @@ extern int end_fields[ 19 ];
/***************/ /***************/
/* emu_timer.c */ /* emu_timer.c */
/***************/ /***************/
extern void reset_timer( int timer );
extern void restart_timer( int timer ); extern void restart_timer( int timer );
extern word_64 get_timer( int timer ); extern word_64 get_timer( int timer );

View file

@ -24,6 +24,7 @@ void signal_handler( int sig )
sigalarm_triggered = true; sigalarm_triggered = true;
break; break;
case SIGPIPE: case SIGPIPE:
ui_stop();
exit_emulator(); exit_emulator();
exit( 0 ); exit( 0 );
default: default:
@ -109,14 +110,64 @@ int main( int argc, char** argv )
/* Start emulation loop */ /* Start emulation loop */
/************************/ /************************/
do { do {
if ( exec_flags ) struct timeval tv;
emulate_debug(); struct timeval tv2;
else struct timezone tz;
emulate();
debug(); reset_timer( T1_TIMER );
} while ( true ); reset_timer( RUN_TIMER );
reset_timer( IDLE_TIMER );
set_accesstime();
start_timer( T1_TIMER );
start_timer( RUN_TIMER );
sched_timer1 = t1_i_per_tick = saturn.t1_tick;
sched_timer2 = t2_i_per_tick = saturn.t2_tick;
set_t1 = saturn.timer1;
do {
step_instruction();
if ( exec_flags & EXEC_BKPT ) {
if ( check_breakpoint( BP_EXEC, saturn.PC ) ) {
enter_debugger |= BREAKPOINT_HIT;
break;
}
}
for ( int i = 0; i < ( int )( sizeof( saturn.keybuf.rows ) / sizeof( saturn.keybuf.rows[ 0 ] ) ); i++ ) {
if ( saturn.keybuf.rows[ i ] || config.throttle ) {
/* Throttling speed if needed */
gettimeofday( &tv, &tz );
gettimeofday( &tv2, &tz );
while ( ( tv.tv_sec == tv2.tv_sec ) && ( ( tv.tv_usec - tv2.tv_usec ) < 2 ) )
gettimeofday( &tv, &tz );
tv2.tv_usec = tv.tv_usec;
tv2.tv_sec = tv.tv_sec;
break;
}
}
if ( schedule_event < 0 ) {
fprintf( stderr, "bug" );
schedule_event = 0;
}
if ( schedule_event-- <= 0 )
schedule();
} while ( !please_exit && !enter_debugger );
fprintf( stderr, "please_exit = %i, enter_debugger = %i\n", please_exit, enter_debugger );
if ( enter_debugger )
debug();
} while ( !please_exit );
ui_stop();
exit_emulator();
/* never reached */
return 0; return 0;
} }

View file

@ -199,3 +199,33 @@ void start_UI( int argc, char** argv )
break; break;
} }
} }
void ui_stop()
{
ui_init_LCD();
switch ( config.frontend_type ) {
#if ( defined( HAS_X11 ) )
case FRONTEND_X11:
default:
x11_ui_stop();
break;
#endif
#if ( defined( HAS_SDL ) )
case FRONTEND_SDL:
# if ( !defined( HAS_X11 ) )
default:
# endif
sdl_ui_stop();
break;
#endif
case FRONTEND_TEXT:
#if ( !defined( HAS_X11 ) && !defined( HAS_SDL ) )
default:
#endif
text_ui_stop();
break;
}
}

View file

@ -28,13 +28,16 @@ extern letter_t small_font[ 128 ];
/*************/ /*************/
#ifdef HAS_X11 #ifdef HAS_X11
extern void init_x11_ui( int argc, char** argv ); extern void init_x11_ui( int argc, char** argv );
extern void x11_ui_stop();
#endif #endif
#ifdef HAS_SDL #ifdef HAS_SDL
extern void init_sdl_ui( int argc, char** argv ); extern void init_sdl_ui( int argc, char** argv );
extern void sdl_ui_stop();
#endif #endif
extern void init_text_ui( int argc, char** argv ); extern void init_text_ui( int argc, char** argv );
extern void text_ui_stop();
/*************************************************/ /*************************************************/
/* public API: if it's there it's used elsewhere */ /* public API: if it's there it's used elsewhere */
@ -61,6 +64,8 @@ extern void ( *ui_refresh_LCD )( void );
/*******************/ /*******************/
/* used in: main.c */ /* used in: main.c */
/*******************/ /*******************/
extern void ui_stop( void );
extern void start_UI( int argc, char** argv ); extern void start_UI( int argc, char** argv );
#endif /* !_UI_H */ #endif /* !_UI_H */

View file

@ -724,8 +724,7 @@ static int SDLKeyToKey( SDLKey k )
break; break;
case SDLK_F7: case SDLK_F7:
case SDLK_F10: case SDLK_F10:
exit_emulator(); please_exit = true;
exit( 0 );
break; break;
default: default:
return -1; return -1;
@ -1779,8 +1778,7 @@ int sdl_get_event( void )
if ( SDL_PollEvent( &event ) ) { if ( SDL_PollEvent( &event ) ) {
switch ( event.type ) { switch ( event.type ) {
case SDL_QUIT: case SDL_QUIT:
exit_emulator(); please_exit = true;
exit( 0 );
break; break;
/* // Mouse move: react to state changes in the buttons that are /* // Mouse move: react to state changes in the buttons that are
@ -2038,6 +2036,8 @@ void sdl_adjust_contrast()
sdl_draw_annunc(); sdl_draw_annunc();
} }
void sdl_ui_stop() {}
void init_sdl_ui( int argc, char** argv ) void init_sdl_ui( int argc, char** argv )
{ {
/* Set public API to this UI's functions */ /* Set public API to this UI's functions */

View file

@ -543,12 +543,7 @@ int text_get_event( void )
case '|': /* Shift+\ */ case '|': /* Shift+\ */
case KEY_SEND: /* Shift+End */ case KEY_SEND: /* Shift+End */
case KEY_F( 10 ): case KEY_F( 10 ):
nodelay( stdscr, FALSE ); please_exit = true;
echo();
endwin();
exit_emulator();
exit( 0 );
break; break;
} }
@ -559,6 +554,13 @@ int text_get_event( void )
return 1; return 1;
} }
void text_ui_stop()
{
nodelay( stdscr, FALSE );
echo();
endwin();
}
void init_text_ui( int argc, char** argv ) void init_text_ui( int argc, char** argv )
{ {
/* Set public API to this UIs functions */ /* Set public API to this UIs functions */

View file

@ -2845,9 +2845,7 @@ int decode_key( XEvent* xev, KeySym sym, char* buf, int buflen )
break; break;
case XK_F7: case XK_F7:
case XK_F10: case XK_F10:
exit_emulator(); please_exit = true;
XCloseDisplay( dpy );
exit( 0 );
break; break;
default: default:
break; break;
@ -2856,6 +2854,8 @@ int decode_key( XEvent* xev, KeySym sym, char* buf, int buflen )
return wake; return wake;
} }
void x11_ui_stop() { XCloseDisplay( dpy ); }
void x11_release_all_keys( void ) void x11_release_all_keys( void )
{ {
release_all_keys(); release_all_keys();
@ -3425,14 +3425,8 @@ int x11_get_event( void )
cm = ( XClientMessageEvent* )&xev; cm = ( XClientMessageEvent* )&xev;
if ( cm->message_type == wm_protocols ) { if ( cm->message_type == wm_protocols ) {
if ( cm->data.l[ 0 ] == ( long )wm_delete_window ) { if ( cm->data.l[ 0 ] == ( long )wm_delete_window )
exit_emulator(); please_exit = true;
XCloseDisplay( dpy );
exit( 0 );
}
if ( cm->data.l[ 0 ] == ( long )wm_save_yourself ) if ( cm->data.l[ 0 ] == ( long )wm_save_yourself )
save_command_line(); save_command_line();
} }