c64bridge 0.5.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 (138) hide show
  1. package/.github/prompts/README.md +6 -0
  2. package/.github/prompts/assembly-routine-session.prompt.md +13 -0
  3. package/.github/prompts/basic-program-session.prompt.md +13 -0
  4. package/.github/prompts/drive-management-session.prompt.md +13 -0
  5. package/.github/prompts/petscii-art-session.prompt.md +13 -0
  6. package/.github/prompts/play-classic-game.prompt.md +13 -0
  7. package/.github/prompts/sid-music-session.prompt.md +13 -0
  8. package/AGENTS.md +173 -0
  9. package/LICENSE +339 -0
  10. package/README.md +582 -0
  11. package/data/README.md +16 -0
  12. package/data/api/basic-api-spec.md +154 -0
  13. package/data/api/kernal-api-spec.md +68 -0
  14. package/data/assembly/assembly-spec.md +196 -0
  15. package/data/assembly/examples/effects/sinewave.asm +5 -0
  16. package/data/assembly/examples/graphics/sprite/mover.asm +15 -0
  17. package/data/assembly/examples/sid-file-structure.md +8 -0
  18. package/data/assembly/examples/sid-overview.md +11 -0
  19. package/data/audio/examples/Biosphere.sid +0 -0
  20. package/data/audio/sid-file-structure.md +91 -0
  21. package/data/audio/sid-programming-best-practices.md +198 -0
  22. package/data/audio/sid-spec.md +166 -0
  23. package/data/audio/sidwave.md +131 -0
  24. package/data/audio/sidwave.schema.json +64 -0
  25. package/data/basic/basic-spec.md +230 -0
  26. package/data/basic/examples/audio/alle-meine-entchen-expressive.bas +41 -0
  27. package/data/basic/examples/audio/c-major-scale-pleasant.bas +29 -0
  28. package/data/basic/examples/io/joystick.bas +5 -0
  29. package/data/basic/examples/video/bounce.bas +8 -0
  30. package/data/basic/examples/video/entchen-petscii.bas +16 -0
  31. package/data/basic/examples/video/hello-world.bas +4 -0
  32. package/data/basic/examples/video/wave.bas +7 -0
  33. package/data/context/bootstrap.md +148 -0
  34. package/data/context/chat.md +36 -0
  35. package/data/drive/drive-spec.md +215 -0
  36. package/data/embeddings_asm.json +1 -0
  37. package/data/embeddings_basic.json +1 -0
  38. package/data/embeddings_hardware.json +1 -0
  39. package/data/embeddings_mixed.json +1 -0
  40. package/data/embeddings_other.json +1 -0
  41. package/data/io/cia-spec.md +115 -0
  42. package/data/io/io-spec.md +124 -0
  43. package/data/memory/kernal-memory-map.md +227 -0
  44. package/data/memory/low-memory-map.md +133 -0
  45. package/data/memory/memory-map.md +186 -0
  46. package/data/printer/printer-commodore-bitmap.md +31 -0
  47. package/data/printer/printer-commodore.md +28 -0
  48. package/data/printer/printer-epson-bitmap.md +29 -0
  49. package/data/printer/printer-epson.md +30 -0
  50. package/data/printer/printer-prompts.md +29 -0
  51. package/data/printer/printer-spec.md +180 -0
  52. package/data/video/character-set.csv +257 -0
  53. package/data/video/vic-spec.md +276 -0
  54. package/dist/assemblyConverter.js +1299 -0
  55. package/dist/audio/record_and_analyze_audio.js +292 -0
  56. package/dist/basicConverter.js +193 -0
  57. package/dist/bootstrap/stdio-logger.js +32 -0
  58. package/dist/c64Client.js +1052 -0
  59. package/dist/chargen.js +197 -0
  60. package/dist/config.js +142 -0
  61. package/dist/context.js +157 -0
  62. package/dist/device.js +413 -0
  63. package/dist/index.js +7 -0
  64. package/dist/knowledge.js +454 -0
  65. package/dist/logger.js +182 -0
  66. package/dist/loggingHttpClient.js +88 -0
  67. package/dist/mcp-server.js +426 -0
  68. package/dist/petscii.js +135 -0
  69. package/dist/petsciiArt.js +356 -0
  70. package/dist/platform.js +82 -0
  71. package/dist/prompts/registry.js +560 -0
  72. package/dist/rag/discover.config.json +41 -0
  73. package/dist/rag/discover.js +401 -0
  74. package/dist/rag/embeddings.js +60 -0
  75. package/dist/rag/externalFetcher.js +934 -0
  76. package/dist/rag/indexer.js +770 -0
  77. package/dist/rag/init.js +139 -0
  78. package/dist/rag/knowledgeIndex.js +361 -0
  79. package/dist/rag/loggingRetriever.js +46 -0
  80. package/dist/rag/rateLimiter.js +127 -0
  81. package/dist/rag/retriever.js +74 -0
  82. package/dist/rag/sources.csv +31 -0
  83. package/dist/rag/types.js +5 -0
  84. package/dist/rag/urlUtils.js +38 -0
  85. package/dist/sidplayRunner.js +240 -0
  86. package/dist/sidwave.js +101 -0
  87. package/dist/sidwaveCompiler.js +329 -0
  88. package/dist/tools/audio.js +944 -0
  89. package/dist/tools/developer.js +515 -0
  90. package/dist/tools/errors.js +59 -0
  91. package/dist/tools/graphics.js +469 -0
  92. package/dist/tools/machineControl.js +267 -0
  93. package/dist/tools/memory.js +224 -0
  94. package/dist/tools/printer.js +482 -0
  95. package/dist/tools/programRunners.js +315 -0
  96. package/dist/tools/rag.js +153 -0
  97. package/dist/tools/registry.js +58 -0
  98. package/dist/tools/responses.js +36 -0
  99. package/dist/tools/schema.js +304 -0
  100. package/dist/tools/storage.js +740 -0
  101. package/dist/tools/streaming.js +132 -0
  102. package/dist/tools/types.js +99 -0
  103. package/dist/viceRunner.js +239 -0
  104. package/doc/MCP_SETUP.md +153 -0
  105. package/doc/README.md +7 -0
  106. package/doc/developer.md +312 -0
  107. package/doc/img/logo.png +0 -0
  108. package/doc/img/prompts/duck_petscii.png +0 -0
  109. package/doc/img/prompts/duck_song.png +0 -0
  110. package/doc/img/vscode/vscode-copilot-c64-chat-mode.png +0 -0
  111. package/doc/img/vscode/vscode-copilot-hello-world.png +0 -0
  112. package/doc/prompts/README.md +96 -0
  113. package/doc/prompts/user-prompt-ideas.md +147 -0
  114. package/doc/rest/c64-openapi.yaml +979 -0
  115. package/doc/rest/c64-rest-api.md +106 -0
  116. package/doc/troubleshooting-mcp.md +177 -0
  117. package/generated/c64/index.js +857 -0
  118. package/mcp.json +106 -0
  119. package/package.json +79 -0
  120. package/scripts/c64-cli.mjs +142 -0
  121. package/scripts/c64-tool.sh +83 -0
  122. package/scripts/check-package.mjs +89 -0
  123. package/scripts/cli.js +61 -0
  124. package/scripts/fetch-external-sources.mjs +67 -0
  125. package/scripts/generate-changelog.mjs +131 -0
  126. package/scripts/postbuild.mjs +101 -0
  127. package/scripts/prepare-release.mjs +58 -0
  128. package/scripts/rag-rebuild.mjs +53 -0
  129. package/scripts/register-ts-node.mjs +6 -0
  130. package/scripts/run-mcp-check.sh +104 -0
  131. package/scripts/run-tests.mjs +195 -0
  132. package/scripts/sid2wav.sh +94 -0
  133. package/scripts/smoke-run.sh +65 -0
  134. package/scripts/start-mock-c64.mjs +51 -0
  135. package/scripts/start-mock.mjs +31 -0
  136. package/scripts/start.mjs +72 -0
  137. package/scripts/update-readme.ts +164 -0
  138. package/scripts/verify-package.mjs +147 -0
