Toggle navigation
Toggle navigation
This project
Loading...
Sign in
Franck Pommereau
/
ttc.js
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
Franck Pommereau
2023-04-06 11:25:55 +0200
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
be38c0f52b6d921a89ce6691cc2b749abbe1ea33
be38c0f5
1 parent
56e4e59a
improved 'ttc run' with '-C' option and 'when' command
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
31 additions
and
9 deletions
test/fact.test
ttc/__main__.py
ttc/run.py
ttc/test.py
test/fact.test
View file @
be38c0f
# source: ../www/examples/fact.ttc
# cycles: 100
# clock: False
wait halted
assert "R0 == 720"
quit
...
...
ttc/__main__.py
View file @
be38c0f
...
...
@@ -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"
:
...
...
ttc/run.py
View file @
be38c0f
...
...
@@ -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
:
...
...
ttc/test.py
View file @
be38c0f
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
])
...
...
Please
register
or
login
to post a comment