diff --git a/.gitignore b/.gitignore index aef0905..71952f8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,10 @@ arm-none-eabi/* microblazeel-xilinx-elf/* -env/* -sdcc-code/* -disk.img +arm-none-eabi-gcc.tar.bz2 +gcc-arm-none-eabi-9-2020-q2-update/* + +gcc-10.2.0.tar.xz +newlib-3.1.0.tar.gz +binutils-2.35.tar.xz +build-mb/* diff --git a/bin/create_disk b/bin/create_disk deleted file mode 120000 index 27d47ba..0000000 --- a/bin/create_disk +++ /dev/null @@ -1 +0,0 @@ -../scripts/create_disk.py \ No newline at end of file diff --git a/bin/upload b/bin/upload deleted file mode 120000 index 0b34209..0000000 --- a/bin/upload +++ /dev/null @@ -1 +0,0 @@ -../scripts/upload.py \ No newline at end of file diff --git a/out.img b/out.img deleted file mode 100644 index 472339b..0000000 Binary files a/out.img and /dev/null differ diff --git a/scripts/__pycache__/mojo.cpython-38.pyc b/scripts/__pycache__/mojo.cpython-38.pyc deleted file mode 100644 index 2ac152f..0000000 Binary files a/scripts/__pycache__/mojo.cpython-38.pyc and /dev/null differ diff --git a/scripts/__pycache__/mojo.cpython-39.pyc b/scripts/__pycache__/mojo.cpython-39.pyc deleted file mode 100644 index 330d2e5..0000000 Binary files a/scripts/__pycache__/mojo.cpython-39.pyc and /dev/null differ diff --git a/scripts/arm.sh b/scripts/arm.sh new file mode 100755 index 0000000..f97c964 --- /dev/null +++ b/scripts/arm.sh @@ -0,0 +1,8 @@ +# Cleanup old files +rm -rf arm-none-eabi + +# Download and extract latest arm toolchain +wget https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2020q2/gcc-arm-none-eabi-9-2020-q2-update-x86_64-linux.tar.bz2 -O arm-none-eabi-gcc.tar.bz2 +tar xvf arm-none-eabi-gcc.tar.bz2 +mv gcc-arm-none-eabi-9-2020-q2-update arm-none-eabi +rm arm-none-eabi-gcc.tar.bz2 diff --git a/scripts/create_disk.py b/scripts/create_disk.py deleted file mode 100755 index d2f7a70..0000000 --- a/scripts/create_disk.py +++ /dev/null @@ -1,122 +0,0 @@ -#!/usr/bin/env python3 -import math - -pageSize = 128 -sectorsPerTrack = 256 -blockSize = 16384 -pagesPerBlock = 128 -maxDirs = 128 -dirBlocks = 1 - - -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 -allocationCounter = 1 -def addFile(filename, n, t): - global fileCounter - global allocationCounter - - if fileCounter > maxDirs: - raise RuntimeError("Max dir entries has been reached") - - 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() - - total_records = math.ceil(len(b)/pageSize) - records = (total_records - 1) % pagesPerBlock + 1 - extends = math.ceil(total_records/pagesPerBlock) - - if extends >= 8: - RuntimeError("File is to big to be stored in one entry, multple entries are not implemented") - - 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 - # @todo This is actually wrong, as the order is EX S1 S2 with S1 being unused, however we never deal with files that big - out.write((extends-1).to_bytes(1, byteorder='little')) - - # Reserved byte - out.write(bytearray(2)) - - # Number of records - - out.write(records.to_bytes(1, byteorder='little')) - - allocationCounterOld = allocationCounter - # We are assuming one block per file for now, so we can use fileCounter - for i in range(extends): - out.write(allocationCounter.to_bytes(2, byteorder='little')) - allocationCounter += 1 - - seekBlock(allocationCounterOld) - out.write(b) - - fileCounter += 1 - - -def main(): - # @todo Load the config from a file that we specify instead of hardcoding everything - # We can probably keep the os part hardcoded as that is not something we really need to change between different projects - global out - out = open('../tools/disk.img', 'wb') - - 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("../cpm/bin/MBASIC.COM", "MBASIC", "COM") - addFile("../cpm/bin/s.com", "S", "COM") - # addFile("../xed/.build/XED.COM", "XED", "COM") - -if __name__ == "__main__": - main() diff --git a/build-mb.sh b/scripts/microblaze.sh similarity index 96% rename from build-mb.sh rename to scripts/microblaze.sh index 9eac9af..8c25c78 100755 --- a/build-mb.sh +++ b/scripts/microblaze.sh @@ -7,6 +7,9 @@ # Current version is tested on Archlinux ## +# Cleanup old files +rm -rf microblazeel-xilinx-elf + TARGET=microblazeel-xilinx-elf PROGRAM_PREFIX=mb- @@ -17,7 +20,7 @@ INSTALL_DIR=$CUR/$TARGET CORES=12 GCC_URL=ftp://ftp.nluug.nl/mirror/languages/gcc/releases/gcc-10.2.0/gcc-10.2.0.tar.xz -NEWLIB_URL=ftp://sources.redhat.com/pub/newlib/newlib-3.1.0.tar.gz +NEWLIB_URL=ftp://sourceware.org/pub/newlib/newlib-3.1.0.tar.gz BINUTILS_URL=http://ftp.gnu.org/gnu/binutils/binutils-2.35.tar.xz GCC_FILE=$(basename $GCC_URL) diff --git a/scripts/mojo.py b/scripts/mojo.py deleted file mode 100755 index 1234bc0..0000000 --- a/scripts/mojo.py +++ /dev/null @@ -1,282 +0,0 @@ -#!/usr/bin/env python3 -###------------------------------------------------------------------------- -### Mojo.py is a bitstream uploader for the mojo v2 board -### author Matthew O'Gorman -### copyright 2013 Matthew O'Gorman -### version 2.0 -### ### License : This program is free software, distributed under the terms of -### the GNU General Public License Version 3. See the COPYING file -### at the top of the source tree. -###------------------------------------------------------------------------- - -import time -import sys -import argparse -import serial - -# Try to rename process to something more friendly than python mojo.py -try: - import setproctitle - - setproctitle.setproctitle("mojo") -except ImportError as error: - pass - - -def main(): - Version = "Mojo v2.0 is licensed under the GPLv3 copyright 2013 Matthew O'Gorman" - - parser = argparse.ArgumentParser(description="Mojo bitstream loader v2") - group = parser.add_mutually_exclusive_group(required=True) - group.add_argument( - "bitstream", - metavar="BITSTREAM", - nargs="?", - help="Bitstream file to upload to the Mojo.", - ) - group.add_argument( - "-i", - "--install", - metavar="BITSTREAM", - dest="install", - action="store", - help="Bitstream file to upload to the Mojo", - ) - parser.add_argument( - "-r", - "--ram", - dest="ram", - action="store_const", - const=True, - default=False, - help="Install bitstream file only to ram", - ) - # not currently supported by the default firmware of the board - # group.add_argument('-c', '--copy', metavar='BITSTREAM', dest='copy', action='append', nargs='?', - # help='Bitstream file to copy from the Mojo [Default: %(default)s]', default=['mojo.bin']) - - # group.add_argument('-o', '--only_verify', metavar='BITSTREAM', dest='only_verify', action='store', - # help='Read flash of Mojo only to verify against bitstream.') - # group.add_argument('-r', '--reboot', dest='reboot', action='store_const', - # const=True, default=False, - # help='Reboot mojo board.') - parser.add_argument( - "-v", - "--verbose", - dest="verbose", - action="store_const", - const=True, - default=False, - help="Enable verbose output to cli.", - ) - parser.add_argument( - "-V", - "--version", - dest="version", - action="store_const", - const=True, - default=False, - help="Display version number of mojo.", - ) - parser.add_argument( - "-n", - "--no-verify", - dest="no_verify", - action="store_const", - const=True, - default=False, - help="Do not verify the operation to the Mojo.", - ) - group.add_argument( - "-e", - "--erase", - dest="erase", - action="store_const", - const=True, - default=False, - help="Erase flash on Mojo.", - ) - parser.add_argument( - "-d", - "--device", - dest="mojo_tty", - action="store", - default="/dev/mojo", - help="Address of the serial port for the mojo [Default: %(default)s]", - ) - parser.add_argument( - "-p", - "--progress", - dest="progress", - action="store_const", - const=True, - default=False, - help="Display progress bar while uploading.", - ) - - args = parser.parse_args() - - if args.version: - print(Version) - sys.exit(0) - - # Serial code - try: - ser = serial.Serial(args.mojo_tty, 19200, timeout=20) - except: - print("No serial port found named " + args.mojo_tty) - sys.exit(1) - - # if (not args.bitstream and not args.install and not args.copy and not args.erase and not args.only_verify and not args.reboot): - if not args.bitstream and not args.install and not args.erase: - print(parser.print_help()) - sys.exit(1) - if args.erase: - if args.verbose: - print("Preparing to erase") - erase_mojo(ser, args.verbose) - sys.exit(0) - if args.bitstream: - install_mojo( - ser, args.bitstream, args.verbose, args.no_verify, args.ram, args.progress - ) - sys.exit(0) - if args.install: - install_mojo( - ser, args.install, args.verbose, args.no_verify, args.ram, args.progress - ) - sys.exit(0) - - -def display_progress(p, width=30): - if p > 1: - p = 1 - if p < 0: - p = 0 - bar_width = int(width * p) - rem_bar_width = int(width - bar_width) - sys.stdout.write( - "\r[" + ("#" * bar_width) + (" " * rem_bar_width) + ("] (%d%%)" % int(100 * p)) - ) - sys.stdout.flush() - - -def install_mojo(ser, bitstream, verbose, no_verify, ram, progress): - file = open(bitstream, "rb") - bits = file.read() - length = len(bits) - reboot_mojo(ser, verbose) - - if ram: - ser.write(b"R") - ret = ser.read(1) - if verbose and ret == b"R": - print("Mojo is ready to recieve bitstream and write it to RAM") - elif ret != b"R": - print("Mojo did not respond correctly! Make sure the port is correct") - sys.exit(1) - - if not ram and no_verify: - ser.write(b"F") - ret = ser.read(1) - if verbose and ret == b"R": - print("Mojo is ready to recieve bitstream and write it to FLASH") - elif ret != b"R": - print("Mojo did not respond correctly! Make sure the port is correct") - sys.exit(1) - - if not ram and not no_verify: - ser.write(b"V") - ret = ser.read(1) - if verbose and ret == b"R": - print("Mojo is ready to recieve bitstream, write it to FLASH and verify it afterwards") - elif ret != b"R": - print("Mojo did not respond correctly! Make sure the port is correct") - sys.exit(1) - - buf = length.to_bytes(4, byteorder="little") - ser.write(buf) - ret = ser.read(1) - if verbose and ret == b"O": - print("Mojo acknowledged size of bitstream. Writing bitstream") - elif ret != b"O": - print("Mojo failed to acknowledge size of bitstream. Did not write") - sys.exit(1) - - if progress: - for i, bit in enumerate(bits): - ser.write(bit.to_bytes(1, byteorder="little")) - display_progress(float(i + 1) / length) - sys.stdout.write("\n") - else: - ser.write(bits) - - ret = ser.read(1) - if verbose and ret == b"D": - print("Mojo has been flashed") - elif ret != b"D": - print("Mojo failed to flash correctly") - sys.exit(1) - - if not ram and not no_verify: - ser.write(b"S") - if verbose: - print("Verifying Mojo") - ret = ser.read(1) - if ret == b"\xAA" and verbose: - print("First Byte was valid getting flash size.") - elif ret != b"\xAA": - print("Flash does not contain valid start byte.") - sys.exit(1) - ret = ser.read(4) - flash_length = int.from_bytes(ret, byteorder='little') - 5 - if flash_length == length and verbose: - print("Flash and local bitstream match file size.") - elif flash_length != length: - print("Flash is not same size as local bitstream.") - sys.exit(1) - ret = ser.read(length) - if ret == bits and verbose: - print("Flash and local bitstream are a match.") - elif ret != bits: - print("Flash and local bitstream do not match.") - sys.exit(1) - if not ram: - ser.write(b"L") - ret = ser.read(1) - if verbose and ret == b"D": - print("Mojo has been loaded bitsream") - elif ret != b"D": - print("Mojo failed to load bitstream") - sys.exit(1) - return - - -def reboot_mojo(ser, verbose): - ser.setDTR(True) - time.sleep(0.005) - for i in range(0, 5): - ser.setDTR(False) - time.sleep(0.005) - ser.setDTR(True) - time.sleep(0.005) - if verbose: - print("Rebooting Mojo") - return - - -def erase_mojo(ser, verbose): - reboot_mojo(ser, verbose) - ser.write(b"E") - ret = ser.read(1) - if verbose and ret == b"D": - print("Erased mojo successfully.") - elif ret != b"D": - print("Failed to erase Mojo. Error code: " + ret) - sys.exit(1) - ser.close() - sys.exit(0) - return - - -# main() diff --git a/scripts/upload.py b/scripts/upload.py deleted file mode 100755 index 6898986..0000000 --- a/scripts/upload.py +++ /dev/null @@ -1,178 +0,0 @@ -#!/usr/bin/env python3 -import serial -import os -import subprocess -import sys -import time -import argparse -import math - -import mojo - -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 upload_rom(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: - ser.write(b'\n') - time.sleep(0.002) - - print("Init") - ser.write(b'#') - time.sleep(0.002) - ser.write(b'u') - time.sleep(0.002) - ser.write(b'\n') - time.sleep(0.002) - - print("Target") - ser.write([0x01]) - time.sleep(0.02) - - print("Length") - size = os.path.getsize(filename) - ser.write([size & 0xFF, (size >> 8) & 0xFF]) - time.sleep(0.02) - - print("Data") - with open(filename, "rb") as f: - ser.write(f.read(size)) - - while ser.out_waiting > 0: - pass - - print("Done") - - ser.close() - - else: - print("Failed to open serial port") - -def upload_i2c(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: - ser.write(b'\n') - time.sleep(0.002) - - print("Init") - ser.write(b'#') - time.sleep(0.002) - ser.write(b'u') - time.sleep(0.002) - ser.write(b'\n') - time.sleep(0.002) - - print("Target") - ser.write([0x02]) - time.sleep(0.02) - - print("Address") - ser.write([0x29]) - time.sleep(0.02) - - print("Length") - size = os.path.getsize(filename) - ser.write([size & 0xFF, (size >> 8) & 0xFF]) - time.sleep(0.02) - - print("Data") - with open(filename, "rb") as f: - ser.write(f.read(size)) - - while ser.out_waiting > 0: - pass - - print("Done") - - ser.close() - - else: - print("Failed to open serial port") - -def upload_bload(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) - - print("Size: {} ({} pages)".format(size, math.ceil(size/256))) - - input("Press enter to start upload") - - 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 upload_sd(filename): - # @todo This does require /dev/sdb to be accessible without root - file_in = open(filename, "rb") - file_out = open("/dev/sdb", "wb") - - file_out.write(file_in.read()) - - -# @todo For now we just wrap the existing mojo.py tool -# At some point we should rewrite it from scratch -def upload_mojo(filename): - # Serial code - try: - ser = serial.Serial("/dev/ttyACM0", 19200, timeout=20) - except: - print("No serial port found named /dev/ttyACM0") - sys.exit(1) - - mojo.install_mojo(ser, filename, True, False, False, True) - -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("--bload", dest="bload", action="store_const", const=True, default=False, help="Upload binary to bload") - parser.add_argument("--mojo", dest="mojo", action="store_const", const=True, default=False, help="Upload binary to mojo") - parser.add_argument("--sd", dest="sd", action="store_const", const=True, default=False, help="Upload binary to sd card") - parser.add_argument("--i2c", dest="i2c", action="store_const", const=True, default=False, help="Upload binary to twiboot") - - args = parser.parse_args() - - if (args.rom): - upload_rom(args.filename) - elif (args.bload): - upload_bload(args.filename) - elif (args.mojo): - upload_mojo(args.filename) - elif (args.sd): - upload_sd(args.filename) - elif (args.i2c): - upload_i2c(args.filename) - else: - print("You needs to specify a target") - -if __name__ == "__main__": - main() diff --git a/setup.sh b/setup.sh index 9b93094..d731858 100755 --- a/setup.sh +++ b/setup.sh @@ -1,20 +1,8 @@ #!/bin/bash + # @todo Check if all the required programs are installed -# Cleanup old files -rm -rf arm-none-eabi -rm -rf env -rm -rf sdcc-code +./scripts/arm.sh +./scripts/microblaze.sh -wget https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2020q2/gcc-arm-none-eabi-9-2020-q2-update-x86_64-linux.tar.bz2 -O arm-none-eabi-gcc.tar.bz2 -tar xvf arm-none-eabi-gcc.tar.bz2 -mv gcc-arm-none-eabi-9-2020-q2-update arm-none-eabi -rm arm-none-eabi-gcc.tar.bz2 - -./build-mb.sh - -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 +# svn checkout svn://svn.code.sf.net/p/sdcc/code/trunk sdcc-code diff --git a/source.sh b/source.sh index 49414cf..ff9c678 100644 --- a/source.sh +++ b/source.sh @@ -1,4 +1,2 @@ -# This order makes it so we can use deactive to also deactive the other additions to the path -sudo chown tim:tim /dev/sdb -source $(dirname $(readlink -f $0))/env/bin/activate +# Add all the tools to the path PATH=$(dirname $(readlink -f $0))/arm-none-eabi/bin:$(dirname $(readlink -f $0))/microblazeel-xilinx-elf/bin:$(dirname $(readlink -f $0))/bin:/opt/Xilinx/14.7/ISE_DS/EDK/bin/lin64:/opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64:$PATH