Franck Pommereau

improved 'ttc run' with '-C' option and 'when' command

# source: ../www/examples/fact.ttc
# cycles: 100
# clock: False
wait halted
assert "R0 == 720"
quit
......
......@@ -31,6 +31,8 @@ runparser.add_argument("-w", "--watch", metavar="PATTERN",
help="watch events matching PATTERN")
runparser.add_argument("-m", "--max-cycles", metavar="MAX", type=int, default=None,
help="stop run after MAX cycles")
runparser.add_argument("-C", "--no-clock", dest="clock", default=True, action="store_false",
help="disable clock interrupt")
runparser.add_argument("bios", metavar="INFILE", type=argparse.FileType(),
help="BIOS file to run")
# tester
......@@ -75,7 +77,7 @@ elif args.command == "run" :
except :
print_errors({f"{addr:04X}" : (word, ["invalid BIOS content"])})
ret = cli(bios, interactive=args.interactive, script=args.script,
watch=args.watch, max_cycles=args.max_cycles)
watch=args.watch, max_cycles=args.max_cycles, clock=args.clock)
if ret is not None :
sys.exit(ret)
elif args.command == "test" :
......
......@@ -60,9 +60,11 @@ class Runner (object) :
print(f"{F.RED}[ttc]{S.RESET_ALL} {msg}")
def msg (self, msg) :
print(f"{F.GREEN}[ttc]{S.RESET_ALL} {msg}")
def watch (self, event) :
def watch (self, event, cb=None) :
if cb is None :
cb = self.print_event
if event not in self._evid :
self._evid[event] = self.sim.connect(event, self.print_event)
self._evid[event] = self.sim.connect(event, cb)
def ignore (self, event) :
if event in self._evid :
self.sim.disconnect(self._evid.pop(event))
......@@ -409,6 +411,14 @@ class ShellRunner (Runner) :
"""
for evt in event :
self.watch(evt)
async def cmd_when (self, event:str, cmd:str, *args:str) :
"""execute command on specified event
- cmd: a shell command
- args: arguments for cmd"""
def cb (e, *a) :
loop = asyncio.get_event_loop()
asyncio.run_coroutine_threadsafe(self._cmd_call(cmd, args), loop)
self.watch(event, cb)
async def cmd_ignore (self, *event:str) :
"""ignore specified events
- event: event to be ignored (unwatched)
......@@ -537,11 +547,11 @@ class ShellRunner (Runner) :
else :
self.err(f"cannot print unknown component {comp!r}")
def cli (bios, interactive=False, script=None, watch=[], max_cycles=None) :
def cli (bios, interactive=False, script=None, watch=[], max_cycles=None, clock=True) :
global CLIRET
CLIRET = None
sim = simul.Simulator()
ttc = TTC(bios)
ttc = TTC(bios, clock=clock)
if interactive or script is not None :
run = ShellRunner(ttc, sim, script, interactive, max_cycles)
else :
......
import sys, subprocess
import sys, subprocess, ast
from pathlib import Path
from tempfile import NamedTemporaryFile
......@@ -11,13 +11,16 @@ class Tester (object) :
if (source := params.pop("source", None)) is None :
self.die(f"missing '# source: PATH' in '{script}'")
try :
max_cycles = int(params.pop("cycles", "0")) or None
max_cycles = int(params.pop("cycles", 0)) or None
except :
self.die("invalid '# cycles:'")
source = script.parent / source
with NamedTemporaryFile(suffix=".rom", mode="r") as rom :
self.asm(str(source), rom.name)
self.run(str(script), rom.name, max_cycles, params.pop("watch", "").split())
self.run(str(script), rom.name,
max_cycles,
params.pop("watch", "").split(),
params.pop("clock", True))
def die (self, step, status=1) :
sys.stderr.write(f"{F.RED}{S.BRIGHT}{step} failed{S.RESET_ALL}\n")
sys.exit(status)
......@@ -29,6 +32,10 @@ class Tester (object) :
if not ":" in line :
break
par, val = (x.strip() for x in line[1:].strip().split(":", 1))
try :
val = ast.literal_eval(val)
except :
pass
params[par.lower()] = val
return params
def asm (self, source, rom) :
......@@ -36,10 +43,12 @@ class Tester (object) :
subprocess.check_call([sys.executable, "-m", "ttc", "asm", source, rom])
except subprocess.CalledProcessError as err :
self.die("asm", err.returncode)
def run (self, script, rom, max_cycles, watch) :
def run (self, script, rom, max_cycles, watch, clock) :
argv = [sys.executable, "-m", "ttc", "run"]
if max_cycles :
argv.extend(["-m", str(max_cycles)])
if not clock :
argv.extend(["-C"])
for w in watch :
argv.extend(["-w", w])
argv.extend(["-s", script, rom])
......