Est. 1967 Advanced

Macro-10

DEC's macro assembler for the 36-bit PDP-10, the language in which the TOPS-10 and TOPS-20 operating systems were written and in which Gates and Allen assembled the first Altair BASIC.

Created by Digital Equipment Corporation

Paradigm Assembly, Imperative, Low-level
Typing None (untyped); every value is a 36-bit word or a halfword, byte or bit field within one
First Appeared 1967
Latest Version MACRO %53B(1247); its last revision-history edit is dated 10 February 1988, and it shipped in DEC's 1988 TOPS-20 V7 distribution

MACRO-10 is the symbolic macro assembler for Digital Equipment Corporation’s 36-bit PDP-10 family, the machines DEC later sold as the DECsystem-10 and DECSYSTEM-20. For two decades it was the main systems programming language of the PDP-10 world. DEC wrote its TOPS-10 and TOPS-20 operating systems, and most of the programs that came with them, in MACRO. Many universities and research labs that bought PDP-10s for time-sharing used it to write their own tools. Its macro facility went well beyond simple text substitution: you could build large table-driven systems out of it. It was flexible enough to produce code for a completely different processor: the 8080 code of Altair BASIC was assembled with it in 1975.

DEC’s own manuals mostly call the program just MACRO. “MACRO-10” is the name used in the 1967 user’s guide and on the 1978 manual’s title page. The same program, assembled for TOPS-20, is sometimes informally called MACRO-20.

History & Origins

From MACRO-6 to MACRO-10

The PDP-10 was a compatible successor to DEC’s PDP-6 of 1964, and its assembler grew out of the PDP-6’s. DEC’s MACRO-6 Assembly Program manual (F-64MAS) is dated May 1964. It already describes most of what later defined MACRO-10:

  • relocatable output with RELOC, and subroutine linking through EXTERN and INTERN
  • macro definition with DEFINE, created symbols, concatenation and the “indefinite repeat” IRP
  • user-defined operators with OPDEF
  • literals, with LIT to place the literal pool
  • halfword data with XWD

The PDP-10 kept the PDP-6 instruction set, so the assembler moved across largely intact. DEC’s 1967 PDP-10 software even included a utility, CONVRT, to convert DECtapes between “the old PDP-6 format” and the new PDP-10 format.

First appearance

The encyclopedia master list dates Macro-10 to 1970, but DEC’s documentation puts it earlier. The April 1978 MACRO Assembler Reference Manual (AA-C780C-TB) gives the manual’s printing history as April 1967 (first printing), followed by revisions in August 1967, June 1969, October 1969, August 1970, April 1972, November 1974, July 1977 and April 1978. DEC’s PDP-10 Systems User’s Guide (DEC-10-NGCA-D, copyright 1967) lists the “Macro-10 Assembler (MACRO)” as one of the two “conversational language translators”, the other being the FORTRAN IV compiler F40. This page therefore uses 1967. The first PDP-10 systems shipped around the same time, in roughly 1967 to 1968; sources disagree on the exact delivery date.

The 1967 guide describes the assembler in a feature summary:

  • a “sophisticated 2-pass assembly”
  • device independence
  • “complete macro instruction facilities”
  • symbolic linkage to separately assembled programs
  • unlimited indexed and indirect addressing
  • relocatable or absolute output

It needed 5K words of core and asked the time-sharing monitor for more memory as it needed it.

Design Philosophy

MACRO was designed around the PDP-10’s unusual and generous architecture:

  • 36-bit words, 18-bit addresses. A program’s address space is 2^18 = 256K words. Each word splits naturally into two 18-bit halfwords, and much of the instruction set (and much of MACRO’s syntax) is built around halfwords.
  • Relocation and linking by default. MACRO normally produces relocatable .REL files for the linking loader (later the LINK program), not absolute images. Addresses within a program are relative to 0, or 400000 octal for the high segment. Separately assembled modules refer to each other through global symbols.
  • The assembler as a programmable tool. Conditional assembly, macros, repeat blocks and UNIVERSAL symbol files let a single source tree produce many different configurations. The TOPS-10 monitor relies on exactly this: one set of sources is assembled with feature-test switches to build a monitor for a particular site.

The 1978 manual describes MACRO as “a statement-oriented language” whose statements “are in free format”. It says MACRO “allows you to create your own language elements, called macros. In this way you can tailor the assembler’s functions for each program.”

Key Features

Two-pass assembly

MACRO reads the source twice. Pass 1 builds the symbol tables and roughly assembles each statement. Pass 2 writes the binary file and the listing and flags errors with single-character codes. If a label has a different value on the second pass, MACRO reports a phase error. The pseudo-ops IF1 and IF2 let code behave differently on each pass.

