#
#  smoke16/Makefile - A GNU Make script to build the SMOKE-16 tools.
#  $Revision: 1.47 $
#  Copyright 1997-2001, Benjamin Sittler
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#


##
## Host Toolchain Configuration
##

## Host conventional filename suffices
OBJ_SUFFIX=.o
LIB_SUFFIX=.a
EXE_SUFFIX=
#EXE_SUFFIX=.exe
BAK_SUFFIX=~
# Convenient single-letter versions of the common suffices
o=$(OBJ_SUFFIX)
a=$(LIB_SUFFIX)
x=$(EXE_SUFFIX)

## Host C preprocessing flags
CPPFLAGS = -Iinclude

## Host ANSI C/C++ compiler (choose one)

# NOTE: The SMOKE-16 toolset is written in ANSI C, but pains have been
# taken to make sure it is also valid ANSI C++. Compiling using a C++
# compiler rather than a C compiler may improve optimization and help
# find subtle type incompatibilities which would go unnoticed by a
# plain C compiler.

# Option 1: GNU C or C++ compiler (g++ or gcc)
#CC = g++
CC = gcc
CFLAGS = -g -Wall -O2

# Option 2: Old C or C++ compiler (c++ or cc)
#CC = c++
#CC = cc
#CFLAGS =

# Complete preprocessing and compilation action for option 1 or 2
COMPILE = $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ -c $<

## Libraries for SMOKE-16 toolchain
LIBS = -Llib -lObj

## Host Linker (choose one)

# Option 1: Link using C/C++ compiler (specified above)
LD = $(CC)
LDFLAGS = $(CFLAGS)

# Option 2: Link using system linker
#LD = ld
#LDFLAGS =

# Complete linking action for option 1 or 2
LINK = $(LD) $(LDFLAGS) -o $@ $<

## Host Librarian
AR = ar
ARFLAGS =
ARCMD = ru
ARCHIVE = $(AR) $(ARFLAGS) ru $@

## Host Library Index Generator (choose one)

# Option 1: Use GNU librarian with the 's' command
#RANLIB = ar s $@

# Option 2: Use old ranlib
RANLIB = ranlib $@

# Option 3: No separate indexing step required
#RANLIB =

## Host Flex fast lexical analyzer generator
FLEX = flex
FLEXFLAGS =
RUN_FLEX = $(FLEX) $(FLEXFLAGS) -o$@ $<

## Host GNU Bison compiler-compiler
BISON = bison
BISONFLAGS = -tv
RUN_BISON = $(BISON) $(BISONFLAGS) -o$@ $<

# Update a file's modification time
TOUCH = touch $@


##
## SMOKE-16 Toolchain Configuration
##

## SMOKE-16 assembly preprocessor [a.k.a. cpp] (choose one)

# Target Processor Architecture: __SMOKE16 and __SMOKE16__ indicate
# that the target processor architecture is the SMOKE-16; the SMOKE-16
# processor architecture is documented in doc/opcodes.txt. Some useful
# SMOKE-16 macros are defined in <smoke16/asm.h>.

# Target Byte Order: __BIG_ENDIAN__ indicates that each number is
# stored in the target processor's memory with the more significant
# byte at the lower address, and the less significant byte at the
# higher address.

# Target Operating System: __mirrors and __mirrors__ indicate that the
# target operating system provides the Mirrors system call interface;
# the Mirrors system calls are described in <smoke16/syscall.h>.

# Target Naming Conventions: __USER_LABEL_PREFIX__ is defined to _
# (underscore,) indicating that exported symbol names will have an
# underscore prefixed to them. (You may safely ignore warnings about
# the redefinition of this symbol.)

ASP16DEFS = \
           -D__SMOKE16 -D__SMOKE16__ -D__mirrors -D__mirrors__ \
           -D__BIG_ENDIAN__ \
           -D__USER_LABEL_PREFIX__=_ \
           -Iinclude

# Option 1: GNU CPP
ASP16 = gcc -E
ASP16FLAGS = -x assembler-with-cpp -traditional-cpp -undef -nostdinc
ASP16ASSERT = -A- -A 'cpu(smoke16)' -A 'system(mirrors)'
ASPREPROCESS16_DEP =
ASPREPROCESS16 = $(ASP16) $(ASP16FLAGS) $(ASP16DEFS) $(ASP16ASSERT) -o $@ $<

# Option 2: Old CPP
#ASP16 = cpp
#ASP16FLAGS =
#ASPREPROCESS16_DEP =
#ASPREPROCESS16 = $(ASP16) $(ASP16FLAGS) $(ASP16DEFS) $< $@

