c64bridge 0.8.1 → 0.9.1
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/.github/prompts/steer.prompt.md +55 -0
- package/AGENTS.md +9 -7
- package/README.md +192 -154
- package/data/embeddings_asm.json +1 -1
- package/data/embeddings_basic.json +1 -1
- package/data/embeddings_hardware.json +1 -1
- package/data/embeddings_mixed.json +1 -1
- package/data/embeddings_other.json +1 -1
- package/data/graphics/petscii-style-guide.md +4 -4
- package/data/graphics/sprite-charset-best-practices.md +9 -9
- package/data/vice/vice-binary-monitor-spec.md +938 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/c64Client.js +76 -2
- package/dist/device.js +129 -13
- package/dist/mcp-server.js +1 -1
- package/dist/prompts/registry.js +27 -25
- package/dist/rag/indexer.js +18 -8
- package/dist/rag/knowledgeIndex.js +112 -79
- package/dist/rag/resourceUris.js +93 -0
- package/dist/sidwaveCompiler.js +1 -1
- package/dist/{assemblyConverter.js → tools/assember.js} +10 -1
- package/dist/tools/audio.js +11 -11
- package/dist/{basicConverter.js → tools/basicTokenizer.js} +1 -1
- package/dist/tools/debug.js +159 -6
- package/dist/tools/developer.js +13 -13
- package/dist/tools/disassembler.js +478 -0
- package/dist/tools/graphics.js +10 -10
- package/dist/tools/input.js +338 -0
- package/dist/tools/machineControl.js +5 -5
- package/dist/tools/memory.js +336 -12
- package/dist/tools/meta/index.js +1 -1
- package/dist/tools/printer.js +11 -12
- package/dist/tools/programRunners.js +61 -22
- package/dist/tools/rag.js +9 -9
- package/dist/tools/registry/batch.js +167 -0
- package/dist/tools/registry/config.js +1 -1
- package/dist/tools/registry/disk.js +1 -1
- package/dist/tools/registry/drive.js +1 -1
- package/dist/tools/registry/extract.js +1 -1
- package/dist/tools/registry/graphics.js +102 -2
- package/dist/tools/registry/index.js +4 -0
- package/dist/tools/registry/input.js +2 -0
- package/dist/tools/registry/memory.js +62 -2
- package/dist/tools/registry/platform.js +1 -1
- package/dist/tools/registry/printer.js +1 -1
- package/dist/tools/registry/program.js +1 -1
- package/dist/tools/registry/rag.js +1 -1
- package/dist/tools/registry/sound.js +1 -1
- package/dist/tools/registry/stream.js +1 -1
- package/dist/tools/registry/system.js +1 -1
- package/dist/tools/schema.js +4 -5
- package/dist/tools/storage.js +15 -15
- package/dist/tools/streaming.js +3 -3
- package/dist/tools/symbolRegistry.js +49 -0
- package/dist/tools/types.js +56 -4
- package/dist/tools/vice.js +2 -5
- package/dist/vice/process.js +120 -2
- package/dist/vice/readiness.js +35 -0
- package/dist/vice/smokeOptions.js +44 -0
- package/dist/vice/viceClient.js +5 -1
- package/dist/viceRunner.js +2 -0
- package/doc/plans/prompts/README.md +7 -7
- package/mcp/prompts.json +42 -59
- package/mcp/protocol-examples.json +2 -2
- package/mcp/resources.json +179 -166
- package/mcp/schemas/c64_batch.schema.json +53 -0
- package/mcp/schemas/c64_config.schema.json +525 -283
- package/mcp/schemas/c64_debug.schema.json +763 -304
- package/mcp/schemas/c64_disk.schema.json +499 -243
- package/mcp/schemas/c64_drive.schema.json +165 -90
- package/mcp/schemas/c64_extract.schema.json +533 -274
- package/mcp/schemas/c64_graphics.schema.json +607 -295
- package/mcp/schemas/c64_input.schema.json +136 -0
- package/mcp/schemas/c64_memory.schema.json +637 -128
- package/mcp/schemas/c64_printer.schema.json +393 -196
- package/mcp/schemas/c64_program.schema.json +699 -340
- package/mcp/schemas/c64_rag.schema.json +100 -54
- package/mcp/schemas/c64_select_backend.schema.json +49 -23
- package/mcp/schemas/c64_sound.schema.json +1092 -577
- package/mcp/schemas/c64_stream.schema.json +89 -47
- package/mcp/schemas/c64_system.schema.json +351 -185
- package/mcp/schemas/c64_vice.schema.json +85 -47
- package/mcp/server.json +1 -1
- package/mcp/tools.json +7299 -3346
- package/mcp.json +3 -3
- package/package.json +17 -14
- package/scripts/fetch-external-sources.mjs +1 -2
- package/scripts/run-coverage.mjs +33 -1
- package/scripts/run-tests.mjs +2 -2
- package/scripts/run-tests.ts +275 -52
- package/scripts/update-readme.ts +132 -3
- package/server.json +2 -2
|
@@ -0,0 +1,478 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 6502/6510 disassembler covering the full 256-opcode space, including
|
|
3
|
+
* undocumented (illegal) opcodes. Mnemonic naming follows the canonical
|
|
4
|
+
* convention used by the 1541U monitor (HLT->JAM, ASO->SLO, LSE->SRE,
|
|
5
|
+
* DCM->DCP, INS->ISC).
|
|
6
|
+
*/
|
|
7
|
+
function entry(mnemonic, mode, illegal = false) {
|
|
8
|
+
return { mnemonic, mode, illegal };
|
|
9
|
+
}
|
|
10
|
+
// Canonicalization rules from disassembler_6502.cc:
|
|
11
|
+
// HLT -> JAM, ASO -> SLO, LSE -> SRE, DCM -> DCP, INS -> ISC
|
|
12
|
+
function canonical(mnemonic) {
|
|
13
|
+
switch (mnemonic) {
|
|
14
|
+
case "HLT": return "JAM";
|
|
15
|
+
case "ASO": return "SLO";
|
|
16
|
+
case "LSE": return "SRE";
|
|
17
|
+
case "DCM": return "DCP";
|
|
18
|
+
case "INS": return "ISC";
|
|
19
|
+
default: return mnemonic;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
// 256-entry opcode table mirroring `opcode_templates` in disassembler_6502.cc.
|
|
23
|
+
// `illegal` is taken from the bitmap `illegal_map` in the same reference.
|
|
24
|
+
const OPCODES = (() => {
|
|
25
|
+
// Build the illegal-opcode bitmap from the reference file.
|
|
26
|
+
const ILLEGAL_MAP = [
|
|
27
|
+
0x989C, 0x9C9C, 0x888C, 0x9C9C,
|
|
28
|
+
0x889C, 0x9C9C, 0x889C, 0x9C9C,
|
|
29
|
+
0x8A8D, 0xD88C, 0x8888, 0x888C,
|
|
30
|
+
0x888C, 0x9C9C, 0x888C, 0x9C9C,
|
|
31
|
+
];
|
|
32
|
+
const isIllegal = (op) => {
|
|
33
|
+
const row = ILLEGAL_MAP[op >> 4];
|
|
34
|
+
return ((row >> (op & 0x0F)) & 1) !== 0;
|
|
35
|
+
};
|
|
36
|
+
const t = new Array(256);
|
|
37
|
+
// Helper: fill one row of 16 entries by mnemonic/mode pairs.
|
|
38
|
+
const set = (op, mnemonic, mode) => {
|
|
39
|
+
t[op] = { mnemonic: canonical(mnemonic), mode, illegal: isIllegal(op) };
|
|
40
|
+
};
|
|
41
|
+
// 0x00-0x0F
|
|
42
|
+
set(0x00, "BRK", 0 /* Mode.Imp */);
|
|
43
|
+
set(0x01, "ORA", 12 /* Mode.IndX */);
|
|
44
|
+
set(0x02, "HLT", 0 /* Mode.Imp */);
|
|
45
|
+
set(0x03, "ASO", 12 /* Mode.IndX */);
|
|
46
|
+
set(0x04, "NOP", 3 /* Mode.Zp */);
|
|
47
|
+
set(0x05, "ORA", 3 /* Mode.Zp */);
|
|
48
|
+
set(0x06, "ASL", 3 /* Mode.Zp */);
|
|
49
|
+
set(0x07, "ASO", 3 /* Mode.Zp */);
|
|
50
|
+
set(0x08, "PHP", 0 /* Mode.Imp */);
|
|
51
|
+
set(0x09, "ORA", 2 /* Mode.Imm */);
|
|
52
|
+
set(0x0A, "ASL", 1 /* Mode.Acc */);
|
|
53
|
+
set(0x0B, "ANC", 2 /* Mode.Imm */);
|
|
54
|
+
set(0x0C, "NOP", 8 /* Mode.Abs */);
|
|
55
|
+
set(0x0D, "ORA", 8 /* Mode.Abs */);
|
|
56
|
+
set(0x0E, "ASL", 8 /* Mode.Abs */);
|
|
57
|
+
set(0x0F, "ASO", 8 /* Mode.Abs */);
|
|
58
|
+
// 0x10-0x1F
|
|
59
|
+
set(0x10, "BPL", 7 /* Mode.Rel */);
|
|
60
|
+
set(0x11, "ORA", 13 /* Mode.IndY */);
|
|
61
|
+
set(0x12, "HLT", 0 /* Mode.Imp */);
|
|
62
|
+
set(0x13, "ASO", 13 /* Mode.IndY */);
|
|
63
|
+
set(0x14, "NOP", 4 /* Mode.ZpX */);
|
|
64
|
+
set(0x15, "ORA", 4 /* Mode.ZpX */);
|
|
65
|
+
set(0x16, "ASL", 4 /* Mode.ZpX */);
|
|
66
|
+
set(0x17, "ASO", 4 /* Mode.ZpX */);
|
|
67
|
+
set(0x18, "CLC", 0 /* Mode.Imp */);
|
|
68
|
+
set(0x19, "ORA", 10 /* Mode.AbsY */);
|
|
69
|
+
set(0x1A, "NOP", 0 /* Mode.Imp */);
|
|
70
|
+
set(0x1B, "ASO", 10 /* Mode.AbsY */);
|
|
71
|
+
set(0x1C, "NOP", 9 /* Mode.AbsX */);
|
|
72
|
+
set(0x1D, "ORA", 9 /* Mode.AbsX */);
|
|
73
|
+
set(0x1E, "ASL", 9 /* Mode.AbsX */);
|
|
74
|
+
set(0x1F, "ASO", 9 /* Mode.AbsX */);
|
|
75
|
+
// 0x20-0x2F
|
|
76
|
+
set(0x20, "JSR", 8 /* Mode.Abs */);
|
|
77
|
+
set(0x21, "AND", 12 /* Mode.IndX */);
|
|
78
|
+
set(0x22, "HLT", 0 /* Mode.Imp */);
|
|
79
|
+
set(0x23, "RLA", 12 /* Mode.IndX */);
|
|
80
|
+
set(0x24, "BIT", 3 /* Mode.Zp */);
|
|
81
|
+
set(0x25, "AND", 3 /* Mode.Zp */);
|
|
82
|
+
set(0x26, "ROL", 3 /* Mode.Zp */);
|
|
83
|
+
set(0x27, "RLA", 3 /* Mode.Zp */);
|
|
84
|
+
set(0x28, "PLP", 0 /* Mode.Imp */);
|
|
85
|
+
set(0x29, "AND", 2 /* Mode.Imm */);
|
|
86
|
+
set(0x2A, "ROL", 1 /* Mode.Acc */);
|
|
87
|
+
set(0x2B, "ANC", 2 /* Mode.Imm */);
|
|
88
|
+
set(0x2C, "BIT", 8 /* Mode.Abs */);
|
|
89
|
+
set(0x2D, "AND", 8 /* Mode.Abs */);
|
|
90
|
+
set(0x2E, "ROL", 8 /* Mode.Abs */);
|
|
91
|
+
set(0x2F, "RLA", 8 /* Mode.Abs */);
|
|
92
|
+
// 0x30-0x3F
|
|
93
|
+
set(0x30, "BMI", 7 /* Mode.Rel */);
|
|
94
|
+
set(0x31, "AND", 13 /* Mode.IndY */);
|
|
95
|
+
set(0x32, "HLT", 0 /* Mode.Imp */);
|
|
96
|
+
set(0x33, "RLA", 13 /* Mode.IndY */);
|
|
97
|
+
set(0x34, "NOP", 4 /* Mode.ZpX */);
|
|
98
|
+
set(0x35, "AND", 4 /* Mode.ZpX */);
|
|
99
|
+
set(0x36, "ROL", 4 /* Mode.ZpX */);
|
|
100
|
+
set(0x37, "RLA", 4 /* Mode.ZpX */);
|
|
101
|
+
set(0x38, "SEC", 0 /* Mode.Imp */);
|
|
102
|
+
set(0x39, "AND", 10 /* Mode.AbsY */);
|
|
103
|
+
set(0x3A, "NOP", 0 /* Mode.Imp */);
|
|
104
|
+
set(0x3B, "RLA", 10 /* Mode.AbsY */);
|
|
105
|
+
set(0x3C, "NOP", 9 /* Mode.AbsX */);
|
|
106
|
+
set(0x3D, "AND", 9 /* Mode.AbsX */);
|
|
107
|
+
set(0x3E, "ROL", 9 /* Mode.AbsX */);
|
|
108
|
+
set(0x3F, "RLA", 9 /* Mode.AbsX */);
|
|
109
|
+
// 0x40-0x4F
|
|
110
|
+
set(0x40, "RTI", 0 /* Mode.Imp */);
|
|
111
|
+
set(0x41, "EOR", 12 /* Mode.IndX */);
|
|
112
|
+
set(0x42, "HLT", 0 /* Mode.Imp */);
|
|
113
|
+
set(0x43, "LSE", 12 /* Mode.IndX */);
|
|
114
|
+
set(0x44, "NOP", 3 /* Mode.Zp */);
|
|
115
|
+
set(0x45, "EOR", 3 /* Mode.Zp */);
|
|
116
|
+
set(0x46, "LSR", 3 /* Mode.Zp */);
|
|
117
|
+
set(0x47, "LSE", 3 /* Mode.Zp */);
|
|
118
|
+
set(0x48, "PHA", 0 /* Mode.Imp */);
|
|
119
|
+
set(0x49, "EOR", 2 /* Mode.Imm */);
|
|
120
|
+
set(0x4A, "LSR", 1 /* Mode.Acc */);
|
|
121
|
+
set(0x4B, "ALR", 2 /* Mode.Imm */);
|
|
122
|
+
set(0x4C, "JMP", 8 /* Mode.Abs */);
|
|
123
|
+
set(0x4D, "EOR", 8 /* Mode.Abs */);
|
|
124
|
+
set(0x4E, "LSR", 8 /* Mode.Abs */);
|
|
125
|
+
set(0x4F, "LSE", 8 /* Mode.Abs */);
|
|
126
|
+
// 0x50-0x5F
|
|
127
|
+
set(0x50, "BVC", 7 /* Mode.Rel */);
|
|
128
|
+
set(0x51, "EOR", 13 /* Mode.IndY */);
|
|
129
|
+
set(0x52, "HLT", 0 /* Mode.Imp */);
|
|
130
|
+
set(0x53, "LSE", 13 /* Mode.IndY */);
|
|
131
|
+
set(0x54, "NOP", 4 /* Mode.ZpX */);
|
|
132
|
+
set(0x55, "EOR", 4 /* Mode.ZpX */);
|
|
133
|
+
set(0x56, "LSR", 4 /* Mode.ZpX */);
|
|
134
|
+
set(0x57, "LSE", 4 /* Mode.ZpX */);
|
|
135
|
+
set(0x58, "CLI", 0 /* Mode.Imp */);
|
|
136
|
+
set(0x59, "EOR", 10 /* Mode.AbsY */);
|
|
137
|
+
set(0x5A, "NOP", 0 /* Mode.Imp */);
|
|
138
|
+
set(0x5B, "LSE", 10 /* Mode.AbsY */);
|
|
139
|
+
set(0x5C, "NOP", 9 /* Mode.AbsX */);
|
|
140
|
+
set(0x5D, "EOR", 9 /* Mode.AbsX */);
|
|
141
|
+
set(0x5E, "LSR", 9 /* Mode.AbsX */);
|
|
142
|
+
set(0x5F, "LSE", 9 /* Mode.AbsX */);
|
|
143
|
+
// 0x60-0x6F
|
|
144
|
+
set(0x60, "RTS", 0 /* Mode.Imp */);
|
|
145
|
+
set(0x61, "ADC", 12 /* Mode.IndX */);
|
|
146
|
+
set(0x62, "HLT", 0 /* Mode.Imp */);
|
|
147
|
+
set(0x63, "RRA", 12 /* Mode.IndX */);
|
|
148
|
+
set(0x64, "NOP", 3 /* Mode.Zp */);
|
|
149
|
+
set(0x65, "ADC", 3 /* Mode.Zp */);
|
|
150
|
+
set(0x66, "ROR", 3 /* Mode.Zp */);
|
|
151
|
+
set(0x67, "RRA", 3 /* Mode.Zp */);
|
|
152
|
+
set(0x68, "PLA", 0 /* Mode.Imp */);
|
|
153
|
+
set(0x69, "ADC", 2 /* Mode.Imm */);
|
|
154
|
+
set(0x6A, "ROR", 1 /* Mode.Acc */);
|
|
155
|
+
set(0x6B, "ARR", 2 /* Mode.Imm */);
|
|
156
|
+
set(0x6C, "JMP", 11 /* Mode.Ind */);
|
|
157
|
+
set(0x6D, "ADC", 8 /* Mode.Abs */);
|
|
158
|
+
set(0x6E, "ROR", 8 /* Mode.Abs */);
|
|
159
|
+
set(0x6F, "RRA", 8 /* Mode.Abs */);
|
|
160
|
+
// 0x70-0x7F
|
|
161
|
+
set(0x70, "BVS", 7 /* Mode.Rel */);
|
|
162
|
+
set(0x71, "ADC", 13 /* Mode.IndY */);
|
|
163
|
+
set(0x72, "HLT", 0 /* Mode.Imp */);
|
|
164
|
+
set(0x73, "RRA", 13 /* Mode.IndY */);
|
|
165
|
+
set(0x74, "NOP", 4 /* Mode.ZpX */);
|
|
166
|
+
set(0x75, "ADC", 4 /* Mode.ZpX */);
|
|
167
|
+
set(0x76, "ROR", 4 /* Mode.ZpX */);
|
|
168
|
+
set(0x77, "RRA", 4 /* Mode.ZpX */);
|
|
169
|
+
set(0x78, "SEI", 0 /* Mode.Imp */);
|
|
170
|
+
set(0x79, "ADC", 10 /* Mode.AbsY */);
|
|
171
|
+
set(0x7A, "NOP", 0 /* Mode.Imp */);
|
|
172
|
+
set(0x7B, "RRA", 10 /* Mode.AbsY */);
|
|
173
|
+
set(0x7C, "NOP", 9 /* Mode.AbsX */);
|
|
174
|
+
set(0x7D, "ADC", 9 /* Mode.AbsX */);
|
|
175
|
+
set(0x7E, "ROR", 9 /* Mode.AbsX */);
|
|
176
|
+
set(0x7F, "RRA", 9 /* Mode.AbsX */);
|
|
177
|
+
// 0x80-0x8F
|
|
178
|
+
set(0x80, "NOP", 2 /* Mode.Imm */);
|
|
179
|
+
set(0x81, "STA", 12 /* Mode.IndX */);
|
|
180
|
+
set(0x82, "NOP", 2 /* Mode.Imm */);
|
|
181
|
+
set(0x83, "SAX", 12 /* Mode.IndX */);
|
|
182
|
+
set(0x84, "STY", 3 /* Mode.Zp */);
|
|
183
|
+
set(0x85, "STA", 3 /* Mode.Zp */);
|
|
184
|
+
set(0x86, "STX", 3 /* Mode.Zp */);
|
|
185
|
+
set(0x87, "SAX", 3 /* Mode.Zp */);
|
|
186
|
+
set(0x88, "DEY", 0 /* Mode.Imp */);
|
|
187
|
+
set(0x89, "NOP", 2 /* Mode.Imm */);
|
|
188
|
+
set(0x8A, "TXA", 0 /* Mode.Imp */);
|
|
189
|
+
set(0x8B, "XAA", 2 /* Mode.Imm */);
|
|
190
|
+
set(0x8C, "STY", 8 /* Mode.Abs */);
|
|
191
|
+
set(0x8D, "STA", 8 /* Mode.Abs */);
|
|
192
|
+
set(0x8E, "STX", 8 /* Mode.Abs */);
|
|
193
|
+
set(0x8F, "SAX", 8 /* Mode.Abs */);
|
|
194
|
+
// 0x90-0x9F
|
|
195
|
+
set(0x90, "BCC", 7 /* Mode.Rel */);
|
|
196
|
+
set(0x91, "STA", 13 /* Mode.IndY */);
|
|
197
|
+
set(0x92, "HLT", 0 /* Mode.Imp */);
|
|
198
|
+
set(0x93, "AHX", 13 /* Mode.IndY */);
|
|
199
|
+
set(0x94, "STY", 4 /* Mode.ZpX */);
|
|
200
|
+
set(0x95, "STA", 4 /* Mode.ZpX */);
|
|
201
|
+
set(0x96, "STX", 5 /* Mode.ZpY */);
|
|
202
|
+
set(0x97, "SAX", 5 /* Mode.ZpY */);
|
|
203
|
+
set(0x98, "TYA", 0 /* Mode.Imp */);
|
|
204
|
+
set(0x99, "STA", 10 /* Mode.AbsY */);
|
|
205
|
+
set(0x9A, "TXS", 0 /* Mode.Imp */);
|
|
206
|
+
set(0x9B, "TAS", 10 /* Mode.AbsY */);
|
|
207
|
+
set(0x9C, "SHY", 9 /* Mode.AbsX */);
|
|
208
|
+
set(0x9D, "STA", 9 /* Mode.AbsX */);
|
|
209
|
+
set(0x9E, "SHX", 10 /* Mode.AbsY */);
|
|
210
|
+
set(0x9F, "AHX", 10 /* Mode.AbsY */);
|
|
211
|
+
// 0xA0-0xAF
|
|
212
|
+
set(0xA0, "LDY", 2 /* Mode.Imm */);
|
|
213
|
+
set(0xA1, "LDA", 12 /* Mode.IndX */);
|
|
214
|
+
set(0xA2, "LDX", 2 /* Mode.Imm */);
|
|
215
|
+
set(0xA3, "LAX", 12 /* Mode.IndX */);
|
|
216
|
+
set(0xA4, "LDY", 3 /* Mode.Zp */);
|
|
217
|
+
set(0xA5, "LDA", 3 /* Mode.Zp */);
|
|
218
|
+
set(0xA6, "LDX", 3 /* Mode.Zp */);
|
|
219
|
+
set(0xA7, "LAX", 3 /* Mode.Zp */);
|
|
220
|
+
set(0xA8, "TAY", 0 /* Mode.Imp */);
|
|
221
|
+
set(0xA9, "LDA", 2 /* Mode.Imm */);
|
|
222
|
+
set(0xAA, "TAX", 0 /* Mode.Imp */);
|
|
223
|
+
set(0xAB, "LAX", 2 /* Mode.Imm */);
|
|
224
|
+
set(0xAC, "LDY", 8 /* Mode.Abs */);
|
|
225
|
+
set(0xAD, "LDA", 8 /* Mode.Abs */);
|
|
226
|
+
set(0xAE, "LDX", 8 /* Mode.Abs */);
|
|
227
|
+
set(0xAF, "LAX", 8 /* Mode.Abs */);
|
|
228
|
+
// 0xB0-0xBF
|
|
229
|
+
set(0xB0, "BCS", 7 /* Mode.Rel */);
|
|
230
|
+
set(0xB1, "LDA", 13 /* Mode.IndY */);
|
|
231
|
+
set(0xB2, "HLT", 0 /* Mode.Imp */);
|
|
232
|
+
set(0xB3, "LAX", 13 /* Mode.IndY */);
|
|
233
|
+
set(0xB4, "LDY", 4 /* Mode.ZpX */);
|
|
234
|
+
set(0xB5, "LDA", 4 /* Mode.ZpX */);
|
|
235
|
+
set(0xB6, "LDX", 5 /* Mode.ZpY */);
|
|
236
|
+
set(0xB7, "LAX", 5 /* Mode.ZpY */);
|
|
237
|
+
set(0xB8, "CLV", 0 /* Mode.Imp */);
|
|
238
|
+
set(0xB9, "LDA", 10 /* Mode.AbsY */);
|
|
239
|
+
set(0xBA, "TSX", 0 /* Mode.Imp */);
|
|
240
|
+
set(0xBB, "LAS", 10 /* Mode.AbsY */);
|
|
241
|
+
set(0xBC, "LDY", 9 /* Mode.AbsX */);
|
|
242
|
+
set(0xBD, "LDA", 9 /* Mode.AbsX */);
|
|
243
|
+
set(0xBE, "LDX", 10 /* Mode.AbsY */);
|
|
244
|
+
set(0xBF, "LAX", 10 /* Mode.AbsY */);
|
|
245
|
+
// 0xC0-0xCF
|
|
246
|
+
set(0xC0, "CPY", 2 /* Mode.Imm */);
|
|
247
|
+
set(0xC1, "CMP", 12 /* Mode.IndX */);
|
|
248
|
+
set(0xC2, "NOP", 2 /* Mode.Imm */);
|
|
249
|
+
set(0xC3, "DCM", 12 /* Mode.IndX */);
|
|
250
|
+
set(0xC4, "CPY", 3 /* Mode.Zp */);
|
|
251
|
+
set(0xC5, "CMP", 3 /* Mode.Zp */);
|
|
252
|
+
set(0xC6, "DEC", 3 /* Mode.Zp */);
|
|
253
|
+
set(0xC7, "DCM", 3 /* Mode.Zp */);
|
|
254
|
+
set(0xC8, "INY", 0 /* Mode.Imp */);
|
|
255
|
+
set(0xC9, "CMP", 2 /* Mode.Imm */);
|
|
256
|
+
set(0xCA, "DEX", 0 /* Mode.Imp */);
|
|
257
|
+
set(0xCB, "AXS", 2 /* Mode.Imm */);
|
|
258
|
+
set(0xCC, "CPY", 8 /* Mode.Abs */);
|
|
259
|
+
set(0xCD, "CMP", 8 /* Mode.Abs */);
|
|
260
|
+
set(0xCE, "DEC", 8 /* Mode.Abs */);
|
|
261
|
+
set(0xCF, "DCM", 8 /* Mode.Abs */);
|
|
262
|
+
// 0xD0-0xDF
|
|
263
|
+
set(0xD0, "BNE", 7 /* Mode.Rel */);
|
|
264
|
+
set(0xD1, "CMP", 13 /* Mode.IndY */);
|
|
265
|
+
set(0xD2, "HLT", 0 /* Mode.Imp */);
|
|
266
|
+
set(0xD3, "DCM", 13 /* Mode.IndY */);
|
|
267
|
+
set(0xD4, "NOP", 4 /* Mode.ZpX */);
|
|
268
|
+
set(0xD5, "CMP", 4 /* Mode.ZpX */);
|
|
269
|
+
set(0xD6, "DEC", 4 /* Mode.ZpX */);
|
|
270
|
+
set(0xD7, "DCM", 4 /* Mode.ZpX */);
|
|
271
|
+
set(0xD8, "CLD", 0 /* Mode.Imp */);
|
|
272
|
+
set(0xD9, "CMP", 10 /* Mode.AbsY */);
|
|
273
|
+
set(0xDA, "NOP", 0 /* Mode.Imp */);
|
|
274
|
+
set(0xDB, "DCM", 10 /* Mode.AbsY */);
|
|
275
|
+
set(0xDC, "NOP", 9 /* Mode.AbsX */);
|
|
276
|
+
set(0xDD, "CMP", 9 /* Mode.AbsX */);
|
|
277
|
+
set(0xDE, "DEC", 9 /* Mode.AbsX */);
|
|
278
|
+
set(0xDF, "DCM", 9 /* Mode.AbsX */);
|
|
279
|
+
// 0xE0-0xEF
|
|
280
|
+
set(0xE0, "CPX", 2 /* Mode.Imm */);
|
|
281
|
+
set(0xE1, "SBC", 12 /* Mode.IndX */);
|
|
282
|
+
set(0xE2, "NOP", 2 /* Mode.Imm */);
|
|
283
|
+
set(0xE3, "INS", 12 /* Mode.IndX */);
|
|
284
|
+
set(0xE4, "CPX", 3 /* Mode.Zp */);
|
|
285
|
+
set(0xE5, "SBC", 3 /* Mode.Zp */);
|
|
286
|
+
set(0xE6, "INC", 3 /* Mode.Zp */);
|
|
287
|
+
set(0xE7, "INS", 3 /* Mode.Zp */);
|
|
288
|
+
set(0xE8, "INX", 0 /* Mode.Imp */);
|
|
289
|
+
set(0xE9, "SBC", 2 /* Mode.Imm */);
|
|
290
|
+
set(0xEA, "NOP", 0 /* Mode.Imp */);
|
|
291
|
+
set(0xEB, "SBC", 2 /* Mode.Imm */);
|
|
292
|
+
set(0xEC, "CPX", 8 /* Mode.Abs */);
|
|
293
|
+
set(0xED, "SBC", 8 /* Mode.Abs */);
|
|
294
|
+
set(0xEE, "INC", 8 /* Mode.Abs */);
|
|
295
|
+
set(0xEF, "INS", 8 /* Mode.Abs */);
|
|
296
|
+
// 0xF0-0xFF
|
|
297
|
+
set(0xF0, "BEQ", 7 /* Mode.Rel */);
|
|
298
|
+
set(0xF1, "SBC", 13 /* Mode.IndY */);
|
|
299
|
+
set(0xF2, "HLT", 0 /* Mode.Imp */);
|
|
300
|
+
set(0xF3, "INS", 13 /* Mode.IndY */);
|
|
301
|
+
set(0xF4, "NOP", 6 /* Mode.ZpS */);
|
|
302
|
+
set(0xF5, "SBC", 4 /* Mode.ZpX */);
|
|
303
|
+
set(0xF6, "INC", 4 /* Mode.ZpX */);
|
|
304
|
+
set(0xF7, "INS", 4 /* Mode.ZpX */);
|
|
305
|
+
set(0xF8, "SED", 0 /* Mode.Imp */);
|
|
306
|
+
set(0xF9, "SBC", 10 /* Mode.AbsY */);
|
|
307
|
+
set(0xFA, "NOP", 0 /* Mode.Imp */);
|
|
308
|
+
set(0xFB, "INS", 10 /* Mode.AbsY */);
|
|
309
|
+
set(0xFC, "NOP", 9 /* Mode.AbsX */);
|
|
310
|
+
set(0xFD, "SBC", 9 /* Mode.AbsX */);
|
|
311
|
+
set(0xFE, "INC", 9 /* Mode.AbsX */);
|
|
312
|
+
set(0xFF, "INS", 9 /* Mode.AbsX */);
|
|
313
|
+
return t;
|
|
314
|
+
})();
|
|
315
|
+
function modeSize(mode) {
|
|
316
|
+
switch (mode) {
|
|
317
|
+
case 0 /* Mode.Imp */:
|
|
318
|
+
case 1 /* Mode.Acc */:
|
|
319
|
+
return 1;
|
|
320
|
+
case 2 /* Mode.Imm */:
|
|
321
|
+
case 3 /* Mode.Zp */:
|
|
322
|
+
case 4 /* Mode.ZpX */:
|
|
323
|
+
case 5 /* Mode.ZpY */:
|
|
324
|
+
case 6 /* Mode.ZpS */:
|
|
325
|
+
case 7 /* Mode.Rel */:
|
|
326
|
+
case 12 /* Mode.IndX */:
|
|
327
|
+
case 13 /* Mode.IndY */:
|
|
328
|
+
return 2;
|
|
329
|
+
case 8 /* Mode.Abs */:
|
|
330
|
+
case 9 /* Mode.AbsX */:
|
|
331
|
+
case 10 /* Mode.AbsY */:
|
|
332
|
+
case 11 /* Mode.Ind */:
|
|
333
|
+
return 3;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
function hex2(v) {
|
|
337
|
+
return v.toString(16).toUpperCase().padStart(2, "0");
|
|
338
|
+
}
|
|
339
|
+
function hex4(v) {
|
|
340
|
+
return v.toString(16).toUpperCase().padStart(4, "0");
|
|
341
|
+
}
|
|
342
|
+
function labelOrHex4(addr, symbols) {
|
|
343
|
+
const label = symbols?.get(addr);
|
|
344
|
+
return label ? `${label} ($${hex4(addr)})` : `$${hex4(addr)}`;
|
|
345
|
+
}
|
|
346
|
+
function formatOperand(mode, bytes, offset, instrAddr, symbols) {
|
|
347
|
+
switch (mode) {
|
|
348
|
+
case 0 /* Mode.Imp */:
|
|
349
|
+
return "";
|
|
350
|
+
case 1 /* Mode.Acc */:
|
|
351
|
+
return "A";
|
|
352
|
+
case 2 /* Mode.Imm */:
|
|
353
|
+
return `#$${hex2(bytes[offset + 1] ?? 0)}`;
|
|
354
|
+
case 3 /* Mode.Zp */:
|
|
355
|
+
return `$${hex2(bytes[offset + 1] ?? 0)}`;
|
|
356
|
+
case 4 /* Mode.ZpX */:
|
|
357
|
+
return `$${hex2(bytes[offset + 1] ?? 0)},X`;
|
|
358
|
+
case 5 /* Mode.ZpY */:
|
|
359
|
+
return `$${hex2(bytes[offset + 1] ?? 0)},Y`;
|
|
360
|
+
case 6 /* Mode.ZpS */:
|
|
361
|
+
return `$${hex2(bytes[offset + 1] ?? 0)},S`;
|
|
362
|
+
case 7 /* Mode.Rel */: {
|
|
363
|
+
const rel = bytes[offset + 1] ?? 0;
|
|
364
|
+
const signed = rel >= 0x80 ? rel - 0x100 : rel;
|
|
365
|
+
const target = (instrAddr + 2 + signed) & 0xffff;
|
|
366
|
+
return labelOrHex4(target, symbols);
|
|
367
|
+
}
|
|
368
|
+
case 8 /* Mode.Abs */: {
|
|
369
|
+
const lo = bytes[offset + 1] ?? 0;
|
|
370
|
+
const hi = bytes[offset + 2] ?? 0;
|
|
371
|
+
const addr = lo | (hi << 8);
|
|
372
|
+
return labelOrHex4(addr, symbols);
|
|
373
|
+
}
|
|
374
|
+
case 9 /* Mode.AbsX */: {
|
|
375
|
+
const lo = bytes[offset + 1] ?? 0;
|
|
376
|
+
const hi = bytes[offset + 2] ?? 0;
|
|
377
|
+
const addr = lo | (hi << 8);
|
|
378
|
+
return `${labelOrHex4(addr, symbols)},X`;
|
|
379
|
+
}
|
|
380
|
+
case 10 /* Mode.AbsY */: {
|
|
381
|
+
const lo = bytes[offset + 1] ?? 0;
|
|
382
|
+
const hi = bytes[offset + 2] ?? 0;
|
|
383
|
+
const addr = lo | (hi << 8);
|
|
384
|
+
return `${labelOrHex4(addr, symbols)},Y`;
|
|
385
|
+
}
|
|
386
|
+
case 11 /* Mode.Ind */: {
|
|
387
|
+
const lo = bytes[offset + 1] ?? 0;
|
|
388
|
+
const hi = bytes[offset + 2] ?? 0;
|
|
389
|
+
const addr = lo | (hi << 8);
|
|
390
|
+
return `($${hex4(addr)})`;
|
|
391
|
+
}
|
|
392
|
+
case 12 /* Mode.IndX */:
|
|
393
|
+
return `($${hex2(bytes[offset + 1] ?? 0)},X)`;
|
|
394
|
+
case 13 /* Mode.IndY */:
|
|
395
|
+
return `($${hex2(bytes[offset + 1] ?? 0)}),Y`;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Disassemble a block of 6502/6510 bytes.
|
|
400
|
+
*
|
|
401
|
+
* @param bytes Raw memory bytes (may be longer than needed)
|
|
402
|
+
* @param baseAddress The C64 memory address of `bytes[0]`
|
|
403
|
+
* @param countOrOptions Either a max-instruction count (legacy form) or an options object
|
|
404
|
+
* @param symbols Optional address->label map (legacy positional form)
|
|
405
|
+
*/
|
|
406
|
+
export function disassemble(bytes, baseAddress, countOrOptions, symbols) {
|
|
407
|
+
const options = typeof countOrOptions === "object" && countOrOptions !== null
|
|
408
|
+
? countOrOptions
|
|
409
|
+
: { count: countOrOptions, symbols };
|
|
410
|
+
const limit = options.count ?? Infinity;
|
|
411
|
+
const symMap = options.symbols ?? symbols;
|
|
412
|
+
const allowUndocumented = options.allowUndocumented !== false;
|
|
413
|
+
const lines = [];
|
|
414
|
+
let offset = 0;
|
|
415
|
+
while (offset < bytes.length && lines.length < limit) {
|
|
416
|
+
const instrAddr = (baseAddress + offset) & 0xffff;
|
|
417
|
+
const opcode = bytes[offset] ?? 0;
|
|
418
|
+
const op = OPCODES[opcode];
|
|
419
|
+
const label = symMap?.get(instrAddr);
|
|
420
|
+
if (op.illegal && !allowUndocumented) {
|
|
421
|
+
lines.push({
|
|
422
|
+
address: instrAddr,
|
|
423
|
+
bytes: [opcode],
|
|
424
|
+
label,
|
|
425
|
+
mnemonic: "???",
|
|
426
|
+
operand: `$${hex2(opcode)}`,
|
|
427
|
+
undocumented: true,
|
|
428
|
+
});
|
|
429
|
+
offset += 1;
|
|
430
|
+
continue;
|
|
431
|
+
}
|
|
432
|
+
const size = modeSize(op.mode);
|
|
433
|
+
const instrBytes = [];
|
|
434
|
+
for (let i = 0; i < size && offset + i < bytes.length; i++) {
|
|
435
|
+
instrBytes.push(bytes[offset + i] ?? 0);
|
|
436
|
+
}
|
|
437
|
+
const operand = formatOperand(op.mode, bytes, offset, instrAddr, symMap);
|
|
438
|
+
lines.push({
|
|
439
|
+
address: instrAddr,
|
|
440
|
+
bytes: instrBytes,
|
|
441
|
+
label,
|
|
442
|
+
mnemonic: op.mnemonic,
|
|
443
|
+
operand,
|
|
444
|
+
undocumented: op.illegal,
|
|
445
|
+
});
|
|
446
|
+
offset += size;
|
|
447
|
+
}
|
|
448
|
+
return lines;
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Render disassembly lines as a human-readable string.
|
|
452
|
+
* Format: [label:\n] $ADDR XX XX XX MNEM operand ; *undocumented*
|
|
453
|
+
*/
|
|
454
|
+
export function formatDisassembly(lines) {
|
|
455
|
+
const parts = [];
|
|
456
|
+
for (const line of lines) {
|
|
457
|
+
if (line.label) {
|
|
458
|
+
parts.push(`${line.label}:`);
|
|
459
|
+
}
|
|
460
|
+
const addrStr = `$${hex4(line.address)}`;
|
|
461
|
+
const byteStr = line.bytes.map((b) => hex2(b)).join(" ").padEnd(8);
|
|
462
|
+
const mnemonic = line.undocumented ? `${line.mnemonic}*` : line.mnemonic;
|
|
463
|
+
const instrStr = line.operand
|
|
464
|
+
? `${mnemonic} ${line.operand}`
|
|
465
|
+
: mnemonic;
|
|
466
|
+
parts.push(` ${addrStr} ${byteStr} ${instrStr}`);
|
|
467
|
+
}
|
|
468
|
+
return parts.join("\n");
|
|
469
|
+
}
|
|
470
|
+
/** Returns true when the opcode is undocumented per the 1541U reference. */
|
|
471
|
+
export function isUndocumentedOpcode(opcode) {
|
|
472
|
+
return OPCODES[opcode & 0xff].illegal;
|
|
473
|
+
}
|
|
474
|
+
/** Lookup helper used by tests to verify table coverage. */
|
|
475
|
+
export function opcodeMetadata(opcode) {
|
|
476
|
+
const entry = OPCODES[opcode & 0xff];
|
|
477
|
+
return { mnemonic: entry.mnemonic, undocumented: entry.illegal, size: modeSize(entry.mode) };
|
|
478
|
+
}
|
package/dist/tools/graphics.js
CHANGED
|
@@ -546,9 +546,9 @@ export const graphicsModule = defineToolModule({
|
|
|
546
546
|
domain: "graphics",
|
|
547
547
|
summary: "PETSCII art, sprite workflows, and VIC-II graphics helpers.",
|
|
548
548
|
resources: [
|
|
549
|
-
"c64://
|
|
550
|
-
"c64://
|
|
551
|
-
"c64://
|
|
549
|
+
"c64://graphics/vic/spec",
|
|
550
|
+
"c64://assembly/6510-spec",
|
|
551
|
+
"c64://basic/spec",
|
|
552
552
|
],
|
|
553
553
|
prompts: ["graphics-demo", "basic-program", "assembly-program"],
|
|
554
554
|
defaultTags: ["graphics", "vic"],
|
|
@@ -559,10 +559,10 @@ export const graphicsModule = defineToolModule({
|
|
|
559
559
|
tools: [
|
|
560
560
|
{
|
|
561
561
|
name: "render_sprite",
|
|
562
|
-
description: "Display supplied 63-byte sprite data at the requested position and colour by writing memory and patching VIC-II registers directly. See c64://
|
|
562
|
+
description: "Display supplied 63-byte sprite data at the requested position and colour by writing memory and patching VIC-II registers directly. See c64://graphics/vic/spec for registers.",
|
|
563
563
|
summary: "Writes sprite data into RAM, updates the sprite pointer table, and patches VIC-II registers to render a sprite preview.",
|
|
564
564
|
inputSchema: spriteArgsSchema.jsonSchema,
|
|
565
|
-
relatedResources: ["c64://
|
|
565
|
+
relatedResources: ["c64://graphics/vic/spec"],
|
|
566
566
|
relatedPrompts: ["graphics-demo", "assembly-program"],
|
|
567
567
|
tags: ["sprite", "assembly", "pal-ntsc"],
|
|
568
568
|
prerequisites: ["upload_run_asm"],
|
|
@@ -587,7 +587,7 @@ export const graphicsModule = defineToolModule({
|
|
|
587
587
|
description: "Import an image file, convert it to a VIC-II bitmap, write it into RAM, and display it.",
|
|
588
588
|
summary: "Decodes a source image, quantizes it into C64 colours, writes bitmap/screen/color RAM, and displays it in hires or multicolor bitmap mode.",
|
|
589
589
|
inputSchema: generateBitmapArgsSchema.jsonSchema,
|
|
590
|
-
relatedResources: ["c64://
|
|
590
|
+
relatedResources: ["c64://graphics/vic/spec", "c64://guide/bootstrap"],
|
|
591
591
|
relatedPrompts: ["graphics-demo"],
|
|
592
592
|
tags: ["bitmap", "vic", "image"],
|
|
593
593
|
workflowHints: [
|
|
@@ -601,10 +601,10 @@ export const graphicsModule = defineToolModule({
|
|
|
601
601
|
},
|
|
602
602
|
{
|
|
603
603
|
name: "render_petscii_text",
|
|
604
|
-
description: "Display PETSCII text with optional border and background colours. See c64://
|
|
604
|
+
description: "Display PETSCII text with optional border and background colours. See c64://basic/spec.",
|
|
605
605
|
summary: "Generates a BASIC program that clears the screen, sets colours, and prints text.",
|
|
606
606
|
inputSchema: renderPetsciiScreenArgsSchema.jsonSchema,
|
|
607
|
-
relatedResources: ["c64://
|
|
607
|
+
relatedResources: ["c64://basic/spec", "c64://guide/bootstrap"],
|
|
608
608
|
relatedPrompts: ["basic-program", "graphics-demo"],
|
|
609
609
|
tags: ["basic", "screen"],
|
|
610
610
|
prerequisites: ["upload_run_basic"],
|
|
@@ -626,10 +626,10 @@ export const graphicsModule = defineToolModule({
|
|
|
626
626
|
},
|
|
627
627
|
{
|
|
628
628
|
name: "render_petscii_art",
|
|
629
|
-
description: "Create PETSCII art from prompts, text, or bitmap input, and optionally display it on the C64. Returns metadata including PETSCII codes and glyphs. See c64://
|
|
629
|
+
description: "Create PETSCII art from prompts, text, or bitmap input, and optionally display it on the C64. Returns metadata including PETSCII codes and glyphs. See c64://basic/spec, c64://graphics/vic/spec, and c64://graphics/character-set.",
|
|
630
630
|
summary: "Synthesises PETSCII art, generates a BASIC program with preview metadata (petsciiCodes, glyphs, dimensions), and uploads it unless dry-run is requested.",
|
|
631
631
|
inputSchema: petsciiImageArgsSchema.jsonSchema,
|
|
632
|
-
relatedResources: ["c64://
|
|
632
|
+
relatedResources: ["c64://basic/spec", "c64://graphics/vic/spec", "c64://graphics/character-set"],
|
|
633
633
|
relatedPrompts: ["graphics-demo", "basic-program"],
|
|
634
634
|
tags: ["petscii", "basic", "pal-ntsc"],
|
|
635
635
|
prerequisites: ["upload_run_basic"],
|