c64bridge 0.9.0 → 0.9.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.
Files changed (61) hide show
  1. package/README.md +161 -135
  2. package/data/assembly/assembly-spec.md +1 -1
  3. package/data/context/bootstrap.md +3 -3
  4. package/data/context/fast-paths.md +3 -1
  5. package/data/graphics/petscii-style-guide.md +1 -1
  6. package/data/graphics/sprite-charset-best-practices.md +14 -13
  7. package/data/sound/sid-file-structure.md +5 -5
  8. package/data/sound/sid-programming-best-practices.md +5 -5
  9. package/data/vice/vice-binary-monitor-spec.md +26 -10
  10. package/dist/.tsbuildinfo +1 -1
  11. package/dist/c64Client.js +107 -8
  12. package/dist/device.js +43 -3
  13. package/dist/rag/indexer.js +18 -8
  14. package/dist/sidwaveCompiler.js +1 -1
  15. package/dist/tools/debug.js +158 -5
  16. package/dist/tools/input.js +336 -0
  17. package/dist/tools/memory.js +326 -1
  18. package/dist/tools/programRunners.js +45 -6
  19. package/dist/tools/registry/batch.js +167 -0
  20. package/dist/tools/registry/graphics.js +101 -1
  21. package/dist/tools/registry/index.js +4 -0
  22. package/dist/tools/registry/input.js +2 -0
  23. package/dist/tools/registry/memory.js +61 -1
  24. package/dist/tools/responses.js +14 -1
  25. package/dist/tools/schema.js +4 -5
  26. package/dist/{assemblyConverter.js → tools/translation/assembler.js} +66 -163
  27. package/dist/{basicConverter.js → tools/translation/basicTokenizer.js} +1 -1
  28. package/dist/tools/translation/disassembler.js +150 -0
  29. package/dist/tools/translation/opcodeInventory.js +126 -0
  30. package/dist/tools/translation/symbolRegistry.js +49 -0
  31. package/dist/tools/types.js +19 -4
  32. package/dist/vice/process.js +43 -2
  33. package/dist/vice/viceClient.js +5 -1
  34. package/doc/reviews/audit.md +143 -0
  35. package/mcp/schemas/c64_batch.schema.json +53 -0
  36. package/mcp/schemas/c64_config.schema.json +461 -2
  37. package/mcp/schemas/c64_debug.schema.json +641 -3
  38. package/mcp/schemas/c64_disk.schema.json +340 -2
  39. package/mcp/schemas/c64_drive.schema.json +157 -2
  40. package/mcp/schemas/c64_extract.schema.json +359 -2
  41. package/mcp/schemas/c64_graphics.schema.json +415 -3
  42. package/mcp/schemas/c64_input.schema.json +254 -0
  43. package/mcp/schemas/c64_memory.schema.json +562 -3
  44. package/mcp/schemas/c64_printer.schema.json +253 -2
  45. package/mcp/schemas/c64_program.schema.json +499 -2
  46. package/mcp/schemas/c64_rag.schema.json +82 -2
  47. package/mcp/schemas/c64_select_backend.schema.json +35 -2
  48. package/mcp/schemas/c64_sound.schema.json +793 -2
  49. package/mcp/schemas/c64_stream.schema.json +73 -2
  50. package/mcp/schemas/c64_system.schema.json +301 -2
  51. package/mcp/schemas/c64_vice.schema.json +71 -2
  52. package/mcp/server.json +1 -1
  53. package/mcp/tools.json +7509 -1929
  54. package/mcp.json +1 -1
  55. package/package.json +2 -2
  56. package/scripts/c64-cli.mjs +2 -2
  57. package/scripts/run-coverage.mjs +61 -3
  58. package/scripts/run-tests.mjs +1 -0
  59. package/scripts/run-tests.ts +3 -0
  60. package/scripts/update-readme.ts +79 -2
  61. package/server.json +2 -2
