@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.
Files changed (162) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +154 -37
  3. package/distribution/package.ts +21 -0
  4. package/distribution/plugin.ts +122 -0
  5. package/package.json +34 -40
  6. package/skills/c64-assembler/SKILL.md +76 -0
  7. package/skills/c64-assembler/scripts/assemble.ts +110 -0
  8. package/skills/c64-assembler/scripts/compare.ts +84 -0
  9. package/skills/c64-basic/SKILL.md +66 -0
  10. package/skills/c64-basic/scripts/basic.ts +46 -0
  11. package/skills/c64-disk/SKILL.md +93 -0
  12. package/skills/c64-disk/scripts/containers.ts +124 -0
  13. package/skills/c64-disk/scripts/disk.ts +120 -0
  14. package/skills/c64-emulator/SKILL.md +134 -0
  15. package/skills/c64-knowledge/SKILL.md +192 -0
  16. package/skills/c64-knowledge/scripts/knowledge.ts +613 -0
  17. package/skills/c64-memory-map/SKILL.md +79 -0
  18. package/skills/c64-memory-map/scripts/memmap.ts +92 -0
  19. package/skills/c64-provenance/SKILL.md +110 -0
  20. package/skills/c64-provenance/scripts/compare.ts +152 -0
  21. package/skills/c64-provenance/scripts/provenance.ts +334 -0
  22. package/skills/c64-provenance/scripts/runtime.ts +191 -0
  23. package/skills/c64-provenance/scripts/separate.ts +140 -0
  24. package/skills/c64-reverse-engineering/SKILL.md +144 -0
  25. package/skills/c64-source/SKILL.md +133 -0
  26. package/skills/c64-source/scripts/generate.ts +503 -0
  27. package/skills/c64-source/scripts/loader.ts +589 -0
  28. package/skills/c64-source/scripts/opcodes.ts +61 -0
  29. package/skills/c64-source/scripts/source.ts +673 -0
  30. package/skills/c64-static-analysis/SKILL.md +120 -0
  31. package/skills/c64-static-analysis/scripts/analyze.ts +293 -0
  32. package/skills/c64-static-analysis/scripts/coverage.ts +78 -0
  33. package/skills/c64-static-analysis/scripts/findings.ts +75 -0
  34. package/skills/c64-static-analysis/scripts/idioms.ts +149 -0
  35. package/skills/c64-static-analysis/scripts/instructions.ts +105 -0
  36. package/skills/c64-static-analysis/scripts/pointers.ts +108 -0
  37. package/skills/c64-testing/SKILL.md +103 -0
  38. package/skills/c64-testing/references/scenario-format.md +116 -0
  39. package/skills/c64-testing/scripts/checklist.ts +51 -0
  40. package/skills/c64-testing/scripts/run.ts +189 -0
  41. package/skills/c64-testing/scripts/scenario.ts +493 -0
  42. package/skills/c64-testing/scripts/test.ts +65 -0
  43. package/skills/c64-unpacker/SKILL.md +135 -0
  44. package/skills/c64-unpacker/scripts/evidence.ts +207 -0
  45. package/skills/c64-unpacker/scripts/loads.ts +209 -0
  46. package/skills/c64-unpacker/scripts/machine.ts +80 -0
  47. package/skills/c64-unpacker/scripts/stages.ts +130 -0
  48. package/skills/c64-unpacker/scripts/unpack.ts +683 -0
  49. package/src/c64.ts +411 -0
  50. package/src/cli/ap-sdk.ts +44 -0
  51. package/src/cli/cleanup.ts +194 -0
  52. package/src/cli/main.ts +125 -0
  53. package/src/cli/status.ts +61 -0
  54. package/src/host/main.ts +134 -0
  55. package/src/host/server.ts +392 -0
  56. package/src/host/tools/c1541.ts +284 -0
  57. package/src/host/tools/index.ts +35 -0
  58. package/src/host/tools/petcat.ts +77 -0
  59. package/src/host/tools/status.ts +47 -0
  60. package/src/host/tools/version.ts +41 -0
  61. package/src/host/vice/adapter.ts +804 -0
  62. package/src/host/vice/binary-monitor.ts +389 -0
  63. package/src/host/vice/chips.ts +118 -0
  64. package/src/host/vice/connect.ts +34 -0
  65. package/src/host/vice/process.ts +413 -0
  66. package/src/host/vice/screen.ts +184 -0
  67. package/src/host/vice/session.ts +1426 -0
  68. package/src/host/vice/text-monitor.ts +223 -0
  69. package/src/host-client/autostart.ts +55 -0
  70. package/src/host-client/connect.ts +241 -0
  71. package/src/host-client/coverage.ts +63 -0
  72. package/src/host-client/image.ts +63 -0
  73. package/src/host-client/steps.ts +170 -0
  74. package/src/host-client/tools.ts +89 -0
  75. package/src/host-client/transfer.ts +126 -0
  76. package/src/host-client/vice-session.ts +316 -0
  77. package/src/knowledge/database.ts +132 -0
  78. package/src/knowledge/expression.ts +209 -0
  79. package/src/knowledge/history.ts +169 -0
  80. package/src/knowledge/import.ts +392 -0
  81. package/src/knowledge/read.ts +392 -0
  82. package/src/knowledge/schema.ts +250 -0
  83. package/src/knowledge/write.ts +837 -0
  84. package/src/mcp/main.ts +134 -0
  85. package/src/mcp/output.ts +32 -0
  86. package/src/mcp/server.ts +316 -0
  87. package/src/mcp/tools/debug.ts +327 -0
  88. package/src/mcp/tools/execution.ts +117 -0
  89. package/src/mcp/tools/input.ts +72 -0
  90. package/src/mcp/tools/machine.ts +100 -0
  91. package/src/mcp/tools/media.ts +129 -0
  92. package/src/mcp/tools/memory.ts +250 -0
  93. package/src/mcp/tools/video.ts +271 -0
  94. package/src/native/acme.ts +116 -0
  95. package/src/native/discover.ts +179 -0
  96. package/src/native/dxa.ts +166 -0
  97. package/src/native/ghidra/analyze.ts +86 -0
  98. package/src/native/ghidra/index.ts +173 -0
  99. package/src/native/ghidra/language/c64rt_6510.cspec +34 -0
  100. package/src/native/ghidra/language/c64rt_6510.ldefs +15 -0
  101. package/src/native/ghidra/language/c64rt_6510.pspec +15 -0
  102. package/src/native/ghidra/language/c64rt_6510.slaspec +596 -0
  103. package/src/native/ghidra/scripts/C64Export.java +274 -0
  104. package/src/native/ghidra/scripts/C64Prepare.java +60 -0
  105. package/src/native/local.ts +34 -0
  106. package/src/native/processes.ts +350 -0
  107. package/src/native/run.ts +172 -0
  108. package/src/native/staging.ts +83 -0
  109. package/src/native/status.ts +113 -0
  110. package/src/native/types.ts +257 -0
  111. package/src/native/watchdog.ts +78 -0
  112. package/src/package.ts +21 -0
  113. package/src/platform.ts +441 -0
  114. package/src/project.ts +39 -0
  115. package/src/protocol/framing.ts +132 -0
  116. package/src/protocol/messages.ts +259 -0
  117. package/src/protocol/tools.ts +266 -0
  118. package/src/protocol/vice.ts +1348 -0
  119. package/src/script.ts +60 -0
  120. package/src/time.ts +15 -0
  121. package/src/trace.ts +194 -0
  122. package/THIRD-PARTY-NOTICES.md +0 -26
  123. package/bin/cli.mjs +0 -283
  124. package/skills/acme-build/SKILL.md +0 -260
  125. package/skills/acme-build/scripts/acme.mjs +0 -341
  126. package/skills/acme-build/template.a +0 -53
  127. package/skills/c64-disk-access/SKILL.md +0 -159
  128. package/skills/c64-disk-access/scripts/c1541.mjs +0 -569
  129. package/skills/c64-memory-mapping/SKILL.md +0 -631
  130. package/skills/c64-memory-mapping/memmap.json +0 -8800
  131. package/skills/c64-memory-mapping/scripts/driver.mjs +0 -553
  132. package/skills/c64-petcat/SKILL.md +0 -87
  133. package/skills/c64-petcat/scripts/petcat.mjs +0 -221
  134. package/skills/c64-program-recon/SKILL.md +0 -706
  135. package/skills/c64-program-recon/references/control-flow.md +0 -180
  136. package/skills/c64-program-recon/references/graphics.md +0 -79
  137. package/skills/c64-program-recon/references/observation-hazards.md +0 -143
  138. package/skills/c64-program-recon/references/reconstruction.md +0 -133
  139. package/skills/c64-program-recon/references/sound-and-input.md +0 -74
  140. package/skills/c64-program-recon/references/tool-selection.md +0 -78
  141. package/skills/c64-program-recon/scripts/derive.mjs +0 -364
  142. package/skills/c64-program-recon/scripts/packer-finding.mjs +0 -709
  143. package/skills/c64-program-recon/templates/memory-map.template.md +0 -101
  144. package/skills/c64-provenance-diff/SKILL.md +0 -292
  145. package/skills/c64-provenance-diff/scripts/diff-images.mjs +0 -984
  146. package/skills/c64-provenance-diff/scripts/recovery-schema.mjs +0 -395
  147. package/skills/c64-ram-capture/RELEASES.json.example +0 -17
  148. package/skills/c64-ram-capture/SKILL.md +0 -474
  149. package/skills/c64-ram-capture/scripts/compare-cross-binary.mjs +0 -525
  150. package/skills/c64-ram-capture/scripts/compare.mjs +0 -258
  151. package/skills/c64-ram-capture/scripts/derive-transients.mjs +0 -575
  152. package/skills/c64-ram-capture/scripts/dump-artifacts.mjs +0 -317
  153. package/skills/c64-ram-capture/scripts/mcp-module.mjs +0 -174
  154. package/skills/c64-ram-capture/scripts/project-paths.mjs +0 -81
  155. package/skills/c64-ram-capture/scripts/releases.mjs +0 -109
  156. package/skills/c64-ram-capture/scripts/vsf-slice.mjs +0 -147
  157. package/skills/c64-ram-capture/scripts/watch-loads.mjs +0 -581
  158. package/skills/c64-ram-capture/templates/capture-record.template.md +0 -99
  159. package/skills/c64-ram-capture/transients/README.md +0 -137
  160. package/skills/routine-queue-walker/SKILL.md +0 -394
  161. package/skills/routine-queue-walker/scripts/completeness-report.mjs +0 -465
  162. package/skills/vice-wedge-triage/SKILL.md +0 -269
