The assembler

Description

XA supports both the standard 6502 opcodes as well as the CMOS versions (Rockwell 65c02). Not supported are the 6502 undocumented opcodes, they have to be put in by hand (with ".byte" directives).

Parameters and features

The assembler contains only a single programm called "xa". It takes one or more Source files into one object file, that can directly be used. But the assembler also has a mode to produce relocatable files, conforming to the 'o65' fileformat (See fileformat.txt).

Call:

xa [options] Source1 [Source2 ...] 
Object: this is the name, the output (object) file gets Error: Here you will find the Error listing. Label: this is the label list

'-C' 		gives error codes when using 65c02 opcodes. Default is not to complain.
'-W' 		gives error codes when using 65816 opcodes. Default is not to complain.
'-c'		    do not produce o65 executable, but object files that can contain undefined references.
'-cc        almost identical to '-c' except the result is usable with CC65 tools.
'-v' 		go into verbose mode
'-R' 		do not produce absolute code, but do relocation and all that.
'-o filename'	set output filename
'-e filename'	set errorlog filename
'-l filename'	set labellist filename
'-r'		add crossreference list to labellist output (i.e list of filename/line where label is used)
'-M'		allow ':' to appear in comments after a semicolon (MASM mode)
'-b? adr'	set segment start address for ? = t(ext), d(ata), b(ss) or z(ero) segment.
'-A adr'	If the _file_ starts at adr in a ROM, then the text segment need not be relocated. 
			That of course only works, if the data/bss/zero segments are not occupied by other programs too!
'-G'		omit writing the exported globals to the file.
'-B'		Show lines with '.(' or '.)' pseudo opcodes
'-Llabel'	defines 'label' as absolute, undefined reference
'-DDEF=TEXT'	define a preprocessor replacement
'-Ipath'        additional include path for include files. Is evaluated before
                the XAINPUT environment variable. One path per '-I',
                multiple '-Ipath' allowed.
Omitting the errorfile or labelfile Parameter will cause xa to not write these files. Using '-x' will cause xa to take the name of the first source file and change the extension (on an Atari there is only one, like in DOS) to 'obj', 'err' and 'lab' respectively - if the old behaviour is selected with the '-x' option or the files are defined with "-l" and "-e". If no output file is given, "a.o65" is used.

Environment variables

You can use the variables XAOUTPUT and XAINPUT to adjust the directory structure. If source or include files are not found, the Path in XAINPUT is being searched for the files. The different paths are separated by a comma (','). XAINPUT gives the directory where the *.obj, *.err and *.lab files are put. If they are not set, there will be no search, respectively the files are saved to the current directory.

The label file is a readable ASCII-file and lists all the labels together with their block-count (see below) and their address. The error file lists the version of the assembler, date and time of the assembler run, all the error messages and the stuff being printed with #echo and #print and last but not least a statistics of used resources.

Some specific details

When using addressing modes that could be zeropage or absolute, zeropage will be taken if possible. This can be prevented by prefixing the address with a '!'. Then absolute addressing is taken, regardless of the address.

Values or Addresses can be expressed by arithmetik expressions with hierachy and bracket. The following operands are understood:

123       -decimal
$234      -hexadecimal
&123      -octal
%010110   -binary
*         -program counter
"A"       -ASCII-code
labelx    -label
-(lab1+1) -expression
The following operands can be used (third column is priority):

+         -addition                     9
-         -subtraction                  9
*         -multiplication               10
/         -integer-division             10
<<        -shift left                   8
>>        -shift right                  8
>=,=>     -more or equal                7 
<=,=<     -less or equal                7
<         -less                         7
>         -more                         7 
=         -equal                        6
<>,><     -not equal                    6
&&        -logical AND                  2
||        -Logical OR                   1
&         -Bitwise AND                  5
|         -Bitwise OR                   3
^         -Bitwise XOR                  4
Operators with higher priority are evaluated first. Brackets can be used as usual.

Valid expressions are, e.g.:

LDA       base+number*2,x
For Addressing modes that do not start with a bracket, you can even use a bracket at the beginning of an expression. Otherwise try this:

LDX       (1+2)*2,y                ; Wrong!
LDX       2*(1+2),y                ; Right!
Before an expression you can use these unitary operators:

    
<      Gives the low byte of the expression
>      Gives the high byte

LDA  #<adresse
Single Assembler statements are being separated by a ':' (You remember the C64 :-) or a newline. Behind Each statement, separated by a ';' you can write some comments. The next colon or a newline ends the comment and starts a new statement. In MASM compatibility mode ('-M' command line option), then a colon in a comment is ignored, i.e. the comment lasts till the newline.

