Beispiel #1
0
        public Machine()
        {
            if (!System.Diagnostics.Debugger.IsAttached)
            {
                AppDomain currentDomain = AppDomain.CurrentDomain;
                currentDomain.UnhandledException += UnhandledException;
            }
            else
            {
                enableDebugger = true;
                logExecution   = true;
            }

            _pathMapper        = new PathMapper(this);
            _globalHeap        = new GlobalHeap(this);
            _stringHeap        = new StringHeap(this);
            _moduleManager     = new ModuleManager(this);
            _messaging         = new Messaging(this);
            _variableResolver  = new VariableResolver();
            _expressionContext = new ExpressionContext(this);
            _symbolResolver    = new SymbolResolver(this);
            _stackWalker       = new StackWalker(this);
            _expressionContext.PushSymbolScope(_symbolResolver);

            this.MemoryBus = _globalHeap;

            RegisterVariables();

            // Create system heaps
            _systemCodeSelector = _globalHeap.Alloc("System Thunks", 0, 0x10000);
            _globalHeap.SetSelectorAttributes(_systemCodeSelector, true, true);
            _systemDataHeap = _globalHeap.CreateLocalHeap("System Local Heap", 0);
            _globalHeap.SetSelectorAttributes(_systemDataHeap.GlobalHandle, false, false);

            // Initialise the system return thunk
            CreateSysRetThunk();

            // Creae DOS Api handler
            _dos = new DosApi(this, this);

            // Load standard modules
            _kernel = _moduleManager.LoadModule(new Kernel()) as Kernel;
            _user   = _moduleManager.LoadModule(new User()) as User;
            _moduleManager.LoadModule(new Gdi());
            _moduleManager.LoadModule(new MMSystem());
            _moduleManager.LoadModule(new Keyboard());
//            _moduleManager.LoadModule(new Shell());
            _moduleManager.LoadModule(new DdeML());
            _moduleManager.LoadModule(new Sound());

            _disassembler = new Disassembler(this);

            this.InstructionHook = () =>
            {
                if (logExecution)
                {
                    _disassembled = null;
                    Log.WriteLine(_variableResolver.ResolveTokenizedString(_logExecutionFormat));
                }
            };
        }
Beispiel #2
0
        public int RunProgram(string programName, string[] commandArgs, int nCmdShow)
        {
            try
            {
                var cl = new Utils.CommandLine(commandArgs);

                // Store the program path
                ProgramHostPath = System.IO.Path.GetFullPath(programName);

                // Work out base name for the program (we'll use this to merge program specific configuration settings)
                var baseProgramName = System.IO.Path.GetFileNameWithoutExtension(programName).ToLowerInvariant();

                // Create merged config
                var config = new Dictionary <string, object>();
                MergeConfig(cl.Config, baseProgramName, config, VariableResolver.Resolve("$(Win3muFolder)\\config.json"));
                MergeConfig(cl.Config, baseProgramName, config, VariableResolver.Resolve("$(AppData)\\Win3mu\\config.json"));
                MergeConfig(cl.Config, baseProgramName, config, System.IO.Path.Combine(System.IO.Path.GetDirectoryName(programName), "config.json"));
                MergeConfig(cl.Config, baseProgramName, config, System.IO.Path.ChangeExtension(programName, ".json"));
                Json.ReparseInto(this, config);

                // Need console?
                if (enableDebugger || consoleLogger)
                {
                    ConsoleHelper.CreateConsole();
                }

                // Initialize logging
                Log.Init(consoleLogger, VariableResolver.Resolve(fileLogger));
                _pathMapper.Prepare(mountPoints);
                _dos.EnableApiLogging  = logApiCalls;
                _dos.EnableFileLogging = logFileOperations;

                // Log configuration
                Log.WriteLine("Configuration:");
                Log.WriteLine(Json.Format(config));
                Log.WriteLine("");

                // Connect debugger?
                if (enableDebugger)
                {
                    // Connect debugger
                    _debugger     = new Debugging.Win3muDebugger(this);
                    _debugger.CPU = this;
                    _debugger.ExpressionContext = ExpressionContext;
                    _debugger.CommandDispatcher.RegisterCommandHandler(new Win3muCore.Debugging.DebuggerCommandExtensions(this));
                    _debugger.SettingsFile = VariableResolver.Resolve(DebuggerSettingsFile);

                    if (DebuggerCommands != null)
                    {
                        foreach (var cmd in DebuggerCommands)
                        {
                            _debugger.CommandDispatcher.EnqueueCommand(cmd);
                        }
                    }

                    // Break immediately?
                    if (cl.Break || breakOnLoad || DebuggerCommands != null && DebuggerCommands.Count > 0)
                    {
                        _debugger.Break();
                    }
                }

                // Setup execution logging
                _logExecutionFormat = VariableResolver.TokenizeString(logExecutionFormat);

                // Map the program name to 8.3 name
                var programName16 = _pathMapper.MapHostToGuest(programName, false);

                // Set the current directory
                _dos.WorkingDirectory = System.IO.Path.GetDirectoryName(programName16);

                // Look for unqualified dll paths in same folder as the program
                _moduleManager.SetProcessPath(System.IO.Path.GetDirectoryName(programName16));

                // Load the executable module
                ProcessModule = _moduleManager.LoadModule(programName16) as Module16;
                ProcessModule.PrepareRun(this, cl.CommandTail16, nCmdShow);

                Log.WriteLine("Starting program...");

                _stackWalker.EnterTransition("WinMain");

                try
                {
                    // Run until finished
                    while (!_finished)
                    {
                        Run(1000000);
                    }
                }
                finally
                {
                    _stackWalker.LeaveTransition();
                }

                Log.WriteLine("Program finished with exit code {0}.", _exitCode);

                ProcessModule = null;

                Log.Flush();

                return(_exitCode);
            }
            catch (Exception x)
            {
                Log.WriteLine(x.Message);
                Log.Flush();
                throw;
            }
        }