This chapter describes the oldstyle syntax module suitable for some
8-bit CPUs (6502, 680x, 68HC1x, Z80, etc.), which is available with the
extension 'oldstyle'.

1 Legal
=======

This module is written in 2002-2018 by Frank Wille and is covered by the
vasm copyright without modifications.

2 Additional options for this version
=====================================

This syntax module provides the following additional options:

'-autoexp'
     Automatically export all non-local symbols, making them visible to
     other modules during linking.

'-dotdir'
     Directives have to be preceded by a dot ('.').

'-i'
     Ignore everything after a blank in the operand field and treat it
     as a comment.  This option is only available when the backend does
     not separate its operands with blanks as well.

'-noc'
     Disable C-style constant prefixes.

'-noi'
     Disable intel-style constant suffixes.

3 General Syntax
================

Labels always start at the first column and may be terminated by a colon
(':'), but don't need to.  In the last case the mnemonic needs to be
separated from the label by whitespace (not required in any case, e.g.
'=').

   Local labels are preceded by ''.'' or terminated by ''$''.  For the
rest, any alphanumeric character including ''_'' is allowed.  Local
labels are valid between two global label definitions.

   It is allowed, but not recommended, to refer to any local symbol
starting with ''.'' in the source, by preceding its name with the name
of the last global symbol, which was defined before it:
'global_name.local_name'.

   The operands are separated from the mnemonic by whitespace.  Multiple
operands are separated by comma (',').

   Make sure that you don't define a label on the same line as a
directive for conditional assembly (if, else, endif)!  This is not
supported.

   Some CPU backends may supported multiple statements (directives or
mnemonics) per line, separated by a special character (e.g.  ':' for
Z80).

   Comments are introduced by the comment character ';', or the first
blank following the operand field when option '-i' was given.  The rest
of the line will be ignored.

   Example:

   'mylabel instr op1,op2 ;comment'

   In expressions, numbers starting with '$' are hexadecimal (e.g.
'$fb2c').  For Z80 also '&' may be used as a hexadecimal prefix, but
make sure to avoid conflicts with the and-operator (either by using
parentheses or blanks).  '%' introduces binary numbers (e.g.
'%1100101').  Numbers starting with '@' are assumed to be octal numbers,
e.g.  '@237' (except for Z80, where it means binary).  A special case is
a digit followed by a '#', which can be used to define an arbitrary base
between 2 and 9 (e.g.  '4#3012').  Intel-style constant suffixes are
supported: 'h' for hexadecimal, 'd' for decimal, 'o' or 'q' for octal
and 'b' for binary.  Hexadecimal intel-style constants must start with a
digit (prepend '0', when required).  Also C-style prefixes are supported
for hexadecimal ('0x') and binary ('0b').  All other numbers starting
with a digit are decimal, e.g.  '1239'.

4 Directives
============

The following directives are supported by this syntax module (if the
CPU- and output-module allow it):

'<symbol> = <expression>'
     Equivalent to '<symbol> equ <expression>'.

'abyte <offset>,<exp1>[,<exp2>,"<string1>"...]'
     Write the integer or string constant operands into successive bytes
     of memory in the current section while adding the constant <offset>
     to each byte.  Any combination of integer and character string
     constant operands is permitted.

'addr <exp1>[,<exp2>...]'
     Equivalent to 'word <exp1>[,<exp2>...]'.

'align <bitcount>'
     Insert as much zero bytes as required to reach an address where
     <bit_count> low order bits are zero.  For example 'align 2' would
     make an alignment to the next 32-bit boundary.

'asc <exp1>[,<exp2>,"<string1>"...]'
     Equivalent to 'byte <exp1>[,<exp2>,"<string1>"...]'.

'ascii <exp1>[,<exp2>,"<string1>"...]'
     See 'defm'.

'asciiz "<string1>"[,"<string2>"...]'
     See 'string'.

'assert <expression>[,<message>]'
     Display an error with the optional <message> when the expression is
     false.

'binary <file>'
     Inserts the binary contents of <file> into the object code at this
     position.  The file will be searched first in the current
     directory, then in all paths defined by '-I' or 'incdir' in the
     order of occurence.

'blk <exp>[,<fill>]'
     Insert <exp> zero or <fill> bytes into the current section.