Pseudo opcodes, Block structures and where Labels are valid

In addition to the 6502 opcodes you have the following Pseudo opcodes:

Labels

A label is defined by not being an opcode:

label1 LDA #0              ; assignes the programm counter
label2 =1234               ; explicit definition
label3 label4 label5       ; implicit programm counter
label6 label7 = 3	   ; label6 becomes the program counter, while
			   ; label7 is set to 3
label8:   sta label2	   ; As ':' divides opcodes, this is also
			   ; working
You can use more than one label for definition, except for explicit definition.

Preprocessor

The preprocessor is very close to the one of the language C. So in addition to the ';'-comments you can also use C-like comments in '/*' and '*/'. Comments can be nested.

#include  "filename"     includes a file on exactly this position.
			 if the file is not found, it is searched using 
			 XAINPUT. 

#echo  comment           gives a comment to the error file.

#file "filename"         Set the internal line counter in order to get correct line numbers at link phase

#print expression        prints an expression to the error file (after preprocessing and calculating)

#printdef DEFINED        prints the definition of a preprocessor define to the error file.

#define DEF  text	 defines 'DEF' by 'text'

#ifdef DEF               The source code from here to the following #endif
			 or #else is only assembled if 'DEF' is defined
			 with #define.

#else                    just else... (optionally)

#endif                   ends an #if-construct. This is a must to end #IF* 

#ifndef  DEF             .... if DEF is not defined

#if expression           .... if expression is not zero

#iflused label           .... if a label has already been used

#ifldef label            .... if a label is already defined
#iflused and #ifldef work an labels, not on preprocessor defs! With these commands a kind of library is easily built:

#iflused  label
#ifldef   label
#echo     label already defined, not from library
#else
label     lda #0
          ....
#endif
#endif
You can have up to 15 #if* on stack before the first #endif

You can also use #define with functions, like in C.

#define mult(a,b)   ((a)*(b))
The preprocessor also allows continuation lines. I.e. lines that end with a '\' directly before the newline have the following line concatenated to it.

Historic

Here is the list of all releases with a short description of things that changed:

2.2.5

- Added a new '-cc' command line parameter to allow compatibility with the CC65 toolchain

2.2.4

- Extended the values for a number of hardcoded defines (labels, blocks, number of open files, etc...)

2.2.3

- Fixed a stupid crash happening when no filename was provided for the symbols or error files.

2.2.2

- Normally C, C++ and asm comments should be handled correctly, and ignored if in a quoted string.

2.2.1

- hopefully fixed a problem of data corruption happening when a line parsed during pass1 generated more than 127 bytes of tokens for the pass2 to decode.

2.1.7

- removed the '-x' switch from XA code. I will progressively remove all the legacy stuff when replacement features already exist, in this case -o, -e and -l

2.1.6

- debogged the #file directive that was actually giving valid file names only for the errors that happened during pass 1.

2.1.5

- added a #file directive
- corrected some error messages

2.1.4h (25nov1998)

- preprocessor fix, improve file65.

2.1.4g (25nov1998)

- fix "!" addressing syntax, add reference list for labels.

2.1.4f (21apr1998)

- cross-compilable for DOS with make dos

2.1.4e

- some bugfixes concerning o65 fileformat, as well as a fileformat change.

2.1.4

- preprocessor understands continuation lines, more command line options available.

2.1.3

- a new feature of the fileformat: aligned segments. Segments can be aligned to 2, 4, or 256 byte address boundary. A new pseudo-opcode has been introduced, ".align", that aligns the address in the current segment to the value given. ".align 4" aligns the segment address to a 4-byte boundary. Also the pseudo-opcodes ".data", ".bss", ".zero" and ".text" to switch segments can now be used in absolute mode, i.e. when started without relocation. They work as they do in relative mode, but the data segment is discarded (this might change in the future, but currently it doesn't work) and no relocation tables or label tables and no o65 file header are written. Advantages are that you can use the same code base for relative and absolute mode programs, and you don't have to manage the variable space yourself.

2.1.2a

- linker, relocator and file utility for 'o65' format included, some bugs fixed.

2.1.1e

- started supporting the 'o65' file format

2.0.7d

- now understands the #undef preprocessor directive.

Version 2.0.7.c

- the include statements can now contain '\' or '/' as directory separator, and both are accepted (with DIRCHAR='/').