# T3X/0 Makefile
# Nils M Holm, 2022, 2023, 2024
# Public domain / 0BSD license

V=45

CC=	cc

# Host platform, pick one
#
  HOST=	unix-386
# HOST=	unix-686
# HOST=	unix-armv6
# HOST=	unix-armv7
# HOST=	fbsd-386
# HOST=	macos-686

# Flags for compiling the TCVM
#
  TCVM_CFLAGS=  -O2 -g
 TCVM_CFLAGS+= -Dunix		# needed for syscalls on macOS

# Flags for compiling T3X/0 assembly output
#
  CFLAGS=
  CFLAGS+= -m32			# on x86_64 in 32-bit mode
 CFLAGS+= -Dunix		# needed for syscalls on macOS
# CFLAGS+= -static		# if all else fails
 CFLAGS+= -fPIC		# get rid of stupid linker errors
 CFLAGS+= -Wl,-z,notext	# get rid of stupid linker errors

# TCVM Options
#
  OPTS=
  LIBS=
#
# EXTRA will include the T3X.TRUNC (truncate file) and
# T3X.BREAK (check for keyboard interrupt) functions in the
# TCVM. Neither is necessary for bootstrapping T3X/0. If
# compilation of the TCVM fails, removing the EXTRA option
# might be worth a try.
#
  OPTS+= -DEXTRA
#
# SYSTEM will include portable system functions in the TCVM.
# Not needed for bootstrapping.
#
  OPTS+= -DSYSTEM
  LIBS+= library/system.c
#
# CONSOLE will include console I/O functions in the TCVM.
# Requires the curses library. Not needed for bootstrapping.
#
  OPTS+= -DCONSOLE
  LIBS+= library/console.c -lcurses

# Where the T3X libraries and most of the compiler binaries will be
# installed. However, this location should NOT be in $PATH.
#
T3XDIR=	${HOME}/t3x/lib

# Where you keep your binaries, e.g. /usr/local/bin. Only the compiler
# driver tx0 and the tcvm will be installed here. This location should
# be in $PATH.
#
BINDIR=	${HOME}/t3x/bin

########## nothing to configure past this line ##########

all:	tcvm txtrn.tc

all-tcode:	tcvm txtrn.tc tx-tcvm.tc tx-dos.tc tx-cpm.tc

all-native:	tcvm txtrn.tc tx-$(HOST) tx-dos tx-cpm tx-tcvm tx-raspi-1 \
		all-tcode

# When something goes wrong during cross-compilation, this
# target will reset the code generator and runtime links.
#
reset:
	ln -fs cgtcvm.t cg.t
	ln -fs txtcvm.t t3x.t
	ln -fs txemtbin.t txemit.t

# Regular bootstrap using a pre-compiled Tcode/0 image
#
txtrn.tc:	txtrn.t cg.t txemit.t tcvm bin/txtrn0.tc
	./tcvm bin/txtrn0.tc txtrn

# Alternative bootstrap using an existing T3Xr7 compiler
#
alt: txtrn.t cg.t txemit.t txtrn0
	txx txtrn0 txtrn

txtrn0:	opt/txtrn0.t
	tx -o txtrn0 opt/txtrn0.t

# The Tcode/0 VM
#
tcvm:	tcvm.c library/console.c library/system.c
	$(CC) $(TCVM_CFLAGS) $(OPTS) -o tcvm tcvm.c $(LIBS)

# Triple test of the Tcode/0 compiler
#
triple: txtrn.tc
	./tcvm txtrn.tc txtrn txtrn1
	./tcvm txtrn1.tc txtrn txtrn2
	cmp txtrn1.tc txtrn2.tc
	rm -f txtrn1.tc txtrn2.tc

# Run the test suite under the Tcode/0 VM
#
test:	programs/test.t tcvm txtrn.tc
	./tcvm txtrn.tc programs/test test
	./tcvm test.tc

# Native CP/M-Z80 compiler
#
tx-cpm.com:
	bin/build.sh cpm cpm

# Native DOS-8086 compiler
#
tx-dos.com:
	bin/build.sh dos dos

