c64bridge 0.5.1 → 0.6.0

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 (48) hide show
  1. package/README.md +17 -5
  2. package/data/assembly/assembly-spec.md +24 -0
  3. package/data/assembly/examples/video/hello_world.asm +39 -0
  4. package/data/basic/basic-pitfalls.md +236 -0
  5. package/data/basic/basic-spec.md +507 -198
  6. package/data/video/petscii-style-guide.md +105 -0
  7. package/data/video/sprite-charset-best-practices.md +292 -0
  8. package/dist/c64Client.js +1 -0
  9. package/dist/prompts/registry.js +10 -2
  10. package/dist/rag/knowledgeIndex.js +111 -24
  11. package/dist/rag/retriever.js +110 -4
  12. package/dist/tools/audio.js +26 -13
  13. package/dist/tools/developer.js +34 -0
  14. package/dist/tools/graphics.js +6 -5
  15. package/dist/tools/memory.js +1 -1
  16. package/dist/tools/pollValidator.js +256 -0
  17. package/dist/tools/programRunners.js +352 -12
  18. package/dist/tools/rag.js +1 -7
  19. package/doc/MCP_SETUP.md +7 -1
  20. package/doc/bun/baseline-metrics.md +16 -0
  21. package/doc/bun/migration-checklist.md +55 -0
  22. package/doc/bun/migration.md +83 -0
  23. package/doc/developer.md +72 -10
  24. package/doc/improve-knowledge/notes.md +29 -0
  25. package/doc/improve-knowledge/plan.md +28 -3
  26. package/doc/improve-knowledge/rollout.md +39 -5
  27. package/doc/meta-tools/README.md +101 -0
  28. package/doc/meta-tools/analysis.md +255 -0
  29. package/doc/{meta-tools.md → meta-tools/catalog.md} +2 -2
  30. package/doc/meta-tools/notes.md +174 -0
  31. package/doc/meta-tools/rollout.md +343 -0
  32. package/mcp.json +1 -1
  33. package/package.json +17 -10
  34. package/scripts/c64-cli.mjs +42 -7
  35. package/scripts/c64-tool.sh +7 -1
  36. package/scripts/check-node-compat.mjs +107 -0
  37. package/scripts/invoke-bun.mjs +58 -0
  38. package/scripts/rag-rebuild.mjs +11 -13
  39. package/scripts/run-mcp-check.sh +10 -2
  40. package/scripts/run-tests.mjs +3 -3
  41. package/scripts/run-tests.ts +187 -0
  42. package/scripts/start.mjs +3 -26
  43. package/scripts/update-readme.ts +17 -1
  44. package/scripts/verify-package.mjs +0 -1
  45. package/data/assembly/examples/effects/sinewave.asm +0 -5
  46. package/doc/meta-tools-rollout.md +0 -211
  47. package/scripts/register-ts-node.mjs +0 -6
  48. /package/data/assembly/examples/{graphics/sprite/mover.asm → video/sprite_mover.asm} +0 -0
package/README.md CHANGED
@@ -332,10 +332,16 @@ Please note that all logs use `stderr` since `stdout` is reserved for the MCP pr
332
332
 
333
333
  ## Build & Test 🧪
334
334
 
335
- - `npm run build` — type-check the TypeScript sources, normalize the dist layout for packaging, and regenerate the MCP API tables in `README.md`.
335
+ - `bun install` — install dependencies for development (fast path). Node users can continue to use `npm install`.
336
+ - `bun run build` — type-check the TypeScript sources, normalize the dist layout for packaging, and regenerate the MCP API tables in `README.md`.
336
337
  - `npm test` — run the integration tests against an in-process mock that emulates the c64 REST API.
337
338
  - `npm test -- --real` — exercise the same tests against a real c64 device. The runner reuses your MCP config (`~/.c64bridge.json` or `C64BRIDGE_CONFIG`) to determine the REST endpoint. You can also override explicitly with `--base-url=http://<host>`.
338
339
  - `npm run check` — convenience command that runs both the type-check and the mock-backed test suite.
340
+ - `npm run coverage` — runs the Bun-powered test harness with coverage enabled and emits `coverage/lcov.info` (CI uploads to Codecov).
341
+
342
+ **Development Tooling**
343
+
344
+ This project uses [Bun](https://bun.sh/) for building and testing due to its high performance (significantly faster than npm/node for development workflows). The npm package remains fully compatible with Node.js 18+ and can be installed and run using standard npm commands. For release preparation, npm/node is still used to ensure everything works correctly on the target platform.
339
345
 
340
346
  The test runner accepts the following options:
341
347
 
@@ -347,6 +353,8 @@ The test runner accepts the following options:
347
353
 
348
354
  <!-- AUTO-GENERATED:MCP-DOCS-START -->
349
355
 
356
+ This MCP server exposes **74 tools**, **25 resources**, and **7 prompts** for controlling your Commodore 64.
357
+
350
358
  ### Tools
351
359
 
352
360
  #### Programs
@@ -395,10 +403,10 @@ The test runner accepts the following options:
395
403
  | `analyze_audio` | Automatically analyze SID playback when the user requests verification feedback. | `sid`, `audio`, `analysis` |
396
404
  | `modplay_file` | Play a MOD tracker module stored on the Ultimate filesystem. | `sid`, `audio`, `playback` |
397
405
  | `music_compile_and_play` | Compile a SIDWAVE composition to PRG or SID and optionally play it immediately. | `sid`, `audio`, `music`, `compiler` |
398
- | `music_generate` | Generate a lightweight arpeggio and schedule playback on SID voice 1. | `sid`, `audio`, `music`, `generator` |
406
+ | `music_generate` | Generate a lightweight arpeggio and schedule playback on SID voice 1. | `sid`, `audio`, `music`, `generator`, `pal-ntsc` |
399
407
  | `record_and_analyze_audio` | Record audio from the default input device and analyze SID playback characteristics. | `sid`, `audio`, `analysis` |
400
408
  | `sid_note_off` | Release a SID voice by clearing its GATE bit. | `sid`, `audio`, `control`, `music` |
401
- | `sid_note_on` | Trigger a SID voice with configurable waveform, pulse width, and ADSR envelope. See c64://specs/sid. | `sid`, `audio`, `control`, `music` |
409
+ | `sid_note_on` | Trigger a SID voice with configurable waveform, pulse width, and ADSR envelope. See c64://specs/sid. | `sid`, `audio`, `control`, `music`, `pal-ntsc` |
402
410
  | `sid_reset` | Reset the SID chip either softly (silence) or with a full register scrub. | `sid`, `audio`, `control` |
403
411
  | `sid_silence_all` | Silence all SID voices by clearing control and envelope registers. | `sid`, `audio`, `control` |
404
412
  | `sid_volume` | Set the SID master volume register at $D418. See c64://specs/sid. | `sid`, `audio`, `control` |
@@ -458,8 +466,8 @@ The test runner accepts the following options:
458
466
 
459
467
  | Name | Description | Tags |
460
468
  | --- | --- | --- |
461
- | `create_petscii_image` | Create PETSCII art from prompts or text, optionally run it on the C64, and return metadata. See c64://specs/basic and c64://specs/vic. | `graphics`, `vic`, `petscii`, `basic` |
462
- | `generate_sprite_prg` | Generate and execute a PRG that displays a sprite from raw 63-byte data. See c64://specs/vic for registers. | `graphics`, `vic`, `sprite`, `assembly` |
469
+ | `create_petscii_image` | Create PETSCII art from prompts or text, optionally run it on the C64, and return metadata including PETSCII codes and glyphs. See c64://specs/basic, c64://specs/vic, and c64://specs/charset. | `graphics`, `vic`, `petscii`, `basic`, `pal-ntsc` |
470
+ | `generate_sprite_prg` | Generate and execute a PRG that displays a sprite from raw 63-byte data. See c64://specs/vic for registers. | `graphics`, `vic`, `sprite`, `assembly`, `pal-ntsc` |
463
471
  | `render_petscii_screen` | Render PETSCII text to the screen with optional border/background colours. See c64://specs/basic. | `graphics`, `vic`, `basic`, `screen` |
464
472
 
465
473
  #### Printer
@@ -561,12 +569,16 @@ The test runner accepts the following options:
561
569
  | `c64://docs/index` | Explains how to approach each knowledge bundle and when to consult it. |
562
570
  | `c64://context/bootstrap` | Step-by-step rules for safe automation, verification, and rollback on the C64. |
563
571
  | `c64://specs/basic` | Token definitions, syntax rules, and device I/O guidance for BASIC v2. |
572
+ | `c64://docs/basic/pitfalls` | Quickref covering quotation handling, line length, tokenization, variable names, and other BASIC traps. |
564
573
  | `c64://specs/assembly` | Official opcode matrix, addressing modes, and zero-page strategy for the 6510 CPU. |
565
574
  | `c64://specs/sid` | Register map, waveform behaviour, and ADSR envelopes for expressive SID playback. |
566
575
  | `c64://specs/sidwave` | Defines the SIDWAVE interchange format used by the SID composer workflow. |
567
576
  | `c64://docs/sid/file-structure` | Explains PSID/RSID headers, metadata blocks, and compatibility notes for imported music. |
568
577
  | `c64://docs/sid/best-practices` | Captures proven waveforms, ADSR presets, phrasing, and verification workflow for pleasant SID music. |
569
578
  | `c64://specs/vic` | Covers raster timing, sprite control, colour RAM, and bitmap modes on the VIC-II. |
579
+ | `c64://specs/charset` | Character code table mapping PETSCII codes to screen codes, glyphs, and keyboard input. |
580
+ | `c64://docs/petscii-style` | Documents colour palette, readability presets, dithering patterns, and best practices for creating artistic and readable PETSCII displays. |
581
+ | `c64://docs/sprite-charset-workflows` | Documents sprite and charset workflows, memory layout, VIC-II configuration, common pitfalls, and proven techniques for hardware-accelerated graphics. |
570
582
  | `c64://specs/memory-map` | Page-by-page breakdown of the 64 KB address space with hardware, ROM, and RAM regions. |
571
583
  | `c64://specs/memory-low` | Documents zero-page variables, BASIC pointers, and KERNAL workspace addresses. |
572
584
  | `c64://specs/memory-kernal` | Lists KERNAL ROM vectors and service routines for OS-level functionality. |
@@ -194,3 +194,27 @@ Modes (columns): `A # ZP ZPX ZPY ABS ABSX ABSY IND IZX IZY REL IMP`
194
194
  - Data: `.byte expr[,…]`, `.word expr[,…]`
195
195
  - Symbols: `name = expr` / `.equ name, expr`
196
196
  - Alignment/fill (assembler‑specific): `.align n`, `.fill count, value`
197
+
198
+ ## Tips and Tricks
199
+
200
+ ### Basic Start Header
201
+
202
+ - PRG file = 2-byte little-endian load address + bytes
203
+ - Place a tokenized BASIC line at $0801, e.g. `10 SYS 4096` (token SYS = $9E) to jump to $1000
204
+ - Ensure load-address at PRG start matches where BASIC was placed (e.g. $01 $08)
205
+ - Machine code may live at $1000 or directly after BASIC; adjust SYS target accordingly
206
+
207
+ ### Display Text on Screen
208
+
209
+ 1) KERNAL CHROUT (portable)
210
+ - Put PETSCII byte in A; JSR $FFD2 to print at cursor. Handles charset mapping.
211
+ - Use for portability and when charset may vary.
212
+ 2) Direct screen writes (fast)
213
+ - STA $0400,X writes VIC-II screen codes directly. Use when you control charset and need speed.
214
+ - Color via STA $D800,X (4-bit color index).
215
+
216
+ Screen-code conversion
217
+
218
+ - If input is ASCII uppercase 'A'..'Z', convert: screen = PETSCII - $40 (e.g. $41→$01). Implement in a small loop if needed.
219
+
220
+ This file is intentionally minimal: use `basicConverter` / `assemblyConverter` in `src/` for tokenization/PRG building and `data/video/character-set.csv` for exact screen-code mappings.
@@ -0,0 +1,39 @@
1
+ ; hello_world_prg.asm
2
+ ; Single-file PRG layout:
3
+ ; - Tokenized one-line BASIC at $0801: 10 SYS 4096
4
+ ; - Machine code placed at $1000 which writes the message directly to screen RAM ($0400)
5
+ ; (no KERNAL CHROUT or BASIC printing is used)
6
+
7
+ .org $0801
8
+ ; next-line pointer (little-endian) -> $080C (start + line length)
9
+ .byte $0C, $08
10
+ ; line number 10
11
+ .byte $0A, $00
12
+ ; tokenized content: SYS (0x9E), space (0x20), '4','0','9','6' (ASCII/PETSCII digits)
13
+ .byte $9E, $20, $34, $30, $39, $36
14
+ ; line terminator
15
+ .byte $00
16
+ ; program end marker (two zero bytes)
17
+ .byte $00, $00
18
+
19
+ ; -- machine code at $1000 ------------------------------------------------
20
+ .org $1000
21
+ start:
22
+ ldx #$00 ; X = 0
23
+ write_loop:
24
+ lda message, x ; load byte from message
25
+ beq done ; zero terminator -> finished
26
+ sta $0400, x ; write character to screen RAM (fast direct write)
27
+ inx
28
+ jmp write_loop
29
+
30
+ done:
31
+ rts
32
+
33
+ message:
34
+ ; ASCII bytes for: HELLO, WORLD! (0-terminated)
35
+ ; VIC-II screen codes for: HELLO, WORLD! (screen codes from data/video/character-set.csv)
36
+ ; H E L L O , <space> W O R L D !
37
+ .byte $08, $05, $0C, $0C, $0F, $2C, $20, $17, $0F, $12, $0C, $04, $21, $00
38
+
39
+ ; End of file
@@ -0,0 +1,236 @@
1
+ # BASIC Pitfalls Quickref
2
+
3
+ Common mistakes and gotchas when writing Commodore BASIC v2 programs.
4
+
5
+ ## Quotation Handling
6
+
7
+ **Problem:** Strings with unmatched quotes cause parsing errors.
8
+
9
+ ```basic
10
+ 10 PRINT "HELLO WORLD
11
+ ```
12
+
13
+ **Solution:** Always close string literals with matching double quotes.
14
+
15
+ ```basic
16
+ 10 PRINT "HELLO WORLD"
17
+ ```
18
+
19
+ **Escaping quotes:** BASIC v2 has no escape sequence. Use `CHR$(34)` for embedded quotes.
20
+
21
+ ```basic
22
+ 10 PRINT "HE SAID " + CHR$(34) + "HELLO" + CHR$(34)
23
+ ```
24
+
25
+ ## Line Length Limits
26
+
27
+ **Problem:** BASIC lines are limited to 80 characters (2 physical screen lines). Longer lines are truncated or cause errors.
28
+
29
+ **Solution:** Break long statements across multiple numbered lines.
30
+
31
+ ```basic
32
+ 10 A=1:B=2:C=3
33
+ 20 D=A+B+C
34
+ ```
35
+
36
+ **Multi-statement lines:** Use `:` to separate statements, but watch total character count.
37
+
38
+ ## Line Numbers
39
+
40
+ **Problem:** Line numbers must be 0-63999. Reordering requires renumbering.
41
+
42
+ **Best practice:** Use increments of 10 (e.g., 10, 20, 30) to leave room for insertions.
43
+
44
+ ```basic
45
+ 10 REM MAIN LOOP
46
+ 20 FOR I=1 TO 10
47
+ 30 PRINT I
48
+ 40 NEXT I
49
+ ```
50
+
51
+ ## Tokenization Issues
52
+
53
+ **Problem:** BASIC tokenizes keywords, which affects string matching and `DATA` statements.
54
+
55
+ **Impact on DATA:**
56
+
57
+ ```basic
58
+ 10 DATA PRINT,GOTO,END
59
+ 20 READ A$,B$,C$
60
+ 30 PRINT A$ :REM DISPLAYS "P" + token bytes, not "PRINT"
61
+ ```
62
+
63
+ **Solution:** Quote `DATA` strings that might contain keywords.
64
+
65
+ ```basic
66
+ 10 DATA "PRINT","GOTO","END"
67
+ ```
68
+
69
+ ## Variable Names
70
+
71
+ **Problem:** Only the first two characters are significant. `SPEED` and `SPECIAL` both resolve to `SP`.
72
+
73
+ ```basic
74
+ 10 SPEED=10
75
+ 20 SPECIAL=20
76
+ 30 PRINT SPEED :REM PRINTS 20, NOT 10
77
+ ```
78
+
79
+ **Solution:** Use unique first-two-character combinations.
80
+
81
+ ```basic
82
+ 10 SP=10
83
+ 20 SZ=20
84
+ ```
85
+
86
+ ## Array Dimensions
87
+
88
+ **Problem:** Arrays default to dimension 10 (indices 0-10, 11 elements). Using `DIM A(10)` also creates 11 elements (0-10).
89
+
90
+ **Solution:** Explicitly dimension arrays to the exact size needed and remember the 0 index.
91
+
92
+ ```basic
93
+ 10 DIM A(9) :REM CREATES 10 ELEMENTS (0-9)
94
+ 20 FOR I=0 TO 9
95
+ 30 A(I)=I*2
96
+ 40 NEXT I
97
+ ```
98
+
99
+ ## String Concatenation
100
+
101
+ **Problem:** String concatenation without spaces can be ambiguous.
102
+
103
+ ```basic
104
+ 10 A$="HELLO"
105
+ 20 B$="WORLD"
106
+ 30 C$=A$+B$ :REM WORKS
107
+ 40 D$=A$B$ :REM SYNTAX ERROR
108
+ ```
109
+
110
+ **Solution:** Always use `+` for concatenation.
111
+
112
+ ## Floating Point Precision
113
+
114
+ **Problem:** BASIC uses 5-byte floating point with limited precision (~9 digits). Rounding errors accumulate.
115
+
116
+ ```basic
117
+ 10 A=0.1+0.1+0.1
118
+ 20 PRINT A=0.3 :REM MAY PRINT 0 (FALSE)
119
+ ```
120
+
121
+ **Solution:** Use integer arithmetic when exact values are required, or add small epsilon for comparisons.
122
+
123
+ ```basic
124
+ 10 A=1+1+1
125
+ 20 B=A/10
126
+ 30 IF ABS(B-0.3)<0.0001 THEN PRINT "CLOSE ENOUGH"
127
+ ```
128
+
129
+ ## Device Numbers
130
+
131
+ **Problem:** Using wrong device numbers causes `FILE NOT FOUND` or hangs.
132
+
133
+ - Device 0: Keyboard
134
+ - Device 1: Cassette
135
+ - Device 3: Screen
136
+ - Device 4-7: Printers
137
+ - Device 8-11: Disk drives
138
+
139
+ **Solution:** Always verify device numbers before `OPEN` statements.
140
+
141
+ ```basic
142
+ 10 OPEN 1,8,15,"I0":REM OPEN COMMAND CHANNEL ON DRIVE 8
143
+ ```
144
+
145
+ ## Memory Conflicts
146
+
147
+ **Problem:** BASIC program area grows downward from `$0801`. String/array space grows upward from `$9FFF` (or lower if adjusted). They can collide.
148
+
149
+ **Symptoms:** `OUT OF MEMORY` errors or system crashes.
150
+
151
+ **Solution:** Monitor free memory with `FRE(0)` and keep programs compact.
152
+
153
+ ```basic
154
+ 10 PRINT FRE(0) :REM PRINT FREE BYTES
155
+ ```
156
+
157
+ ## GOTO/GOSUB Loops
158
+
159
+ **Problem:** Excessive `GOSUB` without matching `RETURN` exhausts the stack (limited to ~50 nested calls).
160
+
161
+ **Solution:** Structure programs with main loops and balanced subroutine calls.
162
+
163
+ ```basic
164
+ 10 FOR I=1 TO 10
165
+ 20 GOSUB 100
166
+ 30 NEXT I
167
+ 40 END
168
+ 100 PRINT I
169
+ 110 RETURN
170
+ ```
171
+
172
+ ## Timing and Speed
173
+
174
+ **Problem:** BASIC is interpreted and slow (~1000 statements/sec). Tight loops with many operations lag.
175
+
176
+ **Solution:** Optimize hot loops, minimize array access, and consider assembly for performance-critical code.
177
+
178
+ ```basic
179
+ 10 REM SLOW
180
+ 20 FOR I=1 TO 1000
181
+ 30 A=A+1:B=B+1:C=C+1
182
+ 40 NEXT I
183
+
184
+ 10 REM FASTER
185
+ 20 FOR I=1 TO 1000
186
+ 30 A=A+1
187
+ 40 NEXT I:B=A:C=A
188
+ ```
189
+
190
+ ## Input Quirks
191
+
192
+ **Problem:** `INPUT` statements can be aborted with `STOP` or `RUN/STOP-RESTORE`, leaving variables unchanged or partially set.
193
+
194
+ **Solution:** Validate inputs and handle empty/invalid responses.
195
+
196
+ ```basic
197
+ 10 INPUT "ENTER NUMBER";A
198
+ 20 IF A<1 OR A>100 THEN PRINT "INVALID":GOTO 10
199
+ ```
200
+
201
+ ## Screen Codes vs. PETSCII
202
+
203
+ **Problem:** `PRINT` uses PETSCII codes, but `POKE` to screen memory requires screen codes (different mappings).
204
+
205
+ **Solution:** Use conversion routines or lookup tables when directly writing to screen RAM ($0400-$07E7).
206
+
207
+ ```basic
208
+ 10 REM PRINT USES PETSCII
209
+ 20 PRINT "A" :REM DISPLAYS 'A'
210
+
211
+ 30 REM POKE TO SCREEN USES SCREEN CODES
212
+ 40 POKE 1024,1 :REM DISPLAYS 'A' (SCREEN CODE 1)
213
+ ```
214
+
215
+ ## RESTORE Statement
216
+
217
+ **Problem:** `RESTORE` without line number resets `READ` pointer to the first `DATA` statement. If you need to re-read from a specific line, use `RESTORE linenum`.
218
+
219
+ ```basic
220
+ 10 DATA 1,2,3
221
+ 20 DATA 4,5,6
222
+ 30 READ A:READ B:READ C
223
+ 40 RESTORE 20 :REM RESET TO LINE 20
224
+ 50 READ D:READ E:READ F
225
+ ```
226
+
227
+ ## Summary
228
+
229
+ - **Always close quotes** and watch line lengths (80 chars).
230
+ - **Use unique variable prefixes** (first 2 chars matter).
231
+ - **Dimension arrays explicitly** and remember 0-indexing.
232
+ - **Quote DATA strings** to avoid tokenization issues.
233
+ - **Check device numbers** before OPEN.
234
+ - **Balance GOSUB/RETURN** to avoid stack overflow.
235
+ - **Validate INPUT** to handle user errors gracefully.
236
+ - **Convert between PETSCII and screen codes** when needed.