mirror of
https://github.com/VARCem/asm6502.git
synced 2026-09-23 07:06:13 +00:00
update documentation
This commit is contained in:
149
README.txt
149
README.txt
@@ -21,14 +21,13 @@ Copyright 2022-2023 by Bernd Boeckmann
|
||||
|
||||
ASM6502 is a small two-pass assembler for the MOS Technology 6502
|
||||
microprocessor used in many home computers of the 8-bit era. It
|
||||
consists of under 2K lines of C code and can be built with compilers
|
||||
consists of under 3K lines of C code and can be built with compilers
|
||||
conformant to the C89 standard.
|
||||
|
||||
ASM6502 implements some advanced features, like local labels, the
|
||||
ability to produce listing files, and the optimization of opcodes.
|
||||
In its current state, it is a usable assembler confirmed to generate
|
||||
the correct code for all supported instructions and addressing mode
|
||||
combinations. Due to the small size, macros are not supported.
|
||||
It is able to produce byte-exact replicas of the Commodore C64
|
||||
Kernal and BASIC ROMs. The one big feature missing is macro support.
|
||||
|
||||
The assembler outputs plain binary files.
|
||||
|
||||
@@ -75,12 +74,12 @@ Copyright 2022-2023 by Bernd Boeckmann
|
||||
|
||||
The task of an assembler is to translate an _assembler
|
||||
source_ containing human readable _instructions_ to a _binary
|
||||
representation_ a processor understands. This binary representation
|
||||
is called _machine code_. There is a one-to-one mapping between the
|
||||
human readable instructions contained in the assembler source and
|
||||
the generated machine code.
|
||||
representation_ the processor understands. This binary
|
||||
representation is called _machine code_. There is a one-to-one
|
||||
mapping between the human readable instructions contained in the
|
||||
assembler source and the generated machine code.
|
||||
|
||||
All instructions a processor understands is given a name, called
|
||||
Each instruction a processor understands is given a name, called
|
||||
_mnemonic_. This name is chosen so that it describes to the
|
||||
programmer what the instruction does. Every instruction is also
|
||||
assigned a numeric value, called the operation code or _opcode_.
|
||||
@@ -117,9 +116,8 @@ Copyright 2022-2023 by Bernd Boeckmann
|
||||
0002 0002 E8 2: INX
|
||||
|
||||
FPos indicates the position of the instructions regarding the output
|
||||
file. PC represents the _memory location_ or _address_ the code
|
||||
gets loaded to when executed. The executable code in memory is also
|
||||
called _image_.
|
||||
file. PC represents the _location_ or _address_ of the code while it
|
||||
is executed.
|
||||
|
||||
Let's further elaborate what the arguments to instructions may be.
|
||||
In the example above, `#42' is a numeric value that is directly used
|
||||
@@ -127,14 +125,14 @@ Copyright 2022-2023 by Bernd Boeckmann
|
||||
the mode the processor operates in is called _immediate addressing_
|
||||
mode. The `INX' instruction above implicitly operates on a register
|
||||
called X. For this reason it is called _implicit addressing_. Often,
|
||||
the argument specifies a memory location. This memory location may
|
||||
be specified with the beginning of the address space as a reference.
|
||||
In this case it is called _absolute addressing_ mode. If the memory
|
||||
location is specified relative to some other location we call it
|
||||
_relative addressing_ mode. Sometimes one does not want to encode a
|
||||
fixed memory location into the machine instruction, but instead use
|
||||
the content of some memory location as the address to operate on.
|
||||
This is called _indirect addressing_.
|
||||
the argument specifies a memory location. This memory location
|
||||
may be referenced to the start of the address space. In this case
|
||||
it is called _absolute addressing_ mode. If the memory location
|
||||
is specified relative to some other location we call it _relative
|
||||
addressing_ mode. Sometimes one does not want to encode a fixed
|
||||
memory location into the machine instruction, but instead use the
|
||||
content of some memory location as the address to operate on. This
|
||||
is called _indirect addressing_.
|
||||
|
||||
The sequence of instructions executed by the processor may be
|
||||
altered by the programmer utilizing special machine instructions.
|
||||
@@ -170,7 +168,7 @@ Copyright 2022-2023 by Bernd Boeckmann
|
||||
referred to as _identifier_.
|
||||
|
||||
Character sequences which by itself provide a value to the
|
||||
assembler, like the character sequence `42', which represents the
|
||||
assembler, like the character sequence `42' that represents the
|
||||
numeric value 42, are considered to be _literals_.
|
||||
|
||||
4 Syntax and Semantics
|
||||
@@ -199,10 +197,10 @@ Copyright 2022-2023 by Bernd Boeckmann
|
||||
4.3 Symbols
|
||||
|
||||
The assembler distinguishes two types of case-sensitive symbols:
|
||||
_labels_ and _variables_. A label stores the address of the current
|
||||
instruction or directive. It is defined at the beginning of a line
|
||||
by appending its name with a colon. The colon may be left out if the
|
||||
label name is not an instruction mnemonic.
|
||||
_labels_ and _variables_. A label stores the address of of the
|
||||
instruction or data it is currently assembling. It is defined at the
|
||||
beginning of a line by appending its name with a colon. The colon
|
||||
may be left out if the label name is not an instruction mnemonic.
|
||||
|
||||
A variable is defined by assigning an expression to it. In the
|
||||
following example, hello is a label, and CHROUT is a variable.
|
||||
@@ -216,18 +214,19 @@ Copyright 2022-2023 by Bernd Boeckmann
|
||||
is that of the expression assigned to it, unless it is forward-
|
||||
referenced.
|
||||
|
||||
Forward-referenced means that a symbol can be used in expressions
|
||||
Forward-referenced means that a symbol is used in an expression
|
||||
before it is defined. Forward-referenced symbols are _always_ of
|
||||
type word, regardless of what is assigned to them.
|
||||
|
||||
Labels may not be redefined. If a variable is assigned a value
|
||||
multiple times, it must always be the same value. Otherwise, it is
|
||||
an illegal redefinition.
|
||||
If a variable is assigned a value multiple times, it must always be
|
||||
the same value. Otherwise, it is an illegal redefinition. Labels may
|
||||
not be defined more than once.
|
||||
|
||||
Symbols may be defined locally by prepending them with @. They are
|
||||
associated with the previous non-local label defined. They may
|
||||
be referenced within expressions locally by @name or with their
|
||||
qualified name label@name outside their local scope. Example:
|
||||
Variables and labels may be defined locally by prepending their name
|
||||
with @. They are then associated with the previous non-local label
|
||||
defined. They may be referenced within expressions locally by @name
|
||||
or with their qualified name label@name outside their local scope.
|
||||
Example:
|
||||
|
||||
jmp hello@l ; fully qualified label reference
|
||||
hello:
|
||||
@@ -265,12 +264,12 @@ Copyright 2022-2023 by Bernd Boeckmann
|
||||
|
||||
'x' ; byte typed ASCII character code of x
|
||||
|
||||
The special symbol @ returns the current value of the program
|
||||
counter. The special symbol ? returns an undefined value of unknown
|
||||
type.
|
||||
The special symbol @ returns the address of the currently assembled
|
||||
instruction. The special symbol ? returns an undefined value of
|
||||
unknown type.
|
||||
|
||||
? ; undefined value
|
||||
@ ; current program counter
|
||||
@ ; current address
|
||||
|
||||
Label and variable names evaluate to their respective value.
|
||||
|
||||
@@ -295,7 +294,7 @@ Copyright 2022-2023 by Bernd Boeckmann
|
||||
- comparison operators: ==, !=, <, >, <=, >=
|
||||
|
||||
- unary low < and high > byte select, lossless unary conversion
|
||||
operators [b] and [w], unary logical negate .not
|
||||
operators [b] and [w], boolean not .not
|
||||
|
||||
4.4.3 Conversion operators
|
||||
|
||||
@@ -311,11 +310,11 @@ Copyright 2022-2023 by Bernd Boeckmann
|
||||
high-byte select operator > returns the high byte of a word-sized
|
||||
expression shifted eight bits to the right. It returns zero for
|
||||
byte-sized expressions. The resulting data type of both operators is
|
||||
byte. If applied to an undefined argument the result is undefined.
|
||||
byte. If applied to an undefined argument, the result is undefined.
|
||||
|
||||
4.4.5 Logical Operators
|
||||
|
||||
The comparison operators and the logical negate operator return 1 if
|
||||
The comparison operators and the boolean not operator return 1 if
|
||||
the comparison is true, else they return 0. The result is of type
|
||||
byte. If one or both arguments have an undefined value, the result
|
||||
is the undefined value.
|
||||
@@ -328,7 +327,7 @@ Copyright 2022-2023 by Bernd Boeckmann
|
||||
operators, the result value is undefined. Type inference is
|
||||
performed as such that if any of the arguments is of type word, the
|
||||
result is of type word. The result is also of type word if it would
|
||||
overflow the range of type byte.
|
||||
otherwise overflow the range of type byte.
|
||||
|
||||
Examples:
|
||||
|
||||
@@ -342,9 +341,10 @@ Copyright 2022-2023 by Bernd Boeckmann
|
||||
or none of them. A statement it either a variable definition, an
|
||||
instruction or a directive. Instructions and directives may be
|
||||
preceded by a label definition. Also, a label definition may stand
|
||||
for its own. Conditional statements are .IF, .ELSE, and .ENDIF. Each
|
||||
line may end with a comment. Comments are started by semicolon and
|
||||
ignored by the assembler.
|
||||
for its own. Conditional statements are .IF, .ELSE, and .ENDIF.
|
||||
These may not be preceded by a label. Each line may end with a
|
||||
comment. Comments are started by semicolon and ignored by the
|
||||
assembler.
|
||||
|
||||
start: ; line consisting only of a label
|
||||
loop: BNE loop ; label and instruction
|
||||
@@ -374,7 +374,9 @@ Copyright 2022-2023 by Bernd Boeckmann
|
||||
4.6.2 .BYTE directive
|
||||
|
||||
Produces one or more output bytes. The arguments are separated by a
|
||||
comma. Strings enclosed by " may also be used.
|
||||
comma. Numeric expressions or strings may be used as arguments. The
|
||||
values of numeric expressions must fit into a byte. Strings must be
|
||||
enclosed by ".
|
||||
|
||||
Example:
|
||||
|
||||
@@ -384,10 +386,11 @@ Copyright 2022-2023 by Bernd Boeckmann
|
||||
|
||||
4.6.3 .ECHO directive
|
||||
|
||||
Prints the arguments to standard output. Processed on second
|
||||
pass. The arguments may either be strings or numeric expressions,
|
||||
separated by comma. Numeric expressions may be prefixed by the
|
||||
format specifier [$] to output the number in hexadecimal format.
|
||||
Prints the arguments to standard output. This is done on the second
|
||||
assembler pass. The arguments may either be strings or numeric
|
||||
expressions, separated by comma. Numeric expressions may be prefixed
|
||||
by the format specifier [$] to output the number in hexadecimal
|
||||
format. Otherwise it is printed in decimal.
|
||||
|
||||
Example:
|
||||
|
||||
@@ -398,7 +401,7 @@ Copyright 2022-2023 by Bernd Boeckmann
|
||||
Starting from the current position of the output file, emits as many
|
||||
bytes as given by the first argument. If the second argument is
|
||||
given, the region is filled with its byte-sized value. Otherwise, it
|
||||
is filled with zero. The program counter is increased accordingly.
|
||||
is filled with zero. The address counter @ is increased accordingly.
|
||||
|
||||
Example:
|
||||
|
||||
@@ -408,14 +411,15 @@ Copyright 2022-2023 by Bernd Boeckmann
|
||||
4.6.5 .IF, .ELSE and .ENDIF directives
|
||||
|
||||
Conditionally assembles code depending on the value of the argument
|
||||
to .IF. If it is non-zero the code between .IF and .ENDIF is
|
||||
to .IF. If it is non-zero, the code between .IF and .ENDIF is
|
||||
assembled, or between .IF and .ELSE, if .ELSE is given. If the
|
||||
argument to .IF is zero the code between the corresponding .ELSE and
|
||||
.ENDIF is assembled, if .ELSE is specified. Otherwise the source
|
||||
between .IF and .ENDIF is skipped.
|
||||
argument to .IF is zero and .ELSE is specified, the code between
|
||||
.ELSE and .ENDIF is assembled. Otherwise the source between .IF and
|
||||
.ENDIF is skipped.
|
||||
|
||||
It is an error if the argument to .IF yields an undefined value. The
|
||||
conditional directives may _not_ be preceded by a label.
|
||||
It is an error if the argument to .IF yields an undefined value in
|
||||
pass one. The conditional directives may _not_ be preceded by a
|
||||
label.
|
||||
|
||||
Example:
|
||||
|
||||
@@ -432,8 +436,7 @@ Copyright 2022-2023 by Bernd Boeckmann
|
||||
4.6.6 .INCLUDE directive
|
||||
|
||||
Substitutes the directive with the contents of a file given by the
|
||||
argument. As a convention the extension of include-files should be
|
||||
.i65.
|
||||
argument for processing by the assembler.
|
||||
|
||||
Example:
|
||||
|
||||
@@ -449,17 +452,15 @@ Copyright 2022-2023 by Bernd Boeckmann
|
||||
If listing generation is disabled when an .INCLUDE statement is
|
||||
processed, .LIST inside the included file has no effect.
|
||||
|
||||
The listing generation flag is restored when the processing of an
|
||||
included file finished. If a .NOLIST statement is contained in an
|
||||
include file and the listing is activated for the parent file,
|
||||
listing generation is resumed after processing the include file from
|
||||
the line after the .INCLUDE line.
|
||||
A .NOLIST inside an include file does not propagate to the parent
|
||||
file.
|
||||
|
||||
4.6.8 .ORG directive
|
||||
|
||||
Sets the current program counter to the numeric value of the
|
||||
argument. Does not modify the offset into the output file. This
|
||||
means that .ORG can not be used to `jump around' in the output file.
|
||||
Sets the address counter for the currently processed instruction
|
||||
to the numeric value of the argument. Does not modify the offset
|
||||
into the output file. This means that .ORG can not be used to `jump
|
||||
around' in the output file.
|
||||
|
||||
Example:
|
||||
|
||||
@@ -534,11 +535,11 @@ Copyright 2022-2023 by Bernd Boeckmann
|
||||
|
||||
4.7.7 Zero-page X and Zero-page Y addressing
|
||||
|
||||
The address is encoded in the byte following the opcode and
|
||||
displaced by the contents for the X or Y register.
|
||||
The address is encoded in the byte following the opcode displaced by
|
||||
the contents for the X or Y register.
|
||||
|
||||
LDA $47,X ; load contents of address $47 displaced by X
|
||||
LDX >$4711,Y ; get contents of address $47 displaced by Y into X
|
||||
LDA $47,X ; A = contents of address $47 displaced by X
|
||||
LDX $11,Y ; X = load contents of address $47 displaced by Y
|
||||
|
||||
4.7.8 Indirect addressing
|
||||
|
||||
@@ -549,15 +550,13 @@ Copyright 2022-2023 by Bernd Boeckmann
|
||||
|
||||
JMP ($4711)
|
||||
|
||||
The following one is a syntax error because the assembler assumes
|
||||
The following one is a syntax error, because the assembler assumes
|
||||
indirect addressing mode instead of a sub-expression grouped by
|
||||
parentheses:
|
||||
|
||||
JMP (2+3)*1000
|
||||
|
||||
If one wants to start an expression with an opening parentheses,
|
||||
while not indicating indirect addressing to the assembler, one can
|
||||
write:
|
||||
To correct this, you may rewrite it as:
|
||||
|
||||
JMP +(2+3)*1000
|
||||
|
||||
@@ -997,4 +996,4 @@ A Instruction Reference
|
||||
|
||||
98 tya
|
||||
|
||||
[Di 18 Apr 16:44:54 2023]
|
||||
[So 23 Apr 19:33:58 2023]
|
||||
|
||||
@@ -20,9 +20,9 @@ Binaries are provided for Windows, DOS, and OS/2. A Unix make file is provided w
|
||||
|
||||
\C{intro}Introduction
|
||||
|
||||
ASM6502 is a small two-pass assembler for the MOS Technology 6502 microprocessor used in many home computers of the 8-bit era. It consists of under 2K lines of C code and can be built with compilers conformant to the C89 standard.
|
||||
ASM6502 is a small two-pass assembler for the MOS Technology 6502 microprocessor used in many home computers of the 8-bit era. It consists of under 3K lines of C code and can be built with compilers conformant to the C89 standard.
|
||||
|
||||
ASM6502 implements some advanced features, like local labels, the ability to produce listing files, and the optimization of opcodes. In its current state, it is a usable assembler confirmed to generate the correct code for all supported instructions and addressing mode combinations. Due to the small size, macros are not supported.
|
||||
ASM6502 implements some advanced features, like local labels, the ability to produce listing files, and the optimization of opcodes. It is able to produce byte-exact replicas of the Commodore C64 Kernal and BASIC ROMs. The one big feature missing is macro support.
|
||||
|
||||
The assembler outputs plain binary files.
|
||||
|
||||
@@ -63,9 +63,9 @@ The following listing contains a small sample program. It is the classic hello w
|
||||
|
||||
\C{concepts}Concepts and Terminology
|
||||
|
||||
The task of an assembler is to translate an \e{assembler source} containing human readable \e{instructions} to a \e{binary representation} a processor understands. This binary representation is called \e{machine code}. There is a one-to-one mapping between the human readable instructions contained in the assembler source and the generated machine code.
|
||||
The task of an assembler is to translate an \e{assembler source} containing human readable \e{instructions} to a \e{binary representation} the processor understands. This binary representation is called \e{machine code}. There is a one-to-one mapping between the human readable instructions contained in the assembler source and the generated machine code.
|
||||
|
||||
All instructions a processor understands is given a name, called \e{mnemonic}. This name is chosen so that it describes to the programmer what the instruction does. Every instruction is also assigned a numeric value, called the operation code or \e{opcode}. This is what gets written by the assembler as machine code to an output file. The opcode is interpreted by the the processor to decide what to do.
|
||||
Each instruction a processor understands is given a name, called \e{mnemonic}. This name is chosen so that it describes to the programmer what the instruction does. Every instruction is also assigned a numeric value, called the operation code or \e{opcode}. This is what gets written by the assembler as machine code to an output file. The opcode is interpreted by the the processor to decide what to do.
|
||||
|
||||
Beside the instruction itself, additional information may be required to process it. The additional information is provided in the source by one or more \e{arguments} following the mnemonic. In machine code this additional information is encoded in binary form following the opcode.
|
||||
|
||||
@@ -79,9 +79,9 @@ Beside generating an output file containing machine code, ASM6502 may also gener
|
||||
\c 0000 0000 69 2A 1: ADC #42
|
||||
\c 0002 0002 E8 2: INX
|
||||
|
||||
FPos indicates the position of the instructions regarding the output file. PC represents the \e{memory location} or \e{address} the code gets loaded to when executed. The executable code in memory is also called \e{image}.
|
||||
FPos indicates the position of the instructions regarding the output file. PC represents the \e{location} or \e{address} of the code while it is executed.
|
||||
|
||||
Let's further elaborate what the arguments to instructions may be. In the example above, \c{#42} is a numeric value that is directly used to do the addition. It is therefore called an \e{immediate} value, and the mode the processor operates in is called \e{immediate addressing} mode. The \c{INX} instruction above implicitly operates on a register called X. For this reason it is called \e{implicit addressing}. Often, the argument specifies a memory location. This memory location may be specified with the beginning of the address space as a reference. In this case it is called \e{absolute addressing} mode. If the memory location is specified relative to some other location we call it \e{relative addressing} mode. Sometimes one does not want to encode a fixed memory location into the machine instruction, but instead use the content of some memory location as the address to operate on. This is called \e{indirect addressing}.
|
||||
Let's further elaborate what the arguments to instructions may be. In the example above, \c{#42} is a numeric value that is directly used to do the addition. It is therefore called an \e{immediate} value, and the mode the processor operates in is called \e{immediate addressing} mode. The \c{INX} instruction above implicitly operates on a register called X. For this reason it is called \e{implicit addressing}. Often, the argument specifies a memory location. This memory location may be referenced to the start of the address space. In this case it is called \e{absolute addressing} mode. If the memory location is specified relative to some other location we call it \e{relative addressing} mode. Sometimes one does not want to encode a fixed memory location into the machine instruction, but instead use the content of some memory location as the address to operate on. This is called \e{indirect addressing}.
|
||||
|
||||
The sequence of instructions executed by the processor may be altered by the programmer utilizing special machine instructions. Some of these instructions modify this sequence unconditionally, and some alter it if a special condition is met. The instructions are called \e{jump} or \e{branching} instructions. The information of the \e{jump target} is encoded as address within the instruction. The assembler supports the programmer by letting him specify a jump target by giving it a name, called \e{label}. In the introductory example, \c{basic_upstart}, \c{start}, and \c{hello} are labels.
|
||||
|
||||
@@ -91,12 +91,11 @@ Using forward-references can sometimes lead to non-optimal machine code, because
|
||||
|
||||
Beside labels the programmer may also define \e{variables}. Variables may be assigned any kind of mathematical expression. Variables and labels are also called \e{symbols}, and the name identifying them is referred to as \e{identifier}.
|
||||
|
||||
Character sequences which by itself provide a value to the assembler, like the character sequence \c{42}, which represents the numeric value 42, are considered to be \e{literals}.
|
||||
Character sequences which by itself provide a value to the assembler, like the character sequence \c{42} that represents the numeric value 42, are considered to be \e{literals}.
|
||||
|
||||
\C{syntax}Syntax and Semantics
|
||||
|
||||
The following chapter describes the data model and the syntax accepted by the
|
||||
assembler.
|
||||
The following chapter describes the data model and the syntax accepted by the assembler.
|
||||
|
||||
\H{input-files}Input Files
|
||||
|
||||
@@ -112,7 +111,7 @@ Two data types are known to the assembler:
|
||||
|
||||
\H{symbols}Symbols
|
||||
|
||||
The assembler distinguishes two types of case-sensitive symbols: \e{labels} and \e{variables}. A label stores the address of the current instruction or directive. It is defined at the beginning of a line by appending its name with a colon. The colon may be left out if the label name is not an instruction mnemonic.
|
||||
The assembler distinguishes two types of case-sensitive symbols: \e{labels} and \e{variables}. A label stores the address of of the instruction or data it is currently assembling. It is defined at the beginning of a line by appending its name with a colon. The colon may be left out if the label name is not an instruction mnemonic.
|
||||
|
||||
A variable is defined by assigning an expression to it. In the following example, hello is a label, and CHROUT is a variable.
|
||||
|
||||
@@ -121,11 +120,11 @@ A variable is defined by assigning an expression to it. In the following example
|
||||
|
||||
Labels and variables may be of type byte or word. A label is of type byte if it is assigned an address within the first 256 bytes (zero page). Otherwise, it is of type word. The data type of a variable is that of the expression assigned to it, unless it is forward-referenced.
|
||||
|
||||
Forward-referenced means that a symbol can be used in expressions before it is defined. Forward-referenced symbols are \e{always} of type word, regardless of what is assigned to them.
|
||||
Forward-referenced means that a symbol is used in an expression before it is defined. Forward-referenced symbols are \e{always} of type word, regardless of what is assigned to them.
|
||||
|
||||
Labels may not be redefined. If a variable is assigned a value multiple times, it must always be the same value. Otherwise, it is an illegal redefinition.
|
||||
If a variable is assigned a value multiple times, it must always be the same value. Otherwise, it is an illegal redefinition. Labels may not be defined more than once.
|
||||
|
||||
Symbols may be defined locally by prepending them with \cw{@}. They are associated with the previous non-local label defined. They may be referenced within expressions locally by \cw{@name} or with their qualified name
|
||||
Variables and labels may be defined locally by prepending their name with \cw{@}. They are then associated with the previous non-local label defined. They may be referenced within expressions locally by \cw{@name} or with their qualified name
|
||||
\cw{label@name} outside their local scope. Example:
|
||||
|
||||
\c jmp hello@l ; fully qualified label reference
|
||||
@@ -157,10 +156,10 @@ A character enclosed by \cw{'} is evaluated to its ASCII value.
|
||||
|
||||
\c 'x' ; byte typed ASCII character code of x
|
||||
|
||||
The special symbol \cw{@} returns the current value of the program counter. The special symbol \cw{?} returns an undefined value of unknown type.
|
||||
The special symbol \cw{@} returns the address of the currently assembled instruction. The special symbol \cw{?} returns an undefined value of unknown type.
|
||||
|
||||
\c ? ; undefined value
|
||||
\c @ ; current program counter
|
||||
\c @ ; current address
|
||||
|
||||
Label and variable names evaluate to their respective value.
|
||||
|
||||
@@ -181,7 +180,7 @@ The supported operations from highest to lowest precedence are:
|
||||
|
||||
\b comparison operators: \cw{==}, \cw{!=}, \cw{<}, \cw{>}, \cw{<=}, \cw{>=}
|
||||
|
||||
\b unary low \cw{<} and high \cw{>} byte select, lossless unary conversion operators \cw{[b]} and \cw{[w]}, unary logical negate \cw{.not}
|
||||
\b unary low \cw{<} and high \cw{>} byte select, lossless unary conversion operators \cw{[b]} and \cw{[w]}, boolean not \cw{.not}
|
||||
|
||||
\S{}Conversion operators
|
||||
|
||||
@@ -189,17 +188,17 @@ The convert to byte \cw{[b]} and convert to word \cw{[w]} operators change the d
|
||||
|
||||
\S{}Byte-select operators
|
||||
|
||||
The low-byte select operator \cw{<} returns the low byte of a word-sized expression, or the unmodified value of a byte-sized expression. The high-byte select operator \cw{>} returns the high byte of a word-sized expression shifted eight bits to the right. It returns zero for byte-sized expressions. The resulting data type of both operators is byte. If applied to an undefined argument the result is undefined.
|
||||
The low-byte select operator \cw{<} returns the low byte of a word-sized expression, or the unmodified value of a byte-sized expression. The high-byte select operator \cw{>} returns the high byte of a word-sized expression shifted eight bits to the right. It returns zero for byte-sized expressions. The resulting data type of both operators is byte. If applied to an undefined argument, the result is undefined.
|
||||
|
||||
\S{}Logical Operators
|
||||
|
||||
The comparison operators and the logical negate operator return 1 if the comparison is true, else they return 0. The result is of type byte. If one or both arguments have an undefined value, the result is the undefined value.
|
||||
The comparison operators and the boolean not operator return 1 if the comparison is true, else they return 0. The result is of type byte. If one or both arguments have an undefined value, the result is the undefined value.
|
||||
|
||||
\S{}Arithmetic Operators
|
||||
|
||||
The usual semantics for the arithmetic operators apply.
|
||||
|
||||
If there is an undefined argument to one of the arithmetic operators, the result value is undefined. Type inference is performed as such that if any of the arguments is of type word, the result is of type word. The result is also of type word if it would overflow the range of type byte.
|
||||
If there is an undefined argument to one of the arithmetic operators, the result value is undefined. Type inference is performed as such that if any of the arguments is of type word, the result is of type word. The result is also of type word if it would otherwise overflow the range of type byte.
|
||||
|
||||
Examples:
|
||||
|
||||
@@ -210,7 +209,7 @@ Examples:
|
||||
|
||||
\H{line-format}Line Format
|
||||
|
||||
A line may either contain a statement or a conditional statement or none of them. A statement it either a variable definition, an instruction or a directive. Instructions and directives may be preceded by a label definition. Also, a label definition may stand for its own. Conditional statements are \cw{.IF}, \cw{.ELSE}, and \cw{.ENDIF}. Each line may end with a comment. Comments are started by semicolon and ignored by the assembler.
|
||||
A line may either contain a statement or a conditional statement or none of them. A statement it either a variable definition, an instruction or a directive. Instructions and directives may be preceded by a label definition. Also, a label definition may stand for its own. Conditional statements are \cw{.IF}, \cw{.ELSE}, and \cw{.ENDIF}. These may not be preceded by a label. Each line may end with a comment. Comments are started by semicolon and ignored by the assembler.
|
||||
|
||||
\c start: ; line consisting only of a label
|
||||
\c loop: BNE loop ; label and instruction
|
||||
@@ -234,7 +233,7 @@ Example:
|
||||
|
||||
\S{}.BYTE directive
|
||||
|
||||
Produces one or more output bytes. The arguments are separated by a comma. Strings enclosed by " may also be used.
|
||||
Produces one or more output bytes. The arguments are separated by a comma. Numeric expressions or strings may be used as arguments. The values of numeric expressions must fit into a byte. Strings must be enclosed by \cw{"}.
|
||||
|
||||
Example:
|
||||
|
||||
@@ -244,7 +243,7 @@ Example:
|
||||
|
||||
\S{}.ECHO directive
|
||||
|
||||
Prints the arguments to standard output. Processed on second pass. The arguments may either be strings or numeric expressions, separated by comma. Numeric expressions may be prefixed by the format specifier \cw{[$]} to output the number in hexadecimal format.
|
||||
Prints the arguments to standard output. This is done on the second assembler pass. The arguments may either be strings or numeric expressions, separated by comma. Numeric expressions may be prefixed by the format specifier \cw{[$]} to output the number in hexadecimal format. Otherwise it is printed in decimal.
|
||||
|
||||
Example:
|
||||
|
||||
@@ -252,7 +251,7 @@ Example:
|
||||
|
||||
\S{}.FILL directive
|
||||
|
||||
Starting from the current position of the output file, emits as many bytes as given by the first argument. If the second argument is given, the region is filled with its byte-sized value. Otherwise, it is filled with zero. The program counter is increased accordingly.
|
||||
Starting from the current position of the output file, emits as many bytes as given by the first argument. If the second argument is given, the region is filled with its byte-sized value. Otherwise, it is filled with zero. The address counter \cw{@} is increased accordingly.
|
||||
|
||||
Example:
|
||||
|
||||
@@ -261,9 +260,9 @@ Example:
|
||||
|
||||
\S{}.IF, .ELSE and .ENDIF directives
|
||||
|
||||
Conditionally assembles code depending on the value of the argument to \cw{.IF}. If it is non-zero the code between \cw{.IF} and \cw{.ENDIF} is assembled, or between \cw{.IF} and \cw{.ELSE}, if \cw{.ELSE} is given. If the argument to \cw{.IF} is zero the code between the corresponding \cw{.ELSE} and \cw{.ENDIF} is assembled, if \cw{.ELSE} is specified. Otherwise the source between \cw{.IF} and \cw{.ENDIF} is skipped.
|
||||
Conditionally assembles code depending on the value of the argument to \cw{.IF}. If it is non-zero, the code between \cw{.IF} and \cw{.ENDIF} is assembled, or between \cw{.IF} and \cw{.ELSE}, if \cw{.ELSE} is given. If the argument to \cw{.IF} is zero and \cw{.ELSE} is specified, the code between \cw{.ELSE} and \cw{.ENDIF} is assembled. Otherwise the source between \cw{.IF} and \cw{.ENDIF} is skipped.
|
||||
|
||||
It is an error if the argument to \cw{.IF} yields an undefined value. The conditional directives may \e{not} be preceded by a label.
|
||||
It is an error if the argument to \cw{.IF} yields an undefined value in pass one. The conditional directives may \e{not} be preceded by a label.
|
||||
|
||||
Example:
|
||||
|
||||
@@ -278,7 +277,7 @@ In listing files, the unprocessed lines are indicated by a minus after the line
|
||||
|
||||
\S{}.INCLUDE directive
|
||||
|
||||
Substitutes the directive with the contents of a file given by the argument. As a convention the extension of include-files should be \cw{.i65}.
|
||||
Substitutes the directive with the contents of a file given by the argument for processing by the assembler.
|
||||
|
||||
Example:
|
||||
|
||||
@@ -290,11 +289,11 @@ If a listing file is given via command line, listing generation is initially ena
|
||||
|
||||
If listing generation is disabled when an \cw{.INCLUDE} statement is processed, \cw{.LIST} inside the included file has no effect.
|
||||
|
||||
The listing generation flag is restored when the processing of an included file finished. If a \cw{.NOLIST} statement is contained in an include file and the listing is activated for the parent file, listing generation is resumed after processing the include file from the line after the \cw{.INCLUDE} line.
|
||||
A \cw{.NOLIST} inside an include file does not propagate to the parent file.
|
||||
|
||||
\S{}.ORG directive
|
||||
|
||||
Sets the current program counter to the numeric value of the argument. Does not modify the offset into the output file. This means that .ORG can not be used to \q{jump around} in the output file.
|
||||
Sets the address counter for the currently processed instruction to the numeric value of the argument. Does not modify the offset into the output file. This means that .ORG can not be used to \q{jump around} in the output file.
|
||||
|
||||
Example:
|
||||
|
||||
@@ -353,10 +352,10 @@ The address is encoded in the word following the opcode and displaced by the con
|
||||
|
||||
\S{}Zero-page X and Zero-page Y addressing
|
||||
|
||||
The address is encoded in the byte following the opcode and displaced by the contents for the X or Y register.
|
||||
The address is encoded in the byte following the opcode displaced by the contents for the X or Y register.
|
||||
|
||||
\c LDA $47,X ; load contents of address $47 displaced by X
|
||||
\c LDX >$4711,Y ; get contents of address $47 displaced by Y into X
|
||||
\c LDA $47,X ; A = contents of address $47 displaced by X
|
||||
\c LDX $11,Y ; X = load contents of address $47 displaced by Y
|
||||
|
||||
\S{}Indirect addressing
|
||||
|
||||
@@ -364,11 +363,11 @@ The word-sized address is stored in the memory location given by the word-sized
|
||||
|
||||
\c JMP ($4711)
|
||||
|
||||
The following one is a syntax error because the assembler assumes indirect addressing mode instead of a sub-expression grouped by parentheses:
|
||||
The following one is a syntax error, because the assembler assumes indirect addressing mode instead of a sub-expression grouped by parentheses:
|
||||
|
||||
\c JMP (2+3)*1000
|
||||
|
||||
If one wants to start an expression with an opening parentheses, while not indicating indirect addressing to the assembler, one can write:
|
||||
To correct this, you may rewrite it as:
|
||||
|
||||
\c JMP +(2+3)*1000
|
||||
|
||||
|
||||
Reference in New Issue
Block a user