@@ -7,7 +7,13 @@
7
7
  "read",
8
8
  "write",
9
9
  "read_screen",
10
- "wait_for_text"
10
+ "wait_for_text",
11
+ "disassemble",
12
+ "copy_memory",
13
+ "fill_memory",
14
+ "search_memory",
15
+ "compare_memory",
16
+ "save_memory"
11
17
  ],
12
18
  "description": "Selects the operation."
13
19
  },
@@ -95,11 +101,564 @@
95
101
  "description": "Poll interval in milliseconds",
96
102
  "minimum": 1,
97
103
  "default": 100
104
+ },
105
+ "instructionCount": {
106
+ "type": [
107
+ "integer",
108
+ "null"
109
+ ],
110
+ "description": "Stop after this many instructions (overrides length as a termination condition).",
111
+ "minimum": 1,
112
+ "maximum": 512
113
+ },
114
+ "source": {
115
+ "type": "string",
116
+ "description": "Source start address ($HHHH, decimal, or symbol).",
117
+ "minLength": 1
118
+ },
119
+ "dest": {
120
+ "type": "string",
121
+ "description": "Destination start address.",
122
+ "minLength": 1
123
+ },
124
+ "startAddress": {
125
+ "type": "string",
126
+ "description": "Start of search range ($HHHH, decimal, or symbol).",
127
+ "minLength": 1
128
+ },
129
+ "endAddress": {
130
+ "type": "string",
131
+ "description": "End of search range (inclusive).",
132
+ "minLength": 1
133
+ },
134
+ "maxResults": {
135
+ "type": [
136
+ "integer",
137
+ "null"
138
+ ],
139
+ "description": "Maximum matches to return (default 10).",
140
+ "minimum": 1,
141
+ "maximum": 100,
142
+ "default": 10
143
+ },
144
+ "address1": {
145
+ "type": "string",
146
+ "description": "First region start address.",
147
+ "minLength": 1
148
+ },
149
+ "address2": {
150
+ "type": "string",
151
+ "description": "Second region start address.",
152
+ "minLength": 1
153
+ },
154
+ "maxDiffs": {
155
+ "type": [
156
+ "integer",
157
+ "null"
158
+ ],
159
+ "description": "Max differences to report (default 10).",
160
+ "minimum": 1,
161
+ "maximum": 200,
162
+ "default": 10
163
+ },
164
+ "filePath": {
165
+ "type": "string",
166
+ "description": "Absolute or relative path for the output file.",
167
+ "minLength": 1
168
+ },
169
+ "asPrg": {
170
+ "type": [
171
+ "boolean",
172
+ "null"
173
+ ],
174
+ "description": "Prepend a 2-byte little-endian load-address header (PRG format). Default: true.",
175
+ "default": true
98
176
  }
99
177
  },
100
178
  "required": [
101
179
  "op"
102
180
  ],
