PiDP-8/I Software

Changes To A Field Guide to PDP-8 Assemblers
Log In

Changes to "A Field Guide to PDP-8 Assemblers" between 2017-12-10 20:54:50 and 2017-12-17 19:56:50

1
2
3
4
5
6
7

8
9
10
11
12
13
14
1
2
3
4
5
6

7
8
9
10
11
12
13
14






-
+







# Introduction

There are many commonly-used PDP-8 assemblers, several of which we ship with the PiDP-8/I software distribution; there are more available elsewhere. How does a programmer discriminate among them, other than to carefully read each one's manual, then spend several months writing code in it to develop a feel for what it is like? They cannot all be equal, else they'd be interchangeable and you'd just pick one based on what was available. One cannot be clearly better for all things, else everyone would just use that.

This article is a **preliminary** survey of these assemblers with an eye toward listing the key distinctions among them. It is modeled on a birder's field guide: having read through this document, a reader should be able to recognize which assembler(s) are likely to be able to process a given piece of assembly code. Eventually, we hope that a programmer beginning a PDP-8 assembly language project should be able to make a sensible selection based on the information in this document, though that ambition likely exceeds this document's current scope.

When multiple versions of a given assembler are available, our commentary applies to the version currently in the PiDP-8/I software distribution, if present, or the latest available version of the assembler if it is hosted externally.
When multiple versions of a given assembler are available, our commentary applies to the version currently in the PiDP-8/I software distribution, if present, or the latest available version of the assembler if it is hosted externally. We tend to prefer *earlier* manuals, however, interested as we are here in history.


## Criteria

This survey does not include every PDP-8 assembler, on purpose. This is not a comprehensive survey, it is not a genealogy project, and it is not an advocacy platform. Our purpose here is to list useful options for the practicing PDP-8 assembly language programmer.

The assemblers listed meet these criteria:
69
70
71
72
73
74
75












76
77
78
79
80
81
82
83

84
85
86

87

88





















89
90
91
92
93
94

95
96
97
98
99

100
101
102

103
104
105
106


107

108
109

110
111

112
113
114
115
116
117
118
119
120
121

122
123
124



125
126

127
128
129
130

131

132
133




134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153

154
155
156
157
158
159
160
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94

95
96
97

98
99
100

101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126

127
128
129
130
131

132
133
134
135
136
137
138
139
140
141
142

143
144

145
146

147
148
149
150
151
152
153
154
155
156
157
158



159
160
161


162


163

164

165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190

191
192
193
194
195
196
197
198







+
+
+
+
+
+
+
+
+
+
+
+







-
+


-
+

+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+





-
+




-
+



+




+
+
-
+

-
+

-
+










+
-
-
-
+
+
+
-
-
+
-
-

-
+
-
+


+
+
+
+



















-
+







## <a id="macro-8"></a>MACRO-8