## SMOKE-16 assembler
# Options:
# -A vNUM                 assemble for SMOKE-16 toolset vNUM
# -J                      ignore overflow
# -portable               use portable execution character encoding
# -R                      place read-only data (.rdata) in the text section
#                         (incompatible with split I&D)
# -7 or -r7 or -t6        allow use of reserved register %7/%r7/%t6
AS16 = bin/as
#AS16 = bin.v0/as
#AS16FLAGS = -R
AS16FLAGS =
ASSEMBLE16_DEP = bin/as$x
ASSEMBLE16 = $(AS16) $(AS16FLAGS) -o $@ $<

## SMOKE-16 linker
# Options:
# -A vNUM                 link for SMOKE-16 toolset vNUM
# -e SYMBOL               set the entry point to SYMBOL (default is '__entry')
# -i or -r                generate relocatable output
# -j or -jmagic           generate split I&D executable (JMAGIC)
# -L DIR                  add DIR to the archive search path
# -l ARCHIVE              link in libARCHIVE.a from the archive search path
# -N or -omagic           generate object or impure executable (OMAGIC)
# -n or -nmagic           generate pure executable (NMAGIC)
# -S                      strip out debugging symbols
# -s                      strip out all symbols
# -Tbss [0x]HEX           set the load address of the BSS section
# -Tdata [0x]HEX          set the load address of the data section
# -T[text] [0x]HEX        set the load address of the text section
# -Z or -lmagic           generate object archive (LMAGIC)
# -1                      process following archives once
# -2                      process following archive list twice
LD16 = bin/ld
#LD16 = bin.v0/ld
#LD16FLAGS =
LD16FLAGS = -j
LD16LIBS = -2 -Llib16 -lc -1
LINK16_DEP = bin/ld$x
LINK16 = $(LD16) $(LD16FLAGS) $(LD16LIBS) -o $@ $<

## SMOKE-16 librarian
# NOTE: until 'ar' works, we use 'ld -Z'
AR16 = bin/ar
AR16FLAGS =
#ARCHIVE16_DEP = bin/ar$x
#ARCHIVE16 = $(AR16) $(AR16FLAGS) ru $@
ARCHIVE16_DEP = bin/ld$x
ARCHIVE16 = $(LD16) -Z -o $@

## SMOKE-16 emulator
# Options:
# -E [0x]HEX              override the entry point
# -M [0x]HEX              set the maximum accessible address
# -N or -numeric          show addresses as numbers
# -S or -symbolic         show addresses as symbols with offsets
# -Tbss [0x]HEX           set the load address of the BSS section
# -Tdata [0x]HEX          set the load address of the data section
# -T[text] [0x]HEX        set the load address of the text section
# -disassemble            show instructions as they are executed
# -trace                  show system calls as they are executed
# -registers              show register contents at every tick
EMU16 = bin/emu
EMU16FLAGS =
EMULATE16_DEP = bin/emu$x
EMULATE16 = $(EMU16) $(EMU16FLAGS) -- $<


##
## Targets
##

OBJS = \
bin/sim$x \
bin/emu$x \
bin/emu--$x \
bin/as$x \
bin/ar$x \
bin/ld$x \
bin/nm$x

SMOKEOBJS = \
bin16/carry bin16/mul bin16/sigill bin16/hello bin16/dump \
bin16/echo bin16/cat bin16/deadbeef bin16/hextest \
bin16/f16

SMOKELIBS = \
lib16/libc.a

LIBCOBJS = \
libc/obj16/_exit.o \
libc/obj16/_sdiv.o \
libc/obj16/_smul.o \
libc/obj16/_udiv.o \
libc/obj16/_umul.o \
libc/obj16/brk.o \
libc/obj16/close.o \
libc/obj16/crt.o \
libc/obj16/fclose.o \
libc/obj16/fgetc.o \
libc/obj16/fopen.o \
libc/obj16/fprintd.o \
libc/obj16/fprintf.o \
libc/obj16/fprintx.o \
libc/obj16/fputc.o \
libc/obj16/fputs.o \
libc/obj16/fscand.o \
libc/obj16/malloc.o \
libc/obj16/open.o \
libc/obj16/perror.o \
libc/obj16/printf.o \
libc/obj16/puts.o \
libc/obj16/raise.o \
libc/obj16/read.o \
libc/obj16/stdio.o \
libc/obj16/strcat.o \
libc/obj16/strcmp.o \
libc/obj16/strcpy.o \
libc/obj16/strlen.o \
libc/obj16/ungetc.o \
libc/obj16/vfprintf.o \
libc/obj16/write.o

