Repository navigation
LINC and LAP6 tutorial
So you want to play with a LINC computer? Good for you! It combines the charm of a lights-and-switches minicomputer with the immediate accessibility of a home computer. It comes standard with many useful and fun peripherals, and has a wide bank of I/O capabilities like a microcontroller.
Prerequisites:
- What is the LINC? https://gunkies.org/wiki/LINC
- What is LAP6? It's the LINC Assembly Program version 6, which is a set of software tools all rolled into one: operating system, text editor, assembler, file system, tape utilities, and document printing. It was written by Mary Allen Wilkes.
- Emulator based on SIMH: https://github.com/open-simh/simh
Or https://github.com/larsbrinkhoff/open-simh for new development.
As of now, there is a pull request with many improvements: https://github.com/open-simh/simh/pull/583
And a branch with experimental updates: https://github.com/larsbrinkhoff/open-simh/tree/lars/linc-addon - Documentation: http://bitsavers.org/pdf/washingtonUniversity/linc
- Tape images: https://github.com/larsbrinkhoff/lap6-forensics/tree/master/tapes
Wilkes writing LAP on a LINC at her parent's home.

The LINC has a CRT display, a keyboard, a speaker, two tape drives, and an operator panel with lights, switches, and buttons. The memory was originally 1K 12-bit words; hence a quarter is 256 words which is also the size of a tape block. Later the memory was expanded to 2K, but a quarter is still the same size and program code can only execute in the lower 1K.
To start LAP6, mount a tape on drive 0 with LAP6 conventionally starting from block 300. You do this by typing to SIMH ATTACH TAPE0 ..., and then BOOT TAPE0. This is a shortcut for toggling RCG (0701) into the left switches, 7300 into the right switches, and pushing the button DO. On the emulator this can also be done with the commands SET LSW 0701, SET RSW 7300, and DO.
Once LAP6 has started, a line editor is entered. Most keys add text to the current line. Del (also mapped from Backspace) deletes the entire line. The _ underscore cursor indicates the current line. There are no lines visible under the current line, even though they are there in memory. You should be able to write something like this.

To restart LAP6 and erase all text, press F2 which is a shortcut for pushing the button START 20. Note, you can only do this in the text editor ("manuscript display"), because in other circumstances something else will be loaded at address 20.
Enter is called EOL, and is used to end lines and terminate command. To type any "upper case" character, first type CASE which is mapped to Shift.
This is the original LINC keyboard.

The emulators maps the LINC keys onto corresponding keys on a standard PC keyboard like this. Note that symbols that are unshifted on a PC keyboard may need CASE to type on the emulator.

LAP6 can store documents on a tape, called a file. Documents in the file are called entries. An entry can have a name up to eight characters. An entry can have both a manuscript (text) and a binary (program code). Two fixed blocks 426-427 on the tape holds the directory of all entries, called the file index. This is the file index on a tape with the LAP6 manuscripts. There are only M type entries, because there are no binaries on this tape.

