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.
- package/README.md +17 -5
- package/data/assembly/assembly-spec.md +24 -0
- package/data/assembly/examples/video/hello_world.asm +39 -0
- package/data/basic/basic-pitfalls.md +236 -0
- package/data/basic/basic-spec.md +507 -198
- package/data/video/petscii-style-guide.md +105 -0
- package/data/video/sprite-charset-best-practices.md +292 -0
- package/dist/c64Client.js +1 -0
- package/dist/prompts/registry.js +10 -2
- package/dist/rag/knowledgeIndex.js +111 -24
- package/dist/rag/retriever.js +110 -4
- package/dist/tools/audio.js +26 -13
- package/dist/tools/developer.js +34 -0
- package/dist/tools/graphics.js +6 -5
- package/dist/tools/memory.js +1 -1
- package/dist/tools/pollValidator.js +256 -0
- package/dist/tools/programRunners.js +352 -12
- package/dist/tools/rag.js +1 -7
- package/doc/MCP_SETUP.md +7 -1
- package/doc/bun/baseline-metrics.md +16 -0
- package/doc/bun/migration-checklist.md +55 -0
- package/doc/bun/migration.md +83 -0
- package/doc/developer.md +72 -10
- package/doc/improve-knowledge/notes.md +29 -0
- package/doc/improve-knowledge/plan.md +28 -3
- package/doc/improve-knowledge/rollout.md +39 -5
- package/doc/meta-tools/README.md +101 -0
- package/doc/meta-tools/analysis.md +255 -0
- package/doc/{meta-tools.md → meta-tools/catalog.md} +2 -2
- package/doc/meta-tools/notes.md +174 -0
- package/doc/meta-tools/rollout.md +343 -0
- package/mcp.json +1 -1
- package/package.json +17 -10
- package/scripts/c64-cli.mjs +42 -7
- package/scripts/c64-tool.sh +7 -1
- package/scripts/check-node-compat.mjs +107 -0
- package/scripts/invoke-bun.mjs +58 -0
- package/scripts/rag-rebuild.mjs +11 -13
- package/scripts/run-mcp-check.sh +10 -2
- package/scripts/run-tests.mjs +3 -3
- package/scripts/run-tests.ts +187 -0
- package/scripts/start.mjs +3 -26
- package/scripts/update-readme.ts +17 -1
- package/scripts/verify-package.mjs +0 -1
- package/data/assembly/examples/effects/sinewave.asm +0 -5
- package/doc/meta-tools-rollout.md +0 -211
- package/scripts/register-ts-node.mjs +0 -6
- /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 {
|
package/dist/prompts/registry.js
CHANGED
|
@@ -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
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
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
|
-
|
|
349
|
-
|
|
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",
|