| **Introduced** | 1965
| **Manual** | [PDF, 1.7 MB](https://www.grc.com/pdp-8/docs/MACRO-8_Programming_Manual.pdf)
| **Delivery** | paper tape

MACRO-8 was another paper tape assembler for the PDP-8. Its main advantage over PAL-III is that it added [macros](https://en.wikipedia.org/wiki/Macro_instruction), a very useful feature in assembly language programming as it reduces a lot of the tedium of writing such programs.

MACRO-8 is based on the PAL-III language, with several new features:

*   The `DEFINE` based macro definition system
*   Other new pseudo-ops:
    *   `DUBL`: ???
    *   `FLTG`: ???
    *   `PAGE`: [re]set the location counter to the top of the given page
    *   `TEXT`: convert a literal string in the program text to 6-bit packed ASCII in the binary output

MACRO-8 dropped the `FIXMRI` pseudo-op relative to PAL-III. One manual I examined showed an example that could only be done using `FIXMRI` under PAL-III, by which I infer that MACRO-8 simply doesn't need the hint from the user: memory reference instructions can be detected as part of regular symbol table manipulations.


**INCOMPLETE**


## <a id="pal-d"></a>PAL-D

| **Introduced** | 1967
| **Manual** | ??
| **Manual** | [PAL-D Disk Assembler Programmer's Reference Manual](https://archive.org/details/bitsavers_decpdp8sofProgRef_1907666)
| **Delivery** | paper tape

PAL-D is basically PAL-III for the [PDP-8 Disk Monitor System](https://en.wikipedia.org/wiki/4K_Disk_Monitor_System), one of OS/8's predecessors.
PAL-D is a descendant of PAL-III, originally appearing as part of the [PDP-8 Disk Monitor System](https://en.wikipedia.org/wiki/4K_Disk_Monitor_System), one of OS/8's predecessors. It would later reappear under TSS/8.

PAL-D came in two forms, the 4K and 8K versions, referring to the minimum amount of core memory each required. Note that the 4K version could assemble for larger machines; it has the `FIELD` pseudo-op, for example, which is of no use unless your assembled program would run in at least 8K of core.
**INCOMPLETE**

The 4K version defines only one new feature in the PDP-8 assembler family so far: the `XLIST` pseudo-op, which lets the programmer stop and then re-start the assembly listing in the optional third pass. The 4K version is more notable for the features it brought into the PAL family from [MACRO-8](#macro-8): the`PAGE` and `TEXT` pseudo-ops.

8K PAL-D added quite a few new features over the 4K version:

*   ability to run in 8K or 12K of core, allowing assembly of larger programs
*   more pseudo-operations:
    *   `EJECT`: emit a form feed in the listing output
    *   `IFDEF` and `IFZERO`: conditional assembly tests, affected statements in angle brackets
    *   `NOPUNCH` and `ENPUNCH`: stop and restart assembled machine code output
    *   `ZBLOCK`: reserve memory, setting initial values to zero

Note that neither version of PAL-D brought over the `DEFINE`, `DUBL` or `FLTG` pseudo-ops from MACRO-8.

Notice that the negated forms of the conditional assembly operations did not appear until later. The first reference to them I've been able to find for `IFNZRO` and `IFNDEF` is in connection with [PAL8](#pal8).

We find evidence for a complicated development history in the `PUNCH` and `XLIST` pseudo-ops. They do much the same thing, only for different passes of the assembler, yet the form of the ops differ.  If this assembler was created by a single mind in a single time and place, or if it were created by a standards committee with a mandate to simplify and unify, you would expect these two sets of pseudo-ops to have similar names and forms, either `XPUNCH` taking an argument or a `NOLIST`/`ENLIST` pair. We can infer different minds behind the 4K and 8K versions of PAL-D.

The `PUNCH` op names also suggest that the operation is mainly useful for paper tape output, still an important I/O device when PAL-D was new. We can still find it documented in the [the OS/8 Handbook (1974 ed.)][os8m], but it was airbrushed out of history by the [1979 edition for OS/78][os78m], suggesting that its purpose became effectively redundant after the bulk of the market moved to disk-based PDP-8 systems.

Like MACRO-8, PAL-D does not have the `FIXMRI` pseudo-op.


## <a id="os8"></a>The OS/8 Assemblers

| **Introduced** | 1971
| **Manual** | most any OS/8 manual, such as [this 1974 edition][os8m]
| **Manual** | most any OS/8 manual, such as the [OS/8 Handbook][os8m] (1974 ed.) or its [successor for OS/78][os78m] (1979 ed.)
| **Delivery** | part of OS/8

[OS/8](https://en.wikipedia.org/wiki/OS/8) was [the primary programming system from DEC][faq10] for the PDP-8 in its later years. It included several different assemblers, all documented in its manual, one edition of which is linked above.

The introduction date is that of OS/8, but OS/8 has a [complicated development history][faq10] that stretches back to 1966 or so. I do not mean by this grouping to imply that they were all created and introduced at the same time. As historical evidence arrives, I will make finer distinctions in the dates. Until then, we have a years-wide window for each of these OS/8 assemblers' creation dates: after PAL-III (1965) and before 1974, the publication date of the linked manual.
The introduction date is that of OS/8, but OS/8 has a [complicated development history][faq10] that stretches back to 1966 or so. Some of the following assemblers predate OS/8; where the dates for them are known, they are called out. For those with no additional date information, it is possible that it was first introduced after OS/8 but before 1974, the date of the manual linked above, which talks about all of these assemblers.

[faq10]: http://www.faqs.org/faqs/dec-faq/pdp8/section-10.html
[os8m]: https://archive.org/details/bitsavers_decpdp8os8_39414792
[os78m]: https://www.grc.com/pdp-8/docs/OS8_Handbook.pdf


### <a id="pal8" name="pal-8"></a>PAL8

The earliest attestation to the PAL8 assembler I've been able to find is in the May 1970 printing of [Programming Languages][pl], the second volume in a set of two books for programming PDP-8 family computers. In the section on 8K PAL-D, it gives a Disk Monitor command for saving the in-core copy of 8K PAL-D as "PAL8". It is therefore unsurprising that the OS/8 version of PAL8 is morphologically more similar to [PAL-D](#pal-d) than to [PAL-III](#pal-iii).

PAL8 understands the same basic language as PAL-III and generally has more features, most especially related to running under OS/8, such as the ability to set options via OS/8's command interpreter (CCL) rather than via the PDP-8's front panel switches.
PAL8 understands the same basic language as PAL-D and generally has more features, most especially related to running under OS/8, such as the ability to set options via OS/8's command interpreter (CCL) rather than via the PDP-8's front panel switches.

I consider it the default assembler for OS/8 users. If none of the information below guides you to one of the other assemblers, you should probably start with PAL8. If you have a piece of assembly code that is meant to be assembled under OS/8, and you have no evidence that is for any other assembler, it's probably meant to be assembled by PAL8.
I consider PAL8 the default assembler for OS/8 users. If none of the information below guides you to one of the other assemblers, you should probably start with PAL8. If you have a piece of assembly code that is meant to be assembled under OS/8, and you have no evidence that is for any other assembler, it's probably meant to be assembled by PAL8.

PAL8 has many features not present in PAL-III:
PAL8 has many features not present in 8K PAL-D:

*   automatic link generation for off-page references
*   output options for [CREF and DDT][os8m]
*   in addition to `+` and `-` in expressions, it allows:
    *    `^` for 12-bit unsigned multiplication (`*` was already taken for setting the location counter)
    *    `%` for 12-bit unsigned division (`/` was already taken as the comment start character)
    *    `!` for Boolean OR (the ASR-33 terminal character set [did not include the &brvbar; character](http://iclces.uk/articles/a_teletype_font.html))
    *    `&` for Boolean AND
*   literals in the current page via `(NN` syntax (closing paren optional) or in page zero via `[NN`
*   single-character ASCII constants: `"A`
*   `EJECT` pseudo-op extended to allow the page header to be changed for the next and following pages
*   more pseudo-operations:
    *   `DEVICE`, `FILENAME`, and `TEXT`: insert 6-bit packed ASCII text strings in the output
    *   `DTORG`: set DECtape block number in typesetting output
*   new pseudo-operations:
    *   `DEVICE` and `FILENAME` alternatives to `TEXT` for passing arguments to OS/8 service routines
    *   `DTORG`: set DECtape block number in output for the [Typeset-8][ts8m] computerized typesetting system ([photo][ts8p])
    *   `EJECT`: emit a form feed in the listing output; optionally set a new header line
    *   `IFDEF`, `IFNDEF`, `IFZERO` and `IFNZRO` with angle brackets for conditional assembly
    *   `IFNDEF` and `IFNZRO` negated forms of the conditional assembly tests
    *   `PAGE`: [re]set the page part of the location counter
    *   `NOPUNCH` and `ENPUNCH`: stop and restart binary output
    *   `RELOC`: assemble code for relocation after loading
    *   `XLIST`: suppress part of the listing output

    *   `ZBLOCK`: reserve memory, setting initial values to zero
The existence of the `RELOC` pseudo-op should not be taken as a sign that PAL8 is a relocatable assembler. It simply allows code to be assembled starting at one fixed address which is intended to be run at a different fixed address. A proper relocatable assembler generally tries to hide the fixed addresses it uses when assembling your program; compare [SABR](#sabr), for example. You must give the generated binary code to a relocating loader to fix up the addresses to their final execution values.

PAL-III has one feature not implemented in PAL8:  the ability to get a brief listing of the undefined symbols in a program. The information is instead presented inline in the listing output, not grouped together into a single place, which can make refinement of an in-development program tedious as you need to comb information about undefined symbols out from among all the other output.

[pl]: http://bitsavers.org/pdf/dec/pdp8/handbooks/programmingLanguages_May70.pdf
[ts8m]: http://bitsavers.org/pdf/dec/pdp8/typeset8/
[ts8p]: http://gordonbell.azurewebsites.net/digital/timeline/1968-3.htm


### <a id="ralf" name="flap"></a>RALF/FLAP

RALF is the back-end assembler for OS/8's FORTRAN IV compiler. As a result of that support role, it has a few primary advantages over PAL8:

*   relocatable output code

*   easy access to the optional [floating-point processor](http://dustyoldcomputers.com/pdp12/fpp12.html)

The RALF assembler has a mode switch that causes it to generate absolute-addressed code, as PAL8 does. In this mode, it is called FLAP.

The FPP modes are the key advantage of RALF/FLAP. Vincent Slyngstad [suggests][smal8] that you think of these as assemblers for the FPP rather than for the PDP-8.

**INCOMPLETE**


### <a id="sabr"></a>SABR

As RALF is to OS/8's FORTRAN IV compiler, so [SABR](http://homepage.cs.uiowa.edu/~jones/pdp8/faqs/#langs) is to OS/8's FORTRAN II compiler.
As RALF is to OS/8's FORTRAN IV compiler, so the [Symbolic Assembler for Binary Relocatable programs](http://homepage.cs.uiowa.edu/~jones/pdp8/faqs/#langs) is to OS/8's FORTRAN II compiler.

SABR is a relative assembler, unlike PAL8 or FLAP, meaning that the OS/8 linking loader (`LOADER.SV`) adjusts all of the addresses in the assembled `*.RL` output to their final values.

SABR does not have any tie to the FPP, unlike RALF/FLAP.

The most notable feature of SABR is that the programmer normally writes SABR code as if using a flat memory model machine, ceding all control over literal placement and of page/field boundary placement to the assembler. This feature — called automatic paging — frees the programmer from having to deal with the [strange PDP-8 memory model][mm8], but it also means she is dependent upon the assembler to make smart decisions about all of this, even while SABR must itself run within those same constraints. This makes writing SABR easier than for most other PDP-8 assemblers, but because you can't get a whole lot of optimization smarts into a 6&nbsp;kWord program, the output code tends to be less efficient than hand-tuned code for other assemblers.

192
193
194
195
196
197
198
199

200
201
202
203
204
205
206
230
231
232
233
234
235
236

237
238
239
240
241
242
243
244







-
+







*   `ACH`, `ACM`, `ACL`: address sub-words in a multi-word value
*   `D` prefix on numeric constants cause decimal interpretation where `OCTAL` is otherwise in effect
*   `K` prefix for octal-in-decimal-context flip case
*   `IF`: conditionally skip assembling some number of the following instructions

Finally, there are some things which are different or missing in SABR as compared to PAL8:

*   `BLOCK`: same as `ZBLOCK` in PAL8
*   `BLOCK`: same as `ZBLOCK` in PAL8 and PAL-D
*   `IF` not as flexible as `IFDEF`, `IFNDEF`, `IFZERO` and `IFNZRO`
*    Missing pseudo-ops:
     *   `DEVICE` and `FILENAME`: not needed, call thru FORTRAN II library instead of direct to OS/8 USR
     *   `DTORG`, `EJECT`, `XLIST, `NOPUNCH` and `ENPUNCH` output controls
     *   `RELOC`: not needed, SABR output is relocatable by default

A programmer may use SABR one of three ways: