# ------------------------------------------------------------------ #
# KOS Environment overrides                                          #
#                                                                    #
# -falign-functions=1	                                             #
# ------------------------------------------------------------------ #

# KOS_CFLAGS=-Wall -ml -m4-single-only -pipe -O3

KOS_CFLAGS= -ml -mbigtable -mnomacsave -m4-single-only 

OPTFLAG = -Os -fschedule-insns2 -fexpensive-optimizations -fomit-frame-pointer -fstrict-aliasing -ffast-math 

		      
#-DZ80_SH4_ASM

# ------------------------------------------------------------------ #
# KOS include / library paths                                        #
# ------------------------------------------------------------------ #

KOS_ALL_INCS = -I$(KOS_INCS) -I$(KOS_BASE)/libc/include \
	-I$(KOS_BASE)/kernel/arch/$(KOS_ARCH)/include -I$(KOS_INCS)/zlib \
	-I$(KOS_BASE)/kernel/arch/$(KOS_ARCH)
KOS_ALL_INCS += -I$(KOS_BASE)/addons/include/zlib -I$(KOS_BASE)/addons/include
KOS_LIBS = -L$(KOS_BASE)/lib -L$(KOS_BASE)/addons/lib -lpng -lkallisti -lz -lm -lgcc
#KOS_LIBS += -ldcutils
KOS_LDFLAGS = -ml -m4-single-only -nostartfiles -nostdlib -Wl,-Ttext=0x8c010000 -e start

# ------------------------------------------------------------------ #
# KOS additional variables                                           #
# ------------------------------------------------------------------ #

KOS_ARCH_DIR = $(KOS_BASE)/kernel/arch/$(KOS_ARCH)
KOS_START = $(KOS_ARCH_DIR)/kernel/startup.o

# ------------------------------------------------------------------ #
# Required target                                                    #
# ------------------------------------------------------------------ #

 #TARGET = AMSTRAD
# TARGET = SMS
 #TARGET = JAGUAR
# TARGET = VECTREX
 TARGET = LYNX
# TARGET = SNES
#TARGET = SPECTRUM
#TARGET = ti994a
#TARGET = vic20
#TARGET = 7800

# ------------------------------------------------------------------ #
# uncomment next line to include the debugger                        #
# ------------------------------------------------------------------ #

# DEBUG = 1

# ------------------------------------------------------------------ #
# uncomment next line to include the symbols for symify		     #
# ------------------------------------------------------------------ #

# SYMBOLS = 1

# ------------------------------------------------------------------ #
# uncomment next line to use Assembler 68000 engine		     #
# ------------------------------------------------------------------ #

# X86_ASM_68000 = 1


# ------------------------------------------------------------------ #
# uncomment next line to use Assembler 68020 engine		     #
# ------------------------------------------------------------------ #

# X86_ASM_68020 = 1

# ------------------------------------------------------------------ #
# Set these up for the operating system you are building for         #
# ------------------------------------------------------------------ #

OS        = $(KOS_ARCH)
DREAMCAST = 1
EXE       = .elf
EXE_HOST  =

# ------------------------------------------------------------------ #
# CPU core include paths					     #
# ------------------------------------------------------------------ #