# HOST -> DOS-8086 cross compiler
#
tx-dos:
	bin/build.sh $(HOST) dos

# HOST -> CP/M-Z80 cross compiler
#
tx-cpm:
	bin/build.sh $(HOST) cpm

# HOST -> TCVM cross compiler
#
tx-tcvm:
	bin/build.sh $(HOST) tcvm

# HOST -> Raspberry Pi 1 bare metal cross compiler
#
tx-raspi-1:
	bin/build.sh $(HOST) raspi-1

# Native HOST compiler
#
tx-$(HOST):
	bin/build.sh $(HOST) $(HOST)

# Native FreeBSD-386 compiler
#
tx-fbsd-386:
	bin/build.sh fbsd-386 fbsd-386

# TCVM -> TCVM compiler
#
tx-tcvm.tc:
	bin/build.sh tcvm tcvm

# TCVM -> DOS compiler
#
tx-dos.tc:
	bin/build.sh tcvm dos

# TCVM -> CP/M compiler
#
tx-cpm.tc:
	bin/build.sh tcvm cpm

# Testing the Unix-386 compiler
#
unix-386-test: tx-unix-386
	bin/test.sh unix-386 unx386 4 "$(CFLAGS)"

# Testing the Unix-686 compiler
#
unix-686-test: tx-unix-686
	bin/test.sh unix-686 unx686 8 "$(CFLAGS)"

# Testing the macOS-686 compiler
#
macos-686-test: tx-macos-686
	bin/test.sh macos-686 mac686 8 "$(CFLAGS)"

# Testing the Unix-ARMv6 compiler
#
unix-armv6-test: tx-unix-armv6
	bin/test.sh unix-armv6 unxav6 4 "$(CFLAGS)"

# Testing the Unix-ARMv7 compiler
#
unix-armv7-test: tx-unix-armv7
	bin/test.sh unix-armv7 unxav7 4 "$(CFLAGS)"

# Testing the FreeBSD-386 compiler
#
fbsd-386-test:
	bin/build.sh fbsd-386 fbsd-386
	ln -fs txemtsrc.t txemit.t
	ln -fs targets/cgfbd386.t cg.t
	ln -fs targets/txfbd386.t t3x.t
	./tx-fbsd-386 txtrn tx-fbsd2
	as -32 -o tx-fbsd2.o tx-fbsd2.s
	ld -o tx-fbsd2 tx-fbsd2.o
	rm -f tx-fbsd2.[so]
	./tx-fbsd2 txtrn tx-fbsd3
	as -32 -o tx-fbsd3.o tx-fbsd3.s
	ld -o tx-fbsd3 tx-fbsd3.o
	rm -f tx-fbsd3.[so]
	cmp tx-fbsd2 tx-fbsd3 && rm tx-fbsd2
	@echo So far, so good!
	./tx-fbsd3 programs/test test
	as -32 -o test.o test.s
	ld -o test test.o
	rm -f test.[so]
	make reset
	./test && rm -f tx-fbsd3 test

install-dirs:
	install -d -m 0755 $(T3XDIR)
	install -d -m 0755 $(BINDIR)
	install -d -m 0755 $(T3XDIR)/cpmz80
	install -d -m 0755 $(T3XDIR)/dos86c
	install -d -m 0755 $(T3XDIR)/fbd386
	install -d -m 0755 $(T3XDIR)/unx386
	install -d -m 0755 $(T3XDIR)/unx686
	install -d -m 0755 $(T3XDIR)/unxav6
	install -d -m 0755 $(T3XDIR)/unxav7
	install -d -m 0755 $(T3XDIR)/raspi1

