-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathknightvm_minimal.py
executable file
·93 lines (82 loc) · 3.08 KB
/
knightvm_minimal.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#!/usr/bin/env python
#
# A derivitive port of:
# https://github.com/oriansj/stage0/blob/master/vm_minimal.c
#
# Copyright (C) 2019 Mark Jenkins <[email protected]>
# This file is part of knightpies
#
# knightpies is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# knightpies is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with knightpies. If not, see <http://www.gnu.org/licenses/>.
from sys import stderr, exit
from string import hexdigits
from pythoncompat import print_func, COMPAT_FALSE, COMPAT_TRUE
from constants import REG, EXIT_SUCCESS, EXIT_FAILURE
from knightdecode import \
MEM, HALTED, \
create_vm, grow_memory, \
get_read_and_eval_for_register_size
from hex0tobin import int_bytes_from_hex0_fd
def load_program(vm, romfilename):
# binary mode because we don't want python's opinion of encoding, newlines
f = open(romfilename, 'rb')
f.seek(0,2) # seek to end so we can find filesize
filesize = f.tell()
f.seek(0)
# this is intended to operate at the start of memory before allocation
assert len(vm[MEM])==0
vm[MEM].fromfile(f, filesize)
f.close()
def load_hex_program(vm, hexromfilename):
# this is intended to operate at the start of memory before allocation
assert len(vm[MEM])==0
f = open(hexromfilename)
for input_byte in int_bytes_from_hex0_fd(f):
vm[MEM].append(input_byte)
f.close()
def execute_vm(vm, optimize=COMPAT_TRUE, halt_print=COMPAT_TRUE):
if optimize:
read_and_eval_register_size_specific = \
get_read_and_eval_for_register_size(vm[REG].itemsize)
else:
read_and_eval_register_size_specific = \
get_read_and_eval_for_register_size(0)
while not vm[HALTED]:
vm = read_and_eval_register_size_specific(
vm, halt_print=halt_print)
def do_minimal_vm(romfile, romhex=COMPAT_FALSE, memory_size=1<<21):
vm = create_vm(size=0, registersize=32)
if romhex:
load_hex_program(vm, romfile)
else:
load_program(vm, romfile)
grow_memory(vm, memory_size)
execute_vm(vm)
def main(args):
if len(args)<2:
print_func("Usage: %s $FileName" % args[0], file=stderr)
print_func("Where $FileName is the name of the paper tape of the"
"program being run", file=stderr)
exit(EXIT_FAILURE)
else: # len(args)>=2
filename = args[1]
if len(args)==2:
do_minimal_vm(filename)
else:
assert len(args)>2
romhex = args[2]=="--rom-hex" # check for rom-hex flag, set romhex
do_minimal_vm(filename, romhex=romhex)
exit(EXIT_SUCCESS)
if __name__ == "__main__":
from sys import argv
main(argv)