VERSION=1.2-7
TARVERSION=1.2
# spec file can override
RPMVERSION=$(VERSION)

# If you don't have either nasm or the ELKS as86, then just do make
# and make install because the assembler sources are supplied preassembled
# If you do make realclean you will have to unpack the mknbi archive again

# Use nasm or as86
ASM=nasm
# This must be the as86 from the ELKS project, the default Linux one won't do
#ASM=as86

# for first32*.linux
# This one makes multiple versions
FIRSTRELOCS=	0x92800 0x82800
OLDGAS:=	$(shell $(AS) --version | grep -q '2\.9\.1' && echo -DGAS291)
CFLAGS=		-Os -ffreestanding -fstrength-reduce -fomit-frame-pointer \
		-mcpu=i386 \
		-Wall -W -Wno-format -Wno-unused -DVERSION=\"$(VERSION)\"
LDBINARYFLAG=	--oformat binary

# for FreeDOS
FDKSEG=	0x60

# for menu
MENURELOC=	0x10000

PREFIX=		/usr/local
INSTPREFIX=	$(BUILD_ROOT)$(PREFIX)
LIBDIR=		$(PREFIX)/lib/mknbi
INSTLIBDIR=	$(INSTPREFIX)/lib/mknbi
BINDIR=		$(INSTPREFIX)/bin
MANDIR=		$(INSTPREFIX)/man/man1
DOCDIR=		$(INSTPREFIX)/doc/mknbi-$(RPMVERSION)

INSTALL=	install

PROG=	mknbi disnbi dismbr disdosbb
MODULES=Nbi.pm Elf.pm TruncFD.pm
FIRSTS=	first16.linux \
	$(foreach i,$(FIRSTRELOCS),first32@$(i).linux first32pm@$(i).linux first32elf@$(i).linux) \
	first.dos first.fdos menu
ALTBOOT=altboot.bin
RMRD=	rmrd.com
MANS=	mknbi.1 disnbi.1 menuc.1
HTMLS=	mknbi.html disnbi.html menuc.html
DOCS=	$(MANS) $(HTMLS)


all:	$(PROG) $(FIRSTS) $(RMRD) $(DOCS)

# Tagged image builder
mknbi:	mknbi.pl Nbi.pm TruncFD.pm
	sed -e 's:@@VERSION@@:$(VERSION):' -e 's:@@LIBDIR@@:$(LIBDIR):' -e 's/@@FDKSEG@@/$(FDKSEG)/' mknbi.pl > $@
	chmod 755 $@

# Tagged image display and disassemble
disnbi:	disnbi.pl
	cp -p disnbi.pl disnbi
	chmod 755 disnbi

# Master boot record display
dismbr:	dismbr.pl
	cp -p dismbr.pl dismbr
	chmod 755 dismbr

# DOS boot block display
disdosbb:	disdosbb.pl
	cp -p disdosbb.pl disdosbb
	chmod 755 disdosbb

# Old 16-bit first stage setup program
first16.linux:	first-linux.S first-linux.h version-linux.h
ifeq ($(ASM),as86)
	gcc $(ASMCFLAGS) -DUSE_AS86 -E -traditional -o first-linux.s first-linux.S
	as86 -0 -b first16.linux first-linux.s
else
	gcc $(ASMCFLAGS) -DUSE_NASM -E -traditional -o first-linux.s first-linux.S
	nasm -f bin first-linux.s -o first16.linux
endif

# New 32-bit first stage setup program
first32@%.linux:	start32@%.o first32.o memsizes.o printf.o
	$(LD) -N -Ttext $* -e _start $(LDBINARYFLAG) -o $@ start32@$*.o first32.o memsizes.o printf.o
	@if [ `wc -c < $@` -gt 6144 ]; then echo Binary too large; fi

# New 32-bit first stage protected mode call setup program
first32pm@%.linux:	start32pm@%.o first32pm.o memsizes.o printf.o
	$(LD) -N -Ttext $* -e _start $(LDBINARYFLAG) -o $@ start32pm@$*.o first32pm.o memsizes.o printf.o
	@if [ `wc -c < $@` -gt 6144 ]; then echo Binary too large; fi

# New 32-bit first stage ELF setup program
first32elf@%.linux:	start32pm@%.o first32elf.o memsizes.o printf.o
	$(LD) -N -Ttext $* -e _start $(LDBINARYFLAG) -o $@ start32pm@$*.o first32elf.o memsizes.o printf.o
	@if [ `wc -c < $@` -gt 6144 ]; then echo Binary too large; fi

start32@%.o:	start32.S
	gcc -E -DRELOC=$* $(OLDGAS) start32.S | $(AS) -o start32@$*.o

start32pm@%.o:	start32.S
	gcc -E -DFIRST32PM -DRELOC=$* $(OLDGAS) start32.S | $(AS) -o start32pm@$*.o

first32.o:	first32.c etherboot.h
	gcc $(CFLAGS) -c $*.c

first32pm.o:	first32.c etherboot.h
	gcc $(CFLAGS) -DFIRST32PM -o first32pm.o -c first32.c

first32elf.o:	first32.c etherboot.h
	gcc $(CFLAGS) -DFIRST32ELF -o first32elf.o -c first32.c

memsizes.o:		memsizes.c
	gcc $(CFLAGS) -c $*.c

printf.o:		printf.c
	gcc $(CFLAGS) -c $*.c

# DOS first stage setup program, depend on Makefile for version number
first.dos:	first-dos.S first-dos.h version-dos.h Makefile
ifeq ($(ASM),as86)
	gcc $(ASMCFLAGS) -DUSE_AS86 -DVENDOR_MAGIC=\"mknbi-dos-$(VERSION)\" -E -traditional -o first-dos.s first-dos.S
	as86 -0 -b first.dos first-dos.s