103
- "description": "Memory operations available via the c64_memory tool.\n\nOperations:\n- read: Read a range of bytes and return a hex dump with address metadata.\n- write: Write a hexadecimal byte sequence into RAM.\n- read_screen: Return the current 40x25 text screen converted to ASCII.\n- wait_for_text: Poll the screen until a substring or regex appears, or timeout elapses.",
104
- "additionalProperties": false
181
+ "description": "Memory operations available via the c64_memory tool.\n\nOperations:\n- read: Read a range of bytes and return a hex dump with address metadata. Required inputs: address. Optional inputs: length.\n- write: Write a hexadecimal byte sequence into RAM. Required inputs: address, bytes. Optional inputs: verify, expected, mask, abortOnMismatch.\n- read_screen: Return the current 40x25 text screen converted to ASCII. Required inputs: none.\n- wait_for_text: Poll the screen until a substring or regex appears, or timeout elapses. Required inputs: pattern. Optional inputs: isRegex, caseInsensitive, timeoutMs, intervalMs.\n- disassemble: Disassemble a memory region into annotated 6502/6510 instructions, including undocumented opcodes with canonical names. Symbol annotations from `.vs` files are applied when available. Works on both C64U and VICE. Required inputs: address. Optional inputs: length, instructionCount.\n- copy_memory: Copy a RAM region to another address. Required inputs: source, dest, length.\n- fill_memory: Fill a memory range with a repeating byte pattern. Required inputs: address, length, pattern.\n- search_memory: Search for a byte pattern within a memory range and return matching addresses. Required inputs: startAddress, endAddress, pattern. Optional inputs: maxResults.\n- compare_memory: Compare two memory regions byte-by-byte and report differences. Required inputs: address1, address2, length. Optional inputs: maxDiffs.\n- save_memory: Dump a memory range to a local file, with an optional PRG load-address header. Required inputs: startAddress, endAddress, filePath. Optional inputs: asPrg.",
182
+ "additionalProperties": false,
183
+ "x-c64bridge-operations": [
184
+ {
185
+ "op": "read",
186
+ "description": "Read a range of bytes and return a hex dump with address metadata.",
187
+ "required": [
188
+ "address"
189
+ ],
190
+ "optional": [
191
+ "length"
192
+ ],
193
+ "inputSchema": {
194
+ "type": "object",
195
+ "description": "Read a range of bytes and return a hex dump with address metadata.",
196
+ "properties": {
197
+ "address": {
198
+ "type": "string",
199
+ "description": "Start address expressed as $HHHH, decimal, or a documented symbol name.",
200
+ "minLength": 1
201
+ },
202
+ "length": {
203
+ "type": "integer",
204
+ "description": "Number of bytes to read starting from the resolved address.",
205
+ "minimum": 1,
206
+ "maximum": 4096,
207
+ "default": 256
208
+ },
209
+ "op": {
210
+ "const": "read"
211
+ }
212
+ },
213
+ "required": [
214
+ "address",
215
+ "op"
216
+ ],
217
+ "additionalProperties": false
218
+ }
219
+ },
220
+ {
221
+ "op": "write",
222
+ "description": "Write a hexadecimal byte sequence into RAM.",
223
+ "required": [
224
+ "address",
225
+ "bytes"
226
+ ],
227
+ "optional": [
228
+ "verify",
229
+ "expected",
230
+ "mask",
231
+ "abortOnMismatch"
232
+ ],
233
+ "inputSchema": {
234
+ "type": "object",
235
+ "description": "Write a hexadecimal byte sequence into RAM.",
236
+ "properties": {
237
+ "address": {
238
+ "type": "string",
239
+ "description": "Destination address expressed as $HHHH, decimal, or a documented symbol name.",
240
+ "minLength": 1
241
+ },
242
+ "bytes": {
243
+ "type": "string",
244
+ "description": "Hex byte sequence like $AABBCC or AA BB CC to write starting at the resolved address.",
245
+ "minLength": 2,
246
+ "pattern": "^[\\s_0-9A-Fa-f$]+$"
247
+ },
248
+ "verify": {
249
+ "type": "boolean",
250
+ "description": "When true, verify the write by reading before and after the change; Ultimate hardware also pauses during verification.",
251
+ "default": false
252
+ },
253
+ "expected": {
254
+ "type": [
255
+ "string",
256
+ "null"
257
+ ],
258
+ "description": "Optional hex data expected before the write (verifies before writing).",
259
+ "minLength": 2,
260
+ "pattern": "^[\\s_0-9A-Fa-f$]+$"
261
+ },
262
+ "mask": {
263
+ "type": [
264
+ "string",
265
+ "null"
266
+ ],
267
+ "description": "Optional verification mask (hex); only bits set in the mask are compared.",
268
+ "minLength": 2,
269
+ "pattern": "^[\\s_0-9A-Fa-f$]+$"
270
+ },
271
+ "abortOnMismatch": {
272
+ "type": "boolean",
273
+ "description": "Abort the write when the pre-write verification fails.",
274
+ "default": true
275
+ },
276
+ "op": {
277
+ "const": "write"
278
+ }
279
+ },
280
+ "required": [
281
+ "address",
282
+ "bytes",
283
+ "op"
284
+ ],
285
+ "additionalProperties": false
286
+ }
287
+ },
288
+ {
289
+ "op": "read_screen",
290
+ "description": "Return the current 40x25 text screen converted to ASCII.",
291
+ "required": [],
292
+ "optional": [],
293
+ "inputSchema": {
294
+ "type": "object",
295
+ "description": "Return the current 40x25 text screen converted to ASCII.",
296
+ "properties": {
297
+ "op": {
298
+ "const": "read_screen"
299
+ }
300
+ },
301
+ "additionalProperties": false,
302
+ "required": [
303
+ "op"
304
+ ]
305
+ }
306
+ },
307
+ {
308
+ "op": "wait_for_text",
309
+ "description": "Poll the screen until a substring or regex appears, or timeout elapses.",
310
+ "required": [
311
+ "pattern"
312
+ ],
313
+ "optional": [
314
+ "isRegex",
315
+ "caseInsensitive",
316
+ "timeoutMs",
317
+ "intervalMs"
318
+ ],
319
+ "inputSchema": {
320
+ "type": "object",
321
+ "description": "Poll the screen until a substring or regex appears, or timeout elapses.",
322
+ "properties": {
323
+ "pattern": {
324
+ "type": "string",
325
+ "description": "Substring or regex to find",
326
+ "minLength": 1
327
+ },
328
+ "isRegex": {
329
+ "type": [
330
+ "boolean",
331
+ "null"
332
+ ],
333
+ "description": "Interpret pattern as regular expression",
334
+ "default": false
335
+ },
336
+ "caseInsensitive": {
337
+ "type": [
338
+ "boolean",
339
+ "null"
340
+ ],
341
+ "description": "Case-insensitive search",
342
+ "default": true
343
+ },
344
+ "timeoutMs": {
345
+ "type": [
346
+ "integer",
347
+ "null"
348
+ ],
349
+ "description": "Overall timeout in milliseconds",
350
+ "minimum": 1,
351
+ "default": 3000
352
+ },
353
+ "intervalMs": {
354
+ "type": [
355
+ "integer",
356
+ "null"
357
+ ],
358
+ "description": "Poll interval in milliseconds",
359
+ "minimum": 1,
360
+ "default": 100
361
+ },
362
+ "op": {
363
+ "const": "wait_for_text"
364
+ }
365
+ },
366
+ "required": [
367
+ "pattern",
368
+ "op"
369
+ ],
370
+ "additionalProperties": false
371
+ }
372
+ },
373
+ {
374
+ "op": "disassemble",
375
+ "description": "Disassemble a memory region into annotated 6502/6510 instructions, including undocumented opcodes with canonical names. Symbol annotations from `.vs` files are applied when available. Works on both C64U and VICE.",
376
+ "required": [
377
+ "address"
378
+ ],
379
+ "optional": [
380
+ "length",
381
+ "instructionCount"
382
+ ],
383
+ "inputSchema": {
384
+ "type": "object",
385
+ "description": "Disassemble a memory region into annotated 6502/6510 instructions, including undocumented opcodes with canonical names. Symbol annotations from `.vs` files are applied when available. Works on both C64U and VICE.",
386
+ "properties": {
387
+ "address": {
388
+ "type": "string",
389
+ "description": "Start address as $HHHH, decimal, or symbol name.",
390
+ "minLength": 1
391
+ },
392
+ "length": {
393
+ "type": "integer",
394
+ "description": "Number of bytes to read and disassemble.",
395
+ "minimum": 1,
396
+ "maximum": 4096,
397
+ "default": 64
398
+ },
399
+ "instructionCount": {
400
+ "type": [
401
+ "integer",
402
+ "null"
403
+ ],
404
+ "description": "Stop after this many instructions (overrides length as a termination condition).",
405
+ "minimum": 1,
406
+ "maximum": 512
407
+ },
408
+ "op": {
409
+ "const": "disassemble"
410
+ }
411
+ },
412
+ "required": [
413
+ "address",
414
+ "op"
415
+ ],
416
+ "additionalProperties": false
417
+ }
418
+ },
419
+ {
420
+ "op": "copy_memory",
421
+ "description": "Copy a RAM region to another address.",
422
+ "required": [
423
+ "source",
424
+ "dest",
425
+ "length"
426
+ ],
427
+ "optional": [],
428
+ "inputSchema": {
429
+ "type": "object",
430
+ "description": "Copy a RAM region to another address.",
431
+ "properties": {
432
+ "source": {
433
+ "type": "string",
434
+ "description": "Source start address ($HHHH, decimal, or symbol).",
435
+ "minLength": 1
436
+ },
437
+ "dest": {
438
+ "type": "string",
439
+ "description": "Destination start address.",
440
+ "minLength": 1
441
+ },
442
+ "length": {
443
+ "type": "integer",
444
+ "description": "Number of bytes to copy (1–16384).",
445
+ "minimum": 1,
446
+ "maximum": 16384
447
+ },
448
+ "op": {
449
+ "const": "copy_memory"
450
+ }
451
+ },
452
+ "required": [
453
+ "source",
454
+ "dest",
455
+ "length",
456
+ "op"
457
+ ],
458
+ "additionalProperties": false
459
+ }
460
+ },
461
+ {
462
+ "op": "fill_memory",
463
+ "description": "Fill a memory range with a repeating byte pattern.",
464
+ "required": [
465
+ "address",
466
+ "length",
467
+ "pattern"
468
+ ],
469
+ "optional": [],
470
+ "inputSchema": {
471
+ "type": "object",
472
+ "description": "Fill a memory range with a repeating byte pattern.",
473
+ "properties": {
474
+ "address": {
475
+ "type": "string",
476
+ "description": "Start address ($HHHH, decimal, or symbol).",
477
+ "minLength": 1
478
+ },
479
+ "length": {
480
+ "type": "integer",
481
+ "description": "Number of bytes to fill (1–16384).",
482
+ "minimum": 1,
483
+ "maximum": 16384
484
+ },
485
+ "pattern": {
486
+ "type": "string",
487
+ "description": "Hex bytes to repeat, e.g. 'FF' or 'AA 55'. Space-separated or run together.",
488
+ "minLength": 2,
489
+ "pattern": "^[\\s0-9A-Fa-f$]+$"
490
+ },
491
+ "op": {
492
+ "const": "fill_memory"
493
+ }
494
+ },
495
+ "required": [
496
+ "address",
497
+ "length",
498
+ "pattern",
499
+ "op"
500
+ ],
501
+ "additionalProperties": false
502
+ }
503
+ },
504
+ {
505
+ "op": "search_memory",
506
+ "description": "Search for a byte pattern within a memory range and return matching addresses.",
507
+ "required": [
508
+ "startAddress",
509
+ "endAddress",
510
+ "pattern"
511
+ ],
512
+ "optional": [
513
+ "maxResults"
514
+ ],
515
+ "inputSchema": {
516
+ "type": "object",
517
+ "description": "Search for a byte pattern within a memory range and return matching addresses.",
518
+ "properties": {
519
+ "startAddress": {
520
+ "type": "string",
521
+ "description": "Start of search range ($HHHH, decimal, or symbol).",
522
+ "minLength": 1
523
+ },
524
+ "endAddress": {
525
+ "type": "string",
526
+ "description": "End of search range (inclusive).",
527
+ "minLength": 1
528
+ },
529
+ "pattern": {
530
+ "type": "string",
531
+ "description": "Hex bytes to find, e.g. 'A9 00' for LDA #$00.",
532
+ "minLength": 2,
533
+ "pattern": "^[\\s0-9A-Fa-f$]+$"
534
+ },
535
+ "maxResults": {
536
+ "type": [
537
+ "integer",
538
+ "null"
539
+ ],
540
+ "description": "Maximum matches to return (default 10).",
541
+ "minimum": 1,
542
+ "maximum": 100,
543
+ "default": 10
544
+ },
545
+ "op": {
546
+ "const": "search_memory"
547
+ }
548
+ },
549
+ "required": [
550
+ "startAddress",
551
+ "endAddress",
552
+ "pattern",
553
+ "op"
554
+ ],
555
+ "additionalProperties": false
556
+ }
557
+ },
558
+ {
559
+ "op": "compare_memory",
560
+ "description": "Compare two memory regions byte-by-byte and report differences.",
561
+ "required": [
562
+ "address1",
563
+ "address2",
564
+ "length"
565
+ ],
566
+ "optional": [
567
+ "maxDiffs"
568
+ ],
569
+ "inputSchema": {
570
+ "type": "object",
571
+ "description": "Compare two memory regions byte-by-byte and report differences.",
572
+ "properties": {
573
+ "address1": {
574
+ "type": "string",
575
+ "description": "First region start address.",
576
+ "minLength": 1
577
+ },
578
+ "address2": {
579
+ "type": "string",
580
+ "description": "Second region start address.",
581
+ "minLength": 1
582
+ },
583
+ "length": {
584
+ "type": "integer",
585
+ "description": "Number of bytes to compare (1–16384).",
586
+ "minimum": 1,
587
+ "maximum": 16384
588
+ },
589
+ "maxDiffs": {
590
+ "type": [
591
+ "integer",
592
+ "null"
593
+ ],
594
+ "description": "Max differences to report (default 10).",
595
+ "minimum": 1,
596
+ "maximum": 200,
597
+ "default": 10
598
+ },
599
+ "op": {
600
+ "const": "compare_memory"
601
+ }
602
+ },
603
+ "required": [
604
+ "address1",
605
+ "address2",
606
+ "length",
607
+ "op"
608
+ ],
609
+ "additionalProperties": false
610
+ }
611
+ },
612
+ {
613
+ "op": "save_memory",
614
+ "description": "Dump a memory range to a local file, with an optional PRG load-address header.",
615
+ "required": [
616
+ "startAddress",
617
+ "endAddress",
618
+ "filePath"
619
+ ],
620
+ "optional": [
621
+ "asPrg"
622
+ ],
623
+ "inputSchema": {
624
+ "type": "object",
625
+ "description": "Dump a memory range to a local file, with an optional PRG load-address header.",
626
+ "properties": {
627
+ "startAddress": {
628
+ "type": "string",
629
+ "description": "Start address of region to save.",
630
+ "minLength": 1
631
+ },
632
+ "endAddress": {
633
+ "type": "string",
634
+ "description": "End address (inclusive).",
635
+ "minLength": 1
636
+ },
637
+ "filePath": {
638
+ "type": "string",
639
+ "description": "Absolute or relative path for the output file.",
640
+ "minLength": 1
641
+ },
642
+ "asPrg": {
643
+ "type": [
644
+ "boolean",
645
+ "null"
646
+ ],
647
+ "description": "Prepend a 2-byte little-endian load-address header (PRG format). Default: true.",
648
+ "default": true
649
+ },
650
+ "op": {
651
+ "const": "save_memory"
652
+ }
653
+ },
654
+ "required": [
655
+ "startAddress",
656
+ "endAddress",
657
+ "filePath",
658
+ "op"
659
+ ],
660
+ "additionalProperties": false
661
+ }
662
+ }
663
+ ]
105
664
  }