RCSOBJS = \
COPYING \
CREDITS \
Makefile \
README \
mkdirs \
mkdirs.bat \
regbfmts \
emucolor \
bin.v0/as \
bin.v0/ld \
include/smoke16/a_out.h \
include/smoke16/fcntl.h \
include/smoke16/asm.h \
src16/carry.s \
src16/deadbeef.s \
src16/f16.s \
src/getopt.c \
include/getopt.h \
src/hashpjw.c \
include/smoke16/hashpjw.h \
src/hashtbl.c \
include/smoke16/hashtbl.h \
src16/hello.s \
src16/echo.s \
src16/cat.s \
src16/dump.s \
src16/hextest.s \
magic \
src16/mul.s \
include/smoke16/regs.h \
src16/sigill.s \
src/sim.c \
src/ar.c \
src/as.c \
src/as_tab.y \
src/as_yy.l \
src/emu.c \
src/emu--.c \
src/ld.c \
src/nm.c \
include/smoke16/libObj.h \
libObj/src/Sym.c \
libObj/src/SymTab.c \
libObj/src/Search.c \
libObj/src/Reloc.c \
libObj/src/TmpFile.c \
libObj/src/Obj.c \
libObj/src/types.c \
libObj/src/a_out.c \
libObj/src/str.c \
libc/src16/_exit.s \
libc/src16/_sdiv.s \
libc/src16/_smul.s \
libc/src16/_udiv.s \
libc/src16/_umul.s \
libc/src16/brk.s \
libc/src16/close.s \
libc/src16/crt.s \
libc/src16/fclose.s \
libc/src16/fgetc.s \
libc/src16/fopen.s \
libc/src16/fprintd.s \
libc/src16/fprintf.s \
libc/src16/fprintx.s \
libc/src16/fputc.s \
libc/src16/fputs.s \
libc/src16/fscand.s \
libc/src16/malloc.s \
libc/src16/open.s \
libc/src16/perror.s \
libc/src16/printf.s \
libc/src16/puts.s \
libc/src16/raise.s \
libc/src16/read.s \
libc/src16/stdio.s \
libc/src16/strcat.s \
libc/src16/strcmp.s \
libc/src16/strcpy.s \
libc/src16/strlen.s \
libc/src16/ungetc.s \
libc/src16/vfprintf.s \
libc/src16/write.s \
include/smoke16/syscall.h \
include/smoke16/types.h \
doc/a_out.txt \
doc/getopt.txt \
doc/opcodes.txt \
doc/portable.txt \
icons/ar.xbm \
icons/ar.xpm \
icons/as.xbm \
icons/as.xpm \
icons/emu.xbm \
icons/emu.xpm \
icons/ld.xbm \
icons/ld.xpm \
icons/nm.xbm \
icons/nm.xpm \
icons/sim.xbm \
icons/sim.xpm \
icons/smoke.xbm \
icons/smoke.xpm \
icons/smoke16.xbm \
icons/smoke16.xpm

LIBOBJ = lib/libObj$a

LIBOBJOBJS = \
libObj/obj/Sym$o \
libObj/obj/SymTab$o \
libObj/obj/Search$o \
libObj/obj/Reloc$o \
libObj/obj/TmpFile$o \
libObj/obj/Obj$o \
libObj/obj/types$o \
libObj/obj/a_out$o \
libObj/obj/str$o

all: $(OBJS) $(SMOKEOBJS) $(LIBOBJ) $(SMOKELIBS)

PHONY = \
all \
update \
checkout \
checkin \
shiny \
clean \
cleaner \
dead \
deader \
distclean \
test \
test1 \
test2 \
test3 \
test4

.PHONY: $(PHONY)

update:
	ci -l $(RCSOBJS)

checkout:
	co -l $(RCSOBJS)

checkin:
	ci $(RCSOBJS)

