Author's Preface
What exactly is a memory map? It is a guide to the memory locations in
your computer. A memory location is one of 65536 storage places
called bytes in which a number is stored. Each of these bytes holds a
number for programs, data, color, sound, system operation, or is
empty (i.e., has a zero in it), waiting for you to fill it with your own
program.
Each byte is composed of eight bits, each of which can be either a one
(on) or a zero (off). The alterable area of memory you use for your
programs is called the Random Access Memory (RAM), while the area
used by the Atari to run things is called the Read Only Memory
(ROM). Although some of the memory locations in the special Atari
chips were designed to be written to like the RAM, the rest of the ROM,
including the Operating System ROM, cannot be altered by you since
it contains routines such as the floating point mathematics package
and the input/output routines.
I hope that the reader is familiar enough with his or her Atari to
understand some of these rudimentary uses of a memory map. It is not
the scope of this manual to fully explain how to use PEEK and POKE
statements; refer to your BASIC manual. Briefly, however, PEEK
allows you to look at the value stored in any one memory location. If
you want that value to be printed to the screen, you must preface the
PEEK statement with a PRINT statement such as:
PRINT PEEK (708)
If you haven't changed your color registers, this will return the number
40 to your screen. All bytes in the Atari can hold a number between
zero and 255. POKE allows you to place a value into a byte, such as:
POKE 755,4
By doing this you will have turned your text upside down! You can
return it to normal by:
POKE 755,2
Similarly, POKE 710,80 will turn your screen dark purple! As with
PEEK, POKE can only involve numbers between zero and 255. You will
not be able to POKE into most of the ROM locations since the numbers
in many of them are "hard-wired," "burned" into the chip, and cannot
be changed in this manner.
So how does the Atari (or other eight-bit microcomputers, for that
matter) store a number larger than 255? By breaking it down into two
parts; the Most Significant Byte (MSB), which is the number divided
by 256 and rounded down to the nearest whole number, and the Least
Significant Byte (LSB), which is the original number minus the MSB.
The Atari knows to multiply the MSB by 256 and add the LSB to get the
number. For example, the number 45290 is stored as two parts: 234
(LSB) and 176 (MSB). 176 times 256 equals 45056, plus 234 equals
45290
LEAST-MOST STORAGE
The Atari uses the convention of storing addresses in the LSB/MSB
manner in memory (i.e., the smaller part is in the first memory
location). For example, locations 88 and 89 store the lowest address of
the screen memory. Let's say the numbers found there are 22 and 56,
respectively. To get the decimal address, you take the MSB (stored in
89) and multiply it by 256, then you add it to the LSB at 88. In our case
that's 56 * 256 equals 14336, plus 22 equals 14358. This is the address
of the upper left corner of the screen. A simple way to do this in BASIC
is:
BYTE = PEEK (88) + PEEK (89) * 256
The reverse (to break up a decimal location into MSB and LSB) is done
by:
MSB = INT (BYTE/256):LSB = BYTE - MSB * 256
This process is easier for assembly language programmers who use
hexadecimal numbers, since the right two digits are always the LSB
and the two left of them are the MSB. For example:
$D016 (hexadecimal for 53270) equals 16 (LSB) and D0 (MSB)
$16 equals 22 in decimal, and $D0 equals 208 decimal. Multiply the
MSB by 256 and add 22 and you get 53270. Throughout the map
portion of this book I have provided both decimal and hexadecimal
numbers together for ease of reference. In 8K BASIC, you can use
decimal numbers only with POKE, and PEEK will return only decimal
values to you.
Hexadecimal is a base 16 used instead of the normal base ten system
because it is more suited to the eight-bit structure of the computer. So,
when we say 2175 in decimal, what we really mean is:
10000 1000 100 10 1
0 2 1 7 5
In hex, the same number is $87F. That breaks down to:
4096 256 16 1
0 8 7 F
Rather than multiply each next step up by ten, we multiply by 16.
Okay, but where do we get "F" from? Well, if base ten has the numbers
zero to nine, base 16 will have to have some letters added to the end to
make up for the extra numbers:
Decimal 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Hex 0 1 2 3 4 5 6 7 8 9 A B C D E F
So $F equals 15 in decimal. Now here's how it all relates to binary math
and bits:
Each byte can be broken up into two parts (nybbles), like this:
0000 0000
If each nybble is considered a separate number, in decimal, the value
of each would range from zero to 15, or zero to $F. Aha! So if all the
bits in each group are on (one, or set), then you have:
1111 1111 Binary
15 15 Decimal
F F Hex
You join the two hex numbers together and you get SFF (255 in deci-
mal), the largest number a byte can hold. So you can see how we
translate bytes from binary to hex, by translating each nybble. For
example:
1001 1101 Binary
9 13 Decimal
9 D Hex
$9D equals nine times 16 plus 13, or 157 in decimal.
0100 0110 Binary
4 6 Decimal
4 6 Hex
$46 equals four times 16 plus six, or 70 in decimal.
1111 1010 Binary
15 10 Decimal
F A Hex
$FA equals 15 times 16 plus ten, or 250 in decimal.
Obviously, it is easier to do this with a translation program or a
calculator!
Since I will often be discussing setting bits and explaining a small
amount of bit architecture, you should be aware of the simple
procedures by which you can turn on and off specific bits in any
location (that is, how to manipulate one of the eight individual bits
within a byte). Each byte is a collection of eight bits: numbers are
represented by turning on the particular bits that add up to the number
stored in that byte. Bits can be either zero (0 equals off) or one (1
equals on, or SET). The bits are numbered zero to seven and represent
the following decimal numbers:
Bit 7 6 5 4 3 2 1 0
Value 128 64 32 16 8 4 2 1
The relationship between the bits and the powers of two should be
obvious. Adding up all the numbers (all the bits are set) gives us 255.
So each byte can hold a number between zero (no bits are set) and 255
(all bits are set).
Sometimes, instead of zero, no bits set is intended to mean 256. That
will be noted in the relevant locations. So how do you set a bit? Simple:
POKE it with the appropriate number. For example, to set Bit 5, POKE
the location with 32. To set Bits 7, 5 and 4, add up their values, 128 +
32 + 16, and POKE the location with the total: 176.
Sometimes you need to set a bit without changing other bits already
set, so you:
POKE number, PEEK (number) + decimal value for the bit to be set.
(i.e., POKE 50418, PEEK (50418) + 32)
To turn off a bit, instead of adding the value you would subtract it with
POKE number, PEEK (number), minus the decimal value for the bit to
be turned off. Binary math is simple and easy to learn; if you don't
understand it now, you should do further reading on machine
language before attempting any serious use of this guide.
AND, OR, And EOR
It is useful for the reader to know how to perform Boolean logic on bits.
There are three functions used in assembly code for bit manipulation
in this manner: AND, OR and EOR (exclusive OR). Each requires you
to use two numbers, the one being acted upon and the one used to
perform the function. Here is a brief explanation of how these logical
functions work:
AND is usually used as a mask--to zero out unwanted bits. You
compare two binary numbers using AND; if both bits in the same
location are one, then the result is one. If either bit is zero, then the
result is zero. For example:
51 = 00110011
AND 15 = 00001111
--------
Result = 00000011 = 3
OR is freguently used to force setting of a bit. If either bit in the
original or the mask is one, then the result is one. For example
65 = 01000001
OR 128 = 10000000
--------
Result = 11000001 = 193
In this case, 65 is the ATASCII "A". By ORing it with 128, we get 193,
the ATASCII inverse "A".
EOR "flips" bits in the original if the mask has a one in the same
location. For example:
193 = 11000001
EOR 128 = 10000000
--------
Result = 01000001 = 65
In this case, we have returned the inverse "A" to the normal ATASCII
value. An EOR with 255 (all ones) will produce the complement of the
number:
171 = 10101011
EOR 255 = 11111111
--------
Result = 01010100 = 84
In brief:
Original: Mask: AND: OR: EOR:
0 0 0 0 0
0 1 0 1 1
1 0 0 1 1
1 1 1 1 0
Atari BASIC supports AND, OR and NOT; NOT is the logical
complement where NOT1 equals zero and NOT0 equals one. If the
expression is true, you get a zero; if NOT true, a one is returned--for
example, NOT ((3 + 4) >= 6) results in zero. See COMPUTE!, May
1981 for a machine language routine to allow you to perform Boolean
bit logic using a USR call from BASIC.
In general, I have attempted to avoid using 6502 assembly language
mnemonics, but have included them where I felt their use described
the action to be taken better than a lengthy explanation. Most common
are JMP (jump to location), JSR (jump to subroutine), RTS (return from
subroutine), and RTI (return from interrupt). Readers should be
minimally familiar with machine language in order to understand any
machine language subroutines used here.
I also suggest that if the reader doesn't already have one, he or she
obtain a program to translate hex to decimal and decimal to hex
(possibly even one with binary translations as well). The ROM
cartridge from Eastern House Software, Monkey Wrench, is useful for
this purpose. Perhaps the easiest to use is the TI Programmer
calculator from Texas Instruments.
The examples in this book were all written using Atari 8K BASIC. They
are intended to demonstrate the use or the effect of a particular
memory location. They are not intended as the best examples of
BASIC programming; they were written for simplicity, not
sophistication.
As a final note, any question or doubt as to either a particular location
or explanation has been noted. It can't hurt to play around yourself,
POKEing in the memory to see what other effects you can discover. If
you find something I didn't, good! Please write and let me know.
You can't hurt the machine by POKEing about in memory, although
you may crash any program in memory, so SAVE your program first.
Usually you can salvage it by pushing RESET, hut you may have to
turn off the machine and reboot on occasion. You can learn a lot about
your machine by simply playing around with it.
ABOUT LANGUAGES
The majority of the information here concerns language-independent
locations and can be used regardless of the language you use for your
programming. When the location is language-dependent, such as the
BASIC or DOS areas, I have noted it in the proper section. You may
exert the same control over your Atari in FORTH, Pascal, LISP, or
whatever language you chose. You will obviously have to change the
commands PEEK and POKE to the proper commands of your
language.
BASIC is a good language to start with: you can use it to learn
programming, to explore your computer, to experiment with, and to
have fun with. However, when you are ready to go on, you will have to
learn a more efficient, faster language if you really want to make the
best use of your Atari. Many people choose 6502 machine language
because of its speed.
If you want to stay with a high-level language, I suggest you learn
FORTH. It has some of the speed of machine language code with the
ease of "higher level language" programming.
Computer languages, whichever you use, are quite exact in their
meaning, especially compared to English. Consider that in English, a
fat chance and a slim chance both mean the same thing. Yet POKE,
PUT, and PUSH have very different meanings in computerese.
TEXT KEY
Example: 912-927 390-39F IOCB5
The main memory map shows you the decimal and then the
hexadecimal location, the label (assigned by Atari and used by OS,
DOS or DUP routines), and then comments and description. The label
has no real function; it is merely a mnemonic convenience. Readers
are referred to Stan Kelly-Bootle's delightful book, The Devil's DP
Dictionary (McGraw-Hill Ryerson, 1981), for a full definition of the
word "label". The following abbreviations are also noted in the
comments:
(R) Read
(W) Write
Sometimes the functions are different in a particular location, so each
is noted.
(D:) Disk Drive
(F:) Screen Editor
(S:) Display
(K:) Keyboard
(P:) Printer
(C:) Cassette
(R:) RS-232 interface. (Don't confuse this with (R) for Read.) The
context should be obvious.
(number) e.g. (708) Shadow Register. This is a RAM register which
corresponds to a ROM register in one of the special Atari chips such as
GTIA or POKEY. The shadow location is the address you use to PEEK
and POKE values. These shadow locations are polled by the hardware
addresses 30 times a second at every stage two VBLANK interval, and
the values used are transferred to the hardware locations for use. In
order to effect any "permanent" change to the hardware location, you
have to use the shadow register in BASIC (of course, every change is
negated when you turn the machine off!). Only machine language is
fast enough to use the hardware addresses directly.
For example, location 54273 is for character control. It polls location
755 to see if the screen characters are to be normal, inverse, or upside-
down. To change the characters, you POKE location 755--the shadow
--not 54273. If you POKE 54273, you will get the desired effect--for
1/60 of a second! As mentioned above, you can use the hardware
addresses directly in machine language, but not in BASIC. It's just too
slow.
Sometimes, where most appropriate, a hexadecimal number will be
displayed and the decimal number put in parentheses. The context
should be obvious concerning which is a shadow or a decimal number.
(* letter) refers to a source in the case of a conflicting location
or explanation. See the source below.
($number) refers to a hexadecimal (also called hex) number
(i.e.: $D40E). I also refer to "pages" in memory. Pages are
sections of 256 bytes ($100) of memory which end with 00 (i.e.:
$E200, $C000, $600). Four pages ($400) equals 1024 bytes or 1K
(kilobyte) of memory.
GLOSSARY
ANTIC, CTIA AND GTIA, PIA, POKEY: Special Atari
chips controlling the 400/800's graphics, color and screen
resolution, controller jacks and sound, respectively. Located in
ROM, locations 53248 to 54783. ANTIC also processes the Non-
Maskable Interrupts and POKEY processes the Interrupt Requests.
These chips, along with the 6502 microprocessor which runs the
rest of the Atari, are housed inside your computer, protected by
the metal shielding underneath the plastic cover.
BIT, BYTE: A hit is the smallest size division of memory in your
computer. It is so small that it can hold only one value in it: off
(zero) or on (one). Eight hits together form a byte; this is the size of
the memory locations discussed in this book. You will sometimes
hear programmers talk about a half-byte called a "nybble."
CIO: Central Input/Output routines located in ROM. Controls
Input/Output Control Block operations. Briefly, CIO handles the
data input and output through the device driver(s) (also known as
device handlers), then passes control to those drivers. It's a single
interface with which to access all peripherals in a device-
independent manner (i.e., uniform handling of data with no
regard to the device being accessed). As an example: writing data
to a disk file is treated in an identical manner as writing data to the
screen; commas insert blanks between elements and both semi-
colons and commas suppress the End-Of-Line character (EOL).
DCB: Device Control Block, used by Serial Input/Output.
DL: Display List. This is a set of instructions which tell the ANTIC chip
where to find the screen display data and how that data is to be
placed on the TV screen.
DLI: Display List Interrupt. A DLI causes the display to stop
processing to temporarily run a user-written routine.
DOS: Disk Operating System. The software loaded from disk file
DOSSYS that controls all disk I/O. The latest edition of DOS is
called DOS 2.OS (S for single density).
DUP: Disk Utilities Package. The software loaded from disk file
DUPSYS that handles the DOS menu functions such as Copy.
FMS (or sometimes DFMS): File Management System portion of
DOS; a dedicated device driver that controls all I/O operations for
device "D:".
FP: Floating Point mathematical package in ROM.
I/O: Input/Output.
IOCB: Input/Output Control Block. Area of RAM (locations 832
to 959) used by CIO to define operations to devices such as the
disk drive (D:), printer (P:), screen display (S:), keyboard (K:) and
screen editor (E:). ZIOCB is the page zero IOCB.
IRQ: Interrupt request used for serial port communication,
peripheral devices, timing and keyboard input. IRQ's are
processed by the POKEY chip.
NMI: Non-Maskable Interrupt; used for video display and
RESET. NMIs are processed by the ANTIC chip.
OS: Operating System. The resident system that runs the Atari.
The OS resides in the 10K front cartridge slot under the hood in
your Atari 800. It's not visible in the 400 without taking the cover
apart (not recommended). The OS is the same for both the 400 and
800. There are two versions of the OS currently in circulation: the
older "A" ROMs and the newer "B" ROMs, released around
January 1982. The new OS is almost identical to the old OS except
that it corrects a few bugs and changes some addresses. Not all of
your old software will run with the new OS. The differences
between the two are better explained in Appendix Four.
Although people often refer to the entire ROM area as the OS, this
is not correct. The OS ROM is that portion of memory which holds
the floating point package, the Atari character set, the device
handlers, and both CIO and SIO. The actual operating system
itself is the portion of the OS ROM which handles the I/O.
PMG, PM Graphics: Player/missile graphics. Players and
missiles are special moveable, user-defined, colored screen
objects. They are often used for games, animation, or special
cursors. PM graphics are unique in that you can establish the
manner (priority) in which they interact with the rest of the screen
display and each other.
RAM: Random Access Memory. All memory below the OS area
(0 to 49151) which is used for storage, programs, buffers,
cartridges, DOS, IOCB, shadow registers, and registers for the
special Atari chips. Random Access means you can get to and
from these locations at random, not that they store information
randomly!
ROM: Read Only Memory. That part of high memory (locations
49152 to 65535) in which the special hardware chips and the OS
reside. ROM is also used to describe cartridge memory such as the
8K BASIC ROM, which cannot be user-altered (the cartridge
ROM supersedes the RAM). You cannot alter most of the ROM,
although some of the locations in the special Atari chips may be
temporarily set to a new value.
With both RAM and ROM, we refer to areas with lesser values as
being in "low" memory and locations with larger values as being in
"high" memory.
SIO: Serial Input/Output routines located in ROM. Controls
serial operations including the 850 interface (R:) and cassette
recorder (C:). Briefly, SIO controls the Atari peripherals as per
the request placed in its Device Control Block (DCB) by the
proper device driver. It is also accessed by FMS for data transfer.
VBI: VBLANK interrupt. A VBI is an interrupt that occurs
during the VBLANK interval, causing the computer to jump to a
user-specified location to process a short user-written routine
during the VBLANK process.
VBLANK: Vertical Blank. The interval between the time the TV
electron beam turns off after reaching the bottom right corner of
the screen and returns to the top left corner and turns back on
again. This small time period may be used by machine language
programmers for short routines without interrupting the display
by writing a VBI (above). There are two VBLANK stages. Stage
one is performed every VBLANK cycle (1/60 second). Stage two
is performed either every 1/30 second or every 1/60 second when
it doesn't interrupt time-critical code being executed. See the
end of the memory map for the processes executed in each stage.
SOURCES
Letters in brackets are used in this guide to identify the source.
(*M) Master Memory Map Ver. 2, Santa Cruz Educational Software,
1981. A memory guide by the same people who brought us the
TRICKY TUTORIAL series. The latter are both tutorials and
applications utilities. The map does contain some annoying errata.
(*Y) Your Atari Computer, by Lon Poole with Martin McNiff & Steven
Cook, Osborne/McGraw-Hill, 1982. The best guide to date on general
use of the Atari. Very highly recommended
(*C) COMPUTE!'s First Book of Atari, by the Editors of COMPUTE!
Magazine, Small System Services Inc., 1981. A good collection of
early articles that appeared in the magazine.
At the time of this writing, COMPUTE!'s Second Book of Atari had just
been released. It is therefore not used as a reference source here, but it
is a must for serious programmers. It contains a wealth of information
on an enormous range of topics, including advanced graphics, forced-
read modes, page flipping, Atari BASIC and many valuable utilities. It
should be a staple in most Atari owners' libraries.
(*I) Inside Atari DOS, compiled by Bill Wilkinson, published by
COMPUTE! Books, Small System Services, Inc., 1982. An
explanation and copyrighted source code for the FMS portion of DOS
2.0.
Atari BASIC: Learning by Using, by Thomas Rowley, Hofhacker
Press, 1981. A lot of information packed into a surprisingly good little
book.
The following publications are all from Atari, Inc. I recommend them
to all truly interested in understanding their Atari computers:
(*D): De Re Atari: an arcane, but indispensable reference to the
Atari's operations and come of its most impressive aspects, by Chris
Crawford et al. Serialized in BYTE magazine, late 1981 to mid 1982.
Earlier editions have some errata, so make sure you obtain the latest
edition.
(*O) Operating System User's Manual and
(*H) Hardware Manual. The famous "technical manuals" pair.
Indispensable for serious users, albeit heavy going and not generally
very professional in their presentation of material.
(*8) 850 Interface Module Operator's Manual. The 850 manual gives
many examples in BASIC of how to use the RS232 serial interface ports
for both printer control and telecommunications. A very good terminal
program called Jonesterm, in BASIC with machine language
subroutines, is in the public domain and is available on many
electronic bulletin board systems, including CompuServe. Modem
users will find many useful programs available in CompuServe.
(*L) Operating Systems Listing and
(*U) Disk Utilities Listings are the commented, copyrighted source
code listings for the OS and the DUP.SYS portion of DOS.
(*B) Atari BASIC Reference Manual.
(*S) Disk Operating System II Reference Manual.
(*A) Atari Microsoft BA SIO Instruction Manual. Microsoft BASIC
makes excellent use of PEEKs and POKEs to accomplish many tasks. It
also has many powerful commands not available in the 8K BASIC.
MAGAZINES
ANTIC Magazine had an extensive memory map, written by James
Capparell, which continued over a number of issues. When it was used
as a source, I labelled these references with (AM). It has a few minor
errata in it.
I found a number of other magazine articles useful, particularly those
in COMPUTE! and Creative Computing. I also found Softside, BYTE,
ANALOG and Micro magazines to be useful in the preparation of this
book. These are all referred to throughout the book by month or issue.
We owe a vote of thanks to the folks at Atari who published the
technical manuals and the source listings of the operating system and
the DOS. We owe another vote of thanks to Bill Wilkinson, of
Optimized Systems Software Inc., who created the DUP portion of
DOS and decided to publish the source code in his Inside Atari DOS.
No other computer manufacturer has, to my knowledge, ever provided
users with such in-depth material or the details of its own operating
systems. Without it, none of this would have been possible: a lot of the
information here was gleaned from those sources.
This book is arranged in four sections: a numerical listing of the main
Atari memory locations, their labels and their use; a general map
diagram to show how the memory is broken down; an appendix of
utility material with charts and tables, and an index/cross-reference
guide.
There is an awful lot of information contained here; tedious as it might
appear, I suggest that you read this manual through at least once.
Some of the information which is not clear in one area may be
elaborated on and made clearer in another area. Wherever another
location is referred to in one description, you should turn to the
reference and read it after you have read through the first location.
You should also refer to the locations used in any sample program. The
more familiar you are with the memory, the more you will get out of
your Atari. When you read the description in any memory location,
make sure you refer to either the shadow or the hardware register
mentioned for more information.
POWERUP AND RESET
COLD STARTS
On powerup (when you turn on the computer) the Atari OS performs a
number of functions, some of which are noted as defaults in the
memory locations to follow. Among these functions are:
Determine the highest RAM address and clear all RAM to zeroes
(except locations zero to 15; $0 to $F).
Erase and format the device table.
S:, E:, K:, P:, C: handlers, SIO, CIO and interrupt processor are all
initialized.
Set the screen to GRAPHICS mode zero, 24 lines by 40 columns; set
screen margins.
Initialize the cartridge(s) if present; test for the B (right), then for the A
(left) cartridge.
Check the cartridge slots for disk boot instructions and, if they are
present, boot disk.
Transfer control to the cartridge or booted program.
Initialize the RAM interrupt vectors at 512 to 548 ($200 to $224).
Store zero in the following hardware registers: 53248 to 53503, 53760
to 54527 ($D000 - $D0FF, $D200 - $D4FF).
The START key flag is tested and, if set (the START key is held down),
CKEY (74; $4A) requests a cassette boot
HATABS (794; $31A) is initialized to point to the ROM-resident device
handlers.
IOCB zero is OPENed to device E:.
Coldstart (powerup) essentially wipes the computer clean and should
only be used for such. It's rather drastic.
WARM STARTS
When the RESET key is pushed, the OS performs some of the same
functions as in powerup as well as some unique functions, including:
Set the warmstart flag (location 8) to true (255; $FF).
Clear the OS portion of RAM from locations 16 to 127 ($10 - $7F) and
512 to 1023 ($200- $3FF).
Reset all RAM interrupt vectors.
Reformat the device handler table (HATABS); added vectors are lost.
Re-initialize the cartridge(s).
Return to GRAPHICS mode zero.
Transfer control to the cartridge or hooted program.
Restore the default values in RAM.
Note that a RESET does not wipe RAM, but leaves it intact. Usually
your program and variables will be secure when you press RESET.
This is considerably less drastic than powerup as above.
There are two vectors for initialization so that these processes may be
user initiated: 58484 ($E474) for RESET and 58487 ($E477) for
powerup.
See the OS User's Manual, pages 109 to 112, and De Re Atari for a
flowchart of the process.
Return to Table of Contents
| Previous Chapter
| Next Chapter