

Introduction to Vectrex Programming

by Christopher L. Tumber, copyright 1998 all rights reserved.



Contents
========
Introduction
Hexadecimal Notation
Signed or Two's Compliment
Memory
The Instruction Set
The Assembler
Labels and Constants
Registers
Addressing Modes
Basic Math
The Stack
Bios Routines



Introduction
============

This is my attempt at an introductory tutorial on programming the Vectrex and 
the 6809. It should hopefully put you over the "hump" of just getting started.
However, this should not be considered a comprehensive text of Vectrex 
programming. My own knowledge of the Vectrex is hardly expert and there are 
plenty of other resources out there.

The most important piece of advice I can give someone learning assembly 
language for the first time is to go slowly and be sure you understand 
everything before you move on. There are a lot of very fundamental concepts 
which will be completely new to you, even if you have programming experience 
in high level languages (like C, BASIC, PASCAL) and it is vitally important 
that you have a firm grasp of the basics or what comes later will just be 
gibberish to you.



Hexadecimal Notation
====================

Learning and getting comfortable with hexadecimal notation is perhaps the 
single most important step to learning assembly language programming. What's 
more, it has been my experience in teaching people assembly that it is one 
of the most difficult subjects to learn.

This is because counting and numbers were one of the first things we ever 
learned. What's more, we all learned them by wrote when we were 4 or 5 years 
old and the concepts behind numbers were never explained to us. Instead, 
we've been using numbers over and over again every day of our lives without 
ever really thinking about what numbers are or why we use them the way we do.

In order to understand hexadecimal, you have to understand what numbers 
really mean and why we use the numbers we do.

To begin with, you have to realise that the numbers 1 or 2 or 5 or 397 are 
arbitrary symbols and don't in and of themselves mean ANYTHING.

Sometime thousands of years ago a couple guys were sitting around and needed 
a way of counting. They had a bunch of sheep or a heard or cattle and needed 
to keep track of how many they had. If they had enough for breeding. If they 
had enough to feed themselves throughout the winter. That kind of thing
So, they came up with some symbols. They called the symbol 1 "One" and the 
symbol 2 "Two" and so on but that decision was completely arbitrary. They 
could just as easily decided to call the symbol 5 "One" and the symbol @ 
"Two".

What's more, the decision that the symbol 1 or "One" would mean "A single 
unit of something" and 2 or "Two" would mean "A single unit PLUS another unit 
of something" is also completely arbitrary. 1 or "One" could have just as 
easily meant "A single unit PLUS another unit PLUS another unit". Or the 
symbol 5 could have mean't "I don't have any of these at all" (what we call 
ZERO).

It's the same with words, really. Why does the word "Apple" mean "A round red 
fruit that grows on trees"? Because, sometime hundreds or thousands of years 
ago someone decided "Apple" would be a good name for that fruit and we've 
been using it ever since. They could just as easily decided "Orange" or 
"Mustard" was a good name and we'd be using that instead. Yup, my mom bakes a 
great mustard pie....

The only reason the word "Apple" or "One" or the symbol 1 means anything is 
because we all agree on the meaning. If you ask someone who only speaks 
French for an "Apple" he's not going to know what you are talking about. Not 
because the word "Apple" doesn't have any meaning anymore, but because his 
language doesn't agree that "A round red fruit that grows on trees" is called 
an "Apple" but instead he calls it a "Pomme".

Similarily, we have all agreed that the numbers 0,1,2,3,4,5,6,7,8,9 all have 
a certain meaning.

However, sometime ago in the days of the Roman Empire we would have been
counting I,II,III,IV,V,VI,VII,VII,IX,X. (Most people have seen Roman Numerals
before, if not, they still appear often on clecks and watches...)

Both systems of counting refer to the same thing. Both are just as valid.

We use our system primarily because we have ten fingers. This system of 
counting is known as Base 10 or Decimal because there are ten different 
symbols used (0 through 9).

When we count in decimal, we start with 0 and go 1,2,3,4,5,6,7,8 up to 9. 
However, when we reach the number TEN we have a problem. We don't have a 
single, simple symbol for the number TEN. Instead, we have to start to RE-USE 
symbols. So, we use two symbols instead of just one and come up with: 10.

Why?

