The HSW12ASM is a simple multi-pass assembler which has been written in Perl code.
Some features of this assembler are:
- It handles 16MB of address space
- It generates linear and paged S-Record files
- It uses two program counters (linear and paged) to control the S-Record output
- It exports source code symbols into the HSW12 IDE
This assembler is normally invoked from the HSW12 IDE
it can be used stand alone with the command line interface hsw12asm.pl
is invoked as follows:
perl hsw12asm.pl <src files> [-L <library paths>] [-D <defines: name=value or name>] [-S19|-S28]
<src files> source code files(*.s)
<library paths> directories to search for include files
<defines> assembler defines
S19,S28 S-Record format
The following sections give some insight to the assembler's source code format and its outputs.
All code following ";" to the end of the line is interpreted as a comment by the HSW12 assembler. Comments may also begin
with an "*" if it is the first non-whitespace character in the line.
Expressions consist of symbols, constants and operators. They are used as operands for the HC(S) opcodes
and and the assembler pseudo opcodes.
Symbols represent integer values.
Symbols can be defined through various pseudo-opcodes
or through the use of labels.
A symbol name must comply to these rules:
- The symbol name must consist of alpha-numeric characters, and underscores (^[A-Z0-9_]+$)
- The symbol name must begin with a letter (^[A-Z])
- The symbol name may not contain any whitespaces
- The symbol name may not be any of the keywords: A, B, D, X, Y, SP, CCR, PC, TMP2, TMP3, UNMAPPED
The HSW12 assembler knows a set of predefined symbols:
@ Represents the current value of the linear program counter
* Represents the current value of the paged program counter
The HSW12 assembler supports the automatic generation of symbol name extensions. If a symbol name ends with a "'",
this character will be substituted by the contents of the LOC
counter variable. This counter may be incremented
by the LOC
Integer Constants are of the following format:
%... binary constant (^%+$)
... decimal constant (^[0-9]+$)
$... hexadecimal constant (^\$[0-9A-H]+$)
"..." ascii strings (^["'].+["']$)
The HSW12 assembler supports the operators that are listed below (from highest to lowest precedence).
Expressions may be nested in parenthesis.
& bitwise AND
| bitwise OR
^ bitwise XOR
/ integer division
Labels assign the current value of the paged program counter to a symbol.
The syntax is:
(The symbol name must be the first characters in the line.)
To assign the current value of the linear program counter to a symbol, use the following syntax:
SYMBOL EQU @
The HSW12 assembler knows the following precompiler directives:
All precompiler directives must comply to the following syntax rules:
line starts with
a hash, directly
followed by the
#<directive> <arg> <arg> ...
^ ^ ^
| | |
Sets an assembler define for conditional code compilation. All assembler defines will be exported
into compiler symbols at the end of the precompile step.
requires two arguments:
- a define name
- a value the define is set to (optional)
To make the HSW12 assembler behave a little more like the
all labels and pseudo-opcode symbol assignments will be considered as precompiler defines as well.
Undefines an assembler define.
requires one argument:
- a define name
Starts a section of conditional code. This code will only be compiled if the define is set.
Starts a section of conditional code. This code will only be compiled if the define is not set.
Starts a section of conditional code. This code will only be compiled if the macro is defined.
Starts a section of conditional code. This code will only be compiled if the macro is not defined.
Ends a section of conditional code that has been initiated with "#IFDEF"
, or "#IFNMAC"
and starts a new one that requires the opposite condition.
End a section of conditional code.
Includes a source code file at the current position.
Starts a macro definition. This directive requires two arguments:
- The macro name
- The number of arguments which are to be passed to the macro
A macro definition ends with an #EMAC
Inside the macro, the strings "\1", "\2", ... will be replaced by the macro arguments.
All lables will be defined in a local name space.
Nested macro calls are possible.
#MACRO MAC0 2
LOOP CPD 0,\2
#MACRO MAC1 1
LOOP CPD 0,\1
MAC0 X, Y
?????? S12 CODE: CPU S12
000000 0F4000 ORG $0000
000000 0F4000 MACRO MAC0 X, Y
000000 0F4000 MACRO MAC1 \1 (MAC0)
000000 0F4000 AC 00 LOOP CPD 0,\1 (MAC0/MAC1)
000002 0F4002 26 FC BNE LOOP (MAC0/MAC1)
000004 0F4004 AC 40 LOOP CPD 0,\2 (MAC0)
000006 0F4006 27 FC BEQ LOOP (MAC0)
Ends a macro definition.
The following pseudo-opcodes are supported by the HSW12 assembler:
All pseudo-opcodes must comply to the following syntax rules:
must start at arguments must
the begin of be separated
the line by a comma
<symbol> <pseudo-opcode> <arg>, <arg>, ...
Increments both program counters until PC & mask == 0. If a second argument is given, then all memory
locations in between are filled with the lower eight bit of this integer.
ALIGN <mask> <pattern>
Switches to a different opcode table. Supported CPUs are:
- HC11 (untested)
Writes a number of constant bytes into the memory.
DC.B <byte>, <byte>, ...
Writes a number of constant words into the memory.
DC.W <word>, <word>, ...
Advances both program counters by a number of bytes.
Advances both program counters by a number of words.
Triggers an intentional compile error. The string must be surrounded by a delimiter
which can be any character.
Directly assigns a value to a symbol.
<symbol> EQU <expression>
Writes an ASCII string into the memory. The string must be surrounded by a delimiter
which can be any character.
Writes an ASCII string into the memory, which is terminated by a set MSB in the last character.
The string must be surrounded by a delimiter which can be any character.
Writes an ASCII string into the memory, which is terminated by a zero character ($00).
The string must be surrounded by a delimeter which can be any character.
Fills a number of memory bytes with an 8-bit pattern.
FILL <pattern>, <#bytes>
Calculates the Fletcher-16 checksum of a paged address range
(defined by the two arguments: start address and end address).
FLET16 <start address>, <end address>
Increments the "LOC"
counter that is used for automatic symbol name extensions.
This pseudo-opcode can be used to set the program counters to a certain value.
If "ORG" is called with two arguments, then the paged program counter will be set to the value of the first
argument. The linear program counter will be set to the value of the second argument.
If only one argument is passed to the pseudo-opcode, then this one will be the new value of the paged program
counter. The value of the linear program counter is determined by the following table.
|Paged Program Counter
||Linear Program Counter
ORG <paged PC>
ORG <paged PC>, <linear PC>
Same as ALIGN
, except that the program counters are incremented until PC & mask == mask.
UNALIGN <mask>, <pattern>
Selects the 256 byte address range in which direct address mode can be applied for S12X MCUs.
SETDP <direct page>
For a description of the HC(S)12 instruction set, please refer to the
HCS12 Core Guide
All opcodes must comply to the following syntax rules:
must start at operands must
the beginning be separated
of the line by a comma
<label> <opcode> <operand>, <operand>, ...
The HSW12 assembler can generate three output files:
- A Code Listing
The Code Listing shows the assembler source together with the associated hex code. The entries are sorted by their paged address.
- A Paged S-Record File
The hex code of the paged address domain (paged program counter) in Motorola's S-Record format.
Paged addresses consist of an 8-bit page value (PPAGE register, MSB) and a 16-bit address value (PC register, LSB) =>PPAGE:ADDR.
- A Linear S-Record File
The hex code of the linear address domain (linear program counter) in Motorola's S-Record format.
Linear addresses are equivalent to the physical address space of the NVMs inside the HC(S)12 MCUs.