joeylib2/make/x68000.mk

198 lines
7.9 KiB
Makefile

# Part of JoeyLib, Copyright (c) 2026 Scott Duensing, under the MIT License.
# See LICENSE.md for license information.
# SPDX-License-Identifier: MIT
#
# Sharp X68000 (elf2x68k / m68k-xelf-gcc) build rules.
#
# The port draws planar into the text plane (src/x68000/halPlanar.c), shares
# the Amiga's 68k planar fills, plots and sprite emitter (src/m68k), plays
# chip music on the OPM and samples through the ADPCM channel.
#
# The toolchain is elf2x68k (BSD-3, gcc 13.4.0 / binutils / newlib), installed
# by ./install.sh (X68K_ROOT). m68k-xelf-gcc emits ELF; the driver's
# -Wl,-elf2x68k pass converts it to a Human68k .X.
#
# This file holds JoeyLib's library for the X68000 and programRules, the
# X68000'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 the X68000 gates are at the end.
PLATFORM := x68000
include $(dir $(lastword $(MAKEFILE_LIST)))/common.mk
$(call requireTool,$(X68K_ROOT)/bin/m68k-xelf-gcc,toolchain:x68000)
X68K_CC := $(X68K_ROOT)/bin/m68k-xelf-gcc
X68K_AR := $(X68K_ROOT)/bin/m68k-xelf-ar
# The linker is driven by a wrapper script (m68k-elf/bin/ld.x) that shells out
# to `m68k-xelf-ld.bfd` by bare name, so the toolchain's own bin/ MUST be on
# PATH or the link dies with "m68k-xelf-ld.bfd: command not found". Compiling
# and archiving work fine without it, so this only bites at link time.
export PATH := $(X68K_ROOT)/bin:$(PATH)
CFLAGS := $(COMMON_CFLAGS) -m68000 -fomit-frame-pointer \
-DJOEYLIB_PLATFORM_X68000 \
-I$(SRC_DIR)/x68000 -I$(SRC_68K) -I$(REPO_DIR)/src/codegen -MMD -MP
LDFLAGS := -lm
PORT_C_SRCS := $(wildcard $(SRC_DIR)/x68000/*.c)
# Raw interrupt shims (timer tick, frame count, SCB raster, SCC receive): each
# saves every register and returns with RTE, which a C function cannot. And
# the present's copy (x68kPresent.s).
PORT_S_SRCS := $(wildcard $(SRC_DIR)/x68000/*.s)
# Sprite codegen is the shared 68k PLANAR emitter, unchanged. Its
# AMIGA_PLANE_STRIDE is JL_SURFACE_WIDTH/8 = 40, which is this port's surface
# stride too -- the display's 128-byte stride never reaches the emitter, which
# only ever addresses the surface. So sprites COMPILE here rather than
# interpret; spriteEmitStub.o is gone.
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)/x68000/%.c,$(BUILD)/obj/port/%.o,$(PORT_C_SRCS)) \
$(patsubst $(SRC_DIR)/x68000/%.s,$(BUILD)/obj/port/%.o,$(PORT_S_SRCS)) \
$(BUILD)/obj/68k/planarFill.o \
$(BUILD)/obj/68k/planarPlot.o \
$(BUILD)/obj/68k/stageBands.o \
$(BUILD)/obj/68k/modMix.o \
$(BUILD)/obj/68k/sfxMix.o \
$(BUILD)/obj/68k/planarSpriteWalk.o \
$(BUILD)/obj/68k/spriteEmitPlanar68k.o \
$(BUILD)/obj/68k/planarSprite.o \
$(BUILD)/obj/codegen/spriteCompile.o \
$(BUILD)/obj/codegen/spriteStage.o
LIB := $(LIBDIR)/libjoey.a
$(BUILD)/obj/core/%.o: $(SRC_CORE)/%.c
@mkdir -p $(dir $@)
$(X68K_CC) $(CFLAGS) -c $< -o $@
$(BUILD)/obj/generic/%.o: $(SRC_DIR)/generic/%.c
@mkdir -p $(dir $@)
$(X68K_CC) $(CFLAGS) -c $< -o $@
# Port-local asm. Same object dir as the port C objects; make picks between the
# two pattern rules by which prerequisite exists.
$(BUILD)/obj/port/%.o: $(SRC_DIR)/x68000/%.s
@mkdir -p $(dir $@)
$(X68K_CC) $(CFLAGS) -c $< -o $@
$(BUILD)/obj/68k/%.o: $(SRC_68K)/%.s
@mkdir -p $(dir $@)
$(X68K_CC) $(CFLAGS) -c $< -o $@
$(BUILD)/obj/68k/%.o: $(SRC_68K)/%.c
@mkdir -p $(dir $@)
$(X68K_CC) $(CFLAGS) -c $< -o $@
$(BUILD)/obj/codegen/%.o: $(CODEGEN_DIR)/%.c
@mkdir -p $(dir $@)
$(X68K_CC) $(CFLAGS) -I$(CODEGEN_DIR) -c $< -o $@
$(BUILD)/obj/port/%.o: $(SRC_DIR)/x68000/%.c
@mkdir -p $(dir $@)
$(X68K_CC) $(CFLAGS) -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 $@
$(X68K_AR) rcs $@ $(LIB_OBJS)
# Pull in per-object header-dependency files generated by gcc -MMD/-MP, so a
# header edit rebuilds every object that includes it.
-include $(LIB_OBJS:.o=.d)
# ---- programs -----------------------------------------------------------------
# A program is NAME.X, in bin/ or in its own bin/NAME/ with its DATA beside it
# (ID_FOLDER: a game's megabyte of data then never rides onto every other
# program's floppy); joey-run copies the program and its DATA onto a Human68k
# data floppy.
PROGRAM_EXT := .X
PROGRAM_FOLDERS := yes
# One program, $(1) its id: compiled and linked in one step with the library
# (the link also leaves NAME.X.elf). gcc's -MMD leaves NAME.d beside it, for
# header edits.
define programRules
$(call programBin,$(1)): $(call programVar,$(1),SRCS) $(LIB)
@mkdir -p $$(dir $$@)
$(X68K_CC) $(CFLAGS) $(call programVar,$(1),CFLAGS) $(call programVar,$(1),SRCS) $(LIB) $(LDFLAGS) $(call programVar,$(1),LDFLAGS) -o $$@
-include $(basename $(call programBin,$(1))).d
endef
# ---- JoeyLib's own build: its examples and the X68000 gates ----------------------
ifndef JOEY_PROJECT
include $(REPO_DIR)/make/examples.mk
include $(REPO_DIR)/make/programs.mk
.DEFAULT_GOAL := all
.PHONY: all x68000 x68000-lib x68000-examples x68000-verify-audio x68000-verify-serial x68000-verify-mouse x68000-verify-serial-mouse x68000-verify-serial-scb x68000-verify-joy x68000-verify-tilebank x68000-verify-scb x68000-verify-golden clean-x68000 clean
all x68000: x68000-lib x68000-examples
x68000-lib: $(LIB)
x68000-examples: programs
# Audio gate: AUDIOPRB (AUDIO pressing its own keys, make/examples.mk) under
# MAME with write taps on the OPM, the PPI and the ADPCM: every noise code in
# the port's table, the ADPCM fed at 7812 Hz to both speakers (~1 min).
x68000-verify-audio: $(call programBin,AUDIOPRB)
$(REPO_DIR)/scripts/verify-x68000-audio.sh $(call programBin,AUDIOPRB)
# Both-directions RS-232C gate (~1 min).
x68000-verify-serial: $(call programBin,SERIAL)
$(REPO_DIR)/scripts/verify-x68000-serial.sh
# Mouse gate: injected MAME mouse packets through the IOCS ROM into
# jlMouse* state, read back from KEYS.X's verification scanline.
x68000-verify-mouse: $(call programBin,KEYS)
$(REPO_DIR)/scripts/verify-x68000-mouse.sh
# Serial + mouse together: both share the SCC, so stream both ways on the
# RS-232C port while the mouse moves, and check neither disturbs the other.
x68000-verify-serial-mouse: $(call programBin,SERMOUSE)
$(REPO_DIR)/scripts/verify-x68000-serial-mouse.sh
# Serial + mouse under per-line palette changes: the serial + mouse gate with
# examples/sermouse built for a dense SCB at 9600, 19200 and 38400 (~3 min).
x68000-verify-serial-scb: $(LIB)
$(REPO_DIR)/scripts/verify-x68000-serial-scb.sh
# Joystick gate: every direction, both triggers and every release on both
# ports, held through MAME's pads and read back from JOY.X's display (~10 s).
x68000-verify-joy: $(call programBin,JOY)
$(REPO_DIR)/scripts/verify-x68000-joy.sh
# Tile-bank gate: this port's own .tbk bake loaded both ways must hash like
# the host gate's, and every other target's bake must be refused (~1 min).
x68000-verify-tilebank: $(call programBin,TILEBANK) $(TILEBANK_DATA)
$(REPO_DIR)/scripts/verify-x68000-tilebank.sh
# SCB gate: every text-palette reload of a 147-change screen, timed on the
# beam, lands between the last stage pixel of the line above its band and the
# band's first (~10 s).
x68000-verify-scb: $(call programBin,SCB)
$(REPO_DIR)/scripts/verify-x68000-scb.sh
# Golden-hash gate against the Apple IIgs reference (~1 min: UBER with
# one-frame windows, which is all the hashes need).
x68000-verify-golden: $(LIB)
$(REPO_DIR)/scripts/verify-x68000-golden.sh
clean-x68000:
rm -rf $(BUILD)
# `clean` as an alias for `clean-x68000`. Without it a bare
# `make -f make/x68000.mk clean` FAILS -- and with stderr discarded that
# looks like success while leaving stale objects the next build links.
clean: clean-x68000
endif