diff --git a/.gitignore b/.gitignore index 9f08d29..fe4cbb9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ -dfu-util arm-none-eabi-gcc +disk.img +env +sdcc-code +zasm diff --git a/convert-font.py b/convert-font.py new file mode 100755 index 0000000..743b504 --- /dev/null +++ b/convert-font.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python3 +import imageio +import math + +asci = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~" +font = "font.png" + +im = imageio.imread(font) + +for c in asci: + + base_x = (ord(c) % 16) * 16 + base_y = math.floor(ord(c)/16) * 16 + + n = 0 + for y in range(16): + n = n << 16 + k = 0 + for x in range(16): + d = im[base_y + y][base_x + x][0] + k = k << 1 + if d == 255: + k = k + 1 + + n = n + k + + print("assign char_data[{:2}] = 256'h{:064x}; // {}".format(ord(c)-32, n, c)) diff --git a/create_img.py b/create_img.py new file mode 100755 index 0000000..1a4d3a2 --- /dev/null +++ b/create_img.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python3 +import math + +pageSize = 128 +sectorsPerTrack = 256 +blockSize = 16384 +maxDirs = 128 +dirBlocks = 1 + +# @todo Currently the tool assumes your are running in a subfolder from z80 + +out = open('../tools/disk.img', 'wb') + +def addBootloader(name): + loader = open(name, 'rb') + b = loader.read() + + if len(b) > pageSize: + raise RuntimeError("Bootloader binary cannot be larger than one page") + + out.seek(0) + out.write(b) + +def addOS(cpmName, biosName): + cpm = open(cpmName, 'rb') + bios = open(biosName, 'rb') + + b = cpm.read() + out.seek(pageSize) + out.write(b) + + b = bios.read() + out.seek(pageSize + 0x1600) + out.write(b) + +def seekBlock(i): + # Blocks start at track 1, sector 0 + out.seek(pageSize*sectorsPerTrack + i*blockSize) + +def initDirs(): + seekBlock(0) + out.write(bytearray(([0xe5] + [0x00] * 31) * maxDirs)) + +fileCounter = 0 +def addFile(filename, n, t): + global fileCounter + + if fileCounter > maxDirs: + raise RuntimeError("Max dir entries has been reached") + + fileCounter += 1 + + if len(n) > 8: + raise RuntimeError("Filename cannot be longer than 8") + + if len(t) > 3: + raise RuntimeError("Filetype cannot be longer than 3") + + f = open(filename, 'rb') + b = f.read() + + seekBlock(0) + out.seek(32*fileCounter, 1) + + # Write user (assume 0 for now) + out.write(bytearray(1)) + + # Write the name + out.write(n.upper().encode("ascii")) + out.write((" " * (8-len(n))).encode("ascii")) + + # Write the type + out.write(t.upper().encode("ascii")) + out.write((" " * (3-len(t))).encode("ascii")) + + # Write extend (assume no extend for now) + out.write(bytearray(2)) + + # Reserved byte + out.write(bytearray(1)) + + # Number of records (Again assuming no extends <128) + out.write(math.ceil(len(b)/128).to_bytes(1, byteorder='little')) + + # We are assuming one block per file for now, so we can use fileCounter + out.write(fileCounter.to_bytes(2, byteorder='little')) + + seekBlock(fileCounter) + out.write(b) + + +addBootloader('../cpm/.build/loader.bin') +addOS('../cpm/.build/cpm22.bin', '../cpm/.build/bios.bin') + +initDirs() + +addFile("../cpm/.build/MONITOR.COM", "MONITOR", "COM") +addFile("../cpm/bin/STAT.COM", "STAT", "COM") +addFile("../qe/.build/test.com", "test", "COM") +addFile("../qe/.build/qe.com", "qe", "COM") +addFile("../xed/.build/xed.com", "xed", "COM") diff --git a/font.png b/font.png new file mode 100644 index 0000000..cf40afa Binary files /dev/null and b/font.png differ diff --git a/setup.sh b/setup.sh index f062105..049b2e8 100755 --- a/setup.sh +++ b/setup.sh @@ -1,25 +1,13 @@ #!/bin/bash -command -v make >/dev/null 2>&1 || echo >&2 "Please install make" -command -v zasm >/dev/null 2>&1 || echo >&2 "Please install zasm" -command -v grep >/dev/null 2>&1 || echo >&2 "Please install grep" -command -v wget >/dev/null 2>&1 || echo >&2 "Please install wget" -command -v unzip >/dev/null 2>&1 || echo >&2 "Please install unzip" -command -v tar >/dev/null 2>&1 || echo >&2 "Please install tar" - -# @todo Check if pyserial is installed -# @todo Check if a serial terminal is installed -if [ "$(uname -r | sed -n 's/.*\( *Microsoft *\).*/\1/p')" == "Microsoft" ]; then - wget http://dfu-util.sourceforge.net/releases/dfu-util-0.9-win64.zip -O dfu-util.zip - unzip dfu-util.zip - mv dfu-util-0.9-win64 dfu-util - rm dfu-util.zip - # todo Check python3 -else - command -v python3 >/dev/null 2>&1 || echo >&2 "Please install python3" -fi +# @todo Check if all the required programs are installed wget https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v9.2.1-1.1/xpack-arm-none-eabi-gcc-9.2.1-1.1-linux-x64.tar.gz -O arm-none-eabi-gcc.tar.gz tar xvf arm-none-eabi-gcc.tar.gz mv xpack-arm-none-eabi-gcc-9.2.1-1.1 arm-none-eabi-gcc rm arm-none-eabi-gcc.tar.gz +svn checkout svn://svn.code.sf.net/p/sdcc/code/trunk sdcc-code + +python -m venv env +source env/bin/activate +pip install pyserial imageio diff --git a/upload.py b/upload.py new file mode 100755 index 0000000..e2041da --- /dev/null +++ b/upload.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python3 +import serial +import os +import sys +import time +import argparse + +def progressbar(it, prefix="", size=60, file=sys.stdout): + count = len(it) + def show(j): + x = int(size*j/count) + file.write("%s[%s%s] %i/%i\r" % (prefix, "#"*x, "."*(size-x), j, count)) + file.flush() + show(0) + for i, item in enumerate(it): + yield item + show(i+1) + file.write("\n") + file.flush() + +def rom_upload(filename): + # ser = serial.Serial("COM3", timeout=1, write_timeout=1) + ser = serial.Serial("/dev/ttyUSB0", timeout=1, write_timeout=1, baudrate=115200) + if ser.is_open: + # Clear out any existing input + ser.write(b'\n') + time.sleep(0.002) + + # Send the upload command + ser.write(b'#') + time.sleep(0.002) + ser.write(b'u') + time.sleep(0.002) + ser.write(b'\n') + time.sleep(0.002) + + size = os.path.getsize(filename) + ser.write([size & 0xFF]) + time.sleep(0.002) + ser.write([(size >> 8) & 0xFF]) + time.sleep(0.002) + + with open(filename, "rb") as f: + for i in progressbar(range(size), "Upload: ", 40): + byte = f.read(1) + ser.write(byte) + time.sleep(0.002) + + ser.close() + + else: + print("Failed to open serial port") + +def serial_upload(filename): + # ser = serial.Serial("COM3", timeout=1, write_timeout=1) + ser = serial.Serial("/dev/ttyUSB0", timeout=1, write_timeout=1, baudrate=115200) + if ser.is_open: + size = os.path.getsize(filename) + + with open(filename, "rb") as f: + for i in progressbar(range(size), "Upload: ", 40): + byte = f.read(1) + ser.write(byte) + + if byte == b'#': + time.sleep(0.002) + ser.write(b'#') + time.sleep(0.002) + ser.write(b'\n') + + time.sleep(0.002) + + ser.close() + + else: + print("Failed to open serial port") + +def main(): + parser = argparse.ArgumentParser(description="Upload binaries to the z80 computer.") + parser.add_argument("filename", help="file to upload") + parser.add_argument("--rom", dest="rom", action="store_const", const=True, default=False, help="Upload binary to rom") + parser.add_argument("--serial", dest="serial", action="store_const", const=True, default=False, help="Upload binary over serial") + + args = parser.parse_args() + + if (args.rom): + rom_upload(args.filename) + elif (args.serial): + serial_upload(args.filename) + else: + print("You needs to specify a target") + + + +if "__main__": + main()