libx48ng/src/main.c

126 lines
3.1 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"
#include "runtime_options.h"
2023-09-16 15:40:24 +02:00
#include "ui.h" /* 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:
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;
2024-04-09 19:47:49 +02:00
int interval = 15625; /* 64Hz according to https://www.hpcalc.org/hp48/docs/faq/48faq-6.html */
2023-04-27 12:15:59 +02:00
it.it_interval.tv_sec = 0;
it.it_interval.tv_usec = interval;
2023-04-27 12:15:59 +02:00
it.it_value.tv_sec = 0;
it.it_value.tv_usec = interval;
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-09 14:26:18 +02:00
parse_args( argc, argv );
/* Emulator */
2023-09-16 15:40:24 +02:00
init_emulator();
init_serial();
init_display();
2024-04-09 14:26:18 +02:00
/* (G)UI */
2024-04-09 19:47:49 +02:00
setup_frontend(); /* points init_ui to the correct function */
2024-04-09 15:51:18 +02:00
init_ui( argc, argv );
2023-09-13 16:49:00 +02:00
2023-05-02 13:42:58 +02:00
/************************/
/* Start emulation loop */
/************************/
2023-04-27 12:15:59 +02:00
do {
if ( !exec_flags )
emulate();
else
emulate_debug();
debug();
2024-04-09 14:23:10 +02:00
} while ( true );
2023-04-27 12:15:59 +02:00
return 0;
}