c64bridge 0.9.1 → 0.9.3

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 (46) hide show
  1. package/AGENTS.md +5 -0
  2. package/README.md +115 -15
  3. package/data/assembly/assembly-spec.md +1 -1
  4. package/data/basic/rom-routines.md +269 -0
  5. package/data/context/bootstrap.md +4 -4
  6. package/data/context/fast-paths.md +3 -1
  7. package/data/graphics/petscii-style-guide.md +1 -1
  8. package/data/graphics/sprite-charset-best-practices.md +14 -13
  9. package/data/io/cia-spec.md +2 -2
  10. package/data/{memory/kernal-memory-map.md → kernal/rom-routines.md} +3 -2
  11. package/data/memory/low-memory-map.md +1 -0
  12. package/data/memory/memory-map.md +13 -0
  13. package/data/sound/sid-file-structure.md +5 -5
  14. package/data/sound/sid-programming-best-practices.md +5 -5
  15. package/data/vice/vice-binary-monitor-spec.md +5 -6
  16. package/dist/.tsbuildinfo +1 -1
  17. package/dist/c64Client.js +33 -15
  18. package/dist/config.js +22 -0
  19. package/dist/mcp-server.js +17 -5
  20. package/dist/rag/knowledgeIndex.js +54 -9
  21. package/dist/rag/resourceUris.js +2 -0
  22. package/dist/sidwaveCompiler.js +1 -1
  23. package/dist/tools/input.js +5 -7
  24. package/dist/tools/memory.js +11 -2
  25. package/dist/tools/programRunners.js +3 -3
  26. package/dist/tools/responses.js +14 -1
  27. package/dist/tools/{assember.js → translation/assembler.js} +56 -162
  28. package/dist/tools/{basicTokenizer.js → translation/basicTokenizer.js} +1 -1
  29. package/dist/tools/translation/disassembler.js +150 -0
  30. package/dist/tools/translation/opcodeInventory.js +126 -0
  31. package/doc/developer.md +3 -2
  32. package/doc/reviews/audit.md +143 -0
  33. package/mcp/resources.json +60 -7
  34. package/mcp/schemas/c64_input.schema.json +231 -113
  35. package/mcp/server.json +1 -1
  36. package/mcp/tools.json +234 -115
  37. package/mcp.json +8 -4
  38. package/package.json +12 -8
  39. package/scripts/c64-cli.mjs +2 -2
  40. package/scripts/run-coverage.mjs +54 -3
  41. package/scripts/run-tests.mjs +1 -0
  42. package/scripts/run-tests.ts +1 -0
  43. package/scripts/update-readme.ts +1 -0
  44. package/server.json +3 -3
  45. package/dist/tools/disassembler.js +0 -478
  46. /package/dist/tools/{symbolRegistry.js → translation/symbolRegistry.js} +0 -0
package/AGENTS.md CHANGED
@@ -115,12 +115,17 @@ Tools and parameters are listed dynamically via ListTools.
115
115
  Use ListResources to discover built-in knowledge, then read specific URIs to enrich context before coding:
116
116
 
117
117
  - `c64://basic/spec` — BASIC v2 tokens, syntax, device I/O
118
+ - `c64://basic/rom-routines` — BASIC ROM routines, parser/evaluator helpers, numeric/string machinery
118
119
  - `c64://assembly/6510-spec` — 6510 opcodes, addressing, zero-page strategy
119
120
  - `c64://graphics/vic/spec` — raster timing, sprites, colour RAM, bitmap modes
120
121
  - `c64://sound/sid/spec` — SID registers, waveforms, ADSR
121
122
  - `c64://memory/map` — full 64 KB address map
123
+ - `c64://memory/zero-page-and-workspace` — zero page, stack, page-2 buffers, page-3 vectors
122
124
  - `c64://vice/binary-monitor-spec` — mandatory reference when targeting VICE; covers Binary Monitor transport, command framing, and debugger side effects
123
125
  - `c64://basic/pitfalls` — quoting, line length, token pitfalls
126
+ - `c64://kernal/rom-routines` — KERNAL ROM routines, jump table, vectors, serial/tape/screen services
127
+ - `c64://io/spec` — memory-mapped VIC-II, SID, CIA, colour RAM, and expansion I/O registers
128
+ - `c64://io/cia/spec` — CIA timers, keyboard matrix, serial bus, TOD, IRQ/NMI details
124
129
  - `c64://graphics/petscii/style-guide` — readable PETSCII, colour/dither guidance
125
130
 
126
131
  Pull RAG snippets via `c64_rag` (ops `basic`/`asm`) for targeted examples.
