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)); } }; }
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; } }