# Apple IIgs build rules (llvm-mos w65816: clang + llvm-mc + link816). # # toolchains/iigs/clang-build.sh drives compile (clang) / assemble # (llvm-mc) / link (link816) against the prebuilt w65816 runtime. # Hand-rolled asm lives in src/iigs/*.s (llvm-mc GAS syntax); # bank placement is handled by -ffunction-sections + link816 # dead-stripping. # # STATUS: the launchable-binary pipeline (multi-segment OMF emission + # disk packaging + GS/OS launch) is still being brought up. `iigs-lib` # compile-checks every library + example translation unit, and # `iigs-clang-smoke` validates the full clang -> llvm-mc -> link816 -> # MAME path end to end. Per-example binary targets build via # clang-build.sh; large examples need the multi-segment OMF wiring still # in progress. include $(dir $(lastword $(MAKEFILE_LIST)))/common.mk PLATFORM := iigs BUILD := $(REPO_DIR)/build/$(PLATFORM) BINDIR := $(BUILD)/bin OBJDIR := $(BUILD)/obj CLANG := $(LLVM816_ROOT)/tools/llvm-mos-build/bin/clang RT_INC := $(LLVM816_ROOT)/runtime/include CFLAGS := --target=w65816 -O2 -ffreestanding -ffunction-sections INCLUDES := -I$(RT_INC) -I$(INCLUDE_DIR) -I$(INCLUDE_DIR)/joey -I$(SRC_CORE) -I$(REPO_DIR)/src/codegen PORT_C_SRCS := $(wildcard $(SRC_DIR)/iigs/*.c) # Hand-rolled asm, migrated to llvm-mc GAS .s. PORT_ASM_SRCS := $(wildcard $(SRC_DIR)/iigs/*.s) # IIgs uses NTPstreamsound for SFX, not the libxmp+overlay combo that # DOS and ST share, so src/core/audioSfxMix.c is unused here. CORE_C_SRCS_IIGS := $(filter-out %/audioSfxMix.c, $(CORE_C_SRCS)) # Sprite codegen: the 65816 emitter (spriteEmitIigs.c) now lives in src/iigs/ # and is picked up by PORT_C_SRCS; only the CPU-independent compile dispatch # remains in src/codegen. CODEGEN_SRCS := $(REPO_DIR)/src/codegen/spriteCompile.c LIB_C_SRCS := $(CORE_C_SRCS_IIGS) $(GENERIC_C_SRCS) $(PORT_C_SRCS) $(CODEGEN_SRCS) LIB_SRCS := $(LIB_C_SRCS) $(PORT_ASM_SRCS) # Example sources (single-TU unless noted). PATTERN_SRC := $(EXAMPLES)/pattern/pattern.c DRAW_SRC := $(EXAMPLES)/draw/draw.c KEYS_SRC := $(EXAMPLES)/keys/keys.c JOY_SRC := $(EXAMPLES)/joy/joy.c SPRITE_SRC := $(EXAMPLES)/sprite/sprite.c UBER_SRC := $(EXAMPLES)/uber/uber.c ADV_SRC := $(EXAMPLES)/adventure/adventure.c ADV2_SRC := $(EXAMPLES)/adventure2/adventure2.c AGI_SRCS := $(EXAMPLES)/agi/agi.c $(EXAMPLES)/agi/agiRes.c $(EXAMPLES)/agi/agiPic.c $(EXAMPLES)/agi/agiView.c $(EXAMPLES)/agi/agiVm.c $(EXAMPLES)/agi/agiObj.c $(EXAMPLES)/agi/agiText.c STAXI_SRCS := $(EXAMPLES)/spacetaxi/spacetaxi.c $(EXAMPLES)/spacetaxi/stLevel.c $(EXAMPLES)/spacetaxi/stRender.c $(EXAMPLES)/spacetaxi/stEngine.c $(EXAMPLES)/spacetaxi/stPassenger.c $(EXAMPLES)/spacetaxi/stHud.c $(EXAMPLES)/spacetaxi/stAudio.c AUDIO_SRC := $(EXAMPLES)/audio/audio.c # NinjaTrackerPlus replayer: Merlin32-assemble ninjatrackerplus.s to a 34KB # binary, then bake it into a dead-strippable GAS data object (gNtpPlayerBytes # / _len, which audio_full.c externs). bin-to-s.sh is the clang-era replacement # for the deleted bin-to-asm.sh. Only the AUDIO binary pulls it in; link816 # dead-strips it everywhere else. NTP_SRC := $(REPO_DIR)/toolchains/iigs/ntp/ninjatrackerplus.s NTP_BIN := $(BUILD)/audio/ntpplayer.bin NTP_ASM := $(BUILD)/audio/ntpdata.s IIGS_MERLIN := $(REPO_DIR)/toolchains/iigs/merlin32/bin/merlin32 .PHONY: all iigs iigs-lib iigs-clang-smoke iigs-examples iigs-disk iigs-verify clean-iigs # Default: compile-check the library + run the end-to-end smoke test. all iigs: iigs-lib iigs-clang-smoke # Per-example launchable binaries. AUDIO (34KB NTP rodata needs link816 # rodata-bank splitting) and STAXI (2-byte cross-seg reloc to a runtime # helper) are blocked on deeper toolchain features and are omitted here. iigs-examples: $(BINDIR)/PATTERN $(BINDIR)/DRAW $(BINDIR)/KEYS $(BINDIR)/JOY \ $(BINDIR)/SPRITE $(BINDIR)/UBER $(BINDIR)/ADV $(BINDIR)/ADV2 \ $(BINDIR)/AGI # Build the JOEYLIB data disk (build/iigs/bin/joey.2mg) that run-iigs-mame.sh / # run-iigs.sh mount on flop4. Packs the launchable examples as ProDOS S16 apps # (an 800KB floppy can't hold every example; see make-iigs-disk.sh). # NTP_BIN rides along so jlpAudioInit's runtime load of "ntpplayer" finds it # on the volume -- without it every example logs "audioInit failed" (Phase 1 # IIgs stabilization item c: the audio code is wired; the file was missing). iigs-disk: iigs-examples $(NTP_BIN) BINDIR="$(BINDIR)" NTP_BIN="$(NTP_BIN)" $(REPO_DIR)/scripts/make-iigs-disk.sh $(BINDIR)/joey.2mg # Headless visual-verification gate: boot GS/OS under MAME, launch the DRAW # example off joey.2mg, and assert the SHR framebuffer was actually rendered # (many distinct colors -> pixels/lines/circles/tiles/flood all drew). Pass # VERIFY_EXAMPLE=name to check a different example. iigs-verify: iigs-disk $(REPO_DIR)/scripts/verify-iigs.sh $(or $(VERIFY_EXAMPLE),draw) $(NTP_BIN): $(NTP_SRC) $(IIGS_MERLIN) @mkdir -p $(BUILD)/audio @cp $(NTP_SRC) $(BUILD)/audio/ninjatrackerplus.s cd $(BUILD)/audio && $(IIGS_MERLIN) . ninjatrackerplus.s mv $(BUILD)/audio/ntpplayer $@ $(NTP_ASM): $(NTP_BIN) $(REPO_DIR)/toolchains/iigs/bin-to-s.sh $(REPO_DIR)/toolchains/iigs/bin-to-s.sh $(NTP_BIN) $@ gNtpPlayerBytes gNtpPlayerBytes_len # Compile-check every library and example translation unit with clang, # and assemble every .s with llvm-mc. This is the canonical "does the # IIgs source still build" gate while the launchable pipeline is wired. iigs-lib: @mkdir -p $(OBJDIR) @set -e; \ for c in $(LIB_C_SRCS); do \ echo " CC $$c"; \ $(CLANG) $(CFLAGS) $(INCLUDES) -c $$c -o $(OBJDIR)/$$(echo $$c | sed 's#[/.]#_#g').o; \ done; \ for s in $(PORT_ASM_SRCS); do \ echo " AS $$s"; \ $(LLVM816_ROOT)/tools/llvm-mos-build/bin/llvm-mc -arch=w65816 -filetype=obj $$s -o $(OBJDIR)/$$(basename $$s .s).o; \ done # End-to-end smoke test: clang -> llvm-mc -> link816 -> MAME, validating # the ported asm computes correctly on emulated hardware. iigs-clang-smoke: $(REPO_DIR)/toolchains/iigs/clang-smoke.sh # Per-example binaries via clang-build.sh. clang-build.sh mirrors the # old driver's CLI (-I / -o / -M; -s and -b are accepted no-ops). These # link single-segment today; examples larger than one bank need the # multi-segment OMF wiring still in progress. DEP_DIR := $(BUILD)/dep $(BINDIR)/PATTERN: $(PATTERN_SRC) $(LIB_SRCS) $(IIGS_CLANG_BUILD) @mkdir -p $(dir $@) $(DEP_DIR) $(IIGS_CLANG_BUILD) -M $(DEP_DIR)/PATTERN.d $(INCLUDES) -o $@ $(PATTERN_SRC) $(LIB_SRCS) $(BINDIR)/DRAW: $(DRAW_SRC) $(LIB_SRCS) $(IIGS_CLANG_BUILD) @mkdir -p $(dir $@) $(DEP_DIR) $(IIGS_CLANG_BUILD) -M $(DEP_DIR)/DRAW.d $(INCLUDES) -o $@ $(DRAW_SRC) $(LIB_SRCS) $(BINDIR)/KEYS: $(KEYS_SRC) $(LIB_SRCS) $(IIGS_CLANG_BUILD) @mkdir -p $(dir $@) $(DEP_DIR) $(IIGS_CLANG_BUILD) -M $(DEP_DIR)/KEYS.d $(INCLUDES) -o $@ $(KEYS_SRC) $(LIB_SRCS) $(BINDIR)/JOY: $(JOY_SRC) $(LIB_SRCS) $(IIGS_CLANG_BUILD) @mkdir -p $(dir $@) $(DEP_DIR) $(IIGS_CLANG_BUILD) -M $(DEP_DIR)/JOY.d $(INCLUDES) -o $@ $(JOY_SRC) $(LIB_SRCS) $(BINDIR)/SPRITE: $(SPRITE_SRC) $(LIB_SRCS) $(IIGS_CLANG_BUILD) @mkdir -p $(dir $@) $(DEP_DIR) $(IIGS_CLANG_BUILD) -M $(DEP_DIR)/SPRITE.d $(INCLUDES) -o $@ $(SPRITE_SRC) $(LIB_SRCS) $(BINDIR)/UBER: $(UBER_SRC) $(LIB_SRCS) $(IIGS_CLANG_BUILD) @mkdir -p $(dir $@) $(DEP_DIR) $(IIGS_CLANG_BUILD) -M $(DEP_DIR)/UBER.d $(INCLUDES) -o $@ $(UBER_SRC) $(LIB_SRCS) $(BINDIR)/ADV: $(ADV_SRC) $(LIB_SRCS) $(IIGS_CLANG_BUILD) @mkdir -p $(dir $@) $(DEP_DIR) $(IIGS_CLANG_BUILD) -M $(DEP_DIR)/ADV.d $(INCLUDES) -o $@ $(ADV_SRC) $(LIB_SRCS) $(BINDIR)/ADV2: $(ADV2_SRC) $(LIB_SRCS) $(IIGS_CLANG_BUILD) @mkdir -p $(dir $@) $(DEP_DIR) $(IIGS_CLANG_BUILD) -M $(DEP_DIR)/ADV2.d $(INCLUDES) -o $@ $(ADV2_SRC) $(LIB_SRCS) $(BINDIR)/AGI: $(AGI_SRCS) $(LIB_SRCS) $(IIGS_CLANG_BUILD) @mkdir -p $(dir $@) $(DEP_DIR) $(IIGS_CLANG_BUILD) -M $(DEP_DIR)/AGI.d $(INCLUDES) -I$(EXAMPLES)/agi -o $@ $(AGI_SRCS) $(LIB_SRCS) $(BINDIR)/STAXI: $(STAXI_SRCS) $(LIB_SRCS) $(IIGS_CLANG_BUILD) @mkdir -p $(dir $@) $(DEP_DIR) $(IIGS_CLANG_BUILD) -M $(DEP_DIR)/STAXI.d $(INCLUDES) -I$(EXAMPLES)/spacetaxi -o $@ $(STAXI_SRCS) $(LIB_SRCS) # AUDIO loads the NTP replayer from disk at runtime: audio_full.c reads # ntpplayer.bin via NTP_PATH instead of baking the 34KB replayer as rodata # (which overflowed bank 0, and clang's IMM16+$BE near form can't reach a far # rodata segment anyway). The binary no longer links $(NTP_ASM); $(NTP_BIN) is # still built so it can be shipped on the application disk next to the binary. $(BINDIR)/AUDIO: $(AUDIO_SRC) $(LIB_SRCS) $(NTP_BIN) $(IIGS_CLANG_BUILD) @mkdir -p $(dir $@) $(DEP_DIR) $(IIGS_CLANG_BUILD) -M $(DEP_DIR)/AUDIO.d $(INCLUDES) -o $@ $(AUDIO_SRC) $(LIB_SRCS) clean-iigs: rm -rf $(BUILD) -include $(wildcard $(DEP_DIR)/*.d)