@henols/c64-re-tools 1.0.0 → 2.0.0-rc.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +154 -37
- package/distribution/package.ts +21 -0
- package/distribution/plugin.ts +122 -0
- package/package.json +34 -40
- package/skills/c64-assembler/SKILL.md +76 -0
- package/skills/c64-assembler/scripts/assemble.ts +110 -0
- package/skills/c64-assembler/scripts/compare.ts +84 -0
- package/skills/c64-basic/SKILL.md +66 -0
- package/skills/c64-basic/scripts/basic.ts +46 -0
- package/skills/c64-disk/SKILL.md +93 -0
- package/skills/c64-disk/scripts/containers.ts +124 -0
- package/skills/c64-disk/scripts/disk.ts +120 -0
- package/skills/c64-emulator/SKILL.md +134 -0
- package/skills/c64-knowledge/SKILL.md +166 -0
- package/skills/c64-knowledge/scripts/knowledge.ts +492 -0
- package/skills/c64-memory-map/SKILL.md +79 -0
- package/skills/c64-memory-map/scripts/memmap.ts +92 -0
- package/skills/c64-provenance/SKILL.md +110 -0
- package/skills/c64-provenance/scripts/compare.ts +152 -0
- package/skills/c64-provenance/scripts/provenance.ts +334 -0
- package/skills/c64-provenance/scripts/runtime.ts +191 -0
- package/skills/c64-provenance/scripts/separate.ts +140 -0
- package/skills/c64-reverse-engineering/SKILL.md +144 -0
- package/skills/c64-source/SKILL.md +126 -0
- package/skills/c64-source/scripts/generate.ts +490 -0
- package/skills/c64-source/scripts/loader.ts +571 -0
- package/skills/c64-source/scripts/opcodes.ts +61 -0
- package/skills/c64-source/scripts/source.ts +595 -0
- package/skills/c64-static-analysis/SKILL.md +119 -0
- package/skills/c64-static-analysis/scripts/analyze.ts +275 -0
- package/skills/c64-static-analysis/scripts/coverage.ts +78 -0
- package/skills/c64-static-analysis/scripts/findings.ts +75 -0
- package/skills/c64-static-analysis/scripts/idioms.ts +149 -0
- package/skills/c64-static-analysis/scripts/instructions.ts +105 -0
- package/skills/c64-testing/SKILL.md +103 -0
- package/skills/c64-testing/references/scenario-format.md +116 -0
- package/skills/c64-testing/scripts/checklist.ts +51 -0
- package/skills/c64-testing/scripts/run.ts +189 -0
- package/skills/c64-testing/scripts/scenario.ts +493 -0
- package/skills/c64-testing/scripts/test.ts +65 -0
- package/skills/c64-unpacker/SKILL.md +135 -0
- package/skills/c64-unpacker/scripts/evidence.ts +207 -0
- package/skills/c64-unpacker/scripts/loads.ts +209 -0
- package/skills/c64-unpacker/scripts/machine.ts +80 -0
- package/skills/c64-unpacker/scripts/stages.ts +130 -0
- package/skills/c64-unpacker/scripts/unpack.ts +683 -0
- package/src/c64.ts +411 -0
- package/src/cli/ap-sdk.ts +44 -0
- package/src/cli/cleanup.ts +194 -0
- package/src/cli/main.ts +125 -0
- package/src/cli/status.ts +61 -0
- package/src/host/main.ts +134 -0
- package/src/host/server.ts +392 -0
- package/src/host/tools/c1541.ts +284 -0
- package/src/host/tools/index.ts +35 -0
- package/src/host/tools/petcat.ts +77 -0
- package/src/host/tools/status.ts +47 -0
- package/src/host/tools/version.ts +41 -0
- package/src/host/vice/adapter.ts +804 -0
- package/src/host/vice/binary-monitor.ts +389 -0
- package/src/host/vice/chips.ts +118 -0
- package/src/host/vice/connect.ts +34 -0
- package/src/host/vice/process.ts +413 -0
- package/src/host/vice/screen.ts +184 -0
- package/src/host/vice/session.ts +1426 -0
- package/src/host/vice/text-monitor.ts +223 -0
- package/src/host-client/autostart.ts +55 -0
- package/src/host-client/connect.ts +241 -0
- package/src/host-client/coverage.ts +63 -0
- package/src/host-client/steps.ts +170 -0
- package/src/host-client/tools.ts +89 -0
- package/src/host-client/transfer.ts +126 -0
- package/src/host-client/vice-session.ts +316 -0
- package/src/knowledge/database.ts +132 -0
- package/src/knowledge/history.ts +163 -0
- package/src/knowledge/import.ts +391 -0
- package/src/knowledge/read.ts +342 -0
- package/src/knowledge/schema.ts +229 -0
- package/src/knowledge/write.ts +663 -0
- package/src/mcp/main.ts +134 -0
- package/src/mcp/output.ts +32 -0
- package/src/mcp/server.ts +316 -0
- package/src/mcp/tools/debug.ts +327 -0
- package/src/mcp/tools/execution.ts +117 -0
- package/src/mcp/tools/input.ts +72 -0
- package/src/mcp/tools/machine.ts +100 -0
- package/src/mcp/tools/media.ts +129 -0
- package/src/mcp/tools/memory.ts +250 -0
- package/src/mcp/tools/video.ts +271 -0
- package/src/native/acme.ts +116 -0
- package/src/native/discover.ts +179 -0
- package/src/native/dxa.ts +166 -0
- package/src/native/ghidra/analyze.ts +86 -0
- package/src/native/ghidra/index.ts +173 -0
- package/src/native/ghidra/language/c64rt_6510.cspec +34 -0
- package/src/native/ghidra/language/c64rt_6510.ldefs +15 -0
- package/src/native/ghidra/language/c64rt_6510.pspec +15 -0
- package/src/native/ghidra/language/c64rt_6510.slaspec +596 -0
- package/src/native/ghidra/scripts/C64Export.java +274 -0
- package/src/native/ghidra/scripts/C64Prepare.java +60 -0
- package/src/native/local.ts +34 -0
- package/src/native/processes.ts +350 -0
- package/src/native/run.ts +172 -0
- package/src/native/staging.ts +83 -0
- package/src/native/status.ts +113 -0
- package/src/native/types.ts +257 -0
- package/src/native/watchdog.ts +78 -0
- package/src/package.ts +21 -0
- package/src/platform.ts +441 -0
- package/src/project.ts +39 -0
- package/src/protocol/framing.ts +132 -0
- package/src/protocol/messages.ts +259 -0
- package/src/protocol/tools.ts +266 -0
- package/src/protocol/vice.ts +1348 -0
- package/src/script.ts +60 -0
- package/src/time.ts +15 -0
- package/src/trace.ts +194 -0
- package/THIRD-PARTY-NOTICES.md +0 -26
- package/bin/cli.mjs +0 -283
- package/skills/acme-build/SKILL.md +0 -260
- package/skills/acme-build/scripts/acme.mjs +0 -341
- package/skills/acme-build/template.a +0 -53
- package/skills/c64-disk-access/SKILL.md +0 -159
- package/skills/c64-disk-access/scripts/c1541.mjs +0 -569
- package/skills/c64-memory-mapping/SKILL.md +0 -631
- package/skills/c64-memory-mapping/memmap.json +0 -8800
- package/skills/c64-memory-mapping/scripts/driver.mjs +0 -553
- package/skills/c64-petcat/SKILL.md +0 -87
- package/skills/c64-petcat/scripts/petcat.mjs +0 -221
- package/skills/c64-program-recon/SKILL.md +0 -706
- package/skills/c64-program-recon/references/control-flow.md +0 -180
- package/skills/c64-program-recon/references/graphics.md +0 -79
- package/skills/c64-program-recon/references/observation-hazards.md +0 -143
- package/skills/c64-program-recon/references/reconstruction.md +0 -133
- package/skills/c64-program-recon/references/sound-and-input.md +0 -74
- package/skills/c64-program-recon/references/tool-selection.md +0 -78
- package/skills/c64-program-recon/scripts/derive.mjs +0 -364
- package/skills/c64-program-recon/scripts/packer-finding.mjs +0 -709
- package/skills/c64-program-recon/templates/memory-map.template.md +0 -101
- package/skills/c64-provenance-diff/SKILL.md +0 -292
- package/skills/c64-provenance-diff/scripts/diff-images.mjs +0 -984
- package/skills/c64-provenance-diff/scripts/recovery-schema.mjs +0 -395
- package/skills/c64-ram-capture/RELEASES.json.example +0 -17
- package/skills/c64-ram-capture/SKILL.md +0 -474
- package/skills/c64-ram-capture/scripts/compare-cross-binary.mjs +0 -525
- package/skills/c64-ram-capture/scripts/compare.mjs +0 -258
- package/skills/c64-ram-capture/scripts/derive-transients.mjs +0 -575
- package/skills/c64-ram-capture/scripts/dump-artifacts.mjs +0 -317
- package/skills/c64-ram-capture/scripts/mcp-module.mjs +0 -174
- package/skills/c64-ram-capture/scripts/project-paths.mjs +0 -81
- package/skills/c64-ram-capture/scripts/releases.mjs +0 -109
- package/skills/c64-ram-capture/scripts/vsf-slice.mjs +0 -147
- package/skills/c64-ram-capture/scripts/watch-loads.mjs +0 -581
- package/skills/c64-ram-capture/templates/capture-record.template.md +0 -99
- package/skills/c64-ram-capture/transients/README.md +0 -137
- package/skills/routine-queue-walker/SKILL.md +0 -394
- package/skills/routine-queue-walker/scripts/completeness-report.mjs +0 -465
- package/skills/vice-wedge-triage/SKILL.md +0 -269
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
// Headless Ghidra, run by the c64-static-analysis script. Ghidra runs with a settings
|
|
2
|
+
// directory of its own per request: the c64-re-tools NMOS 6510 language goes
|
|
3
|
+
// in there as an extension, so the user's Ghidra installation and settings
|
|
4
|
+
// never change. Ghidra compiles the language from its source on first load.
|
|
5
|
+
// Projects are disposable and live in the request workspace.
|
|
6
|
+
|
|
7
|
+
import { cpSync, mkdirSync, readFileSync, realpathSync, writeFileSync } from "node:fs";
|
|
8
|
+
import { userInfo } from "node:os";
|
|
9
|
+
import { dirname, isAbsolute, join, resolve } from "node:path";
|
|
10
|
+
import { fileURLToPath } from "node:url";
|
|
11
|
+
|
|
12
|
+
import { WireFailure } from "../../protocol/messages.ts";
|
|
13
|
+
import { findOnPath, INSTALL_STEPS, isExecutableFile } from "../discover.ts";
|
|
14
|
+
import type { ProcessSupervisor } from "../processes.ts";
|
|
15
|
+
import type { Workspace } from "../staging.ts";
|
|
16
|
+
import { outputTail, runToolOrFail, type ToolRun } from "../run.ts";
|
|
17
|
+
|
|
18
|
+
export const GHIDRA_LANGUAGE = "C64RT_6510:LE:16:nmos";
|
|
19
|
+
// Next to this module. New URL literals, so an installed skill gets the directories too.
|
|
20
|
+
export const LANGUAGE_DIRECTORY = fileURLToPath(new URL("./language/", import.meta.url));
|
|
21
|
+
export const SCRIPT_DIRECTORY = fileURLToPath(new URL("./scripts/", import.meta.url));
|
|
22
|
+
|
|
23
|
+
const REMEDY =
|
|
24
|
+
"Install Ghidra on the machine that runs the skill scripts and set C64RT_GHIDRA to its installation directory " +
|
|
25
|
+
`(the directory that holds support/analyzeHeadless), or put analyzeHeadless on PATH. ${INSTALL_STEPS}`;
|
|
26
|
+
|
|
27
|
+
export interface GhidraInstallation {
|
|
28
|
+
/** The installation directory. */
|
|
29
|
+
root: string;
|
|
30
|
+
analyzeHeadless: string;
|
|
31
|
+
/** For example ghidra_12.1.3_PUBLIC: the name of Ghidra's settings directory. */
|
|
32
|
+
settingsName: string;
|
|
33
|
+
version: string;
|
|
34
|
+
/** The lowest Java version this Ghidra runs on (application.java.min), when it names one. */
|
|
35
|
+
javaMin?: string;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Ghidra's launcher is a shell script, and a batch file on Windows. */
|
|
39
|
+
const LAUNCHER_SUFFIX = process.platform === "win32" ? ".bat" : "";
|
|
40
|
+
|
|
41
|
+
function installationAt(root: string, source: string): GhidraInstallation {
|
|
42
|
+
const analyzeHeadless = join(root, "support", `analyzeHeadless${LAUNCHER_SUFFIX}`);
|
|
43
|
+
let properties: string;
|
|
44
|
+
try {
|
|
45
|
+
if (!isExecutableFile(analyzeHeadless)) throw new Error("no analyzeHeadless");
|
|
46
|
+
properties = readFileSync(join(root, "Ghidra", "application.properties"), "utf8");
|
|
47
|
+
} catch {
|
|
48
|
+
throw new WireFailure("installation-incomplete", `${source} does not point to a Ghidra installation. ${REMEDY}`);
|
|
49
|
+
}
|
|
50
|
+
const value = (key: string) => new RegExp(`^${key.replace(/\./g, "\\.")}=(.*)$`, "m").exec(properties)?.[1]?.trim();
|
|
51
|
+
const version = value("application.version");
|
|
52
|
+
const release = value("application.release.name");
|
|
53
|
+
if (version === undefined || release === undefined) throw new WireFailure("installation-incomplete", `The Ghidra installation at ${source} has no version. ${REMEDY}`);
|
|
54
|
+
const javaMin = value("application.java.min");
|
|
55
|
+
return { root, analyzeHeadless, settingsName: `ghidra_${version}_${release}`, version, ...(javaMin === undefined || javaMin === "" ? {} : { javaMin }) };
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** The version of a Ghidra installation as a result and the tool status name it, for example "Ghidra 12.1.3". */
|
|
59
|
+
export function ghidraVersion(ghidra: GhidraInstallation): string {
|
|
60
|
+
return `Ghidra ${ghidra.version}`;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Finds Ghidra: C64RT_GHIDRA names the installation directory, else analyzeHeadless on PATH. */
|
|
64
|
+
export function findGhidra(env: NodeJS.ProcessEnv = process.env): GhidraInstallation {
|
|
65
|
+
const configured = env.C64RT_GHIDRA;
|
|
66
|
+
if (configured !== undefined && configured !== "") {
|
|
67
|
+
if (!isAbsolute(configured)) throw new WireFailure("installation-incomplete", `C64RT_GHIDRA on this machine is not an absolute path. ${REMEDY}`);
|
|
68
|
+
return installationAt(configured, "C64RT_GHIDRA");
|
|
69
|
+
}
|
|
70
|
+
const found = findOnPath(["analyzeHeadless"], env, [LAUNCHER_SUFFIX]);
|
|
71
|
+
if (found !== undefined) return installationAt(resolve(dirname(realpathSync(found)), ".."), "analyzeHeadless on PATH");
|
|
72
|
+
throw new WireFailure("installation-incomplete", `Ghidra is not installed on this machine. ${REMEDY}`);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* The user name in the name of Ghidra's settings directory: Java's user.name
|
|
77
|
+
* without spaces and without a domain before the last backslash or slash. Java gives "?"
|
|
78
|
+
* for a user without an entry in the password database, where Node throws.
|
|
79
|
+
*/
|
|
80
|
+
export function ghidraUserName(lookup: () => string = () => userInfo().username): string {
|
|
81
|
+
let name: string;
|
|
82
|
+
try {
|
|
83
|
+
name = lookup();
|
|
84
|
+
} catch {
|
|
85
|
+
name = "?";
|
|
86
|
+
}
|
|
87
|
+
name = name.split(" ").join("");
|
|
88
|
+
return name.slice(Math.max(name.lastIndexOf("\\"), name.lastIndexOf("/")) + 1);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Makes a Ghidra settings directory inside the workspace with the NMOS 6510
|
|
93
|
+
* language installed as an extension. Returns the environment that makes
|
|
94
|
+
* Ghidra use it.
|
|
95
|
+
*/
|
|
96
|
+
export function prepareSettings(workspace: Workspace, ghidra: GhidraInstallation, env: NodeJS.ProcessEnv = process.env): NodeJS.ProcessEnv {
|
|
97
|
+
const config = workspace.directory("ghidra-config");
|
|
98
|
+
const cache = workspace.directory("ghidra-cache");
|
|
99
|
+
// With XDG_CONFIG_HOME set, Ghidra keeps its settings in [<user>-]ghidra/<settings name> below it: with
|
|
100
|
+
// the user name only when that directory lies outside the user's home. The temporary directory is
|
|
101
|
+
// outside it on Linux and macOS but inside it on Windows (in AppData), so both names get it.
|
|
102
|
+
for (const application of [`${ghidraUserName()}-ghidra`, "ghidra"]) {
|
|
103
|
+
const extension = join(config, application, ghidra.settingsName, "Extensions", "C64RT");
|
|
104
|
+
mkdirSync(join(extension, "data"), { recursive: true });
|
|
105
|
+
cpSync(LANGUAGE_DIRECTORY, join(extension, "data", "languages"), { recursive: true });
|
|
106
|
+
writeFileSync(join(extension, "extension.properties"), `name=C64RT\ndescription=c64-re-tools NMOS 6510 language\nauthor=c64-re-tools\ncreatedOn=\nversion=${ghidra.version}\n`);
|
|
107
|
+
writeFileSync(join(extension, "Module.manifest"), "");
|
|
108
|
+
}
|
|
109
|
+
return { ...env, XDG_CONFIG_HOME: config, XDG_CACHE_HOME: cache };
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export interface HeadlessOptions {
|
|
113
|
+
ghidra: GhidraInstallation;
|
|
114
|
+
workspace: Workspace;
|
|
115
|
+
/** Workspace-relative path of the file to import. */
|
|
116
|
+
file: string;
|
|
117
|
+
baseAddress: number;
|
|
118
|
+
/** Scripts from these directories, before and after analysis, with their arguments. */
|
|
119
|
+
scriptDirectories: string[];
|
|
120
|
+
preScripts?: Array<{ name: string; args: string[] }>;
|
|
121
|
+
postScripts?: Array<{ name: string; args: string[] }>;
|
|
122
|
+
analyze: boolean;
|
|
123
|
+
timeoutMs: number;
|
|
124
|
+
supervisor: ProcessSupervisor;
|
|
125
|
+
signal: AbortSignal;
|
|
126
|
+
env?: NodeJS.ProcessEnv;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/** What Ghidra's launcher (launch.sh, launch.bat) prints when it finds no Java that it can use. */
|
|
130
|
+
export const NO_USABLE_JDK = /The 'java' command could not be found in your PATH or with JAVA_HOME|Unable to prompt user for JDK path, no TTY detected|Failed to find a supported JDK/;
|
|
131
|
+
|
|
132
|
+
/** A Ghidra without a usable JDK is an incomplete installation that names the Java version it needs (D38). */
|
|
133
|
+
export function noJdk(ghidra: GhidraInstallation): WireFailure {
|
|
134
|
+
const java = ghidra.javaMin === undefined ? "a JDK" : `JDK ${ghidra.javaMin} or later`;
|
|
135
|
+
return new WireFailure(
|
|
136
|
+
"installation-incomplete",
|
|
137
|
+
`${ghidraVersion(ghidra)} found no Java that it can use. It needs ${java}. Install it on the machine that runs the skill scripts and put its java on PATH, or set JAVA_HOME to it. ${INSTALL_STEPS}`,
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/** Imports one file into a disposable project and runs the scripts. Fails on timeout, abort or a Ghidra error exit. */
|
|
142
|
+
export async function runHeadless(options: HeadlessOptions): Promise<ToolRun> {
|
|
143
|
+
const env = prepareSettings(options.workspace, options.ghidra, options.env);
|
|
144
|
+
const project = options.workspace.directory("ghidra-project");
|
|
145
|
+
const argv = [
|
|
146
|
+
options.ghidra.analyzeHeadless,
|
|
147
|
+
project,
|
|
148
|
+
"request",
|
|
149
|
+
"-import",
|
|
150
|
+
options.workspace.path(options.file),
|
|
151
|
+
"-processor",
|
|
152
|
+
GHIDRA_LANGUAGE,
|
|
153
|
+
"-loader",
|
|
154
|
+
"BinaryLoader",
|
|
155
|
+
"-loader-baseAddr",
|
|
156
|
+
`0x${options.baseAddress.toString(16)}`,
|
|
157
|
+
"-scriptPath",
|
|
158
|
+
options.scriptDirectories.join(";"),
|
|
159
|
+
"-deleteProject",
|
|
160
|
+
];
|
|
161
|
+
if (!options.analyze) argv.push("-noanalysis");
|
|
162
|
+
else argv.push("-analysisTimeoutPerFile", String(Math.ceil(options.timeoutMs / 1000)));
|
|
163
|
+
for (const script of options.preScripts ?? []) argv.push("-preScript", script.name, ...script.args);
|
|
164
|
+
for (const script of options.postScripts ?? []) argv.push("-postScript", script.name, ...script.args);
|
|
165
|
+
const run = await runToolOrFail("Ghidra", "The Ghidra analysis", { argv, cwd: options.workspace.root, timeoutMs: options.timeoutMs }, { supervisor: options.supervisor, signal: options.signal, env });
|
|
166
|
+
if (run.code !== 0 && NO_USABLE_JDK.test(run.stdout + run.stderr)) throw noJdk(options.ghidra);
|
|
167
|
+
if (run.code !== 0 || /^ERROR REPORT SCRIPT ERROR|Exception in thread "main"/m.test(run.stdout + run.stderr)) {
|
|
168
|
+
// Ghidra's own error lines tell the user what to fix.
|
|
169
|
+
const tail = outputTail("Ghidra", run, options.workspace.root, /ERROR|Exception|Error:/);
|
|
170
|
+
throw new WireFailure("operation-failed", `Ghidra stopped with an error${tail === "" ? ` (exit ${run.code}).` : `.${tail}`}`);
|
|
171
|
+
}
|
|
172
|
+
return run;
|
|
173
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!-- Calls pass values in A, X and Y and return them in A. -->
|
|
3
|
+
<compiler_spec>
|
|
4
|
+
<global>
|
|
5
|
+
<range space="RAM"/>
|
|
6
|
+
</global>
|
|
7
|
+
<stackpointer register="SP" space="RAM" growth="negative"/>
|
|
8
|
+
<returnaddress>
|
|
9
|
+
<varnode space="stack" offset="1" size="2"/>
|
|
10
|
+
</returnaddress>
|
|
11
|
+
<default_proto>
|
|
12
|
+
<prototype name="__stdcall" extrapop="2" stackshift="2" strategy="register">
|
|
13
|
+
<input>
|
|
14
|
+
<pentry minsize="1" maxsize="1">
|
|
15
|
+
<register name="A"/>
|
|
16
|
+
</pentry>
|
|
17
|
+
<pentry minsize="1" maxsize="1">
|
|
18
|
+
<register name="X"/>
|
|
19
|
+
</pentry>
|
|
20
|
+
<pentry minsize="1" maxsize="1">
|
|
21
|
+
<register name="Y"/>
|
|
22
|
+
</pentry>
|
|
23
|
+
</input>
|
|
24
|
+
<output>
|
|
25
|
+
<pentry minsize="1" maxsize="1">
|
|
26
|
+
<register name="A"/>
|
|
27
|
+
</pentry>
|
|
28
|
+
</output>
|
|
29
|
+
<unaffected>
|
|
30
|
+
<register name="SP"/>
|
|
31
|
+
</unaffected>
|
|
32
|
+
</prototype>
|
|
33
|
+
</default_proto>
|
|
34
|
+
</compiler_spec>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!-- The c64-re-tools NMOS 6510 language: all 256 opcodes of the C64 CPU. -->
|
|
3
|
+
<language_definitions>
|
|
4
|
+
<language processor="C64RT_6510"
|
|
5
|
+
endian="little"
|
|
6
|
+
size="16"
|
|
7
|
+
variant="nmos"
|
|
8
|
+
version="1.0"
|
|
9
|
+
slafile="c64rt_6510.sla"
|
|
10
|
+
processorspec="c64rt_6510.pspec"
|
|
11
|
+
id="C64RT_6510:LE:16:nmos">
|
|
12
|
+
<description>NMOS 6510 (C64) with all undocumented opcodes</description>
|
|
13
|
+
<compiler name="default" spec="c64rt_6510.cspec" id="default"/>
|
|
14
|
+
</language>
|
|
15
|
+
</language_definitions>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!--
|
|
3
|
+
No default memory blocks or vector symbols: the importer makes the blocks
|
|
4
|
+
for the loaded program and the rest of the 64 KiB address space.
|
|
5
|
+
D is tracked as 0 at function entry, so the decimal path of ADC and SBC
|
|
6
|
+
disappears from decompiled code that never sets decimal mode.
|
|
7
|
+
-->
|
|
8
|
+
<processor_spec>
|
|
9
|
+
<programcounter register="PC"/>
|
|
10
|
+
<context_data>
|
|
11
|
+
<tracked_set space="RAM">
|
|
12
|
+
<set name="D" val="0"/>
|
|
13
|
+
</tracked_set>
|
|
14
|
+
</context_data>
|
|
15
|
+
</processor_spec>
|