else
	gcc $(ASMCFLAGS) -DUSE_NASM -DVENDOR_MAGIC=\"mknbi-dos-$(VERSION)\" -E -traditional -o first-dos.s first-dos.S
	nasm -f bin first-dos.s -o first.dos
endif

# FreeDOS first stage setup program, depend on Makefile for version number
first.fdos:	first-dos.S first-dos.h version-dos.h Makefile
ifeq ($(ASM),as86)
	gcc $(ASMCFLAGS) -DFREEDOS -DFDKSEG=$(FDKSEG) -DUSE_AS86 -DVENDOR_MAGIC=\"mknbi-fdos-$(VERSION)\" -E -traditional -o first-fdos.s first-dos.S
	as86 -0 -b first.fdos first-fdos.s
else
	gcc $(ASMCFLAGS) -DFREEDOS -DFDKSEG=$(FDKSEG) -DUSE_NASM -DVENDOR_MAGIC=\"mknbi-fdos-$(VERSION)\" -E -traditional -o first-fdos.s first-dos.S
	nasm -f bin first-fdos.s -o first.fdos
endif

# Menu first stage program
menu:	startmenu.o menu.o string.o printf.o ansiesc.o
	$(LD) -N -Ttext $(MENURELOC) -e _start $(LDBINARYFLAG) -o $@ startmenu.o menu.o string.o printf.o ansiesc.o

# Another menu program, this one simpler
menu-simple:	startmenu.o menu-simple.o string.o printf.o ansiesc.o
	$(LD) -N -Ttext $(MENURELOC) -e _start $(LDBINARYFLAG) -o $@ startmenu.o menu-simple.o string.o printf.o ansiesc.o

startmenu.o:	startmenu.S
	gcc -E -DRELOC=$(MENURELOC) $(OLDGAS) startmenu.S | $(AS) -o startmenu.o

menu.o:		menu.c string.h etherboot.h
	gcc $(CFLAGS) -c $*.c

menu-simple.o:	menu-simple.c string.h etherboot.h
	gcc $(CFLAGS) -c $*.c

string.o:	string.h string.c
	gcc $(CFLAGS) -c $*.c

ansiesc.o:	ansiesc.c etherboot.h
	gcc $(CFLAGS) -DGFX -c $*.c

# Remove ramdisk utility under DOS
rmrd.com:	rmrd.S
ifeq ($(ASM),as86)
	gcc $(ASMCFLAGS) -DUSE_AS86 -E -traditional -o rmrd.s rmrd.S
	# -s appears to be necessary to start binary at 0x100
	as86 -0 -b rmrd.com -s rmrd.map rmrd.s
else
	gcc $(ASMCFLAGS) -DUSE_NASM -E -traditional -o rmrd.s rmrd.S
	nasm -f bin rmrd.s -o rmrd.com
endif

# Alternate boot block, taken from netboot mknbi-dos
# Not made by default because not everybody has as86 installed
$(ALTBOOT):	altboot.S
	gcc -E altboot.S > altboot.s
	as86 -s /dev/null -b $(ALTBOOT) altboot.s
	$(RM) altboot.s

$(MANS):	mknbi.pl disnbi.pl Makefile
	pod2man --date=`date +%Y-%m-%d` --release="Mknbi $(VERSION)" --center="Etherboot tools" mknbi.pl > mknbi.1
	pod2man --date=`date +%Y-%m-%d` --release="Mknbi $(VERSION)" --center="Etherboot tools" disnbi.pl > disnbi.1
	pod2man --date=`date +%Y-%m-%d` --release="Mknbi $(VERSION)" --center="Etherboot tools" menuc.pl > menuc.1

$(HTMLS):	mknbi.pl disnbi.pl
	pod2html mknbi.pl > mknbi.html
	pod2html disnbi.pl > disnbi.html
	pod2html menuc.pl > menuc.html

install:	all
	-mkdir -p $(INSTLIBDIR)
	$(INSTALL) $(PROG) $(INSTLIBDIR)/
	$(INSTALL) -m 644 $(MODULES) $(FIRSTS) $(ALTBOOT) $(RMRD) $(INSTLIBDIR)/
	-mkdir -p $(BINDIR)
	cd $(BINDIR); \
	for i in linux rom fdos dos menu; \
	do \
		ln -sf ../lib/mknbi/mknbi mknbi-$$i; \
	done; \
	for i in linux menu; \
	do \
		ln -sf ../lib/mknbi/mknbi mkelf-$$i; \
	done
	(cd $(BINDIR); ln -sf ../lib/mknbi/disnbi disnbi)
	(cd $(BINDIR); ln -sf ../lib/mknbi/dismbr dismbr)
	(cd $(BINDIR); ln -sf ../lib/mknbi/disdosbb disdosbb)
	-mkdir -p $(MANDIR)
	$(INSTALL) -m 644 mknbi.1 disnbi.1 $(MANDIR)/
	-mkdir -p $(DOCDIR)
	$(INSTALL) -m 644 README LOG RELNOTES spec.txt $(DOCDIR)/

tarball:
	(cd ..; tar zcf /tmp/mknbi-$(TARVERSION).tar.gz --exclude CVS mknbi-$(TARVERSION))

clean:
	$(RM) -f $(PROG) start32*.o start32pm*.o first32*.o first32pm*.o \
	first32elf*.o printf.o menu.o menu-simple.o startmenu.o string.o ansiesc.o \
	first-linux.s first-dos.s first-fdos.s rmrd.s rmrd.map *.l pod2htm*

realclean:	clean
	$(RM) -f $(FIRSTS) $(RMRD) $(DOCS)
