mirror of
https://github.com/pfusik/xasm.git
synced 2024-12-13 00:29:33 +00:00
xasm 3.0.2 release.
This commit is contained in:
parent
fa25272ccd
commit
034b95ea83
53
Makefile
Normal file
53
Makefile
Normal file
@ -0,0 +1,53 @@
|
||||
VERSION = 3.0.2
|
||||
|
||||
ASCIIDOC = asciidoc -o $@ -a doctime
|
||||
ASCIIDOC_POSTPROCESS = perl -pi.bak -e "s/527bbd;/20a0a0;/;END{unlink '$@.bak'}" $@
|
||||
ASCIIDOC_VALIDATE = xmllint --valid --noout --nonet $@
|
||||
RM = rm -f
|
||||
ZIP = 7z a -mx=9 -tzip $@
|
||||
|
||||
all: xasm.exe xasm.html
|
||||
|
||||
xasm.exe: xasm.d
|
||||
dmd -O -release $<
|
||||
|
||||
xasm.html: xasm.1.txt
|
||||
$(ASCIIDOC) -d manpage $<
|
||||
$(ASCIIDOC_POSTPROCESS)
|
||||
$(ASCIIDOC_VALIDATE)
|
||||
|
||||
dist: xasmpage-$(VERSION).zip
|
||||
|
||||
xasmpage-$(VERSION).zip: xasm261.zip xasm-$(VERSION)-src.zip xasm-$(VERSION)-windows.zip inflate6502.zip index.html inflate.html scite.png
|
||||
$(RM) $@
|
||||
$(ZIP) $^
|
||||
|
||||
xasm-$(VERSION)-src.zip: xasm.d Makefile xasm.1.txt
|
||||
$(RM) $@
|
||||
$(ZIP) $^
|
||||
|
||||
xasm-$(VERSION)-windows.zip: xasm.exe xasm.html xasm.properties
|
||||
$(RM) $@
|
||||
$(ZIP) $^
|
||||
|
||||
inflate6502.zip: inflate.asx gzip2deflate.c gzip2deflate.exe
|
||||
$(RM) $@
|
||||
$(ZIP) $^
|
||||
|
||||
gzip2deflate.exe: gzip2deflate.c
|
||||
mingw32-gcc -s -O2 -Wall -o $@ $<
|
||||
|
||||
index.html: index.txt
|
||||
$(ASCIIDOC) $<
|
||||
$(ASCIIDOC_POSTPROCESS)
|
||||
$(ASCIIDOC_VALIDATE)
|
||||
|
||||
inflate.html: inflate.txt
|
||||
$(ASCIIDOC) $<
|
||||
$(ASCIIDOC_POSTPROCESS)
|
||||
$(ASCIIDOC_VALIDATE)
|
||||
|
||||
clean:
|
||||
$(RM) xasmpage-$(VERSION).zip xasm-$(VERSION)-src.zip xasm-$(VERSION)-windows.zip xasm.exe xasm.html inflate6502.zip gzip2deflate.exe index.html inflate.html
|
||||
|
||||
.DELETE_ON_ERROR:
|
117
artistic.txt
117
artistic.txt
@ -1,117 +0,0 @@
|
||||
|
||||
|
||||
|
||||
|
||||
The "Artistic License"
|
||||
|
||||
Preamble
|
||||
|
||||
The intent of this document is to state the conditions under which a
|
||||
Package may be copied, such that the Copyright Holder maintains some
|
||||
semblance of artistic control over the development of the package,
|
||||
while giving the users of the package the right to use and distribute
|
||||
the Package in a more-or-less customary fashion, plus the right to make
|
||||
reasonable modifications.
|
||||
|
||||
Definitions:
|
||||
|
||||
"Package" refers to the collection of files distributed by the
|
||||
Copyright Holder, and derivatives of that collection of files
|
||||
created through textual modification.
|
||||
|
||||
"Standard Version" refers to such a Package if it has not been
|
||||
modified, or has been modified in accordance with the wishes
|
||||
of the Copyright Holder as specified below.
|
||||
|
||||
"Copyright Holder" is whoever is named in the copyright or
|
||||
copyrights for the package.
|
||||
|
||||
"You" is you, if you're thinking about copying or distributing
|
||||
this Package.
|
||||
|
||||
"Reasonable copying fee" is whatever you can justify on the
|
||||
basis of media cost, duplication charges, time of people involved,
|
||||
and so on. (You will not be required to justify it to the
|
||||
Copyright Holder, but only to the computing community at large
|
||||
as a market that must bear the fee.)
|
||||
|
||||
"Freely Available" means that no fee is charged for the item
|
||||
itself, though there may be fees involved in handling the item.
|
||||
It also means that recipients of the item may redistribute it
|
||||
under the same conditions they received it.
|
||||
|
||||
1. You may make and give away verbatim copies of the source form of the
|
||||
Standard Version of this Package without restriction, provided that you
|
||||
duplicate all of the original copyright notices and associated disclaimers.
|
||||
|
||||
2. You may apply bug fixes, portability fixes and other modifications
|
||||
derived from the Public Domain or from the Copyright Holder. A Package
|
||||
modified in such a way shall still be considered the Standard Version.
|
||||
|
||||
3. You may otherwise modify your copy of this Package in any way, provided
|
||||
that you insert a prominent notice in each changed file stating how and
|
||||
when you changed that file, and provided that you do at least ONE of the
|
||||
following:
|
||||
|
||||
a) place your modifications in the Public Domain or otherwise make them
|
||||
Freely Available, such as by posting said modifications to Usenet or
|
||||
an equivalent medium, or placing the modifications on a major archive
|
||||
site such as uunet.uu.net, or by allowing the Copyright Holder to include
|
||||
your modifications in the Standard Version of the Package.
|
||||
|
||||
b) use the modified Package only within your corporation or organization.
|
||||
|
||||
c) rename any non-standard executables so the names do not conflict
|
||||
with standard executables, which must also be provided, and provide
|
||||
a separate manual page for each non-standard executable that clearly
|
||||
documents how it differs from the Standard Version.
|
||||
|
||||
d) make other distribution arrangements with the Copyright Holder.
|
||||
|
||||
4. You may distribute the programs of this Package in object code or
|
||||
executable form, provided that you do at least ONE of the following:
|
||||
|
||||
a) distribute a Standard Version of the executables and library files,
|
||||
together with instructions (in the manual page or equivalent) on where
|
||||
to get the Standard Version.
|
||||
|
||||
b) accompany the distribution with the machine-readable source of
|
||||
the Package with your modifications.
|
||||
|
||||
c) give non-standard executables non-standard names, and clearly
|
||||
document the differences in manual pages (or equivalent), together
|
||||
with instructions on where to get the Standard Version.
|
||||
|
||||
d) make other distribution arrangements with the Copyright Holder.
|
||||
|
||||
5. You may charge a reasonable copying fee for any distribution of this
|
||||
Package. You may charge any fee you choose for support of this
|
||||
Package. You may not charge a fee for this Package itself. However,
|
||||
you may distribute this Package in aggregate with other (possibly
|
||||
commercial) programs as part of a larger (possibly commercial) software
|
||||
distribution provided that you do not advertise this Package as a
|
||||
product of your own. You may embed this Package's interpreter within
|
||||
an executable of yours (by linking); this shall be construed as a mere
|
||||
form of aggregation, provided that the complete Standard Version of the
|
||||
interpreter is so embedded.
|
||||
|
||||
6. The source code and object code supplied as input to or produced as
|
||||
output from the programs of this Package do not automatically fall
|
||||
under the copyright of this Package, but belong to whoever generated
|
||||
them, and may be sold commercially, and may be aggregated with this
|
||||
Package.
|
||||
|
||||
7. Aggregation of this Package with a commercial distribution is always
|
||||
permitted provided that the use of this Package is embedded; that is,
|
||||
when no overt attempt is made to make this Package's interfaces visible
|
||||
to the end user of the commercial distribution. Such use shall not be
|
||||
construed as a distribution of this Package.
|
||||
|
||||
8. The name of the Copyright Holder may not be used to endorse or promote
|
||||
products derived from this software without specific prior written permission.
|
||||
|
||||
9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
The End
|
105
www/index.html
105
www/index.html
@ -1,105 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
||||
<head>
|
||||
<title>xasm</title>
|
||||
<meta name="Description" content="xasm is a 6502 cross-assembler for Windows and Linux." />
|
||||
<meta name="Keywords" content="xasm,6502,cross-assembler,atari,8-bit" />
|
||||
<meta name="Author" content="Piotr Fusik" />
|
||||
<style type="text/css">
|
||||
body { background-color: #f8f8f8; color: black; font-family: sans-serif; }
|
||||
h1 { color: #20a0a0; border-bottom: solid 3px #d0d0d0; }
|
||||
h2 { color: #20a0a0; border-bottom: solid 2px #d0d0d0; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>xasm - 6502 cross-assembler</h1>
|
||||
<p>xasm is a free tool for programming old 8-bit computers based on the 6502 processor.</p>
|
||||
<h2>History</h2>
|
||||
<p>First version of xasm was written in 1998. I needed a cross-assembler
|
||||
that could understand the syntax of Quick Assembler
|
||||
which I used for 8-bit Atari programming before I got a PC.
|
||||
Initially xasm supported the syntax of QA and nothing more.
|
||||
I quickly realized that I could extend the syntax to make it more expressive.
|
||||
This led to xasm 2.0, still in 1998. I added some more features
|
||||
next year. In 2002 I released many versions which contained
|
||||
mostly bugfixes. In 2005 there were some minor enhancements and bug fixes,
|
||||
as well as the whole assembler was rewritten from the x86 assembly language
|
||||
it was initially written in to the
|
||||
<a href="http://www.digitalmars.com/d">D programming language</a>.
|
||||
The rewrite introduced a bug, hopefully fixed in version 3.0.1
|
||||
released 22nd April 2007.</p>
|
||||
<h2>Syntax</h2>
|
||||
<p>6502 assembler code is usually full of LDA, STA, LDA, STA sequences.
|
||||
With xasm you can use MVA as a shortcut for LDA/STA pair
|
||||
or even MWA for 16-bit transfers. You can avoid defining labels
|
||||
when you need short jumps, thanks to conditional skip
|
||||
and repeat pseudo-instructions. You can put two instructions
|
||||
that share their argument in one line.
|
||||
These are just some of the features that help you program
|
||||
in a more concise way. Let's look at typical 6502 code
|
||||
(which is valid in xasm):</p>
|
||||
<pre>
|
||||
lda #<dest
|
||||
sta ptr
|
||||
lda #>dest
|
||||
sta ptr+1
|
||||
ldx #192
|
||||
do_line
|
||||
ldy #39
|
||||
do_byte
|
||||
lda pattern,y
|
||||
sta (ptr),y
|
||||
dey
|
||||
bpl do_byte
|
||||
lda #40
|
||||
clc
|
||||
adc ptr
|
||||
sta ptr
|
||||
bcc skip
|
||||
inc ptr+1
|
||||
skip
|
||||
dex
|
||||
bne do_line
|
||||
</pre>
|
||||
<p>Using xasm features this code can be rewritten to:</p>
|
||||
<pre>
|
||||
mwa #dest ptr
|
||||
ldx #192
|
||||
do_line
|
||||
ldy #39
|
||||
mva:rpl pattern,y (ptr),y-
|
||||
lda #40
|
||||
add:sta ptr
|
||||
scc:inc ptr+1
|
||||
dex:bne do_line
|
||||
</pre>
|
||||
<h2>Usage</h2>
|
||||
<p>xasm is a command-line tool so you additionally need a general-purpose text editor.
|
||||
I use <a href="http://www.scintilla.org/SciTE.html">SciTE</a>.
|
||||
Syntax highlighting definition for it is included with xasm.
|
||||
To install it, copy <em>xasm.properties</em> to the SciTE directory,
|
||||
select <em>Options / Open Global Options File</em>, type <kbd>import xasm</kbd>
|
||||
at the end and save the global configuration file.</p>
|
||||
<p><img src="scite.png" alt="xasm code in SciTE" /></p>
|
||||
<h2>Download</h2>
|
||||
<ul>
|
||||
<li><a href="xasm-3.0.1-win32.zip">xasm 3.0.1 for Windows</a></li>
|
||||
<li><a href="xasm-3.0.1-src.zip">xasm 3.0.1 source code</a></li>
|
||||
<li><a href="xasm261.zip">xasm 2.6.1 for DOS/Windows</a></li>
|
||||
</ul>
|
||||
<p>For other systems, such as GNU/Linux and MacOS X, install the latest D compiler
|
||||
and compile xasm from source code.</p>
|
||||
<h2>Inflate</h2>
|
||||
<p>Need a good decompression routine for 6502?
|
||||
See my <a href="inflate.html">inflate routine</a>.</p>
|
||||
<h2>Links</h2>
|
||||
<ul>
|
||||
<li><a href="http://atari800.sourceforge.net/">Atari800 emulator</a></li>
|
||||
<li><a href="http://sources.pigwa.net/">Atari XL/XE Source Archive</a></li>
|
||||
<li><a href="http://www.cc65.org/">cc65 cross-compiler</a></li>
|
||||
<li><a href="http://epi.atari8.info/hcasm.php">HardCore Assembler</a></li>
|
||||
<li><a href="http://mads.atari8.info/">Mad-Assembler</a></li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
112
www/index.txt
Normal file
112
www/index.txt
Normal file
@ -0,0 +1,112 @@
|
||||
xasm - 6502 cross-assembler
|
||||
===========================
|
||||
|
||||
xasm is a free tool for programming
|
||||
http://en.wikipedia.org/wiki/Atari_8-bit_family[Atari 8-bit family computers].
|
||||
|
||||
History
|
||||
-------
|
||||
|
||||
First version of xasm was written in 1998. I needed a cross-assembler
|
||||
that could understand the syntax of Quick Assembler
|
||||
which I used for 8-bit Atari programming before I got a PC.
|
||||
Initially xasm supported the syntax of QA and nothing more.
|
||||
I quickly realized that I could extend the syntax to make it more expressive.
|
||||
This led to xasm 2.0, still in 1998. I added some more features
|
||||
next year. In 2002 I released many versions which contained
|
||||
mostly bugfixes. In 2005 there were some minor enhancements and bug fixes,
|
||||
as well as the whole assembler was rewritten from the x86 assembly language
|
||||
it was initially written in to the http://www.digitalmars.com/d/[D programming language].
|
||||
Current version 3.0.2 was released 17th October 2009.
|
||||
|
||||
Syntax
|
||||
------
|
||||
|
||||
6502 assembler code is usually full of LDA, STA, LDA, STA sequences.
|
||||
With xasm you can use MVA as a shortcut for LDA/STA pair
|
||||
or even MWA for 16-bit transfers. You can avoid defining labels
|
||||
when you need short jumps, thanks to conditional skip
|
||||
and repeat pseudo-instructions. You can put two instructions
|
||||
that share their argument in one line.
|
||||
These are just some of the features that help you program
|
||||
in a more concise way. Let's look at typical 6502 code
|
||||
(which is also valid in xasm):
|
||||
|
||||
-----------------------------
|
||||
lda #<dest
|
||||
sta ptr
|
||||
lda #>dest
|
||||
sta ptr+1
|
||||
ldx #192
|
||||
do_line
|
||||
ldy #39
|
||||
do_byte
|
||||
lda pattern,y
|
||||
sta (ptr),y
|
||||
dey
|
||||
bpl do_byte
|
||||
lda #40
|
||||
clc
|
||||
adc ptr
|
||||
sta ptr
|
||||
bcc skip
|
||||
inc ptr+1
|
||||
skip
|
||||
dex
|
||||
bne do_line
|
||||
-----------------------------
|
||||
|
||||
Using xasm's features this code can be rewritten to:
|
||||
|
||||
-----------------------------
|
||||
mwa #dest ptr
|
||||
ldx #192
|
||||
do_line
|
||||
ldy #39
|
||||
mva:rpl pattern,y (ptr),y-
|
||||
lda #40
|
||||
add:sta ptr
|
||||
scc:inc ptr+1
|
||||
dex:bne do_line
|
||||
-----------------------------
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
xasm is a command-line tool.
|
||||
Therefore you additionally need a programmer's text editor.
|
||||
|
||||
I use http://www.scintilla.org/SciTE.html[SciTE].
|
||||
Syntax highlighting definition for it is included with xasm.
|
||||
To install it, copy `xasm.properties` to the SciTE directory,
|
||||
select _Options / Open Global Options File_, type `import xasm`
|
||||
at the end and save the global configuration file.
|
||||
|
||||
image::scite.png[xasm code in SciTE]
|
||||
|
||||
Download
|
||||
--------
|
||||
|
||||
- link:xasm-3.0.2-windows.zip[xasm 3.0.2 for Windows]
|
||||
- link:xasm-3.0.2-src.zip[xasm 3.0.2 source code]
|
||||
- link:xasm261.zip[xasm 2.6.1 for DOS]
|
||||
|
||||
For other systems, such as GNU/Linux and MacOS X, install a D 1.x compiler
|
||||
and compile xasm from source code.
|
||||
|
||||
Inflate
|
||||
-------
|
||||
|
||||
Do you need a good decompression routine for 6502?
|
||||
See my link:inflate.html[inflate routine].
|
||||
|
||||
Links
|
||||
-----
|
||||
|
||||
- http://atari800.sourceforge.net/[Atari800 emulator] - portable emulator of Atari 8-bit computers
|
||||
- http://sources.pigwa.net/[Atari XL/XE Source Archive] - source code of Atari demos, utilities and games
|
||||
- http://www.cc65.org/[cc65] - C cross-compiler targeting 6502-based systems
|
||||
- http://epi.atari8.info/hcasm.php[HardCore Assembler] - 6502/65816 cross-assembler, partially supporting xasm's syntax
|
||||
- http://mads.atari8.info/[MADS] - another 6502/65816 cross-assembler, partially supporting xasm's syntax
|
||||
- http://wudsn.com/[WUDSN IDE] - Eclipse plugin, front-end to several 6502 cross-assemblers including xasm
|
825
xasm.1.txt
Normal file
825
xasm.1.txt
Normal file
@ -0,0 +1,825 @@
|
||||
XASM (1)
|
||||
========
|
||||
Piotr Fusik <fox@scene.pl>
|
||||
|
||||
NAME
|
||||
----
|
||||
xasm - 6502 cross-assembler
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
*xasm* '[OPTIONS] SOURCE_FILE'
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
*xasm* is a cross-assembler for the 6502 family processors.
|
||||
|
||||
'SOURCE_FILE' is the name of the source file
|
||||
(you may omit the default `.asx` extension).
|
||||
When invoked without any options, *xasm* assembles 'SOURCE_FILE'
|
||||
and writes the result to an object file named 'SOURCE_FILE'
|
||||
with the extension changed to `.obx`.
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
|
||||
*/c*::
|
||||
Specifies that lines skipped due to a false condition
|
||||
should be included in the listing file.
|
||||
|
||||
[[new_deflabel]]*/d:*'LABEL'='VALUE'::
|
||||
Defines a label.
|
||||
'LABEL' should be a valid label name.
|
||||
'VALUE' may be any expression (may reference to labels defined in source files).
|
||||
You may use several */d* options to define many labels from the command line.
|
||||
|
||||
*/i*::
|
||||
Excludes included files from the listing file.
|
||||
|
||||
*/l*'[:LISTING_FILE]'::
|
||||
Generates listing file.
|
||||
If 'LISTING_FILE' is omitted, the listing filename
|
||||
is 'SOURCE_FILE' with the extension changed to `.lst`.
|
||||
|
||||
[[new_makefile]]*/M*::
|
||||
Prints a rule for use in a `Makefile`.
|
||||
First line of the rule lists 'OBJECT_FILE' as the target of the rule
|
||||
and all source files (including the ones specified by `icl` and `ins` directives)
|
||||
as dependencies. The second line contains the command line with `OBJECT_FILE`
|
||||
replaced by the *make* macro `$@` and `SOURCE_FILE` replaced by the macro `$<`.
|
||||
Dollars in the command line are doubled.
|
||||
Your `make` or shell may require more escaping.
|
||||
|
||||
*/o*':OBJECT_FILE'::
|
||||
Sets output file name.
|
||||
The default is 'SOURCE_FILE' with the extension changed to `.obx`.
|
||||
|
||||
[[new_fullpaths]]*/p*::
|
||||
Prints fully qualified file names in listing and error messages.
|
||||
This option works only on Windows and is silently ignored on other platforms.
|
||||
|
||||
[[new_quiet]]*/q*::
|
||||
Quiet mode. Prevents *xasm* from printing the logo and the summary.
|
||||
|
||||
*/t*'[:LABEL_FILE]'::
|
||||
Generates label table.
|
||||
If 'LABEL_FILE' is omitted then the table is appended to the listing.
|
||||
|
||||
[[new_unlabels]]*/u*::
|
||||
Issues a warning message for each label whose value is unused.
|
||||
|
||||
Alternatively, you may use Unix-style options, for example:
|
||||
|
||||
-----------------------------------------------------------
|
||||
xasm -i -d DEBUG=1 -l listing.lst source.asx
|
||||
-----------------------------------------------------------
|
||||
|
||||
SYNTAX
|
||||
------
|
||||
|
||||
Source files should be plain ASCII files.
|
||||
LF, CR, CR/LF and Atari ($9b) line terminators are supported.
|
||||
Labels and instructions are case-insensitive.
|
||||
|
||||
*xasm* is backward compatible with Quick Assembler.
|
||||
To compile QA sources with *xasm*, simply replace ATASCII-specific characters
|
||||
with their integer codes. You also have to update all `OPT` directives,
|
||||
but usually you can simply remove them.
|
||||
|
||||
'Label' is a symbol that represents a signed 32-bit integer.
|
||||
You define a label by putting its name at the beginning of a line
|
||||
(with no spaces before).
|
||||
The label will be assigned the current value of the 'origin counter'
|
||||
(i.e. the address of the compiled instruction),
|
||||
unless you use it with the `EQU` directive where it is assigned
|
||||
the value of the argument.
|
||||
|
||||
Instructions and directives must be preceded with some whitespace.
|
||||
Without leading whitespace they are treated as label names.
|
||||
For example:
|
||||
----
|
||||
nop
|
||||
----
|
||||
is a 6502 instruction, whereas
|
||||
----
|
||||
nop
|
||||
----
|
||||
defines a label called `nop`.
|
||||
|
||||
Whole-line comments must start with a semicolon, an asterisk or a pipe,
|
||||
with optional label definition and spaces before.
|
||||
Here are examples of whole-line comments:
|
||||
--------------------
|
||||
; this is a comment
|
||||
* so it is
|
||||
label | and this too
|
||||
--------------------
|
||||
|
||||
[[new_linerep]]
|
||||
Lines with instructions (and selected directives) may be 'repeated'.
|
||||
To assemble a single line several times,
|
||||
precede the repeat count with a colon, for example:
|
||||
-----------------
|
||||
:4 asl @
|
||||
table :32*5 dta 5
|
||||
-----------------
|
||||
|
||||
In lines with instructions or directives, a comment starts immediately
|
||||
after the instruction/directive has been successfully parsed.
|
||||
That is, in these lines *xasm* does not require a special character
|
||||
to start a comment.
|
||||
-------------------------------------------------------------
|
||||
lda foo ; this is a comment
|
||||
sta bar this too
|
||||
tax #0 tax has no operand, therefore #0 starts this comment
|
||||
-------------------------------------------------------------
|
||||
|
||||
[[new_pairing]]
|
||||
You may put two instructions in one line so they share the operand.
|
||||
For example:
|
||||
------------
|
||||
eor:sta foo
|
||||
------------
|
||||
is equivalent to
|
||||
------------
|
||||
eor foo
|
||||
sta foo
|
||||
------------
|
||||
|
||||
Note that
|
||||
------------
|
||||
lda:tax #0
|
||||
------------
|
||||
is allowed because `#0` is treated as a comment for `tax`.
|
||||
|
||||
EXPRESSIONS
|
||||
-----------
|
||||
Expressions are numbers combined with operators and brackets.
|
||||
You should use square brackets, because parentheses are reserved
|
||||
for 6502 indirect addressing.
|
||||
|
||||
A number is:
|
||||
|
||||
- a 32-bit decimal integer, e.g. `-12345`
|
||||
- a 32-bit hexadecimal integer, e.g. `$abcd`
|
||||
- a 32-bit binary integer, e.g. `%10100101`
|
||||
- an ASCII character, e.g. `'a'` or `"a"`
|
||||
- origin counter: `*`
|
||||
- a hardware register (see below), e.g. `^4e`
|
||||
- [[new_opcode]]an opcode (see below), e.g. `{lda #0}` is `$a9`
|
||||
- [[new_linecnt]]the line repeat counter (see below): `#`
|
||||
|
||||
Abbreviations of Atari hardware registers are provided
|
||||
to save two characters (`$d40e` vs `^4e`)
|
||||
and to facilitate porting software between Atari 8-bit computers
|
||||
and the Atari 5200 console.
|
||||
These are very similar machines, one of the biggest differences
|
||||
is the location of hardware registers.
|
||||
|
||||
[cols="^m,^d,^m,^d",options="header"]
|
||||
|================================================
|
||||
|Syntax|Chip |Value|Value (Atari 5200 mode `opt g+`)
|
||||
| ^0x |GTIA |$D00x|`$C00x`
|
||||
| ^1x |GTIA |$D01x|`$C01x`
|
||||
| ^2x |POKEY|$D20x|`$E80x`
|
||||
| ^3x |PIA |$D30x|'error (there's no PIA chip)'
|
||||
| ^4x |ANTIC|$D40x|`$D40x`
|
||||
|================================================
|
||||
|
||||
The opcode syntax represents the opcode byte of the instruction inside braces.
|
||||
The operand of the instruction is discarded and is needed only to recognize
|
||||
the addressing mode. The instruction should begin right after the left brace
|
||||
and the right brace should immediately follow the operand 'or' the instruction.
|
||||
[[new_op_op]]You can skip the operand if the addressing mode is fixed.
|
||||
Examples: `{lda #}`, `{jsr}`, `{bne}`, `{jmp ()}`, `{sta a:,x}`.
|
||||
|
||||
You can use the line repeat counter (`#`) in the repeated lines.
|
||||
It counts the iterations starting from zero. Examples:
|
||||
----------------------------------------------------
|
||||
:3 dta # ; generates three bytes: 0, 1, 2.
|
||||
line_lo :192 dta l(screen+40*#)
|
||||
line_hi :192 dta h(screen+40*#)
|
||||
dl :59 dta $4f,a(screen+40*#),0,$4f,a(screen+40*#),0
|
||||
----------------------------------------------------
|
||||
|
||||
The following 'binary operators' are supported:
|
||||
|
||||
- `+` Addition
|
||||
- `-` Subtraction
|
||||
- `*` Multiplication
|
||||
- `/` Division
|
||||
- `%` Remainder
|
||||
- `&` Bitwise AND
|
||||
- `|` Bitwise OR
|
||||
- `^` Bitwise XOR
|
||||
- `<<` Arithmetic shift left
|
||||
- `>>` Arithmetic shift right
|
||||
- `==` Equal
|
||||
- `=` Equal (same as `==`)
|
||||
- `!=` Not equal
|
||||
- `<>` Not equal (same as `!=`)
|
||||
- `<` Less than
|
||||
- `>` Greater than
|
||||
- `<=` Less or equal
|
||||
- `>=` Greater or equal
|
||||
- `&&` Logical AND
|
||||
- `||` Logical OR
|
||||
|
||||
[[new_unary]]
|
||||
The following 'unary operators' are supported:
|
||||
|
||||
- `+` Plus (does nothing)
|
||||
- `-` Minus (changes the sign)
|
||||
- `~` Bitwise NOT (complements all bits)
|
||||
- `!` Logical NOT (changes true to false and vice versa)
|
||||
- `<` Low (extracts the low byte)
|
||||
- `>` High (extracts the high byte)
|
||||
|
||||
The operator precedence is following:
|
||||
|
||||
- first: `[]` (brackets)
|
||||
- `+ - ~ < >` (unary)
|
||||
- `* / % & << >>` (binary)
|
||||
- `+ - | ^` (binary)
|
||||
- `= == <> != < > <= >=` (binary)
|
||||
- `!` (unary)
|
||||
- `&&` (binary)
|
||||
- last: `||` (binary)
|
||||
|
||||
Although the operators are similar to those used in C, C++ and Java,
|
||||
their priorities are different than in these languages.
|
||||
|
||||
Compare and logical operators assume that zero is false and a non-zero
|
||||
is true. They return 1 for true.
|
||||
|
||||
Expressions are calculated in signed 32-bit arithmetic.
|
||||
"Arithmetic overflow" error signals overflow of the 32-bit range.
|
||||
|
||||
DIRECTIVES
|
||||
----------
|
||||
|
||||
*EQU* - assign value of expression to label::
|
||||
Examples:
|
||||
----------
|
||||
five equ 5
|
||||
here equ *
|
||||
----------
|
||||
|
||||
[[new_opt]]*OPT* - set assembler options::
|
||||
Five options are available:
|
||||
|
||||
- `F` - fill the space between memory areas with `$FF`
|
||||
- `G` - Atari 5200 mode for hardware register abbreviations
|
||||
- `H` - generate Atari executable headers
|
||||
- `L` - write to the listing
|
||||
- `O` - write to the object file
|
||||
|
||||
You can turn any of these on or off.
|
||||
The default (if no `OPT` specified) is `opt f-g-h+l+o+`.
|
||||
Examples:
|
||||
------------------------------------------------------------------------------
|
||||
opt l- listing off
|
||||
opt l+o- listing on, object file off
|
||||
opt f+g+h- useful for Atari 5200 cartridges - raw output, 5200 hw regs
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
*ORG* - change value of the origin counter::
|
||||
If Atari executable headers are enabled, you can include an operand prefix:
|
||||
|
||||
- `a:` starts a new block even if it's superfluous
|
||||
because the new address equals the current address.
|
||||
- `f:` is same as `a:`, but additionally generates a double-`$FF` prefix
|
||||
before the new header. This prefix is automatically generated
|
||||
at the beginning of the file (no need to include `f:` in the first `ORG`).
|
||||
Examples:
|
||||
---------------
|
||||
org $600
|
||||
org f:$700
|
||||
table org *+100
|
||||
---------------
|
||||
In the latter example `table` points to 100 bytes
|
||||
of uninitialized data (label is assigned with `*`
|
||||
before the `ORG` directive is executed).
|
||||
|
||||
[[new_orgr]]Starting with version 2.6.0, *xasm* supports code
|
||||
that is relocated in the memory at runtime. Let's say you want your code
|
||||
to be located on page zero. You can't normally load it directly into this
|
||||
place, so you load it at a different address and then move in your program.
|
||||
`org r:` changes the address that it used for code generation
|
||||
but not the address used for generating Atari executable headers.
|
||||
Example:
|
||||
--------------------------------------
|
||||
org $8000
|
||||
ldx #code_length-1
|
||||
mva:rpl code_loaded,x z:code_zpage,x-
|
||||
jmp code_zpage
|
||||
|
||||
code_loaded
|
||||
org r:$30
|
||||
code_zpage
|
||||
jmp * ; ... or something more sensible
|
||||
code_length equ *-code_zpage
|
||||
--------------------------------------
|
||||
Note that both `*` and label definitions use the counter used
|
||||
for code generation. There is no direct access to the other counter,
|
||||
because I think this is not useful. If you really need it, you can
|
||||
always type something like:
|
||||
---------------------------------------
|
||||
where_am_i equ *-code_zpage+code_loaded
|
||||
---------------------------------------
|
||||
|
||||
[[new_dta]]*DTA* - define data::
|
||||
|
||||
- integers
|
||||
+
|
||||
--
|
||||
* bytes: `b(200)` or simply `200`
|
||||
* words: `a(10000)`
|
||||
* low bytes of words: `l(511)` (byte 255)
|
||||
* high bytes of words: `h(511)` (byte 1)
|
||||
|
||||
You may enter many expressions in parentheses and combine different types
|
||||
of data in single line, separating things with commas.
|
||||
|
||||
You may also define a sine lookup table. The syntax is:
|
||||
-------------------------------
|
||||
sin(center,amp,size,first,last)
|
||||
-------------------------------
|
||||
where:
|
||||
|
||||
* `center` is an integer which is added to every sine value
|
||||
* `amp` is the sine amplitude
|
||||
* `size` is the sine period
|
||||
* `first,last` define the range of sine arguments.
|
||||
They are optional. The default are `0,size-1`.
|
||||
|
||||
Example:
|
||||
----------------------------
|
||||
dta a(sin(0,1000,256,0,63))
|
||||
----------------------------
|
||||
defines a table of 64 words representing a quarter of sine with the amplitude of 1000.
|
||||
--
|
||||
|
||||
- real numbers: `r(-1.23456e12)`
|
||||
+
|
||||
Real numbers are stored in the 6-byte Atari Floating-Point format.
|
||||
|
||||
- text strings
|
||||
+
|
||||
--
|
||||
* ASCII strings: `c'Text'` or `c"Text"`
|
||||
* ANTIC strings: `d'Text'` or `d"Text"`
|
||||
|
||||
A character string consists of any number of characters surrounded by quotation
|
||||
marks. You can include the quotation marks in the string by doubling them.
|
||||
Placing a `*` character after a string inverts
|
||||
the highest bit in every byte of the string.
|
||||
--
|
||||
+
|
||||
Examples of `DTA`:
|
||||
+
|
||||
------------------------------------------------
|
||||
dta b(1,2),3,a(1000,-1),l(12345,sin(0,127,256))
|
||||
dta d"ANTIC"*,c'It''s a string',$9b
|
||||
------------------------------------------------
|
||||
|
||||
*ICL* - include another source file::
|
||||
Specifies another file to be included in the assembly as if the contents
|
||||
of the referenced file appeared in place of the `ICL` statement.
|
||||
The included file may contain other `ICL` statements.
|
||||
The `.asx` extension is added if none given.
|
||||
Examples:
|
||||
-----------------
|
||||
icl 'macros.asx'
|
||||
icl 'lib/fileio'
|
||||
-----------------
|
||||
Note: for portability, use only relative paths and slash as the separator.
|
||||
This way your sources will compile under Windows and Linux.
|
||||
|
||||
*END* - end assembling file::
|
||||
May be used if the source file ends with something which shouldn't
|
||||
be read by *xasm* (e.g. your notes). At the end of file it's optional.
|
||||
|
||||
*INS* - insert contents of file::
|
||||
Copies every byte of the specified file into the object file and updates
|
||||
the origin counter, as if these bytes were defined with `DTA`.
|
||||
You may specify a range of the file to insert. The syntax is:
|
||||
-----------------------------
|
||||
ins 'file'[,offset[,length]]
|
||||
-----------------------------
|
||||
The first byte in a file has the offset of zero.
|
||||
If the offset is negative, it counts from the end of the file.
|
||||
Examples:
|
||||
-----------------------------------------------
|
||||
ins 'picture.raw'
|
||||
ins 'file',-256 insert last 256 bytes of file
|
||||
ins 'file',10,10 insert bytes 10..19 of file
|
||||
-----------------------------------------------
|
||||
|
||||
*RUN* - set run address in the Atari executable format::
|
||||
---------
|
||||
run main
|
||||
---------
|
||||
is equivalent to:
|
||||
------------
|
||||
org $2e0
|
||||
dta a(main)
|
||||
------------
|
||||
|
||||
*INI* - set init address in the Atari executable format::
|
||||
Example:
|
||||
------------
|
||||
ini showpic
|
||||
------------
|
||||
|
||||
*ERT* - generate error if expression evaluates to true::
|
||||
Examples:
|
||||
-----------------------
|
||||
ert *>$c000
|
||||
ert len1>$ff||len2>$ff
|
||||
-----------------------
|
||||
|
||||
[[new_eli]]*IFT* - assemble if expression is true::
|
||||
*ELI* - else if::
|
||||
*ELS* - else::
|
||||
*EIF* - end if::
|
||||
With these directives you can construct fragments which
|
||||
are assembled only when a condition is met.
|
||||
Conditional constructions can be nested.
|
||||
Example:
|
||||
-------------
|
||||
noscr equ 1
|
||||
widescr equ 1
|
||||
ift noscr
|
||||
lda #0
|
||||
eli widescr
|
||||
lda #$23
|
||||
els
|
||||
lda #$22
|
||||
eif
|
||||
sta $22f
|
||||
-------------
|
||||
Note: the above example may be rewritten using the 'repeat line' feature:
|
||||
--------------------------
|
||||
noscr equ 1
|
||||
widescr equ 1
|
||||
:noscr lda #0
|
||||
:!noscr&&widescr lda #$23
|
||||
:!noscr&&!widescr lda #$22
|
||||
sta $22f
|
||||
--------------------------
|
||||
|
||||
PSEUDO COMMANDS
|
||||
---------------
|
||||
'Pseudo commands' are built-in macros. There are no user-defined macros in *xasm*.
|
||||
|
||||
*ADD* - addition without carry::
|
||||
If you have ever programmed a 6502, you must have noticed that you had
|
||||
to use a `CLC` before `ADC` for every simple addition.
|
||||
+
|
||||
*xasm* can do it for you. `ADD` replaces two instructions: `CLC` and `ADC`.
|
||||
|
||||
*SUB* - subtraction::
|
||||
It is `SEC` and `SBC`.
|
||||
|
||||
[[new_repskip]]*RCC, RCS, REQ, RMI, RNE, RPL, RVC, RVS* - conditional repeat::
|
||||
These are branches to the previous instruction.
|
||||
They take no operand, because the branch target is the address
|
||||
of the previously assembled instruction or pseudo command.
|
||||
Example:
|
||||
+
|
||||
-----------------------
|
||||
ldx #0
|
||||
mva:rne $500,x $600,x+
|
||||
-----------------------
|
||||
+
|
||||
The above code copies a 256-byte memory block from $500 to $600.
|
||||
Here is the same written with standard 6502 commands only:
|
||||
+
|
||||
--------------------
|
||||
ldx #0
|
||||
copy_loop lda $500,x
|
||||
sta $600,x
|
||||
inx
|
||||
bne copy_loop
|
||||
--------------------
|
||||
|
||||
*SCC, SCS, SEQ, SMI, SNE, SPL, SVC, SVS* - conditional skip::
|
||||
These are branches over the next instruction. No operand is required,
|
||||
because the target is the address of the instruction following
|
||||
the next instruction.
|
||||
Example:
|
||||
+
|
||||
--------------
|
||||
lda #40
|
||||
add:sta ptr
|
||||
scc:inc ptr+1
|
||||
--------------
|
||||
+
|
||||
In the above example the 16-bit variable `ptr` is incremented by 40.
|
||||
|
||||
*JCC, JCS, JEQ, JMI, JNE, JPL, JVC, JVS* - conditional jumps::
|
||||
These are long branches. While standard branches (such as `BNE`)
|
||||
have range of -128..+127, these jumps have range of 64 kB.
|
||||
For example:
|
||||
+
|
||||
---------
|
||||
jne dest
|
||||
---------
|
||||
+
|
||||
is equivalent to:
|
||||
+
|
||||
-------------
|
||||
seq:jmp dest
|
||||
-------------
|
||||
|
||||
*INW* - increment word::
|
||||
Increments a 16-bit word in the memory.
|
||||
Example:
|
||||
+
|
||||
---------
|
||||
inw dest
|
||||
---------
|
||||
+
|
||||
is equivalent to:
|
||||
+
|
||||
---------------
|
||||
inc dest
|
||||
sne:inc dest+1
|
||||
---------------
|
||||
|
||||
*MVA, MVX, MVY* - move byte using accumulator, X or Y::
|
||||
Each of these pseudo commands requires two operands
|
||||
and substitutes two commands:
|
||||
+
|
||||
----------------------------------------
|
||||
mva source dest = lda source : sta dest
|
||||
mvx source dest = ldx source : stx dest
|
||||
mvy source dest = ldy source : sty dest
|
||||
----------------------------------------
|
||||
|
||||
[[new_mwinde]]*MWA, MWX, MWY* - move word using accumulator, X or Y::
|
||||
These pseudo commands require two operands and are combinations of two `MV*`'s:
|
||||
one to move the low byte, and the other to move the high byte.
|
||||
You can't use indirect nor pseudo addressing mode with `MW*`.
|
||||
Destination must be an absolute address, optionally indexed.
|
||||
When source is also an absolute address, an `mw* source dest` expands to:
|
||||
+
|
||||
--------------------
|
||||
mv* source dest
|
||||
mv* source+1 dest+1
|
||||
--------------------
|
||||
+
|
||||
When source is an immediate value, an `mw* #immed dest` expands to:
|
||||
+
|
||||
------------------
|
||||
mv* <immed dest
|
||||
mv* >immed dest+1
|
||||
------------------
|
||||
+
|
||||
When `<immed` equals `>immed` and `immed` is not forward-referenced,
|
||||
*xasm* skips the second `LD*`:
|
||||
+
|
||||
----------------
|
||||
mv* <immed dest
|
||||
st* dest+1
|
||||
----------------
|
||||
+
|
||||
If possible, `MWX` and `MWY` use increment/decrement commands.
|
||||
For example, `mwx #1 dest` expands to:
|
||||
+
|
||||
-----------
|
||||
ldx #1
|
||||
stx dest
|
||||
dex
|
||||
stx dest+1
|
||||
-----------
|
||||
|
||||
ADDRESSING MODES
|
||||
----------------
|
||||
|
||||
All addressing modes are entered in the standard 6502 convention
|
||||
except for the accumulator addressing mode,
|
||||
which should be marked with the `@` character (as in Quick Assembler).
|
||||
|
||||
For Quick Assembler compatibility, there are two extra immediate
|
||||
addressing modes: `<` and `>`, which use the low/high byte of a 16-bit word constant.
|
||||
Unlike in Quick Assembler, you can alternatively use
|
||||
the more common syntax: `#<` and `#>`.
|
||||
Note the difference:
|
||||
-------------------------------
|
||||
lda >$ff+5 ; loads 1 (>$104)
|
||||
lda #>$ff+5 ; loads 5 (0+5)
|
||||
-------------------------------
|
||||
|
||||
You can explicitly specify absolute (`a:`) and zero-page (`z:`) addressing modes.
|
||||
|
||||
Examples:
|
||||
--------------------------------------
|
||||
nop
|
||||
asl @
|
||||
lda >$1234 assembles to lda #$12
|
||||
lda $100,x
|
||||
lda 0 zero-page (8-bit address)
|
||||
lda a:0 absolute (16-bit address)
|
||||
jmp ($0a)
|
||||
lda ($80),y
|
||||
--------------------------------------
|
||||
|
||||
[[new_adrmodes]]
|
||||
There are '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 `MWA`, `MWX` and `MWY`:
|
||||
------------------------------------------
|
||||
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
|
||||
cmd (z),0+ = ldy #0 : cmd (z),y : iny
|
||||
cmd (z),0- = ldy #0 : cmd (z),y : dey
|
||||
------------------------------------------
|
||||
|
||||
HISTORY
|
||||
-------
|
||||
|
||||
Version 3.0.2 (2009-10-17)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
- fixed "Branch out of range" error message - was overstated by 256 bytes
|
||||
for backward branches
|
||||
- <<new_makefile,new command-line option */M* prints Makefile rule>>
|
||||
- command-line options are now case-insensitive
|
||||
- on Windows error messages are printed in red, warnings in yellow
|
||||
|
||||
Version 3.0.1 (2007-04-22)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
- fixed a bug in `OPT H-` mode
|
||||
- made *xasm* compilable with the latest D compiler v1.010
|
||||
(there were incompatible changes in the D language and library)
|
||||
|
||||
Version 3.0.0 (2005-05-22)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
- rewritten from the x86 assembly language to the
|
||||
http://www.digitalmars.com/d[D programming language] - Linux version
|
||||
is now available and DOS is no longer supported
|
||||
- no limits for line length, number of `ICLs`, `ORGs`,`IFTs` and labels
|
||||
- Unix-style command-line options are supported
|
||||
- */e* option is no longer supported
|
||||
- the label table is now sorted alphabetically
|
||||
|
||||
Version 2.6.1 (2005-05-21)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
- no more "Arithmetic overflow" and "Division by zero" errors for correct
|
||||
use of forward-referenced labels (bug found by Marcin Lewandowski)
|
||||
- an error was reported in the following correct code:
|
||||
+
|
||||
---------
|
||||
ift 0
|
||||
foo equ 1
|
||||
ift foo
|
||||
eif
|
||||
eif
|
||||
---------
|
||||
+
|
||||
(bug found by Adrian Matoga)
|
||||
|
||||
- errors for non-existing `INC @` and `DEC @`
|
||||
- negative numbers fixed in the listing
|
||||
|
||||
Version 2.6.0 (2005-02-07)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
- long file names are supported under Windows
|
||||
- <<new_orgr,support for code relocated at runtime>>
|
||||
- <<new_linecnt,line repeat counter>>
|
||||
- label values are now 32-bit, not just 17-bit
|
||||
- command-line options */n* and */s* are no longer supported
|
||||
- fatal I/O errors (such as floppy not ready) no longer print the annoying
|
||||
"Abort, Retry, Ignore" message
|
||||
|
||||
Version 2.5.2 (2002-10-03)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
- version 2.5.1 broke Unix EOLs - fixed
|
||||
- version 2.5.1 omitted all blank/comment/label lines, unless */c* was used
|
||||
|
||||
Version 2.5.1 (2002-08-21)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
- fixed assembling sources with Atari EOLs
|
||||
- blank/comment/label lines in false conditionals are now correctly omitted
|
||||
in listing
|
||||
|
||||
Version 2.5 (2002-07-08)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
- fixed another bug, very similar to the previous one, e.g.
|
||||
+
|
||||
----------
|
||||
ift 0
|
||||
:label nop
|
||||
eif
|
||||
----------
|
||||
+
|
||||
reported "Label not defined before" error for the repeat count
|
||||
|
||||
- <<new_opt,`OPT F+` causes `ORG` to fill the space
|
||||
between the old and the new location with `$FFs`>>
|
||||
- <<new_opt,`OPT G+` enables Atari 5200 mode for hardware
|
||||
register abbreviations>>
|
||||
|
||||
Version 2.4.1 (2002-06-27)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
- fixed a bug related to label definitions in conditionally skipped code,
|
||||
e.g.
|
||||
+
|
||||
----------
|
||||
ift 0
|
||||
label
|
||||
eif
|
||||
----------
|
||||
+
|
||||
reported "No ORG specified" error for the label definition
|
||||
|
||||
Version 2.4 (2002-05-22)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
- fixed incorrect unary operator precedence
|
||||
- fixed wrong label value after a skip pseudo command
|
||||
- the assembler is .EXE (.COM caused problems with DJGPP *make* due
|
||||
to a bug in the DJGPP runtime)
|
||||
- the assembler executable is not compressed (so it occupies less space in the ZIP)
|
||||
- improved command-line parsing: options may be used before source file name,
|
||||
tab character is a valid separator, slash may be used as a directory separator
|
||||
- error and warning messages are written to stderr, not stdout
|
||||
- added `==` (equals) operator, which is equivalent to `=`,
|
||||
but more natural for C/C++/Java programmers
|
||||
- <<new_deflabel,added `/d:label=value` option: define a label>>
|
||||
- <<new_fullpaths,added `/p` option: print full paths
|
||||
in listing and error messages>>
|
||||
- <<new_quiet,added `/q` option: quiet mode>>
|
||||
- <<new_unlabels,added `/u` option: warn of unused labels>>
|
||||
- <<new_opt,writing to the object file may be suppressed with `OPT O-`>>
|
||||
- <<new_eli,added `ELI` (else if) directive>>
|
||||
- <<new_mwinde,`MWX` and `MWY` may use `INX`/`DEX` and `INY`/`DEY`,
|
||||
respectively, for generating shorter code>>
|
||||
|
||||
Version 2.3 (2002-02-10)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
- fixed double skip (e.g. `SCC:SNE`)
|
||||
- fixed real numbers with two-digit exponent
|
||||
- trailing spaces are trimmed from listing lines
|
||||
- label definitions allowed in blank, comment and repeated lines
|
||||
- <<new_unary,unary operators>>
|
||||
- <<new_dta,`DTA` implied byte mode>>
|
||||
- <<new_op_op,operand can be skipped for some opcodes>>
|
||||
|
||||
Version 2.2 (1999-09-10)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
- fixed invalid opcodes of absolute `CPX` and `CPY`
|
||||
- fixed: addressing mode not checked for branch commands
|
||||
- fixed `ICL` in last line
|
||||
- fixed `OPT H-H+`
|
||||
- fixed first `ORG *`
|
||||
- no need to set origin counter until it's used
|
||||
- allow Unix, Macintosh and Atari EOLs
|
||||
- value of 'true' changed to 1
|
||||
- command-line option to set environment variables on error
|
||||
- commane-line option to assemble only if source is newer than object file
|
||||
- <<new_opcode,opcode extracting>>
|
||||
- <<new_linerep,repeat line>>
|
||||
- <<new_pairing,two instructions in line>>
|
||||
- <<new_repskip,conditional repeat and skip pseudo commands>>
|
||||
- <<new_adrmodes,`(),0+` and `(),0-` pseudo addressing modes>>
|
||||
|
||||
Version 2.0 (1998-11-12)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
- fixed: name of object file was truncated
|
||||
- fixed forward references in `EQU` and `DTA`
|
||||
- fixed hex numbers
|
||||
- `.OBX` is now the default extension for the object file
|
||||
- options (command-line switches and `OPT`)
|
||||
- listing
|
||||
- label table
|
||||
- conditional assembly
|
||||
- user errors (`ERT`)
|
||||
- warnings
|
||||
- 6 new pseudo commands (memory-to-memory move)
|
||||
- 8 pseudo addressing modes
|
||||
- indirect conditional jumps
|
||||
- Atari floating-point numbers
|
||||
- object file headers optimization
|
||||
- improved expressions - 19 operators and brackets, 32-bit arithmetic
|
||||
- improved signed numbers
|
||||
- improved `INS`: inserting specified part of file
|
||||
|
||||
Version 1.2 (1998-08-14)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
- first release
|
||||
|
||||
AUTHOR
|
||||
------
|
||||
Piotr Fusik <fox@scene.pl>
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
|
||||
Website: http://xasm.atari.org[]
|
111
xasm.d
111
xasm.d
@ -1,5 +1,20 @@
|
||||
// xasm 3.0.1 by Piotr Fusik <fox@scene.pl>
|
||||
// xasm 3.0.2 by Piotr Fusik <fox@scene.pl>
|
||||
// http://xasm.atari.org
|
||||
// Can be compiled with DMD v1.030.
|
||||
|
||||
// Poetic License:
|
||||
//
|
||||
// This work 'as-is' we provide.
|
||||
// No warranty express or implied.
|
||||
// We've done our best,
|
||||
// to debug and test.
|
||||
// Liability for damages denied.
|
||||
//
|
||||
// Permission is granted hereby,
|
||||
// to copy, share, and modify.
|
||||
// Use as is fit,
|
||||
// free or for profit.
|
||||
// These rights, on this notice, rely.
|
||||
|
||||
import std.math;
|
||||
import std.stream;
|
||||
@ -7,8 +22,10 @@ import std.cstream;
|
||||
import std.string;
|
||||
|
||||
version (Windows) {
|
||||
import std.c.windows.windows;
|
||||
|
||||
extern (Windows) export int GetFullPathNameA(char* lpFileName, int nBufferLength, char* lpBuffer, char** lpFilePart);
|
||||
extern (Windows) HANDLE GetStdHandle(DWORD nStdHandle);
|
||||
|
||||
char[] getFullPath(char[] filename) {
|
||||
char[260] fullPath;
|
||||
@ -31,7 +48,7 @@ version (Windows) {
|
||||
const char[] OPTION_P_DESC = "Ignored for compatibility";
|
||||
}
|
||||
|
||||
const char[] TITLE = "xasm 3.0.1";
|
||||
const char[] TITLE = "xasm 3.0.2";
|
||||
|
||||
char[] sourceFilename = null;
|
||||
|
||||
@ -41,6 +58,10 @@ char[][26] optionParameters;
|
||||
|
||||
char[][] commandLineDefinitions = null;
|
||||
|
||||
char[] makeTarget = null;
|
||||
|
||||
char[] makeSources = "";
|
||||
|
||||
int exitCode = 0;
|
||||
|
||||
int totalLines;
|
||||
@ -212,14 +233,26 @@ bit getOption(char letter) {
|
||||
return options[letter - 'a'];
|
||||
}
|
||||
|
||||
void warning(char[] msg) {
|
||||
void warning(char[] msg, bool error = false) {
|
||||
dout.flush();
|
||||
version (Windows) {
|
||||
HANDLE h = GetStdHandle(STD_ERROR_HANDLE);
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
GetConsoleScreenBufferInfo(h, &csbi);
|
||||
SetConsoleTextAttribute(h, (csbi.wAttributes & ~0xf) | (error ? 12 : 14));
|
||||
}
|
||||
if (line !is null) {
|
||||
derr.printf("%.*s\n", line);
|
||||
}
|
||||
derr.printf("%.*s (%d) WARNING: %.*s\n",
|
||||
derr.printf("%.*s (%d) %.*s: %.*s\n",
|
||||
currentLocation.filename,
|
||||
currentLocation.lineNo, msg
|
||||
currentLocation.lineNo,
|
||||
error ? "ERROR" : "WARNING",
|
||||
msg
|
||||
);
|
||||
version (Windows) {
|
||||
SetConsoleTextAttribute(h, csbi.wAttributes);
|
||||
}
|
||||
exitCode = 1;
|
||||
}
|
||||
|
||||
@ -1163,7 +1196,12 @@ unittest {
|
||||
assert(filenameExt("test\\foo.bar") == 8);
|
||||
}
|
||||
|
||||
char[] makeEscape(char[] s) {
|
||||
return replace(s, "$", "$$");
|
||||
}
|
||||
|
||||
Stream openInputFile(char[] filename) {
|
||||
makeSources ~= ' ' ~ makeEscape(filename);
|
||||
try {
|
||||
return new BufferedFile(filename, FileMode.In);
|
||||
} catch (OpenException e) {
|
||||
@ -1183,6 +1221,9 @@ Stream openOutputFile(char letter, char[] defaultExt) {
|
||||
} else {
|
||||
filename = optionParameters[letter - 'a'];
|
||||
}
|
||||
if (letter == 'o') {
|
||||
makeTarget = makeEscape(filename);
|
||||
}
|
||||
try {
|
||||
return new BufferedFile(filename, FileMode.OutNew);
|
||||
} catch (OpenException e) {
|
||||
@ -1716,7 +1757,7 @@ ubyte calculateBranch(int offset) {
|
||||
if (offset < -0x80 || offset > 0x7f) {
|
||||
int dist;
|
||||
if (offset < 0) {
|
||||
dist = 0x80 - offset;
|
||||
dist = -offset - 0x80;
|
||||
} else {
|
||||
dist = offset - 0x7f;
|
||||
}
|
||||
@ -3043,9 +3084,12 @@ int main(char[][] args) {
|
||||
char[] arg = args[i];
|
||||
if (isOption(arg)) {
|
||||
char letter = arg[1];
|
||||
if (letter >= 'A' && letter <= 'Z')
|
||||
letter += 'a' - 'A';
|
||||
switch (letter) {
|
||||
case 'c':
|
||||
case 'i':
|
||||
case 'm':
|
||||
case 'p':
|
||||
case 'q':
|
||||
case 'u':
|
||||
@ -3110,6 +3154,7 @@ int main(char[][] args) {
|
||||
"/i Don't list included files\n"
|
||||
"/l[:filename] Generate listing\n"
|
||||
"/o:filename Set object file name\n"
|
||||
"/M Print Makefile rule\n"
|
||||
"/p " ~ OPTION_P_DESC ~ "\n"
|
||||
"/q Suppress info messages\n"
|
||||
"/t[:filename] List label table\n"
|
||||
@ -3125,13 +3170,7 @@ int main(char[][] args) {
|
||||
listLabelTable();
|
||||
}
|
||||
} catch (AssemblyError e) {
|
||||
if (line !is null) {
|
||||
derr.printf("%.*s\n", line);
|
||||
}
|
||||
derr.printf("%.*s (%d) ERROR: %.*s\n",
|
||||
currentLocation.filename,
|
||||
currentLocation.lineNo, e.msg
|
||||
);
|
||||
warning(e.msg, true);
|
||||
exitCode = 2;
|
||||
}
|
||||
if (listingStream !is null) {
|
||||
@ -3140,10 +3179,48 @@ int main(char[][] args) {
|
||||
if (objectStream !is null) {
|
||||
objectStream.close();
|
||||
}
|
||||
if (exitCode <= 1 && !getOption('q')) {
|
||||
dout.printf("%d lines of source assembled\n", totalLines);
|
||||
if (objectBytes > 0) {
|
||||
dout.printf("%d bytes written to the object file\n", objectBytes);
|
||||
if (exitCode <= 1) {
|
||||
if (!getOption('q')) {
|
||||
dout.printf("%d lines of source assembled\n", totalLines);
|
||||
if (objectBytes > 0) {
|
||||
dout.printf("%d bytes written to the object file\n", objectBytes);
|
||||
}
|
||||
}
|
||||
if (getOption('m')) {
|
||||
dout.printf("%.*s:%.*s\n\txasm", makeTarget, makeSources);
|
||||
for (int i = 1; i < args.length; i++) {
|
||||
char[] arg = args[i];
|
||||
if (isOption(arg)) {
|
||||
char letter = arg[1];
|
||||
if (letter >= 'A' && letter <= 'Z')
|
||||
letter += 'a' - 'A';
|
||||
switch (letter) {
|
||||
case 'm':
|
||||
break;
|
||||
case 'o':
|
||||
if (arg[0] == '/') {
|
||||
dout.printf(" /%c:$@", arg[1]);
|
||||
} else {
|
||||
dout.printf(" -%c $@", arg[1]);
|
||||
++i;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (arg[0] == '-'
|
||||
&& (letter == 'd' || letter == 'l' || letter == 't')
|
||||
&& i + 1 < args.length && !isOption(args[i + 1])) {
|
||||
dout.printf(" %.*s %.*s", arg, makeEscape(args[++i]));
|
||||
}
|
||||
else {
|
||||
dout.printf(" %.*s", makeEscape(arg));
|
||||
}
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
dout.printf(" $<");
|
||||
}
|
||||
dout.printf("\n");
|
||||
}
|
||||
}
|
||||
return exitCode;
|
||||
|
705
xasm.html
705
xasm.html
@ -1,705 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
||||
<head>
|
||||
<title>xasm 3.0.1</title>
|
||||
<meta name="Author" content="Piotr Fusik"/>
|
||||
</head>
|
||||
<body>
|
||||
<h2>NAME</h2>
|
||||
<p>xasm - 6502 cross-assembler</p>
|
||||
<h2>SYNOPSIS</h2>
|
||||
<p><tt>xasm source [options]</tt></p>
|
||||
<h2>DESCRIPTION</h2>
|
||||
<p><b>xasm</b> is a cross-assembler which generates code for the 6502
|
||||
processor.</p>
|
||||
<p><tt>source</tt> is the name of the source file. If no filename extension
|
||||
is given, <tt>.asx</tt> is appended. The default action (when invoked without
|
||||
options) is to assembly <tt>source</tt>, writing the result to a file with
|
||||
the <tt>.obx</tt> extension.</p>
|
||||
<h2>OPTIONS</h2>
|
||||
<dl>
|
||||
<dt><tt>/c</tt></dt>
|
||||
<dd>List lines skipped due to a false condition.</dd>
|
||||
<dt><a id="new_deflabel"/><tt>/d:label=value</tt></dt>
|
||||
<dd>Define a label.
|
||||
<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.</dd>
|
||||
<dt><tt>/i</tt></dt>
|
||||
<dd>Do not list included files. Only main source file will be listed.</dd>
|
||||
<dt><tt>/l[:filename]</tt></dt>
|
||||
<dd>Generate a listing. If no <tt>filename</tt> is given, the listing is written
|
||||
to <tt>source.lst</tt>, where <tt>source</tt> is the name of the source file
|
||||
without the extension.</dd>
|
||||
<dt><tt>/o:filename</tt></dt>
|
||||
<dd>Set object file name. The default is <tt>source.obx</tt>.
|
||||
You may use the null device (<tt>/o:nul</tt>) to generate no object file.</dd>
|
||||
<dt><a id="new_fullpaths"/><tt>/p</tt></dt>
|
||||
<dd>Print fully qualified file names in listing and error messages.
|
||||
This option works only on Windows and is silently ignored on other platforms.</dd>
|
||||
<dt><a id="new_quiet"/><tt>/q</tt></dt>
|
||||
<dd>Suppress info messages.
|
||||
Quiet mode. Prevents <b>xasm</b> from printing the logo and the summary.</dd>
|
||||
<dt><tt>/t[:filename]</tt></dt>
|
||||
<dd>List label table. If <tt>filename</tt> is omitted then the table is appended
|
||||
to the listing.</dd>
|
||||
<dt><a id="new_unlabels"/><tt>/u</tt></dt>
|
||||
<dd>Issue a warning message for each label whose value is unused.</dd>
|
||||
</dl>
|
||||
<p>Alternatively, you may use Unix-style options, for example:</p>
|
||||
<pre>xasm -i -d DEBUG=1 -l listing.lst source.asx
|
||||
</pre>
|
||||
<h2>SYNTAX</h2>
|
||||
<p>Source files should be plain ASCII files. LF, CR, CR/LF and Atari line terminators
|
||||
are supported. Labels and instructions are case-insensitive.</p>
|
||||
<p><b>xasm</b> is backward compatible with Quick Assembler.
|
||||
To compile QA sources with <b>xasm</b>, simply replace ATASCII-specific characters
|
||||
with their integer codes. You also have to change all <tt>OPT</tt> directives,
|
||||
but usually you can simply remove them.</p>
|
||||
<p>A <i>label</i> is a symbol that represents a 32-bit signed integer.
|
||||
You can define a label by putting its name at the beginning of a line
|
||||
(with no spaces before). Unless you use the <tt>EQU</tt> directive,
|
||||
the label is assigned the current value of the origin counter.</p>
|
||||
<p>Instructions and directives must be preceded with some whitespace.
|
||||
Note that in <b>xasm</b> you can use instruction and directive
|
||||
names as label names. For example</p>
|
||||
<pre>nop
|
||||
</pre><p>defines a label called <tt>nop</tt>, whereas</p>
|
||||
<pre> nop
|
||||
</pre><p>is a 6502 instruction.</p>
|
||||
<p>Full comment lines must start with a semicolon, a pipe or an asterisk,
|
||||
with optional label definition and spaces before. Here are examples
|
||||
of full comment lines:</p>
|
||||
<pre>; this is a comment
|
||||
* so it is
|
||||
label | and this too
|
||||
</pre>
|
||||
<p><a id="new_linerep"/>Lines with instructions (and some directives)
|
||||
may be <i>repeated</i>. A single line may be assembled several times,
|
||||
for example:</p>
|
||||
<pre>:4 asl @
|
||||
table :32*5 dta 5
|
||||
</pre>
|
||||
<p>In lines with instructions or directives, a comment starts immediately
|
||||
after the instruction/directive has been successfully parsed.
|
||||
That is, <b>xasm</b> does not require a special character to start a comment.</p>
|
||||
<pre> lda foo ; this is a comment
|
||||
sta bar so it is
|
||||
tax #0 tax has no operand, therefore #0 starts this comment
|
||||
</pre>
|
||||
<p><a id="new_pairing"/>You may put two instructions in one line
|
||||
so they share the operand. For example:</p>
|
||||
<pre> eor:sta foo
|
||||
</pre>
|
||||
<p>is equivalent to</p>
|
||||
<pre> eor foo
|
||||
sta foo
|
||||
</pre>
|
||||
<p>Note that</p>
|
||||
<pre> lda:tax #0
|
||||
</pre><p>is allowed because <tt>#0</tt> is treated as a comment for <tt>tax</tt>.</p>
|
||||
<h2>EXPRESSIONS</h2>
|
||||
<p>Expressions are numbers combined with operators and brackets.
|
||||
You should use square brackets, because parentheses are reserved
|
||||
for 6502 indirect addressing.</p>
|
||||
<p>Numbers can be expressed as:</p>
|
||||
<ul>
|
||||
<li>a 32-bit decimal integer, e.g. <tt>-12345</tt></li>
|
||||
<li>a 32-bit hexadecimal integer, e.g. <tt>$abcd</tt></li>
|
||||
<li>a 32-bit binary integer, e.g. <tt>%10100101</tt></li>
|
||||
<li>an ASCII character, e.g. <tt>'a'</tt> or <tt>"a"</tt></li>
|
||||
<li>origin counter: <tt>*</tt></li>
|
||||
<li>a hardware register, e.g. <tt>^4e</tt></li>
|
||||
<li><a id="new_opcode"/>an op-code, e.g. <tt>{lda #0}</tt> equals
|
||||
<tt>$a9</tt></li>
|
||||
<li><a id="new_linecnt"/>the line repeat counter: <tt>#</tt></li>
|
||||
</ul>
|
||||
<p>Abbreviations of Atari hardware registers are provided to save you
|
||||
the trouble of typing two extra characters (<tt>^4e</tt> vs <tt>$d40e</tt>)
|
||||
and to ease porting software between Atari 8-bit computers and the Atari 5200
|
||||
console. These are very similar machines, one of the biggest differences is
|
||||
the location of hardware registers.</p>
|
||||
<table>
|
||||
<tr><th>Syntax</th><th>Chip</th>
|
||||
<th>Value in the Atari 8-bit<br/>computer mode (<tt>opt g-</tt>)</th>
|
||||
<th>Value in the Atari 5200<br/>game console mode (<tt>opt g+</tt>)</th>
|
||||
</tr>
|
||||
<tr><td><tt>^0x</tt></td><td>GTIA</td>
|
||||
<td><tt>$D00x</tt></td><td><tt>$C00x</tt></td></tr>
|
||||
<tr><td><tt>^1x</tt></td><td>GTIA</td>
|
||||
<td><tt>$D01x</tt></td><td><tt>$C01x</tt></td></tr>
|
||||
<tr><td><tt>^2x</tt></td><td>POKEY</td>
|
||||
<td><tt>$D20x</tt></td><td><tt>$E80x</tt></td></tr>
|
||||
<tr><td><tt>^3x</tt></td><td>PIA</td>
|
||||
<td><tt>$D30x</tt></td><td>error (there's no PIA chip)</td></tr>
|
||||
<tr><td><tt>^4x</tt></td><td>ANTIC</td>
|
||||
<td><tt>$D40x</tt></td><td><tt>$D40x</tt></td></tr>
|
||||
</table>
|
||||
<p>An op-code is the single-byte op-code of the instruction inside braces.
|
||||
The operand of the instruction is discarded and is necessary only
|
||||
to recognize the addressing mode. The instruction should begin right after
|
||||
the left brace and the right brace should immediately follow the operand
|
||||
or the instruction.
|
||||
<a id="new_op_op"/>You can skip the operand if the addressing mode
|
||||
is fixed. Examples:
|
||||
<tt>{lda #}</tt>, <tt>{jsr}</tt>, <tt>{bne}</tt>, <tt>{jmp ()}</tt>,
|
||||
<tt>{sta a:,x}</tt>.</p>
|
||||
<p>You can use the line repeat counter (<tt>#</tt>) in the repeated lines.
|
||||
It counts the iterations starting from zero. Examples:</p>
|
||||
<pre>:3 dta # ; generates three bytes: 0, 1, 2.
|
||||
line_lo :192 dta l(screen+40*#)
|
||||
line_hi :192 dta h(screen+40*#)
|
||||
dl :59 dta $4f,a(screen+40*#),0,$4f,a(screen+40*#),0
|
||||
</pre>
|
||||
<p>The follownig binary operators are supported:</p>
|
||||
<ul>
|
||||
<li><tt>+ </tt> Addition</li>
|
||||
<li><tt>- </tt> Subtraction</li>
|
||||
<li><tt>* </tt> Multiplication</li>
|
||||
<li><tt>/ </tt> Division</li>
|
||||
<li><tt>% </tt> Remainder</li>
|
||||
<li><tt>& </tt> Bitwise AND</li>
|
||||
<li><tt>| </tt> Bitwise OR</li>
|
||||
<li><tt>^ </tt> Bitwise XOR</li>
|
||||
<li><tt><<</tt> Arithmetic shift left</li>
|
||||
<li><tt>>></tt> Arithmetic shift right</li>
|
||||
<li><tt>= </tt> Equal</li>
|
||||
<li><tt>==</tt> Equal (same as <tt>=</tt>)</li>
|
||||
<li><tt><></tt> Not equal</li>
|
||||
<li><tt>!=</tt> Not equal (same as <tt><></tt>)</li>
|
||||
<li><tt>< </tt> Less than</li>
|
||||
<li><tt>> </tt> Greater than</li>
|
||||
<li><tt><=</tt> Less or equal</li>
|
||||
<li><tt>>=</tt> Greater or equal</li>
|
||||
<li><tt>&&</tt> Logical AND</li>
|
||||
<li><tt>||</tt> Logical OR</li>
|
||||
</ul>
|
||||
<p><a id="new_unary"/>The following unary operators are supported:</p>
|
||||
<ul>
|
||||
<li><tt>+ </tt> Plus (does nothing)</li>
|
||||
<li><tt>- </tt> Minus (changes the sign)</li>
|
||||
<li><tt>~ </tt> Bitwise NOT (complements all bits)</li>
|
||||
<li><tt>! </tt> Logical NOT (changes true to false and vice versa)</li>
|
||||
<li><tt>< </tt> Low (extracts the low byte)</li>
|
||||
<li><tt>> </tt> High (extracts the high byte)</li>
|
||||
</ul>
|
||||
<p>The operator precedence is following:</p>
|
||||
<table>
|
||||
<tr><td>first</td><td><tt>[]</tt></td>
|
||||
<td>(brackets)</td></tr>
|
||||
<tr><td> </td><td><tt>+ - ~ < ></tt></td>
|
||||
<td>(unary)</td></tr>
|
||||
<tr><td> </td><td><tt>* / % & << >></tt></td>
|
||||
<td>(binary)</td></tr>
|
||||
<tr><td> </td><td><tt>+ - | ^</tt></td>
|
||||
<td>(binary)</td></tr>
|
||||
<tr><td> </td><td><tt>= == <> != < > <= >=</tt></td>
|
||||
<td>(binary)</td></tr>
|
||||
<tr><td> </td><td><tt>!</tt></td>
|
||||
<td>(unary)</td></tr>
|
||||
<tr><td> </td><td><tt>&&</tt></td>
|
||||
<td>(binary)</td></tr>
|
||||
<tr>& |