We ❤️ Open Source
A community education resource
How slow was the Teletype?
Slow down the output of a program to see what it was like to use an original terminal.
For years, computers didn’t use networks to talk to one another; instead they “dialed up” other computers using a device called a modem which modulated and demodulated signals over a phone line, like whistling at different pitches.
The first modems were very essential with a speaker and microphone, and you socketed your phone’s handset into a special receiver with rubber pads that acted as sound insulation. These acoustic coupler modems were typically capable of transmission speeds of about 150 bits per second, called 150 baud.
This worked well for terminals of the era, like the Teletype Model 33, which could print at about 10 characters per second. Ken Thompson created Unix at Bell Labs using a Teletype 33. Later, Bell Labs upgraded to the Teletype Model 37, which could print in both uppercase and lowercase letters, and included a limited set of mathematical symbols—useful for printing scientific documents. The Teletype Model 37 ran slightly faster at 15 characters per second.
Doing the math: If we assume 1 byte per character and 8 bits per byte, we can convert “characters per second” to “baud” by multiplying by 8, or convert “baud” to “characters per second” by dividing by 8. For example, if the Teletype 37 could print 15 characters per second, that’s about 15 × 8 = 120 baud.
In an era where home Internet speeds might be 25 Mbps, or 25 mega bits per second, it’s hard to imagine computers running as slow as 120 baud. To see what “120 baud” looked like, we have to do some trickery at the terminal to effectively slow down the output of a program.
Slowing down the output
Printing to a terminal app window is almost instantaneous, but we can simulate this slower transmission speed by inserting a pause between printing each character. To convert “baud” into “seconds per character,” we just invert the math. Given a baud rate of “120 baud” (the printing speed of a Teletype Model 37 terminal) we can divide 8 by the baud rate, and wait that many seconds between printing each character. So to simulate “120 baud,” we need to wait 8 ÷ 120 = 0.0666 … seconds between each character.
The unistd.h
library has a function called usleep
which pauses for a certain number of microseconds. This is enough for us to emulate slower modem speeds from back in the day. At 1,000,000 microseconds in one second, the math is 8,000,000 ÷ 120 = 66,666 microseconds delay between printing each letter to simulate the “120 baud” printing speed of the original Teletype Model 37.
With this conversion, we can write a short C program to simulate any baud rate, by displaying the contents of a file. The pseudocode for this program is this:
- Convert “baud rate” to microseconds
- Read a file from standard input
- For each character in the file:
- Print the character
- Wait for the “microsecond” delay
Converting to microseconds
Programs are more flexible if they can take options from the command line. For this program, assume the first command line option is the “baud rate” that we need to simulate. We can use atoi
to convert this string into an integer, or atol
to convert the string to a long integer. After that, we only need to divide 8,000,000 by the “baud rate” to get the microsecond delay. A simple implementation might look like this:
int main(int argc, char **argv)
{
long baud;
useconds_t udelay;
if (argc >= 2) {
baud = atol(argv[1]);
}
else {
baud = 120;
}
udelay = 8000000 / baud;
return 0;
}
This tests if the command line has at least one option. The argument count or argc
will be 1 if there are no options, because the argument vector or argv
will only contain the name of the program. Similarly, argc
will be 2 if the command line has just one option, and so on.
Printing with a delay
Once we have the microsecond delay, we can use that when printing text to the screen. Let’s say the udelay
variable has the value of 66666, which is the microsecond delay for 120 baud. A simple program to read from standard input or stdin
and print to standard output or stdout
, might look like this:
int main()
{
useconds_t udelay;
int ch;
udelay = 66666;
while ((ch = getchar()) != EOF) {
usleep(udelay);
putchar(ch);
fflush(stdout);
}
return 0;
}
This uses the simple method of reading and writing one character at a time, which is usually slow for most file operations, but fast enough to simulate a very slow baud rate. Usually, the standard output will display the output one line at a time, because it “flushes” the output after each newline. To see each character as it is printed to the terminal, we need to use the fflush
function to flush the standard output on our own.
A sample program
Using these examples, we can create a program that takes the “baud rate” as the first command line option, then prints each character with an appropriate delay to simulate that baud rate:
#include <stdio.h>
#include <stdlib.h> /* atol */
#include <unistd.h> /* usleep */
int main(int argc, char **argv)
{
long baud;
useconds_t udelay;
int ch;
if (argc > 2) {
fputs("usage: baud [ baudrate ]\n", stderr);
return 1;
}
/* get delay */
if (argc == 2) {
baud = atol(argv[1]);
if (baud < 1) {
fputs("baud rate too low\n", stderr);
return 2;
}
}
else {
baud = 120;
}
udelay = 8000000 / baud;
/* read from input, print to output */
while ((ch = getchar()) != EOF) {
usleep(udelay);
putchar(ch);
fflush(stdout);
}
return 0;
}
Save this file as baud.c
and compile it using the GNU C Compiler:
$ gcc -o baud baud.c
See it in action
Because the program reads from the standard input, you can use this program as a filter to slow down how text is printed to the screen. For example, to display the contents of a file at 120 baud, you can use cat
to read a file and display the contents with baud
:
$ cat file | ./baud
But a more direct method is to use the “less than” operator (<
) to redirect a file as the standard input to the baud
program:
$ ./baud < file
The opinions expressed on this website are those of each author, not of the author's employer or All Things Open/We Love Open Source.