shiny:
	rm -f core *$(BAK_SUFFIX) */*$(BAK_SUFFIX) */*/*$(BAK_SUFFIX)

clean: shiny
	rm -f libObj/obj/*$o
	rm -f obj/*$o
	rm -f src/as.output src/as_yy.c src/as_tab.c

cleaner: clean
	rm -f $(LIBOBJ) $(LIBOBJOBJS) $(OBJS)

dead: shiny
	rm -f libc/obj16/*.o obj16/*.o
	rm -f libc/src16/*.spp src16/*.spp

deader: dead
	rm -f $(SMOKEOBJS) $(SMOKELIBS)

distclean: cleaner deader

src16/%.s: include/smoke16/syscall.h include/smoke16/asm.h include/smoke16/fcntl.h
	$(TOUCH)

libc/src16/%.s: include/smoke16/syscall.h include/smoke16/asm.h include/smoke16/fcntl.h
	$(TOUCH)

src16/%.spp: src16/%.s $(ASPREPROCESS16_DEP)
	$(ASPREPROCESS16)

obj16/%.o: src16/%.spp $(ASSEMBLE16_DEP)
	$(ASSEMBLE16)

libc/src16/%.spp: libc/src16/%.s $(ASPREPROCESS16_DEP)
	$(ASPREPROCESS16)

libc/obj16/%.o: libc/src16/%.spp $(ASSEMBLE16_DEP)
	$(ASSEMBLE16)

bin16/%: obj16/%.o lib16/libc.a $(LINK16_DEP)
	$(LINK16)

lib16/libc.a: $(LIBCOBJS) $(ARCHIVE16_DEP)
	$(ARCHIVE16) $(LIBCOBJS)

libc/src16/syscall.s: include/smoke16/asm.h include/smoke16/syscall.h
	$(TOUCH)

obj/%$o: src/%.c
	$(COMPILE)

obj/getopt$o: src/getopt.c include/getopt.h
	$(COMPILE)

bin/sim$x: obj/sim$o
	$(LINK)

obj/sim$o: src/sim.c include/smoke16/a_out.h include/smoke16/regs.h
	$(COMPILE)

bin/emu$x: obj/emu$o obj/getopt$o $(LIBOBJ)
	$(LINK) obj/getopt$o $(LIBS)

obj/emu$o: src/emu.c include/smoke16/libObj.h include/getopt.h include/smoke16/fcntl.h include/smoke16/a_out.h include/smoke16/regs.h include/smoke16/syscall.h
	$(COMPILE)

bin/emu--$x: obj/emu--$o
	$(LINK) $(LIBS)

obj/emu--$o: src/emu--.c src/emu.c include/smoke16/libObj.h include/smoke16/fcntl.h include/smoke16/a_out.h include/smoke16/regs.h include/smoke16/syscall.h
	$(COMPILE)

bin/as$x: obj/as$o obj/getopt$o obj/hashpjw$o obj/hashtbl$o $(LIBOBJ)
	$(LINK) obj/getopt$o obj/hashpjw$o obj/hashtbl$o $(LIBS)

include/smoke16/hashtbl.h: include/smoke16/a_out.h
	$(TOUCH)

src/hashtbl.c: include/smoke16/hashtbl.h
	$(TOUCH)

src/hashpjw.c: include/smoke16/hashpjw.h
	$(TOUCH)

src/as.c: include/smoke16/libObj.h
	$(TOUCH)

obj/as$o: src/as.c src/as_tab.c src/as_yy.c include/smoke16/a_out.h include/getopt.h include/smoke16/hashpjw.h include/smoke16/hashtbl.h
	$(COMPILE)

src/as_tab.c: src/as_tab.y $(BISON_SIMPLE) $(BISON_HAIRY)
	$(RUN_BISON)

src/as_yy.c: src/as_yy.l
	$(RUN_FLEX)

bin/ld$x: obj/ld$o obj/getopt$o obj/hashpjw$o $(LIBOBJ)
	$(LINK) obj/getopt$o obj/hashpjw$o $(LIBS)

bin/nm$x: obj/nm$o obj/getopt$o obj/hashpjw$o $(LIBOBJ)
	$(LINK) obj/getopt$o obj/hashpjw$o $(LIBS)

bin/ar$x: obj/ar$o obj/getopt$o obj/hashpjw$o $(LIBOBJ)
	$(LINK) obj/getopt$o obj/hashpjw$o $(LIBS)

include/smoke16/libObj.h: include/smoke16/a_out.h include/smoke16/hashpjw.h
	$(TOUCH)

lib/libObj$a: $(LIBOBJOBJS)
	$(ARCHIVE) $(LIBOBJOBJS)
	$(RANLIB)

libObj/obj/%$o: libObj/src/%.c include/smoke16/libObj.h
	$(COMPILE)

obj/ld$o: src/ld.c include/smoke16/libObj.h include/getopt.h
	$(COMPILE)

obj/nm$o: src/nm.c include/smoke16/libObj.h include/getopt.h
	$(COMPILE)

include/smoke16/a_out.h include/smoke16/regs.h: include/smoke16/types.h
	$(TOUCH)


## SMOKE-16 Testing targets

test: test1 test2 test3 test4

test1: bin16/carry $(EMULATE16_DEP)
	$(EMULATE16)

test2: bin16/mul $(EMULATE16_DEP)
	$(EMULATE16)

test3: bin16/echo $(EMULATE16_DEP)
	$(EMULATE16) "All echo tests completed."

test4: bin16/hello $(EMULATE16_DEP)
	$(EMULATE16)