@@ -0,0 +1,130 @@
1
+ // The stage rule of the c64-unpacker script (D43, F-17). The memory map keeps
2
+ // no order: a written and executed byte can be code that ran first and was
3
+ // written over later, as a decruncher does to its own start code. So a stage
4
+ // starts only where the CPU executes an opcode byte that the current stage
5
+ // wrote before the CPU got there. Code that the stage executed before it wrote
6
+ // it is the stage's own code: it stops the run once, and then a write watch
7
+ // over it arms it again. Written code that the stage calls, and that returns
8
+ // to the stage, is the stage's own code too (D59): a packer hands off by JMP,
9
+ // RTS or RTI and never runs its own code again.
10
+
11
+ import { COVERAGE } from "#src/c64.ts";
12
+ import { writtenBlocks } from "#src/host-client/coverage.ts";
13
+
14
+ export interface Range {
15
+ start: number;
16
+ end: number;
17
+ }
18
+
19
+ const contains = (range: Range, address: number) => address >= range.start && address <= range.end;
20
+
21
+ /** The flags of two maps from $0000 in one. */
22
+ export function mergeMaps(into: Uint8Array, from: Uint8Array): void {
23
+ for (let address = 0; address < into.length; address++) into[address]! |= from[address]!;
24
+ }
25
+
26
+ /**
27
+ * The written blocks of at least `minimum` bytes in which a chunk executed
28
+ * code that can start a stage: every executed address except own code that
29
+ * the stage has not written.
30
+ */
31
+ export function stageCandidates(stage: Uint8Array, chunk: Uint8Array, own: ReadonlySet<number>, minimum: number, called: readonly Range[] = []): Range[] {
32
+ const combined = Uint8Array.from(stage);
33
+ mergeMaps(combined, chunk);
34
+ return writtenBlocks(combined, minimum).filter((block) => {
35
+ for (let address = block.start; address <= block.end; address++) {
36
+ if ((chunk[address]! & COVERAGE.ramExecute) === 0) continue;
37
+ if (inRanges(called, address)) continue;
38
+ if (own.has(address) && (combined[address]! & COVERAGE.ramWrite) === 0) continue;
39
+ return true;
40
+ }
41
+ return false;
42
+ });
43
+ }
44
+
45
+ /**
46
+ * The points of a run over the candidate blocks: exec breakpoints over all of
47
+ * them except own code that is not written yet, and write watches over that
48
+ * own code.
49
+ */
50
+ export function stagePoints(blocks: readonly Range[], own: ReadonlySet<number>, written: (address: number) => boolean, called: readonly Range[] = []): { exec: Range[]; watch: Range[] } {
51
+ const exec: Range[] = [];
52
+ const watch: Range[] = [];
53
+ const add = (list: Range[], address: number) => {
54
+ const last = list[list.length - 1];
55
+ if (last !== undefined && last.end === address - 1) last.end = address;
56
+ else list.push({ start: address, end: address });
57
+ };
58
+ for (const block of blocks) {
59
+ for (let address = block.start; address <= block.end; address++) {
60
+ if (inRanges(called, address)) continue;
61
+ if (own.has(address) && !written(address)) add(watch, address);
62
+ else add(exec, address);
63
+ }
64
+ }
65
+ return { exec, watch };
66
+ }
67
+
68
+ /** True when the address lies in one of the ranges. */
69
+ export function inRanges(ranges: readonly Range[], address: number): boolean {
70
+ return ranges.some((range) => contains(range, address));
71
+ }
72
+
73
+ /**
74
+ * Where a call returns to the stage (D59): the return address on top of the
75
+ * stack, when a JSR that the stage executed pushed it. `stack` is page 1.
76
+ * Returns the address of the instruction after that JSR.
77
+ */
78
+ export function callReturn(stack: Uint8Array, sp: number, byteAt: (address: number) => number, executed: (address: number) => boolean): number | undefined {
79
+ const pushed = stack[(sp + 1) & 0xff]! | (stack[(sp + 2) & 0xff]! << 8);
80
+ const jsr = (pushed - 2) & 0xffff;
81
+ if (byteAt(jsr) !== 0x20 || !executed(jsr)) return undefined;
82
+ return (pushed + 1) & 0xffff;
83
+ }
84
+
85
+ /**
86
+ * The code that ran in a block: its executed opcode bytes with the two bytes
87
+ * after each, which can be operands, joined and cut at the block's end.
88
+ */
89
+ export function executedIn(map: Uint8Array, block: Range): Range[] {
90
+ const ranges: Range[] = [];
91
+ for (let address = block.start; address <= block.end; address++) {
92
+ if ((map[address]! & COVERAGE.ramExecute) === 0) continue;
93
+ const end = Math.min(block.end, address + 2);
94
+ const last = ranges[ranges.length - 1];
95
+ if (last !== undefined && address <= last.end + 1) last.end = Math.max(last.end, end);
96
+ else ranges.push({ start: address, end });
97
+ }
98
+ return ranges;
99
+ }
100
+
101
+ /**
102
+ * The segments of a capture: the blocks that the stages wrote, without loader
103
+ * leftovers, joined into ranges that do not overlap or touch (F-26). A block
104
+ * is a leftover when it holds the entry of an intermediate stage that started
105
+ * after the block's writer, and no write from that stage on replaced the code
106
+ * at that entry (R2-01). Code that a stage ran before a later stage wrote over
107
+ * it never drops a block, and the block that holds the capture entry is always
108
+ * a segment. The filter comes before the join: a join first would drop the
109
+ * program with a leftover. `writtenBy` is the last stage that wrote into the
110
+ * range.
111
+ */
112
+ export function captureSegments(stages: ReadonlyArray<{ entry: number; wrote: readonly Range[] }>, entry: number): Array<Range & { writtenBy: number }> {
113
+ const last = stages.length - 1;
114
+ const replaced = (from: number, address: number) => stages.slice(from).some((stage) => inRanges(stage.wrote, address));
115
+ const leftover = (block: Range, writer: number) =>
116
+ !contains(block, entry) && stages.some((stage, index) => index > writer && index < last && contains(block, stage.entry) && !replaced(index, stage.entry));
117
+ const blocks = stages
118
+ .flatMap((stage, index) => stage.wrote.map((range) => ({ start: range.start, end: range.end, writtenBy: index })))
119
+ .filter((block) => !leftover(block, block.writtenBy))
120
+ .sort((a, b) => a.start - b.start);
121
+ const segments: Array<Range & { writtenBy: number }> = [];
122
+ for (const block of blocks) {
123
+ const previous = segments[segments.length - 1];
124
+ if (previous !== undefined && block.start <= previous.end + 1) {
125
+ previous.end = Math.max(previous.end, block.end);
126
+ previous.writtenBy = Math.max(previous.writtenBy, block.writtenBy);
127
+ } else segments.push({ ...block });
128
+ }
129
+ return segments;
130
+ }