home *** CD-ROM | disk | FTP | other *** search
- /*
- * Main program for Un*x-hosted v9t9.
- *
- */
- #include <signal.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <sys/time.h>
- #include <X11/Xlib.h>
- #include <stdarg.h>
-
- #include "v9t9_common.h"
- #include "system.h"
- #include "timer.h"
- #include "v9t9.h"
-
- #include "command_rl.h"
- #include "debugger.h"
- #include "moduleconfig.h"
- #include "v9t9_module.h"
-
- #include <gtk/gtk.h>
- #include "gtkloop.h"
- #include "gtkinterface.h"
- #include "unixmain.h"
-
- #define _L LOG_INTERNAL | LOG_INFO
-
- static int unix_v9t9_initialized;
- int console_fd;
- int gdb_debugging = 0;
-
- static void
- system_initlog(void);
-
- static void
- system_termlog(void);
-
- int (*frontend_loop)(void) = 0L;
- void (*frontend_getcommands)(void);
- void (*frontend_log)(u32 srcflags, const char *text) = 0L;
- void (*frontend_report_status)(status_item item, va_list va) = 0L;
- void (*frontend_debugger_enabled)(bool enabled) = 0L;
- void (*frontend_execution_paused)(bool paused) = 0L;
-
- static void
- sigsegv(int x)
- {
- //v9t9_restop();
- if (linuxKeyboard.runtimeflags & vmRTInUse)
- linuxKeyboard.restop();
- if (!gdb_debugging) {
- signal(SIGSEGV, SIG_DFL);
- logger(_L | LOG_FATAL, "SIGSEGV caught.\n");
- exit(23);
- } else {
- signal(SIGSEGV, SIG_DFL);
- *(char *) 0 = 0;
- }
- }
-
- #if defined(LINUX_SVGA_KEYBOARD) && defined(LINUX_SVGA_VIDEO)
- #define HAS_SVGA 1
- #endif
-
- #if defined(X_WIN_KEYBOARD) && defined(X_WIN_VIDEO)
- #define HAS_XLIB 1
- #endif
-
- #if defined(GTK_KEYBOARD) && defined(GTK_VIDEO)
- #define HAS_GTK 1
- #endif
-
- int
- main(int argc, char **argv)
- {
- enum {
- FE_UNKNOWN,
- #if HAS_SVGA
- FE_SVGA,
- #endif
- #if HAS_XLIB
- FE_XLIB,
- #endif
- #if HAS_GTK
- FE_GTK,
- #endif
- } frontend = FE_UNKNOWN;
- Display *display;
-
- int ret;
- int status;
-
- v9t9_config(argc, argv);
-
- unix_v9t9_initialized = 0;
-
- system_initlog();
- initlog();
-
- console_fd = open("/dev/console", O_RDWR);
- // sound_fd = open("/dev/dsp", O_RDWR);
-
- if (argc > 1 && strcmp(argv[1], "--debug") == 0) {
- gdb_debugging = 1;
- argc--;
- argv++;
- }
-
- if (!gdb_debugging)
- signal(SIGSEGV, sigsegv);
- else
- signal(SIGSEGV, SIG_DFL);
-
- #ifdef LINUX_SVGA_VIDEO
- if (argc > 1 && strcmp(argv[1], "--no-video") == 0) {
- svgaVideo.runtimeflags |= vmRTUnselected;
- argc--;
- argv++;
- }
- #endif
-
- #ifdef LINUX_SVGA_KEYBOARD
- if (argc > 1 && strcmp(argv[1], "--no-kbd") == 0) {
- linuxKeyboard.runtimeflags |= vmRTUnselected;
- argc--;
- argv++;
- }
- #endif
-
- /* Look for explicit choice of frontend */
- if (argc > 2 && strcmp(argv[1], "-fe") == 0) {
- #if HAS_SVGA
- if (strcasecmp(argv[2], "svga") == 0) {
- frontend = FE_SVGA;
- argv += 2;
- argc -= 2;
- } else
- #endif
- #if HAS_XLIB
- if (strcasecmp(argv[2], "xlib") == 0) {
- frontend = FE_XLIB;
- argv += 2;
- argc -= 2;
- } else
- #endif
- #if HAS_GTK
- if (strcasecmp(argv[2], "gtk") == 0) {
- frontend = FE_GTK;
- svgaVideo.runtimeflags |= vmRTUnselected;
- linuxKeyboard.runtimeflags |= vmRTUnselected;
- argv += 2;
- argc -= 2;
- } else
- #endif
- {
- logger(_L|LOG_USER|LOG_ERROR, "Unknown option '%s %s';\n"
- "expected one of "
- #if HAS_SVGA
- "svga|"
- #endif
- #if HAS_XLIB
- "xlib|"
- #endif
- #if HAS_GTK
- "gtk"
- #endif
- "\n",
- argv[1], argv[2]);
- return 1;
- }
- }
-
- argv[0] = v9t9_argv[0];
- v9t9_argv = argv;
- v9t9_argc = argc;
-
- #if HAS_GTK || HAS_XLIB
- /* Check for X connection before assuming GTK
- will work; it ABORTS if it can't open a connection. */
-
- if ((display = XOpenDisplay(NULL)) == NULL) {
- if (frontend == FE_UNKNOWN
- #if HAS_GTK
- || frontend == FE_GTK
- #endif
- )
- frontend = FE_SVGA;
- } else {
- XrmInitialize();
- XCloseDisplay(display);
- }
- #endif
-
- #if HAS_GTK
- if ((frontend == FE_UNKNOWN || frontend == FE_GTK) &&
- GTK_system_init()) {
- frontend = FE_GTK;
- frontend_log = GTK_system_log;
- frontend_getcommands = unix_system_getcommands;
- frontend_report_status = GTK_system_report_status;
- frontend_debugger_enabled = GTK_system_debugger_enabled;
- frontend_execution_paused = GTK_system_execution_paused;
- frontend_loop = GTK_system_loop;
-
- #if HAS_SVGA
- svgaVideo.runtimeflags |= vmRTUnselected;
- linuxKeyboard.runtimeflags |= vmRTUnselected;
- #endif
- #if HAS_XLIB
- X_Video.runtimeflags |= vmRTUnselected;
- X_Keyboard.runtimeflags |= vmRTUnselected;
- #endif
- logger(_L|LOG_USER, "Using GTK\n");
- v9t9_window = create_v9t9_window();
- v9t9_drawing_area = gtk_object_get_data(GTK_OBJECT(v9t9_window),
- "v9t9_drawing_area");
- gtk_widget_show(v9t9_window);
- } else
- #endif
- #if HAS_XLIB
- if ((frontend == FE_UNKNOWN || frontend == FE_XLIB) &&
- xlib_system_init()) {
- frontend = FE_XLIB;
- frontend_log = unix_system_log;
- frontend_getcommands = unix_system_getcommands;
- frontend_report_status = unix_system_report_status;
- frontend_loop = xlib_system_loop;
- frontend_debugger_enabled = unix_system_debugger_enabled;
- frontend_execution_paused = unix_system_execution_paused;
-
- #if HAS_SVGA
- svgaVideo.runtimeflags |= vmRTUnselected;
- linuxKeyboard.runtimeflags |= vmRTUnselected;
- #endif
- #if HAS_GTK
- gtkVideo.runtimeflags |= vmRTUnselected;
- gtkKeyboard.runtimeflags |= vmRTUnselected;
- #endif
- logger(_L|LOG_USER, "Using Xlib\n");
- } else
- #endif
- #if HAS_SVGA
- if ((frontend == FE_UNKNOWN || frontend == FE_SVGA) &&
- svga_system_init()) {
- frontend = FE_SVGA;
- frontend_log = unix_system_log;
- frontend_getcommands = unix_system_getcommands;
- frontend_report_status = unix_system_report_status;
- frontend_loop = svga_system_loop;
- frontend_debugger_enabled = unix_system_debugger_enabled;
- frontend_execution_paused = unix_system_execution_paused;
-
- #if HAS_XLIB
- X_Video.runtimeflags |= vmRTUnselected;
- X_Keyboard.runtimeflags |= vmRTUnselected;
- #endif
- #if HAS_GTK
- gtkVideo.runtimeflags |= vmRTUnselected;
- gtkKeyboard.runtimeflags |= vmRTUnselected;
- #endif
-
- logger(_L|LOG_USER, "Using SVGAlib\n");
- } else
- #endif
- {
- logger(_L|LOG_FATAL, "Could not find a frontend\n");
- return 2;
- }
-
- if (!v9t9_init())
- return 3;
-
- if (!v9t9_restart())
- return 4;
-
- signal(SIGINT, v9t9_sigint);
- signal(SIGTERM, v9t9_sigterm);
-
- unix_v9t9_initialized = 1;
- ret = frontend_loop();
-
- v9t9_restop();
-
- v9t9_term(ret);
-
- termlog();
- system_termlog();
-
- wait(&status);
- exit(ret);
- }
-
-
- void
- unix_system_pause(void)
- {
- /* Recommended way from glibc info pages
- for waiting until a certain signal arrives. */
- sigset_t mask, oldmask;
-
- sigemptyset(&mask);
- sigaddset(&mask, SIGINT);
- sigprocmask(SIG_BLOCK, &mask, &oldmask);
- sigsuspend(&oldmask);
- sigprocmask(SIG_UNBLOCK, &mask, NULL);
- }
-
- void
- system_getcommands(void)
- {
- if (frontend_getcommands)
- frontend_getcommands();
- else
- unix_system_getcommands();
- }
-
- void
- unix_system_getcommands(void)
- {
- FILE *cmdsin = fopen("/dev/tty", "r");
- FILE *cmdsout = fopen("/dev/tty", "w");
-
- logger(_L|LOG_INFO, "Entering interactive mode\n");
- if (cmdsin == NULL || cmdsout == NULL || feof(cmdsin)) {
- logger(_L|LOG_ERROR, "FAILED: could not open terminal\n");
- return;
- }
-
- // this leaves sound and timer going!
- // if (X_Video.runtimeflags & vmRTInUse)
- // MODULE_ITERATE(vmKeyboard, vmRestopModule);
- // else
- v9t9_restop();
-
- // system_task(); // eat up X events
- readline_getcommands(cmdsin, cmdsout);
-
- // this leaves sound and timer going!
- // if (X_Video.runtimeflags & vmRTInUse)
- // MODULE_ITERATE(vmKeyboard, vmRestartModule);
- // else
- v9t9_restart();
-
- }
-
- static struct itimerval my_timer;
- unsigned int TM_Ticked;
-
- static void unix_system_timer_handler(int unused)
- {
- TM_Ticked++;
- if (TM_Ticked > 10) TM_Ticked = 10;
- if (!(stateflag & ST_PAUSE)) stateflag |= ST_STOP;
- }
-
- void
- system_timer_init(void)
- {
- TM_Ticked = 0;
- }
-
- void
- system_timer_install(void)
- {
- struct sigaction s;
-
- // s.sa_handler = TM_TickHandler;
- s.sa_handler = unix_system_timer_handler;
- sigemptyset(&s.sa_mask);
- s.sa_flags = SA_RESTART;
- s.sa_restorer = NULL;
-
- sigaction(SIGALRM, &s, NULL);
-
- my_timer.it_value.tv_sec = 0;
- my_timer.it_value.tv_usec = 1000000 / TM_HZ; /* Hz */
- my_timer.it_interval.tv_sec = 0;
- my_timer.it_interval.tv_usec = 1000000 / TM_HZ;
-
- setitimer(ITIMER_REAL, &my_timer, NULL);
- }
-
- void
- system_timer_uninstall(void)
- {
- struct itimerval t;
-
- /* turn off and save current timer */
- memset((void *) &t, 0, sizeof(t));
-
- setitimer(ITIMER_REAL, &t, &my_timer);
- }
-
- // We emit text to both stdout and a logfile.
-
- static FILE *logfile; // to disk
- static FILE *loguser; // to tty
-
- static void
- system_initlog(void)
- {
- if ((logfile = fopen("log.unix.txt", "w")) == NULL) {
- fprintf(stderr, "Could not create log file\n");
- exit(1);
- }
- if ((loguser = fopen("/dev/tty", "w")) == NULL) {
- fprintf(stderr, "Could not create user log file\n");
- exit(1);
- }
- setbuf(logfile, NULL);
- setbuf(loguser, NULL);
- atexit(system_termlog);
- }
-
- static void
- system_termlog(void)
- {
- fclose(logfile);
- fclose(loguser);
- }
-
- void
- system_log(u32 srcflags, const char *text)
- {
- fwrite(text, 1, strlen(text), logfile);
- fflush(logfile);
-
- if (!unix_v9t9_initialized && (srcflags & LOG_TYPE_MASK) == LOG_ERROR) {
- fwrite(text, 1, strlen(text), stdout);
- fflush(stdout);
- }
-
- if (frontend_log)
- frontend_log(srcflags, text);
- }
-
- void
- unix_system_log(u32 srcflags, const char *text)
- {
- if (LOG_IS_VISIBLE(srcflags)) {
- const char *cptr = strchr(text, ':');
-
- if (!cptr || (srcflags & LOG_SRC_MASK) == 0)
- cptr = text;
- else
- cptr += 2;
- if (*text == '\n' && cptr != text)
- fwrite("\n", 1, 1, loguser);
- fwrite(cptr, 1, strlen(cptr), loguser);
- fflush(loguser);
- }
- }
-
-
- #define ITEM_ON_CODE_LINE(item) \
- ((item) >= STATUS_CPU_PC && \
- (item) <= STATUS_CPU_INSTRUCTION_LAST && \
- (item) != STATUS_CPU_REGISTER_VIEW)
-
- void
- system_report_status(status_item item, va_list va)
- {
- char buffer[1024], *bptr = buffer+1;
- static bool last_item_on_code_line;
- bool item_on_code_line;
-
- report_status_text(item, va, bptr, sizeof(buffer)-1);
-
- if (*bptr)
- {
- item_on_code_line = ITEM_ON_CODE_LINE(item);
- if (last_item_on_code_line != item_on_code_line) {
- buffer[0] = '\n';
- bptr--;
- }
-
- system_log(LOG_USER, bptr);
-
- last_item_on_code_line = item_on_code_line;
- }
-
- if (frontend_report_status)
- frontend_report_status(item, va);
- }
-
- void
- unix_system_report_status(status_item item, va_list va)
- {
- }
-
- void
- system_debugger_enabled(bool enabled)
- {
- if (frontend_debugger_enabled)
- frontend_debugger_enabled(enabled);
- }
-
- void
- unix_system_debugger_enabled(bool enabled)
- {
- }
-
- void
- system_execution_paused(bool paused)
- {
- if (frontend_execution_paused)
- frontend_execution_paused(paused);
- }
-
- void
- unix_system_execution_paused(bool paused)
- {
- logger(LOG_USER, "Execution is %s\n",
- paused ? "paused" : "resumed");
- }
-