The most obvious answer is "Because my first grade teacher said so" but that 
doesn't really address what's going on here. We counted from 0 to 9 and then 
ran out of symbols. So, we had to come up with something to do because we 
need to be able to count A LOT higher than just 9.

So, what we do when we get "Stuck" at 9 is instead of using just one symbol 
as we do to represent 0 through 9 we use TWO symbols side by side to 
represent the numbers 10 through 99. This is important! We get around the 
fact that we REALLY only can count from 0 to 9 by adding a new column of 
symbols, by using two symbols instead of just one. So, instead of having a 
different symbol for every possible number there is (billions or trillions 
of symbols) we only have TEN symbols and we just re-use these TEN by symbols 
by putting more and more of them next to each other. So we can make a number 
like 145 or 32354654.

What's more, the symbol and position of the symbol is important. The first of
two symbols is the "Tens column". This is the number of TEN items we have,
or, it's the number of times we got "Stuck" and nine and had to carry over to
the tens column because we ran out of symbols. The second symbol is the "Ones 
columns" or the number of single items, just as when we were counting from 0 
to 9.

Using this system, we can express ANY number using just the symbols 0 through 
9. So the symbols 324 means we counted up from 0 to 9 and had to carry 
over to 10. Then, we counted up from 10 to 19 and AGAIN had to carry over to 
get 20. We repeated this process all the way up to 99. At 99, we were again 
out of symbols so we need to use THREE symbols now and carried over to 100. 
We keep up this process of counting up and carrying over until we reached 324.

As I mentioned, we use this system primarily because we have 10 fingers. 
Well, what if we DIDN'T have 10 fingers? What if we only had 8 (Octal) or 
what if we had 16 (Hexadecimal)...

You can see where this is going....

Well, a computer actually only has two fingers. Or to be more precise, a 
computer has switches. Switches are either on or off. All of a computer's
operations, including counting, are just turning switches on or off.
So, a computer can only really count from 0 to 1. Unlike us, where we can 
count from 0 to 9. However, just as we can "fudge" it and count higher than 9
by using more than one symbol (324) so too a computer can count higher than 1
by using more symbols.

However, just as we get "Stuck" when we reach 9 and have to start over at 0
with another symbol 1 in front, a computer has to start over after it hits 1.

So a computer counts:   0     When we count:  0
                        1                     1
                       10                     2
                       11                     3
                      100                     4
                      101                     5
                      110                     6

This is called "Binary" or "Binary Notation" and it is the way all digital 
computers actually count. Counting in binary, we can't use the symbols 2 
through 9 (We just can't, okay, that's the rule!) we can only use 0 and 1. 
So, every time we hit 1 it's just like hitting 9 in decimal and we have to 
carry and add another symbol if we want to count any higher; going from 1 
to 10 or 11 to 100. When a computer counts from 11 to 100 it's just the same 
carry over as when we count 9 then 10 except the computer runs out of symbols
earlier so it has to carry and add a symbol at "two" instead of at "ten".

So, if all computers actually count in Binary, why is Hexadecimal so 
important?

Well, it turns out that Binary and Hexadecimal happen to fit together really 
nicely.

As you may know, a single Binary digit is called one "Bit" so 0 is a bit or 1 
is a bit and 11 is two bits. 111 is three bits and so on.

Well, 8 "Bits" make a "Byte". The term "Byte" you've certainly heard before, 
it's one of the most common computer terms. Since a byte is 8 bits, a byte is:
10001000 or 10101010 or 11111111 or any other such combination of 8 0's and 
1's.

A slightly less know term is a "Nibble", a nibble is 4 bits or half a byte. A 
Nibble is 1000 or 1111 or 0101 or...

Lets consider all the numbers that can be represented by a Nibble:

      Binary           Decimal        Hexadecimal
       0000            0 (Zero)           0
       0001            1 (One)            1
       0010            2 (Two)            2
       0011            3 (Three)          3
       0100            4 (Four)           4
       0101            5 (Five)           5
       0110            6 (Six)            6
       0111            7 (Seven)          7
       1000            8 (Eight)          8
       1001            9 (Nine)           9
       1010           10 (Ten)            A
       1011           11 (Eleven)         B
       1100           12 (Twelve)         C
       1101           13 (Thirteen)       D
       1110           14 (Fourteen)       E
       1111           15 (Fifteen)        F

