Mapping The Atari
Mapping The Atari
Mapping The Atari
95
MAPPING
THEATARI Ian Chadwick
Introduction by Bill Wilkinson
REVISED EDITION
The comprehensive sourcebook and memory guide for
beginning and veteran programmers of the Atari 400,
800, XL, and XE personal computers .
" I
( MAPPING
THE ATARI
Revised Edition
Ian Chadwick
Introduction by Bill Wilkinson
22~eM!!tEubJications~lnc .•
Greensboro, North Carolina
Revised edition copyright 1985, Ian Chadwick. All rights reserved.
109 8 7 6 5 4 3 2 1
ISBN 0-87455-004-1
We do not accept any responsibility for any damage done to the reader's
programs through use or misuse of the information presented here. Readers
are advised to read the warning in the introduction with regard to saving
critical programs and removing important disks or cassettes before attempt-
ing to use this manual.
The author and publisher have made every ettort in the preparation of this book teo in-
sure the accuracy of the programs and information. However, the information and pro-
grams in this book are sold without warranty. either express or implied. Neither the
author nor COMPUTE! Publications, Inc, will be liable tor any damages caused or al-
leged to be caused directly, indirectly, incidentally, or consequentially by the programs
or information in this book.
COMPUTE! Publications, Inc" Post Office Box 5406, Greensboro, NC 27403, (919)
275-9809, is one 01 the ABC Publishing Companies and is not associated with
any manufacturer of personal computers, Alari 400, 800, 1200XL, 600XL,
800XL, 65XE, and 130XE are trademarks of Alart Inc.
L.J
Contents IIIIIIII
_ _ _ _ _ _ _ __
f~l
Author's Preface to the Revised Edition ... ... ..... v
Author's Preface . . . . . . . . . . .. .. vii
Introduction / Bill Wilkinson .. , , , . xxi
Memory Map . . .. " " ' " ... . . . . 1
Appendix 1. VBLANK Processes 154
Appendix 2. A Graphics Memory Map ., 155
Appendix 3. Atari Timing Values ,. " " " " 160
Appendix 4. Old (A) and New (B) ROMs. .. .... 161
Appendix 5. Color . . . . . . .. ..... .......... 163
Appendix 6. Sound and Music ............ ,... 167
Appendix 7. Player/Missile Graphics
Memory Map . . . .. . ... ,.... 169
Appendix 8. Display Lists ... ...., 171
Appendix 9. Numerical Conversions ., .. ,,'," 175
Appendix 10. ATASCII and Internal Character
Code Values , , , , , , . , . , ... " ,', 180
Appendix 11. Addenda and Errata to the
First Edition .... ,.. ......... .... 182
Appendix 12. The XL/XE Memory Map ...... , ... 200
Appendix 13. XL/XE Enhancements and Bugs 230
Appendix 14. The XL/XE Parallel Bus .. . . . . . . . . .. 232
Appendix 15. XL/XE Graphics Modes ........ , 236
Appendix 16. Memory Management on the l30XE 238
Appendix 17. DOS 2.5 and the 1050 Drive .,' 241
Appendix 18. Changing the 400/800 OS
on the XL/XE Computers , ... " .. ,' 244
Appendix 19. XL/XE Programs ..... ,', ... ,',.,' 247
XL/XE Index ........ , ....................... , , ,. 255
Index by Label . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 258
Index by Subject ........ ," ............... '.... 263
iii
\_-
'-.-J Author's Preface _ _ __
To The Revised Edition
In the past two years, many people have written to me about Map-
ping-mostly complimentary. I was gratified that no serious errors
were uncovered, only a few typos and minor corrections-a tribute
to COMPUTEI's editing skills. There are too many people to mention
everyone, but I appreciate the efforts of you, the readers; please
continue to write to me, even if I can't answer every letter.
Special thanks to Joe Miller of Koala Technologies (previously
with Atari, author of the Translator disk, and frequent CompuServe
user), Matt Ratcliff (remote sysop on the Gateway BBS), Randy Tjin of
Atari Canada, Neil Harris and Richard Frick of Atari USA for tech-
nical support, Bill Wilkinson for the frequent mentions in COMPUTE!
magazine, Gary Yost of Antic, and my friend Yoram Rostas for his in-
cessant prodding and poking into the machine. Also to Atari for its
"open system" policy which helped make this book possible.
The Atari SIG on CompuServe has been a great help and sup-
port; it may be the best source of information and public domain
software for the Atari presently available. If you haven't used
CompuServe, I highly recommend that you do so; the sysop, Ron
Luks, and his group run a super online operation. Ron helped me
gather some of this information by putting up a special message ask-
ing for suggestions and answers to questions I had.
Most of all, lowe an immeasurable amount of love, gratitude,
and affection to the ever-patient Susan McCallan, my constant
companion these past two-plUS. How she stands me, I've never quite
figured out, but I hope she continues to do so for a long time. This
book is for her.
v
As for books, The Programmer's Reference Guide for the Atcxri
400/800 computers by David Heiserman (Howard Sams, 1984) is a
good "single volume" reference, Mark Chasin's Assembly Language
Programming for the Atari Computers (McGraw-HilL 1984) is highly
recommended; it provides many excellent examples strictly for Atari
users, explaining such difficult concepts as I/O, handlers, and VBIs,
Carl Evans's Atari BASIC Faster and Better (IJG, 1983) is an excellent
technique book for BASIC programmers who want to improve their
style and learn some machine language,
Jerry White, well-known Atari software author, coauthored (1
good compendium with Gary Phillips called The Atari User's
Encyclopedia (The Book Company, 1984), Linda Schreiber's Ad-
vanced Programming Techniques for Your Atari (Tab, 1983) has sev-
eral good routines for graphics and strings in BASIC,
COMPUTE! Books has published several good books, including
COMPUTEt's Third Book of Atari, COMPUTEt's First and Second Book
of Atari Graphics, and COMPUTEt's First Book of Atari Games, A real
hacker's delight is The Atari BASIC Sourcebook, by Bill Wilkinson,
Kathleen O'Brien, and Paul Laughton, which includes the entire
source code for Atari BASIC-a must for serious BASIC users (along
with Wilkinson's Inside Atari DOS). One of COMPUTE!'s best books
recently is Richard Mansfield's Machine Language for Beginners,
a painless way to introduce yourself to machine language
programming,
Finally, for the real hardware buff, Atari once published the:lr
400-800 Home Computer Field Service Manual (part # FD 10000 1); it
has a wealth of data, schematics, parts lists, diagnostic tests, and
assembly information, It's hard to get, but worth it. An BOOXL Field
Service Manual is also available, Sams has released an excellent
hardware technical service manual for the 800 and 800XL, it's expen-
sive, but contains material any hardware hacker needs to know,
It looks like the Atari will have a long life; it's already into it!;
third generation (all compatible), I'm glad to see that the recent
change in ownership did not spell the end of my favorite home com- 4
puter, but rather Jack Tramiel is continuing to support and develop it
as well as maintain compatibility between models, I'm looking for- '-
ward to seeing his new 68000-based ST machines,
March 1985
Ian Chadwick
55 Kent Rd
(-
Toronto, Ont.
M4L 2X5
Canada
CompuServe 70375,1010
vi
~ 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 (Le., 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 anyone 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
,_I 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 2557 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
vii
-'
AUTHOR'S PREFACE
(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 LSBIMSB
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 5/3, !-
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 CCise
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 DO (MSB)
$16 equals 22 in decimal, and $DO 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
o 2 175
In hex, the same number is $87F. That breaks down to:
4096 256 16 1
o 8 7 F
Rather than multiply each next step up by ten, we multiply by 16.
Okay, but where do we get \IF" 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 ABC D E F '-
viii
AUTHOR'S PREFACE
ix
AUTHOR'S PREFACE
obvious. Adding up all the numbers (all the bits are set) gives us 2513.
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.
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:
x
AUTHOR'S PREFACE
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:
--.J
171 = 10101011
EOR 255 = 11111111
Result = 01010100 = 84
In brief:
Original: Mask: AND: OR: EOR:
0 0 a a a
0 1 a 1 1
1 a a 1 1
1 1 1 1 a
Atari BASIC supports AND, OR and NOT; NOT is the logical
complement where NOn equals zero and NOTO 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 IMP (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
xi
---------------------
AUTHOR'S PREFACE
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, 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 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 IOCSS
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.
xii
AUTHOR'S PREFACE
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
xiii
AUTHOR'S PREFACE
xiv
AUTHOR'S PREFACE
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 th~ 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'1 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 explainJd 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 Atati character set, the device
handlers, and both CIO and SIO. The actual operating system
itself is the portion of the OS ROM ~hich 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 spme 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.
VB!: VBLANK interrupt. A VBI is an interrupt that occurs
xv
AUTHOR'S PREFACE
xvi
AUTHOR'S PREFACE
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
xvii
AUTHOR'S PREFACE
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 migrht
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.
xviii
AUTHOR'S PREFACE
xix
INTRODUCTION _ _ _ __
Bill Wilkinson
A Common Problem
What? Still with me? Does that mean that you are not comfortable
doing memory mapped access in three or four languages? Well, to tell
the truth, neither am 1. And so the one thing I decided would be of
most value in this introduction would be a summary of how to do
memory access from no less than seven different languages. (Or is it
eight? Well .... )
The title of this section is perhaps a little misleading (on purpose,
of course, as those of you who read my column "Insight: Atari" in
COMPUTE! Magazine can attest). The "common problem" we will
discuss here is not a bug-type problem. Rather, it is a task-type
;~'
problem which occurs in many common programs. Or perhaps we
could approach it as a quiz. Why not?
Quiz: Devise a set of routines which will (1) alter the current
cursor pOSition (in any standard OS graphics mode) to that
horizontal and vertical position specified by the variables "H" and
"V" and (2) retrieve the current cursor pOSition in a like manner.
To receive full credit for this problem, implement the routine in at
least seven different computer languages.
xxi
INTRODUCTION
Well, our first task will be to decide what seven languages we will
use. First step in the solution: find out what languages are available on
the Atari computers. Here's my list:
Atari BASIC
BASICA+
Atari Microsoft BASIC
Forth
C
Pascal
PILOT
LISP
AssemblerlMachine Language
Does it match yours? You don't get credit for more than one
assembler or more than one Forth. And, actually, you shouldn't get
credit for Microsoft BASIC, since it uses exactly the same method as
Atari BASIC. And I will tell you right now that I will not attempt this
task in LISP. If you are a LISP fanatic, more power to you; but I don't
have any idea of how to approach the problem with Datasoft's LISP (the
only LISP currently available on the Atari).
Anyway, let's tackle these languages one at a time.
Atari BASIC And Microsoft BASIC
Well, how about two at a time this one time? The implementation really
is the same for these two languages.
Actually, the first part of this problem set is done for you in Atar!
BASIC: the POSITION statement indeed does exactly what we want
(POSITION H, V will do the assigned task). But that's cheating, since
the object of these problems is to discover how to do machine level
access without such aids.
Step I is to look at the memory map and discover that COLCRS, at
locations 85 and 86, is supposed to be the current graphics cursor
column (COLumn of CuRSor). Also, ROWCRS (ROW of CuRSor) at
location 84 is the current graphics cursor row.
Let's tackle the row first. Assuming that the row number is in the
variable "V" (as specified above), then we may set the row cursor via
"POKE 84,V". And, in a like manner, we may say "V =PEEK(84)" to
assign the current position to "V". Now that's fairly straightforward: to
change a single memory location, use "POKE address,value"; to
retrieve the contents of a single memory location, use
"PEEK(address}". Virtually anyone who has programmed in BASIC on
an Atari is at least familiar with the existence of PEEK and POKE, since
that is the only method of accessing certain functions of the machine
(and since the game programs published in magazines are loaded with
PEEKs and POKEs).
But now let's look at the cursor column, specified as being
xxii
INTRODUCTION
locations 85 and 86, a "two byte" value. What does that mean? How
can something occupy two locations? Actually, it all stems from the
fact that a single location (byte, memory cell, character, etc.) in an
Atari computer can store only 256 different values (usually numbered
oto 255). If you need to store a bigger number, you have to use more
bytes. For example, two contiguous bytes can be used to store 65536
different values, three bytes can store 16,777,216 different values, etc.
Since the Atari graphics mode can have as many as 320 columns,
we can't use a single one-byte location to store the column number.
Great! We'll simply use two bytes and tell BASIC that we want to talk to
a bigger memory cell. What's that? You can't tell BASIC to use a
bigger memory cell? Oops.
Ah, but have no fear. We can still perform the task; it just takes a
little more work in BASIC. The first sub-problem is to break the
column number (variable "H") into two "pieces," one for the first byte
and one for the second. The clearest way to accomplish this is with the
following code:
HI = INT( H/256)
H2 = H -256 * HI
Because of the nature of machine language "arithmetic," numbers
designed to be two-byte integers must usually be divided as shown: the
"high order byte" must be obtained by dividing the number by 256,
and any fractional part of the quotient must be discarded. The "low
order byte" is actually the remainder after all units of 256 have been
extracted (often designated as "the number modulo 256").
So, if we have obtained "H 1': and "H2" as above, we can change
the cursor row as follows:
POKE 85,H2
POKE 86,HI
Notice the reversal of the order of the bytes! For the Atari (and
many other microcomputers), the low order (or least significant) byte
comes first in memory, followed by the high order (or most significant)
byte.
Now, suppose we wish to avoid the use of the temporary variables
"H I" and "H2" and further suppose that we would now like to write the
entire solution to the first problem here. Voila:
POKE 84,V
POKE 86,INT( H/256)
POKE 85,H -256 * INT( H/256 )
And we wrote those last two lines in "reverse" order so that we
could offer a substitute last line, which will not be explained here but
which should become clear a few paragraphs hence:
POKE 85,H -256*PEEK( 86 )
xxiii
-""-----------
INTRODUCTION
Whew! All that to solve just that first problem! Cheer up, it does
get easier. In fact, we already mentioned above that you can retrieve
the current row via "PEEK(84)". But how about the column?
Again, we must remember that the column number might be big
enough to require two adjacent bytes (locations, memory cells, etc.).
Again, we could construct the larger number via the following:
H2 = PEEK( 85 )
HI = PEEK( 86 ) '---
H = H2 + 256 * HI
Do you see the relationship between this and the POKEs? To "put
it back together," we must multiply the "high order byte" by 256
(because, remember, it is actually the number of 256's we could obtain
from the larger number) before adding it to the "low order byte."
Again, let us summarize and simplify. The following code will
satisfy the second problem requirement for BASIC:
V = PEEK( 84)
H = PEEK( 85) + 256 * PEEK( 86 )
Okay. We did it. For two languages. And if you are only interested
in BASIC, you can quit now. But if you are even a little bit curious,
stick with us. It gets better.
BASICA+
There might be a little bit of prejudice on my part here, but I do feel
that this is the easiest language to explain to beginners. In fact, rather
than start with text, let's show the solutions:
Problem l.
POKE 84,V
DPOKE85,H
Problem 2.
V = PEEK( 84)
H = DPEEK( 85 )
As you can see, for the single memory cell situations, BASIC A +
functions exactly the same as the Atari and Microsoft BASICs. But for
the double-byte problems, BASIC A + has an extra statement and ,:m
extra function, designed specifically to interface to the double-byte
"words" of the Atari's 6502 processor.
DPOKE (Double POKE) performs exactly the equivalent of the two
POKEs required by Atari BASIC. DPEEK (Double PEEK) similarly
combines the functions of both the Atari BASIC PEEKs. And that's it.
Simple and straightforward.
Forth
I think the ease of performing the required problems in Forth will show '-
how tightly and neatly Forth is tied to the machine level of the
XXIV
INTRODUCTION
C
No, that does not mean "Section C." Believe it or not, "C" is the name
of a computer language. In fact, it is one of the more popular computer
xxv
INTRODUCTION
*pc = V; *pi = H;
Problem 2.
char *pc;
int *pi;
pc = 84 ; pi = 85 ;
V = *pc; H = *pi;
As with the Pascal solutions, in the follOWing section, we must
declare the "type" of a variable, rather than simply assuming its i_
existence (as in BASIC) or declaring its existence (as in Forth). Thf3
theory is that this will let the compiler detect more logic errors, since
you aren't supposed to do the wrong thing with the wrong variable
type. (In practice, the C compilers available for the Atari, including
xxvi
INTRODUCTION
our own C/65, are "loose" enough to allow you to cheat most of the
time.)
Here, the declarations establish that "pc" (program counter) will
always point to (Le., contain the address of) a byte-sized item. But "pi"
will always point to a word-sized (double byte) item. Now, actually,
these variables point to nothing until we put an address into them,
which we proceed to do via "pc = 84" and "pi = 85".
And, finally, the actual "assignments" to or from memory are
handled by the last line in each problem solution. Now, all this looks
very complicated and hardly worthwhile, but the advantage of Cis,
once we have made all our declarations, that we can use the variables
and structures wherever we need them in a program module, secure in
the knowledge that our code is at least partially self-documented.
Pascal
Actually, standard Pascal has no methods whatsoever available to
solve these problems. Remember, Pascal is a "school" language, and
access to the machine level was definitely not a desirable feature in
such an environment. In fact, most of the Pascal compilers in use today
have invented some way to circumvent the restrictions of "standard"
Pascal, and it is largely because of such "inventions" that the various
versions of the language are incompatible.
Anyway, Atari Pascal does provide a method to access individual
memory cells. I am not sure that the method I will show here is the best
or easiest way, but it appears to work. Again, the solution is presented
first:
Note: the code in this Hrst part is common to both problems, both
forHand v.
(* in the "type" declarations section *)
charaddr = record
row: char;
end;
wordaddr = record
col: integer;
end;
(* in the "var" declarations section *)
pc : "charaddr ;
pw : "wordaddr ;
rowcrs : absolute [84] "charaddr i
colcrs : absolute [85] "wordaddr ;
Problem 1.
(includes the above common code)
(* execution code in the procedure *)
pc : = rowcrs ;
pw : = colcrs ;
xxvii
INTRODUCTION
pc" . row: = V ;
pw" .col : = H ;
Problem 2.
(includes the above common code)
(* again, procedure execution code *)
pc : = rowers;
pw : = colcrs ;
V: = pc".row;
H: = pw" .col;
Did you get lost? Don't feel bad. I really felt that this could be
written in a simpler fashion, but I wanted to present a version which I
felt reasonably sure would work under most circumstances.
The type declarations are necessary simply to establish record
formats which can be pointed to (and it was these record formats which
I felt to be redundant). Then the vFiriables which indeed point to these
record formats are declared. Most importantly, the "absolute" type
allows us to inform the Pascal compiler that we have a constant which
really is (honest, really, please let it be) the address of one of those
record formats we wanted to point to. (And it is this "absolute" type
which is the extension of Pascal which is not in the standard.)
Once we have made all our declarations, the code looks
surprisingly like the C code: assign the absolute address to the pointer
and then fetch or store via the painter. The overhead of the record
element reference (the" .row" and" .col") is the only real difference
(and perhaps unneeded, as I stated).
PILOT
And here we are at last at the simplest of the Atari languages. Again,
standard PILOT has no defined way of accessing individual memory
cells. And, again, the reason for this is that PILOT was (and is) a
language designed for use in schools, where the last thing you want is
poking around in memory and crashing the 100 megabyte disk with
next year's budget on it.
However, when using PILOT on an Atari computer, the worst
anyone can do is to crunch their oWn copy of their own disk or cassette.
So Atari has thoughtfully proVided a way to access memory cells from
PILOT; and they have done it in a fashion that is remarkably
reminiscent of BASIC. Once more, the solution is given first:
Problem 1.
C:@B84 = #V
C: @B86 = #H/256
C:@B85 = #H\256
Problem 2.
C:#V = @B84
C:#H = @B85 + (256 .. @B86)
xxviii ,~
INTRODUCTION
The trick to this is that Atari PILOT uses the "@B" operator to
indicate a memory reference. When used on the left side of the equals
sign in a C: (compute) statement, it implies a store (just as does POKE
in BASIC). When used on the right side of an equals sign (or, for that
matter, in Jump tests, etc.), it implies a memory fetch (j ust as does
PEEK in BASIC).
If you have already examined the BASIC code, you will probably
-..,-J
note a marked similarity between it and this PILOT example. Again,
we must take the larger number apart into its two components: the
number of units of 256 each (#H/256) and the remainder. Notice that
with PILOT we do not need to (nor can we) specify "INT(#H/256)".
There is no INT function simply because all arithmetic in Atari PILOT
is done with double-byte integers already. Sometimes, as in this
instance, that can be an advantage. Other times, the lack of floating
point will preclude PILOT being used for several applications.
Notice the last line of the solution to problem 1: the use of the" \"
(modulo) operator is essentially just a convenient shorthand available
in several languages. In PILOT,
"#H\256"
is exactly equivalent to
"#H - ( 256 * ( # H/256) )".
Atari PILOT is much more flexible and usable than the original, so
why not take advantage of all its features? Experiment. You will be glad
you did.
xxix
INTRODUCTION
xxx '-
INTRODUCTION
Problem l.
MOVEBYTE V,84
MOVEWORD H,85
Problem 2.
MOVEBYTE 84,V
MOVEWORD 85,H
And yet another concept before we leave assembly language. One
of the most powerful features of an assembler is its ability to handle
equated symbols. The real beauty of this, aside from producing more
readable code, is that you can change all references to a location or
value or whatever by simply changing a single equate in your source
code. Thus, if somewhere near the beginning of our source program
we had coded the following two lines:
ROWCRS = 84 ; address of ROW CuRSor
COLCRS = 85 ; address of COLumn CuRSor
then we could have "solved" the problems thus:
Problem l.
MOVEBYTE V,ROWCRS
MOVEWORD H,COLCRS
Problem 2.
MOVEBYTE ROWeRS, V
MOVEWORD COLCRS,H
And I believe that this looks as elegant and readable as any of the
higher level languages! In fact, it looks more readable than most of the
examples given above. To be fair, though, we should note that all of
the examples could have been made more readable by substituting
variable names instead of the absolute numbers "84" and "85," but the
overhead of declaring and assigning variables is sometimes not worth
it for languages such as BASIC and PILOT.
Luckily, the remaining languages (Forth, C, and Pascal) all have
a means of declaring constants (akin to the assembly language equate)
which has little or no consequential overhead. So go ahead - be the
oddball on your block and make your code readable and
maintainable. It may lose you friends, but it might help you land a job.
Happy Mapping
WelL we made it. I hope you now at least have an idea of what to do to
modify and examine various memory locations in all of the languages
shown. Virtually all of the many locations mapped in this book will fall
into one of the two categories examined: they will involve changing or
examining either a single byte or a double byte (word, integer,
address, etc.). Follow the models shown here, and you should have
little trouble effecting your desires.
For those few locations which do not follow the above patterns
xxxi
INTRODUCTION
'-'
xxxii
--------------------------------------------------------------~
0.1
Locations zero to 255 ($0 to $FF) are called "page zero" and have
special importance for assembly language programmers since these
locations are accessed faster and easier by the machine.
Locations zero to 127 ($0 to $7F) are reserved as the OS page zero,
while 128 to 255 ($80 to $FF) are the BASIC and the user zero page
RAM. Locations zero to 1792 ($0 to $700) are all used as the OS and (if
the cartridge is present) 8K BASIC RAM (except page six). Locai:ions
zero to 8191 ($0 to $1 FFF) are the minimum required for operation
(8K).
Locations two through seven are not cleared on any start operation.
3
8
4
12,13
with an RTS instruction, you should set BOOT? to one and 580
($244) to zero.
12,13 C.D DOSINI
Initialization address for the disk boot. Also used to store the'
cassette-boot RUN address, which is then moved to CASINl (2,
3). When you powerup without either the disk or an autoboot
cassette tape, DOSINI will re.ad zero in both locations.
14,15 E,F APPMHI
Applications memory high limit and pointer to the end of your
BASIC program, used by both the OS and BASIC. It contains the
lowest address you can use to set up a screen and Display List
(which is also the highest address usable for programs and data
below which the display RAM may not be placed). The screen
handler will not OPEN the "S:" device if it would extend the
screen RAM or the Display List below this address; memory
above this address may be used for the screen display and other
data (PM graphics, etc.).
If an attempted screen mode change would extend the screen
memory below APPMHI, then the screen is set up for GRAPHICS
mode zero; MEMTOP (locations 741,742; $2E5, $2E6) is updated
and an error is returned to the user. Otherwise, the memory is not
too small for the screen editor; the mode change will take effect
and MEMTOP will be updated. This is one of five locations used
by the OS to keep track of the user and display memory.
Initialized to zero by the OS at powerup. Remember, you cannot
set up a screen display below the location specified here.
If you use the area below the Display List for your character sets,
PM graphics or whatever, be sure to set APPMHI above the last
address used so that the screen or the DL data will not descend
and destroy your own data. See RAM TOP location 106 ($6A),
MEMTOP at 741, 742 ($2E5, $2E6), PMBASE at 54279 ($D407)
and CHBASE at 54281 ($D409) for more information.
Locations 16 through 127 ($10-$7F) are cleared on either cold- or
warmstart.
16 10 POKMSK
POKEY interrupts: the IRQ service uses and alters this location.
Shadow for 53774 ($D20E). POKE with 112 ($70; also POKE this
same value into 53774) to disable the BREAK key. If the follOWing
bits are set (to one), then these interrupts are enabled (bit
decimal values are in parentheses):
BIT DECIMAL FUNCTION
7 128 The BREAK key is enabled.
6 64 The "other key" interrupt is enabled.
5
17
6
-------------------------------
18.19.20
-' 7
21,22
8
31
9
42
48 30 STATUS
Internal status storage. The SIO routines in ROM use this byte to
store the status of the current SlO operation. See page 166 of the
OS User's Manual for status values. STATUS uses location 793
($319) as temporary storage. STATUS is also used as a storage
register for the timeout, BREAK abort and error values during
SIO routines.
49 31 CHKSUM
Data frame checksum used by SlO: single byte sum with carry to
the least significant bit. Checksum is the value of the number of
bytes transmitted (255; $FF). When the number of transmitted
bytes equals the checksum, a checksum sent flag is set at location
59 ($3B). Uses locations 53773 ($D20D) and 56 ($38) for com-
parison of values (bytes transmitted).
50.51 32.33 BUFBLO/HI
Pointer to the data buffer, the contents of which are transmitted
during an I/O operation, used by S10 and the Device Control
Block (DCB); points to the byte to send or receive. Bytes are
transferred to the eight-bit parallel serial output holding register
or from the input holding register at 53773 ($D20D). This register
10
5:2,53
11
64
12 '-
14
14 4A CK'EY
....
~~ .:":../
Cassette boot request flag on doldstart. Checks to see if the
START key is pressed and, if so, CKEY is set. Autoboot cassettes
are loaded by pressing the START console key while turning the
power on. In response to the b~ep, press the PLAY button on the
recorder.
75 4B CASSBT
Cassette boot flag. The Atari attempts
I
both a disk and a cassette
boot simultaneously. Zero her$ means no cassette boot was suc-
cessful. See location 9.
76 4C DSTAT
Display status and keyboard rbgister used by the display handler.
Also used to indicate memory jis too small for the screen mode,
cursor out of range error, and,the BREAK abort status.
77 4D A'lfRACT
Attract mode timer and flag. Attract mode rotates colors on your
screen at low luminance levels when the computer is on but no
keyboard input is read for a lqng time (seven to nine minutes).
This helps to save your TV scr~en from "burn-out" damage suf-
fered from being left on and npt used. It is set to zero by IRQ
whenever a key is pressed, otherwise incremented every four
seconds by VBLANK (see locations 18 - 20; $12 - $14). When the
value in ATRACT reaches 127 ($7F), it is then set to 254 ($FE) un-
til attract mode is terminated. !This sets the flag to reduce the
luminance and rotate the coldrs when the Atari is sitting idle.
POKE with 128 ($80) to see this effect immediately: it normally
takes seven to nine minutes to enable the attract mode. The OS
cannot "attract" color generated by DLI's, although your DLI
routine can, at a loss of time. i
Joysticks alone will not reset location 77 to zero. You will have to
add a POKE 77,0 to your pro<)ram periodically or frequently call
in a subroutine to prevent the Atari from entering attract mode if
you are not using any keyboard input.
78 4E Da,KMSK
Dark attract mask; set to 254 ($FE) for normal brightness when
the attract mode is inactive (s~e location 77). Set to 246 ($F6)
when the attract mode is active to guarantee screen color
luminance will not exceed 50,%. Initialized to 254 ($FE).
"--"
79 4F COLRSH
Color shift mask; attract color shifter; the color registers are
EORd with locations 78 and 79 at the stage two VBLANK (see
locations 18 - 20; $12 - $14). When set to zero and location 78
equals 246, color luminance is reduced 50%. COLRSH contains
13
80
14
85.86
15
81
16
88,89
17
88.89
z = Z + 1
30 GOTO 10
You will notice that you get the Atari internal character code, not
the ATASCII code. See also locations 560,561 ($230, $231) and
57344 ($EOOO).
How do you find the entire screen RAM? First, look at the chart
below and find your GRAPHICS mode. Then you multiply the
number of rows-per-screen type by the number of bytes-per-line.
This will tell you how many bytes each screen uses. Add this
value, minus one, to the address speCified by SAVMSC.
However, if you subtract MEMTOP (locations 741, 742; $2E5,
$2E6) from RAMTOP (106; $6A * 256 for the number of bytes),
you will see that there is more memory reserved than just the
screen area. The extra is taken up by the display list or the text
window, or is simply not used (see the second chart below).
Mode 0 1 2 3 4 5 6 7 8 9-12
Rows
Full 24 24 12 24 48 48 96 96 192 192
Split 20 10 20 40 40 80 80 160
Bytes per
Line 40 20 20 10 10 20 20 40 40 40
Columns
per Line 40 20 20 40 80 80 160 160 320 80
Memory (1) 993 513 261 273 537 1017 2025 3945 7900 7900
Memory (2)
Full 992 672 420 432 696 1176 2184 4200 8138 8138
Split - 674 424 434 694 1174 2174 4190 8112
18
81~,89
..........
Why the minus one in the calculation? The first byte of the screen
'--/ is the first byte in the loop. If we add the total size, we will go one
byte past the end of the screen, so we subtract one from the total.
Here's how to arrive at the value for the total amount at memory
located for screen use, display list and text window:
Total memory allocation for the screen
Screen display Display List
Text unused bytes screen unused used
GR window al:ways condo use bytes bytes Total
0 none none 960 none 32 992
1 160 none 80 400 none 34 674
2 160 none 40 200 none 24 424
3 160 none 40 200 none 34 434
4 160 none 80 400 none 54 694
5 160 none 160 800 none 54 1174
6 160 none 320 1600 none 94 ,2174
7 160 none 640 3200 96 94 4190
8 160 16 1280 6400 80 176 8112
The number of bytes from RAMTOP (location 106; $6A) is counted
from the left text window column towards the total column.
MEMTOP (741, 742; $2E5, $2E6) points to one byte below
RAMTOP * 256 minus the number of bytes in the total column. If
16 is added to the GRAPHICS mode (no text window), then thE~
conditional unused bytes are added to the total. Then the bytes
normally added for the text window become unused, and the
Display List expands slightly. (See COMPUTE!, September 1981.)
When you normally PRINT CHR$(l25) (clear screen), Atari sends
zeroes to the memory starting at locations 88 and 89. It continues to
do this until it reaches one byte less than the contents of RAMTOP
(location 106; $6A). Here is a potential source of conflict with your
program, however: CHR$(l25) - CLEAR SCREEN - and any
GRAPHICS command actually continue to clear the first 64 ($40)
bytes above RAMTOP!
It would have no effect on BASIC since BASIC is a ROM
cartridge. The OS Source Listing seems to indicate that it ends at
RAM TOP , but Atari assumed that there would be nothing after
RAMTOP, so no checks were provided. Don't reserve any data.
within 64 bytes of RAMTOP or else it will be eaten by the CLEAR
SCREEN routine, or avoid using a CLEAR SCREEN or a
GRAPHICS command. Scrolling the text window also clears 800
bytes of memory above RAMTOP.
You can use this to clear other areas of memory by POKEing the
19
88,89
LSB and MSB of the area to be cleared into these locations. Your
routine should always end on a $FF boundary (RAMTOP indicates
the number of pages). Remember to POKE back the proper screen
locations or use a GRAPHICS command immediately after doing
so to set the screen right. Try this:
10 BOTTOM = 30000: TOP = 36863: REM
LOWEST AND HIGHEST ADDRESS TO CLEA
R = $7530 & $8FFF
20 RAMTOP = PEEK(106): POKE 106, INT
(TOP + 1 I 256)
30 TEST = INTCBOTTOM I 256): POKE89~
TEST
40 POKE 88, BOTTOM - 256 TEST *
50 PRINT CHRS(125): POKE 106, RAMTOP
60 GRAPHICS 0
This will clear the speCified memory area and update the address
of screen memory. If you don't specify TOP, the CLEAR SCREEN
will continue merrily cleaning out memory and, most likely, will
cause your program to crash. Use it with caution.
Here's a means to SAVE your current GR. 7 screen display to disk
using BASIC:
1000 SCREEN = PEEK(8B) + PEEK(B9) ~
256
1010 OPEN #2,8,O,"D:picturename"
1020 MODE = PEEK(87): PUT #2, MODE~
REM SAVE GR. MODE
1030 FOR SCN = 0 TO 4: COL = PEEK(70
B + SCN): PUT #2,COL: NEXT SCN:
REM SAVE COLOR REGISTERS
1040 FOR TV = SCREEN TO SCREEN + 319
9:BYTE = PEEKCTV}: PUT #2, BYTE:
NEXT TV: CLOSE #2
To use this with other screen modes, you will have to change the
value of 3199 in line 1040 to suit your screen RAM (see the chart
above). For example, GR.7 + 16 would require 3839 bytes (3840
minus one). You can use the same routine with cassette by usinq
device C:. To retrieve your picture, you use GET#2 and POKE '-
commands. You will, however, find both routines very slow. Using
THE CIO routine at 58454 ($E456) and the IOCBs, try this machine
language save routine:
10 DIM MLS(10): BS(IO): GR.8+16
20 B$ = "your picture name":Q PEEK
(559)
30 FOR N = 1 TO 6: READ BYTE: ML$(N,
20
'-
90
N) = CHR$(BYTE}: NEXT N
35 DATA 104,162,16~76,86,228
36 REM PLA~LDX,$10,JMP $E456
40 OPEN #1,4,0,8$
50 POKE 849,1: POKE 850,7: POKE 852,
PEEK(88): POKE 853,PEEK(89): POKE
856,70: POKE 857,30: POKE 858,4
55 REM THESE POKES SET UP THE IOCB
60 POKE 559,0: REM TURN OFF THE seRE
EN TO SPEED THINGS UP
70 X = USR(ADRCML$}): CLOSE #1
80 POKE 559,Q: REM TURN IT BACK ON A
GAIN
Note that there is no provision to SAVE the color registers in this
program, so I suggest you have them SAVEd after you have
SAVEd the picture. It will make it easier to retrieve them if they are
at the end of the file. You will have to make suitable adjustments
when SAVEing a picture in other than GR.8 + 16 - such as
changing the total amount of screen memory to be SAVEd, POKEd
into 856 and 857. Also, you will need a line such as 1000 GOTO
1000 to keep a GTIA or + 16 mode screen intact. See the Atari
column in InfoAge Magazine, July 1982, for more on this idea. See
location 54277 ($D405) for some ideas on scrolling the screen
RAM.
A SHORT DIGRESSION
There are two techniques used in this book for calling a machine
language program from BASIC with the USR command. One method
is to POKE the values into a specific address - say, page six - and
use the starting address for the USR call, such as X = USR(l536). For
an example of this technique, see location 632 ($278).
The other technique, used above, is to make a string (ML$) out of the
routine by assigning to the elements of the string the decimal
equivalents of the machine language code by using a FOR-NEXT and
READ-DATA loop. To call this routine, you would use X =
USR(ADR(ML$) ). This tells the Atari to call the machine language
routine located at the address where ML$ is stored. This address will
change with program size and memory use. The string method won't
be overwritten by another routine or data since it floats around safely
in memory. The address of the string itself is stored by the string/alrray
table at location 140 ($8C).
90 SA OLDROW
Previous graphics cursor row. Updated from location 84 ($54)
,-' 21
91,92
'-
22
-- 106
106 6A RAMTOP
RAM size, defined by powerup as passed from TRAMSZ (location
6), given in the total number of available pages (one page equals
256 bytes, so PEEK(106) * 256 will tell you where the Atari thinks
the last usable address - byte - of RAM is). MEMTOP (741,
742; $2E5, $2E6) may not extend below this value. In a 48K Atari,
RAM TOP is initialized to 160 ($AO), which points to location
40960 ($AOOO). The user's highest address will be one byte less
than this value.
This is initially the same value as in location 740. PEEK(740) /4 or
PEEK(106) /4 gives the number of lK blocks. You can fool the
computer into thinking you have less memory than you actually
have, thus reserving a relatively safe area for data (for your new
character set or player/missile characters, for example) or
machine language subroutines by:
POKE(106), PEEK(106) - # of pages you want to reserve.
The value here is the number of memory pages (256-byte blocks)
present. This is useful to know when changing GR. 7 and GR.:3
screen RAM. If you are reserving memory for PM graphics,
POKE 54279, PEEK(l06) - # of pages you are reserving beforl~
you actually POKE 106 with that value. To test to see if you have
exceeded your memory by reserving too much memory space,
you can use:
10 SIZE = (PEEK(106) - # of pages)
20
* 256
IF SIZE < = PEEK(144} + PEEK(145
} * 256 THEN PRINT "TOO MUCH MEMOR
Y USED"
If you move RAMTOP to reserve memory, always issue a
GRAPHICS command (even issuing one to the same GRAPHICS
mode you are in will work) immediately so that the display list
and data are moved beneath the new RAM TOP .
You should note that a GRAPHICS command and a CLEAR
command (or PRINT CHR$ (125) ) actually clear the first 64 bytes
above RAM TOP (see location 88; $58 for further discussion).
'Scrolling the text window of a GRAPHICS mode clears up to BOO
($320) bytes above RAMTOP (the text window scroll actually
scrolls an entire GR.O screen-worth of data, so the unseen 20
lines * 40 bytes equals 800 bytes). PM graphics may be safe
(unless you scroll the text window) since the first 384 or768 bytes
(double or single line resolution, respectively) are unused.
However, you should take both of these effects into account when
writing your programs.
23
107
To discover the exact end of memory, use this routine (it's a tad
slow): ,~,~
10 RAHTOP =
106: TOP = PEEK(RAHTOP)
20 ~YTE = TOP *
256: TEST = 255 - PE
EK(BYTE): POKE BYTE,TEST
30 IF PEEK(BYTE) = TEST THEN TOP = T
OP +1: POKE BYTE, 255 - TEST
40 GOTO 20
50 PRINT "MEMORY ENDS AT "; BYTE
One caution: BASIC cannot always handle setting up a displd.y
list and display memory for GRAPHICS 7 and GRAPHICS 8
when you modify this location by less than 4K (16 pages; 4096
bytes). Some bizarre results may occur if you use PEEK(l06) - 8
in these modes, for example. Use a minimum of 4K (PEEK(lOI5)-
16) to avoid trouble. This may explain why some people have
difficulties with player/missile graphics in the hi-res (high
resolution; GR.7 and GR.8) modes. See location 54279 ($D407).
Another alternative to reserving memory in high RAM is to save
an area below MEMLO, location 743 ($2E7: below your BASIC
program). See also MEMTOP, locations 741,742 ($2E5, $2E6).
107 SB BUFCNT
Buffer count: the screen editor current logical line size count,er.
108.109 SC,SD BUFSTR
Editor low byte (AM). Display editor GETCH routine pointer
(location 62867 for entry; $F593). Temporary storage; returns the
character pointed to by BUFCNT above.
llO SE BITMSK
Bit mask used in bit mapping routines by the OS display handler
at locations 64235 to 64305 ($FAEB to $FB3l). Also used as a
display handler temporary storage register.
III SF SHFAMT
Pixel justification: the amount to shift the right justified pixel data
on output or the amount to shift the input data to right justify it.
Prior to the justification process, this value is always the same as
that in 672 ($2AO).
ll2.ll3 70.71 ROWAC
ROWAC and COLAC (below) are both working accumulators for
the control of row and column point plotting and the increment
and decrement functions.
ll4.llS 72.73 COLAC
Controls column point plotting.
24 '--
116,117
25
128,129
drawn, this value is decremented. When the byte equals zero, the
line is complete (drawn).
User and/or BASIC page zero RAM begins here. Locations 128 to ]45
($80 to $91) are for BASIC program pointers; 146 to 202 ($92 to $CA)
are for miscellaneous BASIC RAM; 203 to 209 ($CB to $D 1) are
unused by BASIC, and 210 to 255 ($D2 to $FF) are the floating point
routine work area. The Assembler Editor cartridge uses locations 128
to 176 ($80 to $BO) for its page zero RAM. Since the OS doesn't use this
area, you are free to use it in any non-BASIC or non-cartridge
environment. If you are using another language such as FORTH,
check that program's memory map to see if any conflict will occur.
See COMPUTEJ's First Book of Atari, pages 26 to 53, for a discussion
of Atari BASIC structure, especially that using locations 130 to 137
($82 to $89). Included in the tutorials are a memory analysis, a line
dump, and a renumber utility. See also De Re Atari, BYTE, February
1982, and the locations for the BASIC ROM 40960 to 49151 ($AOOO to
$BFFF).
128.129 80.81 LOMEM
Pointer to BASIC's low memory (at the high end of OS RAM
space). The first 256 bytes of the memory pointed to are the token
output buffer, which is used by BASIC to convert BASIC
statements into numeric representation (tokens; see locations
136, 137; $88, $89). This value is loaded from MEMLO (locations
743, 744; $2E7, $2E8) on initialization or the execution of a NEW
command (not on RESET!). Remember to update this value when
changing MEMLO to reserve space for drivers or buffers.
When a BASIC SAVE is made, two blocks of information are
written: the first block is the seven pointers from LOMEM to
STARP(l28to 141; $80to$8D). The value of LOMEM is
subtracted from each of these two-byte pointers in the process, so
the first two bytes written will both be zero. The second block
contains the following: the variable name table, the variable
value table, the tokenized program, and the immediate mode
line.
When a BASIC LOAD is made, BASIC adds the value at MEMLO
(743, 744; $2E7, $2E8) to each of the two-byte pOinters SAVEd as '-
above. The pOinters are placed back in page zero, and the values
of RUNSTK (142, 143; $8E, $8F) and MEMTOP (144, 145; $90,
$91) are set to the value in STARP. Then 256 bytes are reserved
above the value in MEMLO for the token output buffer, and the
program is read in immediately following this buffer.
When you don't have DOS or any other application program
using low memory loaded, LOMEM points to 1792 ($700). When
26
130,131
27
132,133
28
134,135
29
136.137
30
13B,139
31
142.143
32 '-
144,,145
increment. These two are allocated six bytes each in BCD format
(12 bytes total). The 13th byte is the counter variable number with
the MSB set; the 14th and 15th are the line number and the 16th is
the line offset to the FOR statement.
RUNSTK is also called ENDSTAR; it is used by BASIC to point to
the end of the string/array space pointed to by STARP above.
144,145 90.91 MEMTOP
Pointer to the top of BASIC memory, the end of the space thE>
program takes up. There may still be space between this address
and the display list, the siz.e of which may be retrieved by the
FRE(O} command (which actually subtracts the MEMTOP value
that is at locations 741 and 742; $2E5, $2E6). Not to be confused
with locations 741 and 742, which have the same name but are an
OS variable. MEMTOP is also called TOPSTK; it points to the top
of the stack space pointed to by RUNSTK above.
When reserving memory using location 106 ($6A) and MEMTOP,
here's a short error-trapping routine you can add:
10 SIZE = (PEEK(106)- # of pages yo
u are reserving) * 256
20 IF SIZE < = PEEK(144) + PEEK(145
} • 256 THEN PRINT " PROGRAM TOO L
AR6E": END
Locations 146 to 202 ($92 to $CA) are reserved for use by the 8K
BASIC ROM.
Locations 176 to 207 ($BO to $CF) are reserved by the Assembler
Editor cartridge for the user's page zero use. The Assembler debug
routine also reserves 30 bytes in page zero, scattered from location 164
($A4) to 255 ($FF), but they cannot be used outside the debug process.
(See De Re Atari, Rev. 1, Appendix A for a list of these available
bytes.)
186,187 BA,BB STOPLN
The line where a program was stopped either due to an error or
the use of the BREAK key, or a STOP or a TRAP statement
occurred. You can use PEEK (186) + PEEK (187) * 256 in a
GOTO or GOSUB statement.
195 C3 ERRSAVE
The number of the error code that caused the stop or the TRAP.
You can use this location in a program in a line such as:
10 IF PEEKCI95) (> 144 THEN 100
201 C9 PTABW
This location specifies the number of columns between TAB
stops. The first tab will be at PEEK(201). The default is ten. This is
33
203-207 .~"
34
218-223
35
247,248
36
512.513
interrupts, peripheral and serial bus interrupts, BREAK and other key
interrupts, and 6502 BRK instruction interrupts. They can usually be
used to vector to user routines. See NMIST 54287 ($D40F) and IROEN
53774 ($D20E) for more information. NMI interrupt vectors are mClrked
NMI; IRQ interrupt vectors are marked IRQ.
Refer to the chart below location 534 for a list of the interrupt vectors in
the new OS "B" version ROMs.
37
514,515
Here's a short example of a DLI. It will print the lower half of your
text screen upside down:
10 START = PEEK(560} + PEEK(561}
256: POKE START + 16,130
*
20 PAGE = 1536: FOR PGM = PAGE TO P
AGE + 7: READ BYTE: POKE PGM, BYTE
NEXT PGM
30 DATA 72,169.4,141,1,212,104,64
40 POKE 512,0: POKE 513,6: POKE 542
86,192
SO FOR TEST = 1 TO 240: PRINT"SEE "
;: NEXT TEST
60 GOTO 60
Another example of a DLI changes the color of the bottom half of
the screen. To use it, simply change the PAGE + 7 to PAGE + 10
in the program above and replace line 30 with:
30 DATA 72,169,222,141,10,212,141,2
4,208,104,64
Finally, delete lines 50 and 60. See also location 54282 ($D40A).
514.515 202.203 VPRCED
Serial (peripheral) proceed line vector, initialized to 59314
($E7B2), which is merely a PLA, RTI instruction sequence. It is
used when an IRQ interrupt occurs due to the serial 110 bus
proceed line which is available for peripheral use. According to
De Re Atari, this interrupt is not used and points to a PLA, RTI
instruction sequence. This interrupt is handled by the PIA chip
and can be used to provide more control over external devices.
See the OS Listing, page 33.
516,517 204.205 VINTER
Serial (peripheral) interrupt vector, initialized to 59314 ($E7B2).
Used for the IRQ interrupt due to a serial bus I/O interrupt.
According to De Re Atari, this interrupt is not used and points to
a PLA, RTI sequence. This interrupt is processed by PIA. See the
OS Listing, page 33.
518,519 206.207 VBREAK
Software break instruction vector for the 6502 BRK ($00)
command (not the BREAK key, which is at location 17; $11) I
38
522,523
39
530.531
The locations from 536 to 558 ($218 to $22E) are used for the system
software timers. Hardware timers are located in the POKEY chip a.nd
use the AUDF registers. These timers count backwards every 1160
second (stage one VBLANK) or 1130 second (stage two VBLANK)
interval until they reach zero. If the VBLANK process is disabled or
intercepted, the timers will not be updated. See De Re Atari for
information regarding setting these timers in an assembly routine
using the SETVBV register (58460; $E45C). These locations are user-
accessible and can be made to count time for music duration, game
I/O, game clock and other functions.
Software timers are used for durations greater than one VBLANK
interval (l/60 second). For periods of shorter duration, use the
hardware registers.
536,531 218.219 CDTMVI
System timer one value. Counts backwards from 255. This SIO
40
538,539
41
550.551
--.-!
42
55:t553
When locations 536,537 ($218, $219) reach (count down to) zero,
the OS vectors through here (jumps to the location specified by
these two addresses). You can set your machine code routinl3
address here for execution when timer one reaches (counts down
to) zero. Your code should end with the HTS instruction.
Problems may occur when timer values are set greater than 255,
since the 6502 cannot manipulate 16-bit values directly (a
number in the range of zero to 255 is an eight-bit value; if a value
requires two bytes to store, such as a memory location, it is ii
16-bit value). Technically, a VBLANK interrupt could occur
when one timer byte is being initialized and the other not yet set.
To avoid this, keep timer values less than 255. See the Atari OS
User's Manual, page 106, for details.
Since the OS uses timer one, it is recommended that you use
timer two instead, to avoid conflicts with the operation of the
Atari. Initialized to 60396 ($EBEA) in the old ROMs, 60400
($EBFO) in the new ROMs. NMI
552,553 228,229 CDTMA2
System timer two jump address. Not used by the OS, available to
user to enter the address of his or her own routine to IMP to when
the timer two (538, 539; $21A, $21B) count reaches zero.
Initialized to zero; the address must be user specified. NMI
554 22A CDTMF3
System timer three flag, set when location 540,541 ($2IC, $2lD)
reaches zero. This register is also used by DOS as a timeout flag.
555 22B SRTIMR
Software repeat timer, controlled by the IRQ device routine. It
establishes the initial Y2 second delay before a key will repeat.
Stage two VBLANK establishes the 1110 second repeat rate"
decrements the timer and implements the auto repeat logic.
Every time a key is pressed, STIMEH is set to 48 ($30). Whenever
SRTIMR is equal to zero and a key is being continuously pressed,
the value of that key is continually stored in CH, location764
($2FC).
556 22C CDTMF4
System timer four flag. Set when location 542,543 ($21E, $21F)
counts down to zero.
557 22D IN TEMP
Temporary register used by the SETVBL routine at 58460
($E45C).
558 22E CDTMF5
System timer five flag. Set when location 558,559 ($22E, $22F)
counts down to zero.
43
SSg
44
51;0,581
logical unit which varies in size with the GRAPHICS mode. Due
to the limitations of most TV sets, you will not be able to see all of
the wide playfield unless you scroll into the offscreen portions.
BIT 5 must be set to enable ANTIC operation; it enables DMA for
fetching the display list instructions.
45
560.561
46
5611,561
1 0 0 0 Map
to Modes
1 1 1 1
47
562
The above bits may be combined (Le., DLI, scrolling and LMS
together) if the user wishes.
Special DL instructions (with decimal values):
Blank 1 line = 0 5 lines = 64
2 lines = 16 6 lines = 80
3 lines = 32 7 lines = 96
4 lines = 48 8 lines = 112
Jump instruction (JMP) = zero (three-byte instruction).
Jump and wait for Vertical Blank (JVP) = 65 (three-byte
instruction) .
Special instructions may be combined only with DL interrupt
instructions.
A Display List Interrupt is a special form of interrupt that takes
place during the screen display when the ANTIC encounters ,9-
DL instruction with the interrupt BIT 7 set. See location 512
($200) for DLI information.
Since DL's are too large a topic to cover properly in this manual,
I suggest you look in the many magazines (Le., Creative
Computing, July 1981, August 1981; Micro, December 1981;
Softside, #30 to 32, and BYTE, December 1981) for a more
detailed explanation.
562 232 SSKCTL
Serial port control register, shadow for 53775 ($D20F). Settinq
the bits in this register to one has the follOWing effect:
Bit Decimal Function
0 1 Enable the keyboard debounce circuit.
1 2 Enable the keyboard scanning circuit.
2 4 The pot counter completes a read within two
scan lines instead of one frame time.
3 8 Serial output transmitted as two-tone insteald
of logic true/false (POKEY two-tone mode).
4-6 16-64 Serial port mode control.
7 128 Force break; serial output to zero.
Initialized to 19 ($13), which sets bits zero, one and four.
563 233 SPARE L __ -",
48
566.567
49
576
50
58~l-622
printer suffers from this malady as well) happens when your drive
times out, or the timer value reaches zero. This has been cured
by the new OS \\B" version ROMs.
583-622 247-26E LINBUF
Forty-byte character line buffer, used to temporarily buffer one
physical line of text when the screen editor is moving screen
data. The pointer to this buffer is stored in 100, 101 ($64, $65)
during the routine.
623 26F GPRIOR
Priority selection register, shadow for 53275 ($DO I B). Priority
options select which screen objects will be \\in front" of others. It
also enables you to use all four missiles as a fifth player and
allows certain overlapping players to have different colors in the
areas of overlap. You add your options up as in location 559,
prior to POKEing the total into 623. In this case, choose only one
of the four priorities stated at the beginning. BAK is the
background or border. You can also use this location to select
one of GIlA GRAPHICS modes nine, ten, or eleven.
Priority options in order Decimal Bit
Player 0 - 3, playfield 0 - 3, BAK
(background) 1 0
Player 0 - I, playfield 0 - 3, player 2 - 3,
BAK 2 1
Playfield 0 - 3, player 0 - 3, BAK 4 2
Playfield 0 - 1, player 0 - 3, playfield 2 -3,
BAK 8 3
Other options
Four missiles = fifth player 16 4
Overlaps of players have 3rd color 32 5
GRAPHICS 9 (GTIA mode) 64 6
GRAPHICS 10 (GTIA mode) 128 7
GRAPHICS 11 (GTIA mode) 192 6,7
It is quite easy to set conflicting priorities for players and
playfields. In such a case, areas where both overlap when a
conflict occurs will turn black. The same happens if the overlap
option is not chosen.
With the color/overlap enable, you can get a multicolor player
by combining players. The Atari performs a logical OR to colors
of players 011 and 2/3 when they overlap. Only the 011,2/3
combinations are allowed; you will not get a third color when
players I and 3 overlap, for example (you will get black inste~ad).
If player one is pink and player 0 is blue, the overlap is green. If
you don't enable the overlap option, the area of overlap for (Ill
51
623
52
- - - - - ------------
624
and circles!
GIlA modes are cleared on the OPEN command. How can you
tell if you have the GIlA chip? Try POKE 623,64. If you have the
GIlA, the screen will go all black. If not, you don't have it. Here
is a short routine, written by Craig Chamberlain and Sheldon
Leemon for COMPU'fE!, which allows an Atari to test itself Ifor the
presence of a CIlA or GIlA chip. The routine flashes the answer
on the screen, but can easily be modified so a program will
"know" which chip is present so it can adapt itself accordinqly:
10 POKE 66~1:GRAPHICS 8:POKE 709,0:PO
KE 710.0:POKE 66,O:POKE 623,64:POK
E 53248,42:POKE 53261,3:PUT#6,1
20 POKE 53278,0:FOR K=1 TO 300:NEXT K
:GRAPHICS 18:POKE 53248,0:POSITXON
8,5:? #6;CHR$(71-PEEK(53252»;"TI
A"
30 POKE 708,PEEK(20):GOTO 30
How can you get the GIlA if you don't have one? Ask your local
Atari service representative or dealer, or write directly to Atari in
Sunnyvale, California.
See the GTIA/CIlA introduction at location 53248 ($DOOO) for
more discussion of the chip. See BYTE, May 1982, COMPU'rE!,
July through September 1982, and De Re Atari for more on the
GIlA chip, and the GTIA Demonstration Diskette from the Atari
Program Exchange (APX).
Locations 624 to 647 ($270 to $287) are used for game controllers:
paddle, joystick and lightpen values.
624 210 PADDLO
The value of paddle 0 (paddles are also called pots, short for
potentiometer); PEEK 624 returns a number between zero and
228 ($E4), increasing as the knob is turned counter-clockwise.
When used to move a player or cursor (Le., PLOT
PADDLE(O)'O)' test your screen first. Many sets will not display
locations less than 48 ($30) or greater than 208 ($DO), and in
many GRAPHICS modes you will get an ERROR 141- cursor
out of range. Paddles are paired in the controller jacks, so p,3.ddle
oand paddle 1 both use jack one. PADDL registers are shadows
for POKEY locations 53760 to 53767 ($D200 to $D207).
625 271 PADDLI
This and the next six bytes are the same as 624, but for the other
paddles.
626 212 PADDL2
53
--------
627
-
627 273 PADDL3
628 274 PADDL4
629 275 PADDL5
630 276 PADDL6
631 277 PADDL7
'-
632 278 STICKO
The value of joystick O. STICK registers are shadow locations for
PIA locations 54016 and 54017 ($D300, $D30l). There are nine
possible decimal values (representing 45 degree increments)
read by each joystick register (using the STICKn command),
depending on the position of the stick:
Decimal Binary
14 1110
9/ "'5
13
1001
/1"1l0!
OlOl
54
633
55
641 -..~
---
641 281 PTRIG5
- /
Locations 656 to 703 ($290 to $2BF) are used for the screen RAM
display handler (depending on GRAPHICS mode).
56
656
57
670
58
673
playfield size.
673 2Al TMPLBT
Temporary storage for the bit mask.
674 2A2 ESCFLG
Escape flag. Normally zero, it is set to 128 ($80) if the ESC key is
pressed (on detection of the ESC character; 27, $1 B) . It is reBet to
zero following the output of the next character. To display
ATASCII control codes without the use of an ESC charadeI', set
location 766 ($2FE) to a non-zero value.
675-689 2A3-2Bl TABMAP
Map of the TAB stop positions. There are 15 bytes (120 bits) here,
each bit corresponding to a column in a logical line. A one in any
bit means the TAB is set; to clear all TABs simply POKE every
location with zero. There are 120 TAB locations because there
are three physical lines to one logical line in GRAPHICS mode
zero, each conSisting of 40 columns. Setting the TAB locations for
one logical line means they will also be set for each subsequemt
logical line until changed. Each physical line in one logical line
can have different TAB settings, however.
To POKE TAB locations from BASIC, you must POKE in the
number (Le., set the bit) that cortesponds to the location of the
bit in the byte (there are five bytes in each line). For example:
To set tabs at locations 5, 23, 27 and 32, first visualize the line as a
string of zeros with a one at each desired tab setting:
0000100000000000000000100010000100000000
Then break it into groups of eight bits (one byte units). There are
three bytes with ones (bits set), two with all zeros:
00001000 = 8
00000000 = 0
00000010 = 2
00100001 = 33
00000000 = 0
Converting these to deCimal, we get the values listed at the right
of each byte. These are the numbers you'd POKE into locations
675 (the first byte) to 679 (the fifth byte on the line). On powerup
or when you OPEN the display screen (S: or E:), each byte is
given a value of one (Le., 00000001) so that there are tab defa,ult
tab stops at 7, 15,23, etc., incrementing by eight to 119. Also,
the leftmost screen edge is also a valid TAB stop (2,42, and 82).
In BASIC, these are set by the SET-TAB and CLR-TAB keys.
TABMAP also works for the lines in the text display window in
split-screen formats. TABMAP is reset to the default values on
59
690-693
60
700
lines minus one that were deleted from the top of the screen. This
moves the entire screen up one physical-line for each line
scrolled off the top. Since a logical line has three physical lines,
SCRFLG ranges from zero to two.
Scrolling the text window is the equivalent to scrolling an entire
GR.O screen. An additional20-line equivalent of bytes (800) is
scrolled upwards in the memory below the text window address.
This can play havoc with any data such as PIM graphics you have
stored above RAM TOP .
61
703
Locations 704 to 712 ($2CO to $2CB) are the color registers for players,
missiles, and playfields. These are the RAM shadow registers for
locations 53266 to 53274 ($DOI2 to $DOIA). For the latter, you can use
the SETCOLOR command from BASIC. For all registers you can
POKE the desired color into the location by using this formula:
COLOR = HUE * 16 + LUMINANCE
It is possible to get more colors in GR.B than the one (and a half) that
Atari says is possible by using a technique called artifacting. There is a
small example of artifacting shown at location 710 ($2C6). See De Re
Atari, Your Atari 4001800, Creative Computing, June 19B1, and
COMPUTE!, May 19B2.
Here are the 16 colors the Atari produces, along with their POKE
values for the color registers. The POKE values assume a luminance of
zero. Add the luminance value to the numbers to brighten the color.
The color registers ignore BIT 0; that's why there are no "odd" values
for luminance, just even values.
Color Value Color Value
Black 0, 0 Medium blue 8, 128 '\..'.--
62
103
Grey 0 0 0 0 0 0 0 Darkest
Rust 0 0 0 1 0 0 1
etc. to: etc. to:
Orange 1 1 1 1 1 1 1 Lightest
When you enable the color overlap at location 623 ($26F), ANTIC
performs a logical OR on the overlap areas. For example:
01000010 Red, luminance two
OR 10011010 Dark blue, luminance ten
Result = 10011010 Dark green, luminance ten
Here's a short machine language routine which will rotate the colors in
registers 705 to 712:
10 DIM ROT$(30)
20 FOR LOOP = 1 TO 27: READ BYTE: R
OT$(LOOP,LOOP) = CHR$(BYTE}: NEXT
LOOP
63
704
64
711
E
710~0: POKE 709,15: COLOR 1
30 PLOT A,D: DRAW TO A,C: COLOR 2: P
LOT F,D: DRAWTO F,C:
40 PLOT A + 1,D: DRAWTO A + 1,C
50 COLOR 3: PLOT B,D: DRAWTO B,C
60 GOTO 60
A little experimentation with this will show you that the colors
obtained depend on which pixels are turned on and how cloi;e
together the pixel columns are. There are four "colors" you can
obtain, as shown before. Pixels marked one are on; marked ,~ero
means they are off. Each pair of pixels is one color clock. Three
color clocks are shown together for clarity:
00:01:00 = color A 00:11:00 = color B
00: 10:00 = color C 00:01: 10 = color D
See BYTE, May 1982, De ReAtari, and Your Atari 4001800.
7ill 2C7 COLOR3
I
The same as the above but for playfield three. Also, the color for
GR.1 and GR.2 inverse lowercase letters. Shadow for 53273
($D019).
7112 2C8 COLOR4
The same as the above but for the background (BAK) and border
color. Shadow for 53274 ($D01A). In GTIA mode ten, 704 stores
the background color (BAK), while 712 becomes a normal color
register.
Here are the default (powerup) values for the COLOR registers
(PCOL registers are all set to zero on powerup):
Register Color = Hue Luminance
708 (CO.O) 40 2 8
709 (CO.l) 202 12 10
710 (CO.2) 148 9 4
711 (CO.3) 70 4 6
712 (CO.4) 0 0 0
Uocations 713 to 735 ($2C9 to $2DF) are spare bytes. Locations 73:6 to
767 ($2EO to $2FF) are for miscellaneous use.
't36-739 2EO-2E3 GLBABS
I Global variables, or, four spare bytes for non-DOS users. For
. DOS users they are used as below:
65
738·739
66
'~
67
745
have created a MEM. SAY file, the data will be wiped out when
you call DOS. To alter MEMLO, you start by POKEing WARMST
(location 8) with zero, then doing a JMP to the BASIC cartridge
entry point at 40960($AOOO) after defining your area to protect.
For example, try this:
10 DIM MEM$(24):PROTECT=700:REM NUMBE
R OF BYTES TO CHANGE
15 HIBYTE=INT(PROTECT/256):LOBYTE=PRO
TECT-256*HIBYTE
20 FOR N=l TO 24:READ PRG:MEM$(N}=CHR
$(PRG}:NEXT N
30 MEM$(6~6)=CHR$(LOBYTE):MEM$(14,14)
=CHR$(HIBYTE)
40 RESERVE=USR(ADR{MEM$)}
50 DATA 24,173,231,2,105,0,141,231,2,
173,232,2,105
60 DATA 0,141,232,2,169,0,133,8,76,0,
160
You will find the address of your reserved memory by: PRINT
PEEK(743) + PEEK(744) * 256 before you run the program. This
program will wipe itself out when run. Altering MEMLO is the
method used by both DOS and the RS-232 port driver in the 850
Interface. See COMPUTE!, July 1981.
745 2E9
Spare byte.
746-749 2EA-2ED DVSTAT
Four device status registers used by the 1/0 status operation as
follows:
746 ($2EA) is the device error status and the command status
byte. If the operation is a disk I/O, then the status returned is that
of the 1771 controller chip in your Atari disk drive. Bits set to one
return the following error codes:
Bit Decimal Error
o 1 An invalid command frame was received (error).
1 2 An invalid data frame was received.
2 4 An output operation was unsuccessful.
3 8 The disk is write-protected.
4 16 The system is inactive (on standby).
7 32 The peripheral controller is "intelligent" (has its
own microprocessor: the disk drive). All Atari
devices are intelligent except the cassette
recorder, so BIT 7 will normally be one when a
device is attached.
747 ($2EB) is the device status byte. For the disk, it holds the
68
750,751
value of the status register of the drive controller. For the 850
Interface, it holds the status for DSR,CTS,CRX and RCV whEm
concurrent I/O is not active (see the 850 Interface Manual). It also
contains the AUX2 byte value from the previous operation (see
", the IOCB description at 832 to 959; $340 to $3AF).
748 ($2EC) is the maximum device time-out value in seconds. A
value of 60 here represents 64 seconds. This value is passed back
to location 582 ($246) after every disk status request. Initialized to
31.
749 ($2ED) is used for number of bytes in output buffer. See 850
Manual, p. 43.
When concurrent I/O is active, the STATUS command returns
the number of characters in the input buffer to locations 747 and
748, and the number of characters in the output buffer to location
749.
750.751 2EE.2EF CHAUDL/H
Cassette baud rate low and high bytes. Initialized to 1484
($5CC), which represents a nominal 600 baud (bits per second).
After baud rate calculations, these locations will contain POKEY
values for the corrected baud rate. The baud rate is adjusted by
SIO to account for motor variations, tape stretch, etc. The
beginning of every cassette record contains a pattern of
alternating off/on bits (zer%ne) which are used solely for speed
(baud) correction.
752 2FO CRSINH
Cursor inhibit flag. Zero turns the cursor on; any other number
turns the cursor off. A visible cursor is an inverse blank (space)
character. Note that cursor visibility does not change until the
next time the cursor moves (if changed during a program). If you
wish to change the cursor status without altering the screen data,
follow your CRSINH change with a cursor movement (Le., up,
down) sequence. This register is set to zero (cursor restored) on
powerup, RESET, BREAK, or an OPEN command to either the
"-,, display handler (S:) or screen editor (E:). See location 755 for
another means to turn off the cursor.
753 2Fl KEYDEL
Key delay flag or key debounce counter; used to see if any key
has been pressed. If a zero is returned, then no key has been
pressed. If three is returned, then any key. It is decremented
--- every stage two VBLANK (1/60 or 1/30th second) until it rea.ches
zero. If any key is pressed while KEYDEL is greater than zero, it
is ignored as "bounce." See COMPUU!, December 1981, for a
routine to change the keyboard delay to suit your own typing
needs.
69
754
~"
20 POKE CHACT.INTCRND(0)*4)
30 FOR N=1 TO 100:NEXT N:GOTO 15
See COMPUTE!, December 1981.
Using a machine language routine and page six space, try:
10 PAGE=1536:EXIT=1568
20 FOR N=PAGE TO EXIT:READ BYTE:POKE
N,BYTE:NEXT N
30 PGM=USR(PAGE)
40 PRINT .. ~ IS A ~ OF l.i ... :I:... ara
TEXT":REM MAKE SOME WORDS INVERSE
50 60TO 50
60 DATA 104,169,17,141,40,2,169,6,141
,41
70 DATA 2,169,30,141,26,2,98,173,243,
2
80 DATA 41,1,73,1,141,243,2,169,30,14
1,26,2,96
70
756
71
756
°
1040 DATA 34,0,126,82,82,82,108,0,0
1050 DATA 35,56,84,254,238,254,68,56~
°
1060 DATA 36,100,84,76,0,48,72,72,48
2000 END
RUN it and type the letters A to D.
Why 224 and 226? Translated to hex, these values are $EO and
$E2, respectively. These are the high bytes (MSB) for the location
of the character set stored in ROM: $EOOO (57344) is the address
for the start of the set (which begins with punctuation, numbers
and uppercase letters), and $E200 (57856), for the second half of
the ROM set, lowercase and graphic control characters (both
start on page boundaries). The ROM set uses the internal order
given on page 55 of your BASIC Reference Manual, not the
ATASCII order. See also location 57344 ($EOOO).
You will notice that using the PRINT#6 command will show you
that your characters have more than one color available to them
in GR. I and GR.2. Try PRINTing lowercase or inverse
characters when you are using the uppercase set. This effect can
be very useful in creating colorful text pages. Uppercase letters,
numbers, and special characters use color register zero (location
708; $2C4 - orange) for normal display, and color register two
(710; $2C6 - blue) for inverse display. Lowercase letters use
register one (709; $2C5 - aqua) for normal display and register
three (711; $2C7 - pink) for inverse. See COMPUTE!, December
1981, page 98, for a discussion of using the CTRL keys with letter
keys to get different color effects.
72
756
One problem with POKEing 756 with 226 is that there is no blank
space character in the second set: you get a screen full of hearts.
You have two choices: you can change the color of register zero
to the same as the background and lose those characters which
use register zero - the control characters - but get your blanks
(and you still have registers one, two and three left). Or you can
redefine your own set with a blank character in it. The latter is
obviously more work. See "Ask The Readers," COMPUTE!, July
1982.
It is seldom mentioned in the manuals, but you cannot set 756 to
225 ($El) or any other odd number. Doing so will only give you
screen garbage. The page number 756 points to must be evenly
divisible by two.
When you create your own character set and store it in memory,
you need to reserve at least 1K for a full character set (1024 bytes
- $400 or four pages), and you must begin on a page boundary.
In hex these are the numbers ending with $XXOO such as $COOO
or $600 because you store the pointer to your set here in 756; it
can only hold the MSB of the address and assumes that the l.SB is
always zero - or rather a page boundary. You can reserve
memory by:
POKE 106, PEEK(106) -4 (or any multiple of four)
And do a GRAPHICS command immediately after to have your
new memory value accepted by the computer. If you are using
only one half of the entire set, for GR.1 or GR.2, you need only
reserve 512 bytes, and it may begin on a Y2K boundary (like
$E200; these are hexadecimal memory locations that end in
$X200). If you plan to switch to different character sets, you will
need to reserve the full 1K or more, according to the number of
different character sets you need to display. RAM for half-K sets
can be reserved by:
POKE 106, PEEK (106) -2 (or a multiple of two)
The location for your set will then begin at PEEK(l06) * 256.
Because BASIC cannot always handle setting up a display list for
GR.7 and GR.8 when you modify location 106 by less than 4K (16
pagesL you may find you must use PEEK(l06) -16. See location
88,89 ($58,$59) and 54279 ($D407) for information regarding
screen use and reserving memory.
Make sure you don't have your character set overlap with your
player/missile graphics. Be very careful when using altered
character sets in high memory. Changing GRAPHICS modes, a
CLEAR command, or scrolling the text window all clear memory
past the screen display. When you scroll the text window, you
73
756
don't simply scroll the four lines; you actually scroll a full 24 (20
additional lines • 40 bytes equals 800 bytes scrolled past
memory)! This messes up the memory past the window display
address, so pOSition your character sets below all possible
interference (or don't scroll or clear the screen).
You can create and store as many character sets as your memory
will allow. You switch back and forth between them and the ROM
set by simply POKEing the MSB of the address into 756. Of
course, you can display only one set at a time unless you use an
altered display list and DLI to call up other sets. There are no
restrictions outside of memory requirements on using altered
character sets with P/M graphics as long as the areas reserved for
them do not overlap.
A GRAPHICS command such as GR.O, RESET or a DOS call
restores the character set pointer to the ROM location, so you
must always POKE it again with the correct location of your new
set after any such command. A useful place to store these sets is
one page after the end of RAM, assuming you've gone back to
location 106 ($6A) and subtracted the correct number of pages
from the value it holds (by POKE 106, PEEK( 106) minus the
number of pages to be reserved; see above). Then you can resel
the character set location by simply using POKE
756,PEEK( 106) + 1 (the plus one simply makes sure you start at
the first byte of your set).
A full character set requires 1024 bytes OK: four pages) be
reserved for it. Why? Because there are 128 characters, each
represented by eight bytes, so 128 * eight equals 1024. If you are
using a graphics mode that uses only half the character set, you
need only reserve 512 bytes (64 * eight equals 512). Remember to
begin either one on a page boundary (1 K boundary for full sets or
V2K for half sets). By sWitching back and forth between two
character sets, you could create the illusion of animation.
Many magazines have published good utilities to aid in the
design of altered character sets, such as the January 1982
Creative Computing, and SuperFont in COMPUTE!, January
1982. I suggest that you examine The Next Step from Online,
Instedit from APX, or FontEdit from the Code Works for very
'---
useful set generators. One potentially useful way to alter just a
few of the characters is to duplicate the block of memory which
holds the ROM set by moving it byte by byte into RAM. A BASIC
FOR-NEXT loop can accomplish this, although it's very slow. For
example:
5 CH=57344
10 START=PEEK(106)-4:PLACE=START*256:
POKE 106,PEEK(106)-5:GRAPHICS O:RE
74
75~7·761
757·761 2F5-2F9
Spare bytes.
75
'762
76
765
" /
keyboard).
When a read request is issued to the keyboard, CH is set to 255
by the handler routine. After a keycode has been read from this
register, it is reset to 255. BREAK doesn't show here, and CTRL
and SHIFT will not show here on their own. However, the inverse
toggle (Atari logo key), CAPS/LOWR, TAB and the ESC keys
will show by themselves. You can examine this register with:
10 LOOK=PEEK(764)
20 PRINT "KEY PRESSED = ";LOOK
30 POKE 764,255
40 FOR LOOP=1 TO 250:NEXT LOOP
50 BOTO 10
See COMPUTEf's First Book of Atari for an example of using this
register as a replacement for joystick input.
765 2FD FILDAT
Color data for the fill region in the XIO FILL command.
766 2FE DSPFLG
Display flag, used in displaying the control codes not associated
with an ESC character (see location 674; $2A2). If zero is
returned or POKEd here, then the ATASCII codes 27 - 31, 123-
127, 187 - 191 and 251 - 255 perform their normal display screen
control functions (Le., clear screen, cursor movement,
deletelinsert line, etc.). If any other number is returned, then a
control character is displayed (as in pressing the ESC key with
CTRL-CLEAR for a graphic representation of a screen clear).
POKEing any positive number here will force the display instead
of the control code action. There is, however, a small bug, not
associated with location 766, in Atari BASIC: a PRINTed CTRL-R
or CTRL-U are both treated as a semicolon.
767 2FF SSFLAG
Start/stop display screen flag, used to stop the scrolling of the
screen during a DRAW or graphics routine, a LISTing or a
PRINTing. When the value is zero, the screen output is not
stopped. When the value is 255 ($FF; the one's complement), the
output to the screen is stopped, and the machine waits for the
value to become zero again before continuing with the scrolling
display. Normally SSFLAG is toggled by the user during these
operations by pressing the CTRL-l keys combination to both start
and stop the scroll. Set to zero by RESET and powerup.
PAGE THREE
Locations 768 to 831 ($300 to $33F) are used for the device handler and
vectors to the handler routines (devices S:, P:, E:, D:, C:, R: and K:).
77
768
78
111
All of the above are disk device commands, except write and
status, which are also printer commands (with no verify).
711 303 DSTATS
The status code upon return to user. Also used to set the data
direction; whether the device is to send or receive a data frclme.
This byte is used by the device handler to indicate to S10 what to
do after the command frame is sent and acknowledged. Prior to
the SIO call, the handler examines BIT 6 (one equals receive
data) and BIT 7 (one equals send data). If both bits are zero, then
no data transfer is associated with the operation. Both bits set to
one is invalid. S10 uses it to indicate to the handler the status of
the requested operation after the S10 call.
772,773 304,305 DBUFLO/HI
Data buffer address of the source or destination of the data to be
transferred or the device status information (or the disk sector
data). Set by the user, it need not be set if there is no data
transferred, as in a status request.
774 306 DTIMLO
The time-out value for the handler in one-second units, supplied
by the handler for use by S10. The cassette time-out value is 35,
just over 37 seconds. The timer values are 64 seconds per 60 units
of measurement. Initialized to 31.
775 307 DUNUSE
Unused byte.
116.117 30S,309 DBYTLO/HI
The number of bytes transferred to or from the data buffer (or the
disk) as a result of the most recent operation, set by the handler.
Also used for the count of bad sector data. There is a small bug in
SIO which causes incorrect system actions when the last byte in a
buffer is in a memory location ending with $FF, such as $AOFF.
77S,779 aOA,aOB DAUXI/2
Used tor device-specific information such as the disk sector
number for the read or write operation. Loaded down to locations
572,573 ($23C, $23D) by S10.
There are only five commands supported by the disk handler:
GET sector (82; $52), PUT sector (80; $50), PUT sector with
VERIFY (87; $57), STATUS request (83; $53) and FORMAT entire
disk (33; $21). There is no command to FORMAT a portion of the
disk; this is done by the INS 1771-1 formatter/controller chip in
the drive itself and isn't user-accessible. There is a new disk drive
ROM to replace the current \lC" version. It is the \IE" ROM. Not
only is it faster than the older ROMs, but it also allows for
selective formatting of disk sectors. Atari has not announced yet
79
780,781
whether this new 810 ROM will be made available. For more
information, see the OS User's Manual.
Locations 780 to 793 ($30C to $319) are for miscellaneous use.
Locations 794 to .831 ($3IA to $33F) are handler address tables. To use
these DCBs, the user must provide the required parameters to this
block and then do a machine language ]SR to $E453 (58451) for disk
I/O or $E459 (58457; the 510 entry point) for other devices.
780.781 30C,30D TIMER 1
Initial baud rate timer value.
782 30E ADDCOR
Addition correction flag for the baud rate calculations involving
the timer registers.
783 30F CASFLG
Cassette mode when set. Used by 510 to control the program
flow through shared code. When set to zero, the current
operation is a standard 510 operation; when non-zero, it is a
cassette operation.
784,785 310,311 TIMER2
Final timer value. Timer one and timer two contain reference
times for the start and end of the fixed bit pattern receive period.
The first byte of each timer contains the VCOUNT value (54283;
$D40B), and the second byte contains the current realtime clock
value from location 20 ($14). The difference between the timer
values is used in a lookup table to compute the interval for the
new values for the baud rate passed on to location 750, 751
($2EE, $2EF).
786,787 312.313 TEMPI
Two-byte temporary storage register used by_SIO for the
VCOUNT calculation during baud timer routines. See location
54283 ($D40B).
788 314 TEMP2
Temporary storage register.
789 315 TEMPS
Ditto.
790 316 SAVIO
Save serial data-in port used to detect, and updated after, each
bit arrival. Used to retain the state of BIT 4 of location 53775
($D20F; serial data-in register).
791 317 TIMFLG
Time-out flag for baud rate correction, used to define an
unsuccessful baud rate value. Initially set to one, it is
80
792
81
" - .... ------------~-----
194-831
Locations 832 to 959 ($340 to $3BF) are reserved for the eight rOCB's
(input/output control blocks). IOCB's are channels for the transfer of
information (data bytes) into and out of the Atari, or between devices.
You use them to tell the computer what operation to perform, how
much data to move and, if necessary, where the data to be moved is
located. Each block has 16 bytes reserved for it.
What is an IOCB? Every time you PRINT something on the screen or
the printer, every time you LOAD or SAVE a file, every time you OPEN
a channel, you are using an lOCB. In some cases, operations have
automatic OPEN and CLOSE functions built in - like LPRINT. In
others, you must tell the Atari to do each step as you need it. Some
lOCB's are dedicated to specific use, such as zero for the screen
display. Others can be used for any I/O function you wish. The
information you place after the OPEN commanc:! tells CIO how you
want the data transferred to or from the device. It is SIO and the device
handlers that do the actual transfer of data.
82
832-847
""~
You can easily POKE the necessary values into the memory locations
and use a machine language subroutine through a USR function to call
the CIO directly (you must still use an OPEN and CLOSE statement for
the channel, however). This is useful because BASIC only supports
either record or single byte data transfer, while the CIO will handle
complete buffer I/O. See the CIO entry address, location 58454
($E456), for more details. These blocks are used the same way as the
page zero IOCB (locations 32 to 47; $20 to $2F). The OS takes the
information here, moves it to the ZIOCB for use by the ROM CIO, then
returns the updated information back to the user area when the
operation is done.
Note that when BASIC encounters a DOS command, it CLOSEs a.ll
channels except zero. Refer to the Atari Hardware Manual and the 850
Interface Manual for more detailed use of these locations.
83
~------ .. _ - - - - - - -
848-863
84
94~~-959
85
944·959
<-
Bit 7 6 5 4 3 2 1 o
U&e .... unused .... W R D A
W equals write, R equals read, D equals directory, A equals
append.
ICAX2 11 1 Auxiliary byte two, referred
to as AUX2. Special use by each device driver; some serial port
functions may use this byte. Auxiliary bytes two to five have no
fixed use; they are used to contain device-dependent and/or
user-established data.
ICAX3/4 12,13 2 Auxiliary bytes three and
four; used to maintain a record of the disk sector number for the
BASIC NOTE and POINT commands.
ICAX5 14 1 Auxiliary byte five. Used by
NOTE and POINT to maintain a record of the byte within a sector.
It stores the relative displacement in sector from zero to 124
($7C). Bytes 125 and 126 of a sector are used for sector-link
values, and byte 127 ($7F) is used as a count of the number of
data bytes in actual use in that sector.
ICAX6 15 1 Spare auxiliary byte.
Offset is the number you would add to the start of the IOCB in
order to POKE a value into the right field, such as POKE 832 +
OFFSET,12.
The following is a list of the values associated with OPEN
parameter number 1. Most of these values are listed in Your Atari
4001800. These are the values found in lCAX1, not the ICCOM
values.
Device Task # Description
Cassette 4 Read
recorder 8 Write (can do either, not both)
Disk 4 Read
file 6 Read disk directory
8 Write new file. Any file OPENed in
this mode will be deleted, and the first byte written will be at the
start of the file.
9 Write - append. In this mode the
file is left intact, and bytes written are put at the end of the file.
12 Read and write - update. Bytes
read or written will start at the first byte in the file.
D: if BIT 0 equals one and BIT 3 equals one in AUXl, then
operation will be appended output.
Screen 8 Screen output
editor 12 Keyboard input and screen output
86
944-959
87
------------------------------------------------------~,.
944-959
#n,A
Get binary record (buffer) 7 7 BASIC:
GET#n,A
Put text record (line) 9 9
Put binary record (buffer) 11 B BASIC:
PUT#n,A
Close 12 C
Dynamic (channel) status 13 D
BASIC uses a special "put byte" vector in the IOCB to talk
directly to the handler for the PRINT#n,A$ command.
Disk File Management System Commands (BASIC XIO
command):
Rename 32 20
Erase (delete) 33 21
Protect (lock) 35 23
Unprotect (unlock) 36 24
Point 37 25
Note 38 26
Format 254 FE
In addition, XIO supports the following commands:
Get character 7 7
Put character 11 B
Draw line 17 Display
11
handler
only.
Fill area 18 12 Display
handler
only.
FILL is done in BASIC with XIO 18,#6,12,0, "S:" (see the BASIC
Reference Manual for details).
For the RS-232 (R:), XIO supports:
Output partial block 32 20
Control RTS,XMT,DTR 34 22 ~.........-,
Baud, stop bits, word size 36 24
Translation mode 38 26
Concurrent mode 40 28
(see the 850 Interface Manual for details)
CIO treats any command byte value greater than 13 ($D) as a
special case, and transfers control over to the device handler !for "---
88
961~-999
89
--- -------~------------------
~,
1406
Locations 1152 to 1791 ($480 to $6FF) are for user RAM (outer
environment) requirements, depending on the amount of RAM
available in the machine. Provided you don't use the FP package or
BASIC, you have 640 ($280) free bytes here.
Locations 1152 to 1279 ($480 to $4FF) Me 128 ($80) spare bytes.
The floating point package, when used, requires locations 1406 to 1535
($57E to $5FF).
1406 S7E LBPRI
LBUFF prefix one.
1407 S7F LBPR2
LBUFF prefix two.
S80-SFF LBUFF
BASIC line buffer; 128 bytes. Used as an output result buffer for
the FP to ASCII routine at 55526 ($D8E6). The input buffer is
pointed to by locations 243,244 ($F3, $F4).
1504 5EO PLYARG
Polynomial arguments (FP use).
ISI0-ISIS SE6-SEB FPSCR
FP scratch pad use.
1516-1535 5EC-5FF FPSCRI
Ditto. The end of the buffer is named LBFEND.
90
1536,·1791
91
7548-MEMLO
Locations 1792 to 2047 ($700 to $7FF; page seven) are the user boot
area. MEMLO and LOMEM point to 1792 when no DOS or DUP
program is loaded. This area can then be used for your BASIC or
machine language programs. The lowest free memory address is 1792,
and programs may extend upwards from here. There is a one-page
buffer before the program space used for the tokenization of BASIC
statements, pointed to by locations 128, 129 ($80, $81). Actually a
program may start from any address above 1792 and below the screen
display list as long as it does not overwrite this buffer if it is a BASIC
program. Also, 1792 is the start of the FMS portion of DOS when
resident.
When software is booted, the MEMLO pointer at 743,744 ($2E7,$2E8)
in the OS data base (locations 512 to 1151; $512 to $47F) points to the
first free memory location above that software; otherwise, it points to
1792. The DUP portion of DOS is partly resident here, starting at 5440
($1540) and running to 13062 ($1540 to $3306). The location of the OS
disk boot entry routine (DOBOOT) is 62189 ($F2ED). The standard
Atari DOS 2.0S takes up sectors one through 83 ($53) on a disk. Sector
one is the boot sector. Sectors two through 40 ($28) are the FMS
portion, and sectors 41 ($29) through 83 are the DUP.SYS portion of
DOS. For more information, see the DOS and OS source listings and
Inside Atari DOS.
92
1801
93
- - - _ .. --------------------------
1802
94
21016
95
2751
96
3850
97
5121
98
---------------
;5440
99
S4lS
100
'7548
7548 ID7C
Beginning of non-resident portion of DUP; 40 ($28) byte
parameter buffer.
7588 IDA4 LINE
80 ($50) byte line buffer.
7668 IDF4 DBUF
256 ($100) byte data buffer for COPY routines. Copy routines
work in 125-byte passes, equal to the number of data bytes in
each sector on the disk. There are 256 bytes because Atari had
planned a double density drive which has 253 data bytes in Elach
sector.
7924 IEF4
Miscellaneous variable storage area and data buffers.
7951-8278 IFOF-2056 DMENU
Disk menu screen display data is stored here.
8191 IFFF
This is the top of the minimum RAM required for operation (8K).
To use DOS, you must have a minimum of 16K.
DUP.SYS ROUTINES
Locations 8192 to 32767 ($2000 to $7FFF) are the largest part of the
RAM expansion area; this space is generally for your own use. If you
have DOS.SYS or DUP.SYS loaded in, they also use a portion of this
area to 13062 ($3306) as below:
8309 2075 DOSOS
Start of the DOS utility monitor, including the utilities called
when a menu selection function is completed and the display of
the "SELECT ITEM" message.
8505 2139 DIRLST
Directory listing.
8649 21C9 DELFIL
Delete a file.
8990 231E
Copy a file. This area starts with the copy messages. The copy
routines themselves begin at PYFIL, 9080 ($2378).
9783 2637 RENFIL
Rename a disk file routines.
9856 2680 FMTDSK
Format the entire disk. There is no way to format specific sectors
101
"""----------
9966
of a disk with the He" ROMs currently used in your 810 drives.
There is a new ROM, the HE" version, which not only allows
selective sector formatting, but is also considerably faster. It WdS
not known at the time of this writing whether Atari would release
the HE" version.
9966 26EE STCAR
Start a cartridge.
10060 274C BRUN
Run a binary file at the user-specified address.
10111 277F
Start of the write MEM.SAV file to disk routine. The entry point is
at MEMSAV, 10138 ($279A).
10201 27D9 WBOOT
Write DOS/DUP files to disk.
10483 28F3 TESTVER2
Test for version two DOS. DOS.20S is the latest official DOS,
considerably improved over the earlier DOS 1.0. The S stands for
single density. Atari had planned to release a dual density drive
(the 815), but pulled it out of the production line at the last minute
for some obscure high-level reason. A double density drive is
available from the Percom company.
10522 291A LDFIL
Load a binary file into memory. If it has a run address specified in
the file, it will autoboot.
10608 2970 LKFIL, ULFIL
Lock and unlock files on a disk.
10690 29C2 DDMG
Duplicate a disk.
11528 2D08 DFFM
Duplicate a file.
11841 2E41
Miscellaneous subroutines.
12078 2F2E SAVFIL
Save a binary file.
12348 303C
Miscellaneous subroutines.
13062 3306
End of DUP.SYS.
The rest of RAM is available to location 32767 ($7FFF).
102
CARTRIDGE B: 8K
Locations 32768 to 40959 ($8000 to $9FFF) are used by the right
cartridge (Atari 800 only), when present. When not present, this RAM
area is available for use in programs. When the 8K BASIC cartridge is
being used, this area most frequently contains the display list and screen
memory. As of this writing, the only cartridge that uses this slot is
Monkey Wrench from Eastern House Software.
It is possible to have 16K cartridges on the Atari by either combining
both slots using two 8K cartridges or simply having one with large
enough ROM chips and using one slot. In this case, the entire area from
32768 to 49151 ($8000 to $BFFF) would be used as cartridge ROM.
Technically, the right cartridge slot is checked first for a resident
cartridge and initialized, then the left. You can confirm this by putting
the Assembler Editor cartridge in the right and BASIC in the left slots.
BASIC will boot, but not the ASED. Using FRE(O), you will see,
however, that you have 8K less RAM to use; and PEEKing through this
area will show that the ASED program is indeed in memory, but that
control was passed to BASIC. Control will pass to the ASED cartridge if
the cartridges are reversed. This is because the last six bytes of the
cartridge programs tell the OS where the program begins - in both
cases, it is a location in the area dedicated to the left cartridge. The six
bytes are as follows:
Byte Purpose
Left (A) Right(B)
49146 ($BFFA) 40954 ($9FFA) Cartridge start address (low byte)
49147 ($BFFB) 40955 ($9FFB) Cartridgestartaddress(highbyte)
49148 ($BFFC) 40956,($9FFC) Reads zero if a cartridge is
inserted, non-zero when no cartridge is present. This informa.tion
is passed down to the page zero RAM: if the A cartridge is plugged
in, then location 6 will read one; if the B cartridge is plugged in,
then location 7 will read one; otherwise they will read zero.
49149 ($BFFD) 40957 ($9FFD) Option byte. If BIT 0 equals one,
then boot the disk (else there is no disk boot). If BIT 2 equals one,
then initialize and start the cartridge (else initialize but do not
start). If BIT 7 equals one, then the cartridge is a diagnostic
cartridge which will take control, but not initialize the OS (else
non-diagnostic cartridge). Diagnostic cartridges were used by
Atari in the development of the system and are not available to the
public.
49150 ($BFFE) 40958 ($9FFE) Cartridge initialization address
low byte.
49151 ($BFFF) 40959 ($9FFF) Cartridge initialization address
high byte. This is the address to which the OS will jump during all
103
powerup and RESETs.
The OS makes temporary use of locations 36876 to 36896 ($900C to
$9020) to set up vectors for the interrupt handler. See the OS
listings pages 31 and 81. This code was only used in the
development system used to design the Atari.
CARTRIDGE A: 8K
Locations 40960 to 49151 ($AOOO to $BFFF) are used by the left
cartridge, when present. When not present, this RAM area is available
for other use. The display list and the screen display data will be in this
area when there is no cartridge present.
Most cartridges use this slot (see above) including the 8K BASIC,
Assembler-Editor, and many games. Below are some of the entry
points for the routines in Atari 8K BASIC. There is no official Atari
listing of the BASIC ROM yet. Many of the addresses below are listed
in Your Atari 4001800. Others have been provided in numerous
magazine articles and from disassembling the BASIC cartridge.
BASIC ROUTINES
40960-41036 AOOO-A04C
Cold start.
41037 -41055 A04D-A05F
Warm start.
41056-42081 A060-A461
Syntax checking routines.
42082-42158 A462-A4AE
Search routines.
42159-42508 A4AF-A60C
STATEMENT name table. The statement TOKEN list begins at 42161
($A4Bl). You can print a list of these tokens by:
5 ADDRESS = 42161
10 IF NOT PEEK(ADDRESS) THEN PRINT:
END '-
15 PRINT TOKEN,
20 BYTE = PEEK(ADDRESS): ADDRESS = A
DDRESS + 1
30 IF BYTE < 128 THEN PRINT CHR$(BVT
E);: GO TO 20
40 PRINT CHR$(BVTE - 128)
50 ADDRESS = ADDRESS + 2: TOKEN = TO
KEN + 1: GOTO 10
42509-43134 A60D-A87E
Syntax tables. The OPERATOR token list begins at 42979 ($A7E3). You
104
can print a list of these tokens by:
5 ADDRESS = 42979: TOKEN = 16
10 IF NOT PEEK(ADDRESS} THEN PRINT:
END
15 PRINT TOKEN~
20 BYTE = PEEKCADDRESS): ADDRESS = A
DDRESS + 1
30 IF BYTE < 128 THEN PRINT CHR$(BYT
E);: 60TO 20
40 PRINT CHR$(BYTE - 128)
50 TOKEN = TOKEN + 1
60 60TO 10
See COMPUTE!, January and February 1982; BYTE, February 1982,
and De Re Atari for an explanation of BASIC tokens.
43135-43358 A87F-A95E
Memory manager.
43359-43519 A95F-A9FF
Execute CONT statement.
43520-43631 AAOO-AA6F
Statement table.
43632-43743 AA70-AADF
Operator table.
43744-44094 AAEO-AC3E
Execute expression routine.
44095-44163 AC3F-AC83
Operator precedence routine.
44164-45001 AC84-AFC9
Execute operator routine.
45002-45320 AFCA-B108
Execute function routine.
45321-47127 B109-B817
Execute statement routine.
47128-47381 B818-B915
CONT statement subroutines.
47382-47542 B916-B9B6
Error handling routines.
47543-47732 B9B7-BA74
Graphics handling routines.
47733-48548 BA75-BDA4
I/O routines.
48549-49145 BDA5-BFF9
Floating point routines (see below).
105
48551
106
- ........<'
locations are:
128,129 80,81 LOMEM
130,131 82,83 VNTP
132,133 84,85 VNTD
134,135 86,87 VVTP
136,137 88,89 STMTAB
138,139 8A,8B STMCUR
140,141 8C,8D STARP
The string/array space is not loaded; STARP is included only to
point to the end of the BASIC program.
The two other critical BASIC page zero pointers, which are not
SAVEd with the program, are:
142,143 8E,8F RUNSTK
144,145 90,91 MEMTOP
For more information concerning Atari BASIC, see the appendix.
For detailed description, refer to the Atari BASIC Reference
Manual. For more technical information, see De Re Atari, BYTE,
February 1982, and COMPUTEf's First Book of Atari and
COMPUTEf's Second Book of Atari.
Locations 53248 to 55295 ($DOOO to $D7FF) are for ROM for the special
I/O chips that Atari uses. The CTIA (or GTIA, depending on which
you have) uses memory locations 53248 to 53503 ($DOOO to $DOFF).
POKEY uses 53760 to 54015 ($D200 to $D2FF). PIA uses 54016 to 54271
107
53248-53505
CTIAorGTIA
53248-53505 DODO-DOFF
GTIA (or CTIA) is a speCial television interface chip designed
exclusively for the Atari to process the video signal. ANTIC
controls most of the C/GTIA chip functions. The GTlA shifts the
display by one-half color clock off what the CTIA displays, so it
may display a different color than the CTIA in the same piece of
software. However, this shift allows players and playfields to
overlap perfectly.
There is no text window available in GTIA modes, but you can
create a defined area on your screen with either a DLI (see
COMPUTE!. September 1982) or by POKEing the GTIA mode
number into location 87 ($57), POKEing 703 with four and then
setting the proper bits in location 623 ($26F) for that mode. Only in
108
/'
S3248
Bottom
224 for single,
112 for double line
resolution
--....:
Although you can POKE to these horizontal position registers, they
are reset to zero immediately. The player or missile will stay on the
screen at the location specified by the POKE, but in order to move
it using the horizontal position registers, you can't use:
POKE 53248, PEEK (53248) + n (or -n)
which will end up generating an error message. Instead, you need
to use something like this:
io POKE 704,220: GRAPHICS 1: HPOS =
53248: POKE 623,8
109
53248
110
·~~ 53249
III
53251
112
5~125'l
113
53258
MIPL
(R) Missile 1 to player collisions.
53258 DOOA SIZEP2
(W) Size of player 2.
M2PL
(R) Missile 2 to player collisions.
53259 0008 SIZEP3
(W) Size of player 3.
M3PL
(R) Missile 3 to player collisions.
53260 DOOe SIZEM
(W) Size for all missiles; set bits as below (decimal values
included):
Bits Size:
Normal Double Quadruple
7 & 6: missile 3 0,128 64 192
5 & 4: missile 2 0, 32 16 48
3 & 2: missile 1 0, 8 4 12
1 & 0: missile 0 0, 2 1 3
where turning on the bits in each each pair above does as follows:
oand 0: normal size - two color clocks wide
oand 1: twice normal size - four color clocks wide
1 and 0: normal size
1 and 1: four times normal size - eight color clocks wide
So, to get a double-sized missile 2, you would set BITs 5 and 6, or
POKE 53260,48. Each missile can have a size set separately from
the other missiles or players when using the GRAF registers.
A number of sources, including De Re Atari, say that you can set
neither missile sizes nor shapes separately. Here's a routine to
show that you can in fact do both:
10 POKE 53265,255: REM SHAPE START
15 SR.7
20 POKE 623~1: REM SET PRIORITIES
30 FOR X = 1 TO 25
35 F = 50
40 FOR C = 704 TO 707: POKE C,F + X:
F = F + 50: NEXT C: REM COLOURS
4S S = 100
50 FOR P = 53252 TO 53255: POKE P,S
+ X: S = S + 20: NEXT P : REM SCRE
EN POSITIONS
114
'"- 5:3261
60 NEXT X
70 INPUT A,B: REM MISSILE SIZE AND S
HAPES
80 POKE 53260,A: POKE 53265~B
100 GOTO 30
Here's another example using DMA; GRACTL and DACTL
(53277 and 54272; $DOlD and $D400):
10 POKE 623,1: POKE 559,54: POKE 542
79, 224: POKE 53277.1
20 FOR N = 53252 TO 53255: POKE N, 1
00 + X: X = X + 10: NEXT N: X = 0
30 INPUT SIZE: POKE 53260, SIZE
40 GOTO 30
See 54279 ($D407) for more information on PIM graphics.
POPL
(R) Player 0 to player collisions. Bit use is:
Bli 7 6 5 4 3 2 1 0
Player ... unused. . . 3 2 1 0
Decimal ............ 8 4 2 1
53261 0000 GRAFPO
(W) Graphics shape for player 0 written directly to the player
graphics register. In using these registers, you bypass ANTIC.
You only use the GRAFP# registers when you are not using
Direct Memory Access (DMA: see GRACTL at 53277). If DMA is
enabled, then the graphics registers will be loaded automatically
from the area specified by PMBASE (54279; $D407).
The GRAF registers can only write a single byte to the playfield,
but it runs the entire height of the screen. Try this to see:
10 POKE 53248, 160: REM SET HORIZONT
AL POSITION OF PLAYER 0
20 POKE 704, 245: REM SET PLAYER 0 C
OLOUR TO ORANGE
30 POKE 53261, 203: REM BIT PATTERN
11001011
To remove it, POKE 53261 with zero. The bit order runs from
seven to zero, left to right across the TV screen. Each bit set will
appear as a vertical line on the screen. A value of 255 means all
bits are set, creating a wide vertical line. You can also use the
size registers to change the player width. Using the GRAF
registers will allow you to use players and missiles for such things
as boundaries on game or text fields quite easily.
PIPL
115
(R) Player 1 to player collisions.
53262 DOOE GRAFPl
(W) Graphics for player 1.
P2PL
(R) Player 2 to player collisions.
53263 DOOF GRAFP2
(W) Graphics for player 3.
P3PL
(R) Player 3 to player collisions.
53264 DOlO GRAFP3
(W) Graphics for player 3.
TRIGO
(R) Joystick trigger 0 (644). Controller jack one, pin six. For all.
triggers, zero equals button pressed, one equals not pressed. If
BIT 2 of GRACTL (53277; $DOlD) is set to one, then all TRIG
BITs 0 are latched when the button is pressed (set to zero) and Cire
only reset to one (not pressed) when BIT 2 of GRACTL is reset to
zero. The effect of latching the triggers is to return a constant
\\button pressed" read until reset.
53265 DOll GRAFM
(W) Graphics for all missiles, not used with DMA. GRAFM works
the same as GRAFPO above. Each pair of bits represents one
missile, with the same allocation as in 53260 ($DOOC) above.
Bit 7 6 S 4 3 2 1 0
Missile -3- -2- -1- -0-
Each bit set will create a vertical line running the entire height of
the TV screen. Missile graphics shapes may be set separately
from each other by using the appropriate bit pairs. To mask oui
unwanted players, write zeros to the bits as above.
TRIG 1
(R) Joystick trigger 1 (645). Controller jack two, pin six.
53266 D012 COLPMO
(W) Color and luminance of player and missile 0 (704). Missilei3
share the same colors as their associated players except when
joined together to make a fifth player. Then they take on the same
value as in location 53733 ($D019; color register 3).
TRIG 2
(R) Joystick trigger 2 (646). Controller jack three, pin six.
53267 D013 COLPMl
(W) Color and luminance of player and missile 1 (705).
116
TRIG3
(R) Joystick trigger 3 (647). Controller jack four, pin six.
53268 D014 COLPM2
(W) Color and luminance of player and missile 2 (706).
PAL
(R) Used to determine if the Atari is PAL (European and Israeli
TV compatible when BITs I - 3 equal zero) or NTSC (North
American compatible when BITs 1 - 3 equal one; 14 decimal, $E).
European Ataris run 12% slower if tied to the VBLANK cycle (the
PAL VBLANK cycle is every 50th second rather than every 60th
second). They use only one CPU clock at three MHZ, so the 6502
runs at 2.217 MHZ - 25% faster than North American Ataris.
Also, their $EOOO and $FOOO ROMs are different, so there are
possible incompatibilities with North American Ataris in the
cassette handling routines. There is a third TV standard called
SECAM, used in France, the USSR, and parts of Africa. I am
unaware if there is any Atari support for SECAM standards.
PAL TV has more scan lines per frame, 312 compared to 262 .
NTSC Ataris compensate by adding extra lines at the beginning
of the VBLANK routine. Display lists do not have to be altered,
and colors are the same because of a hardware modification.
53269 D015 COLPM3
Color and luminance of player and missile 3 (707).
53270 D016 COLPFO
Color and luminance of playfield zero (708).
53271 D017 COLPFI
Color and luminance of playfield one (709).
53272 D018 COLPF2
Color and luminance of playfield two (710).
53273 D019 COLPF3
Color and luminance of playfield three (711).
53274 DOIA COLBK
Color and luminance of the background (BAK). (712).
53275 DOIB PRIOR
(W) Priority selection register. PRIOR establishes which objects
on the screen (players, missiles, and playfields) will be in front of
other objects. Values used in this register are also described at
location 623 ($26F), the shadow register. If you use conflicting
priorities, objects whose priorities are in conflict will turn bld"ck
in their overlap region.
117
53276
Priority order
(Decimal values in brackets):
Bit 0 = 1 (1): Bit 1 = 1 (2):
Player 0 Player 0
Player 1 Player 1
Player 2 Playfield 0
Player 3 Playfield 1
Playfield 0 Playfield 2
Playfield 1 Playfield 3 and Player 5
Playfield 2 Player 2
Playfield 3 and Player 5 Player 3
Background Background
Bit 2 = 1 (4): Bit 3 = 1 (8):
Playfield 0 Playfield 0
Playfield 1 Playfield 1
Playfield 2 Player 0
Playfield 3 and Player 5 Player 1
Player 0 Player 2
Player 1 Player 3
Player 2 Playfield 2
Player 3 Playfield 3 and Player 5
Background Background
Bit 4 = 1: Enable a fifth player out of the four missiles.
Bit 5 = 1: Overlap of players 0 and I, 2 and 3 is third color (else
overlap is black). The resulting color is a logical OR of the two
player colors.
Bits 6 and 7 are used to select GTIA modes:
o 0 = no GTIA modes
o 1 = GTIA GR.9
1 0 = GTIA GR.I0
1 1 = GTIA GR.ll
53276 DOIC VDELAY
(W) Vertical delay register. Used to give one-line resolution
movement capability in the vertical positioning of an object when
the two line resolution display is enabled. Setting a bit in
VDELAY to one moves the corresponding object down by one TV
line. If DMA is enabled, then moving an object by more than one
line is accomplished by moving bits in the memory map instead.
Bit Decimal Object
7 128 Player 3
6 64 Player 2
5 32 Player 1 '----
4 16 Player 0
lIB
53277
3 8 Missile 3
2 4 Missile 2
1 2 Missile 1
0 1 Missile 0
53277 0010 GRACTL
(W) Used with DMACTL (location 54272; $D400) to latch all stick
and paddle triggers (to remember if triggers on joysticks or
paddles have been pressed), to turn on players and to turn on
missiles. To get the values to be POKEd here, add the following
options together for the desired function:
Decimal Bit
To turn on missiles 1 0
To turn on players 2 1
To latch trigger inputs 4 2
To revoke PIM authorization and turn off both players and
missiles, POKE 53277,0. Once latched, triggers will give a
continuous "button pressed" read the first time they are pressed
until BIT 2 is restored to zero. Triggers are placed in "latched"
mode when each individual trigger is pressed, but you cannot set
the latch mode for individual triggers.
Have you ever hit BREAK during a program and still had players
or their residue left on the screen? Sometimes hitting RESET
doesn't clear this material from the screen. There are ways to get
rid of it:
POKE 623,4: This moves all players behind playfields.
POKE 53277,0: This should turn them off.
POKE 559,2: This should return you to a blank screen.
Make sure you SAVE your program before POKEing, just in
case!
119
53279
OPTION x X X X
SELECT X X X X
START X X X X
Bits 2 o o o o 1 1 1 1
1 o o 1 1 o o 1 1
o o 1 o 1 o 1 o 1
Where zero means all keys have been pressed, one means
OPTION and SELECT have been pressed, etc., to seven, which
means no keys have been pressed. CONSOL is updated every
stage two VBLANK procedure with the value eight.
H is possible to use the console speaker to generate different
sounds. Here is one idea based on an article in COMPUTE!,
August 1981:
10 BOSUB 1000
20 TEST = USR(1536)
999 END ~
1000 FOR LOOP = 0 TO 26: READ BYTE: P
OKE 1536 + LOOP, BYTE: NEXT LOOP
: RETURN
1010 DATA 104,162,255,169,255,141,31,
208,169
1020 DATA 0,160,240,136,208,253,141,3
1,208,160
1030 DATA 240,136,208,253,202,208,233
,96
To change the tone, you POKE 1547 and 1555 with a higher or
120
53760-54015
lower value (both are set to 240 above). To change the tone
duration, you POKE 1538 with a lower value (it is set to 255 in the
routine above). Do these before you do your USR call or alter the
DATA statements to permanently change the values in your own
program. Turn off DMA (see location 559) to get clearer tones.
POKEY
53760-54015 D200-D2FF
POKEY is a digital 1/0 chip that controls the audio frequency cmd
control registers, frequency dividers, poly noise counters, pot
(paddle) controllers, the random number generator, keyboard
scan, serial port 1/0, and the IRQ interrupts.
The AUDF# (audio frequency) locations are used for the pitch for
the corresponding sound channels, while the AUDC# (audio
control registers) are the volume and distortion values for those
same channels. To POKE sound values, you must first POKE ZHro
into locations 53768 ($D208) and a three into 53775 ($D20F).
Frequency values can range from zero to 255 ($FF), although the
value is increased by the computer by one to range from one to
256. Note that the sum of the volumes should not exceed 32, since
volume is controlled by the least four bits. It is set from zero as no
volume to 15 ($F) as the highest. A POKE with 16 ($10) forces
sound output even if volume is not set (Le., it pushes the speaker
cone out. A tiny "pop" will be heard). The upper four bits control
distortion: 192 ($CO) is for pure tone; other values range from 32 to
192. Note that in BASIC, the BREAK key will not turn off the
sound; RESET will, however. See De Re Atari and BYTE, April
1982, for more information on sound generation.
The AUDF registers are also used as the POKEY hardware timers.
These are generally used when counting an interval less than one
VBLANK. For longer intervals, use the software timers in locations
536 to 545 ($218 to $221). You load the AUDCTL register with the
121
53760
number for the desired clock frequency. You then set the volume
to zero in the AU DC register associated with the AUDF register
you plan to use as a timer. You load the AUDF register itself with
the number of clock intervals you wish to count. Then you load.
your interrupt routine into memory, and POKE the address into the
appropriate timer vector between locations 528 and 533 ($210 and
$215). You must set the proper bit(s) in IROEN and its shadow
register POKMSK at location 16 ($10) to enable the interrupt.
Finally, you load STIMER with any value to load and start the
timer(s). The OS will force a jump to the timer vector and then to
your routine when the AUDF register counts down to zero. Timer
processing can be preempted by ANTIC's DMA, a DLI, or the
VBLANK process.
POT values are for the paddles, ranging from zero to 240,
increasing as the paddle knob is turned counterclockwise, but
values less than 40 and greater than 200 represent an area on
either edge of the screen that may not be visible on all TV sets or
monitors.
53760 D200 AUDFI
(W) Audio channel one frequency. This is actually a number (N)
used in a "divide by N circuit"; for every N pulses coming in (CiS set
by the POKEY clock), one pulse goes out. As N gets larger, output
pulses will decrease, and thus the sound produced will be a lower
note. N can be in the range from one to 256; POKEY adds one to
the value in the AUDF register. See BYTE, April 1982, for a
program to create chords instead of single tones.
POTO
(R) Pot (paddle) 0 (624); pot is short for potentiometer. Turning the
paddle knob clockwise results in decreasing pot values. For
machine language use: these pot values are valid only 228 scan
lines after the POTGO command or after ALLPOT changes (see
53768; $D208 and 53771; $D20B). POT registers continually count
down to zero, decrementing every scan line. They are reset to 228
when they reach zero or by the values read from the shadow
registers. This makes them useful as system timers. See
COMPUTE!, February 1982, for an example of this use.
The POTGO sequence (see 53771; $D20B) resets the POT
registers to zero, then reads them 228 scan lines later. For the fast
pot scan, BIT 2 of SKCTL at 53775 ($D20F) must be set.
122
5:3762
Bit 7 6 5 4 3 2 1 0
Distortion Volume Volume
(noise) only level
0 0 0 0 0 0 0 0 Lowest
0 0 1 0 0 0 1
etc. to: etc. to:
1 1 1 1 1 1 1 1 Highest
(forced
output)
The values for the distortion bits are as follows. The first process is
to divide the clock value by the frequency, then mask the output
using the polys in the order below. Finally, the result is divided by
two.
Bit
7 6 5
0 0 0 five hit, then 17 hit, polys
0 0 1 five hit poly only
0 1 0 five hit, then four hit, polys
0 1 1 five hit poly only
1 0 0 17 hit poly only
1 0 1 no poly counters (pure tone)
1 1 0 four hit poly only
1 1 1 no poly counters (pure tone)
In general, the tones become more regular (a recognizable
droning becomes apparent) with fewer and lower value polys
masking the output. This is all the more obvious at low frequency
ranges. POKE with 160 ($AO) or 224 ($EO) plus the volume for pure
tones.
See De Re Atari and the Hardware Manual for details.
POTI
(R) Pot 1 register (625).
123
53764
POT4
(R) Pot 4 (628).
53765 D205 AUDC3
(W) Audio channel three control.
POTS
(R) Pot 5 (629).
53766 0206 AUOF4
(W) Audio channel four frequency.
POT6
(R) Pot 6 (630).
53767 0207 AUOC4
(W) Audio channel four control.
POT7
(R) Pot 7 (631).
53768 0208 AUOCTL
(W) Audio control. To properly initialize the POKEY sound
capabilities, POKE AUDCTL with zero and POKE 53775,3
($D20F). These two are the equivalent of the BASIC statement
SOUND 0,0,0,0. AUDCTL is the option byte which affects all
sound channels. This bit assignment is:
Bit Description:
7 Makes the 17 bit poly counter into nine bit poly
(see below)
6 Clock channel one with 1.79 MHz
5 Clock channel three with 1.79 MHz
4 Join channels two and one (16 bit)
3 Join channels four and three (16 bit)
2 Insert high pass filter into channel one, clocked by channel
two
1 Insert high pass filter into channel two, clocked by channel
four
o Switch main clock base from 64 KHz to 15 KHz
Poly (polynomial) counters are used as a source of random pulses
for noise generation. There are three polys: four, five and 17 bits
long. The shorter polys create repeatable sound patterns, while the
longer poly has no apparent repetition. Therefore, setting BIT 7
above, making the 17-bit into a nine-bit poly will make the pattern
124
5:3'169
125
----------------------------
53770
POKE any non-zero value here to load and start the timers; the
value isn't itself used in the calculations. This resets all of the audio
frequency dividers to their AUDF values. If enabled by IRQEN
below, these AUDF registers generate timer interrupts when they
count down from the number you POKEd there to zero. The
vectors for the AUDFI / AUDF2 and AUDF4 timer interrupts are
located between 528 and 533 ($210 and $215). POKEY timer four
interrupt is only enabled in the new "B" OS ROMs.
KBCODE
(R) Holds the keyboard code which is then loaded into the shadow
register (764; $2FC) when a key is hit. Usually read in response to
the keyboard interrupt. Compares the value with that in CH I at
754 ($2F2). If both values are the samet then the new code is
accepted only if a suitable key debounce delay time has passed.
The routines which test to see if the key code will be accepted start
at 65470 ($FFBE). BIT 7 is the control key flag, BIT 6 is the shift key
flag.
53770 D20A SKREST
(W) Reset BITs 5 - 7 of the serial port status register at 53775 to one.
RANDOM
(R) When this location is read, it acts as a random number
generator. It reads the high order eight bits of the 17 bit
polynomial counter (nine bit if BIT 7 of AUDCTL is set) for the
value of the number. You can use this location in a program to
generate a random integer between zero and 255 by:
10 PRINT PEEK(53770)
This is a more elegant solution than INT(RND(O) *256). For a test of
the values in this register / use this simple program:
10 FOR N = 1 TO 20: PRINT PEEK(53770): NEXT N
53771 D20B POTGO
(W) Start the POT scan sequence. You must read your POT values
first and then start the scan sequence, since POTGO resets the
POT registers to zero. Written by the stage two VBLANK
sequence.
53772 D20C
Unused.
53773 D20D SERour
(W) Serial port data output. Usually written to in the event of a
serial data out interrupt. Writes to the eight bit (one byte) parallel
holding register that is transferred to the serial shift register when a
full byte of data has been transmitted. This "holding" register is
used to contain the bits to be transmitted one at a time (serially) as
126
5:3114
' ...........
SERIN
(R) Serial port input. Reads the one-byte parallel holding register
that is loaded when a full byte of serial input data has been
received. As above, this holding register is used to hold the bits as
they are received one bit at a time until a full byte is received. This
byte is then taken by the computer for processing. Also used to
verify the checksum value at location 49 ($31).
The serial bus is the port on the Atari into which you plug your
cassette or disk cable. For the pin values of this port, see the OS
User's Manual, p. 133, and the Hardware Manual.
53114 D20E IRQEN
(W) Interrupt request enable. Zero turns off all interrupt requests
such as the BREAK key; to disable or re-enable interrupts, POKE
with the values according to the follOWing chart (setting a bit to one
- i.e., true - enables that interrupt; decimal values are also
shown for each bit):
Bit Decimal Interrupt Vector
o 1 Timer 1 (counted down to zero) VTIMR1
(528; $210)
1 2 Timer 2 (counted down to zero) VTIMR2
(530; $212)
2 4 Timer 4 (counted down to zero) VTIMR4
(532; $214), OS
"B" ROMs only)
3 8 Serial output transmission done VSEROC (526;
$20E)
4 16 Serial output data needed VSEROR
(524; $20C)
5 32 Serial input data ready VSERIN
(522; $20A)
6 64 Other key pressed VKEYBD
(520; $208)
7 128 BREAK key pressed see below
Here is the procedure for the BREAK key interrupt: clear the
interrupt register. Set BRKKEY (17; $11) to zero; clear the
start/stop flag SSFLAG at 767 ($2FF); clear the cursor inhibit flag
CRSINH at 752 ($2FO); clear the attract mode flag at 77 ($4D), and
return from the interrupt after restoring the 6502 A register. (There
is now (in the OS "B" ROMs) a proper vector for BREAK key
interrupts at 566,567 ($236, $237) which is initialized to point to
59220 ($E754).) 1£ the interrupt was due to a serial I/O bus proCl~ed
line interrupt, then vector through VPRCED at 514 ($202).1£ due to
a serial I/O bus interrupt line interrupt, then vector through
127
VINTER at 516 ($204). If due to a 6502 BRK instruction, then vedor
through VBREAK at 518 ($206).
Timers relate to audio dividers of the same number (an interrupt is
processed when the dividers count down to zero). These bits in
IRQEN are not set on powerup and must be initiated by the user
program before enabling the processor IRQ.
There are two other interrupts, processed by PIA, generated over
the serial bus Proceed and Interrupt lines, set by the bits in the
PACTL and PBCTL registers (54018 and 54019; $D302, $D303):
Bit Decimal Location Interrupt
o 1 PACTL Peripheral A (PORTA) interrupt enable,
bit.
7 128 PACTL Peripheral A interrupt status bit.
o 1 PBCTL Peripheral B (PORTB) interrupt enable
bit.
7 128 PBCTL Peripheral B interrupt status hit.
The latter PORT interrupts are automatically disabled on powerup.
Only the BREAK key and data key interrupts are enabled on
powerup. The shadow register is 16 ($10).
IRQST
(R) Interrupt request status. Bit functions are the same as IRQEN
except that they register the interrupt request when it is zero rather
than the enable when a bit equals one. IRQST is used to determine
the cause of interrupt request with IRQEN, PACTL and PBCTL CiS
above.
All IRQ interrupts are normally vectored through 65534 ($FFFE) to
the IRQ service routine at 59123 ($E6F3), which determines the
cause of the interrupt. The IRQ global RAM vector VIMIRQ at :i34
($216) ordinarily pOints to the IRQ processor at 59126 ($E6F6). The
processor then examines 53774 ($D20E) and the PIA registers at
54018 and 54019 to determine the interrupt cause. Once
determined, the routine vectors through one of the IRQ RAM
vectors in locations 514 to 526 ($202 to $20E). For Non-Maskable
Interrupts (NMI's), see locations 54286 to 54287 ($D40E; $D40F).
See the as User's Manual for complete details.
53775 D20F SKCTL
(W) Serial port control. Holds the value 255 ($255) if no key is
pressed, 251 ($FB) for most other keys pressed, 247 ($F7) for
SHIFT key pressed (*M). See the (R) mode below for an
explanation of the bit functions. POKE with three to stop the
occasional noise from cassette after I/O to bring POKEY out of the
two-tone mode. (562).
SKSTAT
128
5:3775
(R) Reads the serial port status. It also returns values governed. by
a signal on the digital track of the cassette tape. You can generate
certain values using the SOUND command in BASIC and a PEEK
toSKSTAT:
SOUND 0,5,10,15 returns a value to here of 255 (or, on
occasion, 127).
SOUND 0,8,10,3 returns a value of 239.
This is handy for adding a voice track to Atari tapes. You use the
left channel for your voice track and the right for the tone(s) you
want to use as cuing marks. You can use the speaker on your TV to
generate the tones by placing the right microphone directly in
front of the speaker. The computer will register these tones in this
register when it encounters them during a later cassette load. See
COMPUTE!, July 1981, for some other suggestions on doing this.
Remember, you can turn the cassette off by POKEing 54018
($D302) with 60 ($3C) and back on with 52 ($34).
Bits in the SKCTL (W) register are normally zero and perform the
functions below when set to one. The status when used as (R) is
listed below the write (W) function:
Bit Function
o (W) Enable keyboard debounce circuits.
(R) Not used by SKSTAT.
(W) Enable keyboard scanning circuit.
(R) Serial input shift register busy.
2 (W) Fast pot scan: the pot scan counter completes its
sequence in two TV line times instead of one frame time (228
scan lines). Not as accurate as the normal pot scan,
however.
(R) the last key is still pressed.
3 (W) Serial output is transmitted as a two-tone signal rather
than a logic true/false. POKEY two-tone mode.
(R) The shift h~y is pressed.
4,5,6 (W) Serial port mode control used to set the bi-directional
clock lines so that you can either receive external clock data
or provide clock data to external devices (see the Hardware
Manual, p. II.27). There are two pins on the serial port for
Clock IN and Clock OUT data. See the OS User's Manual,
p.133.
4 (R) Data can be read directly from the serial input port,
ignoring the shift register.
5 (R) Keyboard over-run. Reset BITs 7 to 5 (latches) to one
using SKRESat 53770 ($D20A).
6 (R) Serial data input over-run. Reset latches as above.
7 (W) Force break (serial output to zero).
129
54016·54211
Left = BIT 2, 6 = 1
Right = BIT 3,7 = 1
Neutral = All four jack bits = 1
PORTA is also used to test if the paddle 0-3 triggers (PTRIG) hdve
been pressed, using these bits:
Bit 7 6 5 4 3 2 1 0
PTRIG 3 2 1 0
Where zero in the appropriate bit equals trigger pressed, one
equals trigger not pressed.
The PORT registers are also used in the keyboard controller (used
with a keypad) operation where:
Bit 7 6 5 4 3 2 1 0
Row 4 3 2 Top 4 3 2 Top
Jack ............ 2............ . ........... 1 ........... .
Columns for the keyboard operation are read through the POT
(PADDL) and TRIG registers. See MicTO, May 1982, and the
Hardware Manual for more information on jacks and ports.
54011 0301 PORTS
(WIR) Port B. Reads or writes data to and/or from jacks three Clnd
four. Same as PORTA, above, for the respective jacks. Shadow
registers are: STICK2 (634; $27A, jack three), STICK3 (635, $27B,
jack four), and PTRIG4-7 (640-643; $280-$283).
54018 D302 PACTL
(WIR) Port A controller (see 54016 above). POKE with 60 ($3C) to
turn the cassette motor off, POKE with 52 to turn it on. You can put
a music cassette in your program recorder, press PLAY and then
POKE 54018,52. Your music will play through the TV speaker or
external amplifier while you work at the Atari. You can use this
technique to add voice tracks to your programs. To turn off the
music or voice, type POKE 54018,60.
PACTL can be used for other external applications by the user. Bit
use is as follows:
Bit Function
7 (read only) Peripheral A interrupt (IRQ) status bit. Set by
Peripheral (PORT) A. Reset by reading PORTA
(53774; $D20E).
6 Set to zero.
5 Set to one.
4 Setto one.
3 (write) Peripheral motor control line (turn the cassette on
or off; zero equals on).
2 (write) Controls PORTA addressing. One equals POHTA
13]
54019
ANTIC
54272-54783 D400-D5FF
ANTIC is a special, separate microprocessor used in your Atari
to control C/GTIA, the screen display, and other screen-related
functions including processing the NMI interrupts. It uses its own
instruction set, called the display list, which tells ANTIC where to
find the screen data in RAM and how to display it. ANTIC also -----;
uses an internal four bit counter called the Delta Counter (DCTR)
to control the vertical dimension of each block.
54272 D400 DMACTL
(W) Direct Memory Access (DMA) control. It is also used to
define one- or two-line resolution for players and to turn on
players and missiles. Values are POKEd into the shadow register,
559 ($22F), and are also described there. You POKE the shadow
register with the follOWing numbers in order to:
Turn off the playfield 0
Use narrow playfield 1
132
--------------~-
-
Use normal playfield 2
Use wide playfield 3
Enable missile DMA 4
Enable player DMA 8
Enable both player and missile DMA 12
Single line player resolution 16
Enable DMA Fetch instructions 32
Double line resolution is the default status. Use this register in
conjunction with GRACTL at 53277 ($DOlD). Both must be set
properly or no display will result. BIT 5 enables DMA to fetch the
display list instructions. If BIT 5 is not set (BIT 5 equals zero),
ANTIC will not work. DMACTL is initialized to 34 ($22).
A player in single line resolution might look like this:
00011000 ##
00111100 ####
01111110 ######
11111111 ########
11111111 ########
01111110 ######
00111100 ####
00011000 ##
so that each byte is displayed on one TV line. The same player in
double line resolution would look like this:
00011000 ##
00011000 ##
00111100 ####
00111100 ####
01111110 ######
01111110 ######
11111111 ########
11111111 ########
11111111 ########
11111111 ########
01111110 ######
01111110 ######
00111100 ####
00111100 ####
00011000 ##
00011000 ##
where every byte is displayed over two TV lines.
54273 D401 CHACTL
(W) Character mode control. See shadow register 755 for vdlues
that can be POKEd in. Only the least three bits (decimal zero to
133
54274,5
"~.'~'
• • ~ • • • • • • & • • • • ~ • • • •
134
- 54277
Now you will have to make each display instruction for each line
into a Load Memory Scan (LMS) instruction. To direct each LMS
to the proper screen RAM for that line, you will have to increment
each memory location by the total length of the line. For
example, if you want to scroll a 256-byte horizontal screen, each
LMS instruction will have to point to a location in memory 256
bytes above the last one. Of course, you will have to implement
error-trapping routines so that your screen does not extend
beyond your desired boundaries.
Coarse scrolling, one byte at a time, can be done without setting
the HSCROL register by the method described above. For
smooth scrolling, you will ha ve to use this register. See De Re
Atari.
54277 D405 VSCROL
(W) Vertical scroll enable, POKE VSCROL with from zero to 16
scan lines, depending on the GRAPHICS mode of the screen for
the number of scan lines to scroll. Vertical fine scrolls can be
used only if BIT 5 of the display list instruction has been set.
Coarse scrolling can be done without using this register, simply
by moving the top of the screen address (as defined by the DL
LMS instruction) up or down one mode line (plus or minus 40 or
20 bytes, depending on the GRAPHICS mode). The top of the
screen address can be found by:
10 DLIST = PEEK(560) + PEEK(561) 2 *
56
20 SCRNLO = DLIST + 4: SCRNHI = DLIS
T + 5: REM LSB/MSB OF SCREEN ADDRE
SS
25 PRINT "SCREEN ADDRESS = » PEEK(SC
RNLO) + PEEK(SCRNHI) 256 *
You could then add a routine to this for a coarse - scroll vertically
through the memory with a joystick, such as:
30 LOBYTE = 0: HIBYTE = 0
40 IF STICK(O) = 14 THEN LOBYTE = LO
BYTE + 40:60TO 100
50 IF STICK(O) = 13 THEN LOBYTE = LO
BYTE - 40
60 IF LOBYTE < 0 THEN LOBYTE = LOBYT
E + 256: HIBYTE = HIBYTE - 1
70 IF HIBYTE ..( 0 THEN HIBYTE = 0
80 GOTO 200
100 IF LOBYTE > 255 THEN LOBYTE LOB
YTE - 256
110 HIBVTE = HIBYTE + 1
135
54278
136
54279
137
54279
60 DATA 205,208,240,198,204~160,0,1
45,203,96
70 A = USR(ADR(P6MS),START,BVTE)
You can use this routine to clear out memory anywhere in the
Atari. You can also use it to load anyone value into memory by
changing the second zero (after the 169) in line 40 to the value
desired.
Locating your graphics tables at the high end of memory may
cause addressing problems for playfield graphics, or may leave
some of the display unusable and cause PLOT to malfunction. If
you locate your tables just before the screen display, it may be
erased if you change graphics modes. You can look at your
highest RAM use graphics statement and plan accordingly. To
calculate a safe starting address below the display list, try:
100DLIST = PEEK(560) + PEEK(561) * 256: PMBASE =
INT (DLIST/SIZE -1) * SIZE
where SIZE is 2048 for single line resolution, 1024 for double
line.
Once you have the starting address, determine the ending
address of your table by adding the correct number of bytes for
the size (same as the SIZE variable above), and POKE this
number (LSBIMSB) into APPMHI at locations 14 and 15 ($E, $F).
This sets the lower limit for playfield graphics memory use. If you
change graphics modes in the program now, it should leave your
player tables intact. For example, if the DL is at 39968, the
PMBASE will equal 36864 in the equation above. Add 2048
(single line resolution) to get 38912. This is $9800. In decimal,
the LSB is zero and the MSB is 152. POKE these values into
APPMHI. This sets the lowest limit to which the screen and DL
data may descend.
The unused portion of the RAM set aside for PIM use, or any
RAM reserved for players, but not used, may be used for other
purposes in your program such as machine language routines.
See the appendix for a map of P/M memory use. The register
stores the address as below:
Bit 7 6 5 4 3 2 1 0
One line resolution: ..... MSB . . . . . . .. unused ...
Two line resolution: ....... MSB . . . . . . . unused ..
There are some restrictions on locating your P /M data above the
display list. If not positioned far enough above your screen data,
you may end up with both the normal and screen data being
displayed at once, resulting in garbage on the screen. A display
list may not cross a IX boundary without a jump instruction, and
138
54280
139
54283
140
54287
Locations 54784 to 55295 ($D600 to $D7FF) are unused but not empty
nor user alterable. See the note at 53504 ($DI00).
141
55296
142
56713
143
entire character set to use. In GR. 1 and GR.2, you can use only one half
of the set at a time. You can't POKE it with 225 because the number
POKEd must be evenly divisible by two.
The characters stored here aren't in ATASCII order; they have their own
internal order for storage. The order of the characters is listed on page
55 of your BASIC Reference Manual.
Here's an example of how a letter (A) is stored in ROM. Each line
represents a byte. The decimal values are those you'd find if you
PEEKed the eight locations where "A" is stored (starting at 57608;
$E108):
Bit 76543210 Decimal
00000000 0
00011000 24 ##
00111100 60 ####
01100110 102 ## ##
01100110 102 ## ##
01111110 126 ######
01100110 102 ## ##
00000000 0
When you create your own character sets (or alter the Atari set
when you move it to RAM - see location 756; $2F4 for a routine
to do this), you do a "bit-map" for each character as in the
example above. It could as easily be a spaceship, a Hebrew
letter, an APL character, or a face. Chris Crawford's game
Eastern Front 1941 (APX) shows excellent use of an altered
character set to create his large map of Russia, plus the symbols
for the armies.
Here's an example of using the bit-mapping of the character set
to provide text in GRAPHICS 8:
1 GRAPHICS S
5 DLIST = PEEK(560) + PEEK(561)*256
6 LOBYTE = DLIST+4: HIBYTE = DLIST +
5
7 REAL = PEEK(LOBYTE) + PEEK(HIBYTE)
'256: SCREEN = REAL: TV = SCREEN
10 CHBASE = 57344
20 DIM AS(12B),BYTE(12S),WANT(12S)
27 PRINT "INPUT A 40 CHARACTER STRIN
G:"
30 INPUT AS
35 TIME = TIME + 1
40 FOR LOOK = 1 TO LEN (AS)
50 BYTE(LOOK) = ASC(AS(LOOK,LOOK»
144
51 IF BYTE(LOOK) > 127 THEN BYTE(LOO
K) = BYTE(LOOK) - 128
52 IF BYTE(LOOK) < 32 THEN BYTE(LOOK
) = BYTE(LOOK} + 64: SOTO 55
53 IF BYTE(LOOK) < 97 THEN BYTE(LOOK
) = BYTE(LOOK) - 32
55 NEXT LOOK
59 FOR EXTRA = 0 TO 7
60 FOR LOOK = 1 TO LEN (AS)
70 WANT(LOOK) = PEEK(CHBASE + EXTRA
+ BYTE(LOOK)*8)
80 POKE TV + EXTRA, WANT(LOOK): TV =
TV + 1
82 NEXT LOOK
85 SCREEN = SCREEN + 39: TV = SCREEN
90 NEXT EXTRA
100 SCREEN = REAL + TIME*320
110 IF SCREEN > REAL + 6080 THEN TIM
E = 0: SOTO 100
120 SOTO 30
This program simply takes the bytes which represent the letters
you input as A$ and finds their places in the ROM character set.
It then proceeds to POKE the bytes into the screen RAM, using a
FOR-NEXT loop.
To convert ATASCII codes to the internal codes, use this table:
ATASCII value Operation for
internal code
o - 31 add 64
32 - 95 subtract 32
96 -127 remains the same
128-159 add 64
160-223 subtract 32
224-255 remains the same
See COMPUTE!, November 1981, for the program "TextPlot"
which displays text in different sizes in GRAPHICS modes three
to eight, and January 1982 for a program to edit character sets,
"SuperFonL"
Locations 58368 to 58447 ($E400 to $E44F) are the vector tables, stored
as LSB, MSB. These base addresses are used by resident handlers.
Handler vectors use the following format:
OPENvecior
CLOSE vector
145
58368
146
58457
SIO (below) to control the actual peripheral(s). CIO treats all I/O
in the same manner: device independent. The differentiation
between operations is done by the actual device drivers.
You jump to here to use the IOCB handler routines in ROM.
BASIC supports only record I/O or one-byte-at-a-time I/O (GET
and PUT). Addressing CIOV directly will allow the user to input
or output a buffer of characters at a time, such as loading a
machine language program directly into memory from a disk file.
This is considerably faster than using BASIC functions such as
GET. Here is a typical machine language subroutine to do this:
PLA, PLA, PLA, TAX, IMP $E456
(104,104,104,170,76,86,228)
($68,$68,$68,$AA,$4C,$56,$E4)
This gets the IOCB number into the 6502 X register and the
return address on the stack. CIOV expects to find the 10CB
number 16 in the 6502 X register (Le., 10CB zero is zero, 10CB
one is 16; $10, 10CB two is 32, $20, etc.). $E456 is the CIO
initialization entry point (this address).
To use CIOV in a program, first you must have OPENed a
channel for the appropriate actions, POKEd the correct 10CB
(locations 848 to 959; $350 to $3BF) with the correct values, and
established a location in which to load your file (lOCB address
plus four and plus five). One use is calling up a high-res picture
from c'l. disk and storing it in the screen memory (locations 88,89;
$58, $59). You can POKE the appropriate decimal values into
memory and call it with a USR call, or make it into a string
(START$ = "hhh *LVd" where the • and the d are both inverse
characters) and call it by:
JUMP = USR(ADR(START$) )
This method is used to start the concurrent mode in the RS-232 of
the 850 interface in the 850 Interface Manual. See location 88,89
($58, $59) for another example of the machine language routine
'"'""-' technique. Still another use of this method can be found in De He
Atari. Initialized to 58564 ($E4C4).
58457 E459 SIOV
Serial Input/Output (SIO) utility entry point. SIO drives the
serial bus and the peripherals. When a request is placed in the
Device Control Block (DCB) by a device handler, SIO takes
control and uses the data in the DCB to perform the operation
required. SIO takes care of the transfer of data as defined by the
DCB. CIO (above) is responsible for the "packaging" of the data
and transfers control to 510 when necessary. See the DCB
locations 768 to 779 ($300-$30B).
147
58460
148
58484
150
60113
151
62100
152
65528
153
APPENDIX ONE _ _ _ _ _lIIiiIIIiiIIb
VB LANK Processes
The VBLANK routines are all documented in the OS listings, pages 35
to 38. In the "A" ROMs, they are processed in locations 59345 to 59665
($E7Dl to $E911). In the "B" ROMs, they are processed at 59310 to
59628 ($E7 AE to $E8EC). See also De Re Atari for more explanation.
Stage 1 VB LANK:
Performed every VBI:
1) Increment the realtime clock at 18 - 20 ($12-$14)
2) Process the attract mode variables (location 77; $4D)
3) Decrement system timer one at 536 ($218) and if zero JSR through
550 ($226).
Stage 2 VBLANK:
Performed every VBI which does not interrupt critical sections:
1) Update the hardware registers from the shadows as follows:
Shadow: Hardware: Update reason:
SDLISTL/H DLISTL/H DISPLAY LIST END
SDMCTL DMACTL
CHBAS CHBASE
CHACT CHACTL
GPRIOR PRIOR
COLORO-4 COLPFO-4,BAK ATTRACT MODE
PCOLO-3 COLPMO-3
LPCNVIH PENVIH LIGHT PEN
STICKO-l PORTA JOYSTICKS
PTRIGO-3 PORTA PADDLE TRIGGERS
STICK2-3 PORTB
PTRIG4-7 PORTB
PADDLO-7 POTO-7 PADDLES
STRIGO-3 TRIGO-3 JOYSTICK TRIGGERS
CONSOL CONSOLE SPEAKER OFF
2) System timers two to five (locations 540,542,544; $2IC,$2lE,$220)
are decremented and if the value is zero, the corresponding flags
are set. A JSR is made through 552 ($228) if timer two equals zero.
3) A character is read from POKEY keyboard register at 53769
($D209) and read into CH at 764 ($2FC) if the auto-repeat is active.
4) The keyboard deb ounce counter is decremented by one if it is not
zero and if no key is being pressed.
5) Keyboard auto-repeat logic is processed.
6) Exit the VB LANK routine through 58466 ($E462).
154
APPENDIX TWO _1IIIIIIIIiIIIII1IIIIIIIIiIIIII1IIIIIIIIiIIIII_
57344
54784-55295 Unused
54272-54783 ANTIC 756 CHBAS
755 CHI
564-565 LPEN
560-561 SDLSTL
559 SDMCTL
155
APPENDIX TWO
49151 8KBASICROM
or Left cartridge (A)
740 RAMSIZ
Size and
location
vary with
GRAPHICS
mode
Text window screen RAM 60,661 TXTMSC
40800 for GR.O
~
156
APPENDIX TWO
32768
"""'--"
144,145 MEMTOP
Stack for FOR-NEXT & GOSUB 142,143 RUNSTK
14,15 APPMHI
Size and
location
vary with
program
size
String & array table &
end of BASIC program 140,141 STARP
BASIC program
area
157
APPENDIX TWO
5377 VTOCbuffer
DOS initialization 12,13 DOSINI
or BASIC RAM without (743,744 MEMLO)
DOS resident (128,129 LOMEM)
FMSRAM
1792 DUP. SYS beginning
Cassette buffer
Printer buffer
IOCB's
512
511 Stack
256
158
APPENDIX TWO
"'-
128
'"-'.,---"
~'"
0 Bottom of 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.
159
APPENDIX THREE _ __
160
APPENDIX FOUR _ _ _ 111111111111111
161
APPENDIX FOUR
162
-----------------------------------------------~--------------------
APPENDIX FIVE _ _ __
Color
Color is a very important aspect in the Atari computers; you may not
fully appreciate it unless you've spent a long time working with
computers or monitors with monochrome displays. The Atari has
sixteen colors available for display in eight different luminance
(brightness) factors. These colors are stored in memory locations 704
to 712. The first four of these registers are used to determine the color
of your players and missiles. The second five determine the color of the
playfields, background, lines drawn and areas filled.
The Atari has a default value for each of the five playfield registers that
is assigned on powerup:
Playfield Location Color Value
o 108 Orange 40
1 109 Light green 202
2 710 Dark blue 148
3 711 Red 70
4 (BAK) 712 Black o
The figure in the value category represents the number you would get
if you PEEKed into that location. For discussion of the locations, refer
to the Memory Map.
To change these colors, you can use either a POKE statement or the
BASIC command SETCOLOR (abbreviated to SE). You should refer to
the description in the earlier Memory Map text. SETCOLOR has three
parameters: the register to change (which always corresponds to one
of the memory locations above); the hue (a number from zero to fifteen
which corresponds to the available colors); and the luminance (an
even number between zero and fourteen). The Atari will treat any odd
number as if it were the next lowest even number where luminance is
concerned. Your statement might look like this:
SETCOLOR 0,2,8
This will produce the orange color in playfield zero. To change it to
red, you would use:
SETCOLOR 0,4,6
Unless you are changing the background or border or you are
changing a register which has already been used for drawing on the
screen, you won't see any change from using SETCOLOR. The eHect
comes when you follow up with a COLOR command, telling the Atari
which register to use for the DRAWTO or fill command. You can easily
POKE the location with the proper color value by using this formula:
COLOR = HUE * 16 + LUMINANCE
So the orange in the above example would be obtained by:
163
APPENDIX FIVE
POKE 708,40
and the red by:
POKE 708,70
These are the values listed in the chart above. It's quite simple to
change them to your own colors using either method. Of course, you'll
have to adjust your colors every time you change GRAPHICS modes
or press RESET, since both restore the registers to their default values. ........ .r-.•
What's more, the player/missile registers can only be changed using
POKE; they have no corresponding SETCOLOR commands and are
all preset to zero. The winter 81182 edition of The Atari Connection,
the house organ of Atari Inc., had a nice little chart in full color to
display all of the colors available. The SETCOLOR number in the
follOWing list is the value you would place as the second number in the
statement right after the register number.
SETCOLOR POKE
Color number number
Black 0 0
Rust 1 16
Red-orange 2 32
Dark orange 3 48
Red 4 64
Dark lavender 5 80
C~~b~ 6 00
Ultramarine blue 7 112
Medium blue 8 128
Dark blue 9 144
Blue-grey 10 166
Olive green 11 176
Medium green 12 192
Dark green 13 208
Orange-green 14 224
Orange 15 240
The next number in the SET COLOR statement would be the
luminance. You would add the luminance value to the POKE number.
When you want to use the DRAWTO or XIO 18 (FILL) commands, you
must first specify what color register to use by the COLOR command.
The confusing part for most people is that the number in the COLOR
command doesn't correspond to the same number as the SETCOLOR
register and, to make things worse, it's not always the same number in
different GRAPHICS modes! Modes zero, one, and two are text
modes; they print characters to the screen rather than graphics, so you
don't use the COLOR command in these modes. In GR.O, you actually
have only one color as chosen by SETCOLOR 2. The luminance is
164
APPENDIX FIVE
165
APPENDIX FIVE
166
APPENDIX SIX _ _ _ __
167
APPENDIX SIX
40 IF STICK(O) = 14 THEN A = A + 1:
IF A > 255 THEN A = 0: GO TO 20
50 IF STICK(O) = 13 THEN A = A - 1:
IF A < 0 THEN A = 255: GOTO 20
60 IF STICK(O) = 7 THEN B = B + 2:
IF B > 14 THEN B = 0: GO TO 20
70 IF STICK(O} = 11 THEN B = B - 2 :
IF B < 0 THEN B = 14: GOTO 20
80 IF STRIG(O) = 0 THEN C = C + 1:
IF C > 15 THEN C = 0: GOTO 20
90 GOTO 20
You move the stick up or down to change pitch, right or left to change
the distortion level. Press the trigger to change the volume level. See
Softside, #30 for a similar program using all four voices and Santa
Cruz's Tricky Tutorial #6 (sound). You should also examine Atari's
Music Composer cartridge; it is not only a fine program, but it also has
excellent documentation on music, sound, and composition. There are
two excellent programs from APX, Sound Editor and Insomnia, both of
which allow you to create sounds to include in your programs (not
tunes however). Insomnia is particularly interesting in that it creates
sound which is played during the VBLANK intervals.
168
APPENDIX SEVEN _ _ __
169
APPENDIX SEVEN
This map is only eight bits - one byte - wide. You can see that all four
missiles share the same width byte, each using two bits for resolution.
If you combine the missiles to form a fifth player, you use this area
exactly as you would the area for any other player.
One means of moving your players vertically is to move the players
within their reserved area rather than on the screen itself. In BASIC,
this is considerably faster than having to move the player on the
screen, but it's a slow process anyway. As far as the boundaries of the
TV set are concerned, all players in both resolutions are mapped to the
entire height of the screen.
There are many good programs to create and edit PM graphics,
mentioned earlier in the Memory Map text. PM graphics are one of the
Atari's most powerful and least understood capabilities. I suggest you
read up on them and try to master their use; they're not as difficult as
they seem.
170
APPENDIX EIGHT _ _ __
Display Lists
A display list is a short program for the ANTIC chip, telling it how to
display data on the screen. This program includes such instructions as
how many blank lines to place on the screen for top boundaries, where
the screen display data is stored, what mode the line(s) to be displayed
are in, whether or not there is an interrupt to execute and where to find
the display list itself .
._' There are nine pre-programmed displ,ay lists (ten with the GTIA) you
use in BASIC, one for each GRAPHICS mode. You can examine the
display lists for each mode by running the program at location 560.
You can change these lists to suit your own needs without much effort.
It is quite easy to design and implement your own display list once you
know where it's located and what the proper instructions are.
Certain techniques, such as horizontal and vertical fine scrolling,
require that you modify the display list in order to properly display
your screen data. Sometimes you want to be able to display data in
more than one mode or mix graphics and text in the same screen.
These are all done by modifying the display list.
The smallest display list is for GRAPHICS 2, so I'll use it as an
example. It consists of a mere twenty odd bytes, but the format is the
same for every list; it's just the instructions that change. Use the
program listed in the Memory Map to examine the list or use a simple
two-liner such as:
10 GRAPHICS 2: P = PEEK(560) + PEEK
(561) * 256
20 FOR N = 0 TO 23: PRINT PEEK(P +
N} ; II If;: NE X T N
When you RUN this example, you should get this:
112 112 112 71 112 158 7 '7 7 7 7 7 7 7 7 66
96 159 2 2 2 65 88 158
Or something similar depending on your available memory. If you
change the GR.2 to GR.2 + 16, you will get:
112 112 112 71 112 158 7 7 7 7 7 7 7 7 7 7 7
65 92 158
The display list instruction set is discussed at location 560, but here's a
chart to summarize it:
Instruction BASIC Scan Pixels Bytes Comments
Decimal Hex mode lines line line
Blank instructions
o o 1 1 blank line
16 10 2 2 blank lines
32 20 3 3 blank lines
171
APPENDIX EIGHT
~,'
48 30 4 4 blank lines
64 40 5 5 blank lines
80 50 6 6 blank lines
96 60 7 7 blank lines
112 70 8 8 blank lines
Display instructions
2 2 0 8 40 40 text mode 0
3 3 10 40 40 text mode·
4 4 8 40 40 text mode *
5 5 16 40 40 text mode *
6 6 1 8 20 20 text mode 1
7 7 2 16 20 20 text mode 2
8 8 3 8 40 10 graphics mode 3
9 9 4 4 80 10 graphics mode 4
10 A 5 4 80 20 graphics mode 5
11 B 6 2 160 20 graphics mode 6
12 C 1 160 20 graphics mode *
13 D 7 2 160 40 graphics mode 7
14 E 1 160 40 graphics mode *
15 F 8 1 320 40 graphics mode 8
Jump instructions
(three bytes long)
1 1 jump to location
65 41 jump and wait for
VBLANK
Modes marked with an asterisk (*) have no equivalent in BASIC.
These are the instructions in the display list. You can alter the display
instructions by setting the bits for horizontal or vertical scroll, load
memory scan (tells ANTIC where the next line(s) to be displayed are in
memory and what mode to use for them) and enable a display list
interrupt. These are:
Function add
decimal hex bit
Vertical scroll 16 10 4
Horizontal scroll 32 20 5
Load memory scan 64 40 6
Display list interrupt 128 80 1
The LMS instruction is a three-byte instruction; the second and third
bytes are the LSB and MSB of the address where the line or screen data
is to be displayed. You can add any or all of these modifications to the
text or graphics mode instructions. You can only add the interrupt
modification to blank line or jump instructions. The two bytes that
follow the jump instructions are the LSB and MSB of the address to
which the ANTIC jumps to continue or repeat the list.
172
APPENDIX EIGHT
173
APPENDIX EIGHT
8 8 3 2 graphics modes
9 9 4 1
10 A 5 2
11 B 6 1
12 C 1
13 D 7 2
14 E 2
15 F 8 1
You can have as many DL's as you wish, using the jump/vertical blank
instruction at the end of the DL to tell ANTIC where your new DL is
located. When placing your new DL (page six, unless used for other
routines, is a good protected place to put it), do a POKE 559,0 to
disable the DL fetch instructions, then POKE it with the proper value to
turn it back on afterwards. Be inventive and create your own screens
with varied lines of text and graphics.
I suggest that you read De Re Atari and Your Atari 4001800 for more
information. The latter has a few good examples of altered display lists
and tells how to create them. Two DL utilities are The Next Step from
Online and Tricky Tutorial #1 from Santa Cruz.
174
APPENDIX NINE _ _ __
Numerical Conversions
If you use this map a lot, or use the Atari a lot for machine language
routines, interrupts, graphics and the like, you know the need to
translate between decimal and hexadecimal, even back and forth with
binary, frequently. It is possible, although tedious, to do your
translations by hand, using pencil and paper. The tables for doing so
are below. It's not the best nor the fastest method available. I
recommend you get the Texas Instruments TI Programmer calculator.
It does most of this work for you, plus bit manipulation (unfortunately it
does not offer binary translation). It's an indispensable tool for
programmers.
There are other ways around buying the calculator: you can buy
Monkey Wrench from Eastern House Software, which will do the hex-
decimal translations for you quite nicely. Or you can buy any of the
numerous disk or programming utilities which include such translation
routines, such as Disk Scan from Micro Media. However, those who
wish to do the work themselves can use a simple translator program.
One such example, modified from routines that appeared separately in
COMPUTE!, November 1981 and March 1982, is:
10 DIM HEX$(16),DEC$(23),NUM$(10),W$(
4),BIN$(8),BNY$(8),TRANS(8)
15 DATA 128,64,32,16,8,4,2,1
20 FOR N=1 TO 8:READ B:TRANS(N)=B:NEX
T N:POKE 201,14
25 PRINT CHR$(125)
30 HEX$="0123456789ABCDEF":DEC$="@ABC
DEFGHI!! ~!!! !JKLMNO"
40 ?:? PRESS [11:.;1.(1]: FOR HE XADEC I MAL
II II :
42 ?"{6 SPACES}TRANSLATIONS":A=I:MAX=
4096
50 IF PEEK(53279)=3 THEN SOTO 100
60 IF PEEK(53279)=5 THEN GOTO 200
70 IF PEEK(53279)=6 THEN SO TO 300
80 GOTO 50
100 ? : ?"ENTER HEXADECIMAL NUMBER":~
H$OOOO TO SFFFF": INPUT NUM$:ACC=
O:A=I:TRAP 100
120 FOR NUM=1 TO LENCNUM$):ACC=ACCt16
+ASC(DEC${ASC(NUM$(NUM»-47})-64:
NEXT NUM:T=ACC
175
APPENDIX NINE
176
APPENDIX NINE
-MAX*BYTE:MAX=MAX/16:NEXT L
340 ?:?"BINARY","HEXADECIMAL","DECIMA
LII
350 ? II II;BIN$,W$,Q
390 GOTO 40
This program will translate any hexadecimal, decimal, and binary
number to and from the others. There are some constraints in its use: it
will not translate a binary number for any hex number larger than $FF
or decimal number larger than 255. It will not translate any hex
number larger than $FFFF or any decimal number larger than 65535.
Since about 99% of your numeric manipulations will be within these
ranges, you should have no problems. You can easily remove the
translation routines from the program for use in your own utility.
For a quick way to translate any number in the range of zero to 65535
($FFFF), use the table below. It's quite simple to use: to translate hex to
decimal you take the number that appears in the column that
corresponds to the value in the proper row and add the values
together. The total is your decimal number. For example:
$7AC1 = 28672 fourth column, 7
2560 third column, A
192 second column, C
1 first column, 1
31425 decimal value
To translate decimal into hex, you find the largest number less than the
number you wish to translate and subtract it from your original
number. The value in the row is the first hexadecimal value. You then
do the same with the remainder until your result is zero. The values in
the row are then concatenated together for a hexadecimal number. For
example:
31425 = 31425
- 28672 largest number, column four. first hex number = 7
2753 remainder, minus third column
2560 second hex number = A
193 remainder, minus second column
192 third hex number = C
1 remainder and fourth hex number
Hexadecimal value = $7ACI
Hex Column Hex
number fourth third second first number
1 4096 256 16 1 1
2 8192 512 32 2 2
3 12288 768 48 3 3
177
APPENDIX NINE
4 16384 1024 64 4 4
5 20480 1280 80 5 5
6 24576 1536 96 6 6
7 28672 1792 112 7 7
8 32768 2048 128 8 8
9 36864 2304 144 9 9
A 40960 2560 160 10 A
B 45056 2816 176 11 B
C 49152 3072 192 12 C
D 53248 3328 208 13 D
E 57344 3584 224 14 E
F 61440 3840 240 15 F
The next few pages are simply a listing of the decimat hex,and binary
values for the range of numbers between zero and 255. I have found
this listing to be extremely useful when I couldn't enter a translator
program or lay my hands on a calculator. Read the note in the
introduction regarding the translation techniques for binary and
hexadecimal.
178
APPENDIX NINE
179
PEND
180
APPENDIX TEN
Inverse characters are the same as the characters above with 128
added to the values listed. This is done by setting the seventh bit
(adding 128).
There are other codes used which are outside this range:
ATASCII Function
155 End Of Line (Return)
156 Delete line
157 Insert line
158 CTRL - Tab
159 Shift - Tab
253 CTRL - 2 (buzzer)
254 Delete character
255 Insert character
See your Atari Reference Manual, pages C1 to C3 and Fl. In order
to print the arrow keys, clear, insert, delete, buzzer, escape key, or
any of the codes listed above to the screen, you must press the
ESC key before entering the keyboard character(s),
Not all of these codes can be sent to the printer. ATASCII codes
zero to 31 print blank or they may send control codes to your
printer, depending on the make. 96 will print a backwards
apostrophe instead of a diamond, 123 will print a left bracket
instead of a spade, 125 will print a right bracket instead of a clear,
126 will print a tildis instead of a backspace and 127 will print a
blank instead of tab.
There is a third set of codes used by the Atari keyboard handler.
These values are listed in the OS User's Manual.
181
APPENDIX ELEVEN _ __
182
APPENDIX ELEVEN
66 42 CRITIC
POKE 66.1 to disable the update between shadow and hard-
ware registers; then you can POKE directly into the hardware
registers themselves. You can disable VBLANK at 54286 (SD40E)
as well.
67-73 43-49 FMZSPG
Reinitialized by FMS each time it takes control.
82,83 52,53 LMARGN and RMARGN
Both have a range of 0 to 39.
85,86 55,56 COLCRS
Has a range of 0 to 319.
87 57 DINDEX
To turn off the cursor when drawing in a text mode. POKE 752.1,
followed by a PRINT statement. To get different colors. add a
COLOR statement before the PLOT routine. The character will
be the ASCII equivalent of the number which follows COLOR.
88,89 58,59 SAVMSC
The program to save the graphics screen doesn't work. To save
your graphics screen. create a string to hold a machine lan-
guage call routine:
1 DATA 104,104,104,170,76,86,228
2 REM PLA. PLA, PLA. TAX, JMP $E456
5 FOR N=l TO 7:READ BYTE:ML$(N,N)=CHR$(BYTE
):NEXT N
183
APPENDIX ELEVEN
To recall the screen, use the same USR routine and the above
PEEKs and POKEs, but POKE 898,7 rather than 11. This was de-
rived from a larger program by Fred Pinto in the March 1984 is-
sue of Antic. An article by Steve Kaufman in COMPUTE!,
November 1983, has a fast and dirty method which works just
as well (save and load), but doesn't save the color registers.
Creative Computing, November 1983, also had a similar ex-
ample in "Outpost Atari."
106 6A RAMTOP
See K. W. Harm's article on the "RAMTOP Dragon" in COM-
PUTEJ's Second Book of Atari Graphics to see how to protect
high memory; another article in the same book, by Jim Clark,
describes how to protect low memory.
118 76 DELTAR
This is the change of vertical position when drawing a sloped
line.
121 79 ROWINC
Direction of line draw: 0 is down, 255 is up.
122 7A COLINC
Direction of draw: 0 is right 255 is left.
126, 127 7E,7F COUNTR
Iterations or steps required to draw a line.
132,133 84,85 VNTD
COMPUTE!, October 1983, has an article by E. H. Foerster on
how to reserve a portion of RAM above VNTD-within a BASIC
program-which will also be saved intact when you save the
program.
138,139 8A,8B STMCUR
Another way to lock up the system if something is done-say,
BREAK pressed-is by Z=USR(O).
146 92 MEOLFLG
BASIC's modified EOL flag register. The Atari BASIC Sourcebook
lists all the RAM locations used by BASIC (pages 144-147).
147 93
Spare.
149,150 95,96 POKADR
Address (LSB/MSB) of last POKE location. If no POKE command
was given, it is the address of the last OPERATOR token (often
155 for EOL).
184
APPENDIX ELEVEN
182 B6 DATAD
The data element being read, Registers the number of the ele-
ment in that line, say the tenth item in a DATA statement.
183,184 B7,B8 DATALN
DATA statement line number; the BASIC line number of a DATA
statement being currently read, The RESTORE statement sets the
locations (and 182, above) back to zero, You can do the same
with a POKE, Here's a program which demonstrates these loca-
tions from Steve Rockower, Atari SIG, CompuServe,
1. REM DEMONSTRATES 182- 184($B6-$B8) AS SU
BSTITUTES FOR RESTORE
2. REM 182 '.B6) POINTS TO ITEM OF A LINE T
o BE READ NEXT
3. REM DATA STATEMENTS HAVE ELEMENT NAME SE
QUENTIALLV AND
4. REM NUMBER IN CURRENT LINE
S. DIM C.(2).A.(2.).C$-CHR.(125)
1 •• DATA ONE-l,TWO-2.THREE-3.FOUR-4,.
11. DATA FIVE-1.SIX-2,SEVEN-3,EIBHT-4 ••
12. DATA <9-1>,<1.-2>.<11-3>,<12-4>,1
IS. PRINT CS.RESTORE 1 • •
16. READ A•• IF A$-".· THEN 2 ••
17. IF PEEK(182)-1 THEN PRINT .PRINT "READI
NG LINEs ".PEEK(183)+2S6.PEEK(184)
18. IF A._nl" THEN 3 ••
19. PRINT "."gPEEK(182)," "gA$."(3 SPACES)"
•• GOTO 16.
2 •• PRINT IGOTO 16.
3 •• PRINT .PRINT
31. TRAP 4 ••• PRINT "WHICH DATA LINE (1.2. 0
R 3)"8.INPUT DATALINE
32. PRINT "WHICH ITEM (1,2.3, DR 4)",.INPUT
ITEM
33. LET DATALINE-9.+1 •• DATALINE
34. POKE 184,INT(DATALINE/2S6).POKE 183.DAT
ALINE-INTCDATALINE/2S6)
3S. POKE 182.ITEM-l
36. READ A$.PRINT AG
37. BOTO 31.
4.. END
190 BE SAVCUR
Saves current line address,
192 CO IOCMD
"--- I/O command,
193 Cl IODVC
I/O device,
185
~--'
APPENDIX ELEVEN
194 C2 PROMPT
Prompt character.
200 C8 COLOR
Stores the COLOR number used in a PLOT or DRAWTO statement.
The statement COLOR x can be replaced by POKE 200, x. Same
as location 763 (S2FB), but BASIC takes the value from 200 and
loads it into 763 before drawing or filling. From Judson Pewther,
New York.
202 CA LOADFLG
Load in progress flag.
210,211 D2,D3
BASIC floating-point work area. SD2 is used for the variable
type, SD3 for the variable number and length of the FP
mantissa.
212,213 04,05 FRO
Used by the USR command to return a two-byte number to
BASIC. If you store nothing here, then the equation
"I=USR(address, variables)" returns the address of the USR sub-
routine. Otherwise, you can store an integer (rang'e 0-65535)
here which becomes the value of the USR function. From Judson
Pewther, New York.
522,523 20A,20B VSERIN
Serial input ready vector.
524,525 20C, 200 VSEROR
Serial output ready vector.
528-533 210-215 POKEY timers
In "From Here to Atari" in Micro, June and December 1983,
Paul Swanson explained how POKEY timers work-properly.
The manuals have an inaccurate description that causes your
system to lock up. The method below is taken from those issues.
This is described for channell; it can be used in channels 2
and 4 (not 3) by selecting the appropriate control and interrupt
vectors. First, POKE AUDCTL (53768; $D208) with a frequency
value (0 = 64 kilohertz, 1= 15 kilohertz, 96 = 1.79 megahertz).
(You can actually change frequency between interrupts it you
wish.) Next. set the channel control register (53761; SD201). Enter
your interrupt routine and POKE its address into 528, 529 ($210,
--'
5211 ).
186
APPENDIX ELEVEN
After this is done, POKE 53769,0 ($D209). Now enable the inter-
rupt: POKE 16 with PEEK(l6) plus the number of the interrupt
you're using (l = timer 1 interrupt 2 = timer 2, 4 = timer 4-
there's no timer 3!). POKE the same value into 53774. Your inter-
rupt routine will begin; it will generate an interrupt when the
timer counts down to zero. The timer is reloaded with the orig-
inal value you POKEd there, and the process begins all over
again.
There are several problems to watch for: First the OS pushes
the A register onto the stack before jumping through the vector
address. If you need the X and Y registers, push them on as
well. Before you return from the interrupt pull the X and Y back
oft PLA, and clear the interrupt with CLI.
If you don't need the screen display, POKE 559,0 to turn it off;
DMA steals clock cycles from the timer. This means you'll have
to make any commands which deal with shadow registers (like
SETCOLOR and GRAPHICS) first. DMA also turns off the keyboard
repeat and realtime clock. Disable the keyboard to gain a bit
more time if necessary.
Refer to Micro and ROM, December 1984, for more information
about POKEY timers.
555 228 SRTIMR
Each time you read this location, you get a different number.
That's because it's counting down from when a key is de-
pressed to time the delay before repeating the key.
187
APPENDIX ELEVEN
188
APPENDIX ELEVEN
764 2FC CH
In COMPUTEt's Third Book of Atari, Orson Scott Card explained
the keyboard and how to read it using the CH register.
The values listed as "internal code" in Appendix 10 are not the
same as those produced at 764. The internal code is the order
the characters are stored in the character set. The keycode re-
llected by 764 is the hardware code, which is altogether dif-
ferent for no reason I've been able to ascertain.
768-779 300-30B Page three device
Information
Here are some brief examples showing how to use these loca-
tions with the disk drive (it already has a handler in place, and
we don't have to write a new one). The CIO call routine can be
used in all your disk I/O routines based around these locations.
To check if a sector has data in it:
5 DIM SECS(128),CHKS(128)
10 DATA 104,32,83,228,96
15 SEC$(I)=CHRS(0):SECS(128)=SECS:SECS(2)=S
ECS:CHKS(1)=CHR$(0):CHK$(128)=CHK$:CHK$(
2)=CHK$
16 REM SETS UP ARRAY SPACE AND FILLS IT
17 REM CHK$ IS FULL OF BLANK SPACES - CONTE
NTS OF UNUSED SECTORS
20 FOR N=1536 TO 1540:READ X:POKE N,X:NEXT
N
25 REM THIS POKES THE CIO CALL UP ROUTINE I
NTO PASE SIX
30 POKE 769,l:POKE 770,82
35 REM THIS POKES THE DRIVE NUMBER (1) AND
READ FUNCTION (82)
40 PRINT "ENTER A SECTOR NUMBER TO CHECK":I
NPUT SNUM
45 IF SNUM<0 OR SNUM>720 THEN 40:REM VALIDI
TY CHECK ON NUMBERS
50 POKE 778,SNUM-(INT(SNUM/256)*256):POKE 7
79.INT(SNUM/256)
51 REM POKES LSB, MSB OF SECTOR INTO 778, 7
79
55 BUFFER=ADR(SECS):BUFFL=BUFFER-(INT(BUFFE
R/2S6)*2S6):BUFFH=INT(BUFFER/256)
56 POKE 772,BUFFL:POKE 773,BUFFH
57 REM POKE ADDRESS OF SECS INTO BUFFER ADD
RESS
60 Z-USR(1536):REM CALL UP CIO ROUTINE
70 IF SEC$=CHK$ THEN PRINT "NO DATA IN SECT
OR"ISOTO 40
B0 PRINT "SECTOR HAS DATA"ISOTO 40
189
APPENDIX ELEVEN
190
APPENDIX ELEVEN
1 DIM SEC$(128),Z$(1)
2 REM SPACE FOR SECTOR DATA
5 DATA 1~4.32.83.228.96
1~ FOR N=1536 TO 154~=READ X:POKE N,X:NEXT
N
15 REM POKE CIO CALL DATA INTO PAGE SIX
2~ PRINT "WHAT SECTOR TO COPY FROM?"
25 INPUT START:IF START<~ OR START>72~ THEN
25
3~ PRINT "WHAT SECTOR TO COpy TO?"
35 INPUT FINISH:IF FINISH<~ OR FINISH>72~ 0
R FINISH=START THEN 35
4~ POKE 77~.82:REM READ COMMAND
45 POKE 778,START-(INT(START/256)*256):POKE
779,INT(START/256)
46 REM POKE LSB/MSB OF SECTOR TO COPY
5~ LOC=ADR(SEC$):POKE 772,LOC-(INT(LOC/256)
*256):POKE 773,INT(LOC/256)
55 REM POKE LSB/MSB OF ADDRESS OF DATA (SEC
S) INTO BUFFER ADDRESS
6~ A=USR(1536):REM READ SECTOR INTO SECS
7~ PRINT "PRESS RETURN TO WRITE SECTOR":INP
UT ZS
8~ POKE 77~.87:REM WRITE COMMAND
85 POKE 778,FINISH-(INT(FINISH/256)*256):PO
KE 779,INT(FINISH/256)
86 REM POKE LSB/MSB OF SECTOR TO COPY TO
9~ A=USR(1536):REM WRITE IT
lli1lt1 GOTO 2~
191
APPENDIX ELEVEN
192
APPENDIX ELEVEN
Byte Use
125 Leftmost six bits: file number (0-63, $3F);
rightmost two bits: next sector number (high two
bits)
126 Next sector number (low eight bits of the sector
"----. number)
127 Number of bytes used in this sector (0-125, $7D)
The next sector to read is in a ten-bit number: eight bits from
byte 126 (S7E) and the two low bits of 125 (S7D). This means the
six leftmost bits remaining in byte 125 can be used only to count
up to 63 (which with zero makes for 64 filenames in one direc-
tory). This is true when reading linked files, such as BASIC pro-
grams or text files; auto-boot programs are usually sequential
and are not linked in this manner (nor are the first four boot
sectors, the VTOC, or directory sectors). When the next sector
number is zero, there are no more sectors to read.
A binary file always begins with 255 (SFF) twice, then four
bytes: the LSB and MSB of the start and end addresses, respec-
tively, of the data to follow (that is, if they were 00 AD 00 BO, it
would start at SAOOO and end at SBOOO). When a number of
bytes are loaded to fulfill the load vector, DOS assumes the next
four bytes are more start/end address vectors and will continue
to input the following data at the new address unless an EOF
(End Of File) is reached. Control is passed back to DOS at the
end of a load unless you put a new run address into 736,737
(S2EO, S2El). You can append a code like EO 02 El 0200 AD to
your binary file (four address bytes, followed by the appro-
priate data-two bytes to fill the two locations specified), which
in this case makes the new run address SAOOO. See COMPUTE!,
March 1982.
1801 709 SABYTE
Can be set greater than 7, but it only wastes memory space.
1923 783
Stores the drive number for the DUP.SYS file. If you POKE here
with the ASCII equivalent of the drive number (for example,
POKE 1923, 50 for drive 2), when you call DOS from BASIC,
DUP.SYS will be loaded from the drive specified rather than the
default Dl:. To make a permanent change to your DOS, POKE
the appropriate number, go to DOS, and write DOS files to a
disk.
193
APPENDIX ELEVEN
3118 C2E
POKE with a to change only the first of matching filenames in
case of duplication error in your directory (normally, Rename
changes all files of the same name). POKE with 184 ($B8) to re-
store. From the aSIA + manual.
3460 D84
Deallocation bytes of the VTOC and directory; see the next few
locations.
4226 1082
LSB of the current directory sector (first of eight reserved sec-
tors). The directory is normally located in sectors 361-368. The
default number here is 105 ($69).
4229 1085
MSB of current directory sector. To change the location of the
directory, first copy the current sectors to the desired location
(see 768 above), then POKE the new location of the first sector
into the LSB/MSB bytes. That and the next seven sectors will be
recognized as the new directory area. Finally, write the number
for the new start sector (sector number/8 + 10) into 3460 ($D84).
Leave BASIC and rewrite DOS onto a newly formatted disk. DOS
disks with the original directory locations cannot read your
directory.
Disk Directories
Format of a directory entry:
Byte Use
o Flag:
$00 entry new (never used)
$01 file opened for I/O
$02 file created by DOS 2
$20 file locked
$40 file in use (normal)
$80 file deleted '-~.
1-2 Number of sectors in the file
3-4 Starting sector number (LSB/MSB)
5-12 Filename (space or $20 if blank)
13-15 Extension
4264 IOA8
LSB 01 the current VTOC (Volume Table Of Contents-only one
sector reserved).
194
APPENDIX ELEVEN
4266 lOAA
MSB of the VTOe sector, normally sector 360. The VTOe is a bit-
map of the disk contents; after the initial status bytes, each of
the following bits represents one sector on the disk in sequential
-, order. There are 720 sectors, but sector 0 cannot be accessed
by the OS. Sectors 1-4 are reserved as "boot" sectors on a DOS
disk, sectors 360-368 are reserved for the VTOe and directory
leaving 707 free for files. You can move the VTOe the same
,.,.... , . /
way you move the directory.
It you change the directory location (make sure there's nothing
in the new directory location that you don't mind erasing first),
go into the VTOe and deallocate the original directory sectors
(write a one into the bits) and write a zero into the bits
representing the new location-this prevents them from being
overwritten. You can also lock out sectors by deallocating them
in the VTOe.
Volu.me Table of Contents
Byte Use
o DOS code (0 = DOS 2.0)
1-2 Total number of sectors (707; $2C3)
3-4 Number of currently unused sectors
5 Reserved (unused at present)
6-9 Unused
10-99 Bitmap: one bit for each sector (O=in use-
locked; 1 =unused-free). The leftmost bit of
byte 10 ($OA) is sector 0 (see above). the next bit
to the right is sector 1. and so on. until the
rightmost bit of byte 99 ($63). which is sector 719
($2CF).
100-127 Unused
There are only 707 sectors counted in bytes land 2 (not 720),
since the first 4 are "boot" sectors; then the VTOe and directory
take another 9, for a total of 13.
A typical DOS 2.0 VToe with DOS.SYS and DUP.SYS, but nothing
else except the boot, VTOe, and directory sectors in use; it looks
like this:
Byte
o 02 C3 02 50 02 00 00 00
8 00 00 00 00 00 00 00 00
16 00 00 00 00 00 00 00 00
24 01 FF FF FF FF FF FF FF
32 FF FF FF FF FF FF FF FF
40 FF FF FF FF FF FF FF FF
195
APPENDIX ELEVEN
48 FF FF FF FF FF FF FF 00
56 7F FF FF FF FF FF FF FF
64 FF FF FF FF FF FF FF FF
72 FF FF FF FF FF FF FF FF
80 FF FF FF FF FF FF FF FF
88 FF FF FF FF FF FF FF FF
96 FF FF 00 00
FF FF 00 00
104 00 00 00 00 00 00 00 00
112 00 00 00 00 00 00 00 00
120 00 00 00 00 00 00 00 00
The VTOC is the leftmost bit of byte 55 ($37), and the directory
sectors are the remainder of the byte plus the leftmost bit of
byte 56 ($38). The leftmost four bits of byte 10 ($OA) are the boot
sectors, and the remainder of the bytes up to and including the
leftmost seven bits of byte 24 ($ 18) are in use by DOS and DUP.
Remember that the last three bytes in the VTOC and directory
are not status bytes.
Disk directories and the VTOC (as well as many other disk mys-
teries and delights) are explained in detail in Bill Wilkinson's
Inside Atari DOS from COMPUTE! Books, and are somewhat dis-
cussed in Atari Software Protection Techniques by George Mor-
rison (Alpha Systems, 1983).
4856 12F8
Should read drive type, not tape.
5446,5450 1546,154A ....
LSB and MSB of the address the warm start routine places in 10
and 11 (DOSVEC). POKE your RESET handler routine address
here to always load it back into DOSVEC when RESET is
pressed. Point to 6047 ($ l79F); a USR call to 6047 loads DUP and
sends you to the DOS menu.
5576 15C8
You can run some machine language programs from within
BASIC by typing OPEN' #1,4,0, "D:filename" then
X=U51(5576). CLOSE the channel afterward if you return to
BASIC.
40960 AOOO
A USR here will cold start the BASIC cartridge. If you're handy
with machine code, you can add commands to BASIC by trap-
ping the keystrokes before they get passed on to the editor.
Charles Brannon describes how to do this (with a good pro-
gram of commands) in COMPUTEl's Third Book of Atari.
196
'-
APPENDIX ELEVEN
':>
Handler OPEN CLOSE GET PUT Status Special JMP
K: E420 E422 E424 E426 E428 E42A E42C
58400 58402 58404 58406 58408 58410 58412 ~-
/ . 2 3 4 5 6 7 8 9 10 II 12 '3 \
198
APPENDIX ELEVEN
59280,81 E790,91 ?
Seems to be the same DLI vector address as 512-513.
199
APPENDIX TWELVE _ __
""'.' .
200
APPENDIX TWELVE
Deleted Registers
The following registers have been completely deleted from the
XL/XE, and other uses have been found for the location (previous
400/800 locations given):
PTEMP (31; $IF)
LINBUF (583-622; $247-$26E)
CSTAT (648; $288)
TMPXl (668; $29C)
HOLD5 (701; $2BD)
ADDCOR (782; $30E).
00 00 LNFLG
Used by the Atari in-house debugging programs and OS on
power-up.
en 01 NGFLAG
Used during power-up routines for self-testing; checks for bad
memory bytes; zero means memory failure.
07 07 CMCMD
Command flag for 835 and 1030 modems; set to any nonzero
number to pass commands to the modem. Used to be TSTDAT.
10,11 A,B DOSVEC
Points to 6047 ($ 179F).
12,13 C,D DOSINI
Points to 5440 ($1540).
28-31 IC-IF ABUFPT
Intended OS use as buffer pointers; currently unused.
201
APPENDIX TWELVE
202
APPENDIX TWELVE
......"'''''''"'''
203
APPENDIX TWELVE
204
APPENDIX TWELVE
205
APPENDIX TWELVE
206
APPENDIX TWELVE
207
APPENDIX TWELVE
208 ',--
APPENDIX TWELVE
209
APPENDIX TWELVE
210
APPENDIX TWELVE
211
APPENDIX TWELVE
Better yet. get DOS 2.5 from Atari (supports double-density and
the 130XE RAMdisk). DOS 3.0 saves in blocks. not sectors-of a
minimum 1000 bytes per block. If you write a program 1001
bytes long. it saves 2000 bytes, wasting 999 bytes on your disk.
20480-22527 $5000-$57FF Self·test ROM
Self-test ROM when enabled. controlled by bit 7 of PORTB
(54017; $D301). The self-test code is in a special ROM area
underneath the GTIA. POKEY. ANTIC chips area (starting at
53248; $D3000) and is moved (remapped) here when you type
BYE in BASIC or when you POKE PORTB with the right value and
JMP (or USR) to the initialization vector (see 58481; $E471 and
58496-58499, $E480-$E483). RAM when self-test isn't enabled.
39967-409599CIF-9FFF ....
Display list and screen RAM. moved into lower memory if a
cartridge is 16K (using RAM from 32767 to 49151 as well).
43234 A8E2 BASIC ROM
If you PEEK here and get 96 ($60), you have the BASIC Revision
B ROMs. What you need is Revision C. B stands for Bugs! See
Appendix 13 on enhancements and bugs. If you get 234 ($EA).
you have Revision C. From Matt Ratcliff.
You can turn BASIC off when you go to DOS by POKEing 1016
($3F8), then pressing RESET. The problem is to turn it back on
again from DOS rather than rebooting the system. There is a
public domain program by Matt Ratcliff on the Gateway BBS
which does this for you.
213
APPENDIX TWELVE
214
APPENDIX TWELVE
215
APPENDIX TWELVE
216
APPENDIX TWELVE
By Joe Miller.
217
APPENDIX TWELVE
218
APPENDIX TWELVE
219
APPENDIX TWELVE
This also means that the area from 49152 to 52991 (SCOOO to
SCEFF) isn't used-almost 4K of free RAM for player missiles,
machine language routines, anything you need it for. Be care-
ful not to run over into the interrupt handlers at 52992 (SCFOO).
54019 DlOl PBCTL
The PORT B controller on the 400/800; not used since there isn't
one on the XL/XE series.
54528-5478l DSOO-DSFF ....
Unused in both XL and 400/800 models. Any access read or
write to this area enables the cartridge control line CCNTL as in
the cartridge interface in the 400/800.
5S296-S7l4lD800-DFFFFP
Floating-paint package; although corrected, the entry point re-
mains the same as in the 400/800. You now get an error if you
try to get a LOG or LOGlO of O. This area becomes addressable
by the device when the OS switches out ROM to perform I/O on
a device connected to the expansion slot.
There are several tables built into the FP package:
Address Table
56909/DE4D Power of 10 coefficients
57202/DF72 Logarithm coefficients
57262/DFAE Arctangent coefficients (unused?)
The OS switches the floating point out and switches in the par-
allel bus interface (PBI) ROM when an external device attached
through the bus is selected, switching it back when the I/O is
completed. This means an external device can't use floating
point or any software which does (such as BASIC).
The first 26 bytes of the hardware ROM vector area (when OS
ROM is deselected) are:
Byte Hex Use
55296/55297 0800/0801 ROM checksum LSB/MSB
(optional)
55298 0802 ROM revision number
(optional)
55299 0803 In number (12S; $SO)
55300 0804 Device type (optional)
55301 0805 JMP instruction ($4C)
55302/55303 D806/D807 I/O vector LSB/MSB
55304 D80S JMP
55305/55306 DS09/DSOA Interrupt vector LSB/MSB
55307 DaOB 10 number (145; $91)
220
APPENDIX TWELVE
221
APPENDIX TWELVE
222
APPENDIX TWELVE
223
APPENDIX TWELVE
Address Routine
59193/E739 Initialization
59326/E7BE Perform poll
59358/E7DE Load handler
59414/E816 Get byte routine
59443/E833 Get next load block
59485/E85D Search handler chain
59540/E894 Handler warm start initialization
59544/E898 Warm start initialization with chaining
59550/E89E Cold start initialization
59584/E8CO Initialize handler and update MEMLO
59648/E900 Initialize handler
59669/E915 Handler unlinking
224
APPENDIX TWELVE
225
APPENDIX TWELVE
226
APPENDIX TWELVE
Address Routine
62986/F60A Advance cursor routines
63073/F661 Return with scrolling
63077/F665 Return
63l50/F6AE Subtract end point
63164/F6BC Check cursor range routines
63256/F718 Restore old data under cursor
63267 F723 BMI
Bitmap routines for the editor and screen handler.
63479 F7F7 SCR
Screen scroll routines.
63665 FIBl CBC
Buffer count computation routines; various keyboard, editor,
and screen follow, including:
Address Routine
63768/F918 Delete line
63804/F93C Check for control character
63820/F94C Save row and column values
63831/F957 Restore row and column
63842/F962 Swap cursor with regular cursor position
63875/F983 Sound key click
63895/F997 Set cursor at left edge
639l0/F9A6 Set memory scan counter address
63919/F9AF Perform screen SPECIAL command
64337 FB5l
Start of the 192-byte keyboard definition table; see location 121.
122 (579, 57A).
227
-'
APPENDIX TWELVE
228
APPENDIX TWELVE
229
APPENDIX THIRTEEN _ _
230
APPENDIX THIRTEEN
231
APPENDIX FOURTEEN
--'" ..--
232
APPENDIX FOURTEEN
TOP
1 3 5 7 9 11 13 15 17 1921 2325272931333537394143454749
2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50
BOTTOM
233
APPENDIX FOURTEEN
A B C D E F H J K L M N P R 5
• • • • • • • • • • • • • • •
• • • • • • • • • • • • • • •
1 2 3 4 S 6 7 8 9 10 11 12 13 14 IS
1. 54 A. RD4
2. A3 B. GND
3. A2 C. A4
4. Al D. AS
S. AO E. A6
6. D4 F. A7
7. DS H. A9
8. D2 J. A9
9. Dl K. A12
10. DO L. D3
11. D6 M.D7
12.5S N. All
13. +5v P. AIO
14. RD5 R. RjW
IS. CCTL S. B02
234
APPENDIX FOURTEEN
It-pin extension
Top side
Pin Place Description
Res A Reserved
IRQ B Interrupt request line
HALT C ANTIC halt signal
_1 A13-15 D-F Upper three address lines
GND H Ground
Bottom side
Pin Place Description
EXSEL 1 External device select ?
RST 2 System RESET
Dlxx 3 Chip select at area $Dlxx
MPD 4 Math pack (FP) disable
AUDIO 5 External audio input
REF 6 Present cycle is a refresh cycle line
+5v 7 Second dc power supply
Looking at the extension from the back, we see:
A B C D E F H
• • • • • • •
• • • • • • •
1 2 3 4 5 6 7
A. Reserved 1. EXSEL
B. IRQ 2. RST
C. HALT 3. DIXX
D. A13 4. MPD
E. A14 5. Audio
-' F. Al5
H. GND
6. REF
7. +5v
Alari 65XE
There is no parallel bus on the 65XE; it was dropped by Atari since
third-party manufacturers had not taken advantage of it.
235
APPENDIX FIFTEEN _ __
236
APPENDIX FIFTEEN
Composite video
Ground
237
APPENDIX SIXTEEN _ __
238
APPENDIX SIXTEEN
the access to the second bank is enabled. Here are the possible bit
configurations eMstands for main bank, E for extended or secondary
bank):
CompatlblUty mode (only main bank enabled)
Bit 5 Bit 4 Bit 3 Bit 2 CPU accesses: ANTIC accesses:
VBE CPE Bank selection
1 1 doesn't matter M $4000-$7FFF M $4000-$7FFF
CPU extended RAM mode
Bit 5 Bit 4 Bit 3 Bit 2 CPU accesses: ANTIC accesses:
VBE CPE Bank selection
1 0 0 0 E $OOOO-$3FFF M $4000-$ 7FFF
1 0 0 1 E $4000-$7FFF M $4000-$7FFF
1 0 1 0 E $8000-$BFFF M $4000-$7FFF
1 0 1 1 E $COOO-$FFFF M $4000-$7FFF
Video (ANTIC) extended RAM mode
Bit 5 Bit 4 Bit 3 Bit 2 CPU accesses: ANTIC accesses:
VBE CPE Bank selection
o 1 0 0 M $4000-$7FFF E $OOOO-$3FFF
o 1 0 1 M $4000-$7FFF E $4000-$7FFF
011 0 M $4000-$7FFF E $8000-$BFFF
o 1 1 1 M $4000-$7FFF E $COOO-$FFFF
General extended RAM Mode
Bit 5 Bit 4 Bit 3 Bit 2 CPU accesses: ANTIC accesses:
VBE CPE Bank selection
o 0 0 0 E $OOOO-$3FFF E $OOOO-$3FFF
o 0 0 1 E $4000-$7FFF E $4000-$7FFF
001 0 E $8000-$BFFF E $8000-$BFFF
o 0 1 1 E $COOO-$FFFF E $COOO-$FFFF
To select which mode and bank you want to access in
BASIC, use
POKE 54017, 193 + (MODE· 16) + (BANK· 4)
For MODE and BANK, chose the number below which represents the
type and area of address:
MODE BANK
No. 6502 ANTIC No. Address
o Extd Extd 0 $0000-$3FFF
1 Main Exd 1 $4000-$7FFF
2 Extd Main 2 $8000-$BFFF
3 Main Main 3 $COOO-$FFFF
Access to the extended memory is always through the bank
S4000-S7FFF, so no matter what the address of the extended bank,
239
APPENDIX SIXTEEN
240
'- APPENDIX SEVENTEEN_
241
APPENDIX SEVENTEEN
the RAMdisk rather than Dl:. This brings up DOS almost immediately
when you leave BASIC. However, if you want to delete DUP.SYS from
the memory drive and call it up from drive 1 as usuaL type POKE
5439, ASC("l"); this points DOS back to the original drive. You can
also delete MEM.SAV from D8: if you don't need it.
242
APPENDIX SEVENTEEN
243
APPENDIX EIGHTEEN_IIIIIIIIIIIIIII
244
APPENDIX EIGHTEEN
245
APPENDIX EIGHTEEN
POKE
Address Value Hex
65284 30 $FF04, $IE
65285 31 $FF05, $IF
65292 28 $FFOC, $IC
65293 29 $FFOD, $10
65348 43 $FF44, $2B
65349 42 $FF45, $2A
65356 45 $FF4C, $20
65357 61 $FF4D, $3D
65412 92 $FF84, $5C
65413 94 $FF85, $5E
65420 95 $FF8C, $5F
65421 124 $FF8D, $7C
(XL/XE owners: Your keyboard definition table begins at 64337.
so to use this modification. subtract 941 from the addresses
given above.)
65281 rrOI
1200XL owners: You can use your function keys as cursor keys
by POKE 65281. 30 ($FFOl.$lE). POKE 65282.31 ($FF02.$lF).
POKE 65297.28 ($FFll. $1C) and POKE 65298. 11 ($FF12.$lD).
65487 rrcr
XL/XE only: To make the HELP key a start/stop key equivalent to
CONTROL-I. POKE here with 17 ($11). The HELP key returns a
keycode value at 732 ($2DC) of 17 ($11) for normal use. 81 ($51)
for SHIFT + HELP. and 145 ($91) for CONTROL+HELP.
65507 rrE3
The time delay for the repeat feature; initially 3; POKE with 1.
See also 65516 (FFEC) below.
65516 rrEC
Key repeat delay. Initially 48 ($30); change to 15 ($OF). Do this
in conjunction with the change at 65507 ($FFE3).
246
APPENDIX NINETEEN _ _
XL/XE Programs
BASIC Software Toggle
This is a version of the BASIC switcher routine used in a public do-
main program called "RamMaster." available on the Gateway BBS,
St. Louis, Missouri, used here with permission by its author, Matt
Ratcliff. The program creates an AUTORUN.SYS file which prompts
you to turn BASIC on and off; there's no need to hold down the OP-
TION key when booting a disk. When you turn it off from DOS, you
gain the 8K RAM it occupies: DOS takes advantage of this memory
space for copy and disk duplication routines. Reier back to the
XLjXE memory map for more information.
247
APPENDIX NINETEEN
248
APPENDIX NINETEEN
249
APPENDIX NINETEEN
250
APPENDIX NINETEEN
251
(-"-
XLjXE INDEX _ _ _ __
255
"--_......'
INDEX
.--
-' 257
-----_ .... __ ... - - - _ . _ - - _ . _ - - -
'-"'
258
INDEX BY LABEL
. . "'-r
----> 259
INDEX BY LABEL
.~.~.~/
260
'---'
INDEX BY LABEL
""',?
-----.J
261
,,_......./
INDEX BY LABEL
",,,---"
262
/~---------------------------------------------------------------------------------
INDEX BY SUBJECT
"--'
o.--J'
263
\---
INDEX BY SUBJECT
--
OPEN for input 58493 Coldstart ,
read block entry 58490 cassette boot 9, 74 \.-
record size 1021 disk boot 9
run address 10,11,12, entry point 58487
13 flag 580
status register 648 powerup 61733
voice track 53775 Color
Characters attract mode 77 -79
ATASCII 763,57344 default values 712
autorepeat 764 GTIA registers 53266- -........- -
bit mapping 57344 53274
blinking text 548,549, player/missile shadows 704 -707
755 playfield shadows 708-712
character sets 756,57344 - rotate 77,703
58367 screen mode 87
character set address 756,54281 Command frame buffer
colors 756 (CFB) 570 - 573
control codes 766 Console keys
control key 702, 764 cassette boot 74
control register 755 Controller jacks 54016,
cursor inhibit 752 54017
hardware code 764
internal code 762, 764 CTIA
inverse 694 seeGTIA
invisible inverse 755 Cursor
last character read, advance 85
written 763 character under 93, 125
logic processing 124 column 85,86
mode 755,54273 current position 84-86,94,
move set to RAM 756 95
printer output 31 end of line 125
prior character code 754 graphics 90-92
ROM routines 63038 - inhibit (disable) 752
63196, LOCATE 85,86
63202 logical line 99
screen location 87 opaque, transparent 755,54273
shadow 756 out of range error 87
shift key 702 previous position 90-92
tests 65470 row 84
translation of code 57344 tab width 201
under cursor 93 text window 85,86,123
upsidedown 512,513, Device "-.-i
755,54273 buffer 772, 773
Checksum 49,59,60 byte transfer 776, 777
CIO command 770
command 23 Device Control Block
IOCBs 832 - 959 (DCB) 768 -779
utility initialization 58478 drivers (adding) 806
variables 43 error status 746
vector 58454 handler address table 794 - 831
handler routines 58534-
Clock 59092
attract mode 77 -79 handler vectors 768·831
realtime 18,19,20 retries 55
serial clock lines 53775 status registers 746-749,
sound use 53768
-....l
264
INDEX BY SUBJECT
_Ii 265
INDEX BY SUBJECT
_r
color of fill area 765 Interrupts
color of line 763 BREAK key disabled 16
endpoint of line 84 - 86, 96- BREAK key vector 566,567 L-....-,.>.
266
'L_
INDEX BY SUBJECT
--1
escape key flag 674 Operating system
handler routines 63197 - character set 57344-
--.J 65535 58367
handler vector 58400 Floating Point 55296 -
interrupts 16,53774 57343
inverse toggle 694 handlers 58534 -
option, select, start keys 53279 65535
shift key flag 702,53769 ROM 55296 -
start, stop flag 767 65535
~.,
status 76 vectors 58368-
f"'- ",..-J' synchronization 54282 58533
~~ timer delay 555 Paddles
Light pen see Pots
horizontal value 564,54284 Page zero
vertical value 565,54285 BASlCuse 128· 209
Line buffer 21. 22
bitmap 690-693 Floating Point use 210 - 255
buffer 583 - 622 FMS registers 67 -73
cursor 99 lOCB 32-47
logical line 83 RAM 0-255
margins 83 Peripherals
plotting 112 - 122, controllers 54018,
126 54019
screen editor 107 interrupts 53744
tabs 201,675 - ports 54016,
689 54017
Luminance PIA
attract mode 77 -79 ROM 54016-
Machine language 54271
page six 1536 - 1791 stick 54016,
techniques 88 54017
Margins paddle (pot) triggers 54016,
editing 83 54017
initialization 82,83 ports 54016·
left 82 54019
right 83 Player/Missile Graphics
scrolling 83 (PMG)
Memory character base 54279
see RAM collision clear 53278
-'---:- ,... collision detection 53248·
,, Monitor 53263
handler routines 61667 - color registers 703-707
62435 disable, enable 559,53277
Non·Maskable Inter- DMA 54272
rupts(NMI) fifth player 623,53275
- DLI 560,561, graphic shape 53261 -
53265
54286
reset register 54287 horizontal movement 53248
service routines 59316 - horizontal position 53248-
59715 53255
status 54287 location 54279
VBLANK 546-549, memory reservation 54279
54286 movement 53248
~ vectors 512,513 multicolor 623,53275
267
---!
---------_._--------------------
268 L,
INDEX BY SUBJECT
-...J
pixel mask 672 cassette buzzer 61530
clock frequency 53768
-1 rows
save routines
703
88,89 console register 53279
screen modes 560,561 CTRL-2 buzzer 66
scrolling 88,89,106, distortion 53761
699,767, filters 53768
54276, I10beeps 65
54277, keyboard speaker 53279
64428 margins 83
size 76,88,89, octave range 53768
fl!tIII_......"'.f 672 poly counters 53761
split screen 123 Stack
TAB map 675-689 page one 256-511
text rows 703 runtime 142, 143
vectors 800,803, Status
58368, device 747
58384 display 76
vertical line counter 54283 printer timeout 28
wait synchronization 54282 810 48
Serial port 2IOCB 35
control 562,53775 Stick (joystick)
data port 790 attract mode 77
input/output 16,53773 PIA registers 54016,
interrupts 16,53774 54017
reset status 53770 read routines 632
shadow 562 shadows 632-635
status 53775 trigger latch 53277
SIO triggers 644-647
checksum 49 values 632
command frame buffer 570-573 Tabs
data buffer 50 - 53,56 comma spaces 201
Device Control Block stop map 675 - 689
(DCB) 768 -779
disk flags 576,577 Text window
error flag 575 address 660,661
flags 56-60 cursor 123,656 -
interrupt handler 58475 658
interrupts 514 - 527 GTIA 87
routines 59716 - margins 82,83
60905 plot 87
send enable 58472 rows available 703
stack pointer 792 screen mode 87,659
status 48 scrolling 699
timeouts 28 tab width 201
transmission flags 55- 60 Tlmeouts
utility initialization 58469 baud rate correction 791
vector 58457 device 748
Software timers 536 - 545 disk 582
printer 28
Sound storage 48
audio control 53761 - value 28
53768
,---,. audio frequency 53760 - Timers
attract mode 77
--
> 53768
•, beeps 64,65 baud rate 780 -782,
784-787
buzz 61530
--........
270
/'..,- ... _-----------------------
COMPUTE! Books
P.o. Box 5058 Greensboro, NC 27403
ISBN 0-87455-004- 1