From 8ef390ae9c747d7f27fcc98daf17a7d6ad76e549 Mon Sep 17 00:00:00 2001 From: David Given Date: Thu, 14 Dec 2023 00:10:20 +0100 Subject: [PATCH 01/23] Initial boilerplate of ab build. --- Makefile | 413 +---------------------------- build.py | 3 + build/_objectify.py | 19 ++ build/ab.mk | 42 +++ build/ab.py | 487 +++++++++++++++++++++++++++++++++++ build/c.py | 265 +++++++++++++++++++ build/pkg.py | 38 +++ build/protobuf.py | 65 +++++ build/utils.py | 43 ++++ third_party/lib6502/build.py | 10 + tools/cpmemu/biosbdos.c | 1 - tools/cpmemu/build.py | 10 + tools/cpmemu/fileio.c | 2 - 13 files changed, 987 insertions(+), 411 deletions(-) create mode 100644 build.py create mode 100644 build/_objectify.py create mode 100644 build/ab.mk create mode 100644 build/ab.py create mode 100644 build/c.py create mode 100644 build/pkg.py create mode 100644 build/protobuf.py create mode 100644 build/utils.py create mode 100644 third_party/lib6502/build.py create mode 100644 tools/cpmemu/build.py diff --git a/Makefile b/Makefile index 25924e58..25bfb2f2 100644 --- a/Makefile +++ b/Makefile @@ -1,409 +1,6 @@ -CXX = g++ -CC = gcc -FPC = fpc -LLVM ?= /opt/bin/ - -CFLAGS = -O0 -g -I. -CXXFLAGS = $(CFLAGS) \ - -std=c++17 -CFLAGS65 = -Os -g -I. \ - -Wno-main-return-type \ - -Wno-incompatible-library-redeclaration - -OBJDIR = .obj - -TARGETS = \ - apple2e.po \ - atari800.atr \ - atari800hd.atr \ - atari800xlhd.atr \ - bbcmicro.ssd \ - c64.d64 \ - oric.dsk \ - pet4032.d64 \ - pet8032.d64 \ - pet8096.d64 \ - vic20.d64 \ - x16.zip \ - -MINIMAL_APPS = \ - $(OBJDIR)/apps/bedit.com \ - $(OBJDIR)/apps/capsdrv.com \ - $(OBJDIR)/apps/cpuinfo.com \ - $(OBJDIR)/apps/devices.com \ - $(OBJDIR)/apps/dinfo.com \ - $(OBJDIR)/apps/dump.com \ - $(OBJDIR)/apps/ls.com \ - $(OBJDIR)/asm.com \ - $(OBJDIR)/copy.com \ - $(OBJDIR)/stat.com \ - $(OBJDIR)/submit.com \ - apps/dump.asm \ - apps/ls.asm \ - apps/cpm65.inc \ - apps/drivers.inc \ - -APPS = \ - $(MINIMAL_APPS) \ - $(OBJDIR)/third_party/altirrabasic/atbasic.com \ - $(OBJDIR)/objdump.com \ - apps/bedit.asm \ - apps/cpuinfo.asm \ - apps/dinfo.asm \ - cpmfs/asm.txt \ - cpmfs/basic.txt \ - cpmfs/bedit.txt \ - cpmfs/demo.sub \ - cpmfs/hello.asm \ - -SCREEN_APPS = \ - $(OBJDIR)/apps/cls.com \ - apps/cls.asm \ - $(OBJDIR)/qe.com \ - $(OBJDIR)/life.com \ - -LIBCPM_OBJS = \ - $(OBJDIR)/lib/printi.o \ - $(OBJDIR)/lib/bdos.o \ - $(OBJDIR)/lib/xfcb.o \ - $(OBJDIR)/lib/screen.o \ - -LIBBIOS_OBJS = \ - $(OBJDIR)/src/bios/biosentry.o \ - $(OBJDIR)/src/bios/relocate.o \ - $(OBJDIR)/src/bios/loader.o \ - -LIBCOMMODORE_OBJS = \ - $(OBJDIR)/src/bios/commodore/ieee488.o \ - $(OBJDIR)/src/bios/commodore/petscii.o \ - -CPMEMU_OBJS = \ - $(OBJDIR)/tools/cpmemu/main.o \ - $(OBJDIR)/tools/cpmemu/emulator.o \ - $(OBJDIR)/tools/cpmemu/fileio.o \ - $(OBJDIR)/tools/cpmemu/biosbdos.o \ - $(OBJDIR)/third_party/lib6502/lib6502.o \ - -all: $(TARGETS) - -$(OBJDIR)/%: $(OBJDIR)/tools/%.o - @mkdir -p $(dir $@) - $(CXX) $(CXXFLAGS) -o $@ $< -lfmt - -bin/cpmemu: $(CPMEMU_OBJS) - @mkdir -p $(dir $@) - $(CC) $(CFLAGS) -o $@ $(CPMEMU_OBJS) -lreadline - -bin/%: $(OBJDIR)/tools/%.o - @mkdir -p $(dir $@) - $(CXX) $(CXXFLAGS) -o $@ $< - -bin/fontconvert: $(OBJDIR)/tools/fontconvert.o $(OBJDIR)/tools/libbdf.o - @mkdir -p $(dir $@) - $(CC) $(CFLAGS) -o $@ $^ - -bin/mads: third_party/mads/mads.pas - @mkdir -p $(dir $@) - $(FPC) -Mdelphi -vh -Os $< -o$@ - -$(OBJDIR)/mkcombifs: $(OBJDIR)/tools/mkcombifs.o - @mkdir -p $(dir $@) - $(CXX) $(CXXFLAGS) -o $@ $^ -lfmt - -$(OBJDIR)/third_party/%.o: third_party/%.c - @mkdir -p $(dir $@) - $(CC) $(CFLAGS) -c -o $@ $< - -$(OBJDIR)/third_party/%.o: third_party/%.cc - @mkdir -p $(dir $@) - $(CXX) $(CXXFLAGS) -c -o $@ $< - -$(OBJDIR)/tools/%.o: tools/%.c - @mkdir -p $(dir $@) - $(CC) $(CFLAGS) -c -o $@ $< - -$(OBJDIR)/tools/%.o: tools/%.cc - @mkdir -p $(dir $@) - $(CXX) $(CXXFLAGS) -c -o $@ $< - -$(OBJDIR)/%.o: %.S include/zif.inc include/mos.inc include/cpm65.inc include/driver.inc - @mkdir -p $(dir $@) - $(LLVM)mos-cpm65-clang $(CFLAGS65) -c -o $@ $< -I include - -$(OBJDIR)/third_party/altirrabasic/%.bin: \ - $(wildcard third_party/altirrabasic/source/*.s) \ - $(wildcard third_party/altirrabasic/source/*.inc) \ - $(wildcard third_party/altirrabasic/kernel/*.s) \ - bin/mads \ - $(OBJDIR)/xextobin - @mkdir -p $(dir $@) - rm -f $(patsubst %.bin,%.xex,$@) - bin/mads third_party/altirrabasic/source/atbasic.s \ - -c \ - -o:$(patsubst %.bin,%.xex,$@) \ - -s \ - -l:$(patsubst %.bin,%.lst,$@) \ - -t:$(patsubst %.bin,%.map,$@) \ - -d:ZPBASE=$(ZPBASE) \ - -d:TEXTBASE='$$$(TEXTBASE)' - $(OBJDIR)/xextobin -i $(patsubst %.bin,%.xex,$@) -o $@ -b 0x$(TEXTBASE) - -$(OBJDIR)/third_party/altirrabasic/atbasic.core.bin: ZPBASE=0 -$(OBJDIR)/third_party/altirrabasic/atbasic.core.bin: TEXTBASE=0200 -$(OBJDIR)/third_party/altirrabasic/atbasic.zp.bin: ZPBASE=1 -$(OBJDIR)/third_party/altirrabasic/atbasic.zp.bin: TEXTBASE=0200 -$(OBJDIR)/third_party/altirrabasic/atbasic.tpa.bin: ZPBASE=0 -$(OBJDIR)/third_party/altirrabasic/atbasic.tpa.bin: TEXTBASE=0300 - -$(OBJDIR)/third_party/altirrabasic/atbasic.com: \ - $(OBJDIR)/third_party/altirrabasic/atbasic.core.bin \ - $(OBJDIR)/third_party/altirrabasic/atbasic.zp.bin \ - $(OBJDIR)/third_party/altirrabasic/atbasic.tpa.bin \ - $(OBJDIR)/multilink - @mkdir -p $(dir $@) - $(OBJDIR)/multilink -o $@ \ - $(OBJDIR)/third_party/altirrabasic/atbasic.core.bin \ - $(OBJDIR)/third_party/altirrabasic/atbasic.zp.bin \ - $(OBJDIR)/third_party/altirrabasic/atbasic.tpa.bin - -$(OBJDIR)/libcommodore.a: $(LIBCOMMODORE_OBJS) - @mkdir -p $(dir $@) - $(LLVM)llvm-ar rs $@ $^ - -$(OBJDIR)/libbios.a: $(LIBBIOS_OBJS) - @mkdir -p $(dir $@) - $(LLVM)llvm-ar rs $@ $^ - -$(OBJDIR)/libcpm.a: $(LIBCPM_OBJS) - @mkdir -p $(dir $@) - $(LLVM)llvm-ar rs $@ $^ - -$(OBJDIR)/%.o: %.c - @mkdir -p $(dir $@) - $(LLVM)mos-cpm65-clang $(CFLAGS65) -c -I. -o $@ $^ - -$(OBJDIR)/%.com: $(OBJDIR)/third_party/%.o $(OBJDIR)/libcpm.a - @mkdir -p $(dir $@) - $(LLVM)mos-cpm65-clang $(CFLAGS65) -I. -o $@ $^ - -$(OBJDIR)/%.com: $(OBJDIR)/apps/%.o $(OBJDIR)/libcpm.a - @mkdir -p $(dir $@) - $(LLVM)mos-cpm65-clang $(CFLAGS65) -v -I. -o $@ $^ - -$(OBJDIR)/%.com: %.asm $(OBJDIR)/asm.com bin/cpmemu $(wildcard apps/*.inc) - @mkdir -p $(dir $@) - bin/cpmemu $(OBJDIR)/asm.com -pA=$(dir $<) -pB=$(dir $@) \ - a:$(notdir $<) b:$(notdir $@) - test -f $@ - -$(OBJDIR)/bdos.sys: $(OBJDIR)/src/bdos.o $(OBJDIR)/libcpm.a - @mkdir -p $(dir $@) - $(LLVM)mos-cpm65-clang $(CFLAGS65) -I. -o $@ $^ - $(LLVM)llvm-objdump -S $@.elf > $@.lst - -$(OBJDIR)/ccp.sys: $(OBJDIR)/src/ccp.o $(OBJDIR)/libcpm.a - @mkdir -p $(dir $@) - $(LLVM)mos-cpm65-clang $(CFLAGS65) -I. -o $@ $^ - -$(OBJDIR)/apple2e.bios: $(OBJDIR)/src/bios/apple2e.o $(OBJDIR)/libbios.a scripts/apple2e.ld scripts/apple2e-prelink.ld Makefile - @mkdir -p $(dir $@) - $(LLVM)ld.lld -T scripts/apple2e-prelink.ld -o $(OBJDIR)/apple2e.o $< $(OBJDIR)/libbios.a --defsym=BIOS_SIZE=0x8000 - $(LLVM)ld.lld -Map $(patsubst %.bios,%.map,$@) -T scripts/apple2e.ld -o $@ $< $(OBJDIR)/libbios.a --defsym=BIOS_SIZE=$$($(LLVM)llvm-objdump --section-headers $(OBJDIR)/apple2e.o | gawk --non-decimal-data '/ [0-9]+/ { size[$$2] = ("0x"$$3)+0 } END { print(size[".text"] + size[".data"] + size[".bss"]) }') - -$(OBJDIR)/oric.exe: $(OBJDIR)/src/bios/oric.o $(OBJDIR)/libbios.a scripts/oric.ld scripts/oric-prelink.ld scripts/oric-common.ld Makefile - @mkdir -p $(dir $@) - $(LLVM)ld.lld -Map $(patsubst %.exe,%.map,$@) -T scripts/oric-prelink.ld -o $(OBJDIR)/oric-prelink.o $< $(OBJDIR)/libbios.a --defsym=BIOS_SIZE=0x4000 - $(LLVM)ld.lld -Map $(patsubst %.exe,%.map,$@) -T scripts/oric.ld -o $@ $< $(OBJDIR)/libbios.a --defsym=BIOS_SIZE=$$($(LLVM)llvm-objdump --section-headers $(OBJDIR)/oric-prelink.o | gawk --non-decimal-data '/ [0-9]+/ { size[$$2] = ("0x"$$3)+0 } END { print(size[".text"] + size[".data"] + size[".bss"]) }') - -$(OBJDIR)/%.exe: $(OBJDIR)/src/bios/%.o $(OBJDIR)/libbios.a scripts/%.ld - @mkdir -p $(dir $@) - $(LLVM)ld.lld -Map $(patsubst %.exe,%.map,$@) -T scripts/$*.ld -o $@ $< $(filter %.a,$^) $(LINKFLAGS) - -$(OBJDIR)/4x8font.inc: bin/fontconvert third_party/tomsfonts/atari-small.bdf - @mkdir -p $(dir $@) - bin/fontconvert third_party/tomsfonts/atari-small.bdf > $@ - -$(OBJDIR)/bbcmicrofs.img: $(APPS) $(SCREEN_APPS) $(OBJDIR)/ccp.sys - mkfs.cpm -f bbc192 $@ - cpmcp -f bbc192 $@ $(OBJDIR)/ccp.sys $(APPS) $(SCREEN_APPS) 0: - cpmchattr -f bbc192 $@ sr 0:ccp.sys - -bbcmicro.ssd: $(OBJDIR)/bbcmicro.exe $(OBJDIR)/bdos.sys Makefile $(OBJDIR)/bbcmicrofs.img $(OBJDIR)/mkdfs - $(OBJDIR)/mkdfs -O $@ \ - -N CP/M-65 \ - -f $(OBJDIR)/bbcmicro.exe -n \!boot -l 0x400 -e 0x400 -B 2 \ - -f $(OBJDIR)/bdos.sys -n bdos \ - -f $(OBJDIR)/bbcmicrofs.img -n cpmfs - -$(OBJDIR)/c64.exe: $(OBJDIR)/libcommodore.a -c64.d64: $(OBJDIR)/c64.exe $(OBJDIR)/bdos.sys Makefile $(APPS) $(OBJDIR)/ccp.sys \ - $(OBJDIR)/mkcombifs - @rm -f $@ - cc1541 -q -n "cp/m-65" $@ - cc1541 -q \ - -t -u 0 \ - -r 18 -f cpm -w $(OBJDIR)/c64.exe \ - $@ - $(OBJDIR)/mkcombifs $@ - cpmcp -f c1541 $@ $(OBJDIR)/bdos.sys $(OBJDIR)/ccp.sys $(APPS) 0: - cpmchattr -f c1541 $@ sr 0:bdos.sys 0:ccp.sys 0:cbmfs.sys - -$(OBJDIR)/generic-1m-cpmfs.img: $(OBJDIR)/bdos.sys $(APPS) $(OBJDIR)/ccp.sys - @rm -f $@ - mkfs.cpm -f generic-1m $@ - cpmcp -f generic-1m $@ $(OBJDIR)/ccp.sys $(APPS) 0: - cpmchattr -f generic-1m $@ sr 0:ccp.sys - -$(OBJDIR)/x16.exe: $(OBJDIR)/libcommodore.a -x16.zip: $(OBJDIR)/x16.exe $(OBJDIR)/bdos.sys $(OBJDIR)/generic-1m-cpmfs.img - @rm -f $@ - zip -9 $@ -j $^ - printf "@ x16.exe\n@=CPM\n" | zipnote -w $@ - printf "@ bdos.sys\n@=BDOS\n" | zipnote -w $@ - printf "@ generic-1m-cpmfs.img\n@=CPMFS\n" | zipnote -w $@ - -$(OBJDIR)/apple2e.bios.swapped: $(OBJDIR)/apple2e.bios bin/shuffle - bin/shuffle -i $< -o $@ -b 256 -t 16 -r -m 02468ace13579bdf - -$(OBJDIR)/apple2e.boottracks: $(OBJDIR)/apple2e.bios.swapped - cp $(OBJDIR)/apple2e.bios.swapped $@ - truncate -s 4096 $@ - -apple2e.po: $(OBJDIR)/apple2e.boottracks $(OBJDIR)/bdos.sys $(APPS) $(OBJDIR)/ccp.sys Makefile diskdefs bin/shuffle - @rm -f $@ - mkfs.cpm -f appleiie -b $(OBJDIR)/apple2e.boottracks $@ - cpmcp -f appleiie $@ $(OBJDIR)/bdos.sys $(OBJDIR)/ccp.sys $(APPS) 0: - cpmchattr -f appleiie $@ sr 0:ccp.sys 0:bdos.sys - truncate -s 143360 $@ - -$(OBJDIR)/pet4032.exe: LINKFLAGS += --no-check-sections -$(OBJDIR)/pet4032.exe: $(OBJDIR)/libcommodore.a -$(OBJDIR)/src/bios/pet4032.o: CFLAGS65 += -DPET4032 -pet4032.d64: $(OBJDIR)/pet4032.exe $(OBJDIR)/bdos.sys Makefile $(APPS) $(SCREEN_APPS) $(OBJDIR)/ccp.sys \ - $(OBJDIR)/mkcombifs - @rm -f $@ - cc1541 -i 15 -q -n "cp/m-65" $@ - cc1541 -q \ - -t -u 0 \ - -r 18 -f cpm -w $(OBJDIR)/pet4032.exe \ - $@ - $(OBJDIR)/mkcombifs $@ - cpmcp -f c1541 $@ $(OBJDIR)/bdos.sys $(OBJDIR)/ccp.sys $(APPS) $(SCREEN_APPS) 0: - cpmchattr -f c1541 $@ sr 0:ccp.sys 0:cbmfs.sys 0:bdos.sys - -$(OBJDIR)/pet8096.exe: LINKFLAGS += --no-check-sections -$(OBJDIR)/pet8096.exe: $(OBJDIR)/libcommodore.a -$(OBJDIR)/src/bios/pet8096.o: CFLAGS65 += -DPET8096 -pet8096.d64: $(OBJDIR)/pet8096.exe $(OBJDIR)/bdos.sys Makefile $(APPS) $(SCREEN_APPS) $(OBJDIR)/ccp.sys \ - $(OBJDIR)/mkcombifs - @rm -f $@ - cc1541 -i 15 -q -n "cp/m-65" $@ - cc1541 -q \ - -t -u 0 \ - -r 18 -f cpm -w $(OBJDIR)/pet8096.exe \ - $@ - $(OBJDIR)/mkcombifs $@ - cpmcp -f c1541 $@ $(OBJDIR)/bdos.sys $(OBJDIR)/ccp.sys $(APPS) $(SCREEN_APPS) 0: - cpmchattr -f c1541 $@ sr 0:ccp.sys 0:cbmfs.sys 0:bdos.sys - -$(OBJDIR)/pet8032.exe: LINKFLAGS += --no-check-sections -$(OBJDIR)/pet8032.exe: $(OBJDIR)/libcommodore.a -$(OBJDIR)/src/bios/pet8032.o: CFLAGS65 += -DPET8032 -pet8032.d64: $(OBJDIR)/pet8032.exe $(OBJDIR)/bdos.sys Makefile $(APPS) $(SCREEN_APPS) $(OBJDIR)/ccp.sys \ - $(OBJDIR)/mkcombifs - @rm -f $@ - cc1541 -i 15 -q -n "cp/m-65" $@ - cc1541 -q \ - -t -u 0 \ - -r 18 -f cpm -w $(OBJDIR)/pet8032.exe \ - $@ - $(OBJDIR)/mkcombifs $@ - cpmcp -f c1541 $@ $(OBJDIR)/bdos.sys $(OBJDIR)/ccp.sys $(APPS) $(SCREEN_APPS) 0: - cpmchattr -f c1541 $@ sr 0:ccp.sys 0:cbmfs.sys 0:bdos.sys - -$(OBJDIR)/vic20.exe: LINKFLAGS += --no-check-sections -$(OBJDIR)/vic20.exe: $(OBJDIR)/libcommodore.a -$(OBJDIR)/src/bios/vic20.o: $(OBJDIR)/4x8font.inc -vic20.d64: $(OBJDIR)/vic20.exe $(OBJDIR)/bdos.sys Makefile $(APPS) \ - $(OBJDIR)/ccp.sys $(OBJDIR)/mkcombifs - @rm -f $@ - cc1541 -i 15 -q -n "cp/m-65" $@ - cc1541 -q \ - -t -u 0 \ - -r 18 -f cpm -w $(OBJDIR)/vic20.exe \ - $@ - $(OBJDIR)/mkcombifs $@ - cpmcp -f c1541 $@ $(OBJDIR)/bdos.sys $(OBJDIR)/ccp.sys $(APPS) 0: - cpmchattr -f c1541 $@ sr 0:cbmfs.sys 0:ccp.sys 0:bdos.sys - -# Atari targets call /usr/bin/printf directly because 'make' calls /bin/sh -# which might be the Defective Annoying SHell which has a broken printf -# implementation. - -$(OBJDIR)/src/bios/atari800.o: CFLAGS65 += -DATARI_SD -$(OBJDIR)/atari800.exe: -atari800.atr: $(OBJDIR)/atari800.exe $(OBJDIR)/bdos.sys Makefile \ - $(MINIMAL_APPS) $(OBJDIR)/ccp.sys $(OBJDIR)/a8setfnt.com \ - $(SCREEN_APPS) $(OBJDIR)/a8tty80drv.com - dd if=/dev/zero of=$@ bs=128 count=720 - mkfs.cpm -f atari90 $@ - cp $(OBJDIR)/a8setfnt.com $(OBJDIR)/setfnt.com - cp $(OBJDIR)/a8tty80drv.com $(OBJDIR)/tty80drv.com - cpmcp -f atari90 $@ $(OBJDIR)/bdos.sys $(OBJDIR)/ccp.sys $(MINIMAL_APPS) $(SCREEN_APPS) 0: - cpmcp -f atari90 $@ $(OBJDIR)/apps/ls.com $(OBJDIR)/setfnt.com $(OBJDIR)/tty80drv.com third_party/fonts/atari/olivetti.fnt 1: - cpmchattr -f atari90 $@ sr 0:ccp.sys o:bdos.sys - dd if=$(OBJDIR)/atari800.exe of=$@ bs=128 conv=notrunc - mv $@ $@.raw - /usr/bin/printf '\x96\x02\x80\x16\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' > $@ - cat $@.raw >> $@ - rm $@.raw - -$(OBJDIR)/src/bios/atari800hd.o: CFLAGS65 += -DATARI_HD -$(OBJDIR)/atari800hd.exe: -atari800hd.atr: $(OBJDIR)/atari800hd.exe $(OBJDIR)/bdos.sys Makefile \ - $(APPS) $(OBJDIR)/ccp.sys $(OBJDIR)/a8setfnt.com \ - $(SCREEN_APPS) $(OBJDIR)/a8tty80drv.com - dd if=/dev/zero of=$@ bs=128 count=8190 - mkfs.cpm -f atarihd $@ - cp $(OBJDIR)/a8setfnt.com $(OBJDIR)/setfnt.com - cp $(OBJDIR)/a8tty80drv.com $(OBJDIR)/tty80drv.com - cpmcp -f atarihd $@ $(OBJDIR)/bdos.sys $(OBJDIR)/ccp.sys $(APPS) $(SCREEN_APPS) 0: - cpmcp -f atarihd $@ $(OBJDIR)/apps/ls.com $(OBJDIR)/setfnt.com $(OBJDIR)/tty80drv.com third_party/fonts/atari/*.fnt 1: - cpmchattr -f atarihd $@ sr 0:ccp.sys 0:bdos.sys - dd if=$(OBJDIR)/atari800hd.exe of=$@ bs=128 conv=notrunc - mv $@ $@.raw - /usr/bin/printf '\x96\x02\xf0\xff\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' > $@ - cat $@.raw >> $@ - rm $@.raw - -$(OBJDIR)/src/bios/atari800xlhd.o: CFLAGS65 += -DATARI_HD -DATARI_XL -$(OBJDIR)/atari800xlhd.exe: -atari800xlhd.atr: $(OBJDIR)/atari800xlhd.exe $(OBJDIR)/bdos.sys Makefile \ - $(APPS) $(OBJDIR)/ccp.sys $(OBJDIR)/a8setfnt.com \ - $(SCREEN_APPS) $(OBJDIR)/a8tty80drv.com - dd if=/dev/zero of=$@ bs=128 count=8190 - mkfs.cpm -f atarihd $@ - cp $(OBJDIR)/a8setfnt.com $(OBJDIR)/setfnt.com - cp $(OBJDIR)/a8tty80drv.com $(OBJDIR)/tty80drv.com - cpmcp -f atarihd $@ $(OBJDIR)/bdos.sys $(OBJDIR)/ccp.sys $(APPS) $(SCREEN_APPS) 0: - cpmcp -f atarihd $@ $(OBJDIR)/apps/ls.com $(OBJDIR)/setfnt.com $(OBJDIR)/tty80drv.com third_party/fonts/atari/*.fnt 1: - cpmchattr -f atarihd $@ sr 0:ccp.sys 0:bdos.sys - dd if=$(OBJDIR)/atari800xlhd.exe of=$@ bs=128 conv=notrunc - mv $@ $@.raw - /usr/bin/printf '\x96\x02\xf0\xff\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' > $@ - cat $@.raw >> $@ - rm $@.raw - -oric.dsk: $(OBJDIR)/oric.exe $(OBJDIR)/bdos.sys Makefile \ - $(APPS) $(SCREEN_APPS) $(OBJDIR)/ccp.sys $(OBJDIR)/mkoricdsk - mkfs.cpm -f oric -b $(OBJDIR)/oric.exe $(OBJDIR)/oric.img - cpmcp -f oric $(OBJDIR)/oric.img $(OBJDIR)/bdos.sys $(OBJDIR)/ccp.sys $(APPS) $(SCREEN_APPS) 0: - cpmchattr -f oric $(OBJDIR)/oric.img sr 0:ccp.sys 0:bdos.sys - $(OBJDIR)/mkoricdsk -i $(OBJDIR)/oric.img -o $@ - -clean: - rm -rf $(OBJDIR) bin $(TARGETS) - -.DELETE_ON_ERROR: -.SECONDARY: +export OBJ = .obj +.PHONY: all +all: +all + +include build/ab.mk diff --git a/build.py b/build.py new file mode 100644 index 00000000..afa85e1a --- /dev/null +++ b/build.py @@ -0,0 +1,3 @@ +from build.ab import export + +export(name="all", items={"bin/cpmemu": "tools/cpmemu"}) diff --git a/build/_objectify.py b/build/_objectify.py new file mode 100644 index 00000000..17148954 --- /dev/null +++ b/build/_objectify.py @@ -0,0 +1,19 @@ +import sys +from functools import partial + +if len(sys.argv) != 3: + sys.exit("Usage: %s " % sys.argv[0]) +filename = sys.argv[1] +symbol = sys.argv[2] + +print("const uint8_t " + symbol + "[] = {") +n = 0 +with open(filename, "rb") as in_file: + for c in iter(partial(in_file.read, 1), b""): + print("0x%02X," % ord(c), end="") + n += 1 + if n % 16 == 0: + print() +print("};") + +print("const size_t " + symbol + "_len = sizeof(" + symbol + ");") diff --git a/build/ab.mk b/build/ab.mk new file mode 100644 index 00000000..27d4bcf4 --- /dev/null +++ b/build/ab.mk @@ -0,0 +1,42 @@ +ifeq ($(findstring 4.,$(MAKE_VERSION)),) +$(error You need GNU Make 4.x for this (if you're on OSX, use gmake).) +endif + +OBJ ?= .obj +PYTHON ?= python3 +CC ?= gcc +CXX ?= g++ +AR ?= ar +CFLAGS ?= -g -Og +LDFLAGS ?= -g +hide = @ +PKG_CONFIG ?= pkg-config +ECHO ?= echo + +ifeq ($(OS), Windows_NT) + EXT ?= .exe +endif +EXT ?= + +include $(OBJ)/build.mk + +.PHONY: update-ab +update-ab: + @echo "Press RETURN to update ab from the repository, or CTRL+C to cancel." \ + && read a \ + && (curl -L https://github.com/davidgiven/ab/releases/download/dev/distribution.tar.xz | tar xvJf -) \ + && echo "Done." + +.PHONY: clean +clean:: + @echo CLEAN + $(hide) rm -rf $(OBJ) bin + +export PYTHONHASHSEED = 1 +build-files = $(shell find . -name 'build.py') $(wildcard build/*.py) $(wildcard config.py) +$(OBJ)/build.mk: Makefile $(build-files) + @echo "AB" + @mkdir -p $(OBJ) + $(hide) $(PYTHON) -X pycache_prefix=$(OBJ) build/ab.py -t +all -o $@ \ + build.py || rm -f $@ + diff --git a/build/ab.py b/build/ab.py new file mode 100644 index 00000000..d5393867 --- /dev/null +++ b/build/ab.py @@ -0,0 +1,487 @@ +from collections.abc import Iterable, Sequence +from os.path import * +from types import SimpleNamespace +import argparse +import copy +import functools +import importlib +import importlib.abc +import importlib.util +import inspect +import re +import sys +import types +import pathlib +import builtins +import os + +defaultGlobals = {} +targets = {} +unmaterialisedTargets = set() +materialisingStack = [] +outputFp = None +cwdStack = [""] + +sys.path += ["."] +old_import = builtins.__import__ + + +def new_import(name, *args, **kwargs): + if name not in sys.modules: + path = name.replace(".", "/") + ".py" + if isfile(path): + sys.stderr.write(f"loading {path}\n") + loader = importlib.machinery.SourceFileLoader(name, path) + + spec = importlib.util.spec_from_loader( + name, loader, origin="built-in" + ) + module = importlib.util.module_from_spec(spec) + sys.modules[name] = module + cwdStack.append(dirname(path)) + spec.loader.exec_module(module) + cwdStack.pop() + + return old_import(name, *args, **kwargs) + + +builtins.__import__ = new_import + + +class ABException(BaseException): + pass + + +class ParameterList(Sequence): + def __init__(self, parent=[]): + self.data = parent + + def __getitem__(self, i): + return self.data[i] + + def __len__(self): + return len(self.data) + + def __str__(self): + return " ".join(self.data) + + def __add__(self, other): + newdata = self.data.copy() + other + return ParameterList(newdata) + + def __repr__(self): + return f"" + + +class Invocation: + name = None + callback = None + types = None + ins = None + outs = None + binding = None + + def materialise(self, replacing=False): + if self in unmaterialisedTargets: + if not replacing and (self in materialisingStack): + print("Found dependency cycle:") + for i in materialisingStack: + print(f" {i.name}") + print(f" {self.name}") + sys.exit(1) + + materialisingStack.append(self) + + # Perform type conversion to the declared rule parameter types. + + try: + self.args = {} + for k, v in self.binding.arguments.items(): + if k != "kwargs": + t = self.types.get(k, None) + if t: + v = t(v).convert(self) + self.args[k] = v + else: + for kk, vv in v.items(): + t = self.types.get(kk, None) + if t: + vv = t(vv).convert(self) + self.args[kk] = vv + + # Actually call the callback. + + cwdStack.append(self.cwd) + self.callback(**self.args) + cwdStack.pop() + except BaseException as e: + print( + f"Error materialising {self} ({id(self)}): {self.callback}" + ) + print(f"Arguments: {self.args}") + raise e + + if self.outs is None: + raise ABException(f"{self.name} didn't set self.outs") + + if self in unmaterialisedTargets: + unmaterialisedTargets.remove(self) + + materialisingStack.pop() + + def __repr__(self): + return "" % self.name + + +def Rule(func): + sig = inspect.signature(func) + + @functools.wraps(func) + def wrapper(*, name=None, replaces=None, **kwargs): + cwd = None + if name: + if ("+" in name) and not name.startswith("+"): + (cwd, _) = name.split("+", 1) + if not cwd: + cwd = cwdStack[-1] + + if name: + i = Invocation() + if name.startswith("./"): + name = join(cwd, name) + elif "+" not in name: + name = cwd + "+" + name + + i.name = name + i.localname = name.split("+")[-1] + + if name in targets: + raise ABException(f"target {i.name} has already been defined") + targets[name] = i + elif replaces: + i = replaces + name = i.name + else: + raise ABException("you must supply either name or replaces") + + i.cwd = cwd + i.types = func.__annotations__ + i.callback = func + setattr(i, func.__name__, SimpleNamespace()) + + i.binding = sig.bind(name=name, self=i, **kwargs) + i.binding.apply_defaults() + + unmaterialisedTargets.add(i) + if replaces: + i.materialise(replacing=True) + return i + + defaultGlobals[func.__name__] = wrapper + return wrapper + + +class Type: + def __init__(self, value): + self.value = value + + +class Targets(Type): + def convert(self, invocation): + value = self.value + if type(value) is str: + value = [value] + if type(value) is list: + value = targetsof(value, cwd=invocation.cwd) + return value + + +class Target(Type): + def convert(self, invocation): + value = self.value + if not value: + return None + return targetof(value, cwd=invocation.cwd) + + +class TargetsMap(Type): + def convert(self, invocation): + value = self.value + if type(value) is dict: + return { + k: targetof(v, cwd=invocation.cwd) for k, v in value.items() + } + raise ABException(f"wanted a dict of targets, got a {type(value)}") + + +def flatten(*xs): + def recurse(xs): + for x in xs: + if isinstance(x, Iterable) and not isinstance(x, (str, bytes)): + yield from recurse(x) + else: + yield x + + return list(recurse(xs)) + + +def fileinvocation(s): + i = Invocation() + i.name = s + i.outs = [s] + targets[s] = i + return i + + +def targetof(s, cwd): + if isinstance(s, Invocation): + s.materialise() + return s + + if s in targets: + t = targets[s] + t.materialise() + return t + + if s.startswith(".+"): + s = cwd + s[1:] + elif s.startswith("./"): + s = normpath(join(cwd, s)) + elif s.endswith("/"): + return fileinvocation(s) + elif s.startswith("$"): + return fileinvocation(s) + + if "+" not in s: + if isdir(s): + s = s + "+" + basename(s) + else: + return fileinvocation(s) + + (path, target) = s.split("+", 2) + loadbuildfile(join(path, "build.py")) + if not s in targets: + raise ABException(f"build file at {path} doesn't contain +{target}") + i = targets[s] + i.materialise() + return i + + +def targetsof(*xs, cwd): + return flatten([targetof(x, cwd) for x in flatten(xs)]) + + +def filenamesof(*xs): + s = [] + for t in flatten(xs): + if type(t) == str: + t = normpath(t) + s += [t] + else: + s += [f for f in [normpath(f) for f in filenamesof(t.outs)]] + return s + + +def targetnamesof(*xs): + s = [] + for x in flatten(xs): + if type(x) == str: + x = normpath(x) + if x not in s: + s += [x] + else: + if x.name not in s: + s += [x.name] + return s + + +def filenameof(x): + xs = filenamesof(x) + if len(xs) != 1: + raise ABException("expected a single item") + return xs[0] + + +def stripext(path): + return splitext(path)[0] + + +def emit(*args): + outputFp.write(" ".join(flatten(args))) + outputFp.write("\n") + + +def templateexpand(s, invocation): + class Converter: + def __getitem__(self, key): + if key == "self": + return invocation + f = filenamesof(invocation.args[key]) + if isinstance(f, Sequence): + f = ParameterList(f) + return f + + return eval("f%r" % s, invocation.callback.__globals__, Converter()) + + +def emitter_rule(name, ins, outs, deps=[]): + emit("") + emit(".PHONY:", name) + if outs: + emit(name, ":", filenamesof(outs), ";") + emit(filenamesof(outs), "&:", filenamesof(ins), filenamesof(deps)) + else: + emit(name, "&:", filenamesof(ins), filenamesof(deps)) + + +def emitter_endrule(name): + pass + + +def emitter_label(s): + emit("\t$(hide)", "$(ECHO)", s) + + +def emitter_exec(cs): + for c in cs: + emit("\t$(hide)", c) + + +def unmake(*ss): + return [ + re.sub(r"\$\(([^)]*)\)", r"$\1", s) for s in flatten(filenamesof(ss)) + ] + + +@Rule +def simplerule( + self, + name, + ins: Targets = [], + outs=[], + deps: Targets = [], + commands=[], + label="RULE", + **kwargs, +): + self.ins = ins + self.outs = outs + self.deps = deps + emitter_rule(self.name, ins + deps, outs) + emitter_label(templateexpand("{label} {name}", self)) + + dirs = [] + for out in filenamesof(outs): + dir = dirname(out) + if dir and dir not in dirs: + dirs += [dir] + + cs = [("mkdir -p %s" % dir) for dir in dirs] + for c in commands: + cs += [templateexpand(c, self)] + emitter_exec(cs) + emitter_endrule(self.name) + + +@Rule +def normalrule( + self, + name=None, + ins: Targets = [], + deps: Targets = [], + outs=[], + label="RULE", + objdir=None, + commands=[], + **kwargs, +): + objdir = objdir or join("$(OBJ)", name) + + self.normalrule.objdir = objdir + simplerule( + replaces=self, + ins=ins, + deps=deps, + outs=[join(objdir, f) for f in outs], + label=label, + commands=commands, + **kwargs, + ) + + +@Rule +def export(self, name=None, items: TargetsMap = {}, deps: Targets = []): + cs = [] + self.ins = items.values() + self.outs = [] + for dest, src in items.items(): + destf = filenameof(dest) + dir = dirname(destf) + + srcs = filenamesof(src) + if len(srcs) != 1: + raise ABException( + "a dependency of an export must have exactly one output file" + ) + + emitter_rule(self.name + "+" + destf, srcs, [destf]) + emitter_label(f"CP {destf}") + if dir: + emitter_exec(["mkdir -p " + dir]) + + emitter_exec(["cp %s %s" % (srcs[0], destf)]) + self.outs += [destf] + + emitter_rule(self.name, self.outs, [], deps) + emit("\t@") + + if self.outs: + emit("clean::") + emit("\t$(hide) rm -f " + (" ".join(filenamesof(self.outs)))) + self.outs += deps + + emitter_endrule(self.name) + + +def loadbuildfile(filename): + filename = filename.replace("/", ".").removesuffix(".py") + builtins.__import__(filename) + + +def load(filename): + loadbuildfile(filename) + callerglobals = inspect.stack()[1][0].f_globals + for k, v in defaultGlobals.items(): + callerglobals[k] = v + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("-o", "--output") + parser.add_argument("files", nargs="+") + parser.add_argument("-t", "--targets", action="append") + args = parser.parse_args() + if not args.targets: + raise ABException("no targets supplied") + + global outputFp + outputFp = open(args.output, "wt") + + for k in ("Rule", "Targets", "load", "filenamesof", "stripext"): + defaultGlobals[k] = globals()[k] + + global __name__ + sys.modules["build.ab"] = sys.modules[__name__] + __name__ = "build.ab" + + for f in args.files: + loadbuildfile(f) + + for t in flatten([a.split(",") for a in args.targets]): + if t not in targets: + raise ABException("target %s is not defined" % t) + targets[t].materialise() + emit("AB_LOADED = 1\n") + + +main() diff --git a/build/c.py b/build/c.py new file mode 100644 index 00000000..eef55ed1 --- /dev/null +++ b/build/c.py @@ -0,0 +1,265 @@ +from os.path import basename, join +from build.ab import ( + ABException, + Rule, + Targets, + TargetsMap, + filenameof, + flatten, + filenamesof, + normalrule, + stripext, +) +from os.path import * +from types import SimpleNamespace + + +def cfileimpl(self, name, srcs, deps, suffix, commands, label, kind, cflags): + outleaf = stripext(basename(filenameof(srcs[0]))) + suffix + + normalrule( + replaces=self, + ins=srcs, + deps=deps, + outs=[outleaf], + label=label, + commands=commands, + cflags=cflags, + ) + + +@Rule +def cfile( + self, + name, + srcs: Targets = [], + deps: Targets = [], + cflags=[], + suffix=".o", + commands=["$(CC) -c -o {outs[0]} {ins[0]} $(CFLAGS) {cflags}"], + label="CC", +): + cfileimpl(self, name, srcs, deps, suffix, commands, label, "cfile", cflags) + + +@Rule +def cxxfile( + self, + name, + srcs: Targets = [], + deps: Targets = [], + cflags=[], + suffix=".o", + commands=["$(CXX) -c -o {outs[0]} {ins[0]} $(CFLAGS) {cflags}"], + label="CXX", +): + cfileimpl( + self, name, srcs, deps, suffix, commands, label, "cxxfile", cflags + ) + + +def findsources(name, srcs, deps, cflags, filerule): + objs = [] + for s in flatten(srcs): + objs += [ + filerule( + name=join(name, f.removeprefix("$(OBJ)/")), + srcs=[f], + deps=deps, + cflags=cflags, + ) + for f in filenamesof(s) + if f.endswith(".c") or f.endswith(".cc") or f.endswith(".cpp") + ] + if any(f.endswith(".o") for f in filenamesof(s)): + objs += [s] + + return objs + + +def libraryimpl( + self, name, srcs, deps, hdrs, cflags, ldflags, commands, label, kind +): + if not srcs and not hdrs: + raise ABException( + "clibrary contains no sources and no exported headers" + ) + + libraries = [d for d in deps if hasattr(d, "clibrary")] + for library in libraries: + if library.clibrary.cflags: + cflags += library.clibrary.cflags + if library.clibrary.ldflags: + ldflags += library.clibrary.ldflags + + for f in filenamesof(srcs): + if f.endswith(".h"): + deps += [f] + + hdrcs = [] + hdrins = list(hdrs.values()) + hdrouts = [] + i = 0 + for dest, src in hdrs.items(): + s = filenamesof(src) + if len(s) != 1: + raise ABException( + "a dependency of an export must have exactly one output file" + ) + + hdrcs += ["cp {ins[" + str(i) + "]} {outs[" + str(i) + "]}"] + hdrouts += [dest] + i = i + 1 + + if not hasattr(self, "clibrary"): + self.clibrary = SimpleNamespace() + if srcs: + hr = None + if hdrcs: + hr = normalrule( + name=f"{name}_hdrs", + ins=hdrins, + outs=hdrouts, + label="HEADERS", + commands=hdrcs, + ) + hr.materialise() + + actualsrcs = findsources( + name, + srcs, + deps + ([f"{name}_hdrs"] if hr else []), + cflags + ([f"-I{hr.normalrule.objdir}"] if hr else []), + kind, + ) + + normalrule( + replaces=self, + ins=actualsrcs, + outs=[basename(name) + ".a"], + label=label, + commands=commands if actualsrcs else [], + ) + + self.clibrary.ldflags = ldflags + self.clibrary.cflags = ["-I" + hr.normalrule.objdir] if hr else [] + else: + r = normalrule( + replaces=self, + ins=hdrins, + outs=hdrouts, + label="HEADERS", + commands=hdrcs, + ) + r.materialise() + + self.clibrary.ldflags = ldflags + self.clibrary.cflags = ["-I" + r.normalrule.objdir] + + +@Rule +def clibrary( + self, + name, + srcs: Targets = [], + deps: Targets = [], + hdrs: TargetsMap = {}, + cflags=[], + ldflags=[], + commands=["$(AR) cqs {outs[0]} {ins}"], + label="LIB", +): + return libraryimpl( + self, name, srcs, deps, hdrs, cflags, ldflags, commands, label, cfile + ) + + +@Rule +def cxxlibrary( + self, + name, + srcs: Targets = [], + deps: Targets = [], + hdrs: TargetsMap = {}, + cflags=[], + ldflags=[], + commands=["$(AR) cqs {outs[0]} {ins}"], + label="LIB", +): + return libraryimpl( + self, name, srcs, deps, hdrs, cflags, ldflags, commands, label, cxxfile + ) + + +def programimpl( + self, name, srcs, deps, cflags, ldflags, commands, label, filerule, kind +): + libraries = [d for d in deps if hasattr(d, "clibrary")] + for library in libraries: + if library.clibrary.cflags: + cflags += library.clibrary.cflags + if library.clibrary.ldflags: + ldflags += library.clibrary.ldflags + + deps += [f for f in filenamesof(srcs) if f.endswith(".h")] + + ars = [f for f in filenamesof(libraries) if f.endswith(".a")] + normalrule( + replaces=self, + ins=(findsources(name, srcs, deps, cflags, filerule) + ars + ars), + outs=[basename(name) + "$(EXT)"], + deps=deps, + label=label, + commands=commands, + ldflags=ldflags, + ) + + +@Rule +def cprogram( + self, + name, + srcs: Targets = [], + deps: Targets = [], + cflags=[], + ldflags=[], + commands=["$(CC) -o {outs[0]} {ins} {ldflags} $(LDFLAGS)"], + label="CLINK", +): + programimpl( + self, + name, + srcs, + deps, + cflags, + ldflags, + commands, + label, + cfile, + "cprogram", + ) + + +@Rule +def cxxprogram( + self, + name, + srcs: Targets = [], + deps: Targets = [], + cflags=[], + ldflags=[], + commands=["$(CXX) -o {outs[0]} {ins} {ldflags} $(LDFLAGS)"], + label="CXXLINK", +): + programimpl( + self, + name, + srcs, + deps, + cflags, + ldflags, + commands, + label, + cxxfile, + "cxxprogram", + ) diff --git a/build/pkg.py b/build/pkg.py new file mode 100644 index 00000000..769cc15f --- /dev/null +++ b/build/pkg.py @@ -0,0 +1,38 @@ +from build.ab import Rule, emit, Target +from types import SimpleNamespace +import os +import subprocess + +emit( + """ +PKG_CONFIG ?= pkg-config +PACKAGES := $(shell $(PKG_CONFIG) --list-all | cut -d' ' -f1 | sort) +""" +) + + +@Rule +def package(self, name, package=None, fallback: Target = None): + emit("ifeq ($(filter %s, $(PACKAGES)),)" % package) + if fallback: + emit(f"PACKAGE_CFLAGS_{package} :=", fallback.clibrary.cflags) + emit(f"PACKAGE_LDFLAGS_{package} := ", fallback.clibrary.ldflags) + emit(f"PACKAGE_DEP_{package} := ", fallback.name) + else: + emit(f"$(error Required package '{package}' not installed.)") + emit("else") + emit( + f"PACKAGE_CFLAGS_{package} := $(shell $(PKG_CONFIG) --cflags {package})" + ) + emit( + f"PACKAGE_LDFLAGS_{package} := $(shell $(PKG_CONFIG) --libs {package})" + ) + emit(f"PACKAGE_DEP_{package} := ") + emit("endif") + + self.clibrary = SimpleNamespace() + self.clibrary.cflags = [f"$(PACKAGE_CFLAGS_{package})"] + self.clibrary.ldflags = [f"$(PACKAGE_LDFLAGS_{package})"] + + self.ins = [] + self.outs = [f"$(PACKAGE_DEP_{package})"] diff --git a/build/protobuf.py b/build/protobuf.py new file mode 100644 index 00000000..8dc7337b --- /dev/null +++ b/build/protobuf.py @@ -0,0 +1,65 @@ +from os.path import join +from build.ab import Rule, Targets, emit, normalrule, filenamesof, flatten +from build.c import cxxlibrary +import build.pkg +from types import SimpleNamespace + +emit( + """ +PROTOC ?= protoc +ifeq ($(filter protobuf, $(PACKAGES)),) +$(error Required package 'protobuf' not installed.)" +endif +""" +) + + +@Rule +def proto(self, name, srcs: Targets = [], deps: Targets = []): + normalrule( + replaces=self, + ins=srcs, + outs=[f"{name}.descriptor"], + deps=deps, + commands=[ + "$(PROTOC) --include_source_info --descriptor_set_out={outs[0]} {ins}" + ], + label="PROTO", + ) + self.proto.srcs = filenamesof(srcs) + flatten( + [s.proto.srcs for s in flatten(deps)] + ) + + +@Rule +def protocc(self, name, srcs: Targets = [], deps: Targets = []): + outs = [] + protos = [] + for f in flatten([s.proto.srcs for s in flatten(srcs + deps)]): + if f.endswith(".proto"): + cc = f.replace(".proto", ".pb.cc") + h = f.replace(".proto", ".pb.h") + protos += [f] + srcs += [f] + outs += [cc, h] + + r = normalrule( + name=f"{name}_srcs", + ins=protos, + outs=outs, + deps=deps, + commands=["$(PROTOC) --cpp_out={self.normalrule.objdir} {ins}"], + label="PROTOCC", + ) + + r.materialise() + headers = { + f: join(r.normalrule.objdir, f) for f in outs if f.endswith(".pb.h") + } + + cxxlibrary( + replaces=self, + srcs=[f"{name}_srcs"], + hdrs=headers, + cflags=[f"-I{r.normalrule.objdir}"], + ) diff --git a/build/utils.py b/build/utils.py new file mode 100644 index 00000000..e1a227aa --- /dev/null +++ b/build/utils.py @@ -0,0 +1,43 @@ +from build.ab import Rule, normalrule, Target, filenameof, Targets +from os.path import basename + + +@Rule +def objectify(self, name, src: Target, symbol): + normalrule( + replaces=self, + ins=["build/_objectify.py", src], + outs=[basename(filenameof(src)) + ".h"], + commands=["$(PYTHON) {ins[0]} {ins[1]} " + symbol + " > {outs}"], + label="OBJECTIFY", + ) + + +@Rule +def test( + self, + name, + command: Target = None, + commands=None, + ins: Targets = [], + deps: Targets = [], + label="TEST", +): + if command: + normalrule( + replaces=self, + ins=[command], + outs=["sentinel"], + commands=["{ins[0]}", "touch {outs}"], + deps=deps, + label=label, + ) + else: + normalrule( + replaces=self, + ins=ins, + outs=["sentinel"], + commands=commands + ["touch {outs}"], + deps=deps, + label=label, + ) diff --git a/third_party/lib6502/build.py b/third_party/lib6502/build.py new file mode 100644 index 00000000..a59bbca6 --- /dev/null +++ b/third_party/lib6502/build.py @@ -0,0 +1,10 @@ +from build.c import clibrary + +clibrary( + name="lib6502", + srcs=["./lib6502.c"], + hdrs={ + "third_party/lib6502/6502data.h": "./6502data.h", + "third_party/lib6502/lib6502.h": "./lib6502.h", + }, +) diff --git a/tools/cpmemu/biosbdos.c b/tools/cpmemu/biosbdos.c index ee048868..d072a508 100644 --- a/tools/cpmemu/biosbdos.c +++ b/tools/cpmemu/biosbdos.c @@ -1,4 +1,3 @@ -#define _XOPEN_SOURCE 500 #include #include #include diff --git a/tools/cpmemu/build.py b/tools/cpmemu/build.py new file mode 100644 index 00000000..0e226fa3 --- /dev/null +++ b/tools/cpmemu/build.py @@ -0,0 +1,10 @@ +from build.c import cprogram +from build.pkg import package + +package(name="libreadline", package="readline") + +cprogram( + name="cpmemu", + srcs=["./biosbdos.c", "./emulator.c", "./fileio.c", "./main.c"], + deps=["third_party/lib6502", ".+libreadline"], +) diff --git a/tools/cpmemu/fileio.c b/tools/cpmemu/fileio.c index def5ce42..8557354e 100644 --- a/tools/cpmemu/fileio.c +++ b/tools/cpmemu/fileio.c @@ -1,5 +1,3 @@ -#define _XOPEN_SOURCE 500 -#define _POSIX_C_SOURCE 200809 #include #include #include From b975ab0c57b1e95962f72e3ddc9479f818332907 Mon Sep 17 00:00:00 2001 From: David Given Date: Thu, 14 Dec 2023 00:58:29 +0100 Subject: [PATCH 02/23] altirra Basic (plus dependencies) builds. --- build.py | 13 ++++++++++- build/ab.mk | 2 ++ third_party/altirrabasic/build.py | 39 +++++++++++++++++++++++++++++++ third_party/mads/build.py | 25 ++++++++++++++++++++ tools/build.py | 32 +++++++++++++++++++++++++ tools/cpmemu/build.py | 5 +--- 6 files changed, 111 insertions(+), 5 deletions(-) create mode 100644 third_party/altirrabasic/build.py create mode 100644 third_party/mads/build.py create mode 100644 tools/build.py diff --git a/build.py b/build.py index afa85e1a..3727a02d 100644 --- a/build.py +++ b/build.py @@ -1,3 +1,14 @@ from build.ab import export +from build.pkg import package -export(name="all", items={"bin/cpmemu": "tools/cpmemu"}) +package(name="libreadline", package="readline") +package(name="libfmt", package="fmt") + +export( + name="all", + items={ + "bin/cpmemu": "tools/cpmemu", + "bin/mads": "third_party/mads", + "bin/atbasic.com": "third_party/altirrabasic", + }, +) diff --git a/build/ab.mk b/build/ab.mk index 27d4bcf4..7e9267ed 100644 --- a/build/ab.mk +++ b/build/ab.mk @@ -20,6 +20,8 @@ EXT ?= include $(OBJ)/build.mk +.SECONDARY: + .PHONY: update-ab update-ab: @echo "Press RETURN to update ab from the repository, or CTRL+C to cancel." \ diff --git a/third_party/altirrabasic/build.py b/third_party/altirrabasic/build.py new file mode 100644 index 00000000..1b79f219 --- /dev/null +++ b/third_party/altirrabasic/build.py @@ -0,0 +1,39 @@ +from third_party.mads.build import mads +from tools.build import multilink, xextobin + +VARIANTS = { + "core": {"ZPBASE": 0, "TEXTBASE": 0x0200}, + "zp": {"ZPBASE": 1, "TEXTBASE": 0x0200}, + "tpa": {"ZPBASE": 0, "TEXTBASE": 0x0300}, +} + +for name, defines in VARIANTS.items(): + xex = mads( + name=name + "_xex", + src="./source/atbasic.s", + deps=[ + "./kernel/mathpack.s", + "./source/variables.s", + "./source/list.s", + "./source/error.s", + "./source/printerror.s", + "./source/statements.s", + "./source/exec.s", + "./source/math.s", + "./source/io.s", + "./source/parser.s", + "./source/cioemu.s", + "./source/util.s", + "./source/parserbytecode.s", + "./source/functions.s", + "./source/evaluator.s", + "./source/memory.s", + "./source/data.s", + ], + defines=defines, + ) + + xextobin(name=name, src=xex, address=defines["TEXTBASE"]) + + +multilink(name="altirrabasic", core=".+core", zp=".+zp", tpa=".+tpa") diff --git a/third_party/mads/build.py b/third_party/mads/build.py new file mode 100644 index 00000000..00318342 --- /dev/null +++ b/third_party/mads/build.py @@ -0,0 +1,25 @@ +from build.ab import normalrule, emit, Rule, Targets, Target + +emit("FPC ?= fpc") + +normalrule( + name="mads", + ins=["./mads.pas"], + outs=["mads"], + commands=["$(FPC) -Mdelphi -v0 -Os {ins[0]} -o{outs[0]}"], + label="FREEPASCAL", +) + + +@Rule +def mads(self, name=None, src: Target = None, deps: Targets = [], defines={}): + ds = [f"-d:{k}={v}" for k, v in defines.items()] + + normalrule( + replaces=self, + ins=[src], + outs=[name + ".bin"], + deps=["third_party/mads"] + deps, + commands=["{deps[0]} {ins[0]} -c -o:{outs[0]} " + " ".join(ds)], + label="MADS", + ) diff --git a/tools/build.py b/tools/build.py new file mode 100644 index 00000000..3b7d643b --- /dev/null +++ b/tools/build.py @@ -0,0 +1,32 @@ +from build.ab import Rule, Target, normalrule +from build.c import cxxprogram + +cxxprogram(name="multilink", srcs=["./multilink.cc"], deps=["+libfmt"]) + +cxxprogram(name="xextobin", srcs=["./xextobin.cc"], deps=["+libfmt"]) + + +@Rule +def multilink( + self, name=None, core: Target = None, zp: Target = None, tpa: Target = None +): + normalrule( + replaces=self, + ins=[core, zp, tpa], + outs=[name + ".com"], + deps=["tools+multilink"], + commands=["{deps[0]} -o {outs[0]} {ins}"], + label="MULTILINK", + ) + + +@Rule +def xextobin(self, name=None, src: Target = None, address=0): + normalrule( + replaces=self, + ins=[src], + outs=[name + ".bin"], + deps=["tools+xextobin"], + commands=["{deps[0]} -i {ins[0]} -o {outs[0]} -b %d" % address], + label="XEXTOBIN", + ) diff --git a/tools/cpmemu/build.py b/tools/cpmemu/build.py index 0e226fa3..aec7798b 100644 --- a/tools/cpmemu/build.py +++ b/tools/cpmemu/build.py @@ -1,10 +1,7 @@ from build.c import cprogram -from build.pkg import package - -package(name="libreadline", package="readline") cprogram( name="cpmemu", srcs=["./biosbdos.c", "./emulator.c", "./fileio.c", "./main.c"], - deps=["third_party/lib6502", ".+libreadline"], + deps=["third_party/lib6502", "+libreadline"], ) From 32bba04baa19753c3f5afa421893aa3441b97711 Mon Sep 17 00:00:00 2001 From: David Given Date: Fri, 15 Dec 2023 14:33:15 +0100 Subject: [PATCH 03/23] Silence mads. --- .github/workflows/ccpp.yml | 2 +- third_party/mads/build.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml index 74a53987..8be1106a 100644 --- a/.github/workflows/ccpp.yml +++ b/.github/workflows/ccpp.yml @@ -18,7 +18,7 @@ jobs: run: echo "MOS_SDK_VERSION=$(cd llvm-mos-sdk && git rev-parse --short HEAD)" >> $GITHUB_ENV - name: apt - run: sudo apt update && sudo apt install cc1541 cpmtools libfmt-dev ninja-build fp-compiler + run: sudo apt update && sudo apt install cc1541 cpmtools libfmt-dev fp-compiler moreutils - name: cache llvm-mos id: cache-llvm-mos diff --git a/third_party/mads/build.py b/third_party/mads/build.py index 00318342..87edd6f7 100644 --- a/third_party/mads/build.py +++ b/third_party/mads/build.py @@ -20,6 +20,6 @@ def mads(self, name=None, src: Target = None, deps: Targets = [], defines={}): ins=[src], outs=[name + ".bin"], deps=["third_party/mads"] + deps, - commands=["{deps[0]} {ins[0]} -c -o:{outs[0]} " + " ".join(ds)], + commands=["chronic {deps[0]} {ins[0]} -c -o:{outs[0]} " + " ".join(ds)], label="MADS", ) From 9820e2dec7273a9e52e66fd3a1ead5e33c39abe5 Mon Sep 17 00:00:00 2001 From: David Given Date: Fri, 15 Dec 2023 14:49:19 +0100 Subject: [PATCH 04/23] Silence FreePascal, multilink and xextobin. --- third_party/mads/build.py | 2 +- tools/multilink.cc | 82 +++++++++++++++++++++++++++++---------- tools/xextobin.cc | 21 ++++++---- 3 files changed, 76 insertions(+), 29 deletions(-) diff --git a/third_party/mads/build.py b/third_party/mads/build.py index 87edd6f7..b34396e1 100644 --- a/third_party/mads/build.py +++ b/third_party/mads/build.py @@ -6,7 +6,7 @@ name="mads", ins=["./mads.pas"], outs=["mads"], - commands=["$(FPC) -Mdelphi -v0 -Os {ins[0]} -o{outs[0]}"], + commands=["chronic $(FPC) -Mdelphi -Os {ins[0]} -o{outs[0]}"], label="FREEPASCAL", ) diff --git a/tools/multilink.cc b/tools/multilink.cc index 74176fcc..61f3e5cf 100644 --- a/tools/multilink.cc +++ b/tools/multilink.cc @@ -4,6 +4,8 @@ */ #include +#include +#include #include #include #include @@ -11,6 +13,12 @@ #include #include +static std::string outfilename; +static std::string corefilename; +static std::string zpfilename; +static std::string memfilename; +static bool verbose = false; + template void error(fmt::format_string fmt, T&&... args) { @@ -93,38 +101,76 @@ unsigned roundup(unsigned value) return (value + 127) & ~127; } +static void syntaxError() +{ + fmt::print(stderr, + "Usage: multilink -o \n"); + exit(1); +} + +static void parseArguments(int argc, char* const* argv) +{ + for (;;) + { + switch (getopt(argc, argv, "vo:")) + { + case -1: + if (!argv[optind + 0] || !argv[optind + 1] || !argv[optind + 2]) + syntaxError(); + + corefilename = argv[optind + 0]; + zpfilename = argv[optind + 1]; + memfilename = argv[optind + 2]; + return; + + case 'o': + outfilename = optarg; + break; + + case 'v': + verbose = true; + break; + + default: + syntaxError(); + } + } +} + int main(int argc, char* const* argv) { - if ((argc != 6) || (std::string(argv[1]) != "-o")) - error("syntax: multilink -o "); + parseArguments(argc, argv); - auto outfile = std::string(argv[2]); - auto corefile = std::string(argv[3]); - auto zpfile = std::string(argv[4]); - auto memfile = std::string(argv[5]); + if (verbose) + { + fmt::print("core file: {}\n", corefilename); + fmt::print("zp file: {}\n", zpfilename); + fmt::print("mem file: {}\n", memfilename); + } - auto coreSize = std::filesystem::file_size(corefile); + auto coreSize = std::filesystem::file_size(corefilename); - auto [zpDifferences, zpMax] = compare(corefile, zpfile); + auto [zpDifferences, zpMax] = compare(corefilename, zpfilename); auto zpBytes = toBytestream(zpDifferences); - auto [memDifferences, memMax] = compare(corefile, memfile); + auto [memDifferences, memMax] = compare(corefilename, memfilename); auto memBytes = toBytestream(memDifferences); unsigned reloBytesSize = zpBytes.size() + 1 + memBytes.size(); - std::fstream outs(outfile, + std::fstream outs(outfilename, std::fstream::in | std::fstream::out | std::fstream::trunc | std::fstream::binary); - fmt::print("{} code bytes, {} zprelo bytes, {} memrelo bytes\n", - coreSize, - zpBytes.size(), - memBytes.size()); + if (verbose) + fmt::print("{} code bytes, {} zprelo bytes, {} memrelo bytes\n", + coreSize, + zpBytes.size(), + memBytes.size()); /* Write the actual code body. */ { auto memi = memDifferences.begin(); - std::ifstream is(corefile); + std::ifstream is(corefilename); unsigned pos = 0; for (;;) { @@ -162,11 +208,5 @@ int main(int argc, char* const* argv) for (uint8_t b : memBytes) outs.put(b); - /* Remove temporary files. */ - - std::filesystem::remove(corefile); - std::filesystem::remove(zpfile); - std::filesystem::remove(memfile); - return 0; } diff --git a/tools/xextobin.cc b/tools/xextobin.cc index bad98403..db224d0d 100644 --- a/tools/xextobin.cc +++ b/tools/xextobin.cc @@ -16,6 +16,7 @@ static uint8_t ram[0x10000]; static uint16_t base = 0; static uint16_t himem = 0; static std::string outfilename; +static bool verbose = false; template void error(fmt::format_string fmt, T&&... args) @@ -36,7 +37,7 @@ static uint16_t readle16(std::istream& is) static void read_file(std::string filename) { std::ifstream ifs(filename, std::ios::binary); - if (!ifs) + if (!ifs) error("could not read input file: {}", strerror(errno)); for (;;) @@ -49,7 +50,7 @@ static void read_file(std::string filename) default: if ((header & 0xff00) == 0xff00) error("unsupported header 0x{:04x}\n", header); - ifs.seekg(ifs.tellg()-2L); + ifs.seekg(ifs.tellg() - 2L); /* fall through */ case 0xffff: { @@ -58,9 +59,11 @@ static void read_file(std::string filename) if (start == 0x0000) error("relocatable blocks are not supported"); uint16_t len = (end - start) + 1; - fmt::print("reading 0x{:04x} bytes to 0x{:04x}\n", len, start); + if (verbose) + fmt::print( + "reading 0x{:04x} bytes to 0x{:04x}\n", len, start); ifs.read((char*)(ram + start), len); - himem = std::max((int)himem, (int)end+1); + himem = std::max((int)himem, (int)end + 1); break; } } @@ -70,8 +73,9 @@ static void read_file(std::string filename) static void write_file() { uint16_t len = himem - base; - fmt::print("writing 0x{:04x} bytes from 0x{:04x}\n", len, base); - + if (verbose) + fmt::print("writing 0x{:04x} bytes from 0x{:04x}\n", len, base); + std::ofstream ofs(outfilename, std::ios::out | std::ios::binary); if (!ofs) error("failed to open output file: {}", strerror(errno)); @@ -100,6 +104,10 @@ int main(int argc, char* const argv[]) outfilename = optarg; break; + case 'v': + verbose = true; + break; + default: fmt::print(stderr, "Usage: xextobin -i -o -b \n"); @@ -107,4 +115,3 @@ int main(int argc, char* const argv[]) } } } - From 85e1fe5e03a03f4534e3f687083d4d2ca3ea076f Mon Sep 17 00:00:00 2001 From: David Given Date: Fri, 15 Dec 2023 17:07:06 +0100 Subject: [PATCH 05/23] The LLVM toolchain works, DFS and CPMFS images can be built, and some of the bbcmicro platform builds. --- Makefile | 7 ++- build.py | 1 + build/c.py | 24 ++++++++-- build/llvm.py | 61 ++++++++++++++++++++++++++ include/build.py | 12 +++++ lib/build.py | 5 +++ src/{bios => arch/bbcmicro}/bbcmicro.S | 0 src/arch/bbcmicro/build.py | 12 +++++ src/build.py | 7 +++ tools/build.py | 54 ++++++++++++++++++++++- tools/mkdfs.c | 1 - 11 files changed, 176 insertions(+), 8 deletions(-) create mode 100644 build/llvm.py create mode 100644 include/build.py create mode 100644 lib/build.py rename src/{bios => arch/bbcmicro}/bbcmicro.S (100%) create mode 100644 src/arch/bbcmicro/build.py create mode 100644 src/build.py diff --git a/Makefile b/Makefile index 25bfb2f2..04f13f07 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,11 @@ +export LLVM = /opt/llvm-mos/bin +export CC6502 = $(LLVM)/mos-cpm65-clang +export AR6502 = $(LLVM)/llvm-ar +export CFLAGS6502 = -Os -g + export OBJ = .obj .PHONY: all all: +all - + include build/ab.mk diff --git a/build.py b/build.py index 3727a02d..c4b606d7 100644 --- a/build.py +++ b/build.py @@ -10,5 +10,6 @@ "bin/cpmemu": "tools/cpmemu", "bin/mads": "third_party/mads", "bin/atbasic.com": "third_party/altirrabasic", + "bbcmicro.ssd": "src/arch/bbcmicro+diskimage", }, ) diff --git a/build/c.py b/build/c.py index eef55ed1..0242c80c 100644 --- a/build/c.py +++ b/build/c.py @@ -69,7 +69,11 @@ def findsources(name, srcs, deps, cflags, filerule): cflags=cflags, ) for f in filenamesof(s) - if f.endswith(".c") or f.endswith(".cc") or f.endswith(".cpp") + if f.endswith(".c") + or f.endswith(".cc") + or f.endswith(".cpp") + or f.endswith(".S") + or f.endswith(".s") ] if any(f.endswith(".o") for f in filenamesof(s)): objs += [s] @@ -168,9 +172,19 @@ def clibrary( ldflags=[], commands=["$(AR) cqs {outs[0]} {ins}"], label="LIB", + cfilerule=cfile, ): return libraryimpl( - self, name, srcs, deps, hdrs, cflags, ldflags, commands, label, cfile + self, + name, + srcs, + deps, + hdrs, + cflags, + ldflags, + commands, + label, + cfilerule, ) @@ -225,6 +239,8 @@ def cprogram( ldflags=[], commands=["$(CC) -o {outs[0]} {ins} {ldflags} $(LDFLAGS)"], label="CLINK", + cfilerule=cfile, + cfilekind="cprogram", ): programimpl( self, @@ -235,8 +251,8 @@ def cprogram( ldflags, commands, label, - cfile, - "cprogram", + cfilerule, + cfilekind, ) diff --git a/build/llvm.py b/build/llvm.py new file mode 100644 index 00000000..103ea60e --- /dev/null +++ b/build/llvm.py @@ -0,0 +1,61 @@ +from build.ab import Rule, Targets +from build.c import cprogram, cfile, clibrary + + +@Rule +def llvmcfile( + self, + name, + srcs: Targets = [], + deps: Targets = [], + cflags=[], + suffix=".o", + commands=["$(CC6502) -c -o {outs[0]} {ins[0]} $(CFLAGS6502) {cflags}"], + label="CC6502", +): + cfile( + replaces=self, + srcs=srcs, + deps=deps, + cflags=cflags, + suffix=suffix, + commands=commands, + label=label, + ) + + +@Rule +def llvmprogram( + self, + name=None, + srcs: Targets = [], + deps: Targets = [], + cflags=[], + ldflags=[], + commands=["$(CC6502) -o {outs[0]} {ins} {ldflags} $(LDFLAGS6502)"], + label="CLINK6502", +): + cprogram( + replaces=self, + srcs=srcs, + deps=deps, + cflags=cflags, + ldflags=ldflags, + commands=commands, + label=label, + cfilerule=llvmcfile, + cfilekind="llvmprogram", + ) + + +@Rule +def llvmclibrary( + name, self, commands=["$(AR6502) cqs {outs[0]} {ins}"], **kwargs +): + clibrary( + replaces=self, + commands=commands, + cfilerule=llvmcfile, + label="LIB6502", + **kwargs + ) diff --git a/include/build.py b/include/build.py new file mode 100644 index 00000000..5308ba42 --- /dev/null +++ b/include/build.py @@ -0,0 +1,12 @@ +from build.llvm import llvmclibrary + +llvmclibrary( + name="include", + hdrs={ + "cpm65.inc": "./cpm65.inc", + "driver.inc": "./driver.inc", + "jumptables.inc": "./jumptables.inc", + "wait.inc": "./wait.inc", + "zif.inc": "./zif.inc", + }, +) diff --git a/lib/build.py b/lib/build.py new file mode 100644 index 00000000..cf9fb4cd --- /dev/null +++ b/lib/build.py @@ -0,0 +1,5 @@ +from build.llvm import llvmclibrary + +llvmclibrary(name="bdos", srcs=["./bdos.S"], deps=["include"]) + +llvmclibrary(name="xfcb", srcs=["./xfcb.S"], deps=["include"]) diff --git a/src/bios/bbcmicro.S b/src/arch/bbcmicro/bbcmicro.S similarity index 100% rename from src/bios/bbcmicro.S rename to src/arch/bbcmicro/bbcmicro.S diff --git a/src/arch/bbcmicro/build.py b/src/arch/bbcmicro/build.py new file mode 100644 index 00000000..a6300662 --- /dev/null +++ b/src/arch/bbcmicro/build.py @@ -0,0 +1,12 @@ +from build.ab import normalrule +from tools.build import mkdfs, mkcpmfs + +mkcpmfs(name="cpmfs", format="bbc192", items={"0:ccp.sys": "src+ccp"}) + +mkdfs( + name="diskimage", + out="bbcmicro.ssd", + title="CP/M-65", + opt=2, + items={"bdos": "src+bdos", "cpmfs": ".+cpmfs"}, +) diff --git a/src/build.py b/src/build.py new file mode 100644 index 00000000..a56a2107 --- /dev/null +++ b/src/build.py @@ -0,0 +1,7 @@ +from build.llvm import llvmprogram + +llvmprogram(name="bdos", srcs=["./bdos.S"], deps=["include"]) + +llvmprogram( + name="ccp", srcs=["./ccp.S"], deps=["include", "lib+bdos", "lib+xfcb"] +) diff --git a/tools/build.py b/tools/build.py index 3b7d643b..1abaad13 100644 --- a/tools/build.py +++ b/tools/build.py @@ -1,10 +1,12 @@ -from build.ab import Rule, Target, normalrule -from build.c import cxxprogram +from build.ab import Rule, Target, normalrule, filenameof, targetsof, TargetsMap +from build.c import cxxprogram, cprogram cxxprogram(name="multilink", srcs=["./multilink.cc"], deps=["+libfmt"]) cxxprogram(name="xextobin", srcs=["./xextobin.cc"], deps=["+libfmt"]) +cprogram(name="mkdfs", srcs=["./mkdfs.c"], deps=["+libfmt"]) + @Rule def multilink( @@ -30,3 +32,51 @@ def xextobin(self, name=None, src: Target = None, address=0): commands=["{deps[0]} -i {ins[0]} -o {outs[0]} -b %d" % address], label="XEXTOBIN", ) + + +@Rule +def mkcpmfs(self, name, format, items: TargetsMap = {}): + cs = ["mkfs.cpm -f %s {outs[0]}" % format] + ins = [] + for k, v in items.items(): + cs += ["cpmcp -f %s {outs[0]} %s %s" % (format, filenameof(v), k)] + ins += [v] + + normalrule( + replaces=self, + ins=ins, + outs=[name + ".img"], + deps=["diskdefs"], + commands=cs, + label="MKCPMFS", + ) + + +@Rule +def mkdfs( + self, name=None, out=None, title="DFS", opt=0, items: TargetsMap = {} +): + cs = [] + ins = [] + for k, v in items.items(): + if type(k) == str: + k = {"name": k} + + ins += [v] + cs += ["-f", filenameof(v), "-n", k["name"]] + if "loadaddr" in k: + cs += ["-l", k["loadaddr"]] + if "execaddr" in k: + cs += ["-e", k["execaddr"]] + + normalrule( + replaces=self, + ins=ins, + outs=[out], + deps=["tools+mkdfs"], + commands=[ + ("{deps[0]} -O {outs[0]} -B %d -N %s " % (opt, title)) + + " ".join(cs) + ], + label="MKDFS", + ) diff --git a/tools/mkdfs.c b/tools/mkdfs.c index 0b9db11e..b682cc87 100644 --- a/tools/mkdfs.c +++ b/tools/mkdfs.c @@ -3,7 +3,6 @@ * see the COPYING file in the root project directory for the full text. */ -#define _XOPEN_SOURCE 500 #include #include #include From 0963d295d9c186b08eaaafa71f6a0c503632b6d9 Mon Sep 17 00:00:00 2001 From: David Given Date: Fri, 15 Dec 2023 18:32:05 +0100 Subject: [PATCH 06/23] The bbcmicro BIOS builds now. Find (and fix) a horrifying ab bug --- turns out mutable default parameters are a bad idea... --- Makefile | 1 + build/ab.py | 35 ++++++++++++----- build/c.py | 45 +++++++++++----------- build/llvm.py | 41 +++++++++++++++----- build/protobuf.py | 4 +- build/utils.py | 4 +- lib/build.py | 1 - {scripts => src/arch/bbcmicro}/bbcmicro.ld | 0 src/arch/bbcmicro/build.py | 14 ++++++- {include => src/arch/bbcmicro}/mos.inc | 0 src/{bios => lib}/biosentry.S | 1 - src/lib/build.py | 7 ++++ src/{bios => lib}/loader.S | 0 src/{bios => lib}/relocate.S | 0 third_party/mads/build.py | 2 +- tools/build.py | 13 +++---- 16 files changed, 113 insertions(+), 55 deletions(-) rename {scripts => src/arch/bbcmicro}/bbcmicro.ld (100%) rename {include => src/arch/bbcmicro}/mos.inc (100%) rename src/{bios => lib}/biosentry.S (99%) create mode 100644 src/lib/build.py rename src/{bios => lib}/loader.S (100%) rename src/{bios => lib}/relocate.S (100%) diff --git a/Makefile b/Makefile index 04f13f07..f81981f1 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,6 @@ export LLVM = /opt/llvm-mos/bin export CC6502 = $(LLVM)/mos-cpm65-clang +export LD6502 = $(LLVM)/ld.lld export AR6502 = $(LLVM)/llvm-ar export CFLAGS6502 = -Os -g diff --git a/build/ab.py b/build/ab.py index d5393867..75c4e8e8 100644 --- a/build/ab.py +++ b/build/ab.py @@ -186,9 +186,21 @@ def __init__(self, value): self.value = value +class List(Type): + def convert(self, invocation): + value = self.value + if not value: + return [] + if type(value) is str: + return [value] + return list(value) + + class Targets(Type): def convert(self, invocation): value = self.value + if not value: + return [] if type(value) is str: value = [value] if type(value) is list: @@ -207,6 +219,8 @@ def convert(self, invocation): class TargetsMap(Type): def convert(self, invocation): value = self.value + if not value: + return {} if type(value) is dict: return { k: targetof(v, cwd=invocation.cwd) for k, v in value.items() @@ -238,6 +252,9 @@ def targetof(s, cwd): s.materialise() return s + if type(s) != str: + raise ABException("parameter of targetof is not a single target") + if s in targets: t = targets[s] t.materialise() @@ -357,10 +374,10 @@ def unmake(*ss): def simplerule( self, name, - ins: Targets = [], - outs=[], - deps: Targets = [], - commands=[], + ins: Targets = None, + outs: List = [], + deps: Targets = None, + commands: List = [], label="RULE", **kwargs, ): @@ -387,12 +404,12 @@ def simplerule( def normalrule( self, name=None, - ins: Targets = [], - deps: Targets = [], - outs=[], + ins: Targets = None, + deps: Targets = None, + outs: List = [], label="RULE", objdir=None, - commands=[], + commands: List = [], **kwargs, ): objdir = objdir or join("$(OBJ)", name) @@ -410,7 +427,7 @@ def normalrule( @Rule -def export(self, name=None, items: TargetsMap = {}, deps: Targets = []): +def export(self, name=None, items: TargetsMap = {}, deps: Targets = None): cs = [] self.ins = items.values() self.outs = [] diff --git a/build/c.py b/build/c.py index 0242c80c..12edf81b 100644 --- a/build/c.py +++ b/build/c.py @@ -4,6 +4,7 @@ Rule, Targets, TargetsMap, + List, filenameof, flatten, filenamesof, @@ -32,9 +33,9 @@ def cfileimpl(self, name, srcs, deps, suffix, commands, label, kind, cflags): def cfile( self, name, - srcs: Targets = [], - deps: Targets = [], - cflags=[], + srcs: Targets = None, + deps: Targets = None, + cflags: List = [], suffix=".o", commands=["$(CC) -c -o {outs[0]} {ins[0]} $(CFLAGS) {cflags}"], label="CC", @@ -46,9 +47,9 @@ def cfile( def cxxfile( self, name, - srcs: Targets = [], - deps: Targets = [], - cflags=[], + srcs: Targets = None, + deps: Targets = None, + cflags: List = [], suffix=".o", commands=["$(CXX) -c -o {outs[0]} {ins[0]} $(CFLAGS) {cflags}"], label="CXX", @@ -165,11 +166,11 @@ def libraryimpl( def clibrary( self, name, - srcs: Targets = [], - deps: Targets = [], + srcs: Targets = None, + deps: Targets = None, hdrs: TargetsMap = {}, - cflags=[], - ldflags=[], + cflags: List = [], + ldflags: List = [], commands=["$(AR) cqs {outs[0]} {ins}"], label="LIB", cfilerule=cfile, @@ -192,11 +193,11 @@ def clibrary( def cxxlibrary( self, name, - srcs: Targets = [], - deps: Targets = [], + srcs: Targets = None, + deps: Targets = None, hdrs: TargetsMap = {}, - cflags=[], - ldflags=[], + cflags: List = [], + ldflags: List = [], commands=["$(AR) cqs {outs[0]} {ins}"], label="LIB", ): @@ -233,10 +234,10 @@ def programimpl( def cprogram( self, name, - srcs: Targets = [], - deps: Targets = [], - cflags=[], - ldflags=[], + srcs: Targets = None, + deps: Targets = None, + cflags: List = [], + ldflags: List = [], commands=["$(CC) -o {outs[0]} {ins} {ldflags} $(LDFLAGS)"], label="CLINK", cfilerule=cfile, @@ -260,10 +261,10 @@ def cprogram( def cxxprogram( self, name, - srcs: Targets = [], - deps: Targets = [], - cflags=[], - ldflags=[], + srcs: Targets = None, + deps: Targets = None, + cflags: List = [], + ldflags: List = [], commands=["$(CXX) -o {outs[0]} {ins} {ldflags} $(LDFLAGS)"], label="CXXLINK", ): diff --git a/build/llvm.py b/build/llvm.py index 103ea60e..28be2869 100644 --- a/build/llvm.py +++ b/build/llvm.py @@ -1,4 +1,4 @@ -from build.ab import Rule, Targets +from build.ab import Rule, Targets, Target, List from build.c import cprogram, cfile, clibrary @@ -6,9 +6,9 @@ def llvmcfile( self, name, - srcs: Targets = [], - deps: Targets = [], - cflags=[], + srcs: Targets = None, + deps: Targets = None, + cflags: List = [], suffix=".o", commands=["$(CC6502) -c -o {outs[0]} {ins[0]} $(CFLAGS6502) {cflags}"], label="CC6502", @@ -28,11 +28,11 @@ def llvmcfile( def llvmprogram( self, name=None, - srcs: Targets = [], - deps: Targets = [], - cflags=[], - ldflags=[], - commands=["$(CC6502) -o {outs[0]} {ins} {ldflags} $(LDFLAGS6502)"], + srcs: Targets = None, + deps: Targets = None, + cflags: List = None, + ldflags: List = None, + commands: List = ["$(CC6502) -o {outs[0]} {ins} {ldflags} $(LDFLAGS6502)"], label="CLINK6502", ): cprogram( @@ -48,6 +48,29 @@ def llvmprogram( ) +@Rule +def llvmrawprogram( + self, + name, + linkscript: Target, + deps: Targets = None, + commands=[ + "$(LD6502) -Map {outs[0]}.map, -T {deps[0]} -o {outs[0]} {ins} {ldflags}" + ], + label="LD6502", + **kwargs +): + cprogram( + replaces=self, + deps=[linkscript] + deps, + commands=commands, + label=label, + cfilerule=llvmcfile, + cfilekind="llvmprogram", + **kwargs + ) + + @Rule def llvmclibrary( name, self, commands=["$(AR6502) cqs {outs[0]} {ins}"], **kwargs diff --git a/build/protobuf.py b/build/protobuf.py index 8dc7337b..27483cbf 100644 --- a/build/protobuf.py +++ b/build/protobuf.py @@ -15,7 +15,7 @@ @Rule -def proto(self, name, srcs: Targets = [], deps: Targets = []): +def proto(self, name, srcs: Targets = None, deps: Targets = None): normalrule( replaces=self, ins=srcs, @@ -32,7 +32,7 @@ def proto(self, name, srcs: Targets = [], deps: Targets = []): @Rule -def protocc(self, name, srcs: Targets = [], deps: Targets = []): +def protocc(self, name, srcs: Targets = None, deps: Targets = None): outs = [] protos = [] for f in flatten([s.proto.srcs for s in flatten(srcs + deps)]): diff --git a/build/utils.py b/build/utils.py index e1a227aa..0ce1cbc6 100644 --- a/build/utils.py +++ b/build/utils.py @@ -19,8 +19,8 @@ def test( name, command: Target = None, commands=None, - ins: Targets = [], - deps: Targets = [], + ins: Targets = None, + deps: Targets = None, label="TEST", ): if command: diff --git a/lib/build.py b/lib/build.py index cf9fb4cd..312211bb 100644 --- a/lib/build.py +++ b/lib/build.py @@ -1,5 +1,4 @@ from build.llvm import llvmclibrary llvmclibrary(name="bdos", srcs=["./bdos.S"], deps=["include"]) - llvmclibrary(name="xfcb", srcs=["./xfcb.S"], deps=["include"]) diff --git a/scripts/bbcmicro.ld b/src/arch/bbcmicro/bbcmicro.ld similarity index 100% rename from scripts/bbcmicro.ld rename to src/arch/bbcmicro/bbcmicro.ld diff --git a/src/arch/bbcmicro/build.py b/src/arch/bbcmicro/build.py index a6300662..632326a4 100644 --- a/src/arch/bbcmicro/build.py +++ b/src/arch/bbcmicro/build.py @@ -1,5 +1,13 @@ from build.ab import normalrule from tools.build import mkdfs, mkcpmfs +from build.llvm import llvmrawprogram + +llvmrawprogram( + name="bios", + srcs=["./bbcmicro.S", "./mos.inc"], + deps=["include", "src/lib+bioslib"], + linkscript="./bbcmicro.ld", +) mkcpmfs(name="cpmfs", format="bbc192", items={"0:ccp.sys": "src+ccp"}) @@ -8,5 +16,9 @@ out="bbcmicro.ssd", title="CP/M-65", opt=2, - items={"bdos": "src+bdos", "cpmfs": ".+cpmfs"}, + items={ + "!boot@0x0400": ".+bios", + "bdos": "src+bdos", + "cpmfs": ".+cpmfs", + }, ) diff --git a/include/mos.inc b/src/arch/bbcmicro/mos.inc similarity index 100% rename from include/mos.inc rename to src/arch/bbcmicro/mos.inc diff --git a/src/bios/biosentry.S b/src/lib/biosentry.S similarity index 99% rename from src/bios/biosentry.S rename to src/lib/biosentry.S index d7b3303c..e3b0645f 100644 --- a/src/bios/biosentry.S +++ b/src/lib/biosentry.S @@ -3,7 +3,6 @@ ; see the COPYING file in the root project directory for the full text. #include "zif.inc" -#include "mos.inc" #include "cpm65.inc" #include "driver.inc" #include "jumptables.inc" diff --git a/src/lib/build.py b/src/lib/build.py new file mode 100644 index 00000000..700b6d8b --- /dev/null +++ b/src/lib/build.py @@ -0,0 +1,7 @@ +from build.llvm import llvmclibrary + +llvmclibrary( + name="bioslib", + srcs=["./biosentry.S", "./relocate.S", "./loader.S"], + deps=["include"], +) diff --git a/src/bios/loader.S b/src/lib/loader.S similarity index 100% rename from src/bios/loader.S rename to src/lib/loader.S diff --git a/src/bios/relocate.S b/src/lib/relocate.S similarity index 100% rename from src/bios/relocate.S rename to src/lib/relocate.S diff --git a/third_party/mads/build.py b/third_party/mads/build.py index b34396e1..8db74f00 100644 --- a/third_party/mads/build.py +++ b/third_party/mads/build.py @@ -12,7 +12,7 @@ @Rule -def mads(self, name=None, src: Target = None, deps: Targets = [], defines={}): +def mads(self, name=None, src: Target = None, deps: Targets = None, defines={}): ds = [f"-d:{k}={v}" for k, v in defines.items()] normalrule( diff --git a/tools/build.py b/tools/build.py index 1abaad13..d92a39e6 100644 --- a/tools/build.py +++ b/tools/build.py @@ -59,15 +59,14 @@ def mkdfs( cs = [] ins = [] for k, v in items.items(): - if type(k) == str: - k = {"name": k} + addr = None + if "@" in k: + k, addr = k.split("@") ins += [v] - cs += ["-f", filenameof(v), "-n", k["name"]] - if "loadaddr" in k: - cs += ["-l", k["loadaddr"]] - if "execaddr" in k: - cs += ["-e", k["execaddr"]] + cs += ["-f", filenameof(v), "-n", k] + if addr: + cs += ["-l", addr, "-e", addr] normalrule( replaces=self, From 2ce136bdffbc42a6e3127e3fc875d5d09344b898 Mon Sep 17 00:00:00 2001 From: David Given Date: Fri, 15 Dec 2023 18:52:32 +0100 Subject: [PATCH 07/23] Some applications build now. --- Makefile | 4 +++- apps/build.py | 4 ++++ build/ab.mk | 11 ++++++++++- config.py | 13 +++++++++++++ lib/build.py | 7 +++++++ src/arch/bbcmicro/build.py | 3 ++- 6 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 apps/build.py create mode 100644 config.py diff --git a/Makefile b/Makefile index f81981f1..46e0a5db 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,9 @@ export LLVM = /opt/llvm-mos/bin export CC6502 = $(LLVM)/mos-cpm65-clang export LD6502 = $(LLVM)/ld.lld export AR6502 = $(LLVM)/llvm-ar -export CFLAGS6502 = -Os -g + +export CFLAGS6502 = -Os -g \ + -Wno-main-return-type export OBJ = .obj diff --git a/apps/build.py b/apps/build.py new file mode 100644 index 00000000..2bb4671b --- /dev/null +++ b/apps/build.py @@ -0,0 +1,4 @@ +from build.llvm import llvmprogram + +for prog in ["asm", "copy", "stat", "submit", "objdump", "qe", "life"]: + llvmprogram(name=prog, srcs=["./%s.c" % prog], deps=["lib+cpm65"]) diff --git a/build/ab.mk b/build/ab.mk index 7e9267ed..fdff03ad 100644 --- a/build/ab.mk +++ b/build/ab.mk @@ -9,10 +9,19 @@ CXX ?= g++ AR ?= ar CFLAGS ?= -g -Og LDFLAGS ?= -g -hide = @ PKG_CONFIG ?= pkg-config ECHO ?= echo +ifdef VERBOSE + hide = +else + ifdef V + hide = + else + hide = @ + endif +endif + ifeq ($(OS), Windows_NT) EXT ?= .exe endif diff --git a/config.py b/config.py new file mode 100644 index 00000000..7e2dbf3c --- /dev/null +++ b/config.py @@ -0,0 +1,13 @@ +MINIMAL_APPS = { + "0:asm.com": "apps+asm", + "0:copy.com": "apps+copy", + "0:stat.com": "apps+stat", + "0:submit.com": "apps+submit", +} + +APPS = MINIMAL_APPS | { + "0:life.com": "apps+life", + "0:qe.com": "apps+qe", + "0:objdump.com": "apps+objdump", + "0:atbasic.com": "third_party/altirrabasic", +} diff --git a/lib/build.py b/lib/build.py index 312211bb..8c83df5b 100644 --- a/lib/build.py +++ b/lib/build.py @@ -2,3 +2,10 @@ llvmclibrary(name="bdos", srcs=["./bdos.S"], deps=["include"]) llvmclibrary(name="xfcb", srcs=["./xfcb.S"], deps=["include"]) + +llvmclibrary( + name="cpm65", + srcs=["./printi.S", "./screen.S"], + hdrs={"lib/printi.h": "./printi.h", "lib/screen.h": "./screen.h"}, + deps=["include"], +) diff --git a/src/arch/bbcmicro/build.py b/src/arch/bbcmicro/build.py index 632326a4..dd741b32 100644 --- a/src/arch/bbcmicro/build.py +++ b/src/arch/bbcmicro/build.py @@ -1,6 +1,7 @@ from build.ab import normalrule from tools.build import mkdfs, mkcpmfs from build.llvm import llvmrawprogram +from config import APPS llvmrawprogram( name="bios", @@ -9,7 +10,7 @@ linkscript="./bbcmicro.ld", ) -mkcpmfs(name="cpmfs", format="bbc192", items={"0:ccp.sys": "src+ccp"}) +mkcpmfs(name="cpmfs", format="bbc192", items={"0:ccp.sys": "src+ccp"} | APPS) mkdfs( name="diskimage", From 2b3a076f44e9c18e868ff3cd3637c39587ac1f7f Mon Sep 17 00:00:00 2001 From: David Given Date: Sat, 16 Dec 2023 00:35:33 +0100 Subject: [PATCH 08/23] Build the asm applications. --- apps/build.py | 34 ++++++++++++++++++++++++++++++++++ build/ab.mk | 1 + config.py | 28 +++++++++++++++++++++++++--- src/arch/bbcmicro/build.py | 21 +++++++++++++++++++-- 4 files changed, 79 insertions(+), 5 deletions(-) diff --git a/apps/build.py b/apps/build.py index 2bb4671b..a4ec58a5 100644 --- a/apps/build.py +++ b/apps/build.py @@ -1,4 +1,38 @@ +from build.ab import Rule, Target, Targets, normalrule from build.llvm import llvmprogram + +@Rule +def asm(self, name, src: Target = None, deps: Targets = []): + normalrule( + replaces=self, + ins=[src], + outs=["out.com"], + deps=["tools/cpmemu", "apps+asm"] + deps, + commands=[ + "chronic {deps[0]} {deps[1]} -pA=$(dir {ins[0]}) -pB=$(dir {outs[0]})" + + " a:$(notdir {ins[0]}) b:$(notdir {outs[0]})", + "test -f {outs[0]}", + ], + label="ASM", + ) + + +# CP/M-65 assembler programs. + +for prog in [ + "bedit", + "capsdrv", + "cls", + "cpuinfo", + "devices", + "dinfo", + "dump", + "ls", +]: + asm(name=prog, src=("./%s.asm" % prog), deps=["./cpm65.inc"]) + +# Simple C programs. + for prog in ["asm", "copy", "stat", "submit", "objdump", "qe", "life"]: llvmprogram(name=prog, srcs=["./%s.c" % prog], deps=["lib+cpm65"]) diff --git a/build/ab.mk b/build/ab.mk index fdff03ad..aa5d2395 100644 --- a/build/ab.mk +++ b/build/ab.mk @@ -30,6 +30,7 @@ EXT ?= include $(OBJ)/build.mk .SECONDARY: +.DELETE_ON_ERROR: .PHONY: update-ab update-ab: diff --git a/config.py b/config.py index 7e2dbf3c..c92b7a01 100644 --- a/config.py +++ b/config.py @@ -1,13 +1,35 @@ MINIMAL_APPS = { "0:asm.com": "apps+asm", + "0:bedit.com": "apps+bedit", + "0:capsdrv.com": "apps+capsdrv", "0:copy.com": "apps+copy", + "0:cpuinfo.com": "apps+cpuinfo", + "0:devices.com": "apps+devices", + "0:dinfo.com": "apps+dinfo", + "0:dump.com": "apps+dump", + "0:ls.com": "apps+ls", "0:stat.com": "apps+stat", "0:submit.com": "apps+submit", } -APPS = MINIMAL_APPS | { +MINIMAL_APPS_SRCS = { + "0:dump.asm": "apps/dump.asm", + "0:ls.asm": "apps/ls.asm", + "0:cpm65.inc": "apps/cpm65.inc", + "0:drivers.inc": "apps/drivers.inc", +} + +BIG_APPS = { + "0:atbasic.com": "third_party/altirrabasic", + "0:objdump.com": "apps+objdump", +} + +BIG_APPS_SRCS = {} + +SCREEN_APPS = { + "0:cls.com": "apps+cls", "0:life.com": "apps+life", "0:qe.com": "apps+qe", - "0:objdump.com": "apps+objdump", - "0:atbasic.com": "third_party/altirrabasic", } + +SCREEN_APPS_SRCS = {"0:cls.asm": "apps/cls.asm"} diff --git a/src/arch/bbcmicro/build.py b/src/arch/bbcmicro/build.py index dd741b32..7a99d391 100644 --- a/src/arch/bbcmicro/build.py +++ b/src/arch/bbcmicro/build.py @@ -1,7 +1,14 @@ from build.ab import normalrule from tools.build import mkdfs, mkcpmfs from build.llvm import llvmrawprogram -from config import APPS +from config import ( + MINIMAL_APPS, + MINIMAL_APPS_SRCS, + BIG_APPS, + BIG_APPS_SRCS, + SCREEN_APPS, + SCREEN_APPS_SRCS, +) llvmrawprogram( name="bios", @@ -10,7 +17,17 @@ linkscript="./bbcmicro.ld", ) -mkcpmfs(name="cpmfs", format="bbc192", items={"0:ccp.sys": "src+ccp"} | APPS) +mkcpmfs( + name="cpmfs", + format="bbc192", + items={"0:ccp.sys": "src+ccp"} + | MINIMAL_APPS + | MINIMAL_APPS_SRCS + | BIG_APPS + | BIG_APPS_SRCS + | SCREEN_APPS + | SCREEN_APPS_SRCS, +) mkdfs( name="diskimage", From 15b7224b602c1993fa2e7f1ed0a81073956aa1bc Mon Sep 17 00:00:00 2001 From: David Given Date: Sat, 16 Dec 2023 13:59:28 +0000 Subject: [PATCH 09/23] Make the Oric BIOS build. --- build.py | 1 + build/ab.py | 29 ++++++------ build/c.py | 5 ++ build/llvm.py | 4 +- scripts/size.awk | 7 +++ src/arch/oric/build.py | 54 ++++++++++++++++++++++ {scripts => src/arch/oric}/oric-common.ld | 0 {scripts => src/arch/oric}/oric-prelink.ld | 2 +- src/{bios => arch/oric}/oric.S | 0 {scripts => src/arch/oric}/oric.ld | 2 +- tools/build.py | 13 ++++-- 11 files changed, 96 insertions(+), 21 deletions(-) create mode 100644 scripts/size.awk create mode 100644 src/arch/oric/build.py rename {scripts => src/arch/oric}/oric-common.ld (100%) rename {scripts => src/arch/oric}/oric-prelink.ld (93%) rename src/{bios => arch/oric}/oric.S (100%) rename {scripts => src/arch/oric}/oric.ld (93%) diff --git a/build.py b/build.py index c4b606d7..4f571653 100644 --- a/build.py +++ b/build.py @@ -11,5 +11,6 @@ "bin/mads": "third_party/mads", "bin/atbasic.com": "third_party/altirrabasic", "bbcmicro.ssd": "src/arch/bbcmicro+diskimage", + "oric.dsk": "src/arch/oric+diskimage", }, ) diff --git a/build/ab.py b/build/ab.py index 75c4e8e8..9fe746f2 100644 --- a/build/ab.py +++ b/build/ab.py @@ -2,7 +2,6 @@ from os.path import * from types import SimpleNamespace import argparse -import copy import functools import importlib import importlib.abc @@ -10,10 +9,8 @@ import inspect import re import sys -import types -import pathlib import builtins -import os +import string defaultGlobals = {} targets = {} @@ -329,16 +326,20 @@ def emit(*args): def templateexpand(s, invocation): - class Converter: - def __getitem__(self, key): - if key == "self": - return invocation - f = filenamesof(invocation.args[key]) - if isinstance(f, Sequence): - f = ParameterList(f) - return f - - return eval("f%r" % s, invocation.callback.__globals__, Converter()) + class Formatter(string.Formatter): + def get_field(self, name, a1, a2): + return ( + eval(name, invocation.callback.__globals__, invocation.args), + False, + ) + + def format_field(self, value, format_spec): + if type(self) == str: + return value + return " ".join( + [templateexpand(f, invocation) for f in filenamesof(value)] + ) + return Formatter().format(s) def emitter_rule(name, ins, outs, deps=[]): diff --git a/build/c.py b/build/c.py index 12edf81b..04d5b626 100644 --- a/build/c.py +++ b/build/c.py @@ -16,6 +16,11 @@ def cfileimpl(self, name, srcs, deps, suffix, commands, label, kind, cflags): + libraries = [d for d in deps if hasattr(d, "clibrary")] + for library in libraries: + if library.clibrary.cflags: + cflags += library.clibrary.cflags + outleaf = stripext(basename(filenameof(srcs[0]))) + suffix normalrule( diff --git a/build/llvm.py b/build/llvm.py index 28be2869..74b23bfb 100644 --- a/build/llvm.py +++ b/build/llvm.py @@ -55,14 +55,14 @@ def llvmrawprogram( linkscript: Target, deps: Targets = None, commands=[ - "$(LD6502) -Map {outs[0]}.map, -T {deps[0]} -o {outs[0]} {ins} {ldflags}" + "$(LD6502) -Map {outs[0]}.map -T {deps[-1]} -o {outs[0]} {ins} {ldflags}" ], label="LD6502", **kwargs ): cprogram( replaces=self, - deps=[linkscript] + deps, + deps=deps + [linkscript], commands=commands, label=label, cfilerule=llvmcfile, diff --git a/scripts/size.awk b/scripts/size.awk new file mode 100644 index 00000000..41974095 --- /dev/null +++ b/scripts/size.awk @@ -0,0 +1,7 @@ +/ [0-9]+/ { + size[$2] = ("0x"$3)+0 +} + +END { + print(size[".text"] + size[".data"] + size[".bss"]) +} diff --git a/src/arch/oric/build.py b/src/arch/oric/build.py new file mode 100644 index 00000000..81640ed5 --- /dev/null +++ b/src/arch/oric/build.py @@ -0,0 +1,54 @@ +from build.ab import normalrule +from tools.build import mkdfs, mkcpmfs +from build.llvm import llvmrawprogram, llvmcfile +from config import ( + MINIMAL_APPS, + MINIMAL_APPS_SRCS, + BIG_APPS, + BIG_APPS_SRCS, + SCREEN_APPS, + SCREEN_APPS_SRCS, +) + +llvmcfile( + name="bios_obj", + srcs=["./oric.S"], + deps=["include", "src/lib+bioslib"], +) + +llvmrawprogram( + name="bios_prelink", + srcs=[".+bios_obj"], + deps=["src/lib+bioslib", "./oric-common.ld"], + linkscript="./oric-prelink.ld", + ldflags=["--defsym=BIOS_SIZE=0x4000"], +) + +llvmrawprogram( + name="bios", + srcs=[".+bios_obj"], + deps=[ + ".+bios_prelink", + "scripts/size.awk", + "src/lib+bioslib", + "./oric-common.ld", + ], + linkscript="./oric.ld", + ldflags=[ + "--defsym=BIOS_SIZE=$$($(LLVM)/llvm-objdump --section-headers {deps[0]} " + + "| gawk --non-decimal-data -f scripts/size.awk)" + ], +) + +mkcpmfs( + name="diskimage", + format="oric", + bootimage=".+bios", + items={"0:ccp.sys": "src+ccp"} + | MINIMAL_APPS + | MINIMAL_APPS_SRCS + | BIG_APPS + | BIG_APPS_SRCS + | SCREEN_APPS + | SCREEN_APPS_SRCS, +) diff --git a/scripts/oric-common.ld b/src/arch/oric/oric-common.ld similarity index 100% rename from scripts/oric-common.ld rename to src/arch/oric/oric-common.ld diff --git a/scripts/oric-prelink.ld b/src/arch/oric/oric-prelink.ld similarity index 93% rename from scripts/oric-prelink.ld rename to src/arch/oric/oric-prelink.ld index f6cf46d4..a5b6ff38 100644 --- a/scripts/oric-prelink.ld +++ b/src/arch/oric/oric-prelink.ld @@ -20,5 +20,5 @@ SECTIONS { *(sector3) } - INCLUDE "scripts/oric-common.ld" + INCLUDE "src/arch/oric/oric-common.ld" } diff --git a/src/bios/oric.S b/src/arch/oric/oric.S similarity index 100% rename from src/bios/oric.S rename to src/arch/oric/oric.S diff --git a/scripts/oric.ld b/src/arch/oric/oric.ld similarity index 93% rename from scripts/oric.ld rename to src/arch/oric/oric.ld index ba70559a..f439311a 100644 --- a/scripts/oric.ld +++ b/src/arch/oric/oric.ld @@ -22,7 +22,7 @@ SECTIONS { . = ALIGN(256); } >microdiscboot AT>initram - INCLUDE "scripts/oric-common.ld" + INCLUDE "src/arch/oric/oric-common.ld" } OUTPUT_FORMAT { diff --git a/tools/build.py b/tools/build.py index d92a39e6..bba9a63e 100644 --- a/tools/build.py +++ b/tools/build.py @@ -35,8 +35,15 @@ def xextobin(self, name=None, src: Target = None, address=0): @Rule -def mkcpmfs(self, name, format, items: TargetsMap = {}): - cs = ["mkfs.cpm -f %s {outs[0]}" % format] +def mkcpmfs( + self, name, format, bootimage: Target = None, items: TargetsMap = {} +): + mkfs = "mkfs.cpm -f %s" % format + if bootimage: + mkfs += " -b %s" % filenameof(bootimage) + mkfs += " {outs[0]}" + + cs = [mkfs] ins = [] for k, v in items.items(): cs += ["cpmcp -f %s {outs[0]} %s %s" % (format, filenameof(v), k)] @@ -46,7 +53,7 @@ def mkcpmfs(self, name, format, items: TargetsMap = {}): replaces=self, ins=ins, outs=[name + ".img"], - deps=["diskdefs"], + deps=["diskdefs"] + [bootimage] if bootimage else [], commands=cs, label="MKCPMFS", ) From 7e28c4a63ddcc007aa597e3db65c7c30dc4c1b18 Mon Sep 17 00:00:00 2001 From: David Given Date: Sat, 16 Dec 2023 14:12:24 +0000 Subject: [PATCH 10/23] Make the Apple II port build. --- build.py | 1 + build/ab.py | 1 + .../arch/apple2e}/apple2e-prelink.ld | 0 src/{bios => arch/apple2e}/apple2e.S | 0 {scripts => src/arch/apple2e}/apple2e.ld | 0 src/arch/apple2e/build.py | 61 +++++++++++++++++++ tools/build.py | 20 +++++- tools/shuffle.cc | 12 +++- 8 files changed, 90 insertions(+), 5 deletions(-) rename {scripts => src/arch/apple2e}/apple2e-prelink.ld (100%) rename src/{bios => arch/apple2e}/apple2e.S (100%) rename {scripts => src/arch/apple2e}/apple2e.ld (100%) create mode 100644 src/arch/apple2e/build.py diff --git a/build.py b/build.py index 4f571653..d52fff72 100644 --- a/build.py +++ b/build.py @@ -12,5 +12,6 @@ "bin/atbasic.com": "third_party/altirrabasic", "bbcmicro.ssd": "src/arch/bbcmicro+diskimage", "oric.dsk": "src/arch/oric+diskimage", + "apple2e.po": "src/arch/apple2e+diskimage", }, ) diff --git a/build/ab.py b/build/ab.py index 9fe746f2..61d948c3 100644 --- a/build/ab.py +++ b/build/ab.py @@ -339,6 +339,7 @@ def format_field(self, value, format_spec): return " ".join( [templateexpand(f, invocation) for f in filenamesof(value)] ) + return Formatter().format(s) diff --git a/scripts/apple2e-prelink.ld b/src/arch/apple2e/apple2e-prelink.ld similarity index 100% rename from scripts/apple2e-prelink.ld rename to src/arch/apple2e/apple2e-prelink.ld diff --git a/src/bios/apple2e.S b/src/arch/apple2e/apple2e.S similarity index 100% rename from src/bios/apple2e.S rename to src/arch/apple2e/apple2e.S diff --git a/scripts/apple2e.ld b/src/arch/apple2e/apple2e.ld similarity index 100% rename from scripts/apple2e.ld rename to src/arch/apple2e/apple2e.ld diff --git a/src/arch/apple2e/build.py b/src/arch/apple2e/build.py new file mode 100644 index 00000000..a0f7f22d --- /dev/null +++ b/src/arch/apple2e/build.py @@ -0,0 +1,61 @@ +from build.ab import normalrule +from tools.build import mkdfs, mkcpmfs, shuffle +from build.llvm import llvmrawprogram, llvmcfile +from config import ( + MINIMAL_APPS, + MINIMAL_APPS_SRCS, + BIG_APPS, + BIG_APPS_SRCS, + SCREEN_APPS, + SCREEN_APPS_SRCS, +) + +llvmcfile( + name="bios_obj", + srcs=["./apple2e.S"], + deps=["include", "src/lib+bioslib"], +) + +llvmrawprogram( + name="bios_prelink", + srcs=[".+bios_obj"], + deps=["src/lib+bioslib"], + linkscript="./apple2e-prelink.ld", + ldflags=["--defsym=BIOS_SIZE=0x4000"], +) + +llvmrawprogram( + name="bios", + srcs=[".+bios_obj"], + deps=[ + ".+bios_prelink", + "scripts/size.awk", + "src/lib+bioslib", + ], + linkscript="./apple2e.ld", + ldflags=[ + "--defsym=BIOS_SIZE=$$($(LLVM)/llvm-objdump --section-headers {deps[0]} " + + "| gawk --non-decimal-data -f scripts/size.awk)" + ], +) + +shuffle( + name="bios_shuffled", + src=".+bios", + blocksize=256, + blockspertrack=16, + map="02468ace13579bdf", +) + +mkcpmfs( + name="diskimage", + format="appleiie", + bootimage=".+bios_shuffled", + items={"0:ccp.sys": "src+ccp"} + | MINIMAL_APPS + | MINIMAL_APPS_SRCS + | BIG_APPS + | BIG_APPS_SRCS + | SCREEN_APPS + | SCREEN_APPS_SRCS, +) diff --git a/tools/build.py b/tools/build.py index bba9a63e..5038e22f 100644 --- a/tools/build.py +++ b/tools/build.py @@ -2,10 +2,9 @@ from build.c import cxxprogram, cprogram cxxprogram(name="multilink", srcs=["./multilink.cc"], deps=["+libfmt"]) - cxxprogram(name="xextobin", srcs=["./xextobin.cc"], deps=["+libfmt"]) - cprogram(name="mkdfs", srcs=["./mkdfs.c"], deps=["+libfmt"]) +cxxprogram(name="shuffle", srcs=["./shuffle.cc"], deps=["+libfmt"]) @Rule @@ -86,3 +85,20 @@ def mkdfs( ], label="MKDFS", ) + + +@Rule +def shuffle( + self, name, src: Target = None, blocksize=256, blockspertrack=16, map="" +): + normalrule( + replaces=self, + ins=[src], + outs=[name + ".bin"], + deps=["tools+shuffle"], + commands=[ + "{deps[0]} -i {ins[0]} -o {outs[0]} -b %d -t %d -r -m %s" + % (blocksize, blockspertrack, map) + ], + label="SHUFFLE", + ) diff --git a/tools/shuffle.cc b/tools/shuffle.cc index 7524c1d3..6ffca603 100644 --- a/tools/shuffle.cc +++ b/tools/shuffle.cc @@ -9,6 +9,7 @@ #include #include #include +#include static int blocksize = 256; static int blockspertrack = 16; @@ -16,6 +17,7 @@ static std::string mappingstring = "0123456789abcdef"; static std::string infilename; static std::string outfilename; static bool reverse = false; +static bool verbose = false; static std::string readfile(std::ifstream& in) { @@ -49,8 +51,8 @@ static void write_file() int inblocks = (infile.size() + blocksize - 1) / blocksize; int tracks = (inblocks + blockspertrack - 1) / blockspertrack; - std::cout << "file size: " << tracks << " tracks of " << blockspertrack - << " blocks\n"; + if (verbose) + fmt::print("file size: {} tracks of {} blocks\n", tracks, blockspertrack); infile.resize(tracks * blockspertrack * blocksize); std::map mapping; @@ -110,10 +112,14 @@ int main(int argc, char* const argv[]) reverse = true; break; + case 'v': + verbose = true; + break; + default: fprintf(stderr, "Usage: shuffle -i -o -b -t " - " -m \n"); + " -m [-v] [-r]\n"); exit(1); } } From 45cd46fe6597367258d24cd9da4490c514327f1a Mon Sep 17 00:00:00 2001 From: David Given Date: Sat, 16 Dec 2023 21:26:56 +0000 Subject: [PATCH 11/23] Make the Atari ports build. --- build.py | 3 + src/arch/apple2e/build.py | 2 +- src/{bios => arch/atari800}/atari800.S | 0 {include => src/arch/atari800}/atari800.inc | 0 {scripts => src/arch/atari800}/atari800.ld | 0 {scripts => src/arch/atari800}/atari800hd.ld | 0 .../arch/atari800}/atari800xlhd.ld | 0 src/arch/atari800/build.py | 122 ++++++++++++++++++ src/arch/atari800/utils/build.py | 13 ++ .../arch/atari800/utils/setfnt.c | 0 .../arch/atari800/utils/tty80drv.S | 4 +- src/arch/oric/build.py | 2 +- src/bios/atari800hd.S | 1 - src/bios/atari800xlhd.S | 1 - third_party/fonts/atari/build.py | 5 + tools/build.py | 15 ++- 16 files changed, 161 insertions(+), 7 deletions(-) rename src/{bios => arch/atari800}/atari800.S (100%) rename {include => src/arch/atari800}/atari800.inc (100%) rename {scripts => src/arch/atari800}/atari800.ld (100%) rename {scripts => src/arch/atari800}/atari800hd.ld (100%) rename {scripts => src/arch/atari800}/atari800xlhd.ld (100%) create mode 100644 src/arch/atari800/build.py create mode 100644 src/arch/atari800/utils/build.py rename apps/a8setfnt.c => src/arch/atari800/utils/setfnt.c (100%) rename apps/a8tty80drv.S => src/arch/atari800/utils/tty80drv.S (99%) delete mode 120000 src/bios/atari800hd.S delete mode 120000 src/bios/atari800xlhd.S create mode 100644 third_party/fonts/atari/build.py diff --git a/build.py b/build.py index d52fff72..e18e56c2 100644 --- a/build.py +++ b/build.py @@ -13,5 +13,8 @@ "bbcmicro.ssd": "src/arch/bbcmicro+diskimage", "oric.dsk": "src/arch/oric+diskimage", "apple2e.po": "src/arch/apple2e+diskimage", + "atari800.atr": "src/arch/atari800+atari800_diskimage", + "atari800hd.atr": "src/arch/atari800+atari800hd_diskimage", + "atari800xlhd.atr": "src/arch/atari800+atari800xlhd_diskimage", }, ) diff --git a/src/arch/apple2e/build.py b/src/arch/apple2e/build.py index a0f7f22d..5a5760e8 100644 --- a/src/arch/apple2e/build.py +++ b/src/arch/apple2e/build.py @@ -51,7 +51,7 @@ name="diskimage", format="appleiie", bootimage=".+bios_shuffled", - items={"0:ccp.sys": "src+ccp"} + items={"0:ccp.sys": "src+ccp", "0:bdos.sys": "src+bdos"} | MINIMAL_APPS | MINIMAL_APPS_SRCS | BIG_APPS diff --git a/src/bios/atari800.S b/src/arch/atari800/atari800.S similarity index 100% rename from src/bios/atari800.S rename to src/arch/atari800/atari800.S diff --git a/include/atari800.inc b/src/arch/atari800/atari800.inc similarity index 100% rename from include/atari800.inc rename to src/arch/atari800/atari800.inc diff --git a/scripts/atari800.ld b/src/arch/atari800/atari800.ld similarity index 100% rename from scripts/atari800.ld rename to src/arch/atari800/atari800.ld diff --git a/scripts/atari800hd.ld b/src/arch/atari800/atari800hd.ld similarity index 100% rename from scripts/atari800hd.ld rename to src/arch/atari800/atari800hd.ld diff --git a/scripts/atari800xlhd.ld b/src/arch/atari800/atari800xlhd.ld similarity index 100% rename from scripts/atari800xlhd.ld rename to src/arch/atari800/atari800xlhd.ld diff --git a/src/arch/atari800/build.py b/src/arch/atari800/build.py new file mode 100644 index 00000000..4c54e25f --- /dev/null +++ b/src/arch/atari800/build.py @@ -0,0 +1,122 @@ +from build.ab import normalrule +from tools.build import mkcpmfs +from build.llvm import llvmrawprogram, llvmclibrary +from config import ( + MINIMAL_APPS, + MINIMAL_APPS_SRCS, + BIG_APPS, + BIG_APPS_SRCS, + SCREEN_APPS, + SCREEN_APPS_SRCS, +) + +llvmclibrary(name="headers", hdrs={"atari800.inc": "./atari800.inc"}) + +llvmrawprogram( + name="atari800_bios", + srcs=["./atari800.S"], + deps=["include", "src/lib+bioslib", ".+headers"], + linkscript="./atari800.ld", +) + +mkcpmfs( + name="atari800_rawdiskimage", + format="atari90", + bootimage=".+atari800_bios", + items={ + "0:ccp.sys": "src+ccp", + "0:bdos.sys": "src+bdos", + "0:setfnt.com": "src/arch/atari800/utils+setfnt", + "0:tty80drv.com": "src/arch/atari800/utils+tty80drv", + "0:olivetti.fnt": "third_party/fonts/atari/olivetti.fnt", + } + | MINIMAL_APPS + | BIG_APPS, +) + +normalrule( + name="atari800_diskimage", + ins=[".+atari800_rawdiskimage"], + outs=["atari80.atr"], + commands=[ + r"/usr/bin/printf '\x96\x02\x80\x16\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' > {outs[0]}", + "cat {ins[0]} >> {outs[0]}", + ], + label="MAKEATR", +) + +llvmrawprogram( + name="atari800hd_bios", + srcs=["./atari800.S"], + deps=["include", "src/lib+bioslib", ".+headers"], + cflags=["-DATARI_HD"], + linkscript="./atari800hd.ld", +) + +mkcpmfs( + name="atari800hd_rawdiskimage", + format="atarihd", + bootimage=".+atari800hd_bios", + items={ + "0:ccp.sys": "src+ccp", + "0:bdos.sys": "src+bdos", + "0:setfnt.com": "src/arch/atari800/utils+setfnt", + "0:tty80drv.com": "src/arch/atari800/utils+tty80drv", + "1:olivetti.fnt": "third_party/fonts/atari/olivetti.fnt", + } + | MINIMAL_APPS + | MINIMAL_APPS_SRCS + | BIG_APPS + | BIG_APPS_SRCS + | SCREEN_APPS + | SCREEN_APPS_SRCS +) + +normalrule( + name="atari800hd_diskimage", + ins=[".+atari800hd_rawdiskimage"], + outs=["atari80hd.atr"], + commands=[ + r"/usr/bin/printf '\x96\x02\xf0\xff\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' > {outs[0]}", + "cat {ins[0]} >> {outs[0]}", + ], + label="MAKEATR", +) + +llvmrawprogram( + name="atari800xlhd_bios", + srcs=["./atari800.S"], + deps=["include", "src/lib+bioslib", ".+headers"], + cflags=["-DATARI_HD", "-DATARI_XL"], + linkscript="./atari800xlhd.ld", +) + +mkcpmfs( + name="atari800xlhd_rawdiskimage", + format="atarihd", + bootimage=".+atari800xlhd_bios", + items={ + "0:ccp.sys": "src+ccp", + "0:bdos.sys": "src+bdos", + "0:setfnt.com": "src/arch/atari800/utils+setfnt", + "0:tty80drv.com": "src/arch/atari800/utils+tty80drv", + "1:olivetti.fnt": "third_party/fonts/atari/olivetti.fnt", + } + | MINIMAL_APPS + | MINIMAL_APPS_SRCS + | BIG_APPS + | BIG_APPS_SRCS + | SCREEN_APPS + | SCREEN_APPS_SRCS +) + +normalrule( + name="atari800xlhd_diskimage", + ins=[".+atari800xlhd_rawdiskimage"], + outs=["atari80xlhd.atr"], + commands=[ + r"/usr/bin/printf '\x96\x02\xf0\xff\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' > {outs[0]}", + "cat {ins[0]} >> {outs[0]}", + ], + label="MAKEATR", +) diff --git a/src/arch/atari800/utils/build.py b/src/arch/atari800/utils/build.py new file mode 100644 index 00000000..610441cc --- /dev/null +++ b/src/arch/atari800/utils/build.py @@ -0,0 +1,13 @@ +from build.llvm import llvmprogram + +llvmprogram(name="setfnt", srcs=["./setfnt.c"], deps=["lib+cpm65"]) + +llvmprogram( + name="tty80drv", + srcs=["./tty80drv.S"], + deps=[ + "include", + "src/arch/atari800+headers", + "third_party/fonts/atari+ivo3x6", + ], +) diff --git a/apps/a8setfnt.c b/src/arch/atari800/utils/setfnt.c similarity index 100% rename from apps/a8setfnt.c rename to src/arch/atari800/utils/setfnt.c diff --git a/apps/a8tty80drv.S b/src/arch/atari800/utils/tty80drv.S similarity index 99% rename from apps/a8tty80drv.S rename to src/arch/atari800/utils/tty80drv.S index 3f024f13..29e82c45 100644 --- a/apps/a8tty80drv.S +++ b/src/arch/atari800/utils/tty80drv.S @@ -38,7 +38,7 @@ #include "zif.inc" ; force to include the clang version and not the asm.com version -#include "include/cpm65.inc" +#include "cpm65.inc" #include "atari800.inc" #include "driver.inc" @@ -834,7 +834,7 @@ banner: ; position) equals 576 bytes font: - #include "../third_party/fonts/atari/ivo3x6.inc" + #include "third_party/fonts/atari/ivo3x6.inc" ; ------------------------------------------------------------------------- diff --git a/src/arch/oric/build.py b/src/arch/oric/build.py index 81640ed5..1bb1072c 100644 --- a/src/arch/oric/build.py +++ b/src/arch/oric/build.py @@ -44,7 +44,7 @@ name="diskimage", format="oric", bootimage=".+bios", - items={"0:ccp.sys": "src+ccp"} + items={"0:ccp.sys": "src+ccp", "0:bdos.sys": "src+bdos"} | MINIMAL_APPS | MINIMAL_APPS_SRCS | BIG_APPS diff --git a/src/bios/atari800hd.S b/src/bios/atari800hd.S deleted file mode 120000 index c14d3dda..00000000 --- a/src/bios/atari800hd.S +++ /dev/null @@ -1 +0,0 @@ -atari800.S \ No newline at end of file diff --git a/src/bios/atari800xlhd.S b/src/bios/atari800xlhd.S deleted file mode 120000 index c14d3dda..00000000 --- a/src/bios/atari800xlhd.S +++ /dev/null @@ -1 +0,0 @@ -atari800.S \ No newline at end of file diff --git a/third_party/fonts/atari/build.py b/third_party/fonts/atari/build.py new file mode 100644 index 00000000..c9b4df93 --- /dev/null +++ b/third_party/fonts/atari/build.py @@ -0,0 +1,5 @@ +from build.llvm import llvmclibrary + +llvmclibrary( + name="ivo3x6", hdrs={"third_party/fonts/atari/ivo3x6.inc": "./ivo3x6.inc"} +) diff --git a/tools/build.py b/tools/build.py index 5038e22f..6110599a 100644 --- a/tools/build.py +++ b/tools/build.py @@ -3,8 +3,9 @@ cxxprogram(name="multilink", srcs=["./multilink.cc"], deps=["+libfmt"]) cxxprogram(name="xextobin", srcs=["./xextobin.cc"], deps=["+libfmt"]) -cprogram(name="mkdfs", srcs=["./mkdfs.c"], deps=["+libfmt"]) cxxprogram(name="shuffle", srcs=["./shuffle.cc"], deps=["+libfmt"]) +cprogram(name="mkdfs", srcs=["./mkdfs.c"]) +cprogram(name="fontconvert", srcs=["./fontconvert.c"]) @Rule @@ -102,3 +103,15 @@ def shuffle( ], label="SHUFFLE", ) + + +@Rule +def fontconvert(self, name, src: Target = None): + normalrule( + replaces=self, + ins=[src], + outs=[name + ".inc"], + deps=["tools+fontconvert"], + commands=["{deps[0]} {ins[0]} > {outs[0]}"], + label="FONTCONVERT", + ) From 8a710748eb57364d83854e4fb527a40583e107f8 Mon Sep 17 00:00:00 2001 From: David Given Date: Sat, 16 Dec 2023 22:27:08 +0000 Subject: [PATCH 12/23] Make Oric disks actually work. --- src/arch/oric/build.py | 8 ++++++-- tools/build.py | 11 +++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/arch/oric/build.py b/src/arch/oric/build.py index 1bb1072c..85150716 100644 --- a/src/arch/oric/build.py +++ b/src/arch/oric/build.py @@ -1,5 +1,5 @@ from build.ab import normalrule -from tools.build import mkdfs, mkcpmfs +from tools.build import mkcpmfs, mkoricdsk from build.llvm import llvmrawprogram, llvmcfile from config import ( MINIMAL_APPS, @@ -41,7 +41,7 @@ ) mkcpmfs( - name="diskimage", + name="cpmfs", format="oric", bootimage=".+bios", items={"0:ccp.sys": "src+ccp", "0:bdos.sys": "src+bdos"} @@ -52,3 +52,7 @@ | SCREEN_APPS | SCREEN_APPS_SRCS, ) + +mkoricdsk( + name="diskimage", + src=".+cpmfs") diff --git a/tools/build.py b/tools/build.py index 6110599a..6644e40c 100644 --- a/tools/build.py +++ b/tools/build.py @@ -4,6 +4,7 @@ cxxprogram(name="multilink", srcs=["./multilink.cc"], deps=["+libfmt"]) cxxprogram(name="xextobin", srcs=["./xextobin.cc"], deps=["+libfmt"]) cxxprogram(name="shuffle", srcs=["./shuffle.cc"], deps=["+libfmt"]) +cxxprogram(name="mkoricdsk", srcs=["./mkoricdsk.cc"], deps=["+libfmt"]) cprogram(name="mkdfs", srcs=["./mkdfs.c"]) cprogram(name="fontconvert", srcs=["./fontconvert.c"]) @@ -115,3 +116,13 @@ def fontconvert(self, name, src: Target = None): commands=["{deps[0]} {ins[0]} > {outs[0]}"], label="FONTCONVERT", ) + +@Rule +def mkoricdsk(self, name, src:Target=None): + normalrule( + replaces=self, + ins=[src], + outs=[name+".img"], + deps=["tools+mkoricdsk"], + commands=["{deps[0]} -i {ins[0]} -o {outs[0]}"], + label="MKORICDSK") From e90be46ebb20c2d9c2f6d38e339e15ef0a9169f0 Mon Sep 17 00:00:00 2001 From: David Given Date: Sat, 16 Dec 2023 22:36:54 +0000 Subject: [PATCH 13/23] Apple II disks boot. --- src/arch/apple2e/build.py | 3 +-- src/arch/atari800/build.py | 4 ++-- src/arch/oric/build.py | 4 +--- tools/build.py | 18 ++++++++++++++---- 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/arch/apple2e/build.py b/src/arch/apple2e/build.py index 5a5760e8..57df49aa 100644 --- a/src/arch/apple2e/build.py +++ b/src/arch/apple2e/build.py @@ -51,11 +51,10 @@ name="diskimage", format="appleiie", bootimage=".+bios_shuffled", + size=143360, items={"0:ccp.sys": "src+ccp", "0:bdos.sys": "src+bdos"} | MINIMAL_APPS | MINIMAL_APPS_SRCS | BIG_APPS | BIG_APPS_SRCS - | SCREEN_APPS - | SCREEN_APPS_SRCS, ) diff --git a/src/arch/atari800/build.py b/src/arch/atari800/build.py index 4c54e25f..100414ea 100644 --- a/src/arch/atari800/build.py +++ b/src/arch/atari800/build.py @@ -69,7 +69,7 @@ | BIG_APPS | BIG_APPS_SRCS | SCREEN_APPS - | SCREEN_APPS_SRCS + | SCREEN_APPS_SRCS, ) normalrule( @@ -107,7 +107,7 @@ | BIG_APPS | BIG_APPS_SRCS | SCREEN_APPS - | SCREEN_APPS_SRCS + | SCREEN_APPS_SRCS, ) normalrule( diff --git a/src/arch/oric/build.py b/src/arch/oric/build.py index 85150716..577b28bf 100644 --- a/src/arch/oric/build.py +++ b/src/arch/oric/build.py @@ -53,6 +53,4 @@ | SCREEN_APPS_SRCS, ) -mkoricdsk( - name="diskimage", - src=".+cpmfs") +mkoricdsk(name="diskimage", src=".+cpmfs") diff --git a/tools/build.py b/tools/build.py index 6644e40c..7e4c7b29 100644 --- a/tools/build.py +++ b/tools/build.py @@ -37,7 +37,12 @@ def xextobin(self, name=None, src: Target = None, address=0): @Rule def mkcpmfs( - self, name, format, bootimage: Target = None, items: TargetsMap = {} + self, + name, + format, + bootimage: Target = None, + size=None, + items: TargetsMap = {}, ): mkfs = "mkfs.cpm -f %s" % format if bootimage: @@ -50,6 +55,9 @@ def mkcpmfs( cs += ["cpmcp -f %s {outs[0]} %s %s" % (format, filenameof(v), k)] ins += [v] + if size: + cs += ["truncate -s %d {outs[0]}" % size] + normalrule( replaces=self, ins=ins, @@ -117,12 +125,14 @@ def fontconvert(self, name, src: Target = None): label="FONTCONVERT", ) + @Rule -def mkoricdsk(self, name, src:Target=None): +def mkoricdsk(self, name, src: Target = None): normalrule( replaces=self, ins=[src], - outs=[name+".img"], + outs=[name + ".img"], deps=["tools+mkoricdsk"], commands=["{deps[0]} -i {ins[0]} -o {outs[0]}"], - label="MKORICDSK") + label="MKORICDSK", + ) From d505b9a42d45be2174729c850f29168c781e7b2d Mon Sep 17 00:00:00 2001 From: David Given Date: Sat, 16 Dec 2023 23:01:14 +0000 Subject: [PATCH 14/23] Turns out llvm needs ninja. --- .github/workflows/ccpp.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml index 8be1106a..74b4c131 100644 --- a/.github/workflows/ccpp.yml +++ b/.github/workflows/ccpp.yml @@ -18,7 +18,7 @@ jobs: run: echo "MOS_SDK_VERSION=$(cd llvm-mos-sdk && git rev-parse --short HEAD)" >> $GITHUB_ENV - name: apt - run: sudo apt update && sudo apt install cc1541 cpmtools libfmt-dev fp-compiler moreutils + run: sudo apt update && sudo apt install cc1541 cpmtools libfmt-dev fp-compiler moreutils ninja-build - name: cache llvm-mos id: cache-llvm-mos From 1aded149e426d4628d6da0b32921ad94bb813d5e Mon Sep 17 00:00:00 2001 From: David Given Date: Sat, 16 Dec 2023 23:18:02 +0000 Subject: [PATCH 15/23] Try using the precompiled llvm-mos binary. --- .github/workflows/ccpp.yml | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml index 74b4c131..f93cb33c 100644 --- a/.github/workflows/ccpp.yml +++ b/.github/workflows/ccpp.yml @@ -20,21 +20,10 @@ jobs: - name: apt run: sudo apt update && sudo apt install cc1541 cpmtools libfmt-dev fp-compiler moreutils ninja-build - - name: cache llvm-mos - id: cache-llvm-mos - uses: actions/cache@v3 - env: - cache-name: cache-llvm-mos - with: - path: ~/llvm-mos - key: ${{ runner.os }}-build-${{ env.cache-name }}-ver-${{ env.MOS_SDK_VERSION }} - - if: ${{ steps.cache-llvm-mos.outputs.cache-hit != 'true' }} name: install llvm-mos run: | - mkdir -p llvm-mos-sdk/build - (cd llvm-mos-sdk/build && cmake -G "Ninja" -DCMAKE_INSTALL_PREFIX=$HOME/llvm-mos ..) - (cd llvm-mos-sdk/build && ninja install) + curl https://github.com/llvm-mos/llvm-mos-sdk/releases/latest/download/llvm-mos-linux.tar.xz | tar -C $HOME xvJf - - name: make run: PATH=$PATH:$HOME/llvm-mos/bin make -C cpm65 LLVM= From 0a5b8bfe234b05241ae0a11d22343e3f7a385b5c Mon Sep 17 00:00:00 2001 From: David Given Date: Sat, 16 Dec 2023 23:19:06 +0000 Subject: [PATCH 16/23] Typo fix. --- .github/workflows/ccpp.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml index f93cb33c..edd2a04f 100644 --- a/.github/workflows/ccpp.yml +++ b/.github/workflows/ccpp.yml @@ -18,12 +18,12 @@ jobs: run: echo "MOS_SDK_VERSION=$(cd llvm-mos-sdk && git rev-parse --short HEAD)" >> $GITHUB_ENV - name: apt - run: sudo apt update && sudo apt install cc1541 cpmtools libfmt-dev fp-compiler moreutils ninja-build + run: sudo apt update && sudo apt install cc1541 cpmtools libfmt-dev fp-compiler moreutils - if: ${{ steps.cache-llvm-mos.outputs.cache-hit != 'true' }} name: install llvm-mos run: | - curl https://github.com/llvm-mos/llvm-mos-sdk/releases/latest/download/llvm-mos-linux.tar.xz | tar -C $HOME xvJf - + curl https://github.com/llvm-mos/llvm-mos-sdk/releases/latest/download/llvm-mos-linux.tar.xz | tar xvJf - -C $HOME - name: make run: PATH=$PATH:$HOME/llvm-mos/bin make -C cpm65 LLVM= From d45189259908ca720a1cd8cf8dc5ccef241ed4e8 Mon Sep 17 00:00:00 2001 From: David Given Date: Sat, 16 Dec 2023 23:21:36 +0000 Subject: [PATCH 17/23] Use wget, not curl. --- .github/workflows/ccpp.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml index edd2a04f..0bc48d00 100644 --- a/.github/workflows/ccpp.yml +++ b/.github/workflows/ccpp.yml @@ -23,7 +23,7 @@ jobs: - if: ${{ steps.cache-llvm-mos.outputs.cache-hit != 'true' }} name: install llvm-mos run: | - curl https://github.com/llvm-mos/llvm-mos-sdk/releases/latest/download/llvm-mos-linux.tar.xz | tar xvJf - -C $HOME + wget -O - https://github.com/llvm-mos/llvm-mos-sdk/releases/latest/download/llvm-mos-linux.tar.xz | tar xvJf - -C $HOME - name: make run: PATH=$PATH:$HOME/llvm-mos/bin make -C cpm65 LLVM= From 82e7f76f04dda0617530d5809ec5a171bcdb65ba Mon Sep 17 00:00:00 2001 From: David Given Date: Sat, 16 Dec 2023 23:23:28 +0000 Subject: [PATCH 18/23] Slowly getting there. --- .github/workflows/ccpp.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml index 0bc48d00..6dfabd56 100644 --- a/.github/workflows/ccpp.yml +++ b/.github/workflows/ccpp.yml @@ -23,10 +23,10 @@ jobs: - if: ${{ steps.cache-llvm-mos.outputs.cache-hit != 'true' }} name: install llvm-mos run: | - wget -O - https://github.com/llvm-mos/llvm-mos-sdk/releases/latest/download/llvm-mos-linux.tar.xz | tar xvJf - -C $HOME + wget -O - https://github.com/llvm-mos/llvm-mos-sdk/releases/latest/download/llvm-mos-linux.tar.xz | tar xJf - -C $HOME - name: make - run: PATH=$PATH:$HOME/llvm-mos/bin make -C cpm65 LLVM= + run: make -C cpm65 LLVM=$HOME/llvm-mos/bin - name: Upload build artifacts uses: actions/upload-artifact@v2 From 0425bdeca3edf5af290ff9bd839f45094f316cfb Mon Sep 17 00:00:00 2001 From: David Given Date: Sun, 17 Dec 2023 21:47:34 +0000 Subject: [PATCH 19/23] Make the main Commodore platforms build. --- build.py | 5 + scripts/pet4032.ld | 1 - scripts/pet8032.ld | 1 - src/arch/apple2e/build.py | 2 +- src/arch/commodore/build.py | 124 ++++++++++++ src/{bios => arch/commodore}/c64.S | 0 {scripts => src/arch/commodore}/c64.ld | 0 src/{bios => arch}/commodore/ieee488.S | 0 src/{bios => arch/commodore}/pet.S | 0 {scripts => src/arch/commodore}/pet.ld | 0 {scripts => src/arch/commodore}/pet8096.ld | 0 src/{bios => arch}/commodore/petscii.S | 0 src/{bios => arch/commodore}/vic20.S | 2 +- {scripts => src/arch/commodore}/vic20.ld | 0 src/{bios => arch/commodore}/x16.S | 0 src/bios/pet4032.S | 1 - src/bios/pet8032.S | 1 - src/bios/pet8096.S | 1 - third_party/tomsfonts/build.py | 10 + tools/build.py | 35 +++- tools/fontconvert.c | 16 +- tools/libbdf.c | 154 +++++++-------- tools/mkcombifs.cc | 209 +++++++++++++-------- tools/mkdfs.c | 43 ++--- tools/mkoricdsk.cc | 2 +- tools/shuffle.cc | 66 +++---- 26 files changed, 439 insertions(+), 234 deletions(-) delete mode 120000 scripts/pet4032.ld delete mode 120000 scripts/pet8032.ld create mode 100644 src/arch/commodore/build.py rename src/{bios => arch/commodore}/c64.S (100%) rename {scripts => src/arch/commodore}/c64.ld (100%) rename src/{bios => arch}/commodore/ieee488.S (100%) rename src/{bios => arch/commodore}/pet.S (100%) rename {scripts => src/arch/commodore}/pet.ld (100%) rename {scripts => src/arch/commodore}/pet8096.ld (100%) rename src/{bios => arch}/commodore/petscii.S (100%) rename src/{bios => arch/commodore}/vic20.S (99%) rename {scripts => src/arch/commodore}/vic20.ld (100%) rename src/{bios => arch/commodore}/x16.S (100%) delete mode 120000 src/bios/pet4032.S delete mode 120000 src/bios/pet8032.S delete mode 120000 src/bios/pet8096.S create mode 100644 third_party/tomsfonts/build.py diff --git a/build.py b/build.py index e18e56c2..cb560cc7 100644 --- a/build.py +++ b/build.py @@ -16,5 +16,10 @@ "atari800.atr": "src/arch/atari800+atari800_diskimage", "atari800hd.atr": "src/arch/atari800+atari800hd_diskimage", "atari800xlhd.atr": "src/arch/atari800+atari800xlhd_diskimage", + "c64.d64": "src/arch/commodore+c64_diskimage", + "pet4032.d64": "src/arch/commodore+pet4032_diskimage", + "pet8032.d64": "src/arch/commodore+pet8032_diskimage", + "pet8096.d64": "src/arch/commodore+pet8096_diskimage", + "vic20.d64": "src/arch/commodore+vic20_diskimage", }, ) diff --git a/scripts/pet4032.ld b/scripts/pet4032.ld deleted file mode 120000 index 8eafaed7..00000000 --- a/scripts/pet4032.ld +++ /dev/null @@ -1 +0,0 @@ -pet.ld \ No newline at end of file diff --git a/scripts/pet8032.ld b/scripts/pet8032.ld deleted file mode 120000 index 8eafaed7..00000000 --- a/scripts/pet8032.ld +++ /dev/null @@ -1 +0,0 @@ -pet.ld \ No newline at end of file diff --git a/src/arch/apple2e/build.py b/src/arch/apple2e/build.py index 57df49aa..f686e37b 100644 --- a/src/arch/apple2e/build.py +++ b/src/arch/apple2e/build.py @@ -56,5 +56,5 @@ | MINIMAL_APPS | MINIMAL_APPS_SRCS | BIG_APPS - | BIG_APPS_SRCS + | BIG_APPS_SRCS, ) diff --git a/src/arch/commodore/build.py b/src/arch/commodore/build.py new file mode 100644 index 00000000..fb1c6ded --- /dev/null +++ b/src/arch/commodore/build.py @@ -0,0 +1,124 @@ +from build.ab import normalrule, TargetsMap, filenameof, Rule +from tools.build import mkcpmfs +from build.llvm import llvmrawprogram, llvmclibrary +from config import ( + MINIMAL_APPS, + MINIMAL_APPS_SRCS, + BIG_APPS, + BIG_APPS_SRCS, + SCREEN_APPS, + SCREEN_APPS_SRCS, +) + +COMMODORE_ITEMS = ( + {"0:ccp.sys": "src+ccp", "0:bdos.sys": "src+bdos"} + | MINIMAL_APPS + | MINIMAL_APPS_SRCS + | BIG_APPS + | BIG_APPS_SRCS +) + +COMMODORE_ITEMS_WITH_SCREEN = COMMODORE_ITEMS | SCREEN_APPS | SCREEN_APPS_SRCS + + +@Rule +def mkcbmfs(self, name, items: TargetsMap = {}, title="CBMFS", id=None): + cs = [] + ins = [] + + cmd = "chronic cc1541 -q " + if id: + cmd += "-i %d " % id + cmd += '-n "%s" {outs[0]}' % title + cs += [cmd] + + for k, v in items.items(): + cs += [ + "chronic cc1541 -q -t -u 0 -r 18 -f %s -w %s {outs[0]}" + % (k, filenameof(v)) + ] + ins += [v] + + cs += ["{deps[0]} -f {outs[0]}"] + normalrule( + replaces=self, + ins=ins, + outs=[name + ".img"], + deps=["tools+mkcombifs"], + commands=cs, + label="MKCBMFS", + ) + + +llvmclibrary( + name="commodore_lib", srcs=["./ieee488.S", "./petscii.S"], deps=["include"] +) + +llvmrawprogram( + name="pet4032_bios", + srcs=["./pet.S"], + deps=["src/lib+bioslib", "include", ".+commodore_lib"], + cflags=["-DPET4032"], + ldflags=["--no-check-sections"], + linkscript="./pet.ld", +) + +llvmrawprogram( + name="pet8032_bios", + srcs=["./pet.S"], + deps=["src/lib+bioslib", "include", ".+commodore_lib"], + cflags=["-DPET8032"], + ldflags=["--no-check-sections"], + linkscript="./pet.ld", +) + +llvmrawprogram( + name="pet8096_bios", + srcs=["./pet.S"], + deps=["src/lib+bioslib", "include", ".+commodore_lib"], + cflags=["-DPET8096"], + ldflags=["--no-check-sections"], + linkscript="./pet8096.ld", +) + +llvmrawprogram( + name="c64_bios", + srcs=["./c64.S"], + deps=["src/lib+bioslib", "include", ".+commodore_lib"], + linkscript="./c64.ld", +) + +llvmrawprogram( + name="vic20_bios", + srcs=["./vic20.S"], + deps=[ + ".+commodore_lib", + "include", + "src/lib+bioslib", + "third_party/tomsfonts+4x8", + ], + linkscript="./vic20.ld", +) + +for target in ["c64", "pet4032", "pet8032", "pet8096", "vic20"]: + mkcbmfs( + name=target + "_cbmfs", + title="cp/m-65: %s" % target, + items={"cpm": ".+%s_bios" % target}, + ) + +for target in ["pet4032", "pet8032", "pet8096"]: + mkcpmfs( + name=target + "_diskimage", + format="c1541", + template=".+%s_cbmfs" % target, + items=COMMODORE_ITEMS_WITH_SCREEN, + ) + +for target in ["c64", "vic20"]: + mkcpmfs( + name=target + "_diskimage", + format="c1541", + template=".+%s_cbmfs" % target, + items=COMMODORE_ITEMS_WITH_SCREEN, + ) diff --git a/src/bios/c64.S b/src/arch/commodore/c64.S similarity index 100% rename from src/bios/c64.S rename to src/arch/commodore/c64.S diff --git a/scripts/c64.ld b/src/arch/commodore/c64.ld similarity index 100% rename from scripts/c64.ld rename to src/arch/commodore/c64.ld diff --git a/src/bios/commodore/ieee488.S b/src/arch/commodore/ieee488.S similarity index 100% rename from src/bios/commodore/ieee488.S rename to src/arch/commodore/ieee488.S diff --git a/src/bios/pet.S b/src/arch/commodore/pet.S similarity index 100% rename from src/bios/pet.S rename to src/arch/commodore/pet.S diff --git a/scripts/pet.ld b/src/arch/commodore/pet.ld similarity index 100% rename from scripts/pet.ld rename to src/arch/commodore/pet.ld diff --git a/scripts/pet8096.ld b/src/arch/commodore/pet8096.ld similarity index 100% rename from scripts/pet8096.ld rename to src/arch/commodore/pet8096.ld diff --git a/src/bios/commodore/petscii.S b/src/arch/commodore/petscii.S similarity index 100% rename from src/bios/commodore/petscii.S rename to src/arch/commodore/petscii.S diff --git a/src/bios/vic20.S b/src/arch/commodore/vic20.S similarity index 99% rename from src/bios/vic20.S rename to src/arch/commodore/vic20.S index 9240cc2d..f83cd313 100644 --- a/src/bios/vic20.S +++ b/src/arch/commodore/vic20.S @@ -765,7 +765,7 @@ zproc draw_glyph rts font_tab: - #include ".obj/4x8font.inc" + #include "4x8font.inc" zendproc zproc toggle_cursor diff --git a/scripts/vic20.ld b/src/arch/commodore/vic20.ld similarity index 100% rename from scripts/vic20.ld rename to src/arch/commodore/vic20.ld diff --git a/src/bios/x16.S b/src/arch/commodore/x16.S similarity index 100% rename from src/bios/x16.S rename to src/arch/commodore/x16.S diff --git a/src/bios/pet4032.S b/src/bios/pet4032.S deleted file mode 120000 index 730b25cc..00000000 --- a/src/bios/pet4032.S +++ /dev/null @@ -1 +0,0 @@ -pet.S \ No newline at end of file diff --git a/src/bios/pet8032.S b/src/bios/pet8032.S deleted file mode 120000 index 730b25cc..00000000 --- a/src/bios/pet8032.S +++ /dev/null @@ -1 +0,0 @@ -pet.S \ No newline at end of file diff --git a/src/bios/pet8096.S b/src/bios/pet8096.S deleted file mode 120000 index 730b25cc..00000000 --- a/src/bios/pet8096.S +++ /dev/null @@ -1 +0,0 @@ -pet.S \ No newline at end of file diff --git a/third_party/tomsfonts/build.py b/third_party/tomsfonts/build.py new file mode 100644 index 00000000..316008ce --- /dev/null +++ b/third_party/tomsfonts/build.py @@ -0,0 +1,10 @@ +from build.llvm import llvmclibrary +from tools.build import fontconvert + +llvmclibrary( + name="ivo3x6", hdrs={"third_party/fonts/atari/ivo3x6.inc": "./ivo3x6.inc"} +) + +fontconvert(name="4x8_h", src="./atari-small.bdf") + +llvmclibrary(name="4x8", hdrs={"4x8font.inc": ".+4x8_h"}) diff --git a/tools/build.py b/tools/build.py index 7e4c7b29..1a14821e 100644 --- a/tools/build.py +++ b/tools/build.py @@ -5,8 +5,11 @@ cxxprogram(name="xextobin", srcs=["./xextobin.cc"], deps=["+libfmt"]) cxxprogram(name="shuffle", srcs=["./shuffle.cc"], deps=["+libfmt"]) cxxprogram(name="mkoricdsk", srcs=["./mkoricdsk.cc"], deps=["+libfmt"]) +cxxprogram(name="mkcombifs", srcs=["./mkcombifs.cc"], deps=["+libfmt"]) cprogram(name="mkdfs", srcs=["./mkdfs.c"]) -cprogram(name="fontconvert", srcs=["./fontconvert.c"]) +cprogram( + name="fontconvert", srcs=["./fontconvert.c", "./libbdf.c", "./libbdf.h"] +) @Rule @@ -40,19 +43,29 @@ def mkcpmfs( self, name, format, + template: Target = None, bootimage: Target = None, size=None, items: TargetsMap = {}, ): - mkfs = "mkfs.cpm -f %s" % format - if bootimage: - mkfs += " -b %s" % filenameof(bootimage) - mkfs += " {outs[0]}" + cs = [] + if template: + cs += ["cp %s {outs[0]}" % filenameof(template)] + else: + mkfs = "mkfs.cpm -f %s" % format + if bootimage: + mkfs += " -b %s" % filenameof(bootimage) + mkfs += " {outs[0]}" + cs += [mkfs] - cs = [mkfs] ins = [] for k, v in items.items(): + flags = None + if "@" in k: + k, flags = k.split("@") cs += ["cpmcp -f %s {outs[0]} %s %s" % (format, filenameof(v), k)] + if flags: + cs += ["chpmchattr -f %s {outs[0]} %s %s" % (format, flags, k)] ins += [v] if size: @@ -62,16 +75,18 @@ def mkcpmfs( replaces=self, ins=ins, outs=[name + ".img"], - deps=["diskdefs"] + [bootimage] if bootimage else [], + deps=["diskdefs"] + [bootimage] + if bootimage + else [] + [template] + if template + else [], commands=cs, label="MKCPMFS", ) @Rule -def mkdfs( - self, name=None, out=None, title="DFS", opt=0, items: TargetsMap = {} -): +def mkdfs(self, name, out=None, title="DFS", opt=0, items: TargetsMap = {}): cs = [] ins = [] for k, v in items.items(): diff --git a/tools/fontconvert.c b/tools/fontconvert.c index 870767a4..ae4f6e25 100644 --- a/tools/fontconvert.c +++ b/tools/fontconvert.c @@ -42,14 +42,14 @@ int main(int argc, const char* argv[]) printf( "\t.byte 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, " "0x%02x ; char %d\n", - p[0] | (p[0]>>4), - p[1] | (p[1]>>4), - p[2] | (p[2]>>4), - p[3] | (p[3]>>4), - p[4] | (p[4]>>4), - p[5] | (p[5]>>4), - p[6] | (p[6]>>4), - p[7] | (p[7]>>4), + p[0] | (p[0] >> 4), + p[1] | (p[1] >> 4), + p[2] | (p[2] >> 4), + p[3] | (p[3] >> 4), + p[4] | (p[4] >> 4), + p[5] | (p[5] >> 4), + p[6] | (p[6] >> 4), + p[7] | (p[7] >> 4), c); } diff --git a/tools/libbdf.c b/tools/libbdf.c index 46623345..bb3643c2 100644 --- a/tools/libbdf.c +++ b/tools/libbdf.c @@ -7,95 +7,99 @@ static bool startswith(const char* string, const char* prefix) { - return strncmp(prefix, string, strlen(prefix)) == 0; + return strncmp(prefix, string, strlen(prefix)) == 0; } BDF* bdf_load(const char* filename) { - BDF* bdf = calloc(1, sizeof(BDF)); - FILE* fp = fopen(filename, "rt"); + BDF* bdf = calloc(1, sizeof(BDF)); + FILE* fp = fopen(filename, "rt"); - char* ptr = NULL; - size_t size = 0; - Glyph* glyph = NULL; - for (;;) - { - if (getline(&ptr, &size, fp) == -1) - break; + char* ptr = NULL; + size_t size = 0; + Glyph* glyph = NULL; + for (;;) + { + if (getline(&ptr, &size, fp) == -1) + break; - int p1, p2, p3, p4; - if (startswith(ptr, "STARTCHAR ")) - { - glyph = calloc(1, sizeof(Glyph)); - glyph->data = calloc(bdf->height, sizeof(&glyph->data)); - } - else if (sscanf(ptr, "ENCODING %d\n", &p1) == 1) - bdf->glyphs[p1] = glyph; - else if (sscanf(ptr, "FONTBOUNDINGBOX %d %d %d %d\n", &p1, &p2, &p3, &p4) == 4) - { - bdf->width = p1; - bdf->height = p2; - } - else if (sscanf(ptr, "FONT_ASCENT %d\n", &p1) == 1) - bdf->ascent = p1; - else if (sscanf(ptr, "FONT_DESCENT %d\n", &p1) == 1) - bdf->descent = p1; - else if (sscanf(ptr, "BBX %d %d %d %d\n", &p1, &p2, &p3, &p4) == 4) - { - if (!glyph) - goto malformed; - glyph->width = p1; - glyph->height = p2; - glyph->dx = p3; - glyph->dy = p4; - } - else if (strcmp(ptr, "BITMAP\n") == 0) - { - int yo = bdf->ascent - glyph->dy - glyph->height; + int p1, p2, p3, p4; + if (startswith(ptr, "STARTCHAR ")) + { + glyph = calloc(1, sizeof(Glyph)); + glyph->data = calloc(bdf->height, sizeof(&glyph->data)); + } + else if (sscanf(ptr, "ENCODING %d\n", &p1) == 1) + bdf->glyphs[p1] = glyph; + else if (sscanf(ptr, + "FONTBOUNDINGBOX %d %d %d %d\n", + &p1, + &p2, + &p3, + &p4) == 4) + { + bdf->width = p1; + bdf->height = p2; + } + else if (sscanf(ptr, "FONT_ASCENT %d\n", &p1) == 1) + bdf->ascent = p1; + else if (sscanf(ptr, "FONT_DESCENT %d\n", &p1) == 1) + bdf->descent = p1; + else if (sscanf(ptr, "BBX %d %d %d %d\n", &p1, &p2, &p3, &p4) == 4) + { + if (!glyph) + goto malformed; + glyph->width = p1; + glyph->height = p2; + glyph->dx = p3; + glyph->dy = p4; + } + else if (strcmp(ptr, "BITMAP\n") == 0) + { + int yo = bdf->ascent - glyph->dy - glyph->height; - for (int y=0; yheight; y++) - { - if (getline(&ptr, &size, fp) == -1) - goto malformed; - if (sscanf(ptr, "%x\n", &p1) != 1) - goto malformed; - int yy = y + yo; - if ((yy >= 0) && (yy < bdf->height)) - glyph->data[yy] = p1 >> (glyph->dx); - } - } - } - free(ptr); + for (int y = 0; y < glyph->height; y++) + { + if (getline(&ptr, &size, fp) == -1) + goto malformed; + if (sscanf(ptr, "%x\n", &p1) != 1) + goto malformed; + int yy = y + yo; + if ((yy >= 0) && (yy < bdf->height)) + glyph->data[yy] = p1 >> (glyph->dx); + } + } + } + free(ptr); - fclose(fp); - return bdf; + fclose(fp); + return bdf; toobig: - fprintf(stderr, "libbdf: glyphs may be a maximum of 8x8\n"); - goto error; + fprintf(stderr, "libbdf: glyphs may be a maximum of 8x8\n"); + goto error; malformed: - fprintf(stderr, "libbdf: malformed BDF file\n"); + fprintf(stderr, "libbdf: malformed BDF file\n"); error: - bdf_free(bdf); - if (fp) - fclose(fp); - return NULL; + bdf_free(bdf); + if (fp) + fclose(fp); + return NULL; } void bdf_free(BDF* bdf) { - if (bdf) - { - for (int i=0; i<256; i++) - { - Glyph* g = bdf->glyphs[i]; - if (g) - { - free(g->data); - free(g); - } - } - free(bdf); - } + if (bdf) + { + for (int i = 0; i < 256; i++) + { + Glyph* g = bdf->glyphs[i]; + if (g) + { + free(g->data); + free(g); + } + } + free(bdf); + } } - diff --git a/tools/mkcombifs.cc b/tools/mkcombifs.cc index 44aa8176..d1121152 100644 --- a/tools/mkcombifs.cc +++ b/tools/mkcombifs.cc @@ -4,6 +4,7 @@ #include #include #include +#include /* Does the magic fixing up to make a combination 1541/CPMFS disk. * @@ -14,6 +15,9 @@ * blocks are in use. */ +static std::string infilename; +static bool verbose = false; + template void error(fmt::format_string fmt, T&&... args) { @@ -24,95 +28,140 @@ void error(fmt::format_string fmt, T&&... args) static int get1541TrackSize(int track) { - if (track <= 17) - return 21; - if (track <= 24) - return 19; - if (track <= 30) - return 18; - return 17; + if (track <= 17) + return 21; + if (track <= 24) + return 19; + if (track <= 30) + return 18; + return 17; } /* 1-offset track numbers! But 0-offset sector numbers... */ static int get1541LBA(int track, int sector) { - int offset = 0; + int offset = 0; - assert(track != 0); - for (int t = 1; t < track; t++) - offset += get1541TrackSize(t); + assert(track != 0); + for (int t = 1; t < track; t++) + offset += get1541TrackSize(t); - return offset + sector; + return offset + sector; } -int main(int argc, const char* argv[]) +static void syntaxError() { - std::fstream fs(argv[1], std::ios::binary | std::ios::in | std::ios::out); - if (!fs) - error("Cannot open input file: {}", strerror(errno)); - uint32_t size = std::filesystem::file_size(argv[1]); - - uint8_t bam[256]; - fs.seekg(get1541LBA(18, 0) * 256); - fs.read((char*) bam, sizeof(bam)); - - if (bam[2] != 0x41) - error("This doesn't look like a 1541 file system"); - - std::set usedSectors; - - for (int track=1;; track++) - { - int offset = get1541LBA(track, 0) * 256; - if (offset >= size) - break; - - uint8_t* bamp = &bam[5 + (track-1) * 4]; - uint32_t bitmap = bamp[0] | (bamp[1] << 8) | (bamp[2] << 16); - int sectorCount = get1541TrackSize(track); - - for (int sector=0; sector>= 1; - - if (allocated) - usedSectors.insert(get1541LBA(track, sector)); - } - - bamp[-1] = bamp[0] = bamp[1] = bamp[2] = 0; - } - fmt::print("1541 filesystem has {} allocated sectors\n", usedSectors.size()); - - std::set usedBlocks; - for (int sector : usedSectors) - usedBlocks.insert(sector/4); - - fmt::print("CP/M filesystem has {} allocated blocks\n", usedBlocks.size()); - - for (int i=0; i<64; i++) - { - fs.seekp(32*i); - for (int j=0; j<32; j++) - fs.put(0xe5); - } - - uint8_t dirent[32] = { - 0, 'C', 'B', 'M', 'F', 'S', ' ', ' ', ' ', 'S', 'Y', 'S', - /* EX */ 0, - /* S1 */ 0, - /* S2 */ 0, - /* RC */ (uint8_t)(usedBlocks.size() * 8) - }; - uint8_t* al = &dirent[16]; - for (int block : usedBlocks) - *al++ = block; - fs.seekp(0); - fs.write((const char*) dirent, sizeof(dirent)); - - fs.seekp(get1541LBA(18, 0) * 256); - fs.write((char*) bam, sizeof(bam)); - - return 0; + fmt::print(stderr, "Usage: mkcombifs [-v] \n"); + exit(1); } +static void parseArguments(int argc, char* const* argv) +{ + for (;;) + { + switch (getopt(argc, argv, "vf:")) + { + case -1: + if (infilename.empty() || argv[optind]) + syntaxError(); + + case 'f': + infilename = optarg; + return; + + case 'v': + verbose = true; + break; + + default: + syntaxError(); + } + } +} + +int main(int argc, char* const* argv) +{ + parseArguments(argc, argv); + + std::fstream fs( + infilename, std::ios::binary | std::ios::in | std::ios::out); + if (!fs) + error("Cannot open input file: {}", strerror(errno)); + uint32_t size = std::filesystem::file_size(infilename); + + uint8_t bam[256]; + fs.seekg(get1541LBA(18, 0) * 256); + fs.read((char*)bam, sizeof(bam)); + + if (bam[2] != 0x41) + error("This doesn't look like a 1541 file system"); + + std::set usedSectors; + + for (int track = 1;; track++) + { + int offset = get1541LBA(track, 0) * 256; + if (offset >= size) + break; + + uint8_t* bamp = &bam[5 + (track - 1) * 4]; + uint32_t bitmap = bamp[0] | (bamp[1] << 8) | (bamp[2] << 16); + int sectorCount = get1541TrackSize(track); + + for (int sector = 0; sector < sectorCount; sector++) + { + bool allocated = !(bitmap & 1); + bitmap >>= 1; + + if (allocated) + usedSectors.insert(get1541LBA(track, sector)); + } + + bamp[-1] = bamp[0] = bamp[1] = bamp[2] = 0; + } + if (verbose) + fmt::print( + "1541 filesystem has {} allocated sectors\n", usedSectors.size()); + + std::set usedBlocks; + for (int sector : usedSectors) + usedBlocks.insert(sector / 4); + + if (verbose) + fmt::print( + "CP/M filesystem has {} allocated blocks\n", usedBlocks.size()); + + for (int i = 0; i < 64; i++) + { + fs.seekp(32 * i); + for (int j = 0; j < 32; j++) + fs.put(0xe5); + } + + uint8_t dirent[32] = {0, + 'C', + 'B', + 'M', + 'F', + 'S', + ' ', + ' ', + ' ', + 'S', + 'Y', + 'S', + /* EX */ 0, + /* S1 */ 0, + /* S2 */ 0, + /* RC */ (uint8_t)(usedBlocks.size() * 8)}; + uint8_t* al = &dirent[16]; + for (int block : usedBlocks) + *al++ = block; + fs.seekp(0); + fs.write((const char*)dirent, sizeof(dirent)); + + fs.seekp(get1541LBA(18, 0) * 256); + fs.write((char*)bam, sizeof(bam)); + + return 0; +} diff --git a/tools/mkdfs.c b/tools/mkdfs.c index b682cc87..b4ad513b 100644 --- a/tools/mkdfs.c +++ b/tools/mkdfs.c @@ -66,7 +66,7 @@ static void add_file(const char* filename) leaf = filename; else leaf++; - for (int i=0; i<7; i++) + for (int i = 0; i < 7; i++) { char c = leaf[i]; if ((c == '.') || (c == '\0')) @@ -99,18 +99,18 @@ static void write_byte(int fd, uint32_t pos, uint8_t value) static void write_word(int fd, uint32_t pos, uint16_t value) { write_byte(fd, pos, value); - write_byte(fd, pos+1, value>>8); + write_byte(fd, pos + 1, value >> 8); } static void write_quad(int fd, uint32_t pos, uint32_t value) { write_word(fd, pos, value); - write_word(fd, pos+2, value>>16); + write_word(fd, pos + 2, value >> 16); } static void write_disk(void) { - int fd = open(output_filename, O_WRONLY|O_CREAT|O_TRUNC, 0644); + int fd = open(output_filename, O_WRONLY | O_CREAT | O_TRUNC, 0644); if (fd == -1) { fprintf(stderr, "cannot open output file: %s\n", strerror(errno)); @@ -119,27 +119,27 @@ static void write_disk(void) ftruncate(fd, disk_size * 0x100); write_byte(fd, 0x107, disk_size); - write_byte(fd, 0x106, (boot_mode<<4) | (disk_size>>8)); + write_byte(fd, 0x106, (boot_mode << 4) | (disk_size >> 8)); write_byte(fd, 0x105, catalogue_pos << 3); - pwrite(fd, disk_name+0, 8, 0x000); - pwrite(fd, disk_name+8, 4, 0x100); + pwrite(fd, disk_name + 0, 8, 0x000); + pwrite(fd, disk_name + 8, 4, 0x100); - for (int i=0; idata, 0x100 * ce->sectors, ce->startsector * 0x100); - pwrite(fd, ce->name, 7, 8 + i*8); - write_byte(fd, 0x008 + i*8 + 7, ce->directory); - write_word(fd, 0x108 + i*8 + 0, ce->load_address); - write_word(fd, 0x108 + i*8 + 2, ce->exec_address); - write_word(fd, 0x108 + i*8 + 4, ce->length); - write_byte(fd, 0x108 + i*8 + 7, ce->startsector); - - write_byte(fd, 0x108 + i*8 + 6, + pwrite(fd, ce->name, 7, 8 + i * 8); + write_byte(fd, 0x008 + i * 8 + 7, ce->directory); + write_word(fd, 0x108 + i * 8 + 0, ce->load_address); + write_word(fd, 0x108 + i * 8 + 2, ce->exec_address); + write_word(fd, 0x108 + i * 8 + 4, ce->length); + write_byte(fd, 0x108 + i * 8 + 7, ce->startsector); + + write_byte(fd, + 0x108 + i * 8 + 6, (((ce->load_address >> 16) & 0x3) << 2) | - (((ce->exec_address >> 16) & 3) << 6) | - (((ce->length >> 16) & 3) << 4) | - (ce->startsector >> 8)); + (((ce->exec_address >> 16) & 3) << 6) | + (((ce->length >> 16) & 3) << 4) | (ce->startsector >> 8)); } close(fd); @@ -183,7 +183,7 @@ int main(int argc, char* const argv[]) optarg = optarg + 2; } memset(&lastfile->name, ' ', 7); - for (int i=0; i<7; i++) + for (int i = 0; i < 7; i++) { char c = optarg[i]; if (c == '\0') @@ -203,7 +203,8 @@ int main(int argc, char* const argv[]) break; default: - fprintf(stderr, "Usage: mkdfs -O -f ...\n"); + fprintf( + stderr, "Usage: mkdfs -O -f ...\n"); exit(1); } } diff --git a/tools/mkoricdsk.cc b/tools/mkoricdsk.cc index 57802677..e67a3966 100644 --- a/tools/mkoricdsk.cc +++ b/tools/mkoricdsk.cc @@ -207,7 +207,7 @@ int main(int argc, char* argv[]) buffer[2] = 0xa1; buffer[3] = 0xfb; inf.clear(); - inf.seekg((s + h*sectors + t*heads*sectors)*256); + inf.seekg((s + h * sectors + t * heads * sectors) * 256); if (inf) inf.read((char*)buffer + 4, 256); putbe16(&buffer[256 + 4], crc16(&buffer[0], 256 + 4)); diff --git a/tools/shuffle.cc b/tools/shuffle.cc index 6ffca603..510e33ec 100644 --- a/tools/shuffle.cc +++ b/tools/shuffle.cc @@ -28,23 +28,23 @@ static std::string readfile(std::ifstream& in) static int chartoint(char c) { - if (isdigit(c)) - return c - '0'; - c = tolower(c); - if (isalpha(c)) - return 10 + c - 'a'; - std::cerr << "bad mapping string\n"; - exit(1); + if (isdigit(c)) + return c - '0'; + c = tolower(c); + if (isalpha(c)) + return 10 + c - 'a'; + std::cerr << "bad mapping string\n"; + exit(1); } static void write_file() { std::ifstream ifs(infilename, std::ios::binary); - std::ofstream ofs(outfilename, std::ios::binary); + std::ofstream ofs(outfilename, std::ios::binary); std::string infile = readfile(ifs); - if (!ifs) - { + if (!ifs) + { perror("Could not read input file"); exit(1); } @@ -52,27 +52,29 @@ static void write_file() int inblocks = (infile.size() + blocksize - 1) / blocksize; int tracks = (inblocks + blockspertrack - 1) / blockspertrack; if (verbose) - fmt::print("file size: {} tracks of {} blocks\n", tracks, blockspertrack); + fmt::print( + "file size: {} tracks of {} blocks\n", tracks, blockspertrack); infile.resize(tracks * blockspertrack * blocksize); - std::map mapping; - for (int i=0; i mapping; + for (int i = 0; i < mappingstring.size(); i++) + { + if (reverse) + mapping[i] = chartoint(mappingstring[i]); + else + mapping[chartoint(mappingstring[i])] = i; + } + + for (int track = 0; track < tracks; track++) + { + int baseblock = track * blockspertrack; + for (int block = 0; block < blockspertrack; block++) + ofs << infile.substr( + (baseblock + mapping[block]) * blocksize, blocksize); + } + + if (!ofs) + { perror("Could not write output file"); exit(1); } @@ -108,9 +110,9 @@ int main(int argc, char* const argv[]) outfilename = optarg; break; - case 'r': - reverse = true; - break; + case 'r': + reverse = true; + break; case 'v': verbose = true; From d141886dbc26177d0d0cbe34a6a5a0e81c5d8769 Mon Sep 17 00:00:00 2001 From: David Given Date: Sun, 17 Dec 2023 22:11:24 +0000 Subject: [PATCH 20/23] Make the X16 port build. --- build.py | 1 + src/arch/commodore/build.py | 2 +- src/arch/x16/build.py | 43 +++++++++++++++++++++++++++++++ src/arch/{commodore => x16}/x16.S | 0 {scripts => src/arch/x16}/x16.ld | 2 +- 5 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 src/arch/x16/build.py rename src/arch/{commodore => x16}/x16.S (100%) rename {scripts => src/arch/x16}/x16.ld (97%) diff --git a/build.py b/build.py index cb560cc7..ecbad162 100644 --- a/build.py +++ b/build.py @@ -21,5 +21,6 @@ "pet8032.d64": "src/arch/commodore+pet8032_diskimage", "pet8096.d64": "src/arch/commodore+pet8096_diskimage", "vic20.d64": "src/arch/commodore+vic20_diskimage", + "x16.zip": "src/arch/x16+diskimage", }, ) diff --git a/src/arch/commodore/build.py b/src/arch/commodore/build.py index fb1c6ded..d9142344 100644 --- a/src/arch/commodore/build.py +++ b/src/arch/commodore/build.py @@ -23,7 +23,7 @@ @Rule def mkcbmfs(self, name, items: TargetsMap = {}, title="CBMFS", id=None): - cs = [] + cs = ["rm -f {outs[0]}"] ins = [] cmd = "chronic cc1541 -q " diff --git a/src/arch/x16/build.py b/src/arch/x16/build.py new file mode 100644 index 00000000..50d60725 --- /dev/null +++ b/src/arch/x16/build.py @@ -0,0 +1,43 @@ +from build.ab import normalrule +from tools.build import mkdfs, mkcpmfs +from build.llvm import llvmrawprogram +from config import ( + MINIMAL_APPS, + MINIMAL_APPS_SRCS, + BIG_APPS, + BIG_APPS_SRCS, +) + +llvmrawprogram( + name="x16", + srcs=["./x16.S"], + deps=["include", "src/lib+bioslib", "src/arch/commodore+commodore_lib"], + linkscript="./x16.ld", +) + +mkcpmfs( + name="cpmfs", + format="generic-1m", + items={"0:ccp.sys": "src+ccp"} + | MINIMAL_APPS + | MINIMAL_APPS_SRCS + | BIG_APPS + | BIG_APPS_SRCS, +) + +normalrule( + name="diskimage", + ins=[ + ".+cpmfs", + ".+x16", + "src+bdos", + ], + outs=["x16.zip"], + commands=[ + "zip -9qj {outs[0]} {ins}", + r'printf "@ src+bdos\n@=BDOS\n" | zipnote -w {outs[0]}', + r'printf "@ x16+x16\n@=CPM\n" | zipnote -w {outs[0]}', + r'printf "@ x16+cpmfs.img\n@=CPMFS\n" | zipnote -w {outs[0]}', + ], + label="ZIP", +) diff --git a/src/arch/commodore/x16.S b/src/arch/x16/x16.S similarity index 100% rename from src/arch/commodore/x16.S rename to src/arch/x16/x16.S diff --git a/scripts/x16.ld b/src/arch/x16/x16.ld similarity index 97% rename from scripts/x16.ld rename to src/arch/x16/x16.ld index f0288e66..466010d4 100644 --- a/scripts/x16.ld +++ b/src/arch/x16/x16.ld @@ -9,7 +9,7 @@ SECTIONS { .zp : { *(.zp .zp.*) __ZP1_START__ = .; - __ZP1_END__ = 0x100; + __ZP1_END__ = 0xff; __ZP0_START__ = 0x22; __ZP0_END__ = 0x80; From 4fcbef0affa9207e0464aff41a9c9741d257872d Mon Sep 17 00:00:00 2001 From: David Given Date: Sun, 17 Dec 2023 23:22:38 +0000 Subject: [PATCH 21/23] Build scrntest. --- apps/build.py | 1 + config.py | 1 + 2 files changed, 2 insertions(+) diff --git a/apps/build.py b/apps/build.py index a4ec58a5..465582b7 100644 --- a/apps/build.py +++ b/apps/build.py @@ -29,6 +29,7 @@ def asm(self, name, src: Target = None, deps: Targets = []): "dinfo", "dump", "ls", + "scrntest", ]: asm(name=prog, src=("./%s.asm" % prog), deps=["./cpm65.inc"]) diff --git a/config.py b/config.py index c92b7a01..13233804 100644 --- a/config.py +++ b/config.py @@ -22,6 +22,7 @@ BIG_APPS = { "0:atbasic.com": "third_party/altirrabasic", "0:objdump.com": "apps+objdump", + "0:scrntest.com": "apps+scrntest", } BIG_APPS_SRCS = {} From e1ac60b0481d5c44e0116647c821ab7205a6b8c8 Mon Sep 17 00:00:00 2001 From: David Given Date: Sun, 17 Dec 2023 23:23:53 +0000 Subject: [PATCH 22/23] Update workflows. --- .github/workflows/ccpp.yml | 3 +-- .github/workflows/release.yml | 26 ++++---------------------- 2 files changed, 5 insertions(+), 24 deletions(-) diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml index 6dfabd56..51d963c2 100644 --- a/.github/workflows/ccpp.yml +++ b/.github/workflows/ccpp.yml @@ -20,8 +20,7 @@ jobs: - name: apt run: sudo apt update && sudo apt install cc1541 cpmtools libfmt-dev fp-compiler moreutils - - if: ${{ steps.cache-llvm-mos.outputs.cache-hit != 'true' }} - name: install llvm-mos + - name: install llvm-mos run: | wget -O - https://github.com/llvm-mos/llvm-mos-sdk/releases/latest/download/llvm-mos-linux.tar.xz | tar xJf - -C $HOME diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b016dbb8..015ee908 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,34 +13,16 @@ jobs: with: repository: 'davidgiven/cpm65' path: 'cpm65' - - uses: actions/checkout@v3 - with: - repository: 'davidgiven/llvm-mos-sdk' - path: 'llvm-mos-sdk' - - name: get llvm-mos-sdk version - run: echo "MOS_SDK_VERSION=$(cd llvm-mos-sdk && git rev-parse --short HEAD)" >> $GITHUB_ENV - name: apt - run: sudo apt update && sudo apt install cc1541 cpmtools libfmt-dev ninja-build fp-compiler - - - name: cache llvm-mos - id: cache-llvm-mos - uses: actions/cache@v3 - env: - cache-name: cache-llvm-mos - with: - path: ~/llvm-mos - key: ${{ runner.os }}-build-${{ env.cache-name }}-ver-${{ env.MOS_SDK_VERSION }} + run: sudo apt update && sudo apt install cc1541 cpmtools libfmt-dev fp-compiler moreutils - - if: ${{ steps.cache-llvm-mos.outputs.cache-hit != 'true' }} - name: install llvm-mos + - name: install llvm-mos run: | - mkdir -p llvm-mos-sdk/build - (cd llvm-mos-sdk/build && cmake -G "Ninja" -DCMAKE_INSTALL_PREFIX=$HOME/llvm-mos ..) - (cd llvm-mos-sdk/build && ninja install) + wget -O - https://github.com/llvm-mos/llvm-mos-sdk/releases/latest/download/llvm-mos-linux.tar.xz | tar xJf - -C $HOME - name: make - run: PATH=$PATH:$HOME/llvm-mos/bin make -C cpm65 LLVM= + run: make -C cpm65 LLVM=$HOME/llvm-mos/bin - name: date run: | From 131499f0a0e57a3bbd709c49fbf490733ebcc6fd Mon Sep 17 00:00:00 2001 From: David Given Date: Sun, 17 Dec 2023 23:24:55 +0000 Subject: [PATCH 23/23] Typo fix. --- .github/workflows/ccpp.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml index 51d963c2..0ac38056 100644 --- a/.github/workflows/ccpp.yml +++ b/.github/workflows/ccpp.yml @@ -10,12 +10,6 @@ jobs: with: repository: 'davidgiven/cpm65' path: 'cpm65' - - uses: actions/checkout@v3 - with: - repository: 'davidgiven/llvm-mos-sdk' - path: 'llvm-mos-sdk' - - name: get llvm-mos-sdk version - run: echo "MOS_SDK_VERSION=$(cd llvm-mos-sdk && git rev-parse --short HEAD)" >> $GITHUB_ENV - name: apt run: sudo apt update && sudo apt install cc1541 cpmtools libfmt-dev fp-compiler moreutils