0 ratings0% found this document useful (0 votes) 163 views283 pages6502 Assembly Language (283pages) Programming Commodore 64
Programming The C64 in 6502 Assembler
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content,
claim it here.
Available Formats
Download as PDF or read online on Scribd
TT baie
i eee Ld A
0
SO
i;
chee Fs
e113 -
ey
.
bbe eee
. of eee rr Hi seeeetet
Mecca JE ||| TR
éComputers
$14.95
Boost the power and performance of your micro with
902
ASSEMBLY LANGUAGE
PROGRAMMING
A SELF-TEACHING GUIDE
Assembly language programming is
the key to writing faster, more sophis-
ticated programs that tap the full
power of your microcomputer. This
dynamic guide shows you how to
put the power and efficiency of this
programming tool—previously avail-
able only to professionals—to work
for you. The format is self-paced and
self-instructional, and the crystal-
clear coverage is equally applicable
to Apple®, Atari®, and Commodore
microcomputers—in fact to any
machine based on the 6502 micro-
processor chip.
From a discussion of the character-
istics and features of 6502 Assembly
Language, the authors take you step
by step through the entire set of as-
sembly language instructions. You'll
get hundreds of opportunities to
practice coding typical routines and
to check and correct your errors.
You'll master techniques for handling
routine operations, conditional com-
mands, assembly language logic,
subroutines, numeric manipulation,
and more.
Scores of sample programs demon-
strate how the instructions are used
in practice. Abundant summaries and
self-tests reinforce the material every
step of the way. And, because the
book requires only minimal knowl-
edge of programming, even compu-
ter novices can easily add the funda-
mentals of assembly language to
their repertoire.
Judi N. Fernandez and Ruth Ashley
are Co-Presidents of DuoTech, Inc.
They are co-authors of three other
bestselling Self-Teaching Guides.
Donna N. Tabler is a programmer/
analyst with the Naval Air Rework
Facility.
More than a million people
have learned to program and
use microcomputers with Wiley
Self-Teaching Guides. Look for
them at your favorite
bookshop or computer
store!
JOHN WILEY & SONS, INC.
605 Third Avenue, New York, N.Y. 10158
New York @ Chichester # Brisbane
Toronto * Singapore
Apple® is a registered trademark of Apple Computer, Inc.
‘Atari® is a registered trademark of Atari, Inc.
ISBN 0 471 86120-0
Cover Photography: Shiah Grumet6502 ASSEMBLY
LANGUAGE
PROGRAMMING
Judi N. Fernandez
Donna N. Tabler
Ruth Ashley
JOHN WILEY & SONS, INC.
lew York « Chichester + Brisbane + Toronto + SingaporeHow To Use This Book
This Self-Teaching Guide consists of 12 chapters that have been carefully designed
to introduce you to 6502 Assembly Language and to help you develop useful pro-
gramming skills. We have made every effort to organize the material in the best
possible sequence to learn as quickly as possible, You will first learn to code easy
programs, with increasingly more complex programs following, until you have
mastered the language.
Each chapter begins with a short introduction followed by objectives that
outline what you can expect to learn. A Self-Test at the end allows you to measure
your learning and practice what you have studied. Each chapter also contains a
review that summarizes the material in the chapter.
‘The body of each chapter is divided into frames—short numbered sections in
which information is presented or reviewed, followed by questions that ask you to
apply the material. ‘The correct answers are given immediately after the questions.
As you work through the book, use a folded paper or a card to cover the correct
answer until you have written yours. And be sure you actually write each response,
especially when the activity involves coding Assembly Language instructions. Only
by actually writing out the instructions and checking them carefully can you get the
most from this Self-Teaching Guide.
viiContents
Chapter
Chapter
Chapter
Chapter
Chapter
Chapter
Chapter
Chapter
Chapter
8
9
Chapter 10
Chapter 11
Chapter 12
How To Use This Book
Introduction
Number Systems and Data Representation
Instruction Format
Operand Formats
Elementary Instruction Set
Assembler Directives
Conditional Instructions
Logical Operations
The Stack
Subroutines
Numeric Manipulation
Additional Instructions
Appendix A
Appendix B
Appendix C
Appendix D
Index
vii
9
47
61
107
1
173
193
203
231
263 |
269
270
272
274
275CHAPTER ONE
INTRODUCTION
Before you can understand and code instructions, you should know some basic con-
cepts of the language. You should also know how the microcomputer works and
what it is.
In this chapter, we'll discuss 6502 Assembly Language and what types of pro-
grams it can be used for. We'll also compare it to other computer languages. We'll
talk about the 6502 microprocessor itself—what makes up the microprocessor and
how data is stored,in the computer in bits and bytes. You'll also learn what the
registers are and what they are used for in a 6502 microcomputer.
When you complete this chapter, you'll be able to:
«classify 6502 Assembly Language’s level and use;
* identify the size and characteristics of bits and bytes;
* name the 6502 registers and their functions.
1, 6502 Assembly Language is used to program computers that contain 6502
microprocessors made by MOS Technology, Inc. and others, or any computer that
has a 6502 assembler. An assembler is a program that translates Assembly
Language into the correct machine language for the processor. If the processor is a
6502, then the assembler would translate 6502 Assembly Language into 6502
machine language.
Computer languages are usually categorized as low-level or high-level. A low.
level language is very machine-oriented; the lowest level language is the machine's
own language, which is comprised entirely of digits. A high-level language is
oriented more to humans; the instructions use English words or abbreviations and
English-like syntax.
‘Assembly Languages are always low-level languages. The language of an
assembler is very close to the actual machine language, but uses alphanumeric codes
instead of digits. (Alphanumeric code is made up of letters, numbers, and symbols
such as *.)2 _ 6502 ASSEMBLY LANGUAGE PROGRAMMING
(a) Which of the following describe 6502 Assembly Language? (More than one
answer is correct.)
——_——_ low-level
—_——_ high-level
———_ uses only digits
uses alphanumeric codes
uses English-like words and phrases
(b) Which of the following types of computers can be programmed using 6502
Assembly Language?
any computer
any computer that has a 6502 microprocessor and an assembler pro-
gram
any microcomputer
(c) See if you can identify the following instructions as machine language,
Assembly Language, or high-level language.
ADD 1 TO COUNTER
000 000 100 011 000 110.
ADC #1
{a) low-level, uses alphanumeric codes; (b) any computer that has a 6502
microprocessor and an assembler program; (c) high-level, machine. Assembly
2, You've probably heard of such high-level languages as COBOL, FORTRAN,
and BASIC. These languages have the advantages of being easy to learn and use;
but there are disadvantages. A high-level program must be translated into machine
language before it can be used. The translation is done by a program called an inter-
preter or a compiler. This compilation step is time-consuming. Also, the machine-
language program produced by the compiler is never the most efficient program
possible. One high-level instruction, such as ADD, may be translated into ten or
more machine-language instructions.INTRODUCTION 3
When you use Assembly Language, you have to think less like a human and
more like a computer. For example, to add two numbers you must:
1. move the first number to a special place (the accumulator);
2. add the second number to it;
3. make sure the result isn’t too large for the accumulator (check for overflow);
4
5.
6.
do something about overflow if it occurs;
check and set the sign (positive or negative) of the result;
store the result in memory.
Assembly Language programs are also translated, but it's a much simpler pro-
cess called assembling. Assembling is a one-to-one translation of the alphanumeric
instructions into their machine language counterparts. So when you code in
Assembly Language, you're virtually coding in machine language. The alphanumeric
codes save you the bother of using the digital form of the instructions.
By coding at the machine Jevel, you can code a much more efficient program
than a compiler can produce. This is one advantage of using Assembly Language.
Another advantage is that you have more control over the computer. Instructions
exist at the Assembly-Language level that have no high-level equivalents. They
allow you to access and control computer functions at a very minute level. For ex-
ample, only in Assembly Language can you directly address a 6502 register, such as
the accumulator that is used for arithmetic.
Match the languages with their characteristics.
(a) Assembly 1. more efficient
2. less efficient
__— b) hightevel (COBOL, 3. compiled
FORTRAN, BASIC, 4. assembled
ete.)
5. more control
6. easier to learn and use
7. interpreted
(a) 1,4,5; (b) 2,3,6,7
3. When do you use Assembly Language? Some people use it all the time. but
most people use it when they're writing system programs as opposed to application
programs.
‘An application program is a program that solves some sort of problem for a
user. If your computer is in a business setting, then typical applications might be
payroll and inventory. If your computer is in a scientific setting, then typical ap-
plications might be statistical analysis and graph plotting.46502 ASSEMBLY LANGUAGE PROGRAMMING
In contrast, a system program is one that solves a problem for the computer
system itself, System programs are frequently used by programmers, computer
operators, and other computer programs. (An application program will call a system
program to read data from a terminal, for example.) Typical system programs are:
‘* input/output (1/0) routines that transfer data between peripheral devices
and main storage. (A peripheral device is a device that is attached by
cable to the main part of the computer; terminals, printers, disk, and tape
units may be peripheral devices.)
© interpreters and compilers that translate high-level code into machine
language.
+ librarians that organize disk files and keep up-to-date directories.
‘An application program may be used once a week or even once a day. A
system program may be used several times an hour. Some of the more important
system programs, such as the I/O routines, are used several times a second, It’s
critical that a system program be as efficient as possible. And that’s one reason we
use Assembly Language to code system programs, even when we have high-level
languages available to us. Another reason is to take advantage of that extra
measure of control that’s available with Assembly Language and not with high-level
languages. System programs frequently require us to make full use of the
‘computer’s capabilities.
Match the two types of programs with their characteristics.
—— a) system programs 1. typically used by non‘computer
staff such as accounting depart-
ment, research staff
— |b) application programs 2. _ typically used by computer pro-
graramers and operators
3. frequently used by other pro-
grams
4, solves computer problems
solves user problems
6. typically coded in Assembly
Language
7. typically coded in high-level
language
8. commonly used on daily,
weekly, or monthly basis
9. may be used several times per
minute
(©) List two reasons that we usually use Assembly Language for system programs.INTRODUCTION 5
(a) 2,3,4,6,9; (b) 1,5,7,8; (c) efficiency and control
Any low-level language is involved with the physical structure (architecture) of
the system it programe. Before you can begin learning to code Assembly Language
instructions, you need to know more about the microprocessor itself. In the next
section of this chapter, we'll explore the critical details of the 6502 chip.
BITS AND BYTES
4, A microprocessor is an integrated cireuit inside the microcomputer that con-
tains the logic that makes the rest of the computer work. The microprocessor con-
tains some control circuits and special storage areas called registers. Main storage
{also called internal memory, main memory, internal storage, or core memory) is
located on separate chips external to the microprocessor itself. The registers and
main storage are both used to store data while it's being worked on.
Data is stored in bytes (pronounced.“*bites”). A byte is the amount of space it
takes to store one alphanumeric character such as the letter ‘A,’ the number ‘6,’ or
the symbol ‘&,’ or the space to store a value up to 255. The size of a storage area is
usually given in terms of the number of bytes it can hold. 1K stands for 1024 bytes,
or 2°° bytes.
(a) Which of the following are considered part of the microprocessor?
_——_ main storage
—— registers
——— peripheral devices
—— logic circuits
(b) If your computer has 20K bytes of main storage, how many characters can it
hold? (K stands for 1024.)
(c) Ifa register holds one byte, how many characters can it hold?.
(a) registers and logic circuits; (b) 20,480 characters: (c) one
Decimal Binary
co oO
4 4
2 10
3 11
4 100
5 101
6 110
7 “444
8 1000
9 1001
10 1010
FIGURE 1, Binary Equivalents6 6502 ASSEMBLY LANGUAGE PROGRAMMING
5. To store a character in a byte, it must be encoded as a binary number. In this
frame, we'll explain what binary numbers are and why we have to use them,
‘The binary number system has a base of two, instead of ten as the decimal
number system hes. It has only two digits—zero and one. Figure 1 shows the binary
equivalents for the first ten decimal numbers. You'll be learning a great deal more
about the binary number system in the next chapter. For now, the important things
to remember are that only two digits are involved and that binary numbers are
generally longer than decimal numbers.
Because binary numbers have only two digits, we can represent them elec-
tronically. For example, a high voltage in a circuit can represent a one and a low
voltage can represent a zero. This is why we use binary numbers rather than
decimal numbers inside the computer. The input/output devices, such as the ter-
minal, translate data between decimal and binary.
. (a) The binary number system has a base of
(b) The digits of the decimal number system are 0,1.2,3,4,5,6,7,8,9. Write the
digits of the binary number system.
(c) Using Figure 1, what is the binary equivalent of the decimal number 5?__
(d) Which is easier to represent electronically—a binary number or a decimal
number?
{e) In order to use a computer, you have to translate all your data into binary
numbers before you can type them on the terminal or punch them on cards,
True or false?
(a) two; (b) 0,1; (c) 101; (d) a binary number; (e) false—the I/O devices do the
translating
6. One binary digit is called a bit. ("Bit” is an acronym for “Binary digiT” or
maybe “Binary digIT.”) A bit is either a one or a zero. There are two basic types of
data: numeric and alphanumeric. Numeric data can be converted directly to binary
and stored in memory.
We use a code system to translate alphanumeric data into binary numbers. It
takes several bits to represent one character. The number of bits depends on the
code system we use. For example, one popular system is called ASCII (American
Standard Code for Information Interchange). It requires seven bits per character.
‘The letter A is encoded as 1000001. The number 5 is encoded as 0110101. The sym-
bol *&’ is encoded as 0100110.
Another popular code system is EBCDIC (Extended Binary-Coded Decimal In-
terchange Code), It uses eight bits per character. The letter A is encoded as
11000001. The number 5 is éncoded as 11110101. The symbol ‘&’ is encoded as
01010000.
Remember that a byte holds one character. So a byte holds several bits, In the
6502 microprocessor, one byte contains eight bits. (This is becoming the standardINTRODUCTION 7
byte size throughout the computer industry.) So a byte in the 6502 chip is large
enough to use either ASCII or EBCDIC code. For numeric data, it can hold a value
up to 255.
ASCII is usually pronounced ask’-ey and EBCDIC is usually pronounced
bb-see-dick.
(a) A binary digit is also called a
(b) A bit can have one of two values. What are they?
(c) Suppose your microcomputer has 20K bytes of main storage. How many bits
does it have?.
fa) bit; (b) 0,1; (c) 160K or 163,840
7. Let's review what you have learned about bits and bytes. Match each term
with its characteristics.
(a) bit.
—— (b) byte
holds one character
1
2, holds a zero or a one
3, holds eight zeros and/or ones
4, the smaller storage area
5, the larger storage area
6, memory size is given in terms of
this
(a) 2,4; (b) 1,3,5,6
MEMORY
8 Your computer will have some chips that are used for storage of information.
They are connected to the microprocessor. These chips comprise your computer's
memory. The size of memory depends on the number and types of memory chips
your computer has.
Where is your computer's memory?
(a) on the microprocessor chip
(b) on separate chips connected to the microprocessor
©) on tape or disk8 6502 ASSEMBLY LANGUAGE PROGRAMMING
9. Every byte in memory has an address. The address is simply a number that
tefers to that byte. For example, the first byte has the address 0.
‘The address for the byte does not tell us what is in it, any more than your
street address indicates who lives in your house,
(a) What is the address of the second byte in memory?,
(b) Suppose your computer has 65,536 bytes (64K) of memory. If the first address
is 0, what's the address of the last byte?.
(a) 1; (b) 65535
We usually show memory addresses as four-digit hexadecimal numbers, so we
would normally write the above two addresses as $0001 and $FFFF. You'll learn
how to use hexadecimal numbers in Chapter 2.
10. Memory is used for the storage of programs and data while they're being
worked on. The diagram below depicts the relationship of the microprocessor,
storage, and memory.
MICROPROCESSOR —_—_— MEMORY
CURRENT.
PROGRAM
ITSDATA
STORAGE
OTHER
PROGRAMS
OTHER
DATAINTRODUCTION 9
(a) Where does the program currently being executed get stored?
(b) Where do programs not currently being executed get stored?
(c) What is the main purpose of memory?
(a) memory; (b) storage (tapes, disks, and so forth); (c) to hold the current program
and its data
REGISTERS
‘The 6502 microprocessor has several registers. Some have special purposes, and
some are available for the programmer to use (general purpose). In this section, we'll
discuss a few of the special-purpose registers and all of the general-purpose
registers.
11. A register is a very small storage area. Most of the registers store only one
byte. A couple of them are two bytes long. The 6502 registers we will study are: A,
X, Y, stack pointer, program counter, and status.
‘The A register is also called the accumulator because you use it for addition
and subtraction, To add two values, move one value into the A register, then add
the second value to it,
The A register contains one byte. It is called a general-purpose register. This
means that you, the programmer, can control the contents of the register. The
system never changes the contents of the A register unless you tell it to.
{a) How large are most of the registers?.
{b) The A register is also called the :
{e)_ Which of the following is the intended purpose of the A register?
——— to hold the sum of an addition
to hold a byte to be output to a terminal
to receive input characters from a terminal
(d) The A register is one byte. What is the maximum value it can hold? (Refer to
frame 6 if you don’t remember.)
(a) one byte; (b) accumulator; {c) to hold the sum of an addition; (d) 25510 6502 ASSEMBLY LANGUAGE PROGRAMMING
12, X and Y are also one-byte, general-purpose registers; they are called the index
registers. Their intended purpose needs a bit of explaining.
‘Suppose you want to access 100 bytes in memory; for example, you want to
send a 100-byte message to the terminal. The most direct, but longest and most
tedious, method is diagrammed below.
SEND SEND SEND
THE THE a THE
FIRST SECOND 100TH
BYTE BYTE BYTE
It would take an awful lot of instructions to do it this way; more than 100 in-
structions. A more economical way is diagrammed below.
SET SEND THE
ul ‘INDEX, YES
INDEX | —~_}-— BYTEAT |——~ — —
7 N+ INDEX ao = 1007
INDEX
NO
We start by initializing an index register to zero. N is a label that addresses
the first byte of the message in memory. So, the first time we do the loop, we send
the N + 0 byte, or the first byte. Then we add one to the index register. It doesn’t
equal 100. so we repeat the loop, causing the second byte to be sent. And on it goes
until we send the byte at N + 99, which is the 100th byte. After that, the index is
incremented to 100 and we leave the loop.
This second technique looks more complicated, but it takes only a few instruc-
tions to accomplish. So the use of the index register saves a lot of time and bother.
The 6502 microprocessor, with its X and Y registers, is perfectly designed to
use indexing techniques for accessing data in memory. You'll be using these two
registers a lot, because you'll rarely want to access just one byte in memory.
(a) Name the 6502 index registers.
(b) Which of the following best explains the purpose of the 6502 index registers?
to provide additional arithmetic storage space for problems with more
than two factors.
to allow you to read or write two bytes at a time.
to provide a means of addressing successive memory bytes without
having to code separate instructions.
(c) How many bytes does the X register contain?INTRODUCTION 11
“(a) X and ¥; (b) to provide a means of addressing successive memory bytes without
_ having to code separate instructions; (c) one
A, X, and Y are the three general-purpose registers of the 6502. Now let’s turn
our attention to the special-purpose registers.
13. One special-purpose register is called the stack pointer (SP). Some Assembly
‘Language instructions allow you to store data in a memory stack and retrieve it
again. It’s called a stack because of the way it behaves. Imagine a stack of plates.
When you add one more. it goes on top. When you remove one, you get the top
plate—that is, the one that was stacked last. This is frequently referred to as “last
in, first out’’ or LIFO, This is how a 6502 memory stack works. It is a handy tool in
Assembly Language programming, as you will see in Chapter 9.
address 0100-—-
SP— address 01FB—+| next | ———— top of stack
data
data
. data
address 01FF—+| data bottom of stack
FIGURE 2. A Data Stack in Memory
‘The stack pointer is a register that always keeps track of, or points to, the cur-
rent top of the stack in memory. (See Figure 2. Notice that the “top” of the stack is
the lowest address and the “bottom” of the stack is the highest address.) Whenever
you add something to the stack, the stack pointer is decreased, or decremented,
after the data is stored. Whenever you remove something from the stack. the stack
pointer is increased, or incremented. Then, the item is copied from the stack. So the
SP is always pointing to the top of the stack.
In the 6502, memory addresses are all two bytes long. Since the stack pointer
holds the address of the top of the stack, you'd think it would be a two-byte
register. But it isn’t. The stack must be in the part of memory where the addresses
begin with 01. :12 6502 ASSEMBLY LANGUAGE PROGRAMMING
‘The stack pointer holds only one byte—the second byte of the address, The
first byte is presumed to be 01. So if the stack pointer says 25, the top of the stack
is at 0125. :
(a) Where is the stack in memory?.
(b) Where does the stack pointer point; the top or bottom of the stack?.
(c) When you remove something from the stack, what do you get?
___. The first thing that was put in.
—— The last thing that was put in.
(@) How long is a 6502 address?
{e) How large is the stack pointer register?.
a) at addresses starting with 01; (b) top; (c) the last thing that was put in; (d) two
bytes; (e) one byte
14, ‘The program counter register is a double (two-byte) register that tells the com-
puter what to do next.
‘A computer program is made up of a series of instructions, They are stored in
main memory when the program is executed. The instructions are executed one at a
time. As each instruction is picked up from memory for execution, the memory ad-
dress of the first byte of the next instruction is stored in the program counter
register. When an instruction has finished executing, the computer uses the pro-
gram counter to find out where to pick up the next instruction.
‘The programmer has Assembly Language instructions to change the address
in the program counter register. These are called jump instructions because they
cause the computer to jump to another memory location instead of executing the
program in sequence. You will learn to use the jump instructions in this book.
(a) (review) How long is a memory address in the 6502 microcomputer?
(b) Which register holds the address of the next instruction?,
How long is it?
(c) ‘The programmer can change the value in the program counter register with a
instruction.
{a) two bytes; (b) program counter, two bytes; (c) jump;
15. Now we'll talk about the status.register. The status register is treated as eight
separate bits, Seven of the bits are used as flags or indicators. If a flag bit contains
a 1, the flag is on or “set.” If it contains a 0, the flag is off or “cleared.” The flags
are set or cleared as a result of operations such as addition, subtraction, or any
changes to a register. They tell you about the result of the operation. They tell youINTRODUCTION 18
such things as whether the result is positive or negative, whether it overflowed the
register, and so forth. There are many Assembly Language instructions that access
the values of the flags.
‘Two of the flags tell something about the result of a data movement or opera-
tion.
The zero flag shows whether the result is zero.
The sign flag or negative result flag reflects the eighth (high-order) bit of
the result. This is useful when you are using signed numbers, You'll learn
how to deal with signed numbers in Chapter 11.
Two other flags also indicate something about the result of an operation.
‘The carry flag shows whether an arithmetic operation needed to carry or
borrow outside of the result byte.
‘The overflow flag reflects the seventh bit of the result. Like the sign flag.
it is useful when dealing with signed numbers.
‘The next two flags are used in processing interrupts. You'll learn about these
in Chapter 12. :
‘The interrupt disable flag tells the microprocessor whether it’s all right to
Process an interrupt immediately.
‘The break flag shows whether an interrupt is caused by an external event
or by a program command,
‘The final flag you will also learn more about in Chapter 11.
‘The decimal flag tells the microprocessor whether it is doing binary or
decimal arithmetic,
(a) How large is the status register?
(b) How many flags are in the status register?
(c) Which flag tells you if an arithmetic operation resulted in a carry (or a
borrow}?
(d) Which flag tells the processor whether you are using binary or decimal
numbers?
(e) Which flag tells you about the seventh bit of a result?
() Which flag tells you about the source of an interrupt?
(g) Which flag tells you about the high-order bit of a result?
(h) Which flag tells you if an operation resulted in zero?.
(i) Which flag tells the processor whether to allow an interrupt?
(a) one byte; (b) seven; (c) carry; (4) decimal; (e) overflow; (f) breaks; (g) sign: (h) zero;
(i) interrupt disable14 _ 6502 ASSEMBLY LANGUAGE PROGRAMMING
16. Figure 3 depicts the directions in which data may be transferred between
registers. You will learn the instructions to cause these data transfers later in this
book.
A stack ——— } status
¥ |——}] memory PC
re LJ
x | sP
FIGURE 3. 6502 Data Flow
Which of the following transfers are possible in 6502 Assembly Language?
——— (a) Ato memory
—— 6) XtoY
—— () SPtox
—— 1d) memory to Y
—— ) XtoA
{a), (c), (d), (e)
REVIEW
Here's what you have learned in this chapter:
* Computer languages can be classified as high-level and low-level. A high-
level language is more “humanized” —it uses English words and syntax. It
is easier to learn and use, but it is less efficient and gives the programmer
less
s control. A low-level language is more like the machine's internal
language. It uses alphanumeric codes, and it gives the programmer more
control and more efficient programs.”INTRODUCTION 15
© 6502 Assembly Language is a low-level language used to program
microcomputers containing the 6502 microprocessor. It is generally used
for writing system programs as opposed to application programs. An ap-
plication program solves a user problem such as payroll. A system pro-
gram solves a computer problem such as input/output. System programs
are quite heavily used and must be efficient; they must also make full use
of the system’s capabilities.
* A microprocessor is an integrated circuit containing control circuits,
registers, and main storage. A byte is the amount of storage space
necessary to hold one character or a number up to 255. In the 6502, a byte
contains eight bits, A bit is a binary digit. The binary number system has
only two digits, zero and one. Computers use the binary number system
because the two digits can be represented electrically. All data is
translated into binary codes as it enters the system, Two popular coding
systems are ASCII and EBCDIC.
© ‘The 6502 microprocessor has three general purpose registers.
- The A register, or accumulator, is used for arithmetic operations.
- The X and Y registers are used for indexed addressing.
© Some of the special-purpose registers are:
‘The stack pointer, which holds the address of the top of the stack, a LIFO
storage area in the part of memory with addresses starting with 01.
‘The program counter, which keeps track of the next instruction in
memory. Assembly Language jump instructions are used to change this
address.
‘The status register, which contains seven on/off flags that reflect the
status of certain operations such as addition and subtraction.
= The carry flag shows a carry or borrow. .
- The zero flag indicates a zero result,
~The sign flag shows the eighth bit.
- The overflow flag shows the seventh bit of the result.
~The interrupt disable flag tells the processor whether to allow inter-
mupts.
- The break flag indicates the source of a break.
~The decimal flag tells the processor what kind of arithmetic to use.
Now complete the Self-Test to practice what you have learned.16
6502 ASSEMBLY LANGUAGE PROGRAMMING
CHAPTER 1 SELF-TEST
Is 6502 Assembly Language a low-level or high-level language?.
Which of the following are characteristics of system programs?
_—— a. used by non-computer staff
—— b. used by programmers
——¢. used by programs
_—— d. solve business or scientific problems
—e. solve computer system problems
__ f. high usage rate
—— g. low usage rate
‘The microprocessor contains ________ and
Memory size is stated in terms of
In the 6502, how many bits are ina byte?
One byte can hold:
a, one alphanumeric character
—— b. avalue up to 255
——¢ eight characters
—— 4. azero or a one only
One bit can hold:
——— a. one alphanumeric character
—— b. a value up to 255
——c. eight characters
__d.azero or a one only
What is memory used for?
What is the address of the first byte of memory?INTRODUCTION 17
10.
iL.
12.
Name the registers described below.
a. general-purpose registers
b, holds seven status flags
¢. the accumulator
d. index registers
holds the next instruction address
points to the stack
‘Name the two-byte register.
Match the flag names with their descriptions.
carry flag a. shows carry or borrow status
overflow flag b. shows whether interrupts are allowed
break flag c. shows source of an interrupt
sign flag d. shows the eighth bit of a result
zero flag e. shows whether a value is zeto
interrupt f, shows type of arithmetic
disable fag g. shows the seventh bit of a result
decimal flag
Self-Test Answer Key
low-level
b, ce, f
registers and logic circuits
bytes
eight
aandb
a
to hold the current program and its data
0 {or $0000)18 6502 ASSEMBLY LANGUAGE PROGRAMMING
10. AXY
status
A
X and Y
ae gp
e. program counter
f. stack pointer
11, program counter .
12, carry flag - a
overflow flag - g
break flag -
sign flag - d
zero flag - e
interrupt disable flag - b
decimal flag -
If you missed any of these, you may want to review the appropriate frames
before going on to Chapter 2.CHAPTER TWO
NUMBER SYSTEMS AND
DATA REPRESENTATION
‘The binary number system was briefly introduced in Chapter 1. In the study of
Assembly Language programming, number systems are so important that they war-
rant a chapter to themselves, You must become comfortable not only with binary,
but also hexadecimal (base 16). numbers.
Of the two code systems we introduced in Chapter 1, ASCII and EBCDIC,
your microcomputer probably uses ASCII. EBCDIC is used mainly by larger IBM
computers. Therefore, we'll also introduce you to ASCII code in this chapter.
By the time you have finished this chapter, you will be able to:
* add and subtract binary numbers;
* add and subtract hexadecimal numbers; -
* convert numbers among binary, decimal, and hexadecimal;
* interpret ASCII codes using a chart.
The Decimal Number System
Let's start by reviewing some basic facts about the system you've used every day
since the first grade—the decimal number system. This review will give you the con-
cepts and terminology you need to learn about other number systems.
1920 6502 ASSEMBLY LANGUAGE PROGRAMMING
1. The decimal number system has a base of ten. What does that mean? Essen-
tially, it means that we count in groups of ten.
‘This many objects we
call 9.
If we add one more, we make
one group, which we call 10.
‘The number 10 means:
one group of ten no singles
When we get ten groups of ten, we make a larger group.
oe is written 125.
elles] oe
0 [lool oe
2 |lee|| oe
to
‘one group two groups five singles
of ten tens of ten
‘The same principle holds true for all number systems,
(a) What is the base of the decimal system?
(b) The binary number system has a base of two. Draw the number of objects
represented by the binary number 11.NUMBER SYSTEMS AND DATAREPRESENTATION 21
(c) The hexadecimal number system has a base of 16. Draw the number of objects
represented by the hexadecimal number 11.
(a) ten
ow fe (one group of two; one single —
. a three objects altogether)
(one group of sixteen: one single —
. seventeen objects altogether)
te)
2. Because the decimal system has a base of ten, each column represents a power
of ten. The singles, or units, column represents 10°.
J 5
1 x 10° 2t10 5 x 10°
‘Any number (except 0) to the zero power equals 1. 10° = 1. 5° = 1. 45° = 1.
154387260416333.61527° = 1, X° = 1, unless X = 0.
The second column from the right, the groupof-ten column, represents 10'.
‘Any number to the first power equals itself. 10! = 10. 5! = 5. 45! = 45.
1543872694 16333.61527! = 154387269416333.61527. X' = X.
The third column from the right represents 102. The fourth column 10°, ete.
Here is how we break down a decimal number:
10523 = 1 x 10 = 1 x 10000 = 10000
Ox 100= 0
5x10?=5x 100= 500 .
2x10 =2x 10= 20
3x10=3x 1=_ 3 .
1052322 6502 ASSEMBLY LANGUAGE PROGRAMMING
Use the framework below to break down the decimal value 1984.
1984 = ___ x 10° =
x10? =
x10!=______x«
x 10° =
1984
1x 10° = 1 x 1000 = 1000
9x10°=9x 100= 900
8x10'=8x 10= 80
4x1!=4x 1 4
1984
3, ‘The above shows how you would convert a decimal number to the decimal
number system, The result is the same as the original because we didn’t change
number systems, In other number systems, you use the same method.
‘The binary value 101 is converted to decimal like this:
101= 1x2=1x4=4
Ox2=0x2=0
1x®=1x1=1
5
‘The hexadecimal value 11 is converted to decimal like this:
1x16=16
xe aol
17
(a) Convert the hexadecimal number 106 to decimal.
(b) Convert the binary number 1101 to decimal.NUMBER SYSTEMS AND DATA REPRESENTATION 23
(a) hexadecimal 106 = 1 x 16?
Oxlé=0x 16=
6x1@=6x 1
(ob) binary 1101 =1x2=1x8= 8
Ix2=1x4= 4
Ox2=0x1= 0
1x29=1x1= 1
13
4, Now let’s talk about the individual digits in the decimal number system.
Decimal is based on ten and so there are ten digits: 0,1,2,3,4,5,6,7,8,9. When you add
1 to 9, you get a group of ten, so you move to the left one column.
9+1=10
Cis the lowest value digit and 9 is the highest value digit.
(a) The binary number system has a base of two. How many digits does it need?
What are they? What's the lowest value digit?
What's the highest value digit?
(b). The hexadecimal number system has a base of sixteen. How many digits does
it need?
What do you think the hexadecimal digits are?
What's the lowest value digit? From the digits you used, what's the
highest value digit?
Hexadecimal uses letters when it runs out of decimal digits.
(a) two; 0,1; 0; 1; (b) sixteen; the standard hexadecimal digits are
0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F; 0; F
5. Now you've reviewed the decimal number system and learned quite a bit about
binary and hexadecimal gystems. These questions will help you to practice what
you've learned.
(a) What is the decimal base?
(b) What is the binary base?
(c) What is the hexadecimal base?24 6502 ASSEMBLY LANGUAGE PROGRAMMING
Convert the following numbers to decimal.
(a) binary 110 =
(e) hexadecimal 21 =
Give the digits for these number systems.
(f) Decimal
(g) Binary
(h) Hexadecimal
() What is the highest digit in decimal?
() What is the highest digit in binary?
(x) Whatis the highest digit in hexadecimal?
(a) ten; (b) two; (c) sixteen;
(d) binary 110 = 1x 22=1x4
1x2!=1x2
Ox2=0x1=0
6
(e) hexadecimal 21 =.2 x 161 = 2x 16
1x16°=1x 1
32
1
33
(f) 0,1,2,3,4,5,6,7,8,9; (g) 0,1; (h) 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F; (i) 9; (j) 1; (k) FNUMBER SYSTEMS AND DATA REPRESENTATION 25
THE HEXADECIMAL NUMBER SYSTEM
You may be saying to yourself, “I see why I might need to understand binary since
the computer uses it But why do I have to learn the hexadecimal number system?”
6. Sometimes we want to communicate with the computer in binary numbers in-
stead of decimal. For example, memory addresses are usually not translated into
decimal, But binary numbers are long and awkward and it’s easy to make mistakes
when reading, writing, and typing them, So instead of using binary directly, we usé
hexadecimal as a go-between. :
Hexadecimal and binary numbers are directly related. Four binary digits equal
one hexadecimal digit. So each byte can be expressed in two digits rather than
eight. This saves a lot of bother when you are coding instructions to the computer.
‘The computer can easily convert hex to binary; all work is actually done in binary.
1 ORG $8000
2 LDX #0
3. MAPLOP LDA TEXT,X =; TRANSFER TEXT TO
4 STA $0400,X ; THE PIRST LINE
5 INX + OP THE SCREEN
6 CPX #22 7 MEMORY
7 BNE MAPLOP
8 MAPOUT LDY $C054 3 SET SCREEN TO
9 ST¥ §C051 } PRIMARY TEXT PAGE
10 LOOP JMP LOOP
11 TEXT ASC ‘PLEASE TYPE YOUR NAME:'
*#* SUCCESSFUL ASSEMBLY: NO ERRORS
FIGURE 4. Assembler Listing
The computer also prints some data in hexadecimal, For an example, look at
Figure 4. This is a portion of an assembler listing—the report we get when a pro-
gram has been assembled, We have circled the data that has been printed in hex-
adecimal. It includes memory address information and the machine language in-
structions. The computer prints them out as hex (hex is short for hexadecimal), but
internally only binary is used.
In 6502 Assembly Language, we usually,indicate a binary number by the
prefix % and a hexadecimal number by the prefix $; a decimal number has no prefix.
(a) What number system is used inside the computer?
(b) What number system is used as a shorthand for binary numbers?26 6502 ASSEMBLY LANGUAGE PROGRAMMING
Indicate the number system of each of the following values:
{o) %1010
fd) 10
(e) $01
(a) binary; (b) hexadecimal; (c) binary; (d) decimal; (e) hexadecimal
7. The binary system is based on two and the hexadecimal system is based on
sixteen. Since 24 = 16, there is a direct relationship between a group of four binary
digits and a hexadecimal digit.
Figure 5 is a table showing the binary values for all the hexadecimal digits.
Use the table to answer the questions below.
decimal Shexadecimal febinary
Oo oO 0000
1 1 0001
2 2 0010
3 3 0011
4 4 0100
5s 5 0104
6 6 0110
? 7 ana
8 8 1000
9 9 1001
10 A 1010
" 8 4014
2 ¢ 1100
13 Dd 1101
1% E 1110
15 F 1111
FIGURE 5. Decimal-Hexadecimal-Binary Equivalents
Give the binary equivalents of these numbers.
(a) $3=
fb) s9=
() SA=
(d) 8C=
Give the hexadecimal equivalents of these numbers.
(e) %1010 =
( %1000
) %0101 =
(hy) 1211
() —-%0110NUMBER SYSTEMS AND DATA REPRESENTATION 27
(a) %0011; (b) %1001; (c) %1010; (d) %1100; (e) $A; (f) $8; (g) $5; (h) $F; (i) $6
8 Converting between larger binary and hexadecimal values is also easy. If a
binary number has more than four digits, divide it into groups of four starting from
the right.
0019010:
Fill in leading zeros as necessary to make groups of four digits.
pooygongpi0y,
‘Then translate each group into hex.
%900190199104 = $125
Give the hexadecimal equivalents for each of the following numbers.
(a) %101110 =
(by %1111000 =
() %10000 =
{a) $2E; (b) $78; (c) $10
9 You can convert hex into binary one digit at a time. For example, $52B is
equivalent to %0101 0010 1011. Many programmers like to write binary numbers
with a space every four digits to simplify conversion,
Give the binary equivalents for each of the following numbers.
(a) $23 =
(bo) $FB=
{a) %0010 0011 or %10-0011; (b) %1111 1011
10. Recall that a 6502 memory address is two bytes, or sixteen bits. So it takes
four hex digits to write a memory address. The first memory address is $0000.
(a) What is the second memory address?
(b) What is the eleventh memory address?
(c) What is the highest possible memory address (the largest hex value that will
fit in two bytes)?
(d) Indecimal, what's the highest possible address?28 6502 ASSEMBLY LANGUAGE PROGRAMMING
{a) $0001; (b) $000A; (c) SFFFF; (d) 65,535
15 x 16° = 15 x 4096 = 61440
15x le? = 15x 256= 3840
15x16'= 15x 16 240
15x16°=15x 1 15
65,535,
(The value 65,535 is the same as 16‘ — 1 and 21° — 1,)
11. Here are some more binary-hexadecimal conversion problems for you.
(a) Suppose the A register contains the value $FO. In binary, what is the value?
In decimal?
{b) Suppose the program counter (PC) contains $0010. In binary, what is the
value?
In decimal?
(c) In the flag register, the least significant (right most) bit is the carry flag. For
each of the following values, convert to binary to find out whether the carry
flag is on or off.
$23:
380A: __
SF1:
FF:
(a) %1111 0000; 240; (b) %0000 0000 0001 0000; 16; (c) on; off; on; on (Remember the
spaces we show aren't really there. We've separated the binary digits into groups of
four to make it easier for you to read them.)
Since one byte is eight bits, we usually represent a binary value showing all
eight bits and a hex value showing two digits, including leading zeros as necessary.
DECIMAL CONVERSIONS
Now you've been introduced to the binary and hexadecimal number systems and
can make these conversions: binary to decimal, binary to hexadecimal, hexadecimal
to binary, and hexadecimal to decimal. In the following frames, we'll show you how
to convert decimal to binary and decimal to hexadecimal,BB0 eve weu noo a
1
1
12
13
1%
15
16
FIGU
NUMBER SYSTEMS AND DATA REPRESENTATION 29
an n 16"
1 a 1
2 1 16
‘4 2 256
8 3 4096
16 4 65,536
32 5 1,068,576
64 é 16,777,216
128 ' 7 268,435,456
256 8 4,296,967 ,296
512 F
1026 IGURE 7. Powers of 16
2048
4096
8192
16,384
32,768
65,536
IRE 6. Powers of Two
12, Figures 6 and 7 show the values of some powers of two and sixteen, respective-
ly. You'll need them ‘to convert from decimal. To show you how it’s done, we'll con-
vert 43
(37 to hexadecimal:
A. First, we find the largest Ter Ter Te
power of 16 that will divide
into 437. It’s 16%, or 256. (16° os
(4096) is too big.) From this, 256)437
we know that our answer is
going to have three digits,
since we'll have some number
times 16%,
B, We divide 256 into 437. The quo-
er. 16" tient is our first digit because it
tells us how many 16?s there are in
re 437. We save the remainder for the
next y
Be step.
181
to next step30 _ 6502 ASSEMBLY LANGUAGE PROGRAMMING
{a)
(b)
fe)
(a)
fe)
(a)
(b)
C. We divide the remainder by
16%, The quotient becomes
the second digit of the
answer. Note that we convert
the decimal 11 to a single
hexadecimal digit, B.
1
16?
B 5
Ter Te
n
16/181
16
2
16
3
1 B.
Te Te \ w
ll
16187
16
Bt
16
3
D. Since we're down to the units col-
umn (16° = 1), the remainder
becomes the last digit.
If any quotient or the final remainder comes out greater than 15, a mistake
has been made somewhere and you need to recalculate it.
Now convert the following decimal numbers to hexadecimal.
2 =
100 =
241 =
16 =
4291 =
25 = $19
100 = $64NUMBER SYSTEMS AND DATA REPRESENTATION 31.
() 241 = $F1
15
16)241
a6,
81
80
a
(a) 716 = $2CC
2 12
256)716 16)204
512 d6e_
204 44
32
iz
(e) 4291 = 81003
2 a ane
4096/4291 256195 16)195
4096 16
195 35
32
3
13. Decimal to binary conversions are done just the same as decimal to hex except
that you use powers of two instead of powers of sixteen. For our example, we'll con-
vert 21 to binary.
A. The largest power of two ap PEs
that will divide into 21 is
24 = 16, This tells us that 16
the answer has five digits. a
3B
= B. The next lower power of
¥ PP : Pe
F "2 2 two, 2° = 8 produces a
4 zero quotient.
85
o
5
1 o 4
©. The next lower power of two, x p/n ep
2 = 4, will divide into 5.
1
4532 6502 ASSEMBLY LANGUAGE PROGRAMMING
1 oo o 4 D. The next lower power of two,
a Ss BY 2! = 2, produces a zero quotient.
And the final remainder is 1.
When converting to binary, each quotient will either be 1 or 0. If you get a
quotient (or final remainder) larger than 1, you've made a mistake somewhere.
Convert the following decimal numbers to binary.
{a 10=
(b) 16=
() 25=
(a) 3885
{a) %1010; (b) %10000; (c) %11001; (d) %100001
14. Now you can convert a number from any one system to any other.
Practice by filling in the chart below.
decimal hexadecimal binary
210 fa) tb)
o- 896 @
{e) 6 %1011 O111
(g) $224, (b)
49 @ a
(k) What is the largest number (in decimal) that the accumulator can hold?
(a) 82; (b) %1101 0010; (c) 150; (d) %1001 0110; (e) 183; (f) $B7; (g) 554; (h) %0010
0010 1016; (i) $31; (j) %0011 0001; (k) 255 (FF or %1111 1111—This is equivalent
to 16? — 1 or 28-1)NUMBER SYSTEMS AND DATA REPRESENTATION 33
* ADDITION
In order to read assembler listings, you need to be able to do simple addition and
subtraction in binary and hexadecimal. We'll cover addition first.
15. Do you remember learning how to add? If you had the usual education, you
memorized the addition facts from 1 + 0 through 9 + 9. Then you learned to handle
larger numbers in columns.
No, you don’t have to memorize math facts in hexadecimal and binary. We'll
give you some tables to use. But you should be able to figure out simple addition
problems without using the tables.
Here's the hex count from $1 to $20:
0123456789ABCDEF 1011 1213 1415 161718 191A 1B 1C 1D 1E 1F
20
Here are some sample problems that you can work out using the hex count line
above.
$2 + $3 = 85
$1 + $6 = 87
8A + $0 = $A
$9 + $1 = 8A (A critical fact! 10 = $A)
82+8B = sD
87 + $5 = $C (Count on your fingers if you
have to: 7,8,9,A,B,C.)
$F + $1 = $10 (Another critical fact!
16 = $10) a
Now you can solve the problems below.
fa) $10 + $B =
(bh) $5 + $F =
{) $9 +$2=
(d) $5 + 85
@ si9+st=_
() $1F + $1
(g) $15 +8B
(a) $1B; (b) $14; (c) $B; (d) $A; (e) $1A; (f) $20; (g) $2034 6502 ASSEMBLY LANGUAGE PROGRAMMING
16. The hexadecimal addition and subtraction table is located in Appendix A. To
use it for addition, find the row for one addend and the column for the other addend.
‘The intersection gives the sum.
Use the table to solve these problems.
(a) $5 +89 =
(b) 8A + 8B
(c) $3 + $9
(@) sD+sD=
(a) $E; (b) $15; (c) $C; (d) $1A
17. Binary addition is very simple. There are only three math facts.
xo x0 x
+40 24 +
x0 at 10
‘See if you can solve the problems below.
(a) 101 (b) %1000 () 10
-h2 pos) a
(a) %111; (b) %1001; (c) %101
18. Now let's do some problems with carrying.
Decimal examples:
VW
257 3265
8
285 5416NUMBER SYSTEMS AND DATAREPRESENTATION 35,
Hexadecimal examples:
1 we
S2a S39FF
+318 sp25
$45 $4526
When you carry a 1 to the second column from the right, you are actually car-
rying $10 or 16.
Binary examples:
“ tate
10410 144101
+ x10 + x44
%77000 7001100
Solve the problems below.
(a) s2e (b) 11017
+328 + 1100
© SEF @) mt
+ st bt
) 1110 © SEF
+ e114 + $927
(a) $56; (b) %100111; (c) $1000; (d) %1000; (e) %10101; (f) $171636 6502 ASSEMBLY LANGUAGE PROGRAMMING
SUBTRACTION
19, To use the hex tables for subtraction, find the minuend (the smaller number)
across the top, Then go down that column until you find the subtrahend (the larger
number). Go across to the left column to find the answer.
Examples:
1D $10 315
= se = $8 = 37
SF ‘$8 SE
Problems:
(a) $8 (b) $10 ) $13
35 SA =?
@ $17
(a) 86; (b) 86; (c) $C; (d) $C
20. Now let’s try some subtraction with borrowing.
Decimal examples:
i
aps Be
38
786 78
Hexadecimal examples:
9 !
s4Kbo sft
= 88 = sie
$5969 $2NUMBER SYSTEMS AND DATA REPRESENTATION 37
Now try to work these problems.
(a) $325 (b) $116 © S10A
SB =S2F $88
@ = $3211
= SBCD
, 2 £
(a) 8325 ) 81%6 © sida
288 = S2E $88
S318 SE? ‘S4F
@ $3211
= SBep
$2644
21,, Binary subtraction is simpler than hex subtraction. Here are the binary sub-
traction facts:
x0 m1 x 210 x10
30 40 24 een 20
%0 x1 20 “1 10
‘The important thing to remember in binary subtraction is that %10 — %1 =
%1. Now solve these problems.
(a) 21100 (b)-x10114 @ —oxaaaa4444
ezigg | = 4104 =-#10101010
{a) %1000; (b) %10010; (c) %0101010138 6502 ASSEMBLY LANGUAGE PROGRAMMING
22, Binary subtraction often requires borrowing. Here are some examples.
00 0 o
xatvozo x10401
7 - = a1
4101101 ‘210011
Find the answers to these problems.
(a) 411410 (b) -*101010
pemee SET = a0101
2 °
(a) -x11170 (b) 107010
#1101 £0101
*10001 %700107
23. Sometimes you have to borrow through zero. This is the trickiest part of sub-
traction. Let's look at how it works in decimal. We'll use the problem 50001 — 16.
A. We borrow from the first
non-zero digit. ALL THE IN-
TERVENING ZEROS
CHANGE TO HIGHEST
VALUED DIGITS. (Don’t
think of them as 9’s, think of
them as highest digits.) The
borrowing column receives
10, so it becomes 11.
449:
$0n01
. 5
C. The remainder of the pro-
blem is subtracted in normal
fashion.
ihe
46
B. The units column is then com-
pleted.
4999
56001
16NUMBER SYSTEMS AND DATA REPRESENTATION 39
Here are some hex examples:
a , ¢
sfoun ssfabpbe sé
ae : or :
‘SOFFD! S3OFFFFC SI4FA
Here are some binary examples:
2 ole ou
xféo10 1660101 x7030
it ae att
Now work these problems. Remember to use highest value digits for the ap-
propriate number system.
(a) $co001 (b) $2008 (©) 1000
1s = SEE ht
6FFF Wa ou
(a) sfip1 (b) s2K668 (ce) xf gpo
SBFFFC S29FOC 101
24. For practice, find the sums and differences below.
(a) x1001 1114 (b) 41110 0000 1111
+310 0014 + 21010
(co) %1001 11114 (d) %1110 0000 1111
410 0014 - 21010
(e) $426A (f $6000
sae 2 $5162
(bh) $6000
{g) $426A
= $516240 6502 ASSEMBLY LANGUAGE PROGRAMMING
{a) %1100 0010; (b) %1110 0001 1001; (c) %0111 1109; (d) %1110 0000 0101; (e)
$4323; (f) $B2B2; (g) $41B1; (h) 80EEE
ASCII CODE
So far, you have learned how to handle hexadecimal and binary numbers. You'll use
this information frequently as you develop programs, But when a number is entered
into the system from the outside, it's not translated directly into binary; it’s always
treated as alphanumeric data and encoded by a code system such as ASCII or
EBCDIC. In this book, we'll use ASCII and assume that the first bit (the leftmost
or high-order bit) is zero, since ASCII uses only seven of the eight available bits.
Many systems use the high-order bit for special purposes. The Apple, for example,
uses it as an I/O indicator. The Pet can use it to indicate an alternative character
set, The Atari uses it to reverse the colors displayed on the terminal. You'll need to
become familiar with your system's use of the high-order bit.
25. Appendix B shows ASCII code. Each character shown in the grid is
represented by two hex digits. These are shown on the top and left of the grid. For
example, 850 is the ASCII code for the letter P. Use Appendix B to answer the
questions below.
Write the ASCII code (in hex) for the following characters.
fa) *
(b) 3
A
@ a
Give the character indicated by each of the following ASCII codes.
fe) $35
() 84D
(ge) 877
(h) $25
(a) $2A; (b) $33; (c) $41; (d) $64; (e) 5; (£) M; (g) w; (h) %NUMBER SYSTEMS AND DATA REPRESENTATION 41
26. Notice particularly how the ten decimal digits are coded in ASCII. The code
always starts with $3. The second half of the byte is equal to the decimal digit.
‘Thus, 0 is coded as $30, 1 is coded as $31, ete.
(a) If you type and enter the character ‘5,’ what will be received by the computer?
(Choose one.)
%0000 0101 (binary for decimal 5)
$05 (hex for decimal 5)
%0011 0101 ($35)
(>) Suppose you write a program to add together registers A and X.
Register A contains the ASCII code for 2. What i
Register X contains the ASCII code for 3. What is it?
What will the sum be? (Give the answer in ASCII code.)
What is the character form of that code?
(a) %00110101 ($35); (b) $82, $33, $65, e (That's right, the computer comes up with
the wrong answer. Later in this book you'll learn how to handle numeric values so
your programs don't produce erroneous arithmetic results.) »
27. The codes from $00 through $1F and code $7F are special codes that control
the action of the output device. These are recommended codes used by most
systems. A terminal or other device may interpret them differently. (The Ataris are
different.) You use them by sending (or writing) the appropriate byte to the device.
For example, if you write the code 807, the bell on the output device will ring.
(Nothing will be printed.) If the terminal does not have a bell, it won't recognize $07
as a special code. All unrecognized codes are ignored or printed as blanks. Refer to
the explanations in Appendix B to answer these questions,
(a) What code will cause one character to be deleted (DEL)?
(b) What code will cause the output device (printer or video screen) to start a new
page (FF)?
(c) If you want to start a new line on a printer or a video terminal, you need to
write a carriage return (CR) followed by a line feed (LF). What are the ASCII
codes for these two characters?
{d) Suppose your program sends $0B, for vertical tab, to a terminal that does not
have a vertical tabbing capability. What will happen?42 6502 ASSEMBLY LANGUAGE PROGRAMMING
(a) $7F; (b) $0C; (c) $0D and 80A; (d) it will be ignored or a space will be printed.
Don't be frightened by all those special characters. Most of them are only for
special equipment and special applications, Remember, too, that your equipment
may use different codes. Check your manuals if you want to use these codes.
28, When you are using ASCII values in your Assembly Language programs, you
don’t need to use the hexadecimal codes. You can use the letters or digits directly
by enclosing them in single quotes.
For example, we can store a T in the accumulator by this instruction:
LDA #854
Or we can code:
LDA #T
This has a special advantage because we don’t have to worry about whether
our system uses standard ASCII code. So one program can be used on more than
cone machine,
‘Write an instruction to load the ASCII code for + in the accumulator,
LDA #+'
29. The ASCII control codes from $00 through 81F and $7F cannot be called on
directly in quotes. You have to use the hexadecimal code,
‘You should memorize the codes for carriage return and line feed. You'll use
these a lot. The others can be looked up if you ever need them.
(a) What is the ASCII code for a carriage return (CR)?
(b) What is the ASCII code for a line feed (LF)?
(a) $0D or $8D; (b) $0A or $8ANUMBER SYSTEMS AND DATA REPRESENTATION 43
REVIEW
In this chapter, you have studied data representation in the computer.
‘The binary number system is based on two. Each column represents a
power of two, The least significant digit represents 2°. the next left col-
umn represents 2!, and so forth. Zero is the lowest digit and one is the
highest digit.
Binary numbers are converted to decimal by multiplying each column by
the appropriate power of two and summing the results.
Decimal numbers are converted to binary by dividing by successive
powers of two, starting with the largest power that will fit into the
decimal number.
‘The binary math facts are:
0+0=0;04+1or1+0=1,1+1=10,
‘The hexadecimal (or hex) number system is based on 16. Hex numbers are
used merely as shorthand for binary numbers. The computer will report
numbers to you in hex and you can give it hex numbers.
Each column represents a power of 16. The least significant column is
16°, the next column is 16, ete. The digits are 0.1,2,8,4,5.6,7,8,9,A,B,C,D,E.F.
F is the highest digit.
Hex numbers are converted to decimal numbers by multiplying each col-
umn by the appropriate power of 16 and summing the results.
Decimal numbers are converted to hexadecimal by dividing by successive
powers of 16, starting with the largest power that will fit into the decimal
number.
‘The hex math facts are shown in Appendix A.
Binary and hex numbers are directly related. Four binary digits equal one
hex digit, Numbers can be converted between the two systems on sight if
you memorize the table of equivalents, from %0 = 80 through %1111 =
$F. (See Figure 5.)
Data entering the system through a terminal is always treated as
alphanumeric data and is encoded in a code system such as ASCII. Ap-
pendix B shows ASCII code, Assume that the left-most (high-order or
most significant) bit is always zero.
Now take the Self-Test for this chapter.44 6502 ASSEMBLY LANGUAGE PROGRAMMING
CHAPTER 2 SELF-TEST
‘You may use Figures 5 through 7 and Appendices A and B for this Self-Test.
1, Convert to decimal.
a $= _ d. $10 =
be 1816 See e. $100 =
Gyo £. $255 =
2. Convert to decimal.
a %101 = 4, %1001
b, %10100= e %llll =
c. %1100 = oO
3. Convert to hex.
a. %101 = d %1001 =
b. %11011011 e %100000
e. %10001 = ____ f, %11011 =
4, Convert to binary.
a $16= a. s2=
b, s7= e $10
sats SAS
5. Convert to hex.
aM a 16=
b 4s e 100=
e105 f. 256
6. Convert to binary.
a 8s d. 8% =
b. 25= e 525
e 88s £ 18=
7. Add.
a. ‘2101101 b. RINT %1000110
tot + s1t0 + 41101010.
i.
12.
NUMBER SYSTEMS AND DATAREPRESENTATION 45
Add.
a $64 bo srt c $2183
SAB + $a 28015
Subtract.
a, 100101 b. *110000 ec. %100000
x1110 z 14 xtst14
Subtract,
a $1008 b. $a0007 c — $3009
828 =_-$8E =A
Write the alphanumeric character for each of these ASCII codes.
a, $23 = d. $62 =
b. $37 = e sID=
ce 84A= £ $3F =
‘Write the ASCII code for each of these characters or control functions.
a b= d. line feed = ___
& [= fe. space =
¢. carriage return = __ £ H=___
Self-Test Answer Key
33 a 16
b, 22 e256
«7 £597
5 a9
b. 20 e 1546 6502 ASSEMBLY LANGUAGE PROGRAMMING
3a.
b.
©
4.
©
5k.
b.
6 a.
b.
c
1 a.
Se
oa
10. a
MM.
b.
©
12.
b.
©
$5
sDB
ESE
%10110
111
%100001
$15
84
SA
%1000
%11001
%100110
%110010
. $10F
%10111
SFDF
4
7
J
‘Boor $35
T or 85B
30D
f.
%100101
. $109,
%101101
SOFF48
a.
SE
$20
$1B
%10
%10000
%1010
$10
$64
SFF
% 1010101.
%110100
%10010
c %1100000
ce. $2DC8
© %1
c 83B5F
}
7
SOA
* or $20
or $48
If you missed any of these, study the appropriate frames before going on to
Chapter 3.
‘This has been a brief look at number systems and data representation. If you
would like to learn more, try the Wiley Self-Teaching Guide, Background Math for a
Computer World, by Ruth Ashley.| ns aseniinhhihihsaeienennsensnshthisnseatenana
CHAPTER THREE
INSTRUCTION FORMAT
In the two previous chapters you studied some necessary background information.
Now you're ready to begin attacking the subject of Assembly Language itself. In
this chapter, we'll look at the format of an Assembly Language instruction. You'll
learn how to code all the parts of an instruction, and you'll be exposed to many in-
structions that will be used later in this book.
When you have finished this chapter, you will be able to:
© name the parts of an Assembly Language instruction, and identify the re-
quired part;
* — recode it in correct format, given Assembly Language code in incorrect
format;
‘* create a label for an instruction or a data area;
* identify the types of instructions that need labels;
* write comments in a program;
* identify the operands in an instruction.
1. Figure 8 shows some sample code that we'll use throughout this chapter to
demonstrate the format of Assembly Language instructions. It is not a complete
program, just a few lines of code.
; THIS ROUTINE READS A NUMBER FROM
3 THE TERMINAL, ADDS TO IT, AND PUTS
; THE RESULT BACK OUT TO THE TERMINAL
% THEN THE ROUTINE GOES INTO AN ENDLESS
; LOOP UNTIL STOPPED BY OPERATOR,
Ri
EADIN JSR INPUT ;_ READ BYTE
LDA NUMBER
ApbIT ADC. #SOZ_—; ADD 2
STA NUMBER
JSR OUTPUT ; DISPLAY BYTE
DONE JMP DONE
FIGURE 8. Sample Code
aT48 6502 ASSEMBLY LANGUAGE PROGRAMMING
The first six lines are descriptive comments. They are printed whenever the
program is printed but are otherwise ignored by the computer. They are intended
for human beings who are reading the program.
‘The first instruction, JSR (Jump to SubRoutine), calls a subroutine named IN-
PUT that reads a byte from the terminal and stores it in a memory location called
NUMBER. The next instruction, LDA (LoaD Accumulator), copies the byte from
NUMBER to the accumulator.
The third instruction, ADC (ADd with Carry) adds 2 to the contents of the ac-
cumulator, assuming that the carry flag is clear. The fourth instruction, STA (STore
Accumulator) copies the changed byte from the accumulator back to memory loca-
tion NUMBER.
The fifth instruction, JSR, arranges to write the byte in NUMBER to the
original terminal. Notice that the original byte was not written back—only the
changed one. The final instruction (JuMP)-sets up an endless loop, which will repeat
itself until the program is interrupted.
(a) What happens if the user presses the “'3” on the keyboard?
—— “3” is displayed on the screen, and then “5”
_—— "8" is displayed
(b) What happens after the answer is displayed?
— the program waits for the user to type another number
the program ends; the user can start to run another program or re-run
this one
_— the program continues running, with no action occurring
(a) “5” is displayed on the screen (the number typed never shows up on the screen);
(b) the program continues running, with no action occurring, until the user inter-
rupts it in some way (such as turning off the system)
GENERAL INSTRUCTION FORMAT
‘The format of an Assembly Language instruction is dictated by the program that
will translate it—the assembler. Different brands of assemblers have different re-
quirements for instruction formats. but we can find some common points. We'll
discuss the common points and show you what our assembler requires. Don’t forget
that your assembler may be somewhat different.INSTRUCTION FORMAT 49
2, Refer to Figure 8 again and you'll see that an Assembly Language instruction
can have up to four parts:
© The label gives the instruction a name that we can refer to from other in-
structions.
‘* The operation tells the computer what to do (such as jump or load ac-
cumulator).
‘* The operand identifies the data or other program address to be used in the
operation,
© Any instruction may have a narrative comment at the end.
In the instruction below, identify the four parts.
READIN JSR . INPUT jREAD BYTE
(a) () te) @
{a) label; (b) operation; (c) operand; (d) comment
3. Refer to Figure 8 again. Two types of statements are shown—comments and
instructions. Comment statements are free-form after the semicolon (;) in column
one. Any information may be contained in column 2 and later. Instructions, on the
other hand, may consist of up to four parts. Name the four parts.
fa) (b)
Peetses sss esesee ieee (d)
{a} label; (b) operation; (c) operand; (d) comment
THE LABEL FIELD
4, A label gives a name to an instruction. You then use that name as an operand
in other instructions. There are two major ways we use labels.
* Jump or branch instructions: When we want to jump or branch to an in-
struction, we give it a label. Then we jump or branch to that label, In
Figure 8, DONE is a label. The JMP instruction jumps to itself, creating
the endless loop at the end of the program. :
* > Data names: We assign names to data storage areas in our programs.
Then our instructions refer to the data areas by name rather than numeric
address. The names serve as labels for the storage areas.50 6502 ASSEMBLY LANGUAGE PROGRAMMING
Which of the following would you label?
—— (a) Every instruction in the program.
—— (b) Every fifth instruction in the program.
_— (e) Instructions that have to be jumped to.
—— (d) Jump instructions.
_—— (e) Data storage areas.
—— (f) The last instruction in the program.
—— (g) The first instruction in the program.
(c) and (e) are the best answers. Many programmers also label (g) to give the pro-
gram a name.
5. Your assembler will have a set of rules for proper labels. In this book, we'll use
the rules shown below. They're fairly common.
* A label must be one to six characters long.
* It can contain letters (A-Z) or digits (0-9). No special characters such as
oe
© It must start with a letter.
© It must start in column 1.
«© The following cannot be used as labels:
—register names (A, X, Y)
—6502 operation codes (such as JMP and STA)
According to our rules, which of the following are legal labels?
——. (a) START — () TRY#
—— &) STA —— (gs) EXCEPTION
—— (¢) 3RDONE —— th) A
— (@) THIRD — ai
—— (e) B100 —WK
{a}, (d), (e), and j) are correct
(b) is an operation code; (c) starts with a digit; (f) contains an illegal character; (g) is
too long; (h) is a register name; and (i) starts with a digitINSTRUCTION FORMAT 51
6. Most programmers prefer to use meaningful names as labels. For example,
suppose you want to give a name to the first instruction of a routine that adds two
numbers. ADDER js a better name than B1 or Q.
Meaningful labels will help other people read your programs with understand-
ing and will also help you when you return to a program you haven't worked on for
a couple of months,
Which of the following labels are better?
a) For a data storage area that will hold a social security number—SSN,
,SOCSEO, or N9?—
(b) For the first instruction of a routine that reads and stores the social security
number—GETSOC, RANDS, or X2T1?
Now try writing some labels of your own.
©) For the first instruction of a routine that prints a page number on a new page.
(d) For the first instruction of a routine that counts the time in tenths of seconds un-
til the user pushes any key.
(a) SOCSEC is best, SSN is second best; (b) GETSOC is best; (c) we would use
NUMPAG or PAGE: (d) we would use TIMER (You could use any meaningful name
that meets the name-forming rules. It’s easier if your names are pronounceable.)
7. According to our rules, which of the following labels are legal?
——{a) STOPPER —— (h) RUN-IT
—(b) GATER — x
__(c) ENDER —w *
—(@) ENDAL —— k) 3010
—le) ENDTWO — RUNIO
—(f JMP —— (m) FORCE
—1e) JONES —— (a) TIN
Write good labels for each of the following:
(o) The first instruction of a routine that handles input errors.
(p) A data storage area that holds the old balance.52 6502 ASSEMBLY LANGUAGE PROGRAMMING
(b), (c), (e), (g), (1), and (m) are correct
(a) is too long; (d) contains an illegal character; (f) is an operation code; (h) con-
tains an illegal character; (i) is a register name; (j) contains an illegal character;
(k) doesn’t start with a letter; and (n) contains an illegal character;
(0) we would use INERR or ERRIN; (p) we would use OLDBAL
THE OPERATION FIELD
8. The operation is like the verb of a sentence; it tells the computer what to do.
Some typical operation codes are:
LDA for LoaD data irito the Accumulator
ADC for ADd with Carry
CMP for CoMPare to accumulator
BEQ for Branch if EQual
IMP for JuMP
STA for STore data from Accumulator
You don’t make up your own operation codes for the standard 6502 operations.
There is a standard set of 6502 codes. (Your assembler may have added some special
‘ones to the set.)
Every operation code contains three letters. The operation is not optional;
every instruction must have an operation.
(a) In the sentence SET THE TABLE, which word is most like the operation?
—— SET
—— THE
__ TABLE
(b) Can you make up your own operation codes?
(c) ‘Two of the following are not operation codes. Can you tell which two?
—x
—— SBC
i)
—— ERASE
{) Which instructions in Figure 8 require an operation code?INSTRUCTION FORMAT 53
(a) SET; (b) no; (c) X is too short and ERASE is too long; (d) all instructions; the
comments aren't instructions
9. Your assembler may have some rules for coding the operation. A fairly com-
mon rule is that the operation must be preceded by at least one space. If the in-
struction contains a label, the space or spaces separate the label from the operation.
If there is no label, the space or spaces tell the assembler that there is no label.
‘Most programmers code their programs so that the operation codes and the
operands are lined up in columns. (See Figure 8 again.) This makes programs much
easier to read. It also allows us to add labels later on if we need to. We always start
the operation code in column 8 (to leave room for a six-character label plus one
space). We always start the operands in column 12 (to leave room for a three-
character operation code followed by a space).
A section of Assembly Language code is shown below. Some of the instruc-
tions are coded correctly and some incorrectly. Recode the entire section legibly, ac-
cording to our rules. Use the coding form provided.
START LDA #10 FFE ele TT eadafalefobafpafe pole
ADC MORE
STA ANSWER
STOP JMP STOP
THE COMMENTS FIELD
10. You've learned how to code labels and operations, We're going to skip over
operands for now and discuss comments first. Then we'll finish up the chapter with
operands—a very large topic.
Corhments are used to docuthent the program. They're ignored by the
assembler. They're used by human beings who are reading the program. You can
usually code comments after the instruction. If they're too long to fit on the screen
line, they'll show up on the next line, as long as the total line doesn’t exceed 80
characters.54 6502 ASSEMBLY LANGUAGE PROGRAMMING
Why do we add comments to a program? To help others understand what the
program is doing. The effect or intent of a program or segment is not always clear
from reading the labels, operations, and operands.
We also write comments for ourselves. Sometimes we can forget the intention
of a routine by the next day. Reading an Assembly Language program written a
month ago can be like reading hieroglyphics.
(a) Are comments required or optional?
(b) Which is better—to limit comments or to use them freely?
(c) Suppose you're writing a program for your own purpose and it will never be
seen by anyone else. Should you add comments or not?
{a) optional; (b} use comments freely; (c) yes
11. Most, assemblers allow you to code separate comment lines. These are lines
that do not contain any label, operation, or operand—just narrative comments. For
our assembler, we indicate a separate comment line by coding a semicolon in column
1. Then we can use the rest of the line (through column 71) to code our comments.
(Leaving the line blank after the semicolon provides some spacing, which makes the
program easier to read.)
Figure 8 is an example of a well-commented program. Use it to answer the
questions below.
(a) How many separate comment lines are there?
-(b) How many instructions contain comments?
(c) Why did we include a line that contains only a semicolon in column 1?
(a) 6; (b) 3; (c) for spacing
12, Below is the sample code you formatted before. Add the following comments
to the coding form:
(a) On separate lines at the beginning, add: THIS ROUTINE ADDS 10 TO A
MEMORY BYTE AND STORES THE RESULT. Break the line anywhere
that's convenient.INSTRUCTION FORMAT 55.
(b) On the second instruction, add the comment: MORE CONTAINS 01
THE OPERAND FIELD
13. You have learned how to code the label, operation, and comments; now we'll
talk about the operand.
An operand answers the question “WHERE?” In the instruction JMP DONE,
the operation code JMP means “jump to ...”; the operand, DONE, specifies
WHERE to jump. In the instruction LDA NUMBER, the operation code LDA
means “‘copy the byte from ... into the accumulator”; the operand, NUMBER,
specifies WHERE to copy from.
Sometimes an operand may have two parts, separated by a comma; for exam-
ple, the operand in LDA $30,X has two parts,
(a), What is the operand in the instruction ADC C? —_
If the operation code means “‘add to the accumulator .. .,”” what does the
operand specify?
(b) What is the operand in the instruction STA $90,X?.
If the operation code means “copy the value from the accumulator ...,”" what
does the operand specify?
(c) What is the operand in the instruction CMP SUMOFD?.
If the operation code means “compare the value in the accumulator to
what does the operand specify?
(a) C, where to find the value to be added; (b) $90,X where to copy the accumulator
value to; (c) SUMOFD, where to find the value, to compare it to56 6502 ASSEMBLY LANGUAGE PROGRAMMING
14. Some instructions do not require an operand. The instruction itself includes all
the necessary information, For example, the instruction TAX means “transfer the
byte in register A to register X"; no operand is necessary to describe WHERE the
byte comes from or WHERE it goes.
In each of the following instructions, indicate whether there’s an operand and
if 80, what it is.
(a) CMP 805 Is there an operand?____If so, what is it?
(b) DEX Is there an operand?___If so, what is it?
(c) DEC $20,X Is there an operand?____If so, what is it?
(a) JMPSTOP Is there an operand?____If so, what is it?
(e) BRK Is there an operand?____If so, what is it?
(a) yes, $05; (b) no; (c) yes, $20,X; (d) yes, STOP; (e) no
15. Your assembler will have coding rules for operands. Here are some fairly com-
mon rules:
* Operands must be separated from the operation code by at least one
space. :
‘* No spaces are permitted within the operands, except inside quotation
marks,
(a) If your assembler uses the format rules as presented in this chapter and you
want all your instructions to line up in columns (as in Figure 8), in what col-
umn will you start the label? ___, the operation? ____, the operand? _
(b) Code ANY as an operand in this instruction: STA
(c) Code #120 as an operand in this instruction: ADC
(a) 1, 8, 12; (b) STA ANY; (c) ADC #120
REVIEW
Let’s review what you've learned in this chapter.
* The general format of an Assembly Language instruction for the majority
of assemblers is:
Uabel] operation [operand] [;comment]
Brackets indicate optional items.INSTRUCTION FORMAT _57
* A label gives a name to the location of the instruction, The label is then
used as an operand in other instructions. Every assembler will have rules
for the formation of labels. Here are some common rules:
— one to six characters
— numbers or letters, no special symbols
— start with a letter
— start in column 1
— don’t use register names or operation codes
‘Most programmers prefer to use meaningful names as labels.
* The operation code is a three-character code that is standard for 6502
Assembly Language. It tells the computer what to do. Most assemblers
require that it be preceded and followed by at least one space.
* Comments are used to document the intention of routines and individual
instructions that might not otherwise be clear. We document for ourselves
as well as others. Comments are ignored by the assembler and do not ap-
pear in the machine language version of the program. In many assemblers,
they are separated from the operands by at least one space and are preced-
ed with a semicolon or other special character.
‘© Most assemblers allow separate comment lines by coding a semicolon or
other special symbol in column 1.
* An operand specifies WHERE to find data or WHERE to transfer con-
trol, Some instructions have one operand; some have none, No spaces may
appear in the operand section except within quotation marks. Some
operands are written in two parts, with a comma separating the parts.
CHAPTER 3 SELF-TEST
What are the four possible parts of an instruction?
Which of the four parts of the instruction are required in every instruction?58 6502 ASSEMBLY LANGUAGE PROGRAMMING
3. Here is a series of instructions and comments, Recode them on the coding
form so the parts are in the proper columns.
BEGIN HERE
Loa START, x
REPEAT CMP MAK
Bee NEXT
TAK
apc #02
SNP REPEAT ; REPEAT UNTIL MAX REACHED
y
init
4, Make up valid labels for the following items.
a. The first instruction of a routine that reads and stores an addend.
b. The memory area where the addend is stored.
c. The first instruction of a routine that multiplies a value by 5.
d. The memory area where the above result is stored.
5. Which of the following items should have labels?
—— a. Instructions that are jumped to,
—— . Jump instructions (JMP and JSR).
—— ©. Instructions without comments.
—— 4. Data areas used as operands.INSTRUCTION FORMAT 59
‘The following routine reads a byte from the terminal (JSR INPUT), displays
the same byte on the terminal (JSR OUTPUT), compares the byte to 9 (CMP
#9) and goes into an endless loop if the byte equals 9 (LOOP BEQ LOOP).
‘Add appropriate comments to the program, including at least one comment
line before the routine.
I
I Lt
i
I
Chie! Sk] LIMPluiri
a) LUSK Oi IPlu| |_|
lchues_ ee!" 19
Lloolr| | | Ielela|_vloolr!
In each of the following instructions, identify the operand. If the instruction
has no operand, write NONE.
a, STA $02
b. CMP SFF
ce, CMP $25,x
d. INX
e. ADC ADDEND
If ADC means “add ... to the accumulator,” what does ADC ADDEND
mean?
Answer Key
label, operation, operand, comments
only the operation is required60 6502 ASSEMBLY LANGUAGE PROGRAMMING
4. Some sample answers are shown below. Yours may be different but should
follow the general rules for labels.
a, GETADD , STORAD
b, ADDEND , ADDER? (presuming there are more than one)
e. MULTER , MULTIS , TIMESS
d. PRODUC, RESULT, ANSWER, FIVEX
5. aandd
6. Our sample comments are shown below. Yours may be different but should
follow the general rules for comments.
EIKO | 5} NIP UIT! Ip) {rimlel_|elyir|
[ lol |plotri ilolrislele jal! [ai7t
lolol che ada 5 id CA Izi7|"|5|
: eR PE
7 a. 802
b. SFF
ce. $25X
d. none
e. ADDEND
8. Add the data stored at ADDEND to the accumulator.
If you missed any, restudy the appropriate frames before going on to the next
chapter.CHAPTER FOUR
OPERAND FORMATS
In 6502 Assembly Language, there are several different formats for operands that
you'll learn how to code in this chapter. You'll see a variety of terms for the for-
mats. There is no agreement on the number of them. We have chosen a set of terms
that we feel are descriptive and clear.
Don't be disturbed if your reference manuals use different terms for these
operand formats, or even if they group them differently. They're the same formats.
You will learn all the formats here.
When you have-completed studying this chapter, you will be able to:
* code the following addressing modes:
— immediate
— direct
— zero-page direct
— indexed direct
— zero-page indexed direct
— indirect
— pre-indexed indirect
— post-indexed indirect
— relative;
* Use labels and expressions as operands.
IMMEDIATE ADDRESSING
1. Some instructions manipulate one byte of data—copying it, adding or subtrac-
ting it from the accumulator, etc. If you know when you code the instruction exactly
what value this byte will have at execution time, you can write the value as the
operand, This is called immediate addressing.
When you use immediate addressing, the question “WHERE?” is answered
“RIGHT HERE!” On many 6502 assemblers. and in this book. a byte of immediate
data is preceded by “#”; the value of the byte may be coded in any of the notations
described in Chapter 2. For instance, #10 would be the immediate address for value
10 written in decimal notation; the same value in hexadecimal notation would be
#804.
6162 6502 ASSEMBLY LANGUAGE PROGRAMMING
(a) How many bytes are in an immediate address?
Code the following operands using immediate addresses:
(b) the value 25, using decimal notation
(c) the value 14, using hexadecimal notation
(d) the letter A, using ASCII character notation
(e) the value 4, using binary notation
(a) one; (b) #25: (c) $0; (d) #*A’; (e) #%00000100 (We'll continue to use two digits for
hex and eight for binary. Hex addresses will have four digits.)
2. Figure 9 shows a sot of operation codes that we'll use throughout this chapter.
CODE STANDS FOR EFFECT OF OPERATION
ADC ADd with Carry Adds value from operand to value in
accumulator
BEQ Branch if EQual Changes “next instruction” address in
program counter if zero-flag is “‘on’
CMP CoMPare Compares value in accumulator to
value in operand
JMP JuMP Change ‘next instruction” address in
program counter
LDA —_LoaD Accumulator Copies value from operand to ac-
cumulator
STA —STore Accumulator Copies value in accumulator to operand
FIGURE 9, Some Sample Operation Codes That Require Operands
Use the operation codes from the figure and immediate addressing to code a
series of instructions that will set the accumulator to zero, add 25 to the accum-
ulator, and compare the result to 20. Use decimal values.OPERAND FORMATS 68
LDA #0
ADC #25
CMP #20
3. You will find yourself using immediate addressing quite often in a program.
When you want to load a specific value in a register, immediate addressing is the
most natural way.
For example, suppose we want to use index register X in a loop. We need to in-
itialize it to zero. The easiest way is:
LOX #0
Suppose we want to write out an asterisk on the terminal. It has to be loaded
into register A first. The easiest way is:
LDA wre!
Another frequent use of immediate addressing is in making comparisons. For
example, suppose we have just read a byte from the terminal keyboard and we want
to see if it is a carriage return, We could code:
cup #s0D
Suppose we want to compare the value in A to decimal 25. We could code:
cmp #25
Which of the following are frequent uses of immediate addressing?
—— (a) _ comparisons
—— (b) branching
— (©) loading registers
—— 4) storing registers
{a) and {c)64 6502 ASSEMBLY LANGUAGE PROGRAMMING
DIRECT ADDRESSING
4. Operands that are not immediate answer the question “WHERE?” by specify-
ing a memory address. With some operations, this would be the address of a byte of
data; for others, it would be the beginning address for the next instruction.
In the direct addressing mode, you just write the numeric value of the address
as the operand. Addresses are usually coded in hexadecimal notation, showing all
four digits,
Use operation codes from Figure 9 and direct addressing to code instructions
that will:
(a) copy data from location $02FF to the accumulator
(b) execute next the instruction beginning at address $72FF
(a) LDA $02FF; (b) JMP $72FF
ZERO-PAGE DIRECT ADDRESSING
5. In 6502 Assembly Language, it is convenient to look at the 64K bytes of
memory as though they were divided into 256 pages of 256 bytes each. The first 256
bytes, with addresses from $0000 to $OOFF, are called the zero page. The next page,
with addresses from $0100 to $01FF, is page one.
(a) What would you call the page with addresses from $F A00 to $FAFF?
(b) What addresses are on page 10?
(a) page FA; (b) $1000 to $10FF
6. When you code a direct address that is on the zero page, you do not need to
code the two leading zeros. For instance. $30 represents the same address as $0030.
(The Pet assembler requires an asterisk to indicate a zero-page address.) The com-
puter will assume that an address with only one byte (two hexadecimal digits) is on
the zero page. A zero-page address saves one byte of space in the length of the in-
struction; it can also increase the speed of executing the instruction. Data that will
be referenced often should be put on the zero page.OPERAND FORMATS 65
(a) What is the unabbreviated form of this address — $F5?
(b) What is a shorter way to code the address $0029? =
(c) What is the advantage of using zero-page addressing?
(a) 800F5; (b) $29 (for Pet, this would be *829); (c) it saves space and time
7. You will probably code more direct addresses than any other type in a pro-
gram. We use direct addressing whenever we want to access a known memory loca-
tion. Don’t forget that a label can be a direct address,
Suppose we want to transfer control to the instruction labeled OTLOOP. The
most natural instruction is:
IMP OTLOOP
‘Suppose we want to load register A from the byte labeled CARRET. We would
code:
LDA CARRET
Suppose we want to store A at address $05 in memory. We would code:
STA $05
When do you use direct addressing? (Choose one.)
(a) When you're not sure what memory address to use.
(b) Whenever you can’t use immediate addressing.
(c) When you want to refer to a specific memory address.66 6502 ASSEMBLY LANGUAGE PROGRAMMING
8. Let's review the three types of operands you have studied so far.
Using operation codes from Figure 9, code instructions to:
(a) ~ set the accumulator to 10
(b) add the value from the seventh byte on page 3 to the accumulator
{c) compare the value in the accumulator to the value in the third byte of memory
(d) How do you distinguish between an immediate address and a direct address?
(a) LDA #10; (b) ADC $0306; (c) CMP $02; (d) an immediate address is marked by a
# in most assemblers; a direct address is not.
INDEXED DIRECT ADDRESSING
9, When an operand is written as an indexed direct address, the value in one of
the index (X or Y) registers is added to a direct address; the result is the actual ad-
dress. This is one of those two-part operands we mentioned earlier, where the two
parts are separated by a comma. The first part is a direct address, and the second
part is the register name (X or Y).
For instance, the instruction LDA $0218,X will load the accumulator with the
byte from 8021A if the value in X is $02, because $0218 + 802 = 021A. If the
value in X is $03, the same instruction will load the accumulator with the byte from
$021B.
(a) If the value in register X is $01, and the value in register Y is $0A, where will
the comparison bytes be found in these instructions?
cmp $0527,x
CMP SO8FF,Y
(b) The following instructions use direct addressing. Recode them using indexed
direct addresses, assuming that register X = $02 and register Y = $15.
LDA $0713
ADC SO8F8
ta) $0528; $0909; (b) LDA $0711,X or LDA 806FE,Y; ADC $08F6,X or ADC
808E3,YOPERAND FORMATS 67
ZERO-PAGE INDEXED DIRECT ADDRESSING
10. When the direct address portion of an indexed direct address is on the zero
page—that is, between $0000 and 800FF—the two leading zeroes can be omitted.
For example, the indexed direct address $0036,X is equivalent to $36,X. What is
another way to code each of the following?
(a) $00AA,x
() sze,x
(a) $AA,X; (b) $0028,
11. Using zero-page indexed direct instead of indexed direct addressing will cut
one byte from the length of an instruction and increase execution speed. You need
to be careful, though. If the result of the addition is larger than $FF, the page-
number portion (first two hexadecimal digits) will be dropped; the result will still be
a location on the zero page. For example, if X register = $02, the address resulting
from $FF,X will be 801, which is the second byte on the zero page.
Are the following operands valid? If so, what is the actual address
represented?
(a) $32,X (X register = $02)
(b) $0050,Y (¥ register = $04)
(c) 801FF,Y (Y register = 805)
(4) SFF,Y (Y register = $10)
(a) $34; (b) $54; (c) $0204; (d) $0F (They are all valid.)
12, We usually use indexed addressing in loops where we are accessing successive
bytes of memory. For example, suppose we want to write the message “THANK
YOU" on the terminal. The message is stored in memory starting at address
THANKS. Here's the routine we would use:
Lox #0 + INITIALIZE X
OTLOOP LDA THANKS,x 3 MOVE NEXT LETTER INTO A
JSR OUTPUT 7 WRITE THE LETTER
INK # ADD 1 TO X
CMP o#tut ¢ 1S IT THE LAST LETTER?
BNE ‘OTLOOP 7 IF NOT, GO BACK AND GET THE NEXT LETTER68 6502 ASSEMBLY LANGUAGE PROGRAMMING
‘The instruction labeled OTLOOP contains an indexed address, using the X
register as the index, Before the loop starts, we initialize X to zero. The first loop
loads A from THANKS+. This puts a ‘T’ in register A, which is sent to the ter-
minal by the JSR instruction. Then we increment X. On the second loop, H will be
loaded from THANKS+1, and so forth until the entire message has been written.
Match the types of addresses you have studied so far with their major uses.
— a) immediate 1. accessing successive addresses in a
loop
—— tb} direct and zero page 2. accessing a specific memory ad-
direct, dress
— (©) indexed direct and 8. avoiding memory access and put-
indexed direct page ting the data right in the instruc-
tion
fa) 3; (b) 2; (c) 1
18. In the previous frames, we have discussed five ways of coding operands. In im-
mediate addressing, the data to be used by the operation is included in the instruc-
tion. In the four forms of direct addressing, the operand represents the address
where a byte of data is to be found or the address of the next instruction to be ex-
ecuted. In the simplest form, a direct address is written as part of the instruction. A
zero-page direct address is a dirett address on the zero page; the two leading zeroes
on the address are not written. An indexed direct address specifies a direct address
and the name of an index register that contains a value to be added to the direct ad-
dress. A zero-page indexed direct address does the same thing, using the shorter
zero-page address.“ OPERAND FORMATS 69
To practice these addressing modes, fill in the blanks in the chart below.
Assume that the X register = $12, the Y register = $20, and the accumulator = 15
(decimal) before the instruction is executed. Use operation codes from Figure 9. The
first two examples have been done for you.
Address Mode Instructic Result
Direct, LDA $1732 A = byte at $1732
Zero-Page Indexed CMP 825,X A compared to byte at
Direct $0037
Direct ADC $1111 At
Immediate (b) ADC __ 10 is added to A
Direct; () IMP_ Next instruction ex-
ecuted is at $3212
Zero-Page Direct, (@ A = byte at 80015,
Indexed Direct LDA $0222,Y (ec) A = byte at
(a) byte at $1111; (b) #10; (c) $3212; (d) LDA $15; (e) $0242
These are the address types you will use most often. In the following section,
we'll show some more operand styles. You won't use the following types of operands
nearly as often until you begin to write advanced programs. But you'll see them in
your system manuals, so you need to know what they look like and what they do.
INDIRECT ADDRESSING
14. An indirect address points to a memory location where the actual address to
be used in the instruction has been stored. In other words, this second address is
the one which would have been the operand if the instruction had been coded using
adirect address. This form of addressing is useful when we need to change an
operand at execution time. Instructions previously executed will store the address,
which can vary depending on input data or other factors. An indirect operand is
always enclosed in parentheses. ($1010) and ($0010) are indirect addresses; $1010 is
a direct address, This simplest form of indirect addressing is used only with the
IMP operation code.70 6502 ASSEMBLY LANGUAGE PROGRAMMING
Code JMP instructions to do the following:
(a) Jump to an address which can be found at location $2020.
(b) Jump to address $1510.
() Jump to an address which can be found at byte $15 of page one.
(a) JMP ($2020); (b) JMP $1510; (c) JMP ($0115)
15. An address is two bytes long, but each memory location can only hold one
byte; so two consecutive memory locations are needed to hold an address. In 6502
Assembly Language, addresses are stored with the low-order byte (last two hexa-
decimal digits) in the first location, and the high-order byte (first two hexadecimal
digits, or page number) in the following location. The indirect address points to the
first location. The microprocessor will automatically go to the next byte to get the
rest of the address.
If a partial map of memory shows:
Location Value
$1530 $03
$1531 $13
$1532 SFA
31533 $02
(a) What is the address of the instruction which is executed after JMP ($1530)?
(b) What about JMP ($1532)?
{) Code an instruction to jump to address $FA13 using a direct address.
(d) Recode the instruction using an indirect address.
(a) $1303; (b) $02F A; (c) JMP $FA13; (d) JMP (81531)OPERAND FORMATS 71
PRE-INDEXED INDIRECT ADDRESSING
16. A pre-indexed indirect address is a zero-page indexed direct address, enclosed
in parentheses, indicating the memory location where the address of the actual
operand can be found. The actual address can refer to any memory location, but the
location it is stored in must be on the zero page. Only the X register can be used in
this operand.
Some valid pre-indexed indirect, addresses are: (826,X), (830,X), and (SFF,X).
(816,Y) is invalid because it uses the Y register. Pre-indexed indirect addressing
‘must use the X register. ($0116,X) is invalid because it references an indirect ad-
dress that is not on page zero. Whenever indexing is used with indirect addresses,
the indirect address must be on page zero.
‘This addressing mode will “wrap around’ if necessary, so the resulting address
is always on the zero page. If the X register contains $15, the address pointed to by
(8FF,X) would be $0014.
What address is pointed to by each of these operands? (Assume the X register
contains $10.)
(a) ($03,X)
(b) (875,¥)
() ($0103,X)
(d) (817,X)
fe) (SF1,X)
Assume the X register = $10; code pre-indexed indirect addresses that will
point to addresses stored at the following locations: :
(f) byte $25 of the zero page
(g) byte $07 of the zero page
(h) byte $15 of page one
(i) byte $F2 of memory
§) byte $0101 of memory
(a) $0013; (b) none, the Y register cannot be used in this addressing mode; (c) none,
only zero-page addresses can be used in this addressing mode; (d) $0027; (e) $0001;
(f) (815,X); (g) ($F7,X); (h) can’t do this—preindexed indirect addresses always point
to locations on page zero; (i) ($E2,X\; j) can’t do this —byte $0101 of memory is
byte $01 on page one72 6502 ASSEMBLY LANGUAGE PROGRAMMING
POST-INDEXED INDIRECT ADDRESS
17. A postindexed indirect address uses an indirect address to point to a zero-page
location, then adds the contents of the ¥ register to the address stored at that loca-
tion, The result is the actual address used in the instruction. Only the Y register can
be used in this addressing mode, The indirect, address portion of the operand is
enclosed in parentheses; the Y is not. Some valid post-indexed indirect addresses are
(813),¥ and (802),Y.
Here is a partial map of memory:
Location Value
$0011 801
$0012 $BC
$0013 $88
$0014 8E3
$0015 $00
S00FF $E0
$0100 8FE
$0101 $02
$0102 80A,
$0103 30F
SFFOO $08
‘Use this map and operation codes from Figure 9 to fill in the blanks in the ex-
amples below. Assume that the X register = $12, the Y register = $20, and the ac-
cumulator = 15 before each instruction is executed. The first two examples have
been filled in for you.OPERAND FORMATS 73
Addressing Mc Instruction Result
Pre-indexed STA (802,X) 802+$12=:
Indirect dress at $14-15 is
S00E3; Byte $00E3
receives ac-
cumulator (15)
Indirect SMP (80102) Next instruction
at $OFOA
Preindexed Direct | (a) STA (800,__) | (b) Byte = 15
Indirect (c) JMP Next instruction
at $00E3
Post-indexed. ADC ($14),Y Seeeeseee
Indirect
Indirect {e) JMP Next instruction
at $02FE
{a) X; (b) $88BC; (c) ($0014); (d) A = 30; (e) ($0100)
‘The following addressing modé is used only with branching instructions. Since
it is the only form of operand allowed for branching instructions, you'll need to
know it very well.
RELATIVE ADDRESSING
18. A relative address is a special form of address that is used only with the
branch instructions. Before we can show you how it’s coded in Assembly Language,
we must discuss its machine language form; that is, after it has been translated by
the assembler. In machine language, it is a one-byte signed number indicating the
number of bytes to branch forward or backward. A relative operand of $20 would
mean to branch forward 32 bytes, since $20 = +32. Because the machine language
operand is limited to one byte, and the value is treated as a signed number, the
maximum branches are +127 bytes (that’s the largest positive signed number) and
—128 bytes (that's the largest negative signed number).74 _6502 ASSEMBLY LANGUAGE PROGRAMMING.
(a) | What kind of addressing must be used with branch instructions?
(b) What does a relative address of —16 tell the computer to do?
(c) What is the largest possible forward branch?
(d) What is the largest possible backward branch?
(a) relative addressing; (b) branch backward 16 bytes; (c) 127 bytes; (d) 128 bytes
19. In Assembly Language, you don't code relative addresses themselves. You in-
dicate what you want using the other forms of 6502 addresses. For example, relative
addresses may be coded as direct addresses. The assembler calculates the relative
address by subtracting the “current” address from the operand address. The “cur-
rent” address is the address that would be in the PC when the branch instruction is
processed at execution time.
The direct address form of relative addressing is not the only way to code a
relative address in Assembly Language, but it is by far the easiest way. Other
forms of coding relative addresses involve counting the bytes in the machine
language instructions to be branched past; this can land you in a lot of hot water.
Experienced programmers always use direct addresses, preferably labels, as
operands of branch instructions.
(a) What is the best way to express a relative address in Assembly Language?
(b) Ifa direct address is a two-byte operand, how can it be used to express a one-
byte signed operand?
{c) In the following routine, the branch instruction, BNE, wants to transfer con-
trol to the LDA instruction, which is at address $0725. Code the operand for
the BNE instruction,
Lox #5
LDA #5.
JSR OUTPUT
DEX
BNE
(d) (Review) What is the maximum branch forward? __, backward?
If all instructions contain 1, 2, or 3 bytes, will the BNE instruction
above exceed the maximum backward branch?OPERAND FORMATS 75
(a) as a direct address, preferably a label; (b) the assembler calculates the one-byte
operand from the information you give it; (c) BNE $0725; (d) 127, 128, no—at most,
you've jumped back 12 bytes (actually, it’s eight)
As we described the various ways of coding addresses as operands, we
assumed that you would know the address of each instruction and each data byte
used in your programs, Some programmers do calculate the addresses they want to
use by counting bytes: but fortunately, there is a simpler way. In the next few
frames, you will learn to use labels and expressions as address operands.
LABELS AS OPERANDS
20. Look at the program in Figure 8 again. Notice that the instruction JSR IN-
PUT has a label, READIN. Anytime the 6502 assembler sees the name READIN in
the program, it will replace it with the address of the JSR INPUT instruction. If the
address of JSR INPUT is $2513, the instruction JMP READIN is the same as the
instruction JMP $2513.
If the instruction ADC $02 has the address $FA12, and the label ADIT, show
two ways that you could code an instruction to jump to it.
IMP $FA12; JMP ADIT
21, Labels as operands have the obvious advantages that you don't need to know
the exact addresses and that, if you change your program, you don't need to change
all the operands. This holds true whether the operand addresses an instruction or a
byte of data.
If the value in address $0110 is 15, and you have assigned the label FTEEN to
address $0110, the command LDA FTEEN will place the value 15 in the accumu-
lator.
If the location $OFFO contains the value $10, and the label FIRST has been at-
tached to this location, what will the command ADC FIRST do?
Add $10 to the accumulator76 6502 ASSEMBLY LANGUAGE PROGRAMMING
22. So far, all our examples using labels have used direct addressing. However,
since the assembler replaces every label with an address, labels can be used to
replace addresses in any addressing mode.
If the label TEMP has been assigned to location $00AA, and REPLAC to loca-
tion $0515, recode the following instructions using labels:
(a) sHP ($0515)
(b) LDA SAA,x
(co) ADC (SAA, XD
(a) CMP CSAA),Y
(e) STA $0515,¥ _
(f) LDA SAA
(a) JMP (REPLAC); (b) LDA TEMP; (c) ADC (TEMP,X); (a) CMP (TEMP),Y; (e)
STA REPLAC,Y; (f) LDA TEMP
EXPRESSIONS AS OPERANDS
23. Many assemblers allow you to use expressions as operands. An expression is
like the right side of an equation, as in X = Y+5. In instructions that use addresses
for operands, the expression must work out to be a legitimate address. For instance,
3+5 would be okay, because it works out to 8, or 80008. But 5 — 9 would not be
valid because it yields a negative number. $FFFF+805 would not be valid because
it yields a value outside of the memory range. A more common form of expression is
START+5, where START is a label in the program. The result would be an address
five bytes beyond the first byte of the instruction or data labeled START.
If your assembler allows expressions, it will have its own rules for how they
are coded. Usually + is used for addition and — for subtraction. Other arithmetic
operations may or may not be allowed. You need to be very careful when you use an
expression as an operand. Remember that if lines are added or removed from the
program the value at the computed location may change. However. expressions are
useful when you want to refer to a data area without developing a name for every
byte of data.
If the label START represents address $033F:
(a) What address does START+1 represent?
(b) What address does START-1 represent?
(c) Assuming that the X register = 3, recode the instruction STA BEGIN.X us-
ing an expression equivalent to the indexed direct address.
{a) $0340; (b) $033E; (c) STA BEGIN+3OPERAND FORMATS 77
REVIEW
Let's review what you've learned in this chapter.
* There are several operand formats, called addressing modes, which can be
used when coding operations. We call them: immediate, direct, zero-page
direct, indexed direct, zero-page indexed direct, indirect, pre-indexed in-
direct, post indexed indirect, and relative,
* In the immediate addressing mode, a byte of data is coded by writing ite
value, preceded by #, in the operand field. Examples: #36, #815, #'A’
«In the direct addressing mode. the numeric value of an address is written
as an operand. Examples: $0136, $0278, $FF15.
* The first two hexadecimal digits of an address identify the page it is on.
In zero-page direct addressing, an address on the zero page is coded omit-
ting the page digits, Examples: $FF, $00. This is faster and saves space.
* In the indexed direct addressing mode, a two-part operand specifies a
direct address and an index register (X or Y) that contains a value to be
added to the direct address. The result is the actual address to use for the
instruction. Examples: $1515,X; $FF34,Y.
* The zero-page indexed direct addressing mode is similar to the indexed
direct mode. but both the direct address and the actual address are always
on the zero page. Examples: $15,X; $FA,X.
* In the indirect addressing mode, the operand field contains an address
enclosed in parentheses. This address points to a memory location where
the low-order byte of the actual address is stored, (The computer will find
the high-order, or page-number, byte in the next location.) This mode is
used only with JMP (jump) instructions. Examples: ($1001); (SFAFA).
‘+ In the pre-indexed indirect addressing mode, the operand field contains a
zerorpage indexed direct, operand using the X register, enclosed in paren-
theses, Adding the value in the X register to the specified address results
in another zero-page address that points to the memory location where the
low-order byte of the actual address is stored. (The high-order, or page-
number, byte is in the next location.) Examples: ($15,Xh; (8FA,X).
‘* In the post-indexed indirect addressing mode, a zero-page address enclosed
in parentheses is followed by “.Y"". The zero-page address points to the
memory location where the low-order byte of another address is stored.
(The high-order byte is in the next location.) The value in the Y register is
added to this second address, resulting in the actual address, Examples:
($15),Y; (SFALY.
* In the relative addressing mode, the address is a one-byte signed value
used to branch forward or backward. It is used only with branch instruc-
tions. The maximum branches are —128 to +127. We usually use direct
addresses as branch operands and let the assembler calculate the relative
address.78 6502 ASSEMBLY LANGUAGE PROGRAMMING
Labels should replace addresses in operands, If the operand requires a
zero-page address, the label must be attached to a zero-page address. A
label in a conditional branch instruction replaces the entire operand; the
assembler will calculate the difference between the address attached to the
label and the one in the PC register. Therefore, this difference must be
within the range —128 to +127. Examples: START; START, X; (START);
(START,X); START, Y; (START)Y.
Simple expressions such as a label plus or minus a number may be used as
addresses on most operands, The assembler will interpret such an expres
sion as an address that is that number of bytes after or before the address
the label is attached to. ‘The computed address must be a valid one for the
addressing mode. Examples: START +1; (BEGIN—3.X).
CHAPTER 4 SELF-TEST
1, __ Identify the addressing mode of each of the following operands. If it is invalid,
indicate why. (Assume that none are relative addresses.)
a.
b.
9
ron ®
$0719,x
($17,x)
$0315
$£0,x
#10
($1930)
(SFAD,Y
#SFFI3
($86 ,X)
SFA,X
SFFFE
$15OPERAND FORMATS 79
Examine the operands in each instruction below. Identify from the list on the
right what each operand represents.
2 CHP SSF — a. immediate value
3. -BEQ START a b. address of data byte or instruction
address that contains another ad-
dress
4, STA (SFB,X)
5. ADC $16FD ——_ d. value for determining a relative ad-
dress
6. ADC S14
7. amp ($02)
8. CMP SFE,X a
9. LDA #tBt _
10. JP S16F4
Write operands for the instructions below.
11. Add the value at address $0072 to the accumulator.
ADC
12, Load the letter Z into the accumulator. LDA
13. Compare register A to decimal 16. CMP
14. If the zero flag is set, branch to location $06FO, which is labeled NEXT.
BEQ
15. Jump to location $1740, which is labeled FOURTH.
JMP _—___ eo _—___—_ .
16. Store the value from the accumulator at memory locations $1400, which is
labeled KEEP. STA
17. Store the value in the accumulator at the memory location that is at location
$1400 (labeled KEEP) plus the value in register X. STA
18. Jump to the address currently stored in byte $1020 and 1021.
JMP
19. Suppose byte $1020=$20 and byte $1021=840. What is the actual address of
the next instruction?
Check your answers below.80
6502 ASSEMBLY LANGUAGE PROGRAMMING
10.
1.
12,
13.
14,
Self-Test Answer Key
a. indexed direct
b. pre-indexed indirect
©. direct
d. zero-page indexed direct
e. immediate
f. indirect
&. post-indexed indirect
h. this is invalid—an immediate address is one byte; $00 through $FF,
or 0 through 256. :
i. pre-indexed indirect
j. zero-page indexed direct
k, direct
1. zero-page direct
b
d
apc $72
LDA #*z!
CMP #16
Bea NEXTOPERAND FORMATS 81
15.
16.
17.
18.
19,
JNP FOURTH (or JMP $1740)
STA KEEP (or STA $1400)
STA KEEP,X (or STA $1400,X)
Loa ($1020)
$4020
If you missed any, restudy the appropriate frames.CHAPTER FIVE
ELEMENTARY
INSTRUCTION SET
‘Now you're ready to actually begin learning to use some Assembly Language in-
structions. In this chapter, we're going to introduce a very basic set of instructions;
ones you'll need most of the time no matter what program you're writing. You'll
learn enough instructions to be able to read data from the terminal, move data
around from place to place inside the computer, add and subtract, write date out to
the terminal, specify which instruction to process next, and stop processing.
When you have finished this chapter, you will be able to:
* code instructions to:
— load registers from memory (LDA, LDX, LDY)
— store data from registers in memory (STA, STX, STY)
— transfer data between registers (TAX, TAY, TXA, TYA)
— increment and decrement registers and memory (INC, INX, INY,
DEC, DEX, DEY)
— add and subtract using the carry flag (ADC, SBC)
— set and clear the carry flag (SEC, CLC)
— jump to another instruction (JMP)
— jump to a subroutine (JSR)
* solve the following types of programming problems:
— read data from a terminal
— store data in memory
— write data to a terminal
— add and subtract
— stop a program
LOADING REGISTERS FROM MEMORY
‘We'll start with some instructions that move data from a memory location to a
register. This is called loading a register. Actually, the data is copied, not moved—
the value at the original location is not changed.
8384 6502 ASSEMBLY LANGUAGE PROGRAMMING
1. ‘The operation LDA (LoaD Accumulator) loads the accumulator with a byte of
data from a memory location specified by an operand. The operand can be in any of
these addressing modes:
~ immediate
— direct
— zero-page direct
— indexed direct (using either the X or Y index register)
— zero-page indexed direct (using the X index register)
— pre-indexed indirect
— post-indexed indirect
(a) Which of the following instructions are valid?
—— LDA #25
nn uw)
——— _LDA BEGINe1
——— LDA Here,x
LDA ($15),
(b) Code an instruction that will copy the value in location FIRST into the
~ accumulator.
(c) Code an instruction that will set the accumulator to zero.
{a) LDA #25, LDA BEGIN+1, LDA HERE,X, LDA (815),Y. (LDA (START) is in-
valid because the operand is indirect}; (b) LDA FIRST; (c) LDA #0
2. Look at the table in Appendix C. This table has a line for each operation code
used in 6502 Assembly Language; it has a column for each of the nine addressing
modes. As you learn about the operations, you will fill in the table so that it shows
which addressing modes can be used with each operation. The table will become a
handy reference document, so be sure to fill it in accurately.
‘LDA has been filled in for you. Notice that the columns for indexed direct and
zero-page indexed direct specify which index registers can be used with the instruc-
tions, Why isn’t it necessary to specify the registers which can be used in the pre
_ indexed and post-indexed indirect, modes?ELEMENTARY INSTRUCTION SET 85
Because the pre-indexed indirect mode always uses the X register, and the
post-indexed mode always uses the Y register.
8. Data can be loaded into the X register and into the Y register using operation
codes LDX (LoaD X) and LDY (LoaD ¥). Each of these operations requires an
operand that specifies where to find the byte to be loaded into the register. Im-
mediate, direct, and zero-page direct operands can be used with both LDX and LDY.
Code instructions to:
(a) Set the Y register to zero.
(b) Copy the data from location HITIME to the X register.
(c) Load data from location 815 into the ¥ register.
(@ Copy data from location $1212 to the accumulator.
(a) LDY # 0; (b) LDX HITIME; (c) LDY $15; (d) LDA $1212
4. LDX and LDY can also be coded using indexed direct. and zero-page indexed
direct operands. But with LDX, only the Y register can be used for indexing, and
with LDY, only the X register can be used for indexing, Neither LDX nor LDY can
use operands with indirect, pre-indexed or post-indexed indirect, or relative address-
ing.
(2) Fill in the lines for LDX and LDY in the table in Appendix C.
Which of these instructions are valid?
—— (b) Lvx one, x —— (@) Lox cone)
—— (e) LDA (START),Y —— th) Loy cnew, x9
— (d) Lox wi16h — (Lox #123
—(e) Loy New,x — Wi) LDA CANEW, x)
— (fh Loy $15
Ho 2 8 4 8 © Mm BB I
UD? ck 2 ok 2 ok Yok) GYok - S S
LDY ok ok ok Xok Xok ~ - SG S
(c), (d), (e), (f), (i), and (j) are valid; (b) is invalid because LDX cannot use the X
register for indexing; (g) is invalid because LDX cannot use indirect addresses; (h) is
invalid because LDY cannot use a pre-indexed indirect address86 6502 ASSEMBLY LANGUAGE PROGRAMMING
5. LDA, LDX, and LDY instructions affect the zero and sign status flags. This
means that if the byte moved has a value of zero, the zero flag will be set (=:
otherwise, it will be cleared (=0). The sign flag reflects the high-order bit of the byte
moved. If you are using signed data. a one in this bit indicates a negative value, and
a zero indicates a positive (or zero) value. (Signed numbers are discussed in Chapter
11.) Will the sign and zero flags be on or off after each of these instructions?
(a) LDY WHICH, where the location labeled WHICH contains $00.
{b) LDX LESS, where the location labeled LESS contains —25.
(c) LDA OK, where the location labeled OK contains 75.
(@) LDY #130.
(a) Zero = on, Sign = off; (b) Zero = off, Sign = on; (c) Zero = off, Sign = off; (d)
Zero = off, Sign = on {the value is greater than +127, or +87F]
Now you have learned how to move data from memory locations into the ac-
cumulator (LDA), X register (LDX) and Y register (LDY). You have learned that:
— all three of these operations can use direct, zero-page direct, indexed
direct, and zero-page indexed direct addresses, with the restriction that
the register being loaded cannot be used for indexing:
— the LDA operation can also use pre- or post-indexed indirect addresses;
— none of the three can use indirect or relative addressing;
— all three operations set the zero and sign flags.
In the next part of the chapter, you'll learn how to move data from these
registers to memory and how to move data between these registers.