In the case of 0000 or 0001 we use the leading zeros to show that the number 
is four bits (a nibble or half a byte). In the same way 009 or 09 is the same 
as 9 (in Decimal or Base 10), we just normaly drop the leading zeros because 
we don't need them. However, in Binary (and Hexadecimal) Notation we tend to 
keep them in there to show how much space the number takes up (a nibble, a 
byte or even two bytes).

As you can see, I've also included the equivalent Hexadecimal Notation.

In Hexadecimal, instead of using 10 digits (symbols) as in Decimal or using 2 
digits as in Binary we use 16 digits (symbols).

Of course, we only actually HAVE the digits 0 through 9 to use. But, we need 
16. So, we borrow the extra 6 symbols we need from the alphabet. We use the 
letters A through F.

This is a big sticking point for some reason, this using letters as numbers. 
A lot of people have trouble getting their brain around it. Remember earlier 
we decided that numbers and their meanings are completely arbitrary. 1 
doesn't REALLY mean anything except that we say so. 5 doesn't REALLY mean 
anything either, we just say it does. Well, now, we're going to say that 
the letter A means "One more than 9" and the letter B means "One more than A" and so one.

We could have used ANY symbols. We could have made up new symbols. We use 
the letters A through F because they're a lot easier to remember than some 
weird symbol just made up for that purpose. There's also no other occaision 
where you'll see numbers mixed up with letters like 2A5F.

Except Hexadecimal (and some postal codes and licence plates....!)
                                              
So there's not really any room for confusion.

Now, if you refer back to that listing of all the values that can be 
represented by a nibble, you'll see that all nibble values can be represented 
by a single Hexadecimal symbol from 0 to F.

Pretty convenient, eh? 

If order to represent those numbers in decimal, we have to use 0 to 15. (Two 
digits, where we can get away with only one in hexadecimal. Plus, decimal may 
be 1 digit or it may be 2. Hexadecimal is ALWAYS 1 digit. This is actually 
important as where computers are concerned standardisation is a REALLY good 
thing!)

In fact, if you take a Byte:

     Binary        Decimal      Hexadecimal

    00000000          0           00
    00000001          1           01
       .
       .
       .
    10001001        137           89
    10001010        138           90
       .
       .
       .
    11111110        254           FE
    11111111        255           FF

I'm not going to list all the possible values in a Byte because that would be 
256 lines long. However, as you can see any Byte value of 8 bits can be 
expressed with 2 Hexadecimal digits. It takes up to 3 decimal digits.

The only reason we use Hexadecimal is because it translates back and 
forth to Binary so nice and neatly. Trust me, it's A LOT easier to deal with 
Hexadecimal than Binary!


In order to avoid confusion, it is often neccessary to be able to tell when 
we're talking about a decimal number or a hexadecimal. The most common method
is to preceed hexadecimal numbers with a $. (There are others but I'm not 
going to go into them here. I'll only use these and if/when you come upon 
the others you'll know.)

So we would write 10 or $0A. These are really the same number.

While working on an 8-bit machine like the Vectrex you will often see 1 and 2 
byte hexadecimal values.

A 1 byte hexadecimal value looks like $2F.

A 2 byte hexadecimal value looks like $C32F.

The difference is similar to the difference between 10 and 1000, a matter 
of scale. In most computers, values tend to be divided up neatly into Bytes. 
You CAN work with just 1 bit, or with a nibble or any part thereof but most 
of the time you're working with 1 byte or 2 byte values. (You can also work 
with larger values, but probably won't be doing so very often on the 
Vectrex).

1 byte values can represent $00 to $FF (0 to 255) and 2 byte values can 
represent $0000 to $FFFF (0 to 65535). Again, it's a matter of convention 
because these values fit neatly into bytes.


If you need to translate hexadecimal values back to decimal, it is very easy 
to do so.

Remember, is decimal a number like 324 really means:

    3 X 100   (3 times 100)      (100 = 10^2)
  + 2 X 10    (Plus 2 times 10)  (10  = 10^1)
    4         (Plus 4 times 1)   (1   = 10^0)
   -------
    324

(The symbol ^ means "To the power of")

To convert a hexadecimal number back to decimal, you do the same thing, 
EXCEPT each leading digit is a factor of 16 instead of a factor of 10.