'blkw <exp>[,<fill>]'
     Insert <exp> zero or <fill> 16-bit words into the current section,
     using the endianess of the target CPU.

'bsz exp>[,<fill>]'
     Equivalent to 'blk <exp>[,<fill>]'.

'byt'
     Increases the program counter by one.  Equivalent to 'blk 1,0'.

'byte <exp1>[,<exp2>,"<string1>"...]'
     Assign the integer or string constant operands into successive
     bytes of memory in the current section.  Any combination of integer
     and character string constant operands is permitted.

'data <exp1>[,<exp2>,"<string1>"...]'
     Equivalent to 'byte <exp1>[,<exp2>,"<string1>"...]'.

'db <exp1>[,<exp2>,"<string1>"...]'
     Equivalent to 'byte <exp1>[,<exp2>,"<string1>"...]'.

'dc <exp>[,<fill>]'
     Equivalent to 'blk <exp>[,<fill>]'.

'defb <exp1>[,<exp2>,"<string1>"...]'
     Equivalent to 'byte <exp1>[,<exp2>,"<string1>"...]'.

'defc <symbol> = <expression>'
     Define a new program symbol with the name <symbol> and assign to it
     the value of <expression>.  Defining <symbol> twice will cause an
     error.

'defl <exp1>[,<exp2>...]'
     Assign the values of the operands into successive 32-bit integers
     of memory in the current section, using the endianess of the target
     CPU.

'defp <exp1>[,<exp2>...]'
     Assign the values of the operands into successive 24-bit integers
     of memory in the current section, using the endianess of the target
     CPU.

'defm "string"'
     Equivalent to 'text "string"'.

'defw <exp1>[,<exp2>...]'
     Equivalent to 'word <exp1>[,<exp2>...]'.

'dfb <exp1>[,<exp2>,"<string1>"...]'
     Equivalent to 'byte <exp1>[,<exp2>,"<string1>"...]'.

'dfw <exp1>[,<exp2>...]'
     Equivalent to 'word <exp1>[,<exp2>...]'.

'defs <exp>[,<fill>]'
     Equivalent to 'blk <exp>[,<fill>]'.

'dephase'
     Equivalent to 'rend'.

'ds <exp>[,<fill>]'
     Equivalent to 'blk <exp>[,<fill>]'.

'dsb <exp>[,<fill>]'
     Equivalent to 'blk <exp>[,<fill>]'.

'dsw <exp>[,<fill>]'
     Equivalent to 'blkw <exp>[,<fill>]'.

'dw <exp1>[,<exp2>...]'
     Equivalent to 'word <exp1>[,<exp2>...]'.

'end'
     Assembly will terminate behind this line.

'endif'
     Ends a section of conditional assembly.

'el'
     Equivalent to 'else'.

'else'
     Assemble the following lines when the previous 'if'-condition was
     false.

'ei'
     Equivalent to 'endif'.  (Not available for Z80 CPU)

'endm'
     Ends a macro definition.

'endmac'
     Ends a macro definition.

'endmacro'
     Ends a macro definition.

'endr'
     Ends a repetition block.

'endrep'
     Ends a repetition block.

'endrepeat'
     Ends a repetition block.

'endstruct'
     Ends a structure definition.

'endstructure'
     Ends a structure definition.

'<symbol> eq <expression>'
     Equivalent to '<symbol> equ <expression>'.

'<symbol> equ <expression>'
     Define a new program symbol with the name <symbol> and assign to it
     the value of <expression>.  Defining <symbol> twice will cause an
     error.

'extern <symbol>[,<symbol>...]'
     See 'global'.

'even'
     Aligns to an even address.  Equivalent to 'align 1'.

'fail <message>'
     Show an error message including the <message> string.  Do not
     generate an ouput file.

'fill <exp>'
     Equivalent to 'blk <exp>,0'.

'fcb <exp1>[,<exp2>,"<string1>"...]'
     Equivalent to 'byte <exp1>[,<exp2>,"<string1>"...]'.

'fcc "<string>"'
     Equivalent to 'text'.

'fdb <exp1>[,<exp2>,"<string1>"...]'
     Equivalent to 'word <exp1>[,<exp2>...]'.

'global <symbol>[,<symbol>...]'
     Flag <symbol> as an external symbol, which means that <symbol> is
     visible to all modules in the linking process.  It may be either
     defined or undefined.