VPATH=src $(wildcard src/cpu/*)

# ------------------------------------------------------------------ #
# compiler, linker and utilities				     #
# ------------------------------------------------------------------ #

ifdef DREAMCAST
AR      = $(KOS_AR)
CC      = $(KOS_CC)
AS      = $(KOS_AS)
CC_HOST = gcc
LD      = $(CC)
NAME    = mess_$(TARGET)
endif

MD      = @mkdir
RM      = @rm -f
PERL    = @perl -w

ifdef DEBUG
NAME = mess_$(TARGET)DBG
endif

# ------------------------------------------------------------------ #
# build the targets in different object dirs, since mess changes     #
# some structures and thus they can't be linked against each other.  #
# cleantiny isn't needed anymore, because the tiny build has its     #
# own object directory too. (OBJ = obj/$(NAME) OBJ = $(NAME).obj)    #
# ------------------------------------------------------------------ #

OBJ = obj/$(NAME)

EMULATOR = $(NAME)$(EXE)

DEFS = -DLSB_FIRST -D_arch_$(KOS_ARCH) -DMAME -DEXENAME=\"$(NAME)\"
DEFS += -DINLINE="static __inline__" -DMAMENAME='"MESS"' -DMESS
DEFS += -DWT_MALLOCDBG 
#-DWT_ARCADEMACHINE -DWT_MALLOCDBG -DWT_CHUNKMEMORY -DWT_ASSERT

ifdef DREAMCAST
CFLAGS  = $(KOS_ALL_INCS) -Imess -Isrc/includes -Imess/$(OS) -Isrc -Isrc/$(OS) -I$(OBJ)/cpu/m68000 -Isrc/cpu/m68000  \
	$(KOS_CFLAGS) -DNDEBUG -DUCHAR_MAX=0xff -DUSHRT_MAX=0xffff -DULONG_MAX=0xffffffff
	
CFLAGS +=  
	
	
#CFLAGS += -fno-exceptions -funroll-loops -ffast-math -fomit-frame-pointer
	     
# CFLAGS += -fno-optimize-sibling-calls 
# CFLAGS += -funroll-all-loops

# -falign-functions -falign-loops -falign-labels -falign-jumps
# -fstrict-aliasing -ffast-math -fomit-frame-pointer \
# -fdelete-null-pointer-checks -funroll-all-loops -fno-optimize-sibling-calls \
# -falign-loops -ffloat-store \
# -frename-registers
# -funroll-all-loops                        -> Adds about 15% speed performance
# -fno-optimize-sibling-calls               -> Adds speed
# -funroll-all-loops (in environ-dc.sh)     -> Adds speed
# -fomit-frame-pointer                      -> small effect?
# -falign-loops				    -> small improvement

# -falign-labels
							  
# -falign-functions=32                      -> no effect ?
# -fssa                                     -> no effect ?    
# -fexpensive-optimizations                 -> no effect
# -mbigtable                                -> no effect
# -mfmovd                                   -> no effect
# -fno-builtin	                            -> no effect
# -fno-gcse		                    -> no effect
# -falign-jumps	                            -> no effect
# -falign-jumps=32                          -> no effect

# -fno-guess-branch-probability             -> slower
# -fmove-all-movables (except drawgfx.o)    -> slower
# -finline-functions & -finline-limit=10000 -> slows things down some
# -fno-strict-aliasing                      -> display error?
# -fssa & -fdce                             -> no display!
# -mrelax                                   -> segmentation fault in compilation
# -freduce-all-givs			    -> drawgfx won't compile

LDFLAGS = $(KOS_LDFLAGS)
LIBS    = $(KOS_LIBS)
AFLAGS  = $(KOS_AFLAGS)
endif

CFLAGS_HOST = -I/opt/dreamcast/dc/include

OBJDIRS = obj $(OBJ) $(OBJ)/cpu $(OBJ)/sound  \
	$(OBJ)/drivers $(OBJ)/machine $(OBJ)/vidhrdw $(OBJ)/sndhrdw $(OBJ)/$(OS)

OBJDIRS += 	$(OBJ)/mess         $(OBJ)/mess/$(OS) $(OBJ)/mess/cpu \
		$(OBJ)/mess/systems $(OBJ)/mess/machine               \
		$(OBJ)/mess/vidhrdw $(OBJ)/mess/sndhrdw               \
		$(OBJ)/mess/formats $(OBJ)/mess/tools                 \
		$(OBJ)/mess/devices                                   \
		$(OBJ)/mess/tools/dat2html $(OBJ)/mess/tools/mkhdimg  \
		$(OBJ)/mess/tools/messroms $(OBJ)/mess/tools/imgtool  \
		$(OBJ)/mess/tools/mkimage  $(OBJ)/mess/sound          \
		$(OBJ)/ui $(OBJ)/mess/ui
		
all:	maketree $(EMULATOR) extra

# include the various .mak files
include src/core.mak
include src/$(OS)/lst/$(TARGET).mak
include src/rules.mak
include src/$(OS)/$(OS).mak
include mess/rules_ms.mak

ifdef DEBUG
DBGDEFS = -DMAME_DEBUG
else
DBGDEFS =
DBGOBJS =
endif

#extra:	romcmp$(EXE) $(TOOLS) $(TEXTS)
extra:

# combine the various definitions to one
CDEFS = $(DEFS) $(COREDEFS) $(CPUDEFS) $(SOUNDDEFS) $(ASMDEFS) $(DBGDEFS)
CDEFS_HOST = -DLSB_FIRST=1

$(EMULATOR): $(OBJS) $(COREOBJS) $(sort $(CPUOBJS)) $(OSOBJS) $(DRVLIBS)
# always recompile the version string
ifdef DREAMCAST
	$(CC) $(CDEFS) $(CFLAGS) $(OPTFLAG) -c src/version.c -o $(OBJ)/version.o
	$(CC) $(CDEFS) $(CFLAGS) $(OPTFLAG) -c src/dreamcast/dreamcast.c -o $(OBJ)/dreamcast/dreamcast.o
endif
ifdef DREAMCAST

	@echo Linking $@...
	$(LD) $(LDFLAGS) -o $@ $(KOS_START) $(OBJS) $(COREOBJS) $(sort $(CPUOBJS)) $(OSOBJS) $(LIBS) $(DRVLIBS)
	nm $(NAME)$(EXE) > junk
	$(KOS_STRIP) $(NAME)$(EXE)
	grep driver_ junk > junk2
	grep " R " junk2 > $(NAME).txt
	rm junk
	rm junk2
	$(KOS_OBJCOPY) -O binary $(NAME)$(EXE) $(NAME).bin
else
	@echo Linking $@...
	$(LD) $(LDFLAGS) $(OBJS) $(COREOBJS) $(sort $(CPUOBJS)) $(OSOBJS) $(LIBS) $(DRVLIBS) -o $@
endif

#ifndef DEBUG
#	upx -9 $(EMULATOR)
#endif

romcmp$(EXE): $(OBJ)/romcmp.o $(OBJ)/unzip.o
	@echo Linking $@...
	$(LD) $(LDFLAGS) $^ -lz -o $@

./$(OBJ)/drawgfx.o: ./src/drawgfx.c
	@echo OPTFREE Compling  $<...
	$(CC) $(CDEFS) $(CFLAGS) -O1 -c $< -o $@

./$(OBJ)/$(OS)/dgfx_16bit.o: ./src/$(OS)/dgfx_16bit.c
	@echo OPTFREE Compling  $<...
	$(CC) $(CDEFS) $(CFLAGS) -O1 -c $< -o $@

./$(OBJ)/%.o: ./src/%.c
	@echo Compiling $<...
	$(CC) $(CDEFS) $(CFLAGS) $(OPTFLAG) -c $< -o $@

./$(OBJ)/%.o: ./src/%.s
	@echo Assembling $<...
	$(AS) $(AFLAGS) $< -o $@

$(OBJ)/mess/%.o: mess/%.c
	@echo [$(NAME)] Compiling $<...
	$(CC) $(CDEFS) $(CFLAGS) $(OPTFLAG) -c $< -o $@


# compile generated C files for the 68000 emulator
$(M68000_GENERATED_OBJS): $(OBJ)/cpu/m68000/m68kmake$(EXE_HOST)
	@echo Compiling $(subst .o,.c,$@)...
	$(CC) $(CDEFS) $(CFLAGS) $(OPTFLAG) -c $(subst .o,.c,$@) -o $@


# additional rule, because m68kcpu.c includes the generated m68kops.h :-/
$(OBJ)/cpu/m68000/m68kcpu.o: $(OBJ)/cpu/m68000/m68kmake$(EXE_HOST)

# generate C source files for the 68000 emulator
$(OBJ)/cpu/m68000/m68kmake$(EXE_HOST): src/cpu/m68000/m68kmake.c
	@echo M68K make $<...
	$(CC_HOST) $(CDEFS_HOST) $(CFLAGS_HOST) -o $(OBJ)/cpu/m68000/m68kmake$(EXE_HOST) $<
	@echo Generating M68K source files...
	@$(OBJ)/cpu/m68000/m68kmake$(EXE_HOST) $(OBJ)/cpu/m68000 src/cpu/m68000/m68k_in.c

# generate asm source files for the 68000 emulator
#$(OBJ)/cpu/m68000/68000.asm:  src/cpu/m68000/make68k.c
#	@echo Compiling $<...
#	$(CC_HOST) $(CDEFS) $(CFLAGS) -O0 -DDOS -o $(OBJ)/cpu/m68000/make68k$(EXE_HOST) $<
#	@echo Generating $@...
#	@$(OBJ)/cpu/m68000/make68k$(EXE_HOST) $@ $(OBJ)/cpu/m68000/comptab.asm

# generated asm files for the 68000 emulator
$(OBJ)/cpu/m68000/68000.o:  $(OBJ)/cpu/m68000/68000.asm
	@echo Assembling $<...
	$(ASM) -o $@ $(ASMFLAGS) $(subst -D,-d,$(ASMDEFS)) $<

$(OBJ)/%.a:
	@echo Archiving $@...
	@rm -f $@
	$(AR) cr $@ $^
#	$(LD)  -r -o $@ $^
#	$(LD) -EL -r -o $@ $^

makedir:
	@echo make makedir is no longer necessary, just type make

$(sort $(OBJDIRS)):
	$(MD) $@

koschg: cleanemu $(EMULATOR)
	$(KOS_LOADER) $(EMULATOR)
	
disk: romdisk_boot.o
	$(CC) $(CDEFS) $(CFLAGS) $(OPTFLAG) -c src/dreamcast/dreamcast.c -DWT_ROMDISK -o $(OBJ)/dreamcast/dreamcast.o
	$(LD) $(LDFLAGS) -o dsk$(EMULATOR) $(KOS_START) $(OBJS) $(COREOBJS) $(sort $(CPUOBJS)) $(OSOBJS) romdisk_boot.o $(LIBS) $(DRVLIBS)
	nm dsk$(NAME)$(EXE) > junk
	$(KOS_STRIP) dsk$(NAME)$(EXE)
	grep driver_ junk > junk2
	grep " R " junk2 > dsk$(NAME).txt
	rm junk
	rm junk2
	$(KOS_OBJCOPY) -O binary dsk$(NAME)$(EXE) dsk$(NAME).bin

romdisk_boot.img:
	$(KOS_GENROMFS) -f romdisk_boot.img -d romdisk_boot -v

romdisk_boot.o: romdisk_boot.img
	$(KOS_BASE)/utils/bin2o/bin2o romdisk_boot.img romdisk_boot romdisk_boot.o

rundisk: $(EMULATOR) disk
#	$(KOS_LOADER) dsk$(EMULATOR)
	start cmd /K C:\\MINGW\\TEST\\$(KOS_LOADER) C:\\MINGW\\mess\\dsk$(EMULATOR)

cleandisk:
	$(RM) romdisk_boot.img
	$(RM) romdisk_boot.o
	
cleanemu:
	$(RM) $(EMULATOR)	
	
maketree: $(sort $(OBJDIRS))

src/$(OS)/lst/$(TARGET).mak: src/$(OS)/lst/$(TARGET).lst
	perl makemak.pl src/$(OS)/lst/$(TARGET)


run: $(EMULATOR)
	$(KOS_LOADER) $(EMULATOR)
	
clean:
	@echo Deleting object tree $(OBJ)...
	$(RM) -r $(OBJ)
	@echo Deleting $(EMULATOR)...
	$(RM) $(EMULATOR)
	@echo Deleting $(NAME).bin...
	$(RM) $(NAME).bin
	@echo Deleting $(NAME).txt...
	$(RM) $(NAME).txt

clean68k:
	@echo Deleting 68k files...
	$(RM) -r $(OBJ)/cpuintrf.o
	$(RM) -r $(OBJ)/drivers/cps2.o
	$(RM) -r $(OBJ)/cpu/m68000
