@henols/c64-re-tools 1.1.0 → 2.0.0-rc.11
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 +192 -0
- package/skills/c64-knowledge/scripts/knowledge.ts +613 -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 +133 -0
- package/skills/c64-source/scripts/generate.ts +503 -0
- package/skills/c64-source/scripts/loader.ts +589 -0
- package/skills/c64-source/scripts/opcodes.ts +61 -0
- package/skills/c64-source/scripts/source.ts +673 -0
- package/skills/c64-static-analysis/SKILL.md +120 -0
- package/skills/c64-static-analysis/scripts/analyze.ts +293 -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-static-analysis/scripts/pointers.ts +108 -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/image.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/expression.ts +209 -0
- package/src/knowledge/history.ts +169 -0
- package/src/knowledge/import.ts +392 -0
- package/src/knowledge/read.ts +392 -0
- package/src/knowledge/schema.ts +250 -0
- package/src/knowledge/write.ts +837 -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,144 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: c64-reverse-engineering
|
|
3
|
+
description: Use this skill to reverse engineer a C64 program or a part of it. The work goes from an unknown disk or file to documented understanding or a rebuilt program. It decides what to learn next and which specialist skill does that work. Use it for questions such as "what does this game do", "find the main loop", "understand $2100" or "rebuild this program".
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# c64-reverse-engineering
|
|
7
|
+
|
|
8
|
+
## Purpose
|
|
9
|
+
|
|
10
|
+
Coordinate the reverse engineering of a C64 program. Decide the next unknown to examine and the specialist skill that examines it.
|
|
11
|
+
|
|
12
|
+
This skill does not do the specialist work itself.
|
|
13
|
+
|
|
14
|
+
## Inputs
|
|
15
|
+
|
|
16
|
+
- The subject: a disk image or a program file in the project, or a program that runs in the emulator.
|
|
17
|
+
- The scope: the question or the target. Examples:
|
|
18
|
+
- identify the main loop
|
|
19
|
+
- understand the routine at `$2100`
|
|
20
|
+
- find the IRQ handler
|
|
21
|
+
- reconstruct the input system
|
|
22
|
+
- reverse engineer and rebuild the whole program
|
|
23
|
+
- The current project knowledge.
|
|
24
|
+
|
|
25
|
+
## Tools / execution path
|
|
26
|
+
|
|
27
|
+
This skill uses the other skills. It does not use the host runtime or the emulator directly.
|
|
28
|
+
|
|
29
|
+
## Workflow
|
|
30
|
+
|
|
31
|
+
Select the path for the scope:
|
|
32
|
+
|
|
33
|
+
- A narrow scope, for example one routine, the IRQ handler or the input system: use the loop.
|
|
34
|
+
- A full rebuild of the program: use the stages.
|
|
35
|
+
|
|
36
|
+
### The loop
|
|
37
|
+
|
|
38
|
+
1. Write down the scope. Stop when the scope is complete.
|
|
39
|
+
2. Read the current knowledge for the subject with the c64-knowledge skill. Do not examine again what the knowledge already explains.
|
|
40
|
+
3. Find the next unknown or blocker, and use the specialist for it:
|
|
41
|
+
|
|
42
|
+
| Unknown | Skill |
|
|
43
|
+
|---|---|
|
|
44
|
+
| The files on a disk image, or a file to extract | c64-disk |
|
|
45
|
+
| A BASIC program, and where it starts machine code | c64-basic |
|
|
46
|
+
| A program that can be packed or crunched | c64-unpacker |
|
|
47
|
+
| What the program does at run time: values, input, timing, screen | c64-emulator |
|
|
48
|
+
| The routines, code, data and references of the program | c64-static-analysis |
|
|
49
|
+
| The platform meaning of an address or a register | c64-memory-map |
|
|
50
|
+
| Differences between releases of the program | c64-provenance |
|
|
51
|
+
| Source code from the knowledge | c64-source |
|
|
52
|
+
| Source code to build | c64-assembler |
|
|
53
|
+
| Proof that a rebuild behaves as the original | c64-testing |
|
|
54
|
+
|
|
55
|
+
4. Interpret the result. Keep observed facts apart from your conclusions.
|
|
56
|
+
5. Record each conclusion that the evidence supports with the c64-knowledge skill: names of routines and variables, data classifications, comments.
|
|
57
|
+
6. Go back to step 3 until the scope is complete.
|
|
58
|
+
|
|
59
|
+
### The stages of a full rebuild
|
|
60
|
+
|
|
61
|
+
Do the stages in this sequence. Go to the next stage only when its exit check is true, or when the user accepts an exception. Write each exception in the report.
|
|
62
|
+
|
|
63
|
+
| Stage | Work | Exit check |
|
|
64
|
+
|---|---|---|
|
|
65
|
+
| 1. Acceptance | Ask the user for the criteria of the rebuild. Offer these: identical source, a verified loader, passed c64-testing scenarios, a list of the code that no run executed. Write the criteria in `report.md`. | The user gave the criteria. |
|
|
66
|
+
| 2. Get | c64-disk: list the disk. Extract the start file into `original/`. | The start file is in the project. |
|
|
67
|
+
| 3. Start | c64-basic: find the SYS address of the BASIC start. | You have the entry address. |
|
|
68
|
+
| 4. Unpack | c64-unpacker: examine the program. Capture a packed program into `unpacked/`. | `image.json` and `entry_state.json` exist, or the evidence shows no packer. |
|
|
69
|
+
| 5. Run | c64-emulator and the run of c64-testing: run each part that the scope names. Write a coverage file for each part into `coverage/`. | Each part that the scope names has a coverage file. |
|
|
70
|
+
| 6. Analyze | c64-static-analysis with `--coverage` for each coverage file. | No coverage conflict is open. |
|
|
71
|
+
| 7. Name | c64-knowledge and c64-memory-map: name each routine in the scope and give it a comment. Record the modules. | Each routine in the scope has a name and a comment. |
|
|
72
|
+
| 8. Generate | c64-source with `--coverage` into `src/`. For an unpacked program, add `--loader`. | `check.identical` is true. For an unpacked program, `loader.verified` is true. |
|
|
73
|
+
| 9. Build and test | c64-assembler with `--compare` into `build/`. c64-testing scenarios in `tests/`. | The criteria of stage 1 are true. |
|
|
74
|
+
| 10. Report | Write `report.md`. | The report has all its sections. |
|
|
75
|
+
|
|
76
|
+
In stage 5, if you cannot get to a part of the program, ask the user how to get to it. Do stages 7 and 8 again until the source is clear. Each run of c64-source writes the source again.
|
|
77
|
+
|
|
78
|
+
### Deliverables of a full rebuild
|
|
79
|
+
|
|
80
|
+
- `.c64-re-tools/knowledge.db` with the names, regions, comments and modules
|
|
81
|
+
- the image and the entry state
|
|
82
|
+
- the coverage files
|
|
83
|
+
- the generated source
|
|
84
|
+
- the built program and the loader
|
|
85
|
+
- the c64-testing scenarios and their results
|
|
86
|
+
- `report.md`.
|
|
87
|
+
|
|
88
|
+
### The report
|
|
89
|
+
|
|
90
|
+
`report.md` is short. It has these sections:
|
|
91
|
+
|
|
92
|
+
1. Acceptance: each criterion of stage 1 and its result, and each exception that the user accepted.
|
|
93
|
+
2. The program: what the program does, in a few sentences.
|
|
94
|
+
3. Modules: the file, the address range and the title of each module.
|
|
95
|
+
4. Untested code: all ranges in the `not_executed.json` file of c64-source. Tell why no run executed them, if you know.
|
|
96
|
+
5. Open questions: what the evidence does not explain.
|
|
97
|
+
|
|
98
|
+
Keep observed facts apart from your conclusions.
|
|
99
|
+
|
|
100
|
+
### Project layout
|
|
101
|
+
|
|
102
|
+
If the project has no layout, use this one. It is a proposal. No script checks it. Each script takes the paths that you give.
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
original/ the disk image or the program as you got it
|
|
106
|
+
unpacked/ image.json, image.bin and entry_state.json from c64-unpacker
|
|
107
|
+
coverage/ coverage files from c64_memmap
|
|
108
|
+
src/ the generated source from c64-source
|
|
109
|
+
build/ programs from c64-assembler
|
|
110
|
+
tests/ c64-testing scenarios and their results
|
|
111
|
+
report.md the report
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
If the project has a layout, use that layout.
|
|
115
|
+
|
|
116
|
+
## Knowledge
|
|
117
|
+
|
|
118
|
+
Read:
|
|
119
|
+
- the knowledge for the addresses, ranges and routines in the scope
|
|
120
|
+
- the history of a conclusion that is surprising or that a person disputes.
|
|
121
|
+
|
|
122
|
+
Automatic write:
|
|
123
|
+
- none directly.
|
|
124
|
+
|
|
125
|
+
Record durable conclusions with the c64-knowledge skill. Do not store:
|
|
126
|
+
- the state of the current investigation
|
|
127
|
+
- a name only because a routine needs a temporary name
|
|
128
|
+
- guesses.
|
|
129
|
+
|
|
130
|
+
## Result
|
|
131
|
+
|
|
132
|
+
A clear answer for the scope, with the durable conclusions in the project knowledge. For a full rebuild, the deliverables and the report, with the criteria of the user met or each exception in the report.
|
|
133
|
+
|
|
134
|
+
## Failure and conflicts
|
|
135
|
+
|
|
136
|
+
- A skill reports `installation-incomplete`, or `machine-unavailable` with a message that the host runtime does not run: stop the whole task. Give the message to the user and wait for the user. Do not continue with other skills. Do not make a replacement for the tool or the host runtime, for example your own disk parser, disassembler or emulator script.
|
|
137
|
+
- If the evidence does not support a conclusion, keep the unknown and get more evidence. Do not make up a meaning.
|
|
138
|
+
- Before you replace current knowledge from the user or the LLM, read its history and the evidence for it.
|
|
139
|
+
- A conflict from the static analysis: find the correct answer at run time with the c64-emulator skill.
|
|
140
|
+
- A test that is INCONCLUSIVE does not show a defect. Find why the test could not compare.
|
|
141
|
+
|
|
142
|
+
## Handoffs
|
|
143
|
+
|
|
144
|
+
All specialist skills in the table above.
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: c64-source
|
|
3
|
+
description: Use this skill to generate ACME source code for a C64 program from its image and the project knowledge. The script runs Ghidra for the instructions and writes the source files. It checks with ACME that the source assembles to the same bytes as the image. It can also write a loader that sets the entry state of an unpacked program. Use it to make a rebuild. Do not edit the generated files. Change the knowledge and generate again.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# c64-source
|
|
7
|
+
|
|
8
|
+
## Purpose
|
|
9
|
+
|
|
10
|
+
Generate ACME source from an image and the knowledge. The same knowledge gives the same source. Make the source better through the knowledge: names, comments, regions and modules. Then generate again.
|
|
11
|
+
|
|
12
|
+
This skill does not change the knowledge.
|
|
13
|
+
|
|
14
|
+
## Inputs
|
|
15
|
+
|
|
16
|
+
- The image: an `image.json` from c64-unpacker capture, or a PRG. The path is relative to the project directory.
|
|
17
|
+
- The output directory for the source files, relative to the project directory.
|
|
18
|
+
- Optional entry points for Ghidra.
|
|
19
|
+
- For the loader: the `entry_state.json` next to `image.json`.
|
|
20
|
+
|
|
21
|
+
## Tools / execution path
|
|
22
|
+
|
|
23
|
+
The script runs Ghidra and ACME on this machine. With `--loader`, it also runs the loader in the emulator through the host runtime.
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
node <skill>/scripts/generate.ts unpacked/image.json --out src
|
|
27
|
+
node <skill>/scripts/generate.ts game.prg --out src --entry '$080d'
|
|
28
|
+
node <skill>/scripts/generate.ts unpacked/image.json --out src --loader
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
| Option | Meaning |
|
|
32
|
+
|---|---|
|
|
33
|
+
| `--out src` | The directory for the source files. The script writes over the files that it generated before. |
|
|
34
|
+
| `--entry '$080d'` | An entry point for Ghidra. Use it again for more entry points. The entry of `image.json`, the routines and the code regions in the knowledge are entry points too. |
|
|
35
|
+
| `--coverage coverage/attract.bin` | A coverage file of 64 KiB from `c64_memmap` with `out`. Use it again for more runs. Code that no run executed gets the line `; not executed` with its range. `notExecuted` lists it. |
|
|
36
|
+
| `--space drive8` | Generate the source of drive code or a cartridge bank from the knowledge of that space. `--coverage` and `--loader` are only for `c64`, and platform names are only for `c64`. |
|
|
37
|
+
| `--loader` | Also write `loader.asm` and `loader.prg`. This needs `image.json` with an entry, and `entry_state.json`. |
|
|
38
|
+
|
|
39
|
+
## Workflow
|
|
40
|
+
|
|
41
|
+
1. Get the image. For a packed program, use c64-unpacker capture. For a program without a packer, use the PRG.
|
|
42
|
+
2. Run the script.
|
|
43
|
+
3. Read `check`. `identical: true` tells that the source assembles to the image byte by byte.
|
|
44
|
+
4. Read the source. A label `l_xxxx` is an address that has no name in the knowledge.
|
|
45
|
+
5. Record names, comments, regions and modules with the c64-knowledge skill. Use `apply` for many changes.
|
|
46
|
+
6. Run the script again. Do steps 4 to 6 again until the source is clear.
|
|
47
|
+
7. Build the program with the c64-assembler skill: `--source-root src --entry main.asm`.
|
|
48
|
+
8. For an unpacked program, run the script with `--loader` at the end. Test `loader.prg` against the original with the c64-testing skill.
|
|
49
|
+
|
|
50
|
+
## The source
|
|
51
|
+
|
|
52
|
+
- `main.asm` sets the address of each segment and includes the files in address order.
|
|
53
|
+
- Each module in the knowledge is one file. A module starts at its address and stops at the next module or at the end of its segment. Without modules, each segment is one file, `segment_xxxx.asm`.
|
|
54
|
+
- `constants.asm` holds the names of addresses outside the image, for example `EXTCOL = $d020`.
|
|
55
|
+
- A label or a constant gets the name of the address in the knowledge. Without a knowledge name, it gets the platform name of the c64-memory-map skill, for example `EXTCOL` or `CHROUT`. A platform name wins over a name from an analyzer (`dxa`, `ghidra` or `heuristic`), for example `EXTCOL` over `ld020`. A `user` or `llm` name wins over a platform name. An address in the image without a name gets `l_xxxx`.
|
|
56
|
+
- Code regions, and the instructions that Ghidra decodes outside of data regions, become instructions.
|
|
57
|
+
- Data regions become data by their type: `!byte`, `!word`, `!pet`, `!scr`, `!fill`, tables of labels, and sprite bytes in binary.
|
|
58
|
+
- `lda+2 $0012` is an absolute operand below $0100. `+1` is a zero-page operand with a label.
|
|
59
|
+
- `sta NMINV+1` is an address inside a platform entry of more than one byte, for example the high byte of a vector.
|
|
60
|
+
- `name = * + 1` is a label inside an instruction, for example for code that changes its own operand.
|
|
61
|
+
- `lda #<irq_handler` and `lda bar_colours-1,x` are operand expressions of the knowledge. The script writes each name of an expression with the name of its address in the source. An operand expression in a non-immediate mode that starts with a bracket gets `0+` before it, because ACME reads `(...)` as indirect.
|
|
62
|
+
- `; = <irq_handler` at the end of an instruction with a number: the source cannot use this operand expression. `operandsAsNumbers` gives the reason.
|
|
63
|
+
- `!byte` with an instruction as its comment: ACME writes this instruction with a different opcode. The bytes keep the source identical.
|
|
64
|
+
- `not decoded` marks bytes in a code region that Ghidra did not decode.
|
|
65
|
+
- `; not executed $xxxx-$yyyy` starts code that no run of the `--coverage` files executed. The range is the same as in `not_executed.json`.
|
|
66
|
+
|
|
67
|
+
Do not edit the generated files. The next run writes over them.
|
|
68
|
+
|
|
69
|
+
## The loader
|
|
70
|
+
|
|
71
|
+
`--loader` writes `loader.asm` and assembles it to `loader.prg`. The loader does these steps:
|
|
72
|
+
|
|
73
|
+
1. `10 SYS 2061` starts it.
|
|
74
|
+
2. It moves its copier to two free pages. The copier runs with interrupts off and with all RAM visible.
|
|
75
|
+
3. It copies each segment and the pages $0002-$03ff of the entry state into place. The script selects an order in which no copy writes over the packed bytes of a copy that has not run yet.
|
|
76
|
+
4. It sets the display registers of the VIC-II and the VIC bank from `io` in the entry state. Then it waits for the raster line of the entry.
|
|
77
|
+
5. It sets the CIA timers, their latches and the interrupt masks from `io` and `cia` in the entry state. A running timer gets the value that counts down to the timer value of the entry at the entry.
|
|
78
|
+
6. It sets $00/$01, the stack pointer, A, X, Y and the flags, and jumps to the entry.
|
|
79
|
+
|
|
80
|
+
The copy table, the copier and the jump to the entry use labels, not numbers. `loader_from_xxxx` and `loader_end_xxxx` are around each packed segment, and `loader_to_xxxx` is its first address in place. The jump goes to the label of the entry. Thus a segment can change its length, and the loader still copies it and jumps to the entry that moved. The display values, the raster line and the CIA values stay numbers. They are the entry state, not addresses of the program.
|
|
81
|
+
|
|
82
|
+
The flags go through the free stack byte below the stack pointer (`stackByte`). The loader changes this byte. The loader does not set the SID, the time of day of the CIAs, the CIA interrupt flags or the interrupt registers of the VIC-II. `loader.limits` names each CIA value that the loader cannot set as it was at the entry. A program that reads the SID voice 3 for random numbers can still differ in a scenario. A raster sync does not change a timer or the SID. Then observe after the program sets up its own random numbers.
|
|
83
|
+
|
|
84
|
+
The script simulates the copies first. Then it runs `loader.prg` in the emulator to its jump to the entry. It compares the memory, $00/$01, the registers, the display registers of the VIC-II, the VIC bank and the raster line with the entry state there. It also compares the CIA timers, latches and interrupt masks. `loader.verified: true` tells that all of them are equal. An interrupt can run right at the entry, as in the original program.
|
|
85
|
+
|
|
86
|
+
## Knowledge
|
|
87
|
+
|
|
88
|
+
Read:
|
|
89
|
+
- symbols, regions, comments, references, modules and operand expressions of all origins.
|
|
90
|
+
|
|
91
|
+
Automatic write:
|
|
92
|
+
- none.
|
|
93
|
+
|
|
94
|
+
Do not store:
|
|
95
|
+
- the generated source or its labels `l_xxxx`.
|
|
96
|
+
|
|
97
|
+
## Result
|
|
98
|
+
|
|
99
|
+
One JSON object:
|
|
100
|
+
|
|
101
|
+
- `files`: the files in the output directory.
|
|
102
|
+
- `instructions`, `dataBytes` and `undecodedBytes`.
|
|
103
|
+
- `labels`: `named` labels from the knowledge and `generated` labels `l_xxxx`.
|
|
104
|
+
- `entriesInData`: each `--entry` in a data region of the knowledge, with the `region` and its `origin`. Ghidra does not decode an entry in a data region.
|
|
105
|
+
- `asBytes`: the instructions that the source has as bytes.
|
|
106
|
+
- `operandExpressions`: the count of instructions that the source has with an operand expression.
|
|
107
|
+
- `operandsAsNumbers`: the operand expressions that the source has as a number with a side comment, each with its `address`, `expression` and `reason`. An expression becomes a number when no instruction with an operand value is at the address, or when a name has no address. An expression that ACME refuses or does not assemble to the image also becomes a number. Then the script assembles the source again, at most three times.
|
|
108
|
+
- `unusedModules`: modules in the knowledge whose start is in no segment of the image. Often this tells that the image does not hold code that the knowledge describes.
|
|
109
|
+
- `entryOutside`: the entry of `image.json` is in no segment of the image, with a `reason`. The image does not hold the program.
|
|
110
|
+
- `notExecuted`: with `--coverage`, the count of instructions that no run executed, the count of their ranges, and the first ranges. `all` names the file `not_executed.json` in `--out`. It has all of the ranges. Put all of these ranges in the report.
|
|
111
|
+
- `check`: `identical`, and the result for each segment. A different segment gives its first different address.
|
|
112
|
+
- `loader`: the program, the copies in their order, the copier page, `stackByte`, `verified` and `differences`. `limits` lists the CIA values that the loader cannot set. When the script cannot make the loader, `loader` has `verified: false` and a `reason`. The loader includes the source. Thus a source that does not assemble to the image also stops the loader.
|
|
113
|
+
|
|
114
|
+
The exit status is 0 when the source is identical and the emulator check of the loader passes. The exit status is 1 for a failed check, for an entry in no segment, and for an error. The exit status is 2 for a wrong argument.
|
|
115
|
+
|
|
116
|
+
## Failure and conflicts
|
|
117
|
+
|
|
118
|
+
- `check.diagnostics`: ACME did not assemble the source. A name in the knowledge can be wrong for ACME. Read the diagnostics and change the name with c64-knowledge.
|
|
119
|
+
- `check.identical: false`: the script has a defect. Give the result to the user.
|
|
120
|
+
- `operandsAsNumbers`: read each `reason`. Correct the expression with `operand` of the c64-knowledge skill, or remove it with `unoperand`.
|
|
121
|
+
- `invalid-input` that names a symbol or a module: change that symbol or module in the knowledge.
|
|
122
|
+
- `entryOutside`: the run fails, but the script still writes and checks the source. With `--loader`, `loader.verified` is `false` with the same `reason`. Capture the image again with c64-unpacker `loads` or `capture`. Make sure that a segment holds the entry.
|
|
123
|
+
- `entriesInData`: an analyzer region of data hides the code at the entry. If the entry is code, record a code region at the entry with the c64-knowledge skill, for example `classify '$0500' '$05ff' code`. A region of the user or the LLM replaces the analyzer region. Then generate again.
|
|
124
|
+
- `loader.verified: false` with a `reason`: the script did not make the loader. The script still writes and checks the source. When no copy order or no free pages exist, or the loader needs too many copies, the reason gives the ranges. Capture the image again with fewer segments, or write the loader by hand.
|
|
125
|
+
- `loader.verified: false` with `differences`: the loader ran, and `differences` gives the bytes and registers that are not equal.
|
|
126
|
+
- `installation-incomplete`, or `machine-unavailable` with a message that the host runtime does not run: stop the task. Give the message to the user and wait for the user. The message gives the remedy. Do not make a replacement for the tool or the host runtime, for example your own disassembler or emulator script.
|
|
127
|
+
|
|
128
|
+
## Handoffs
|
|
129
|
+
|
|
130
|
+
- Get an image → c64-unpacker
|
|
131
|
+
- Names, regions, comments and modules → c64-knowledge
|
|
132
|
+
- Build the program → c64-assembler
|
|
133
|
+
- Test the rebuild against the original → c64-testing
|