DIRNAME := $(shell basename $$PWD)
NASM := nasm009838 
#NASM := nasm
TEMP := /tmp
BOOTDISK := /tmp/cftest.cf
BOCHS ?= /usr/local/bin/bochs  # /usr/bin/bochs or /usr/local/bin/bochs
BXSHARE ?= $(shell dirname $(shell dirname $(BOCHS)))/share/bochs
BXRC ?= floppy.bxrc
LATEST_CF := ../af-35f-g144a12-PD
WORKING := $(LATEST_CF)/OkadWork.cf
BACKUP := $(LATEST_CF)/OkadBack.cf
VGA ?= std
BUILDOPTIONS ?= jcmods newboot
DEBUGLEVEL ?= 2
SERVERS := www tek
SOURCES := $(wildcard *.nasm) okadfull.dsm
CF2F ?= ./cf2f.py  # f2cf and cf2f are symlinks to same script
F2CF ?= ./f2cf.py
export
default: newboot.cf.boot
set:
	set
%: %.asm
	cias $< $@
	-wc -c $@
%.obj: %.nasm $(filter-out $<, $(SOURCES))
	nasm -f elf -o $@ $<
%: %.obj
	ld -o $@ $<
diff:
	$(MAKE) DIFFOPTIONS=--suppress-common-lines okadfull.diff
$(BOOTDISK): okadkern .FORCE
	cp $(BACKUP) $@
	dd if=$< of=$@ conv=notrunc
qemu:	$(BOOTDISK)  # check for bootworthiness
	qemu -m 32 -fda $< -serial stdio -vga $(VGA)
bochs: hda.bxrc /dev/sdb
	$(MAKE) BXRC=$< $(word 2, $+).bochs
%: %.nasm $(filter-out $<, $(SOURCES))
	@echo building $@ with BUILDOPTIONS="$(BUILDOPTIONS)"
	$(NASM) -l /tmp/$*.log $(addprefix -D,$(BUILDOPTIONS)) -o $@ $<
%.dsm: % %.cul
	cidis $+ > $@
%.dsm: %
	ndisasm $< > $@
%.dat: %.dsm
	if [ -f $@ ]; then \
	 read -p '^C to abort overwriting $@: ' confirmed; \
	fi
	awk '{print $$2}' $< | xxd -r -p > $@
%.dsm: %.dat
	ndisasm $< > $@
liloboot.dsm: liloboot.dat Makefile
	ndisasm -o 0x7c00 -s 0x7c24 $< > $@
usb: $(BOOTDISK)
	[ -e /dev/sdb ] && dd if=$< of=/dev/sdb || echo failed >&2
part: $(BOOTDISK)
	[ -e /dev/sdb1 ] && dd if=$< of=/dev/sdb1 || echo failed >&2
gdbboot: newboot  # check new kernel
	qemu -m 32 -fda $< -serial stdio -vga $(VGA) -s -S
qboot: newboot $(BOOTDISK) # check new kernel
	dd if=$< of=$(BOOTDISK) conv=notrunc
	qemu -m 32 -fda $(BOOTDISK) -serial stdio -vga $(VGA)
bboot: newboot $(BOOTDISK)
	dd if=$< of=$(BOOTDISK) conv=notrunc
	$(BOCHS) -qf $(BXRC)
clean:
	rm -f *.pyc
checkupload:
	$(MAKE) DRYRUN=--dry-run upload
upload: clean zip
	for server in $(SERVERS); do \
		rsync -avuz \
		 $(DRYRUN) \
		 --exclude='.bzr' \
		 --delete \
		 . $$server:/var/www/unternet.net/src/$(notdir $(PWD))/; \
	done
gdb: .gdbinit
	$@
.FORCE:
%.boot: %
	qemu -m 32 -fda $< -serial stdio -vga $(VGA)
%.key: %  # simulate boot from USB key
	# -drive file=$<,index=0,media=disk,cyls=247,heads=250,secs=32
	qemu -m 32 \
	 -drive file=$<,index=0,media=disk \
	 -serial stdio \
	 -vga $(VGA)
%.gdb: % %.gdbinit
	gdb -n -x $(word 2, $+) $<
%.gdb: %
	qemu -m 32 -fda $< -serial stdio -vga $(VGA) -s -S
%.kgb: %  # boot from key with gdb
	qemu -m 32 \
	 -drive file=$<,index=0,media=disk \
	 -serial stdio \
	 -vga $(VGA) \
	 -s -S
%.part: %  # load bootcode into partition 1 bootblock of USB key
	[ -e /dev/sdb1 ] && dd if=$< of=/dev/sdb1 || echo failed >&2
%.usb: %  # load bootcode into MBR of USB key
	[ -e /dev/sdb ] && dd if=$< of=/dev/sdb || echo failed >&2
%boot.diff: %.dsm %boot.dsm
	diff -y $(DIFFOPTIONS) $+
okad.dat: $(BACKUP)
	head -c 512 $< > $@
okad.dsm: okad.dat
	ndisasm -k 0x1b4,$$(printf 0x%x $$((0x200-0x1b4))) $< > $@
	ndisasm -k 0x00,0x1b4 -b 32 $< >> $@
okadfull.dsm: # $(BACKUP) # commented out so it does not rebuild
	head -c $$(printf %d 0x3000) $< | \
	 ndisasm -o 0x200200 -e 0x200 -b 32 - > $@
okadwork.dsm: $(BACKUP)
	ndisasm -o 0x200000 -b 32 $< > $@
okadfull.ref: $(BACKUP)
	head -c $$(printf %d 0x3000) $< | tail -c +513 > $@
