#!/usr/bin/env python

import sys
import struct
import time
import array
import re

import gameduino.remote
import gameduino.prep as gdprep
import gameduino


code = open("dump.eforth").read()

hh = open("../eforth-nuc.h", "w")
gdprep.dump(hh, "nuc", array.array('B', code[:-2]))
print >>hh, ("#define NUC_ENTRY %#x" % struct.unpack("<H", code[-2:]))
hh.close()

gd = gameduino.remote.Gameduino(sys.argv[1], 115200)
gd.wr(gameduino.J1_RESET, 1)
print "J1_RESET", gd.rd(gameduino.J1_RESET)
time.sleep(1)
gd.ascii()
gd.wrstr(0x4000, code[:-2])
gd.fill(gameduino.COMM, 0, 48)
gd.wr16(gameduino.COMM, *struct.unpack("<H", code[-2:]))

gd.wr16(gameduino.COMM+2, 0x4000 + len(code) - 2)
gd.wr(gameduino.COMM + 5, 0)
gd.microcode(open("eforth.binle").read())

def frobch():
    if gd.rd(gameduino.COMM + 7) != 0:
        c = chr(gd.rd(gameduino.COMM + 6))
        sys.stdout.write(c)
        sys.stdout.flush()
        gd.wr(gameduino.COMM + 7, 0)

if 1:
    def runscreen():
        gd.wr(gameduino.COMM + 5, 1)
        while gd.rd(gameduino.COMM + 5) == 1:
            frobch()
        gd.wrstr(0, 1024 * " ")
    a = open("screens.fs").read()
    starts = [m.start() for m in re.finditer("\( [0-9][0-9]: .*\)", a)] + [len(a)]
    ranges = zip(starts, starts[1:])
    screens = [a[start:end].rstrip() for (start,end) in ranges]

    for i,s in enumerate(screens):
        print s
        dat = ""
        for (j,l) in enumerate(s.split('\n')):
            assert j < 16, "overflow screen %d: %s" % (i, l)
            l = l.rstrip().ljust(64)
            assert len(l) == 64
            dat += l
        gd.wrstr(0, dat)
        runscreen()

# time.sleep(1)
# gd.dump(gameduino.COMM,48)

while True:
    while gd.rd(gameduino.COMM + 7) == 0:
        pass
    c = chr(gd.rd(gameduino.COMM + 6))
    if False and c == '#':
        gd.dump(0x4780, 256)
    else:
        sys.stdout.write(c)
        sys.stdout.flush()
    gd.wr(gameduino.COMM + 7, 0)