package/README.md CHANGED
@@ -14,6 +14,7 @@ Your AI Command Bridge for the Commodore 64.
14
14
  [![Install in VS Code Insiders](https://img.shields.io/badge/Install_in-VS_Code_Insiders-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=io.github.chrisgleissner%2Fc64bridge&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22c64bridge%22%5D%2C%22env%22%3A%7B%22C64_MODE%22%3A%22c64u%22%2C%22C64U_HOST%22%3A%22c64u%22%2C%22VICE_BINARY%22%3A%22%2Fusr%2Flocal%2Fbin%2Fx64sc%22%2C%22VICE_DIRECTORY%22%3A%22%2Fusr%2Flocal%2Fshare%2Fvice%22%2C%22VICE_VISIBLE%22%3A%22true%22%2C%22VICE_WARP%22%3A%22false%22%7D%7D&quality=insiders)
15
15
  [![Install in Visual Studio](https://img.shields.io/badge/Install_in-Visual_Studio-C16FDE?style=flat-square&logo=visualstudio&logoColor=white)](https://vs-open.link/mcp-install?%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22c64bridge%22%5D%2C%22env%22%3A%7B%22C64_MODE%22%3A%22c64u%22%2C%22C64U_HOST%22%3A%22c64u%22%2C%22VICE_BINARY%22%3A%22%2Fusr%2Flocal%2Fbin%2Fx64sc%22%2C%22VICE_DIRECTORY%22%3A%22%2Fusr%2Flocal%2Fshare%2Fvice%22%2C%22VICE_VISIBLE%22%3A%22true%22%2C%22VICE_WARP%22%3A%22false%22%7D%7D)
16
16
  [![Install in Cursor](https://img.shields.io/badge/Install_in-Cursor-000000?style=flat-square&logoColor=white)](https://cursor.com/en/install-mcp?name=io.github.chrisgleissner%2Fc64bridge&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsImM2NGJyaWRnZSJdLCJlbnYiOnsiQzY0X01PREUiOiJjNjR1IiwiQzY0VV9IT1NUIjoiYzY0dSIsIlZJQ0VfQklOQVJZIjoiL3Vzci9sb2NhbC9iaW4veDY0c2MiLCJWSUNFX0RJUkVDVE9SWSI6Ii91c3IvbG9jYWwvc2hhcmUvdmljZSIsIlZJQ0VfVklTSUJMRSI6InRydWUiLCJWSUNFX1dBUlAiOiJmYWxzZSJ9fQ==)
17
+ [![Use with Claude Code](https://img.shields.io/badge/Use_with-Claude_Code-D97757?style=flat-square&logo=anthropic&logoColor=white)](#claude-code)
17
18
 
18
19
  C64 Bridge is an MCP server for controlling and working with a Commodore 64 from an AI client.
19
20
 
@@ -39,6 +40,8 @@ C64 Bridge is listed in the [Official MCP Registry](https://registry.modelcontex
39
40
  - [Configuration Merge Rules](#configuration-merge-rules)
40
41
  - [Backend Configuration: C64 Ultimate](#backend-configuration-c64-ultimate)
41
42
  - [Backend Configuration: VICE](#backend-configuration-vice)
43
+ - [VICE Window Modes](#vice-window-modes)
44
+ - [Recommended VICE Configurations](#recommended-vice-configurations)
42
45
  - [Runtime Backend Switching](#runtime-backend-switching)
43
46
  - [VS Code MCP Setup](#vs-code-mcp-setup)
44
47
  - [Enable the C64 Agent](#enable-the-c64-agent)
@@ -52,6 +55,7 @@ C64 Bridge is listed in the [Official MCP Registry](https://registry.modelcontex
52
55
  - [SID Playback](#sid-playback)
53
56
  - [RAG](#rag)
54
57
  - [Testing](#testing)
58
+ - [Claude Code](#claude-code)
55
59
  - [Example Workflow](#example-workflow)
56
60
  - [HTTP Invocation](#http-invocation)
57
61
  - [Build and Test](#build-and-test)
@@ -59,12 +63,14 @@ C64 Bridge is listed in the [Official MCP Registry](https://registry.modelcontex
59
63
  - [Static MCP Interface](#static-mcp-interface)
60
64
  - [MCP API Reference](#mcp-api-reference)
61
65
  - [Tools](#tools)
66
+ - [c64\_batch](#c64_batch)
62
67
  - [c64\_config](#c64_config)
63
68
  - [c64\_debug](#c64_debug)
64
69
  - [c64\_disk](#c64_disk)
65
70
  - [c64\_drive](#c64_drive)
66
71
  - [c64\_extract](#c64_extract)
67
72
  - [c64\_graphics](#c64_graphics)
73
+ - [c64\_input](#c64_input)
68
74
  - [c64\_memory](#c64_memory)
69
75
  - [c64\_printer](#c64_printer)
70
76
  - [c64\_program](#c64_program)
@@ -191,9 +197,14 @@ The detailed lookup order, merge rules, backend examples, and override model are
191
197
 
192
198
  ### 4. Connect from an MCP Client
193
199
 
194
- If you use VS Code, follow the [VS Code MCP Setup](#vs-code-mcp-setup) section below.
200
+ C64 Bridge ships a single canonical `stdio` entry point that every MCP client uses:
195
201
 
196
- If you use another MCP client, point it at the `stdio` server entry point and pass any required environment variables exactly as documented in this README and in [mcp.json](./mcp.json).
202
+ - **VS Code (GitHub Copilot)** — see [VS Code MCP Setup](#vs-code-mcp-setup).
203
+ - **Claude Code (CLI and VS Code plugin)** — see [Claude Code](#claude-code).
204
+ - **Cursor, Visual Studio, VS Code Insiders** — use the install badges at the top of this README.
205
+ - **Any other MCP client** — point it at the same `stdio` server, with the environment variables documented in [Runtime Environment Variable Reference](#runtime-environment-variable-reference) and the registry manifest in [mcp.json](./mcp.json).
206
+
207
+ The startup command is the same across clients: `npx -y c64bridge@latest` for the published package, or `node scripts/start.mjs` from a local checkout. Backend selection (`c64u` vs `vice`) and credentials live in the shared [Configuration](#configuration) files and environment variables — clients only need to know the command.
197
208
 
198
209
  ## Configuration
199
210
 
@@ -233,7 +244,7 @@ Use this for a C64 Ultimate or Ultimate 64:
233
244
 
234
245
  ### Backend Configuration: VICE
235
246
 
236
- Use this for managed VICE launches:
247
+ C64 Bridge can either connect to an already running VICE Binary Monitor or manage a local VICE process for you. The usual managed setup only needs the emulator binary and, when auto-detection cannot find it, the VICE resource directory:
237
248
 
238
249
  ```json
239
250
  {
@@ -244,9 +255,69 @@ Use this for managed VICE launches:
244
255
  }
245
256
  ```
246
257
 
258
+ - `exe` is optional when `x64sc` or `x64` is on `PATH`. If no explicit binary is configured, the runtime prefers `/usr/local/bin/x64sc` when present, then falls back to `x64sc` or `x64` on `PATH`.
247
259
  - `directory` is optional. When omitted, C64 Bridge auto-detects a VICE resource directory by looking for the standard C64 ROM set near the emulator binary and in common system locations.
248
- - `VICE_BINARY`, `VICE_DIRECTORY`, `VICE_HOST`, `VICE_PORT`, `VICE_VISIBLE`, `VICE_WARP`, and `VICE_ARGS` override managed VICE startup without editing config files.
249
- - If no explicit binary is configured, the runtime prefers `/usr/local/bin/x64sc` when present, then falls back to `x64sc` or `x64` on `PATH` so the same setup remains portable across operating systems.
260
+ - `host` and `port` are optional and default to `127.0.0.1:6502`, the Binary Monitor endpoint C64 Bridge starts for managed local sessions. On local endpoints, C64 Bridge first tries to reuse an already running monitor before starting its own process.
261
+ - `visible`, `warp`, and `args` are optional runtime controls. They can live in JSON config, but most users set their environment-variable equivalents from the MCP client because they are per-session preferences.
262
+ - By default, VICE is started lazily on first access. When setting the environment variable `VICE_PREWARM=1`, C64 Bridge starts or connects VICE in the background during MCP startup.
263
+ - `VICE_BINARY`, `VICE_DIRECTORY`, `VICE_HOST`, `VICE_PORT`, `VICE_VISIBLE`, `VICE_WARP`, `VICE_ARGS`, and `VICE_PREWARM` override the JSON values without editing config files.
264
+
265
+ #### VICE Window Modes
266
+
267
+ Choose the window mode based on where the MCP server runs:
268
+
269
+ | Mode | Configuration | What happens | Use when |
270
+ | --- | --- | --- | --- |
271
+ | Visible | `VICE_VISIBLE=true` | VICE opens a normal desktop window. Warp defaults to off. | You are developing locally and want to watch or interact with the emulator. |
272
+ | Minimized | `VICE_VISIBLE=true`, `VICE_ARGS="-minimized"` | VICE still runs as a normal desktop app, but its window starts iconified. Binary Monitor operations, screen reads, frame capture, and keyboard input continue to work. | You are using an agent locally and do not want the emulator stealing focus, but still want the option to restore the window. |
273
+ | Headless/Xvfb | `VICE_VISIBLE=false` | C64 Bridge launches VICE without a user-facing desktop window, using Xvfb unless disabled. Warp defaults to on. | CI, unattended tests, servers, or any session where no one needs to inspect the emulator window. |
274
+
275
+ Minimized and headless are not the same thing. Minimized is still a visible desktop session with a real VICE window; it is simply hidden by the window manager at startup. Headless/Xvfb has no user-facing window, so it is better for automation but less convenient when you need to debug by looking at the emulator.
276
+
277
+ For normal local MCP use, prefer minimized VICE. It avoids focus stealing while preserving the ability to restore the window for visual inspection. Prefer headless/Xvfb for CI and remote or display-less environments.
278
+
279
+ `FORCE_XVFB=1` forces the Xvfb path even if a graphical session is available. `DISABLE_XVFB=1` disables that fallback and uses the current display, which is mainly useful for troubleshooting display detection.
280
+
281
+ #### Recommended VICE Configurations
282
+
283
+ Local agent session, VICE starts minimized:
284
+
285
+ ```json
286
+ {
287
+ "servers": {
288
+ "c64bridge": {
289
+ "command": "npx",
290
+ "args": ["-y", "c64bridge@latest"],
291
+ "env": {
292
+ "C64_MODE": "vice",
293
+ "VICE_VISIBLE": "true",
294
+ "VICE_ARGS": "-minimized",
295
+ "VICE_WARP": "false"
296
+ }
297
+ }
298
+ }
299
+ }
300
+ ```
301
+
302
+ Headless automation, VICE runs without a visible desktop window:
303
+
304
+ ```json
305
+ {
306
+ "servers": {
307
+ "c64bridge": {
308
+ "command": "npx",
309
+ "args": ["-y", "c64bridge@latest"],
310
+ "env": {
311
+ "C64_MODE": "vice",
312
+ "VICE_VISIBLE": "false",
313
+ "VICE_WARP": "true"
314
+ }
315
+ }
316
+ }
317
+ }
318
+ ```
319
+
320
+ If VICE is installed outside the usual search paths, add `VICE_BINARY` and, if ROM/resource auto-detection fails, `VICE_DIRECTORY` to either example.
250
321
 
251
322
  > [!NOTE]
252
323
  > VICE supports only the operations marked with a VICE checkmark in the [MCP API Reference](#mcp-api-reference). Unsupported operations return `unsupported_platform`.
@@ -265,6 +336,9 @@ Prompt illustration (issued via Copilot in VS Code, using GPT 5.4 Medium):
265
336
 
266
337
  ```text
267
338
  c64u: write a small BASIC program that clears the screen and prints HELLO C64U
339
+ ```
340
+
341
+ ```text
268
342
  vice: write a small BASIC program that clears the screen and prints HELLO VICE
269
343
  ```
270
344
 
@@ -277,6 +351,8 @@ The screenshots below were captured from actual backend bitmap responses after t
277
351
 
278
352
  ## VS Code MCP Setup
279
353
 
354
+ This section covers the GitHub Copilot integration that ships with VS Code. For the Claude Code VS Code plugin, see [Claude Code](#claude-code) — it reads `.mcp.json`, not `.vscode/mcp.json`.
355
+
280
356
  If this repository is checked out locally, open the prepared [.vscode/mcp.json](./.vscode/mcp.json).
281
357
 
282
358
  Otherwise, put the following into your own `.vscode/mcp.json`:
@@ -342,6 +418,8 @@ You can add `env` entries in `.vscode/mcp.json` to select a config file, overrid
342
418
  - `C64_MODE` forces the initial backend to `c64u` or `vice`
343
419
  - `LOG_LEVEL=debug` enables verbose logging
344
420
 
421
+ For VICE-specific overrides such as `VICE_ARGS=-minimized`, `VICE_VISIBLE=false`, or custom VICE paths, use the patterns in [Backend Configuration: VICE](#backend-configuration-vice).
422
+
345
423
  ### Environment Variables in MCP Client Configs
346
424
 
347
425
  Every runtime environment variable documented in the root [mcp.json](./mcp.json) can be supplied by your MCP client configuration, including `.vscode/mcp.json` under `servers.c64bridge.env`.
@@ -359,7 +437,7 @@ When an environment variable has no JSON config equivalent, the order is:
359
437
 
360
438
  That rule applies uniformly across the documented runtime environment variables below.
361
439
 
362
- Example: visible VICE with a specific ROM or resource directory, plus a hardware fallback that can still be selected instantly at runtime:
440
+ Example: start on minimized VICE with a specific ROM or resource directory, plus a hardware fallback that can still be selected instantly at runtime:
363
441
 
364
442
  ```json
365
443
  {
@@ -375,6 +453,7 @@ Example: visible VICE with a specific ROM or resource directory, plus a hardware
375
453
  "VICE_BINARY": "/usr/local/bin/x64sc",
376
454
  "VICE_DIRECTORY": "/usr/local/share/vice",
377
455
  "VICE_VISIBLE": "true",
456
+ "VICE_ARGS": "-minimized",
378
457
  "VICE_WARP": "false"
379
458
  }
380
459
  }
@@ -437,13 +516,14 @@ Every runtime environment variable documented in `mcp.json` can be set in your M
437
516
  | Variable | Default | JSON Config Key | Description |
438
517
  | --- | --- | --- | --- |
439
518
  | `DISABLE_XVFB` | 0 | — | Set to 1 to disable Xvfb fallback and use the current display only |
440
- | `FORCE_XVFB` | 0 | — | Set to 1 to force managed VICE launches to run under Xvfb |
441
- | `VICE_ARGS` | | vice.args | Extra command-line arguments forwarded to managed VICE launches |
519
+ | `FORCE_XVFB` | 0 | — | Set to 1 to force managed VICE launches to use Xvfb even when a graphical session is detected |
520
+ | `VICE_ARGS` | | vice.args | Extra command-line arguments forwarded to managed VICE launches, such as -minimized for a visible window that starts iconified |
442
521
  | `VICE_BINARY` | x64sc | vice.exe | VICE binary to launch for managed emulator sessions and audio capture; automatic search is used only when this override is missing or invalid |
443
522
  | `VICE_DIRECTORY` | auto-detect | vice.directory | Override the VICE resource directory used for ROM and UI asset discovery; automatic search is used only when this override is missing or invalid |
444
523
  | `VICE_HOST` | 127.0.0.1 | vice.host | Override the VICE Binary Monitor host |
445
524
  | `VICE_PORT` | 6502 | vice.port | Override the VICE Binary Monitor port |
446
- | `VICE_VISIBLE` | true | vice.visible | Launch VICE visibly on the desktop instead of headless/Xvfb when possible |
525
+ | `VICE_PREWARM` | 0 | vice.prewarm | Set to 1 to start/connect VICE in the background during MCP startup; disabled by default so VICE starts lazily on first use |
526
+ | `VICE_VISIBLE` | true | vice.visible | Launch VICE as a desktop window when true; use headless/Xvfb managed launch when false |
447
527
  | `VICE_WARP` | false when visible, true when headless | vice.warp | Enable warp mode for managed VICE sessions |
448
528
  | `VICE_XVFB_DISPLAY` | :99 | — | Display number to use when managed VICE launches under Xvfb |
449
529
 
@@ -483,6 +563,24 @@ Every runtime environment variable documented in `mcp.json` can be set in your M
483
563
 
484
564
  <!-- AUTO-GENERATED:ENV-VARS-END -->
485
565
 
566
+ ## Claude Code
567
+
568
+ [Claude Code](https://docs.claude.com/en/docs/claude-code/mcp) is supported as a first-class MCP client. It uses the same canonical start command and the same backend [Configuration](#configuration) files and environment variables as every other client — only the discovery file differs.
569
+
570
+ **Claude Code CLI** — register the published server in one command:
571
+
572
+ ```bash
573
+ claude mcp add c64bridge -- npx -y c64bridge@latest
574
+ ```
575
+
576
+ Use `--scope user` to make it available across all your projects, or `--scope project` to write a `.mcp.json` next to the current repo. Backend selection (`c64u` vs `vice`), host, port, and password come from the same files documented in [Configuration](#configuration); per-shell overrides come from the variables in [Runtime Environment Variable Reference](#runtime-environment-variable-reference).
577
+
578
+ **Project-scoped discovery** — this repository ships a checked-in [.mcp.json](./.mcp.json) that points Claude Code at the local source via `node scripts/start.mjs`. When you open the repo with `claude` (CLI or VS Code plugin), Claude Code prompts to enable the project-scoped server on first run. Approve it once and the `c64_*` tools become discoverable in that workspace.
579
+
580
+ **Claude Code VS Code plugin** — the plugin reads the same `.mcp.json` and the same user-scope `claude mcp add` registrations as the CLI. No extra setup is required beyond installing the plugin and approving the project server prompt. The existing [.vscode/mcp.json](./.vscode/mcp.json) is read by GitHub Copilot, not by Claude Code; the two files coexist without conflict because they target different clients with different config schemas.
581
+
582
+ **Verify it works** — after registration, run `claude mcp list` (CLI) or open the MCP panel (plugin) and look for `c64bridge`. Then ask Claude Code something like *“use vice: write a small BASIC program that clears the screen and prints HELLO CLAUDE”* — it should call `c64_select_backend` and `c64_program` directly. If tools do not appear, confirm Node 24+ is on `PATH`, that the server was approved at the requested scope, and that the backend is reachable per the [Configuration](#configuration) section.
583
+
486
584
  ## Example Workflow
487
585
 
488
586
  Compose a children’s song with ChatGPT and VS Code:
@@ -546,10 +644,11 @@ The [`./build`](./build) script at the project root wraps all development tasks
546
644
 
547
645
  ## Documentation
548
646
 
549
- - [doc/developer.md](doc/developer.md) — development workflow and RAG details
550
- - [data/context/bootstrap.md](data/context/bootstrap.md) — primer injected ahead of prompts
551
- - [doc/c64u/c64-openapi.yaml](doc/c64u/c64-openapi.yaml) — REST surface (OpenAPI 3.1)
552
- - [AGENTS.md](AGENTS.md) — LLM-facing quick setup, usage, and personas
647
+ - [DeepWiki](https://deepwiki.com/chrisgleissner/c64bridge) - architecture and implementation overview
648
+ - [doc/developer.md](doc/developer.md) - development workflow and RAG details
649
+ - [data/context/bootstrap.md](data/context/bootstrap.md) - primer injected ahead of prompts
650
+ - [doc/c64u/c64-openapi.yaml](doc/c64u/c64-openapi.yaml) - REST surface (OpenAPI 3.1)
651
+ - [AGENTS.md](AGENTS.md) - LLM-facing quick setup, usage, and personas
553
652
 
554
653
  ## Static MCP Interface
555
654
 
@@ -561,7 +660,7 @@ This allows agents to inspect the available tools, resources, prompts, and schem
561
660
 
562
661
  <!-- AUTO-GENERATED:MCP-DOCS-START -->
563
662
 
564
- This MCP server exposes **17 tools**, **26 resources**, and **10 prompts** for controlling your Commodore 64.
663
+ This MCP server exposes **17 tools**, **27 resources**, and **10 prompts** for controlling your Commodore 64.
565
664
 
566
665
  ### Tools
567
666
 
@@ -814,7 +913,8 @@ Grouped entry point for reading and updating selected VICE resources.
814
913
  | `c64://graphics/sprite-charset/best-practices` | Documents sprite and charset workflows, memory layout, VIC-II configuration, common pitfalls, and proven techniques for hardware-accelerated graphics. |
815
914
  | `c64://memory/map` | Page-by-page breakdown of the 64 KB address space with hardware, ROM, and RAM regions. |
816
915
  | `c64://memory/zero-page-and-workspace` | Documents zero-page variables, BASIC pointers, and KERNAL workspace addresses. |
817
- | `c64://kernal/rom-routines` | Lists KERNAL ROM vectors and service routines for OS-level functionality. |
916
+ | `c64://basic/rom-routines` | Maps BASIC ROM landmarks, reusable interpreter routines, numeric helpers, string helpers, and C64-specific BASIC continuation entries. |
917
+ | `c64://kernal/rom-routines` | Maps KERNAL ROM vectors, jump table entries, internal routines, serial/tape/screen services, and reset handlers. |
818
918
  | `c64://io/spec` | Covers VIC-II, SID, CIA, and system control registers with address ranges and usage notes. |
819
919
  | `c64://io/cia/spec` | Details CIA 1/2 registers, timers, interrupts, and keyboard matrix layout. |
820
920
  | `c64://printer/spec` | Covers device setup, control codes, and Ultimate 64 integration for printers. |
@@ -506,4 +506,4 @@ Screen-code conversion
506
506
 
507
507
  - If input is ASCII uppercase 'A'..'Z', convert: screen = PETSCII - $40 (e.g. $41→$01). Implement in a small loop if needed.
508
508
 
509
- This file is intentionally minimal: use `basicConverter` / `assemblyConverter` in `src/` for tokenization/PRG building and `data/graphics/character-set.csv` for exact screen-code mappings.
509
+ This file is intentionally minimal: use `src/tools/basicTokenizer.ts` / `src/tools/assembler.ts` for tokenization/PRG building and `data/graphics/character-set.csv` for exact screen-code mappings.
@@ -0,0 +1,269 @@
1
+ # C64 BASIC ROM Routines Memory Map — Compact ($A000-$BFFF, $E000-$E4D2)
2
+
3
+ > Purpose: Token-efficient reference for Commodore 64 BASIC V2 ROM routines, tables, parser/evaluator helpers, numeric/string machinery, statement/function dispatch, and C64-specific BASIC continuation code.
4
+ > Format: Address-first tables; **bold** names indicate the most reusable entry points for machine-language or MCP tooling.
5
+ > Conventions: A=Accumulator, X,Y=Index, C=Carry; “—” = not applicable.
6
+ > Related memory maps: `../memory/memory-map.md`, `../memory/low-memory-map.md`, `../kernal/rom-routines.md`, `../io/io-spec.md`.
7
+
8
+ ## Legend
9
+
10
+ Class: A=safe helper, B=usable with guardrails, C=interpreter-coupled, D=non-returning/control-flow, data=table/constant.
11
+
12
+ ## Direct-Use Rules
13
+
14
+ - BASIC ROM must be banked in (`$0001` LORAM+HIRAM set). KERNAL ROM must also be visible for I/O and error reporting.
15
+ - Many failures jump to `$A437` (`ERROR`) rather than returning a status code.
16
+ - Prefer KERNAL APIs for files/devices and dynamic keyboard or tokenized program install for statements.
17
+ - Best reusable BASIC targets: `FRMEVL`, `FRMNUM`, `GETBYT`, `GETADR`, `PTRGET`, `FOUT`, `MOVFM`, `MOVMF`, `LNKPRG`, `CLR`.
18
+ - Avoid direct statement entries unless a wrapper controls `TXTPTR`, stack, BASIC vectors, error recovery, and runtime pointers.
19
+
20
+ ## Essential BASIC State
21
+
22
+ | Address | Decimal | Name | Function | Notes |
23
+ |:--|:--|:--|:--|:--|
24
+ | `$000C` | 12 | DIMFLG | Array allocation/reference flag | Used by `PTRGET`. |
25
+ | `$000D` | 13 | VALTYP | Current type | `$00` numeric, `$FF` string. |
26
+ | `$000E` | 14 | INTFLG | Numeric subtype | `$00` float, `$80` integer. |
27
+ | `$0014–$0015` | 20–21 | LINNUM | Line/address/number temp | Used by `PEEK`, `POKE`, `WAIT`, `SYS`. |
28
+ | `$0016–$0021` | 22–33 | TEMPPT/TEMPST | Temporary string descriptor stack | Three 3-byte descriptors. |
29
+ | `$002B–$002C` | 43–44 | **TXTTAB** | BASIC program start | Normally `$0801`. |
30
+ | `$002D–$002E` | 45–46 | **VARTAB** | Scalar variable table start | Updated after program changes. |
31
+ | `$002F–$0030` | 47–48 | **ARYTAB** | Array table start | Follows scalars. |
32
+ | `$0031–$0032` | 49–50 | **STREND** | End of arrays / free RAM start | Moves upward. |
33
+ | `$0033–$0034` | 51–52 | **FREETOP** | Bottom of string heap | Strings grow downward. |
34
+ | `$0037–$0038` | 55–56 | **MEMSIZ** | BASIC memory top | Lower then `CLR` to reserve RAM. |
35
+ | `$0039–$003A` | 57–58 | CURLIN | Current BASIC line | High byte `$FF` = direct mode. |
36
+ | `$0041–$0042` | 65–66 | DATPTR | Current DATA item pointer | Reset by `RESTORE`. |
37
+ | `$0045–$0048` | 69–72 | VARNAM/VARPNT | Current variable name/value pointer | Set by `PTRGET`. |
38
+ | `$0050–$0052` | 80–82 | DSCPNT | String descriptor pointer/temp | String functions. |
39
+ | `$0061–$0066` | 97–102 | **FAC1** | Primary floating-point accumulator | Exponent, mantissa, sign. |
40
+ | `$0069–$006E` | 105–110 | FAC2/ARG | Secondary FP accumulator | Arithmetic argument. |
41
+ | `$0070` | 112 | FACOV | FP rounding byte | Used by `ROUND`. |
42
+ | `$0073–$008A` | 115–138 | **CHRGET/CHRGOT** | BASIC scanner in zero page | `CHRGOT` entry at `$0079`. |
43
+ | `$007A–$007B` | 122–123 | **TXTPTR** | BASIC text pointer | Parser/evaluator input. |
44
+ | `$008B–$008F` | 139–143 | RNDX | RND seed | Five-byte FP seed. |
45
+ | `$0300–$030B` | 768–779 | BASIC vectors | Error, warm start, tokenize, LIST, execute, evaluate | Copied from `$E447`. |
46
+ | `$030C–$030F` | 780–783 | SYS save | A, X, Y, status for BASIC `SYS` | Restored after SYS returns. |
47
+ | `$0310–$0311` | 784–785 | USR vector | Target for `USR()` | Default illegal quantity. |
48
+
49
+ ## ROM Landmarks
50
+
51
+ | Address | Decimal | Name | Function | Class | Notes |
52
+ |:--|:--|:--|:--|:--|:--|
53
+ | `$A000` | 40960 | Cold vector | Points to `$E394` | data | Do not execute as code. |
54
+ | `$A002` | 40962 | Warm vector | Points to `$E37B` | data | BASIC warm start. |
55
+ | `$A004` | 40964 | CBMBASIC | ROM signature | data | Identification text. |
56
+ | `$A00C` | 40972 | Command table | 35 statement addresses minus 1 | data | Token `$80–$A2`. |
57
+ | `$A052` | 41042 | Function table | 23 function addresses minus 1 | data | Token `$B4–$CA`. |
58
+ | `$A080` | 41088 | Operator table | Precedence + address minus 1 | data | Arithmetic, compare, logical. |
59
+ | `$A09E` | 41118 | Keyword table | Statement keywords | data | High bit marks final char. |
60
+ | `$A129` | 41257 | Reserved-word table | `TAB(`, `TO`, `SPC(`, etc. | data | Tokenizer metadata. |
61
+ | `$A140` | 41280 | Operator keyword table | `+ - * / ^ AND OR > = <` | data | Tokenizer metadata. |
62
+ | `$A14D` | 41293 | Function keyword table | `SGN` through `MID$` | data | Tokenizer metadata. |
63
+ | `$A19E` | 41374 | Error text | BASIC error message strings | data | Indexed by `$A328`. |
64
+ | `$A328` | 41768 | Error pointers | Pointers to error text | data | X = error index. |
65
+ | `$A364` | 41828 | Interpreter text | `OK`, `ERROR IN`, `READY`, `BREAK` | data | Screen messages. |
66
+ | `$BFED` | 49133 | EXP | EXP function body | A/B | Continues at `$E000`. |
67
+ | `$E000–$E4D2` | 57344–58578 | BASIC continuation | EXP/RND/trig, I/O wrappers, init, BASIC vectors | mixed | Located in ROM area often grouped with KERNAL. |
68
+
69
+ ## Core Reusable Entries
70
+
71
+ | Address | Decimal | Name | Function | Args/Input | Output | Class | Notes |
72
+ |:--|:--|:--|:--|:--|:--|:--|:--|
73
+ | `$A533` | 42291 | **LNKPRG** | Relink tokenized BASIC program | Program at `TXTTAB` | Forward links rebuilt | B | Use after raw program writes. |
74
+ | `$A57C` | 42364 | CRUNCH | Tokenize input line | BASIC input-buffer state | Tokenized line | B/C | Easier: use keyboard injection. |
75
+ | `$A613` | 42515 | FNDLIN | Find BASIC line | `LINNUM` target | C set if found | B | Program table must be valid. |
76
+ | `$A65E` | 42590 | **CLR** | Clear variables/runtime/string heap | BASIC pointers valid | Runtime reset | B/C | Use after program/memory-bound changes. |
77
+ | `$A68E` | 42638 | STXTPT | Set text pointer to program start | `TXTTAB` valid | `TXTPTR=TXTTAB-1` | B/C | Prepares interpreter scan. |
78
+ | `$A717` | 42775 | LIST helper | Detokenize through output channel | Program text/current channel | Output text | C | Output-channel dependent. |
79
+ | `$AB1E` | 43806 | **STROUT** | Output zero/quote-terminated string | A/Y pointer | Characters output | B | Current output channel used. |
80
+ | `$AB47` | 43847 | CHR output wrapper | Output PETSCII char | A=byte | Character output | B/C | Prefer KERNAL `CHROUT`. |
81
+ | `$AD8A` | 44426 | **FRMNUM** | Evaluate numeric expression | `TXTPTR` at first char | FAC1 numeric | B | String result -> type error. |
82
+ | `$AD8D` | 44429 | **CHKNUM** | Require numeric result | `VALTYP` | Return or error | A | Type mismatch jumps to error. |
83
+ | `$AD8F` | 44431 | CHKSTR | Require string result | `VALTYP` | Return or error | A | Type mismatch jumps to error. |
84
+ | `$AD90` | 44432 | CHKVAL | Type check by carry | C clear=numeric, set=string | Return or error | A | Helper under `CHKNUM/CHKSTR`. |
85
+ | `$AD9E` | 44446 | **FRMEVL** | Evaluate any expression | `TXTPTR` at first char | FAC1 or string result; `VALTYP` | B | Most useful parser entry. |
86
+ | `$AEF7` | 44791 | CHKCLS | Require `)` | Scanner state | Advances or error | B | Syntax helper. |
87
+ | `$AEFA` | 44794 | CHKOPN | Require `(` | Scanner state | Advances or error | B | Syntax helper. |
88
+ | `$AEFD` | 44797 | CHKCOM | Require `,` | Scanner state | Advances or error | B | Syntax helper. |
89
+ | `$AEFF` | 44799 | SYNCHR | Require char in A | A=required char | Advances or error | B | Syntax helper. |
90
+ | `$B08B` | 45195 | **PTRGET** | Find/create variable | `TXTPTR` at var name | `VARPNT`, Y/A value address | B | May allocate or evaluate subscripts. |
91
+ | `$B1AA` | 45482 | FAC→int | Convert FAC1 to signed 16-bit | FAC1 | A=lo,Y=hi | A/B | Range-sensitive. |
92
+ | `$B391` | 45969 | **GIVAYF** | Signed int to FAC1 | A=hi,Y=lo | FAC1 | A | Values >32767 become negative. |
93
+ | `$B3A2` | 45986 | SNGFLT | Byte to FAC1 | Y=byte | FAC1 | A | Sets numeric result. |
94
+ | `$B487` | 46215 | STRLIT | Create string descriptor from literal | A/Y pointer | Temp string descriptor | B | String heap/temps apply. |
95
+ | `$B4F4` | 46324 | GETSPA | Allocate string space | A=bytes | X/Y pointer | B/C | May garbage collect or error. |
96
+ | `$B526` | 46374 | GARBA2 | Garbage collect string heap | BASIC string state | Compacted strings | C | Avoid unless runtime owned. |
97
+ | `$B6DB` | 46811 | FRETMS | Release temp string | A/Y descriptor | Temp stack updated | B/C | Descriptor discipline matters. |
98
+ | `$B79E` | 47006 | **GETBYT** | Parse byte expression | `TXTPTR` expression | X=`0..255` | B | Illegal quantity on range error. |
99
+ | `$B7EB` | 47083 | **GETNUM** | Parse `addr,byte` | `TXTPTR` expression | `$14/$15`, X=byte | B | Useful for POKE-style syntax. |
100
+ | `$B7F1` | 47089 | COMBYT | Parse comma then byte | Current char comma | X=byte | B | Calls comma check. |
101
+ | `$B7F7` | 47095 | **GETADR** | FAC1 to unsigned address | FAC1 | `$14/$15`, A/Y | A/B | `0..65535`. |
102
+ | `$BBA2` | 48034 | **MOVFM** | Load packed float to FAC1 | A/Y pointer | FAC1 | A/B | Read numeric variable/constant. |
103
+ | `$BBD4` | 48084 | **MOVMF** | Store FAC1 as packed float | X/Y destination, FAC1 | 5 bytes written | A/B | Floating scalar vars. |
104
+ | `$BC1B` | 48155 | ROUND | Round FAC1 | FAC1/FACOV | FAC1 | A | Numeric helper. |
105
+ | `$BC2B` | 48171 | SIGN | Sign of FAC1 | FAC1 | A=`0`,`1`,`$FF` | A | Zero/positive/negative. |
106
+ | `$BDDD` | 48605 | **FOUT** | FAC1 to ASCII | FAC1 | A/Y temp string pointer | A/B | Copy text immediately. |
107
+
108
+ ## Math Helpers
109
+
110
+ | Address | Decimal | Name | Input | Output | Class | Notes |
111
+ |:--|:--|:--|:--|:--|:--|:--|
112
+ | `$BC39` | 48185 | SGN | FAC1 | FAC1 = -1/0/1 | A | Function token `$B4`. |
113
+ | `$BC58` | 48216 | ABS | FAC1 | FAC1 | A | Clears sign. |
114
+ | `$BCCC` | 48332 | INT | FAC1 | FAC1 | A | BASIC floor semantics. |
115
+ | `$B9EA` | 47594 | LOG | FAC1 > 0 | FAC1 | A/B | Domain errors jump to `ERROR`. |
116
+ | `$BF71` | 49009 | SQR | FAC1 >= 0 | FAC1 | A/B | Uses LOG/EXP path. |
117
+ | `$BFB4` | 49076 | NEGOP | FAC1 | -FAC1 | A | Unary negation. |
118
+ | `$BFED` | 49133 | EXP | FAC1 | FAC1 | A/B | Continues at `$E000`; overflow possible. |
119
+ | `$E097` | 57495 | RND | FAC1 argument | FAC1 | A/B | Positive advances, negative seeds, zero mixes time. |
120
+ | `$E264` | 57956 | COS | FAC1 radians | FAC1 | A/B | Adds PI/2, uses SIN. |
121
+ | `$E26B` | 57963 | SIN | FAC1 radians | FAC1 | A/B | Dispatch entry. |
122
+ | `$E2B4` | 58036 | TAN | FAC1 radians | FAC1 | A/B | SIN/COS division. |
123
+ | `$E30E` | 58126 | ATN | FAC1 | FAC1 radians | A/B | Polynomial approximation. |
124
+
125
+ ## Statement Dispatch Entries
126
+
127
+ Statement entries assume live interpreter context unless noted. Prefer text/tokenized program execution over direct calls.
128
+
129
+ | Token | Command | Entry | Class | Direct-use note |
130
+ |:--|:--|:--|:--|:--|
131
+ | `$80` | END | `$A831` | D | Program termination. |
132
+ | `$81` | FOR | `$A742` | C | Requires FOR stack frame. |
133
+ | `$82` | NEXT | `$AD1E` | C | Requires matching FOR frame. |
134
+ | `$83` | DATA | `$A8F8` | C | Statement skipper. |
135
+ | `$84` | INPUT# | `$ABA5` | C | Prefer KERNAL channel I/O. |
136
+ | `$85` | INPUT | `$ABBF` | C | Editor/string context. |
137
+ | `$86` | DIM | `$B081` | C | Allocates arrays. |
138
+ | `$87` | READ | `$AC06` | C | Depends on `DATPTR`. |
139
+ | `$88` | LET | `$A9A5` | C | Prefer `FRMEVL` + `PTRGET` + store helper. |
140
+ | `$89` | GOTO | `$A8A0` | D | Interpreter flow. |
141
+ | `$8A` | RUN | `$A871` | D | Non-local flow. |
142
+ | `$8B` | IF | `$A928` | C | Interpreter-only. |
143
+ | `$8C` | RESTORE | `$A81D` | C | Resets DATA state. |
144
+ | `$8D` | GOSUB | `$A883` | C | Requires BASIC return frame. |
145
+ | `$8E` | RETURN | `$A8D2` | C | Requires GOSUB frame. |
146
+ | `$8F` | REM | `$A93B` | C | Statement skipper. |
147
+ | `$90` | STOP | `$A82F` | D | STOP/BREAK path. |
148
+ | `$91` | ON | `$A94B` | C | Interpreter-only. |
149
+ | `$92` | WAIT | `$B82D` | C | Can hang; avoid for MCP. |
150
+ | `$93` | LOAD | `$E168` | C | Prefer KERNAL `LOAD`. |
151
+ | `$94` | SAVE | `$E156` | C | Prefer KERNAL `SAVE`. |
152
+ | `$95` | VERIFY | `$E165` | C | Prefer KERNAL load/verify. |
153
+ | `$96` | DEF | `$B3B3` | C | DEF FN machinery. |
154
+ | `$97` | POKE | `$B824` | C | Prefer memory write or `GETNUM`. |
155
+ | `$98` | PRINT# | `$AA80` | C | Prefer KERNAL channel output. |
156
+ | `$99` | PRINT | `$AAA0` | C | Output context required. |
157
+ | `$9A` | CONT | `$A857` | D | Requires continuation state. |
158
+ | `$9B` | LIST | `$A69C` | C | Output-channel dependent. |
159
+ | `$9C` | CLR | `$A65E` | B/C | Useful after memory/program edits. |
160
+ | `$9D` | CMD | `$AA86` | C | Prefer KERNAL channel control. |
161
+ | `$9E` | SYS | `$E12A` | C | Parses BASIC `SYS`; direct ML should `JSR/JMP`. |
162
+ | `$9F` | OPEN | `$E1BE` | C | Prefer KERNAL `OPEN`. |
163
+ | `$A0` | CLOSE | `$E1C7` | C | Prefer KERNAL `CLOSE`. |
164
+ | `$A1` | GET | `$AB7B` | C | Assignment/string path. |
165
+ | `$A2` | NEW | `$A642` | D | Destructive. |
166
+
167
+ ## Function Dispatch Entries
168
+
169
+ Function entries are normally called by the evaluator. Direct use is safest for simple FAC1 numeric helpers.
170
+
171
+ | Token | Function | Entry | Class | Direct-use note |
172
+ |:--|:--|:--|:--|:--|
173
+ | `$B4` | SGN | `$BC39` | A | FAC1 in/out. |
174
+ | `$B5` | INT | `$BCCC` | A | FAC1 in/out. |
175
+ | `$B6` | ABS | `$BC58` | A | FAC1 in/out. |
176
+ | `$B7` | USR | `$0310` | C | RAM vector. |
177
+ | `$B8` | FRE | `$B37D` | C | Can trigger GC. |
178
+ | `$B9` | POS | `$B39E` | C | Reads cursor/channel state. |
179
+ | `$BA` | SQR | `$BF71` | A/B | FAC1 non-negative. |
180
+ | `$BB` | RND | `$E097` | A/B | FAC1 argument. |
181
+ | `$BC` | LOG | `$B9EA` | A/B | FAC1 positive. |
182
+ | `$BD` | EXP | `$BFED` | A/B | Overflow possible. |
183
+ | `$BE` | COS | `$E264` | A/B | FAC1 radians. |
184
+ | `$BF` | SIN | `$E26B` | A/B | FAC1 radians. |
185
+ | `$C0` | TAN | `$E2B4` | A/B | FAC1 radians. |
186
+ | `$C1` | ATN | `$E30E` | A/B | FAC1 in/out. |
187
+ | `$C2` | PEEK | `$B80D` | C | Parser convention; ML should `LDA`. |
188
+ | `$C3` | LEN | `$B77C` | C | String argument convention. |
189
+ | `$C4` | STR$ | `$B465` | C | String descriptor result. |
190
+ | `$C5` | VAL | `$B7AD` | C | String parser state. |
191
+ | `$C6` | ASC | `$B78B` | C | Errors on empty string. |
192
+ | `$C7` | CHR$ | `$B6EC` | C | String descriptor result. |
193
+ | `$C8` | LEFT$ | `$B700` | C | String function convention. |
194
+ | `$C9` | RIGHT$ | `$B72C` | C | String function convention. |
195
+ | `$CA` | MID$ | `$B737` | C | String function convention. |
196
+
197
+ ## Operator Dispatch Entries
198
+
199
+ | Operator | Entry | Precedence | Direct-use note |
200
+ |:--|:--|:--|:--|
201
+ | `+` | `$B86A` | `$79` | Prefer `FRMEVL`. |
202
+ | `-` | `$B853` | `$79` | Prefer `FRMEVL`. |
203
+ | `*` | `$BA2B` | `$7B` | Prefer `FRMEVL`. |
204
+ | `/` | `$BB12` | `$7B` | Prefer `FRMEVL`. |
205
+ | `^` | `$BF7B` | `$7D` | Prefer `FRMEVL`. |
206
+ | `AND` | `$AFE9` | low | Evaluator convention. |
207
+ | `OR` | `$AFE6` | low | Evaluator convention. |
208
+ | comparison | `$B016` | compare | Evaluator convention. |
209
+ | unary `-` | `$BFB4` | unary | FAC1 negation is reasonable. |
210
+ | `NOT` | `$AF0D` | unary | Evaluator convention. |
211
+
212
+ ## C64-Specific BASIC Continuation (`$E000–$E4D2`)
213
+
214
+ | Address | Decimal | Name | Function | Class | Notes |
215
+ |:--|:--|:--|:--|:--|:--|
216
+ | `$E000` | 57344 | EXP continuation | Completes EXP from `$BFED` | A/B | Cross-ROM BASIC code. |
217
+ | `$E043` | 57411 | POLY1 | FP polynomial helper | B | FAC1/coefficient state. |
218
+ | `$E059` | 57433 | POLY2 | FP polynomial helper | B | Used by math functions. |
219
+ | `$E08D` | 57485 | RMULC | RND multiply constant | data | Five-byte FP. |
220
+ | `$E092` | 57490 | RADDC | RND add constant | data | Five-byte FP. |
221
+ | `$E097` | 57495 | RND | Random number function | A/B | FAC1 argument. |
222
+ | `$E0F9` | 57593 | BASIC/KERNAL I/O bridge | Checked CHKIN/CHKOUT/CHRIN/CHROUT/GETIN | C/D | May enter BASIC error path. |
223
+ | `$E12A` | 57642 | SYS | BASIC `SYS` parser/executor | C | Uses `$030C–$030F`. |
224
+ | `$E156` | 57686 | SAVE wrapper | BASIC `SAVE` statement | C | Prefer KERNAL API. |
225
+ | `$E165` | 57701 | VERIFY wrapper | BASIC `VERIFY` statement | C | Falls into LOAD path. |
226
+ | `$E168` | 57704 | LOAD wrapper | BASIC `LOAD` statement | C | May relink BASIC program. |
227
+ | `$E1BE` | 57790 | OPEN wrapper | BASIC `OPEN` statement | C | Prefer KERNAL API. |
228
+ | `$E1C7` | 57799 | CLOSE wrapper | BASIC `CLOSE` statement | C | Prefer KERNAL API. |
229
+ | `$E1D4` | 57812 | L/V/S parameter setup | Parse filename/LFN/dev/SA | C | For LOAD/SAVE/VERIFY. |
230
+ | `$E200` | 57856 | Get int to X | Parse comma + integer byte | B/C | Parser helper. |
231
+ | `$E206` | 57862 | Fetch/endline helper | Parser control-flow helper | D | Can unwind caller. |
232
+ | `$E20E` | 57870 | Check comma | Require comma | B/C | Parser helper. |
233
+ | `$E219` | 57881 | O/C parameter setup | Parse OPEN/CLOSE params | C | Sets KERNAL file state. |
234
+ | `$E264` | 57956 | COS | Cosine | A/B | FAC1 radians. |
235
+ | `$E26B` | 57963 | SIN | Sine | A/B | FAC1 radians. |
236
+ | `$E2B4` | 58036 | TAN | Tangent | A/B | FAC1 radians. |
237
+ | `$E30E` | 58126 | ATN | Arctangent | A/B | FAC1 in/out. |
238
+ | `$E37B` | 58235 | Warm BASIC | READY/warm-start path | D | Jump target, not subroutine. |
239
+ | `$E38B` | 58251 | Error message path | Print BASIC error and READY | D | X=error index. |
240
+ | `$E394` | 58260 | Cold BASIC | Power-on BASIC init | D | Reset/init path. |
241
+ | `$E3A2` | 58274 | CHRGET image | Source copied to `$0073` | data | Scanner code image. |
242
+ | `$E3BF` | 58303 | INIT | BASIC zero-page init | C/D | Copies `CHRGET`. |
243
+ | `$E422` | 58402 | Startup messages | Banner and bytes-free output | D | Boot path. |
244
+ | `$E447` | 58439 | BASIC vector table | Defaults for `$0300–$030B` | data | Error, warm, crunch, list, execute, evaluate. |
245
+ | `$E453` | 58451 | Copy BASIC vectors | Restore BASIC RAM vectors | B/C | Mostly init/recovery. |
246
+ | `$E460` | 58464 | Text constants | Startup/message text | data | Constants. |
247
+
248
+ ## Compact Workflows
249
+
250
+ | Need | Preferred mechanism | Minimal sequence |
251
+ |:--|:--|:--|
252
+ | Evaluate expression | `FRMNUM`/`FRMEVL` | Set `TXTPTR` to first char, `JSR $AD8A` or `JSR $AD9E`, handle BASIC errors. |
253
+ | Numeric result as text | `FOUT` | FAC1 ready, `JSR $BDDD`, copy A/Y string immediately. |
254
+ | Parse byte/address syntax | `GETBYT`/`GETADR`/`GETNUM` | Use BASIC-compatible expression text and controlled `TXTPTR`. |
255
+ | Read/write numeric scalar | `PTRGET` + `MOVFM`/`MOVMF` | Set `TXTPTR` to var name; use returned `VARPNT`. |
256
+ | Install tokenized program | Raw write + `LNKPRG` + `CLR` | Write at `TXTTAB`, final next pointer `$0000`, `JSR $A533`, `JSR $A65E`. |
257
+ | Execute BASIC statement | Dynamic keyboard or normal interpreter | Avoid direct statement entries unless runtime/error context is controlled. |
258
+ | Reserve high RAM | Lower `MEMSIZ`, then `CLR` | Update `$37/$38`, `JSR $A65E`; keep ML/sprites above new top. |
259
+
260
+ ## Avoid as General MCP APIs
261
+
262
+ | Entry | Reason |
263
+ |:--|:--|
264
+ | `$A437` | BASIC error path; non-returning for normal callers. |
265
+ | `$A7AE` | Main interpreter loop; full runtime context required. |
266
+ | `$A7ED` | Command dispatcher; token/stack conventions required. |
267
+ | `$E206` | May skip a return address at end-of-statement. |
268
+ | `$E37B`, `$E394` | Warm/cold BASIC entry paths, not subroutines. |
269
+ | Direct string allocation/GC | Safe only when descriptor stack and movable string heap are controlled. |
@@ -17,12 +17,12 @@ Do not assume the current backend is correct without checking
17
17
 
18
18
  ## Fast Paths
19
19
 
20
- - Grouped MCP tools are never called bare. For tools such as `c64_program`, `c64_memory`, `c64_graphics`, `c64_sound`, and `c64_system`, always send an object with `op` first.
21
- - Wrong: `c64_program {}`. Correct: `c64_program { op: "cross_platform_greeting" }`.
20
+ - Grouped MCP tools are never called bare. For tools such as `c64_program`, `c64_memory`, `c64_graphics`, `c64_sound`, and `c64_system`, call the tool with flat arguments that include `op`.
21
+ - Wrong: `c64_program {}` or `{ "c64_program": { "op": "cross_platform_greeting" } }`. Correct: call tool `c64_program` with `{ "op": "cross_platform_greeting" }`.
22
22
  - For simple visible confirmation on `vice`, `c64u`, or both, prefer `c64_program` with `op: "cross_platform_greeting"`.
23
23
  - For trivial hello-world and smoke-test requests, route to `.github/skills/hello-world/SKILL.md` and let that skill use the shortest greeting workflow.
24
24
  - That workflow switches backends internally, writes a platform-customized BASIC greeting, captures screenshots, and verifies the rendered text without extra tool composition.
25
- - Use manual `c64_select_backend` plus `upload_run_basic` only when the user needs custom program logic beyond a quick greeting or text demo.
25
+ - Use manual `c64_select_backend` with `op: "select"` plus `c64_program` with `op: "upload_run_basic"` only when the user needs custom program logic beyond a quick greeting or text demo.
26
26
  - On local machines with a graphical session, assume VICE should be visible by default. Only expect Xvfb or other headless fallback in CI or when no framebuffer/display session exists.
27
27
  - For manual visible VICE BASIC runs, avoid immediate `read_screen` or `wait_for_text` calls, because Binary Monitor traffic traps execution while servicing requests.
28
28
 
@@ -33,7 +33,7 @@ Do not assume the current backend is correct without checking
33
33
 
34
34
  ## Memory Map (default RAM layout)
35
35
 
36
- For Full details see `../memory/memory-map.md` with focus on low-memory (pages 0-3) in `../memory/low-memory-map.md` and KERNAL memory in `../memory/kernal-memory-map.md`.
36
+ For full details see `../memory/memory-map.md`. Use `../memory/low-memory-map.md` for zero page/pages 0-3, `../basic/rom-routines.md` for BASIC ROM routines, `../kernal/rom-routines.md` for KERNAL ROM routines, and `../io/io-spec.md` or `../io/cia-spec.md` for hardware registers.
37
37
 
38
38
  - $0000–$00FF: Zero page
39
39
  - $0100–$01FF: Stack
@@ -27,6 +27,8 @@ Use these routing shortcuts when the user wants a quick visible or audible resul
27
27
 
28
28
  Example:
29
29
 
30
+ Call tool `c64_sound` with:
31
+
30
32
  ```json
31
33
  {
32
34
  "op": "play_preset",
@@ -41,4 +43,4 @@ Example:
41
43
  ## Verification Order
42
44
 
43
45
  1. Trust the verification defined by the selected skill first.
44
- 2. Use captured artifacts or follow-up inspection only when the selected skill indicates that extra verification is needed.
46
+ 2. Use captured artifacts or follow-up inspection only when the selected skill indicates that extra verification is needed.
@@ -63,7 +63,7 @@ Conversion: Screen code ≠ PETSCII code. Use charset reference (c64://graphics/
63
63
 
64
64
  - BASIC/printing: Use PETSCII codes with CHR$() or PRINT
65
65
  - Direct screen memory: Use screen codes with POKE to $0400+offset
66
- - Tools: `c64_graphics` (`render_petscii_art`) returns both `petsciiCodes` array and screen memory data
66
+ - Tools: `c64_graphics` with `op: "render_petscii_art"` returns both `petsciiCodes` array and screen memory data
67
67
 
68
68
  ## Essential PETSCII Symbols
69
69