'if <expression>'
     Conditionally assemble the following lines if <expression> is
     non-zero.

'ifdef <symbol>'
     Conditionally assemble the following lines if <symbol> is defined.

'ifndef <symbol>'
     Conditionally assemble the following lines if <symbol> is
     undefined.

'ifd <symbol>'
     Conditionally assemble the following lines if <symbol> is defined.

'ifnd <symbol>'
     Conditionally assemble the following lines if <symbol> is
     undefined.

'ifeq <expression>'
     Conditionally assemble the following lines if <expression> is zero.

'ifne <expression>'
     Conditionally assemble the following lines if <expression> is
     non-zero.

'ifgt <expression>'
     Conditionally assemble the following lines if <expression> is
     greater than zero.

'ifge <expression>'
     Conditionally assemble the following lines if <expression> is
     greater than zero or equal.

'iflt <expression>'
     Conditionally assemble the following lines if <expression> is less
     than zero.

'ifle <expression>'
     Conditionally assemble the following lines if <expression> is less
     than zero or equal.

'ifused <symbol>'
     Conditionally assemble the following lines if <symbol> has been
     previously referenced in an expression or in a parameter of an
     opcode.  Issue a warning, when <symbol> is already defined.  Note
     that 'ifused' does not work, when the symbol has only been used in
     the following lines of the source.

'incbin <file>[,<offset>[,<nbytes>]]'
     Inserts the binary contents of <file> into the object code at this
     position.  When <offset> is specified, then the given number of
     bytes will be skipped at the beginning of the file.  The optional
     <nbytes> argument specifies the maximum number of bytes to be read
     from that file.  The file will be searched first in the current
     directory, then in all paths defined by '-I' or 'incdir' in the
     order of occurence.

'incdir <path>'
     Add another path to search for include files to the list of known
     paths.  Paths defined with '-I' on the command line are searched
     first.

'include <file>'
     Include source text of <file> at this position.  The include file
     will be searched first in the current directory, then in all paths
     defined by '-I' or 'incdir' in the order of occurence.

'mac <name>'
     Equivalent to 'macro <name>'.

'list'
     The following lines will appear in the listing file, if it was
     requested.

'local <symbol>[,<symbol>...]'
     Flag <symbol> as a local symbol, which means that <symbol> is local
     for the current file and invisible to other modules in the linking
     process.

'macro <name>[,<argname>...]'
     Defines a macro which can be referenced by <name>.  The <name> may
     also appear on the left side of the 'macro' directive, starting at
     the first column.  The macro definition is closed by an 'endm'
     directive.  When calling a macro you may pass up to 9 arguments,
     separated by comma.  Those arguments are referenced within the
     macro context as '\1' to '\9', or optionally by named arguments,
     which you have to specify in the operand.  Argument '\0' is set to
     the macro's first qualifier (mnemonic extension), when given.  The
     special argument '\@' inserts an underscore followed by a six-digit
     unique id, useful for defining labels.  '\()' may be used as a
     separator between the name of a macro argument and the subsequent
     text.  '\<symbolname>' inserts the current decimal value of the
     absolute symbol 'symbolname'.

'mdat <file>'
     Equivalent to 'incbin <file>'.

'nolist'
     The following lines will not be visible in a listing file.

'org <expression>'
     Sets the base address for the subsequent code.  This is equivalent
     to '*=<expression>'.

'phase <expression>'
     Equivalent to 'rorg <expression>'.

'repeat <expression>'
     Equivalent to 'rept <expression>'.

'rept <expression>'
     Repeats the assembly of the block between 'rept' and 'endr'
     <expression> number of times.  <expression> has to be positive.

'reserve <exp>'
     Equivalent to 'blk <exp>,0'.

'rend'
     Ends a 'rorg' block of label relocation.  Following labels will be
     based on 'org' again.

'roffs <expression>'
     Sets the program counter <expression> bytes behind the start of the
     current section.  The new program counter must not be smaller than
     the current one.  The space will be padded with zeros.

'rorg <expression>'
     Relocate all labels between 'rorg' and 'rend' based on the new
     origin from '<expression>'.

