# IBM Machine Code Printer Control Characters

Early mainframe printers were usually line printers. Line printers provide a limited set of commands to control how the paper is advanced when print lines are printed. The application writing reports, list, etc. to be printed has to include those commands in the print data. These single character print commands are called printer control characters.

## Introduction into Print Control Characters

Printer control characters and Carriage control characters are IBM mainframe terms that denote the special meaning which the first character on a line of printable text may have. The first character of each line of text is interpreted as a control character or printer command instead of a character to be printed if a corresponding attribute is set for the print data set (data set is mainframe speak for what is known as a file on other operating systems).

### How Printer Control Characters work

While mostly replaced by an electronic versions later on, line printers initially used a loop of punched paper tape to control the movement of the paper while printing. This tape is called a carriage control tape and is mounted on the printer. The looped carriage tape moves synchronously with the stream of fanfold paper.
The line printers have 12 sensors to recognize 12 independent positions on the carriage control tape. Each position is called a channel, numbered from 1 to 12. If a hole is punched in a channel, then this hole marked a position on the page that the printer can 'jump to' quickly by advancing until the hole is sensed by the corresponding channel sensor. This is called skip to channel number n.
Commands are implemented so that each of the 12 channels can be jumped to. Instead of having to write empty print lines, applications can simply jump to a predefined channel if nothing is to be written between the current position and the target position, a huge performance gain at that time.
In addition to those skip to channel commands, there are other commands that the printer interprets to either stay at the current line or to space one, two, or three lines. By staying on the current line, one can create:
* Bold text by rewriting the same text two or three times on the same line. More ink was put on the paper by this repeated printing which lead to kind of bold text appearance.
* Underlined text by writing underline characters at the desired positions after writing the text to be underlined.
* Struck through text by writing dash characters at the desired positions after writing the text to be struck through.
Instructing the printer to skip to a channel which is not punched will cause the printer to continue to feed paper at high speed. This might be caused by a mismatch between the tape installed and the one the application expects.

#### Special Meaning of Channel 1

By convention the position on a sheet of paper where the first print line has to be written is associated with Channel 1. For example, if the first line of text has to always be on physical line 3 for a given form, then the channel 1 hole has to be punched in line 3 of the carriage control tape.
By convention, IBM mainframe applications always jump to channel 1 when beginning a new logical page.
Channel 12 is less common, but usually indicates a line on the page where a footer can be printed.

## Types of Printer Control Characters

Print data sets on IBM mainframe operating systems may have either of two variants of printer control characters:
* ASA control characters, see ASA carriage control characters.
* IBM Machine control characters. Described in this article.
The attribute for specifying the presence of print control characters is part of the Record Format (aka RECFM) attribute must therefore allow for two variants:
* RECFM=..A specifies that the data set contains ASA control characters.
* RECFM=..M specifies that the data set contains IBM machine control characters.

### ASA Control Characters

ASA control characters are logical printer commands. They tell the printer how far to advance the paper before printing the current line of text. ASA control characters are all displayable characters. Printers do not understand these characters themselves, therefore the printer driver must translate them to the corresponding printer commands when sending the print data to the printer.

### IBM Machine Control Characters

Machine control characters, in contrast, are the hardware commands which IBM line printers understand. This is why they are hardware dependent or hardware determined. IBM defined this set of commands for their line printers and made sure all their line printers understand them. Other (mainframe) line printer manufacturers also had to make sure their printers understood those commands. Since machine control characters are hardware commands, many of them are not displayable characters and therefore machine control characters are always specified as hexadecimal values.

### Main difference between ASA and Machine Control Characters

The main difference between the two sets of printer control characters might be the portability of ASA control characters versus the hardware dependency of machine control characters. The fact that the ASA controls were space before write, while the machine controls were space after write could require some data streams to be converted.

## Language support for printer control

Many programming languages simply place the desired control character in the first byte of the line to be printed. COBOL and PL/I also have a system-independent method of specifying printer controls. The compiler or run-time will translate these options into the appropriate control character.

### COBOL

COBOL uses the syntax WRITE record-name AFTER ADVANCING n Lines., where record-name is the name of the area containing the line and n is the number of lines. Additionally BEFORE ADVANCING can be used or BEFORE|AFTER ADVANCING TOP to skip to the top of a new page.

### PL/I

PL/I uses the syntax PUT SKIP(n) ... to skip n lines before printing, or PUT PAGE ... to skip to a new page.

## List of IBM Machine Print Control Characters

IBM defined two sets of printer commands, and therefore two sets of printer control characters are available. The first set of commands did not send any data to be printed to the printer but only a paper movement instruction. These are called immediate commands. The second set of commands send data to be printed on the current line plus a paper movement instruction to the printer. Note that in contrast to the ASA control characters, the IBM machine print control characters ask the printer to firstly print the data on the current line, and then secondly advance the paper.

### Immediate commands

These commands do not send any data to the printer. The commands only ask the printer to advance the paper.
| Control Code | Action |
| x'03' | No operation. |
| x'0B' | Space 1 line immediate |
| x'13' | Space 2 line immediate |
| x'1B' | Space 3 line immediate |
| x'8B' | Skip to channel 1 immediate |
| x'93' | Skip to channel 2 immediate |
| x'9B' | Skip to channel 3 immediate |
| x'A3' | Skip to channel 4 immediate |
| x'AB' | Skip to channel 5 immediate |
| x'B3' | Skip to channel 6 immediate |
| x'BB' | Skip to channel 7 immediate |
| x'C3' | Skip to channel 8 immediate |
| x'CB' | Skip to channel 9 immediate |
| x'D3' | Skip to channel 10 immediate |
| x'DB' | Skip to channel 11 immediate |
| x'E3' | Skip to channel 12 immediate |

### Write and Space Commands

Write and space commands ask the printer to write the data on the line and afterwards move the paper.
| Control code | Action |
| x'01' | Write without spacing |
| x'09' | Write and space 1 line |
| x'11' | Write and space 2 lines |
| x'19' | Write and space 3 lines |
| x'89' | Write and skip to channel 1 |
| x'91' | Write and skip to channel 2 |
| x'99' | Write and skip to channel 3 |
| x'A1' | Write and skip to channel 4 |
| x'A9' | Write and skip to channel 5 |
| x'B1' | Write and skip to channel 6 |
| x'B9' | Write and skip to channel 7 |
| x'C1' | Write and skip to channel 8 |
| x'C9' | Write and skip to channel 9 |
| x'D1' | Write and skip to channel 10 |
| x'D9' | Write and skip to channel 11 |
| x'E1' | Write and skip to channel 12 |