install-modules:
	install -c -m 0644 targets/txtcvm.t $(T3XDIR)/t3x.t
	install -c -m 0644 targets/txunx386.t $(T3XDIR)/unx386/t3x.t
	install -c -m 0644 targets/txunx686.t $(T3XDIR)/unx686/t3x.t
	install -c -m 0644 targets/txunxav6.t $(T3XDIR)/unxav6/t3x.t
	install -c -m 0644 targets/txunxav7.t $(T3XDIR)/unxav7/t3x.t
	install -c -m 0644 targets/txfbd386.t $(T3XDIR)/fbd386/t3x.t
	install -c -m 0644 targets/txcpmz80.t $(T3XDIR)/cpmz80/t3x.t
	install -c -m 0644 targets/txdos86c.t $(T3XDIR)/dos86c/t3x.t
	install -c -m 0644 targets/txraspi1.t $(T3XDIR)/raspi1/t3x.t
	install -c -m 0644 targets/unixlib.c $(T3XDIR)
	install -c -m 0644 library/host.tvm $(T3XDIR)/host.t
	install -c -m 0644 library/host.cpm $(T3XDIR)/cpmz80/host.t
	install -c -m 0644 library/host.dos $(T3XDIR)/dos86c/host.t
	install -c -m 0644 library/host.unx $(T3XDIR)/unx386/host.t
	install -c -m 0644 library/host.unx $(T3XDIR)/unx686/host.t
	install -c -m 0644 library/host.unx $(T3XDIR)/unxav6/host.t
	install -c -m 0644 library/host.unx $(T3XDIR)/unxav7/host.t
	install -c -m 0644 library/*.t $(T3XDIR)
	install -c -m 0644 library/console.tvm $(T3XDIR)/console.t
	install -c -m 0644 library/console.cpm $(T3XDIR)/cpmz80/console.t
	install -c -m 0644 library/console.dos $(T3XDIR)/dos86c/console.t
	install -c -m 0644 library/console.unx $(T3XDIR)/unx386/console.t
	install -c -m 0644 library/console.unx $(T3XDIR)/unx686/console.t
	install -c -m 0644 library/console.unx $(T3XDIR)/unxav6/console.t
	install -c -m 0644 library/console.unx $(T3XDIR)/unxav7/console.t
	install -c -m 0644 library/console.c $(T3XDIR)
	install -c -m 0644 library/system.tvm $(T3XDIR)/system.t
	install -c -m 0644 library/system.dos $(T3XDIR)/dos86c/system.t
	install -c -m 0644 library/system.unx $(T3XDIR)/unx386/system.t
	install -c -m 0644 library/system.unx $(T3XDIR)/unx686/system.t
	install -c -m 0644 library/system.unx $(T3XDIR)/unxav6/system.t
	install -c -m 0644 library/system.unx $(T3XDIR)/unxav7/system.t
	install -c -m 0644 library/chnload.cpm $(T3XDIR)/cpmz80/chnload.t
	install -c -m 0644 library/system.c $(T3XDIR)

# System-wide bytecode installation
# Use this if there is no native code support for your system
#
install-tcode:	all-tcode install-dirs install-modules
	install -c -m 0644 txtrn.tc $(T3XDIR)
	install -c -m 0644 tx-tcvm.tc $(T3XDIR)
	install -c -m 0644 tx-dos.tc $(T3XDIR)
	install -c -m 0644 tx-cpm.tc $(T3XDIR)
	install -c -m 0755 tcvm $(BINDIR)
	install -c -m 0755 bin/tx0.sh $(BINDIR)/tx0

# System-wide native code installation
# Use this with HOST=unix-* HOST=macos-* or HOST=fbsd-386
#
install-native:	all-native all-tcode install-dirs install-modules
	install -c -m 0644 txtrn.tc $(T3XDIR)/tx-tcvm.tc
	install -c -m 0755 tx-$(HOST) $(T3XDIR)
	install -c -m 0755 tx-dos $(T3XDIR)
	install -c -m 0755 tx-cpm $(T3XDIR)
	install -c -m 0755 tx-tcvm $(T3XDIR)
	install -c -m 0755 tx-raspi-1 $(T3XDIR)
	install -c -m 0644 tx-dos.tc $(T3XDIR)
	install -c -m 0644 tx-cpm.tc $(T3XDIR)
	install -c -m 0755 tcvm $(BINDIR)
	install -c -m 0755 bin/tx0.sh $(BINDIR)/tx0

# System-wide FreeBSD-386 installation
# Use this with HOST=unix-386 to also install the fbsd-386 backend
#
install-fbsd-native:	all-native tx-fbsd-386 install-native
	install -c -m 0644 targets/txfbd386.t $(T3XDIR)/fbd386/t3x.t
	install -c -m 0755 tx-fbsd-386 $(T3XDIR)

# Create DOS distribution archive
#
dosdist:
	-mkdir t3x0
	-mkdir t3x0/library
	-mkdir t3x0/programs
	-mkdir t3x0/docs
	cp bin/tx-dos.com t3x0/tx0.com
	tx0 -t dos programs/txconf t3x0/txconf
	tx0 -t dos programs/noe t3x0/noe
	tx0 -t dos programs/vee t3x0/vee
	tx0 programs/dosfile dosfile
	./dosfile docs/README.DOS t3x0/README
	./dosfile docs/veehelp.txt t3x0/docs/veehelp.txt
	./dosfile docs/t3x.txt t3x0/docs/t3x.txt
	./dosfile docs/t3x-libs.txt t3x0/docs/t3x-libs.txt
	./dosfile targets/txdos86c.t t3x0/library/t3x.t
	./dosfile library/char.t t3x0/library/char.t
	./dosfile library/io.t t3x0/library/io.t
	./dosfile library/iostream.t t3x0/library/iostream.t
	./dosfile library/memory.t t3x0/library/memory.t
	./dosfile library/rng.t t3x0/library/rng.t
	./dosfile library/shellsrt.t t3x0/library/shellsrt.t
	./dosfile library/strcomp.t t3x0/library/strcomp.t
	./dosfile library/strfmt.t t3x0/library/strfmt.t
	./dosfile library/string.t t3x0/library/string.t
	./dosfile library/strparse.t t3x0/library/strparse.t
	./dosfile library/console.dos t3x0/library/console.t
	./dosfile library/host.dos t3x0/library/host.t
	./dosfile library/system.dos t3x0/library/system.t
	./dosfile programs/apfel.t t3x0/programs/apfel.t
	./dosfile programs/ascii.t t3x0/programs/ascii.t
	./dosfile programs/base.t t3x0/programs/base.t
	./dosfile programs/bubble.t t3x0/programs/bubble.t
	./dosfile programs/dosfile.t t3x0/programs/dosfile.t
	./dosfile programs/echo.t t3x0/programs/echo.t
	./dosfile programs/fib.t t3x0/programs/fib.t
	./dosfile programs/hello.t t3x0/programs/hello.t
	./dosfile programs/hexdump.t t3x0/programs/hexdump.t
	./dosfile programs/noe.t t3x0/programs/noe.t
	./dosfile programs/primes.t t3x0/programs/primes.t
	./dosfile programs/queens.t t3x0/programs/queens.t
	./dosfile programs/sysdir.t t3x0/programs/sysdir.t
	./dosfile programs/tm.t t3x0/programs/tm.t
	./dosfile programs/uapfel.t t3x0/programs/uapfel.t
	./dosfile programs/vee.t t3x0/programs/vee.t
	rm -f dosfile
	zip -r9 t3x0dos.zip t3x0
	rm -r t3x0

# Create CP/M distribution archive
#
cpmdist:
	-mkdir t3x0
	cp bin/tx-cpm.com t3x0/tx0.com
	cp bin/tx-cpm.ovl t3x0/tx0.ovl
	tx0 -t cpm programs/txconf t3x0/txconf
	tx0 -t cpm programs/veecpm t3x0/vee
	tx0 -t cpm programs/noecpm t3x0/noe
	tx0 programs/cpmfile cpmfile
	./cpmfile docs/README.CPM t3x0/README
	./cpmfile docs/veehelp.txt t3x0/veehelp.txt
	./cpmfile docs/t3x.txt t3x0/t3x.txt
	./cpmfile docs/t3x-libs.txt t3x0/t3x-libs.txt
	./cpmfile targets/txcpmz80.t t3x0/t3x.t
	./cpmfile library/char.t t3x0/char.t
	./cpmfile library/cpm.t t3x0/cpm.t
	./cpmfile library/io.t t3x0/io.t
	./cpmfile library/iostream.t t3x0/iostream.t
	./cpmfile library/memory.t t3x0/memory.t
	./cpmfile library/rng.t t3x0/rng.t
	./cpmfile library/shellsrt.t t3x0/shellsrt.t
	./cpmfile library/strcomp.t t3x0/strcomp.t
	./cpmfile library/strfmt.t t3x0/strfmt.t
	./cpmfile library/string.t t3x0/string.t
	./cpmfile library/strparse.t t3x0/strparse.t
	./cpmfile library/console.cpm t3x0/console.t
	./cpmfile library/host.cpm t3x0/host.t
	./cpmfile library/chnload.cpm t3x0/chnload.t
	./cpmfile programs/apfel.t t3x0/apfel.t
	./cpmfile programs/ascii.t t3x0/ascii.t
	./cpmfile programs/base.t t3x0/base.t
	./cpmfile programs/bubble.t t3x0/bubble.t
	./cpmfile programs/cpmdir.t t3x0/cpmdir.t
	./cpmfile programs/cpmfile.t t3x0/cpmfile.t
	./cpmfile programs/echo.t t3x0/echo.t
	./cpmfile programs/fib.t t3x0/fib.t
	./cpmfile programs/hello.t t3x0/hello.t
	./cpmfile programs/hexdump.t t3x0/hexdump.t
	./cpmfile programs/noecpm.t t3x0/noecpm.t
	./cpmfile programs/primes.t t3x0/primes.t
	./cpmfile programs/queens.t t3x0/queens.t
	./cpmfile programs/tm.t t3x0/tm.t
	./cpmfile programs/uapfel.t t3x0/uapfel.t
	./cpmfile programs/veecpm.t t3x0/veecpm.t
	rm -f cpmfile
	(cd t3x0; zip -0 t3x0cpm.zip *; mv t3x0cpm.zip ..)
	rm -r t3x0

# Create disk for the Agon Light 2
#
agondist:
	make cpmdist
	mkdir t3x0agon
	(cd t3x0agon; unzip ../t3x0cpm.zip)
	dd if=/dev/zero of=cpmh.dsk bs=1024 count=8192
	mkfs.cpm -f 8mb cpmh.dsk
	cpmcp -f 8mb cpmh.dsk t3x0agon/* 0:
	mv cpmh.dsk t3x0agon
	cp docs/README.agon t3x0agon/README
	zip -9 t3x0agon.zip t3x0agon/cpmh.dsk t3x0agon/README
	rm t3x0agon/* && rmdir t3x0agon

csums:
	txsum -u <_checksums >_checksums.new
	mv -f _checksums.new _checksums

mksums:	clean
	find . -type f | grep -v t3x0-$V.zip | grep -v _checksums \
		| txsum -m >_checksums

arc:	clean
	(cd ..; zip -9r t3x0-$V.zip t3x0)
	mv ../t3x0-$V.zip .

clean:	reset
	sh bin/modpath.sh reset
	rm -f -R tcvm.dSYM
	rm -f txtrn0 txtrn1.tc txtrn.tc \
		tx-tcvm.tc tx-tcvm.com tx-tcvm \
		tx-cpm.tc tx-cpm.com tx-cpm \
		tx-dos.tc tx-dos.com tx-dos \
		tx-dos.tc tx-cpm.tc \
		tx-fbsd-386.tc tx-fbsd-386 \
		tx-unix-386.tc tx-unix-386 \
		tx-unix-686.tc tx-unix-686 \
		tx-unix-armv6.tc tx-unix-armv6 \
		tx-unix-armv7.tc tx-unix-armv7 \
		tx-macos-686.tc tx-macos-686 \
		tx-raspi-1.tc tx-raspi-1 \
		cpmfile.tc dosfile.tc \
		tcvm test.tc *.core core t3x0-$V.zip \
		t3x0dos.zip t3x0cpm.zip t3x0agon.zip

