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.
- package/AGENTS.md +53 -43
- package/CHANGELOG.md +91 -0
- package/README.md +3 -3
- package/examples/README.md +7 -7
- package/examples/atari2600/templates/platformer.asm +1225 -332
- package/examples/atari2600/templates/puzzle.asm +1056 -0
- package/examples/atari2600/templates/racing.asm +906 -275
- package/examples/atari2600/templates/shmup.asm +1031 -239
- package/examples/atari2600/templates/sports.asm +1135 -253
- package/examples/atari7800/templates/platformer.c +991 -156
- package/examples/atari7800/templates/puzzle.c +1091 -148
- package/examples/atari7800/templates/racing.c +952 -124
- package/examples/atari7800/templates/shmup.c +812 -134
- package/examples/atari7800/templates/sports.c +820 -184
- package/examples/c64/templates/platformer.c +879 -164
- package/examples/c64/templates/puzzle.c +855 -178
- package/examples/c64/templates/racing.c +873 -97
- package/examples/c64/templates/shmup.c +757 -161
- package/examples/c64/templates/sports.c +755 -100
- package/examples/gb/templates/platformer.c +841 -179
- package/examples/gb/templates/puzzle.c +986 -246
- package/examples/gb/templates/racing.c +754 -174
- package/examples/gb/templates/shmup.c +673 -175
- package/examples/gb/templates/sports.c +790 -159
- package/examples/gba/templates/platformer.c +626 -165
- package/examples/gba/templates/puzzle.c +519 -269
- package/examples/gba/templates/racing.c +511 -206
- package/examples/gba/templates/shmup.c +564 -179
- package/examples/gba/templates/sports.c +454 -174
- package/examples/gbc/templates/platformer.c +944 -180
- package/examples/gbc/templates/puzzle.c +363 -109
- package/examples/gbc/templates/racing.c +884 -180
- package/examples/gbc/templates/shmup.c +821 -185
- package/examples/gbc/templates/sports.c +870 -162
- package/examples/genesis/templates/platformer.c +747 -129
- package/examples/genesis/templates/puzzle.c +694 -261
- package/examples/genesis/templates/racing.c +726 -203
- package/examples/genesis/templates/shmup.c +535 -142
- package/examples/genesis/templates/sports.c +495 -158
- package/examples/gg/templates/platformer.c +880 -215
- package/examples/gg/templates/puzzle.c +875 -216
- package/examples/gg/templates/racing.c +915 -172
- package/examples/gg/templates/shmup.c +714 -191
- package/examples/gg/templates/sports.c +732 -129
- package/examples/lynx/templates/platformer.c +604 -69
- package/examples/lynx/templates/puzzle.c +498 -158
- package/examples/lynx/templates/racing.c +538 -102
- package/examples/lynx/templates/shmup.c +458 -131
- package/examples/lynx/templates/sports.c +496 -72
- package/examples/msx/platformer/main.c +649 -162
- package/examples/msx/puzzle/main.c +742 -240
- package/examples/msx/racing/main.c +669 -178
- package/examples/msx/shmup/main.c +460 -178
- package/examples/msx/sports/main.c +592 -126
- package/examples/nes/templates/platformer.c +589 -171
- package/examples/nes/templates/puzzle.c +563 -242
- package/examples/nes/templates/racing.c +502 -208
- package/examples/nes/templates/shmup.c +339 -145
- package/examples/nes/templates/sports.c +341 -183
- package/examples/pce/platformer/main.c +874 -205
- package/examples/pce/puzzle/main.c +802 -287
- package/examples/pce/racing/main.c +783 -208
- package/examples/pce/shmup/main.c +638 -212
- package/examples/pce/sports/main.c +586 -169
- package/examples/porting-across-platforms/README.md +1 -1
- package/examples/sms/templates/platformer.c +762 -177
- package/examples/sms/templates/puzzle.c +752 -212
- package/examples/sms/templates/racing.c +808 -145
- package/examples/sms/templates/shmup.c +599 -162
- package/examples/sms/templates/sports.c +630 -122
- package/examples/snes/templates/music_demo.c +7 -0
- package/examples/snes/templates/platformer-data.asm +123 -24
- package/examples/snes/templates/platformer-hdr.asm +57 -0
- package/examples/snes/templates/platformer.c +586 -165
- package/examples/snes/templates/puzzle-data.asm +116 -21
- package/examples/snes/templates/puzzle-hdr.asm +57 -0
- package/examples/snes/templates/puzzle.c +614 -235
- package/examples/snes/templates/racing-data.asm +390 -32
- package/examples/snes/templates/racing-hdr.asm +57 -0
- package/examples/snes/templates/racing.c +807 -196
- package/examples/snes/templates/shmup-data.asm +87 -29
- package/examples/snes/templates/shmup-hdr.asm +57 -0
- package/examples/snes/templates/shmup.c +459 -198
- package/examples/snes/templates/sports-data.asm +48 -2
- package/examples/snes/templates/sports-hdr.asm +57 -0
- package/examples/snes/templates/sports.c +414 -163
- package/package.json +12 -12
- package/src/cores/wasm/bluemsx_libretro.js +1 -1
- package/src/cores/wasm/bluemsx_libretro.wasm +0 -0
- package/src/cores/wasm/fceumm_libretro.js +1 -1
- package/src/cores/wasm/fceumm_libretro.wasm +0 -0
- package/src/cores/wasm/gambatte_libretro.js +1 -1
- package/src/cores/wasm/gambatte_libretro.wasm +0 -0
- package/src/cores/wasm/geargrafx_libretro.js +1 -1
- package/src/cores/wasm/geargrafx_libretro.wasm +0 -0
- package/src/cores/wasm/genesis_plus_gx_libretro.js +1 -1
- package/src/cores/wasm/genesis_plus_gx_libretro.wasm +0 -0
- package/src/cores/wasm/handy_libretro.js +1 -1
- package/src/cores/wasm/handy_libretro.wasm +0 -0
- package/src/cores/wasm/mgba_libretro.js +1 -1
- package/src/cores/wasm/mgba_libretro.wasm +0 -0
- package/src/cores/wasm/prosystem_libretro.js +1 -1
- package/src/cores/wasm/prosystem_libretro.wasm +0 -0
- package/src/cores/wasm/snes9x_libretro.js +1 -1
- package/src/cores/wasm/snes9x_libretro.wasm +0 -0
- package/src/cores/wasm/stella2014_libretro.js +1 -1
- package/src/cores/wasm/stella2014_libretro.wasm +0 -0
- package/src/cores/wasm/vice_x64_libretro.js +1 -1
- package/src/cores/wasm/vice_x64_libretro.wasm +0 -0
- package/src/host/LibretroHost.js +84 -8
- package/src/http/tool-registry.js +11 -11
- package/src/mcp/tools/cheats.js +2 -1
- package/src/mcp/tools/frame.js +3 -2
- package/src/mcp/tools/index.js +3 -3
- package/src/mcp/tools/input.js +5 -4
- package/src/mcp/tools/lifecycle.js +6 -4
- package/src/mcp/tools/memory.js +131 -24
- package/src/mcp/tools/platform-docs.js +1 -1
- package/src/mcp/tools/preview-tile.js +6 -2
- package/src/mcp/tools/project.js +1098 -130
- package/src/mcp/tools/record.js +6 -7
- package/src/mcp/tools/rom-id.js +5 -1
- package/src/mcp/tools/run-until.js +12 -4
- package/src/mcp/tools/snippets.js +6 -6
- package/src/mcp/tools/sprite-pipeline.js +14 -2
- package/src/mcp/tools/state.js +2 -1
- package/src/mcp/tools/tile-inspect.js +8 -1
- package/src/mcp/tools/toolchain.js +12 -1
- package/src/mcp/tools/watch-memory.js +53 -10
- package/src/observer/bus.js +73 -0
- package/src/observer/livestream.html +4 -2
- package/src/observer/tool-wrap.js +17 -14
- package/src/platforms/_guides/ROMHACKING_PLAYBOOK.md +32 -3
- package/src/platforms/atari7800/MENTAL_MODEL.md +5 -5
- package/src/platforms/atari7800/TROUBLESHOOTING.md +5 -5
- package/src/platforms/c64/MENTAL_MODEL.md +11 -4
- package/src/platforms/c64/TROUBLESHOOTING.md +13 -0
- package/src/platforms/gb/MENTAL_MODEL.md +3 -3
- package/src/platforms/gb/TROUBLESHOOTING.md +61 -8
- package/src/platforms/gb/lib/c/README.md +10 -11
- package/src/platforms/gb/lib/c/gb_crt0.s +27 -3
- package/src/platforms/gb/lib/c/patch-header.js +13 -3
- package/src/platforms/gba/MENTAL_MODEL.md +4 -4
- package/src/platforms/gba/TROUBLESHOOTING.md +3 -3
- package/src/platforms/gba/lib/c/gba_sfx.c +40 -0
- package/src/platforms/gba/lib/c/gba_sfx.h +10 -0
- package/src/platforms/gbc/MENTAL_MODEL.md +4 -4
- package/src/platforms/gbc/TROUBLESHOOTING.md +4 -4
- package/src/platforms/gbc/UPSTREAM_SOURCES.md +1 -1
- package/src/platforms/gbc/lib/c/README.md +10 -11
- package/src/platforms/gbc/lib/c/gb_crt0.s +26 -3
- package/src/platforms/gbc/lib/c/patch-header.js +13 -3
- package/src/platforms/genesis/MENTAL_MODEL.md +3 -3
- package/src/platforms/genesis/TROUBLESHOOTING.md +2 -2
- package/src/platforms/gg/MENTAL_MODEL.md +4 -4
- package/src/platforms/gg/TROUBLESHOOTING.md +3 -3
- package/src/platforms/gg/UPSTREAM_SOURCES.md +1 -1
- package/src/platforms/gg/lib/c/joypad_read.c +29 -0
- package/src/platforms/lynx/MENTAL_MODEL.md +1 -1
- package/src/platforms/lynx/TROUBLESHOOTING.md +3 -3
- package/src/platforms/msx/MENTAL_MODEL.md +5 -5
- package/src/platforms/msx/TROUBLESHOOTING.md +2 -2
- package/src/platforms/msx/lib/c/msx_hw.h +1 -0
- package/src/platforms/msx/lib/c/msx_vdp.c +25 -0
- package/src/platforms/nes/MENTAL_MODEL.md +2 -2
- package/src/platforms/nes/lib/c/nes_runtime.c +149 -34
- package/src/platforms/nes/lib/c/nes_runtime.h +34 -1
- package/src/platforms/pce/MENTAL_MODEL.md +5 -5
- package/src/platforms/pce/TROUBLESHOOTING.md +1 -1
- package/src/platforms/pce/lib/c/pce_hw.h +11 -0
- package/src/platforms/pce/lib/c/pce_video.c +32 -0
- package/src/platforms/sms/MENTAL_MODEL.md +6 -6
- package/src/platforms/snes/MENTAL_MODEL.md +2 -2
- package/src/platforms/snes/TROUBLESHOOTING.md +40 -1
- package/src/toolchains/cc65/presets/nes/chr-ram-runtime.cfg +13 -8
- package/src/toolchains/cc65/presets/nes/chr-ram-runtime.crt0.s +58 -5
- package/src/toolchains/cc65/presets/nes/chr-rom.crt0.s +52 -3
- package/src/toolchains/cc65/presets/pce/rom32k.cfg +52 -0
- package/src/toolchains/index.js +27 -11
|
@@ -1,6 +1,230 @@
|
|
|
1
|
-
; ── racing-data.asm —
|
|
1
|
+
; ── racing-data.asm — EMBER CIRCUIT's assembly half ──────────────────────────
|
|
2
|
+
;
|
|
3
|
+
; What lives here (and why it can't live in racing.c):
|
|
4
|
+
; 1. The Mode 7 HDMA tables, in a RAMSECTION pinned to WRAM BANK $7E.
|
|
5
|
+
; tcc-65816 puts C globals in bank $7F — but an HDMA channel's A1Bx bank
|
|
6
|
+
; byte + the table address must be known exactly, so the tables live here
|
|
7
|
+
; where WE pick the bank. racing.c reaches them as plain externs.
|
|
8
|
+
; 2. m7_build — the per-frame matrix-table builder. 168 multiplies per frame
|
|
9
|
+
; is far beyond tcc-compiled C (software 16-bit mul ≈ 200+ cycles); this
|
|
10
|
+
; uses the S-CPU's 8x8 hardware multiplier ($4202/$4203 → $4216, 8-cycle
|
|
11
|
+
; latency) and finishes in ~30% of a frame.
|
|
12
|
+
; 3. sram_read16/sram_write16 — battery SRAM accessors. SRAM sits at
|
|
13
|
+
; $70:0000 (declared in hdr.asm — see racing-hdr.asm), reachable only
|
|
14
|
+
; with long (24-bit) addressing, which tcc C pointers don't emit.
|
|
15
|
+
; 4. Font + car sprite tiles (rodata).
|
|
16
|
+
;
|
|
17
|
+
; Section names must stay unique vs snes_sfx_data.asm (also linked in).
|
|
18
|
+
|
|
2
19
|
.include "hdr.asm"
|
|
3
20
|
|
|
21
|
+
; ── HARDWARE IDIOM (load-bearing — reshape gameplay around this; see TROUBLESHOOTING) ──
|
|
22
|
+
; The double-buffered HDMA tables. HDMA reads these DURING active display —
|
|
23
|
+
; rewriting the table the beam is walking shears the ground mid-frame. So:
|
|
24
|
+
; two copies of each; racing.c builds into the back buffer while HDMA walks
|
|
25
|
+
; the front, and flips by rewriting A1Tx during vblank.
|
|
26
|
+
;
|
|
27
|
+
; Table grammar (walked by hardware, one entry header per batch of lines):
|
|
28
|
+
; [count 1-127][data] = write data once, hold it for <count> lines
|
|
29
|
+
; [count|$80] [data...] = REPEAT: fresh data EVERY line for count&$7F lines
|
|
30
|
+
; [0] = end of table (last value persists to frame bottom)
|
|
31
|
+
; We use plain 2-line hold entries (84 entries x 2 lines = 168 road lines):
|
|
32
|
+
; half the multiplies of per-line repeat mode, visually identical.
|
|
33
|
+
;
|
|
34
|
+
; AB/CD layout (matrix channels, transfer mode 3 → $211B,$211B,$211C,$211C):
|
|
35
|
+
; [0] = 56 hold the identity matrix through the mode-1 HUD strip
|
|
36
|
+
; [1-4] = A=$0100, B=0 (identity — these lines are text, matrix unused)
|
|
37
|
+
; [5..] = 84 x { count=2, Alo, Ahi, Blo, Bhi } ← m7_build rewrites data
|
|
38
|
+
; [425] = 0 terminator
|
|
39
|
+
; m7_cdN MUST sit exactly 426 bytes after m7_abN: m7_build stores the CD
|
|
40
|
+
; (M7C/M7D) halves through the same index register at offset +426/+428.
|
|
41
|
+
;
|
|
42
|
+
; VOFS layout (mode 2 → $210E,$210E): [56][0,0] then 84 x {2, lo, hi}, [0].
|
|
43
|
+
; The VOFS value steps -2 per entry = -1 per scanline (see racing.c for the
|
|
44
|
+
; camera math that makes that constant slope correct at every zoom).
|
|
45
|
+
.RAMSECTION "mode7_tables" BANK $7E SLOT 2
|
|
46
|
+
m7_ab0 dsb 426 ; matrix A/B table, buffer 0
|
|
47
|
+
m7_cd0 dsb 426 ; matrix C/D table, buffer 0 (= m7_ab0 + 426, load-bearing)
|
|
48
|
+
m7_ab1 dsb 426 ; buffer 1
|
|
49
|
+
m7_cd1 dsb 426
|
|
50
|
+
m7_vo0 dsb 256 ; M7VOFS table, buffer 0
|
|
51
|
+
m7_vo1 dsb 256
|
|
52
|
+
lam8_tab dsb 84 ; per-band zoom λ>>3 (max 184, fits the 8x8 multiplier)
|
|
53
|
+
hdma_mode_tab dsb 8 ; BGMODE split table (static after boot)
|
|
54
|
+
hdma_hofs_tab dsb 8 ; M7HOFS table (racing.c patches bytes [4],[5] in vblank)
|
|
55
|
+
m7_cos dsb 1 ; inputs to m7_build, written by racing.c each frame:
|
|
56
|
+
m7_sin dsb 1 ; heading cos/sin, signed, 64 = 1.0
|
|
57
|
+
m7_dst dsb 2 ; back-buffer AB table, address of first entry
|
|
58
|
+
m7_vdst dsb 2 ; back-buffer VOFS table, address of first entry
|
|
59
|
+
m7_vstart dsb 2 ; VOFS value for the first road line
|
|
60
|
+
m7_cabs dsb 1 ; m7_build scratch: |cos|, |sin|, sign flags, products
|
|
61
|
+
m7_sabs dsb 1
|
|
62
|
+
m7_cneg dsb 2
|
|
63
|
+
m7_sneg dsb 2
|
|
64
|
+
m7_pc dsb 2
|
|
65
|
+
m7_ps dsb 2
|
|
66
|
+
telem dsb 16 ; headless-test telemetry block (see racing.c)
|
|
67
|
+
.ENDS
|
|
68
|
+
|
|
69
|
+
.SECTION ".racing_asm" SUPERFREE
|
|
70
|
+
|
|
71
|
+
; ── HARDWARE IDIOM (load-bearing — reshape gameplay around this; see TROUBLESHOOTING) ──
|
|
72
|
+
; void m7_build(void) — rebuild the BACK buffer's 84 matrix entries + VOFS
|
|
73
|
+
; column from m7_cos/m7_sin/m7_dst/m7_vdst/m7_vstart (racing.c sets all five
|
|
74
|
+
; first). Per entry: two hardware multiplies
|
|
75
|
+
; value = (λ>>3) x |trig| → $4216, then >>3 → 8.8 fixed point
|
|
76
|
+
; λ is 8.8 zoom (so λ>>3 is 5.3, ≤184); trig is 64=1.0 (1.6); the product is
|
|
77
|
+
; 6.9, and >>3 lands it in the 8.8 the M7x registers expect. Quantizing λ to
|
|
78
|
+
; 8 bits costs ≤3% scale error on the nearest rows — invisible, and it turns
|
|
79
|
+
; a 16x16 software multiply into one 8-cycle hardware one.
|
|
80
|
+
; Matrix written per band: A = λcosθ B = -λsinθ C = λsinθ D = λcosθ
|
|
81
|
+
; (the standard 2D rotation, scaled per scanline-band — that's all Mode 7 is).
|
|
82
|
+
m7_build:
|
|
83
|
+
php
|
|
84
|
+
phb
|
|
85
|
+
sep #$20
|
|
86
|
+
lda #$7E
|
|
87
|
+
pha
|
|
88
|
+
plb ; DBR = $7E → every .w absolute below hits WRAM
|
|
89
|
+
|
|
90
|
+
; split cos/sin into |value| + 16-bit negate flag
|
|
91
|
+
stz.w m7_cneg
|
|
92
|
+
stz.w m7_cneg + 1
|
|
93
|
+
stz.w m7_sneg
|
|
94
|
+
stz.w m7_sneg + 1
|
|
95
|
+
lda.w m7_cos
|
|
96
|
+
bpl @cpos
|
|
97
|
+
eor #$FF
|
|
98
|
+
inc a
|
|
99
|
+
inc.w m7_cneg
|
|
100
|
+
@cpos:
|
|
101
|
+
sta.w m7_cabs
|
|
102
|
+
lda.w m7_sin
|
|
103
|
+
bpl @spos
|
|
104
|
+
eor #$FF
|
|
105
|
+
inc a
|
|
106
|
+
inc.w m7_sneg
|
|
107
|
+
@spos:
|
|
108
|
+
sta.w m7_sabs
|
|
109
|
+
|
|
110
|
+
rep #$30
|
|
111
|
+
ldx.w m7_dst ; X → first AB entry's count byte
|
|
112
|
+
ldy.w #0 ; Y = entry index 0..83 (also indexes lam8_tab)
|
|
113
|
+
@entry:
|
|
114
|
+
; Pc = (lam8[y] * |cos|) >> 3, negated if cos was negative
|
|
115
|
+
sep #$20
|
|
116
|
+
lda.w lam8_tab,y
|
|
117
|
+
sta.l $004202 ; multiplicand
|
|
118
|
+
lda.w m7_cabs
|
|
119
|
+
sta.l $004203 ; multiplier — starts the 8-cycle multiply
|
|
120
|
+
rep #$20
|
|
121
|
+
nop ; rep(3) + nop+nop(4) + lda.l setup ≥ the 8-cycle
|
|
122
|
+
nop ; result latency — NEVER read $4216 sooner
|
|
123
|
+
lda.l $004216
|
|
124
|
+
lsr a
|
|
125
|
+
lsr a
|
|
126
|
+
lsr a
|
|
127
|
+
sta.w m7_pc
|
|
128
|
+
lda.w m7_cneg
|
|
129
|
+
beq @pcok
|
|
130
|
+
lda.w #0
|
|
131
|
+
sec
|
|
132
|
+
sbc.w m7_pc
|
|
133
|
+
sta.w m7_pc
|
|
134
|
+
@pcok:
|
|
135
|
+
; Ps = (lam8[y] * |sin|) >> 3, negated if sin was negative
|
|
136
|
+
sep #$20
|
|
137
|
+
lda.w lam8_tab,y
|
|
138
|
+
sta.l $004202
|
|
139
|
+
lda.w m7_sabs
|
|
140
|
+
sta.l $004203
|
|
141
|
+
rep #$20
|
|
142
|
+
nop
|
|
143
|
+
nop
|
|
144
|
+
lda.l $004216
|
|
145
|
+
lsr a
|
|
146
|
+
lsr a
|
|
147
|
+
lsr a
|
|
148
|
+
sta.w m7_ps
|
|
149
|
+
lda.w m7_sneg
|
|
150
|
+
beq @psok
|
|
151
|
+
lda.w #0
|
|
152
|
+
sec
|
|
153
|
+
sbc.w m7_ps
|
|
154
|
+
sta.w m7_ps
|
|
155
|
+
@psok:
|
|
156
|
+
; store the band's matrix: AB entry data at 1,x — CD twin at +426
|
|
157
|
+
lda.w m7_pc
|
|
158
|
+
sta.w $0001,x ; M7A = λcosθ
|
|
159
|
+
sta.w $01AD,x ; M7D = λcosθ ($1AD = 429 = 426 + 3)
|
|
160
|
+
lda.w m7_ps
|
|
161
|
+
sta.w $01AB,x ; M7C = λsinθ ($1AB = 427 = 426 + 1)
|
|
162
|
+
lda.w #0
|
|
163
|
+
sec
|
|
164
|
+
sbc.w m7_ps
|
|
165
|
+
sta.w $0003,x ; M7B = -λsinθ
|
|
166
|
+
txa
|
|
167
|
+
clc
|
|
168
|
+
adc.w #5 ; next entry (count byte + 4 data bytes)
|
|
169
|
+
tax
|
|
170
|
+
iny
|
|
171
|
+
cpy.w #84
|
|
172
|
+
bne @entry
|
|
173
|
+
|
|
174
|
+
; VOFS column: linear ramp, -2 per 2-line band (-1 per scanline)
|
|
175
|
+
ldx.w m7_vdst
|
|
176
|
+
lda.w m7_vstart
|
|
177
|
+
ldy.w #84
|
|
178
|
+
@vrow:
|
|
179
|
+
sta.w $0001,x
|
|
180
|
+
dec a
|
|
181
|
+
dec a
|
|
182
|
+
inx
|
|
183
|
+
inx
|
|
184
|
+
inx
|
|
185
|
+
dey
|
|
186
|
+
bne @vrow
|
|
187
|
+
|
|
188
|
+
plb
|
|
189
|
+
plp
|
|
190
|
+
rtl
|
|
191
|
+
|
|
192
|
+
; ── HARDWARE IDIOM (load-bearing) — battery SRAM accessors ──────────────────
|
|
193
|
+
; SRAM is mapped at $70:0000 (LoROM, SRAMSIZE $01 in racing-hdr.asm = 2 KB).
|
|
194
|
+
; Long addressing only — there is no SRAM mirror in the program banks, which
|
|
195
|
+
; is why these are asm and not C. tcc calling convention: u16 arg at 5,s
|
|
196
|
+
; (after the 4-byte rtl frame), second arg at 7,s; u16 return in tcc__r0.
|
|
197
|
+
|
|
198
|
+
; u16 sram_read16(u16 offset)
|
|
199
|
+
sram_read16:
|
|
200
|
+
php
|
|
201
|
+
rep #$30
|
|
202
|
+
lda 5,s ; offset
|
|
203
|
+
tax
|
|
204
|
+
sep #$20
|
|
205
|
+
lda.l $700000,x
|
|
206
|
+
sta.w tcc__r0
|
|
207
|
+
lda.l $700001,x
|
|
208
|
+
sta.w tcc__r0 + 1
|
|
209
|
+
plp
|
|
210
|
+
rtl
|
|
211
|
+
|
|
212
|
+
; void sram_write16(u16 offset, u16 value)
|
|
213
|
+
sram_write16:
|
|
214
|
+
php
|
|
215
|
+
rep #$30
|
|
216
|
+
lda 5,s ; offset
|
|
217
|
+
tax
|
|
218
|
+
lda 7,s ; value
|
|
219
|
+
sep #$20
|
|
220
|
+
sta.l $700000,x ; low byte
|
|
221
|
+
xba
|
|
222
|
+
sta.l $700001,x ; high byte
|
|
223
|
+
plp
|
|
224
|
+
rtl
|
|
225
|
+
|
|
226
|
+
.ENDS
|
|
227
|
+
|
|
4
228
|
.section ".rodata1" superfree
|
|
5
229
|
|
|
6
230
|
tilfont:
|
|
@@ -307,47 +531,181 @@ palfont:
|
|
|
307
531
|
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
308
532
|
.db $00, $00
|
|
309
533
|
|
|
534
|
+
palsprite:
|
|
535
|
+
.db $00, $00 ; 0 transparent
|
|
536
|
+
.db $FF, $7F ; 1 white (cockpit stripe)
|
|
537
|
+
.db $1F, $00 ; 2 red (body)
|
|
538
|
+
.db $10, $00 ; 3 dark red (shading)
|
|
539
|
+
.db $C6, $18 ; 4 dark grey (tires)
|
|
540
|
+
.db $CE, $39 ; 5 grey
|
|
541
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
542
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
543
|
+
.db $00, $00, $00, $00
|
|
544
|
+
|
|
310
545
|
tilsprite:
|
|
311
|
-
;
|
|
312
|
-
|
|
313
|
-
|
|
546
|
+
; The car, 16x16, as OBJ-page tiles. SNES large (16x16) sprites fetch tiles
|
|
547
|
+
; n, n+1, n+16, n+17 from a 16-tile-wide page — so the four quadrants sit at
|
|
548
|
+
; page positions 0, 1, 16, 17 with blank tiles padding the rest of each row.
|
|
549
|
+
; 4bpp: per tile 32 bytes = rows 0-7 plane0/plane1 pairs, then plane2/plane3.
|
|
550
|
+
; tile 0 - car top-left
|
|
551
|
+
.db $00, $03, $00, $07, $03, $04, $03, $04
|
|
552
|
+
.db $00, $0F, $01, $0F, $03, $1F, $03, $1F
|
|
553
|
+
.db $00, $00, $00, $00, $00, $00, $C0, $00
|
|
554
|
+
.db $C0, $00, $F0, $00, $20, $00, $00, $00
|
|
555
|
+
; tile 1 - car top-right
|
|
556
|
+
.db $00, $C0, $00, $E0, $00, $E0, $00, $E0
|
|
557
|
+
.db $00, $F0, $80, $F0, $C0, $F8, $C0, $F8
|
|
558
|
+
.db $00, $00, $00, $00, $00, $00, $03, $00
|
|
559
|
+
.db $03, $00, $0F, $00, $00, $00, $00, $00
|
|
560
|
+
; tile 2 - blank
|
|
314
561
|
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
315
562
|
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
316
|
-
; Tile 1 — enemy car (colour 2)
|
|
317
|
-
.db $00, $3C, $00, $7E, $00, $42, $00, $7E
|
|
318
|
-
.db $00, $7E, $00, $42, $00, $7E, $00, $66
|
|
319
563
|
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
320
564
|
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
321
|
-
|
|
322
|
-
palsprite:
|
|
323
|
-
.db $00, $00 ; 0 transparent
|
|
324
|
-
.db $FF, $7F ; 1 white (player)
|
|
325
|
-
.db $00, $7C ; 2 red (enemy)
|
|
565
|
+
; tile 3 - blank
|
|
326
566
|
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
327
567
|
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
328
568
|
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
329
569
|
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
;
|
|
336
|
-
|
|
337
|
-
.db $
|
|
338
|
-
.db $
|
|
339
|
-
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
.db $00, $00
|
|
345
|
-
|
|
346
|
-
.db $
|
|
347
|
-
.db $
|
|
348
|
-
.db $
|
|
570
|
+
; tile 4 - blank
|
|
571
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
572
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
573
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
574
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
575
|
+
; tile 5 - blank
|
|
576
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
577
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
578
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
579
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
580
|
+
; tile 6 - blank
|
|
581
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
582
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
583
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
584
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
585
|
+
; tile 7 - blank
|
|
586
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
587
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
588
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
589
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
590
|
+
; tile 8 - blank
|
|
591
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
592
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
593
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
594
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
595
|
+
; tile 9 - blank
|
|
596
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
597
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
598
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
599
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
600
|
+
; tile 10 - blank
|
|
601
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
602
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
603
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
604
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
605
|
+
; tile 11 - blank
|
|
606
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
607
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
608
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
609
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
610
|
+
; tile 12 - blank
|
|
611
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
612
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
613
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
614
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
615
|
+
; tile 13 - blank
|
|
616
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
617
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
618
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
619
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
620
|
+
; tile 14 - blank
|
|
621
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
622
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
623
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
624
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
625
|
+
; tile 15 - blank
|
|
626
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
627
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
628
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
629
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
630
|
+
; tile 16 - car bottom-left
|
|
631
|
+
.db $01, $1F, $01, $0F, $01, $0F, $01, $1F
|
|
632
|
+
.db $00, $0F, $03, $1F, $07, $0F, $07, $07
|
|
633
|
+
.db $00, $00, $00, $00, $C0, $00, $C0, $00
|
|
634
|
+
.db $F0, $00, $20, $00, $00, $00, $00, $00
|
|
635
|
+
; tile 17 - car bottom-right
|
|
636
|
+
.db $80, $F8, $80, $F0, $80, $F0, $80, $F8
|
|
637
|
+
.db $00, $F0, $C0, $F8, $E0, $F0, $E0, $E0
|
|
638
|
+
.db $00, $00, $00, $00, $03, $00, $03, $00
|
|
639
|
+
.db $0F, $00, $00, $00, $00, $00, $00, $00
|
|
640
|
+
; tile 18 - blank
|
|
641
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
642
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
643
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
644
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
645
|
+
; tile 19 - blank
|
|
646
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
647
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
648
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
649
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
650
|
+
; tile 20 - blank
|
|
651
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
652
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
653
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
654
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
655
|
+
; tile 21 - blank
|
|
656
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
657
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
658
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
659
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
660
|
+
; tile 22 - blank
|
|
661
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
662
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
663
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
664
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
665
|
+
; tile 23 - blank
|
|
666
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
667
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
668
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
669
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
670
|
+
; tile 24 - blank
|
|
671
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
672
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
673
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
674
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
675
|
+
; tile 25 - blank
|
|
676
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
677
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
678
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
679
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
680
|
+
; tile 26 - blank
|
|
681
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
682
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
683
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
684
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
685
|
+
; tile 27 - blank
|
|
686
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
687
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
688
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
689
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
690
|
+
; tile 28 - blank
|
|
691
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
692
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
693
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
694
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
695
|
+
; tile 29 - blank
|
|
696
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
697
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
698
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
699
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
700
|
+
; tile 30 - blank
|
|
701
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
702
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
703
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
704
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
705
|
+
; tile 31 - blank
|
|
706
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
707
|
+
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
349
708
|
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
350
709
|
.db $00, $00, $00, $00, $00, $00, $00, $00
|
|
351
|
-
.db $00, $00, $00, $00, $00, $00
|
|
352
710
|
|
|
353
711
|
.ends
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
;==LoRom== racing 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 "best time" 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 HDMA tables land 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 "EMBER CIRCUIT " ; 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
|