c64bridge 0.9.3 → 1.0.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/AGENTS.md +19 -3
  2. package/README.md +190 -148
  3. package/dist/.tsbuildinfo +1 -1
  4. package/dist/c64Client.js +127 -5
  5. package/dist/config.js +12 -8
  6. package/dist/device.js +75 -45
  7. package/dist/mcp-server.js +11 -3
  8. package/dist/platform.js +13 -2
  9. package/dist/tools/audio.js +1 -1
  10. package/dist/tools/developer.js +6 -6
  11. package/dist/tools/graphics.js +4 -4
  12. package/dist/tools/input.js +129 -12
  13. package/dist/tools/machineControl.js +85 -6
  14. package/dist/tools/memory.js +1 -1
  15. package/dist/tools/meta/index.js +1 -1
  16. package/dist/tools/programRunners.js +5 -5
  17. package/dist/tools/rag.js +1 -1
  18. package/dist/tools/registry/batch.js +1 -1
  19. package/dist/tools/registry/config.js +5 -5
  20. package/dist/tools/registry/disk.js +2 -2
  21. package/dist/tools/registry/drive.js +2 -2
  22. package/dist/tools/registry/graphics.js +2 -2
  23. package/dist/tools/registry/memory.js +2 -2
  24. package/dist/tools/registry/platform.js +7 -5
  25. package/dist/tools/registry/program.js +5 -5
  26. package/dist/tools/registry/rag.js +1 -1
  27. package/dist/tools/registry/sound.js +4 -4
  28. package/dist/tools/registry/system.js +13 -3
  29. package/dist/tools/storage.js +1 -1
  30. package/doc/c64u/c64-openapi.yaml +1130 -774
  31. package/doc/u2/u2-openapi.yaml +1192 -0
  32. package/generated/c64/index.js +142 -9
  33. package/generated/openapi/c64u/index.js +1117 -0
  34. package/generated/openapi/u2/index.js +929 -0
  35. package/mcp/schemas/c64_graphics.schema.json +3 -3
  36. package/mcp/schemas/c64_input.schema.json +247 -6
  37. package/mcp/schemas/c64_memory.schema.json +3 -3
  38. package/mcp/schemas/c64_program.schema.json +3 -3
  39. package/mcp/schemas/c64_select_backend.schema.json +2 -0
  40. package/mcp/schemas/c64_system.schema.json +41 -1
  41. package/mcp/server.json +1 -1
  42. package/mcp/tools.json +382 -41
  43. package/mcp.json +14 -2
  44. package/package.json +4 -2
  45. package/scripts/mockC64Server.mjs +40 -0
  46. package/scripts/prepare-release.mjs +13 -2
  47. package/scripts/update-readme.ts +18 -30
  48. package/server.json +3 -3
