-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsendtomodelt
executable file
·123 lines (94 loc) · 3.51 KB
/
sendtomodelt
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
121
122
123
#!/bin/bash
# sendtomodelt: Send a BASIC text file to a Tandy portable over a serial port.
# At the end of the file, sends ^Z (the Tandy BASIC EOF marker).
# Why use this instead of TELCOM? Each line is tokenized as it is
# read, which saves memory. TELCOM requires downloading the entire
# text file before it can be loaded in BASIC, so enough RAM must exist
# for both the untokenized and tokenized versions simultaneously. This
# program only keeps one line of untokenized text in RAM at any time.
# Note: If you get repeated "?DS" errors and see garbled text when you
# try LIST, then it is likely that you are using a serial port on your
# PC which does not have hardware support for XON/XOFF flow control.
# Be sure to purchase a serial card or USB adapter which advertises
# "ON CHIP SOFTWARE FLOW CONTROL". Tip: an FTDI USB cable will work.
# BUGS:
# * This is a glorified one-line program with lots of error checking.
# It ought to be just a simple 'cat $1 > /dev/ttyUSB0'.
# * And yet.... there is more that I could add that is missing. It
# does not yet check if the serial port is writable by the user.
# Nor does it check if the port is already open by another program.
# * Should probably give a hint to users if the tty is unwritable by
# * the user but is writable by the a group. (E.g., `sudo addgroup
# * dialout $USER` then re-login to get access. )
# * Not tested on MacOS.
#
# hackerb9, 2022
basename=$(basename $0)
usage() {
cat >&2 <<EOF
$basename: Send a BASIC text file to a Model T portable over the serial port.
Each line is tokenized as it is read, which saves memory.
Usage: $basename <filename> [serial port]
Longer example:
1) On Tandy Model 100/102/200, type:
LOAD "COM:98N1ENN"
2) a. On UNIX host, type:
$basename FILENAME.DO
b. Wait for the Tandy to say "Ok"
c. Hit Enter to close the serial port
3) OPTIONAL: When done, you may want to:
SAVE "FILENM"
EOF
}
listports() {
shopt -s nullglob
printf "%s\n" /dev/cu.* /dev/ttyUSB* /dev/ttyS* /dev/ttyACM*
}
if [[ "$1" == "-h" || "$1" == "--help" ]]; then
usage
exit
fi
if [[ $2 ]]; then
serial=$2
else
serial=$(listports | head -1)
fi
if [[ ! -e $serial ]]; then
echo "$serial does not exist. Maybe try $basename $1 /dev/ttyS0?"
exit 1
fi
# Configure serial port the way the Tandy portables like.
#
# icanon: Read from serial port one line at a time. (For receiving, EOF).
sttyargs+=(icanon)
# ixon: Enable processing of software flow control in received data.
# ixoff: Enable XON/XOFF if PC gets overwhelmed by Model T (unlikely).
# stop ^S: Use the standard software flow control character for XOFF...
# start ^Q: ... same for XON.
sttyargs+=(ixon ixoff stop ^S start ^Q)
# -onlcr: Do not turn newlines into carriage returns on output...
# -icrnl: ... nor vice versa.
sttyargs+=(-onlcr -icrnl)
# susp '': Incoming ^Z is no longer bound to Suspend. (For receiving).
# eof ^Z: Incoming ^Z character is now End-of-File. (For receiving).
sttyargs+=(susp '' eof ^Z)
# -echo: Do not echo received characters. (For receiving).
sttyargs+=(-echo)
# 19200: Bits per second ("baud rate").
# pass8: 8-bit characters, no parity
# -cstopb: 1 stop bit
sttyargs+=(19200 pass8 -cstopb)
#
echo stty -F $serial "${sttyargs[@]}"
stty -F $serial "${sttyargs[@]}"
# Note: Running with no filename sets up the serial port before exiting.
if [[ -z $1 ]]; then
usage
exit 1
fi
echo "cat $1 >$serial" >&2;
{
cat "$1";
echo $'\cZ';
read -p 'Hit Enter when Model T says, "Ok". ';
} >$serial