BIN= $(GDK)/bin
LIB= $(GDK)/lib

LIBSRC= $(GDK)/src
LIBRES= $(GDK)/res
LIBINCLUDE= $(GDK)/inc

SRC= src
RES= res
INCLUDE= inc

SHELL= $(BIN)/sh
RM= $(BIN)/rm
CP= $(BIN)/cp
CC= $(BIN)/gcc
LD= $(BIN)/ld
NM= $(BIN)/nm
ECHO= echo
OBJCPY= $(BIN)/objcopy
ASMZ80= $(BIN)/sjasm
MACCER= $(BIN)/mac68k
SIZEBND= $(BIN)/sizebnd
BINTOS= $(BIN)/bintos
RESCOMP= ../tools/rescomp
MKDIR= $(BIN)/mkdir

SRC_C= $(wildcard *.c)
SRC_C+= $(wildcard $(SRC)/*.c)
SRC_S= $(wildcard *.s)
SRC_S+= $(wildcard $(SRC)/*.s)
SRC_ASM= $(wildcard *.asm)
SRC_ASM+= $(wildcard $(SRC)/*.asm)
SRC_S80= $(wildcard *.s80)
SRC_S80+= $(wildcard $(SRC)/*.s80)

RES_C= $(wildcard $(RES)/*.c)
RES_S= $(wildcard $(RES)/*.s)
RES_RES= $(wildcard *.res)
RES_RES+= $(wildcard $(RES)/*.res)

OBJ= $(RES_RES:.res=.o)
OBJ+= $(RES_S:.s=.o)
OBJ+= $(RES_C:.c=.o)
OBJ+= $(SRC_S80:.s80=.o)
OBJ+= $(SRC_ASM:.asm=.o)
OBJ+= $(SRC_S:.s=.o)
OBJ+= $(SRC_C:.c=.o)

OBJ_DB= $(SRC_C:.c=.db)

OBJS= $(addprefix out/, $(OBJ))
OBJS_DB= $(addprefix out/, $(OBJ_DB))

INCS= -I$(INCLUDE) -I$(SRC) -I$(RES) -I$(LIBINCLUDE) -I$(LIBRES)
DEFAULT_FLAGS= -m68000 -Wall -fno-builtin $(INCS) -B$(BIN)
FLAGSZ80= -i$(SRC) -i$(INCLUDE) -i$(RES) -i$(LIBSRC) -i$(LIBINCLUDE)

release: FLAGS= $(DEFAULT_FLAGS) -O3 -flto -fuse-linker-plugin -fno-web -fno-gcse -fno-unit-at-a-time -fomit-frame-pointer
release: LIBMD= $(LIB)/libmd.a
release: LDSCRIPT= md.ld
release: pre-build out/rom.bin out/symbol.txt out/rom.wch

release_db: FLAGS= $(DEFAULT_FLAGS) -O3 -fno-web -fno-gcse -fno-unit-at-a-time -fomit-frame-pointer -fdata-sections -DRELEASE_DB=1
release_db: LIBMD= $(LIB)/libmd.a
release_db: LDSCRIPT= md_db.ld
release_db: pre-build $(OBJS) $(OBJS_DB)
release_db: OBJS+= $(OBJS_DB)
release_db: out/rom.bin out/symbol.txt out/rom.wch

debug: FLAGS= $(DEFAULT_FLAGS) -O1 -ggdb -DDEBUG=1
debug: LIBMD= $(LIB)/libmd_debug.a
debug: LDSCRIPT= md.ld
debug: pre-build out/rom.bin out/rom.out out/symbol.txt out/rom.wch

all: release
default: release

Default: release
Debug: debug
Release: release

.PHONY: clean

cleanobj:
	$(RM) -f $(OBJS) $(OBJS_DB) out/sega.o out/rom_head.bin out/rom_head.o out/rom.out

clean: cleanobj
	$(RM) -f out.lst out/cmd_ out/rom.nm out/rom.wch out/rom.bin

cleanrelease: clean

cleandebug: clean
	$(RM) -f  out/symbol.txt

cleandefault: clean
cleanDefault: clean
cleanRelease: cleanrelease
cleanDebug: cleandebug


pre-build:
	$(MKDIR) -p $(SRC)/boot
	$(MKDIR) -p out
	$(MKDIR) -p out/src
	$(MKDIR) -p out/res


out/rom.bin: out/rom.out
	$(OBJCPY) -O binary out/rom.out out/rom.bin
	$(SIZEBND) out/rom.bin -sizealign 131072

out/symbol.txt: out/rom.out
	$(NM) --plugin=liblto_plugin-0.dll -n out/rom.out > out/symbol.txt

out/rom.out: out/sega.o out/cmd_ $(LIBMD)
	$(CC) -B$(BIN) -n -T $(LDSCRIPT) -nostdlib out/sega.o @out/cmd_ $(LIBMD) $(LIB)/libgcc.a -o out/rom.out $(FLAGS)
	$(RM) out/cmd_

out/cmd_: $(OBJS)
	$(ECHO) "$(OBJS)" > out/cmd_

out/sega.o: $(SRC)/boot/sega.s out/rom_head.bin
	$(CC) $(DEFAULT_FLAGS) -c $(SRC)/boot/sega.s -o $@

out/rom_head.bin: out/rom_head.o
	$(LD) -T $(LDSCRIPT) -nostdlib --oformat binary -o $@ $<

out/rom_head.o: $(SRC)/boot/rom_head.c
	$(CC) $(DEFAULT_FLAGS) -c $< -o $@

$(SRC)/boot/sega.s: $(LIBSRC)/boot/sega.s
	$(CP) $< $@

$(SRC)/boot/rom_head.c: $(LIBSRC)/boot/rom_head.c
	$(CP) $< $@


out/%.o: %.c
	$(CC) $(FLAGS) -c $< -o $@

out/%.o: %.s
	$(CC) $(FLAGS) -c $< -o $@

%.s: %.res
	$(RESCOMP) $< $@

%.s: %.asm
	$(MACCER) -o $@ $<

%.o80: %.s80
	$(ASMZ80) $(FLAGSZ80) $< $@ out.lst

%.s: %.o80
	$(BINTOS) $<

out/%.db: out/%.o
	$(OBJCPY) --wildcard -R .text -R .text.* -R .rodata.* -R .wram_text --prefix-symbols db_ -i 65535 --byte 0 $< $@ || \
		$(OBJCPY) --wildcard -R .text -R .text.* --strip-all -i 65535 --byte 0 $< $@

out/rom.wch: out/symbol.txt
	$(BIN)/nm2wch out/symbol.txt out/rom.wch
