Skip to content


Switch branches/tags


Failed to load latest commit information.
Latest commit message
Commit time

A09 - 6800/6801/6809/6301/6309/68HC11 Assembler

Copyright (c) 1993,1994 L.C. Benschop
Parts Copyright (c) 2001-2020 Hermann Seib

Based on Lennart Benschop's C core that can be found somewhere on the 'net (last address known to me was, I built a complete Macro Assembler that is functionally better than the TSC Flex9 Assembler (no wonder, I got multimegabytes to play with, whereas this excellent piece of software works within 50K or so!). It can deliver binary, Intel Hex, Motorola S1, and Flex9 binary output files, plus Flex9 RELASMB-compatible relocatable object modules.

I taylored the original to my taste by working through the source code; since A09 has reached a level of complexity that doesn't really lend itself to following the "Use the Source, Luke!" principle if you just want to hack a little 6809 assembly program, I've added this documentation. Have fun!

Hermann Seib, 2020


a09 [-{b|r|s|x|f}[filename]]|[-c] [-l[filename]] [-ooption]* [-dsym=value]* sourcefile*

Command Line Parameters

suppresses code output (corresponds to ASMB's B command line option)
-bfilename (default output mode)
create a binary output file
if no file name is given, the extension .bin is used (.b on Unix)
create a Flex9 RELASMB-compatible output file name
if no file name is given, the extension .rel is used
Attention: this file format is undocumented; my solution has been derived from some bits of information gathered on the Flex User Group mailing list and a bit of playing with the original. In my tests, the output was identical to RELASMB's; nevertheless, A09 might create modules that are incompatible with the original under circumstances that I don't know or haven't tested.
create a Motorola S-record output file name
if no file name is given, the extension .s09 is used
create an Intel hex output file name
if no file name is given, the extension .hex is used
create Flex9 ASMB-compatible output file
if no file name is given, the extension .bin is used
create a list file (default no listing)
if no file name is given, the extension .lst is used
define a symbol (see TEXT directive below)
(roughly corresponds to ASMB's command line parameters 1-3)
defines an option (see below)
the assembler source file(s) to be processed.
At least one source file must be given; the first one also defines the default output and listing file names.


Over the years, A09 has learned quite a lot, and it can handle source files / list files in various formats. To allow their selection, I have expanded the scope of the OPT directive (see the FLEX9 Assembler Manual that can be found in the Documentation section on for details). Here's the list of additional options available in A09 (* denotes the default value for a mutually exclusive set):

SYM * print a symbol table
NOS suppress symbol table printing (corresponds to ASMB's S command line option)
MUL * print multiple object code lines
NMU suppress printing of multiple object code lines (corresponds to ASMB's G command line option)
LP1 print a Pass 1 listing
NO1 * print Pass 2 listing only
DAT * print current date on formatted pages
NOD do not print the current date (corresponds to ASMB's D command line option)
NUM print line numbers (corresponds to ASMB's N command line option)
NON * do not print line numbers
INV print invisible lines
NOI * do not print invisible lines
TSC strict TSC Assembler compatibility
NOT * accept source code in a much more relaxed format
WAR * print warnings
NOW only print errors, suppress warnings (corresponds to ASMB's W command line option)
CLL * check line length (see the SETLI directive on that)
NCL do not check line length
LFN print long file names; on Win32 systems, this causes the file names displayed in warning and error messages to contain the full path name of the corresponding source file.
NLF * do not print long file names
LLL * list library file lines
NLL suppress listing of library file lines
GAS accept Gnu AS-compatible source code

This isn't fully implemented yet. At the moment, the only significant difference is that A09 accepts constants in the form 0xXXXX (hex), 0bXXXX (binary), 0NNN (octal) in addition to the "standard" $,%, or @ notation.

NOG * don't accept Gnu AS-compatible source code
REL * print the relocation table if in Relocating Assembler mode
NOR suppress printing of the relocation table
M68|M09 * both forms accept Motorola 6809 mnemonics
H63|H09 accept Hitachi 6309 mnemonics (still slightly experimental)
M00|M02|M08 accept Motorola 6800 mnemonics
M01|M03 accept Motorola 6801 mnemonics
H01|H03 accept Hitachi 6301 mnemonics (slightly experimental)
H11 accept Motorola 68HC11 mnemonics (very experimental)
TXT print the text table if text symbols are defined (see TEXT directive)
NTX * do not print the text table
LPA print listing in f9dasm patch format

This option makes it easier to create complex patches to be embedded in images processed by f9dasm

NLP * don't print listing in f9dasm patch format
DLM define label on macro expansion; see Issue #1 for details.
NDL * do not define labels on macro expansion

Each of the above options has a corresponding text symbol that is set to 0 or 1, corresponding to the state of the option. This allows for conditional assembly, for example:

  IF &H63
    LDW  Data
    SUBW #12
    STW  Data
    PSHS D
    LDD  Data
    SUBD #12
    STD  Data
    PULS D


A09 handles the full set of directives available in the FLEX9 ASMB and RELASMB programs (see the excellent Documentation section on for the manuals of these programs). Apart from these, it knows the following directives:

[label] BIN filename or [label] BINARY filename loads the binary contents of the file given in filename at the current position
EXTERN label is implemented as an alias to the EXT directive (see RELASMB documentation)
FILL value,bytecount writes the 8-bit value value into bytecount consecutive memory locations

Note: if bytecount exceeds 255 and OPT MUL (see above) is set, only the first 255 bytes are shown in the listing.

IFD, IFND symbol[,skipcount] assembles the block up to the next ELSE or ENDIF directive if the symbol is (not) defined.

Attention: this directive is a little bit dangerous - if the symbol is defined after the IF(N)D directive, phasing errors can occur!

PHASE addr DEPHASE tells the assembler that the following code shall be executed at the specified address. This "shifting" is switched off by the instruction DEPHASE.

This can be useful for generation of EPROM contents which contain overlayed code banks where code has to be stored at an address in the EPROM (governed by ORG), but is executed at a different address (governed by PHASE).

REP, REPEAT count are implemented as aliases to the RPT directive (see ASMB documentation)
RZB, BSZ, ZMB nnn works like the RMB directive (see ASMB documentation), but it doesn't only reserve memory, but also zeroes the reserved bytes

Note: if nnn exceeds 255 and OPT MUL (see above) is set, only the first 255 bytes are shown in the listing.

SETLI nnn sets the line length for listings (see the CLL option above); nnn is the number of columns that can be printed in a line (40-2000). If the NCL option is selected, A09 ignores the line width (default is 80).
SETPG nnn sets the page length for paginated listings (see the PAG option in the ASMB documentation); nnn is the number of lines that fit on a page (10-1000, default is 66).
SYMLEN nnn sets the maximum number of significant symbol characters; nnn is the number (6-32). For implications, see Symbols below.
label TEXT text this corresponds to the -dsym[=value] command line option (see above).The FLEX9 ASMB and RELASMB programs can accept up to 3 replacement strings from the command line; these can be used in the source file as "dummy parameters" &A, &B, and &C (see section "COMMAND LINE PARAMETERS" in the ASMB manual on page 50). A09 can do more than that. The -d command line option and the TEXT directive (which can, for example be given in a library file) allow the definition of any number of text replacements (well... not really "any", but 4000 should be no problem :-) which can then be used in the assembler source as &label. In addition to all options (see above), the following constants are predefined:
&ASM Name of the Assembler; contains A09
&VERSION contains the A09 version number as a hex constant ($vvss, vv being the main version and ss being the subversion; at the time of writing, the version is $0128).
&PASS current pass; contains 1 or 2
&FILCHR filler character used for RMB areas in binary output files; defaults to $00
TITLE text is implemented as an alias to the NAM, TTL directive (see ASMB documentation)

Symbol Table Contents

The symbol table produced by A09 is a bit more verbose than the original. For each symbol, it lists the symbol name, type, and value. The following symbol types can occur:

00 constant value (from EQU)
01 variable value (from SET)
02 address within module (LABEL)
03 variable containing address
04 external label
05 variable containing external address
06 unresolved address
07 variable containing unresolved address
08 public label
09 macro definition
10 unresolved public label
11 parameter name
13 empty; should never occur
14 REG directive
15 TEXT directive (value is the index into the text table; if you want to see the last used replacement text for this label, set the TXT option)
18 Common data block name (value is the length of the common data block in this case)
20 Common data RMB label (value is the offset in the common data block)
34 local label (multiple definitions are sorted based on their address)
38 unresolved local label

Relocation Table Contents

The Relocation Table is something which doesn't exist in the original. When in Relocating mode, A09 creates this table to show where a relocation is to be applied. For each entry, A09 lists the symbol name, type, and the relocation address. There can be a '-' prepended to the symbol name to indicate that the symbol is to be subtracted from the value at the relocation address (normally, the symbol is added). The relocation table uses the same set of types as the symbol table.

Things that are.. and things that aren't

My version of A09 aims to reproduce the behaviour of the Flex9 ASMB and RELASMB products. As of now, it reproduces about 99% of the originals' functionality, and surpasses them in some areas. Some things still work slightly different or aren't implemented, however.

Expression Operators

In ASMB and RELASMB, ! denotes a "logical NOT operator"; "logical" in this context means that each bit is inverted. A09's original core came with a slightly different syntax for that, which obviously has its roots in the "C" language the assembler is written in; there, ! denotes a logical NOT (meaning that everything that's not 0 results in 0, and zero results in 1) and ~ denotes a binary inversion, which corresponds to the ! in TSC's assemblers. I decided to keep A09's syntax, as it is more versatile - so ! has a slightly different meaning in A09 than in ASMB/RELASMB.


A09 normally handles symbols with up to 32 significant characters. This is far more than the 6 (ASMB) or 8 (RELASMB) places in the predecessors and normally quite convenient, but it can cause problems when

  • dealing with old sources that rely on the old maximum to work

  • creating RELASMB-compatible relocatable modules

When creating RELASMB-compatible relocatable modules, the number of significant places is automatically reduced to 8. To resolve issues with old sources, the SYMLEN directive has been added in V1.10 (see above). The symbol table always shows the symbols reduced to the number of significant places, since that's how they are treated internally.

Local Labels

This nice feature of RELASMB has been added to A09, too. Due to the completely different implementation, and since A09 doesn't have to work in the extremely limited address space available to a 6809, A09 isn't restricted to 100 local labels; you can define as many local labels as you want to. The only restriction is that the length of the all-numeric symbol must be less than the number of significant symbol characters (see above) so that the B and F character can be appended in references to the local label.

External Expressions

When in Relocating Assembler mode, you can define external labels (i.e., labels that refer to a location in another module, that are resolved by the Linker/Loader at a later time). These labels can be used in expressions, but in a more restricted way than in RELASMB, due to the way the parser works. If there is a mixture of relocatable and external elements in the expression, the relocatable elements have to be in pairs so that they effectively cancel each other's effect, just like in the original - but, additionally, the external label has to be either the last element in the expression or the paired relocatable elements have to be parenthesized. As an example,


would be flagged as an error while


would work.

The command line switch that instructs RELASMB to treat all undefined labels as external labels isn't implemented.

Fix Mode

RELASMB's Fix Mode is not implemented. While that may be a nifty feature, it can easily be replaced by a combination of TEXT and IF directives, which offer a better control over what gets assembled and what doesn't.


In RELASMB, nested macro definitions are allowed; in A09, they are not. Nested macro calls, however, are possible; A09 allows up to 31 levels of macro call nesting.

Like in RELASMB, macros can be used to redefine mnemonics, but with a little twist that is either missing in the original or undocumented: if the need arises to use the original mnemonic in certain places, it can be prefixed with a backslash (\); in this case, A09 doesn't check for macros but uses the original mnemonic. Prefixing a macro name that doesn't overload a mnemonic with \ leads to an error.