home *** CD-ROM | disk | FTP | other *** search
/ ftp.whtech.com / ftp.whtech.com.7z / ftp.whtech.com / emulators / v9t9 / linux / sources / V9t9 / source / v9t9.c < prev    next >
Encoding:
C/C++ Source or Header  |  2006-10-19  |  11.4 KB  |  615 lines

  1.  
  2. /*
  3.         V9t9.C
  4.         ======
  5.  
  6. */
  7.  
  8. #define __V9t9__
  9.  
  10. #include "v9t9_common.h"
  11.  
  12. #include "memory.h"
  13. #include "9900.h"
  14. #include "9901.h"
  15. #include "vdp.h"
  16. #include "video.h"
  17. #include "sound.h"
  18. #include "speech.h"
  19. #include "emulate.h"
  20. #include "keyboard.h"
  21. #include "dsr.h"
  22. #include "v9t9.h"
  23. #include "timer.h"
  24. #include "cru.h"
  25. #include "roms.h"
  26. #include "moduledb.h"
  27. #include "system.h"
  28. #include "command.h"
  29. #include "moduleconfig.h"
  30. #include "debugger.h"
  31. #include "config.h"
  32. #ifdef EMU_DISK_DSR
  33. #include "fiad.h"
  34. #endif
  35.  
  36. DECL_SYMBOL_ACTION(dump_config);
  37.  
  38. OSPathSpec  v9t9_homedir;
  39. OSSpec        v9t9_progspec;
  40. int            v9t9_argc;
  41. char        **v9t9_argv;
  42.  
  43. int         v9t9_preconfiginit(void);
  44.  
  45. static    int         preconfiginit(void);
  46. static    int         postconfiginit(void);
  47. static    void        shutdown(void);
  48.  
  49. char *sessionspath, *configspath;
  50.  
  51. #include "v9t9_common.h"
  52.  
  53. static int  dying = 0;
  54.  
  55. static void
  56. __die(void)
  57. {
  58.     v9t9_term(0);
  59. }
  60.  
  61. void v9t9_sigint(int ignored)
  62. {    
  63.     stateflag |= ST_STOP | ST_TERMINATE;
  64. }
  65.  
  66. void v9t9_sigterm(int ignored)
  67. {
  68.     TM_Stop();
  69.     v9t9_restop();
  70.     v9t9_term(ignored);
  71.     exit(ignored);
  72. }
  73.  
  74. #define _L     LOG_INTERNAL | LOG_INFO
  75.  
  76. static void v9t9_help(void)
  77. {
  78.     logger(LOG_USER|LOG_ERROR,
  79.            "\n"
  80.            "V9t9: TI Emulator! v7.0\n"
  81.            "\n"
  82.            "v9t9 [options] [file...]\n"
  83.            "\n"
  84.            "-h:      display help\n"
  85.            "-r:      reboot instead of loading previous 'session.cnf'\n"
  86.            "-e cmds: execute 'cmds'\n"
  87.            "file:    load config or session file\n"
  88.            "\n");
  89. }
  90.  
  91. int 
  92. v9t9_config(int argc, char **argv)
  93. {
  94.     v9t9_argc = argc;
  95.     v9t9_argv = argv;
  96.  
  97.     OS_InitProgram(&v9t9_argc, &v9t9_argv);
  98.  
  99.     sessionspath = xstrdup(".");
  100.     configspath = xstrdup(".");
  101.     xminit();
  102.  
  103.     OS_GetCWD(&v9t9_homedir);
  104.     OS_FindProgram(v9t9_argv[0], &v9t9_progspec);
  105.     return 1;
  106. }
  107.  
  108. int        
  109. v9t9_init(void)
  110. {
  111.     int load_std_session = 1, do_reset = 0;
  112.     char *last_command;
  113.     int argc; char **argv;
  114.  
  115.     command_init();
  116.     log_add_commands();
  117.  
  118.     TM_Init();
  119.  
  120.     vdpinit();
  121.     cruinit();
  122.     if (!setup_9901())
  123.         return 0;
  124.  
  125.     sound_init();
  126.     modules_init();
  127.     debugger_init();
  128. #ifdef EMU_DISK_DSR
  129.     fiad_set_logger(logger);
  130. #endif
  131.  
  132.     if (!preconfiginit())
  133.         return 0;
  134.  
  135.     // try to load config from cwd and then v9t9 home dir
  136.     if (!config_load_file(".", "v9t9.cnf", false /*session*/)) 
  137.         config_load_file(OS_PathSpecToString1(&v9t9_homedir), 
  138.                          "v9t9.cnf", false);
  139.  
  140.     // In case they forgot the "ReadModuleDatabase" command
  141.     if (moddb == NULL && !modules_init_db("modules.inf"))
  142.     {
  143.         logger(LOG_ROMS|LOG_USER|LOG_ERROR, 
  144.                "Cannot find 'modules.inf'; no modules available\n");
  145.         return 0;
  146.     }
  147.  
  148.  
  149.     vmClearUserFlagsOnModules();
  150.  
  151.     if (!postconfiginit())
  152.         return 0;
  153.  
  154.     last_command = 0L;
  155.  
  156.     argc = v9t9_argc;
  157.     argv = v9t9_argv;
  158.  
  159.     while (--argc > 0) {
  160.         if (last_command && !command_parse_text(last_command))
  161.             return 0;
  162.         last_command = 0L;
  163.  
  164.         ++argv;
  165.         if (strncmp(*argv, "-h", 2) == 0) {
  166.             v9t9_help();
  167.             return 0;
  168.         } else if (strncmp(*argv, "-e", 2) == 0) {
  169.             if (!argc) {
  170.                 logger(_L|LOG_USER|LOG_ERROR, "The '%s' option needs an argument\n", *argv);
  171.                 v9t9_help();
  172.                 return 0;
  173.             }
  174.             argc--;
  175.             last_command = *++argv;
  176.         } else if (strncmp(*argv, "-r", 2) == 0) {
  177.             do_reset = 1;
  178.             load_std_session = 0;
  179.         } else if (**argv == '-') {
  180.             logger(_L|LOG_USER|LOG_ERROR, "Unknown option '%s'\n", *argv);
  181.             v9t9_help();
  182.             return 0;
  183.         } else {
  184.             do_reset = 0;
  185.             load_std_session = 0;
  186.             if (!config_load_file(sessionspath, *argv, false) &&
  187.                 !config_load_file(configspath, *argv, true))
  188.             {
  189.                 do_reset = 1;
  190.                 load_std_session = 1;
  191.             }
  192.         }
  193.     }
  194.  
  195.     if (load_std_session) {
  196.         // try to load session from cwd and v9t9 home
  197.         if (!config_load_file(sessionspath, "session.cnf", true /*session*/)) {
  198.             emulate_setup_for_restore();
  199.         }
  200.     }
  201.    
  202.     if (last_command && !command_parse_text(last_command)) {
  203.         return 0;
  204.     }
  205.  
  206.     if (do_reset) {
  207.            command_parse_text("ResetComputer\n");
  208.     } else {
  209.         emulate_setup_for_restore();
  210.     }
  211.  
  212.     atexit(__die);
  213.  
  214.     dying = 0;
  215.     return 1;
  216. }
  217.  
  218. int
  219. v9t9_execute(void)
  220. {
  221.     int ret = vmCPU->m.cpu->execute();
  222.     return ret;
  223. }
  224.  
  225. void
  226. v9t9_term(int exitcode)
  227. {
  228.     if (dying)
  229.         return;
  230.  
  231.     dying = 1;
  232.  
  233.     TM_Stop();
  234.     
  235.     v9t9_restop();
  236.     shutdown();
  237.  
  238.     termlog();
  239. }
  240.  
  241. static int
  242. preconfiginit(void)
  243. {
  244.     static int  (*preconfiginitlist[]) (void) = {
  245.         v9t9_preconfiginit,
  246.         keyboard_preconfiginit,
  247.         speech_preconfiginit,    /* after sound_... */
  248.         NULL
  249.     };
  250.  
  251.     int         (**ptr) (void) = preconfiginitlist;
  252.  
  253.     if (!vmModulesInit())
  254.         return 0;
  255.  
  256.     if (!vmRegisterModules(installed_modules))
  257.         return 0;
  258.  
  259.     vmAddModuleCommands();
  260.  
  261.     if (!vmDetectModules())
  262.         return 0;
  263.  
  264.  
  265.     while (*ptr)
  266.         if ((**ptr) () == 0)
  267.             return 0;
  268.         else
  269.             ptr++;
  270.  
  271.     if (!vmInitModules())
  272.         return 0;
  273.  
  274.     if (!vmSelectStartupModules())
  275.         return 0;
  276.  
  277.     return 1;
  278. }
  279.  
  280. static int
  281. postconfiginit(void)
  282. {
  283.     static int  (*postconfiginitlist[]) (void) = {
  284.         speech_postconfiginit,    /* after sound_... */
  285.         keyboard_postconfiginit,
  286.         NULL
  287.     };
  288.  
  289.     int (**ptr) (void);
  290.     int ret = 1;
  291.  
  292.     if (!vmEnableModules())
  293.         ret = 0;
  294.  
  295.     ptr = postconfiginitlist;
  296.     while (*ptr)
  297.         if ((**ptr) () == 0)
  298.             ret = 0;
  299.         else
  300.             ptr++;
  301.  
  302.     return ret;
  303. }
  304.  
  305. int         restarted = 0;
  306.  
  307. #define    RS_VIDEO 0x1
  308. //#define RS_EMULATE 0x2
  309. #define RS_KEYBOARD 0x4
  310. #define RS_SOUND 0x8
  311. #define RS_DSR 0x10
  312. #define RS_SPEECH 0x20
  313.  
  314. int
  315. v9t9_restart(void)
  316. {
  317.     static struct {
  318.         int         (*func) (void);
  319.         int         mask;
  320.         char       *desc;
  321.     } restartlist[] = {
  322.         {
  323.         video_restart, RS_VIDEO, "Video"}, {
  324.         keyboard_restart, RS_KEYBOARD, "Keyboard"}, {
  325.         sound_restart, RS_SOUND, "Sound"}, {
  326.         speech_restart, RS_SPEECH, "Speech"},    /* after sound_... */
  327.         {
  328.         NULL, 0, ""}
  329.     }, *ptr;
  330.     int ret = 1;
  331.  
  332.     if (!vmRestartModules())
  333.         ret = 0;
  334.  
  335.     ptr = restartlist;
  336.  
  337.     while (ptr->func) {
  338.         if ((ptr->func) () == 0)
  339.             ret = 0;
  340.         else {
  341.  
  342. /*            log("Restarted %s\n",ptr->desc);*/
  343.             restarted |= ptr->mask;
  344.             ptr++;
  345.         }
  346.     }
  347.  
  348.  
  349.     TM_Start();
  350.     vdpcompleteredraw();
  351.     return ret;
  352. }
  353.  
  354.  
  355. void
  356. v9t9_restop(void)
  357. {
  358.     static struct {
  359.         void        (*func) (void);
  360.         int         mask;
  361.         char       *desc;
  362.     } restoplist[] = {
  363.         { video_restop, RS_VIDEO, "Video"},
  364.         { keyboard_restop, RS_KEYBOARD, "Keyboard"}, 
  365.         { sound_restop, RS_SOUND, "Sound"}, 
  366.         { speech_restop, RS_SPEECH, "Speech"},    /* after sound_... */
  367.         {
  368.         NULL, 0, ""}
  369.     }, *ptr;
  370.  
  371.     TM_Stop();
  372.     vmRestopModules();
  373.  
  374.     ptr = restoplist;
  375.     while (ptr->func) {
  376.         if (restarted & ptr->mask) {
  377.             ptr->func();
  378.  
  379. /*            log("Restopped %s\n",ptr->desc);*/
  380.         }
  381.         ptr++;
  382.     }
  383.  
  384.     restarted = 0;
  385. }
  386.  
  387.  
  388. static void
  389. shutdown(void)
  390. {
  391.     vmDisableModules();
  392.  
  393.     TM_Kill();
  394.     vmTermModules();
  395.  
  396.     speech_shutdown();
  397. }
  398.  
  399. /****************************************/
  400.  
  401. static
  402. DECL_SYMBOL_ACTION(v9t9_display_help)
  403. {
  404.     command_help();
  405.     return 1;
  406. }
  407.  
  408. static
  409. DECL_SYMBOL_ACTION(v9t9_exit_interactive)
  410. {
  411.     stateflag &= ~ST_INTERACTIVE;
  412.     return 1;
  413. }
  414.  
  415. static
  416. DECL_SYMBOL_ACTION(v9t9_die)
  417. {
  418.     stateflag |= ST_TERMINATE;
  419.     stateflag &= ~ST_INTERACTIVE;
  420.     return 1;
  421. }
  422.  
  423. static
  424. DECL_SYMBOL_ACTION(v9t9_quit)
  425. {
  426.     //    Save session on a positive exit
  427.     config_save_file(sessionspath, "session.cnf", true /*session*/);
  428.  
  429.     stateflag |= ST_TERMINATE;
  430.     stateflag &= ~ST_INTERACTIVE;
  431.     return 1;
  432. }
  433.  
  434. int
  435. v9t9_preconfiginit(void)
  436. {
  437.     command_symbol_table *v9t9commands =
  438.         command_symbol_table_new("Major Emulator Commands",
  439.                                  "These are general commands to control the emulator",
  440.  
  441.          command_symbol_new("Help",
  442.                             "Display command help",
  443.                             c_DONT_SAVE,
  444.                             v9t9_display_help,
  445.                             NULL /* ret */ ,
  446.                             NULL    /* args */
  447.                             ,
  448.  
  449.         command_symbol_new("Interactive",
  450.                              "Control whether emulator waits for user commands",
  451.                              c_DONT_SAVE,
  452.                              NULL /* action */ ,
  453.                              RET_FIRST_ARG,
  454.                              command_arg_new_toggle
  455.                              ("on|off",
  456.                               "if 'on', emulation will halt; "
  457.                               "if 'off', emulation continues at end of command list",
  458.                               NULL /* action */ ,
  459.                               ARG_NUM(stateflag),
  460.                               ST_INTERACTIVE,
  461.                               NULL /* next */ )
  462.                              ,
  463.  
  464.       command_symbol_new("Exit",
  465.                               "Exit from interactive mode (same as 'Interactive=off')",
  466.                               c_DONT_SAVE,
  467.                               v9t9_exit_interactive,
  468.                               NULL /* ret */ ,
  469.                               NULL    /* args */
  470.                               ,
  471.  
  472.       command_symbol_new ("Die",
  473.                                "Exit V9t9 without saving session",
  474.                                c_DONT_SAVE,
  475.                                v9t9_die,
  476.                                NULL /* ret */ ,
  477.                                NULL    /* args */
  478.                                ,
  479.  
  480.       command_symbol_new ("Quit|Bye",
  481.                                "Exit V9t9 and save session",
  482.                                c_DONT_SAVE,
  483.                                v9t9_quit,
  484.                                NULL /* ret */ ,
  485.                                NULL    /* args */
  486.                                ,
  487.  
  488.       command_symbol_new ("HomeDirectory|Home",
  489.                                 "Directory where V9t9 started",
  490.                                 c_DONT_SAVE,
  491.                                 NULL /* action */ ,
  492.                                 command_arg_new_pathspec
  493.                                 ("dir", "directory",
  494.                                  NULL /* action */ ,
  495.                                  &v9t9_homedir,
  496.                                  NULL /* next */ ),
  497.                                 NULL    /* args */
  498.                                 ,
  499.  
  500.       command_symbol_new
  501.          ("ConfigsPath",
  502.           "Set directory list for searching and saving configuration files; "
  503.           "when saving, new files written to first directory and old files "
  504.           "are overwritten where found",
  505.           c_STATIC|c_CONFIG_ONLY,
  506.           NULL /* action*/,
  507.           RET_FIRST_ARG,
  508.           command_arg_new_string
  509.             ("path",
  510.              "list of directories "
  511.              "separated by one of these characters: '"
  512.              OS_ENVSEPLIST "'",
  513.              NULL    /* action */,
  514.              NEW_ARG_STRBUF(&configspath),
  515.              NULL /* next */ )
  516.           ,
  517.  
  518.       command_symbol_new
  519.          ("SessionsPath",
  520.           "Set directory list for searching and saving session files; "
  521.           "when saving, new files written to first directory and old files "
  522.           "are overwritten where found",
  523.           c_STATIC|c_CONFIG_ONLY,
  524.           NULL /* action*/,
  525.           RET_FIRST_ARG,
  526.           command_arg_new_string
  527.             ("path",
  528.              "list of directories "
  529.              "separated by one of these characters: '"
  530.              OS_ENVSEPLIST "'",
  531.              NULL    /* action */,
  532.              NEW_ARG_STRBUF(&sessionspath),
  533.              NULL /* next */ )
  534.           ,
  535.  
  536.      command_symbol_new("SaveConfigFile",
  537.           "Save current configuration settings to 'file'",
  538.           c_DONT_SAVE,
  539.           save_config  /* action */ ,
  540.           NULL    /* ret */,
  541.           command_arg_new_string
  542.           ("file",
  543.            "name of config file",
  544.            NULL  /* action */ ,
  545.            NEW_ARG_STR(256),
  546.            NULL    /* next */
  547.           ),
  548.  
  549.      command_symbol_new("LoadConfigFile|ReadModuleDatabase",
  550.           "Load configuration settings from 'file', "
  551.           "or merge module list from 'file'",
  552.           c_DONT_SAVE,
  553.           load_config  /* action */ ,
  554.           NULL    /* ret */,
  555.           command_arg_new_string
  556.           ("file",
  557.            "name of config file or modules.inf file",
  558.            NULL  /* action */ ,
  559.            NEW_ARG_STR(256),
  560.            NULL    /* next */
  561.           ),
  562.  
  563.      command_symbol_new("SaveSessionFile",
  564.           "Save current configuration settings and machine state to 'file'",
  565.           c_DONT_SAVE,
  566.           save_session  /* action */ ,
  567.           NULL    /* ret */,
  568.           command_arg_new_string
  569.           ("file",
  570.            "name of config file",
  571.            NULL  /* action */ ,
  572.            NEW_ARG_STR(256),
  573.            NULL    /* next */
  574.           ),
  575.  
  576.      command_symbol_new("LoadSessionFile",
  577.           "Load configuration settings and machine state from 'file'",
  578.           c_DONT_SAVE,
  579.           load_session  /* action */ ,
  580.           NULL    /* ret */,
  581.           command_arg_new_string
  582.           ("file",
  583.            "name of config file",
  584.            NULL  /* action */ ,
  585.            NEW_ARG_STR(256),
  586.            NULL    /* next */
  587.           ),
  588.  
  589.      command_symbol_new("SaveScreenShot",
  590.           "Take a screenshot and save to 'file' or an autogenerated name",
  591.           c_DONT_SAVE,
  592.           vdp_take_screenshot  /* action */ ,
  593.           NULL    /* ret */,
  594.           command_arg_new_string
  595.           ("file",
  596.            "name of file to write, or \"\" to use an automatic name "
  597.            "in the current directory",
  598.            NULL  /* action */ ,
  599.            NEW_ARG_STR(256),
  600.            NULL    /* next */
  601.           ),
  602.  
  603.     NULL /* next */ ))))))))))))),
  604.  
  605.     NULL /* sub */ ,
  606.  
  607.     NULL    /* next */
  608.     );
  609.  
  610.     configspath = xstrdup(OS_CWDSTR);
  611.     sessionspath = xstrdup(OS_CWDSTR);
  612.     command_symbol_table_add_subtable(universe, v9t9commands);
  613.     return 1;
  614. }
  615.