Signetics Assemblers
Signetics made available at least four assemblers for the 2650:
- 2650 cross-assembler
- Prometheus resident assembler
- 2650 TWIN assembler
- 2650 TWIN relocatable assembler
2650 Cross-assembler
The cross-assembler is a program for GE or NCSS time-sharing mainframes, written in Fortran. It is only of historical interest, but since it was documented as part of the 2650 CPU Manual its syntax provides a baseline for newer assemblers. Its features include:
- Symbols consist of at most four characters. No symbols are predefined.
- Numeric constants in binary, octal, decimal, and hexadecimal; character constants in EBDIC or ASCII.
- The constant $ refers to the current program location.
- Numeric expressions can contain addition, subtraction, or the special operator < (high byte, divide by 256) and > (low byte, module 256).
- Indirect jumps are marked by an asterisk * as the first character of the branch expression.
- Indexing is specified by register 0 in the opcode, and the index register after the address expression, separated by a comma. Auto-increment and auto-decrement are specified by a second comma, followed by + or -.
- Comments are marked by an asterisk * in the first column.
- Assembler directives ORG, EQU, ACON, DATA, RES, END, EJE, PRT, SPC, TITL and PCH.
The output of the cross-assembler consists of punched cards, each consisting of a starting address and one or more bytes to be loaded at that location. This allows for ‘gaps’ in the output and cards can be loaded in any order. The final card contains the starting address (specified in the END assembler directive).
Prometheus resident assembler
The Prometheus resident assembler is a circuit board containing an assembler in 11 PROM chips. The board has model number PC1600SC, and its intended use is together with either the PC1001 or ABC1500 prototyping boards. The DS2000 base can be used to mount these boards.
Prometheus reads the assembler source from paper tape, using the PIPBUG monitor program. As output it produces a paper tape containing the hexadecimal translation of that program. Some common symbols are predefined (R0..R3, condition codes and program status word bits).
In addition to the assembler directives of the cross assembler, Prometheus recognizes the LIBR directive. When the LIBR directive is encountered, the assembler prints a specified text string and waits for any character to be entered, after which assembly continues. During the wait period the operator can load another paper tape. Several short tapes can be used instead of a single long tape, and tapes can be reused in multiple programs.
2650 TWIN assembler
With the TWIN it is no longer necessary to submit jobs on paper tapes or on punched cards to a remote time-sharing system. Instead assembler programs can be written using the terminal, stored locally on floppy diskettes and assembled by the TWIN directly.
The language for the TWIN assembler is mostly upwards compatible to the cross-assembler, with a few improvements.
- EBDIC constants are not available (the single exception to upwards compatibility).
- Symbols can be six characters long (instead of just four).
- Expressions can contain many more operators, including multiplication and division and operators written between two periods: .MOD., .AND., .XOR., .SHR., .EQ., etc. Parentheses can be used to override the priority of operators.
- Parts of the source code can be assembled or skipped based on certain conditions, using the new directives IF, ELSE, and ENDIF.
- The new directive SET allows for symbols to be redefined.
The output of the TWIN assembler is a load module, stored as a file on disk.
Because the assembler is too large to fit into an overlay areas like the other SDOS modules it is run from slave memory by the slave processor.
The standard TWIN assembler is also called the ‘absolute assembler’ to distinguish it from the relocatable assembler.
2650 TWIN relocatable assembler
The cross-assembler had a number of restrictions. The TWIN assembler is a close copy of the cross-assembler and therefore shares many of its limitations. The relocatable assembler received a new design with many new features while still maintaining compatibility.
- Assembler output is an address-independent object file. The address of program code is decided during the linking phase.
- Modules can be used to structure source programs. Symbols can be selectively exported, and dependencies on external symbols must be declared explicitely.
- Branch instructions can be written using a new shorthand code, purportedly increasing readability of programs.
The relocatable assembler is accompanied by a new LINK program to combine object files into a load module that can be executed. The relocatable assembler can be used together with the MACRO preprocessor.
Despite these major changes the assembler language is mostly compatible with the absolute assembler:
- Symbols are still limited to just six characters.
- The extended operators of the absolute assembler can be used.
- Two new directives are available: CEJE (conditional eject) and REPRO (to include LINK commands inside a source file).
- Three directives relate to relocatability: CSECT, ENTRY and EXTRN.
Alternative branch instructions
The relocatable assembler adds shorthand notations for branch instructions, subroutine calls and subroutine return instructions. A few examples below; the full list can be found in the manual.
New | Meaning | Normal |
BHR | Branch if higher, relative (after compare) | BCTR,GT |
BEA | Branch if equal, absolute (after compare) | BCTA,EQ |
BNLR | Branch if not lower, relative (after compare) | BCFR,LT |
BPR | Branch if positive (after load or arithmetic operation) | BCTR,P |
BR | Branch, relative | BCTR,UN |
BSA | Branch to subroutine, absolute | BSTA,UN |
RET | Return from subroutine | RETC,UN |
Use of the alternative notation is a matter of preference, and you can use either or both. Notice that there are no shorthand codes for conditional subroutine calls, nor for conditional return instructions. It is therefore not entirely possible to use the new notation exclusively.
These instructions might be inspired by the ones used on IBM mainframes. See for example Extended Mnemonics for BCR instruction. Personally I find the original opcodes easier to read…
Modules and linking
The ENTRY directive lists one or more symbols which may be referenced by other modules. It is like the EXPORT statement found in several high-level programming languages. The listed symbols must have been defined in the source code.
The EXTRN directive lists one or more symbols which must be defined in other modules. It is like an IMPORT statement in other languages. The listed symbols must not be defined in this source module.
The optional CSECT directive declares the name of the module, for information purposes.
Macro preprocessor
A macro is a sequence of 2650 opcodes that can be re-used using a single instruction. In effect a macro creates a new pseudo-instruction. A macro can take arguments, and optional arguments can have default values.
The following example is given in the relocatable assembler manual. It creates a new MOVE pseudo-instruction that copies a number N
of bytes from address A
in memory to address B
.
.MACRO
&L MOVE &A,&B,&N
lodi,r1 &N
&L subi,r1 1
loda,r0 &A,r1
stra,r0 &B,r1
brnr,r1 &L
.MEND
Once defined like this, the macro preprocessor will translate the instruction
Labl MOVE fromA,toA,10
into
lodi,r1 10
Labl subi,r1 1
loda,r0 fromA,r1
stra,r0 toA,r1
brnr,r1 Labl
Documentation
2650 CPU Manual: contains documentation on the cross-assembler and syntax.
Prometheus resident assembler: manual, Signetics/Mullard Technical Information 52.
Signetics TWIN 2650 Assembler Manual, TW09005000: documentation on the TWIN assembler.
Signetics TWIN 2650 relocatable assembler, TW09007000: documentation on the TWIN relocatable assembler.
You may also be interested in my asm2650 assembler, which runs as a Python script on modern hardware.