@@ -0,0 +1,198 @@
1
+ # SID Programming Best Practices - Perfect Scale Generation
2
+
3
+ ## Overview
4
+
5
+ This document captures the successful approach for creating pleasant, musical SID sounds on the Commodore 64, discovered through iterative testing with the MCP server and real hardware feedback.
6
+
7
+ ## Sample Programs
8
+
9
+ ### Play C Major Scale with Basic
10
+
11
+ ```basic
12
+ 10 POKE 54296,15:REM VOLUME
13
+ 20 POKE 54277,17:POKE 54278,240:REM FAST ATTACK, SLOW RELEASE
14
+ 30 REM LOWER C MAJOR SCALE WITH TRIANGLE WAVE
15
+ 40 POKE 54273,30:POKE 54274,0:POKE 54276,17:FOR I=1 TO 3000:NEXT I:POKE 54276,16:FOR I=1 TO 500:NEXT I
16
+ 50 POKE 54273,34:POKE 54274,0:POKE 54276,17:FOR I=1 TO 3000:NEXT I:POKE 54276,16:FOR I=1 TO 500:NEXT I
17
+ 60 POKE 54273,38:POKE 54274,0:POKE 54276,17:FOR I=1 TO 3000:NEXT I:POKE 54276,16:FOR I=1 TO 500:NEXT I
18
+ 70 POKE 54273,40:POKE 54274,0:POKE 54276,17:FOR I=1 TO 3000:NEXT I:POKE 54276,16:FOR I=1 TO 500:NEXT I
19
+ 80 POKE 54273,45:POKE 54274,0:POKE 54276,17:FOR I=1 TO 3000:NEXT I:POKE 54276,16:FOR I=1 TO 500:NEXT I
20
+ 90 POKE 54273,51:POKE 54274,0:POKE 54276,17:FOR I=1 TO 3000:NEXT I:POKE 54276,16:FOR I=1 TO 500:NEXT I
21
+ 100 POKE 54273,57:POKE 54274,0:POKE 54276,17:FOR I=1 TO 3000:NEXT I:POKE 54276,16:FOR I=1 TO 500:NEXT I
22
+ 110 POKE 54273,60:POKE 54274,0:POKE 54276,17:FOR I=1 TO 3000:NEXT I:POKE 54276,16
23
+ 120 POKE 54276,0:PRINT "SMOOTH SCALE DONE"
24
+ ```
25
+
26
+ ## Key Success Factors
27
+
28
+ ### 1. Ultra-Low Frequencies
29
+
30
+ - **Critical Discovery**: The standard frequency tables from documentation are too high for pleasant listening
31
+ - **Working Range**: Use frequencies around 30-60 for the low byte, 0 for high byte
32
+ - **Result**: Produces warm, bass-like tones instead of harsh, screechy sounds
33
+
34
+ ### 2. Triangle Wave Instead of Pulse
35
+
36
+ - **Register 54276**: Use value `17` (triangle wave + GATE) instead of `33` (pulse wave + GATE)
37
+ - **Benefit**: Triangle waves are much smoother and more musical than pulse waves
38
+ - **Off State**: Use `16` (triangle wave, no GATE) to properly release notes
39
+
40
+ ### 3. Proper ADSR Envelope
41
+
42
+ - **Attack/Decay (54277)**: `17` = fast attack (1), slow decay (7)
43
+ - **Sustain/Release (54278)**: `240` = high sustain (15), no release (0)
44
+ - **Effect**: Creates natural-sounding note onset and sustain
45
+
46
+ ### 4. Timing is Everything
47
+
48
+ - **Note Duration**: 3000 cycles provides proper sustain (~1.5 seconds)
49
+ - **Pause Duration**: 500 cycles between notes for clear separation
50
+ - **GATE Control**: Keep GATE on during entire note, then turn off cleanly
51
+
52
+ ### 5. Musical Expression and Phrasing
53
+
54
+ - **Varied Note Lengths**: Don't make all notes the same duration - create rhythm and emphasis
55
+ - **Phrase Breathing**: Use longer pauses between musical phrases (150-200 cycles)
56
+ - **Dynamic Emphasis**: Emphasize important notes (phrase beginnings/endings) with longer durations
57
+ - **Narrative Flow**: Each phrase should have its own character and emotional arc
58
+ - **Quick Passages**: Use shorter notes (140-180 cycles) for rapid, flowing sections
59
+ - **Sustained Endings**: Use longer notes (400-600 cycles) for phrase climaxes and endings
60
+
61
+ ## Technical Analysis
62
+
63
+ ### Frequency Values Used
64
+
65
+ ```text
66
+ Note | Low Byte | High Byte | Estimated Hz
67
+ -----|----------|-----------|-------------
68
+ C | 30 | 0 | ~50 Hz
69
+ D | 34 | 0 | ~57 Hz
70
+ E | 38 | 0 | ~63 Hz
71
+ F | 40 | 0 | ~67 Hz
72
+ G | 45 | 0 | ~75 Hz
73
+ A | 51 | 0 | ~85 Hz
74
+ B | 57 | 0 | ~95 Hz
75
+ C | 60 | 0 | ~100 Hz
76
+ ```
77
+
78
+ ### Register Settings
79
+
80
+ ```text
81
+ 54296 (Volume): 15 (maximum)
82
+ 54277 (AD): 17 (attack=1, decay=7)
83
+ 54278 (SR): 240 (sustain=15, release=0)
84
+ 54273 (Freq Lo): Variable per note
85
+ 54274 (Freq Hi): 0 (always)
86
+ 54276 (Control): 17 (triangle+gate) / 16 (triangle only)
87
+ ```
88
+
89
+ ## Common Pitfalls to Avoid
90
+
91
+ ### 1. Using Documentation Frequencies Directly
92
+
93
+ - Standard frequency tables (C4=261Hz → 0x113E) produce harsh, unpleasant sounds
94
+ - These frequencies are mathematically correct but not musically pleasant for listening
95
+
96
+ ### 2. Pulse Wave Without Proper Setup
97
+
98
+ - Pulse waves require careful pulse width settings
99
+ - Triangle waves are much more forgiving and musical
100
+
101
+ ### 3. Inadequate ADSR Settings
102
+
103
+ - Without proper envelope, notes sound like short clicks
104
+ - Fast attack + slow decay + high sustain = musical notes
105
+
106
+ ### 4. Poor GATE Timing
107
+
108
+ - GATE must stay on during the entire note duration
109
+ - Turning GATE off too early creates click-like sounds
110
+
111
+ ## Testing Methodology
112
+
113
+ This solution was developed through:
114
+
115
+ 1. **Real Hardware Testing**: Used actual C64 Ultimate with MCP server
116
+ 2. **Iterative Refinement**: Multiple attempts with frequency adjustments
117
+ 3. **Audio Feedback**: Human verification of pleasant vs. harsh sounds
118
+ 4. **Systematic Debugging**: Isolated individual notes before building full scale
119
+
120
+ ## MCP Server Integration
121
+
122
+ ### Upload Command
123
+
124
+ > [!NOTE]
125
+ > These curl commands require the optional legacy HTTP bridge. Start it manually before using them; the day-to-day workflow runs over MCP stdio.
126
+
127
+ ```bash
128
+ curl -X POST -H 'Content-Type: application/json' \
129
+ -d '{"program": "... BASIC program ..."}' \
130
+ http://localhost:8000/tools/upload_and_run_basic
131
+ ```
132
+
133
+ ### Future Audio Analysis
134
+
135
+ The working scale can now be used with the `analyze_audio` tool:
136
+
137
+ ```bash
138
+ curl -X POST -H 'Content-Type: application/json' \
139
+ -d '{"request": "verify the scale sounds correct"}' \
140
+ http://localhost:8000/tools/analyze_audio
141
+ ```
142
+
143
+ ## Musical Expression Example: "Alle meine Entchen"
144
+
145
+ The following example demonstrates how to create a musically expressive children's song using varied timing and proper phrasing. This serves as a template for writing engaging melodies.
146
+
147
+ ### Key Musical Programming Principles
148
+
149
+ 1. **Opening Emphasis**: First note gets longer duration (250 cycles) to establish the song
150
+ 2. **Flowing Middle**: Quick notes (180 cycles) for melodic flow
151
+ 3. **Phrase Endings**: Extended notes (400-600 cycles) at the end of each phrase
152
+ 4. **Breathing Space**: Longer pauses (150-200 cycles) between phrases
153
+ 5. **Character Variation**: Each verse has its own timing character:
154
+ - "Swimming" = light, quick notes (160 cycles)
155
+ - "Diving" = very short, rapid notes (140 cycles)
156
+ - "Triumphant ending" = building emphasis
157
+
158
+ ### Example Implementation
159
+
160
+ ```basic
161
+ REM ALLE MEINE ENTCHEN - MUSICAL PHRASING
162
+ POKE 54296,15:POKE 54277,17:POKE 54278,240
163
+
164
+ REM OPENING PHRASE - emphasis on first note
165
+ POKE 54273,30:POKE 54274,0:POKE 54276,17:FOR I=1 TO 250:NEXT I:POKE 54276,16:FOR I=1 TO 40:NEXT I
166
+ POKE 54273,34:POKE 54274,0:POKE 54276,17:FOR I=1 TO 180:NEXT I:POKE 54276,16:FOR I=1 TO 40:NEXT I
167
+ REM ... continued with varied timing for musical expression
168
+ ```
169
+
170
+ **Complete example**: See `data/basic/examples/audio/alle-meine-entchen-expressive.bas`
171
+
172
+ ### Timing Patterns for Different Musical Effects
173
+
174
+ - **Emphasis/Importance**: 250-400+ cycles
175
+ - **Normal melody notes**: 180-200 cycles
176
+ - **Quick/flowing passages**: 140-160 cycles
177
+ - **Short pauses**: 25-40 cycles
178
+ - **Phrase breathing**: 120-200 cycles
179
+ - **Dramatic pauses**: 150-250 cycles
180
+
181
+ ## Conclusion
182
+
183
+ The key insight is that **musical programming requires human feedback**, not just technical accuracy. The "correct" mathematical frequencies from documentation don't necessarily produce the most pleasant musical experience. This approach prioritizes:
184
+
185
+ 1. **Listenability** over technical accuracy
186
+ 2. **Smooth waveforms** (triangle) over complex ones (pulse)
187
+ 3. **Proper envelopes** for musical note shaping
188
+ 4. **Musical expression** through varied timing and phrasing
189
+ 5. **Real hardware testing** to validate results
190
+
191
+ **For Children's Songs and Simple Melodies**: Use the expressive timing patterns demonstrated in "Alle meine Entchen" to create engaging, musical compositions that tell a story rather than just playing notes mechanically.
192
+
193
+ This methodology can be applied to create more complex musical compositions while maintaining the warm, pleasant character achieved in this scale progression.
194
+
195
+ ---
196
+
197
+ *Document created: December 2024*
198
+ *Based on successful MCP server + C64 Ultimate testing session*
@@ -0,0 +1,166 @@
1
+ # Commodore 64 SID (MOS 6581 / 8580) — Concise Technical Overview
2
+
3
+ ## Overview
4
+
5
+ - **Voices:** 3 independent oscillators
6
+ Each has: 16-bit frequency, waveform select (triangle / saw / pulse / noise), pulse-width, ADSR envelope, optional SYNC and RING-MOD.
7
+ - **Global:** Analog multimode filter (LP / BP / HP), resonance, master volume, and read-back registers for OSC3 and ENV3.
8
+ - **Models:** 6581 (original, “warmer”, nonlinear filter) and 8580 (revised, linear filter, lower noise).
9
+
10
+ ---
11
+
12
+ ## Register Map (base = $D400 / 54272)
13
+
14
+ **Per Voice (1 – 3):**
15
+
16
+ | Function | Voice 1 | Voice 2 | Voice 3 | Bits / Notes |
17
+ |-----------|----------|----------|----------|--------------|
18
+ | Frequency LO | $D400 | $D407 | $D40E | Low byte of 16-bit pitch increment |
19
+ | Frequency HI | $D401 | $D408 | $D40F | High byte |
20
+ | Pulse Width LO | $D402 | $D409 | $D410 | 12-bit value (0-4095) |
21
+ | Pulse Width HI | $D403 | $D40A | $D411 | Upper 4 bits used |
22
+ | Control | $D404 | $D40B | $D412 | **7..0 = NOISE PULSE SAW TRI TEST RING SYNC GATE** |
23
+ | AD | $D405 | $D40C | $D413 | Attack/Decay nibbles |
24
+ | SR | $D406 | $D40D | $D414 | Sustain/Release nibbles |
25
+
26
+ **Global:**
27
+
28
+ | Function | Address | Description |
29
+ |-----------|----------|-------------|
30
+ | Cutoff LO | $D415 | Lower 8 bits of filter cutoff |
31
+ | Cutoff HI | $D416 | Upper 3 bits of cutoff |
32
+ | Res/Routing | $D417 | 7..4 = resonance (0–15); 3..0 = route Ext,V3,V2,V1 into filter |
33
+ | Mode/Volume | $D418 | 0..3 = master vol (0–15); 4..6 = LP/BP/HP; 7 = CH3 off |
34
+ | Read-backs | $D419–$D41C | POTX, POTY, OSC3, ENV3 |
35
+
36
+ ---
37
+
38
+ ## Note → SID Frequency
39
+
40
+ ```
41
+ FREQ = round( note_hz * 2^24 / φ2 ) >> 8 ; 16-bit register value
42
+ ```
43
+
44
+ - φ₂ = system clock
45
+ - PAL = 985 248 Hz
46
+ - NTSC = 1 022 727 Hz
47
+ - Store FREQ (low/high) into FREQLO/HI.
48
+ - Typical usage: lookup table per note/octave.
49
+
50
+ **Example (PAL):**
51
+
52
+ ```
53
+ FREQ16 = round( (note_hz * 16777216) / 985248 ) >> 8
54
+ ```
55
+
56
+ ---
57
+
58
+ ## Basic Play / Stop Sequence
59
+
60
+ 1. Set FREQ, PW, AD/SR.
61
+ 2. Write CTRL = waveform bits | GATE (=1) → start note.
62
+ 3. Clear GATE bit to release note.
63
+
64
+ ---
65
+
66
+ ## Waveforms & Pulse Width
67
+
68
+ - **Waveform bits:** Triangle = bit 4, Saw = 5, Pulse = 6, Noise = 7.
69
+ - **Pulse Width:** 12-bit ($000–$FFF); $0800 ≈ 50 % duty.
70
+ - Combining waveform bits produces nonlinear mixed timbres.
71
+ - PWM = vary pulse-width in real time.
72
+
73
+ ---
74
+
75
+ ## Filter Block
76
+
77
+ - **Cutoff:** $D415 + $D416 (11 bits).
78
+ - **Resonance / Routing:** $D417.
79
+ - **Mode / Volume:** $D418 → LP/BP/HP bits + master volume.
80
+ - **Differences:** 6581 = nonlinear; 8580 = more accurate.
81
+
82
+ ---
83
+
84
+ ## Famous Effects
85
+
86
+ **Arpeggio** – Cycle chord intervals (e.g. 0,+4,+7) each tick by rewriting FREQ.
87
+ **Vibrato** – Small sinusoidal offset of FREQ each tick (software LFO).
88
+ **PWM** – Periodic variation of pulse-width for animated tone.
89
+ **Filter Sweep** – Ramp cutoff ($D415/$D416) and/or resonance ($D417).
90
+ **Hard Restart** – Clear GATE early, optionally TEST=1 to reset osc; next tick set ADSR + GATE=1 for tight attack.
91
+ **Sync / Ring-Mod** – Enable SYNC or RING bits in CTRL to tie oscillators.
92
+ **Digi Playback** – Rapid writes to $D418 volume simulate 4-bit PCM DAC (~4–8 kHz).
93
+
94
+ ---
95
+
96
+ ## Reset Tips
97
+
98
+ Write $FF then $00 to all SID registers on init to clear stale state before loading new instrument settings.
99
+
100
+ ---
101
+
102
+ ## Alternative Exact Frequency Formulas
103
+
104
+ ```
105
+ PAL: x = f * (18 * 2^24) / 17734475
106
+ NTSC: x = f * (14 * 2^24) / 14318182
107
+ ```
108
+
109
+ Equivalent to `FREQ = f * 2^24 / φ2`, then take the upper 16 bits.
110
+
111
+ ---
112
+
113
+ ## Frequency Table (C-Major, A4 = 440 Hz)
114
+
115
+ | Note | Freq (Hz) | FREQ PAL (hex) | FREQ NTSC (hex) |
116
+ |------|------------|----------------|-----------------|
117
+ | C4 (Do) | 261.63 | 0x113E (4414) | 0x1069 (4201) |
118
+ | D4 (Re) | 293.66 | 0x1325 (4901) | 0x123C (4668) |
119
+ | E4 (Mi) | 329.63 | 0x154E (5454) | 0x1459 (5209) |
120
+ | F4 (Fa) | 349.23 | 0x1667 (5735) | 0x156E (5486) |
121
+ | G4 (Sol)| 392.00 | 0x18EE (6382) | 0x1753 (5971) |
122
+ | A4 (La) | 440.00 | 0x1B9B (7067) | 0x19B5 (6581) |
123
+ | B4 (Ti) | 493.88 | 0x1F04 (7940) | 0x1BFD (7165) |
124
+ | C5 (Do) | 523.25 | 0x2102 (8450) | 0x1E08 (7688) |
125
+
126
+ *Multiply FREQ by 2ⁿ to move up n octaves.*
127
+
128
+ ---
129
+
130
+ ## Primary References (for RAG)
131
+
132
+ - Oxyron SID Register Reference — bit map, frequency formulas, play sequence.
133
+ - Commodore 64 Programmer’s Reference (sound chapter, PDF).
134
+ - C64-Wiki — SID overview and filter behavior.
135
+ - Codebase64 — SID programming patterns (arpeggio, vibrato, PWM, players).
136
+ - $D418 Digi Playback articles — technique and bias requirements.
137
+
138
+ ---
139
+
140
+ ## Typical Usage Snippet (ASM)
141
+
142
+ ```asm
143
+ ; Initialize SID
144
+ lda #$0f ; volume = 15
145
+ sta $d418
146
+
147
+ ; Play note (Voice 1 example)
148
+ lda freq_lo
149
+ sta $d400
150
+ lda freq_hi
151
+ sta $d401
152
+ lda #$00
153
+ sta $d402
154
+ lda #$08
155
+ sta $d403
156
+ lda #$11
157
+ sta $d405
158
+ lda #$f3
159
+ sta $d406
160
+ lda #%01000001 ; pulse + gate
161
+ sta $d404
162
+
163
+ ; ... release ...
164
+ and #%11111110
165
+ sta $d404
166
+ ```
@@ -0,0 +1,131 @@
1
+ # SIDWAVE Format Specification
2
+
3
+ This document defines **SIDWAVE**, a declarative format for describing structured, modern C64 SID compositions.
4
+ SIDWAVE files are authored in YAML (optionally JSON) and compiled by an MCP server into `.SID` or `.PRG` binaries for playback on the Commodore 64 via the Ultimate64 REST API.
5
+
6
+ ---
7
+
8
+ ## Purpose
9
+
10
+ SIDWAVE provides a human- and machine-readable way to describe complex, atmospheric, and modern electronic music for the MOS 6581/8580 SID chip.
11
+ It captures instruments, modulation, and structure symbolically, allowing large language models to generate music that the MCP expands into precise SID register sequences.
12
+
13
+ Pipeline:
14
+
15
+ LLM → SIDWAVE (YAML) → MCP Compiler → SID Binary (.sid/.prg) → Ultimate64 REST → C64 Playback
16
+
17
+ ---
18
+
19
+ ## File and Schema Conventions
20
+
21
+ - **Format name:** SIDWAVE
22
+ - **File suffix:** `.sidwave.yaml` (or `.sid.yaml` for brevity)
23
+ - **Schema field:** `sidwave: 1.0`
24
+ - **Schema file:** `sidwave.schema.json`
25
+ - **Primary serialization:** YAML 1.2 (JSON also valid)
26
+
27
+ ---
28
+
29
+ ## Example SIDWAVE File
30
+
31
+ ```yaml
32
+ # yaml-language-server: $schema=https://example.com/sidwave.schema.json
33
+ sidwave: 1.0
34
+ title: "Echoes of Tomorrow"
35
+ author: "Generated by MCP"
36
+ tempo: 92
37
+ mode: PAL
38
+ global_fx:
39
+ reverb_sim: { depth: 0.3, delay_frames: 3 }
40
+ filter_env: { cutoff_base: 1800, sweep: -800, speed: 12 }
41
+
42
+ voices:
43
+ - id: 1
44
+ name: LeadPad
45
+ waveform: sawtooth
46
+ adsr: [4, 2, 10, 3]
47
+ patterns:
48
+ A:
49
+ length: 16
50
+ motif: "Cmin9 pad motif"
51
+ transpositions: [0, 5, 7]
52
+ fx:
53
+ vibrato: { depth: 2, rate: 5 }
54
+ filter_mod: { sweep: +500 over 8 steps }
55
+
56
+ - id: 2
57
+ name: ArpLayer
58
+ waveform: pulse
59
+ pulse_width: 0.3
60
+ patterns:
61
+ B:
62
+ type: "arpeggio"
63
+ notes: [C3, Eb3, G3, Bb3]
64
+ frame_rate: 2
65
+ fx:
66
+ pwm_sweep: { speed: 6, depth: 8 }
67
+
68
+ - id: 3
69
+ name: Bass
70
+ waveform: triangle
71
+ patterns:
72
+ C:
73
+ groove: [C1, C1, C1, G0]
74
+ fx:
75
+ slide: { depth: 2, speed: 3 }
76
+
77
+ timeline:
78
+ - section: "Intro"
79
+ bars: 16
80
+ layers: { v1: A, v2: -, v3: C }
81
+ - section: "Build"
82
+ bars: 32
83
+ layers: { v1: A↑, v2: B, v3: C }
84
+ - section: "Drift"
85
+ bars: 48
86
+ layers: { v1: A↓, v2: B, v3: C }
87
+ - section: "Fade"
88
+ bars: 32
89
+ layers: { v1: A–, v2: -, v3: - }
90
+ ```
91
+
92
+ ---
93
+
94
+ ## MCP Responsibilities
95
+
96
+ 1. Parse SIDWAVE YAML or JSON input.
97
+ 2. Expand patterns, transpositions, and modulation into frame-accurate SID register writes.
98
+ 3. Compile to valid `.SID` or `.PRG` binaries with proper init and play routines.
99
+ 4. Send the binary to Ultimate64 via:
100
+
101
+ ```
102
+ POST /v1/attachment:sid
103
+ Content-Type: application/octet-stream
104
+ Body = compiled binary
105
+ ```
106
+
107
+ ---
108
+
109
+ ## Authoring and Validation
110
+
111
+ - SIDWAVE files are plain YAML and open cleanly in any standard editor.
112
+ - Validation uses JSON Schema:
113
+
114
+ ```json
115
+ {
116
+ "yaml.schemas": {
117
+ "https://example.com/sidwave.schema.json": "*.sidwave.yaml"
118
+ }
119
+ }
120
+ ```
121
+
122
+ This enables autocomplete, hover info, and validation in VS Code or similar IDEs.
123
+
124
+ ---
125
+
126
+ ## LLM Prompt Template
127
+
128
+ > Compose a 3–5 minute atmospheric, modern electronic SID composition using the **SIDWAVE** format.
129
+ > Use three voices with expressive modulation (PWM, filter sweeps, arpeggios, evolving pads).
130
+ > Output valid YAML conforming to `sidwave.schema.json`.
131
+ > Avoid direct note repetition; reuse and transpose patterns.
@@ -0,0 +1,64 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://example.com/schemas/sidwave.schema.json",
4
+ "title": "SIDWAVE Composition Schema",
5
+ "type": "object",
6
+ "required": ["sidwave", "title", "tempo", "mode", "voices", "timeline"],
7
+ "properties": {
8
+ "sidwave": { "type": ["number", "string"], "enum": [1, "1.0", "1"] },
9
+ "title": { "type": "string" },
10
+ "author": { "type": "string" },
11
+ "tempo": { "type": "number", "minimum": 30, "maximum": 220 },
12
+ "mode": { "type": "string", "enum": ["PAL", "NTSC"] },
13
+ "global_fx": { "type": "object", "additionalProperties": true },
14
+ "voices": {
15
+ "type": "array",
16
+ "minItems": 1,
17
+ "items": {
18
+ "type": "object",
19
+ "required": ["id"],
20
+ "properties": {
21
+ "id": { "type": "number", "minimum": 1, "maximum": 3 },
22
+ "name": { "type": "string" },
23
+ "waveform": { "type": "string", "enum": ["pulse", "sawtooth", "triangle", "noise", "saw", "tri"] },
24
+ "pulse_width": { "type": "number", "minimum": 0 },
25
+ "adsr": { "type": "array", "items": { "type": "number", "minimum": 0, "maximum": 15 }, "minItems": 4, "maxItems": 4 },
26
+ "patterns": {
27
+ "type": "object",
28
+ "additionalProperties": {
29
+ "oneOf": [
30
+ { "type": "object", "required": ["type", "notes"], "properties": {
31
+ "type": { "const": "arpeggio" },
32
+ "notes": { "type": "array", "items": { "type": "string" }, "minItems": 1 },
33
+ "frame_rate": { "type": "number", "minimum": 1 },
34
+ "fx": { "type": "object", "additionalProperties": true }
35
+ }, "additionalProperties": false },
36
+ { "type": "object", "properties": {
37
+ "length": { "type": "number", "minimum": 1 },
38
+ "motif": { "type": "string" },
39
+ "transpositions": { "type": "array", "items": { "type": "number" } },
40
+ "fx": { "type": "object", "additionalProperties": true }
41
+ }, "additionalProperties": false },
42
+ { "type": "object", "required": ["groove"], "properties": {
43
+ "groove": { "type": "array", "items": { "type": "string" }, "minItems": 1 },
44
+ "fx": { "type": "object", "additionalProperties": true }
45
+ }, "additionalProperties": false }
46
+ ]
47
+ }
48
+ }
49
+ },
50
+ "additionalProperties": true
51
+ }
52
+ },
53
+ "timeline": {
54
+ "type": "array",
55
+ "minItems": 1,
56
+ "items": { "type": "object", "required": ["bars", "layers"], "properties": {
57
+ "section": { "type": "string" },
58
+ "bars": { "type": "number", "minimum": 1 },
59
+ "layers": { "type": "object", "additionalProperties": { "type": "string" } }
60
+ }, "additionalProperties": false }
61
+ }
62
+ },
63
+ "additionalProperties": false
64
+ }