Atari Assembly Language Programmers Guide
Atari Assembly Language Programmers Guide
SOFTWARE SERIES
by
Allan E. Moose
Marian J. Lorenz
The authors ha ve exercised due care in the preparation of this book and
the programs contained in it. The authors and the publisher make no
warranties either express or implied with regard to the information and
programs contained in this book. I n no event shall the authors or publisher be
liable for incidental or consequential damages arising out of the furnishing,
performance, or use of this book andl or its programs.
Atari 400', Atari 800 '". Atari 800XL'. Atari 130X E'. and Atari TOLich Table +'. arc
trad emark s or Atari Cor poration. Koala Pad' is a trademark o r Koala T ec hnologi es In c.
Published by:
Weber Systems, Inc.
8437 Mayfield Road
Chesterland, Ohio 44026
(2 I 6)729-2858
Contents
List of Boxes
List of Figures
List of Tables
Preface
Introduction
7
9
11
13
15
21
22
22
31
35
36
40
41
45
Instructions by Function
Addressing Modes
48
55
64
66
72
76
95
97
106
107
112
115
129
135
5. Sound
A Bit of Theory
Sound Hardware
Program Examples
Si xteen-Bit Music _ __ _ _ _ _ _ _ _ _ _ __ __ _
6. Advanced Techniques
The Vertical Blank Routin es
Scrolling
162
168
169
171
179
180
189
197
224
229
230
235
Vertical Scrolling
Horizontal Scrolling
Diagonal Scrolling
Vertical Blank Music
237
249
257
Touch Tablet
260
274
Appendices
281
An Atari Disassembler
Memory Map
ATASCII Codes
Instructions and Flags
Decimal Values for the 6502 Instructions
281
283
293
301
309
319
321
325
Index
329
Li st of Boxes
1
2
3
4
5
6
7A
7B
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
25A
Flags
Memory Allocation
AND-OR-EOR
Program - Display List Dump
Program - Position Concepts
Program - Modified Graphics 8
Program - Mode 4 Display List
Program - Antic Mode 4 with Rocket
Program - Antic Mode 14 Display List
Program - Page Flipping
Program - POKEing in Colors
Program - Two Methods of Displaying
Program - Artifacting
Utility - BASIC Character Generator
Program - Redefined Character
Utility - Multicolored Character Generator
Program - Light Bulb Player
Program - Collision
Program - Display List Interrupt
Program - Display List Interrupt
Program - Display List Interrupt
Program - DLI Color Table
Program - USR , Strings
Notation/ Listing for Machine Language
Assembly Language Listing - MOV$
Assembly Language Listing - REDEF$
Assembly Language Listing - REDEF$ (256 bytes)
39
42
54
79
86
87
92
93
96
97
103
105
107
110
113
116
129
132
137
140
143
146
153
154
157
158
159
25B
26
27
28
29
30
31
31A
32
32A
33
33A
34
34A
35
35A
36
36A
37
38
38A
39
39A
40
40A
41
42
42A
42B
42C
43
43A
43B
44
44A
45
45A
45B
46
46A
47
160
164
166
173
174
193
198
199
201
202
204
205
208
209
210
211
214
215
216
218
219
221
222
225
226
233
238
240
241
243
253
255
256
257
259
264
267
272
276
277
278
List of Fi g ures
2-1
3-1
3-2
3-3
3-4
3-5
3-6
3-7
3-8
3-9
3-10
3-11
3-12
3-13
4-1
4-2
5-1
5-2
5-3
5-4
5-5
5-6
6-1
6-2
6-3
59
65
73
75
78
81
83
89
108
109
114
115
126
127
155
178
180
182
182
183
186
187
231
246
248
List of Tabl es
1-1
1-2
1-3
1-4
2-1
3-1
3-3
3-4
3-5
3-6
3-7
3-8
3-9
3-10
3-11
3-12
3-13
5-1
5-2
5-3
6-1
6-2
11
Prefac e
Atari Assembly Language Programmer's Guide is written forthe
person who has had little or no experience with 6502 machine language
(machine language and assembly language are used interchangeably)
but who would like to incorporate machine language subroutines into
BASIC programs as well as for the intermediate programmer. The
preparation and organization of the book assumes that the reader has
a working knowledge of BASIC as the book is designed to build upon
that foundation. Bya working knowledge we mean that the reader is
familiar with FOR-NEXT Loops, PEEKS and POKES, setting up
strings, etc.
As you leaf through the book , you will notice that there is a good
deal of material included besides 6502 assembly language. The reason
is that we want the book to be useful for readers who want to tap the
unique graphics and sound capabilities of Atari Home Computers.
Since many of these features are available only through machine
language, we thought it appropriate to devote two chapters to graphics
and sound. These chapters serve to give you the background necessary
to put your new machine language programming abilities to maximum
use.
13
Introduction
It has become traditional to begin a book or article written for
machine language novices with the question: "Why machine language?" The answer to the question is two-fold. First, the traditional
answers. Then, more specifically, why Atari owners will find it
advantageous to learn machine language programming.
Introduction 17
you to get the 111 0s t aU! o/rour A tari's sound and grap hics capabilities.
The designers of Atari Home Computers built an excellent machine
with probably the best sound and graphics capabilities of any
microcomputer presently on the market. Because of these unique
features , one canjustify calling it a seco nd generation microcomputer.
Many of its features such as display list interrupts, vertical blank
subroutines and dynamic music are not accessible from BASIC.
Others, such as, player-miss le movement, page flipping, and scrolling,
although accessible from BASIC. are most satisfactorily implemented
by machine language s ubroutines.
Through machine language the programmer can access many of
the internal registers used in sound a nd graphics generation. There any
many things that this accessibility will allow you to do. With machine
language subroutines you can play music while a display is being
created, or generate sounds that imitate musical instruments. Machine
language is absolutely essential for dynamic sound production. In
creating graphics, machine language allows you to change colors on
the fly, use different character se ts on different parts of the same
screen, achieve smooth animation, and smooth sc rolling, to mention a
few applications.
One of the first problems that confronts a beginner is the
profusion of bu zzwo rds , acro nyms and unfamiliar number systems.
Vectors, pointers, MSB's, LSB's, AUDCI, POKMSK, binary
numbers , hex numbers and other arcania slow down the learning
process . To ease the way, chapter I begins with a discussion of the
decimal , binary, and hexadecimal number system. The computer
works with binary numbers , experienced assembly language programmers work with hexadecimal numbers, and the rest of the world
uses decimal numbers. In writing programs and reading other people's
programs, you will need to be adept at converting from one system to
another. Chapter I will help you hone your skills in this area.
The discussion of the num ber syste ms is followed by an ov.e rview
of the 6502 architecture and its operation. Usually a beginning
programmer will not need to worry about counting machine cycles or
other such details. However, a general knowledge of the inner
workings of the central processor unit (CPU) is an important aid to
visualizing what the various machine language instructions do .
Introduction 19
in chapters 5 and 6.
As mentioned before, one of our goals has been to write a book
that includes useful reference material. For this reason we've included
boxes, charts, tables , and appendices that cover all the necessary
fundamentals. This material will serve as a handy resource when
programming. Two of the appendices deserve special mention.
Appendix C is a disassembler written in BASIC. This program allows
you to input the decimal numbers representing a machine language
routine: it will return the assembly language listing. This will be helpful
in taking apart and understanding someone else's machine language
routines. Appendix B is an assembler written in BASIC. This program
will be useful in writing longer machine language programs.
Programming examples are designed to be directly applicable to
your use and are designed to illustrate general principles rather than
programming tricks. The programs in this book have been tested and
run on Atari 800's , 800XL's and the new 65XE and 130 XE computers.
Some of the programs assume that you have 48K of RAM available.
They are easy to modify . Ready to use machine language subroutines
are included. These routines have been chosen to be useful to those
readers who want to work within the Atari off-the-shelf capabilities as
opposed to system programming or arithmetic routines. The materials
and techniques presented in this book should provide the reader with
the necessary background to be comfortable with assembly language
and therefore write more sophisticated programs .
In summary, Atari Assembly Language Programmer's Guide
presents the fundamentals of machine language programming as well
as the techniques for establishing and operating machine language
programs called from BASIC. It is, therefore, in one sense a textbook
and in another sense a practical handbook. Among its purposes is to
help the reader enjoy the best of both languages-BASIC and Machine
Language by providing the necessary tools.
1
Number Systems and Hardware
Introduction
Computers use binary numbers, professional assembly language
programmers use hexadecimal numbers, and the rest of the world uses
decimal numbers. When starting to learn assembly language programming
it is necessary to begin by learning how to convert from one number
system to another. Among the reasons for learning this skill is that
many machine language routines you will come across are written
using hexadecimal numbers. If you want to call these routines from
BASIC it will be necessary to convert the hexadecimal numbers to
decimal. The first section of this chapter will discuss the decimal,
binary, and hexadecimal number systems and the representation of
characters and numbers by number codes.
In many situations assembly language programmers do not
require a detailed knowledge of computer hardware in order to write
programs that work. However, it is necessary to know some basic facts
about the 6502 processor, the AT ARI's special sound and graphics
chips, and memory organization to aid you in visualizing how to
organize and write more effective machine language routines. These
topics will be covered in the second section of this chapter.
21
HUNDREDS
TENS
UNITS
10 3
10 2
10 '
10
1000
100
10
(1 x 1000)
(7x100)
+(2x100)+ (9x1)
2 '5
2 '4
2 13
2' 2
2 "
2 10
29
28
27
26
25
2 4
23
22
2'
Weight in
decimal
32768
16384
8192
4096
2048
1024
512 256
128
64
32
16
27
26
25
2"
23
22
2'
128
64
32
16
Binary
Number:
Conversion
to decimal: (1 x128)+(1 x64 )+(O x32 )+( 1x16)+(Ox8)+(Ox4 )+(1 x2)+(Ox1)
= 210
The left most bit of a byte (D?) is called the Most Significant Bit (MSB)
because it has the greatest weight or value. The right most bit (Do) is the
Least Significant Bit (LSB) because it has the smallest weight.
There are several ways to convert binary numbers to decimal. One
method is to write down the powers of two as we did for I 10 100 10 and
add together the weights wherever a I appears. Another scheme is to
write down the number and use the recursive rule:
(previous result) x base + (next digit) = result
[~x2]
[~ext digit(06=1)] = 3
+ [next digit(05=0)] = 6
[13x2] + [0 3 (=0)] = 26
[2rx2] + [0 2 (=0)] = 22
Example 2:
128
64
32
16
{?O
(~~~)
(1 x2) + 1 :: 3
~
~=
(3x2) + 0 = 6
(6x2) + 1
13
(1~26
/
(2lX2) + 1 = 53
{5~'06
dedmal equivalent
Notice that the middle column of numbers is a sequence of 1's and O's
that matches the binary number. With a little practice, it is possible to
make the conversion shorter and do it in your head or with a
calculator.
MSB
LSB
o
2
o
5
11
23
46
93
186 (Decimal)
In each case the number in the second row was obtained by mUltiplying
the previous result by two and adding the digit above it. Remember
that the 'previous result' for the MSB is always zero . The recursive rule
of conversion has the advantage that it can also be used to convert
hexadecimal numbers into decimal.
Another way to convert binary numbers to decimal numbers is to
be consciously aware of digit patterns and number combinations. For
example, in decimal the binary number 11111111 is 255. The binary
number 11111110 is 255 minus I or 254. The number 11111101 is 255
minus 2 (2' is missing) or 253. Similarly 11000000 is 192 in decimal and
so 11000001 is easily seen to be 193. As you work with binary numbers,
more and more of these combinations will become familiar to you.
Taking note of them can save a lot of calculations in converting from
one system to another.
As an example of where you will use conversion from binary to
decimal, to produce a pure note on the Atari, it is necessary to store the
bit pattern 10100000 at one of four memory locations. Using anyone
of the conversion techniques discussed, you can easily convert this
binary number to its decimal equivalent, 160.
The largest number that can be represented in binary with 8 bits is
255 decimal. With assembly language it will be necessary to represent
numbers as large as 65535. This is accomplished by using two bytes for
a total of 16 bits. Referring back to Table 1-2 you can see that the
largest number that can be expressed with two bytes is:
Byte 1
r''''''--A....-_.,
11111111
Byte 2
r_ _ _ _A ...._
_.
....
11111111
32768+16384+8192+4096+2048+1024+412+256+128+64+32+16+8+4+2+1
~------------------------~I~I
=65355
____________~
Byte 1
Byte 2
The byte labeled as byte 1 is often called the Most Significant Byte
(MSB) or Hi-Byte. Byte 2 is called the Least Significant Byte (LSB) or
Lo-Byte. In order to avoid confusion with the most significant and
least significant bits, hereafter we will refer to bytes 1 and 2 as the
High-Byte and Lo-Byte respectively.
Situations in which you have to convert decimal numbers greater
than 255 to binary are rare . We will illustrate two ways to do the
conversion with 8 bit numbers. The principles are the same for larger
numbers . The first method is to use Table 1-2 and subtract powers of 2,
recording a 1 for each power used and a 0 for those powers you don't
use. For example, to convert 233 to binary proceed as follows:
22
27
24
23
26
25
2'
Power of 2:
2
Decimal Value:
Computation:
128
64
32
16
233
-123
105
105
--64
41
41
-32
9
9
-16
X
9
-8
- -4
- -2
- -1
0
0
0
The second way to convert decimal numbers to binary is to
repeatedly divide by two and record remainders. Starting with the
number, divide by 2 (see example below). If there is no remainder,
record a 0 as the LSB. Now divide the quotient and record the
remainder as the next bit. Continue until the quotient is zero.
Binary Equi:
Finish
Start
211
0
1
213
2
3
7
14
29
58
116
217 2[14 2129 2158 21116 21233
6
14
28
58 -116
232
-
Binary
2r1
0
1
2f2
2
2
2[4
4
4
2r9
8
9
2118
18
18
2m
36
37
2174
74
In this case you "pad" the binary to 8 bits and write it as 01001010.
One of the most frequent calculations you will have is to convert a
decimal number into its Hi-Byte, Lo-Byte form where each byte is
written as a decimal number. Conceptually (not computationally!) this
is expressed as:
Dec ima l Number
Binary rBY,e
Binary Lo-Byte
Decimal Equivalent
11010010
\
210
00000001
Binary
Decimal
DECIMAL
BINARY
HEX
0
1
2
3
0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
1011
1100
1101
1110
1111
0
1
2
3
4
5
5
6
7
8
9
10
11
12
13
14
15
6
7
8
9
A
B
C
D
E
F
- ..
1
.... . \-1- 1--
= AF
or
1 01 0
1 00 1
9
A
Conversion from hexadecimal to decimal can be done using the
recursive rule [previous result*base]+[next digit]=result rule.
For example:
A9
[previous result(O)x16) + A(=10) = 1()
J
For two digit numbers like this you'll shorten it to (l6x10) + 9 = 169.
But for numbers such as D20 I the rule is helpful :
0201
[previous result(=O)) + 0(=13)
= 13
~
= 3360
(210 x 16) + 0
---------
(3360 x 16) + 1
= 53761
33
Finish
o
1613
3
16152
48
4
832 (deCimal)
52
161832
80
32
32
= 340 (hexadecimal)
I
o
Start
16f13
0
13
13
16 f211
16
51
48
3
54271 (decimal)
211
1613391
32
19
16
31
16
15
3391
16154271
48
62
48
147
144
-31
16
15
= D3FF (hexadecimal)
1. 1536
2. 53768
3. 53762
4. 53249
5. 54282
6. 54286
7. 58466
1.22F
2. 230
3. 26F
4. 2F4
5. D407
6. E45F
7. D20E
C. Convert from decimal to binary:
1.255
2. 198
3. 228
4. 195
5. 248
6.219
7. 63
Codes
As well as using the digits zero and one to represent numbers in
binary form, sequences ofO's and I 's can be used as codes to represent
characters, special symbols, and instructions to peripheral devices.
Such codes permit communication between the computer's central
processor unit (CPU) and the keyboard, TV screen, and printer.
One of the most common codes used in computers is the ASCII
Code (American Standard Code for Information Interchange). The
AT ARI uses a modified version of this code, called AT ASCII. The
two major differences between ASCII and AT ASCII are that the
former uses only 7 bits for each character or instruction code while
A T ASCII uses 8 bits and the AT ASCII code includes many special
graphics symbols. In fact AT ASCII makes use of all the numbers 0
through 255 while ASCII does not. This property of the AT ASCII
code will be very important later for it will allow you to store machine
language routines as strings in BASIC. Appendix E lists the A TASCII
code with its corresponding symbols and keystrokes. This listing is an
important resource in your work.
o 1 00
01 1 0
00 1
9
Binary Code
0000
0001
0011
0010
0100
0101
0110
0111
1000
1001
2
3
4
5
6
7
8
9
Two of the bits are control bits . The remaining five are status flags The
status flags provide information on the result of a previously executed
instruction (usually the preceding instruction). The 6502 can be
programmed to test the condition of each of these flags . Based on the
results of these tests, the 6502 can choose between two possible
sequences of instructions . The locations , labels, and functions of these
bits are described in Box 1.
4. The Stack Pointer: The stack is a special storage area in memory
at locations 256 to 511 (Page 1 of memory) . The stack works as a
last-in/ first-out storage area analogous to a stack of plates in a kitchen
cabinet. It is used to store information necessary to perform subroutine
calls and interrupts correctly. On power-up or after a reset, the stack
begins at address 511, which in Hi-Byte / Lo-Byte form is 01,255. The
stack pointer will, at this time, contain the byte 255, as data is stored or
removed on the stack, the stack pointer is incremented or decremented
so that it always gives the address of the next available stack location.
5. The Program Counter: Machine language instructions are
stored in memory in order by address. The program counter insures
that instructions are performed in the proper sequence . At any instant
the program counter contains the address of the next byte of the
program to be read .
BOX1
D7
D6
Ds
D4
D3
D2
D,
Do
Note: If a flag is set, then there is a Logical 1 in that particular bit of the
status register. If a flag is clear, then there is a Logical 0 in that
particular bit of the status register.
C == Carry Flag. This bit is set when an addition, shift, or rotate
generates a carry. It is cleared when a subtraction or compare
produces a borrow.
Z == Zero Flag. This bit is set when the accumulator, the index
registers or a memory location contain all zeros as the result of an
instruction such as increment, decrement or the arithmetic and logical
instructions.
I == Interrupt Flag. This bit is set whenever an interrupt in the
normal processing occurs or when a Break (BRK) instruction is
executed. It is cleared whenever a Return from Interrupt (RTI)
instruction is executed.
D == Decimal Flag. This flag is used to signal the processor that
addition and subtraction are to be performed in the decimal mode
using BCD .
B == Break Flag. This flag is set, along with the I flag whenever a
BRK instruction is executed. It is cleared following an RTI instruction.
V == Overflow Flag. This flag is set when an addition or subtraction
prod uces a resu It greater than 127 or less than -128. It is used in
applications involving signed numbers.
N == Negative Flag. This flag indicates whether or not the result of a
signed arithmetic operation produced a negative result.
CPU Operation
A machine language program is nothing more than a series of
numbers stored as bytes in memory . When a computer is executing a
program it goes through a fundamental sequence that is repeated over
and over again. To execute a program , the CPU must fetch a byte,
decode its meaning, and execute the instruction. This fetch-decodeexecute sequence is repeated at very high speed until the program is
finished. The rate at which operations occur within the CPU, and their
sequence, is governed by a system clock that sends out electrical pulses
at the rate of 1.79 million cycles per second. One cycle per second is
a lso called one Hertz so you will often see this written as 1.79 MHz.
Instructions to the CPU are either one, two , or three bytes long. A
three byte instruction consists of a numeric code followed by two
address bytes. A typical two byte instruction is one code byte followed
by a number. A single byte instruction is simply a code byte to do some
task, for example, Return from Subroutine (RTS). CPU instructions
take from two to seven clock cycles to execute with most taking three
to four cycles. Occasionally it is necessary to time the length of a
subroutine in order to insure that it will be completed within a
specified time limit. Timing considerations will come up later when we
discuss display list interrupts.
busses to access the memory that it needs . This process is called Direct
Memory Access (DMA). ANTIC also controls the non-maskable
interrupts of the processor. A Non-Maskable Interrupt (NMI) is just
what its name implies - a signal to the CPU , which it cannot ignore, to
stop its current operations and go to another program . These
interrupts are useful in both sound and graphics programming.
2. GTIA: is a special television interface adaptor chip that works in
conjunction with ANTIC. Its primary purpose is the direct control of
the TV display . Thus it is responsible for controlling color and
luminance, playfield and player missile graphics, collisions and
priority.
3. POKEY: is a digital I / O chip that has a variety offunctions. One
of the foremost is sound generation . It is the keeper of the registers that
control the frequency and type of sound output. In addition POKEY
takes care of transmission of data from the keyboard and from the
serial communications port. Serial data transfer differs from the
parallel data transfer mentioned earlier in that data is transmitted one
bit at a time. Other functions of POKEY will be described in Chapter
Six.
4. PIA: is the Peripheral Interface Adaptor chip with the primary
responsibility for controlling data to and from the joystick ports . It is
used with any peripheral, such as paddles, joysticks, keypads, or the
Koala pad, that plugs into th ese ports .
USE
LOCATION
65535
to
and
55296
Arithmetic Routines
55295
Hardware Registers
53248
ANTIC
PIA
POKEY
GTIA
53247
4K unused memory
to
54272
54016
53760
53248
54783
54271
54015
53503
to
40960
-- -
40959
to
32768
32767
to
1791
to
1536
1535
to
and
1152
Arithmetic routines
1151
to
512
511
to
256
STACK Page 1
255
to
128
127
to
0
as Page Zero
Box 2. (cont.)
2
OVERVIEW OF 6502 INSTRUCTIONS
Introduction
Table 2-1 is a list of the fifty-six different instruction names for the
6502 CPU. Each instruction name has been coded into a three letter
mnemonic that is suggestive of the task to be carried out. Roughly half
of these instructions perform simple workman-like jobs such as
transferring the contents of one register into another, incrementing or
decrementing a register, and setting or clearing a bit . Approximately
half of the remaining instructions manipulate data by transfering it to
and from memory, or comparing a register with the contents of
memory.
One of the most important features of the 6502 is the number of
options available for specifying the location of the byte to be
manipulated. There are thirteen different addressing modes . This is
several more than are available on other common 8-bit microprocessors
and provides for greater flexibility in programming the 6502. The
fifty-six basic instructions in combination with the thirteen addressing
modes yields a total of 151 different instructions available to the
programmer.
45
ADC
AND
ASL
BCC
BCS
BEQ
BIT
BMI
BNE
BPL
BRK
Force Break
BVC
BVS
CLC
CLD
CLI
CLV
CMP
CPX
CPY
DEC
DEY
EOR
INC
INX
INY
JMP
JSR
Jump to subroutine
LDA
LDX
LDY
LSR
NOP
No operation
ORA
PHA
PHP
PLA
PLP
ROL
ROR
RTI
RTS
SBC
SEC
SED
SEI
STA
STX
STY
TAX
TAY
TSX
TXA
TXS
TYA
Instructions by Function
1. Load and Store Instructions: Since the 6502 processor has a
Of these six instructions , the first four will be the most useful.
Examples of their use will be demonstrated with display list interrupt
routines in Chapter Four.
3. Increment and Decrement Instructions: One of the functions
BNE
and
work very nicely with the compare instructions when you want to
execute a loop. The remaining six branch instructions are:
BCC
BCS
BMI
BPL
BVS
BVC
Branch
Branch
Branch
Branch
Branch
Branch
on
on
on
on
on
on
eLi
CLD
and
Of course, SED causes the CPU to work in the decimal mode while
CLD directs the CPU to act in the binary mode.
Addition can be completed with or without a carry occuring as
part of the result. Similarly subtraction can be performed with or
without borrowing. Unlike some other processors, the 6502 only has
instructions for addition with a carry and subtraction with borrow.
The digit to be 'borrowed' is contributed by the carry flag of the status
register. Before an addition the carry flag shou ld be cleared. Before a
subtraction the carry flag should be set. The relevant instructions are:
CLC Clear Carry
ADC Add with Carry
SEC Set Carry
SBC Subtract with Carry as Borrow
CLV
ASL
in which you wish to test certain bits rather than a whole byte. Or, you
may wish to set or clear certain bits. The logical instructions will allow
you to do this. They are:
AND
EOR
ORA
Box 3
AND
Input Bit #1
Input Bit #2
Result
Input Bit #1
Input Bit #2
0
0
0
0
OR
Result
EOR
Input Bit #1
Input Bit #2
Result
0
0
0
Result
0
0
0
1
BIT
No Operation
Break
Test Bits in memory with Accumulator
Addressing Modes
Each of the 151 instructions has its own numeric operation code
(op-code, for short). Most instructions consist of one byte of op-code
plus a one or two byte operand. The op-code tells the CPU what task is
to be performed and the mode of addressing used. The operand may be
Immediate
Absolute
Zero Page
Indirect
5. Implied
6. Relative
7. Accumulator
and six modes that are a combination of indexed addressing and one of
the basic modes:
8. Absolute X-indexed
9. Absolute V-indexed
10. Zero Page X-indexed
11. Zero Page V-indexed
12. Indirect indexed
13. Indexed indirect
Second byte
Third Byte
Op-code
La-Byte of addr.
Hi-Byte of addr .
06
This instruction sends the CPU to memory location 1664 (06,128) for
the Lo-Byte of the effective address . The Hi-Byte of the effective
address is in the next memory location , 1665 (06,129). The advantage
of indirect addressing is that it allows a fixed instruction sequence to
go to different memory locations simply by changing the values in the
immediate storage area.
Implied Addressing: Many instructions involve operations internal
FLOW
CHART
2 -1
BRANCH
INSTRUCTION
IS
DECODED
BACKWARD
( - OFFSET)
1
IS
CONDITION
MET'
NO
YES
PROGRAM
COUNTER
POINTS TO
NE X T
INSTRUCTION
PROGRAM
COUNTER
BECOMES
PROGRAM
COUNTER
PLUS OFFSET
FO RWARD
(+OFFSETl
PROGRAM
COUNTER
POINTS TO
NE X T
INSTR UCTION
FETCH
NE XT
IN STRUC TION
3
Atari Graphics
Introduction
The video portion of the Atari Home Computer system was
developed to be compa tible with the functioning of an ordinary TV set.
Forexample, the system clock was designed to have a frequency that is
a multiple of a fundamental TV frequency. This allows CPU interrupts
during horizontal and vertical blanks to be easily implemented. The
compatibility of the TV and the computer is an important feature of
Atari graphics. In addition , the Atari system is unique among home
computers because it uses a second microprocessor (ANTIC) to
control the TV display. Since there is such an intimate connection
between the Atari system and the TV set , we shall begin this chapter
with a description of how a TV operates , with the remainder of the
chapter devoted to an in depth discussion of ANTIC and Atari
graphics .
63
TV Operation
The picture on a TV screen is made up of many small picture
elements, or pixels. A TV picture is produced by the interaction of a
modulated beam of electrons with phosphors on the screen. At the rear
of the TV is an electron gun that produces a narrow beam of electrons.
In the beginning of the sequence that forms a picture, the beam is
aimed above the upper left hand corner of the TV screen (see figure
3-1). The beam sweeps from left to right across the face ofthe screen in
64/1 sec. (a microsecond is a unit of time equal to one millionth of a
second). A single horizontal sweep of the electron beam across the
screen is called a scan line. When the electron beam reaches the end of
the scan line it is shut off briefly and the electron gun is re-aimed at the
left side of the screen, but slightly lower down. The period of time that
the electron gun is turned off is called the horizontal blank (14/1 sec.).
This horizontal scanning process is repeated until a picture is built
up line by line. The complete sequence from top to bottom is called a
frame and sixty complete frames are drawn per second. In a normal
TV picture received from a broadcast station there are 525 scan lines
per frame in an arrangement called interlacing. The Atari system does
not use interlacing and there are 262 scan lines from top to bottom. In
actuality, the electron beam scanning starts slightly above and ends
slightly below the visible portion ofthe TV screen. Similarly, it extends
slightly to the left and slightly to the right of the visible screen. This
overscanning prevents unsightly borders for normal TV pictures, and
must be taken into consideration in computer displays.
Vertical positioning on the screen is measured in scan lines.
Horizontal positioning on the screen is measured in units called color
clocks. There are two machine cycles per color clock and 228 color
clocks per scan line. Display dimensions including overscan are 262
scan lines by 228 color clocks. To prevent loss of information due to
overscanning, the normal Atari display uses 192 scan lines by 160 color
clocks.
When the electron beam reaches the end of the last scan line it is
shut off and the electron gun is re-aimed at the upper left hand corner
of the screen. This period of time in which the beam is off is called the
Atari Graphics 65
TELE VISION
SCANNING
OVERSCAN
- ---
-+--~'~~--------------~~~~-r-~
~~--~'~--------------------~~-=~--HORIZONTAL
- ---
--~~-=-~~~----------------------~~_SYNC
'- -
-~
-,
-_....
-
SIGNAL
'~
,
,
VERT IC AL
SY NC SIGNAL
vertical blank (1400 f.1 sec.). The hori zontal and vertical blanks are
important events in the Atari system. The display hardware generates
horizontal and vertical synchronization pulses that are used by the TV
and can also be used to signal interrupts to the CPU. The Atari system
uses these synchronization signals to give programmers an opportunity
to interrupt normal program flow and have the processor carry out
machine language subroutines. In later chapters we will see that the
horizontal blank is specially useful in graphics and the vertical blank is
useful in scrolling and music.
ANTIC
At the heart of the Atari graphics system is the microprocessor,
ANTIC. Along with the integrated circuit chip GTIA, ANTIC
controls the display of text and graphics on the screen. Since it is a
microprocessor, ANTIC has control lines , a data bus , an address bus,
and an instruction set that can be used to program it. The control lines
allow ANTIC to communicate with the CPU, while the address bus
and data bus allow it to access memory. ANTIC shares the RAM
memory used by the 6502. This sharing of memory by both processors
has two interesting implications. First, it means that ANTIC must
obtain data from memory by a process known as direct memory access
(DMA). Essentially what happens is that when ANTIC needs access to
memory it halts the CPU, gets the information it needs, and then
allows the CPU to go on about its business. This process, called cycle
stealing, slows down the CPU's execution speed. The second implication
is that the CPU can modify the sections of memory used by ANTIC.
This, of course, is precisely the idea behind creating dynamic graphics
-ANTIC handles the details of generating the TV display while the
CPU changes the data ANTIC uses.
ANTIC's program is called a display list. The section of memory
used by ANTIC to determine what to disp lay on the screen is called
screen memory. The remainder of this section of the chapter is devoted
to a discussion of ANTIC's instruction set and writing display lists that
provide custom graphics.
Atori Graphics 67
Although ANTlC, like the 6502, has a 16 line address bus, it has
limitations in addressing a display list and screen memory. ANTIC has
two registers that act as program counters. There is a display list
counter for accessing the display list and a memory scan counter for
accessing screen memory (recall that a program counter holds the
address of the byte to be fetched in the fetch-decode-execute sequence).
The two counters are each 16 bits wide, but do not function as full 16
bit counters. The upper six bits of the display list counter are fixed,
leaving bits Do to 0 9 to act as the program counter. Restricting the
counter to ten bits means that a display list cannot cross a I K
boundary unless ajump instruction is used. This is because the largest
decimal number that can be represented with ten bits is 1023. If the
display list starts on a I K boundary, that is, if the starting address of
the display list is divisible by 1024 with no remainder, it usually will not
be a problem. Most display lists are short -less than a hundred bytes.
While the upper six bits of the display list counter are fixed, only
the upper four bits of the memory scan counter are fixed. This leaves
bits Do to D11 to function as the counter. Since the largest decimal
number that can be represented with twelve bits is 4095, ANTlC
cannot access screen memory that crosses a 4K boundary without a
special instruction .
ANTlC's instructions can be grouped as:
1. Display mode instructions
a. Character mode
b. Map mode
2. Blank line instructions
3. Jump instructions
a. Jump during vertical blank (JVB)
b. Jump to a new memory address (JMP)
ANTIC combines the TV's scan lines into groups known as mode
lines. Each mode line is made up of one to sixteen scan lines depending
on the graphics mode. There are two types of graphics modes character mode and map mode. Character mode instructions cause
ANTIC to disRlay a mode line with alpha-numeric or character
- .'
graphics in it. Each byte in screen memory is the internal code of the
character to be displayed. Map mode instructions cause ANTIC to
display solid color pixels.
Blank line instructions cause ANTIC to display one to eight scan
lines in the background color. These instructions are most commonly
used to allow for TV overscan.
Jump instructions are analogous to the BASIC GOTO command,
except that you specify the memory address to go to, not a line
number. When the program is run the address specified is loaded into
the display list counter and consequently starts the fetch-decodeexecute sequence at the new memory location.
Instructions for any 8 bit microprocessor such as ANTIC are
coded as binary numbers . We shall examine ANTIC's instruction byte
in detail to see how to derive the decimal code for each instruction and
option. The ANTIC instruction byte can be represented as:
D7 D6 D5 D4: D3 D2 D,
instruction option nibble
I
I
I
Do
Atari Graphics 69
D3
D2
D,
Do
0
0
0
0
0
0
1
1
0
0
0
1
0
1
0
1
0
0
0
0
0
0
0
0
1
0
0
Display Mode
Decimal
Lower Nibble
0
1
0
0
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Note: The supporting system of the 'XL' and 'XE' series computers
supports ANTIC Modes.
To use
ANTIC
ANTIC
ANTIC
ANTIC
4
5
12
14
call a Graphics
12
13
14
15
command
Weight
Bit
Bi nary
OLl--...:.
16
32
64
128
07
06
05
04
1
0
0 ~1
Horizontal Scrolling..J
Basic mode 7
Using the techniques in chapter one you can convert this into its
decimal equivalent: 128+ 16+8+4+ 1= 157 . The decimal value is what
you will use in your display list.
As another example, suppose you need an LMS in BASIC
Graphics 2. The bit pattern is:
Weight
Bit
Binary
128
07
0
64
06
1
.LMS
32
05
0
16
04
0
8
03
0
O2
2
01
00
BASIC Mode 2
Atari Graphics 71
D7 D6 D5 D4 D3 D2 D1 Do
Decimal Value
NumberofBlank Lines
,
0
0
0
0
0
0
0
0
0
0
0
0
1
1
1
1
0
0
1
1
0
0
1
1
0
1
0
1
0
1
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
2
3
4
5
6
7
8
0
16
32
48
64
80
96
112
D3 D2 D,
Do
IT kXJXI I I I I
r
DLI Bit
If 0 then JMP
If 1 then JVB
Jump Bit
1 = jump
0= no jump
Thus a JVB without the DLI option has the code 65 and the JMP
instruction without the DLI option has the numeric code 0 I.
Display Modes
An important feature of Atari graphics is the ease with which a
programmer can mix graphics modes on the screen by writing a
custom display list. Before we discuss how to construct a custom
display list, it is important to have an understanding of Atari display
modes . First, we shall describe the modes available from BASIC. Then
we will describe the ANTIC display modes.
The fundamental structure of the TV display is 192 scan lines
vertically and 160 color clocks horizontally. The basic differences
between the display modes are how this structure is organized into
pixels, and the colors available. There are three character modes and
six map modes accessible from BASIC. These are BASIC Modes 0, 1,
2 and 3, 4,5,6,7 , 8, respectively. Atari Computers with GTIA support
three additional graphics modes (9 ,10, 11) that are enhancements of
Graphics 8. As an example of the different ways to organize the basic
structure, Graphics 0 uses pixels that are 8 scan lines by 4 color clocks,
while Graphics 2 uses pixels that are 16 scan lines by 8 color clocks.
Consequently, Graphics 2 pixels are twice as high and twice as wide as
Graphics 0 pixels. Additionally, Graphics 0 has two colors and
Graphics 2 has five colors available.
The location of pixels on the screen is conveniently described by
X-Y coordinates in which the X-coordinate labels the horizontal
position, or column and the Y-coordinate labels the vertical position,
or row. Figure 3-2 illustrates this idea with a full screen in Graphics 2.
All of the BASIC display modes except Graphics 0 and GTIA
Modes have both a full screen and a split screen version. In a split
screen version, the bottom 32 scan lines are devoted to four Graphics 0
mode lines that provide a text window. Pixel location in the text
window, when expressed in terms of coordinates, is best thought of
independently ofthe coordinates of the graphics mode above it. Figure
3-3 shows Graphics 3 with a text window to emphasize this point. In
figure 3-3, the upper lefthand pixel of the text window is labeled 0,0,
Atari Graphics 73
just as if it were at the top of the screen. This idea of locating pixels
within a particular group of mode lines independently of the other
graphics modes on the screen is useful with custom display lists and
mixed modes.
GRAPHICS 2+16
o
COORDINATES
12
16
19
Atari Graphics 75
GRAPHICS
MODE
WITH
TE X T
WINDOW
H-+-++-+-H-++++++++++++-H--I-l--l-l+-l-~~H-+-+H-+-+- -
_ _ -+-, --+--I---+-
(,
H-+++-t--+-t-++-++-t-I---H--H-+--,H--H--I---~+_H-+__I_-I_I'. -I_
,,
W-W-l-- 1-+I---
--
H-t-i=~-h IT!-/
, Lttc-t-Jf-Li-rt+-I
"
You can see that there are trade offs made between resolution, colors,
and screen memory. Consideration of these factors is important when
you are planning large or complex programs that may use several
different colorful screen displays.
Display Lists
The Atari Home Computer, with its many different display
modes and its built in capability for mixing these modes on the TV
screen allows you many opportunities for creative programming. You
can mix character and map modes almost at will. The way to do this is
to write your own custom display list. There are two ways to proceed
when creating a display list. First, you can modify one that is accessible
from BASIC. Second, you can create your own display list from
scratch, store it in memory, and tell the computer to use it.
When planning a custom display list, there are two categories of
items to take into account. The first category relates to the overall
organization of the display you wish to create. These factors are: the
types of modes you wish to use, the colors available, and special
features such as scrolling and display list interrupts. The second
category of factors to consider are of primary importance in actually
constructing the display list. These are: the number of scan lines per
mode line, the number of memory bytes per mode line, and the total
screen memory needed. Since these factors are essential in planning a
display list, Table 3-4 summarizes this information.
Atari Graphics 77
BASIC ANTIC
0
-
5
6
7
3
4
5
6
8
9
10
11
12
13
14
15
COL/ROW
SCAN LINES
SCRN RAM
MINIMUM
with
no
per
per
TOTAL
TEXT WINDOW
TEXT WINDOW
MODE LINE
MODE LINE
SCRN MEM
40 X 24
40 X 19
40 X 24
40 X 12
20 X 24
20 X 12
40 X 24
80 X 48
80 X 48
160 X 96
160x192
8
10
8
16
40
960
760
960
480
480
240
2
3
4
1
2
7
-
COL/ROW
20 X 20
20 X 10
40 X 20
80 X 40
80 X 40
160 X 80
160
80
320
160
160 X 96
160 X 192
320 X 192
8
16
8
4
4
2
1
2
1
1
40
40
40
20
20
10
10
20
20
20
40
40
40
240
480
960
1920
3840
3840
7680
7680
DL Byte
Decimal Value
Binary
2
3
112
112
112
0111 0000
24
Blank
Lines
4
5
6
71
01000111
158
LMS and GR . 2
Lo-Byte
Hi-Byte
7
8
10
00000111
BASIC
MODE
112
11
12
13
14
15
7
7
16
17
18
19
20
65
92
158
01000001
JVB
Lo-Byte
Hi-Byte
Atari Graphics 79
The addresses following the JVB and LMS op codes allow you to
infer how the OS has positioned the display list and screen memory
within the computer's memory. According to the JVB instruction, the
display list starts at 40540 (158 ,92). If you count the number of bytes in
the display list you will see that the last one is in memory location
40559 (I58, Ill). Checking the LMS instruction, we see that the next
byte in memory, 40560 (158,1 12), is the start of screen memory. In the
Atari the OS locates screen memory immediately following the display
list. The exact addresses where the OS positions the display list and
screen memory are dependent on the amount of system memory and
graphics mode .
Box 4 is a short BASIC program that will allow you to print out
display lists for each of the BASIC display modes. It is useful to have
these printouts for reference when planning a custom display list.
BOX 4
Utility Progra..
Display List Dump
II,
\..
Box 4.
FUNCTION
SDLSTL
560,561
SAVMSC
88,89
DINDEX
87
LAQ_E_L
Atari Graphics 81
x 20 080
rvlODE 1
MODE B
128 "40: 5120
MODE 2
5240
SCREEN RAM
2x16=32
IQ2
SCAN LINES
10 GRAPHICS 8
Next you will need a variable to keep track of the starting address of
the display list. Call this variable something like "DL" or "START"
and peek the display list pointer with the following command:
20 DL= PEEK(560)+PEEK(561 )*256
Step 4: If needed modify the original LMS instruction in the
display list to give you the proper mode line at the top of the screen. To
get the first mode line of Gra phics 1:
30 POKE DL +3,70
Step 5: Modify the remainder of the display list. Here is where the
printout of the original display list is handy because you can count
bytes in the original to figure out where to put your new instructions .
The Graphics 8 display list is shown in figure 3-6.
First, we want three more Graphics I lines at the top of the screen.
This is accomplished with:
40 POKE DL+6,6 :POKE DL+7,6:POKE DL+8,6
which will replace the three graphics 8 instructions following the LMS
address bytes.
In order to place the Mode 2 lines we count 128 Graphics 8 lines
down the display list. This example illustrates something important
about Graphics 8 display lists . Recall that the memory scan counter
cannot cross a 4K boundary and Graphics 8 needs 7680 bytes of screen
memory. Consequently screen memory is broken up into two blocks.
ANTIC is sent to the first block of screen memory by the first LMS
instruction in address 32851, and is then sent to the second block of
screen memory by the second LMS instruction in address 32947. The
need to "jump the 4K boundary" occurs only in the Graphics 8 Mode.
Care should be exercised that neither the second LMS instruction nor
its operand are accidentally clobbered by inserted mode lines. Also the
two address bytes must be allowed for in counting where you will insert
mode lines near the bottom of the screen. Taking all of this into
account we have line 50:
Atari Graphics 83
ADDRESS
32848
32849
32850
32851
32852
32853
32854
32855
32856
32857
32943
32944
32945
32946
32947
32948
32949
32950
32951
32952
DL BYTE
1
2
3
4
5
6
7
8
9
10
85 Bytes omitted
96
97
98
99
100
101
102
103
104
105
INSTRUCTION
112
112
112
79
80
129
15
15
15
15
15
15
15
15
79
0
144
15
15
15
60 Bytes omitted
33013
33014
33015
33016
33017
33018
33019
33020
33021
33022
33023
166
167
168
169
170
171
172
173
174
175
176
15
15
66
96
159
2
2
2
65
80
128
Note that after these values are put into the display list any bytes
remaining from the original display list will not be used .
Displaying characters or graphics on a modified screen involves
telling the OS how to interpret the data in screen memory. It would not
work to tell the computer to display a character in Mode 1 if the
computer thinks it is using Graphics 8. The register DINDEX
(location 87) tells the OS which display mode is in use. Accordingly, to
print in either the Mode 1 or Mode 2 portions of the above display list
it is first necessary to POKE 87,1 or POKE 87,2 respectively. In all
cases the number POKEd is the BASIC display mode number.
A second complication arises when the OS positions text or
graphics on the screen. This occurs because positioning is done by
counting bytes from the start of screen memory. The OS does its
calculation on the basis of the size of screen memory associated with
the display mode value stored in location 87. With a custom display
list, it is possible for total screen memory to be considerably longer
than the mode the OS is using. This disparity can cause the dreaded
"cursor out of range" error message as well as trouble positioning
material on the screen. Fortunately the cure for this problem is fairly
simple. Before creating a display on the screen, change the pointer to
the top of screen memory (SA VMSC) to coincide with the start of the
mode section where you want the display to appear. This means that
you temporarily treat the upper left hand pixel of that mode as being
position 0,0 and place your display within that mode section in the
usual manner. This technique also eliminates the trial and error
method of positioning things on the screen.
Atari Graphics 85
r
BOX 5
Custom Display List
PositioninQ Concepts
5 REM ** CUSTOM DL/POSITIONING **
1111 GRAPHICS 8
20 DL=PEEK(560)+PEEK(561)*256
30 POKE DL +3,7111
40 POKE DL+6,6:POKE DL+7,6:POKE DL+8,6
50 POKE DL+139,7:POKE DL+140,7
60 POKE DL+141,65
70 POKE DL+142.PEEK(560):POKE DL+143.PEEK(561)
80 POKE 87,I:POSITION 0,0:7 #6; "GRAPHICS PROGRAMMING"
85 POSITION 1,2:? #6; "SCREEN POSITIONING"
9121 POKE 87, 8
100 TPSCRN=PEEK(88)+PEEK(89)*256
105 TPSCRN=PEEK(88)+PEEKI89)*256
110 TPSCRN=TPSCRN+81
120 POKE 88,TPSCRN-IINTCTPSCRN/256*256
130 POKE 89,INTCTPSCRN/256)
140 COLOR 1
150 FOR T=@ TO 720 STEP 3
1~0 W=T/57.26:R=5*W
170 X=INTCR*COSCW:Y=INTCR*SINCW))
180 IF T=0 THEN PLOT 160+X,64-Y
190 DRAWTO 160+X,64-Y
21110 NEXT T
210 POKE 87,2
220 TPSCRN=TPSCRN+5200
230 POKE 88,TPSCRN-CINTCTPSCRN/25611*256
240 POKE 89,INTCTPSCRN/256)
250 POSITION 111,121: 7 #6; "ATARI DISPLAY LIST"
second LMS byte in the Graphics 8 display list. See what happens!
Does it affect PLOT's and ORA WTO's? Deliberately creating programs
with 'bugs' and studying the results can be a great help in later program
debugging; (d) change the address bytes for the first block of screen
memory to page zero of memory. One thing you should see is the real
time clock in action.
Atari Graphics 87
BOX6
Creating your own display list from scratch can seem easier than
modifying a display list provided by BASIC, because you are starting
with a clean slate. The first concern is where to store the display list and
its screen memory so that they won't be overwritten by BASIC. The
OS solves this problem by storing them between the addresses pointed
to by MEMTOP (741 ,742) and RAMTOP (106). MEMTOP is the
pointer to the last free byte available to BASIC. RAMTOP points to
the dividing line between RA M and the high memory address used for
the BASIC cartridge, GTlA, POKEY , and so on. The value in
RAMTOP is always expressed in pages (multiples of 256), and in a
48K Atari is 160, corresponding to memory address 40960.
Providing a place in memory that is safe from being overwritten
by BASIC is a problem that occurs whenever you want to use special
features such as redefined character sets, player/ missile graphics,
machine language subroutines , or when creating your own display list.
There are several solutions to the problem . One solution we shall
frequently use is to lower RAMTOP by a BASIC statement such as:
The space in memory between the old RAMTOP value and the new
one is essentially safe. Usually, if you are working from BASIC, it is a
good idea to follow the change in RAMTOP with a GRAPHICS or a
CLOSE #6,OPEN#6 ,8,0,"S:" sequence . This will update MEMTOP
and insure that any display list created later in the program by the OS
will not override data in your reserved area. You should be aware that
any clear screen commands or text window scrolling that occurs will
clear some memory beyond RAMTOP - up to 800 bytes for text
window scrolling. Therefore, to avoid memory conflicts it is fortuitous
to leave a buffer zone between RAMTOP and your display list, or
other special programs.
As with modifying a BASIC display list, writing a display list
from scratch should be approached in a sequential manner.
Step 1: Figure out how you want to present the screen . Be sure to:
(a) Allow for 24 blank lines at the top of the screen . (b) Plan what mode
lines you are using and their position on the screen. (c) Take into
account special options. For example, with scrolling you may want
every mode line used to have the LMS option . Figure 3-7 is a rather
complicated example that we have provided simply to give you a
feeling for the calculations involved in this and succeeding steps.
As a practical example we will construct an ANTIC Mode 4
display list. After making a drawing similar to Figure 3-7 and taking
into account special option, make a rough display list such as this:
Atari Graphics
89
LINE
BLANK
.M~
LO~8YTE
HI~BYTE
ANTIC
,3
40 X 4: 160
ANTIC
4 X 8: 32
40XI06=4.,20
ANTIC
12
108X I 106
ANTIC
2 X16 :: 32
40X5=200
47E.0
JV B
~INIMU~~
SCREE.N ME.MORY
2X 10:20
192 SCAN
'-....--~----'/
D.L . 124 I3YTES
~
=19.08
OR
20
FOR
DISPLAY
LIST
AND SCI.'EEN
MEMORY
PAGES
LINES
112
112 24 blank lines
112
LMS
SCRN MEM ADDR-LO
SCRN MEM ADDR-HI
MODE LINE
MODE LINE
23 Mode 4 lines
JVB
DL ADDR-LO
DL ADDR-HI
Step 2: From the draft display list, count the number of bytes that
number of bytes required per mode line. The total number of bytes
equals the amount of screen memory. (40 bytes * 24 mode lines = 960)
Step 4: The results of steps 2 and 3 determine the number of pages
needed for both the display list and screen memory (32+960= 992/ 256
or
text window scrolling later in the program, leiwe a buffer between
RAMTOP and your display list.
Atari Graphics 91
CONTENTS
160
Old RAMTOP
159
158
157
156
Screen Memory
155
Display List
154
153
152
New RAMTOP
Also replace each number 155 with (PEEK(l06)+3) and each number
156 with (PEEK(l06)+4).
,
.,X7
Nn'IC . . . . 4 Di ... ley Uat
~ PtE'"
**
ANTI C "'ODE 4
2.
3111
4111
51
..
**
aRAPHIC8 "
DL-l~~*2S6
11"
11 ~
12"
13"
14111
~. . ,IIIIPOKI S61,l~~
Atari Graphics 93
lOX 78
MlTle ..... 4 . i th
~ket
1 REM BOX 7B
REM ANTIC MODE 4 WITH ROCKET
S REM LOWER RAMTOP
1. POKE 1'6,1~2
21 BRAPH I CS
2~ REM SET UP DISPLAY LIlT
3. DL-l~e.~
4. ~OR I . . TO 2:POKE DL+I,112:NEXT I
51 POKE DL+4,6S:POKE DL+e,':POKE DL+6.1e6
6. FOR 1-1 TO 22:POKE DL+7+I,4:NEXT I
7. POKE DL+29.6~
. . POKE DL+3I, I
. . POKE DL+31,les
IN POKE s..,lrPOKE !561. ISS
~
lie
11.
111
112
113
11~
12.
12e
131
141
IS.
16.
161
16S
17.
17~
lB.
IS5
19.
195
2
2.5
210
22.
225
230
23S
240
24~
2 ~f21
p~riod
a.
Atari Graphics 95
A Useful Exercise
This exercise is primarily for AT ARI 400 and 800 owners. The
operating system of the XL I XE Series computers supports ANTIC
Mode 14 through the BASIC Statement Graphics 15. Write your own
ANTIC Mode 14 display list. 00 it from scratch, NOT by modifying a
Graphics 8 display list. Modifying a Graphics 8 display list into an
ANTIC 14 display list is too easy and misses the point of the exercise.
You will have to pay special attention to allocating screen memory into
blocks. At 40 bytes per scan line, 102 scan lines of ANTIC 14 needs
4080 bytes of screen memory. A full screen of ANTIC 14 has 192 scan
lines so there will have to be an LMS instruction somewhere before the
103rd scan line. But, there is more to it than that. What about the
relative positions of the two blocks of screen memory? The OS
calculates PLOTs and ORA WTOs on the basis of screen memory size.
What will happen if your two memory blocks are not contiguous? This
raises another question: How do you tell the OS what graphics mode
to use? OINOEX (location 87) accepts BASIC Mode numbers, not
ANTIC Mode numbers. Basic Mode 7 is a four color graphics mode so
maybe we can use that.. .. But, BASIC 7 uses 3840 bytes of screen
memory while ANTIC 14 uses 7680. What does that do to a
ORA WTO from the top of the screen to the bottom?
Box 8 is one solution to the display list problem that shows how to
plot to the bottom of the screen by POKEing numbers directly into
screen memory, but doesn't answer the problem of PLOTing and
ORA Wing on a full screen.
Page Flipping
From the knowledge that you have accumulated at this point, the
concept behind page flipping should be easy to grasp and almost as
easy to implement. The intent of page flipping is to reserve several
different sections of RAM for screen memory, each with its own
display, and 'flip' from one section to another simply by changing the
address bytes of an LMS instruction. One can flip whole screens or
parts of screens depending on where the LMS instruction is placed in
the display list. This technique is useful for animation or providing a
BOX 8
Atari Graphics 97
,
BOX9
~
1'"
20
30
40
50
60
70 GO TO 3121
Color
Another facet that distinguishes the Atari Home Computer from
other popular computer systems is the greater number of colors
available. One reason for the larger color selection is that in an Atari
one can choose a luminance and a hue to produce a color rather than
simply specify just a color number. Luminance can be thought of as
OPERATING SYSTEM
HARDWARE
LABEL
PCOLRO
ADDRESS
704
Player 1
PCLOR1
705
COLPM1
53267
208
19
Player 2
PCOLR2
706
COLPM2
53268
208
20
Player 0
LABEL
COLPMO
Player 3
PCOLR3
707
COLPM3
53269
208
21
Playfield 0
COLORO
708
COLPFO
53270
208
22
Playfield 1
COLOR1
709
COLPF1
53271
208
23
Pl ayfield 2
COLOR2
710
COLPF2
53272
208
24
Playfield 3
COLOR3
711
COLPF3
53273
208
25
Backround
COLOR4
712
COLBK
53274
208
26
Atari Graphics 99
I~I'-~t
I I I I I I ~
I
t
not used
Hue nibble
Luminance
Taken as a group of four bits, the hue nibble can have any value
between 0 and 15. Corresponding to these numbers are the hues listed
in Table 3-7. To POKE, or store a hue value in the left four bits of an 8
bit color register it is first necessary to mUltiply the decimal value (0 to
15) by 16 (see Table 3-7). Luminance is determined by bits D1 to D3 of
the color register. Since bit Do is not used, luminance is effectively
determined by the even numbers 0 through 14 with fourteen being the
highest luminance and therefore the brightest. To set these bits in a
color register simply add the luminance value to the appropriate hue
number:
COLOR NUMBER
NIBBLE VALUE
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
POKEORSTOREVALU~
16
32
48
64
80
96
112
128
144
160
176
192
208
224
240
Table 3-8. Displa y modes with ava il ab le number of co lors a nd default colors
NUMBER
OF
COLORS
DISPLAY
MODES
SHADOW
COLORS REGISTERS
DEFAULT
709
710
712
TWO
COLORS
BASIC 4,6
ANTIC 12
Orange
Black
708
712
FOUR
BASIC 4,6
3,5,7
Orange
LtGreen
ANTIC 14
Blue
Black
708
709
710
712
Orange
Lt Green
Blue
Red
Black
708
709
710
711
712
COLORS
BASIC 1,2
FIVE
ANTIC 4,5
COLORS
..
NOTES
Regist. determ .
Background
Border
COLOR 1
Background
(COLOR 0)
COLOR 1
COLOR 2
COLOR 3
Background
(COLOR 0)
BASIC 1 &2 color
GTIA Modes
Graphics Modes 9, IO and 11 are enhancements of Graphics 8 that
give extended color choices. Briefly, Graphics 9 allows 16 luminances
of one hue; Graphics 10 allows the selection of nine colors; Graphics II
allows 16 hues with one luminance . These Modes are referred to as
GTIA Modes because their appearance on the screen is determined,
not by an instruction in ANTIC's display list, but by the setting of bits
D6 and D7 in the GTiA hardware register PRIOR (53275).
Bit: 0 7
0 6 Mode
U Determined by ANTIC's DL
1
Mode 9
o Mode 10
Mode 11
07
06
Os
04
03
O2
0,
Do
I
~~
Hue Nibble
Luminance Nibble
0 0 0 0 Hue 13 Ok Green
o 1 0 Luminance 6
0 1 1 0 Display color #
But suppose the value stored in 712 inadvertently had some extra bits:
register 712
Pixel Data
o
o
1
1
01 Hue13 Ok Green
0 Luminance 6
Display Color #
Because of the way a logical OR works (see Box 3), the final luminance
value is IS, not 6 as originally desired.
Graphics II works analogously to Graphics 9 except that now the
luminance value is taken from Bits D1 - D3 of color register 712. Since
Do is not used, there are only eight luminances. The hue value used in
plotting is specified with a COLOR N, or POKE 200,N statement,
where N is a number from 0 to 15. Table 3-7 lists colors and their
corresponding number. Again the final color number is obtained by a
logical ORing of the hardware register a nd the pixel data. This time,
the color register should be set up with zeros in the left hand nibble so
that the ORing doesn't modify the final color data.
Graphics 10 makes use of all nine color registers 704 - 712 (53266
-53274). The color number is derived in the usual manner:
COLOR NO. = HUE *16+LUMINANCE
Registers 708 through 712 can be set with either the SETCOLOR
command or a POKE. Color in registers 704 through 708 must be set
with POKE statements. Colors to PLOT or ORA W with can be chosen
with COLOR N or POKE 200,N. However, now N is restricted to 0 to
8. Zero selects 704, one selects 705, and so on. Numbers from 9 to 15
will select one of the lower value color registers.
The GTIA Graphics Modes will run very much the same way as
other display modes. This means that you can use standard graphics
commands, player / missiles , and the full set of ANTIC options .
A Digression
When one gets involved in programming in BASIC or another
higher level language it is easy to lose sight of what's going on at the
machine level when a sequence such as,
10 COLOR 3
20 PLOT O,O:DR. 40,40
is executed. Suppose you are working in Graphics 10. Then the above
two lines will cause the execution of a number of subroutines that will
store the bit pattern 0 101 into screen memory in such a way that when
the screen memory is accessed by ANTIC, a colored line is displayed
diagonally on the screen. In the other display modes how the data in
screen memory is interpreted differs from the GTIA Modes but the
idea is the same. Screen memory contains information that is read and
interpreted by ANTIC and GTIA. At this point we would like to
remind you that there is absolutely no reason why you have to rely
entirely on BASIC commands such as PRINT, PLOT, DRA WTO,
and the OS to place data into screen memory. The two programs in
Box II illustrate this point. Program A draws a diagonal line with
PLOT and DRAWTO. Program B usesa FOR NEXT Loop to put the
data that generates the line directly into screen memory.
If you think back to the exercise we proposed with the ANTIC 14
display list, there is a problem using the OS's routines for PLOT and
DRA WTO . POKEing 87,7 gives you four color graphics, but limits
you to using only half the screen . The above discussion provides a clue
to one approach to using ANTIC display modes; write routines that
place display data directly into screen memory.
r
10
20
30
40
50
BOX 11
"""
GRAPHICS 10
POKE 704,144:POKE 707 , 88
COLOR 3
PLOT 0,0:DRAWTO 40,40
GOTO 50
r
10
20
30
40
50
60
..J
BOX 11B
""
GRAPHICS 10
POKE 704, 144 :POKE 707,88
START=PEEK (88) +PEEK(89)*2 56
FOR 1=0 TO 39
POKE START+41*I , 3: NEXT I
GOTO 60
~
Box 11B. Method of Displaying
.J
Artifacting
Artifacting is a method of putting color on the TV screen that
depends on three things: (I) how the TV produces color; (2) how the
human eye interprets combinations of color; and (3) the two to one
relationship between machine cycles and color clocks in the display
modes BASIC 0,8 and ANTIC 3.
To produce color, the inside of a color television screen is coated
with an array of dots that glow in red , green, and blue when struck by
electrons. By controlling the brightness of each dot, it is possible to
produce any desired color. At normal viewing distances, the dots are
too small for the human eye to perceive individually and so the colors
appear to merge into a single image.
The signal sent to a color television set is called a composite video
signal. It consists of horizontal and vertical synchronizing pulses ,
brightness information (luminance), and a 3.58 MHz "subcarrier" that
contains color information (chrominance) . This 3.58 MHz frequency
is a standard value designed into color TV circuitry. Incidentally, if
you divide 3.58 MHz by 2, the result is 1.79 MHz, the frequency of the
Atari CPU. In the composite video signal, the luminance is the
primary signal. Whenever the luminance changes it forces a phase shift
or timing change in the color signal. The phase or timing of the
chrominance signal is crucial to determining the color displayed. If the
luminance is changed on a whole color clock boundary, the color is
unaffected. However, ifthe luminance is changed on a half color clock
boundary, it will affect the colors. This is the reason that artifacting is
used in those modes that have one color, two luminances and a pixel
width of one-half color clock. Box 12 is a short program that illustrates
artifacting.
BOX 12
Artif&cting
5 REM ** ARTIFACTING **
20 GRAPHICS 8:SETCOLOR 2,0,0
30 COLOR 1
40 REM * DRAW A SERIES OF VERTICAL BARS *
50 FOR 1=1 TO 315 STEP 4
60 PLOT I, 10:DRAWTO 1,100
70 NEXT I
80 REM * REM DRAW VERTICAL BARS SHIFTED ONE HALF COLOR CLOCK
*90
CHARACTER
DATA BYTES
0 0
0
0
0
1
()
0 ,
0
0
0
()
0 0
Now you can see why each character occupies eight bytes in memory.
There is one byte for each row of pixels. The spacing between lines of
print on the screen is made by leaving the top and bottom rows of the
grid unlit. There are spaces between characters only if you construct
them that way. Thus, you may build up large pictures by combining
characters.
There are four basic steps to follow when redefining characters.
These are:
11000000
1100000
o , 1 1 0001
o 1 1 1 1 1 10
0011 0000
00011 000
00 d 11 001
00011
001
128 +64
128t64t32
I
64132+16
64'32.1618.4,2
32 t 16
16.8
.1
1618
16.8
192
" 224
~ 112
=126
'48
24
.24
+1 .24
the pixel lit, type 'N' and the '0' is erased. After running through a grid
you may edit and then print out the data.
Step 2: Move the standard character set from ROM to RAM.
Strictly speaking this step is necessary only if you intend to use some of
the standard characters. In BASIC this is done by PEEKing each ROM
location from 57344 to 58367 (in BASIC Modes I and 2 from 57855 to
58367) and POKEing the value into a RAM location. Before doing this
you must reserve a safe place in memory. As we discussed in the section
on display lists one way to secure a safe location is to lower RAMTOP.
BOX 13
Utili ty P"'OQra/ll
**
**
5 REM
CHARACTER GENERATOR
HI DII'1 D (8)
::I~ OPEN #2,4, 0, "f<: "
:3111 GRAPH I CS 2
35 REM
DISPLAY GRID
40 FOR J=l TO 8:FOR 1=6 TO 13
5el POSITION I,J:? +16;"0"
6111 NEXT I: NEXT J
70 PRINT "TYPE Y FOR PIXEL LIT"
8Ji1 PRINT
9111 PRINT "TYPE N FOR PIXEL OFF"
100 FOR J=1 TO 8:FOR 1=6 TO 13
110 POS I T I ON I, J:? +16; '":' ''
120 REM
GET USER'S CHOICE AND COMPUTE DATA NUMBERS
130 GET +l2,CHOICE
140 IF CHOICE=ASC ("Y") THEN GOTCJ 56111
150 IF CHOICE=ASC("N") THEN POSITION I,J:? +16;" " :GOTO 170
16111 GOTO 120
170 NEXT I
180 D(J)=DECICODE
190 DEC I CODE=~~
200 NEXT J
210 REM
GIVE USER A CHANCE TO EDIT
220 PRINT :PRINT
230 PRINT "EDIT LINE ( Y, N ) "
240 GET +12, ED IT
2~0 I F ED IT=ASC ( "Y" ) THEN GOTO 611~
260 IF EDIT=ASC ("N") THEN GOTO 290
27121 GOTO 240
280 REM
GIVE USER AN OUTPUT OPTION
PRINT :PRINT
BOX 13 continued
Internal Char.
Codes 0 - 127
Normal Video
Internal Char.
Codes 128 - 127
Inverse Video
00
01
10
11
COLBAK 712
PFO 708
COLBAK 712
PFO 708
PF1 709
PF3 711
PF1 709
PF2710
LIGHT
SLUE
~
ELLOW
00
01
10
11
COLBAK
PFO
PF1
PF2
00 01 01 01
00 01. 01 01
10 10
10 10
10 10
JO 10
10 11
to
11
10
10
10
10
'\0 10
10
10
10 1 1
10 1 1
712
708
709
710
LT . BLUE
DARK BLUE
YELLOW
RED
000 I 0 I 0 I
000 I 0 10 I
21
21
170
170
I 0 I 0 I0 I 0
I 0 I 0 I 0 I 0
I 0 I 0 I 0 I 0
170
10/0/010/70
101 I I 0 I I
187
101 I 101 I
187
BOX 1:S
Uti 11 ty ProQralll
'"
480
490
500
51121
52121
530
54121
550
560
5712l
58121
59fZl
6121121
61121
62fZl
63fZl
64121
65121
66121
670
68121
69121
700
71121
72121
73121
74121
75121
760
77fZl
78fZl
79fZl
80121
81121
82fZl
830
84121
850
86121
870
880
890
13
AND COMPUTE DATA NUMBERS
920
POSITION I,J:? "6, "121": GOTO 53fZl
DN(J)~DECICODE
DECICODE-12l
NEXT J
REM * GIVE USER A CHANCE TO EDIT *
PRINT :PRINT
PRINT "EDIT LINE?
(YIN) "
GET "2, ED IT
IF EDIT-ASC ("Y") THEN 97121
IF EDIT=ASC("N") THEN 65fZl
GOTO 6121121
REM * GIVE USER AN OUTPUT OPTION *
PRINT :PRINT
PRINT "PRINT TO SCREEN OR PRINTER? (PIS)"
GET "2,CHOICE
IF CHOICE-ASC("P") THEN 760
IF CHOICE'"ASC("S") THEN 71121
GOTO 670
PRINT :FOR pool TO 8:PRINT DN(P),","I
NEXT P
GOTO 84121
REM * OUTPUT TO EPSON PRINTER *
REM * YOUR FORMAT MAY DIFFER *
OPEN *3,8,0,"P:"
FOR P"l TO 8
PRINT *3,DN(P),
PRINT "3," '"
NEXT P
PRINT .. 3
CLOSE *3
PRINT :PRINT
PRINT :PRINT
PRINT "C TO CONT. OR Q TO QUIT"
GET "2,OPTION
IF OPTION-ASC("C") THEN 390
IF OPTION-ASC("Q") THEN 9121121
GOTO 86121
END
REM ALGORITHM TO COMPUTE DATA NUMBERS
POWER-INT2 (l3-I+f2I. l):POSITION I,J:?
A
930
940
950
960
970
980
990
DECICODE=DECICODE+POWER
IF FLAG=1 THEN 1070
GIJTIJ 530
REM EDITING ROUTINE
TRAP 970:PRINT "TYPE LINE NUMBER (1-8)"
INPUT J
FLAG=1
10m0 TRAP 4011100
11~1I/1 FIJR 1=6 TO 13: POSITION I, J: 7 116,"''': NEXT
1020 FOR 1=6 TO 13:POSITION I,J:7 116;"7"
1030 GET 112,CHOICE
1040 IF CHOICE-ASC("I") THEN 920
111!~11I IF CHOICE=ASC("0") THEN POSITION I,J:? l+6,"0":GOTO 111!7!1l
1060 GOTO 1030
11117111 NEXT I
1080 FLAG-0
109111 DN(J)=DECICODE
1100 FLAG-0:DECICODE=0
1110 GOTO ~90
1120 REM
1130 REM
5000 FOR 1-1 TO 10
~01111 PLOT Q,~0+I:DRAWTO Q+~,51/1+I
502121 NEXT I
503111 RETURN
PO - P3 and four missiles , MO - M3. Missiles are columns that are two
pixels wide. Each missile is associated with the player of the same
number by the simple technique of having both ofthem the same color.
The four missiles can be combined to form a fifth player. In order to
combine the four missiles into a player the bit D" of PRIOR (53275)
must be set. This may be done by POKEing 16 into its shadow register
at memory location 623. This sets the "fifth player enable bit". However,
using the fifth player from BASIC is clumsy since each missile retains
its own width and horizontal position. Consequently, moving the fifth
player horizontally entails four POKEs, one for each missile. The only
feasible way to utilize this option is to program the movement in
machine language.
Organization of player memory so that it represents a column on
the screen greatly simplifies movement of an image from one place to
another. Horizontal positions can be changed with a simple POKE or
ST A. Vertical positions can be changed with a short, efficient machine
language routine. The result is that animation can be accomplished
more smoothly and more rapidly than if you were moving bytes
through the normal screen memory.
PM graphics works like the normal BASIC character set graphics
in that bit mapping is used to display a pattern. As usual, "I" equals
pixel on and "0" equals pixel off. Player and missile pixel sizes can be
varied. There are two choices of vertical resolution: one scan line, (256
byte player) or two scan lines , (128 byte player). Normal horizontal
resolution of the players is eight color clocks. There is the option to set
individual players to widths of sixteen or thirty-two color clocks. The
widths of all missiles is set the same: either two, four, or eight color
clocks. Colors for each player and its associated missile are taken from
the four color registers 53266 - 53269 which are shadowed at 704
through 707.
Part of the complexity of PM graphics revolves around the fact
that there are over thirty registers or memory locations that can be
used to implement various options. In addition, some of these registers
have dual functions. To impose some order on this chaos, we have
prepared two tables that list the registers and their functions. Table
3-10 lists the general PM graphics control registers. Table 3-11 lists the
hardware registers that serve dual functions.
559 (shadow)
DMACTL
54272 (hardware)
00
o1
10
11
O 2 Missile DMA
no playfield
narrow playfield
standard playfield
wide playfield
0= disable
= enable
0 3 Player DMA
0= disable
1
enable
0 4 P/M Resolution
0 5 DMA Enable
= 1 scan
line
GPRIOR
623 (shadow)
PRIOR
53275 (hardware)
This register selects which parts of the screen display wi II have priority
and allows several other options. Bit assignments are as follows:
continued on next page
BIT
Do, if set :
0" if set:
O2 , if set:
0 3, if set:
0-3/ Background
0-3/ Player 2-3/ Back0-3/ Background
0-3/ Playfield 2-3/
0 4 , if set:
Os, if set:
6
}
07
COLOR
704-707
53266-53269
GRACTL
53277
Graphics ConTrol.
To turn on missiles set bit Do
To turn on players set bit 0 1
54297
This location, in pages, of the Player/ Missile shape data. See discussion
in text on how player miss ile memory is organized.
DECIMAL
(R)=read
HEX
HPOSPO
53248
0000
53249
0001
53250
0002
53251
0003
M2PF
HPOSP3
53252
0004
53253
0005
53254
0006
P1PF
HPOSM2
POPF
HPOSM1
of player 3
(R) missile-playfield collision
M3PF
HPOSMO
M1PF
HPOSP2
MOPF
HPOS1
FUNCTION
P2PF
HPOSM3
53255
0007
P3PF
MOPL
53256
0008
SIZEPO
M1PL
53257
0007
53258
DOOA
SIZEP2
M3PL
53259
0008
53260
DOOe
SIZEP3
POPL
SIZEM
GRAFPO
53261
DODD
P1PL
GRAPFP1
SIZEP1
M2PL
53262
P2PL
DOOE
GRAPFP2
53263
OOOF
P3PL
GRAPFP3
53264
0010
TRIGO
(644)
GRAPFPM
53265
0011
TRIG1
COLPMO
53266
0012
(704) color/luminence of
player/missile 0
(R) joystick trigger 2
TRIG2
(646)
COLPM1
TRIG3
(647)
53267
0013
(705) color/luminance of
player/missile 1
(R) joystick 3 trigger
Sketching the light bulb and calculating the data numbers is the
same procedure as with character sets. The major difference between
the two is that you can have many more data bytes per player than per
character.
DATA
NUt-l8ERS
60
12E>
255
255
12b
60
24
24
24
r-PM BASE-
r---- PMBASE
UNUSED
MAY BE USED FOR
MACHINE LANGUAGE
ROUTI/\/ES, ETC
384
BY rES
768
BYTES
PM BASE-t 384
M3IM2IMIIM
512
31 M 21 M I 1-1.1 9'
PM BASE t
t
1024
640
1280
1 768
15-36
1896
11742
-t
.,. 1024
2.048
2 LINE
RESOLUTION
PLAYER- MISSILE
768
MEM OR Y
LINE
RESOLUT ION
MAP
Line 140 turns the player off by resetting Direct Memory Access to
playfield DMA only, and clearing GRACTL. Both changes must be
made in order to clear the player from the screen. An alternate method
of disposing of an unwanted player is to store it off the edge of the
screen. Try changing line 140 to:
POKE 53248,0
6 0 FOR 1=1 TO 9
70 READ D:POKE PBASE +562 + I,D
B I~ NE XT I
9 ,,1 POKE 5 3 248, 12 0:REM SET HORI ZON TA L POS ITION
101i1 POKE 704,BB:REM * SET THE COLOR *
11~5 REM TURN ON THE PLAYER
110 POKE 559,46:POKE 5 3 27 7 ,3
12 111 DATA
\..
~ 4, 2 4, 24
Table 3-12 gives the bits set and the values returned when ' a
collision occurs. Keep in mind that the value returned by a PEEK
statement is the decimal equivalent ofthe binary number expressed by
bits Do to 0 3 . Because ofthis , the value returned will depend on how
many different collisions have occured since the last 'hit clear',
Table 3-12 .Collision Detection
COLLISION DETECTION
VALUE RETURNED BY PEEK
MISSILE TO PLAYFIELD
REGISTER
53248
53249
53250
53251
MISSILE
COLOR 1
COLOR 2
COLOR 3
MO
M1
M2
M3
1
1
1
1
2
2
2
2
4
4
4
4
2
2
2
2
4
4
4
4
53252
53253
53254
53255
PO
P1
P2
P3
1
1
1
1
MISSILE TO PLAYER
53256
53257
53258
53259
MISSILE
PO
P1
P2
P3
MO
M1
M2
M3
1
1
1
1
2
2
2
2
4
4
4
4
8
8
8
8
53260
53261
53262
53263
PO
P1
P2
P3
0
1
1
1
2
0
2
2
4
4
0
4
8
8
8
=2
=8
53263 = 10
collision register values change. These changes are a result of the color
registers, ie. the playfield registers, used to display the * and the text
window.
This illustrates another aspect of collision detection - the
values returned depend upon the color registers being used (registers
708-712) but not on the color values in the registers. Recall that in a
sense playfields are synonymous with color registers. Thus a multicolored
character in ANTIC Mode 4 or 55 could return a different value
depending on which part of the character was overwritten.
BOX 17
1 REM ** COLLISION **
5 PRINT CHR$(125)
10 DIM MOVE$(21):DOWN=ADR(MOVE$)
15 A=PEEK(106)-8:POKE 106,A
20 POKE 54279,A
30 PB=A*256
35 FOR CM=PB+512 TO PB+640:POKE CM,0:NEXT CM
40 X=120:V:z20
50 FOR P=1 TO 9:READ D:POKE PB+512+V+P,D:NEXT P
~5 DATA 60,126,255,255,126,6121,
24,24,24
60 POKE 53248, X
70 FOR I=DOWN TO DOWN+20
75 READ S:POKE I,B:NEXT I
80 DATA 104,104,133,204 , 104 , 133,203
85 DATA 160,2~,177,203,200,145,203
90 DATA 136,136,192,255 , 21218,245,96
100 GRAPHICS 2:POKE 704,88
105 POS I T I ON Iii, 8: 7 "6;" MMMMMMMMMMMMMMMMMMM"
110 POSITION 121,9:7 "6;"*******************"
120 POKE 559,46:POKE 53277, 3
125 POKE 53278,255
130 ST=USR(DOWN,PB+511+V):Y=Y+1
13~ PRINT PEEK(53252)
140 IF PEEK(53252)=4 THEN GOTO 150
145 FOR 1=1 TO 25:NEXT I:GOTO 125
15121 7 PEEK(53252):SOUND 1,2@,0,14:S0UND 2,255,10,15
165 FOR 1=1 TO 300:NEXT I
170 SOUND 1,0,0,@:SOUND 2,0,0,121
When you have one or more objects on the screen, you may want
to hide one behind the other. If one of the objects is moving, this can
add a three dimensional quality to the picture. The Atari operating
system has a register at 623 (GPRIOR) that is the shadow register for
PRIOR at 53275 which controls display priority among the players
and playfields. As you can see from table 3-10, PRIOR controls
several unrelated functions. However the lower four bits Do to D3
control display priority. On power-up bit is set and players have
priority over the playfields and backround. The backround always has
the lowest priority. Setting bit 1 POKE 623,2) gives players and 1
priority over playfields and over players 2 and 3, but the playfields
have priority over players 2 and 3. The remaining priorities may be
found in table 3-13. The bits in PRIOR are mutually exclusive . This
means, theoretically, you can only set one of the bits Do to D 3 . In a
mutually exclusive situation, turning on more than one bit causes the
bits to be in opposition. When the priority bits are opposed and any of
the objects displayed overlap the display turns black in the overlapping
area.
Finally, if you have established priority between players and
playfields, the collision registers respond in the usual manner. Hence,
when two objects are on the screen at the same time and place a
collision will occur whether or not you see it and this is duly recorded
by the collision registers.
To see priority in action add the following lines to the program in
box 17:
When you run the program with this addition you will see that the
playfield #'s have priority over the light bulb so that the bulb appears to
pass behind the #'s.
GPRIOR @623
07
06
Os
03
04
00
01
O2
""-
priority select
BIT
Set by
PRIORITY CONTROL
POKE 623.
0
Within the group of players, lower numbered players have priority over
higher numbered players .
A lower numbered playfield has priority over higher numbered
playfields .
4
Getting Started in Machine Language
Programming
Introduction
After the previous three chapter's lengthy introduction to the
fundamentals of machine language and Atari graphics, it is time to get
started on some programming examples using machine language
subroutines. There are three ways in which such a subroutine can be
integrated into a BASIC program: (1) Flags set in one or more
hardware registers can cause the CPU to jump to a short subroutine;
(2) A machine language routine can be called by a BASIC USR
command; (3) Through a process called vector stealing, a subroutine
can be added to the normal tasks carried out by the operating system
during the vertical blank . The first of these three methods, flag setting,
is used by display list interrupt routines. The BASIC USR command is
useful for all sorts of routines such as moving players, clearing sections
of memory, and redefining characters sets. Using vector stealing to
insert machine language routines into the vertical blank is valuable in
fine scrolling and music. We shall begin the discussion of actual
135
BOX 18
Dlsplay Llst Interrupt
One Color Change
\...
DECIMAL VALUE
FUNCTION
Once the machine language program has been read into memory
(line 20) it is necessary to set up the proper conditions to have it
implemented. This consists of setting the DLI bit (D?) in the display
list instruction of the mode line before the one at which you want the
change to occur. Then you must tell the OS where to find the DLI
service routine by putting its starting address in 512 and 513. The final
jo b is to set bits 6 and 7 of hardware register 54286 by PO KEing in 192.
A DLI may be turned off by a POKE 54286,64.
In the previous chapter we discussed the problem of providing a
safe place for display lists, player-missile memory, and character sets.
It is of prime importance to store machine language routines where
they are not going to be overwritten by BASIC. Nothing makes a
program crash faster than a machine language routine missing an R TS
or some other vital instruction because it was overwritten with another
part of the program. One option for storing machine language routines
is to use page six (1536-1791) of memory. It has been pretty well documented
that some cassette 110 can write over the first half of page six (15361664). Consequently, if you are using cassette storage, only page six
locations 1665-1791 are safe . If you use disk storage all of page six is
safe. Later we will discuss other techniques for storing or setting aside
a safe place for machine language routines .
Display list interrupts are most advantageously used in situations
where there is an OS shadow register associated with a hardware
register. The reason for this is that during each vertical blank, the OS
uses the value in the shadow register to update the corresponding
hardware register. With a DLI you can change the number in the
hardware register. Using color as an example, you effectively partition
the screen so that the
OS controls
things her ..
DLI control,.
things h .. r ..
Of course, one doesn't have to split the screen in half. You can place a
DLI on any or all mode lines. This means that you do not have to rely
entirely on shadow register / hardware register pairs in using DLIs.
With the inclusion of a D LI in one of the three blank line instructions
at the top of ANTIC's display list, any change made in a system register
while the electron beam is partway down the screen can be restored
before the start of the drawing of a new display.
The program in Box 18 makes a single color change at a single
location on the screen and serves to illustrate the use of PHA, LDA,
ST A, PLA, and RTI. There are three good ways to build on this simple
program . One is to make up to three color changes during one
interrupt routine by using the accumulator, the X and Y registers. A
second course is to use mUltiple DLI routines. The final method is to
use DLls to access a table of color values.
The program in Box 19 makes changes in two color registers and
one control register. It illustrates the use of several commands: TXA,
TYA, LDX, LDY, STX, STY, TAY, and TAX.
Box 19. Display List Interrupt Two Color Changes / Text Inversion
r
BOX 19
168,104,17~,104,64
LOA #146 .... .... 169,146 ....... Load accumulator with the
number for medium blue
LOX #42 ....... ..162,42 ...... ..Load X-register with the
number for yellow
LOY #6 .. ........ 160,6 ....... .. Load V- register with #6
Section III: Wait for the horizontal blank. Store colors.
STA WYSNC ...... 141, 1O,212 ...... Wait for horizontal blank
STA Color1.. .... 141,26,208 ...... Medium blue to background register
STX Color2 ...... 142,22,20B ...... Yeliow to foreground register
STY Control. .... . 140,01 ,212 .... ..Change character mode control
Observe that the order in which the values are recalled from the
stack by the PLA statements in Section IV is the reverse of the order in
which they were pushed onto the stack by the PHA commands in
Section I. This illustrates the last-in-first-out nature of the stack. You
should also note that there are no instructions that pull values from the
stack directly into the X and Y registers. Rather, one must restore these
registers in a two step process involving the accumulator and the
transfer instructions TAX, T A Y. As a final comment on this program,
observe that the load instructions use the immediate mode of addressing
and the store instructions use the absolute mode of addressing.
Suppose that you plan a screen display using several DLIs, each
doing a different job. You write the service routines and store them in
page six. But how do you tell the CPU where to find the proper service
routine for each interrupt when there is only one place to store a
starting address? The solution is to have each service routine put the
starting address for the next routine into 512 and 513. Box 20 is a very
simple program illustrating linking one routine to the next. The
program changes the background color of a Graphics 18 screen twice,
first from light blue to pink and then to gold.
BOX 20
The two service routines are in the data lines 30 and 40. With some
counting you can see that the first routine is stored from 1536 through
1551 and the second from 1552 through 1568. Therefore, the starting
address for the first routine in Lo-Byte / Hi-Byte order is 00, 06; for the
second routine, 16, 06 . The structure of the two routines is the same.
The assembly listing of the first routine follows . You should write out
the listing for the second routine for practice.
MNEMONIC
DECIMAL VALUE
FUNCTION
Column II
PHA
PLA
TAX
TAY
TXA
TYA
RTI
LOA
LOX
LOY
STA
STX
STY
addressing modes ; LDX and LDY each have five addressing modes;
while STX and STY have three, and ST A has seven. Recall that
addressing modes determine how the CPU locates data that is
retrieved from memory or how it locates where data is to be stored.
The large number of addressing modes provided by the 6502 processor
is an advantage in machine language programming because it allows
the programmer more options in writing code for a given task .
In Boxes 18 , 19, and 20 the ST A, STX , and STY instructions use
absolute addressing. The LDA, LDX, and LDY instructions use either
the immediate mode of addressing or absolute addressing. These two
addressing modes are used a great deal in machine language programs
and will rapidly become very familiar to you. On the other hand, they
both suffer from a severe limitation. Neither of these modes is useful
for retrieving data from , or storing data in, an array or table .
Many of the tasks carried out by machine language routines
involve either moving blocks of data called strings or arrays, or
manipulation of data stored in a table. Since these are very common
programming jobs, they are one of the first things that a beginning
assembly language programmer should master. Both arrays and tables
are stored in contiguous memory locations . Very often what is
required is to move a block of data from one location to another or to
access the items in a table in sequential order. Since the 6502 is an 8 bit
processor, these manipulations occur one byte at a time . As a
consequence, the program structure usually is a loop that cycles as
many times as there elements in the array.
The DLI routine in Box 21 illustrates the basic elements needed to
repeatedly loop through a table. In the program, six display list
interrupts are written into a Graphics 2 display list. At each interrupt,
the routine loads a color number from a table of values and puts it into
the background color register. In order to do this properly, the
program needs a way to keep track of its position in the color table and
needs to determine when it has reached the end of the color table. The
first task is handled by using a pointer and indexed addressing. The
second by a compare and branch sequence.
BOX 21
Display List Interrupt
Color Tabl e
The service routine, pointer, and color table have been loaded
into page six as follows:
31 bytes of machine language routine at locations 1536
through 1566 .
The pointer at location 1567 .
6 bytes of the color table at 1568 through 1573.
The service routine may be split into sections as follows :
Section I: Save registers to stack and increment the pointer.
MNEMONIC DECIMAL VALUE
FUNCTION
PHA
72
TXA
138
PHA
INC POINTER
72
238,31,6
This last instruction is carried out each time the interrupt is used. The
pointer was initialized to 31 in line 50 of the program so that when the
first DLI is encountered, this instruction will increment the pointer to
32, the Lo-Byte of the first color number's address.
Section II: Load the X-register. Get the color value.
LDX POINTER
174,31,6
LDA ADDR,X
189,0,6
When the LDA command is executed, the zero in 0,6 is added to the
value in the X-register to get the Lo-Byte of the address of the color
number in the table .
Section III: Change the color register
STA WSYNC
141,10,212
STA COLREG
141,26,208
CPX NUM
224,37
BNE END
208,5
If the result of the CPX command is not equal to zero, the program
jumps ahead to restore the X-register and then returns from the
interrupt , thus by-passing the next two instructions .
Section V:
LDA RESET
STA POINTER
169,31
141,31,6
END PLA
104
TAX
170
PLA
104
Restore accumulator
RTI
64
Program Listing
Before proceeding with the development of programs let's briefly
consider some conventions used for writing assembly language
programs. If you are familiar with more than one higher level
language, such as BASIC, PASCAL, and FORTRAN, then you know
that each language has rules as to how to construct a program - line
numbers, special punctuation, and things of this nature. Strictly
USR
The USR command is one of the handiest ways to integrate
machine language subroutines into a BASIC program . The command
is structured so that parameters can easily be passed from the BASIC
program to the subroutine. The USR command has the format:
D U MMY=USR(ADDR,parameter 1,parameter 2.. .)
BOTTOM OF
STACK
Strings
The USR and Atari BASIC's string handling capabilities provide
a good way to store machine language routines safely within a BASIC
program. The idea is to translate the decimal numbers representing the
subroutine into AT ASCII characters and store these in a string. As
we'll see shortly, the routine can be easily addressed by USR.
Storing machine language routines in strings has several advantages.
First, it avoids memory management problems by turning the job over
to BASIC. Second , the length of the machine language program is not
limited as it is with page six storage . Third, the string method of
storage is more efficient in terms of time and space. Spacewise, the
data for the machine language routine is stored as at single symbol in
the string rather than as a sequence of numerals and commas.
Timewise, efficiency is achieved because string storage eliminates
time-consuming READ and POKE sequences such as those in lines 50
to 90 of Box 14.
Our next program combines many of the ideas discussed so far in
this chapter into one example. In this program (Box 22), machine
language routines are used to speed up redefinition of the character set
in program 14. The machine language routines that move and redefine
the standard character set are stored as strings in lines 30 and 40. Also,
the data used to redefine the characters as a cat is stored as a string in
line 50. These simple changes in program 14 yield a fantastic increase
in execution speed, as you will see when you type in and run the
program.
Storing subroutines in strings does entail some extra steps and
occasionally a little inconvenience . Consider the subroutine MOV$
which consists of twenty decimal numbers. To store these as a string it
is necessary to convert the decimal numbers into character symbols
using Appendix E. As an example, for the first four numbers of
MOV$:
DECIMAL #
KEYSTROKE
RESULT
104
162
160
inverse"
CTL D
inverse space
I.
BOX 22
Storing Characters as a String
Cat
pmE
21~5,I_OQ:
POf': E
~'1116,
~C)
listing and write a separate listi ng for the machine language routine
using the notation defined in Box 23.
+MOV$ +
DECIMAL .oft
104
KEYSTROKE
RESULT
162
~
III
160
177
205
145
CLD
CL,
OJ
81
ICLQI
[i)
12
DECIMAL
203
200
208
249
230
20E-
230
204
KEYSTROKE
[]
[ill
[ill
[f]
[IJ
II
II!
[ZJ
lD
[]
RESULT
[f]
Iii
(!]
202
208
0
D
203
200
DECI~AL
KEYSTROKE
RESULT
+
DECIMAL
104
KEYSTROKE h
242
CL.
1M
REOEF$+
160
177
205
145
CL,
IT]
[0
ICLQI
[2J
iii
12
[3
ill
RESULT
DECIMAL
192
144
208
247
KEYSTROKE
ICLPI
@l
[g
RE SU LT
%
CL
CI
+LEGENO+
CL = conTrol
SP = spoCO
E. C, C=
QSC~Q
v id eo
ADDR I
f+-
START 57344
TO BE
DATA
NOVED
~
ADDR 2
j~
58367
5 TART
39936 (At 4)
T ARG E T
AREA
I~
I -~ EN D 4 09 :' 9
You also need a way to determine when you have moved all your data.
There are several ways to solve each of these programming problems
and sometimes they can be handled simultaneously by use of indexed
addressing. Such is the case here, where we want to move 1024 bytes of
character data from ROM to RAM. The source and target addresses
can be handled with indirect indexed addressing which makes use of
the Y-register and two page zero locations. The page zero locations
hold the Lo-Byte and Hi-Byte of a base address to which the current
value in the Y-register is added. The resulting value is used to
determine the location of the data for the LDA or the target for the
ST A. In MOV$, locations 205 and 206 are used to hold the base
address for the LDA. Locations 203 and 204 are used to hold the base
address for the ST A.
The assembly language listing of MOV$ is in Box 24. The first
instruction, PLA, removes the top number from the stack. This
number is the parameter count in the USR function ( in this case 0).
The next two instructions, LDX and LDY, load the X and Y registers
with values used in the looping. The Y-register serves a dual purpose
-as an index register and as a counter for the inner loop. We have to
move 1024 data bytes. However, an 8-bit register can count only 256
values . As a result we need to cycle through the inner loop four times.
Decrementing the X-register down to zero counts these cycles.
This explains the general structure of the program. There are a
couple of remaining details. The two BNE instructions depend on the
zero flag being set when the Y-register "rolls over" to zero and the
X-register is being decremented to zero. Finally, the two INC's
increment the base addresses to the next higher page when 256 bytes
have been moved .
REDEF$ moves the data stored in CHAR$ into the character set
that was stored in RAM. This subroutine is similar to but simpler
than MOV$ so we will leave it to you to figure out the details. The
assembly language listings are in Boxes 25, 25A, and 25B.
Box 24
MOV$
203,206 Base Address (where to get it)
203,204 Base Address (where to put it)
LABEL
MNEMONIC
OPERAND
PLA
OPCODE
OPERAND
NUMBER
NUMBER
104
LOX
#4
LOY
#0
LOA
(ADDR1),Y
162
COMMENT
LOOP
(205),Y
STA
(ADDR2),Y
145
(203),Y
INY
200
Increment Y to point to
next byte
ENDLP1
BNE
LOOP
208
249
INC
206
230
206
INC
204
DEX
230
204
202
ENDLP2
BNE
RTS
LOOP
208
96
242
REDEF$
Less than 256 Bytes
LABE L
MNEMONIC
OPERAND
OPERAND
NUMBER
NUMBER
COMMENT
104
PLA
#0
169
LOA
(AOOR1),Y
177
205
STA
(AOOR2),Y
145
203
LOY
LOOP
OPCODE
INY
200
Byte
CPY
#144
192
144
247
to 144
BNE
LOOP
208
continue
RTS
96
REDEF$
More than 256 Bytes
LABEL
Mnemonic
OPERAND
OPCODE
OPERAND
NUMBER
NUMBER
COMMENT
PLA
LOOP
LOY
#0
LOA
(205 ), Y
STA
(203),Y
INY
LOOPS
SNE
LOOP
INC
204
INC
206
LOA
(205),Y
STA
(203),Y
INY
CPY
REMAINDER
SNE
LOOPS
RTS
The simplest way to redefine more than 256 bytes is to move a multiple
of 256 first and then move the remainder. We have left the Opcodes,
Operands, and Comments for you to fill in.
REDEF$
More than 512 Bytes
LABEL
MNEMONIC
OPERAND
OPCODE
OPERAND
NUMBER
NUMBER
COMMENT
PLA
LOY
#0
LOX
#MULTIPLE
LOA
(205),Y
STA
(203).Y
INY
BNE
LOOPA
INC
204
INC
206
DE X
BNE
LOOPA
LOA
(205),Y
STA
(203).Y
INY
CPY
REMAINDER
BNE
LOOPB
RTS
The simplest way to redefine more than 512 bytes is to move multiples
of 256 first and then move the remainder. We have left the Operands,
Opcodes, Operands, and Comments for you to fill in.
More on Branching
224
208
169
141
37
5
3'fstart counting here
31 6
104 --Target
The relative address for the BNE is 5. But, "5", from where? The
target is the PLA. The number following the BNE is added to the
program counter to get the address of the target instruction. A little
counting tells us that the program counter was pointing to LDA when
5 was added to it. Thus, the opcodefollowing the branch operand is the
starting point for count ing in relat ive addressing. Notice that all the
numbers between this opcode and the target area are counted.
Consider a segment of the code for MOV$:
LABEL
MNEMONIC
OPERAND
OPCODE
NUMBER
OPERAND
NUMBER
LOOP
LOA
STA
INY
BNE
INC
ADDR1
ADDR2
177
145
200
208
230
205
203
ENDPL 1
LOOP+206
249
206
OPCODE
OPERAND
NUMERIC
OPCODE
OPERAND
PLA
104
PLA
104
STA
POS-1
PLA
STA
LOOP
NUMERIC
133
104
POS-2
133
203
LOA
#10
160
10
LOA
(POS-2) ,Y
177
203
INY
COMMENT
200
STA
DEY
(POS-2) ,Y
145
136
203
DEC Y twice in order to
fetch next player byte
DEY
CPY
BNE
RTS
136
ENOUGH
LOOP
192
208
255
245
96
You can see from the listing that the Hi-Byte and Lo-Byte of the
Y-position are pulled offthe stack and put into page zero locations 203
and 204 respectively . Page zero locations 203 to 209 are free to use in
subroutines and probably will be sufficient in most cases. However, if
neither the machine language routine nor the BASIC part of your
program use the floating point package, then page zero locations from
212 to 255 are also free to use.
Study the structure of the loop portion of this subroutine because
it will also appear in the next program example. The object is to move
each byte, of a group, up one location in memory. This moves the
player down on the screen. The loop starts with an indirect indexed
load to get the byte at the base of the player. Incrementing the Yregister and using indirect indexed addressing with STA moves this
byte up one memory location. Then the Y-register is decremented
twice in order to get the next byte. However, before branching back to
LDA a CPY instruction checks to see if all the bytes have been moved.
If they have, the result of the CPY is zero, the Z flag is set, and the
subroutine ends. The program will loop 256 times before control is
returned to the BASIC program.
Because the next program (Box 26) is considerably more complicated
than our previous program examples , we will discuss in general terms
the program's structure before looking at the assembly language code.
Pedagogically, the program illustrates the use of simple binary
arithmetic which also involves two's complement arithmetic.
,
BOX 26
Play_r Mov __ nt
I, 133,204.
165,2~3,56,233.4,133
208,246,231~,205, 198,21~14,
In the program the user is asked to input a number between 8 and 120.
This number defines a position to which the machine language in lines
140 to 175 will move the lightbulb player. The first task that the
subroutine must do is determine whether to move the lightbulb up,
down, or not at all. This means that the position number, input by the
user, must be passed to the subroutine and compared with the bulb's
current position. Physically, the lightbulb is a group of nine bytes
located somewhere in the 128 bytes of Player O.
PMBASE+512
Top of bulb
middle byte
...
Bottom of bulb
PMBASE+640
Box 27
Assembly Language Listing
Moving Lightbulb
POSITION = 203
COUNTER 204
OFFSET = 205
BASE 206,207
LABEL
MNEMONIC
OPERAND
OPCODE
OPERAND
104
104
PLA
PLA
104
216
PLA
CLD
COMMENTS
SEC
SBC
POSITION
BEQ
END
BPL
DOWN
56
229
240
16
EOR
#255
73
ADC
#1
STA
COUNTER
24
105
133
LOA
SEC
POSIT ION
203
43
42
255
CLC
204
203
player
165
56
OUTRLP
SBC
#4
STA
OFFSET
LOY
OFFSET
L OX
#11
233
133
164
162
4
205
205
11
INNRLP
BASE,Y
177
BASE ,Y
136
145
DEC
DEC
INNRLP
OFFSET
COUNTER
200
200
202
208
198
198
BNE
OUTRLP
LO A
CLC
OFFSET
LO A
DEY
ST A
IN Y
IN Y
DEX
BNE
END
DOWN
#4
ADC
STA
RTS
POSITION
ST A
LO A
COUNTER
POSITION
C LC
208
165
24
105
133
96
133
165
24
206
206
246
205
204
236
205
4
203
204
203
OU TRLP
INNRLP
ADC
#4
STA
LOY
OFFSET
L OX
LOA
IN Y
STA
#11
105
133
164
162
4
205
205
11
BASE ,Y
177
206
coun t
Load Accumulator with player
BASE,Y
200
145
206
136
136
202
208
230
198
246
205
204
OFFSET
DEY
DEY
DEX
SN E
INNRLP
IN C
OFFSET
DE C
COUNTER
SNE
LOA
SEC
SSC
ST A
RTS
OUTR LP
OFFSET
114
POSITION
208
165
56
233
133
96
byte
Change Y-reg ister
236
205
4
203
Arithmetic Instructions
The arithmetic instructions used in this routine are simple single
byte binary instructions. To see them in action, look at Box 27 which is
the assembly language of the 'Moving Lightbulb' program. The first
two PLA's remove the parameter count and Hi-Byte of the player
position from the stack. This Hi-Byte will always be zero, so we don't
need it. The third PLA removes the byte we need and holds it in the
accumulator.
The 6502 CPU can perform two types of arithmetic, binary and
binary coded decimal. Binary arithmetic can be treated as signed or
unsigned. In this book we will only concern ourselves with binary
arithmetic. Therefore, the first instruction we use is CLD (Clear
Decimal mode). This instruction must always precede a binary
arithmetic sequence. This done, we are ready to subtract the current
position from the new position. The value of the bulb's current
position is in memory location 203; the value of the new position is in
the accumulator.
The 6502 subtract instruction is SBC (SuBtract with Carry) which
actually means subtract using the carry flag as a borrow digit, if
necessary. This allows for the possibility that the number being
subtracted from the accumulator is bigger than the number in the
accumulator. Since SBC needs the carry flag, it must be preceded by
SEC in all cases. SBC, like LDA , has eight different addressing modes.
In this program we use zero mode.
Having subtracted the current position from the new position, it is
necessary to determine which direction to move the player. BEQ END
takes care of the case in which there is no movement. BPL DOWN
sends program control to the section of the routine that moves the
player down. If neither of these conditions occur, then the routine
goes about moving the player up .
N ow we come to a somewhat technical topic. The 6502 performs
its subtraction by addition! The method used is known as two's
complement arithmetic. The practical consequence here is, that if the
result of the subtraction is a negative number, then the number left in
the accumulator will not be in ordinary binary form, but rather in
two's compliment form. Accordingly, the result will have to be
converted to its positive equivalent before we can use it as a loop
counter.
0 0 0
000
0 0 0 0 0 0 0
~
a ninth bit
You will get the same result if you add 2 and 254 in binary form . Or if
you add 3 and 253. Or 4 and 252. By now you should see the pattern.
Every positive number up to 128 has a corresponding number (its
negative) that, when added to it, gives 256. Which, as far as an eight bit
register like the accumulator is concerned, is really zero.
N ow, what does this mean for the subroutine? Well, if we were to
subtract an input position value of80 from a current position value of
42, the result left in the accumulator would be the two's compliment
equivalent of minus 38, or 218 (in binary from 1101 1010). To use this
as a counter in the subroutine, it must be converted to a positive
number.
The algorithm for changing a number into its two's compliment
form is very simple. All you do is change every zero to a one and every
one to a zero and then add one. The algorithm works both ways.
Consider our example of 42 minus 80. The result, in decimal is -38 . The
result in 6502 subtraction is I 10 II 0 I0 which has the decimal equivalent
of 218. Parenthetically, 218+38= 256, as we would expect. By decimal
arithmetic, we have concluded that 218 must be the negative of 38.
Let's apply the algorithm:
11011010
(218)
001 001 01
Flip bits
+1
Add 1
o0 1 0 0 1 1 0
= 32 + 6 = 38
o 0 1 0 0 1 1 0 = 38
Flip bits
1 1 01 1 001
+1
1 1 0 1 1 0 1 0 = 218
The 6502 instruction set has a very handy command that allows
you to change one's to zero and vice versa. It is the EOR (review Box 3)
command. To flip all the digits of a number all you have to do is to
EOR the number with 255. For example:
1 0 1 1 0 1 1 1 = 183
11111111
01001000
o 1 00 1 00
M2
M3
Bit
Decimal
07
06
128
64
32
M0
MI
5 04
16
03
02
-4
01
00
MO
M2
00
00
00
00
11
11
11
11
00
00
00
00
11
11
11
11
M2
00
00
00
00
00
00
00
00
00
00
00
00
11
11
11
11
MO
00
00
00
00
00
00
00
00
11
11
11
11
00
00
00
00
and you want to move MO next to M2, you have to take care
that M2's bits are not wiped out in the process. This is accomplished
by masking with AND and unmasking with OR. Of course the
same comments hold true if it's M2 that is being moved rather
than MO.
,
80X 28
Missile Move.ent
\~5 \ REM
REM ' ** MISSILE MIJVEMENT
* LOWER RAMTOP *
1~
2111
25
30
4111
50
60
6:5
7111
7:5
.*
A-PEEK(106)-8:POKE 106,A
GRAPHICS 2
REM SET PM BASE *
POKE 54279,A
PMBASE~A*2:56
POKE 20:5,0
POKE 206,A+3
REM * CLEAR PM MEMORY *
FOR I=PMBASE+768 TO PMBASE+1024:POKE I,0:NEXT
REM * READ IN MISSILE DATA
8~ FOR 1-9 TO 3:POKE PMBASE+896+I,:51:NEXT
85 REM * SET HORIZONTAL POSITION.
90 POKE 532:52, 160: POI<:E 53254, 120
9:5 REM * READ IN MOVE ROUTINE
100 FOR I-Ill TO 63
110 READ ML:POKE 1536+I,ML
12" NEXT I
12:5 REM
130 DATA 162,6,160,25:5,1 3 6,208,2:53,
202,208,248,162,:5,164,203,200,177,205,74 ,7 4,201,12,240,17,136
,177,20:5,41,3
13:5 REM
140 DATA 200,14:5,20:5,136, 21n, 208, 236, 23~1, 21n, 76, 54, 6,1 .3 6
145 REM
1:5111 DATA 177,2i1l:5,9,48,21111~, 145,205,
136,202,208,219,230,203 , 165,204,141,4,208 ,230 ,204,76,0,6
1:5:5 REM
1:56 REM TURN ON MISSILES
157 REM * START MOTION.
160 POKE 21l13,131:POKE 21114,160
170 POKE 704,88:POKE 706,56
180 POKE 559,54:POKE 53277,1
190 FOR 1=0 TO 150:NEXT I
21110 X=USR ( 1536)
BOX 29
Assembly Language Listing
Moving Missiles
Register Usage:
= 203
HPOS(Horizontal
position) = 204
BASE = 205,206
LABEL
MNEMONIC
OPERAND
OPCODE
BEGIN
OUTER
INN ER
LOX
LOY
DEY
BNE
OEX
BNE
LOX
#4
#255
OUTER
#5
162
160
136
208
202
208
162
LOY
VPOS
164
LOOP
INY
LOA
LSR
LSR
CM P
BEQ
Inner
(BASE),Y
#12
OTHER
COMMENT
Delay action
to slow missile movement
to speed the human eye
can perceive
255
253
248
5
203
205
12
17
136
DEY
LOA
AND
INY
STA
DEY
OEX
200
177
74
74
201
240
OPERAND
(BASE),Y
#3
(BASE),Y
177
41
200
145
136
202
205
3
205
OTHER
BNE
LO OP
208
236
INC
VPOS
230
203
JMP
DEY
HOR IZ
54,6
LOA
ORA
INY
STA
DEY
(BASE ),Y
76
136
177
#48
(BASE),Y
DE X
HORIZ
205
48
9
200
145
136
205
Store MO and M2
Dec rem ent Y for next test and
pickup
Check off segment moved
BNE
LOOP
202
208
219
INC
VPOS
230
203
segm ent
If done increment position
LOA
STA
HPO S
HPO SMO
HPO S
165
141
204
4,208
230
76
204
0,6
INC
JMP
BEGIN
register
Load horizontal position
Store in MO position register
I ncrement horizontal position
Jump back to beginning
MO
M2
00
00
00
00
11
11
11
11
00
00
00
00
11
11
11
11
M2
7 6
0
M0
Ds
D4
D3
D2
D1
De
M0
06
5 4
D3
D2
D1
De
CARRY
M0
M2
D7
D6
DS
D4
D)
D2
Dl
De
Note that the MO bits are gone. The M2 bits have been shifted
to the right so they now represent the decimal number 12. It is
now a simple matter to test for their presence with a CMP #12.
There is something else we can learn from the LSR
instruction. Each LSR will divide an even number by two. 48
divided by two twice is twelve. With odd numbers the presence
of a one in the carry flag indicates the existence of a .5
remainder. What happens to a number if you shift the bits to
the left? If you answered the number is mUltiplied by two, you
are correct.
The comments in the machine language listing provide a
detailed description of the missile movement. The following
flowchart will help you to follow the logic.
5
Sound
Introduction
Second generation computers such as the Atari Home Computer
provide the programmer with the opportunity to use music and sounds
within their programs as another means of communication. In an
adventure game , music can set a mood , arouse emotions and
complement the action. In a utility program, sounds can signal a
keyboard entry error or warn that the disk is almost full. In addition to
these common applications, the hardware capabilities of the Atari
computers offer you the chance to try your hand at music synthesis via
programs dedicated solely to sound generation. For maximum
versatility and satisfaction, sound programs should be written in
machine language since BASIC is too slow for generating complex
sounds. Additionally, because of the nature of the 6502 processor, a
music program written in BASIC cannot run simultaneously with the
mam program.
179
A Bit of Theory
A sound or musical tone may be described by its intensity or
loudness, its frequency or pitch, and its waveform or timbre. Sounds
are created by devices such as tuning forks , TV speakers, or human
vocal chords, that vibrate back and forth in a cyclic manner. These
vibrations generate pressure changes in the surrounding air that are
detected by the human ear as sound. What a human perceives as sound
is a function of both the instrument generating the sound and the
human ear - a piano sounds different from an oboe. Before we can
understand complex tones, like those generated by a piano, it is
necessary to understand simple tones or notes.
Sound transmission can be represented pictorially as waveforms
with the simplest waveform being a sine wave. A waveform is usually
drawn as a graph where the horizontal a xis represents time and the
vertical axis represents a parameter such as the displacement or
pressure of the medium carrying the wave . The sine wave is referred to
as a pure tone even though the aural perception of a pure tone may be
Impure.
sin t
Sound 181
= 1/period
..
..
:"j
: :
: :
'.
\,/
,j
\)
Sustain
Attack
_ _J
Sound 183
If we connect the peaks with a line and throwaway the sine wave the
result is a picture of the sound envelope. This envelope is descriptive of
a single note that sounds for a short period of time. The shape of the
envelope is described by the risetime (attack), the sustain time, and the
decay time .
.......
"
'
"
I
,I
i
.,t.
.. .
~I-------------------~
Sound 185
,""''.
,'\
,,
"../
.1
1" ,
/ i
-------~
-lr
:r
- -- -
i / -~~~
I
--
.__ ___
-,.-
- -- ~
"
. (.. ~
):::.~ _ _
,t . . . -"\
... ....
"--
'--'
Sin
5%
:r
.'-
Sound 187
il101(::
NOTE
C
C#
0
0#
E
F
F#
G
G#
A
A#
16.35
17.32
18.35
19.45
20 .60
21 .83
23.12
24.50
25.96
27 .50
29.41
30.87
32.70
34.65
36.71
65.41
' =m iddle C
# =concert A
38 .89
41.20
43 .65
46.25
49.00
51 .91
55 .00
58.27
61 .74
1046.50
1108.75
1174.66
1244.51
1318.51
2093 .00
2217.46
2349.32
2489 .02
2637.02
2793.83
2959.96
3135 .96
3322.44
3520 .00
3729.31
3951 .07
1396.91
1479.98
1567.98
1661.22
1760.00
1864.66
1975..53
Sound 189
Sound Hardware
The heart of sound generation in the Atari Home Computer is
four programmable sound channels that can operate independently or
in pairs. Associated with each sound channel is a frequency register,
that is used to determine which note is played, and an audio control
register. This is all handled by POKEY. In addition to sound
generation, POKEY is an input / output chip that controls serial I / O
and keyboard input. POKEY allows a sufficient number of control,
frequency, and volume options so that the programmer can work with
these parameters to synthesize music.
Frequency is the basis of music so we 'll look at the frequency
registers first. The frequency registers AUDFI through AUDF4 are at
memory locations 53760, 53762, 53764, and 53766 respectively.
Numbers stored in these registers provide the "N" in divide by N
counters that reduce one of the three basic clock frequencies to a
desired sound frequency . The three basic clock frequencies are 15 KHz
(kilohertz) , 64 KHz and the system clock 1.79 MHz (millionhertz).
Suppose you are working with the 15 KHz clock. This clock generates
a signal consisting of 15,000 square pulses per second:
15 KHz
Jl_---JnL...--_----llL
after divide-by-three
frequency out
= clock frequency/2(AUDF+1)
= 2909.1
Hz
Sound 191
06 0 5
04
03
O2
01
For a pure tone the upper four bits of a control register must be set as:
would cause the speaker to move out with the rising portion and return
to its rest position with the falling portion of the pulse.
Using the volume only mode, the speakers moves to one of sixteen
positions depending on the value stored in AUOC. In this case,
however, the speaker does not automatically return to the zero
position as with the pulse above, but remains set in a position until the
program modifies it. In principle then, synthesizing a waveform
becomes a matter of writing a progra m to move the speaker so that its
successive positions match the amplitude of the waveform. The major
limitation is that there is only sixteen position settings.
The upper three bits (0 7 - 0 5 ) of the audio control registers are
used to create sound effects where a pure tone is not wanted . These bits
control polynomial counters, also called poly-counters, that are used
to remove pulses from a normal pure tone's train of pulses. These
pulses are removed in a semi-random manner and the bit pattern that
results will repeat after a span of time. When bits are removed
randomly, giving a pulse train such as,
Sound 193
Uti 11 ty Proor . .
..
241~
245
250
255
260
270
275
280
290
:3111~1
310
320
:33111
34111
35ul
355
36121
3"711'
380
391~
41110
405
410
415
420
425
43111
435
440
445
450
460
470
480
PRINT
PRINT "BITS 7,6,5
l.,1,111 => 192+VOL."
PRINT :TRAP 160
INPUT DIST
POKE 53761,DIST
FOR 1=1 TO 10~0:NEXT
POKE 53761,0
PRINT :TRAP 290
PRINT "TRY AGAIN (YIN)?"
INPUT ANS$
IF ANS$="Y" THEN GOTO 70
PRINT :PRINT
PR I NT "CURREI\JT NUMBER IN AIJDF l. IS:"; N
PRINT
PR I NT " DI ~3TORTI ON-VOLUME NUMBER"
PRINT
PRINT " IN AUDCl IS:"; DIST
END
REM * DEMONSTRATION SECTION *
PRINT
PRINT "STARTING WITH A LOW FREQUENCY"
PRINT
PRII\JT "WE WILL CYCLE THROUGH"
PRINT
PRINT "THESE DISTORTION-VOL NUMBERS:"
PRINT
PRINT "8,4111,72,136,2111111"
PRINT
PRINT "IN EACH CASE tHE VOLUME IS 112 MAX."
FOR I-I TO 1000:NEXT I
POKE 53760,255
PRINT CHR$(125)
PRINT "LOW FREQUENCY"
GOSUB 640
Sound 195
~10
~20
~30
54{1
~~e
~6{1
~7l1
~80
5ge
600
6111
620
62~
630
640
6~0
660
670
680
\.690
04
05
06
07
o
o
o
0
X
1
0
0
0
0
o
X
O2
03
04
05
06
07
00
01
Sound 197
Program Examples
The next few programs (Boxes 3 I - 33A) illustrate the theoretical
concepts discussed earlier: Envelope, Tremolo, and Vibrato. The
programs are all structured similarly and are intended to be taken
apart and used in other programs . Each has four sections.
The first section initializes the hardware for sound by turning off
interrupts, ANTIC's direct memory access, then storing a 0 in
AUDCTL, and a 3 in SKTL. Turning off the interrupts and ANTIC is
important because in a program devoted solely to music consistent
timing is important. ANTIC turns off the CPU at odd intervals which
could wreak havoc in a music program. Note that it is not sufficient to
just store a 0 in DMACTL since it is shadowed at 559 and would be
restored during the vertical blank.
The second section of each program sets the initial sound
frequency and volume and initializes a delay loop. The third section
manipulates either AUDC or AUDF for the desired effect. Finally,
there is a delay loop. A delay loop is needed because things happen so
quickly in machine language, that you have to slow down the time
between frequency or volume changes in order for the effect to be
meaningful in terms of human perception.
Each delay loop actually has an inner and outer loop. The inner
loop takes some set amount of time say, for example, .225 milliseconds
to execute and the outer loop determines how many of these units of
time are used in the delay . The amount of time taken for delay loops
can be estimated by counting the machine cycles needed for execution
of each instruction. Using the approximate value of the CPU clock
frequency, 1.79 MHz, the time for one machine cycle is:
.000000559 seconds
BOX 31
Envelope
Sound 199
BOX 31A
Assembly Language Listing
for
Attack, Sustain, Delay
Section 1: Initialize the machine
PLA
LOA
STA
STA
STA
STA
LOA
STA
#0
NMIEN
IRQEN
OMACTL
AUOCTL
#3
SKCTL
104
169,0
141,14,212
141 ,14,210
141 ,0,212
141 ,8,210
169,3
141 ,15,210
#20
COUNT
#72
AUOF1
169,20
133,203
169,72
141,0,212
Initialize
delay loop
Intialize
frequency
BOX 31A. Assembly language listing for Attack, Sustain, and Decay
160,160
140,1 ,210
200
32 ,65,6
192,176
208,245
169,100
133,203
32,65 ,6
162,80
202
208,253
198,203
208,247
96
136
STY AUDC1
140,1,210
LOA #200
169,200
STA COUNT
133,203
JSR DELAY
32,65,6
CPY #160
192,160
BNE LOOPB
208,241
RTS
96
Section 4: Delay Subroutine
Start with
zero volume
Increment for next volume
Delay before changing volume
Is volume its maximum?
If not continue
Create delay for the
sustain portion of envelop
Jump to delay
Start decay portion of
the envelop
create delay for the
decay portion
Jump to delay
Is volume zero?
If not, continue
Return to basic
Inner loop counter
Inner
Loop
Decrement delay counter
If counter not 0, continue
Return from delay
Sound 201
BOX 32
T,...,lo
REM ** TREMOLO EXAMPLE **
20 NUMBER=75
30 FOR I=~ TO NUMBER:READ D
4~ POKE 1~36+I,D:NEXT I
~0 REM * INITIALIZE MACHINE *
60 DATA 104,169,0,141,14,212,
141, 14,21~, 141,~,212, 141,8,21~, 169,3, 141, 15,210
65 REM
70 REM * INITIALIZE DELAY AND SOUND REGISTERS *
8~ DATA 169,2,133,203,16~,72,
1~
140,0,21~,160,166,140,1,210,32,62.6
192,169,208,24~,136,140,1,210,32,62,6.192,166,208,245,76,37,6
BOX 32A
Assembly Language Listing
for
Tremolo
#0
NMIEN
IRQEN
DMACTL
AUDCTL
#3
STA SKCTL
104
169,0
141 ,14,212
141 ,14,2 10
141,0,212
141,8,210
169,3
141,15,210
Initialize POKEY
\.
LDA #2
STA 203
LDY #72
STY AUDF1
LDY #166
STY AUDC1
JSR DELAY
169,2
133,203
160,72
141,0,210
160,166
140,1 ,210
32,62,6
Initialize
delay
Initialize
frequency
Initialize
volume
Jump to delay
Sound 203
r
Section 3: Volume increase and decay
STY AUDC1
JSR DELAY
CPY #166
200
140
32,62,6
192,169
208,245
136
140,1,210
32,62,6
192,166
BNE DEeR
JMP INCR
208,245
76,37,6
INCR INY
STY AUDC1
JSR DELAY
CPY #169
BNE INCR
DECR DEY
Increment
volume
Jump to delay
Is volume increase done?
If not, continue
Decrease
volume
Jump to delay
Is volume done?
If not, continue
Jump to increase
162,80
202
208,253
198,203
208,247
96
BOX 33
Vibrato
10
20
30
40
50
60
15,
~ U~l
65 REM
70 REM * INITIALIZE DELAY AND SOUN D REGISTERS
80 DATA 169 , 2,1 33,203, 160,72 ,14@,
1!t,211;J, 169, 168, 141,
1, 2 11~,32 , 6: ,6
133,203,96
Sound 205
BOX 33A
PLA
LOA #0
STA
STA
STA
STA
LOA
STA
NMIEN
IRQEN
OMACTL
AUOCTL
#3
SKCTL
104
169,0
141,14,212
141,14,210
141,0,212
141,8,210
169,3
141,15,210
\..
STY AUOF1
LOA #168
STA AUOC1
JSR DELAY
169,2
133,203
160,72
140,0,210
169,168
141,1,210
32 ,62,6
Initialize
delay loop
Initialize
frequency
Set volume
at % maximum
Jump to delay
200
140,0,210
32,62 ,6
192,75
208,245
136
140,1 210
32,62,6
192,70
208,245
76,37 ,6
Increase
frequency
Jump to delay
Is frequency increase done?
If not, continue
Decrease
frequency
Jump to delay
Is f requency done?
If not, continue
jump to increase
162,80
202
208,253
198,203
208,247
96
Sound 207
Instruction
Immltdiat.
LDA, LDX.
LDY
DEX
INX
Pag. 0
2
Ab!loluta
Implied
DEY
INY
5
DEC
BNE
BEQ
JSR
RTS
Relative
6
.3
(same page l
(di Her-ent P9)
BOX 34
Voluae Only
.*
l@
2Qj
30
40
92,16,208,243,76,25,6
12@ " X=USR (1~36)
Sound 209
,
BOX 34A
PLA
LDA #0
STA NMIEN
STA IRQEN
STA DMACTL
STA AUDCTL
LDA#3
STA SKCTL
104
169,0
141,14,212
141 ,14,210
141 ,0,212
141 ,8,210
169,3
141 ,15,210
160,16
140,1,210
200
140,1,210
Increase
volume
Delay loop. Value in X
register determines
frequency of the sound
Is up-ramp complete?
162,40
202
208,253
192,31
208,243
136
140,1,210
If not, continue
If volume is max,
start down-ramp
Delay loop. Value will
determine frequency of
162,40
202
208,253
192,16
208,243
790,25,6
the sound
Is down-ramp complete?
If not, continue
If yes, go to up ramp
**
2f~
212'8,253,192,31,212'8,243,1 .3 6.14(2'.1}
6,208, 24.3
=11~,
16:, 4m,
= ~!J'2,
2Q18, 253,192,1
110 REM
12" DATA
208,2~3,
2~0, 1412' , 1,
192,31, 208,
211~). 162~
24 ~, .
32 , 2! ~ 1:: .
136, 141, 1 ~ 2
11~1.
6,208,243,76,25,6
141~
X= U5R (1536)
Sound 211
,
BOX 35A
PLA
LOA
STA
STA
STA
STA
#0
NMIEN
IRQEN
OMACTL
AUOCTL
LOA #3
STA SKCTL
104
169,0
141,14,212
141 ,14,210
141 ,0,212
141 ,8,210
169,3
141,15,210
160,16
140,1,210
\,.
..,
200
140,1,210
162,40
202
208,253
192,31
208,243
136
140,1,210
162,40
202
208,253
192,16
208,243
200
140,1 ,210
162,30
202
208,253
192,31
208,243
136
141,1,210
162,30
202
208,253
192,16
208,243
76,25,6
Sound 213
You can change the pitch of the sound by changing the delay
value . A shorter delay yields a higher pitch. The two programs differ in
that the second program (box 35) effectively generates triangle waves
with two different frequencies. When you compare the two assembly
listings you will see that the program in box 34 creates a triangle
waveform with a delay value of 40 and then creates a triangle
waveform with a delay value of 30. There is a very noticeable difference
in the sound produced by this change.
There are two simple exercises that you should do at this point.
The first is to put comments into the assembly listing in box 35A. The
second is to rewrite the program so that it carries out the same task but
in a more efficient manner. The program as written is straightforward
but repetitive . Anytime that you have a repetitive set of commands
such as we have here, it should be possible to write the program code
more efficiently.
The most versatile way to use the volume only mode is to generate
sound waveforms from a set of data numbers stored in a look up table.
The data table holds different speaker position settings 0- I 5. Since
volume only sound requires bit 0 4 to be set as well, the data numbers
range from 16 to 31. The central idea of such a program is to load
successive values from the table into one of the AUOC registers.
Suppose you wanted to create a waveform such as this:
This waveform repeated over and over again will produce a note
subtly different from those in previous programs . The reason is that if
the waveform were synthesized by the addition of sine waves it would
have a different fundamental frequency and different harmonics or
overtones than the previous examples such as the triangle waveform.
By programming different waveforms you can experiment with note
timbre, or quality. Box 36 is a program that uses the data numbers
given above to produce a continuous note. Writing music this way is a
considerable task since the duration of the note and the frequency
must be written into the program. The frequency is controlled by the
delay portion (see the assembly listing in box 36A). For music, the
delay portion must be modified to access a table of frequencies for each
note. The frequencies must be calculated from knowledge of machine
cycles or determined experimentally with the help of a piano or other
musical instrument. The duration of the note can be handled by
replacing the JMP START instruction with program lines that make
the waveform repeat a suitable number of times.
BOX 36
Waveform
10
:::' 0
30
4 1il
50
6Vl
REM
**
WA VEFORM ExnM~~~
7f,1
~ I~ TO f'IUMP l::R : ;;'liIL D
NUMBE R~
c' OR
FOf . E
15:::.6+I, n:I~ E xr
RE M
6
85 RE M
Sound 215
BOX 36A
Assembly Language Listing
for
Waveform Example
START LOX #0
162,0
LOOPA LOA TABLE,X 189,41 ,6
STA AUDC1
LOY #40
LOOP B DEY
BNELOOPB
INX
CPX #31
BNELOOPA
JMP START
produce a quarter note, half note, or whole note. Notice that while
there are increment and decrement instructions for the index registers
and memory locations , there aren't any such instructions for the
accumu lator. Consequently you must use addition or subtraction to
increment or decrement the accumulator.
BOX 37
Utility Progrilm
a-Bit Music Data Generator
Sound 217
360 NTE2INTCLoCKFREGl/(2*FRED) ) - 1)
370 K-I<+1
380 NTEDAT(K)-NTE
390 IF K( N THEN GO TO 130
400 PRINT :PRINT :TRAP 410
410 PRINT "PRINT TO SCREEN OR PRINTER
420 INPUT OPTION.
4 3 121 IF of.TION.="S" THEN GOTO 461:'
440 IF OPTION'~"F'" THEN GOTO 4 ' ,,1
431!l GOTO 41~1'\
,II ,,;, r 'h I NT
. :7,., For, f ~t TIJ N:f-'hlNl '~lEl'n1" I; " . " ; :
'l:. lI'l G() 1 r l
~,bt:'
I;
560 END
5 70
BASE=t t,3~:RETURN
(S.P)~"
'~f
xr
I>
,
BOX 38
8-Bit Music
Three Blind Mice
*.
10 REM
THREE BLIND MICE **
NUM8ER=' 1 "1 3
:25 REM
30 FOR 1=0 TO NUMBER:READ D
40 POKE 1536+I,D:NEXT I
4 5 REM
50 REM * INITIALIZE MACHINE *
61<1 DATA 104,169,1<1,141,14,212,
141 , 14, 21"', 1 41 , QI, 212, 141 , 8, 211<1, 169, 3, 141 . 15, 211<1
65 REM * PLAY NOTE AND LOAD THE DURATION *
70 DATA 162,0,189, 78,6,141,0,210,
169 ,168, 141,1 , 2JeI, 232, 189,78,6, 32,61<1,6
75 REM * TURN OFF SOUND 8ETWEEN NOTES *
81<1 DATA 169, 16QI, 141,1, 21Q1, lMI, 2QI, 136,208,25:',.231<1, 2Q13, 2Q18, 247
85 REM * CONTINUE OR RETURN TO 8ASIC *
90 DATA 232,224,96,208,219,96
95 REM * DELA Y -CONTROLS NOTE DUR AT ION *
100 DATA 160,200,136 ,208,253,230,
21~13,208,247~216, ' 56,233, 1,201,0,2Q I8.239,96
105 REM * NOTE TABLE *
tIl!! DATA 95~ .3 , ifl'?, 3,121,3,95,3, 1m?,
3, 121,3,80,3,9 0,2,90,3,95,4,80,3,90,2,90,2,95,4,8,~,3,60 ,2,60,
3,63,3,71,3
115 REM
1 2 1~ DATA 63,3 , 6r~',3 .81~,2 ,8 r~',4,8f~,3,
:21~
f2J, .3 , 63,3,71,3
125 REM
130 DATA 63 , 3,60,3,80,3,80.2,80,3,
90,3,95,4,107,4,121,4
135 REM
Sound 219
BOX 38A
104
169,0
141,14,212
141,14,210
141 ,0,212
141,8,210
169,3
141,15,210
32,60,6
,
Section 3: Turn off sound between notes
LOA #160
169,160
Load pure tone 0 volume
STA AUDC1
LOOPB LDY#20
LOOPC DEY
BNE LOOPC
DEC DREG
BNE LOOPB
141,1 ,210
160,20
Store in AUDC1
A two loop delay routine
136
208,253
230,203
208,247
232
CPX TABLEND
BNE LOOPA
RTS
224,96
208,233
96
Check if finished
If not, continue
If yes, return to basic
\.
CLD
SEC
SBC #1
CMP#O
BNE DELAY
RTS
216
56
233,1
201,0
208,239
96
Sound 221
1~
2121
30
4@
50
60
2 .3 2, 189,91 ,6, 141, 2 ~ 21 Ql. 169 ~ 1 6!, 14 1 , 1 I 21 Q! , 141 ~ 3, 21@, 232, 189,91
,6,32,7.3 ,6
:' .
91~,
144,3
,95, 16 2,4,80,128
120 DATA 3,9@,144.2,90.144.2,95.
162,4,8121, 162.3,60, 121. :;" . 60 . 121. 3 . 63, 1('17, .3 , 7 t ,95, .3 , 63,107,3,60
,9:5,3,81!1,128,2
13121 DATA 80.128,4,80.128. 3 . 6 0,95. : .
60.95,2,6~,95.3.63~1~17,~,71,95~ ~ . 63 ,1!~7,3. ~~ 1,95, 3 ,8,~,9~.2,80,
95,
3,81~,
128
128. 3 .60, 95 . ~ . 60 . o5 . 3 ,
-:"
QI~ .
De'.
,9~',144,3
151~ DATA 95,162 .4,11,17 .1 132 .4.1 21.1'12 .4
201,1 X =U5R ( 15.3 6)
21~ 5 REM
RESTIJRE SCREFri
:' I t!l
F'O~
5/l~/2 .
-:-.4 : F-OLE
S ,, ~o ~ )
.~ ,'!
: rfH
Box 39A
Assembly Language Listing
for
Three Blind Mice with Chords
Section 1: Initialize the machine
PLA
LOA #0
STA NMIEN
STA IRQEN
STA OMACTL
STA AUOCTL
LOA#3
STA SKCTL
104
169,0
141,14,212
141,14,210
141,0,212
141,8,210
169,3
141,15,210
162,0
LOOPA LOA TABLE,X 189,91 ,6
STA AUOF1
141,0,210
INX
232
LOA TABLE,X
189,91,6
STA AUOF2
141,2,210
\...
LOA #168
STA AUOC1
STA AUOC2
INX
LOA TABLE,X
JSR DELAY
169,168
141 ,1,210
141 ,2,210
232
189,91 ,6
32,73,6
Box 39A. Assembly language listing for Three Blind Mice with Chords
Sound 223
169,160
141,1,210
141,3,210
160,20
136
208,253
230,203
208,247
232
224,144
208,206
96
\...
DEY
BNELOOPC
DEC DREG
BNE DELAY
160,200
136
208,253
230,203
208,247
CLD
SEC
SBC #1
CMP #0
BNE DELAY
RTS
216
56
233,1
201,0
208,239
96
Sound 225
r
"'*
**'
10 REM
THREE BLIND MI CE
1 G BIT MUSIC
20 NUMBER= 235
30 FOR 1=0 TO NUMBER:READ D
40 POKE 1536 +I,D:NE XT I
50 REM
INI T IALIZE MACHINE
60 DATA
104, 169,0, 141, 14 , 2 12, 111, 14, 2 10, 141,0, 212, 169 , 1 G0 . 141, 1, 210, 1
69 , 80,141,8,21121,169,3,141,15,210
65 REM
PLAY NOTES AND LOAD DURATION ~:
70 DATA
162, 121, 189, 92, 6, 141, 0 , 21121 , 232, 189 , 92, 6, 141 , 2, 21 Ci, 16 9, 168, 14 J .
,210,232,1 89,92 ,6,32 ,74,6
75 REM
TURN OFF SOUND BETI'IEEN NOTES
80 DATA 169, 160,1 41 ,3,2 10,160,20, 136,208,25 J . 2 30 , 203,208,2 4 7
85 REM
CONTINUE OR RET URN TO BASIC *
90 DATA 232,224,144,208,212,96
95 REM
DELAY -CONTROLS NOTE DURATION
100 DATA
160,150, 136,208 ,253,23121 , 21213,208,247,216,56,233, 1 ,~ 01,0,208,23
9 , 96
105 REM
NOTE TABLE '"
1110 DATA
148,110,3 ,224 , 11,3,85,13,3,148,10,3,224,11,3,85, 13 ., 3 ., :)~~8, 8, 3, 2
51, 9, 2, 251, 9, 3, 148 , 10 , 4 , 228, 8, 3, 251 , g, 2
120 DATA
25 1, 9, 2, 148, 10, 4 , 228 , 8 ., 3 J 67 , 6 , 2, 167 6, 3, 13, 7 , 3 , 235, 7 , 3, 1 :-; . 'I.
3,167,6,3, 22e , 8, 2, 228 , e , 4, 228, 8, 3,167
130 DATA
6, 3, 167 , 6 2, 167 , 6.' 3 , 13, 7 , 3, ? 3 5 7 :3 13, 7 . 3 , 1 C7 . 6 . 3 ., ~::2 8 . S . 2 . ~ ~ 8
,8,3, 228 ,8 , 3,228,8,3, 167,6,3,167, 8 , 3
140 DATA
13 7 , 3, 235, 7 3 13, 7, 3 , ] 67 6 3 J 228, 8, 3, 228 I S, 2, 228 8 3, 2 fJ 1, ~J ., 3
, 14e, 1121,4,224,11,4,85,13,4
150 DATA 95, 162,4 , 107, 182,4 , 121,19 2 ,4
200 X= [JSR ( 15 36)
205 REM
RESTORE SCREEN
210 POKE 54272,34: POKE 54286,64: POKE 53774,192
*'
*
*
*'
*'
*'
*'
BOX 40A
START LOX #0
162,0
LOOPA LOA TABLE,X 189,92,6
141,0,210
STA AUDF1
232
INX
LOA TABLE,X
189,92,6
STA AUDF2
141,2,210
169,168
LOA #168
STA AUDC2
141,3,210
INX
232
LOA TABLE,X
189,92,6
JSR DELAY
LOA #160
STA AUDC2
LOOPB LOY #20
LOOPC DEY
BNELOOPC
DEC DREG
BNELOOPB
Load counter
Load Lo-Byte of music data number.
Store it in AUDFI
Increment X to point to next value
Load Hi-Byte of music data no.
Store it in AUDF2
Load volume number
Store volume number in AUDC2
Increment X to point to delay value
\..
Sound 227
r
INX
CPX TABLEND
BNE LOOPA
RTS
DELA Y LOY #200
232
224,144
208 ,212
96
160,200
LOOPD DEY
BNELOOPD
DEC DREG
BNE DELAY
136
208,253
230,203
208,247
CLD
SEC
SBC #1
CMP#O
BNE DELAY
216
56
233,1
201,0
208,239
subtract
} determines
is accumulator 0
length of
note
if not, recycle
RTS
96
\".
Summary
In this chapter we have presented the fundamentals of music but
have only scratched the surface of what you can do. There are many
options available. We have mentioned tremolo, vibrato, and chords.
You can put in glides, attack, sustain, decay. The sound channels do
not have to be turned on and off at the same time as we did in our
simple programs. There is one option yet to go . That is to combine
music with the vertical blank interrupt. This option is the subject ofthe
next chapter.
6
Advanced Techniques
Introduction
As you now know, most of the sound and graphics features of the
Atari Home Computer are, to so me extent, accessible from BASIC.
However, there are situations in which the only satisfactory implementation
of sound or graphics comes through machine language subroutines.
Forexample, yo u can use BASIC to play music, but if you want to play
music as an integral part of your program, it can only be done in
machine language during the TV's vertical blank. You can detect
collisions, or write programs to go with a touch tablet in BASIC, but
these tasks are also done more satisfactorily in the vertical blank with
machine language.
The OS vertical blank routines a re among the more powerful and
ve rsa tile features of Atari co mputers. In this chapter we will focus on
describing what happens during the vertical blank and how to
integrate your own routine(s) into the regular OS protocols. We will
illustrate the general procedures with examples that demonstrate
scrolling, music, and input with a touch tablet.
229
FLOWCHART
for
VERTICAL BLANK INTERRUPT ROUTINE
(VB
INTERRUPT
SIGNAL
~ump
WBLKI
540,:547
USER
STAGE I
ROUTINE
SB463
VBLANI<
St.aQ. I
PROCESSED
CRITICAL
/~CJ(
CRITIC
CODE
NOT
CR I TI CAL
VBLANK
St.aQ. II
PROCESSED
Jump
Through
:548,:549
USER RESET
USER
STAGE II
ROUTINE
XITVBL
58~66
PLA
LOY AOORLO
LOX AOORHI
LOA#7
JSR SETVBV
RTS
104
160,AOORLO Load Y with Lo-Byte of routines
address
162,AOORHI Load X with Hi-Byte of routines
address
169,7
7 indicates Stage" link .
32 ,92,228
Jump to SETVBV .
Return
96
instead.
The reason for the SETVBV subroutine is that it prevents system
lockup. The vertical blank vectors are two byte critters. Setting these
vectors with BASIC POKE statements runs the risk of an interrupt
occuring before both locations are updated and .. . that would crash the
program!
546,547
548,549
58460
58463
Advanced Techniques
235
Scrolling
Our first programs that use the vertical blank will illustrate
horizontal and vertical scrolling. Scrolling in the Atari Home Computer
is best thought of as using the TV screen as a window on memory.
Using ANTIC's LMS instruction a rd two fine scroll registers, the
window can be moved smoothly from one part of memory to another.
Scrolling done this way is more versatile than scrolling in machines
that use a fixed area in memory for the screen display. In this case you
have to move information (bytes) through the screen memory,
sometimes moving thousands of bytes . With the Atari you can create a
large picture and scroll across it as if it were a panaroma .
The heart of scrolling is manipulating ANTIC's display list and
the two fine scroll registers, HSCROL (54276) and VSCROL(54277).
Recall that ANTIC's display list is a microprocessor program and as
such can be modified. Any mode line instruction can also have the load
memory scan option (LMS instruction). Suppose that the address for
each LMS instruction is changed during a vertical blank. Then what is
shown on the screen next will have shifted position, or changed
entirely, depending on the value(s) stored.
The ideas involved can be visualized with the help of some
diagrams. We commonly think of computer memory as organized
vertically:
page 135
page 134
page 133
page 132
page 131
page 130
138-------------------------------------------
136--------~============~-----------134----------~--------------~r_---------------
132--------~~--------------_4----------------
====!::=====~======
130
128---------------------------------------------
BOX 42
Vertical Scrolling
The Yellow Submarine
'"
10 REM
21!'
F'(J~< E
166,20 6,232~224,
445 REM
450 DATA 206,169,6,141,26,2 ,96,
216,24,173,4,157, 105,2C2l, 1 76, 16, 141~4, 15 7 ~ 169,C!l, 1 41,5,21 2, 133
455 REM
460 DATA 206,169,6,141,26,2,96,
238,5, 15 7,141,4,157,169,12',141,5.212,13.3 , 21!l6, 169,6,14 1, 26,2, 96
465
470
480
490
50 0
510
520
5 31~
REM
REM * INS TALL ADDRESS OF THE S CROLLING PROGRAM *
POKE 55 2 , 0 : POKE 55 3 ,15 8
REM * SET REGISTER S USED BY SCROLLING ROUTINE *
PO KE 205 ,0 :POKE 206,0 :POKE 54277,0
REM S TART SYS TE M TIMER 2
PO KE 538, 10
GOTO 531~
BOX 42A
CLEAR$ Li sti nf~
1"
h
"
169
162
16i1
CLI,
[:J
CLIO
28:5
2H
2fJ8
2:51
"
G
14:5
ICLI, I
CLI,
ICL/Q
23.
2iJ4
21112
21118
246
96
GJ
GJ
CL/.
LEGEND
0
CLI
Around
= inverse
= Control
video
Key
BOX 42B
1.
120
96
CLI.
2. ($) 0
(#)
120
96
96
96
96
96
127
127
127
ES/TAB
CLI,
3. (%)0
CLI,
4. (&) 15
5.
6.
(')
(')
17
49
63
?
CLIO
CLIO
248
40
40
CLI,
127
248
63
255
CLIG
!ES/ CL> !
255
255
255
IES/ CL> I
254
255
255
255
224
254
CLI.
IES/BSI
255
7.
(,)
8. (*) 127
127
ES/TB
9.
(+)
255
192
Cl/,
255
15
31
63
255
255
255
255
252
254
252
252
248
ISH=I
IEs/cL/B~~H= I
63
31
15
ES/ Cl *CLlO
255
255
252
ISH=I
IEs/cL> \
248
ICLlI0
11 . (-) 255
255
255
127
63
15
ES/ TB ?
CLIO
CLI,
255
255
255
CLI,
IES/ CL> I
255
224
ISH=I
ICLII
CLI,
224
ICu.1
CLI,
IES/ CL> I
I~
Cl/ ,
[ES/CL> I
ISH=\
252
LEGEND
SH = Shift
Cli = Control Key
TB = Tab Key
BOX 42C
Vertical Scrolling Routine
The Yellow Submarine
205 (COUNT) keeps track of how far we 've scrolled
206 (SCRLREG) keeps track of value to put in VSCROL.
LOY COUNT
BEQ COARSE
STX VSCROL
STX SCRLREG
LOA #6
STA TIMER
SCRLREG
142,5,212If not store value in VSCROL
134,206 Save value for next time around
169,6
Load and store a delay value. A
141,26,2 fine scroll each 6th VB .
RTS
96
INY
CPY #120
BEQ END
STY COUNT
LOX SCRLREG
INX
CPX
END
\..
1t-IG
COARSECLO
CLC
LOA SCNLO
AOC #20
BCS AOOHI
STA SCNLO
LOA #0
STA
STA
LOA
STA
AOOHI
VSCROL
SCRLREG
#6
TIMER
RTS sc..NH;:..
INC...cNLD
1t-. ST A SCNLO
~ D:.
-:-=f"
LOA #0
~\ STA VSCROL
'j-
216
24
169,6
141 ,26,2
96
238,5,157
141 ,5,212
STA SCRLREG 133,206
LOA #6
169,6
STA TIMER
14 1,26,2
96
RTS
153,236
1:54, (lJ - - - - -
1:54,2J2!
1:54, 4 ( l J - - - - -
..
1:54,22 (lJ
154,240-------~~~------------
TV display
Since the image moves one whole mode line at a time, coarse
scrolling is noticeably jerky, especially in Graphics 2, where a single
mode line has 16 scan lines. Using the vertical fine scroll option allows
you to move a mode line, a group of mode lines, or the entire screen up
or down in scan line increments. The number of scan lines to move the
display is determined by the number in VSCROL. By incrementing
VSCROL during the vertical blank, the display drawn is shifted up
slightly from the previous one. Fine scrolling is limited by the fact that
only the lowerfour bits of VSCROL are significant. Consequently, the
largest number of scan lines that a display can be moved with fine
scrolling alone is 15. To continue the scrolling beyond this limit
involves invoking a coarse scroll and resetting the fine scroll register.
The process in flowchart form is shown in figure 6.3. Vertical fine
scrolling can be done with the whole display or part of the display . All
that is required is to set bit 05 in each display list instruction by adding
32 to the normal mode line number (see chapter 3).
Now we are in a position to look at the assembly language listing
in box 42C. The program starts off with a check on how far the
scrolling has progressed. This is done with a page zero register count
called COUNT at location 20.6 which is incremented on each pass
through the program. After 120. passes, aRTS is performed without
resetting system timer 2, thus effectively ending program execution.
Without the check on the scrolling, the screen window would scroll
across the computer memory which would be interesting but not
necessarily desira ble . For an interesting experience , rep lace BEQ # 19
with two NOP's.
Once the check on scrolling is done , the program loads the current
value in VSCROL from a software register at 20.6, increments it, and
compares it with 16. A natural question is "Why do we need a software
register?"The answer is because VSCROL is a write only register. This
means that there are some things you can't do with it such as load
CPU registers from it or use the INC VSCROL instruction. If fine
scrolling is not complete, which is determined by the results of CPX
# 16, the new va lue is stored in VSCROL and back into SCRLREG .
Finally, a delay value of 6 is loaded into system timer 2. This value does
SET UP
DISPLAY
INCREMENT
VSCROL
NO
IS
FINE SCROLL
COMPLETE
YES
DO
COARSE SCROLL
RESET VSCROL
TOO
Figure 6-3. Vertical fine scrolling process
two things . It makes sure the subroutine will be called again when
timer 2 counts down to 0 and it controls the speed of scrolling.
When SCRLREG increments to 16, it is necessary to shift the
LMS instruction to point to the next lower screen mode line by adding
20 to the low byte of the LMS address. The program section beginning
with the label COARSE does a binary add and resets VSCROL and
SCRLREG. A new wrinkle in this addition routine is that sometimes
we must perform two byte addition. That happens when adding 20 to
SCNLO ;the Lo-Byte in the LMS address gives a result greater than
255. The procedure for doing this should be evident from the assembly
listing.
Before going further, test your understanding of the concepts
covered by rewriting the program so that the submarine scrolls down
the screen. To do this you will want to decrement the value in
VSCROL. Since VSCROL does not use the upper four bits, one way
to proceed is to load both hardware and software registers with 255
and decrement down until bits Do-Ds are clear. Now since you are
scrolling down, you must subtract 20 from the Lo-Byte of the screen
address . Don't forget it may be necessary to borrow from the Hi-Byte .
Horizontal Scrolling
The idea behind horizontal scrolling is to allocate a portion of
screen memory for each mode line . If the memory allocated is larger
than necessary, and if each mode line has the LMS option, then by
changing the address in the instruction, the display can be moved left
or right. This concept is illustrated with a single mode line thusly:
130,19
130,0------+
I Graphics 2
\1
.
130,255....;::J
Change the Lo-Byte of the LMS from 0 to 20 and the display shifts:
nOIOngerShOWn~
The easiest way to organize memory for horizontal scrolling is to
set aside one page for each mode line. Then you need only increment or
decrement the Lo-Byte of the LMS instruction. Incrementing scrolls
the display to the left. Decrementing scrolls the display to the right.
The diagram above shows the effect of adding 20 bytes to the address,
which is coarse scrolling in a big way! Normal coarse scrolling
increments by one byte at a time. To smooth out the motion, the
horizontal equivalent of a vertical fine scroll must be done. Horizontal
fine scrolling is done in color clock units. The fine scrolling register
HSCROL is nominally 8 bits wide but only the lower four bits are
used. Thus, the maximum number of color clocks that an image can be
fine scrolled before resetting is 16. The actual number to use depends
in the number of color clocks in the characters of the graphics mode
being used.
Box 43 is a horizontal scrolling example using the submarine of
the previous program. This program and our succeeding example, in
box 44, are similar, in order to reduce the amount of typing you need to
do. In both programs the machine language routine is stored in a string
for reasons of efficiency and economy. To make space for the display
list, character set, and screen memory, RAMTOP is lowered 27 pages.
Memory is used in the following manner:
PAGE
133
134
135
LO-BYTE
128
o
o
FUNCTION
Start of display list
Start of character set
Start of screen memory
The screen memory actually uses only eleven pages. The remaining
space, from page 149 to 160 is cleared to act as a buffer so that the
diagonal scrolling program in box 44 does not bring 'garbage' (actually
the BASIC cartridge) onto the screen.
The program outline is as follows. The strings are DIMensioned
and all but ML$ are defined . Then RAMTOP is lowered and all ofthe
space above RAMTOP is cleared. You can save some typing by
starting out with the previous program and modifying or changing the
appropriate lines. After the character set has been moved and
redefined, a custom display list is constructed . The display list,
112
112
112
LMS
ADDRLO
ADDRHI
LMS
ADDRLO
ADDRHI
~ ;;:
~ ~scr-een location
tI
page 144
145
&
146
147
Lines 330-400 put the display in memory. Lines 420-450 tell ANTIC
where to find the display list and the OS where to find the character set.
Finally, lines 460-560 define the scrolling routine and start things
gomg.
The assembly listing of the scrolling routine is in box 43A. The
listing is fully documented. However, a couple of comments are in
order. As in the previous program, a count value is used to keep from
scrolling beyond the page boundary. There are, of course, other ways
to do this check. One way is to load in a typical LMS address and test
to see if it is within bounds. Also note that there is a curious asymmetry
between what we do to the fine scroll register and the address bytes. To
scroll right, HSCROL is incremented and the address is decremented .
To scroll left, HSCROL is decremented and the address is incremented.
Once again, it would be a good idea for you to rewrite the
program so that the submarine scrolls to the left across the screen.
Never mind that submarines probably don't back up too well! Start
your changes by repositioning the submarine in screen memory and
decrement the screen address bytes. This time however, decrement the
fine scrolling number down from 15 and make use of the fact that the Z
flag is set when DEX results in a zero in the X-register. That will
shorten the routine so watch your branch!
BOX 43
Horizontal Scrolling
Th. Y.llow Bub~arin.
\.
BOX 43A
The Yellow Submarine
Assembly listing for Horizontal Scroll
164,205
200
CPY LIMIT
192,100
BEQ END
240,19
STY COUNT
132,205
LDX SCRLREG 166,206
INX
232
CPX #16
224,16
BEQ COARSE 240,11
STX HSCROL 142,4,212
STX SCRLREG 134,206
LDA #4
169,4
STA TIMER
141 ,26,2
END RTS
96
COARSE LDX#O 162,0
LOOP DEC Dec., sc.fi'; _.'1'. :1
LOSeNMEM;-X- 222,132,133
INX ~~ 232
INX
INX
232
232
224 ,33
CpX#33
208,246
BNELOOP
169,0
LDA #0
STA HSCROL 141,4,212
STA SCRLREG 133,206
169,4
LDA #4
141,26,2
STA TIMER
96
RTS
\..
Box 43A. The Yellow Submarine assembly listing for horizontal scroll
Bo)( 438
DECIMAL ..
164
20:5
200
192
KEYSTROKE
[!]
[;]
DECIMAL ..
19
132
20:5
166
KEYSTROKE
Cl/SM
DECIMAL ..
224
KEYSTROKE
~Cl /P
DECIMAL ..
212
KEYSTROKE
GJ
16
134
240
Gl
206
232
GJ [UGJ GJ
11
GJ
Cl/K ICl/NI Cl / D
206
169
Cl / D FllMl
162
222
96
142
240
ICLlFI0
141
DECIMAL ..
26
KEYSTROKE
Cl/Z CLIB Cl / .
CJ
Cl/,
DECIMAL ..
132
133
232
232
224
KEYSTROKE
Hl0
JCLlDlbl/E!
--- DECIMAL ..
33
KEYSTROKE
DECIMAL II
4
Cl/D
DECIMAL
141
KEYSTROKE
GJ GJ GJ
246
212
133
141
Cl / , !ClIM]
169
[2J IcLl~GJ Q
26
.,
f 0 r- dlago n a I scroll
language 1 ist "ing in 80;< 44A.
contr-ol
2@6
Cl / D
96
NO TE: ML$
ell:
169
GJ GJ GJ
r; EYS TROKE
II
208
232
key
I
I
can be deri v ed
a round
f r-am
inverse vi deo
Diagonal Scrolling
The final scrolling example, in box 44, shows how to program a
diagonal scroll. Except for the fact that both fine scrolling bits are set
in the LMS instruction, all of the interesting differences between this
program and the previous one occur in the scrolling routine which is
written out in detail in box 44A.
Diagonal scrolling involves simultaneous manipulation of both
fine scroll registers. N ow, because we are using Graphics 2, the vertical
fine scroll register goes from 0 to 15, while HSCROL is incremented
from 0 to 7. To keep things simple, we increment VSCROL twice for
each increment of HSCROL. Consequently, both registers reach their
limits together and by testing only HSCROL it is possible to choose
whether or not to branch to the coarse scroll segment. The vertical
coarse scroll differs from the example in box 42 because screen
memory is organized in one page per mode line. Here it is only
necessary to increment the address Hi-Byte to scroll one line .
BOX 44
Diagonal Scrolling
The Yellow Submarine
O=ADR(SUB$)
HID='INT (0/256)
LOO=Q--H I 0*256
POKE 205,LOO:POKE 206,HID
POKE 203,24:POKE 204,134
R=USR(ADR(REDEF$
REM * SET UP CUSTOM DISPLAY LIST *
FOR 1=0 TO 2:POKE 34176+1,1 2:NEXT
FOR 1=0 TO 10:POKE 34179+1* ,119:NEXT
FOR 1=0 TO 10:POKE 34180+[* ,128:NEXT
FOR [=QI TO 1111: F'm:E 34181+[* ,138+1: NEXT
pm~ E 3421:2, 65
F'm~E 34213,128
pm:E 34214,133
REM * TELL ANTIC AND OS WHERE SCREE N MEMORY IS *
REM * PUT SUBMARINE IN MEMOR Y *
REM * POKE INTERNAL CHAR NUMBERS DIRECTL Y TN MEMORY *
POKE 144*256+133,3
FOR 1=1 TD 6:POKE 145*256+ (I:~9+ I ) . (li- ~S ) :NE XT
POKE 146*256+130,10
FOR 1=1 TO 4:F'Of<E 146*256+-(1 31~I+ I) .l.l.:NEXT I
POKE 146 *256+135,12
FIJR 1=121 TO ~~:F'Of' E 147*256+-(13121+I>,l.3+I:I\IE~T
FOR [=0 TO 2:POKE 147* 2 56+(133+[) , 15+I:NEXT
REM * CHANGE CHAR BAS *
POfT 559, QI
POKE 560, 128:POKE 561.133
POf: E 756, 1 ~; 4
POI<E 559, :::4
ML$
REM * INSTALL ADDRESS OF THE SCROLLING ROUTINE *
O=ADR(ML$)
HIO=INT(Q /2 56)
LOQ=Q-HIQ* 256
POKE 552,LOQ:POkE 553,HIQ
REM * SET REGISTERS USED BY SCROLLING ROUTINE *
POKE 205,0:POKE 206,0:POKE 54276,0
POKE 2QJ'7, QI
REM * START SYSTEM TIMER 2 *
pm:: E 538, 10
(30TO 571~
BOX 44A
The Yellow Submarine
Assembly Listing for Diagonal Scroll
LOY COUNT
INY
CPY LIMIT
SEQ ENO
STY COUNT
LOX HSREG
INX
CPX #8
SEQ COARSE
STX HSREG
STX HSCROL
LOX VSREG
INX
\...
164,205
200
192,80
240,28
132,205
166,206
232
224,8
240,20
134,206
142,4,212
166,207
232
232
In 2 scan line increments)
Store value in software and
134,207
142,5,212 hardware registers
169,6
Reset system
141 ,26,2
timer 2
96
Return to VB Processing
COARSE LDX#O 162,0
Load X-reg for indexed addressing
LOOP DEC
LOSCNMEM,X
222,132, 133Change Lo-Byte of screen address
INX
232
I nc X-reg to point to Hi-Byte of
Screen Address
INC HISCNMEM,X254, 132, 1331ncrement Hi-Byte of screen address
INX
232
Increment X-reg to point to next
INX
232
Lo-Byte of the screen address
CPX#33
224,33
Are all screen addresses changed?
208,243
BNELOOP
No? Then branch back to do next one
169,0
LDA#O
If yes , reset
all software
133,206
STA HSREG
and
133,207
STA VSREG
STA HSCROL
141,4,212 hardware
STA VSCROL
141 ,5,212 registers
169,6
LOA #6
Reset system
STA TIMER
timer 2
141,26,2
RTS
Return to VB processing
96
Box 44A. The Yellow Subma rine assembly listing for diagonal scroll
When you plan out programs that are going to run during the
vertical blank, one important thing to remember is to make sure that
the machine language routines are in place before they are called up by
the BASIC program. Otherwise the computer will lock up.
The program in box 45 makes sure everything is in place by
going to a loading subroutine at line 420, right after the submarine has
been put in memory. Since this is a rather lengthy process, a message is
printed in the text window to let the user know what's happening.
After the machine language routines are in place, the registers they use
are set, the system timer is started, the music routine is linked, and the
action begins. Speaking of linking a subroutine to the VB, here is the
routine again: LDY with the Lo-Byte of the routine's address, LDX
with the Hi-Byte, LDA with a 6 for an immediate, or with a 7 for a
deferred vertical blank routine. Then JSR SETVBV. SETBV is at
92,228 (Lo-Byte, Hi-Byte).
In keeping with the format of the book, the entire assembly listing
of the scrolling routine is in box 45A and the assembly listing of the
music routine is in box 45B . However, because of the length and
complex nature of the programs we offer the following explanation.
Basically the scrolling consists of four sections:
A
A
A
A
vertical scroll up
horizontal scroll to the right
vertical scroll down and
horizontal scroll to the left.
can't do this . Why? Becau se the horizontal left routine is executed 100
times before it gets down to zero, and after the first time through,
COUNTI would be set. The program would read that, branch to
VERTUP , and never go back to HORZLFT. For every vertical scroll
up after the first, VERTUP is executed as the default routine when
section I finds only zero CO UNT registers. The register values needed
by VER TUP are provided in section 2.
Notice that the values stored in the COUNT registers for
VERTUP and VERTDN are different. Also, the initial values of the
software scrolling register, VSCLREG, are different in each case. The
reason for this is that it is necessary to use these numbers in order to
make sure that the scrolling rectangle closes and the submarine doesn't
slowly sink into the mud at the bottom of the sea.
Other than this, the scrolling routines are similar to the ones in the
previous programs. First, the program does a fine scroll until the limit
has been reached. Then it branches to a coarse scroll. As in diagonal
scrolling, in this program a coarse vertical scroll is done by in'crementing,
or decrementing the Hi-B yte of the screen address in the LMS
instruction . This reflects the allocation of one page of memory per scan
line. HORZRT is the same as before and HORZLFT is the answer to
the exercise we posed earlier.
The music routine, in Box 45B has three parts:
one which stores music frequency numbers in AUDFI and
AUDF2 (8 bit music)
one which turns the notes off so they do not run together
and
BOX 45
Fi n a l e
Scrol ling and Mus ic
*
*
*
3,22
8 1 5 REM
820 DATA 71,53,22,80 , 53 , 22,85 , 53,
30, 47, 0, 12, 85, 7 I, 30, 85, 71, 8, 85, 7 I , 30 , 85, 7 1 , 8, 85, 71 , 50 , B5 , 71, 3
0 , 85,71,8
825 REM
830 DATA 85,71,30,85 , 71, 8 , 8 5,71,
50,107 , 80,30,107 , 80,8,107,80 , 30 , 107,80,B , 107,80,22,0 , 63 , 30,60
,0,8
835 REM
840 DATA 0,53,64,63 , 0,8 , 0, 7 1, 30,
63,0,8,0,B0 , 64,63,80,30,0,63,8,71, 121,30,0,80,8,95 , 12 1 ,48 , 80,
63,313
845 REM
8513 DATA 13,63,8,71,13,64,13,63,313,
613,13,8,13,53,64,63,13,12,13,71,313,63,13,8,13,813.72
8613 REM
8713 REM READ IN SCROLLING ROUTINE
8813 FOR 1=0 TO 2413:READ ML
8913 POKE 33536+I,ML:NEXT I
895 REM
91313 DATA 164,2133,192,13,2138,24,
164,2134,192,13,208 , 75,164,2135,192,13,2138,123 , 164, 2136,192.13,2138,
613
9135 REM
9113 DATA 169,8,133,2137,1613,913,
169,11313,133,2134 , 169,4,133,2138,136,.132,2133,166,207, 232, 224,16,
2413, 11
915 REM
9213 DATA 142,5,212,134,2137,169,6,
141,26,2,96,162 , 13,254,133,133,232,232,232,224, 33 ,. 2138 , 246 ,. lG9.
13,133,2137
925 REM
9313 DATA 141,5,212,169,6,141,26,
2,96, 76, 195, 131, 169, 85, 133, 2135, 169, 2, 133, 2137 , 136, 132, 2134, 166,
2138,232,224
935 REM
9413 DATA 8,240,11,142,4,212 , 134,
208 , IS9,6, 141,26,2,96, 162,0,222, 132 , 133,232,232,232,224, 3 3,20
8,246,169,13
845 REM
950 DATA 141,4,212,133,208 , 168,6.
14 1 ,26 , 2,86, 169,1013,133,2136,169 , 1 , 133,208,136,132, 205,166,2137
, 202,224,0
955 REM
9613 DATA 2413,11 , 142,5,212,134 ,
207, 168,6,141.26,2,96 , 162,0,222,133,133,232,232, 232. 224 . 33 , 20
8,2 46, 169,15 , 1 33
965 REM
8713 DA TA 207,14 1 ,5,212,169,6,141,
26, 2, 96, 136, 132 , 206, 166, 2138, 202, 224,13, 2413, 11, 142 , 4, 212, 134, 213
8, 169,6,141
975 REM
980 DATA 26,2 , 96,162,13,254,132,
133 , 232,232,232,224,33,2138,246,169,8,141,4.212 , 133,2138,169 . 6,
141,26,2,96
985 REM
890 RE TURN
BOX 45A
Assembly Language Listing
for
Yellow Submarine Scrolling
Register use:
COUNT1 = 203
COUNT2 204
COUNT3 205
COUNT4 206
=
=
=
VSCLREG = 207
HSCLREG = 208
LOY COUNT1
CPY #0
BNE VERTUP
LOY COUNT2
CPY #0
BNE HORZRT
LOY COUNT3
CPY #0
BNE VERTON
LOY COUNT 4
Cpy #0
BNE HORZLFT
164,203
192,0
208,24
164,204
192,0
208,75
164,205
192,0
208,123
164,206
192,0
208,60
169,8
133,207
169,90
COARSE1
LOOP
LOA #100
STA COUNT2
LOA #4
STA HSCLREG
DEY
STY COUNT1
LOX VSCLREG
INX
CPX #16
BEQ COARSE1
STX VSCROL
STX VSCRLREG
LOA #6
STA TIMER
RTS
LOX #0
INC HISCN,X
INX
INX
INX
CPX #33
BNELOOP
LOA #0
169,100
133,204
169,4
133,208
136
132,203
166,207
232
224,16
240,11
142,5,212
135,207
169,6
141,26,2
96
162,0
254,133,135
232
232
232
224,33
208,246
169,0
STA VSCLREG
STA VSCROL
133,207
141,5,212
LOA #6
STA TIMER
RTS
JMP HORZLFT
169,6
141,26,2
96
76,195 ,131
COARSE2
LOOP
LOA#85
STA COUNT3
LOA #15
STA VSCRLREG
DEY
STY COUNT2
LOX HSCLREG
169,85
133,205
169,2
133,207
136
132,204
166,208
232
INX
CPX #8
BEQ COARSE2
STX HSCROL
STX HSCLREG
LOA #6
STA TIMER
RTS
96
LOA #0
DEC LOSCN,X
INX
INX
INX
CPX #33
BNE LOOP
162,0
222,132,133
232
232
232
224,33
208,246
224,8
240,11
142,4,212
134,208
169,6
141 ,26,2
LOA #0
STA HSCROL
STA HSCREG
LOA #6
STA TIMER
RTS
169,0
141,4,212
133,208
169,6
141,26,2
96
COARSE3
LOOP
LOA #100
STA COUNT4
LOA #1
STA HSCLREG
DEY
STY COUNT3
169,100
133,206
169,1
133,208
136
132,205
LOX VCSCLREG
OEX
CPX #0
BEQ COARSE3
STX VSCROL
STX VSCLREG
LOA #6
STA TIMER
166,207
202
224,0
240,11
142,5,212
135,207
169,6
RTS
LOX #0
DEC HISCN,X
INX
96
162,0
222,133,133
232
232
232
224,33
208,246
169,15
INX
INX
CPX #33
BNELOOP
LOA #15
141,26,2
STA
STA
LOA
STA
VSCLREG
VSCROL
#6
TIMER
RTS
133,207
141,5,212
169,6
141,26,2
96
DEY
STY COUNT4
LOX HSCLREG
OEX
CPX #0
BEQ COARSE4
STX HSCROL
STX HSCRLREG
LOA #6
STA TIMER
COARSE4
LOOP
136
132,206
166,208
202
224,0
240,11
142,4,212
134,208
169,6
141,26,2
RTS
LOX #0
INC LOSCN ,X
96
162,0
254,132,133
INX
INX
INX
CPX #33
BNELOOP
LOA #8
STA HSCROL
STA HSCLREG
LOA #6
STA TIMER
RTS
232
232
232
224,33
208,246
169,8
141 ,4,212
133,208
169,6
141,26,2
96
r
BOX 45B
MUSTIMER = 1536
DATACNT = 1537
CYCLE = 209
166,209
224,1
240,20
OATACNT 174,1 ,6
TABLE,X 189,0,132
AUOF1
141 ,0,210
232
TABLE,X 189,0,132
AUOF2
141 ,2,210
232
and store duration in
189,0,132 MUSTIMR
STA MUSTIMR 141,0,6
TABLE ,X
INX
CPX TABLENO
BEQ REPEAT
STX OATACNT
LOA #0
STA CYCLE
JMP XITVBL
232
224,186
240,10
142,1,6
169,0
132,209
REPEATLOA #0
169,0
STA CYCLE
133,209
STA OATACNT 141,1,6
LOA #20
169,20
STA MUSTIMR 141,0,6
JMP XITVBL
76.98.228
PADDLE 0
Notice that the tablet is laid out the same as quadrant I of a normal
X-Y coordinate system with the origin in the lower hand corner. This is
different from how coordinates are laid out on the TV screen where the
origin is at the upper left hand corner. The Koala Pad, on the
other hand uses the same layout as the screen display with the origin in
the upper left hand corner and PADDLO giving the X values and
PADDLl giving the Y values.
In order to make use of a touch pad (digitizer) for input you need
to know how the PADDLO and PADDLl numbers are mapped on to
the pad. The program in box 46 will help you to do this. Cut a piece of
graph paper withY4inch squares the size of the sensitive surface and lay
it on the pad. Plug your digitizer into Port I. When run, the program
reads PADDLO and PADDLl every 1/ 6th second during the vertical
blank storing the values in page 158. It waits for a while at line 145 to
allow the reading to be completed and then prints out the values on the
screen. Reading the paddle values during the vertical blank is more
accurate than doing it from BASIC. This is particularly true for the
Atari Touch Tablet which has the quicker response and sensitivity of
the two digitizers. By running the program several times and making
contact with the pad at different places you can prepare a diagram with
the paddle values obtained.
As an example of what can be done with a digitizer, Box 47
contains a program to play music by simply moving the stylus around
the surface.
BOX 46
Reading tb e Atari Toucb Tabl e t
5 REM ** PROGRAM TO TEST TOUCH TABLETS **10 REM * Lm~ER RAMTOP TO RESERVE SPACE FOR DATA *
20 POKE 106, 158:GRAPHICS 0
30 REM * LOAD I N ROUTINE TO READ PADDL0 / PADDLl DURING VB t.
40 FOR 1=0 TO 37 :READ ML
50 POKE J536+ I ,ML:NEXT I
60 DATA 164,204,136,132,204,
192,0,208,26,160,10,132,204, 16 6, 203 ,22 4, 254,2 40 , 16,232,173, 11
2,2
70 DATA 157,0,158,232,173 , JJ 3,2, 157,0, J58,1 34.203 . 76,88.22 8
80 POKE 203,0: POKE 204, 10
90 REM '" LOAD IN VB LINKING ROUTINE *'
100 FOR 1=0 TO 10:READ ML
110 POKE 1684+1,ML:NEXT I
120 DATA 104,160,0,162,6,1 69 ,7, 32,92,228 , 96
130 X=USR(1684)
140 REM DELAY
DATA TO BE READ *
150 FOR 1=0 TO 6000
160 NEXT I
170 REM * PRINT OUT PADDL0 / PADDL1 DATA .t.
180 FOR 1= 1 TO 255
190 PRINT rEEK(40448~r);"
200 NE XT r
*'
BOX 46A
Register Use :
204
203
LOY TIMER
DEY
STY TIMER
CPY #0
BNE END
LOY TIMER
STA TIMER
164,204
136
132,204
192,0
208,26
160,10
132,204
LOX,COUNT
CPX FINAL
BEQ END
166,203
224,254
240,16
INX
LOA PAOOLO
STA TABLE,X
INX
LOA PAOOL 1
232
173,113,2
157,0,158
232
173,112,2
Increment offset
Get paddle 0 value
Store in Table
Incroment offset
Get paddle 1 value
STA TABLE,X
STX,COUNT
JMP,XITVBL
\...
157,0,158
134,203
76,98,228
Store in table
Save Offset
Leave vertical blank processing
Reset
Timer
BOX 47
Atari Touch Tablet Music
10 REM ** PROGRAM TO PLAY MUSIC WITH TOUCH PAD **
20 FOR I=0 TO 27:READ ML
30 POKE 1536+I,ML:NEXT I
4~ DATA 164,21214,136,132,204, 192,0,208,16,164,10,132
50 DATA 21214,173,112,2,141,0,
210,173,l13,2,141,2,210,76,98,228
60 FOR I=0 TO 10:READ ML
70 POKE 1664+I,ML:NEXT I
80 DATA 104,160,0,162,6,169,7, 32,92,228,96
9121 POKE 53768,0:POKE 53775,3:POKE 204,10
11210 POKE 53761, 168:POKE 53763,168
110 X=USR(1664)
121?J GOTO 12121
Once again the program reads PADDLO and PADDLl during the
vertical blank. However, this time it stores the values in AUDFI and
AUDF2 which have been initialized for pure tones. This is a simple
program which we have left for you to disassemble. It makes use of a
timer register on page 0 (204) and reads the paddles every 10th vertical
blank. As written, the program addresses the Atari Touch Tablet and
needs to be modified for the Koala Pad by shortening the delay value
used in the timer.
In addition to the touch sensitive surface which inputs paddle
numbers, the digitizers have either two (Koala Pad) or three (Atari
Touch Tablet) switches. The status of these switches can be monitored
by reading the STICK or STRIG registers. Table 6-2 lists the ports to
read and the values produced when each switch is closed. Additionally,
the hardware and shadow registers for the STICK and STRIG ports
are listed.
Left Switch
Right Switch
Probe Switch
Left switch afld probe
Right switch and probe
Left and right switch
(x)
Kaola Pad
Value
Atari
Value
Stick( x)
Stick(x)
11
7
Stick(x)
- - - - ----
--
--------
--
--------
--
Stick(x)
11
7
14
10
6
3
Stick(x)
Stick(x)
Stick(x)
Stick(x)
Stick(x)
STRIG
Shadow Register
Hardware Register
STRIG(O)
STRIG(1)
STRIG(2)
STRIG(3)
644
645
646
647
53264
53265
53266
53267
STICK(O)
STICK(1)
STICK(2)
STICK(3)
632
633
634
635
54016
54016
54017
54018
Bits
Bits
Bits
Bits
Do - 0 3
04 - 07
Do - 0 3
04 - 07
When writing programs that use digitizer pads, there are several
ways to regard them as input devices. One common way is to think of
the pad surface as the primary input source, and use the switches to
control program branching between different program segments that
process this input. Another way to use them is to partition the surface
into areas, each of which is associated with some program action. This
is the sort of programming that is done when you use the stylus to pick
an icon for paint or draw. Another way to look at them is to consider
the geometry involved. The pad can be thought of as a grid of
approximately 220 horizontal and 220 vertical lines. Where these lines
meet defines a point. The total number of points is approximately
48400. Each point is labelled with two numbers and since order is
important, each point can be distinguished from every other point.
Thus, in principle a digitizer pad can be used to input 48400 separate
pieces of information . Combine this with the switches and you can
input up to 242 ,000 pieces of information. Granted this is a rather
abstract way in which to regard the touch pads , but it is one with many
possibilities that have not yet been explored in any depth.
Appendix A
ADC
AND
ASl
BCC
BCS
BEQ
BIT
BMI
BNE
BPl
BRK
BVC
BVS
ClC
ClD
CLI
ClV
CMP
281
CPX
CPY
DEC
DEX
DEY
EOR
INC
INX
INY
JMP
JSR
LOA
LOX
LOY
LSR
NOP
ORA
PHA
PHP
PLA
PLP
ROL
ROR
RTI
RTS
sec
SEC
SED
SEI
STA
STX
STY
TAX
TAY
TSX
TXA
TXS
TYA
Appendix B
and use pages 156 through 159 (39936-40960). Remember that you
need a buffer above RAMTOP since each time the screen is cleared the
OS clears beyond RAMTOP. The program will next give you the
option to continue , quit, list or print. If you choose to continue, an
input prompt is displayed on the screen. The input asked for is a string
283
PR
DAT
DAT SUF
t
1
1
Field
Field
Field
Field
Field
5
4
3
2
1
Appendicies 285
= implied or accumulator
= immediate addressing
=absolute addressing
0 page,Y indexed
addressing
MNEMONIC + 2 data nos,X
addressing
= absolute,X indexed
= absolute,Y indexed
MNEMONIC+ (data,X)
MNEMONIC + (data),Y
JSR + (
= indirect indexed
) = absolute indirect
APPENDIX B
ASSEMBLER
1000
10111'
1020
1030
1040
1~9~
11~~
Z-0:CODES"":DAT1-0:DAT2-~
10~~
107~
1~7~
1~B~
PRINT CHRS(12~)
112111 PRINT "PRESS (RETURN> TO CONTINUE":PRINT "PRESS [Q] TO
IiIUIT":PRINT "PRESS [Pl TO PRINT"
112~ PRINT "PRESS [Ll TO LIST"
113~ INPUT AS
114111 IF A'-"" THEN GOTO 117111
11~1II IFA "Q" THEN END
116111 IF A. .. P" OR A."L" THEN OOTO 163~
116~ GOTO 112f/J
117f/J PRINT CHR.(12~):POSITION 4,4:POKE 7~2,1
llB~ PRINT "MNE PR DAT DAT aUF
PC-", PC
119~ POSITION 4,6:PRINT .2, "?"
12~0 GET .1,S:S CHR.(S):ZZ+1
121~ POSITION 3+Z,6:PRINT .2,SS
122~ CODES(LEN(CODES)+1)-S$
1230 IF Z.19 THEN GOTO 1290
1240 IF Z(19 AND as.CHR.(1~~) THEN GO TO 126~
12~" POSITION 4+Z,6:PRINT .2,"?":GOTO 12~~
126~ FOR I.LEN(CODE.) TO 18
127~ CODES(I,I)-" "
12B~ NEXT I
1290 POSITION 4,B:PRINT .2, "CHANGE ?? (YIN)"
13~0 INPUT ANS$
131~ IF ANSS"Y" THEN GOTO 110111
1320 IF ANS .... N" THEN GOTO 134111
1330 GOT a 129111
134111 MNS.CODES(l,3):PRES-CODES(~,6)
13~0 DAT1SCODES(S,10):DAT2S-CODE$(12,14)
1360 SUF CODES(16,1B)
13'70 IF DATU."
"AND DAT2$-"
"THEN DC'"I1I:GOTO 141110
13B0 IF DATU< >"
"AND DAT2$-"
"THEN DC-l: GOTO 1400
1390 DC-2
1400 GOSUB 1900
1410 PRINT CHR$(12~)
1420 PRINT :PRINT
143111 POKE 7~2,0
1440 PRINT "MNEMONIC:
",MNS;"
"; "!liP CODE:
";OP
1450 PRINT "ADDR MODE: "IPRES;" ";SUFS
1460 PRINT "DATA CNT:
";DC
111~
Appendicies 287
2140 IF MN.="STX"
3600
2150 IF MN$="TYA"
2160 IF MN$=-"STA"
36"121
217121 IF MN.=-"TXS"
218" IF MN.-"STA"
360121
219121 IF MN.-"LDY"
36"0
22"" IF MN'-"LDA"
36""
221" IF MNt-"LDX"
222" IF MN.-"LDY"
OP-164:GOTD 36121121
223" IF MN.-"LDA"
OP-165:GOTO 36"121
224" IF MNt-"LDX"
OP-166:GOTO 36""
225" IF MNt-"TAY"
226" IF MNt-"LDA"
227" IF MNt-"TAX"
228" IF MNt-"LDY"
36""
229" IF MNt-"LDA"
36""
23121" IF MNt""LDX"
36""
231" IF MN. .. BCS"
2320 IF MNt-"LDA"
360"
233" IF MN.-"LDY"
3600
234" IF MN.-"LDA"
36"0
235" IF MN.-"LDX"
360121
236" IF MN.""CLV"
2370 IF MNt-"LDA"
3600
238" IF MN.="TSX"
2390 IF MN.-"LDY"
361210
24121" IF MN."'''LDA''
36121"
2410 IF MN.="LDX"
36121121
2420 IF MN.="CPY"
243121 IF MN.'" "CMP ",
36121121
244" IF MN.="CPY"
OP-196:GOTO 361210
2450 IF MN."'''CMP''
OP=197~GOTO 3600
..
AND PREt-".
THEN OP-162:GOTO 36"121
AND DC-l AND PRE.-". " AND SUFt-"
" THEN
AND DC-l AND PRE.-"
" l'HEN
..
" THEN
AND
AND
AND
AND
AND SUFt- ..
THEN OP-181:GOTO
..
AND SUF.="
" THEN
AND SUF.="
..
THEN
Appendicies 289
246121
36130
2470
2480
249t11
2:5"tII
2:51t11
36"tII
2:52t11
36"tII
2:53/11
2:54/11
36
2:5:5/11
36"0
2:56/11
36111/11
2:578
2:58l1li
MNS""INY"
MN$-"CMP"
MNS-"DEX"
MN$-"CPY"
MN$-"CMP"
AND
AND
AND
AND
AND
368
26 IF I1N$-"DEC"
361.
261. IF MN$-;'CPX"
262t11 ~F MN$-"SBC"
36"l1li
263" IF I1N$-"CPX"
OP-228:GOTO 36"0
264" IF MN$-"SlBC"
OP-229: GOTO 36111"
26:5l1li IF MN$-"INC"
361118
266l1li IF MN$-"INX"
267l1li IF MN$-"SBC"
268l1li IF I1N$-"NOP"
269" IF I1N$-"CPX"
27"tII IF MN.-"SBC"
36"0
271t11 IF MN$-"INC"
36121t11
272" IF MN$-"BEQ"
273J1 IF MN$ .. "SBC"
36"tII
274t11 IF MNS-"SBC"
361210
27:5121 IF MN.-"INC"
361210
2760 IF MNS","SED"
277121 IF MNS-"SBC"
361ill1'
278r!1 IF MNS-"SBC"
361210
27911l IF MNS-"INC"
" THEN
" THEN
361/.1~1
280'" IF MN$="8RK"
2810 IF MN$"'''ORA''
2820 IF MN$="ORA"
283" IF MNS""ASL"
2840 IF MN.="PHP"
28:50 IF MN$ .. "ORA"
2861!J IF MN$ .. "ASL"
287f2! IF MN ... "ORA"
36"0
2880 IF MN$-"ASL"
36f/:10
2890 IF MN.-"BPL"
291210 IF MNS .. "ORA"
2910 IF MNS-"ORA"
36f/:10
292111 IF MNs-"ASL"
36f/:10
293111 IF MNs-"CLC"
2940 IF MNS-"ORA"
36f/:10
29:5/11 IF MNS-"ORA"
36121121
296111 IF MNS .. "ASL"
36/11/11
297f2! ~F MNs="JSR"
298121 IF MN.-"AND"
360111
2990 IF MN.-"BIT"
30f/:10 IF MN$ .. "AND"
OP-37:GOTO 36013
3f/:110 IF MN.-"ROL"
36f/:1f2!
302" IF MNS-"PLP"
303f2! IF MNS.. "AND"
3040 IF MN ... "ROL"
30:50 IF MN$","BIT"
3060 IF MN$="AND"
3600
3070 IF MN$="ROL"
3600
3f2!80 IF MN$="BMI"
309f2! IF MNS .. "AND"
36f2!0
311210 IF MN$="AND"
36f2!0
3110 IF MN$="ROL"
36f2!1ZI
312" IF MNS="SEC"
3130 IF MNS""AND"
36f2!0
3140 IF MN$="AND"
361210
31512' IF MN$="ROL"
AND
AND
AND
AND
AND
AND
AND
AND
" THEN
Appendicies 291
3600
3160 IF MN$="RTI" AND DC=l~ THEN OP=64: GO TO 361~1'
3170 IF MN$="EOR" AND DC=l AND SUF$=",X)" THEN OP=65:GOTO
36121121
360121
Appendix C
BASIC Disassembler
The BASIC disassembler is an example of a simple look-up table
translator. By PEEKing consecutive memory locations and comparing
their contents to the OP CODES of the 6502 instruction set, it is able to
generate a list of mnemonics and operands. Operand is a general term
used to refer to the addresses or data numbers following an OP CODE.
As mentioned in the previous appendix, the disassembler can be used
in conjunction with the assembler or, to disassemble someone else's
machine language routine. To use the disassembler in this manner you
should add the following lines to the beginning of the program:
100 FOR 1=10 TO NUMBER
120 READ ML:POKE MEMORY+I,ML
130
140
150
160
NEXT 1
REM DATA NUMBERS HERE
REM DATA NUMBERS HERE
REM DATA NUMBERS HERE
293
NUMBER in line 100 is 1 less than the total data numbers in the
program you are disassembling. MEMORY in line 120 is the place
where you want to store the data numbers. This is usually page 6
(1536), but you could store them above RAMTOP. If that is your
choice add lines:
80 POKE 106,PEEK(106)-8
90 GRAPHICS 0
This is a forced read command and must be used with some care. It
should precede all other lines in the program.
When you run this program you will find that the addresses are
listed in hexadecimal. In this book we have not made use of hex
numbers beyond the introduction to number systems in chapter one.
That was a deliberate choice on our part since all of the machine
language routines we have discussed were meant to be called by
BASIC, and BASIC requires decimal numbers. However, many
programmers use hexadecimal numbers and so it is useful to become
familiar with them. By exposing you to hex numbers here we believe
that you can begin to get used to them without being forced into
innumerable conversions between number systems. Of course, if you
wish, you can modify the program to output the addresses in decimal.
Appendicies 295
APPENDIX C
4000
41211121
4020
412130
412140
412150
411J611J
4070
411J811J
411J911J
4111J11J
41111J
4120
4130
41411J
4150
41611J
41711J
4180
4190
4211J11J
4210
42211J
42311.1
4240
42:511.1
42611J
4270
42811J
42911.1
4300
4310
43211J
4330
43411J
4350
43611J
43711J
438121
43911J
4412111.1
44111J
44211J
44311J
444121
44!5121
446121
44711J
448121
4490
450121
451111
OPEN #2,5,0,"E:"
REM DISASSEMBLER VERSION 1.0
REM
PRINT CHR$ (125)
REM
DIM HEX$(16),AS(5),ADDR$(5),PRE$(2),SUF$(3),LINE$(120)
DIM MNS(3),OP$(3),B$(1),HEX2$(1),HEX3$(1),HEX4$C1)
HEXS .. "12I123456789ABCDEF"
PRINT
PRINT "6502 IN-MEMORY DISASSEMBLER"
PRINT
PRINT
REM
PRINT "ENTER STARTING ADDRESS IN DECIMAL"
INPUT AS
IF AS-"" THEN END
A-VAL CAs)
PRINT CHRs C125)
PRINT
PRINT" ADDR
MNEM
OP CODE
DATA"
PRINT
REM DISPLAY ONLY 18 LINES AT A TIME
CNT--1:LINE--1
eNT-CNT+1:LINE=LINE+1
IF LINE-18 THEN GOTO 4470
ADDR-CNT+A
BOSUS 4550
REM READ MEMORY
P-PEEKCADDR)
OPS-STRSCP)
MNS-"???":PRE$=" ":SUFs="
DC-IIJ:R-II.I:RL=11J
B06US 46711J
REM PRINTOUT SECTION
IF DC-1 THEN GOTO 4380
IF DC-2 THEN GOTO 441121
PRINT" "IADDRs;"
";MN$;"
";OP$
ADDRS-"":GOTO 4230
PRINT" ";ADDR$;"
";MN$;"
";OPS;"
";PRE$;
CNT-CNT+1:ADDR~CNT+A:DTA=PEEKCADDR):PRINT DTA;SUF$
ADDRS-"":GOTO 4230
";PRE$;
PRINT" "IADDR$;"
";MNS; '"
";OP$;"
CNT=CNT+1:ADDR=CNT+A:DTA=PEEKCADDR)
PRINT DTA;
CNT=CNT+1:ADDR=CNT+A:DTA=PEEKCADDR)
PRINT ", "; DTA; SUF$
ADDRS=" " : GO TO 4231~
REM PAUSE SECTION
P FOR PRINT"
' N' FOR NEXT
PRINT "( RETURN > TO END
TRAP 4500
INPUT B.
IF BS="" THEN END
4520
4530
4540
4550
ADDR$(LEN(ADDR$)+1)~HEX3$
463~
HEX4mINT(ADDR-HEX1*4~96-HEX2*256-HEX3*16)
HEX4$=HEXS(HEX4+1,HEX4+1)
465~ ADDR$(LEN(ADDRS)+1)-HEX4$
466~ RETURN
4670 REM LOOK-UP TABLE
468~ IF P-129 THEN MN$="STA":DC ml:PRE$"'''
(":SUF$-",X)":GOTO
6180
4690 IF P-132 THEN MNS""STY":DC-l:GOTO 6180
471211Z' IF P-133 THEN MN$""STA":DC-1:GOTO 6180
471121 IF P-134 THEN MN$-"STX":DC-l:GOTO 6180
472121 IF P-136 THEN MN$""DEY":GOTO 6180
473121 IF P-138 THEN MN$="TXA":GOTO 618~
474121 IF P-140 THEN MN$-"STY":DC-2:GOTO 6180
47:5121 IF P-141 THEN MN$-"STA":DC-2:GOTO 618~
4760 IF P-142 THEN MN$-="STX":DC-2:GOTO 6180
4770 IF P"144 THEN MN$-"BCC":DC-l:GOTO 6180
4780 IF P-145 THEN MN$-"STA":DC-l:PRE$-" (":SUF$-"),Y":GOTO
6180
4790 IF P .. 148 THEN MNS="STY":DC-l:SUFS-",X ":GOTO 6181~
4800 IF P-149 THEN MN$-"STA":DC-l:SUFS-",X ":GOTO 618121
48U' IF P-l:5121 THEN MNS-"STX":DC-l:SUFS-",Y ":GOTO 6180
4820 IF P"1:52 THEN MN$-"TYA":GOTO 6180
4830 IF P"153 THEN MN$-"STA":DC-2:SUF$"",Y "
4840 IF P-154 THEN MN$-"TXS":GOTO 6180
4850 IF P-l:57 THEN MN$""STA":DC-2:SUFS=",X ":GOTO 6180
4860 IF P-160 THEN MNS="LDY":DC-=l:PRES-"* ":GOTO 6180
4870 IF P-161 THEN MNS="LDA":DC"'l:PRE$=" (":SUFS=",X) ":GOTO
6180
4880 IF P=162 THEN MN$="LDX":DC=l:PRE$="* ":GOTO 6180
4890 IF P=164 THEN MN$="LDY":DC-1:GOTO 6180
4900 IF P=165 THEN MN$="LDA":DC=1:GOTO 6180
4910 IF P"166 THEN MN$="LDX":DC-1:GOTO 6180
4920 IF P=168 THEN MNS="TAY":GOTO 6180
4930 IF P=169 THEN MN$="LDA":DC-=1:PRE$="# ":GOTO 6180
4940 IF P=170 THEN MN$="TAX":GOTO 6180
4950 IF P=172 THEN MN$="LDY":DC-2:GOTO 6180
4960 IF P=173 THEN MN$="LDA":DC=2:GOTO 6181~
4970 IF P=174 THEN MN$="LDX":DC=2:GOTO 6180
4980 IF P=176 THEN MN$="BCS":DC=1:GOTO 6180
4990 IF P=177 THEN MN$="LriA":DC=1:PRE$=" (":SUFS="),Y":GOTO
6180
51111210 IF P=180 THEN MNS="LDY":DC=l:SUF$=",X ":GOTO 618(1)
5010 IF P=181 THEN MNS="LDA": DC=l: SUF$=". X ": GOTO 618f!I
464~
Appendicies 297
502'11 IF
503~1 IF
510410 IF
5105~1 IF
512'60 IF
5070 IF
5080 IF
5090 IF
5100 IF
6180
5110 IF
5120 IF
5130 IF
5140 IF
~150 IF
5160 IF
5170 IF
5180 IF
519. IF
520121 IF
521111 IF
618111
5220 IF
523111 IF
524111 IF
5250 I.F
52611.1 IF
5270 IF
5280 IF
5290 IF
6180
5300 IF
5310 IF
5320 IF
5330 IF
5340 IF
5350 IF
5360 IF
53712' IF
53812' IF
5390 IF
541210 IF
61812'
541117 IF
54212' IF
54310 IF
54412' IF
54510 IF
5460 IF
5470 IF
:5480 IF
618117
5490 IF
55f!'!!} IF
P=182
P=184
P=185
P=186
P=188
P=189
P=-190
P=192
P=193
THEN
THEN
THEN
THEN
THEN
THEN
THEN
THEN
THEN
p c 196
P"197
P"198
P=200
P"21171
P"21172
P=204
P-21215
P-21216
P"208
P-21219
THEN
THEN
THEN
THEN
THEN
THEN
THEN
THEN
THEN
THEN
THEN
MNS-"CPY":DC~l:GOTO 6180
MN$""CMP":DC"l:GOTO 6180
MNS-"DEC":DC=l:GOTO 61811.1
MN$=" I NY" : GOTO '618.0
MN$="CMP":DC=1:PRES-"tI ":GOTO 618117
MN$="DEX":GOTO 6180
MNS-"CPY":DC=2:GOTO 618121
MNS""CMP":DC"2:GOTO 6180
MNs-"DEC":DC-2:GOTO 6180
MNS-"BNE":DC-1:GOTO 618121
MNS="CMP":DC=l:PRES=" (":SUF.-"),Y":GOTO
P-213
P-214
P-216
P-217
P-221
P-222
P=224
P"'225
THEN
THEN
THEN
THEN
THEN
THEN
THEN
THEN
P=228
P-229
P-23121
P-232
P=233
P=234
P=236
P=237
P=238
P=240
P=241
THEN
THEN
THEN
THEN
THEN
THEN
THEN
THEN
THEN
THEN
THEN
MN$="CPX":DC-1:GOTO 6180
MNS="SBC":DC-1:GOTO 6180
MN$-"INC":DC-1:GOTO 618121
MN$-"INX":GOTO 618121
MN$="SBC":DC-1:PRES-"tt ":GOTO 6180
MNS="NOP":GOTO 618121
MNS="CPX":DC=2:GOTO 6180
MN$="SBC":DC=2:GOTO 61812'
MN$="INC":DC=2:GOTO 6180
MN$="BEQ":DC=l:GOTO 61812'
MNS="SBC":DC=1:PRE$=" (":SUF$="),Y":GOTO
5511~
552@
5530
5540
5550
5560
557111
6180
5580
5590
5600
561111
5620
5630
5640
5650
618111
5660
5670
5680
5690
5700
5710
5720
5730
5740
5751J
5760
6180
577111
578111
579111
581110
5810
582111
5830
584111
6180
585el
5860
587117
5880
5890
59117117
5910
5920
5930
6180
5940
5950
596el
5970
5980
5990
IF
IF
IF
IF
IF
IF
IF
IF
IF
IF
IF
IF
IF
IF
IF
P"21
P-22
P-24
P-25
P"29
P-30
P-32
P-33
THEN
THEN
THEN
THEN
THEN
THEN
THEN
THEN
MN$="ORA":DC- 1:SUF$=",X
MNSc"ASL":DC = l:SUFS=",X
MNS-"CLC":GOTO 6180
MNS""ORA":DC=2:SUF$=",Y
MNS:"ORA":DC-2:SUFS-",X '
IF
IF
IF
IF
IF
IF
IF
IF
IF
IF
IF
P-36
P-37
P-38
P-4111
P-41
P-42
P-44
P-45
P-46
P-48
P-49
THEN
THEN
THEN
THEN
THEN
THEN
THEN
THEN
THEN
THEN
THEN
MNS-"BIT":DC-1:GOTO 6180
MNS-"AND":DC-1:GOTO 6180
MNS-"ROL":DC-l:GOTO 6180
MNS-"PLP":GOTO 6180
MNS-"AND":DC-1:PRE$a:"4t ":GOTO 6180
MNS"ROL":GOTO 6180
MNS-"BIT":DC-2:GOTO 61813
MNS-"AND":DC-2:GOTO 6180
MNS"ROL": DC=2: GO TO 6180
MNS-"BMI":DC-l:S0TO 6180
MNS-"AND":DC-l:PRE$-" ( " : SUFS=" l , Y" : GO TO
IF
IF
IF
IF
IF
, IF
IF
IF
P-53
P-54
P-56
P-57
P-il1
THEN
THEN
THEN
THEN
THEN
P~62 THEN
P-64 THEN
P-65 THEN
MNS:"ASL":DC - ~:SUFS=",X
":GOTO 6181~
":GOTO 61812'
":GOTO 6180
":GOTO 6180
":GOTO 6180
MNS-"JSR":DC-2:GOTO 6180
MNS-"AND": DC'"' 1: PRE$=" ( " : SUF$=" , x l
":GOTO
IF
IF
IF
IF
IF
IF
IF
IF
IF
IF
tF
IF
IF
IF
IF
P=85
P=86
P=88
P=89
P=93
P=94
THEN
THEN
THEN
THEN
THEN
THEN
MNS"'"EOR"
MNS="LSR"
MNS-"CLI"
MN$=';EOR"
MN$="EOR"
MN$="LSR"
DC=l: SUF$=", X
DC=1:SUF$=",X
GOTO 6181<1
DC=2 SUF$=",Y
DC=2 SUF$=",X
DC=2 SUF$=",X
":GOTO 6181!!
": GOTO 6181!!
"
GOTO 6180
" GO TO 6181!!
" GO TO 618'"
Appendicies 299
60013
61l' 113
6180
6020
6030
6041!1
61!1:'.51!1
6061!1
61!171!1
6181!1
6f2181!1
6f2191!1
611!1"
6111!1
618"
612"
6131!1
6141!1
61:511'
61611'
61711'
61811'
61911'
62f2111'
62111'
6221!1
6231!1
6241!1
(":SUF$=",X)":GOTO
MNS="ADC":DC=l:GOTO 6181~
MNS="ROR":DC-l:GOTO 6180
MN$=" PLA" : GOTO 61811'
MNS-"ADC":DC-l:PRE$","tI ":GOTO 6180
MN$="ROR":GOTO 6180
MNS-"JMP":DC-l:PRE$=" (":SUF$-")
":GOTO
IF
IF
IF
IF
IF
IF
P-1I2'1
P"102
P-104
P-ll!1:5
P-106
P-1I2'8
IF
IF
IF
IF
":GOTO 6180
":GOTO 6180
" GOTO 6180
" GOTO 6180
" GOTO 6181!1
Appendix D
Memory Map
This memory map is arranged to give you an overview of the
organization of Atari memory . We have given emphasis to the specific
memory locations that are directly useful in terms of sound and
graphics as explained in the text of this book. See the end of the
memory map for sources of the complete memory allocations.
LABEL
301
POKMSK
BRKKEY
16
17
RTCLOCK
18,19,20
10
11
POKEY interrupts
Indicates status of the
BREAK key
12,13,14 Realtime clock
CRITIC
66
42
ATRACT
DRKMSK
COLRSH
LMARGN
77
78
79
82
4D
4E
4F
52
RMARGN
ROWCRS
COLCRS
83
84
53
54
55 ,56
DINDEX
SAVMSC
87
88,89
57
58,59
LDROW
90
5A
OLDCOL
91 ,92
5B ,5C
OLDCHR
93
5D
ADRESS
100,101
64,65
RAMTOP
106
6A
Appendicies
303
LOMEM
128,129
80,81
MEMTOP
144,145
90,91
STOPLN
186,187
BA ,BB
ERRSAVE
195
C3
------
203-207
-----
208-209
210-211
-----
Page 1 - The Stack are at locations 256 - 511 . Machine language , JSR,
PHA and interrupts result in data bei ng written to page I; R TS , PLA,
and R TI instructions read data from page I.
VOSLST
VPRCEO
VINTER
VBREAK
VKEYBO
VTIMR1
VTIMR2
VTIMR3
VIMIRQ
512,513
514,515
516,517
518,519
520,521
528,529
530,531
532,533
534,535
200 ,201
202,203
204,205
206,207
208,209
210,211
212 ,213
214,215
216,217
Locations 536 - 558 are used for the system software timers and are
accessed by assembly language. T hese timers count backwards every
sixtieth or thirtieth of a second until ~hey r~ac1!zero.
CDTMV1
CDTMV2
CDTMV3
CDTMV4
System
System
System
System
System
timer
timer
timer
timer
timer
1 value
2 value
3 value
4 value
5 value
536,537
538,539
540,541
542,543
544,545
218,219
21A,21 B
21 C,21 D
21 E,21 F
220 ,22 1
546,547
VVBLKD
CDTMA1
CDTMA2
CDTMF3
SRTIMR
CDTMF4
548,549
555
556
224,225
226,227
228,229
22A
22B
22C
INTEMP
557
22D
CTMF5
SDMCTL
SDLSTL
558
559
560,561
CDTMV5
VVBLKI
550,551
552,553
554
SSKCTL
SPARE
LPENH
562
563
564
LPENV
BRKKY
565
566,567
568,569
581
623
GPRIOR
address
VB deferred jump address
System timer 1 jump addr
System timer 2 jump addr
System time 3 flag
Software repeat timer
System timer 4 flag
Temporary register used by
SETVBL
22E
System timer 5 flag
22F
DMA enable
230,231 Hi-Byte/ Lo-Byte of the
starting address of the
display list
232
Serial port control
233
No OS use
234
Horizontal value of light
pen
235
Vertical value of light pen
236,237 Break key interrupt vector
238,239 Two spare bytes
245
Spare byte buffer
26F
Priority selection register shadow of 53275.
Appendicies 305
PADDLO
PADDL 1
PADDL2
PADDL3
PADDL4
PADDL5
624
625
626
627
628
629
271
272
273
274
275
PADDL6
PADDL7
630
631
276
277
STICKa
STICK1
STICK2
STICK3
632
633
634
635
278
279
27A
278
Value
Value
Value
Value
PTRIGO
636
27C
Determines if trigger or
button on paddle has been
pressed
PTRIG1
PTRIG2
637
638
27D
27E
PTRIG3
PTRIG4
PTRIG5
PTRIG6
PTRIG7
639
640
27F
280
641
642
643
281
282
283
STRIGO
644
284
STRIG1
STRIG2
STRIG3
645
646
647
285
286
287
270
Value
Value
Value
Value
Value
of
of
of
of
of
paddle
paddle
paddle
paddle
paddle
a
1
2
3
4
Value of paddle 5
Value of paddle 6
Value of paddle 7
of
of
of
of
joystick
joystick
joystick
joystick
a
1
2
3
------ -- --------
651
652,653
654,655
288
Spare byte
28C,28D OS ROM interrupt handler
28E,28F Spare bytes
Locations 656 - 703 are used for screen RAM display handler and
depends on the Graphics Mode.
TXTROW
TXTCOL
TINDEX
656
657,658
659
TXTMSC
660,661
PCOLRO
PCOLR1
PCOLR2
PCOLR3
COLORO
704
405
406
707
708
2CO
2C1
2C2
2C3
2C4
COLOR1
709
2C5
COLOR2
710
2C6
COLOR3
711
2C7
COLOR4
712
2C8
Appendic ies
307
713-735
736-739
740
CRSINH
741,742
745
752
KEYDEL
CH1
753
754
CHAT
CHABAS
CHAR
755
756
757-761
762
ATACHR
763
CH
764
FILDAT
DSPFLG
765
766
SSFLAG
767
-----------
RAMSIZ
MEMTOP
------
------
2F1
2F2
Page three: The locations 768 to 831 are the device handler and vectors
to the handler routines.
Locations 832 - 959 are used for the eight Input j Output control
blocks. These are the channels for the transfer of data into and out of
the computer, or between devices.
PRNBUF
960-999
CASBUF
1021-1151
Locations 1152 - 1791 are for user RAM requirements. There are 128
spare bytes available at location 1152 - 1279 if you don't use the
floating point package at locations 1406 - 1535.
Locations 1536 - 1791 are on page six and are not used by the OS.
These locations may be used safely for machine language routines,
redefined character sets and whatever the programmer can fit into this
space.
Locations 1792 - 2047 (page 7) are the user boot area. Locations 1792
to the address of LOMEM at 128, 129 are also used by DOS and the
File Management System.
CTRDGE. B
CTRDGE. A
32768
40960
8000
AOOO
Appendicies
GTIA
53248-53505
0000
HPOSPO
53248
DOFF
0000
53249
0001
MOPF
HPOS1
53250
0002
53251
0003
53252
0004
M3PF
HPOSMO
collision
(W) horizontal position of
POPF
HPOSM1
player 2
(R) missile-playfield
collision
M2PF
HPOSP3
player 1
(R) missile-playfield
M1PF
HPOSP2
309
53253
0005
collision
(W) horizontal position of
missile 1
P1PF
HPOSM2
53254
0006
53255
0007
P2PF
HPOSM3
P3PF
MOPL
53256
0008
SIZEPO
M1PL
53257
0007
SIZEP1
M2PL
53258
OOOA
SIZEP2
M3PL
53259
0008
SIZEP3
POPL
53260
oooe
SIZEM
GRAFPO
53261
0000
53262
OOOE
53263
OOOF
GRAPFP3
53264
0010
TRIGO
(644)
GRAPFPM
TRIG1
eOLPMO
53265
0011
53266
0012
P1PL
GRAPFP1
P2PL
GRAPFP2
P3PL
TRIG2
(646)
Appendicies 311
COLPM1
53267
0013
TRIG3
(647)
COLPM2
53268
0014
COLPM3
53269
0015
COLPFO
53270
0016
COLPF1
53271
0017
COLPF2
53272
0018
COLPF3
53273
0019
COLBK
53274
001A
PRIOR
VOELAY
GRACTL
53275
53276
53277
001B
001C
0010
HITCLR
CONSOL
53278
53279
001E
001F
Locations 53504 - 53759 are unused . However they are not empty. If
you are interested you can PEEK these locations to see their contents.
POKEY: Locations 53760 - 54015 are the 110 chip that controls audio
(requency registers and audio control registers, frequency dividers,
polynoise counters, paddle controllers, random number generation,
keyboard scan, serial port 110 and IRQ interrupts .
AUOF1
POTO (624)
AUOC1
53760
0200
53761
0201
53762
0202
53763
0203
AUOF3
POT4 (628)
53764
0204
AUOC3
53765
0205
POT1 (625)
AUOF2
POT2 (626)
AUOC2
POT3 (627)
POT5 (629)
AUOF4
POT6 (630)
AUOC4
POT7 (631)
AUOCTL
ALLPOT
STIMER
KBCOOE (764)
SKREST
RANDOM
POTGO
------
SEROUT
53766
0206
53767
0207
53768
0208
53769
0209
53770
020A
53771
020B
53722
53773
020C
0200
Appendicies 313
SERIN
IRQEN
IRQST
SKCTL
SKSTAT
53774
020E
53775
020F
PORTA
54016
0300
PORTB
54017
0301
PACTL
PBCTL
54018
54019
0302
0303
OMACTL
C HACTL
54272
54273
54274,5
HSCRO L
54276
VSCROL
54277
54278
54279
0405
0406
0407
54280
54281
54282
0408
0409
040A
- - --- -
PMBASE
-- ----
CHBASE
WSYNC
co ntrol (755)
0402,3 Disp lay li st po inter
(560,561 )
0404 (W) Horizonta l scroll
enab le
OLi STL/H
I
0400
0401
VCOUNT
PENH
54283
040B
54284
040C
PEN V
54285
0400
NM IEN
54286
040E
NMIRES
54286
040F
NMIST
Appendicies 315
,- -- -- - - -- - - - - -- - - -- - - - - - - - -- Locations 55296 to 57343 are used for the ROM 's Floating Point
57344
57600
57856
58112
EOOO
E100
E200
E300
Special characters
Punctuation, numbers
Capital letters@
Lowercase letters
~----------~---L------------- I
Locations 58368 to 58477 ace vector tables . These are base addresses
't
d ISP
' Iay
W h'IC h are use d b y th e resl'd en t h an dl ers ( screen e d lor,
handler, keyboard handler, printer and cassette handler) and are
stored in Lo-Byte / Hi-Byte form,
SETVBV
SYSVBV
XITVBV
58460
58463
58466
E45C
E45F
E462
Locations 58534 to 59092 are the addresses for the Central Input / Output
routines
ILoc~tions 59093 to 59715 are the addresses for the interrupt handler
routines
'---59123
E6F3
SYSVBL
59310
E7AE
PNMI
59316
E7B4
SETVBL
59629
E8ED
PIRQ
Start of I RQ interrupt
service routine
Start of the VBLANK
routines
(JSR) interrupt service
routine
Subroutines to set the
VBLANK timers/ vectors
Locations 59716 - 60905 are the addresses for the serial Input / Output
routines.
Locations 61667 - 62435 are the addresses for the monitor handler
routines.
DE RE ATARI
Technical Users Notes
ANTIC Magazine
Master Memory Map, Santa Cruz Educational Software (1981)
Mapping The Atari, COMPUTE! Publications (1983)
Appendix E
CHARACTER CODES
ATASCI I
DECIMAL
I)
KEYSTROKE
CHARACTER
CNTRL
CNTRL A
CNTRL B
CNTRL C
..
CNTRL 0
04
CNTRL E
CNTRL F
CNTRL G
CNTRL H
CNTRL
10
CNTRL J
,
/
INTERNAL CODE
64
65
66
67
68
69
70
71
72
73
74
11
CNTRL
12
CNTRL L
13
CNTRL M
14
CNTRL N
79
15
CNTRL 0
16
CNTRL
79
F'
80
17
CNTRL
81
18
CNTRL R
19
CNTRL S
83
20
CNTRL T
84
I<
75
76
77
82
317
21
CNTRL U
22
CNTRL V
23
CNTRL W
24
CNTRL X
25
CNTRL Y
26
CNTRL Z
27
ESC ESC
28
ESC CNTRL -
29
ESC CNTRL -
30
ESC CNTRL +
31
ESC CNTRL
32
SPACE BAR
33
SHIFT
34
SHIFT 2
85
...
87
...
I
.~
l'
86
88
89
90
91
92
...
93
94
95
0
3~
SHIFT 3
II
36
SHIFT 4
37
SHIFT
Yo
38
SHIFT 6
&c
39
SHIFT 7
40
SHIFT 9
41
SHIFT 0
42
10
43
11
44
12
45
13
46
14
Appendicies 319
47
48
15
16
17
49
:50
18
:51
19
:52
20
:53
:5
:5
21
:54
22
:5:5
23
:56
24
:57
2:5
:58
26
SHIFT!
27
:59
60
<
<
61
62
>
28
29
>
30
63
SHIFT
31
64
SHIFT 8
(I
32
6:5
33
66
34
67
3:5
68
36
69
37
70
38
71
39
72
40
73
41
J
42
7!5
43
76
44
77
4!5
78
46
79
47
80
48
81
CI
CI
49
82
!50
83
~1
84
~2
8~
~3
86
~4
87
~~
88
~6
89
~7
90
~8
74
91
SHIFT
92
SHIFT
93
SHIFT
94
SHIFT
62
9~
SHIFT -
63
96
CNTRL
~9
60
61
96
97
97
98
98
Appendicies 321
99
99
100
00
101
101
102
102
103
103
104
104
10~
10~
106
106
107
L07
108
108
109
109
110
110
111
111
112
112
113
113
114
114
11~
11~
116
116
117
117
118
118
119
119
120
120
121
121
122
122
123
CNTRL
124
SHIFT
123
124
<
125
ESC CNTRL
126
ESC BACK S
127
ESC TAB
"'.
.,
~
125
126
127
[.-...J
Inverse Vi .dec
128
[A.JCNTRL.
129
[~JCNTRL
130
[A-JCNTRL B
131
[AI.]CNTRL C
132
192
193
194
[.h-JCNTRL D
a
a
196
133
[ A-JCNTRL E
CI
197
134
[A-JCNTRL F
198
13~
[ft,JCNTRL G
199
136
[ .....JCNTRL H
!J
200
137
[A.]CNTRL
It
201
138
[A-JCNTRL J
139
["'JCNTRL K
140
[""JCNTRL L
m
m
19:5
202
203
141
[..+JCNTRL M
142
[A-JCNTRL N
"e
143
[AlCNTRL 0
II
207
144
[A-JCNTRL P
Qg
208
14:5
["'JCNTRL tl
17
209
146
[A'-JCNTRL R
147
[NCNTRL S
148
[",JCNTRL T
149
[A\JCNTRL U
ii
D
0
204
20:5
206
21<)
211
212
213
Appendicies 323
150
[J
[AJCNTRL V
214
151
[4]CNTRL W
152
[.A]CNTRL X
153
[-4.]CNTRL Y
154
[ ....]CNTRL Z
II
&:I
155
[~RETURN
156
157
ESC SHIFT
1;58
)59
160
[A]SPACE BAR
161
[~
SHIFT 1
129
162
["-]
SHIFT 2
ii
13(1
163
[..+.J
SHIFT 3
131
164
CA-.]
SHIFT 4
132
165
C.AJ
SHIFT :5
133
166
CAJ
SHIFT 6
fl
134
167
CA]
SHIFT 7
r.
135
168
CA\.]
SHIFT 9
136
169
CA]
SHIFT 0
tJ
137
170
CA]
138
171
CA.]
172
CA]
173
[ft.]
174
[A]
175
CA.]
215
216
217
2'8
219
>
220
221
C
:l
222
223
128
...
139
140
;;
141
II
142
143
176
[AJ
(I
ill
144
177
[ A. J
(!
145
178
[ -1-.J
146
179
[ ".J 3
147
180
[ 1'3 4
148
181
[AJ 5
149
182
[A-J 6
150
183
[AJ
fj
184
[AI.J 8
[;J
185
[4J
153
186
[AJ SHIFT;
154
187
[A.J
155
188
~..-N
<
156
189
[;\.J
Iii
157
190
u,J
158
191
[ "-J SHIFT I
159
192
C~J
SHIFT 8
[g
160
193
[.,f.J
161
193
[ A. J
l!)
162
195
[ A. J C
[ A-. J
l!J
l!l
163
196
197
CAl E
165
198
["'J F
La
166
199
[~
Ul
167
200
[ -+-J H
t:J
201
4J
>
151
152
164
168
'169
Appendicies 325
202
(..j.
J J
!J
17(>
203
(AJ K
171
204
CA.J L
172
20~
(.lJ M
(i)
173
206
(A.J N
l!l
174
207
(4.J 0
[!l
175
208
(..f..J P
176
209
( ...... J
til
177
210
CA.J R
[3
178
211
CA.J S
179
212
(..,.J T
il
180
213
C-+.J U
214
CA.J V
L!J
L!J
182
215
CA'-J W
I!l
183
216
UJ X
184
217
C.... J Y
185
218
(-'" J Z
186
219
( ... J SHIFT
187
220
C+J SHIFT +
188
221
C... J SHIFT
lJ
189
222
(~J
SHIFT
223
C-"'J SHIFT
224
(~J
225
CAJ
226
( ... J b
227
(~'J
228
( ....1
181
190
I!!
191
CNTRL
224
225
m
[;
rn
226
227
Z'2a
229
[ A. J e
230
[ .... J f
231
229
1 30
[ "'J 9
231
232
[AJ h
232
233
[-1-J i
m
n
234
[ I).J
1I
234
23:5
[ f'J k
235
236
[~J
237
0
CJ
236
[",J m
238
[-1'J n
!i]
238
239
[.+J
239
240
[hJ p
rn
m
241
[.A.J q
Ci1
241
242
[ -l'J r
[j1
24~
243
[4J
f12
243
244
UJ.J t
24 ..
24:5
[-lJ u
[!]
24~
246
[~J
t!l
246
247
[AJ
...
247
248
[ II-J
248
249
[.A.J Y
249
2~O
[~J
2~O
251
[I)..J CNTRL
251
252
[A..J SHIFT
II
252
253
ESC CNTRL 2
1a
..::..; .,j
254
254
2!l"5"
255"
II
233
237
240
-.C'~
Appendix F
Flag
Instruction
ADC
AND
ASL
x
x
x
x
x
x
x
BIT
BRK
CLC
CLD
CLI
CLV
CMP
CPX
CPY
DEC
DEX
DEY
C
x
0
0
0
0
x
x
x
x
x
x
x
x
x
x
x
x
327
x
x
x
x
EOR
INC
INX
INY
LOA
LOX
LOY
LSR
ORA
PLA
PLP
ROL
ROR
RTI
SBC
SEC
SEO
SEI
TAX
TAY
TSX
TXA
TYA
x
x
x
x
x
x
x
0
x
x
x
x
x
x
x
x
x
x
x
x
From Stack
x
x
x
x
From Stack
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
Appendix G
Values for
Decim~l
6502
Instructions
I~
..
~ I
~
..,
u
III
L.
'tI
c:
<I:
11)1
11)5
ADC
1 109
117
1:;:5
121
197
113 1
~A--N-D-+---~1-4-1--+-3-7--~5-3--~--~~ -5-7--+-----~--+3-3--}-4-9~~~
ASL
8CC
10
14
22
-+,---I
i-----r- _.
!
-'j---i-!I --+--+-
-r;
I~-~t---'--- 136
i
144
.3 0
176
240
-1---,-----144-+I---+-j_1+--!-------!----l---+-!- i!f---"
!~~-:---I I :~ --+i----+--+I----;!---l1-1-6-+I!
I::, I I :
-iC-----'I'----l
I
~ ._~. ___ .
1-----.--,--
-l-.-_:__
avs
--;!__+-_+-_-+-_ _
+-8_0- +__-+-_-+___
I
: j
112
CLC
1 -I - j-'-,---+1---t---+----t-- 2- 4- 1 - - l -- + ----If------j
1
CLD
1
!
I
I 216 I
I
------~I-----+----+--------~
I --~----}---~----~--~--~---+---j
~----,----;-----r--_+----r---~--~-----+--~--_+-----i---___j
I~L I
CL V
+ ____
j __
329
184
E
.
u
u
<i
CMF
I-~
CPY
DEC
.,
>-
Cl
'"
'"a.
Cl
''""
'"a.
Cl
.0
<i
r
_ -__ 11-2-2-4- --LF
:?-88
-:[I
, . __ ._ 192
,----
.0
<i
<i
217
209
T - 1 ---+----1
2l)4
2c)2
136
DEY
73
EOR
INC
69
85
77
93
:23 0
246
238
254
65
89
81
,I
232
lNX
INY
JMP
\
\ 76
JSR
32
200
LOA
169
16:=> 1 181
LOX
162
166
160
164
f----.LOY
LSR
119:-
! 2 -1-4-+---l-2-0-6-~112-2-2-+-- --T
DEX
- -
1196
198
.,;
.0
"0
."!
Ci
>-
.,;
'"
a.
'
70
74
--
NOP
-- I---ORA
..- -
182 11 174
--
I 21
78
1 86
I
--
172
180
.,
189
173
I 13
190
I
94
I
-I
:--188
29
I 25
il l
17
1 0 4 f l1- - + - - + - - - 1
1--.--tI
I
ROL
4:?
ROR_
1')6I---H --=-~.
RTI
RTS
234
PHP
-;~I--I--+
I
-- -~-
177
t---I--T--~'
--r--~'-::~
I
PHA
PLP
-161
185
38
54
40
I
461. 62-
~t_--~I~~i~r--t_-_+-4_-~-~~
t--,-~,
__
LllO ~j...
I
I
I
iI
I
I,
___ _ _
-+_-+_-+_ __-1--1
64
96 -:1- - -.
I
Appendicies 331
5 8C
J~
2:9
~37
:!45
253
STA
133
STX
134
STY
132
TXA
TYA
120
SEI
TSX
291
248
SED
TAY
'::' _..J
56
SEC
TAX
~ .., ~
249
141
149
j15(1
148
157
129
153
142
140
170
168
186
138
152
1~:'
Appendix H
FREQUENCY VALUES
e .................. 51649
213
201
190
179
169
160
151
142
134
127
119
113
OCTAVE 1
0 24372 52 . 95
Ott 23003 , .219 89
E 21712 208 84
F 20493 13 80
F . . . . . . . . . . . . . . . . . . 19342 142 7~
G 182:57 81 71
G. . . . . . . . . . . . . . . . . . 17231 79 67
A 16264 136 63
A. . . . . . . . . . . . . . . . . . 15351 247 ~9
B 14489 153 56
333
OCTAVE 2
C 1367~ 107 53
ett 12907 107 50
O 12182 150 47
Ott 11498 234 44
E 10852 100 42
F 10243 .. 3 40
F . . . . . . . . . . . . . . . . . . . 9668 196 37
G 9125 165 35
8ft 8612 164 33
A 8128 192 31
Aft 7672 248 29
B 7241 73 28
OCTAVE 3
OCTAVE 4
e .................. 3413 . 85 13
eft 3222 150 12
O 3040 224 11
Oft 2869 . 53 , 11
E 2708 , 148 10
F 2555 251 9
F . . . . . . . . . . . . . . . . . . . 2412 108 9
G 2276 228 8
Gft 21 48 100 8
A 2027 235 7
Aft 1913 121 7
B 180:5 13 7
Appendicies 335
OCTAVE :5
c 1703 167 6
Cft 1607 71 6
O 1:517 237 5
Ott 1431 1:51 :5
E 13:50 70 5
F 1274 250 4
Fft 1202 178 4
G 1134 110 4
Gtt 1070 46 4
A 1010 242 3
A.. 962 ' .' 194 3
B 899 131 ~
OCTAVE 6
c ..... 848 80 3
Ctt 800 32
O 755 243
Oft . 712 200
E 672 160
F 634 122
F . . . . . . . . . . . . . . . . . . . . 598 86
G 564 52
Gtt 532 20
A :501 245
A. . . . . . . . . . . . . . . . . . . . 473 217
B . 446 190
3
2
2
2
2
2
2
2
1
1
1
OCTAVE 7
C 421 165
Cft 397 141
O 374 118
Ott 3:53 97
E . 332 76
F 313 57
F . . . . . . . . . . . . . . . . . . . . 295 39
G ' .' . 278 22
G. . . . . . . . . . . . . . . . . . . . 262 6
A 247 247
A. . . . . . . . . . . . . . . . . . . . 233 233
B 219 219
1
1
1
1
1
1
1
1
1
0
0
0
OCTAVE B
F 153 153 0
Ft! 144 .
a .... ............. 136.
aft ... 128
A 120
A . . . . . . . . . . . . . . . . . . . . 113
B 106
144 0
1 36 0
128 0
120 0
113 0
106 0
Index
BNE 50
BPL 50
Branching
BRK 55
BYC 55
BYS 50
Accumulator 37
ADC 52
Addressing Modes 55-61
Immed iate 57
Accumulator 58
Absolute 57
Zero Page 57
Indirect 57
Implied 58
Relative 58
A bsolu te Indexed 60
Zero Page Indexed 60
I ndirect Inde xe d 60
I ndexed I nd i rect 61
Amplitude 181
AND 53
ANTIC 40
Instructions 66-71
Multicolored Characters 112-115
Artifacting 106
Arithmetic Instructions 52, 53, 168
ATASCII 35
ASCII 35
ASL 53
c
C haract er Set Graphics
CLC 52, 145
CLD 52
107-112
CLI 51
CMP 49
Codes
ATASCII 35
Binary Coded Decimal
Collisions 129
Color 97-104
CPU 36-37,40
Cpy 49
CPX 49
D
Data-Moving 155
DEC 49
Decimal System 22
DEX 49
DEY 49
Diagonal Scrolling 257
Display List 66, 76
Custom DL 80
DL from scratch 88
Display Modes 72-76
DL Interrupts 69,70, 136
B
BBC 50
BSC 50
BEQ 50
Binary System 22-30
Binary Coded Decimal
BIT 55
BMI 50
49-50,161
36
337
36
JjK
Eight-bit Music
EOR 53, 145
215
F
F lags 39
Frequency
181, 188
G
Graphics 2 DL 78
Graphics 8 DL 83
GTiA 41. 101-104
H
Half-step 188
Harmonics 183
Hexadecimal System 31-35
Hi-Byte 27,34
Horizontal Blank 64
Horizontal Scroll in g 70,249
INC 49
International Pitch Standard 188
I nstruction Set 45-51
Load / Store 48
Register Transfer Operations 49
I ncrement / Decrement 49
Compare / Branch 49-50
Jump / Return 50-51
Interrupt 51
Stack Operations 51 -52
Arithmetic 52-53
Logical / Miscellaneous 53-55
INY 49
INX 49
JMP
JSR
JVB
Koala
71
51
71. 77, 78, 84
Pad 274
L
LDA 48,112
LDX 48
LDY 48
LMS 57, 59,67, 70
Lo-Byte 27,34
LSR 53
Luminance 97, 99, 102
M
Machine Language
Comments On 44
Instructions 48
Program Listing Conventions
Map Modes 8 1
Memory 41-43
Lowering RAMTOP 87,88
Screen 66
M icroseco nd 64
Mnemonic 45
Music 215,260
Missiles 172
N
NOP 55
Number Systems
Binary 22-30
Binary Coded Decimal
Decimal 22
Hexadecimal 31-35
36
149
Index 339
SEC 52 , 142
SED 52
SE I 5 1
S ixtee n-bit Music 224
So und 179
Theory 180
Ha rdware 189
Pro gra m Exa mples 197-2 17
S ta ck Pointer 38
STA 48
STU 48
STX 48
Sta IUs Register 38
S trings 152
Octave 187,188
ORA 53
p
Page Flipping 95-97
Parameter Passing 162
Parameter Passing 162
Period 181
PHA 51
PHP 51
PIA 4 1
Pixel 64, 75
PLA 51, 112, 114
P laye r Missi le Gra phics 115
Registers 121-125
Collisions 129
Priority 133
Memory 127
PLP 41
POKEY 41, 163
Priority 133
Program Counter 38
Program Listing Convention
R
R AMTOP 87 ,88
Recursive Rule 23
ROL 53
ROR 53
RTI 51
RTS 51
s
SAVMCS 80,81, 84
SBC 52
Screen Memory 66
Sc rolling 235
149
TAX 49
TAY 49
Timbre 183
Touch Tablet 274
Tremolo 187
TSX 49
TV 64-66
Two's Co mplement Arithmetic
TXA 49
TXS 49
TYA 49
U/V/W
USR 15 1
Vertical Blank 66
Vertical Blank Int e rrupts 230
Ve rti ca l Blank Music 260
Vertical Scro lling 235
Vibrato 185
X/V/Z
X-reg iste r
Y-register
38
38
169
dBASE III Plus: Thi ngs the Manual Didn 't Tell You
Working with MS-DOS v. 3-2
Working with Reflex
Microsoft Basic 3rd Edition
Alar i XE User's Handbook
Alari XL U ser's Handbook
$ 7.95
$15.95
$17.95
$19.95
$19.95
$19.95
$19 .95
$17.95
$19 .95
$19.95
$19.95
$17.95
$15.95
$17.95
S 9.95
$15.95
$17 .95
$ 9.95
$17 .95
$19.50
$19.95
$15.95
Supercalc Models
All About 1-2-3
1-2-3 Manager ial Worksheets
$15.95
$ 5.95
$ 7.95
$17.50
$19.95
Symphony: 1-2-3
$19.95
$ 7.95
$13.95
519.95
$ 7.95
Lisp
Pascal: Step-by -Step Prog rammi ng
Introduction to C
Introduction to Madu ra 2
Introduction to Ada
Turbo Pascal Prog rammer's Guide
Xen ix User's H andbook
Title
Price
Quantity
$ 5.95
$14.95
$12.95
$17.95
$11 .95
$ 5.95
$ 5.95
$ 5.95
$12.95
$ 9.95
$ 4.95
$ 3.95
$14.95
$14.95
$19.95
$ 7.95
$14.95
$ 7.95
$ 9.95
$17.95
$ 7.95
$ 7.95
$ 9.95
$ 7.95
$15.95
$15.95
$16.95
$ 9.95
$19.95
$15.95
$16.95
519.95
$19.95
$19.95
$17.95
$17.95
$17.95
Total
NC
Catalogue
Book Subtotal
GRAND TOTAL
Method of Payment:
Card Number
0 Check
Charge my:
0 VI SA
0 Master Card
0 Am erican Express
Exp. Date
Cardhold er Name
Ship To
Name
Address
City
State
Z ip
Send to: Web er Sys tems Inc. , 8437 Mayfield Road, Ches terland, OH 44026
TOil-free order number 800-851-6018
$19.95 US
$28.95 Canada
ISBN 0-938862-54-5