okadboot.dsm: okadboot
	ndisasm -k 0x1b4,$$(printf 0x%x $$((0x200-0x1b4))) $< > $@
	ndisasm -k 0x00,0x1b4 -b 32 $< >> $@
okadboot.cf: okadboot
	cp -f $(BACKUP) $@
	dd if=$< of=$@ conv=notrunc
okadtest.cf: okadtest
	cp -f $(BACKUP) $@
	dd if=$< of=$@ conv=notrunc
okadtest.diff: okad.dsm okadtest.dsm
	diff -y $+
okadfull.nasm: okadfull.dsm Makefile
	@cut -c28- $< | sed -e '/^%ifdef undefined/,/^%endif/d' -e '/^$$/d' > $@
Okad2.nasm: Okad2.dsm Makefile
	@cut -c40- $< | sed -e '/^%ifdef undefined/,/^%endif/d' -e '/^$$/d' > $@
okadfull.dat: okadfull.nasm $(filter-out $<, $(SOURCES))
	@echo building $@ with BUILDOPTIONS="$(BUILDOPTIONS)"
	$(NASM) -l /tmp/okadfull.log -o $@ $(addprefix -D,$(BUILDOPTIONS)) $<
okadfull.dat.dsm: okadfull.dat Makefile  # for comparison with okadwork.dsm
	ndisasm -o 0x200000 -b 32 $< > $@
okadfull.cf: okadfull.dat okadboot
	cp $(BACKUP) $@
	dd if=$< of=$@ conv=notrunc
newboot.cf: okadfull.dat newboot
	cp $(BACKUP) $@
	dd if=$< of=$@ conv=notrunc
cf2010.cf: okadfull.dat /usr/src/cf2010/cf2010.blk
	cp $(word 2, $+) $@
	dd if=$< of=$@ conv=notrunc
okadfull.diff: okadkern.dsm okadfull.dat.dsm
	diff -y $(DIFFOPTIONS) $+
okadfull.cmp: $(BACKUP) okadfull.dat
	cmp -l $+
%.bochs: %
	BOOTDISK=$* $(BOCHS) -qf $(BXRC)
okadkern: $(BACKUP)
	dd if=$< of=$@ bs=1024 count=12
okadkern.dsm: okadkern Makefile
	ndisasm -o 0x200000 -b 32 $< > $@
cf2010.diff: okadkern.dsm cf2010kern.dsm
	diff -y $(DIFFOPTIONS) $+
cf2010kern.dsm: cf2010kern.blk
	ndisasm -o 0x200000 -b 32 $< > $@
cf2010kern.blk: /usr/src/cf2010/cf2010.blk
	dd if=$< of=$@ bs=1024 count=12
hda.img: ~/tmp/1gb.img
	ln -sf $< $@
~/tmp/1gb.img:
	dd if=/dev/zero of=$@ bs=512 count=2000000
oldboot:
	touch okad{boot,full}.nasm && \
	 $(MAKE) BUILDOPTIONS= okadfull.cf.boot
log:
	less /tmp/floppy.bxrc.txt
bochskey:
	[ -f /tmp/bochskey ] || dd if=/dev/sdb \
	 of=/tmp/bochskey bs=512 count=8000
	$(MAKE) BXRC=hda.bxrc /tmp/bochskey.bochs
/tmp/%.dat: /dev/%
	dd if=$< of=$@ bs=512 count=312
stick:
	$(MAKE) mbr.dat.usb
	@echo Now remove and reinsert USB stick
	@echo Wait for blue light to flash three times, then key \<ENTER\>
	@read continue
	$(MAKE) newboot.cf.part
%.block: $(WORKING) # extract block from OkadWork.cf
	dd if=$< of=$@ bs=1024 count=1 skip=$$(($*))
%.cf.rebuild:
	$(CF2F) $*.cf > /tmp/$(notdir $*).f 2>/tmp/$(notdir $*).log
	$(F2CF) /tmp/$(notdir $*).f > /tmp/$(notdir $*).cf \
	 2>>/tmp/$(notdir $*).log
	bindiff -y --suppress-common-lines $*.cf /tmp/$(notdir $*).cf
%.f.rebuild:
	$(F2CF) $*.f > /tmp/$(notdir $*).cf 2>/tmp/$(notdir $*).log
	$(CF2F) /tmp/$(notdir $*).cf > /tmp/$(notdir $*).f \
	 2>>/tmp/$(notdir $*).log
	diff $*.f /tmp/$(notdir $*).f
uncompressed.cf:
	dd if=/dev/sdb1 of=$@ bs=1024 count=1440
.FORCE:
%.f: %.cf .FORCE
	$(CF2F) $< > $@ 2>/tmp/$*.log
edit:
	vi cf2f.py cfword.py
%.both:  # update both uncompressed.cf and OkadWork.cf from an .f file
	DEBUGLEVEL=0 $(F2CF) $* uncompressed.cf
	DEBUGLEVEL=0 $(F2CF) $* $(WORKING)
winrun:
	cd latest && wine Okad2.exe &
Okad2.dsm: latest/Okad2.exe
	objdump \
	 --all-headers \
	 --disassemble-all \
	 $< > $@  # as code
	xxd $< >> $@  # as text
%.f.cf: %.f
	$(F2CF) $< > $@ 2>/tmp/$*.log
zip: $(DIRNAME).zip
$(DIRNAME).zip: .
	cd .. && zip -r $(DIRNAME)/$@ $(DIRNAME) \
	 -x $(DIRNAME)/$@ -x '*.bzr*' -x '*/latest/*'
%.respace: %
	# fix ndisasm output to be the same spacing as objdump --disassemble
	sed -i \
	 's/^\([0-9A-F]\{8\}  [0-9A-F]\{2,\}\)\(.*\)/\1            \2/' \
	 $<