@@ -0,0 +1,1192 @@
1
+ openapi: 3.1.0
2
+ info:
3
+ title: Ultimate-II REST API
4
+ version: 3.15 alpha
5
+ summary: REST API exposed by the Ultimate-II 3.14a firmware.
6
+ description: |
7
+ Source-derived OpenAPI description for the HTTP API implemented in
8
+ `/software/api` of the 1541ultimate firmware tree and linked into the
9
+ `target/u2/riscv/ultimate` firmware target.
10
+
11
+ The U2 target links the shared `routes`, `files`, `drives`, `runners`,
12
+ `configs`, and `machine` route modules. It does not link `route_streams`;
13
+ keyboard/joystick injection, debug registers, and power-off are also omitted
14
+ because the firmware source gates or rejects those operations on non-U64
15
+ targets.
16
+
17
+ JSON responses include an `errors` array. Binary endpoints return
18
+ `application/octet-stream` on success and JSON with `errors` when the request
19
+ cannot be completed.
20
+
21
+ If a network password is configured on the device, every API request must
22
+ include the `X-Password` header. If no network password is configured, the
23
+ same endpoints are available without the header.
24
+ servers:
25
+ - url: http://u2
26
+ description: Ultimate-II on the local network
27
+ - url: http://{host}
28
+ description: Custom Ultimate host or IP address
29
+ variables:
30
+ host:
31
+ default: u2
32
+ tags:
33
+ - name: System
34
+ - name: Runners
35
+ - name: Configuration
36
+ - name: Machine
37
+ - name: Drives
38
+ - name: Files
39
+ security:
40
+ - NetworkPassword: []
41
+ - {}
42
+ components:
43
+ securitySchemes:
44
+ NetworkPassword:
45
+ type: apiKey
46
+ in: header
47
+ name: X-Password
48
+ description: Required only when the device network password is configured.
49
+ parameters:
50
+ Category:
51
+ name: category
52
+ in: path
53
+ required: true
54
+ schema:
55
+ type: string
56
+ description: Configuration category name or firmware wildcard pattern.
57
+ Item:
58
+ name: item
59
+ in: path
60
+ required: true
61
+ schema:
62
+ type: string
63
+ description: Configuration item name or firmware wildcard pattern.
64
+ Setting:
65
+ name: setting
66
+ in: path
67
+ required: true
68
+ schema:
69
+ type: string
70
+ description: Configuration value carried as the third path segment.
71
+ Drive:
72
+ name: drive
73
+ in: path
74
+ required: true
75
+ schema:
76
+ type: string
77
+ enum: [a, b]
78
+ description: Internal drive slot.
79
+ FilePath:
80
+ name: path
81
+ in: path
82
+ required: true
83
+ allowReserved: true
84
+ schema:
85
+ type: string
86
+ description: Device filesystem path below `/v1/files/`; URL-encode reserved characters.
87
+ Address:
88
+ name: address
89
+ in: query
90
+ required: true
91
+ schema:
92
+ type: string
93
+ pattern: "^(0x)?[0-9A-Fa-f]{1,4}$"
94
+ description: C64 address in hexadecimal.
95
+ Length:
96
+ name: length
97
+ in: query
98
+ required: false
99
+ schema:
100
+ type: integer
101
+ minimum: 0
102
+ maximum: 65536
103
+ default: 256
104
+ FileQuery:
105
+ name: file
106
+ in: query
107
+ required: true
108
+ schema:
109
+ type: string
110
+ description: Absolute or device-relative file path.
111
+ SongNumber:
112
+ name: songnr
113
+ in: query
114
+ required: false
115
+ schema:
116
+ type: integer
117
+ minimum: 0
118
+ default: 0
119
+ DiskName:
120
+ name: diskname
121
+ in: query
122
+ required: false
123
+ schema:
124
+ type: string
125
+ D64Tracks:
126
+ name: tracks
127
+ in: query
128
+ required: false
129
+ schema:
130
+ type: integer
131
+ minimum: 35
132
+ maximum: 41
133
+ default: 35
134
+ DnpTracks:
135
+ name: tracks
136
+ in: query
137
+ required: true
138
+ schema:
139
+ type: integer
140
+ minimum: 1
141
+ maximum: 255
142
+ schemas:
143
+ ErrorList:
144
+ type: object
145
+ required: [errors]
146
+ properties:
147
+ errors:
148
+ type: array
149
+ items:
150
+ type: string
151
+ VersionResponse:
152
+ allOf:
153
+ - $ref: "#/components/schemas/ErrorList"
154
+ - type: object
155
+ required: [version]
156
+ properties:
157
+ version:
158
+ type: string
159
+ example: "0.1"
160
+ InfoResponse:
161
+ allOf:
162
+ - $ref: "#/components/schemas/ErrorList"
163
+ - type: object
164
+ required: [product, firmware_version, fpga_version, hostname]
165
+ properties:
166
+ product:
167
+ type: string
168
+ example: Ultimate-II
169
+ firmware_version:
170
+ type: string
171
+ example: 3.15 alpha
172
+ fpga_version:
173
+ type: string
174
+ example: U2
175
+ core_version:
176
+ type: string
177
+ description: Present on Ultimate 64-class firmware builds.
178
+ example: 1.4B
179
+ hostname:
180
+ type: string
181
+ unique_id:
182
+ type: string
183
+ ConfigCategoriesResponse:
184
+ allOf:
185
+ - $ref: "#/components/schemas/ErrorList"
186
+ - type: object
187
+ required: [categories]
188
+ properties:
189
+ categories:
190
+ type: array
191
+ items:
192
+ type: string
193
+ ConfigValue:
194
+ oneOf:
195
+ - type: string
196
+ - type: integer
197
+ ConfigItemDetail:
198
+ type: object
199
+ required: [current]
200
+ properties:
201
+ current:
202
+ $ref: "#/components/schemas/ConfigValue"
203
+ values:
204
+ type: array
205
+ items:
206
+ type: string
207
+ presets:
208
+ type: array
209
+ items:
210
+ type: string
211
+ min:
212
+ type: integer
213
+ max:
214
+ type: integer
215
+ format:
216
+ type: string
217
+ default:
218
+ $ref: "#/components/schemas/ConfigValue"
219
+ additionalProperties: true
220
+ ConfigCategoryResponse:
221
+ allOf:
222
+ - $ref: "#/components/schemas/ErrorList"
223
+ - type: object
224
+ additionalProperties:
225
+ type: object
226
+ additionalProperties:
227
+ oneOf:
228
+ - $ref: "#/components/schemas/ConfigValue"
229
+ - $ref: "#/components/schemas/ConfigItemDetail"
230
+ ConfigBatchUpdate:
231
+ type: object
232
+ additionalProperties:
233
+ type: object
234
+ additionalProperties:
235
+ $ref: "#/components/schemas/ConfigValue"
236
+ example:
237
+ Drive A Settings:
238
+ Drive: Enabled
239
+ Drive Bus ID: 8
240
+ ConfigStoreListResponse:
241
+ allOf:
242
+ - $ref: "#/components/schemas/ErrorList"
243
+ - type: object
244
+ properties:
245
+ loaded:
246
+ type: array
247
+ items:
248
+ type: string
249
+ written:
250
+ type: array
251
+ items:
252
+ type: string
253
+ reset:
254
+ type: array
255
+ items:
256
+ type: string
257
+ ActionResponse:
258
+ allOf:
259
+ - $ref: "#/components/schemas/ErrorList"
260
+ - type: object
261
+ additionalProperties: true
262
+ DriveInfo:
263
+ type: object
264
+ properties:
265
+ enabled:
266
+ type: boolean
267
+ bus_id:
268
+ type: integer
269
+ type:
270
+ type: string
271
+ rom:
272
+ type: string
273
+ image_file:
274
+ type: string
275
+ image_path:
276
+ type: string
277
+ last_error:
278
+ type: string
279
+ partitions:
280
+ type: array
281
+ items:
282
+ type: object
283
+ properties:
284
+ id:
285
+ type: integer
286
+ path:
287
+ type: string
288
+ additionalProperties: true
289
+ DriveListResponse:
290
+ allOf:
291
+ - $ref: "#/components/schemas/ErrorList"
292
+ - type: object
293
+ required: [drives]
294
+ properties:
295
+ drives:
296
+ type: array
297
+ items:
298
+ type: object
299
+ additionalProperties:
300
+ $ref: "#/components/schemas/DriveInfo"
301
+ FileInfoResponse:
302
+ allOf:
303
+ - $ref: "#/components/schemas/ErrorList"
304
+ - type: object
305
+ required: [files]
306
+ properties:
307
+ files:
308
+ type: object
309
+ properties:
310
+ path:
311
+ type: string
312
+ filename:
313
+ type: string
314
+ size:
315
+ type: integer
316
+ extension:
317
+ type: string
318
+ additionalProperties: true
319
+ requestBodies:
320
+ BinaryUpload:
321
+ required: true
322
+ content:
323
+ multipart/form-data:
324
+ schema:
325
+ type: object
326
+ required: [file]
327
+ properties:
328
+ file:
329
+ type: string
330
+ format: binary
331
+ application/octet-stream:
332
+ schema:
333
+ type: string
334
+ format: binary
335
+ SidUpload:
336
+ required: true
337
+ content:
338
+ multipart/form-data:
339
+ schema:
340
+ type: object
341
+ required: [file]
342
+ properties:
343
+ file:
344
+ type: array
345
+ minItems: 1
346
+ maxItems: 2
347
+ items:
348
+ type: string
349
+ format: binary
350
+ description: First file is the SID; optional second file is SID song-length data.
351
+ responses:
352
+ JsonOk:
353
+ description: Successful JSON response.
354
+ content:
355
+ application/json:
356
+ schema:
357
+ $ref: "#/components/schemas/ActionResponse"
358
+ BadRequest:
359
+ description: Request could not be parsed or failed validation.
360
+ content:
361
+ application/json:
362
+ schema:
363
+ $ref: "#/components/schemas/ErrorList"
364
+ Forbidden:
365
+ description: Network password is configured and `X-Password` is missing or wrong.
366
+ content:
367
+ application/json:
368
+ schema:
369
+ $ref: "#/components/schemas/ErrorList"
370
+ NotFound:
371
+ description: Route, file, category, item, or active menu screen was not found.
372
+ content:
373
+ application/json:
374
+ schema:
375
+ $ref: "#/components/schemas/ErrorList"
376
+ PreconditionFailed:
377
+ description: Required request body was missing.
378
+ content:
379
+ application/json:
380
+ schema:
381
+ $ref: "#/components/schemas/ErrorList"
382
+ NotImplemented:
383
+ description: Firmware route exists, but the current FPGA or hardware capability is unavailable.
384
+ content:
385
+ application/json:
386
+ schema:
387
+ $ref: "#/components/schemas/ErrorList"
388
+ ServerError:
389
+ description: Device-side operation failed.
390
+ content:
391
+ application/json:
392
+ schema:
393
+ $ref: "#/components/schemas/ErrorList"
394
+ paths:
395
+ /v1/help:
396
+ get:
397
+ tags: [System]
398
+ operationId: getHelp
399
+ summary: Return minimal HTML help for a command.
400
+ parameters:
401
+ - name: command
402
+ in: query
403
+ required: true
404
+ schema:
405
+ type: string
406
+ responses:
407
+ "200":
408
+ description: HTML help.
409
+ content:
410
+ text/html:
411
+ schema:
412
+ type: string
413
+ "400":
414
+ $ref: "#/components/responses/BadRequest"
415
+ "403":
416
+ $ref: "#/components/responses/Forbidden"
417
+ /v1/version:
418
+ get:
419
+ tags: [System]
420
+ operationId: getApiVersion
421
+ summary: Get REST API version.
422
+ responses:
423
+ "200":
424
+ description: API version.
425
+ content:
426
+ application/json:
427
+ schema:
428
+ $ref: "#/components/schemas/VersionResponse"
429
+ "403":
430
+ $ref: "#/components/responses/Forbidden"
431
+ /v1/info:
432
+ get:
433
+ tags: [System]
434
+ operationId: getDeviceInfo
435
+ summary: Get device identity and firmware versions.
436
+ responses:
437
+ "200":
438
+ description: Device information.
439
+ content:
440
+ application/json:
441
+ schema:
442
+ $ref: "#/components/schemas/InfoResponse"
443
+ "403":
444
+ $ref: "#/components/responses/Forbidden"
445
+ /v1/runners:sidplay:
446
+ put:
447
+ tags: [Runners]
448
+ operationId: playSidFromFile
449
+ summary: Play a SID file already present on the device filesystem.
450
+ parameters:
451
+ - $ref: "#/components/parameters/FileQuery"
452
+ - $ref: "#/components/parameters/SongNumber"
453
+ responses:
454
+ "200":
455
+ $ref: "#/components/responses/JsonOk"
456
+ "400":
457
+ $ref: "#/components/responses/BadRequest"
458
+ "403":
459
+ $ref: "#/components/responses/Forbidden"
460
+ "404":
461
+ $ref: "#/components/responses/NotFound"
462
+ post:
463
+ tags: [Runners]
464
+ operationId: playUploadedSid
465
+ summary: Upload and play a SID file.
466
+ parameters:
467
+ - $ref: "#/components/parameters/SongNumber"
468
+ requestBody:
469
+ $ref: "#/components/requestBodies/SidUpload"
470
+ responses:
471
+ "200":
472
+ $ref: "#/components/responses/JsonOk"
473
+ "400":
474
+ $ref: "#/components/responses/BadRequest"
475
+ "403":
476
+ $ref: "#/components/responses/Forbidden"
477
+ "412":
478
+ $ref: "#/components/responses/PreconditionFailed"
479
+ /v1/runners:modplay:
480
+ put:
481
+ tags: [Runners]
482
+ operationId: playModFromFile
483
+ summary: Play a MOD file from the device filesystem.
484
+ description: Requires the FPGA sampler capability.
485
+ parameters:
486
+ - $ref: "#/components/parameters/FileQuery"
487
+ responses:
488
+ "200":
489
+ $ref: "#/components/responses/JsonOk"
490
+ "403":
491
+ $ref: "#/components/responses/Forbidden"
492
+ "404":
493
+ $ref: "#/components/responses/NotFound"
494
+ "501":
495
+ $ref: "#/components/responses/NotImplemented"
496
+ post:
497
+ tags: [Runners]
498
+ operationId: playUploadedMod
499
+ summary: Upload and play a MOD file.
500
+ description: Requires the FPGA sampler capability.
501
+ requestBody:
502
+ $ref: "#/components/requestBodies/BinaryUpload"
503
+ responses:
504
+ "200":
505
+ $ref: "#/components/responses/JsonOk"
506
+ "403":
507
+ $ref: "#/components/responses/Forbidden"
508
+ "412":
509
+ $ref: "#/components/responses/PreconditionFailed"
510
+ "501":
511
+ $ref: "#/components/responses/NotImplemented"
512
+ /v1/runners:load_prg:
513
+ put:
514
+ tags: [Runners]
515
+ operationId: loadPrgFromFile
516
+ summary: Load a PRG from the device filesystem without starting it.
517
+ parameters:
518
+ - $ref: "#/components/parameters/FileQuery"
519
+ responses:
520
+ "200":
521
+ $ref: "#/components/responses/JsonOk"
522
+ "403":
523
+ $ref: "#/components/responses/Forbidden"
524
+ "404":
525
+ $ref: "#/components/responses/NotFound"
526
+ post:
527
+ tags: [Runners]
528
+ operationId: loadUploadedPrg
529
+ summary: Upload a PRG and load it without starting it.
530
+ requestBody:
531
+ $ref: "#/components/requestBodies/BinaryUpload"
532
+ responses:
533
+ "200":
534
+ $ref: "#/components/responses/JsonOk"
535
+ "403":
536
+ $ref: "#/components/responses/Forbidden"
537
+ "412":
538
+ $ref: "#/components/responses/PreconditionFailed"
539
+ /v1/runners:run_prg:
540
+ put:
541
+ tags: [Runners]
542
+ operationId: runPrgFromFile
543
+ summary: Load and run a PRG from the device filesystem.
544
+ parameters:
545
+ - $ref: "#/components/parameters/FileQuery"
546
+ responses:
547
+ "200":
548
+ $ref: "#/components/responses/JsonOk"
549
+ "403":
550
+ $ref: "#/components/responses/Forbidden"
551
+ "404":
552
+ $ref: "#/components/responses/NotFound"
553
+ post:
554
+ tags: [Runners]
555
+ operationId: runUploadedPrg
556
+ summary: Upload, load, and run a PRG.
557
+ requestBody:
558
+ $ref: "#/components/requestBodies/BinaryUpload"
559
+ responses:
560
+ "200":
561
+ $ref: "#/components/responses/JsonOk"
562
+ "403":
563
+ $ref: "#/components/responses/Forbidden"
564
+ "412":
565
+ $ref: "#/components/responses/PreconditionFailed"
566
+ /v1/runners:run_crt:
567
+ put:
568
+ tags: [Runners]
569
+ operationId: runCrtFromFile
570
+ summary: Load and start a CRT cartridge image from the device filesystem.
571
+ parameters:
572
+ - $ref: "#/components/parameters/FileQuery"
573
+ responses:
574
+ "200":
575
+ $ref: "#/components/responses/JsonOk"
576
+ "403":
577
+ $ref: "#/components/responses/Forbidden"
578
+ "404":
579
+ $ref: "#/components/responses/NotFound"
580
+ post:
581
+ tags: [Runners]
582
+ operationId: runUploadedCrt
583
+ summary: Upload, load, and start a CRT cartridge image.
584
+ requestBody:
585
+ $ref: "#/components/requestBodies/BinaryUpload"
586
+ responses:
587
+ "200":
588
+ $ref: "#/components/responses/JsonOk"
589
+ "403":
590
+ $ref: "#/components/responses/Forbidden"
591
+ "412":
592
+ $ref: "#/components/responses/PreconditionFailed"
593
+ /v1/configs:
594
+ get:
595
+ tags: [Configuration]
596
+ operationId: listConfigCategories
597
+ summary: List configuration categories.
598
+ responses:
599
+ "200":
600
+ description: Configuration categories.
601
+ content:
602
+ application/json:
603
+ schema:
604
+ $ref: "#/components/schemas/ConfigCategoriesResponse"
605
+ "403":
606
+ $ref: "#/components/responses/Forbidden"
607
+ post:
608
+ tags: [Configuration]
609
+ operationId: batchUpdateConfig
610
+ summary: Apply a JSON batch of configuration values.
611
+ description: Use single-item `PUT` for interactive writes; batch POST buffers the body on-device.
612
+ requestBody:
613
+ required: true
614
+ content:
615
+ application/json:
616
+ schema:
617
+ $ref: "#/components/schemas/ConfigBatchUpdate"
618
+ responses:
619
+ "200":
620
+ $ref: "#/components/responses/JsonOk"
621
+ "400":
622
+ $ref: "#/components/responses/BadRequest"
623
+ "403":
624
+ $ref: "#/components/responses/Forbidden"
625
+ "412":
626
+ $ref: "#/components/responses/PreconditionFailed"
627
+ /v1/configs/{category}:
628
+ get:
629
+ tags: [Configuration]
630
+ operationId: getConfigCategory
631
+ summary: Get matching configuration categories and their current values.
632
+ parameters:
633
+ - $ref: "#/components/parameters/Category"
634
+ responses:
635
+ "200":
636
+ description: Matching category values.
637
+ content:
638
+ application/json:
639
+ schema:
640
+ $ref: "#/components/schemas/ConfigCategoryResponse"
641
+ "403":
642
+ $ref: "#/components/responses/Forbidden"
643
+ /v1/configs/{category}/{item}:
644
+ get:
645
+ tags: [Configuration]
646
+ operationId: getConfigItem
647
+ summary: Get detailed metadata for matching configuration items.
648
+ parameters:
649
+ - $ref: "#/components/parameters/Category"
650
+ - $ref: "#/components/parameters/Item"
651
+ responses:
652
+ "200":
653
+ description: Matching item metadata.
654
+ content:
655
+ application/json:
656
+ schema:
657
+ $ref: "#/components/schemas/ConfigCategoryResponse"
658
+ "403":
659
+ $ref: "#/components/responses/Forbidden"
660
+ put:
661
+ tags: [Configuration]
662
+ operationId: updateConfigItem
663
+ summary: Update one configuration item using the `value` query parameter.
664
+ parameters:
665
+ - $ref: "#/components/parameters/Category"
666
+ - $ref: "#/components/parameters/Item"
667
+ - name: value
668
+ in: query
669
+ required: true
670
+ schema:
671
+ type: string
672
+ responses:
673
+ "200":
674
+ $ref: "#/components/responses/JsonOk"
675
+ "400":
676
+ $ref: "#/components/responses/BadRequest"
677
+ "403":
678
+ $ref: "#/components/responses/Forbidden"
679
+ "404":
680
+ $ref: "#/components/responses/NotFound"
681
+ /v1/configs/{category}/{item}/{setting}:
682
+ put:
683
+ tags: [Configuration]
684
+ operationId: updateConfigItemByPath
685
+ summary: Update one configuration item using the third path segment as the value.
686
+ parameters:
687
+ - $ref: "#/components/parameters/Category"
688
+ - $ref: "#/components/parameters/Item"
689
+ - $ref: "#/components/parameters/Setting"
690
+ responses:
691
+ "200":
692
+ $ref: "#/components/responses/JsonOk"
693
+ "400":
694
+ $ref: "#/components/responses/BadRequest"
695
+ "403":
696
+ $ref: "#/components/responses/Forbidden"
697
+ "404":
698
+ $ref: "#/components/responses/NotFound"
699
+ /v1/configs:load_from_flash:
700
+ put:
701
+ tags: [Configuration]
702
+ operationId: loadAllConfigsFromFlash
703
+ summary: Reload all configuration stores from flash.
704
+ responses:
705
+ "200":
706
+ $ref: "#/components/responses/JsonOk"
707
+ "403":
708
+ $ref: "#/components/responses/Forbidden"
709
+ /v1/configs/{category}:load_from_flash:
710
+ put:
711
+ tags: [Configuration]
712
+ operationId: loadConfigCategoryFromFlash
713
+ summary: Reload matching configuration stores from flash.
714
+ parameters:
715
+ - $ref: "#/components/parameters/Category"
716
+ responses:
717
+ "200":
718
+ description: Matching stores loaded.
719
+ content:
720
+ application/json:
721
+ schema:
722
+ $ref: "#/components/schemas/ConfigStoreListResponse"
723
+ "403":
724
+ $ref: "#/components/responses/Forbidden"
725
+ /v1/configs:save_to_flash:
726
+ put:
727
+ tags: [Configuration]
728
+ operationId: saveAllConfigsToFlash
729
+ summary: Save stale configuration stores to flash.
730
+ responses:
731
+ "200":
732
+ description: Stores written.
733
+ content:
734
+ application/json:
735
+ schema:
736
+ $ref: "#/components/schemas/ConfigStoreListResponse"
737
+ "403":
738
+ $ref: "#/components/responses/Forbidden"
739
+ /v1/configs/{category}:save_to_flash:
740
+ put:
741
+ tags: [Configuration]
742
+ operationId: saveConfigCategoryToFlash
743
+ summary: Save matching stale configuration stores to flash.
744
+ parameters:
745
+ - $ref: "#/components/parameters/Category"
746
+ responses:
747
+ "200":
748
+ description: Matching stores written.
749
+ content:
750
+ application/json:
751
+ schema:
752
+ $ref: "#/components/schemas/ConfigStoreListResponse"
753
+ "403":
754
+ $ref: "#/components/responses/Forbidden"
755
+ /v1/configs:reset_to_default:
756
+ put:
757
+ tags: [Configuration]
758
+ operationId: resetAllConfigsToDefault
759
+ summary: Reset all configuration stores to firmware defaults.
760
+ responses:
761
+ "200":
762
+ $ref: "#/components/responses/JsonOk"
763
+ "403":
764
+ $ref: "#/components/responses/Forbidden"
765
+ /v1/configs/{category}:reset_to_default:
766
+ put:
767
+ tags: [Configuration]
768
+ operationId: resetConfigCategoryToDefault
769
+ summary: Reset matching configuration stores to firmware defaults.
770
+ parameters:
771
+ - $ref: "#/components/parameters/Category"
772
+ responses:
773
+ "200":
774
+ description: Matching stores reset.
775
+ content:
776
+ application/json:
777
+ schema:
778
+ $ref: "#/components/schemas/ConfigStoreListResponse"
779
+ "403":
780
+ $ref: "#/components/responses/Forbidden"
781
+ /v1/machine:reset:
782
+ put:
783
+ tags: [Machine]
784
+ operationId: resetMachine
785
+ summary: Reset the C64.
786
+ responses:
787
+ "200":
788
+ $ref: "#/components/responses/JsonOk"
789
+ "403":
790
+ $ref: "#/components/responses/Forbidden"
791
+ /v1/machine:reboot:
792
+ put:
793
+ tags: [Machine]
794
+ operationId: rebootMachine
795
+ summary: Reboot the C64.
796
+ responses:
797
+ "200":
798
+ $ref: "#/components/responses/JsonOk"
799
+ "403":
800
+ $ref: "#/components/responses/Forbidden"
801
+ /v1/machine:pause:
802
+ put:
803
+ tags: [Machine]
804
+ operationId: pauseMachine
805
+ summary: Pause the machine using DMA.
806
+ responses:
807
+ "200":
808
+ $ref: "#/components/responses/JsonOk"
809
+ "403":
810
+ $ref: "#/components/responses/Forbidden"
811
+ /v1/machine:resume:
812
+ put:
813
+ tags: [Machine]
814
+ operationId: resumeMachine
815
+ summary: Resume a paused machine.
816
+ responses:
817
+ "200":
818
+ $ref: "#/components/responses/JsonOk"
819
+ "403":
820
+ $ref: "#/components/responses/Forbidden"
821
+ /v1/machine:menu_button:
822
+ put:
823
+ tags: [Machine]
824
+ operationId: pressMenuButton
825
+ summary: Press the Ultimate menu button.
826
+ responses:
827
+ "200":
828
+ $ref: "#/components/responses/JsonOk"
829
+ "403":
830
+ $ref: "#/components/responses/Forbidden"
831
+ /v1/machine:writemem:
832
+ put:
833
+ tags: [Machine]
834
+ operationId: writeMemoryHex
835
+ summary: Write up to 128 bytes of C64 memory from a hex string.
836
+ parameters:
837
+ - $ref: "#/components/parameters/Address"
838
+ - name: data
839
+ in: query
840
+ required: true
841
+ schema:
842
+ type: string
843
+ pattern: "^([0-9A-Fa-f]{2}){1,128}$"
844
+ responses:
845
+ "200":
846
+ $ref: "#/components/responses/JsonOk"
847
+ "400":
848
+ $ref: "#/components/responses/BadRequest"
849
+ "403":
850
+ $ref: "#/components/responses/Forbidden"
851
+ post:
852
+ tags: [Machine]
853
+ operationId: writeMemoryUpload
854
+ summary: Write C64 memory from an uploaded binary payload.
855
+ parameters:
856
+ - $ref: "#/components/parameters/Address"
857
+ requestBody:
858
+ $ref: "#/components/requestBodies/BinaryUpload"
859
+ responses:
860
+ "200":
861
+ $ref: "#/components/responses/JsonOk"
862
+ "400":
863
+ $ref: "#/components/responses/BadRequest"
864
+ "403":
865
+ $ref: "#/components/responses/Forbidden"
866
+ "404":
867
+ $ref: "#/components/responses/NotFound"
868
+ "412":
869
+ $ref: "#/components/responses/PreconditionFailed"
870
+ "500":
871
+ $ref: "#/components/responses/ServerError"
872
+ /v1/machine:readmem:
873
+ get:
874
+ tags: [Machine]
875
+ operationId: readMemory
876
+ summary: Read C64 memory as raw bytes.
877
+ parameters:
878
+ - $ref: "#/components/parameters/Address"
879
+ - $ref: "#/components/parameters/Length"
880
+ responses:
881
+ "200":
882
+ description: Raw memory bytes.
883
+ content:
884
+ application/octet-stream:
885
+ schema:
886
+ type: string
887
+ format: binary
888
+ "400":
889
+ $ref: "#/components/responses/BadRequest"
890
+ "403":
891
+ $ref: "#/components/responses/Forbidden"
892
+ /v1/machine:menu_screen:
893
+ get:
894
+ tags: [Machine]
895
+ operationId: readMenuScreen
896
+ summary: Read the active Ultimate menu screen matrix as raw bytes.
897
+ description: Returns 404 JSON when no active menu screen matrix is available.
898
+ responses:
899
+ "200":
900
+ description: Active screen matrix bytes.
901
+ content:
902
+ application/octet-stream:
903
+ schema:
904
+ type: string
905
+ format: binary
906
+ "403":
907
+ $ref: "#/components/responses/Forbidden"
908
+ "404":
909
+ $ref: "#/components/responses/NotFound"
910
+ /v1/machine:measure:
911
+ get:
912
+ tags: [Machine]
913
+ operationId: measureCartridgeBus
914
+ summary: Capture cartridge-bus timing as a VCD file.
915
+ responses:
916
+ "200":
917
+ description: VCD timing capture.
918
+ content:
919
+ application/octet-stream:
920
+ schema:
921
+ type: string
922
+ format: binary
923
+ "403":
924
+ $ref: "#/components/responses/Forbidden"
925
+ "501":
926
+ $ref: "#/components/responses/NotImplemented"
927
+ /v1/drives:
928
+ get:
929
+ tags: [Drives]
930
+ operationId: listDrives
931
+ summary: List internal drives and IEC service devices.
932
+ responses:
933
+ "200":
934
+ description: Drive list.
935
+ content:
936
+ application/json:
937
+ schema:
938
+ $ref: "#/components/schemas/DriveListResponse"
939
+ "403":
940
+ $ref: "#/components/responses/Forbidden"
941
+ /v1/drives/{drive}:mount:
942
+ put:
943
+ tags: [Drives]
944
+ operationId: mountDiskImage
945
+ summary: Mount a disk image from the device filesystem.
946
+ parameters:
947
+ - $ref: "#/components/parameters/Drive"
948
+ - name: image
949
+ in: query
950
+ required: true
951
+ schema:
952
+ type: string
953
+ - name: type
954
+ in: query
955
+ required: false
956
+ schema:
957
+ type: string
958
+ enum: [d64, g64, d71, g71, d81]
959
+ - name: mode
960
+ in: query
961
+ required: false
962
+ schema:
963
+ type: string
964
+ enum: [readwrite, readonly, unlinked]
965
+ responses:
966
+ "200":
967
+ $ref: "#/components/responses/JsonOk"
968
+ "400":
969
+ $ref: "#/components/responses/BadRequest"
970
+ "403":
971
+ $ref: "#/components/responses/Forbidden"
972
+ post:
973
+ tags: [Drives]
974
+ operationId: mountUploadedDiskImage
975
+ summary: Upload and mount a disk image.
976
+ parameters:
977
+ - $ref: "#/components/parameters/Drive"
978
+ - name: type
979
+ in: query
980
+ required: false
981
+ schema:
982
+ type: string
983
+ enum: [d64, g64, d71, g71, d81]
984
+ - name: mode
985
+ in: query
986
+ required: false
987
+ schema:
988
+ type: string
989
+ enum: [readwrite, readonly, unlinked]
990
+ requestBody:
991
+ $ref: "#/components/requestBodies/BinaryUpload"
992
+ responses:
993
+ "200":
994
+ $ref: "#/components/responses/JsonOk"
995
+ "400":
996
+ $ref: "#/components/responses/BadRequest"
997
+ "403":
998
+ $ref: "#/components/responses/Forbidden"
999
+ "412":
1000
+ $ref: "#/components/responses/PreconditionFailed"
1001
+ /v1/drives/{drive}:reset:
1002
+ put:
1003
+ tags: [Drives]
1004
+ operationId: resetDrive
1005
+ summary: Reset a drive.
1006
+ parameters:
1007
+ - $ref: "#/components/parameters/Drive"
1008
+ responses:
1009
+ "200":
1010
+ $ref: "#/components/responses/JsonOk"
1011
+ "403":
1012
+ $ref: "#/components/responses/Forbidden"
1013
+ /v1/drives/{drive}:remove:
1014
+ put:
1015
+ tags: [Drives]
1016
+ operationId: removeMountedImage
1017
+ summary: Remove the mounted image from a drive.
1018
+ parameters:
1019
+ - $ref: "#/components/parameters/Drive"
1020
+ responses:
1021
+ "200":
1022
+ $ref: "#/components/responses/JsonOk"
1023
+ "403":
1024
+ $ref: "#/components/responses/Forbidden"
1025
+ /v1/drives/{drive}:on:
1026
+ put:
1027
+ tags: [Drives]
1028
+ operationId: powerOnDrive
1029
+ summary: Power on a drive.
1030
+ parameters:
1031
+ - $ref: "#/components/parameters/Drive"
1032
+ responses:
1033
+ "200":
1034
+ $ref: "#/components/responses/JsonOk"
1035
+ "403":
1036
+ $ref: "#/components/responses/Forbidden"
1037
+ /v1/drives/{drive}:off:
1038
+ put:
1039
+ tags: [Drives]
1040
+ operationId: powerOffDrive
1041
+ summary: Power off a drive.
1042
+ parameters:
1043
+ - $ref: "#/components/parameters/Drive"
1044
+ responses:
1045
+ "200":
1046
+ $ref: "#/components/responses/JsonOk"
1047
+ "403":
1048
+ $ref: "#/components/responses/Forbidden"
1049
+ /v1/drives/{drive}:unlink:
1050
+ put:
1051
+ tags: [Drives]
1052
+ operationId: unlinkMountedImage
1053
+ summary: Unlink the mounted image from host storage.
1054
+ parameters:
1055
+ - $ref: "#/components/parameters/Drive"
1056
+ responses:
1057
+ "200":
1058
+ $ref: "#/components/responses/JsonOk"
1059
+ "403":
1060
+ $ref: "#/components/responses/Forbidden"
1061
+ /v1/drives/{drive}:load_rom:
1062
+ put:
1063
+ tags: [Drives]
1064
+ operationId: loadDriveRomFromFile
1065
+ summary: Load a drive ROM from the device filesystem.
1066
+ parameters:
1067
+ - $ref: "#/components/parameters/Drive"
1068
+ - $ref: "#/components/parameters/FileQuery"
1069
+ responses:
1070
+ "200":
1071
+ $ref: "#/components/responses/JsonOk"
1072
+ "403":
1073
+ $ref: "#/components/responses/Forbidden"
1074
+ post:
1075
+ tags: [Drives]
1076
+ operationId: loadUploadedDriveRom
1077
+ summary: Upload and load a drive ROM.
1078
+ parameters:
1079
+ - $ref: "#/components/parameters/Drive"
1080
+ requestBody:
1081
+ $ref: "#/components/requestBodies/BinaryUpload"
1082
+ responses:
1083
+ "200":
1084
+ $ref: "#/components/responses/JsonOk"
1085
+ "403":
1086
+ $ref: "#/components/responses/Forbidden"
1087
+ "412":
1088
+ $ref: "#/components/responses/PreconditionFailed"
1089
+ /v1/drives/{drive}:set_mode:
1090
+ put:
1091
+ tags: [Drives]
1092
+ operationId: setDriveMode
1093
+ summary: Set drive emulation mode.
1094
+ parameters:
1095
+ - $ref: "#/components/parameters/Drive"
1096
+ - name: mode
1097
+ in: query
1098
+ required: true
1099
+ schema:
1100
+ type: string
1101
+ enum: ["1541", "1571", "1581"]
1102
+ responses:
1103
+ "200":
1104
+ $ref: "#/components/responses/JsonOk"
1105
+ "400":
1106
+ $ref: "#/components/responses/BadRequest"
1107
+ "403":
1108
+ $ref: "#/components/responses/Forbidden"
1109
+ /v1/files/{path}:info:
1110
+ get:
1111
+ tags: [Files]
1112
+ operationId: getFileInfo
1113
+ summary: Get metadata for a device filesystem path.
1114
+ parameters:
1115
+ - $ref: "#/components/parameters/FilePath"
1116
+ responses:
1117
+ "200":
1118
+ description: File metadata.
1119
+ content:
1120
+ application/json:
1121
+ schema:
1122
+ $ref: "#/components/schemas/FileInfoResponse"
1123
+ "403":
1124
+ $ref: "#/components/responses/Forbidden"
1125
+ "404":
1126
+ $ref: "#/components/responses/NotFound"
1127
+ /v1/files/{path}:create_d64:
1128
+ put:
1129
+ tags: [Files]
1130
+ operationId: createD64
1131
+ summary: Create and format a D64 image.
1132
+ parameters:
1133
+ - $ref: "#/components/parameters/FilePath"
1134
+ - $ref: "#/components/parameters/D64Tracks"
1135
+ - $ref: "#/components/parameters/DiskName"
1136
+ responses:
1137
+ "200":
1138
+ $ref: "#/components/responses/JsonOk"
1139
+ "400":
1140
+ $ref: "#/components/responses/BadRequest"
1141
+ "403":
1142
+ $ref: "#/components/responses/Forbidden"
1143
+ "500":
1144
+ $ref: "#/components/responses/ServerError"
1145
+ /v1/files/{path}:create_d71:
1146
+ put:
1147
+ tags: [Files]
1148
+ operationId: createD71
1149
+ summary: Create and format a D71 image.
1150
+ parameters:
1151
+ - $ref: "#/components/parameters/FilePath"
1152
+ - $ref: "#/components/parameters/DiskName"
1153
+ responses:
1154
+ "200":
1155
+ $ref: "#/components/responses/JsonOk"
1156
+ "403":
1157
+ $ref: "#/components/responses/Forbidden"
1158
+ "500":
1159
+ $ref: "#/components/responses/ServerError"
1160
+ /v1/files/{path}:create_d81:
1161
+ put:
1162
+ tags: [Files]
1163
+ operationId: createD81
1164
+ summary: Create and format a D81 image.
1165
+ parameters:
1166
+ - $ref: "#/components/parameters/FilePath"
1167
+ - $ref: "#/components/parameters/DiskName"
1168
+ responses:
1169
+ "200":
1170
+ $ref: "#/components/responses/JsonOk"
1171
+ "403":
1172
+ $ref: "#/components/responses/Forbidden"
1173
+ "500":
1174
+ $ref: "#/components/responses/ServerError"
1175
+ /v1/files/{path}:create_dnp:
1176
+ put:
1177
+ tags: [Files]
1178
+ operationId: createDnp
1179
+ summary: Create and format a DNP image.
1180
+ parameters:
1181
+ - $ref: "#/components/parameters/FilePath"
1182
+ - $ref: "#/components/parameters/DnpTracks"
1183
+ - $ref: "#/components/parameters/DiskName"
1184
+ responses:
1185
+ "200":
1186
+ $ref: "#/components/responses/JsonOk"
1187
+ "400":
1188
+ $ref: "#/components/responses/BadRequest"
1189
+ "403":
1190
+ $ref: "#/components/responses/Forbidden"
1191
+ "500":
1192
+ $ref: "#/components/responses/ServerError"