How Slow Was the Teletype?
How slow was the Teletype? | We Love Open Source - All Things Open

            
            A community education resource
        
                                        
                        September 4, 2024
                                                    5 min read                    
                                            
                    How slow was the Teletype?
                    Slow down the output of a program to see what it was like to use an original terminal.                    
                    
                                        
                                                                            
                                
                                                            Image by PublicDomainPictures from Pixabay
                                                        
                                            
                    
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.



Photo of an acoustic coupler modem (image: Rama, CC-By-SA), source WikiMedia Commons.



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.



Photo of the Teletype Model 33 (image: Jim Hall, CC-By-SA)



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











                                                                
                                                                        
                                About the Author
                                Jim Hall is an open source software advocate and developer, best known for usability testing in GNOME and as the founder + project coordinator of FreeDOS. At work, Jim is CEO of Hallmentum, an IT executive consulting company that provides hands-on IT Leadership training, workshops, and coaching.
                                Read Jim's Full Bio                                
                            
                                                            

                    

                    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.

                    
    Want to contribute your open source content?


        