@henols/c64-re-tools 0.2.0 → 0.2.2
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 +1 -1
- package/THIRD-PARTY-NOTICES.md +26 -0
- package/bin/cli.mjs +18 -7
- package/package.json +6 -4
- package/skills/acme-build/SKILL.md +67 -47
- package/skills/acme-build/scripts/acme.mjs +2 -19
- package/skills/acme-build/template.a +17 -3
- package/skills/c64-memory-mapping/SKILL.md +426 -2
- package/skills/c64-program-recon/SKILL.md +479 -3
- package/skills/c64-program-recon/references/reconstruction.md +10 -4
- package/skills/c64-program-recon/references/tool-selection.md +2 -3
- package/skills/c64-program-recon/scripts/packer-finding.mjs +631 -0
- package/skills/c64-program-recon/templates/memory-map.template.md +86 -51
- package/skills/c64-provenance-diff/SKILL.md +4 -4
- package/skills/c64-provenance-diff/scripts/diff-images.mjs +3 -0
- package/skills/c64-provenance-diff/scripts/recovery-schema.mjs +14 -4
- package/skills/c64-ram-capture/RELEASES.json.example +17 -0
- package/skills/c64-ram-capture/SKILL.md +46 -2
- package/skills/c64-ram-capture/scripts/project-paths.mjs +1 -1
- package/skills/c64-ram-capture/scripts/watch-loads.mjs +6 -0
- package/skills/routine-queue-walker/SKILL.md +273 -0
- package/skills/vice-wedge-triage/SKILL.md +16 -0
- package/skills/c64-provenance-diff/scripts/diff-images.test.mjs +0 -665
- package/skills/c64-ram-capture/scripts/d64-parse.test.mjs +0 -243
- package/skills/c64-ram-capture/scripts/dump-artifacts.test.mjs +0 -133
- package/skills/c64-ram-capture/scripts/test-corpus.mjs +0 -75
- package/skills/c64-ram-capture/scripts/watch-loads.test.mjs +0 -339
package/README.md
CHANGED
|
@@ -43,7 +43,7 @@ you pass `--force`.
|
|
|
43
43
|
## Requirements
|
|
44
44
|
|
|
45
45
|
- **This installer** runs on Node ≥ 18.
|
|
46
|
-
- **The VICE MCP server** it wires up requires **Node ≥
|
|
46
|
+
- **The VICE MCP server** it wires up requires **Node ≥ 24**, and a
|
|
47
47
|
host with VICE (`x64sc`) reachable from the MCP client. See the
|
|
48
48
|
[`@henols/vice-mcp`](https://www.npmjs.com/package/@henols/vice-mcp) readme.
|
|
49
49
|
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Third-Party Notices for `@henols/c64-re-tools`
|
|
2
|
+
|
|
3
|
+
This package is MIT-licensed, copyright Henrik Olsson (see `LICENSE` at the
|
|
4
|
+
repository root). It ships the C64 reverse-engineering **skill playbooks**
|
|
5
|
+
under `skills/` plus the installer CLI under `bin/`, and it declares one
|
|
6
|
+
runtime dependency, `@henols/vice-mcp`, which carries its own notices file.
|
|
7
|
+
|
|
8
|
+
This document covers only the third-party material that ships **in this
|
|
9
|
+
package**. It is deliberately not a second, competing inventory: the canonical
|
|
10
|
+
third-party notices for the whole repository — including the cc65 opcode-table
|
|
11
|
+
transcription and the ACME/VICE not-incorporated scope notes, none of which
|
|
12
|
+
ship here — live in the `@henols/vice-mcp` package at
|
|
13
|
+
`src/mcp/vice/THIRD-PARTY-NOTICES.md` in the repository, and inside that
|
|
14
|
+
package's own tarball as `THIRD-PARTY-NOTICES.md`. Read that file for the full
|
|
15
|
+
inventory; read this one for what `@henols/c64-re-tools` itself carries.
|
|
16
|
+
|
|
17
|
+
## Incorporated material
|
|
18
|
+
|
|
19
|
+
None. The skill playbooks under `skills/` are this project's own prose,
|
|
20
|
+
written against this project's own curated tool surface.
|
|
21
|
+
|
|
22
|
+
## Runtime dependency
|
|
23
|
+
|
|
24
|
+
- **`@henols/vice-mcp`** — this repository's own MCP server package, MIT. Its
|
|
25
|
+
own third-party notices ship inside it as `THIRD-PARTY-NOTICES.md`, and that
|
|
26
|
+
file is the canonical inventory referred to at the top of this document.
|
package/bin/cli.mjs
CHANGED
|
@@ -13,6 +13,9 @@
|
|
|
13
13
|
import { spawnSync } from "node:child_process";
|
|
14
14
|
import { fileURLToPath } from "node:url";
|
|
15
15
|
import { dirname, join, resolve } from "node:path";
|
|
16
|
+
// Entry-point dispatch guard (see the bottom of this file): the same idiom
|
|
17
|
+
// `src/skills/c64-memory-mapping/scripts/driver.mjs` already uses, so a bare
|
|
18
|
+
// `import` from a test file does not also execute the CLI.
|
|
16
19
|
import {
|
|
17
20
|
existsSync,
|
|
18
21
|
readFileSync,
|
|
@@ -27,11 +30,11 @@ const PKG_ROOT = dirname(HERE);
|
|
|
27
30
|
const SKILLS_SRC = join(PKG_ROOT, "skills");
|
|
28
31
|
|
|
29
32
|
// The single version-resolution seam this repo maintains is
|
|
30
|
-
//
|
|
33
|
+
// `src/mcp/vice/version.ts` (quick-260819-tsz, D-5). This package
|
|
31
34
|
// deliberately does NOT import it: it ships without the seam file (its
|
|
32
35
|
// `files[]` is `bin/`, `skills/`, `README.md`) and targets node >= 18, which
|
|
33
36
|
// cannot type-strip the seam's `.ts` the way the vice-mcp package's own
|
|
34
|
-
// node >=
|
|
37
|
+
// node >= 24 runtime can. What follows is exactly the seam's own
|
|
35
38
|
// precedence step 1 -- "read my own package.json's `.version`, trust it
|
|
36
39
|
// when it is a real published number" -- not a second, independent
|
|
37
40
|
// implementation of the resolution algorithm; there is no template/`-`
|
|
@@ -45,11 +48,11 @@ const SELF_VERSION = typeof SELF.version === "string" ? SELF.version : "0.0.0";
|
|
|
45
48
|
const MCP_PKG = "@henols/vice-mcp";
|
|
46
49
|
// The dev placeholder every derived, publishable version string carries in
|
|
47
50
|
// the working tree (R-2, quick-260819-tsz). Defined authoritatively as
|
|
48
|
-
// `DEV_PLACEHOLDER` in
|
|
51
|
+
// `DEV_PLACEHOLDER` in `src/mcp/vice/version.ts` -- repeated here as a
|
|
49
52
|
// literal, NOT imported, because this package deliberately ships without
|
|
50
53
|
// that seam file (see the comment above) and targets node >= 18, which
|
|
51
54
|
// cannot type-strip a `.ts` import the way the vice-mcp package's own
|
|
52
|
-
// node >=
|
|
55
|
+
// node >= 24 runtime can. This is the same disclosed divergence as
|
|
53
56
|
// `SELF_VERSION` above: one literal, kept in sync by hand, documented here
|
|
54
57
|
// so a future edit to the seam's placeholder is not missed.
|
|
55
58
|
const MCP_DEV_PLACEHOLDER = "0.0.0-dev";
|
|
@@ -124,7 +127,7 @@ What it does:
|
|
|
124
127
|
1. Copies bundled skills into <target>/.claude/skills/
|
|
125
128
|
2. Adds a 'vice' server to <target>/.mcp.json (other servers are preserved)
|
|
126
129
|
|
|
127
|
-
Requires Node >=
|
|
130
|
+
Requires Node >= 24 to RUN the vice MCP server (this installer runs on Node >= 18).`;
|
|
128
131
|
|
|
129
132
|
function viceServerEntry(vendor) {
|
|
130
133
|
return {
|
|
@@ -262,8 +265,16 @@ function main() {
|
|
|
262
265
|
console.error("Dry run -- nothing was written.");
|
|
263
266
|
} else {
|
|
264
267
|
console.error("Done. Restart Claude Code in this project so it picks up the skills and MCP server.");
|
|
265
|
-
console.error("Note: running the vice MCP server requires Node >=
|
|
268
|
+
console.error("Note: running the vice MCP server requires Node >= 24.");
|
|
266
269
|
}
|
|
267
270
|
}
|
|
268
271
|
|
|
269
|
-
|
|
272
|
+
// Only dispatch when this module is the process entry point -- i.e. run as
|
|
273
|
+
// `node bin/cli.mjs ...` or via the `c64-re-tools` bin shim -- not when
|
|
274
|
+
// imported by a test (installer/wire-mcp.test.mjs imports `wireMcp`/`readJson`
|
|
275
|
+
// below and must not trigger a real install as a side effect).
|
|
276
|
+
if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
|
277
|
+
main();
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
export { wireMcp, readJson };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@henols/c64-re-tools",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "Installer that adds the C64 reverse-engineering skills and the VICE emulator MCP server (@henols/vice-mcp) to a project.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
"files": [
|
|
10
10
|
"bin/",
|
|
11
11
|
"skills/",
|
|
12
|
-
"README.md"
|
|
12
|
+
"README.md",
|
|
13
|
+
"THIRD-PARTY-NOTICES.md"
|
|
13
14
|
],
|
|
14
15
|
"engines": {
|
|
15
16
|
"node": ">=18"
|
|
@@ -44,10 +45,11 @@
|
|
|
44
45
|
"installer"
|
|
45
46
|
],
|
|
46
47
|
"dependencies": {
|
|
47
|
-
"@henols/vice-mcp": "0.2.
|
|
48
|
+
"@henols/vice-mcp": "0.2.2"
|
|
48
49
|
},
|
|
49
50
|
"scripts": {
|
|
50
51
|
"sync-skills": "node scripts/sync-skills.mjs",
|
|
51
|
-
"prepack": "node scripts/sync-skills.mjs"
|
|
52
|
+
"prepack": "node scripts/sync-skills.mjs",
|
|
53
|
+
"test": "node --test '*.test.mjs'"
|
|
52
54
|
}
|
|
53
55
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: acme-build
|
|
3
|
-
description: Assemble Commodore 64 6510 assembly with the ACME cross assembler. Use when asked to assemble, build, compile or link .a/.asm 6502/6510 source, produce a C64 .prg, scaffold a new C64 program, list
|
|
3
|
+
description: Assemble Commodore 64 6510 assembly with the ACME cross assembler. Use when asked to assemble, build, compile or link .a/.asm 6502/6510 source, produce a C64 .prg, scaffold a new C64 program, or list which symbols an assembled build actually used from its symbol file.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Assembling C64 source with ACME
|
|
@@ -8,15 +8,14 @@ description: Assemble Commodore 64 6510 assembly with the ACME cross assembler.
|
|
|
8
8
|
Source in, `.prg` out. Everything goes through one script:
|
|
9
9
|
|
|
10
10
|
```bash
|
|
11
|
-
A
|
|
11
|
+
A=src/skills/acme-build/scripts/acme.mjs # from the repo root
|
|
12
12
|
|
|
13
13
|
node $A new game.asm # scaffold a C64 program
|
|
14
14
|
node $A build game.asm # assemble -> .prg .sym .vs .rep
|
|
15
15
|
node $A sym game.asm # the symbols the program uses
|
|
16
|
-
node $A disasm game.prg # object code back into ACME source
|
|
17
16
|
```
|
|
18
17
|
|
|
19
|
-
The script wraps `acme` and
|
|
18
|
+
The script wraps `acme` and nothing else — **assembling only**. Running
|
|
20
19
|
the result on a C64 belongs to the emulator skills (`acme.mjs:3-4` says so, and the
|
|
21
20
|
absent `run` verb is not an omission). It contacts nothing.
|
|
22
21
|
|
|
@@ -133,60 +132,80 @@ you also assemble by hand, so these stay recognised as mnemonics.
|
|
|
133
132
|
|
|
134
133
|
## Disassembly
|
|
135
134
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
135
|
+
This skill does not disassemble. The route that does is `anno export-asm`, and
|
|
136
|
+
it lives in the `anno` CLI rather than here.
|
|
137
|
+
|
|
138
|
+
**Dated withdrawal 2026-08-29, dated return 2026-08-31 — both halves are kept,
|
|
139
|
+
because the withdrawal is the record of why the route is shaped the way it is.**
|
|
140
|
+
Whole-program static disassembly was WITHDRAWN on 2026-08-29 (`D-02`/`D-14`)
|
|
141
|
+
rather than left standing on an unverified reassembly claim: the removed route
|
|
142
|
+
settled correctness with a transcript parser, and the recorded false pass that
|
|
143
|
+
discipline exists against read `ACME not found in PATH (skipped)` / `All
|
|
144
|
+
roundtrip verifications passed.` / `EXIT=0` — exit zero, an aggregate line
|
|
145
|
+
reading as a full pass, and the one assembler this project cares about never
|
|
146
|
+
having run. On **2026-08-31 the route returned**, rebuilt over the annotation
|
|
147
|
+
store as `anno export-asm`. It is not a rename of what was removed: its
|
|
148
|
+
correctness is settled by **assembling the output with a real ACME and diffing
|
|
149
|
+
the bytes against the input** — never by an exit code, and never by a string
|
|
150
|
+
match on the exporter's own output.
|
|
151
|
+
|
|
152
|
+
**The live invocation:**
|
|
151
153
|
|
|
152
154
|
```bash
|
|
153
|
-
|
|
155
|
+
npx -y @henols/vice-mcp anno export-asm game.prg --store game.annostore --out game.a
|
|
156
|
+
node <plugin-root>/src/mcp/vice/vice-proxy.ts anno export-asm game.prg --store game.annostore
|
|
154
157
|
```
|
|
155
158
|
|
|
156
|
-
`
|
|
159
|
+
`<image>` and `--store` are **two separate arguments and neither is derived from
|
|
160
|
+
the other** — the image supplies the bytes, the store supplies the names, ranges,
|
|
161
|
+
typed regions and comments, and naming one does not name the other. `--out`
|
|
162
|
+
defaults to a `.a` beside the **store**, not beside the image, because the export
|
|
163
|
+
is a generated view of the annotations. An existing destination is refused rather
|
|
164
|
+
than overwritten unless you pass `--force`.
|
|
165
|
+
|
|
166
|
+
**The verb writes source text and runs no assembler.** Its own second output line
|
|
167
|
+
says so, in as many words:
|
|
157
168
|
|
|
158
169
|
```
|
|
159
|
-
|
|
160
|
-
L0801 !by$0b;ANC# <- BASIC stub, read as data
|
|
161
|
-
L0802 php
|
|
162
|
-
L0805 SHX L3032, y
|
|
163
|
-
...
|
|
164
|
-
L080d lda #$00 <- code, decoded correctly
|
|
165
|
-
L080f sta Ld021
|
|
166
|
-
L0812 lda #$05
|
|
167
|
-
L0814 sta Ld020
|
|
168
|
-
L081e jsr Lffd2
|
|
169
|
-
L0824 rts
|
|
170
|
-
L0825 pha <- PETSCII string, read as data
|
|
170
|
+
export-asm: this file has NOT been assembled -- this command writes source text and runs no assembler.
|
|
171
171
|
```
|
|
172
172
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
173
|
+
The real-ACME byte-diff oracle is **test-only** — it lives in
|
|
174
|
+
`src/mcp/vice/acme-verify.ts`, is exercised by `acme-verify.test.ts` (hard-failed
|
|
175
|
+
in CI with `VICE_REQUIRE_ACME=1`), and is deliberately absent from the published
|
|
176
|
+
package, so nothing on the runtime path can reach it. A clean `export-asm` run is
|
|
177
|
+
therefore evidence that source was written and nothing more; it is not an
|
|
178
|
+
assembler verdict. If you need to know the emitted source reassembles, assemble
|
|
179
|
+
it yourself — that is what this skill's own build route is for.
|
|
180
|
+
|
|
181
|
+
**Reading one range at a time is still the right move for a single routine.**
|
|
182
|
+
`anno_read_region` and `anno_disassemble` render an explicit inclusive range out
|
|
183
|
+
of the image on demand, capped at 4096 bytes per call and REFUSED by name above
|
|
184
|
+
the cap rather than truncated. `c64-program-recon` documents that route and this
|
|
185
|
+
history together; it is not restated there.
|
|
177
186
|
|
|
178
187
|
## Setup
|
|
179
188
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
189
|
+
`acme` on `$PATH` is the **only** requirement. The scaffold that `new` writes
|
|
190
|
+
assembles against a bare install with no standard hardware-register library —
|
|
191
|
+
that's deliberate: neither a plain `~/.local/bin/acme` build nor the Debian
|
|
192
|
+
trixie `apt` candidate ships one, so a scaffold that depended on it would fail
|
|
193
|
+
to assemble on a fresh install (Phase 8.1 FINDING-A1).
|
|
194
|
+
|
|
195
|
+
`$ACME` and the wrapper's auto-probe (`$ACME`, `/usr/local/share/acme`,
|
|
196
|
+
`/usr/share/acme`, `/usr/lib/acme`, `~/.acme`) still exist and still matter —
|
|
197
|
+
but only for **your own** sources that use angle-bracket includes (see
|
|
198
|
+
"Writing source" above), not for the scaffold. If you have that library
|
|
199
|
+
somewhere, point `$ACME` at its directory and angle-bracket includes work as
|
|
200
|
+
before; if you don't, the scaffold doesn't need it.
|
|
201
|
+
|
|
202
|
+
Re-checked against ACME release 0.97 "Zem" (31 Jan 2021). CI now assembles
|
|
203
|
+
the shipped scaffold on every build with `$ACME` cleared (the "Assemble the
|
|
204
|
+
acme-build scaffold (library-free)" step in `.github/workflows/ci.yml`), so
|
|
205
|
+
this claim is re-checkable rather than a one-machine observation.
|
|
187
206
|
|
|
188
207
|
Copy `acme.mjs` into any project's `.claude/skills/acme-build/scripts/`, and
|
|
189
|
-
`template.a` into `.claude/skills/acme-build/`, to use this elsewhere.
|
|
208
|
+
`template.a` into `.claude/skills/acme-build/`, to use this elsewhere (the path Claude Code auto-discovers and `installSkills()` deploys to).
|
|
190
209
|
|
|
191
210
|
## Which skill does what
|
|
192
211
|
|
|
@@ -197,14 +216,15 @@ This one turns source into bytes. It does not restate what the others carry.
|
|
|
197
216
|
| Where to start on an unknown program, and which address to read next | `c64-program-recon` |
|
|
198
217
|
| What a specific address or bit means, or annotating a listing | `c64-memory-mapping` — `node … lookup '$D018'` |
|
|
199
218
|
| A verified 64K image, or comparing two captures | `c64-ram-capture` |
|
|
200
|
-
|
|
|
219
|
+
| Static disassembly of a `.prg` or flat image | **`anno export-asm`** — withdrawn 2026-08-29, returned 2026-08-31 behind a real-ACME byte-diff oracle that is test-only, so the verb writes source and assembles nothing (see Disassembly above) |
|
|
220
|
+
| **Source in, `.prg` out** | here |
|
|
201
221
|
|
|
202
222
|
## References
|
|
203
223
|
|
|
204
224
|
| File | Covers |
|
|
205
225
|
|---|---|
|
|
206
226
|
| `scripts/acme.mjs` | The driver. Its comments are the contract for every flag above |
|
|
207
|
-
| `template.a` | The scaffold `new` writes: BASIC stub with a computed `SYS`,
|
|
227
|
+
| `template.a` | The scaffold `new` writes: BASIC stub with a computed `SYS`, five local hardware constants (no library needed), no `!to` |
|
|
208
228
|
|
|
209
229
|
Findings that make RE faster go in `.planning/RE-FINDINGS.md` **at the moment you
|
|
210
230
|
find them**, graded with `Evidence:` and `Confidence:`. Promote by re-logging with
|
|
@@ -205,22 +205,6 @@ function cmdNew(argv) {
|
|
|
205
205
|
console.log(`next: node ${selfPath()} build ${path}`);
|
|
206
206
|
}
|
|
207
207
|
|
|
208
|
-
// `toacme` ships with ACME and turns object code back into ACME source.
|
|
209
|
-
function cmdDisasm(argv) {
|
|
210
|
-
const src = argv[0];
|
|
211
|
-
if (!src) die("usage: disasm <file.prg> [out.a]");
|
|
212
|
-
const out = argv[1] || src.replace(/\.prg$/i, "") + ".dis.a";
|
|
213
|
-
const r = spawnSync("toacme", ["object", src, out], { encoding: "utf8" });
|
|
214
|
-
if (r.error) die("install the ACME cross assembler and put `toacme` on PATH");
|
|
215
|
-
if (r.status !== 0) die(`toacme: ${(r.stderr || r.stdout).trim()}`);
|
|
216
|
-
const n = readFileSync(out, "utf8").split("\n").filter((l) => /^L[0-9a-f]{4}/.test(l)).length;
|
|
217
|
-
console.log(`${out}: ${n} lines`);
|
|
218
|
-
console.log("Read it as a linear decode: trust the instruction stream, and");
|
|
219
|
-
console.log("treat strings, tables and the BASIC stub as data. To reassemble,");
|
|
220
|
-
console.log("define the out-of-range labels it emits (Ld020, Lffd2, ...) and");
|
|
221
|
-
console.log("indent its illegal-opcode lines to the operand column.");
|
|
222
|
-
}
|
|
223
|
-
|
|
224
208
|
// ------------------------------------------------------------------ options
|
|
225
209
|
|
|
226
210
|
function parseOpts(argv) {
|
|
@@ -247,14 +231,13 @@ function parseOpts(argv) {
|
|
|
247
231
|
// --------------------------------------------------------------------- main
|
|
248
232
|
|
|
249
233
|
const [cmd, ...rest] = process.argv.slice(2);
|
|
250
|
-
const VERBS = { new: cmdNew, build: cmdBuild, sym: cmdSym
|
|
234
|
+
const VERBS = { new: cmdNew, build: cmdBuild, sym: cmdSym };
|
|
251
235
|
if (!cmd || !VERBS[cmd]) {
|
|
252
236
|
console.log(`usage: node ${selfPath()} <command> [options]
|
|
253
237
|
|
|
254
|
-
new <file.a> scaffold a C64 program (BASIC stub
|
|
238
|
+
new <file.a> scaffold a C64 program (BASIC stub, no libraries needed)
|
|
255
239
|
build <file.a> assemble -> .prg .sym .vs .rep
|
|
256
240
|
sym <file.a> list the symbols the program uses
|
|
257
|
-
disasm <file.prg> [out.a] turn object code back into ACME source
|
|
258
241
|
|
|
259
242
|
options: -o FILE --out-dir DIR -f FORMAT --setpc ADDR -DSYM=VAL -I DIR
|
|
260
243
|
--no-report --json`);
|
|
@@ -2,11 +2,25 @@
|
|
|
2
2
|
; Build: node .claude/skills/acme-build/scripts/acme.mjs build THIS.a
|
|
3
3
|
; No !to here on purpose - the driver passes -o, and having both makes ACME
|
|
4
4
|
; warn "Output file already chosen" and silently ignore the !to.
|
|
5
|
+
;
|
|
6
|
+
; No angle-bracket library includes here on purpose. Neither documented ACME
|
|
7
|
+
; provisioning route ships the standard hardware-register library - a bare
|
|
8
|
+
; `~/.local/bin/acme` install and the Debian trixie `apt` candidate were both
|
|
9
|
+
; verified to lack it (Phase 8.1 FINDING-A1) - so a scaffold that depends on
|
|
10
|
+
; it fails to assemble on a fresh install. The five constants below are
|
|
11
|
+
; exactly what this scaffold's body uses, defined locally instead. If you
|
|
12
|
+
; want the full library for your own sources' angle-bracket includes, set
|
|
13
|
+
; $ACME to a directory containing that library (with vic.a inside it);
|
|
14
|
+
; acme.mjs's findAcmeLib() already probes for it and passes it through to
|
|
15
|
+
; the child.
|
|
5
16
|
|
|
6
17
|
!cpu 6510 ; C64's CPU: legal 6502 + the illegal opcodes
|
|
7
|
-
|
|
8
|
-
!
|
|
9
|
-
!
|
|
18
|
+
|
|
19
|
+
!address vic_cborder = $d020 ; VIC-II border color register
|
|
20
|
+
!address vic_cbg = $d021 ; VIC-II background color register
|
|
21
|
+
viccolor_BLACK = 0
|
|
22
|
+
viccolor_GREEN = 5
|
|
23
|
+
!address k_chrout = $ffd2 ; KERNAL: print one PETSCII char
|
|
10
24
|
|
|
11
25
|
* = $0801 ; start of BASIC RAM
|
|
12
26
|
|