romdevtools 0.14.0 → 0.16.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/AGENTS.md +18 -11
- package/CHANGELOG.md +94 -0
- package/README.md +1 -1
- package/examples/atari2600/main.asm +1 -1
- package/examples/atari2600/templates/default.asm +1 -1
- package/examples/atari2600/templates/paddle.asm +59 -47
- package/examples/atari7800/main.c +1 -1
- package/examples/atari7800/templates/default.c +1 -1
- package/examples/atari7800/templates/music_demo.c +1 -1
- package/examples/c64/main.c +1 -1
- package/examples/c64/templates/platformer.c +2 -2
- package/examples/c64/templates/puzzle.c +1 -1
- package/examples/c64/templates/racing.c +3 -3
- package/examples/c64/templates/shmup.c +6 -5
- package/examples/c64/templates/sports.c +4 -4
- package/examples/gb/main.asm +1 -1
- package/examples/gb/main.c +1 -1
- package/examples/gb/templates/puzzle.c +1 -1
- package/examples/gb/templates/racing.c +1 -1
- package/examples/gb/templates/shmup.c +1 -1
- package/examples/gba/templates/gba_hello.c +1 -1
- package/examples/gba/templates/maxmod_demo.c +1 -1
- package/examples/gba/templates/puzzle.c +17 -3
- package/examples/gba/templates/racing.c +16 -2
- package/examples/gba/templates/shmup.c +23 -4
- package/examples/gba/templates/tonc_hello.c +6 -4
- package/examples/gbc/main.asm +1 -1
- package/examples/gbc/templates/puzzle.c +1 -1
- package/examples/gbc/templates/racing.c +1 -1
- package/examples/gbc/templates/shmup.c +1 -1
- package/examples/genesis/main.s +1 -1
- package/examples/genesis/templates/puzzle.c +1 -1
- package/examples/genesis/templates/racing.c +45 -1
- package/examples/genesis/templates/shmup.c +12 -3
- package/examples/genesis/templates/shmup_2p.c +2 -2
- package/examples/genesis/templates/sports.c +39 -0
- package/examples/gg/templates/hello_sprite.c +38 -23
- package/examples/gg/templates/music_demo.c +11 -8
- package/examples/gg/templates/platformer.c +37 -15
- package/examples/gg/templates/racing.c +25 -12
- package/examples/gg/templates/shmup.c +12 -6
- package/examples/gg/templates/sports.c +30 -16
- package/examples/gg/templates/tile_engine.c +24 -10
- package/examples/lynx/templates/platformer.c +7 -1
- package/examples/lynx/templates/puzzle.c +8 -2
- package/examples/lynx/templates/racing.c +7 -1
- package/examples/lynx/templates/sports.c +7 -1
- package/examples/nes/main.c +2 -2
- package/examples/nes/space-shooter/nes_runtime.h +1 -1
- package/examples/nes/templates/default.c +4 -1
- package/examples/nes/templates/racing.c +50 -1
- package/examples/pce/main.c +1 -1
- package/examples/sms/templates/hello_sprite.c +1 -1
- package/examples/sms/templates/music_demo.c +1 -1
- package/examples/sms/templates/puzzle.c +1 -1
- package/examples/sms/templates/racing.c +1 -1
- package/examples/sms/templates/shmup.c +1 -1
- package/examples/sms/templates/shmup_2p.c +2 -2
- package/examples/snes/main.asm +1 -1
- package/examples/snes/templates/c-hello-data.asm +309 -14
- package/examples/snes/templates/c-hello.c +13 -2
- package/examples/snes/templates/default.c +1 -1
- package/examples/snes/templates/hello_sprite-data.asm +300 -2
- package/examples/snes/templates/hello_sprite.c +10 -1
- package/examples/snes/templates/music_demo-data.asm +300 -2
- package/examples/snes/templates/music_demo.c +10 -1
- package/examples/snes/templates/platformer-data.asm +300 -2
- package/examples/snes/templates/platformer.c +10 -1
- package/examples/snes/templates/puzzle-data.asm +300 -2
- package/examples/snes/templates/puzzle.c +11 -1
- package/examples/snes/templates/racing-data.asm +300 -2
- package/examples/snes/templates/racing.c +40 -4
- package/examples/snes/templates/shmup-data.asm +299 -6
- package/examples/snes/templates/shmup.c +11 -7
- package/examples/snes/templates/sports-data.asm +300 -2
- package/examples/snes/templates/sports.c +40 -5
- package/package.json +1 -1
- package/src/http/skill-doc.js +1 -1
- package/src/http/tool-registry.js +1 -1
- package/src/mcp/tools/index.js +4 -4
- package/src/mcp/tools/project.js +33 -22
- package/src/mcp/tools/toolchain.js +196 -20
- package/src/observer/livestream.html +34 -4
- package/src/platforms/gg/MENTAL_MODEL.md +14 -13
- package/src/platforms/gg/lib/c/vdp_init.c +10 -8
- package/src/platforms/msx/MENTAL_MODEL.md +1 -1
- package/src/platforms/nes/TROUBLESHOOTING.md +1 -1
- package/src/platforms/nes/lib/c/nes_runtime.c +28 -6
- package/src/platforms/pce/MENTAL_MODEL.md +1 -1
- package/src/platforms/pce/lib/c/pce_hw.h +1 -0
- package/src/platforms/pce/lib/c/pce_video.c +26 -0
- package/src/platforms/sms/MENTAL_MODEL.md +12 -12
- package/src/platforms/sms/lib/c/vdp_init.c +10 -8
- package/src/platforms/sms/lib/vdp_init.s +1 -1
- package/src/toolchains/cc65/cc65.js +8 -1
- package/src/toolchains/cc65/presets/nes/chr-ram-runtime.cfg +1 -1
- package/src/toolchains/cc65/presets/nes/chr-ram.cfg +1 -1
- package/src/toolchains/cc65/presets/nes/chr-ram.crt0.s +1 -1
- package/src/toolchains/gba-c/gba-c.js +6 -1
- package/src/toolchains/genesis-c/README.md +1 -1
- package/src/toolchains/genesis-c/genesis-c.js +10 -2
- package/src/toolchains/parse-errors.js +67 -5
- package/src/toolchains/sdcc/preflight-lint.js +47 -7
- package/src/toolchains/snes-c/snes-c.js +3 -7
|
@@ -5,10 +5,308 @@
|
|
|
5
5
|
.section ".rodata1" superfree
|
|
6
6
|
|
|
7
7
|
tilfont:
|
|
8
|
-
|
|
8
|
+
; 8x8 4bpp console font, 96 glyphs (ASCII 0x20-0x7F). consoleInitText
|
|
9
|
+
; DMAs exactly 3072 bytes (96 tiles x 32 bytes, 4bpp) from here into
|
|
10
|
+
; VRAM. Glyph index = (char - 0x20); only bitplane 0 carries pixels so
|
|
11
|
+
; every set pixel uses palette colour 1. Public-domain font8x8 basic.
|
|
12
|
+
; 0x20 '(space)'
|
|
13
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
14
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
15
|
+
; 0x21 '!'
|
|
16
|
+
.db $18, $00, $3C, $00, $3C, $00, $18, $00, $18, $00, $00, $00, $18, $00, $00, $00
|
|
17
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
18
|
+
; 0x22 '"'
|
|
19
|
+
.db $6C, $00, $6C, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
20
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
21
|
+
; 0x23 '#'
|
|
22
|
+
.db $6C, $00, $6C, $00, $FE, $00, $6C, $00, $FE, $00, $6C, $00, $6C, $00, $00, $00
|
|
23
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
24
|
+
; 0x24 '$'
|
|
25
|
+
.db $30, $00, $7C, $00, $C0, $00, $78, $00, $0C, $00, $F8, $00, $30, $00, $00, $00
|
|
26
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
27
|
+
; 0x25 '%'
|
|
28
|
+
.db $00, $00, $C6, $00, $CC, $00, $18, $00, $30, $00, $66, $00, $C6, $00, $00, $00
|
|
29
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
30
|
+
; 0x26 '&'
|
|
31
|
+
.db $38, $00, $6C, $00, $38, $00, $76, $00, $DC, $00, $CC, $00, $76, $00, $00, $00
|
|
32
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
33
|
+
; 0x27 '''
|
|
34
|
+
.db $60, $00, $60, $00, $C0, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
35
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
36
|
+
; 0x28 '('
|
|
37
|
+
.db $18, $00, $30, $00, $60, $00, $60, $00, $60, $00, $30, $00, $18, $00, $00, $00
|
|
38
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
39
|
+
; 0x29 ')'
|
|
40
|
+
.db $60, $00, $30, $00, $18, $00, $18, $00, $18, $00, $30, $00, $60, $00, $00, $00
|
|
41
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
42
|
+
; 0x2A '*'
|
|
43
|
+
.db $00, $00, $66, $00, $3C, $00, $FF, $00, $3C, $00, $66, $00, $00, $00, $00, $00
|
|
44
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
45
|
+
; 0x2B '+'
|
|
46
|
+
.db $00, $00, $30, $00, $30, $00, $FC, $00, $30, $00, $30, $00, $00, $00, $00, $00
|
|
47
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
48
|
+
; 0x2C ','
|
|
49
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $30, $00, $30, $00, $60, $00
|
|
50
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
51
|
+
; 0x2D '-'
|
|
52
|
+
.db $00, $00, $00, $00, $00, $00, $FC, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
53
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
54
|
+
; 0x2E '.'
|
|
55
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $30, $00, $30, $00, $00, $00
|
|
56
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
57
|
+
; 0x2F '/'
|
|
58
|
+
.db $06, $00, $0C, $00, $18, $00, $30, $00, $60, $00, $C0, $00, $80, $00, $00, $00
|
|
59
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
60
|
+
; 0x30 '0'
|
|
61
|
+
.db $7C, $00, $C6, $00, $CE, $00, $DE, $00, $F6, $00, $E6, $00, $7C, $00, $00, $00
|
|
62
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
63
|
+
; 0x31 '1'
|
|
64
|
+
.db $30, $00, $70, $00, $30, $00, $30, $00, $30, $00, $30, $00, $FC, $00, $00, $00
|
|
65
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
66
|
+
; 0x32 '2'
|
|
67
|
+
.db $78, $00, $CC, $00, $0C, $00, $38, $00, $60, $00, $CC, $00, $FC, $00, $00, $00
|
|
68
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
69
|
+
; 0x33 '3'
|
|
70
|
+
.db $78, $00, $CC, $00, $0C, $00, $38, $00, $0C, $00, $CC, $00, $78, $00, $00, $00
|
|
71
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
72
|
+
; 0x34 '4'
|
|
73
|
+
.db $1C, $00, $3C, $00, $6C, $00, $CC, $00, $FE, $00, $0C, $00, $1E, $00, $00, $00
|
|
74
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
75
|
+
; 0x35 '5'
|
|
76
|
+
.db $FC, $00, $C0, $00, $F8, $00, $0C, $00, $0C, $00, $CC, $00, $78, $00, $00, $00
|
|
77
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
78
|
+
; 0x36 '6'
|
|
79
|
+
.db $38, $00, $60, $00, $C0, $00, $F8, $00, $CC, $00, $CC, $00, $78, $00, $00, $00
|
|
80
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
81
|
+
; 0x37 '7'
|
|
82
|
+
.db $FC, $00, $CC, $00, $0C, $00, $18, $00, $30, $00, $30, $00, $30, $00, $00, $00
|
|
83
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
84
|
+
; 0x38 '8'
|
|
85
|
+
.db $78, $00, $CC, $00, $CC, $00, $78, $00, $CC, $00, $CC, $00, $78, $00, $00, $00
|
|
86
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
87
|
+
; 0x39 '9'
|
|
88
|
+
.db $78, $00, $CC, $00, $CC, $00, $7C, $00, $0C, $00, $18, $00, $70, $00, $00, $00
|
|
89
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
90
|
+
; 0x3A ':'
|
|
91
|
+
.db $00, $00, $30, $00, $30, $00, $00, $00, $00, $00, $30, $00, $30, $00, $00, $00
|
|
92
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
93
|
+
; 0x3B ';'
|
|
94
|
+
.db $00, $00, $30, $00, $30, $00, $00, $00, $00, $00, $30, $00, $30, $00, $60, $00
|
|
95
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
96
|
+
; 0x3C '<'
|
|
97
|
+
.db $18, $00, $30, $00, $60, $00, $C0, $00, $60, $00, $30, $00, $18, $00, $00, $00
|
|
98
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
99
|
+
; 0x3D '='
|
|
100
|
+
.db $00, $00, $00, $00, $FC, $00, $00, $00, $00, $00, $FC, $00, $00, $00, $00, $00
|
|
101
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
102
|
+
; 0x3E '>'
|
|
103
|
+
.db $60, $00, $30, $00, $18, $00, $0C, $00, $18, $00, $30, $00, $60, $00, $00, $00
|
|
104
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
105
|
+
; 0x3F '?'
|
|
106
|
+
.db $78, $00, $CC, $00, $0C, $00, $18, $00, $30, $00, $00, $00, $30, $00, $00, $00
|
|
107
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
108
|
+
; 0x40 '@'
|
|
109
|
+
.db $7C, $00, $C6, $00, $DE, $00, $DE, $00, $DE, $00, $C0, $00, $78, $00, $00, $00
|
|
110
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
111
|
+
; 0x41 'A'
|
|
112
|
+
.db $30, $00, $78, $00, $CC, $00, $CC, $00, $FC, $00, $CC, $00, $CC, $00, $00, $00
|
|
113
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
114
|
+
; 0x42 'B'
|
|
115
|
+
.db $FC, $00, $66, $00, $66, $00, $7C, $00, $66, $00, $66, $00, $FC, $00, $00, $00
|
|
116
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
117
|
+
; 0x43 'C'
|
|
118
|
+
.db $3C, $00, $66, $00, $C0, $00, $C0, $00, $C0, $00, $66, $00, $3C, $00, $00, $00
|
|
119
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
120
|
+
; 0x44 'D'
|
|
121
|
+
.db $F8, $00, $6C, $00, $66, $00, $66, $00, $66, $00, $6C, $00, $F8, $00, $00, $00
|
|
122
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
123
|
+
; 0x45 'E'
|
|
124
|
+
.db $FE, $00, $62, $00, $68, $00, $78, $00, $68, $00, $62, $00, $FE, $00, $00, $00
|
|
125
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
126
|
+
; 0x46 'F'
|
|
127
|
+
.db $FE, $00, $62, $00, $68, $00, $78, $00, $68, $00, $60, $00, $F0, $00, $00, $00
|
|
128
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
129
|
+
; 0x47 'G'
|
|
130
|
+
.db $3C, $00, $66, $00, $C0, $00, $C0, $00, $CE, $00, $66, $00, $3E, $00, $00, $00
|
|
131
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
132
|
+
; 0x48 'H'
|
|
133
|
+
.db $CC, $00, $CC, $00, $CC, $00, $FC, $00, $CC, $00, $CC, $00, $CC, $00, $00, $00
|
|
134
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
135
|
+
; 0x49 'I'
|
|
136
|
+
.db $78, $00, $30, $00, $30, $00, $30, $00, $30, $00, $30, $00, $78, $00, $00, $00
|
|
137
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
138
|
+
; 0x4A 'J'
|
|
139
|
+
.db $1E, $00, $0C, $00, $0C, $00, $0C, $00, $CC, $00, $CC, $00, $78, $00, $00, $00
|
|
140
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
141
|
+
; 0x4B 'K'
|
|
142
|
+
.db $E6, $00, $66, $00, $6C, $00, $78, $00, $6C, $00, $66, $00, $E6, $00, $00, $00
|
|
143
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
144
|
+
; 0x4C 'L'
|
|
145
|
+
.db $F0, $00, $60, $00, $60, $00, $60, $00, $62, $00, $66, $00, $FE, $00, $00, $00
|
|
146
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
147
|
+
; 0x4D 'M'
|
|
148
|
+
.db $C6, $00, $EE, $00, $FE, $00, $FE, $00, $D6, $00, $C6, $00, $C6, $00, $00, $00
|
|
149
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
150
|
+
; 0x4E 'N'
|
|
151
|
+
.db $C6, $00, $E6, $00, $F6, $00, $DE, $00, $CE, $00, $C6, $00, $C6, $00, $00, $00
|
|
152
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
153
|
+
; 0x4F 'O'
|
|
154
|
+
.db $38, $00, $6C, $00, $C6, $00, $C6, $00, $C6, $00, $6C, $00, $38, $00, $00, $00
|
|
155
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
156
|
+
; 0x50 'P'
|
|
157
|
+
.db $FC, $00, $66, $00, $66, $00, $7C, $00, $60, $00, $60, $00, $F0, $00, $00, $00
|
|
158
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
159
|
+
; 0x51 'Q'
|
|
160
|
+
.db $78, $00, $CC, $00, $CC, $00, $CC, $00, $DC, $00, $78, $00, $1C, $00, $00, $00
|
|
161
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
162
|
+
; 0x52 'R'
|
|
163
|
+
.db $FC, $00, $66, $00, $66, $00, $7C, $00, $6C, $00, $66, $00, $E6, $00, $00, $00
|
|
164
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
165
|
+
; 0x53 'S'
|
|
166
|
+
.db $78, $00, $CC, $00, $E0, $00, $70, $00, $1C, $00, $CC, $00, $78, $00, $00, $00
|
|
167
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
168
|
+
; 0x54 'T'
|
|
169
|
+
.db $FC, $00, $B4, $00, $30, $00, $30, $00, $30, $00, $30, $00, $78, $00, $00, $00
|
|
170
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
171
|
+
; 0x55 'U'
|
|
172
|
+
.db $CC, $00, $CC, $00, $CC, $00, $CC, $00, $CC, $00, $CC, $00, $FC, $00, $00, $00
|
|
173
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
174
|
+
; 0x56 'V'
|
|
175
|
+
.db $CC, $00, $CC, $00, $CC, $00, $CC, $00, $CC, $00, $78, $00, $30, $00, $00, $00
|
|
176
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
177
|
+
; 0x57 'W'
|
|
178
|
+
.db $C6, $00, $C6, $00, $C6, $00, $D6, $00, $FE, $00, $EE, $00, $C6, $00, $00, $00
|
|
179
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
180
|
+
; 0x58 'X'
|
|
181
|
+
.db $C6, $00, $C6, $00, $6C, $00, $38, $00, $38, $00, $6C, $00, $C6, $00, $00, $00
|
|
182
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
183
|
+
; 0x59 'Y'
|
|
184
|
+
.db $CC, $00, $CC, $00, $CC, $00, $78, $00, $30, $00, $30, $00, $78, $00, $00, $00
|
|
185
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
186
|
+
; 0x5A 'Z'
|
|
187
|
+
.db $FE, $00, $C6, $00, $8C, $00, $18, $00, $32, $00, $66, $00, $FE, $00, $00, $00
|
|
188
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
189
|
+
; 0x5B '['
|
|
190
|
+
.db $78, $00, $60, $00, $60, $00, $60, $00, $60, $00, $60, $00, $78, $00, $00, $00
|
|
191
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
192
|
+
; 0x5C 'backslash'
|
|
193
|
+
.db $C0, $00, $60, $00, $30, $00, $18, $00, $0C, $00, $06, $00, $02, $00, $00, $00
|
|
194
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
195
|
+
; 0x5D ']'
|
|
196
|
+
.db $78, $00, $18, $00, $18, $00, $18, $00, $18, $00, $18, $00, $78, $00, $00, $00
|
|
197
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
198
|
+
; 0x5E '^'
|
|
199
|
+
.db $10, $00, $38, $00, $6C, $00, $C6, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
200
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
201
|
+
; 0x5F '_'
|
|
202
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $FF, $00
|
|
203
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
204
|
+
; 0x60 '`'
|
|
205
|
+
.db $30, $00, $30, $00, $18, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
206
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
207
|
+
; 0x61 'a'
|
|
208
|
+
.db $00, $00, $00, $00, $78, $00, $0C, $00, $7C, $00, $CC, $00, $76, $00, $00, $00
|
|
209
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
210
|
+
; 0x62 'b'
|
|
211
|
+
.db $E0, $00, $60, $00, $60, $00, $7C, $00, $66, $00, $66, $00, $DC, $00, $00, $00
|
|
212
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
213
|
+
; 0x63 'c'
|
|
214
|
+
.db $00, $00, $00, $00, $78, $00, $CC, $00, $C0, $00, $CC, $00, $78, $00, $00, $00
|
|
215
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
216
|
+
; 0x64 'd'
|
|
217
|
+
.db $1C, $00, $0C, $00, $0C, $00, $7C, $00, $CC, $00, $CC, $00, $76, $00, $00, $00
|
|
218
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
219
|
+
; 0x65 'e'
|
|
220
|
+
.db $00, $00, $00, $00, $78, $00, $CC, $00, $FC, $00, $C0, $00, $78, $00, $00, $00
|
|
221
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
222
|
+
; 0x66 'f'
|
|
223
|
+
.db $38, $00, $6C, $00, $60, $00, $F0, $00, $60, $00, $60, $00, $F0, $00, $00, $00
|
|
224
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
225
|
+
; 0x67 'g'
|
|
226
|
+
.db $00, $00, $00, $00, $76, $00, $CC, $00, $CC, $00, $7C, $00, $0C, $00, $F8, $00
|
|
227
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
228
|
+
; 0x68 'h'
|
|
229
|
+
.db $E0, $00, $60, $00, $6C, $00, $76, $00, $66, $00, $66, $00, $E6, $00, $00, $00
|
|
230
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
231
|
+
; 0x69 'i'
|
|
232
|
+
.db $30, $00, $00, $00, $70, $00, $30, $00, $30, $00, $30, $00, $78, $00, $00, $00
|
|
233
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
234
|
+
; 0x6A 'j'
|
|
235
|
+
.db $0C, $00, $00, $00, $0C, $00, $0C, $00, $0C, $00, $CC, $00, $CC, $00, $78, $00
|
|
236
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
237
|
+
; 0x6B 'k'
|
|
238
|
+
.db $E0, $00, $60, $00, $66, $00, $6C, $00, $78, $00, $6C, $00, $E6, $00, $00, $00
|
|
239
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
240
|
+
; 0x6C 'l'
|
|
241
|
+
.db $70, $00, $30, $00, $30, $00, $30, $00, $30, $00, $30, $00, $78, $00, $00, $00
|
|
242
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
243
|
+
; 0x6D 'm'
|
|
244
|
+
.db $00, $00, $00, $00, $CC, $00, $FE, $00, $FE, $00, $D6, $00, $C6, $00, $00, $00
|
|
245
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
246
|
+
; 0x6E 'n'
|
|
247
|
+
.db $00, $00, $00, $00, $F8, $00, $CC, $00, $CC, $00, $CC, $00, $CC, $00, $00, $00
|
|
248
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
249
|
+
; 0x6F 'o'
|
|
250
|
+
.db $00, $00, $00, $00, $78, $00, $CC, $00, $CC, $00, $CC, $00, $78, $00, $00, $00
|
|
251
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
252
|
+
; 0x70 'p'
|
|
253
|
+
.db $00, $00, $00, $00, $DC, $00, $66, $00, $66, $00, $7C, $00, $60, $00, $F0, $00
|
|
254
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
255
|
+
; 0x71 'q'
|
|
256
|
+
.db $00, $00, $00, $00, $76, $00, $CC, $00, $CC, $00, $7C, $00, $0C, $00, $1E, $00
|
|
257
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
258
|
+
; 0x72 'r'
|
|
259
|
+
.db $00, $00, $00, $00, $DC, $00, $76, $00, $66, $00, $60, $00, $F0, $00, $00, $00
|
|
260
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
261
|
+
; 0x73 's'
|
|
262
|
+
.db $00, $00, $00, $00, $7C, $00, $C0, $00, $78, $00, $0C, $00, $F8, $00, $00, $00
|
|
263
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
264
|
+
; 0x74 't'
|
|
265
|
+
.db $10, $00, $30, $00, $7C, $00, $30, $00, $30, $00, $34, $00, $18, $00, $00, $00
|
|
266
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
267
|
+
; 0x75 'u'
|
|
268
|
+
.db $00, $00, $00, $00, $CC, $00, $CC, $00, $CC, $00, $CC, $00, $76, $00, $00, $00
|
|
269
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
270
|
+
; 0x76 'v'
|
|
271
|
+
.db $00, $00, $00, $00, $CC, $00, $CC, $00, $CC, $00, $78, $00, $30, $00, $00, $00
|
|
272
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
273
|
+
; 0x77 'w'
|
|
274
|
+
.db $00, $00, $00, $00, $C6, $00, $D6, $00, $FE, $00, $FE, $00, $6C, $00, $00, $00
|
|
275
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
276
|
+
; 0x78 'x'
|
|
277
|
+
.db $00, $00, $00, $00, $C6, $00, $6C, $00, $38, $00, $6C, $00, $C6, $00, $00, $00
|
|
278
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
279
|
+
; 0x79 'y'
|
|
280
|
+
.db $00, $00, $00, $00, $CC, $00, $CC, $00, $CC, $00, $7C, $00, $0C, $00, $F8, $00
|
|
281
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
282
|
+
; 0x7A 'z'
|
|
283
|
+
.db $00, $00, $00, $00, $FC, $00, $98, $00, $30, $00, $64, $00, $FC, $00, $00, $00
|
|
284
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
285
|
+
; 0x7B '{'
|
|
286
|
+
.db $1C, $00, $30, $00, $30, $00, $E0, $00, $30, $00, $30, $00, $1C, $00, $00, $00
|
|
287
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
288
|
+
; 0x7C '|'
|
|
289
|
+
.db $18, $00, $18, $00, $18, $00, $00, $00, $18, $00, $18, $00, $18, $00, $00, $00
|
|
290
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
291
|
+
; 0x7D '}'
|
|
292
|
+
.db $E0, $00, $30, $00, $30, $00, $1C, $00, $30, $00, $30, $00, $E0, $00, $00, $00
|
|
293
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
294
|
+
; 0x7E '~'
|
|
295
|
+
.db $76, $00, $DC, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
296
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
297
|
+
; 0x7F 'del'
|
|
298
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
299
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
|
|
9
300
|
|
|
10
301
|
palfont:
|
|
11
|
-
|
|
302
|
+
; 16-colour text palette (32 bytes, BGR555): colour 0 transparent
|
|
303
|
+
; (backdrop shows through), colour 1 white (the text colour).
|
|
304
|
+
.db $00, $00 ; 0 transparent
|
|
305
|
+
.db $FF, $7F ; 1 white
|
|
306
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
307
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
308
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
309
|
+
.db $00, $00
|
|
12
310
|
|
|
13
311
|
tilsprite:
|
|
14
312
|
; Tile 0 — solid 8×8 block, colour 1
|
|
@@ -16,6 +16,10 @@
|
|
|
16
16
|
extern char tilfont, palfont;
|
|
17
17
|
extern char tilsprite, palsprite;
|
|
18
18
|
|
|
19
|
+
/* consoleVblank() copies the dirty text tilemap to VRAM during VBlank.
|
|
20
|
+
* No public prototype in console.h, so declare it; call once per frame. */
|
|
21
|
+
extern void consoleVblank(void);
|
|
22
|
+
|
|
19
23
|
#define COURT_TOP 16
|
|
20
24
|
#define COURT_BOT 208
|
|
21
25
|
#define PADDLE_H 24
|
|
@@ -23,6 +27,12 @@ extern char tilsprite, palsprite;
|
|
|
23
27
|
#define PADDLE_X1 16
|
|
24
28
|
#define PADDLE_X2 232
|
|
25
29
|
|
|
30
|
+
/* oamSet's FIRST arg is a BYTE OFFSET into OAM, not a slot number: slot N lives
|
|
31
|
+
* at byte offset N*4. Passing the raw slot writes every sprite into OAM bytes
|
|
32
|
+
* 0-9, corrupting each other → black/garbled screen. (The shmup scaffold gets
|
|
33
|
+
* this right; sports/racing did not — SNES-1.) */
|
|
34
|
+
#define SPR(slot) ((slot) << 2)
|
|
35
|
+
|
|
26
36
|
static s16 p1y, p2y, bx, by;
|
|
27
37
|
static s8 bdx, bdy;
|
|
28
38
|
static u16 score_p1, score_p2;
|
|
@@ -53,6 +63,25 @@ static void render_scores(void) {
|
|
|
53
63
|
consoleDrawText(24, 2, buf);
|
|
54
64
|
}
|
|
55
65
|
|
|
66
|
+
/* Draw a Pong court out of font glyphs on the text BG (no extra tile
|
|
67
|
+
* data needed): a dashed rail across the top and bottom of the playfield
|
|
68
|
+
* plus a dashed centre net. The text grid is 32x28 cells (8px each). */
|
|
69
|
+
#define COURT_NET_COL 16
|
|
70
|
+
#define COURT_ROW_TOP 4
|
|
71
|
+
#define COURT_ROW_BOT 23
|
|
72
|
+
static void draw_court(void) {
|
|
73
|
+
char rail[29];
|
|
74
|
+
u16 i;
|
|
75
|
+
for (i = 0; i < 28; i++) rail[i] = '-';
|
|
76
|
+
rail[28] = 0;
|
|
77
|
+
consoleDrawText(2, COURT_ROW_TOP, rail);
|
|
78
|
+
consoleDrawText(2, COURT_ROW_BOT, rail);
|
|
79
|
+
/* Dashed centre net: a ':' every other row between the rails. */
|
|
80
|
+
for (i = COURT_ROW_TOP + 1; i < COURT_ROW_BOT; i += 2) {
|
|
81
|
+
consoleDrawText(COURT_NET_COL, i, ":");
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
56
85
|
int main(void) {
|
|
57
86
|
u16 p1, p2;
|
|
58
87
|
u16 i, slot;
|
|
@@ -60,9 +89,13 @@ int main(void) {
|
|
|
60
89
|
|
|
61
90
|
consoleSetTextMapPtr(0x6800);
|
|
62
91
|
consoleSetTextGfxPtr(0x3000);
|
|
63
|
-
consoleSetTextOffset(
|
|
92
|
+
consoleSetTextOffset(0x0000); /* tile index = (char-0x20); font is at the BG char base */
|
|
64
93
|
consoleInitText(0, 16 * 2, &tilfont, &palfont);
|
|
65
94
|
setMode(BG_MODE1, 0);
|
|
95
|
+
/* consoleInitText DMAs the font but does NOT set the PPU BG base
|
|
96
|
+
* registers — point BG0 at the same font ($3000) + map ($6800). */
|
|
97
|
+
bgSetGfxPtr(0, 0x3000);
|
|
98
|
+
bgSetMapPtr(0, 0x6800, SC_32x32);
|
|
66
99
|
bgSetDisable(1);
|
|
67
100
|
bgSetDisable(2);
|
|
68
101
|
|
|
@@ -71,9 +104,10 @@ int main(void) {
|
|
|
71
104
|
consoleDrawText(2, 1, "P1");
|
|
72
105
|
consoleDrawText(28, 1, "P2");
|
|
73
106
|
consoleDrawText(6, 26, "UP/DOWN MOVES YOUR PADDLE");
|
|
107
|
+
draw_court(); /* dashed rails + centre net (font glyphs, no extra tiles) */
|
|
74
108
|
|
|
75
109
|
/* Hide all OAM slots initially. */
|
|
76
|
-
for (i = 0; i < 7; i++) oamSet(i, 0, 240, 3, 0, 0, 0, 0);
|
|
110
|
+
for (i = 0; i < 7; i++) oamSet(SPR(i), 0, 240, 3, 0, 0, 0, 0);
|
|
77
111
|
|
|
78
112
|
setScreenOn();
|
|
79
113
|
sfx_init();
|
|
@@ -83,15 +117,16 @@ int main(void) {
|
|
|
83
117
|
slot = 0;
|
|
84
118
|
/* Left paddle = 3 stacked 8×8 sprites */
|
|
85
119
|
for (i = 0; i < PADDLE_H / 8; i++) {
|
|
86
|
-
oamSet(slot
|
|
120
|
+
oamSet(SPR(slot++), PADDLE_X1, (u16)(p1y + i * 8), 3, 0, 0, 0, 0);
|
|
87
121
|
}
|
|
88
122
|
for (i = 0; i < PADDLE_H / 8; i++) {
|
|
89
|
-
oamSet(slot
|
|
123
|
+
oamSet(SPR(slot++), PADDLE_X2, (u16)(p2y + i * 8), 3, 0, 0, 0, 0);
|
|
90
124
|
}
|
|
91
|
-
oamSet(slot
|
|
125
|
+
oamSet(SPR(slot++), bx, by, 3, 0, 0, 0, 0);
|
|
92
126
|
oamUpdate();
|
|
93
127
|
render_scores();
|
|
94
128
|
WaitForVBlank();
|
|
129
|
+
consoleVblank();
|
|
95
130
|
|
|
96
131
|
p1 = padsCurrent(0);
|
|
97
132
|
p2 = padsCurrent(1);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "romdevtools",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"description": "Tool server giving coding agents full control of homebrew ROM development AND reverse-engineering/romhacking across 14 retro platforms (NES, SNES, GB, Genesis, Atari, C64, PC Engine, MSX, ...) via WASM toolchains + emulator cores. Use over plain HTTP, as an Agent Skill, or as an MCP server.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/mcp/server.js",
|
package/src/http/skill-doc.js
CHANGED
|
@@ -18,7 +18,7 @@ import { toolJsonSchema } from "./tool-registry.js";
|
|
|
18
18
|
*/
|
|
19
19
|
export const mcpPreamble = [
|
|
20
20
|
"romdev: homebrew retro game development + reverse-engineering for coding agents.",
|
|
21
|
-
"All ~
|
|
21
|
+
"All ~32 tools register at session init — call any by name directly, no loading step. Each is a domain VERB with an operation axis: memory({op}), build({output}), breakpoint({on}), cpu({op}), sprites({op}), tiles({op}), disasm({target}), romPatch({op}), …",
|
|
22
22
|
"catalog({op:'categories'}) maps the tools by purpose (a guide, not a gate); catalog({op:'status'}) is a session re-orient.",
|
|
23
23
|
].join("\n");
|
|
24
24
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Tool registry harvester — the single source the HTTP route/skill/OpenAPI
|
|
2
2
|
// surfaces build from.
|
|
3
3
|
//
|
|
4
|
-
// The MCP path registers
|
|
4
|
+
// The MCP path registers 32 tools via registerTools(server, z, sessionKey),
|
|
5
5
|
// where `server` is an McpServer and each handler closes over `sessionKey` for
|
|
6
6
|
// per-session host isolation. The HTTP surfaces (POST /tool/{name},
|
|
7
7
|
// /skills/romdev/SKILL.md, /openapi.json, /documentation) want the EXACT same handlers,
|
package/src/mcp/tools/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Register MCP tools on the server.
|
|
2
2
|
//
|
|
3
|
-
// The surface is ~
|
|
3
|
+
// The surface is ~32 consolidated domain tools (memory({op}), build({output}),
|
|
4
4
|
// breakpoint({on}), …) and EVERY one registers at session init. There is no
|
|
5
5
|
// progressive-disclosure / lean mode anymore: the dynamic loadCategory dance
|
|
6
6
|
// never propagated reliably to clients (they don't re-read tools/list after a
|
|
@@ -208,7 +208,7 @@ export function registerTools(server, z, sessionKey) {
|
|
|
208
208
|
if (!sessionKey) sessionKey = randomUUID();
|
|
209
209
|
// Clear validation errors for EVERY tool registered below: turns the SDK's
|
|
210
210
|
// raw JSON validation dump into a plain sentence and catches unknown/misspelled
|
|
211
|
-
// params (which the SDK otherwise drops silently). One wrap, all
|
|
211
|
+
// params (which the SDK otherwise drops silently). One wrap, all 32 tools.
|
|
212
212
|
// This is what lets the param descriptions stay terse — the guidance lives in
|
|
213
213
|
// the error (paid only on a bad call), not in every agent's initial context.
|
|
214
214
|
server = withClearToolErrors(server, z);
|
|
@@ -259,7 +259,7 @@ export function registerTools(server, z, sessionKey) {
|
|
|
259
259
|
);
|
|
260
260
|
|
|
261
261
|
// loadCategory + describeTool DELETED with the progressive-disclosure path:
|
|
262
|
-
// the whole surface is ~
|
|
262
|
+
// the whole surface is ~32 tools now and every one registers at session init,
|
|
263
263
|
// so the dynamic lean-mode dance (which never worked reliably — clients don't
|
|
264
264
|
// re-read tools/list after list_changed) has no reason to exist. `catalog`
|
|
265
265
|
// still exposes the category map for orientation. (See the consolidation.)
|
|
@@ -293,7 +293,7 @@ export function registerTools(server, z, sessionKey) {
|
|
|
293
293
|
// So by default we register EVERY category at session init. listCategories
|
|
294
294
|
// / loadCategory still exist (idempotent, harmless) for clients that probe
|
|
295
295
|
// Register EVERY category now — there is no lean/deferred mode anymore. The
|
|
296
|
-
// surface is small enough (~
|
|
296
|
+
// surface is small enough (~32 tools) that loading it all up front is the
|
|
297
297
|
// right call (the dynamic loadCategory dance never propagated reliably to
|
|
298
298
|
// clients). `disclosure.loadCategory("all")` is just the internal "register
|
|
299
299
|
// all categories" helper here, not a user-facing tool.
|
package/src/mcp/tools/project.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// Policy (2026-05-25): no auto-injection at build time. createProject copies
|
|
4
4
|
// every file the template depends on (runtime, headers, crt0, linker .cfg)
|
|
5
5
|
// into the project directory. The project is then self-contained — any
|
|
6
|
-
// `
|
|
6
|
+
// `build({output:'run'})` call points at the project's own files via
|
|
7
7
|
// sources/sourcesPaths/includePaths/crt0/linkerConfig args. If you take
|
|
8
8
|
// the project elsewhere and rebuild with cc65/sdcc directly, every byte
|
|
9
9
|
// that compiles is in the directory.
|
|
@@ -1086,7 +1086,7 @@ TEMPLATES.gba = {
|
|
|
1086
1086
|
runtimeDirs: GBA_LIBTONC_RUNTIME_DIRS,
|
|
1087
1087
|
lang: GBA_TONC_LANG,
|
|
1088
1088
|
ext: ".gba",
|
|
1089
|
-
describe: "Idiomatic Tonc-tutorial GBA C starter. #include <tonc.h>, TTE (Tonc Text Engine) draws 'Hello, Tonc!' on BG0 in MODE_0. Matches what every published GBA C tutorial at gbadev.net teaches. libtonc is compiled from its vendored source by the build (a fast prebuilt seed by default; pass rebuildSdk:true if you edit the SDK source) — the project gets the headers + gba_crt0 + linker script. Build with
|
|
1089
|
+
describe: "Idiomatic Tonc-tutorial GBA C starter. #include <tonc.h>, TTE (Tonc Text Engine) draws 'Hello, Tonc!' on BG0 in MODE_0. Matches what every published GBA C tutorial at gbadev.net teaches. libtonc is compiled from its vendored source by the build (a fast prebuilt seed by default; pass rebuildSdk:true if you edit the SDK source) — the project gets the headers + gba_crt0 + linker script. Build with build({output:'run', platform:'gba', language:'c'}) — defaults to runtime:'libtonc'.",
|
|
1090
1090
|
},
|
|
1091
1091
|
tonc_hello_sprite: {
|
|
1092
1092
|
main: "templates/tonc_hello_sprite.c",
|
|
@@ -1144,10 +1144,10 @@ TEMPLATES.gba = {
|
|
|
1144
1144
|
runtimeDirs: GBA_LIBGBA_RUNTIME_DIRS,
|
|
1145
1145
|
lang: GBA_LIBGBA_LANG,
|
|
1146
1146
|
ext: ".gba",
|
|
1147
|
-
describe: "Alternate GBA C starter using devkitPro's libgba SDK. MODE_3 framebuffer + red pixel. Pass runtime:'libgba' to
|
|
1147
|
+
describe: "Alternate GBA C starter using devkitPro's libgba SDK. MODE_3 framebuffer + red pixel. Pass runtime:'libgba' to build({output:'run'}) — or just use the Tonc path (gba_hello_tonc) which is better aligned with what published tutorials teach.",
|
|
1148
1148
|
},
|
|
1149
1149
|
// R34: maxmod music demo. Ships a hand-authored CC0 chiptune.xm +
|
|
1150
|
-
// its pre-built soundbank.bin.
|
|
1150
|
+
// its pre-built soundbank.bin. build({output:'run'}) must be called with
|
|
1151
1151
|
// `maxmod: true` AND binaryIncludes:{ "soundbank.bin": <bytes> } —
|
|
1152
1152
|
// the buildGbaC layer auto-emits a `.incbin "soundbank.bin"` asm
|
|
1153
1153
|
// stub exposing the soundbank under the global symbol soundbank_bin.
|
|
@@ -1173,7 +1173,7 @@ TEMPLATES.gba = {
|
|
|
1173
1173
|
ext: ".gba",
|
|
1174
1174
|
maxmod: true,
|
|
1175
1175
|
binaryIncludes: ["soundbank.bin"],
|
|
1176
|
-
describe: "Maxmod music demo (Tonc + libmm). Plays a CC0 chiptune.xm soundbank via mmInitDefault + mmStart + mmFrame, with START toggling pause. Pass `maxmod:true` AND `binaryIncludes:{\"soundbank.bin\": <bytes>}` to
|
|
1176
|
+
describe: "Maxmod music demo (Tonc + libmm). Plays a CC0 chiptune.xm soundbank via mmInitDefault + mmStart + mmFrame, with START toggling pause. Pass `maxmod:true` AND `binaryIncludes:{\"soundbank.bin\": <bytes>}` to build({output:'run'}). The .xm source + generator script + pre-built soundbank.bin all ship in the project — edit and re-run mmutil to swap the tune.",
|
|
1177
1177
|
},
|
|
1178
1178
|
};
|
|
1179
1179
|
|
|
@@ -1558,11 +1558,11 @@ Compiles **C89**, not C99/C11. Stick to:
|
|
|
1558
1558
|
const incLines = runtimeHeaders.length > 0
|
|
1559
1559
|
? runtimeHeaders.map((h) => ` "${h.dst}": "${h.dst}",`).join("\n")
|
|
1560
1560
|
: "";
|
|
1561
|
-
buildBlock = "```js\
|
|
1561
|
+
buildBlock = "```js\nbuild({\n output: \"run\",\n platform: \"" + platform + "\",\n sourcesPaths: {\n" + srcLines + "\n },\n" + (incLines ? " includePaths: {\n" + incLines + "\n },\n" : "") + " linkerConfig: /* contents of " + tmpl.linkerConfig.dst + " */,\n frames: 240,\n})\n```";
|
|
1562
1562
|
} else if (isSdccSm83) {
|
|
1563
|
-
// GB / GBC (SDCC sm83).
|
|
1564
|
-
// call AND auto-fixes the cartridge header (Nintendo logo, header +
|
|
1565
|
-
// global checksums, CGB flag on .gbc) — no manual
|
|
1563
|
+
// GB / GBC (SDCC sm83). build({output:'run'}) BUILDS + RUNS + SCREENSHOTS
|
|
1564
|
+
// in one call AND auto-fixes the cartridge header (Nintendo logo, header +
|
|
1565
|
+
// global checksums, CGB flag on .gbc) — no manual header-patch step.
|
|
1566
1566
|
// Derive sources/includes from the template's runtime list so extra
|
|
1567
1567
|
// .c files (e.g. music_demo's hUGEDriver) are listed too.
|
|
1568
1568
|
const runtimeCs = (tmpl?.runtime ?? []).filter((r) => /\.c$/i.test(r.dst));
|
|
@@ -1573,7 +1573,7 @@ Compiles **C89**, not C99/C11. Stick to:
|
|
|
1573
1573
|
? runtimeHeaders.map((h) => ` "${h.dst}": "${h.dst}",`).join("\n")
|
|
1574
1574
|
: "";
|
|
1575
1575
|
buildBlock =
|
|
1576
|
-
"```js\
|
|
1576
|
+
"```js\nbuild({\n output: \"run\",\n" +
|
|
1577
1577
|
" platform: \"" + platform + "\",\n" +
|
|
1578
1578
|
" sourcesPaths: {\n" + srcLines + "\n },\n" +
|
|
1579
1579
|
(incLines ? " includePaths: {\n" + incLines + "\n },\n" : "") +
|
|
@@ -1581,7 +1581,7 @@ Compiles **C89**, not C99/C11. Stick to:
|
|
|
1581
1581
|
" codeLoc: 0x150,\n" +
|
|
1582
1582
|
" frames: 60,\n" +
|
|
1583
1583
|
"})\n```\n\n" +
|
|
1584
|
-
"`
|
|
1584
|
+
"`build({output:\"run\"})` auto-fixes the GB/GBC cartridge header (logo, checksums, " +
|
|
1585
1585
|
"CGB flag) — you do **not** call a header patch for a freshly built " +
|
|
1586
1586
|
"ROM. Use `romPatch({op:'gbHeader'})` only to fix up an existing/external " +
|
|
1587
1587
|
"ROM on disk or to override header fields (title, cart type, ROM/RAM size).";
|
|
@@ -1589,12 +1589,12 @@ Compiles **C89**, not C99/C11. Stick to:
|
|
|
1589
1589
|
const inc = runtimeHeaders.length > 0
|
|
1590
1590
|
? `\n includePaths: { ${runtimeHeaders.map((h) => `"${h.dst}": "${h.dst}"`).join(", ")} },`
|
|
1591
1591
|
: "";
|
|
1592
|
-
buildBlock = "```js\
|
|
1592
|
+
buildBlock = "```js\nbuild({\n output: \"run\",\n platform: \"" + platform + "\",\n sourcePath: \"" + mainFilename + "\"," + inc + "\n frames: 240,\n})\n```";
|
|
1593
1593
|
} else if (platform === "c64") {
|
|
1594
1594
|
const inc = runtimeHeaders.length > 0
|
|
1595
1595
|
? `\n includePaths: { ${runtimeHeaders.map((h) => `"${h.dst}": "${h.dst}"`).join(", ")} },`
|
|
1596
1596
|
: "";
|
|
1597
|
-
buildBlock = "```js\
|
|
1597
|
+
buildBlock = "```js\nbuild({\n output: \"run\",\n platform: \"c64\",\n sourcePath: \"" + mainFilename + "\"," + inc + "\n frames: 240,\n})\n```";
|
|
1598
1598
|
} else if (platform === "snes" && /\.c$/i.test(mainFilename)) {
|
|
1599
1599
|
// R19b: SNES C-mode template (PVSnesLib runtime auto-linked). Multi-file
|
|
1600
1600
|
// build with sibling .asm providing data symbols (tilfont/palfont).
|
|
@@ -1631,7 +1631,7 @@ Compiles **C89**, not C99/C11. Stick to:
|
|
|
1631
1631
|
.join("\n");
|
|
1632
1632
|
|
|
1633
1633
|
buildBlock =
|
|
1634
|
-
"```js\
|
|
1634
|
+
"```js\nbuild({\n output: \"run\",\n" +
|
|
1635
1635
|
" platform: \"snes\",\n" +
|
|
1636
1636
|
" language: \"c\",\n" +
|
|
1637
1637
|
" sourcesPaths: {\n" + sourceLines + "\n },\n" +
|
|
@@ -1672,12 +1672,12 @@ Compiles **C89**, not C99/C11. Stick to:
|
|
|
1672
1672
|
const incLine = runtimeHs.length > 0
|
|
1673
1673
|
? `\n includePaths: {\n${runtimeHs.map((r) => ` "${r.dst}": "${r.dst}",`).join("\n")}\n },`
|
|
1674
1674
|
: "";
|
|
1675
|
-
buildBlock = "```js\
|
|
1675
|
+
buildBlock = "```js\nbuild({\n output: \"run\",\n platform: \"" + platform + "\",\n language: \"c\",\n sourcesPaths: {\n" + srcLines + "\n }," + incLine + "\n frames: 240,\n})\n```";
|
|
1676
1676
|
} else {
|
|
1677
1677
|
const inc = runtimeAsmIncludes.length > 0
|
|
1678
1678
|
? `\n includePaths: { ${runtimeAsmIncludes.map((r) => `"${r.dst}": "${r.dst}"`).join(", ")} },`
|
|
1679
1679
|
: "";
|
|
1680
|
-
buildBlock = "```js\
|
|
1680
|
+
buildBlock = "```js\nbuild({\n output: \"run\",\n platform: \"" + platform + "\",\n sourcePath: \"" + mainFilename + "\"," + inc + "\n frames: 240,\n})\n```";
|
|
1681
1681
|
}
|
|
1682
1682
|
} else if (platform === "gba") {
|
|
1683
1683
|
// GBA libtonc / libgba runtimes ship gba_sfx.{h,c} as a tiny DMG-APU
|
|
@@ -1692,12 +1692,12 @@ Compiles **C89**, not C99/C11. Stick to:
|
|
|
1692
1692
|
const incLine = runtimeHs.length > 0
|
|
1693
1693
|
? `\n includePaths: {\n${runtimeHs.map((r) => ` "${r.dst}": "${r.dst}",`).join("\n")}\n },`
|
|
1694
1694
|
: "";
|
|
1695
|
-
buildBlock = "```js\
|
|
1695
|
+
buildBlock = "```js\nbuild({\n output: \"run\",\n platform: \"gba\",\n language: \"c\",\n sourcesPaths: {\n" + srcLines + "\n }," + incLine + "\n frames: 240,\n})\n```";
|
|
1696
1696
|
} else {
|
|
1697
|
-
buildBlock = "```js\
|
|
1697
|
+
buildBlock = "```js\nbuild({ output: \"run\", platform: \"gba\", language: \"c\", sourcePath: \"" + mainFilename + "\", frames: 240 })\n```";
|
|
1698
1698
|
}
|
|
1699
1699
|
} else {
|
|
1700
|
-
buildBlock = "```js\
|
|
1700
|
+
buildBlock = "```js\nbuild({ output: \"run\", platform: \"" + platform + "\", sourcePath: \"" + mainFilename + "\", frames: 240 })\n```";
|
|
1701
1701
|
}
|
|
1702
1702
|
|
|
1703
1703
|
let filesSection = `## Files\n\n- \`${mainFilename}\` — your game's entry point.\n`;
|
|
@@ -1714,7 +1714,7 @@ Compiles **C89**, not C99/C11. Stick to:
|
|
|
1714
1714
|
}
|
|
1715
1715
|
filesSection += `\nEvery byte that compiles into your ROM is in this directory. If you move the repo somewhere else, you don't need to install anything from romdev to rebuild it — the compiler binaries are the only external dependency.\n\n`;
|
|
1716
1716
|
|
|
1717
|
-
const readme = `# ${title ?? name}\n\nA ${lang} project for ${platform}, scaffolded by romdev.\n\n${tmpl?.describe ? tmpl.describe + "\n\n" : ""}${filesSection}${c89Note}## Build + run with romdev\n\n${buildBlock}\n\n## Iterating\n\n- Edit \`${mainFilename}\` (or any of the runtime / crt0 / cfg files — they're yours).\n- Call \`
|
|
1717
|
+
const readme = `# ${title ?? name}\n\nA ${lang} project for ${platform}, scaffolded by romdev.\n\n${tmpl?.describe ? tmpl.describe + "\n\n" : ""}${filesSection}${c89Note}## Build + run with romdev\n\n${buildBlock}\n\n## Iterating\n\n- Edit \`${mainFilename}\` (or any of the runtime / crt0 / cfg files — they're yours).\n- Call \`build({output:"run", ...})\` to see your changes. It builds + loads + runs + screenshots in one round trip.\n- Inspect at byte level: \`memory({op:"read"})\`, \`sprites({op:"inspect"})\`, \`palette({source:"live"})\`, \`background({view:"rendered"})\`.\n- Open a playtest window for human eyes: \`playtest({op:"open"})\` — returns immediately, the window follows your rebuilds, and the emulator stays live for every other tool.\n`;
|
|
1718
1718
|
await fs.writeFile(path.join(projPath, "README.md"), readme, "utf-8");
|
|
1719
1719
|
writtenFiles.push("README.md");
|
|
1720
1720
|
|
|
@@ -1783,7 +1783,7 @@ Compiles **C89**, not C99/C11. Stick to:
|
|
|
1783
1783
|
snippetsCopied: withSnippets ? snippetFiles : null,
|
|
1784
1784
|
sourceFile: path.join(projPath, mainFilename),
|
|
1785
1785
|
toolchain: lang,
|
|
1786
|
-
nextStep: `Edit ${path.join(projPath, mainFilename)} and call
|
|
1786
|
+
nextStep: `Edit ${path.join(projPath, mainFilename)} and call build({output:"run", ...}) with sourcesPaths/includePaths pointing at the project's files (see the README's "Build + run" block for the exact call). Everything you need is in the directory — nothing is hidden.`,
|
|
1787
1787
|
};
|
|
1788
1788
|
}
|
|
1789
1789
|
|
|
@@ -1810,10 +1810,21 @@ async function createGameCore({ platform, genre, name, path: projPath, title, ov
|
|
|
1810
1810
|
? CANONICAL_GENRES.filter((g) => platformTemplates[g])
|
|
1811
1811
|
: [];
|
|
1812
1812
|
if (availableGenres.length === 0) {
|
|
1813
|
+
// Point at the real, working project templates each genre-less
|
|
1814
|
+
// platform actually ships, so the agent has a concrete next step
|
|
1815
|
+
// instead of a bare "default".
|
|
1816
|
+
const PROJECT_TEMPLATE_HINTS = {
|
|
1817
|
+
msx: "default, sprite_move, music_sfx, catch_game",
|
|
1818
|
+
pce: "default, sprite_move, music_sfx, catch_game",
|
|
1819
|
+
atari2600: "default, single_screen, paddle, mini_invaders, music_demo",
|
|
1820
|
+
};
|
|
1821
|
+
const hint = PROJECT_TEMPLATE_HINTS[platform];
|
|
1813
1822
|
throw new Error(
|
|
1814
1823
|
`createGame: no genre scaffolds for platform '${platform}' yet. ` +
|
|
1815
1824
|
`Supported platforms: ${genrePlatforms.join(", ") || "(none)"}. ` +
|
|
1816
|
-
|
|
1825
|
+
(hint
|
|
1826
|
+
? `For ${platform}, use createProject({platform:"${platform}", template:"..."}) with one of: ${hint}.`
|
|
1827
|
+
: `For other platforms, use createProject({platform, template:"default"}) and build up from there.`)
|
|
1817
1828
|
);
|
|
1818
1829
|
}
|
|
1819
1830
|
if (!availableGenres.includes(genre)) {
|