BUILD=./build

# Default rule
.PHONY: default
default: $(BUILD)/disk.img

# Remove all build files
.PHONY: clean
clean:
	rm -drf $(BUILD)
	cd tetros; cargo clean

#
# MARK: disk
#

# Compile tetros as a library
# (so that we can link it with a custom linker script)
LIB_SRC = ./tetros/Cargo.toml ./tetros/Cargo.lock $(shell find ./tetros/src -type f)
$(BUILD)/tetros.lib: $(LIB_SRC)
	@mkdir -p $(BUILD)
	cd tetros && \
		env RUSTFLAGS="-C soft-float" \
		cargo rustc \
			-Z build-std=core \
			-Z build-std-features=compiler-builtins-mem \
			--target "./targets/x86-unknown-none.json" \
			--lib \
			--release \
			-- \
			--emit link="$(CURDIR)/$@"

# Link tetros using custom linker script
BIOS_LD = ./tetros/linkers/x86-unknown-none.ld
$(BUILD)/tetros.elf: $(BUILD)/tetros.lib $(BIOS_LD)
	ld \
		-m elf_i386 \
		--gc-sections \
		-z max-page-size=0x1000 \
		-T "$(BIOS_LD)" \
		-o "$@" \
		"$<"

	objcopy --only-keep-debug "$@" "$@.sym"
	objcopy --strip-debug "$@"

# Wrap tetros in BIOS loader
# Parameters:
# - BIOS_SRC: source directory of bios assembly
# - STAGE2_SECTOR: the index of the first sector of the stage 2 binary on the disk
BIOS_SRC = ./bios
STAGE2_SECTOR = 1
$(BUILD)/disk.img: $(wildcard $(BIOS_SRC)/*.asm) $(BUILD)/tetros.elf 
	@mkdir -p "$(BUILD)"
	nasm \
		-f bin \
		-D STAGE3=$(BUILD)/tetros.elf \
		-D STAGE2_SECTOR=$(STAGE2_SECTOR) \
		-o "$@" \
		-l "$@.lst" \
		-i "$(BIOS_SRC)" \
		"$(BIOS_SRC)/main.asm"

#
# MARK: qemu
#
# Do not use `-enable-kvm` or `-cpu host`,
# this confuses gdb.
#

.PHONY: qemu
qemu: $(BUILD)/disk.img
	qemu-system-i386 \
		-d cpu_reset \
		-no-reboot \
		-smp 1 -m 2048 \
		-machine q35 \
		-net none \
		-serial stdio \
		-fda "$<"

# Same as qemu, but with no dependency.
# Used for remote dev, where build box != run box.
.PHONY: qemu-remote
qemu-remote:
	qemu-system-i386 \
		-d cpu_reset \
		-no-reboot \
		-smp 1 -m 2048 \
		-machine q35 \
		-net none \
		-serial stdio \
		-fda "$(BUILD)/disk.img"

# Same as qemu, but with gdb options
.PHONY: qemu-gdb
qemu-gdb: $(BUILD)/disk.img
	qemu-system-i386 \
		-d cpu_reset \
		-no-reboot \
		-smp 1 -m 2048 \
		-machine q35 \
		-net none \
		-serial stdio \
		-fda "$<" \
		-gdb tcp::26000 \
		-S