-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathterminal.py
120 lines (99 loc) · 3.88 KB
/
terminal.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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# A simple terminal program.
#
# Can be used for any communication with the Sirichote 68008 kit,
# but especially suited for the Lox68k interpreter, since uploading
# Lox source files is possible via the F2 key.
#
# Line feeds in the source files are converted to ASCII record separator
# chars, which 'gets()' on the 68008 Kit accepts and indicate a new line
# there, but don't terminate input yet.
#
import msvcrt
import serial
import time
import os
# Adapt pathes etc. for your needs here
ser = serial.Serial("COM8:", baudrate=9600, timeout=0)
transcript = open("transcript.log", "w")
loxPattern = "lox/{}.lox"
hexPattern = "../FBI/{}.hex"
encoding = "ascii" # The Monitor getchar() only reads 7 bits to allow fast processing, so
# we restrict the entire serial protocol to pure 7 bit ASCII
CHAR_RS = b'\x1e' # ASCII record separator, passes thru gets(), but marks new line for Lox (scanner.c:11)
anti_stress_delay = 0.0005 # Avoid too much CPU load when waiting for a char from serial or key press
char_delay = 0.003 # Time to wait for char sent to the Kit is echoed back.
line_delay = 0.01 # Same for newline char.
def transcript_char(char):
if char == '\r':
pass # ignore the extra CR sent from the Kit
elif char == '\b':
transcript.seek(transcript.tell()-1) # backspace from Kit: remove last char transcripted
else:
transcript.write(char)
def response():
resp = ser.read(1)
if resp == CHAR_RS: resp = b'\n' # Convert back
char = resp.decode(encoding, errors="ignore");
print(char, end="", flush=True)
transcript_char(char)
def terminal_help():
print("Any input is sent to 68008 kit via serial port, any response from it is displayed here.")
print("Ctrl-ENTER: Send a line break to Lox, but don't terminate input, yet.")
print("F2: Upload a LOX source file to the Lox68k REPL.")
print("F3: Upload a HEX file, press LOAD button on the Kit before.")
print("Ctrl-C: Quit terminal")
def uploadLOX():
print("Upload LOX file: ", end="")
name = input()
try:
path = loxPattern.format(name)
if os.stat(path).st_size >= 16384:
print("...file too large to load.")
else:
with open(path, "r") as loxFile:
for line in loxFile:
for char in line.rstrip('\n'):
time.sleep(char_delay)
ser.write(char.encode(encoding, errors="replace"))
response()
time.sleep(char_delay)
ser.write(CHAR_RS)
response()
time.sleep(line_delay)
ser.write(b'\n')
except FileNotFoundError:
print("...not found.");
def uploadHEX():
print("Upload HEX file: ", end="")
name = input()
try:
with open(hexPattern.format(name), "r") as hexFile:
for line in hexFile:
for char in line:
ser.write(char.encode(encoding))
except FileNotFoundError:
print("...not found.");
def terminal_loop():
while True:
time.sleep(anti_stress_delay)
if msvcrt.kbhit():
key = msvcrt.getwch()
if key == '\x00' or key == '\xe0':
key = msvcrt.getwch()
if key == ';': # F1
terminal_help()
elif key == '<': # F2
uploadLOX()
elif key == '=': # F3
uploadHEX()
elif key == '\x0a': # Ctrl-ENTER -> new line in input, but not completed yet
ser.write(CHAR_RS)
else:
ser.write(key.encode(encoding, errors="replace"))
response()
try:
terminal_loop()
except KeyboardInterrupt:
print("=== Terminal terminated, transcript closed. ===")
finally:
transcript.close()