To issue a LAP6 command, first type CASE EOL, which is META. For convenience you can also type Alt on the emulator. LAP6 will display a right arrow 🡒 at the bottom of the display to indicate it's ready to accept a command.
To move to a line, type META and then the line number, terminated by EOL. To move up and down by pages, type CASE Q and CASE 0, or PageUp and PageDown for convenience. To move by lines, type CASE W and CASE 1, or Up and Down.
Important META commands:
- DX (unit) - display file index.
- AM file,unit - add (append) manuscript to the editor.
- SM file,unit - save manuscript to a file (tape).
- CV - convert (assemble) the manuscript currently in editor.
- LO (file,unit) - load and run the latest converted program, or the specified entry.
- SB file,unit - take the latest converted program and save binary into the specified entry.
Any META command that accesses a tape will take a long time. A real LINC machine would provide feedback from spinning tape drives, but the emulator doesn't have those. But it does have the speaker, which can play data from the S address register if you type to SIMH SET MUS ENABLED S10. LAP6 will buzz when accessing the tape, and trill when it passes over tape blocks. If you type SET MUS SCOPE a window pops up and displays the audio signal.
To play music, type to SIMH SET MUS ENABLED Z0 to have the emulator play sound from the Z register. A specially prepared tape (music.linc) should be mounted and started from drive 1. A music data tape (music0.linc) should be mounted on drive 0. LAP6 will start normally. The file has manuscripts with music notation. To play an entry, F2 clear the current manuscript if necessary, META AM load a manuscript, and type META FM. The META F command runs code from block 317, receiving the next character after F. On the music tape, it holds a program to handle music. META FM is for converting the current manuscript and then playing the result. META FP will play the latest converted music. Type any key to exit back to LAP6.
- A program LO-aded from LAP6 will be started from location 1. It should probably jump from there to address 20, which is the normal starting address for most programs.
- A program must exit back to LAP6 with an RCG 7|300 instruction at location 15-16.
- Other than that, locations 1-17 normally don't have any code since they are frequently used as indirect address registers. Location 0 is used to return from subroutines.
- If a program exits by a key stroke detected with KST, it's prudent to consume it with KBD before jumping to 15.
Here is a simple "hello line" program. Make sure to make the "i" in there lower case, not upper case! See the emulator keyboard above to find the lower case i.
⊟1
JMP 20 [START HERE
0 [CLEAR LOCATION 2 - X COORDINATE
⊟15
RCG [EXIT HERE
7|300 [TO LAP6
⊟20
CLR [CLEAR ACCUMULATOR - Y COORDINATE
#1A DIS i 2 [PLOT A POINT ON SCOPE 0 AND ADVANCE X
KST [CHECK WHETHER KEY STRUCK
JMP 1A [NO? LOOP
KBD [YES? CONSUME
JMP 15 [EXIT
You may want to save your masterpiece with META SM HELLO,0. To assemble this, type META CV. This will first load the assembler from tape, so be patient. When done, it will display errors if any (none if you typed it right), memory allocations, and a symbol table. Press EOL to advance and get back to the manuscript. To run it, type META LO. It should display a horizontal line across the middle of the CRT. Type any key to exit.
It's easy to make a tiny mistake, leaving you with a blank screen and no indication what's going on. The front panel lights would have been good to have in this situation. Fortunately there is an equivalent in the SIMH command line. You can type Control+E (the standard SIMH break key) to stop the simulation and examine the machine state. Type EXAMINE P to check whether P is pointing to a reasonable instruction address. Type EXAMINE -M 0-25 to see if the instructions there match what you typed.
The LINC programming model looks something like this.

Light green boxes mean "new" features added in the final 1965 design. Light blue means internal registers.
A is the accumulator through which all arithmetic and logic operations are done. L is the link bit, which is essentially the carry out of A. Z is an auxiliary register which holds the low result of a multiplication, character data for display, and bits shifted left out of A. OVF indicates addition overflow. IEN is interrupt enable.
P is also called the Instruction Location (IL) and is the code address currently executing. C is the control register which holds the current instruction.
S is the memory address register, and B is the memory buffer. Any time the computer is accessing memory, the address and data go through these two registers. S is 12 bits wide, but only 11 are used for addressing.
R holds the current state of six digital relay outputs. One of the relays can be attached to a Teletype and used for printing.
There are three banks of switches: 12 left switches, 12 right switches, and 6 sense switches. The left and right switches can be read into A. The sense switches can be used in skip instructions.
Some instructions have a four-bit field which can be used to address the first sixteen locations in memory for various purposes. The P register is only 10 bits wide, so only the low 1K can be used for code. The address space is divided into eight quarters; for tape data transfers, a quarter is specified as the target or source.
Arithmetic is done in one's complement.
Instruction formats are:
| 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| opcode | |||||||||||
| opcode | i | n | |||||||||
| opcode | i | α | |||||||||
| opcode | i | β | |||||||||
| opcode | u | i | u | opcode | |||||||
| opcode | x | ||||||||||
Where "n" means a four-bit small immediate number, "i" is a flag that is used in various different ways, "α" is a four-bit address into the low locations at 0-17, "β" is a four-bit address except 0 is treated specially, "u" is a tape drive unit, and "x" is a 10-bit address.
In the three shift instructions ROL, ROR, and SRC, i means to include the link. In OPR and KBD, i means to wait until the operation is done; without i, proceed immediately to next instruction. In SAM, i means to proceed immediately to next instruction; without i, wait until the operation is done. In SET, i means to treat the next location as the immediate value; without i next location holds the address of the value. In DIS and XSK, i means to increment location α.
| Instruction | Description |
|---|---|
| HLT | Halt the computer and chime a gong. |
| CLR | Clear accumulator, link, and Z. |
| ATR | Copy accumulator to R. |
| RTA | Copy R to accumulator. |
| NOP | No operation. |
| COM | Complement accumulator. |
| LSW | Copy left switches to accumulator. |
| RSW | Copy right switches to accumulator. |
| ROL i n | Rotate accumulator left n bits. |
| ROR i n | Rotate accumulator right left n bits. Bits shifted out are also shifted into Z. |
| SCR i n | Arithmetic right shift left n bits. Bits shifted out are also shifted into Z. |
| OPR i n | Perform digital I/O against port n. |
| KBD i | Read keyboard key code into accumulator. |
| ADD x | Add location x to accumulator. |
| STC x | Store accumulator in location x, then clear accumulator. |
| JMP x | Jump to location x. |
| SET α | Copy word addressed by next location to location α. |
| SET i α | Copy next location to location α. |
| SAM i n | Sample A/D port n. |
| DIS i α | Display a point at coordinates specified by location α and the accumulator. |
| XSK i α | Skip next instruction if location α is 1777. |
Skipping means to skip the next instruction if some condition is met. In all skip instructions, i means to invert the skip condition.
| Instruction | Description |
|---|---|
| SXL i n | Skip if external input level is -3V. |
| KST i | Skip if keyboard key has been struck. |
| SNS i n | Skip if sense switch n is up. |
| LZE i | Skip if link is zero. |
| IBZ i | Skip if the tape head is in an interblock zone. |
| OVF i | Skip if the overflow flag is zet. |
| ZZZ i | Skip Z bit 0 is zero. |
| LZE i | Skip if link is zero. |
The tape unit is selected with u, which can be 0, 1, 4, or 5. The i bit means to keep the tape spinning when the instruction is done.
| Instruction | Description |
|---|---|
| RDC i u | Read tape block and check. |
| RCG i u | Read tape group and check. |
| RDE i u | Read tape block. |
| MTB i u | Move towards tape block. |
| WRC i u | Write tape block and check. |
| WCG i u | Write tape group and check. |
| WRI i u | Write tape block. |
| CHK i u | Check tape block. |
The indexing group of instruction all locate the operand in the same way. The address can access the full 11-bit range of the 2K memory. Three addressing mode use indirect addressing. One mode can pre-increment the address.
The MUL instruction uses address bit 11 to select between multiplying as integers or as fractions. The half word instructions use bit 11 to select the upper or lower half of a word. The display character instruction uses bit 11 to select the display channel.
| i | β | Effect |
|---|---|---|
| 0 | 0 | The next location has the address of the operand. |
| 1 | 0 | The next location is the operand. |
| 0 | ≠0 | Location β has the address of the operand. |
| 1 | ≠0 | First increment location β, then use it as the address of the operand. |
| Instruction | Description |
|---|---|
| LDA i β | Load accumulator from memory. |
| STA i β | Store accumulator in memory. |
| ADA i β | Add memory to accumulator. |
| ADM i β | Add memory to accumulator and store back in both. |
| LAM i β | Link add to memory. |
| MUL i β | Multiply giving a 22-bit result in A and Z. |
| LDH i β | Load half word from memory. |
| STH i β | Store half word in memory. |
| SHD i β | Skip if half word is different from accumulator. |
| SAE i β | Skip if accumulator is equal to memory. |
| SRO i β | Skip if memory bit 0 is 0, then rotate. |
| BCL i β | Bit clear, and accumulator with the complement of memory. |
| BSE i β | Bit set, or accumulator with memory. |
| BCO i β | Bit complement, xor accumulator with memory. |
| DSC i β | Display character. |