1
0
mirror of https://github.com/pfusik/xasm.git synced 2024-12-22 15:31:23 +00:00
xasm/xasm.txt
2013-01-07 12:07:26 +01:00

323 lines
12 KiB
Plaintext

X-Assembler version 1.2
=======================
coded by Fox/Taquart
INTRODUCTION
============
The X-Assembler is an assembler, which generates code for the 6502 processor.
Currently it generates files only in standard 8-bit Atari executable format.
It is designed to be used with Atari Peripheral Emulator. You can now write
and assemble programs on PC and load into Atari using APE.
The X-Assembler is 100% compatible with Quick Assembler on Atari.
System requirements
-------------------
- a PC compatible computer with 386 or better CPU
- a MS-DOS compatible OS
- a numeric coprocessor for generating sinus tables
Your CPU probably has a built-in coprocessor.
Creating a source program
-------------------------
Source file should be standard text file with IBM-style EOLs: CR/LF. You can
use any text editor on PC to prepare your source code.
No line of source file should be longer than 256 characters.
There is absolutely no limitation on the length of the file.
Source may contain TAB characters - there are treated as spaces.
Assembler is NOT case-sensitive.
Converting Quick Assembler files
--------------------------------
The X-Asm recognizes all Quick Assembler directives, symbols and expressions.
The only one problem with converting is that Atari text files are bit
different from PC text files. Firstly, EOL's must be converted from $9b to
$0d/$0a. Secondly, some of editors do not like Atari's special characters:
ASCII 0-31 and 128-255. You must replace these characters with its ATASCII
codes, using QAsm-style expressions.
Once you have converted source to PC-style text file, you may write your
programs using only QAsm features, so you don't have to learn anything more.
Note that QAsm's OPT directive is ignored by X-Asm.
Assembling a source program
---------------------------
If you have written source code, just enter it's path\filename as a parameter
and it will be assembled. Currently there are no switches. You don't even
specify object filename - it will have same path\name, but the .COM extension.
Remember it is an Atari executable, so don't run it on PC!
It's a good idea to give the .ASX extension to your source, because
it is default, so you don't have to specify it.
If assembling is successful, X-Asm displays number of lines assembled
and bytes written and returns exitcode 0.
If source is incorrect, X-Asm displays ONLY FIRST encountered error
and returns exitcode 1.
X-ASM LANGUAGE STRUCTURE
========================
Lines of source code may be:
- empty lines - ignored, of course
- comments - ignored, too
- statements - not ignored :-)
Comment lines must have one of the following characters in the FIRST column
of the line: * ; |
Note that spaces at the beginning of comment line are NOT allowed.
Numbers
-------
A number can be:
- a 16-bit decimal number -12345
- a 16-bit hexadedecimal number $abcd
- a 16-bit binary number %10100101
- a character 'a'
- a hardware register ^31
- an origin counter *
I think only 'a hardware register' should be explained. It is a short way
of accessing Atari hardware registers:
^0x means $d00x
^1x means $d01x
^2x means $d20x
^3x means $d30x
^4x means $d40x
where x is a hexadecimal digit.
Expressions
-----------
Expressions are numbers combined with operators. Currently there are only
two operators: '+' for addition and '-' for subtraction. You can't use
brackets in expressions.
Some valid expressions:
5
-1+2+3-4
*+4
'a'-'A'
17-$10+label
Statements
----------
A statement is divided into four fields: a label field, an operation field,
an operand field, and a comment field. There should be at least one space
between every two fields and there can't be any space within a field.
1. label field
This field is optional. It is required only by the EQU directive.
Specyfying this field definies a label. Defined label represents a 16-bit
signed or unsigned integer.
Label's name must begin in column 1 and can contain letters, digits
and underscores (_). Digit can't be label's first character. Label's name
can be as long as you want and all the characters are meaningful!
Defining a label without using EQU makes it equal to current value
of the origin counter.
Every label can be defined only once.
Note that in Quick Assembler only 6 leading characters are recognized.
It means that label12 and label13 are the same label! They are not the same
for X-Asm and thus some programs may not compile well for this reason.
2. operation field
Operation field is the only field which is always required.
You have to put one or more spaces or tab characters between label
and operation field. If no label is defined, line must start with a blank.
Operation field is always 3 letters long. It can be:
a. a 6502 processor command
b. a compiler directive
c. a pseudo-command
a. 6502 command
One of 56 well known processor commands.
b. compiler directive
One of the following:
EQU - define a label by assigning a value of an expression to the label.
Note that label represents a number, not a text macro.
Examples:
five equ 5
ten equ five+five
ORG - set new origin counter
Example:
org $600 code will be located starting from $0600
table org *+100 'table' points to 100 bytes of uninitialized data
DTA - define data
You may define:
* numbers
- bytes: b(200)
- words: a(10000)
- low bytes of words: l(511) defines byte 255
- high bytes of words: h(511) defines byte 1
You may enter many numbers in parentheses and combine different types of data
in single line.
You may also define a sinus table. Enter this expression inside brackets:
sin(centre,amp,size,first,last)
where:
- centre is a number which is added to every value of sinus
- amp is the amplitude of sinus
- size is the period of sinus
- first,last define range of values in the table.
They are optional. Default are 0,size-1.
Example: dta a(sin(0,1000,256,0,63)) defines table of 64 words representing
a quarter of sinus with amplitude of 1000.
* text strings
- ASCII strings: c'Text'
- ANTIC strings: d'Text'
A character string consists of any of characters surrounded by single
quotation marks. Within a string, a single quotation mark character is
represented by two succesive single quotation marks.
Placing a '*' character after a string inverts bit 7 in every byte of string.
Examples of DTA:
dta b(2,5),a(1000,-1),l(12345,sin(0,127,256))
dta d'ANTIC'*,c'It''s a string',b(155)
ICL - include another source file
Specifies another file to be included in the assembly as if the contests of
the referenced file appeared in place of the ICL statement. The included file
may contain other ICL statements.
Examples:
icl 'macros.asx'
icl 'c:\atari\xasm\fileio.asx'
END - end assembling of file
Remaining part of the file is not assembled. If this statement does not occur,
assembler stops assembling when encounters end of file.
Example:
end
OPT - set assembling options
This directive is implemented only for compatibility with Quick Assembler.
It is ignored by X-Asm, so don't use it in your programs.
INS - insert contents of file
Copies every byte of specified file into object file and moves origin counter,
as if these bytes were defined with DTA.
Examples:
ins 'picture.raw'
ins 'tables.dat'
RUN - generate run address
The Atari executable program should have run address specified. Remember that
a program may be loaded in many areas of memory and started from any address.
run addr
is equivalent to:
org $2e0
dta a(addr)
Examples:
run start
run program
INI - generate init address
The Atari executable program may have some routines which are executed during
loading process. There may be many init blocks in one file.
Examples:
ini init
ini showpic
c. pseudo-command
It is something like built-in macro. It replaces two or more standard
processor command. Note that it is not an illegal instruction and works
on typical 6502.
ADD - addition without carry
If you have some experience with programming 6502, you must have noticed that
you had to use a CLC before ADC. X-Asm does it for you. ADD is simply two
instructions: CLC and ADC.
SUB - subtraction
It is SEC and SBC.
JNE, JEQ, JCC, JCS, JPL, JMI, JVC, JVS - conditional jumps
These are a kind of 'long' branches. While standard branches (BNE, BEQ) have
range of -128..+127, these jumps have range of all 64 kB.
For example: a JNE DEST is replaced with:
BEQ *+5
JMP DEST
As you see these pseudo-instructions are 5 bytes long.
INW - increment word
It is a 16-bit memory increment command. An INW DEST will be replaced by:
INC DEST
BNE _skip
INC DEST+1
_skip equ *
The '_skip' label is not declared of course.
3. Operand
It depends on the operation field. Some statements don't need an operand and
thus there is no operand field there. Other statements require some special
kind of operand, for example DTA and ICL.
6502 commands require operand depending on the addressing mode.
Addressing modes should be entered in standard convention except
the accumulator addressing mode, which should be marked with a '@' character.
There are two extra addressing modes: < and >. They are assembled to
immediate addressing mode (#), but low/high byte of word is used rather than
byte value.
In absolute addressing modes, X-Asm examines expression and uses zero-page
addressing mode if it thinks it is possible to do it. You may also specify
the mode by yourself, using 'a:' and 'z:' prefixes.
Examples:
nop
asl @
lda >$1234 assembled to lda #$12
lda $100,x
lda a:0 generates 16-bit address
jmp ($0a)
lda ($80),y
4. Comment
Does not need a comment :-)
Problems
--------
These notes may help you:
* No spaces are allowed within a field.
label equ 1 + 2
causes label to be equal 1 ('+ 2' is treated as a comment).
* Only addition and subtraction can be used as operators in expressions
* < and > represent addressing modes rather than LOW and HIGH operators.
You specify 'lda <table', not 'lda #<table' like in most 6502 assemblers.
* Label definition does not include a colon
label: lda ^4b ERROR - colon after label name
* Signed bytes are not supported, only signed words.
For example: if you want to define byte -5, use 'dta l(-5)'
* Be careful when specifying ORGs
You may have not specified ORG at all or specified address is invalid.
You may have located your code where it shouldn't be. You can't use:
- memory under ROM unless ROM is disabled
- memory reserved for OS if it is in use
- memory occupied by other parts of program
- memory where program places data, tables, variables
* Exactly one run address should be specified
Remember that unlike in other assemblers
end start
does not tell the assembler that 'start' is the run address (it is a comment).
You must specify the run address with RUN directive.
* X-Asm reads source twice (in pass 1 and pass 2)
This allows forward references, but not too complex.
Keep in mind that assembler should know all the values in second pass.
Example:
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
These values could be fixed in 2 passes.
But if you insert following statement as first line
three equ one+two
X-Asm will generate an error because it doesn't know the value of 'three' in
second pass.
* X-Asm displays only first error
When you correct an error don't be surpised if you get another one.
* If you encounter X-Asm works improperly, please let me know.
===