So, $C32F is

    12 X 4096  ($C=12 -> 12 times 4096)     (4096 = 16^3)
+    3 X 256   ($3=3  -> Plus 3 times 256)  (256  = 16^2)
     2 X 16    ($2=2  -> Plus 2 times 16)   (16   = 16^1)
    15         ($F=15 -> Plus 15 times 1)   (1    = 16^0)
   -----------
    49967

So $C32F = 49967

You could do all your assembly programming in decimal, however it isn't 
nearly as neat and tidy as hexadecimal simply because of the way hexadecimal 
translates back to binary. In other words, hexadecimal is a kind of 
shorthand. A compromise between binary, which is what the computer actually 
uses but is quite awkward and unwieldy for us humans and decimal which is 
what we humans normal use but is awkward for computers.


Your assembler should be able to deal with both hexadecimal and decimal (and 
binary for that matter) values equally. It's generally up to you to decide 
which is most convenient for you to use in any given situation. You'll tend 
to find that you refer to memory locations in hexadecimal but some data and
variables in decimal. It's really a matter of convenience, when telling the
computer what to do it's generally easier to "speak it's language" and use 
hexadecimal.

You'll also find hexadecimal used all over the place by other programmers so 
it's REALLY important to learn if you're going to look at anyone else's code. 
You could conceivably write all your programs using only decimal notation but 
it'd look really odd and you probably get beat up and called a geek at 
recess...


Signed or Two's Compliment
==========================

The previous description of Hexadecimal Notation has one problem.

How do you express -80 in Hexadecimal?

With a lot of CPU's you're on your own if you want to use negative numbers 
and have to come up with your own way of dealing with negatives.
The 6809 however uses Two's Compliment integers and has the capability of 
dealing with negative numbers built in.

Two's Compliment is kind of a weird format (and you though hex was strange!) 
where negative numbers are the bit-wise inverse of the positve number +1.

So,      1 = 0001
but     -1 = 1111 (1110 + 1 =1111)

and    127 = 0111
but   -127 = 1001 (1000 + 1 =1001)

The bottom line is that in 1 byte you can use -128 to 127 and in 2 bytes you 
can express -32768 to 32767 and if you're going to use positive and negative 
values (and you will!) you should probably use decimal instead of 
hexadecimal.


Memory
======

First of all, a computer's memory is NOTHING like a person's memory.

As noted before, a computer really only sees everything as a series of 0's and
1's. We abstract these 0's and 1's out to be hexadecimal numbers which then 
mean something to us. To the computer, they're just a bunch of on and off 
switches.

