Skip to content

markjenkins/knightpies

Repository files navigation

A Python implementation of the Knight instruction architecture found in Jeremiah Orians' stage0 project:
https://github.com/oriansj/stage0

knightpies is licensed under GNU GPL v3 or later, see LICENSE

Currently incomplete, knightpies can only run the instructions used by stage0/stage0_monitor, stage1/stage1_assembler-0, stage1/stage1_assembler-1, and stage1/stage1_assembler-2. See ROADMAP for the plans to add more on the pathway to a 1.0 release and to full compatibility with stage0/vm_instructions.c. Patches and pull requests targeting that order of attack are most welcome.

See RATIONAL for why I'm writing this.

Attempts have been made to remain compatible with Python 2.2 and later in the main code and Python 3.2 and later in the test suite. I'm interested in remaining compatible with both CPython (python.org) and PyPy (pypy.org) implementations. These compatibility goals hasn't been tested yet.

Programs you can invoke:

$ ./hex0tobin.py
Takes a hex0 file (first argument) and encodes the parts in hex into a binary output file (second argument), ignoring comments

$ ./hex1tobin.py
Takes a hex1 file (first argument), encodes the parts in hex into binary output, identifies 1 letter labels marked with colon ":",  replaces references to those labels prefixed with @ with relative 16 bit addresses, and ignores comments (";" and "#")

$ ./hex2tobin.py
Takes a hex2 file (first argument), encodes the parts in hex into binary output, identifies multi-character labels marked with colon ":",  replaces references to those labels prefixed with @ with relative 16 bit addresses, references prefixed with $ as 16 bit pointers, referenced prefixed with & as 32 bit addresses, and ignores comments (";" and "#")

$ ./M1.py
Takes knight assembler (.s) files and outputs hex2 to either standard out or to a file if you have '-o' or '--output' followed by space and an output file name. Unless your have your assembler macro definitions concatenated into your .s file, you would normally put stage0/High_level_prototypes/defs as a first argument to get Knight instruction defenitions. The hex2 output is not currently whitespace compatible with M0-macro.s / M0-macro.c / M1-macro.c, but after conversion to a binary you'll end up with the same result.
For example
$ ./M1.py stage0/High_level_prototypes/defs stage0/stage0/stage0_monitor.s \
  -o stage0/stage0/stage0_monitor.hex2
$ mkdir -p stage0/roms
$ ./hex2tobin stage0/stage0/stage0_monitor.hex2 stage0/roms/stage0_monitor
$ sha256sum stage0/roms/stage0_monitor
$ grep stage0_monitor stage0/test/SHA256SUMS

M1.py also has a special mode --dump-defs-used for dumping which defined macros are used in a given set of assembler files. The output always goes to standard out:
$ ./M1 --dump-defs-used stage0/High_level_prototypes/defs stage0/stage0/stage0_monitor.s

$ ./M1tobin.py
Combines knight assembly, linking and hex encoding (hex2) into one command. If you have all your knight definitions and code in one file you can us a simple two argument version
$ ./M1tobin.py input_file output_file
Often that won't be the case if you're going to use the definitions in stage0/High_level_prototypes/defs first and other .s files second, so you'll need -o or --output for the output file. For example:
$ ./M1tobin.py stage0/High_level_prototypes/defs stage0/stage0/stage0_monitor.s -o stage0/roms/stage0_monitor
$ sha256sum stage0/roms/stage0_monitor
$ grep stage0_monitor stage0/test/SHA256SUMS

$ ./knightvm_minimal.py
This is largely compatible with stage0/vm_minimal.c, accepting a Knight rom binary file as its first argument and acting upon tape_01 and tape_02 files in the current working directory. The only difference is that an additional --rom-hex argument (after the file name, not before) can be provided if the rom is in the hex0 format of the stage0 project.
Example invocations:
$ ./knightvm_minimal.py stage0_monitor
$ ./knightvm_minimal.py stage0/stage0/stage0_monitor.hex0 --rom-hex

At this stage, invocation is better illustrated by the test suite, which doesn't rely on the limitations of knightvm_minimal.main and instead directly calls relevant functions to set up knight ISA tape IO.

The test suite (knighttests) relies upon the stage0 code base. Revision 2988d0e3913f9767b2026ccb95df55ec303576f3 (Release_0.2.0) of the stage0 project is referenced as a git submodule, you can bring that up with git submodule [1] commands
$ git submodule init
$ git submodule update
https://git-scm.com/book/en/v2/Git-Tools-Submodules

It's also possible to clone knightpies, stage0 and all stage0 sub-modules recursively:
$ git clone --recurse-submodules

You can also supply your own copy of the stage0 code instead of using the submodule feature. If you want to use stage0 from another directory, you could make a symlink or stage0dir.py allows you to specify another location.

The test suite mostly works with stage0 revision 09536c775df8bee4952c4a09eba97079d083adea (Release_0.4.0), the exceptions are knighttests/test_parallel_execution.py, test_parallel_execution_stage1.py and test_parallel_execution_stage1_M0.py which need some further work to be compatible. These tests can be skipped, see below.

You can run individual test cases with
$ python3 -m knighttests.test_module_name
or
$ ./runtestmodule.py knighttests/test_module.py
direct invocation of some of the test files does not work.

Run the entire test suite with
$ ./run_tests.py
add -v for verbose output, other python unittest discover sub-command flags work too.

On top of python unittest discover flags, both scripts accept  '--skip-optimize' and '--skip-diff-reg-size' to skip variations of the same tests using register size optimized versions of instructions and variations with 64 bit and 16 bit register sizes.

$ ./run_tests.py also accepts --skip-parallel to skip the parallel tests.

They are the most interesting tests, though.
$ python3 -m knighttests.test_parallel_execution
and
$ python3 -m knighttests.test_parallel_execution_stage1
take advantage of stage0/User_Interface.py and stage0/wrapper.c to run our python implementation and the original C implementation in parallel, comparing the respective registers and program stacks after every instruction is run.

This requires libvm.so from stage0 to be built:
$ cd stage0
$ make libvm.so
$ cd ../
$ ln -s stage0/libvm.so libvm.so
$ python3 -m knighttests.test_parallel_execution

so you may also find
$ ./run_tests.py --skip-parallel
convenient if you'd like to run the rest of the test suite, but building libvm.so isn't desired or possible.

-- Mark Jenkins <mark@markjenkins.ca>


Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved.  This file is offered as-is,
without any warranty.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published