Pseudo-ops

The 1967-68 user’s guide already lists a rich set of pseudo-operations:

Pseudo-opPurpose
ASCII, ASCIZ, SIXBIT7-bit text, 7-bit text with a guaranteed trailing null, and DEC’s 6-bit character code
BYTE, POINTPack bytes of 1 to 36 bits, and build byte pointers for the PDP-10’s byte instructions
XWD, EXP, DEC, OCT, RADIXHalfword pairs, expressions and numeric radix control
DEFINE, IRP, REPEATMacro definition, iteration over macro arguments, and repeated blocks
IFE, IFN, IFDEF, IFIDN, IFB, …Conditional assembly on values, definitions, identical/different strings and blank arguments
OPDEF, SYNDefine new operators, and make one symbol a synonym for another
RELOC, LOC, PHASE/DEPHASERelocatable and absolute location control, and code assembled to run at a different address
EXTERN, INTERN, ENTRYGlobal symbols and library entry points
LIT, VARPlace the literal pool and variable storage
RADIX50DEC’s packed symbol format, used in symbol tables

By 1978 the language had added PSECT program sections, UNIVERSAL files that other assemblies could load with SEARCH, .DIRECTIVE controls, and “Polish” (complex) expressions passed to the linker so that it could evaluate relocatable arithmetic at load time.

Literals

You write a literal by putting a value or even a whole instruction in square brackets. The assembler stores it in a literal pool and substitutes its address. A sample program dated January 1968 in DEC’s user’s guide uses this to pass a SIXBIT argument to a monitor call:

1
        CALL    ACX,[SIXBIT/TIMER/]   ;GET TIME IN CLOCK TICKS.

Macros

A macro is defined with DEFINE and its body is enclosed in angle brackets. IRP repeats a block once for each element of a list argument. For example, here is a macro that pushes any number of accumulators onto the stack:

1
2
3
4
5
6
P=17                            ;stack pointer accumulator

        DEFINE  SAVE (ACS) <
        IRP     ACS, <PUSH P,ACS>>

        SAVE    <1,2,3>         ;expands to PUSH P,1 / PUSH P,2 / PUSH P,3

A complete program

The example below writes a greeting under TOPS-10. SEARCH UUOSYM loads DEC’s universal file of monitor-call symbols, so that OUTSTR (type a string) and MONRT. (return to monitor) can be used by name.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
        TITLE   HELLO
        SEARCH  UUOSYM          ;monitor call symbols

MSG:    ASCIZ   /Hello, World!
/                               ;text, CR-LF, null terminator

START:  RESET                   ;initialise the job
        OUTSTR  MSG             ;type the string on the terminal
        MONRT.                  ;return to the monitor
        JRST    START           ;if the user types CONTINUE
        END     START           ;end of assembly; START is the entry point

The listing shows each word in octal next to the source, with a ' mark on relocatable values, and ends with a symbol table. On TOPS-10 you would assemble, load and run the program with the monitor’s COMPILE, LOAD and RUN commands.

Evolution

MACRO was revised continually for more than twenty years. Each version carries DEC’s standard version(edit) number. Some milestones that can be pinned down:

  • 1967: first printing of the MACRO-10 manual (April); the assembler ships as part of standard PDP-10 software.
  • 1975: the September 1975 Altair BASIC listings, produced on Harvard’s PDP-10, name MACRO version 47(113).
  • Version 52 to Version 53: documented in DEC’s change notes, which say version 53 “fully supersedes all previous versions, and includes edits up to #1020”. The April 1978 manual covers Version 53 under TOPS-10 6.03.
  • Version 53A (August 1979): a reliability release for both TOPS-10 and TOPS-20, including edits up to #1152.
  • Version 53B: begun in September 1980. It added code to recognise the KS10 processor (the low-cost DECSYSTEM-2020), and later edits refer to the TOPS-10 7.03 monitor. The source in DEC’s 1988 TOPS-20 V7 distribution is titled MACRO %53B(1247), and its final edit, 1247, is dated 10 February 1988.

As DEC added new processors (KA10, KI10, KL10, KS10), the assembler learned each one’s opcodes and could record in the .REL file which processor a program was written for.

Current Relevance

MACRO-10 is a historical language. DEC cancelled the next-generation PDP-10 (the “Jupiter” project) in 1983 and moved its customers towards the VAX. TOPS-10 7.04 (July 1988) and the TOPS-20 V7 era were the last major releases. MACRO itself saw its last DEC edit in early 1988.

