home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 8 Other / 08-Other.zip / cpem8010.zip / main.cc < prev    next >
C/C++ Source or Header  |  1995-02-16  |  10KB  |  402 lines

  1. //     $Id: main.cc 1.4 1995/02/16 22:55:51 rg Exp $
  2. //      Copyright (c) 1994 by R. Griech
  3. //
  4. //  CP/M emulator
  5. //  -------------
  6. //  This is the CmdArgs-interpreter and the CCP emulation of the CP/M
  7. //  emulator.
  8. //
  9. //  environment-variablen:
  10. //  ----------------------
  11. //  CPEMOPT     Standardoptionen
  12. //  CPEMAP      Default Mapping
  13. //  CPEMAP0     Mapping für User 0
  14. //    :
  15. //  CPEMAP15    Mapping für User 15
  16. //  CPEMPATH    Path for open file
  17. //
  18.  
  19.  
  20.  
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <ctype.h>
  24. #include <fcntl.h>
  25. #include <io.h>
  26. #include <string.h>
  27. #include <Strng.h>
  28.  
  29. #define DEF_GLOBALS
  30. #include "glob.h"
  31.  
  32. const Regex CpmFName("\\([A-P]:\\)?[-A-Z0-9$?*/]*\\(\\.[-A-Z0-9$?*/]*\\)?",1);
  33. const Regex CpmFNameStart("[-A-Z0-9$?*/]",1);
  34.  
  35.  
  36.  
  37. static void Usage( void )
  38. {
  39.    fprintf( stderr,"\r\nCP/M emulation by rg (%s)\r\n", VERSION);
  40.    fprintf( stderr,"\r\nusage:  cpem [-v[+|-]]                | verbose\r\n" );
  41. //   fprintf( stderr,"\t     [-b bdospage]            | 2hex-digit for bdos beginning\r\n" );
  42.    fprintf( stderr,"\t     [-o[+|-|{num}]]          | buffer output\r\n" );
  43.    fprintf( stderr,"\t     [-t[{term}]]             | terminal name\r\n" );
  44.    fprintf( stderr,"\t     [-u{usernum}]            | cpm user-number\r\n" );
  45.    fprintf( stderr,"\t     [-C]                     | make a core dump after initialization\r\n" );
  46.    fprintf( stderr,"\t     [-NT]                    | show questionable BDOS/BIOS calls\r\n" );
  47.    fprintf( stderr,"\t                              | or not-tested opcodes\r\n" );
  48. #ifdef DEBUG
  49.    fprintf( stderr,"\t     [-B]                     | show BDOS/BIOS calls\r\n" );
  50.    fprintf( stderr,"\t     [-P]                     | show a profile of the Z80 opcodes\r\r\n" );
  51.    fprintf( stderr,"\t     [-S]                     | single step thru program\r\n" );
  52. #endif
  53.    fprintf( stderr,"\t     CPMPROG [cpm-cmdline]    | cpm command line\r\n");
  54.    fprintf( stderr,"\t                              | CPMPROG is an OS/2-path\r\n" );
  55.    fprintf( stderr,"optional environment paras: '%s','%s','%s',\r\n",ARG_OPT,ARG_MAP,ARG_PATH );
  56.    fprintf( stderr,"\t\t\t    'TERM', 'TERMCAP'\r\n" );
  57.    exit(3);
  58. }   // Usage
  59.  
  60.  
  61.  
  62. static void GetArgs( int argc, char *argv[] )
  63. {
  64.    int i;
  65.  
  66.    opt_CoreDump = 0;
  67.    opt_CpmArg   = "";
  68.    opt_CpmCmd   = "";
  69.    opt_OutBuf   = 0;
  70.    opt_Quest    = 0;
  71.    opt_Term     = "";
  72.    opt_User     = 0;
  73.    opt_Verbose  = 0;
  74.    ExitCode     = 0;
  75.    _getcwd2( StartPath,sizeof(StartPath) );
  76.    StartDrive = toupper(*StartPath) -'A';
  77.    opt_BsCalls    = 0;
  78.    opt_SingleStep = 0;
  79.  
  80.    for (i = 1;  i < argc;  i++) {
  81.       if (argv[i][0] == '-') {
  82.          switch (argv[i][1])
  83.         {
  84.         case 't':
  85.            opt_Term = argv[i]+2;
  86.            break;
  87.         case 'o':
  88.            if (opt_OutBuf)
  89.           opt_OutBuf = 0;
  90.            else
  91.           opt_OutBuf = 100;
  92.            if (argv[i][2] == '-')
  93.           opt_OutBuf = 0;
  94.            else if (argv[i][2] == '+')
  95.           opt_OutBuf = 100;
  96.            else if (isdigit(argv[i][2]))
  97.           opt_OutBuf = atoi(argv[i]+2);
  98.            else if (argv[i][2])
  99.           Usage();
  100.            break;
  101.         case 'u':
  102.            opt_User = atoi(argv[i]+2);
  103.            if (opt_User < 0  ||  opt_User > 15)
  104.           Usage();
  105.            break;
  106.         case 'v':
  107.            opt_Verbose = !opt_Verbose;
  108.            if (argv[i][2] == '-')
  109.           opt_Verbose = 0;
  110.            else if (argv[i][2] == '+')
  111.           opt_Verbose = 1;
  112.            else if (argv[i][2])
  113.           Usage();
  114.            break;
  115.         case 'C':
  116.            if ( argv[i][2] )
  117.           Usage();
  118.            opt_CoreDump =1 ;
  119.            break;
  120.         case 'N':
  121.            if ( strcmp(argv[i],"-NT"))
  122.           Usage();
  123.            opt_Quest = 1;
  124.            break;
  125. #ifdef DEBUG
  126.         case 'B':
  127.            if (argv[i][2])
  128.           Usage();
  129.            opt_BsCalls = 1;
  130.            break;
  131.         case 'P':
  132.            if (argv[i][2])
  133.           Usage();
  134.            opt_Profile = 1;
  135.            break;
  136.         case 'S':
  137.            if (argv[i][2])
  138.           Usage();
  139.            opt_SingleStep = 1;
  140.            break;
  141. #endif
  142.         default:
  143.            Usage();
  144.            break;
  145.         }
  146.       }
  147.       else {
  148.          //
  149.          //
  150.          //  erstes Zeichen muß ein Blank sein (wenn was angegeben)
  151.          //
  152.          int j;
  153.          opt_CpmCmd = argv[i++];
  154.          for (j = i;  j < argc;  j++)
  155.             opt_CpmArg = opt_CpmArg + " " + argv[j];
  156.          break;
  157.       }
  158.    }
  159.    if (opt_CpmCmd == "")
  160.       Usage();
  161.  
  162.    opt_CpmCmd.upcase();
  163.    opt_CpmArg.upcase();
  164.    opt_Term.upcase();
  165.    if (opt_Verbose) {
  166.       fprintf( stderr,"CpmCmd:    %s\r\n",(char *)opt_CpmCmd );
  167.       fprintf( stderr,"CpmArg:    %s\r\n",(char *)opt_CpmArg );
  168.       fprintf( stderr,"CpmUser:   %d\r\n",opt_User );
  169.       fprintf( stderr,"CpmTerm:   %s\r\n",(char *)opt_Term );
  170.       fprintf( stderr,"StartPath: %s (extra search for the drive)\r\n",StartPath );
  171.       fprintf( stderr,"CpemPath:  %s\r\n",getenv(ARG_PATH) );
  172.       fprintf( stderr,"OutBufCnt: %d\r\n",opt_OutBuf );
  173.    }
  174. }   // GetArgs
  175.  
  176.  
  177.  
  178. static void GetEnvVars( void )
  179. {
  180.    String Map;
  181.    int n;
  182.    String words[16];
  183.    int  d,u;
  184.    char drv;
  185.  
  186.    //
  187.    //  init of maps
  188.    //
  189.    for (u = 0;  u < 16;  u++) {
  190.       drv = 'A';
  191.       for (d = 0;  d < 16;  d++) {
  192.          CpmMap[u][d] = String(drv) + ":.";
  193.          ++drv;
  194.       }
  195.    }
  196.  
  197.    //
  198.    //  get default map
  199.    //
  200.    Map = getenv( ARG_MAP );
  201.    n = split( Map,words,16,String(";") );
  202.    for (d = 0;  d < n;  d++) {
  203.       if (words[d] != "") {
  204.          for (u = 0;  u < 16;  u++)
  205.             CpmMap[u][d] = words[d];
  206.       }
  207.    }
  208.  
  209.    //
  210.    //  get other maps
  211.    //
  212.    for (u = 0;  u < 16;  u++) {
  213.       char tmp[40];
  214.       sprintf( tmp,"%s%d",ARG_MAP,u );
  215.       Map = getenv( tmp );
  216.       n = split( Map,words,16,String(";") );
  217.       for (d = 0;  d < n;  d++) {
  218.          if (words[d] != "")
  219.             CpmMap[u][d] = words[d];
  220.       }
  221.    }
  222.  
  223.    //
  224.    //  if verbose, then list the maps
  225.    //
  226.    if (opt_Verbose) {
  227.       for (u = 0;  u < 16;  u++) {
  228.          fprintf( stderr,"uMap %2d:  ",u );
  229.          for (d = 0;  d < 16;  d++)
  230.             fprintf( stderr,"%s;",(char *)CpmMap[u][d] );
  231.          fprintf( stderr,"\r\n" );
  232.       }
  233.    }
  234. }   // GetEnvVars
  235.  
  236.  
  237.  
  238. //---------------------------------------------------------
  239.  
  240.  
  241.  
  242. static void SetFcb( unsigned adr, String fn )
  243. {
  244.    String Drive, Ext;
  245.    FCB *fcb = (FCB *)(Mem+adr);
  246.  
  247.    Drive = fn.through(":");
  248.    if (Drive != String(""))
  249.       fn = fn.after(":");
  250.    Ext = fn.after(".",-1);
  251.    if (Ext != String(""))
  252.       fn = fn.before(".");
  253.  
  254.    fcb->dr = 0;
  255.    if (Drive != String(""))
  256.       fcb->dr = Drive[0] - '@';
  257.    memset( fcb->f,' ',sizeof(fcb->f) );
  258.    if (fn != String(""))
  259.       memcpy( fcb->f,&(fn[0]),(fn.length() > 8) ? 8 : fn.length() );
  260.    memset( fcb->t,' ',sizeof(fcb->t) );
  261.    if (Ext != String(""))
  262.       memcpy( fcb->t,&(Ext[0]),(Ext.length() > 3) ? 3 : Ext.length() );
  263.  
  264.    fcb->ex = 0;
  265.    fcb->rc = 0;
  266. }   // SetFcb
  267.  
  268.  
  269.  
  270. static void SetUpCmdLine( void )
  271. {
  272.    if (opt_Verbose)
  273.       fprintf( stderr,"SetUpCmdLine...\r\n");
  274.  
  275.    strncpy( (char *)Mem+DEF_DMA+1,opt_CpmArg,0x7f );
  276.    B(Mem+DEF_DMA) = (strlen(opt_CpmArg) > 0x7f) ? 0x7f : strlen(opt_CpmArg);
  277.    {
  278.       String tmp;
  279.       String FName1, FName2;
  280.  
  281.       tmp = opt_CpmArg.from( CpmFNameStart );
  282.       FName1 = tmp.through( CpmFName );
  283.       if (opt_Verbose)
  284.          fprintf( stderr,"FName1: %s\r\n",(char *)FName1 );
  285.       tmp = tmp.after( FName1 );
  286.       tmp = tmp.from( CpmFNameStart );
  287.       FName2 = tmp.through( CpmFName );
  288.       if (opt_Verbose)
  289.          fprintf( stderr,"FName2: %s\r\n",(char *)FName2 );
  290.       SetFcb( DEF_FCB1,FName1 );
  291.       SetFcb( DEF_FCB2,FName2 );
  292.    }
  293. }   // SetUpCmdLine
  294.  
  295.  
  296.  
  297. static String SearchPath( String Path, String DefExt )
  298. {
  299.    char path[_MAX_PATH];
  300.    char opath[_MAX_PATH];
  301.  
  302.    strcpy( path,Path );
  303.    _defext( path,DefExt );
  304.    _searchenv( path,ARG_PATH,opath );
  305.    return( String(opath) );
  306. }   // SearchPath
  307.  
  308.  
  309.  
  310. static void LoadProg( void )
  311. {
  312.    int hnd, res;
  313.    String p;
  314.  
  315.    if (opt_Verbose)
  316.       fprintf( stderr,"LoadProg...\r\n" );
  317.  
  318.    p = SearchPath( opt_CpmCmd,EXT_CPM );
  319.    if (p == "") {
  320.       fprintf( stderr,"fatal:  '%s' not found.\r\n",(char *)opt_CpmCmd );
  321.       exit(3);
  322.    }
  323.    if (opt_Verbose)
  324.       fprintf( stderr,"loading '%s'\r\n",(char *)p );
  325.  
  326.    hnd = open( p,O_RDONLY | O_BINARY );
  327.    res = read( hnd,Mem+TPA_BEG,BDOS_BEG-TPA_BEG );
  328.    if (res < 0  ||  res >= BDOS_BEG-TPA_BEG) {
  329.       fprintf( stderr,"can't execute '%s'\r\n",(char *)p );
  330.       exit( 3 );
  331.    }
  332.    close( hnd );
  333. }   // LoadProg
  334.  
  335.  
  336.  
  337. static void SetUpRegs( REGS *r )
  338. {
  339.    if (opt_Verbose)
  340.       fprintf( stderr,"SetUpRegs...\r\n" );
  341.    r->w.AF  = 0;
  342.    r->w.BC  = 0;
  343.    r->w.DE  = 0;
  344.    r->w.HL  = 0;
  345.    r->w.AF2 = 0;
  346.    r->w.BC2 = 0;
  347.    r->w.DE2 = 0;
  348.    r->w.HL2 = 0;
  349.    r->w.IR  = 0;
  350.    r->w.IX  = 0;
  351.    r->w.IY  = 0;
  352.    r->w.SP  = BDOS_BEG+0xfe;    // bei *0xfe ist 0 als Rücksprungadresse
  353.    r->w.PC  = TPA_BEG;
  354. }   // SetUpRegs
  355.  
  356.  
  357.  
  358. static void DoCCP( void )
  359. {
  360.    REGS regs;
  361.  
  362.    if (opt_Verbose)
  363.       fprintf( stderr,"DoCCP...\r\n" );
  364.    LoadProg();
  365.    SetUpCmdLine();
  366.    SetUpRegs( ®s );
  367.    Z80Emu( ®s );
  368. }   // DoCCP
  369.  
  370.  
  371.  
  372. int main( int argc, char *argv[] )
  373. {
  374.    _fsetmode( stdout,"b" );
  375.    _fsetmode( stderr,"b" );
  376.  
  377.    _envargs( &argc,&argv,ARG_OPT );
  378.    GetArgs( argc,argv );
  379.    if (opt_OutBuf)
  380.       setvbuf( stdout,NULL,_IOFBF,1024 );
  381.  
  382.    GetEnvVars();
  383.  
  384.    Z80EmuInit();
  385.    BiosInit();
  386.    BdosInit();
  387.  
  388.    if (opt_CoreDump) {
  389.       int Hnd = open("core",O_BINARY|O_TRUNC|O_CREAT|O_WRONLY,0666);
  390.       _core(Hnd);
  391.       fprintf( stderr,"core dumped...\r\n" );
  392.       fprintf( stderr,"please rebind prog with 'emxbind -c cpem'\r\n" );
  393.       exit(3);
  394.    }
  395.  
  396.    DoCCP();
  397.    BdosExit();
  398.    BiosExit();
  399.    Z80EmuExit();
  400.    exit( ExitCode );
  401. }   // main
  402.