libx48ng/src/main.c

167 lines
4.3 KiB
C
Raw Normal View History

2022-03-24 13:41:22 +01:00
#include <errno.h>
#include <fcntl.h>
#include <langinfo.h>
#include <locale.h>
2022-03-24 13:41:22 +01:00
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
2022-03-24 13:41:22 +01:00
#include <unistd.h>
#include "debugger.h"
#include "emulator.h"
2024-04-18 15:47:23 +02:00
#include "config.h"
2024-04-10 11:01:13 +02:00
#include "ui.h" /* setup_frontend(); init_ui(); */
void signal_handler( int sig )
{
2023-04-27 12:15:59 +02:00
switch ( sig ) {
case SIGINT: /* Ctrl-C */
enter_debugger |= USER_INTERRUPT;
break;
2023-04-27 12:15:59 +02:00
case SIGALRM:
2024-04-10 09:34:57 +02:00
sigalarm_triggered = true;
2023-04-27 12:15:59 +02:00
break;
case SIGPIPE:
ui_stop();
2023-09-13 15:07:31 +02:00
exit_emulator();
2023-04-27 12:15:59 +02:00
exit( 0 );
default:
break;
}
}
int main( int argc, char** argv )
{
2023-04-27 12:15:59 +02:00
setlocale( LC_ALL, "C" );
/*****************************************/
2023-09-13 16:49:00 +02:00
/* handlers for SIGALRM, SIGPIPE */
/*****************************************/
sigset_t set;
struct sigaction sa;
2023-04-27 12:15:59 +02:00
sigemptyset( &set );
sigaddset( &set, SIGALRM );
sa.sa_handler = signal_handler;
sa.sa_mask = set;
#ifdef SA_RESTART
2023-04-27 12:15:59 +02:00
sa.sa_flags = SA_RESTART;
#endif
2023-04-27 12:15:59 +02:00
sigaction( SIGALRM, &sa, ( struct sigaction* )0 );
sigemptyset( &set );
sigaddset( &set, SIGINT );
sa.sa_handler = signal_handler;
sa.sa_mask = set;
#ifdef SA_RESTART
sa.sa_flags = SA_RESTART;
#endif
sigaction( SIGINT, &sa, ( struct sigaction* )0 );
2023-04-27 12:15:59 +02:00
sigemptyset( &set );
sigaddset( &set, SIGPIPE );
sa.sa_handler = signal_handler;
sa.sa_mask = set;
#ifdef SA_RESTART
2023-04-27 12:15:59 +02:00
sa.sa_flags = SA_RESTART;
#endif
2023-04-27 12:15:59 +02:00
sigaction( SIGPIPE, &sa, ( struct sigaction* )0 );
/************************************/
/* set the real time interval timer */
/************************************/
2024-04-09 14:26:18 +02:00
/*
2024-04-09 14:32:45 +02:00
Every <interval>µs setitimer will trigger a SIGALRM
2024-04-10 09:34:57 +02:00
which will set sigalarm_triggered to true
In emulate() sigalarm_triggered triggers LCD refresh and UI event handling
2024-04-09 14:26:18 +02:00
*/
struct itimerval it;
2023-04-27 12:15:59 +02:00
it.it_interval.tv_sec = 0;
2024-04-10 11:01:13 +02:00
it.it_interval.tv_usec = USEC_PER_FRAME;
2023-04-27 12:15:59 +02:00
it.it_value.tv_sec = 0;
2024-04-10 11:01:13 +02:00
it.it_value.tv_usec = USEC_PER_FRAME;
2023-04-27 12:15:59 +02:00
setitimer( ITIMER_REAL, &it, ( struct itimerval* )0 );
/**********************************************************/
/* Set stdin flags to not include O_NDELAY and O_NONBLOCK */
/**********************************************************/
2024-04-09 14:26:18 +02:00
/*
I don't know what this is for?
*/
long flags;
2023-04-27 12:15:59 +02:00
flags = fcntl( STDIN_FILENO, F_GETFL, 0 );
flags &= ~O_NDELAY;
flags &= ~O_NONBLOCK;
fcntl( STDIN_FILENO, F_SETFL, flags );
/********************/
/* initialize stuff */
/********************/
2024-04-18 15:47:23 +02:00
config_init( argc, argv );
2024-04-09 14:26:18 +02:00
/* Emulator */
2024-04-10 14:59:50 +02:00
start_emulator();
2024-04-09 14:26:18 +02:00
/* (G)UI */
2024-04-10 14:59:50 +02:00
start_UI( argc, argv );
2023-09-13 16:49:00 +02:00
2023-05-02 13:42:58 +02:00
/************************/
/* Start emulation loop */
/************************/
2024-06-05 14:07:47 +02:00
struct timeval tv;
struct timeval tv2;
struct timezone tz;
2023-04-27 12:15:59 +02:00
do {
reset_timer( T1_TIMER );
reset_timer( RUN_TIMER );
reset_timer( IDLE_TIMER );
set_accesstime();
2024-06-05 14:07:47 +02:00
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();
2024-06-05 14:07:47 +02:00
if ( config.useDebugger && ( exec_flags & EXEC_BKPT ) && check_breakpoint( BP_EXEC, saturn.PC ) ) {
2024-04-25 14:17:12 +02:00
enter_debugger |= BREAKPOINT_HIT;
break;
}
2024-06-05 14:08:10 +02:00
for ( int i = 0; i < KEYS_BUFFER_SIZE; i++ )
if ( saturn.keybuf[ i ] || config.throttle ) {
/* Throttling speed if needed */
gettimeofday( &tv, &tz );
gettimeofday( &tv2, &tz );
2024-06-05 14:07:47 +02:00
while ( ( tv.tv_sec == tv2.tv_sec ) && ( ( tv.tv_usec - tv2.tv_usec ) < 2 ) )
gettimeofday( &tv, &tz );
break;
}
2024-06-05 14:07:47 +02:00
if ( schedule_event < 0 ) // "bug"
schedule_event = 0;
2024-06-05 14:07:47 +02:00
if ( schedule_event-- <= 0 )
schedule();
} while ( /* !please_exit && */ !enter_debugger );
if ( enter_debugger )
debug();
} while ( true /* !please_exit */ );
2024-08-13 20:54:16 +02:00
/* Never reached when not using please_exit */
ui_stop();
exit_emulator();
2023-04-27 12:15:59 +02:00
return 0;
}