#!/usr/bin/env python3 import os import socket import time mod_prolog = [ "rom/croot.c", "rom/fsmain.s" ] mod_iolib = [ "lib/dofmt.c", "lib/mdump.c", "lib/pause.c", "lib/printf.c", "lib/rawio.c", "lib/sprintf.c", "lib/waitcr.c", "lib/hwdefs.s", "lib/rtraps.s", "lib/setipl.s", "lib/setsr.s", "lib/traps.s" ] mod_libcio = [ "lib/atoi.c", "lib/atol.c", "lib/blkrd.c", "lib/blkwr.c", "lib/close.c", "lib/clusmap.c", "lib/conin.c", "lib/conwr.c", "lib/dirfns.c", "lib/fgets.c", "lib/filesys.c", "lib/filname.c", "lib/flread.c", "lib/fopen.c", "lib/fprintf.c", "lib/fputs.c", "lib/fread.c", "lib/fscanf.c", "lib/fseek.c", "lib/fsinit.c", "lib/fsize.c", "lib/fstubs.c", "lib/ftell.c", "lib/fwrite.c", "lib/getbuff.c", "lib/getc.c", "lib/getl.c", "lib/getw.c", "lib/lseek.c", "lib/open.c", "lib/posit.c", "lib/putc.c", "lib/putl.c", "lib/putw.c", "lib/read.c", "lib/readrn.c", "lib/rename.c", "lib/scan.c", "lib/setbuf.c", "lib/ungetc.c", "lib/unlink.c", "lib/write.c", "lib/writern.c", "lib/ptcl12.s" ] mod_libsm = [ "lib/index.c", "lib/memccpy.c", "lib/memchr.c", "lib/memcmp.c", "lib/memcmpu.c", "lib/memcpy.c", "lib/memcpyw.c", "lib/memset.c", "lib/memsetw.c", "lib/rindex.c", "lib/str2lc.c", "lib/str2uc.c", "lib/strcat.c", "lib/strccpy.c", "lib/strchr.c", "lib/strcmp.c", "lib/strcpy.c", "lib/strcspn.c", "lib/strfill.c", "lib/strlcmp.c", "lib/strlen.c", "lib/strltrm.c", "lib/strncat.c", "lib/strncmp.c", "lib/strncpy.c", "lib/strpbrk.c", "lib/strrchr.c", "lib/strrev.c", "lib/strrevi.c", "lib/strrtrm.c", "lib/strspn.c", "lib/strtok.c", "lib/strtol.c" ] mod_lib700 = [ "lib/bitrev.c", "lib/ctype.c", "lib/ispow2.c", "lib/mangle.c", "lib/micons.c", "lib/tolower.c", "lib/toupper.c", "lib/aldiv.s", "lib/almul.s", "lib/alrem.s", "lib/blkfill.s", "lib/blkmove.s", "lib/finalone.s", "lib/jumpto.s", "lib/ldiv.s", "lib/lmul.s", "lib/lrem.s", "lib/rand24.s", "lib/setjmp.s", "lib/uldiv.s" ] mod_vlib = [ "lib/cg2.c", "lib/cg3.c", "lib/glcinit.c", "lib/lseg.c", "lib/vbfill4.c", "lib/vclrs.c", "lib/vhinit.c", "lib/vmput.c", "lib/vobjfns.c", "lib/vputs.c", "lib/vputsv.c", "lib/vsetpal.c", "lib/vsinit.c", "lib/vspray4.c", "lib/vtext.c", "lib/vwputm.c", "lib/acctrl.s", "lib/glcplot.s", "lib/tsplot4.s", "lib/vbank.s", "lib/vclrav.s", "lib/vcputs.s", "lib/vcputsv.s", "lib/viint.s", "lib/vputa.s", "lib/vputc.s", "lib/vputcv.s", "lib/vputp.s", "lib/vsetav.s", "lib/vsetcv.s", "lib/vsplot4.s", "lib/vvputsv.s", "lib/vwputp.s", "lib/vwputs.s" ] mod_rom = [ "rom/booter.c", "rom/romp.c", "rom/bios.s", "rom/timeint.s" ] codes = { "-": 12, "=": 13, "\b": 14, "\t": 15, "`": 41, "[": 26, "]": 27, "\n": 28, ";": 39, "'": 40, "\\": 43, ",": 51, ".": 52, "/": 53, " ": 57 } codes_shifted = { "!": 2, "@": 3, "#": 4, "$": 5, "%": 6, "^": 7, "&": 8, "*": 9, "(": 10, ")": 11, "_": 12, "+": 13, "~": 41, "{": 26, "}": 27, ":": 39, "\"": 40, "|": 43, "<": 51, ">": 52, "?": 53 } sig_path = "hatari/d/signal" lis_path = "/tmp/buchla.sock" con = None def hatari_connect(): lis = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) if os.path.exists(lis_path): os.unlink(lis_path) lis.bind(lis_path) lis.listen(1) global con (con, _) = lis.accept() def hatari_send(command): global con con.sendall((command + "\n").encode("ascii")) def send_alnum(c): hatari_send("hatari-event keypress {}".format(c)) def send_code(code): hatari_send("hatari-event keypress {}".format(code)) def send_code_shifted(code): hatari_send("hatari-event keydown 42") send_code(code) hatari_send("hatari-event keyup 42") def send_line(line): line += "\n" for c in line: if c in codes: send_code(codes[c]) elif c in codes_shifted: send_code_shifted(codes_shifted[c]) else: send_alnum(c) time.sleep(0.1) def run_command(command): if os.path.exists(sig_path): os.unlink(sig_path) print("Executing {}".format(command)) send_line(command + "; touch d:\\signal") print("Waiting for completion") while not os.path.exists(sig_path): time.sleep(0.5) os.unlink(sig_path) def assemble(dir, base): print("Assembling {}.s in {}".format(base, dir)) run_command("cp d:\\{}\\{}.s code.s".format(dir, base)) run_command("as code") run_command("cp code.o d:\\out\\{}.o".format(base)) run_command("rm code.o") run_command("rm code.s") send_line("") def compile(dir, base): print("Compiling {}.c in {}".format(base, dir)) run_command("cp d:\\{}\\{}.c code.c".format(dir, base)) run_command("cc code") run_command("as code") run_command("cp code.s d:\\out\\{}.s".format(base)) run_command("cp code.o d:\\out\\{}.o".format(base)) run_command("rm code.o") run_command("rm code.s") run_command("rm code.c") send_line("") print("Waiting for Hatari to connect to {}.".format(lis_path)) hatari_connect() print("Hatari connected.") input("Please start C:\\BIN\\SH.TTP manually, then press enter.") send_line("PATH=\\bin") send_line("cd \\work") start_at = None for mod in [mod_prolog, mod_iolib, mod_libcio, mod_libsm, mod_lib700, mod_vlib, mod_rom]: for path in mod: if start_at != None: if start_at != path: continue else: start_at = None (dir, file) = path.split("/") (base, ext) = file.split(".") if ext == "s": assemble(dir, base) elif ext == "c": compile(dir, base) else: raise Exception("file {} with invalid extension {}".format(file, ext))