1
0
mirror of https://github.com/pfusik/xasm.git synced 2024-06-16 09:29:27 +00:00
xasm/doc/xasm.htm
2013-01-07 12:07:31 +01:00

904 lines
35 KiB
HTML

<HTML><HEAD><TITLE>X-Assembler 2.5.2</TITLE></HEAD>
<BODY BACKGROUND="6502proc.gif">
<CENTER>
<H1>X-Assembler version 2.5.2</H1>
<HR>
<H2>TABLE OF CONTENTS</H2>
<TABLE><TR><TD VALIGN=top>
<UL><LI><A HREF="#intro">INTRODUCTION</A>
<UL><LI><A HREF="#changes">Changes</A>
<UL><LI><A HREF="#ver252">Version 2.5.2</A>
<LI><A HREF="#ver251">Version 2.5.1</A>
<LI><A HREF="#ver25">Version 2.5</A>
<LI><A HREF="#ver241">Version 2.4.1</A>
<LI><A HREF="#ver24">Version 2.4</A>
<LI><A HREF="#ver23">Version 2.3</A>
<LI><A HREF="#ver22">Version 2.2</A>
<LI><A HREF="#ver20">Version 2.0</A>
<LI><A HREF="#ver12">Version 1.2</A>
</UL></UL><LI><A HREF="#usage">USAGE</A>
<UL><LI><A HREF="#sysreq">System requirements</A>
<LI><A HREF="#srcreq">Source code requirements</A>
<LI><A HREF="#convqa">Converting Quick Assembler files</A>
<LI><A HREF="#asm">Assembling a source program</A>
<LI><A HREF="#opts">Assembling options</A>
<LI><A HREF="#exitcod">Exit codes</A>
<LI><A HREF="#listing">Listing structure</A>
<LI><A HREF="#labtab">Label table structure</A>
</UL>
</TD><TD VALIGN=top>
<UL><LI><A HREF="#syntax">SYNTAX</A>
<UL><LI><A HREF="#fields">Fields</A>
<UL><LI><A HREF="#label">Label field</A>
<LI><A HREF="#repeat">Repeat count</A>
<LI><A HREF="#instr">Instruction field</A>
<LI><A HREF="#operand">Operand field</A>
<LI><A HREF="#comment">Comment</A>
</UL><LI><A HREF="#expr">Expressions</A>
<UL><LI><A HREF="#numbers">Numbers</A>
<LI><A HREF="#operators">Operators</A>
</UL><LI><A HREF="#directives">Directives</A>
<LI><A HREF="#pseudocom">Pseudo-commands</A>
<LI><A HREF="#adrmod">Addressing modes</A>
</UL><LI><A HREF="#faq">FAQ</A>
</UL>
</TD></TR></TABLE></CENTER>
<P><HR>
<A NAME="intro"><H2>INTRODUCTION</H2>
The X-Assembler is a cross-assembler, which generates code for the 6502 processor.
It has been designed to be easy to use for Quick Assembler programmers,
therefore its syntax is an extension of QA's.<BR>
<A NAME="changes"><H3>Changes</H3>
<A NAME="ver252"><H4>Version 2.5.2</H4>
<UL>
<LI> version 2.5.1 broke Unix EOLs - fixed
<LI> version 2.5.1 omitted all blank/comment/label lines, unless <TT>/c</TT> was used
</UL>
<A NAME="ver251"><H4>Version 2.5.1</H4>
<UL>
<LI> fixed assembling sources with Atari EOLs ($9b)
<LI> blank/comment/label lines in false conditionals are now correctly omitted in listing
</UL>
<A NAME="ver25"><H4>Version 2.5</H4>
<UL>
<LI> fixed another bug, very similar to previous one, e.g.
<PRE> ift 0
:label nop
eif
</PRE>
reported <TT>Label not defined before</TT> error for the repeat count.
<LI> <A HREF="#new_opt"><TT>OPT F+</TT> causes <TT>ORG</TT>s to fill the space between old and new
location with <TT>$FF</TT>s</A>
<LI> <A HREF="#new_opt"><TT>OPT G+</TT> enables Atari 5200 mode for hardware register abbreviations</A>
</UL>
<A NAME="ver241"><H4>Version 2.4.1</H4>
<UL>
<LI> fixed a bug related to label definitions in conditionally skipped code, e.g.
<PRE> ift 0
label
eif
</PRE>
reported <TT>No ORG specified</TT> error for the label definition.
</UL>
<A NAME="ver24"><H4>Version 2.4</H4>
<UL>
<LI> fixed a bug causing incorrect unary operator precedence
<LI> fixed wrong label value after a skip pseudo-command
<LI> the assembler is .EXE (.COM caused problems with DJGPP make due
to a bug in DJGPP runtime)
<LI> the assembler is not compressed (so it occupies less space in the ZIP)
<LI> improved command-line parsing: options may be used before source file
name, tab character is a valid separator, <TT>/</TT> may be used as directory
separator (Unix convention)
<LI> error and warning messages are written to stderr, not stdout
<LI> added <TT>==</TT> (equal) operator, which is equivalent to <TT>=</TT>
(but is more natural for C/C++/Java programmers)
<LI> <A HREF="#new_deflabel">added <TT>/d:label=value</TT> option: define a label</A>
<LI> <A HREF="#new_fullpaths">added <TT>/p</TT> option: print full paths in listing and error messages</A>
<LI> <A HREF="#new_quiet">added <TT>/q</TT> option: quiet mode</A>
<LI> <A HREF="#new_unlabels">added <TT>/u</TT> option: warn of unused labels</A>
<LI> <A HREF="#new_opt">writing to the object file may be suppressed with <TT>OPT O-</TT></A>
<LI> <A HREF="#new_eli">added <TT>ELI</TT> (else if) directive</A>
<LI> <A HREF="#new_mwinde"><TT>MWX</TT> and <TT>MWY</TT> may use <TT>INX</TT>/<TT>DEX</TT>
and <TT>INY</TT>/<TT>DEY</TT>, respectively, for generating smaller code</A>
</UL>
<A NAME="ver23"><H4>Version 2.3</H4>
<UL>
<LI> double skip (e.g. <TT>SCC:SNE</TT>) bug fixed
<LI> real number two-digit exponent bug fixed
<LI> truncating line trailing spaces in listing
<LI> <A HREF="#new_labdef">label definitions allowed in blank,
comment and repeated lines</A>
<LI> <A HREF="#new_unary">unary operators</A>
<LI> <A HREF="#new_dta"><TT>DTA</TT> implied byte mode</A>
<LI> <A HREF="#new_op_op">operand can be skipped for some op-codes</A>
</UL>
<A NAME="ver22"><H4>Version 2.2</H4>
<UL>
<LI> invalid absolute <TT>CPX</TT> and <TT>CPY</TT> op-codes bug fixed
<LI> branch addressing mode not checking bug fixed
<LI> <TT>ICL</TT> in last line bug fixed
<LI> <TT>OPT H-H+</TT> bug fixed
<LI> first <TT>ORG *</TT> bug fixed
<LI> origin setting not required until not used
<LI> Unix ($0a), Macintosh ($0d) and Atari ($9b) EOLs allowed in source
<LI> value of 'true' changed to 1
<LI> <A HREF="#new_environment">
setting environment variables on error option</A>
<LI> <A HREF="#new_newer">
assembling only if source newer than object option</A>
<LI> <A HREF="#new_opcode">op-code extracting</A>
<LI> <A HREF="#new_linerep">line repeating</A>
<LI> <A HREF="#new_pairing">instructions pairing</A>
<LI> <A HREF="#new_repskip">conditional repeat and skip pseudo commands</A>
<LI> <A HREF="#new_adrmodes">
<TT>(),0+</TT> and <TT>(),0-</TT> pseudo addressing modes</A>
</UL>
<A NAME="ver20"><H4>Version 2.0</H4>
<UL>
<LI> truncating name of object bug fixed
<LI> <TT>EQU</TT> and <TT>DTA</TT> forward reference bugs fixed
<LI> hex number recognizing bug fixed
<LI> now <TT>.OBX</TT> is default extension for Atari executables
<LI> assembling options (switches and <TT>OPT</TT> directive)
<LI> listing generation
<LI> label table generation
<LI> conditional assembling
<LI> user errors
<LI> warnings
<LI> improved headers generation
<LI> improved expressions - 19 operators and brackets, 32-bit arithmetic
<LI> improved signed numbers
<LI> 6 new pseudo commands (memory-to-memory move)
<LI> 8 pseudo addressing modes
<LI> indirect conditional jumps
<LI> Atari floating-point numbers generation
<LI> improved <TT>INS</TT>: inserting specified part of file
</UL>
<A NAME="ver12"><H4>Version 1.2</H4>
<UL>
<LI> first release
</UL>
<HR>
<A NAME="usage"><H2>USAGE</H2>
<A NAME="sysreq"><H3>System requirements</H3>
<UL>
<LI> a PC compatible computer with 386 or better CPU
(a numeric coprocessor is required for generating sine lookup tables)
<LI> a MS-DOS compatible OS
</UL>
<A NAME="srcreq"><H3>Source code requirements</H3>
<UL>
<LI> Source file should be plain ASCII file.
Although different EOLs are supported,
CR/LF is recommended because it is standard for text files on PC.
<LI> No line of source can be longer than 256 characters.
<LI> There is no limitation on the length of the source file.
<LI> Tabulators can be used in place of spaces.
<LI> The assembler is not case-sensitive.
</UL>
<A NAME="convqa"><H3>Converting Quick Assembler files</H3>
Because of possible editor-associated problems you had better convert
an Atari text file to a regular PC text file, i.e. EOLs from $9b to $0d/$0a
and ATASCII specific characters to their integer representation.<BR>
You have to change all <TT>OPT</TT> directives,
but usually you only need to remove them.<BR>
<A NAME="asm"><H3>Assembling a source program</H3>
The common syntax of invoking command line is following:<BR>
<PRE>XASM source [options]
</PRE><TT>source</TT> is the name of source file.
If no extension is given, the .ASX is implied.<P>
Default action on invoking without options is to compile
writing to a file with the .OBX extension.<P>
<A NAME="opts"><H3>Assembling options</H3>
Following options are supported:
<DL>
<DT><TT>/c</TT>
<DD>Enable listing false conditionals.<BR>
By default lines skipped due to false condition are not listed.<P>
<A NAME="new_deflabel">
<DT><TT>/d:label=value</TT>
<DD>Define a label.<BR>
<TT>label</TT> should be a valid label name.
<TT>value</TT> may be any expression (it may use forward references
to labels defined in the source file).
You may use several <TT>/d</TT> options to define many labels
from the command line.<P>
<A NAME="new_environment">
<DT><TT>/e</TT>
<DD>Enable setting environment variables pointing to the error location.<BR>
With this option, X-Asm sets two environment variables:
ERRFILE and ERRLINE.
They may be used in a batch file to locate error and set editor's
insertion point on it. For example, you may create following batch file:
<PRE>XASM %1 /e
IF NOT ERRORLEVEL 1 GOTO ok
NCE +%ERRLINE% %ERRFILE%
:ok
</PRE>
NCE stands for Norton Classic Editor.<P>
If there was no error, variables point to the last issued warning.
If no warning occured, they are removed from the environment.<P>
<B>Note:</B> NCE is an old editor for DOS. To learn about integration with
modern text editors for Windows <A HREF="editors.htm">read this</A>.
<P>
<DT><TT>/i</TT>
<DD>Disable listing included source. Only main source file will be listed.<P>
<DT><TT>/l[:filename]</TT>
<DD>Enable generating listing.
If no <TT>filename</TT> given, listing is written to <TT>source.lst</TT>
(where <TT>source</TT> is the name of the source file (without extension).<P>
<A NAME="new_newer">
<DT><TT>/n</TT>
<DD>Check source and object file modification time and assemble only
if source is newer than object file. X-Asm does NOT check included
nor inserted files but only main source, so be careful with this option.<P>
<B>Note:</B> Much more powerful for this purpose is GNU make utility.
In DOS and Windows you may use its DJGPP port (available from
<A HREF="http://www.delorie.com/djgpp">http://www.delorie.com/djgpp</A>).<P>
<DT><TT>/o:filename</TT>
<DD>Specify object file name. Default is <TT>source.obx</TT>.
You may use the null device (<TT>/o:nul</TT>) to generate no object file.<P>
<A NAME="new_fullpaths">
<DT><TT>/p</TT>
<DD>Print fully qualified file names in listing and error messages.<BR>
This option is useful for the Code-Genie editor (see
<A HREF="editors.htm">here</A>), which can jump to the error location
only if full path is given.<P>
<A NAME="new_quiet">
<DT><TT>/q</TT>
<DD>Suppress info messages.<BR>
Prevents X-Asm from printing "<TT>X-Assembler 2.5.2 by Fox/Taquart</TT>"
and the summary (how many lines assembled and bytes written).
Good if you are building a project from many source files and don't want
tons of messages.<P>
<DT><TT>/s</TT>
<DD>Disable converting spaces to tabs in listing.<BR>
Using tabs makes listing file shorter.
Tab stops are assumed to be every 8 characters.<P>
<DT><TT>/t[:filename]</TT>
<DD>List label table.<BR>
If no <TT>filename</TT> given, the table is written at the end of listing
or to <TT>source.tab</TT>.<P>
<A NAME="new_unlabels">
<DT><TT>/u</TT>
<DD>Warn of unused labels.<BR>
A warning message will be issued for each label, which value is never
used.<P>
</DL>
If source is incorrect, X-Asm stops on first encountered error.<P>
<A NAME="exitcod"><H3>Exit codes</H3>
Meaning of exit codes returned by X-Asm:<BR>
3 = bad parameters, assembling not started<BR>
2 = error occured<BR>
1 = warning(s) only<BR>
0 = no errors, no warnings<BR>
<A NAME="listing"><H3>Listing structure</H3>
A line of listing contains:
<UL>
<LI> decimal number of line of source file (if source is different than in
previous listed line, appropriate message line is issued)
<LI> hexadecimal origin counter value
<LI> hexadecimal values of bytes written to object file<BR>
Listed are also generated headers. A <TT>xxxx-yyyy&gt;</TT> in place of origin
counter represents generated header: <TT>$xxxx</TT> is the first and
<TT>$yyyy</TT> is the last byte of the block.
A <TT>FFFF&gt;</TT> represents two $ff bytes written as a header prefix.<BR>
A plus sign placed after hex numbers stands for more bytes written to object
in this line, not listed through lack of space.
<LI> remaining part of listing line is verbatim copy of source line
</UL>
<A NAME="labtab"><H3>Label table structure</H3>
A line of label table contains:
<UL>
<LI> some label attributes:<BR>
<TT>n</TT> - label defined but not used elsewhere<BR>
<TT>2</TT> - label value known in pass 2 only (label definition uses forward
reference and thus you can't make forward references to that label)
<LI> hexadecimal value of the label
<LI> name of the label
</UL>
<HR>
<A NAME="syntax"><H2>SYNTAX</H2>
<A NAME="fields"><H3>Fields</H3>
Source code is line-oriented. Every line of source consists of <I>fields</I>.
Same sequence of characters used in different fields has completely different meaning.
Fields are separated with one or more blank characters.
There can't be any space within a field, except for strings and comments.<P>
There are following types of fields:
<UL>
<LI> <A HREF="#label">label field</A>
<LI> <A HREF="#repeat">repeat count</A>
<LI> <A HREF="#instr">instruction field</A>
<LI> <A HREF="#operand">operand</A>
<LI> <A HREF="#comment">comment</A>
</UL>
<A NAME="new_labdef">Every line of source must match one of two general forms:
<UL>
<LI> <TT>LABEL *COMMENT</TT>
<LI> <TT>LABEL :COUNT CMD:CMD OP1 OP2 COMMENT</TT>
</UL>
In the first form, both fields are optional. Blank lines are ignored of course.
Comment must here start with one of these characters: <TT>; |</TT> or <TT>*</TT>
(semicolon, pipe or asterisk). Any information in the line following
such character is ignored.<P>
In the latter form, you must use a minimum of an instruction field.
It depends on the instruction, how many operands it takes.
Every instruction takes constant number of operands, therefore
there's no need to use a special character at the start of a comment, because after
succesfully taking operands, X-Asm discards the remaining part of line.
However, <A HREF="editors.htm">general purpose text editors</A> may highlight
the comments only if a special delimiter is used, and for that reason,
the semicolon is recommended to start a comment.<P>
<A NAME="label"><H4>Label field</H4>
This field is optional. It must start at first character in line, without
any blank characters before. The purpose of using label field is to define a label.<BR>
Label is a symbol representing an integer of range -$ffff..$ffff.<BR>
Name of a label may contain letters, digits and underscores (<TT>_</TT>).
Digit can not be label's first character.
Name of a label may be as long as you want and all the characters
are meaningful. In Quick Assembler only 6 leading characters were recognized
and some sources may not compile under X-Asm for this reason.<BR>
Defining a label without using <TT>EQU</TT> makes it equal to current value
of the origin counter.<BR>
Labels can't be redefined.<P>
<A NAME="new_linerep"><A NAME="repeat"><H4>Repeat count</H4>
Repeating means here assembling single line several times as if
there were several identical lines. Note it is not just duplicating
bytes written to the object file.<BR>
Repeat count, which can be any valid expression, has to be preceded
with a colon.<BR>
Examples:
<PRE>:4 asl @
:2 dta a(*)
</PRE>
In the latter example each <TT>DTA</TT> has different operand value.<BR>
If repeat count equals zero, remaining part of line is not assembled.
This allows compact single-line conditional assembly.
<A NAME="new_pairing"><A NAME="instr"><H4>Instruction field</H4>
If this is the first field in a line, the line must start with at least
one blank character. Instruction field consists of one or two instructions.
The latter case is called instructions pairing, because a pair
of instructions have shared operand. You separate instructions
with a colon.<BR>
Example:
<PRE> adc:sta $80
</PRE>is equivalent to
<PRE> adc $80
sta $80
</PRE>
Note that
<PRE> lda:tax $80
</PRE>is correct, because <TT>$80</TT> is a comment for <TT>TAX</TT>.<P>
Single instruction always consists of 3 letters. It may be:
<OL TYPE=a>
<LI> a 6502 command - standard mnemonics are used
<LI> <A HREF="#directives">a directive</A>
<LI> <A HREF="#pseudocom">a pseudo-command</A>
</OL>
<A NAME="operand"><H4>Operand field</H4>
Some instructions don't need any operand,
other need two operands.<BR>
6502 commands require operand with proper
<A HREF="#adrmod">addressing mode</A>.<P>
<A NAME="comment"><H4>Comment</H4>
Comment in a statement does not start from any special character
like <TT>;</TT> for example. Comment field is implied when appropriate
number of operands was taken.<P>
<P><HR><P>
<A NAME="expr"><H3>Expressions</H3>
Expressions are numbers combined with operators and brackets.
You should use square brackets, because parentheses are reserved
for 6502 indirect addressing.
<A NAME="numbers"><H4>Numbers</H4>
Numbers are 32-bit signed integers, in the range of -$7fffffff..$7fffffff.
A number may be:<P>
<TABLE>
<TR><TD WIDTH=300><UL><LI> a decimal number</TD><TD><TT>-12345</TT></TD></TR>
<TR><TD><UL><LI> a hexadecimal number</TD><TD><TT>$abcd</TT></TD></TR>
<TR><TD><UL><LI> a binary number</TD><TD><TT>%10100101</TT></TD></TR>
<TR><TD><UL><LI> an ASCII character</TD><TD><TT>'a'</TT> or <TT>"a"</TT></TD></TR>
<TR><TD><UL><LI> the origin counter value</TD><TD><TT>*</TT></TD></TR>
<TR><TD><UL><LI> a hardware register</TD><TD><TT>^4e</TT></TD></TR>
</UL></TABLE>
<BLOCKQUOTE>
An abbreviation of Atari hardware register is provided to save you trouble of typing
two extra characters (<TT>^4e</TT> vs <TT>$d40e</TT>) and to support porting software
between Atari 8-bit computers and Atari 5200 console. These are very similar machines,
one of biggest differences is different location of hardware registers.<P>
<TABLE>
<TR><TD><B>Syntax&nbsp;</B></TD><TD><B>Chip&nbsp;</B></TD>
<TD><B>Value in Atari 8-bit<BR>computer mode (<TT>OPT G-</TT>)&nbsp;</B></TD>
<TD><B>Value in Atari 5200<BR>game console mode (<TT>OPT G+</TT>)&nbsp;</B></TD>
</TR>
<TR><TD><TT>^0x</TT></TD><TD>GTIA&nbsp;</TD><TD><TT>$d00x</TT></TD><TD><TT>$c00x</TT></TD></TR>
<TR><TD><TT>^1x</TT></TD><TD>GTIA&nbsp;</TD><TD><TT>$d01x</TT></TD><TD><TT>$c01x</TT></TD></TR>
<TR><TD><TT>^2x</TT></TD><TD>POKEY&nbsp;</TD><TD><TT>$d20x</TT></TD><TD><TT>$e80x</TT></TD></TR>
<TR><TD><TT>^3x</TT></TD><TD>PIA&nbsp;</TD><TD><TT>$d30x</TT></TD><TD><I>error</I> (there's no PIA chip)</TD></TR>
<TR><TD><TT>^4x</TT></TD><TD>ANTIC&nbsp;</TD><TD><TT>$d40x</TT></TD><TD><TT>$d40x</TT></TD></TR>
</TABLE>
(<TT>x</TT> is a hexadecimal digit).
</BLOCKQUOTE>
<A NAME="new_opcode">
<TABLE>
<TR><TD WIDTH=300><UL><LI> an op-code</TD><TD><TT>{lda #0}</TT></TD></TR>
</UL></TABLE>
<BLOCKQUOTE>
Single-byte op-code of the instruction inside braces (e.g. value of <TT>{nop}</TT> is <TT>$ea</TT>).
Operand is discarded and is necessary only for identifying addressing mode.
Instruction should begin just after the left brace and the right brace should
immediately follow the operand or the command.<BR>
<A NAME="new_op_op">You can skip the operand, if the addressing mode is fixed.
Examples:<BR>
<TT>{lda #}</TT>, <TT>{jsr}</TT>, <TT>{bne}</TT>, <TT>{jmp ()}</TT>,
<TT>{sta a:,x}</TT>.
</BLOCKQUOTE>
<P>
<A NAME="operators"><H4>Operators</H4>
<I>Binary operators:</I><P>
<TABLE>
<TR><TD><TT>+ </TT></TD><TD>Addition</TD></TR>
<TR><TD><TT>- </TT></TD><TD>Subtraction</TD></TR>
<TR><TD><TT>* </TT></TD><TD>Multiplication</TD></TR>
<TR><TD><TT>/ </TT></TD><TD>Division</TD></TR>
<TR><TD><TT>% </TT></TD><TD>Remainder</TD></TR>
<TR><TD><TT>& </TT></TD><TD>Bitwise and</TD></TR>
<TR><TD><TT>| </TT></TD><TD>Bitwise or</TD></TR>
<TR><TD><TT>^ </TT></TD><TD>Bitwise xor</TD></TR>
<TR><TD><TT>&lt;&lt; </TT></TD><TD>Arithmetic shift left</TD></TR>
<TR><TD><TT>&gt;&gt; </TT></TD><TD>Arithmetic shift right</TD></TR>
<TR><TD><TT>= </TT></TD><TD>Equal</TD></TR>
<TR><TD><TT>== </TT></TD><TD>Equal (same as <TT>=</TT>)</TD></TR>
<TR><TD><TT>&lt;&gt; </TT></TD><TD>Not equal</TD></TR>
<TR><TD><TT>!= </TT></TD><TD>Not equal (same as <TT>&lt;&gt;</TT>)</TD></TR>
<TR><TD><TT>&lt; </TT></TD><TD>Less than</TD></TR>
<TR><TD><TT>&gt; </TT></TD><TD>Greater than</TD></TR>
<TR><TD><TT>&lt;= </TT></TD><TD>Less or equal</TD></TR>
<TR><TD><TT>&gt;= </TT></TD><TD>Greater or equal</TD></TR>
<TR><TD><TT>&& </TT></TD><TD>Logical and</TD></TR>
<TR><TD><TT>|| </TT></TD><TD>Logical or</TD></TR>
</TABLE><P>
<A NAME="new_unary">
<I>Unary operators:</I><P>
<TABLE>
<TR><TD><TT>+</TT></TD><TD>Plus (does nothing)</TD></TR>
<TR><TD><TT>-</TT></TD><TD>Minus (changes sign)</TD></TR>
<TR><TD><TT>~</TT></TD><TD>Bitwise not (complements all bits)</TD></TR>
<TR><TD><TT>!</TT></TD><TD>Logical not (changes true to false and vice versa)</TD></TR>
<TR><TD><TT>&lt;</TT></TD><TD>Low (extracts low byte)</TD></TR>
<TR><TD><TT>&gt;</TT></TD><TD>High (extracts high byte)</TD></TR>
</TABLE><P>
<I>Operator precedence:</I><P>
<TABLE>
<TR><TD>first</TD><TD><TT>[]</TT><TD>(brackets)</TD></TR>
<TR><TD> </TD><TD><TT>+ - ~ &lt; &gt;</TT><TD>(unary)</TD></TR>
<TR><TD> </TD><TD><TT>* / % & &lt;&lt; &gt;&gt;</TT><TD>(binary)</TD></TR>
<TR><TD> </TD><TD><TT>+ - | ^</TT><TD>(binary)</TD></TR>
<TR><TD> </TD><TD><TT>= == &lt;&gt; != &lt; &gt; &lt;= &gt;=</TT><TD>(binary)</TD></TR>
<TR><TD> </TD><TD><TT>!</TT><TD>(unary)</TD></TR>
<TR><TD> </TD><TD><TT>&&</TT><TD>(binary)</TD></TR>
<TR><TD>last </TD><TD><TT>||</TT><TD>(binary)</TD></TR>
</TABLE><P>
Note that although the operators are similar to these used in C, C++ and Java,
their priorities are different than in these languages.<P>
Compare and logical operators assume that zero is false and a non-zero is true.
They return 1 for true.<P>
While calculating expression, signed 32-bit arithmetic is used. When range of 32 bits
is exceeded, <TT>'Arithmetic overflow'</TT> error is generated.<P>
<P><HR><P>
<A NAME="directives"><H3>Directives</H3>
<DL>
<DT><TT><B>EQU</B></TT> - assign a value of an expression to the label
<DD>Note that label represents a number, not a text macro.<BR>
Examples:
<PRE>five equ 5
here equ *
</PRE>
<A NAME="new_opt">
<DT><TT><B>OPT</B></TT> - set assembly options
<DD>Five options are available:
<UL>
<LI> <TT>F</TT> - fill space between <TT>ORG</TT>s
(details <A HREF="#org_fill">here</A>)
<LI> <TT>G</TT> - Atari 5200 mode for hardware register abbreviations
(details <A HREF="#numbers">here</A>)
<LI> <TT>H</TT> - generate Atari executable headers
<LI> <TT>L</TT> - generate listing
<LI> <TT>O</TT> - generate object file
</UL>
You can turn any of these on or off.<BR>
Default (if no <TT>OPT</TT> specified) is <TT>opt f-g-h+l+o+</TT>.<BR>
Examples:
<PRE> opt l- listing off
opt l+o- listing on, object file off
opt f+g+h- useful for Atari 5200 cartridges - raw output format, 5200 hw regs
</PRE>
<A NAME="org_fill">
<DT><TT><B>ORG</B></TT> - change value of the origin counter
<DD>
<!-- Option '<TT>F</TT> affects all <TT>ORG</TT> directives except for the first one. -->
You can set some options applied to the new header (if headers are
enabled):
<UL>
<LI> <TT>a:</TT> tells X-Asm to always make a header, even it is unnecessary,
like in <TT>ORG *</TT>.
<LI> <TT>f:</TT> works same as <TT>a:</TT>, but additionally tells to generate
a $ff,$ff prefix before the header. X-Asm adds it at the beginning of the file
by default, so use this option only if you want the $ff's somewhere inside.<BR>
</UL>
Examples:
<PRE> org $600
org f:$700
table org *+100
</PRE>
In the latter example <TT>table</TT> points to 100 bytes
of uninitialized data (label is assigned to <TT>*</TT>
before <TT>ORG</TT> directive is executed).<P>
<A NAME="new_dta">
<DT><TT><B>DTA</B></TT> - define data
<DD>There are various data types:
<UL>
<LI> integers
<UL>
<LI> bytes: <TT>b(200)</TT> or simply <TT>200</TT>
<LI> words: <TT>a(10000)</TT>
<LI> low bytes of words: <TT>l(511)</TT> defines byte 255
<LI> high bytes of words: <TT>h(511)</TT> defines byte 1
</UL>
You may enter many expressions in parentheses and combine different types
of data in single line, separating things with commas.<BR>
You may also define a sine lookup table. Syntax is:<BR>
<TT>sin(centre,amp,size,first,last)</TT><BR>
where:
<UL>
<LI> <TT>centre</TT> is a number which is added to every sine value
<LI> <TT>amp</TT> is the sine amplitude
<LI> <TT>size</TT> is the sine period
<LI> <TT>first,last</TT> define range of values in the table.
They are optional. Default are <TT>0,size-1</TT>.
</UL>
Example: <TT>dta a(sin(0,1000,256,0,63))</TT> defines table of 64 words
representing a quarter of sine with amplitude of 1000.<P>
<LI> real numbers: <TT>r(-1.23456e12)</TT><BR>
Real numbers are written in 6-byte Atari Floating-Point format. You can't
combine reals with operators, as you can integers.<P>
<LI> text strings
<UL>
<LI> ASCII strings: <TT>c'Text'</TT> or <TT>c"Text"</TT>
<LI> ANTIC strings: <TT>d'Text'</TT> or <TT>d"Text"</TT>
</UL>
A character string consists of any of characters surrounded by quotation
marks. Within a string, a single quotation mark character is
represented by two succesive quotation marks.<BR>
Placing a <TT>*</TT> character after a string inverts
high bit in every byte of string.<P>
</UL>
Examples of <TT>DTA</TT>:
<PRE>
dta b(1,2),3,a(1000,-1),l(12345,sin(0,127,256))
dta d"ANTIC"*,c'It''s a string',$9b
</PRE>
<DT><TT><B>ICL</B></TT> - include another source file
<DD>Specifies another file to be included in the assembly as if the contents of
the referenced file appeared in place of the <TT>ICL</TT> statement.
The included file may contain other <TT>ICL</TT> statements.
The <TT>.ASX</TT> extension is added if none given.<P>
Examples:
<PRE>
icl 'macros.asx'
icl 'c:\atari\xasm\fileio'
</PRE>
<DT><TT><B>END</B></TT> - end assembling file
<DD>Remaining part of the file is not assembled. If this statement does
not occur, assembler stops assembling when encounters end of file.<BR>
Example:
<PRE>
end
</PRE>
<DT><TT><B>INS</B></TT> - insert contents of file
<DD>Copies every byte of specified file into the object file and updates
the origin counter, as if these bytes were defined with <TT>DTA</TT>.<BR>
You may specify range of inserted file. Syntax is following:
<PRE>
ins 'file'[,offset[,length]]
</PRE>
First byte in file has offset 0.<BR>
If offset is negative, it is counted from the end of file.<BR>
Examples:
<PRE>
ins 'picture.raw'
ins 'file',-256 insert last 256 bytes of file
ins 'file',10,10 insert bytes 10..19 of file
</PRE>
<DT><TT><B>RUN</B></TT> - generate run address
<DD>The Atari executable program should have a run address specified.
A program may be loaded in many areas of memory and started from any address.
<PRE> run addr
</PRE>
is equivalent to:
<PRE> org $2e0
dta a(addr)
</PRE>
Examples:
<PRE> run start
run main
</PRE>
<DT><TT><B>INI</B></TT> - generate init address
<DD>The Atari executable program may have some routines which are executed
during loading process. There may be many init blocks in one file.<BR>
Examples:
<PRE> ini init
ini showpic
</PRE>
<DT><TT><B>ERT</B></TT> - generate error if expression is true
<DD>Examples:
<PRE> ert *&gt;$c000
ert len1&gt;$ff||len2&gt;$ff
</PRE>
<A NAME="new_eli">
<DT><TT><B>IFT</B></TT> - assemble if expression is true<BR>
<TT><B>ELI</B></TT> - else if<BR>
<TT><B>ELS</B></TT> - else<BR>
<TT><B>EIF</B></TT> - end if<BR>
<DD>With these directives you can construct fragments which
are assembled when a condition is met.
Conditional constructions can be nested.<BR>
Example:
<PRE>noscr equ 1
widescr equ 1
ift noscr
lda #0
eli widescr
lda #$23
els
lda #$22
eif
sta $22f
</PRE>
Above example can be rewritten using line repeating feature:
<PRE>noscr equ 1
widescr equ 1
:noscr lda #0
:!noscr&amp;&amp;widescr lda #$23
:!noscr&amp;&amp;!widescr lda #$22
sta $22f
</PRE>
</DL>
<HR>
<A NAME="pseudocom"><H3>Pseudo-commands</H3>
Pseudo-commands are built-in macros.
They are not unofficial instructions, so they work on typical 6502.<P>
<DL>
<DT><TT><B>ADD</B></TT> - addition without carry
<DD>If you have ever programmed 6502, you must have noticed that you had
to use a <TT>CLC</TT> before <TT>ADC</TT> for every simple addition.<BR>
X-Asm can do it for you. <TT>ADD</TT> replaces two instructions:
<TT>CLC</TT> and <TT>ADC</TT>.<P>
<DT><TT><B>SUB</B></TT> - subtraction
<DD>It is <TT>SEC</TT> and <TT>SBC</TT>.<P>
<A NAME="new_repskip">
<DT><TT><B>RCC, RCS, REQ, RMI, RNE, RPL, RVC, RVS</B></TT> - conditional repeat
<DD>These are branches to the previous instruction.
They take no operand, because the branch target
is the address of previously assembled instruction.<BR>
Example:
<PRE> ldx #0
mva:rne $500,x $600,x+
</PRE>
The example code copies memory $500-$5ff to $600-$6ff.
Here is the same written with standard 6502 commands only:
<PRE> ldx #0
loop lda $500,x
sta $600,x
inx
bne loop
</PRE>
<DT><TT><B>SCC, SCS, SEQ, SMI, SNE, SPL, SVC, SVS</B></TT> - conditional skip
<DD>These are branches over the next instructions. No operand is required,
because the target is the address of instruction following
the next instruction.<BR>
Example:
<PRE> lda #40
add:sta $80
scc:inc $81
</PRE>
In the above example word-size variable $80 is incremented by 40.<BR>
Nor conditional repeat nor skip pseudo-commands require operand,
thus they can be paired with any other command.<P>
<DT><TT><B>JCC, JCS, JEQ, JMI, JNE, JPL, JVC, JVS</B></TT> - conditional jumps
<DD>These are a kind of 'long' branches. While standard branches
(<TT>BNE, BEQ</TT>) have range of -128..+127, these jumps have range
of all 64 kB.<BR>
Example:
<PRE> jne dest
</PRE>is equivalent to:
<PRE> seq:jmp dest
</PRE>
<DT><TT><B>INW</B></TT> - increment word
<DD>Increments a 16-bit word in the memory.<BR>
Example:
<PRE> inw dest
</PRE>is equivalent to:
<PRE> inc dest
sne:inc dest+1
</PRE>
<DT><TT><B>MVA, MVX, MVY</B></TT> - move byte using accumulator, X or Y
<DD>Each of these pseudo-commands requires two operands
and substitutes two commands:
<PRE> mva source dest = lda source : sta dest
mvx source dest = ldx source : stx dest
mvy source dest = ldy source : sty dest
</PRE>
<A NAME="new_mwinde">
<DT><TT><B>MWA, MWX, MWY</B></TT> - move word using accumulator, X or Y
<DD>These pseudo-commands require two operands
and are combinations of two <TT>MV*</TT>'s:
one to move low byte, and the other to move high byte.<BR>
You can't use indirect nor pseudo addressing mode with <TT>MW*</TT>.
Destination must be absolute address (optionally indexed).<BR>
When source is also absolute, a <TT>mw* source dest</TT> will be:
<PRE> mv* source dest
mv* source+1 dest+1
</PRE>
When source is an immediate, a <TT>mw* #immed dest</TT> will be:
<PRE> mv* &lt;immed dest
mv* &gt;immed dest+1
</PRE>
When <TT>&lt;immed</TT> equals <TT>&gt;immed</TT> and <TT>immed</TT>
is not forward-referenced, X-Asm uses optimization:
<PRE> mv* &lt;immed dest
st* dest+1
</PRE>
If possible, <TT>MWX</TT> and <TT>MWY</TT> use increment/decrement
commands. E.g. <TT>mwx #1 dest</TT> is assembled as:
<PRE> mvx #1 dest
dex
stx dest+1
</DL>
</OL>
<HR>
<A NAME="adrmod"><H3>Addressing modes</H3>
All addressing modes are entered in standard convention except
the accumulator addressing mode, which should be marked with a
<TT>@</TT> character (as in Quick Assembler).<P>
There are two extra immediate addressing modes:
<TT>&lt;</TT> and <TT>&gt;</TT>,
which use low/high byte of 16-bit word constant.
They are for Quick Assembler compatibility.
You can use traditional <TT>#&lt;</TT> and <TT>#&gt;</TT>.
Note <NOBR><TT>lda &gt;$ff+5</TT></NOBR> loads 1 (<TT>&gt;$104</TT>),
while <NOBR><TT>lda #&gt;$ff+5</TT></NOBR>
loads 5 (<TT>0+5</TT>) to accumulator, because unary operator <TT>&gt;</TT>
has higher priority than the binary plus.<P>
In absolute addressing modes, X-Asm examines the expression and uses zero-page
addressing mode if it supposes it's possible. You may override it with
<TT>a:</TT> and <TT>z:</TT> prefixes.<P>
Examples:
<PRE>
nop
asl @
lda &gt;$1234 assembles to lda #$12
lda $100,x
lda a:0 generates 16-bit address
jmp ($0a)
lda ($80),y
</PRE>
There are also pseudo addressing modes, which are similar to
pseudo-commands. You may use them just like standard addressing modes
in all 6502 commands and pseudo-commands, except for
<TT>MWA</TT>, <TT>MWX</TT> and <TT>MWY</TT>:
<PRE> cmd a,x+ = cmd a,x : inx
cmd a,x- = cmd a,x : dex
cmd a,y+ = cmd a,y : iny
cmd a,y- = cmd a,y : dey
cmd (z),y+ = cmd (z),y : iny
cmd (z),y- = cmd (z),y : dey
cmd (z,0) = ldx #0 : cmd (z,x)
cmd (z),0 = ldy #0 : cmd (z),y
<A NAME="new_adrmodes"> cmd (z),0+ = ldy #0 : cmd (z),y : iny
cmd (z),0- = ldy #0 : cmd (z),y : dey
</PRE>
<HR>
<A NAME="faq"><H2>FAQ</H2>
<B>Note:</B> All the following things, which may be odd for you,
are familiar to Quick Assembler users.
<UL>
<LI><B>Q:</B> Why does X-Asm ignore <TT>+2</TT> in the following line?
<PRE>label equ 1 +2
</PRE>
<B>A:</B> X-Asm treats space as operand terminator. Remaining part of line
is a comment. You should write <TT>1+2</TT> without any spaces.<P>
<LI><B>Q:</B> Why does <TT>lda &gt;$abcd</TT> assemble to
<TT>lda #$ab</TT>?<P>
<B>A:</B> <TT>&lt;</TT> and <TT>&gt;</TT> are not only 'low' and 'high'
operators, but also 'low of immediate' and 'high of immediate'
addressing modes indicators.
In order to get <TT>lda $ab</TT>, write <TT>lda +&gt;$abcd</TT><P>
<LI><B>Q:</B> What's wrong with <TT>asl a</TT> or just <TT>asl</TT> ?<P>
<B>A:</B> You must use <TT>@</TT> for accumulator addressing mode.<P>
<LI><B>Q:</B> What's wrong in following line?
<PRE>label: lda #0
</PRE>
<B>A:</B> Label definition can not include a colon.<P>
<LI><B>Q:</B> I wrote <TT>end start</TT>, where <TT>start</TT> points
to program beginning, but program seems not to start there. Why?<P>
<B>A:</B> You should have explicit run address specified.
Use <TT>run start</TT> directive. <TT>end</TT> takes no operand.<P>
<LI><B>Q:</B> Why this construction does not work:
<PRE>three equ one+two
two equ one+one
one equ 1
</PRE>
while this does:
<PRE>
two equ one+one
one equ 1
</PRE>
<B>A:</B> X-Asm reads source twice (in pass 1 and pass 2)
from the beginning until the end.<BR>
This allows forward references, but not too complex.<BR>
Keep in mind that the assembler must know all the values in the second
pass.<P>
Example:
<PRE>two equ one+one This value is known in 2nd pass only
one equ 1 This value is known as early as in 1st pass
</PRE>
These values can be fixed in two passes.<BR>
If you insert following statement as first line:
<PRE>three equ one+two
</PRE>
X-Asm will generate an error because it can't fix
the value of <TT>three</TT> in second pass.<P>
<LI><B>Q:</B> X-Asm displayed single error while assembling my program.
When I fixed it, another error appeared. Why?<P>
<B>A:</B> X-Asm displays only first error.<BR>
When you were assembling for the first time, both errors might exist,
but X-Asm stopped on the first one.<P>
</UL>
If you have other questions/problems,
<A HREF=mailto:fox@scene.pl>contact me</A>.
<P><HR><P><A HREF="index.htm">Back</A>
</BODY></HTML>