This is main.c in view mode; [Download] [Up]
/*
* main.c - VICE startup.
*
* Written by
* Ettore Perazzoli (ettore@comm2000.it)
* Teemu Rantanen (tvr@cs.hut.fi)
* Vesa-Matti Puro (vmp@lut.fi)
* Jarkko Sonninen (sonninen@lut.fi)
* Jouko Valta (jopi@stekt.oulu.fi)
* André Fachat (a.fachat@physik.tu-chemnitz.de)
*
* This file is part of VICE, the Versatile Commodore Emulator.
* See README for copyright notice.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA.
*
*/
#include "vice.h"
#ifdef __hpux
#ifndef _INCLUDE_POSIX_SOURCE
#define _INCLUDE_POSIX_SOURCE
#endif
#ifndef _POSIX_SOURCE
#define _POSIX_SOURCE
#endif
#endif /* __hpux */
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#ifdef __hpux
#define _INCLUDE_XOPEN_SOURCE
#define _XPG2
#include <limits.h>
#undef _INCLUDE_XOPEN_SOURCE
#undef _XPG2
#else
#include <limits.h>
#endif
#if defined __MSDOS__ || defined WIN32
#include <fcntl.h>
#endif
#include "machine.h"
#include "maincpu.h"
#include "serial.h"
#include "interrupt.h"
#include "sound.h"
#include "ui.h"
#include "vsync.h"
#include "video.h"
#include "kbd.h"
#include "resources.h"
#include "sysfile.h"
#include "mon.h"
#include "autostart.h"
#include "findpath.h"
#include "utils.h"
#include "joystick.h"
#include "attach.h"
#include "cmdline.h"
#include "fsdevice.h"
#include "cartridge.h"
/* ------------------------------------------------------------------------- */
char *progname;
char *boot_path;
static RETSIGTYPE break64(int sig);
static void exit64(void);
/* ------------------------------------------------------------------------- */
#if defined __MSDOS__ || defined WIN32
#ifdef __MSDOS__
#include <dir.h>
#endif
static char *orig_workdir;
static void restore_workdir(void)
{
if (orig_workdir)
chdir(orig_workdir);
}
static void preserve_workdir(void)
{
orig_workdir = getcwd(NULL, GET_PATH_MAX);
atexit(restore_workdir);
}
/* Warning! This must be called *once*. */
static void set_boot_path(const char *prg_path)
{
fname_split(prg_path, &boot_path, NULL);
}
#else /* __MSDOS__ */
/* Warning! This must be called *once*. */
static void set_boot_path(const char *prg_path)
{
boot_path = findpath(prg_path, getenv("PATH"), X_OK);
/* Remove the program name. */
*strrchr(boot_path, '/') = '\0';
}
#endif /* __MSDOS__ */
/* ------------------------------------------------------------------------- */
/* These are the command-line options for the initialization sequence. */
static char *autostart_string;
static char *startup_disk_images[4];
static char *startup_tape_image;
static int cmdline_help(const char *param, void *extra_param)
{
cmdline_show_help();
exit(0);
}
static int cmdline_default(const char *param, void *extra_param)
{
resources_set_defaults();
return 0;
}
static int cmdline_autostart(const char *param, void *extra_param)
{
if (autostart_string != NULL)
free(autostart_string);
autostart_string = stralloc(param);
return 0;
}
static int cmdline_attach(const char *param, void *extra_param)
{
int unit = (int) extra_param;
switch (unit) {
case 1:
if (startup_tape_image != NULL)
free(startup_tape_image);
startup_tape_image = stralloc(param);
break;
case 8:
case 9:
case 10:
case 11:
if (startup_disk_images[unit - 8] != NULL)
free(startup_disk_images);
startup_disk_images[unit - 8] = stralloc(param);
break;
default:
fprintf(stderr, "cmdline_attach(): unexpected unit number %d?!\n",
unit);
}
return 0;
}
static cmdline_option_t cmdline_options[] = {
{ "-help", CALL_FUNCTION, 1, cmdline_help, NULL, NULL, NULL,
NULL, "Show a list of the available options and exit normally" },
{ "-?", CALL_FUNCTION, 1, cmdline_help, NULL, NULL, NULL,
NULL, "Show a list of the available options and exit normally" },
{ "-default", CALL_FUNCTION, 1, cmdline_default, NULL, NULL, NULL,
NULL, "Restore default (factory) settings" },
{ "-autostart", CALL_FUNCTION, 1, cmdline_autostart, NULL, NULL, NULL,
"<name>", "Attach and autostart tape/disk image <name>" },
{ "-1", CALL_FUNCTION, 1, cmdline_attach, (void *) 1, NULL, NULL,
"<name>", "Attach <name> as a tape image" },
{ "-8", CALL_FUNCTION, 1, cmdline_attach, (void *) 8, NULL, NULL,
"<name>", "Attach <name> as a disk image in drive #8" },
{ "-9", CALL_FUNCTION, 1, cmdline_attach, (void *) 9, NULL, NULL,
"<name>", "Attach <name> as a disk image in drive #9" },
{ "-10", CALL_FUNCTION, 1, cmdline_attach, (void *) 10, NULL, NULL,
"<name>", "Attach <name> as a disk image in drive #10" },
{ "-11", CALL_FUNCTION, 1, cmdline_attach, (void *) 11, NULL, NULL,
"<name>", "Attach <name> as a disk image in drive #11" },
{ NULL }
};
/* ------------------------------------------------------------------------- */
/* This is the main program entry point. When not compiling for Windows,
this is `main()'; on Windows we have to #define the name to something
different because the standard entry point is `WinMain()' there. */
int MAIN_PROGRAM(int argc, char **argv)
{
if (atexit (exit64) < 0) {
perror ("atexit");
return -1;
}
#if defined __MSDOS__ || defined WIN32
/* Set the default file mode. */
_fmode = O_BINARY;
#endif
#ifdef __MSDOS__
/* Avoid exiting to a different directory than the one we were called
from. */
preserve_workdir();
#endif
progname = strrchr(argv[0], '/');
if (!progname)
progname = argv[0];
else
progname++;
set_boot_path(argv[0]);
/* Initialize system file locator. */
sysfile_init(boot_path, machine_name);
/* VICE boot sequence. */
printf ("\n*** VICE Version %s ***\n", VERSION);
printf ("Welcome to %s, the free portable Commodore %s Emulator.\n\n",
progname, machine_name);
printf ("Written by\n"
"E. Perazzoli, T. Rantanen, A. Fachat, D. Sladic,\n"
"A. Boose, J. Valta and J. Sonninen.\n\n");
printf ("This is free software with ABSOLUTELY NO WARRANTY.\n");
printf ("See the \"About VICE\" command for more info.\n\n");
/* Initialize the user interface. `ui_init()' might need to handle the
command line somehow, so we call it before parsing the options.
(e.g. under X11, the `-display' option is handled independently). */
if (ui_init(&argc, argv) < 0) {
fprintf(stderr, "Cannot initialize the UI.\n");
exit (-1);
}
/* Initialize resource handling. */
if (resources_init(machine_name)) {
fprintf(stderr, "Cannot initialize resource handling.\n");
exit(-1);
}
if (sysfile_init_resources() < 0) {
fprintf(stderr,
"Cannot initialize resources for the system file locator.\n");
exit(-1);
}
if (ui_init_resources() < 0) {
fprintf(stderr, "Cannot initialize UI-specific resources.\n");
exit(-1);
}
if (file_system_init_resources() < 0) {
fprintf(stderr, "Cannot initialize file system-specific resources.\n");
exit(-1);
}
/* Initialize file system device-specific resources. */
if (fsdevice_init_resources() < 0) {
fprintf(stderr, "Cannot initialize file system device-specific resources.\n");
exit(-1);
}
if (machine_init_resources() < 0) {
fprintf(stderr, "Cannot initialize machine-specific resources.\n");
exit(-1);
}
if (joystick_init_resources() < 0) {
fprintf(stderr, "Cannot initialize joystick-specific resources.\n");
exit(-1);
}
/* Set factory defaults. */
resources_set_defaults();
/* Load the user's default configuration file. */
{
int retval = resources_load(NULL);
if (retval < 0) {
fprintf(stderr,
"Couldn't load user's configuration file: "
"using default settings.\n");
/* The resource file might contain errors, and thus certain
resources might have been initialized anyway. */
resources_set_defaults();
#ifndef __MSDOS__
/* XXX: This assumes that it's safe to call `ui_error()' before
`ui_init_finish()'. */
if (retval == RESERR_FILE_INVALID)
ui_error("Configuration file not valid\n"
"(maybe from an older version?).\n\n"
"Using default settings.");
#endif
}
}
/* Initialize command-line options. */
cmdline_init();
if (cmdline_register_options(cmdline_options) < 0) {
fprintf(stderr, "Cannot initialize main command-line options.\n");
exit(-1);
}
if (sysfile_init_cmdline_options() < 0) {
fprintf(stderr, "Cannot initialize command-line options for system file locator.\n");
exit(-1);
}
if (ui_init_cmdline_options() < 0) {
fprintf(stderr, "Cannot initialize UI-specific command-line options.\n");
exit(-1);
}
if (machine_init_cmdline_options() < 0) {
fprintf(stderr, "Cannot initialize machine-specific command-line options.\n");
exit(-1);
}
if (fsdevice_init_cmdline_options() < 0) {
fprintf(stderr, "Cannot initialize file system-specific command-line options.\n");
exit(-1);
}
if (joystick_init_cmdline_options() < 0) {
fprintf(stderr, "Cannot initialize joystick-specific command-line options.\n");
exit(-1);
}
if (cmdline_parse(&argc, argv) < 0) {
fprintf(stderr, "Error parsing command-line options, bailing out.\n");
exit(-1);
}
/* The last orphan option is the same as `-autostart'. */
if (argc >= 1 && autostart_string == NULL) {
autostart_string = stralloc(argv[1]);
argc--, argv++;
}
if (argc > 1) {
int i;
fprintf(stderr, "Extra arguments on command-line:\n");
for (i = 1; i < argc; i++)
fprintf(stderr, "\t%s\n", argv[i]);
exit(-1);
}
putchar('\n');
/* Complete the GUI initialization (after loading the resources and
parsing the command-line) if necessary. */
if (ui_init_finish() < 0)
exit(-1);
putchar('\n');
#ifdef __MSDOS__
signal(SIGINT, SIG_IGN);
#else
signal(SIGINT, break64);
#endif
signal(SIGSEGV, break64);
signal(SIGILL, break64);
signal(SIGTERM, break64);
#ifndef WIN32
/* Windows does not have these ones. */
signal(SIGPIPE, break64);
signal(SIGHUP, break64);
signal(SIGQUIT, break64);
#endif
/* Initialize real joystick. */
joystick_init();
if (video_init() < 0)
exit (-1);
/* Machine-specific initialization. */
if (machine_init() < 0) {
fprintf(stderr, "Machine initialization failed.\n");
exit(1);
}
/* Handle general-purpose command-line options. */
/* `-autostart' */
if (autostart_string != NULL) {
FILE *autostart_fd;
char *autostart_prg;
char *autostart_file;
char *tmp;
/* Check for image:prg -format. */
tmp = strrchr(autostart_string, ':');
if (tmp) {
autostart_file = stralloc(autostart_string);
autostart_prg = strrchr(autostart_file, ':');
*autostart_prg++ = '\0';
autostart_fd = fopen(autostart_file, "r");
/* Does the image exist? */
if (autostart_fd) {
fclose(autostart_fd);
autostart_autodetect(autostart_file, autostart_prg);
}
else
autostart_autodetect(autostart_string, NULL);
free(autostart_file);
} else {
autostart_autodetect(autostart_string, NULL);
}
}
/* `-8', `-9', `-10' and `-11': Attach specified disk image. */
{
int i;
for (i = 0; i < 4; i++) {
if (startup_disk_images[i] != NULL
&& file_system_attach_disk(i + 8, startup_disk_images[i]) < 0)
fprintf(stderr, "Cannot attach disk image `%s' to unit %d.\n",
startup_disk_images[i], i + 8);
}
}
/* `-1': Attach specified tape image. */
if (startup_tape_image
&& serial_select_file(DT_TAPE, 1, startup_tape_image) < 0)
fprintf(stderr, "Cannot attach tape image `%s'.\n",
startup_tape_image);
putchar ('\n');
/* Let's go... */
maincpu_trigger_reset();
mainloop(0);
printf("perkele!\n");
exit(0); /* never reached */
}
static RETSIGTYPE break64(int sig)
{
#ifdef SYS_SIGLIST_DECLARED
fprintf(stderr, "Received signal %d (%s).\n", sig, sys_siglist[sig]);
#else
fprintf(stderr, "Received signal %d.\n", sig);
#endif
exit (-1);
}
static void exit64(void)
{
/* Disable SIGINT. This is done to prevent the user from keeping C-C
pressed and thus breaking the cleanup process, which might be
dangerous. */
signal(SIGINT, SIG_IGN);
printf("\nExiting...\n");
machine_shutdown();
video_free();
sound_close();
#ifndef __MSDOS__
joystick_close();
#endif
putchar ('\n');
}
void end64()
{
exit (-1);
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.