The language is far from lost, though:

  • Sources survive. The Trailing Edge PDP-10 archive holds DEC distribution tapes containing MACRO’s own source and change notes, along with the MACRO sources for the TOPS-10 and TOPS-20 monitors.
  • Manuals survive. Bitsavers hosts DEC’s MACRO-6 (1964) and MACRO-10 (1978) manuals and the 1967 PDP-10 Systems User’s Guide.
  • It still runs. Hobbyists run TOPS-10 and TOPS-20 on PDP-10 emulators such as SIMH and KLH10, and MACRO assembles code there just as it did on real hardware.

There is no Docker image for MACRO-10. Running it means running a PDP-10 operating system under emulation.

Two textbooks taught the language beyond DEC’s manuals: Michael Singer’s Introduction to DECsystem-10 Assembler Language Programming (Wiley, 1978) and Ralph E. Gorin’s Introduction to DECSYSTEM-20 Assembly Language Programming (Digital Press, 1981).

Why It Matters

MACRO-10 matters because of what was written in it. The PDP-10 was one of the most widely used time-sharing machines in 1970s university computing and on the early ARPANET. Its DEC operating systems, utilities and much locally written software were MACRO programs. The language’s powerful macro and conditional-assembly features made it unusually capable for building large systems in assembly language. They also made it flexible enough that Bill Gates, Paul Allen and Monte Davidoff could use a 36-bit mainframe assembler to produce code for an 8-bit microprocessor, testing it under Allen’s 8080 emulator on Harvard’s PDP-10. That program, Altair BASIC, became Microsoft’s first product.

Timeline

1964
DEC publishes the MACRO-6 Assembly Program manual (F-64MAS, May 1964) for the PDP-6. Its DEFINE, IRP, OPDEF, LIT, XWD, EXTERN/INTERN, REPEAT and RELOC pseudo-ops are the core that MACRO-10 later carries over
1967
First printing of the MACRO-10 assembler reference manual in April 1967, with a revision following in August 1967; DEC's 1967 PDP-10 Systems User's Guide (DEC-10-NGCA-D) lists the Macro-10 Assembler among the standard system programs
1968
A sample session dated 27 January 1968, bound into DEC's PDP-10 Systems User's Guide, shows a FORTRAN IV program calling a Macro-10 random-number subroutine, edited with TECO, assembled, cross-referenced with CREF and debugged under DDT on the time-sharing monitor
1975
Bill Gates and Paul Allen develop Altair BASIC on Harvard's PDP-10; surviving listings from September 1975 carry the header "MACRO 47(113)", showing the 8080 interpreter was assembled with DEC's MACRO
1978
The MACRO Assembler Reference Manual (AA-C780C-TB, April 1978) documents MACRO-10 Version 53 for TOPS-10 6.03, now with PSECTs, Polish (complex) expressions and UNIVERSAL symbol files; the manual lists nine printings since April 1967
1979
MACRO 53A (edit 1152) is released in August 1979 as a reliability release that supports both TOPS-10 and TOPS-20; programs that use PSECTs must be loaded with LINK V4 or later
1980
Work on MACRO 53B begins; the source's revision history records edit 1153 on 5 September 1980, and later edits add KS10 support to the .DIRECTIVE pseudo-op
1988
Edit 1247, dated 10 February 1988, is the last entry in the MACRO %53B source shipped with DEC's 1988 TOPS-20 V7 distribution. TOPS-10 7.04, the final major TOPS-10 release, follows in July 1988

Notable Uses & Legacy

TOPS-10

DEC's PDP-10 time-sharing monitor was written in MACRO assembly language; monitor modules such as COMMON.MAC in the TOPS-10 source distributions preserved on the Trailing Edge archive are MACRO source files built with SEARCH-ed parameter files and conditional feature switches

TOPS-20

The DECSYSTEM-20 operating system's monitor sources (for example SCHED.MAC and STG.MAC in DEC's TOPS-20 distributions and the 1991 SRI-NIC source archive) are also MACRO assembly language; DEC documented the same assembler for TOPS-20 in manual AA-4159C-TM

Altair BASIC

Gates, Allen and Monte Davidoff wrote the 1975 Altair BASIC interpreter on Harvard's PDP-10 and assembled it with DEC's MACRO assembler, which listing headers identify as MACRO 47(113)

MACRO itself

The assembler was written in its own language and was self-hosting: DEC's 53A release notes describe building it first with the previous field-image MACRO and then using the result to assemble itself

Language Influence

Influenced By

MACRO-6

Running Today

Run examples using the official Docker image:

docker pull
Last updated: