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
@@ -0,0 +1,105 @@
1
+ # PETSCII Style Guide
2
+
3
+ Colour presets and character codes for C64 PETSCII art. Target: LLM optimization.
4
+
5
+ ## C64 Colour Palette (0-15)
6
+
7
+ | Index | Name | Luminance | Common Use |
8
+ |-------|------|-----------|------------|
9
+ | 0 | Black | Low | Background, shadows |
10
+ | 1 | White | High | Text, highlights |
11
+ | 2 | Red | Medium | Accents |
12
+ | 3 | Cyan | High | Water, sky |
13
+ | 4 | Purple | Medium | Decorative |
14
+ | 5 | Green | Medium | Nature |
15
+ | 6 | Blue | Low | Sky, UI |
16
+ | 7 | Yellow | High | Highlights |
17
+ | 8 | Orange | Medium | Warm tones |
18
+ | 9 | Brown | Low | Earth |
19
+ | 10 | Light Red | Medium | Soft accents |
20
+ | 11 | Dark Grey | Low | Depth |
21
+ | 12 | Grey | Medium | Neutral |
22
+ | 13 | Light Green | High | Nature highlights |
23
+ | 14 | Light Blue | Medium | UI |
24
+ | 15 | Light Grey | Medium | Borders |
25
+
26
+ ## Recommended Colour Presets
27
+
28
+ | Preset | Border | Background | Foreground | Use Case |
29
+ |--------|--------|------------|------------|----------|
30
+ | High Contrast | 0 | 0 | 1 | Text, menus, maximum readability |
31
+ | Green Terminal | 0 | 0 | 5 | Retro terminal aesthetic |
32
+ | Ocean | 6 | 6 | 3 | Water scenes |
33
+ | Sunset | 2 | 8 | 7 | Warm scenes |
34
+ | Nature | 5 | 0 | 13 | Outdoor, forest |
35
+ | Professional UI | 6 | 0 | 14 | Applications, tools |
36
+
37
+ ## Contrast Guidelines
38
+
39
+ **Readable combinations** (luminance difference ≥3):
40
+ - 0/1 (Black/White), 0/7 (Black/Yellow), 0/13 (Black/Lt.Green)
41
+ - 6/1 (Blue/White), 6/7 (Blue/Yellow), 11/1 (Dk.Grey/White)
42
+
43
+ **Marginal** (luminance difference 2):
44
+ - 0/3 (Black/Cyan), 6/14 (Blue/Lt.Blue), 12/1 (Grey/White)
45
+
46
+ **Unreadable** (insufficient contrast):
47
+ - 12/15 (Grey/Lt.Grey), 11/12 (Dk.Grey/Grey), 2/4 (Red/Purple)
48
+ - 6/11 (Blue/Dk.Grey), 9/11 (Brown/Dk.Grey)
49
+
50
+ Border matching: Set border=background for seamless look.
51
+
52
+ ## PETSCII vs Screen Codes
53
+
54
+ **PETSCII codes** ($00-$FF): Used in BASIC strings, CHR$(), keyboard input, PRINT statements
55
+ **Screen codes** ($00-$FF): Values directly written to screen memory ($0400-$07E7)
56
+
57
+ Conversion: Screen code ≠ PETSCII code. Use charset reference (c64://specs/charset) for mapping.
58
+
59
+ **Usage**:
60
+ - BASIC/printing: Use PETSCII codes with CHR$() or PRINT
61
+ - Direct screen memory: Use screen codes with POKE to $0400+offset
62
+ - Tools: `create_petscii_image` returns both `petsciiCodes` array and screen memory data
63
+
64
+ ## Essential PETSCII Symbols
65
+
66
+ | PETSCII | Char | Name | Use |
67
+ |---------|------|------|-----|
68
+ | 32 | (space) | Space | Empty cell |
69
+ | 160 | █ | Full block | Solid fill (reverse space) |
70
+ | 65-90 | A-Z | Uppercase | Text |
71
+ | 193-218 | a-z | Lowercase | Text (shifted mode) |
72
+ | 48-57 | 0-9 | Digits | Numbers |
73
+ | 115 | ♥ | Heart | Decoration, life |
74
+ | 122 | ♦ | Diamond | Suit, decoration |
75
+ | 120 | ♣ | Club | Suit, decoration |
76
+ | 97 | ♠ | Spade | Suit, decoration |
77
+ | 94 | ↑ | Up arrow | Direction, pointer |
78
+ | 95 | ← | Left arrow | Direction |
79
+ | 96 | ─ | Horizontal line | Borders, dividers |
80
+ | 125 | │ | Vertical line | Borders |
81
+ | 117 | ╭ | Arc top-left | Rounded corners |
82
+ | 105 | ╮ | Arc top-right | Rounded corners |
83
+ | 106 | ╰ | Arc bottom-left | Rounded corners |
84
+ | 107 | ╯ | Arc bottom-right | Rounded corners |
85
+ | 123 | ┼ | Cross | Grid intersection |
86
+ | 66-82 | Various | Block fractions | Dithering, gradients |
87
+
88
+ ## Tool Integration
89
+
90
+ ```javascript
91
+ create_petscii_image({
92
+ prompt: "cat",
93
+ borderColor: 0,
94
+ backgroundColor: 6,
95
+ foregroundColor: 1
96
+ })
97
+ ```
98
+
99
+ Returns: `petsciiCodes[]`, `bitmapHex`, `rowHex`, `program`, dimensions
100
+
101
+ ## Related Resources
102
+
103
+ - `c64://specs/charset` - Full PETSCII/screen code mappings
104
+ - `c64://specs/vic` - VIC-II registers, colour RAM
105
+ - `c64://specs/basic` - BASIC screen commands
@@ -0,0 +1,292 @@
1
+ # Sprite and Charset Workflows Best Practices
2
+
3
+ This guide provides proven workflows and best practices for creating, managing, and deploying sprites and custom character sets on the Commodore 64.
4
+
5
+ ## Sprite Workflow Overview
6
+
7
+ Sprites are hardware-accelerated movable graphics objects. Each sprite is 24×21 pixels with support for multicolour or hires modes.
8
+
9
+ ### Basic Sprite Workflow
10
+
11
+ 1. **Design**: Create 24×21 pixel bitmap (monochrome or multicolour)
12
+ 2. **Encode**: Convert to 63-byte sprite data format
13
+ 3. **Upload**: Place sprite data in memory ($0340-$07FF recommended for safety)
14
+ 4. **Configure**: Set sprite pointer, position, colour, and enable flags
15
+ 5. **Verify**: Read screen or sprite registers to confirm appearance
16
+
17
+ ### Sprite Memory Layout
18
+
19
+ Each sprite requires 63 bytes (24×21 pixels / 8 bits per byte):
20
+ - 21 rows of 3 bytes each
21
+ - Bit 1 = pixel on, Bit 0 = pixel off (hires mode)
22
+ - In multicolour mode, 2 bits per pixel define 4 colours
23
+
24
+ ### Sprite Pointer Configuration
25
+
26
+ Sprites are enabled via VIC-II registers:
27
+ - `$D015` - Sprite enable (bits 0-7 for sprites 0-7)
28
+ - `$D010` - Sprite X MSB for horizontal positioning beyond 255
29
+ - `$D000-$D00F` - X/Y coordinates for sprites 0-7
30
+ - `$07F8-$07FF` - Sprite data pointers (screen memory + $03F8)
31
+
32
+ ### Safe Sprite Data Locations
33
+
34
+ Use these memory ranges to avoid conflicts:
35
+ - `$0340-$03FF` - Cassette buffer (192 bytes, safe when not using tape)
36
+ - `$C000-$CFFF` - RAM under BASIC ROM (4KB, requires bank switching)
37
+ - `$2000-$3FFF` - Screen/bitmap alternatives (8KB when not displaying there)
38
+
39
+ ### Sprite Colour Selection
40
+
41
+ - Individual sprite colour: `$D027-$D02E` (one per sprite)
42
+ - Multicolour shared colours: `$D025` (shared 1), `$D026` (shared 2)
43
+ - Background colour: `$D021`
44
+
45
+ Choose high-contrast colours for visibility:
46
+ - White (1) on black (0) background
47
+ - Yellow (7) or cyan (3) for highlights
48
+ - Avoid grey on grey or similar-hue combinations
49
+
50
+ ## Character Set (Charset) Workflow Overview
51
+
52
+ Custom charsets allow you to redefine the 256 character glyphs displayed on screen.
53
+
54
+ ### Basic Charset Workflow
55
+
56
+ 1. **Design**: Create 8×8 pixel bitmaps for each character
57
+ 2. **Encode**: Convert to 8-byte character definitions
58
+ 3. **Upload**: Place charset in 2KB memory block ($2000, $2800, $3000, or $3800)
59
+ 4. **Configure**: Point VIC-II to custom charset via `$D018`
60
+ 5. **Test**: POKE characters to screen and verify appearance
61
+
62
+ ### Character Definition Format
63
+
64
+ Each character uses 8 bytes (8 rows × 8 pixels):
65
+ ```
66
+ Byte 0: Row 0 bitmap (MSB = leftmost pixel)
67
+ Byte 1: Row 1 bitmap
68
+ ...
69
+ Byte 7: Row 7 bitmap
70
+ ```
71
+
72
+ Example: 'A' character
73
+ ```
74
+ 00111100 ($3C) - Row 0
75
+ 01100110 ($66) - Row 1
76
+ 01100110 ($66) - Row 2
77
+ 01111110 ($7E) - Row 3
78
+ 01100110 ($66) - Row 4
79
+ 01100110 ($66) - Row 5
80
+ 01100110 ($66) - Row 6
81
+ 00000000 ($00) - Row 7
82
+ ```
83
+
84
+ ### Charset Memory Alignment
85
+
86
+ Custom charsets must be aligned to 2KB boundaries:
87
+ - `$2000` (8192) - VIC bank 0, offset $0000
88
+ - `$2800` (10240) - VIC bank 0, offset $0800
89
+ - `$3000` (12288) - VIC bank 0, offset $1000
90
+ - `$3800` (14336) - VIC bank 0, offset $1800
91
+
92
+ ### Switching Charsets
93
+
94
+ Configure VIC-II register `$D018`:
95
+ - Bits 1-3 control charset pointer
96
+ - Formula: (charset_address / 2048) << 1
97
+ - Example: For charset at $2000, POKE 53272, (53272 AND 240) OR ((8192/2048) << 1)
98
+
99
+ ### Partial Charset Updates
100
+
101
+ You don't need to redefine all 256 characters:
102
+ - Only redefine characters you actually use
103
+ - Leave standard characters (A-Z, 0-9) unchanged for debugging
104
+ - Focus on block graphics (160-255) for custom effects
105
+
106
+ ## Advanced Techniques
107
+
108
+ ### Sprite Multiplexing
109
+
110
+ **Technical implementation**: Once VIC-II completes drawing a sprite (after scanline Y+21), the same physical sprite can be repositioned and redrawn. This maps one physical sprite definition to multiple logical sprite instances across different scanlines.
111
+
112
+ **Mechanism**:
113
+ - VIC-II fetches sprite data during raster lines Y to Y+20 (21 lines)
114
+ - After line Y+20 completes, sprite registers ($D000-$D00F, $D015, $D027-$D02E) can be modified
115
+ - Same sprite pointer ($07F8-$07FF) reused by updating position/colour for next instance
116
+ - Raster IRQ at Y+21 triggers repositioning code
117
+ - Typical: 20-24 multiplexed sprites achievable with careful timing
118
+
119
+ **Requirements**:
120
+ - Precise raster interrupt timing (see c64://specs/vic)
121
+ - Fast register updates (< 63 cycles between sprite positions)
122
+ - Pre-calculated Y-coordinate tables for performance
123
+
124
+ ### Multicolour vs Hires Sprites
125
+
126
+ **Hires (default)**:
127
+ - 24×21 pixels, one colour per sprite
128
+ - Better detail and sharpness
129
+ - Ideal for detailed characters or objects
130
+
131
+ **Multicolour**:
132
+ - 12×21 effective resolution (2 bits per pixel)
133
+ - 4 colours: background, sprite colour, shared 1, shared 2
134
+ - Better for colourful, less detailed objects
135
+ - Enable via bit in `$D01C`
136
+
137
+ ### Character Animation
138
+
139
+ Animate by rapidly switching between character definitions:
140
+ - Pre-load multiple frames into charset memory
141
+ - Switch displayed character code or charset pointer
142
+ - Use raster interrupts for smooth timing
143
+
144
+ ### Mixed Charset/Bitmap Modes
145
+
146
+ Combine text and graphics:
147
+ - Use charset for UI elements and text
148
+ - Use sprites for player characters and bullets
149
+ - Use bitmap mode for detailed backgrounds
150
+
151
+ ## Performance Considerations
152
+
153
+ ### Sprite Priorities
154
+
155
+ - Sprites 0-7 have priority order (0 = front, 7 = back)
156
+ - Sprite-to-background priority controlled by `$D01B`
157
+ - Sprite-to-sprite collisions detected via `$D01E`
158
+ - Sprite-to-background collisions via `$D01F`
159
+
160
+ ### Memory Bandwidth and VIC-II Cycles
161
+
162
+ **VIC-II "bad lines"** (every 8th raster, lines $30-$F7):
163
+ - VIC-II fetches 40 bytes of screen data + 40 bytes of character data
164
+ - CPU halted for ~40-43 cycles (exact depends on sprite activity)
165
+ - Bad lines occur when lower 3 bits of $D011 match lower 3 bits of raster counter
166
+
167
+ **Sprite DMA cycles**:
168
+ - Each active sprite costs 2 cycles per raster line for data fetch
169
+ - Sprite X-coordinate at DMA fetch point determines if CPU is blocked
170
+ - 8 sprites active: CPU loses 16 cycles per line
171
+ - Sprite display starts at cycle 11-12 of raster line
172
+
173
+ **Border timing and precision**:
174
+ - Upper border: Open at raster $30 by writing $D011 bit 3=0 at cycle 56
175
+ - Lower border: Open at raster $F7 by writing $D011 bit 3=1 at cycle 56
176
+ - Side borders: $D016 bit 3 controls, must write at precise X-coordinate
177
+ - **NOP instruction** ($EA): Used for cycle-exact timing delays in border opening routines
178
+ - Typical pattern: `NOP; NOP; STA $D011` to hit exact cycle 56
179
+
180
+ **CPU availability**:
181
+ - Normal line: ~63 cycles available
182
+ - Bad line + 8 sprites: ~20 cycles available
183
+ - Critical code: Use raster lines outside $30-$F7 range or disable screen ($D011 bit 4=0)
184
+
185
+ ### Charset Performance
186
+
187
+ Custom charsets have minimal performance impact:
188
+ - One-time memory copy during setup
189
+ - No runtime overhead compared to ROM charset
190
+ - Screen updates (POKE to screen memory) are the bottleneck
191
+
192
+ ## Common Pitfalls and Solutions
193
+
194
+ ### Sprite Not Appearing
195
+ 1. Check sprite enable bit in `$D015`
196
+ 2. Verify sprite pointer at `$07F8-$07FF`
197
+ 3. Confirm sprite data is in correct memory location
198
+ 4. Check X/Y coordinates are on screen (0-320, 0-200)
199
+ 5. Verify sprite colour is different from background
200
+
201
+ ### Charset Not Displaying
202
+ 1. Confirm charset is at 2KB boundary
203
+ 2. Check VIC-II bank selection (default is bank 0)
204
+ 3. Verify `$D018` charset pointer bits
205
+ 4. Ensure characters are POKEd to screen memory
206
+ 5. Check that BASIC/KERNAL ROMs aren't blocking access
207
+
208
+ ### Sprite Flicker
209
+ 1. Reduce number of active sprites
210
+ 2. Use sprite multiplexing carefully
211
+ 3. Synchronize updates with raster beam
212
+ 4. Consider double-buffering techniques
213
+
214
+ ### Colour Clashing
215
+ 1. Use PETSCII style guide for colour selection
216
+ 2. Test on both PAL and NTSC if possible
217
+ 3. Maintain sufficient contrast (see c64://docs/petscii-style)
218
+ 4. Avoid adjacent similar-hue colours
219
+
220
+ ## Tool Integration
221
+
222
+ ### Using generate_sprite_prg
223
+
224
+ ```javascript
225
+ {
226
+ spriteData: "base64-encoded-63-bytes",
227
+ x: 160, // Center horizontally
228
+ y: 100, // Center vertically
229
+ colour: 1, // White
230
+ multicolour: false
231
+ }
232
+ ```
233
+
234
+ The tool:
235
+ - Validates 63-byte sprite format
236
+ - Generates BASIC program to display sprite
237
+ - Handles sprite pointer and VIC-II register setup
238
+ - Returns structured metadata for follow-up operations
239
+
240
+ ### Memory Safety
241
+
242
+ When working with sprites and charsets:
243
+ 1. Use memory ranges documented in c64://specs/memory-map
244
+ 2. Avoid BASIC program area ($0801-$9FFF) unless controlling it
245
+ 3. Preserve zero page ($0000-$00FF) and stack ($0100-$01FF)
246
+ 4. Use `read_memory` and `write_memory` tools for safe access
247
+
248
+ ## Example Workflows
249
+
250
+ ### Simple Sprite Display
251
+
252
+ 1. Prepare 24×21 sprite bitmap
253
+ 2. Call `generate_sprite_prg` with sprite data
254
+ 3. Tool returns PRG that sets up sprite automatically
255
+ 4. Use `read_screen` to verify appearance
256
+ 5. Optionally `write_memory` to adjust position/colour
257
+
258
+ ### Custom Charset Installation
259
+
260
+ 1. Design character set (full or partial)
261
+ 2. Encode to 8-byte-per-char format
262
+ 3. Use `write_memory` to copy charset to $2000
263
+ 4. POKE $D018 to point VIC-II at new charset
264
+ 5. Use `upload_and_run_basic` to test character display
265
+ 6. Verify with `read_screen`
266
+
267
+ ### Animated Sprite Sequence
268
+
269
+ 1. Create multiple sprite frames (3-8 frames typical)
270
+ 2. Upload all frames to consecutive memory locations
271
+ 3. Generate BASIC program that cycles sprite pointer
272
+ 4. Use raster timing for smooth animation
273
+ 5. Verify frame timing with `read_memory` checks
274
+
275
+ ## Best Practices Summary
276
+
277
+ 1. **Plan Memory Layout**: Map out sprite and charset locations before coding
278
+ 2. **Test Incrementally**: Display one sprite/char before adding more
279
+ 3. **Use Tools**: Leverage `generate_sprite_prg` and memory tools
280
+ 4. **Document State**: Note which sprites/chars are active
281
+ 5. **Handle Errors**: Check return values and screen output
282
+ 6. **Optimize Last**: Get it working, then optimize if needed
283
+ 7. **Verify Hardware**: Test on real C64 or accurate emulator
284
+ 8. **Read Resources**: Consult c64://specs/vic for register details
285
+
286
+ ## Related Resources
287
+
288
+ - `c64://specs/vic` - Complete VIC-II register reference
289
+ - `c64://specs/charset` - Character code mappings
290
+ - `c64://docs/petscii-style` - Colour and style guidelines
291
+ - `c64://specs/memory-map` - Memory layout and safe ranges
292
+ - `c64://context/bootstrap` - Safety and workflow rules
package/dist/c64Client.js CHANGED
@@ -666,6 +666,7 @@ export class C64Client {
666
666
  /**
667
667
  * Low-level memory read that transparently handles devices returning either
668
668
  * raw binary bytes or JSON with a base64 payload.
669
+ * Public to allow advanced polling and monitoring use cases.
669
670
  */
670
671
  async readMemoryRaw(address, length) {
671
672
  try {
@@ -303,7 +303,7 @@ export function createPromptRegistry() {
303
303
  "c64://specs/sid",
304
304
  "c64://context/bootstrap",
305
305
  ],
306
- optionalResources: [],
306
+ optionalResources: ["c64://docs/sid/best-practices"],
307
307
  tools: ["upload_and_run_asm", "write_memory", "read_memory", "read_screen"],
308
308
  tags: ["assembly", "program"],
309
309
  },
@@ -315,6 +315,13 @@ export function createPromptRegistry() {
315
315
  },
316
316
  ],
317
317
  prepareArgs: prepareAssemblyArgs,
318
+ selectOptionalResources: (args) => {
319
+ const hardware = args.hardware;
320
+ if (hardware === "sid" || hardware === "multi") {
321
+ return ["c64://docs/sid/best-practices"];
322
+ }
323
+ return [];
324
+ },
318
325
  buildMessages: (args) => {
319
326
  const hardware = args.hardware;
320
327
  return [
@@ -335,6 +342,7 @@ export function createPromptRegistry() {
335
342
  "c64://specs/sid",
336
343
  "c64://specs/sidwave",
337
344
  "c64://docs/sid/file-structure",
345
+ "c64://docs/sid/best-practices",
338
346
  ],
339
347
  optionalResources: [],
340
348
  tools: ["music_generate", "analyze_audio", "sid_note_on", "sid_volume", "sidplay_file"],
@@ -356,7 +364,7 @@ export function createPromptRegistry() {
356
364
  "c64://specs/vic",
357
365
  "c64://context/bootstrap",
358
366
  ],
359
- optionalResources: ["c64://specs/assembly"],
367
+ optionalResources: ["c64://specs/assembly", "c64://specs/charset", "c64://docs/petscii-style"],
360
368
  tools: ["upload_and_run_basic", "upload_and_run_asm", "render_petscii_screen"],
361
369
  tags: ["graphics", "vic"],
362
370
  },
@@ -1,5 +1,37 @@
1
1
  import { readFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
+ function generateCharsetQuickref() {
4
+ const csvPath = join(process.cwd(), "data/video/character-set.csv");
5
+ const csvContent = readFileSync(csvPath, "utf-8");
6
+ const lines = csvContent.trim().split("\n");
7
+ const headers = lines[0].split(",");
8
+ let markdown = "# PETSCII Character Set Reference\n\n";
9
+ markdown += "Complete reference of C64 character codes, screen codes, and glyphs.\n\n";
10
+ markdown += "## Character Code Table\n\n";
11
+ markdown += "| Screen Code | PETSCII | Char | Name | Keyboard |\n";
12
+ markdown += "|-------------|---------|------|------|----------|\n";
13
+ for (let i = 1; i < lines.length; i++) {
14
+ const parts = lines[i].split(",");
15
+ if (parts.length < 8)
16
+ continue;
17
+ const screenCode = parts[0];
18
+ const petsciiCode = parts[2];
19
+ const char = parts[4] || " ";
20
+ const name = parts[6] || "";
21
+ const keyboard = parts[7] || "";
22
+ markdown += `| ${screenCode} | ${petsciiCode} | ${char} | ${name} | ${keyboard} |\n`;
23
+ }
24
+ markdown += "\n## Usage Notes\n\n";
25
+ markdown += "- **Screen Code**: Value used in screen memory ($0400-$07E7)\n";
26
+ markdown += "- **PETSCII Code**: Value used in BASIC strings and CHR$() function\n";
27
+ markdown += "- **Keyboard**: Key combination to type the character\n";
28
+ markdown += "\n## Common Patterns\n\n";
29
+ markdown += "- Uppercase letters: PETSCII $41-$5A (A-Z)\n";
30
+ markdown += "- Lowercase letters: PETSCII $61-$7A (a-z) in graphics mode\n";
31
+ markdown += "- Digits: PETSCII $30-$39 (0-9)\n";
32
+ markdown += "- Graphics characters: Screen codes $60-$7F and $E0-$FF\n";
33
+ return markdown;
34
+ }
3
35
  const KNOWLEDGE_BUNDLES = [
4
36
  {
5
37
  id: "orientation",
@@ -37,9 +69,21 @@ const KNOWLEDGE_BUNDLES = [
37
69
  summary: "Token definitions, syntax rules, and device I/O guidance for BASIC v2.",
38
70
  prompts: ["basic-program"],
39
71
  tools: ["upload_and_run_basic", "read_screen"],
40
- relatedResources: ["c64://context/bootstrap"],
72
+ relatedResources: ["c64://context/bootstrap", "c64://docs/basic/pitfalls"],
41
73
  tags: ["basic", "language"],
42
74
  },
75
+ {
76
+ uri: "c64://docs/basic/pitfalls",
77
+ name: "BASIC Pitfalls & Gotchas",
78
+ description: "Common mistakes and gotchas when writing Commodore BASIC v2 programs",
79
+ relativePath: "data/basic/basic-pitfalls.md",
80
+ priority: "reference",
81
+ summary: "Quickref covering quotation handling, line length, tokenization, variable names, and other BASIC traps.",
82
+ prompts: ["basic-program"],
83
+ tools: ["upload_and_run_basic"],
84
+ relatedResources: ["c64://specs/basic"],
85
+ tags: ["basic", "pitfalls", "quickref"],
86
+ },
43
87
  {
44
88
  uri: "c64://specs/assembly",
45
89
  name: "6502/6510 Assembly Reference",
@@ -127,9 +171,45 @@ const KNOWLEDGE_BUNDLES = [
127
171
  summary: "Covers raster timing, sprite control, colour RAM, and bitmap modes on the VIC-II.",
128
172
  prompts: ["graphics-demo"],
129
173
  tools: ["render_petscii_screen", "generate_sprite_prg", "write_memory"],
130
- relatedResources: ["c64://specs/assembly"],
174
+ relatedResources: ["c64://specs/assembly", "c64://specs/charset", "c64://docs/petscii-style"],
131
175
  tags: ["vic", "graphics"],
132
176
  },
177
+ {
178
+ uri: "c64://specs/charset",
179
+ name: "PETSCII Character Set Reference",
180
+ description: "Complete PETSCII character codes, screen codes, and glyph mappings",
181
+ relativePath: "data/video/character-set.csv",
182
+ priority: "reference",
183
+ summary: "Character code table mapping PETSCII codes to screen codes, glyphs, and keyboard input.",
184
+ prompts: ["graphics-demo"],
185
+ tools: ["render_petscii_screen", "create_petscii_image"],
186
+ relatedResources: ["c64://specs/vic", "c64://docs/petscii-style"],
187
+ tags: ["petscii", "charset", "graphics"],
188
+ },
189
+ {
190
+ uri: "c64://docs/petscii-style",
191
+ name: "PETSCII Style Guide and Presets",
192
+ description: "Colour combinations, contrast guidelines, and recommended presets for PETSCII art",
193
+ relativePath: "data/video/petscii-style-guide.md",
194
+ priority: "reference",
195
+ summary: "Documents colour palette, readability presets, dithering patterns, and best practices for creating artistic and readable PETSCII displays.",
196
+ prompts: ["graphics-demo"],
197
+ tools: ["create_petscii_image", "render_petscii_screen"],
198
+ relatedResources: ["c64://specs/vic", "c64://specs/charset", "c64://docs/sprite-charset-workflows"],
199
+ tags: ["petscii", "style", "colours", "graphics"],
200
+ },
201
+ {
202
+ uri: "c64://docs/sprite-charset-workflows",
203
+ name: "Sprite & Charset Workflows Best Practices",
204
+ description: "Comprehensive guide to creating, managing, and deploying sprites and custom character sets",
205
+ relativePath: "data/video/sprite-charset-best-practices.md",
206
+ priority: "reference",
207
+ summary: "Documents sprite and charset workflows, memory layout, VIC-II configuration, common pitfalls, and proven techniques for hardware-accelerated graphics.",
208
+ prompts: ["graphics-demo"],
209
+ tools: ["generate_sprite_prg", "write_memory", "read_memory", "upload_and_run_basic"],
210
+ relatedResources: ["c64://specs/vic", "c64://specs/charset", "c64://docs/petscii-style", "c64://specs/memory-map"],
211
+ tags: ["sprites", "charset", "graphics", "workflows"],
212
+ },
133
213
  ],
134
214
  },
135
215
  {
@@ -326,29 +406,36 @@ const KNOWLEDGE_BUNDLES = [
326
406
  ],
327
407
  },
328
408
  ];
329
- const BASE_RESOURCES = KNOWLEDGE_BUNDLES.flatMap((bundle, bundleIndex) => bundle.resources.map((resource, resourceIndex) => ({
330
- uri: resource.uri,
331
- name: resource.name,
332
- description: resource.description,
333
- mimeType: "text/markdown",
334
- relativePath: resource.relativePath,
335
- metadata: {
336
- domain: bundle.id,
337
- priority: resource.priority,
338
- summary: resource.summary,
339
- prompts: resource.prompts,
340
- tools: resource.tools,
341
- tags: resource.tags ?? [],
342
- bundle: {
343
- id: bundle.id,
344
- title: bundle.title,
345
- summary: bundle.summary,
346
- order: bundleIndex,
409
+ const BASE_RESOURCES = KNOWLEDGE_BUNDLES.flatMap((bundle, bundleIndex) => bundle.resources.map((resource, resourceIndex) => {
410
+ const baseResource = {
411
+ uri: resource.uri,
412
+ name: resource.name,
413
+ description: resource.description,
414
+ mimeType: "text/markdown",
415
+ relativePath: resource.relativePath,
416
+ metadata: {
417
+ domain: bundle.id,
418
+ priority: resource.priority,
419
+ summary: resource.summary,
420
+ prompts: resource.prompts,
421
+ tools: resource.tools,
422
+ tags: resource.tags ?? [],
423
+ bundle: {
424
+ id: bundle.id,
425
+ title: bundle.title,
426
+ summary: bundle.summary,
427
+ order: bundleIndex,
428
+ },
429
+ order: resourceIndex,
430
+ relatedResources: resource.relatedResources ?? [],
347
431
  },
348
- order: resourceIndex,
349
- relatedResources: resource.relatedResources ?? [],
350
- },
351
- })));
432
+ };
433
+ // Add buildContent for resources that need dynamic generation
434
+ if (resource.uri === "c64://specs/charset") {
435
+ return { ...baseResource, buildContent: generateCharsetQuickref };
436
+ }
437
+ return baseResource;
438
+ }));
352
439
  const INDEX_RESOURCE = {
353
440
  uri: "c64://docs/index",
354
441
  name: "C64 Knowledge Map",