212 lines
9.5 KiB
Makefile
212 lines
9.5 KiB
Makefile
# Apple IIgs build rules.
|
|
#
|
|
# Uses GoldenGate's iix to drive ORCA/C 2.1.0 + ORCA Linker. The
|
|
# toolchains/iigs/iix-build.sh wrapper handles ORCA's case-sensitivity
|
|
# quirks (lowercase .a/.root/.sym vs linker demands for uppercase),
|
|
# multi-source compile/link, and pragma injection for include paths
|
|
# and the stdint/stdbool shim headers.
|
|
|
|
include $(dir $(lastword $(MAKEFILE_LIST)))/common.mk
|
|
|
|
PLATFORM := iigs
|
|
BUILD := $(REPO_DIR)/build/$(PLATFORM)
|
|
BINDIR := $(BUILD)/bin
|
|
|
|
PORT_C_SRCS_ALL := $(wildcard $(SRC_PORT)/iigs/*.c)
|
|
# Hand-rolled .asm sources go through ORCA's macro assembler via
|
|
# iix-build.sh's `assemble` dispatch. Each .asm declares its target
|
|
# load segment in the START operand (e.g. peislam.asm -> PEISLAMS)
|
|
# so the linker places its bytes in a separate bank from _ROOT.
|
|
# See ORCA/M for IIgs ch. 6 "Load Segments" for the mechanism.
|
|
PORT_ASM_SRCS_ALL := $(wildcard $(SRC_PORT)/iigs/*.asm)
|
|
|
|
# audio_full.c declares its functions in the AUDIOIMPL load segment
|
|
# (`segment "AUDIOIMPL"` at file scope, see ORCA/C ch. 30) so the
|
|
# implementation code lives in its own bank, not _ROOT. That lets
|
|
# the same source link into every binary, replacing the earlier
|
|
# audio.c-stub vs audio_full.c-real split. The 34 KB NTP replayer
|
|
# bytes still ride along via the xxd-baked header.
|
|
PORT_C_SRCS := $(PORT_C_SRCS_ALL)
|
|
|
|
# IIgs uses NTPstreamsound for SFX, not the libxmp+overlay combo that
|
|
# DOS and ST share, so src/core/audioSfxMix.c is unused here. Filter
|
|
# it out so the ORCA Linker doesn't pull its dead code into every
|
|
# IIgs binary (the monolithic-link budget is tight).
|
|
CORE_C_SRCS_IIGS := $(filter-out %/audioSfxMix.c, $(CORE_C_SRCS))
|
|
|
|
# Sprite codegen: 65816 emitter + cross-platform compile dispatch.
|
|
CODEGEN_SRCS := $(REPO_DIR)/src/codegen/spriteEmitIigs.c \
|
|
$(REPO_DIR)/src/codegen/spriteCompile.c
|
|
|
|
# NinjaTrackerPlus replayer. Assembled with Merlin32 from the staged
|
|
# source at toolchains/iigs/ntp/ninjatrackerplus.s. Output is a 34 KB
|
|
# raw 65816 binary that the IIgs audio HAL loads at runtime via
|
|
# Memory Manager into a fixed-bank handle. NTP source is bank-internal
|
|
# (no JSL/JML cross-bank jumps) so the player works at any bank-start
|
|
# load address even though it was assembled with `org $0F0000`.
|
|
NTP_SRC := $(REPO_DIR)/toolchains/iigs/ntp/ninjatrackerplus.s
|
|
NTP_BIN := $(BUILD)/audio/ntpplayer.bin
|
|
NTP_ASM := $(BUILD)/audio/ntpdata.asm
|
|
IIGS_MERLIN := $(REPO_DIR)/toolchains/iigs/merlin32/bin/merlin32
|
|
|
|
LIB_SRCS := $(CORE_C_SRCS_IIGS) $(PORT_C_SRCS) $(PORT_ASM_SRCS_ALL) $(NTP_ASM) $(CODEGEN_SRCS)
|
|
|
|
# HELLO is omitted from the disk because UBER exercises everything it
|
|
# does and the disk was tight. PATTERN is included as the SCB / palette
|
|
# golden-reference for cross-port debugging.
|
|
PATTERN_SRC := $(EXAMPLES)/pattern/pattern.c
|
|
PATTERN_BIN := $(BINDIR)/PATTERN
|
|
DRAW_SRC := $(EXAMPLES)/draw/draw.c
|
|
DRAW_BIN := $(BINDIR)/DRAW
|
|
KEYS_SRC := $(EXAMPLES)/keys/keys.c
|
|
KEYS_BIN := $(BINDIR)/KEYS
|
|
JOY_SRC := $(EXAMPLES)/joy/joy.c
|
|
JOY_BIN := $(BINDIR)/JOY
|
|
SPRITE_SRC := $(EXAMPLES)/sprite/sprite.c
|
|
SPRITE_BIN := $(BINDIR)/SPRITE
|
|
UBER_SRC := $(EXAMPLES)/uber/uber.c
|
|
UBER_BIN := $(BINDIR)/UBER
|
|
AUDIO_SRC := $(EXAMPLES)/audio/audio.c
|
|
AUDIO_BIN := $(BINDIR)/AUDIO
|
|
AUDIO_MOD := $(REPO_DIR)/assets/test.mod
|
|
AUDIO_SFX := $(REPO_DIR)/assets/test.sfx
|
|
AUDIO_NTP := $(BUILD)/audio/test.ntp
|
|
AUDIO_HEADER := $(BUILD)/audio/test_assets.h
|
|
JOEYMOD := $(REPO_DIR)/tools/joeymod/joeymod
|
|
DISK_IMG := $(BINDIR)/joey.2mg
|
|
|
|
IIGS_PACKAGE := $(REPO_DIR)/toolchains/iigs/package-disk.sh
|
|
|
|
IIX_INCLUDES := \
|
|
-I $(IIGS_INCLUDE_SHIM) \
|
|
-I $(INCLUDE_DIR) \
|
|
-I $(INCLUDE_DIR)/joey \
|
|
-I $(SRC_CORE) \
|
|
-I $(REPO_DIR)/src/codegen
|
|
|
|
.PHONY: all iigs iigs-disk clean-iigs
|
|
# Building the disk implicitly builds every binary it depends on, so
|
|
# `make iigs` ends with a fresh joey.2mg on every change. Without this,
|
|
# stale disk images would silently mask binary updates -- a surprise
|
|
# when the run script always boots from joey.2mg.
|
|
all iigs: $(DISK_IMG)
|
|
|
|
$(NTP_BIN): $(NTP_SRC) $(IIGS_MERLIN)
|
|
@mkdir -p $(dir $@)
|
|
@cp $(NTP_SRC) $(BUILD)/audio/ninjatrackerplus.s
|
|
cd $(BUILD)/audio && $(IIGS_MERLIN) . ninjatrackerplus.s
|
|
mv $(BUILD)/audio/ntpplayer $@
|
|
|
|
# Bake the NTP replayer bytes into an ORCA-M asm file. The asm declares
|
|
# the bytes in a `data NTPDATA` segment; ORCA's linker groups same-
|
|
# name object segments into one load segment, and the GS/OS loader
|
|
# places it in its own bank. Net effect: the 34 KB of NTP bytes don't
|
|
# crowd _ROOT in any binary, so audio_full.c can link into every demo
|
|
# (vs the old audio.c-stub split). audio_full.c references
|
|
# gNtpPlayerBytes / gNtpPlayerBytes_len as externs (case-sensitive
|
|
# symbol match against the asm labels).
|
|
$(NTP_ASM): $(NTP_BIN) $(REPO_DIR)/toolchains/iigs/bin-to-asm.sh
|
|
@mkdir -p $(dir $@)
|
|
$(REPO_DIR)/toolchains/iigs/bin-to-asm.sh $(NTP_BIN) $@ NTPDATA gNtpPlayerBytes gNtpPlayerBytes_len
|
|
|
|
# iix-build.sh takes MAIN.c first, then EXTRA sources (compiled with
|
|
# #pragma noroot). The example source supplies main(); libjoey sources
|
|
# are the extras. The chtyp post-step tags the output as GS/OS S16
|
|
# ($B3) so GS/OS recognizes it as launchable; the file-type lives in
|
|
# a user.com.apple.FinderInfo xattr that iix and profuse preserve.
|
|
#
|
|
# All binaries use ORCA-C large memory model (-b). Cost: slightly
|
|
# larger / slower compiled C per the ORCA docs. Win: 32-bit pointers
|
|
# everywhere, so library asm can take SurfaceT* args via one
|
|
# consistent ABI (small-mm 16-bit pointers truncated bank bytes,
|
|
# which broke any asm that wanted to address bank-1 stage memory).
|
|
# Per-binary header dependency files. iix-build.sh -M emits one .d
|
|
# alongside each binary covering every header transitively included
|
|
# by the C sources in that binary's build. Pulled in via -include at
|
|
# the bottom of this file so editing a shared header (e.g.
|
|
# surfaceInternal.h) triggers a rebuild of every IIgs binary that
|
|
# transitively depends on it.
|
|
DEP_DIR := $(BUILD)/dep
|
|
PATTERN_DEP := $(DEP_DIR)/PATTERN.d
|
|
DRAW_DEP := $(DEP_DIR)/DRAW.d
|
|
KEYS_DEP := $(DEP_DIR)/KEYS.d
|
|
JOY_DEP := $(DEP_DIR)/JOY.d
|
|
SPRITE_DEP := $(DEP_DIR)/SPRITE.d
|
|
UBER_DEP := $(DEP_DIR)/UBER.d
|
|
AUDIO_DEP := $(DEP_DIR)/AUDIO.d
|
|
|
|
$(PATTERN_BIN): $(PATTERN_SRC) $(LIB_SRCS) $(NTP_ASM) $(IIGS_BUILD)
|
|
@mkdir -p $(dir $@) $(DEP_DIR)
|
|
$(IIGS_BUILD) -b -M $(PATTERN_DEP) $(IIX_INCLUDES) -o $@ $(PATTERN_SRC) $(LIB_SRCS)
|
|
$(IIGS_IIX) chtyp -t S16 $@
|
|
|
|
$(DRAW_BIN): $(DRAW_SRC) $(LIB_SRCS) $(NTP_ASM) $(IIGS_BUILD)
|
|
@mkdir -p $(dir $@) $(DEP_DIR)
|
|
$(IIGS_BUILD) -b -M $(DRAW_DEP) $(IIX_INCLUDES) -o $@ $(DRAW_SRC) $(LIB_SRCS)
|
|
$(IIGS_IIX) chtyp -t S16 $@
|
|
|
|
$(KEYS_BIN): $(KEYS_SRC) $(LIB_SRCS) $(NTP_ASM) $(IIGS_BUILD)
|
|
@mkdir -p $(dir $@) $(DEP_DIR)
|
|
$(IIGS_BUILD) -b -M $(KEYS_DEP) $(IIX_INCLUDES) -o $@ $(KEYS_SRC) $(LIB_SRCS)
|
|
$(IIGS_IIX) chtyp -t S16 $@
|
|
|
|
$(JOY_BIN): $(JOY_SRC) $(LIB_SRCS) $(NTP_ASM) $(IIGS_BUILD)
|
|
@mkdir -p $(dir $@) $(DEP_DIR)
|
|
$(IIGS_BUILD) -b -M $(JOY_DEP) $(IIX_INCLUDES) -o $@ $(JOY_SRC) $(LIB_SRCS)
|
|
$(IIGS_IIX) chtyp -t S16 $@
|
|
|
|
$(SPRITE_BIN): $(SPRITE_SRC) $(LIB_SRCS) $(NTP_ASM) $(IIGS_BUILD)
|
|
@mkdir -p $(dir $@) $(DEP_DIR)
|
|
$(IIGS_BUILD) -b -M $(SPRITE_DEP) $(IIX_INCLUDES) -o $@ $(SPRITE_SRC) $(LIB_SRCS)
|
|
$(IIGS_IIX) chtyp -t S16 $@
|
|
|
|
# UBER bumps user stack to 16 KB. ORCA-C's default user stack is small
|
|
# (~1 KB) and vfprintf's parsing buffer + the demo's own stack-local
|
|
# format buffers were spilling past it -- the symptom was a crash to
|
|
# monitor on the second varargs-style joeyLogF call. The hand-rolled
|
|
# decimal formatter in uber.c also uses larger stack-local buffers
|
|
# (line[96], num[16]) than typical demos. 16 KB is plenty of headroom.
|
|
$(UBER_BIN): $(UBER_SRC) $(LIB_SRCS) $(NTP_ASM) $(IIGS_BUILD)
|
|
@mkdir -p $(dir $@) $(DEP_DIR)
|
|
$(IIGS_BUILD) -b -s 16384 -M $(UBER_DEP) $(IIX_INCLUDES) -o $@ $(UBER_SRC) $(LIB_SRCS)
|
|
$(IIGS_IIX) chtyp -t S16 $@
|
|
|
|
# Convert the cross-platform .MOD asset to NinjaTrackerPlus runtime
|
|
# format via joeymod (which shells out to ntpconverter.php). Without
|
|
# php-cli the conversion is skipped; in that case the IIgs disk just
|
|
# won't carry a TEST.NTP and the audio demo will report "missing data
|
|
# file" at runtime instead of crashing on bad MOD magic.
|
|
HAVE_PHP := $(shell command -v php >/dev/null 2>&1 && echo 1)
|
|
|
|
ifeq ($(HAVE_PHP),1)
|
|
$(AUDIO_NTP): $(AUDIO_MOD) $(JOEYMOD)
|
|
@mkdir -p $(dir $@)
|
|
$(JOEYMOD) $< $@
|
|
|
|
AUDIO_DATA_FILES := $(AUDIO_NTP) $(AUDIO_SFX)
|
|
else
|
|
$(info iigs: php-cli not installed -- AUDIO demo will ship without TEST.NTP; install php-cli for real IIgs audio playback)
|
|
AUDIO_DATA_FILES := $(AUDIO_SFX)
|
|
endif
|
|
|
|
$(AUDIO_BIN): $(AUDIO_SRC) $(LIB_SRCS) $(NTP_ASM) $(IIGS_BUILD)
|
|
@mkdir -p $(dir $@) $(DEP_DIR)
|
|
$(IIGS_BUILD) -b -M $(AUDIO_DEP) $(IIX_INCLUDES) -I $(EXAMPLES)/audio -o $@ $(AUDIO_SRC) $(LIB_SRCS)
|
|
$(IIGS_IIX) chtyp -t S16 $@
|
|
|
|
# Assemble a ProDOS 2img containing the examples, ready to mount in
|
|
# GSplus alongside a GS/OS boot volume.
|
|
iigs-disk: $(DISK_IMG)
|
|
|
|
$(DISK_IMG): $(PATTERN_BIN) $(DRAW_BIN) $(KEYS_BIN) $(JOY_BIN) $(SPRITE_BIN) $(AUDIO_BIN) $(UBER_BIN) $(AUDIO_DATA_FILES) $(IIGS_PACKAGE)
|
|
@mkdir -p $(dir $@)
|
|
$(IIGS_PACKAGE) $@ $(PATTERN_BIN) $(DRAW_BIN) $(KEYS_BIN) $(JOY_BIN) $(SPRITE_BIN) $(AUDIO_BIN) $(UBER_BIN) -- $(AUDIO_DATA_FILES)
|
|
|
|
clean-iigs:
|
|
rm -rf $(BUILD)
|
|
|
|
# Pull in per-binary header-dependency files generated by iix-build.sh -M.
|
|
# Without this, editing a header (e.g. surfaceInternal.h) doesn't rebuild
|
|
# IIgs binaries that include it -- the IIgs's iix toolchain has no native
|
|
# -MMD analog, so iix-build.sh shells out to host gcc for the scan.
|
|
-include $(PATTERN_DEP) $(DRAW_DEP) $(KEYS_DEP) $(JOY_DEP) $(SPRITE_DEP) $(UBER_DEP) $(AUDIO_DEP)
|