uae-dap
Version:
Debug Adapter Protocol for Amiga development with FS-UAE or WinUAE
222 lines • 7.75 kB
JavaScript
;
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