-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathMakefile
More file actions
296 lines (257 loc) · 9.57 KB
/
Copy pathMakefile
File metadata and controls
296 lines (257 loc) · 9.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
# Galaxian BASIC - Makefile
# Build runtime for Galaxian/Scramble hardware. Run from galaxian-basic/ directory.
# All output stays in galaxian-basic/ (build/, scramble/).
#
# BASIC -> C -> ROM pipeline:
# make PROGRAM=examples/hello.bas # Compile BASIC to ROM
# make PROGRAM=examples/hello.bas run
#
# Default (no PROGRAM): builds demo with bouncing sprites.
#
# Pac-Man (Namco): TARGET=pacman — CPU ROM only; stock gfx from pacman.5e/5f + proms.
# make TARGET=pacman PROGRAM=examples/hello.bas run-pacman
PARENT := ..
BUILD_DIR = build
SCRAMBLE_DIR = scramble
# PROGRAM=path/to/file.bas compiles BASIC to C and builds ROM
# Default: examples/demo.bas (bouncing sprites + scrolling)
PROGRAM ?= examples/demo.bas
# SDCC 3.8.0
SDCC_HOME ?= $(HOME)/Downloads/sdcc-3.8.0
SDCC_BIN ?= $(SDCC_HOME)/bin
SDCC_LIB ?= $(SDCC_HOME)/share/sdcc/lib/z80
CC = $(SDCC_BIN)/sdcc
AS = $(SDCC_BIN)/sdasz80
LD = $(SDCC_BIN)/sdldz80
TARGET ?= galaxian
GFXDATA_H = $(BUILD_DIR)/gfxdata.h
ifeq ($(TARGET),pacman)
PROJECT_NAME := pacman-basic-game
CRT0_ASM := lib/crt0_pacman.asm
RUNTIME_C := lib/runtime_pacman.c
LDFLAGS := -mjwxyu -i $(BUILD_DIR)/main.ihx -b _CODE=0x0 -b _DATA=0x4C00 -b _INITIALIZER=0x3C00 -k $(SDCC_LIB) -l z80
HEX2ROM := scripts/hex2rom_pacman.py
RUNTIME_EXTRA_DEPS :=
else
PROJECT_NAME ?= galaxian-scramble-game
CRT0_ASM := lib/crt0.asm
RUNTIME_C := lib/runtime.c
LDFLAGS := -mjwxyu -i $(BUILD_DIR)/main.ihx -b _CODE=0x0 -b _DATA=0x4000 -b _INITIALIZER=0x3C00 -k $(SDCC_LIB) -l z80
HEX2ROM := $(PARENT)/hex2rom.py
RUNTIME_EXTRA_DEPS := $(GFXDATA_H)
endif
ROM_FILE = $(BUILD_DIR)/$(PROJECT_NAME).rom
MAP_FILE = $(BUILD_DIR)/$(PROJECT_NAME).map
DEMO_C = src/demo.c
PROGRAM_C = $(BUILD_DIR)/program.c
# Plain C main for Pac-Man only (no BASIC). Example: PACMAN_C_MAIN=examples/pacman_minimal.c
# (Must use ?= so `make PACMAN_C_MAIN=...` is not overwritten.)
ifeq ($(TARGET),pacman)
PACMAN_C_MAIN ?=
endif
# When PROGRAM is set: program.rel. Else: demo.rel (galaxian) or demo.rel (pacman without PACMAN_C_MAIN)
ifeq ($(TARGET),pacman)
ifneq ($(strip $(PACMAN_C_MAIN)),)
MAIN_OBJ := $(BUILD_DIR)/pacman_c.rel
MAIN_SRC := $(PACMAN_C_MAIN)
MAIN_LST := $(BUILD_DIR)/pacman_c.lst
else
ifeq ($(PROGRAM),)
MAIN_OBJ := $(BUILD_DIR)/demo.rel
MAIN_SRC := $(DEMO_C)
MAIN_LST := $(BUILD_DIR)/demo.lst
else
MAIN_OBJ := $(BUILD_DIR)/program.rel
MAIN_SRC := $(PROGRAM_C)
MAIN_LST := $(BUILD_DIR)/program.lst
endif
endif
else
ifeq ($(PROGRAM),)
MAIN_OBJ := $(BUILD_DIR)/demo.rel
MAIN_SRC := $(DEMO_C)
MAIN_LST := $(BUILD_DIR)/demo.lst
else
MAIN_OBJ := $(BUILD_DIR)/program.rel
MAIN_SRC := $(PROGRAM_C)
MAIN_LST := $(BUILD_DIR)/program.lst
endif
endif
OBJECTS = $(BUILD_DIR)/crt0.rel $(BUILD_DIR)/runtime.rel $(MAIN_OBJ)
# Graphics: always use .gfx.json as source (PROGRAM's or default)
GFX_JSON = $(patsubst %.bas,%.gfx.json,$(PROGRAM))
DEFAULT_GFX = lib/default.gfx.json
CFLAGS = --vc --std-sdcc99 -mz80 --less-pedantic --oldralloc --no-peep --nolospre
# Pac-Man: PACMAN_VRAM_TEST=1 fills VRAM at boot (optional debug; use examples/pacman_ramtest.bas — no CLS)
# PACMAN_TILE_COLOR_RAM=1 enables writes to 0x4400 (default on for visible text)
ifeq ($(TARGET),pacman)
PACMAN_VRAM_TEST ?= 0
ifeq ($(PACMAN_VRAM_TEST),1)
CFLAGS += -DPACMAN_VRAM_TEST=1
endif
PACMAN_TILE_COLOR_RAM ?= 1
ifeq ($(PACMAN_TILE_COLOR_RAM),1)
CFLAGS += -DPACMAN_TILE_COLOR_RAM=1
endif
endif
# -l: per-module .lst (crt0.lst, runtime.lst, program.lst) for debugging
ASFLAGS = -plosgffwyu -l
INCLUDES = -I$(BUILD_DIR) -I. -Ilib
.PHONY: all run run-pacman run-pacman-minimal clean check-sdcc info help
all: check-sdcc $(ROM_FILE) post-build
help:
@echo "Galaxian BASIC - Makefile"
@echo ""
@echo "Targets:"
@echo " make [all] - Build ROM (default: examples/demo.bas)"
@echo " make run - Build and run in MAME (detects TARGET)"
@echo " make clean - Remove build artifacts (keeps crt0.asm)"
@echo " make info - Show ROM info"
@echo ""
@echo "Pac-Man target (see README_PACMAN.md):"
@echo " make TARGET=pacman PROGRAM=examples/hello.bas run"
@echo " make run-pacman PROGRAM=examples/hello.bas - Shortcut (forces TARGET=pacman)"
@echo ""
@echo "BASIC -> ROM pipeline:"
@echo " make - Build demo.bas (bouncing sprites)"
@echo " make PROGRAM=examples/hello.bas"
@echo " make PROGRAM=examples/chase.bas run - Joystick + enemy"
@echo " make PROGRAM=examples/sprite.bas run"
@echo " make PROGRAM= - Build C demo (no BASIC)"
@echo ""
@echo "Output: build/$(PROJECT_NAME).rom, scramble/*.2d etc"
@echo "MAME: mame scramble -rompath ."
@echo ""
@echo "Graphics:"
@echo " make gfx-export - Export default gfx to examples/default.gfx.json"
@echo " make PROGRAM=x.bas - Uses x.gfx.json if present (same dir as .bas)"
check-sdcc:
@if [ ! -x "$(CC)" ]; then \
echo "Error: SDCC not found at $(CC)"; \
exit 1; \
fi
@echo "Using SDCC from $(SDCC_HOME)"
@$(CC) --version | head -1
# BASIC -> C compilation - always rebuild when PROGRAM is set (it may have changed)
.PHONY: .force-program
.force-program:
$(PROGRAM_C): $(PROGRAM) .force-program
@mkdir -p $(BUILD_DIR)
@echo "Compiling BASIC: $(PROGRAM) -> $@"
@python3 scripts/gbasic.py $(PROGRAM) -o $@
$(GFXDATA_H):
@mkdir -p $(BUILD_DIR)
@if [ -n "$(GFX_JSON)" ] && [ -f "$(GFX_JSON)" ]; then \
echo "Graphics: $(GFX_JSON) -> $@"; \
python3 scripts/gfxmanager.py to-header $(GFX_JSON) -o $@; \
else \
echo "Graphics: $(DEFAULT_GFX) -> $@"; \
python3 scripts/gfxmanager.py to-header $(DEFAULT_GFX) -o $@; \
fi
$(BUILD_DIR)/runtime.asm: $(RUNTIME_C) $(RUNTIME_EXTRA_DEPS)
@mkdir -p $(BUILD_DIR)
@echo "Compiling $(RUNTIME_C) ..."
$(CC) -S $(CFLAGS) $(INCLUDES) -o $@ $<
$(BUILD_DIR)/program.asm: $(PROGRAM_C)
@mkdir -p $(BUILD_DIR)
@echo "Compiling $(PROGRAM_C) ..."
$(CC) -S $(CFLAGS) $(INCLUDES) -o $@ $<
$(BUILD_DIR)/program.rel: $(BUILD_DIR)/program.asm
@echo "Assembling program.asm ..."
$(AS) $(ASFLAGS) -o $@ $<
$(BUILD_DIR)/demo.rel: $(DEMO_C)
@mkdir -p $(BUILD_DIR)
@echo "Compiling $(DEMO_C) ..."
$(CC) -S $(CFLAGS) $(INCLUDES) -o $(BUILD_DIR)/demo.asm $<
$(AS) $(ASFLAGS) -o $@ $(BUILD_DIR)/demo.asm
$(BUILD_DIR)/pacman_c.rel: $(PACMAN_C_MAIN)
@mkdir -p $(BUILD_DIR)
@echo "Compiling $(PACMAN_C_MAIN) ..."
$(CC) -S $(CFLAGS) $(INCLUDES) -o $(BUILD_DIR)/pacman_c.asm $<
$(AS) $(ASFLAGS) -o $@ $(BUILD_DIR)/pacman_c.asm
$(BUILD_DIR)/crt0.rel: $(CRT0_ASM)
@mkdir -p $(BUILD_DIR)
@echo "Assembling $(CRT0_ASM) ..."
$(AS) $(ASFLAGS) -o $@ $<
$(BUILD_DIR)/runtime.rel: $(BUILD_DIR)/runtime.asm
@echo "Assembling runtime.asm ..."
$(AS) $(ASFLAGS) -o $@ $<
$(BUILD_DIR)/main.ihx: $(OBJECTS)
@echo "Linking ..."
$(LD) $(LDFLAGS) $(OBJECTS)
$(ROM_FILE): $(BUILD_DIR)/main.ihx
@mkdir -p $(BUILD_DIR)
@echo "Creating ROM ..."
@python3 $(HEX2ROM) $(BUILD_DIR)/main.ihx $@ || (echo "hex2rom failed"; exit 1)
@echo "ROM: $@"
@ls -la $@
post-build: $(ROM_FILE)
ifeq ($(TARGET),pacman)
@echo "Slicing ROM for MAME pacman ..."
@python3 scripts/slice_pacman.py
@python3 scripts/rom_rom_dump.py $(ROM_FILE) -o $(BUILD_DIR)/$(PROJECT_NAME).rom.flat.lst
@echo "ROM hex dump: $(BUILD_DIR)/$(PROJECT_NAME).rom.flat.lst"
@cat $(BUILD_DIR)/crt0.lst $(BUILD_DIR)/runtime.lst $(MAIN_LST) > $(BUILD_DIR)/$(PROJECT_NAME).merged.lst
@echo "Merged asm listings: $(BUILD_DIR)/$(PROJECT_NAME).merged.lst"
@echo ""
@echo "Build complete. Run: mame pacman -rompath ."
else
@echo "Slicing ROM for MAME scramble ..."
@mkdir -p $(SCRAMBLE_DIR)
@python3 scripts/slice.py
@if [ -f "$(PARENT)/sound.bin" ]; then \
echo "Extracting sound ROMs ..."; \
(cd $(PARENT) && python3 slicesound.py); \
cp $(PARENT)/ot1.5c $(PARENT)/ot2.5d $(PARENT)/ot3.5e $(SCRAMBLE_DIR)/; \
echo "Sound ROMs copied to $(SCRAMBLE_DIR)/"; \
else \
for dir in $(PARENT)/roms/pitfall $(PARENT)/roms_backup/pitfall; do \
if [ -f "$$dir/ot1.5c" ]; then \
echo "Copying sound ROMs from $$dir ..."; \
cp "$$dir/ot1.5c" "$$dir/ot2.5d" "$$dir/ot3.5e" $(SCRAMBLE_DIR)/; \
break; \
fi; \
done; \
fi
@echo ""
@echo "Build complete. Run: mame scramble -rompath ."
endif
run: all
ifeq ($(TARGET),pacman)
@echo "Running MAME pacman ..."
mame pacman -rompath . -window
else
@echo "Running MAME scramble ..."
mame scramble -rompath . -window
endif
run-pacman:
@$(MAKE) TARGET=pacman PROGRAM="$(PROGRAM)" PACMAN_C_MAIN="$(PACMAN_C_MAIN)" \
PACMAN_VRAM_TEST=$(PACMAN_VRAM_TEST) PACMAN_TILE_COLOR_RAM=$(PACMAN_TILE_COLOR_RAM) all
@echo "Running MAME pacman ..."
mame pacman -rompath . -window
# Ultra-minimal Pac-Man: random tilemap + moving sprites (no BASIC)
run-pacman-minimal:
@$(MAKE) TARGET=pacman PACMAN_C_MAIN=examples/pacman_minimal.c all
@echo "Running MAME pacman (pacman_minimal) ..."
mame pacman -rompath . -window
# Clean: remove generated files. Source in lib/, src/, scripts/ preserved.
clean:
@echo "Cleaning build artifacts ..."
rm -rf $(BUILD_DIR)
rm -f *.lst *.sym *.map *.ihx *.lk *.rst *.noi
@echo "Clean done."
info: $(ROM_FILE)
@echo "=== Galaxian BASIC Build ==="
@echo "ROM: $(ROM_FILE)"
@echo "Size: $(shell wc -c < $(ROM_FILE)) bytes"
@echo "Scramble: $(SCRAMBLE_DIR)/ ($(shell ls $(SCRAMBLE_DIR) 2>/dev/null | wc -l) files)"
@if [ -f $(MAP_FILE) ]; then echo ""; echo "=== Symbols ==="; cat $(MAP_FILE); fi
# Web IDE - serve on http://localhost:8080
ide:
@echo "Starting IDE at http://localhost:8080"
cd ide && python3 -m http.server 8080
# Legacy: export gfxdata.h to .gfx.json (only needed for migration)
gfx-export:
@echo "Exporting lib/gfxdata.h -> lib/default.gfx.json"
@python3 scripts/gfxmanager.py from-header lib/gfxdata.h -o lib/default.gfx.json
@echo "Note: .gfx.json is now the source format. lib/gfxdata.h is deprecated."