Note from the tired typist:

  WHEW!  This is a LOT of text.  And, yes, this whole darned 11,000-line thing
was completely hand-typed.  As for the content, I tried to get everything
exactly word-for-word.  However, many typos are bound to be lurking in these
pages.  Thus I give permission for anybody to edit and repost this file
without having to contact me.  I also made some minor changes, which include
throwing out page numbers and delimitation, filling up to 79 columns wide,
listing out some ordinary-formatted text into somewhat formatted tables, and
correcting some typos and errors in the original text.

  The book bears Sheldon Leemon's name and was published by Compute!
Publications, (c) 1984.  Again (like the Project 64 header should read), this
copy is meant for reference only, and to preserve its contents from being
eternally lost.  No monetary or other damages to Compute! Publications or
Sheldon Leemon are meant by the creation and transfer of this electronic book,
and the intellectual ownership of the contents of this text by the above
parties is hereby acknowledged.  No profit is to be made from the transfer of
this electronic copy!  I claim no responsibility for anything that anybody
does with the text herein, as do the original author and publisher.

  Without further ado, here's one of the best C64 references around!  Enjoy!

White Flame (aka David Holz)
http://www.geocities.com/ResearchTriangle/Lab/1767



MAPPING THE Commodore 64


::::::::::::
::Contents::
::::::::::::

Foreword

Acknowledgments

Introduction

Chapter 1.  Page 0

Chapter 2.  Page 1

Chapter 3.  Pages 2 and 3
  BASIC and Kernal Working Storage

Chapter 4.  1K to 40K
  Screen, Memory, Sprite Pointers, and
  BASIC Program Text

Chapter 5.  8K BASIC ROM and 4K Free RAM

Chapter 6.  VIC-II, SID, I/O Devices, Color RAM,
  and Character ROM

Chapter 7. 8K Operating System Kernal ROM

Appendix A.  A Beginner's Guide to
  Typing In Programs

Appendix B.  How to Type In Programs

Appendix C.  Screen Location Table

Appendix D.  Screen Color Memory Table

Appendix E.  Screen Color Codes

Appendix F.  ASCII Codes
  [*** OMITTED ***]
  [widely available elsewhere; not suitable for textual formatting]

Appendix G.  Screen Codes
  [*** OMITTED ***]
  [widely available elsewhere; not suitable for textual formatting]

Appendix H.  Commodore 64 Keycodes

Index (By Memory Location)


::::::::::::
::Foreword::
::::::::::::

This is a memory map of the Commodore 64 personal computer.  But it's much
more than that.  It's a reference book which every programmer who uses the 64
will find invaluable.  What is a memory map?  It's a list of the memory
locations in a computer.  But Mapping the Commodore 64 is a memory amp that
goes much further.  It explains the purpose of each location and shows you
how to change the contents of many of them.  You can make the computer do what
you want it to.  If you're a BASIC programmer, you'll find easy-to-understand
explanations of how to use the advanced features of the Commodore 64, and how
to include these features in your own programs.  If you're already using
machine language to write your own programs, you'll use this guide over and
over again, referring to specific memory locations and routines.  You'll have
the most complete guide to the Commodore 64's memory available.
  As with all COMPUTE! books, the explanations are clear and easy to
understand.  Beginning and advanced programmers alike will find Mapping the
Commodore 64 a valuable resource.


::::::::::::::::::::
::Acknowledgements::
::::::::::::::::::::

I would like to thank Russ Davies, author of Mapping the VIC, for his
generosity in sharing the results of his research.  Without his help, and that
of Dan Heeb, author of the The Commodore 64 and VIC Tool Kit, this book would
have been much less complete.
  Of all the published sources of information about the 64, I have found
the Commodore 64 Programmer's Reference Guide to be the most valuable for
technical information.  That Commodore has come out with such a thorough
reference work so quickly after the introduction of the machine is much to
their credit.  Because of the similarities between the 64 and previous
Commodore computers, I have also relied heavily on ooks that deal with the
PET/CBM.  Of particular interest are Programming the PET/CBM by Raeto West,
which should be subtitled "Everything You Ever Wanted to Know about Commodore
Computers," and the PET/CBM Personal Computer Guide, Third Edition, Osborne/
McGraw-Hill.  These important reference works contain more information of real
benefit to the 64 owner than most books which deal specifically with the 64.
  Finally, I would like to thank my wife Lenore.  Although her contribution
to this book was nontechnical in nature, it was as important as any other.


::::::::::::::::
::Introduction::
::::::::::::::::

To many computer users, the concept of a memory map may be an unfamiliar one.
Simply stated, it is a guide to your computer's internal hardware and
software.  A memory map can help you use the PEEK and POKE instructions to
extend your BASIC programming powers.  If you plan to do machine language
programming, it is necessary that you be able to find your way around the
system.
  Many computer owners think of a program as something they buy at a store
and feed into the computer so that it will let them play games, or do word
processing, or keep financial records.  But this type of applications software
is by no means the only kind.
  It is important to remember that a computer cannot do anything without
some kind of program.  When the computer displays the READY prompt, or blinks
the cursor, or displays the letters that you type, it can only do so by
executing a program.  In the examples shown above, it is the master control
program, the Operating System (OS), which is being executed.
  When you give the computer a command such as LOAD, the BASIC interpreter
program translates the English-like request to the language of numbers which
the computer understands.  The Operating System and BASIC interpreter programs
are contained in permanent Read Only Memory (ROM), and are available as soon
as you turn the power on.  Without them, your computer would be a rather
expensive paperweight.
  This permanent software co-exists inside your computer with the
applications program that you load.  Since the system software performs many
of the same functions as the applications program (such as reading information
from the keyboard and displaying it on the screen), it is often possible for
the applications program to make use of certain parts of the Operating System.
This not only makes the task of the programmer easier, but in come cases it
allows him or her to do things that otherwise would not be possible.
  The Commodore 64 also has hardware support chips which enable the
graphics display, sound synthesis, and communications with external devices.
Since these chips are addressed like memory, they occupy space in our map.
Control over these chips, and the graphics, sound, and I/O functions they make
possible, can only be accomplished by manipulation of the memory addresses
which correspond to these devices.  Therefore, a guide to these addresses is
necessary in order to take advantage of the graphics, music, and communications
power that they offer.
  The purpose of this book is to describe the memory locations used by the
system, and to show, wherever possible, how to utilize them in your own
programs.  The book should clear up some of the mystery surrounding the way
your computer works.

How to Use This Book

The Commodore 64 and communicate with 64K or 65536 (64*1024) bytes of memory.
Each of these bytes of memory can store a number from 0 to 255.  The computer
can read (and sometimes write) information from any of these 65536 locations
by using its address, a number from 0 to 65535.

Bits and Bytes

Each byte is make up of eight binary digits called bits.  These bits are the
computer's smallest unit of information.  They can contain only the number one
or the number zero, but when combined, they can be used to form any number
needed.  To see how that is possible, let's look at a single bit.
  A single bit can only be a one or a zero.  But if two bits are combined
the number increases.

00,01,10,11

That makes four possible combinations.  And if a third bit is added:

000,001,010,011,100,101,110,111

When eight bits are put together, the number of combinations increases to 256.
These eight bits are called a byte and can be used to represent the numbers
from 0 to 255.
  This system of numbering is known as binary (or base two).  It works
much like the decimal (base ten) system.  In the base ten numbering system,
the rightmost digit is known as the one's place, and holds a number from 0 to
9.  The next place to the left is known as then ten's place, and also holds a
number from 0 to 9, which represents the number of times the one's place has
been used in counting (the number of tens).
  In the binary system, there is a one's place, then a two's place, a
four's place, etc.  The bits are counted from right to left, starting with Bit
0.  Here are the values of each bit:

Bit 0 = 1
Bit 1 = 2
Bit 2 = 4
Bit 3 = 8
Bit 4 = 16
Bit 5 = 32
Bit 6 = 64
Bit 7 = 128

If all the bits are added together (128+64+32+16+4+2+1), they total 255, which
is the maximum value of one byte.  What if you need to count higher than 255?
Use two bytes.
  By using a second bytere to count the number of 255's, 65536 combinations
are possible (256*256).  This is the same number as the bytes of memory in the
Commodore 64.  Therefore, any byte can be addressed by a number using a
maximum of two bytes.
  When discussing large, even units of memory, the second byte, the number
of 256's, is often used alone.  These units are known as pages.  Page 0 starts
at location zero (0*256), Page 1 starts at location 256 (1*256), etc.
  You may see thn terms low-byte, high-byte order or LSB (Least Significant
Byte), MSB (Most Significant Byte) order, mentioned later in this book.  That
refers to the way in which the Commodore 64 usually deals with a two-byte
address.  The byte of the address that represents the number of 256's (MSB) is
usually stored higher in memory than the part that stores the leftover value
from 0 to 255 (LSB).  Therefore, to find the address, you must add the LSB to
256*MSB.

Hexadecimal

One other numbering system that is used in speaking about computers is the
hexadecimal (base 16) system.  Each hexadecimal digit can count a number from
0 to 15.  Since the highest numeric digit is 9, the alphabet must be used:
A=10, B=11, and so on up to F=15.  With just two digits, 256 combinations are
possible (16*16).  That means that each byte can be represented by just two
hexadecimal digits, each of which stands for four bits of memory.  These four-
bit units are smaller than a byte, so they are known as nybbles.
  Since programmers often find that hexadecimal numbers are easier to use
than binary or decimal numbers, many numbers in this book are given in both
decimal and hexadecimal format.  A dollar sign ($) has been placed in front
of each hexadecimal number.

AND, OR, and EOR

Certain functions on the 64 (particularly those using the sound and graphics
chips) are controlled by a single bit.  You will often see references to
setting Bit 6 to a value of one, or setting Bit 3 to a value of zero.  This
can be done by adding or subtracting the bit value for that particular bit
from the value of the whole byte.
  Adding or subtracting the bit value will work only if you know the status
of that bit already.  If Bit 4 is off, and you add 16 (the bit value of Bit 4)
to the byte, it will turn Bit 4 on.  But if it were on already, adding 16
would turn Bit 4 off, and another bit on.
  This is where logical (sometimes called Boolean) functions come in handy.
Two functions, OR and AND, are available in BASIC, and a third, EOR, can be
used in machine language programming for bit manipulation.
  AND is usually used to zero out (or mask) unwanted bits.  When you AND a
number with another, a 1 will appear in the resulting number only of identical
bits in the ANDed numbers had been set to 1.  For example, if you wanted to
turn of Bit 4 in the number 154, you could AND it with 239 (which is the
maximum bit combination minus the bit value to be masked; 255-16):

    10011010 = 154
AND 11101111 = 239
    --------
  = 10001010 = 138

By using the AND function, nothing would be harmed if we tried to turn off a
bit that wasn't on.  You can always turn a bit off by using the formula
BYTEVALUE AND (255-BITVALUE).  Remember, there must be a 1 in the same bit of
both numbers in order for the same bit in the result to have a 1.
  The opposite function, turning a bit on, is performed by the OR
statement.  The OR function puts a 1 in the bit of the resulting number if
there was a 1 in the same bit in either of the two numbers.  For example, to
turn Bit 4 back on in the number 138, we would use the statement 138 OR 16
(the bit value for the bit we want to turn on):

    10001010 = 138
OR  00010000 =  16
    --------
  = 10011010 = 154

Again, no harm would be done if the bit was already on.  A bit can always be
turned on with the formula BYTEVALUE OR BITVALUE.
  The third operation, EOR, can be done only in machine language.  It is
used to reverse the value of a bit.  If the bit of the second number holds a
1, it will reverse the value of the corresponding bit in the first number.
Therefore, to switch all of the bits, you can EOR a number by 255:

    10011010 = 154
EOR 11111111 = 255
    --------
  = 01100101 = 101

Notice that this produces the complement of the original number (256 minus the
number).  Anytime you with to flip a bit from 0 to 1, or 1 to 0, you can EOR
it with the value of that bit.

The Format of Entries

The entries in this book are organized at the most general level by large
blocks 9the 256 page 0 locations, for example, or the 8192 locations in the
BASIC ROM).  At the beginning of these blocks, you will often find an
explanation that will give you an idea of how the lcoations in that section
are related.  Usually, this overview will make it easier to understand the
more detailed explanations of the individual locations in that block.
  Within these larger blocks, you will sometimes see a few locations
grouped under the heading Location Range.  This grouping is done where the
locations are so interrelated that it would be meaningless to try to explain
one without explaining them all.
  Finally comes the entries for individual locations.  These give the
address, first in decimal, then in hexadecimal, and sometimes a label.  This
label is merely a mnemonic device, used in machine language programming, for
easier reference to a particular memory location.  Although Commodore has not
released the source code for their Operating System or BASIC, they have
published some of these labels in the Commodore 64 Programmer's Reference
Guide.
  Other labels used here are taken from Jim Butterfield's PET memory maps,
which have enjoyed a wide circulation among Commodore users.  Their use here
should help 64 owners adapt information about the PET to their own machines.
  The mnemonic label for an entry is followed by a one-line description of
the location.  Often, a more detailed explanation will appear under that,
ranging from a couple of sentences to several pages.  Occasionally, program
samples will accompany these explanations.
  Sometimes the single-line descriptions will identify a location as a
flag, a vector, or a pointer.  A flag is just a number that the program uses
to store the outcome of a previous operation.  A pointer of vector is usually
a two-byte location that holds a significant address.  Generally, the term
pointer is used when the address points to the start of some data, and vector
is used when the address points to the start of a machine language program.
However, sometimes these terms will be used interchangeably, with the meaning
clear from the context.


:::::::::::::
::Chapter 1::
::         ::
:: Page 0  ::
:::::::::::::

Memory locations 0-255 ($0-$FF) have a special significance in 6502 machine
language programming (the 6510 microprocessor in the Commodore 64 shares the
same instruction set as the 6502).  Since these addresses cn be expressed
using just one byte, instructions which access data stored in these locations
are shorter and execute more quickly than do instructions which operate on
addresses in higher memory, which requires two bytes.
  Because of this relatively fast execution time, most 6502 software makes
heavy use of zero-page locations.  The 64 is no exception, and uses this area
for many important system variables and pointers.
  In addition, locations 0 and 1 have special Input/Output functions on
the 6510.  In the case of the 64, this on-chip I/O port is used to select the
possible combinations of ROM, as we will se below, and to control cassette
I/O.

Location Range: 0-143 ($0-$8F)
BASIC Working Storage

This portion of zero page is used by BASIC only.  Therefore, a program written
entirely in machine language that does not interact with BASIC can freely use
this area.

0             $0             D6510
6510 On-Chip I/O DATA Direction Register

Bit 0: Direction of Bit 0 I/O on port at next address.  Default = 1 (output)
Bit 1: Direction of Bit 1 I/O on port at next address.  Default = 1 (output)
Bit 2: Direction of Bit 2 I/O on port at next address.  Default = 1 (output)
Bit 3: Direction of Bit 3 I/O on port at next address.  Default = 1 (output)
Bit 4: Direction of Bit 4 I/O on port at next address.  Default = 0 (input)
Bit 5: Direction of Bit 5 I/O on port at next address.  Default = 1 (output)
Bit 6: Direction of Bit 6 I/O on port at next address.  Not used.
Bit 7: Direction of Bit 7 I/O on port at next address.  Not used.

This location is the first of a number of hardware registers that we will
discuss.  Although they can be written to and/or read like RAM, they are
connected to hardware devices, and their contents affect the operation of the
devices.
  Each bit of this Data Direction Register determines whether the contents of
the corresponding bit on the Internal I/O Port (see location 1) can be written
to by peripheral devices.  If the bit is set to 0, it indicates the direction
of data flow as Input, which means that the corresponding bit of the I/O port
will be affected by peripheral defices.  If the bit is set to 1, it indicates
Output.  On the 64, only Bits 0-5 are significant.  On power-up, this register
is set to 239 ($EF), which indicates that all bits, except for Bit 4 (which
senses the cassette switch), are set up for Output.

1             $1             R6510

Bit 0: LORAM signal.  Selects ROM or RAM at 40960 ($A000).  1=BASIC, 0=RAM
Bit 1: HIRAM signal.  Selects ROM or RAM at 57344 ($E000).  1=Kernal, 0=RAM
Bit 2: CHAREN signal.  Selects character ROM or I/O devices.  1=I/O, 0=ROM
Bit 3: Cassette Data Output line.
Bit 4: Cassette Switch Sense.  Reads 0 if a button is pressed, 1 if not.
Bit 5: Cassette Motor Switch Control.  A 1 turns the motor on, 0 turns it off.
Bits 6-7: Not connected--no function presently defined.

The chief function of this register is to determine which blocks of RAM and
ROM the 6510 microprocessor will address.  The Commodore 64 comes with 64K
RAM, even though it normally does not use all of that RAM at once.  In
addition, it has an 8K BASIC Interpreter ROM, an 8K Operating System Kernal
ROM, a 4K Character Generator ROM, a Sound Interface Device (SID), a 6566
Video Interface Controller (VIC-II), and two 6526 Complex Interface adapter
chips.
  To address all of these at once would require 88K, 24K past the addressing
limit of the 6510 microprocessor.  In order to allocate address space, the I/O
Port is used to affect the addressing lines, and thus determine which segments
of RAM and ROM will be addressed at any one time.
  Bit 0.  This bit controls the LORAM signal.  A 0 in this bit position
switches the BASIC ROM out, and replaces it with RAM at addresses 40960-49151
($A000-$BFFF).  The default value of this bit is 1.
  Bit 1.  Bit 1 controls the HIRAM signal.  A 0 in this bit position switches
the Kernal ROM out, and replaces it with RAM at 57344-65535 ($E000-$FFFF).  As
the BASIC interpreter uses the Kernal, it is also switched out and replaced by
RAM.  The default value of this bit is 1.
  The system allows a wide range of combinations of RAM and ROM to be
utilized.  Of course, the BASIC programmer will have little need, in the
ordinary course of events, to switch out the BASIC ROM and the Kernal.  To do
so would just hang the system up.  But one way to make use of this feature is
to move the contents of ROM to the corresponding RAM addresses.  That way, you
can easily modify and customize the BASIC interpreter and OS Kernal routines,
which are ordinarily fixed in ROM.  For examples, to move BASIC into RAM, just
type:

FOR I=40960 TO 49151:POKE I,PEEK(I):NEXT

Though it appears that such a program would not do anything, it in fact copies
bytes from ROM to RAM.  This is because any data which is written to a ROM
location is stored in the RAM which resides at the same address.  So while you
are PEEKing ROM, you are POKEing RAM.  To switch to your RAM copy of BASIC,
type in:

POKE 1,PEEK(1) AND 254.

Now you are ready to make modifications.  Examples of simple modifications
include changing the text which the interpreter prints, such as the READY
prompt, the power-up message, or the keyword table.
  An example of the latter would be POKE 41122,69.  This changes the FOR
keyword to FER, so that BASIC would respond normally to a FER-NEXT loop, but
fail to recognize FOR as syntactically correct.
  On the more practical side, you could change the prompt that INPUT issues
to a colon, rather than a question mark:

POKE 43846,58

You are not limited to just cosmetic changes of text.  Jim Butterfield has
given an example in COMPUTE! magazine of changing the interpreter so that it
assigns a null string the ASCII value 0.  In the ROM version, the command
PRINT ASC("") will return ?ILLEGAL QUANTITY ERROR.  This is inconvenient when
INPUTting a string, because if the user presses RETURN and you try to check
the ASCII value of the string that has been entered, you will get this error.
By entering POKE 46991,5, this is changed so that PRINT ASC("") now responds
with a zero.
  For the more serious machine language programmer, it is quite feasible to
add new commands or modify existing ones by diverting the vectors which are
discussed in the section covering the BASIC interpreter ROM.  For a good
example of this technique, see the article "Hi-Res Graphics Made Simple" by
Paul Schatz in COMPUTE!'s First Book of Commodore 64 Sound and Graphics.  The
program example there inserts new graphics commands into a RAM version of
BASIC.  When you want to switch back to the ROM BASIC, enter POKE 1,PEEK(1)
OR 1.
  For machine language applications, it would be possible to replace the ROM
programs with an entirely different operating system, or an application that
has its own screen editing and I/O functions included.  Such an application
would first have to be loaded from disk into RAM.  A language other than BASIC
could be loaded, and could then just switch out the BASIC ROM, while still
using the OS Kernal.
  Or a spreadsheet application that contained its own I/O routines could
switch out all ROMs and have the use of all of RAM that is not actually needed
for the program itself, for data.  It should be remembered, however, that
before switching the Kernal out, it is necessary to disable interrupts, as
the vectors for these interrupts are contained in the Kernal.
  Bit 2.  This bit controls the CHAREN signal.  A 0 in this position switches
the character generator ROM in, so that it can be read by the 6510 at
addresses 53248-57343 ($D000-$DFFF).  Normally, this bit is set to 1, so that
while the VIC-II chip has access to the character generator ROM for purposes
of creating the screen display, the user cannot PEEK into it.  Since this
ROM is switched into the system in the same location as the I/O devices (SID
chip, VIC-II chip, and 6526 CIA's), o I/O can occur when this ROM is switched
in.
  The ability to switch in the character generator ROM is very useful to the
programmer who wishes to expirement with user-defined characters.  Modified
character graphics is one of the  more powerful graphics tools available, but
often the user will not want to redefine a whole character set at one time.
By reading the character ROM and duplicating its contents in RAM, the user can
replace only a few characters in the set.  The method for reading this ROM
into RAM from BASIC is as follows:

10 POKE 56333,127:POKE1,PEEK(1) AND 251:FOR I=0 TO 2048
20 POKE BASE+I,PEEK(53248+I):NEXT:POKE 1,PEEK(1) OR 4:POKE 56333,129

The first POKE is necessary to turn off the system timer interrupt.  Since the
I/O devices are addressed in the same space as the character ROM, switching
that ROM in switches all I/O out, making it necessary to turn off any
interrupts which use these devices.
  The second POKE is the one which switches in the character ROM.  The program
loop then reads this ROM memory into RAM, starting with the address BASE.
Note that this address should start on an even 2K boundary (an address evenly
divisible by 2048) within the block of memory presently being addresses by the
VIC-II chip (for more information on where to put user-defined character sets,
and how to use them, see the section on the VIC-II chip, under location 53272
($D018), the section on the character ROM at 49152 ($C000), and the section on
banking VIC-II memory at 56576 ($DD00)).  After reading the contents of ROM
into RAM, the next POKEs switch out the character ROM and restore the
interrupt.
  It should be noted that while Bits 0-2 of this register allow software
control of some signals that determine the memory configuration that is used
by the Commodore 64 at any given time, they are not the only determining
factor.  Signals can also be generated by means of plug-in expansion
cartridges which are connected to the expansion port, and these can change the
memory map.
  Two lines located on the exapansion port are called GAME and EXROM.  When
used in conjunction with the software-controlled lines noted above, these two
hardware lines can enable cartridge ROM to replace various segments of ROM
and/or RAM.
  Possible configurations include 8K of cartridge ROM to be switched in at
$8000-$9FFF, for a BASIC enhancement program; an 8K cartridge ROM at $A000-
$BFFF, replacing BASIC, or at $E000-$FFFF, replacing the Kernal, or a 16k
cartridge at $8000-$C000.
  When cartridge ROM is selected to replace the Kernal, a Max emulator mode
is entered, which mimics the specification of the ill-fated Max Machine, a
game machine which Commodore never produced for sale int he U.S.  In this
mode, only the first 6K of RAM are used, there is no access to the character
ROM, and graphics data such as charactger dot-data is mapped down from 57344
($E000) to 8192 ($2000).  Further hardware information may be obtained from
the Commodore 64 Porgrammer's Reference Guide.
  Bits 3-5 of this register have functions connected with the Datasette
recorder.  These are as follows:
  Bit 3.  This is the Cassette Data Output line.  This line is connected to
the Cassette Data Write line on the cassette port, and is used to send the
data which is written to tape.
  Bit 4.  This bit is the Cassette Switch Sense line.  This bit enables a
program to tell whether or not one of the buttons that moves the recorder is
pressed down.  If the switch on the recorder is down, this bit will have a
value of 1.  Remember that Bit 4 of the data direction register at location
0 must contain a 0 for this bit to properly reflect the status of the switch.
  Bit 5.  Bit 5 is the Cassette Motor Control.  Setting this bit to zero
allows the motor to turn when you press one of the buttons on the recorder,
while setting it to one disables it from turning.
  Most of the time, the setting of this bit will be controlled by the
interrupt routine that is used to read the keyboard every sixtieth of a
second.  If none of the buttons on the recorder is pressed, that interrupt
routine shuts the motor off and sets the interlock at location 192 ($C0) to
zero.  When a button is pressed, if the interlock location is zero, Bit 5 of
this register is set to zero to turn the motor on.
  When the interlock location contains a zero, the keyscan routine will not
let you control the setting of this bit of the register (and the interlock is
always set to zero when no buttons are pressed).  In order for you to gain
control of the motor, you must POKE a nonzero value into 192 after a button on
the recorder has been pressed.  You can then shut off the motor and turn it
back on as you please, by manipulating this bit, so long as a button stays
pressed.

2             $2
Unused

3-4           $3-$4          ADRAY1
Vector: Routine to Convert a Number from Floating Point to Signed Integer

This vector points to the address of the BASIC routine which converts a
floating point number to an integer.  In the current Kernal version, the
address that it points to is 45482 ($B1AA).  Disassembly of the ROMs indicates
that BASIC does not use this vector.  However, it may be of real assistance to
the programmer who wishes to use data that is stored in floating point format.
The parameter that is passed by the USR command is available only in that
format, for example.
  Since it is extremely difficult to decipher and use a floating point number,
the simplest way to deal with such data is to use the conversion routines that
are built into BASIC to change it into a two-byte signed integer.  This could
be accomplished by jumping directly into the BASIC ROM, if you know the
location of the routine.  Therefore, if the address changes in future versions
of the 64 or future Commodore computers, you won't have to modify your
program to make it work with them.
  See the entry for the USR vector at 785 ($311) for an explanation of how to
use this routine in connection with the USR command.

5-6           $5-$6          ADRAY2
Vector: Routine to Convert a Number from Integer to Floating Point

This vector points to the address of the BASIC routine which converts an
integer to a floating point number.  This routine is currently located at
45969 ($B391).  BASIC does not appear to reference this location.  It is
available for use by the programmer who needs to make such a conversion for a
machine language program that interacts with BASIC.  For an explanation of how
to use this routine in connection with the USR command, see the entry for the
USR vector at 785 ($311).

7             $7             CHARAC
Search Character for Scanning BASIC Text Input

This location and the next are used heavily by the BASIC routines that scan
the text that comes into the buffer at 512 ($200), in order to detect
significant characters such as quotes, comma, the colon which separates BASIC
statements, and end-of-line.  The ASCII values of such special characters are
usually stored here.
  This location is also used as a work area by other BASIC routines that do
not involve scanning text.

8             $8             ENDCHR
Search Character for Statement Termination or Quote

Like location 7, this location is used as a work byte during the tokenization
of a BASIC statement.  Most of the time, its value is 0 or 34.

9             $9             TRMPOS
Column position of the Cursor before the Last TAB or SPC

TRMPOS is used by TAB and SPC.  The cursor column position prior to the TAB or
SPC is moved here from 211 ($D3), and is used to calculate where the cursor
ends up after one of these functions is invoked.  Note that the value
contained here shows the position of the cursor on a logical line.  Since one
logical line can be up to two physical lines long, the value stored here can
range from 0 to 79.

10            $A             VERCK
Flag: LOAD or VERIFY

BASIC uses one Kernal routine to perform either the LOAD or VERIFY function,
depending on whether the Accumulator (.A) is set to 0 or 1 upon entry to the
routine.  BASIC sets the value of VERCK to 0 for a LOAD, or 1 for a VERIFY.
Its contents are passed to the Kernal LOAD routine, which in turn stores it
in location 147 ($93).

11            $B             COUNT
Index into the Text Input Buffer/Number of Array Subscripts

The routines that convert the text in the input buffer at 512 ($200) into
lines of executable program tokes, and the routines that link these program
lines together, use this location as an index into the input buffer area.
When the job of converting text to tokens is finished, the value in this
location is equal to the length of the tokenized line.
  The routines which build an array or locate an element in an array use this
location to calculate the number of DIMensions called for and the amount of
storage required for a newly created array, or the number of subscripts
specified when referencing an array element.

12            $C             DIMFLG
Flags for the Routines That Locate or Build an Array

This location is used as a flag by the routines that build an array or
reference an existing array.  It is used to determine whether a variable is in
an array, whether the array has already been DIMensioned, and whether a new
array should assume the default dimensions.

13            $D             VALTYP
Flag: Type of Data (String or Numeric)

This flag is used internally to indicate whether data being operated upon is
string or numeric.  A value of 255 ($FF) in this location indicates string
data, while a 0 indicates numeric data.  This determination is made every time
a variable is located or created.

14            $E             INTFLG
Flat: Type of Numeric Data (Integer or Floating Point)

If data which BASIC is using is determined to be numeric, it is further
classified here as either a floating point number or as an integer.  A 128
($80) in this location identifies the number as an integer, and a 0 indicates
a floating point number.

15            $F             GARBFL
Flag for LIST, Garbage Collection, and Program Tokenization

The LIST routine uses this byte as a flag to let it know when it has come to
a character string in quotes.  It will then print the string, rather than
search it for BASIC keyword tokens.
  The garbage collection routine uses this location as a flag to indicate that
garbage collection has already been tried before adding a new string.  If
there is still not enough memory, an OUT OF MEMORY message will result.
  This location is also used as a work byte for the process of converting a
line of text in the BASIC input buffer (512, $200) into a linked program line
of BASIC keyword tokens.

16            $10            SUBFLG
Flag: Subscript Reference to an Array or User-Defined Function Call (FN)

This flag is used by the PTRGET routine which finds or creates a variable, at
the time it checks whether the name of a variable is valid.  If an opening
parenthesis is found, this flag is set to indicate that the variable in
question is either an array variable or a user-defined function.
  You should note that it is perfectly legal for a user-defined function (FN)
to have the same name as a floating point variable.  Moreover, it is also
legal to redefine a function.  Using a FN name in an already defined function
results in the new definition of the function.

17            $11            INPFLG
Flag: Is Data Input to GET, READ or INPUT?

Since the keywords GET, INPUT, and READ perform similar functions, BASIC
executes some of the same instructions for all three.  There are also many
areas of difference, however, and this flag indicates which of the three
keywords is currently being executed, so that BASIC will know whether or not
to execute the instructions which relate to the areas in which the commands
differ (152 ($98)=READ, 64 ($40)=GET, 0=INPUT).
  As a result, INPUT will show the ? prompt, will echo characters back to the
screen, and will wait for a whole line of text ended by a carriage return.
GET gives no prompt and accepts one character without waiting.  The colon
character and the comma are valid data for GET, but are treated as delimiters
between data by INPUT and READ.
  As each command has its own error messages, this flag is used to determine
the appropriate message to issue in case of an error.

18            $12            TANSGN
Flag: Sign of the Result of the TAN or SIN Function

This location is used to determine whether the sign of the value returned by
the functions SIN or TAN is positive or negative.
  Additionally, the string and numeric comparison routines use this location
to indicate the outcome of the comparison.  For a comparison of variable A to
variable B, the value here will be 1 if A is greater than B, 2 if A equals B,
and 4 if a is less than B.  If more than one comparison operator was used to
compare the two variables (e.g., >= or <=), the value here will be a
combination of the above values.

19            $13            CHANNL
Current I/O Channel (CMD Logical File) Number

Whenever BASIC inputs or outputs data, it looks here to determine which I/O
device is currently active for the purpose of prompting or output control.  It
uses location 184 ($B8) for purposes of deciding what device actually to put
input from or output to.
  When the default input device (number 0, the keyboard) or output device
(number 3, the display screen) is used, the value here will be a zero, and the
format of prompting and output will be the standard screen output format.
  When another device is used, the logical file number (CMD channel number)
will be placed here.  This lets the system now that it may have to make some
subtle changes in the way it performs the I/O operation.  For example, if TAB
is used with the PRINT command, cursor right characters are used if the device
PRINTed to is the screen.  Otherwise, spaces are output when the number here
is other than zero (the assumption being that you can't tab a printer like you
can the screen).
  Likewise, the ? prompt for INPUT is suppressed if the file number here is
nonzero, as is the EXTRA IGNORED message, and input of a carriage return by
itself is ignored, rather than being treated as a null string ("").
Therefore, by OPENing the screen as a device, and issuing the CMD statement,
you can force the suppression of the ? prompt, and the other effects above.
  CMD places the new output file number here, and calls the Kernal to open the
device for output, leaving it LISTENing for output (such as the READY prompt,
which is diverted to the new device).
  Many routines reset this location and UNLISTEN the device, defeating the CMD
and once again sending the output to the screen.  If an error message has to
be displayed, for example, this location will be reset and the message will be
displayed on the screen.  GET, GET#, INPUT, INPUT#, and PRINT# all will reset
this location after the I/O is completed, effectively redirecting output back
to the screen.  PRINT and LIST are the only I/O operations that will not undo
the CMD.
  This location can also be used to fool BASIC into thinking that data it is
reading from the tape is actually being entered into the keyboard in immediate
mode.
  For a look at a technique that uses a different approach to accomplish the
same thing for disk or tape users, see location 512 ($200), the keyboard
buffer.

20-21         $14-$15        LINNUM
Integer Line Number Value

The target line number for GOTO, LIST, ON, and GOSUB is stored here in low-
byte, high-byte integer format, as is the number of a BASIC line that is to be
added or replaced.
  LIST saves the highest line number to list (or 65535 ($FFFF) if program is
to be listed to the end) at this location.
  GOTO tests the target line number to see if it is greater than the line
number currently being executed.  If it is greater, GOTO starts its search for
the target line at the current line number.  If it is not greater, GOTO must
search for the target line from the first line of the program.  It is
interesting to note that the test is of the most significant byte only.
Therefore, INT(TARGETLINE/256) must be greater than INT(CURRENTLINE/256) in
order for the search to start with the current line, instead of at the
beginning of the program.
  PEEK, POKE, WAIT, and SYS use this location as a pointer to the address
which is the subject of the command.

22            $16            TEMPPT
Pointer to the Next Available Space in the Temporary String Stack

This location points to the next available slot in the temporary string
descriptor stack located at 25-33 ($19-$21).  Since that stack has room for
three descriptors of three bytes each, this location will point to 25 ($19)
if the stack is empty, to 28 ($1C) if there is one entry, to 31 ($1F) if there
are two entries, and to 34 ($22) if the stack is full.
  If BASIC needs to add an entry to the temporary string descriptor stack, and
this location holds a 34, indicating that the stack is full, the FORMULA TOO
COMPLEX error message is issued.  Otherwise, the entry is added, and three is
added to this pointer.

23-24         $17-$18        LASTPT
Pointer to the Address of the Last String in the Temporary String Stack

This pointer indicates the last slot used in the temporary string
descriptor stack.  Therefore, the value stored at 23 ($17) should be 3 less
than that stored at 22 ($16), while 24 ($18) will contain a 0.

25-33         $19-$21        TEMPST
Descriptor Stack for Temporary Strings

The temporary string descriptor stack contains information about temporary
strings which hve not yet been assigned to a string variable.  An examples of
such a temporary string is the literal string "HELLO" in the statement PRINT
"HELLO".
  Each three-byte descriptor in this stack contains the length of the string,
and its starting and ending locations, expresses as displacements within the
BASIC storage area.

34-37         $22-$25        INDEX
Miscellaneous Temporary Pointers and Save Area

This area is used by many BASIC routines to hold temporary pointers and
calculation results.

38-42         $26-$2A        RESHO
Floating Point Multiplication Work Area

This location is used by BASIC multiplication and division routines.  It is
also used by the routines which compute the size of the area required to store
an array which is being created.

43-44         $2B-$2C        TXTTAB
Pointer to the Start of BASIC Program Text

This two-byte pointer lets BASIC know where program text is stored.
Ordinarily, such text is located beginning at 2049 ($801).  Using this
pointer, it is possible to change the program text area.  Typical reasons for
doing this include:
  1.  Conforming the memory configuration to that of other Commodore
computers.  On 32K PET and CBM computers, for example, screen memory starts at
32768 ($8000), and BASIC text begins at 1025 ($401).  You can emulate this
configuration with the 64 with the following short program:

10 POKE 55,0:POKE 56,128: CLR: REM LOWER TOP OF MEMORY TO 32768
20 POKE 56576,PEEK(56576) AND 253: REM ENABLE BANK 2
30 POKE 53272,4: REM TEXT DISPLAY MEMORY NOW STARTS AT 32768
40 POKE 648,128:REM OPERATING SYSTEM PRINTS TO SCREEN AT 32768 (128*256)
50 POKE 44,4:POKE 1024,0: REM MOVE START OF BASIC TO 1025 (4*256+1)
60 POKE 792,193: REM DISABLE RESTORE KEY
70 PRINT CHR$(147);"NOW CONFIGURED LIKE PET":NEW
80 REM ALSO SEE ENTRIES FOR LOCATION 55, 56576, AND 648

Such reconfiguring can be helpful in transferring programs from the 64 to the
PET, or vice versa.  Since the 64 automatically relocates BASIC program text,
it can load and list PET programs even though the program file indicates a
loading addresss that is different from the 64 start of BASIC.  The PET does
not have this automatic relocation feature, however, and it loads all BASIC
programs at the two-byte address indicated at the beginning of the disk or
tape file.
  So if the PET loads a 64 program at its normal starting address of 2049
($801), it will not recognize its presence because it expects a BASIC program
to start at 1025 ($401).  Therefore, if you want to let a PET and 64 share a
program, you must either reconfigure the 64 to start BASIC where the PET does,
or reconfigure the PET to start BASIC where the 64 does (with a POKE 41,8:POKE
2048,0).
  2.  Raising the lowest location used for BASIC text in order to create a
safe area in low memory.  For example, if you wish to use the high-resolution
graphics mode, you may want to put the start of screen memory at 8192 ($2000).
The high-resolution moe requires 8K of memory, and you cannot use the lowest
8K for this purpose because it is already being used for the zero-page
assignments.
  Since BASIC program text normally starts at 2048 ($801), this means that
you only have 6k for program text before your program runs over into screen
memory.  One way around this is by moving the start of basic to 16385 ($4001)
by typing in direct entry mode:

POKE 44,64: POKE 64*256,0:NEW

Other uses might include setting aside a storage area for sprite shape data,
or user-defined character sets.
  3.  Keeping two or more programs in memory simultaneously.  By changing this
pointer, you can keep more than one BASIC program in memory at one time, and
switch back and forth betwenn them.  Examples of this application can be
found in COMPUTE!'s First Book of PET/CBM, pages 66 and 163.
  This technique has a number of offshoots that are perhaps of more practical
use.
  a) You can store two programs in memory simultaneously for the purpose of
appending one to the other.  This technique requires that the line numbers of
the two programs do not overlap.  (See Programming the PET/CBM by Raeto Collin
West, pages 41-42, for a discussion of this technique).
  b) You can have two programs in memory at once and use the concept in (2)
above to allow an easier way to create a safe area in low memory.  The first
program is just onw line that sets the start of BASIC pointer to the address
of the second program which is located higher in memory, and then runs that
second program.
  4. Since this address is used as the address of the first byte to SAVE, you
can save any section of memory by changing this pointer to indicate the
starting address, and the pointer 45-46 ($2D-$2D) to indicate the address of
the byte after the last byte that you wish to save.

45-46         $2D-$2E        VARTAB
Pointer to the Start of the BASIC Variable Storage Area

This location points to the address which marks the end of the BASIC program
text area, and the beginning of the variable storage area.  All nonarray
variables are stored here, as are string descriptors (for the address of the
area where the actual text of strings is stored, see location 51 ($33)).
  Seven bytes of memory are allocated for each variable.  The first two bytes
are used for the variable name, which consists of the ASCII value of the
first two letters of the variable name.  If the variable name is a single
letter, the second byte will contain a zero.
  The seventh bit of one or both of these bytes can be set (which would add
128 to the ASCII value of the letter).  This indicates the variable type.  If
neither byte has the seventh bit set, the variable is the regular floating
point type.  If only the first byte has its seventh bit set, the variable is a
string.  If only the second byte has its seventh bit set, the variable is a
defined function (FN).  If both bytes have the seventh bit set, the variable
is an integer.
  The use of the other five bytes depends on the type of variable.  A floating
point variable will use the five bytes to store the value of the variable in
floating point format.  An integer will have its value stored in the third and
fourth bytes, high byte first, and the other three will be unused.
  A string variable will use the third byte for its length, and the fourth and
fifth bytes for a pointer to the address of the string text, leaving the last
two bytes unused.  Note that the acrual string text that is pointed to is
located either in the part of the BASIC program where the string is first
assigned a value, or in the string text storage area pointed to by location
51 ($33).
  A function definition will use the third and fourth bytes for a pointer to
the address in the BASIC program text where the function definition starts.
It uses the fifth and sixth bytes for a pointer to the dependent variable (the
X of FN A(X)).  The final byte is not used.
  Knowing something about how variables are created can help your BASIC
programming.  For example, you can see that nonarray integer variables take up
no less space than floating point variables, and since most BASIC commands
convert the integers to floating point, they do not offer a speed advantage
either, and in many cases will actually slow the program down.  As will be
seen below, however, integer arrays can save a considerable amount of space.
  Variables are stored in the order in which they are created.  Likewise,
when BASIC goes looking for a variable, it starts its search at the beginning
of this area.  If commonly used variables are defined at the end of the
program, and are thus at the back of this area, it will take longer to find
them.  It may help program execution speed to define the variables that will
be used most frequently right at the beginning of the program.
  Also, remember that once created, variables do not go away during program
execution.  Even if they are never used again, they still take up space in the
variable storage area, and they slow down the routine that is used to search
for variables that are referenced.
  Another point to consider about the order in which to define variables is
that arrays are created in a separate area of memory which starts at the end
of the nonarray variable area.  Therefore, every time a nonarray variable is
created, all of the arrays must be moved seven bytes higher in memory in order
to make room for the new variable.  Therefore, it may help performance to
avoid defining nonarray variables after defining arrays.
  This pointer will be reset to one byte past the end of the BASIC program
text whenever you execute the statements CLR, NEW, RUN, or LOAD.  Adding or
modifying a BASIC statement will have the same effect, because the higher
numbered BASIC statements have to be moved up into memory to make room for the
new statements, and can therefore overwrite the variable storage area.  This
means that if you wish to check the value of a variable after stopping a
program, you can only do so before modifying the program.
  The exception to the above is when the LOAD command is issued from a
program.  The purpose of not resetting this pointer in such a case is to allow
the chaining of programs by having one program load and then run the next
(that is also why a LOAD issued from a program causes a RUN from the beginning
of the program).  This allows the second program to share variables with the
first.  There are problems with this, however.  Some string variable
descriptors and function definitions have their pointers set to areas within
the program text.  When this text is replaced by a load, these pointers are
no longer valid, which will lead to errors if the FN or string value is
referenced.  And if the second program text area is larger than that of the
first, the second program will overwrite some of the first program's
variables, and their values will be lost.
  The ability to chain short programs is a holdover from the days of the 8K
PET, for which this BASIC was written, but with the vastly increased memory of
the 64, program chaining should not be necessary.
  You should also note that SAVE uses this pointer as the address of the byte
after the last byte to SAVE.

47-48          $2F-$30       ARYTAB
Pointer to the Start of the BASIC Array Storage Area

This location points to the address of the end of nonarray variable storage,
and the beginning of array variable storage.  The format for array storage is
as follows:
  The first two bytes hold the array name.  The format and high-bit patterns
are the same as for nonarray variables (see 45 ($2D) above), except that there
is no equivalent to the function definition.
  Next comes a two-byte offset to the start of the next array, low byte first.
Then there is a one-byte value for the number of array dimensions (e.g., 2 for
a two-dimensional array like A(x,y)).  That byte is followed by pairs of bytes
which hold the value of each array dimension+1 (DIMensioning an array always
makes space for 0, so A(0) can be used).
  Finally come the values of the variables themselves.  The format for these
values is the same as with nonarray values, but each value only takes up the
space required; that is, floating point variables use five bytes each,
integers two bytes, and string descriptors three bytes each.
  Remember that as with nonarray string, the actual string text is stored
elsewhere, in the area which starts at the location pointed to in 51-52 ($33-
$34).

49-50         $31-$32        STREND
Pointer to End of the BASIC Array Storage Area (+1), and the Start of Free RAM

This location points to the address of the end of BASIC array storage space
and the start of free RAM.  Since string text starts at the top of memory and
builds downwards, this location can also be thought of as the last possible
address of the string storage area.  Defining new variables pushes this
pointer upward, toward the last string text.
  If a string for which space is being allocated would cross over this
boundary into the array storage area, garbage collection is performed, and if
there still is not enough room, an OUT OF MEMORY error occurs.  FRE performs
garbage collection, and returns the difference between the addresses pointed
to here and the address of the end of string text storage pointed to by
location 51 ($33).

51-52         $33-$34        FREETOP
Poiner to the Bottom of the String Text Storage Area

This pointer marks the current end of the string text area, and the top of
free RAM (strings are built from the top of memory downward).  Additional
string texts are added, to the area below the address pointed to here.  After
they are added, this pointer is lowered to point below the newly added string
text.  The garbage collection routine (which is also called by FRE) readjusts
this pointer upward.
  While the power-on/reset routines set this pointer to the top of RAM, the
CLR command sets this pointer to the end of BASIC memory, as indicated in
location 55 ($37).  This allows the user to set aside an area of BASIC memory
that will not be disturbed by the program, as detailed at location 55 ($37).

53-54         $35-$36        FRESPC
Temporary Pointer for Strings

This is used as a temporary pointer to the most current string added by the
routines which build strings or move them in memory.

55-56         $37-$38        MEMSIZ
Pointer to the Highest Address Used by BASIC

The power-on/reset routine tests each byte of RAM until it comes to the BASIC
ROM, and sets this pointer to the adress of the highest byte of consecutive
RAM found (40959, $9FFF).
  There are two circumstances under which this pointer may be changed after
power-up to reflect an address lower than the actual top of consecutive RAM:
  1.  Users may wish to lower this pointer themselves, in order to set aside
an area of free RAM that will not be disturbed by BASIC.  For example, to set
aside a 1K area at the top of BASIC, start your program with the line:

POKE 56,PEEK(56)-4:CLR

The CLR is necessary to insure that the string text will start below your safe
area.
  You may wish to store machine language programs, sprites, or alternate
character sets in such an area.  For the latter two applications, however,
keep in mind the 16K addressing range limitation of the VIC-II chip.  If you
do not assign the VIC-II to a bank other than the default memory bank of
0-16383 ($0-$3FFF), you must lower the top of memory below 16383 ($3FFF) if
you wish your sprite or character data area to be within its addressing range.
  2.  Then the RS-232 device (number 2) is opened, this pointer and the
pointer to the end of user RAM at 643 are lowered by 512 bytes in order to
create two 256-byte buffers, one for input and the other for output.
  Since the contents of these buffers will overwrite any variables at the top
of memory, a CLR command is issued at the time device 2 is opened.  Therefore,
the RS-232 device should be opened before defining any variables, and before
setting aside a safe area for machine language programs or other uses, as
described above.

57-58         $39-$3A        CURLIN
Current BASIC Line Number

This location contains the line number of the BASIC statement which is
currently being executed, in LSB/MSB format.  A value of 255 ($FF) in location
58 ($3A), which translates to a line number of 65280 or above (well over the
63999 limit for a program line), means that BASIC is currently in immediate
mode, rather than RUN mode.
  BASIC keywords that are illegal in direct mode check 58 ($3A) to determine
whether or not this is the current mode.
  When in RUN mode, this location is updated as each new BASIC line is fetched
for execution.  Therefore, a TRACE function could be added by diverting the
vector at 776 ($308), which points to the routine that executes the next
token, to a user-written routine which prints the line number indicated by
this location before jumping to the token execution routine.  (LISTing the
line itself would be somewhat harder, because LIST uses many Page 0 locations
that would have to be preserved and restored afterwards.)
  This line number is used by BREAK and error messages to show where program
execution stopped.  The value here is copied to 59 ($3B) by STOP, END, and the
stop-key BREAK, and copied back by CONT.

59-60         $3B-$3C        OLDLIN
Previous BASIC Line Number

When program execution ends, the last line number executed is stored here, and
restored to location 57 ($39) by CONT.

61-62         $3D-$3E        OLDTXT
Pointer to the Address of the Current BASIC Statement

This location contains the address (not the line number) of the text of the
BASIC statement that is being executed.  The value of TXTPTR (122, $7A), the
pointer tot he address of the BASIC text character currently being scanned, is
stored here each time a new BASIC line begins execution.
  END, STOP, and the STOP-key BREAK save the value of TXTPTR here, and CONT
restores this value to TXTPTR.  CONT will not continue if 62 ($3E) has been
changed to a zero by a LOAD, a modification to the program text, or by error
routines.

63-64         $3F-$40        DATLIN
Current DATA Line Number

This location holds the line number of the current DATA statement being READ.
It should be noted that this information is not used to determine where the
next DATA item is read from (that is the job of the pointer at 65-66 ($41-$42)
below).  But if an error concerning the DATA occurs, this number will be moved
to 57 ($39), so that the error message will show that the error occurred in
the line that contains the DATA statement, rather than in the line that
contains the READ statement.

65-66         $41-$42        DATPTR
Pointer to the Address of the Current DATA Item

This location points to the address (not the line number) within the BASIC
program text area where DATA is currently being READ.  RESTORE sets this
pointer back to the address indicated by the start of BASIC pointer at
location 43 ($2B).
  The sample program below shows how the order in which DATA statements are
READ can be changed using this pointer.  The current address of the statement
before the DATA statement is stored in a variable, and then used to change
this pointer.

10 A1=PEEK(61):A2=PEEK(62)
20 DATA THIS DATA WILL BE USED SECOND
30 B1=PEEK(61):B2=PEEK(62)
40 DATA THIS DATA WILL BE USED FIRST
50 C1=PEEK(61):C2=PEEK(62)
60 DATA THIS DATA WILL BE USED THIRD
70 POKE 65,B1:POKE 66,B2:READ A$:PRINT A$
80 POKE 65,A1:POKE 66,A2:READ A$:PRINT A$
90 POKE 65,C1:POKE 66,C2:READ A$:PRINT A$

67-68         $43-$44        INPPTR
Pointer in the Source of GET, READ, or INPUT Information

READ, INPUT and GET all use this as a pointer to the address of the source of
incoming data, such as DATA statements, or the text input buffer at 512
($200).

69-70         $45-$46        VARNAM
Current BASIC Variable Name

The current variable name being searched for is stored here, in the same two-
byte format as in the variable value storage area located at the address
pointed to by 45 ($2D).  See that location for an explanation of the format.

71-72         $47-$48        VARPNT
Pointer to the Current BASIC Variable Value

This location points to the address of the descriptor of the current BASIC
variable (see location 45 ($2D) for the format of a variable descriptor).
Specifically, it points to the byte just after the two-character variable
name.
  During a FN call, this location does not point to the dependent variable
(the A of FN A), so that a real variable of the same name will not have its
value changed by the call.

73-74         $49-$4A        FORPNT
Temporary Pointer to the Index Variable Used by FOR

The address of the BASIC variable which is the subject of a FOR/NEXT loop is
first stored here, but is then pushed onto the stack.  That leaves this
location free to be used as a work area by such statements as INPUT, GET,
READ, LIST, WAIT, CLOSE, LOAD, SAVE, RETURN, and GOSUB.
  For a description of the stack entries made by FOR, see location 256 ($100).

75-76         $4B-$4C        OPPTR
Math Operator Table Displacement

This location is used during the evaluation of mathematical expressions to
hold the displacement of the current math operator in an operator table.  It
is also used as a save area for the pointer to the address of program text
which is currently being read.

77            $4D            OPMASK
Mask for Comparison Operation

The expression evaluation routine creates a mask here which lets it know
whether the current comparieson operation is a less-than (1), equals (2), or
greater-than (4) comparison.

78-79         $4E-$4F        DEFPNT
Pointer to the Current FN Descriptor

During function definition (DEF FN) this location is used as a pointer to the
descriptor that is created.  During function execution (FN) it points to the
FN descriptor in which the evaluation results should be saved.

80-82         $50-$52        DSCPNT
Temporary Pointer to the Current String Descriptor

The string assignment and handling routines use the first two bytes as a
temporary pointer to the current string descriptor, and the third to hold the
value of the string length.

83            $53            FOUR6
Constant for Garbage Collection

The constant contained here lets the garbage collection routines know whether
a three- or seven-byte string descriptor is being collected.

84-86         $54-$56        JMPER
Jump to Function Instruction

The first byte is the 6502 JMP instruction ($4C), followed by the address of
the required function taken from the table at 41042 ($A052).

87-96         $57-$60
BASIC Numeric Work Area

This is a very busy work area, used by many routines.

97-102        $61-$66        FAC1
Floating Point Accumulator #1

The Floating Point Accumulator is central to the execution of any BASIC
mathematical operation.  It is used in the conversion of integers to floating
point numbers, strings to floating point numbers, and vice versa.  The results
of most evaluations are stored in this location.
  The internal format of floating point numbers is not particularly easy to
understand (or explain).  Generally speaking, the number is broken into the
normalized mantissa, which represents a number between 1 and 1.99999..., and
an exponent value, which represents a power of 2.  Multiplying the mantissa by
2 raised to the value of the exponent gives you the value of the floating
point number.
  Fortunately, the BASIC interpreter contains many routines for the
manipulation and conversion of floating point number, and these routines can
be called by the user.  See the entries for locations 3 and 5
  Floating Point Accumulator #1 can be further divided into the following
locations:

97            $61            FACEXP
Floating Point Accumulator #1: Exponent

This exponent represents the closest power of two to the number, with 129
added to take care of the sign problem for negative exponents.  An exponent
of 128 is used for the value 0; an exponent of 129 represents 2 to the 0
power, or 1; an exponent of 130 represents 2 to the first power, or 2; 131 is
2 squared, or 4; 132 is 2 cubed, or 8; and so on.

98-101        $62-$65        FACHO
Floating Point Accumulator #1: Mantissa

The most significant digit can be assumed to be a 1 (remember that the range
of the mantissa is from 1 to 1.99999...) when a floating point number is
stored to a variable.  The first bit is used for the sign of the number, and
the other 31 bits of the four-byte mantissa hold the other significant digits.
  The first two bytes (98-99, $62-$63) of this location will hold the signed
integer result of a floating point to integer conversion, in high-byte, low-
byte order.

102           $66            FACSGN
Floating Point Accumulator #1: Sign

A value of 0 here indicates a positive number, while a value of 255 ($FF)
indicates a negative number.

103           $67            SGNFLG
Number of Terms in a Series Evaluation

This location is used by mathematical formula evaluation routines.  It
indicates the number of separate evaluations that must be done to resolve a
complex expression down to a single term.

104           $68            BITS
Floating Point Accumulator #1: Overflow Digit

This location contains the overflow byte.  The overflow byte is used in an
intermediate step of conversion from an integer or text string to a floating
point number.

105-110       $69-$6E        FAC2
Floating Point Accumulator #2

A second Floating Point Accumulator, used in conjunction with Floating Point
Accumulator #1 in the evaluation of products, sums, differences--in short, any
operation requiring more than one value.  The format of this accumulator is
the same as FAC1.

105           $69            ARGEXP
Floating Point Accumulator #2: Exponent

106-109       $6A-$6D        ARGHO
Floating Point Accumulator #2: Mantissa

110           $6E            ARGSGN
Floating Point Accumulator #2: Sign

111           $6F            ARISGN
Result of a Signed Comparison of Accumulator #1 to Accumulator #2

Used to indicate whether the two Floating Point Accumulators have like or
unlike signs.  A 0 indicates like signs, a 255 ($FF) indicates unlike signs.

112           $70            FACOV
Low Order Mantissa Byte of Floating Point Accumulator #1 (For Rounding)

If the mantissa of the floating point number has more significant figures than
can be held in four bytes, the least significant figures are placed here.
They are used to extend the accuracy of intermediate mathematical operations
and to round to the final figure.

113-114       $71-$72        FBUFPT
Series Evaluation Pointer

This location points to the address of a temporary table of values built in
the free RAM area for the evaluation of formulas.  It is also used for such
various purposes as a TI$ work area, string setup pointer, and work space for
the evaluation of the size of an array.
  Although this is labeled a pointer to the tape buffer in the Programmer's
Reference Guide, disassembly of the BASIC ROM reveals no reference to this
location for that purpose (see 178 ($B2) for pointer to tape buffer).

115-138       $73-$8A        CHRGET
Subroutine: Get Next BASIC Text Character

This is actually a machine language subroutine, which at the time of a BASIC
cold start (such as when the power is turned on) is copied from MOVCHG (58274,
$E3A2) in the ROM to this zero page location.
  CHRGET is a crucial routine which BASIC uses to read text characters, such
as the text of the BASIC program which is being interpreted.  It is placed on
zero page to make the routine run faster.  Since it keeps track of the address
of the character being read within the routine itself, the routine must be in
RAM in order to update that pointer.  The pointer to the address of the byte
currently being read is really the operand of a LDA instruction.  When entered
from CHRGET, the routine increments the pointer by modifying the operand at
TXTPTR (122, $7A), thus allowing the next character to be read.
  Entry at CHRGOT (121, $79) allows the current character to be read again.
The CHRGET routine skips spaces, sets the various flags or the status register
(.P) to indicate whether the character read was a digit, statement terminator,
or other type of character, and returns with the retrieved character in the
Accumulator (.A).
  Since CHRGET is used to read every BASIC statement before it is executed,
and since it is in RAM, and therefore changeable, it makes a handy place to
intercept BASIC to add new features and commands (and in the older PET line,
it was the only way to add such features).  Diversion of the CHRGET routine
for this purpose is generally referred to as a wedge.
  Since a wedge can greatly slow down execution speed, mose of the time it is
set up so that it performs its preprocessing functions only when in direct or
immediate mode.  The most well-known example of such a wedge is the
"Universal DOS Support" program that allows easier communication with the
disk drive command channel.
  As this is such a central routine, a disassembly listing is given below to
provide a better understanding of how it works.

115 $73   CHRGET  INC TXTPTR   ; increment low byte of TXTPTR
117 $75           BNE CHRGOT   ; if low byte isn't 0, skip next
119 $77           INC TXTPTR+1 ; increment high byte of TXTPTR
121 $79   CHRGOT  LDA          ; load byte from where TXTPTR points
                               ; entry here does not update TXTPTR,
                               ; allowing you to readl the old byte again
122 $7A   TXTPTR  $0207        ; pointer is really the LDA operand
                               ; TXTPTR+1 points to 512-580 ($200-$250)
                               ; when reading from the input buffer
                               ; in direct mode
124 $7C   POINTB  CMP #$3A     ; carry flag set if > ASCII numeral 9
126 $7E           BCS EXIT     ; character is not a numeral--exit
128 $80           CMP #$20     ; if it is an ASCI space...
130 $82           BEQ CHRGET   ; ignore it and get next character
132 $84           SEC          ; prepare to subtract
133 $85           SBC #$30     ; ASCII 0-9 are between 48-57 ($30-$39)
135 $87           SEC          ; prepare to subtract again
136 $88           SBC #$D0     ; if < ASCII 0 (57, $39) then carry is set
138 $8A   EXIT    RTS          ; carry is clear only for numeral on return

The Accumulator (.A register) holds the character that was read on exit from
the routine.  Status register (.P) bits which can be tested for on exit are:

  Carry Clear if the character was an ASCII digit 0-9.
  Carry Set, otherwise.
  Zero Set only if the character was a statement terminator 0 or an ASCII
colon, 58 ($3A).
  Zero Clear, otherwise.

  One wedge insertion technique is to change CHRGET's INC $7A to a JMP WEDGE,
have your wedge update TXTPTR itself, and then JSR CHRGOT.  Another is to
change the CMP #$3A at location 124 ($7C), which I have labeled POINTB, to a
JMP WEDGE, do your wedge processing, and then exit through the ROM version of
POINTB, which is located at 48283 ($E3AB).  For more detailed information
about wedges, see Programming the PET/CBM, Raeto Collin West, pages 365-68.
  While the wedge is a good, quick technique for adding new commands, a much
more elegant method exists for accomplishing this task on the VIC-20 and 64
withouth slowing BASIC down to the extent that the wedge does.  See the
entries for the BASIC RAM vector area at 768-779 ($300-$30B) for more details.

139-143       $8B-$8F        RNDX
RND Function Seed Value

This location holds the five-byte floating point value returned by the RND
function.  It is initially set to a seed value copied from ROM (the five bytes
are 128, 79, 199, 82, 88--$80, $4F, $C7, $52, $58).
  When the function RND(X) is called, the numeric value of X does not affect
the number returned, but its sign does.  If X is equal to 0, RND generates a
seed value from chip-level hardware timers.  If X is a positive number, RND(X)
will return the next number in an arithmetic sequence.  This sequence
continues for such a long time without repeating itself, and gives such an
even distribution of numbers, that it can be considered random.  If X is
negative, the seed value is changed to a number that corresponds to a
scrambled floating point representation of the number X itself.
  Given a particular seed value, the same pseudorandom series of numbers will
always be returned.  This can be handy for debugging purposes, but not where
you wish to have truly random numbers.
  The traditional Commodore method of selecting a random seed is by using the
expression RND(-TI), mostly because RND(0) didn't function correctly on early
PETs.  While the RND(0) form doesn't really work right on the 64 either (see
location 57495 ($E097)), the expression RND(-RND(0)) may produce a more random
seed value.

Location Range: 144-255 ($90-$FF)
Kernal Work Storage Area

This is the zero-page storage area for the Kernal.  The user should take into
account what effect changing a location here will have on the operation of the
Kernal functions before making any such changes.
  At power-on, this range of locations is first filled with zeros, and then
initialized from values stored in ROM as needed.

144           $90            STATUS
Kernal I/O Status Word (ST)

The Kernal routines which open I/O channels or perform input/output functions
check and update this location.  The value here is almost always the same as
that returned to BASIC by use of the reserved variable ST.  Note that BASIC
syntax will not allow an assignment such as ST=4.  A table of status codes for
cassette and serial devices follows below:

Cassette:
Bit 2 (Bit Value of 4) = Short Block
Bit 3 (Bit Value of 8) = Long Block
Bit 4 (Bit Value of 16) = Unrecoverable error (Read), mismatch
Bit 5 (Bit Value of 32) = Checksum error
Bit 6 (Bit Value of 64) = End of file

Serial Devices:
Bit 0 (Bit Value of 1) = Time out (Write)
Bit 1 (Bit Value of 2) = Time out (Read)
Bit 6 (Bit Value of 64) = EOI (End or Identify)
Bit 7 (Bit Value of 128) = Device not present

Probably the most useful bit to test is Bit 6 (end of file).  When using the
GET statement to read in individual bytes from a file, the statement IF ST AND
64 will be true if you have got to the end of the file.
  For status codes for the RS-232 device, see the entry for location 663
($297).
  
145           $91            STKEY
Flag: Was STOP Key Pressed?

This location is updated every 1/60 second during the execution of the IRQ
routine that reads the keyboard and updates the jiffy clock.
  The value of the last row of the keyboard matrix is placed here.  That row
contains the STOP key, and although this location is used primarily to detect
when that key has been pressed, it can also detect when any of the other keys
in that row of the matrix have been pressed.
  In reading the keyboard matrix, a bit set to 1 means that no key has been
pressed, while a bit reset to 0 indicates that a key is pressed.  Therefore,
the following values indicate the keystrokes detailed below:

255 $FF  = no key pressed
254 $FE  = 1 key pressed
253 $FD  = (left arrow) key pressed
251 $FB  = CTRL key pressed
247 $F7  = 2 key pressed
239 $EF  = space bar pressed
223 $DF  = Commodore logo key pressed
191 $BF  = Q key pressed
127 $7F  = STOP key pressed

VIC owners will notice that the 64's keyboard matrix is very different from
the VIC's.  One of the advantages of this difference is that you can test for
the STOP key by following a read of this location with a BPL instruction,
which will cause a branch to occur anytime that the STOP key is pressed.

146           $92            SVXT
Timing Constant for Tape Reads

This location is used as an adjustable timing constant for tape reads, which
can be changed to allow for the slight speed variation between tapes.

147           $93            VERCK
Flag for Load Routine: 0=LOAD, 1=VERIFY

The same Kernal routine can perform either a LOAD or VERIFY, depending on the
value stored in the Accumulator (.A) on entry to the routine.  This location
is used to determine which operation to perform.

148           $94            C3PO
Flag: Serial Bus--Output Character Was Buffered

This location is used by the serial output routines to indicate that a
character has been placed in the output buffer and is waiting to be sent.

149           $95            BSOUR
Buffered Character for Serial Bus

This is the character waiting to be sent.  A 255 ($FF) indicates that no
character is waiting for serial output.

150           $96            SYNO
Cassette Block Synchronization Number

151           $97            XSAV
Temporary .X Register Save Area

This .X register save area is used by the routines that get and put an ASCII
character.

152           $98            LDTND
Number of Open I/O Files/Index to the End of File Tables

The number of currently open I/O files is stored here.  The maximum number
that can be open at one time is ten.  The number stored here is used as the
index to the end of the tables that hold the file numbers, device numbers, and
secondary address numbers (see locations 601-631 ($259-$277) for more
information about these tables).
  CLOSE decreases this number and removes entries from the tables referred to
above, while OPEN increases it and adds the appropriate information to the end
of the tables.  The Kernal routine CLALL closes all files by setting this
number to 0, which effectively empties the table.

153           $99            DFLTN
Default Input Device (Set to 0 for Keyboard)

The default value of this location is 0, which designates the keyboard as the
current input device.  That value can be changed by the Kernal routine CHKIN
(61966, $F20E), which uses this location to store the device number of the
device whose file it defines as an input channel.
  BASIC calls CHKIN whenever the command INPUT# or GET# is executed, but
clears the channel after the input operation has been completed.

154           $9A            DFLTO
Default Output (CMD) Device (Set to 3 for the Screen)

The default value of this location is 3, which designates the screen as the
current output device.  That value can be changed by the Kernal routine CHKOUT
(62032, $F250), which uses this location to store the device number of the
device whose file it defines as an output channel.
  BASIC calls CHKOUT whenever the command PRINT# or CMD is executed, but
clears the channel after the PRINT# operation has been completed.

155           $9B            PRTY
Tape Character Parity

This location is used to help detect when bits of information have been lost
during transmission of tape data.

156           $9C            DPSW
Flag: Tape Byte Received

This location is used as a flag to indicate whether a complete byte of tape
data has been received, or whether it has only been partially received.

157           $9D            MSGFLG
Flag: Kernal Message Control

This flag is set by the Kernal routine SETMSG (65048, $FE18), and it controls
whether or not Kernal error messages or control messages will be displayed.
  A value of 192 ($C0) here means that both Kernal error and control messages
will be displayed.  This will never normally occur when using BASIC, which
prefers its own plain text error messages over the Kernal's perfunctory I/O
ERROR (number).  The Kernal error messages might be used, however, when you
are SAVEing or LOADing with a machine language monitor.
  A 128 ($80) means that control messages only will be displayed.  Such will
be the case when you are in the BASIC direct or immediate mode.  These
messages include SEARCHING, SAVING, FOUND, etc.
  A value of 64 means that Kernal error messages only are on.  A 0 here
suppresses the display of all Kernal messages.  This is the value placed here
when BASIC enters the program or RUN mode.

158           $9E            PTR1
Tape Pass 1 Error Log Index

This location is used in setting up an error log of bytes in which
transmission parity errors occur the first time that the block is received
(each tape block is sent twice to minimize data loss from transmission error).

159           $9F            PTR2
Tape Pass 2 Error Log Correction Index

This location is used in correcting bytes of tape data which were transmitted
incorrectly on the first pass.

160-162       $A0-$A2        TIME
Software Jiffy Clock

These three locations are updated 60 times a second, and serve as a software
clock which counts the number of jiffies (sixtieths of a second) that have
elapsed since the computer was turned on.
  The value of location 162 ($A2) is increased every jiffy (0.1667 second),
161 ($A1) is updated every 256 jiffies (4.2267 seconds), and 160 ($A0) changes
every 65536 jiffies (or every 18.2044 minutes).  After 24 hours, these
locations are set back to 0.
  The jiffy clock is used by the BASIC reserved variables TI and TI$.  These
are not ordinary variables that are stored in the RAM variable area, but are
functions that call the Kernal routines RDTIM (63197, $F6DD), and SETTIM
(63204, $F6E4).  Assigning the value of TI or TI$ to another variable reads
these locations, while assigning a given value to TI$ alters these locations.
  To illustrate the relationship between these locations and TI$, try the
following program.  The program sets the jiffy clock to 23 hours, 50 minutes.
After the program has been running for one minute, all these locations will
be reset to 0.

100 TI$="235900"
110 PRINT TI$,PEEK(160),PEEK(161),PEEK(162)
120 GOTO 110

Since updating is done by the IRQ interrupt that reads the keyboard, anything
which affects the operation of that interrupt routine will also interfere with
this clock.  A typical example is tape I/O operations, which steal the IRQ
vector for their own use, and restore it afterwards.  Obviously, user routines
which redirect the IRQ and do not send it back to the normal routine will
upset software clock operation as well.

163-164       $A3-$A4
Temporary Data Storage Area

These locations are used temporarily by the tape and serial I/O routines.

165           $A5            CNTDN
Cassette Synchronization Character Countdown

Used to count down the number of synchronization characters that are sent
before the actual data in a tape block.

166           $A6            BUFPNT
Count of Characters in Tape I/O Buffer

This location is used to count the number of bytes that have been read in or
written to the tape buffer.  Since on a tape write, no data is sent until the
192 byte buffer is full, you can force output of the buffer with the statement
POKE 166,191.

167           $A7            INBIT
RS-232 Input Bits/Cassette Temporary Storage Area

This location is used to temporarily store each bit of serial data that is
received, as well as for miscellaneous tasks by tape I/O.

168           $A8            BITCI
RS-232 Input Bit Count/Cassete Temporary Storage

This location is used to count the number of bits of serial data that has been
received.  This is necessary so that the serial routines will know when a full
word has been received.  It is also used as an error flag during tape loads.

169           $A9            RINONE
RS-232 Flag: Check for Start Bit

This flag is used when checking for a start bit.  A 144 ($90) here indicates
that no start bit was received, while a 0 means that a start bit was received.

170           $AA            RIDATA
RS-232 Input Byte Buffer/Cassette Temporary Storage

Serial routines use this area to reassemble the bits received into a byte that
will be stored in the receiving buffer pointer to by 247 ($F7).  Tape routines
use this as a flag to help determine whether a received character should be
treated as data or as a synchronization character.

171           $AB            RIPRTY
RS-232 Input Parity/Cassete Leader Counter

This location is used to help detect if data was lost during RS-232
transmission, or if a tape leader is completed.

172-173       $AC-$AD        SAL
Pointer to the Starting Address of a Load/Screen Scrolling

The pointer to the start of the RAM area to be SAVEd or LOADed at 193 ($C1) is
copied here.  This pointer is used as a working version, to be increased as
the data is received or transmitted.  At the end of the operation, the initial
value is restored here.  Screen management routines temporarily use this as a
work pointer.

174-175       $AE-$AF        EAL
Pointer to Ending Address of Load (End of Program)

This location is set by the Kernal routine SAVE to point to the ending address
for SAVE, LOAD, or VERIFY.

176-177       $B0-$B1        CMP0
Tape Timing

Location 176 ($B0) is used to determine the value of the adjustable timing
constant at 146 ($92).  Location 199 is also used in the timing of tape reads.

178-179       $B2-$B3        TAPE1
Pointer: Start of Tape Buffer

On power-on, this pointer is set to the address of the cassette buffer (828,
$33C).  This pointer must contain an address greater than or equal to 512
($200), or an ILLEGAL DEVICE NUMBER error will be sent when tape I/O is tried.

180           $B4            BITTS
RS-232 Output Bit Count/Cassette Temporary Storage

RS-232 routines use this to count the number of bits transmitted, and for
parity and stop bit manipulation.  Tape load routines use this location to
flag when they are ready to receive data bytes.

181           $B5            NXTBIT
RS-232 Next Bit to Send/Tape EOT Flag

This location is used by the RS-232 routines to hold the next bit to be sent,
and by the tape routines to indicate what part of a block the read routine is
currently reading.

182           $B6            RODATA
RS-232 Output Byte Buffer

RS-232 routines use this area to disassemble each byte to be sent from the
transmission buffer pointed to by 249 ($F9).

183           $B7            FNLEN
Length of Current Filename

This location holds the number of characters in the current filename.  Disk
filenames may have from 1 to 16 characters, while tape filenames range from
0 to 187 characters in length.
  If the tape name is longer than 16 characters, the excess will be
truncated by the SEARCHING and FOUND messages, but will still be present on
the tape.  This means that machine language programs meant to run in the
cassette buffer may be saved as tape filenames.
  A disk file is always referred to be a name, whether full or generic
(containing the wildcard characters * or ?).  This location will always be
greater than 0 if the current file is a disk file.  Tape LOAD, SAVE, and
VERIFY operations do not require that a name be specified, and this location
can therefore contain a 0.  If this is the case, the contents of the pointer
to the filename at 187 will be irrelevant.
  An RS-232 OPEN command may specify a filename of up to four characters.
These characters are copied to locations 659-662 ($293-$296), and determine
baud rate, word length, and parity.

184           $B8            LA
Current Logical File Number

This location holds the logical file number of the device currently being
used.  A maximum of five disk files, and ten files in total, may be open at
any one time.
  File numbers range from 1 to 255 (a 0 is used to indicate system defaults).
When printing to a device with a file number greater than 127, an ASCII
linefeed character will be sent following each carriage return, which is
useful for devices like serial printers that require linefeeds in addition to
carriage returns.
  The BASIC OPEN command calls the Kernal OPEN routine, which sets the value
of this location.  In the BASIC statement OPEN 4,8,15, the logical file number
corresponds to the first parameter 4.

185           $B9            SA
Current Secondary Address

This location holds the secondary address of the device currently being used.
The range of valid secondary address numbers is 0 through 31 for serial
devices, and 0 through 127 for other devices.
  Secondary device numbers mean something different to each device that they
are used with.  The keyboard and screen devices ignore the secondary address
completely.  But any device which can have more than one file open at the
same time, such as the disk drive, distinguishes between these files by using
the secondary address when opening a disk file.  Secondary address numbers 0,
1, and 15-31 have a special significance to the disk drive, and therefore
device numbers 2-14 only should be used as secondary addresses when opening a
disk file.
  OPENing a disk file with a secondary address of 15 enables the user to
communicate with the Disk Operating System through that channel.  A LOAD
command which specifies a secondary address of 0 (for example, LOAD
"AT BASIC",8,0) results in the program being loaded not to the address
specified on the file as the starting address, but rather to the address
pointed to by the start of BASIC pointer (43, $2B).
  A LOAD with a secondary address of 1 (for example, LOAD "HERE",8,1) results
in the contents of the file being loaded to the address specified in the file.
A disk file that has been LOADed using a secondary address of 1 can be
successfully SAVEd in the same manner (SAVE "DOS 5.1",8,1).
  LOADs and SAVEs that do not specify a secondary address will default to a
secondary address of 0.
  When OPENing a Datasette recorder file, a secondary address of 0 signifies
that the file will be read, while a secondary address of 1 signifies that the
file will be written to.  A value of 2 can be added to indicate that an End
of Tape marker should be written as well.  This marker tells the Datasette
not to search past it for any more files on the tape, though more files can be
written to the tape if desired.
  As with the disk drive, the LOAD and SAVE commands use secondary addresses
of 0 and 1 respectively to indicate whether the operation should be relocating
or nonrelocating.
  When the 1515 or 1525 Printer is opened with a secondary address of 7, the
uppercase/lowercase character set is used.  If it is openend with a secondary
address of 0, or without a secondary address, the uppercase/graphics character
set will be used.

186           $BA            FA
Current Device Number

This location holds the number of the device that is currently being used.
Device number assignments are as follows:

0    = Keyboard
1    = Datasette Recorder
2    = RS-232/User Port
3    = Screen
4-5  = Printer
8-11 = Disk
   
187-188       $BB-$BC        FNADR
Pointer: Current Filename

This location holds a pointer to the address of the current filename.  If an
operation which OPENs a tape file does not specify a filename, this pointer
is not used.
  When a disk filename contains a shifted space character, the remainder of
the name will appear outside the quotes in the directory, and may be used for
comments.  For example, if you SAVE "ML[shifted space]SYS828", the directory
entry will read "ML"SYS 828.  You may reference the program either by the
portion of the name that appears within quotes, or by the full name, including
the shifted space.  A program appearing later in the directory as "ML"SYS 900
would not be found just by reference to "ML", however.
  A filename of up to four characters may be used when opening the RS-232
device.  These four characters will be copied to 659-662 ($293-$296), where
they are used to control such parameters as baud rate, parity, and word
length.

189           $BD            ROPRTY
RS-232 Output Parity/Cassette Temporary Storage

This location is used by the RS-232 routines as an output parity work byte,
and by the tape as temporary storage for the current character being read or
sent.

190           $BE            FSBLK
Cassette Read/Write Block Count

Used by the tape routines to count the number of copies of a data block
remaining to be read or written.

191           $BF            MYCH
Tape Input Byte Buffer

This is used by the tape routines as a work area in which incoming characters
area assembled.

192           $C0            CAS1
Tape Motor Interlock

This location is maintained by the IRQ interrupt routine that scans the
keyboard.  Whenever a button is pressed on the recorder, this location is
checked.  If it contains a 0, the motor is turned on by setting Bit 5 of
location 1 to 0.  When the button is let up, the tape motor is turned off, and
this location is set to 0.
  Since the interrupt routine is executed 60 times per second, you will not be
able to keep the motor bit set to keep the motor on if no buttons are pushed.
Likewise, if you try to turn the motor off when a button is pressed and this
location is set to 0, the interrupt routine will turn it back on.
  To control the motor via software, you must set this location to a nonzero
value after one of the buttons on the recorder has been pressed.

193-194       $C1-$C2        STAL
I/O Start Address

This location points to the beginning address of the area in RAM which is
currently being LOADed or SAVEd.  For tape I/O, it will point to the cassette
buffer, and the rest of the data is LOADed or SAVEd directly to or from RAM.
This location points to the beginning address of the area of RAM to be used
for the blocks of data that come after the initial header.

197           $C5            LSTX
Matrix Coordinate of Last Key Pressed, 64=None Pressed

During every normal IRQ interrput this location is set with the value of the
last keypress, to be used in keyboard debouncing.  The Operating System can
check if the current keypress is the same as the last one, and will not repeat
the character if it is.
  The value returned here is based on the keyboard matrix values as set forth
in the explanation of location 56320 ($DC00).  The values returned for each
key pressed are shown at the entry for location 203 ($CB).

198           $C6            NDX
Number of Characters in Keyboard Buffer (Queue)

The value here indicates the number of charracters waiting in the keyboard
buffer at 631 ($277).  The maximum number of characters in the keyboard buffer
at any one time is determined by the value in location 649 ($289), which
defaults to 10.
  If INPUT or GET is executed while there are already characters in the
buffer, those characters will be read as part of the data stream.  You can
prevent this by POKEing a 0 to this location before those operations, which
will always cause any character in the buffer to be ignored.  This technique
can be handy when using the joystick in Controller Port #1, which sometimes
causes fake keypresses to be registered, placing unwanted characters in the
keyboard buffer.
  Not only is this location handy for taking unwanted characters out of the
keyboard buffer, but it can also be used to put desired characters into the
buffer, and thus to program the keyboard buffer.  This technique (dynamic
keyboard) allows you to simulate keyboard input in direct mode from a program.
  The dynamic keyboard technique is an extremely useful one, as it enables you
to add, delete, or modify program lines while the program is running.  The
basic scheme is to POKE the PETASCII character values that you wish to be
printed (including cursor control characters and carriage returns) into the
buffer.  Then, when an END statement is executed, the characters in the buffer
will be printed, and entered by the carriage return.
  This technique can help with the problem of trying to use data separation
and terminator characters with INPUT statements.  If you try to INPUT a string
that has a comma or colon, the INPUT will read only up to that character and
issue an EXTRA IGNORED error message.  You can avoid this by entering the
input string in quotes, but this places on the user the burder of remembering
the quote marks.  One solution is to use the statements:

POKE 198,3:POKE 631,34: POKE 632,34: POKE 633,20

before the input.  This will force two quote marks and a delete into the
buffer.  The first quote mark allows the comma or colon to be INPUT, the
second is used to get the editor out of quote mode, and the delete removes
that second quote.
  For more specific information and programming examples, see the description
of location 631 ($277), the keyboard buffer.

199           $C7            RVS
Flag: Print Reverse Characters? 0=No

When the [CTRL][RVS-ON] characters are printer (CHR$(18)), this flag is set to
18 ($12), and the print routines will add 128 ($80) to the screen code of each
character which is printed, so that the caracter will appear on the screen
with its colors reversed.
  POKEing this location directly with a nonzero number will achieve the same
results.  You should remember, however, that the contents of this location are
returned to 0 not only upon entry of a [CTRL][RVS-OFF] character (CHR$(146)),
but also at every carriage return.  When this happens, characters printed
thereafter appear with the normal comination of colors.

200           $C8            INDX
Pointer: End of Logical Line for Input

This pointer indicates the column number of the last nonblank character on the
logical line that is to be input.  Since a logical line can be up to 80
characters long, this number can range from 0-79.

201-202       $C9-$CA        LXSP
Cursor X,Y Position at Start of Input

These locations keep track of the logical line that the cursor is on, and its
column position on that logical line (in line, column format).
  Each logical line may contain one or two 40-column physical lines.  Thus
there may be as many as 25 logical lines, or as few as 13 at any one time.
Therefore, the logical line number might be anywhere from 1-25.  Depending on
the length of the logical line, the cursor column may be from 1-40 or 1-80.
  For a more detailed exaplanation of logical lines, see the description of
the screen line link talbe, 217 ($D9).

203           $CB            SFDX
Matrix Coordinate of Current Key Pressed

The keyscan interrupt routine uses this location to indicate which key is
currently being pressed.  The value here is then used as an index into the
appropriate keyboard table to determine which character to print when a key is
struck.
  The correspondence between the key pressed and the number stored here is as
follows:

0  = INST/DEL                34 = J
1  = RETURN                  35 = 0
2  = CRSR RIGHT              36 = M
3  = F7                      37 = K
4  = F1                      38 = O
5  = F3                      39 = N
6  = F5                      40 = +
7  = CRSR DOWN               41 = P
8  = 3                       42 = L
9  = W                       43 = -
10 = A                       44 = .
11 = 4                       45 = :
12 = Z                       46 = @
13 = S                       47 = ,
14 = E                       48 = LIRA (BRITISH POUND SIGN)
15 = NOT USED                49 = *
  (WOULD BE LEFT SHIFT)      50 = ;
16 = 5                       51 = CLR/HOME
17 = R                       52 = NOT USED
18 = D                         (WOULD BE RIGHT SHIFT)
19 = 6                       53 = =
20 = C                       54 = UP ARROW
21 = F                         (EXPONENTATION SIGN)
22 = T                       55 = /
23 = X                       56 = 1
24 = 7                       57 = LEFT ARROW
25 = Y                       58 = NOT USED
26 = G                         (WOULD BE CTRL)
27 = 8                       59 = 2
28 = B                       60 = SPACE BAR
29 = H                       61 = NOT USED
30 = U                         (WOULD BE COMMODORE LOGO)
31 = V                       62 = Q
32 = 9                       63 = RUN/STOP
33 = I                       64 = NO KEY PRESSED

The RESTORE key is not accounted for, because it is not part of the normal
keyboard matrix.  Instead, it is connected directly to the microprocessor NMI
line, and causes an NMI interrupt whenever it is pressed.

204           $CC            BLNSW
Cursor Blink Enable: 0=Flash Cursor

When this flag is set to a nonzero value, it indicates to the routine that
normally flashes the cursor not to do so.  The cursor blink is turned off
when there are characters in the keyboard buffer, or when the program is
running.
  You can use this location to turn the cursor on during a program (for a
series of GET operations, for example, to show the user that input is
expected) by using the statement POKE 204,0.

205           $CD            BLNCT
Timer: Countdown to Blink Cursor

The interrupt routine that blinks the cursor uses this location to tell when
it's time for a blink.  First the number 20 is put here, and every jiffy
(1/60 second) the value here is decreased by one, until it reaches zero.  Then
the cursor is blinked, the number 20 is put back here, and the cycle starts
all over again.  Thus, under normal circumstances, the cursor blinks three
times per second.

206           $CE            GDBLN
Character Under Cursor

The cursor is formed by printing the inverse of the character that occupies
the cursor position.  If that characters is the letter A, for example, the
flashing cursor merely alternates between printing an A and a reverse-A.  This
location keeps track of the normal screen code of the character that is
located at the cursor position, so that it may be restored when the cursor
moves on.

207           $CF            BLNON
Flag: Was Last Curson Blink on or off?

This location keeps track of whether, during the current cursor blink, the
character under the cursor was reversed, or was restored to normal.  This
location will contain a 0 if the character is reversed, and a 1 if the
character is restored to its nonreversed status.

208           $D0            CRSW
Flag: Input from Keyboard or Screen

This flag is used by the Kernal CHRIN (61783, $F157) routine to indicate
whether input is available from the screen (3), or whether a new line should
be obtained from the keyboard (0).

209-210       $D1-$D2        PNT
Pointer to the Address of the Current Screen Line

This location points to the address in screen RAM of the first column of the
logical line upon which the cursor is currently positioned.

211           $D3            PNTR
Cursor Column on Current Line

The number contained here is the cursor column position within the logical
line pointed to by 209 ($D1).  Since a logical line can contain up to two
physical lines, this value may be from 0 to 79 (the number here is the value
returned by the POS function).

212           $D4            QTSW
Flag: Editor in Quote Mode? 0=No

A nonzero value in this location indicates that the editor is in quote mode.
Quote mode is toggled every time that you type in a quotation mark on a given
line--the first quote mark turns it on, the second turns it off, the third
turns it back on, etc.
  If the editor is in this mode when a cursor control character or other
nonprinting character is entered, a printed equivalent will appear on the
screen instead of the cursor movement or other control operation taking place.
Instead, that action is deferred until the string is sent to the string by a
PRINT statement, at which time the cursor movement or other control operation
will take place.
  The exception to this rule is the DELETE key, which will function normally
within quote mode.  The only way to print a character which is equivalent to
the DELETE key is by entering insert mode (see loctaion 216 ($D8)).  Quote
mode may be exited by printing a closing quote, or by hitting the RETURN or
SHIFT-RETURN keys.
  Sometimes, it would be handy to be able to escape from quote mode or insert
mode without skipping to a new line.  The machine language program below hooks
into the keyscan interrupt routine, and allows you to escape quote mode by
changing this flag to 0 when you press the f1 key:

10 FOR I=850 TO I+41:READ A:POKE I,A:NEXT
20 PRINTCHR$(147)"PRESS F1 KEY TO ESCAPE QUOTE MODE"
30 PRINT"TO RESTART AFTER RESTORE ONLY, SYS 850":SYS850:NEW
40 DATA  173 , 143 , 2 , 141 , 46 , 3 , 173 , 144 , 2 , 141
50 DATA 47 , 3 , 120 , 169 , 107 , 141 , 143 , 2 , 169 , 3
60 DATA 141 , 144 , 2 , 88 , 96 , 165 , 203 , 201 , 4 , 208
70 DATA 8 , 169 , 0 , 133 , 212 , 133 , 216 , 133 , 199 , 108 , 46 , 3

213           $D5            LNMX
Maximum Length of Physical Screen Line

The line editor uses this location when the end of a line has been reached to
determine whether another physical line can be added to the current logical
line, or if a new logical line must be started.

214           $D6            TBLX
Current Cursor Physical Line Number

This location contains the current physical screen line position of the cursor
(0-24).  It can be used in a fashion to move the cursor vertically, by POKEing
the target screen line (1-25) minus 1 here, followed by a PRINT command.  For
example,

POKE 214,9:PRINT:PRINT "WE'RE ON LINE ELEVEN"

prints the message on line 11.  The first PRINT statement allows the system to
update the other screen editor variables so that they will also show the new
line.  The cursor can also be set or read using the Kernal PLOT routine
(58634, $E50A) as explained in the entry from locations 780-783 ($30C-$30F).

215           $D7
Temporary Storage Area for ASCII Value of Last Character Printed

The ASCII value of the last character printed to the screen is held here
temporarily.

216           $D8            INSRT
Flag: Insert Mode (Any Number Greater Than 0 Is the Number of Inserts)

When the INST key is pressed, the screen editor shifts the line to the right,
allocates another physical line to the logical line if necessary (and
possible), updates the screen line length in 213 ($D5), and adjusts the screen
line link table at 217 ($D9).  This location is used to keep track of the
number of spaces that has been opened up in this way.
  Until the spaces that have been opened up are filled, the editor acts as if
in quote mode (see location 212 ($D4), the quote mode flag).  This means that
cursor control characters that are normally nonprinting will leave a printed
equivalent on the screen when entered, instead of having their normal effect
on cursor movement, etc.  The only difference between insert and quote mode is
that the DELETE key will leave a printed equivalent in insert mode, while the
INST key will insert spaces as normal.

217-242       $D9-$F2        LDTB1
Screen Line Link Table/Editor Temporary Storage

This table contains 25 entries, one for each row of the screen display.  Each
entry has two functions.  Bits 0-3 indicate on which of the four pages of
screen memory  the first byte of memory for that row is located.  This is used
in calculating the pointer to the starting address of a screen line at 209
($D1).
  While earlier PETs used one table for the low bytes of screen rows and
another for the high bytes, this is not possible on the 64, where screen
memory is not fixed in any one spot.  Therefore, the Operating System uses a
table of low bytes at 60656 ($ECF0), but calculates the high byte by adding
the value of the starting page of screen memory held in 648 ($288) to the
displacement page held here.
  The other function of this table is to establish the makeup of logical lines
on the screen.  While each screen line is only 40 characters long, BASIC
allows the entry of program lines that contain up to 80 characters.
Therefore, some method must be used to determine which pairs of physical lines
are linked into a longer logical line, so that this longer logical line may
be edited as a unit.
  The high bit of each byte here is used as a flag by the screen editor.  That
bit is set (leaving the value of the byte over 128 ($80)) when a line is the
first or only physical line in a logical line.  The high bit is reset to 0
only when a line is the second half of a logical line.

243-244       $F3-$F4        USER
Pointer to the Address of the Current Screen Color RAM Location

This poitner is synchronized with the pointer to the address of the first
byte of screen RAM for the current line kept in location 209 ($D1).  It holds
the address of the first byte of color RAM for the corresponding screen line.

245-246       $F5-$F6        KEYTAB
Vector: Keyboard Decode Table

KEYTAB points to the address of the keyboard matrix lookup table currently
being used.  Although there are only 64 keys on the keyboard matrix, each key
can be used to print up to four different characters, depending on whether it
is struck by itself or in combination with the SHIFT, CTRL, or Commodore logo
keys.
  The tables pointed to y this address hold the ASCII value of each of the 64
keys for one of these possible combinations of keypresses.  When it comes time
to print the character, the table that is used determines which character is
printed.
  The addresses of the four tables are:

60289 ($EB81) = default uppercase/graphics characters (unshifted)
60354 ($EBC2) = shifted characters
60419 ($EC03) = Commodore logo key characters
60536 ($EC78) = CTRL characters

  The concept of the keyboard matrix tables should not be confused with
changing the character sets from uppercase/graphics to upper/lowercase.  The
former involves determining what character is to be placed into screen memory,
while the latter involves determining which character data table is to be used
to decode the screen memory into individual dots for the display of characters
on the screen.  That character base is determined by location 53272 ($D018) of
the VIC-II chip.

247-248       $F7-$F8        RIBUF
Pointer: RS-232 Input Buffer

When device number 2 (the RS-232 channel) is opened, two buffers of 256 bytes
each are created at the top of memory.  This location points to the address of
the one which is used to store characters as they are received.  A BASIC
program should always OPEN device 2 before assigning any variables to avoid
the consequences of overwriting variables which were previously located at the
top of memory, as BASIC executes a CLR after opening this device.

249-250       $F9-$FA        ROBUF
Pointer: RS-232 Output Buffer

This location points to the address of the 256-byte output buffer which is
used for transmitting data to RS-232 devices (device number 2)l

251-254       $FB-$FE        FREEZP
Four Free Bytes of Zero Page for User Programs

These locations were specifically set aside for user-written ML routines that
require zero-page addressing.  While other zero-page locations can be used on
a noninterference basis, it is guaranteed that BASIC will not alter these
locations.

255           $FF            BASZPT
BASIC Temporary Data for Floating Point to ASCII Conversion

This location is used for temporary storage in the process of converting
floating point numbers to ASCII characters..


:::::::::::::
::Chapter 2::
::         ::
:: Page 1  ::
:::::::::::::

256-511       $100-$1FF
Microprocessor Stack Area

Locations 256-511 are reserved for the 6510 microprocessor hardware stack.
The organization of this temporary storage area has often been compared to
that of a push-down stack of trays at a cafeteria.  The first number placed on
the stack goes to the bottom, and subsequent entries are placed on top of it.
Then you pull a number off the stack, you come up with the last number that
was pushed on (such a stack is called a Last In, First Out, or LIFO stack).
  The stack is controlled by one of the microprocessor registers called the
Stack Pointer, which keeps track of the last stack location used.  The first
number placed on the stack goes to location 511 ($1FF), and subsequent entries
are built downward toward 256 ($100).  If more than 256 numbers are pushed
onto the stack, the Stack Pointer will start counting from 0 again, and an
overflow error will result.  Likewise, if you try to pull more items off the
stack than have been pushed on, an underflow error will result.  Most often,
such errors will cause the system to go haywire, and nothing will operate
until you turn the power off and on again.
  The stack is used by the system to keep track of the return addresses of
machine language subroutines and interrupt calls and to save the contents of
internal registers.  The stack can also be used by the programmer for
temporary storage.  BASIC and the Kernal make heavy use of the stack.
  Microsoft BASIC uses part of the stack for a temporary work area.
Therefore, the stack may be broken down into the following subregions:

256-266       $100-$10A
Work Area for Floating Point to String Conversions

Used in the conversion of numbers to the equivalent ASCII digits, and in
scanning strings.

256-318       $100-$13E      BAD
Tape Input Error Log

Each tape block is saved twice consecutively, in order to minimize loss of
data from transmission errors.  These 62 bytes serve as indices of which bytes
in the tape block were not received corectly during the first transmission, so
that corrections might be made on the second pass.

319-511       $13F-$1FF

This area is exclusively for the microprocessor stack.  Some BASIC commands,
such as FOR-NEXT loops require many stack entries at a time.  Therefore, BASIC
frequently checks the stack before pushing entries on, and returns an OUT OF
MEMORY error if an operation would result in less than 62 bytes of available
stack memory.
  Each FOR statement causes 18 bytes to be pushed onto the stack, which come
off in the following order:
  First comes a one-byte constant of 129 ($81).  Next is a two-byte pointer to
the address of the subject variable (the X of FOR X=1 to 10).  This is
followed by the five-byte floating point representation of the TO value.
Finally comes the two-byte line number of the line to which the program
returns after a NEXT, and the two-byte address of the next character to read
in that line after the FOR statement.
  Each GOSUB call places five bytes on the stack.  The first byte to come off
is a one-byte constant of 141 ($8D).  The next two bytes contain the line
number of the statement to which the program will RETURN after the subroutine
ends.  And the final two bytes are a pointer to the address of the BASIC
program text for that statement in which the program RETURNs.
  DEF also leaves a five-byte entry on the stack.  It is the same as that
described for GOSUB, except that instead of a constant byte of 141, the first
number is a dummy byte, whose value has no significance.


::::::::::::::::::::::::
::     Chapter 3      ::
::                    ::
::   Pages 2 and 3    ::
::                    ::
::BASIC and the Kernal::
::  Working Storage   ::
::::::::::::::::::::::::

This area is used to store important information for the Operating System and
BASIC.  It contains vectors to certain BASIC routines as well as Operating
System Kernal routines.  Registers for RS-232 serial I/O are located here.
Buffer space is allocated in this area for tape I/O, BASIC text input, and the
keyboard queue.  In addition, there are a number of Operating System variables
and pointers here which the programmer can utilize.

512-600       $200-$258      BUF
BASIC Line Editor Input Buffer

When you are in the BASIC immediate mode, and type in a line of characters,
those characters are stored here.  BASIC then scans the string of characters,
converts the text to tokenized BASIC program format, and either stores it or
executes the line, depending on whether or not it started with a line number.
  This same area is also used to store data which is received via the INPUT
and GET commands.  This explains why these commands are illegal in immediate
mode--they must use the same buffer space that is required by the immediate
mode statement itself.
  It is interesting to note that this buffer is 89 bytes long.  The screen
editor will allow a maximum of only 80 characters in a program line, with one
extra byte required for a 0 character, marking the end of the line.  This
presumable is a carry over from the VIC, which allows a line length of up to
88 characters.  The last eight bytes of this buffer are therefore normally not
used, and can be considered free space for the programmer to use as he or she
sees fit.

Location Range: 601-630 ($259-$276)
Tables for File Numbers, Device Numbers, and Secondary Addresses

All three of the tables here have room for ten one-byte entries, each of which
represents an active Input/Output file.  When an I/O file is opened, its
logical file number is put into the table at 601 ($259), the device number of
the I/O device is put into the table at 611 ($263), and its secondary address
is put into the table at 621 ($26D).
  The entry for any particular I/O file will occupy the same position in each
of the three tables.  That is, if logical file number 2 is the third entry in
the file number table, its secondary address will be the third entry in the
secondary address table, and its corresponding device number will occupy the
third spot in the device number table.
  Every time a device is OPENed, its information is added as the last entry
in each table, and the value at location 152 ($98) is increased by one,
indicating that there is one more active I/O file.  When a device is CLOSEd,
the value at location 152 is decreased by one, and all entries that occupy a
position in the tables that is higher than that of the closed device are
moved down one position, thus eliminating the entry for that device.  The
Kernal CLALL routine (62255, $F32F) simply zeros location 152, which has the
effect of emptying these tables.

601-610       $259-$262      LAT
Kernal Table of Active Logical File Numbers

611-620       $263-$26C      FAT
Kernal Table of Device Numbers for Each Logical File

621-630       $26D-$276      SAT
Kernal Table of Secondary Addresses for Each Logical File

631-640       $277-$280      KEYD
Keyboard Buffer (Queue)

This buffer, sometimes also referred to as the keyboard queue, holds the ASCII
values of the characters entered from the keyboard.  The interrupt routine
which scans the keyboard deposits a character here each time a key is pressed.
When BASIC sees that there are characters waiting, it removes and prints them,
one by one, in the order in which they were entered.
  This kind of a buffer is known as FIFO, for First In, First Out.  The buffer
will hold up to ten characters, allowing you to type faster than the computer
prints characters, without losing characters.  The maximum number of
characters this buffer can hold at one time is ten (as determined by the value
at 649 ($289)).  Characters entered after the buffer is full will be ignored.
  The commands GET and INPUT retrieve characters from this buffer.  If one of
these is executed while there are already characters waiting in the buffer,
those characters will be fetched as if they were part of the data being input.
To prevent this from happening, you can clear the buffer by POKEing a 0 into
location 198 ($C6), which holds the number of characters that are waiting in
the buffer.
  One of the most interesting and useful techniques for programming Commodore
computers is to have a program simulate direct entry of commands from the
keyboard.  This dynamic keyboard trick is achieved by first POKEing PETASCII
characters, usually cursor movement characters and carriage returns, into the
buffer, and setting location 198 ($C6) to show how many characters are
waiting in the buffer.
  Next, you clear the screen, and PRINT the statements that you wish to have
executed on the screen, carefully positioning them so that the first statement
to be entered is on the fourth line of the screen.
  You then home the cursor and execute an END statement.  This causes the
keyboard buffer to be read, and the carriage returns to be executed, thus
entering the printed lines as if they had been typed in immediate or direct
mode.  The program can be continued by including a GOTO statement in the last
line entered.
  Many interesting effects can be achieved using this method.  Examples of
a few of these are included below.  For example, program lines can be added,
modified, or deleted, while the program is running.  The following example
shows how this is done:

10 REM THIS LINE WILL BE DELETED
20 REM A NEW LINE 30 WILL BE CREATED
40 PRINT CHR$(147):PRINT:PRINT
50 PRINT "80 LIST":PRINT"30 REM THIS LINE WASN'T HERE BEFORE"
60 PRINT "10":PRINT "GOTO 80"CHR$(19)
70 FOR I=631 TO 634:POKE I,13:NEXT:POKE 198,4:END
80 REM THIS LINE WILL BE REPLACED

You can use this technique to enter numbered DATA statements automatically,
using values in memory.  These statements become a permanent part of the
program.
  Another interesting application is taking ASCII program lines from a tape
data file, or sequential disk file, and having them entered automatically.
This can be used for merging programs, or for transferring programs between
computers with a modem and a terminal program.  To create the ASCII program
file, you use CMD to direct a LISTing to the desired device as follows:

For tape: OPEN 1,1,1,"ASCII":CMD 1:LIST
After the listing has ended: PRINT #1:CLOSE 1

For disk: OPEN 8,8,8,"ASCII,S,W":CMD 8:LIST
After the listing has ended: PRINT #8:CLOSE 8

This file can then be uploaded using a modem and appropriate terminal
software, entered by itself or merged with another program by using the
following program.  Be sure to save this program before you run it, because it
will erase itself when it is done.

60000 OPEN 1,8,8,"ASCII"
60010 POKE 152,1:B=0:GOSUB 60170
60020 GET #1,A$:IF A$=""THEN60020
60030 IF ST AND 64 THEN 60120
60040 IF A$=CHR$(13)AND B=0THEN60020
60050 PRINT A$;:B=1:IF A$=CHR$(34)THEN POKE 212,0
60060 IF A$<>CHR$(13) THEN 60020
60070 PRINT CHR$(5);"GOTO 60010";CHR$(5):PRINT:PRINT:POKE 198,0
60080 PRINT "RETURN=KEEP LINE    S=SKIP LINE":B=0
60090 GET A$:IF A$=""THEN 60090
60100 IF A$="S" THEN 60010
60110 GOTO 60180
60120 PRINT "END OF FILE--HIT RETURN TO FINISH MERGE"
60130 IF PEEK(197)<>1THEN60130
60140 A=60000
60150 GOSUB 60170:FOR I=A TO A+60 STEP10:PRINTI:NEXT
60160 PRINT "A="I":GOTO 60150":GOTO 60180
60170 PRINT CHR$(147):PRINT:PRINT:RETURN
60180 FOR I=631TO640:POKEI,13:NEXT:POKE198,10:PRINTCHR$(19);:END

If you wish to merge additional programs at the same time, when it indicates
that the file has ended, press the STOP key rather than RETURN, enter the
name of the new file in line 60000, and RUN 60000

641-642       $281-282       MEMSTR
Pointer: O.S. Start of Memory

When the power is first turned on, or a cold start RESET is performed, the
Kernal routine RAMTAS (64848, $FD50) sets this location to point to address
2048 ($800).  This indicates that this is the starting address of user RAM.
BASIC uses this location to set its own start of memory pointer at location 43
($2B), and thereafter uses only its own pointer.
  The Kernal routine MEMBOT (65076, $FE34) may be used to read or set this
pointer, or these locations may be directly PEEKed or POKEd from BASIC.

643-644       $283-284       MEMSIZ
Pointer: O.S. End of Memory

When the power is first turned on, or a cold start RESET is performed, the
Kernal routine RAMTAS (64848, $FD50) performs a nondestructive test of RAM
from 1024 ($400) up, stopping when the test fails, indicating the presence of
ROM.  This will normally occur at 40960 ($A000), the location of the BASIC
ROM.  The top of user RAM pointer is then set to point to that first ROM
location.
  After BASIC has been started, the system will alter this location only when
an RS-232 channel (device number 2) is OPENed or CLOSEd.  As 512 bytes of
memory are required for the RS-232 transmission and reception buffers, this
pointer, as well as the end of BASIC pointer at 55 ($37), is lowered to create
room for those buffers when the device is opened.  CLOSing the device resets
these pointers.
  The Kernal routine MEMTOP (65061, $FE25) may be used to read or set this
pointer.

645           $285           TIMOUT
Flag: Kernal Variable for IEEE Time-Out

This location is used only with the external IEEE interface card (which was
not yet available from Commodore at the time of writing).  For more
information, see the entry for the Kernal SETTMO routine at 65057 ($FE21).

646           $286           COLOR
Current Foreground Color for Text

The process of PRINTing a character to the screen consists of both placing the
screen code value for the character in screen memory and placing a foreground
color value in the corresponding location in color RAM.  Whenever a character
is PRINTed, the Operating System fetches the value to be put in color RAM from
this location.
  The foreground color may be changed in a number of ways.  Pressing the CTRL
or Commodore logo key and numbers 1-8 at the same time will change the value
stored here, and thus the color being printed.  PRINTing the PETASCII
equivalent character with the CHR$ command will have the same effect.  But
probably the easiest method is to POKE the color value directly to this
location.  The table below lists the possible colors that may be produced, and
shows how to produce them using all three methods.

POKE
COLOR #   COLOR     CHR$   KEYS TO PRESS
 0        Black     144    CTRL-1
 1        White       5    CTRL-2
 2        Red        28    CTRL-3
 3        Cyan      159    CTRL-4
 4        Purple    156    CTRL-5
 5        Green      30    CTRL-6
 6        Blue       31    CTRL-7
 7        Yellow    158    CTRL-8
 8        Orange    129    Logo-1
 9        Brown     149    Logo-2
10        Lt Red    150    Logo-3
11        Dark Gray 151    Logo-4
12        Med Gray  152    Logo-5
13        Lt Green  153    Logo-6
14        Lt Blue   154    Logo-7
15        Lt Gray   155    Logo-8

647           $287           GDCOL
Color of Character under Cursor

This location is used to keep track of the original color code of the
character stored at the present cursor location.  Since the blinking cursor
uses the current foreground color at 646 ($286), the original value must be
stored here so that if the cursor moves on without changing that character,
its color code can be restored to its original value.

648           $288           HIBASE
Top Page of Screen Memory

This location contains the value used by the Operating System routines that
print to the screen as the base address for screen RAM.  The top of screen
memory can be found by multiplying this location by 256.  The default value
for screen RAM is set on power-up to location 1024 ($400), and this location
therefore usually contains a 4.
  Screen display memory on the Commodore 64 can be moved to start on any 1K
boundary (location evenly divisible by 1024).  This is done by manipulating
the VIC-II chip memory bank select at location 56576 ($DD00).
  It is important to note, however, that while any area may be displayed, the
Operating System will look here to find out where it should PRINT characters.
Therefore, if you change the screen location by altering the contents of one
of the two addresses listed above, the Operating System will still not know
where to PRINT characters unless you also change this address as well.  The
result will be that characters entered from the keyboard or PRINTed will not
appear on the screen.
  Examples of how to properly relocate the screen can be found at the entries
for location 53272 ($D018) and 43 ($2B).
  Since the PRINT command in essence just POKEs a lot of values to screen and
color memory, by changing this pointer you can print a string of characters to
memory locations other than screen RAM.  For example, you could PRINT a sprite
shape to memory without having to READ a lot of DATA statements.  The program
below PRINTs different sprite shapes into the sprite data area:

10 SP=53248:POKESP,170:POKESP+1,125:POKESP+21,1:POKE 2040,13:PRINT CHR$(147)
20 A$="THIS TEXT WILL BE PRINTED TO THE SPRITE SHAPE DATA AREA AND DISPLAYED"
30 GOSUB 100
40 A$="THIS IS SOME DIFFERENT TEXT TO BE PRINTED TO THE SPRITE SHAPE AREA"
50 GOSUB 100
60 COUNT=COUNT+1:IF COUNT<15 THEN 20
70 END
100 POKE 648,3:PRINT CHR$(19);CHR$(17);SPC$(24);A$;:POKE 648,4:RETURN

Since PRINTing also changes color memory, you can change the pointer to print
the characters harmlessly to ROM, while changing a lot of screen RAM at one
time, as the following program demonstrates:

10 D$=CHR(94):FOR I=1 TO 4:D$=D$+D$:NEXT
20 PRINT CHR$(147);:FOR I=1 TO 7:PRINT TAB(10) D$:NEXT:PRINT:PRINT:PRINT:PRINT
30 PRINT TAB(9);CHR$(5);"HIT ANY KEY TO STOP"
40 DIM C(15):FOR I=0TO14:READ A:C(I)=A:NEXT:DATA2,8,7,5,6,4,1,2,8,7,5,6,4,1,2
50 POKE 53281,0:POKE 648,212:FOR J=0 TO 6:PRINT CHR$(19);
60 FOR I=J TO J+6:POKE 646,C(I):PRINT TAB(10) D$:NEXT I,J
70 GET A$:IF A$="" THEN 50
80 POKE 648,4:POKE 646,1

649           $289           XMAX
Maximum Keyboard Buffer Size

The value here indicates the maximum number of characters that the keyboard
buffer at 631 ($277) may hold at any one time.  Anytime that the current
buffer length in location 198 ($C6) matches the value here, further keypresses
will be ignored.
  Although the maximum size of the keyboard buffer is usually 10 characters,
it may be possible to extend it up to 15 characters by changing the number
here.  This could cause the Operating System pointers to the bottom and top of
memory at 641-644 ($281-$284) to be overwritten, but no real harm should
result.

650           $28A           RPTFLAG
Flag: Which Keys Will Repeat?

The flag at this location is used to determine whether to continue printing a
character as long as its key is held down, or whether to wait until the key is
let up before allowing it to be printed again.  The default value here is 0,
which allows only the cursor movement keys, insert/delete key, and the space
bar to repeat.
  POKEing this location with 128 ($80) will make all keys repeating, while a
value of 64 ($40) will disable all keys from repeating.

651           $28B           KOUNT
Counter for Timing the Delay Between Key Repeats

This lcoation is used as a delay counter to determine how long to wait while
a key is being held down until the next repeat printing of that key.
  The value here starts at 6.  If location 652 ($28C) contains a 0, the value
in this location is counted down once every 1/60 second, so long as the same
key is held down.  When this counter gets to 0, and if the repeat flag at 650
($28A) allows that key to repeat, its ASCII equivalent will once again be
placed in the keyboard buffer.  A value of 4 is then placed in location 651,
allowing subsequent repeats to occur at a rate of 15 per second.

652           $28C           DELAY
Counter for Timing the Delay Until the First Key Repeat Begins

This location is used as a delay counter to determine how long a key must be
held down before the entry of that key should be repeated.
  The initial value of 16 is counted down every 1/60 second, as long as the
same key remains pressed.  When the value gets to 0, location 651 ($28B) is
counted down from 6, and the key is repeated when the value there reaches 0.
Thus a total of 22/60, or approximately 1/3, second will elapse before the
first repeat of a key.  The value here will be held to 0 after the first
repeat, so that subsequent keystroke repititions occur much more quickly.

653           $28D           SHFLAG
Flag: SHIFT/CTRL/Logo Keypress

This flag signals which of the SHIFT, CTRL, or Commodore logo keys are
currently being pressed, if any.
  A value of 1 signifies that one of the SHIFT keys is being pressed, a 2
shows that the Commodore logo key is down, and 4 means that the CTRL key is
being pressed.  If more than one key is held down, these values will be added;
for example, a 3 indicates that SHIFT and logo are both held down.
  The value here is used by the Operating System when determining how to
convert a keypress into a PETASCII character.  There are four different tables
used to translate one of the 64 keys on the keyboard matrix into a PETASCII
character, and the combination of special SHIFT keys determines which of these
tables will be used (see the entry for location 245 ($F5) for more details on
the keyboard tables).
  Pressing the SHIFT and Commodore logo keys at the same time will toggle the
character set that is presently being used between the uppercase/graphics set,
and the lowercase/uppercase set (provided that the flag at 657 ($291) has not
been set to disable this switch).
This changes the appearance of all of the characters on the screen at once.
It has nothing whatever to do with the keyboard shift tables, however, and
should not be confused with the printing of SHIFTed characters, which affects
only one character at a time.  Rather, it is the result of the value of the
character dot data table base address in 53272 ($D018) being changed.  The
came result may be obtained by POKEing that address directly.

654           $28E           LSTSHF
Last Pattrn of SHIFT/CTRL/Logo Keypress

This location is used in combination with the one above to debounce the
special SHIFT keys.  This will keep the SHIFT/logo combination from changing
character sets back and forth during a single pressing of both keys.

655-656       $28F-$290      KEYLOG
Vector to Keyboard Table Setup Routine

This location points to the address of the Operating System routine which
actually determines which keyboard matrix lookup table will be used.
  The routine looks at the value of the SHIFT flag at 653 ($28D), and based on
what value it finds there, stores the address of the correct table to use at
location 245 ($F5).
  The interrupt driven keyboard-scanning routine jumps through this RAM vector
to get to the table setup routine.  Therefore, it is possible to alter the
address contained in this vector, and direct the keyscan routine to your own
routine, which can check the keypress and SHIFT combination, and act before a
character is printed.
  Since this routine comes after the keypress, but before it is printed, this
is a very good place to have your preprocessor routine check for a particular
keypress.  An excellent example of such a program is the "VICword" program by
Mark Niggemann, COMPUTE!'s Second Book of VIC.  This program adds a machine
language routine that checks if the SHIFT or Commodore logo key is pressed
while not in quote mode.  If it finds one of these keypresses, it substitutes
an entire BASIC keyword for the letter (A-Z) of the key that was pressed.  An
adaptation of that program for the 64 appears below.

100 IF PEEK(PEEK(56)*256)<>120THENPOKE56,PEEK(56)-1:CLR
110 HI=PEEK(56):BASE=HI*256
120 PRINTCHR$(147)"READING DATA"
130 FOR AD=0 TO 211:READ BY
140 POKE BASE+AD,BY:NEXT AD
150 :
200 REM RELOCATION ADJUSTMENTS
210 POKE BASE+26,HI:POKE BASE+81,HI
220 POKE BASE+123,HI:POKE BASE+133,HI
230 :
240 PRINT CHR$(147) TAB(15)"***64WORD***":PRINT
250 PRINT"TO TOGGLE THE PROGRAM ON/OFF:":PRINT:PRINT:PRINT "SYS";BASE;
260 PRINT CHR$(145);CHR$(145);
270 DATA 120,173,143,2,201,32
280 DATA 208,12,169,220,141,143
290 DATA 2,169,72,141,144,2
300 DATA 88,96,169,32,141,143
310 DATA 2,169,0,141,144,2
320 DATA 88,96,165,212,208,117
330 DATA 173,141,2,201,3,176
340 DATA 110,201,0,240,106,169
350 DATA 194,133,245,169,235,133
360 DATA 246,165,215,201,193,144
370 DATA 95,201,219,176,91,56
380 DATA 233,193,174,141,2,224
390 DATA 2,208,3,24,105,26
400 DATA 170,189,159,0,162,0
410 DATA 134,198,170,160,158,132
420 DATA 34,160,160,132,35,160
430 DATA 0,10,240,16,202,16
440 DATA 12,230,34,208,2,230
450 DATA 35,177,34,16,246,48
460 DATA 241,200,177,34,48,17
470 DATA 8,142,211,0,230,198
480 DATA 166,198,157,119,2,174
490 DATA 211,0,40,208,234,230
500 DATA 198,166,198,41,127,157
510 DATA 199,2,230,198,169,20
520 DATA 141,119,2,76,72,235
530 DATA 76,224,234
550 REM TOKENS FOR SHIFT KEY
570 DATA 153,175,199,135,161,129
580 DATA 141,164,133,137,134,147
590 DATA 202,181,159,151,163,201
600 DATA 196,139,192,149,150,155
610 DATA 191,138
630 REM TOKENS FOR COMMODORE KEY
650 DATA 152,165,198,131,128,130
660 DATA 142,169,132,145,140,148
670 DATA 195,187,160,194,166,200
680 DATA 197,167,186,157,165,184
690 DATA 190,158,0

Commodore 64word: Keys into BASIC Commands

Key   SHIFT   Commodore
A     PRINT   PRINT#
B     AND     OR
C     CHR$    ASC
D     READ    DATA
E     GET     END
F     FOR     NEXT
G     GOSUB   RETURN
H     TO      STEP
I     INPUT   INPUT#
J     GOTO    ON
K     DIM     RESTORE
L     LOAD    SAVE
M     MID$    LEN
N     INT     RND
O     OPEN    CLOSE
P     POKE    PEEK
Q     TAB(    SPC(
R     RIGHT$  LEFT$
S     STR$    VAL
T     IF      THEN
U     TAN     SQR
V     VERIFY  CMD
W     DEF     FN
X     LIST    FRE
Y     SIN     COS
Z     RUN     SYS

657           $291           MODE
Flag: Enable or Disable Changing Character Sets with SHIFT/Logo Keypress

This flag is used to enable or disable the feature which lets you switch
between the uppercase/graphics and upper/lowercase character sets by pressing
the SHIFT and Commodore logo keys simultaneously.
  This flag affects only this special SHIFT key function, and does not affect
the printing of SHIFTed characters.  POKEing a value of 128 ($80) here will
disable this feature, while POKEing a value of 0 will enable it once more.
The same effect can be achieved by PRINTing CHR$(8) or CTRL-H to disable the
switching of character sets, and CHR$(9) or CTRL-I to enable it.  See entries
for locations 53272 ($D018) and 49152 ($C000) for more information on
switching character sets.

658           $292           AUTODN
Flag: Screen Scrolling Enabled

This location is used to determine whether moving the cursor past the fortieth
column of a logical line will cause another physical line to be added to the
logical line.
  A value of 0 enables the screen to scroll the following lines down in order
to add that line; any nonzero value will disable the scroll.  This flag is set
to disable the scroll temporarily when there are characters waiting in the
keyboard buffer (these may include cursor movement characters that would
eliminate the need for a scroll).

Location Range: 659-663 ($293-$297)
RS-232 Pseudo 6551 Registers

For serial Input/Output via the RS-232 port, the internal software of the
Commodore 64 emulates the operation of a 6551 UART chip (that's Universal
Asynchronous Receiver/Transmitter, for you acronym buffs), also known as an
ACIA (Asynchronous Communications Interface Adapter).
  These RAM locations are used to mimic the functions of that chip's hardware
command, control, and status registers.  Although RAM locations are allocated
for mimicking the 6551's ability to use either an on-board baud rate generator
or an external clock crystal, this function is not implemented by the internal
software.
  Provisions have been made for the user to communicate with these registers
through the RS-232 OPEN command.  When device 2 is opened, a filename of up to
four characters may be appended.  These four characters are copied to
locations 659-662 ($293-$296), although the last two, which specify a
nonstandard baud rate, are not used because that feature is not implemented.

659           $293           M51CTR
RS-232: Mock 6551 Control Register

This location is used to control the RS-232 serial I/O baud rate (speed at
which data is transmitted and received), the word length (number of bits per
data character), and the number of stop bits used to mark the end of a
transmitted character.  It uses the same format as that of the 6551 UART
control register to set these parameters, although, as you will see, some of
the 6551 configurations are not implemented by the software that emulates the
UART device.  For example, the standard baud rates which are higher than 2400
baud are not implemented, presumably because the software cannot keep up at
higher rates.  The meanings of the various bit patterns are as follows:

Bit 7: STOP Bits
0    (bit value of 0)   = 1 STOP Bit
1    (bit value of 128) = 0 STOP Bits

Bits 6-5: WORD LENGTH
00   (bit value of 0)   = 8 DATA Bits
01   (bit value of 32)  = 7 DATA Bits
10   (bit value of 64)  = 6 DATA Bits
11   (bit value of 96)  = 5 DATA Bits

Bit 4: Unused

Bits 3-0: BAUD RATE
0000 (bit value of 0)   = Nonstandard (User-Defined) Rate (Not Implemented)
0001 (bit value of 1)   = 50 Baud
0010 (bit value of 2)   = 75 Baud
0011 (bit value of 3)   = 110 Baud
0100 (bit value of 4)   = 134.5 Baud
0101 (bit value of 5)   = 150 Baud
0110 (bit value of 6)   = 300 Baud
0111 (bit value of 7)   = 600 Baud
1000 (bit value of 8)   = 1200 Baud
1001 (bit value of 9)   = 1800 Baud
1010 (bit value of 10)  = 2400 Baud
1011 (bit value of 11)  = 3600 Baud (Not Implemented on the Commodore 64)
1100 (bit value of 12)  = 4800 Baud (Not Implemented on the Commodore 64)
1101 (bit value of 13)  = 7200 Baud (Not Implemented on the Commodore 64)
1110 (bit value of 14)  = 9600 Baud (Not Implemented on the Commodore 64)
1111 (bit value of 15)  = 19200 Baud (Not Implemented on the Commodore 64)

This register is the only one which must be set when opening RS-232 device
(number 2).  The first character of the filename will be stored here.  For
example, the statement OPEN 2,2,0,CHR$(6+32) will set the value of this
location to 38.  As you can see from the above chart, this sets up the RS-232
device for a data transfer rate of 300 baud, using seven data bits per
character and one stop bit.

660           $294           M51CDR
RS-232: Mock 6551 Command Register

This location performs the same function as the 6551 UART chip's command
register, which specifies type of parity, duplex mode, and handshaking
protocol.
  The type of parity used determines how the 64 will check that RS-232 data
is received correctly.
  The duplex mode can be either full duplex (the 64 will be able to transmit
at the same time it is receiving) or half duplex (it will take turns sending
and receiving).
  The handshaking protocol has to do with the manner in which the sending
device lets the receiver know that it is ready to send data, and the receiver
lets the sender know that it has gotten the data correctly.  The meanings of
the bit patterns in this register are as follows:

Bits 7-5: Parity
XX0 (bit value of
     0,64,128, or 192) = No Parity Generated or Received
001 (bit value of 32)  = Odd Parity Transmitted and Received
011 (bit value of 96)  = Even Parity Transmitted and Received
101 (bit value of 160) = Mark Parity Transmitted and Received
111 (bit value of 224) = Space Parity Transmitted and Received

Bit 4: Duplex
0 (bit value of 0)  = Full Duplex
1 (bit value of 16) = Half Duplex

Bits 3-1: Unused

Bit 0: Handshake Protocol
0 (bit value of 0) = 3 Line
1 (bit value of 1) = X Line

This register can be set at the user's option when opening RS-232 device
(number 2).  The second character of the filename will be stored here.  For
example, the statement

OPEN 2,2,0,CHR$(6+32)+CHR$(32+16)

will set the value of this location to 48, which is the value of the second
character in the filename portion of the statement.  As you can see from the
above chart, this configures the RS-232 device for half duplex data transfer
using odd parity and three-line handshaking.

661-662       $295-$296      M51AJB
RS-232: Nonstandard Bit Timing

These locations are provided for storing a nonstandard user-defined baud rate,
to be used when the low nybble of the control register at 659 ($293) is set to
0.  They were presumable provided to conform to the nodel of the 6551 UART
device, which allows a nonstandard baud rate to be generated from an external
reference crystal.  However, the software emulation of that feature is not
provided in the current version of the Kernal, and thus these locations are
currently nonfunctional.
  Nonetheless, Commodore has specified that if the nonstandard baud rate
feature is implemented, the value placed here should equal the system clock
frequency divided by the baud rate divided by 2 minus 100, stored in low byte,
high byte order.  The system clock frequency for American television monitors
(NTSC standard) is 1.02273 MHz, and for European monitors (PAL standard)
.98525 MHz.

663           $297           $RSSTAT
RS-232: Mock 6551 Status Register

The contents of this register indicate the error status of RS-232 data
transmission.  That status can be determined by PEEKing this location
directly, by referencing the BASIC reserved variable ST, or by using the
Kernal READST (65031, $FE07) routine.
  Note that if you use ST or Kernal, this location will be set to 0 after it
is read.  Therefore, if you need to test more than one bit, make sure that
each test preserves the original value, because you won't be able to read it
again.  The meaning of each bit value is specified below:

Bit 7: 1 (bit value of 128) = Break Detected
Bit 6: 1 (bit value of 64)  = DTR (Data Set Ready) Signal Missing
Bit 5: Unused
Bit 4: 1 (bit value of 16)  = CTS (Clear to Send) Signal Missing
Bit 3: 1 (bit value of 8)   = Receiver Buffer Empty
Bit 2: 1 (bit value of 4)   = Receiver Buffer Overrun
Bit 1: 1 (bit value of 2)   = Framing Error
Bit 0: 1 (bit value of 1)   = Parity Error

The user is responsible for checking these errors and taking appropriate
action.  If, for example, you find that Bit 0 or 1 is set when you are
sending, indicating a framing or parity error, you should resend the last
byte.  If Bit 2 is set, the GET#2 command is not being executed quickly
enough to empty the buffer (BASIC should be able to keep up at 300 baud, but
not higher).  If Bit 7 is set, you will want to stop sending, and execute a
GET#2 to see what is being sent.

664           $298           BITNUM
RS-232: Number of Bits Left to be Sent/Received

This location is used to determine how many zero bits must be added to the
data character to pad its length out to the word length specified in 659
($293).

665-666       $299-$29A      BAUDOF
Time Required to Send a Bit

This location holds the prescaler value used by CIA #2 timers A and B.
  These timers cause an NMI interrupt to drive the RS-232 receive and transmit
routines CLOCK/PRESCALER times per second each, where CLOCK is the system 02
frequency of 1,022,730 Hz (985,250 if you are using the European PAL
television standard rather than the American NTSC standard), and PRESCALER is
the value stored at 56580-1 ($DD04-5) and 56582-3 ($DD06-7), in low-byte,
high-byte order.  You can use the following formula to figure the correct
prescaler value for a particular RS-232 baud rate:

PRESCALER=((CLOCK/BAUDRATE)/2)-100

The American (NTSC standard) prescaler values for the standard RS-232 baud
rates which the control register at 659 ($293) makes available are stored in
a table at 65218 ($FEC2), starting with the two-byte value used for 50 baud.
The European (PAL standard) version of that table is located at 58604 ($E4EC).

Location Range: 667-670 ($29B-$29E)
Byte Indices to the Beginning and End of Receive and Transmit Buffers

The two 256-byte First In, First Out (FIFO) buffers for RS-232 data reception
and transmission are dynamic wraparound buffers.  This means that the starting
point and the ending point of the buffer can change over time, and either
point can be anywhere withing the buffer.  If, for example, the starting point
is at byte 100, the buffer will fill towards byte 255, at which point it will
wrap around to byte 0 again.  To maintain this system, the following four
locations are used as indices to the starting and the ending point of each
buffer.

667           $29B           RIDBE
RS-232: Index to End of Receive Buffer

This index points to the ending byte within the 256-byte RS-232 receive
buffer, and is used to add data to that buffer.

668           $29C           RIDBS
RS-232: Index to Start of Receive Buffer

This index points to the starting byte within the 256-byte RS-232 receive
buffer, and is used to remove data from that buffer.

669           $29D           RODBS
RS-232: Index to Start of Transmit Buffer

This index points to the starting byte within the 256-byte RS-232 transmit
buffer, and is used to remove data from that buffer.

670           $29E           RODBE
RS-232: Index to End of Transmit Buffer

This index points to the ending byte within the 256-byte RS-232 transmit
buffer, and is used to add data to that buffer.

671-672       $29F-$2A0      IRQTMP
SAve Area for IRQ Vector During Cassette I/O

The routines that read and write tape data are driven by an IRQ interrupt.  In
order to hook one of these routines into the interrupt, the RAM IRQ vector at
788-789 ($314-$315) must be changed to point to the address at which it
starts.  Before that change is made, the old IRQ vector address is saved at
these locations, so that after the tape I/O is finished, the interrupt that is
used for scanning the keyboard, checking the stop key, and updating the clock
can be restored.
  You will note that all of the above functions will be suspended during tape
I/O.

673           $2A1           ENABL
RS-232 Interrupts Enabled

This location holds the active NMI interrupt flag byte from CIA #2 Interrupt
Control Register (56589, $DD0D).  The bit values for this flag are as follows:

Bit 4: 1 (bit value of 16) = System is Waiting for Receiver Edge
Bit 1: 1 (bit value of 2)  = System is Receiving Data
Bit 0: 1 (bit value of 1)  = System is Transmitting Data

674           $2A2
Indicator of CIA #1 Control Register B Activity During Cassette I/O

675           $2A3
Save Area for CIA #1 Interrupt Control Register During Cassette Read

676           $2A4
Save Area for CIA #1 Control Register A During Cassette Read

677           $2A5
Temporary Index to the Next 40-Column Line for Screen Scrolling

678           $2A6
PAL/NTSC Flag

At power-on, a test is performed to see if the monitor uses the NTSC (North
American) or PAL (European) television standard.
  This test is accomplished by setting a raster interrupt for scan line 311,
and testing if the interrupt occurs.  Since NTSC monitors have only 262 raster
scan lines per screen, the interrupt will occur only if a PAL monitor is used.
The results of that test are stored here, with a 0 indicating an NTSC system
in use, and one signifying a PAL system.
  This information is used by the routines which set the prescaler values for
the system IRQ timer, so that the IRQ occurs every 1/60 second.  Since the PAL
system 02 clock runs a bit slower than the NTSC version, this prescaler value
must be adjusted accordingly.

679-767       $2A7-$2FF
Unused

The programmer may use this area for machine language subroutines, or for
graphics data storage.
  If the VIC-II ship is using the bottom 16K for graphics and memory (the
default setting when the system is turned on), this is one of the few free
areas available for storing sprite or character data.  Locaitons 704-767 could
be used for sprite data block number 11, without interfering with BASIC
program text or variables.

Location Range: 768-779 ($300-$30B)
BASIC Indirect Vector Table

Several important BASIC routines are vectored through RAM.  This means that
the first instruction executed by the routine is an indirect jump to a
location pointed to by one of the vectors in this table.
  On power up, the system sets these vectors to point to the next instruction
past the original JuMP instruction.  The routine then continues with that
instruction as if the jump never took place.  For example, the BASIC error
message routine starts at 42039 ($A437) with the instruction JMP ($300).  The
indirect vector at 768 ($300) points to 42042 ($A43A), which is the
instruction immediately following JMP ($300).
  Although this may seem like a fancy way of accomplishing nothing, using
these indirect vectors serves two important purposes.  First, it allows you
to use these important BASIC routines without knowing their addrses in the
BASIC ROM.
  For example, the routine to LIST the ASCII text of the single-byte BASIC
program token that is currently in the Accumulator (.A) is located at one
address in the VIC, and another in the 64.  On future Commodore computers it
may be found at still another location.  Yet as long as the routine is
vectored in RAM at 774 ($306), the statement QP=PEEK(774)+256*PEEK(775) would
find the address of that routine on any of the machines.  Thus, entering such
routines through RAM vectors rather than a direct jump into the ROMs helps to
keep your programs compatible with different machines.
  The other important effect of having these vectors in RAM is that you can
alter them.  In that way, you can redirect these important BASIC routines to
execute your own preprocessing routines first.
  If you wanted to add commands to BASIC, for example, how would you go about
it?  First, you would need to change the BASIC routines that convert ASCII
program text to tokenized program format, so that when a line of program text
was entered, the new keyword would be stored as a token.
  Next, you would need to change the routine that executes tokens, so that
when the interpreter comes to your new keyword token, it will take the proper
action.
  You would also have to change the routine that converts tokens back to ASCII
text, so that your program would LIST the token out correctly.  And you might
want to alter the routine that prints error messages, to add new messages for
your keyword.
  As you will see, vectors to all of these routines can be found in the
following indirect vector table.  Changing these vectors is a much more
elegant and efficient solution than the old wedge technique discussed at
location 115 ($73)

768-769       $300-$301      IERROR
Vector to the Print BASIC Error Message Routine

This vector points to the address of the ERROR routine at 58251 ($E38B).

770-771       $302-$303      IMAIN
Vector to the Main BASIC Program Loop

This vector points to the address of the main BASIC program loop at 42115
($A483).  This is the routine that is operating when you are in the direct
mode (READY).  It executes statements, or stores them as program lines.

772-773       $304-$305      ICRNCH
Vector to the Routine That Crunches the ASCII Text of Keywords into Tokens

This vector points to the address of the CRUNCH routine at 42364 ($A57C).

774-775       $306-$307      IQPLOP
Vector to the Routine That Lists BASIC Program Token as ASCII Text

This vector points to the address of the QPLOP routine at 42778 ($A71A).

776-777       $308-$309      IGONE
Vector to the Routine That Executes the Next BASIC Program Token

This vector points to the address of the GONE routine at 42980 ($A7E4) that
executes the next program token.

778-779       $30A-$30B      IEVAL
Vector to the Routine That Evaluates a Single-Term Arithmetic Expression

This vector points to the address of the EVAL routinea t 44678 ($AE86) which,
among other things, is used to evaluate BASIC functions such as INT and ABS.

Location Range: 780-783 ($30C-$30F)
Register Storage Area

The BASIC SYS command uses this area to store 6510 internal registers--the
Accumulator (.A), the .X and .Y index registers, and the status register, .P.
  Before every SYS command, each of the registers is loaded with the value
found in the corresponding storage address.  After the ML program finished
executing, and returns to BASIC with an RTS instruction, the new value of
each register is stored in the appropriate storage address.  This is only true
of SYS, not of the similar USR command.
  This feature allows you to place the necessary preentry values into the
registers from BASIC before you SYS to a Kernal or BASIC ML routine.  It also
enables you to examine the resulting effect of the routine on the registers,
and to preserve the condition of the registers on exit for subsequent SYS
calls.
  An extremely practical application comes immediately to mind.  Although the
64's BASIC 2 has many commands for formatting printed characters on the
monitor screen (for example, TAB, SPC, PRINT A$,B), there is none to adjust
the vertical cursor position.
  There is a Kernal routine, PLOT (58634, $E50A), which will allow you to
position the cursor anywhere on the screen.  In order to use it, you must
first clear the carry flag (set it to 0), and then place the desired
horizontal column number in the .Y register and the vertical row number in the
.X register before entering the routine with a SYS 65520.  Using the register
storage area, we can print the work HELLO at row 10, column 5 with the
following BASIC line:

POKE 781,10:POKE 782,5:POKE 783,0:SYS 65520:PRINT "HELLO"

You can also use these locations to help you take advantage of Kernal routines
that return information in the register.  For example, the SCREEN routine
(58629,$E505) returns the number of screen rows int he .Y register, and the
number of columns in the .X register.  Using this routine, a BASIC program
could be written to run on machines with different screen formats (for
example, the 64 and the VIC-20).  Just PEEK(781) after a SYS 65517 to see how
many screen columns the computer display has.

780           $30C           SAREG
Storage Area for .A Register (Accumulator)

781           $30D           SXREG
Storage Area for .X Index Register

782           $30E           SYREG
Storage Area for .Y Index Register

783           $30F           SPREG
Storage Area for .P (Status) Register

The Status (.P) register has seven different flags.  Their bit assignments are
as follows:

Bit 7 (bit value of 128) = Negative
Bit 6 (bit value of 64)  = Overflow
Bit 5 (bit value of 32)  = Not Used
Bit 4 (bit value of 16)  = BREAK
Bit 3 (bit value of 8)   = Decimal
Bit 2 (bit value of 4)   = Interrupt Disable
Bit 1 (bit value of 2)   = Zero
Bit 0 (bit value of 1)   = Carry

If you wish to clear any flag before a SYS, it is safe to clear them all with
a POKE 783,0.  The reverse is not true, however, as you must watch out for the
Interrupt disable flag.
  A 1 in this flag bit is equal to an SEI instruction, which turns off all IRQ
interrupts (like the one that reads the keyboard, for example).  Turning off
the keyboard could make the computer very difficult to operate!  To set all
flags except for Interrupt disable to 1, POKE 783,247.

784           $310           USRPOK
Jump Instruction for User Function ($4C)

The value here (67, $4C) is first part of the 6510 machine language JuMP
instruction for the USR command.

785-786       $311-$312      USRADD
Address of USR Routine (Low Byte First)

These locations contain the target address of the USR command.  They are
initialized by the Operating System to point to the BASIC error message
handler routine, so that if you try to execute a USR call without changing
these values, you wil receive an ILLEGAL QUANTITY error message.
  In order to successfully execute a USR call, you must first POKE in the
target address in low-byte, high-byte order.  You can calculate these two
values for any address with the formula:

HI=INT(AD/256):LO=AD-(HI*256)

For example, if the USR routine started at 49152 ($C000), you would POKE 786,
INT(49152/256):POKE 785,49152-(PEEK(786)*256 before executing the USR command.
  What makes the USR command different from SYS is that you can pass a
parameter into the machine language routine by placing it in parenthesis after
the USR keyword, and you can pass a parameter back to a variable by assigning
its value to the USR function.
  In other words, the statement X=USR(50) will first put the number 50 in
floating point format into the Floating Point Accumulator (FAC1) at 97-102
($61-$66).  Then, the machine language program designated by the address at
this vector will be executed.  Finally, the variable X will be assigned the
floating point value which ends up in FAC1 after the user-written routine is
finished.
  Since floating point representation is difficult to work with, it is handy
to change these floating point parameters into integers before working with
them.  Fortunately, there are vectored routines which will do the conversions
for you.  The routine vectored at locations 3-4 converts the number in FAC1 to
a two-byte signed integer, with the low byte in the .Y register (and location
101 ($65)) and the high byte in the Accumulator (.A).  Remember, that number
is converted to a signed integer in the range between 32767 and -32768, with
Bit 7 of the high byte used to indicate the sign.
  To pass a value back through the USR function, you need to place the number
into FAC1.  To conert a signed integer to floating point format, place the
high byte into the Accumulator (.A), the low byte into the .Y register, and
jump through the vector at locations 5-6 with a JMP ($0005) instruction.  The
floating point result will be left in FAC1.

787           $313
Unused

788-789       $314-$315      CINV
Vector to IRQ Interrupt Routine

This vector points to the address of the routine that is executed when an IRQ
interrupt occurs (normally 59953 ($FA31)).
  At power on, the CIA #1 Timer B is set to cause an IRQ interrupt to occur
every 1/60 second.  This vector is set to point to the routine which updates
the software clock and STOP key check, blinks the cursor, maintains the tape
interlock, and reads the keyboard.  By changing this vector, the user can add
or substitute a machine language routine that will likewise execute every 1/60
second.  The user who is writing IRQ interrupt routines should consider the
following:
  1.  It is possible for an IRQ interrupt to occur while you are changing this
vector, which would cause an error from which no recovery could be made.
Therefore, you must disable all IRQ interrupts before changing the contents of
this location, and reenable them afterwards, by using the 6510 SEI and CLI
instructions, or by using the Kernal VECTOR routine (64794, $FD1A) to set this
vector.
  2.  There is some code in ROM that is executed before the interrupt routine
is directed through this vector.  This code checks whether the source of the
interrupt was an IRQ or BRK instruction.  If first preserves the contents of
all the registers by pushing them onto the stack in the following sequence:
PHA, TXA, PHA, TYA, PHA.  It is up to the user to restore the stack at the end
of his routine, either by exiting through the normal IRQ, or with the
sequence:  PLA, TAY, PLA, TAX, PLA, RTI.
  3.  There is only one IRQ vector, but there are many sources for IRQ
interrupts (two CIA chips, and several VIC chip IRQs).  If you plan to enable
IRQs from more than one source, the IRQ routine here must determine the
source, and continue the routine in the appropriate place for an IRQ from that
source.
  In the same vein, if you replace the normal IRQ routine with your own, you
should be aware that the keyboard's scanning and clock update will not occur
unless you call the old interrupt routine once every 1/60 second.  It is
suggested that if you plan to use that routine, you save the old vector
address in some other location.  In that way, you can JuMP to the keyboard
interrupt routine through this alternate vector, rather than assuming that the
ROM address will never change and that it is safe to jump into the ROM
directly.

790-791       $316-$317      CBINV
Vector: BRK Instruction Interrupt

This vector points to the address of the routine which will be executed
anytime that a 6510 BRK instruction (00) is encountered.
  The default value points to a routine that calls several of the Kernal
initialization routines such as RESTOR, IOINIT and part of CINT, and then
jumps through the BASIC warm start vector at 40962.  This is the same routine
that is used when the STOP and RESTORE keys are pressed simultaneously, and is
currently located at 65126 ($Fe66).
  A machine language monitor program will usually change this vector to point
to the monitor warm start address, so that break points may be set that will
return control to the monitor for debugging purposes.

792-793       $318-$319      NMINV
Vector: Non-Maskable Interrupt

This vector points to the address of the routine that will be executed when a
Non-Maskable Interrupt (NMI) occurs (currently at 65095 ($FE47)).
  There are two possible sources for an NMI interrupt.  The first is the
RESTORE key, which is connected directly to the 6510 NMI line.  The second is
CIA #2, the interrupt line of which is connected to the 6510 NMI line.
  When an NMI interrupt occurs, a ROM routine sets the Interrupt disable flag,
and then jumps through this RAM vector.  The default vector points to an
interrupt routine which checks to see what the cause of the NMI was.
  If the cause was CIA #2, the routine checks to see if one of the RS-232
routines should be called.  If the source was the RESTORE key, it checks for
a cartridge, and if present, the cartridge is entered at the warm start entry
point.  If there is no cartridge, the STOP key is tested.  If the STOP key was
pressed at the same time as the RESTORE key, several of the Kernal
initialization routines such as RESTOR, IOINIT and part of CINT are executed,
and BASIC is entered through its warm start vector at 40962.  If the STOP key
was not pressed simultaneously with the RESTORE, the interrupt will end
without letting the user know that anything happened at all when the RESTORE
key was pressed.
  Since this vector controls the outcome of pressing the RESTORE key, it can
be used to disable the STOP/RESTORE sequence.  A simple way to do this is to
change this vector to point to the RTI instruction.  A simple POKE 792,193
will accomplish this.  To set the vector back, POKE 792,71.  Note that this
will cut out all NMIs, including those required for RS-232 I/O.

Location Range: 794-813 ($31A-$32D)
Kernal Indirect Vectors

There are 39 Kernal routines for which there are vectors in the jump table
located at the top of the ROM (65409, $FF81).  For ten of these routines, the
jump table entry contains a machine language instruction to jump to the
address pointed to by the RAM vector in this table.  The addresses in this
table are initialized to point to the corresponding routines in the Kernal
ROM.  Since these addresses are in RAM, however, any entry in this table may
be changed.  This enables the user to add to these routines, or to replace
them completely.
  You will notice, for example, that many of these routines involve Input/
Output functions.  By changing the vectors  to these routines, it is possible
to support new I/O devices, such as an IEEE disk drive used through an
adapter.
  The user should be cautioned that since some of these routines are
interrupt-driven, it is dangerous to change these vectors without first
turning off all interrupts.  For a safe method of changing all of these
vectors at one time, along with the interrupt vectors above, see the entry for
the Kernal VECTOR routine at 64794 ($FD1A).
  More specific information about the individual routines can be found in the
descriptions given for their ROM locations.

794-795       $31A-$31B      IOPEN
Vector to Kernal OPEN Routine (Currently at 62282 ($F34A))

796-797       $31C-$31D      ICLOSE
Vector to Kernal CLOSE Routine (Currently at 62097 ($F291))

798-799       $31E-$31F      ICHKIN
Vector to Kernal CHKIN Routine (Currently at 61966 ($F20E))

800-801       $320-$321      ICKOUT
Vector to Kernal CKOUT Routine (Currently at 62032 ($F250))

802-803       $322-$323      ICLRCH
Vector to Kernal CLRCHN Routine (Currently at 62259 ($F333))

804-805       $324-$325      IBASIN
Vector to Kernal CHRIN Routine (Currently at 61783 ($F157))

806-807       $326-$327      IBSOUT
Vector to Kernal CHROUT Routine (Currently at 61898 ($F1CA))

808-809       $328-$329      ISTOP
Vector to Kernal STOP Routine (Currently at 63213 ($F6ED))

This vector points to the address of the routine that tests the STOP key.  The
STOP key can be disabled by changing this with a POKE 808,239.  This will not
disable the STOP/RESTORE combination, however.  To disable both STOP and STOP/
RESTORE, POKE 808,234 (POKEing 234 here will cause the LIST command not to
function properly).  To bring things back to normal in either case, POKE 808,
237.

810-811       $32A-$32B      IGETIN
Vector to Kernal GETIN Routine (Currently at 61758 ($F13E))

812-813       $32C-$32D      ICLALL
Vector to Kernal CLALL Routine (Currently at 62255 ($F32F))

814-815       $32E-$32F      USRCMD
Vector to User-Defined Command (Currently Points to BRK at 65126 ($FE66))

This appears to be a holdover from PET days, when the built-in machine
language monitor would JuMP through the USRCMD vector when it encountered a
command that it did not understand, allowing the user to add new commands to
the monitor.
  Although this vector is initialized to point to the routine called by STOP/
RESTORE and the BRK interrupt, and is updated by the Kernal VECTOR routine
(64794, $FD1A), it does not seem to have the function of aiding in the
addition of new commands.

816-817       $330-$331      ILOAD
Vector to Kernal LOAD Routine (Currently at 62622 ($F49E))

818-819       $332-$333      ISAVE
Vector: Kernal SAVE Routine (Currently at 62941 ($F5DD))

820-827       $334-$33B
Unused

Eight free bytes for user vectors or other data.

828-1019      $33C-$3FB      TBUFFER
Cassette I/O Buffer

This 192-byte buffer area is used to temporarily hold data that is read from
or written to the tape device (device number 1).
  When not being used for tape I/O, the cassette buffer has long been a
favorite place for Commodore programmers to place short machine language
routines (although the 64 has 4K of unused RAM above the BASIC ROM at 49152
($C000) that would probably better serve the purpose).
  Of more practical interest to the 64 programmer is the possible use of this
area for VIC-II chip graphics memory (for example, sprite shape data or text
character dot data).  If the VIC-II chip is banked to the lowest 16K of
memory (as is the default selection), there is very little memory space which
can be used for such things as sprite shape data without conflict.  If the
tape is not in use, locations 832-895 ($340-$37F) can be used as sprite data
block number 13, and locations 896-959 ($380-$3BF) can be used as sprite data
block number 14.
  The types of tape blocks that can be stored here are program header blocks,
data header blocks, and data storage blocks.
  The first byte of any kind of block (which is stored at location 828 ($33C))
identifies the block type.  Header blocks follow this identifier byte with the
two-byte starting RAM address of the tape data, the two-byte ending RAM
address, and the filename, padded with blanks so that the total length of the
name portion equals 187 bytes.  Data storage blocks have 191 bytes of data
following the identifier byte.  The meanings of the various identifier blocks
are as follows:
  A value of 1 signifies that the block is the header for a relocatable
program file, while a value of 3 indicates that the block is the header for a
nonrelocatable program file.
  A relocatable file is created when a program is SAVEd with a secondary
address of 0 (or any even number), while a nonrelocatable program file is
created if the secondary SAVE address is 1 (or any odd number).  The
difference between the two types of files is that a nonrelocatable program
will always load at the address specified in the header.  A relocatable
program will load at the current start of BASIC address unless the LOAD
statement uses a secondary address of 1, in which case it will also be
loaded at the addrss specified in the header.
  You should note that a program file uses the cassette buffer only to store
the header block.  Actual program data is transferred directly to or from RAM,
without first being buffered.
  An identifier value of 4 means that the block is a data file header.  Such
a header block is stored in the cassette buffer whenever a BASIC program OPENs
a tape data file for reading or writing.  Subsequent data blocks start with an
identifier byte of 2.  These blocks contain the actual data byte written by
the PRINT #1 command, and read by the GET #1 and INPUT #1 commands.  Unlike
the body of a program file, these blocks are temporarily stored in the
cassette byffer when being written or read.
  An identifier byte of 5 indicates that this block is the logical end of the
tape.  This signals the Kernal not to search past this point, even if there
are additional tape blocks physically present on the tape.

1020-1023     $3FC-$3FF
Unused

Four more free bytes.


::::::::::::::::::::::::
::     Chapter 4      ::
::                    ::
::     1K to 40K      ::
::                    ::
::   Screen Memory,   ::
::Sprite Pointers, and::
:: BASIC Program Text ::
::::::::::::::::::::::::

1024-2047     $400-$7FF      VICSCN
Video Screen Memory Area

This is the default location of the video screen memory area, which contains
the video matrix and the sprite data pointers.  Keep in mind, however, that
the video screen memory area can be relocated to start on any even 1K
boundary.  Its location at any given moment is getermined by the VIC-II chip
memory control register at 53272 ($D018), and the VIC-II memory bank select
bits on CIA #2 Data Port A (56576, $DD00).

1024-2023     $400-$7E7
Video Matrix: 25 Lines by 40 Columns

The video matrix is where thext screen characters are stored in RAM.
Normally, the VIC-II chip will treat each byte of memory here as a screen
display code and will display the text character that corresponds to that byte
of code.  The first byte of memory here will be displayed in the top-left
corner of the screen, and subsequent bytes will be displayed in the columns to
the right and the rows below that character.
  It is possible to make text or graphics characters appear on the screen by
POKEing their screen codes directly into this area of RAM.  For example, the
letter A has a screen code value of 1.  Therefore, POKE 1024,1 should make the
letter A appear in the top-left corner of the screen.
  However, you should be aware that the most current version of the Operating
System initializes the color RAM which is used for the foreground color of
text characters to the same value as the background color every time that the
screen is cleared.  The result is that although the POKE will put a blue A on
the screen, you won't be able to see it because it is the same color blue as
the background.  This can be remedied by POKEing a different value into color
RAM (which starts at 55296 ($D800)).
  A POKE 1024,1:POKE 1024+54272,1 will put a white A in the upper-left corner
of the screen.  The loop

FOR I=0 TO 255:POKE 1024+I,I:POKE 1024+54272+I,1:NEXT

will display all of the characters in white at the top of the screen.  Another
solution to the color RAM problem is to fool the Operating System into
initializing the color RAM for you.  If you change the background color to the
desired foreground color before you clear the screen, color RAM will be set to
that color.  Then, all you have to do is change the background color back to
what it was.  This example will show how it's done:

10 POKE 53281,2:REM BACKGROUND IS RED
20 PRINT CHR$(147):REM CLEAR SCREEN
30 POKE 53281,1:REM BACKGROUND IS WHITE
40 POKE 1024,1:REM RED "A" APPEARS IN TOP LEFT CORNER

2040-2047     $7F8-$7FF
Sprite Shape Data Pointers

The last eight bytes of the video matrix (whether it is here at the default
location, or has been relocated elsewhere) are used as pointers to the data
blocks used to define the sprite shapes.
  Each sprite is 3 bytes wide (24 bits) by 21 lines high.  It therefore
requires 63 bytes for its shape definition, but it actually uses 64 bytes in
order to arrive at an even 256 shape blocks in the 16K area of RAM which the
VIC-II chip addresses.
  Each pointer holds the current data block being used to define the shape of
one sprite.  The block numver used to define the shape of Sprite 0 is held in
location 2040 ($7F8), the Sprite 1 shape block is designated by location 2041
($7F9), etc.  The value in the pointer times 64 equals the starting location
of the sprite shape data table.  For example, a value of 11 in location 2040
indicates that the shape data for Sprite 0 starts at address 704 (11*64), and
continues for 63 more bytes to 767.
  For additional information on sprite graphics, see the entries for
individual VIC-II chip sprite graphics locations, and the summary at the
beginning of the VIC-II chip section, at 53248 ($D000).

2048-40959    $800-$9FFF
BASIC Program Text

This is the area where the actual BASIC program text is stored.  The text of a
BASIC program consists of linked lines of program tokens.  Each line contains
the following:
  1.  A two-byte pointer to the address of the next program line (in standard
low-byte, high-byte order).  After the last program line, a link pointer
consisting of two zeros marks the end of the program.
  2.  A two-byte line number (also in low-byte, high-byte order).
  3.  The program commands.  Each keyword is stored as a one-byte character
whose value is equal to or greater than 128.  Print, for example, is stored as
the number 151.  Other elements of the BASIC command, such as the variable
names, string literals ("HELLO"), and numbers, are stored using their ASCII
equivalents.
  4.  A 0 character, which acts as a line terminator.  In order for BASIC to
work correctly, the first character of the BASIC text area must be 0.
  A quick review of the BASIC pointers starting at 43 ($2B) reveals that the
layout of the BASIC program area (going from lower memory addresses to
higher) is as follows:

BASIC Program Text
Non-Array Variables and String Descriptors
Array Variables
Free Area (Reported by FRE(0))
String Text Area (Strings build from top of memory down into free area)
BASIC ROM

It is interesting to note that the NEW command does not zero out the text
area but rather replaces the first link address in the BASIC program with two
zeros, indicating the end of the program.  Therefore, you can recover a
program from a NEW by replacing the first link adress, finding the address of
the two zeros that actually mark the end of the program, and setting the
pointers at 45, 47, and 49 (which all point to the end of a BASIC program
before the program is RUN) to the byte following these zeros.

4096-8191     $1000-$1FFF
Character ROM Image for VIC-II Chip When Using Memory Bank 0 (Default)

Though the VIC-II chip shares memory with the 6510 processor chip, it does not
always see that memory in exactly the same way as the main microprocessor.
  Although the 6510 accesses RAM at these locations, when the VIC-II is banked
to use the first 16K of RAM (which is the default condition), it sees the
character ROM here (the 6510 cannot access this ROM unless it is switched into
its memory at 49152 ($C000)).  This solves the riddle of how the VIC-II chip
can use the character ROM at 49152 ($C000) for character shape data and RAM
at 1024 ($400), when it can only address memory within a 16K range.  It also
means that the RAM at 4096-8191 cannot be used for screen display memory or
user-defined character dot data, and sprite data blocks 64-127 are not
accessible.
  You can verify this by turning on bitmap graphics with the screen memory set
to display addresses from 0 to 8192.  You will see that the bottom portion of
the screen shows all of the text character shapes stored in the ROM.  For more
information on the format of text character data storage, see the description
of the Character ROM at 49152 ($C000).

32768         $8000
Autostart ROM Cartridge

An 8K or 16K autostart ROM cartridge designed to use this as a starting memory
address may be plugged into the Expansion Port on the back.  If the cartridge
ROM at locations 32772-32776 ($8004-$8008) contains the numbers 195, 194, 205,
56, 48 ($C3, $C2, $CD, $38, $30) when the computer powers up, it will start
the program pointed to by the vector at locations 32768-32769 ($8000-$8001),
and will use 32770-32771 ($8002-$8003) for a warm start vector when the
RESTORE key is pressed.  These characters are PETASCII for the inverse letters
CBM, followed by the digits 80.  An autostart cartridge may also be addressed
at 40960 ($A000), where it would replace BASIC, or at 61440 ($F000), where it
would replace the Kernal.
  It is possible to have a 16K cartridge sitting at 32768 ($8000), such as
Simon's BASIC, which can be turned on and off so that the BASIC ROM underneath
can also be used.  Finally, it is even possible to have bank-selected
cartridges, which turn banks of memory in the cartidge on and off alternately,
so that a 32K program could fit into only 16K of addressing space.

36864-40959   $9000-$9FFF
Character ROM Image for VIC-II Chip When Using Memory Bank 2

When the VIC-II chip is set up to use the third 16K block of memory for
graphics (as would be the case when the 64 is set up to emulate the PET, which
has its text screen memory at 32768 ($8000), it sees the character generator
ROM at this address (see entry at 4096 ($1000) above for more details).
  It should be noted that the character ROM is available only when the VIC-II
chip is using banks 0 or 2.  When using one of the other two banks, the user
must supply all of the character shape data in a RAM table.


::::::::::::::
::Chapter 5 ::
::          ::
:: 8K BASIC ::
::ROM and 4K::
:: Free RAM ::
::::::::::::::

Locations 40960 to 49152 ($A000 to $BFFF) are used by the BASIC ROM when it is
selected (which is the default condition).  BASIC is the 64's main program,
which is always run if there is no autostart cartridge inserted at power-up
time.  When the 64 tells you READY, that's BASIC talking.
  The BASIC interpreter that comes with the 64 is, aside from being located in
a different memory space, almost identical to the Microsoft BASIC interpreter
found on the VIC-20.  Both of these interpreters are slightly modified
versions of PET BASIC 2.0, also known as PET BASIC 3.0 or Upgrade BASIC,
because it was an upgraded version of the BASIC found on the original PET.
  This is a somewhat mixed blessing, because while PET BASIC was, in its day,
quote an advanced language for use with an eight-bit microprocessor, it lacks
several of the features (such as error trapping) which are now standard on
most home computers.  And, of course, it makes no provision whatever for easy
use of the many graphics and sound capabilities made available by the new
dedicated video and sound support chips.
  On the other hand, its faithfulness to the original Commodore BASIC allows a
large body of software to be translated for the 64 with little change (in most
cases, the PET Emulator program from Commodore will allow you to run PET
programs with no changes).  Programming aids and tricks developed for the PET
and VIC will, for the most part, carry over quite nicely to the 64.  Although
there is no official source code listing of the ROM available from Commodore,
this version of BASIC has been around long enough that it has been thoroughly
disassembled, dissected, and documented by PET users.
  The labels used here correspond to those used by Jim Butterfield in his PET
memory maps, which are well-known among PET BASIC users.  They should,
therefore, provide some assistance in locating equivalent routines on the two
machines.  A good description of the workings of PET BASIC can be found in
Programming the PET/CBM by Raeto West.
  It is beyond the scope of this book to detail the inner workings of each
routine in the BASIC interpreter.  However, the following summary of routines
and their functions should aid the user who is interested in calling BASIC
routines from his or her own program, or in modifying the BASIC.
  Please keep in mind that the entry and exit points listed for routines that
perform a particular function are to be used as guideposts, and not absolutes.
In fact, BASIC enters many of these routines from slightly different places to
accomplish different tasks.  Some subroutines are called by so many commands
that it is hard to say which they belong to.  You will even find that some
whole commands are part of other commands.  Where it is important for you to
know the details of a particular routine, you will need to obtain a
disassembly of that section and look at the machine language program itself.
  It should be noted that when BASIC is not neede,d it can be switched out and
the RAM underneath can be accessed by the VIC-II chip and used for screen
graphics.  See location 56576 ($DD00) for more information.

40960-40961   $A000-$A001
Cold Start Vector

This vector points to the address of the routine used to initialize BASIC.
After the Operating System finishes its power-on activities, it enters the
BASIC program through this vector.  The most visible effect of the BASIC
initialization routine is that the screen is cleared, and the words:

     **** COMMODORE 64 BASIC V2 ****

are printed along with the BYTES FREE message.  For details of the steps
taken during the initialization of BASIC, see the entry for 58260 ($E394), the
current cold start entry point.

40962-40963   $A002-$A003
Warm Start Vector

The warm start vector points to the address of the routines used to reset
BASIC after the STOP/RESTORE key combination is pressed.  This is the same
address to which the BRK instruction is vectored.  When BASIC is entered
through this vector, the program in memory is not disturbed.  For more
information, see the entry for 58235 ($E37B), the current warm start entry
point.

40964-40971   $A004-$A00B
ASCII Text characters CBMBASIC

The ASCII characters for the letters CBMBASIC are located here.  Possibly an
identifier, this text is not referenced elsewhere in the program.

40972041941   $A00C-$A051    STMDSP
Statement Dispatch Vector Table

This table contains two-byte vectors, each of which points to an address which
is one byte before the address of one of the routines that perform a BASIC
statement.
  The statements are in token number order.  When it comes time to execute a
statement, the NEWSTT routine at 42926 ($A7AE) places this address-1 on the
stack and jumps to the CHRGET routine.  The RTS instruction at the end of that
routine causes the statement address to be pulled off the stack, incremented,
and placed in the Program Counter, just as if it were the actual return
address.
  This table is handy for locating the address of the routine that performs a
BASIC statement, so that the routine can be disassembled and examined.  To aid
in this purpose, the table is reproduced below with the actual target address,
and not in the address-1 format used by BASIC.

Token #   Statement   Routine Address
128 $80   END         43057 $A831
129 $81   FOR         42818 $A742
130 $82   NEXT        44318 $AD1E
131 $83   DATA        43256 $A8F8
132 $84   INPUT#      43941 $ABA5
133 $85   INPUT       43967 $ABBF
134 $86   DIM         45185 $B081
135 $87   READ        44038 $AC06
136 $88   LET         43429 $A9A5
137 $89   GOTO        43168 $A8A0
138 $8A   RUN         43121 $A871
139 $8B   IF          43304 $A928
140 $8C   RESTORE     43037 $A81D
141 $8D   GOSUB       43139 $A883
142 $8E   RETURN      43218 $A8D2
143 $8F   REM         43323 $A93B
144 $90   STOP        43055 $A82F
145 $91   ON          43339 $A94B
146 $92   WAIT        47149 $B82D
147 $93   LOAD        57704 $E168
148 $94   SAVE        57686 $E156
149 $95   VERIFY      57701 $E165
150 $96   DEF         46003 $B3B3
151 $97   POKE        47140 $B824
152 $98   PRINT#      43648 $AA80
153 $99   PRINT       43680 $AAA0
154 $9A   CONT        43095 $A857
155 $9B   LIST        42652 $A69C
156 $9C   CLR         42590 $A65E
157 $9D   CMD         43654 $AA86
158 $9E   SYS         57642 $E12A
159 $9F   OPEN        57790 $E1BE
160 $A0   CLOSE       57799 $E1C7
161 $A1   GET         43899 $AB7B
162 $A2   NEW         42562 $A642

41042-41087   $A052-$A07F    FUNDSP
                             TABLE
Function Dispatch Vector Table

This table contains two-byte vectors, each of which points to the address of
one of the routines that performs a BASIC function.
  A function is distinguished by a following argument, in parentheses.  The
expression in the parentheses is first evaluated by the routines which begin
at 44446 ($AD9E).  Then this table is used to find the address of the function
that corresponds to the token number of the function to be executed.
  The substance of this table, which can be used for locating the addresses of
these routines, is reproduced below.  Note that the address for the USR
function is 784 ($310), which is the address of the JMP instruction which
precedes the user-supplied vector.

Token #   Function     Routine Address
180 $B4   SGN          48185 $BC39
181 $B5   INT          48332 $BCCC
182 $B6   ABS          48216 $BC58
183 $B7   USR            784 $0310
184 $B8   FRE          45949 $B37D
185 $B9   POS          45982 $B39E
186 $BA   SQR          49009 $BF71
187 $BB   RND          57495 $E097
188 $BC   LOG          45794 $B9EA
189 $BD   EXP          49133 $BFED
180 $BE   COS          57956 $E264
191 $BF   SIN          57963 $E26B
192 $C0   TAN          58036 $E2B4
193 $C1   ATN          58126 $E30E
194 $C2   PEEK         47117 $B80D
195 $C3   LEN          46972 $B77C
196 $C4   STR$         46181 $B465
197 $C5   VAL          47021 $B7AD
198 $C6   ASC          46987 $B78B
199 $C7   CHR$         46828 $B6EC
200 $C8   LEFT$        46848 $B700
201 $C9   RIGHT$       46892 $B72C
202 $CA   MID$         46903 $B737

41088-41117   $A080-$A09D    OPTAB
Operator Dispatch Vector Table

This table contains two-byte vectors, each of which points to an address which
is one byte before the address of one of the routines that perform a BASIC
math operation.
  For the reasoning behind the one-byte offset to the true address, see the
entry for location 40972 ($A00C).  In addition, each entry has a one-byte
number which indicates the degree of precedence that operation takes.
Operations with a higher degree of precedence are performed before operations
of a lower degree (for example, in the expression A=3+4*6, the 4*6 operation
is performed first, and 3 is added to the total).  The order in which they are
performed is:

1.  Expressions in parentheses
2.  Exponentation (raising to a power, using the up-arrow symbol)
3.  Negation of an expression (-5, -A)
4.  Multiplication and division
5.  Addition and subtraction
6.  Relation tests (=, <>, <, >, <=, >= all have the same precedence)
7.  NOT (logical operation)
8.  AND (logical operation)
9.  OR (logical operation)

The substance of this table, which can be used to locate the addresses of the
math routines, is given below.  Note that less that, equal, and greater than
operators all use the same routines, though they have different token numbers.

Token #   Operator           Routine Address
170 $AA   + (ADD)            47210 $B86A
171 $AB   - (SUBTRACT)       47187 $B853
172 $AC   * (MULTIPLY)       47659 $BA2B
173 $AD   / (DIVIDE)         47890 $BB12
174 $AE   ^ (EXPONENTIATE)   49019 $BF7B
175 $AF   AND (LOGICAL AND)  45033 $AFE9
176 $B0   OR (LOGICAL OR)    45030 $AFE6
177 $B1   > (GREATER THAN)   49076 $BFB4
178 $B2   = (EQUAL TO)       44756 $AED4
179 $B3   < (LESS THAN)      45078 $B016

41118-41373   $A09E-$A19D    RESLST
List of Keywords

This table contains a complete list of the reserved BASIC keywords (those
combinations of ASCII text characters that cause BASIC to do something).  The
ASCII text characters of these words are stored in token number order.  Bit #7
of the last letter of each word is set to indicate the end of the word (the
last letter has 128 added to its true ASCII value).
  When the BASIC program text is stored, this list of words is used to reduce
any keywords to a single-byte value called a token.  The command PRINT, for
example, is not stored in a program as five ASCII bytes, but rather as the
single token 153 ($99).
  When the BASIC program is listed, this table is used to convert these tokens
back to ASCII text.  The entries in this table consist of the following:

1.  The statements found in STMDSP at 40972 ($A00C), in the token number order
indicated (token numbers 128-162).
2.  Some miscellaneous keywords which never begin a BASIC statement:

Token #    Keyword
162 $A3    TAB(
164 $A4    TO
165 $A5    FN
166 $A6    SPC(
167 $A7    THEN
168 $A8    NOT
169 $A9    STEP

3.  The math operators found in OPTAB at 41088 ($A080), in the token number
order indicated (token numbers 170-179).
4.  The functions found in FUNDSP at 41042 ($A052), in the token number order
indicated (token numbers 182-202).
5.  The word GO (token number 203 ($CB)).  This word was added to the table to
make the statement GO TO legal, to afford some compatibility with the very
first PET BASIC, which allowed spaces within keywords.

41374-41767   $A19E-$A327    ERRTAB
ASCII Text of BASIC Error Messages

This table contains the ASCII text of all of the BASIC error messages.  As in
the keyword table, Bit 7 of the last letter of each message is set to indicate
the end of the message.  Although we've all seen some of them at one time or
another, it's somewhat daunting to see the whole list at once.  The possible
errors you can make include:

 1.  TOO MANY FILES
 2.  FILE OPEN
 3.  FILE NOT OPEN
 4.  FILE NOT FOUND
 5.  DEVICE NOT PRESENT
 6.  NOT INPUT FILE
 7.  NOT OUTPUT FILE
 8.  MISSING FILENAME
 9.  ILLEGAL DEVICE NUMBER
10.  NEXT WITHOUT FOR
11.  SYNTAX
12.  RETURN WITHOUT GOSUB
13.  OUT OF DATA
14.  ILLEGAL QUANTITY
15.  OVERFLOW
16.  OUT OF MEMORY
17.  UNDEF'D STATEMENT
18.  BAD SUBSCRIPT
19.  REDIM'D ARRAY
20.  DIVISION BY ZERO
21.  ILLEGAL DIRECT
22.  TYPE MISMATCH
23.  STRING TOO LONG
24.  FILE DATA
25.  FORMULA TOO COMPLEX
26.  CAN'T CONTINUE
27.  UNDEF'D FUNCTION
28.  VERIFY
29.  LOAD

Message number 30, BREAK, is located in the Miscellaneous Messages table
below.

41768-41828   $A328-$A364
Error Message Vector Table

This table contains the two-byte address of the first letter of each of the 30
error messages.

41829-41865   $A365-$A389
Miscellaneous Messages

The text of some of the other messages that BASIC can give you is stored here.
This text includes cursor movement characters, and each message ends with a 0
character.  The messages are:

1) Carriage return, OK, carriage return
2) Space, space, ERROR
3) Space, IN, space
4) Carriage return, linefeed, READY., carraige return, linefeed
5) Carriage return, linefeed, BREAK

41866-41911   $A38A-$A3B7    FNDFOR
Find FOR on Stack

This routine searches the stack for the blocks of data entries which are
stored by each FOR command.  For more information on the data that FOR places
on the stack, see location 256 ($100).

41912         $A3B8          BLTU
Open a Space in Memory for a New Program Line or Variable

When a new nonarray variable is being created, or when a BASIC program line is
being added or replaced, this routine is used to make room for the addition.
It first checks to see if space is available, and then moves the program text
and/or variables to make room.

41979-41991   $A3FB-$A407    GETSTK
Check for Space on Stack

Before undertaking an operation that requires stack space, this routine is
used to check if there is enough room on the stack.  If there is not, an OUT
OF MEMORY error is issued.

41992-42036   $A408-$A434    REASON
Check for Space in Memory

This is the subroutine that checks to see if there is enough space in free
memory for proposed additions such as new lines of program text.  If not, it
calls for garbage collection, and if this still does not produce enough space,
an OUT OF MEMORY error is issued.

42037-42088   $A435-$A468    OMERR
OUT OF MEMORY Error Handler

This routine just sets the error message code, and falls through to the
general error handler.

42039-42088   $A437-$A468    ERROR
General Error Handler

The error number is passed to this routine in the .X register, and it displays
the appropriate error message.  Since this routine is vectored through RAM at
768 ($300), you can divert this vector to the address of your own routine,
which would allow error trapping, or the addition of new commands.

42089-42099   $A474-$A47F    READY
Print READY

This routine displays the word READY, sets the Kernal message flag to show
that direct mode is operative, and falls through to the main BASIC loop.

42112-42139   $A480-$A49B    MAIN
Main Loop, Receives Input and Executes Immediately or Stores as Program Line

This is the main BASIC program loop.  It jumps through the RAM vector at 770
($302), so this routine can be diverted.  The routine gets a line of input
from the keyboard, and checks for a line number.  If there is a line number,
the program branches to the routine that stores a line of program text.  If
there is no line number, it branches to the routine that executes statements.

42140         $A49C          MAIN1
Add or Replace a Line of Program Text

This routine calls subroutines to get the line number, tokenize keywords, and
then looks for a line with the same line number.
  If it finds a line with the same number, the routine deletes that line by
moving all higher program text and variables down to where it started.  The
new line is then added.  Since the CLR routine is called, the value of all
current program variables is lost.

42291         $A533          LINKPRG
Relink Lines of Tokenized Program Text

Each line of program text starts with a pointer to the address of the next
line (link address).  This routine scans each line to the end (which is marked
with a 0), and calculates the new link address by adding the offset to the
address of the current statement.

42336         $A560          INLIN
Input a Line to Buffer from Keyboard

This subroutine calls the Kernal CHRIN routine (61783, $F157) to obtain a line
of input from the current input device (usually the keyboard).  It stores the
characters in the BASIC text input buffer at 512 ($200) until a carriage
return or 89 characters have been received.  The keyboard device will never
return more than 80 characters before a carriage return, but other devices can
output a longer line.  An error will occur if the line goes over 80
characters.

42361         $A579          CRUNCH
Tokenize Line in Input Buffer

When a line of program text has been input into the BASIC text buffer at 512
($200), this routine goes through the line and changes any keywords or their
abbreviations, which do not appear in quotes, into their corresponding token.
This command is vectored through RAM at 772 ($304), so it can be diverted in
order to add new commands.

42515         $A613          FINDLN
Search for Line Number

This routine searches through the program text, trying to match the two-byte
integer line number that is stored in 20-21 ($14-$15).  If it is found, 95-96
($5F-$60) will be set as a pointer to the address of the link field for that
line, and the Carry flag will be set.  If it is not found, the Carry flag will
be cleared.

42562         $A642          SCRTCH
Perform NEW

The NEW command stores two zeros in the link address of the first program line
to indicate the end of program, and sets the end of program pointer at 45-46
($2D-$2E) to point to the byte past those zeros.  It continues through to the
CLR command code.

42590         $A65E          CLEAR
Perform CLR

The CLR command closes all I/O files with the Kernal CLALL routine (62255,
$F32F).  It eliminates string variables by copying the end of memory pointer
at 55-56 ($37-$38) to the bottom of strings pointer at 51-52 ($33-$34).  It
also copies the pointer to the end of BASIC program text at 49-50 ($31-$31) to
the pointer to the start of nonarray variables at 45-46 ($2D-$2E) and the
start of array variables at 47-48 ($2F-$30).  This makes these variables
unusable (although the contents of these areas are not actually erased).
RESTORE is called to set the data pointer back to the beginning, and the stack
is cleared.

42638         $A68E          RUNC
Reset Pointer to Current Text Character to the Beginning of Program Text

This routine resets the CHRGET pointer TXTPTR (122-123, $7A-$7B) so that the
next byte of text that the interpreter will read comes from the beginning of
program text.

52652         $A69C          LIST
Perform LIST

This routine saves the range of lines to be printed in pointers at 95-96 ($5F-
$60) and 20-21 ($14-$15), and then prints them out, translating any tokens
back to their ASCII equivalent.

42775         $A717          QPLOP
Print BASIC Tokens as ASCII Characters

This is the part of the LIST routine that chagnes one-byte program tokens back
to their ASCII text characters.  The routine is vectored through RAM at 774
($306), so it is possible to list out new command words that you have added by
changing this vector to detour through your own routine.

42818         $A742          FOR
Perform FOR

FOR is performed mostly by saving the needed information for the NEXT part of
the command on the stack (see the entry for 256 ($100) for details).  This
includes the TO termination value, so if the upper limit is a variable, the
current value of the variable will be stored, and you cannot end the loop
early by decreasing the value of the TO variable within the loop (although you
can end it early by increasing the value of the FOR variable within the loop).
  Also, since the TO expression is evaluated only once, at the time FOR is
performed, a statement such as FOR I=1 TO I+100 is valid.  The terminating
value is not checked until NEXT is executed, so the loop statements always
execute at least once.  The variable used by FOR must be a nonarray floating
point variable.  Reusing the same FOR variable in a loop that is still active
will cause the previous FOR loop and all intervening loops to be cancelled.

42926         $A7AE          NEWSTT
Set Up Next Statement for Execution

This routine tests for the STOP key, updates the pointer to the current line
number, and positions the text pointer to read the beginning of the statement.

42980         $A7E4          GONE
Read and Execute the Next Statement

This is the routine which gets the next token and executes the statement.  It
is vectored through RAM at 776 ($308) to allow the addition and execution of
new statement tokens.
  Since a statement must always start with a token or an implied LET
statement, this routine checks to see if the first character is a valid token.
If it is, the address is placed on the stack, so that a call to CHRGET will
return to the address of the code that executes the statement (see the table
of statement tokens at 40972 ($A00C)).
  An invalid token will cause a SYNTAX ERROR.  A character whose ASCII value
is less that 128 will cause LET to be executed.

43037         $A81D          RESTOR
Perform RESTORE

The RESTORE command simply resetes the DATA pointer at 65-66 ($41-$42) from
the start of BASIC pointer at 43-44 ($2B-$2V).

43052         $A82C
Test STOP Key for Break in Program

The Kernal STOP routine is called from here, and if the key is pressed, the
STOP (63213, $F6ED) command, below, is executed.

43055         $A831          END
Perform END

The current line number and text pointers are preserved for a possible CONT
command, and the READY prompt is printed.  If a STOP key break occured, the
BREAK message is printed first.

43095         $A857          CONT
Perform CONT

The CONT statement is performed by moving the saved pointers back to the
current statement and current text character pointers.  If the saved pointers
cannot be retrieved, the CAN'T CONTINUE error statement is printed.

43121         $A871          RUN
Perform RUN

RUN is executed by calling the Kernal SETMSG (65048, $FE18) routine to set the
message flag for RUN mode and performing a CLR to start the program.  If a
line followed RUN, a GOTO is executed after the CLR.

43139         $A883          GOSUB
Perform GOSUB

This statement pushes the pointers to the current text character and current
line onto the stack, along with a constant 141 ($8D) which identifies the
block as saved GOSUB information to be used by RETURN.  The GOTO is called.

43168         $A8A0          GOTO
Perform GOTO

This statement scans BASIC for the target line number (the scan starts with
the current line if the target line number is higher, otherwise it starts with
the first line).  When the line is found, the pointers to the current
statement and text character are changed, so that the target statement will be
executed next.

43218         $A8D2          RETURN
Perform RETURN

The RETURN statement finds the saved GOSUB data on the stack, and uses it to
restore the pointers to the current line and current character.  This will
cause execution to continue where it left off when GOSUB was executed.

43256         $A8F8          DATA
Perform DATA

DATA uses the next subroutine to find the offset to the next statement, and
adds the offset to the current pointers so that the next statement will be
executed.  If effect, it skips the statement, much like REM.

43270         $A906          DATAN
Search Program Text for the End of the Current BASIC Statement

This routine starts at the current byte of program text and searches until it
finds a zero character (line delimiter) or a colon character that is not in
quotes (statement delimiter).

43304         $A928          IF
Perform IF

IF uses the FRMEVL routine at 44446 ($AD9E) to reduce the expression which
follows to a single term.  If the expression evaluates to 0 (false), the
routine falls through to REM.  If it is not 0, GOTO or the statement following
THEN is executed.

43323         $A93B          REM
Perform REM

The REM statement is executed by skipping all program text until the beginning
of the next statement.  It is actually a part of the IF statement, which
continues for a few bytes after the REM part.

43339         $A94B          ONGOTO
Perform ON GOTO or ON GOSUB

ON is performed by converting the argument to an integer, and then skipping a
number between commas each time that the integer is decremented until the
argument reaches 0.  If a GOTO or GOSUB is the next token, the current number
between commas is used to execute one of those statements.  If the numbers
between commas are used up before the argument reaches 0, the statement has no
effect, and the next statement is executed.

43371         $A96B          LINGET
Convert an ASCII Decimal Number to a Two-Byte Binary Line Nmumber

This subroutine is used by several statements to read a decimal number,
convert it to a two-byte integer line number (in low-byte, high-byte format),
and check that it is in the correct range of 0-63999.

43429         $A9A5          LET
Perform LET

The LET command causes variables to be created and initialized, or to have a
new value assigned.  It handles all types of array or nonarray variables:
strings, floating point, integers, ST, TI, and TI$.  The routine is composed
of several subroutines that evaluate the variable, evaluate the assigned
expression, check that the assigned value is suitable for a variable of that
type, and then assign a value to the existing variable, or create a new
variable.

43648         $AA80          PRINTN
Perform PRINT#

The PRINT# statement calls CMD and then closes the output channel with the
Kernal CLRCHN routine (62259, $F333).

43654         $AA86          CMD
Perform CMD

This routine calls the Kernal CHKOUT routine (62032, $F250), and calls PRINT
to send any included text to the device.  Unlike PRINT# it leaves the output
channel open, so that output continues to go to that device.

43680         $AAA0          PRINT
Perform PRINT

The PRINT routine has many segments, which are required for the various
options which can be added to it:  TAB, SPC, comman, semicolon, variables, PI,
ST, TI, and TI$.  Eventually, all output is converted to strings, and the
Kernal CHROUT routine is called to print each character.

43806         $AB1E          STROUT
Print Message from a String Whose Address Is in the .Y and .A Registers

This part of the PRINT routine outputs a string whose address is in the
Accumulator (low byte) and .Y register (high byte), and which ends in a zero
byte.

43853         $AB4D          DOAGIN
Error Message Formatting Routines for GET, INPUT, and READ

43899         $AB7B          GET
Perform GET and GET#

The GET routine first makes sure that the program is not in direct mode.  It
opens an input channel using the Kernal CHKIN routine (61966, $F20E) if a
number sign was added to make GET#.  Then it calls the common I/O routines in
READ to get a single character, and causes the input channel to be closed if
one was opened.

43941         $ABA5          INPUTN
Perform INPUT#

This routine opens an input channel with the Kernal CHKIN routine, calls
INPUT, and then closes the channel with a CHKOUT routine (62032, $F250).
Extra data is discarded without an EXTRA IGNORED message, and a FILE DATA
ERROR message is issued when the data type is not suitable for the type of
variable used.

43967         $ABBF          INPUT
Perform INPUT

The INPUT routine checks to make sure that direct mode is not active, prints
prompts, receives a line of input from the device, and jumps to the common
code in READ that assigns the input to the variables which were named.

44038         $AC06          READ
Perform READ

This routine includes the READ command and common code for GET and INPUT.  The
READ command locates the next piece of DATA, reads the text, and converts it
to the appropriate type of data to be assigned to a numeric or string
variable.

44284         $ACFC          EXIGNT
ASCII Text for Input Error Messages

The text stored here is ?EXTRA IGNORED and ?REDO FROM START, each followed by
a carriage return and a zero byte.

44318         $AD1E          NEXT
Perform NEXT

NEXT is executed by finding the appropriate FOR data on the stack, adding the
STEP value to the FOR variable, and comparing the result to the TO value.  If
the loop is done, the stack entries for that FOR command are removed from the
stack.  If the loop hasn't reached its limit, the pointers to the current
statement and text character are updated from the FOR stack entry, which
causes execution to continue with the statement after the FOR statement.

44426         $AD8A          FRMNUM
Evaluate a Numeric Expression and/or Check for Data Type Mismatch

This routine can be called from different entry points to check the current
data against the desired data type (string or numeric) to see if they match.
If they don't, a TYPE MISMATCH error will result.

44446         $AD9E          FRMEVAL
Evaluate Expression

This is the beginning point of a very powerful group of subroutines which are
used extensively by BASIC.
  The main purpose of these routines is to read in the ASCII text of BASIC
expressions, separate the operators and terms of the expression, check them
for errors, combine the individual terms by performing the indicated
operations, and obtain a single value which the BASIC program can use.
  This can be a very complex task, and expressions an be of the string or
numeric type, and can contain any type of variable, as well as constants.
  At the end, the flag which shows whether the resulting value is string or
numeric at 13 ($D) is set, and if the value is numeric, the flag at 14 ($E) is
set as well, to show if it is an integer or floating point numer.

44675         $AE83          EVAL
Convert a Single Numeric Term from ASCII Text to a Floating Point Number

This routine reduces a single arithmetic term which is part of an expression
from ASCII text to its floating point equivalent.
  If the term is a constant, the routine sets the data type flag to number,
sets the text pointer to the first ASCII numeric character, and jumps to the
routine which converts the ASCII string to a floating point number.
  If the term is a variable, the variable value is retrieved.  If it is the PI
character, the value of PI is moved into the Floating Point Accumulator.
  This routine is vectored through RAM at 778 ($30A).

44712         $AEA8          PIVAL
PI Expressed as a Five-Byte Floating Point Number

The value of PI is stored here as a five-byte floating point number.

44785         $AEF1          PARCHK
Evaluate Expression Within Parentheses

This routine evaluates an expression within parentheses by calling the syntax
checking routines that look for opening and closing parentheses, and then
calling FRMEVL (4446, $AD9E) for each level of parentheses.

44791         $AEF7          CHKCLS
Check for and Skip Closing Parentheses

44794         $AEFA          CHKOPN
Check for and Skip Opening Parentheses

44799         $AEFF          CHKCOM
Check for and Skip Comma

This syntax checking device is the same in substance as the two checking
routines above.  It is used when the next character should be a comma.  If it
is not, a SYNTAX ERROR retults.  If it is, the character is skipped and the
next character is read.  Any character can be checked for and skipped this
way by loading the character into the Accumulator and entering this routine
from SYNCHR at 44799 ($AEFF).

44808         $AF08          SNERR
Print Syntax Error Message

44843         $AF2B          ISVAR
Get the Value of a Variable

44967         $AFA7          ISFUN
Dispatch and Evaluate a Function

If a BASIC function (like ASC("A")) is part of an expression, this routine
will use the function dispatch table at 42242 ($A502) to set up the address
of th proper function routine, and then branch to that routine.

45030         $AFE6          OROP
Perform OR

The OR routine sets the .Y register as a flag, and falls through to the AND
routine, which also performs OR.

45033         $AFE9          ANDOP
Perform AND

The AND routine changes the parameters to two-byte integer values, and
performs the appropriate logical operation (AND or OR).  A result of 0
signifies false, while a result of -1 signifies true.

45078         $B016          DORE1
Perform Comparisons

This routine does the greater than (>), less than (<), and equal (=)
comparisons for foating point numbers and strings.  The result in the Floating
Point Accumulator will be 0 if the comparison is false, and -1 if it is true.

45185         $B018          DIM
Perform DIM

This command calls the next routine to create an array for every variable
dimensioned (since a statement can take the form DIM A(12), B(13), C(14)...).
If the array element is referenced before a DIM statement (for example,
A(3)=4), the array will be dimensioned to 10 (as if DIM A(10) were executed).
Remember, DIMensioning an array to 10 really creates 11 elements (10).  The 0
element should always be considered in calculating the size to DIMension your
array.

45195         $B08B          PTRGET
Search for a Variable and Set It Up If It Is Not Found

This routine attempts to locate a variable by searching for its name in the
variable area.  If an existing variable of that name cannot be found, one is
created with the NOTFNS routine below.

45331         $B113
Check If .A Register Holds Alphabetic ASCII Character

This is part of the check for a valid variable name (it must start with an
alphabetic character).

45341         $B11D          NOTFNS
Create a New BASIC Variable

This routine makes space for a seven-byte descriptor by moving the variable
storage area seven bytes higher in memory, and then creates the descriptor.

45445         $B185          FINPTR
Return the Address of the Variable That Was Found or Created

This routine stores the address of the variable that was found or created by
the preceding routines in a pointer at 71-72 ($47-$48).

45460         $B194          ARYGET
Allocate Space for Array Descriptors

This routine allocates five bytes plus two bytes for every dimension specified
for the array descriptor.

45477         $B1A5          N32768
The Constant -32768 in Five-Byte Floating Point Format

This constant is used for range checking in the conversion of a floating
point number to a signed integer (the minimum inter value is -32768).

45482         $B1AA
Convert a Floating Point Number to a Signed Integer in .A and .Y Registers

This subroutine calls AYINT, below, which checks to make sure that the number
in the Floating Point Accumulator is between 32767 and -32768, and converts it
to a 16-bit signed integer in 100-101 ($64-$65), high byte first.  It leaves
the high byte of the integer in the Accumulator, and the low byte in the .Y
register.
  Although this routine does not appear to be referenced anywhere in BASIC,
the vector at locations 3-4 points to its address.  Presumably, it is provided
for the benefit of the user who wishes to pass parameters in a USR call, or
the like.

45490         $B1B2          INTIDX
Input and Convert a Floating Point Subscript to a Positive Integer

This routine converts a floating point subscript value to an integer, making
sure first that it is positive.

45503         $B1BF          AYINT
Convert a Floating Point Number to a Signed Integer

This subroutine first checks to make sure that the number in the Floating
Point Accumulator is between 32767 and -32768.  If it is not, an ILLEGAL
QUANTITY error results.  If it is, the routine converts it to a 16-bit signed
integer with the high byte in location 100 ($64), and the low byte in location
101 ($65).

45521         $B1D1          ISARY
Find Array Element or Create New Array in RAM

This routine searches for an array.  If it is found, the subscript value is
checked to see if it is valid, and pointers to the array and element of the
array are set.  If it is not found, the array is created, and the pointers
set.

45637         $B245          BSERR
Print BAD SUBSCRIPT Error Message

45640         $B248          FCERR
Print ILLEGAL QUANTITY Error Message

45900         $B34C          UMULT
Compute the Size of a Multidimensional Array

This routine calculates the size of a multidimensional array by multiplying
the dimensions.

45949         $B37D          FRE
Perform FRE

The FRE function calls the garbage collection routine at 46374 ($B526) to get
rid of unused string text, and calculates the difference between the bottom
of string text and the top of array storage.  It then drops through to the
follow routine, which assumes that the free memory value is a 16-bit signed
integer, and converts it to floating point accordingly.
  Of course, while the free memory space on the PET might have always been
32767 or less (the maximum value of a signed integer), sich is definitely not
the case on the 64.  Because conversion is from a signed integer, any memory
value over 32767 will be regarded as negative (the high bit is treated as a
sign bit).  Therefore, for these higher values you must add twice the bit
value of the high bit (65536) in order to come up with the correct value.  The
expression FRE(0)-6556*(FRE(0)<0) will always return the correct amount of
free memory.

45969         $B391          GIVAYF
Convert 16-Bit Signed Integer to Floating Point

This routine treats the value in the Accumulator as the high byte of a 16-bit
signed integer, and the value in the .Y register as the low byte, and converts
the signed integer into a floating point number in the Floating Point
Accumulator.
  The address of this routine is pointed to by the RAM vector at 5-6, and the
routine can be used to return an argument from the USR call in the Floating
Point Accumulator.

45982         $B39E          POS
Perform POS

The POS command calls the Kernal PLOT routine (58634, $E50A) to get the
position of the cursor on the logical line.  What it really does is an
equivalent of PEEK(211).  Remember, since we are dealing with a logical line,
this number can be over 39.  The statement "THIS SENTENCE IS LONGER THAN ONE
PHYSICAL LINE";POS(X) will return a value of 48 for the POS(X).

45990         $B3A6          ERRDIR
Check If the Program is Running in Direct Mode, and If So Issue an Error

This routine is called by statements that prohibit execution in direct mode.
It checks a flag that is set when a line without a linenumber is entered, and
causes an ILLEGAL DIRECT error if the flag is set.

46003         $B3B3          DEF
Perform DEF

DEF performs some syntax checking, and pushes five bytes onto the stack:  the
first byte of the function statement, a two-byte pointer to the dependent
variable (the X in FN(X)), and the address of the first character of the
definition itself, where it resides in the program text.
  The DEF statement must fit on one line, but functions can be extended by
nesting them (having one function call another).

46049         $B3E1          GETFNM
Check DEF and FN Syntax

This routine checks to make sure that FN follow SEG, and that the dependent
variable has a valid floating point variable name.  It calls the routine to
find or create a variable to get the pointer to its address.

46068         $B3F4          FNDOER
Perform FN

The FN evaluation is done by evaluating the FN argument (for example,
FN(A+B*C/D)) and then getting the rest of the expression from the text of the
function definition statement.  The function variable descriptor area is used
as a work area, and the dependent variable is not disturbed (so that if the
definition used FN(X), the value of X will not be changed by the function
call).

46181         $B465          STRD
Perform STR$

STR$ first checks to make sure that the parameter is a number, and then calls
the routines that convert floating point to ASCII and crate the pointers to a
string constant.

46215         $B487          STRLIT
Scan and Set Up Pointers to a String in Memory

This routine calculates the length of the string, and calls the routine that
allocates space in memory.  It then saves the string, or creates a pointer to
its location in the BASIC text input buffer at 512 ($200).

46324         $B4F4          GETSPA
Allocate Space in Memory for String

The amount of space needed for a string is passed to this routine, and the
routine checks if there is that amount of space available in free memory.  If
not, it does a garbage collection and tries again.

46374         $B526          GARBAG
String Garbage Collection

Whenever a string is changed in any way, the revised version of the text is
added to the bottom of the string text area, leaving the old version higher
up in memory, wasting space.
  In order to reclaim that space, the descriptor for every string whose text
is in the string text area (rather than in the program text area) must be
searched to find the valid text that is highest in memory.  If that string is
not as high as it could be, it is moved up to replace any string that is no
longer valid.  Then all of the string descriptors must be searched again to
find the next highest string and move it up.  This continues until every
string that is un use has been covered.  After all have been moved up, the
pointer to the bottom of string text at 51-52 ($33-$34) is changed to show
the new bottom location.
  If there are more than a few strings whose text is in the string text
storage area, rather than in the body of the program, scanning every string
as many times as there are strings can take an awful lot of time.  The
computer may seem as if it had died (the STOP key is not even checked during
the procedure).
  The collection will take about as long whether there is any spare space or
not; the full collection will be done even if it is done immediately after
the last collection.  Although the increased memory capacity of the 64 helps
to forestall the need for garbage collection, a large program with many
string arrays may still experience lengthy collection delays.

46525         $B5BD
Check for Most Eligible String to Collect

This part of the garbage collection routine checks to see if the current
string is the highest in memory.

46598         $B606
Collect a String

This part of the garbage collection routine moves the string to high memory
and updates the descriptor to point to its new location.

46653         $B63D          CAT
Concatenate Two Strings

This routine is used to add the text of one string onto the end of another
(A$+B$).  Error checking is done to see if the length of the combined string
is within range, the allocation routine is called to allocate space, and the
new string is built at the bottom of the string text area.

46714         $B67A          MOVINS
Move a String in Memory

This is the routine which is used to move a string to the bottom of the string
text area for the above routine.  It is generally used as a utility routine to
move strings.

46755         $B6A3          FRESTR
Discard a Temporary String

This routine calls the following routine which clears an entry from the
temporary descriptor stack.  If the descriptor was on the stack, it exits
after setting pointers to the string and its length.  If it wasn't on the
temporary stack and is at the bottom of string text storage, the pointer to
the bottom is moved up to deallocate the string.

46811         $B6DB          FRETMS
Remove an Entry from the String Descriptor Stack

If the descriptor of a currently valid string is the same as one of the
entries on the temporary string descriptor stack, the stack entry is removed.

46828         $B6EC          CHRD
Perform CHR$

The CHR$ routine creates a descriptor on the temporary string stack for the
one-byte string whose value is specified in the command, and sets a pointer to
that string.

46848         $B700          LEFTD
Perform LEFT$

LEFT$ creates a temporary string descriptor for a new string which contains
the number of characters from the left side of the string that is specified in
the command.

46892         $B72C          RIGHTD
Perform RIGHT$

RIGHT$ manipulates its parameters so that the tail end of LEFT$ can be used to
create a temporary string descriptor for a new string.  This new string
contains the number of characters from the right side of the string that is
specified in the command.

46903         $B737          MIDD
Perform MID$

MID$ manipulates its parameters so that the tail end of LEFT$ can be used to
create a temporary string descriptor for a new string.  This new string
contains the number of characters from the position in the middle of the
string that is specified in the command.

46945         $B761          PREAM
Pull String Function Parameters from Stack for LEFT$, RIGHT$, and MID$

This routine is used to obtain the first two parameters for all three of these
commands.

46972         $B77C          LEN
Perform LEN

The LEN function is performed by obtaining the string length from the
descriptor and converting it to a floating point number.

46987         $B78B          ASC
Perform ASC

This routine gets the first character of the string in the .Y register (if
it's not a null string).  Then it calls the part of POS that converts a one-
byte integer in .Y to a floating point number.

47003         $B79B          GETBYTC
Input a Parameter Whose Value Is Between 0 and 255

This routine reads numeric ASCII program text, converts it to an integer,
checks that it is in the range 0-255, and stores it in the .X register.  This
routine can be useful for reading parameters from a USR statement or new
commands.

47021         $B7AD          VAL
Perform VAL

The VAL routine obtains the string pointer, and reads the string one character
at a time until an invalid character is found (ASCII numbers, sign character,
a single decimal point, exponent, and spaces are all valid).  Then the string
is changed to floating point.  If no valid characters are found, a 0 is
returned.

47083         $B7EB          GETNUM
Get a 16-Bit Address Parameter and an 8-Bit Parameter (for POKE and WAIT)

This routine gets the next numeric parameter from the current place in program
text.  The routine evaluates it, checks that it is a positive integer within
the range 0-65535, and changes it from floating point to a two-byte integer
in 20-21 ($14-$15).  It checks for and skips a comma, then gets a one-byte
integer parameter in the .X register.  The routine is used to get the
parameters for POKE an WAIT.

47095         $B7F7          GETADR
Convert a Floating Point Number to an Unsigned Two-Byte Integer

This routine checks the number in the Floating Point Accumulator to make sure
that it is a positive number less than 65536, and then calls the subroutine
which conerts floatin point to integer.  It is used to get address parameters,
for commands such as PEEK.

47117         $B80D          PEEK
Perform PEEK

PEEK reads the address parameter and converts it to a pointer.  Then it gets
the byte pointed to into the .Y register, and calls the part of POS that
converts a single integer in .Y to a floating point number.

47140         $B824          POKE
Perform POKE

POKE gets a pointer to the address parameter, and stores the next parameter
there.

47149         $B82D          FUWAIT
Perform WAIT

WAIT gets an address parameter and an integer parameter to use as a mask.
WAIT then looks for an optional parameter to use as a pattern for the
exclusive OR.  Then, the address location is read, its value is exclusive ORed
with the optional pattern value (or 0 if there is none).  This value is ANDed
with the mask value.  The command loops continuously until the result is not-
zero.
  The purpose of this command is to allow the program to watch a location
which can be changed by the system or by outside hardware (such as the
software clock or keycode value locations).
  The AND function lets you check if a bit changes from 0 to 1, while the EOR
function allows you to check if a bit changes from 1 to 0.  For more
information, see the article "All About the Wait Instruction," by Louis Sander
and Doug Ferguson, in COMPUTE!'s First Book of Commodore 64.

47177         $B849          FADDH
Add .5 to Contents of Floating Point Accumulator #1

47184         $B850          FSUB
Subtract FAC1 from a Number in Memory

This routine is used to subtract the Floating Point Accumulator from a number
in memory.  It moves the number in memory into FAC2, and falls through to the
next routine.

47187         $B853          FSUBT
BASIC's Subtraction Operation

This routine subtracts the contents of FAC2 from FAC1 by complementing its
sign and adding.

47207         $B867          FADD
Add FAC1 to a Number in Memory

This routine is used to add the contents of the Floating Point Accumulator
(FAC1) to a number in memory, by moving that number into FAC2, and falling
through to the next routine.

47210         $B86A          FADDT
Perform BASIC's Addition Operation

This routine adds the contents of FAC1 and FAC2 and stores the results in
FAC1.

47271         $B8A7          FADD4
Make the Result Negative If a Borrow Was Done

47358         $B8FE          NORMAL
Normalize Floating Point Accumulator #1

47431         $B947          NEGFAC
Replace FAC1 with Its 2's Complement

47486         $B97E          OVERR
Print Overflow Error Message

47491         $B983          MULSHF
SHIFT Routine

47548         $B9BC          FONE
Floating Point Constant with a Value of 1

This five-byte floating point representation of the number 1 is stored here
for use by the floating point routines.  It is also used as the default STEP
value for the FOR statement.

47553         $B9C1          LOGCN2
Table of Floating Point Constants for the LOG Function

This table of eight numeric constants in five-byte floating point
representation is used by the LOG function.

47594         $B9EA          LOG
Perform LOG to Base E

The LOG to the base e of the number in FAC1 is performed here, and the result
left in FAC1.

47656         $BA28          FMULT
Multiply FAC1 with FAC2

This routine multiplies the contents of FAC1 by the contents of FAC2 and
stores the result in FAC1

47705         $BA59          MLTPLY
Multiply a Byte Subroutine

This subroutine is used to repetitively add a mantissa byte of FAC2 to FAC1
the number of times specified in the .A register.

47756         $BA8C          CONUPK
Move a Floating Point Number from Memory into FAC2

This subroutine loads FAC2 from the four-byte number (three mantissa and one
sign) pointed to by the .A and .Y registers.

47799         $BAB7          MULDIV
Add Exponent of FAC1 to Exponent of FAC2

47828         $BAD4          MLDVEX
Handle Underflow or Overflow

47842         $BAE2          MUL10
Multiply FAC1 by 10

This subroutine is called to help convert a floating point number to a series
of ASCII numerals.

47865         $BAF9          TENC
The Constant 10 in Five-Byte Floating Format

47870         $BAFE          DIV10
Divide FAC1 by 10

47887         $BB0F          FDIV
Divide a Number in Memory by FAC1

This number in memory is stored to FAC2, and this routine falls through to the
next.

47890         $BB12          FDIVT
Divide FAC2 by FAC1

This routine is used to divide the contents of FAC2 by the contents of FAC1,
with the result being stored in FAC1.  A check for division by 0 is made
before dividing.

48034         $BBA2          MOVFM
Move a Floating Point Number from Memory to FAC1

This routine loads FAC1 with the five-byte floating point number pointed to by
the address stored in the Accumulator (low byte) and the .Y register (high
byte).

48071         $BBC7          MOV2F
Move a Floating Point Number from FAC1 to Memory

This routine is used to move a number from the Floating Point Accumulator
(FAC1) to memory at either 92-96 ($5C-$60) or 87-91 ($57-$5B), depending on
the entry point to the routine.

48124         $BBFC          MOVFA
Move a Floating Point Number from FAC2 to FAC1

48140         $BC0C          MOVAF
Round and Move a Floating Point Number from FAC1 to FAC2

48143         $BC0F          MOVEF
Copy FAC1 to FAC2 Without Rounding

48155         $BC1B          ROUND
Round Accumulator #1 by Adjusting the Rounding Byte

If doubling the rounding byte at location 112 ($70) makes it greater than 128,
the value of FAC1 is increased by 1.

48171         $BC2B          SIGN
Put the Sign of Accumulator #1 into .A Register

On exit from this routine the Accumulator will hold a 0 if FAC1 is 0, a 1 if
it is positive, and a value of 255 ($FF) if it is negative.

48185         $BC39          SGN
Perform SGN

The SGN routine calls the above routine to put the sign of FAC1 into .A, and
then converts that value into a floating point number in FAC1.

48216         $BC58          ABS
Perform ABS

The FAC1 sign byte at 102 ($66) is shifted right by this command, so that the
top bit is a 0 (positive).

48219         $BC5B          FCOMP
Compare FAC1 to Memory

On entry to this routine, .A and .Y point to a five-byte floating point number
to be compared to FAC1.  After the comparison, .A holds 0 if the two are
equal, a 1 if the value of FAC1 is greater than that in the memory location,
and 255 ($FF) if the value of FAC1 is less than that in the memory location.

48283         $BC9B          QINT
Convert FAC1 into Integer Within FAC1

This routine converts the value in FAC1 into a four-byte signed integer in 98-
101 ($62-$65), with the most significant byte first.

48332         $BCCC          INT
Perform INT

This routine removes the fractional part of a floating point number by calling
the routine above to change it to an integer, and then changing the integer
back to floating point format.

48371         $BCF3          FIN
Convert an ASCII String to a Floating Point Number FAC1

This routine is called by VAL to evaluate and convert an ASCII string to a
floating point number.

48510         $BD7E          FINLOG
Add Signed Integer to FAC1

This routine is used to add an ASCII digit that has been converted to a signed
integer to FAC1.

48563         $BDB3          NO999

This table of three floating point constants holds the values 99,999,999.5,
999,999,999.5 and 1,000,000,000.  These values are used in converting strings
to floating point numbers.

48576         $BDC0          INPRT
Print IN Followed by a Line Number

48589         $BDCD          LINPRT
Output a Number in ASCII Decimal Digits

This routine is used to output the line number for the routine above.  It
converts thenumber whose high byte is in .A and whose low byte is in .X to a
floating point number.  It also calls the routine below, which converts the
floating point number to an ASCII string.

48605         $BDDD          FOUT
Convert Contents of FAC1 to ASCII String

This routine converts a floating point number to a string of ASCII digits,
and sets a pointer to the string in .A and .Y.

48913         $BF11          FHALF
The Constant Value 1/2 in Five-Byte Floating Point Notation

This constant is used for rounding and SQR.

48924         $BF1C          FOUTBL
Powers of Minus Ten Constants Table

This table contains the powers of -10 expressed as four-byte floating point
numbers (that is, -1; +10; -100; +1000; -10,000; +100,000; -1,000,000;
+10,000,000; and -100,000,000).

48954         $BF3A          FDCEND
Table of Constants for TI$ Conversion

This table contains the floating point representation of the powers of -60
multiplied by 1 or 10.  These constants are used for converting TI$ to ASCII.

48978         $BF52
Unused area

This unused area is filled with byts of 170 ($AA).

49009         $BF71          SQR
Perform SQR

This routine moves the contents of FAC1 to FAC2, moves the constant 0.5 to
FAC1, and falls through to the exponentation routine.

49019         $BF7B          FPWRT
Performs Exponentation (Power Calculation Called for by UPARROW)

This routine raises the value in FAC2 to the power in FAC1 and leaves the
result in FAC1.

49076         $BFB4          NEGOP
Perform NOT and >

This negates the Floating Point Accumulator by exclusive ORing the sign byte
with a constant of 255 ($FF).  Zero is left unchanged.  The results of this
command follow rom the formula NOT X=-(X+1).  Therefore, if you NOT a
tatement that is true (-1), you get 0 (false).

49087         $BFBF          EXPCON
Table of Constants for EXP and LOG in Five-Byte Floating Point Format

These tables are used to calculate 2 to the N power.

49133         $BFED          EXP
Perform EXP

This routine calculates the natural logarithm e (2.718281828...) raised to the
power in FAC1.  The result is left in FAC1.
  This routine is split between the BASIC ROM wich ends at 49151 ($BFFF) and
the Kernal ROM which begins at 57344 ($E000).  Therefore, a JMP $E000
instruction is tacked on to the end, which makes the BASIC routines in the 64
Kernal ROM three bytes higher in memory than the corresponding VIC-20
routines.


49152-53247   $C000-$CFFF
4K Free RAM

Locations 49152 to 53247 ($C000 to $CFFF) are free RAM.  Since this area is
not contiguous with the BASIC program text RAM area, it is not available for
BASIC program or variable storage (it is not counted in the FRE(0) total).
  This area is fully available for any other use, however, sudh as storing
machine language subroutines for use with BASIC, alternate I/O drivers for
parallel or IEEE devices, character graphics or sprite data, etc.
  This large free area is such a tempting spot for system additions that many
such applications may be competing for the same RAM space.  For example, the
Universal Wedge DOS Support program that adds easy access to the disk
communications channel is usually loaded at 52224 ($CC00).  Programs that use
that part of RAM will therefore overwrite the DOS support program, with the
result that they may not run correctly, or even at all.  Likewise, Simon's
BASIC, the extended language which Commodore has released on cartridge, uses
several locations in this range.  Be aware of this potential problem when you
buy hardware additions that use this spot to hook into the system.


::::::::::::::::::::
::   Chapter 6    ::
::                ::
::VIC-II, SID, I/O::
:: Devices, Color ::
::    RAM, and    ::
:: Character ROM  ::
::::::::::::::::::::

53248-57343   $D000-$DFFF

This 4K block of memory is used for several key functions.  Normally, the 6510
microprocessor addresses the two Complex Interface Adapter (CIA) Input/Output
chips here, along with the VIC-II video controller chip, the Sound Interface
Device (SID) music synthesizer, and the Color RAM.
  Alternatively, the 6510 can address the character ROM here (though normally
only the VIC-II chip has access to it).  Finally, there is also 4K of RAM
here, although to use it may require banking it in only when necessary, as the
I/O devices are needed for such niceties as reading he keyboard, and updating
the screen display.
  It will appear from the map of the I/O devices below that many of the
locations are not accounted for.  That is beause these devices tie up more
addressing space than they actually use.  Each of them uses only a few
addresses, mostly on the bit level.
  The missing addresses either consist of images of the hardware registers, or
cannot be addressed in this configuration.  In addition, some address space is
left open for the use of future hardware devices which might be plugged into
the expansion port, like the CP/M card.
  As mentioned above, memory usage by these I/O devices is to intensive that
to work with them often requires that you turn individual bits on and off.
Here is a quick reminder of how to manipulate bits.
  The bit values for each bit are:

Bit 0 = 1
Bit 1 = 2
Bit 2 = 4
Bit 3 = 8
Bit 4 = 16
Bit 5 = 32
Bit 6 = 64
Bit 7 = 128

To set a bit to 1 from BASIC, POKE address, PEEK(address) OR Bitvalue.  To
reset a bit to 0 from BASIC, POKE address, PEEK(address) AND 255-Bitvalue.

53248-53294   $D000-$D02E
VIC-II Chip Registers

The Video Interface Controller (VIC-II chip) is a specially designed processor
that is in charge of the 64's video display.  It is this chip which makes
possible the 64's wide range of graphics capabilities.
  The VIC-II chip's ability to address memory is independent of the 6510
microprocessor.  It can address only 16K at a time, and any of the four blocks
of 16K can be chosen for video memory.  The system default is for it to use
the first 16K.
  All of the video display memory, character dot data, and sprite shapes must
be stored within the chosen 16K block.  Locations 53248-53294 ($D000-$D02E)
are registers which allow the user to communicate with the VIC-II chip.
Although for the most part they can be written to and read like ordinary
memory locations, their contents directly control the video display.  Since
many of these locations work in close conjunction with others, a general
overview of some of the different graphics systems on the 64 is in order.
  The most familiar type of graphics display is the ordinary text that appears
when you turn the machine on.  The area of RAM which is displayed on the
screen is determined by the Video Matrix Base Address Nybble of the VIC-II
Memory Control Register (53272, $D018).  The address of the dot-data which is
used to assign a shape to each text character based on an 8 by 8 matrix of lit
or unlit dots is determined by the other half of the Memory Control Register
at 53272 ($D018).  More information on how the data is used to represent the
character shapes may be found at the alternate entry for 49152 ($C000), the
Character Generator ROM.
  Text character graphics may employ one of the two sets of text and graphics
characters in the Character Generator ROM, or the user may substitute a
completely different set of graphics or text characters in RAM.
  Normally, the text graphics screen uses a background color which is common
to all text characters, and that value is stored in Background Color Register
0 (53281, $D021).  The color of the frame around the screen is determined by
the Border Color Register at 53280 ($D020).
  The color of each character is determined by one nybble of the Color RAM
which starts at 55296 ($D800).  There are, however, two variations which alter
this scheme somewhat.
  The first is called multicolor text mode, and is set by Bit 4 of 53270
  ($D016).  Instead of each bit selecting either the foreground or the
background color for each dot in the character, bit-pairs are used to select
one of four colors for each double-width dot.  This results in the horizontal
resolution being cut to four dots across per character, but allows two extra
colors to be introduced from Background Color Registers 1 and 2 (53282-53283,
$D022-$D023).
  The other text mode is called Extended Background Color Mode.  In this mode,
the foreground color is always selected by the Color RAM.  The background
color depends on the actual screen code of the character.  In this mode, only
the first 64 character shapes are available, but each can have one of four
different background colors.
  The background color for each character is determined by its screen code as
follows:

1.  If the screen code is from 0-63 (this includes the normal alphanumerics),
the value in Background Color Register 0 (53281, $D021) will determine the
background color, as is usual.
2.  Characters with codes 64-255 will have the same shape as the corresponding
character in the group with codes 0-63.
3.  For characters with codes 64-127 (SHIFTed characters), the background
colors are deterined by the value in Background Color Register 1 (53282,
$D022).
4.  The value in Background Color Register 2 (53283, $D023) is used for
characters with codes 128-191 (reversed alphanumerics).
5.  For characters with codes 192-255, the value in Background Color Register
3 (53284, $D024) is used to determine the background color.

  In place of the normal text mode, a bitmap graphics mode is also abailable
by setting Bit 5 of location 53265 ($D011).  In this mode, each bit of data
determines whether one dot on the screen will be set to either the background
color or foreground color.  Within an 8 by 8 dot area, the foreground and
background colors may be individually selected.
  The bitmap area is 320 dots wide and 200 dots high.  The area which contains
the graphics data, the bitmap, is determined by the Character Dot Data Base
Address in the lower nybble of the VIC-II Memory Control Register (53272,
$D018).  The Video Matrix Base Address in the upper nybble, which normally
determines which area of memory will be displayed, instead determines where
the color memory for each 8 by 8 ground of dots will be located.
  The Color RAM is not used for high-resolution bitmap graphics.  But
multicolor mode is also available for bitmap graphics, and it uses the Color
RAM to determine the foreground color of each dot.
  As with multicolor text mode, the horizontal resolution is but in half (to
160 dots across), so that in addition to the foreground and background colors,
each dot can be one of two other colors as well.  This mode gets the value for
the two extra colors from the two nybbles of each byte of bitmap color memory,
the location of which is determined by the Video Matrix Base Address.
  Multicolor text mode offers four colors, three of which will be common to
all characters, and one of which can be selected individually.  Multicolor
bitmap mode offers a choice of four colors, three of which can be individually
selected within an 8 by 8 dot area.
  The 64 also contains an entirely separate graphics system, whose character
shapes, colors, and positions are derived and displayed without any reference
to the Video Matrix and Character Dot-Data addresses.  Best of all, these
characters may be moved quickly and easily to any position on the screen,
greatly facilitating games and animated graphics of all types.  This system is
known as sprite graphics.
  Sprite graphics takes its name from the graphics characters it displays,
each of which is called a sprite.  There are eight sprites, known as Sprites
0-7.  Each sprite character is 24 dots wide by 21 dots high.  This is about
eight times as large as a regular text character, which is only 8 dots wide by
8 dots high.
  A sprite takes its shape from 63 bytes of data in one of the 256 data
blocks, each 64 bytes long, that can fit into the 16K space which the VIC-II
chip can address.  The block currently assigned to any given sprite is
determined by the Sprite Data Pointers, which are located at the last eight
bytes of the screen memory area (the default locations are 2040-2047,
$7F8-$7FF).
  The first Sprite Data Pointer determines the data block used for the shape
of Sprite 0, the second for the shape of Sprite 1, etc.  The number in the
pointer times 64 equals the address of the first byte of the data block within
the VIC-II addressing range.
  For example, using the default values for VIC-II addressing area and screen
memory, a value of 11 in location 2040 ($7F8) would mean that the shape of
Sprite0 is determined by the data in the 63-byte block starting at location
704 (11*64).  It should be noted that it is possible for more than one sprite
to take its shape data from the same block, so that only 64 bytes of data are
required to create eight sprites, each having the same shape.
  The dot patterns of each sprite correspond to the bit patterns of the sprite
shape data.  Each byte of shape data in memory consists of a number from 0 to
255.  This number can be represented by eight binary digits of 0 or 1.
  Each binary digit has a bit value that is two times greater than the last.
If the digit in the zero bit place is a 1, it has a value of 1 (we count bit
places from 0 to 7).  A 1 in the first bit place has a value of 2, the second
bit has a value of 4, the third has a value of 8, the fourth has a vlue of 16,
the fifth a value of 32, the sixth a value of 64, and the seventh a value of
128.
  By making all of the possible combinations of 0's and 1's in all eight bit
places, and adding the bit values of every bit place that contains a 1, we can
represent every number from 0 to 255 as a series of 1's and 0's.
  If you think of every 0 as a dot having the same color as the background,
and every 1 as a dot which is the color of the sprite, you can see how a
series of bytes could be used to represent the sprite shape.
  Since each line of the sprite is 24 dots wide, it takes 3 bytes of memory
(24 bits) per line to portray its shape.  Let's take a look at a couple of
sample sprite lines.

00000000 01111110 00000000 = 0, 126, 0

As you can see, the first and last bytes are all 0's, so nothing will be
displayed there.  The middle byte has six 1's, so it will be displayed as a
line six dots long.  By adding the values of these dix bits (64+32+16+8+4+2),
we get a byte value of 126.  Let's try another line.

00011111 11111111 11111000 = 21, 255, 248

The first byte has five bits set to 1, having values of 16, 8, 4, 2, and 1,
for a total of 31.  The second byte has all bits set to 1, so it has the
maximum value of 255.  The third byte also has five bits set to 1, having
values of 128, 64, 32, 16, and 8, for a total of 248.  The result is that this
line of sprite data will display a line that is 18 dots long.
  We can put these two kinds of lines together to show how a large cross might
be drawn using bytes of sprite data.

000000000000000000000000 = 0, 0, 0
000000000000000000000000 = 0, 0, 0
000000000111111000000000 = 0, 126, 0
000000000111111000000000 = 0, 126, 0
000000000111111000000000 = 0, 126, 0
000000000111111000000000 = 0, 126, 0
000000000111111000000000 = 0, 126, 0
000000000111111000000000 = 0, 126, 0
000000000111111000000000 = 0, 126, 0
000111111111111111111000 = 21, 255, 248
000111111111111111111000 = 21, 255, 248
000111111111111111111000 = 21, 255, 248
000000000111111000000000 = 0, 126, 0
000000000111111000000000 = 0, 126, 0
000000000111111000000000 = 0, 126, 0
000000000111111000000000 = 0, 126, 0
000000000111111000000000 = 0, 126, 0
000000000111111000000000 = 0, 126, 0
000000000111111000000000 = 0, 126, 0
000000000000000000000000 = 0, 0, 0
000000000000000000000000 = 0,0,0

The 63 numbers, displayed three per line opposite the bit patters they
represent, are the values that would have to be put in the sprite shape data
area in order to display this cross using sprite graphics.
  Even after the sprite shape data has been placed in memory, and the Sprite
Data Pointer has been set to display that block of data bytes as the sprite
shape, there are still several steps that must be taken in order to display
the sprite on the screen.
  The proper bit of the Sprite Display Enable Register at 53269 ($D015) must
be set to 1 in order to turn on the sprite display.  A horizontal and vertical
screen position must be selected for the sprite by means of the horizontal and
vertical position registers (53248-53264, $D000-$D010).  Finally, the color
value of the sprite should be placed in the appropriate Sprite Color Register
(53287-53294, $D027-$D02E).
  Once you have the sprite on the screen, animation is fairly simple to
achieve.  Moving the sprite is as easy as changing the values in the sprite
position registers.  Changing the sprite shape can be accomplished by merely
changing the Sprite Data Pointer to point to another block of shape data in
memory.
  There are also some optional sprite graphics features available which
enhance its flexibility.  Sprite expand registers allow you to make each
sprite twice as wide as normal, twice as tall, or both.  Collision detection
registers let you know when a sprite shape overlaps a regular text character
or bitmap dot, or if two sprites are touching.
  If a sprite is positioned in the same place on the screen as a text
character or bitmap dot, a Priority Register allows you to choose whether the
sprite or the normal graphics will by displayed.  This enables three-
dimensional effects by letting you choose whether the sprite goes in front of 
or behind other objects on the screen.
  Finally, any sprite may be selected for multicolor display, using the
register at location 53276 ($D01C).  In this mode, as in multicolor text and
bitmap modes, pairs of bits are used to determine the color of each double-
width dot.  The possible color values which may be selected are those of
Background Color Register 0, the Sprite Color Register, or the two color
values in the Sprite Multicolor Registers at 53285-53286 ($D025-$D026).

Location Range: 53248-53264 ($D000-$D010)
Sprite Horizontal and Vertical Position Registers

These locations determine the horizontal and vertical position at which each
sprite will be displayed on the screen.  Each sprite has its own horizontal
and vertical position register.  In addition, all of the sprites share a
common register which is used to extend the range of horizontal positions.
  Vertical positions for each sprite range from 0 to 255, and these indicate
the vertical position of the top line of the sprite's 21-line length.  Since
there are only 200 visible scan lines in the screen display, some of these
vertical positions will result in the sprite being partially or wholly
offscreen.
  The visible viewing area starts at line 50 and extends to line 249.
Therefore, any sprite whose vertical psition is 29 ($1D) or less will be
completely above the visible picture.  At vertical position 30 ($1E), the
bottom line of the sprite display becomes visible at the top of the screen.
At position 230 ($E6), the bottom line of the sprite is lost from view off the
bottom of the screen, and at vertical position 250 ($FA), the entire sprite
disappears from view off the bottom edge of the screen.
  Horizontal positioning is somewhat trickier, because the visible display
area is 320 dots wide, and one eight-bit register can hold only 256 position
values.  Therefore, an additional register is needed to hold the ninth bit of
each sprite's horizontal position.
  Each sprite is assigned a single bit in the Most Significant Bit of
Horizontal Position register (MSB register) at 53264 ($D010).  If that bit is
set to 1, the value 256 is added to the horizontal position.  This extends the
range of possible horizontal positions to 511.
  In order to set a sprite's horizontal position, you must make sure that both
the values in the horizontal position register and the MSB Register are
correct.  For example, if you wish to set the horizontal position of Sprite 5
to a value of 30, you must place a value of 30 in the Sprite 5 Horizontal
Position Register (POKE 53258,30 will do it from BASIC), and you must also
clear Bit 5 of the MSB Register (POKE 53264,PEEK(53264)AND(255-16)).  If you
forget the MSB register, and Bit 5 is set to 1, you will end up with position
286 instead of 30.
  The horizontal position value indicates the position of the leftmost dot of
the sprite's 24-dot width.  The visible display is restricted to the 320 dot
positions between positions 24 and 344.  At position 0 the whole sprite is
past the left edge of the visible screen.  At position 1 the righmost dot
enters the display area, and at position 24 ($18) the entire sprite is
displayed on screen.  At position 321 ($141) the rightmost dot goes past the
right edge of the visible display area, and a position 355 ($158) the whole
sprite has moved out of sight, off the right edge of the screen.
  These registers are all intialized to 0 at power-up.

53248         $D000          SP0X
Sprite 0 Horizontal Position

53249         $D001          SP0Y
Sprite 0 Vertical Position

53250         $D002          SP1X
Sprite 1 Horizontal Position

53251         $D003          SP1Y
Sprite 1 Vertical Position

53252         $D004          SP2X
Sprite 2 Horizontal Position

53253         $D005          SP2Y
Sprite 2 Vertical Position

53254         $D006          SP3X
Sprite 3 Horizontal Position

53255         $D007          SP3Y
Sprite 3 Vertical Position

53256         $D008          SP4X
Sprite 4 Horizontal Position

53257         $D009          SP4Y
Sprite 4 Vertical Position

53258         $D00A          SP5X
Sprite 5 Horizontal Position

53259         $D00B          SP5Y
Sprite 5 Vertical Position

53260         $D00C          SP6X
Sprite 6 Horizontal Position

53261         $D00D          SP6Y
Sprite 6 Vertical Position

53262         $D00E          SP7X
Sprite 7 Horizontal Position

53263         $D00F          SP7Y
Sprite 7 Vertical Position

53264         $D010          MSIGX
Most Significant Bits of Sprites 0-7 Horizontal Position

Bit 0:  Most significant bit of Sprite 0 horizontal position
Bit 1:  Most significant bit of Sprite 1 horizontal position
Bit 2:  Most significant bit of Sprite 2 horizontal position
Bit 3:  Most significant bit of Sprite 3 horizontal position
Bit 4:  Most significant bit of Sprite 4 horizontal position
Bit 5:  Most significant bit of Sprite 5 horizontal position
Bit 6:  Most significant bit of Sprite 6 horizontal position
Bit 7:  Most significant bit of Sprite 7 horizontal position

Setting one of these bites to 1 adds 256 to the horizontal position of the
corresponding sprite.  Resetting one of these bits to 0 restricts the
horizontal position of the corresponding sprite to a value of 255 or less

53265         $D011          SCROLY
Vertical Fine Scrolling and Control Register

Bits 0-2:  Fine scroll display vertically by X scan lines (0-7)
Bit 3:  Select a 24-row or 25-row text display (1=25 rows, 0=24 rows)
Bit 4:  Blank the entire screen to the same color as the background (0=blank)
Bit 5:  Enable bitmap graphics mode (1=enable)
Bit 6:  Enable extended color text mode (1=enable)
Bit 7:  High bit (Bit 8) of raster compare register at 53266 ($D012)

This is one of the two important multifunction control registers on the VIC-II
chip.  Its defaule value is 155, which sets the high bit of the raster compare
to 1, selects a 25-row display, disables the blanking feature, and uses a
vertical scrolling offset of three scan lines.
  Bits 0-2.  These bits control vertical fine scrolling of the screen display.
This feature allows you to move the entire text display smoothly up and down,
enabling the display area to act as a window, scrolling over a larger text or
character graphics display.
  Since each row of text is eight scan lines high, if you simply move each
line of text up one row, the characters travel an appreciable distance each
time they move, which gives the motion a jerky quality.  This is called coarse
scrolling, and you can see an example of it when LISTing a program that is too
long to fit on the screen all at one time.
  By placing a number from 1 to 7 into these three bits, you can move the
whole screen display down by from 1 to 7 dot spaces.  Stepping through the
values 1 to 7 allows you to smoothly make the transition from having a
character appear in one row on the screen to having it appear in the next row.
To demonstrate this, type in the following sample program, LIST it, and RUN.

10 FOR I= 1 TO 50:FOR J=0 TO 7
20 POKE 53265, (PEEK(53265)AND248) OR J:NEXTJ,I
30 FOR I= 1 TO 50:FOR J=7 TO 0 STEP-1
40 POKE 53265, (PEEK(53265)AND248) OR J:NEXTJ,I

As you can see, after the display has moved seven dot positions up or down, it
starts over at its original position.  In order to continue the scroll, you
must do a coarse scroll every time the value of the scroll bits goes from 7 to
0, or from 0 to 7.  This is accomplished by moving the display data for each
line by 40 bytes in either direction, overwriting the data for the last line,
and introducing a line of data at the opposite end of screen memory to replace
it.  Obviously, ony a machine language program can move all of these lines
quickly enough to maintain the effect of smooth motion.  The following BASIC
program, however, will give you an iea of what vertical fine scrolling is
like:

10 POKE 53281,0:PRINTCHR$(5);CHR$(147)
20 FORI=1 TO 27:
30 PRINTTAB(15)CHR$(145)"            ":POKE 53265,PEEK(53265)AND248
40 WAIT53265,128:PRINTTAB(15)"I'M FALLING"
50 FOR J=1 TO 7
60 POKE53265,(PEEK(53265)AND248)+J
70 FORK=1TO50
80 NEXT K,J,I:RUN

  Bit 3.  This bit register allows you to select either the normal 25-line
text display (by setting the bit to 1), or a shortened 24-row display (by
resetting that bit to 0).  This shortened display is created by extending the
border to overlap the top or bottom row.  The characters in these rows are
still there; they are just covered up.
  The shortened display is designed to aid vertical fine scrolling.  It covers
up the line into which new screen data is introduced, so that the viewer does
not see the new data being moved into place.
  However, unlink the register at 53270 ($D016) which shortens the screen by
one character space on either side to aid horizontal scrolling in either
direction, this register can blank only one vertical line at a time.  In order
to compensate, it blanks the top line when the three scroll bits in this
register are set to 0, and shifts the blanking one scan line at a time as the
value of thee bits increases.  Thus the bottom line is totally blanked when
these bits are set to 7.
  Bit 4.  Bit 4 of this register controls the screen blanking feature.  When
this bit is set to 0, no data can be displayed on the screen.  Instead, the
whole screen will be filled with the color of the frame (which is controlled
by th eBorder Color Register at 53280 ($D020)).
  Screen blanking is useful because of the way in which the VIC-II chip
interacts with the 6510 microprocessor.  Since the VIC-II and the 6510 both
have to address the same memory, they must share the system data bus.  Sharing
the data bus means that they must take turns whenever they want to address
memory.
  The VIC-II chip was designed so that it fetches most of the data it needs
during the part of the cycle in which the 6510 is not using the data bus.  But
certain operations, such as reading the 40 screen codes needed for each line
of text from video mmeory, or fetching sprite data, require that the VIC-II
chip get data at a faster rate than is possible just by using the off half of
the 6510 cycle.
  Thus, the VIC-II chip must delay the 6510 for a short amount of time while
it is using the data bus to gather display information for text or bitmap
graphics, and must delay it a little more if sprites are also enabled.  When
you set the screen blanking bit to 0, these delays are eliminated, and the
6510 processor is allowed to run at its full speed.  This speeds up any
processing task a little.
  To demonstrate this, run the following short program.  As you will see,
leaving the screen on makes the processor run about 7 percent slower than when
you turn it off.  If you perform the same timing test on the VIC-20, you will
find that it runs at the same speed with its screen on as the 64 does with its
screen off.  And the same test on a PET will run substantially slower.

10 PRINT CHR$(147);TAB(13);"TIMING TEST":PRINT:TI$="000000":GOTO 30
20 FOR I=1 TO 10000:NEXT I:RETURN
30 GOSUB 20:DISPLAY=TI
40 POKE 53265,11:TI$="000000"
50 GOSUB 20:NOSCREEN=TI:POKE 53265,27
60 PRINT "THE LOOP TOOK";DISPLAY;" JIFFIES"
70 PRINT "WITH NO SCREEN BLANKING":PRINT
80 PRINT "THE LOOP TOOK";NOSCREEN;" JIFFIES"
90 PRINT "WITH SCREEN BLANKING":PRINT
100 PRINT "SCREEN BLANKING MAKE THE PROCESSOR"
110 PRINT "GO";DISPLAY/NOSCREEN*100-100;"PERCENT FASTER"

The above explanation accounts for the screen being turned off during tape
read and write operations.  The timing of these operations is rather critical,
and would be affected by even the relatively small delay caused by the video
chip.  It also explains why the 64 has difficulty loading programs from an
unmodified 1540 Disk Drive, since the 1540 was set up to transfer data from
the VIC-20, which does not have to contend with these slight delays.
  If you turn off the 64 display with a POKE 53265,PEEEK(53265) AND 239, you
will be able to load programs correctly from an old 1540 drive.  The new 1541
drive transfers data at a slightly slower rate in the default setting, and can
be set from software to transfer it at the higher rate for the VIC-20.
  Bit 5.  Setting Bit 5 of this register to 1 enables the bitmap graphics
mode.  In this mode, the screen area is broken down into 64,000 separate dots
of light, 320 dots across by 200 dots high.  Each dot corresponds to one bit
of display memory.  If the bit is set to 1, the dot will be displayed in the
foreground color.  If the bit is reset to 0, it will be displayed in the
background color.  This allows the display of high-resolution graphics images
for games, charts, and graphs, etc.
  Bitmapping is a common technique for implementing high-resolution graphics
on a microcomputer.  There are some features of the Commodore system which are
unusual, however.
  Most systems display screen memory sequentially; that is, the first byte
controls the display of the first eight dots in the upper-left corner of the
screen, the second byte controls the eight dots to the right of that, etc.  In
the Commodore system, display memory is laid out more along the lines of how
character graphics dot-data is arranged.
  The first byte controls the row of eight dots in the top-left corner of the
screen, but the next byte controls the eight dots below that, and so on until
the ninth byte.  The ninth byte controls the eight dots directly to the right
of those controlled by the first byte of display memory.  It is exactly the
same as if the screen were filled with 1000 programmable characters, with
display memory taking the place of the character dot-data.
  The 64's bitmap graphics mode also resembles character graphics in that the
foreground color of the dots is set by a color map (although it does not use
the Color RAM for this purpose).  Four bits of each byte of this color memory
control the foreground color of one of these eight-byte groups of display
memory (which form an 8 by 8 grid of 64 dots).  Unlike character graphics,
however, the other four bits control the background color that will be seen in
the eight-byte display group where a bit has a value of 0.
  Setting up a bitmap graphics screen is somewhat more complicated than just
setting this register bit to 1.  You must first choose a location for the
display memory area, and for the color memory area.  The display memory area
will be 8192 bytes long (8000 of which are actually used for the display) and
can occupy only the first or the second half of the 16K space which the VIC-II
chip can address.
  Each byte of bitmap graphics color memory uses four bits for the background
color as well as four bits for the foreground color.  Therefore, the Color RAM
nybbles at 55296 ($D800), which are wired for four bits only, cannot be used.
Another RAM location must therefore be found for color memory.
  This color memory area will take up 1K (1000 bytes of which are actually
used to control the foreground and background colors of the dots), and must be
in the opposite half of VIC-II memory as the display data.  Since bitmap
graphics require so much memory for the display, you may want to select a
different 16K bank for VIC-II memory (see the discussion of things to consider
in selecting a VIC-II memory bank at location 56576 ($DD00)).
  To keep things simple, however, let's assume that you have selected to use
the default bank of VIC-II memory, which is the first 16K.  You would have to
select locations 8192-16383 ($2000-$3FFF) for screen memory, because the
VIC-II chip sees an image of the character ROM in the first half of the 16K
block (at locations 4096-8192 ($1000-$1FFF)).  Color memory could be placed at
the default location of text display memory, at 1024-2047 ($400-$7FF).
Placement of bitmap display and color memory is controlled by the VIC Memory
Control Register at 53272 ($D018).
  When in bitmap mode, the lower four bits of this register, which normally
control the base address of character dot-data, now control the location of
the 8K bitmap.  Only Bit 3 is significant.  If it is set to 1, the graphics
display memory will be in the second 8K of VIC-II memory (in this case,
starting at 8192 ($2000)).  If that bit contains a 0, the first 8K will be
used for the bitmap.  The upper four bits of this register, which normally
control the location of the Video Display Matrix, are used in bitmap mode to
establish the location of the color map within the VIC-II address space.
These four bits can hold a number from 0 to 15, which indicates on which 1K
boundary the color map begins.  For example, if color memory began at 1024
(1K), the value of these four bits would be 0001.
  Once the bitmap mode has been selected, and the screen and color memory
areas set up, you must establish a method for turning each individual dot on
and off.  The conventional method for identifying each dot is to assign it to
a horizontal (X) position coordinate and a vertical (Y) coordinate.
  Horizontal position values will range from 0 to 319, where dot 0 is at the
extreme left-hand side of the screen, and dot 319 at the extreme right.
Vertical positions will range from 0 to 199, where dot 0 is on the top line,
and dot 199 is on the bottom line.
  Because of the unusual layout of bitmap screen data on the 64, it is fairly
easy to transfer text characters to a bitmap screen, but it is somewhat
awkward finding the bit which affects the screen dot having a given X-Y
coordinate.  First, you must find the byte BY in which the bit resides, and
then you must POKE a vlue into that byte which turns the desired bit on or
off.  Given that the horizontal position of the dot is stored in the variable
X, its vertical position is in the variable Y, and the base address of the
bitmap area is in the variable BASE, you can find the desired byte with the
formula:

BY=BASE+40*(Y AND 256)+(Y AND 7)+(X AND 504)

To turn on the desired dot,

POKE BY, PEEK(BY) OR (2^(NOTX AND 7)

To turn the dot off,

POKE BY, PEEK(BY) AND (255-2^(NOTX AND 7))

The exponentation function takes a lot of time.  To speed things up, an array
can be created, each of whose elements corresponds to a power of two.

FOR I=0 TO 7:BIT(I)=2^1:NEXT

After this is done, the expression 2^(I) can be replaced by BI(I).
  The following sample program illustrates the bit-graphics concepts explained
above, and serves as a summary of that information.

10 FOR I=0 TO 7:BI(I)=2^I:NEXT: REM SET UP ARRAY OF POWERS OF 2 (BIT VALUE)
20 BASE=2*4096:POKE53272,PEEK(53272)OR8:REM PUT BIT MAP AT 8192
30 POKE53265,PEEK(53265)OR32:REM ENTER BIT MAP MODE
40 A$="":FOR I=1 TO 37:A$=A$+"C":NEXT:PRINT CHR$(19);
50 FOR I=1 TO 27:PRINTA$;:NEXT:POKE2023,PEEK(2022): REM SET COLOR MAP
60 A$="":FOR I=1 TO 27:A$=A$+"@":NEXT:FOR I=32 TO 63 STEP 2
70 POKE648,I:PRINT CHR$(19);A$;A$;A$;A$:NEXT:POKE648,4:REM CLEAR HI-RES SCREEN
80 FORY=0TO199STEP.5:REM FROM THE TOP OF THE SCREEN TO THE BOTTOM
90 X=INT(160+40*SIN(Y/10)): REM SINE WAVE SHAPE
100 BY=BASE+40*(Y AND 248)+(Y AND 7)+(X AND 504): REM FIND HI-RES BYTE
110 POKEBY,PEEK(BY)OR(BI(NOT X AND 7)):NEXT Y:REM POKE IN BIT VALUE
120 GOTO 120: REM LET IT STAY ON SCREEN

As you can see, using BASIC to draw in bit-graphics mode is somewhat slow and
tedious.  Machine language is much more suiable for bit-graphics plotting.
For a program that lets you replace some BASIC ommands with high-res drawing
commands, see the article "Hi-Res Graphics Made Simple," by Paul F. Schatz, in
COMPUTE!'s First Book of Commodore 64 Sound and Graphics.
  There is a slightly lower resolution bitmap graphics mode available which
offers up to four colors per 8 by 8 dot matrix.  To enable this mode, you must
set the multicolor bit (Bit 4 of 53270 ($D016)) while in bitmap graphics mode.
For more information on this mode, see the entry for the multicolor enable
bit.
  Bit 6.  This bit of this register enables extended background color mode.
This mode lets you select the background color of each text character, as well
as its foreground color.  It is able to increase the number of background
colors displayed, by reducing the number of characters that can be shown on
the screen.
  Normally, 256 character shapes can be displayed on the screen.  You can use
them either by using the PRINT statement or by POKEing a display code from 0
to 255 into screen memory.  If the POKEing method is used, you must also POKE
a color code from 0 to 15 into color memory (for example, if you POKE 1024,1,
and POKE 55296,1, a white A appears in the top-left corner of the screen).
  The background color of the screen is determined by Background Color
Register 0, and you can change this color by POKEing a new value to that
register, which is located at 53281 ($D021).  For example, POKE 53281,0
creates a black background.
  When extended background color mode is activated, however, only the first
64 shapes found in the table of the screen display codes can be displayed on
the screen.  This group includes the letters of the alphabet, numerals, and
punctuation marks.  If you try to print on the screen a character having a
higher display code, the shape displayed will be from the first group of 64,
but that character's background will no longer be determined by the register
at 53281 ($D021).  Instead, it will be determined by one of the other
background color registers.
  When in extended background color mode, characters having display codes 64-
127 will take their background color from register 1, and location 53282
($D022).  These characters include various SHIFTed characters.  Those with
codes 128-191 will have their background colors determined by register 2, at
53283 ($D023).  These include the reversed numbers, letters, and punctuation
marks.  Finally, characters with codes 192-255 will use register 4, at 53284
($D024).  These are the reversed graphics characters.
  Let's try an experiment to see just how this works.  First, we will put the
codes for four different letters in screen memory:

FOR I=0 TO 3:POKE 1230+(I*8),I*64+I:POKE 55502+(I*8),1:NEXT

Four white letters should appear on the screen, an A, a shifted A, a reversed
A, and a reversed, shifted A, all on a blue background.  Next, we will put
colors in the other background color registers:

POKE 53282,0:POKE53283,2:POKE53284,5

This sets the registers to black, red, and green, respectively.  Finally, we
will activate extended color mode by setting Bit 6 of the VIC-II register at
location 53265 to a 1.  The BASIC statement that turns this mode on is:

POKE 53265,PEEK(53265) OR 64

Notice that two things happened.  First, all of the letters took on the same
shape, that of the letter A.  Second, each took on the background color of a
different color register.  To get things back to normal, turn off extended
color mode with this statement:

POKE 53265,PEEK(53265) AND 191

Extended color mode can be a very useful enhancement for your text displays.
It allows the creation of windows.  These windows, because of their different
background colors, make different bodies of text stand out as visually
distinct from one another.  For example, a text adventure program could have
one window to display the player's current location, one to show an inventory
of possessions, and one to accept commands for the next move.
  In this mode the background color of these windows can be changed instantly,
just by POKEing a new value to the color register.  This technique lends
itself to some dramatic effects.  A window can be flashed to draw attention to
a particular message at certain times.  And varying the foreground color can
make either the window or the message vanish and reappear later.
  There are, however, a couple of problems involved in using these windows.
The character shape that you want to use might not have a screen code of less
than 64.  In that case, the only solution is to define your own character set,
with the shape you want in one of the first 64 characters.
  Another problem is that characters within a PRINT statement in your program
listing are not always going to look the same on the screen.  Having to figure
out what letter to print to get the number 4 with a certain background color
can be very inconvenient.  The easiest solution to this problem is to have a
subroutine to the translation for you.  Since letters will appear normally in
window 1, and window 3 characters are simply window 1 characters reversed, you
will only have problems with characters in windows 2 and 4.  To conver these
characters, put your message in A$, and use the following subroutine:

500 B$="":FOR I=1 TO LEN(A$):B=ASC(MID$(A$,I,1))
510 B=B+32:IF B<96 THEN B=B+96
520 B$=B$+CHR$(B):NEXT I:RETURN

This subroutine converts each letter to its ASCII equivalent, adds the proper
offset, and converts it back to part of the new string, B$.  When the
conversion is complete, B$ will hold the characters necessary to PRINT that
message in window 2.  For window 4, PRINT CHR$(18);B$;CHR$(146).  This will
turn reverse video on before printing the string, and turn it off afterwards.
  A practical demonstration of the technique for setting up windows is given
in the sample program below.  The program sets up three windows, and shows
them flashing, appearing and disappearing.

5 DIM RO$(25):RO$(0)=CHR$(19):FOR I=1 TO 24:RO$(I)=RO$(I-1)+CHR$(17):NEXT
10 POKE 53265,PEEK(53265) OR 64
20 POKE 53280,0:POKE 53281,0:POKE 53282,1:POKE 53283,2:POKE 53284,13
25 OP$=CHR$(160):FOR I=1 TO 4:OP$=OP$:NEXTI:PRINTCHR$(147);RO$(3);
30 FOR I=1 TO10:PRINTTAB(1);CHR$(18);"               ";TAB(23);OP$:NEXT
40 PRINT CHR$(146):PRINT:PRINT:FOR I=1 TO 4:PRINTOP$;OP$;OP$;OP$;OP$;:NEXTI
50 PRINT RO$(5);CHR$(5);CHR$(18);TAB(2);"A RED WINDOW"
60 PRINT CHR$(18);TAB(2);"COULD BE USED"
70 PRINT CHR$(18);TAB(2);"FOR ERROR"
80 PRINT CHR$(18);TAB(2);"MESSAGES"
100 A$="A GREEN WINDOW":GOSUB 300:PRINT RO$(5);CHR$(144);CHR$(18);TAB(24);B$
110 A$="COULD BE USED":GOSUB 300:PRINTTAB(24);CHR$(18);B$
120 A$="TO GIVE":GOSUB 300:PRINTTAB(24);CHR$(18);B$
130 A$="INSTRUCTIONS":GOSUB 300:PRINTTAB(24);CHR$(18);B
140 PRINT CHR$(31);RO$(19);
150 A$="  WHILE THE MAIN WINDOW COULD BE USED":GOSUB 300:PRINT B$
160 A$="  FOR ACCEPTING COMMANDS.":GOSUB 300:PRINT B$
170 FOR I=1 TO 5000:NEXT I:POKE 53284,0
180 FOR I=1 TO 5:FOR J=1 TO 300:NEXT J:POKE 53282,15
190 FOR J=1 TO 300:NEXT J:POKE 53282,1
200 NEXT I:POKE 53283,-2*(PEEK(53283)=240):POKE 53284,-13*(PEEK(53284)=240)
210 GOTO 180
300 B$="":FOR I=1TOLEN(A$):B=ASC(MID$(A$,I,1))
310 B=B+32:IFB<96THENB=B+96
320 B$=B$+CHR$(B):NEXTI:RETURN

  Bit 7.  Bit 7 of this register is the high-order bit (Bit 8) of the Raster
Compare register at 53266 ($D012).  Even though it is located here, it
functions as part of that register (see the description below for more
information on the Raster Compare register).
  Machine language programmers should note that its position here at Bit 7
allows testing this bit with the Negative flag.  Since scan lines above number
256 are all off the screen, this provides an easy way to delay changing the
graphics display until the scan is in the vertical blanking interval and the
display is no longer being drawn:

LOOP  LDA $D011
      BPL LOOP

Sprites should always be moved when the raster is scanning off-screen, because
if they are moved while they are being scanned, their shapes will waver
slightly.
  The BASIC equivalent of the program fragment above is the statement WAIT
53265,128, but BASIC is usually not fast enough to execute the next statement
while still in the blanking interval.

53266          $D012         RASTER
Read Current Raster Scan Line/Write Line to Compare for Raster IRQ

The Raster Compare register has two different functions, depending on whether
you are reading from it or writing to it.  When this register is read, it
tells which screen line the electron beam is currently scanning.
  There are 262 horizontal lines which make up the American (NTSC) standard
display screen (312 lines in the European or PAL standard screen).  Every one
of these lines is scanned and updated 60 times per second.  Only 200 of these
lines (numbers 50-249) are part of the visible display.
  It is sometimes helpful to know just what line is being scanned, because
changing screen graphics on a particular line while that line is being
scanned may cause a slight disruption on the screen.  By reading this
register, it is possible for a machine language program to wait until the scan
is off the bottom of the screen before changing the graphics display.
  It is even possible for a machine language program to read this register,
and change the screen display when a certain scan line is reached.  The
program below uses this technique to change the background color in midscreen,
in order to show all 256 combinations of foreground and background text colors
at once.

40 FOR I=49152 TO 49188:READ A:POKE I,A:NEXT:POKE 53280,11
50 PRINT CHR$(147):FOR I=1024 TO I+1000:POKE I,160:POKE I+54272,11:NEXT I
60 FOR I=0 TO 15:FOR J=0 TO 15
70 P=1196+(48*I)+J:POKE P,J+I:POKE P+54272,J:NEXT J,I
80 PRINT TAB(15)CHR$(5)"COLOR CHART":FOR I=1 TO 19:PRINT:NEXT
85 PRINT "THIS CHART SHOWS ALL COMBINATIONS OF   "
86 PRINT "FOREGROUND AND BACKGROUND COLORS.      "
87 PRINT "FOREGROUND INCREASES FROM LEFT TO RIGHT"
88 PRINT "BACKGROUND INCREASES FROM TOP TO BOTTOM"
90 SYS 12*4096
100 DATA 169,90,133,251,169,0,141,33,208,162,15,120,173,17,208,48
105 DATA 251,173,18,208
110 DATA 197,251,208,249,238,33,208,24,105,8,133,251,202,16,233,48,219

Writing to this register designates the comparison value for the Raster
Compare Interrupt.  When that interrupt is enabled, a maskable interrupt
request will be issued every time the electron beam scan reaches the scan line
whose number was written here.  This is a much more flexible technique for
changing the display in midscreen than reading this register as the sample
program above does.  That technique requires that the program continuously
watch the Raster Register, while the interrupt method will call the program
when the time is right to act.  For more information on raster interrupts, see
the entry for the Interrupt Mask Register (53274, $D01A).
  It is very important to remember that this register requires nine bits, and
that this location only holds eight of those bits (the ninth is Bit 7 of 53265
($D011)).  If you forget to read or write to the ninth bit, your results could
be in error by a factor of 256.
  For example, some early programs written to demonstrate the raster interrupt
took for granted that the ninth bit of this register would be set to 0 on
power-up.  When a later version of the Kernal changed this initial value to a
1, their interrupt routines, which were supposed to set the raster interrupt
to occur at scan line number 150, ended up setting it for line number 406
instead.  Since the scan line numbers do not go up that high, no interrupt
request was ever issued and the program did not work.

Location Range: 53267-53268 ($D013-$D014)
Light Pen Registers

A light pen is an input device that can be plugged into joystick Control Port
#1.  It is shaped like a pen and has a light-sensitive device at its tip that
causes the trigger switch of the joystick port to close at the moment the
electron beam that updates the screen display strikes it.  The VIC-II chip
keeps track of where the beam is when that happens, and records the
corresponding horizontal and vertical screen coordinates in the registers at
these locations.
  A program can read the position at which the light pen is held up to the
screen.  The values in these registers are updated once every screen frame
(60 times per second).  Once the switch is closed and a value written to these
registers, the registers are latched, and subsequent switch closings during
the same screen frame will not be recorded.
  A given light pen may not be entirely accurate (and the operator may not
have a steady hand).  It is probably wise to average the positions returned
from a number of samplings, particularly when using a machine language driver.

53267         $D013          LPENX
Light Pen Horizontal Position

This location holds the horizontal position of the light pen.  Since there are
only eight bits available (which give a range of 256 values) for 320 possible
horizontal screen positions, the value here is accurate only to every second
dot position.  The number here will range from 0 to 160 and must be multiplied
by 2 in order to get a close approximation of the actual horizontal dot
position of the light pen.

53268         $D014          LPENY
Light Pen Vertical Position

This location holds the vertical position of the light pen.  Since there are
only 200 visible scan lines on the screen, the value in this register
corresponds exactly to the current raster scan line.

53269         $D015          SPENA
Sprite Enable Register

Bit 0:  Enable Sprite 0 (1=sprite is on, 0=sprite is off)
Bit 1:  Enable Sprite 1 (1=sprite is on, 0=sprite is off)
Bit 2:  Enable Sprite 2 (1=sprite is on, 0=sprite is off)
Bit 3:  Enable Sprite 3 (1=sprite is on, 0=sprite is off)
Bit 4:  Enable Sprite 4 (1=sprite is on, 0=sprite is off)
Bit 5:  Enable Sprite 5 (1=sprite is on, 0=sprite is off)
Bit 6:  Enable Sprite 6 (1=sprite is on, 0=sprite is off)
Bit 7:  Enable Sprite 7 (1=sprite is on, 0=sprite is off)

In order for any sprite to be displayed, the corresponding bit in this
register must be set to 1 (the default for this location is 0).  Of course,
just setting this bit along will not guarantee that a sprite will be shown on
the screen.  The Sprite Data Pointer must indicate a data area that holds
some values other than 0.  The Sprite Color Register must also contain a value
other than that of the background color.  In addition, the Sprite Horizontal
and Vertical Position Registers must be set for positions that lie within the
visible screen range in order for a sprite to appear on screen.

53270         $D016          SCROLX
Horizontal Fine Scrolling and Control Register

Bits 0-2:  Fine scroll display horizontally by X dot positions (0-7)
Bit 3:  Select a 38-column or 40-column text display (1=40 columns, 0=38
  columns)
Bit 4:  Enable multicolor text or multicolor bitmap mode (1=multicolor on,
  0=multicolor off)
Bit 5:  Video chip reset (0=normal operations, 1=video completely off)
Bits 6-7:  Unused

This is one of the two important multifunction control registers on the VIC-II
chip.  On power-up, it is set to a default value of 8, which means that the
VIC chip Reset line is set for a normal display, Multicolor Mode is disabled,
a 40-column text display is selected, and no horizontal fine-scroll offset is
used.
  Bits 0-2.  The first three bits of this chip control vertical fine scrolling
of the screen display.  This feature allows you to smoothly move the entire
text display back and forth, enabling the display area to act as a window,
scrolling over a larger text or character graphics display.
  Since each text character is eight dots wide, moving each character over one
whole character position (known as coarse scrolling) is a relatively big jump,
and the motion looks jerky.  By placing a number from 1 to 7 into these three
bits, you can move the whole screen display from one to seven dot spaces to
the right.
  Stepping through values 1 to 7 allows you to smoothly make the transition
from having a character appear at one screen column to having it appear at the
next one over.  To demonstrate this, type in the following program, LIST, and
RUN it.

10 FOR I=1 TO 50:FOR J=0 TO 7
20 POKE 53270,(PEEK(53270)AND248) OR J:NEXT J,I
30 FOR I=1 TO 50:FOR J=7 TO 0 STEP-1
40 POKE 53270,(PEEK(53270)AND248) OR J:NEXT J,I

As you can see, after the display has moved over seven dots, it starts over at
its original position.  In order to continue with the scroll, you must do a
coarse scroll every time the value of the scroll bits goes from 7 to 0, or
from 0 to 7.  This is accomplished by moving each byte of display data on each
line over one position, overwriting the last character, and introducing a new
byte of data on the opposite end of the screen line to replace it.
  Obviously, only a machine language program can move all of these bytes
quickly enough to maintain the effect of smooth motion.  The following BASIC
program, however, will give you an idea of what the combination of fine and
coarse scrolling looks like.

10 POKE 53281,0:PRINT CHR$(5);CHR$(147):FOR I=1 TO 5:PRINT CHR$(17):NEXT
20 FOR I=1 TO 30
30 PRINT TAB(I-1)"{UP}{10 SPACES}{UP}"
40 WAIT53265,128:POKE53270,PEEK(53270)AND248:PRINTTAB(I)"AWAY WE GO"
50 FOR J=1 TO 7
60 POKE 53270,(PEEK(53270)AND248)+J
70 FORK=1TO30-I
80 NEXT K,J,I:RUN

Changing the value of the three horizontal scroll bits will affect the entire
screen display.  If you wish to scroll only a portion of the screen, you will
have to use raster interrupts (see 53274 ($D01A) below) to establish a scroll
zone, change the value of these scroll bits only when that zone is being
displayed, and change it back to 0 afterward.
  Bit 3.  Bit 3 of this register allows you to cover up the first and last
columns of the screen display with the border.  Since the viewers cannot see
the characters there, they will not be able to see you insert a new character
on the end of the line when you do coarse scrolling (see explanation of Bits
0-2 above).
  Setting this bit to 1 enables the normal 40-column display, while resetting
it to 0 changes the display to 38 columns.  This is a purely cosmetic aid, and
it is not necessary to change the screen to the smaller size to use the
scrolling feature.
  Bit 4.  This bit selects multicolor graphics.  The effect of setting this
bit to 1 depends on whether or not the bitmap graphics mode is also enabled.
  If you are not in bitmap mode, and you select multicolor text character mode
by setting this bit to 1, characters with a color nybble whose value is less
than 8 are displyed normally.  There will be one background color and one
foreground color.  But each dot of a character with a color nybble whose value
is over 7 can have any one of four different colors.
  The two colors in the Background Control Registers 1 and 2 (53282-3,
$D022-3) are available in addition to the colors supplied by the Color RAM.
The price of these extra colors is a reduction in horizontal resolution.
Instead of each bit controlling one dot, in multicolor mode a pair of bits
control the color of a larger dot.  A pattern of 11 will light it with the
color from the lower three bits of color RAM.  Patterns of 01 and 10 will
select the colors from Background Color Registers 1 and 2, respectively, for
the double-width dot.
  You can see the effect that setting this bit has by typing in the following
BASIC command line:

POKE 53270,PEEK(53280)OR16:PRINT CHR$(149)"THIS IS MULTICOLOR MODE"

It is obvious from this example that the normal set of text characters was not
made to be used in multicolor mode.  In order to take advantage of this mode,
you will need to design custom four-color characters.  For more information,
see the alternate entry for 53248 ($D000), the Character Generator ROM.
  If the multicolor and bitmap enable bits are both set to 1, the result is a
multicolor bitmap mode.  As in multicolor text mode, pairs of graphics data
bits are used to set each dot in a 4 by 8 matrix to one of four colors.  This
results in a reduction of the horizontal resolution to 160 double-wide dots
across.  But while text multicolor mode allows only one of the four colors to
be set individually for each 4 by 8 dot area, bitmap multicolor mode allows up
to three different colors to be individually selected in each 4 by 8 dot area.
The source of the dot color for each bit-pair combination is shown below:

00 Background Color Register 0 (53281, $D021)
01 Upper four bits of Video Matrix
10 Lower four bits of Video Matrix
11 Color RAM nybble (area starts at 55296 ($D800))

The fact that bit-pairs are used in this mode changes the strategy for
plotting somewhat.  In order to find the byte BY in which the desired bit-pair
resides, you must multiply the horizontal position X, which has a value of 0-
159, by 2, and then use the same formula as for hi-res bitmap mode.
  Given that the horizontal position (0-159) of the dot is stored in the
variable X, its vertical position is in the variable Y, and the base address
of the bitmap area ia in the variable BASE, you can find the desired byte with
the formula:

BY=BASE+(Y AND 248)*40+(Y AND 7)+(2*X AND 504)

Setting the desired bit-pair will depend on what color you chose.  First, you
must set up an array of bit masks.

CA(0)=1:CA(1)=4:CA(2)=16:CA(3)=64

To turn on the desired dot, select a color CO from 0 to 3 (representing the
color selected by the corresponding bit pattern) and execute the following
statement:

BI=(NOT X AND 3):POKE BY,PEEK(BY) AND (NOT 3*CA(BI)) OR (CO*CA(BI))

The following program will demonstrate this technique:

10 CA(0)=1:CA(1)=4:CA(2)=16:CA(3)=64:REM ARRAY FOR BIT PAIRS
20 BASE=2*4096:POKE53272,PEEK(53272)OR8:REM PUT BIT MAP AT 8192
30 POKE53265,PEEK(53265)OR32:POKE53270,PEEK(53270)OR16:REM MULTI-COLOR BIT MAP
40 A$="":FOR I=1 TO 37:A$=A$+"C":NEXT:PRINT CHR$(19);
50 FOR I=1 TO 27:PRINT A$;:NEXT:POKE 2023,PEEK(2022): REM SET COLOR MAP
60 A$="":FOR I=1 TO 128:A$=A$+"@":NEXT:FOR I=32 TO 63 STEP 2
70 POKE648,I:PRINTCHR$(19);A$;A$;A$;A$:NEXT:POKE648,4:REM CLR HI-RES SCREEN
80 FOR CO=1TO3:FOR Y=0TO199STEP.5:REM FROM THE TOP OF THE SCREEN TO THE BOTTOM
90 X=INT(10*CO+15*SIN(CO*45+Y/10)): REM SINE WAVE SHAPE
100 BY=BASE+40*(Y AND 248)+(Y AND 7)+(X*2 AND 504): REM FIND HI-RES BYTE
110 BI=(NOT X AND 3):POKE BY,PEEK(BY) AND (NOT 3*CA(BI)) OR(CO*CA(BI))
120 NEXT Y,CO
130 GOTO 130: REM LET IT STAY ON SCREEN

  Bit 5:  Bit 5 controls the VIC-II chip Reset line.  Setting this bit to 1
will completely stop the video chip from operating.  On older 64s, the screen
will go black.  It should always be set to 0 to insure normal operation of the
chip.
  Bits 6 and 7.  These bits are not used.

53271         $D017          YXPAND
Sprite Vertical Expansion Register

Bit 0:  Expand Sprite 0 vertically (1=double height, 0=normal height)
Bit 1:  Expand Sprite 1 vertically (1=double height, 0=normal height)
Bit 2:  Expand Sprite 2 vertically (1=double height, 0=normal height)
Bit 3:  Expand Sprite 3 vertically (1=double height, 0=normal height)
Bit 4:  Expand Sprite 4 vertically (1=double height, 0=normal height)
Bit 5:  Expand Sprite 5 vertically (1=double height, 0=normal height)
Bit 6:  Expand Sprite 6 vertically (1=double height, 0=normal height)
Bit 7:  Expand Sprite 7 vertically (1=double height, 0=normal height)

This register can be used to double the height of any sprite.  When the bit in
this register that corresponds to a particular sprite is set to 1, each dot of
the 24 by 21 sprite dot matrix will become two raster scan lines high instead
of one.

53272         $D018          VMCSB
VIC-II Chip Memory Control Register

Bit 0:  Unused
Bits 1-3:  Text character dot-data base address within VIC-II address space
Bits 4-7:  Video matrix base address within VIC-II address space

This register affects virtually all graphics operations.  It determines the
vase address of two very important data areas, the Video Matrix, and the
Character Dot-Data area.
  Bits 1-3.  These bits are used to set the location of the Character Dot-Data
area.  This area is where the data is stored (for more information on
character shape data, see the alternate entry for location 53248 ($D000), the
Character Generator ROM).
  Bits 1-3 can represent any even number from 0 to 14.  That numer stands for
the even 1K offset of the character data area from the beginning of VIC-II
memory.  For example, if these bits are all set to 0, it means that the
character memory occupies the first 2K of VIC-II memory.  If they equal 2, the
data area starts 2*1K (2*1024) or 2048 bytes from the beginning of VIC memory.
  The default value of this nybble is 4.  This sets the address of the
Character Dot-Data area to 4096 ($1000), which is the starting address of
where the VIC-II chip addresses the Character ROM.  The normal character set
which contains uppercase and graphics occupies the first 2K of that ROM.  The
alternate character set which contains both upper- and lowercase letters use
the second 2K.  Therefore, to shift to the alternate character set, you must
change the value of this nybble to 6, with a POKE 53272,PEEK(53272)OR2.  To
change it back, POKE 53272,PEEK(53272)AND253.
  In bitmap mode, the lower nybble controls the location of the bitmap screen
data.  Since this data area can start only at an offset of 0 or 8K from the
beginning of VIC-II memory, only Bit 3 of the Memory Control Register is
significant in bitmap mode.  If Bit 3 holds a 0, the offset is 0, and if it
holds a 1, the offset is 8192 (8K).
  Bits 4-7.  This nybble determines the starting address of the Video Matrix
area.  This is the 1024-byte area of memory which contains the screen codes
for the text characters that are displayed on the screen.  In addition, the
last eight bytes of this area are used as pointers which designate which 64-
byte block of VIC-II memory will be used as shape data for each sprite.
  These four bits can represent numbers from 0 to 15.  These numbers stand for
the offset (in 1K increments) from the beginning of VIC-II memory to the
Video Matrix.
  For example, the default bit pattern is 0001.  This indicates that the Video
Matrix is offset by 1K from the beginning of VIC-II memory, the normal
starting place for screen memory.  Remember, though, the bit value of this
number will be 16 times what the bit pattern indicates, because we are dealing
with Bits 4-7.  Therefore, the 0001 in the upper nybble has a value of 16.
  Using this register, we can move the start of screen memory to any 1K
boundary within the 16K VIC-II memory area.  Just changing this register,
however, is not enough if you want to use the BASIC line editor.  The editor
looks to location 648 ($288) to determine where to print screen characters.
  If you just change the location of the Video Matrix without changing the
value in 648, BASIC will continue to print characters in the memory area
starting at 1024, even though that area is no longer being displayed.  The
result is that you will not be able to see anything that you type in on the
keyboard.  To fix this, you must POKE 648 with the page number of the starting
address of screen memory (page number=location/256).  Remember, the actual
starting address of screen memory depends not only on the offset from the
beginning of VIC-II memory in the register, but also on which bank of 16K is
used for VIC-II memory.
  For example, if the screen area starts 1024 bytes from the beginning of VIC-
II memory, and the video chip is using Bank 2 (32768-49151), the actual
starting address of screen memory is 32768+1024=33792 ($8400).  For examples
of how to change the video memory area, and of how to relocate the screen, see
the entro for 56576 ($DD00).

53273         $D019          VICIRQ
VIC Interrupt Flag Register

Bit 0:  Flag:  Is the Raster Compare a possible source of an IRQ?  (1=yes)
Bit 1:  Flag:  Is a collision between a sprite and the normal graphics display
        a possible source of an IRQ?  (1=yes)
Bit 2:  Flag:  Is a collision between two sprites a possible source of an IRQ?
        (1=yes)
Bit 3:  Flag:  Is the light pen trigger a possible source of an IRQ?  (1=yes)
Bits 4-6:  Not used
Bit 7:  Flag:  Is there any VIC-II chip IRQ source which could cause an IRQ?
        (1=yes)

The VIC-II chip is capable of generating a maskable request (IRQ) when certain
conditions relating to the video display are fulfilled.  Briefly, the
conditions that can cause a VIC-II chip IRQ are:
  1.  The line number of the current screen line being scanned by the raster
is the same as the line number value written to the Raster Register (53266,
$D012).
  2.  A sprite is positioned at the same location where normal graphics data
are being displayed.
  3.  Two sprites are positioned so that they are touching.
  4.  The light sensor on the light pen has been struck by the raster beam,
causing the fire button switch on joystick Control Port #1 to close (pressing
the joystick fire button can have the same effect).
  When one of these conditions is met, the corresponding bit in this status
register is set to 1 and latched.  That means that as long as the
corresponding enable bit in the VIC IRQ Mask register is set to 1, and IRQ
requested will be generated, and any subsequent fulfillment of the same
condition will be ignored until the latch is cleared.
  This allows you to preserve multiple interrupt requests if more than one of
the interrupt conditions is met at a time.  In order to keep an IRQ source
from generating another request after it has been serviced, and to enable
subsequent interrupt conditions to be detected, the interrupt service routine
must write a 1 to the corresponding bit.  This will clear the latch for that
bit.  The default value written to this register is 15, which clears all
interrupts.
  There is only 1 IRQ vector that points to the address of the routine that
will be executed when an IRQ interrupt occurs.  The same routine will
therefore be executed regardless of the source of the interrupt.  This status
register provides a method for that routine to check what the source of the
IRQ was, so that the routine can take appropriate action.  First, the routine
can check Bit 7.  Anytime that any of the other bits in the status register is
set to 1, Bit 7 will also be set.  Therefore, if that bit holds a 1, you know
that the VIC-II chip requested an IRQ (the two CIA chips which are the other
sources of IRQ interrupts can be checked in a similar manner).  Once it has
been determined that the VIC chip is responsible for the IRQ, the individual
bits can be tested to see which of the IRQ conditions have been met.
  For more information, and a sample VIC IRQ program, see the following entry.

53274         $D01A          IRQMASK
IRQ Mask Register

Bit 0:  Enable Raster Compare IRQ (1=interrupt enabled)
Bit 1:  Enable IRQ to occure when sprite collides with display of normal
        graphics data (1=interrupt enabled)
Bit 2:  Enable IRQ to occur when two sprites collide (1=interrupt enabled)
Bit 3:  Enable light pen to trigger an IRQ (1=interrupt enabled)
Bits 4-7:  Not used

This register is used to enable an IRQ request to occur when one of the VIC-II
chip interrupt conditions is met.  In order to understand what that means, and
how these interrupts can extend the range of options available to a
programmer, you must first understand what an interrupt is.
  An interrupt is a signal given to the microprocessor (the brains of the
computer) that tells it to stop executing its machine language program (for
example, BASIC), and to work on another program for a short time, perhaps only
a fraction of a second.  After finishing the interrupt program, the computer
goes back to executing the main program, just as if there had never been a
detour.
  Bit 0.  This bit enables the Raster Compare IRQ.  The conditions for this
IRQ are met when the raster scan reaches the video line indicated by the value
written to the Raster Register at 53266 ($D012) and Bit 7 of 53265 ($D011).
Again, an explanation of the terminology is in order.
  In the normal TV display, a beam of electrons (raster) scans the screen,
starting in the top-left corner, and moving in a straight line to the right,
lighting up appropriate parts of the screen line on the way.  When it comes to
the right edge, the beam moves down a line, and starts again from the left.
There are 262 such line that are scanned by the 64 display, 200 of which form
the visible screen area.  This scan updates the complete screen display 60
times every second.
  The VIC-II chip keeps track of which line is being scanned, and stores the
scan number in the Raster Register at 53266 and 53265 ($D012 and $D011).  The
Raster Register has two functions.  When read, it tells what line is presently
being scanned.  But when written to, it designates a particular scan line as
the place where a raster interrupt will occur.
  At the exact moment that the raster beam line number equals the number
written to the register, Bit 0 of the status register will be set to 1,
showing that the conditions for a Raster Compare Interrupt have been
fulfulled.  If the raster interrupt is enabled then, simultaneously, the
interrupt program will be executed.  This allows the user to reset any of the
VIC-II registers at any point in the display, and thus change character sets,
background color, or graphics mode for only a part of the screen display.
  The interrupt routine will first check if the desired condition is the
source of the interrupt (see above entry) and then make the changes to the
screen display.  Once you have written this interrupt routine, you must take
the following steps to install it.
  1.  Set the interrupt disable flag in the status register with an SEI
instruction.  This will disable all interrupts and prevent th system from
crashing while you are changing the interrupt vectors.
  1.  Enable the raster interrupt.  This is done by setting Bit 0 of the VIC-
II chip interrupt enable register at location 53274 ($D01A) to 1.
  3.  Indicate the scan line on which you want the interrupt to occur by
writing to the raster registers.  Don't forget that this is a nine-bit value,
and you must set both the low byte (in location 53266 ($D012)) and the high
bit (in the register at 53265 ($D011)) in order to insure that the interrupt
will start at the scan line you want it to, and not 256 lines earlier or
later.
  4.  Let the computer know where the machine language routine that you want
the interrupt to execute starts.  This is done by placing the address in the
interrupt vector at locations 788-789 ($314-$315).  This address is split
into two parts, a low byte and a high byte, with the low byte stored at 788.
  To calculate the two values for a given address AD, you may use the formula
HIBYTE=INT(AD/156) and LOWBYTE=AD-(HIBYTE*256).  The value LOWBYTE would go
into location 788, and the value HIBYTE would go into location 789.
  5.  Reenable interrupts with a CLI instruction, which clears the interrupt
disable flag on the status register.
  When the computer is first turned on, the interrupt vector is set to point
to the normal hardware timer interrupt routine, the one that advances the
jiffy clock and reads the keyboard.  Since this interrupt routine uses the
same vector as the raster interrupt routine, it is best to turn off the
hardware timer interrupt by putting a value of 127 in location 56333 ($DC0D).
  If you want the keyboard and jiffy clock to function normally while your
interrupt is enabled, you must preserve the contents of locations 788 and 789
before you change them to point to your new routine.  Then you must have your
interrupt routine jump to the old interrupt routine exactly once per screen
refresh (every 1/60 second).
  Another thing that you should keep in mind is that at least two raster
interrupts are required if you want to change only a part of the screen.  Not
only must the interrupt routine change the display, but it must also set up
another raster interrput that will change it back.
  The sample program below uses a raster-scan interrupt to divide the display
into three sections.  The first 80 scan lines are in high-resolution bitmap
mode, the next 40 are regular text, and the last 80 are in multicolor bitmap
mode.  The screen will split this way as soon as a SYS to the routine that
turns on the interrupt occurs.  The display will stay split even after the
program ends.  Only if you hit the STOP and RESTORE keys together will the
display return to normal.
  The interrupt uses a table of values that are POKEd into four key locations
during each of the three interrupts, as well as values to determine at what
scan lines the interrupt will occur.  The locations affected are Control
Register 1 (53265, $D011), Control Register 2 (53270, $D016), the Memory
Control Register (53272, $D018), and Background Color 0 (53281, $D021).  The
data for the interrupt routine is contained in lines 49152-49276.  Each of
these line numbers corresponds to the locations where the first data byte in
the statement is POKEd into memory.
  If you look at lines 49264-49276 of the BASIC program, you will see REMark
statements that explain which VIC-II registers are affected by the DATA
statements in each line.  The number in these DATA startements appear in the
reverse order in which they are put into the VIC register.  For example, line
49273 holds the data that will go into Control Register 2.  The last number,
8, is the one that will be placed into Control Register 2 while the top part
of the screen is displayed.  The first number, 24, is placed into Control
Register 2 during the bottom part of the screen display, and changes that
portion of the display to multicolor mode.
  The only tricky part in determining which data byte affects which interrupt
comes in line 49264, which holds the data that determines the scan line at
which each interrupt will occur.  Each DATA statement entry reflects the scan
line at which the next interrupt will occur.  The first item in line 49264 is
49.  Even though this is the entry for the third interrupt, the next to be
generates is the first interrupt, which occurs at the top of the screen.
Likewise, the last data item of 129 is used during the first interrupt to
start the next interrupt at scan line 129.
  Try experimenting with these values to see what results you come up with.
For example, if you change the number 170 to 210, you will increase the text
area by five lines (40 scan lines).
  By changing the values in the data tables, you can alter the effect of each
interrupt.  Change the 20 in line 49276 to 22, and you will get lowercase text
in the middle of the screen.  Change the first 8 in line 49273 to 24, and
you'll get multicolor text in the center window.  Each of these table items
may be used exactly like you would use the corresponding register, in order to
change background color, to obtain text or bitmap graphics, regular or
multicolor modes, screen blanking or extended background color mode.
  It is even possible to change the table values during a program, by POKEing
the new value into the memory location where those table values are stored.
In that way, you can, for example, change the background color of any of the
screen parts while the program is running.

5 FOR I=0 TO 7:BI(I)=2^I:NEXT
10 FOR I=49152 TO 49278:READ A:POKE I,A:NEXT:SYS12*4096
20 PRINT CHR$(147):FOR I=0 TO 8:PRINT:NEXT
30 PRINT"THE TOP AREA IS HIGH-RES BIT MAP MODE"
40 PRINT:PRINT"THE MIDDLE AREA IS ORDINARY TEXT "
50 PRINT:PRINT"THE BOTTOM AREA IS MULTI-COLOR BIT MAP"
60 FORG=1384 TO 1423:POKE G,6:NEXT
70 FORG=1024 TO 1383:POKEG,114:POKE G+640,234:NEXT
80 A$="":FOR I=1 TO 128:A$=A$+"@":NEXT:FOR I=32 TO 63 STEP 2
90 POKE 648,I:PRINT CHR$(19)CHR$(153);A$;A$;A$;A$:NEXT:POKE 648,4
100 BASE=2*4096:BK=49267
110 H=40:C=0:FORX=0TO319:GOSUB150:NEXT
120 H=160:C=0:FORX=0TO319STEP2:GOSUB150:NEXT:C=40
125 FORX=1TO319STEP2:GOSUB150:NEXT
130 C=80:FOR X=0 TO 319 STEP2:W=0:GOSUB150:W=1:GOSUB150:NEXT
140 GOTO 140
150 Y=INT(H+20*SIN(X/10+C)):BY=BASE+40*(Y AND 248)+(Y AND 7)+(X AND 504)
160 POKE BY,PEEK(BY) OR (BI(ABS(7-(XAND7)-W))):RETURN
49152 DATA 120, 169, 127, 141, 13, 220
49158 DATA 169, 1, 141, 26, 208, 169
49164 DATA 3, 133, 251, 173, 112, 192
49170 DATA 141, 18, 208, 169, 24, 141
49176 DATA 17, 208, 173, 20, 3, 141
49182 DATA 110, 192, 173, 21, 3, 141
49188 DATA 111, 192, 169, 50, 141, 20
49194 DATA 3, 169, 192, 141, 21, 3
49200 DATA 88, 96, 173, 25, 208, 141
49206 DATA 25, 208, 41, 1, 240, 43
49212 DATA 190, 251, 16, 4, 169, 2
49218 DATA 133, 251, 166, 251, 189, 115
49224 DATA 192, 141, 33, 208, 189, 118
49230 DATA 192, 141, 17, 208, 189, 121
49236 DATA 192, 141, 22, 208, 189, 124
49242 DATA 192, 141, 24, 208, 189, 112
49248 DATA 192, 141, 18, 208, 138, 240
49254 DATA 6, 104, 168, 104, 170, 104
49260 DATA 64, 76, 49, 234
49264 DATA 49, 170, 129 :REM SCAN LINES
49267 DATA 0, 6, 0:REM BACKGROUND COLOR
49270 DATA 59, 27,59:REM CONTROL REG. 1
49273 DATA 24, 8, 8:REM CONTROL REG. 2
49276 DATA 24, 20, 24:REM MEMORY CONTROLRUN

Besides enabling the creation of mixed graphics-modes screens, the Raster
Compare Interrupt is also useful for creating scrolling zones, so that some
parts of the screen can be fine-scrolled while the rest remains stationary.
  Bit 1 enables the light pen interrupt.  This interrupt can occur when the
light of the raster beam strikes the light-sensitive device in the pen's tip,
causing it to close the fire button switch on joystick Controller Port #1.
  The light pen interrupt affords a method of signaling to a program that the
pen is being held to the screen, and that its position can be read.  Some
light pens provide a push-button switch which grounds one of the other lines
on the joystick port.  This switch can be pressed by the user as an additional
signal that the pen is properly positioned.  Its location can then be read in
the light pen position registers (53267-8, $D013-4).
  Bit 2 enables the sprite-foreground collision interrupt.  This interrupt can
occur if one of the srpte character's dots is touching one of the dots from
the foreground display of either text character or bitmap graphics.
  Bit 3 enables the sprite-sprite collision interrupt, which can occur if one
of the sprite character's dots is touching one of the dots of another sprite
character.
  These two interrupts are useful for games, where such collisions often
require that some action be taken immediately.  Once the interrupt signals
that a collision has occurred, the interrupt routine can check the Sprite-
Foreground Collision Register at 53279 ($D01F), or the Sprite-Sprite Collision
Register at 53278 ($D01E), to see which sprite or sprites are involved in the
collision.  See the entry for those locations for more details on collisions.

53275         $D01B          SPBGPR
Sprite to Foreground Display Priority Register

Bit 0:  Select display priority of Sprite 0 to foreground (0=sprite appears in
        front of foreground)
Bit 1:  Select display priority of Sprite 1 to foreground (0=sprite appears in
        front of foreground)
Bit 2:  Select display priority of Sprite 2 to foreground (0=sprite appears in
        front of foreground)
Bit 3:  Select display priority of Sprite 3 to foreground (0=sprite appears in
        front of foreground)
Bit 4:  Select display priority of Sprite 4 to foreground (0=sprite appears in
        front of foreground)
Bit 5:  Select display priority of Sprite 5 to foreground (0=sprite appears in
        front of foreground)
Bit 6:  Select display priority of Sprite 6 to foreground (0=sprite appears in
        front of foreground)
Bit 7:  Select display priority of Sprite 7 to foreground (0=sprite appears in
        front of foreground)

If a sprite is positioned to appear at a spot on the screen that is already
occupied by text or bitmap graphics, a conflict arises.  The contents of this
register determines which one will be displayed in such a situation.  If the
bit that corresponds to a particular sprite is set to 0, the sprite will be
displayed in front of the foreground graphics data.  If that bit is set to 1,
the foreground data will be displayed in front of the sprite.  The default
value that this register is set to at power-on is 0, so all sprites start out
with priority over foreground graphics.
  Note that for the purpose of priority, the 01 bit-pair of multicolor
graphics modes is considered to display a background color, and therefore will
be shown behind sprite graphics even if the foreground graphics data takes
priority.  Also, between the sprites themselves there is a fixed priority.
Each sprite has priority over all higher-number sprites, so that Sprite 0 is
displayed in front of all the others.
  The use of priority can aid in creating three-dimensional effects, by
allowing some objects on the screen to pass in front of or behind other
objects.

53276         $D01C          SPMC
Sprite Multicolor Registers

Bit 0:  Select multicolor mode for Sprite 0 (1=multicolor, 0=hi-res)
Bit 1:  Select multicolor mode for Sprite 1 (1=multicolor, 0=hi-res)
Bit 2:  Select multicolor mode for Sprite 2 (1=multicolor, 0=hi-res)
Bit 3:  Select multicolor mode for Sprite 3 (1=multicolor, 0=hi-res)
Bit 4:  Select multicolor mode for Sprite 4 (1=multicolor, 0=hi-res)
Bit 5:  Select multicolor mode for Sprite 5 (1=multicolor, 0=hi-res)
Bit 6:  Select multicolor mode for Sprite 6 (1=multicolor, 0=hi-res)
Bit 7:  Select multicolor mode for Sprite 7 (1=multicolor, 0=hi-res)

Sprite multicolor mode is very similar to text and bitmap multicolor modes
(see Bit 4 of 53270, $D016).  Normally, the color of each dot of the sprite is
controlled by a single bit of sprite shape data.  When thi mode is enabled for
a sprite, by setting the corresponding bit of this register to 1, the bits of
sprite shape data are grouped together in pairs, with each pair of bits
controlling a double-wide dot of the sprite display.  By sacrificing some of
the horizontal resolution (the sprite, although the same size, is now only 12
dots wide), you gain the use of two additional colors.  The four possible
combinations of these bit-pairs display dot colors from the following sources:

00 Background Color Register 0 (transparent)
01 Sprite Multicolor Register 0 (53285, $D025)
10 Sprite Color Registers (53287-94, $D027-E)
11 Sprite Multicolor Register 1 (53286, $D026)

Like multicolor text characters, multicolor sprites all share two color
registers.  While each sprite can display three foreground colors, only one of
these colors in unique to that sprite.  The number of unique colors may be
increated by combining more than one sprite into a single character.

53277         $D01D          XXPAND
Sprite Horizontal Expansion Register

Bit 0:  Expand Sprite 0 horizontally (1=double-width sprite, 0=normal width)
Bit 1:  Expand Sprite 1 horizontally (1=double-width sprite, 0=normal width)
Bit 2:  Expand Sprite 2 horizontally (1=double-width sprite, 0=normal width)
Bit 3:  Expand Sprite 3 horizontally (1=double-width sprite, 0=normal width)
Bit 4:  Expand Sprite 4 horizontally (1=double-width sprite, 0=normal width)
Bit 5:  Expand Sprite 5 horizontally (1=double-width sprite, 0=normal width)
Bit 6:  Expand Sprite 6 horizontally (1=double-width sprite, 0=normal width)
Bit 7:  Expand Sprite 7 horizontally (1=double-width sprite, 0=normal width)

This register can be used to double the width of any sprite.  Setting any bit
of this register to 1 will cause each dot of the corresponding sprite shape to
be displayed twice as wide as normal, so that without changing its horizontal
resolution, the sprite takes up twice as much space.  The horizontal expansion
feature can be used alone, or in combination with the vertical expansion
register at 53271 ($D017).

Location Range: 53278-53279 ($D01E-$D01F)
Sprite Collision Detection Registers

While Bit 2 of the VIC IRQ Register at 53273 ($D019) is set to 1 anytime two
sprites overlap, and Bit 1 is set to 1, when a sprite shape is touching the
foreground text or bit-graphics display, these registers specify which sprites
were involved in the collision.  Every bit that is set to 1 indicates that the
corresponding sprite was involved in the collision.  Reading these registers
clears them so that they can detect the next collision.  Therefore, if you
plan to make multiple tests on the values stored here, it may be necessary to
copy it to a RAM variable for further reference.
  Note that while these registers tell you what sprites were involved in a
collision, they do not necessarily tell you what objects have collided with
each other.  It is quite possible to have three sprites lined up in a row,
where Sprite A is on the left, Sprite B is in the middle, touching Sprite A,
and Sprite C is on the right, touching Sprite B but not touching Sprite A.
The Sprite-Sprite Collision register would show that all three are involved.
The only way to make absolutely certain which collided with which is to check
the position of each sprite, and calculate for each sprite display line if a
sprite of that size would touch either of the others.  As you can imagine,
this is no easy task.
  There are a few simple rules concerning what does or does not cause a
collision.  Though the sprite character consists of 504 dots in a 24 by 21
matrix, does which represent data bits that are equal to 0 (or multicolor bit-
pairs equal to 00), and therefore always displayed in the background color, do
not count when it comes to collision.
  A collision can occur only if a dot which represents a sprite shape data bit
of 1 touches another dot of nonzero graphics data.  Consider the case of two
invisible sprites.  The first sprite is enabled, its color set to contrast the
background, and it is positioned on the screen, but its shape data bytes are
all 0.  This sprite can never be involved in a collision, because it displays
no nonzero data.  The second sprite is enabled, positioned on the screen, and
its shape pointer set for a data read that is filled with bytes having a value
of 255.  Even if that sprite's color is set to the same value as the
background color, making the sprite invisible, it can still be involved in
collisions.  The only exception to this rule is the 01 bit-pair of multicolor
graphics data.  This bit-pair is considered part of the background, and the
dot it displays can never be involved in a collision.
  The other rule to remember about collisions is that they can occur in areas
that are covered by the screen border.  Collision between sprites can occur
when the sprites are offscreen, and collisions between sprites and foreground
display data can occur when that data is in an area that is covered by the
border due to the reduction of the display to 38 columns or 24 rows.

53278         $D01E          SPSPCL
Sprite to Sprite Collision Register

Bit 0:  Did Sprite 0 collide with another sprite?  (1=yes)
Bit 1:  Did Sprite 1 collide with another sprite?  (1=yes)
Bit 2:  Did Sprite 2 collide with another sprite?  (1=yes)
Bit 3:  Did Sprite 3 collide with another sprite?  (1=yes)
Bit 4:  Did Sprite 4 collide with another sprite?  (1=yes)
Bit 5:  Did Sprite 5 collide with another sprite?  (1=yes)
Bit 6:  Did Sprite 6 collide with another sprite?  (1=yes)
Bit 7:  Did Sprite 7 collide with another sprite?  (1=yes)

53279         $D01F          SPBGCL
Sprite to Foreground Collision Register

Bit 0:  Did Sprite 0 collide with the foreground display?  (1=yes)
Bit 1:  Did Sprite 1 collide with the foreground display?  (1=yes)
Bit 2:  Did Sprite 2 collide with the foreground display?  (1=yes)
Bit 3:  Did Sprite 3 collide with the foreground display?  (1=yes)
Bit 4:  Did Sprite 4 collide with the foreground display?  (1=yes)
Bit 5:  Did Sprite 5 collide with the foreground display?  (1=yes)
Bit 6:  Did Sprite 6 collide with the foreground display?  (1=yes)
Bit 7:  Did Sprite 7 collide with the foreground display?  (1=yes)

Location Range: 53280-53294 ($D020-$D02E)
VIC-II Color Register

Although these color registers are used for various purposes, all of them have
one thing in common.  Like the Color RAM Nybbles, only the lower four bits are
connected.  Therefore, when reading these registers, you must mask out the
upper four bits (that is, BORDERCOLOR=PEEK(53280)AND15) in order to get a true
reading.

53280         $D020          EXTCOL
Border Color Register

The color value here determines the color of the border or frame around the
central display area.  The entire screen is set to this color when the
blanking feature of Bit 4 of 53265 ($D011) is enabled.  The default color
value is 14 (light blue).

53281         $D021          BGCOL0
Background Color 0

This register sets the background color for all text modes, sprite graphics,
and multicolor bitmap graphics.  The default color value is 6 (blue).

53282         $D022          BGCOL1
Background Color 1

This register sets the color for the 01 bit-pair of multicolor character
graphics, and the background color for characters having screen codes 64-127
in extended background color text mode.  The default color value is 1 (white).

53283         $D023          BGCOL2
Background Color 2

This register sets the color for the 10 bit-pair of multicolor character
graphics, and the background color for characters habing screen codes 128-191
in extended background color text mode.  The default color value is 2 (red).

53285         $D024          BGCOL3
Background Color 3

This register sets the background color for characters having screen codes
between 192 and 255 in extended background color text mode.  The default color
value is 3 (cyan).

53285         $D025          SPMC0
Sprite Multicolor Register 0

This register sets the color that is displayed by the 01 bit-pair in
multicolor sprite graphics.  The default color value is 4 (purple).

53286         $D026          SPMC1
Sprite Multicolor Register 1

This register sets the color that is displayed by the 11 bit-pair in
multicolor sprite graphics.  The default color value is 0 (black).

Location Range: 53287-53294 ($D027-$D02E)
Sprite Color Registers

These registers are used to set the color to be displayed by bits of hi-res
sprite data having a value of 1, and by bit-pairs of multicolor sprite data
having a value of 10.  The color of each sprite is determined by its own
individual color register.

53287         $D027          SP0COL
Sprite 0 Color Register (the default color value is 1, white)

53288         $D028          SP1COL
Sprite 1 Color Register (the default color value is 2, red)

53289         $D029          SP2COL
Sprite 2 Color Register (the default color value is 3, cyan)

53290         $D01A          SP3COL
Sprite 3 Color Register (the default color value is 4, purple)

53291         $D01B          SP4COL
Sprite 4 Color Register (the default color value is 5, green)

53292         $D01C          SP5COL
Sprite 5 Color Register (the default color value is 6, blue)

53293         $D01D          SP6COL
Sprite 6 Color Register (the default color value is 7, yellow)

53294         $D01E          SP7COL
Sprite 7 Color Register (the default color value is 12, medium gray)

Location Range: 53295-53311 ($D02F-$D03F)
Not Connected

The VIC-II chip has only 47 registers for 64 bytes of possible address space.
Therefore, the remaining 17 addresses do not access any memory.  When read,
they will always give a value of 255 ($FF).  This value will not change after
writing to them.

Location Range: 53312-54271 ($D040-$D3FF)
VIC-II Register Images

Since the VIC-II requires only enough addressing lines to handle 64 locations
(the minimum possible for its 47 registers), none of the higher bits are
decoded when addressing this 1K area.  The result is that every 64 byte area
in this 1K block is a mirror of every other.  POKE53281+64,1 has the same
effect as POKE53281,1 or POKE53281+10*64,1; they all turn the screen
background to white.  For the sake of clarity in your programs it is advisable
to use the base address of the chip.

54272-54300   $D400-$D41C
Sound Interface Device (SID) Registers

Mmeory locations 54272-54300 ($D400-$D41C) are used to address the 6581 Sound
Interface Device (SID).
  SID is a custom music synthesizer and sound effects generator chip that
gives the 64 its impressive musical capabilities.  It provides three separate
music channels, or voices, as they are called.  Each voice has 16-bit
frequency resolution, waveform control, envelope shaping, oscillator
synchronization, and ring modulation.  In addition, programmable high-pass,
low-pass, and band-pass filters can be set and enabled or disabled for each
sound channel.
  Since quite a few of these locations must be used in concert to produce
sound, a brief summary of the interplay between some of these registers may be
helpful.
  Often the first step is to select an overall volume level using the Volume
Register.  Then, the desired frequency or pitch of the note is chosen by
writing to each of the two bytes which make up the 16-bit Frequency Register.
  An ADSR envelope setting must be chosen by writing values to the Attack/
Decay and Sustain/Release Register.  These determine the rate of the rise and
fall of the volume of the note from zero volume to peak volume and back again.
These rates have a great influence on the character of the sound.
  Finally, the waveform must be selected, and the note started (or the
oscillator gated, as we say).  This is done by writing certain bits to the
Control Register.  The waveform control lets you select one of four different
waveforms, each of which has varying harmonic content that affects the tone
quality of the sound.  By writing a 1 to the gate bit, you start the Attack/
Delay/Sustain cycle.  Afer rising to a peak and declining to the Sustain
volume, the volume will continue at the same level until you write a 0 to the
gate bit.  Then, the Release cycle will start.  Make sure that you keep the
same waveform bit set to 1 while you write the 0 to the gate bit, so that the
Release cycle starts.  Otherwise, the sound will stop entirely, as it also
will if the Volume Register or the Frequency Register is set to 0.
  It should be noted that except for the last four SID chip registers, these
addresses are write-only.  That means that their values cannot be determined
by PEEKing these locations.

Location Range: 54272-54273 ($D400-$D401)
Voice 1 Frequency Control

Together, these two locations control the frequency or pitch of the musical
output of voice 1.  Some frequency must be selected in order for voice 1 to be
heard.  This frequency may be changed in the middle of a note to achieve
special effects.  The 16-bit range of the Frequency Control Register covers
over eight full octaves, and allows you to vary the pitch from 0 (very low) to
about 4000 Hz (very high), in 65536 steps.  The exact frequency of the output
can be determined by the equation

FREQUENCY=(REGISTER VALUE*CLOCK/16777216)Hz

where CLOCK equals the system clock frequency, 1022730 for American (NTSC)
systems, 985250 for European (PAL), and REGISTER VALUE is the combined value
of these frequency registers.  That combined value equals the value of the
low byte plus 256 times the value of the high byte.  Using the American (NTSC)
clock value, the equation works out to

FREQUENCY=REGISTER VALUE*.060959458 Hz

54272         $D400          FRELO1
Voice 1 Frequency Control (low byte)

54273         $D401          FREHI1
Voice 1 Frequency Control (high byte)

Location Range: 54274-54275 ($D402-$D403)
Voice 1 Pulse Waveform Width Control

As you will see below under the description of the Control Register at 54276
($D404), you can select one of four different waveforms for the output of each
voice.  If the pulse waveform is selected, these registers must be set to
establish the pulse width.
  The pulse width has a 12-bit resolution, being made up of the value in the
first register and the value in the lower nybble of the second register.  The
pulse width determines the duty cycle, or proportion of the time that the
rectangular wave will stay at the high part of the cycle.
  The following formula shows the relationship between the value in the Pulse
Width Register and the proportion of time that the wave stays at the high part
of the cycle:

PULSE WIDTH=(REGISTER VALUE/40.95)%

The possible range of the register values (0-4095) covers the range of the
duty cycles from 0 to 100 percent in 4096 steps.  Changing the pulse width
will vastly change the sound created with the pulse waveform.

54274         $D402          PWLO1
Voice 1 Pulse Waveform Width (low byte)

54275         $D403          PWHI1
Voice 1 Pulse Waveform Width (high nybble)

54276         $D404          VCREG1
Voice 1 Control Register

Bit 0:  Gate Bit:  1=Start attack/decay/sustain, 0=Start release
Bit 1:  Sync Bit:  1=Synchronize Oscillator with Oscillator 3 frequency
Bit 2:  Ring Modulation:  1=Ring modulate Oscillators 1 and 3
Bit 3:  Test Bit:  1=Disable Oscillator 1
Bit 4:  Select triangle waveform
Bit 5:  Select sawtooth waveform
Bit 6:  Select pulse waveform
Bit 7:  Select random noise waveform

  Bit 0.  Bit 0 is used to gate the sound.  Setting this bit to a 1 while
selecting one of the four waveforms will start the attack/decay/sustain part
of the cycle.  Setting this bit back to 0 (while keeping the same waveform
setting) anytime after a note has started playing will begin the release cycle
of the note.  Of course, in order for the gate bit to have an effect, the
frequency and attack/decay/sustain/release (ADSR) registers must be set, as
well as the pulse width, if necessary, and the volume control set to a nonzero
value.
  Bit 1.  This bit is used to synchronize the fundamental frequency of
Oscillator 1 with the fundamental frequency of Oscillator 3, allowing you to
create a wide range of complex harmonic structures from voice 1.
Synchronization occurs when this bit is set to 1.  Oscillator 3 must be set to
some frequency other than zero, but no other voice 3 parameters will affect
the output from voice 1.
  Bit 2.  When Bit 2 is set to 1, the triangle waveform output of voice 1 is
replaced with a ring modulated combination of Oscillators 1 and 3.  This ring
modulation produces nonharmonic overtone structures that are useful for
creating bell or gong effects.
  Bit 3.  Bit 3 is the test bit.  When set to 1, it disables the output of the
oscillator.  This can be useful in generating very complex waveforms (even
speech synthesis) under software control.
  Bit 4.  When set to 1, Bit 4 selects the triangle waveform output of
Oscillator 1.  Bit 0 must also be set for the note to be sounded.
  Bit 5.  This bit selects the sawtooth waveform when set to 1.  Bit 0 must
also be set for the sound to begin.
  Bit 6.  Bit 6 chooses the pulse waveform when set to 1.  The harmonic
content of sound produced using this waveform may be varied using the Pulse
Width Registers.  Bit 0 must be set to begin the sound.
  Bit 7.  When Bit 7 is set to 1, the noise output waveform for Oscillator 1
is set.  This creates a random sound output whose waveform varies with a
frequency proportionate to that of Oscillator 1.  It can be used to imitate
the sound of explosions, drums, and other unpitched noises.
  One of the four waveforms must be chosed in order to create a sound.
Setting more than one of these bits will result in a logical ANDing of the
waveforms.  Particularly, the combination of the noise waveform and another is
not recommended.

Location Range: 54277-54278 ($D405-$D406)
Voice 1 Envelop (ADSR) Control

When a note is played on a musical instrument, the volume does not suddenly
rise to a peak and then cut off to zero.  Rather, the volume builds to a peak,
levels off to an intermediate value, and then fades away.  This creates what
is known as a volume envelope.
  The first phase of the envelope, in which the volume builds to a peak, is
known as the attack phase.  The second, in which it declines to an
intermediate level, is called the decay phase.  The third, in which the
intermediate leve of volume is held, is known as the sustain period.  The
final interval, in which the sound fades away, is called the release part of
the cycle.
  The SID chip allows the volume envelope of each voice to be controlled, so
that specific instruments may be imitated, or new sounds created.  This is
done via the attack/decay and sustain/release registers.  Each register
devotes four bits (which can store a number from 0 to 15) to each phase of the
cycle.  When a note is gated by writing a 1 to a waveform bit and to Bit 0 of
the Control Register, the attack cycle begins.
  The volume of the sound builds to a peak over the period of time specified
by the high nybble of the attack/decay register.  Once it has reached the peak
volume, it falls to the intermediate level during the period indicated by the
low nybble of the attack/decay register (this is the decay phase).  The volume
of this intermediate or sustain level is selected by placing a value in the
high nybble of the sustain/release register.  This volume level is held until
a 0 is written to the gate bit of the control register (while leaving the
waveform bit set).  When that happens, the release phase begins, and the
volume of the sound begins to taper off during the period indicated by the low
nybble of the sustain/release register.
  You may notice the volume of the sound does not quite get to 0 at the end of
the release cycle, and you may need to turn off the sound to get rid of the
residual noise.  You can do this either by setting the waveform bit back to 0,
changing the frequency to 0, or setting the volume to 0.

54277         $D405          ATDCY1
Voice 1 Attack/Decay Register

Bits 0-3:  Select decay cycle duration (0-15)
Bits 4-7:  Select attack cycle duration (0-15)

Bits 4-7 control the duration of the attack cycle.  This is the period of time
over which the volume will rise from 0 to its peak amplitude.  There are 16
durations which may be selected.  The way in which the number placed here
corresponds to the elapsed time of this cycle is as follows:

0 = 2 milliseconds           8 = 100 milliseconds
1 = 8 milliseconds           9 = 250 milliseconds
2 = 16 milliseconds         10 = 500 milliseconds
3 = 24 milliseconds         11 = 800 milliseconds
4 = 38 milliseconds         12 = 1 second
5 = 56 milliseconds         13 = 3 seconds
6 = 68 milliseconds         14 = 5 seconds
7 = 80 milliseconds         15 = 8 seconds

Bits 0-3 control the length of the decay phase, in which the volume of the
note declines from the peak reached in the attack phase to the sustain level.
The number selected corresponds to the length of this phase as shown below:

0 = 6 milliseconds           8 = 300 milliseconds
1 = 24 milliseconds          9 = 750 milliseconds
2 = 48 milliseconds         10 = 1.5 seconds
3 = 72 milliseconds         11 = 2.4 seconds
4 = 114 milliseconds        12 = 3 seconds
5 = 168 milliseconds        13 = 9 seconds
6 = 204 milliseconds        14 = 15 seconds
7 = 240 milliseconds        15 = 24 seconds

Since the two functions share one register, you must multiply the attack value
by 16 and add it to the decay value in order to come up with the number to be
placed in the register:

REGISTER VALUE=(ATTACK*16)+DECAY

54278         $D406          SUREL1
Voice 1 Sustain/Release Control Register

Bits 0-3:  Select release cycle duration (0-15)
Bits 4-7:  Select sustain volume level (0-15)

Bits 4-7 select the volume level at which the note is sustained.  Following
the decay cycle, the volume of the output of voice 1 will remain at the
selected sustain level as long as the gate bit of the Control Register is set
to 1.  The sustain values range from 0, which chooses no volume, to 15, which
sets the output of voice 1 equal to the peak volume achieved during the attack
cycle.
  Bits 0-3 determine the length of the release cycle.  This phase, in which
the volume fades from the sustain level to near zero volume, begins when the
gate bit of the Control Register is set to 0 (while leaving the waveform
setting that was previously chosen).  The duration of this decline in volume
corresponds to the number (0-15) selected in the same way as for the decay
value:

0 = 6 milliseconds           8 = 300 milliseconds
1 = 24 milliseconds          9 = 750 milliseconds
2 = 48 milliseconds         10 = 1.5 seconds
3 = 72 milliseconds         11 = 2.4 seconds
4 = 114 milliseconds        12 = 3 seconds
5 = 168 milliseconds        13 = 9 seconds
6 = 204 milliseconds        14 = 15 seconds
7 = 240 milliseconds        15 = 24 seconds

Location Range: 54279-54292 ($D407-$D414)
Voice 2 and Voice 3 Controls

The various control registers for these two voices correspond almost exactly
to those of voice 1.  The one exception is that the sync and ring-modulation
bits of voice 2 operate on Oscillators 1 and 2, while the same bits of the
Control Register for voice 3 uses Oscillators 2 and 3.

54279         $D407          FRELO2
Voice 2 Frequency Control (low byte)

54280         $D408          FREHI2
Voice 2 Frequency Control (high byte)

54281         $D409          PWLO2
Voice 2 Pulse Waveform Width (low byte)

54282         $D40A          PWHI2
Voice 2 Pulse Waveform Width (high nybble)

54283         $D40B          VCREG2
Voice 2 Control Register

Bit 0:  Gate Bit:  1=Start attack/decay/sustain, 0=Start release
Bit 1:  Sync Bit:  1=Synchronize oscillator with Oscillator 1 frequency
Bit 2:  Ring Modulation:  1=Ring modulate Oscillators 2 and 1
Bit 3:  Test Bit:  1=Disable Oscillator 2
Bit 4:  Select triangle waveform
Bit 5:  Select sawtooth waveform
Bit 6:  Select pulse waveform
Bit 7:  Select noise waveform

54284         $D40C          ATDCY2
Voice 2 Attack/Decay Register

Bits 0-3:  Select decay cycle duration (0-15)
Bits 4-7:  Select attack cycle duration (0-15)

54285         $D40D          SUREL2
Voice 2 Sustain/Release Control Register

Bits 0-3:  Select release cycle duration (0-15)
Bits 4-7:  Select sustain volume level (0-15)

54286         $D40E          FRELO3
Voice 3 Frequency Control (low byte)

54287         $D40F          FREHI3
Voice 3 Frequency Control (high byte)

54288         $D410          PWLO3
Voice 3 Pulse Waveform Width (low byte)

54289         $D411          PWHI3
Voice 3 Pulse Waveform Width (high nybble)

54290         $D412          VCREG3
Voice 3 Control Register

Bit 0:  Gate Bit:  1=Start attack/decay/sustain, 0=Start release
Bit 1:  Sync Bit:  1=Synchronize oscillator with Oscillator 2 frequency
Bit 2:  Ring Modulation:  1=Ring modulate Oscillators 3 and 2
Bit 3:  Test Bit:  1=Disable Oscillator 3
Bit 4:  Select triangle waveform
Bit 5:  Select sawtooth waveform
Bit 6:  Select pulse waveform
Bit 7:  Select noise waveform

54291         $D413          ATDCY3
Voice 3 Attack/Decay Register

Bits 0-3:  Select decay cycle duration (0-15)
Bits 4-7:  Select attack cycle duration (0-15)

54292         $D414          SUREL3
Voice 3 Sustain/Release Control Register

Bits 0-3:  Select release cycle duration (0-15)
Bits 4-7:  Select sustain volume level (0-15)

Location Range: 54293-54296 ($D415-$D418)
Filter Controls

In addition to the controls detailed above for each voice, the SID chip also
provides a filtering capability which allows you to attenuate (make quieter)
certain ranges of frequencies.  Any one or all three voices can be filtered,
and there is even a provision for filtering an external signal that is input
through pin 5 of the monitor jack.
  A low-pass filter is available, which suppresses the volume of those
frequency components that are above a designated cutoff level.  The high-pass
filter reduces the volume of frequency components that are below a certain
level.  The band-pass filter reduces the volume of frequency components on
both sides of the chosen frequency, thereby enhancing that frequency.
Finally, the high-pass and low-pass filters can be combined to form a notch
reject filter, which reduces the folume of the frequency components nearest
the selected frequency.  These various filters can dramatically change the
quality of the sound produced.
  The first two registers are used to select the filter cutoff frequency.
This is the frequency above or below which any sounds will be made quieter.
The further away from this level any frequency components are, the more their
output volume will be suppresed (high- and low-pass filters reduce the volume
of those components by 12 dB per octave away from the center frequency, while
the band-pass filter attenuates them by 6 dB per octave).
  The cutoff frequency has an 11-bit range (which corresponds to the numbers
0 to 2047).  This is made up of a high-byte and three low bits.  Therefore, to
compute the frequency represented by the value in these registers, you must
multiply the value in the high byte by 8, and add the value of the low three
bits.  The range of cutoff freqnencies represented by these 2048 values
stretches from 30 Hz to about 12,000 Hz.  The exact frequency may be
calculated with the formula:

FREQUENCY=(REGISTER VALUE*5.8)+30Hz

An additional element in filtering is the resonance control.  This allows you
to peak the volume of the frequency elements nearest the cutoff frequency.

54293         $D415          CUTLO

Bits 0-2:  Low portion of filter cutoff frequency
Bits 5-7:  Unused

54294         $D416          CUTHI
Filter Cutoff Frequency (high byte)

54295         $D417          RESON
Filter Resonance Control Register

Bit 0:  Filter the output of voice 1?  1=yes
Bit 1:  Filter the output of voice 2?  1=yes
Bit 2:  Filter the output of voice 3?  1=yes
Bit 3:  Filter the output from the external input?  1=yes
Bits 4-7:  Select filter resonance 0-15

Bits 0-3 are used to control which of the voices will be altered by the
filters.  If one of these bits is set to 1, the corresponding voice will be
processed through the filter, and its harmonic content will be changed
accordingly.  If the bit is set to 0, the voice will pass directly to the
audio output.  Note that there is also a provision for processing an external
audio signal which is brought through pin 5 of the Audio/Video Port.
  Bits 4-7 control the resonance of the filter.  By placing a number from 0 to
15 in these four bits, you may peak the volume of those frequencies nearest
the cutoff.  This creates an even sharper filtering effect.  A setting of 0
causes no resonance, while a setting of 15 gives maximum resonance.

54296         $D418          SIGVOL
Volume and Filter Select Register

Bits 0-3:  Select output volume (0-15)
Bit 4:  Select low-pass filter, 1=low-pass on
Bit 5:  Select band-pass filter, 1=band-pass on
Bit 6:  Select high-pass filter, 1=high-pass on
Bit 7:  Disconnect output of voice 4, 1=voice 3 off

Bits 0-3 control the volume of all outputs.  The possible volume levels range
from 0 (no volume) to 15 (maximum volume).  Some level of volume must be set
here before any sound can be heard.
  Bits 4-6 control the selection of the low-pass, band-pass, or high-pass
filter.  A 1 in any of these bits turns the corresponding filter on.  These
filters can be combined, although only one cutoff frequency can be chosen.  In
order for the filter to have any effect, at least one of the voices must be
routed through it using the Filter Resonance Control Register at 54295
($D417).
  When Bit 7 is set to 1,  it disconnects the output of voice 3.  This allows
you to use the output of the oscillator for modulating the frequency of the
other voices, or for generating random number, without any undesired audio
output.

Location Range: 54297-54298 ($D419-$D41A)
Game Paddle Inputs

These registers allow you to read the game paddles that plug into joystick
Controller Ports 1 and 2.  Each paddle uses a variable resistor (also known as
a potentiometer or pot), whose resistance is controlled by turning a knob.
The varying resistance is used to vary the voltage to two pins of the SID chip
between 0 and +5 volts.  Analog-to-digital (A/D) converters in the chip
interpret these voltage levels as binary values and store the values in these
registers.  These registers return a number from 0 (minumum resistance) to 255
(maximum resistance) for each paddle in either of the ports, depending on the
position of the paddle knob.
  Since these registers will read the paddle values for only one controller
port, there is a switching mechanism which allows you to select which of the
two ports to read.  By writing a bit-pair of 01 (bit value of 64) to the last
two bits of CIA #1 Data Port A (56320, $DC00), you select the paddles on
joystick Controller Port 1.  By writing a bit-pair of 10 (bit value of 128),
you select the paddles on Controller Port 2.
  If you look at the description of Data Port A (56320, $DC00), however, you
will notice that it is also used in the keyboard scanning process.  By writing
to this port, you determine which keyboard column will be read.
  Since the IRQ interrupt keyboard scan routine and the routine that checks
for the STOP key are putting values into this location 60 times per second,
you cannot reliable select the pair of paddles you wish to read from BASIC
without first turning off the keyboard IRQ.  This can be done with a POKE
56333,127.  You can then read the paddles with the statements A=PEEK(54297)
and B=PEEK(54298).  The IRQ can be restored after a paddle read with a POKE
56333,129.  It may, however, be easier and more accurate in the long run to
use a machine language paddle read subroutine such as that presented on page
347 of the Commodore 64 Programmer's Reference Guide.
  The paddle fire buttons are read as Bits 2 and 3 of the Data Ports A (56320,
$DC00) and B (56321, $DC01).  On Port A, if Bit 2 is set to 0, button 1 is
pushed, and if Bit 3 is set to 0, button 2 is pushed.  On Port B, if Bit 2 is
set to 0, button 3 is pushed, and if Bit 3 is set to 0, button 4 is pushed.
  The BASIC statements to test these buttons, thereore, are:

PB(1)=(PEEK(56321)AND4)/4
PB(2)=(PEEK(56321)AND8)/8
PB(3)=(PEEK(56320)AND4)/4
PB(4)=(PEEK(56320)AND8)/8

If a 0 is returned by the PEEK statement, the button is pushed, and if a 1 is
returned, it is not.

54297         $D419          POTX
Read Game Paddle 1 (or 3) Position

54298         $D41A          POTY
Read Game Paddle 2 (or 4) Position

54299         $D41B          RANDOM
Read Oscillator 3/Random Number Generator

This register lets you read the upper eight bits of the waveform output of
Oscillator 3.  The kinds of numbers generated by this output depend on the
type of waveform selected.
  If the sawtooth waveform is chosen, the output read by this register will be
a series of numbers which start at 0 and increase by 1 to a maximum of 255, at
which time they start over at 0.
  When the triangle waveform is chosen, they increase from 0 to 255, at which
time they decrease to 0 again.  The rate at which these numbers change is
determined by the frequency of Oscillator 3.
  If the pulse waveform is selected, the output here will be either 255 or 0.
  Finally, selecting the noise waveform will produce a random series of
numbers between 0 and 255.  This allows you to use the register as a random
number generator for games.
  There are many other uses for reading Oscillator 3, however, particularly
for modulation of the other voices through machine language software.  For
example, the output of this register could be added to the frequency of
another voice.  If the triangle waveform were selected for this purpose, it
would cause the frequency of the other voice to rise and fall, at the
frequency of Oscillator 3 (perhaps for vibrato effects).  This output can also
be combined with the Filter Frequency or Pulse Width Registers to vary the
values in these registers quickly over a short period of time.
  Normally, when using Oscillator 3 for modulation, the audio output of voice
3 should be turned off by setting Bit 7 of the Volume and Filter Select
Register at 54296 ($d418) to 1.  It is not necessary to gate Bit 0 of Control
Register 3 to use the oscillator, however, as its output is not affected by
the ADSR envelope cycle.

54300         $D41C          ENV3
Envelope Generator 3 Output

This register allows you to read the output of the voice 3 Envelope generator,
in much the same way that the preceding register lets you read the output of
Oscillator 3.  This output can also be added to another oscillator's Frequency
Control Registers, Pulse Width Registers, or the Filter Frequency Control
Register.  In order to produce any output from this register, however, the
gate bit in Control Register 3 must be set to 1.  Just as in the production of
sound, setting the gate bit to 1 starts the attack/decay/sustain cycle, and
setting it back to 0 starts the release cycle.

Location Range: 54301-54303 ($D41D-$D41F)
Not Connected

The SID chip has been provided with enough addresses for 32 different
registers, but as it has only 29, the remaining three addresses are not used.
Reading them will always return a value of 255 ($FF), and writing to them will
have no effect.

Location Range: 54304-55295 ($D420-$D7FF)
SID Register Images

Since the SID chip requires enough addressing lines for only 32 locations (the
minimum possible for its 29 registers), none of the higher bits are decoded
when addressing the 1K area that has been assigned to it.  The result is that
every 32-byte area in this 1K block is a mirror of every other.  For the sake
of clarity in your programs, it is advisable not to use these addresses at
all.

55296-56319   $D800-$DBFF
Color RAM

The normal Commodore 64 text graphics system uses a screen RAM area to keep
track of the character shapes that are to be displayed.  But since each
character can be displayed in any of 16 foreground colors, there must also be
a parallel area which keeps track of the foreground color.  This 1024-byte
area is used for that purpose (actually, since there are only 1000 screen
positions, only 1000 byte actually affect screen color).
  These 1000 bytes each control the foreground color of one character, with
the first byte controlling the foreground color of the character in the upper-
left corner, and subsequent bytes controlling the characters to the right and
below that character.
  Because only four bits are needed to represent the 16 colors available, only
the low four bits of each Color RAM location are connected (this is why they
are sometimes referred to as Color RAM Nybbles).  Writing to the high bits
will not affect them, and these four bits will usually return a random value
when read (a small number of 64s return a constant value).
  Therefore, in order to read Color RAM correctly, you must mask out the top
bits by using the logical AND function.  In BASIC, you can read the first byte
of Color RAM with the statement CR=PEEK(55296)AND15.  This will always return
a color value between 0 and 15.  These color values correspond to the
following colors:

 0 = BLACK
 1 = WHITE
 2 = RED
 3 = CYAN (LIGHT BLUE-GREEN)
 4 = PURPLE
 5 = GREEN
 6 = BLUE
 7 = YELLOW
 8 = ORANGE
 9 = BROWN
10 = LIGHT RED
11 = DARK GRAY
12 = MEDIUM GRAY
13 = LIGHT GREEN
14 = LIGHT BLUE
15 = LIGHT GRAY

Color mapping affords a convenient method of changing the color of the text
display without changing the letters.  By POKEing the appropriate section of
Color RAM, you can change the color of a whole section of text on the screen
without affecting the content of the text.  You can even use this method to
make letters disappear by changing their foreground colors to match the
background (or by changing the background to match the foreground), and later
make them reappear by changing them back, or by changing the background to
a contrasting color.  An interesting example program which changes Color RAM
quickly in BASIC can be found under the entry for 648 ($288).
  A change in the Operating System causes newer 64s to set all of the Color
RAM locations to the same value as the current background color whenever the
screen is cleared.  Therefore, POKEing character codes to the Screen RAM area
will not appear to have any effect, because the letters will be the same color
as the background.  This can easily be turned to your advantage, however,
because it means that all you have to do to set all of Color RAM to a
particular value is to set the background color to that value (using the
register at 53281 ($D021)), clear the screen, and return the background color
in the desired value.
  The various garphics modes use this area differently than does the regular
text mode.  In high-resolution bitmap mode, this area is not used at all, but
in multicolor bitmap mode it is used to determine the color of the 11 bit-pair
for a given 8 by 8 dot area.
  In multicolor text mode, only the lowest three bits are used, so only colors
0-7 may be selected.  The fourth bit is used to determine whether a character
will be displayed in regular text or multicolor text.  Characters with a color
value over 7 are displayed as multicolor characters, with the color of the 11
bit-pair determined by the color value minus 8.  Characters with a color value
under 8 are displayed normally.
  It should be noted that unlike the Screen RAM area, which can be moved to
any RAM location, the Color RAM area is fixed, and will function normally
regardless of where screen memory is located.

56320-56335   $DC00-$DC0F
Complex Interface Adapter (CIA) #1 Registers

Locations 56320-56335 ($DC00-$DC0F) are used to communicate with the Complex
Interface Adapter chip #1 (CIA #1).  This chip is a successor to the earlier
VIA and PIA devices used on the VIC-20 and PET.  This chip functions the same
way as the VIA and PIA:  It allows the 6510 microprocessor to communicate with
peripheral input and output devices.  The specific devices that CIA #1 reads
data from and sends data to are the joystick controllers, the paddle fire
buttons, and the keyboard.
  In addition to its two data ports, CIA #1 has two timers, each of which can
count an interval from a millionth of a second to a fifteenth of a second.  Or
the timers can be hooked together to count much longer intervals.  CIA #1 has
an interrupt line which is connected to the 6510 IRQ line.  These two timers
can be used to generate interrupts at specified intervals (such as the 1/60
second interrupt used for keyboard scanning, or the more complexly timed
interrupts that drive the tape read and write routines).  As you will see
below, the CIA chip has a host of other features to aid in Input/Output
functions.

Location Range: 56320-56321 ($DC00-$DC01)
CIA #1 Data Ports A and B

These registers are where the actual communication with outside devices takes
place.  Bits of data written to these registers can be sent to external
devices, while bits of data that those devices send can be read here.
  The keyboard is so necessary to the computer's operation that you may have
a hard time thinking of it as a peripheral device.  Nonetheless, it cannot be
directly read by the 6510 microprocessor.  Instead, the keys are connected in
a matrix of eight rows by eight columns to CIA #1 Ports A and B.  The layout
of this matrix is shown below.

WRITE TO PORT A               READ PORT B (56321, $DC01)
56320/$DC00
                Bit 7   Bit 6   Bit 5   Bit 4   Bit 3   Bit 2   Bit 1   Bit 0

Bit 7           STOP    Q       C=      SPACE   2       CTRL    <-      1

Bit 6           /       ^       =       RSHIFT  HOME    ;       *       LIRA

Bit 5           ,       @       :       .       -       L       P       +

Bit 4           N       O       K       M       0       J       I       9

Bit 3           V       U       H       B       8       G       Y       7

Bit 2           X       T       F       C       6       D       R       5

Bit 1           LSHIFT  E       S       Z       4       A       W       3

Bit 0           CRSR DN F5      F3      F1      F7      CRSR RT RETURN  DELETE

As you can see, there are two keys which do not appear in the matrix.  The
SHIFT LOCK key is not read as a separate key, but rather is a mechanical
device which holds the left SHIFT key switch in a closed position.  The
RESTORE key is not read like the other keys either.  It is directly connected
to the NMI interrupt line of the 6510 microprocessor, and causes an NMI
interrupt to occur whenever it is pressed (not just when it is pressed with
the STOP key).
  In order to read the individual keys in the matrix, you must first set Port
A for all outputs (255, $FF), and Port B for all inputs (0), using the Data
Direction Registers.  Note that this is the default condition.  Next, you must
write a 0 in the bit of Data Port A that corresponds to the column that you
wish to read, and a 1 to the bits that correspond to columns you wish to
ignore.  You will then be able to read Data Port B to see which keys in that
column are being pushed.
  A 0 in any bit position signifies that the key in the corresponding row of
the selected column is being pressed, while a 1 indicates that the key is not
being pressed.  A value of 255 ($FF) means that no keys in that column are
being pressed.
  Fortunately for us all, an interrupt routine causes the keyboard to be read,
and the results are made available to the Operating System automatically every
1/60 second.  And even when the normal interrupt routine cannot be used, you
can use the Kernal SCNKEY routine at 65439 ($FF9F) to read the keyboard.
  These same data ports are also used to read the joystick controllers.
Although common sense might lead you to believe that you could read the
joystick that is plugged into the port marked Controller Port 1 from Data Port
A, and the second joystick from Data Port B, there is nothing common about the
Commodore 64.  Controller Port 1 is read from Data Port B, and Controller Port
2 is read from CIA #1 Data Port A.
  Joysticks consist of five switches, one each for up, down, right, and left
directions, and another for the fire button.  The switches are read like the
key switches--if the switch is pressed, the corresponding bit will read 0, and
if it is not pressed, the bit will be set to 1.  From BASIC, you can PEEK the
ports and use the AND and NOT operators to mask the unused bits and inverse
the logic for easier comprehension.  For example, to read the joystick in
Controller Port 1, you could use the statement:

S1=NOT PEEK(56321)AND15

The meaning of the possible numbers returned are:

 0 = none pressed
 1 = up
 2 = down
 4 = left
 5 = up left
 6 = down left
 8 = right
 9 = up right
10 = down right

The same technique can be used for joystick 2, by substituting 56320 as the
number to PEEK.  By the way, the 3 and 7 aren't listed because they represent
impossible combinations like up-down.
  To read the fire buttons, you can PEEK the appropriate port and use the AND
operator to mask all but bit 4:

T1=(PEEK(56321)AND16)/16

The above will return a 0 if the button is pressed, and a 1 if it is not.
Substitute location 56320 as the location to PEEK for Trigger Button 2.
  Since CIA #1 Data Port B is used for reading the keyboard as well as
joystick 1, some confusion can result.  The routine that checks the keyboard
has no way of telling whether a particular bit was set to 0 by a keypress or
one of the joystick switches.  For example, if you plug the joystick into
Controller Port 1 and push the stick to the right, the routine will interpret
this as the 2 key being pressed, because both set the same bit to 0.
Likewise, when you read the joystick, it will register as being pushed to the
right if the 2 key is being pressed.
  The problem of mistaking the keyboard for the joystick can be solved by
turning off the keyscan momentarily when reading the stick with a POKE 56333,
127:POKE 56320,255, and restoring it after the read with a POKE 56333,129.
Sometimes you can use the simpler solution of clearing the keyboard buffer
after reading the joystick, with a POKE 198,0.
  The problem of mistaking the joystick for a keypress is much more
difficult--there is no real way to turn off the joystick.  Many commercially
available games just use Controller Port 2 to avoid the conflict.  So, if you
can't beat them, sit back and press your joystick to the left in order to
slow down a program listing (the keyscan routine thinks that it is the CTRL
key).
  As if all of the above were not enough, Port A is also used to control
which set of paddles is read by the SID chip, and to read the paddle fire
buttons.  Since there are two paddles per joystick Controller Port, and only
two SID registers for reading paddle positions, there has to be a method for
switching the paddle read from joystick Port 1 to joystick Port 2.
  When Bit 7 of Port A is set to 1 and Bit 6 is cleared to 0, the SID
registers will read the paddles on Port 1.  When Bit 7 is set to 0 and Bit 6
is set to 1, the paddles on Port 2 are read by the SID chip registers.  Note
that this also conflicts with the keyscan routine, which is constantly writing
different values to CIA #1 Data Port A in order to select the keyboard column
to read (most of the time, the value for the last column is written to this
port, which coincides with the selection of paddles on joystick Port 1).
Therefore, in order to get an accurate reading, you must turn off the keyscan
IRQ and select which joystick port you want to read.  See POTX at 54297
($D419), which is the SID register where the paddles are read, for the exact
technique.
  Although the SID chip is used to read the paddle settings, the fire buttons
are read at CIA #1 Data Ports A and B.  The fire buttons for the paddles
plugged into Controller Port 1 are read at Data Port B (56321, $DC01), while
those for the paddles plugged into Controller Port 2 are read from Data Port A
(56320, $DC00).  The fire buttons are read at Bit 2 and Bit 3 of each port
(the same as the joystick left and joystick right switches), and as usual, the
bit will read 0 if the corresponding button is pushed, and 1 if it is not.
  Although only two of the rout paddle values can be read at any one time, you
can always read all four paddle buttons.  See the game paddle input
description at 54297 ($D419) for the BASIC statements used to read these
buttons.
  Finally, Data Port B can also be used as an output by either Timer A or B.
It is possible to set a mode in which the timers do not cause an interrupt
when they run down (see the descriptions of Control Registers A and B at
56334-5 ($DC0E-F)).  Instead, they cause the output on Bit 6 or 7 of Data Port
B to change.  Timer A can be set either to pulse the output of Bit 6 for one
machine cycle, or to toggle that bit from 1 to 0 or 0 to 1.  Timer B can use
Bit 7 of this register for the same purpose.

56320         $DC00          CIAPRA
Data Port Register A

Bit 0:  Select to read keyboard column 0
        Read joystick 2 up direction
Bit 1:  Select to read keyboard column 1
        Read joystick 2 down direction
Bit 2:  Select to read keyboard column 2
        Read joystick 2 left direction
        Read paddle 1 fire button
Bit 3:  Select to read keyboard column 3
        Read joystick 2 right direction
        Read paddle 2 fire button
Bit 4:  Select to read keyboard column 4
        Read joystick 2 fire button
Bit 5:  Select to read keyboard column 5
Bit 6:  Select to read keyboard column 6
        Select to read paddles on Port A or B
Bit 7:  Select to read keyboard column 7
        Select to read paddles on Port A or B

56321         $DC01          CIAPRB
Data Port Register B

Bit 0:  Read keyboard row 0
        Read joystick 1 up direction
Bit 1:  Read keyboard row 1
        Read joystick 1 down direction
Bit 2:  Read keyboard row 2
        Read joystick 1 left direction
        Read paddle 1 fire button
Bit 3:  Read keyboard row 3
        Read joystick 1 right direction
        Read paddle 2 fire button
Bit 4:  Read keyboard row 4
        Read joystick 1 fire button
Bit 5:  Read keyboard row 5
Bit 6:  Read keyboard row 6
        Toggle or pulse data output for Timer A
Bit 7:  Read keyboard row 7
        Toggle or pulse data output for Timer B

Location Range: 56322-56323 ($DC02-$DC03)
CIA #1 Data Direction Registers A and B

These Data Direction Registers control the direction of data flow over Data
Ports A and B.  Each bit controls the direction of the data on the
corresponding bit of the port.  If teh bit of the Direction Register is set to
a 1, the corresponding Data Port bit will be used for data output.  If the bit
is set to a 0, the corresponding Data Port bit will be used for data input.
For example, Bit 7 of Data Direction Register A controls Bit 7 of Data Port A,
and if that direction bit is set to 0, Bit 7 of Data Port A will be used for
data input.  If the direction bit is set to 1, however, data Bit 7 on Port A
will be used for data output.
  The default setting for Data Direction Register A is 255 (all outputs), and
for Data Direction Register B it is 0 (all inputs).  This corresponds to the
setting used when reading the keyboard (the keyboard column number is written
to Data Port A, and the row number is then read in Data Port B).

56322         $DC02          CIDDRA
Data Direction Register A

Bit 0:  Select Bit 0 of Data Port A for input or output (0=input, 1=output)
Bit 1:  Select Bit 1 of Data Port A for input or output (0=input, 1=output)
Bit 2:  Select Bit 2 of Data Port A for input or output (0=input, 1=output)
Bit 3:  Select Bit 3 of Data Port A for input or output (0=input, 1=output)
Bit 4:  Select Bit 4 of Data Port A for input or output (0=input, 1=output)
Bit 5:  Select Bit 5 of Data Port A for input or output (0=input, 1=output)
Bit 6:  Select Bit 6 of Data Port A for input or output (0=input, 1=output)
Bit 7:  Select Bit 7 of Data Port A for input or output (0=input, 1=output)

56323         $DC03          CIDDRB
Data Direction Register B

Bit 0:  Select Bit 0 of Data Port B for input or output (0=input, 1=output)
Bit 1:  Select Bit 1 of Data Port B for input or output (0=input, 1=output)
Bit 2:  Select Bit 2 of Data Port B for input or output (0=input, 1=output)
Bit 3:  Select Bit 3 of Data Port B for input or output (0=input, 1=output)
Bit 4:  Select Bit 4 of Data Port B for input or output (0=input, 1=output)
Bit 5:  Select Bit 5 of Data Port B for input or output (0=input, 1=output)
Bit 6:  Select Bit 6 of Data Port B for input or output (0=input, 1=output)
Bit 7:  Select Bit 7 of Data Port B for input or output (0=input, 1=output)

Location Range: 56324-56327 ($DC04-$DC07)
Timers A and B Low and High Bytes

These four timer registers (two for each timer) have different functions
depending on whether you are reading from them or writing to them.  When you
read from these registers, you get the present value of the Timer Counter
(which counts down from its initial value to 0).  When you write data to these
registers, it is stored in the Timer Latch, and from there it can be used to
load the Timer Counter using the Force Load bit of Control Register A or B
(see 56334-5 ($DC0E-F) below).
  These interval timers can hold a 16-bit number from 0 to 65535, in normal
6510 low-byte, high-byte format (VALUE=LOW BYTE+256*HIGH BYTE).  Once the
Timer Counter is set to an initial value, and the timer is started, the timer
will count down one number every microprocessor clock cycle.  Since the clock
speed of the 64 (using the American NTSC television standard) is 1,022,730
cycles per second, every count takes approximately a millionth of a second.
The formula for calculating the amount of time it will take for the timer to
count down from its latch value to 0 is:

TIME=LATCH VALUE/CLOCK SPEED

where LATCH VALUE is the value written to the low and high timer registers
(LATCH VALUE=TIMER LOW+256*TIMER HIGH), and CLOCK SPEED is 1,022,370 cycles
per second for American (NTSC) standard television monitors, or 985,250 for
European (PAL) monitors.
  When Timer Counter A or B gets to 0, it will set Bit 0 or 1 in the Interrupt
Control Register at 56333 ($DC0D).  If the timer interrupt has been enabled
(see 56333 ($DC0D)), an IRQ will take place, and the high bit of the Interrupt
Control Register will be set to 1.  Alternately, if the Port B output bit is
set, the timer will write data to Bit 6 or 7 of Port B.  After the timer gets
to 0, it will reload the Timer Latch Value, and either stop or count down
again, depending on whether it is in one-shot or continuous mode (determined
by Bit 3 of the Control Register).
  Although usually a timer will be used to count the microprocessor cycles,
Timer A can count either the microprocessor clock cycles or external pulses on
the CTN line, which is connected to pin 4 of the User Port.
  Timer B is even more versatile.  In addition to these two sources, Timer B
can count the number of times that Timer A goes to 0.  By setting Timer A to
count the microprocessor clock, and setting Timer B to count the number of
times that Timer A zeros, you effectively link the two timers into one 32-bit
timer that can count up to 70 minutes with accuracy within 1/15 second.
  In the 64, CIA #1 Timer A is used to generate the interrupt which drives the
routine for reading the keyboard and updating the software clock.  Both Timers
A and B are also used for the timing of the routines that read and write tape
data.  Normally, Timer A is set for continuous operation, and latched with a
value of 149 in the low byte and 66 in the high byte, for a total Latch Value
of 17045.  This means that it is set to count to 0 every 17045/1022730
seconds, or approximately 1/60 second.
  For tape reads and writes, the tape routines take over the IRQ vectors.
Even though the tape write routines use the on-chip I/O port at location 1 for
the actual data output to the cassette, reading and writing to the cassette
uses both CIA #1 Timer A and Timer B for timing the I/O routines.

56324         $DC04          TIMALO
Timer A (low byte)

56325         $DC05          TIMAHI
Timer A (high byte)

56326         $DC06          TIMBLO
Timer B (low byte)

56327         $DC07          TIMBHI
Timer B (high byte)

Location Range: 56328-56331 ($DC08-$DC0B)
Time of Day Clock (TOD)

In addition to the two general-purpose timers, the 6526 CIA chip has a
special-purpose Time of Day Clock, which keeps time in a format that humans
can understand a little more easily than microseconds.
  This Time of Day Clock even has an alarm, which can cause an interrupt at a
specific time.  It is organized in four registers, one each for hours,
minutes, seconds, and tenths of seconds.  Each register reads out in Binary
Coded Decimal (BCD) format, for easier conversion to ASCII digits.  A BCD byte
is divided into two nybbles, each of which represents a single digit in base
10.  Even though a four-bit nybble can hold a number from 0 to 15, only the
base 10 digits of 0-9 are used.  Therefore, 10 0'clock would be represented by
a byte in the hours register with the nybbles 0001 and 0000, which stand for
the digits 1 and 0.  The binary value of this byte would be 16 (16 times the
high nybble plus the low nybble).  Each of the other registers operates in the
same manner.  In addition, Bit 7 of the hours register is used as an AM/PM
flag.  If that bit is set to 1, it indicates PM, and if it is set to 0, the
time is AM.
  The Time of Day Clock Registers can be used for two purposes, depending on
whether you are reading them or writing to them.  If you are reading them, you
will always be reading the time.  There is a latching feature associated with
reading the hours register in order to solve the problem of the time changing
while you are reading the registers.  For example, if you were reading the
hours register just as the time was changing from 10:59 to 11:00, it is
possible that you would read the 10 in the hours register, and by the time you
read the minutes register it would have changed from 59 to 00.  Therefore, you
would read 10:00 instead of either 10:59 or 11:00.
  To prevent this kind of mistake, the Time of Day Clock Registers stop
updating as soon as you read the hours register, and do not start again until
you read the tenths of seconds register.  Of course, the clock continues to
keep time internally even though it does not update the registers.  If you
want to read only minutes, or seconds or tenths of seconds, there is no
problem, and no latching will occur.  But anytime you read hours, you must
follow it by reading tenths of seconds, even if you don't care about them, or
else the registers will not continue to update.
  Writing to these registers either sets the time or the alarm, depending on
the setting of Bit 7 of Control Register B (56335, $DC0F).  If that bit is set
to 1, writing to the Time of Day registers sets the alarm.  If the bit is set
to 0, writing to the Time of Day registers sets the Time of Day clock.  In
either case, as with reading the registers, there is a latch function.  This
function stops the clock from updating when you write to the hours register.
The clock will not start again until you write to the tenths of seconds
registers.
  The only apparent use of the Time of Day Clock by the 64's Operating System
is in the BASIC RND statement.  There, the seconds and tenths of seconds
registers are read and their values used as part of the seed value for the
RND(0) command.
  Nonetheless, this clock can be an invaluable resource for the 64 user.  It
will keep time more accurately than the software clock maintained at locations
60-162 ($A0-$A2) by the Timer A interrupt routine.  And unlike that software
clock, the Time of Day Clock will not be disturbed when I/O operations disrupt
the Timer A IRQ, or when the IRQ vector is diverted elsewhere.  Not even a
cold start RESET will disrupt the time.  For game timers, just set the time
for 00:00:00:0 and it will keep track of elapsed time in hours, minutes,
seconds and tenths of seconds format.
  The following digital clock program, written in BASIC, will demonstrate the
use of these timers:

10 PRINT CHR$(147):GOSUB 200
20 H=PEEK(56331):POKE 1238,(H AND 16)/16+48:POKE 1239,(H AND 15)+48
30 M=PEEK(56330):POKE 1241,(M AND 240)/16+48:POKE 1242,(M AND 15)+48
40 S=PEEK(56329):POKE 1244,(S AND 240)/16+48:POKE 1245,(S AND 15)+48
50 T=PEEK(56328)AND15:POKE 1247,T+48:GOTO 20
200 INPUT"WHAT IS THE HOUR";H$:IF H$="" THEN 200
210 H=0:IF LEN(H$)>1 THEN H=16
220 HH=VAL(RIGHT$(H$,1)):H=H+HH:POKE56331,H
230 INPUT "WHAT IS THE MINUTE";M$:IF M$=""THEN 200
240 M=0:IF LEN(M$)>1 THEN M=16*VAL(LEFT$(M$,1))
250 MM=VAL(RIGHT$(M$,1)):M=M+MM:POKE56330,M
260 INPUT "WHAT IS THE SECOND";S$:IF S$=""THEN 200
270 S=0:IF LEN(S$)>1 THEN S=16*VAL(LEFT$(S$,1))
280 SS=VAL(RIGHT$(S$,1)):S=S+SS:POKE56329,S:POKE56328,0
290 POKE 53281,1:PRINT CHR$(147):POKE 53281,6
300 POKE 1240,58:POKE 1243,58:POKE 1246,58:GOTO 20

56328         $DC08          TODTEN
Time of Day Clock Tenths of Seconds

Bits 0-3:  Time of Day tenths of second digit (BCD)
Bits 4-7:  Unused

56329         $DC09          TODSEC
Time of Day Clock Seconds

Bits 0-3:  Second digit of Time of Day seconds (BCD)
Bits 4-6:  First digit of Time of Day seconds (BCD)
Bit 7:  Unused

56330         $DC0A          TODMIN
Time of Day Clock Minutes

Bits 0-3:  Second digit of Time of Day minutes (BCD)
Bits 4-6:  First digit of Time of Day minutes (BCD)
Bit 7:  Unused

56331         $DC0B          TODHRS
Time of Day Clock Hours

Bits 0-3:  Second digit of Time of Day hours (BCD)
Bit 4:  First digit of Time of Day hours (BCD)
Bits 5-6:  Unused
Bit 7:  AM/PM Flag (1=PM, 0=AM)

56332         $DC0C          CIASDR
Serial Data Port

The CIA chip has an on-chip serial port, which allows you to send or receive a
byte of data one bit at a time, with the most significant bit (Bit 7) being
transferred first.  Control Register A at 56334 ($DC0E) allows you to choose
input or output modes.  In input mode, a bit of data is read from the SP line
(pin 5 of the User Port) whenever a signal on the CNT line (pin 4) appears to
let you know that it is time for a read.  After eight bits are received this
way, the data is placed in the Serial Port Register, and an interrupt is
generated to let you know that the register should be read.
  In output mode, you write data to the Serial Port Register, and it is sent
out over the SP line (pin 5 of the User Port), using Timer A for the baud rate
generator.  Whenever a byte of data is written to this register, transmission
will start as long as Timer A is running and in continuous mode.  Data is sent
at half the Timer A rage, and an output will appear on the CNT line (pin 4 of
the User Port) whenever a bit is sent.  After all eight bits have been sent,
an interrupt is generated to indicate that it is time to load the next byte to
send into the Serial Register.
  The Serial Data Register is not used by the 64, which does all of its serial
I/O through the regular data ports.

56333         $DC0D          CIAICR
Interrupt Control Register

Bit 0:  Read / did Timer A count down to 0?  (1=yes)
        Write/ enable or disable Timer A interrupt (1=enable, 0=disable)
Bit 1:  Read / did Timer B count down to 0?  (1=yes)
        Write/ enable or disable Timer B interrupt (1=enable, 0=disable)
Bit 2:  Read / did Time of Day Clock reach the alarm time?  (1=yes)
        Write/ enable or disable TOD clock alarm interrupt (1=enable,
        0=disable)
Bit 3:  Read / did the serial shift register finish a byte? (1=yes)
        Write/ enable or disable serial shift register interrupt (1=enable,
        0=disable)
Bit 4:  Read / was a signal sent on the flag line?  (1=yes)
        Write/ enable or disable FLAG line interrupt (1=enable, 0=disable)
Bit 5:  Not used
Bit 6:  Not used
Bit 7:  Read / did any CIA #1 source cause an interrupt?  (1=yes)
        Write/ set or clear bits of this register (1=bits written with 1 will
        be set, 0=bits written with 1 will be cleared)

This register is used to control the five interrupt sources on the 6526 CIA
chip.  These sources are Timer A, Timer B, the Time of Day Clock, the Serial
Register, and the FLAG line.  Timers A and B cause an interrupt when they
count down to 0.  The Time of Day Clock generates an interrupt when it reaches
the ALARM time.  The Serial Shift Register interrupts when it compiles eight
bits of input or output.  An external signal pulling the CIA hardware line
called FLAG low will also cause an interrupt (on CIA #1, this FLAG line is
connected to the Cassette Read line of the Cassette Port).
  Even if the condition for a particular interrupt is satisfied, the interrupt
must still be enabled for an IRQ actually to occur.  This is done by writing
to the Interrupt Control Register.  What happens when you write to this
register depends on the way that you set Bit 7.  If you set it to 0, any other
bit that was written to with a 1 will be cleared, and the corresponding
interrupt will be disabled.  If you set Bit 7 to 1, any bit written to with a
1 will be set, and the corresponding interrupt will be enabled.  In either
case, the interrupt enable flags for those bits written to with a 0 will not
be affected.
  For example, in order to disable all interrupts from BASIC, you could POKE
56333, 127.  This sets Bit 7 to 0, which clears all of the other bits, since
they are all written with 1's.  Don't try this from BASIC immediate mode, as
it will turn off Timer A which causes the IRQ for reading the keyboard, so
that it will in effect turn off the keyboard.
  To turn on the Timer A interrupt, a program could POKE 56333,129.  Bit 7 is
set to 1 and so is Bit 0, so the interrupt which corresponds to Bit 0 (Timer
A) is enabled.
  When you read this register, you can tell if any of the conditions for a CIA
Interrupt were satisfied because the corresponding bit will be set to a 1.
For example, if Timer A counts down to 0, Bit 0 of this register will be set
to 1.  If, in addition, the mask bit that corresponds to that interrupt source
is set to 1, and an interrupt occurs, Bit 7 will also be set.  This allows a
multi-interrupt system to read one bit and see if the source of a particular
interrupt was CIA #1.  You should note, however, that reading this register
clears it, so you should preserve its contents in RAM if you want to test more
than one bit.

56334         $DC0E          CIACRA
Control Register A

Bit 0:  Start Timer A (1=start, 0=stop)
Bit 1:  Select Timer A output on Port B (1=Timer A output appears on Bit 6 of
        Port B)
Bit 2:  Port B output mode (1=toggle Bit 6, 0=pulse Bit 6 for one cycle)
Bit 3:  Timer A run mode (1=one-shot, 0=continuous)
Bit 4:  Force latched value to be loaded to Timer A counter (1=force load
        strobe)
Bit 5:  Timer A input mode (1=count microprocessor cycles, 0=count signals on
        CNT line at pin 4 of User Port)
Bit 6:  Serial Port (56332, $DC0C) mode (1=output, 0=input)
Bit 7:  Time of Day Clock frequency (1=50 Hz required on TOD pin, 0=60 Hz)

Bits 0-3.  This nybble controls Timer A.  Bit 0 is set to 1 to start the timer
counting down, and set to 0 to stop it.  Bit 3 sets the timer for one-shot or
continuous mode.
  In one-shot mode, the timer counts down to 0, sets the counter value back to
the latch value, and then sets Bit 0 back to 0 to stop the timer.  In
continuous mode, it reloads the latch value and starts all over again.
  Bits 1 and 2 allow you to send a signal on Bit 6 of Data Port B when the
timer counts.  Setting Bit 1 to 1 forces this output (which overrides the Data
Direction Register B Bit 6, and the normal Data Port B value).  Bit 2 allows
you to choose the form this output to Bit 6 of Data Port B will take.  Setting
Bit 2 to a value of 1 will cause Bit 6 to toggle to the opposite value when
the timer runs down (a value of 1 will change to 0, and a value of 0 will
change to 1).  Setting Bit 2 to a value of 0 will cause a single pulse of a
one machine-cycle duration (about a millionth of a second) to occur.
  Bit 4.  This bit is used to load the Timer A counter with the value that was
previously written to the Timer Low and High Byte Registers.  Writing a 1 to
this bit will force the load (although there is no data stored here, and the
bit has no significance on a read).
  Bit 5.  Bit 5 is used to control just what it is Timer A is counting.  If
this bit is set to 1, it counts the microprocessor machine cycles (which occur
at the rate of 1,022,730 cycles per second).  If the bit is set to 0, the
timer counts pulses on the CNT line, which is connected to pin 4 of the User
Port.  This allows you to use the CIA as a frequency counter or an event
counter, or to measure pulse width or delay times of external signals.
  Bit 6.  Whether the Serial Port Register is currently inputting or
outputting data (see the entry for that register at 56332 ($DC0C) for more
information) is controlled by this bit.
  Bit 7.  This bit allows you to select from software whether the Time of Day
Clock will use a 50 Hz or 60 Hz signal on the TOD pin in order to keep
accurate time (the 64 uses a 60 Hz signal on that pin).

56335         $DC0F          CIACRB
Control Register B

Bit 0:  Start Timer B (1=start, 0=stop)
Bit 1:  Select Timer B output on Port B (1=Timer B output appears on Bit 7 of
        Port B)
Bit 2:  Port B output mode (1=toggle Bit 7, 0=pulse Bit 7 for one cycle)
Bit 3:  Timer B run mode (1=one-shot, 0=continuous)
Bit 4:  Force latched value to be loaded to Timer B counter (1=force load
        strobe)
Bits 5-6:  Timer B input mode
           00 = Timer B counts microprocessor cycles
           01 = Count signals on CNT line at pin 4 of User Port
           10 = Count each time that Timer A counts down to 0
           11 = Count Timer A 0's when CNT pulses are also present
Bit 7:  Select Time of Day write (0=writing to TOD registers sets alarm,
        1=writing to TOD registers sets clock)

  Bits 0-3.  This nybble performs the same functions for Timer B that Bits 0-3
of Control Register A perform for Timer A, except that Timer B output on Data
Port B appears at Bit 7, and not Bit 6.
  Bits 5 and 6.  These two bits are used to select what Timer B counts.  If
both bits are set to 0, Timer B counts the microprocessor machine cycles
(which occur at the rate of 1,022,730 cycles per second).  If Bit 6 is set to
0 and Bit 5 is set to 1, Timer B counts pulses on the CNT line, which is
connected to pin 4 of the User Port.  If Bit 6 is set to 1 and Bit 5 is set to
0, Timer B counts Timer A underflow pulses, which is to say that it counts the
number of times that Timer A counts down to 0.  This is used to link the two
numbers into one 32-bit timer that can count up to 70 minutes with accuracy to
within 1/15 second.  Finally, if both bits are set to 1, Timer B counts the
number of times that Timer A counts down to 0 and there is a signal on the CNT
line (pin 4 of the User Port).
  Bit 7.  Bit 7 controls what happens when you write to the Time of Day
registers.  If this bit is set to 1, writing to the TOD registers sets the
ALARM time.  If this bit is cleared to 0, writing to the TOD registers sets
the TOD clock.

Location Range: 56336-56575 ($DC10-$DCFF)
CIA #1 Register Images

Since the CIA chip requires only enough addressing lines to handle 16
registers, none of the higher bits are decoded when addressing the 256-byte
area that has been assigned to it.  The result is that every 16-byte area in
this 256-byte block is a mirror of every other.  Even so, for the sake of
clarity in your programs it is advisable to use the base address of the chip,
and not use the higher addresses to communicate with the chip.

56576-56591    $DD00-$DD0F
Complex Interface Adapter (CIA) #2 Registers

Locations 56576-56591 ($DD00-$DD0F) are used to address the Complex Interface
Adapter chip #2 (CIA #2).  Since the chip itself is identical to CIA #1,
which is addressed at 56320 ($DC00), the discussion here will be limited to
the use which the 64 makes of this particular chip.  For more general
information on the chip registers, please see the corresponding entries for
CIA #1.
  One of the significant differences between CIA chips #1 and #1 is the use to
which Data Ports A and B are put.  The peripheral input and output devices
that CIA #2 controls are those on the Serial Bus (such as the 1541 Disk Drive
and 1525 printer), the RS-232 device (which is used for telecommunications),
and the User Port, an eight-bit parallel port that can be turned to whatever
purpose the user desires.  In addition, Data Port A has the important task of
selecting the 16K bank ofmemory that will be used by the VIC-II chip for
graphics.
  Another significant difference between CIA chips #1 and #2 is that the
interrupt line of CIA #1 is wired to the 6510 IRQ line, while that of CIA #2
is wired to the NMI line.  This means that interrupts from this chip cannot
be masked by setting the Interrupt disable flag (SEI).  They can be disabled
from CIA's Mask Register, though.  Be sure to use the NMI vector when setting
up routines to be driven by interrupts generated by this chip.

Location Range: 56576-56577 ($DD00-$DD01)
CIA #2 Data Ports A and B

These registers are where the communication with the Serial Bus, RS-232
device, and User Port take place.  The Serial Bus is like the IEEE bus which
is used by the PET, in that it allows more than one device to be connected to
the port at a time, in a daisychain arrangement.  Since each byte of data is
sent one bit at a time, however, the Serial Bus is at least eight times
slower than the IEEE.  It is presently used to control the 1541 Disk Drive
and 1525 printer, and other devices (such as printer interface for Centronics-
type parallel pritners and stringy floppy wafer tape storage units) can be
placed on this bus.
  Data Port A is used for communication with the Serial Bus.  Bits 5 and 7 are
used for Serial Bus Data Output and Input, respectively, and Bits 4 and 6 are
used for the Serial Bus Clock Pulse Output and Input.  Bit 3 of Data Port A is
used to send the ATN signal on the Serial Bus.
  The 64 has built-in software to handle RS-232 communications through a modem
or other device plugged in the RS-232/User Port.  The RS-232 device uses Bit 2
of Data Port A for data output (it is the only line from Port A that is
connected to the RS-232/User Port jack).  It also makes heavy use of Port B,
using Bit 7 for the Data Set Ready (DSR) signal, Bit 6 for the Clear to Send
(CTS), Bit 4 for the Carrier Detect (DCD), Bit 3 for the Ring Indicator (RI),
Bit 2 for Data Terminal Ready (DTR), Bit 1 for Request to Send (RTS), and Bit
0 for data input.  See locations 659-660 ($293-$294) for more details on the
RS-232 device.
  All of the data lines which the RS-232 device uses are also available to the
user as part of the User Port.  All of the Port B data lines, and Bit 2 of
Port A, are brought out to the User Port connector on the back of the 64.
These data bits are utilized in the normal way:  The port connections are made
to TTL-level input or output devices, and the direction of data is determined
by the Data Direction Registers.
  In addition, the User Port has pins connected to the two CIA Serial Ports
(whose eight-bit shift registers are well-suited for serial-to-parallel and
parallel-to-serial conversion),and the two CNT lines which aid in the
operation of the Serial Ports.  The CNT lines can also be used in conjunction
with the CIA Timers, and allow them to be used as frequency counters, event
counters, interval timers, etc.  The advanced features of the CIA chip make
almost any type of interfacing application possible, and in the near future we
will probably see many interesting applications for the User Port on the 64.
A pin description of tthe User Port connector is provided below:

User         RS-232
Port  CIA    DB-25
Pin   Line   Pin     Description

1                    Ground
2                    +5 Volts (100 milliamps maximum)
3                    RESET (grounding this pin causes a cold start)
4     CNT1           CIA #1 Serial Port and Timer Counter
5     SP1            CIA #1 Serial Data Port
6     CNT2           CIA #2 Serial Port and Timer Counter
7     SP2            CIA #2 Serial Data Port
8     PC2            CIA #2 handshaking line
9                    Connected to the ATN line of the Serial Bus
10                   9 Volts AC (+ phase, 50 milliamps maximum)
11                   9 volts AC (- phase, 50 milliamps maximum)
12                   Ground
A            1       Ground
B     FLAG2          CIA #2 handshaking line
C     PB0    3       Port B Bit 0--RS-232 Received Data (SIN)
D     PB1    4       Port B Bit 1--RS-232 Request to Send (RTS)
E     PB2    20      Port B Bit 2--RS-232 Data Terminal Ready (DTR)
F     PB3    22      Port B Bit 3--RS-232 Ring Indicator (RI)
H     PB4    8       Port B Bit 4--RS-232 Carrier Detect (DCD)
J     PB5            Port B Bit 5
K     PB6    5       Port B Bit 6--RS-232 Clear to Send (CTS)
L     PB7    6       Port B Bit 7--RS-232 Data Set Ready (DSR)
M     PA2    2       Port A Bit 2--RS-232 Transmitted Data (Sout)
N            7       Ground

One of the handshaking lines on the above chart, PC2, was not covered in the
discussion of CIA #1, because that line of CIA #1 is not connected to
anything.  The CIA #2 PC line is accessible from the User Port, however.  This
line will go low for one cycle following a read or write of Port B on CIA #2.
This signal lets external devices know when data has been read or written.
  Bits 0 and 1 of CIA #2 Port A have an extremely important function.  As
mentioned in the section on the VIC-II chip (53248, $D000), the video chip can
address only 16K of memory at a time, and all graphics data must be stored in
that 16K block in order to be displayed.  Within this area, sprite graphics
data may be placed in any of 256 groups of 64 bytes each.  Character data can
be stored in any of eight 2K blocks.  Text screen memory may be in any of 16
1K areas, and bitmap screen memory may be in either of two 8K sections.
  When you turn the power on, the VIC-II uses the bottom 16K of memory for
graphics.  Unfortunately, this block of memory is also used extensively for
other important purposes.  Though some means of eliminating these conflicts
are discussed above, in many situations you will want to change from the
default 16K bank at the low end of memory.
  Bits 0 and 1 select the current 16K bank for video memory from the four
possible choices using the following bit patterns:

00 (bit value of 0) Bank 3 (49152-65535, $C000-$FFFF)
01 (bit value of 1) Bank 2 (32768-49151, $8000-$BFFF)
10 (bit value of 2) Bank 1 (16384-32767, $4000-$7FFF)
11 (bit value of 3) Bank 0 (0-16383, $0-$3FFF)

The technique for making this change from BASIC is discussed below.  But
before we go ahead and start changing banks, let's briefly review the contents
of these areas, and the considerations for using them for graphics.
  Block 0.  This is normally used for system variables and BASIC program text.
Locations 1024-2047 ($400-$7FF) are reserved for the default position of
screen memory.
  There is an addition limitation on memory usage of this block, as the VIC-II
sees the character generator ROM at 4096-8191 ($1000-$1FFF), making this
portion of memory unavailable for other graphics data.  Generally, there is
little free space here for graphics display data.  Locations 679-767 ($2A7-
$2FF) are unused, and could hold one sprite shape (number 11) or data for 11
characters.  The area from 820-1023 ($334-$3FF), which includes the cassette
I/O buffer, is available for graphics memory, and is large enough to hold
three sprite shapes (numbers 13, 14, and 15), or data for 25 characters
(numbers 103-127).  But getting enough memory for bitmap graphics requires
that you either reserve memory after the end of BASIC text by lowering the end
of BASIC pointer at 56 ($38), or raise the start of BASIC pointer at 44 ($2C).
See the entries for these pointers for more details.
  Block 1.  Block 1 is normally used for BASIC program storage.  When using
this bank, the VIC-II does not have access to the character generator ROM.
Providing that you lower the top of memory so that BASIC programs do not
interfere, this area is wide open for sprite shapes, character graphics, and
bitmap graphics.
  The drawbacks to useing this bank are the unavailability of the character
ROM and the limitation on BASIC program space (as little as 14K).  The absence
of the character ROM is a relatively minor nuisance, because you can always
switch in the ROM and copy any or all of the characters to RAM (see the
entries for location 1 and the alternate entry for 53248 ($D000), the
Character ROM, for details).  This block may be a good alternate choice to
avoid potential conflicts with other applications that use higher memory.
  Block 2.  The third block (Block 2) consists of 8K of RAM, half of which is
seen by the VIC-II chip as character ROM, and the 8K BASIC interpreter ROM.
The BASIC ROM area is available for graphics.  This is possible because of the
64's special addressing.  The VIC-II chip reads only from RAM, and thus sees
the RAM underneath the BASIC ROM, even if the 6510 has ROM switched in.  The
6510, on the other hand, always writes to RAM, even when dealing with memory
it reads as ROM.  Whatever is written to the RAM underlying the BASIC ROM is
displayed normally by the VIC-II chip.  This opens up an extra 8K are for
sprites and character data under the BASIC ROM.
  You should keep in mind that while you can write to this area, you cannot
read it from BASIC.  This may not be a serious problem when it comes to
character sets and sprite data, but it's more of a drawback if you want to use
this RAM for screen memory.
  For example, the Operating System has to read the text screen to move the
cursor properly, and if it reads the ROM value instead of the RAM screen data,
it gets hopelessly confused, making it impossible to type in any commands.
  Likewise, you would not be able to read the high-resolution screen if it
were placed here, without some machine language trickery.  With locations
36863-40959 ousted by the character ROM, only 4K of true RAM remains for use
as screen memory, not enough for a complete high-resolution screen.
Therefore, this block is not recommended for use in bitmap mode if your
program needs to check the screen.  Otherwise, this is a good place for
graphics memory, particularly if you need to emulate the screen configuration
of the PET.
  Block 3.  Normally Block 3 contains 4K of RAM that is completely unused by
the system, 4K if I/O registers, and the 8K Operating System Kernal ROM.  It
is very convenient to use when you need a lot of memory space for both
graphics and a BASIC program.  Although the character ROM is not available, it
can be copied to RAM.  The area under the Kernal ROM can be used as explained
above.  One possible conflict that you should be aware of is that the current
version of the DOS support program is written to reside at 52224 ($CC00).  It
would be safest to avoid using 52224-53247 for graphics if you plan to use DOS
support.
  Changing banks.  Once you have selected a bank of 16K to use, the procedure
for making the change from BASIC is as follows:

1.  Set the Data Direction Register if necessary.  In order to use Bits 0 and
1 of Port A to change banks, these bits must be set as outputs in Data
Direction Register A.  Since this is the default condition on powering-up,
this step normally will not be needed.

2.  Select a bank.  Banks 0-3 can be chosen by entering the following lines:

POKE 56578,PEEK(56578) OR 3: REM SET FOR OUTPUT IF NOT ALREADY
POKE 56576,(PEEK(56576) AND 252) OR (3-BANK): REM BANK IS BANK #, MUST BE 0-3

3.  Set the VIC-II register for character memory.  As explained at the entry
for location 53272 ($D018), the formula for this is:

POKE 53272,(PEEK(53272) AND 240) OR TK: REM TK IS 2 KBYTE OFFSET FROM
  BEGINNING OF BLOCK

4.  Set the VIC-II register for display memory.  As explained at the entry for
location 53272 ($D018), the formula for this is:

POKE 53272,(PEEK(53272) AND 15) OR K*16: REM K IS KBYTE OFFSET FROM
  BEGINNING OF BLOCK

Since steps 3 and 4 operate on the same register, you could combine these
steps and just POKE 53272,(16*K+TK).

5.  Set the Operating System pointer for display memory at 648 ($288).  Even
though you have just told the VIC-II chip where to display memory for the
screen, the Operating System does not yet know where to write its text
characters.  Let it know with this statement:

POKE 648,AD/256: REM AD IS THE ACTUAL ADDRESS OF SCREEN MEMORY

After you make this change, you must watch out for the STOP/RESTORE key
combination.  The BRK initialization changes the screen display default to
location 1024 in Bank 0, but not the Operating System pointer at 648 ($288).
As a result, what you are typing will not be displayed on the screen.  The
computer will lock up until you turn the power off and back on again.  The
simplest way to avoid this problem is to disable the RESTORE key entirely (see
the entries for 792 ($318) and 808 ($328) for more information).
  Below is a sample program which switches to Bank 3.  It includes a machine
language transfer routine to move the ROM character set to RAM, and a short
interrupt routine to correct the RESTORE key problem.  After the switch is
made, a loop isused to POKE characters into the new screen memory area.  Next,
the character data is slowly erased, to show that the character set is now in
RAM.  Then, a loop is used to read the locations of the character set, and
write to the same locations.  This demonstrates that the 6510 reads the Kernal
ROM when you PEEK those locations, but POKEs to the RAM which is being
displayed.  Finally, the machine language move is used again to show how
quickly the set is restored.

20 FOR I=1 TO 33:READ A:POKE 49152+I,A:NEXT: REM SET UP ML ROUTINE
30 GOSUB 200: REM ML COPY OF ROM CHARACTER SET TO RAM
40 POKE 56576,PEEK(56576) AND 252: REM STEP 1, ENABLE BANK 3
50 POKE 53272,44: REM STEPS 2-3, POINT VIC-II TO SCREEN AND CHARACTER MEMORY
60 REM SCREEN OFFSET IS 2*16, CHARACTER OFFSET IS 12
70 POKE 648,200: REM STEP 4, POINT OS TO SCREEN AT 51200 (200*256)
80 PRINT CHR$(147): REM CLEAR SCREEN
90 FOR I=53236 TO 53245:READ A:POKE I,A:NEXT: REM NEW INTERRUPT ROUTINE
100 POKE 53246,PEEK(792):POKE 53247,PEK(793): REM SAVE OLD NMI VECTOR
110 POKE 792,244:POKE 793,207: REM ROUTE THE INTERRUPT THROUGH THE NEW ROUTINE
120 FOR I=0 TO 255:POKE 51400+I,I:POKE 55496+I,1:NEXT
125 REM POKE CHARACTERS TO SCREEN
130 FOR J=1 TO 8:FOR I=61439+J TO I+2048 STEP 8
140 POKE I,0:NEXT I,J: REM ERASE CHARACTER SET
150 FOR I=61440 TO I+2048:POKE I,PEEK(I):NEXT: REM POKE ROM TO RAM
160 GOSUB 200:END: REM RESTORE CHARACTER SET
200 POKE 56334,PEEK(56334) AND 254: REM DISABLE INTERRUPTS
210 POKE 1,PEEK(1) AND 251:REM SWITCH CHARACTER ROM INTO 6510 MEMORY
220 SYS 49152: REM COPY ROM CHARACTER SET TO RAM AT 61440
230 POKE 1,PEEK(1) OR 4: REM SWITCH CHARACTER ROM OUT OF 6510 MEMORY
240 POKE 56334,PEEK(56334)OR 1: REM ENABLE INTERRUPTS
250 RETURN
300 REM DATA FOR ML PROGRAM TO COPY CHARACTER SET TO RAM
310 DATA169,0,133,251,133,253,169,208,133,252,169,240,133,254,162,16
320 DATA160,0,177,251,145,253,136,208,249,230,252,230,254,202,208,240,96
330 REM NEXT IS ML PROGRAM TO MAKE THE RESTORE KEY RESET OS POINTER TO SCREEN
340 DATA 72,169,4,141,136,02,104,108,254,207

See also the sample program showing how to configure your 64 like a PET at
location 43 ($2B).

56576         $DD00          CI2PRA
Data Port Register A

Bits 0-1:  Select the 16K VIC-II chip memory bank (11=bank 0, 00=bank 3)
Bit 2:  RS-232 data output (Sout)/Pin M of User Port
Bit 3:  Serial bus ATN signal output
Bit 4:  Serial bus clock pulse output
Bit 5:  Serial bus data output
Bit 6:  Serial bus clock pulse input
Bit 7:  Serial bus data input

56577         $DD01          CI2PRB
Data Port B

Bit 0:  RS-232 data input (SIN)/ Pin C of User Port
Bit 1:  RS-232 request to send (RTS)/ Pin D of User Port
Bit 2:  RS-232 data terminal ready (DTR)/ Pin E of User Port
Bit 3:  RS-232 ring indicator (RI)/ Pin F of User Port
Bit 4:  RS-232 carrier detect (DCD)/ Pin H of User Port
Bit 5:  Pin J of User Port
Bit 6:  RS-232 clear to send (CTS)/ Pin K of User Port
        Toggle or pulse data output for Timer A
Bit 7:  RS-232 data set ready (DSR)/ Pin L of User Port
        Toggle or pulse data output for Timer B

Location Range: 56578-56579 ($DD02-$DD03)
CIA #2 Data Direction Registers A and B

These Data Direction registers control the direction of data flow over Data
Ports A and B.  For more details on the operation of these registers, see the
entry for the CIA #1 Data Direction Registers at 56322 ($DC02).
  The default setting for Data Direction Register A is 63 (all bits except 6
and 7 are outputs), and for Data Direction Register B the default setting is
0 (all inputs).  Bits 1 and 2 of Port B are changed to output when the RS-232
device is opened.

56578         $DD02          C2DDRA
Data Direction Register A

Bit 0:  Select Bit 0 of data Port A for input or output (0=input, 1=output)
Bit 1:  Select Bit 1 of data Port A for input or output (0=input, 1=output)
Bit 2:  Select Bit 2 of data Port A for input or output (0=input, 1=output)
Bit 3:  Select Bit 3 of data Port A for input or output (0=input, 1=output)
Bit 4:  Select Bit 4 of data Port A for input or output (0=input, 1=output)
Bit 5:  Select Bit 5 of data Port A for input or output (0=input, 1=output)
Bit 6:  Select Bit 6 of data Port A for input or output (0=input, 1=output)
Bit 7:  Select Bit 7 of data Port A for input or output (0=input, 1=output)

56579         $DD03          C2DDRB
Data Direction Register B

Bit 0:  Select Bit 0 of data Port B for input or output (0=input, 1=output)
Bit 1:  Select Bit 1 of data Port B for input or output (0=input, 1=output)
Bit 2:  Select Bit 2 of data Port B for input or output (0=input, 1=output)
Bit 3:  Select Bit 3 of data Port B for input or output (0=input, 1=output)
Bit 4:  Select Bit 4 of data Port B for input or output (0=input, 1=output)
Bit 5:  Select Bit 5 of data Port B for input or output (0=input, 1=output)
Bit 6:  Select Bit 6 of data Port B for input or output (0=input, 1=output)
Bit 7:  Select Bit 7 of data Port B for input or output (0=input, 1=output)

Location Range: 56580-56583 ($DD04-$DD07)
Timer A and B Low and High Bytes

These four timer registers are used to control Timers A and B.  For details on
the operation of these timers, see the entry for Location Range 56324-56327
($DC04-$DC07).
  The 64 Operating System uses the CIA #2 Timers A and B mostly for timing
RS-232 send and receive operations.  Serial Bus timing uses CIA #1 Timer B.

56580         $DD04          TI2ALO
Timer A (low byte)

56581         $DD05          TI2AHI
Timer A (high byte)

56582         $DD06          TI2BLO
Timer B (low byte)

56583         $DD07          TI2BHI
Timer B (high byte)

Location Range: 56584-56587 ($DD08-$DD0B)
Time of Day Clock

In addition to the two general purpose timers, the 6526 CIA chip has a special
purpose Time of Day Clock, which keeps time in a format that humans can
understand a little more easily than microseconds.  For more information about
this clock, see the entry for Location Range 56328-56331 ($DC08-$DC0B).  The
64's Operating system does not make use of these registers.

56584         $DD08          TO2TEN
Time of Day Clock Tenths of Seconds

Bits 0-3:  Time of Day tenths of second digit (BCD)
Bits 4-7:  Unused

56585         $DD09          TO2SEC
Time of Day Clock Seconds

Bits 0-3:  Second digit of Time of Day seconds (BCD)
Bits 4-6:  First digit of Time of Day seconds (BCD)
Bit 7:  Unused

56586         $DD0A          TO2MIN
Time of Day Clock Minutes

Bits 0-3:  Second digit of Time of Day minutes (BCD)
Bits 4-6:  First digit of Time of Day minutes (BCD)
Bit 7:  Unused

56587         $DD0B          TO2HRS
Time of Day Clock Hours

Bits 0-3:  Second digit of Time of Day hours (BCD)
Bit 4:  First digit of Time of Day hours (BCD)
Bits 5-6:  Unused
Bit 7:  AM/PM flag (1=PM, 0=AM)

56588         $DD0C          CI2SDR
Serial Data Port

The CIA chip has an on-chip serial port, which allows you to send or receive a
byte of data one bit at a time, with the most significant bit (Bit 7) being
transferred first.  For more information about its use, see the entry for
location 56332 ($DC0C).  The 64's Operating System does not use this facility.

56589         $DD0D          CI2ICR
Interrupt Control Register

Bit 0:  Read / did Timer A count down to 0?  (1=yes)
        Write/ enable or disable Timer A interrupt (1=enable, 0=disable)
Bit 1:  Read / did Timer B count down to 0?  (1=yes)
        Write/ enable or disable Timer B interrupt (1=enable, 0=disable)
Bit 2:  Read / did Time of Day Clock reach the alarm time?  (1=yes)
        Write/ enable or disable TOD clock alarm interrupt (1=enable,
        0=disable)
Bit 3:  Read / did the serial shift register finish a byte?  (1=yes)
        Write/ enable or disable serial shift register interrupt (1=enable,
        0=disable)
Bit 4:  Read / was a signal sent on the FLAG line?  (1=yes)
        Write/ enable or disable FLAG line interrupt (1=enable, 0=disable)
Bit 5:  Not used
Bit 6:  Not used
Bit 7:  Read / did any CIA #2 source cause an interrupt?  (1=yes)
        Write/ set or clear bits of this register (1=bits written with 1 will
        be set, 0=bits written with 1 will be cleared)

This register is used to control the five interrupt sources on the 6526 CIA
chip.  For details on its operation, see the entry for 56333 ($DC0D).  The
main difference between these two chips pertaining to this register is that on
CIA #2, the FLAG line is connected to Pin B of the User Port, and thus is
available to the user who wishes to take advantage of its ability to cause
interrupts for handshaking purposes.

Location Range: 56590-$56591 ($DD0E-$DD0F)
See locations 56334 and 56334 for details

56590         $DD0E          CI2CRA
Control Register A

Bit 0:  Start Timer A (1=start, 0=stop)
Bit 1:  Select Timer A output on Port B (1=Timer A output appears on Bit 6 of
        Port B)
Bit 2:  Port B output mode (1=toggle Bit 6, 0=pulse Bit 6 for one cycle)
Bit 3:  Timer A run mode (1=one-shot, 0=continuous)
Bit 4:  Force latched value to be loaded to Timer A counter (1=force load
        strobe)
Bit 5:  Timer A input mode (1=count microprocessor cycles, 0=count signals on
        CNT line at pin 4 of User Port)
Bit 6:  Serial Port (56588, $DD0C) mode (1=output, 0=input)
Bit 7:  Time of Day Clock frequency (1=50 Hz required on TOD pin, 0=60 Hz)

56591         $DD0F          CI2CRB
Control Register B

Bit 0:  Start Timer B (1=start, 0=stop)
Bit 1:  Select Timer B output on Port B (1=Timer B output appears on Bit 7 of
        Port B)
Bit 2:  Port B output mode (1=toggle Bit 7, 0=pulse Bit 7 for one cycle)
Bit 3:  Timer B run mode (1=one shot, 0=continuous)
Bit 4:  Force latched value to be loaded to Timer B counter (1=force load
        strobe)
Bits 5-6:  Timer B input mode
           00 = Timer B counts microprocessor cycles
           01 = Count signals on CNT line at pin 4 of User Port
           10 = Count each time that Timer A counts down to 0
           11 = Count Timer A 0's when CNT pulses are also present
Bit 7:  Select Time of Day write (0=writing to TOD registers sets alarm,
        1=writing to ROD registers sets clock)

Location Range: 56592-56831 ($DD10-$DDFF)
CIA #2 Register Images

Since the CIA chip requires only enough addressing lines to handle 16
registers, none of the higher bits are decoded when addressing the 256-byte
area that has been assigned to it.  The result is that every 16-byte area in
this 256-byte block is a mirror of every other.  For the sake of clarity in
your programs, it is advisable not to use these addresses.

Location Range: 56832-57087 ($DE00-$DEFF)
Reserved for I/O Expansion

This range of locations is not used directly by the 64's internal hardware.
It is, however, accessible via pin 7 of the Expansion Port.  It can be used to
control cartridges which are connected to this port.  For example, the CP/M
module uses this space to control which microprocessor is in control of the
system.  The Z-80 microprocessor is turned on and off by writing to 56832
($DE00).
  Another cartridge which uses this space is Simon's BASIC.  This 16K
cartridge is addressed at memory locations 32768-49151 ($8000-$BFFF), which
means that it overlaps the regular BASIC ROM at 40960-49151 ($A000-$BFFF).
But since it contains additions to BASIC, it must use the BASIC ROM as well.
This problem is solved by copying the cartridge at 32768-40959 ($8000-$9FFF)
to RAM, and turning the cartridge on and off by writing to or reading from
location 56832 ($DE00).

Location Range: 57088-57343 ($DF00-$DFFF)
CIA #2 Register Images

This range of locations is not used directly by the 64's internal hardward,
but is accessible via pin 10 of the Expansion Port.  One possible use for this
I/O memory that Commodore has mentioned is an inexpensive parallel disk drive
(which presumable would be much faster than the current serial model).

Alternate 53248-57343 ($D000-$DFFF)
Character Generator ROM

The character generator ROM supplies the data which is to form the shapes of
the text and graphics characters that are displayed on the screen.  Each
character requires eight bytes of shape data, and these eight-byte sequences
are arranged in order in which the characters appear in the screen code chart
(see Appendix G).  For example, the first eight bytes of data in the ROM hold
the shape information for the commercial at sign (@), the next eight hold the
shape of the letter A, etc.  In all, there are 4096 bytes, representing shape
data for two complete character sets of 256 characters each--1K each for
uppercase/graphics, reverse uppercase/reverse graphics, lowercase/uppercase,
and reverse lowercase/reverse uppercase.
  The shape of each character is formed by an 8 by 8 matrix of screen dots.
Whether any of the 64 dots is lit up or not is determined by the bit patterns
of the character data.  Each byte of the Character ROM holds a number from 0
to 255.  This number can be represented by eight binary digits of 0 or 1.
The leftmost bit of these eight is known as Bit 7, while the rightmost bit is
called Bit 0.  Each of these binary digits has a bit value that is two times
greater than the last.  The values of a bit set to 1 in each of the bit places
are:

Bit    0    1     2    3    4    5    6    7
Value  1    2     4    8   16   32   64  128

A byte whose value is 255 has every bit set to 1 (128+64+32+16+8+4+2+1=255),
while a byte whose value is 0 is made up of all zero bits.  Numbers in between
are made up of combinations of bits set to 1 and bits set to 0.  If you think
of every bit that holds 0 as a dot on the screen which is the color of the
screen background, and every bit that holds a 1 as a dot whose color is that
of the appropriate nybble in Color RAM, you can begin to get an idea of how
the byte values relate to the shape of the character.  For example, if you
PEEK at the first eight bytes of the character ROM (the technique is explained
in the entry for location 1), you will see the numbers 60, 102, 110, 110, 96,
98, 60, 0.  Breaking these data bytes down into their bit values gives us a
picture that looks like the following:

00111100   0 +   0 +  32 +  16 +   8 +   4 +   0 +   0 =  60
01100110   0 +  64 +  32 +   0 +   0 +   4 +   2 +   0 = 101
01101110   0 +  64 +  32 +   0 +   8 +   4 +   2 +   0 = 110
01101110   0 +  64 +  32 +   0 +   8 +   4 +   2 +   0 = 110
01100000   0 +  64 +  32 +   0 +   0 +   0 +   0 +   0 =  96
01100010   0 +  64 +  32 +   0 +   0 +   0 +   2 +   0 =  98
00111100   0 +   0 +  32 +  16 +   8 +   4 +   0 +   0 =  60
00000000   0 +   0 +   0 +   0 +   0 +   0 +   0 +   0 =   0

If you look closely, you will recognize the shape of the commercial at sign
(@) as it's displayed on your screen.  The first byte of data is 60, and you
can see that Bits 5, 4, 3, and 2 are set to 1.  The chart above shows that the
bit values for these bits are 32, 16, 8, and 4.  Adding these together, you
get 32+16+8+4=60.  This should give you an idea of how the byte value
corresponds to the patterns of lit dots.  For an even more graphic display,
type in the following program, which shows the shape of any of the 512
characters in the ROM, along with the number value of each byte of the shape.

10 DIM B%(7),T%(7):FOR I=0 TO 7:T%(I)=2^I:NEXT
20 POKE 53281,2:PRINT CHR$(147):POKE 53281,1:POKE 53280,0:POKE 646,11
30 POKE 214,20:PRINT:INPUT" CHARACTER NUMBER (0-511)";C$
40 C=VAL(C$):GOSUB 80:FOR I=0 TO 7
50 POKE 214,6+I:PRINT:PRINT TAB(23);B%(I);CHR$(20);"   "
60 FOR J=7 TO 0 STEP-1:POKE 1319+(7-J)+I*40,32-128*((B%(I)ANDT%(J))=T%(J))
70 NEXT J,I:POKE 214,20:PRINT:PRINT TAB(27)"    ":GOTO 30
80 POKE 56333,127:POKE 1,51:FOR I=0 TO 7
90 B%(I)=PEEK(53248+C*8+I):NEXT:POKE 1,55:POKE 56333,129:RETURN

If you have read about the VIC-II video chip, you know that it can address
only 16K of memory at a time, and that all display data such as screen memory,
character shape data, and sprite shape data must be stored within that 16K
block.
  Since it would be very inconvenient for the VIC-II chip to be able to access
the character data only at the 16K block which includes adresses 53248-57343
($D000-$DFFF), the 64 uses an addressing trick that makes the VIC-II chip see
an image of the Character ROM at 4096-8191 ($1000-$1FFF) and at 36864-40959
($9000-$9FFF).  It is not available in the other two blocks.  To generate
characters in these blocks, you must supply your own user-defined character
set, or copy the ROM data to RAM.  A machine language routine for doing this
is included in a sample program at the entry for 56576 ($DD00).
  As indicated above, you are by no means limited to useing the character data
furnished by the ROM.  The availability of user-defined characters greatly
extends the graphics power of the 64.  It allows you to create special text
characters, like math or chemistry symbols and foreign language alphabets.
You can also develop special graphics characters as a substitute for plotting
points in bitmap graphics.  You can achieve the same resolution using a custom
character as in high-resolution bitmap mode, but with less memory. Once you
have defined the character, it is much faster to print it to the screen than
in would be to plot out all of the individual points.
  To employ user-defined characters, you must first pick a spot to put the
shape data.  This requires choosing a bank of 16K for video chip memory (see
the entry under Bits 0-1 of 56576 ($DD00) for the considerations involved),
and setting the pointer to the 2K area of character memory in 53272 ($D018).
It is then up to you to supply the shape data for the characters.  You can use
part of the ROM character set by reading the ROM and transferring the data to
your character shape area (see the entry for location 1 for a method of
reading the ROM).
  Your original characters may be created by darkening squares on an 8 by 8
grid, converting all darkened squares to their bit values, and then adding the
bit values for each of the eight bytes.  Or, you may use one of the many
character graphics editor programs that are available commercially to generate
the data interactively by drawing on the screen.
  One graphics mode, multicolor text mode, almost requires that you define
your own character set in order to use it effectively.  Multicolor mode is
enabled by Bit 4 of location 53270 ($D016).  Instead of using each bit to
control whether an individual dot will be foreground color (1) or background
color (0), that mode breaks down each byte of shape data in four bit-pairs.
These bit pairs control whether a dot will be the color in Background Color
Register #0 (00), the color in Background Color Register #1 (01), the color in
Background Color Register #2 (10), or the color in the appropriate nybble of
Color RAM (11).  Since each pair of bits controls one dot, each character is
only four dots across.  To make up for this, each dot is twice as wide as a
normal high-resolution dot.


::::::::::::::::
:: Chapter 7  ::
::            ::
::8K Operating::
::   System   ::
:: Kernal ROM :: 
::::::::::::::::

As with the section on the BASIC ROM, this section is not meant to be a
complete explanation of the Kernal ROM, but rather a guidepost for further
exploration.  Where the exact instructions the Kernal ROM routines use are
important to your programming, it will be necessary for you to obtain a
disassembly listing of those routines and look at the code itself.
  Keep in mind that there is 8K of RAM underlying the Kernal ROM that can be
used by turning off interrupts and switching out the Kernal ROM temporarily.
Even without switching out the Kernal ROM, this RAM may be read by the VIC-II
chip if it is banked to use the top 16K of memory, and may be used for
graphics data.  The Kernal and BASIC ROMs may be copied to RAM, and the RAM
versions modified to change existing features or add new ones.
  There are some differences between the version of the Kernal found on the
first few Commodore 64s and those found on the majority of newer models.
Those differences are discussed in the entries for the sections on later
Kernal additions (patches) at 58541-58623 ($E4AD-$E4FF) an 65371-67407
($FF5B-$FF7F).
  The most obvious change causes the Color RAM at 55296 ($D800) to be
initialized to the background color when the screen is cleared on newer
models, instead of white as on the original models.  Other changes allow the
new Kernal software to be used by either U.S. or European 64s.  Keep in mind
that the Kernal is always subject to change, and that the following
discussion, while accurate at the time written (mid-1983), may not pertain to
later models.  If future changes are like past ones, however, they are likely
to be minor ones.  The first place to look for these changes would be in the
patch sections identified above.

57344         $E000
Continuation of EXP Routine

This routine is split, with part on the BASIC ROM and the other part here.
Since the two ROMs do not occupy contiguous memory as on most Commodore
machines, the BASIC ROM ends with a JMP $E000 instruction.  Thus, while the
BASIC interpreter on the 64 is for the most part the same as on the VIC, the
addresses for routines in this ROM are displaced by three bytes from their
location on the VIC.

57411         $E043          POLY1
Function Series Evaluation Subroutine 1

This routine is used to evaluate more comples expressions, and calls the
following routine to do the intermediate evaluation.

57433         $E059          POLY2
Function Series Evaluation Subroutine 2

This is the main series evaluation routine, which evaluates expressions by
using a table of the various values that must be operated on in sequence to
obtain the proper result.

57485         $E08D          RMULC
Multiplicative Constant for RND

A five-byte floating point number which is multiplied by the seed value as
part of the process of obtaining the next value for RND>

57490         $E092          RADDC
Additive Constant for RND

The five-byte floating point number stored here is added to the seed as part
of the process of obtaining the value for RND.

57495         $E097          RND
Perform RND

This routine comes up with a random number in one of three ways, depending on
the argument X of RND(X).  If the argument is positive, the next RND value is
obtained by multiplying the seed value in location 139 ($8B) by one of the
constants above, adding the other constant, and scrambling the resulting
bytes.  This produces the next number in a sequence.  So many numbers can be
produced in this way before the sequence begins to repear that it can be
considered random.
  If the argument is negative, the argument itself is scrambled, and made the
new seed.  This allows creation of a sequence that can be duplicated.
  If the argument is 0, four bytes of the Floating Point Accumulator are
loaded from the low and high byte of Timer A, and the tenths of second and
second Time of Day Clock registers, all on CIA #1.  This provides a somewhat
random value determined by the setting of those timers at the moment that the
command is executed, which becomes the new seed value.  The RND(1) command
should then be used to generate further random numbers.
  The RND(0) implementation on the 64 has serious problems which make it
unusable for generating a series of random numbers when used by itself.  First
of all, the Time of Day Clock on CIA #1 (see 56328-56331 ($DC08-$DC0B)) does
not start running until you write to the tenth of second register.  The
Operating System never starts this clock, and therefore the two registers used
as part of the floating point RND(0) value always have a value of 0.  Even if
the clock was started, however, these registers keep time in Binary Coded
Decimal (BCD) format, which means that they do not produce a full range of
numbers from 0 to 255.  In addition, the Timer A high register output ranges
only from 0 to 66, which also imits the range of the final floating point
value so that certain numbers are never chosen.

57593         $E0F9
Call Kernal I/O Routines

This section is used when BASIC wants to call the Kernal I/O routines CHROUT,
CHRIN, CHKOUT, CHKIN, and GETIN.  It handles any errors that result from the
call, and creates a 512-byte buffer space at the top of BASIC and executes a
CLR if the RS-232 device is opened.

57642         $E12A          SYS
Perform SYS

Before executing the machine language subroutine (JSR) at the address
indicated, the .A, .X, .Y, and .P registers are loaded from the storage area
at 780-783 ($30C-$30F).  After the return from subroutine (RTS), the new
values of those registers are stored back at 780-783 ($30C-$30F).

57686         $E156          SAVE
Perform SAVE

This routine sets the range of addresses to be saved from the start of BASIC
program text and end of BASIC program text pointers at 43 ($2B) and 45 ($2D),
and calls the Kernal SAVE routine.  This means that any area of memory can be
saved by altering these two pointers to point to the starting and ending
address of the desired area, and then changing them back.

57701         $E165          VERIFY
Perform VERIFY

This routine sets the load/verify flag at 10 ($A), and falls through to the
LOAD routine.

57704         $E168          LOAD
Perform LOAD

This routine sets the load address to the start of BASIC (from pointer at 43
($2B)), and calls the Kerneal LOAD routine.  If the load is successful, it
relinks the BASIC program so that the links agree with the address to which it
is loaded, and it resets the end of BASIC pointer to reflect the new end of
program text.  If the LOAD was done while a program was running, the pointers
are reset so that the program starts executing all over again from the
beginning.  A CLR is not performed, so that the variables build so far are
retained, and their values are still accessible.  The pointer to the variable
area is not changed, but if the new program is longer than the one that loaded
it, the variable table will be partially overwritten.  This will cause errors
when the overwritten variables are referenced.  Likewise, strings whose text
was referenced at its location within the original program listing will be
incorrect.
  Since a LOAD from a program causes the program execution to continue at the
first line, when loading a machine language routine or data file with a
nonrelocating load (for example, LOAD"FILE",8,1) from a program, you should
read a flag and GOTO the line after the LOAD if you don't want the program to
keep rerunning indefinitely:

10 IF FLAG=1 THEN GOTO 30
20 FLAG=1:LOAD"FILE",8,1
30 REM PROGRAM CONTINUES HERE

57790         $E1BE          OPEN
Perform OPEN

The BASIC OPEN statement calls the Kernal OPEN routine.

57799         $E1C7          CLOSE
Perform CLOSE

The BASIC CLOSE statement calls the Kernal CLOSE routine.

57812         $E1D4
Set Parameters for LOAD, VERIFY, and SAVE

This routine is used in common by LOAD, SAVE, and VERIFY for setting the
filename, the logical file, device number, and secondary address, all of which
must be done prior to these operations.

57856         $E200
Skip Comma and Get Integer in .X

This subroutine is used to skip the comma between parameters and get the
following integer value in the .X register.

57862         $E206
Fetch Current Character and Check for End of Line

This subroutine gets the current character, and if it is 0 (end of line), it
pulls its own return address off the stack and returns.  This terminates both
its own execution and that of the subroutine which called it.

57870         $E20E
Check for Comma

This subroutine checks for a comma, moves the text pointer past it if found,
and returns an error if it is not found.

57881         $E219
Set Parameters for OPEN and CLOSE

This routine is used in common by OPEN and CLOSE for setting the filename, the
logical file, device number, and secondary address, all of which must be done
prior to these operations.

57956         $E264          COS
Perform COS

COS is executed by adding PI/2 to the contents of FAC1 and dropping through to
SIN.

57960         $E268          SIN
Perform SIN

This routine evaluates the SIN of the number in FAC1 (which represents the
angle in radians), and leaves the result there.

58036         $E2B4          TAN
Perform TAN

This routine evaluates the tangent of the number in FAC1 (which represents the
angle in radians) by dividing its sine by its cosine.

Location Range: 58080-58125 ($E2E0-$E30D)
Table of Constants for Evaluation of SIN, COS, and TAN

58080         $E2E0          PI2
The Five-Byte Floating Point Representation of the Constant PI/2

58085         $E2E5          TWOPI
The Five-Byte Floating Point Representation of the Constant 2*PI

58090         $E2EA          FR4
The Five-Byte Floating Point Representation of the Constant 1/4

58095         $E2EF          SINCON
Table of Constants for Evaluation of SIN, COS, and TAN

This table starts with a counter byte of 5, indicating that there are six
entries in the table.  This is followed by the six floating point constants of
five bytes each.

58126         $E30E          ATN
Perform ATN

The arc tangent of the number in FAC1 (which represents the angle in radians)
is evaluated using the 12-term series of operations from the constant table
which follows.  The answer is left in FAC1.

58174         $E33E          ATNCON
Table of Constants for ATN Evaluation

The table begins with a count byte of 11, which is followed by 12 constants in
five-byte floating point representation.

58235         $E37B
Warm Start BASIC

This is the entry point into BASIC from the BRK routine at 65126 ($FE66),
which is executed when the STOP and RESTORE keys are both pressed.  It first
executes the Kernal CLRCHN routine which closes all files.  It then sets the
default devices, resets the stack and BASIC program pointers, and jumps
through the vector at 768 ($300) to the next routine to print the READY prompt
and enter the main BASIC loop.

58251         $E38B
Error Message Handler

This routine to print error messages is pointed to by the vector at 768
($300).  Using the .X register as an index, it either prints an error message
from the table at 41363 ($A193) or the READY prompt, and continues through the
vector at 770 ($302) to the main BASIC loop.

58260         $E394
Cold Start BASIC

This initialization routine is executed at the time of power-up.  The RAM
vectors to important BASIC routines are set up starting at 768 ($300), the
interpreter is initialized, the start-up messages are printed, and the main
loop entered through the end of the warm start routine.

58274         $E3A2          INITAT
Text of the CHRGET Routine Which Runs at 115 ($73)

The text of the CHRGET routine is stored here, and moved to Page 0 by the
BASIC initialization routine.  When creating a wedge in CHRGET, it is possible
to execute all or part of this code in place of the RAM version.

59298         $E3BA
Initial RND Seed Value

At power-up time, this five-byte floating point constant is transferred to 139
($8B), where it functions as the starting RND seed number.  Thus, if RND is
not initialized with a negative or zero argument, it will always return the
same sequence of numbers.

58303         $E3BF          INIT
Initialize BASIC

This routine is called by the cold start routine to initialize all of the
BASIC zero-page locations which have a fixed value.  This includes copying the
CHRGET routine from the ROM location above, to 115 ($73).

58402         $E422
Print BASIC Start-Up Messages

This routine prints the start-up message "**** COMMODORE 64 BASIC V2 ****",
calculates the amount of free memory, and prints the BYTES FREE message.

58439         $E447
Table of Vectors to Important BASIC Routines

This table contains the vectors which point to the addresses of some important
BASIC routines.  The contents of this table are moved to the RAM table at 768
($300).

58451         $E453
Copy BASIC Vectors to RAM

The cold start routine calls this subroutine to copy the table of vectors to
important BASIC routines to RAM, starting at location 768 ($300).

58464         $E460          WORDS
Power-Up Messages

The ASCII text of the start-up messages "**** COMMODORE 64 BASIC V2 ****" and
"BYTES FREE" is stored here.

Location Range: 58551-58623 ($E4B7-E4FF)
Patches Added to Later Kernal Versions

This area contains code that was not found in the original version of the
Kernal.  These additions were made to fix some bugs and to increase Kernal
compatibility between U.S. and European 64s.

58541         $E4AD
Patch for BASIC Call of CHKOUT

This patch was made to preserve the .A register if there was no error returned
from BASIC's call of the Kernal CHKOUT routine.  Apparently, the first version
could cause a malfunction of the CMD and PRINT# commands.

58551         $E4B7
35 Unused Bytes (all have the value of 170 ($AA)

Locaiton Range: 58586-65535 ($E4DA-$FFFF)
Kernal I/O Routines

After the conclusion of BASIC comes the part of this ROM which can be
considered the Kernal proper.  This part contains all of the vectored routines
found in the jump table starting at 65409 ($FF81).

58586         $E4DA
Clear Color RAM to the Color in Background Color Register 0

This routine is a patch added to the more recent versions of the Kernal.  It
is called by the routine which clears a screen line (59903, $E9FF), and it
places the color value in Background Color Register 0 (53281, $D021) into the
current byte of Color RAM pointed to by USER (243, $F3).
  In the original version of the Kernal, the routine that cleared a screen
line set the corresponding Color RAM to a value of 1, which gives text
characters a white foreground color.  This was changed when the white color
was found to sometimes cause light flashes during screen scrolling.  It was
that white foreground color, however, that enabled the user to POKE the screen
code for a character into screen RAM, and make that character appear on the
screen in a color that contrasted the blue background.  This change to the
Operating System causes colors POKEd to screen RAM to be the same color as the
background, and thus they are invisible.
  This is a fairly serious problem, because the technique of POKEing
characters to screen RAM has long been a staple of Commodore graphics
programming.  Fortunately, the problem has an easy colution.  Since the Color
RAM will be set to whatevere color is in Background Color Register 0, what you
have to do to initialize Color RAM to the color you desire is change the
background color to the desired foreground color, clear the screen, and then
change the background color back again:

C=PEEK(53281):POKE 53281,HUE:PRINT CHR$(147):POKE 53281,C

58592         $E4E0
Pause after Finding a File on Cassette

This routine is a patch to the routine which finds a file on cassette.  After
the file is found, the message FILETITLE FOUND appears on the screen.  On the
original versions of the Kernal, the user would then have to hit the Commodore
key to continue the load.  On the newer versions, this patch causes a slight
pause after the tape file is round, during which time a keypress is looked
for.  If a key is pressed, the loading process continues immediately.  If it
is not, the load continues by itself after the end of the pause.

58604         $E4EC
Baud Rate Table for European (PAL) Standard Monitors

This table of prescaler values was added to later Kernal versions to allow the
same Kernal software to be used with either U.S. or European 64s.  It contains
the values which are required to obtain interrupts at the proper frequency for
the standard RS-232 baud rates, and corresponds exactly in format to the table
of values for the U.S. (NTSC) monitor format at 65218 ($FEC2).  Separate
tables are required because the prescaler values are derived from dividing the
system clock rate by the baud rate, and PAL machines operate with a slightly
slower clock frequency.

58624         $E500          IOBASE
Store Base Address of Memory-Mapped I/O Devices in .X and .Y Registers

This is one of the documented Kernal routines for which there is a vector in
the jump table at 65523 ($FFF3).
  When called, this routine sets the .X register to the low byte of the base
address of the memory-mapped I/O devices, and puts the high byte in the .Y
register.  This allows a user to set up a zero-page pointer to the device, and
to load and store indirectly through that pointer.  A program which uses this
method, rather than directly accessing such devices could be made to function
without change on future Commodore models, even though the I/O chips may be
addressed at different locations.  This of course assumes that the CIA or a
similar chip will be used.  This routine is of limited value for creating
software that is compatible with both the VIC-20 and the 64 because of the
differences in the VIA I/O chip that the VIC uses.
  The current version of this routine loads the .X register with a 0, and the
.Y register with 220 ($DC), thus pointing to CIA #1, which is at 56320
($DC00).

58629         $E505          SCREEN
Store Number of Screen Rows and Columns in .Y and .X

This is a documented Kernal routine which is vectored in the jump table at
65517 ($FFED), and is provided to allow for program compatibility between
computers.
  When called, this subroutine returns the number of screen columns in the .X
register, and the number of screen rows in .Y.  Thus, a program can detect the
screen format of the machine on which it is running, and make sure that text
output is formatted accordingly.
  The present version of this routine loads the .X register with 40 ($28) and
the .Y register with 25 ($19).

58634         $E50A          PLOT
Read/Set Location of the Cursor

The jump table entry for this documented Kernal is at 65520 ($FFF0).
  The routine allows the user to read or set the position of the cursor.  If
the carry flag is set with the SEC instruction before calling this subroutine,
cursor column (X position) will be returned in the .X register, and the cursor
row (Y position) will be returned in the .Y register.  If the carry flag is
cleared with a CLC instruction before entering this routine, and the .Y and .X
registers are loaded with the desired row and column positions respectively,
this routine will set the cursor position accordingly.
  The current read routine loads .X and .Y from locations 214 ($D6) and 211
($D3) respectively.  The cursor set routine stores .X and .Y in these
locations, and calls the routine that sets the screen pointers at 58732
($E56C).
  The user can access this routine from BASIC by loading the .X, .Y, and .P
register values desired to the save area starting at 780 ($30C).

58648         $E518
Initialize Screen and Keyboard

This is the original CINT Kernal routine, to which additions were made in
later versions of the Kernal.
  After calling the routine at 58784 ($E5A0) to set up default I/O values,
this routine initializes the cursor blink flags, the keyboard decode vector,
the key repeat delay and frequency counters, the current color code, and
maximum keyboard buffer size.  It then falls through to the next routine.

58692         $E544
Initialize the Screen Line Link Table and Clear the Screen

This routine initializes the screen line link table at 217 ($D9), clears the
screen, and clears the Color RAM to the background color.  It falls through to
the next routine.

58726         $E566
Home the Cursor

This routine sets PNTR (211, $D3) and TBLX (214, $D6) to 0, and falls through
to the next routine.

58732         $E56C
Set Pointer to Current Screen Line

This routine sets the pointer PNT (209, $D1) to the address of the first byte
of the current logical line.  In figuring this address, it takes into account
the status of the screen line link table, which can indicate that two physical
lines should be joined as one logical line.

58784         $E5A0
Set Default I/O Devices and Set Default Values for VIC-II Chip Registers

This routine sets the keyboard and screen as the current input and output
devices.  It then writes the default values found in the table at 60601
($ECB9) to the VIC-II chip.

58804         $E5B4          LP2
Get a Character from the Keyboard Buffer

This routine transfers the first character from the keybard buffer to the .A
register, bumps the rest of the characters one place up in line, and
decrements the pointer, showing how many characters are waiting in the buffer.

58826         $E5CA
Wait for a Carriage Return from the Keyboard

This subroutine is called by the portion of the CHKIN routine that handles
keyboard input.  It turns the cursor on, gets characters, and echoes them to
the screen until a carriage return has been entered.  It also looks for the
shifted RUN/STOP key, and forces the output of the commands LOAD and RUN if it
finds it.

58930         $E632
Input a Character from Screen or Keyboard

This routine is the portion of the Kernal CHRIN routine that handles input
from the keyboard and screen devices.  CHRIN gets one byte at a time from the
current screen position, or inputs a whole line from the keyboard and returns
it one byte at a time.

59012         $E684
Test for Quote Marks

This subroutine checks if the current character is a quotation mark, and if it
is, toggles the quote switch at 212 ($D4).

59025         $E691
Add a Character to the Screen

This is part of the routine that outputs a character to the screen.  It puts
printable characters into screen memory.

59048         $E6A8
Return from Outputting a Character to the Screen

This is the common exit point for the screen portion of the CHROUT routine.

59062         $E6B6
Advance the Cursor

This routine advances the cursor, and provides for such things as scrolling at
the end of the screen, and inserting a blank line in order to add another
physical line to the current logical line.

59137         $E701
Move Cursor Back over a 40-Column Line Boundary

59158         $E716
Output to the Screen

This is the main entry point for the part of CHROUT that handles output to the
screen device.  It takes an ASCII character number, and tests if the character
is printable.  If it is, it prints it (taking into consideration the reverse
flag, if any inserts are left, etc.).  If it is a nonprinting character, the
routine performs the appropriate cursor movement, color change, screen
clearing, or whatever else might be indicated.

59516         $E87C
Move Cursor to Next Line

This subroutine moves the cursor down to the next line if possible, or scrolls
the screen if the cursor is on the last line.

59537         $E891
Output a Carriage Return

A carriage return is performed by clearing insert mode, reverse video, and
quote mode, and moving the cursor to the next line.

59553         $E8A1
If at the Beginning of a Screen Line, Move Cursor to Previous Line

59571         $E8B3
If at the End of a Screen Line, Move Cursor to the Next Line

59595         $E8CB
Check for a Color Change

This routine is used by the screen CHROUT routine to check if the character to
be printed is one that causes the current foreground color to change (such as
the CTRL-1 combination).

59601         $E8D1
PETASCII Color Code Equivalent Table

This table gives the PETASCII values of the color change characters for each
of the 16 possible colors.  These values are:

144 ($90)  Change to color 0 (black)
  5 ($05)  Change to color 0 (white)
 28 ($1C)  Change to color 0 (red)
159 ($9F)  Change to color 0 (cyan)
156 ($9C)  Change to color 0 (purple)
 30 ($1E)  Change to color 0 (green)
 31 ($1F)  Change to color 0 (blue)
158 ($9E)  Change to color 0 (yellow)
129 ($81)  Change to color 0 (orange)
149 ($95)  Change to color 0 (brown)
150 ($96)  Change to color 0 (light red)
151 ($97)  Change to color 0 (dark gray)
152 ($98)  Change to color 0 (medium gray)
153 ($99)  Change to color 0 (light green)
154 ($9A)  Change to color 0 (light blue)
155 ($9B)  Change to color 0 (light gray)

59626         $E8EA
Scroll Screen

This subroutine moves all of the screen lines up, so that a blank line is
created at the bottom of the screen and the top screen line is lost.  If the
top logical line is two physical lines long, all lines are moved up two lines.
Holding down the CTRL key will cause a brief pause after the scroll.

59749         $E965
Insert a Blank Line on the Screen

This subroutine is used when INSERTing to add a blank physical line to a
logical line.

59848         $E9C8
Move Screen Line

This subroutine is used by the scroll routine to move one screen line (and its
associated Color RAM) up a line.

59872         $E9E0
Set Temporary Color Pointer for Scrolling

This subrouting sets up a pointer in 17-175 ($AE-$AF) to the Color RAM address
that corresponds to the temporary screen line address in 172-173 ($AC-$AD).

59888         $E9F0
Set Pointer to Screen Address of Start of Line

This subroutine puts the address of the first byte of the screen line
designated by the .X register into locations 209-210 ($D1-$D2).

59903         $E9FF
Clear Screen Line

This subroutine writes space characters to an entire line of screen memory,
and clears the corresponding line of color memory to color in Background Color
Register 0 (53281, $D021).

59923         $EA13
Set Cursor Blink Timing and Color Memory Address for Print to Screen

This subroutine sets the cursor blink countdown and sets the pointer to Color
RAM.  It then falls through to the next routine.

59932         $EA1C
Store to Screen

This routine stores the character in the .A register to the screen address
pointed to by 209 ($D1), and stores the color in the .X register to the
address pointed to by 243 ($F3).

59940         $EA24
Synchronize Color RAM Pointer to Screen Line Pointer

This subroutine sets the pointer at 243 ($F3) to the address of the beginning
of the line of Color RAM which corresponds to the current line of screen RAM
(whose pointer is at 209 ($D1)).

59953         $EA31
IRQ Interrupt Entry

This is the entry point to the standard IRQ interrupt handler.  Timer A of CIA
#1 is set at power-on to cause an IRQ interrupt to occur every 1/60 second.
When the interrupt occurs, program flow is transferred here via the CINV
vector at 788 ($314).  This routine updates the software clock at 160-162
($A0-$A2), handles the cursor flash, and maintains the tape interlock which
keeps the cassette motor on if a button is pushed and the interlock flag is
on.  Finally, it calls the keyboard scan routine, which checks the keyboard
and puts any character it finds into the keyboard buffer.

60039         $EA87          SCNKEY
Read the Keyboard

This subroutine is called by the IRQ interrupt handler above to read the
keyboard device which is connected to CIA #1 (see entry for 56320 ($DC00) for
details on how to read the keyboard).
  It is the Kernal routine SCNKEY which can be entered from the jump table at
65439 ($FF9F).  This routine returns the keycode of the key currently being
pressed in 203 ($CB), sets the shift/control flag if appropriate, and jumps
through the vector at 655 ($28F) to the routine that sets up the proper table
to translate the keycode to PETASCII.  It concludes with the next routine,
which places the PETASCII value of the character in the keyboard buffer.

60128         $EAE0
Decode the Keystroke and Place its ASCII Value in the Keyboard Buffer

This is the continuation of the IRQ keyscan routine.  It decodes the keycode
with the proper PETASCII table, and compares it with the last keystroke.  If
if is the same, it checks to see if it is okay to repeat the character without
waiting for the key to be let up.  If the character should be printed, it is
moved to the end of the keyboard buffer at 631 ($277).

60232         $Eb48
Set Up the Proper Keyboard Decode Table

This routine is pointed to by the vector at 655 ($28F).  Its function is to
read the shift/control flag at 653 ($28D), and set the value of the decode
table pointer at 245 ($F5) accordingly.
  First it checks if the SHIFT/Commodore logo combination was pressed, and if
the toggle enable at 657 (291) will allow a change, the character set will be
changed to lowercase/uppercase or uppercase/graphics by changing the VIC
Memory Control Register at 53272 ($D018), and no character will be printed.
  Next it sets the decode table pointer.  There are 64 keys, and each can have
four different PETASCII values, depending on whether the key is pressed by
itself, or in combination with the SHIFT, CTRL, or Commodore logo keys.
Therefore, there are four tables of 64 entries each to translate the keycode
to PETASCII:  the standard table, the SHIFT table, the Commodore logo table,
and the CONTROL table.  The routine will set up the pointer for the
appropriate table, depending on whether the SHIFT, CTRL, or logo key was
pressed.  The CTRL key takes precedence, so that if another of these keys is
pressed along with the CTRL key, the CONTROL table is used.

60281         $EB79
Keyboard Decode Table Vectors

This table contains the two-byte addresses of the four keyboard decode tables
in low-byte, high-byte format.

60289         $EB81
Standard Keyboard Matrix Decode Table

This table contains the 64 PETASCII values for the standard keyboard, one for
each key which is struck by itself.  The table is in keycode order (see the
keycode table in Appendix H for the correspondence of keycode to key).  A 65th
byte with the value of 255 ($FF) marks the end of the table (this corresponds
to a keypress value of 64, no key pressed).

60354         $EBC2
SHIFTed Keyboard Matrix Decode Table

This table contains the 64 PETASCII values for the shifted keyboard, one for
each key which is struck while the SHIFT key is pressed.  The table is in
keycode order (see the keycode table in Appendix H for the correspondence of
keycode to key).  A 65th byte with the value of 255 ($FF) marks the end of the
table (this corresponds to a keypress value of 64, no key pressed).

60419         $EC03
Commodore Logo Keyboard Matrix Decode Table

This table contains the 64 PETASCII values for the logo keyboard, one for each
key which is struck while the Commodore logo key is pressed.  The table is in
keycode order (see the keycode table in Appendix H for the correspondence of
keycode to key).  A 65th byte with the value of 255 ($FF) marks the end of the
table (this corresponds to a keypress value of 64, no key pressed).

60484         $EC44
Set Lowercase/Uppercase or Uppercase/Graphics Character Set

The part of the Kernal CHROUT routine that outputs to the screen uses this
subroutine to check for the special nonprinting characters that switch the
character set (CHR$(14) and CHR$(142)).  If one of these is the character to
be printed, this routine makes the switch by setting the location 53272
($D018) accordingly.

60510         $EC5E
Set Flag to Enable or Disable Switching Character Sets

This subroutine is also used to check for special characters to print.  In
this case, it checks for the characters that enable or disable the SHIFT/logo
combination from toggling the character set currently in use (CHR$(8) and
CHR$(9)).  If one of these is to be printed, the flag at 657 ($291) is
changed.

60536         $EC78
Control Keyboard Matrix Decode Table

This table contains the 64 PETASCII values for the Control keyboard, one for
each key which is struck while the CTRL key is pressed.  The table is in
keycode order (see the keycode table in Appendix H for the correspondence of
keycode to key).  A 65th byte with the value of 255 ($FF) marks the end of the
table (this corresponds to a keypress value of 64, no key pressed).
  The only keys generally struck in combination with the CTRL key are the ones
that change the colors on the top row of the keyboard, but this doesn't
necessarily mean that the other CTRL key combinations don't do anything.  On
the contrary, looking at the values in this table, you can see that any of the
first 32 values in the PETASCII table can be produced by some combination of
the CTRL key and another key.  CTRL-@ produces a CHR$(0).  CTRL-A through
CTRL-Z produce CHR$(1) through CHR$(26).  Ctrl-: is the same as CHR$(27),
CTRL-Lira (that's the slashed-L British pound sign) produces CHR$(28), CTRL-;
equals CHR$(29), CTRL-up arrow produces CHR$(30), and CTRL-= produces
CHR$(31).
  Any of these combinations produce the same effect as the CHR$(X) statement.
For examble, CTRL-; moves the cursor over to the right, CTRL-N switches to
lowercase, CTRL-R turns on reverse video, and CTRL-E changes the printing to
white.

60601         $ECB9
Video Chip Register Default Table

This table contains the default values that are stored in the 47 VIC-II chip
registers.  It is interesting to note that this table appears to be
incomplete.  While Sprite Color Registers 0-6 are initialized to values of
1-7, Sprite Color Register 7 is initialized to 76--the ASCII value of the
letter L which begins on the next table.

60647         $ECE7
Text for Keyboard Buffer When SHIFT/RUN is Pressed

When the SHIFT and RUN keys are pressed, the ASCII text stored here is forced
into the keyboard buffer.  That text is LOAD, carriage return, RUN, carriage
return.

60656         $ECF0
Low Byte Table of Screen Line Addresses

This table holds the low byte of the screen address for lines 0-24.  The high
byte is derived from combining a value from the screen line link table at 217
($D9) with the pointer to screen memory at 648 ($288).

60681         $ED09          TALK
Send TALK to a Device on the Serial Bus

This is a documented Kernal routine whose entry in the jump table is 65460
($FFB4).  When called, it ORs the device number in the Accumulator with the
TALK code (64, $40) and sends it on the serial bus.  This commands the device
to TALK.

60684         $ED0C          LISTEN

This is a documented Kernal routine whose entry in the jump table is 65457
($FFB1).  When called, it ORs the device number in the Accumulator with the
LISTEN code (32, $20) and sends it on the serial bus.  This commands the
device to LISTEN.

60689         $ED11
Send Command Code to a Device on the Serial Bus

This subroutine is used in common by many Kernal routines to send the command
code in the Accumulator to a device on the serial bus.

60736         $ED40
Send a Byte on the Serial Bus

This subroutine is used in common by several Kernal routines to send the byte
in the serial bus character buffer at 149 ($95) on the serial bus.

60848         $EDB0
Time-Out Error on Serial Bus

This subroutine handles the case when the device does not respond by setting
the DEVICE NOT PRESENT error code and exiting.

60857         $EDB9          SECOND
Send a Secondary Address to a Device on the Serial Bus after LISTEN

This is a documented Kernal routine that can be entered from the jump table at
65427 ($FF93).  It sends a secondary address from the Accumulator to the
device on the serial bus that has just been commanded to LISTEN.  This is
usually done to give the device more particular instructions on how the I/O is
to be carried out before information is sent.

60871         $EDC7          TKSA
Send a Secondary Address to a Device on the Serial Bus after TALK

This is a documented Kernal routine that can be entered from the jump table at
65430 ($FF96).  It sends a secondary address from the Accumulator to the
device on the serial bus that has just been commanded to TALK.  This is
usually done to give the device more particular instructions on how the I/O is
to be carried out before information is sent.

60893         $EDDD          CIOUT
Send a Byte to an I/O Device over the Serial Bus

This is a documented Kernal routine which can be entered from the jump table
at 65448 ($FFA8).  Its purpose is to send a byte of data over the serial bus.
In order for the data to be received, the serial device must have first been
commanded to LISTEN and been given a secondary address if necessary.  This
routine always buffers the current character, and defers sending it until the
next byte is buffered.  When the UNLISTEN command is sent, the last byte will
be sent with an End or Identify (EOI).

60911         $EDEF          UNTLK
Send UNTALK to a Device on the Serial Bus

This is a documented Kernal routine whose entry in the jump table is 65451
($FFAB).  When called, it sends the UNTALK code (95, $5F) on the serial bus.
This commands any TALKer on the bus to stop sending data.

60926         $EDFE          UNLSN
Send UNLISTED to a Device on the Serial Bus

This is a documented Kernal routine whose entry in the jump table is 65454
($FFAE).  It sends the UNLISTEN code (63, $3F) on the serial bus.  This
commands any LISTENers to get off the serial bus, and frees up the bus for
other users.

60947         $EE13          ACPTR
Receive a Byte of Data from a Device on the Serial Bus

This is a documented Kernal routine whose entry point in the jump table is
65445 ($FFA5).  When called, it will get a byte of data from the current
TALKer on the serial bus and store it in the Accumulator.  In order to receive
the data, the device must have previously been sent a command to TALK and a
secondary address if it needs one.

61061         $EE85
Set the Serial Clock Line Low (Active)

This subroutine clears the serial bus clock pulse output bit (Bit 4 of CIA #2
Data Port A at 56576 ($DD00)).

61070         $EE8E
Set the Serial Clock Line High (Inactive)

This subroutine sets the serial bus clock pulse output bit to 1 (Bit 4 of CIA
#2 Data Port A at 56576 ($DD00)).

61079         $EE97
Set Serial Bus Data Output Line Low

This subroutine clears the serial bus data output to 0 (Bit 5 of CIA #2 Data
Port A at 56576 ($DD00)).

61097         $EEA9
Get Serial Bus Data Input Bit and Clock Pulse Input Bit

This subroutine reads the serial bus data input bit and clock pulse input bit
(Bits 7 and 6 of CIA #2 Data Port A at 56576 ($DD00)), and returns the data
bit in the Carry flag and the clock bit in the Negative flag.

61107         $EEB3
Perform a One-Millisecond Delay

61115         $EEBB
Send Next RS-232 Bit (NMI)

This subroutine is called by the NMI interrupt handler routine to send the
next bit of data to the RS-232 device.

61230         $EF2E
Handle RS-232 Errors

This subroutine sets the appropriate error bits in the status register at 663
($297).

61258         $#F4A
Set the Word Length For the Current RS-232 Character

This routine takes the number of data bits to send per RS-232 character from
the control register and puts it into the .X register for use by the RS-232
routines.

61273         $EF59
Receive Next RS-232 Bit (NMI)

This routine is called by the NMI interrupt handler routine to receive the
next bit of data from the RS-232 device.

61310         $EF7E
Setup to Receive a New Byte from RS-232

61328         $EF90
Test If Start Bit Received from RS-232

61335         $EF97
Put a Byte of Received Data into RS-232 Receive Buffer

This routine checks for a Receive Buffer Overrun, stores the byte just
received in the RS-232 receive buffer, and checks for Parity Error, Framing
Error, or Break Detected Error.  It then sets up to receive the next byte.

61409         $EFE1
CHKOUT for the RS-232 device

The Kernal CHKOUT routine calls this subroutine to define the RS-232 device's
logical file as an output channel.  Before this can be done, the logical file
must first be OPENed.

61460         $F014
CHROUT for the RS-232 Device

The Kernal CHROUT routine calls this subroutine to output a character to the
RS-232 device.  After the logical file has been OPENed and set for output
using CHKOUT, the CHROUT routine is used to actually send a byte of data.

61517         $F04D
CHKIN for the RS-232 Device

The Kernal CHKIN routine calls this subroutine to define the RS-232 device's
logical file as an input channel.  A prerequisite for this is that the logical
file first be OPENed.

61574         $F086
GETIN for the RS-232 Device

The Kernal GETIN routine calls this subroutine to remove the next byte of data
from the RS-232 receive buffer and return it in the Accumulator.  The routine
checks for the Receive Buffer Empty Error.  It is also called by the Kernal
CHRIN routine, which essentially does the same thing as GETIN for the RS-232
device.

61604         $F0A4
Stop CIA #2 RS-232 NMIs for Serial/Cassette Routines

This subroutine turns off the NMIs that drive the RS-232 routines before any
I/O is done using the serial bus or cassette device.  Such interrupts could
throw off the timing of those I/O routines, and interfere with the
transmission of data.

61629         $F0BD
Kernal Control Messages

The ASCII text of the Kernal I/O control messages is stored here.  The last
byte of every message has Bit 7 set to 1 (ASCII value + 128).  The messages
are:

I/O ERROR
SEARCHING
FOR
PRESS PLAY ON TAPE
PRESS RECORD & PLAY ON TAPE
LOADING
SAVING
VERIFYING
FOUND
OK

61739         $F12B
Print Kernal Error Message if in Direct Mode

This routine first checks location 157 ($9D) to see if the messages are
enabled.  If they are, it prints the message indexed by the .Y register.

61758         $F13E          GETIN
Get One Byte from the Input Device

This is a documented Kernal routine whose jump table entry point is at 65508
($FFE4).  The routine jumps through a RAM vector at 810 ($32A).  Its function
is to get a character from the current input device (whose device number is
stored at 153 ($99)).  In practive, it operates identically to the CHRIN
routine below for all devices except for the keyboard.  If the keyboard is the
current input device, this routine gets one character from the keyboard buffer
at 631 ($277).  It depends on the IRQ interrupt routine to rad the keyboard
and put characters into the buffer.

61783         $F157          CHRIN
Input a Character from the Current Device

This is a documented Kernal routine whose jump table entry point is at 65487
($FFCF).
  The routine jumps through a RAM vector at 804 ($324).  Its function is to
get a character from the current input device (whose device number is stored
at 153 ($99)).  This device must first have been OPENed and then designated as
the input channel by the CHKIN routine.
  When this routine is called, the next byte of data available from this
device is returned in the Accumulator.  The only exception is the routine for
the keyboard device (which is the default input device).  It the keyboard is
the current input device, this routine blinks the cursor, fetches characters
from the keyboard buffer, and echoes them to the screen until a carriage
return is encountered.  When a carriage return is round, the routine sets a
flag to indicate the length of the last logical line before the return
character, and reads the first character of this logical line from the screen.
  Subsequent calls to this routine will cause the next character in the line
to be read from the screen and returned in the Accumulator, until the carriage
return character is returned to indicate the end of the line.  Any call after
this character is received will start the whole process over again.
  Note that only the last logical line before the carriage return is used.
Any time you type in more than 80 characters, a new logical line is started.
This routine will ignore any characters on the old logical line, and process
only the most recent 80-character group.

61898         $F1CA          CHROUT
Output a Byte

This is a documented Kernal routine whose jump table entry point is at 65490
($FFD2).  The routine jumps through a RAM vector at 806 ($326).  It is
probably one of the best known and most used Kernal routines, because it sends
the character in the Accumulator to the current output device.  Unless a
device has been OPENed and designated as the current output channel using the
CHKOUT routine, the character is printed to the screen, which is the default
output device.  If the cassette is the current device, outputting a byte will
only add it to the buffer.  No actual transmission of data will occur until
the 192-byte buffer is full.

61966         $F20E          CHKIN
Designate a Logical File As the Current Input Channel

This is a documented Kernal routine which can be entered from the jump table
at 65478 ($FFC6).
  The routine jumps through a RAM vector at 798 ($31E).  If you wish to get
data from any device other than the keyboard, this routine must be called
after OPENing the device, before you can get a data byte with the CHRIN or
GETIN routine.  When called, the routine will designate the logical file whose
file number is in the .X register as the current file, its device as the
current device, and its secondary address as the current secondary address.
If the device on the channel is a serial device, which requires a TALK command
and sometimes a secondary address, this routine will send them over the serial
bus.

62032         $F250          CHKOUT
Designate a Logical File As the Current Output Channel

This is a documented Kernal routine which can be entered from the jump table
at 65481 ($FFC9).
  The routine jumps through a RAM vector at 800 ($320).  If you wish to output
data to any device other than the screen, this routine must be called after
OPENing the device, and before you output a data byte with the CHROUT routine.
When called, the routine will designate the logical file whose file number is
in the .X register as the current file, its device as the current device, and
its secondary address as the current secondary address.  If the device on the
channel uses the serial bus, and therefore requires a LISTEN command and
possibly a secondary address, this information will be sent on the bus.

62097         $F291          CLOSE
Close a Logical I/O File

CLOSE is a documented Kernal routine which can be entered via the jump table
at 65475 ($FFC3).
  The routine jumps through a RAM vector at 796 ($31C).  It is used to close
a logical file after all I/O operations involving that file have been
completed.  This is accomplished by loading the Accumulator with the logical
file number of the file to be closed, and calling this routine.
  Closing an RS-232 file will de-allocate space at the top of memory for the
receiving and trasmit buffers.  Closing a cassette file that was opened for
writing will force the last block to be written to cassette, even if it is not
a full 192 bytes.  Closing a serial bus device will send an UNLISTEN command
on the bus.  Remember, it is necessary to properly CLOSE a cassette or disk
data file in order to retrieve the file later.
  For all types of files, CLOSE removes the file's entry from the tables of
logical files, device, and secondary address at 601, 611, and 621 ($259, $263,
$26D), and moves all higher entries in the table down one space.

62223         $F30F
Find the File in the Logical File Table

This subroutine is used by many Kernal routines to find the position of the
logical file in the logical file table at 601 ($259).

62239         $F31F
Set Current Logical File, Current Device, and Current Seconday Address

This subroutine is used to update the Kernal variables at 184-186 ($B8-$BA)
which holds the current logical file number, current device number, and
current secondary address number.

62255         $F32F          CLALL
Close All Logical I/O Files

CLALL is a documented Kernal routine whose entry point in the jump table is
65511 ($FFE7).
  The routine jumps through a RAM vector at 812 ($32C).  It closes all open
files, by resetting the index into open files at 152 ($98) to zero.  It then
falls through to the next routine, which restores the default I/O devices.

62259         $F333          CLRCHN
Restore Current Input and Output Devices to the Default Devices

This is a documented Kernal Routine which can be entered at location 65484
($FFCC) in the jump table.
  The routine jumps through a RAM vector at 802 ($322).  It sets the current
input device to the keyboard, and the current output device to the screen.
Also, if the current input device was formerly a serial device, the routine
sends it an UNTALK command on the serial bus, and if a serial device was
formerly the current output device, the routine sends it an UNLISTEN command.

62282         $F34A          OPEN
Open a Logical I/O File

OPEN is a documented Kernal I/O routine.  It can be entered from the jump
table at 65472 ($FFC0).
  The routine jumps through a RAM vector at 794 ($31A).  This routine assigns
a logical file to a device, so that it can be used for Input/Output
operations.  In order to specify the logical file number, the device number,
and the secondary address if any, the SETLFS routine must first be called.
Likewise, in order to designate the filename, the SETNAM routine must be used
first.  After these two routines are called, OPEN is then called.

62622         $F49E          LOAD
Load RAM from a Device

This is a documented Kernal routine, whose entry in the jump table appears at
65493 ($FFD5).
  The routine jumps through a RAM vector at 816 ($330).  LOAD is used to
transfer data froma device directly to RAM.  It can also be used to verify
RAM, comparing its contents to those of a disk or tape file.  To choose
between these operations you must set the Accumulator with a 0 for LOAD, or a
1 for VERIFY.
  Since the LOAD routine performs an OPEN, it must be preceded by a call to
the SETLFS routine to specify the logical file number, device number, and
secondary address, and a call to the SETNAM routine to specify the filename
(a LOAD from tape can be performed without a filename being specified).  Then
the .X and .Y registers should be set with the starting address for the load,
and the LOAD routine called.  If the secondary address specified was a 1, this
starting address will be ignored, and the header information will be used to
supply the load address.  If the secondary address was a 0, the address
supplied by the call will be used.  In either case, upon return from the
subroutine, the .X and .Y registers will contain the address of the highest
RAM location that was loaded.

62885         $F5A5
Print SEARCHING Message if in Direct Mode

62930         $F5D2
Print LOADING or VERIFYING

62941         $F5DD          SAVE
Save RAM to a Device

This is a documented Kernal routine, whose entry in the jump table appears at
65496 ($FFD8).
  The routine jumps through a RAM vector at 818 ($332).  SAVE is used to
transfer data directly from RAM to an I/O device.  Since the SAVE routine
performs an OPEN, it must be preceded by a call to the SETLFS routine to
specify the logical file number, device number, and secondary address, and a
call to the SETNAM routine to specify the filename (although a SAVE to the
cassette can be performed without giving a filename).  A Page 0 pointer to the
starting address of the area to be saved should be set up, with the low byte
of the address first.  The accumulator should be loaded with the Page 0 offset
of that pointer, then the .X and .Y registers should be set with the ending
address for the save, and the SAVE routine called.

63119         $F68F
If in Direct Mode, Print SAVING and Filename

63131         $F69B          UDTIM
Update the Software Clock and Check for the STOP Key

UDTIM is a documented Kernal routine which can be entered through the jump
table at 65514 ($FFEA).
  It is normally called by the IRQ interrupt handler once every sixtieth of a
second.  It adds one to the value in the three-byte software jiffy clock at
160-162 ($A0-$A2), and sets the clock back to zero when it reaches the 24 hour
point.  In addition, it scans the keyboard row in which the STOP key is
located, and stores the current value of that key in location 145 ($91).  This
variable is used by the STOP routine which checks for the STOP key.

63197         $F6DD          RDTIM
Read the Time From the Software Clock into the .A, .X, and .Y Registers

This is a documented Kernal routine whose entry point in the jump table is
65502 ($FFDE).
  It reads the software clock (which counts sixtieths of a second) into the
internal registers.  The .Y register contains the most significant byte (from
location 160 ($A0)), the .X register contains the middle byte (from location
161 ($A1)), and the Accumulator contains the least significant byte (from
location 162 ($A2)).

63204         $F6E4          SETTIM
Set the Software Clock from the .A, .X, and .Y Registers

This documented Kernal routine can be entered from location 65499 ($FFDB).
  It performs the reverse operation from RDTIM, storing the value in the .Y
register into location 160 ($A0), the .X register into 161 ($A1), and the
Accumulator into 162 ($A2).  Interrupts are first disabled, to make sure that
the clock will not be updated while being set.

63213         $F6ED          STOP
Test STOP Key

STOP is a documented Kernal routine which can be entered from the jump table
at location 65505 ($FFE1).
  It is vectored through RAM at 808 ($328).  The routine checks to see if the
STOP key was pressed during the last UDTIM call.  If it was, the Zero flag is
set to 1, the CLRCHN routine is called to set the input and output devices
back to the keyboard and screen, and the keyboard queue is emptied.

63227         $F6FB
Set Kernal I/O Error Messages

This subroutine is used to handle I/O errors from Kernal I?O routines.  It
calls CLRCHN to restore default I/O devices.  If Bit 6 of the flag at 157
($9D) is set, it prints I/O ERROR followed by the error number, and then sets
the Carry flag to indicate an error, with the error number in the Accumulator.
The Kernal error messages are not used by BASIC, but may be used by machine
language monitors and other applications.

63276         $F72C
Get Next Tape File Header from Cassette

This routine reads in tape blocks until it finds a file header block.  It then
prints out the FOUND message along with the first 16 characters of the
filename.

63338         $F76A
Write Tape File Header Block

63440         $F7D0
Put Pointer to Tape Buffer in .X and .Y Registers

63447         $F7D7
Set I/O Area Start and End Pointers to Tape Buffer Start and End Address

63466         $F7EA
Search Tape for a Filename

63511         $F817
Test Cassette Buttons and Handle Messages for Tape Read

This routine tests the sense switch, and if no buttons are depressed it prints
the PRESS PLAY ON TAPE message, and loops until a cassette button is pressed,
or until the STOP key is pressed.  If a button is pressed, it prints the
message OK.
  Since the message printing routine is entered after the test for direct
mode, these messages cannot be superseded by changing the flag at 157 ($9D).
You could have them harmlessly printed to ROM, however, by changing the value
of HIBASE at 648 ($288) temporarily to 160, and then back to 4.

63534         $F82E
Check Cassette Switch

This subroutine is used to check if a button on the recorder has been pressed.

63544         $F838
Test Cassette Buttons and Handle Messages for Tape Write

This routine tests the sense switch, and if no buttons are depressed it prints
the PRESS PLAY & RECORD message, and loops until a cassette button is pressed,
or until the STOP key is pressed.  If a button is pressed, it prints the
message OK.  These messages cannot be supressed by changing the flag at 157
($9D).  See the entry for 63511 ($F817) for more information.

63553         $F841
Start Reading a Block of Data from the Cassette

This subroutine tests the cassette switch and initializes various flags for
reading a block of data from cassette.

63588         $F864
Start Writing a Block of Data to the Cassette

This subroutine tests the cassette switch and initializes various flags for
writing a block of data to cassette.

63605         $F875
Common Code for Reading a Data Block from Tape and Writing a Block to Tape

This routine sets the actual reading or writing of a block of data.  It sets
CIA #1 Timer B to call the IRQ which drives the actual reading or writing
routine, saves the old IRQ vector, and sets the new IRQ vector to the read or
write routine.  It also blanks the screen so that the video chip's memory
addressing (which normally takes away some of the 6510 microprocessor's
addressing time) will not interfere with the timing of the routines.

63696         $F8D0
Test the STOP Key during Cassette I/O Operations

This subroutine is used to test the STOP key during tape I/O oeprations, and
to stop I/O if it is pressed.

63714         $F8E2
Adjust CIA #1 Timer A for Tape Bit Timing

63788         $F92C
Read Tape Data (IRQ)

This is the IRQ handler routine that is used for reading data from the
cassette.  At the end of the read, the IRQ vector is restored to the normal
IRQ routine.

64096         $FA60
Receive and Store the Next Character from Cassette

This is the part of the cassette read IRQ routine that actually gets the next
byte of data from the cassette.

64398         $FB8E
Move the Tape SAVE/LOAD Address into the Pointer at 172

64407         $FB97
Reset Counters for Reading or Writing a New Byte of Cassette Data

64422         $FBA6
Toggle the Tape Data Output Line

This routine sets the CIA #1 Timer B, and toggles the Tape Data Output line on
the 6510 on-chip I/O port (Bit 3 of location 1).

64456         $FBC8
Write Data to Cassette--Part 2 (IRQ)

This IRQ handler routine is one part of the write data to cassette routine

64618         $FC6A
Write Data fo Cassette--Part 1 (IRQ)

This IRQ handler routine is the other part of the write data to cassette
routine.

64659         $FC93
Restores the Default IRQ Routine

At the end of the tape I/O operations, this subroutine is used to turn the
screen back on and stop the cassette motor.  It then resets the CIA #1 Timer A
to generate an interrupt every sixtieth of a second, and restores the IRQ
vector to point to the normal interrupt routine that updates the software
clock and scans the keyboard.

64696         $FCB8
Terminate Cassette I/O

This routine calls the subroutine above and returns from the interrupt.

64714         $FCCA
Turn Off the Tape Motor

64721         $FCD1
Check the Tape Read/Write Pointer

This routine compares the current tape read/write address with the ending
read/write address.

64731         $FCDB
Advance the Tape Read/Write Pointer

This routine is used to move the pointer to the current read/write address up
a byte.

64738         $FCE2
Power-On Reset Routine

This is the RESET routine which is pointed to by the 6510 hardware RESET
vector at 65532 ($FFFC).
  This routine is automatically executed when the computer is first turned on.
First, it sets the Interrupt disable flag, sets the stack pointer, and clears
the Decimal mode flag.  Next, it tests for an autostart cartridge.  If one is
found, the routine immediately jumps through the cartridge cold start vector
at 32768 ($8000).  If no cartridge is found, the Kernal initialization
routines IOINIT, RAMTAS, RESTOR, and CINT are called, the Interrupt disable
flag is cleared, and the BASIC program is entered through the cold start
vector at 40960 ($A000).

64770         $FD02
Check for an Autostart Cartridge

This routine tests for an autostart cartridge by comparing the characters at
location 32772-6 ($8004-8) to the text below.  The Zero flag will be set if
they match, and cleared if they don't.

64784         $FD10
Text for Autostart Cartridge Check

The characters stored here must be the fifth through the ninth characters in
the cartridge in order for it to be started on power-up.  These characters are
the PETASCII values for CBM, each with the high bit set (+128), and the
characters "80".

64789         $FD15          RESTOR
Restore RAM Vectors for Default I/O Routines

This documented Kernal routine can be entered through the jump table at 65418
($FF8A).
  It sets the values for the 16 RAM vectors to the interrupt and important
Kernal I/O routines in the table that starts at 788 ($314) to the standard
values held in the ROM table at 64816 ($FD30).

64794         $FD1A          VECTOR
Set the RAM Vector Table from the Table Pointed to by .X and .Y

This documented Kernal routine can be entered through the jump table at 65421
($FF8D).
  It is used to read or change the values for the 16 RAM vectors to the
interrupt and important Kernal I/O routines in the table that starts at 788
($314).  If the Carry flag is set when the routine is called, the current
value of the 16 vectors will be stored at a table whose address is pointed to
by the values in the .X and .Y registers.  If the Carry flag is cleared, the
RAM vectors will be loaded from the table whose address is pointed to by the
.X and .Y registers.  Since this routine can change the vectors for the IRQ
and NMI interrupts, you might expect that the Interrupt disable flag would be
set at its beginning.  Such is not the case, however, and therefore it would
be wise to execute an SEI before calling it and a CLI afterwards (as the
power-on RESET routine does) just to be safe.

64816         $FD30
Table of RAM Vectors to the Default I/O Routines

This table contains the 16 RAM I/O vectors that are moved to 788-819
($314-$333).

64848         $FD50          RAMTAS
Perform RAM Test and Set Pointers to the Top and Bottom of RAM

This documented Kernal routine, which can be entered through location 65415
($FF87) of the jump table, performs a number of initialization tasks.
  First, it clears Pages 0, 2, and 3 of memory to zeros.  Next, it sets the
tape buffer pointer to address 828 ($33C), and performs a nondestructive test
of RAM from 1024 ($400) up.  When it reaches a non-RAM address (presumably the
BASIC ROM at 40960 ($A000)), that address is placed in the top of memory
pointer at 643-4 ($283-4).  The bottom of memory pointer at 641-2 ($281-2) is
set to point to address 2048 ($800), which is the beginning of BASIC program
text.  Finally, the pointer to screen memory at 648 ($288) is set to 4, which
lets the Operating System know that screen memory starts at 1024 ($400).

64923         $FD9B
Table of IRQ Vectors

This table holds the vectors to the four IRQ routines which the system uses.
The first points to Part 1 of the cassette write routine at 64618 ($FC6A), the
second to Part 2 of the cassette write routine at 64461 ($FBCD), the third to
the standard scan keyboard IRQ at 59953 ($EA31), and the last to the cassette
read routine at 63788 ($F92C).

64931         $FDA3          IOINIT
Initialize CIA I/O Devices

This documented Kernal routine, which can be entered through the jump table at
65412 ($FF84), intializes the Complex Interface Adapter (CIA) devices, and
turns the volume of the SID chip off.  As part of this initialization, it sets
CIA #1 Timer A to cause an IRQ interrupt every sixtieth of a second.

65017         $FDF9          SETNAM
Set Filename Parameters

This is a documented Kernal routine, which can be entered through the jump
table at location 65469 ($FFBD).
  It puts the value in the Accumulator into the location which stores the
number of characters in the filename, and sets the pointer to the address of
the ASCII text of the filename from the .X and .Y registers.  This sets up the
filename for the OPEN, LOAD, or SAVE routine.

65024         $FE00          SETLFS
Set Logical File Number, Device Number, and Secondary Address

This is a documented Kernal routine, which can be entered through the jump
table at location 65466 ($FFBA).
  It stores the value in the Accumulator in the location which holds the
current logical file number, the value in the .X register is put in the
location that holds the current device number, and the value in the .Y
register is stored in the location that holds the current secondary address.
If no secondary address is used, the .Y register should be set to 255 ($FF).
It is necessary to set the values of the current file number, device number,
and secondary address before you OPEN a file, or LOAD or SAVE.

65031         $FE07          READST
Read the I/O Status Word

This is a documented Kernal routine, which can be entered through the jump
table at location 65463 ($FFB7).
  Whenever an I/O error occurs, a bit of the Status Word is set to indicate
what the problem was.  The routine allows you to read the status word (it is
returned in the Accumulator).  If the device was the RS-232, its status
register is read and cleared to zero.  For the meanings of the various status
codes, see the entry for location 144 ($90) or 663 ($297) for the RS-232
device.

65048         $FE18          SETMSG
Set the Message Control Flag

This documented Kernal routine can be entered through its jump table vector at
65424 ($FF90).
  The routine controls the printing of error messages and control messages by
the Kernal.  It Bit 6 is seto to 1 (bit value of 64), Kernal control messages
can be printed.  These messages include SEARCHING FOR, LOADING, and the like.
If Bit 6 is cleared to 0, these messages will not be printed (BASIC will clear
this bit when a program is running so that the messages do not appear when I/O
is performed from a program).  Setting Bit 6 will not suppress the PRESS PLAY
ON TAPE or PRESS PLAY & RECORD messages, however.
  If Bit 7 is set to 1 (bit value of 128), Kernal error messages can be
printed.  If Bit 7 is set to 0, those error messages (for example, I/O ERROR
#nn) will be suppressed.  Note that BASIC has its own set of error messages
(such as FILE NOT FOUND ERROR) which it uses in preference to the Kernal's
message.

65057         $E21           SETTMO
Set Time-Out Flag for IEEE Bus

This documented Kernal routine can be entered fromthe jump table at 65442
($FFA2).
  The routine sets the time-out flag for the IEEE bus.  When timeouts are
enabled, the Commodore will wait for a device for 64 milliseconds, and if it
does not receive a response to its signal it will issue a time-out error.
Loading the Accumulator with a value less than 128 and calling this routine
will enable time-outs, while using a value over 128 will disable time-outs.
  This routine is for use only with the Commodore IEEE add-on card, which at
the time of this writing was not yet available.

65061         $FE25          MEMTOP
Read/Set Top of RAM Pointer

This is a documented Kernal routine, which can be entered through the jump
table at location 65433 ($FF99).
  It cn be used to either read or set the top of RAM pointer.  If called with
the Carry flag set, the address in the pointer will be loaded into the .X and
.Y registers.  If called with the Carry flag cleared, the pointer will be
changed to the address found in the .X and .Y registers.

65076         $FE34          MEMBOT
Read/Set Bottom of RAM Pointer

This is a documented Kernal routine, which can be entered through the jump
table at location 65436 ($FF9C).
  It can be used to either read or set the bottom of RAM pointer.  If called
with the Carry flag set, the address in the pointer willbe loaded into the .X
and .Y registers.  If called with the Carry flag cleared, the pointer will be
changed to the address found in the .X and .Y registers.

65091         $FE43
NMI Interrupt Entry Point

This routine is the NMI interrupt handler entry, which is pointed to by the
hardware NMI vector at 65530 ($FFFA).
  Any time an NMI interrupt occurs, the Interrupt disable flag will be set,
and the routine will jump through the RAM vector at 792 ($318), which
ordinarily points to the continuation of this routine.  The standard handler
first checks to see if the NMI was caused by the RS-232 device.  If not, the
RESTORE key is assumed.  The routine checks for a cartridge, and if one is
found it exits through the cartridge warm start vector at 32770 ($8002).  If
not, the STOP key is checked, and if it is being pressed, the BRK routine is
executed.  If the RS-232 device was the cause of the NMI, the cartridge and
STOP key checks are bypassed, and the routine skips to the end, where it
checks whether it is time to send or receive a data bit via the RS-232 device.

65126         $FE66
BRK, Warm Start Routine

This routine is executed when the STOP/RESTORE combination of keypresses
occurs.  In addition, it is the default target address of the BRK instruction
vector.  This routine calls the Kernal intialization routines RESTOR, IOINIT,
and part of CINT.  It then exits through the BASIC warm start vector at 40962
($A002).

65138         $FE72
NMI RS-232 Handler

This is the part of the NMI handler that checks if it is time to receive or
send a bit on the RS-232 channel, and takes the appropriate action if it is
indeed the time.

65218         $FEC2
RS-232 Baud Rate Tables for U.S. Television Standard (NTSC)

This table contains the ten prescaler values for the ten standard baud rates
implemented by the RS-232 Control Register at 659 ($293).  The table starts
with the two values needed for the lowest baud rate (50 baud) and finishes
with the entries for the highest baud rate, 2400 baud.  The RS-232 routines
are handled by NMI interrupts which are caused by the timers on CIA #2.  Since
the RS-232 device could both receive and send a bit in a single cycle, the
time between interrupts should be a little less than half of the clock
frequency divided by the baud rate.  The exact formula used is:

((CLOCK/BAUD)/2)-100

where CLOCK is the processor clock speed and BAUD is the baud rate.  The clock
frequency for machines using the U.S. television standard (NTSC) is 1,022,730
cycles per second, while the frequency for the European (PAL) standard is
985,250 cycles per second.  For this reason, separate baud rate tables were
added for European machines at 58604 ($E4EC).

65238         $FED6
RS-232 Receive the Next Bit (NMI)

The NMI handler calls this subroutine to input the next bit on the RS-232 bus.
It then calls the next subroutine to reload the timer that causes the
interrupts.

65306         $FF1A
Load the Timer with Prescaler Values from the Baud Rate Lookup Table

65352         $FF48
Main IRQ/BRK Interrupt Entry Point

The 6510 hardware IRQ/BRK vector at 65534 ($FFFE) points to this address.
  Anytime the BRK instruction is encountered or an IRQ interrupt occurs, this
routine will be executed.  The routine first saves the .A, .X, and .Y
registers on the stack, and then tests the BRK bit of the status register (.P)
to see if a BRK was executed.  If it was, the routine exits through the RAM
BRK vector at 790 ($316), where it will usually be directed to the BRK routine
at 65126 ($FE66).  If not, the routine exits through the RAM IRQ vector at 788
($314), where it will usually be directed to the handler that scans the
keyboard at 59953 ($EA31).
  If you plan to change either of these vectors to your own routine, remember
to pull the stored register values off the stack before finishing.

Location Range: 65371-65407 ($FF5B-$FF7F)
Patches Added to Later Kernal Versions

This area contains additional code not found in the original version of the
Kernal.  It is used to test whether a European (PAL) or U.S. (NTSC) standard
monitor is used, and to compensate so that the sixtieth of a second interrupt
will be accurately timed on either system.

65371         $FF5B          CINT
Initialize Screen Editor and VIC-II Chip

This is a documented Kernal routine whose entry in the jump table is located
at 65409 ($FF81).
  The start of the routine appears to be a patch that was added to later
versions of the Kernal.  It first calls the old routine at 58648 ($E518).
This initializes the VIC-II chip to the default values, sets the keyboard as
the input device and the screen as the output device, initializes the cursor
flash variables, builds the screen line link table, clears the screen, and
homes the cursor.  The new code then checks the VIC Interrupt register to see
if the conditions for a Raster Compare IRQ have been fulfilled.  Since the
Raster Register was initialized to 311, that can only occur when using a PAL
system (NTSC screens do not have that many scan lines).  The PAL/NTSC register
at 678 ($2A6) is set on the basis of the outcome of this test.  The CIA #1
Timer A is then set to cause an IRQ interrupt every sixtieth of a second,
using the prescaler figures for a PAL or NTSC system, as appropriate.

65390         $FF6E
End of Routine to Set Timer for Sixtieth of a Second IRQ

This appears to be a patch added to compensate for the extra length of the
current version of this routine, which chooses either the PAL or NTSC
prescaler values for the timer.

65408         $FF80
Kernal Version Identifier Byte

This last byte before the jump table can be used to identify the version of
the Kernal.  The first version has a 170 ($AA) stored here, while the most
current version at the time of this writing has a zero in this location.
  The PET 64, a one-piece version with an integrated monochrome display, has
an identifier byte of 100 ($64).  The Commodore 64 logo uses this byte to
recognize the PET 64, and adjust its display accordingly.

Location Range: 65409-65525 ($FF81-$FFF5)
Kernal Jump Table

The following jump table is provided by Commodore in an effort to maintain
stable entry points for key I/O routines.  Each three-byte table entry
consists of a 6510 JMP instruction and the actual address of the routine in
the ROM.  Although the actual address of the routine may vary from machine to
machine, or in later versions of the Kernal, these addresses will stay where
they are.  By jumping to the entry point provided by this table, rather than
directly into the ROM, you insure your programs against changes in the
Operating System.  In addition, this jump table may help you write programs
that will function on more than one Commodore machine.  The 15 table entries
from 65472-65514 ($FFC0-$FFEA) are the same for all Commodore machines, from
the earliest PET on.
  As an additional aid, some of these routines are also vectored through the
table which starts at 788 ($314).  Since this table is in RAM, you can change
those vectors to point to your own routines which support additional I/O
devices.  Programs that use the jump table entry points to the I/O routines
will be able to use these I/O devices without a problem.
  The following table will give the entry point, routine name, RAM vector if
any, its current address, and a brief summary of its function.

65409 ($FF81) CINT   (65371, $FF5B) initialize screen editor and video chip
65412 ($FF84) IOINIT (64931, $FDA3) initialize I/O devices
65415 ($FF87) RAMTAS (64848, $FD50) initialize RAM, tape buffer, screen
65418 ($FF8A) RESTOR (64789, $FD15) restore default I/O vectors
65421 ($FF8D) VECTOR (64794, $FD1A) read/set I/O vector table
65424 ($FF90) SETMSG (65048, $FE18) set Kernal message control flag
65427 ($FF93) SECOND (60857, $EDB9) send secondary address after LISTEN
65430 ($FF96) TKSA   (60871, $EDC7) send secondary address after TALK
65433 ($FF99) MEMTOP (65061, $FE25) read/set top of memory pointer
65436 ($FF9C) MEMBOT (65076, $FE34) read/set bottom of memory pointer
65439 ($FF9F) SCNKEY (60039, $EA87) scan the keyboard
65442 ($FFA2) SETTMO (65057, $FE21) set time-out flag for IEEE bus
65445 ($FFA5) ACPTR  (60947, $FE13) input byte from serial bus
65448 ($FFA8) CIOUT  (60893, $EDDD) output byte to serial bus
65451 ($FFAB) UNTLK  (60911, $EDEF) command serial bus device to UNTALK
65454 ($FFAE) UNLSN  (60926, $EDFE) command serial bus device to UNLISTEN
65457 ($FFB1) LISTEN (60684, $ED0C) command serial bus device to LISTEN
65460 ($FFB4) TALK   (60681, $ED09) command serial bus device to TALK
65463 ($FFB7) READST (65031, $FE07) read I/O status word
65466 ($FFBA) SETLFS (65024, $FE00) set logical file parameters
65469 ($FFBD) SETNAM (65017, $FDF9) set filename parameters
65472 ($FFC0) OPEN   (via 794 ($31A) to 62282, $F34A) open a logical file
65475 ($FFC3) CLOSE  (via 796 ($31C) to 62097, $F291) close a logical file
65478 ($FFC6) CHKIN  (via 798 ($31E) to 61966, $F20E) define an input channel
65481 ($FFC9) CHKOUT (via 800 ($320) to 62032, $F250) define an output channel
65484 ($FFCC) CLRCHN (via 802 ($322) to 62259, $F333) restore default devices
65487 ($FFCF) CHRIN  (via 804 ($324) to 61783, $F157) input a character
65490 ($FFD2) CHROUT (via 806 ($326) to 61898, $F1CA) output a character
65493 ($FFD5) LOAD   (via 816 ($330) to 62622, $F49E) load from device
65496 ($FFD8) SAVE   (via 818 ($332) to 62941, $F5DD) save to a device
65499 ($FFDB) SETTIM (63204, $F6E4) set the software clock
65502 ($FFDE) RDTIM  (63197, $F6DD) read the software clock
65505 ($FFE1) STOP   (via 808 ($328) to 63213, $F6ED) check the STOP key
65508 ($FFE4) GETIN  (via 810 ($32A) to 61758, $F13E) get a character
65511 ($FFE7) CLALL  (via 812 ($32C) to 62255, $F32F) close all files
65514 ($FFEA) UDTIM  (63131, $F69B) update the software clock
65517 ($FFED) SCREEN (58629, $E505) read number of screen rows and columns
65520 ($FFF0) PLOT   (58634, $E50A) read/set position of cursor on screen
65523 ($FFF3) IOBASE (58624, $E500) read base address of I/O devices

Location Range: 65530-65535 ($FFFA-$FFFF)
6510 Hardware Vectors

The last six locations in memory are reserved by the 6510 processor chip for
three fixed vectors.  These vectors let the chip know at what address to start
executing machine language program code when an NMI interrupt occurs, when the
computer is turned on, or when an IRQ interrupt or BRK occurs.

65530         $FFFA
Non-Maskable Interrupt Hardware Vector

This vector points to the main NMI routine at 65091 ($FE43).

65532         $FFFC
System Reset (RES) Hardware Vector

This vector points to the power-on routine at 64738 ($FCE2).

65534         $FFFE
Maskable Interrupt Request and Break Hardware Vectors

This vector points to the main IRQ handler routine at 65352 ($FF48).


:::::::::::::::::::
::  Appendix A   ::
::               ::
:: A Beginner's  ::
::Guide to Typing::
::  In Programs  ::
:::::::::::::::::::

What Is a Program?

A computer cannot perform any task by itself.  Like a car without gas, a
computer has potential, but without a program, it isn't going anywhere.  Most
of the programs published in this book are written in a computer language
called BASIC.  BASIC is easy to learn and is built into all Commodore 64s.

BASIC Programs

Computers can be picky.  Unlike the English language, which is full of
ambiguities, BASIC usually has only one right way of stating something.  Every
letter, character, or number is significant.  A common mistake is substituting
a letter such as O for the numeral 0, a lowercase l for the numeral 1, or an
uppercase B for the numeral 8.  Also, you must enter all punctuation such as
colons and commas just as they appears in the book.  Spacing can be important.
To be safe, type in the listings exactly as they appear.

Braces and Special Characters

The exception to this typing rule is when you see the braces, such as {DOWN}.
Anything within a set of braces is a special character or characters that
cannot easily by listed on a printer.  When you come across such a special
statement, refer to Appendix B, "How to Type In Programs."

About DATA Statements

Some programs contain a section or sections of DATA statements.  These lines
provide information needed by the program.  Some DATA statements contain
actual programs (called machine language); others contain graphics codes.
These lines are especially sensitive to errors.
  If a single number in any one DATA statement is mistyped, your machine could
lock up, or crash.  The keyboard and STOP key may seem dead, and the screen
may go blank.  Don't panic--no damage is done.  To regain control, you have to
turn off your computer, then turn it back on.  This will erase whatever
program was in memory, so always SAVE a copy of your program before you RUN
it.  If your computer crashes, you can LOAD the program and look for your
mistake.
  Sometimes a mistyped DATA statement will cause an error message when the
program is RUN.  The error message may refer to the program line that READs
the data.  The error is still in the DATA statements, though.

Get to Know Your Machine

You should familiarize yourself with your computer before attempting to type
in a program.  Learn the statements you use to store and retrieve your
programs from tape or disk.  You'll want to save a copy of your program, so
that you won't have to type it in every time you want to use it.  Learn to use
your machine's editing functions.  How do you change a line if you made a
mistake?  You can always retype the line, but you at least need to know how to
backspace.  Do you know how to enter reverse video, lowercase, and control
characters?  It's all explained in your computer's manuals.

A Quick Review

1.  Type in the program a line at a time, in order.  Press RETURN at the end
of each line.  Use backspace or the back arrow to correct mistakes
2.  Check the line you've typed against the line in the book.  You can check
the entire program again if you get an error when you RUN the program.


:::::::::::::::
::Appendix B ::
::           ::
::How to Type::
;:In Programs::
:::::::::::::::

To make it easy to know exactly what to type when entering one of these
programs into your computer, we have established the following listing
conventions.
  Generally, Commodore 64 program listings will contain words within braces
which spell out any special characters:  {DOWN} would mean to press the cursor
down key.  {5 SPACES} would mean to press the space bar five times.
  To indicate that a key should be shifted (hold down the SHIFT key while
pressing the other key), the key would be unterlined in our listings.  For
example, _S_ would mean to type the S key while holding the SHIFT key.  This
would appear on your screen as a heart symbol.  If you find an underlined key
enclosed in braces (e.g., {10 _N_}), you should type the key as many times as
indicated (in our example, you would enter ten shifted N's).
  If a key is enclosed in special brackets, [<>], you should hold down the
Commodore key while pressing the key inside the special brackets.  (The
Commodore key is the key in the lower-left corner of the keyboard.)  Again, if
the key is preceded by a number, you should press the key as many times as
necessary.
  Rarely, you'll see a solitary letter of the alphabet enclosed in braces.
These characters can be entered by holding down the CTRL key while typing the
letter in the braces.  For example, {A} would indicate that you should press
CTRL-A.
  About the quote mode:  You know that you can move the cursor around the
screen with the CRSR keys.  Sometimes a programmer will want to move the
cursor under program control.  That's why you see all the {LEFT}'s, {HOME}'s,
and {BLU}'s in our programs.  The only way the computer can tell the
difference between direct and programmed cursor control is the quote mode.
  Once you press the quote (the double quote, SHIFT-2), you are in the quote
mode.  If you type something and then try to change it by moving the cursor
left, you'll only get a bunch of reverse-video lines.  These are the symbols
for cursor left.  The only editing key that isn't programmable is the DEL key;
you can still use DEL to back up and edit the line.  Once you type another
quote, you are out of quote mode.
  You also go into quote mode when you INSerT spaces into a line.  In any
case, the easiest way to get out of quote mode is to just press RETURN.
You'll then be out of quote mode and you can cursor up to the mistyped line
and fix it.
  Use the following table when entering cursor and color control keys:

When You                               When You
Read:         Press:                   Read:          Press:
[CLR]       SHIFT CLR/HOME             [<1>]           C= 1
[HOME]            CLR/HOME             [<2>]           C= 2
[UP]        SHIFT CRSR UP/DOWN         [<3>]           C= 3
[DOWN]            CRSR UP/DOWN         [<4>]           C= 4
[LEFT]      SHIFT CRSR LEFT/RIGHT      [<5>]           C= 5
[RIGHT]           CRSR LEFT/RIGHT      [<6>]           C= 6
[RVS]        CTRL 9                    [<7>]           C= 7
[OFF]        CTRL 0                    [<8>]           C= 8
[BLK]        CTRL 1                    [F1]               F1
[WHT]        CTRL 2                    [F2]         SHIFT F1
[RED]        CTRL 3                    [F3]               F3
[CYN]        CTRL 4                    [F4]         SHIFT F3
[PUR]        CTRL 5                    [F5]               F5
[GRN]        CTRL 6                    [F6]         SHIFT F5
[BLU]        CTRL 7                    [F7]               F7
[YEL]        CTRL 8                    [F8]         SHIFT F8


::::::::::::::
::Appendix C::
::          ::
::  Screen  ::
:: Location ::
::  Table   ::
::::::::::::::

Row
 0 1024  oooooooooooooooooooooooooooooooooooooooo
   1064  oooooooooooooooooooooooooooooooooooooooo
   1104  oooooooooooooooooooooooooooooooooooooooo
   1144  oooooooooooooooooooooooooooooooooooooooo
   1184  oooooooooooooooooooooooooooooooooooooooo
 5 1224  oooooooooooooooooooooooooooooooooooooooo
   1264  oooooooooooooooooooooooooooooooooooooooo
   1304  oooooooooooooooooooooooooooooooooooooooo
   1344  oooooooooooooooooooooooooooooooooooooooo
   1384  oooooooooooooooooooooooooooooooooooooooo
10 1424  oooooooooooooooooooooooooooooooooooooooo
   1464  oooooooooooooooooooooooooooooooooooooooo
   1504  oooooooooooooooooooooooooooooooooooooooo
   1544  oooooooooooooooooooooooooooooooooooooooo
   1584  oooooooooooooooooooooooooooooooooooooooo
15 1624  oooooooooooooooooooooooooooooooooooooooo
   1664  oooooooooooooooooooooooooooooooooooooooo
   1704  oooooooooooooooooooooooooooooooooooooooo
   1744  oooooooooooooooooooooooooooooooooooooooo
   1784  oooooooooooooooooooooooooooooooooooooooo
20 1824  oooooooooooooooooooooooooooooooooooooooo
   1864  oooooooooooooooooooooooooooooooooooooooo
   1904  oooooooooooooooooooooooooooooooooooooooo
   1944  oooooooooooooooooooooooooooooooooooooooo
24 1984  oooooooooooooooooooooooooooooooooooooooo
         |    |    |    |    |    |    |    |   |
         0    5   10   15   20   25   30   35  39

                          Column


::::::::::::::::
:: Appendix D ::
::            ::
::Screen Color::
::Memory Table::
::::::::::::::::

Row
 0 55296  oooooooooooooooooooooooooooooooooooooooo
   55336  oooooooooooooooooooooooooooooooooooooooo
   55376  oooooooooooooooooooooooooooooooooooooooo
   55416  oooooooooooooooooooooooooooooooooooooooo
   55456  oooooooooooooooooooooooooooooooooooooooo
 5 55496  oooooooooooooooooooooooooooooooooooooooo
   55536  oooooooooooooooooooooooooooooooooooooooo
   55576  oooooooooooooooooooooooooooooooooooooooo
   55616  oooooooooooooooooooooooooooooooooooooooo
   55656  oooooooooooooooooooooooooooooooooooooooo
10 55696  oooooooooooooooooooooooooooooooooooooooo
   55736  oooooooooooooooooooooooooooooooooooooooo
   55776  oooooooooooooooooooooooooooooooooooooooo
   55816  oooooooooooooooooooooooooooooooooooooooo
   55856  oooooooooooooooooooooooooooooooooooooooo
15 55896  oooooooooooooooooooooooooooooooooooooooo
   55936  oooooooooooooooooooooooooooooooooooooooo
   55976  oooooooooooooooooooooooooooooooooooooooo
   56016  oooooooooooooooooooooooooooooooooooooooo
   56056  oooooooooooooooooooooooooooooooooooooooo
20 56096  oooooooooooooooooooooooooooooooooooooooo
   56136  oooooooooooooooooooooooooooooooooooooooo
   56176  oooooooooooooooooooooooooooooooooooooooo
   56216  oooooooooooooooooooooooooooooooooooooooo
24 56256  oooooooooooooooooooooooooooooooooooooooo
          |    |    |    |    |    |    |    |   |
          0    5   10   15   20   25   30   35  39

                           Column


:::::::::::::::
::Appendix E ::
::           ::
::  Screen   ::
::Color Codes::
:::::::::::::::

Value to POKE for Each Color

             Low nybble    High nybble   Select multicolor
Color        color value   color value   color value

Black         0              0            8
White         1             16            9
Red           2             32           10
Cyan          3             48           11
Purple        4             64           12
Green         5             80           13
Blue          6             96           14
Yellow        7            112           15
Orange        8            128           --
Brown         9            144           --
Light Red    10            160           --
Dark Gray    11            176           --
Medium Gray  12            192           --
Light Green  13            208           --
Light Blue   14            224           --
Light Gray   15            240           --

Where To POKE Color Values For Each Mode

                 Bit or
Mode *           bit-pair   Location        Color value

Regular text      0         53281           Low nybble
                  1         Color memory    Low nybble
Multicolor text  00         53281           Low nybble
                 01         53282           Low nybble
                 10         53283           Low nybble
                 11         Color memory    Select Multicolor
Extended color   00         53281           Low nybble
text +           01         53282           Low nybble
                 10         53283           Low nybble
                 11         53284           Low nybble
Bitmapped         0         Screen memory   Low nybble ++
                  1         Screen memory   High nybble ++
Multicolor       00         53281           Low nybble
bitmapped        01         Screen memory   High nybble ++
                 10         Screen memory   Low nybble ++
                 11         Color memory    Low nybble

* For all modes, the screen border color is controlled by POKEing location
53280 with the low nybble color value.
+ In exteded color mode, Bits 6 and 7 of each byte of screen memory serve as
the bit-pair controlling background color.  Because only Bits 0-5 are
available for character selection, only characters with screen codes 0-63 can
be used in this mode.
++ In the bitmapped modes, the high and low nybble color values are ORed
together and POKEd into the same location in memory to control the colors of
the corresponding cell in the bitmap.  For example, to control the colors of
cell 0 of the bitmap, OR the high and low nybbles and POKE the result into
location 0 of screen memory.


:::::::::::::::
::Appendix F ::
::           ::
::ASCII Codes::
:::::::::::::::

[*** OMITTED ***]
[widely available elsewhere; not suitable for textual formatting]


::::::::::::::::
:: Appendix G ::
::            ::
::Screen Codes::
::::::::::::::::

[*** OMITTED ***]
[widely available elsewhere; not suitable for textual formatting]


:::::::::::::::
::Appendix H ::
::           ::
:: Commodore ::
::64 Keycodes::
:::::::::::::::

Key          Keycode                   Key          Keycode
A            10                        6            19
B            28                        7            24
C            20                        8            27
D            18                        9            32
E            14                        0            35
F            21                        +            40
G            26                        -            43
H            29                        LIRA         48
I            33                        CLR/HOME     51
J            34                        INST/DEL      0
K            37                        LEFT ARROW   57
L            42                        @            46
M            36                        *            49
N            39                        ^            54
O            38                        :            45
P            41                        ;            50
Q            62                        =            53
R            17                        RETURN        1
S            13                        ,            47
T            22                        .            44
U            30                        /            55
V            31                        CRSR UP/DN    7
W             9                        CRSR LF/RT    2
X            23                        F1            4
Y            25                        F3            5
Z            12                        F5            6
1            56                        F7            3
2            59                        SPACE        60
3             8                        RUN/STOP     63
4            11                        NO KEY
5            16                        PRESSED      64

The keycode is the number found at location 197 for the current key being
pressed.  Try this one-line program:

10 PRINT PEEK(197):GOTO 10


::::::::::::::
::  Index   ::
::          ::
::(by memory::
:: location)::
::::::::::::::

ABS  48216
AND  45033
ASC  46987
ATN  58126
BASIC
  adding new commands  115,768
  current line number  57
  execution of statements  776,42980
  expression evaluation  778, 44446, 44675
  function evaluation  44967
  pointer to bottom of string text  51
  pointer to current data item address  65
  pointer to current statement address  61
  pointer to end of array storage  49
  pointer to start of array storage  47
  pointer to start of program text  43
  pointer to start of variable storage  45
  pointer to top of BASIC RAM  55
  program text storage  2048
  RAM vector table  768
Buffer
  cassette I/O buffer  178, 828
  keyboard buffer  198, 631
  RS-232 input buffer 247
  RS-232 output buffer  249
  text input buffer  512
cartridge, autostart ROM  32768
cassette
  data output line  01
  I/O buffer  828
  Kernal ROM routines  63466-64737
  motor control  01, 192
  switch sense  01
character generator ROM  01, 4096, 36864, 53248
charcter graphics  53248
CHAREN  01
CHRGET  115, 58274
CHR$  46828
CIA (Complex Interface Adapter)
  CIA #1  56320-56335
  CIA #2  56576-56591
  data direction registers  56322, 56323, 56578, 56579
  data ports  56320, 56321, 56576, 56577
  timers  56334, 56335, 56590, 56591
clock
  clock speed (6510 microprocessor)  56334
  software clock  160
  Time of Day clock  56328, 56584
CLOSE  57799
CLR  42590
CMD  43654
cold start, BASIC  40960, 58260
color
  background  53281
  border (frame)  53280
  color codes  646
  color RAM nybbles  55296
  current character color  646
  multicolor background registers 53282, 53283
  PETASCII color change characters  59601
  sprite color registers  53287-53294
  sprite multicolor registers  53285, 53286
CONT  43095
COS  57956
DATA  43256
data direction register  00, 56322, 56323, 56578, 56579
data port  01, 56320, 56321, 56576, 56577
DEF  46003
DIM  45185
dynamic keyboard  198, 631
error
  BASIC error handler  768, 42039, 58251
  error message control flag  157
  I/O error status  144
  RS-232 I/O error status  663
EXP  49133
expression evaluation  778, 44446, 44675
floating point
  addition  47207, 47210
  division  47887, 47890
  fixed-floating point conversion  05, 45969
  floating-fixed point conversion  03, 45482, 45503
  Floating Point Accumulators  97, 110
  floating point-ASCII conversion  48605
  multiplication  47656, 47667
  subtraction  47194, 47194
FN  46068
FOR  42818
FRE  45949
garbage collection, string variable  46374
GET, GET#  43899
GOSUB  43139
GOTO  43168
graphics
  bitmapped graphics  53265
  character graphics  53248
  extended background color mode  53265
  fine scrolling  53265, 43271
  multicolor mode  53271
  raster position  53265, 53266
  screen blanking  53265
  sprites SEE sprite graphics
HIRAM  01
IF  43304
INT  48332
interrupt
  CIA hardware FLAG line  56589, 56333
  CIA serial shift register  56589, 56333
  CIA Time of Day clock alarm  56589, 56333
  CIA Timers A and B  56589, 56333
  IRQ handler  59953, 65352
  IRQ vector  788, 65534
  light pen IRQ  53273, 53274
  NMI handler  65091
  NMI vector  792, 65530
  raster compare IRQ  53266, 53273, 53274
  sprite-display data collision IRQ  53273, 53275
  sprite-sprite collision IRQ  53273, 53275
INPUT  43967
INPUT#  43941
I/O
  current device number  186
  current filename address 187
  current filename length  183
  current input device  153
  current I/O channel number  19
  current logical file number  184
  current output device  154
  current secondary address  185
  device number table  611
  logical file table  601
  number of I/O files open  152
  RS-232 status  663
  secondary address table  621
  status word codes  144
joystick controllers  56320, 56321
Kernal
  jump table  65409
  RAM vector table  794
  ACPTR  60947, 65445
  CHKIN  798, 61966, 65478
  CHKOUT  800, 62032, 65481
  CHRIN  804, 61783, 65487
  CHROUT  806, 61898, 65490
  CINT  65371, 65409
  CIOUT  60893, 65448
  CLALL  812, 62255, 65511
  CLOSE  796, 62097, 65475
  CLRCHN  802, 62259, 65484
  GETIN  810, 61758, 65508
  IOBASE  58624, 65523
  IOINIT  64931, 65412
  LISTEN  60684, 65457
  LOAD  816, 62622, 65493
  MEMBOT  65076, 65436
  MEMTOP  65061, 65433
  OPEN  794, 62282, 65472
  PLOT  58634, 65520
  RAMTAS  64848, 65415
  RDTIM  63197, 65502
  READST  65031, 65463
  RESTOR  64789, 65418
  SAVE  818, 62941, 65496
  SCNKEY  60039, 65439
  SCREEN  58629, 65517
  SECOND  60857, 65427
  SETLFS  65024, 65466
  SETMSG  65048, 65424
  SETNAM  65017, 65469
  SETTIM  63204, 65499
  SETTMO  65057, 65442
  STOP  808, 63213, 65505
  TALK  60681, 65460
  TKSA  60871, 65430
  UDTIM  63131, 65514
  UNLSN  60926, 65454
  UNTLK  60911, 65451
  VECTOR  64794, 65421
keyboard
  current key pressed  203
  keyboard buffer  631
  keycodes  203
  keyboard matrix  245, 655, 56321
  last key pressed  197
  number of characters in buffer  198
  pointer to matrix lookup table  245
  reading the keyboard  56320
  repeating keys  650
LEFT$  46848
LEN  46972
LET  43429
light pen  53267, 53268
LIST  42652
LOAD  57704
LORAM  01
MID$ 46903
NEW  42562
NEXT  44318
NMI  65095
ON GOSUB, ON GOTO  43339
OPEN  57790
Operating System (OS)
  OS end of RAM pointer  643
  OS screen memory pointer  648
  OS start of RAM pointer  641
OR  45030
paddle controllers  54297, 54298
paddle fire button  56320, 56321
PAL/NTSC flag  678
PEEK  47117
POKE  47140
POS  45982
PRINT  43680
PRINT#  43648
program text area  43, 2048
program text input buffer  512
RAM
  BASIC pointer to end of RAM  55
  RAM/ROM selection  01
  OS pointer to end of RAM  643
  OS pointer to start of RAM  641
random number generator  54299
READ  44038
registers, reading/setting from BASIC  780
REM  43323
RESER, power-on  64738, 65532
reset, VIC-II chip  53270
RESTORE  43037
RESTORE key, disabling  792, 808
RETURN  43218
RIGHT$  46892
RND  139, 57495
RS-232
  baud rate  659, 661, 665
  baud rate tables  58604, 65218
  buffers  247, 249
  command register  660
  connector pin assignments  56576, 56577
  control register  659
  duplex mode  660
  handshaking protocol  660
  Kernal ROM routines  57344-65535
  parity  660
  status register  663
  stop bits  659
  word length  659
RUN  43121
SAVE  57686
screen editor
  current character color  646
  cursor color RAM position  243
  cursor flash  204, 205, 207
  cursor maintenance  206, 647
  cursor screen position  209, 211, 214
  insert mode flag  216
  key repeat  650, 651, 652
  quote mode flag  212
  reverse character flag  199
  screen line link table  217
  screen RAM  1024, 648, 53272
  shift flag  653, 654
Serial Bus I/O  56576, 60681-61114
Serial Data Port (CIA)  56332, 56588
SGN  48185
SID chip register  54272-54300
  SEE ALSO sound
SIN  57960
sound
  ADSR envelope control  54278-54279, 54285-54286, 54292-54293
  filtering  54293-54296
  frequency (pitch) control  54272-54273, 54279-54280, 54286-54287
  gate bit  54276
  Oscillator 3 envelope generator  54300
  Oscillator 3 output  54299
  pulse waveform pulse width  54274-54275, 54281-54282, 54288-54289
  ring modulation  54276, 54283, 54290
  synchronization (hard sync)  54276, 54283, 54290
  volume control  54296
  waveform control  54276, 54283, 54290
sprite graphics
  color registers  53287-53294
  display priority  53275
  enabling sprite display  53274
  horizontal expansion  53277
  multicolor color registers  53285-53286
  multicolor sprites  53276
  position registers  53248-53264
  shape data pointers  2040
  sprite-display data collision detection  53279
  sprite-sprite collision detection  53278
  vertical expansion  53271
SQR  49009
ST (I/O status word)  144
stack, 6510 microprocessor  256
STOP  43055
STOP key  145, 808
STR$  46181
SYS  780, 57642
TAN  56083
Time of Day clock  56328-56331, 56584-56587
timers, hardware  56324-56327, 56334-56335, 56580-56583, 56590-56591
tokens, keyword  772, 774, 40972, 41042, 41088, 41118, 42364, 42772
User Port  56567-56577
USR  785
VAL  47021
variable
  array variable storage  47
  find or create variable routine  45195
  storage format  45
  string text area  51
VERIFY  57701
VIC-II CHIP
  memory bank switching  56576
  registers  53248-53294
  SEE ALSO graphics, sprite graphics
warm start, BASIC  40962, 58235
WAIT  47149
wedges  115

