romdevtools 0.28.0 → 0.30.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 (179) hide show
  1. package/AGENTS.md +53 -43
  2. package/CHANGELOG.md +91 -0
  3. package/README.md +3 -3
  4. package/examples/README.md +7 -7
  5. package/examples/atari2600/templates/platformer.asm +1225 -332
  6. package/examples/atari2600/templates/puzzle.asm +1056 -0
  7. package/examples/atari2600/templates/racing.asm +906 -275
  8. package/examples/atari2600/templates/shmup.asm +1031 -239
  9. package/examples/atari2600/templates/sports.asm +1135 -253
  10. package/examples/atari7800/templates/platformer.c +991 -156
  11. package/examples/atari7800/templates/puzzle.c +1091 -148
  12. package/examples/atari7800/templates/racing.c +952 -124
  13. package/examples/atari7800/templates/shmup.c +812 -134
  14. package/examples/atari7800/templates/sports.c +820 -184
  15. package/examples/c64/templates/platformer.c +879 -164
  16. package/examples/c64/templates/puzzle.c +855 -178
  17. package/examples/c64/templates/racing.c +873 -97
  18. package/examples/c64/templates/shmup.c +757 -161
  19. package/examples/c64/templates/sports.c +755 -100
  20. package/examples/gb/templates/platformer.c +841 -179
  21. package/examples/gb/templates/puzzle.c +986 -246
  22. package/examples/gb/templates/racing.c +754 -174
  23. package/examples/gb/templates/shmup.c +673 -175
  24. package/examples/gb/templates/sports.c +790 -159
  25. package/examples/gba/templates/platformer.c +626 -165
  26. package/examples/gba/templates/puzzle.c +519 -269
  27. package/examples/gba/templates/racing.c +511 -206
  28. package/examples/gba/templates/shmup.c +564 -179
  29. package/examples/gba/templates/sports.c +454 -174
  30. package/examples/gbc/templates/platformer.c +944 -180
  31. package/examples/gbc/templates/puzzle.c +363 -109
  32. package/examples/gbc/templates/racing.c +884 -180
  33. package/examples/gbc/templates/shmup.c +821 -185
  34. package/examples/gbc/templates/sports.c +870 -162
  35. package/examples/genesis/templates/platformer.c +747 -129
  36. package/examples/genesis/templates/puzzle.c +694 -261
  37. package/examples/genesis/templates/racing.c +726 -203
  38. package/examples/genesis/templates/shmup.c +535 -142
  39. package/examples/genesis/templates/sports.c +495 -158
  40. package/examples/gg/templates/platformer.c +880 -215
  41. package/examples/gg/templates/puzzle.c +875 -216
  42. package/examples/gg/templates/racing.c +915 -172
  43. package/examples/gg/templates/shmup.c +714 -191
  44. package/examples/gg/templates/sports.c +732 -129
  45. package/examples/lynx/templates/platformer.c +604 -69
  46. package/examples/lynx/templates/puzzle.c +498 -158
  47. package/examples/lynx/templates/racing.c +538 -102
  48. package/examples/lynx/templates/shmup.c +458 -131
  49. package/examples/lynx/templates/sports.c +496 -72
  50. package/examples/msx/platformer/main.c +649 -162
  51. package/examples/msx/puzzle/main.c +742 -240
  52. package/examples/msx/racing/main.c +669 -178
  53. package/examples/msx/shmup/main.c +460 -178
  54. package/examples/msx/sports/main.c +592 -126
  55. package/examples/nes/templates/platformer.c +589 -171
  56. package/examples/nes/templates/puzzle.c +563 -242
  57. package/examples/nes/templates/racing.c +502 -208
  58. package/examples/nes/templates/shmup.c +339 -145
  59. package/examples/nes/templates/sports.c +341 -183
  60. package/examples/pce/platformer/main.c +874 -205
  61. package/examples/pce/puzzle/main.c +802 -287
  62. package/examples/pce/racing/main.c +783 -208
  63. package/examples/pce/shmup/main.c +638 -212
  64. package/examples/pce/sports/main.c +586 -169
  65. package/examples/porting-across-platforms/README.md +1 -1
  66. package/examples/sms/templates/platformer.c +762 -177
  67. package/examples/sms/templates/puzzle.c +752 -212
  68. package/examples/sms/templates/racing.c +808 -145
  69. package/examples/sms/templates/shmup.c +599 -162
  70. package/examples/sms/templates/sports.c +630 -122
  71. package/examples/snes/templates/music_demo.c +7 -0
  72. package/examples/snes/templates/platformer-data.asm +123 -24
  73. package/examples/snes/templates/platformer-hdr.asm +57 -0
  74. package/examples/snes/templates/platformer.c +586 -165
  75. package/examples/snes/templates/puzzle-data.asm +116 -21
  76. package/examples/snes/templates/puzzle-hdr.asm +57 -0
  77. package/examples/snes/templates/puzzle.c +614 -235
  78. package/examples/snes/templates/racing-data.asm +390 -32
  79. package/examples/snes/templates/racing-hdr.asm +57 -0
  80. package/examples/snes/templates/racing.c +807 -196
  81. package/examples/snes/templates/shmup-data.asm +87 -29
  82. package/examples/snes/templates/shmup-hdr.asm +57 -0
  83. package/examples/snes/templates/shmup.c +459 -198
  84. package/examples/snes/templates/sports-data.asm +48 -2
  85. package/examples/snes/templates/sports-hdr.asm +57 -0
  86. package/examples/snes/templates/sports.c +414 -163
  87. package/package.json +12 -12
  88. package/src/cores/wasm/bluemsx_libretro.js +1 -1
  89. package/src/cores/wasm/bluemsx_libretro.wasm +0 -0
  90. package/src/cores/wasm/fceumm_libretro.js +1 -1
  91. package/src/cores/wasm/fceumm_libretro.wasm +0 -0
  92. package/src/cores/wasm/gambatte_libretro.js +1 -1
  93. package/src/cores/wasm/gambatte_libretro.wasm +0 -0
  94. package/src/cores/wasm/geargrafx_libretro.js +1 -1
  95. package/src/cores/wasm/geargrafx_libretro.wasm +0 -0
  96. package/src/cores/wasm/genesis_plus_gx_libretro.js +1 -1
  97. package/src/cores/wasm/genesis_plus_gx_libretro.wasm +0 -0
  98. package/src/cores/wasm/handy_libretro.js +1 -1
  99. package/src/cores/wasm/handy_libretro.wasm +0 -0
  100. package/src/cores/wasm/mgba_libretro.js +1 -1
  101. package/src/cores/wasm/mgba_libretro.wasm +0 -0
  102. package/src/cores/wasm/prosystem_libretro.js +1 -1
  103. package/src/cores/wasm/prosystem_libretro.wasm +0 -0
  104. package/src/cores/wasm/snes9x_libretro.js +1 -1
  105. package/src/cores/wasm/snes9x_libretro.wasm +0 -0
  106. package/src/cores/wasm/stella2014_libretro.js +1 -1
  107. package/src/cores/wasm/stella2014_libretro.wasm +0 -0
  108. package/src/cores/wasm/vice_x64_libretro.js +1 -1
  109. package/src/cores/wasm/vice_x64_libretro.wasm +0 -0
  110. package/src/host/LibretroHost.js +84 -8
  111. package/src/http/tool-registry.js +11 -11
  112. package/src/mcp/tools/cheats.js +2 -1
  113. package/src/mcp/tools/frame.js +3 -2
  114. package/src/mcp/tools/index.js +3 -3
  115. package/src/mcp/tools/input.js +5 -4
  116. package/src/mcp/tools/lifecycle.js +6 -4
  117. package/src/mcp/tools/memory.js +131 -24
  118. package/src/mcp/tools/platform-docs.js +1 -1
  119. package/src/mcp/tools/preview-tile.js +6 -2
  120. package/src/mcp/tools/project.js +1098 -130
  121. package/src/mcp/tools/record.js +6 -7
  122. package/src/mcp/tools/rom-id.js +5 -1
  123. package/src/mcp/tools/run-until.js +12 -4
  124. package/src/mcp/tools/snippets.js +6 -6
  125. package/src/mcp/tools/sprite-pipeline.js +14 -2
  126. package/src/mcp/tools/state.js +2 -1
  127. package/src/mcp/tools/tile-inspect.js +8 -1
  128. package/src/mcp/tools/toolchain.js +12 -1
  129. package/src/mcp/tools/watch-memory.js +53 -10
  130. package/src/observer/bus.js +73 -0
  131. package/src/observer/livestream.html +4 -2
  132. package/src/observer/tool-wrap.js +17 -14
  133. package/src/platforms/_guides/ROMHACKING_PLAYBOOK.md +32 -3
  134. package/src/platforms/atari7800/MENTAL_MODEL.md +5 -5
  135. package/src/platforms/atari7800/TROUBLESHOOTING.md +5 -5
  136. package/src/platforms/c64/MENTAL_MODEL.md +11 -4
  137. package/src/platforms/c64/TROUBLESHOOTING.md +13 -0
  138. package/src/platforms/gb/MENTAL_MODEL.md +3 -3
  139. package/src/platforms/gb/TROUBLESHOOTING.md +61 -8
  140. package/src/platforms/gb/lib/c/README.md +10 -11
  141. package/src/platforms/gb/lib/c/gb_crt0.s +27 -3
  142. package/src/platforms/gb/lib/c/patch-header.js +13 -3
  143. package/src/platforms/gba/MENTAL_MODEL.md +4 -4
  144. package/src/platforms/gba/TROUBLESHOOTING.md +3 -3
  145. package/src/platforms/gba/lib/c/gba_sfx.c +40 -0
  146. package/src/platforms/gba/lib/c/gba_sfx.h +10 -0
  147. package/src/platforms/gbc/MENTAL_MODEL.md +4 -4
  148. package/src/platforms/gbc/TROUBLESHOOTING.md +4 -4
  149. package/src/platforms/gbc/UPSTREAM_SOURCES.md +1 -1
  150. package/src/platforms/gbc/lib/c/README.md +10 -11
  151. package/src/platforms/gbc/lib/c/gb_crt0.s +26 -3
  152. package/src/platforms/gbc/lib/c/patch-header.js +13 -3
  153. package/src/platforms/genesis/MENTAL_MODEL.md +3 -3
  154. package/src/platforms/genesis/TROUBLESHOOTING.md +2 -2
  155. package/src/platforms/gg/MENTAL_MODEL.md +4 -4
  156. package/src/platforms/gg/TROUBLESHOOTING.md +3 -3
  157. package/src/platforms/gg/UPSTREAM_SOURCES.md +1 -1
  158. package/src/platforms/gg/lib/c/joypad_read.c +29 -0
  159. package/src/platforms/lynx/MENTAL_MODEL.md +1 -1
  160. package/src/platforms/lynx/TROUBLESHOOTING.md +3 -3
  161. package/src/platforms/msx/MENTAL_MODEL.md +5 -5
  162. package/src/platforms/msx/TROUBLESHOOTING.md +2 -2
  163. package/src/platforms/msx/lib/c/msx_hw.h +1 -0
  164. package/src/platforms/msx/lib/c/msx_vdp.c +25 -0
  165. package/src/platforms/nes/MENTAL_MODEL.md +2 -2
  166. package/src/platforms/nes/lib/c/nes_runtime.c +149 -34
  167. package/src/platforms/nes/lib/c/nes_runtime.h +34 -1
  168. package/src/platforms/pce/MENTAL_MODEL.md +5 -5
  169. package/src/platforms/pce/TROUBLESHOOTING.md +1 -1
  170. package/src/platforms/pce/lib/c/pce_hw.h +11 -0
  171. package/src/platforms/pce/lib/c/pce_video.c +32 -0
  172. package/src/platforms/sms/MENTAL_MODEL.md +6 -6
  173. package/src/platforms/snes/MENTAL_MODEL.md +2 -2
  174. package/src/platforms/snes/TROUBLESHOOTING.md +40 -1
  175. package/src/toolchains/cc65/presets/nes/chr-ram-runtime.cfg +13 -8
  176. package/src/toolchains/cc65/presets/nes/chr-ram-runtime.crt0.s +58 -5
  177. package/src/toolchains/cc65/presets/nes/chr-rom.crt0.s +52 -3
  178. package/src/toolchains/cc65/presets/pce/rom32k.cfg +52 -0
  179. package/src/toolchains/index.js +27 -11
