In the series about the assemblers Commodore used for developing the ROMs of their 8-bit computers, this article covers the 1984 “Boston Systems Office” (BSO) cross-assembler running on VAX/VMS.
6502 relocating cross assembler version 20.53.12
Copyright, The Boston Systems Office, Inc. 1978
(617) 894-7800 TWX: 710-324-0760
Type /H for help
Series Overview
- Part 0: Overview
- Part 1: MOS Cross-Assembler
- Part 2: MOS Resident Assembler
- Part 3: BSO CY6502 ← this article
- Part 4: HCD65
- Part 5: 6502ASM
History
Commodore bought the chip-maker MOS in 1976 and with it its development tools: They used the so-called MOS “Resident Assembler” (part 2 of the series) – first on the MDT650 and later on the PET – to develop for machines like the VIC-20 and the C64, and for disk drives like the 8250 and the 1541.
In 1984, they switched to a cross-assembler by the company “Boston Systems Office” (BSO).
Boston Systems Office
Boston Systems Office had been specializing on cross-development tools since 1975, offering dozens of cross-assemblers for Tymshare systems that were hand-written in PDP-10 assembly for maximum speed, and that aimed at full compatibility with the CPU-makers’ own tools.
Since 1976, they had been offering a 6502 assembler. The 1979 version of the BSO 6502 cross-assembler, called “CA6500” (documentation, PDP-10 binary) was highly compatible with the original MOS assemblers, and had added a few features.
According to internal documentation, Atari had used CA6500 on a PDP-11 for their in-house 6502 development as early as mid-1980.
In early 1984, BSO released a version for PDP-11 and VAX/VMS named CY65XX1, which was then licensed by Commodore. This version had many additional features added.
No binary of the assembler seems to be archived anywhere, but we do have the manual of the last version Commodore used:
Usage
When run, the BSO assembler shows the following prompt:
6502 relocating cross assembler version 20.53.12
Copyright, The Boston Systems Office, Inc. 1978
(617) 894-7800 TWX: 710-324-0760
Type /H for help
C65>
The output file (ABS) file, the LST file and the SRC file would be specified like this:
C65>PROG.ABS,PROG.LST=PROG.SRC
The file name extensions are optional. If they are omitted, the defaults are used.
The output file is in BSOs’ own “ABS” format, and needs another conversion step using the tool OBJCNV:
Object file converter Version 3.25
Copyright, The Boston Systems Office, Inc. 1978
TEL: (617) 894-7800 TWX: 710-324-0760
Type /H for help
>
To convert the resulting ABS file into the MOS “OBJ” format, you would type this at the prompt:
>PROG.OBJ/F:MTK=PROG.ABS/F:BSO
MTK
stands for MOSTEK, a chipmaker unrelated to MOS Technology, Inc. BSO seems to have had confused the two companies: ABS files also contain the string 6502,MOSTEK
.
In practice, one would use a DCL script to invoke both tools with the right arguments.
Differences to Original MOS Spec
The BSO assembler diverged in two aspects from the original MOS syntax:
- Labels have to start at column 1, so lines with labels cannot have any leading whitespace. But it is still legal for statements to also start on column 1: The assembler can tell them apart, since all mnemos are reserved keywords, which can’t be used as labels.
- The
.OPT
directive is not supported. Several of the options are supported through dedicated directives though. See below.
Differences to Updated Resident Assembler
The syntax of both the Resident Assembler and the BSO cross-assembler are based on the original MOS syntax, but some features that are supported by later versions of both have diverged.
Include Syntax
The Resident Assembler uses the .LIB
directive to include source files. The BSO assembler uses the .INCLUDE
directive:
.include disclaimer
Macro Syntax
Macros for the BSO assembler look like this:
dpinc .macro arg ;double precision increment
inc arg
bne 1$
inc arg+1
1$ .endm
The name of the macro is defined as a label. Arguments can be any string of characters after the .MACRO
directive, and are blindly searched and replaced in the macro’s body. .ENDM
marks the end of the body.
Conditional Assembly Syntax
Conditional assembly on the BSO assembler uses an .IF
/.ELSE
/.ENDIF
construct, like this:
.ifn gdebug
jsr grbpri ;garbage debug
.endif
New Features
There are a number of additional features supported by the BSO assembler compared to the original MOS assemblers.
Text Format
Source files can now use the complete ASCII character set, as opposed to just uppercase. This means that comments can use mixed case and that TABs can be used for indenting.
In addition, labels, statements and operands are now case insensitive. In practice, all Commodore BSO source code uses lower case for those.
Local Labels
Local labels are in the form of a number from 1 to 255 followed by a $
sign, e.g.:
100$ ; this is legal
001$ ; this is the same as the next
1$ ; this is the same as the previous
999$ ; this is illegal (1-255).
The range of local labels is delimited by global labels as well as the .LOCAL
directive.
Additional Directives
The BSO assembler supports a number of additional directives:
.NAME
/.TITLE
: set name of project.SUBTTL
: set name of section (like.PAGE
on MOS).SKIP
/.SPACE
: skip lines in LST.FORMLN
: set number of lines per page.LIST
/.NLIST
: enable/disable LST (like.OPT LIST
).CLIST
/.NCLIST
: show/hide disabled conditional assembly in LST.MLIST
/.NMLIST
/.BLIST
: control macro expansions in LST.GEN
/.NOGEN
: enable/disable extra lines in LST (like.OPT GENERATE
).INCLUDE
: include file.MACRO
/.ENDM
: macro definition (existed on MOS, but different syntax).REPT
/.ENDR
: repeat.IRP
/.IRPC
: extended repeat.IFE
conditional assembly if == 0 (existed on MOS, but different syntax).IFN
/.IF
conditional assembly if != 0 (existed on MOS, but different syntax).IFGE
conditional assembly if is >= 0.IFGT
conditional assembly if is > 0.IFLT
conditional assembly if is < 0.IFLE
conditional assembly if is =< 0.IFB
/.IFNB
conditional assembly if (not) blank.IFIDN
/.IFNIDN
conditional assembly if strings are (not) identical.IFDEF
/.IFNDEF
conditional assembly if symbol is (not) defined.LOCAL
: delimit the range of local labels.MESSG
: print message during pass 2.RMB
: reserve memory byte.RADIX
: change default radix for literals without a prefix
All these features are also documented in the “Commodore 128 Developer’s Package”, which cloned the BSO assembler for the C128. (More details in part 4 of the series.)
Relocating
It was possible to create relocatable object files with the BSO assembler. Commodore never made use of this feature. The following directives control this:
.AORG
/.RORG
/.ZORG
.SECT
/.ASECT
/.RSECT
/.ZSECT
.EXTERN
/.INTERN
.LINK
LST Files
Listing files had an updated format. Here is an example:
1581 DOS v10 318045-01 (c)1987 CBM CR6502/11 version 20.53.12 19-Mar-87 20:17:11 Page 26
"copy" COPY.SRC
Error Addr Code Seq Source statement
1755 ; copy file(s) to one file
1756
87A2 20 82B9 1757 copy jsr lookup ; look ip all files
87A5 AD 022F 1758 lda f2cnt
The header distinguishes between the project name (.NAME
, first field of first line), the section name (.SUBTTL
, first field of second line) and the filename (second field of second line), and contains the assembler’s name and the current date.
The body lines have a new first column that can contain one or more characters that indicate errors in the line, e.g. U
for undefined symbol. This is instead of added lines with error messages.
Use at Commodore
From the headers of the Commodore LST that have been preserved, we can see that Commodore was using at least the following versions:
- version 10.36.6 since at least July 1984 (TED KERNAL and Char ROM)
- version 20.51.10 since at least August 1984 (TED BASIC, 1570, original C128 ROM)
- version 20.53.12 since at least December 1985 until July 1990 (later C128 ROM, 1551, later 1541/1541C/1541-II, 1571, 1571CR, 1581, C64GS)
CY6502 was available for VAX/VMS and PDP-11 systems. Everything points towards Commodore using VAX hardware. The original C128 source archive contains a VAX reference dated October 1984 (file monitor.sum
). A different file (c65.doc
) in the C128 source archive mentions that the C128 ROM was developed on a VAX-8600 (12.5 MHz, 4+ MB RAM; released in October 1984).
According to a usenet post to net.micro.cbm from December 1985, Commodore had multiple VAX systems at least as early as December 1985:
[…] which consists of the cbmvax 11/750 and a host of VMS Vaxen, Sun’s and developmental systems at both Commodore and Commodore [Amiga].
(cbmvax
was the UUCP-connected machine at Commodore. Usenet identifiers and (later) email addresses of Commodore employees contained this machine name.)
Another document (howto.doc
) in the source archive describes how the result was transferred from the VAX to the Commodore computer: VAX computers were multi-user, and each developer had their own VT100-like terminal connected through RS-232. Each terminal had a second AUX/printer RS-232 connection that was connected to the Commodore computer (at 9600 baud if it had an ACIA chip). The tool “DOWNLOAD” on the VAX then sent the contents of the OBJ file through the terminal to the Commodore computer, which used a tool named “RSX” to receive the data.
The next article will discuss the HDC65 assembler on C128 that Commodore built in 1986 as a clone of the BSO assembler.
-
The BSO 6502 cross-assembler seems to have many names. The 1976 documentation called it CA6500: Back then, the 6502 was part of the 6500-series that consisted of the 6501 and the 6502. The version Commodore used 8 years later was called CY6502 in the documentation, but in LST files, it called itself CR6502/11: The “11” must have stood for either PDP-11 or VAX-11, or both. The “R” could stand for “relocatable”, which seemed to have been a recent feature.↩
Several of the features are quite similar to Digtital’s MACRO-11 assembler (and no doubt their MACRO assembler for VAX has them too). In particular the single-letter listing prefix for an error and `IRP`.
BTW Mostek had it’s own format for ROM files. I think I somewhere have an old manual for it. Maybe it’s the same format.