joeylib2/make/iigs.mk

182 lines
7.7 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_SRC := $(EXAMPLES)/hello/hello.c
HELLO_BIN := $(BINDIR)/HELLO
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
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).
$(HELLO_BIN): $(HELLO_SRC) $(LIB_SRCS) $(NTP_ASM) $(IIGS_BUILD)
@mkdir -p $(dir $@)
$(IIGS_BUILD) -b $(IIX_INCLUDES) -o $@ $(HELLO_SRC) $(LIB_SRCS)
$(IIGS_IIX) chtyp -t S16 $@
$(PATTERN_BIN): $(PATTERN_SRC) $(LIB_SRCS) $(NTP_ASM) $(IIGS_BUILD)
@mkdir -p $(dir $@)
$(IIGS_BUILD) -b $(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 $@)
$(IIGS_BUILD) -b $(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 $@)
$(IIGS_BUILD) -b $(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 $@)
$(IIGS_BUILD) -b $(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 $@)
$(IIGS_BUILD) -b $(IIX_INCLUDES) -o $@ $(SPRITE_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 $@)
$(IIGS_BUILD) -b $(IIX_INCLUDES) -I $(EXAMPLES)/audio -o $@ $(AUDIO_SRC) $(LIB_SRCS)
$(IIGS_IIX) chtyp -t S16 $@
# Assemble an 800KB ProDOS 2img containing the examples, ready to
# mount in GSplus alongside a GS/OS boot volume.
iigs-disk: $(DISK_IMG)
$(DISK_IMG): $(HELLO_BIN) $(PATTERN_BIN) $(DRAW_BIN) $(KEYS_BIN) $(JOY_BIN) $(SPRITE_BIN) $(AUDIO_BIN) $(AUDIO_DATA_FILES) $(IIGS_PACKAGE)
@mkdir -p $(dir $@)
$(IIGS_PACKAGE) $@ $(HELLO_BIN) $(PATTERN_BIN) $(DRAW_BIN) $(KEYS_BIN) $(JOY_BIN) $(SPRITE_BIN) $(AUDIO_BIN) -- $(AUDIO_DATA_FILES)
clean-iigs:
rm -rf $(BUILD)