Picture a computer's memory like a school hallway filled with lockers. Each 
locker is one byte of memory and can hold one thing. Each locker is also 
individually numbered (in hexadecimal) so we can identify it. (ie: "What's in
locker $2333??")

For our purposes, there are two types of memory, RAM and ROM.

If a locker is ROM (Read Only Memory) we can look into the locker but we 
can't EVER change the contents.

If a locker is RAM (Random Access Memory) we can look in the locker AND we 
can change the contents at any time. We can store anything we want in there.

So, if your PC has 8 Megs RAM, it has 8 million lockers that can be used to 
store things (A meg is a million). 

There are two basic kinds of things we can have in each locker, a program or 
data. Our program is simply a series of instructions which tell the Vectrex 
what to do. Just like you tell your kid brother what to do you have to tell 
the Vectrex exactly what to do. This is our program.

Our lockers can also contain data. Data is a little different than program in 
that it isn't exactly instructions for the Vectrex, rather, it is information 
our program will use in some way (ie: Lines of text, musical notes in a song).

To the Vectrex, a locker is a locker, it doesn't matter what's stored there. 
All that matters is what we tell the Vectrex to do with that locker. The 
locker could contain parts of our program or it could contain some data.
We generally tell the Vectrex to excute program instructions, however, it will
be more than happy to try and execute data as if it were instructions or 
manipulate our program as if it was data. It's up to us to make sure we tell 
the Vectrex to go to the right lockers when we want it to do something or to 
go to the right locker to get some data.

Again, each of these lockers is 1 byte. So each locker actually just contains 
a number. If the locker contains program code, then that number represents an 
instruction for the computer. If the number is $01 it tells the Vectrex to 
do one thing, if it is $55 it tells the Vectrex to do something completely 
different.

If the contents of the locker is data, then it could be the circumference of 
a circle or the distance from the Earth to the Moon. It's up to us to decide. 
To the Vectrex, it's all just numbers. We just tell the Vectrex "Do the 
instructions in locker $1000" or "Get us the data in $1000".


In the high-school named "Vectrex High", locker numbers $0000 to $7FFF 
contain our program (game). These lockers are ROM. They're burned onto the 
cartridge and may never be changed. $0000 to $7FFF is 32768 lockers or 32K. 
Therefore, our maximum program size is 32K (without doing any REALLY fancy 
stuff that's well beyond the scope of this text...) We decide the contents
of these ROM lockers when we write our program. When the Vectrex starts up, it
(essentially) goes to the first locker, at $0000 and looks for the first 
instruction. It then proceeds sequentially through the lockers ($0000 then 
$0001 then $0002 then...) until or unless the instructions in those lockers 
tell it to do otherwise.

Locker numbers $C800 to $CFFF are _supposed_ to be RAM that we can use, 
however for some reason we can only ACTUALLY use $C800 to $CBFF (If you ever 
discover why, please let us all know!!).  What's more, the Vectrex itself 
actually uses lockers $C800 to $C87F for it's own storage purposes. So we 
really only can use lockers $C880 to $CBFF to store our gym shorts. These 
lockers are empty when you first turn on the Vectrex. However, throughout 
the course of our program, we can put stuff in here. Stuff like scores, 
spaceship positions, etc.

Locker numbers $E000 to $FFFF are also ROM. However, THESE lockers were 
filled by the designers of the Vectrex. These lockers contain the BIOS. The 
BIOS is a set of program instructions built into the Vectrex that we can use 
for our own programs. A handy bunch of instructions that do all kinds of 
things like draw vectors and make sounds.

Obviously, there are a whole bunch of lockers I haven't mentioned, but we 
don't need to go into those. Really!

These are the basic lockers you need to be able to get into.


The Instruction Set
===================

The Vectrex (or to be more specific the 6809) has a number of built in 
instructions. Just like you can tell your kid brother to wash the dishes 
for you but you can't get him to drive you to the mall because he's only 
8 the Vectrex can only do so many things. This is the instruction set.
You WILL need a list of the Vectrex's instruction set. I won't provide it 
here, there are a couple on my WWW site and you can get a copy from Motorola 
themselves (this is a REALLY good idea, btw! See my web site for instructions 
on how).

A single line of instruction for the Vectrex looks like this:

$1000     deca

  ^        ^  
  |        |
  |         ---------- The instruction
  |
   ------------------- The locker number 

It doesn't really matter what this actually does, I just want you to get the 
idea of the format.

The first number, $1000 is the memory location where this instruction 
resides. This is the locker number where the Vectrex will find this 
instruction. The term "deca" is an instruction, it tells the Vectrex to do 
something.

Most instructions will, at first look incomprehensible to you. In most cases
they are abbreviations which is why they don't mean anything to you right 
now. There are maybe a dozen instrcutions you will use all the time, and 
you'll quickly come to recognise them.

As I mentioned previously, the contents of all lockers (memory) is actually 
just a number. So why did I just tell you the contents of locker $1000 is 
"deca"?

Well, I lied!

$1000 does just contain a number. However, if you were going to try to 
memorise all instructions by their actual number you would have a REALLY hard 
time as there are hundreds of them. Instead, we use a mnemonic like "deca" 
because it's much easier to remember and understand. 

The purpose of an ASSEMBLER is to take our mnemonics like "deca" and 
translate them to their real, numeric code that the Vectrex actually sees 
(in this case "deca" becomes $4A). Meanwhile, a DISASSEMBLER will convert 
the numeric code back to mnemonic code that we can understand more easily.

In general, each of the various instructions provided do a very small task. 
Unlike a high level language like C or BASIC where the instructions can 
perform relatively complex tasks, assembly language instructions tend to be 
very simple and it is by doing several instructions in sequence that we 
accomplish large jobs.

Once the Vectrex has finished with our instruction, it will move onto the 
next locker and look there for another instruction. For example:

$1000    deca
$1001    tsta

That's generally the way it works. The Vectrex just goes sequentially through 
all our lockers executing whatever instructions it finds there.

Of course, it's a little more complex than that. 

Some instructions tell the Vectrex to go to a different locker to find the 
next instruction.

Some instructions are a little more complicated and actually take up to four 
lockers to hold.

Something like:

$1000     sta $C880
$1003     deca
$1004     tsta


The Assembler
=============

Our list of instructions for the Vectrex is know as Source Code. All this is 
is a normal text file with all your instruction for the Vectrex in it. You 
can write your source code in any text editor as long as it will save in 
standard ASCII text.

An Assembler is a program that translates our source code into the actual
machine language that the Vectrex can read.

In my case, I use the AS9 assembler which adds an intermediate stage in that 
it doesn't translate into machine code directly but instead into hexadecimal. 
The program hex2bin is then used to convert this to the true machine code.

To take my source code, run it through the assembler AND run the resulting 
program on the Vectrex emulator, I enter the following commands at the DOS 
prompt:

as9_new omega.as9
hex2bin omega.s19
vectrex omega.b00

The file omega.as9 is my source code. The file omega.b00 is the resulting 
Vectrex ready game file like BERZERK.GAM or BEDLAM.GAM for the emulator.


Labels and Constants
====================

If you look at some source code, you'll notice that every line DOES NOT start
with a locker number.

If fact most if not all lines don't have locker numbers at all.

This is because the ASSEMBLER does this for us automatically. Let's say we 
wrote a program that was 100 lines long. Having to type in every memory 
address (locker number) for each program line would be very tedious. Also, 
because some instructions take up more than 1 locker it would be very easy 
to make a mistake and wind up with instructions in the wrong locker.

Instead, we just tell the ASSEMBLER what locker to START putting our program 
into. After that, the ASSEMBLER just goes sequentially down the line of 
lockers adding more instructions according to our source code.

We tell the ASSEMBLER where to start with a line like:

        ORG     $0000

This line, which you'll find near the begining of every Vectrex program tells 
the ASEEMBLER "Start putting program code in memory location $0000".

If you were programming on a different machine, you might start at a 
different locker. However, on the Vectrex you ALWAYS start with locker $0000.

So, instead of our code looking like this:

$1000     sta $C880
$1003     deca
$1004     tsta

It's just going to look like this:

          sta $C880
          deca
          tsta

But, what if for some reason we need to find the lockers with "sta $C880" in 
it? Before, we could say it's in $1000. We always new where it was. But, 
because the ASSEMBLER is doing the counting for us we don't really know 
exactly which locker it's going to put this instruction in. What if we move 
this piece of code around? What if we put something in the locker in front of 
it, so it all gets moved down a locker?

That's what a label is for.

If we need to be able to find this locker later, we attach a label to it like 
this:

kill_ship:
          sta $C880
          deca
          tsta

The characters "kill_ship" is the label, using the colon is what indicates 
that this is a label and isn't considered part of the label itself.

This label acts sort of like a name tag stuck onto the locker. We don't have 
to refer to the actual locker number anymore, we can just refer to the name 
tag (label). When the ASSEMBLER actually translates our source code into 
machine code, it subtitutes the actual locker numbers for any labels.

The big benefit of using labels is that they are a lot easier to remember AND 
they are a lot more meaningful than just a locker number. If at some point in 
the future, you need to find the above code you will remember that it's 
kill_ship, remembering that it was at $1000 would be a lot more difficult. 
Also, if someone else comes along and reads your code, kill_ship gives you a 
pretty good idea of what that code does. $1000 could mean anything.

Taking this one step further, there are often a lot of numbers or values 
you use over and over again. Often these will be declared as constants at the 
begining of a progrma. If you look at any Vectrex source code you will 
generally see a list of such constants. Constants look like:

user_RAM        EQU     $C880

The line above means that whenever the ASSEMBLER sees "user_RAM" later it 
interprets it as $C880. As shown in the Memory section, $C880 is the start of 
RAM available for use by the programmer.

So, by adding this line to the start of our program, whenever we need to look
in the first RAM locker we use, we can say "user_RAM" instead of $C880.

After adding this line to the start of our program, we could change:

kill_ship:
          sta $C880
          deca
          tsta

To instead read:

user_RAM        EQU     $C880


kill_ship:
          sta user_RAM
          deca
          tsta

These two snippets of code mean the very same thing. However, using labels 
and constants has made it much easier to read, and much easier for us to 
remember where things go.

In addition, constants MUST all be placed at the very begining of your source
code, BEFORE any actual instructions. This makes constants even more 
convenient because if you ever forget them, you can just go to the start of 
code and look them up.


Registers
=========

Lockers (memory) can hold either program or data.

If lockers contain data, there's generally not much you can do with it while 
it's sitting in the locker. You have to take it out to use it.

To do this, you take data out of a locker and put it in your pocket. Once in 
your pocket, you can fool around with it. Change it, manipulate it, and 
eventually if you want to, put it back in the locker.

Of course, you have several pockets. A couple in your pants, your jacket and 
of course your shirt pocket with it's pocket protector! So, you can have a 
few things in your pockets without having to put them back into a locker 
while you work with what's in another pocket.

The Vectrex's pocket's are called REGISTERS.

The registers are called (rather unimaginatively) A,B,D,X,Y,U,S,PC,DP and CC.

Some of these pockets actually have pretty specific uses.. You only put your 
wallet in your back pocket or your breast pocket for example. But some are 
very general purpose; your jacket pockets might contain your keys or change 
or...

The A and B registers are 8-bit (1 byte) registers which are the most often 
used for general purpose data manipulation. However, the A and B registers 
are a little weird. They're like how some jeans have a little "change pocket" 
inside the front right pocket. You know, anything in that little pocket, it's 
not in the same pocket as your front right pocket. But, if you think about it 
it sort of is...

A is the right hand pocket. B is the little change pocket. The D register is 
these two pockets combined! The D register is a 16-bit (2 byte) register that 
is actually a combination of A and B.

So, if the A register has a value of $A0 and the B register has a value of 
$FF then the D register has a value of $A0FF. If you change the contents of 
the D register, you ALSO change A and B. If you change A, then you change the
"top" part of D. If you change B then you change the "bottom" part of D.

Generally you are either using A and/or B for their 8-bit storage OR you're 
using D for it's 16-bit storage at any given time. It's sort of "cheating" by 
giving you a couple extra registers without using up any more space because A 
and B "overlap" with D.

Most of your data manipulation type work will be done using A, B or D.

The X and Y registers are two 16-bit registers. They're usually used as 
pointers in Indexed Mode Instructions (see below).

U and S are both Stack Pointers (more on that later).

PC is the program counter. This is the number of the current locker being 
checked to see what instruction to execute. This register can be manipulated
by a variety of instructions to cause the program to progress other than 
sequentially (for example, if you want to execute some code over and over 
again).

DP is a special register for use with Direct Addressing. More on that later 
as well.

CC is the Condition Code Register. It tells you the results of some types of 
instructions the Vectrex just did (ie: If the result was a Zero, or Negative, 
or if there's a Carry or Borrow (for addition/subtraction)).


As an example. Let's say locker number $C880 contains the number of ships a 
player has left in the game. Let's say the player has just qualified for a 
bonus ship by scoring a bunch of points.

What we do, is we go to locker $C880. We see what value is stored in that 
locker (The player could have 1 ship left or 5 or anything...). We take this 
value and put it in A. We then add 1 to A. We put whatever's in A back 
into locker $C880. We then go on to do whatever else needs to be done (play 
some special "Bonus Man" music, continue with the game, etc...)

On the other hand. Let's say the player has just been killed.

Well, then we'd go to locker $C880. Put the contents of that locker into A. 
Now, we subtract 1 from A. Next, we check if A is equal to zero. If it is, we 
go do whatever we need to do to end the game ("Got you humanoid!"). If it's 
not 0, then we put the new value in A into $C880 and continue with the game.

Somewhere else in the program, we would have a some instructions that look 
into $C880 and then print that many ships remaining onto the screen.


Seems like a lot of work, eh?

Well, it is! Nobody said this was easy!

That's why most sane people use C or BASIC or PASCAL....

Actually, it's not really that difficult. The above isn't really the best 
example. It actually IS possible to do some VERY SIMPLE things to data while 
it is still in a locker. So doing something like increasing/decreasing the 
number of ships left would actually be simpler. However, for any complex 
operations you do have to move data out of the locker (memory) and into your 
pockets (registers).


Addressing Modes
================

The 6809 offers 5 different addressing modes.


