CROSS := i686-elf-
CC := $(CROSS)gcc
LD := $(CROSS)ld
QEMU := qemu-system-i386
MACHINE := pc-i440fx-7.2
BIOS := /usr/share/seabios/bios-256k.bin
QEMU_COMMON := -machine $(MACHINE) -accel tcg -cpu qemu32 -smp 1 -m 64M -bios $(BIOS) -boot order=c,strict=on -nic none -no-reboot
QEMU_FLAGS := $(QEMU_COMMON) -drive file=build/mbr.img,format=raw,if=ide
QEMU_BLANK_FLAGS := $(QEMU_COMMON) -drive file=build/blank.img,format=raw,if=ide
QEMU_BADSIG_FLAGS := $(QEMU_COMMON) -drive file=build/mbr-badsig.img,format=raw,if=ide
CFLAGS := -std=c11 -ffreestanding -O0 -g -Wall -Wextra -Werror -fno-pie -fno-stack-protector -fno-asynchronous-unwind-tables

.PHONY: build run debug screenshot check help
build: build/sample.elf build/blank.img build/mbr.img build/mbr-badsig.img

build/.dir:
	mkdir -p build
	touch $@

build/demo.o: sample/demo.c | build/.dir
	$(CC) $(CFLAGS) -c $< -o $@

build/entry.o: sample/entry.asm | build/.dir
	nasm -f elf32 -g -F dwarf $< -o $@

build/sample.elf: build/entry.o build/demo.o sample/linker.ld
	$(LD) -z noexecstack -T sample/linker.ld build/entry.o build/demo.o -o $@

build/mbr.bin: boot/mbr.asm | build/.dir
	nasm -f bin $< -o $@
	test "$$(wc -c < $@)" -eq 512

build/mbr.img: build/mbr.bin
	cp $< $@
	truncate -s 1048576 $@

build/mbr-badsig.img: build/mbr.img
	cp $< $@
	printf '\0\0' | dd of=$@ bs=1 seek=510 conv=notrunc status=none

build/blank.img: | build/.dir
	dd if=/dev/zero of=$@ bs=512 count=2048 status=none

run: build
	LC_ALL=C.UTF-8 $(QEMU) $(QEMU_FLAGS) -display curses -serial none

debug: build
	$(QEMU) $(QEMU_FLAGS) -display none -serial none -monitor none -S -gdb tcp:127.0.0.1:1234

screenshot: build
	{ sleep 2; printf 'screendump build/day02-screen.png -f png\nquit\n'; } | $(QEMU) $(QEMU_FLAGS) -display none -serial none -monitor stdio >/dev/null

check: build
	QEMU='$(QEMU)' QEMU_FLAGS='$(QEMU_FLAGS)' QEMU_BLANK_FLAGS='$(QEMU_BLANK_FLAGS)' QEMU_BADSIG_FLAGS='$(QEMU_BADSIG_FLAGS)' sh tools/check.sh

help:
	@printf '%s\n' 'make build: ELF32 sample, blank disk and day-02 boot disk' 'make run: boot day-02 MBR in curses display' 'make debug: CPU paused, GDB on container loopback port 1234' 'make screenshot: save build/day02-screen.png with QEMU monitor' 'make check: ELF, missing-symbol, boot-sector and QEMU/GDB checks'