'section <name>[,"<attributes>"]'
     Starts a new section named <name> or reactivate an old one.  If
     attributes are given for an already existing section, they must
     match exactly.  The section's name will also be defined as a new
     symbol, which represents the section's start address.  The
     "<attributes>" string may consist of the following characters:

     Section Contents:
     'c'
          section has code

     'd'
          section has initialized data

     'u'
          section has uninitialized data

     'i'
          section has directives (info section)

     'n'
          section can be discarded

     'R'
          remove section at link time

     'a'
          section is allocated in memory

     Section Protection:

     'r'
          section is readable

     'w'
          section is writable

     'x'
          section is executable

     's'
          section is sharable

'<symbol> set <expression>'
     Create a new symbol with the name <symbol> and assign the value of
     <expression>.  If <symbol> is already assigned, it will contain a
     new value from now on.

'spc <exp>'
     Equivalent to 'blk <exp>,0'.

'string "<string1>"[,"<string2>"...]'
     Like 'text', but adds a terminating zero-byte.

'struct <name>'
     Defines a structure which can be referenced by <name>.  Labels
     within a structure definitation can be used as field offsets.  They
     will be defined as local labels of '<name>' and can be referenced
     through '<name>.<label>'.  All directives are allowed, but
     instructions will be ignored when such a structure is used.  Data
     definitions can be used as default values when the structure is
     used as initializer.  The structure name, <name>, is defined as a
     global symbol with the structure's size.  A structure definition is
     ended by 'endstruct'.

'structure <name>'
     Equivalent to 'struct <name>'.

'text "<string>"'
     Places a single string constant operands into successive bytes of
     memory in the current section.  The string delimiters may be any
     printable ASCII character.

'weak <symbol>[,<symbol>...]'
     Flag <symbol> as a weak symbol, which means that <symbol> is
     visible to all modules in the linking process and may be replaced
     by any global symbol with the same name.  When a weak symbol
     remains undefined its value defaults to 0.

'wor <exp1>[,<exp2>...]'
     Equivalent to 'word <exp1>[,<exp2>...]'.

'wrd'
     Increases the program counter by two.  Equivalent to 'blkw 1,0'.

'word <exp1>[,<exp2>...]'
     Assign the values of the operands into successive 16-bit words of
     memory in the current section, using the endianess of the target
     CPU.

'xdef <symbol>[,<symbol>...]'
     See 'global'.

'xlib <symbol>[,<symbol>...]'
     See 'global'.

'xref <symbol>[,<symbol>...]'
     See 'global'.

5 Structures
============

The oldstyle syntax is able to manage structures.  Structures can be
defined in two ways:
     mylabel struct[ure]
             <fields>
             endstruct[ure]
   or:
             struct[ure] mylabel
             <fields>
             endstruct[ure]

   Any directive is allowed to define the structure fields.  Labels can
be used to define offsets into the structure.  The initialized data is
used as default value, whenever no value is given for a field when the
structure is referenced.

   Some examples of structure declarations:
       struct point
     x    db 4
     y    db 5
     z    db 6
       endstruct

   This will create the following labels:
     point.x  ; 0   offsets
     point.y  ; 1
     point.z  ; 2
     point    ; 3   size of the structure

   The structure can be used by optionaly redefining the fields value:
     point1 point
     point2 point 1, 2, 3
     point3 point ,,4
   is equivalent to
     point1
                    db 4
                    db 5
                    db 6
     point2
                    db 1
                    db 2
                    db 3
     point3
                    db 4
                    db 5
                    db 4

6 Known Problems
================

Some known problems of this module at the moment:

   - Addresses assigned to 'org' or to the current pc symbol ''*'' (on
     the z80 the pc symbol is ''$'') must be constant.

   - Expressions in an 'if' directive must be constant.

7 Error Messages
================

This module has the following error messages:

   - 1001: syntax error
   - 1002: invalid extension
   - 1003: no space before operands
   - 1004: too many closing parentheses
   - 1005: missing closing parentheses
   - 1006: missing operand
   - 1007: garbage at end of line
   - 1008: %c expected
   - 1009: invalid data operand
   - 1010: , expected
   - 1011: identifier expected
   - 1012: illegal escape sequence %c
   - 1013: unexpected "%s" without "%s"
   - 1021: cannot open binary file "%s"
   - 1023: alignment too big
   - 1024: label <%s> has already been defined
   - 1025: skipping instruction in struct init
   - 1026: last %d bytes of string constant have been cut

