# Part of JoeyLib, Copyright (c) 2026 Scott Duensing, under the MIT License. # See LICENSE.md for license information. # SPDX-License-Identifier: MIT # # Atari ST (m68k-atari-mint-gcc) build rules: JoeyLib's library for the ST, # and programRules, the ST's rules for one program, which make/programs.mk # instantiates for every program (a project reaches both through # make/project.mk). JoeyLib's own examples and gates are at the end. # # The same rules build the STe variant: make/ste.mk sets ATARI_VARIANT to # ste and includes this file. That build lands in build/ste, compiles # src/atarist/ste as well, and defines JOEYLIB_ATARI_STE (BLiTTER, DMA # sound, 4-bit palette; its jlInit refuses anything but an STe or Mega # STe). The ST build never compiles src/atarist/ste. PLATFORM := $(or $(ATARI_VARIANT),atarist) include $(dir $(lastword $(MAKEFILE_LIST)))/common.mk $(call requireTool,$(ST_CC),toolchain:atarist) ST_SHIM := $(REPO_DIR)/make/support/atarist/include-shim # STe-only sources and flags (empty in the ST build). ifeq ($(PLATFORM),ste) STE_SRC_DIR := $(SRC_DIR)/atarist/ste STE_CFLAGS := -DJOEYLIB_ATARI_STE -I$(STE_SRC_DIR) STE_ASFLAGS := -Wa,--defsym,JOEYLIB_ATARI_STE=1 STE_C_SRCS := $(wildcard $(STE_SRC_DIR)/*.c) endif # so flag experiments never edit a tracked file (perf-hunt-2 rank 17). CFLAGS := $(COMMON_CFLAGS) $(STE_CFLAGS) -m68000 -fomit-frame-pointer -I$(ST_SHIM) -I$(SRC_DIR)/atarist -I$(SRC_68K) -MMD -MP LDFLAGS := PORT_C_SRCS := $(wildcard $(SRC_DIR)/atarist/*.c) PORT_S_SRCS := $(wildcard $(SRC_DIR)/atarist/*.s) # planarFill.s and planarShape.s are the separate-plane ports' (the Amiga, # the X68000): the ST's planes interleave, and its jlFillRect and # jlTilePasteGlyph are its own (lineSpan.s, stGlyph.s). SHARED_S := $(filter-out $(SRC_68K)/planarFill.s $(SRC_68K)/planarShape.s,$(wildcard $(SRC_68K)/*.s)) # Sprite codegen: the ST-interleaved emitter (spriteEmitInterleaved68k.c) # and the planar sprite interpreter (planarSprite.c) live in src/m68k/ and # build into obj/68k/; only the CPU-independent dispatch stays in # src/codegen. CODEGEN_DIR := $(REPO_DIR)/src/codegen LIB_OBJS := \ $(patsubst $(SRC_CORE)/%.c,$(BUILD)/obj/core/%.o,$(CORE_C_SRCS)) \ $(patsubst $(SRC_DIR)/generic/%.c,$(BUILD)/obj/generic/%.o,$(GENERIC_C_SRCS)) \ $(patsubst $(SRC_DIR)/atarist/%.c,$(BUILD)/obj/port/%.o,$(PORT_C_SRCS)) \ $(patsubst $(SRC_DIR)/atarist/%.s,$(BUILD)/obj/port/%.o,$(PORT_S_SRCS)) \ $(patsubst $(STE_SRC_DIR)/%.c,$(BUILD)/obj/ste/%.o,$(STE_C_SRCS)) \ $(patsubst $(SRC_68K)/%.s,$(BUILD)/obj/68k/%.o,$(SHARED_S)) \ $(BUILD)/obj/68k/spriteEmitInterleaved68k.o \ $(BUILD)/obj/68k/planarHash.o \ $(BUILD)/obj/68k/planarSprite.o \ $(BUILD)/obj/68k/spriteC2p.o \ $(BUILD)/obj/codegen/spriteCompile.o \ $(BUILD)/obj/codegen/spriteStage.o \ $(BUILD)/obj/shim/math_shim.o LIB := $(LIBDIR)/libjoey.a $(BUILD)/obj/core/%.o: $(SRC_CORE)/%.c @mkdir -p $(dir $@) $(ST_CC) $(CFLAGS) -c $< -o $@ $(BUILD)/obj/generic/%.o: $(SRC_DIR)/generic/%.c @mkdir -p $(dir $@) $(ST_CC) $(CFLAGS) -c $< -o $@ $(BUILD)/obj/port/%.o: $(SRC_DIR)/atarist/%.c @mkdir -p $(dir $@) $(ST_CC) $(CFLAGS) -c $< -o $@ ifeq ($(PLATFORM),ste) $(BUILD)/obj/ste/%.o: $(STE_SRC_DIR)/%.c @mkdir -p $(dir $@) $(ST_CC) $(CFLAGS) -c $< -o $@ endif # Hand-written 68k assembly: GAS syntax, fed through the gcc driver # so the bundled m68k-atari-mint-as (binutils) does the work. No vasm # dependency on the ST path. The STe build defines JOEYLIB_ATARI_STE for # the port's .ifdef as well (the .s files see no preprocessor). $(BUILD)/obj/port/%.o: $(SRC_DIR)/atarist/%.s @mkdir -p $(dir $@) $(ST_CC) $(CFLAGS) $(STE_ASFLAGS) -c $< -o $@ $(BUILD)/obj/68k/%.o: $(SRC_68K)/%.s @mkdir -p $(dir $@) $(ST_CC) $(CFLAGS) -c $< -o $@ # 68k sprite emitters (spriteEmitInterleaved68k.c) live in src/m68k/; # -I$(CODEGEN_DIR) lets them resolve spriteEmitter.h. $(BUILD)/obj/68k/%.o: $(SRC_68K)/%.c @mkdir -p $(dir $@) $(ST_CC) $(CFLAGS) -I$(CODEGEN_DIR) -c $< -o $@ $(BUILD)/obj/codegen/%.o: $(CODEGEN_DIR)/%.c @mkdir -p $(dir $@) $(ST_CC) $(CFLAGS) -I$(CODEGEN_DIR) -c $< -o $@ # Archived from scratch, so the members -- and every program's layout -- # follow LIB_OBJS rather than the order earlier builds added them in. $(LIB): $(LIB_OBJS) @mkdir -p $(dir $@) rm -f $@ $(ST_AR) rcs $@ $^ # mintlib has no libm: the shim's few functions, for a program that # includes , which -I$(ST_SHIM) gives it. $(BUILD)/obj/shim/math_shim.o: $(ST_SHIM)/math_shim.c @mkdir -p $(dir $@) $(ST_CC) $(CFLAGS) -c $< -o $@ # Pull in per-object header-dependency files generated by gcc -MMD/-MP. # Without this, editing a header (e.g. surfaceInternal.h) doesn't rebuild # the .c files that include it, leaving a frankenstein binary where # different TUs see different struct layouts. -include $(LIB_OBJS:.o=.d) # ---- programs ----------------------------------------------------------------- # A program is NAME.PRG, in bin/ or in its own bin/NAME/ with its DATA beside # it, where Hatari's GEMDOS drive (bin/ or the folder as C:) finds both. PROGRAM_EXT := .PRG PROGRAM_FOLDERS := yes # One program, $(1) its id: compiled and linked in one step with the # library. gcc's -MMD leaves NAME.d beside it, for header edits. define programRules $(call programBin,$(1)): $(call programVar,$(1),SRCS) $(LIB) @mkdir -p $$(dir $$@) $(ST_CC) $(CFLAGS) $(call programVar,$(1),CFLAGS) $(call programVar,$(1),SRCS) $(LIB) -o $$@ $(LDFLAGS) $(call programVar,$(1),LDFLAGS) -include $(basename $(call programBin,$(1))).d endef # ---- JoeyLib's own build: its examples and the ST gates ------------------------- ifndef JOEY_PROJECT include $(REPO_DIR)/make/examples.mk include $(REPO_DIR)/make/programs.mk .DEFAULT_GOAL := all .PHONY: all $(PLATFORM) clean-$(PLATFORM) clean all $(PLATFORM): $(LIB) programs clean-$(PLATFORM): rm -rf $(BUILD) # `clean` as an alias for `clean-atarist` (or `clean-ste`). Without it a bare # `make -f make/atarist.mk clean` FAILS -- and with stderr discarded that # looks like success while leaving stale objects the next build links. clean: clean-$(PLATFORM) # UBER with its probe rows, for the display gate (scripts/verify-atarist-display.sh). .PHONY: $(PLATFORM)-uberprob $(PLATFORM)-uberprob: $(call programTarget,UBERPROB) # The dirty-mark check is the ST build's (DIRTYMRK_PORTS). ifeq ($(PLATFORM),atarist) .PHONY: atarist-dirtymark atarist-verify-dirtymark atarist-dirtymark: $(call programBin,DIRTYMRK) atarist-verify-dirtymark: $(call programBin,DIRTYMRK) $(REPO_DIR)/scripts/verify-atarist-dirtymark.sh endif endif