Classic Computer Magazine Archive ANTIC VOL. 8, NO. 4 / AUGUST 1989

Mapping the Atari

Exclusive!

Antic brings back the classic 8-bit reference book.

Serialization by Ian Chadwick

Ian Chadwick's "Mapping The Atari" has been one of the core references for Atari 8-bit programmers since the first edition was published in 1983. The book is set up as a comprehensive guide to the memory locations in the Atari 130XE, 65XE, 800XL, 600XL, 1200XL, 800 and 400. But it is much more than that. It is a virtual encyclopedia of indispensible information about the inner workings of the Atari.

This invaluable sourcebook essentially is out of print today, although a few copies of "Mapping The Atari" can still be found in the publisher's warehouse and occasionally at specialty computer stores. Therefore, it is with great satisfaction that Antic announces we are beginning an exclusive serialization of key excerpts from the revised second edition of Chadwick's book. This opening segment provides a useful overview of the material that will be covered in upcoming issues.


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 you are familiar enough with your 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. 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 8-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 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 $FF (255 in decimal), 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 discuss 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 belween 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 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 frequently 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 retumed--for example NOT ((3 + 4) > = 6) results in zero.

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.

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], but 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 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 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.

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, an PUSH have very different meanings in computerese.


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 bit 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 bits 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 semicolons and commas suppress the End-Of-Line charracter (EOL).

DCB: Device Control Block, 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 DOS.SYS that controls all disk I/O. The latest edition of DOS is called DOS 2.0S (S for single density).

DUP: Disk Utilities Package. The software loaded from disk file DUP.SYS 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.

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 SIG. The actual operating system itself is the portion of the OS ROM which handles the I/O.

PMG, PM Graphics: Player/missle 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 randem, 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 retums 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.

Copyright 1983 and 1985, COMPUTE! publications, Inc.

MAPPING THE ATARI
$16.95, COMPUTEI Books, P.O. Box 5406, Greensboro, North Carolina 27403
(919) 275-9809.

Ian Chadwick is a Toronto-based freelance writer.


A Graphics Memory Map

This diagram is not to scale; it is merely meant to give you a visual idea of the structure of the Atari memory. The numbers on the right are the memory pointers: these locations point to the addresses shown. The numbers on the left are the actual locations in memory.


Notes

The bottom of the BASIC RAM depends on whether or not you have DOS files loaded in. Without DOS, LOMEM should be 1792, with DOS 7420. If you increase or decrease the number of disk and sector buffers by modifying DOS, this value will change again. See locations 743, 744 and 1801, 1802.

The size and location of the variable, string and array tables depend on the program use and size. The more variables and arrays, the larger the memory the tables use.

The size and address of the Display List and screen memory depend on the GRAPHICS mode in use.

The first 256 bytes pointed to by LOMEM are the token output buffer. The actual BASIC program starts at the address pointed to by VNTP.


Atari Timing Values

clock frequency = 1.79 MHz
1 machine cycle = 0.558 microseconds
1 frame = 1/60 second
scan lines = 262/frame
color clocks = 228/scan line
color clocks = 2/machine cycle
machine cycles = 29868/frame
machine cycles = 114/scan line

VBLANK time = 7980 machine cycles or less, depending on GRAPHICS mode. The shortest 6502 instruction requires two cycles; during that time the electron beam moves four color clocks.


Horizontal blank time:

Wide playfield  18 machine cycles
Normal
playfield       34 machine cycles
Narrow
playfield       50 machine cycles



   Location Contents Pointers
65535 _____


60906-60905
59716-60905
59093-59092

58534-59092


58533 _____
58496-58533
58448-58495
58432-58447
58416-58431
58400-58415
58384-58399
58368-58383


58367 _____


57344


57343 _____


55295 _____
54784-55295
54272-54783




54016-54271

53760-54015


53504-53759
53248-53503





53247 _____


49151 _____



40959 _____
___________






Size and
location
vary with
GRAPHICS
mode










(OS)

32768

32767 _____





(13062)







Size and
location
vary with
program
size














(7420)



6781
6047
5440
5377




1792


1791 ______











































Top of memory ______________________
Operating System ROM

Device handler routines
Serial Input/Output (SIO) utilities
Interrupt handler

Central Input/Output (CIO) utilities


Operating System vectors_______________
Initial RAM vectors on powerup
JMP vectors
Cassette
Printer
Keyboard
Screen
Editor


ROM Character set ____________________





Floating Point ROM package


I/O chips____________________________
Unused
ANTIC




PIA

POKEY


unused
GTIA or CTIA





Unused 4K ROM block ________________


8K BASIC ROM
or Left cartridge (A) ___________________


Top of BASIC RAM or
____________________________________


Right cartridge (B) ROM if present
(Atari 800 only)







Text window screen RAM
40800 for GR. 0

Bottom of screen RAM
40000 for GR. 0

Display List:
39968 for GR. 0

Top of BASIC RAM




User-program RAM ___________________

The amount of RAM can be ascertained by:
PRINT FRE(0)

Bottom varies: see note below
Depends on buffer area allocated.


RAM used by DOS and File System Manager


Stack for FOR-NEXT & GOSUB






String & array table &
end of BASIC program
BASIC program
area


Statement table:
Beginning of BASIC program
Variable variable table

VNTP + 1

Variable name table

BASIC bottom of memory


Sector buffer
Drive & sector buffer
DOS vector
DUP.SYS start
VTOC buffer
DOS initialization
or BASIC RAM without
DOS resident
FMS RAM
DUP.SYS beginning


RAM used by OS and cartridge.
(to bottom of RAM)

Page six RAM

_________________________________


794-831 HATABS

512,513 VDSLST
514-527 Vectors



_________________________________









756 CHBAS ______________________








_________________________________

756 CHBAS
755 CH1
564-565 LPEN
560-561 SDLSTL
559 SDMCTL
636-639 PTRIG#
632-635 STICK#
624-631 PADDL#
562 SSKCTL
16 POKMSK

704-707 PCOLR#
708-712 COLOR#
644-647 STRIG#
623 GPRIOR


________________________________



________________________________


106 RAMTOP
________________________________
740 RAMSIZ










60,661 TXTMSC


88,89 SAVMSC


560,561 SDLSTL


741, 742 MEMTOP




________________________________










144,145 MEMTOP
142,143 RUNSTK
14,15 APPMHI






140,141 STRAP




136,137 STMTAB

134,135 VVTP

132,133 VNTD

130,131 VNTP

743,744 MEMLO
128,129 LOMRM

4921,4937 SABUFL/H
4905,4913 DBUFA1/H
10,11 DOSVEC


12,13 DOSINI
(743,744 MEMLO)
(128,129 LOMEM)









1535 _____________________________


1406
1405




































RAM used by BASIC______________
(to bottom of RAM)

Floating Point RAM
BASIC RAM

1151








512

511



256

255







128

127





0
Operating System RAM


Cassette buffer

Printer buffer

IOCB's


__________________
Stack




__________________
BASIC zero page RAM

Floating Point pg. 0

Assembler Cart. pg. 0




__________________
OS page zero RAM


Zero page IOCB


Bottom of memory