@henols/c64-re-tools 2.0.0-rc.10 → 2.0.0-rc.12
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/README.md +7 -5
- package/package.json +1 -1
- package/skills/c64-assembler/SKILL.md +9 -2
- package/skills/c64-assembler/scripts/assemble.ts +4 -4
- package/skills/c64-basic/SKILL.md +8 -1
- package/skills/c64-basic/scripts/basic.ts +3 -3
- package/skills/c64-disk/SKILL.md +10 -3
- package/skills/c64-disk/scripts/disk.ts +4 -4
- package/skills/c64-emulator/SKILL.md +4 -0
- package/skills/c64-knowledge/SKILL.md +49 -11
- package/skills/c64-knowledge/scripts/knowledge.ts +254 -94
- package/skills/c64-memory-map/SKILL.md +7 -0
- package/skills/c64-memory-map/scripts/memmap.ts +1 -1
- package/skills/c64-provenance/SKILL.md +56 -3
- package/skills/c64-provenance/scripts/library.ts +584 -0
- package/skills/c64-provenance/scripts/provenance.ts +201 -9
- package/skills/c64-reverse-engineering/SKILL.md +15 -2
- package/skills/c64-source/SKILL.md +18 -4
- package/skills/c64-source/scripts/generate.ts +74 -57
- package/skills/c64-source/scripts/loader.ts +29 -11
- package/skills/c64-source/scripts/opcodes.ts +19 -0
- package/skills/c64-source/scripts/source.ts +166 -14
- package/skills/c64-static-analysis/SKILL.md +10 -2
- package/skills/c64-static-analysis/scripts/analyze.ts +25 -7
- package/skills/c64-static-analysis/scripts/pointers.ts +108 -0
- package/skills/c64-testing/SKILL.md +8 -1
- package/skills/c64-testing/references/scenario-format.md +1 -1
- package/skills/c64-testing/scripts/checklist.ts +2 -2
- package/skills/c64-testing/scripts/run.ts +4 -4
- package/skills/c64-testing/scripts/scenario.ts +1 -1
- package/skills/c64-testing/scripts/test.ts +4 -4
- package/skills/c64-unpacker/SKILL.md +11 -4
- package/skills/c64-unpacker/scripts/unpack.ts +4 -4
- package/src/c64.ts +2 -2
- package/src/cli/main.ts +5 -3
- package/src/host-client/image.ts +63 -0
- package/src/host-client/transfer.ts +34 -10
- package/src/host-client/vice-session.ts +9 -9
- package/src/knowledge/conflicts.ts +145 -0
- package/src/knowledge/database.ts +150 -38
- package/src/knowledge/expression.ts +209 -0
- package/src/knowledge/history.ts +30 -19
- package/src/knowledge/import.ts +5 -3
- package/src/knowledge/read.ts +91 -19
- package/src/knowledge/schema.ts +85 -67
- package/src/knowledge/text.ts +364 -0
- package/src/knowledge/write.ts +317 -48
- package/src/mcp/output.ts +14 -7
- package/src/mcp/tools/debug.ts +8 -6
- package/src/mcp/tools/media.ts +17 -13
- package/src/mcp/tools/memory.ts +9 -5
- package/src/mcp/tools/video.ts +6 -5
- package/src/platform.ts +28 -5
- package/src/project.ts +166 -3
- package/src/protocol/tools.ts +1 -1
- package/src/script.ts +46 -7
package/README.md
CHANGED
|
@@ -12,8 +12,8 @@ functional-equivalence tests.
|
|
|
12
12
|
Architecture in one line: one MCP process owns one VICE instance and is
|
|
13
13
|
VICE-only; a Host Runtime on the graphical host owns VICE and the tools that
|
|
14
14
|
come with it (c1541, petcat); skill scripts call the Host Runtime for those,
|
|
15
|
-
run ACME, DXA and Ghidra themselves, and keep project knowledge local
|
|
16
|
-
`.c64-re-tools/knowledge
|
|
15
|
+
run ACME, DXA and Ghidra themselves, and keep project knowledge local as
|
|
16
|
+
text in `.c64-re-tools/knowledge/`.
|
|
17
17
|
The design is in [`docs/redesign/`](docs/redesign/README.md), and
|
|
18
18
|
[`docs/plan.md`](docs/plan.md) tracks the implementation.
|
|
19
19
|
|
|
@@ -37,6 +37,8 @@ npx -y @henols/c64-re-tools@latest install --target claude
|
|
|
37
37
|
claude
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
+
Several programs in one repository: install once at the root, give each program its own folder, and start the agent at the root. A folder with `.c64-re-tools/` is a project; the agent names one with `--project <folder>`.
|
|
41
|
+
|
|
40
42
|
`npx -y @henols/c64-re-tools@latest status` shows what works.
|
|
41
43
|
|
|
42
44
|
Until 2.0.0 is released, `@latest` is the old 1.1.0. Use the prerelease instead. For the prerelease, a dev container and debugging, see [docs/debug-install.md](docs/debug-install.md).
|
|
@@ -76,7 +78,7 @@ and settings stay unchanged.
|
|
|
76
78
|
|
|
77
79
|
1. Install for your harness: `--target claude`, `codex`, `pi`, `opencode`, `gemini`, `copilot`, `cursor` or `windsurf`. Without `--target`, `install` installs for all of them.
|
|
78
80
|
2. Start the Host Runtime and leave it running.
|
|
79
|
-
3. Start the harness in the project, for example `claude` or `codex`, or open the project in Cursor or Windsurf. The harness starts the MCP server and finds the skills by itself.
|
|
81
|
+
3. Start the harness in the project (or at the root of a repository with several projects), for example `claude` or `codex`, or open the project in Cursor or Windsurf. The harness starts the MCP server and finds the skills by itself.
|
|
80
82
|
4. Ask for the result you want, in plain words. The agent picks the skills and the `c64_*` tools.
|
|
81
83
|
|
|
82
84
|
Examples:
|
|
@@ -93,7 +95,7 @@ Build it, run it in the emulator, and write a test for it.
|
|
|
93
95
|
Show me the emulator window.
|
|
94
96
|
```
|
|
95
97
|
|
|
96
|
-
The agent keeps what it learns about the program in `.c64-re-tools/knowledge
|
|
98
|
+
The agent keeps what it learns about the program as text in `.c64-re-tools/knowledge/`. Commit that folder with the project. After a `git pull` that joined the work of two computers, run `knowledge.ts merge` when a command reports conflicts.
|
|
97
99
|
|
|
98
100
|
## Skills
|
|
99
101
|
|
|
@@ -107,7 +109,7 @@ The agent keeps what it learns about the program in `.c64-re-tools/knowledge.db`
|
|
|
107
109
|
| c64-basic | BASIC V2 listings and the SYS/USR handoff to machine code. |
|
|
108
110
|
| c64-unpacker | Packing evidence, and capture of the unpacked program from the emulator. |
|
|
109
111
|
| c64-memory-map | Platform meaning of addresses and register values. |
|
|
110
|
-
| c64-provenance | Byte comparison of releases. |
|
|
112
|
+
| c64-provenance | Byte comparison of releases, and a library of routines that several programs share. |
|
|
111
113
|
| c64-source | ACME source from the image and the knowledge, checked byte by byte, and a loader for the entry state. |
|
|
112
114
|
| c64-assembler | ACME builds with diagnostics and symbols. |
|
|
113
115
|
| c64-testing | Original-against-rebuild scenarios with PASS, FAIL or INCONCLUSIVE. |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@henols/c64-re-tools",
|
|
3
|
-
"version": "2.0.0-rc.
|
|
3
|
+
"version": "2.0.0-rc.12",
|
|
4
4
|
"description": "Agent-friendly Commodore 64 engineering toolkit for reverse engineering, debugging, development and testing.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Henrik Olsson",
|
|
@@ -13,9 +13,9 @@ This skill does not run the program and does not change project knowledge.
|
|
|
13
13
|
|
|
14
14
|
## Inputs
|
|
15
15
|
|
|
16
|
-
- The source root: the project
|
|
16
|
+
- The source root: the folder in the project that holds all source files of the program.
|
|
17
17
|
- The entry source: the main file, relative to the source root.
|
|
18
|
-
- The output path: where to write the PRG, relative to the project
|
|
18
|
+
- The output path: where to write the PRG, relative to the project folder.
|
|
19
19
|
- Optional include directories, symbol definitions and a start address.
|
|
20
20
|
|
|
21
21
|
## Tools / execution path
|
|
@@ -37,6 +37,13 @@ The script copies the full source root. Put all files that the program includes
|
|
|
37
37
|
|
|
38
38
|
The script prints one JSON object. The target CPU is the 6510 and the output is always a C64 PRG.
|
|
39
39
|
|
|
40
|
+
### Project folder
|
|
41
|
+
|
|
42
|
+
- Paths are relative to the project folder. The project folder is the nearest folder at or above the working directory that holds `.c64-re-tools/`.
|
|
43
|
+
- If the working directory is not in a project and has projects below it, the script refuses and lists them. Then give `--project <folder>` to each script.
|
|
44
|
+
- Keep the results, batches and step files that you save for yourself in `.c64-re-tools/local/` of the project. Git ignores that folder.
|
|
45
|
+
- A shell redirect (`>`) is relative to the working directory, not to the project folder. From the folder above the project, write `<folder>/.c64-re-tools/local/result.json`.
|
|
46
|
+
|
|
40
47
|
## Workflow
|
|
41
48
|
|
|
42
49
|
1. Find the source root and the entry source. The entry source sets its own start address with `* = $0801` or similar.
|
|
@@ -16,7 +16,7 @@ import { compareBuild } from "./compare.ts";
|
|
|
16
16
|
|
|
17
17
|
const USAGE = `assemble.ts --source-root <dir> --entry <file> --out <file.prg> [options]
|
|
18
18
|
|
|
19
|
-
--source-root <dir> project
|
|
19
|
+
--source-root <dir> folder in the project to assemble from; all of it is sent
|
|
20
20
|
--entry <file> the main source file, relative to the source root
|
|
21
21
|
--out <file.prg> where to write the program, relative to the project
|
|
22
22
|
--include <dir> include directory relative to the source root (repeatable)
|
|
@@ -61,7 +61,7 @@ async function run(argv: string[]): Promise<{ output: unknown; failed: boolean }
|
|
|
61
61
|
try {
|
|
62
62
|
outPath = resolveProjectPath(out);
|
|
63
63
|
} catch {
|
|
64
|
-
throw new UsageError(`--out must be a path relative to the project
|
|
64
|
+
throw new UsageError(`--out must be a path relative to the project folder that stays inside it, not ${out}`);
|
|
65
65
|
}
|
|
66
66
|
const defines = Object.fromEntries((values.define ?? []).map(parseDefine));
|
|
67
67
|
let setPc: number | undefined;
|
|
@@ -101,8 +101,8 @@ async function run(argv: string[]): Promise<{ output: unknown; failed: boolean }
|
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
await runScript(
|
|
104
|
-
async () => {
|
|
105
|
-
const { output, failed } = await run(
|
|
104
|
+
async (argv) => {
|
|
105
|
+
const { output, failed } = await run(argv);
|
|
106
106
|
if (failed) process.exitCode = 1;
|
|
107
107
|
return output;
|
|
108
108
|
},
|
|
@@ -13,7 +13,7 @@ This skill does not run the program and does not change project knowledge.
|
|
|
13
13
|
|
|
14
14
|
## Inputs
|
|
15
15
|
|
|
16
|
-
- The program: a PRG file, relative to the project
|
|
16
|
+
- The program: a PRG file, relative to the project folder.
|
|
17
17
|
|
|
18
18
|
## Tools / execution path
|
|
19
19
|
|
|
@@ -25,6 +25,13 @@ node <skill>/scripts/basic.ts extracted/game.prg
|
|
|
25
25
|
|
|
26
26
|
The script prints one JSON object. Addresses are `$` and four hex digits.
|
|
27
27
|
|
|
28
|
+
### Project folder
|
|
29
|
+
|
|
30
|
+
- Paths are relative to the project folder. The project folder is the nearest folder at or above the working directory that holds `.c64-re-tools/`.
|
|
31
|
+
- If the working directory is not in a project and has projects below it, the script refuses and lists them. Then give `--project <folder>` to each script.
|
|
32
|
+
- Keep the results, batches and step files that you save for yourself in `.c64-re-tools/local/` of the project. Git ignores that folder.
|
|
33
|
+
- A shell redirect (`>`) is relative to the working directory, not to the project folder. From the folder above the project, write `<folder>/.c64-re-tools/local/result.json`.
|
|
34
|
+
|
|
28
35
|
## Workflow
|
|
29
36
|
|
|
30
37
|
1. Run the script on the program.
|
|
@@ -11,7 +11,7 @@ import { runScript, UsageError } from "#src/script.ts";
|
|
|
11
11
|
|
|
12
12
|
const USAGE = `basic.ts <program>
|
|
13
13
|
|
|
14
|
-
<program> is a PRG file relative to the project
|
|
14
|
+
<program> is a PRG file relative to the project folder. The result is one
|
|
15
15
|
JSON object. Addresses are $ and four hex digits.`;
|
|
16
16
|
|
|
17
17
|
async function run(argv: string[]): Promise<{ output: unknown; failed: boolean }> {
|
|
@@ -37,8 +37,8 @@ async function run(argv: string[]): Promise<{ output: unknown; failed: boolean }
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
await runScript(
|
|
40
|
-
async () => {
|
|
41
|
-
const { output, failed } = await run(
|
|
40
|
+
async (argv) => {
|
|
41
|
+
const { output, failed } = await run(argv);
|
|
42
42
|
if (failed) process.exitCode = 1;
|
|
43
43
|
return output;
|
|
44
44
|
},
|
package/skills/c64-disk/SKILL.md
CHANGED
|
@@ -13,10 +13,10 @@ This skill does not change the disk image and does not change project knowledge.
|
|
|
13
13
|
|
|
14
14
|
## Inputs
|
|
15
15
|
|
|
16
|
-
- The disk image: a `.d64`, `.d71`, `.d81` or `.g64` file, relative to the project
|
|
16
|
+
- The disk image: a `.d64`, `.d71`, `.d81` or `.g64` file, relative to the project folder.
|
|
17
17
|
- For one file: the file name as the directory shows it.
|
|
18
|
-
- To extract a file: the output path, relative to the project
|
|
19
|
-
- A T64 tape file or a CRT cartridge file, relative to the project
|
|
18
|
+
- To extract a file: the output path, relative to the project folder.
|
|
19
|
+
- A T64 tape file or a CRT cartridge file, relative to the project folder.
|
|
20
20
|
|
|
21
21
|
## Tools / execution path
|
|
22
22
|
|
|
@@ -42,6 +42,13 @@ The script prints one JSON object.
|
|
|
42
42
|
|
|
43
43
|
File names show the characters that the C64 shows in a directory list. A byte that has no character shows as `{$xx}`, for example `{$c1}`. Write the name in the same form. The letter case of a name is not important. Put the name in single quotes in a shell, for example `'GAME {$c1}'`.
|
|
44
44
|
|
|
45
|
+
### Project folder
|
|
46
|
+
|
|
47
|
+
- Paths are relative to the project folder. The project folder is the nearest folder at or above the working directory that holds `.c64-re-tools/`.
|
|
48
|
+
- If the working directory is not in a project and has projects below it, the script refuses and lists them. Then give `--project <folder>` to each script.
|
|
49
|
+
- Keep the results, batches and step files that you save for yourself in `.c64-re-tools/local/` of the project. Git ignores that folder.
|
|
50
|
+
- A shell redirect (`>`) is relative to the working directory, not to the project folder. From the folder above the project, write `<folder>/.c64-re-tools/local/result.json`.
|
|
51
|
+
|
|
45
52
|
## Workflow
|
|
46
53
|
|
|
47
54
|
1. Run `directory`. Find the file in `entries`. Each entry has a `name`, a `type`, a size in `blocks` and the `closed` and `locked` flags.
|
|
@@ -23,7 +23,7 @@ const USAGE = `disk.ts <action> <image> [name] [--out <file>]
|
|
|
23
23
|
read <image> <name> --out <file> write the bytes of one file into the project
|
|
24
24
|
crt <file.crt> --out <dir> write each CHIP packet of a cartridge as a PRG
|
|
25
25
|
|
|
26
|
-
<image> is a .d64, .d71, .d81 or .g64 file, relative to the project
|
|
26
|
+
<image> is a .d64, .d71, .d81 or .g64 file, relative to the project folder.
|
|
27
27
|
directory and read also take a .t64 tape file, and directory a .crt cartridge
|
|
28
28
|
file; the script reads those itself. A CRT can have hardware type 0 (normal
|
|
29
29
|
8K, 16K or Ultimax), 5 (Ocean), 19 (Magic Desk) or 32 (EasyFlash).
|
|
@@ -49,7 +49,7 @@ async function run(argv: string[]): Promise<{ output: unknown; failed: boolean }
|
|
|
49
49
|
try {
|
|
50
50
|
outPath = resolveProjectPath(values.out);
|
|
51
51
|
} catch {
|
|
52
|
-
throw new UsageError(`--out must be a path relative to the project
|
|
52
|
+
throw new UsageError(`--out must be a path relative to the project folder that stays inside it, not ${values.out}`);
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
|
|
@@ -111,8 +111,8 @@ function local(kind: "t64" | "crt", action: Action, image: string, name: string
|
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
await runScript(
|
|
114
|
-
async () => {
|
|
115
|
-
const { output, failed } = await run(
|
|
114
|
+
async (argv) => {
|
|
115
|
+
const { output, failed } = await run(argv);
|
|
116
116
|
if (failed) process.exitCode = 1;
|
|
117
117
|
return output;
|
|
118
118
|
},
|
|
@@ -52,6 +52,10 @@ For a large result, give `out` with a path in the project. `c64_memory_read`, `c
|
|
|
52
52
|
|
|
53
53
|
`c64_memmap` keeps RAM, ROM and I/O apart. Use action `summary` to see which code ran. Use action `read` with `out` to keep a coverage run as a file, for example `coverage/attract.bin`. Clear the map before each run that you want to keep apart.
|
|
54
54
|
|
|
55
|
+
### Project folder
|
|
56
|
+
|
|
57
|
+
Paths (`path`, `file` and `out`) are relative to the project folder. A project folder holds `.c64-re-tools/`. The tools use the nearest project folder at or above the folder where the agent started. If that folder is not in a project and has projects below it, a tool with a path refuses and lists them. Then give `project` with the project folder, for example `"project": "game"`. Give the same folder as the `--project` of the skill scripts. A tool without a path does not need `project`.
|
|
58
|
+
|
|
55
59
|
## Workflow
|
|
56
60
|
|
|
57
61
|
1. Read the project knowledge for the addresses in the question. Use the c64-knowledge skill.
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: c64-knowledge
|
|
3
|
-
description: Use this skill to read, write, correct and review the durable knowledge of a C64 project in .c64-re-tools/knowledge
|
|
3
|
+
description: Use this skill to read, write, correct and review the durable knowledge of a C64 project in .c64-re-tools/knowledge/. It gives the knowledge at an address, and it names symbols, classifies memory regions, sets comments and records references. It also shows the history of each change, and it can revert to an earlier revision. Do not use it for live emulator state or for static analysis.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# c64-knowledge
|
|
7
7
|
|
|
8
8
|
## Purpose
|
|
9
9
|
|
|
10
|
-
Read, write, correct and review the durable understanding of a C64 project. The knowledge is in `.c64-re-tools/knowledge.db`
|
|
10
|
+
Read, write, correct and review the durable understanding of a C64 project. The knowledge is text in `.c64-re-tools/knowledge/` in the project folder: one JSON line for each row. Commit that folder with git. The script keeps an index of the text in `.c64-re-tools/local/knowledge.db` and makes the index again when the text changes. Do not commit the index.
|
|
11
11
|
|
|
12
12
|
This skill is the only write path for conclusions of the user and the LLM. It does not run an emulator or an analyzer.
|
|
13
13
|
|
|
@@ -22,8 +22,6 @@ One of these:
|
|
|
22
22
|
|
|
23
23
|
## Tools / execution path
|
|
24
24
|
|
|
25
|
-
Run the script in the project directory. The project directory is the directory that the harness started in.
|
|
26
|
-
|
|
27
25
|
```
|
|
28
26
|
node <skill>/scripts/knowledge.ts <command> [arguments] [options]
|
|
29
27
|
```
|
|
@@ -41,20 +39,25 @@ The script prints one JSON object. An error prints `{"error": {"code": ..., "mes
|
|
|
41
39
|
| Remove a symbol | `remove-symbol '$2100'` |
|
|
42
40
|
| Classify memory | `classify '$3000' '$303f' sprite` |
|
|
43
41
|
| Classify a table of records | `classify '$3000' '$303b' bytes --element 6` |
|
|
44
|
-
| Many writes as one revision | `apply
|
|
42
|
+
| Many writes as one revision | `apply -` with the JSON on standard input, or `apply <file>` |
|
|
45
43
|
| Make memory unknown, and keep the analyzers out of it | `unclassify '$3000' '$303f'` |
|
|
46
44
|
| Set or remove a comment | `comment '$2100' line Reads joystick 2.` / `uncomment '$2100' line` |
|
|
47
45
|
| Add or remove a reference | `reference '$2000' '$2100' call` / `unreference ...` |
|
|
48
46
|
| Places that a removal blocks | `suppressions` with `--start` and `--end` |
|
|
49
47
|
| Start a file of generated source | `module '$2000' player.asm --title 'Player movement'` / `unmodule '$2000'` |
|
|
48
|
+
| Write the operand of an instruction as an expression | `operand '$8079' --lo irq_handler --image unpacked/image.json` / `unoperand '$8079'` |
|
|
49
|
+
| Operand expressions | `operands` with `--start` and `--end` |
|
|
50
50
|
| Files of generated source | `modules` |
|
|
51
51
|
| The address spaces that hold knowledge | `spaces` |
|
|
52
|
-
| History | `history '$2100'`, `history --name update_player`, `revisions`, `revision
|
|
53
|
-
| Go back to an earlier state | `revert
|
|
52
|
+
| History | `history '$2100'`, `history --name update_player`, `revisions`, `revision 20261015T2145` |
|
|
53
|
+
| Go back to an earlier state | `revert 20261015T2145` |
|
|
54
|
+
| Decide the conflicts after a git merge | `merge --reason 'merge of two computers'` |
|
|
55
|
+
|
|
56
|
+
A revision has an id such as `20261015T214501.123-k3f9qz`. The id starts with the date and time. A command takes the full id, or a start of the id that only one revision has. The revision `0` is the knowledge before the first revision.
|
|
54
57
|
|
|
55
58
|
Every command takes `--space`: `c64` (the default), `drive8` for code in the 1541 drive, or `bank0` to `bank255` for cartridge banks. Drive code and banks use the same addresses as the C64, so each space has its own knowledge. A name is unique inside one space. In a batch, a write can name its own `space`.
|
|
56
59
|
|
|
57
|
-
Symbol kinds are `label`, `routine`, `variable`, `data` and `vector`. Reference kinds are `call`, `jump`, `read`, `write` and `reference
|
|
60
|
+
Symbol kinds are `label`, `routine`, `variable`, `data` and `vector`. Reference kinds are `call`, `jump`, `read`, `write`, `reference` and `pointer`. Only an operand expression writes a `pointer` reference.
|
|
58
61
|
|
|
59
62
|
Region types:
|
|
60
63
|
|
|
@@ -71,6 +74,13 @@ Region types:
|
|
|
71
74
|
|
|
72
75
|
`--element` gives the bytes of one element of a table. The length of the region must be a multiple of it. The result shows `element` and `count`.
|
|
73
76
|
|
|
77
|
+
### Project folder
|
|
78
|
+
|
|
79
|
+
- Paths are relative to the project folder. The project folder is the nearest folder at or above the working directory that holds `.c64-re-tools/`.
|
|
80
|
+
- If the working directory is not in a project and has projects below it, the script refuses and lists them. Then give `--project <folder>` to each script.
|
|
81
|
+
- Keep the results, batches and step files that you save for yourself in `.c64-re-tools/local/` of the project. Git ignores that folder.
|
|
82
|
+
- A shell redirect (`>`) is relative to the working directory, not to the project folder. From the folder above the project, write `<folder>/.c64-re-tools/local/result.json`.
|
|
83
|
+
|
|
74
84
|
## Workflow
|
|
75
85
|
|
|
76
86
|
Read:
|
|
@@ -87,7 +97,7 @@ Write:
|
|
|
87
97
|
|
|
88
98
|
Each write is one revision. A classification inside a region splits that region, so regions never overlap.
|
|
89
99
|
|
|
90
|
-
For more than a few writes,
|
|
100
|
+
For more than a few writes, use `apply -` and give the writes on standard input as one JSON list. Each write has `op` and the arguments of the command with the same name, for example:
|
|
91
101
|
|
|
92
102
|
```json
|
|
93
103
|
[
|
|
@@ -110,13 +120,39 @@ The ops and their fields:
|
|
|
110
120
|
| `reference`, `unreference` | `from`, `to`, `kind` |
|
|
111
121
|
| `module` | `start`, `file`, `title` (optional) |
|
|
112
122
|
| `unmodule` | `start` |
|
|
123
|
+
| `operand` | `address`, `select` (`lo`, `hi`, `value` or `expr`), `symbol` and `offset` (optional), or `expression` for `expr` |
|
|
124
|
+
| `unoperand` | `address` |
|
|
113
125
|
|
|
114
126
|
A `line` comment is a line of its own above the address. A `side` comment is at the end of the line of the address. All writes become one revision. If the knowledge refuses one write, the script writes nothing, and the error names the write.
|
|
115
127
|
|
|
128
|
+
The c64-provenance skill writes a batch with `match --out`. The batch holds the names of library routines at their addresses in this program. Read the `batch.leftOut` of its result first. Then apply the batch with the command in its `apply`.
|
|
129
|
+
|
|
116
130
|
## Modules
|
|
117
131
|
|
|
118
132
|
A module tells the c64-source skill where a file of the generated source starts. The file runs to the next module or to the end of its segment. Each address has one module, and each file name has one module. A file name has letters, digits, underscores or hyphens, and ends in `.asm`. The c64-source skill writes `main.asm`, `loader.asm` and `constants.asm` itself. Thus a module cannot have one of these names, in upper or lower case. The title becomes the first line of the file. A `module` write without a title keeps the title that the module has. Modules have a history, and `revert` restores them.
|
|
119
133
|
|
|
134
|
+
## Operand expressions
|
|
135
|
+
|
|
136
|
+
An operand expression tells the c64-source skill how to write the operand of one instruction. The source then has a name, not a number. When code or data changes its length, the operand follows the address that moved.
|
|
137
|
+
|
|
138
|
+
Give one selector:
|
|
139
|
+
|
|
140
|
+
| Option | Operand | Source |
|
|
141
|
+
|---|---|---|
|
|
142
|
+
| `--lo <symbol>` | The low byte of the symbol plus the offset | `lda #<irq_handler` |
|
|
143
|
+
| `--hi <symbol>` | The high byte of the symbol plus the offset | `lda #>(sprite_bank+$1000)` |
|
|
144
|
+
| `--value <symbol>` | The symbol plus the offset | `lda bar_colours-1,x` |
|
|
145
|
+
| `--expr <text>` | ACME expression text with names and numbers | `lda #(sprite_bank + 5*64) / 64` |
|
|
146
|
+
|
|
147
|
+
- `--offset` adds a whole number to the symbol. Write a negative offset as `--offset=-1`.
|
|
148
|
+
- A name is a symbol of the knowledge or a platform name of the c64-memory-map skill.
|
|
149
|
+
- `--expr` takes `$`, `%` and decimal numbers, names, brackets, the operators `+ - * / % << >> >>> & | XOR`, and `<`, `>`, `-` and `!` before an operand.
|
|
150
|
+
- The script compares the value of the expression with the operand in the image. If they are not equal, the script refuses the write. Give the image with `--image`: an `image.json` of the c64-unpacker skill or a PRG. `apply` with an `operand` write also needs `--image`.
|
|
151
|
+
- Each name in the expression gets a `pointer` reference from the instruction. Thus `at` on the named address shows the code that uses the address.
|
|
152
|
+
- A `rename` of a symbol changes the name in each expression. The knowledge refuses `remove-symbol` while an expression uses the symbol. Use `unoperand` first.
|
|
153
|
+
|
|
154
|
+
Write an operand expression for each immediate that is a byte of an address. Also write one for each table read through the byte before the table. The pointer candidates of the c64-static-analysis skill show many of these places.
|
|
155
|
+
|
|
120
156
|
## Removals
|
|
121
157
|
|
|
122
158
|
`remove-symbol`, `unclassify` and `unreference` block the place for DXA and Ghidra. An analysis does not add a symbol at that address, a region in that range or that reference again. This applies to every removed fact, also to a fact from the LLM.
|
|
@@ -146,7 +182,7 @@ The script records the origin `llm`. Use `--origin user` only when the user deci
|
|
|
146
182
|
|
|
147
183
|
For a read: the current or historical knowledge in compact JSON.
|
|
148
184
|
|
|
149
|
-
For a write: the new revision and the current value after the write. If the write replaces a symbol
|
|
185
|
+
For a write: the new revision and the current value after the write. If the write replaces a symbol, a region or an operand expression of a different origin, `previous` gives that row as it was before the write. For example, an `llm` write over a `user` name gives `previous`. Read `previous` and tell the user about the change. For `apply`, `replaced` lists each write that replaced a row. Each item has the number of the write, its `op` and its `previous`.
|
|
150
186
|
|
|
151
187
|
The exit status is 0 for a result. The exit status is 1 for an error from the knowledge, for example `conflict`. The exit status is 2 for a wrong argument.
|
|
152
188
|
|
|
@@ -155,7 +191,8 @@ The exit status is 0 for a result. The exit status is 1 for an error from the kn
|
|
|
155
191
|
- `conflict`: the change contradicts current knowledge. For example, the name belongs to another address. Read that address and its history, then decide.
|
|
156
192
|
- `stale-revision`: the knowledge changed after you read it. Read it again, then decide again.
|
|
157
193
|
- `not-found`: there is nothing to remove or no such revision.
|
|
158
|
-
- `
|
|
194
|
+
- `conflict` with "from a git merge": git joined the knowledge of two computers, and two rows are current where the knowledge permits one row. For example, two names are at one address. Every read shows these rows in `conflicts`. Writes stop until you run `merge`. The `merge` command keeps the newest row of each conflict and closes the other rows, in one revision. Its result lists each choice. Tell the user the choices.
|
|
195
|
+
- `invalid-database` or `unsupported-schema`: tell the user the message. Do not edit the knowledge files.
|
|
159
196
|
|
|
160
197
|
A revert makes a new revision. The history stays complete.
|
|
161
198
|
|
|
@@ -164,3 +201,4 @@ A revert makes a new revision. The history stays complete.
|
|
|
164
201
|
- Runtime evidence → c64-emulator
|
|
165
202
|
- Static evidence → c64-static-analysis
|
|
166
203
|
- Source from the knowledge → c64-source
|
|
204
|
+
- Names of routines that other programs share → c64-provenance
|