UNPKG

uae-dap

Version:

Debug Adapter Protocol for Amiga development with FS-UAE or WinUAE

222 lines 7.75 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.WinUAE = exports.FsUAE = exports.Emulator = void 0; const debugadapter_1 = require("@vscode/debugadapter"); const cp = __importStar(require("child_process")); const fs = __importStar(require("fs")); const path_1 = require("path"); const files_1 = require("./utils/files"); const isWin = process.platform === "win32"; /** * Base emulator class */ class Emulator { /** * Factory */ static getInstance(type) { switch (type) { case "fs-uae": return new FsUAE(); case "winuae": return new WinUAE(); } } /** * Start emulator with remote debugger */ debug(opts) { const args = [...opts.args, ...this.debugArgs(opts)]; return this.run({ ...opts, args }); } /** * Start emulator process */ run(opts) { const customBin = opts.bin; const defaultBin = this.defaultBin(); let bin = customBin || defaultBin; if (customBin && !this.checkBin(customBin)) { debugadapter_1.logger.warn("Defaulting to bundled emulator binary"); bin = defaultBin; } if (!this.checkBin(bin)) { throw new Error("[EMU] No suitable emulator binary"); } const cwd = (0, path_1.dirname)(bin); const args = [...opts.args, ...this.runArgs(opts)]; const env = { ...process.env, LD_LIBRARY_PATH: ".", // Allow Linux fs-uae to find bundled .so files }; debugadapter_1.logger.log(`[EMU] Starting emulator: ${bin} ${args.join(" ")}`); return new Promise((resolve, reject) => { this.childProcess = cp.spawn(bin, args, { cwd, env }); this.childProcess.once("spawn", resolve); this.childProcess.once("error", reject); this.childProcess.once("exit", () => { debugadapter_1.logger.log(`[EMU] Emulator quit`); if (opts.onExit) { opts.onExit(); } this.childProcess = undefined; }); const onData = (data) => debugadapter_1.logger.log("[EMU] " + data.toString().trim()); this.childProcess.stdout?.on("data", onData); this.childProcess.stderr?.on("data", onData); }); } /** * Check suitablity of emulator binary path */ checkBin(bin) { // Ensure binary file exists if (!fs.existsSync(bin)) { debugadapter_1.logger.error(`Emulator binary not found at '${bin}'`); return false; } // Ensure binary is executable for POSIX if (!isWin) { try { fs.accessSync(bin, fs.constants.X_OK); } catch (_) { debugadapter_1.logger.log("Emulator binary '${executable}' not executable - trying to chmod"); try { fs.chmodSync(bin, 0o755); } catch (_) { debugadapter_1.logger.error(`The emulator binary '${bin}' is not executable and permissions could not be changed`); return false; } } } return true; } /** * Terminate process */ destroy() { if (this.childProcess) { if (!this.childProcess.kill("SIGKILL")) { debugadapter_1.logger.log(`The emulator could not be stopped with SIGKILL`); if (this.childProcess.pid) { debugadapter_1.logger.log(`Killing process`); process.kill(-this.childProcess.pid); } } this.childProcess = undefined; } } } exports.Emulator = Emulator; /** * FS-UAE emaultor program */ class FsUAE extends Emulator { defaultBin() { const binDir = (0, files_1.findBinDir)(); // Choose default binary based on platform let bin = (0, path_1.join)(binDir, "fs-uae", `fs-uae-${process.platform}_x64`); if (isWin) { bin += ".exe"; } return bin; } checkBin(bin) { const valid = super.checkBin(bin); if (!valid) { return false; } // Check version string to ensure correct patched version const output = cp.spawnSync(bin, ["--version"]); const version = output.stdout.toString().trim(); debugadapter_1.logger.log("[EMU] Version: " + version); if (!version.includes("remote_debug")) { debugadapter_1.logger.warn("FS-UAE must be patched 4.x version. Ensure you're using the latest binaries."); return false; } return true; } runArgs(opts) { const args = []; if (opts.mountDir && !opts.args.some((v) => v.startsWith("--hard_drive_0") || v.match(/.adf/i))) { args.push("--hard_drive_0=" + opts.mountDir); } return args; } debugArgs(opts) { const args = []; if (!opts.args.some((v) => v.startsWith("--remote_debugger="))) { args.push("--remote_debugger=60"); } if (!opts.args.some((v) => v.startsWith("--remote_debugger_port"))) { args.push("--remote_debugger_port=" + opts.serverPort); } if (!opts.args.some((v) => v.startsWith("--remote_debugger_trigger"))) { args.push("--remote_debugger_trigger=" + opts.remoteProgram); } return args; } } exports.FsUAE = FsUAE; /** * WinUAE Emulator program */ class WinUAE extends Emulator { defaultBin() { const binDir = (0, files_1.findBinDir)(); return (0, path_1.join)(binDir, "winuae", `winuae.exe`); } checkBin(bin) { if (!isWin) { debugadapter_1.logger.warn("WinUAE only supported on Windows"); return false; } return super.checkBin(bin); } runArgs(opts) { const args = []; if (opts.mountDir && !opts.args.some((v) => v.startsWith("filesystem") || v.match(/.adf/i))) { args.push("-s", "filesystem=rw,dh0:$" + opts.mountDir); } return args; } debugArgs(opts) { const args = []; if (!opts.args.some((v) => v.startsWith("debugging_features"))) { args.push("-s", "debugging_features=gdbserver"); } if (!opts.args.some((v) => v.startsWith("debugging_trigger"))) { args.push("-s", "debugging_trigger=" + opts.remoteProgram); } return args; } } exports.WinUAE = WinUAE; //# sourceMappingURL=emulator.js.map