romdevtools 0.16.0 → 0.22.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 +75 -16
- package/CHANGELOG.md +316 -0
- package/examples/README.md +2 -0
- package/examples/atari2600/templates/platformer.asm +460 -0
- package/examples/atari2600/templates/racing.asm +463 -0
- package/examples/atari2600/templates/shmup.asm +386 -0
- package/examples/atari2600/templates/sports.asm +362 -0
- package/examples/atari7800/templates/default.c +49 -5
- package/examples/atari7800/templates/hello_sprite.c +48 -4
- package/examples/atari7800/templates/music_demo.c +47 -2
- package/examples/atari7800/templates/platformer.c +43 -4
- package/examples/atari7800/templates/puzzle.c +39 -4
- package/examples/atari7800/templates/racing.c +39 -4
- package/examples/atari7800/templates/shmup.c +40 -2
- package/examples/atari7800/templates/sports.c +36 -5
- package/examples/c64/templates/platformer.c +19 -5
- package/examples/c64/templates/puzzle.c +32 -2
- package/examples/c64/templates/shmup.c +28 -2
- package/examples/c64/templates/sports.c +30 -2
- package/examples/c64/templates/tile_engine.c +77 -27
- package/examples/gb/templates/default.c +110 -16
- package/examples/gb/templates/hello_sprite.c +15 -6
- package/examples/gb/templates/music_demo.c +36 -0
- package/examples/gb/templates/platformer.c +28 -6
- package/examples/gb/templates/puzzle.c +35 -4
- package/examples/gb/templates/racing.c +75 -10
- package/examples/gb/templates/shmup.c +41 -3
- package/examples/gb/templates/sports.c +51 -3
- package/examples/gb/templates/tile_engine.c +3 -2
- package/examples/gba/templates/gba_hello.c +29 -11
- package/examples/gba/templates/maxmod_demo.c +36 -2
- package/examples/gba/templates/platformer.c +3 -1
- package/examples/gba/templates/puzzle.c +15 -3
- package/examples/gba/templates/racing.c +65 -3
- package/examples/gba/templates/shmup.c +41 -4
- package/examples/gba/templates/sports.c +36 -2
- package/examples/gba/templates/tonc_hello.c +41 -5
- package/examples/gba/templates/tonc_hello_sprite.c +35 -1
- package/examples/gbc/templates/default.c +103 -26
- package/examples/gbc/templates/hello_sprite.c +12 -3
- package/examples/gbc/templates/music_demo.c +56 -12
- package/examples/gbc/templates/platformer.c +28 -6
- package/examples/gbc/templates/puzzle.c +35 -4
- package/examples/gbc/templates/racing.c +88 -21
- package/examples/gbc/templates/shmup.c +37 -3
- package/examples/gbc/templates/sports.c +48 -3
- package/examples/gbc/templates/tile_engine.c +3 -2
- package/examples/genesis/main.s +53 -1
- package/examples/genesis/templates/hello_sprite.c +25 -3
- package/examples/genesis/templates/puzzle.c +37 -3
- package/examples/genesis/templates/racing.c +44 -11
- package/examples/genesis/templates/sgdk_hello.c +34 -1
- package/examples/genesis/templates/shmup.c +31 -1
- package/examples/genesis/templates/shmup_2p.c +31 -0
- package/examples/genesis/templates/xgm2_demo.c +20 -0
- package/examples/gg/templates/default.c +56 -18
- package/examples/gg/templates/hello_sprite.c +25 -2
- package/examples/gg/templates/music_demo.c +24 -2
- package/examples/gg/templates/platformer.c +18 -12
- package/examples/gg/templates/puzzle.c +38 -7
- package/examples/gg/templates/racing.c +58 -9
- package/examples/gg/templates/shmup.c +47 -3
- package/examples/gg/templates/sports.c +57 -16
- package/examples/gg/templates/tile_engine.c +12 -6
- package/examples/lynx/templates/default.c +39 -8
- package/examples/lynx/templates/hello_sprite.c +15 -1
- package/examples/lynx/templates/music_demo.c +13 -1
- package/examples/lynx/templates/puzzle.c +28 -1
- package/examples/lynx/templates/racing.c +34 -7
- package/examples/lynx/templates/shmup.c +42 -3
- package/examples/lynx/templates/sports.c +29 -2
- package/examples/msx/platformer/main.c +213 -0
- package/examples/msx/puzzle/main.c +250 -0
- package/examples/msx/racing/main.c +249 -0
- package/examples/msx/shmup/main.c +288 -0
- package/examples/msx/sports/main.c +182 -0
- package/examples/nes/templates/default.c +67 -19
- package/examples/nes/templates/hello_sprite.c +35 -0
- package/examples/nes/templates/music_demo.c +40 -0
- package/examples/nes/templates/platformer.c +65 -6
- package/examples/nes/templates/puzzle.c +67 -6
- package/examples/nes/templates/racing.c +45 -13
- package/examples/nes/templates/shmup.c +51 -2
- package/examples/nes/templates/sports.c +51 -6
- package/examples/pce/catch_game/main.c +22 -3
- package/examples/pce/music_sfx/main.c +28 -1
- package/examples/pce/platformer/main.c +283 -0
- package/examples/pce/puzzle/main.c +304 -0
- package/examples/pce/racing/main.c +304 -0
- package/examples/pce/shmup/main.c +346 -0
- package/examples/pce/sports/main.c +254 -0
- package/examples/pce/sprite_move/main.c +7 -2
- package/examples/sms/main.c +35 -6
- package/examples/sms/templates/hello_sprite.c +29 -3
- package/examples/sms/templates/music_demo.c +18 -4
- package/examples/sms/templates/puzzle.c +34 -5
- package/examples/sms/templates/racing.c +39 -2
- package/examples/sms/templates/shmup.c +41 -2
- package/examples/sms/templates/shmup_2p.c +24 -1
- package/examples/sms/templates/sports.c +47 -4
- package/examples/snes/main.asm +108 -17
- package/examples/snes/templates/c-hello-data.asm +23 -0
- package/examples/snes/templates/c-hello.c +18 -1
- package/examples/snes/templates/default.c +50 -28
- package/examples/snes/templates/hello_sprite-data.asm +23 -0
- package/examples/snes/templates/hello_sprite.c +17 -1
- package/examples/snes/templates/music_demo-data.asm +23 -0
- package/examples/snes/templates/music_demo.c +22 -4
- package/examples/snes/templates/platformer-data.asm +22 -0
- package/examples/snes/templates/platformer.c +20 -2
- package/examples/snes/templates/puzzle-data.asm +22 -0
- package/examples/snes/templates/puzzle.c +21 -2
- package/examples/snes/templates/racing-data.asm +22 -0
- package/examples/snes/templates/racing.c +17 -1
- package/examples/snes/templates/shmup-data.asm +22 -0
- package/examples/snes/templates/shmup.c +20 -1
- package/examples/snes/templates/sports-data.asm +22 -0
- package/examples/snes/templates/sports.c +16 -1
- package/package.json +1 -1
- package/src/cheats/gamegenie.js +0 -1
- package/src/cli/smoke.js +1 -3
- 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 +191 -16
- package/src/host/callbacks.js +9 -1
- package/src/host/chafa-render.js +2 -0
- package/src/host/dsp-state.js +2 -2
- package/src/host/gpgx-state.js +4 -0
- package/src/host/types.js +15 -8
- package/src/http/routes.js +1 -1
- package/src/http/tool-registry.js +26 -1
- package/src/mcp/server.js +1 -1
- package/src/mcp/state.js +36 -0
- package/src/mcp/tools/address-to-symbol.js +0 -1
- package/src/mcp/tools/art-loaders.js +1 -1
- package/src/mcp/tools/cart-parts.js +75 -4
- package/src/mcp/tools/classify-region.js +1 -1
- package/src/mcp/tools/diff-roms.js +1 -1
- package/src/mcp/tools/disasm-rebuild.js +507 -0
- package/src/mcp/tools/disasm.js +97 -9
- package/src/mcp/tools/find-references.js +1 -2
- package/src/mcp/tools/font-map.js +1 -1
- package/src/mcp/tools/frame.js +168 -3
- package/src/mcp/tools/index.js +0 -49
- package/src/mcp/tools/input-layout.js +0 -1
- package/src/mcp/tools/input.js +33 -3
- package/src/mcp/tools/lifecycle.js +18 -4
- package/src/mcp/tools/lospec.js +0 -19
- package/src/mcp/tools/platform-docs.js +1 -1
- package/src/mcp/tools/platform-tools.js +4 -4
- package/src/mcp/tools/project.js +54 -11
- package/src/mcp/tools/reinject.js +0 -1
- package/src/mcp/tools/rom-id.js +2 -2
- package/src/mcp/tools/snippets.js +2 -2
- package/src/mcp/tools/sprite-pipeline.js +1 -2
- package/src/mcp/tools/state.js +201 -14
- package/src/mcp/tools/tile-inspect.js +1 -1
- package/src/mcp/tools/toolchain.js +105 -12
- package/src/mcp/tools/watch-memory.js +137 -16
- package/src/platforms/_guides/ROMHACKING_PLAYBOOK.md +34 -0
- package/src/platforms/atari2600/TROUBLESHOOTING.md +6 -0
- package/src/platforms/atari7800/TROUBLESHOOTING.md +6 -0
- package/src/platforms/c64/MENTAL_MODEL.md +45 -1
- package/src/platforms/c64/TROUBLESHOOTING.md +6 -0
- package/src/platforms/c64/d64.js +280 -0
- package/src/platforms/c64/sid.js +0 -2
- package/src/platforms/common/metasprite-adapters.js +1 -1
- package/src/platforms/common/metasprite-codegen.js +3 -3
- package/src/platforms/common/registers.js +5 -3
- package/src/platforms/gb/MENTAL_MODEL.md +10 -0
- package/src/platforms/gb/TROUBLESHOOTING.md +6 -0
- package/src/platforms/gb/lib/c/gb_runtime.c +4 -4
- package/src/platforms/gba/TROUBLESHOOTING.md +6 -0
- package/src/platforms/gbc/TROUBLESHOOTING.md +6 -0
- package/src/platforms/gbc/lib/c/gb_runtime.c +4 -4
- package/src/platforms/genesis/TROUBLESHOOTING.md +6 -0
- package/src/platforms/gg/TROUBLESHOOTING.md +6 -0
- package/src/platforms/lynx/TROUBLESHOOTING.md +6 -0
- package/src/platforms/msx/MENTAL_MODEL.md +10 -6
- package/src/platforms/msx/TROUBLESHOOTING.md +6 -0
- package/src/platforms/nes/MENTAL_MODEL.md +63 -2
- package/src/platforms/nes/TROUBLESHOOTING.md +6 -0
- package/src/platforms/nes/image-to-tilemap.js +3 -0
- package/src/platforms/nes/lib/asm/famitone2.s +5 -1
- package/src/platforms/pce/MENTAL_MODEL.md +9 -4
- package/src/platforms/pce/TROUBLESHOOTING.md +6 -0
- package/src/platforms/pce/lib/c/pce_video.c +1 -1
- package/src/platforms/sms/TROUBLESHOOTING.md +6 -0
- package/src/platforms/snes/TROUBLESHOOTING.md +6 -0
- package/src/platforms/snes/brr.js +0 -2
- package/src/playtest/playtest.js +0 -7
- package/src/rom-id/identifier.js +15 -0
- package/src/toolchains/asar/asar.js +0 -9
- package/src/toolchains/assemble-snippet.js +30 -12
- package/src/toolchains/cc65/ines.js +145 -0
- package/src/toolchains/cc65/presets/nes/chr-ram-runtime.cfg +14 -1
- package/src/toolchains/cc65/presets/nes/chr-rom.cfg +83 -0
- package/src/toolchains/cc65/presets/nes/chr-rom.crt0.s +153 -0
- package/src/toolchains/common/reassemble.js +10 -3
- package/src/toolchains/common/sdk-cache.js +1 -1
- package/src/toolchains/genesis-c/genesis-c.js +5 -3
- package/src/toolchains/index.js +27 -3
- package/src/toolchains/parse-errors.js +78 -1
- package/src/toolchains/sdcc/preflight-lint.js +5 -1
- package/src/toolchains/sdcc/sdcc.js +1 -1
- package/src/toolchains/sjasm/sjasm.js +1 -1
- package/src/toolchains/snes-c/snes-c.js +2 -2
- package/src/toolchains/vasm68k/vasm68k.js +2 -4
- package/src/toolchains/wladx/wladx.js +1 -1
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
; ── shmup.asm — Atari 2600 SHMUP genre scaffold ─────────────────────
|
|
2
|
+
;
|
|
3
|
+
; The 2600's flagship genre — Space Invaders, Galaxian, Demon Attack
|
|
4
|
+
; were all fixed/gallery shooters, because that is exactly what the TIA
|
|
5
|
+
; is good at. This is the canonical 2600 shmup, identical in spirit to
|
|
6
|
+
; the verified `mini_invaders` template.
|
|
7
|
+
;
|
|
8
|
+
; A fixed-shooter / gallery-shooter 2600 game that uses the RIGHT TIA
|
|
9
|
+
; objects instead of playfield "barcode" bars (see the note at the bottom).
|
|
10
|
+
;
|
|
11
|
+
; TIA object roles (the canonical layout for this genre):
|
|
12
|
+
; P0 = player cannon (double-width via NUSIZ0 = %00000111)
|
|
13
|
+
; P1 + NUSIZ1 = %011 (3 medium-spaced copies) = a ROW OF INVADERS
|
|
14
|
+
; → one GRP1 write draws three aliens, hardware-replicated.
|
|
15
|
+
; M0 = the player's shot
|
|
16
|
+
; PF = a thin ground line only (NOT the aliens — playfield bits look
|
|
17
|
+
; like a barcode; real sprites read as actual invaders).
|
|
18
|
+
;
|
|
19
|
+
; The aliens march left/right as a block (move P1's X), drop a step at
|
|
20
|
+
; the edges, and you shoot upward with the joystick button. This is the
|
|
21
|
+
; deliberately-small but visually-honest version of the genre on the
|
|
22
|
+
; 2600 — extend it by reusing P1 again lower down for shields, or
|
|
23
|
+
; adding M1 as an alien bomb.
|
|
24
|
+
;
|
|
25
|
+
; NTSC kernel: 3 VSYNC + 37 VBLANK + 192 visible + 30 overscan.
|
|
26
|
+
|
|
27
|
+
processor 6502
|
|
28
|
+
org $F000
|
|
29
|
+
|
|
30
|
+
VSYNC = $00
|
|
31
|
+
VBLANK = $01
|
|
32
|
+
WSYNC = $02
|
|
33
|
+
NUSIZ0 = $04
|
|
34
|
+
NUSIZ1 = $05
|
|
35
|
+
COLUP0 = $06
|
|
36
|
+
COLUP1 = $07
|
|
37
|
+
COLUPF = $08
|
|
38
|
+
COLUBK = $09
|
|
39
|
+
CTRLPF = $0A
|
|
40
|
+
RESP0 = $10
|
|
41
|
+
RESP1 = $11
|
|
42
|
+
RESM0 = $12
|
|
43
|
+
GRP0 = $1B
|
|
44
|
+
GRP1 = $1C
|
|
45
|
+
ENAM0 = $1D
|
|
46
|
+
PF0 = $0D
|
|
47
|
+
HMP0 = $20
|
|
48
|
+
HMP1 = $21
|
|
49
|
+
HMM0 = $22
|
|
50
|
+
HMOVE = $2A
|
|
51
|
+
HMCLR = $2B
|
|
52
|
+
SWCHA = $280
|
|
53
|
+
INPT4 = $0C ; P0 fire (active-low, bit 7)
|
|
54
|
+
AUDC0 = $15
|
|
55
|
+
AUDF0 = $17
|
|
56
|
+
AUDV0 = $19
|
|
57
|
+
|
|
58
|
+
; Zero page
|
|
59
|
+
P_X = $80 ; player cannon X (visible column)
|
|
60
|
+
ALIEN_X = $81 ; left edge of the alien block (P1 X)
|
|
61
|
+
ALIEN_Y = $82 ; top scanline of the alien row
|
|
62
|
+
ALIEN_DIR = $83 ; 1 = right, $FF = left
|
|
63
|
+
SHOT_X = $84
|
|
64
|
+
SHOT_Y = $85 ; $FF = no shot active
|
|
65
|
+
FRAME = $86
|
|
66
|
+
MARCH = $87 ; march timer
|
|
67
|
+
SFX_LEFT = $88
|
|
68
|
+
|
|
69
|
+
START:
|
|
70
|
+
SEI
|
|
71
|
+
CLD
|
|
72
|
+
LDX #$FF
|
|
73
|
+
TXS
|
|
74
|
+
LDA #0
|
|
75
|
+
.clr:
|
|
76
|
+
STA $00,X
|
|
77
|
+
DEX
|
|
78
|
+
BNE .clr
|
|
79
|
+
|
|
80
|
+
LDA #76
|
|
81
|
+
STA P_X
|
|
82
|
+
LDA #40
|
|
83
|
+
STA ALIEN_X
|
|
84
|
+
LDA #60
|
|
85
|
+
STA ALIEN_Y
|
|
86
|
+
LDA #1
|
|
87
|
+
STA ALIEN_DIR
|
|
88
|
+
LDA #$FF
|
|
89
|
+
STA SHOT_Y ; no shot yet
|
|
90
|
+
|
|
91
|
+
; Colours
|
|
92
|
+
LDA #$06 ; dark blue-grey bg
|
|
93
|
+
STA COLUBK
|
|
94
|
+
LDA #$1E ; yellow cannon
|
|
95
|
+
STA COLUP0
|
|
96
|
+
LDA #$46 ; red-ish aliens
|
|
97
|
+
STA COLUP1
|
|
98
|
+
LDA #$0A ; grey ground line
|
|
99
|
+
STA COLUPF
|
|
100
|
+
|
|
101
|
+
; Object sizes: P0 double-width; P1 = 3 medium-spaced copies.
|
|
102
|
+
LDA #%00000101 ; NUSIZ0: P0 double size (2x width)
|
|
103
|
+
STA NUSIZ0
|
|
104
|
+
LDA #%00000011 ; NUSIZ1: three copies, medium spacing
|
|
105
|
+
STA NUSIZ1
|
|
106
|
+
LDA #1
|
|
107
|
+
STA CTRLPF ; PF reflected (symmetric ground)
|
|
108
|
+
|
|
109
|
+
MAIN:
|
|
110
|
+
INC FRAME
|
|
111
|
+
|
|
112
|
+
; ── VSYNC (3 lines) ──
|
|
113
|
+
LDA #2
|
|
114
|
+
STA VSYNC
|
|
115
|
+
STA WSYNC
|
|
116
|
+
STA WSYNC
|
|
117
|
+
STA WSYNC
|
|
118
|
+
LDA #0
|
|
119
|
+
STA VSYNC
|
|
120
|
+
|
|
121
|
+
; ── VBLANK (37 lines) — do all game logic here ──
|
|
122
|
+
LDA #2
|
|
123
|
+
STA VBLANK
|
|
124
|
+
LDX #37
|
|
125
|
+
.vb:
|
|
126
|
+
STA WSYNC
|
|
127
|
+
DEX
|
|
128
|
+
BNE .vb
|
|
129
|
+
|
|
130
|
+
; Player move (every 2nd frame), joystick port A high nibble.
|
|
131
|
+
LDA FRAME
|
|
132
|
+
AND #$01
|
|
133
|
+
BNE .skipmove
|
|
134
|
+
LDA SWCHA
|
|
135
|
+
ASL ; bit7 = P0 Right
|
|
136
|
+
BCS .nr
|
|
137
|
+
LDA P_X
|
|
138
|
+
CMP #140
|
|
139
|
+
BCS .nr
|
|
140
|
+
INC P_X
|
|
141
|
+
INC P_X
|
|
142
|
+
.nr:
|
|
143
|
+
ASL ; bit6 = P0 Left
|
|
144
|
+
BCS .nl
|
|
145
|
+
LDA P_X
|
|
146
|
+
CMP #10
|
|
147
|
+
BCC .nl
|
|
148
|
+
DEC P_X
|
|
149
|
+
DEC P_X
|
|
150
|
+
.nl:
|
|
151
|
+
.skipmove:
|
|
152
|
+
|
|
153
|
+
; Fire on button (INPT4 bit7 active-low) if no shot active.
|
|
154
|
+
LDA SHOT_Y
|
|
155
|
+
CMP #$FF
|
|
156
|
+
BNE .noFire
|
|
157
|
+
BIT INPT4
|
|
158
|
+
BMI .noFire ; bit7 set = not pressed
|
|
159
|
+
LDA P_X
|
|
160
|
+
CLC
|
|
161
|
+
ADC #4
|
|
162
|
+
STA SHOT_X
|
|
163
|
+
LDA #180
|
|
164
|
+
STA SHOT_Y
|
|
165
|
+
; pew sfx
|
|
166
|
+
LDA #$04
|
|
167
|
+
STA AUDC0
|
|
168
|
+
LDA #$08
|
|
169
|
+
STA AUDF0
|
|
170
|
+
LDA #$0C
|
|
171
|
+
STA AUDV0
|
|
172
|
+
LDA #6
|
|
173
|
+
STA SFX_LEFT
|
|
174
|
+
.noFire:
|
|
175
|
+
|
|
176
|
+
; Move shot up 4px/frame; despawn past the aliens.
|
|
177
|
+
LDA SHOT_Y
|
|
178
|
+
CMP #$FF
|
|
179
|
+
BEQ .noShotMove
|
|
180
|
+
SEC
|
|
181
|
+
SBC #4
|
|
182
|
+
STA SHOT_Y
|
|
183
|
+
CMP #50
|
|
184
|
+
BCS .noShotMove
|
|
185
|
+
LDA #$FF
|
|
186
|
+
STA SHOT_Y
|
|
187
|
+
.noShotMove:
|
|
188
|
+
|
|
189
|
+
; March the alien block every 24 frames.
|
|
190
|
+
INC MARCH
|
|
191
|
+
LDA MARCH
|
|
192
|
+
CMP #24
|
|
193
|
+
BCC .noMarch
|
|
194
|
+
LDA #0
|
|
195
|
+
STA MARCH
|
|
196
|
+
LDA ALIEN_DIR
|
|
197
|
+
BMI .marchLeft
|
|
198
|
+
LDA ALIEN_X
|
|
199
|
+
CMP #96
|
|
200
|
+
BCS .flip ; hit right edge → reverse + drop
|
|
201
|
+
CLC
|
|
202
|
+
ADC #6
|
|
203
|
+
STA ALIEN_X
|
|
204
|
+
JMP .noMarch
|
|
205
|
+
.marchLeft:
|
|
206
|
+
LDA ALIEN_X
|
|
207
|
+
CMP #14
|
|
208
|
+
BCC .flip ; hit left edge → reverse + drop
|
|
209
|
+
SEC
|
|
210
|
+
SBC #6
|
|
211
|
+
STA ALIEN_X
|
|
212
|
+
JMP .noMarch
|
|
213
|
+
.flip:
|
|
214
|
+
; Reverse direction and step the whole row DOWN one notch. ALIEN_Y is
|
|
215
|
+
; the row's top scanline; SMALLER Y = lower on screen (Y counts 192→1),
|
|
216
|
+
; so "drop" means decrement ALIEN_Y. Stop dropping once they reach the
|
|
217
|
+
; player's row (game-over territory — kept simple here: clamp).
|
|
218
|
+
LDA ALIEN_DIR
|
|
219
|
+
EOR #$FE ; 1 <-> $FF
|
|
220
|
+
STA ALIEN_DIR
|
|
221
|
+
LDA ALIEN_Y
|
|
222
|
+
CMP #30
|
|
223
|
+
BCC .noMarch ; already near the bottom — don't go further
|
|
224
|
+
SEC
|
|
225
|
+
SBC #6
|
|
226
|
+
STA ALIEN_Y
|
|
227
|
+
.noMarch:
|
|
228
|
+
|
|
229
|
+
; sfx countdown
|
|
230
|
+
LDA SFX_LEFT
|
|
231
|
+
BEQ .sfxDone
|
|
232
|
+
DEC SFX_LEFT
|
|
233
|
+
BNE .sfxDone
|
|
234
|
+
LDA #0
|
|
235
|
+
STA AUDV0
|
|
236
|
+
.sfxDone:
|
|
237
|
+
|
|
238
|
+
; ── Position objects (race-the-beam) ──
|
|
239
|
+
; P0 (player) at column P_X.
|
|
240
|
+
STA WSYNC
|
|
241
|
+
STA HMCLR
|
|
242
|
+
LDX P_X
|
|
243
|
+
LDA #0
|
|
244
|
+
.p0pos:
|
|
245
|
+
CPX #15
|
|
246
|
+
BCC .p0done
|
|
247
|
+
SEC
|
|
248
|
+
SBC #15
|
|
249
|
+
TAX
|
|
250
|
+
JMP .p0pos
|
|
251
|
+
.p0done:
|
|
252
|
+
STA RESP0
|
|
253
|
+
; P1 (alien block) at column ALIEN_X.
|
|
254
|
+
STA WSYNC
|
|
255
|
+
LDX ALIEN_X
|
|
256
|
+
LDA #0
|
|
257
|
+
.p1pos:
|
|
258
|
+
CPX #15
|
|
259
|
+
BCC .p1done
|
|
260
|
+
SEC
|
|
261
|
+
SBC #15
|
|
262
|
+
TAX
|
|
263
|
+
JMP .p1pos
|
|
264
|
+
.p1done:
|
|
265
|
+
STA RESP1
|
|
266
|
+
; M0 (shot) at column SHOT_X.
|
|
267
|
+
STA WSYNC
|
|
268
|
+
LDX SHOT_X
|
|
269
|
+
LDA #0
|
|
270
|
+
.m0pos:
|
|
271
|
+
CPX #15
|
|
272
|
+
BCC .m0done
|
|
273
|
+
SEC
|
|
274
|
+
SBC #15
|
|
275
|
+
TAX
|
|
276
|
+
JMP .m0pos
|
|
277
|
+
.m0done:
|
|
278
|
+
STA RESM0
|
|
279
|
+
STA HMOVE
|
|
280
|
+
|
|
281
|
+
LDA #0
|
|
282
|
+
STA VBLANK
|
|
283
|
+
|
|
284
|
+
; ── Visible (192 lines) ──
|
|
285
|
+
LDY #192
|
|
286
|
+
.draw:
|
|
287
|
+
STA WSYNC
|
|
288
|
+
|
|
289
|
+
; Player cannon: 8 rows around scanline 176 (near the bottom).
|
|
290
|
+
TYA
|
|
291
|
+
SEC
|
|
292
|
+
SBC #16 ; 192-176 region → small Y window near bottom
|
|
293
|
+
CMP #8
|
|
294
|
+
BCS .pBlank
|
|
295
|
+
TAX
|
|
296
|
+
LDA SHIP,X
|
|
297
|
+
STA GRP0
|
|
298
|
+
JMP .pDone
|
|
299
|
+
.pBlank:
|
|
300
|
+
LDA #0
|
|
301
|
+
STA GRP0
|
|
302
|
+
.pDone:
|
|
303
|
+
|
|
304
|
+
; Alien row: 8 rows starting at ALIEN_Y, drawn via P1 (NUSIZ1 gives
|
|
305
|
+
; 3 hardware copies, so one GRP1 write paints all three invaders).
|
|
306
|
+
; Window: (Y - ALIEN_Y) in [0..7] → index into the ALIEN bitmap.
|
|
307
|
+
TYA
|
|
308
|
+
SEC
|
|
309
|
+
SBC ALIEN_Y
|
|
310
|
+
CMP #8
|
|
311
|
+
BCS .aBlank
|
|
312
|
+
TAX
|
|
313
|
+
LDA ALIEN,X
|
|
314
|
+
STA GRP1
|
|
315
|
+
JMP .aDone
|
|
316
|
+
.aBlank:
|
|
317
|
+
LDA #0
|
|
318
|
+
STA GRP1
|
|
319
|
+
.aDone:
|
|
320
|
+
|
|
321
|
+
; Shot: enable M0 for 4 lines around SHOT_Y.
|
|
322
|
+
TYA
|
|
323
|
+
SEC
|
|
324
|
+
SBC SHOT_Y
|
|
325
|
+
CMP #4
|
|
326
|
+
BCS .sBlank
|
|
327
|
+
LDA #2
|
|
328
|
+
STA ENAM0
|
|
329
|
+
JMP .sDone
|
|
330
|
+
.sBlank:
|
|
331
|
+
LDA #0
|
|
332
|
+
STA ENAM0
|
|
333
|
+
.sDone:
|
|
334
|
+
|
|
335
|
+
; Ground line near the very bottom via PF0.
|
|
336
|
+
CPY #6
|
|
337
|
+
BCS .noGround
|
|
338
|
+
LDA #$F0
|
|
339
|
+
STA PF0
|
|
340
|
+
JMP .gDone
|
|
341
|
+
.noGround:
|
|
342
|
+
LDA #0
|
|
343
|
+
STA PF0
|
|
344
|
+
.gDone:
|
|
345
|
+
|
|
346
|
+
DEY
|
|
347
|
+
BNE .draw
|
|
348
|
+
|
|
349
|
+
; ── Overscan (30 lines) ──
|
|
350
|
+
LDA #2
|
|
351
|
+
STA VBLANK
|
|
352
|
+
LDX #30
|
|
353
|
+
.os:
|
|
354
|
+
STA WSYNC
|
|
355
|
+
DEX
|
|
356
|
+
BNE .os
|
|
357
|
+
|
|
358
|
+
JMP MAIN
|
|
359
|
+
|
|
360
|
+
; 8-row cannon silhouette (double-width via NUSIZ0).
|
|
361
|
+
SHIP:
|
|
362
|
+
.byte %00011000
|
|
363
|
+
.byte %00011000
|
|
364
|
+
.byte %00111100
|
|
365
|
+
.byte %01111110
|
|
366
|
+
.byte %11111111
|
|
367
|
+
.byte %11111111
|
|
368
|
+
.byte %11111111
|
|
369
|
+
.byte %11100111
|
|
370
|
+
|
|
371
|
+
; 8-row invader silhouette — drawn via P1 with NUSIZ1=%011 so it
|
|
372
|
+
; hardware-replicates into 3 medium-spaced aliens from one GRP1 write.
|
|
373
|
+
ALIEN:
|
|
374
|
+
.byte %00100100
|
|
375
|
+
.byte %00111100
|
|
376
|
+
.byte %01111110
|
|
377
|
+
.byte %11011011
|
|
378
|
+
.byte %11111111
|
|
379
|
+
.byte %01011010
|
|
380
|
+
.byte %00100100
|
|
381
|
+
.byte %01000010
|
|
382
|
+
|
|
383
|
+
org $FFFA
|
|
384
|
+
.word START
|
|
385
|
+
.word START
|
|
386
|
+
.word START
|