@@ -78,6 +78,13 @@ int main(void) {
78
78
  * screen is on you get a black/forced-blank screen forever. */
79
79
  sfx_init();
80
80
 
81
+ /* One frame between init and the FIRST command: sfx_init returns the
82
+ * instant the SPC echoes the jump command, but the driver then spends
83
+ * ~50 port writes initialising the DSP BEFORE it seeds its command
84
+ * edge-detector from $2140. A command sent inside that window gets
85
+ * swallowed by the seed — the music silently never starts. */
86
+ WaitForVBlank();
87
+
81
88
  /* Auto-start music. */
82
89
  sfx_music_play();
83
90
  music_running = 1;
@@ -1,6 +1,61 @@
1
- ; ── platformer-data.asm — one sprite (player) + font stubs ─────────
1
+ ; ── platformer-data.asm — CRAG CAPER's assembly half ─────────────────────────
2
+ ;
3
+ ; What lives here (and why it can't live in platformer.c):
4
+ ; 1. The telem block, in a RAMSECTION pinned to WRAM BANK $7E. tcc-65816
5
+ ; puts C globals in bank $7F at addresses the linker picks; a headless
6
+ ; test harness wants a block it can FIND by scanning, at an address WE
7
+ ; control. platformer.c reaches it as a plain extern.
8
+ ; 2. sram_read16/sram_write16 — battery SRAM accessors. SRAM sits at
9
+ ; $70:0000 (declared in hdr.asm — see platformer-hdr.asm), reachable
10
+ ; only with long (24-bit) addressing, which tcc C pointers don't emit.
11
+ ; 3. Font + sprite tiles + level BG tiles (rodata).
12
+ ;
13
+ ; Section names must stay unique vs snes_sfx_data.asm (also linked in).
14
+
2
15
  .include "hdr.asm"
3
16
 
17
+ .RAMSECTION "platformer_wram" BANK $7E SLOT 2
18
+ telem dsb 24 ; headless-test telemetry block (see platformer.c)
19
+ .ENDS
20
+
21
+ .SECTION ".platformer_asm" SUPERFREE
22
+
23
+ ; ── HARDWARE IDIOM (load-bearing) — battery SRAM accessors ──────────────────
24
+ ; SRAM is mapped at $70:0000 (LoROM, SRAMSIZE $01 in platformer-hdr.asm =
25
+ ; 2 KB). Long addressing only — there is no SRAM mirror in the program banks,
26
+ ; which is why these are asm and not C. tcc calling convention: u16 arg at
27
+ ; 5,s (after the 4-byte rtl frame), second arg at 7,s; u16 return in tcc__r0.
28
+
29
+ ; u16 sram_read16(u16 offset)
30
+ sram_read16:
31
+ php
32
+ rep #$30
33
+ lda 5,s ; offset
34
+ tax
35
+ sep #$20
36
+ lda.l $700000,x
37
+ sta.w tcc__r0
38
+ lda.l $700001,x
39
+ sta.w tcc__r0 + 1
40
+ plp
41
+ rtl
42
+
43
+ ; void sram_write16(u16 offset, u16 value)
44
+ sram_write16:
45
+ php
46
+ rep #$30
47
+ lda 5,s ; offset
48
+ tax
49
+ lda 7,s ; value
50
+ sep #$20
51
+ sta.l $700000,x ; low byte
52
+ xba
53
+ sta.l $700001,x ; high byte
54
+ plp
55
+ rtl
56
+
57
+ .ENDS
58
+
4
59
  .section ".rodata1" superfree
5
60
 
6
61
  tilfont:
@@ -308,40 +363,84 @@ palfont:
308
363
  .db $00, $00
309
364
 
310
365
  tilsprite:
311
- ; Tile 0 player (filled diamond, colour 1)
312
- .db $18, $00, $3C, $00, $7E, $00, $FF, $00
313
- .db $FF, $00, $7E, $00, $3C, $00, $18, $00
366
+ ; OBJ tiles, 8x8 4bpp (32 bytes each: rows 0-7 plane0/plane1 byte pairs,
367
+ ; then rows 0-7 plane2/plane3 pairs). Pixel colour = the 4 plane bits, and
368
+ ; the colour indexes palsprite below so plane choice IS colour choice:
369
+ ; player body = plane0 only → colour 1 (red)
370
+ ; player eyes = plane0+plane1 → colour 3 (white)
371
+ ; coin disc = plane2 only → colour 4 (gold)
372
+ ; coin ring = plane0+plane2 → colour 5 (dark gold)
373
+ ; spike = plane1+plane2 → colour 6 (danger red)
374
+ ; tile 0 — player, idle (round body + legs, two eyes)
375
+ .db $3C, $00, $7E, $24, $FF, $24, $FF, $00
376
+ .db $FF, $00, $7E, $00, $66, $00, $66, $00
314
377
  .db $00, $00, $00, $00, $00, $00, $00, $00
315
378
  .db $00, $00, $00, $00, $00, $00, $00, $00
316
-
317
- palsprite:
318
- .db $00, $00 ; 0 transparent
319
- .db $00, $7C ; 1 red
379
+ ; tile 1 — player, jumping (arms up)
380
+ .db $18, $00, $7E, $24, $FF, $24, $FF, $00
381
+ .db $E7, $00, $C3, $00, $81, $00, $00, $00
320
382
  .db $00, $00, $00, $00, $00, $00, $00, $00
321
383
  .db $00, $00, $00, $00, $00, $00, $00, $00
384
+ ; tile 2 — coin (gold disc, embossed ring)
385
+ .db $00, $00, $3C, $00, $66, $00, $5A, $00
386
+ .db $5A, $00, $66, $00, $3C, $00, $00, $00
387
+ .db $3C, $00, $7E, $00, $FF, $00, $FF, $00
388
+ .db $FF, $00, $FF, $00, $7E, $00, $3C, $00
389
+ ; tile 3 — ground spike
390
+ .db $00, $00, $00, $18, $00, $18, $00, $3C
391
+ .db $00, $3C, $00, $7E, $00, $7E, $00, $FF
392
+ .db $00, $00, $18, $00, $18, $00, $3C, $00
393
+ .db $3C, $00, $7E, $00, $7E, $00, $FF, $00
394
+
395
+ palsprite:
396
+ ; OBJ palette block 0 (CGRAM 128-143), BGR555 little-endian.
397
+ .db $00, $00 ; 0 transparent
398
+ .db $1F, $00 ; 1 red (player body)
399
+ .db $10, $00 ; 2 dark red (unused, free)
400
+ .db $FF, $7F ; 3 white (player eyes)
401
+ .db $3F, $13 ; 4 gold (coin disc)
402
+ .db $3C, $0A ; 5 dark gold (coin ring)
403
+ .db $DE, $18 ; 6 danger red (spike)
404
+ .db $00, $00 ; 7 unused
322
405
  .db $00, $00, $00, $00, $00, $00, $00, $00
323
406
  .db $00, $00, $00, $00, $00, $00, $00, $00
324
407
 
325
- ; ── Background wallpaper (one 8x8 4bpp tile, 4 solid colour quadrants) ──
326
- ; Tiled across BG1 it paints the whole screen in four muted colours so the
327
- ; playfield never reads as a flat/blank backdrop. Quadrant->colour: TL=1,
328
- ; TR=2, BL=3, BR=4. 4bpp plane order: bytes 0-15 = rows 0-7 plane0/plane1
329
- ; pairs, bytes 16-31 = rows 0-7 plane2/plane3 pairs.
408
+ ; ── Level BG tiles (8x8 4bpp, same plane layout as the sprites above).
409
+ ; Colour 0 is TRANSPARENT the backdrop (CGRAM colour 0 = sky blue) shows
410
+ ; through, which is also why the dirt speckle holes read as sky-blue grit.
330
411
  tilbg:
331
- .db $F0, $0F, $F0, $0F, $F0, $0F, $F0, $0F ; rows 0-3: p0=left p1=right
332
- .db $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0 ; rows 4-7: p0+p1 = left
333
- .db $00, $00, $00, $00, $00, $00, $00, $00 ; rows 0-3: p2/p3 = 0
334
- .db $0F, $00, $0F, $00, $0F, $00, $0F, $00 ; rows 4-7: p2 = right
412
+ ; tile 0 blank (all transparent = pure sky)
413
+ .db $00, $00, $00, $00, $00, $00, $00, $00
414
+ .db $00, $00, $00, $00, $00, $00, $00, $00
415
+ .db $00, $00, $00, $00, $00, $00, $00, $00
416
+ .db $00, $00, $00, $00, $00, $00, $00, $00
417
+ ; tile 1 — puffy cloud (colour 1 = white, shared with the text ink)
418
+ .db $00, $00, $18, $00, $3C, $00, $7E, $00
419
+ .db $7E, $00, $00, $00, $00, $00, $00, $00
420
+ .db $00, $00, $00, $00, $00, $00, $00, $00
421
+ .db $00, $00, $00, $00, $00, $00, $00, $00
422
+ ; tile 2 — dirt fill (colour 2 brown, speckled with transparent holes)
423
+ .db $00, $FF, $00, $FF, $00, $EF, $00, $FF
424
+ .db $00, $FF, $00, $FE, $00, $FF, $00, $FF
425
+ .db $00, $00, $00, $00, $00, $00, $00, $00
426
+ .db $00, $00, $00, $00, $00, $00, $00, $00
427
+ ; tile 3 — grass top (2 rows colour 3 green over colour 2 dirt) — used for
428
+ ; both the ground surface and the floating one-way platforms
429
+ .db $FF, $FF, $FF, $FF, $00, $FF, $00, $FF
430
+ .db $00, $FF, $00, $FF, $00, $FF, $00, $FF
431
+ .db $00, $00, $00, $00, $00, $00, $00, $00
432
+ .db $00, $00, $00, $00, $00, $00, $00, $00
335
433
 
336
434
  palbg:
337
- ; 16-colour BG palette; only 1-4 used (the four wallpaper quadrant tones).
338
- .db $00, $00 ; 0 unused (BG fully opaque)
339
- .db $C4, $30 ; 1 dark blue
340
- .db $42, $29 ; 2 dark teal
341
- .db $88, $30 ; 3 dark purple
342
- .db $C6, $24 ; 4 dark slate
435
+ ; BG palette block 0 (CGRAM 0-15), BGR555 little-endian. Loaded AFTER the
436
+ ; console font palette and deliberately a SUPERSET of it: colour 1 stays
437
+ ; white so the HUD/title text keeps its ink, colour 0 is the backdrop sky.
438
+ .db $4B, $72 ; 0 sky blue (the backdrop colour — colour 0 IS the sky)
439
+ .db $FF, $7F ; 1 white (text ink + clouds)
440
+ .db $2E, $11 ; 2 dirt brown
441
+ .db $86, $1A ; 3 grass green
442
+ .db $00, $00, $00, $00, $00, $00, $00, $00
343
443
  .db $00, $00, $00, $00, $00, $00, $00, $00
344
444
  .db $00, $00, $00, $00, $00, $00, $00, $00
345
- .db $00, $00, $00, $00, $00, $00
346
445
 
347
446
  .ends
@@ -0,0 +1,57 @@
1
+ ;==LoRom== platformer hdr.asm — PROJECT OVERRIDE of PVSnesLib's stock header
2
+ ;
3
+ ; Why this file exists: the stock include/hdr.asm declares CARTRIDGETYPE $00
4
+ ; (ROM only) and SRAMSIZE $00. The SNES cart header is the ONLY place battery
5
+ ; SRAM gets declared — snes9x (and real flash carts) size the save RAM from
6
+ ; these two bytes. Delete this file and the build still succeeds, the game
7
+ ; still runs, and saves silently stop existing: sram_read16/sram_write16 hit
8
+ ; open bus at $70:0000 and the hi-score never survives a power cycle.
9
+ ;
10
+ ; Everything except CARTRIDGETYPE/SRAMSIZE/NAME is byte-identical to the
11
+ ; stock header — the memory map and vectors MUST match what PVSnesLib's
12
+ ; crt0/libs were assembled against, or wlalink places sections inconsistently.
13
+
14
+ .MEMORYMAP ; Begin describing the system architecture.
15
+ SLOTSIZE $8000 ; ROM slot is $8000 bytes (LoROM 32K banks).
16
+ DEFAULTSLOT 0
17
+ SLOT 0 $8000 ; ROM
18
+ SLOT 1 $0 $2000 ; low WRAM mirror (tcc registers live at $0000)
19
+ SLOT 2 $2000 $E000 ; WRAM $2000-$FFFF (our telem block lands here)
20
+ SLOT 3 $0 $10000 ; bank $7F WRAM (tcc C globals)
21
+ .ENDME
22
+
23
+ .ROMBANKSIZE $8000 ; 32 KByte ROM banks
24
+ .ROMBANKS 8 ; 2 Mbits (256 KB) — matches PVSnesLib stock
25
+
26
+ .SNESHEADER
27
+ ID "SNES"
28
+
29
+ NAME "CRAG CAPER " ; Program Title - 21 bytes, space-padded.
30
+ ; "123456789012345678901"
31
+
32
+ SLOWROM
33
+ LOROM
34
+
35
+ CARTRIDGETYPE $02 ; $02 = ROM + SRAM + battery ← THE SAVE SWITCH
36
+ ROMSIZE $08 ; $08 = 2 Mbits
37
+ SRAMSIZE $01 ; $01 = 2 KB SRAM, mapped at $70:0000-$07FF
38
+ COUNTRY $01 ; $01 = U.S.
39
+ LICENSEECODE $00
40
+ VERSION $00
41
+ .ENDSNES
42
+
43
+ .SNESNATIVEVECTOR ; Native Mode interrupt vector table
44
+ COP EmptyHandler
45
+ BRK EmptyHandler
46
+ ABORT EmptyHandler
47
+ NMI VBlank ; PVSnesLib's vblank.asm handler
48
+ IRQ EmptyHandler
49
+ .ENDNATIVEVECTOR
50
+
51
+ .SNESEMUVECTOR ; Emulation Mode interrupt vector table
52
+ COP EmptyHandler
53
+ ABORT EmptyHandler
54
+ NMI EmptyHandler
55
+ RESET tcc__start ; PVSnesLib crt0 entry
56
+ IRQBRK EmptyHandler
57
+ .ENDEMUVECTOR